@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.
Files changed (250) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/command/command.api.json +7857 -0
  3. package/dist/context/context.api.json +1084 -0
  4. package/dist/declarative/declarative.api.json +8130 -0
  5. package/dist/definition-schema/definition-schema.api.json +2689 -0
  6. package/dist/di/di.api.json +4945 -0
  7. package/dist/dts/arrays.d.ts +2 -0
  8. package/dist/dts/binding/binding.d.ts +59 -0
  9. package/dist/dts/binding/exports.d.ts +9 -0
  10. package/dist/dts/binding/normalize.d.ts +9 -0
  11. package/dist/dts/binding/one-time.d.ts +11 -0
  12. package/dist/dts/binding/one-way.d.ts +20 -0
  13. package/dist/dts/binding/signal.d.ts +36 -0
  14. package/dist/dts/binding/two-way.d.ts +44 -0
  15. package/dist/dts/command/behavior.d.ts +94 -0
  16. package/dist/dts/command/behaviors/confirm-behavior.d.ts +139 -0
  17. package/dist/dts/command/behaviors/undo-behavior.d.ts +178 -0
  18. package/dist/dts/command/command.d.ts +79 -0
  19. package/dist/dts/command/component-registry.d.ts +50 -0
  20. package/dist/dts/command/components/confirm-dialog.d.ts +117 -0
  21. package/dist/dts/command/index.d.ts +21 -0
  22. package/dist/dts/command/registry.d.ts +201 -0
  23. package/dist/dts/command/schema-validation.d.ts +45 -0
  24. package/dist/dts/command/types.d.ts +332 -0
  25. package/dist/dts/command/validation.d.ts +116 -0
  26. package/dist/dts/command/weak-ref.d.ts +11 -0
  27. package/dist/dts/components/attributes.d.ts +153 -0
  28. package/dist/dts/components/definition-schema-transforms.d.ts +9 -0
  29. package/dist/dts/components/element-controller.d.ts +349 -0
  30. package/dist/dts/components/element-hydration.d.ts +2 -0
  31. package/dist/dts/components/enable-hydration.d.ts +66 -0
  32. package/dist/dts/components/fast-definitions.d.ts +211 -0
  33. package/dist/dts/components/fast-element-registry.d.ts +23 -0
  34. package/dist/dts/components/fast-element.d.ts +91 -0
  35. package/dist/dts/components/hydration-tracker.d.ts +110 -0
  36. package/dist/dts/components/hydration.d.ts +52 -0
  37. package/dist/dts/components/schema.d.ts +205 -0
  38. package/dist/dts/context.d.ts +171 -0
  39. package/dist/dts/debug.d.ts +5 -0
  40. package/dist/dts/declarative/attribute-map.d.ts +58 -0
  41. package/dist/dts/declarative/debug.d.ts +4 -0
  42. package/dist/dts/declarative/index.d.ts +14 -0
  43. package/dist/dts/declarative/interfaces.d.ts +8 -0
  44. package/dist/dts/declarative/observer-map-utilities.d.ts +58 -0
  45. package/dist/dts/declarative/observer-map.d.ts +89 -0
  46. package/dist/dts/declarative/runtime.d.ts +5 -0
  47. package/dist/dts/declarative/syntax.d.ts +21 -0
  48. package/dist/dts/declarative/template-bridge.d.ts +33 -0
  49. package/dist/dts/declarative/template-parser.d.ts +98 -0
  50. package/dist/dts/declarative/template.d.ts +9 -0
  51. package/dist/dts/declarative/utilities.d.ts +358 -0
  52. package/dist/dts/definition-schema/api.d.ts +42 -0
  53. package/dist/dts/definition-schema/cem.d.ts +78 -0
  54. package/dist/dts/definition-schema/extension.d.ts +18 -0
  55. package/dist/dts/definition-schema/extract.d.ts +38 -0
  56. package/dist/dts/definition-schema/index.d.ts +9 -0
  57. package/dist/dts/definition-schema/storage.d.ts +35 -0
  58. package/dist/dts/definition-schema/types.d.ts +176 -0
  59. package/dist/dts/dev-mode.d.ts +13 -0
  60. package/dist/dts/di/di.d.ts +894 -0
  61. package/dist/dts/dom-policy.d.ts +101 -0
  62. package/dist/dts/dom.d.ts +88 -0
  63. package/dist/dts/hydration/diagnostics.d.ts +93 -0
  64. package/dist/dts/hydration/exports.d.ts +18 -0
  65. package/dist/dts/hydration/hydration-debugger.d.ts +35 -0
  66. package/dist/dts/hydration/messages.d.ts +62 -0
  67. package/dist/dts/hydration/runtime.d.ts +7 -0
  68. package/dist/dts/hydration/target-builder.d.ts +107 -0
  69. package/dist/dts/index.d.ts +51 -0
  70. package/dist/dts/index.debug.d.ts +1 -0
  71. package/dist/dts/index.rollup.d.ts +1 -0
  72. package/dist/dts/index.rollup.debug.d.ts +1 -0
  73. package/dist/dts/interfaces.d.ts +106 -0
  74. package/dist/dts/metadata.d.ts +26 -0
  75. package/dist/dts/observation/arrays.d.ts +248 -0
  76. package/dist/dts/observation/notifier.d.ts +127 -0
  77. package/dist/dts/observation/observable.d.ts +276 -0
  78. package/dist/dts/observation/update-queue.d.ts +40 -0
  79. package/dist/dts/observation/volatile.d.ts +9 -0
  80. package/dist/dts/platform.d.ts +87 -0
  81. package/dist/dts/registry.d.ts +2 -0
  82. package/dist/dts/render.d.ts +7 -0
  83. package/dist/dts/schema.d.ts +1 -0
  84. package/dist/dts/scoped/detection.d.ts +55 -0
  85. package/dist/dts/scoped/index.d.ts +68 -0
  86. package/dist/dts/scoped/mixin.d.ts +118 -0
  87. package/dist/dts/scoped/registry.d.ts +76 -0
  88. package/dist/dts/scoped/types.d.ts +48 -0
  89. package/dist/dts/state/exports.d.ts +3 -0
  90. package/dist/dts/state/reactive.d.ts +8 -0
  91. package/dist/dts/state/state.d.ts +141 -0
  92. package/dist/dts/state/visitor.d.ts +6 -0
  93. package/dist/dts/state/watch.d.ts +10 -0
  94. package/dist/dts/styles/css-directive.d.ts +50 -0
  95. package/dist/dts/styles/css.d.ts +34 -0
  96. package/dist/dts/styles/element-styles.d.ts +61 -0
  97. package/dist/dts/styles/host.d.ts +65 -0
  98. package/dist/dts/styles/style-strategy.d.ts +42 -0
  99. package/dist/dts/templating/children.d.ts +62 -0
  100. package/dist/dts/templating/compiler.d.ts +54 -0
  101. package/dist/dts/templating/html-binding-directive.d.ts +155 -0
  102. package/dist/dts/templating/html-directive.d.ts +218 -0
  103. package/dist/dts/templating/html.d.ts +1 -0
  104. package/dist/dts/templating/hydration-view.d.ts +130 -0
  105. package/dist/dts/templating/markup.d.ts +48 -0
  106. package/dist/dts/templating/node-observation.d.ts +99 -0
  107. package/dist/dts/templating/ref.d.ts +23 -0
  108. package/dist/dts/templating/render.d.ts +318 -0
  109. package/dist/dts/templating/repeat.d.ts +131 -0
  110. package/dist/dts/templating/slotted.d.ts +38 -0
  111. package/dist/dts/templating/template.d.ts +221 -0
  112. package/dist/dts/templating/view.d.ts +268 -0
  113. package/dist/dts/templating/when.d.ts +12 -0
  114. package/dist/dts/testing/exports.d.ts +3 -0
  115. package/dist/dts/testing/fakes.d.ts +15 -0
  116. package/dist/dts/testing/fixture.d.ts +84 -0
  117. package/dist/dts/testing/models.d.ts +20 -0
  118. package/dist/dts/testing/timeout.d.ts +7 -0
  119. package/dist/dts/trust/index.d.ts +8 -0
  120. package/dist/dts/trust/types.d.ts +48 -0
  121. package/dist/dts/trust/utils.d.ts +26 -0
  122. package/dist/dts/tsdoc-metadata.json +11 -0
  123. package/dist/dts/utilities.d.ts +76 -0
  124. package/dist/esm/arrays.js +1 -0
  125. package/dist/esm/binding/binding.js +18 -0
  126. package/dist/esm/binding/exports.js +6 -0
  127. package/dist/esm/binding/normalize.js +17 -0
  128. package/dist/esm/binding/one-time.js +21 -0
  129. package/dist/esm/binding/one-way.js +30 -0
  130. package/dist/esm/binding/signal.js +99 -0
  131. package/dist/esm/binding/two-way.js +110 -0
  132. package/dist/esm/command/behavior.js +155 -0
  133. package/dist/esm/command/behaviors/confirm-behavior.js +225 -0
  134. package/dist/esm/command/behaviors/undo-behavior.js +312 -0
  135. package/dist/esm/command/command.js +104 -0
  136. package/dist/esm/command/component-registry.js +107 -0
  137. package/dist/esm/command/components/confirm-dialog.js +370 -0
  138. package/dist/esm/command/index.js +22 -0
  139. package/dist/esm/command/registry.js +752 -0
  140. package/dist/esm/command/schema-validation.js +194 -0
  141. package/dist/esm/command/types.js +86 -0
  142. package/dist/esm/command/validation.js +511 -0
  143. package/dist/esm/command/weak-ref.js +5 -0
  144. package/dist/esm/components/attributes.js +219 -0
  145. package/dist/esm/components/definition-schema-transforms.js +23 -0
  146. package/dist/esm/components/element-controller.js +839 -0
  147. package/dist/esm/components/element-hydration.js +2 -0
  148. package/dist/esm/components/enable-hydration.js +123 -0
  149. package/dist/esm/components/fast-definitions.js +294 -0
  150. package/dist/esm/components/fast-element-registry.js +67 -0
  151. package/dist/esm/components/fast-element.js +82 -0
  152. package/dist/esm/components/hydration-tracker.js +210 -0
  153. package/dist/esm/components/hydration.js +187 -0
  154. package/dist/esm/components/schema.js +253 -0
  155. package/dist/esm/context.js +185 -0
  156. package/dist/esm/debug.js +71 -0
  157. package/dist/esm/declarative/attribute-map.js +121 -0
  158. package/dist/esm/declarative/debug.js +4 -0
  159. package/dist/esm/declarative/index.js +10 -0
  160. package/dist/esm/declarative/interfaces.js +9 -0
  161. package/dist/esm/declarative/observer-map-utilities.js +565 -0
  162. package/dist/esm/declarative/observer-map.js +216 -0
  163. package/dist/esm/declarative/runtime.js +14 -0
  164. package/dist/esm/declarative/syntax.js +36 -0
  165. package/dist/esm/declarative/template-bridge.js +160 -0
  166. package/dist/esm/declarative/template-parser.js +306 -0
  167. package/dist/esm/declarative/template.js +116 -0
  168. package/dist/esm/declarative/utilities.js +1069 -0
  169. package/dist/esm/definition-schema/api.js +129 -0
  170. package/dist/esm/definition-schema/cem.js +89 -0
  171. package/dist/esm/definition-schema/extension.js +53 -0
  172. package/dist/esm/definition-schema/extract.js +167 -0
  173. package/dist/esm/definition-schema/index.js +8 -0
  174. package/dist/esm/definition-schema/storage.js +58 -0
  175. package/dist/esm/definition-schema/types.js +8 -0
  176. package/dist/esm/dev-mode.js +22 -0
  177. package/dist/esm/di/di.js +1440 -0
  178. package/dist/esm/dom-policy.js +374 -0
  179. package/dist/esm/dom.js +101 -0
  180. package/dist/esm/hydration/diagnostics.js +50 -0
  181. package/dist/esm/hydration/exports.js +6 -0
  182. package/dist/esm/hydration/hydration-debugger.js +112 -0
  183. package/dist/esm/hydration/messages.js +84 -0
  184. package/dist/esm/hydration/runtime.js +33 -0
  185. package/dist/esm/hydration/target-builder.js +264 -0
  186. package/dist/esm/index.debug.js +3 -0
  187. package/dist/esm/index.js +49 -0
  188. package/dist/esm/index.rollup.debug.js +6 -0
  189. package/dist/esm/index.rollup.js +4 -0
  190. package/dist/esm/interfaces.js +55 -0
  191. package/dist/esm/metadata.js +63 -0
  192. package/dist/esm/observation/arrays.js +661 -0
  193. package/dist/esm/observation/notifier.js +164 -0
  194. package/dist/esm/observation/observable.js +324 -0
  195. package/dist/esm/observation/update-queue.js +56 -0
  196. package/dist/esm/observation/volatile.js +16 -0
  197. package/dist/esm/platform.js +98 -0
  198. package/dist/esm/registry.js +2 -0
  199. package/dist/esm/render.js +1 -0
  200. package/dist/esm/schema.js +1 -0
  201. package/dist/esm/scoped/detection.js +102 -0
  202. package/dist/esm/scoped/index.js +69 -0
  203. package/dist/esm/scoped/mixin.js +127 -0
  204. package/dist/esm/scoped/registry.js +125 -0
  205. package/dist/esm/scoped/types.js +4 -0
  206. package/dist/esm/state/exports.js +3 -0
  207. package/dist/esm/state/reactive.js +34 -0
  208. package/dist/esm/state/state.js +148 -0
  209. package/dist/esm/state/visitor.js +28 -0
  210. package/dist/esm/state/watch.js +36 -0
  211. package/dist/esm/styles/css-directive.js +36 -0
  212. package/dist/esm/styles/css.js +56 -0
  213. package/dist/esm/styles/element-styles.js +144 -0
  214. package/dist/esm/styles/host.js +1 -0
  215. package/dist/esm/styles/style-strategy.js +1 -0
  216. package/dist/esm/templating/children.js +67 -0
  217. package/dist/esm/templating/compiler.js +359 -0
  218. package/dist/esm/templating/html-binding-directive.js +288 -0
  219. package/dist/esm/templating/html-directive.js +113 -0
  220. package/dist/esm/templating/html.js +1 -0
  221. package/dist/esm/templating/hydration-view.js +228 -0
  222. package/dist/esm/templating/markup.js +83 -0
  223. package/dist/esm/templating/node-observation.js +84 -0
  224. package/dist/esm/templating/ref.js +21 -0
  225. package/dist/esm/templating/render.js +468 -0
  226. package/dist/esm/templating/repeat.js +434 -0
  227. package/dist/esm/templating/slotted.js +49 -0
  228. package/dist/esm/templating/template.js +206 -0
  229. package/dist/esm/templating/view.js +298 -0
  230. package/dist/esm/templating/when.js +22 -0
  231. package/dist/esm/testing/exports.js +3 -0
  232. package/dist/esm/testing/fakes.js +107 -0
  233. package/dist/esm/testing/fixture.js +86 -0
  234. package/dist/esm/testing/models.js +58 -0
  235. package/dist/esm/testing/timeout.js +24 -0
  236. package/dist/esm/trust/index.js +7 -0
  237. package/dist/esm/trust/types.js +6 -0
  238. package/dist/esm/trust/utils.js +126 -0
  239. package/dist/esm/utilities.js +140 -0
  240. package/dist/fast-element.api.json +26798 -0
  241. package/dist/fast-element.d.ts +3985 -0
  242. package/dist/fast-element.debug.js +7618 -0
  243. package/dist/fast-element.debug.min.js +3 -0
  244. package/dist/fast-element.js +7617 -0
  245. package/dist/fast-element.min.js +3 -0
  246. package/dist/fast-element.untrimmed.d.ts +4103 -0
  247. package/dist/observation/arrays/arrays.api.json +2621 -0
  248. package/dist/scoped/scoped.api.json +891 -0
  249. package/dist/trust/trust.api.json +629 -0
  250. 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
+ });
@@ -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
+ }