@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.
Files changed (36) hide show
  1. package/lib/convert-ruleset.d.ts +1 -1
  2. package/lib/convert-ruleset.js +1 -1
  3. package/lib/debug.js +8 -2
  4. package/lib/index.d.ts +1 -0
  5. package/lib/index.js +3 -1
  6. package/lib/ml-core.d.ts +2 -1
  7. package/lib/ml-core.js +25 -16
  8. package/lib/ml-dom/document.d.ts +5 -2
  9. package/lib/ml-dom/document.js +99 -51
  10. package/lib/ml-dom/helper/match-selector.d.ts +12 -1
  11. package/lib/ml-dom/helper/match-selector.js +108 -90
  12. package/lib/ml-dom/helper/selector.d.ts +5 -3
  13. package/lib/ml-dom/helper/selector.js +275 -79
  14. package/lib/ml-dom/helper/walkers.js +1 -1
  15. package/lib/ml-dom/rule-mapper.d.ts +16 -0
  16. package/lib/ml-dom/rule-mapper.js +57 -0
  17. package/lib/ml-dom/tokens/abstract-element.d.ts +1 -0
  18. package/lib/ml-dom/tokens/abstract-element.js +31 -6
  19. package/lib/ml-dom/tokens/attribute.d.ts +1 -0
  20. package/lib/ml-dom/tokens/attribute.js +7 -0
  21. package/lib/ml-dom/tokens/node.d.ts +8 -7
  22. package/lib/ml-dom/tokens/node.js +21 -13
  23. package/lib/ml-dom/tokens/preprocessor-specific-attribute.d.ts +1 -0
  24. package/lib/ml-dom/tokens/preprocessor-specific-attribute.js +3 -0
  25. package/lib/ml-dom/tokens/token.d.ts +0 -2
  26. package/lib/ml-dom/tokens/token.js +0 -1
  27. package/lib/ml-rule/ml-rule.d.ts +5 -2
  28. package/lib/ml-rule/ml-rule.js +19 -3
  29. package/lib/ml-rule/types.d.ts +3 -3
  30. package/lib/test/index.d.ts +8 -5
  31. package/lib/test/index.js +7 -7
  32. package/markuplint-recommended.json +150 -11
  33. package/package.json +7 -7
  34. package/tsconfig.tsbuildinfo +1 -1
  35. package/lib/create-rule.d.ts +0 -4
  36. package/lib/create-rule.js +0 -8
@@ -1,50 +1,86 @@
1
1
  "use strict";
2
- var _Selector_ruleset, _Ruleset_selectorGroup, _StructuredSelector_edge, _StructuredSelector_selector, _SelectorTarget_isAdded, _SelectorTarget_combinatedFrom;
2
+ var _Selector_ruleset, _Ruleset_selectorGroup, _StructuredSelector_edge, _StructuredSelector_selector, _SelectorTarget_tagNameCaseSensitive, _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
- function createSelector(selector) {
8
- return new Selector(selector);
7
+ const debug_1 = require("../../debug");
8
+ const log = debug_1.log.extend('selector');
9
+ const resLog = log.extend('result');
10
+ function createSelector(selector, tagNameCaseSensitive) {
11
+ return new Selector(selector, !!tagNameCaseSensitive);
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
- constructor(selector) {
37
+ constructor(selector, tagNameCaseSensitive) {
13
38
  _Selector_ruleset.set(this, void 0);
14
- (0, tslib_1.__classPrivateFieldSet)(this, _Selector_ruleset, Ruleset.parse(selector), "f");
39
+ (0, tslib_1.__classPrivateFieldSet)(this, _Selector_ruleset, Ruleset.parse(selector, tagNameCaseSensitive), "f");
15
40
  }
16
41
  match(el, caller = el) {
17
- return (0, tslib_1.__classPrivateFieldGet)(this, _Selector_ruleset, "f").match(el, caller);
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();
21
52
  class Ruleset {
22
- constructor(selectors) {
53
+ constructor(selectors, tagNameCaseSensitive) {
23
54
  _Ruleset_selectorGroup.set(this, []);
24
- (0, tslib_1.__classPrivateFieldGet)(this, _Ruleset_selectorGroup, "f").push(...selectors.map(selector => new StructuredSelector(selector)));
55
+ (0, tslib_1.__classPrivateFieldGet)(this, _Ruleset_selectorGroup, "f").push(...selectors.map(selector => new StructuredSelector(selector, tagNameCaseSensitive)));
25
56
  }
26
- static parse(selector) {
57
+ static parse(selector, tagNameCaseSensitive) {
27
58
  const selectors = [];
28
59
  (0, postcss_selector_parser_1.default)(root => {
29
60
  selectors.push(...root.nodes);
30
61
  }).processSync(selector);
31
- return new Ruleset(selectors);
62
+ return new Ruleset(selectors, tagNameCaseSensitive);
32
63
  }
33
64
  match(el, caller) {
34
- return (0, tslib_1.__classPrivateFieldGet)(this, _Ruleset_selectorGroup, "f").some(selector => selector.match(el, caller));
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();
38
74
  class StructuredSelector {
39
- constructor(selector) {
75
+ constructor(selector, tagNameCaseSensitive) {
40
76
  _StructuredSelector_edge.set(this, void 0);
41
77
  _StructuredSelector_selector.set(this, void 0);
42
78
  (0, tslib_1.__classPrivateFieldSet)(this, _StructuredSelector_selector, selector, "f");
43
- (0, tslib_1.__classPrivateFieldSet)(this, _StructuredSelector_edge, new SelectorTarget(), "f");
79
+ (0, tslib_1.__classPrivateFieldSet)(this, _StructuredSelector_edge, new SelectorTarget(tagNameCaseSensitive), "f");
44
80
  (0, tslib_1.__classPrivateFieldGet)(this, _StructuredSelector_selector, "f").nodes.forEach(node => {
45
81
  switch (node.type) {
46
82
  case 'combinator': {
47
- const combinatedTarget = new SelectorTarget();
83
+ const combinatedTarget = new SelectorTarget(tagNameCaseSensitive);
48
84
  combinatedTarget.from((0, tslib_1.__classPrivateFieldGet)(this, _StructuredSelector_edge, "f"), node);
49
85
  (0, tslib_1.__classPrivateFieldSet)(this, _StructuredSelector_edge, combinatedTarget, "f");
50
86
  break;
@@ -65,76 +101,146 @@ 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
  }
71
110
  }
72
111
  _StructuredSelector_edge = new WeakMap(), _StructuredSelector_selector = new WeakMap();
73
112
  class SelectorTarget {
74
- constructor() {
113
+ constructor(tagNameCaseSensitive) {
75
114
  this.tag = null;
76
115
  this.id = [];
77
116
  this.class = [];
78
117
  this.attr = [];
79
118
  this.pseudo = [];
119
+ _SelectorTarget_tagNameCaseSensitive.set(this, void 0);
80
120
  _SelectorTarget_isAdded.set(this, false);
81
121
  _SelectorTarget_combinatedFrom.set(this, null);
122
+ (0, tslib_1.__classPrivateFieldSet)(this, _SelectorTarget_tagNameCaseSensitive, tagNameCaseSensitive, "f");
82
123
  }
83
124
  match(el, caller) {
84
- const matched = this._matchWithoutCombinateChecking(el, caller);
85
- if (!matched) {
86
- return false;
125
+ const unitCheck = this._matchWithoutCombinateChecking(el, caller);
126
+ if (!unitCheck.matched) {
127
+ return unitCheck;
87
128
  }
88
129
  if (!(0, tslib_1.__classPrivateFieldGet)(this, _SelectorTarget_combinatedFrom, "f")) {
89
- return true;
130
+ return unitCheck;
90
131
  }
91
132
  const { target, combinator } = (0, tslib_1.__classPrivateFieldGet)(this, _SelectorTarget_combinatedFrom, "f");
92
133
  switch (combinator.value) {
93
134
  // Descendant combinator
94
135
  case ' ': {
95
- let ancestor = el.parentNode;
136
+ let ancestor = el.getParentElement();
137
+ let matched = false;
138
+ let specificity;
96
139
  while (ancestor) {
97
- const ancestorMatched = target._matchWithoutCombinateChecking(ancestor, caller);
98
- if (ancestorMatched) {
99
- return target.match(ancestor, caller);
140
+ const res = target.match(ancestor, caller);
141
+ if (!specificity) {
142
+ specificity = [
143
+ unitCheck.specificity[0] + res.specificity[0],
144
+ unitCheck.specificity[1] + res.specificity[1],
145
+ unitCheck.specificity[2] + res.specificity[2],
146
+ ];
147
+ }
148
+ if (res.matched) {
149
+ matched = true;
100
150
  }
101
- ancestor = ancestor.parentNode;
151
+ ancestor = ancestor.getParentElement();
152
+ }
153
+ if (!specificity) {
154
+ const res = target.match(el, caller);
155
+ specificity = [
156
+ unitCheck.specificity[0] + res.specificity[0],
157
+ unitCheck.specificity[1] + res.specificity[1],
158
+ unitCheck.specificity[2] + res.specificity[2],
159
+ ];
102
160
  }
103
- return false;
161
+ return {
162
+ specificity,
163
+ matched,
164
+ };
104
165
  }
105
166
  // Child combinator
106
167
  case '>': {
107
- if (!el.parentNode) {
108
- return false;
168
+ let matched;
169
+ const specificity = unitCheck.specificity;
170
+ const parentNode = el.getParentElement();
171
+ if (parentNode) {
172
+ const res = target.match(parentNode, caller);
173
+ specificity[0] += res.specificity[0];
174
+ specificity[1] += res.specificity[1];
175
+ specificity[2] += res.specificity[2];
176
+ matched = res.matched;
109
177
  }
110
- const parentMatched = target._matchWithoutCombinateChecking(el.parentNode, caller);
111
- if (parentMatched) {
112
- return target.match(el.parentNode, caller);
178
+ else {
179
+ const res = target.match(el, caller);
180
+ specificity[0] += res.specificity[0];
181
+ specificity[1] += res.specificity[1];
182
+ specificity[2] += res.specificity[2];
183
+ matched = false;
113
184
  }
114
- return false;
185
+ return {
186
+ specificity,
187
+ matched,
188
+ };
115
189
  }
116
190
  // Next-sibling combinator
117
191
  case '+': {
118
- if (!el.previousElementSibling) {
119
- return false;
192
+ let matched;
193
+ const specificity = unitCheck.specificity;
194
+ if (el.previousElementSibling) {
195
+ const res = target.match(el.previousElementSibling, caller);
196
+ specificity[0] += res.specificity[0];
197
+ specificity[1] += res.specificity[1];
198
+ specificity[2] += res.specificity[2];
199
+ matched = res.matched;
120
200
  }
121
- const prevMatched = target._matchWithoutCombinateChecking(el.previousElementSibling, caller);
122
- if (prevMatched) {
123
- return target.match(el.previousElementSibling, caller);
201
+ else {
202
+ const res = target.match(el, caller);
203
+ specificity[0] += res.specificity[0];
204
+ specificity[1] += res.specificity[1];
205
+ specificity[2] += res.specificity[2];
206
+ matched = false;
124
207
  }
125
- return false;
208
+ return {
209
+ specificity,
210
+ matched,
211
+ };
126
212
  }
127
- // Subsequent-sibling combinator
213
+ // // Subsequent-sibling combinator
128
214
  case '~': {
129
215
  let prev = el.previousElementSibling;
216
+ let matched = false;
217
+ let specificity;
130
218
  while (prev) {
131
- const prevMatched = target._matchWithoutCombinateChecking(prev, caller);
132
- if (prevMatched) {
133
- return target.match(prev, caller);
219
+ const res = target.match(prev, caller);
220
+ if (!specificity) {
221
+ specificity = [
222
+ unitCheck.specificity[0] + res.specificity[0],
223
+ unitCheck.specificity[1] + res.specificity[1],
224
+ unitCheck.specificity[2] + res.specificity[2],
225
+ ];
226
+ }
227
+ if (res.matched) {
228
+ matched = true;
134
229
  }
135
230
  prev = prev.previousElementSibling;
136
231
  }
137
- return false;
232
+ if (!specificity) {
233
+ const res = target.match(el, caller);
234
+ specificity = [
235
+ unitCheck.specificity[0] + res.specificity[0],
236
+ unitCheck.specificity[1] + res.specificity[1],
237
+ unitCheck.specificity[2] + res.specificity[2],
238
+ ];
239
+ }
240
+ return {
241
+ specificity,
242
+ matched,
243
+ };
138
244
  }
139
245
  // Column combinator
140
246
  case '||': {
@@ -146,27 +252,48 @@ class SelectorTarget {
146
252
  }
147
253
  }
148
254
  _matchWithoutCombinateChecking(el, caller) {
149
- if (!(0, tslib_1.__classPrivateFieldGet)(this, _SelectorTarget_isAdded, "f")) {
150
- return isScope(el, caller);
151
- }
152
- if (this.tag && this.tag.type === 'tag') {
153
- if (this.tag.value.toLowerCase() !== el.nodeName.toLowerCase()) {
154
- return false;
155
- }
255
+ const specificity = [0, 0, 0];
256
+ let matched = true;
257
+ if (!(0, tslib_1.__classPrivateFieldGet)(this, _SelectorTarget_isAdded, "f") && !isScope(el, caller)) {
258
+ matched = false;
156
259
  }
157
260
  if (!this.id.every(id => id.value === el.id)) {
158
- return false;
261
+ matched = false;
159
262
  }
263
+ specificity[0] += this.id.length;
160
264
  if (!this.class.every(className => el.classList.includes(className.value))) {
161
- return false;
265
+ matched = false;
162
266
  }
267
+ specificity[1] += this.class.length;
163
268
  if (!this.attr.every(attr => attrMatch(attr, el))) {
164
- return false;
269
+ matched = false;
165
270
  }
166
- if (!this.pseudo.every(pseudo => pseudoMatch(pseudo, el, caller))) {
167
- return false;
271
+ specificity[1] += this.attr.length;
272
+ for (const pseudo of this.pseudo) {
273
+ const pseudoRes = pseudoMatch(pseudo, el, caller, (0, tslib_1.__classPrivateFieldGet)(this, _SelectorTarget_tagNameCaseSensitive, "f"));
274
+ specificity[0] += pseudoRes.specificity[0];
275
+ specificity[1] += pseudoRes.specificity[1];
276
+ specificity[2] += pseudoRes.specificity[2];
277
+ if (!pseudoRes.matched) {
278
+ matched = false;
279
+ }
168
280
  }
169
- return true;
281
+ if (this.tag && this.tag.type === 'tag') {
282
+ specificity[2] += 1;
283
+ let a = this.tag.value;
284
+ let b = el.nodeName;
285
+ if (!(0, tslib_1.__classPrivateFieldGet)(this, _SelectorTarget_tagNameCaseSensitive, "f")) {
286
+ a = a.toLowerCase();
287
+ b = b.toLowerCase();
288
+ }
289
+ if (a !== b) {
290
+ matched = false;
291
+ }
292
+ }
293
+ return {
294
+ specificity,
295
+ matched,
296
+ };
170
297
  }
171
298
  add(selector) {
172
299
  (0, tslib_1.__classPrivateFieldSet)(this, _SelectorTarget_isAdded, true, "f");
@@ -198,7 +325,7 @@ class SelectorTarget {
198
325
  (0, tslib_1.__classPrivateFieldSet)(this, _SelectorTarget_combinatedFrom, { target, combinator }, "f");
199
326
  }
200
327
  }
201
- _SelectorTarget_isAdded = new WeakMap(), _SelectorTarget_combinatedFrom = new WeakMap();
328
+ _SelectorTarget_tagNameCaseSensitive = new WeakMap(), _SelectorTarget_isAdded = new WeakMap(), _SelectorTarget_combinatedFrom = new WeakMap();
202
329
  function attrMatch(attr, el) {
203
330
  return el.attributes.some(attrOfEl => {
204
331
  if (attr.attribute !== attrOfEl.getName().potential) {
@@ -253,41 +380,94 @@ function attrMatch(attr, el) {
253
380
  return true;
254
381
  });
255
382
  }
256
- function pseudoMatch(pseudo, el, caller) {
383
+ function pseudoMatch(pseudo, el, caller, tagNameCaseSensitive) {
257
384
  switch (pseudo.value) {
258
- case ':not': {
259
- const ruleset = new Ruleset(pseudo.nodes);
260
- if (ruleset.match(el, caller)) {
261
- return false;
385
+ /**
386
+ * Below, markuplint Specific Selector
387
+ */
388
+ case ':closest': {
389
+ const ruleset = new Ruleset(pseudo.nodes, tagNameCaseSensitive);
390
+ const specificity = getSpecificity(ruleset.match(el, caller));
391
+ let parent = el.getParentElement();
392
+ while (parent) {
393
+ if (ruleset.match(parent, caller).some(r => r.matched)) {
394
+ return {
395
+ specificity,
396
+ matched: true,
397
+ };
398
+ }
399
+ parent = parent.getParentElement();
262
400
  }
263
- break;
401
+ return {
402
+ specificity,
403
+ matched: false,
404
+ };
405
+ }
406
+ /**
407
+ * Below, Selector Level 4
408
+ */
409
+ case ':not': {
410
+ const ruleset = new Ruleset(pseudo.nodes, tagNameCaseSensitive);
411
+ const resList = ruleset.match(el, caller);
412
+ const specificity = getSpecificity(resList);
413
+ const matched = resList.every(r => !r.matched);
414
+ return {
415
+ specificity,
416
+ matched,
417
+ };
264
418
  }
265
419
  case ':is': {
266
- const ruleset = new Ruleset(pseudo.nodes);
267
- if (!ruleset.match(el, caller)) {
268
- return false;
269
- }
270
- break;
420
+ const ruleset = new Ruleset(pseudo.nodes, tagNameCaseSensitive);
421
+ const resList = ruleset.match(el, caller);
422
+ const specificity = getSpecificity(resList);
423
+ const matched = resList.some(r => r.matched);
424
+ return {
425
+ specificity,
426
+ matched,
427
+ };
271
428
  }
272
429
  case ':has': {
273
- const ruleset = new Ruleset(pseudo.nodes);
430
+ const ruleset = new Ruleset(pseudo.nodes, tagNameCaseSensitive);
431
+ const specificity = getSpecificity(ruleset.match(el, caller));
274
432
  const descendants = getDescendants(el);
275
- if (!descendants.some(desc => ruleset.match(desc, caller))) {
276
- return false;
277
- }
278
- break;
433
+ const matched = descendants.some(desc => ruleset.match(desc, caller).some(m => m.matched));
434
+ return {
435
+ specificity,
436
+ matched,
437
+ };
438
+ }
439
+ case ':where': {
440
+ const ruleset = new Ruleset(pseudo.nodes, tagNameCaseSensitive);
441
+ const resList = ruleset.match(el, caller);
442
+ const matched = resList.some(r => r.matched);
443
+ return {
444
+ specificity: [0, 0, 0],
445
+ matched,
446
+ };
279
447
  }
280
448
  case ':scope': {
281
449
  if (!isScope(el, caller)) {
282
- return false;
450
+ return {
451
+ specificity: [0, 1, 0],
452
+ matched: false,
453
+ };
283
454
  }
284
- break;
455
+ return {
456
+ specificity: [0, 1, 0],
457
+ matched: true,
458
+ };
285
459
  }
286
460
  case ':root': {
287
461
  if (!(!el.isInFragmentDocument && el.parentNode === null)) {
288
- return false;
462
+ return {
463
+ specificity: [0, 1, 0],
464
+ matched: false,
465
+ };
289
466
  }
290
- break;
467
+ return {
468
+ specificity: [0, 1, 0],
469
+ matched: true,
470
+ };
291
471
  }
292
472
  case ':enable':
293
473
  case ':disable':
@@ -320,7 +500,6 @@ function pseudoMatch(pseudo, el, caller) {
320
500
  case ':nth-col': {
321
501
  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).`);
322
502
  }
323
- case ':where':
324
503
  case ':dir':
325
504
  case ':lang':
326
505
  case ':any-link':
@@ -343,7 +522,6 @@ function pseudoMatch(pseudo, el, caller) {
343
522
  throw new Error(`Unsupported pseudo ${pseudo.toString()} selector.`);
344
523
  }
345
524
  }
346
- return true;
347
525
  }
348
526
  function isScope(el, caller) {
349
527
  return el.uuid === (caller === null || caller === void 0 ? void 0 : caller.uuid) || (!el.isInFragmentDocument && el.parentNode === null);
@@ -351,3 +529,21 @@ function isScope(el, caller) {
351
529
  function getDescendants(el, includeSelf = false) {
352
530
  return [...el.children.map(child => getDescendants(child, true)).flat(), ...(includeSelf ? [el] : [])];
353
531
  }
532
+ function getSpecificity(result) {
533
+ let specificity;
534
+ for (const res of result) {
535
+ if (specificity) {
536
+ const order = compareSpecificity(specificity, res.specificity);
537
+ if (order === -1) {
538
+ specificity = res.specificity;
539
+ }
540
+ }
541
+ else {
542
+ specificity = res.specificity;
543
+ }
544
+ }
545
+ if (!specificity) {
546
+ throw new Error('Result is empty');
547
+ }
548
+ return specificity;
549
+ }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.syncWalk = void 0;
4
4
  function syncWalk(nodeList, walker) {
5
5
  for (const node of nodeList) {
6
- if (node.type === 'Element' || node.type === 'OmittedElement') {
6
+ if (node.type === 'Element' || node.type === 'OmittedElement' || node.type === 'PSBlock') {
7
7
  syncWalk(node.childNodes, walker);
8
8
  }
9
9
  walker(node);
@@ -0,0 +1,16 @@
1
+ import type { Specificity } from './helper/selector';
2
+ import type { AnonymousNode } from './types';
3
+ import type { AnyRule } from '@markuplint/ml-config';
4
+ declare type RuleType = 'rules' | 'nodeRules' | 'childNodeRules';
5
+ declare type MappingLayer = {
6
+ from: RuleType;
7
+ specificity: Specificity;
8
+ rule: AnyRule;
9
+ };
10
+ export declare class RuleMapper<N extends AnonymousNode<any, any> = AnonymousNode<any, any>> {
11
+ #private;
12
+ constructor(nodeList: ReadonlyArray<N>);
13
+ set(node: N, ruleName: string, rule: MappingLayer): void;
14
+ apply(): void;
15
+ }
16
+ export {};
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var _RuleMapper_nodeList, _RuleMapper_ruleMap;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.RuleMapper = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const debug_1 = require("../debug");
7
+ const selector_1 = require("./helper/selector");
8
+ const ruleMapperLog = debug_1.log.extend('rule-mapper');
9
+ const ruleMapperNodeLog = ruleMapperLog.extend('node');
10
+ const ruleMapperNodeRuleLog = ruleMapperNodeLog.extend('rule');
11
+ class RuleMapper {
12
+ constructor(nodeList) {
13
+ _RuleMapper_nodeList.set(this, void 0);
14
+ _RuleMapper_ruleMap.set(this, new Map());
15
+ (0, tslib_1.__classPrivateFieldSet)(this, _RuleMapper_nodeList, nodeList, "f");
16
+ }
17
+ set(node, ruleName, rule) {
18
+ if (node.type === 'ElementCloseTag') {
19
+ return;
20
+ }
21
+ const rules = (0, tslib_1.__classPrivateFieldGet)(this, _RuleMapper_ruleMap, "f").get(node.uuid) || {};
22
+ const currentRule = rules[ruleName];
23
+ if (currentRule) {
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);
27
+ return;
28
+ }
29
+ ruleMapperLog('Unset %o from %s', currentRule, node);
30
+ }
31
+ rules[ruleName] = rule;
32
+ (0, tslib_1.__classPrivateFieldGet)(this, _RuleMapper_ruleMap, "f").set(node.uuid, rules);
33
+ if (node.type === 'Element' && node.closeTag) {
34
+ (0, tslib_1.__classPrivateFieldGet)(this, _RuleMapper_ruleMap, "f").set(node.closeTag.uuid, rules);
35
+ }
36
+ ruleMapperLog('Set to %s from %s (%o): %O', node.raw, rule.from, rule.specificity, rule.rule);
37
+ }
38
+ apply() {
39
+ ruleMapperLog('ruleTree:');
40
+ (0, tslib_1.__classPrivateFieldGet)(this, _RuleMapper_nodeList, "f").forEach(node => {
41
+ const rules = (0, tslib_1.__classPrivateFieldGet)(this, _RuleMapper_ruleMap, "f").get(node.uuid);
42
+ if (!rules) {
43
+ return;
44
+ }
45
+ const slash = node.type === 'ElementCloseTag' ? '/' : '';
46
+ const nodeName = 'nodeName' in node ? node.nodeName : `#${node.type}`;
47
+ ruleMapperNodeLog('<%s%s>', slash, nodeName);
48
+ Object.keys(rules).forEach(ruleName => {
49
+ const rule = rules[ruleName];
50
+ node.rules[ruleName] = rule.rule;
51
+ ruleMapperNodeRuleLog('[from: %s(%s)] %s: %o', rule.from, rule.specificity, ruleName, rule.rule);
52
+ });
53
+ });
54
+ }
55
+ }
56
+ exports.RuleMapper = RuleMapper;
57
+ _RuleMapper_nodeList = new WeakMap(), _RuleMapper_ruleMap = new WeakMap();
@@ -40,4 +40,5 @@ export default abstract class MLDOMAbstractElement<T extends RuleConfigValue, O
40
40
  */
41
41
  hasMutableChildren(): boolean;
42
42
  isDescendantByUUIDList(uuidList: string[]): boolean;
43
+ toNormalizeString(): string;
43
44
  }