@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,27 +1,53 @@
1
- import { CHILD, NEXT, PARENT, PREV } from './constants.mjs';
1
+ import { CHILD, asciiLowercase, NEXT, splitOnASCIIWhitespace, HTML_NAMESPACE, PARENT, PREV } from './constants.mjs';
2
2
  import { isElementNode } from './shared.mjs';
3
+ import { NodeList } from './NodeList.mjs';
4
+ import { createDOMException } from './dom-exception.mjs';
3
5
 
4
- var Combinator = /*#__PURE__*/function (Combinator) {
5
- Combinator[Combinator["Descendant"] = 0] = "Descendant";
6
- Combinator[Combinator["Child"] = 1] = "Child";
7
- Combinator[Combinator["Sibling"] = 2] = "Sibling";
8
- Combinator[Combinator["Adjacent"] = 3] = "Adjacent";
9
- Combinator[Combinator["Inner"] = 4] = "Inner";
10
- return Combinator;
11
- }(Combinator || {});
12
- var MatcherType = /*#__PURE__*/function (MatcherType) {
13
- MatcherType[MatcherType["Unknown"] = 0] = "Unknown";
14
- MatcherType[MatcherType["Element"] = 1] = "Element";
15
- MatcherType[MatcherType["Id"] = 2] = "Id";
16
- MatcherType[MatcherType["Class"] = 3] = "Class";
17
- MatcherType[MatcherType["Attribute"] = 4] = "Attribute";
18
- MatcherType[MatcherType["Pseudo"] = 5] = "Pseudo";
19
- MatcherType[MatcherType["Function"] = 6] = "Function";
20
- return MatcherType;
21
- }(MatcherType || {});
22
- const ELEMENT_SELECTOR_TEST = /[a-z]/;
6
+ const COMBINATOR_DESCENDANT = 0;
7
+ const COMBINATOR_CHILD = 1;
8
+ const COMBINATOR_SIBLING = 2;
9
+ const COMBINATOR_ADJACENT = 3;
10
+ const COMBINATOR_INNER = 4;
11
+ const MATCHER_UNKNOWN = 0;
12
+ const MATCHER_ELEMENT = 1;
13
+ const MATCHER_ID = 2;
14
+ const MATCHER_CLASS = 3;
15
+ const MATCHER_ATTRIBUTE = 4;
16
+ const MATCHER_PSEUDO = 5;
17
+ const MATCHER_FUNCTION = 6;
18
+ const MATCHER_SCOPE = 7;
19
+ const SUPPORTED_IDENTIFIER_TEST = /^(?:--|-?[A-Za-z_\u0080-\u{10FFFF}])[A-Za-z0-9_\u0080-\u{10FFFF}-]*$/u;
20
+ function readFunctionArgument(selector, start) {
21
+ let depth = 1;
22
+ let quote = null;
23
+ for (let index = start; index < selector.length; index++) {
24
+ const character = selector[index];
25
+ if (quote) {
26
+ if (character === '\\') {
27
+ index++;
28
+ } else if (character === quote) {
29
+ quote = null;
30
+ }
31
+ continue;
32
+ }
33
+ if (character === '"' || character === "'") {
34
+ quote = character;
35
+ } else if (character === '(') {
36
+ depth++;
37
+ } else if (character === ')' && --depth === 0) {
38
+ return [selector.slice(start, index), index + 1];
39
+ }
40
+ }
41
+ return [selector.slice(start), selector.length];
42
+ }
43
+ function throwSelectorSyntaxError(selector) {
44
+ throw createDOMException(`Invalid or unsupported selector: "${selector}"`, 'SyntaxError');
45
+ }
23
46
  function querySelector(within, selector) {
24
- const parts = parseSelector(selector);
47
+ const parts = typeof selector === 'string' ? parseSelector(selector) : [{
48
+ combinator: COMBINATOR_INNER,
49
+ matchers: selector
50
+ }];
25
51
  let result = null;
26
52
  const child = within[CHILD];
27
53
  if (child && parts[0].matchers.length) {
@@ -33,8 +59,11 @@ function querySelector(within, selector) {
33
59
  return result;
34
60
  }
35
61
  function querySelectorAll(within, selector) {
36
- const parts = parseSelector(selector);
37
- const results = [];
62
+ const parts = typeof selector === 'string' ? parseSelector(selector) : [{
63
+ combinator: COMBINATOR_INNER,
64
+ matchers: selector
65
+ }];
66
+ const results = new NodeList();
38
67
  const child = within[CHILD];
39
68
  if (child && parts[0].matchers.length) {
40
69
  walkNodesForSelector(child, parts, node => {
@@ -43,98 +72,170 @@ function querySelectorAll(within, selector) {
43
72
  }
44
73
  return results;
45
74
  }
46
- function parseSelector(selector) {
75
+ function parseSelector(selector, insideHas = false, allowLeadingCombinator = false) {
47
76
  let part = {
48
- combinator: Combinator.Inner,
77
+ combinator: COMBINATOR_INNER,
49
78
  matchers: []
50
79
  };
51
80
  const parts = [part];
52
- const tokenizer = /\s*?([>\s+~]?)\s*?(?:(?:\[\s*([^\]=]+)(?:=(['"])(.*?)\3)?\s*\])|([#.]?)([^\s#.[>:+~]+)|:(\w+)(?:\((.*?)\))?)/gi;
81
+ const tokenizer = /[\t\n\f\r ]*?([>\t\n\f\r +~]?)[\t\n\f\r ]*?(?:(?:\[[\t\n\f\r ]*([^\]=\t\n\f\r ]+)[\t\n\f\r ]*(?:=[\t\n\f\r ]*(?:(['"])(.*?)\3|([^\]\t\n\f\r ]+)))?[\t\n\f\r ]*(?:\]|$))|([#.]?)([^\t\n\f\r #.[>:+~()]+)|:(\w+)(\()?)/gi;
82
+ const normalizedSelector = selector.replace(/^[\t\n\f\r ]+|[\t\n\f\r ]+$/g, '');
83
+ if (normalizedSelector === '') throwSelectorSyntaxError(selector);
84
+ let consumed = 0;
53
85
  let token;
54
- while (token = tokenizer.exec(selector)) {
55
- // [1]: ancestor/parent/sibling/adjacent
86
+ while (token = tokenizer.exec(normalizedSelector)) {
87
+ if (token.index !== consumed) throwSelectorSyntaxError(selector);
88
+
89
+ // [1]: ancestor/ parent/ sibling/ adjacent
56
90
  // [2]: attribute name
57
- // [4]: attribute value
58
- // [5]: id/class sigil
59
- // [6]: id/class name
60
- // [7]: :pseudo/:function() name
61
- // [8]: :function(argument) value
91
+ // [3]/[4]: quoted attribute value
92
+ // [5]: unquoted attribute value
93
+ // [6]: id/class sigil
94
+ // [7]: id/class/type name
95
+ // [8]: :pseudo/:function() name
96
+ // [9]: :function opening parenthesis
62
97
  if (token[1]) {
63
- // Update the combinator on the (now parent) Part:
64
- if (token[1] === '>') part.combinator = Combinator.Child;else if (token[1] === '+') part.combinator = Combinator.Adjacent;else if (token[1] === '~') part.combinator = Combinator.Sibling;else part.combinator = Combinator.Descendant;
65
- // Add a new Part for the next selector parts:
98
+ if (part.matchers.length === 0 && !(allowLeadingCombinator && parts.length === 1)) {
99
+ throwSelectorSyntaxError(selector);
100
+ }
101
+ if (token[1] === '>') part.combinator = COMBINATOR_CHILD;else if (token[1] === '+') part.combinator = COMBINATOR_ADJACENT;else if (token[1] === '~') part.combinator = COMBINATOR_SIBLING;else part.combinator = COMBINATOR_DESCENDANT;
66
102
  part = {
67
- combinator: Combinator.Inner,
103
+ combinator: COMBINATOR_INNER,
68
104
  matchers: []
69
105
  };
70
106
  parts.push(part);
71
107
  }
72
- let type = MatcherType.Unknown;
108
+ const name = token[8] ? asciiLowercase(token[8]) : token[2] || token[7];
109
+ const isTypeSelector = token[7] != null && !token[6];
110
+ if (isTypeSelector && part.matchers.length > 0) {
111
+ throwSelectorSyntaxError(selector);
112
+ }
113
+ let type;
114
+ let value = token[4] ?? token[5] ?? token[7];
73
115
  if (token[2]) {
74
- type = MatcherType.Attribute;
75
- } else if (token[5]) {
76
- type = token[5] === '#' ? MatcherType.Id : MatcherType.Class;
77
- } else if (token[7]) {
78
- type = token[8] == null ? MatcherType.Pseudo : MatcherType.Function;
116
+ if (!SUPPORTED_IDENTIFIER_TEST.test(name)) {
117
+ throwSelectorSyntaxError(selector);
118
+ }
119
+ const unquotedValue = token[5];
120
+ const openingQuote = unquotedValue?.[0];
121
+ if (token[3] == null && (openingQuote === '"' || openingQuote === "'")) {
122
+ const valueOffset = token[0].lastIndexOf(unquotedValue);
123
+ value = normalizedSelector.slice(token.index + valueOffset + 1);
124
+ tokenizer.lastIndex = normalizedSelector.length;
125
+ } else if (unquotedValue != null && !SUPPORTED_IDENTIFIER_TEST.test(unquotedValue)) {
126
+ throwSelectorSyntaxError(selector);
127
+ }
128
+ type = MATCHER_ATTRIBUTE;
79
129
  } else if (token[6]) {
80
- if (token[6] === '*') {
81
- type = MatcherType.Unknown; // Universal selector matches all
82
- } else if (ELEMENT_SELECTOR_TEST.test(token[6])) {
83
- type = MatcherType.Element;
130
+ if (!SUPPORTED_IDENTIFIER_TEST.test(name)) {
131
+ throwSelectorSyntaxError(selector);
84
132
  }
133
+ type = token[6] === '#' ? MATCHER_ID : MATCHER_CLASS;
134
+ } else if (token[8]) {
135
+ type = token[9] == null ? MATCHER_PSEUDO : MATCHER_FUNCTION;
136
+ } else if (token[7] === '*') {
137
+ type = MATCHER_UNKNOWN;
138
+ } else if (token[7] && SUPPORTED_IDENTIFIER_TEST.test(token[7])) {
139
+ type = MATCHER_ELEMENT;
140
+ } else {
141
+ throwSelectorSyntaxError(selector);
142
+ }
143
+ if (token[9]) {
144
+ [value, tokenizer.lastIndex] = readFunctionArgument(normalizedSelector, tokenizer.lastIndex);
145
+ if (name !== 'has' && name !== 'not') {
146
+ throwSelectorSyntaxError(selector);
147
+ }
148
+ if (name === 'has' && insideHas) throwSelectorSyntaxError(selector);
149
+ parseSelector(value, insideHas || name === 'has', name === 'has');
150
+ } else if (type === MATCHER_PSEUDO) {
151
+ throwSelectorSyntaxError(selector);
85
152
  }
86
153
  part.matchers.push({
87
154
  type,
88
- name: token[2] || token[6] || token[7],
89
- value: token[4] ?? token[6] ?? token[8]
155
+ name,
156
+ value
90
157
  });
158
+ consumed = tokenizer.lastIndex;
159
+ }
160
+ if (consumed !== normalizedSelector.length || part.matchers.length === 0) {
161
+ throwSelectorSyntaxError(selector);
91
162
  }
92
163
  return parts;
93
164
  }
94
165
  function matchesSelector(element, selector) {
95
166
  const parsed = parseSelector(selector);
96
- let part;
97
- while (part = parsed.pop()) {
98
- if (!matchesSelectorPart(element, part)) return false;
99
- }
100
- return true;
167
+ return parsed[0]?.matchers.length ? matchesSelectorRecursive(element, parsed) : false;
101
168
  }
102
- function walkNodesForSelector(node, parts, callback) {
103
- if (isElementNode(node)) {
104
- if (matchesSelectorRecursive(node, parts)) {
105
- if (callback(node) === false) return false;
106
- }
107
- const child = node[CHILD];
108
- if (child && walkNodesForSelector(child, parts, callback) === false) {
109
- return false;
110
- }
169
+ function matchesRelativeSelector(scope, selector) {
170
+ const parts = parseSelector(selector, true, true);
171
+ const first = parts[0];
172
+ if (parts.length === 1 && first.matchers.length === 0) return false;
173
+ let leadingCombinator = COMBINATOR_DESCENDANT;
174
+ const scopeMatcher = {
175
+ type: MATCHER_SCOPE,
176
+ name: ':scope'
177
+ };
178
+ if (first.matchers.length === 0) {
179
+ leadingCombinator = first.combinator;
180
+ first.matchers.push(scopeMatcher);
181
+ } else {
182
+ parts.unshift({
183
+ combinator: COMBINATOR_DESCENDANT,
184
+ matchers: [scopeMatcher]
185
+ });
111
186
  }
112
- const next = node[NEXT];
113
- if (next && walkNodesForSelector(next, parts, callback) === false) {
187
+ if (parts.some(({
188
+ matchers
189
+ }) => matchers.length === 0)) return false;
190
+ const root = leadingCombinator === COMBINATOR_ADJACENT || leadingCombinator === COMBINATOR_SIBLING ? scope[NEXT] : scope[CHILD];
191
+ if (!root) return false;
192
+ let matched = false;
193
+ walkNodesForSelector(root, parts, () => {
194
+ matched = true;
114
195
  return false;
196
+ }, scope);
197
+ return matched;
198
+ }
199
+ function walkNodesForSelector(node, parts, callback, scope) {
200
+ const pendingSiblings = [];
201
+ let current = node;
202
+ while (current) {
203
+ if (isElementNode(current)) {
204
+ if (matchesSelectorRecursive(current, parts, scope)) {
205
+ if (callback(current) === false) return false;
206
+ }
207
+ const child = current[CHILD];
208
+ if (child) {
209
+ const sibling = current[NEXT];
210
+ if (sibling) pendingSiblings.push(sibling);
211
+ current = child;
212
+ continue;
213
+ }
214
+ }
215
+ current = current[NEXT] ?? pendingSiblings.pop() ?? null;
115
216
  }
116
217
  return true;
117
218
  }
118
- function matchesSelectorRecursive(element, parts) {
219
+ function matchesSelectorRecursive(element, parts, scope) {
119
220
  const {
120
221
  combinator,
121
222
  matchers
122
223
  } = parts[parts.length - 1];
123
- if (combinator === Combinator.Inner) {
124
- if (!matchesSelectorMatcher(element, matchers)) return false;
224
+ if (combinator === COMBINATOR_INNER) {
225
+ if (!matchesSelectorMatcher(element, matchers, scope)) return false;
125
226
  const pp = parts.slice(0, -1);
126
- return pp.length === 0 || matchesSelectorRecursive(element, pp);
227
+ return pp.length === 0 || matchesSelectorRecursive(element, pp, scope);
127
228
  }
128
- const link = combinator === Combinator.Child || combinator === Combinator.Descendant ? PARENT : PREV;
229
+ const link = combinator === COMBINATOR_CHILD || combinator === COMBINATOR_DESCENDANT ? PARENT : PREV;
129
230
  let ref = element[link];
130
231
  if (!ref) return false;
131
- if (combinator === Combinator.Descendant || combinator === Combinator.Sibling) {
232
+ if (combinator === COMBINATOR_DESCENDANT || combinator === COMBINATOR_SIBLING) {
132
233
  // For descendant/sibling combinators, search through all ancestors/siblings
133
234
  while (ref) {
134
- if (isElementNode(ref) && matchesSelectorMatcher(ref, matchers)) {
235
+ if (isElementNode(ref) && matchesSelectorMatcher(ref, matchers, scope)) {
135
236
  const pp = parts.slice(0, -1);
136
237
  if (pp.length === 0) return true;
137
- if (matchesSelectorRecursive(element, pp)) return true;
238
+ if (matchesSelectorRecursive(ref, pp, scope)) return true;
138
239
  }
139
240
  ref = ref[link];
140
241
  }
@@ -142,53 +243,30 @@ function matchesSelectorRecursive(element, parts) {
142
243
  } else {
143
244
  // For child/adjacent combinators, check only the immediate parent/sibling
144
245
  // For sibling combinators, skip non-element siblings
145
- if (combinator === Combinator.Adjacent && !isElementNode(ref)) {
246
+ if (combinator === COMBINATOR_ADJACENT && !isElementNode(ref)) {
146
247
  // Skip to next element sibling
147
248
  while (ref && !isElementNode(ref)) {
148
249
  ref = ref[link];
149
250
  }
150
251
  if (!ref) return false;
151
252
  }
152
- if (!isElementNode(ref) || !matchesSelectorMatcher(ref, matchers)) {
253
+ if (!isElementNode(ref) || !matchesSelectorMatcher(ref, matchers, scope)) {
153
254
  return false;
154
255
  }
155
256
  const pp = parts.slice(0, -1);
156
- return pp.length === 0 || matchesSelectorRecursive(element, pp);
257
+ return pp.length === 0 || matchesSelectorRecursive(ref, pp, scope);
157
258
  }
158
259
  }
159
- function matchesSelectorPart(element, {
160
- combinator,
161
- matchers
162
- }) {
163
- if (combinator === Combinator.Inner) {
164
- return matchesSelectorMatcher(element, matchers);
165
- }
166
- const link = combinator === Combinator.Child || combinator === Combinator.Descendant ? PARENT : PREV;
167
- let ref = element[link];
168
- if (!ref) return false;
169
-
170
- // For sibling combinators, skip non-element siblings
171
- if (combinator === Combinator.Adjacent && !isElementNode(ref)) {
172
- while (ref && !isElementNode(ref)) {
173
- ref = ref[link];
174
- }
175
- if (!ref) return false;
176
- }
177
- if (!isElementNode(ref) || !matchesSelectorMatcher(ref, matchers)) {
178
- return false;
179
- }
180
- if (combinator === Combinator.Descendant || combinator === Combinator.Sibling) {
181
- while (ref = ref[link]) {
182
- if (isElementNode(ref) && matchesSelectorMatcher(ref, matchers)) return true;
183
- }
184
- }
185
- return true;
260
+ function getSelectorAttribute(element, name) {
261
+ return element.getAttributeNS(null, element.namespaceURI === HTML_NAMESPACE ? asciiLowercase(name) : name);
186
262
  }
187
- function matchesSelectorMatcher(element, matcher) {
263
+ function matchesSelectorMatcher(element, matcher, scope) {
188
264
  if (!element) return false;
189
265
  if (Array.isArray(matcher)) {
190
266
  for (const single of matcher) {
191
- if (matchesSelectorMatcher(element, single) === false) return false;
267
+ if (matchesSelectorMatcher(element, single, scope) === false) {
268
+ return false;
269
+ }
192
270
  }
193
271
  return true;
194
272
  }
@@ -198,35 +276,35 @@ function matchesSelectorMatcher(element, matcher) {
198
276
  value
199
277
  } = matcher;
200
278
  switch (type) {
201
- case MatcherType.Unknown:
279
+ case MATCHER_UNKNOWN:
202
280
  return name === '*';
203
281
  // Universal selector
204
- case MatcherType.Element:
205
- return element.localName === name;
206
- case MatcherType.Id:
207
- return element.getAttribute('id') === name;
208
- case MatcherType.Class:
209
- const classAttr = element.getAttribute('class');
282
+ case MATCHER_ELEMENT:
283
+ return element.namespaceURI === HTML_NAMESPACE ? element.localName === asciiLowercase(name) : element.localName === name;
284
+ case MATCHER_ID:
285
+ return getSelectorAttribute(element, 'id') === name;
286
+ case MATCHER_CLASS:
287
+ const classAttr = getSelectorAttribute(element, 'class');
210
288
  if (!classAttr) return false;
211
- return classAttr.split(/\s+/).includes(name);
212
- case MatcherType.Attribute:
213
- return value == null ? element.hasAttribute(name) : element.getAttribute(name) === value;
214
- case MatcherType.Pseudo:
215
- switch (name) {
216
- default:
217
- throw Error(`Pseudo :${name} not implemented`);
218
- }
219
- case MatcherType.Function:
289
+ return splitOnASCIIWhitespace(classAttr).includes(name);
290
+ case MATCHER_ATTRIBUTE:
291
+ const attribute = getSelectorAttribute(element, name);
292
+ return value == null ? attribute != null : attribute === value;
293
+ case MATCHER_SCOPE:
294
+ return element === scope;
295
+ case MATCHER_PSEUDO:
296
+ throwSelectorSyntaxError(`:${name}`);
297
+ case MATCHER_FUNCTION:
220
298
  switch (name) {
221
299
  case 'has':
222
- return matchesSelector(element, value || '');
300
+ return matchesRelativeSelector(element, value || '');
223
301
  case 'not':
224
302
  return !matchesSelector(element, value || '');
225
303
  default:
226
- throw Error(`Function :${name}(${value}) not implemented`);
304
+ throwSelectorSyntaxError(`:${name}(${value})`);
227
305
  }
228
306
  }
229
307
  return false;
230
308
  }
231
309
 
232
- export { parseSelector, querySelector, querySelectorAll };
310
+ export { COMBINATOR_ADJACENT, COMBINATOR_CHILD, COMBINATOR_DESCENDANT, COMBINATOR_INNER, COMBINATOR_SIBLING, MATCHER_ATTRIBUTE, MATCHER_CLASS, MATCHER_ELEMENT, MATCHER_FUNCTION, MATCHER_ID, MATCHER_PSEUDO, MATCHER_SCOPE, MATCHER_UNKNOWN, parseSelector, querySelector, querySelectorAll };