@microsoft/fast-element 1.10.5 → 2.0.0-beta.10
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 +629 -6
- package/CHANGELOG.md +152 -5
- package/dist/dts/components/attributes.d.ts +14 -1
- package/dist/dts/components/{controller.d.ts → element-controller.d.ts} +32 -32
- package/dist/dts/components/fast-definitions.d.ts +51 -11
- package/dist/dts/components/fast-element.d.ts +18 -23
- package/dist/dts/context.d.ts +157 -0
- package/dist/{esm/observation/behavior.js → dts/debug.d.ts} +0 -0
- package/dist/dts/di/di.d.ts +899 -0
- package/dist/dts/index.d.ts +17 -16
- 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 +176 -0
- package/dist/dts/metadata.d.ts +25 -0
- package/dist/dts/observation/arrays.d.ts +207 -0
- package/dist/dts/observation/notifier.d.ts +18 -18
- package/dist/dts/observation/observable.d.ts +117 -34
- package/dist/dts/observation/update-queue.d.ts +40 -0
- package/dist/dts/pending-task.d.ts +20 -0
- package/dist/dts/platform.d.ts +23 -66
- package/dist/dts/polyfills.d.ts +8 -0
- package/dist/dts/state/exports.d.ts +3 -0
- package/dist/dts/state/reactive.d.ts +8 -0
- package/dist/dts/state/state.d.ts +141 -0
- package/dist/dts/state/visitor.d.ts +6 -0
- package/dist/dts/state/watch.d.ts +10 -0
- package/dist/dts/styles/css-directive.d.ts +44 -6
- package/dist/dts/styles/css.d.ts +19 -3
- package/dist/dts/styles/element-styles.d.ts +49 -63
- package/dist/dts/styles/host.d.ts +68 -0
- package/dist/dts/templating/binding-signal.d.ts +21 -0
- package/dist/dts/templating/binding-two-way.d.ts +39 -0
- package/dist/dts/templating/binding.d.ts +101 -70
- 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 +239 -45
- package/dist/dts/templating/markup.d.ts +48 -0
- package/dist/dts/templating/node-observation.d.ts +45 -30
- package/dist/dts/templating/ref.d.ts +6 -20
- package/dist/dts/templating/render.d.ts +272 -0
- package/dist/dts/templating/repeat.d.ts +36 -33
- package/dist/dts/templating/slotted.d.ts +13 -14
- package/dist/dts/templating/template.d.ts +28 -22
- package/dist/dts/templating/view.d.ts +82 -24
- package/dist/dts/templating/when.d.ts +3 -3
- package/dist/dts/testing/exports.d.ts +3 -0
- package/dist/dts/testing/fakes.d.ts +4 -0
- package/dist/dts/testing/fixture.d.ts +84 -0
- package/dist/dts/testing/timeout.d.ts +7 -0
- package/dist/{tsdoc-metadata.json → dts/tsdoc-metadata.json} +1 -1
- package/dist/dts/utilities.d.ts +22 -0
- package/dist/esm/components/attributes.js +38 -28
- package/dist/esm/components/{controller.js → element-controller.js} +150 -140
- package/dist/esm/components/fast-definitions.js +48 -46
- package/dist/esm/components/fast-element.js +31 -12
- package/dist/esm/context.js +163 -0
- package/dist/esm/debug.js +61 -0
- package/dist/esm/di/di.js +1435 -0
- package/dist/esm/index.debug.js +2 -0
- package/dist/esm/index.js +20 -14
- package/dist/esm/index.rollup.debug.js +3 -0
- package/dist/esm/index.rollup.js +2 -0
- package/dist/esm/interfaces.js +12 -1
- package/dist/esm/metadata.js +60 -0
- package/dist/esm/observation/arrays.js +570 -0
- package/dist/esm/observation/notifier.js +27 -35
- package/dist/esm/observation/observable.js +116 -149
- package/dist/esm/observation/update-queue.js +67 -0
- package/dist/esm/pending-task.js +16 -0
- package/dist/esm/platform.js +60 -42
- package/dist/esm/polyfills.js +85 -0
- package/dist/esm/state/exports.js +3 -0
- package/dist/esm/state/reactive.js +34 -0
- package/dist/esm/state/state.js +148 -0
- package/dist/esm/state/visitor.js +28 -0
- package/dist/esm/state/watch.js +36 -0
- package/dist/esm/styles/css-directive.js +29 -13
- package/dist/esm/styles/css.js +29 -42
- package/dist/esm/styles/element-styles.js +79 -104
- package/dist/esm/styles/host.js +1 -0
- package/dist/esm/templating/binding-signal.js +83 -0
- package/dist/esm/templating/binding-two-way.js +103 -0
- package/dist/esm/templating/binding.js +189 -159
- package/dist/esm/templating/children.js +33 -23
- package/dist/esm/templating/compiler.js +258 -152
- package/dist/esm/templating/dom.js +49 -0
- package/dist/esm/templating/html-directive.js +193 -36
- package/dist/esm/templating/markup.js +75 -0
- package/dist/esm/templating/node-observation.js +51 -45
- package/dist/esm/templating/ref.js +8 -25
- package/dist/esm/templating/render.js +391 -0
- package/dist/esm/templating/repeat.js +83 -79
- package/dist/esm/templating/slotted.js +23 -20
- package/dist/esm/templating/template.js +51 -93
- package/dist/esm/templating/view.js +125 -46
- package/dist/esm/templating/when.js +6 -4
- package/dist/esm/testing/exports.js +3 -0
- package/dist/esm/testing/fakes.js +76 -0
- package/dist/esm/testing/fixture.js +86 -0
- package/dist/esm/testing/timeout.js +24 -0
- package/dist/esm/utilities.js +44 -0
- package/dist/fast-element.api.json +12153 -5373
- package/dist/fast-element.d.ts +1448 -696
- package/dist/fast-element.debug.js +4107 -0
- package/dist/fast-element.debug.min.js +1 -0
- package/dist/fast-element.js +3817 -4029
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +2814 -0
- package/docs/api-report.md +567 -254
- package/docs/fast-element-2-changes.md +15 -0
- package/karma.conf.cjs +6 -17
- package/package.json +76 -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/dts/observation/behavior.d.ts +0 -19
- package/dist/esm/dom.js +0 -207
- package/dist/esm/observation/array-change-records.js +0 -326
- package/dist/esm/observation/array-observer.js +0 -177
|
@@ -1,55 +1,41 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isFunction } from "../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
|
-
this.source = null;
|
|
20
|
-
this.context = null;
|
|
21
|
-
}
|
|
22
|
-
function contentUnbind() {
|
|
23
|
-
this.bindingObserver.disconnect();
|
|
24
|
-
this.source = null;
|
|
25
|
-
this.context = null;
|
|
26
|
-
const view = this.target.$fastView;
|
|
27
|
-
if (view !== void 0 && view.isComposed) {
|
|
28
|
-
view.unbind();
|
|
29
|
-
view.needsBindOnly = true;
|
|
3
|
+
import { FAST } from "../platform.js";
|
|
4
|
+
import { DOM } from "./dom.js";
|
|
5
|
+
import { Aspect, Binding, HTMLDirective, } from "./html-directive.js";
|
|
6
|
+
import { Markup, nextId } 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
|
+
class OnChangeBinding extends Binding {
|
|
17
|
+
createObserver(_, subscriber) {
|
|
18
|
+
return Observable.binding(this.evaluate, subscriber, this.isVolatile);
|
|
30
19
|
}
|
|
31
20
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
function updateBooleanAttributeTarget(value) {
|
|
41
|
-
DOM.setBooleanAttribute(this.target, this.targetName, value);
|
|
21
|
+
class OneTimeBinding extends Binding {
|
|
22
|
+
createObserver() {
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
bind(controller) {
|
|
26
|
+
return this.evaluate(controller.source, controller.context);
|
|
27
|
+
}
|
|
42
28
|
}
|
|
43
|
-
function
|
|
29
|
+
function updateContent(target, aspect, value, controller) {
|
|
44
30
|
// If there's no actual value, then this equates to the
|
|
45
31
|
// empty string for the purposes of content bindings.
|
|
46
32
|
if (value === null || value === undefined) {
|
|
47
33
|
value = "";
|
|
48
34
|
}
|
|
49
|
-
// If the value has a "create" method, then it's a
|
|
35
|
+
// If the value has a "create" method, then it's a ContentTemplate.
|
|
50
36
|
if (value.create) {
|
|
51
|
-
|
|
52
|
-
let view =
|
|
37
|
+
target.textContent = "";
|
|
38
|
+
let view = target.$fastView;
|
|
53
39
|
// If there's no previous view that we might be able to
|
|
54
40
|
// reuse then create a new view from the template.
|
|
55
41
|
if (view === void 0) {
|
|
@@ -60,7 +46,7 @@ function updateContentTarget(value) {
|
|
|
60
46
|
// from the same template as the new value, then we
|
|
61
47
|
// need to remove the old view if it's still in the DOM
|
|
62
48
|
// and create a new view from the template.
|
|
63
|
-
if (
|
|
49
|
+
if (target.$fastTemplate !== value) {
|
|
64
50
|
if (view.isComposed) {
|
|
65
51
|
view.remove();
|
|
66
52
|
view.unbind();
|
|
@@ -72,18 +58,18 @@ function updateContentTarget(value) {
|
|
|
72
58
|
// and that there's actually no need to compose it.
|
|
73
59
|
if (!view.isComposed) {
|
|
74
60
|
view.isComposed = true;
|
|
75
|
-
view.bind(
|
|
76
|
-
view.insertBefore(
|
|
77
|
-
|
|
78
|
-
|
|
61
|
+
view.bind(controller.source, controller.context);
|
|
62
|
+
view.insertBefore(target);
|
|
63
|
+
target.$fastView = view;
|
|
64
|
+
target.$fastTemplate = value;
|
|
79
65
|
}
|
|
80
66
|
else if (view.needsBindOnly) {
|
|
81
67
|
view.needsBindOnly = false;
|
|
82
|
-
view.bind(
|
|
68
|
+
view.bind(controller.source, controller.context);
|
|
83
69
|
}
|
|
84
70
|
}
|
|
85
71
|
else {
|
|
86
|
-
const view =
|
|
72
|
+
const view = target.$fastView;
|
|
87
73
|
// If there is a view and it's currently composed into
|
|
88
74
|
// the DOM, then we need to remove it.
|
|
89
75
|
if (view !== void 0 && view.isComposed) {
|
|
@@ -96,16 +82,16 @@ function updateContentTarget(value) {
|
|
|
96
82
|
view.unbind();
|
|
97
83
|
}
|
|
98
84
|
}
|
|
99
|
-
|
|
85
|
+
target.textContent = value;
|
|
100
86
|
}
|
|
101
87
|
}
|
|
102
|
-
function
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
88
|
+
function updateTokenList(target, aspect, value) {
|
|
89
|
+
var _a;
|
|
90
|
+
const lookup = `${this.id}-t`;
|
|
91
|
+
const state = (_a = target[lookup]) !== null && _a !== void 0 ? _a : (target[lookup] = { c: 0, v: Object.create(null) });
|
|
92
|
+
const versions = state.v;
|
|
93
|
+
let currentVersion = state.c;
|
|
94
|
+
const tokenList = target[aspect];
|
|
109
95
|
// Add the classes, tracking the version at which they were added.
|
|
110
96
|
if (value !== null && value !== undefined && value.length) {
|
|
111
97
|
const names = value.split(/\s+/);
|
|
@@ -114,139 +100,183 @@ function updateClassTarget(value) {
|
|
|
114
100
|
if (currentName === "") {
|
|
115
101
|
continue;
|
|
116
102
|
}
|
|
117
|
-
|
|
118
|
-
|
|
103
|
+
versions[currentName] = currentVersion;
|
|
104
|
+
tokenList.add(currentName);
|
|
119
105
|
}
|
|
120
106
|
}
|
|
121
|
-
|
|
122
|
-
this.version = version + 1;
|
|
107
|
+
state.v = currentVersion + 1;
|
|
123
108
|
// If this is the first call to add classes, there's no need to remove old ones.
|
|
124
|
-
if (
|
|
109
|
+
if (currentVersion === 0) {
|
|
125
110
|
return;
|
|
126
111
|
}
|
|
127
112
|
// Remove classes from the previous version.
|
|
128
|
-
|
|
129
|
-
for (const name in
|
|
130
|
-
if (
|
|
131
|
-
|
|
113
|
+
currentVersion -= 1;
|
|
114
|
+
for (const name in versions) {
|
|
115
|
+
if (versions[name] === currentVersion) {
|
|
116
|
+
tokenList.remove(name);
|
|
132
117
|
}
|
|
133
118
|
}
|
|
134
119
|
}
|
|
120
|
+
const setProperty = (t, a, v) => (t[a] = v);
|
|
121
|
+
const eventTarget = () => void 0;
|
|
135
122
|
/**
|
|
136
|
-
* A directive that
|
|
123
|
+
* A directive that applies bindings.
|
|
137
124
|
* @public
|
|
138
125
|
*/
|
|
139
|
-
export class HTMLBindingDirective
|
|
126
|
+
export class HTMLBindingDirective {
|
|
140
127
|
/**
|
|
141
|
-
* Creates an instance of
|
|
142
|
-
* @param
|
|
128
|
+
* Creates an instance of HTMLBindingDirective.
|
|
129
|
+
* @param dataBinding - The binding configuration to apply.
|
|
143
130
|
*/
|
|
144
|
-
constructor(
|
|
145
|
-
|
|
146
|
-
this.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
this.
|
|
131
|
+
constructor(dataBinding) {
|
|
132
|
+
this.dataBinding = dataBinding;
|
|
133
|
+
this.updateTarget = null;
|
|
134
|
+
/**
|
|
135
|
+
* The unique id of the factory.
|
|
136
|
+
*/
|
|
137
|
+
this.id = nextId();
|
|
138
|
+
/**
|
|
139
|
+
* The type of aspect to target.
|
|
140
|
+
*/
|
|
141
|
+
this.aspectType = Aspect.content;
|
|
142
|
+
/** @internal */
|
|
143
|
+
this.bind = this.bindDefault;
|
|
144
|
+
this.data = `${this.id}-d`;
|
|
151
145
|
}
|
|
152
146
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
147
|
+
* Creates HTML to be used within a template.
|
|
148
|
+
* @param add - Can be used to add behavior factories to a template.
|
|
155
149
|
*/
|
|
156
|
-
|
|
157
|
-
return this
|
|
158
|
-
}
|
|
159
|
-
set targetName(value) {
|
|
160
|
-
this.originalTargetName = value;
|
|
161
|
-
if (value === void 0) {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
switch (value[0]) {
|
|
165
|
-
case ":":
|
|
166
|
-
this.cleanedTargetName = value.substr(1);
|
|
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
|
-
}
|
|
150
|
+
createHTML(add) {
|
|
151
|
+
return Markup.interpolation(add(this));
|
|
189
152
|
}
|
|
190
153
|
/**
|
|
191
|
-
*
|
|
192
|
-
* a particular attribute or property.
|
|
154
|
+
* Creates a behavior.
|
|
193
155
|
*/
|
|
194
|
-
|
|
195
|
-
this.updateTarget
|
|
196
|
-
|
|
156
|
+
createBehavior() {
|
|
157
|
+
if (this.updateTarget === null) {
|
|
158
|
+
if (this.targetAspect === "innerHTML") {
|
|
159
|
+
this.dataBinding.evaluate = createInnerHTMLBinding(this.dataBinding.evaluate);
|
|
160
|
+
}
|
|
161
|
+
switch (this.aspectType) {
|
|
162
|
+
case 1:
|
|
163
|
+
this.updateTarget = DOM.setAttribute;
|
|
164
|
+
break;
|
|
165
|
+
case 2:
|
|
166
|
+
this.updateTarget = DOM.setBooleanAttribute;
|
|
167
|
+
break;
|
|
168
|
+
case 3:
|
|
169
|
+
this.updateTarget = setProperty;
|
|
170
|
+
break;
|
|
171
|
+
case 4:
|
|
172
|
+
this.bind = this.bindContent;
|
|
173
|
+
this.updateTarget = updateContent;
|
|
174
|
+
break;
|
|
175
|
+
case 5:
|
|
176
|
+
this.updateTarget = updateTokenList;
|
|
177
|
+
break;
|
|
178
|
+
case 6:
|
|
179
|
+
this.bind = this.bindEvent;
|
|
180
|
+
this.updateTarget = eventTarget;
|
|
181
|
+
break;
|
|
182
|
+
default:
|
|
183
|
+
throw FAST.error(1205 /* Message.unsupportedBindingBehavior */);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return this;
|
|
197
187
|
}
|
|
198
|
-
/**
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
188
|
+
/** @internal */
|
|
189
|
+
bindDefault(controller) {
|
|
190
|
+
var _a;
|
|
191
|
+
const target = controller.targets[this.nodeId];
|
|
192
|
+
const observer = (_a = target[this.data]) !== null && _a !== void 0 ? _a : (target[this.data] = this.dataBinding.createObserver(this, this));
|
|
193
|
+
observer.target = target;
|
|
194
|
+
observer.controller = controller;
|
|
195
|
+
this.updateTarget(target, this.targetAspect, observer.bind(controller), controller);
|
|
196
|
+
if (this.updateTarget === updateContent) {
|
|
197
|
+
controller.onUnbind(this);
|
|
198
|
+
}
|
|
206
199
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
*/
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
* @param binding - The binding that returns the latest value for an update.
|
|
218
|
-
* @param isBindingVolatile - Indicates whether the binding has volatile dependencies.
|
|
219
|
-
* @param bind - The operation to perform during binding.
|
|
220
|
-
* @param unbind - The operation to perform during unbinding.
|
|
221
|
-
* @param updateTarget - The operation to perform when updating.
|
|
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;
|
|
200
|
+
/** @internal */
|
|
201
|
+
bindContent(controller) {
|
|
202
|
+
this.bindDefault(controller);
|
|
203
|
+
controller.onUnbind(this);
|
|
204
|
+
}
|
|
205
|
+
/** @internal */
|
|
206
|
+
bindEvent(controller) {
|
|
207
|
+
const target = controller.targets[this.nodeId];
|
|
208
|
+
target[this.data] = controller;
|
|
209
|
+
target.addEventListener(this.targetAspect, this, this.dataBinding.options);
|
|
238
210
|
}
|
|
239
211
|
/** @internal */
|
|
240
|
-
|
|
241
|
-
|
|
212
|
+
unbind(controller) {
|
|
213
|
+
const target = controller.targets[this.nodeId];
|
|
214
|
+
const view = target.$fastView;
|
|
215
|
+
if (view !== void 0 && view.isComposed) {
|
|
216
|
+
view.unbind();
|
|
217
|
+
view.needsBindOnly = true;
|
|
218
|
+
}
|
|
242
219
|
}
|
|
243
220
|
/** @internal */
|
|
244
221
|
handleEvent(event) {
|
|
222
|
+
const target = event.currentTarget;
|
|
245
223
|
ExecutionContext.setEvent(event);
|
|
246
|
-
const
|
|
224
|
+
const controller = target[this.data];
|
|
225
|
+
const result = this.dataBinding.evaluate(controller.source, controller.context);
|
|
247
226
|
ExecutionContext.setEvent(null);
|
|
248
227
|
if (result !== true) {
|
|
249
228
|
event.preventDefault();
|
|
250
229
|
}
|
|
251
230
|
}
|
|
231
|
+
/** @internal */
|
|
232
|
+
handleChange(binding, observer) {
|
|
233
|
+
const target = observer.target;
|
|
234
|
+
const controller = observer.controller;
|
|
235
|
+
this.updateTarget(target, this.targetAspect, observer.bind(controller), controller);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
HTMLDirective.define(HTMLBindingDirective, { aspected: true });
|
|
239
|
+
/**
|
|
240
|
+
* Creates an standard binding.
|
|
241
|
+
* @param binding - The binding to refresh when changed.
|
|
242
|
+
* @param isVolatile - Indicates whether the binding is volatile or not.
|
|
243
|
+
* @returns A binding configuration.
|
|
244
|
+
* @public
|
|
245
|
+
*/
|
|
246
|
+
export function bind(binding, isVolatile = Observable.isVolatileBinding(binding)) {
|
|
247
|
+
return new OnChangeBinding(binding, isVolatile);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Creates a one time binding
|
|
251
|
+
* @param binding - The binding to refresh when signaled.
|
|
252
|
+
* @returns A binding configuration.
|
|
253
|
+
* @public
|
|
254
|
+
*/
|
|
255
|
+
export function oneTime(binding) {
|
|
256
|
+
return new OneTimeBinding(binding);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Creates an event listener binding.
|
|
260
|
+
* @param binding - The binding to invoke when the event is raised.
|
|
261
|
+
* @param options - Event listener options.
|
|
262
|
+
* @returns A binding configuration.
|
|
263
|
+
* @public
|
|
264
|
+
*/
|
|
265
|
+
export function listener(binding, options) {
|
|
266
|
+
const config = new OnChangeBinding(binding, false);
|
|
267
|
+
config.options = options;
|
|
268
|
+
return config;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Normalizes the input value into a binding.
|
|
272
|
+
* @param value - The value to create the default binding for.
|
|
273
|
+
* @returns A binding configuration for the provided value.
|
|
274
|
+
* @public
|
|
275
|
+
*/
|
|
276
|
+
export function normalizeBinding(value) {
|
|
277
|
+
return isFunction(value)
|
|
278
|
+
? bind(value)
|
|
279
|
+
: value instanceof Binding
|
|
280
|
+
? value
|
|
281
|
+
: oneTime(() => value);
|
|
252
282
|
}
|
|
@@ -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
|
}
|