@microsoft/fast-element 1.10.2 → 2.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +1 -12
- package/CHANGELOG.json +387 -1
- package/CHANGELOG.md +74 -2
- package/README.md +2 -2
- package/dist/dts/components/attributes.d.ts +4 -1
- package/dist/dts/components/controller.d.ts +12 -11
- package/dist/dts/components/fast-definitions.d.ts +10 -2
- package/dist/dts/components/fast-element.d.ts +12 -5
- package/dist/dts/context.d.ts +157 -0
- package/dist/dts/debug.d.ts +1 -0
- package/dist/dts/hooks.d.ts +20 -0
- package/dist/dts/index.d.ts +16 -15
- package/dist/dts/index.debug.d.ts +2 -0
- package/dist/dts/index.rollup.d.ts +2 -0
- package/dist/dts/index.rollup.debug.d.ts +3 -0
- package/dist/dts/interfaces.d.ts +145 -0
- package/dist/dts/metadata.d.ts +25 -0
- package/dist/dts/observation/arrays.d.ts +207 -0
- package/dist/dts/observation/behavior.d.ts +4 -4
- package/dist/dts/observation/notifier.d.ts +18 -18
- package/dist/dts/observation/observable.d.ts +56 -18
- package/dist/dts/observation/splice-strategies.d.ts +13 -0
- package/dist/dts/observation/update-queue.d.ts +40 -0
- package/dist/dts/platform.d.ts +18 -67
- package/dist/dts/polyfills.d.ts +8 -0
- package/dist/dts/styles/css-directive.d.ts +43 -5
- package/dist/dts/styles/css.d.ts +19 -3
- package/dist/dts/styles/element-styles.d.ts +42 -62
- package/dist/dts/templating/binding-signal.d.ts +38 -0
- package/dist/dts/templating/binding-two-way.d.ts +56 -0
- package/dist/dts/templating/binding.d.ts +233 -65
- package/dist/dts/templating/children.d.ts +18 -15
- package/dist/dts/templating/compiler.d.ts +46 -28
- package/dist/dts/templating/dom.d.ts +41 -0
- package/dist/dts/templating/html-directive.d.ts +181 -43
- package/dist/dts/templating/markup.d.ts +48 -0
- package/dist/dts/templating/node-observation.d.ts +45 -29
- package/dist/dts/templating/ref.d.ts +6 -12
- package/dist/dts/templating/repeat.d.ts +26 -14
- package/dist/dts/templating/slotted.d.ts +13 -14
- package/dist/dts/templating/template.d.ts +27 -21
- package/dist/dts/templating/view.d.ts +15 -22
- package/dist/{tsdoc-metadata.json → dts/tsdoc-metadata.json} +1 -1
- package/dist/dts/utilities.d.ts +40 -0
- package/dist/esm/components/attributes.js +25 -24
- package/dist/esm/components/controller.js +77 -57
- package/dist/esm/components/fast-definitions.js +16 -22
- package/dist/esm/components/fast-element.js +10 -2
- package/dist/esm/context.js +159 -0
- package/dist/esm/debug.js +30 -0
- package/dist/esm/hooks.js +32 -0
- package/dist/esm/index.debug.js +2 -0
- package/dist/esm/index.js +19 -14
- package/dist/esm/index.rollup.debug.js +3 -0
- package/dist/esm/index.rollup.js +2 -0
- package/dist/esm/interfaces.js +8 -1
- package/dist/esm/metadata.js +60 -0
- package/dist/esm/observation/arrays.js +269 -0
- package/dist/esm/observation/notifier.js +27 -35
- package/dist/esm/observation/observable.js +93 -68
- package/dist/esm/observation/{array-change-records.js → splice-strategies.js} +136 -62
- package/dist/esm/observation/update-queue.js +67 -0
- package/dist/esm/platform.js +36 -42
- package/dist/esm/polyfills.js +85 -0
- package/dist/esm/styles/css-directive.js +29 -13
- package/dist/esm/styles/css.js +27 -40
- package/dist/esm/styles/element-styles.js +65 -104
- package/dist/esm/templating/binding-signal.js +84 -0
- package/dist/esm/templating/binding-two-way.js +82 -0
- package/dist/esm/templating/binding.js +306 -153
- package/dist/esm/templating/children.js +33 -23
- package/dist/esm/templating/compiler.js +236 -152
- package/dist/esm/templating/dom.js +49 -0
- package/dist/esm/templating/html-directive.js +128 -40
- package/dist/esm/templating/markup.js +75 -0
- package/dist/esm/templating/node-observation.js +50 -45
- package/dist/esm/templating/ref.js +7 -16
- package/dist/esm/templating/repeat.js +39 -36
- package/dist/esm/templating/slotted.js +23 -20
- package/dist/esm/templating/template.js +51 -95
- package/dist/esm/templating/view.js +44 -43
- package/dist/esm/templating/when.js +2 -1
- package/dist/esm/utilities.js +139 -0
- package/dist/fast-element.api.json +11789 -5377
- package/dist/fast-element.d.ts +1178 -530
- package/dist/fast-element.debug.js +3722 -0
- package/dist/fast-element.debug.min.js +1 -0
- package/dist/fast-element.js +3484 -4033
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +2699 -0
- package/docs/api-report.md +472 -219
- package/docs/fast-element-2-changes.md +15 -0
- package/docs/guide/declaring-templates.md +4 -4
- package/docs/guide/defining-elements.md +2 -2
- package/docs/guide/next-steps.md +2 -2
- package/docs/guide/observables-and-state.md +1 -1
- package/docs/guide/using-directives.md +1 -1
- package/karma.conf.cjs +6 -17
- package/package.json +63 -15
- package/dist/dts/dom.d.ts +0 -112
- package/dist/dts/observation/array-change-records.d.ts +0 -48
- package/dist/dts/observation/array-observer.d.ts +0 -9
- package/dist/esm/dom.js +0 -207
- package/dist/esm/observation/array-observer.js +0 -177
|
@@ -1,46 +1,113 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "../interfaces.js";
|
|
2
2
|
import { ExecutionContext, Observable, } from "../observation/observable.js";
|
|
3
|
-
import {
|
|
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
|
-
|
|
3
|
+
import { FAST } from "../platform.js";
|
|
4
|
+
import { DOM } from "./dom.js";
|
|
5
|
+
import { Aspect, HTMLDirective, } from "./html-directive.js";
|
|
6
|
+
import { Markup } from "./markup.js";
|
|
7
|
+
const createInnerHTMLBinding = globalThis.TrustedHTML
|
|
8
|
+
? (binding) => (s, c) => {
|
|
9
|
+
const value = binding(s, c);
|
|
10
|
+
if (value instanceof TrustedHTML) {
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
throw FAST.error(1202 /* Message.bindingInnerHTMLRequiresTrustedTypes */);
|
|
14
|
+
}
|
|
15
|
+
: (binding) => binding;
|
|
16
|
+
/**
|
|
17
|
+
* Describes how aspects of an HTML element will be affected by bindings.
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export const BindingMode = Object.freeze({
|
|
21
|
+
/**
|
|
22
|
+
* Creates a binding mode based on the supplied behavior types.
|
|
23
|
+
* @param UpdateType - The base behavior type used to update aspects.
|
|
24
|
+
* @param EventType - The base behavior type used to respond to events.
|
|
25
|
+
* @returns A new binding mode.
|
|
26
|
+
*/
|
|
27
|
+
define(UpdateType, EventType = EventBinding) {
|
|
28
|
+
return Object.freeze({
|
|
29
|
+
[1]: d => new UpdateType(d, DOM.setAttribute),
|
|
30
|
+
[2]: d => new UpdateType(d, DOM.setBooleanAttribute),
|
|
31
|
+
[3]: d => new UpdateType(d, (t, a, v) => (t[a] = v)),
|
|
32
|
+
[4]: d => new (createContentBinding(UpdateType))(d, updateContentTarget),
|
|
33
|
+
[5]: d => new UpdateType(d, updateTokenListTarget),
|
|
34
|
+
[6]: d => new EventType(d),
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* Describes the configuration for a binding expression.
|
|
40
|
+
* @public
|
|
41
|
+
*/
|
|
42
|
+
export const BindingConfig = Object.freeze({
|
|
43
|
+
/**
|
|
44
|
+
* Creates a binding configuration based on the provided mode and options.
|
|
45
|
+
* @param mode - The mode to use for the configuration.
|
|
46
|
+
* @param defaultOptions - The default options to use for the configuration.
|
|
47
|
+
* @returns A new binding configuration.
|
|
48
|
+
*/
|
|
49
|
+
define(mode, defaultOptions) {
|
|
50
|
+
const config = (options) => {
|
|
51
|
+
return {
|
|
52
|
+
mode: config.mode,
|
|
53
|
+
options: Object.assign({}, defaultOptions, options),
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
config.options = defaultOptions;
|
|
57
|
+
config.mode = mode;
|
|
58
|
+
return config;
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* A base binding behavior for DOM updates.
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export class UpdateBinding {
|
|
66
|
+
/**
|
|
67
|
+
* Creates an instance of UpdateBinding.
|
|
68
|
+
* @param directive - The directive that has the configuration for this behavior.
|
|
69
|
+
* @param updateTarget - The function used to update the target with the latest value.
|
|
70
|
+
*/
|
|
71
|
+
constructor(directive, updateTarget) {
|
|
72
|
+
this.directive = directive;
|
|
73
|
+
this.updateTarget = updateTarget;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Bind this behavior to the source.
|
|
77
|
+
* @param source - The source to bind to.
|
|
78
|
+
* @param context - The execution context that the binding is operating within.
|
|
79
|
+
* @param targets - The targets that behaviors in a view can attach to.
|
|
80
|
+
*/
|
|
81
|
+
bind(source, context, targets) { }
|
|
82
|
+
/**
|
|
83
|
+
* Unbinds this behavior from the source.
|
|
84
|
+
* @param source - The source to unbind from.
|
|
85
|
+
* @param context - The execution context that the binding is operating within.
|
|
86
|
+
* @param targets - The targets that behaviors in a view can attach to.
|
|
87
|
+
*/
|
|
88
|
+
unbind(source, context, targets) { }
|
|
89
|
+
/**
|
|
90
|
+
* Creates a behavior.
|
|
91
|
+
* @param targets - The targets available for behaviors to be attached to.
|
|
92
|
+
*/
|
|
93
|
+
createBehavior(targets) {
|
|
94
|
+
return this;
|
|
30
95
|
}
|
|
31
96
|
}
|
|
32
|
-
function
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
97
|
+
function createContentBinding(Type) {
|
|
98
|
+
return class extends Type {
|
|
99
|
+
unbind(source, context, targets) {
|
|
100
|
+
super.unbind(source, context, targets);
|
|
101
|
+
const target = targets[this.directive.nodeId];
|
|
102
|
+
const view = target.$fastView;
|
|
103
|
+
if (view !== void 0 && view.isComposed) {
|
|
104
|
+
view.unbind();
|
|
105
|
+
view.needsBindOnly = true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
42
109
|
}
|
|
43
|
-
function updateContentTarget(value) {
|
|
110
|
+
function updateContentTarget(target, aspect, value, source, context) {
|
|
44
111
|
// If there's no actual value, then this equates to the
|
|
45
112
|
// empty string for the purposes of content bindings.
|
|
46
113
|
if (value === null || value === undefined) {
|
|
@@ -48,8 +115,8 @@ function updateContentTarget(value) {
|
|
|
48
115
|
}
|
|
49
116
|
// If the value has a "create" method, then it's a template-like.
|
|
50
117
|
if (value.create) {
|
|
51
|
-
|
|
52
|
-
let view =
|
|
118
|
+
target.textContent = "";
|
|
119
|
+
let view = target.$fastView;
|
|
53
120
|
// If there's no previous view that we might be able to
|
|
54
121
|
// reuse then create a new view from the template.
|
|
55
122
|
if (view === void 0) {
|
|
@@ -60,7 +127,7 @@ function updateContentTarget(value) {
|
|
|
60
127
|
// from the same template as the new value, then we
|
|
61
128
|
// need to remove the old view if it's still in the DOM
|
|
62
129
|
// and create a new view from the template.
|
|
63
|
-
if (
|
|
130
|
+
if (target.$fastTemplate !== value) {
|
|
64
131
|
if (view.isComposed) {
|
|
65
132
|
view.remove();
|
|
66
133
|
view.unbind();
|
|
@@ -72,18 +139,18 @@ function updateContentTarget(value) {
|
|
|
72
139
|
// and that there's actually no need to compose it.
|
|
73
140
|
if (!view.isComposed) {
|
|
74
141
|
view.isComposed = true;
|
|
75
|
-
view.bind(
|
|
76
|
-
view.insertBefore(
|
|
77
|
-
|
|
78
|
-
|
|
142
|
+
view.bind(source, context);
|
|
143
|
+
view.insertBefore(target);
|
|
144
|
+
target.$fastView = view;
|
|
145
|
+
target.$fastTemplate = value;
|
|
79
146
|
}
|
|
80
147
|
else if (view.needsBindOnly) {
|
|
81
148
|
view.needsBindOnly = false;
|
|
82
|
-
view.bind(
|
|
149
|
+
view.bind(source, context);
|
|
83
150
|
}
|
|
84
151
|
}
|
|
85
152
|
else {
|
|
86
|
-
const view =
|
|
153
|
+
const view = target.$fastView;
|
|
87
154
|
// If there is a view and it's currently composed into
|
|
88
155
|
// the DOM, then we need to remove it.
|
|
89
156
|
if (view !== void 0 && view.isComposed) {
|
|
@@ -96,16 +163,17 @@ function updateContentTarget(value) {
|
|
|
96
163
|
view.unbind();
|
|
97
164
|
}
|
|
98
165
|
}
|
|
99
|
-
|
|
166
|
+
target.textContent = value;
|
|
100
167
|
}
|
|
101
168
|
}
|
|
102
|
-
function
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
let
|
|
169
|
+
function updateTokenListTarget(target, aspect, value) {
|
|
170
|
+
var _a;
|
|
171
|
+
const directive = this.directive;
|
|
172
|
+
const lookup = `${directive.id}-t`;
|
|
173
|
+
const state = (_a = target[lookup]) !== null && _a !== void 0 ? _a : (target[lookup] = { c: 0, v: Object.create(null) });
|
|
174
|
+
const versions = state.v;
|
|
175
|
+
let currentVersion = state.c;
|
|
176
|
+
const tokenList = target[aspect];
|
|
109
177
|
// Add the classes, tracking the version at which they were added.
|
|
110
178
|
if (value !== null && value !== undefined && value.length) {
|
|
111
179
|
const names = value.split(/\s+/);
|
|
@@ -114,139 +182,224 @@ function updateClassTarget(value) {
|
|
|
114
182
|
if (currentName === "") {
|
|
115
183
|
continue;
|
|
116
184
|
}
|
|
117
|
-
|
|
118
|
-
|
|
185
|
+
versions[currentName] = currentVersion;
|
|
186
|
+
tokenList.add(currentName);
|
|
119
187
|
}
|
|
120
188
|
}
|
|
121
|
-
|
|
122
|
-
this.version = version + 1;
|
|
189
|
+
state.v = currentVersion + 1;
|
|
123
190
|
// If this is the first call to add classes, there's no need to remove old ones.
|
|
124
|
-
if (
|
|
191
|
+
if (currentVersion === 0) {
|
|
125
192
|
return;
|
|
126
193
|
}
|
|
127
194
|
// Remove classes from the previous version.
|
|
128
|
-
|
|
129
|
-
for (const name in
|
|
130
|
-
if (
|
|
131
|
-
|
|
195
|
+
currentVersion -= 1;
|
|
196
|
+
for (const name in versions) {
|
|
197
|
+
if (versions[name] === currentVersion) {
|
|
198
|
+
tokenList.remove(name);
|
|
132
199
|
}
|
|
133
200
|
}
|
|
134
201
|
}
|
|
135
202
|
/**
|
|
136
|
-
* A
|
|
203
|
+
* A binding behavior for one-time bindings.
|
|
137
204
|
* @public
|
|
138
205
|
*/
|
|
139
|
-
export class
|
|
206
|
+
export class OneTimeBinding extends UpdateBinding {
|
|
140
207
|
/**
|
|
141
|
-
*
|
|
142
|
-
* @param
|
|
208
|
+
* Bind this behavior to the source.
|
|
209
|
+
* @param source - The source to bind to.
|
|
210
|
+
* @param context - The execution context that the binding is operating within.
|
|
211
|
+
* @param targets - The targets that behaviors in a view can attach to.
|
|
143
212
|
*/
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
this.binding
|
|
147
|
-
this.bind = normalBind;
|
|
148
|
-
this.unbind = normalUnbind;
|
|
149
|
-
this.updateTarget = updateAttributeTarget;
|
|
150
|
-
this.isBindingVolatile = Observable.isVolatileBinding(this.binding);
|
|
213
|
+
bind(source, context, targets) {
|
|
214
|
+
const directive = this.directive;
|
|
215
|
+
this.updateTarget(targets[directive.nodeId], directive.targetAspect, directive.binding(source, context), source, context);
|
|
151
216
|
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* A binding behavior for bindings that change.
|
|
220
|
+
* @public
|
|
221
|
+
*/
|
|
222
|
+
export class ChangeBinding extends UpdateBinding {
|
|
152
223
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
224
|
+
* Creates an instance of ChangeBinding.
|
|
225
|
+
* @param directive - The directive that has the configuration for this behavior.
|
|
226
|
+
* @param updateTarget - The function used to update the target with the latest value.
|
|
155
227
|
*/
|
|
156
|
-
|
|
157
|
-
|
|
228
|
+
constructor(directive, updateTarget) {
|
|
229
|
+
super(directive, updateTarget);
|
|
230
|
+
this.isBindingVolatile = Observable.isVolatileBinding(directive.binding);
|
|
231
|
+
this.observerProperty = `${directive.id}-o`;
|
|
158
232
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
this.updateTarget = updatePropertyTarget;
|
|
168
|
-
if (this.cleanedTargetName === "innerHTML") {
|
|
169
|
-
const binding = this.binding;
|
|
170
|
-
this.binding = (s, c) => DOM.createHTML(binding(s, c));
|
|
171
|
-
}
|
|
172
|
-
break;
|
|
173
|
-
case "?":
|
|
174
|
-
this.cleanedTargetName = value.substr(1);
|
|
175
|
-
this.updateTarget = updateBooleanAttributeTarget;
|
|
176
|
-
break;
|
|
177
|
-
case "@":
|
|
178
|
-
this.cleanedTargetName = value.substr(1);
|
|
179
|
-
this.bind = triggerBind;
|
|
180
|
-
this.unbind = triggerUnbind;
|
|
181
|
-
break;
|
|
182
|
-
default:
|
|
183
|
-
this.cleanedTargetName = value;
|
|
184
|
-
if (value === "class") {
|
|
185
|
-
this.updateTarget = updateClassTarget;
|
|
186
|
-
}
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
233
|
+
/**
|
|
234
|
+
* Returns the binding observer used to update the node.
|
|
235
|
+
* @param target - The target node.
|
|
236
|
+
* @returns A BindingObserver.
|
|
237
|
+
*/
|
|
238
|
+
getObserver(target) {
|
|
239
|
+
var _a;
|
|
240
|
+
return ((_a = target[this.observerProperty]) !== null && _a !== void 0 ? _a : (target[this.observerProperty] = Observable.binding(this.directive.binding, this, this.isBindingVolatile)));
|
|
189
241
|
}
|
|
190
242
|
/**
|
|
191
|
-
*
|
|
192
|
-
*
|
|
243
|
+
* Bind this behavior to the source.
|
|
244
|
+
* @param source - The source to bind to.
|
|
245
|
+
* @param context - The execution context that the binding is operating within.
|
|
246
|
+
* @param targets - The targets that behaviors in a view can attach to.
|
|
193
247
|
*/
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
248
|
+
bind(source, context, targets) {
|
|
249
|
+
const directive = this.directive;
|
|
250
|
+
const target = targets[directive.nodeId];
|
|
251
|
+
const observer = this.getObserver(target);
|
|
252
|
+
observer.target = target;
|
|
253
|
+
observer.source = source;
|
|
254
|
+
observer.context = context;
|
|
255
|
+
this.updateTarget(target, directive.targetAspect, observer.observe(source, context), source, context);
|
|
197
256
|
}
|
|
198
257
|
/**
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* @param
|
|
258
|
+
* Unbinds this behavior from the source.
|
|
259
|
+
* @param source - The source to unbind from.
|
|
260
|
+
* @param context - The execution context that the binding is operating within.
|
|
261
|
+
* @param targets - The targets that behaviors in a view can attach to.
|
|
202
262
|
*/
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
263
|
+
unbind(source, context, targets) {
|
|
264
|
+
const target = targets[this.directive.nodeId];
|
|
265
|
+
const observer = this.getObserver(target);
|
|
266
|
+
observer.dispose();
|
|
267
|
+
observer.target = null;
|
|
268
|
+
observer.source = null;
|
|
269
|
+
observer.context = null;
|
|
270
|
+
}
|
|
271
|
+
/** @internal */
|
|
272
|
+
handleChange(binding, observer) {
|
|
273
|
+
const target = observer.target;
|
|
274
|
+
const source = observer.source;
|
|
275
|
+
const context = observer.context;
|
|
276
|
+
this.updateTarget(target, this.directive.targetAspect, observer.observe(source, context), source, context);
|
|
206
277
|
}
|
|
207
278
|
}
|
|
208
279
|
/**
|
|
209
|
-
* A behavior
|
|
210
|
-
* BindingDirective.
|
|
280
|
+
* A binding behavior for handling events.
|
|
211
281
|
* @public
|
|
212
282
|
*/
|
|
213
|
-
export class
|
|
214
|
-
/**
|
|
215
|
-
* Creates an instance of
|
|
216
|
-
* @param
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
* @param targetName - The name of the target attribute or property to update.
|
|
223
|
-
*/
|
|
224
|
-
constructor(target, binding, isBindingVolatile, bind, unbind, updateTarget, targetName) {
|
|
225
|
-
/** @internal */
|
|
226
|
-
this.source = null;
|
|
227
|
-
/** @internal */
|
|
228
|
-
this.context = null;
|
|
229
|
-
/** @internal */
|
|
230
|
-
this.bindingObserver = null;
|
|
231
|
-
this.target = target;
|
|
232
|
-
this.binding = binding;
|
|
233
|
-
this.isBindingVolatile = isBindingVolatile;
|
|
234
|
-
this.bind = bind;
|
|
235
|
-
this.unbind = unbind;
|
|
236
|
-
this.updateTarget = updateTarget;
|
|
237
|
-
this.targetName = targetName;
|
|
283
|
+
export class EventBinding {
|
|
284
|
+
/**
|
|
285
|
+
* Creates an instance of EventBinding.
|
|
286
|
+
* @param directive - The directive that has the configuration for this behavior.
|
|
287
|
+
*/
|
|
288
|
+
constructor(directive) {
|
|
289
|
+
this.directive = directive;
|
|
290
|
+
this.sourceProperty = `${directive.id}-s`;
|
|
291
|
+
this.contextProperty = `${directive.id}-c`;
|
|
238
292
|
}
|
|
239
|
-
/**
|
|
240
|
-
|
|
241
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Bind this behavior to the source.
|
|
295
|
+
* @param source - The source to bind to.
|
|
296
|
+
* @param context - The execution context that the binding is operating within.
|
|
297
|
+
* @param targets - The targets that behaviors in a view can attach to.
|
|
298
|
+
*/
|
|
299
|
+
bind(source, context, targets) {
|
|
300
|
+
const directive = this.directive;
|
|
301
|
+
const target = targets[directive.nodeId];
|
|
302
|
+
target[this.sourceProperty] = source;
|
|
303
|
+
target[this.contextProperty] = context;
|
|
304
|
+
target.addEventListener(directive.targetAspect, this, directive.options);
|
|
242
305
|
}
|
|
243
|
-
/**
|
|
306
|
+
/**
|
|
307
|
+
* Unbinds this behavior from the source.
|
|
308
|
+
* @param source - The source to unbind from.
|
|
309
|
+
* @param context - The execution context that the binding is operating within.
|
|
310
|
+
* @param targets - The targets that behaviors in a view can attach to.
|
|
311
|
+
*/
|
|
312
|
+
unbind(source, context, targets) {
|
|
313
|
+
const directive = this.directive;
|
|
314
|
+
const target = targets[directive.nodeId];
|
|
315
|
+
target[this.sourceProperty] = target[this.contextProperty] = null;
|
|
316
|
+
target.removeEventListener(directive.targetAspect, this, directive.options);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Creates a behavior.
|
|
320
|
+
* @param targets - The targets available for behaviors to be attached to.
|
|
321
|
+
*/
|
|
322
|
+
createBehavior(targets) {
|
|
323
|
+
return this;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* @internal
|
|
327
|
+
*/
|
|
244
328
|
handleEvent(event) {
|
|
329
|
+
const target = event.currentTarget;
|
|
245
330
|
ExecutionContext.setEvent(event);
|
|
246
|
-
const result = this.binding(this.
|
|
331
|
+
const result = this.directive.binding(target[this.sourceProperty], target[this.contextProperty]);
|
|
247
332
|
ExecutionContext.setEvent(null);
|
|
248
333
|
if (result !== true) {
|
|
249
334
|
event.preventDefault();
|
|
250
335
|
}
|
|
251
336
|
}
|
|
252
337
|
}
|
|
338
|
+
/**
|
|
339
|
+
* The default onChange binding configuration.
|
|
340
|
+
* @public
|
|
341
|
+
*/
|
|
342
|
+
export const onChange = BindingConfig.define(BindingMode.define(ChangeBinding), {});
|
|
343
|
+
/**
|
|
344
|
+
* The default onTime binding configuration.
|
|
345
|
+
* @public
|
|
346
|
+
*/
|
|
347
|
+
export const oneTime = BindingConfig.define(BindingMode.define(OneTimeBinding), {
|
|
348
|
+
once: true,
|
|
349
|
+
});
|
|
350
|
+
/**
|
|
351
|
+
* A directive that applies bindings.
|
|
352
|
+
* @public
|
|
353
|
+
*/
|
|
354
|
+
export class HTMLBindingDirective {
|
|
355
|
+
/**
|
|
356
|
+
* Creates an instance of HTMLBindingDirective.
|
|
357
|
+
* @param binding - The binding to apply.
|
|
358
|
+
* @param mode - The binding mode to use when applying the binding.
|
|
359
|
+
* @param options - The options to configure the binding with.
|
|
360
|
+
*/
|
|
361
|
+
constructor(binding, mode, options) {
|
|
362
|
+
this.binding = binding;
|
|
363
|
+
this.mode = mode;
|
|
364
|
+
this.options = options;
|
|
365
|
+
this.factory = null;
|
|
366
|
+
/**
|
|
367
|
+
* The type of aspect to target.
|
|
368
|
+
*/
|
|
369
|
+
this.aspectType = Aspect.content;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Creates HTML to be used within a template.
|
|
373
|
+
* @param add - Can be used to add behavior factories to a template.
|
|
374
|
+
*/
|
|
375
|
+
createHTML(add) {
|
|
376
|
+
return Markup.interpolation(add(this));
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Creates a behavior.
|
|
380
|
+
* @param targets - The targets available for behaviors to be attached to.
|
|
381
|
+
*/
|
|
382
|
+
createBehavior(targets) {
|
|
383
|
+
if (this.factory == null) {
|
|
384
|
+
if (this.targetAspect === "innerHTML") {
|
|
385
|
+
this.binding = createInnerHTMLBinding(this.binding);
|
|
386
|
+
}
|
|
387
|
+
this.factory = this.mode[this.aspectType](this);
|
|
388
|
+
}
|
|
389
|
+
return this.factory.createBehavior(targets);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
HTMLDirective.define(HTMLBindingDirective, { aspected: true });
|
|
393
|
+
/**
|
|
394
|
+
* Creates a binding directive with the specified configuration.
|
|
395
|
+
* @param binding - The binding expression.
|
|
396
|
+
* @param config - The binding configuration.
|
|
397
|
+
* @returns A binding directive.
|
|
398
|
+
* @public
|
|
399
|
+
*/
|
|
400
|
+
export function bind(binding, config = onChange) {
|
|
401
|
+
if (!("mode" in config)) {
|
|
402
|
+
config = onChange(config);
|
|
403
|
+
}
|
|
404
|
+
return new HTMLBindingDirective(binding, config.mode, config.options);
|
|
405
|
+
}
|
|
@@ -1,45 +1,55 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isString } from "../interfaces.js";
|
|
2
|
+
import { HTMLDirective } from "./html-directive.js";
|
|
3
|
+
import { NodeObservationDirective } from "./node-observation.js";
|
|
3
4
|
/**
|
|
4
5
|
* The runtime behavior for child node observation.
|
|
5
6
|
* @public
|
|
6
7
|
*/
|
|
7
|
-
export class
|
|
8
|
+
export class ChildrenDirective extends NodeObservationDirective {
|
|
8
9
|
/**
|
|
9
|
-
* Creates an instance of
|
|
10
|
-
* @param
|
|
11
|
-
* @param options - The options to use when observing the element children.
|
|
10
|
+
* Creates an instance of ChildrenDirective.
|
|
11
|
+
* @param options - The options to use in configuring the child observation behavior.
|
|
12
12
|
*/
|
|
13
|
-
constructor(
|
|
14
|
-
super(
|
|
15
|
-
this.
|
|
13
|
+
constructor(options) {
|
|
14
|
+
super(options);
|
|
15
|
+
this.observerProperty = `${this.id}-o`;
|
|
16
|
+
this.handleEvent = (mutations, observer) => {
|
|
17
|
+
const target = observer.target;
|
|
18
|
+
this.updateTarget(this.getSource(target), this.computeNodes(target));
|
|
19
|
+
};
|
|
16
20
|
options.childList = true;
|
|
17
21
|
}
|
|
18
22
|
/**
|
|
19
23
|
* Begins observation of the nodes.
|
|
24
|
+
* @param target - The target to observe.
|
|
20
25
|
*/
|
|
21
|
-
observe() {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
observe(target) {
|
|
27
|
+
var _a;
|
|
28
|
+
const observer = (_a = target[this.observerProperty]) !== null && _a !== void 0 ? _a : (target[this.observerProperty] = new MutationObserver(this.handleEvent));
|
|
29
|
+
observer.target = target;
|
|
30
|
+
observer.observe(target, this.options);
|
|
26
31
|
}
|
|
27
32
|
/**
|
|
28
33
|
* Disconnects observation of the nodes.
|
|
34
|
+
* @param target - The target to unobserve.
|
|
29
35
|
*/
|
|
30
|
-
disconnect() {
|
|
31
|
-
this.
|
|
36
|
+
disconnect(target) {
|
|
37
|
+
const observer = target[this.observerProperty];
|
|
38
|
+
observer.target = null;
|
|
39
|
+
observer.disconnect();
|
|
32
40
|
}
|
|
33
41
|
/**
|
|
34
|
-
* Retrieves the nodes that should be assigned to the
|
|
42
|
+
* Retrieves the raw nodes that should be assigned to the source property.
|
|
43
|
+
* @param target - The target to get the node to.
|
|
35
44
|
*/
|
|
36
|
-
getNodes() {
|
|
37
|
-
if ("
|
|
38
|
-
return Array.from(
|
|
45
|
+
getNodes(target) {
|
|
46
|
+
if ("selector" in this.options) {
|
|
47
|
+
return Array.from(target.querySelectorAll(this.options.selector));
|
|
39
48
|
}
|
|
40
|
-
return Array.from(
|
|
49
|
+
return Array.from(target.childNodes);
|
|
41
50
|
}
|
|
42
51
|
}
|
|
52
|
+
HTMLDirective.define(ChildrenDirective);
|
|
43
53
|
/**
|
|
44
54
|
* A directive that observes the `childNodes` of an element and updates a property
|
|
45
55
|
* whenever they change.
|
|
@@ -47,10 +57,10 @@ export class ChildrenBehavior extends NodeObservationBehavior {
|
|
|
47
57
|
* @public
|
|
48
58
|
*/
|
|
49
59
|
export function children(propertyOrOptions) {
|
|
50
|
-
if (
|
|
60
|
+
if (isString(propertyOrOptions)) {
|
|
51
61
|
propertyOrOptions = {
|
|
52
62
|
property: propertyOrOptions,
|
|
53
63
|
};
|
|
54
64
|
}
|
|
55
|
-
return new
|
|
65
|
+
return new ChildrenDirective(propertyOrOptions);
|
|
56
66
|
}
|