diff --git a/packages/@ember/-internals/glimmer/index.ts b/packages/@ember/-internals/glimmer/index.ts index 6697901b6d5..8cacb65eff4 100644 --- a/packages/@ember/-internals/glimmer/index.ts +++ b/packages/@ember/-internals/glimmer/index.ts @@ -307,4 +307,5 @@ export { default as OutletView } from './lib/views/outlet'; export { capabilities } from './lib/component-managers/custom'; export { setComponentManager, getComponentManager } from './lib/utils/custom-component-manager'; export { setModifierManager, getModifierManager } from './lib/utils/custom-modifier-manager'; +export { capabilities as modifierCapabilties } from './lib/modifiers/custom'; export { isSerializationFirstNode } from './lib/utils/serialization-first-node-helpers'; diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/custom.ts b/packages/@ember/-internals/glimmer/lib/component-managers/custom.ts index 311f2fbaa13..587bce404d0 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/custom.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/custom.ts @@ -22,6 +22,7 @@ import { Destroyable } from '@glimmer/util'; import Environment from '../environment'; import RuntimeResolver from '../resolver'; import { OwnedTemplate } from '../template'; +import { ManagerArgs, valueForCapturedArgs } from '../utils/managers'; import { RootReference } from '../utils/references'; import AbstractComponentManager from './abstract'; @@ -64,15 +65,10 @@ export interface Capabilities { destructor: boolean; } -export interface CustomComponentManagerArgs { - named: Dict; - positional: Opaque[]; -} - export interface ManagerDelegate { capabilities: Capabilities; - createComponent(factory: Opaque, args: CustomComponentManagerArgs): ComponentInstance; - updateComponent(instance: ComponentInstance, args: CustomComponentManagerArgs): void; + createComponent(factory: Opaque, args: ManagerArgs): ComponentInstance; + updateComponent(instance: ComponentInstance, args: ManagerArgs): void; getContext(instance: ComponentInstance): Opaque; } @@ -104,12 +100,6 @@ export interface ComponentArguments { named: Dict; } -function valueForCapturedArgs(args: CapturedArguments): CustomComponentManagerArgs { - return { - named: args.named.value(), - positional: args.positional.value(), - }; -} /** The CustomComponentManager allows addons to provide custom component implementations that integrate seamlessly into Ember. This is accomplished diff --git a/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts b/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts index b395809dd7c..32c30af833f 100644 --- a/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts +++ b/packages/@ember/-internals/glimmer/lib/modifiers/custom.ts @@ -1,7 +1,8 @@ import { Factory } from '@ember/-internals/owner'; -import { Dict, Opaque } from '@glimmer/interfaces'; +import { Opaque } from '@glimmer/interfaces'; import { Tag } from '@glimmer/reference'; import { Arguments, CapturedArguments, ModifierManager } from '@glimmer/runtime'; +import { ManagerArgs, valueForCapturedArgs } from '../utils/managers'; export interface CustomModifierDefinitionState { ModifierClass: Factory; @@ -9,8 +10,10 @@ export interface CustomModifierDefinitionState { delegate: ModifierManagerDelegate; } +export interface Capabilities {} + // Currently there are no capabilities for modifiers -export function capabilities() { +export function capabilities(_managerAPI: string, _optionalFeatures?: {}): Capabilities { return {}; } @@ -19,7 +22,7 @@ export class CustomModifierDefinition { public manager = CUSTOM_MODIFIER_MANAGER; constructor( public name: string, - ModifierClass: Factory, + public ModifierClass: Factory, public delegate: ModifierManagerDelegate ) { this.state = { @@ -45,27 +48,12 @@ export class CustomModifierState { } } -export interface CustomModifierManagerArgs { - named: Dict; - positional: Opaque[]; -} - export interface ModifierManagerDelegate { - createModifier(factory: Opaque, args: CustomModifierManagerArgs): ModifierInstance; - installModifier( - instance: ModifierInstance, - element: Element, - args: CustomModifierManagerArgs - ): void; - updateModifier(instance: ModifierInstance, args: CustomModifierManagerArgs): void; - destroyModifier(instance: ModifierInstance, args: CustomModifierManagerArgs): void; -} - -function valueForCapturedArgs(args: CapturedArguments): CustomModifierManagerArgs { - return { - named: args.named.value(), - positional: args.positional.value(), - }; + capabilities: Capabilities; + createModifier(factory: Opaque, args: ManagerArgs): ModifierInstance; + installModifier(instance: ModifierInstance, element: Element, args: ManagerArgs): void; + updateModifier(instance: ModifierInstance, args: ManagerArgs): void; + destroyModifier(instance: ModifierInstance, args: ManagerArgs): void; } class CustomModifierManager diff --git a/packages/@ember/-internals/glimmer/lib/resolver.ts b/packages/@ember/-internals/glimmer/lib/resolver.ts index 8df76b995af..0be90ea2d6a 100644 --- a/packages/@ember/-internals/glimmer/lib/resolver.ts +++ b/packages/@ember/-internals/glimmer/lib/resolver.ts @@ -41,7 +41,7 @@ import { default as queryParams } from './helpers/query-param'; import { default as readonly } from './helpers/readonly'; import { default as unbound } from './helpers/unbound'; import ActionModifierManager from './modifiers/action'; -import { CustomModifierDefinition } from './modifiers/custom'; +import { CustomModifierDefinition, ModifierManagerDelegate } from './modifiers/custom'; import { populateMacros } from './syntax'; import { mountHelper } from './syntax/mount'; import { outletHelper } from './syntax/outlet'; @@ -285,14 +285,7 @@ export default class RuntimeResolver implements IRuntimeResolver>(modifier.class); let manager = managerFactory!(owner); return new CustomModifierDefinition(name, modifier, manager); @@ -352,20 +345,14 @@ export default class RuntimeResolver implements IRuntimeResolver>(component.class); + if (managerFactory) { + let delegate = managerFactory(meta.owner); let definition = new CustomManagerDefinition( name, component, - manager, + delegate, layout || meta.owner.lookup(P`template:components/-default`) ); finalizer(); diff --git a/packages/@ember/-internals/glimmer/lib/utils/custom-component-manager.ts b/packages/@ember/-internals/glimmer/lib/utils/custom-component-manager.ts index 5f3f5d56483..f5fd66dda47 100644 --- a/packages/@ember/-internals/glimmer/lib/utils/custom-component-manager.ts +++ b/packages/@ember/-internals/glimmer/lib/utils/custom-component-manager.ts @@ -1,27 +1,24 @@ +import { Owner } from '@ember/-internals/owner'; import { GLIMMER_CUSTOM_COMPONENT_MANAGER } from '@ember/canary-features'; +import { Opaque } from '@glimmer/interfaces'; +import { getManager, ManagerFactory, setManager } from './managers'; -const getPrototypeOf = Object.getPrototypeOf; -const MANAGERS: WeakMap = new WeakMap(); - -export function setComponentManager(managerId: string, obj: any) { - MANAGERS.set(obj, managerId); - - return obj; +export function setComponentManager(stringOrFunction: string | ManagerFactory, obj: any) { + let factory; + if (typeof stringOrFunction === 'string') { + factory = function(owner: Owner) { + return owner.lookup(`component-manager:${stringOrFunction}`); + }; + } else { + factory = stringOrFunction; + } + return setManager(factory, obj); } -export function getComponentManager(obj: any): string | undefined { +export function getComponentManager(obj: any): undefined | ManagerFactory { if (!GLIMMER_CUSTOM_COMPONENT_MANAGER) { return; } - let pointer = obj; - while (pointer !== undefined && pointer !== null) { - if (MANAGERS.has(pointer)) { - return MANAGERS.get(pointer); - } - - pointer = getPrototypeOf(pointer); - } - - return; + return getManager(obj); } diff --git a/packages/@ember/-internals/glimmer/lib/utils/custom-modifier-manager.ts b/packages/@ember/-internals/glimmer/lib/utils/custom-modifier-manager.ts index 8109c57d271..d4d0ff85357 100644 --- a/packages/@ember/-internals/glimmer/lib/utils/custom-modifier-manager.ts +++ b/packages/@ember/-internals/glimmer/lib/utils/custom-modifier-manager.ts @@ -1,32 +1,15 @@ -import { Owner } from '@ember/-internals/owner'; import { GLIMMER_MODIFIER_MANAGER } from '@ember/canary-features'; import { Opaque } from '@glimmer/util'; -import { ModifierManagerDelegate } from '../modifiers/custom'; +import { getManager, ManagerFactory, setManager } from './managers'; -const getPrototypeOf = Object.getPrototypeOf; - -export type ModifierManagerFactory = (owner: Owner) => ModifierManagerDelegate; - -const MANAGERS: WeakMap = new WeakMap(); - -export function setModifierManager(factory: ModifierManagerFactory, obj: any) { - MANAGERS.set(obj, factory); - return obj; +export function setModifierManager(factory: ManagerFactory, obj: any) { + return setManager(factory, obj); } -export function getModifierManager(obj: any): undefined | ModifierManagerFactory { +export function getModifierManager(obj: any): undefined | ManagerFactory { if (!GLIMMER_MODIFIER_MANAGER) { return; } - let pointer = obj; - while (pointer !== undefined && pointer !== null) { - if (MANAGERS.has(pointer)) { - return MANAGERS.get(pointer); - } - - pointer = getPrototypeOf(pointer); - } - - return; + return getManager(obj); } diff --git a/packages/@ember/-internals/glimmer/lib/utils/managers.ts b/packages/@ember/-internals/glimmer/lib/utils/managers.ts new file mode 100644 index 00000000000..fc5d05830c6 --- /dev/null +++ b/packages/@ember/-internals/glimmer/lib/utils/managers.ts @@ -0,0 +1,39 @@ +import { Owner } from '@ember/-internals/owner'; +import { Dict, Opaque } from '@glimmer/interfaces'; +import { CapturedArguments } from '@glimmer/runtime'; + +const MANAGERS: WeakMap> = new WeakMap(); + +const getPrototypeOf = Object.getPrototypeOf; + +export type ManagerFactory = (owner: Owner) => ManagerDelegate; + +export function setManager(factory: ManagerFactory, obj: any) { + MANAGERS.set(obj, factory); + return obj; +} + +export function getManager(obj: any): undefined | ManagerFactory { + let pointer = obj; + while (pointer !== undefined && pointer !== null) { + if (MANAGERS.has(pointer)) { + return MANAGERS.get(pointer) as ManagerFactory; + } + + pointer = getPrototypeOf(pointer); + } + + return; +} + +export function valueForCapturedArgs(args: CapturedArguments): ManagerArgs { + return { + named: args.named.value(), + positional: args.positional.value(), + }; +} + +export interface ManagerArgs { + named: Dict; + positional: Opaque[]; +}