diff --git a/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts b/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts index 4829f477b09..b4154056b6a 100644 --- a/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts +++ b/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts @@ -1,6 +1,6 @@ import { Factory } from '@ember/-internals/owner'; import { Dict, Opaque, Simple } from '@glimmer/interfaces'; -import { Tag } from '@glimmer/reference'; +import { CONSTANT_TAG, Tag } from '@glimmer/reference'; import { Arguments, CapturedArguments, ModifierManager } from '@glimmer/runtime'; export interface CustomModifierDefinitionState { @@ -18,17 +18,23 @@ export function capabilities(_managerAPI: string, _optionalFeatures?: {}): Capab export class CustomModifierDefinition { public state: CustomModifierDefinitionState; - public manager = CUSTOM_MODIFIER_MANAGER; + public manager: ModifierManager>; + constructor( public name: string, public ModifierClass: Factory, - public delegate: ModifierManagerDelegate + public delegate: ModifierManagerDelegate, + isInteractive: boolean ) { this.state = { ModifierClass, name, delegate, }; + + this.manager = isInteractive + ? CUSTOM_INTERACTIVE_MODIFIER_MANAGER + : CUSTOM_NON_INTERACTIVE_MODIFIER_MANAGER; } } @@ -67,12 +73,15 @@ export interface ModifierManagerDelegate { implements a set of hooks that determine modifier behavior. To create a custom modifier manager, instantiate a new CustomModifierManager class and pass the delegate as the first argument: + ```js let manager = new CustomModifierManager({ // ...delegate implementation... }); ``` + ## Delegate Hooks + Throughout the lifecycle of a modifier, the modifier manager will invoke delegate hooks that are responsible for surfacing those lifecycle changes to the end developer. @@ -81,7 +90,7 @@ export interface ModifierManagerDelegate { * `updateModifier()` - invoked when the arguments passed to a modifier change * `destroyModifier()` - invoked when the modifier is about to be destroyed */ -class CustomModifierManager +class InteractiveCustomModifierManager implements ModifierManager< CustomModifierState, @@ -119,4 +128,24 @@ class CustomModifierManager } } -const CUSTOM_MODIFIER_MANAGER = new CustomModifierManager(); +class NonInteractiveCustomModifierManager + implements ModifierManager> { + create() { + return null; + } + + getTag(): Tag { + return CONSTANT_TAG; + } + + install() {} + + update() {} + + getDestructor() { + return null; + } +} + +const CUSTOM_INTERACTIVE_MODIFIER_MANAGER = new InteractiveCustomModifierManager(); +const CUSTOM_NON_INTERACTIVE_MODIFIER_MANAGER = new NonInteractiveCustomModifierManager(); diff --git a/packages/@ember/-internals/glimmer/lib/resolver.ts b/packages/@ember/-internals/glimmer/lib/resolver.ts index 53ec8cad3c3..a7978c15ae8 100644 --- a/packages/@ember/-internals/glimmer/lib/resolver.ts +++ b/packages/@ember/-internals/glimmer/lib/resolver.ts @@ -89,6 +89,7 @@ const BUILTIN_MODIFIERS = { }; export default class RuntimeResolver implements IRuntimeResolver { + public isInteractive: boolean; public compiler: LazyCompiler; private handles: any[] = [ @@ -114,10 +115,11 @@ export default class RuntimeResolver implements IRuntimeResolver(new CompileTimeLookup(this), this, macros); + this.isInteractive = isInteractive; } /*** IRuntimeResolver ***/ @@ -290,7 +292,7 @@ export default class RuntimeResolver implements IRuntimeResolver>(modifier.class); let manager = managerFactory!(owner); - return new CustomModifierDefinition(name, modifier, manager); + return new CustomModifierDefinition(name, modifier, manager, this.isInteractive); } } diff --git a/packages/@ember/-internals/glimmer/lib/setup-registry.ts b/packages/@ember/-internals/glimmer/lib/setup-registry.ts index 46d1303c149..6d9154652e1 100644 --- a/packages/@ember/-internals/glimmer/lib/setup-registry.ts +++ b/packages/@ember/-internals/glimmer/lib/setup-registry.ts @@ -92,6 +92,7 @@ export function setupEngineRegistry(registry: Registry) { registry.register('service:-glimmer-environment', Environment); registry.register(P`template-compiler:main`, TemplateCompiler); + registry.injection(P`template-compiler:main`, 'environment', '-environment:main'); registry.injection('template', 'compiler', P`template-compiler:main`); diff --git a/packages/@ember/-internals/glimmer/lib/template-compiler.ts b/packages/@ember/-internals/glimmer/lib/template-compiler.ts index 1e67214d7b5..cedd4d93acd 100644 --- a/packages/@ember/-internals/glimmer/lib/template-compiler.ts +++ b/packages/@ember/-internals/glimmer/lib/template-compiler.ts @@ -1,9 +1,15 @@ import { Compiler } from '@glimmer/interfaces'; import RuntimeResolver from './resolver'; +export interface ICompilerOptions { + environment: { + isInteractive: boolean; + }; +} + // factory for DI export default { - create(): Compiler { - return new RuntimeResolver().compiler; + create({ environment }: ICompilerOptions): Compiler { + return new RuntimeResolver(environment.isInteractive).compiler; }, };