-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6d57f74
commit 64eadfe
Showing
7 changed files
with
363 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
packages/@ember/-internals/glimmer/lib/modifiers/custom.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { Factory } from '@ember/-internals/owner'; | ||
import { Dict, Opaque } from '@glimmer/interfaces'; | ||
import { Tag } from '@glimmer/reference'; | ||
import { Arguments, CapturedArguments, ModifierManager } from '@glimmer/runtime'; | ||
|
||
export interface CustomModifierDefinitionState<ModifierInstance> { | ||
ModifierClass: Factory<ModifierInstance>; | ||
name: string; | ||
delegate: ModifierManagerDelegate<ModifierInstance>; | ||
} | ||
|
||
// Currently there are no capabilities for modifiers | ||
export function capabilities() { | ||
return {}; | ||
} | ||
|
||
export class CustomModifierDefinition<ModifierInstance> { | ||
public state: CustomModifierDefinitionState<ModifierInstance>; | ||
public manager = CUSTOM_MODIFIER_MANAGER; | ||
constructor( | ||
public name: string, | ||
ModifierClass: Factory<ModifierInstance>, | ||
public delegate: ModifierManagerDelegate<ModifierInstance> | ||
) { | ||
this.state = { | ||
ModifierClass, | ||
name, | ||
delegate, | ||
}; | ||
} | ||
} | ||
|
||
export class CustomModifierState<ModifierInstance> { | ||
constructor( | ||
public element: Element, | ||
public delegate: ModifierManagerDelegate<ModifierInstance>, | ||
public modifier: ModifierInstance, | ||
public args: CapturedArguments | ||
) {} | ||
|
||
destroy() { | ||
const { delegate, modifier, args } = this; | ||
let modifierArgs = valueForCapturedArgs(args); | ||
delegate.destroyModifier(modifier, modifierArgs); | ||
} | ||
} | ||
|
||
export interface CustomModifierManagerArgs { | ||
named: Dict<Opaque>; | ||
positional: Opaque[]; | ||
} | ||
|
||
export interface ModifierManagerDelegate<ModifierInstance> { | ||
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(), | ||
}; | ||
} | ||
|
||
class CustomModifierManager<ModifierInstance> | ||
implements | ||
ModifierManager< | ||
CustomModifierState<ModifierInstance>, | ||
CustomModifierDefinitionState<ModifierInstance> | ||
> { | ||
create( | ||
element: Element, | ||
definition: CustomModifierDefinitionState<ModifierInstance>, | ||
args: Arguments | ||
) { | ||
const capturedArgs = args.capture(); | ||
let modifierArgs = valueForCapturedArgs(capturedArgs); | ||
let instance = definition.delegate.createModifier(definition.ModifierClass, modifierArgs); | ||
return new CustomModifierState(element, definition.delegate, instance, capturedArgs); | ||
} | ||
|
||
getTag({ args }: CustomModifierState<ModifierInstance>): Tag { | ||
return args.tag; | ||
} | ||
|
||
install(state: CustomModifierState<ModifierInstance>) { | ||
let { element, args, delegate, modifier } = state; | ||
let modifierArgs = valueForCapturedArgs(args); | ||
delegate.installModifier(modifier, element, modifierArgs); | ||
} | ||
|
||
update(state: CustomModifierState<ModifierInstance>) { | ||
let { args, delegate, modifier } = state; | ||
let modifierArgs = valueForCapturedArgs(args); | ||
delegate.updateModifier(modifier, modifierArgs); | ||
} | ||
|
||
getDestructor(state: CustomModifierState<ModifierInstance>) { | ||
return state; | ||
} | ||
} | ||
|
||
const CUSTOM_MODIFIER_MANAGER = new CustomModifierManager(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
packages/@ember/-internals/glimmer/lib/utils/custom-modifier-manager.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Owner } from '@ember/-internals/owner'; | ||
import { GLIMMER_MODIFIER_MANAGER } from '@ember/canary-features'; | ||
import { Opaque } from '@glimmer/util'; | ||
import { ModifierManagerDelegate } from '../modifiers/custom'; | ||
|
||
const getPrototypeOf = Object.getPrototypeOf; | ||
|
||
export type ModifierManagerFactory = (owner: Owner) => ModifierManagerDelegate<Opaque>; | ||
|
||
const MANAGERS: WeakMap<any, ModifierManagerFactory> = new WeakMap(); | ||
|
||
export function setModifierManager(factory: ModifierManagerFactory, obj: any) { | ||
MANAGERS.set(obj, factory); | ||
return obj; | ||
} | ||
|
||
export function getModifierManager(obj: any): undefined | ModifierManagerFactory { | ||
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; | ||
} |
Oops, something went wrong.