@lushly-dev/fast-element 3.0.1-preview.0 → 3.0.1-preview.1
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.md +6 -0
- package/dist/command/command.api.json +7857 -0
- package/dist/context/context.api.json +1084 -0
- package/dist/declarative/declarative.api.json +8130 -0
- package/dist/definition-schema/definition-schema.api.json +2689 -0
- package/dist/di/di.api.json +4945 -0
- package/dist/dts/arrays.d.ts +2 -0
- package/dist/dts/binding/binding.d.ts +59 -0
- package/dist/dts/binding/exports.d.ts +9 -0
- package/dist/dts/binding/normalize.d.ts +9 -0
- package/dist/dts/binding/one-time.d.ts +11 -0
- package/dist/dts/binding/one-way.d.ts +20 -0
- package/dist/dts/binding/signal.d.ts +36 -0
- package/dist/dts/binding/two-way.d.ts +44 -0
- package/dist/dts/command/behavior.d.ts +94 -0
- package/dist/dts/command/behaviors/confirm-behavior.d.ts +139 -0
- package/dist/dts/command/behaviors/undo-behavior.d.ts +178 -0
- package/dist/dts/command/command.d.ts +79 -0
- package/dist/dts/command/component-registry.d.ts +50 -0
- package/dist/dts/command/components/confirm-dialog.d.ts +117 -0
- package/dist/dts/command/index.d.ts +21 -0
- package/dist/dts/command/registry.d.ts +201 -0
- package/dist/dts/command/schema-validation.d.ts +45 -0
- package/dist/dts/command/types.d.ts +332 -0
- package/dist/dts/command/validation.d.ts +116 -0
- package/dist/dts/command/weak-ref.d.ts +11 -0
- package/dist/dts/components/attributes.d.ts +153 -0
- package/dist/dts/components/definition-schema-transforms.d.ts +9 -0
- package/dist/dts/components/element-controller.d.ts +349 -0
- package/dist/dts/components/element-hydration.d.ts +2 -0
- package/dist/dts/components/enable-hydration.d.ts +66 -0
- package/dist/dts/components/fast-definitions.d.ts +211 -0
- package/dist/dts/components/fast-element-registry.d.ts +23 -0
- package/dist/dts/components/fast-element.d.ts +91 -0
- package/dist/dts/components/hydration-tracker.d.ts +110 -0
- package/dist/dts/components/hydration.d.ts +52 -0
- package/dist/dts/components/schema.d.ts +205 -0
- package/dist/dts/context.d.ts +171 -0
- package/dist/dts/debug.d.ts +5 -0
- package/dist/dts/declarative/attribute-map.d.ts +58 -0
- package/dist/dts/declarative/debug.d.ts +4 -0
- package/dist/dts/declarative/index.d.ts +14 -0
- package/dist/dts/declarative/interfaces.d.ts +8 -0
- package/dist/dts/declarative/observer-map-utilities.d.ts +58 -0
- package/dist/dts/declarative/observer-map.d.ts +89 -0
- package/dist/dts/declarative/runtime.d.ts +5 -0
- package/dist/dts/declarative/syntax.d.ts +21 -0
- package/dist/dts/declarative/template-bridge.d.ts +33 -0
- package/dist/dts/declarative/template-parser.d.ts +98 -0
- package/dist/dts/declarative/template.d.ts +9 -0
- package/dist/dts/declarative/utilities.d.ts +358 -0
- package/dist/dts/definition-schema/api.d.ts +42 -0
- package/dist/dts/definition-schema/cem.d.ts +78 -0
- package/dist/dts/definition-schema/extension.d.ts +18 -0
- package/dist/dts/definition-schema/extract.d.ts +38 -0
- package/dist/dts/definition-schema/index.d.ts +9 -0
- package/dist/dts/definition-schema/storage.d.ts +35 -0
- package/dist/dts/definition-schema/types.d.ts +176 -0
- package/dist/dts/dev-mode.d.ts +13 -0
- package/dist/dts/di/di.d.ts +894 -0
- package/dist/dts/dom-policy.d.ts +101 -0
- package/dist/dts/dom.d.ts +88 -0
- package/dist/dts/hydration/diagnostics.d.ts +93 -0
- package/dist/dts/hydration/exports.d.ts +18 -0
- package/dist/dts/hydration/hydration-debugger.d.ts +35 -0
- package/dist/dts/hydration/messages.d.ts +62 -0
- package/dist/dts/hydration/runtime.d.ts +7 -0
- package/dist/dts/hydration/target-builder.d.ts +107 -0
- package/dist/dts/index.d.ts +51 -0
- package/dist/dts/index.debug.d.ts +1 -0
- package/dist/dts/index.rollup.d.ts +1 -0
- package/dist/dts/index.rollup.debug.d.ts +1 -0
- package/dist/dts/interfaces.d.ts +106 -0
- package/dist/dts/metadata.d.ts +26 -0
- package/dist/dts/observation/arrays.d.ts +248 -0
- package/dist/dts/observation/notifier.d.ts +127 -0
- package/dist/dts/observation/observable.d.ts +276 -0
- package/dist/dts/observation/update-queue.d.ts +40 -0
- package/dist/dts/observation/volatile.d.ts +9 -0
- package/dist/dts/platform.d.ts +87 -0
- package/dist/dts/registry.d.ts +2 -0
- package/dist/dts/render.d.ts +7 -0
- package/dist/dts/schema.d.ts +1 -0
- package/dist/dts/scoped/detection.d.ts +55 -0
- package/dist/dts/scoped/index.d.ts +68 -0
- package/dist/dts/scoped/mixin.d.ts +118 -0
- package/dist/dts/scoped/registry.d.ts +76 -0
- package/dist/dts/scoped/types.d.ts +48 -0
- package/dist/dts/state/exports.d.ts +3 -0
- package/dist/dts/state/reactive.d.ts +8 -0
- package/dist/dts/state/state.d.ts +141 -0
- package/dist/dts/state/visitor.d.ts +6 -0
- package/dist/dts/state/watch.d.ts +10 -0
- package/dist/dts/styles/css-directive.d.ts +50 -0
- package/dist/dts/styles/css.d.ts +34 -0
- package/dist/dts/styles/element-styles.d.ts +61 -0
- package/dist/dts/styles/host.d.ts +65 -0
- package/dist/dts/styles/style-strategy.d.ts +42 -0
- package/dist/dts/templating/children.d.ts +62 -0
- package/dist/dts/templating/compiler.d.ts +54 -0
- package/dist/dts/templating/html-binding-directive.d.ts +155 -0
- package/dist/dts/templating/html-directive.d.ts +218 -0
- package/dist/dts/templating/html.d.ts +1 -0
- package/dist/dts/templating/hydration-view.d.ts +130 -0
- package/dist/dts/templating/markup.d.ts +48 -0
- package/dist/dts/templating/node-observation.d.ts +99 -0
- package/dist/dts/templating/ref.d.ts +23 -0
- package/dist/dts/templating/render.d.ts +318 -0
- package/dist/dts/templating/repeat.d.ts +131 -0
- package/dist/dts/templating/slotted.d.ts +38 -0
- package/dist/dts/templating/template.d.ts +221 -0
- package/dist/dts/templating/view.d.ts +268 -0
- package/dist/dts/templating/when.d.ts +12 -0
- package/dist/dts/testing/exports.d.ts +3 -0
- package/dist/dts/testing/fakes.d.ts +15 -0
- package/dist/dts/testing/fixture.d.ts +84 -0
- package/dist/dts/testing/models.d.ts +20 -0
- package/dist/dts/testing/timeout.d.ts +7 -0
- package/dist/dts/trust/index.d.ts +8 -0
- package/dist/dts/trust/types.d.ts +48 -0
- package/dist/dts/trust/utils.d.ts +26 -0
- package/dist/dts/tsdoc-metadata.json +11 -0
- package/dist/dts/utilities.d.ts +76 -0
- package/dist/esm/arrays.js +1 -0
- package/dist/esm/binding/binding.js +18 -0
- package/dist/esm/binding/exports.js +6 -0
- package/dist/esm/binding/normalize.js +17 -0
- package/dist/esm/binding/one-time.js +21 -0
- package/dist/esm/binding/one-way.js +30 -0
- package/dist/esm/binding/signal.js +99 -0
- package/dist/esm/binding/two-way.js +110 -0
- package/dist/esm/command/behavior.js +155 -0
- package/dist/esm/command/behaviors/confirm-behavior.js +225 -0
- package/dist/esm/command/behaviors/undo-behavior.js +312 -0
- package/dist/esm/command/command.js +104 -0
- package/dist/esm/command/component-registry.js +107 -0
- package/dist/esm/command/components/confirm-dialog.js +370 -0
- package/dist/esm/command/index.js +22 -0
- package/dist/esm/command/registry.js +752 -0
- package/dist/esm/command/schema-validation.js +194 -0
- package/dist/esm/command/types.js +86 -0
- package/dist/esm/command/validation.js +511 -0
- package/dist/esm/command/weak-ref.js +5 -0
- package/dist/esm/components/attributes.js +219 -0
- package/dist/esm/components/definition-schema-transforms.js +23 -0
- package/dist/esm/components/element-controller.js +839 -0
- package/dist/esm/components/element-hydration.js +2 -0
- package/dist/esm/components/enable-hydration.js +123 -0
- package/dist/esm/components/fast-definitions.js +294 -0
- package/dist/esm/components/fast-element-registry.js +67 -0
- package/dist/esm/components/fast-element.js +82 -0
- package/dist/esm/components/hydration-tracker.js +210 -0
- package/dist/esm/components/hydration.js +187 -0
- package/dist/esm/components/schema.js +253 -0
- package/dist/esm/context.js +185 -0
- package/dist/esm/debug.js +71 -0
- package/dist/esm/declarative/attribute-map.js +121 -0
- package/dist/esm/declarative/debug.js +4 -0
- package/dist/esm/declarative/index.js +10 -0
- package/dist/esm/declarative/interfaces.js +9 -0
- package/dist/esm/declarative/observer-map-utilities.js +565 -0
- package/dist/esm/declarative/observer-map.js +216 -0
- package/dist/esm/declarative/runtime.js +14 -0
- package/dist/esm/declarative/syntax.js +36 -0
- package/dist/esm/declarative/template-bridge.js +160 -0
- package/dist/esm/declarative/template-parser.js +306 -0
- package/dist/esm/declarative/template.js +116 -0
- package/dist/esm/declarative/utilities.js +1069 -0
- package/dist/esm/definition-schema/api.js +129 -0
- package/dist/esm/definition-schema/cem.js +89 -0
- package/dist/esm/definition-schema/extension.js +53 -0
- package/dist/esm/definition-schema/extract.js +167 -0
- package/dist/esm/definition-schema/index.js +8 -0
- package/dist/esm/definition-schema/storage.js +58 -0
- package/dist/esm/definition-schema/types.js +8 -0
- package/dist/esm/dev-mode.js +22 -0
- package/dist/esm/di/di.js +1440 -0
- package/dist/esm/dom-policy.js +374 -0
- package/dist/esm/dom.js +101 -0
- package/dist/esm/hydration/diagnostics.js +50 -0
- package/dist/esm/hydration/exports.js +6 -0
- package/dist/esm/hydration/hydration-debugger.js +112 -0
- package/dist/esm/hydration/messages.js +84 -0
- package/dist/esm/hydration/runtime.js +33 -0
- package/dist/esm/hydration/target-builder.js +264 -0
- package/dist/esm/index.debug.js +3 -0
- package/dist/esm/index.js +49 -0
- package/dist/esm/index.rollup.debug.js +6 -0
- package/dist/esm/index.rollup.js +4 -0
- package/dist/esm/interfaces.js +55 -0
- package/dist/esm/metadata.js +63 -0
- package/dist/esm/observation/arrays.js +661 -0
- package/dist/esm/observation/notifier.js +164 -0
- package/dist/esm/observation/observable.js +324 -0
- package/dist/esm/observation/update-queue.js +56 -0
- package/dist/esm/observation/volatile.js +16 -0
- package/dist/esm/platform.js +98 -0
- package/dist/esm/registry.js +2 -0
- package/dist/esm/render.js +1 -0
- package/dist/esm/schema.js +1 -0
- package/dist/esm/scoped/detection.js +102 -0
- package/dist/esm/scoped/index.js +69 -0
- package/dist/esm/scoped/mixin.js +127 -0
- package/dist/esm/scoped/registry.js +125 -0
- package/dist/esm/scoped/types.js +4 -0
- package/dist/esm/state/exports.js +3 -0
- package/dist/esm/state/reactive.js +34 -0
- package/dist/esm/state/state.js +148 -0
- package/dist/esm/state/visitor.js +28 -0
- package/dist/esm/state/watch.js +36 -0
- package/dist/esm/styles/css-directive.js +36 -0
- package/dist/esm/styles/css.js +56 -0
- package/dist/esm/styles/element-styles.js +144 -0
- package/dist/esm/styles/host.js +1 -0
- package/dist/esm/styles/style-strategy.js +1 -0
- package/dist/esm/templating/children.js +67 -0
- package/dist/esm/templating/compiler.js +359 -0
- package/dist/esm/templating/html-binding-directive.js +288 -0
- package/dist/esm/templating/html-directive.js +113 -0
- package/dist/esm/templating/html.js +1 -0
- package/dist/esm/templating/hydration-view.js +228 -0
- package/dist/esm/templating/markup.js +83 -0
- package/dist/esm/templating/node-observation.js +84 -0
- package/dist/esm/templating/ref.js +21 -0
- package/dist/esm/templating/render.js +468 -0
- package/dist/esm/templating/repeat.js +434 -0
- package/dist/esm/templating/slotted.js +49 -0
- package/dist/esm/templating/template.js +206 -0
- package/dist/esm/templating/view.js +298 -0
- package/dist/esm/templating/when.js +22 -0
- package/dist/esm/testing/exports.js +3 -0
- package/dist/esm/testing/fakes.js +107 -0
- package/dist/esm/testing/fixture.js +86 -0
- package/dist/esm/testing/models.js +58 -0
- package/dist/esm/testing/timeout.js +24 -0
- package/dist/esm/trust/index.js +7 -0
- package/dist/esm/trust/types.js +6 -0
- package/dist/esm/trust/utils.js +126 -0
- package/dist/esm/utilities.js +140 -0
- package/dist/fast-element.api.json +26798 -0
- package/dist/fast-element.d.ts +3985 -0
- package/dist/fast-element.debug.js +7618 -0
- package/dist/fast-element.debug.min.js +3 -0
- package/dist/fast-element.js +7617 -0
- package/dist/fast-element.min.js +3 -0
- package/dist/fast-element.untrimmed.d.ts +4103 -0
- package/dist/observation/arrays/arrays.api.json +2621 -0
- package/dist/scoped/scoped.api.json +891 -0
- package/dist/trust/trust.api.json +629 -0
- package/package.json +12 -12
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { DOMAspect } from "./dom.js";
|
|
2
|
+
import { isString, Message } from "./interfaces.js";
|
|
3
|
+
import { FAST } from "./platform.js";
|
|
4
|
+
const surroundingWhitespaceAndControlChars = /^[\u0000-\u0020\u007F]+|[\u0000-\u0020\u007F]+$/g;
|
|
5
|
+
const whitespaceAndControlChars = /[\u0000-\u0020\u007F]+/g;
|
|
6
|
+
const unsafeURLProtocol = /^(?:javascript|vbscript|data):/;
|
|
7
|
+
function trimURL(value) {
|
|
8
|
+
return value.replace(surroundingWhitespaceAndControlChars, "");
|
|
9
|
+
}
|
|
10
|
+
function decodeURL(value) {
|
|
11
|
+
try {
|
|
12
|
+
return decodeURIComponent(value);
|
|
13
|
+
}
|
|
14
|
+
catch (_a) {
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function hasUnsafeURLProtocol(value) {
|
|
19
|
+
let normalized = trimURL(value);
|
|
20
|
+
for (let i = 0; i < 3; ++i) {
|
|
21
|
+
const decoded = decodeURL(normalized);
|
|
22
|
+
if (decoded === normalized) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
normalized = trimURL(decoded);
|
|
26
|
+
}
|
|
27
|
+
normalized = normalized.replace(whitespaceAndControlChars, "").toLowerCase();
|
|
28
|
+
return unsafeURLProtocol.test(normalized);
|
|
29
|
+
}
|
|
30
|
+
function sanitizeURL(value) {
|
|
31
|
+
const trimmed = trimURL(value);
|
|
32
|
+
return hasUnsafeURLProtocol(trimmed) ? "" : trimmed;
|
|
33
|
+
}
|
|
34
|
+
function safeURL(tagName, aspect, aspectName, sink) {
|
|
35
|
+
return (target, name, value, ...rest) => {
|
|
36
|
+
if (isString(value)) {
|
|
37
|
+
value = sanitizeURL(value);
|
|
38
|
+
}
|
|
39
|
+
sink(target, name, value, ...rest);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function block(tagName, aspect, aspectName, sink) {
|
|
43
|
+
throw FAST.error(Message.blockedByDOMPolicy, {
|
|
44
|
+
aspectName,
|
|
45
|
+
tagName: tagName !== null && tagName !== void 0 ? tagName : "text",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const defaultDOMElementGuards = {
|
|
49
|
+
a: {
|
|
50
|
+
[DOMAspect.attribute]: {
|
|
51
|
+
href: safeURL,
|
|
52
|
+
},
|
|
53
|
+
[DOMAspect.property]: {
|
|
54
|
+
href: safeURL,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
area: {
|
|
58
|
+
[DOMAspect.attribute]: {
|
|
59
|
+
href: safeURL,
|
|
60
|
+
},
|
|
61
|
+
[DOMAspect.property]: {
|
|
62
|
+
href: safeURL,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
button: {
|
|
66
|
+
[DOMAspect.attribute]: {
|
|
67
|
+
formaction: safeURL,
|
|
68
|
+
},
|
|
69
|
+
[DOMAspect.property]: {
|
|
70
|
+
formAction: safeURL,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
embed: {
|
|
74
|
+
[DOMAspect.attribute]: {
|
|
75
|
+
src: block,
|
|
76
|
+
},
|
|
77
|
+
[DOMAspect.property]: {
|
|
78
|
+
src: block,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
form: {
|
|
82
|
+
[DOMAspect.attribute]: {
|
|
83
|
+
action: safeURL,
|
|
84
|
+
},
|
|
85
|
+
[DOMAspect.property]: {
|
|
86
|
+
action: safeURL,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
frame: {
|
|
90
|
+
[DOMAspect.attribute]: {
|
|
91
|
+
src: safeURL,
|
|
92
|
+
},
|
|
93
|
+
[DOMAspect.property]: {
|
|
94
|
+
src: safeURL,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
iframe: {
|
|
98
|
+
[DOMAspect.attribute]: {
|
|
99
|
+
src: safeURL,
|
|
100
|
+
},
|
|
101
|
+
[DOMAspect.property]: {
|
|
102
|
+
src: safeURL,
|
|
103
|
+
srcdoc: block,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
input: {
|
|
107
|
+
[DOMAspect.attribute]: {
|
|
108
|
+
formaction: safeURL,
|
|
109
|
+
},
|
|
110
|
+
[DOMAspect.property]: {
|
|
111
|
+
formAction: safeURL,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
link: {
|
|
115
|
+
[DOMAspect.attribute]: {
|
|
116
|
+
href: block,
|
|
117
|
+
},
|
|
118
|
+
[DOMAspect.property]: {
|
|
119
|
+
href: block,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
object: {
|
|
123
|
+
[DOMAspect.attribute]: {
|
|
124
|
+
codebase: block,
|
|
125
|
+
data: block,
|
|
126
|
+
},
|
|
127
|
+
[DOMAspect.property]: {
|
|
128
|
+
codeBase: block,
|
|
129
|
+
data: block,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
script: {
|
|
133
|
+
[DOMAspect.attribute]: {
|
|
134
|
+
src: block,
|
|
135
|
+
text: block,
|
|
136
|
+
},
|
|
137
|
+
[DOMAspect.property]: {
|
|
138
|
+
src: block,
|
|
139
|
+
text: block,
|
|
140
|
+
innerText: block,
|
|
141
|
+
textContent: block,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
style: {
|
|
145
|
+
[DOMAspect.property]: {
|
|
146
|
+
innerText: block,
|
|
147
|
+
textContent: block,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
const blockedEvents = {
|
|
152
|
+
onabort: block,
|
|
153
|
+
onauxclick: block,
|
|
154
|
+
onbeforeinput: block,
|
|
155
|
+
onbeforematch: block,
|
|
156
|
+
onblur: block,
|
|
157
|
+
oncancel: block,
|
|
158
|
+
oncanplay: block,
|
|
159
|
+
oncanplaythrough: block,
|
|
160
|
+
onchange: block,
|
|
161
|
+
onclick: block,
|
|
162
|
+
onclose: block,
|
|
163
|
+
oncontextlost: block,
|
|
164
|
+
oncontextmenu: block,
|
|
165
|
+
oncontextrestored: block,
|
|
166
|
+
oncopy: block,
|
|
167
|
+
oncuechange: block,
|
|
168
|
+
oncut: block,
|
|
169
|
+
ondblclick: block,
|
|
170
|
+
ondrag: block,
|
|
171
|
+
ondragend: block,
|
|
172
|
+
ondragenter: block,
|
|
173
|
+
ondragleave: block,
|
|
174
|
+
ondragover: block,
|
|
175
|
+
ondragstart: block,
|
|
176
|
+
ondrop: block,
|
|
177
|
+
ondurationchange: block,
|
|
178
|
+
onemptied: block,
|
|
179
|
+
onended: block,
|
|
180
|
+
onerror: block,
|
|
181
|
+
onfocus: block,
|
|
182
|
+
onformdata: block,
|
|
183
|
+
oninput: block,
|
|
184
|
+
oninvalid: block,
|
|
185
|
+
onkeydown: block,
|
|
186
|
+
onkeypress: block,
|
|
187
|
+
onkeyup: block,
|
|
188
|
+
onload: block,
|
|
189
|
+
onloadeddata: block,
|
|
190
|
+
onloadedmetadata: block,
|
|
191
|
+
onloadstart: block,
|
|
192
|
+
onmousedown: block,
|
|
193
|
+
onmouseenter: block,
|
|
194
|
+
onmouseleave: block,
|
|
195
|
+
onmousemove: block,
|
|
196
|
+
onmouseout: block,
|
|
197
|
+
onmouseover: block,
|
|
198
|
+
onmouseup: block,
|
|
199
|
+
onpaste: block,
|
|
200
|
+
onpause: block,
|
|
201
|
+
onplay: block,
|
|
202
|
+
onplaying: block,
|
|
203
|
+
onprogress: block,
|
|
204
|
+
onratechange: block,
|
|
205
|
+
onreset: block,
|
|
206
|
+
onresize: block,
|
|
207
|
+
onscroll: block,
|
|
208
|
+
onsecuritypolicyviolation: block,
|
|
209
|
+
onseeked: block,
|
|
210
|
+
onseeking: block,
|
|
211
|
+
onselect: block,
|
|
212
|
+
onslotchange: block,
|
|
213
|
+
onstalled: block,
|
|
214
|
+
onsubmit: block,
|
|
215
|
+
onsuspend: block,
|
|
216
|
+
ontimeupdate: block,
|
|
217
|
+
ontoggle: block,
|
|
218
|
+
onvolumechange: block,
|
|
219
|
+
onwaiting: block,
|
|
220
|
+
onwebkitanimationend: block,
|
|
221
|
+
onwebkitanimationiteration: block,
|
|
222
|
+
onwebkitanimationstart: block,
|
|
223
|
+
onwebkittransitionend: block,
|
|
224
|
+
onwheel: block,
|
|
225
|
+
};
|
|
226
|
+
const defaultDOMGuards = {
|
|
227
|
+
elements: defaultDOMElementGuards,
|
|
228
|
+
aspects: {
|
|
229
|
+
[DOMAspect.attribute]: Object.assign({}, blockedEvents),
|
|
230
|
+
[DOMAspect.property]: Object.assign({ innerHTML: block }, blockedEvents),
|
|
231
|
+
[DOMAspect.event]: Object.assign({}, blockedEvents),
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
function createDomSinkGuards(config, defaults) {
|
|
235
|
+
const result = {};
|
|
236
|
+
for (const name in defaults) {
|
|
237
|
+
const overrideValue = config[name];
|
|
238
|
+
const defaultValue = defaults[name];
|
|
239
|
+
switch (overrideValue) {
|
|
240
|
+
case null:
|
|
241
|
+
// remove the default
|
|
242
|
+
break;
|
|
243
|
+
case undefined:
|
|
244
|
+
// keep the default
|
|
245
|
+
result[name] = defaultValue;
|
|
246
|
+
break;
|
|
247
|
+
default:
|
|
248
|
+
// override the default
|
|
249
|
+
result[name] = overrideValue;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// add any new sinks that were not overrides
|
|
254
|
+
for (const name in config) {
|
|
255
|
+
if (!(name in result)) {
|
|
256
|
+
result[name] = config[name];
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return Object.freeze(result);
|
|
260
|
+
}
|
|
261
|
+
function createDOMAspectGuards(config, defaults) {
|
|
262
|
+
const result = {};
|
|
263
|
+
for (const aspect in defaults) {
|
|
264
|
+
const overrideValue = config[aspect];
|
|
265
|
+
const defaultValue = defaults[aspect];
|
|
266
|
+
switch (overrideValue) {
|
|
267
|
+
case null:
|
|
268
|
+
// remove the default
|
|
269
|
+
break;
|
|
270
|
+
case undefined:
|
|
271
|
+
// keep the default
|
|
272
|
+
result[aspect] = createDomSinkGuards(defaultValue, {});
|
|
273
|
+
break;
|
|
274
|
+
default:
|
|
275
|
+
// override the default
|
|
276
|
+
result[aspect] = createDomSinkGuards(overrideValue, defaultValue);
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// add any new aspect guards that were not overrides
|
|
281
|
+
for (const aspect in config) {
|
|
282
|
+
if (!(aspect in result)) {
|
|
283
|
+
result[aspect] = createDomSinkGuards(config[aspect], {});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return Object.freeze(result);
|
|
287
|
+
}
|
|
288
|
+
function createElementGuards(config, defaults) {
|
|
289
|
+
const result = {};
|
|
290
|
+
for (const tag in defaults) {
|
|
291
|
+
const overrideValue = config[tag];
|
|
292
|
+
const defaultValue = defaults[tag];
|
|
293
|
+
switch (overrideValue) {
|
|
294
|
+
case null:
|
|
295
|
+
// remove the default
|
|
296
|
+
break;
|
|
297
|
+
case undefined:
|
|
298
|
+
// keep the default
|
|
299
|
+
result[tag] = createDOMAspectGuards(defaultValue, {});
|
|
300
|
+
break;
|
|
301
|
+
default:
|
|
302
|
+
// override the default aspects
|
|
303
|
+
result[tag] = createDOMAspectGuards(overrideValue, defaultValue);
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// Add any new element guards that were not overrides
|
|
308
|
+
for (const tag in config) {
|
|
309
|
+
if (!(tag in result)) {
|
|
310
|
+
result[tag] = createDOMAspectGuards(config[tag], {});
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return Object.freeze(result);
|
|
314
|
+
}
|
|
315
|
+
function createDOMGuards(config, defaults) {
|
|
316
|
+
return Object.freeze({
|
|
317
|
+
elements: config.elements
|
|
318
|
+
? createElementGuards(config.elements, defaults.elements)
|
|
319
|
+
: defaults.elements,
|
|
320
|
+
aspects: config.aspects
|
|
321
|
+
? createDOMAspectGuards(config.aspects, defaults.aspects)
|
|
322
|
+
: defaults.aspects,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
function createTrustedType() {
|
|
326
|
+
const createHTML = html => html;
|
|
327
|
+
return globalThis.trustedTypes
|
|
328
|
+
? globalThis.trustedTypes.createPolicy("fast-element", { createHTML })
|
|
329
|
+
: { createHTML };
|
|
330
|
+
}
|
|
331
|
+
function tryGuard(aspectGuards, tagName, aspect, aspectName, sink) {
|
|
332
|
+
const sinkGuards = aspectGuards[aspect];
|
|
333
|
+
if (sinkGuards) {
|
|
334
|
+
const guard = sinkGuards[aspectName];
|
|
335
|
+
if (guard) {
|
|
336
|
+
return guard(tagName, aspect, aspectName, sink);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* A helper for creating DOM policies.
|
|
342
|
+
* @public
|
|
343
|
+
*/
|
|
344
|
+
export const DOMPolicy = Object.freeze({
|
|
345
|
+
/**
|
|
346
|
+
* Creates a new DOM Policy object.
|
|
347
|
+
* @param options - The options to use in creating the policy.
|
|
348
|
+
* @returns The newly created DOMPolicy.
|
|
349
|
+
*/
|
|
350
|
+
create(options = {}) {
|
|
351
|
+
var _a, _b;
|
|
352
|
+
const trustedType = (_a = options.trustedType) !== null && _a !== void 0 ? _a : createTrustedType();
|
|
353
|
+
const guards = createDOMGuards((_b = options.guards) !== null && _b !== void 0 ? _b : {}, defaultDOMGuards);
|
|
354
|
+
return Object.freeze({
|
|
355
|
+
createHTML(value) {
|
|
356
|
+
return trustedType.createHTML(value);
|
|
357
|
+
},
|
|
358
|
+
protect(tagName, aspect, aspectName, sink) {
|
|
359
|
+
var _a;
|
|
360
|
+
// Check for element-specific guards.
|
|
361
|
+
const key = (tagName !== null && tagName !== void 0 ? tagName : "").toLowerCase();
|
|
362
|
+
const elementGuards = guards.elements[key];
|
|
363
|
+
if (elementGuards) {
|
|
364
|
+
const guard = tryGuard(elementGuards, tagName, aspect, aspectName, sink);
|
|
365
|
+
if (guard) {
|
|
366
|
+
return guard;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
// Check for guards applicable to all nodes.
|
|
370
|
+
return ((_a = tryGuard(guards.aspects, tagName, aspect, aspectName, sink)) !== null && _a !== void 0 ? _a : sink);
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
},
|
|
374
|
+
});
|
package/dist/esm/dom.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Message } from "./interfaces.js";
|
|
2
|
+
import { FAST } from "./platform.js";
|
|
3
|
+
/**
|
|
4
|
+
* The type of HTML aspect to target.
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export const DOMAspect = Object.freeze({
|
|
8
|
+
/**
|
|
9
|
+
* Not aspected.
|
|
10
|
+
*/
|
|
11
|
+
none: 0,
|
|
12
|
+
/**
|
|
13
|
+
* An attribute.
|
|
14
|
+
*/
|
|
15
|
+
attribute: 1,
|
|
16
|
+
/**
|
|
17
|
+
* A boolean attribute.
|
|
18
|
+
*/
|
|
19
|
+
booleanAttribute: 2,
|
|
20
|
+
/**
|
|
21
|
+
* A property.
|
|
22
|
+
*/
|
|
23
|
+
property: 3,
|
|
24
|
+
/**
|
|
25
|
+
* Content
|
|
26
|
+
*/
|
|
27
|
+
content: 4,
|
|
28
|
+
/**
|
|
29
|
+
* A token list.
|
|
30
|
+
*/
|
|
31
|
+
tokenList: 5,
|
|
32
|
+
/**
|
|
33
|
+
* An event.
|
|
34
|
+
*/
|
|
35
|
+
event: 6,
|
|
36
|
+
});
|
|
37
|
+
const createHTML = html => html;
|
|
38
|
+
const fastTrustedType = globalThis.trustedTypes
|
|
39
|
+
? globalThis.trustedTypes.createPolicy("fast-element", { createHTML })
|
|
40
|
+
: { createHTML };
|
|
41
|
+
let defaultPolicy = Object.freeze({
|
|
42
|
+
createHTML(value) {
|
|
43
|
+
return fastTrustedType.createHTML(value);
|
|
44
|
+
},
|
|
45
|
+
protect(tagName, aspect, aspectName, sink) {
|
|
46
|
+
return sink;
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
const fastPolicy = defaultPolicy;
|
|
50
|
+
/**
|
|
51
|
+
* Common DOM APIs.
|
|
52
|
+
* @public
|
|
53
|
+
*/
|
|
54
|
+
export const DOM = Object.freeze({
|
|
55
|
+
/**
|
|
56
|
+
* Gets the dom policy used by the templating system.
|
|
57
|
+
*/
|
|
58
|
+
get policy() {
|
|
59
|
+
return defaultPolicy;
|
|
60
|
+
},
|
|
61
|
+
/**
|
|
62
|
+
* Sets the dom policy used by the templating system.
|
|
63
|
+
* @param policy - The policy to set.
|
|
64
|
+
* @remarks
|
|
65
|
+
* This API can only be called once, for security reasons. It should be
|
|
66
|
+
* called by the application developer at the start of their program.
|
|
67
|
+
*/
|
|
68
|
+
setPolicy(value) {
|
|
69
|
+
if (defaultPolicy !== fastPolicy) {
|
|
70
|
+
throw FAST.error(Message.onlySetDOMPolicyOnce);
|
|
71
|
+
}
|
|
72
|
+
defaultPolicy = value;
|
|
73
|
+
},
|
|
74
|
+
/**
|
|
75
|
+
* Sets an attribute value on an element.
|
|
76
|
+
* @param element - The element to set the attribute value on.
|
|
77
|
+
* @param attributeName - The attribute name to set.
|
|
78
|
+
* @param value - The value of the attribute to set.
|
|
79
|
+
* @remarks
|
|
80
|
+
* If the value is `null` or `undefined`, the attribute is removed, otherwise
|
|
81
|
+
* it is set to the provided value using the standard `setAttribute` API.
|
|
82
|
+
*/
|
|
83
|
+
setAttribute(element, attributeName, value) {
|
|
84
|
+
value === null || value === undefined
|
|
85
|
+
? element.removeAttribute(attributeName)
|
|
86
|
+
: element.setAttribute(attributeName, value);
|
|
87
|
+
},
|
|
88
|
+
/**
|
|
89
|
+
* Sets a boolean attribute value.
|
|
90
|
+
* @param element - The element to set the boolean attribute value on.
|
|
91
|
+
* @param attributeName - The attribute name to set.
|
|
92
|
+
* @param value - The value of the attribute to set.
|
|
93
|
+
* @remarks
|
|
94
|
+
* If the value is true, the attribute is added; otherwise it is removed.
|
|
95
|
+
*/
|
|
96
|
+
setBooleanAttribute(element, attributeName, value) {
|
|
97
|
+
value
|
|
98
|
+
? element.setAttribute(attributeName, "")
|
|
99
|
+
: element.removeAttribute(attributeName);
|
|
100
|
+
},
|
|
101
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { formatDefaultMismatchMessage, unknownHostName } from "./messages.js";
|
|
2
|
+
function formatMinimalMessage(hostName, detail) {
|
|
3
|
+
const host = (hostName !== null && hostName !== void 0 ? hostName : unknownHostName).toLowerCase();
|
|
4
|
+
return formatDefaultMismatchMessage(host, detail);
|
|
5
|
+
}
|
|
6
|
+
const defaultDiagnostic = {
|
|
7
|
+
formatBindingMismatch(_factory, _firstChild, _lastChild, hostName) {
|
|
8
|
+
return {
|
|
9
|
+
message: formatMinimalMessage(hostName, undefined),
|
|
10
|
+
};
|
|
11
|
+
},
|
|
12
|
+
formatStructuralError(_node, hostName, expectedDescription) {
|
|
13
|
+
return {
|
|
14
|
+
message: formatMinimalMessage(hostName, expectedDescription),
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
let activeDiagnostic = defaultDiagnostic;
|
|
19
|
+
/**
|
|
20
|
+
* Installs a {@link HydrationDiagnostic} as the active formatter for
|
|
21
|
+
* hydration mismatch errors. Called by `enableHydration()` when an opt-in
|
|
22
|
+
* debugger configuration is supplied; not exposed as `@public` because
|
|
23
|
+
* library consumers should always go through `enableHydration` to install
|
|
24
|
+
* a debugger.
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export function installHydrationDiagnostic(diagnostic) {
|
|
28
|
+
activeDiagnostic = diagnostic;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Returns the currently active {@link HydrationDiagnostic} — either the
|
|
32
|
+
* minimal default or one installed by an opt-in debugger.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export function getHydrationDiagnostic() {
|
|
36
|
+
return activeDiagnostic;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Reads the host element's tag name from any node inside a hydration view.
|
|
40
|
+
* Returns `undefined` when the node is not inside a shadow root.
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export function getHostName(node) {
|
|
44
|
+
var _a;
|
|
45
|
+
if (!node) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const root = node.getRootNode();
|
|
49
|
+
return (_a = root.host) === null || _a === void 0 ? void 0 : _a.nodeName;
|
|
50
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { deferHydrationAttribute, enableHydration, StopHydration, } from "../components/enable-hydration.js";
|
|
2
|
+
export { isHydratable } from "../components/hydration.js";
|
|
3
|
+
export { HydrationTracker } from "../components/hydration-tracker.js";
|
|
4
|
+
export { DOMPolicy, } from "../dom-policy.js";
|
|
5
|
+
export { HydrationBindingError, HydrationStage, } from "../templating/hydration-view.js";
|
|
6
|
+
export { hydrationDebugger } from "./hydration-debugger.js";
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { DOMAspect } from "../dom.js";
|
|
2
|
+
import { aspectLabelAttribute, aspectLabelBooleanAttribute, aspectLabelContent, aspectLabelEvent, aspectLabelProperty, aspectLabelTokenList, aspectLabelUnknown, formatAspect, formatExpectedTarget, formatRichMismatchMessage, unknownHostName, } from "./messages.js";
|
|
3
|
+
const aspectLabelsByCode = Object.freeze({
|
|
4
|
+
[DOMAspect.attribute]: aspectLabelAttribute,
|
|
5
|
+
[DOMAspect.booleanAttribute]: aspectLabelBooleanAttribute,
|
|
6
|
+
[DOMAspect.property]: aspectLabelProperty,
|
|
7
|
+
[DOMAspect.content]: aspectLabelContent,
|
|
8
|
+
[DOMAspect.tokenList]: aspectLabelTokenList,
|
|
9
|
+
[DOMAspect.event]: aspectLabelEvent,
|
|
10
|
+
});
|
|
11
|
+
const defaultSnippetLength = 500;
|
|
12
|
+
function describeAspect(aspectType, sourceAspect) {
|
|
13
|
+
var _a;
|
|
14
|
+
const base = aspectType !== undefined
|
|
15
|
+
? ((_a = aspectLabelsByCode[aspectType]) !== null && _a !== void 0 ? _a : aspectLabelUnknown)
|
|
16
|
+
: aspectLabelUnknown;
|
|
17
|
+
return formatAspect(base, sourceAspect);
|
|
18
|
+
}
|
|
19
|
+
function describeExpectedTarget(factory) {
|
|
20
|
+
var _a;
|
|
21
|
+
const aspectType = factory.aspectType;
|
|
22
|
+
const sourceAspect = factory.sourceAspect;
|
|
23
|
+
return {
|
|
24
|
+
tagName: (_a = factory.targetTagName) !== null && _a !== void 0 ? _a : null,
|
|
25
|
+
aspect: describeAspect(aspectType, sourceAspect),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function stripEmptyComments(root) {
|
|
29
|
+
var _a;
|
|
30
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_COMMENT);
|
|
31
|
+
const empties = [];
|
|
32
|
+
let current;
|
|
33
|
+
while ((current = walker.nextNode()) !== null) {
|
|
34
|
+
if (current.data === "") {
|
|
35
|
+
empties.push(current);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (const comment of empties) {
|
|
39
|
+
(_a = comment.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(comment);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function truncate(value, maxLength) {
|
|
43
|
+
return value.length > maxLength ? `${value.slice(0, maxLength)}…` : value;
|
|
44
|
+
}
|
|
45
|
+
function serializeNodeForError(node, maxLength = defaultSnippetLength) {
|
|
46
|
+
const wrapper = document.createElement("div");
|
|
47
|
+
wrapper.appendChild(node.cloneNode(true));
|
|
48
|
+
stripEmptyComments(wrapper);
|
|
49
|
+
return truncate(wrapper.innerHTML.trim(), maxLength);
|
|
50
|
+
}
|
|
51
|
+
function serializeRangeForError(first, last, maxLength = defaultSnippetLength) {
|
|
52
|
+
const wrapper = document.createElement("div");
|
|
53
|
+
let current = first;
|
|
54
|
+
while (current !== null) {
|
|
55
|
+
wrapper.appendChild(current.cloneNode(true));
|
|
56
|
+
if (current === last) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
current = current.nextSibling;
|
|
60
|
+
}
|
|
61
|
+
stripEmptyComments(wrapper);
|
|
62
|
+
return truncate(wrapper.innerHTML.trim(), maxLength);
|
|
63
|
+
}
|
|
64
|
+
function formatMismatchMessage(hostName, expected, received) {
|
|
65
|
+
const host = (hostName !== null && hostName !== void 0 ? hostName : unknownHostName).toLowerCase();
|
|
66
|
+
const expectedText = typeof expected === "string"
|
|
67
|
+
? expected
|
|
68
|
+
: formatExpectedTarget(expected.tagName, expected.aspect);
|
|
69
|
+
return formatRichMismatchMessage(host, expectedText, received.html);
|
|
70
|
+
}
|
|
71
|
+
const richDiagnostic = {
|
|
72
|
+
formatBindingMismatch(factory, firstChild, lastChild, hostName) {
|
|
73
|
+
const expected = describeExpectedTarget(factory);
|
|
74
|
+
const received = {
|
|
75
|
+
html: serializeRangeForError(firstChild, lastChild),
|
|
76
|
+
};
|
|
77
|
+
const result = {
|
|
78
|
+
message: formatMismatchMessage(hostName, expected, received),
|
|
79
|
+
expected,
|
|
80
|
+
received,
|
|
81
|
+
};
|
|
82
|
+
return result;
|
|
83
|
+
},
|
|
84
|
+
formatStructuralError(node, hostName, expectedDescription) {
|
|
85
|
+
const received = {
|
|
86
|
+
html: serializeNodeForError(node),
|
|
87
|
+
};
|
|
88
|
+
const result = {
|
|
89
|
+
message: formatMismatchMessage(hostName, expectedDescription, received),
|
|
90
|
+
expected: expectedDescription,
|
|
91
|
+
received,
|
|
92
|
+
};
|
|
93
|
+
return result;
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Returns a {@link HydrationDebugger} that, when supplied to
|
|
98
|
+
* `enableHydration({ debugger })`, installs the rich hydration mismatch
|
|
99
|
+
* formatter: a single-line "Expected … / Received …" message plus an HTML
|
|
100
|
+
* snippet of the SSR DOM and structured `expected`/`received` fields on
|
|
101
|
+
* the thrown error (both `HydrationBindingError` and
|
|
102
|
+
* `HydrationTargetElementError`).
|
|
103
|
+
*
|
|
104
|
+
* Without the debugger, hydration errors emit only a minimal one-line
|
|
105
|
+
* message pointing at this function — keeping the runtime hydration cost
|
|
106
|
+
* small for production bundles that do not need rich diagnostics.
|
|
107
|
+
*
|
|
108
|
+
* @public
|
|
109
|
+
*/
|
|
110
|
+
export function hydrationDebugger() {
|
|
111
|
+
return { diagnostic: richDiagnostic };
|
|
112
|
+
}
|