@microsoft/fast-html 1.0.0-alpha.16 → 1.0.0-alpha.18
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/dist/dts/components/element.d.ts +10 -10
- package/dist/dts/components/index.d.ts +1 -0
- package/dist/dts/components/observer-map.d.ts +143 -0
- package/dist/dts/components/observer-map.spec.d.ts +1 -0
- package/dist/dts/components/template.d.ts +11 -0
- package/dist/dts/components/utilities.d.ts +60 -1
- package/dist/dts/fixtures/observer-map/main.d.ts +1 -0
- package/dist/dts/fixtures/observer-map/observer-map.spec.d.ts +1 -0
- package/dist/dts/index.d.ts +1 -1
- package/dist/esm/components/element.js +24 -17
- package/dist/esm/components/index.js +1 -0
- package/dist/esm/components/observer-map.js +551 -0
- package/dist/esm/components/observer-map.spec.js +613 -0
- package/dist/esm/components/template.js +103 -85
- package/dist/esm/components/utilities.js +301 -50
- package/dist/esm/components/utilities.spec.js +109 -1
- package/dist/esm/fixtures/attribute/main.js +3 -3
- package/dist/esm/fixtures/binding/main.js +5 -5
- package/dist/esm/fixtures/children/main.js +3 -3
- package/dist/esm/fixtures/dot-syntax/dot-syntax.spec.js +109 -2
- package/dist/esm/fixtures/dot-syntax/main.js +30 -4
- package/dist/esm/fixtures/event/main.js +6 -6
- package/dist/esm/fixtures/observer-map/main.js +304 -0
- package/dist/esm/fixtures/observer-map/observer-map.spec.js +174 -0
- package/dist/esm/fixtures/partial/main.js +3 -2
- package/dist/esm/fixtures/ref/main.js +3 -2
- package/dist/esm/fixtures/repeat/main.js +5 -5
- package/dist/esm/fixtures/slotted/main.js +3 -3
- package/dist/esm/fixtures/when/main.js +21 -21
- package/dist/esm/index.js +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/fast-html.api.json +247 -32
- package/dist/fast-html.d.ts +214 -6
- package/dist/fast-html.untrimmed.d.ts +214 -6
- package/package.json +5 -4
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { __awaiter, __decorate, __metadata } from "tslib";
|
|
2
2
|
import { attr, elements, FAST, FASTElement, FASTElementDefinition, fastElementRegistry, HydratableElementController, ViewTemplate, } from "@microsoft/fast-element";
|
|
3
3
|
import "@microsoft/fast-element/install-hydratable-view-templates.js";
|
|
4
|
-
import { getAllPartials, getExpressionChain, getNextBehavior,
|
|
4
|
+
import { bindingResolver, getAllPartials, getExpressionChain, getNextBehavior, resolveWhen, transformInnerHTML, } from "./utilities.js";
|
|
5
|
+
import { ObserverMap } from "./observer-map.js";
|
|
5
6
|
/**
|
|
6
7
|
* The <f-template> custom element that will provide view logic to the element
|
|
7
8
|
*/
|
|
@@ -13,6 +14,7 @@ class TemplateElement extends FASTElement {
|
|
|
13
14
|
const value = elementOptions[key];
|
|
14
15
|
result[key] = {
|
|
15
16
|
shadowOptions: (_a = value.shadowOptions) !== null && _a !== void 0 ? _a : TemplateElement.defaultElementOptions.shadowOptions,
|
|
17
|
+
observerMap: value.observerMap,
|
|
16
18
|
};
|
|
17
19
|
}
|
|
18
20
|
this.elementOptions = result;
|
|
@@ -22,7 +24,9 @@ class TemplateElement extends FASTElement {
|
|
|
22
24
|
constructor() {
|
|
23
25
|
super();
|
|
24
26
|
this.partials = {};
|
|
25
|
-
|
|
27
|
+
// Ensure elementOptions is initialized if it's empty
|
|
28
|
+
if (!TemplateElement.elementOptions ||
|
|
29
|
+
Object.keys(TemplateElement.elementOptions).length === 0) {
|
|
26
30
|
TemplateElement.options();
|
|
27
31
|
}
|
|
28
32
|
}
|
|
@@ -31,30 +35,37 @@ class TemplateElement extends FASTElement {
|
|
|
31
35
|
* @param name - The name of the custom element to set options for.
|
|
32
36
|
*/
|
|
33
37
|
static setOptions(name) {
|
|
34
|
-
if (
|
|
38
|
+
if (!TemplateElement.elementOptions[name]) {
|
|
35
39
|
TemplateElement.elementOptions[name] = TemplateElement.defaultElementOptions;
|
|
36
40
|
}
|
|
37
41
|
}
|
|
38
42
|
connectedCallback() {
|
|
39
43
|
super.connectedCallback();
|
|
40
|
-
if (this.name) {
|
|
44
|
+
if (typeof this.name === "string") {
|
|
41
45
|
FASTElementDefinition.registerAsync(this.name).then((value) => __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
var _a, _b;
|
|
43
|
-
if (
|
|
46
|
+
var _a, _b, _c, _d;
|
|
47
|
+
if (!((_a = TemplateElement.elementOptions) === null || _a === void 0 ? void 0 : _a[this.name])) {
|
|
44
48
|
TemplateElement.setOptions(this.name);
|
|
45
49
|
}
|
|
50
|
+
if (((_b = TemplateElement.elementOptions[this.name]) === null || _b === void 0 ? void 0 : _b.observerMap) ===
|
|
51
|
+
"all") {
|
|
52
|
+
this.observerMap = new ObserverMap(value.prototype);
|
|
53
|
+
}
|
|
46
54
|
const registeredFastElement = fastElementRegistry.getByType(value);
|
|
47
55
|
const template = this.getElementsByTagName("template").item(0);
|
|
48
56
|
if (template) {
|
|
49
57
|
const innerHTML = yield transformInnerHTML(this.innerHTML);
|
|
50
58
|
yield this.resolveAllPartials(innerHTML);
|
|
51
|
-
|
|
59
|
+
// Cache paths during template processing (pass undefined if observerMap is not available)
|
|
60
|
+
const { strings, values } = yield this.resolveStringsAndValues(innerHTML, false, null, 0, this.observerMap);
|
|
61
|
+
// Define the root properties cached in the observer map as observable (only if observerMap exists)
|
|
62
|
+
(_c = this.observerMap) === null || _c === void 0 ? void 0 : _c.defineProperties();
|
|
52
63
|
if (registeredFastElement) {
|
|
53
64
|
// all new elements will get the updated template
|
|
54
65
|
registeredFastElement.template = this.resolveTemplateOrBehavior(strings, values);
|
|
55
66
|
// set shadow options as defined by the f-template
|
|
56
67
|
registeredFastElement.shadowOptions =
|
|
57
|
-
(
|
|
68
|
+
(_d = TemplateElement.elementOptions[this.name]) === null || _d === void 0 ? void 0 : _d.shadowOptions;
|
|
58
69
|
}
|
|
59
70
|
}
|
|
60
71
|
else {
|
|
@@ -67,12 +78,13 @@ class TemplateElement extends FASTElement {
|
|
|
67
78
|
* Resolve strings and values from an innerHTML string
|
|
68
79
|
* @param innerHTML - The innerHTML.
|
|
69
80
|
* @param self - Indicates that this should refer to itself instead of a property when creating bindings.
|
|
81
|
+
* @param observerMap - ObserverMap instance for caching binding paths (optional).
|
|
70
82
|
*/
|
|
71
|
-
resolveStringsAndValues(innerHTML, self = false) {
|
|
83
|
+
resolveStringsAndValues(innerHTML, self = false, parentContext, level, observerMap) {
|
|
72
84
|
return __awaiter(this, void 0, void 0, function* () {
|
|
73
85
|
const strings = [];
|
|
74
86
|
const values = []; // these can be bindings, directives, etc.
|
|
75
|
-
yield this.resolveInnerHTML(innerHTML, strings, values, self);
|
|
87
|
+
yield this.resolveInnerHTML(innerHTML, strings, values, self, parentContext, level, observerMap);
|
|
76
88
|
strings.raw = strings.map(value => String.raw({ raw: value }));
|
|
77
89
|
return {
|
|
78
90
|
strings,
|
|
@@ -93,28 +105,30 @@ class TemplateElement extends FASTElement {
|
|
|
93
105
|
* @param behaviorConfig - The directive behavior configuration object.
|
|
94
106
|
* @param externalValues - The interpreted values from the parent.
|
|
95
107
|
* @param innerHTML - The innerHTML.
|
|
108
|
+
* @param self - Indicates that this should refer to itself instead of a property when creating bindings.
|
|
109
|
+
* @param observerMap - ObserverMap instance for caching binding paths (optional).
|
|
96
110
|
*/
|
|
97
|
-
resolveTemplateDirective(behaviorConfig, externalValues, innerHTML, self = false) {
|
|
111
|
+
resolveTemplateDirective(behaviorConfig, externalValues, innerHTML, self = false, parentContext, level, observerMap) {
|
|
98
112
|
var _a;
|
|
99
113
|
return __awaiter(this, void 0, void 0, function* () {
|
|
100
114
|
switch (behaviorConfig.name) {
|
|
101
|
-
case "when":
|
|
102
|
-
{
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
externalValues.push(when(whenLogic, this.resolveTemplateOrBehavior(strings, values)));
|
|
108
|
-
}
|
|
115
|
+
case "when": {
|
|
116
|
+
const { when } = yield import("@microsoft/fast-element");
|
|
117
|
+
const expressionChain = getExpressionChain(behaviorConfig.value);
|
|
118
|
+
const whenLogic = resolveWhen(self, expressionChain, parentContext, level, observerMap);
|
|
119
|
+
const { strings, values } = yield this.resolveStringsAndValues(innerHTML.slice(behaviorConfig.openingTagEndIndex, behaviorConfig.closingTagStartIndex), self, parentContext, level, observerMap);
|
|
120
|
+
externalValues.push(when(whenLogic, this.resolveTemplateOrBehavior(strings, values)));
|
|
109
121
|
break;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
122
|
+
}
|
|
123
|
+
case "repeat": {
|
|
124
|
+
const valueAttr = behaviorConfig.value.split(" "); // syntax {{x in y}}
|
|
125
|
+
const updatedLevel = level + 1;
|
|
126
|
+
const { repeat } = yield import("@microsoft/fast-element");
|
|
127
|
+
const binding = bindingResolver(valueAttr[2], self, parentContext, "repeat", observerMap !== null && observerMap !== void 0 ? observerMap : null, valueAttr[0], level);
|
|
128
|
+
const { strings, values } = yield this.resolveStringsAndValues(innerHTML.slice(behaviorConfig.openingTagEndIndex, behaviorConfig.closingTagStartIndex), true, valueAttr[0], updatedLevel, observerMap);
|
|
129
|
+
externalValues.push(repeat((x, c) => binding(x, c), this.resolveTemplateOrBehavior(strings, values)));
|
|
117
130
|
break;
|
|
131
|
+
}
|
|
118
132
|
case "apply": {
|
|
119
133
|
const openingTag = innerHTML.slice(behaviorConfig.openingTagStartIndex, behaviorConfig.openingTagEndIndex);
|
|
120
134
|
const partial = (_a = openingTag
|
|
@@ -124,7 +138,8 @@ class TemplateElement extends FASTElement {
|
|
|
124
138
|
})) === null || _a === void 0 ? void 0 : _a.split('"')[1];
|
|
125
139
|
if (partial) {
|
|
126
140
|
const { when } = yield import("@microsoft/fast-element");
|
|
127
|
-
|
|
141
|
+
const binding = bindingResolver(behaviorConfig.value, self, parentContext, "access", observerMap !== null && observerMap !== void 0 ? observerMap : null, null, level);
|
|
142
|
+
externalValues.push(when((x, c) => binding(x, c), () => this.partials[partial]));
|
|
128
143
|
}
|
|
129
144
|
}
|
|
130
145
|
}
|
|
@@ -139,37 +154,34 @@ class TemplateElement extends FASTElement {
|
|
|
139
154
|
resolveAttributeDirective(name, propName, externalValues) {
|
|
140
155
|
return __awaiter(this, void 0, void 0, function* () {
|
|
141
156
|
switch (name) {
|
|
142
|
-
case "children":
|
|
143
|
-
{
|
|
144
|
-
|
|
145
|
-
externalValues.push(children(propName));
|
|
146
|
-
}
|
|
157
|
+
case "children": {
|
|
158
|
+
const { children } = yield import("@microsoft/fast-element");
|
|
159
|
+
externalValues.push(children(propName));
|
|
147
160
|
break;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
161
|
+
}
|
|
162
|
+
case "slotted": {
|
|
163
|
+
const { slotted } = yield import("@microsoft/fast-element");
|
|
164
|
+
const parts = propName.trim().split(" filter ");
|
|
165
|
+
const slottedOption = {
|
|
166
|
+
property: parts[0],
|
|
167
|
+
};
|
|
168
|
+
if (parts[1]) {
|
|
169
|
+
if (parts[1].startsWith("elements(")) {
|
|
170
|
+
let params = parts[1].replace("elements(", "");
|
|
171
|
+
params = params.substring(0, params.lastIndexOf(")"));
|
|
172
|
+
Object.assign(slottedOption, {
|
|
173
|
+
filter: elements(params || undefined),
|
|
174
|
+
});
|
|
163
175
|
}
|
|
164
|
-
externalValues.push(slotted(slottedOption));
|
|
165
176
|
}
|
|
177
|
+
externalValues.push(slotted(slottedOption));
|
|
166
178
|
break;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
179
|
+
}
|
|
180
|
+
case "ref": {
|
|
181
|
+
const { ref } = yield import("@microsoft/fast-element");
|
|
182
|
+
externalValues.push(ref(propName));
|
|
172
183
|
break;
|
|
184
|
+
}
|
|
173
185
|
}
|
|
174
186
|
});
|
|
175
187
|
}
|
|
@@ -180,20 +192,21 @@ class TemplateElement extends FASTElement {
|
|
|
180
192
|
* @param values - The interpreted values.
|
|
181
193
|
* @param self - Indicates that this should refer to itself instead of a property when creating bindings.
|
|
182
194
|
* @param behaviorConfig - The binding behavior configuration object.
|
|
195
|
+
* @param observerMap - ObserverMap instance for caching binding paths (optional).
|
|
183
196
|
*/
|
|
184
|
-
resolveDataBinding(innerHTML, strings, values, self = false, behaviorConfig) {
|
|
197
|
+
resolveDataBinding(innerHTML, strings, values, self = false, behaviorConfig, parentContext, level, observerMap) {
|
|
185
198
|
return __awaiter(this, void 0, void 0, function* () {
|
|
186
199
|
switch (behaviorConfig.subtype) {
|
|
187
|
-
case "content":
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
200
|
+
case "content": {
|
|
201
|
+
strings.push(innerHTML.slice(0, behaviorConfig.openingStartIndex));
|
|
202
|
+
const propName = innerHTML.slice(behaviorConfig.openingEndIndex, behaviorConfig.closingStartIndex);
|
|
203
|
+
const binding = bindingResolver(propName, self, parentContext, "access", observerMap !== null && observerMap !== void 0 ? observerMap : null, null, level);
|
|
204
|
+
const contentBinding = (x, c) => binding(x, c);
|
|
205
|
+
values.push(contentBinding);
|
|
206
|
+
yield this.resolveInnerHTML(innerHTML.slice(behaviorConfig.closingEndIndex, innerHTML.length), strings, values, self, parentContext, level, observerMap);
|
|
195
207
|
break;
|
|
196
|
-
|
|
208
|
+
}
|
|
209
|
+
case "attribute": {
|
|
197
210
|
strings.push(innerHTML.slice(0, behaviorConfig.openingStartIndex));
|
|
198
211
|
if (behaviorConfig.aspect === "@") {
|
|
199
212
|
const bindingHTML = innerHTML.slice(behaviorConfig.openingEndIndex, behaviorConfig.closingStartIndex);
|
|
@@ -203,28 +216,30 @@ class TemplateElement extends FASTElement {
|
|
|
203
216
|
(closingParenthesis - openingParenthesis) -
|
|
204
217
|
1);
|
|
205
218
|
const arg = bindingHTML.slice(openingParenthesis + 1, closingParenthesis);
|
|
206
|
-
const binding = (
|
|
207
|
-
|
|
219
|
+
const binding = bindingResolver(propName, self, parentContext, "event", observerMap !== null && observerMap !== void 0 ? observerMap : null, null, level);
|
|
220
|
+
const attributeBinding = (x, c) => binding(x, c).bind(x)(...(arg === "e" ? [c.event] : []), ...(arg !== "e" && arg !== ""
|
|
221
|
+
? [
|
|
222
|
+
bindingResolver(arg, self, parentContext, "event", observerMap !== null && observerMap !== void 0 ? observerMap : null, null, level)(x, c),
|
|
223
|
+
]
|
|
208
224
|
: []));
|
|
209
|
-
values.push(
|
|
225
|
+
values.push(attributeBinding);
|
|
210
226
|
}
|
|
211
227
|
else {
|
|
212
228
|
const propName = innerHTML.slice(behaviorConfig.openingEndIndex, behaviorConfig.closingStartIndex);
|
|
213
|
-
const binding = (
|
|
214
|
-
|
|
229
|
+
const binding = bindingResolver(propName, self, parentContext, "access", observerMap !== null && observerMap !== void 0 ? observerMap : null, null, level);
|
|
230
|
+
const attributeBinding = (x, c) => binding(x, c);
|
|
231
|
+
values.push(attributeBinding);
|
|
215
232
|
}
|
|
216
|
-
yield this.resolveInnerHTML(innerHTML.slice(behaviorConfig.closingEndIndex, innerHTML.length), strings, values, self);
|
|
233
|
+
yield this.resolveInnerHTML(innerHTML.slice(behaviorConfig.closingEndIndex, innerHTML.length), strings, values, self, parentContext, level, observerMap);
|
|
217
234
|
break;
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
yield this.resolveAttributeDirective(behaviorConfig.name, propName, values);
|
|
225
|
-
yield this.resolveInnerHTML(innerHTML.slice(behaviorConfig.closingEndIndex + 1, innerHTML.length), strings, values, self);
|
|
226
|
-
}
|
|
235
|
+
}
|
|
236
|
+
case "attributeDirective": {
|
|
237
|
+
strings.push(innerHTML.slice(0, behaviorConfig.openingStartIndex - behaviorConfig.name.length - 4));
|
|
238
|
+
const propName = innerHTML.slice(behaviorConfig.openingEndIndex, behaviorConfig.closingStartIndex);
|
|
239
|
+
yield this.resolveAttributeDirective(behaviorConfig.name, propName, values);
|
|
240
|
+
yield this.resolveInnerHTML(innerHTML.slice(behaviorConfig.closingEndIndex + 1, innerHTML.length), strings, values, self, parentContext, level, observerMap);
|
|
227
241
|
break;
|
|
242
|
+
}
|
|
228
243
|
}
|
|
229
244
|
});
|
|
230
245
|
}
|
|
@@ -234,8 +249,9 @@ class TemplateElement extends FASTElement {
|
|
|
234
249
|
* @param strings - The strings array.
|
|
235
250
|
* @param values - The interpreted values.
|
|
236
251
|
* @param self - Indicates that this should refer to itself instead of a property when creating bindings.
|
|
252
|
+
* @param observerMap - ObserverMap instance for caching binding paths (optional).
|
|
237
253
|
*/
|
|
238
|
-
resolveInnerHTML(innerHTML, strings, values, self = false) {
|
|
254
|
+
resolveInnerHTML(innerHTML, strings, values, self = false, parentContext, level, observerMap) {
|
|
239
255
|
return __awaiter(this, void 0, void 0, function* () {
|
|
240
256
|
const behaviorConfig = getNextBehavior(innerHTML);
|
|
241
257
|
if (behaviorConfig === null) {
|
|
@@ -243,14 +259,16 @@ class TemplateElement extends FASTElement {
|
|
|
243
259
|
}
|
|
244
260
|
else {
|
|
245
261
|
switch (behaviorConfig.type) {
|
|
246
|
-
case "dataBinding":
|
|
247
|
-
yield this.resolveDataBinding(innerHTML, strings, values, self, behaviorConfig);
|
|
262
|
+
case "dataBinding": {
|
|
263
|
+
yield this.resolveDataBinding(innerHTML, strings, values, self, behaviorConfig, parentContext, level, observerMap);
|
|
248
264
|
break;
|
|
249
|
-
|
|
265
|
+
}
|
|
266
|
+
case "templateDirective": {
|
|
250
267
|
strings.push(innerHTML.slice(0, behaviorConfig.openingTagStartIndex));
|
|
251
|
-
yield this.resolveTemplateDirective(behaviorConfig, values, innerHTML, self);
|
|
252
|
-
yield this.resolveInnerHTML(innerHTML.slice(behaviorConfig.closingTagEndIndex, innerHTML.length), strings, values, self);
|
|
268
|
+
yield this.resolveTemplateDirective(behaviorConfig, values, innerHTML, self, parentContext, level, observerMap);
|
|
269
|
+
yield this.resolveInnerHTML(innerHTML.slice(behaviorConfig.closingTagEndIndex, innerHTML.length), strings, values, self, parentContext, level, observerMap);
|
|
253
270
|
break;
|
|
271
|
+
}
|
|
254
272
|
}
|
|
255
273
|
}
|
|
256
274
|
});
|
|
@@ -263,7 +281,7 @@ class TemplateElement extends FASTElement {
|
|
|
263
281
|
return __awaiter(this, void 0, void 0, function* () {
|
|
264
282
|
const allPartials = Object.entries(getAllPartials(unresolvedInnerHTML));
|
|
265
283
|
for (let i = 0, partialLength = allPartials.length; i < partialLength; i++) {
|
|
266
|
-
const { strings, values } = yield this.resolveStringsAndValues(allPartials[i][1].innerHTML);
|
|
284
|
+
const { strings, values } = yield this.resolveStringsAndValues(allPartials[i][1].innerHTML, undefined, null, 0, this.observerMap);
|
|
267
285
|
this.partials[allPartials[i][0]] = this.resolveTemplateOrBehavior(strings, values);
|
|
268
286
|
}
|
|
269
287
|
});
|