-
-
Notifications
You must be signed in to change notification settings - Fork 147
/
binding-behavior.ts
72 lines (59 loc) · 3.05 KB
/
binding-behavior.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
import {
Class,
Constructable,
IContainer,
IResourceDefinition,
IResourceKind,
IResourceType,
Registration,
Writable
} from '@aurelia/kernel';
import { LifecycleFlags } from '../flags';
import { IBinding } from '../lifecycle';
import { IScope } from '../observation';
export interface IBindingBehavior {
bind(flags: LifecycleFlags, scope: IScope, binding: IBinding): void;
unbind(flags: LifecycleFlags, scope: IScope, binding: IBinding): void;
}
export interface IBindingBehaviorDefinition extends IResourceDefinition { }
export interface IBindingBehaviorType<C extends Constructable = Constructable> extends IResourceType<IBindingBehaviorDefinition, InstanceType<C> & IBindingBehavior> { }
export interface IBindingBehaviorResource extends
IResourceKind<IBindingBehaviorDefinition, IBindingBehavior, Class<IBindingBehavior>> {
}
function register(this: IBindingBehaviorType, container: IContainer): void {
const resourceKey = BindingBehaviorResource.keyFrom(this.description.name);
container.register(Registration.singleton(resourceKey, this));
}
export function bindingBehavior(definition: IBindingBehaviorDefinition): BindingBehaviorDecorator;
export function bindingBehavior(name: string): BindingBehaviorDecorator;
export function bindingBehavior(nameOrDefinition: string | IBindingBehaviorDefinition): BindingBehaviorDecorator;
export function bindingBehavior(nameOrDefinition: string | IBindingBehaviorDefinition): BindingBehaviorDecorator {
return target => BindingBehaviorResource.define(nameOrDefinition, target);
}
function keyFrom(this: IBindingBehaviorResource, name: string): string {
return `${this.name}:${name}`;
}
function isType<T>(this: IBindingBehaviorResource, Type: T & Partial<IBindingBehaviorType>): Type is T & IBindingBehaviorType {
return Type.kind === this;
}
function define<T extends Constructable = Constructable>(this: IBindingBehaviorResource, definition: IBindingBehaviorDefinition, ctor: T): T & IBindingBehaviorType<T>;
function define<T extends Constructable = Constructable>(this: IBindingBehaviorResource, name: string, ctor: T): T & IBindingBehaviorType<T>;
function define<T extends Constructable = Constructable>(this: IBindingBehaviorResource, nameOrDefinition: string | IBindingBehaviorDefinition, ctor: T): T & IBindingBehaviorType<T>;
function define<T extends Constructable = Constructable>(this: IBindingBehaviorResource, nameOrDefinition: string | IBindingBehaviorDefinition, ctor: T): T & IBindingBehaviorType<T> {
const Type = ctor as T & IBindingBehaviorType<T>;
const WritableType = Type as T & Writable<IBindingBehaviorType<T>>;
const description = typeof nameOrDefinition === 'string'
? { name: nameOrDefinition }
: nameOrDefinition;
WritableType.kind = BindingBehaviorResource as IBindingBehaviorResource;
WritableType.description = description;
Type.register = register;
return Type;
}
export const BindingBehaviorResource = {
name: 'binding-behavior',
keyFrom,
isType,
define
};
export type BindingBehaviorDecorator = <T extends Constructable>(target: T) => T & IBindingBehaviorType<T>;