@remote-dom/polyfill 1.5.0 → 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 +94 -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 +7 -3
  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 +15 -3
  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,24 +1,26 @@
1
- import { NodeType, OWNER_DOCUMENT, NAME, PARENT, CHILD, PREV, NEXT, IS_CONNECTED, HOOKS, NamespaceURI } from './constants.esnext';
1
+ import { NODE_TYPE_NODE, OWNER_DOCUMENT, NAME, PARENT, HOST, CHILD, PREV, NEXT, IS_CONNECTED, HOOKS, HOOKS_DISPATCH, NODE_TYPE_ATTRIBUTE, NODE_TYPE_DOCUMENT_FRAGMENT, NODE_TYPE_DOCUMENT_TYPE, NODE_TYPE_DOCUMENT, NODE_TYPE_ELEMENT, XMLNS_NAMESPACE } from './constants.esnext';
2
2
  import { EventTarget } from './EventTarget.esnext';
3
+ import { normalizeNamespace } from './names.esnext';
3
4
  import { isCharacterData, descendants, isTextNode, isParentNode, cloneNode } from './shared.esnext';
4
5
 
5
6
  class Node extends EventTarget {
6
- nodeType = NodeType.NODE;
7
+ nodeType = NODE_TYPE_NODE;
7
8
  [OWNER_DOCUMENT];
8
9
  [NAME] = "";
9
10
  [PARENT] = null;
11
+ [HOST] = null;
10
12
  [CHILD] = null;
11
13
  [PREV] = null;
12
14
  [NEXT] = null;
13
15
  [IS_CONNECTED] = false;
14
16
  get [HOOKS]() {
15
- return this[OWNER_DOCUMENT].defaultView[HOOKS];
17
+ return this[OWNER_DOCUMENT].defaultView[HOOKS_DISPATCH];
16
18
  }
17
19
  get localName() {
18
20
  return this[NAME];
19
21
  }
20
22
  get nodeName() {
21
- return this[NAME].toUpperCase();
23
+ return this[NAME];
22
24
  }
23
25
  get ownerDocument() {
24
26
  return this[OWNER_DOCUMENT];
@@ -27,7 +29,8 @@ class Node extends EventTarget {
27
29
  return this[IS_CONNECTED];
28
30
  }
29
31
  isDefaultNamespace(namespace) {
30
- return namespace === NamespaceURI.XHTML;
32
+ const normalizedNamespace = normalizeNamespace(namespace);
33
+ return locateNamespace(this) === normalizedNamespace;
31
34
  }
32
35
  get parentNode() {
33
36
  return this[PARENT];
@@ -102,11 +105,12 @@ class Node extends EventTarget {
102
105
  if (isCharacterData(this)) {
103
106
  this.data = data;
104
107
  } else if (isParentNode(this)) {
105
- let child;
106
- while (child = this[CHILD]) {
107
- this.removeChild(child);
108
+ const text = data == null ? "" : String(data);
109
+ if (text === "") {
110
+ this.replaceChildren();
111
+ } else {
112
+ this.replaceChildren(text);
108
113
  }
109
- this.append(data);
110
114
  }
111
115
  }
112
116
  cloneNode(deep) {
@@ -114,12 +118,46 @@ class Node extends EventTarget {
114
118
  }
115
119
  contains(node) {
116
120
  let currentNode = node;
117
- while (true) {
118
- if (currentNode == null) return false;
121
+ while (currentNode != null) {
119
122
  if (currentNode === this) return true;
120
- currentNode = node.parentNode;
123
+ currentNode = currentNode.parentNode;
124
+ }
125
+ return false;
126
+ }
127
+ }
128
+ function locateNamespace(node) {
129
+ let current = node;
130
+ while (current) {
131
+ switch (current.nodeType) {
132
+ case NODE_TYPE_ELEMENT: {
133
+ const element = current;
134
+ if (element.prefix == null && element.namespaceURI != null) {
135
+ return element.namespaceURI;
136
+ }
137
+ const namespace = element.attributes.getNamedItemNS(
138
+ XMLNS_NAMESPACE,
139
+ "xmlns"
140
+ );
141
+ if (namespace != null && namespace.prefix == null) {
142
+ return normalizeNamespace(namespace.value);
143
+ }
144
+ current = element.parentElement;
145
+ break;
146
+ }
147
+ case NODE_TYPE_DOCUMENT:
148
+ current = current.documentElement;
149
+ break;
150
+ case NODE_TYPE_DOCUMENT_TYPE:
151
+ case NODE_TYPE_DOCUMENT_FRAGMENT:
152
+ return null;
153
+ case NODE_TYPE_ATTRIBUTE:
154
+ current = current.ownerElement;
155
+ break;
156
+ default:
157
+ current = current.parentElement;
121
158
  }
122
159
  }
160
+ return null;
123
161
  }
124
162
 
125
163
  export { Node };
@@ -1,6 +1,6 @@
1
1
  class NodeList extends Array {
2
2
  item(index) {
3
- return this[index];
3
+ return this[index] ?? null;
4
4
  }
5
5
  }
6
6
 
@@ -1,72 +1,130 @@
1
- import { PREV, NEXT, CHILD, PARENT, IS_CONNECTED, NodeType, HOOKS, OWNER_DOCUMENT } from './constants.esnext';
2
- import { ChildNode, toNode } from './ChildNode.esnext';
1
+ import { IS_CONNECTED, PREV, NEXT, NODE_TYPE_DOCUMENT_FRAGMENT, CHILD, OWNER_DOCUMENT, PARENT, NODE_TYPE_ELEMENT, HOOKS } from './constants.esnext';
2
+ import { ChildNode, REPLACE_NODE, validateInsertionNodes, INSERT_NODE, PREFLIGHT_INSERTIONS, stageNodes, toNode } from './ChildNode.esnext';
3
3
  import { NodeList } from './NodeList.esnext';
4
4
  import { querySelectorAll, querySelector } from './selectors.esnext';
5
- import { selfAndDescendants } from './shared.esnext';
5
+ import { selfAndDescendants, collectAdoptionSnapshot, adoptNodes, isElementNode } from './shared.esnext';
6
+ import { childListObserversActive, queueMutationRecord, mutationNodeList } from './MutationObserver.esnext';
7
+ import { performWithCustomElementReactions, enqueueCustomElementReaction } from './custom-element-reactions.esnext';
8
+ import { performHookEffects, isCoveredByPendingPublication } from './hook-effects.esnext';
9
+ import { createDOMException } from './dom-exception.esnext';
6
10
 
7
11
  class ParentNode extends ChildNode {
8
12
  childNodes = new NodeList();
9
13
  children = new NodeList();
10
14
  appendChild(child) {
11
- this.insertInto(child, null);
15
+ return performWithCustomElementReactions(
16
+ () => this[INSERT_NODE](child, null)
17
+ );
12
18
  }
13
19
  insertBefore(child, ref) {
14
- this.insertInto(child, ref || null);
20
+ return performWithCustomElementReactions(
21
+ () => this[INSERT_NODE](child, ref || null)
22
+ );
15
23
  }
16
24
  append(...nodes) {
17
- for (const child of nodes) {
18
- if (child == null) continue;
19
- this.appendChild(toNode(this, child));
20
- }
25
+ return performWithCustomElementReactions(() => {
26
+ const staged = stageNodes(nodes.filter((node) => node != null));
27
+ if (staged.length > 1) validateInsertionNodes(this, staged);
28
+ for (const child of staged) {
29
+ this[INSERT_NODE](toNode(this, child), null);
30
+ }
31
+ });
21
32
  }
22
33
  prepend(...nodes) {
23
- const before = this.firstChild;
24
- for (const child of nodes) {
25
- if (child == null) continue;
26
- this.insertBefore(toNode(this, child), before);
27
- }
34
+ return performWithCustomElementReactions(() => {
35
+ const staged = stageNodes(nodes.filter((node) => node != null));
36
+ if (staged.length > 1) validateInsertionNodes(this, staged);
37
+ const before = this.firstChild;
38
+ for (const child of staged) {
39
+ this[INSERT_NODE](toNode(this, child), before);
40
+ }
41
+ });
28
42
  }
29
43
  replaceChildren(...nodes) {
30
- let child;
31
- while (child = this.firstChild) {
32
- this.removeChild(child);
33
- }
34
- this.append(...nodes);
44
+ return performWithCustomElementReactions(() => {
45
+ const staged = stageNodes(nodes.filter((node) => node != null));
46
+ validateInsertionNodes(this, staged);
47
+ let child;
48
+ while (child = this.firstChild) {
49
+ this.removeChildImmediately(child);
50
+ }
51
+ for (const node of staged) {
52
+ this[INSERT_NODE](toNode(this, node), null);
53
+ }
54
+ });
35
55
  }
36
56
  removeChild(child) {
37
- if (child.parentNode !== this) throw Error(`not a child of this node`);
38
- const prev = child[PREV];
39
- const next = child[NEXT];
40
- if (prev) prev[NEXT] = next;
41
- else this[CHILD] = next;
42
- if (next) next[PREV] = prev;
43
- const childNodes = this.childNodes;
44
- const childNodesIndex = childNodes.indexOf(child);
45
- childNodes.splice(childNodesIndex, 1);
46
- if (child.nodeType === 1) {
47
- const children = this.children;
48
- children.splice(children.indexOf(child), 1);
49
- }
50
- child[PARENT] = null;
51
- child[NEXT] = null;
52
- child[PREV] = null;
53
- if (this[IS_CONNECTED]) {
54
- for (const node of selfAndDescendants(child)) {
55
- node[IS_CONNECTED] = false;
56
- node.disconnectedCallback?.();
57
- }
57
+ return performWithCustomElementReactions(() => {
58
+ this.removeChildImmediately(child);
59
+ return child;
60
+ });
61
+ }
62
+ removeChildImmediately(child) {
63
+ if (child.parentNode !== this) {
64
+ throw createDOMException(
65
+ "The node is not a child of this node",
66
+ "NotFoundError"
67
+ );
68
+ }
69
+ const disconnectedNodes = this[IS_CONNECTED] ? selfAndDescendants(child) : void 0;
70
+ const previousSibling = child[PREV];
71
+ const nextSibling = child[NEXT];
72
+ const childNodesIndex = detachChild(this, child);
73
+ if (disconnectedNodes) {
74
+ for (const node of disconnectedNodes) node[IS_CONNECTED] = false;
58
75
  }
59
- if (this.nodeType === NodeType.ELEMENT_NODE) {
60
- this[HOOKS].removeChild?.(this, child, childNodesIndex);
76
+ this.queueRemovalMutationRecord(this, child, previousSibling, nextSibling);
77
+ if (disconnectedNodes) {
78
+ this.enqueueTreeReactions(disconnectedNodes, "disconnectedCallback");
61
79
  }
80
+ performHookEffects(this.collectRemovalHookEffects(child, childNodesIndex));
62
81
  }
63
82
  replaceChild(newChild, oldChild) {
83
+ return performWithCustomElementReactions(
84
+ () => this[REPLACE_NODE](newChild, oldChild)
85
+ );
86
+ }
87
+ [REPLACE_NODE](newChild, oldChild, hookEffects) {
88
+ validateInsertionNodes(this, [newChild]);
64
89
  if (oldChild.parentNode !== this) {
65
- throw Error("reference node is not a child of this parent");
90
+ throw createDOMException(
91
+ "The reference node is not a child of this parent",
92
+ "NotFoundError"
93
+ );
66
94
  }
95
+ const previous = oldChild[PREV];
67
96
  const next = oldChild[NEXT];
68
- this.removeChild(oldChild);
69
- this.insertInto(newChild, next);
97
+ const insertion = this.prepareInsertion(newChild);
98
+ const removedNodes = this[IS_CONNECTED] ? selfAndDescendants(oldChild) : void 0;
99
+ const insertionRoots = new Set(insertion.map(({ node }) => node));
100
+ let before = next;
101
+ while (before && insertionRoots.has(before)) before = before[NEXT];
102
+ const oldChildIndex = detachChild(this, oldChild);
103
+ if (removedNodes) {
104
+ for (const node of removedNodes) node[IS_CONNECTED] = false;
105
+ const removedNodeSet = new Set(removedNodes);
106
+ for (const prepared of insertion) {
107
+ if (removedNodeSet.has(prepared.node)) {
108
+ prepared.shouldDisconnect = false;
109
+ }
110
+ }
111
+ }
112
+ this.commitInsertion(insertion, before);
113
+ const destinationIsConnected = this[IS_CONNECTED];
114
+ this.queueRemovalMutationRecord(this, oldChild, previous, next);
115
+ this.queueInsertionMutationRecords(insertion);
116
+ if (removedNodes) {
117
+ this.enqueueTreeReactions(removedNodes, "disconnectedCallback");
118
+ }
119
+ this.enqueueInsertionReactions(insertion, destinationIsConnected);
120
+ this.performOrCollectHookEffects(
121
+ [
122
+ ...this.collectRemovalHookEffects(oldChild, oldChildIndex),
123
+ ...this.collectInsertionHookEffects(insertion)
124
+ ],
125
+ hookEffects
126
+ );
127
+ return oldChild;
70
128
  }
71
129
  querySelectorAll(selector) {
72
130
  return querySelectorAll(this, selector);
@@ -74,26 +132,110 @@ class ParentNode extends ChildNode {
74
132
  querySelector(selector) {
75
133
  return querySelector(this, selector);
76
134
  }
77
- insertInto(child, before) {
78
- if (child.nodeType === NodeType.DOCUMENT_FRAGMENT_NODE) {
135
+ [INSERT_NODE](child, before, hookEffects) {
136
+ this.validateInsertion(child, before);
137
+ this.insertIntoValidated(child, before, hookEffects);
138
+ return child;
139
+ }
140
+ [PREFLIGHT_INSERTIONS](children) {
141
+ for (const child of children) {
142
+ this.validateInsertion(child, null);
143
+ this.prepareInsertion(child);
144
+ }
145
+ }
146
+ validateInsertion(child, before) {
147
+ validateInsertionNodes(this, [child]);
148
+ if (before && before.parentNode !== this) {
149
+ throw createDOMException(
150
+ "The reference node is not a child of this parent",
151
+ "NotFoundError"
152
+ );
153
+ }
154
+ }
155
+ insertIntoValidated(child, before, hookEffects) {
156
+ if (child === before) before = child[NEXT];
157
+ const insertion = this.prepareInsertion(child);
158
+ this.commitInsertion(insertion, before);
159
+ const destinationIsConnected = this[IS_CONNECTED];
160
+ this.queueInsertionMutationRecords(insertion);
161
+ this.enqueueInsertionReactions(insertion, destinationIsConnected);
162
+ this.performOrCollectHookEffects(
163
+ this.collectInsertionHookEffects(insertion),
164
+ hookEffects
165
+ );
166
+ }
167
+ performOrCollectHookEffects(effects, hookEffects) {
168
+ if (hookEffects) hookEffects.push(...effects);
169
+ else performHookEffects(effects);
170
+ }
171
+ prepareInsertion(child) {
172
+ const roots = [];
173
+ if (child.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT) {
79
174
  let node = child[CHILD];
80
175
  while (node) {
81
- const next = node[NEXT];
82
- this.insertInto(node, before);
83
- node = next;
176
+ roots.push(node);
177
+ node = node[NEXT];
84
178
  }
85
- return;
179
+ } else {
180
+ roots.push(child);
86
181
  }
87
- if (child.parentNode !== null) {
88
- child.parentNode.removeChild(child);
182
+ const destinationIsConnected = this[IS_CONNECTED];
183
+ const ownerDocument = this[OWNER_DOCUMENT];
184
+ const insertion = [];
185
+ for (const node of roots) {
186
+ const wasConnected = node[IS_CONNECTED];
187
+ const shouldTraverse = wasConnected || destinationIsConnected;
188
+ let nodes;
189
+ let adoption;
190
+ if (node[OWNER_DOCUMENT] === ownerDocument) {
191
+ if (shouldTraverse) nodes = selfAndDescendants(node);
192
+ } else {
193
+ const snapshot = collectAdoptionSnapshot(node);
194
+ adoption = snapshot.nodes;
195
+ if (shouldTraverse) nodes = snapshot.treeNodes;
196
+ }
197
+ insertion.push({ node, nodes, adoption, shouldDisconnect: wasConnected });
89
198
  }
90
- if (before) {
91
- if (before.parentNode !== this) {
92
- throw Error("reference node is not a child of this parent");
199
+ return insertion;
200
+ }
201
+ commitInsertion(insertion, before) {
202
+ for (const prepared of insertion) {
203
+ const sourceParent = prepared.node[PARENT];
204
+ if (sourceParent) {
205
+ const previousSibling = prepared.node[PREV];
206
+ const nextSibling = prepared.node[NEXT];
207
+ prepared.source = {
208
+ parent: sourceParent,
209
+ index: detachChild(sourceParent, prepared.node),
210
+ previousSibling,
211
+ nextSibling
212
+ };
93
213
  }
214
+ }
215
+ for (const prepared of insertion) {
216
+ const attached = this.attachChild(prepared.node, before);
217
+ prepared.insertIndex = attached.index;
218
+ prepared.previousSibling = attached.previousSibling;
219
+ prepared.nextSibling = attached.nextSibling;
220
+ }
221
+ const ownerDocument = this[OWNER_DOCUMENT];
222
+ for (const { adoption } of insertion) {
223
+ if (adoption) adoptNodes(adoption, ownerDocument);
224
+ }
225
+ const isConnected = this[IS_CONNECTED];
226
+ for (const { nodes } of insertion) {
227
+ if (nodes) {
228
+ for (const node of nodes) node[IS_CONNECTED] = isConnected;
229
+ }
230
+ }
231
+ }
232
+ attachChild(child, before) {
233
+ if (before) {
234
+ const previous = before[PREV];
94
235
  child[NEXT] = before;
95
- child[PREV] = before[PREV];
96
- if (before[PREV] === null) this[CHILD] = child;
236
+ child[PREV] = previous;
237
+ if (previous) previous[NEXT] = child;
238
+ else this[CHILD] = child;
97
239
  before[PREV] = child;
98
240
  } else {
99
241
  child[NEXT] = null;
@@ -108,40 +250,171 @@ class ParentNode extends ChildNode {
108
250
  child[PREV] = null;
109
251
  }
110
252
  }
111
- const ownerDocument = this[OWNER_DOCUMENT];
112
- const isElement = child.nodeType === NodeType.ELEMENT_NODE;
253
+ const isElement = isElementNode(child);
113
254
  child[PARENT] = this;
114
- child[OWNER_DOCUMENT] = ownerDocument;
115
- const childNodes = this.childNodes;
116
255
  let insertIndex;
117
256
  if (before) {
118
- insertIndex = childNodes.indexOf(before);
119
- childNodes.splice(insertIndex, 0, child);
257
+ insertIndex = this.childNodes.indexOf(before);
258
+ this.childNodes.splice(insertIndex, 0, child);
120
259
  if (isElement) {
121
- const children = this.children;
122
- let ref = before;
123
- while (ref && ref.nodeType !== 1) ref = ref[NEXT];
124
- if (ref) {
125
- children.splice(children.indexOf(ref), 0, child);
260
+ let reference = before;
261
+ while (reference && !isElementNode(reference)) {
262
+ reference = reference[NEXT];
263
+ }
264
+ if (reference) {
265
+ this.children.splice(this.children.indexOf(reference), 0, child);
126
266
  } else {
127
- children.push(child);
267
+ this.children.push(child);
128
268
  }
129
269
  }
130
270
  } else {
131
- insertIndex = childNodes.length;
132
- childNodes.push(child);
271
+ insertIndex = this.childNodes.length;
272
+ this.childNodes.push(child);
133
273
  if (isElement) this.children.push(child);
134
274
  }
135
- if (this[IS_CONNECTED]) {
136
- for (const node of selfAndDescendants(child)) {
137
- node[IS_CONNECTED] = true;
138
- node.connectedCallback?.();
275
+ return {
276
+ index: insertIndex,
277
+ previousSibling: child[PREV],
278
+ nextSibling: child[NEXT]
279
+ };
280
+ }
281
+ queueRemovalMutationRecord(parent, child, previousSibling, nextSibling) {
282
+ if (!childListObserversActive) return;
283
+ queueMutationRecord({
284
+ type: "childList",
285
+ target: parent,
286
+ removedNodes: mutationNodeList(child),
287
+ previousSibling,
288
+ nextSibling
289
+ });
290
+ }
291
+ queueInsertionMutationRecords(insertion) {
292
+ if (!childListObserversActive) return;
293
+ for (const prepared of insertion) {
294
+ const { node, source } = prepared;
295
+ if (source) {
296
+ this.queueRemovalMutationRecord(
297
+ source.parent,
298
+ node,
299
+ source.previousSibling,
300
+ source.nextSibling
301
+ );
302
+ }
303
+ queueMutationRecord({
304
+ type: "childList",
305
+ target: this,
306
+ addedNodes: mutationNodeList(node),
307
+ previousSibling: prepared.previousSibling,
308
+ nextSibling: prepared.nextSibling
309
+ });
310
+ }
311
+ }
312
+ collectRemovalHookEffects(child, childNodesIndex) {
313
+ if (this.nodeType !== NODE_TYPE_ELEMENT || isCoveredByPendingPublication(this)) {
314
+ return [];
315
+ }
316
+ return [
317
+ [
318
+ () => this[HOOKS].removeChild?.(this, child, childNodesIndex)
319
+ ]
320
+ ];
321
+ }
322
+ collectInsertionHookEffects(insertion) {
323
+ const effects = [];
324
+ for (const prepared of insertion) {
325
+ const { node, source } = prepared;
326
+ if (source?.parent.nodeType === NODE_TYPE_ELEMENT && !isCoveredByPendingPublication(source.parent)) {
327
+ effects.push([
328
+ () => source.parent[HOOKS].removeChild?.(
329
+ source.parent,
330
+ node,
331
+ source.index
332
+ )
333
+ ]);
334
+ }
335
+ if (this.nodeType === NODE_TYPE_ELEMENT && !isCoveredByPendingPublication(this)) {
336
+ effects.push([
337
+ () => this[HOOKS].insertChild?.(
338
+ this,
339
+ node,
340
+ prepared.insertIndex
341
+ ),
342
+ node
343
+ ]);
344
+ }
345
+ }
346
+ return effects;
347
+ }
348
+ enqueueInsertionReactions(insertion, destinationIsConnected) {
349
+ for (const prepared of insertion) {
350
+ const { nodes } = prepared;
351
+ if (nodes) {
352
+ if (prepared.shouldDisconnect) {
353
+ this.enqueueTreeReactions(nodes, "disconnectedCallback");
354
+ }
355
+ if (destinationIsConnected) {
356
+ this.enqueueTreeReactions(nodes, "connectedCallback");
357
+ }
139
358
  }
140
359
  }
141
- if (this.nodeType === NodeType.ELEMENT_NODE) {
142
- this[HOOKS].insertChild?.(this, child, insertIndex);
360
+ }
361
+ enqueueTreeReactions(nodes, callbackName) {
362
+ enqueueTreeReactions(nodes, callbackName);
363
+ }
364
+ }
365
+ function removeChildForAdoption(parent, child, adoption, destination) {
366
+ if (child.parentNode !== parent) throw Error(`not a child of this node`);
367
+ const disconnectedNodes = parent[IS_CONNECTED] ? adoption.treeNodes : void 0;
368
+ const previousSibling = child[PREV];
369
+ const nextSibling = child[NEXT];
370
+ const childNodesIndex = detachChild(parent, child);
371
+ if (disconnectedNodes) {
372
+ for (const node of disconnectedNodes) node[IS_CONNECTED] = false;
373
+ }
374
+ adoptNodes(adoption.nodes, destination);
375
+ if (childListObserversActive) {
376
+ queueMutationRecord({
377
+ type: "childList",
378
+ target: parent,
379
+ removedNodes: mutationNodeList(child),
380
+ previousSibling,
381
+ nextSibling
382
+ });
383
+ }
384
+ if (disconnectedNodes) {
385
+ enqueueTreeReactions(disconnectedNodes, "disconnectedCallback");
386
+ }
387
+ const effects = [];
388
+ if (parent.nodeType === NODE_TYPE_ELEMENT && !isCoveredByPendingPublication(parent)) {
389
+ effects.push([
390
+ () => parent[HOOKS].removeChild?.(parent, child, childNodesIndex)
391
+ ]);
392
+ }
393
+ performHookEffects(effects);
394
+ }
395
+ function detachChild(parent, child) {
396
+ const previous = child[PREV];
397
+ const next = child[NEXT];
398
+ if (previous) previous[NEXT] = next;
399
+ else parent[CHILD] = next;
400
+ if (next) next[PREV] = previous;
401
+ const childNodesIndex = parent.childNodes.indexOf(child);
402
+ parent.childNodes.splice(childNodesIndex, 1);
403
+ if (isElementNode(child)) {
404
+ parent.children.splice(parent.children.indexOf(child), 1);
405
+ }
406
+ child[PARENT] = null;
407
+ child[NEXT] = null;
408
+ child[PREV] = null;
409
+ return childNodesIndex;
410
+ }
411
+ function enqueueTreeReactions(nodes, callbackName) {
412
+ for (const node of nodes) {
413
+ const callback = node[callbackName];
414
+ if (typeof callback === "function") {
415
+ enqueueCustomElementReaction(node, () => callback.call(node));
143
416
  }
144
417
  }
145
418
  }
146
419
 
147
- export { ParentNode };
420
+ export { ParentNode, removeChildForAdoption };
@@ -1,8 +1,8 @@
1
- import { NS, NamespaceURI } from './constants.esnext';
1
+ import { SVG_NAMESPACE, NS } from './constants.esnext';
2
2
  import { Element } from './Element.esnext';
3
3
 
4
4
  class SVGElement extends Element {
5
- [NS] = NamespaceURI.SVG;
5
+ [NS] = SVG_NAMESPACE;
6
6
  get ownerSVGElement() {
7
7
  let root = null;
8
8
  let parent = this.parentNode;
@@ -1,8 +1,8 @@
1
- import { NodeType, NAME } from './constants.esnext';
1
+ import { NODE_TYPE_TEXT, NAME } from './constants.esnext';
2
2
  import { CharacterData } from './CharacterData.esnext';
3
3
 
4
4
  class Text extends CharacterData {
5
- nodeType = NodeType.TEXT_NODE;
5
+ nodeType = NODE_TYPE_TEXT;
6
6
  [NAME] = "#text";
7
7
  }
8
8