@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/source/selectors.ts
CHANGED
|
@@ -1,43 +1,112 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
CHILD,
|
|
3
|
+
NEXT,
|
|
4
|
+
PARENT,
|
|
5
|
+
PREV,
|
|
6
|
+
HTML_NAMESPACE,
|
|
7
|
+
asciiLowercase,
|
|
8
|
+
splitOnASCIIWhitespace,
|
|
9
|
+
} from './constants.ts';
|
|
2
10
|
import {isElementNode} from './shared.ts';
|
|
11
|
+
import {NodeList} from './NodeList.ts';
|
|
12
|
+
import {createDOMException} from './dom-exception.ts';
|
|
3
13
|
|
|
4
14
|
import type {Node} from './Node.ts';
|
|
5
15
|
import type {Element} from './Element.ts';
|
|
6
16
|
import type {ParentNode} from './ParentNode.ts';
|
|
7
17
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Inner,
|
|
14
|
-
}
|
|
18
|
+
export const COMBINATOR_DESCENDANT = 0;
|
|
19
|
+
export const COMBINATOR_CHILD = 1;
|
|
20
|
+
export const COMBINATOR_SIBLING = 2;
|
|
21
|
+
export const COMBINATOR_ADJACENT = 3;
|
|
22
|
+
export const COMBINATOR_INNER = 4;
|
|
15
23
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
export type Combinator =
|
|
25
|
+
| typeof COMBINATOR_DESCENDANT
|
|
26
|
+
| typeof COMBINATOR_CHILD
|
|
27
|
+
| typeof COMBINATOR_SIBLING
|
|
28
|
+
| typeof COMBINATOR_ADJACENT
|
|
29
|
+
| typeof COMBINATOR_INNER;
|
|
30
|
+
|
|
31
|
+
export const MATCHER_UNKNOWN = 0;
|
|
32
|
+
export const MATCHER_ELEMENT = 1;
|
|
33
|
+
export const MATCHER_ID = 2;
|
|
34
|
+
export const MATCHER_CLASS = 3;
|
|
35
|
+
export const MATCHER_ATTRIBUTE = 4;
|
|
36
|
+
export const MATCHER_PSEUDO = 5;
|
|
37
|
+
export const MATCHER_FUNCTION = 6;
|
|
38
|
+
export const MATCHER_SCOPE = 7;
|
|
25
39
|
|
|
26
|
-
|
|
40
|
+
export type MatcherType =
|
|
41
|
+
| typeof MATCHER_UNKNOWN
|
|
42
|
+
| typeof MATCHER_ELEMENT
|
|
43
|
+
| typeof MATCHER_ID
|
|
44
|
+
| typeof MATCHER_CLASS
|
|
45
|
+
| typeof MATCHER_ATTRIBUTE
|
|
46
|
+
| typeof MATCHER_PSEUDO
|
|
47
|
+
| typeof MATCHER_FUNCTION
|
|
48
|
+
| typeof MATCHER_SCOPE;
|
|
49
|
+
|
|
50
|
+
export interface Part {
|
|
27
51
|
combinator: Combinator;
|
|
28
52
|
matchers: Matcher[];
|
|
29
53
|
}
|
|
30
54
|
|
|
31
|
-
interface Matcher {
|
|
55
|
+
export interface Matcher {
|
|
32
56
|
type: MatcherType;
|
|
33
57
|
name: string;
|
|
34
58
|
value?: string;
|
|
35
59
|
}
|
|
36
60
|
|
|
37
|
-
const
|
|
61
|
+
const SUPPORTED_IDENTIFIER_TEST =
|
|
62
|
+
/^(?:--|-?[A-Za-z_\u0080-\u{10FFFF}])[A-Za-z0-9_\u0080-\u{10FFFF}-]*$/u;
|
|
63
|
+
|
|
64
|
+
function readFunctionArgument(
|
|
65
|
+
selector: string,
|
|
66
|
+
start: number,
|
|
67
|
+
): [string, number] {
|
|
68
|
+
let depth = 1;
|
|
69
|
+
let quote: string | null = null;
|
|
70
|
+
|
|
71
|
+
for (let index = start; index < selector.length; index++) {
|
|
72
|
+
const character = selector[index]!;
|
|
73
|
+
|
|
74
|
+
if (quote) {
|
|
75
|
+
if (character === '\\') {
|
|
76
|
+
index++;
|
|
77
|
+
} else if (character === quote) {
|
|
78
|
+
quote = null;
|
|
79
|
+
}
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (character === '"' || character === "'") {
|
|
84
|
+
quote = character;
|
|
85
|
+
} else if (character === '(') {
|
|
86
|
+
depth++;
|
|
87
|
+
} else if (character === ')' && --depth === 0) {
|
|
88
|
+
return [selector.slice(start, index), index + 1];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return [selector.slice(start), selector.length];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function throwSelectorSyntaxError(selector: string): never {
|
|
96
|
+
throw createDOMException(
|
|
97
|
+
`Invalid or unsupported selector: "${selector}"`,
|
|
98
|
+
'SyntaxError',
|
|
99
|
+
);
|
|
100
|
+
}
|
|
38
101
|
|
|
39
|
-
export function querySelector(
|
|
40
|
-
|
|
102
|
+
export function querySelector(
|
|
103
|
+
within: ParentNode,
|
|
104
|
+
selector: string | Matcher[],
|
|
105
|
+
): Element | null {
|
|
106
|
+
const parts: Part[] =
|
|
107
|
+
typeof selector === 'string'
|
|
108
|
+
? parseSelector(selector)
|
|
109
|
+
: [{combinator: COMBINATOR_INNER, matchers: selector}];
|
|
41
110
|
let result: Element | null = null;
|
|
42
111
|
|
|
43
112
|
const child = within[CHILD];
|
|
@@ -50,9 +119,15 @@ export function querySelector(within: ParentNode, selector: string) {
|
|
|
50
119
|
return result;
|
|
51
120
|
}
|
|
52
121
|
|
|
53
|
-
export function querySelectorAll(
|
|
54
|
-
|
|
55
|
-
|
|
122
|
+
export function querySelectorAll(
|
|
123
|
+
within: ParentNode,
|
|
124
|
+
selector: string | Matcher[],
|
|
125
|
+
): NodeList<Element> {
|
|
126
|
+
const parts: Part[] =
|
|
127
|
+
typeof selector === 'string'
|
|
128
|
+
? parseSelector(selector)
|
|
129
|
+
: [{combinator: COMBINATOR_INNER, matchers: selector}];
|
|
130
|
+
const results = new NodeList<Element>();
|
|
56
131
|
|
|
57
132
|
const child = within[CHILD];
|
|
58
133
|
if (child && parts[0]!.matchers.length) {
|
|
@@ -63,108 +138,221 @@ export function querySelectorAll(within: ParentNode, selector: string) {
|
|
|
63
138
|
return results;
|
|
64
139
|
}
|
|
65
140
|
|
|
66
|
-
export function parseSelector(
|
|
67
|
-
|
|
141
|
+
export function parseSelector(
|
|
142
|
+
selector: string,
|
|
143
|
+
insideHas = false,
|
|
144
|
+
allowLeadingCombinator = false,
|
|
145
|
+
) {
|
|
146
|
+
let part: Part = {combinator: COMBINATOR_INNER, matchers: []};
|
|
68
147
|
const parts = [part];
|
|
69
148
|
const tokenizer =
|
|
70
|
-
|
|
149
|
+
/[\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;
|
|
150
|
+
const normalizedSelector = selector.replace(
|
|
151
|
+
/^[\t\n\f\r ]+|[\t\n\f\r ]+$/g,
|
|
152
|
+
'',
|
|
153
|
+
);
|
|
154
|
+
if (normalizedSelector === '') throwSelectorSyntaxError(selector);
|
|
155
|
+
|
|
156
|
+
let consumed = 0;
|
|
71
157
|
let token;
|
|
72
|
-
while ((token = tokenizer.exec(
|
|
73
|
-
|
|
158
|
+
while ((token = tokenizer.exec(normalizedSelector))) {
|
|
159
|
+
if (token.index !== consumed) throwSelectorSyntaxError(selector);
|
|
160
|
+
|
|
161
|
+
// [1]: ancestor/ parent/ sibling/ adjacent
|
|
74
162
|
// [2]: attribute name
|
|
75
|
-
// [4]: attribute value
|
|
76
|
-
// [5]:
|
|
77
|
-
// [6]: id/class
|
|
78
|
-
// [7]:
|
|
79
|
-
// [8]: :function(
|
|
163
|
+
// [3]/[4]: quoted attribute value
|
|
164
|
+
// [5]: unquoted attribute value
|
|
165
|
+
// [6]: id/class sigil
|
|
166
|
+
// [7]: id/class/type name
|
|
167
|
+
// [8]: :pseudo/:function() name
|
|
168
|
+
// [9]: :function opening parenthesis
|
|
80
169
|
if (token[1]) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
170
|
+
if (
|
|
171
|
+
part.matchers.length === 0 &&
|
|
172
|
+
!(allowLeadingCombinator && parts.length === 1)
|
|
173
|
+
) {
|
|
174
|
+
throwSelectorSyntaxError(selector);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (token[1] === '>') part.combinator = COMBINATOR_CHILD;
|
|
178
|
+
else if (token[1] === '+') part.combinator = COMBINATOR_ADJACENT;
|
|
179
|
+
else if (token[1] === '~') part.combinator = COMBINATOR_SIBLING;
|
|
180
|
+
else part.combinator = COMBINATOR_DESCENDANT;
|
|
181
|
+
part = {combinator: COMBINATOR_INNER, matchers: []};
|
|
88
182
|
parts.push(part);
|
|
89
183
|
}
|
|
90
184
|
|
|
91
|
-
|
|
185
|
+
const name = token[8] ? asciiLowercase(token[8]) : (token[2] || token[7])!;
|
|
186
|
+
const isTypeSelector = token[7] != null && !token[6];
|
|
187
|
+
if (isTypeSelector && part.matchers.length > 0) {
|
|
188
|
+
throwSelectorSyntaxError(selector);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
let type: MatcherType;
|
|
192
|
+
let value = token[4] ?? token[5] ?? token[7];
|
|
92
193
|
if (token[2]) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
194
|
+
if (!SUPPORTED_IDENTIFIER_TEST.test(name)) {
|
|
195
|
+
throwSelectorSyntaxError(selector);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const unquotedValue = token[5];
|
|
199
|
+
const openingQuote = unquotedValue?.[0];
|
|
200
|
+
if (token[3] == null && (openingQuote === '"' || openingQuote === "'")) {
|
|
201
|
+
const valueOffset = token[0].lastIndexOf(unquotedValue!);
|
|
202
|
+
value = normalizedSelector.slice(token.index + valueOffset + 1);
|
|
203
|
+
tokenizer.lastIndex = normalizedSelector.length;
|
|
204
|
+
} else if (
|
|
205
|
+
unquotedValue != null &&
|
|
206
|
+
!SUPPORTED_IDENTIFIER_TEST.test(unquotedValue)
|
|
207
|
+
) {
|
|
208
|
+
throwSelectorSyntaxError(selector);
|
|
209
|
+
}
|
|
210
|
+
type = MATCHER_ATTRIBUTE;
|
|
98
211
|
} else if (token[6]) {
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
} else if (ELEMENT_SELECTOR_TEST.test(token[6])) {
|
|
102
|
-
type = MatcherType.Element;
|
|
212
|
+
if (!SUPPORTED_IDENTIFIER_TEST.test(name)) {
|
|
213
|
+
throwSelectorSyntaxError(selector);
|
|
103
214
|
}
|
|
215
|
+
type = token[6] === '#' ? MATCHER_ID : MATCHER_CLASS;
|
|
216
|
+
} else if (token[8]) {
|
|
217
|
+
type = token[9] == null ? MATCHER_PSEUDO : MATCHER_FUNCTION;
|
|
218
|
+
} else if (token[7] === '*') {
|
|
219
|
+
type = MATCHER_UNKNOWN;
|
|
220
|
+
} else if (token[7] && SUPPORTED_IDENTIFIER_TEST.test(token[7])) {
|
|
221
|
+
type = MATCHER_ELEMENT;
|
|
222
|
+
} else {
|
|
223
|
+
throwSelectorSyntaxError(selector);
|
|
104
224
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
225
|
+
|
|
226
|
+
if (token[9]) {
|
|
227
|
+
[value, tokenizer.lastIndex] = readFunctionArgument(
|
|
228
|
+
normalizedSelector,
|
|
229
|
+
tokenizer.lastIndex,
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
if (name !== 'has' && name !== 'not') {
|
|
233
|
+
throwSelectorSyntaxError(selector);
|
|
234
|
+
}
|
|
235
|
+
if (name === 'has' && insideHas) throwSelectorSyntaxError(selector);
|
|
236
|
+
parseSelector(value, insideHas || name === 'has', name === 'has');
|
|
237
|
+
} else if (type === MATCHER_PSEUDO) {
|
|
238
|
+
throwSelectorSyntaxError(selector);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
part.matchers.push({type, name, value});
|
|
242
|
+
consumed = tokenizer.lastIndex;
|
|
110
243
|
}
|
|
244
|
+
|
|
245
|
+
if (consumed !== normalizedSelector.length || part.matchers.length === 0) {
|
|
246
|
+
throwSelectorSyntaxError(selector);
|
|
247
|
+
}
|
|
248
|
+
|
|
111
249
|
return parts;
|
|
112
250
|
}
|
|
113
251
|
|
|
114
252
|
function matchesSelector(element: Element, selector: string) {
|
|
115
253
|
const parsed = parseSelector(selector);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
254
|
+
return parsed[0]?.matchers.length
|
|
255
|
+
? matchesSelectorRecursive(element, parsed)
|
|
256
|
+
: false;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function matchesRelativeSelector(scope: Element, selector: string) {
|
|
260
|
+
const parts = parseSelector(selector, true, true);
|
|
261
|
+
const first = parts[0]!;
|
|
262
|
+
if (parts.length === 1 && first.matchers.length === 0) return false;
|
|
263
|
+
|
|
264
|
+
let leadingCombinator = COMBINATOR_DESCENDANT;
|
|
265
|
+
const scopeMatcher: Matcher = {type: MATCHER_SCOPE, name: ':scope'};
|
|
266
|
+
if (first.matchers.length === 0) {
|
|
267
|
+
leadingCombinator = first.combinator;
|
|
268
|
+
first.matchers.push(scopeMatcher);
|
|
269
|
+
} else {
|
|
270
|
+
parts.unshift({
|
|
271
|
+
combinator: COMBINATOR_DESCENDANT,
|
|
272
|
+
matchers: [scopeMatcher],
|
|
273
|
+
});
|
|
119
274
|
}
|
|
120
|
-
|
|
275
|
+
|
|
276
|
+
if (parts.some(({matchers}) => matchers.length === 0)) return false;
|
|
277
|
+
|
|
278
|
+
const root =
|
|
279
|
+
leadingCombinator === COMBINATOR_ADJACENT ||
|
|
280
|
+
leadingCombinator === COMBINATOR_SIBLING
|
|
281
|
+
? scope[NEXT]
|
|
282
|
+
: scope[CHILD];
|
|
283
|
+
if (!root) return false;
|
|
284
|
+
|
|
285
|
+
let matched = false;
|
|
286
|
+
walkNodesForSelector(
|
|
287
|
+
root,
|
|
288
|
+
parts,
|
|
289
|
+
() => {
|
|
290
|
+
matched = true;
|
|
291
|
+
return false;
|
|
292
|
+
},
|
|
293
|
+
scope,
|
|
294
|
+
);
|
|
295
|
+
return matched;
|
|
121
296
|
}
|
|
122
297
|
|
|
123
298
|
function walkNodesForSelector(
|
|
124
299
|
node: Node,
|
|
125
300
|
parts: Part[],
|
|
126
301
|
callback: (node: Element) => boolean | void,
|
|
302
|
+
scope?: Element,
|
|
127
303
|
) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
304
|
+
const pendingSiblings: Node[] = [];
|
|
305
|
+
let current: Node | null = node;
|
|
306
|
+
|
|
307
|
+
while (current) {
|
|
308
|
+
if (isElementNode(current)) {
|
|
309
|
+
if (matchesSelectorRecursive(current, parts, scope)) {
|
|
310
|
+
if (callback(current) === false) return false;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const child: Node | null = current[CHILD];
|
|
314
|
+
if (child) {
|
|
315
|
+
const sibling = current[NEXT];
|
|
316
|
+
if (sibling) pendingSiblings.push(sibling);
|
|
317
|
+
current = child;
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
135
320
|
}
|
|
321
|
+
|
|
322
|
+
current = current[NEXT] ?? pendingSiblings.pop() ?? null;
|
|
136
323
|
}
|
|
137
|
-
|
|
138
|
-
if (next && walkNodesForSelector(next, parts, callback) === false) {
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
324
|
+
|
|
141
325
|
return true;
|
|
142
326
|
}
|
|
143
327
|
|
|
144
|
-
function matchesSelectorRecursive(
|
|
328
|
+
function matchesSelectorRecursive(
|
|
329
|
+
element: Element,
|
|
330
|
+
parts: Part[],
|
|
331
|
+
scope?: Element,
|
|
332
|
+
): boolean {
|
|
145
333
|
const {combinator, matchers} = parts[parts.length - 1]!;
|
|
146
|
-
if (combinator ===
|
|
147
|
-
if (!matchesSelectorMatcher(element, matchers)) return false;
|
|
334
|
+
if (combinator === COMBINATOR_INNER) {
|
|
335
|
+
if (!matchesSelectorMatcher(element, matchers, scope)) return false;
|
|
148
336
|
const pp = parts.slice(0, -1);
|
|
149
|
-
return pp.length === 0 || matchesSelectorRecursive(element, pp);
|
|
337
|
+
return pp.length === 0 || matchesSelectorRecursive(element, pp, scope);
|
|
150
338
|
}
|
|
151
339
|
const link =
|
|
152
|
-
combinator ===
|
|
340
|
+
combinator === COMBINATOR_CHILD || combinator === COMBINATOR_DESCENDANT
|
|
153
341
|
? PARENT
|
|
154
342
|
: PREV;
|
|
155
343
|
let ref = element[link];
|
|
156
344
|
if (!ref) return false;
|
|
157
345
|
|
|
158
346
|
if (
|
|
159
|
-
combinator ===
|
|
160
|
-
combinator ===
|
|
347
|
+
combinator === COMBINATOR_DESCENDANT ||
|
|
348
|
+
combinator === COMBINATOR_SIBLING
|
|
161
349
|
) {
|
|
162
350
|
// For descendant/sibling combinators, search through all ancestors/siblings
|
|
163
351
|
while (ref) {
|
|
164
|
-
if (isElementNode(ref) && matchesSelectorMatcher(ref, matchers)) {
|
|
352
|
+
if (isElementNode(ref) && matchesSelectorMatcher(ref, matchers, scope)) {
|
|
165
353
|
const pp = parts.slice(0, -1);
|
|
166
354
|
if (pp.length === 0) return true;
|
|
167
|
-
if (matchesSelectorRecursive(
|
|
355
|
+
if (matchesSelectorRecursive(ref, pp, scope)) return true;
|
|
168
356
|
}
|
|
169
357
|
ref = ref[link];
|
|
170
358
|
}
|
|
@@ -172,7 +360,7 @@ function matchesSelectorRecursive(element: Element, parts: Part[]): boolean {
|
|
|
172
360
|
} else {
|
|
173
361
|
// For child/adjacent combinators, check only the immediate parent/sibling
|
|
174
362
|
// For sibling combinators, skip non-element siblings
|
|
175
|
-
if (combinator ===
|
|
363
|
+
if (combinator === COMBINATOR_ADJACENT && !isElementNode(ref)) {
|
|
176
364
|
// Skip to next element sibling
|
|
177
365
|
while (ref && !isElementNode(ref)) {
|
|
178
366
|
ref = ref[link];
|
|
@@ -180,89 +368,64 @@ function matchesSelectorRecursive(element: Element, parts: Part[]): boolean {
|
|
|
180
368
|
if (!ref) return false;
|
|
181
369
|
}
|
|
182
370
|
|
|
183
|
-
if (!isElementNode(ref) || !matchesSelectorMatcher(ref, matchers)) {
|
|
371
|
+
if (!isElementNode(ref) || !matchesSelectorMatcher(ref, matchers, scope)) {
|
|
184
372
|
return false;
|
|
185
373
|
}
|
|
186
374
|
const pp = parts.slice(0, -1);
|
|
187
|
-
return pp.length === 0 || matchesSelectorRecursive(
|
|
375
|
+
return pp.length === 0 || matchesSelectorRecursive(ref, pp, scope);
|
|
188
376
|
}
|
|
189
377
|
}
|
|
190
378
|
|
|
191
|
-
function
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
combinator === Combinator.Child || combinator === Combinator.Descendant
|
|
197
|
-
? PARENT
|
|
198
|
-
: PREV;
|
|
199
|
-
let ref = element[link];
|
|
200
|
-
if (!ref) return false;
|
|
201
|
-
|
|
202
|
-
// For sibling combinators, skip non-element siblings
|
|
203
|
-
if (combinator === Combinator.Adjacent && !isElementNode(ref)) {
|
|
204
|
-
while (ref && !isElementNode(ref)) {
|
|
205
|
-
ref = ref[link];
|
|
206
|
-
}
|
|
207
|
-
if (!ref) return false;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (!isElementNode(ref) || !matchesSelectorMatcher(ref, matchers)) {
|
|
211
|
-
return false;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
if (
|
|
215
|
-
combinator === Combinator.Descendant ||
|
|
216
|
-
combinator === Combinator.Sibling
|
|
217
|
-
) {
|
|
218
|
-
while ((ref = ref[link])) {
|
|
219
|
-
if (isElementNode(ref) && matchesSelectorMatcher(ref, matchers))
|
|
220
|
-
return true;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
return true;
|
|
379
|
+
function getSelectorAttribute(element: Element, name: string) {
|
|
380
|
+
return element.getAttributeNS(
|
|
381
|
+
null,
|
|
382
|
+
element.namespaceURI === HTML_NAMESPACE ? asciiLowercase(name) : name,
|
|
383
|
+
);
|
|
224
384
|
}
|
|
225
385
|
|
|
226
386
|
function matchesSelectorMatcher(
|
|
227
387
|
element: Element | null,
|
|
228
388
|
matcher: Matcher | Matcher[],
|
|
389
|
+
scope?: Element,
|
|
229
390
|
) {
|
|
230
391
|
if (!element) return false;
|
|
231
392
|
if (Array.isArray(matcher)) {
|
|
232
393
|
for (const single of matcher) {
|
|
233
|
-
if (matchesSelectorMatcher(element, single) === false)
|
|
394
|
+
if (matchesSelectorMatcher(element, single, scope) === false) {
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
234
397
|
}
|
|
235
398
|
return true;
|
|
236
399
|
}
|
|
237
400
|
const {type, name, value} = matcher;
|
|
238
401
|
switch (type) {
|
|
239
|
-
case
|
|
402
|
+
case MATCHER_UNKNOWN:
|
|
240
403
|
return name === '*'; // Universal selector
|
|
241
|
-
case
|
|
242
|
-
return element.
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
case
|
|
246
|
-
|
|
404
|
+
case MATCHER_ELEMENT:
|
|
405
|
+
return element.namespaceURI === HTML_NAMESPACE
|
|
406
|
+
? element.localName === asciiLowercase(name)
|
|
407
|
+
: element.localName === name;
|
|
408
|
+
case MATCHER_ID:
|
|
409
|
+
return getSelectorAttribute(element, 'id') === name;
|
|
410
|
+
case MATCHER_CLASS:
|
|
411
|
+
const classAttr = getSelectorAttribute(element, 'class');
|
|
247
412
|
if (!classAttr) return false;
|
|
248
|
-
return classAttr
|
|
249
|
-
case
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
case MatcherType.Function:
|
|
413
|
+
return splitOnASCIIWhitespace(classAttr).includes(name);
|
|
414
|
+
case MATCHER_ATTRIBUTE:
|
|
415
|
+
const attribute = getSelectorAttribute(element, name);
|
|
416
|
+
return value == null ? attribute != null : attribute === value;
|
|
417
|
+
case MATCHER_SCOPE:
|
|
418
|
+
return element === scope;
|
|
419
|
+
case MATCHER_PSEUDO:
|
|
420
|
+
throwSelectorSyntaxError(`:${name}`);
|
|
421
|
+
case MATCHER_FUNCTION:
|
|
259
422
|
switch (name) {
|
|
260
423
|
case 'has':
|
|
261
|
-
return
|
|
424
|
+
return matchesRelativeSelector(element, value || '');
|
|
262
425
|
case 'not':
|
|
263
426
|
return !matchesSelector(element, value || '');
|
|
264
427
|
default:
|
|
265
|
-
|
|
428
|
+
throwSelectorSyntaxError(`:${name}(${value})`);
|
|
266
429
|
}
|
|
267
430
|
}
|
|
268
431
|
return false;
|