@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
package/dist/fast-element.js
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal
|
|
3
|
+
*/
|
|
4
|
+
const isFunction = (object) => typeof object === "function";
|
|
5
|
+
/**
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
const isString = (object) => typeof object === "string";
|
|
9
|
+
/**
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
const noop = () => void 0;
|
|
13
|
+
|
|
14
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
1
15
|
(function ensureGlobalThis() {
|
|
2
16
|
if (typeof globalThis !== "undefined") {
|
|
3
17
|
// We're running in a modern environment.
|
|
4
18
|
return;
|
|
5
19
|
}
|
|
20
|
+
// @ts-ignore
|
|
6
21
|
if (typeof global !== "undefined") {
|
|
7
22
|
// We're running in NodeJS
|
|
23
|
+
// @ts-ignore
|
|
8
24
|
global.globalThis = global;
|
|
9
25
|
}
|
|
10
26
|
else if (typeof self !== "undefined") {
|
|
@@ -22,14 +38,8 @@
|
|
|
22
38
|
result.globalThis = result;
|
|
23
39
|
}
|
|
24
40
|
})();
|
|
25
|
-
// API-only Polyfill for trustedTypes
|
|
26
|
-
if (!globalThis.trustedTypes) {
|
|
27
|
-
globalThis.trustedTypes = {
|
|
28
|
-
createPolicy: (n, r) => r,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
41
|
|
|
32
|
-
// ensure FAST global - duplicated
|
|
42
|
+
// ensure FAST global - duplicated debug.ts
|
|
33
43
|
const propConfig = {
|
|
34
44
|
configurable: false,
|
|
35
45
|
enumerable: false,
|
|
@@ -117,19 +127,6 @@ function createMetadataLocator() {
|
|
|
117
127
|
};
|
|
118
128
|
}
|
|
119
129
|
|
|
120
|
-
/**
|
|
121
|
-
* @internal
|
|
122
|
-
*/
|
|
123
|
-
const isFunction = (object) => typeof object === "function";
|
|
124
|
-
/**
|
|
125
|
-
* @internal
|
|
126
|
-
*/
|
|
127
|
-
const isString = (object) => typeof object === "string";
|
|
128
|
-
/**
|
|
129
|
-
* @internal
|
|
130
|
-
*/
|
|
131
|
-
const noop = () => void 0;
|
|
132
|
-
|
|
133
130
|
/**
|
|
134
131
|
* The default UpdateQueue.
|
|
135
132
|
* @public
|
|
@@ -196,6 +193,456 @@ const Updates = FAST.getById(1 /* KernelServiceId.updateQueue */, () => {
|
|
|
196
193
|
});
|
|
197
194
|
});
|
|
198
195
|
|
|
196
|
+
/**
|
|
197
|
+
* The type of HTML aspect to target.
|
|
198
|
+
* @public
|
|
199
|
+
*/
|
|
200
|
+
const DOMAspect = Object.freeze({
|
|
201
|
+
/**
|
|
202
|
+
* Not aspected.
|
|
203
|
+
*/
|
|
204
|
+
none: 0,
|
|
205
|
+
/**
|
|
206
|
+
* An attribute.
|
|
207
|
+
*/
|
|
208
|
+
attribute: 1,
|
|
209
|
+
/**
|
|
210
|
+
* A boolean attribute.
|
|
211
|
+
*/
|
|
212
|
+
booleanAttribute: 2,
|
|
213
|
+
/**
|
|
214
|
+
* A property.
|
|
215
|
+
*/
|
|
216
|
+
property: 3,
|
|
217
|
+
/**
|
|
218
|
+
* Content
|
|
219
|
+
*/
|
|
220
|
+
content: 4,
|
|
221
|
+
/**
|
|
222
|
+
* A token list.
|
|
223
|
+
*/
|
|
224
|
+
tokenList: 5,
|
|
225
|
+
/**
|
|
226
|
+
* An event.
|
|
227
|
+
*/
|
|
228
|
+
event: 6,
|
|
229
|
+
});
|
|
230
|
+
const createHTML$1 = html => html;
|
|
231
|
+
const fastTrustedType = globalThis.trustedTypes
|
|
232
|
+
? globalThis.trustedTypes.createPolicy("fast-html", { createHTML: createHTML$1 })
|
|
233
|
+
: { createHTML: createHTML$1 };
|
|
234
|
+
let defaultPolicy = Object.freeze({
|
|
235
|
+
createHTML(value) {
|
|
236
|
+
return fastTrustedType.createHTML(value);
|
|
237
|
+
},
|
|
238
|
+
protect(tagName, aspect, aspectName, sink) {
|
|
239
|
+
return sink;
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
const fastPolicy = defaultPolicy;
|
|
243
|
+
/**
|
|
244
|
+
* Common DOM APIs.
|
|
245
|
+
* @public
|
|
246
|
+
*/
|
|
247
|
+
const DOM = Object.freeze({
|
|
248
|
+
/**
|
|
249
|
+
* @deprecated
|
|
250
|
+
* Use Updates.enqueue().
|
|
251
|
+
*/
|
|
252
|
+
queueUpdate: Updates.enqueue,
|
|
253
|
+
/**
|
|
254
|
+
* @deprecated
|
|
255
|
+
* Use Updates.next()
|
|
256
|
+
*/
|
|
257
|
+
nextUpdate: Updates.next,
|
|
258
|
+
/**
|
|
259
|
+
* @deprecated
|
|
260
|
+
* Use Updates.process()
|
|
261
|
+
*/
|
|
262
|
+
processUpdates: Updates.process,
|
|
263
|
+
/**
|
|
264
|
+
* Gets the dom policy used by the templating system.
|
|
265
|
+
*/
|
|
266
|
+
get policy() {
|
|
267
|
+
return defaultPolicy;
|
|
268
|
+
},
|
|
269
|
+
/**
|
|
270
|
+
* Sets the dom policy used by the templating system.
|
|
271
|
+
* @param policy - The policy to set.
|
|
272
|
+
* @remarks
|
|
273
|
+
* This API can only be called once, for security reasons. It should be
|
|
274
|
+
* called by the application developer at the start of their program.
|
|
275
|
+
*/
|
|
276
|
+
setPolicy(value) {
|
|
277
|
+
if (defaultPolicy !== fastPolicy) {
|
|
278
|
+
throw FAST.error(1201 /* Message.onlySetDOMPolicyOnce */);
|
|
279
|
+
}
|
|
280
|
+
defaultPolicy = value;
|
|
281
|
+
},
|
|
282
|
+
/**
|
|
283
|
+
* Sets an attribute value on an element.
|
|
284
|
+
* @param element - The element to set the attribute value on.
|
|
285
|
+
* @param attributeName - The attribute name to set.
|
|
286
|
+
* @param value - The value of the attribute to set.
|
|
287
|
+
* @remarks
|
|
288
|
+
* If the value is `null` or `undefined`, the attribute is removed, otherwise
|
|
289
|
+
* it is set to the provided value using the standard `setAttribute` API.
|
|
290
|
+
*/
|
|
291
|
+
setAttribute(element, attributeName, value) {
|
|
292
|
+
value === null || value === undefined
|
|
293
|
+
? element.removeAttribute(attributeName)
|
|
294
|
+
: element.setAttribute(attributeName, value);
|
|
295
|
+
},
|
|
296
|
+
/**
|
|
297
|
+
* Sets a boolean attribute value.
|
|
298
|
+
* @param element - The element to set the boolean attribute value on.
|
|
299
|
+
* @param attributeName - The attribute name to set.
|
|
300
|
+
* @param value - The value of the attribute to set.
|
|
301
|
+
* @remarks
|
|
302
|
+
* If the value is true, the attribute is added; otherwise it is removed.
|
|
303
|
+
*/
|
|
304
|
+
setBooleanAttribute(element, attributeName, value) {
|
|
305
|
+
value
|
|
306
|
+
? element.setAttribute(attributeName, "")
|
|
307
|
+
: element.removeAttribute(attributeName);
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
function safeURL(tagName, aspect, aspectName, sink) {
|
|
312
|
+
return (target, name, value, ...rest) => {
|
|
313
|
+
if (isString(value)) {
|
|
314
|
+
value = value.replace("javascript:", "");
|
|
315
|
+
}
|
|
316
|
+
sink(target, name, value, ...rest);
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function block(tagName, aspect, aspectName, sink) {
|
|
320
|
+
throw new Error(`${aspectName} on ${tagName !== null && tagName !== void 0 ? tagName : "text"} is blocked by the current DOMPolicy.`);
|
|
321
|
+
}
|
|
322
|
+
const defaultDOMElementGuards = {
|
|
323
|
+
a: {
|
|
324
|
+
[DOMAspect.attribute]: {
|
|
325
|
+
href: safeURL,
|
|
326
|
+
},
|
|
327
|
+
[DOMAspect.property]: {
|
|
328
|
+
href: safeURL,
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
area: {
|
|
332
|
+
[DOMAspect.attribute]: {
|
|
333
|
+
href: safeURL,
|
|
334
|
+
},
|
|
335
|
+
[DOMAspect.property]: {
|
|
336
|
+
href: safeURL,
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
button: {
|
|
340
|
+
[DOMAspect.attribute]: {
|
|
341
|
+
formaction: safeURL,
|
|
342
|
+
},
|
|
343
|
+
[DOMAspect.property]: {
|
|
344
|
+
formAction: safeURL,
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
embed: {
|
|
348
|
+
[DOMAspect.attribute]: {
|
|
349
|
+
src: block,
|
|
350
|
+
},
|
|
351
|
+
[DOMAspect.property]: {
|
|
352
|
+
src: block,
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
form: {
|
|
356
|
+
[DOMAspect.attribute]: {
|
|
357
|
+
action: safeURL,
|
|
358
|
+
},
|
|
359
|
+
[DOMAspect.property]: {
|
|
360
|
+
action: safeURL,
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
frame: {
|
|
364
|
+
[DOMAspect.attribute]: {
|
|
365
|
+
src: safeURL,
|
|
366
|
+
},
|
|
367
|
+
[DOMAspect.property]: {
|
|
368
|
+
src: safeURL,
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
iframe: {
|
|
372
|
+
[DOMAspect.attribute]: {
|
|
373
|
+
src: safeURL,
|
|
374
|
+
},
|
|
375
|
+
[DOMAspect.property]: {
|
|
376
|
+
src: safeURL,
|
|
377
|
+
srcdoc: block,
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
input: {
|
|
381
|
+
[DOMAspect.attribute]: {
|
|
382
|
+
formaction: safeURL,
|
|
383
|
+
},
|
|
384
|
+
[DOMAspect.property]: {
|
|
385
|
+
formAction: safeURL,
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
link: {
|
|
389
|
+
[DOMAspect.attribute]: {
|
|
390
|
+
href: block,
|
|
391
|
+
},
|
|
392
|
+
[DOMAspect.property]: {
|
|
393
|
+
href: block,
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
object: {
|
|
397
|
+
[DOMAspect.attribute]: {
|
|
398
|
+
codebase: block,
|
|
399
|
+
data: block,
|
|
400
|
+
},
|
|
401
|
+
[DOMAspect.property]: {
|
|
402
|
+
codeBase: block,
|
|
403
|
+
data: block,
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
script: {
|
|
407
|
+
[DOMAspect.attribute]: {
|
|
408
|
+
src: block,
|
|
409
|
+
text: block,
|
|
410
|
+
},
|
|
411
|
+
[DOMAspect.property]: {
|
|
412
|
+
src: block,
|
|
413
|
+
text: block,
|
|
414
|
+
innerText: block,
|
|
415
|
+
textContent: block,
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
style: {
|
|
419
|
+
[DOMAspect.property]: {
|
|
420
|
+
innerText: block,
|
|
421
|
+
textContent: block,
|
|
422
|
+
},
|
|
423
|
+
},
|
|
424
|
+
};
|
|
425
|
+
const blockedEvents = {
|
|
426
|
+
onabort: block,
|
|
427
|
+
onauxclick: block,
|
|
428
|
+
onbeforeinput: block,
|
|
429
|
+
onbeforematch: block,
|
|
430
|
+
onblur: block,
|
|
431
|
+
oncancel: block,
|
|
432
|
+
oncanplay: block,
|
|
433
|
+
oncanplaythrough: block,
|
|
434
|
+
onchange: block,
|
|
435
|
+
onclick: block,
|
|
436
|
+
onclose: block,
|
|
437
|
+
oncontextlost: block,
|
|
438
|
+
oncontextmenu: block,
|
|
439
|
+
oncontextrestored: block,
|
|
440
|
+
oncopy: block,
|
|
441
|
+
oncuechange: block,
|
|
442
|
+
oncut: block,
|
|
443
|
+
ondblclick: block,
|
|
444
|
+
ondrag: block,
|
|
445
|
+
ondragend: block,
|
|
446
|
+
ondragenter: block,
|
|
447
|
+
ondragleave: block,
|
|
448
|
+
ondragover: block,
|
|
449
|
+
ondragstart: block,
|
|
450
|
+
ondrop: block,
|
|
451
|
+
ondurationchange: block,
|
|
452
|
+
onemptied: block,
|
|
453
|
+
onended: block,
|
|
454
|
+
onerror: block,
|
|
455
|
+
onfocus: block,
|
|
456
|
+
onformdata: block,
|
|
457
|
+
oninput: block,
|
|
458
|
+
oninvalid: block,
|
|
459
|
+
onkeydown: block,
|
|
460
|
+
onkeypress: block,
|
|
461
|
+
onkeyup: block,
|
|
462
|
+
onload: block,
|
|
463
|
+
onloadeddata: block,
|
|
464
|
+
onloadedmetadata: block,
|
|
465
|
+
onloadstart: block,
|
|
466
|
+
onmousedown: block,
|
|
467
|
+
onmouseenter: block,
|
|
468
|
+
onmouseleave: block,
|
|
469
|
+
onmousemove: block,
|
|
470
|
+
onmouseout: block,
|
|
471
|
+
onmouseover: block,
|
|
472
|
+
onmouseup: block,
|
|
473
|
+
onpaste: block,
|
|
474
|
+
onpause: block,
|
|
475
|
+
onplay: block,
|
|
476
|
+
onplaying: block,
|
|
477
|
+
onprogress: block,
|
|
478
|
+
onratechange: block,
|
|
479
|
+
onreset: block,
|
|
480
|
+
onresize: block,
|
|
481
|
+
onscroll: block,
|
|
482
|
+
onsecuritypolicyviolation: block,
|
|
483
|
+
onseeked: block,
|
|
484
|
+
onseeking: block,
|
|
485
|
+
onselect: block,
|
|
486
|
+
onslotchange: block,
|
|
487
|
+
onstalled: block,
|
|
488
|
+
onsubmit: block,
|
|
489
|
+
onsuspend: block,
|
|
490
|
+
ontimeupdate: block,
|
|
491
|
+
ontoggle: block,
|
|
492
|
+
onvolumechange: block,
|
|
493
|
+
onwaiting: block,
|
|
494
|
+
onwebkitanimationend: block,
|
|
495
|
+
onwebkitanimationiteration: block,
|
|
496
|
+
onwebkitanimationstart: block,
|
|
497
|
+
onwebkittransitionend: block,
|
|
498
|
+
onwheel: block,
|
|
499
|
+
};
|
|
500
|
+
const defaultDOMGuards = {
|
|
501
|
+
elements: defaultDOMElementGuards,
|
|
502
|
+
aspects: {
|
|
503
|
+
[DOMAspect.attribute]: Object.assign({}, blockedEvents),
|
|
504
|
+
[DOMAspect.property]: Object.assign({ innerHTML: block }, blockedEvents),
|
|
505
|
+
[DOMAspect.event]: Object.assign({}, blockedEvents),
|
|
506
|
+
},
|
|
507
|
+
};
|
|
508
|
+
function createDomSinkGuards(config, defaults) {
|
|
509
|
+
const result = {};
|
|
510
|
+
for (const name in defaults) {
|
|
511
|
+
const overrideValue = config[name];
|
|
512
|
+
const defaultValue = defaults[name];
|
|
513
|
+
switch (overrideValue) {
|
|
514
|
+
case null:
|
|
515
|
+
// remove the default
|
|
516
|
+
break;
|
|
517
|
+
case undefined:
|
|
518
|
+
// keep the default
|
|
519
|
+
result[name] = defaultValue;
|
|
520
|
+
break;
|
|
521
|
+
default:
|
|
522
|
+
// override the default
|
|
523
|
+
result[name] = overrideValue;
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
// add any new sinks that were not overrides
|
|
528
|
+
for (const name in config) {
|
|
529
|
+
if (!(name in result)) {
|
|
530
|
+
result[name] = config[name];
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return Object.freeze(result);
|
|
534
|
+
}
|
|
535
|
+
function createDOMAspectGuards(config, defaults) {
|
|
536
|
+
const result = {};
|
|
537
|
+
for (const aspect in defaults) {
|
|
538
|
+
const overrideValue = config[aspect];
|
|
539
|
+
const defaultValue = defaults[aspect];
|
|
540
|
+
switch (overrideValue) {
|
|
541
|
+
case null:
|
|
542
|
+
// remove the default
|
|
543
|
+
break;
|
|
544
|
+
case undefined:
|
|
545
|
+
// keep the default
|
|
546
|
+
result[aspect] = createDomSinkGuards(defaultValue, {});
|
|
547
|
+
break;
|
|
548
|
+
default:
|
|
549
|
+
// override the default
|
|
550
|
+
result[aspect] = createDomSinkGuards(overrideValue, defaultValue);
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
// add any new aspect guards that were not overrides
|
|
555
|
+
for (const aspect in config) {
|
|
556
|
+
if (!(aspect in result)) {
|
|
557
|
+
result[aspect] = createDomSinkGuards(config[aspect], {});
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return Object.freeze(result);
|
|
561
|
+
}
|
|
562
|
+
function createElementGuards(config, defaults) {
|
|
563
|
+
const result = {};
|
|
564
|
+
for (const tag in defaults) {
|
|
565
|
+
const overrideValue = config[tag];
|
|
566
|
+
const defaultValue = defaults[tag];
|
|
567
|
+
switch (overrideValue) {
|
|
568
|
+
case null:
|
|
569
|
+
// remove the default
|
|
570
|
+
break;
|
|
571
|
+
case undefined:
|
|
572
|
+
// keep the default
|
|
573
|
+
result[tag] = createDOMAspectGuards(overrideValue, {});
|
|
574
|
+
break;
|
|
575
|
+
default:
|
|
576
|
+
// override the default aspects
|
|
577
|
+
result[tag] = createDOMAspectGuards(overrideValue, defaultValue);
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
// Add any new element guards that were not overrides
|
|
582
|
+
for (const tag in config) {
|
|
583
|
+
if (!(tag in result)) {
|
|
584
|
+
result[tag] = createDOMAspectGuards(config[tag], {});
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
return Object.freeze(result);
|
|
588
|
+
}
|
|
589
|
+
function createDOMGuards(config, defaults) {
|
|
590
|
+
return Object.freeze({
|
|
591
|
+
elements: config.elements
|
|
592
|
+
? createElementGuards(config.elements, defaults.elements)
|
|
593
|
+
: defaults.elements,
|
|
594
|
+
aspects: config.aspects
|
|
595
|
+
? createDOMAspectGuards(config.aspects, defaults.aspects)
|
|
596
|
+
: defaults.aspects,
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
function createTrustedType() {
|
|
600
|
+
const createHTML = html => html;
|
|
601
|
+
return globalThis.trustedTypes
|
|
602
|
+
? globalThis.trustedTypes.createPolicy("fast-html", { createHTML })
|
|
603
|
+
: { createHTML };
|
|
604
|
+
}
|
|
605
|
+
function tryGuard(aspectGuards, tagName, aspect, aspectName, sink) {
|
|
606
|
+
const sinkGuards = aspectGuards[aspect];
|
|
607
|
+
if (sinkGuards) {
|
|
608
|
+
const guard = sinkGuards[aspectName];
|
|
609
|
+
if (guard) {
|
|
610
|
+
return guard(tagName, aspect, aspectName, sink);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
const DOMPolicy = Object.freeze({
|
|
615
|
+
/**
|
|
616
|
+
* Creates a new DOM Policy object.
|
|
617
|
+
* @param options The options to use in creating the policy.
|
|
618
|
+
* @returns The newly created DOMPolicy.
|
|
619
|
+
*/
|
|
620
|
+
create(options = {}) {
|
|
621
|
+
var _a, _b;
|
|
622
|
+
const trustedType = (_a = options.trustedType) !== null && _a !== void 0 ? _a : createTrustedType();
|
|
623
|
+
const guards = createDOMGuards((_b = options.guards) !== null && _b !== void 0 ? _b : {}, defaultDOMGuards);
|
|
624
|
+
return Object.freeze({
|
|
625
|
+
createHTML(value) {
|
|
626
|
+
return trustedType.createHTML(value);
|
|
627
|
+
},
|
|
628
|
+
protect(tagName, aspect, aspectName, sink) {
|
|
629
|
+
var _a;
|
|
630
|
+
// Check for element-specific guards.
|
|
631
|
+
const key = (tagName !== null && tagName !== void 0 ? tagName : "").toLowerCase();
|
|
632
|
+
const elementGuards = guards.elements[key];
|
|
633
|
+
if (elementGuards) {
|
|
634
|
+
const guard = tryGuard(elementGuards, tagName, aspect, aspectName, sink);
|
|
635
|
+
if (guard) {
|
|
636
|
+
return guard;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
// Check for guards applicable to all nodes.
|
|
640
|
+
return ((_a = tryGuard(guards.aspects, tagName, aspect, aspectName, sink)) !== null && _a !== void 0 ? _a : sink);
|
|
641
|
+
},
|
|
642
|
+
});
|
|
643
|
+
},
|
|
644
|
+
});
|
|
645
|
+
|
|
199
646
|
/**
|
|
200
647
|
* An implementation of {@link Notifier} that efficiently keeps track of
|
|
201
648
|
* subscribers interested in a specific change notification on an
|
|
@@ -1482,55 +1929,6 @@ css.partial = (strings, ...values) => {
|
|
|
1482
1929
|
*/
|
|
1483
1930
|
const cssPartial = css.partial;
|
|
1484
1931
|
|
|
1485
|
-
/**
|
|
1486
|
-
* Common DOM APIs.
|
|
1487
|
-
* @public
|
|
1488
|
-
*/
|
|
1489
|
-
const DOM = Object.freeze({
|
|
1490
|
-
/**
|
|
1491
|
-
* @deprecated
|
|
1492
|
-
* Use Updates.enqueue().
|
|
1493
|
-
*/
|
|
1494
|
-
queueUpdate: Updates.enqueue,
|
|
1495
|
-
/**
|
|
1496
|
-
* @deprecated
|
|
1497
|
-
* Use Updates.next()
|
|
1498
|
-
*/
|
|
1499
|
-
nextUpdate: Updates.next,
|
|
1500
|
-
/**
|
|
1501
|
-
* @deprecated
|
|
1502
|
-
* Use Updates.process()
|
|
1503
|
-
*/
|
|
1504
|
-
processUpdates: Updates.process,
|
|
1505
|
-
/**
|
|
1506
|
-
* Sets an attribute value on an element.
|
|
1507
|
-
* @param element - The element to set the attribute value on.
|
|
1508
|
-
* @param attributeName - The attribute name to set.
|
|
1509
|
-
* @param value - The value of the attribute to set.
|
|
1510
|
-
* @remarks
|
|
1511
|
-
* If the value is `null` or `undefined`, the attribute is removed, otherwise
|
|
1512
|
-
* it is set to the provided value using the standard `setAttribute` API.
|
|
1513
|
-
*/
|
|
1514
|
-
setAttribute(element, attributeName, value) {
|
|
1515
|
-
value === null || value === undefined
|
|
1516
|
-
? element.removeAttribute(attributeName)
|
|
1517
|
-
: element.setAttribute(attributeName, value);
|
|
1518
|
-
},
|
|
1519
|
-
/**
|
|
1520
|
-
* Sets a boolean attribute value.
|
|
1521
|
-
* @param element - The element to set the boolean attribute value on.
|
|
1522
|
-
* @param attributeName - The attribute name to set.
|
|
1523
|
-
* @param value - The value of the attribute to set.
|
|
1524
|
-
* @remarks
|
|
1525
|
-
* If the value is true, the attribute is added; otherwise it is removed.
|
|
1526
|
-
*/
|
|
1527
|
-
setBooleanAttribute(element, attributeName, value) {
|
|
1528
|
-
value
|
|
1529
|
-
? element.setAttribute(attributeName, "")
|
|
1530
|
-
: element.removeAttribute(attributeName);
|
|
1531
|
-
},
|
|
1532
|
-
});
|
|
1533
|
-
|
|
1534
1932
|
const marker = `fast-${Math.random().toString(36).substring(2, 8)}`;
|
|
1535
1933
|
const interpolationStart = `${marker}{`;
|
|
1536
1934
|
const interpolationEnd = `}${marker}`;
|
|
@@ -1607,67 +2005,6 @@ const Parser = Object.freeze({
|
|
|
1607
2005
|
},
|
|
1608
2006
|
});
|
|
1609
2007
|
|
|
1610
|
-
/**
|
|
1611
|
-
* Bridges between ViewBehaviors and HostBehaviors, enabling a host to
|
|
1612
|
-
* control ViewBehaviors.
|
|
1613
|
-
* @public
|
|
1614
|
-
*/
|
|
1615
|
-
const ViewBehaviorOrchestrator = Object.freeze({
|
|
1616
|
-
/**
|
|
1617
|
-
* Creates a ViewBehaviorOrchestrator.
|
|
1618
|
-
* @param source - The source to to associate behaviors with.
|
|
1619
|
-
* @returns A ViewBehaviorOrchestrator.
|
|
1620
|
-
*/
|
|
1621
|
-
create(source) {
|
|
1622
|
-
const behaviors = [];
|
|
1623
|
-
const targets = {};
|
|
1624
|
-
let unbindables = null;
|
|
1625
|
-
let isConnected = false;
|
|
1626
|
-
return {
|
|
1627
|
-
source,
|
|
1628
|
-
context: ExecutionContext.default,
|
|
1629
|
-
targets,
|
|
1630
|
-
get isBound() {
|
|
1631
|
-
return isConnected;
|
|
1632
|
-
},
|
|
1633
|
-
addBehaviorFactory(factory, target) {
|
|
1634
|
-
const nodeId = factory.nodeId || (factory.nodeId = nextId());
|
|
1635
|
-
factory.id || (factory.id = nextId());
|
|
1636
|
-
this.addTarget(nodeId, target);
|
|
1637
|
-
this.addBehavior(factory.createBehavior());
|
|
1638
|
-
},
|
|
1639
|
-
addTarget(nodeId, target) {
|
|
1640
|
-
targets[nodeId] = target;
|
|
1641
|
-
},
|
|
1642
|
-
addBehavior(behavior) {
|
|
1643
|
-
behaviors.push(behavior);
|
|
1644
|
-
if (isConnected) {
|
|
1645
|
-
behavior.bind(this);
|
|
1646
|
-
}
|
|
1647
|
-
},
|
|
1648
|
-
onUnbind(unbindable) {
|
|
1649
|
-
if (unbindables === null) {
|
|
1650
|
-
unbindables = [];
|
|
1651
|
-
}
|
|
1652
|
-
unbindables.push(unbindable);
|
|
1653
|
-
},
|
|
1654
|
-
connectedCallback(controller) {
|
|
1655
|
-
if (!isConnected) {
|
|
1656
|
-
isConnected = true;
|
|
1657
|
-
behaviors.forEach(x => x.bind(this));
|
|
1658
|
-
}
|
|
1659
|
-
},
|
|
1660
|
-
disconnectedCallback(controller) {
|
|
1661
|
-
if (isConnected) {
|
|
1662
|
-
isConnected = false;
|
|
1663
|
-
if (unbindables !== null) {
|
|
1664
|
-
unbindables.forEach(x => x.unbind(this));
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
},
|
|
1668
|
-
};
|
|
1669
|
-
},
|
|
1670
|
-
});
|
|
1671
2008
|
const registry = createTypeRegistry();
|
|
1672
2009
|
/**
|
|
1673
2010
|
* Instructs the template engine to apply behavior to a node.
|
|
@@ -1695,67 +2032,6 @@ const HTMLDirective = Object.freeze({
|
|
|
1695
2032
|
registry.register(options);
|
|
1696
2033
|
return type;
|
|
1697
2034
|
},
|
|
1698
|
-
});
|
|
1699
|
-
/**
|
|
1700
|
-
* Decorator: Defines an HTMLDirective.
|
|
1701
|
-
* @param options - Provides options that specify the directive's application.
|
|
1702
|
-
* @public
|
|
1703
|
-
*/
|
|
1704
|
-
function htmlDirective(options) {
|
|
1705
|
-
/* eslint-disable-next-line @typescript-eslint/explicit-function-return-type */
|
|
1706
|
-
return function (type) {
|
|
1707
|
-
HTMLDirective.define(type, options);
|
|
1708
|
-
};
|
|
1709
|
-
}
|
|
1710
|
-
/**
|
|
1711
|
-
* Captures a binding expression along with related information and capabilities.
|
|
1712
|
-
*
|
|
1713
|
-
* @public
|
|
1714
|
-
*/
|
|
1715
|
-
class Binding {
|
|
1716
|
-
/**
|
|
1717
|
-
* Creates a binding.
|
|
1718
|
-
* @param evaluate - Evaluates the binding.
|
|
1719
|
-
* @param isVolatile - Indicates whether the binding is volatile.
|
|
1720
|
-
*/
|
|
1721
|
-
constructor(evaluate, isVolatile = false) {
|
|
1722
|
-
this.evaluate = evaluate;
|
|
1723
|
-
this.isVolatile = isVolatile;
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
/**
|
|
1727
|
-
* The type of HTML aspect to target.
|
|
1728
|
-
* @public
|
|
1729
|
-
*/
|
|
1730
|
-
const Aspect = Object.freeze({
|
|
1731
|
-
/**
|
|
1732
|
-
* Not aspected.
|
|
1733
|
-
*/
|
|
1734
|
-
none: 0,
|
|
1735
|
-
/**
|
|
1736
|
-
* An attribute.
|
|
1737
|
-
*/
|
|
1738
|
-
attribute: 1,
|
|
1739
|
-
/**
|
|
1740
|
-
* A boolean attribute.
|
|
1741
|
-
*/
|
|
1742
|
-
booleanAttribute: 2,
|
|
1743
|
-
/**
|
|
1744
|
-
* A property.
|
|
1745
|
-
*/
|
|
1746
|
-
property: 3,
|
|
1747
|
-
/**
|
|
1748
|
-
* Content
|
|
1749
|
-
*/
|
|
1750
|
-
content: 4,
|
|
1751
|
-
/**
|
|
1752
|
-
* A token list.
|
|
1753
|
-
*/
|
|
1754
|
-
tokenList: 5,
|
|
1755
|
-
/**
|
|
1756
|
-
* An event.
|
|
1757
|
-
*/
|
|
1758
|
-
event: 6,
|
|
1759
2035
|
/**
|
|
1760
2036
|
*
|
|
1761
2037
|
* @param directive - The directive to assign the aspect to.
|
|
@@ -1763,9 +2039,9 @@ const Aspect = Object.freeze({
|
|
|
1763
2039
|
* @remarks
|
|
1764
2040
|
* If a falsy value is provided, then the content aspect will be assigned.
|
|
1765
2041
|
*/
|
|
1766
|
-
|
|
2042
|
+
assignAspect(directive, value) {
|
|
1767
2043
|
if (!value) {
|
|
1768
|
-
directive.aspectType =
|
|
2044
|
+
directive.aspectType = DOMAspect.content;
|
|
1769
2045
|
return;
|
|
1770
2046
|
}
|
|
1771
2047
|
directive.sourceAspect = value;
|
|
@@ -1774,24 +2050,53 @@ const Aspect = Object.freeze({
|
|
|
1774
2050
|
directive.targetAspect = value.substring(1);
|
|
1775
2051
|
directive.aspectType =
|
|
1776
2052
|
directive.targetAspect === "classList"
|
|
1777
|
-
?
|
|
1778
|
-
:
|
|
2053
|
+
? DOMAspect.tokenList
|
|
2054
|
+
: DOMAspect.property;
|
|
1779
2055
|
break;
|
|
1780
2056
|
case "?":
|
|
1781
2057
|
directive.targetAspect = value.substring(1);
|
|
1782
|
-
directive.aspectType =
|
|
2058
|
+
directive.aspectType = DOMAspect.booleanAttribute;
|
|
1783
2059
|
break;
|
|
1784
2060
|
case "@":
|
|
1785
2061
|
directive.targetAspect = value.substring(1);
|
|
1786
|
-
directive.aspectType =
|
|
2062
|
+
directive.aspectType = DOMAspect.event;
|
|
1787
2063
|
break;
|
|
1788
2064
|
default:
|
|
1789
2065
|
directive.targetAspect = value;
|
|
1790
|
-
directive.aspectType =
|
|
2066
|
+
directive.aspectType = DOMAspect.attribute;
|
|
1791
2067
|
break;
|
|
1792
2068
|
}
|
|
1793
2069
|
},
|
|
1794
2070
|
});
|
|
2071
|
+
/**
|
|
2072
|
+
* Decorator: Defines an HTMLDirective.
|
|
2073
|
+
* @param options - Provides options that specify the directive's application.
|
|
2074
|
+
* @public
|
|
2075
|
+
*/
|
|
2076
|
+
function htmlDirective(options) {
|
|
2077
|
+
/* eslint-disable-next-line @typescript-eslint/explicit-function-return-type */
|
|
2078
|
+
return function (type) {
|
|
2079
|
+
HTMLDirective.define(type, options);
|
|
2080
|
+
};
|
|
2081
|
+
}
|
|
2082
|
+
/**
|
|
2083
|
+
* Captures a binding expression along with related information and capabilities.
|
|
2084
|
+
*
|
|
2085
|
+
* @public
|
|
2086
|
+
*/
|
|
2087
|
+
class Binding {
|
|
2088
|
+
/**
|
|
2089
|
+
* Creates a binding.
|
|
2090
|
+
* @param evaluate - Evaluates the binding.
|
|
2091
|
+
* @param policy - The security policy to associate with this binding.
|
|
2092
|
+
* @param isVolatile - Indicates whether the binding is volatile.
|
|
2093
|
+
*/
|
|
2094
|
+
constructor(evaluate, policy, isVolatile = false) {
|
|
2095
|
+
this.evaluate = evaluate;
|
|
2096
|
+
this.policy = policy;
|
|
2097
|
+
this.isVolatile = isVolatile;
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
1795
2100
|
/**
|
|
1796
2101
|
* A base class used for attribute directives that don't need internal state.
|
|
1797
2102
|
* @public
|
|
@@ -1803,10 +2108,6 @@ class StatelessAttachedAttributeDirective {
|
|
|
1803
2108
|
*/
|
|
1804
2109
|
constructor(options) {
|
|
1805
2110
|
this.options = options;
|
|
1806
|
-
/**
|
|
1807
|
-
* The unique id of the factory.
|
|
1808
|
-
*/
|
|
1809
|
-
this.id = nextId();
|
|
1810
2111
|
/**
|
|
1811
2112
|
* Opts out of JSON stringification.
|
|
1812
2113
|
* @internal
|
|
@@ -1831,15 +2132,6 @@ class StatelessAttachedAttributeDirective {
|
|
|
1831
2132
|
}
|
|
1832
2133
|
}
|
|
1833
2134
|
|
|
1834
|
-
const createInnerHTMLBinding = globalThis.TrustedHTML
|
|
1835
|
-
? (binding) => (s, c) => {
|
|
1836
|
-
const value = binding(s, c);
|
|
1837
|
-
if (value instanceof TrustedHTML) {
|
|
1838
|
-
return value;
|
|
1839
|
-
}
|
|
1840
|
-
throw FAST.error(1202 /* Message.bindingInnerHTMLRequiresTrustedTypes */);
|
|
1841
|
-
}
|
|
1842
|
-
: (binding) => binding;
|
|
1843
2135
|
class OnChangeBinding extends Binding {
|
|
1844
2136
|
createObserver(_, subscriber) {
|
|
1845
2137
|
return Observable.binding(this.evaluate, subscriber, this.isVolatile);
|
|
@@ -1952,8 +2244,14 @@ function updateTokenList(target, aspect, value) {
|
|
|
1952
2244
|
}
|
|
1953
2245
|
}
|
|
1954
2246
|
}
|
|
1955
|
-
const
|
|
1956
|
-
|
|
2247
|
+
const sinkLookup = {
|
|
2248
|
+
[DOMAspect.attribute]: DOM.setAttribute,
|
|
2249
|
+
[DOMAspect.booleanAttribute]: DOM.setBooleanAttribute,
|
|
2250
|
+
[DOMAspect.property]: (t, a, v) => (t[a] = v),
|
|
2251
|
+
[DOMAspect.content]: updateContent,
|
|
2252
|
+
[DOMAspect.tokenList]: updateTokenList,
|
|
2253
|
+
[DOMAspect.event]: () => void 0,
|
|
2254
|
+
};
|
|
1957
2255
|
/**
|
|
1958
2256
|
* A directive that applies bindings.
|
|
1959
2257
|
* @public
|
|
@@ -1966,15 +2264,10 @@ class HTMLBindingDirective {
|
|
|
1966
2264
|
constructor(dataBinding) {
|
|
1967
2265
|
this.dataBinding = dataBinding;
|
|
1968
2266
|
this.updateTarget = null;
|
|
1969
|
-
/**
|
|
1970
|
-
* The unique id of the factory.
|
|
1971
|
-
*/
|
|
1972
|
-
this.id = nextId();
|
|
1973
2267
|
/**
|
|
1974
2268
|
* The type of aspect to target.
|
|
1975
2269
|
*/
|
|
1976
|
-
this.aspectType =
|
|
1977
|
-
this.data = `${this.id}-d`;
|
|
2270
|
+
this.aspectType = DOMAspect.content;
|
|
1978
2271
|
}
|
|
1979
2272
|
/**
|
|
1980
2273
|
* Creates HTML to be used within a template.
|
|
@@ -1987,45 +2280,28 @@ class HTMLBindingDirective {
|
|
|
1987
2280
|
* Creates a behavior.
|
|
1988
2281
|
*/
|
|
1989
2282
|
createBehavior() {
|
|
2283
|
+
var _a;
|
|
1990
2284
|
if (this.updateTarget === null) {
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
case 1:
|
|
1996
|
-
this.updateTarget = DOM.setAttribute;
|
|
1997
|
-
break;
|
|
1998
|
-
case 2:
|
|
1999
|
-
this.updateTarget = DOM.setBooleanAttribute;
|
|
2000
|
-
break;
|
|
2001
|
-
case 3:
|
|
2002
|
-
this.updateTarget = setProperty;
|
|
2003
|
-
break;
|
|
2004
|
-
case 4:
|
|
2005
|
-
this.updateTarget = updateContent;
|
|
2006
|
-
break;
|
|
2007
|
-
case 5:
|
|
2008
|
-
this.updateTarget = updateTokenList;
|
|
2009
|
-
break;
|
|
2010
|
-
case 6:
|
|
2011
|
-
this.updateTarget = eventTarget;
|
|
2012
|
-
break;
|
|
2013
|
-
default:
|
|
2014
|
-
throw FAST.error(1205 /* Message.unsupportedBindingBehavior */);
|
|
2285
|
+
const sink = sinkLookup[this.aspectType];
|
|
2286
|
+
const policy = (_a = this.dataBinding.policy) !== null && _a !== void 0 ? _a : this.policy;
|
|
2287
|
+
if (!sink) {
|
|
2288
|
+
throw FAST.error(1205 /* Message.unsupportedBindingBehavior */);
|
|
2015
2289
|
}
|
|
2290
|
+
this.data = `${this.id}-d`;
|
|
2291
|
+
this.updateTarget = policy.protect(this.targetTagName, this.aspectType, this.targetAspect, sink);
|
|
2016
2292
|
}
|
|
2017
2293
|
return this;
|
|
2018
2294
|
}
|
|
2019
2295
|
/** @internal */
|
|
2020
2296
|
bind(controller) {
|
|
2021
2297
|
var _a;
|
|
2022
|
-
const target = controller.targets[this.
|
|
2023
|
-
switch (this.
|
|
2024
|
-
case
|
|
2298
|
+
const target = controller.targets[this.targetNodeId];
|
|
2299
|
+
switch (this.aspectType) {
|
|
2300
|
+
case DOMAspect.event:
|
|
2025
2301
|
target[this.data] = controller;
|
|
2026
2302
|
target.addEventListener(this.targetAspect, this, this.dataBinding.options);
|
|
2027
2303
|
break;
|
|
2028
|
-
case
|
|
2304
|
+
case DOMAspect.content:
|
|
2029
2305
|
controller.onUnbind(this);
|
|
2030
2306
|
// intentional fall through
|
|
2031
2307
|
default:
|
|
@@ -2038,7 +2314,7 @@ class HTMLBindingDirective {
|
|
|
2038
2314
|
}
|
|
2039
2315
|
/** @internal */
|
|
2040
2316
|
unbind(controller) {
|
|
2041
|
-
const target = controller.targets[this.
|
|
2317
|
+
const target = controller.targets[this.targetNodeId];
|
|
2042
2318
|
const view = target.$fastView;
|
|
2043
2319
|
if (view !== void 0 && view.isComposed) {
|
|
2044
2320
|
view.unbind();
|
|
@@ -2068,21 +2344,23 @@ HTMLDirective.define(HTMLBindingDirective, { aspected: true });
|
|
|
2068
2344
|
/**
|
|
2069
2345
|
* Creates an standard binding.
|
|
2070
2346
|
* @param expression - The binding to refresh when changed.
|
|
2347
|
+
* @param policy - The security policy to associate with th binding.
|
|
2071
2348
|
* @param isVolatile - Indicates whether the binding is volatile or not.
|
|
2072
2349
|
* @returns A binding configuration.
|
|
2073
2350
|
* @public
|
|
2074
2351
|
*/
|
|
2075
|
-
function bind(expression, isVolatile = Observable.isVolatileBinding(expression)) {
|
|
2076
|
-
return new OnChangeBinding(expression, isVolatile);
|
|
2352
|
+
function bind(expression, policy, isVolatile = Observable.isVolatileBinding(expression)) {
|
|
2353
|
+
return new OnChangeBinding(expression, policy, isVolatile);
|
|
2077
2354
|
}
|
|
2078
2355
|
/**
|
|
2079
2356
|
* Creates a one time binding
|
|
2080
2357
|
* @param expression - The binding to refresh when signaled.
|
|
2358
|
+
* @param policy - The security policy to associate with th binding.
|
|
2081
2359
|
* @returns A binding configuration.
|
|
2082
2360
|
* @public
|
|
2083
2361
|
*/
|
|
2084
|
-
function oneTime(expression) {
|
|
2085
|
-
return new OneTimeBinding(expression);
|
|
2362
|
+
function oneTime(expression, policy) {
|
|
2363
|
+
return new OneTimeBinding(expression, policy);
|
|
2086
2364
|
}
|
|
2087
2365
|
/**
|
|
2088
2366
|
* Creates an event listener binding.
|
|
@@ -2092,7 +2370,7 @@ function oneTime(expression) {
|
|
|
2092
2370
|
* @public
|
|
2093
2371
|
*/
|
|
2094
2372
|
function listener(expression, options) {
|
|
2095
|
-
const config = new OnChangeBinding(expression
|
|
2373
|
+
const config = new OnChangeBinding(expression);
|
|
2096
2374
|
config.options = options;
|
|
2097
2375
|
return config;
|
|
2098
2376
|
}
|
|
@@ -2373,20 +2651,25 @@ const warningHost = new Proxy(document.createElement("div"), {
|
|
|
2373
2651
|
},
|
|
2374
2652
|
});
|
|
2375
2653
|
class CompilationContext {
|
|
2376
|
-
constructor(fragment, directives) {
|
|
2654
|
+
constructor(fragment, directives, policy) {
|
|
2377
2655
|
this.fragment = fragment;
|
|
2378
2656
|
this.directives = directives;
|
|
2657
|
+
this.policy = policy;
|
|
2379
2658
|
this.proto = null;
|
|
2380
2659
|
this.nodeIds = new Set();
|
|
2381
2660
|
this.descriptors = {};
|
|
2382
2661
|
this.factories = [];
|
|
2383
2662
|
}
|
|
2384
|
-
addFactory(factory, parentId, nodeId, targetIndex) {
|
|
2663
|
+
addFactory(factory, parentId, nodeId, targetIndex, tagName) {
|
|
2664
|
+
var _a, _b;
|
|
2385
2665
|
if (!this.nodeIds.has(nodeId)) {
|
|
2386
2666
|
this.nodeIds.add(nodeId);
|
|
2387
2667
|
this.addTargetDescriptor(parentId, nodeId, targetIndex);
|
|
2388
2668
|
}
|
|
2389
|
-
factory.
|
|
2669
|
+
factory.id = (_a = factory.id) !== null && _a !== void 0 ? _a : nextId();
|
|
2670
|
+
factory.targetNodeId = nodeId;
|
|
2671
|
+
factory.targetTagName = tagName;
|
|
2672
|
+
factory.policy = (_b = factory.policy) !== null && _b !== void 0 ? _b : this.policy;
|
|
2390
2673
|
this.factories.push(factory);
|
|
2391
2674
|
}
|
|
2392
2675
|
freeze() {
|
|
@@ -2439,19 +2722,19 @@ function compileAttributes(context, parentId, node, nodeId, nodeIndex, includeBa
|
|
|
2439
2722
|
let result = null;
|
|
2440
2723
|
if (parseResult === null) {
|
|
2441
2724
|
if (includeBasicValues) {
|
|
2442
|
-
result = new HTMLBindingDirective(oneTime(() => attrValue));
|
|
2443
|
-
|
|
2725
|
+
result = new HTMLBindingDirective(oneTime(() => attrValue, context.policy));
|
|
2726
|
+
HTMLDirective.assignAspect(result, attr.name);
|
|
2444
2727
|
}
|
|
2445
2728
|
}
|
|
2446
2729
|
else {
|
|
2447
2730
|
/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
|
|
2448
|
-
result = Compiler.aggregate(parseResult);
|
|
2731
|
+
result = Compiler.aggregate(parseResult, context.policy);
|
|
2449
2732
|
}
|
|
2450
2733
|
if (result !== null) {
|
|
2451
2734
|
node.removeAttributeNode(attr);
|
|
2452
2735
|
i--;
|
|
2453
2736
|
ii--;
|
|
2454
|
-
context.addFactory(result, parentId, nodeId, nodeIndex);
|
|
2737
|
+
context.addFactory(result, parentId, nodeId, nodeIndex, node.tagName);
|
|
2455
2738
|
}
|
|
2456
2739
|
}
|
|
2457
2740
|
}
|
|
@@ -2476,8 +2759,8 @@ function compileContent(context, node, parentId, nodeId, nodeIndex) {
|
|
|
2476
2759
|
}
|
|
2477
2760
|
else {
|
|
2478
2761
|
currentNode.textContent = " ";
|
|
2479
|
-
|
|
2480
|
-
context.addFactory(currentPart, parentId, nodeId, nodeIndex);
|
|
2762
|
+
HTMLDirective.assignAspect(currentPart);
|
|
2763
|
+
context.addFactory(currentPart, parentId, nodeId, nodeIndex, null);
|
|
2481
2764
|
}
|
|
2482
2765
|
lastNode = currentNode;
|
|
2483
2766
|
}
|
|
@@ -2509,7 +2792,7 @@ function compileNode(context, parentId, node, nodeIndex) {
|
|
|
2509
2792
|
if (parts !== null) {
|
|
2510
2793
|
context.addFactory(
|
|
2511
2794
|
/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
|
|
2512
|
-
Compiler.aggregate(parts), parentId, nodeId, nodeIndex);
|
|
2795
|
+
Compiler.aggregate(parts), parentId, nodeId, nodeIndex, null);
|
|
2513
2796
|
}
|
|
2514
2797
|
break;
|
|
2515
2798
|
}
|
|
@@ -2523,45 +2806,28 @@ function isMarker(node, directives) {
|
|
|
2523
2806
|
Parser.parse(node.data, directives) !== null);
|
|
2524
2807
|
}
|
|
2525
2808
|
const templateTag = "TEMPLATE";
|
|
2526
|
-
const policyOptions = { createHTML: html => html };
|
|
2527
|
-
let htmlPolicy = globalThis.trustedTypes
|
|
2528
|
-
? globalThis.trustedTypes.createPolicy("fast-html", policyOptions)
|
|
2529
|
-
: policyOptions;
|
|
2530
|
-
const fastHTMLPolicy = htmlPolicy;
|
|
2531
2809
|
/**
|
|
2532
2810
|
* Common APIs related to compilation.
|
|
2533
2811
|
* @public
|
|
2534
2812
|
*/
|
|
2535
2813
|
const Compiler = {
|
|
2536
|
-
/**
|
|
2537
|
-
* Sets the HTML trusted types policy used by the compiler.
|
|
2538
|
-
* @param policy - The policy to set for HTML.
|
|
2539
|
-
* @remarks
|
|
2540
|
-
* This API can only be called once, for security reasons. It should be
|
|
2541
|
-
* called by the application developer at the start of their program.
|
|
2542
|
-
*/
|
|
2543
|
-
setHTMLPolicy(policy) {
|
|
2544
|
-
if (htmlPolicy !== fastHTMLPolicy) {
|
|
2545
|
-
throw FAST.error(1201 /* Message.onlySetHTMLPolicyOnce */);
|
|
2546
|
-
}
|
|
2547
|
-
htmlPolicy = policy;
|
|
2548
|
-
},
|
|
2549
2814
|
/**
|
|
2550
2815
|
* Compiles a template and associated directives into a compilation
|
|
2551
2816
|
* result which can be used to create views.
|
|
2552
2817
|
* @param html - The html string or template element to compile.
|
|
2553
|
-
* @param
|
|
2818
|
+
* @param factories - The behavior factories referenced by the template.
|
|
2819
|
+
* @param policy - The security policy to compile the html with.
|
|
2554
2820
|
* @remarks
|
|
2555
2821
|
* The template that is provided for compilation is altered in-place
|
|
2556
2822
|
* and cannot be compiled again. If the original template must be preserved,
|
|
2557
2823
|
* it is recommended that you clone the original and pass the clone to this API.
|
|
2558
2824
|
* @public
|
|
2559
2825
|
*/
|
|
2560
|
-
compile(html,
|
|
2826
|
+
compile(html, factories, policy = DOM.policy) {
|
|
2561
2827
|
let template;
|
|
2562
2828
|
if (isString(html)) {
|
|
2563
2829
|
template = document.createElement(templateTag);
|
|
2564
|
-
template.innerHTML =
|
|
2830
|
+
template.innerHTML = policy.createHTML(html);
|
|
2565
2831
|
const fec = template.content.firstElementChild;
|
|
2566
2832
|
if (fec !== null && fec.tagName === templateTag) {
|
|
2567
2833
|
template = fec;
|
|
@@ -2572,18 +2838,18 @@ const Compiler = {
|
|
|
2572
2838
|
}
|
|
2573
2839
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1111864
|
|
2574
2840
|
const fragment = document.adoptNode(template.content);
|
|
2575
|
-
const context = new CompilationContext(fragment,
|
|
2841
|
+
const context = new CompilationContext(fragment, factories, policy);
|
|
2576
2842
|
compileAttributes(context, "", template, /* host */ "h", 0, true);
|
|
2577
2843
|
if (
|
|
2578
2844
|
// If the first node in a fragment is a marker, that means it's an unstable first node,
|
|
2579
2845
|
// because something like a when, repeat, etc. could add nodes before the marker.
|
|
2580
2846
|
// To mitigate this, we insert a stable first node. However, if we insert a node,
|
|
2581
2847
|
// that will alter the result of the TreeWalker. So, we also need to offset the target index.
|
|
2582
|
-
isMarker(fragment.firstChild,
|
|
2848
|
+
isMarker(fragment.firstChild, factories) ||
|
|
2583
2849
|
// Or if there is only one node and a directive, it means the template's content
|
|
2584
2850
|
// is *only* the directive. In that case, HTMLView.dispose() misses any nodes inserted by
|
|
2585
2851
|
// the directive. Inserting a new node ensures proper disposal of nodes added by the directive.
|
|
2586
|
-
(fragment.childNodes.length === 1 && Object.keys(
|
|
2852
|
+
(fragment.childNodes.length === 1 && Object.keys(factories).length > 0)) {
|
|
2587
2853
|
fragment.insertBefore(document.createComment(""), fragment.firstChild);
|
|
2588
2854
|
}
|
|
2589
2855
|
compileChildren(context, fragment, /* root */ "r");
|
|
@@ -2602,15 +2868,17 @@ const Compiler = {
|
|
|
2602
2868
|
* Aggregates an array of strings and directives into a single directive.
|
|
2603
2869
|
* @param parts - A heterogeneous array of static strings interspersed with
|
|
2604
2870
|
* directives.
|
|
2871
|
+
* @param policy - The security policy to use with the aggregated bindings.
|
|
2605
2872
|
* @returns A single inline directive that aggregates the behavior of all the parts.
|
|
2606
2873
|
*/
|
|
2607
|
-
aggregate(parts) {
|
|
2874
|
+
aggregate(parts, policy = DOM.policy) {
|
|
2608
2875
|
if (parts.length === 1) {
|
|
2609
2876
|
return parts[0];
|
|
2610
2877
|
}
|
|
2611
2878
|
let sourceAspect;
|
|
2612
2879
|
let binding;
|
|
2613
2880
|
let isVolatile = false;
|
|
2881
|
+
let bindingPolicy = void 0;
|
|
2614
2882
|
const partCount = parts.length;
|
|
2615
2883
|
const finalParts = parts.map((x) => {
|
|
2616
2884
|
if (isString(x)) {
|
|
@@ -2619,6 +2887,7 @@ const Compiler = {
|
|
|
2619
2887
|
sourceAspect = x.sourceAspect || sourceAspect;
|
|
2620
2888
|
binding = x.dataBinding || binding;
|
|
2621
2889
|
isVolatile = isVolatile || x.dataBinding.isVolatile;
|
|
2890
|
+
bindingPolicy = bindingPolicy || x.dataBinding.policy;
|
|
2622
2891
|
return x.dataBinding.evaluate;
|
|
2623
2892
|
});
|
|
2624
2893
|
const expression = (scope, context) => {
|
|
@@ -2630,12 +2899,26 @@ const Compiler = {
|
|
|
2630
2899
|
};
|
|
2631
2900
|
binding.evaluate = expression;
|
|
2632
2901
|
binding.isVolatile = isVolatile;
|
|
2902
|
+
binding.policy = bindingPolicy !== null && bindingPolicy !== void 0 ? bindingPolicy : policy;
|
|
2633
2903
|
const directive = new HTMLBindingDirective(binding);
|
|
2634
|
-
|
|
2904
|
+
HTMLDirective.assignAspect(directive, sourceAspect);
|
|
2635
2905
|
return directive;
|
|
2636
2906
|
},
|
|
2637
2907
|
};
|
|
2638
2908
|
|
|
2909
|
+
// Much thanks to LitHTML for working this out!
|
|
2910
|
+
const lastAttributeNameRegex =
|
|
2911
|
+
/* eslint-disable-next-line no-control-regex */
|
|
2912
|
+
/([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F "'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/;
|
|
2913
|
+
function createHTML(value, prevString, add, definition = HTMLDirective.getForInstance(value)) {
|
|
2914
|
+
if (definition.aspected) {
|
|
2915
|
+
const match = lastAttributeNameRegex.exec(prevString);
|
|
2916
|
+
if (match !== null) {
|
|
2917
|
+
HTMLDirective.assignAspect(value, match[2]);
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
return value.createHTML(add);
|
|
2921
|
+
}
|
|
2639
2922
|
/**
|
|
2640
2923
|
* A template capable of creating HTMLView instances or rendering directly to DOM.
|
|
2641
2924
|
* @public
|
|
@@ -2645,8 +2928,10 @@ class ViewTemplate {
|
|
|
2645
2928
|
* Creates an instance of ViewTemplate.
|
|
2646
2929
|
* @param html - The html representing what this template will instantiate, including placeholders for directives.
|
|
2647
2930
|
* @param factories - The directives that will be connected to placeholders in the html.
|
|
2931
|
+
* @param policy - The security policy to use when compiling this template.
|
|
2648
2932
|
*/
|
|
2649
|
-
constructor(html, factories) {
|
|
2933
|
+
constructor(html, factories = {}, policy) {
|
|
2934
|
+
this.policy = policy;
|
|
2650
2935
|
this.result = null;
|
|
2651
2936
|
/**
|
|
2652
2937
|
* Opts out of JSON stringification.
|
|
@@ -2662,10 +2947,28 @@ class ViewTemplate {
|
|
|
2662
2947
|
*/
|
|
2663
2948
|
create(hostBindingTarget) {
|
|
2664
2949
|
if (this.result === null) {
|
|
2665
|
-
this.result = Compiler.compile(this.html, this.factories);
|
|
2950
|
+
this.result = Compiler.compile(this.html, this.factories, this.policy);
|
|
2666
2951
|
}
|
|
2667
2952
|
return this.result.createView(hostBindingTarget);
|
|
2668
2953
|
}
|
|
2954
|
+
/**
|
|
2955
|
+
* Sets the DOMPolicy for this template.
|
|
2956
|
+
* @param policy - The policy to associated with this template.
|
|
2957
|
+
* @returns The modified template instance.
|
|
2958
|
+
* @remarks
|
|
2959
|
+
* The DOMPolicy can only be set once for a template and cannot be
|
|
2960
|
+
* set after the template is compiled.
|
|
2961
|
+
*/
|
|
2962
|
+
withPolicy(policy) {
|
|
2963
|
+
if (this.result) {
|
|
2964
|
+
throw FAST.error(1208 /* Message.cannotSetTemplatePolicyAfterCompilation */);
|
|
2965
|
+
}
|
|
2966
|
+
if (this.policy) {
|
|
2967
|
+
throw FAST.error(1207 /* Message.onlySetTemplatePolicyOnce */);
|
|
2968
|
+
}
|
|
2969
|
+
this.policy = policy;
|
|
2970
|
+
return this;
|
|
2971
|
+
}
|
|
2669
2972
|
/**
|
|
2670
2973
|
* Creates an HTMLView from this template, binds it to the source, and then appends it to the host.
|
|
2671
2974
|
* @param source - The data source to bind the template to.
|
|
@@ -2679,17 +2982,47 @@ class ViewTemplate {
|
|
|
2679
2982
|
view.appendTo(host);
|
|
2680
2983
|
return view;
|
|
2681
2984
|
}
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2985
|
+
/**
|
|
2986
|
+
* Creates a template based on a set of static strings and dynamic values.
|
|
2987
|
+
* @param strings - The static strings to create the template with.
|
|
2988
|
+
* @param values - The dynamic values to create the template with.
|
|
2989
|
+
* @param policy - The DOMPolicy to associated with the template.
|
|
2990
|
+
* @returns A ViewTemplate.
|
|
2991
|
+
* @remarks
|
|
2992
|
+
* This API should not be used directly under normal circumstances because constructing
|
|
2993
|
+
* a template in this way, if not done properly, can open up the application to XSS
|
|
2994
|
+
* attacks. When using this API, provide a strong DOMPolicy that can properly sanitize
|
|
2995
|
+
* and also be sure to manually sanitize all static strings particularly if they can
|
|
2996
|
+
* come from user input.
|
|
2997
|
+
*/
|
|
2998
|
+
static create(strings, values, policy) {
|
|
2999
|
+
let html = "";
|
|
3000
|
+
const factories = Object.create(null);
|
|
3001
|
+
const add = (factory) => {
|
|
3002
|
+
var _a;
|
|
3003
|
+
const id = (_a = factory.id) !== null && _a !== void 0 ? _a : (factory.id = nextId());
|
|
3004
|
+
factories[id] = factory;
|
|
3005
|
+
return id;
|
|
3006
|
+
};
|
|
3007
|
+
for (let i = 0, ii = strings.length - 1; i < ii; ++i) {
|
|
3008
|
+
const currentString = strings[i];
|
|
3009
|
+
let currentValue = values[i];
|
|
3010
|
+
let definition;
|
|
3011
|
+
html += currentString;
|
|
3012
|
+
if (isFunction(currentValue)) {
|
|
3013
|
+
currentValue = new HTMLBindingDirective(bind(currentValue));
|
|
3014
|
+
}
|
|
3015
|
+
else if (currentValue instanceof Binding) {
|
|
3016
|
+
currentValue = new HTMLBindingDirective(currentValue);
|
|
3017
|
+
}
|
|
3018
|
+
else if (!(definition = HTMLDirective.getForInstance(currentValue))) {
|
|
3019
|
+
const staticValue = currentValue;
|
|
3020
|
+
currentValue = new HTMLBindingDirective(oneTime(() => staticValue));
|
|
3021
|
+
}
|
|
3022
|
+
html += createHTML(currentValue, currentString, add, definition);
|
|
3023
|
+
}
|
|
3024
|
+
return new ViewTemplate(html + strings[strings.length - 1], factories, policy);
|
|
2691
3025
|
}
|
|
2692
|
-
return value.createHTML(add);
|
|
2693
3026
|
}
|
|
2694
3027
|
/**
|
|
2695
3028
|
* Transforms a template literal string into a ViewTemplate.
|
|
@@ -2701,49 +3034,10 @@ function createAspectedHTML(value, prevString, add) {
|
|
|
2701
3034
|
* @public
|
|
2702
3035
|
*/
|
|
2703
3036
|
function html(strings, ...values) {
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
const add = (factory) => {
|
|
2707
|
-
var _a;
|
|
2708
|
-
const id = (_a = factory.id) !== null && _a !== void 0 ? _a : (factory.id = nextId());
|
|
2709
|
-
factories[id] = factory;
|
|
2710
|
-
return id;
|
|
2711
|
-
};
|
|
2712
|
-
for (let i = 0, ii = strings.length - 1; i < ii; ++i) {
|
|
2713
|
-
const currentString = strings[i];
|
|
2714
|
-
const currentValue = values[i];
|
|
2715
|
-
let definition;
|
|
2716
|
-
html += currentString;
|
|
2717
|
-
if (isFunction(currentValue)) {
|
|
2718
|
-
html += createAspectedHTML(new HTMLBindingDirective(bind(currentValue)), currentString, add);
|
|
2719
|
-
}
|
|
2720
|
-
else if (isString(currentValue)) {
|
|
2721
|
-
const match = lastAttributeNameRegex.exec(currentString);
|
|
2722
|
-
if (match !== null) {
|
|
2723
|
-
const directive = new HTMLBindingDirective(oneTime(() => currentValue));
|
|
2724
|
-
Aspect.assign(directive, match[2]);
|
|
2725
|
-
html += directive.createHTML(add);
|
|
2726
|
-
}
|
|
2727
|
-
else {
|
|
2728
|
-
html += currentValue;
|
|
2729
|
-
}
|
|
2730
|
-
}
|
|
2731
|
-
else if (currentValue instanceof Binding) {
|
|
2732
|
-
html += createAspectedHTML(new HTMLBindingDirective(currentValue), currentString, add);
|
|
2733
|
-
}
|
|
2734
|
-
else if ((definition = HTMLDirective.getForInstance(currentValue)) === void 0) {
|
|
2735
|
-
html += createAspectedHTML(new HTMLBindingDirective(oneTime(() => currentValue)), currentString, add);
|
|
2736
|
-
}
|
|
2737
|
-
else {
|
|
2738
|
-
if (definition.aspected) {
|
|
2739
|
-
html += createAspectedHTML(currentValue, currentString, add);
|
|
2740
|
-
}
|
|
2741
|
-
else {
|
|
2742
|
-
html += currentValue.createHTML(add);
|
|
2743
|
-
}
|
|
2744
|
-
}
|
|
3037
|
+
if (Array.isArray(strings) && Array.isArray(strings.raw)) {
|
|
3038
|
+
return ViewTemplate.create(strings, values);
|
|
2745
3039
|
}
|
|
2746
|
-
|
|
3040
|
+
throw FAST.error(1206 /* Message.directCallToHTMLTagNotAllowed */);
|
|
2747
3041
|
}
|
|
2748
3042
|
|
|
2749
3043
|
/**
|
|
@@ -2756,7 +3050,7 @@ class RefDirective extends StatelessAttachedAttributeDirective {
|
|
|
2756
3050
|
* @param controller - The view controller that manages the lifecycle of this behavior.
|
|
2757
3051
|
*/
|
|
2758
3052
|
bind(controller) {
|
|
2759
|
-
controller.source[this.options] = controller.targets[this.
|
|
3053
|
+
controller.source[this.options] = controller.targets[this.targetNodeId];
|
|
2760
3054
|
}
|
|
2761
3055
|
}
|
|
2762
3056
|
HTMLDirective.define(RefDirective);
|
|
@@ -2830,7 +3124,7 @@ class RepeatBehavior {
|
|
|
2830
3124
|
* @param controller - The view controller that manages the lifecycle of this behavior.
|
|
2831
3125
|
*/
|
|
2832
3126
|
bind(controller) {
|
|
2833
|
-
this.location = controller.targets[this.directive.
|
|
3127
|
+
this.location = controller.targets[this.directive.targetNodeId];
|
|
2834
3128
|
this.controller = controller;
|
|
2835
3129
|
this.items = this.itemsBindingObserver.bind(controller);
|
|
2836
3130
|
this.template = this.templateBindingObserver.bind(controller);
|
|
@@ -3010,10 +3304,6 @@ class RepeatDirective {
|
|
|
3010
3304
|
this.dataBinding = dataBinding;
|
|
3011
3305
|
this.templateBinding = templateBinding;
|
|
3012
3306
|
this.options = options;
|
|
3013
|
-
/**
|
|
3014
|
-
* The unique id of the factory.
|
|
3015
|
-
*/
|
|
3016
|
-
this.id = nextId();
|
|
3017
3307
|
ArrayObserver.enable();
|
|
3018
3308
|
}
|
|
3019
3309
|
/**
|
|
@@ -3062,9 +3352,15 @@ const elements = (selector) => selector
|
|
|
3062
3352
|
* Internally used by the SlottedDirective and the ChildrenDirective.
|
|
3063
3353
|
*/
|
|
3064
3354
|
class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3355
|
+
/**
|
|
3356
|
+
* The unique id of the factory.
|
|
3357
|
+
*/
|
|
3358
|
+
get id() {
|
|
3359
|
+
return this._id;
|
|
3360
|
+
}
|
|
3361
|
+
set id(value) {
|
|
3362
|
+
this._id = value;
|
|
3363
|
+
this._controllerProperty = `${value}-c`;
|
|
3068
3364
|
}
|
|
3069
3365
|
/**
|
|
3070
3366
|
* Bind this behavior to the source.
|
|
@@ -3073,8 +3369,8 @@ class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
|
3073
3369
|
* @param targets - The targets that behaviors in a view can attach to.
|
|
3074
3370
|
*/
|
|
3075
3371
|
bind(controller) {
|
|
3076
|
-
const target = controller.targets[this.
|
|
3077
|
-
target[this.
|
|
3372
|
+
const target = controller.targets[this.targetNodeId];
|
|
3373
|
+
target[this._controllerProperty] = controller;
|
|
3078
3374
|
this.updateTarget(controller.source, this.computeNodes(target));
|
|
3079
3375
|
this.observe(target);
|
|
3080
3376
|
controller.onUnbind(this);
|
|
@@ -3086,10 +3382,10 @@ class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
|
3086
3382
|
* @param targets - The targets that behaviors in a view can attach to.
|
|
3087
3383
|
*/
|
|
3088
3384
|
unbind(controller) {
|
|
3089
|
-
const target = controller.targets[this.
|
|
3385
|
+
const target = controller.targets[this.targetNodeId];
|
|
3090
3386
|
this.updateTarget(controller.source, emptyArray);
|
|
3091
3387
|
this.disconnect(target);
|
|
3092
|
-
target[this.
|
|
3388
|
+
target[this._controllerProperty] = null;
|
|
3093
3389
|
}
|
|
3094
3390
|
/**
|
|
3095
3391
|
* Gets the data source for the target.
|
|
@@ -3097,7 +3393,7 @@ class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
|
3097
3393
|
* @returns The source.
|
|
3098
3394
|
*/
|
|
3099
3395
|
getSource(target) {
|
|
3100
|
-
return target[this.
|
|
3396
|
+
return target[this._controllerProperty].source;
|
|
3101
3397
|
}
|
|
3102
3398
|
/**
|
|
3103
3399
|
* Updates the source property with the computed nodes.
|
|
@@ -3238,6 +3534,29 @@ function children(propertyOrOptions) {
|
|
|
3238
3534
|
return new ChildrenDirective(propertyOrOptions);
|
|
3239
3535
|
}
|
|
3240
3536
|
|
|
3537
|
+
/**
|
|
3538
|
+
* A directive capable of injecting static HTML platform runtime protection.
|
|
3539
|
+
* @public
|
|
3540
|
+
*/
|
|
3541
|
+
class DangerousHTMLDirective {
|
|
3542
|
+
constructor(html) {
|
|
3543
|
+
this.html = html;
|
|
3544
|
+
}
|
|
3545
|
+
createHTML() {
|
|
3546
|
+
return this.html;
|
|
3547
|
+
}
|
|
3548
|
+
}
|
|
3549
|
+
HTMLDirective.define(DangerousHTMLDirective);
|
|
3550
|
+
/**
|
|
3551
|
+
* Injects static HTML without platform protection.
|
|
3552
|
+
* @param html - The html to injection.
|
|
3553
|
+
* @returns A DangerousHTMLDirective.
|
|
3554
|
+
* @public
|
|
3555
|
+
*/
|
|
3556
|
+
function dangerousHTML(html) {
|
|
3557
|
+
return new DangerousHTMLDirective(html);
|
|
3558
|
+
}
|
|
3559
|
+
|
|
3241
3560
|
const booleanMode = "boolean";
|
|
3242
3561
|
const reflectMode = "reflect";
|
|
3243
3562
|
/**
|
|
@@ -4098,4 +4417,6 @@ function customElement(nameOrDef) {
|
|
|
4098
4417
|
};
|
|
4099
4418
|
}
|
|
4100
4419
|
|
|
4101
|
-
|
|
4420
|
+
DOM.setPolicy(DOMPolicy.create());
|
|
4421
|
+
|
|
4422
|
+
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 };
|