@markuplint/selector 3.14.0 → 4.0.0-alpha.10
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/LICENSE +1 -1
- package/lib/compare-specificity.d.ts +1 -1
- package/lib/compare-specificity.js +1 -5
- package/lib/create-selector.d.ts +1 -1
- package/lib/create-selector.js +9 -13
- package/lib/debug.js +9 -14
- package/lib/extended-selector/aria-pseudo-class.d.ts +1 -1
- package/lib/extended-selector/aria-pseudo-class.js +6 -10
- package/lib/extended-selector/aria-role-pseudo-class.d.ts +1 -1
- package/lib/extended-selector/aria-role-pseudo-class.js +7 -13
- package/lib/extended-selector/content-model-pseudo-class.d.ts +1 -1
- package/lib/extended-selector/content-model-pseudo-class.js +8 -13
- package/lib/index.d.ts +5 -5
- package/lib/index.js +5 -13
- package/lib/invalid-selector-error.d.ts +3 -3
- package/lib/invalid-selector-error.js +2 -6
- package/lib/is.js +3 -9
- package/lib/match-selector.d.ts +6 -6
- package/lib/match-selector.js +48 -50
- package/lib/regex-selector-matches.d.ts +2 -6
- package/lib/regex-selector-matches.js +7 -7
- package/lib/selector.d.ts +5 -5
- package/lib/selector.js +83 -92
- package/lib/types.d.ts +13 -13
- package/lib/types.js +1 -2
- package/package.json +12 -8
- package/test/create-selector.spec.js +0 -44
- package/test/match-selector.spec.js +0 -342
- package/test/regex-selector-matches.spec.js +0 -16
- package/test/selector.spec.js +0 -284
package/LICENSE
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Specificity } from './types';
|
|
1
|
+
import type { Specificity } from './types.js';
|
|
2
2
|
export declare function compareSpecificity(a: Specificity, b: Specificity): 0 | 1 | -1;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.compareSpecificity = void 0;
|
|
4
|
-
function compareSpecificity(a, b) {
|
|
1
|
+
export function compareSpecificity(a, b) {
|
|
5
2
|
if (a[0] < b[0]) {
|
|
6
3
|
return -1;
|
|
7
4
|
}
|
|
@@ -22,4 +19,3 @@ function compareSpecificity(a, b) {
|
|
|
22
19
|
}
|
|
23
20
|
return 0;
|
|
24
21
|
}
|
|
25
|
-
exports.compareSpecificity = compareSpecificity;
|
package/lib/create-selector.d.ts
CHANGED
package/lib/create-selector.js
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const aria_role_pseudo_class_1 = require("./extended-selector/aria-role-pseudo-class");
|
|
6
|
-
const content_model_pseudo_class_1 = require("./extended-selector/content-model-pseudo-class");
|
|
7
|
-
const selector_1 = require("./selector");
|
|
1
|
+
import { ariaPseudoClass } from './extended-selector/aria-pseudo-class.js';
|
|
2
|
+
import { ariaRolePseudoClass } from './extended-selector/aria-role-pseudo-class.js';
|
|
3
|
+
import { contentModelPseudoClass } from './extended-selector/content-model-pseudo-class.js';
|
|
4
|
+
import { Selector } from './selector.js';
|
|
8
5
|
const caches = new Map();
|
|
9
|
-
function createSelector(selector, specs) {
|
|
6
|
+
export function createSelector(selector, specs) {
|
|
10
7
|
let instance = caches.get(selector);
|
|
11
8
|
if (instance) {
|
|
12
9
|
return instance;
|
|
13
10
|
}
|
|
14
|
-
instance = new
|
|
11
|
+
instance = new Selector(selector, specs
|
|
15
12
|
? {
|
|
16
|
-
model:
|
|
17
|
-
aria:
|
|
18
|
-
role:
|
|
13
|
+
model: contentModelPseudoClass(specs),
|
|
14
|
+
aria: ariaPseudoClass(),
|
|
15
|
+
role: ariaRolePseudoClass(specs),
|
|
19
16
|
}
|
|
20
17
|
: undefined);
|
|
21
18
|
caches.set(selector, instance);
|
|
22
19
|
return instance;
|
|
23
20
|
}
|
|
24
|
-
exports.createSelector = createSelector;
|
package/lib/debug.js
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.enableDebug = exports.log = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const debug_1 = tslib_1.__importDefault(require("debug"));
|
|
1
|
+
import debug from 'debug';
|
|
6
2
|
const CLI_NS = 'markuplint-cli';
|
|
7
|
-
|
|
8
|
-
function enableDebug() {
|
|
9
|
-
if (!
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (!
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
export const log = debug('selector');
|
|
4
|
+
export function enableDebug() {
|
|
5
|
+
if (!log.enabled) {
|
|
6
|
+
debug.enable(`${log.namespace}*`);
|
|
7
|
+
log(`Debug enable: ${log.namespace}`);
|
|
8
|
+
if (!debug.enabled(CLI_NS)) {
|
|
9
|
+
debug.enable(`${log.namespace}*,${CLI_NS}*`);
|
|
10
|
+
log(`Debug enable: ${log.namespace}, ${CLI_NS}`);
|
|
15
11
|
}
|
|
16
12
|
}
|
|
17
13
|
}
|
|
18
|
-
exports.enableDebug = enableDebug;
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ariaPseudoClass = void 0;
|
|
4
|
-
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
1
|
+
import { validateAriaVersion, ARIA_RECOMMENDED_VERSION, getAccname } from '@markuplint/ml-spec';
|
|
5
2
|
/**
|
|
6
3
|
* Version Syntax is not support yet.
|
|
7
4
|
*/
|
|
8
|
-
function ariaPseudoClass() {
|
|
5
|
+
export function ariaPseudoClass() {
|
|
9
6
|
return (content) => (
|
|
10
7
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
11
8
|
el) => {
|
|
12
9
|
const aria = ariaPseudoClassParser(content);
|
|
13
|
-
const name =
|
|
10
|
+
const name = getAccname(el);
|
|
14
11
|
switch (aria.type) {
|
|
15
12
|
case 'hasName': {
|
|
16
13
|
if (name) {
|
|
@@ -43,12 +40,11 @@ function ariaPseudoClass() {
|
|
|
43
40
|
}
|
|
44
41
|
};
|
|
45
42
|
}
|
|
46
|
-
exports.ariaPseudoClass = ariaPseudoClass;
|
|
47
43
|
function ariaPseudoClassParser(syntax) {
|
|
48
44
|
const [_query, _version] = syntax.split('|');
|
|
49
|
-
const query = _query
|
|
50
|
-
const version = _version
|
|
51
|
-
if (!
|
|
45
|
+
const query = _query?.replace(/\s+/g, '').toLowerCase();
|
|
46
|
+
const version = _version ?? ARIA_RECOMMENDED_VERSION;
|
|
47
|
+
if (!validateAriaVersion(version)) {
|
|
52
48
|
throw new SyntaxError(`Unsupported ARIA version: ${version}`);
|
|
53
49
|
}
|
|
54
50
|
switch (query) {
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.ariaRolePseudoClass = void 0;
|
|
4
|
-
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
5
|
-
function ariaRolePseudoClass(specs) {
|
|
1
|
+
import { validateAriaVersion, ARIA_RECOMMENDED_VERSION, getComputedRole } from '@markuplint/ml-spec';
|
|
2
|
+
export function ariaRolePseudoClass(specs) {
|
|
6
3
|
return (content) => (
|
|
7
4
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
8
5
|
el) => {
|
|
9
|
-
var _a, _b;
|
|
10
6
|
const aria = ariaPseudoClassParser(content);
|
|
11
|
-
const computed =
|
|
12
|
-
if (
|
|
7
|
+
const computed = getComputedRole(specs, el, aria.version ?? ARIA_RECOMMENDED_VERSION);
|
|
8
|
+
if (computed.role?.name === aria.role) {
|
|
13
9
|
return {
|
|
14
10
|
specificity: [0, 1, 0],
|
|
15
11
|
matched: true,
|
|
@@ -23,16 +19,14 @@ function ariaRolePseudoClass(specs) {
|
|
|
23
19
|
};
|
|
24
20
|
};
|
|
25
21
|
}
|
|
26
|
-
exports.ariaRolePseudoClass = ariaRolePseudoClass;
|
|
27
22
|
function ariaPseudoClassParser(syntax) {
|
|
28
|
-
var _a;
|
|
29
23
|
const [roleName, _version] = syntax.split('|');
|
|
30
|
-
const version = _version
|
|
31
|
-
if (!
|
|
24
|
+
const version = _version ?? ARIA_RECOMMENDED_VERSION;
|
|
25
|
+
if (!validateAriaVersion(version)) {
|
|
32
26
|
throw new SyntaxError(`Unsupported ARIA version: ${version}`);
|
|
33
27
|
}
|
|
34
28
|
return {
|
|
35
|
-
role:
|
|
29
|
+
role: roleName?.trim().toLowerCase() ?? syntax.trim().toLowerCase(),
|
|
36
30
|
version,
|
|
37
31
|
};
|
|
38
32
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { SelectorResult } from '../types';
|
|
1
|
+
import type { SelectorResult } from '../types.js';
|
|
2
2
|
import type { MLMLSpec } from '@markuplint/ml-spec';
|
|
3
3
|
export declare function contentModelPseudoClass(specs: MLMLSpec): (category: string) => (el: Element) => SelectorResult;
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
5
|
-
const create_selector_1 = require("../create-selector");
|
|
6
|
-
function contentModelPseudoClass(specs) {
|
|
1
|
+
import { contentModelCategoryToTagNames } from '@markuplint/ml-spec';
|
|
2
|
+
import { createSelector } from '../create-selector.js';
|
|
3
|
+
export function contentModelPseudoClass(specs) {
|
|
7
4
|
return (category) => (
|
|
8
5
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
9
6
|
el) => {
|
|
10
7
|
category = category.trim().toLowerCase();
|
|
11
|
-
const selectors =
|
|
8
|
+
const selectors = contentModelCategoryToTagNames(`#${category}`, specs.def);
|
|
12
9
|
const matched = selectors
|
|
13
|
-
.
|
|
10
|
+
.flatMap(selector => {
|
|
14
11
|
if (selector === '#custom') {
|
|
15
12
|
// @ts-ignore
|
|
16
13
|
if (el.isCustomElement) {
|
|
@@ -38,16 +35,15 @@ function contentModelPseudoClass(specs) {
|
|
|
38
35
|
},
|
|
39
36
|
];
|
|
40
37
|
}
|
|
41
|
-
return
|
|
38
|
+
return createSelector(selector, specs).search(el);
|
|
42
39
|
})
|
|
43
|
-
.flat()
|
|
44
40
|
.filter((m) => m.matched);
|
|
45
41
|
if (matched.length > 0) {
|
|
46
42
|
return {
|
|
47
43
|
specificity: [0, 1, 0],
|
|
48
44
|
matched: true,
|
|
49
|
-
nodes: matched.
|
|
50
|
-
has: matched.
|
|
45
|
+
nodes: matched.flatMap(m => (m.matched ? m.nodes : [])),
|
|
46
|
+
has: matched.flatMap(m => (m.matched ? m.has : [])),
|
|
51
47
|
};
|
|
52
48
|
}
|
|
53
49
|
return {
|
|
@@ -56,4 +52,3 @@ function contentModelPseudoClass(specs) {
|
|
|
56
52
|
};
|
|
57
53
|
};
|
|
58
54
|
}
|
|
59
|
-
exports.contentModelPseudoClass = contentModelPseudoClass;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { compareSpecificity } from './compare-specificity';
|
|
2
|
-
export { matchSelector } from './match-selector';
|
|
3
|
-
export { createSelector } from './create-selector';
|
|
4
|
-
export { InvalidSelectorError } from './invalid-selector-error';
|
|
5
|
-
export * from './types';
|
|
1
|
+
export { compareSpecificity } from './compare-specificity.js';
|
|
2
|
+
export { matchSelector } from './match-selector.js';
|
|
3
|
+
export { createSelector } from './create-selector.js';
|
|
4
|
+
export { InvalidSelectorError } from './invalid-selector-error.js';
|
|
5
|
+
export * from './types.js';
|
package/lib/index.js
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Object.defineProperty(exports, "compareSpecificity", { enumerable: true, get: function () { return compare_specificity_1.compareSpecificity; } });
|
|
7
|
-
var match_selector_1 = require("./match-selector");
|
|
8
|
-
Object.defineProperty(exports, "matchSelector", { enumerable: true, get: function () { return match_selector_1.matchSelector; } });
|
|
9
|
-
var create_selector_1 = require("./create-selector");
|
|
10
|
-
Object.defineProperty(exports, "createSelector", { enumerable: true, get: function () { return create_selector_1.createSelector; } });
|
|
11
|
-
var invalid_selector_error_1 = require("./invalid-selector-error");
|
|
12
|
-
Object.defineProperty(exports, "InvalidSelectorError", { enumerable: true, get: function () { return invalid_selector_error_1.InvalidSelectorError; } });
|
|
13
|
-
tslib_1.__exportStar(require("./types"), exports);
|
|
1
|
+
export { compareSpecificity } from './compare-specificity.js';
|
|
2
|
+
export { matchSelector } from './match-selector.js';
|
|
3
|
+
export { createSelector } from './create-selector.js';
|
|
4
|
+
export { InvalidSelectorError } from './invalid-selector-error.js';
|
|
5
|
+
export * from './types.js';
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.InvalidSelectorError = void 0;
|
|
4
|
-
class InvalidSelectorError extends Error {
|
|
1
|
+
export class InvalidSelectorError extends Error {
|
|
5
2
|
constructor(selector, message) {
|
|
6
|
-
super(message
|
|
3
|
+
super(message ?? `Invalid selector: "${selector}"`);
|
|
7
4
|
this.name = 'InvalidSelectorError';
|
|
8
5
|
this.selector = selector;
|
|
9
6
|
}
|
|
10
7
|
}
|
|
11
|
-
exports.InvalidSelectorError = InvalidSelectorError;
|
package/lib/is.js
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isPureHTMLElement = exports.isNonDocumentTypeChildNode = exports.isElement = void 0;
|
|
4
|
-
function isElement(
|
|
1
|
+
export function isElement(
|
|
5
2
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
6
3
|
node) {
|
|
7
4
|
return node.nodeType === node.ELEMENT_NODE;
|
|
8
5
|
}
|
|
9
|
-
|
|
10
|
-
function isNonDocumentTypeChildNode(
|
|
6
|
+
export function isNonDocumentTypeChildNode(
|
|
11
7
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
12
8
|
node) {
|
|
13
9
|
return 'previousElementSibling' in node && 'nextElementSibling' in node;
|
|
14
10
|
}
|
|
15
|
-
|
|
16
|
-
function isPureHTMLElement(
|
|
11
|
+
export function isPureHTMLElement(
|
|
17
12
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
18
13
|
el) {
|
|
19
14
|
return el.localName !== el.nodeName;
|
|
20
15
|
}
|
|
21
|
-
exports.isPureHTMLElement = isPureHTMLElement;
|
package/lib/match-selector.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type { Specificity, RegexSelector } from './types';
|
|
1
|
+
import type { Specificity, RegexSelector } from './types.js';
|
|
2
2
|
export type SelectorMatches = SelectorMatched | SelectorUnmatched;
|
|
3
3
|
type SelectorMatched = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
readonly matched: true;
|
|
5
|
+
readonly selector: string;
|
|
6
|
+
readonly specificity: Specificity;
|
|
7
|
+
readonly data?: Readonly<Record<string, string>>;
|
|
8
8
|
};
|
|
9
9
|
type SelectorUnmatched = {
|
|
10
|
-
|
|
10
|
+
readonly matched: false;
|
|
11
11
|
};
|
|
12
12
|
export declare function matchSelector(el: Node, selector: string | RegexSelector | undefined): SelectorMatches;
|
|
13
13
|
export {};
|
package/lib/match-selector.js
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
2
12
|
var _SelectorTarget_combinedFrom, _SelectorTarget_selector;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const regex_selector_matches_1 = require("./regex-selector-matches");
|
|
8
|
-
const selector_1 = require("./selector");
|
|
9
|
-
function matchSelector(
|
|
13
|
+
import { isElement, isNonDocumentTypeChildNode, isPureHTMLElement } from './is.js';
|
|
14
|
+
import { regexSelectorMatches } from './regex-selector-matches.js';
|
|
15
|
+
import { Selector } from './selector.js';
|
|
16
|
+
export function matchSelector(
|
|
10
17
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
11
18
|
el, selector) {
|
|
12
19
|
if (selector == null || selector === '') {
|
|
@@ -15,7 +22,7 @@ el, selector) {
|
|
|
15
22
|
};
|
|
16
23
|
}
|
|
17
24
|
if (typeof selector === 'string') {
|
|
18
|
-
const sel = new
|
|
25
|
+
const sel = new Selector(selector);
|
|
19
26
|
const specificity = sel.match(el);
|
|
20
27
|
if (specificity !== false) {
|
|
21
28
|
return {
|
|
@@ -30,7 +37,6 @@ el, selector) {
|
|
|
30
37
|
}
|
|
31
38
|
return regexSelect(el, selector);
|
|
32
39
|
}
|
|
33
|
-
exports.matchSelector = matchSelector;
|
|
34
40
|
function regexSelect(
|
|
35
41
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
36
42
|
el, selector) {
|
|
@@ -48,10 +54,10 @@ class SelectorTarget {
|
|
|
48
54
|
constructor(selector) {
|
|
49
55
|
_SelectorTarget_combinedFrom.set(this, null);
|
|
50
56
|
_SelectorTarget_selector.set(this, void 0);
|
|
51
|
-
|
|
57
|
+
__classPrivateFieldSet(this, _SelectorTarget_selector, selector, "f");
|
|
52
58
|
}
|
|
53
59
|
from(target, combinator) {
|
|
54
|
-
|
|
60
|
+
__classPrivateFieldSet(this, _SelectorTarget_combinedFrom, { target, combinator }, "f");
|
|
55
61
|
}
|
|
56
62
|
match(
|
|
57
63
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
@@ -60,13 +66,13 @@ class SelectorTarget {
|
|
|
60
66
|
if (!unitCheck.matched) {
|
|
61
67
|
return unitCheck;
|
|
62
68
|
}
|
|
63
|
-
if (!
|
|
69
|
+
if (!__classPrivateFieldGet(this, _SelectorTarget_combinedFrom, "f")) {
|
|
64
70
|
return unitCheck;
|
|
65
71
|
}
|
|
66
|
-
if (!
|
|
72
|
+
if (!isNonDocumentTypeChildNode(el)) {
|
|
67
73
|
return unitCheck;
|
|
68
74
|
}
|
|
69
|
-
const { target, combinator } =
|
|
75
|
+
const { target, combinator } = __classPrivateFieldGet(this, _SelectorTarget_combinedFrom, "f");
|
|
70
76
|
switch (combinator) {
|
|
71
77
|
// Descendant combinator
|
|
72
78
|
case ' ': {
|
|
@@ -141,21 +147,21 @@ class SelectorTarget {
|
|
|
141
147
|
return { matched: false };
|
|
142
148
|
}
|
|
143
149
|
default: {
|
|
144
|
-
throw new Error(`Unsupported ${
|
|
150
|
+
throw new Error(`Unsupported ${__classPrivateFieldGet(this, _SelectorTarget_combinedFrom, "f").combinator} combinator in selector`);
|
|
145
151
|
}
|
|
146
152
|
}
|
|
147
153
|
}
|
|
148
154
|
_matchWithoutCombineChecking(
|
|
149
155
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
150
156
|
el) {
|
|
151
|
-
return uncombinedRegexSelect(el,
|
|
157
|
+
return uncombinedRegexSelect(el, __classPrivateFieldGet(this, _SelectorTarget_selector, "f"));
|
|
152
158
|
}
|
|
153
159
|
}
|
|
154
160
|
_SelectorTarget_combinedFrom = new WeakMap(), _SelectorTarget_selector = new WeakMap();
|
|
155
161
|
function uncombinedRegexSelect(
|
|
156
162
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
157
163
|
el, selector) {
|
|
158
|
-
if (!
|
|
164
|
+
if (!isElement(el)) {
|
|
159
165
|
return {
|
|
160
166
|
matched: false,
|
|
161
167
|
};
|
|
@@ -166,7 +172,7 @@ el, selector) {
|
|
|
166
172
|
const specificity = [0, 0, 0];
|
|
167
173
|
const specifiedAttr = new Map();
|
|
168
174
|
if (selector.nodeName) {
|
|
169
|
-
const matchedNodeName =
|
|
175
|
+
const matchedNodeName = regexSelectorMatches(selector.nodeName, el.localName, isPureHTMLElement(el));
|
|
170
176
|
if (matchedNodeName) {
|
|
171
177
|
delete matchedNodeName.$0;
|
|
172
178
|
}
|
|
@@ -180,46 +186,38 @@ el, selector) {
|
|
|
180
186
|
tagSelector = el.localName;
|
|
181
187
|
specificity[2] = 1;
|
|
182
188
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
const matchedAttrName = (
|
|
189
|
+
const isPure = isPureHTMLElement(el);
|
|
190
|
+
if (selector.attrName || selector.attrValue) {
|
|
191
|
+
const matchedAttrList = [...el.attributes]
|
|
192
|
+
.map(attr => {
|
|
193
|
+
const matchedAttrName = regexSelectorMatches(selector.attrName, attr.name, isPure);
|
|
194
|
+
if (selector.attrName && !matchedAttrName) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
const matchedAttrValue = regexSelectorMatches(selector.attrValue, attr.value, isPure);
|
|
198
|
+
if (selector.attrValue && !matchedAttrValue) {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
188
201
|
if (matchedAttrName) {
|
|
189
202
|
delete matchedAttrName.$0;
|
|
190
|
-
data = {
|
|
191
|
-
...data,
|
|
192
|
-
...matchedAttrName,
|
|
193
|
-
};
|
|
194
|
-
specifiedAttr.set(attrName, '');
|
|
195
203
|
}
|
|
196
|
-
return matchedAttrName;
|
|
197
|
-
});
|
|
198
|
-
if (!matchedAttrNameList.some(_ => !!_)) {
|
|
199
|
-
matched = false;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
if (selector.attrValue) {
|
|
203
|
-
const selectorAttrValue = selector.attrValue;
|
|
204
|
-
const matchedAttrValueList = Array.from(el.attributes).map(attr => {
|
|
205
|
-
const attrName = attr.name;
|
|
206
|
-
const attrValue = attr.value;
|
|
207
|
-
const matchedAttrValue = (0, regex_selector_matches_1.regexSelectorMatches)(selectorAttrValue, attrValue, (0, is_1.isPureHTMLElement)(el));
|
|
208
204
|
if (matchedAttrValue) {
|
|
209
205
|
delete matchedAttrValue.$0;
|
|
210
|
-
data = {
|
|
211
|
-
...data,
|
|
212
|
-
...matchedAttrValue,
|
|
213
|
-
};
|
|
214
|
-
specifiedAttr.set(attrName, attrValue);
|
|
215
206
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
207
|
+
data = {
|
|
208
|
+
...data,
|
|
209
|
+
...matchedAttrName,
|
|
210
|
+
...matchedAttrValue,
|
|
211
|
+
};
|
|
212
|
+
specifiedAttr.set(attr.name, matchedAttrValue ? attr.value : '');
|
|
213
|
+
return matchedAttrValue ?? matchedAttrName ?? null;
|
|
214
|
+
})
|
|
215
|
+
.filter((a) => !!a);
|
|
216
|
+
if (matchedAttrList.length === 0) {
|
|
219
217
|
matched = false;
|
|
220
218
|
}
|
|
221
219
|
}
|
|
222
|
-
const attrSelector =
|
|
220
|
+
const attrSelector = [...specifiedAttr.entries()]
|
|
223
221
|
.map(([name, value]) => {
|
|
224
222
|
return `[${name}${value ? `="${value}"` : ''}]`;
|
|
225
223
|
})
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
export declare function regexSelectorMatches(
|
|
2
|
-
|
|
3
|
-
raw: string,
|
|
4
|
-
ignoreCase: boolean,
|
|
5
|
-
): {
|
|
6
|
-
[x: string]: string;
|
|
1
|
+
export declare function regexSelectorMatches(reg: string | undefined, raw: string, ignoreCase: boolean): {
|
|
2
|
+
[x: string]: string;
|
|
7
3
|
} | null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export function regexSelectorMatches(reg, raw, ignoreCase) {
|
|
2
|
+
if (!reg) {
|
|
3
|
+
return null;
|
|
4
|
+
}
|
|
5
5
|
const res = {};
|
|
6
6
|
const pattern = toRegexp(reg);
|
|
7
7
|
const regex = new RegExp(pattern instanceof RegExp ? pattern : `^${pattern.trim()}$`, ignoreCase ? 'i' : undefined);
|
|
@@ -9,15 +9,15 @@ function regexSelectorMatches(reg, raw, ignoreCase) {
|
|
|
9
9
|
if (!matched) {
|
|
10
10
|
return null;
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
for (const [i, val] of matched.entries())
|
|
13
|
+
res[`$${i}`] = val;
|
|
13
14
|
return {
|
|
14
15
|
...res,
|
|
15
16
|
...matched.groups,
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
|
-
exports.regexSelectorMatches = regexSelectorMatches;
|
|
19
19
|
function toRegexp(pattern) {
|
|
20
|
-
const matched = pattern.match(/^\/(.+)\/([
|
|
20
|
+
const matched = pattern.match(/^\/(.+)\/([gi]*)$/i);
|
|
21
21
|
if (matched && matched[1]) {
|
|
22
22
|
return new RegExp(matched[1], matched[2]);
|
|
23
23
|
}
|
package/lib/selector.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { SelectorResult, Specificity } from './types';
|
|
1
|
+
import type { SelectorResult, Specificity } from './types.js';
|
|
2
2
|
type ExtendedPseudoClass = Readonly<Record<string, (content: string) => (el: Element) => SelectorResult>>;
|
|
3
3
|
export declare class Selector {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
#private;
|
|
5
|
+
constructor(selector: string, extended?: ExtendedPseudoClass);
|
|
6
|
+
match(el: Node, scope?: ParentNode | null): Specificity | false;
|
|
7
|
+
search(el: Node, scope?: ParentNode | null): SelectorResult[];
|
|
8
8
|
}
|
|
9
9
|
export {};
|