@microsoft/fast-element 2.0.0-beta.6 → 2.0.0-beta.7
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/CHANGELOG.json +57 -0
- package/CHANGELOG.md +16 -1
- package/dist/dts/components/attributes.d.ts +10 -0
- package/dist/dts/components/{controller.d.ts → element-controller.d.ts} +24 -25
- package/dist/dts/components/fast-definitions.d.ts +28 -3
- package/dist/dts/components/fast-element.d.ts +2 -2
- package/dist/dts/di/di.d.ts +41 -0
- package/dist/dts/index.d.ts +2 -2
- package/dist/dts/observation/observable.d.ts +86 -47
- package/dist/dts/pending-task.d.ts +20 -0
- package/dist/dts/platform.d.ts +6 -0
- package/dist/dts/styles/css-directive.d.ts +2 -2
- package/dist/dts/styles/element-styles.d.ts +3 -3
- package/dist/dts/styles/host.d.ts +68 -0
- package/dist/dts/templating/binding-signal.d.ts +2 -2
- package/dist/dts/templating/binding-two-way.d.ts +11 -3
- package/dist/dts/templating/binding.d.ts +21 -119
- package/dist/dts/templating/children.d.ts +1 -1
- package/dist/dts/templating/html-directive.d.ts +69 -39
- package/dist/dts/templating/node-observation.d.ts +4 -5
- package/dist/dts/templating/ref.d.ts +5 -13
- package/dist/dts/templating/render.d.ts +15 -20
- package/dist/dts/templating/repeat.d.ts +11 -16
- package/dist/dts/templating/slotted.d.ts +1 -1
- package/dist/dts/templating/template.d.ts +4 -4
- package/dist/dts/templating/view.d.ts +68 -9
- package/dist/dts/templating/when.d.ts +1 -1
- package/dist/dts/testing/exports.d.ts +1 -0
- package/dist/dts/testing/fakes.d.ts +4 -0
- package/dist/dts/testing/fixture.d.ts +0 -6
- package/dist/esm/components/attributes.js +13 -4
- package/dist/esm/components/{controller.js → element-controller.js} +95 -105
- package/dist/esm/components/fast-definitions.js +3 -1
- package/dist/esm/components/fast-element.js +4 -4
- package/dist/esm/di/di.js +87 -3
- package/dist/esm/index.js +2 -1
- package/dist/esm/observation/observable.js +59 -126
- package/dist/esm/pending-task.js +16 -0
- package/dist/esm/platform.js +21 -0
- package/dist/esm/styles/css.js +4 -4
- package/dist/esm/{observation/behavior.js → styles/host.js} +0 -0
- package/dist/esm/templating/binding-signal.js +21 -17
- package/dist/esm/templating/binding-two-way.js +32 -27
- package/dist/esm/templating/binding.js +73 -177
- package/dist/esm/templating/html-directive.js +78 -7
- package/dist/esm/templating/node-observation.js +9 -8
- package/dist/esm/templating/ref.js +4 -12
- package/dist/esm/templating/render.js +30 -31
- package/dist/esm/templating/repeat.js +37 -38
- package/dist/esm/templating/template.js +3 -4
- package/dist/esm/templating/view.js +96 -24
- package/dist/esm/testing/exports.js +1 -0
- package/dist/esm/testing/fakes.js +76 -0
- package/dist/esm/testing/fixture.js +1 -3
- package/dist/fast-element.api.json +5720 -5385
- package/dist/fast-element.d.ts +510 -399
- package/dist/fast-element.debug.js +492 -509
- package/dist/fast-element.debug.min.js +1 -1
- package/dist/fast-element.js +492 -509
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +519 -405
- package/docs/api-report.md +197 -129
- package/package.json +5 -1
- package/dist/dts/observation/behavior.d.ts +0 -19
|
@@ -14,29 +14,19 @@ const createInnerHTMLBinding = globalThis.TrustedHTML
|
|
|
14
14
|
}
|
|
15
15
|
: (binding) => binding;
|
|
16
16
|
class OnChangeBinding extends Binding {
|
|
17
|
-
constructor(evaluate, isVolatile) {
|
|
18
|
-
super();
|
|
19
|
-
this.evaluate = evaluate;
|
|
20
|
-
this.isVolatile = isVolatile;
|
|
21
|
-
}
|
|
22
17
|
createObserver(_, subscriber) {
|
|
23
18
|
return Observable.binding(this.evaluate, subscriber, this.isVolatile);
|
|
24
19
|
}
|
|
25
20
|
}
|
|
26
21
|
class OneTimeBinding extends Binding {
|
|
27
|
-
constructor(evaluate) {
|
|
28
|
-
super();
|
|
29
|
-
this.evaluate = evaluate;
|
|
30
|
-
}
|
|
31
22
|
createObserver() {
|
|
32
23
|
return this;
|
|
33
24
|
}
|
|
34
|
-
|
|
35
|
-
return this.evaluate(source, context);
|
|
25
|
+
bind(controller) {
|
|
26
|
+
return this.evaluate(controller.source, controller.context);
|
|
36
27
|
}
|
|
37
|
-
dispose() { }
|
|
38
28
|
}
|
|
39
|
-
function
|
|
29
|
+
function updateContent(target, aspect, value, controller) {
|
|
40
30
|
// If there's no actual value, then this equates to the
|
|
41
31
|
// empty string for the purposes of content bindings.
|
|
42
32
|
if (value === null || value === undefined) {
|
|
@@ -68,14 +58,14 @@ function updateContentTarget(target, aspect, value, source, context) {
|
|
|
68
58
|
// and that there's actually no need to compose it.
|
|
69
59
|
if (!view.isComposed) {
|
|
70
60
|
view.isComposed = true;
|
|
71
|
-
view.bind(source
|
|
61
|
+
view.bind(controller.source);
|
|
72
62
|
view.insertBefore(target);
|
|
73
63
|
target.$fastView = view;
|
|
74
64
|
target.$fastTemplate = value;
|
|
75
65
|
}
|
|
76
66
|
else if (view.needsBindOnly) {
|
|
77
67
|
view.needsBindOnly = false;
|
|
78
|
-
view.bind(source
|
|
68
|
+
view.bind(controller.source);
|
|
79
69
|
}
|
|
80
70
|
}
|
|
81
71
|
else {
|
|
@@ -95,10 +85,9 @@ function updateContentTarget(target, aspect, value, source, context) {
|
|
|
95
85
|
target.textContent = value;
|
|
96
86
|
}
|
|
97
87
|
}
|
|
98
|
-
function
|
|
88
|
+
function updateTokenList(target, aspect, value) {
|
|
99
89
|
var _a;
|
|
100
|
-
const
|
|
101
|
-
const lookup = `${directive.id}-t`;
|
|
90
|
+
const lookup = `${this.id}-t`;
|
|
102
91
|
const state = (_a = target[lookup]) !== null && _a !== void 0 ? _a : (target[lookup] = { c: 0, v: Object.create(null) });
|
|
103
92
|
const versions = state.v;
|
|
104
93
|
let currentVersion = state.c;
|
|
@@ -128,154 +117,8 @@ function updateTokenListTarget(target, aspect, value) {
|
|
|
128
117
|
}
|
|
129
118
|
}
|
|
130
119
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
* @public
|
|
134
|
-
*/
|
|
135
|
-
export class BindingBehavior {
|
|
136
|
-
/**
|
|
137
|
-
* Creates an instance of ChangeBinding.
|
|
138
|
-
* @param directive - The directive that has the configuration for this behavior.
|
|
139
|
-
* @param updateTarget - The function used to update the target with the latest value.
|
|
140
|
-
*/
|
|
141
|
-
constructor(directive, updateTarget) {
|
|
142
|
-
this.directive = directive;
|
|
143
|
-
this.updateTarget = updateTarget;
|
|
144
|
-
this.observerProperty = `${directive.id}-o`;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Bind this behavior to the source.
|
|
148
|
-
* @param source - The source to bind to.
|
|
149
|
-
* @param context - The execution context that the binding is operating within.
|
|
150
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
151
|
-
*/
|
|
152
|
-
bind(source, context, targets) {
|
|
153
|
-
const directive = this.directive;
|
|
154
|
-
const target = targets[directive.nodeId];
|
|
155
|
-
const observer = this.getObserver(target);
|
|
156
|
-
observer.target = target;
|
|
157
|
-
observer.source = source;
|
|
158
|
-
observer.context = context;
|
|
159
|
-
this.updateTarget(target, directive.targetAspect, observer.observe(source, context), source, context);
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Unbinds this behavior from the source.
|
|
163
|
-
* @param source - The source to unbind from.
|
|
164
|
-
* @param context - The execution context that the binding is operating within.
|
|
165
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
166
|
-
*/
|
|
167
|
-
unbind(source, context, targets) {
|
|
168
|
-
const target = targets[this.directive.nodeId];
|
|
169
|
-
const observer = this.getObserver(target);
|
|
170
|
-
observer.dispose();
|
|
171
|
-
observer.target = null;
|
|
172
|
-
observer.source = null;
|
|
173
|
-
observer.context = null;
|
|
174
|
-
}
|
|
175
|
-
/** @internal */
|
|
176
|
-
handleChange(binding, observer) {
|
|
177
|
-
const target = observer.target;
|
|
178
|
-
const source = observer.source;
|
|
179
|
-
const context = observer.context;
|
|
180
|
-
this.updateTarget(target, this.directive.targetAspect, observer.observe(source, context), source, context);
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Returns the binding observer used to update the node.
|
|
184
|
-
* @param target - The target node.
|
|
185
|
-
* @returns A BindingObserver.
|
|
186
|
-
*/
|
|
187
|
-
getObserver(target) {
|
|
188
|
-
var _a;
|
|
189
|
-
return ((_a = target[this.observerProperty]) !== null && _a !== void 0 ? _a : (target[this.observerProperty] = this.directive.dataBinding.createObserver(this.directive, this)));
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Creates a behavior.
|
|
193
|
-
* @param targets - The targets available for behaviors to be attached to.
|
|
194
|
-
*/
|
|
195
|
-
createBehavior(targets) {
|
|
196
|
-
return this;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* A special binding behavior that can bind node content.
|
|
201
|
-
* @public
|
|
202
|
-
*/
|
|
203
|
-
export class ContentBehavior extends BindingBehavior {
|
|
204
|
-
/**
|
|
205
|
-
* Unbinds this behavior from the source.
|
|
206
|
-
* @param source - The source to unbind from.
|
|
207
|
-
* @param context - The execution context that the binding is operating within.
|
|
208
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
209
|
-
*/
|
|
210
|
-
unbind(source, context, targets) {
|
|
211
|
-
super.unbind(source, context, targets);
|
|
212
|
-
const target = targets[this.directive.nodeId];
|
|
213
|
-
const view = target.$fastView;
|
|
214
|
-
if (view !== void 0 && view.isComposed) {
|
|
215
|
-
view.unbind();
|
|
216
|
-
view.needsBindOnly = true;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* A binding behavior for handling events.
|
|
222
|
-
* @public
|
|
223
|
-
*/
|
|
224
|
-
export class EventBehavior {
|
|
225
|
-
/**
|
|
226
|
-
* Creates an instance of EventBinding.
|
|
227
|
-
* @param directive - The directive that has the configuration for this behavior.
|
|
228
|
-
*/
|
|
229
|
-
constructor(directive) {
|
|
230
|
-
this.directive = directive;
|
|
231
|
-
this.sourceProperty = `${directive.id}-s`;
|
|
232
|
-
this.contextProperty = `${directive.id}-c`;
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Bind this behavior to the source.
|
|
236
|
-
* @param source - The source to bind to.
|
|
237
|
-
* @param context - The execution context that the binding is operating within.
|
|
238
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
239
|
-
*/
|
|
240
|
-
bind(source, context, targets) {
|
|
241
|
-
const directive = this.directive;
|
|
242
|
-
const target = targets[directive.nodeId];
|
|
243
|
-
target[this.sourceProperty] = source;
|
|
244
|
-
target[this.contextProperty] = context;
|
|
245
|
-
target.addEventListener(directive.targetAspect, this, directive.dataBinding.options);
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Unbinds this behavior from the source.
|
|
249
|
-
* @param source - The source to unbind from.
|
|
250
|
-
* @param context - The execution context that the binding is operating within.
|
|
251
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
252
|
-
*/
|
|
253
|
-
unbind(source, context, targets) {
|
|
254
|
-
const directive = this.directive;
|
|
255
|
-
const target = targets[directive.nodeId];
|
|
256
|
-
target[this.sourceProperty] = target[this.contextProperty] = null;
|
|
257
|
-
target.removeEventListener(directive.targetAspect, this, directive.dataBinding.options);
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Creates a behavior.
|
|
261
|
-
* @param targets - The targets available for behaviors to be attached to.
|
|
262
|
-
*/
|
|
263
|
-
createBehavior(targets) {
|
|
264
|
-
return this;
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* @internal
|
|
268
|
-
*/
|
|
269
|
-
handleEvent(event) {
|
|
270
|
-
const target = event.currentTarget;
|
|
271
|
-
ExecutionContext.setEvent(event);
|
|
272
|
-
const result = this.directive.dataBinding.evaluate(target[this.sourceProperty], target[this.contextProperty]);
|
|
273
|
-
ExecutionContext.setEvent(null);
|
|
274
|
-
if (result !== true) {
|
|
275
|
-
event.preventDefault();
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
120
|
+
const setProperty = (t, a, v) => (t[a] = v);
|
|
121
|
+
const eventTarget = () => void 0;
|
|
279
122
|
/**
|
|
280
123
|
* A directive that applies bindings.
|
|
281
124
|
* @public
|
|
@@ -287,7 +130,7 @@ export class HTMLBindingDirective {
|
|
|
287
130
|
*/
|
|
288
131
|
constructor(dataBinding) {
|
|
289
132
|
this.dataBinding = dataBinding;
|
|
290
|
-
this.
|
|
133
|
+
this.updateTarget = null;
|
|
291
134
|
/**
|
|
292
135
|
* The unique id of the factory.
|
|
293
136
|
*/
|
|
@@ -296,6 +139,9 @@ export class HTMLBindingDirective {
|
|
|
296
139
|
* The type of aspect to target.
|
|
297
140
|
*/
|
|
298
141
|
this.aspectType = Aspect.content;
|
|
142
|
+
/** @internal */
|
|
143
|
+
this.bind = this.bindDefault;
|
|
144
|
+
this.data = `${this.id}-d`;
|
|
299
145
|
}
|
|
300
146
|
/**
|
|
301
147
|
* Creates HTML to be used within a template.
|
|
@@ -306,37 +152,87 @@ export class HTMLBindingDirective {
|
|
|
306
152
|
}
|
|
307
153
|
/**
|
|
308
154
|
* Creates a behavior.
|
|
309
|
-
* @param targets - The targets available for behaviors to be attached to.
|
|
310
155
|
*/
|
|
311
|
-
createBehavior(
|
|
312
|
-
if (this.
|
|
156
|
+
createBehavior() {
|
|
157
|
+
if (this.updateTarget === null) {
|
|
313
158
|
if (this.targetAspect === "innerHTML") {
|
|
314
159
|
this.dataBinding.evaluate = createInnerHTMLBinding(this.dataBinding.evaluate);
|
|
315
160
|
}
|
|
316
161
|
switch (this.aspectType) {
|
|
317
162
|
case 1:
|
|
318
|
-
this.
|
|
163
|
+
this.updateTarget = DOM.setAttribute;
|
|
319
164
|
break;
|
|
320
165
|
case 2:
|
|
321
|
-
this.
|
|
166
|
+
this.updateTarget = DOM.setBooleanAttribute;
|
|
322
167
|
break;
|
|
323
168
|
case 3:
|
|
324
|
-
this.
|
|
169
|
+
this.updateTarget = setProperty;
|
|
325
170
|
break;
|
|
326
171
|
case 4:
|
|
327
|
-
this.
|
|
172
|
+
this.bind = this.bindContent;
|
|
173
|
+
this.updateTarget = updateContent;
|
|
328
174
|
break;
|
|
329
175
|
case 5:
|
|
330
|
-
this.
|
|
176
|
+
this.updateTarget = updateTokenList;
|
|
331
177
|
break;
|
|
332
178
|
case 6:
|
|
333
|
-
this.
|
|
179
|
+
this.bind = this.bindEvent;
|
|
180
|
+
this.updateTarget = eventTarget;
|
|
334
181
|
break;
|
|
335
182
|
default:
|
|
336
183
|
throw FAST.error(1205 /* Message.unsupportedBindingBehavior */);
|
|
337
184
|
}
|
|
338
185
|
}
|
|
339
|
-
return this
|
|
186
|
+
return this;
|
|
187
|
+
}
|
|
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
|
+
}
|
|
199
|
+
}
|
|
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);
|
|
210
|
+
}
|
|
211
|
+
/** @internal */
|
|
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
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/** @internal */
|
|
221
|
+
handleEvent(event) {
|
|
222
|
+
const target = event.currentTarget;
|
|
223
|
+
ExecutionContext.setEvent(event);
|
|
224
|
+
const controller = target[this.data];
|
|
225
|
+
const result = this.dataBinding.evaluate(controller.source, controller.context);
|
|
226
|
+
ExecutionContext.setEvent(null);
|
|
227
|
+
if (result !== true) {
|
|
228
|
+
event.preventDefault();
|
|
229
|
+
}
|
|
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);
|
|
340
236
|
}
|
|
341
237
|
}
|
|
342
238
|
HTMLDirective.define(HTMLBindingDirective, { aspected: true });
|
|
@@ -1,5 +1,67 @@
|
|
|
1
|
+
import { ExecutionContext, } from "../observation/observable.js";
|
|
1
2
|
import { createTypeRegistry } from "../platform.js";
|
|
2
3
|
import { Markup, nextId } from "./markup.js";
|
|
4
|
+
/**
|
|
5
|
+
* Bridges between ViewBehaviors and HostBehaviors, enabling a host to
|
|
6
|
+
* control ViewBehaviors.
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export const ViewBehaviorOrchestrator = Object.freeze({
|
|
10
|
+
/**
|
|
11
|
+
* Creates a ViewBehaviorOrchestrator.
|
|
12
|
+
* @param source - The source to to associate behaviors with.
|
|
13
|
+
* @returns A ViewBehaviorOrchestrator.
|
|
14
|
+
*/
|
|
15
|
+
create(source) {
|
|
16
|
+
const behaviors = [];
|
|
17
|
+
const targets = {};
|
|
18
|
+
let unbindables = null;
|
|
19
|
+
let isConnected = false;
|
|
20
|
+
return {
|
|
21
|
+
source,
|
|
22
|
+
context: ExecutionContext.default,
|
|
23
|
+
targets,
|
|
24
|
+
get isBound() {
|
|
25
|
+
return isConnected;
|
|
26
|
+
},
|
|
27
|
+
addBehaviorFactory(factory, target) {
|
|
28
|
+
const nodeId = factory.nodeId || (factory.nodeId = nextId());
|
|
29
|
+
factory.id || (factory.id = nextId());
|
|
30
|
+
this.addTarget(nodeId, target);
|
|
31
|
+
this.addBehavior(factory.createBehavior());
|
|
32
|
+
},
|
|
33
|
+
addTarget(nodeId, target) {
|
|
34
|
+
targets[nodeId] = target;
|
|
35
|
+
},
|
|
36
|
+
addBehavior(behavior) {
|
|
37
|
+
behaviors.push(behavior);
|
|
38
|
+
if (isConnected) {
|
|
39
|
+
behavior.bind(this);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
onUnbind(unbindable) {
|
|
43
|
+
if (unbindables === null) {
|
|
44
|
+
unbindables = [];
|
|
45
|
+
}
|
|
46
|
+
unbindables.push(unbindable);
|
|
47
|
+
},
|
|
48
|
+
connectedCallback(controller) {
|
|
49
|
+
if (!isConnected) {
|
|
50
|
+
isConnected = true;
|
|
51
|
+
behaviors.forEach(x => x.bind(this));
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
disconnectedCallback(controller) {
|
|
55
|
+
if (isConnected) {
|
|
56
|
+
isConnected = false;
|
|
57
|
+
if (unbindables !== null) {
|
|
58
|
+
unbindables.forEach(x => x.unbind(this));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
});
|
|
3
65
|
const registry = createTypeRegistry();
|
|
4
66
|
/**
|
|
5
67
|
* Instructs the template engine to apply behavior to a node.
|
|
@@ -45,6 +107,15 @@ export function htmlDirective(options) {
|
|
|
45
107
|
* @public
|
|
46
108
|
*/
|
|
47
109
|
export class Binding {
|
|
110
|
+
/**
|
|
111
|
+
* Creates a binding.
|
|
112
|
+
* @param evaluate - Evaluates the binding.
|
|
113
|
+
* @param isVolatile - Indicates whether the binding is volatile.
|
|
114
|
+
*/
|
|
115
|
+
constructor(evaluate, isVolatile = false) {
|
|
116
|
+
this.evaluate = evaluate;
|
|
117
|
+
this.isVolatile = isVolatile;
|
|
118
|
+
}
|
|
48
119
|
}
|
|
49
120
|
/**
|
|
50
121
|
* The type of HTML aspect to target.
|
|
@@ -144,13 +215,6 @@ export class StatelessAttachedAttributeDirective {
|
|
|
144
215
|
*/
|
|
145
216
|
this.id = nextId();
|
|
146
217
|
}
|
|
147
|
-
/**
|
|
148
|
-
* Creates a behavior.
|
|
149
|
-
* @param targets - The targets available for behaviors to be attached to.
|
|
150
|
-
*/
|
|
151
|
-
createBehavior(targets) {
|
|
152
|
-
return this;
|
|
153
|
-
}
|
|
154
218
|
/**
|
|
155
219
|
* Creates a placeholder string based on the directive's index within the template.
|
|
156
220
|
* @param index - The index of the directive within the template.
|
|
@@ -160,4 +224,11 @@ export class StatelessAttachedAttributeDirective {
|
|
|
160
224
|
createHTML(add) {
|
|
161
225
|
return Markup.attribute(add(this));
|
|
162
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Creates a behavior.
|
|
229
|
+
* @param targets - The targets available for behaviors to be attached to.
|
|
230
|
+
*/
|
|
231
|
+
createBehavior() {
|
|
232
|
+
return this;
|
|
233
|
+
}
|
|
163
234
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { emptyArray } from "../platform.js";
|
|
2
|
-
import { StatelessAttachedAttributeDirective
|
|
2
|
+
import { StatelessAttachedAttributeDirective } from "./html-directive.js";
|
|
3
3
|
const selectElements = (value) => value.nodeType === 1;
|
|
4
4
|
/**
|
|
5
5
|
* Creates a function that can be used to filter a Node array, selecting only elements.
|
|
@@ -26,11 +26,12 @@ export class NodeObservationDirective extends StatelessAttachedAttributeDirectiv
|
|
|
26
26
|
* @param context - The execution context that the binding is operating within.
|
|
27
27
|
* @param targets - The targets that behaviors in a view can attach to.
|
|
28
28
|
*/
|
|
29
|
-
bind(
|
|
30
|
-
const target = targets[this.nodeId];
|
|
31
|
-
target[this.sourceProperty] = source;
|
|
32
|
-
this.updateTarget(source, this.computeNodes(target));
|
|
29
|
+
bind(controller) {
|
|
30
|
+
const target = controller.targets[this.nodeId];
|
|
31
|
+
target[this.sourceProperty] = controller.source;
|
|
32
|
+
this.updateTarget(controller.source, this.computeNodes(target));
|
|
33
33
|
this.observe(target);
|
|
34
|
+
controller.onUnbind(this);
|
|
34
35
|
}
|
|
35
36
|
/**
|
|
36
37
|
* Unbinds this behavior from the source.
|
|
@@ -38,9 +39,9 @@ export class NodeObservationDirective extends StatelessAttachedAttributeDirectiv
|
|
|
38
39
|
* @param context - The execution context that the binding is operating within.
|
|
39
40
|
* @param targets - The targets that behaviors in a view can attach to.
|
|
40
41
|
*/
|
|
41
|
-
unbind(
|
|
42
|
-
const target = targets[this.nodeId];
|
|
43
|
-
this.updateTarget(source, emptyArray);
|
|
42
|
+
unbind(controller) {
|
|
43
|
+
const target = controller.targets[this.nodeId];
|
|
44
|
+
this.updateTarget(controller.source, emptyArray);
|
|
44
45
|
this.disconnect(target);
|
|
45
46
|
target[this.sourceProperty] = null;
|
|
46
47
|
}
|
|
@@ -5,20 +5,12 @@ import { HTMLDirective, StatelessAttachedAttributeDirective, } from "./html-dire
|
|
|
5
5
|
*/
|
|
6
6
|
export class RefDirective extends StatelessAttachedAttributeDirective {
|
|
7
7
|
/**
|
|
8
|
-
* Bind this behavior
|
|
9
|
-
* @param
|
|
10
|
-
* @param context - The execution context that the binding is operating within.
|
|
11
|
-
* @param targets - The targets that behaviors in a view can attach to.
|
|
8
|
+
* Bind this behavior.
|
|
9
|
+
* @param controller - The view controller that manages the lifecycle of this behavior.
|
|
12
10
|
*/
|
|
13
|
-
bind(
|
|
14
|
-
source[this.options] = targets[this.nodeId];
|
|
11
|
+
bind(controller) {
|
|
12
|
+
controller.source[this.options] = controller.targets[this.nodeId];
|
|
15
13
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Unbinds this behavior from the source.
|
|
18
|
-
* @param source - The source to unbind from.
|
|
19
|
-
*/
|
|
20
|
-
/* eslint-disable-next-line @typescript-eslint/no-empty-function */
|
|
21
|
-
unbind() { }
|
|
22
14
|
}
|
|
23
15
|
HTMLDirective.define(RefDirective);
|
|
24
16
|
/**
|
|
@@ -11,57 +11,48 @@ import { html, } from "./template.js";
|
|
|
11
11
|
export class RenderBehavior {
|
|
12
12
|
/**
|
|
13
13
|
* Creates an instance of RenderBehavior.
|
|
14
|
-
* @param
|
|
15
|
-
* @param dataBinding - A binding expression that returns the data to render.
|
|
16
|
-
* @param templateBinding - A binding expression that returns the template to use with the data.
|
|
14
|
+
* @param directive - The render directive that created this behavior.
|
|
17
15
|
*/
|
|
18
|
-
constructor(directive
|
|
16
|
+
constructor(directive) {
|
|
19
17
|
this.directive = directive;
|
|
20
|
-
this.location =
|
|
21
|
-
this.
|
|
18
|
+
this.location = null;
|
|
19
|
+
this.controller = null;
|
|
22
20
|
this.view = null;
|
|
23
21
|
this.data = null;
|
|
24
|
-
this.originalContext = void 0;
|
|
25
|
-
this.childContext = void 0;
|
|
26
22
|
this.dataBindingObserver = directive.dataBinding.createObserver(directive, this);
|
|
27
23
|
this.templateBindingObserver = directive.templateBinding.createObserver(directive, this);
|
|
28
24
|
}
|
|
29
25
|
/**
|
|
30
|
-
* Bind this behavior
|
|
31
|
-
* @param
|
|
32
|
-
* @param context - The execution context that the binding is operating within.
|
|
26
|
+
* Bind this behavior.
|
|
27
|
+
* @param controller - The view controller that manages the lifecycle of this behavior.
|
|
33
28
|
*/
|
|
34
|
-
bind(
|
|
35
|
-
this.
|
|
36
|
-
this.
|
|
37
|
-
this.
|
|
38
|
-
this.
|
|
39
|
-
|
|
29
|
+
bind(controller) {
|
|
30
|
+
this.location = controller.targets[this.directive.nodeId];
|
|
31
|
+
this.controller = controller;
|
|
32
|
+
this.data = this.dataBindingObserver.bind(controller);
|
|
33
|
+
this.template = this.templateBindingObserver.bind(controller);
|
|
34
|
+
controller.onUnbind(this);
|
|
40
35
|
this.refreshView();
|
|
41
36
|
}
|
|
42
37
|
/**
|
|
43
|
-
* Unbinds this behavior
|
|
44
|
-
* @param
|
|
38
|
+
* Unbinds this behavior.
|
|
39
|
+
* @param controller - The view controller that manages the lifecycle of this behavior.
|
|
45
40
|
*/
|
|
46
|
-
unbind(
|
|
47
|
-
this.source = null;
|
|
48
|
-
this.data = null;
|
|
41
|
+
unbind(controller) {
|
|
49
42
|
const view = this.view;
|
|
50
43
|
if (view !== null && view.isComposed) {
|
|
51
44
|
view.unbind();
|
|
52
45
|
view.needsBindOnly = true;
|
|
53
46
|
}
|
|
54
|
-
this.dataBindingObserver.dispose();
|
|
55
|
-
this.templateBindingObserver.dispose();
|
|
56
47
|
}
|
|
57
48
|
/** @internal */
|
|
58
49
|
handleChange(source, observer) {
|
|
59
50
|
if (observer === this.dataBindingObserver) {
|
|
60
|
-
this.data = this.dataBindingObserver.
|
|
51
|
+
this.data = this.dataBindingObserver.bind(this.controller);
|
|
61
52
|
}
|
|
62
53
|
if (this.directive.templateBindingDependsOnData ||
|
|
63
54
|
observer === this.templateBindingObserver) {
|
|
64
|
-
this.template = this.templateBindingObserver.
|
|
55
|
+
this.template = this.templateBindingObserver.bind(this.controller);
|
|
65
56
|
}
|
|
66
57
|
this.refreshView();
|
|
67
58
|
}
|
|
@@ -70,6 +61,8 @@ export class RenderBehavior {
|
|
|
70
61
|
const template = this.template;
|
|
71
62
|
if (view === null) {
|
|
72
63
|
this.view = view = template.create();
|
|
64
|
+
this.view.context.parent = this.controller.source;
|
|
65
|
+
this.view.context.parentContext = this.controller.context;
|
|
73
66
|
}
|
|
74
67
|
else {
|
|
75
68
|
// If there is a previous view, but it wasn't created
|
|
@@ -82,19 +75,21 @@ export class RenderBehavior {
|
|
|
82
75
|
view.unbind();
|
|
83
76
|
}
|
|
84
77
|
this.view = view = template.create();
|
|
78
|
+
this.view.context.parent = this.controller.source;
|
|
79
|
+
this.view.context.parentContext = this.controller.context;
|
|
85
80
|
}
|
|
86
81
|
}
|
|
87
82
|
// It's possible that the value is the same as the previous template
|
|
88
83
|
// and that there's actually no need to compose it.
|
|
89
84
|
if (!view.isComposed) {
|
|
90
85
|
view.isComposed = true;
|
|
91
|
-
view.bind(this.data
|
|
86
|
+
view.bind(this.data);
|
|
92
87
|
view.insertBefore(this.location);
|
|
93
88
|
view.$fastTemplate = template;
|
|
94
89
|
}
|
|
95
90
|
else if (view.needsBindOnly) {
|
|
96
91
|
view.needsBindOnly = false;
|
|
97
|
-
view.bind(this.data
|
|
92
|
+
view.bind(this.data);
|
|
98
93
|
}
|
|
99
94
|
}
|
|
100
95
|
}
|
|
@@ -124,8 +119,8 @@ export class RenderDirective {
|
|
|
124
119
|
* Creates a behavior.
|
|
125
120
|
* @param targets - The targets available for behaviors to be attached to.
|
|
126
121
|
*/
|
|
127
|
-
createBehavior(
|
|
128
|
-
return new RenderBehavior(this
|
|
122
|
+
createBehavior() {
|
|
123
|
+
return new RenderBehavior(this);
|
|
129
124
|
}
|
|
130
125
|
}
|
|
131
126
|
HTMLDirective.define(RenderDirective);
|
|
@@ -297,7 +292,11 @@ export class NodeTemplate {
|
|
|
297
292
|
this.node = node;
|
|
298
293
|
node.$fastTemplate = this;
|
|
299
294
|
}
|
|
300
|
-
|
|
295
|
+
get context() {
|
|
296
|
+
// HACK
|
|
297
|
+
return this;
|
|
298
|
+
}
|
|
299
|
+
bind(source) { }
|
|
301
300
|
unbind() { }
|
|
302
301
|
insertBefore(refNode) {
|
|
303
302
|
refNode.parentNode.insertBefore(this.node, refNode);
|