@microsoft/fast-element 2.0.0-beta.17 → 2.0.0-beta.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/CHANGELOG.json +21 -0
- package/CHANGELOG.md +10 -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 +15 -24
- 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/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/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 +708 -384
- package/dist/fast-element.debug.min.js +1 -1
- package/dist/fast-element.js +679 -358
- 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/yarn-error.log +177 -0
- 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,48 @@ Object.assign(FAST$1, {
|
|
|
90
62
|
},
|
|
91
63
|
});
|
|
92
64
|
|
|
93
|
-
|
|
65
|
+
/**
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
const isFunction = (object) => typeof object === "function";
|
|
69
|
+
/**
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
const isString = (object) => typeof object === "string";
|
|
73
|
+
/**
|
|
74
|
+
* @internal
|
|
75
|
+
*/
|
|
76
|
+
const noop = () => void 0;
|
|
77
|
+
|
|
78
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
79
|
+
(function ensureGlobalThis() {
|
|
80
|
+
if (typeof globalThis !== "undefined") {
|
|
81
|
+
// We're running in a modern environment.
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
if (typeof global !== "undefined") {
|
|
86
|
+
// We're running in NodeJS
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
global.globalThis = global;
|
|
89
|
+
}
|
|
90
|
+
else if (typeof self !== "undefined") {
|
|
91
|
+
self.globalThis = self;
|
|
92
|
+
}
|
|
93
|
+
else if (typeof window !== "undefined") {
|
|
94
|
+
// We're running in the browser's main thread.
|
|
95
|
+
window.globalThis = window;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// Hopefully we never get here...
|
|
99
|
+
// Not all environments allow eval and Function. Use only as a last resort:
|
|
100
|
+
// eslint-disable-next-line no-new-func
|
|
101
|
+
const result = new Function("return this")();
|
|
102
|
+
result.globalThis = result;
|
|
103
|
+
}
|
|
104
|
+
})();
|
|
105
|
+
|
|
106
|
+
// ensure FAST global - duplicated debug.ts
|
|
94
107
|
const propConfig = {
|
|
95
108
|
configurable: false,
|
|
96
109
|
enumerable: false,
|
|
@@ -178,19 +191,6 @@ function createMetadataLocator() {
|
|
|
178
191
|
};
|
|
179
192
|
}
|
|
180
193
|
|
|
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
194
|
/**
|
|
195
195
|
* The default UpdateQueue.
|
|
196
196
|
* @public
|
|
@@ -257,6 +257,456 @@ const Updates = FAST.getById(1 /* KernelServiceId.updateQueue */, () => {
|
|
|
257
257
|
});
|
|
258
258
|
});
|
|
259
259
|
|
|
260
|
+
/**
|
|
261
|
+
* The type of HTML aspect to target.
|
|
262
|
+
* @public
|
|
263
|
+
*/
|
|
264
|
+
const DOMAspect = Object.freeze({
|
|
265
|
+
/**
|
|
266
|
+
* Not aspected.
|
|
267
|
+
*/
|
|
268
|
+
none: 0,
|
|
269
|
+
/**
|
|
270
|
+
* An attribute.
|
|
271
|
+
*/
|
|
272
|
+
attribute: 1,
|
|
273
|
+
/**
|
|
274
|
+
* A boolean attribute.
|
|
275
|
+
*/
|
|
276
|
+
booleanAttribute: 2,
|
|
277
|
+
/**
|
|
278
|
+
* A property.
|
|
279
|
+
*/
|
|
280
|
+
property: 3,
|
|
281
|
+
/**
|
|
282
|
+
* Content
|
|
283
|
+
*/
|
|
284
|
+
content: 4,
|
|
285
|
+
/**
|
|
286
|
+
* A token list.
|
|
287
|
+
*/
|
|
288
|
+
tokenList: 5,
|
|
289
|
+
/**
|
|
290
|
+
* An event.
|
|
291
|
+
*/
|
|
292
|
+
event: 6,
|
|
293
|
+
});
|
|
294
|
+
const createHTML$1 = html => html;
|
|
295
|
+
const fastTrustedType = globalThis.trustedTypes
|
|
296
|
+
? globalThis.trustedTypes.createPolicy("fast-html", { createHTML: createHTML$1 })
|
|
297
|
+
: { createHTML: createHTML$1 };
|
|
298
|
+
let defaultPolicy = Object.freeze({
|
|
299
|
+
createHTML(value) {
|
|
300
|
+
return fastTrustedType.createHTML(value);
|
|
301
|
+
},
|
|
302
|
+
protect(tagName, aspect, aspectName, sink) {
|
|
303
|
+
return sink;
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
const fastPolicy = defaultPolicy;
|
|
307
|
+
/**
|
|
308
|
+
* Common DOM APIs.
|
|
309
|
+
* @public
|
|
310
|
+
*/
|
|
311
|
+
const DOM = Object.freeze({
|
|
312
|
+
/**
|
|
313
|
+
* @deprecated
|
|
314
|
+
* Use Updates.enqueue().
|
|
315
|
+
*/
|
|
316
|
+
queueUpdate: Updates.enqueue,
|
|
317
|
+
/**
|
|
318
|
+
* @deprecated
|
|
319
|
+
* Use Updates.next()
|
|
320
|
+
*/
|
|
321
|
+
nextUpdate: Updates.next,
|
|
322
|
+
/**
|
|
323
|
+
* @deprecated
|
|
324
|
+
* Use Updates.process()
|
|
325
|
+
*/
|
|
326
|
+
processUpdates: Updates.process,
|
|
327
|
+
/**
|
|
328
|
+
* Gets the dom policy used by the templating system.
|
|
329
|
+
*/
|
|
330
|
+
get policy() {
|
|
331
|
+
return defaultPolicy;
|
|
332
|
+
},
|
|
333
|
+
/**
|
|
334
|
+
* Sets the dom policy used by the templating system.
|
|
335
|
+
* @param policy - The policy to set.
|
|
336
|
+
* @remarks
|
|
337
|
+
* This API can only be called once, for security reasons. It should be
|
|
338
|
+
* called by the application developer at the start of their program.
|
|
339
|
+
*/
|
|
340
|
+
setPolicy(value) {
|
|
341
|
+
if (defaultPolicy !== fastPolicy) {
|
|
342
|
+
throw FAST.error(1201 /* Message.onlySetDOMPolicyOnce */);
|
|
343
|
+
}
|
|
344
|
+
defaultPolicy = value;
|
|
345
|
+
},
|
|
346
|
+
/**
|
|
347
|
+
* Sets an attribute value on an element.
|
|
348
|
+
* @param element - The element to set the attribute value on.
|
|
349
|
+
* @param attributeName - The attribute name to set.
|
|
350
|
+
* @param value - The value of the attribute to set.
|
|
351
|
+
* @remarks
|
|
352
|
+
* If the value is `null` or `undefined`, the attribute is removed, otherwise
|
|
353
|
+
* it is set to the provided value using the standard `setAttribute` API.
|
|
354
|
+
*/
|
|
355
|
+
setAttribute(element, attributeName, value) {
|
|
356
|
+
value === null || value === undefined
|
|
357
|
+
? element.removeAttribute(attributeName)
|
|
358
|
+
: element.setAttribute(attributeName, value);
|
|
359
|
+
},
|
|
360
|
+
/**
|
|
361
|
+
* Sets a boolean attribute value.
|
|
362
|
+
* @param element - The element to set the boolean attribute value on.
|
|
363
|
+
* @param attributeName - The attribute name to set.
|
|
364
|
+
* @param value - The value of the attribute to set.
|
|
365
|
+
* @remarks
|
|
366
|
+
* If the value is true, the attribute is added; otherwise it is removed.
|
|
367
|
+
*/
|
|
368
|
+
setBooleanAttribute(element, attributeName, value) {
|
|
369
|
+
value
|
|
370
|
+
? element.setAttribute(attributeName, "")
|
|
371
|
+
: element.removeAttribute(attributeName);
|
|
372
|
+
},
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
function safeURL(tagName, aspect, aspectName, sink) {
|
|
376
|
+
return (target, name, value, ...rest) => {
|
|
377
|
+
if (isString(value)) {
|
|
378
|
+
value = value.replace("javascript:", "");
|
|
379
|
+
}
|
|
380
|
+
sink(target, name, value, ...rest);
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function block(tagName, aspect, aspectName, sink) {
|
|
384
|
+
throw new Error(`${aspectName} on ${tagName !== null && tagName !== void 0 ? tagName : "text"} is blocked by the current DOMPolicy.`);
|
|
385
|
+
}
|
|
386
|
+
const defaultDOMElementGuards = {
|
|
387
|
+
a: {
|
|
388
|
+
[DOMAspect.attribute]: {
|
|
389
|
+
href: safeURL,
|
|
390
|
+
},
|
|
391
|
+
[DOMAspect.property]: {
|
|
392
|
+
href: safeURL,
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
area: {
|
|
396
|
+
[DOMAspect.attribute]: {
|
|
397
|
+
href: safeURL,
|
|
398
|
+
},
|
|
399
|
+
[DOMAspect.property]: {
|
|
400
|
+
href: safeURL,
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
button: {
|
|
404
|
+
[DOMAspect.attribute]: {
|
|
405
|
+
formaction: safeURL,
|
|
406
|
+
},
|
|
407
|
+
[DOMAspect.property]: {
|
|
408
|
+
formAction: safeURL,
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
embed: {
|
|
412
|
+
[DOMAspect.attribute]: {
|
|
413
|
+
src: block,
|
|
414
|
+
},
|
|
415
|
+
[DOMAspect.property]: {
|
|
416
|
+
src: block,
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
form: {
|
|
420
|
+
[DOMAspect.attribute]: {
|
|
421
|
+
action: safeURL,
|
|
422
|
+
},
|
|
423
|
+
[DOMAspect.property]: {
|
|
424
|
+
action: safeURL,
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
frame: {
|
|
428
|
+
[DOMAspect.attribute]: {
|
|
429
|
+
src: safeURL,
|
|
430
|
+
},
|
|
431
|
+
[DOMAspect.property]: {
|
|
432
|
+
src: safeURL,
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
iframe: {
|
|
436
|
+
[DOMAspect.attribute]: {
|
|
437
|
+
src: safeURL,
|
|
438
|
+
},
|
|
439
|
+
[DOMAspect.property]: {
|
|
440
|
+
src: safeURL,
|
|
441
|
+
srcdoc: block,
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
input: {
|
|
445
|
+
[DOMAspect.attribute]: {
|
|
446
|
+
formaction: safeURL,
|
|
447
|
+
},
|
|
448
|
+
[DOMAspect.property]: {
|
|
449
|
+
formAction: safeURL,
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
link: {
|
|
453
|
+
[DOMAspect.attribute]: {
|
|
454
|
+
href: block,
|
|
455
|
+
},
|
|
456
|
+
[DOMAspect.property]: {
|
|
457
|
+
href: block,
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
object: {
|
|
461
|
+
[DOMAspect.attribute]: {
|
|
462
|
+
codebase: block,
|
|
463
|
+
data: block,
|
|
464
|
+
},
|
|
465
|
+
[DOMAspect.property]: {
|
|
466
|
+
codeBase: block,
|
|
467
|
+
data: block,
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
script: {
|
|
471
|
+
[DOMAspect.attribute]: {
|
|
472
|
+
src: block,
|
|
473
|
+
text: block,
|
|
474
|
+
},
|
|
475
|
+
[DOMAspect.property]: {
|
|
476
|
+
src: block,
|
|
477
|
+
text: block,
|
|
478
|
+
innerText: block,
|
|
479
|
+
textContent: block,
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
style: {
|
|
483
|
+
[DOMAspect.property]: {
|
|
484
|
+
innerText: block,
|
|
485
|
+
textContent: block,
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
};
|
|
489
|
+
const blockedEvents = {
|
|
490
|
+
onabort: block,
|
|
491
|
+
onauxclick: block,
|
|
492
|
+
onbeforeinput: block,
|
|
493
|
+
onbeforematch: block,
|
|
494
|
+
onblur: block,
|
|
495
|
+
oncancel: block,
|
|
496
|
+
oncanplay: block,
|
|
497
|
+
oncanplaythrough: block,
|
|
498
|
+
onchange: block,
|
|
499
|
+
onclick: block,
|
|
500
|
+
onclose: block,
|
|
501
|
+
oncontextlost: block,
|
|
502
|
+
oncontextmenu: block,
|
|
503
|
+
oncontextrestored: block,
|
|
504
|
+
oncopy: block,
|
|
505
|
+
oncuechange: block,
|
|
506
|
+
oncut: block,
|
|
507
|
+
ondblclick: block,
|
|
508
|
+
ondrag: block,
|
|
509
|
+
ondragend: block,
|
|
510
|
+
ondragenter: block,
|
|
511
|
+
ondragleave: block,
|
|
512
|
+
ondragover: block,
|
|
513
|
+
ondragstart: block,
|
|
514
|
+
ondrop: block,
|
|
515
|
+
ondurationchange: block,
|
|
516
|
+
onemptied: block,
|
|
517
|
+
onended: block,
|
|
518
|
+
onerror: block,
|
|
519
|
+
onfocus: block,
|
|
520
|
+
onformdata: block,
|
|
521
|
+
oninput: block,
|
|
522
|
+
oninvalid: block,
|
|
523
|
+
onkeydown: block,
|
|
524
|
+
onkeypress: block,
|
|
525
|
+
onkeyup: block,
|
|
526
|
+
onload: block,
|
|
527
|
+
onloadeddata: block,
|
|
528
|
+
onloadedmetadata: block,
|
|
529
|
+
onloadstart: block,
|
|
530
|
+
onmousedown: block,
|
|
531
|
+
onmouseenter: block,
|
|
532
|
+
onmouseleave: block,
|
|
533
|
+
onmousemove: block,
|
|
534
|
+
onmouseout: block,
|
|
535
|
+
onmouseover: block,
|
|
536
|
+
onmouseup: block,
|
|
537
|
+
onpaste: block,
|
|
538
|
+
onpause: block,
|
|
539
|
+
onplay: block,
|
|
540
|
+
onplaying: block,
|
|
541
|
+
onprogress: block,
|
|
542
|
+
onratechange: block,
|
|
543
|
+
onreset: block,
|
|
544
|
+
onresize: block,
|
|
545
|
+
onscroll: block,
|
|
546
|
+
onsecuritypolicyviolation: block,
|
|
547
|
+
onseeked: block,
|
|
548
|
+
onseeking: block,
|
|
549
|
+
onselect: block,
|
|
550
|
+
onslotchange: block,
|
|
551
|
+
onstalled: block,
|
|
552
|
+
onsubmit: block,
|
|
553
|
+
onsuspend: block,
|
|
554
|
+
ontimeupdate: block,
|
|
555
|
+
ontoggle: block,
|
|
556
|
+
onvolumechange: block,
|
|
557
|
+
onwaiting: block,
|
|
558
|
+
onwebkitanimationend: block,
|
|
559
|
+
onwebkitanimationiteration: block,
|
|
560
|
+
onwebkitanimationstart: block,
|
|
561
|
+
onwebkittransitionend: block,
|
|
562
|
+
onwheel: block,
|
|
563
|
+
};
|
|
564
|
+
const defaultDOMGuards = {
|
|
565
|
+
elements: defaultDOMElementGuards,
|
|
566
|
+
aspects: {
|
|
567
|
+
[DOMAspect.attribute]: Object.assign({}, blockedEvents),
|
|
568
|
+
[DOMAspect.property]: Object.assign({ innerHTML: block }, blockedEvents),
|
|
569
|
+
[DOMAspect.event]: Object.assign({}, blockedEvents),
|
|
570
|
+
},
|
|
571
|
+
};
|
|
572
|
+
function createDomSinkGuards(config, defaults) {
|
|
573
|
+
const result = {};
|
|
574
|
+
for (const name in defaults) {
|
|
575
|
+
const overrideValue = config[name];
|
|
576
|
+
const defaultValue = defaults[name];
|
|
577
|
+
switch (overrideValue) {
|
|
578
|
+
case null:
|
|
579
|
+
// remove the default
|
|
580
|
+
break;
|
|
581
|
+
case undefined:
|
|
582
|
+
// keep the default
|
|
583
|
+
result[name] = defaultValue;
|
|
584
|
+
break;
|
|
585
|
+
default:
|
|
586
|
+
// override the default
|
|
587
|
+
result[name] = overrideValue;
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
// add any new sinks that were not overrides
|
|
592
|
+
for (const name in config) {
|
|
593
|
+
if (!(name in result)) {
|
|
594
|
+
result[name] = config[name];
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return Object.freeze(result);
|
|
598
|
+
}
|
|
599
|
+
function createDOMAspectGuards(config, defaults) {
|
|
600
|
+
const result = {};
|
|
601
|
+
for (const aspect in defaults) {
|
|
602
|
+
const overrideValue = config[aspect];
|
|
603
|
+
const defaultValue = defaults[aspect];
|
|
604
|
+
switch (overrideValue) {
|
|
605
|
+
case null:
|
|
606
|
+
// remove the default
|
|
607
|
+
break;
|
|
608
|
+
case undefined:
|
|
609
|
+
// keep the default
|
|
610
|
+
result[aspect] = createDomSinkGuards(defaultValue, {});
|
|
611
|
+
break;
|
|
612
|
+
default:
|
|
613
|
+
// override the default
|
|
614
|
+
result[aspect] = createDomSinkGuards(overrideValue, defaultValue);
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
// add any new aspect guards that were not overrides
|
|
619
|
+
for (const aspect in config) {
|
|
620
|
+
if (!(aspect in result)) {
|
|
621
|
+
result[aspect] = createDomSinkGuards(config[aspect], {});
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return Object.freeze(result);
|
|
625
|
+
}
|
|
626
|
+
function createElementGuards(config, defaults) {
|
|
627
|
+
const result = {};
|
|
628
|
+
for (const tag in defaults) {
|
|
629
|
+
const overrideValue = config[tag];
|
|
630
|
+
const defaultValue = defaults[tag];
|
|
631
|
+
switch (overrideValue) {
|
|
632
|
+
case null:
|
|
633
|
+
// remove the default
|
|
634
|
+
break;
|
|
635
|
+
case undefined:
|
|
636
|
+
// keep the default
|
|
637
|
+
result[tag] = createDOMAspectGuards(overrideValue, {});
|
|
638
|
+
break;
|
|
639
|
+
default:
|
|
640
|
+
// override the default aspects
|
|
641
|
+
result[tag] = createDOMAspectGuards(overrideValue, defaultValue);
|
|
642
|
+
break;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
// Add any new element guards that were not overrides
|
|
646
|
+
for (const tag in config) {
|
|
647
|
+
if (!(tag in result)) {
|
|
648
|
+
result[tag] = createDOMAspectGuards(config[tag], {});
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return Object.freeze(result);
|
|
652
|
+
}
|
|
653
|
+
function createDOMGuards(config, defaults) {
|
|
654
|
+
return Object.freeze({
|
|
655
|
+
elements: config.elements
|
|
656
|
+
? createElementGuards(config.elements, defaults.elements)
|
|
657
|
+
: defaults.elements,
|
|
658
|
+
aspects: config.aspects
|
|
659
|
+
? createDOMAspectGuards(config.aspects, defaults.aspects)
|
|
660
|
+
: defaults.aspects,
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
function createTrustedType() {
|
|
664
|
+
const createHTML = html => html;
|
|
665
|
+
return globalThis.trustedTypes
|
|
666
|
+
? globalThis.trustedTypes.createPolicy("fast-html", { createHTML })
|
|
667
|
+
: { createHTML };
|
|
668
|
+
}
|
|
669
|
+
function tryGuard(aspectGuards, tagName, aspect, aspectName, sink) {
|
|
670
|
+
const sinkGuards = aspectGuards[aspect];
|
|
671
|
+
if (sinkGuards) {
|
|
672
|
+
const guard = sinkGuards[aspectName];
|
|
673
|
+
if (guard) {
|
|
674
|
+
return guard(tagName, aspect, aspectName, sink);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
const DOMPolicy = Object.freeze({
|
|
679
|
+
/**
|
|
680
|
+
* Creates a new DOM Policy object.
|
|
681
|
+
* @param options The options to use in creating the policy.
|
|
682
|
+
* @returns The newly created DOMPolicy.
|
|
683
|
+
*/
|
|
684
|
+
create(options = {}) {
|
|
685
|
+
var _a, _b;
|
|
686
|
+
const trustedType = (_a = options.trustedType) !== null && _a !== void 0 ? _a : createTrustedType();
|
|
687
|
+
const guards = createDOMGuards((_b = options.guards) !== null && _b !== void 0 ? _b : {}, defaultDOMGuards);
|
|
688
|
+
return Object.freeze({
|
|
689
|
+
createHTML(value) {
|
|
690
|
+
return trustedType.createHTML(value);
|
|
691
|
+
},
|
|
692
|
+
protect(tagName, aspect, aspectName, sink) {
|
|
693
|
+
var _a;
|
|
694
|
+
// Check for element-specific guards.
|
|
695
|
+
const key = (tagName !== null && tagName !== void 0 ? tagName : "").toLowerCase();
|
|
696
|
+
const elementGuards = guards.elements[key];
|
|
697
|
+
if (elementGuards) {
|
|
698
|
+
const guard = tryGuard(elementGuards, tagName, aspect, aspectName, sink);
|
|
699
|
+
if (guard) {
|
|
700
|
+
return guard;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
// Check for guards applicable to all nodes.
|
|
704
|
+
return ((_a = tryGuard(guards.aspects, tagName, aspect, aspectName, sink)) !== null && _a !== void 0 ? _a : sink);
|
|
705
|
+
},
|
|
706
|
+
});
|
|
707
|
+
},
|
|
708
|
+
});
|
|
709
|
+
|
|
260
710
|
/**
|
|
261
711
|
* An implementation of {@link Notifier} that efficiently keeps track of
|
|
262
712
|
* subscribers interested in a specific change notification on an
|
|
@@ -1543,55 +1993,6 @@ css.partial = (strings, ...values) => {
|
|
|
1543
1993
|
*/
|
|
1544
1994
|
const cssPartial = css.partial;
|
|
1545
1995
|
|
|
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
1996
|
const marker = `fast-${Math.random().toString(36).substring(2, 8)}`;
|
|
1596
1997
|
const interpolationStart = `${marker}{`;
|
|
1597
1998
|
const interpolationEnd = `}${marker}`;
|
|
@@ -1668,67 +2069,6 @@ const Parser = Object.freeze({
|
|
|
1668
2069
|
},
|
|
1669
2070
|
});
|
|
1670
2071
|
|
|
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
2072
|
const registry = createTypeRegistry();
|
|
1733
2073
|
/**
|
|
1734
2074
|
* Instructs the template engine to apply behavior to a node.
|
|
@@ -1756,67 +2096,6 @@ const HTMLDirective = Object.freeze({
|
|
|
1756
2096
|
registry.register(options);
|
|
1757
2097
|
return type;
|
|
1758
2098
|
},
|
|
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
2099
|
/**
|
|
1821
2100
|
*
|
|
1822
2101
|
* @param directive - The directive to assign the aspect to.
|
|
@@ -1824,9 +2103,9 @@ const Aspect = Object.freeze({
|
|
|
1824
2103
|
* @remarks
|
|
1825
2104
|
* If a falsy value is provided, then the content aspect will be assigned.
|
|
1826
2105
|
*/
|
|
1827
|
-
|
|
2106
|
+
assignAspect(directive, value) {
|
|
1828
2107
|
if (!value) {
|
|
1829
|
-
directive.aspectType =
|
|
2108
|
+
directive.aspectType = DOMAspect.content;
|
|
1830
2109
|
return;
|
|
1831
2110
|
}
|
|
1832
2111
|
directive.sourceAspect = value;
|
|
@@ -1835,24 +2114,53 @@ const Aspect = Object.freeze({
|
|
|
1835
2114
|
directive.targetAspect = value.substring(1);
|
|
1836
2115
|
directive.aspectType =
|
|
1837
2116
|
directive.targetAspect === "classList"
|
|
1838
|
-
?
|
|
1839
|
-
:
|
|
2117
|
+
? DOMAspect.tokenList
|
|
2118
|
+
: DOMAspect.property;
|
|
1840
2119
|
break;
|
|
1841
2120
|
case "?":
|
|
1842
2121
|
directive.targetAspect = value.substring(1);
|
|
1843
|
-
directive.aspectType =
|
|
2122
|
+
directive.aspectType = DOMAspect.booleanAttribute;
|
|
1844
2123
|
break;
|
|
1845
2124
|
case "@":
|
|
1846
2125
|
directive.targetAspect = value.substring(1);
|
|
1847
|
-
directive.aspectType =
|
|
2126
|
+
directive.aspectType = DOMAspect.event;
|
|
1848
2127
|
break;
|
|
1849
2128
|
default:
|
|
1850
2129
|
directive.targetAspect = value;
|
|
1851
|
-
directive.aspectType =
|
|
2130
|
+
directive.aspectType = DOMAspect.attribute;
|
|
1852
2131
|
break;
|
|
1853
2132
|
}
|
|
1854
2133
|
},
|
|
1855
2134
|
});
|
|
2135
|
+
/**
|
|
2136
|
+
* Decorator: Defines an HTMLDirective.
|
|
2137
|
+
* @param options - Provides options that specify the directive's application.
|
|
2138
|
+
* @public
|
|
2139
|
+
*/
|
|
2140
|
+
function htmlDirective(options) {
|
|
2141
|
+
/* eslint-disable-next-line @typescript-eslint/explicit-function-return-type */
|
|
2142
|
+
return function (type) {
|
|
2143
|
+
HTMLDirective.define(type, options);
|
|
2144
|
+
};
|
|
2145
|
+
}
|
|
2146
|
+
/**
|
|
2147
|
+
* Captures a binding expression along with related information and capabilities.
|
|
2148
|
+
*
|
|
2149
|
+
* @public
|
|
2150
|
+
*/
|
|
2151
|
+
class Binding {
|
|
2152
|
+
/**
|
|
2153
|
+
* Creates a binding.
|
|
2154
|
+
* @param evaluate - Evaluates the binding.
|
|
2155
|
+
* @param policy - The security policy to associate with this binding.
|
|
2156
|
+
* @param isVolatile - Indicates whether the binding is volatile.
|
|
2157
|
+
*/
|
|
2158
|
+
constructor(evaluate, policy, isVolatile = false) {
|
|
2159
|
+
this.evaluate = evaluate;
|
|
2160
|
+
this.policy = policy;
|
|
2161
|
+
this.isVolatile = isVolatile;
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
1856
2164
|
/**
|
|
1857
2165
|
* A base class used for attribute directives that don't need internal state.
|
|
1858
2166
|
* @public
|
|
@@ -1864,10 +2172,6 @@ class StatelessAttachedAttributeDirective {
|
|
|
1864
2172
|
*/
|
|
1865
2173
|
constructor(options) {
|
|
1866
2174
|
this.options = options;
|
|
1867
|
-
/**
|
|
1868
|
-
* The unique id of the factory.
|
|
1869
|
-
*/
|
|
1870
|
-
this.id = nextId();
|
|
1871
2175
|
/**
|
|
1872
2176
|
* Opts out of JSON stringification.
|
|
1873
2177
|
* @internal
|
|
@@ -1892,15 +2196,6 @@ class StatelessAttachedAttributeDirective {
|
|
|
1892
2196
|
}
|
|
1893
2197
|
}
|
|
1894
2198
|
|
|
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
2199
|
class OnChangeBinding extends Binding {
|
|
1905
2200
|
createObserver(_, subscriber) {
|
|
1906
2201
|
return Observable.binding(this.evaluate, subscriber, this.isVolatile);
|
|
@@ -2013,8 +2308,14 @@ function updateTokenList(target, aspect, value) {
|
|
|
2013
2308
|
}
|
|
2014
2309
|
}
|
|
2015
2310
|
}
|
|
2016
|
-
const
|
|
2017
|
-
|
|
2311
|
+
const sinkLookup = {
|
|
2312
|
+
[DOMAspect.attribute]: DOM.setAttribute,
|
|
2313
|
+
[DOMAspect.booleanAttribute]: DOM.setBooleanAttribute,
|
|
2314
|
+
[DOMAspect.property]: (t, a, v) => (t[a] = v),
|
|
2315
|
+
[DOMAspect.content]: updateContent,
|
|
2316
|
+
[DOMAspect.tokenList]: updateTokenList,
|
|
2317
|
+
[DOMAspect.event]: () => void 0,
|
|
2318
|
+
};
|
|
2018
2319
|
/**
|
|
2019
2320
|
* A directive that applies bindings.
|
|
2020
2321
|
* @public
|
|
@@ -2027,15 +2328,10 @@ class HTMLBindingDirective {
|
|
|
2027
2328
|
constructor(dataBinding) {
|
|
2028
2329
|
this.dataBinding = dataBinding;
|
|
2029
2330
|
this.updateTarget = null;
|
|
2030
|
-
/**
|
|
2031
|
-
* The unique id of the factory.
|
|
2032
|
-
*/
|
|
2033
|
-
this.id = nextId();
|
|
2034
2331
|
/**
|
|
2035
2332
|
* The type of aspect to target.
|
|
2036
2333
|
*/
|
|
2037
|
-
this.aspectType =
|
|
2038
|
-
this.data = `${this.id}-d`;
|
|
2334
|
+
this.aspectType = DOMAspect.content;
|
|
2039
2335
|
}
|
|
2040
2336
|
/**
|
|
2041
2337
|
* Creates HTML to be used within a template.
|
|
@@ -2048,45 +2344,28 @@ class HTMLBindingDirective {
|
|
|
2048
2344
|
* Creates a behavior.
|
|
2049
2345
|
*/
|
|
2050
2346
|
createBehavior() {
|
|
2347
|
+
var _a;
|
|
2051
2348
|
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 */);
|
|
2349
|
+
const sink = sinkLookup[this.aspectType];
|
|
2350
|
+
const policy = (_a = this.dataBinding.policy) !== null && _a !== void 0 ? _a : this.policy;
|
|
2351
|
+
if (!sink) {
|
|
2352
|
+
throw FAST.error(1205 /* Message.unsupportedBindingBehavior */);
|
|
2076
2353
|
}
|
|
2354
|
+
this.data = `${this.id}-d`;
|
|
2355
|
+
this.updateTarget = policy.protect(this.targetTagName, this.aspectType, this.targetAspect, sink);
|
|
2077
2356
|
}
|
|
2078
2357
|
return this;
|
|
2079
2358
|
}
|
|
2080
2359
|
/** @internal */
|
|
2081
2360
|
bind(controller) {
|
|
2082
2361
|
var _a;
|
|
2083
|
-
const target = controller.targets[this.
|
|
2084
|
-
switch (this.
|
|
2085
|
-
case
|
|
2362
|
+
const target = controller.targets[this.targetNodeId];
|
|
2363
|
+
switch (this.aspectType) {
|
|
2364
|
+
case DOMAspect.event:
|
|
2086
2365
|
target[this.data] = controller;
|
|
2087
2366
|
target.addEventListener(this.targetAspect, this, this.dataBinding.options);
|
|
2088
2367
|
break;
|
|
2089
|
-
case
|
|
2368
|
+
case DOMAspect.content:
|
|
2090
2369
|
controller.onUnbind(this);
|
|
2091
2370
|
// intentional fall through
|
|
2092
2371
|
default:
|
|
@@ -2099,7 +2378,7 @@ class HTMLBindingDirective {
|
|
|
2099
2378
|
}
|
|
2100
2379
|
/** @internal */
|
|
2101
2380
|
unbind(controller) {
|
|
2102
|
-
const target = controller.targets[this.
|
|
2381
|
+
const target = controller.targets[this.targetNodeId];
|
|
2103
2382
|
const view = target.$fastView;
|
|
2104
2383
|
if (view !== void 0 && view.isComposed) {
|
|
2105
2384
|
view.unbind();
|
|
@@ -2129,21 +2408,23 @@ HTMLDirective.define(HTMLBindingDirective, { aspected: true });
|
|
|
2129
2408
|
/**
|
|
2130
2409
|
* Creates an standard binding.
|
|
2131
2410
|
* @param expression - The binding to refresh when changed.
|
|
2411
|
+
* @param policy - The security policy to associate with th binding.
|
|
2132
2412
|
* @param isVolatile - Indicates whether the binding is volatile or not.
|
|
2133
2413
|
* @returns A binding configuration.
|
|
2134
2414
|
* @public
|
|
2135
2415
|
*/
|
|
2136
|
-
function bind(expression, isVolatile = Observable.isVolatileBinding(expression)) {
|
|
2137
|
-
return new OnChangeBinding(expression, isVolatile);
|
|
2416
|
+
function bind(expression, policy, isVolatile = Observable.isVolatileBinding(expression)) {
|
|
2417
|
+
return new OnChangeBinding(expression, policy, isVolatile);
|
|
2138
2418
|
}
|
|
2139
2419
|
/**
|
|
2140
2420
|
* Creates a one time binding
|
|
2141
2421
|
* @param expression - The binding to refresh when signaled.
|
|
2422
|
+
* @param policy - The security policy to associate with th binding.
|
|
2142
2423
|
* @returns A binding configuration.
|
|
2143
2424
|
* @public
|
|
2144
2425
|
*/
|
|
2145
|
-
function oneTime(expression) {
|
|
2146
|
-
return new OneTimeBinding(expression);
|
|
2426
|
+
function oneTime(expression, policy) {
|
|
2427
|
+
return new OneTimeBinding(expression, policy);
|
|
2147
2428
|
}
|
|
2148
2429
|
/**
|
|
2149
2430
|
* Creates an event listener binding.
|
|
@@ -2153,7 +2434,7 @@ function oneTime(expression) {
|
|
|
2153
2434
|
* @public
|
|
2154
2435
|
*/
|
|
2155
2436
|
function listener(expression, options) {
|
|
2156
|
-
const config = new OnChangeBinding(expression
|
|
2437
|
+
const config = new OnChangeBinding(expression);
|
|
2157
2438
|
config.options = options;
|
|
2158
2439
|
return config;
|
|
2159
2440
|
}
|
|
@@ -2434,20 +2715,25 @@ const warningHost = new Proxy(document.createElement("div"), {
|
|
|
2434
2715
|
},
|
|
2435
2716
|
});
|
|
2436
2717
|
class CompilationContext {
|
|
2437
|
-
constructor(fragment, directives) {
|
|
2718
|
+
constructor(fragment, directives, policy) {
|
|
2438
2719
|
this.fragment = fragment;
|
|
2439
2720
|
this.directives = directives;
|
|
2721
|
+
this.policy = policy;
|
|
2440
2722
|
this.proto = null;
|
|
2441
2723
|
this.nodeIds = new Set();
|
|
2442
2724
|
this.descriptors = {};
|
|
2443
2725
|
this.factories = [];
|
|
2444
2726
|
}
|
|
2445
|
-
addFactory(factory, parentId, nodeId, targetIndex) {
|
|
2727
|
+
addFactory(factory, parentId, nodeId, targetIndex, tagName) {
|
|
2728
|
+
var _a, _b;
|
|
2446
2729
|
if (!this.nodeIds.has(nodeId)) {
|
|
2447
2730
|
this.nodeIds.add(nodeId);
|
|
2448
2731
|
this.addTargetDescriptor(parentId, nodeId, targetIndex);
|
|
2449
2732
|
}
|
|
2450
|
-
factory.
|
|
2733
|
+
factory.id = (_a = factory.id) !== null && _a !== void 0 ? _a : nextId();
|
|
2734
|
+
factory.targetNodeId = nodeId;
|
|
2735
|
+
factory.targetTagName = tagName;
|
|
2736
|
+
factory.policy = (_b = factory.policy) !== null && _b !== void 0 ? _b : this.policy;
|
|
2451
2737
|
this.factories.push(factory);
|
|
2452
2738
|
}
|
|
2453
2739
|
freeze() {
|
|
@@ -2500,19 +2786,19 @@ function compileAttributes(context, parentId, node, nodeId, nodeIndex, includeBa
|
|
|
2500
2786
|
let result = null;
|
|
2501
2787
|
if (parseResult === null) {
|
|
2502
2788
|
if (includeBasicValues) {
|
|
2503
|
-
result = new HTMLBindingDirective(oneTime(() => attrValue));
|
|
2504
|
-
|
|
2789
|
+
result = new HTMLBindingDirective(oneTime(() => attrValue, context.policy));
|
|
2790
|
+
HTMLDirective.assignAspect(result, attr.name);
|
|
2505
2791
|
}
|
|
2506
2792
|
}
|
|
2507
2793
|
else {
|
|
2508
2794
|
/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
|
|
2509
|
-
result = Compiler.aggregate(parseResult);
|
|
2795
|
+
result = Compiler.aggregate(parseResult, context.policy);
|
|
2510
2796
|
}
|
|
2511
2797
|
if (result !== null) {
|
|
2512
2798
|
node.removeAttributeNode(attr);
|
|
2513
2799
|
i--;
|
|
2514
2800
|
ii--;
|
|
2515
|
-
context.addFactory(result, parentId, nodeId, nodeIndex);
|
|
2801
|
+
context.addFactory(result, parentId, nodeId, nodeIndex, node.tagName);
|
|
2516
2802
|
}
|
|
2517
2803
|
}
|
|
2518
2804
|
}
|
|
@@ -2537,8 +2823,8 @@ function compileContent(context, node, parentId, nodeId, nodeIndex) {
|
|
|
2537
2823
|
}
|
|
2538
2824
|
else {
|
|
2539
2825
|
currentNode.textContent = " ";
|
|
2540
|
-
|
|
2541
|
-
context.addFactory(currentPart, parentId, nodeId, nodeIndex);
|
|
2826
|
+
HTMLDirective.assignAspect(currentPart);
|
|
2827
|
+
context.addFactory(currentPart, parentId, nodeId, nodeIndex, null);
|
|
2542
2828
|
}
|
|
2543
2829
|
lastNode = currentNode;
|
|
2544
2830
|
}
|
|
@@ -2570,7 +2856,7 @@ function compileNode(context, parentId, node, nodeIndex) {
|
|
|
2570
2856
|
if (parts !== null) {
|
|
2571
2857
|
context.addFactory(
|
|
2572
2858
|
/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
|
|
2573
|
-
Compiler.aggregate(parts), parentId, nodeId, nodeIndex);
|
|
2859
|
+
Compiler.aggregate(parts), parentId, nodeId, nodeIndex, null);
|
|
2574
2860
|
}
|
|
2575
2861
|
break;
|
|
2576
2862
|
}
|
|
@@ -2584,45 +2870,28 @@ function isMarker(node, directives) {
|
|
|
2584
2870
|
Parser.parse(node.data, directives) !== null);
|
|
2585
2871
|
}
|
|
2586
2872
|
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
2873
|
/**
|
|
2593
2874
|
* Common APIs related to compilation.
|
|
2594
2875
|
* @public
|
|
2595
2876
|
*/
|
|
2596
2877
|
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
2878
|
/**
|
|
2611
2879
|
* Compiles a template and associated directives into a compilation
|
|
2612
2880
|
* result which can be used to create views.
|
|
2613
2881
|
* @param html - The html string or template element to compile.
|
|
2614
|
-
* @param
|
|
2882
|
+
* @param factories - The behavior factories referenced by the template.
|
|
2883
|
+
* @param policy - The security policy to compile the html with.
|
|
2615
2884
|
* @remarks
|
|
2616
2885
|
* The template that is provided for compilation is altered in-place
|
|
2617
2886
|
* and cannot be compiled again. If the original template must be preserved,
|
|
2618
2887
|
* it is recommended that you clone the original and pass the clone to this API.
|
|
2619
2888
|
* @public
|
|
2620
2889
|
*/
|
|
2621
|
-
compile(html,
|
|
2890
|
+
compile(html, factories, policy = DOM.policy) {
|
|
2622
2891
|
let template;
|
|
2623
2892
|
if (isString(html)) {
|
|
2624
2893
|
template = document.createElement(templateTag);
|
|
2625
|
-
template.innerHTML =
|
|
2894
|
+
template.innerHTML = policy.createHTML(html);
|
|
2626
2895
|
const fec = template.content.firstElementChild;
|
|
2627
2896
|
if (fec !== null && fec.tagName === templateTag) {
|
|
2628
2897
|
template = fec;
|
|
@@ -2633,18 +2902,18 @@ const Compiler = {
|
|
|
2633
2902
|
}
|
|
2634
2903
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1111864
|
|
2635
2904
|
const fragment = document.adoptNode(template.content);
|
|
2636
|
-
const context = new CompilationContext(fragment,
|
|
2905
|
+
const context = new CompilationContext(fragment, factories, policy);
|
|
2637
2906
|
compileAttributes(context, "", template, /* host */ "h", 0, true);
|
|
2638
2907
|
if (
|
|
2639
2908
|
// If the first node in a fragment is a marker, that means it's an unstable first node,
|
|
2640
2909
|
// because something like a when, repeat, etc. could add nodes before the marker.
|
|
2641
2910
|
// To mitigate this, we insert a stable first node. However, if we insert a node,
|
|
2642
2911
|
// that will alter the result of the TreeWalker. So, we also need to offset the target index.
|
|
2643
|
-
isMarker(fragment.firstChild,
|
|
2912
|
+
isMarker(fragment.firstChild, factories) ||
|
|
2644
2913
|
// Or if there is only one node and a directive, it means the template's content
|
|
2645
2914
|
// is *only* the directive. In that case, HTMLView.dispose() misses any nodes inserted by
|
|
2646
2915
|
// the directive. Inserting a new node ensures proper disposal of nodes added by the directive.
|
|
2647
|
-
(fragment.childNodes.length === 1 && Object.keys(
|
|
2916
|
+
(fragment.childNodes.length === 1 && Object.keys(factories).length > 0)) {
|
|
2648
2917
|
fragment.insertBefore(document.createComment(""), fragment.firstChild);
|
|
2649
2918
|
}
|
|
2650
2919
|
compileChildren(context, fragment, /* root */ "r");
|
|
@@ -2663,15 +2932,17 @@ const Compiler = {
|
|
|
2663
2932
|
* Aggregates an array of strings and directives into a single directive.
|
|
2664
2933
|
* @param parts - A heterogeneous array of static strings interspersed with
|
|
2665
2934
|
* directives.
|
|
2935
|
+
* @param policy - The security policy to use with the aggregated bindings.
|
|
2666
2936
|
* @returns A single inline directive that aggregates the behavior of all the parts.
|
|
2667
2937
|
*/
|
|
2668
|
-
aggregate(parts) {
|
|
2938
|
+
aggregate(parts, policy = DOM.policy) {
|
|
2669
2939
|
if (parts.length === 1) {
|
|
2670
2940
|
return parts[0];
|
|
2671
2941
|
}
|
|
2672
2942
|
let sourceAspect;
|
|
2673
2943
|
let binding;
|
|
2674
2944
|
let isVolatile = false;
|
|
2945
|
+
let bindingPolicy = void 0;
|
|
2675
2946
|
const partCount = parts.length;
|
|
2676
2947
|
const finalParts = parts.map((x) => {
|
|
2677
2948
|
if (isString(x)) {
|
|
@@ -2680,6 +2951,7 @@ const Compiler = {
|
|
|
2680
2951
|
sourceAspect = x.sourceAspect || sourceAspect;
|
|
2681
2952
|
binding = x.dataBinding || binding;
|
|
2682
2953
|
isVolatile = isVolatile || x.dataBinding.isVolatile;
|
|
2954
|
+
bindingPolicy = bindingPolicy || x.dataBinding.policy;
|
|
2683
2955
|
return x.dataBinding.evaluate;
|
|
2684
2956
|
});
|
|
2685
2957
|
const expression = (scope, context) => {
|
|
@@ -2691,12 +2963,26 @@ const Compiler = {
|
|
|
2691
2963
|
};
|
|
2692
2964
|
binding.evaluate = expression;
|
|
2693
2965
|
binding.isVolatile = isVolatile;
|
|
2966
|
+
binding.policy = bindingPolicy !== null && bindingPolicy !== void 0 ? bindingPolicy : policy;
|
|
2694
2967
|
const directive = new HTMLBindingDirective(binding);
|
|
2695
|
-
|
|
2968
|
+
HTMLDirective.assignAspect(directive, sourceAspect);
|
|
2696
2969
|
return directive;
|
|
2697
2970
|
},
|
|
2698
2971
|
};
|
|
2699
2972
|
|
|
2973
|
+
// Much thanks to LitHTML for working this out!
|
|
2974
|
+
const lastAttributeNameRegex =
|
|
2975
|
+
/* eslint-disable-next-line no-control-regex */
|
|
2976
|
+
/([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F "'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/;
|
|
2977
|
+
function createHTML(value, prevString, add, definition = HTMLDirective.getForInstance(value)) {
|
|
2978
|
+
if (definition.aspected) {
|
|
2979
|
+
const match = lastAttributeNameRegex.exec(prevString);
|
|
2980
|
+
if (match !== null) {
|
|
2981
|
+
HTMLDirective.assignAspect(value, match[2]);
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2984
|
+
return value.createHTML(add);
|
|
2985
|
+
}
|
|
2700
2986
|
/**
|
|
2701
2987
|
* A template capable of creating HTMLView instances or rendering directly to DOM.
|
|
2702
2988
|
* @public
|
|
@@ -2706,8 +2992,10 @@ class ViewTemplate {
|
|
|
2706
2992
|
* Creates an instance of ViewTemplate.
|
|
2707
2993
|
* @param html - The html representing what this template will instantiate, including placeholders for directives.
|
|
2708
2994
|
* @param factories - The directives that will be connected to placeholders in the html.
|
|
2995
|
+
* @param policy - The security policy to use when compiling this template.
|
|
2709
2996
|
*/
|
|
2710
|
-
constructor(html, factories) {
|
|
2997
|
+
constructor(html, factories = {}, policy) {
|
|
2998
|
+
this.policy = policy;
|
|
2711
2999
|
this.result = null;
|
|
2712
3000
|
/**
|
|
2713
3001
|
* Opts out of JSON stringification.
|
|
@@ -2723,10 +3011,28 @@ class ViewTemplate {
|
|
|
2723
3011
|
*/
|
|
2724
3012
|
create(hostBindingTarget) {
|
|
2725
3013
|
if (this.result === null) {
|
|
2726
|
-
this.result = Compiler.compile(this.html, this.factories);
|
|
3014
|
+
this.result = Compiler.compile(this.html, this.factories, this.policy);
|
|
2727
3015
|
}
|
|
2728
3016
|
return this.result.createView(hostBindingTarget);
|
|
2729
3017
|
}
|
|
3018
|
+
/**
|
|
3019
|
+
* Sets the DOMPolicy for this template.
|
|
3020
|
+
* @param policy - The policy to associated with this template.
|
|
3021
|
+
* @returns The modified template instance.
|
|
3022
|
+
* @remarks
|
|
3023
|
+
* The DOMPolicy can only be set once for a template and cannot be
|
|
3024
|
+
* set after the template is compiled.
|
|
3025
|
+
*/
|
|
3026
|
+
withPolicy(policy) {
|
|
3027
|
+
if (this.result) {
|
|
3028
|
+
throw FAST.error(1208 /* Message.cannotSetTemplatePolicyAfterCompilation */);
|
|
3029
|
+
}
|
|
3030
|
+
if (this.policy) {
|
|
3031
|
+
throw FAST.error(1207 /* Message.onlySetTemplatePolicyOnce */);
|
|
3032
|
+
}
|
|
3033
|
+
this.policy = policy;
|
|
3034
|
+
return this;
|
|
3035
|
+
}
|
|
2730
3036
|
/**
|
|
2731
3037
|
* Creates an HTMLView from this template, binds it to the source, and then appends it to the host.
|
|
2732
3038
|
* @param source - The data source to bind the template to.
|
|
@@ -2740,17 +3046,47 @@ class ViewTemplate {
|
|
|
2740
3046
|
view.appendTo(host);
|
|
2741
3047
|
return view;
|
|
2742
3048
|
}
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
3049
|
+
/**
|
|
3050
|
+
* Creates a template based on a set of static strings and dynamic values.
|
|
3051
|
+
* @param strings - The static strings to create the template with.
|
|
3052
|
+
* @param values - The dynamic values to create the template with.
|
|
3053
|
+
* @param policy - The DOMPolicy to associated with the template.
|
|
3054
|
+
* @returns A ViewTemplate.
|
|
3055
|
+
* @remarks
|
|
3056
|
+
* This API should not be used directly under normal circumstances because constructing
|
|
3057
|
+
* a template in this way, if not done properly, can open up the application to XSS
|
|
3058
|
+
* attacks. When using this API, provide a strong DOMPolicy that can properly sanitize
|
|
3059
|
+
* and also be sure to manually sanitize all static strings particularly if they can
|
|
3060
|
+
* come from user input.
|
|
3061
|
+
*/
|
|
3062
|
+
static create(strings, values, policy) {
|
|
3063
|
+
let html = "";
|
|
3064
|
+
const factories = Object.create(null);
|
|
3065
|
+
const add = (factory) => {
|
|
3066
|
+
var _a;
|
|
3067
|
+
const id = (_a = factory.id) !== null && _a !== void 0 ? _a : (factory.id = nextId());
|
|
3068
|
+
factories[id] = factory;
|
|
3069
|
+
return id;
|
|
3070
|
+
};
|
|
3071
|
+
for (let i = 0, ii = strings.length - 1; i < ii; ++i) {
|
|
3072
|
+
const currentString = strings[i];
|
|
3073
|
+
let currentValue = values[i];
|
|
3074
|
+
let definition;
|
|
3075
|
+
html += currentString;
|
|
3076
|
+
if (isFunction(currentValue)) {
|
|
3077
|
+
currentValue = new HTMLBindingDirective(bind(currentValue));
|
|
3078
|
+
}
|
|
3079
|
+
else if (currentValue instanceof Binding) {
|
|
3080
|
+
currentValue = new HTMLBindingDirective(currentValue);
|
|
3081
|
+
}
|
|
3082
|
+
else if (!(definition = HTMLDirective.getForInstance(currentValue))) {
|
|
3083
|
+
const staticValue = currentValue;
|
|
3084
|
+
currentValue = new HTMLBindingDirective(oneTime(() => staticValue));
|
|
3085
|
+
}
|
|
3086
|
+
html += createHTML(currentValue, currentString, add, definition);
|
|
3087
|
+
}
|
|
3088
|
+
return new ViewTemplate(html + strings[strings.length - 1], factories, policy);
|
|
2752
3089
|
}
|
|
2753
|
-
return value.createHTML(add);
|
|
2754
3090
|
}
|
|
2755
3091
|
/**
|
|
2756
3092
|
* Transforms a template literal string into a ViewTemplate.
|
|
@@ -2762,49 +3098,10 @@ function createAspectedHTML(value, prevString, add) {
|
|
|
2762
3098
|
* @public
|
|
2763
3099
|
*/
|
|
2764
3100
|
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
|
-
}
|
|
3101
|
+
if (Array.isArray(strings) && Array.isArray(strings.raw)) {
|
|
3102
|
+
return ViewTemplate.create(strings, values);
|
|
2806
3103
|
}
|
|
2807
|
-
|
|
3104
|
+
throw FAST.error(1206 /* Message.directCallToHTMLTagNotAllowed */);
|
|
2808
3105
|
}
|
|
2809
3106
|
|
|
2810
3107
|
/**
|
|
@@ -2817,7 +3114,7 @@ class RefDirective extends StatelessAttachedAttributeDirective {
|
|
|
2817
3114
|
* @param controller - The view controller that manages the lifecycle of this behavior.
|
|
2818
3115
|
*/
|
|
2819
3116
|
bind(controller) {
|
|
2820
|
-
controller.source[this.options] = controller.targets[this.
|
|
3117
|
+
controller.source[this.options] = controller.targets[this.targetNodeId];
|
|
2821
3118
|
}
|
|
2822
3119
|
}
|
|
2823
3120
|
HTMLDirective.define(RefDirective);
|
|
@@ -2891,7 +3188,7 @@ class RepeatBehavior {
|
|
|
2891
3188
|
* @param controller - The view controller that manages the lifecycle of this behavior.
|
|
2892
3189
|
*/
|
|
2893
3190
|
bind(controller) {
|
|
2894
|
-
this.location = controller.targets[this.directive.
|
|
3191
|
+
this.location = controller.targets[this.directive.targetNodeId];
|
|
2895
3192
|
this.controller = controller;
|
|
2896
3193
|
this.items = this.itemsBindingObserver.bind(controller);
|
|
2897
3194
|
this.template = this.templateBindingObserver.bind(controller);
|
|
@@ -3071,10 +3368,6 @@ class RepeatDirective {
|
|
|
3071
3368
|
this.dataBinding = dataBinding;
|
|
3072
3369
|
this.templateBinding = templateBinding;
|
|
3073
3370
|
this.options = options;
|
|
3074
|
-
/**
|
|
3075
|
-
* The unique id of the factory.
|
|
3076
|
-
*/
|
|
3077
|
-
this.id = nextId();
|
|
3078
3371
|
ArrayObserver.enable();
|
|
3079
3372
|
}
|
|
3080
3373
|
/**
|
|
@@ -3123,9 +3416,15 @@ const elements = (selector) => selector
|
|
|
3123
3416
|
* Internally used by the SlottedDirective and the ChildrenDirective.
|
|
3124
3417
|
*/
|
|
3125
3418
|
class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3419
|
+
/**
|
|
3420
|
+
* The unique id of the factory.
|
|
3421
|
+
*/
|
|
3422
|
+
get id() {
|
|
3423
|
+
return this._id;
|
|
3424
|
+
}
|
|
3425
|
+
set id(value) {
|
|
3426
|
+
this._id = value;
|
|
3427
|
+
this._controllerProperty = `${value}-c`;
|
|
3129
3428
|
}
|
|
3130
3429
|
/**
|
|
3131
3430
|
* Bind this behavior to the source.
|
|
@@ -3134,8 +3433,8 @@ class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
|
3134
3433
|
* @param targets - The targets that behaviors in a view can attach to.
|
|
3135
3434
|
*/
|
|
3136
3435
|
bind(controller) {
|
|
3137
|
-
const target = controller.targets[this.
|
|
3138
|
-
target[this.
|
|
3436
|
+
const target = controller.targets[this.targetNodeId];
|
|
3437
|
+
target[this._controllerProperty] = controller;
|
|
3139
3438
|
this.updateTarget(controller.source, this.computeNodes(target));
|
|
3140
3439
|
this.observe(target);
|
|
3141
3440
|
controller.onUnbind(this);
|
|
@@ -3147,10 +3446,10 @@ class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
|
3147
3446
|
* @param targets - The targets that behaviors in a view can attach to.
|
|
3148
3447
|
*/
|
|
3149
3448
|
unbind(controller) {
|
|
3150
|
-
const target = controller.targets[this.
|
|
3449
|
+
const target = controller.targets[this.targetNodeId];
|
|
3151
3450
|
this.updateTarget(controller.source, emptyArray);
|
|
3152
3451
|
this.disconnect(target);
|
|
3153
|
-
target[this.
|
|
3452
|
+
target[this._controllerProperty] = null;
|
|
3154
3453
|
}
|
|
3155
3454
|
/**
|
|
3156
3455
|
* Gets the data source for the target.
|
|
@@ -3158,7 +3457,7 @@ class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
|
3158
3457
|
* @returns The source.
|
|
3159
3458
|
*/
|
|
3160
3459
|
getSource(target) {
|
|
3161
|
-
return target[this.
|
|
3460
|
+
return target[this._controllerProperty].source;
|
|
3162
3461
|
}
|
|
3163
3462
|
/**
|
|
3164
3463
|
* Updates the source property with the computed nodes.
|
|
@@ -3299,6 +3598,29 @@ function children(propertyOrOptions) {
|
|
|
3299
3598
|
return new ChildrenDirective(propertyOrOptions);
|
|
3300
3599
|
}
|
|
3301
3600
|
|
|
3601
|
+
/**
|
|
3602
|
+
* A directive capable of injecting static HTML platform runtime protection.
|
|
3603
|
+
* @public
|
|
3604
|
+
*/
|
|
3605
|
+
class DangerousHTMLDirective {
|
|
3606
|
+
constructor(html) {
|
|
3607
|
+
this.html = html;
|
|
3608
|
+
}
|
|
3609
|
+
createHTML() {
|
|
3610
|
+
return this.html;
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3613
|
+
HTMLDirective.define(DangerousHTMLDirective);
|
|
3614
|
+
/**
|
|
3615
|
+
* Injects static HTML without platform protection.
|
|
3616
|
+
* @param html - The html to injection.
|
|
3617
|
+
* @returns A DangerousHTMLDirective.
|
|
3618
|
+
* @public
|
|
3619
|
+
*/
|
|
3620
|
+
function dangerousHTML(html) {
|
|
3621
|
+
return new DangerousHTMLDirective(html);
|
|
3622
|
+
}
|
|
3623
|
+
|
|
3302
3624
|
const booleanMode = "boolean";
|
|
3303
3625
|
const reflectMode = "reflect";
|
|
3304
3626
|
/**
|
|
@@ -4159,4 +4481,6 @@ function customElement(nameOrDef) {
|
|
|
4159
4481
|
};
|
|
4160
4482
|
}
|
|
4161
4483
|
|
|
4162
|
-
|
|
4484
|
+
DOM.setPolicy(DOMPolicy.create());
|
|
4485
|
+
|
|
4486
|
+
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 };
|