@asamuzakjp/dom-selector 4.2.2 → 4.3.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/README.md +7 -3
- package/dist/cjs/js/constant.js +1 -1
- package/dist/cjs/js/constant.js.map +2 -2
- package/dist/cjs/js/dom-util.js +1 -1
- package/dist/cjs/js/dom-util.js.map +2 -2
- package/dist/cjs/js/finder.js +1 -1
- package/dist/cjs/js/finder.js.map +3 -3
- package/package.json +5 -5
- package/src/js/constant.js +1 -1
- package/src/js/dom-util.js +3 -3
- package/src/js/finder.js +47 -13
- package/types/js/finder.d.ts +1 -0
package/package.json
CHANGED
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"@types/css-tree": "^2.3.7",
|
|
33
33
|
"benchmark": "^2.1.4",
|
|
34
34
|
"c8": "^9.1.0",
|
|
35
|
-
"chai": "^5.1.
|
|
35
|
+
"chai": "^5.1.1",
|
|
36
36
|
"commander": "^12.0.0",
|
|
37
|
-
"esbuild": "^0.21.
|
|
37
|
+
"esbuild": "^0.21.1",
|
|
38
38
|
"eslint": "^8.57.0",
|
|
39
39
|
"eslint-config-standard": "^17.1.0",
|
|
40
40
|
"eslint-plugin-import": "^2.29.1",
|
|
41
|
-
"eslint-plugin-jsdoc": "^48.2.
|
|
41
|
+
"eslint-plugin-jsdoc": "^48.2.4",
|
|
42
42
|
"eslint-plugin-regexp": "^2.5.0",
|
|
43
|
-
"eslint-plugin-unicorn": "^
|
|
43
|
+
"eslint-plugin-unicorn": "^53.0.0",
|
|
44
44
|
"happy-dom": "^14.10.1",
|
|
45
45
|
"jsdom": "^24.0.0",
|
|
46
46
|
"linkedom": "^0.16.11",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"tsc": "node scripts/index clean --dir=types -i && npx tsc",
|
|
61
61
|
"update-wpt": "git submodule update --init --recursive --remote"
|
|
62
62
|
},
|
|
63
|
-
"version": "4.
|
|
63
|
+
"version": "4.3.0"
|
|
64
64
|
}
|
package/src/js/constant.js
CHANGED
|
@@ -54,7 +54,7 @@ export const SHOW_ELEMENT = 1;
|
|
|
54
54
|
export const WALKER_FILTER = 0x501;
|
|
55
55
|
|
|
56
56
|
/* regexp */
|
|
57
|
-
export const REG_LOGICAL_PSEUDO = /^(?:
|
|
57
|
+
export const REG_LOGICAL_PSEUDO = /^(?:has|is|not|where)$/;
|
|
58
58
|
export const REG_SHADOW_HOST = /^host(?:-context)?$/;
|
|
59
59
|
export const REG_SHADOW_MODE = /^(?:close|open)$/;
|
|
60
60
|
export const REG_SHADOW_PSEUDO = /^part|slotted$/;
|
package/src/js/dom-util.js
CHANGED
|
@@ -139,9 +139,9 @@ export const getDirectionality = (node = {}) => {
|
|
|
139
139
|
let text;
|
|
140
140
|
switch (localName) {
|
|
141
141
|
case 'input': {
|
|
142
|
-
if (!node.type || /^(?:
|
|
142
|
+
if (!node.type || /^(?:button|email|hidden|password|reset|search|submit|tel|text|url)$/.test(node.type)) {
|
|
143
143
|
text = node.value;
|
|
144
|
-
} else if (/^(?:
|
|
144
|
+
} else if (/^(?:checkbox|color|date|image|number|radio|range|time)$/.test(node.type)) {
|
|
145
145
|
res = 'ltr';
|
|
146
146
|
}
|
|
147
147
|
break;
|
|
@@ -164,7 +164,7 @@ export const getDirectionality = (node = {}) => {
|
|
|
164
164
|
if (itemNodeType === TEXT_NODE) {
|
|
165
165
|
text = itemTextContent.trim();
|
|
166
166
|
} else if (itemNodeType === ELEMENT_NODE) {
|
|
167
|
-
if (!/^(?:bdi|
|
|
167
|
+
if (!/^(?:bdi|script|style|textarea)$/.test(itemLocalName) &&
|
|
168
168
|
(!itemDir || !regDir.test(itemDir))) {
|
|
169
169
|
if (itemLocalName === 'slot') {
|
|
170
170
|
text = getSlottedTextContent(item);
|
package/src/js/finder.js
CHANGED
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
|
|
16
16
|
/* constants */
|
|
17
17
|
import {
|
|
18
|
-
COMBINATOR, DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE, ELEMENT_NODE,
|
|
19
|
-
NOT_SUPPORTED_ERR, REG_LOGICAL_PSEUDO, REG_SHADOW_HOST, SELECTOR_CLASS,
|
|
18
|
+
BIT_01, COMBINATOR, DOCUMENT_FRAGMENT_NODE, DOCUMENT_NODE, ELEMENT_NODE,
|
|
19
|
+
EMPTY, NOT_SUPPORTED_ERR, REG_LOGICAL_PSEUDO, REG_SHADOW_HOST, SELECTOR_CLASS,
|
|
20
20
|
SELECTOR_ID, SELECTOR_PSEUDO_CLASS, SELECTOR_PSEUDO_ELEMENT, SELECTOR_TYPE,
|
|
21
21
|
SHOW_ALL, SYNTAX_ERR, TEXT_NODE, WALKER_FILTER
|
|
22
22
|
} from './constant.js';
|
|
@@ -58,6 +58,7 @@ export class Finder {
|
|
|
58
58
|
#content;
|
|
59
59
|
#descendant;
|
|
60
60
|
#document;
|
|
61
|
+
#event;
|
|
61
62
|
#node;
|
|
62
63
|
#nodes;
|
|
63
64
|
#noexcept;
|
|
@@ -120,14 +121,16 @@ export class Finder {
|
|
|
120
121
|
* @param {string} selector - CSS selector
|
|
121
122
|
* @param {object} node - Document, DocumentFragment, Element node
|
|
122
123
|
* @param {object} opt - options
|
|
124
|
+
* @param {object} [opt.event] - MouseEvent, KeyboardEvent
|
|
123
125
|
* @param {boolean} [opt.noexcept] - no exception
|
|
124
126
|
* @param {boolean} [opt.warn] - console warn
|
|
125
127
|
* @returns {object} - node
|
|
126
128
|
*/
|
|
127
129
|
_setup(selector, node, opt = {}) {
|
|
128
|
-
const { noexcept, warn } = opt;
|
|
130
|
+
const { event, noexcept, warn } = opt;
|
|
129
131
|
this.#noexcept = !!noexcept;
|
|
130
132
|
this.#warn = !!warn;
|
|
133
|
+
this.#event = this._setEvent(event);
|
|
131
134
|
this.#node = node;
|
|
132
135
|
[this.#content, this.#root, this.#walker] = resolveContent(node);
|
|
133
136
|
this.#shadow = isInShadowTree(node);
|
|
@@ -136,6 +139,19 @@ export class Finder {
|
|
|
136
139
|
return node;
|
|
137
140
|
}
|
|
138
141
|
|
|
142
|
+
/**
|
|
143
|
+
* set event
|
|
144
|
+
* @private
|
|
145
|
+
* @param {object} event - instance of MouseEvent, KeyboardEvent
|
|
146
|
+
* @returns {object} - result
|
|
147
|
+
*/
|
|
148
|
+
_setEvent(event) {
|
|
149
|
+
return (event instanceof this.#window.MouseEvent ||
|
|
150
|
+
event instanceof this.#window.KeyboardEvent)
|
|
151
|
+
? event
|
|
152
|
+
: null;
|
|
153
|
+
}
|
|
154
|
+
|
|
139
155
|
/**
|
|
140
156
|
* correspond ast and nodes
|
|
141
157
|
* @private
|
|
@@ -898,14 +914,14 @@ export class Finder {
|
|
|
898
914
|
} else {
|
|
899
915
|
const regAnchor = /^a(?:rea)?$/;
|
|
900
916
|
const regFormCtrl =
|
|
901
|
-
/^(?:
|
|
902
|
-
const regFormValidity = /^(?:
|
|
903
|
-
const regInteract = /^
|
|
917
|
+
/^(?:button|fieldset|input|optgroup|option|select|textarea)$/;
|
|
918
|
+
const regFormValidity = /^(?:button|form|input|select|textarea)$/;
|
|
919
|
+
const regInteract = /^(?:details|dialog)$/;
|
|
904
920
|
const regTypeCheck = /^(?:checkbox|radio)$/;
|
|
905
921
|
const regTypeDate = /^(?:date(?:time-local)?|month|time|week)$/;
|
|
906
922
|
const regTypeRange =
|
|
907
|
-
/(?:
|
|
908
|
-
const regTypeText = /^(?:
|
|
923
|
+
/(?:date(?:time-local)?|month|number|range|time|week)$/;
|
|
924
|
+
const regTypeText = /^(?:email|number|password|search|tel|text|url)$/;
|
|
909
925
|
switch (astName) {
|
|
910
926
|
case 'any-link':
|
|
911
927
|
case 'link': {
|
|
@@ -928,6 +944,22 @@ export class Finder {
|
|
|
928
944
|
// prevent fingerprinting
|
|
929
945
|
break;
|
|
930
946
|
}
|
|
947
|
+
case 'hover': {
|
|
948
|
+
const { target, type } = this.#event ?? {};
|
|
949
|
+
if ((type === 'mouseover' || type === 'pointerover') &&
|
|
950
|
+
node.contains(target)) {
|
|
951
|
+
matched.add(node);
|
|
952
|
+
}
|
|
953
|
+
break;
|
|
954
|
+
}
|
|
955
|
+
case 'active': {
|
|
956
|
+
const { buttons, target, type } = this.#event ?? {};
|
|
957
|
+
if ((type === 'mousedown' || type === 'pointerdown') &&
|
|
958
|
+
buttons & BIT_01 && node.contains(target)) {
|
|
959
|
+
matched.add(node);
|
|
960
|
+
}
|
|
961
|
+
break;
|
|
962
|
+
}
|
|
931
963
|
case 'target': {
|
|
932
964
|
const { hash } = new URL(this.#content.URL);
|
|
933
965
|
if (node.id && hash === `#${node.id}` &&
|
|
@@ -961,8 +993,12 @@ export class Finder {
|
|
|
961
993
|
}
|
|
962
994
|
break;
|
|
963
995
|
}
|
|
964
|
-
case 'focus':
|
|
965
|
-
|
|
996
|
+
case 'focus':
|
|
997
|
+
case 'focus-visible': {
|
|
998
|
+
const { target, type } = this.#event ?? {};
|
|
999
|
+
if (node === this.#content.activeElement && node.tabIndex >= 0 &&
|
|
1000
|
+
(astName === 'focus' ||
|
|
1001
|
+
(type === 'keydown' && node.contains(target)))) {
|
|
966
1002
|
let refNode = node;
|
|
967
1003
|
let focus = true;
|
|
968
1004
|
while (refNode) {
|
|
@@ -1527,15 +1563,13 @@ export class Finder {
|
|
|
1527
1563
|
}
|
|
1528
1564
|
break;
|
|
1529
1565
|
}
|
|
1530
|
-
|
|
1566
|
+
// not supported
|
|
1531
1567
|
case 'autofill':
|
|
1532
1568
|
case 'blank':
|
|
1533
1569
|
case 'buffering':
|
|
1534
1570
|
case 'current':
|
|
1535
|
-
case 'focus-visible':
|
|
1536
1571
|
case 'fullscreen':
|
|
1537
1572
|
case 'future':
|
|
1538
|
-
case 'hover':
|
|
1539
1573
|
case 'modal':
|
|
1540
1574
|
case 'muted':
|
|
1541
1575
|
case 'past':
|