@microsoft/fast-element 2.0.0-beta.17 → 2.0.0-beta.19
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 +36 -0
- package/CHANGELOG.md +18 -1
- package/dist/dts/dom-policy.d.ts +68 -0
- package/dist/dts/dom.d.ts +116 -0
- package/dist/dts/index.d.ts +3 -2
- package/dist/dts/index.rollup.d.ts +0 -1
- package/dist/dts/index.rollup.debug.d.ts +0 -1
- package/dist/dts/interfaces.d.ts +24 -31
- package/dist/dts/polyfills.d.ts +0 -1
- package/dist/dts/templating/binding-signal.d.ts +3 -1
- package/dist/dts/templating/binding-two-way.d.ts +3 -1
- package/dist/dts/templating/binding.d.ts +16 -5
- package/dist/dts/templating/compiler.d.ts +11 -13
- package/dist/dts/templating/dangerous-html.d.ts +18 -0
- package/dist/dts/templating/html-directive.d.ts +50 -119
- package/dist/dts/templating/node-observation.d.ts +11 -1
- package/dist/dts/templating/ref.d.ts +4 -0
- package/dist/dts/templating/render.d.ts +30 -6
- package/dist/dts/templating/repeat.d.ts +1 -5
- package/dist/dts/templating/template.d.ts +39 -13
- package/dist/dts/templating/view.d.ts +2 -2
- package/dist/dts/utilities.d.ts +39 -0
- package/dist/esm/components/attributes.js +1 -1
- package/dist/esm/components/fast-definitions.js +2 -2
- package/dist/esm/debug.js +4 -1
- package/dist/esm/dom-policy.js +337 -0
- package/dist/esm/dom.js +117 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.rollup.debug.js +3 -1
- package/dist/esm/index.rollup.js +3 -1
- package/dist/esm/interfaces.js +45 -0
- package/dist/esm/observation/observable.js +3 -3
- package/dist/esm/observation/update-queue.js +2 -2
- package/dist/esm/platform.js +1 -1
- package/dist/esm/polyfills.js +3 -7
- package/dist/esm/templating/binding-signal.js +3 -2
- package/dist/esm/templating/binding-two-way.js +3 -2
- package/dist/esm/templating/binding.js +31 -54
- package/dist/esm/templating/compiler.js +31 -38
- package/dist/esm/templating/dangerous-html.js +23 -0
- package/dist/esm/templating/html-directive.js +38 -135
- package/dist/esm/templating/node-observation.js +14 -8
- package/dist/esm/templating/ref.js +1 -1
- package/dist/esm/templating/render.js +17 -6
- package/dist/esm/templating/repeat.js +2 -6
- package/dist/esm/templating/template.js +81 -56
- package/dist/esm/testing/fixture.js +1 -1
- package/dist/esm/utilities.js +68 -0
- package/dist/fast-element.api.json +1088 -608
- package/dist/fast-element.d.ts +190 -147
- package/dist/fast-element.debug.js +756 -388
- package/dist/fast-element.debug.min.js +1 -1
- package/dist/fast-element.js +727 -362
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +190 -147
- package/docs/api-report.md +66 -56
- package/package.json +5 -1
- package/dist/dts/templating/dom.d.ts +0 -41
- package/dist/esm/templating/dom.js +0 -49
|
@@ -1,34 +1,3 @@
|
|
|
1
|
-
(function ensureGlobalThis() {
|
|
2
|
-
if (typeof globalThis !== "undefined") {
|
|
3
|
-
// We're running in a modern environment.
|
|
4
|
-
return;
|
|
5
|
-
}
|
|
6
|
-
if (typeof global !== "undefined") {
|
|
7
|
-
// We're running in NodeJS
|
|
8
|
-
global.globalThis = global;
|
|
9
|
-
}
|
|
10
|
-
else if (typeof self !== "undefined") {
|
|
11
|
-
self.globalThis = self;
|
|
12
|
-
}
|
|
13
|
-
else if (typeof window !== "undefined") {
|
|
14
|
-
// We're running in the browser's main thread.
|
|
15
|
-
window.globalThis = window;
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
// Hopefully we never get here...
|
|
19
|
-
// Not all environments allow eval and Function. Use only as a last resort:
|
|
20
|
-
// eslint-disable-next-line no-new-func
|
|
21
|
-
const result = new Function("return this")();
|
|
22
|
-
result.globalThis = result;
|
|
23
|
-
}
|
|
24
|
-
})();
|
|
25
|
-
// API-only Polyfill for trustedTypes
|
|
26
|
-
if (!globalThis.trustedTypes) {
|
|
27
|
-
globalThis.trustedTypes = {
|
|
28
|
-
createPolicy: (n, r) => r,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
1
|
if (globalThis.FAST === void 0) {
|
|
33
2
|
Reflect.defineProperty(globalThis, "FAST", {
|
|
34
3
|
value: Object.create(null),
|
|
@@ -40,11 +9,14 @@ if (globalThis.FAST === void 0) {
|
|
|
40
9
|
const FAST$1 = globalThis.FAST;
|
|
41
10
|
const debugMessages = {
|
|
42
11
|
[1101 /* needsArrayObservation */]: "Must call enableArrayObservation before observing arrays.",
|
|
43
|
-
[1201 /*
|
|
12
|
+
[1201 /* onlySetDOMPolicyOnce */]: "The DOM Policy can only be set once.",
|
|
44
13
|
[1202 /* bindingInnerHTMLRequiresTrustedTypes */]: "To bind innerHTML, you must use a TrustedTypesPolicy.",
|
|
45
14
|
[1203 /* twoWayBindingRequiresObservables */]: "View=>Model update skipped. To use twoWay binding, the target property must be observable.",
|
|
46
15
|
[1204 /* hostBindingWithoutHost */]: "No host element is present. Cannot bind host with ${name}.",
|
|
47
16
|
[1205 /* unsupportedBindingBehavior */]: "The requested binding behavior is not supported by the binding engine.",
|
|
17
|
+
[1206 /* directCallToHTMLTagNotAllowed */]: "Calling html`` as a normal function invalidates the security guarantees provided by FAST.",
|
|
18
|
+
[1207 /* onlySetTemplatePolicyOnce */]: "The DOM Policy for an HTML template can only be set once.",
|
|
19
|
+
[1208 /* cannotSetTemplatePolicyAfterCompilation */]: "The DOM Policy cannot be set after a template is compiled.",
|
|
48
20
|
[1401 /* missingElementDefinition */]: "Missing FASTElement definition.",
|
|
49
21
|
[1501 /* noRegistrationForContext */]: "No registration for Context/Interface '${name}'.",
|
|
50
22
|
[1502 /* noFactoryForResolver */]: "Dependency injection resolver for '${key}' returned a null factory.",
|
|
@@ -90,7 +62,92 @@ Object.assign(FAST$1, {
|
|
|
90
62
|
},
|
|
91
63
|
});
|
|
92
64
|
|
|
93
|
-
|
|
65
|
+
let kernelMode;
|
|
66
|
+
const kernelAttr = "fast-kernel";
|
|
67
|
+
try {
|
|
68
|
+
if (document.currentScript) {
|
|
69
|
+
kernelMode = document.currentScript.getAttribute(kernelAttr);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const scripts = document.getElementsByTagName("script");
|
|
73
|
+
const currentScript = scripts[scripts.length - 1];
|
|
74
|
+
kernelMode = currentScript.getAttribute(kernelAttr);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
kernelMode = "isolate";
|
|
79
|
+
}
|
|
80
|
+
let KernelServiceId;
|
|
81
|
+
switch (kernelMode) {
|
|
82
|
+
case "share": // share the kernel across major versions
|
|
83
|
+
KernelServiceId = Object.freeze({
|
|
84
|
+
updateQueue: 1,
|
|
85
|
+
observable: 2,
|
|
86
|
+
contextEvent: 3,
|
|
87
|
+
elementRegistry: 4,
|
|
88
|
+
});
|
|
89
|
+
break;
|
|
90
|
+
case "share-v2": // only share the kernel with other v2 instances
|
|
91
|
+
KernelServiceId = Object.freeze({
|
|
92
|
+
updateQueue: 1.2,
|
|
93
|
+
observable: 2.2,
|
|
94
|
+
contextEvent: 3.2,
|
|
95
|
+
elementRegistry: 4.2,
|
|
96
|
+
});
|
|
97
|
+
break;
|
|
98
|
+
default:
|
|
99
|
+
// fully isolate the kernel from all other FAST instances
|
|
100
|
+
const postfix = `-${Math.random().toString(36).substring(2, 8)}`;
|
|
101
|
+
KernelServiceId = Object.freeze({
|
|
102
|
+
updateQueue: `1.2${postfix}`,
|
|
103
|
+
observable: `2.2${postfix}`,
|
|
104
|
+
contextEvent: `3.2${postfix}`,
|
|
105
|
+
elementRegistry: `4.2${postfix}`,
|
|
106
|
+
});
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* @internal
|
|
111
|
+
*/
|
|
112
|
+
const isFunction = (object) => typeof object === "function";
|
|
113
|
+
/**
|
|
114
|
+
* @internal
|
|
115
|
+
*/
|
|
116
|
+
const isString = (object) => typeof object === "string";
|
|
117
|
+
/**
|
|
118
|
+
* @internal
|
|
119
|
+
*/
|
|
120
|
+
const noop = () => void 0;
|
|
121
|
+
|
|
122
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
123
|
+
(function ensureGlobalThis() {
|
|
124
|
+
if (typeof globalThis !== "undefined") {
|
|
125
|
+
// We're running in a modern environment.
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
// @ts-ignore
|
|
129
|
+
if (typeof global !== "undefined") {
|
|
130
|
+
// We're running in NodeJS
|
|
131
|
+
// @ts-ignore
|
|
132
|
+
global.globalThis = global;
|
|
133
|
+
}
|
|
134
|
+
else if (typeof self !== "undefined") {
|
|
135
|
+
self.globalThis = self;
|
|
136
|
+
}
|
|
137
|
+
else if (typeof window !== "undefined") {
|
|
138
|
+
// We're running in the browser's main thread.
|
|
139
|
+
window.globalThis = window;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
// Hopefully we never get here...
|
|
143
|
+
// Not all environments allow eval and Function. Use only as a last resort:
|
|
144
|
+
// eslint-disable-next-line no-new-func
|
|
145
|
+
const result = new Function("return this")();
|
|
146
|
+
result.globalThis = result;
|
|
147
|
+
}
|
|
148
|
+
})();
|
|
149
|
+
|
|
150
|
+
// ensure FAST global - duplicated debug.ts
|
|
94
151
|
const propConfig = {
|
|
95
152
|
configurable: false,
|
|
96
153
|
enumerable: false,
|
|
@@ -178,24 +235,11 @@ function createMetadataLocator() {
|
|
|
178
235
|
};
|
|
179
236
|
}
|
|
180
237
|
|
|
181
|
-
/**
|
|
182
|
-
* @internal
|
|
183
|
-
*/
|
|
184
|
-
const isFunction = (object) => typeof object === "function";
|
|
185
|
-
/**
|
|
186
|
-
* @internal
|
|
187
|
-
*/
|
|
188
|
-
const isString = (object) => typeof object === "string";
|
|
189
|
-
/**
|
|
190
|
-
* @internal
|
|
191
|
-
*/
|
|
192
|
-
const noop = () => void 0;
|
|
193
|
-
|
|
194
238
|
/**
|
|
195
239
|
* The default UpdateQueue.
|
|
196
240
|
* @public
|
|
197
241
|
*/
|
|
198
|
-
const Updates = FAST.getById(
|
|
242
|
+
const Updates = FAST.getById(KernelServiceId.updateQueue, () => {
|
|
199
243
|
const tasks = [];
|
|
200
244
|
const pendingErrors = [];
|
|
201
245
|
const rAF = globalThis.requestAnimationFrame;
|
|
@@ -257,6 +301,456 @@ const Updates = FAST.getById(1 /* KernelServiceId.updateQueue */, () => {
|
|
|
257
301
|
});
|
|
258
302
|
});
|
|
259
303
|
|
|
304
|
+
/**
|
|
305
|
+
* The type of HTML aspect to target.
|
|
306
|
+
* @public
|
|
307
|
+
*/
|
|
308
|
+
const DOMAspect = Object.freeze({
|
|
309
|
+
/**
|
|
310
|
+
* Not aspected.
|
|
311
|
+
*/
|
|
312
|
+
none: 0,
|
|
313
|
+
/**
|
|
314
|
+
* An attribute.
|
|
315
|
+
*/
|
|
316
|
+
attribute: 1,
|
|
317
|
+
/**
|
|
318
|
+
* A boolean attribute.
|
|
319
|
+
*/
|
|
320
|
+
booleanAttribute: 2,
|
|
321
|
+
/**
|
|
322
|
+
* A property.
|
|
323
|
+
*/
|
|
324
|
+
property: 3,
|
|
325
|
+
/**
|
|
326
|
+
* Content
|
|
327
|
+
*/
|
|
328
|
+
content: 4,
|
|
329
|
+
/**
|
|
330
|
+
* A token list.
|
|
331
|
+
*/
|
|
332
|
+
tokenList: 5,
|
|
333
|
+
/**
|
|
334
|
+
* An event.
|
|
335
|
+
*/
|
|
336
|
+
event: 6,
|
|
337
|
+
});
|
|
338
|
+
const createHTML$1 = html => html;
|
|
339
|
+
const fastTrustedType = globalThis.trustedTypes
|
|
340
|
+
? globalThis.trustedTypes.createPolicy("fast-html", { createHTML: createHTML$1 })
|
|
341
|
+
: { createHTML: createHTML$1 };
|
|
342
|
+
let defaultPolicy = Object.freeze({
|
|
343
|
+
createHTML(value) {
|
|
344
|
+
return fastTrustedType.createHTML(value);
|
|
345
|
+
},
|
|
346
|
+
protect(tagName, aspect, aspectName, sink) {
|
|
347
|
+
return sink;
|
|
348
|
+
},
|
|
349
|
+
});
|
|
350
|
+
const fastPolicy = defaultPolicy;
|
|
351
|
+
/**
|
|
352
|
+
* Common DOM APIs.
|
|
353
|
+
* @public
|
|
354
|
+
*/
|
|
355
|
+
const DOM = Object.freeze({
|
|
356
|
+
/**
|
|
357
|
+
* @deprecated
|
|
358
|
+
* Use Updates.enqueue().
|
|
359
|
+
*/
|
|
360
|
+
queueUpdate: Updates.enqueue,
|
|
361
|
+
/**
|
|
362
|
+
* @deprecated
|
|
363
|
+
* Use Updates.next()
|
|
364
|
+
*/
|
|
365
|
+
nextUpdate: Updates.next,
|
|
366
|
+
/**
|
|
367
|
+
* @deprecated
|
|
368
|
+
* Use Updates.process()
|
|
369
|
+
*/
|
|
370
|
+
processUpdates: Updates.process,
|
|
371
|
+
/**
|
|
372
|
+
* Gets the dom policy used by the templating system.
|
|
373
|
+
*/
|
|
374
|
+
get policy() {
|
|
375
|
+
return defaultPolicy;
|
|
376
|
+
},
|
|
377
|
+
/**
|
|
378
|
+
* Sets the dom policy used by the templating system.
|
|
379
|
+
* @param policy - The policy to set.
|
|
380
|
+
* @remarks
|
|
381
|
+
* This API can only be called once, for security reasons. It should be
|
|
382
|
+
* called by the application developer at the start of their program.
|
|
383
|
+
*/
|
|
384
|
+
setPolicy(value) {
|
|
385
|
+
if (defaultPolicy !== fastPolicy) {
|
|
386
|
+
throw FAST.error(1201 /* Message.onlySetDOMPolicyOnce */);
|
|
387
|
+
}
|
|
388
|
+
defaultPolicy = value;
|
|
389
|
+
},
|
|
390
|
+
/**
|
|
391
|
+
* Sets an attribute value on an element.
|
|
392
|
+
* @param element - The element to set the attribute value on.
|
|
393
|
+
* @param attributeName - The attribute name to set.
|
|
394
|
+
* @param value - The value of the attribute to set.
|
|
395
|
+
* @remarks
|
|
396
|
+
* If the value is `null` or `undefined`, the attribute is removed, otherwise
|
|
397
|
+
* it is set to the provided value using the standard `setAttribute` API.
|
|
398
|
+
*/
|
|
399
|
+
setAttribute(element, attributeName, value) {
|
|
400
|
+
value === null || value === undefined
|
|
401
|
+
? element.removeAttribute(attributeName)
|
|
402
|
+
: element.setAttribute(attributeName, value);
|
|
403
|
+
},
|
|
404
|
+
/**
|
|
405
|
+
* Sets a boolean attribute value.
|
|
406
|
+
* @param element - The element to set the boolean attribute value on.
|
|
407
|
+
* @param attributeName - The attribute name to set.
|
|
408
|
+
* @param value - The value of the attribute to set.
|
|
409
|
+
* @remarks
|
|
410
|
+
* If the value is true, the attribute is added; otherwise it is removed.
|
|
411
|
+
*/
|
|
412
|
+
setBooleanAttribute(element, attributeName, value) {
|
|
413
|
+
value
|
|
414
|
+
? element.setAttribute(attributeName, "")
|
|
415
|
+
: element.removeAttribute(attributeName);
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
function safeURL(tagName, aspect, aspectName, sink) {
|
|
420
|
+
return (target, name, value, ...rest) => {
|
|
421
|
+
if (isString(value)) {
|
|
422
|
+
value = value.replace("javascript:", "");
|
|
423
|
+
}
|
|
424
|
+
sink(target, name, value, ...rest);
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
function block(tagName, aspect, aspectName, sink) {
|
|
428
|
+
throw new Error(`${aspectName} on ${tagName !== null && tagName !== void 0 ? tagName : "text"} is blocked by the current DOMPolicy.`);
|
|
429
|
+
}
|
|
430
|
+
const defaultDOMElementGuards = {
|
|
431
|
+
a: {
|
|
432
|
+
[DOMAspect.attribute]: {
|
|
433
|
+
href: safeURL,
|
|
434
|
+
},
|
|
435
|
+
[DOMAspect.property]: {
|
|
436
|
+
href: safeURL,
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
area: {
|
|
440
|
+
[DOMAspect.attribute]: {
|
|
441
|
+
href: safeURL,
|
|
442
|
+
},
|
|
443
|
+
[DOMAspect.property]: {
|
|
444
|
+
href: safeURL,
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
button: {
|
|
448
|
+
[DOMAspect.attribute]: {
|
|
449
|
+
formaction: safeURL,
|
|
450
|
+
},
|
|
451
|
+
[DOMAspect.property]: {
|
|
452
|
+
formAction: safeURL,
|
|
453
|
+
},
|
|
454
|
+
},
|
|
455
|
+
embed: {
|
|
456
|
+
[DOMAspect.attribute]: {
|
|
457
|
+
src: block,
|
|
458
|
+
},
|
|
459
|
+
[DOMAspect.property]: {
|
|
460
|
+
src: block,
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
form: {
|
|
464
|
+
[DOMAspect.attribute]: {
|
|
465
|
+
action: safeURL,
|
|
466
|
+
},
|
|
467
|
+
[DOMAspect.property]: {
|
|
468
|
+
action: safeURL,
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
frame: {
|
|
472
|
+
[DOMAspect.attribute]: {
|
|
473
|
+
src: safeURL,
|
|
474
|
+
},
|
|
475
|
+
[DOMAspect.property]: {
|
|
476
|
+
src: safeURL,
|
|
477
|
+
},
|
|
478
|
+
},
|
|
479
|
+
iframe: {
|
|
480
|
+
[DOMAspect.attribute]: {
|
|
481
|
+
src: safeURL,
|
|
482
|
+
},
|
|
483
|
+
[DOMAspect.property]: {
|
|
484
|
+
src: safeURL,
|
|
485
|
+
srcdoc: block,
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
input: {
|
|
489
|
+
[DOMAspect.attribute]: {
|
|
490
|
+
formaction: safeURL,
|
|
491
|
+
},
|
|
492
|
+
[DOMAspect.property]: {
|
|
493
|
+
formAction: safeURL,
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
link: {
|
|
497
|
+
[DOMAspect.attribute]: {
|
|
498
|
+
href: block,
|
|
499
|
+
},
|
|
500
|
+
[DOMAspect.property]: {
|
|
501
|
+
href: block,
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
object: {
|
|
505
|
+
[DOMAspect.attribute]: {
|
|
506
|
+
codebase: block,
|
|
507
|
+
data: block,
|
|
508
|
+
},
|
|
509
|
+
[DOMAspect.property]: {
|
|
510
|
+
codeBase: block,
|
|
511
|
+
data: block,
|
|
512
|
+
},
|
|
513
|
+
},
|
|
514
|
+
script: {
|
|
515
|
+
[DOMAspect.attribute]: {
|
|
516
|
+
src: block,
|
|
517
|
+
text: block,
|
|
518
|
+
},
|
|
519
|
+
[DOMAspect.property]: {
|
|
520
|
+
src: block,
|
|
521
|
+
text: block,
|
|
522
|
+
innerText: block,
|
|
523
|
+
textContent: block,
|
|
524
|
+
},
|
|
525
|
+
},
|
|
526
|
+
style: {
|
|
527
|
+
[DOMAspect.property]: {
|
|
528
|
+
innerText: block,
|
|
529
|
+
textContent: block,
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
};
|
|
533
|
+
const blockedEvents = {
|
|
534
|
+
onabort: block,
|
|
535
|
+
onauxclick: block,
|
|
536
|
+
onbeforeinput: block,
|
|
537
|
+
onbeforematch: block,
|
|
538
|
+
onblur: block,
|
|
539
|
+
oncancel: block,
|
|
540
|
+
oncanplay: block,
|
|
541
|
+
oncanplaythrough: block,
|
|
542
|
+
onchange: block,
|
|
543
|
+
onclick: block,
|
|
544
|
+
onclose: block,
|
|
545
|
+
oncontextlost: block,
|
|
546
|
+
oncontextmenu: block,
|
|
547
|
+
oncontextrestored: block,
|
|
548
|
+
oncopy: block,
|
|
549
|
+
oncuechange: block,
|
|
550
|
+
oncut: block,
|
|
551
|
+
ondblclick: block,
|
|
552
|
+
ondrag: block,
|
|
553
|
+
ondragend: block,
|
|
554
|
+
ondragenter: block,
|
|
555
|
+
ondragleave: block,
|
|
556
|
+
ondragover: block,
|
|
557
|
+
ondragstart: block,
|
|
558
|
+
ondrop: block,
|
|
559
|
+
ondurationchange: block,
|
|
560
|
+
onemptied: block,
|
|
561
|
+
onended: block,
|
|
562
|
+
onerror: block,
|
|
563
|
+
onfocus: block,
|
|
564
|
+
onformdata: block,
|
|
565
|
+
oninput: block,
|
|
566
|
+
oninvalid: block,
|
|
567
|
+
onkeydown: block,
|
|
568
|
+
onkeypress: block,
|
|
569
|
+
onkeyup: block,
|
|
570
|
+
onload: block,
|
|
571
|
+
onloadeddata: block,
|
|
572
|
+
onloadedmetadata: block,
|
|
573
|
+
onloadstart: block,
|
|
574
|
+
onmousedown: block,
|
|
575
|
+
onmouseenter: block,
|
|
576
|
+
onmouseleave: block,
|
|
577
|
+
onmousemove: block,
|
|
578
|
+
onmouseout: block,
|
|
579
|
+
onmouseover: block,
|
|
580
|
+
onmouseup: block,
|
|
581
|
+
onpaste: block,
|
|
582
|
+
onpause: block,
|
|
583
|
+
onplay: block,
|
|
584
|
+
onplaying: block,
|
|
585
|
+
onprogress: block,
|
|
586
|
+
onratechange: block,
|
|
587
|
+
onreset: block,
|
|
588
|
+
onresize: block,
|
|
589
|
+
onscroll: block,
|
|
590
|
+
onsecuritypolicyviolation: block,
|
|
591
|
+
onseeked: block,
|
|
592
|
+
onseeking: block,
|
|
593
|
+
onselect: block,
|
|
594
|
+
onslotchange: block,
|
|
595
|
+
onstalled: block,
|
|
596
|
+
onsubmit: block,
|
|
597
|
+
onsuspend: block,
|
|
598
|
+
ontimeupdate: block,
|
|
599
|
+
ontoggle: block,
|
|
600
|
+
onvolumechange: block,
|
|
601
|
+
onwaiting: block,
|
|
602
|
+
onwebkitanimationend: block,
|
|
603
|
+
onwebkitanimationiteration: block,
|
|
604
|
+
onwebkitanimationstart: block,
|
|
605
|
+
onwebkittransitionend: block,
|
|
606
|
+
onwheel: block,
|
|
607
|
+
};
|
|
608
|
+
const defaultDOMGuards = {
|
|
609
|
+
elements: defaultDOMElementGuards,
|
|
610
|
+
aspects: {
|
|
611
|
+
[DOMAspect.attribute]: Object.assign({}, blockedEvents),
|
|
612
|
+
[DOMAspect.property]: Object.assign({ innerHTML: block }, blockedEvents),
|
|
613
|
+
[DOMAspect.event]: Object.assign({}, blockedEvents),
|
|
614
|
+
},
|
|
615
|
+
};
|
|
616
|
+
function createDomSinkGuards(config, defaults) {
|
|
617
|
+
const result = {};
|
|
618
|
+
for (const name in defaults) {
|
|
619
|
+
const overrideValue = config[name];
|
|
620
|
+
const defaultValue = defaults[name];
|
|
621
|
+
switch (overrideValue) {
|
|
622
|
+
case null:
|
|
623
|
+
// remove the default
|
|
624
|
+
break;
|
|
625
|
+
case undefined:
|
|
626
|
+
// keep the default
|
|
627
|
+
result[name] = defaultValue;
|
|
628
|
+
break;
|
|
629
|
+
default:
|
|
630
|
+
// override the default
|
|
631
|
+
result[name] = overrideValue;
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
// add any new sinks that were not overrides
|
|
636
|
+
for (const name in config) {
|
|
637
|
+
if (!(name in result)) {
|
|
638
|
+
result[name] = config[name];
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return Object.freeze(result);
|
|
642
|
+
}
|
|
643
|
+
function createDOMAspectGuards(config, defaults) {
|
|
644
|
+
const result = {};
|
|
645
|
+
for (const aspect in defaults) {
|
|
646
|
+
const overrideValue = config[aspect];
|
|
647
|
+
const defaultValue = defaults[aspect];
|
|
648
|
+
switch (overrideValue) {
|
|
649
|
+
case null:
|
|
650
|
+
// remove the default
|
|
651
|
+
break;
|
|
652
|
+
case undefined:
|
|
653
|
+
// keep the default
|
|
654
|
+
result[aspect] = createDomSinkGuards(defaultValue, {});
|
|
655
|
+
break;
|
|
656
|
+
default:
|
|
657
|
+
// override the default
|
|
658
|
+
result[aspect] = createDomSinkGuards(overrideValue, defaultValue);
|
|
659
|
+
break;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
// add any new aspect guards that were not overrides
|
|
663
|
+
for (const aspect in config) {
|
|
664
|
+
if (!(aspect in result)) {
|
|
665
|
+
result[aspect] = createDomSinkGuards(config[aspect], {});
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
return Object.freeze(result);
|
|
669
|
+
}
|
|
670
|
+
function createElementGuards(config, defaults) {
|
|
671
|
+
const result = {};
|
|
672
|
+
for (const tag in defaults) {
|
|
673
|
+
const overrideValue = config[tag];
|
|
674
|
+
const defaultValue = defaults[tag];
|
|
675
|
+
switch (overrideValue) {
|
|
676
|
+
case null:
|
|
677
|
+
// remove the default
|
|
678
|
+
break;
|
|
679
|
+
case undefined:
|
|
680
|
+
// keep the default
|
|
681
|
+
result[tag] = createDOMAspectGuards(overrideValue, {});
|
|
682
|
+
break;
|
|
683
|
+
default:
|
|
684
|
+
// override the default aspects
|
|
685
|
+
result[tag] = createDOMAspectGuards(overrideValue, defaultValue);
|
|
686
|
+
break;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
// Add any new element guards that were not overrides
|
|
690
|
+
for (const tag in config) {
|
|
691
|
+
if (!(tag in result)) {
|
|
692
|
+
result[tag] = createDOMAspectGuards(config[tag], {});
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return Object.freeze(result);
|
|
696
|
+
}
|
|
697
|
+
function createDOMGuards(config, defaults) {
|
|
698
|
+
return Object.freeze({
|
|
699
|
+
elements: config.elements
|
|
700
|
+
? createElementGuards(config.elements, defaults.elements)
|
|
701
|
+
: defaults.elements,
|
|
702
|
+
aspects: config.aspects
|
|
703
|
+
? createDOMAspectGuards(config.aspects, defaults.aspects)
|
|
704
|
+
: defaults.aspects,
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
function createTrustedType() {
|
|
708
|
+
const createHTML = html => html;
|
|
709
|
+
return globalThis.trustedTypes
|
|
710
|
+
? globalThis.trustedTypes.createPolicy("fast-html", { createHTML })
|
|
711
|
+
: { createHTML };
|
|
712
|
+
}
|
|
713
|
+
function tryGuard(aspectGuards, tagName, aspect, aspectName, sink) {
|
|
714
|
+
const sinkGuards = aspectGuards[aspect];
|
|
715
|
+
if (sinkGuards) {
|
|
716
|
+
const guard = sinkGuards[aspectName];
|
|
717
|
+
if (guard) {
|
|
718
|
+
return guard(tagName, aspect, aspectName, sink);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
const DOMPolicy = Object.freeze({
|
|
723
|
+
/**
|
|
724
|
+
* Creates a new DOM Policy object.
|
|
725
|
+
* @param options The options to use in creating the policy.
|
|
726
|
+
* @returns The newly created DOMPolicy.
|
|
727
|
+
*/
|
|
728
|
+
create(options = {}) {
|
|
729
|
+
var _a, _b;
|
|
730
|
+
const trustedType = (_a = options.trustedType) !== null && _a !== void 0 ? _a : createTrustedType();
|
|
731
|
+
const guards = createDOMGuards((_b = options.guards) !== null && _b !== void 0 ? _b : {}, defaultDOMGuards);
|
|
732
|
+
return Object.freeze({
|
|
733
|
+
createHTML(value) {
|
|
734
|
+
return trustedType.createHTML(value);
|
|
735
|
+
},
|
|
736
|
+
protect(tagName, aspect, aspectName, sink) {
|
|
737
|
+
var _a;
|
|
738
|
+
// Check for element-specific guards.
|
|
739
|
+
const key = (tagName !== null && tagName !== void 0 ? tagName : "").toLowerCase();
|
|
740
|
+
const elementGuards = guards.elements[key];
|
|
741
|
+
if (elementGuards) {
|
|
742
|
+
const guard = tryGuard(elementGuards, tagName, aspect, aspectName, sink);
|
|
743
|
+
if (guard) {
|
|
744
|
+
return guard;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
// Check for guards applicable to all nodes.
|
|
748
|
+
return ((_a = tryGuard(guards.aspects, tagName, aspect, aspectName, sink)) !== null && _a !== void 0 ? _a : sink);
|
|
749
|
+
},
|
|
750
|
+
});
|
|
751
|
+
},
|
|
752
|
+
});
|
|
753
|
+
|
|
260
754
|
/**
|
|
261
755
|
* An implementation of {@link Notifier} that efficiently keeps track of
|
|
262
756
|
* subscribers interested in a specific change notification on an
|
|
@@ -441,7 +935,7 @@ const SourceLifetime = Object.freeze({
|
|
|
441
935
|
* Common Observable APIs.
|
|
442
936
|
* @public
|
|
443
937
|
*/
|
|
444
|
-
const Observable = FAST.getById(
|
|
938
|
+
const Observable = FAST.getById(KernelServiceId.observable, () => {
|
|
445
939
|
const queueUpdate = Updates.enqueue;
|
|
446
940
|
const volatileRegex = /(:|&&|\|\||if)/;
|
|
447
941
|
const notifierLookup = new WeakMap();
|
|
@@ -712,7 +1206,7 @@ function volatile(target, name, descriptor) {
|
|
|
712
1206
|
},
|
|
713
1207
|
});
|
|
714
1208
|
}
|
|
715
|
-
const contextEvent = FAST.getById(
|
|
1209
|
+
const contextEvent = FAST.getById(KernelServiceId.contextEvent, () => {
|
|
716
1210
|
let current = null;
|
|
717
1211
|
return {
|
|
718
1212
|
get() {
|
|
@@ -1543,55 +2037,6 @@ css.partial = (strings, ...values) => {
|
|
|
1543
2037
|
*/
|
|
1544
2038
|
const cssPartial = css.partial;
|
|
1545
2039
|
|
|
1546
|
-
/**
|
|
1547
|
-
* Common DOM APIs.
|
|
1548
|
-
* @public
|
|
1549
|
-
*/
|
|
1550
|
-
const DOM = Object.freeze({
|
|
1551
|
-
/**
|
|
1552
|
-
* @deprecated
|
|
1553
|
-
* Use Updates.enqueue().
|
|
1554
|
-
*/
|
|
1555
|
-
queueUpdate: Updates.enqueue,
|
|
1556
|
-
/**
|
|
1557
|
-
* @deprecated
|
|
1558
|
-
* Use Updates.next()
|
|
1559
|
-
*/
|
|
1560
|
-
nextUpdate: Updates.next,
|
|
1561
|
-
/**
|
|
1562
|
-
* @deprecated
|
|
1563
|
-
* Use Updates.process()
|
|
1564
|
-
*/
|
|
1565
|
-
processUpdates: Updates.process,
|
|
1566
|
-
/**
|
|
1567
|
-
* Sets an attribute value on an element.
|
|
1568
|
-
* @param element - The element to set the attribute value on.
|
|
1569
|
-
* @param attributeName - The attribute name to set.
|
|
1570
|
-
* @param value - The value of the attribute to set.
|
|
1571
|
-
* @remarks
|
|
1572
|
-
* If the value is `null` or `undefined`, the attribute is removed, otherwise
|
|
1573
|
-
* it is set to the provided value using the standard `setAttribute` API.
|
|
1574
|
-
*/
|
|
1575
|
-
setAttribute(element, attributeName, value) {
|
|
1576
|
-
value === null || value === undefined
|
|
1577
|
-
? element.removeAttribute(attributeName)
|
|
1578
|
-
: element.setAttribute(attributeName, value);
|
|
1579
|
-
},
|
|
1580
|
-
/**
|
|
1581
|
-
* Sets a boolean attribute value.
|
|
1582
|
-
* @param element - The element to set the boolean attribute value on.
|
|
1583
|
-
* @param attributeName - The attribute name to set.
|
|
1584
|
-
* @param value - The value of the attribute to set.
|
|
1585
|
-
* @remarks
|
|
1586
|
-
* If the value is true, the attribute is added; otherwise it is removed.
|
|
1587
|
-
*/
|
|
1588
|
-
setBooleanAttribute(element, attributeName, value) {
|
|
1589
|
-
value
|
|
1590
|
-
? element.setAttribute(attributeName, "")
|
|
1591
|
-
: element.removeAttribute(attributeName);
|
|
1592
|
-
},
|
|
1593
|
-
});
|
|
1594
|
-
|
|
1595
2040
|
const marker = `fast-${Math.random().toString(36).substring(2, 8)}`;
|
|
1596
2041
|
const interpolationStart = `${marker}{`;
|
|
1597
2042
|
const interpolationEnd = `}${marker}`;
|
|
@@ -1668,67 +2113,6 @@ const Parser = Object.freeze({
|
|
|
1668
2113
|
},
|
|
1669
2114
|
});
|
|
1670
2115
|
|
|
1671
|
-
/**
|
|
1672
|
-
* Bridges between ViewBehaviors and HostBehaviors, enabling a host to
|
|
1673
|
-
* control ViewBehaviors.
|
|
1674
|
-
* @public
|
|
1675
|
-
*/
|
|
1676
|
-
const ViewBehaviorOrchestrator = Object.freeze({
|
|
1677
|
-
/**
|
|
1678
|
-
* Creates a ViewBehaviorOrchestrator.
|
|
1679
|
-
* @param source - The source to to associate behaviors with.
|
|
1680
|
-
* @returns A ViewBehaviorOrchestrator.
|
|
1681
|
-
*/
|
|
1682
|
-
create(source) {
|
|
1683
|
-
const behaviors = [];
|
|
1684
|
-
const targets = {};
|
|
1685
|
-
let unbindables = null;
|
|
1686
|
-
let isConnected = false;
|
|
1687
|
-
return {
|
|
1688
|
-
source,
|
|
1689
|
-
context: ExecutionContext.default,
|
|
1690
|
-
targets,
|
|
1691
|
-
get isBound() {
|
|
1692
|
-
return isConnected;
|
|
1693
|
-
},
|
|
1694
|
-
addBehaviorFactory(factory, target) {
|
|
1695
|
-
const nodeId = factory.nodeId || (factory.nodeId = nextId());
|
|
1696
|
-
factory.id || (factory.id = nextId());
|
|
1697
|
-
this.addTarget(nodeId, target);
|
|
1698
|
-
this.addBehavior(factory.createBehavior());
|
|
1699
|
-
},
|
|
1700
|
-
addTarget(nodeId, target) {
|
|
1701
|
-
targets[nodeId] = target;
|
|
1702
|
-
},
|
|
1703
|
-
addBehavior(behavior) {
|
|
1704
|
-
behaviors.push(behavior);
|
|
1705
|
-
if (isConnected) {
|
|
1706
|
-
behavior.bind(this);
|
|
1707
|
-
}
|
|
1708
|
-
},
|
|
1709
|
-
onUnbind(unbindable) {
|
|
1710
|
-
if (unbindables === null) {
|
|
1711
|
-
unbindables = [];
|
|
1712
|
-
}
|
|
1713
|
-
unbindables.push(unbindable);
|
|
1714
|
-
},
|
|
1715
|
-
connectedCallback(controller) {
|
|
1716
|
-
if (!isConnected) {
|
|
1717
|
-
isConnected = true;
|
|
1718
|
-
behaviors.forEach(x => x.bind(this));
|
|
1719
|
-
}
|
|
1720
|
-
},
|
|
1721
|
-
disconnectedCallback(controller) {
|
|
1722
|
-
if (isConnected) {
|
|
1723
|
-
isConnected = false;
|
|
1724
|
-
if (unbindables !== null) {
|
|
1725
|
-
unbindables.forEach(x => x.unbind(this));
|
|
1726
|
-
}
|
|
1727
|
-
}
|
|
1728
|
-
},
|
|
1729
|
-
};
|
|
1730
|
-
},
|
|
1731
|
-
});
|
|
1732
2116
|
const registry = createTypeRegistry();
|
|
1733
2117
|
/**
|
|
1734
2118
|
* Instructs the template engine to apply behavior to a node.
|
|
@@ -1756,67 +2140,6 @@ const HTMLDirective = Object.freeze({
|
|
|
1756
2140
|
registry.register(options);
|
|
1757
2141
|
return type;
|
|
1758
2142
|
},
|
|
1759
|
-
});
|
|
1760
|
-
/**
|
|
1761
|
-
* Decorator: Defines an HTMLDirective.
|
|
1762
|
-
* @param options - Provides options that specify the directive's application.
|
|
1763
|
-
* @public
|
|
1764
|
-
*/
|
|
1765
|
-
function htmlDirective(options) {
|
|
1766
|
-
/* eslint-disable-next-line @typescript-eslint/explicit-function-return-type */
|
|
1767
|
-
return function (type) {
|
|
1768
|
-
HTMLDirective.define(type, options);
|
|
1769
|
-
};
|
|
1770
|
-
}
|
|
1771
|
-
/**
|
|
1772
|
-
* Captures a binding expression along with related information and capabilities.
|
|
1773
|
-
*
|
|
1774
|
-
* @public
|
|
1775
|
-
*/
|
|
1776
|
-
class Binding {
|
|
1777
|
-
/**
|
|
1778
|
-
* Creates a binding.
|
|
1779
|
-
* @param evaluate - Evaluates the binding.
|
|
1780
|
-
* @param isVolatile - Indicates whether the binding is volatile.
|
|
1781
|
-
*/
|
|
1782
|
-
constructor(evaluate, isVolatile = false) {
|
|
1783
|
-
this.evaluate = evaluate;
|
|
1784
|
-
this.isVolatile = isVolatile;
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1787
|
-
/**
|
|
1788
|
-
* The type of HTML aspect to target.
|
|
1789
|
-
* @public
|
|
1790
|
-
*/
|
|
1791
|
-
const Aspect = Object.freeze({
|
|
1792
|
-
/**
|
|
1793
|
-
* Not aspected.
|
|
1794
|
-
*/
|
|
1795
|
-
none: 0,
|
|
1796
|
-
/**
|
|
1797
|
-
* An attribute.
|
|
1798
|
-
*/
|
|
1799
|
-
attribute: 1,
|
|
1800
|
-
/**
|
|
1801
|
-
* A boolean attribute.
|
|
1802
|
-
*/
|
|
1803
|
-
booleanAttribute: 2,
|
|
1804
|
-
/**
|
|
1805
|
-
* A property.
|
|
1806
|
-
*/
|
|
1807
|
-
property: 3,
|
|
1808
|
-
/**
|
|
1809
|
-
* Content
|
|
1810
|
-
*/
|
|
1811
|
-
content: 4,
|
|
1812
|
-
/**
|
|
1813
|
-
* A token list.
|
|
1814
|
-
*/
|
|
1815
|
-
tokenList: 5,
|
|
1816
|
-
/**
|
|
1817
|
-
* An event.
|
|
1818
|
-
*/
|
|
1819
|
-
event: 6,
|
|
1820
2143
|
/**
|
|
1821
2144
|
*
|
|
1822
2145
|
* @param directive - The directive to assign the aspect to.
|
|
@@ -1824,9 +2147,9 @@ const Aspect = Object.freeze({
|
|
|
1824
2147
|
* @remarks
|
|
1825
2148
|
* If a falsy value is provided, then the content aspect will be assigned.
|
|
1826
2149
|
*/
|
|
1827
|
-
|
|
2150
|
+
assignAspect(directive, value) {
|
|
1828
2151
|
if (!value) {
|
|
1829
|
-
directive.aspectType =
|
|
2152
|
+
directive.aspectType = DOMAspect.content;
|
|
1830
2153
|
return;
|
|
1831
2154
|
}
|
|
1832
2155
|
directive.sourceAspect = value;
|
|
@@ -1835,24 +2158,53 @@ const Aspect = Object.freeze({
|
|
|
1835
2158
|
directive.targetAspect = value.substring(1);
|
|
1836
2159
|
directive.aspectType =
|
|
1837
2160
|
directive.targetAspect === "classList"
|
|
1838
|
-
?
|
|
1839
|
-
:
|
|
2161
|
+
? DOMAspect.tokenList
|
|
2162
|
+
: DOMAspect.property;
|
|
1840
2163
|
break;
|
|
1841
2164
|
case "?":
|
|
1842
2165
|
directive.targetAspect = value.substring(1);
|
|
1843
|
-
directive.aspectType =
|
|
2166
|
+
directive.aspectType = DOMAspect.booleanAttribute;
|
|
1844
2167
|
break;
|
|
1845
2168
|
case "@":
|
|
1846
2169
|
directive.targetAspect = value.substring(1);
|
|
1847
|
-
directive.aspectType =
|
|
2170
|
+
directive.aspectType = DOMAspect.event;
|
|
1848
2171
|
break;
|
|
1849
2172
|
default:
|
|
1850
2173
|
directive.targetAspect = value;
|
|
1851
|
-
directive.aspectType =
|
|
2174
|
+
directive.aspectType = DOMAspect.attribute;
|
|
1852
2175
|
break;
|
|
1853
2176
|
}
|
|
1854
2177
|
},
|
|
1855
2178
|
});
|
|
2179
|
+
/**
|
|
2180
|
+
* Decorator: Defines an HTMLDirective.
|
|
2181
|
+
* @param options - Provides options that specify the directive's application.
|
|
2182
|
+
* @public
|
|
2183
|
+
*/
|
|
2184
|
+
function htmlDirective(options) {
|
|
2185
|
+
/* eslint-disable-next-line @typescript-eslint/explicit-function-return-type */
|
|
2186
|
+
return function (type) {
|
|
2187
|
+
HTMLDirective.define(type, options);
|
|
2188
|
+
};
|
|
2189
|
+
}
|
|
2190
|
+
/**
|
|
2191
|
+
* Captures a binding expression along with related information and capabilities.
|
|
2192
|
+
*
|
|
2193
|
+
* @public
|
|
2194
|
+
*/
|
|
2195
|
+
class Binding {
|
|
2196
|
+
/**
|
|
2197
|
+
* Creates a binding.
|
|
2198
|
+
* @param evaluate - Evaluates the binding.
|
|
2199
|
+
* @param policy - The security policy to associate with this binding.
|
|
2200
|
+
* @param isVolatile - Indicates whether the binding is volatile.
|
|
2201
|
+
*/
|
|
2202
|
+
constructor(evaluate, policy, isVolatile = false) {
|
|
2203
|
+
this.evaluate = evaluate;
|
|
2204
|
+
this.policy = policy;
|
|
2205
|
+
this.isVolatile = isVolatile;
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
1856
2208
|
/**
|
|
1857
2209
|
* A base class used for attribute directives that don't need internal state.
|
|
1858
2210
|
* @public
|
|
@@ -1864,10 +2216,6 @@ class StatelessAttachedAttributeDirective {
|
|
|
1864
2216
|
*/
|
|
1865
2217
|
constructor(options) {
|
|
1866
2218
|
this.options = options;
|
|
1867
|
-
/**
|
|
1868
|
-
* The unique id of the factory.
|
|
1869
|
-
*/
|
|
1870
|
-
this.id = nextId();
|
|
1871
2219
|
/**
|
|
1872
2220
|
* Opts out of JSON stringification.
|
|
1873
2221
|
* @internal
|
|
@@ -1892,15 +2240,6 @@ class StatelessAttachedAttributeDirective {
|
|
|
1892
2240
|
}
|
|
1893
2241
|
}
|
|
1894
2242
|
|
|
1895
|
-
const createInnerHTMLBinding = globalThis.TrustedHTML
|
|
1896
|
-
? (binding) => (s, c) => {
|
|
1897
|
-
const value = binding(s, c);
|
|
1898
|
-
if (value instanceof TrustedHTML) {
|
|
1899
|
-
return value;
|
|
1900
|
-
}
|
|
1901
|
-
throw FAST.error(1202 /* Message.bindingInnerHTMLRequiresTrustedTypes */);
|
|
1902
|
-
}
|
|
1903
|
-
: (binding) => binding;
|
|
1904
2243
|
class OnChangeBinding extends Binding {
|
|
1905
2244
|
createObserver(_, subscriber) {
|
|
1906
2245
|
return Observable.binding(this.evaluate, subscriber, this.isVolatile);
|
|
@@ -2013,8 +2352,14 @@ function updateTokenList(target, aspect, value) {
|
|
|
2013
2352
|
}
|
|
2014
2353
|
}
|
|
2015
2354
|
}
|
|
2016
|
-
const
|
|
2017
|
-
|
|
2355
|
+
const sinkLookup = {
|
|
2356
|
+
[DOMAspect.attribute]: DOM.setAttribute,
|
|
2357
|
+
[DOMAspect.booleanAttribute]: DOM.setBooleanAttribute,
|
|
2358
|
+
[DOMAspect.property]: (t, a, v) => (t[a] = v),
|
|
2359
|
+
[DOMAspect.content]: updateContent,
|
|
2360
|
+
[DOMAspect.tokenList]: updateTokenList,
|
|
2361
|
+
[DOMAspect.event]: () => void 0,
|
|
2362
|
+
};
|
|
2018
2363
|
/**
|
|
2019
2364
|
* A directive that applies bindings.
|
|
2020
2365
|
* @public
|
|
@@ -2027,15 +2372,10 @@ class HTMLBindingDirective {
|
|
|
2027
2372
|
constructor(dataBinding) {
|
|
2028
2373
|
this.dataBinding = dataBinding;
|
|
2029
2374
|
this.updateTarget = null;
|
|
2030
|
-
/**
|
|
2031
|
-
* The unique id of the factory.
|
|
2032
|
-
*/
|
|
2033
|
-
this.id = nextId();
|
|
2034
2375
|
/**
|
|
2035
2376
|
* The type of aspect to target.
|
|
2036
2377
|
*/
|
|
2037
|
-
this.aspectType =
|
|
2038
|
-
this.data = `${this.id}-d`;
|
|
2378
|
+
this.aspectType = DOMAspect.content;
|
|
2039
2379
|
}
|
|
2040
2380
|
/**
|
|
2041
2381
|
* Creates HTML to be used within a template.
|
|
@@ -2048,45 +2388,28 @@ class HTMLBindingDirective {
|
|
|
2048
2388
|
* Creates a behavior.
|
|
2049
2389
|
*/
|
|
2050
2390
|
createBehavior() {
|
|
2391
|
+
var _a;
|
|
2051
2392
|
if (this.updateTarget === null) {
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
case 1:
|
|
2057
|
-
this.updateTarget = DOM.setAttribute;
|
|
2058
|
-
break;
|
|
2059
|
-
case 2:
|
|
2060
|
-
this.updateTarget = DOM.setBooleanAttribute;
|
|
2061
|
-
break;
|
|
2062
|
-
case 3:
|
|
2063
|
-
this.updateTarget = setProperty;
|
|
2064
|
-
break;
|
|
2065
|
-
case 4:
|
|
2066
|
-
this.updateTarget = updateContent;
|
|
2067
|
-
break;
|
|
2068
|
-
case 5:
|
|
2069
|
-
this.updateTarget = updateTokenList;
|
|
2070
|
-
break;
|
|
2071
|
-
case 6:
|
|
2072
|
-
this.updateTarget = eventTarget;
|
|
2073
|
-
break;
|
|
2074
|
-
default:
|
|
2075
|
-
throw FAST.error(1205 /* Message.unsupportedBindingBehavior */);
|
|
2393
|
+
const sink = sinkLookup[this.aspectType];
|
|
2394
|
+
const policy = (_a = this.dataBinding.policy) !== null && _a !== void 0 ? _a : this.policy;
|
|
2395
|
+
if (!sink) {
|
|
2396
|
+
throw FAST.error(1205 /* Message.unsupportedBindingBehavior */);
|
|
2076
2397
|
}
|
|
2398
|
+
this.data = `${this.id}-d`;
|
|
2399
|
+
this.updateTarget = policy.protect(this.targetTagName, this.aspectType, this.targetAspect, sink);
|
|
2077
2400
|
}
|
|
2078
2401
|
return this;
|
|
2079
2402
|
}
|
|
2080
2403
|
/** @internal */
|
|
2081
2404
|
bind(controller) {
|
|
2082
2405
|
var _a;
|
|
2083
|
-
const target = controller.targets[this.
|
|
2084
|
-
switch (this.
|
|
2085
|
-
case
|
|
2406
|
+
const target = controller.targets[this.targetNodeId];
|
|
2407
|
+
switch (this.aspectType) {
|
|
2408
|
+
case DOMAspect.event:
|
|
2086
2409
|
target[this.data] = controller;
|
|
2087
2410
|
target.addEventListener(this.targetAspect, this, this.dataBinding.options);
|
|
2088
2411
|
break;
|
|
2089
|
-
case
|
|
2412
|
+
case DOMAspect.content:
|
|
2090
2413
|
controller.onUnbind(this);
|
|
2091
2414
|
// intentional fall through
|
|
2092
2415
|
default:
|
|
@@ -2099,7 +2422,7 @@ class HTMLBindingDirective {
|
|
|
2099
2422
|
}
|
|
2100
2423
|
/** @internal */
|
|
2101
2424
|
unbind(controller) {
|
|
2102
|
-
const target = controller.targets[this.
|
|
2425
|
+
const target = controller.targets[this.targetNodeId];
|
|
2103
2426
|
const view = target.$fastView;
|
|
2104
2427
|
if (view !== void 0 && view.isComposed) {
|
|
2105
2428
|
view.unbind();
|
|
@@ -2129,21 +2452,23 @@ HTMLDirective.define(HTMLBindingDirective, { aspected: true });
|
|
|
2129
2452
|
/**
|
|
2130
2453
|
* Creates an standard binding.
|
|
2131
2454
|
* @param expression - The binding to refresh when changed.
|
|
2455
|
+
* @param policy - The security policy to associate with th binding.
|
|
2132
2456
|
* @param isVolatile - Indicates whether the binding is volatile or not.
|
|
2133
2457
|
* @returns A binding configuration.
|
|
2134
2458
|
* @public
|
|
2135
2459
|
*/
|
|
2136
|
-
function bind(expression, isVolatile = Observable.isVolatileBinding(expression)) {
|
|
2137
|
-
return new OnChangeBinding(expression, isVolatile);
|
|
2460
|
+
function bind(expression, policy, isVolatile = Observable.isVolatileBinding(expression)) {
|
|
2461
|
+
return new OnChangeBinding(expression, policy, isVolatile);
|
|
2138
2462
|
}
|
|
2139
2463
|
/**
|
|
2140
2464
|
* Creates a one time binding
|
|
2141
2465
|
* @param expression - The binding to refresh when signaled.
|
|
2466
|
+
* @param policy - The security policy to associate with th binding.
|
|
2142
2467
|
* @returns A binding configuration.
|
|
2143
2468
|
* @public
|
|
2144
2469
|
*/
|
|
2145
|
-
function oneTime(expression) {
|
|
2146
|
-
return new OneTimeBinding(expression);
|
|
2470
|
+
function oneTime(expression, policy) {
|
|
2471
|
+
return new OneTimeBinding(expression, policy);
|
|
2147
2472
|
}
|
|
2148
2473
|
/**
|
|
2149
2474
|
* Creates an event listener binding.
|
|
@@ -2153,7 +2478,7 @@ function oneTime(expression) {
|
|
|
2153
2478
|
* @public
|
|
2154
2479
|
*/
|
|
2155
2480
|
function listener(expression, options) {
|
|
2156
|
-
const config = new OnChangeBinding(expression
|
|
2481
|
+
const config = new OnChangeBinding(expression);
|
|
2157
2482
|
config.options = options;
|
|
2158
2483
|
return config;
|
|
2159
2484
|
}
|
|
@@ -2434,20 +2759,25 @@ const warningHost = new Proxy(document.createElement("div"), {
|
|
|
2434
2759
|
},
|
|
2435
2760
|
});
|
|
2436
2761
|
class CompilationContext {
|
|
2437
|
-
constructor(fragment, directives) {
|
|
2762
|
+
constructor(fragment, directives, policy) {
|
|
2438
2763
|
this.fragment = fragment;
|
|
2439
2764
|
this.directives = directives;
|
|
2765
|
+
this.policy = policy;
|
|
2440
2766
|
this.proto = null;
|
|
2441
2767
|
this.nodeIds = new Set();
|
|
2442
2768
|
this.descriptors = {};
|
|
2443
2769
|
this.factories = [];
|
|
2444
2770
|
}
|
|
2445
|
-
addFactory(factory, parentId, nodeId, targetIndex) {
|
|
2771
|
+
addFactory(factory, parentId, nodeId, targetIndex, tagName) {
|
|
2772
|
+
var _a, _b;
|
|
2446
2773
|
if (!this.nodeIds.has(nodeId)) {
|
|
2447
2774
|
this.nodeIds.add(nodeId);
|
|
2448
2775
|
this.addTargetDescriptor(parentId, nodeId, targetIndex);
|
|
2449
2776
|
}
|
|
2450
|
-
factory.
|
|
2777
|
+
factory.id = (_a = factory.id) !== null && _a !== void 0 ? _a : nextId();
|
|
2778
|
+
factory.targetNodeId = nodeId;
|
|
2779
|
+
factory.targetTagName = tagName;
|
|
2780
|
+
factory.policy = (_b = factory.policy) !== null && _b !== void 0 ? _b : this.policy;
|
|
2451
2781
|
this.factories.push(factory);
|
|
2452
2782
|
}
|
|
2453
2783
|
freeze() {
|
|
@@ -2500,19 +2830,19 @@ function compileAttributes(context, parentId, node, nodeId, nodeIndex, includeBa
|
|
|
2500
2830
|
let result = null;
|
|
2501
2831
|
if (parseResult === null) {
|
|
2502
2832
|
if (includeBasicValues) {
|
|
2503
|
-
result = new HTMLBindingDirective(oneTime(() => attrValue));
|
|
2504
|
-
|
|
2833
|
+
result = new HTMLBindingDirective(oneTime(() => attrValue, context.policy));
|
|
2834
|
+
HTMLDirective.assignAspect(result, attr.name);
|
|
2505
2835
|
}
|
|
2506
2836
|
}
|
|
2507
2837
|
else {
|
|
2508
2838
|
/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
|
|
2509
|
-
result = Compiler.aggregate(parseResult);
|
|
2839
|
+
result = Compiler.aggregate(parseResult, context.policy);
|
|
2510
2840
|
}
|
|
2511
2841
|
if (result !== null) {
|
|
2512
2842
|
node.removeAttributeNode(attr);
|
|
2513
2843
|
i--;
|
|
2514
2844
|
ii--;
|
|
2515
|
-
context.addFactory(result, parentId, nodeId, nodeIndex);
|
|
2845
|
+
context.addFactory(result, parentId, nodeId, nodeIndex, node.tagName);
|
|
2516
2846
|
}
|
|
2517
2847
|
}
|
|
2518
2848
|
}
|
|
@@ -2537,8 +2867,8 @@ function compileContent(context, node, parentId, nodeId, nodeIndex) {
|
|
|
2537
2867
|
}
|
|
2538
2868
|
else {
|
|
2539
2869
|
currentNode.textContent = " ";
|
|
2540
|
-
|
|
2541
|
-
context.addFactory(currentPart, parentId, nodeId, nodeIndex);
|
|
2870
|
+
HTMLDirective.assignAspect(currentPart);
|
|
2871
|
+
context.addFactory(currentPart, parentId, nodeId, nodeIndex, null);
|
|
2542
2872
|
}
|
|
2543
2873
|
lastNode = currentNode;
|
|
2544
2874
|
}
|
|
@@ -2570,7 +2900,7 @@ function compileNode(context, parentId, node, nodeIndex) {
|
|
|
2570
2900
|
if (parts !== null) {
|
|
2571
2901
|
context.addFactory(
|
|
2572
2902
|
/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
|
|
2573
|
-
Compiler.aggregate(parts), parentId, nodeId, nodeIndex);
|
|
2903
|
+
Compiler.aggregate(parts), parentId, nodeId, nodeIndex, null);
|
|
2574
2904
|
}
|
|
2575
2905
|
break;
|
|
2576
2906
|
}
|
|
@@ -2584,45 +2914,28 @@ function isMarker(node, directives) {
|
|
|
2584
2914
|
Parser.parse(node.data, directives) !== null);
|
|
2585
2915
|
}
|
|
2586
2916
|
const templateTag = "TEMPLATE";
|
|
2587
|
-
const policyOptions = { createHTML: html => html };
|
|
2588
|
-
let htmlPolicy = globalThis.trustedTypes
|
|
2589
|
-
? globalThis.trustedTypes.createPolicy("fast-html", policyOptions)
|
|
2590
|
-
: policyOptions;
|
|
2591
|
-
const fastHTMLPolicy = htmlPolicy;
|
|
2592
2917
|
/**
|
|
2593
2918
|
* Common APIs related to compilation.
|
|
2594
2919
|
* @public
|
|
2595
2920
|
*/
|
|
2596
2921
|
const Compiler = {
|
|
2597
|
-
/**
|
|
2598
|
-
* Sets the HTML trusted types policy used by the compiler.
|
|
2599
|
-
* @param policy - The policy to set for HTML.
|
|
2600
|
-
* @remarks
|
|
2601
|
-
* This API can only be called once, for security reasons. It should be
|
|
2602
|
-
* called by the application developer at the start of their program.
|
|
2603
|
-
*/
|
|
2604
|
-
setHTMLPolicy(policy) {
|
|
2605
|
-
if (htmlPolicy !== fastHTMLPolicy) {
|
|
2606
|
-
throw FAST.error(1201 /* Message.onlySetHTMLPolicyOnce */);
|
|
2607
|
-
}
|
|
2608
|
-
htmlPolicy = policy;
|
|
2609
|
-
},
|
|
2610
2922
|
/**
|
|
2611
2923
|
* Compiles a template and associated directives into a compilation
|
|
2612
2924
|
* result which can be used to create views.
|
|
2613
2925
|
* @param html - The html string or template element to compile.
|
|
2614
|
-
* @param
|
|
2926
|
+
* @param factories - The behavior factories referenced by the template.
|
|
2927
|
+
* @param policy - The security policy to compile the html with.
|
|
2615
2928
|
* @remarks
|
|
2616
2929
|
* The template that is provided for compilation is altered in-place
|
|
2617
2930
|
* and cannot be compiled again. If the original template must be preserved,
|
|
2618
2931
|
* it is recommended that you clone the original and pass the clone to this API.
|
|
2619
2932
|
* @public
|
|
2620
2933
|
*/
|
|
2621
|
-
compile(html,
|
|
2934
|
+
compile(html, factories, policy = DOM.policy) {
|
|
2622
2935
|
let template;
|
|
2623
2936
|
if (isString(html)) {
|
|
2624
2937
|
template = document.createElement(templateTag);
|
|
2625
|
-
template.innerHTML =
|
|
2938
|
+
template.innerHTML = policy.createHTML(html);
|
|
2626
2939
|
const fec = template.content.firstElementChild;
|
|
2627
2940
|
if (fec !== null && fec.tagName === templateTag) {
|
|
2628
2941
|
template = fec;
|
|
@@ -2633,18 +2946,18 @@ const Compiler = {
|
|
|
2633
2946
|
}
|
|
2634
2947
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1111864
|
|
2635
2948
|
const fragment = document.adoptNode(template.content);
|
|
2636
|
-
const context = new CompilationContext(fragment,
|
|
2949
|
+
const context = new CompilationContext(fragment, factories, policy);
|
|
2637
2950
|
compileAttributes(context, "", template, /* host */ "h", 0, true);
|
|
2638
2951
|
if (
|
|
2639
2952
|
// If the first node in a fragment is a marker, that means it's an unstable first node,
|
|
2640
2953
|
// because something like a when, repeat, etc. could add nodes before the marker.
|
|
2641
2954
|
// To mitigate this, we insert a stable first node. However, if we insert a node,
|
|
2642
2955
|
// that will alter the result of the TreeWalker. So, we also need to offset the target index.
|
|
2643
|
-
isMarker(fragment.firstChild,
|
|
2956
|
+
isMarker(fragment.firstChild, factories) ||
|
|
2644
2957
|
// Or if there is only one node and a directive, it means the template's content
|
|
2645
2958
|
// is *only* the directive. In that case, HTMLView.dispose() misses any nodes inserted by
|
|
2646
2959
|
// the directive. Inserting a new node ensures proper disposal of nodes added by the directive.
|
|
2647
|
-
(fragment.childNodes.length === 1 && Object.keys(
|
|
2960
|
+
(fragment.childNodes.length === 1 && Object.keys(factories).length > 0)) {
|
|
2648
2961
|
fragment.insertBefore(document.createComment(""), fragment.firstChild);
|
|
2649
2962
|
}
|
|
2650
2963
|
compileChildren(context, fragment, /* root */ "r");
|
|
@@ -2663,15 +2976,17 @@ const Compiler = {
|
|
|
2663
2976
|
* Aggregates an array of strings and directives into a single directive.
|
|
2664
2977
|
* @param parts - A heterogeneous array of static strings interspersed with
|
|
2665
2978
|
* directives.
|
|
2979
|
+
* @param policy - The security policy to use with the aggregated bindings.
|
|
2666
2980
|
* @returns A single inline directive that aggregates the behavior of all the parts.
|
|
2667
2981
|
*/
|
|
2668
|
-
aggregate(parts) {
|
|
2982
|
+
aggregate(parts, policy = DOM.policy) {
|
|
2669
2983
|
if (parts.length === 1) {
|
|
2670
2984
|
return parts[0];
|
|
2671
2985
|
}
|
|
2672
2986
|
let sourceAspect;
|
|
2673
2987
|
let binding;
|
|
2674
2988
|
let isVolatile = false;
|
|
2989
|
+
let bindingPolicy = void 0;
|
|
2675
2990
|
const partCount = parts.length;
|
|
2676
2991
|
const finalParts = parts.map((x) => {
|
|
2677
2992
|
if (isString(x)) {
|
|
@@ -2680,6 +2995,7 @@ const Compiler = {
|
|
|
2680
2995
|
sourceAspect = x.sourceAspect || sourceAspect;
|
|
2681
2996
|
binding = x.dataBinding || binding;
|
|
2682
2997
|
isVolatile = isVolatile || x.dataBinding.isVolatile;
|
|
2998
|
+
bindingPolicy = bindingPolicy || x.dataBinding.policy;
|
|
2683
2999
|
return x.dataBinding.evaluate;
|
|
2684
3000
|
});
|
|
2685
3001
|
const expression = (scope, context) => {
|
|
@@ -2691,12 +3007,26 @@ const Compiler = {
|
|
|
2691
3007
|
};
|
|
2692
3008
|
binding.evaluate = expression;
|
|
2693
3009
|
binding.isVolatile = isVolatile;
|
|
3010
|
+
binding.policy = bindingPolicy !== null && bindingPolicy !== void 0 ? bindingPolicy : policy;
|
|
2694
3011
|
const directive = new HTMLBindingDirective(binding);
|
|
2695
|
-
|
|
3012
|
+
HTMLDirective.assignAspect(directive, sourceAspect);
|
|
2696
3013
|
return directive;
|
|
2697
3014
|
},
|
|
2698
3015
|
};
|
|
2699
3016
|
|
|
3017
|
+
// Much thanks to LitHTML for working this out!
|
|
3018
|
+
const lastAttributeNameRegex =
|
|
3019
|
+
/* eslint-disable-next-line no-control-regex */
|
|
3020
|
+
/([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F "'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/;
|
|
3021
|
+
function createHTML(value, prevString, add, definition = HTMLDirective.getForInstance(value)) {
|
|
3022
|
+
if (definition.aspected) {
|
|
3023
|
+
const match = lastAttributeNameRegex.exec(prevString);
|
|
3024
|
+
if (match !== null) {
|
|
3025
|
+
HTMLDirective.assignAspect(value, match[2]);
|
|
3026
|
+
}
|
|
3027
|
+
}
|
|
3028
|
+
return value.createHTML(add);
|
|
3029
|
+
}
|
|
2700
3030
|
/**
|
|
2701
3031
|
* A template capable of creating HTMLView instances or rendering directly to DOM.
|
|
2702
3032
|
* @public
|
|
@@ -2706,8 +3036,10 @@ class ViewTemplate {
|
|
|
2706
3036
|
* Creates an instance of ViewTemplate.
|
|
2707
3037
|
* @param html - The html representing what this template will instantiate, including placeholders for directives.
|
|
2708
3038
|
* @param factories - The directives that will be connected to placeholders in the html.
|
|
3039
|
+
* @param policy - The security policy to use when compiling this template.
|
|
2709
3040
|
*/
|
|
2710
|
-
constructor(html, factories) {
|
|
3041
|
+
constructor(html, factories = {}, policy) {
|
|
3042
|
+
this.policy = policy;
|
|
2711
3043
|
this.result = null;
|
|
2712
3044
|
/**
|
|
2713
3045
|
* Opts out of JSON stringification.
|
|
@@ -2723,10 +3055,28 @@ class ViewTemplate {
|
|
|
2723
3055
|
*/
|
|
2724
3056
|
create(hostBindingTarget) {
|
|
2725
3057
|
if (this.result === null) {
|
|
2726
|
-
this.result = Compiler.compile(this.html, this.factories);
|
|
3058
|
+
this.result = Compiler.compile(this.html, this.factories, this.policy);
|
|
2727
3059
|
}
|
|
2728
3060
|
return this.result.createView(hostBindingTarget);
|
|
2729
3061
|
}
|
|
3062
|
+
/**
|
|
3063
|
+
* Sets the DOMPolicy for this template.
|
|
3064
|
+
* @param policy - The policy to associated with this template.
|
|
3065
|
+
* @returns The modified template instance.
|
|
3066
|
+
* @remarks
|
|
3067
|
+
* The DOMPolicy can only be set once for a template and cannot be
|
|
3068
|
+
* set after the template is compiled.
|
|
3069
|
+
*/
|
|
3070
|
+
withPolicy(policy) {
|
|
3071
|
+
if (this.result) {
|
|
3072
|
+
throw FAST.error(1208 /* Message.cannotSetTemplatePolicyAfterCompilation */);
|
|
3073
|
+
}
|
|
3074
|
+
if (this.policy) {
|
|
3075
|
+
throw FAST.error(1207 /* Message.onlySetTemplatePolicyOnce */);
|
|
3076
|
+
}
|
|
3077
|
+
this.policy = policy;
|
|
3078
|
+
return this;
|
|
3079
|
+
}
|
|
2730
3080
|
/**
|
|
2731
3081
|
* Creates an HTMLView from this template, binds it to the source, and then appends it to the host.
|
|
2732
3082
|
* @param source - The data source to bind the template to.
|
|
@@ -2740,17 +3090,47 @@ class ViewTemplate {
|
|
|
2740
3090
|
view.appendTo(host);
|
|
2741
3091
|
return view;
|
|
2742
3092
|
}
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
3093
|
+
/**
|
|
3094
|
+
* Creates a template based on a set of static strings and dynamic values.
|
|
3095
|
+
* @param strings - The static strings to create the template with.
|
|
3096
|
+
* @param values - The dynamic values to create the template with.
|
|
3097
|
+
* @param policy - The DOMPolicy to associated with the template.
|
|
3098
|
+
* @returns A ViewTemplate.
|
|
3099
|
+
* @remarks
|
|
3100
|
+
* This API should not be used directly under normal circumstances because constructing
|
|
3101
|
+
* a template in this way, if not done properly, can open up the application to XSS
|
|
3102
|
+
* attacks. When using this API, provide a strong DOMPolicy that can properly sanitize
|
|
3103
|
+
* and also be sure to manually sanitize all static strings particularly if they can
|
|
3104
|
+
* come from user input.
|
|
3105
|
+
*/
|
|
3106
|
+
static create(strings, values, policy) {
|
|
3107
|
+
let html = "";
|
|
3108
|
+
const factories = Object.create(null);
|
|
3109
|
+
const add = (factory) => {
|
|
3110
|
+
var _a;
|
|
3111
|
+
const id = (_a = factory.id) !== null && _a !== void 0 ? _a : (factory.id = nextId());
|
|
3112
|
+
factories[id] = factory;
|
|
3113
|
+
return id;
|
|
3114
|
+
};
|
|
3115
|
+
for (let i = 0, ii = strings.length - 1; i < ii; ++i) {
|
|
3116
|
+
const currentString = strings[i];
|
|
3117
|
+
let currentValue = values[i];
|
|
3118
|
+
let definition;
|
|
3119
|
+
html += currentString;
|
|
3120
|
+
if (isFunction(currentValue)) {
|
|
3121
|
+
currentValue = new HTMLBindingDirective(bind(currentValue));
|
|
3122
|
+
}
|
|
3123
|
+
else if (currentValue instanceof Binding) {
|
|
3124
|
+
currentValue = new HTMLBindingDirective(currentValue);
|
|
3125
|
+
}
|
|
3126
|
+
else if (!(definition = HTMLDirective.getForInstance(currentValue))) {
|
|
3127
|
+
const staticValue = currentValue;
|
|
3128
|
+
currentValue = new HTMLBindingDirective(oneTime(() => staticValue));
|
|
3129
|
+
}
|
|
3130
|
+
html += createHTML(currentValue, currentString, add, definition);
|
|
3131
|
+
}
|
|
3132
|
+
return new ViewTemplate(html + strings[strings.length - 1], factories, policy);
|
|
2752
3133
|
}
|
|
2753
|
-
return value.createHTML(add);
|
|
2754
3134
|
}
|
|
2755
3135
|
/**
|
|
2756
3136
|
* Transforms a template literal string into a ViewTemplate.
|
|
@@ -2762,49 +3142,10 @@ function createAspectedHTML(value, prevString, add) {
|
|
|
2762
3142
|
* @public
|
|
2763
3143
|
*/
|
|
2764
3144
|
function html(strings, ...values) {
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
const add = (factory) => {
|
|
2768
|
-
var _a;
|
|
2769
|
-
const id = (_a = factory.id) !== null && _a !== void 0 ? _a : (factory.id = nextId());
|
|
2770
|
-
factories[id] = factory;
|
|
2771
|
-
return id;
|
|
2772
|
-
};
|
|
2773
|
-
for (let i = 0, ii = strings.length - 1; i < ii; ++i) {
|
|
2774
|
-
const currentString = strings[i];
|
|
2775
|
-
const currentValue = values[i];
|
|
2776
|
-
let definition;
|
|
2777
|
-
html += currentString;
|
|
2778
|
-
if (isFunction(currentValue)) {
|
|
2779
|
-
html += createAspectedHTML(new HTMLBindingDirective(bind(currentValue)), currentString, add);
|
|
2780
|
-
}
|
|
2781
|
-
else if (isString(currentValue)) {
|
|
2782
|
-
const match = lastAttributeNameRegex.exec(currentString);
|
|
2783
|
-
if (match !== null) {
|
|
2784
|
-
const directive = new HTMLBindingDirective(oneTime(() => currentValue));
|
|
2785
|
-
Aspect.assign(directive, match[2]);
|
|
2786
|
-
html += directive.createHTML(add);
|
|
2787
|
-
}
|
|
2788
|
-
else {
|
|
2789
|
-
html += currentValue;
|
|
2790
|
-
}
|
|
2791
|
-
}
|
|
2792
|
-
else if (currentValue instanceof Binding) {
|
|
2793
|
-
html += createAspectedHTML(new HTMLBindingDirective(currentValue), currentString, add);
|
|
2794
|
-
}
|
|
2795
|
-
else if ((definition = HTMLDirective.getForInstance(currentValue)) === void 0) {
|
|
2796
|
-
html += createAspectedHTML(new HTMLBindingDirective(oneTime(() => currentValue)), currentString, add);
|
|
2797
|
-
}
|
|
2798
|
-
else {
|
|
2799
|
-
if (definition.aspected) {
|
|
2800
|
-
html += createAspectedHTML(currentValue, currentString, add);
|
|
2801
|
-
}
|
|
2802
|
-
else {
|
|
2803
|
-
html += currentValue.createHTML(add);
|
|
2804
|
-
}
|
|
2805
|
-
}
|
|
3145
|
+
if (Array.isArray(strings) && Array.isArray(strings.raw)) {
|
|
3146
|
+
return ViewTemplate.create(strings, values);
|
|
2806
3147
|
}
|
|
2807
|
-
|
|
3148
|
+
throw FAST.error(1206 /* Message.directCallToHTMLTagNotAllowed */);
|
|
2808
3149
|
}
|
|
2809
3150
|
|
|
2810
3151
|
/**
|
|
@@ -2817,7 +3158,7 @@ class RefDirective extends StatelessAttachedAttributeDirective {
|
|
|
2817
3158
|
* @param controller - The view controller that manages the lifecycle of this behavior.
|
|
2818
3159
|
*/
|
|
2819
3160
|
bind(controller) {
|
|
2820
|
-
controller.source[this.options] = controller.targets[this.
|
|
3161
|
+
controller.source[this.options] = controller.targets[this.targetNodeId];
|
|
2821
3162
|
}
|
|
2822
3163
|
}
|
|
2823
3164
|
HTMLDirective.define(RefDirective);
|
|
@@ -2891,7 +3232,7 @@ class RepeatBehavior {
|
|
|
2891
3232
|
* @param controller - The view controller that manages the lifecycle of this behavior.
|
|
2892
3233
|
*/
|
|
2893
3234
|
bind(controller) {
|
|
2894
|
-
this.location = controller.targets[this.directive.
|
|
3235
|
+
this.location = controller.targets[this.directive.targetNodeId];
|
|
2895
3236
|
this.controller = controller;
|
|
2896
3237
|
this.items = this.itemsBindingObserver.bind(controller);
|
|
2897
3238
|
this.template = this.templateBindingObserver.bind(controller);
|
|
@@ -3071,10 +3412,6 @@ class RepeatDirective {
|
|
|
3071
3412
|
this.dataBinding = dataBinding;
|
|
3072
3413
|
this.templateBinding = templateBinding;
|
|
3073
3414
|
this.options = options;
|
|
3074
|
-
/**
|
|
3075
|
-
* The unique id of the factory.
|
|
3076
|
-
*/
|
|
3077
|
-
this.id = nextId();
|
|
3078
3415
|
ArrayObserver.enable();
|
|
3079
3416
|
}
|
|
3080
3417
|
/**
|
|
@@ -3123,9 +3460,15 @@ const elements = (selector) => selector
|
|
|
3123
3460
|
* Internally used by the SlottedDirective and the ChildrenDirective.
|
|
3124
3461
|
*/
|
|
3125
3462
|
class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3463
|
+
/**
|
|
3464
|
+
* The unique id of the factory.
|
|
3465
|
+
*/
|
|
3466
|
+
get id() {
|
|
3467
|
+
return this._id;
|
|
3468
|
+
}
|
|
3469
|
+
set id(value) {
|
|
3470
|
+
this._id = value;
|
|
3471
|
+
this._controllerProperty = `${value}-c`;
|
|
3129
3472
|
}
|
|
3130
3473
|
/**
|
|
3131
3474
|
* Bind this behavior to the source.
|
|
@@ -3134,8 +3477,8 @@ class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
|
3134
3477
|
* @param targets - The targets that behaviors in a view can attach to.
|
|
3135
3478
|
*/
|
|
3136
3479
|
bind(controller) {
|
|
3137
|
-
const target = controller.targets[this.
|
|
3138
|
-
target[this.
|
|
3480
|
+
const target = controller.targets[this.targetNodeId];
|
|
3481
|
+
target[this._controllerProperty] = controller;
|
|
3139
3482
|
this.updateTarget(controller.source, this.computeNodes(target));
|
|
3140
3483
|
this.observe(target);
|
|
3141
3484
|
controller.onUnbind(this);
|
|
@@ -3147,10 +3490,10 @@ class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
|
3147
3490
|
* @param targets - The targets that behaviors in a view can attach to.
|
|
3148
3491
|
*/
|
|
3149
3492
|
unbind(controller) {
|
|
3150
|
-
const target = controller.targets[this.
|
|
3493
|
+
const target = controller.targets[this.targetNodeId];
|
|
3151
3494
|
this.updateTarget(controller.source, emptyArray);
|
|
3152
3495
|
this.disconnect(target);
|
|
3153
|
-
target[this.
|
|
3496
|
+
target[this._controllerProperty] = null;
|
|
3154
3497
|
}
|
|
3155
3498
|
/**
|
|
3156
3499
|
* Gets the data source for the target.
|
|
@@ -3158,7 +3501,7 @@ class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
|
3158
3501
|
* @returns The source.
|
|
3159
3502
|
*/
|
|
3160
3503
|
getSource(target) {
|
|
3161
|
-
return target[this.
|
|
3504
|
+
return target[this._controllerProperty].source;
|
|
3162
3505
|
}
|
|
3163
3506
|
/**
|
|
3164
3507
|
* Updates the source property with the computed nodes.
|
|
@@ -3299,6 +3642,29 @@ function children(propertyOrOptions) {
|
|
|
3299
3642
|
return new ChildrenDirective(propertyOrOptions);
|
|
3300
3643
|
}
|
|
3301
3644
|
|
|
3645
|
+
/**
|
|
3646
|
+
* A directive capable of injecting static HTML platform runtime protection.
|
|
3647
|
+
* @public
|
|
3648
|
+
*/
|
|
3649
|
+
class DangerousHTMLDirective {
|
|
3650
|
+
constructor(html) {
|
|
3651
|
+
this.html = html;
|
|
3652
|
+
}
|
|
3653
|
+
createHTML() {
|
|
3654
|
+
return this.html;
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
HTMLDirective.define(DangerousHTMLDirective);
|
|
3658
|
+
/**
|
|
3659
|
+
* Injects static HTML without platform protection.
|
|
3660
|
+
* @param html - The html to injection.
|
|
3661
|
+
* @returns A DangerousHTMLDirective.
|
|
3662
|
+
* @public
|
|
3663
|
+
*/
|
|
3664
|
+
function dangerousHTML(html) {
|
|
3665
|
+
return new DangerousHTMLDirective(html);
|
|
3666
|
+
}
|
|
3667
|
+
|
|
3302
3668
|
const booleanMode = "boolean";
|
|
3303
3669
|
const reflectMode = "reflect";
|
|
3304
3670
|
/**
|
|
@@ -3497,7 +3863,7 @@ function attr(configOrTarget, prop) {
|
|
|
3497
3863
|
const defaultShadowOptions = { mode: "open" };
|
|
3498
3864
|
const defaultElementOptions = {};
|
|
3499
3865
|
const fastElementBaseTypes = new Set();
|
|
3500
|
-
const fastElementRegistry = FAST.getById(
|
|
3866
|
+
const fastElementRegistry = FAST.getById(KernelServiceId.elementRegistry, () => createTypeRegistry());
|
|
3501
3867
|
/**
|
|
3502
3868
|
* Defines metadata for a FASTElement.
|
|
3503
3869
|
* @public
|
|
@@ -4159,4 +4525,6 @@ function customElement(nameOrDef) {
|
|
|
4159
4525
|
};
|
|
4160
4526
|
}
|
|
4161
4527
|
|
|
4162
|
-
|
|
4528
|
+
DOM.setPolicy(DOMPolicy.create());
|
|
4529
|
+
|
|
4530
|
+
export { ArrayObserver, AttributeConfiguration, AttributeDefinition, Binding, CSSDirective, ChildrenDirective, Compiler, DOM, DOMAspect, DangerousHTMLDirective, ElementController, ElementStyles, ExecutionContext, FAST, FASTElement, FASTElementDefinition, HTMLBindingDirective, HTMLDirective, HTMLView, Markup, NodeObservationDirective, Observable, Parser, PropertyChangeNotifier, RefDirective, RepeatBehavior, RepeatDirective, SlottedDirective, SourceLifetime, Splice, SpliceStrategy, SpliceStrategySupport, StatelessAttachedAttributeDirective, SubscriberSet, Updates, ViewTemplate, attr, bind, booleanConverter, children, createMetadataLocator, createTypeRegistry, css, cssDirective, cssPartial, customElement, dangerousHTML, elements, emptyArray, html, htmlDirective, lengthOf, listener, normalizeBinding, nullableNumberConverter, observable, oneTime, ref, repeat, slotted, volatile, when };
|