@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
@@ -0,0 +1,137 @@
1
+ import {CustomElementRegistryImplementation} from '../CustomElementRegistry.ts';
2
+ import {Window} from '../Window.ts';
3
+
4
+ import {beforeEach, describe, expect, it, vi} from 'vitest';
5
+
6
+ beforeEach(() => {
7
+ Window.setGlobalThis(new Window());
8
+ });
9
+
10
+ describe('CustomElementRegistry', () => {
11
+ describe('define()', () => {
12
+ it.each([
13
+ 'my-element',
14
+ 'x-',
15
+ 'ui-4.x_thing',
16
+ 'math-α',
17
+ 'icon-💡',
18
+ 'my-💡!',
19
+ 'my-\u{F0000}',
20
+ ])('defines an element with the valid name %s', (name) => {
21
+ const registry = new CustomElementRegistryImplementation();
22
+ class CustomElement extends HTMLElement {}
23
+
24
+ registry.define(name, CustomElement);
25
+
26
+ expect(registry.get(name)).toBe(CustomElement);
27
+ });
28
+
29
+ it.each([
30
+ '',
31
+ 'element',
32
+ 'My-element',
33
+ '1-element',
34
+ '-element',
35
+ 'my element',
36
+ 'my- element',
37
+ 'my-\telement',
38
+ 'my-\nelement',
39
+ 'my-\felement',
40
+ 'my-\relement',
41
+ 'my-\0element',
42
+ 'my-/element',
43
+ 'my->element',
44
+ 'my-Element',
45
+ 'é-element',
46
+ 'annotation-xml',
47
+ 'color-profile',
48
+ 'font-face',
49
+ 'font-face-src',
50
+ 'font-face-uri',
51
+ 'font-face-format',
52
+ 'font-face-name',
53
+ 'missing-glyph',
54
+ ])('rejects the invalid name %j with a SyntaxError', (name) => {
55
+ const registry = new CustomElementRegistryImplementation();
56
+ class CustomElement extends HTMLElement {}
57
+
58
+ expect(() => registry.define(name, CustomElement)).toThrowError(
59
+ DOMException,
60
+ );
61
+ expect(() => registry.define(name, CustomElement)).toThrowError(
62
+ expect.objectContaining({name: 'SyntaxError'}),
63
+ );
64
+ expect(registry.get(name)).toBeUndefined();
65
+ });
66
+
67
+ it('rejects duplicate names and preserves the original definition', () => {
68
+ const registry = new CustomElementRegistryImplementation();
69
+ class OriginalElement extends HTMLElement {}
70
+ class ReplacementElement extends HTMLElement {}
71
+
72
+ registry.define('original-element', OriginalElement);
73
+
74
+ expect(() =>
75
+ registry.define('original-element', ReplacementElement),
76
+ ).toThrowError(DOMException);
77
+ expect(() =>
78
+ registry.define('original-element', ReplacementElement),
79
+ ).toThrowError(expect.objectContaining({name: 'NotSupportedError'}));
80
+ expect(registry.get('original-element')).toBe(OriginalElement);
81
+ expect(registry.getName(ReplacementElement)).toBeNull();
82
+ });
83
+
84
+ it('rejects duplicate constructors and preserves the original definition', () => {
85
+ const registry = new CustomElementRegistryImplementation();
86
+ class CustomElement extends HTMLElement {}
87
+
88
+ registry.define('original-element', CustomElement);
89
+
90
+ expect(() =>
91
+ registry.define('replacement-element', CustomElement),
92
+ ).toThrowError(DOMException);
93
+ expect(() =>
94
+ registry.define('replacement-element', CustomElement),
95
+ ).toThrowError(expect.objectContaining({name: 'NotSupportedError'}));
96
+ expect(registry.get('replacement-element')).toBeUndefined();
97
+ expect(registry.getName(CustomElement)).toBe('original-element');
98
+ });
99
+
100
+ it('notifies whenDefined() listeners only after a successful definition', async () => {
101
+ const registry = new CustomElementRegistryImplementation();
102
+ class OriginalElement extends HTMLElement {}
103
+ class ReplacementElement extends HTMLElement {}
104
+ const listener = vi.fn();
105
+ const definition = registry
106
+ .whenDefined('replacement-element')
107
+ .then(listener);
108
+
109
+ registry.define('original-element', OriginalElement);
110
+ expect(() =>
111
+ registry.define('replacement-element', OriginalElement),
112
+ ).toThrowError(expect.objectContaining({name: 'NotSupportedError'}));
113
+
114
+ await Promise.resolve();
115
+ expect(listener).not.toHaveBeenCalled();
116
+
117
+ registry.define('replacement-element', ReplacementElement);
118
+ await definition;
119
+ expect(listener).toHaveBeenCalledOnce();
120
+ expect(listener).toHaveBeenCalledWith(ReplacementElement);
121
+ });
122
+ });
123
+
124
+ describe('whenDefined()', () => {
125
+ it.each(['element', 'My-element', 'font-face'])(
126
+ 'rejects the invalid name %s with a SyntaxError',
127
+ async (name) => {
128
+ const registry = new CustomElementRegistryImplementation();
129
+
130
+ const definition = registry.whenDefined(name);
131
+
132
+ await expect(definition).rejects.toBeInstanceOf(DOMException);
133
+ await expect(definition).rejects.toMatchObject({name: 'SyntaxError'});
134
+ },
135
+ );
136
+ });
137
+ });
@@ -0,0 +1,26 @@
1
+ import {describe, expect, it} from 'vitest';
2
+
3
+ import {CustomEvent} from '../CustomEvent.ts';
4
+
5
+ describe('CustomEvent', () => {
6
+ describe('constructor', () => {
7
+ it('defaults detail to null when the initialization dictionary is omitted', () => {
8
+ expect(new CustomEvent('test').detail).toBeNull();
9
+ });
10
+
11
+ it('defaults detail to null when omitted from the initialization dictionary', () => {
12
+ expect(new CustomEvent('test', {}).detail).toBeNull();
13
+ });
14
+
15
+ it('defaults an explicitly undefined detail to null', () => {
16
+ expect(new CustomEvent('test', {detail: undefined}).detail).toBeNull();
17
+ });
18
+
19
+ it.each([null, 0, false, '', {custom: 'detail'}])(
20
+ 'preserves an explicitly supplied detail value of %j',
21
+ (detail) => {
22
+ expect(new CustomEvent('test', {detail}).detail).toBe(detail);
23
+ },
24
+ );
25
+ });
26
+ });
@@ -0,0 +1,77 @@
1
+ import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
2
+
3
+ import {Window} from '../index.ts';
4
+
5
+ let window: Window;
6
+ let document: Window['document'];
7
+
8
+ beforeEach(() => {
9
+ window = new Window();
10
+ Window.setGlobalThis(window);
11
+ document = window.document;
12
+ });
13
+
14
+ afterEach(() => {
15
+ vi.unstubAllGlobals();
16
+ });
17
+
18
+ describe('Document cloning and importing', () => {
19
+ it.each([false, true])(
20
+ 'rejects cloneNode(%s) with a named, clear error',
21
+ (deep) => {
22
+ const clone = () => document.cloneNode(deep);
23
+
24
+ expect(clone).toThrowError(DOMException);
25
+ expect(clone).toThrowError(
26
+ expect.objectContaining({
27
+ name: 'NotSupportedError',
28
+ message: 'Cannot clone a document node',
29
+ }),
30
+ );
31
+ },
32
+ );
33
+
34
+ it.each([false, true])(
35
+ 'rejects importNode(document, %s) with a named, clear error',
36
+ (deep) => {
37
+ const destination = new Window().document;
38
+ const importDocument = () => destination.importNode(document, deep);
39
+
40
+ expect(importDocument).toThrowError(DOMException);
41
+ expect(importDocument).toThrowError(
42
+ expect.objectContaining({
43
+ name: 'NotSupportedError',
44
+ message: 'Cannot import a document node',
45
+ }),
46
+ );
47
+ },
48
+ );
49
+
50
+ it('continues to clone and import supported document descendants', () => {
51
+ document.body.append('content');
52
+ const destination = new Window().document;
53
+
54
+ const clone = document.documentElement.cloneNode(true);
55
+ const imported = destination.importNode(document.documentElement, true);
56
+
57
+ expect(clone.textContent).toBe('content');
58
+ expect(clone.ownerDocument).toBe(document);
59
+ expect(imported.textContent).toBe('content');
60
+ expect(imported.ownerDocument).toBe(destination);
61
+ });
62
+
63
+ it('preserves the named error when DOMException is unavailable', () => {
64
+ vi.stubGlobal('DOMException', undefined);
65
+ const destination = new Window().document;
66
+
67
+ for (const operation of [
68
+ () => document.cloneNode(),
69
+ () => destination.importNode(document),
70
+ ]) {
71
+ expect(operation).toThrowError(Error);
72
+ expect(operation).toThrowError(
73
+ expect.objectContaining({name: 'NotSupportedError'}),
74
+ );
75
+ }
76
+ });
77
+ });
@@ -0,0 +1,122 @@
1
+ import {Window} from '../index.ts';
2
+
3
+ import {beforeEach, describe, expect, it} from 'vitest';
4
+
5
+ beforeEach(() => {
6
+ const window = new Window();
7
+ Window.setGlobalThis(window);
8
+ });
9
+
10
+ describe('NonElementParentNode.getElementById', () => {
11
+ describe('Document', () => {
12
+ it('returns the first matching element in tree order after arbitrary insertions', () => {
13
+ const container = document.createElement('div');
14
+ const createTarget = () => {
15
+ const element = document.createElement('span');
16
+ element.id = 'target';
17
+ return element;
18
+ };
19
+ const first = createTarget();
20
+ const second = createTarget();
21
+ const third = createTarget();
22
+ const fourth = createTarget();
23
+
24
+ container.appendChild(second);
25
+ container.appendChild(fourth);
26
+ container.insertBefore(third, fourth);
27
+ container.insertBefore(first, second);
28
+ document.body.appendChild(container);
29
+
30
+ for (const element of [first, second, third, fourth]) {
31
+ expect(document.getElementById('target')).toBe(element);
32
+ element.remove();
33
+ }
34
+
35
+ expect(document.getElementById('target')).toBeNull();
36
+ });
37
+
38
+ it('only returns elements connected to the document', () => {
39
+ const container = document.createElement('div');
40
+ const target = document.createElement('span');
41
+ target.id = 'target';
42
+ container.appendChild(target);
43
+
44
+ expect(document.getElementById('target')).toBeNull();
45
+
46
+ document.body.appendChild(container);
47
+ expect(document.getElementById('target')).toBe(target);
48
+
49
+ container.remove();
50
+ expect(document.getElementById('target')).toBeNull();
51
+ });
52
+
53
+ it('reflects id property and attribute changes immediately', () => {
54
+ const target = document.createElement('div');
55
+ document.body.appendChild(target);
56
+
57
+ target.id = 'before';
58
+ expect(target.getAttribute('id')).toBe('before');
59
+ expect(document.getElementById('before')).toBe(target);
60
+
61
+ target.setAttribute('id', 'after');
62
+ expect(target.id).toBe('after');
63
+ expect(document.getElementById('before')).toBeNull();
64
+ expect(document.getElementById('after')).toBe(target);
65
+
66
+ target.removeAttribute('id');
67
+ expect(target.id).toBe('');
68
+ expect(document.getElementById('after')).toBeNull();
69
+ });
70
+
71
+ it('coerces identifiers to strings but never matches an empty id', () => {
72
+ document.body.innerHTML = `
73
+ <div id=""></div>
74
+ <div id="null"></div>
75
+ <div id="undefined"></div>
76
+ `;
77
+
78
+ expect(document.getElementById('')).toBeNull();
79
+ expect(document.getElementById(null as any)?.id).toBe('null');
80
+ expect(document.getElementById(undefined as any)?.id).toBe('undefined');
81
+ });
82
+
83
+ it('matches identifiers literally instead of parsing them as selectors', () => {
84
+ const ids = ['a.b', 'a b', 'a[b]', 'a:b', 'a#b'];
85
+
86
+ for (const id of ids) {
87
+ const element = document.createElement('div');
88
+ element.id = id;
89
+ document.body.appendChild(element);
90
+ }
91
+
92
+ for (const id of ids) {
93
+ expect(document.getElementById(id)?.id).toBe(id);
94
+ }
95
+ });
96
+ });
97
+
98
+ describe('DocumentFragment', () => {
99
+ it('finds the first matching element within the fragment', () => {
100
+ const fragment = document.createDocumentFragment();
101
+ const first = document.createElement('div');
102
+ const second = document.createElement('div');
103
+ first.id = 'target';
104
+ second.id = 'target';
105
+ fragment.append(first, second);
106
+
107
+ expect(fragment.getElementById('target')).toBe(first);
108
+ expect(fragment.getElementById('missing')).toBeNull();
109
+ });
110
+
111
+ it('does not find elements outside the fragment', () => {
112
+ const target = document.createElement('div');
113
+ target.id = 'target';
114
+ document.body.appendChild(target);
115
+
116
+ const fragment = document.createDocumentFragment();
117
+
118
+ expect(fragment.getElementById('target')).toBeNull();
119
+ expect((target as any).getElementById).toBeUndefined();
120
+ });
121
+ });
122
+ });