@microsoft/fast-element 2.0.0-beta.1 → 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/CHANGELOG.json +333 -0
- package/CHANGELOG.md +106 -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 +43 -9
- package/dist/dts/components/fast-element.d.ts +15 -21
- package/dist/dts/context.d.ts +157 -0
- package/dist/dts/di/di.d.ts +899 -0
- package/dist/dts/index.d.ts +2 -2
- package/dist/dts/interfaces.d.ts +44 -12
- package/dist/dts/metadata.d.ts +25 -0
- package/dist/dts/observation/arrays.d.ts +1 -1
- package/dist/dts/observation/observable.d.ts +101 -75
- package/dist/dts/pending-task.d.ts +20 -0
- package/dist/dts/platform.d.ts +6 -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 +2 -2
- package/dist/dts/styles/element-styles.d.ts +9 -3
- 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 +69 -294
- package/dist/dts/templating/children.d.ts +1 -1
- package/dist/dts/templating/compiler.d.ts +1 -2
- package/dist/dts/templating/html-directive.d.ts +93 -35
- 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 +272 -0
- package/dist/dts/templating/repeat.d.ts +20 -75
- package/dist/dts/templating/slotted.d.ts +1 -1
- package/dist/dts/templating/template.d.ts +12 -61
- package/dist/dts/templating/view.d.ts +77 -12
- 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} +0 -0
- package/dist/dts/utilities.d.ts +0 -18
- 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 +38 -28
- package/dist/esm/components/fast-element.js +31 -12
- package/dist/esm/context.js +163 -0
- package/dist/esm/debug.js +36 -4
- package/dist/esm/di/di.js +1435 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/interfaces.js +4 -0
- package/dist/esm/metadata.js +60 -0
- package/dist/esm/observation/arrays.js +304 -3
- package/dist/esm/observation/observable.js +81 -87
- package/dist/esm/pending-task.js +16 -0
- package/dist/esm/platform.js +25 -1
- 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.js +4 -4
- package/dist/esm/styles/element-styles.js +14 -0
- package/dist/esm/{observation/behavior.js → styles/host.js} +0 -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 +134 -414
- package/dist/esm/templating/compiler.js +30 -7
- package/dist/esm/templating/html-directive.js +100 -28
- package/dist/esm/templating/node-observation.js +9 -8
- package/dist/esm/templating/ref.js +4 -12
- package/dist/esm/templating/render.js +391 -0
- package/dist/esm/templating/repeat.js +96 -72
- package/dist/esm/templating/template.js +11 -29
- package/dist/esm/templating/view.js +107 -29
- package/dist/esm/templating/when.js +5 -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 +0 -95
- package/dist/fast-element.api.json +9034 -10524
- package/dist/fast-element.d.ts +707 -811
- package/dist/fast-element.debug.js +1133 -850
- package/dist/fast-element.debug.min.js +1 -1
- package/dist/fast-element.js +1097 -846
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +724 -818
- package/docs/api-report.md +264 -305
- package/package.json +39 -10
- package/dist/dts/hooks.d.ts +0 -20
- package/dist/dts/observation/behavior.d.ts +0 -19
- package/dist/dts/observation/splice-strategies.d.ts +0 -13
- package/dist/esm/hooks.js +0 -32
- package/dist/esm/observation/splice-strategies.js +0 -400
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { isString } from "../interfaces.js";
|
|
1
|
+
import { isFunction, isString } from "../interfaces.js";
|
|
2
2
|
import { FAST } from "../platform.js";
|
|
3
3
|
import { Parser } from "./markup.js";
|
|
4
|
-
import {
|
|
4
|
+
import { HTMLBindingDirective, oneTime } from "./binding.js";
|
|
5
5
|
import { Aspect } from "./html-directive.js";
|
|
6
6
|
import { HTMLView } from "./view.js";
|
|
7
7
|
const targetIdFrom = (parentId, nodeIndex) => `${parentId}.${nodeIndex}`;
|
|
@@ -11,6 +11,22 @@ const next = {
|
|
|
11
11
|
index: 0,
|
|
12
12
|
node: null,
|
|
13
13
|
};
|
|
14
|
+
function tryWarn(name) {
|
|
15
|
+
if (!name.startsWith("fast-")) {
|
|
16
|
+
FAST.warn(1204 /* Message.hostBindingWithoutHost */, { name });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const warningHost = new Proxy(document.createElement("div"), {
|
|
20
|
+
get(target, property) {
|
|
21
|
+
tryWarn(property);
|
|
22
|
+
const value = Reflect.get(target, property);
|
|
23
|
+
return isFunction(value) ? value.bind(target) : value;
|
|
24
|
+
},
|
|
25
|
+
set(target, property, value) {
|
|
26
|
+
tryWarn(property);
|
|
27
|
+
return Reflect.set(target, property, value);
|
|
28
|
+
},
|
|
29
|
+
});
|
|
14
30
|
class CompilationContext {
|
|
15
31
|
constructor(fragment, directives) {
|
|
16
32
|
this.fragment = fragment;
|
|
@@ -61,7 +77,7 @@ class CompilationContext {
|
|
|
61
77
|
const fragment = this.fragment.cloneNode(true);
|
|
62
78
|
const targets = Object.create(this.proto);
|
|
63
79
|
targets.r = fragment;
|
|
64
|
-
targets.h = hostBindingTarget !== null && hostBindingTarget !== void 0 ? hostBindingTarget :
|
|
80
|
+
targets.h = hostBindingTarget !== null && hostBindingTarget !== void 0 ? hostBindingTarget : warningHost;
|
|
65
81
|
for (const id of this.nodeIds) {
|
|
66
82
|
targets[id]; // trigger locator
|
|
67
83
|
}
|
|
@@ -78,7 +94,7 @@ function compileAttributes(context, parentId, node, nodeId, nodeIndex, includeBa
|
|
|
78
94
|
let result = null;
|
|
79
95
|
if (parseResult === null) {
|
|
80
96
|
if (includeBasicValues) {
|
|
81
|
-
result =
|
|
97
|
+
result = new HTMLBindingDirective(oneTime(() => attrValue));
|
|
82
98
|
Aspect.assign(result, attr.name);
|
|
83
99
|
}
|
|
84
100
|
}
|
|
@@ -115,6 +131,7 @@ function compileContent(context, node, parentId, nodeId, nodeIndex) {
|
|
|
115
131
|
}
|
|
116
132
|
else {
|
|
117
133
|
currentNode.textContent = " ";
|
|
134
|
+
Aspect.assign(currentPart);
|
|
118
135
|
context.addFactory(currentPart, parentId, nodeId, nodeIndex);
|
|
119
136
|
}
|
|
120
137
|
lastNode = currentNode;
|
|
@@ -247,22 +264,28 @@ export const Compiler = {
|
|
|
247
264
|
return parts[0];
|
|
248
265
|
}
|
|
249
266
|
let sourceAspect;
|
|
267
|
+
let binding;
|
|
268
|
+
let isVolatile = false;
|
|
250
269
|
const partCount = parts.length;
|
|
251
270
|
const finalParts = parts.map((x) => {
|
|
252
271
|
if (isString(x)) {
|
|
253
272
|
return () => x;
|
|
254
273
|
}
|
|
255
274
|
sourceAspect = x.sourceAspect || sourceAspect;
|
|
256
|
-
|
|
275
|
+
binding = x.dataBinding || binding;
|
|
276
|
+
isVolatile = isVolatile || x.dataBinding.isVolatile;
|
|
277
|
+
return x.dataBinding.evaluate;
|
|
257
278
|
});
|
|
258
|
-
const
|
|
279
|
+
const expression = (scope, context) => {
|
|
259
280
|
let output = "";
|
|
260
281
|
for (let i = 0; i < partCount; ++i) {
|
|
261
282
|
output += finalParts[i](scope, context);
|
|
262
283
|
}
|
|
263
284
|
return output;
|
|
264
285
|
};
|
|
265
|
-
|
|
286
|
+
binding.evaluate = expression;
|
|
287
|
+
binding.isVolatile = isVolatile;
|
|
288
|
+
const directive = new HTMLBindingDirective(binding);
|
|
266
289
|
Aspect.assign(directive, sourceAspect);
|
|
267
290
|
return directive;
|
|
268
291
|
},
|
|
@@ -1,5 +1,67 @@
|
|
|
1
|
+
import { ExecutionContext, } from "../observation/observable.js";
|
|
1
2
|
import { createTypeRegistry } from "../platform.js";
|
|
2
|
-
import { Markup } from "./markup.js";
|
|
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.
|
|
@@ -39,6 +101,22 @@ export function htmlDirective(options) {
|
|
|
39
101
|
HTMLDirective.define(type, options);
|
|
40
102
|
};
|
|
41
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Captures a binding expression along with related information and capabilities.
|
|
106
|
+
*
|
|
107
|
+
* @public
|
|
108
|
+
*/
|
|
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
|
+
}
|
|
119
|
+
}
|
|
42
120
|
/**
|
|
43
121
|
* The type of HTML aspect to target.
|
|
44
122
|
* @public
|
|
@@ -76,26 +154,22 @@ export const Aspect = Object.freeze({
|
|
|
76
154
|
*
|
|
77
155
|
* @param directive - The directive to assign the aspect to.
|
|
78
156
|
* @param value - The value to base the aspect determination on.
|
|
157
|
+
* @remarks
|
|
158
|
+
* If a falsy value is provided, then the content aspect will be assigned.
|
|
79
159
|
*/
|
|
80
160
|
assign(directive, value) {
|
|
81
|
-
directive.sourceAspect = value;
|
|
82
161
|
if (!value) {
|
|
162
|
+
directive.aspectType = Aspect.content;
|
|
83
163
|
return;
|
|
84
164
|
}
|
|
165
|
+
directive.sourceAspect = value;
|
|
85
166
|
switch (value[0]) {
|
|
86
167
|
case ":":
|
|
87
168
|
directive.targetAspect = value.substring(1);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
case "classList":
|
|
93
|
-
directive.aspectType = Aspect.tokenList;
|
|
94
|
-
break;
|
|
95
|
-
default:
|
|
96
|
-
directive.aspectType = Aspect.property;
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
169
|
+
directive.aspectType =
|
|
170
|
+
directive.targetAspect === "classList"
|
|
171
|
+
? Aspect.tokenList
|
|
172
|
+
: Aspect.property;
|
|
99
173
|
break;
|
|
100
174
|
case "?":
|
|
101
175
|
directive.targetAspect = value.substring(1);
|
|
@@ -106,14 +180,8 @@ export const Aspect = Object.freeze({
|
|
|
106
180
|
directive.aspectType = Aspect.event;
|
|
107
181
|
break;
|
|
108
182
|
default:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
directive.aspectType = Aspect.property;
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
directive.targetAspect = value;
|
|
115
|
-
directive.aspectType = Aspect.attribute;
|
|
116
|
-
}
|
|
183
|
+
directive.targetAspect = value;
|
|
184
|
+
directive.aspectType = Aspect.attribute;
|
|
117
185
|
break;
|
|
118
186
|
}
|
|
119
187
|
},
|
|
@@ -129,13 +197,10 @@ export class StatelessAttachedAttributeDirective {
|
|
|
129
197
|
*/
|
|
130
198
|
constructor(options) {
|
|
131
199
|
this.options = options;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
*/
|
|
137
|
-
createBehavior(targets) {
|
|
138
|
-
return this;
|
|
200
|
+
/**
|
|
201
|
+
* The unique id of the factory.
|
|
202
|
+
*/
|
|
203
|
+
this.id = nextId();
|
|
139
204
|
}
|
|
140
205
|
/**
|
|
141
206
|
* Creates a placeholder string based on the directive's index within the template.
|
|
@@ -146,4 +211,11 @@ export class StatelessAttachedAttributeDirective {
|
|
|
146
211
|
createHTML(add) {
|
|
147
212
|
return Markup.attribute(add(this));
|
|
148
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Creates a behavior.
|
|
216
|
+
* @param targets - The targets available for behaviors to be attached to.
|
|
217
|
+
*/
|
|
218
|
+
createBehavior() {
|
|
219
|
+
return this;
|
|
220
|
+
}
|
|
149
221
|
}
|
|
@@ -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
|
/**
|