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