@markuplint/ml-core 2.0.0-dev.20211213.2 → 2.0.0-dev.20220107.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/lib/ml-core.d.ts +1 -1
- package/lib/ml-core.js +14 -12
- package/lib/ml-dom/document.js +27 -14
- package/lib/ml-dom/helper/match-selector.d.ts +12 -1
- package/lib/ml-dom/helper/match-selector.js +103 -85
- package/lib/ml-dom/helper/selector.d.ts +3 -1
- package/lib/ml-dom/helper/selector.js +237 -66
- package/lib/ml-dom/rule-mapper.d.ts +2 -1
- package/lib/ml-dom/rule-mapper.js +8 -8
- 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 +6 -5
- package/lib/ml-dom/tokens/node.js +20 -6
- package/lib/ml-dom/tokens/preprocessor-specific-attribute.d.ts +1 -0
- package/lib/ml-dom/tokens/preprocessor-specific-attribute.js +3 -0
- package/markuplint-recommended.json +9 -9
- package/package.json +7 -7
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,20 +1,51 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _Selector_ruleset, _Ruleset_selectorGroup, _StructuredSelector_edge, _StructuredSelector_selector, _SelectorTarget_isAdded, _SelectorTarget_combinatedFrom;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.createSelector = void 0;
|
|
4
|
+
exports.compareSpecificity = exports.createSelector = void 0;
|
|
5
5
|
const tslib_1 = require("tslib");
|
|
6
6
|
const postcss_selector_parser_1 = (0, tslib_1.__importDefault)(require("postcss-selector-parser"));
|
|
7
|
+
const debug_1 = require("../../debug");
|
|
8
|
+
const log = debug_1.log.extend('selector');
|
|
9
|
+
const resLog = log.extend('result');
|
|
7
10
|
function createSelector(selector) {
|
|
8
11
|
return new Selector(selector);
|
|
9
12
|
}
|
|
10
13
|
exports.createSelector = createSelector;
|
|
14
|
+
function compareSpecificity(a, b) {
|
|
15
|
+
if (a[0] < b[0]) {
|
|
16
|
+
return -1;
|
|
17
|
+
}
|
|
18
|
+
else if (a[0] > b[0]) {
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
else if (a[1] < b[1]) {
|
|
22
|
+
return -1;
|
|
23
|
+
}
|
|
24
|
+
else if (a[1] > b[1]) {
|
|
25
|
+
return 1;
|
|
26
|
+
}
|
|
27
|
+
else if (a[2] < b[2]) {
|
|
28
|
+
return -1;
|
|
29
|
+
}
|
|
30
|
+
else if (a[2] > b[2]) {
|
|
31
|
+
return 1;
|
|
32
|
+
}
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
exports.compareSpecificity = compareSpecificity;
|
|
11
36
|
class Selector {
|
|
12
37
|
constructor(selector) {
|
|
13
38
|
_Selector_ruleset.set(this, void 0);
|
|
14
39
|
(0, tslib_1.__classPrivateFieldSet)(this, _Selector_ruleset, Ruleset.parse(selector), "f");
|
|
15
40
|
}
|
|
16
41
|
match(el, caller = el) {
|
|
17
|
-
|
|
42
|
+
const results = (0, tslib_1.__classPrivateFieldGet)(this, _Selector_ruleset, "f").match(el, caller);
|
|
43
|
+
for (const result of results) {
|
|
44
|
+
if (result.matched) {
|
|
45
|
+
return result.specificity;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
18
49
|
}
|
|
19
50
|
}
|
|
20
51
|
_Selector_ruleset = new WeakMap();
|
|
@@ -31,7 +62,12 @@ class Ruleset {
|
|
|
31
62
|
return new Ruleset(selectors);
|
|
32
63
|
}
|
|
33
64
|
match(el, caller) {
|
|
34
|
-
|
|
65
|
+
log('%s', el.raw);
|
|
66
|
+
return (0, tslib_1.__classPrivateFieldGet)(this, _Ruleset_selectorGroup, "f").map(selector => {
|
|
67
|
+
const res = selector.match(el, caller);
|
|
68
|
+
resLog('%s => %o', selector.selector, res);
|
|
69
|
+
return res;
|
|
70
|
+
});
|
|
35
71
|
}
|
|
36
72
|
}
|
|
37
73
|
_Ruleset_selectorGroup = new WeakMap();
|
|
@@ -65,6 +101,9 @@ class StructuredSelector {
|
|
|
65
101
|
}
|
|
66
102
|
});
|
|
67
103
|
}
|
|
104
|
+
get selector() {
|
|
105
|
+
return (0, tslib_1.__classPrivateFieldGet)(this, _StructuredSelector_selector, "f").nodes.join('');
|
|
106
|
+
}
|
|
68
107
|
match(el, caller) {
|
|
69
108
|
return (0, tslib_1.__classPrivateFieldGet)(this, _StructuredSelector_edge, "f").match(el, caller);
|
|
70
109
|
}
|
|
@@ -81,60 +120,125 @@ class SelectorTarget {
|
|
|
81
120
|
_SelectorTarget_combinatedFrom.set(this, null);
|
|
82
121
|
}
|
|
83
122
|
match(el, caller) {
|
|
84
|
-
const
|
|
85
|
-
if (!matched) {
|
|
86
|
-
return
|
|
123
|
+
const unitCheck = this._matchWithoutCombinateChecking(el, caller);
|
|
124
|
+
if (!unitCheck.matched) {
|
|
125
|
+
return unitCheck;
|
|
87
126
|
}
|
|
88
127
|
if (!(0, tslib_1.__classPrivateFieldGet)(this, _SelectorTarget_combinatedFrom, "f")) {
|
|
89
|
-
return
|
|
128
|
+
return unitCheck;
|
|
90
129
|
}
|
|
91
130
|
const { target, combinator } = (0, tslib_1.__classPrivateFieldGet)(this, _SelectorTarget_combinatedFrom, "f");
|
|
92
131
|
switch (combinator.value) {
|
|
93
132
|
// Descendant combinator
|
|
94
133
|
case ' ': {
|
|
95
|
-
let ancestor = el.
|
|
134
|
+
let ancestor = el.getParentElement();
|
|
135
|
+
let matched = false;
|
|
136
|
+
let specificity;
|
|
96
137
|
while (ancestor) {
|
|
97
|
-
const
|
|
98
|
-
if (
|
|
99
|
-
|
|
138
|
+
const res = target.match(ancestor, caller);
|
|
139
|
+
if (!specificity) {
|
|
140
|
+
specificity = [
|
|
141
|
+
unitCheck.specificity[0] + res.specificity[0],
|
|
142
|
+
unitCheck.specificity[1] + res.specificity[1],
|
|
143
|
+
unitCheck.specificity[2] + res.specificity[2],
|
|
144
|
+
];
|
|
145
|
+
}
|
|
146
|
+
if (res.matched) {
|
|
147
|
+
matched = true;
|
|
100
148
|
}
|
|
101
|
-
ancestor = ancestor.
|
|
149
|
+
ancestor = ancestor.getParentElement();
|
|
150
|
+
}
|
|
151
|
+
if (!specificity) {
|
|
152
|
+
const res = target.match(el, caller);
|
|
153
|
+
specificity = [
|
|
154
|
+
unitCheck.specificity[0] + res.specificity[0],
|
|
155
|
+
unitCheck.specificity[1] + res.specificity[1],
|
|
156
|
+
unitCheck.specificity[2] + res.specificity[2],
|
|
157
|
+
];
|
|
102
158
|
}
|
|
103
|
-
return
|
|
159
|
+
return {
|
|
160
|
+
specificity,
|
|
161
|
+
matched,
|
|
162
|
+
};
|
|
104
163
|
}
|
|
105
164
|
// Child combinator
|
|
106
165
|
case '>': {
|
|
107
|
-
|
|
108
|
-
|
|
166
|
+
let matched;
|
|
167
|
+
const specificity = unitCheck.specificity;
|
|
168
|
+
const parentNode = el.getParentElement();
|
|
169
|
+
if (parentNode) {
|
|
170
|
+
const res = target.match(parentNode, caller);
|
|
171
|
+
specificity[0] += res.specificity[0];
|
|
172
|
+
specificity[1] += res.specificity[1];
|
|
173
|
+
specificity[2] += res.specificity[2];
|
|
174
|
+
matched = res.matched;
|
|
109
175
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
176
|
+
else {
|
|
177
|
+
const res = target.match(el, caller);
|
|
178
|
+
specificity[0] += res.specificity[0];
|
|
179
|
+
specificity[1] += res.specificity[1];
|
|
180
|
+
specificity[2] += res.specificity[2];
|
|
181
|
+
matched = false;
|
|
113
182
|
}
|
|
114
|
-
return
|
|
183
|
+
return {
|
|
184
|
+
specificity,
|
|
185
|
+
matched,
|
|
186
|
+
};
|
|
115
187
|
}
|
|
116
188
|
// Next-sibling combinator
|
|
117
189
|
case '+': {
|
|
118
|
-
|
|
119
|
-
|
|
190
|
+
let matched;
|
|
191
|
+
const specificity = unitCheck.specificity;
|
|
192
|
+
if (el.previousElementSibling) {
|
|
193
|
+
const res = target.match(el.previousElementSibling, caller);
|
|
194
|
+
specificity[0] += res.specificity[0];
|
|
195
|
+
specificity[1] += res.specificity[1];
|
|
196
|
+
specificity[2] += res.specificity[2];
|
|
197
|
+
matched = res.matched;
|
|
120
198
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
199
|
+
else {
|
|
200
|
+
const res = target.match(el, caller);
|
|
201
|
+
specificity[0] += res.specificity[0];
|
|
202
|
+
specificity[1] += res.specificity[1];
|
|
203
|
+
specificity[2] += res.specificity[2];
|
|
204
|
+
matched = false;
|
|
124
205
|
}
|
|
125
|
-
return
|
|
206
|
+
return {
|
|
207
|
+
specificity,
|
|
208
|
+
matched,
|
|
209
|
+
};
|
|
126
210
|
}
|
|
127
|
-
// Subsequent-sibling combinator
|
|
211
|
+
// // Subsequent-sibling combinator
|
|
128
212
|
case '~': {
|
|
129
213
|
let prev = el.previousElementSibling;
|
|
214
|
+
let matched = false;
|
|
215
|
+
let specificity;
|
|
130
216
|
while (prev) {
|
|
131
|
-
const
|
|
132
|
-
if (
|
|
133
|
-
|
|
217
|
+
const res = target.match(prev, caller);
|
|
218
|
+
if (!specificity) {
|
|
219
|
+
specificity = [
|
|
220
|
+
unitCheck.specificity[0] + res.specificity[0],
|
|
221
|
+
unitCheck.specificity[1] + res.specificity[1],
|
|
222
|
+
unitCheck.specificity[2] + res.specificity[2],
|
|
223
|
+
];
|
|
224
|
+
}
|
|
225
|
+
if (res.matched) {
|
|
226
|
+
matched = true;
|
|
134
227
|
}
|
|
135
228
|
prev = prev.previousElementSibling;
|
|
136
229
|
}
|
|
137
|
-
|
|
230
|
+
if (!specificity) {
|
|
231
|
+
const res = target.match(el, caller);
|
|
232
|
+
specificity = [
|
|
233
|
+
unitCheck.specificity[0] + res.specificity[0],
|
|
234
|
+
unitCheck.specificity[1] + res.specificity[1],
|
|
235
|
+
unitCheck.specificity[2] + res.specificity[2],
|
|
236
|
+
];
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
specificity,
|
|
240
|
+
matched,
|
|
241
|
+
};
|
|
138
242
|
}
|
|
139
243
|
// Column combinator
|
|
140
244
|
case '||': {
|
|
@@ -146,27 +250,42 @@ class SelectorTarget {
|
|
|
146
250
|
}
|
|
147
251
|
}
|
|
148
252
|
_matchWithoutCombinateChecking(el, caller) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (this.tag.value.toLowerCase() !== el.nodeName.toLowerCase()) {
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
253
|
+
const specificity = [0, 0, 0];
|
|
254
|
+
let matched = true;
|
|
255
|
+
if (!(0, tslib_1.__classPrivateFieldGet)(this, _SelectorTarget_isAdded, "f") && !isScope(el, caller)) {
|
|
256
|
+
matched = false;
|
|
156
257
|
}
|
|
157
258
|
if (!this.id.every(id => id.value === el.id)) {
|
|
158
|
-
|
|
259
|
+
matched = false;
|
|
159
260
|
}
|
|
261
|
+
specificity[0] += this.id.length;
|
|
160
262
|
if (!this.class.every(className => el.classList.includes(className.value))) {
|
|
161
|
-
|
|
263
|
+
matched = false;
|
|
162
264
|
}
|
|
265
|
+
specificity[1] += this.class.length;
|
|
163
266
|
if (!this.attr.every(attr => attrMatch(attr, el))) {
|
|
164
|
-
|
|
267
|
+
matched = false;
|
|
165
268
|
}
|
|
166
|
-
|
|
167
|
-
|
|
269
|
+
specificity[1] += this.attr.length;
|
|
270
|
+
for (const pseudo of this.pseudo) {
|
|
271
|
+
const pseudoRes = pseudoMatch(pseudo, el, caller);
|
|
272
|
+
specificity[0] += pseudoRes.specificity[0];
|
|
273
|
+
specificity[1] += pseudoRes.specificity[1];
|
|
274
|
+
specificity[2] += pseudoRes.specificity[2];
|
|
275
|
+
if (!pseudoRes.matched) {
|
|
276
|
+
matched = false;
|
|
277
|
+
}
|
|
168
278
|
}
|
|
169
|
-
|
|
279
|
+
if (this.tag && this.tag.type === 'tag') {
|
|
280
|
+
specificity[2] += 1;
|
|
281
|
+
if (this.tag.value.toLowerCase() !== el.nodeName.toLowerCase()) {
|
|
282
|
+
matched = false;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
specificity,
|
|
287
|
+
matched,
|
|
288
|
+
};
|
|
170
289
|
}
|
|
171
290
|
add(selector) {
|
|
172
291
|
(0, tslib_1.__classPrivateFieldSet)(this, _SelectorTarget_isAdded, true, "f");
|
|
@@ -260,51 +379,87 @@ function pseudoMatch(pseudo, el, caller) {
|
|
|
260
379
|
*/
|
|
261
380
|
case ':closest': {
|
|
262
381
|
const ruleset = new Ruleset(pseudo.nodes);
|
|
263
|
-
|
|
382
|
+
const specificity = getSpecificity(ruleset.match(el, caller));
|
|
383
|
+
let parent = el.getParentElement();
|
|
264
384
|
while (parent) {
|
|
265
|
-
if (ruleset.match(parent, caller)) {
|
|
266
|
-
return
|
|
385
|
+
if (ruleset.match(parent, caller).some(r => r.matched)) {
|
|
386
|
+
return {
|
|
387
|
+
specificity,
|
|
388
|
+
matched: true,
|
|
389
|
+
};
|
|
267
390
|
}
|
|
268
|
-
parent = parent.
|
|
391
|
+
parent = parent.getParentElement();
|
|
269
392
|
}
|
|
270
|
-
return
|
|
393
|
+
return {
|
|
394
|
+
specificity,
|
|
395
|
+
matched: false,
|
|
396
|
+
};
|
|
271
397
|
}
|
|
272
398
|
/**
|
|
273
399
|
* Below, Selector Level 4
|
|
274
400
|
*/
|
|
275
401
|
case ':not': {
|
|
276
402
|
const ruleset = new Ruleset(pseudo.nodes);
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
403
|
+
const resList = ruleset.match(el, caller);
|
|
404
|
+
const specificity = getSpecificity(resList);
|
|
405
|
+
const matched = resList.every(r => !r.matched);
|
|
406
|
+
return {
|
|
407
|
+
specificity,
|
|
408
|
+
matched,
|
|
409
|
+
};
|
|
281
410
|
}
|
|
282
411
|
case ':is': {
|
|
283
412
|
const ruleset = new Ruleset(pseudo.nodes);
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
413
|
+
const resList = ruleset.match(el, caller);
|
|
414
|
+
const specificity = getSpecificity(resList);
|
|
415
|
+
const matched = resList.some(r => r.matched);
|
|
416
|
+
return {
|
|
417
|
+
specificity,
|
|
418
|
+
matched,
|
|
419
|
+
};
|
|
288
420
|
}
|
|
289
421
|
case ':has': {
|
|
290
422
|
const ruleset = new Ruleset(pseudo.nodes);
|
|
423
|
+
const specificity = getSpecificity(ruleset.match(el, caller));
|
|
291
424
|
const descendants = getDescendants(el);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
425
|
+
const matched = descendants.some(desc => ruleset.match(desc, caller).some(m => m.matched));
|
|
426
|
+
return {
|
|
427
|
+
specificity,
|
|
428
|
+
matched,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
case ':where': {
|
|
432
|
+
const ruleset = new Ruleset(pseudo.nodes);
|
|
433
|
+
const resList = ruleset.match(el, caller);
|
|
434
|
+
const matched = resList.some(r => r.matched);
|
|
435
|
+
return {
|
|
436
|
+
specificity: [0, 0, 0],
|
|
437
|
+
matched,
|
|
438
|
+
};
|
|
296
439
|
}
|
|
297
440
|
case ':scope': {
|
|
298
441
|
if (!isScope(el, caller)) {
|
|
299
|
-
return
|
|
442
|
+
return {
|
|
443
|
+
specificity: [0, 1, 0],
|
|
444
|
+
matched: false,
|
|
445
|
+
};
|
|
300
446
|
}
|
|
301
|
-
|
|
447
|
+
return {
|
|
448
|
+
specificity: [0, 1, 0],
|
|
449
|
+
matched: true,
|
|
450
|
+
};
|
|
302
451
|
}
|
|
303
452
|
case ':root': {
|
|
304
453
|
if (!(!el.isInFragmentDocument && el.parentNode === null)) {
|
|
305
|
-
return
|
|
454
|
+
return {
|
|
455
|
+
specificity: [0, 1, 0],
|
|
456
|
+
matched: false,
|
|
457
|
+
};
|
|
306
458
|
}
|
|
307
|
-
|
|
459
|
+
return {
|
|
460
|
+
specificity: [0, 1, 0],
|
|
461
|
+
matched: true,
|
|
462
|
+
};
|
|
308
463
|
}
|
|
309
464
|
case ':enable':
|
|
310
465
|
case ':disable':
|
|
@@ -337,7 +492,6 @@ function pseudoMatch(pseudo, el, caller) {
|
|
|
337
492
|
case ':nth-col': {
|
|
338
493
|
throw new Error(`Unsupported pseudo ${pseudo.toString()} selector yet. If you want it, please request it as the issue (https://github.com/markuplint/markuplint/issues/new).`);
|
|
339
494
|
}
|
|
340
|
-
case ':where':
|
|
341
495
|
case ':dir':
|
|
342
496
|
case ':lang':
|
|
343
497
|
case ':any-link':
|
|
@@ -360,7 +514,6 @@ function pseudoMatch(pseudo, el, caller) {
|
|
|
360
514
|
throw new Error(`Unsupported pseudo ${pseudo.toString()} selector.`);
|
|
361
515
|
}
|
|
362
516
|
}
|
|
363
|
-
return true;
|
|
364
517
|
}
|
|
365
518
|
function isScope(el, caller) {
|
|
366
519
|
return el.uuid === (caller === null || caller === void 0 ? void 0 : caller.uuid) || (!el.isInFragmentDocument && el.parentNode === null);
|
|
@@ -368,3 +521,21 @@ function isScope(el, caller) {
|
|
|
368
521
|
function getDescendants(el, includeSelf = false) {
|
|
369
522
|
return [...el.children.map(child => getDescendants(child, true)).flat(), ...(includeSelf ? [el] : [])];
|
|
370
523
|
}
|
|
524
|
+
function getSpecificity(result) {
|
|
525
|
+
let specificity;
|
|
526
|
+
for (const res of result) {
|
|
527
|
+
if (specificity) {
|
|
528
|
+
const order = compareSpecificity(specificity, res.specificity);
|
|
529
|
+
if (order === -1) {
|
|
530
|
+
specificity = res.specificity;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
specificity = res.specificity;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
if (!specificity) {
|
|
538
|
+
throw new Error('Result is empty');
|
|
539
|
+
}
|
|
540
|
+
return specificity;
|
|
541
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import type { Specificity } from './helper/selector';
|
|
1
2
|
import type { AnonymousNode } from './types';
|
|
2
3
|
import type { AnyRule } from '@markuplint/ml-config';
|
|
3
4
|
declare type RuleType = 'rules' | 'nodeRules' | 'childNodeRules';
|
|
4
5
|
declare type MappingLayer = {
|
|
5
6
|
from: RuleType;
|
|
6
|
-
|
|
7
|
+
specificity: Specificity;
|
|
7
8
|
rule: AnyRule;
|
|
8
9
|
};
|
|
9
10
|
export declare class RuleMapper<N extends AnonymousNode<any, any> = AnonymousNode<any, any>> {
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.RuleMapper = void 0;
|
|
5
5
|
const tslib_1 = require("tslib");
|
|
6
6
|
const debug_1 = require("../debug");
|
|
7
|
+
const selector_1 = require("./helper/selector");
|
|
7
8
|
const ruleMapperLog = debug_1.log.extend('rule-mapper');
|
|
8
9
|
const ruleMapperNodeLog = ruleMapperLog.extend('node');
|
|
9
10
|
const ruleMapperNodeRuleLog = ruleMapperNodeLog.extend('rule');
|
|
@@ -20,13 +21,12 @@ class RuleMapper {
|
|
|
20
21
|
const rules = (0, tslib_1.__classPrivateFieldGet)(this, _RuleMapper_ruleMap, "f").get(node.uuid) || {};
|
|
21
22
|
const currentRule = rules[ruleName];
|
|
22
23
|
if (currentRule) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
else {
|
|
27
|
-
ruleMapperLog("Don't set %o (%d vs %d)", rule, currentRule.index, rule.index);
|
|
24
|
+
const order = (0, selector_1.compareSpecificity)(currentRule.specificity, rule.specificity);
|
|
25
|
+
if (order === 1) {
|
|
26
|
+
ruleMapperLog("Don't set %o ([%s] vs [%s])", rule, currentRule.specificity, rule.specificity);
|
|
28
27
|
return;
|
|
29
28
|
}
|
|
29
|
+
ruleMapperLog('Unset %o from %s', currentRule, node);
|
|
30
30
|
}
|
|
31
31
|
rules[ruleName] = rule;
|
|
32
32
|
(0, tslib_1.__classPrivateFieldGet)(this, _RuleMapper_ruleMap, "f").set(node.uuid, rules);
|
|
@@ -42,13 +42,13 @@ class RuleMapper {
|
|
|
42
42
|
if (!rules) {
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
|
-
const
|
|
45
|
+
const slash = node.type === 'ElementCloseTag' ? '/' : '';
|
|
46
46
|
const nodeName = 'nodeName' in node ? node.nodeName : `#${node.type}`;
|
|
47
|
-
ruleMapperNodeLog('<%s%s>',
|
|
47
|
+
ruleMapperNodeLog('<%s%s>', slash, nodeName);
|
|
48
48
|
Object.keys(rules).forEach(ruleName => {
|
|
49
49
|
const rule = rules[ruleName];
|
|
50
50
|
node.rules[ruleName] = rule.rule;
|
|
51
|
-
ruleMapperNodeRuleLog('[from: %s(%
|
|
51
|
+
ruleMapperNodeRuleLog('[from: %s(%s)] %s: %o', rule.from, rule.specificity, ruleName, rule.rule);
|
|
52
52
|
});
|
|
53
53
|
});
|
|
54
54
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var _MLDOMAbstractElement_fixedNodeName;
|
|
2
|
+
var _MLDOMAbstractElement_fixedNodeName, _MLDOMAbstractElement_getChildElementsAndTextNodeWithoutWhitespacesCache, _MLDOMAbstractElement_normalizedString;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
@@ -15,6 +15,8 @@ class MLDOMAbstractElement extends node_1.default {
|
|
|
15
15
|
this.childModels = new Set();
|
|
16
16
|
this.descendantModels = new Set();
|
|
17
17
|
_MLDOMAbstractElement_fixedNodeName.set(this, void 0);
|
|
18
|
+
_MLDOMAbstractElement_getChildElementsAndTextNodeWithoutWhitespacesCache.set(this, null);
|
|
19
|
+
_MLDOMAbstractElement_normalizedString.set(this, null);
|
|
18
20
|
this.nodeName = astNode.nodeName;
|
|
19
21
|
(0, tslib_1.__classPrivateFieldSet)(this, _MLDOMAbstractElement_fixedNodeName, astNode.nodeName, "f");
|
|
20
22
|
this.namespaceURI = astNode.namespace;
|
|
@@ -113,7 +115,7 @@ class MLDOMAbstractElement extends node_1.default {
|
|
|
113
115
|
if (selecor.match(el, this)) {
|
|
114
116
|
return el;
|
|
115
117
|
}
|
|
116
|
-
el = el.
|
|
118
|
+
el = el.getParentElement();
|
|
117
119
|
} while (el !== null && el.type === 'Element');
|
|
118
120
|
return null;
|
|
119
121
|
}
|
|
@@ -145,12 +147,15 @@ class MLDOMAbstractElement extends node_1.default {
|
|
|
145
147
|
return !!this.getAttributeToken(attrName).length;
|
|
146
148
|
}
|
|
147
149
|
matches(selector) {
|
|
148
|
-
return (0, helper_1.createSelector)(selector).match(this);
|
|
150
|
+
return !!(0, helper_1.createSelector)(selector).match(this);
|
|
149
151
|
}
|
|
150
152
|
fixNodeName(name) {
|
|
151
153
|
(0, tslib_1.__classPrivateFieldSet)(this, _MLDOMAbstractElement_fixedNodeName, name, "f");
|
|
152
154
|
}
|
|
153
155
|
getChildElementsAndTextNodeWithoutWhitespaces() {
|
|
156
|
+
if ((0, tslib_1.__classPrivateFieldGet)(this, _MLDOMAbstractElement_getChildElementsAndTextNodeWithoutWhitespacesCache, "f")) {
|
|
157
|
+
return (0, tslib_1.__classPrivateFieldGet)(this, _MLDOMAbstractElement_getChildElementsAndTextNodeWithoutWhitespacesCache, "f");
|
|
158
|
+
}
|
|
154
159
|
const filteredNodes = [];
|
|
155
160
|
this.childNodes.forEach(node => {
|
|
156
161
|
if (node.type === 'Element') {
|
|
@@ -164,6 +169,7 @@ class MLDOMAbstractElement extends node_1.default {
|
|
|
164
169
|
filteredNodes.push(...children);
|
|
165
170
|
}
|
|
166
171
|
});
|
|
172
|
+
(0, tslib_1.__classPrivateFieldSet)(this, _MLDOMAbstractElement_getChildElementsAndTextNodeWithoutWhitespacesCache, filteredNodes, "f");
|
|
167
173
|
return filteredNodes;
|
|
168
174
|
}
|
|
169
175
|
/**
|
|
@@ -173,7 +179,7 @@ class MLDOMAbstractElement extends node_1.default {
|
|
|
173
179
|
return this.childNodes.some(node => node.type === 'PSBlock');
|
|
174
180
|
}
|
|
175
181
|
isDescendantByUUIDList(uuidList) {
|
|
176
|
-
let el = this.
|
|
182
|
+
let el = this.getParentElement();
|
|
177
183
|
if (el === null) {
|
|
178
184
|
return false;
|
|
179
185
|
}
|
|
@@ -181,10 +187,29 @@ class MLDOMAbstractElement extends node_1.default {
|
|
|
181
187
|
if (uuidList.includes(el.uuid)) {
|
|
182
188
|
return true;
|
|
183
189
|
}
|
|
184
|
-
el = el.
|
|
190
|
+
el = el.getParentElement();
|
|
185
191
|
} while (el !== null && el.type === 'Element');
|
|
186
192
|
return false;
|
|
187
193
|
}
|
|
194
|
+
toNormalizeString() {
|
|
195
|
+
if ((0, tslib_1.__classPrivateFieldGet)(this, _MLDOMAbstractElement_normalizedString, "f")) {
|
|
196
|
+
return (0, tslib_1.__classPrivateFieldGet)(this, _MLDOMAbstractElement_normalizedString, "f");
|
|
197
|
+
}
|
|
198
|
+
const children = this.getChildElementsAndTextNodeWithoutWhitespaces();
|
|
199
|
+
const attrs = this.attributes.map(attr => attr.toNormalizeString());
|
|
200
|
+
const attrString = attrs.length ? ' ' + attrs.join('') : '';
|
|
201
|
+
const startTag = `<${this.nodeName}${attrString}>`;
|
|
202
|
+
const childNodes = children.map(node => {
|
|
203
|
+
if (node.type === 'Element') {
|
|
204
|
+
return node.toNormalizeString();
|
|
205
|
+
}
|
|
206
|
+
return node.originRaw;
|
|
207
|
+
});
|
|
208
|
+
const endTag = `</${this.nodeName}>`;
|
|
209
|
+
const normalizedString = `${startTag}${childNodes.join('')}${endTag}`;
|
|
210
|
+
(0, tslib_1.__classPrivateFieldSet)(this, _MLDOMAbstractElement_normalizedString, normalizedString, "f");
|
|
211
|
+
return normalizedString;
|
|
212
|
+
}
|
|
188
213
|
}
|
|
189
214
|
exports.default = MLDOMAbstractElement;
|
|
190
|
-
_MLDOMAbstractElement_fixedNodeName = new WeakMap();
|
|
215
|
+
_MLDOMAbstractElement_fixedNodeName = new WeakMap(), _MLDOMAbstractElement_getChildElementsAndTextNodeWithoutWhitespacesCache = new WeakMap(), _MLDOMAbstractElement_normalizedString = new WeakMap();
|
|
@@ -69,5 +69,12 @@ class MLDOMAttribute extends token_1.default {
|
|
|
69
69
|
toString(withSpace = true) {
|
|
70
70
|
return (withSpace ? this.spacesBeforeName.raw : '') + this.raw;
|
|
71
71
|
}
|
|
72
|
+
toNormalizeString() {
|
|
73
|
+
return (this.name.originRaw +
|
|
74
|
+
this.equal.originRaw +
|
|
75
|
+
this.startQuote.originRaw +
|
|
76
|
+
this.value.originRaw +
|
|
77
|
+
this.endQuote.originRaw);
|
|
78
|
+
}
|
|
72
79
|
}
|
|
73
80
|
exports.default = MLDOMAttribute;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Document } from '../';
|
|
2
2
|
import type { RuleInfo } from '../../';
|
|
3
3
|
import type { AnonymousNode, IMLDOMNode, NodeType } from '../types';
|
|
4
|
-
import type { MLDOMElement, MLDOMOmittedElement } from './';
|
|
4
|
+
import type { MLDOMElement, MLDOMOmittedElement, MLDOMPreprocessorSpecificBlock } from './';
|
|
5
5
|
import type { MLASTAbstructNode } from '@markuplint/ml-ast';
|
|
6
6
|
import type { AnyRule, RuleConfigValue } from '@markuplint/ml-config';
|
|
7
7
|
import MLDOMToken from './token';
|
|
@@ -11,13 +11,14 @@ export default abstract class MLDOMNode<T extends RuleConfigValue, O = null, A e
|
|
|
11
11
|
readonly rules: Record<string, AnyRule>;
|
|
12
12
|
protected _astToken: A;
|
|
13
13
|
constructor(astNode: A, document: Document<T, O>);
|
|
14
|
-
get parentNode(): MLDOMElement<T, O> | MLDOMOmittedElement<T, O> | null;
|
|
14
|
+
get parentNode(): MLDOMElement<T, O> | MLDOMOmittedElement<T, O> | MLDOMPreprocessorSpecificBlock<T, O> | null;
|
|
15
15
|
get prevNode(): AnonymousNode<T, O> | null;
|
|
16
16
|
get nextNode(): AnonymousNode<T, O> | null;
|
|
17
|
-
get syntaxicalParentNode(): MLDOMElement<T, O> | null;
|
|
17
|
+
get syntaxicalParentNode(): MLDOMElement<T, O> | MLDOMPreprocessorSpecificBlock<T, O> | null;
|
|
18
18
|
get prevToken(): AnonymousNode<T, O> | null;
|
|
19
19
|
get nodeStore(): import("../helper").NodeStore;
|
|
20
|
-
toString(): string;
|
|
21
|
-
is(type: NodeType): boolean;
|
|
22
20
|
get rule(): RuleInfo<T, O>;
|
|
21
|
+
getParentElement(): MLDOMElement<T, O> | MLDOMOmittedElement<T, O> | null;
|
|
22
|
+
is(type: NodeType): boolean;
|
|
23
|
+
toString(): string;
|
|
23
24
|
}
|
|
@@ -70,12 +70,6 @@ class MLDOMNode extends token_1.default {
|
|
|
70
70
|
get nodeStore() {
|
|
71
71
|
return (0, tslib_1.__classPrivateFieldGet)(this, _MLDOMNode_doc, "f").nodeStore;
|
|
72
72
|
}
|
|
73
|
-
toString() {
|
|
74
|
-
return this.raw;
|
|
75
|
-
}
|
|
76
|
-
is(type) {
|
|
77
|
-
return this.type === type;
|
|
78
|
-
}
|
|
79
73
|
get rule() {
|
|
80
74
|
if (!(0, tslib_1.__classPrivateFieldGet)(this, _MLDOMNode_doc, "f").currentRule) {
|
|
81
75
|
throw new Error('Invalid call.');
|
|
@@ -87,6 +81,26 @@ class MLDOMNode extends token_1.default {
|
|
|
87
81
|
}
|
|
88
82
|
return (0, tslib_1.__classPrivateFieldGet)(this, _MLDOMNode_doc, "f").currentRule.optimizeOption(rule);
|
|
89
83
|
}
|
|
84
|
+
getParentElement() {
|
|
85
|
+
let parent = this.parentNode;
|
|
86
|
+
if (!parent) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
while (parent) {
|
|
90
|
+
if (parent.type === 'PSBlock') {
|
|
91
|
+
parent = parent.parentNode;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
return parent;
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
is(type) {
|
|
99
|
+
return this.type === type;
|
|
100
|
+
}
|
|
101
|
+
toString() {
|
|
102
|
+
return this.raw;
|
|
103
|
+
}
|
|
90
104
|
}
|
|
91
105
|
exports.default = MLDOMNode;
|
|
92
106
|
_MLDOMNode_doc = new WeakMap(), _MLDOMNode_prevToken = new WeakMap();
|