@markuplint/ml-core 4.13.3 → 5.0.0-alpha.1
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/ARCHITECTURE.ja.md +92 -35
- package/ARCHITECTURE.md +85 -28
- package/CHANGELOG.md +54 -0
- package/docs/linting-pipeline.ja.md +18 -14
- package/docs/linting-pipeline.md +18 -14
- package/docs/maintenance.ja.md +1 -1
- package/docs/maintenance.md +1 -1
- package/docs/ml-dom/attr.ja.md +8 -0
- package/docs/ml-dom/attr.md +8 -0
- package/docs/ml-dom/block.ja.md +33 -33
- package/docs/ml-dom/block.md +33 -33
- package/docs/ml-dom/element.ja.md +17 -17
- package/docs/ml-dom/element.md +17 -17
- package/docs/ml-dom/node.ja.md +4 -5
- package/docs/ml-dom/node.md +4 -5
- package/docs/ml-dom/others.ja.md +2 -1
- package/docs/ml-dom/others.md +5 -4
- package/docs/rule-system.ja.md +23 -6
- package/docs/rule-system.md +23 -6
- package/lib/index.d.ts +4 -3
- package/lib/index.js +1 -1
- package/lib/ml-core.d.ts +1 -1
- package/lib/ml-core.js +142 -82
- package/lib/ml-dom/helper/accname.d.ts +8 -0
- package/lib/ml-dom/helper/accname.js +71 -55
- package/lib/ml-dom/helper/create-node.js +1 -0
- package/lib/ml-dom/helper/get-indent.js +17 -29
- package/lib/ml-dom/node/attr.js +122 -73
- package/lib/ml-dom/node/block.d.ts +3 -3
- package/lib/ml-dom/node/block.js +10 -1
- package/lib/ml-dom/node/document-type.js +12 -0
- package/lib/ml-dom/node/document.d.ts +14 -3
- package/lib/ml-dom/node/document.js +75 -34
- package/lib/ml-dom/node/dom-token-list.js +17 -30
- package/lib/ml-dom/node/element-close-tag.js +1 -0
- package/lib/ml-dom/node/element.d.ts +19 -7
- package/lib/ml-dom/node/element.js +134 -55
- package/lib/ml-dom/node/node-store.js +6 -15
- package/lib/ml-dom/node/node.d.ts +3 -1
- package/lib/ml-dom/node/node.js +159 -166
- package/lib/ml-dom/node/parent-node.js +14 -30
- package/lib/ml-dom/node/rule-mapper.js +7 -20
- package/lib/ml-dom/node/text.d.ts +7 -0
- package/lib/ml-dom/node/text.js +9 -0
- package/lib/ml-dom/token/token.js +23 -39
- package/lib/ml-rule/create-rule.d.ts +8 -1
- package/lib/ml-rule/create-rule.js +0 -9
- package/lib/ml-rule/ml-rule-context.js +7 -11
- package/lib/ml-rule/ml-rule.d.ts +33 -1
- package/lib/ml-rule/ml-rule.js +65 -25
- package/lib/ruleset/index.js +6 -0
- package/lib/test/index.js +4 -1
- package/lib/types.d.ts +2 -1
- package/lib/violation-collector.js +15 -28
- package/lib/virtual-rule.d.ts +72 -0
- package/lib/virtual-rule.js +233 -0
- package/package.json +16 -13
package/lib/ml-dom/node/node.js
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
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
|
-
};
|
|
12
|
-
var _MLNode_pureChildNodesCache, _MLNode_ownerDocument, _MLNode_prevToken, _MLNode_conditionalChildNodes;
|
|
13
1
|
import { branchesToPatterns } from '@markuplint/shared';
|
|
14
2
|
import { MLToken } from '../token/token.js';
|
|
15
3
|
import { isChildNode } from './child-node.js';
|
|
@@ -26,132 +14,137 @@ import { UnexpectedCallError } from './unexpected-call-error.js';
|
|
|
26
14
|
* @template A - The underlying AST node type
|
|
27
15
|
*/
|
|
28
16
|
export class MLNode extends MLToken {
|
|
17
|
+
/**
|
|
18
|
+
* @implements DOM API: `Node`
|
|
19
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
20
|
+
*/
|
|
21
|
+
ATTRIBUTE_NODE = 2;
|
|
22
|
+
/**
|
|
23
|
+
* @implements DOM API: `Node`
|
|
24
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
25
|
+
*/
|
|
26
|
+
CDATA_SECTION_NODE = 4;
|
|
27
|
+
/**
|
|
28
|
+
* @implements DOM API: `Node`
|
|
29
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
30
|
+
*/
|
|
31
|
+
COMMENT_NODE = 8;
|
|
32
|
+
/**
|
|
33
|
+
* @implements DOM API: `Node`
|
|
34
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
35
|
+
*/
|
|
36
|
+
DOCUMENT_FRAGMENT_NODE = 11;
|
|
37
|
+
/**
|
|
38
|
+
* @implements DOM API: `Node`
|
|
39
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
40
|
+
*/
|
|
41
|
+
DOCUMENT_NODE = 9;
|
|
42
|
+
/**
|
|
43
|
+
* @implements DOM API: `Node`
|
|
44
|
+
* @see https://dom.spec.whatwg.org/#dom-node-document_position_contained_by
|
|
45
|
+
*/
|
|
46
|
+
DOCUMENT_POSITION_CONTAINED_BY = 0b1_0000;
|
|
47
|
+
/**
|
|
48
|
+
* @implements DOM API: `Node`
|
|
49
|
+
* @see https://dom.spec.whatwg.org/#dom-node-document_position_contains
|
|
50
|
+
*/
|
|
51
|
+
DOCUMENT_POSITION_CONTAINS = 0b1000;
|
|
52
|
+
/**
|
|
53
|
+
* @implements DOM API: `Node`
|
|
54
|
+
* @see https://dom.spec.whatwg.org/#dom-node-document_position_disconnected
|
|
55
|
+
*/
|
|
56
|
+
DOCUMENT_POSITION_DISCONNECTED = 0b1;
|
|
57
|
+
/**
|
|
58
|
+
* @implements DOM API: `Node`
|
|
59
|
+
* @see https://dom.spec.whatwg.org/#dom-node-document_position_following
|
|
60
|
+
*/
|
|
61
|
+
DOCUMENT_POSITION_FOLLOWING = 0b100;
|
|
62
|
+
/**
|
|
63
|
+
* @implements DOM API: `Node`
|
|
64
|
+
* @see https://dom.spec.whatwg.org/#dom-node-document_position_implementation_specific
|
|
65
|
+
*/
|
|
66
|
+
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0b10_0000;
|
|
67
|
+
/**
|
|
68
|
+
* @implements DOM API: `Node`
|
|
69
|
+
* @see https://dom.spec.whatwg.org/#dom-node-document_position_preceding
|
|
70
|
+
*/
|
|
71
|
+
DOCUMENT_POSITION_PRECEDING = 0b10;
|
|
72
|
+
/**
|
|
73
|
+
* @implements DOM API: `Node`
|
|
74
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
75
|
+
*/
|
|
76
|
+
DOCUMENT_TYPE_NODE = 10;
|
|
77
|
+
/**
|
|
78
|
+
* @implements DOM API: `Node`
|
|
79
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
80
|
+
*/
|
|
81
|
+
ELEMENT_NODE = 1;
|
|
82
|
+
/**
|
|
83
|
+
* @deprecated
|
|
84
|
+
* @implements DOM API: `Node`
|
|
85
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
86
|
+
*/
|
|
87
|
+
ENTITY_NODE = 6;
|
|
88
|
+
/**
|
|
89
|
+
* @deprecated
|
|
90
|
+
* @implements DOM API: `Node`
|
|
91
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
92
|
+
*/
|
|
93
|
+
ENTITY_REFERENCE_NODE = 5;
|
|
94
|
+
/**
|
|
95
|
+
* @implements `@markuplint/ml-core` API: `MLNode`
|
|
96
|
+
*/
|
|
97
|
+
MARKUPLINT_PREPROCESSOR_BLOCK = 101;
|
|
98
|
+
/**
|
|
99
|
+
* @deprecated
|
|
100
|
+
* @implements DOM API: `Node`
|
|
101
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
102
|
+
*/
|
|
103
|
+
NOTATION_NODE = 12;
|
|
104
|
+
/**
|
|
105
|
+
* @implements DOM API: `Node`
|
|
106
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
107
|
+
*/
|
|
108
|
+
PROCESSING_INSTRUCTION_NODE = 7;
|
|
109
|
+
/**
|
|
110
|
+
* @implements DOM API: `Node`
|
|
111
|
+
* @see https://dom.spec.whatwg.org/#interface-node
|
|
112
|
+
*/
|
|
113
|
+
TEXT_NODE = 3;
|
|
114
|
+
/**
|
|
115
|
+
* Cached `childNodes` property
|
|
116
|
+
*/
|
|
117
|
+
#pureChildNodesCache;
|
|
118
|
+
/**
|
|
119
|
+
* Returns child nodes when parent node access by `childNodes` property.
|
|
120
|
+
*/
|
|
121
|
+
isFragment;
|
|
122
|
+
/**
|
|
123
|
+
* Owner `Document`
|
|
124
|
+
*
|
|
125
|
+
* @implements DOM API: `Node`
|
|
126
|
+
* @see https://dom.spec.whatwg.org/#ref-for-dom-node-ownerdocument
|
|
127
|
+
*/
|
|
128
|
+
#ownerDocument;
|
|
129
|
+
/**
|
|
130
|
+
* Cached `prevToken` property
|
|
131
|
+
*/
|
|
132
|
+
#prevToken;
|
|
133
|
+
/**
|
|
134
|
+
* Cached `conditionalChildNodes` method
|
|
135
|
+
*/
|
|
136
|
+
#conditionalChildNodes;
|
|
137
|
+
/**
|
|
138
|
+
*
|
|
139
|
+
*/
|
|
140
|
+
rules = {};
|
|
141
|
+
_astToken;
|
|
29
142
|
constructor(astNode,
|
|
30
143
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
31
144
|
document, isFragment) {
|
|
32
145
|
super(astNode);
|
|
33
|
-
/**
|
|
34
|
-
* @implements DOM API: `Node`
|
|
35
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
36
|
-
*/
|
|
37
|
-
this.ATTRIBUTE_NODE = 2;
|
|
38
|
-
/**
|
|
39
|
-
* @implements DOM API: `Node`
|
|
40
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
41
|
-
*/
|
|
42
|
-
this.CDATA_SECTION_NODE = 4;
|
|
43
|
-
/**
|
|
44
|
-
* @implements DOM API: `Node`
|
|
45
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
46
|
-
*/
|
|
47
|
-
this.COMMENT_NODE = 8;
|
|
48
|
-
/**
|
|
49
|
-
* @implements DOM API: `Node`
|
|
50
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
51
|
-
*/
|
|
52
|
-
this.DOCUMENT_FRAGMENT_NODE = 11;
|
|
53
|
-
/**
|
|
54
|
-
* @implements DOM API: `Node`
|
|
55
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
56
|
-
*/
|
|
57
|
-
this.DOCUMENT_NODE = 9;
|
|
58
|
-
/**
|
|
59
|
-
* @implements DOM API: `Node`
|
|
60
|
-
* @see https://dom.spec.whatwg.org/#dom-node-document_position_contained_by
|
|
61
|
-
*/
|
|
62
|
-
this.DOCUMENT_POSITION_CONTAINED_BY = 16;
|
|
63
|
-
/**
|
|
64
|
-
* @implements DOM API: `Node`
|
|
65
|
-
* @see https://dom.spec.whatwg.org/#dom-node-document_position_contains
|
|
66
|
-
*/
|
|
67
|
-
this.DOCUMENT_POSITION_CONTAINS = 0b1000;
|
|
68
|
-
/**
|
|
69
|
-
* @implements DOM API: `Node`
|
|
70
|
-
* @see https://dom.spec.whatwg.org/#dom-node-document_position_disconnected
|
|
71
|
-
*/
|
|
72
|
-
this.DOCUMENT_POSITION_DISCONNECTED = 0b1;
|
|
73
|
-
/**
|
|
74
|
-
* @implements DOM API: `Node`
|
|
75
|
-
* @see https://dom.spec.whatwg.org/#dom-node-document_position_following
|
|
76
|
-
*/
|
|
77
|
-
this.DOCUMENT_POSITION_FOLLOWING = 0b100;
|
|
78
|
-
/**
|
|
79
|
-
* @implements DOM API: `Node`
|
|
80
|
-
* @see https://dom.spec.whatwg.org/#dom-node-document_position_implementation_specific
|
|
81
|
-
*/
|
|
82
|
-
this.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32;
|
|
83
|
-
/**
|
|
84
|
-
* @implements DOM API: `Node`
|
|
85
|
-
* @see https://dom.spec.whatwg.org/#dom-node-document_position_preceding
|
|
86
|
-
*/
|
|
87
|
-
this.DOCUMENT_POSITION_PRECEDING = 0b10;
|
|
88
|
-
/**
|
|
89
|
-
* @implements DOM API: `Node`
|
|
90
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
91
|
-
*/
|
|
92
|
-
this.DOCUMENT_TYPE_NODE = 10;
|
|
93
|
-
/**
|
|
94
|
-
* @implements DOM API: `Node`
|
|
95
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
96
|
-
*/
|
|
97
|
-
this.ELEMENT_NODE = 1;
|
|
98
|
-
/**
|
|
99
|
-
* @deprecated
|
|
100
|
-
* @implements DOM API: `Node`
|
|
101
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
102
|
-
*/
|
|
103
|
-
this.ENTITY_NODE = 6;
|
|
104
|
-
/**
|
|
105
|
-
* @deprecated
|
|
106
|
-
* @implements DOM API: `Node`
|
|
107
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
108
|
-
*/
|
|
109
|
-
this.ENTITY_REFERENCE_NODE = 5;
|
|
110
|
-
/**
|
|
111
|
-
* @implements `@markuplint/ml-core` API: `MLNode`
|
|
112
|
-
*/
|
|
113
|
-
this.MARKUPLINT_PREPROCESSOR_BLOCK = 101;
|
|
114
|
-
/**
|
|
115
|
-
* @deprecated
|
|
116
|
-
* @implements DOM API: `Node`
|
|
117
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
118
|
-
*/
|
|
119
|
-
this.NOTATION_NODE = 12;
|
|
120
|
-
/**
|
|
121
|
-
* @implements DOM API: `Node`
|
|
122
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
123
|
-
*/
|
|
124
|
-
this.PROCESSING_INSTRUCTION_NODE = 7;
|
|
125
|
-
/**
|
|
126
|
-
* @implements DOM API: `Node`
|
|
127
|
-
* @see https://dom.spec.whatwg.org/#interface-node
|
|
128
|
-
*/
|
|
129
|
-
this.TEXT_NODE = 3;
|
|
130
|
-
/**
|
|
131
|
-
* Cached `childNodes` property
|
|
132
|
-
*/
|
|
133
|
-
_MLNode_pureChildNodesCache.set(this, void 0);
|
|
134
|
-
/**
|
|
135
|
-
* Owner `Document`
|
|
136
|
-
*
|
|
137
|
-
* @implements DOM API: `Node`
|
|
138
|
-
* @see https://dom.spec.whatwg.org/#ref-for-dom-node-ownerdocument
|
|
139
|
-
*/
|
|
140
|
-
_MLNode_ownerDocument.set(this, void 0);
|
|
141
|
-
/**
|
|
142
|
-
* Cached `prevToken` property
|
|
143
|
-
*/
|
|
144
|
-
_MLNode_prevToken.set(this, void 0);
|
|
145
|
-
/**
|
|
146
|
-
* Cached `conditionalChildNodes` mothod
|
|
147
|
-
*/
|
|
148
|
-
_MLNode_conditionalChildNodes.set(this, void 0);
|
|
149
|
-
/**
|
|
150
|
-
*
|
|
151
|
-
*/
|
|
152
|
-
this.rules = {};
|
|
153
146
|
this._astToken = astNode;
|
|
154
|
-
|
|
147
|
+
this.#ownerDocument = document;
|
|
155
148
|
this.isFragment = !!isFragment;
|
|
156
149
|
nodeStore.setNode(astNode, this);
|
|
157
150
|
}
|
|
@@ -167,6 +160,8 @@ export class MLNode extends MLToken {
|
|
|
167
160
|
}
|
|
168
161
|
/**
|
|
169
162
|
* The list of child nodes that contains `Element`, `Text`, and `Comment`.
|
|
163
|
+
* Fragment nodes and preprocessor blocks with `each` or `end` block behavior
|
|
164
|
+
* are transparent — their child nodes are flattened into this list.
|
|
170
165
|
*
|
|
171
166
|
* @readonly
|
|
172
167
|
* @implements DOM API: `Node`
|
|
@@ -175,7 +170,9 @@ export class MLNode extends MLToken {
|
|
|
175
170
|
get childNodes() {
|
|
176
171
|
const pureChildNodes = [...this.getPureChildNodes()];
|
|
177
172
|
const childNodes = pureChildNodes.flatMap(node => {
|
|
178
|
-
if (node.isFragment
|
|
173
|
+
if (node.isFragment ||
|
|
174
|
+
(node.is(node.MARKUPLINT_PREPROCESSOR_BLOCK) &&
|
|
175
|
+
['each', 'end'].includes(node.blockBehavior?.type ?? ''))) {
|
|
179
176
|
return [...node.childNodes];
|
|
180
177
|
}
|
|
181
178
|
return [node];
|
|
@@ -217,7 +214,7 @@ export class MLNode extends MLToken {
|
|
|
217
214
|
* @implements `@markuplint/ml-core` API: `MLNode`
|
|
218
215
|
*/
|
|
219
216
|
get nextNode() {
|
|
220
|
-
const siblings = [...(this.syntacticalParentNode?.childNodes ??
|
|
217
|
+
const siblings = [...(this.syntacticalParentNode?.childNodes ?? this.#ownerDocument.nodeList)];
|
|
221
218
|
const index = siblings.findIndex(node => node.uuid === this.uuid);
|
|
222
219
|
return siblings[index + 1] ?? null;
|
|
223
220
|
}
|
|
@@ -278,7 +275,7 @@ export class MLNode extends MLToken {
|
|
|
278
275
|
* @see https://dom.spec.whatwg.org/#ref-for-dom-node-ownerdocument%E2%91%A0
|
|
279
276
|
*/
|
|
280
277
|
get ownerDocument() {
|
|
281
|
-
return
|
|
278
|
+
return this.#ownerDocument;
|
|
282
279
|
}
|
|
283
280
|
/**
|
|
284
281
|
* The owning `MLDocument` instance with proper generic types,
|
|
@@ -288,7 +285,7 @@ export class MLNode extends MLToken {
|
|
|
288
285
|
* @implements `@markuplint/ml-core` API: `MLNode`
|
|
289
286
|
*/
|
|
290
287
|
get ownerMLDocument() {
|
|
291
|
-
return
|
|
288
|
+
return this.#ownerDocument;
|
|
292
289
|
}
|
|
293
290
|
/**
|
|
294
291
|
* The parent element.
|
|
@@ -376,7 +373,7 @@ export class MLNode extends MLToken {
|
|
|
376
373
|
* @implements `@markuplint/ml-core` API: `MLNode`
|
|
377
374
|
*/
|
|
378
375
|
get prevNode() {
|
|
379
|
-
const siblings = [...(this.syntacticalParentNode?.childNodes ??
|
|
376
|
+
const siblings = [...(this.syntacticalParentNode?.childNodes ?? this.#ownerDocument.nodeList)];
|
|
380
377
|
const index = siblings.findIndex(node => node.uuid === this.uuid);
|
|
381
378
|
return siblings[index - 1] ?? null;
|
|
382
379
|
}
|
|
@@ -384,8 +381,8 @@ export class MLNode extends MLToken {
|
|
|
384
381
|
* @implements `@markuplint/ml-core` API: `MLNode`
|
|
385
382
|
*/
|
|
386
383
|
get prevToken() {
|
|
387
|
-
if (
|
|
388
|
-
return
|
|
384
|
+
if (this.#prevToken !== undefined) {
|
|
385
|
+
return this.#prevToken;
|
|
389
386
|
}
|
|
390
387
|
let index = -1;
|
|
391
388
|
for (let i = 0; i < this.ownerMLDocument.nodeList.length; i++) {
|
|
@@ -402,11 +399,11 @@ export class MLNode extends MLToken {
|
|
|
402
399
|
}
|
|
403
400
|
}
|
|
404
401
|
if (index === -1) {
|
|
405
|
-
|
|
406
|
-
return
|
|
402
|
+
this.#prevToken = null;
|
|
403
|
+
return this.#prevToken;
|
|
407
404
|
}
|
|
408
|
-
|
|
409
|
-
return
|
|
405
|
+
this.#prevToken = this.ownerMLDocument.nodeList[index - 1] ?? null;
|
|
406
|
+
return this.#prevToken ?? null;
|
|
410
407
|
}
|
|
411
408
|
/**
|
|
412
409
|
* The previous sibling of an object is its first preceding sibling or null if it has no preceding sibling.
|
|
@@ -548,7 +545,7 @@ export class MLNode extends MLToken {
|
|
|
548
545
|
/**
|
|
549
546
|
* Returns an array of NodeLists representing the conditional child nodes of the current node.
|
|
550
547
|
* Conditional child nodes are nodes that are nested within
|
|
551
|
-
* **preprocessor blocks** such as `if
|
|
548
|
+
* **preprocessor blocks** such as `if` or `switch`.
|
|
552
549
|
* Each NodeList represents a branch of conditional child nodes.
|
|
553
550
|
*
|
|
554
551
|
* Note: NodeList doesn't include whitespace nodes.
|
|
@@ -559,8 +556,8 @@ export class MLNode extends MLToken {
|
|
|
559
556
|
* @implements `@markuplint/ml-core` API: `MLNode`
|
|
560
557
|
*/
|
|
561
558
|
conditionalChildNodes() {
|
|
562
|
-
if (
|
|
563
|
-
return
|
|
559
|
+
if (this.#conditionalChildNodes != null) {
|
|
560
|
+
return this.#conditionalChildNodes;
|
|
564
561
|
}
|
|
565
562
|
const branches = [];
|
|
566
563
|
let mode = null;
|
|
@@ -568,22 +565,19 @@ export class MLNode extends MLToken {
|
|
|
568
565
|
let subBranches = [];
|
|
569
566
|
for (const child of this.childNodes) {
|
|
570
567
|
if (child.is(child.MARKUPLINT_PREPROCESSOR_BLOCK)) {
|
|
571
|
-
switch (child.
|
|
568
|
+
switch (child.blockBehavior?.type) {
|
|
572
569
|
case 'if':
|
|
573
570
|
case 'if:elseif': {
|
|
574
571
|
mode = 'if';
|
|
575
572
|
break;
|
|
576
573
|
}
|
|
577
|
-
case 'each': {
|
|
578
|
-
mode = 'each';
|
|
579
|
-
break;
|
|
580
|
-
}
|
|
581
574
|
case 'switch:case': {
|
|
582
575
|
mode = 'switch';
|
|
583
576
|
break;
|
|
584
577
|
}
|
|
585
578
|
/* No default mode */
|
|
586
579
|
case 'if:else':
|
|
580
|
+
case 'each':
|
|
587
581
|
case 'each:empty':
|
|
588
582
|
case 'switch:default':
|
|
589
583
|
case 'await':
|
|
@@ -601,7 +595,7 @@ export class MLNode extends MLToken {
|
|
|
601
595
|
continue;
|
|
602
596
|
}
|
|
603
597
|
if (openConditional) {
|
|
604
|
-
if (['if', '
|
|
598
|
+
if (['if', 'switch'].includes(mode)) {
|
|
605
599
|
subBranches.push(null);
|
|
606
600
|
}
|
|
607
601
|
branches.push(subBranches);
|
|
@@ -615,13 +609,13 @@ export class MLNode extends MLToken {
|
|
|
615
609
|
branches.push(child);
|
|
616
610
|
}
|
|
617
611
|
if (subBranches.length > 0) {
|
|
618
|
-
if (['if', '
|
|
612
|
+
if (['if', 'switch'].includes(mode)) {
|
|
619
613
|
subBranches.push(null);
|
|
620
614
|
}
|
|
621
615
|
branches.push(subBranches);
|
|
622
616
|
}
|
|
623
617
|
const cache = branchesToPatterns(branches).map(array => toNodeList(array));
|
|
624
|
-
|
|
618
|
+
this.#conditionalChildNodes = cache;
|
|
625
619
|
return cache;
|
|
626
620
|
}
|
|
627
621
|
/**
|
|
@@ -685,8 +679,8 @@ export class MLNode extends MLToken {
|
|
|
685
679
|
* @implements DOM API: `MLNode`
|
|
686
680
|
*/
|
|
687
681
|
getPureChildNodes() {
|
|
688
|
-
if (
|
|
689
|
-
return
|
|
682
|
+
if (this.#pureChildNodesCache != null) {
|
|
683
|
+
return this.#pureChildNodesCache;
|
|
690
684
|
}
|
|
691
685
|
if (this.is(this.DOCUMENT_NODE)) {
|
|
692
686
|
const childNodes = [];
|
|
@@ -696,8 +690,8 @@ export class MLNode extends MLToken {
|
|
|
696
690
|
}
|
|
697
691
|
}
|
|
698
692
|
// Cache
|
|
699
|
-
|
|
700
|
-
return
|
|
693
|
+
this.#pureChildNodesCache = toNodeList(childNodes);
|
|
694
|
+
return this.#pureChildNodesCache;
|
|
701
695
|
}
|
|
702
696
|
if (this.is(this.DOCUMENT_FRAGMENT_NODE) ||
|
|
703
697
|
this.is(this.ELEMENT_NODE) ||
|
|
@@ -714,12 +708,12 @@ export class MLNode extends MLToken {
|
|
|
714
708
|
.map(node => nodeStore.getNode(node))
|
|
715
709
|
.filter(node => isChildNode(node));
|
|
716
710
|
// Cache
|
|
717
|
-
|
|
718
|
-
return
|
|
711
|
+
this.#pureChildNodesCache = toNodeList(childNodes);
|
|
712
|
+
return this.#pureChildNodesCache;
|
|
719
713
|
}
|
|
720
714
|
// Cache
|
|
721
|
-
|
|
722
|
-
return
|
|
715
|
+
this.#pureChildNodesCache = toNodeList([]);
|
|
716
|
+
return this.#pureChildNodesCache;
|
|
723
717
|
}
|
|
724
718
|
/**
|
|
725
719
|
* **IT THROWS AN ERROR WHEN CALLING THIS.**
|
|
@@ -735,7 +729,7 @@ export class MLNode extends MLToken {
|
|
|
735
729
|
throw new UnexpectedCallError('Not supported options');
|
|
736
730
|
}
|
|
737
731
|
// The original DOM API returns a document fragment if the element is a fragment.
|
|
738
|
-
return
|
|
732
|
+
return this.#ownerDocument;
|
|
739
733
|
}
|
|
740
734
|
/**
|
|
741
735
|
* **IT THROWS AN ERROR WHEN CALLING THIS.**
|
|
@@ -875,7 +869,6 @@ export class MLNode extends MLToken {
|
|
|
875
869
|
resetChildren(
|
|
876
870
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
877
871
|
childNodes) {
|
|
878
|
-
|
|
872
|
+
this.#pureChildNodesCache = childNodes ?? this.#pureChildNodesCache;
|
|
879
873
|
}
|
|
880
874
|
}
|
|
881
|
-
_MLNode_pureChildNodesCache = new WeakMap(), _MLNode_ownerDocument = new WeakMap(), _MLNode_prevToken = new WeakMap(), _MLNode_conditionalChildNodes = new WeakMap();
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
-
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");
|
|
4
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
-
};
|
|
6
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
-
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");
|
|
10
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
-
};
|
|
12
|
-
var _MLParentNode_children, _MLParentNode_selectedElements;
|
|
13
1
|
import { syncWalk } from '../helper/walkers.js';
|
|
14
2
|
import { getChildren } from '../manipulations/get-children.js';
|
|
15
3
|
import { toNodeList } from './node-list.js';
|
|
@@ -20,17 +8,14 @@ import { UnexpectedCallError } from './unexpected-call-error.js';
|
|
|
20
8
|
* @see https://dom.spec.whatwg.org/#interface-parentnode
|
|
21
9
|
*/
|
|
22
10
|
export class MLParentNode extends MLNode {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
*/
|
|
32
|
-
_MLParentNode_selectedElements.set(this, new Map());
|
|
33
|
-
}
|
|
11
|
+
/**
|
|
12
|
+
* Cached `children`
|
|
13
|
+
*/
|
|
14
|
+
#children = null;
|
|
15
|
+
/**
|
|
16
|
+
* Cached elements that created from `querySelectorAll`
|
|
17
|
+
*/
|
|
18
|
+
#selectedElements = new Map();
|
|
34
19
|
/**
|
|
35
20
|
* @implements DOM API: `Element`, `Document`, `DocumentFragment`
|
|
36
21
|
* @see https://dom.spec.whatwg.org/#dom-parentnode-childelementcount
|
|
@@ -43,12 +28,12 @@ export class MLParentNode extends MLNode {
|
|
|
43
28
|
* @see https://dom.spec.whatwg.org/#ref-for-dom-parentnode-children%E2%91%A0
|
|
44
29
|
*/
|
|
45
30
|
get children() {
|
|
46
|
-
if (
|
|
47
|
-
return
|
|
31
|
+
if (this.#children) {
|
|
32
|
+
return this.#children;
|
|
48
33
|
}
|
|
49
34
|
const children = getChildren(this);
|
|
50
|
-
|
|
51
|
-
return
|
|
35
|
+
this.#children = children;
|
|
36
|
+
return this.#children;
|
|
52
37
|
}
|
|
53
38
|
/**
|
|
54
39
|
* @implements DOM API: `Element`, `Document`, `DocumentFragment`
|
|
@@ -101,7 +86,7 @@ export class MLParentNode extends MLNode {
|
|
|
101
86
|
* @see https://dom.spec.whatwg.org/#ref-for-dom-parentnode-queryselectorall%E2%91%A0
|
|
102
87
|
*/
|
|
103
88
|
querySelectorAll(selectors) {
|
|
104
|
-
const selected =
|
|
89
|
+
const selected = this.#selectedElements.get(selectors);
|
|
105
90
|
if (selected) {
|
|
106
91
|
return selected;
|
|
107
92
|
}
|
|
@@ -110,7 +95,7 @@ export class MLParentNode extends MLNode {
|
|
|
110
95
|
return node;
|
|
111
96
|
}
|
|
112
97
|
}));
|
|
113
|
-
|
|
98
|
+
this.#selectedElements.set(selectors, elements);
|
|
114
99
|
return elements;
|
|
115
100
|
}
|
|
116
101
|
/**
|
|
@@ -140,4 +125,3 @@ export class MLParentNode extends MLNode {
|
|
|
140
125
|
return Object.freeze(nodeList);
|
|
141
126
|
}
|
|
142
127
|
}
|
|
143
|
-
_MLParentNode_children = new WeakMap(), _MLParentNode_selectedElements = new WeakMap();
|
|
@@ -1,32 +1,20 @@
|
|
|
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
|
-
};
|
|
12
|
-
var _RuleMapper_nodeList, _RuleMapper_ruleMap;
|
|
13
1
|
import { compareSpecificity } from '@markuplint/selector';
|
|
14
2
|
import { log as coreLog } from '../../debug.js';
|
|
15
3
|
const ruleMapperLog = coreLog.extend('rule-mapper');
|
|
16
4
|
const ruleMapperNodeLog = ruleMapperLog.extend('node');
|
|
17
5
|
const ruleMapperNodeRuleLog = ruleMapperNodeLog.extend('rule');
|
|
18
6
|
export class RuleMapper {
|
|
7
|
+
#nodeList;
|
|
8
|
+
#ruleMap = new Map();
|
|
19
9
|
constructor(
|
|
20
10
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
21
11
|
document) {
|
|
22
|
-
|
|
23
|
-
_RuleMapper_ruleMap.set(this, new Map());
|
|
24
|
-
__classPrivateFieldSet(this, _RuleMapper_nodeList, Object.freeze([document, ...document.nodeList]), "f");
|
|
12
|
+
this.#nodeList = Object.freeze([document, ...document.nodeList]);
|
|
25
13
|
}
|
|
26
14
|
apply() {
|
|
27
15
|
ruleMapperLog('ruleTree:');
|
|
28
|
-
for (const node of
|
|
29
|
-
const rules =
|
|
16
|
+
for (const node of this.#nodeList) {
|
|
17
|
+
const rules = this.#ruleMap.get(node.uuid);
|
|
30
18
|
if (!rules) {
|
|
31
19
|
continue;
|
|
32
20
|
}
|
|
@@ -44,7 +32,7 @@ export class RuleMapper {
|
|
|
44
32
|
set(
|
|
45
33
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
46
34
|
node, ruleName, rule) {
|
|
47
|
-
const rules =
|
|
35
|
+
const rules = this.#ruleMap.get(node.uuid) ?? {};
|
|
48
36
|
const currentRule = rules[ruleName];
|
|
49
37
|
if (currentRule) {
|
|
50
38
|
const order = compareSpecificity(currentRule.specificity, rule.specificity);
|
|
@@ -55,8 +43,7 @@ export class RuleMapper {
|
|
|
55
43
|
ruleMapperLog('Unset %o from %s', currentRule, node);
|
|
56
44
|
}
|
|
57
45
|
rules[ruleName] = rule;
|
|
58
|
-
|
|
46
|
+
this.#ruleMap.set(node.uuid, rules);
|
|
59
47
|
ruleMapperLog('Set to %s from %s (%o): %O', node.nodeName, rule.from, rule.specificity, rule.rule);
|
|
60
48
|
}
|
|
61
49
|
}
|
|
62
|
-
_RuleMapper_nodeList = new WeakMap(), _RuleMapper_ruleMap = new WeakMap();
|
|
@@ -18,6 +18,13 @@ export declare class MLText<T extends RuleConfigValue, O extends PlainData = und
|
|
|
18
18
|
* @implements DOM API: `Text`
|
|
19
19
|
*/
|
|
20
20
|
get assignedSlot(): HTMLSlotElement;
|
|
21
|
+
/**
|
|
22
|
+
* Returns `true` if this text node originated from an invalid (bogus) AST
|
|
23
|
+
* node, such as an orphaned end tag.
|
|
24
|
+
*
|
|
25
|
+
* @implements `@markuplint/ml-core` API: `MLText`
|
|
26
|
+
*/
|
|
27
|
+
get isBogus(): boolean;
|
|
21
28
|
/**
|
|
22
29
|
* Returns a string appropriate for the type of node as `Text`
|
|
23
30
|
*
|
package/lib/ml-dom/node/text.js
CHANGED
|
@@ -24,6 +24,15 @@ export class MLText extends MLCharacterData {
|
|
|
24
24
|
get assignedSlot() {
|
|
25
25
|
throw new UnexpectedCallError('Not supported "assignedSlot" property');
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Returns `true` if this text node originated from an invalid (bogus) AST
|
|
29
|
+
* node, such as an orphaned end tag.
|
|
30
|
+
*
|
|
31
|
+
* @implements `@markuplint/ml-core` API: `MLText`
|
|
32
|
+
*/
|
|
33
|
+
get isBogus() {
|
|
34
|
+
return this._astToken.isBogus ?? false;
|
|
35
|
+
}
|
|
27
36
|
/**
|
|
28
37
|
* Returns a string appropriate for the type of node as `Text`
|
|
29
38
|
*
|