@markuplint/ml-core 2.2.3 → 2.3.2
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/lib/ml-core.d.ts +1 -1
- package/lib/ml-dom/helper/accname.js +1 -0
- package/lib/ml-dom/helper/selector.d.ts +1 -1
- package/lib/ml-dom/manipulations/child-node-methods.d.ts +33 -0
- package/lib/ml-dom/manipulations/child-node-methods.js +73 -0
- package/lib/ml-dom/manipulations/get-children.d.ts +4 -0
- package/lib/ml-dom/manipulations/get-children.js +10 -0
- package/lib/ml-dom/node/attr.d.ts +93 -0
- package/lib/ml-dom/node/attr.js +144 -0
- package/lib/ml-dom/node/block.d.ts +38 -0
- package/lib/ml-dom/node/block.js +53 -0
- package/lib/ml-dom/node/character-data.d.ts +57 -0
- package/lib/ml-dom/node/character-data.js +87 -0
- package/lib/ml-dom/node/child-node.d.ts +9 -0
- package/lib/ml-dom/node/child-node.js +10 -0
- package/lib/ml-dom/node/comment.d.ts +17 -0
- package/lib/ml-dom/node/comment.js +24 -0
- package/lib/ml-dom/node/document-fragment.d.ts +24 -0
- package/lib/ml-dom/node/document-fragment.js +33 -0
- package/lib/ml-dom/node/document-type.d.ts +38 -0
- package/lib/ml-dom/node/document-type.js +52 -0
- package/lib/ml-dom/node/document.d.ts +1554 -0
- package/lib/ml-dom/node/document.js +2117 -0
- package/lib/ml-dom/node/dom-token-list.d.ts +15 -0
- package/lib/ml-dom/node/dom-token-list.js +61 -0
- package/lib/ml-dom/node/element.d.ts +1832 -0
- package/lib/ml-dom/node/element.js +2483 -0
- package/lib/ml-dom/node/named-node-map.d.ts +42 -0
- package/lib/ml-dom/node/named-node-map.js +64 -0
- package/lib/ml-dom/node/node-list.d.ts +6 -0
- package/lib/ml-dom/node/node-list.js +39 -0
- package/lib/ml-dom/node/node-store.d.ts +14 -0
- package/lib/ml-dom/node/node-store.js +32 -0
- package/lib/ml-dom/node/node.d.ts +475 -0
- package/lib/ml-dom/node/node.js +672 -0
- package/lib/ml-dom/node/parent-node.d.ts +66 -0
- package/lib/ml-dom/node/parent-node.js +131 -0
- package/lib/ml-dom/node/rule-mapper.d.ts +17 -0
- package/lib/ml-dom/node/rule-mapper.js +49 -0
- package/lib/ml-dom/node/text.d.ts +51 -0
- package/lib/ml-dom/node/text.js +76 -0
- package/lib/ml-dom/node/types.d.ts +25 -0
- package/lib/ml-dom/node/types.js +2 -0
- package/lib/ml-dom/node/unexpected-call-error.d.ts +2 -0
- package/lib/ml-dom/node/unexpected-call-error.js +5 -0
- package/lib/ml-dom/token/token.d.ts +47 -0
- package/lib/ml-dom/token/token.js +89 -0
- package/lib/ml-dom/tokens/abstract-element.d.ts +1 -2
- package/lib/ml-dom/tokens/abstract-element.js +0 -4
- package/lib/ml-dom/tokens/node.d.ts +1 -0
- package/lib/ml-dom/tokens/node.js +8 -0
- package/lib/selector/is-pure-html-element.d.ts +1 -0
- package/lib/selector/is-pure-html-element.js +7 -0
- package/lib/selector/match-selector.d.ts +14 -0
- package/lib/selector/match-selector.js +230 -0
- package/lib/selector/selector.d.ts +9 -0
- package/lib/selector/selector.js +561 -0
- package/package.json +5 -5
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.matchSelector = void 0;
|
|
4
|
+
const ml_config_1 = require("@markuplint/ml-config");
|
|
5
|
+
const is_pure_html_element_1 = require("./is-pure-html-element");
|
|
6
|
+
const selector_1 = require("./selector");
|
|
7
|
+
function matchSelector(el, selector) {
|
|
8
|
+
if (!selector) {
|
|
9
|
+
return {
|
|
10
|
+
matched: false,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
if (typeof selector === 'string') {
|
|
14
|
+
const sel = (0, selector_1.createSelector)(selector);
|
|
15
|
+
const specificity = sel.match(el);
|
|
16
|
+
if (specificity) {
|
|
17
|
+
return {
|
|
18
|
+
matched: true,
|
|
19
|
+
selector,
|
|
20
|
+
specificity,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
matched: false,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return regexSelect(el, selector);
|
|
28
|
+
}
|
|
29
|
+
exports.matchSelector = matchSelector;
|
|
30
|
+
function regexSelect(el, selector) {
|
|
31
|
+
let edge = new SelectorTarget(selector);
|
|
32
|
+
let edgeSelector = selector.combination;
|
|
33
|
+
while (edgeSelector) {
|
|
34
|
+
const child = new SelectorTarget(edgeSelector);
|
|
35
|
+
child.from(edge, edgeSelector.combinator);
|
|
36
|
+
edge = child;
|
|
37
|
+
edgeSelector = edgeSelector.combination;
|
|
38
|
+
}
|
|
39
|
+
return edge.match(el);
|
|
40
|
+
}
|
|
41
|
+
class SelectorTarget {
|
|
42
|
+
constructor(selector) {
|
|
43
|
+
this._combinatedFrom = null;
|
|
44
|
+
this._selector = selector;
|
|
45
|
+
}
|
|
46
|
+
from(target, combinator) {
|
|
47
|
+
this._combinatedFrom = { target, combinator };
|
|
48
|
+
}
|
|
49
|
+
match(el) {
|
|
50
|
+
const unitCheck = this._matchWithoutCombinateChecking(el);
|
|
51
|
+
if (!unitCheck.matched) {
|
|
52
|
+
return unitCheck;
|
|
53
|
+
}
|
|
54
|
+
if (!this._combinatedFrom) {
|
|
55
|
+
return unitCheck;
|
|
56
|
+
}
|
|
57
|
+
const { target, combinator } = this._combinatedFrom;
|
|
58
|
+
switch (combinator) {
|
|
59
|
+
// Descendant combinator
|
|
60
|
+
case ' ': {
|
|
61
|
+
let ancestor = el.parentElement;
|
|
62
|
+
while (ancestor) {
|
|
63
|
+
const matches = target.match(ancestor);
|
|
64
|
+
if (matches.matched) {
|
|
65
|
+
return mergeMatches(matches, unitCheck, ' ');
|
|
66
|
+
}
|
|
67
|
+
ancestor = ancestor.parentElement;
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
matched: false,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// Child combinator
|
|
74
|
+
case '>': {
|
|
75
|
+
const parentNode = el.parentElement;
|
|
76
|
+
if (!parentNode) {
|
|
77
|
+
return { matched: false };
|
|
78
|
+
}
|
|
79
|
+
const matches = target.match(parentNode);
|
|
80
|
+
if (matches.matched) {
|
|
81
|
+
return mergeMatches(matches, unitCheck, ' > ');
|
|
82
|
+
}
|
|
83
|
+
return { matched: false };
|
|
84
|
+
}
|
|
85
|
+
// Next-sibling combinator
|
|
86
|
+
case '+': {
|
|
87
|
+
if (!el.previousElementSibling) {
|
|
88
|
+
return { matched: false };
|
|
89
|
+
}
|
|
90
|
+
const matches = target.match(el.previousElementSibling);
|
|
91
|
+
if (matches.matched) {
|
|
92
|
+
return mergeMatches(matches, unitCheck, ' + ');
|
|
93
|
+
}
|
|
94
|
+
return { matched: false };
|
|
95
|
+
}
|
|
96
|
+
// Subsequent-sibling combinator
|
|
97
|
+
case '~': {
|
|
98
|
+
let prev = el.previousElementSibling;
|
|
99
|
+
while (prev) {
|
|
100
|
+
const matches = target.match(prev);
|
|
101
|
+
if (matches.matched) {
|
|
102
|
+
return mergeMatches(matches, unitCheck, ' ~ ');
|
|
103
|
+
}
|
|
104
|
+
prev = prev.previousElementSibling;
|
|
105
|
+
}
|
|
106
|
+
return { matched: false };
|
|
107
|
+
}
|
|
108
|
+
// Prev-sibling combinator
|
|
109
|
+
case ':has(+)': {
|
|
110
|
+
if (!el.nextElementSibling) {
|
|
111
|
+
return { matched: false };
|
|
112
|
+
}
|
|
113
|
+
const matches = target.match(el.nextElementSibling);
|
|
114
|
+
if (matches.matched) {
|
|
115
|
+
return mergeMatches(matches, unitCheck, ':has(+ ', true);
|
|
116
|
+
}
|
|
117
|
+
return { matched: false };
|
|
118
|
+
}
|
|
119
|
+
// Subsequent-sibling (in front) combinator
|
|
120
|
+
case ':has(~)': {
|
|
121
|
+
let next = el.nextElementSibling;
|
|
122
|
+
while (next) {
|
|
123
|
+
const matches = target.match(next);
|
|
124
|
+
if (matches.matched) {
|
|
125
|
+
return mergeMatches(matches, unitCheck, ':has(~ ', true);
|
|
126
|
+
}
|
|
127
|
+
next = next.nextElementSibling;
|
|
128
|
+
}
|
|
129
|
+
return { matched: false };
|
|
130
|
+
}
|
|
131
|
+
default: {
|
|
132
|
+
throw new Error(`Unsupported ${this._combinatedFrom.combinator} combinator in selector`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
_matchWithoutCombinateChecking(el) {
|
|
137
|
+
return uncombinatedRegexSelect(el, this._selector);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function uncombinatedRegexSelect(el, selector) {
|
|
141
|
+
let matched = true;
|
|
142
|
+
let data = {};
|
|
143
|
+
let tagSelector = '';
|
|
144
|
+
const specificity = [0, 0, 0];
|
|
145
|
+
const specifiedAttr = new Map();
|
|
146
|
+
if (selector.nodeName) {
|
|
147
|
+
const matchedNodeName = (0, ml_config_1.regexSelectorMatches)(selector.nodeName, el.localName, (0, is_pure_html_element_1.isPureHTMLElement)(el));
|
|
148
|
+
if (matchedNodeName) {
|
|
149
|
+
delete matchedNodeName.$0;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
matched = false;
|
|
153
|
+
}
|
|
154
|
+
data = {
|
|
155
|
+
...data,
|
|
156
|
+
...matchedNodeName,
|
|
157
|
+
};
|
|
158
|
+
tagSelector = el.localName;
|
|
159
|
+
specificity[2] = 1;
|
|
160
|
+
}
|
|
161
|
+
if (selector.attrName) {
|
|
162
|
+
const selectorAttrName = selector.attrName;
|
|
163
|
+
const matchedAttrNameList = Array.from(el.attributes).map(attr => {
|
|
164
|
+
const attrName = attr.name;
|
|
165
|
+
const matchedAttrName = (0, ml_config_1.regexSelectorMatches)(selectorAttrName, attrName, (0, is_pure_html_element_1.isPureHTMLElement)(el));
|
|
166
|
+
if (matchedAttrName) {
|
|
167
|
+
delete matchedAttrName.$0;
|
|
168
|
+
data = {
|
|
169
|
+
...data,
|
|
170
|
+
...matchedAttrName,
|
|
171
|
+
};
|
|
172
|
+
specifiedAttr.set(attrName, '');
|
|
173
|
+
}
|
|
174
|
+
return matchedAttrName;
|
|
175
|
+
});
|
|
176
|
+
if (!matchedAttrNameList.some(_ => !!_)) {
|
|
177
|
+
matched = false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (selector.attrValue) {
|
|
181
|
+
const selectorAttrValue = selector.attrValue;
|
|
182
|
+
const matchedAttrValueList = Array.from(el.attributes).map(attr => {
|
|
183
|
+
const attrName = attr.name;
|
|
184
|
+
const attrValue = attr.value;
|
|
185
|
+
const matchedAttrValue = (0, ml_config_1.regexSelectorMatches)(selectorAttrValue, attrValue, (0, is_pure_html_element_1.isPureHTMLElement)(el));
|
|
186
|
+
if (matchedAttrValue) {
|
|
187
|
+
delete matchedAttrValue.$0;
|
|
188
|
+
data = {
|
|
189
|
+
...data,
|
|
190
|
+
...matchedAttrValue,
|
|
191
|
+
};
|
|
192
|
+
specifiedAttr.set(attrName, attrValue);
|
|
193
|
+
}
|
|
194
|
+
return matchedAttrValue;
|
|
195
|
+
});
|
|
196
|
+
if (!matchedAttrValueList.some(_ => !!_)) {
|
|
197
|
+
matched = false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const attrSelector = Array.from(specifiedAttr.entries())
|
|
201
|
+
.map(([name, value]) => {
|
|
202
|
+
return `[${name}${value ? `="${value}"` : ''}]`;
|
|
203
|
+
})
|
|
204
|
+
.join('');
|
|
205
|
+
specificity[1] += specifiedAttr.size;
|
|
206
|
+
if (matched) {
|
|
207
|
+
return {
|
|
208
|
+
matched,
|
|
209
|
+
selector: `${tagSelector}${attrSelector}`,
|
|
210
|
+
specificity,
|
|
211
|
+
data,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return { matched };
|
|
215
|
+
}
|
|
216
|
+
function mergeMatches(a, b, sep, close = false) {
|
|
217
|
+
return {
|
|
218
|
+
matched: true,
|
|
219
|
+
selector: `${a.selector}${sep}${b.selector}${close ? ')' : ''}`,
|
|
220
|
+
specificity: [
|
|
221
|
+
a.specificity[0] + b.specificity[0],
|
|
222
|
+
a.specificity[1] + b.specificity[1],
|
|
223
|
+
a.specificity[2] + b.specificity[2],
|
|
224
|
+
],
|
|
225
|
+
data: {
|
|
226
|
+
...a.data,
|
|
227
|
+
...b.data,
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare type Specificity = [number, number, number];
|
|
2
|
+
export declare function createSelector(selector: string): Selector;
|
|
3
|
+
export declare function compareSpecificity(a: Specificity, b: Specificity): 1 | 0 | -1;
|
|
4
|
+
declare class Selector {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(selector: string);
|
|
7
|
+
match(el: Element, caller?: ParentNode | null): Specificity | false;
|
|
8
|
+
}
|
|
9
|
+
export {};
|