-
Notifications
You must be signed in to change notification settings - Fork 418
/
binding_observer.ts
95 lines (78 loc) · 2.51 KB
/
binding_observer.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
import { Action } from "./action"
import { Binding } from "./binding"
import { Context } from "./context"
import { ErrorHandler } from "./error_handler"
import { Schema } from "./schema"
import { Token, ValueListObserver, ValueListObserverDelegate } from "../mutation-observers"
export interface BindingObserverDelegate extends ErrorHandler {
bindingConnected(binding: Binding): void
bindingDisconnected(binding: Binding, clearEventListeners?: boolean): void
}
export class BindingObserver implements ValueListObserverDelegate<Action> {
readonly context: Context
private delegate: BindingObserverDelegate
private valueListObserver?: ValueListObserver<Action>
private bindingsByAction: Map<Action, Binding>
constructor(context: Context, delegate: BindingObserverDelegate) {
this.context = context
this.delegate = delegate
this.bindingsByAction = new Map()
}
start() {
if (!this.valueListObserver) {
this.valueListObserver = new ValueListObserver(this.element, this.actionAttribute, this)
this.valueListObserver.start()
}
}
stop() {
if (this.valueListObserver) {
this.valueListObserver.stop()
delete this.valueListObserver
this.disconnectAllActions()
}
}
get element() {
return this.context.element
}
get identifier() {
return this.context.identifier
}
get actionAttribute() {
return this.schema.actionAttribute
}
get schema(): Schema {
return this.context.schema
}
get bindings(): Binding[] {
return Array.from(this.bindingsByAction.values())
}
private connectAction(action: Action) {
const binding = new Binding(this.context, action)
this.bindingsByAction.set(action, binding)
this.delegate.bindingConnected(binding)
}
private disconnectAction(action: Action) {
const binding = this.bindingsByAction.get(action)
if (binding) {
this.bindingsByAction.delete(action)
this.delegate.bindingDisconnected(binding)
}
}
private disconnectAllActions() {
this.bindings.forEach((binding) => this.delegate.bindingDisconnected(binding, true))
this.bindingsByAction.clear()
}
// Value observer delegate
parseValueForToken(token: Token): Action | undefined {
const action = Action.forToken(token, this.context)
if (action.identifier == this.identifier) {
return action
}
}
elementMatchedValue(element: Element, action: Action) {
this.connectAction(action)
}
elementUnmatchedValue(element: Element, action: Action) {
this.disconnectAction(action)
}
}