-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
custom.ts
109 lines (95 loc) · 3.25 KB
/
custom.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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();