@remote-dom/polyfill 1.5.1 → 1.6.0

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 (304) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +51 -3
  3. package/build/cjs/Attr.cjs +33 -4
  4. package/build/cjs/CharacterData.cjs +10 -0
  5. package/build/cjs/ChildNode.cjs +79 -13
  6. package/build/cjs/Comment.cjs +1 -1
  7. package/build/cjs/CustomElementRegistry.cjs +27 -2
  8. package/build/cjs/CustomEvent.cjs +2 -2
  9. package/build/cjs/Document.cjs +56 -32
  10. package/build/cjs/DocumentFragment.cjs +6 -2
  11. package/build/cjs/Element.cjs +68 -8
  12. package/build/cjs/Event.cjs +29 -27
  13. package/build/cjs/EventTarget.cjs +128 -58
  14. package/build/cjs/HTMLTemplateElement.cjs +1 -0
  15. package/build/cjs/MutationObserver.cjs +167 -1
  16. package/build/cjs/NamedNodeMap.cjs +82 -45
  17. package/build/cjs/Node.cjs +47 -11
  18. package/build/cjs/NodeList.cjs +9 -1
  19. package/build/cjs/ParentNode.cjs +319 -77
  20. package/build/cjs/SVGElement.cjs +1 -1
  21. package/build/cjs/Text.cjs +1 -1
  22. package/build/cjs/Window.cjs +131 -38
  23. package/build/cjs/attribute-reactions.cjs +20 -0
  24. package/build/cjs/constants.cjs +48 -24
  25. package/build/cjs/custom-element-reactions.cjs +52 -0
  26. package/build/cjs/dom-exception.cjs +15 -0
  27. package/build/cjs/hook-effects.cjs +51 -0
  28. package/build/cjs/names.cjs +61 -0
  29. package/build/cjs/selectors.cjs +213 -122
  30. package/build/cjs/serialization.cjs +168 -65
  31. package/build/cjs/shared.cjs +177 -28
  32. package/build/esm/Attr.mjs +34 -5
  33. package/build/esm/CharacterData.mjs +10 -0
  34. package/build/esm/ChildNode.mjs +76 -15
  35. package/build/esm/Comment.mjs +2 -2
  36. package/build/esm/CustomElementRegistry.mjs +27 -2
  37. package/build/esm/CustomEvent.mjs +2 -2
  38. package/build/esm/Document.mjs +60 -35
  39. package/build/esm/DocumentFragment.mjs +7 -3
  40. package/build/esm/Element.mjs +69 -9
  41. package/build/esm/Event.mjs +27 -27
  42. package/build/esm/EventTarget.mjs +130 -60
  43. package/build/esm/HTMLTemplateElement.mjs +2 -1
  44. package/build/esm/MutationObserver.mjs +166 -2
  45. package/build/esm/NamedNodeMap.mjs +83 -46
  46. package/build/esm/Node.mjs +48 -12
  47. package/build/esm/NodeList.mjs +9 -1
  48. package/build/esm/ParentNode.mjs +322 -81
  49. package/build/esm/SVGElement.mjs +2 -2
  50. package/build/esm/Text.mjs +2 -2
  51. package/build/esm/Window.mjs +132 -39
  52. package/build/esm/attribute-reactions.mjs +16 -0
  53. package/build/esm/constants.mjs +28 -23
  54. package/build/esm/custom-element-reactions.mjs +47 -0
  55. package/build/esm/dom-exception.mjs +11 -0
  56. package/build/esm/hook-effects.mjs +46 -0
  57. package/build/esm/names.mjs +54 -0
  58. package/build/esm/selectors.mjs +202 -124
  59. package/build/esm/serialization.mjs +169 -66
  60. package/build/esm/shared.mjs +173 -30
  61. package/build/esnext/Attr.esnext +45 -5
  62. package/build/esnext/CharacterData.esnext +10 -0
  63. package/build/esnext/ChildNode.esnext +84 -15
  64. package/build/esnext/Comment.esnext +2 -2
  65. package/build/esnext/CustomElementRegistry.esnext +42 -0
  66. package/build/esnext/CustomEvent.esnext +2 -2
  67. package/build/esnext/Document.esnext +69 -32
  68. package/build/esnext/DocumentFragment.esnext +6 -2
  69. package/build/esnext/Element.esnext +78 -9
  70. package/build/esnext/Event.esnext +36 -37
  71. package/build/esnext/EventTarget.esnext +133 -61
  72. package/build/esnext/HTMLTemplateElement.esnext +3 -1
  73. package/build/esnext/MutationObserver.esnext +163 -2
  74. package/build/esnext/NamedNodeMap.esnext +110 -42
  75. package/build/esnext/Node.esnext +50 -12
  76. package/build/esnext/NodeList.esnext +1 -1
  77. package/build/esnext/ParentNode.esnext +352 -79
  78. package/build/esnext/SVGElement.esnext +2 -2
  79. package/build/esnext/Text.esnext +2 -2
  80. package/build/esnext/Window.esnext +120 -16
  81. package/build/esnext/attribute-reactions.esnext +21 -0
  82. package/build/esnext/constants.esnext +34 -21
  83. package/build/esnext/custom-element-reactions.esnext +49 -0
  84. package/build/esnext/dom-exception.esnext +11 -0
  85. package/build/esnext/hook-effects.esnext +46 -0
  86. package/build/esnext/names.esnext +61 -0
  87. package/build/esnext/selectors.esnext +202 -100
  88. package/build/esnext/serialization.esnext +171 -48
  89. package/build/esnext/shared.esnext +181 -34
  90. package/build/tsconfig.tsbuildinfo +1 -1
  91. package/build/typescript/Attr.d.ts +6 -4
  92. package/build/typescript/Attr.d.ts.map +1 -1
  93. package/build/typescript/CharacterData.d.ts.map +1 -1
  94. package/build/typescript/ChildNode.d.ts +5 -0
  95. package/build/typescript/ChildNode.d.ts.map +1 -1
  96. package/build/typescript/ClipboardEvent.d.ts.map +1 -1
  97. package/build/typescript/Comment.d.ts +2 -2
  98. package/build/typescript/Comment.d.ts.map +1 -1
  99. package/build/typescript/CustomElementRegistry.d.ts +1 -0
  100. package/build/typescript/CustomElementRegistry.d.ts.map +1 -1
  101. package/build/typescript/CustomEvent.d.ts.map +1 -1
  102. package/build/typescript/Document.d.ts +10 -5
  103. package/build/typescript/Document.d.ts.map +1 -1
  104. package/build/typescript/DocumentFragment.d.ts +2 -1
  105. package/build/typescript/DocumentFragment.d.ts.map +1 -1
  106. package/build/typescript/Element.d.ts +16 -7
  107. package/build/typescript/Element.d.ts.map +1 -1
  108. package/build/typescript/ErrorEvent.d.ts.map +1 -1
  109. package/build/typescript/Event.d.ts +9 -10
  110. package/build/typescript/Event.d.ts.map +1 -1
  111. package/build/typescript/EventTarget.d.ts +20 -3
  112. package/build/typescript/EventTarget.d.ts.map +1 -1
  113. package/build/typescript/FocusEvent.d.ts.map +1 -1
  114. package/build/typescript/HTMLTemplateElement.d.ts.map +1 -1
  115. package/build/typescript/MutationObserver.d.ts +42 -0
  116. package/build/typescript/MutationObserver.d.ts.map +1 -1
  117. package/build/typescript/NamedNodeMap.d.ts +5 -3
  118. package/build/typescript/NamedNodeMap.d.ts.map +1 -1
  119. package/build/typescript/Node.d.ts +4 -3
  120. package/build/typescript/Node.d.ts.map +1 -1
  121. package/build/typescript/NodeList.d.ts +3 -2
  122. package/build/typescript/NodeList.d.ts.map +1 -1
  123. package/build/typescript/ParentNode.d.ts +29 -10
  124. package/build/typescript/ParentNode.d.ts.map +1 -1
  125. package/build/typescript/PromiseRejectionEvent.d.ts.map +1 -1
  126. package/build/typescript/SVGElement.d.ts +1 -1
  127. package/build/typescript/SVGElement.d.ts.map +1 -1
  128. package/build/typescript/Text.d.ts +1 -1
  129. package/build/typescript/Text.d.ts.map +1 -1
  130. package/build/typescript/ToggleEvent.d.ts.map +1 -1
  131. package/build/typescript/Window.d.ts +5 -1
  132. package/build/typescript/Window.d.ts.map +1 -1
  133. package/build/typescript/attribute-reactions.d.ts +4 -0
  134. package/build/typescript/attribute-reactions.d.ts.map +1 -0
  135. package/build/typescript/constants.d.ts +27 -18
  136. package/build/typescript/constants.d.ts.map +1 -1
  137. package/build/typescript/custom-element-reactions.d.ts +6 -0
  138. package/build/typescript/custom-element-reactions.d.ts.map +1 -0
  139. package/build/typescript/dom-exception.d.ts +2 -0
  140. package/build/typescript/dom-exception.d.ts.map +1 -0
  141. package/build/typescript/extensions.d.ts +4 -0
  142. package/build/typescript/extensions.d.ts.map +1 -0
  143. package/build/typescript/hook-effects.d.ts +6 -0
  144. package/build/typescript/hook-effects.d.ts.map +1 -0
  145. package/build/typescript/hooks.d.ts +3 -3
  146. package/build/typescript/hooks.d.ts.map +1 -1
  147. package/build/typescript/index.d.ts +1 -0
  148. package/build/typescript/index.d.ts.map +1 -1
  149. package/build/typescript/names.d.ts +11 -0
  150. package/build/typescript/names.d.ts.map +1 -0
  151. package/build/typescript/selectors.d.ts +21 -22
  152. package/build/typescript/selectors.d.ts.map +1 -1
  153. package/build/typescript/serialization.d.ts.map +1 -1
  154. package/build/typescript/shared.d.ts +10 -0
  155. package/build/typescript/shared.d.ts.map +1 -1
  156. package/build/typescript/tests/ChildNode.test.d.ts +2 -0
  157. package/build/typescript/tests/ChildNode.test.d.ts.map +1 -0
  158. package/build/typescript/tests/MutationObserver.test.d.ts +2 -0
  159. package/build/typescript/tests/MutationObserver.test.d.ts.map +1 -0
  160. package/build/typescript/tests/adopt-inserted-subtrees.test.d.ts +2 -0
  161. package/build/typescript/tests/adopt-inserted-subtrees.test.d.ts.map +1 -0
  162. package/build/typescript/tests/attr-mutation.test.d.ts +2 -0
  163. package/build/typescript/tests/attr-mutation.test.d.ts.map +1 -0
  164. package/build/typescript/tests/child-node-before-after.test.d.ts +2 -0
  165. package/build/typescript/tests/child-node-before-after.test.d.ts.map +1 -0
  166. package/build/typescript/tests/child-node-replace-with.test.d.ts +2 -0
  167. package/build/typescript/tests/child-node-replace-with.test.d.ts.map +1 -0
  168. package/build/typescript/tests/clone-import-namespaces.test.d.ts +2 -0
  169. package/build/typescript/tests/clone-import-namespaces.test.d.ts.map +1 -0
  170. package/build/typescript/tests/constants.test.d.ts +2 -0
  171. package/build/typescript/tests/constants.test.d.ts.map +1 -0
  172. package/build/typescript/tests/create-element-namespaces.test.d.ts +2 -0
  173. package/build/typescript/tests/create-element-namespaces.test.d.ts.map +1 -0
  174. package/build/typescript/tests/create-text-node.test.d.ts +2 -0
  175. package/build/typescript/tests/create-text-node.test.d.ts.map +1 -0
  176. package/build/typescript/tests/custom-element-reactions.test.d.ts +2 -0
  177. package/build/typescript/tests/custom-element-reactions.test.d.ts.map +1 -0
  178. package/build/typescript/tests/custom-element-registry.test.d.ts +2 -0
  179. package/build/typescript/tests/custom-element-registry.test.d.ts.map +1 -0
  180. package/build/typescript/tests/custom-event.test.d.ts +2 -0
  181. package/build/typescript/tests/custom-event.test.d.ts.map +1 -0
  182. package/build/typescript/tests/document-clone-import-contract.test.d.ts +2 -0
  183. package/build/typescript/tests/document-clone-import-contract.test.d.ts.map +1 -0
  184. package/build/typescript/tests/document.test.d.ts +2 -0
  185. package/build/typescript/tests/document.test.d.ts.map +1 -0
  186. package/build/typescript/tests/dom-mutation-selector-errors.test.d.ts +2 -0
  187. package/build/typescript/tests/dom-mutation-selector-errors.test.d.ts.map +1 -0
  188. package/build/typescript/tests/event-dispatch.test.d.ts +2 -0
  189. package/build/typescript/tests/event-dispatch.test.d.ts.map +1 -0
  190. package/build/typescript/tests/event-target.test.d.ts +2 -0
  191. package/build/typescript/tests/event-target.test.d.ts.map +1 -0
  192. package/build/typescript/tests/event.test.d.ts +2 -0
  193. package/build/typescript/tests/event.test.d.ts.map +1 -0
  194. package/build/typescript/tests/extensions.test.d.ts +2 -0
  195. package/build/typescript/tests/extensions.test.d.ts.map +1 -0
  196. package/build/typescript/tests/get-elements-by-tag-name.test.d.ts +2 -0
  197. package/build/typescript/tests/get-elements-by-tag-name.test.d.ts.map +1 -0
  198. package/build/typescript/tests/getElementsByClassName.test.d.ts +2 -0
  199. package/build/typescript/tests/getElementsByClassName.test.d.ts.map +1 -0
  200. package/build/typescript/tests/hooks.test.d.ts +2 -0
  201. package/build/typescript/tests/hooks.test.d.ts.map +1 -0
  202. package/build/typescript/tests/inner-html-parsing.test.d.ts +2 -0
  203. package/build/typescript/tests/inner-html-parsing.test.d.ts.map +1 -0
  204. package/build/typescript/tests/is-default-namespace.test.d.ts +2 -0
  205. package/build/typescript/tests/is-default-namespace.test.d.ts.map +1 -0
  206. package/build/typescript/tests/name-and-namespace-normalization.test.d.ts +2 -0
  207. package/build/typescript/tests/name-and-namespace-normalization.test.d.ts.map +1 -0
  208. package/build/typescript/tests/named-node-map.test.d.ts +2 -0
  209. package/build/typescript/tests/named-node-map.test.d.ts.map +1 -0
  210. package/build/typescript/tests/namespaced-attribute-reactions.test.d.ts +2 -0
  211. package/build/typescript/tests/namespaced-attribute-reactions.test.d.ts.map +1 -0
  212. package/build/typescript/tests/node.test.d.ts +2 -0
  213. package/build/typescript/tests/node.test.d.ts.map +1 -0
  214. package/build/typescript/tests/parent-node-mutation-return-values.test.d.ts +2 -0
  215. package/build/typescript/tests/parent-node-mutation-return-values.test.d.ts.map +1 -0
  216. package/build/typescript/tests/parent-node-mutation-validation.test.d.ts +2 -0
  217. package/build/typescript/tests/parent-node-mutation-validation.test.d.ts.map +1 -0
  218. package/build/typescript/tests/parent-node.test.d.ts +2 -0
  219. package/build/typescript/tests/parent-node.test.d.ts.map +1 -0
  220. package/build/typescript/tests/serialization-template.test.d.ts +2 -0
  221. package/build/typescript/tests/serialization-template.test.d.ts.map +1 -0
  222. package/build/typescript/tests/slot-attribute.test.d.ts +2 -0
  223. package/build/typescript/tests/slot-attribute.test.d.ts.map +1 -0
  224. package/build/typescript/tests/text-content.test.d.ts +2 -0
  225. package/build/typescript/tests/text-content.test.d.ts.map +1 -0
  226. package/build/typescript/tests/toggle-attribute.test.d.ts +2 -0
  227. package/build/typescript/tests/toggle-attribute.test.d.ts.map +1 -0
  228. package/build/typescript/tests/wide-tree-traversal.test.d.ts +2 -0
  229. package/build/typescript/tests/wide-tree-traversal.test.d.ts.map +1 -0
  230. package/build/typescript/tests/window-set-global.test.d.ts +2 -0
  231. package/build/typescript/tests/window-set-global.test.d.ts.map +1 -0
  232. package/package.json +1 -1
  233. package/source/Attr.ts +60 -8
  234. package/source/CharacterData.ts +13 -0
  235. package/source/ChildNode.ts +107 -14
  236. package/source/Comment.ts +2 -2
  237. package/source/CustomElementRegistry.ts +56 -0
  238. package/source/CustomEvent.ts +2 -2
  239. package/source/Document.ts +104 -38
  240. package/source/DocumentFragment.ts +12 -2
  241. package/source/Element.ts +129 -14
  242. package/source/Event.ts +34 -32
  243. package/source/EventTarget.ts +203 -79
  244. package/source/HTMLTemplateElement.ts +2 -1
  245. package/source/MutationObserver.ts +279 -1
  246. package/source/NamedNodeMap.ts +141 -60
  247. package/source/Node.ts +70 -14
  248. package/source/NodeList.ts +13 -3
  249. package/source/ParentNode.ts +500 -88
  250. package/source/SVGElement.ts +2 -2
  251. package/source/Text.ts +2 -2
  252. package/source/Window.ts +156 -17
  253. package/source/attribute-reactions.ts +32 -0
  254. package/source/constants.ts +40 -17
  255. package/source/custom-element-reactions.ts +64 -0
  256. package/source/dom-exception.ts +14 -0
  257. package/source/extensions.ts +4 -0
  258. package/source/hook-effects.ts +56 -0
  259. package/source/hooks.ts +11 -3
  260. package/source/index.ts +1 -0
  261. package/source/names.ts +94 -0
  262. package/source/selectors.ts +301 -138
  263. package/source/serialization.ts +224 -66
  264. package/source/shared.ts +269 -40
  265. package/source/tests/ChildNode.test.ts +178 -0
  266. package/source/tests/MutationObserver.test.ts +303 -0
  267. package/source/tests/adopt-inserted-subtrees.test.ts +584 -0
  268. package/source/tests/attr-mutation.test.ts +112 -0
  269. package/source/tests/child-node-before-after.test.ts +421 -0
  270. package/source/tests/child-node-replace-with.test.ts +251 -0
  271. package/source/tests/clone-import-namespaces.test.ts +365 -0
  272. package/source/tests/constants.test.ts +46 -0
  273. package/source/tests/create-element-namespaces.test.ts +142 -0
  274. package/source/tests/create-text-node.test.ts +38 -0
  275. package/source/tests/custom-element-reactions.test.ts +600 -0
  276. package/source/tests/custom-element-registry.test.ts +137 -0
  277. package/source/tests/custom-event.test.ts +26 -0
  278. package/source/tests/document-clone-import-contract.test.ts +77 -0
  279. package/source/tests/document.test.ts +122 -0
  280. package/source/tests/dom-mutation-selector-errors.test.ts +484 -0
  281. package/source/tests/event-dispatch.test.ts +270 -0
  282. package/source/tests/event-target.test.ts +208 -0
  283. package/source/tests/event.test.ts +98 -0
  284. package/source/tests/extensions.test.ts +159 -0
  285. package/source/tests/get-elements-by-tag-name.test.ts +79 -0
  286. package/source/tests/getElementsByClassName.test.ts +109 -0
  287. package/source/tests/hooks.test.ts +43 -0
  288. package/source/tests/inner-html-parsing.test.ts +461 -0
  289. package/source/tests/is-default-namespace.test.ts +111 -0
  290. package/source/tests/name-and-namespace-normalization.test.ts +319 -0
  291. package/source/tests/named-node-map.test.ts +122 -0
  292. package/source/tests/namespaced-attribute-reactions.test.ts +141 -0
  293. package/source/tests/node.test.ts +56 -0
  294. package/source/tests/parent-node-mutation-return-values.test.ts +63 -0
  295. package/source/tests/parent-node-mutation-validation.test.ts +362 -0
  296. package/source/tests/parent-node.test.ts +169 -0
  297. package/source/tests/selectors.test.ts +533 -22
  298. package/source/tests/serialization-template.test.ts +232 -0
  299. package/source/tests/slot-attribute.test.ts +133 -0
  300. package/source/tests/text-content.test.ts +440 -0
  301. package/source/tests/toggle-attribute.test.ts +113 -0
  302. package/source/tests/wide-tree-traversal.test.ts +699 -0
  303. package/source/tests/window-set-global.test.ts +321 -0
  304. package/tsconfig.json +1 -1
@@ -1,6 +1,12 @@
1
- import { NEXT } from './constants.mjs';
1
+ import { PARENT, HOST, NEXT, PREV } from './constants.mjs';
2
+ import { performWithCustomElementReactions } from './custom-element-reactions.mjs';
3
+ import { performHookEffects } from './hook-effects.mjs';
4
+ import { createDOMException } from './dom-exception.mjs';
2
5
  import { Node } from './Node.mjs';
3
6
 
7
+ const INSERT_NODE = Symbol('insertNode');
8
+ const PREFLIGHT_INSERTIONS = Symbol('preflightInsertions');
9
+ const REPLACE_NODE = Symbol('replaceNode');
4
10
  class ChildNode extends Node {
5
11
  remove() {
6
12
  const parent = this.parentNode;
@@ -8,35 +14,90 @@ class ChildNode extends Node {
8
14
  parent.removeChild(this);
9
15
  }
10
16
  replaceWith(...nodes) {
17
+ const staged = stageNodes(nodes);
11
18
  const parent = this.parentNode;
12
19
  if (!parent) return;
13
- const node = toNode(parent, nodes[0]);
14
- const next = node[NEXT];
15
- parent.replaceChild(this, node);
16
- for (let i = 1; i < nodes.length; i++) {
17
- parent.insertBefore(toNode(parent, nodes[i]), next);
18
- }
20
+ return performChildNodeMutation(hookEffects => {
21
+ validateInsertionNodes(parent, staged);
22
+ let next = this[NEXT];
23
+ while (next && staged.includes(next)) next = next[NEXT];
24
+ const replacement = convertNodesIntoNode(parent, staged, hookEffects);
25
+ if (this.parentNode === parent) {
26
+ parent[REPLACE_NODE](replacement, this, hookEffects);
27
+ } else {
28
+ parent[INSERT_NODE](replacement, next, hookEffects);
29
+ }
30
+ });
19
31
  }
20
32
  before(...nodes) {
33
+ const staged = stageNodes(nodes);
21
34
  const parent = this.parentNode;
22
35
  if (!parent) return;
23
- for (const node of nodes) {
24
- parent.insertBefore(toNode(parent, node), this);
25
- }
36
+ return performChildNodeMutation(hookEffects => {
37
+ validateInsertionNodes(parent, staged);
38
+ let previous = this[PREV];
39
+ while (previous && staged.includes(previous)) previous = previous[PREV];
40
+ const node = convertNodesIntoNode(parent, staged, hookEffects);
41
+ parent[INSERT_NODE](node, previous ? previous[NEXT] : parent.firstChild, hookEffects);
42
+ });
26
43
  }
27
44
  after(...nodes) {
45
+ const staged = stageNodes(nodes);
28
46
  const parent = this.parentNode;
29
47
  if (!parent) return;
30
- const next = this[NEXT];
31
- for (const node of nodes) {
32
- parent.insertBefore(toNode(parent, node), next);
33
- }
48
+ return performChildNodeMutation(hookEffects => {
49
+ validateInsertionNodes(parent, staged);
50
+ let next = this[NEXT];
51
+ while (next && staged.includes(next)) next = next[NEXT];
52
+ const node = convertNodesIntoNode(parent, staged, hookEffects);
53
+ parent[INSERT_NODE](node, next, hookEffects);
54
+ });
34
55
  }
35
56
  }
57
+ function performChildNodeMutation(mutation) {
58
+ return performWithCustomElementReactions(() => {
59
+ const hookEffects = [];
60
+ try {
61
+ mutation(hookEffects);
62
+ } catch (error) {
63
+ try {
64
+ performHookEffects(hookEffects);
65
+ } catch {}
66
+ throw error;
67
+ }
68
+ performHookEffects(hookEffects);
69
+ });
70
+ }
71
+ function stageNodes(nodes) {
72
+ return nodes.map(node => node instanceof Node ? node : String(node));
73
+ }
36
74
  function toNode(parent, node) {
37
75
  if (node instanceof Node) return node;
38
76
  const ownerDocument = parent.ownerDocument;
39
77
  return ownerDocument.createTextNode(String(node));
40
78
  }
79
+ function validateInsertionNodes(parent, nodes) {
80
+ for (const node of nodes) {
81
+ if (!(node instanceof Node)) continue;
82
+ let ancestor = parent;
83
+ while (ancestor) {
84
+ if (ancestor === node) {
85
+ throw createDOMException('Cannot insert a node into itself or one of its descendants', 'HierarchyRequestError');
86
+ }
87
+ ancestor = ancestor[PARENT] ?? ancestor[HOST];
88
+ }
89
+ }
90
+ }
91
+ function convertNodesIntoNode(parent, nodes, hookEffects) {
92
+ const convertedNodes = [];
93
+ for (const node of nodes) convertedNodes.push(toNode(parent, node));
94
+ if (convertedNodes.length === 1) return convertedNodes[0];
95
+ const fragment = parent.ownerDocument.createDocumentFragment();
96
+ fragment[PREFLIGHT_INSERTIONS](convertedNodes);
97
+ for (const node of convertedNodes) {
98
+ fragment[INSERT_NODE](node, null, hookEffects);
99
+ }
100
+ return fragment;
101
+ }
41
102
 
42
- export { ChildNode, toNode };
103
+ export { ChildNode, INSERT_NODE, PREFLIGHT_INSERTIONS, REPLACE_NODE, stageNodes, toNode, validateInsertionNodes };
@@ -1,8 +1,8 @@
1
- import { NAME } from './constants.mjs';
1
+ import { NODE_TYPE_COMMENT, NAME } from './constants.mjs';
2
2
  import { CharacterData } from './CharacterData.mjs';
3
3
 
4
4
  class Comment extends CharacterData {
5
- nodeType = 8;
5
+ nodeType = NODE_TYPE_COMMENT;
6
6
  [NAME] = '#comment';
7
7
  }
8
8
 
@@ -1,7 +1,26 @@
1
+ import { createDOMException } from './dom-exception.mjs';
2
+
3
+ const VALID_CUSTOM_ELEMENT_NAME = /^[a-z][^A-Z\u0000\t\n\f\r />]*-[^A-Z\u0000\t\n\f\r />]*$/u;
4
+ const RESERVED_CUSTOM_ELEMENT_NAMES = new Set(['annotation-xml', 'color-profile', 'font-face', 'font-face-src', 'font-face-uri', 'font-face-format', 'font-face-name', 'missing-glyph']);
5
+ function isValidCustomElementName(name) {
6
+ return VALID_CUSTOM_ELEMENT_NAME.test(name) && !RESERVED_CUSTOM_ELEMENT_NAMES.has(name);
7
+ }
8
+ function createInvalidCustomElementNameError(name) {
9
+ return createDOMException(`Invalid custom element name: "${name}"`, 'SyntaxError');
10
+ }
1
11
  class CustomElementRegistryImplementation {
2
- registry = (() => new Map())();
3
- listenersByName = (() => new Map())();
12
+ registry = new Map();
13
+ listenersByName = new Map();
4
14
  define(name, Constructor, _options) {
15
+ if (!isValidCustomElementName(name)) {
16
+ throw createInvalidCustomElementNameError(name);
17
+ }
18
+ if (this.registry.has(name)) {
19
+ throw createDOMException(`A custom element named "${name}" has already been defined`, 'NotSupportedError');
20
+ }
21
+ if (this.getName(Constructor) != null) {
22
+ throw createDOMException('This constructor has already been registered in this custom element registry', 'NotSupportedError');
23
+ }
5
24
  this.registry.set(name, Constructor);
6
25
  const listeners = this.listenersByName.get(name);
7
26
  if (listeners == null) return;
@@ -20,6 +39,9 @@ class CustomElementRegistryImplementation {
20
39
  return null;
21
40
  }
22
41
  whenDefined(name) {
42
+ if (!isValidCustomElementName(name)) {
43
+ return Promise.reject(createInvalidCustomElementNameError(name));
44
+ }
23
45
  const Constructor = this.registry.get(name);
24
46
  if (Constructor != null) return Promise.resolve(Constructor);
25
47
  let listeners = this.listenersByName.get(name);
@@ -34,6 +56,9 @@ class CustomElementRegistryImplementation {
34
56
  upgrade(_root) {
35
57
  // TODO
36
58
  }
59
+ initialize(_root) {
60
+ // TODO
61
+ }
37
62
  }
38
63
 
39
64
  export { CustomElementRegistryImplementation };
@@ -9,7 +9,7 @@ class CustomEvent extends Event {
9
9
 
10
10
  constructor(type, eventInitDict) {
11
11
  super(type, eventInitDict);
12
- this.detail = eventInitDict?.detail;
12
+ this.detail = eventInitDict?.detail ?? null;
13
13
  }
14
14
 
15
15
  /**
@@ -19,7 +19,7 @@ class CustomEvent extends Event {
19
19
  */
20
20
  initCustomEvent(type, bubbles, cancelable, detail) {
21
21
  super.initEvent(type, bubbles, cancelable);
22
- this.detail = detail;
22
+ this.detail = detail ?? null;
23
23
  }
24
24
  }
25
25
 
@@ -1,19 +1,22 @@
1
- import { NodeType, NAME, IS_CONNECTED, OWNER_DOCUMENT, HOOKS, NamespaceURI, NS } from './constants.mjs';
1
+ import { NODE_TYPE_DOCUMENT, NAME, IS_CONNECTED, OWNER_DOCUMENT, HTML_NAMESPACE, asciiLowercase, CREATE_ELEMENT, HOOKS, PREFIX, NS, SVG_NAMESPACE } from './constants.mjs';
2
+ import { validateElementLocalName, validateAndExtractQualifiedName } from './names.mjs';
2
3
  import { Event } from './Event.mjs';
3
- import { ParentNode } from './ParentNode.mjs';
4
+ import { ParentNode, removeChildForAdoption } from './ParentNode.mjs';
4
5
  import { Element } from './Element.mjs';
5
6
  import { SVGElement } from './SVGElement.mjs';
6
7
  import { Text } from './Text.mjs';
7
8
  import { Comment } from './Comment.mjs';
8
9
  import { DocumentFragment } from './DocumentFragment.mjs';
9
10
  import { HTMLTemplateElement } from './HTMLTemplateElement.mjs';
10
- import { cloneNode, isParentNode } from './shared.mjs';
11
+ import { getElementsByClassName, getElementById, getElementsByTagName, cloneNode, collectAdoptionSnapshot, adoptNodes } from './shared.mjs';
11
12
  import { HTMLBodyElement } from './HTMLBodyElement.mjs';
12
13
  import { HTMLHeadElement } from './HTMLHeadElement.mjs';
13
14
  import { HTMLHtmlElement } from './HTMLHtmlElement.mjs';
15
+ import { performWithCustomElementReactions } from './custom-element-reactions.mjs';
16
+ import { createDOMException } from './dom-exception.mjs';
14
17
 
15
18
  class Document extends ParentNode {
16
- nodeType = (() => NodeType.DOCUMENT_NODE)();
19
+ nodeType = NODE_TYPE_DOCUMENT;
17
20
  [NAME] = '#document';
18
21
  [IS_CONNECTED] = true;
19
22
  constructor(defaultView) {
@@ -27,15 +30,29 @@ class Document extends ParentNode {
27
30
  this.documentElement.appendChild(this.head);
28
31
  this.documentElement.appendChild(this.body);
29
32
  }
33
+ get textContent() {
34
+ return null;
35
+ }
36
+ set textContent(data) {
37
+ }
38
+ getElementsByClassName(classNames) {
39
+ return getElementsByClassName(this, classNames);
40
+ }
30
41
  createElement(localName) {
31
- return createElement(this, localName);
42
+ const name = String(localName);
43
+ validateElementLocalName(name);
44
+ return createElement(this, asciiLowercase(name));
32
45
  }
33
- createElementNS(namespaceURI, localName) {
34
- return createElement(this, localName, namespaceURI);
46
+ createElementNS(namespaceURI, qualifiedName) {
47
+ const name = validateAndExtractQualifiedName(namespaceURI, qualifiedName, 'element');
48
+ return createElement(this, name.qualifiedName, name.namespace, name.prefix, name.localName);
49
+ }
50
+ [CREATE_ELEMENT](qualifiedName, namespace, prefix, localName) {
51
+ return createElement(this, qualifiedName, namespace, prefix, localName);
35
52
  }
36
53
  createTextNode(data) {
37
54
  const text = createNode(new Text(data), this);
38
- this[HOOKS].createText?.(text, String(data));
55
+ this[HOOKS].createText?.(text, text.data);
39
56
  return text;
40
57
  }
41
58
  createComment(data) {
@@ -47,14 +64,26 @@ class Document extends ParentNode {
47
64
  createEvent() {
48
65
  return new Event('');
49
66
  }
67
+ getElementById(elementId) {
68
+ return getElementById(this, elementId);
69
+ }
70
+ getElementsByTagName(qualifiedName) {
71
+ return getElementsByTagName(this, qualifiedName);
72
+ }
50
73
  importNode(node, deep) {
74
+ if (node.nodeType === NODE_TYPE_DOCUMENT) {
75
+ throw createDOMException('Cannot import a document node', 'NotSupportedError');
76
+ }
51
77
  return cloneNode(node, deep, this);
52
78
  }
53
79
  adoptNode(node) {
54
80
  if (node[OWNER_DOCUMENT] === this) return node;
55
- node.parentNode?.removeChild(node);
56
- adoptNode(node, this);
57
- return node;
81
+ const adoption = collectAdoptionSnapshot(node);
82
+ return performWithCustomElementReactions(() => {
83
+ const parent = node.parentNode;
84
+ if (parent) removeChildForAdoption(parent, node, adoption, this);else adoptNodes(adoption.nodes, this);
85
+ return node;
86
+ });
58
87
  }
59
88
  }
60
89
  function createNode(node, ownerDocument) {
@@ -65,39 +94,35 @@ function createNode(node, ownerDocument) {
65
94
  });
66
95
  return node;
67
96
  }
68
- function createElement(ownerDocument, name, namespace) {
97
+ function createElement(ownerDocument, qualifiedName, namespace = HTML_NAMESPACE, prefix = null, localName = qualifiedName) {
69
98
  let element;
70
- const lowerName = String(name).toLowerCase();
71
- if (namespace === NamespaceURI.SVG) {
99
+ if (namespace === SVG_NAMESPACE) {
72
100
  element = new SVGElement();
73
- } else if (lowerName === 'template') {
101
+ } else if (namespace === HTML_NAMESPACE && localName === 'template') {
74
102
  element = new HTMLTemplateElement();
75
- } else {
76
- const CustomElement = ownerDocument.defaultView.customElements.get(name);
103
+ } else if (namespace === HTML_NAMESPACE) {
104
+ const CustomElement = ownerDocument.defaultView.customElements.get(localName);
77
105
  element = CustomElement ? new CustomElement() : new Element();
106
+ } else {
107
+ element = new Element();
78
108
  }
79
- return setupElement(element, ownerDocument, name, namespace);
109
+ return setupElement(element, ownerDocument, qualifiedName, namespace, prefix);
80
110
  }
81
- function setupElement(element, ownerDocument, name, namespace) {
111
+ function setupElement(element, ownerDocument, qualifiedName, namespace = HTML_NAMESPACE, prefix = null) {
82
112
  createNode(element, ownerDocument);
83
- Object.defineProperty(element, NAME, {
84
- value: name
85
- });
86
- if (namespace) {
87
- Object.defineProperty(element, NS, {
113
+ Object.defineProperties(element, {
114
+ [NAME]: {
115
+ value: qualifiedName
116
+ },
117
+ [NS]: {
88
118
  value: namespace
89
- });
90
- }
119
+ },
120
+ [PREFIX]: {
121
+ value: prefix
122
+ }
123
+ });
91
124
  ownerDocument[HOOKS].createElement?.(element, namespace);
92
125
  return element;
93
126
  }
94
- function adoptNode(node, document) {
95
- node[OWNER_DOCUMENT] = document;
96
- if (isParentNode(node)) {
97
- for (const child of node.childNodes) {
98
- adoptNode(child, document);
99
- }
100
- }
101
- }
102
127
 
103
- export { Document, adoptNode, createElement, createNode, setupElement };
128
+ export { Document, createElement, createNode, setupElement };
@@ -1,10 +1,14 @@
1
- import { NodeType, NAME, OWNER_DOCUMENT } from './constants.mjs';
1
+ import { NODE_TYPE_DOCUMENT_FRAGMENT, NAME, OWNER_DOCUMENT } from './constants.mjs';
2
2
  import { ParentNode } from './ParentNode.mjs';
3
+ import { getElementById } from './shared.mjs';
3
4
 
4
5
  class DocumentFragment extends ParentNode {
5
- nodeType = (() => NodeType.DOCUMENT_FRAGMENT_NODE)();
6
+ nodeType = NODE_TYPE_DOCUMENT_FRAGMENT;
6
7
  [NAME] = '#document-fragment';
7
- [OWNER_DOCUMENT] = (() => typeof window !== 'undefined' ? window.document : null)();
8
+ [OWNER_DOCUMENT] = typeof window !== 'undefined' ? window.document : null;
9
+ getElementById(elementId) {
10
+ return getElementById(this, elementId);
11
+ }
8
12
  }
9
13
 
10
14
  export { DocumentFragment };
@@ -1,24 +1,43 @@
1
- import { NodeType, NS, NamespaceURI, ATTRIBUTES } from './constants.mjs';
1
+ import { NODE_TYPE_ELEMENT, HTML_NAMESPACE, NS, PREFIX, NAME, asciiUppercase, ATTRIBUTES, asciiLowercase } from './constants.mjs';
2
+ import { validateAttributeLocalName, validateAndExtractQualifiedName, normalizeNamespace } from './names.mjs';
2
3
  import { ParentNode } from './ParentNode.mjs';
3
4
  import { NamedNodeMap } from './NamedNodeMap.mjs';
4
5
  import { Attr } from './Attr.mjs';
5
6
  import { serializeNode, serializeChildren, parseHtml } from './serialization.mjs';
7
+ import { getElementsByTagName, getElementsByClassName } from './shared.mjs';
6
8
 
7
9
  class Element extends ParentNode {
8
- nodeType = (() => NodeType.ELEMENT_NODE)();
9
- [NS] = (() => NamespaceURI.XHTML)();
10
+ nodeType = NODE_TYPE_ELEMENT;
11
+ [NS] = HTML_NAMESPACE;
12
+ [PREFIX] = null;
10
13
  get namespaceURI() {
11
14
  return this[NS];
12
15
  }
16
+ get prefix() {
17
+ return this[PREFIX];
18
+ }
19
+ get localName() {
20
+ const prefix = this[PREFIX];
21
+ return prefix == null ? this[NAME] : this[NAME].slice(prefix.length + 1);
22
+ }
23
+ get nodeName() {
24
+ return this[NS] === HTML_NAMESPACE ? asciiUppercase(this[NAME]) : this[NAME];
25
+ }
13
26
  get tagName() {
14
27
  return this.nodeName;
15
28
  }
29
+ get id() {
30
+ return this.getAttributeNS(null, 'id') ?? '';
31
+ }
32
+ set id(id) {
33
+ this.setAttribute('id', String(id));
34
+ }
16
35
  get slot() {
17
- return this.getAttribute('slot') ?? '';
36
+ return this.getAttributeNS(null, 'slot') ?? '';
18
37
  }
19
38
  set slot(slot) {
20
39
  const finalSlot = String(slot);
21
- if (this.getAttribute('slot') !== finalSlot) {
40
+ if (this.getAttributeNS(null, 'slot') !== finalSlot) {
22
41
  this.attributes.setNamedItem(new Attr('slot', finalSlot));
23
42
  }
24
43
  }
@@ -33,9 +52,15 @@ class Element extends ParentNode {
33
52
  getAttributeNames() {
34
53
  return [...this.attributes].map(attr => attr.name);
35
54
  }
55
+ getElementsByTagName(qualifiedName) {
56
+ return getElementsByTagName(this, qualifiedName);
57
+ }
36
58
  get firstElementChild() {
37
59
  return this.children[0] ?? null;
38
60
  }
61
+ getElementsByClassName(classNames) {
62
+ return getElementsByClassName(this, classNames);
63
+ }
39
64
  get lastElementChild() {
40
65
  return this.children[this.children.length - 1] ?? null;
41
66
  }
@@ -50,10 +75,43 @@ class Element extends ParentNode {
50
75
  return sib;
51
76
  }
52
77
  setAttribute(name, value) {
53
- this.attributes.setNamedItem(new Attr(name, String(value)));
78
+ const qualifiedName = String(name);
79
+ const normalizedValue = String(value);
80
+ validateAttributeLocalName(qualifiedName);
81
+ const normalizedName = this[NS] === HTML_NAMESPACE ? asciiLowercase(qualifiedName) : qualifiedName;
82
+ const attribute = this.attributes.getNamedItemNS(null, normalizedName);
83
+ if (attribute) {
84
+ attribute.value = normalizedValue;
85
+ } else {
86
+ this.attributes.setNamedItem(new Attr(normalizedName, normalizedValue));
87
+ }
88
+ }
89
+ setAttributeNS(namespace, qualifiedName, value) {
90
+ const normalizedNamespace = normalizeNamespace(namespace);
91
+ const normalizedQualifiedName = String(qualifiedName);
92
+ const normalizedValue = String(value);
93
+ const name = validateAndExtractQualifiedName(normalizedNamespace, normalizedQualifiedName, 'attribute');
94
+ const attribute = this.attributes.getNamedItemNS(name.namespace, name.localName);
95
+ if (attribute) {
96
+ attribute.value = normalizedValue;
97
+ } else {
98
+ this.attributes.setNamedItemNS(new Attr(name.qualifiedName, normalizedValue, name.namespace));
99
+ }
54
100
  }
55
- setAttributeNS(namespace, name, value) {
56
- this.attributes.setNamedItemNS(new Attr(name, String(value), namespace));
101
+ toggleAttribute(name, force) {
102
+ const qualifiedName = String(name);
103
+ validateAttributeLocalName(qualifiedName);
104
+ const normalizedName = this[NS] === HTML_NAMESPACE ? asciiLowercase(qualifiedName) : qualifiedName;
105
+ const attribute = this.attributes.getNamedItemNS(null, normalizedName);
106
+ const normalizedForce = force === undefined ? undefined : Boolean(force);
107
+ if (attribute == null) {
108
+ if (normalizedForce === false) return false;
109
+ this.attributes.setNamedItem(new Attr(normalizedName, ''));
110
+ return true;
111
+ }
112
+ if (normalizedForce === true) return true;
113
+ this.attributes.removeNamedItemNS(null, normalizedName);
114
+ return false;
57
115
  }
58
116
  getAttribute(name) {
59
117
  const attr = this.attributes.getNamedItem(name);
@@ -72,7 +130,9 @@ class Element extends ParentNode {
72
130
  return attr != null;
73
131
  }
74
132
  removeAttribute(name) {
75
- this.attributes.removeNamedItem(name);
133
+ const qualifiedName = String(name);
134
+ const normalizedName = this[NS] === HTML_NAMESPACE ? asciiLowercase(qualifiedName) : qualifiedName;
135
+ this.attributes.removeNamedItemNS(null, normalizedName);
76
136
  }
77
137
  removeAttributeNS(namespace, name) {
78
138
  this.attributes.removeNamedItemNS(namespace, name);
@@ -1,26 +1,22 @@
1
- import { PATH, STOP_IMMEDIATE_PROPAGATION, IS_TRUSTED, LISTENERS } from './constants.mjs';
1
+ import { PATH, STOP_IMMEDIATE_PROPAGATION, DISPATCHING, IS_TRUSTED, LISTENERS } from './constants.mjs';
2
2
 
3
- let EventPhase = /*#__PURE__*/function (EventPhase) {
4
- EventPhase[EventPhase["NONE"] = 0] = "NONE";
5
- EventPhase[EventPhase["CAPTURING_PHASE"] = 1] = "CAPTURING_PHASE";
6
- EventPhase[EventPhase["AT_TARGET"] = 2] = "AT_TARGET";
7
- EventPhase[EventPhase["BUBBLING_PHASE"] = 3] = "BUBBLING_PHASE";
8
- return EventPhase;
9
- }({});
10
- const CAPTURE_MARKER = '@';
3
+ const EVENT_PHASE_NONE = 0;
4
+ const EVENT_PHASE_CAPTURING = 1;
5
+ const EVENT_PHASE_AT_TARGET = 2;
6
+ const EVENT_PHASE_BUBBLING = 3;
11
7
  const now = typeof performance === 'undefined' ? Date.now : performance.now.bind(performance);
12
8
  class Event {
13
- static NONE = (() => EventPhase.NONE)();
14
- static CAPTURING_PHASE = (() => EventPhase.CAPTURING_PHASE)();
15
- static AT_TARGET = (() => EventPhase.AT_TARGET)();
16
- static BUBBLING_PHASE = (() => EventPhase.BUBBLING_PHASE)();
9
+ static NONE = EVENT_PHASE_NONE;
10
+ static CAPTURING_PHASE = EVENT_PHASE_CAPTURING;
11
+ static AT_TARGET = EVENT_PHASE_AT_TARGET;
12
+ static BUBBLING_PHASE = EVENT_PHASE_BUBBLING;
17
13
 
18
- // NONE = EventPhase.NONE;
19
- // CAPTURING_PHASE = EventPhase.CAPTURING_PHASE;
20
- // AT_TARGET = EventPhase.AT_TARGET;
21
- // BUBBLING_PHASE = EventPhase.BUBBLING_PHASE;
14
+ // NONE = EVENT_PHASE_NONE;
15
+ // CAPTURING_PHASE = EVENT_PHASE_CAPTURING;
16
+ // AT_TARGET = EVENT_PHASE_AT_TARGET;
17
+ // BUBBLING_PHASE = EVENT_PHASE_BUBBLING;
22
18
 
23
- timeStamp = (() => now())();
19
+ timeStamp = now();
24
20
  target = null;
25
21
  currentTarget = null;
26
22
  srcElement = null;
@@ -29,11 +25,12 @@ class Event {
29
25
  composed = false;
30
26
  defaultPrevented = false;
31
27
  cancelBubble = false;
32
- eventPhase = 0;
28
+ eventPhase = EVENT_PHASE_NONE;
33
29
  // private inPassiveListener = false;
34
30
 
35
31
  [PATH] = [];
36
32
  [STOP_IMMEDIATE_PROPAGATION] = false;
33
+ [DISPATCHING] = false;
37
34
  constructor(type, options) {
38
35
  this.type = type;
39
36
  Object.defineProperty(this, IS_TRUSTED, {
@@ -50,7 +47,7 @@ class Event {
50
47
  return this[IS_TRUSTED];
51
48
  }
52
49
  composedPath() {
53
- return this[PATH];
50
+ return [...this[PATH]];
54
51
  }
55
52
  stopPropagation() {
56
53
  this.cancelBubble = true;
@@ -60,13 +57,13 @@ class Event {
60
57
  this.cancelBubble = true;
61
58
  }
62
59
  preventDefault() {
63
- this.defaultPrevented = true;
60
+ if (this.cancelable) this.defaultPrevented = true;
64
61
  }
65
62
  set returnValue(value) {
66
- this.defaultPrevented = value;
63
+ if (!value) this.preventDefault();
67
64
  }
68
65
  get returnValue() {
69
- return this.defaultPrevented;
66
+ return !this.defaultPrevented;
70
67
  }
71
68
 
72
69
  /** @deprecated */
@@ -77,12 +74,15 @@ class Event {
77
74
  }
78
75
  }
79
76
  function fireEvent(event, currentTarget, phase) {
77
+ if (event.cancelBubble) return;
80
78
  const listeners = currentTarget[LISTENERS];
81
- const list = listeners?.get(`${event.type}${phase === EventPhase.CAPTURING_PHASE ? CAPTURE_MARKER : ''}`);
79
+ const list = listeners?.get(event.type)?.[phase === EVENT_PHASE_CAPTURING ? 'capture' : 'bubble'];
82
80
  if (!list) return;
83
- for (const listener of list) {
84
- event.eventPhase = event.target === currentTarget ? EventPhase.AT_TARGET : phase;
81
+ for (const registration of [...list]) {
82
+ if (!list.has(registration) || registration.signal?.aborted) continue;
83
+ event.eventPhase = event.target === currentTarget ? EVENT_PHASE_AT_TARGET : phase;
85
84
  event.currentTarget = currentTarget;
85
+ const listener = registration.normalizedListener;
86
86
  try {
87
87
  if (typeof listener === 'object') {
88
88
  listener.handleEvent(event);
@@ -99,4 +99,4 @@ function thrower(error) {
99
99
  throw error;
100
100
  }
101
101
 
102
- export { CAPTURE_MARKER, Event, EventPhase, fireEvent };
102
+ export { EVENT_PHASE_AT_TARGET, EVENT_PHASE_BUBBLING, EVENT_PHASE_CAPTURING, EVENT_PHASE_NONE, Event, fireEvent };