@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.
- package/CHANGELOG.md +88 -0
- package/README.md +51 -3
- package/build/cjs/Attr.cjs +33 -4
- package/build/cjs/CharacterData.cjs +10 -0
- package/build/cjs/ChildNode.cjs +79 -13
- package/build/cjs/Comment.cjs +1 -1
- package/build/cjs/CustomElementRegistry.cjs +27 -2
- package/build/cjs/CustomEvent.cjs +2 -2
- package/build/cjs/Document.cjs +56 -32
- package/build/cjs/DocumentFragment.cjs +6 -2
- package/build/cjs/Element.cjs +68 -8
- package/build/cjs/Event.cjs +29 -27
- package/build/cjs/EventTarget.cjs +128 -58
- package/build/cjs/HTMLTemplateElement.cjs +1 -0
- package/build/cjs/MutationObserver.cjs +167 -1
- package/build/cjs/NamedNodeMap.cjs +82 -45
- package/build/cjs/Node.cjs +47 -11
- package/build/cjs/NodeList.cjs +9 -1
- package/build/cjs/ParentNode.cjs +319 -77
- package/build/cjs/SVGElement.cjs +1 -1
- package/build/cjs/Text.cjs +1 -1
- package/build/cjs/Window.cjs +131 -38
- package/build/cjs/attribute-reactions.cjs +20 -0
- package/build/cjs/constants.cjs +48 -24
- package/build/cjs/custom-element-reactions.cjs +52 -0
- package/build/cjs/dom-exception.cjs +15 -0
- package/build/cjs/hook-effects.cjs +51 -0
- package/build/cjs/names.cjs +61 -0
- package/build/cjs/selectors.cjs +213 -122
- package/build/cjs/serialization.cjs +168 -65
- package/build/cjs/shared.cjs +177 -28
- package/build/esm/Attr.mjs +34 -5
- package/build/esm/CharacterData.mjs +10 -0
- package/build/esm/ChildNode.mjs +76 -15
- package/build/esm/Comment.mjs +2 -2
- package/build/esm/CustomElementRegistry.mjs +27 -2
- package/build/esm/CustomEvent.mjs +2 -2
- package/build/esm/Document.mjs +60 -35
- package/build/esm/DocumentFragment.mjs +7 -3
- package/build/esm/Element.mjs +69 -9
- package/build/esm/Event.mjs +27 -27
- package/build/esm/EventTarget.mjs +130 -60
- package/build/esm/HTMLTemplateElement.mjs +2 -1
- package/build/esm/MutationObserver.mjs +166 -2
- package/build/esm/NamedNodeMap.mjs +83 -46
- package/build/esm/Node.mjs +48 -12
- package/build/esm/NodeList.mjs +9 -1
- package/build/esm/ParentNode.mjs +322 -81
- package/build/esm/SVGElement.mjs +2 -2
- package/build/esm/Text.mjs +2 -2
- package/build/esm/Window.mjs +132 -39
- package/build/esm/attribute-reactions.mjs +16 -0
- package/build/esm/constants.mjs +28 -23
- package/build/esm/custom-element-reactions.mjs +47 -0
- package/build/esm/dom-exception.mjs +11 -0
- package/build/esm/hook-effects.mjs +46 -0
- package/build/esm/names.mjs +54 -0
- package/build/esm/selectors.mjs +202 -124
- package/build/esm/serialization.mjs +169 -66
- package/build/esm/shared.mjs +173 -30
- package/build/esnext/Attr.esnext +45 -5
- package/build/esnext/CharacterData.esnext +10 -0
- package/build/esnext/ChildNode.esnext +84 -15
- package/build/esnext/Comment.esnext +2 -2
- package/build/esnext/CustomElementRegistry.esnext +42 -0
- package/build/esnext/CustomEvent.esnext +2 -2
- package/build/esnext/Document.esnext +69 -32
- package/build/esnext/DocumentFragment.esnext +6 -2
- package/build/esnext/Element.esnext +78 -9
- package/build/esnext/Event.esnext +36 -37
- package/build/esnext/EventTarget.esnext +133 -61
- package/build/esnext/HTMLTemplateElement.esnext +3 -1
- package/build/esnext/MutationObserver.esnext +163 -2
- package/build/esnext/NamedNodeMap.esnext +110 -42
- package/build/esnext/Node.esnext +50 -12
- package/build/esnext/NodeList.esnext +1 -1
- package/build/esnext/ParentNode.esnext +352 -79
- package/build/esnext/SVGElement.esnext +2 -2
- package/build/esnext/Text.esnext +2 -2
- package/build/esnext/Window.esnext +120 -16
- package/build/esnext/attribute-reactions.esnext +21 -0
- package/build/esnext/constants.esnext +34 -21
- package/build/esnext/custom-element-reactions.esnext +49 -0
- package/build/esnext/dom-exception.esnext +11 -0
- package/build/esnext/hook-effects.esnext +46 -0
- package/build/esnext/names.esnext +61 -0
- package/build/esnext/selectors.esnext +202 -100
- package/build/esnext/serialization.esnext +171 -48
- package/build/esnext/shared.esnext +181 -34
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/typescript/Attr.d.ts +6 -4
- package/build/typescript/Attr.d.ts.map +1 -1
- package/build/typescript/CharacterData.d.ts.map +1 -1
- package/build/typescript/ChildNode.d.ts +5 -0
- package/build/typescript/ChildNode.d.ts.map +1 -1
- package/build/typescript/ClipboardEvent.d.ts.map +1 -1
- package/build/typescript/Comment.d.ts +2 -2
- package/build/typescript/Comment.d.ts.map +1 -1
- package/build/typescript/CustomElementRegistry.d.ts +1 -0
- package/build/typescript/CustomElementRegistry.d.ts.map +1 -1
- package/build/typescript/CustomEvent.d.ts.map +1 -1
- package/build/typescript/Document.d.ts +10 -5
- package/build/typescript/Document.d.ts.map +1 -1
- package/build/typescript/DocumentFragment.d.ts +2 -1
- package/build/typescript/DocumentFragment.d.ts.map +1 -1
- package/build/typescript/Element.d.ts +16 -7
- package/build/typescript/Element.d.ts.map +1 -1
- package/build/typescript/ErrorEvent.d.ts.map +1 -1
- package/build/typescript/Event.d.ts +9 -10
- package/build/typescript/Event.d.ts.map +1 -1
- package/build/typescript/EventTarget.d.ts +20 -3
- package/build/typescript/EventTarget.d.ts.map +1 -1
- package/build/typescript/FocusEvent.d.ts.map +1 -1
- package/build/typescript/HTMLTemplateElement.d.ts.map +1 -1
- package/build/typescript/MutationObserver.d.ts +42 -0
- package/build/typescript/MutationObserver.d.ts.map +1 -1
- package/build/typescript/NamedNodeMap.d.ts +5 -3
- package/build/typescript/NamedNodeMap.d.ts.map +1 -1
- package/build/typescript/Node.d.ts +4 -3
- package/build/typescript/Node.d.ts.map +1 -1
- package/build/typescript/NodeList.d.ts +3 -2
- package/build/typescript/NodeList.d.ts.map +1 -1
- package/build/typescript/ParentNode.d.ts +29 -10
- package/build/typescript/ParentNode.d.ts.map +1 -1
- package/build/typescript/PromiseRejectionEvent.d.ts.map +1 -1
- package/build/typescript/SVGElement.d.ts +1 -1
- package/build/typescript/SVGElement.d.ts.map +1 -1
- package/build/typescript/Text.d.ts +1 -1
- package/build/typescript/Text.d.ts.map +1 -1
- package/build/typescript/ToggleEvent.d.ts.map +1 -1
- package/build/typescript/Window.d.ts +5 -1
- package/build/typescript/Window.d.ts.map +1 -1
- package/build/typescript/attribute-reactions.d.ts +4 -0
- package/build/typescript/attribute-reactions.d.ts.map +1 -0
- package/build/typescript/constants.d.ts +27 -18
- package/build/typescript/constants.d.ts.map +1 -1
- package/build/typescript/custom-element-reactions.d.ts +6 -0
- package/build/typescript/custom-element-reactions.d.ts.map +1 -0
- package/build/typescript/dom-exception.d.ts +2 -0
- package/build/typescript/dom-exception.d.ts.map +1 -0
- package/build/typescript/extensions.d.ts +4 -0
- package/build/typescript/extensions.d.ts.map +1 -0
- package/build/typescript/hook-effects.d.ts +6 -0
- package/build/typescript/hook-effects.d.ts.map +1 -0
- package/build/typescript/hooks.d.ts +3 -3
- package/build/typescript/hooks.d.ts.map +1 -1
- package/build/typescript/index.d.ts +1 -0
- package/build/typescript/index.d.ts.map +1 -1
- package/build/typescript/names.d.ts +11 -0
- package/build/typescript/names.d.ts.map +1 -0
- package/build/typescript/selectors.d.ts +21 -22
- package/build/typescript/selectors.d.ts.map +1 -1
- package/build/typescript/serialization.d.ts.map +1 -1
- package/build/typescript/shared.d.ts +10 -0
- package/build/typescript/shared.d.ts.map +1 -1
- package/build/typescript/tests/ChildNode.test.d.ts +2 -0
- package/build/typescript/tests/ChildNode.test.d.ts.map +1 -0
- package/build/typescript/tests/MutationObserver.test.d.ts +2 -0
- package/build/typescript/tests/MutationObserver.test.d.ts.map +1 -0
- package/build/typescript/tests/adopt-inserted-subtrees.test.d.ts +2 -0
- package/build/typescript/tests/adopt-inserted-subtrees.test.d.ts.map +1 -0
- package/build/typescript/tests/attr-mutation.test.d.ts +2 -0
- package/build/typescript/tests/attr-mutation.test.d.ts.map +1 -0
- package/build/typescript/tests/child-node-before-after.test.d.ts +2 -0
- package/build/typescript/tests/child-node-before-after.test.d.ts.map +1 -0
- package/build/typescript/tests/child-node-replace-with.test.d.ts +2 -0
- package/build/typescript/tests/child-node-replace-with.test.d.ts.map +1 -0
- package/build/typescript/tests/clone-import-namespaces.test.d.ts +2 -0
- package/build/typescript/tests/clone-import-namespaces.test.d.ts.map +1 -0
- package/build/typescript/tests/constants.test.d.ts +2 -0
- package/build/typescript/tests/constants.test.d.ts.map +1 -0
- package/build/typescript/tests/create-element-namespaces.test.d.ts +2 -0
- package/build/typescript/tests/create-element-namespaces.test.d.ts.map +1 -0
- package/build/typescript/tests/create-text-node.test.d.ts +2 -0
- package/build/typescript/tests/create-text-node.test.d.ts.map +1 -0
- package/build/typescript/tests/custom-element-reactions.test.d.ts +2 -0
- package/build/typescript/tests/custom-element-reactions.test.d.ts.map +1 -0
- package/build/typescript/tests/custom-element-registry.test.d.ts +2 -0
- package/build/typescript/tests/custom-element-registry.test.d.ts.map +1 -0
- package/build/typescript/tests/custom-event.test.d.ts +2 -0
- package/build/typescript/tests/custom-event.test.d.ts.map +1 -0
- package/build/typescript/tests/document-clone-import-contract.test.d.ts +2 -0
- package/build/typescript/tests/document-clone-import-contract.test.d.ts.map +1 -0
- package/build/typescript/tests/document.test.d.ts +2 -0
- package/build/typescript/tests/document.test.d.ts.map +1 -0
- package/build/typescript/tests/dom-mutation-selector-errors.test.d.ts +2 -0
- package/build/typescript/tests/dom-mutation-selector-errors.test.d.ts.map +1 -0
- package/build/typescript/tests/event-dispatch.test.d.ts +2 -0
- package/build/typescript/tests/event-dispatch.test.d.ts.map +1 -0
- package/build/typescript/tests/event-target.test.d.ts +2 -0
- package/build/typescript/tests/event-target.test.d.ts.map +1 -0
- package/build/typescript/tests/event.test.d.ts +2 -0
- package/build/typescript/tests/event.test.d.ts.map +1 -0
- package/build/typescript/tests/extensions.test.d.ts +2 -0
- package/build/typescript/tests/extensions.test.d.ts.map +1 -0
- package/build/typescript/tests/get-elements-by-tag-name.test.d.ts +2 -0
- package/build/typescript/tests/get-elements-by-tag-name.test.d.ts.map +1 -0
- package/build/typescript/tests/getElementsByClassName.test.d.ts +2 -0
- package/build/typescript/tests/getElementsByClassName.test.d.ts.map +1 -0
- package/build/typescript/tests/hooks.test.d.ts +2 -0
- package/build/typescript/tests/hooks.test.d.ts.map +1 -0
- package/build/typescript/tests/inner-html-parsing.test.d.ts +2 -0
- package/build/typescript/tests/inner-html-parsing.test.d.ts.map +1 -0
- package/build/typescript/tests/is-default-namespace.test.d.ts +2 -0
- package/build/typescript/tests/is-default-namespace.test.d.ts.map +1 -0
- package/build/typescript/tests/name-and-namespace-normalization.test.d.ts +2 -0
- package/build/typescript/tests/name-and-namespace-normalization.test.d.ts.map +1 -0
- package/build/typescript/tests/named-node-map.test.d.ts +2 -0
- package/build/typescript/tests/named-node-map.test.d.ts.map +1 -0
- package/build/typescript/tests/namespaced-attribute-reactions.test.d.ts +2 -0
- package/build/typescript/tests/namespaced-attribute-reactions.test.d.ts.map +1 -0
- package/build/typescript/tests/node.test.d.ts +2 -0
- package/build/typescript/tests/node.test.d.ts.map +1 -0
- package/build/typescript/tests/parent-node-mutation-return-values.test.d.ts +2 -0
- package/build/typescript/tests/parent-node-mutation-return-values.test.d.ts.map +1 -0
- package/build/typescript/tests/parent-node-mutation-validation.test.d.ts +2 -0
- package/build/typescript/tests/parent-node-mutation-validation.test.d.ts.map +1 -0
- package/build/typescript/tests/parent-node.test.d.ts +2 -0
- package/build/typescript/tests/parent-node.test.d.ts.map +1 -0
- package/build/typescript/tests/serialization-template.test.d.ts +2 -0
- package/build/typescript/tests/serialization-template.test.d.ts.map +1 -0
- package/build/typescript/tests/slot-attribute.test.d.ts +2 -0
- package/build/typescript/tests/slot-attribute.test.d.ts.map +1 -0
- package/build/typescript/tests/text-content.test.d.ts +2 -0
- package/build/typescript/tests/text-content.test.d.ts.map +1 -0
- package/build/typescript/tests/toggle-attribute.test.d.ts +2 -0
- package/build/typescript/tests/toggle-attribute.test.d.ts.map +1 -0
- package/build/typescript/tests/wide-tree-traversal.test.d.ts +2 -0
- package/build/typescript/tests/wide-tree-traversal.test.d.ts.map +1 -0
- package/build/typescript/tests/window-set-global.test.d.ts +2 -0
- package/build/typescript/tests/window-set-global.test.d.ts.map +1 -0
- package/package.json +1 -1
- package/source/Attr.ts +60 -8
- package/source/CharacterData.ts +13 -0
- package/source/ChildNode.ts +107 -14
- package/source/Comment.ts +2 -2
- package/source/CustomElementRegistry.ts +56 -0
- package/source/CustomEvent.ts +2 -2
- package/source/Document.ts +104 -38
- package/source/DocumentFragment.ts +12 -2
- package/source/Element.ts +129 -14
- package/source/Event.ts +34 -32
- package/source/EventTarget.ts +203 -79
- package/source/HTMLTemplateElement.ts +2 -1
- package/source/MutationObserver.ts +279 -1
- package/source/NamedNodeMap.ts +141 -60
- package/source/Node.ts +70 -14
- package/source/NodeList.ts +13 -3
- package/source/ParentNode.ts +500 -88
- package/source/SVGElement.ts +2 -2
- package/source/Text.ts +2 -2
- package/source/Window.ts +156 -17
- package/source/attribute-reactions.ts +32 -0
- package/source/constants.ts +40 -17
- package/source/custom-element-reactions.ts +64 -0
- package/source/dom-exception.ts +14 -0
- package/source/extensions.ts +4 -0
- package/source/hook-effects.ts +56 -0
- package/source/hooks.ts +11 -3
- package/source/index.ts +1 -0
- package/source/names.ts +94 -0
- package/source/selectors.ts +301 -138
- package/source/serialization.ts +224 -66
- package/source/shared.ts +269 -40
- package/source/tests/ChildNode.test.ts +178 -0
- package/source/tests/MutationObserver.test.ts +303 -0
- package/source/tests/adopt-inserted-subtrees.test.ts +584 -0
- package/source/tests/attr-mutation.test.ts +112 -0
- package/source/tests/child-node-before-after.test.ts +421 -0
- package/source/tests/child-node-replace-with.test.ts +251 -0
- package/source/tests/clone-import-namespaces.test.ts +365 -0
- package/source/tests/constants.test.ts +46 -0
- package/source/tests/create-element-namespaces.test.ts +142 -0
- package/source/tests/create-text-node.test.ts +38 -0
- package/source/tests/custom-element-reactions.test.ts +600 -0
- package/source/tests/custom-element-registry.test.ts +137 -0
- package/source/tests/custom-event.test.ts +26 -0
- package/source/tests/document-clone-import-contract.test.ts +77 -0
- package/source/tests/document.test.ts +122 -0
- package/source/tests/dom-mutation-selector-errors.test.ts +484 -0
- package/source/tests/event-dispatch.test.ts +270 -0
- package/source/tests/event-target.test.ts +208 -0
- package/source/tests/event.test.ts +98 -0
- package/source/tests/extensions.test.ts +159 -0
- package/source/tests/get-elements-by-tag-name.test.ts +79 -0
- package/source/tests/getElementsByClassName.test.ts +109 -0
- package/source/tests/hooks.test.ts +43 -0
- package/source/tests/inner-html-parsing.test.ts +461 -0
- package/source/tests/is-default-namespace.test.ts +111 -0
- package/source/tests/name-and-namespace-normalization.test.ts +319 -0
- package/source/tests/named-node-map.test.ts +122 -0
- package/source/tests/namespaced-attribute-reactions.test.ts +141 -0
- package/source/tests/node.test.ts +56 -0
- package/source/tests/parent-node-mutation-return-values.test.ts +63 -0
- package/source/tests/parent-node-mutation-validation.test.ts +362 -0
- package/source/tests/parent-node.test.ts +169 -0
- package/source/tests/selectors.test.ts +533 -22
- package/source/tests/serialization-template.test.ts +232 -0
- package/source/tests/slot-attribute.test.ts +133 -0
- package/source/tests/text-content.test.ts +440 -0
- package/source/tests/toggle-attribute.test.ts +113 -0
- package/source/tests/wide-tree-traversal.test.ts +699 -0
- package/source/tests/window-set-global.test.ts +321 -0
- package/tsconfig.json +1 -1
package/build/esm/selectors.mjs
CHANGED
|
@@ -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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
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
|
-
|
|
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:
|
|
77
|
+
combinator: COMBINATOR_INNER,
|
|
49
78
|
matchers: []
|
|
50
79
|
};
|
|
51
80
|
const parts = [part];
|
|
52
|
-
const tokenizer =
|
|
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(
|
|
55
|
-
|
|
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]:
|
|
59
|
-
// [6]: id/class
|
|
60
|
-
// [7]:
|
|
61
|
-
// [8]: :function(
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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:
|
|
103
|
+
combinator: COMBINATOR_INNER,
|
|
68
104
|
matchers: []
|
|
69
105
|
};
|
|
70
106
|
parts.push(part);
|
|
71
107
|
}
|
|
72
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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 (
|
|
81
|
-
|
|
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
|
|
89
|
-
value
|
|
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
|
-
|
|
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
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
|
|
113
|
-
|
|
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 ===
|
|
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 ===
|
|
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 ===
|
|
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(
|
|
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 ===
|
|
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(
|
|
257
|
+
return pp.length === 0 || matchesSelectorRecursive(ref, pp, scope);
|
|
157
258
|
}
|
|
158
259
|
}
|
|
159
|
-
function
|
|
160
|
-
|
|
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)
|
|
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
|
|
279
|
+
case MATCHER_UNKNOWN:
|
|
202
280
|
return name === '*';
|
|
203
281
|
// Universal selector
|
|
204
|
-
case
|
|
205
|
-
return element.localName === name;
|
|
206
|
-
case
|
|
207
|
-
return element
|
|
208
|
-
case
|
|
209
|
-
const classAttr = element
|
|
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
|
|
212
|
-
case
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
case
|
|
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
|
|
300
|
+
return matchesRelativeSelector(element, value || '');
|
|
223
301
|
case 'not':
|
|
224
302
|
return !matchesSelector(element, value || '');
|
|
225
303
|
default:
|
|
226
|
-
|
|
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 };
|