@markuplint/ml-core 4.13.2 → 5.0.0-alpha.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/ARCHITECTURE.ja.md +524 -0
- package/ARCHITECTURE.md +524 -0
- package/CHANGELOG.md +52 -2
- package/README.md +5 -0
- package/SKILL.md +61 -0
- package/docs/linting-pipeline.ja.md +307 -0
- package/docs/linting-pipeline.md +307 -0
- package/docs/maintenance.ja.md +210 -0
- package/docs/maintenance.md +210 -0
- package/docs/ml-dom/attr.ja.md +103 -0
- package/docs/ml-dom/attr.md +103 -0
- package/docs/ml-dom/block.ja.md +272 -0
- package/docs/ml-dom/block.md +272 -0
- package/docs/ml-dom/document.ja.md +141 -0
- package/docs/ml-dom/document.md +141 -0
- package/docs/ml-dom/element.ja.md +176 -0
- package/docs/ml-dom/element.md +176 -0
- package/docs/ml-dom/helpers.ja.md +203 -0
- package/docs/ml-dom/helpers.md +203 -0
- package/docs/ml-dom/node.ja.md +199 -0
- package/docs/ml-dom/node.md +199 -0
- package/docs/ml-dom/others.ja.md +120 -0
- package/docs/ml-dom/others.md +120 -0
- package/docs/ml-dom/overview.ja.md +102 -0
- package/docs/ml-dom/overview.md +102 -0
- package/docs/ml-dom/pretender.ja.md +269 -0
- package/docs/ml-dom/pretender.md +269 -0
- package/docs/ml-dom/rule-mapping.ja.md +371 -0
- package/docs/ml-dom/rule-mapping.md +371 -0
- package/docs/ml-dom.ja.md +18 -0
- package/docs/ml-dom.md +18 -0
- package/docs/rule-system.ja.md +287 -0
- package/docs/rule-system.md +287 -0
- package/lib/convert-ruleset.d.ts +7 -0
- package/lib/convert-ruleset.js +7 -0
- package/lib/debug.d.ts +4 -0
- package/lib/debug.js +4 -0
- package/lib/index.d.ts +4 -3
- package/lib/index.js +1 -1
- package/lib/ml-core.d.ts +37 -1
- package/lib/ml-core.js +171 -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.d.ts +4 -1
- package/lib/ml-dom/helper/get-indent.js +21 -30
- package/lib/ml-dom/node/attr.d.ts +65 -4
- package/lib/ml-dom/node/attr.js +151 -53
- package/lib/ml-dom/node/block.d.ts +23 -2
- package/lib/ml-dom/node/block.js +24 -1
- package/lib/ml-dom/node/child-node.d.ts +9 -0
- package/lib/ml-dom/node/child-node.js +9 -0
- package/lib/ml-dom/node/comment.d.ts +7 -0
- package/lib/ml-dom/node/comment.js +7 -0
- package/lib/ml-dom/node/document-fragment.d.ts +8 -0
- package/lib/ml-dom/node/document-fragment.js +8 -0
- package/lib/ml-dom/node/document-type.d.ts +22 -0
- package/lib/ml-dom/node/document-type.js +25 -0
- package/lib/ml-dom/node/document.d.ts +88 -7
- package/lib/ml-dom/node/document.js +128 -32
- 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 +151 -5
- package/lib/ml-dom/node/element.js +242 -50
- package/lib/ml-dom/node/node-store.js +6 -15
- package/lib/ml-dom/node/node.d.ts +19 -1
- package/lib/ml-dom/node/node.js +175 -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 +19 -0
- package/lib/ml-dom/node/text.js +21 -0
- package/lib/ml-dom/node/types.d.ts +68 -0
- package/lib/ml-dom/token/token.d.ts +42 -0
- package/lib/ml-dom/token/token.js +59 -39
- package/lib/ml-rule/create-rule.d.ts +17 -1
- package/lib/ml-rule/ml-rule-context.js +7 -11
- package/lib/ml-rule/ml-rule.d.ts +66 -1
- package/lib/ml-rule/ml-rule.js +95 -25
- package/lib/ml-rule/types.d.ts +41 -0
- package/lib/plugin/plugin.d.ts +8 -0
- package/lib/plugin/plugin.js +8 -0
- package/lib/plugin/types.d.ts +21 -0
- package/lib/ruleset/index.d.ts +10 -0
- package/lib/ruleset/index.js +13 -0
- package/lib/test/index.d.ts +42 -1
- package/lib/test/index.js +39 -2
- package/lib/types.d.ts +10 -1
- package/lib/violation-collector.d.ts +33 -0
- package/lib/violation-collector.js +48 -28
- package/lib/virtual-rule.d.ts +72 -0
- package/lib/virtual-rule.js +233 -0
- package/package.json +16 -13
|
@@ -1,19 +1,10 @@
|
|
|
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 _MLDOMIndentation_fixed, _MLDOMIndentation_node, _MLDOMIndentation_parent;
|
|
13
1
|
/**
|
|
2
|
+
* Computes the indentation preceding the given node by analyzing
|
|
3
|
+
* the whitespace in adjacent text nodes.
|
|
14
4
|
*
|
|
15
5
|
* @deprecated
|
|
16
|
-
* @param node
|
|
6
|
+
* @param node - The node whose indentation to determine
|
|
7
|
+
* @returns An indentation object describing the whitespace, or null if no indentation is found
|
|
17
8
|
*/
|
|
18
9
|
export function getIndent(
|
|
19
10
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
@@ -59,52 +50,52 @@ node) {
|
|
|
59
50
|
return null;
|
|
60
51
|
}
|
|
61
52
|
class MLDOMIndentation {
|
|
53
|
+
#fixed;
|
|
54
|
+
line;
|
|
55
|
+
#node;
|
|
56
|
+
#parent;
|
|
62
57
|
constructor(
|
|
63
58
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
64
59
|
originTextNode, raw, line,
|
|
65
60
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
66
61
|
parentNode) {
|
|
67
|
-
_MLDOMIndentation_fixed.set(this, void 0);
|
|
68
|
-
_MLDOMIndentation_node.set(this, void 0);
|
|
69
|
-
_MLDOMIndentation_parent.set(this, void 0);
|
|
70
62
|
this.line = line;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
this.#node = originTextNode;
|
|
64
|
+
this.#parent = parentNode;
|
|
65
|
+
this.#fixed = raw;
|
|
74
66
|
}
|
|
75
67
|
get raw() {
|
|
76
|
-
if (!
|
|
68
|
+
if (!this.#parent.is(this.#parent.TEXT_NODE) && this.line !== this.#node.endLine) {
|
|
77
69
|
return '';
|
|
78
70
|
}
|
|
79
|
-
return
|
|
71
|
+
return this.#fixed;
|
|
80
72
|
}
|
|
81
73
|
get type() {
|
|
82
|
-
if (!
|
|
74
|
+
if (!this.#parent.is(this.#parent.TEXT_NODE) && this.line !== this.#node.endLine) {
|
|
83
75
|
return 'none';
|
|
84
76
|
}
|
|
85
|
-
const raw =
|
|
77
|
+
const raw = this.#fixed;
|
|
86
78
|
return raw === '' ? 'none' : /^\t+$/.test(raw) ? 'tab' : /^[^\t]+$/.test(raw) ? 'space' : 'mixed';
|
|
87
79
|
}
|
|
88
80
|
get width() {
|
|
89
|
-
if (!
|
|
81
|
+
if (!this.#parent.is(this.#parent.TEXT_NODE) && this.line !== this.#node.endLine) {
|
|
90
82
|
return 0;
|
|
91
83
|
}
|
|
92
|
-
return
|
|
84
|
+
return this.#fixed.length;
|
|
93
85
|
}
|
|
94
86
|
fix(raw) {
|
|
95
|
-
const current =
|
|
96
|
-
|
|
97
|
-
const node =
|
|
87
|
+
const current = this.#fixed;
|
|
88
|
+
this.#fixed = raw;
|
|
89
|
+
const node = this.#node;
|
|
98
90
|
const line = node.startLine;
|
|
99
91
|
const lines = node.raw.split(/\r?\n/);
|
|
100
92
|
const index = this.line - line;
|
|
101
93
|
if (lines[index] != null) {
|
|
102
|
-
lines[index] = lines[index].replace(current,
|
|
94
|
+
lines[index] = lines[index].replace(current, this.#fixed);
|
|
103
95
|
}
|
|
104
96
|
node.fix(lines.join('\n'));
|
|
105
97
|
}
|
|
106
98
|
}
|
|
107
|
-
_MLDOMIndentation_fixed = new WeakMap(), _MLDOMIndentation_node = new WeakMap(), _MLDOMIndentation_parent = new WeakMap();
|
|
108
99
|
function isFirstToken(
|
|
109
100
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
110
101
|
node) {
|
|
@@ -5,24 +5,69 @@ import type { PlainData, RuleConfigValue } from '@markuplint/ml-config';
|
|
|
5
5
|
import { MLToken } from '../token/token.js';
|
|
6
6
|
import { MLDomTokenList } from './dom-token-list.js';
|
|
7
7
|
import { MLNode } from './node.js';
|
|
8
|
+
/**
|
|
9
|
+
* Represents a DOM Attr (attribute) node wrapper in the markuplint DOM tree.
|
|
10
|
+
* Wraps an AST attribute token and provides access to the attribute's name, value,
|
|
11
|
+
* tokens (name, equal sign, quotes, value), and metadata such as whether
|
|
12
|
+
* the attribute is a directive or has a dynamic value.
|
|
13
|
+
*
|
|
14
|
+
* @template T - The rule configuration value type
|
|
15
|
+
* @template O - The rule options type
|
|
16
|
+
*/
|
|
8
17
|
export declare class MLAttr<T extends RuleConfigValue, O extends PlainData = undefined> extends MLNode<T, O, MLASTAttr> implements Attr {
|
|
9
18
|
#private;
|
|
19
|
+
/**
|
|
20
|
+
* A candidate attribute name suggested by the parser, if available.
|
|
21
|
+
*/
|
|
10
22
|
readonly candidate?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The end quote token of the attribute value, or null if the attribute has no value or quotes.
|
|
25
|
+
*/
|
|
11
26
|
readonly endQuote: MLToken | null;
|
|
27
|
+
/**
|
|
28
|
+
* The equal sign token between the attribute name and value, or null if absent.
|
|
29
|
+
*/
|
|
12
30
|
readonly equal: MLToken | null;
|
|
31
|
+
/**
|
|
32
|
+
* Whether this attribute is a directive (e.g., framework-specific attributes like `v-if` or `@click`).
|
|
33
|
+
*/
|
|
13
34
|
readonly isDirective?: true;
|
|
35
|
+
/**
|
|
36
|
+
* Whether this attribute can be duplicated on the same element.
|
|
37
|
+
*/
|
|
14
38
|
readonly isDuplicatable: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Whether this attribute has a dynamic value (e.g., a template expression rather than a static string).
|
|
41
|
+
*/
|
|
15
42
|
readonly isDynamicValue?: true;
|
|
43
|
+
/**
|
|
44
|
+
* The token representing the attribute name, or null for spread attributes.
|
|
45
|
+
*/
|
|
16
46
|
readonly nameNode: MLToken | null;
|
|
17
47
|
/**
|
|
18
48
|
* @implements DOM API: `Attr`
|
|
19
49
|
* @see https://dom.spec.whatwg.org/#ref-for-dom-node-previoussibling%E2%91%A0
|
|
20
50
|
*/
|
|
21
51
|
readonly ownerElement: MLElement<T, O>;
|
|
52
|
+
/**
|
|
53
|
+
* The whitespace token after the equal sign, or null if absent.
|
|
54
|
+
*/
|
|
22
55
|
readonly spacesAfterEqual: MLToken | null;
|
|
56
|
+
/**
|
|
57
|
+
* The whitespace token before the equal sign, or null if absent.
|
|
58
|
+
*/
|
|
23
59
|
readonly spacesBeforeEqual: MLToken | null;
|
|
60
|
+
/**
|
|
61
|
+
* The whitespace token before the attribute name, or null if absent.
|
|
62
|
+
*/
|
|
24
63
|
readonly spacesBeforeName: MLToken | null;
|
|
64
|
+
/**
|
|
65
|
+
* The start quote token of the attribute value, or null if the attribute has no value or quotes.
|
|
66
|
+
*/
|
|
25
67
|
readonly startQuote: MLToken | null;
|
|
68
|
+
/**
|
|
69
|
+
* The token representing the attribute value, or null if the attribute has no value.
|
|
70
|
+
*/
|
|
26
71
|
readonly valueNode: MLToken | null;
|
|
27
72
|
/**
|
|
28
73
|
* Returns the "string" if HTML syntax. Otherwise, returns a type in its syntax.
|
|
@@ -31,25 +76,30 @@ export declare class MLAttr<T extends RuleConfigValue, O extends PlainData = und
|
|
|
31
76
|
* @implements `@markuplint/ml-core` API: `MLAttr`
|
|
32
77
|
*/
|
|
33
78
|
readonly valueType: 'string' | 'number' | 'boolean' | 'code';
|
|
79
|
+
/**
|
|
80
|
+
* Creates a new MLAttr instance from an AST attribute token.
|
|
81
|
+
*
|
|
82
|
+
* @param astToken - The AST attribute token to wrap
|
|
83
|
+
* @param ownElement - The element that owns this attribute
|
|
84
|
+
*/
|
|
34
85
|
constructor(astToken: MLASTAttr, ownElement: MLElement<T, O>);
|
|
35
86
|
/**
|
|
36
|
-
*
|
|
87
|
+
* Returns the local name portion of the attribute (without namespace prefix).
|
|
37
88
|
*
|
|
38
|
-
* @unsupported
|
|
39
89
|
* @implements DOM API: `Attr`
|
|
40
90
|
* @see https://dom.spec.whatwg.org/#ref-for-dom-attr-localname
|
|
41
91
|
*/
|
|
42
92
|
get localName(): string;
|
|
43
93
|
/**
|
|
94
|
+
* Returns the qualified attribute name (the potential name resolved by the parser).
|
|
44
95
|
*
|
|
45
96
|
* @implements DOM API: `Attr`
|
|
46
97
|
* @see https://dom.spec.whatwg.org/#dom-attr-name
|
|
47
98
|
*/
|
|
48
99
|
get name(): string;
|
|
49
100
|
/**
|
|
50
|
-
*
|
|
101
|
+
* Returns the namespace URI of this attribute, resolved from the attribute name.
|
|
51
102
|
*
|
|
52
|
-
* @unsupported
|
|
53
103
|
* @implements DOM API: `Attr`
|
|
54
104
|
* @see https://dom.spec.whatwg.org/#ref-for-dom-attr-namespaceuri
|
|
55
105
|
*/
|
|
@@ -64,6 +114,12 @@ export declare class MLAttr<T extends RuleConfigValue, O extends PlainData = und
|
|
|
64
114
|
* Returns a number appropriate for the type of `Attr`
|
|
65
115
|
*/
|
|
66
116
|
get nodeType(): AttributeNodeType;
|
|
117
|
+
/**
|
|
118
|
+
* Returns the attribute value, equivalent to the `value` property.
|
|
119
|
+
*
|
|
120
|
+
* @implements DOM API: `Attr`
|
|
121
|
+
* @see https://dom.spec.whatwg.org/#dom-node-nodevalue
|
|
122
|
+
*/
|
|
67
123
|
get nodeValue(): string;
|
|
68
124
|
/**
|
|
69
125
|
* **IT THROWS AN ERROR WHEN CALLING THIS.**
|
|
@@ -106,7 +162,12 @@ export declare class MLAttr<T extends RuleConfigValue, O extends PlainData = und
|
|
|
106
162
|
*/
|
|
107
163
|
fix(raw: string): void;
|
|
108
164
|
/**
|
|
165
|
+
* Returns a normalized string representation of the attribute,
|
|
166
|
+
* stripping extraneous whitespace around the name, equal sign, and value tokens.
|
|
167
|
+
* Falls back to the raw string if any token is missing.
|
|
168
|
+
*
|
|
109
169
|
* @implements `@markuplint/ml-core` API: `MLAttr`
|
|
170
|
+
* @returns The normalized attribute string
|
|
110
171
|
*/
|
|
111
172
|
toNormalizeString(): string;
|
|
112
173
|
/**
|
package/lib/ml-dom/node/attr.js
CHANGED
|
@@ -1,51 +1,100 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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 _MLAttr_localName, _MLAttr_namespaceURI, _MLAttr_potentialName, _MLAttr_potentialValue;
|
|
13
|
-
import { resolveNamespace } from '@markuplint/ml-spec';
|
|
1
|
+
import { resolveNamespace, compileDirectivePatterns, resolveDirective } from '@markuplint/ml-spec';
|
|
2
|
+
import { searchIDLAttribute } from '@markuplint/parser-utils';
|
|
14
3
|
import { MLToken } from '../token/token.js';
|
|
15
4
|
import { MLDomTokenList } from './dom-token-list.js';
|
|
16
5
|
import { MLNode } from './node.js';
|
|
17
6
|
import { UnexpectedCallError } from './unexpected-call-error.js';
|
|
7
|
+
/**
|
|
8
|
+
* Represents a DOM Attr (attribute) node wrapper in the markuplint DOM tree.
|
|
9
|
+
* Wraps an AST attribute token and provides access to the attribute's name, value,
|
|
10
|
+
* tokens (name, equal sign, quotes, value), and metadata such as whether
|
|
11
|
+
* the attribute is a directive or has a dynamic value.
|
|
12
|
+
*
|
|
13
|
+
* @template T - The rule configuration value type
|
|
14
|
+
* @template O - The rule options type
|
|
15
|
+
*/
|
|
18
16
|
export class MLAttr extends MLNode {
|
|
17
|
+
/**
|
|
18
|
+
* A candidate attribute name suggested by the parser, if available.
|
|
19
|
+
*/
|
|
20
|
+
candidate;
|
|
21
|
+
/**
|
|
22
|
+
* The end quote token of the attribute value, or null if the attribute has no value or quotes.
|
|
23
|
+
*/
|
|
24
|
+
endQuote = null;
|
|
25
|
+
/**
|
|
26
|
+
* The equal sign token between the attribute name and value, or null if absent.
|
|
27
|
+
*/
|
|
28
|
+
equal = null;
|
|
29
|
+
/**
|
|
30
|
+
* Whether this attribute is a directive (e.g., framework-specific attributes like `v-if` or `@click`).
|
|
31
|
+
*/
|
|
32
|
+
isDirective;
|
|
33
|
+
/**
|
|
34
|
+
* Whether this attribute can be duplicated on the same element.
|
|
35
|
+
*/
|
|
36
|
+
isDuplicatable;
|
|
37
|
+
/**
|
|
38
|
+
* Whether this attribute has a dynamic value (e.g., a template expression rather than a static string).
|
|
39
|
+
*/
|
|
40
|
+
isDynamicValue;
|
|
41
|
+
#localName;
|
|
42
|
+
/**
|
|
43
|
+
* The token representing the attribute name, or null for spread attributes.
|
|
44
|
+
*/
|
|
45
|
+
nameNode = null;
|
|
46
|
+
#namespaceURI;
|
|
47
|
+
/**
|
|
48
|
+
* @implements DOM API: `Attr`
|
|
49
|
+
* @see https://dom.spec.whatwg.org/#ref-for-dom-node-previoussibling%E2%91%A0
|
|
50
|
+
*/
|
|
51
|
+
ownerElement;
|
|
52
|
+
#potentialName;
|
|
53
|
+
#potentialValue;
|
|
54
|
+
/**
|
|
55
|
+
* The whitespace token after the equal sign, or null if absent.
|
|
56
|
+
*/
|
|
57
|
+
spacesAfterEqual = null;
|
|
58
|
+
/**
|
|
59
|
+
* The whitespace token before the equal sign, or null if absent.
|
|
60
|
+
*/
|
|
61
|
+
spacesBeforeEqual = null;
|
|
62
|
+
/**
|
|
63
|
+
* The whitespace token before the attribute name, or null if absent.
|
|
64
|
+
*/
|
|
65
|
+
spacesBeforeName = null;
|
|
66
|
+
/**
|
|
67
|
+
* The start quote token of the attribute value, or null if the attribute has no value or quotes.
|
|
68
|
+
*/
|
|
69
|
+
startQuote = null;
|
|
70
|
+
/**
|
|
71
|
+
* The token representing the attribute value, or null if the attribute has no value.
|
|
72
|
+
*/
|
|
73
|
+
valueNode = null;
|
|
74
|
+
/**
|
|
75
|
+
* Returns the "string" if HTML syntax. Otherwise, returns a type in its syntax.
|
|
76
|
+
*
|
|
77
|
+
* @default "string"
|
|
78
|
+
* @implements `@markuplint/ml-core` API: `MLAttr`
|
|
79
|
+
*/
|
|
80
|
+
valueType = 'string';
|
|
81
|
+
/**
|
|
82
|
+
* Creates a new MLAttr instance from an AST attribute token.
|
|
83
|
+
*
|
|
84
|
+
* @param astToken - The AST attribute token to wrap
|
|
85
|
+
* @param ownElement - The element that owns this attribute
|
|
86
|
+
*/
|
|
19
87
|
constructor(astToken,
|
|
20
88
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
21
89
|
ownElement) {
|
|
22
90
|
super(astToken, ownElement.ownerMLDocument);
|
|
23
|
-
this.endQuote = null;
|
|
24
|
-
this.equal = null;
|
|
25
|
-
_MLAttr_localName.set(this, void 0);
|
|
26
|
-
this.nameNode = null;
|
|
27
|
-
_MLAttr_namespaceURI.set(this, void 0);
|
|
28
|
-
_MLAttr_potentialName.set(this, void 0);
|
|
29
|
-
_MLAttr_potentialValue.set(this, void 0);
|
|
30
|
-
this.spacesAfterEqual = null;
|
|
31
|
-
this.spacesBeforeEqual = null;
|
|
32
|
-
this.spacesBeforeName = null;
|
|
33
|
-
this.startQuote = null;
|
|
34
|
-
this.valueNode = null;
|
|
35
|
-
/**
|
|
36
|
-
* Returns the "string" if HTML syntax. Otherwise, returns a type in its syntax.
|
|
37
|
-
*
|
|
38
|
-
* @default "string"
|
|
39
|
-
* @implements `@markuplint/ml-core` API: `MLAttr`
|
|
40
|
-
*/
|
|
41
|
-
this.valueType = 'string';
|
|
42
91
|
this.ownerElement = ownElement;
|
|
43
92
|
if (this._astToken.type === 'spread') {
|
|
44
|
-
|
|
93
|
+
this.#namespaceURI = ownElement.namespaceURI;
|
|
45
94
|
this.valueType = 'code';
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
95
|
+
this.#localName = '#spread';
|
|
96
|
+
this.#potentialName = '#spread';
|
|
97
|
+
this.#potentialValue = this._astToken.raw;
|
|
49
98
|
this.isDirective = true;
|
|
50
99
|
this.isDynamicValue = true;
|
|
51
100
|
this.isDuplicatable = true;
|
|
@@ -59,43 +108,82 @@ export class MLAttr extends MLNode {
|
|
|
59
108
|
this.startQuote = new MLToken(this._astToken.startQuote);
|
|
60
109
|
this.valueNode = new MLToken(this._astToken.value);
|
|
61
110
|
this.endQuote = new MLToken(this._astToken.endQuote);
|
|
62
|
-
this.isDynamicValue = this._astToken.isDynamicValue;
|
|
63
|
-
this.isDirective = this._astToken.isDirective;
|
|
64
111
|
this.candidate = this._astToken.candidate;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
112
|
+
this.#potentialValue = this._astToken.potentialValue ?? this.valueNode?.raw ?? '';
|
|
113
|
+
if (this._astToken.potentialName == null) {
|
|
114
|
+
// Try declarative directive pattern resolution from spec
|
|
115
|
+
const patterns = ownElement.ownerMLDocument.specs.directivePatterns ?? [];
|
|
116
|
+
const resolution = patterns.length > 0
|
|
117
|
+
? resolveDirective(this.nameNode?.raw ?? '', compileDirectivePatterns(patterns))
|
|
118
|
+
: null;
|
|
119
|
+
if (resolution) {
|
|
120
|
+
this.#potentialName = resolution.potentialName ?? this.nameNode?.raw ?? '';
|
|
121
|
+
this.isDynamicValue = resolution.isDynamicValue;
|
|
122
|
+
this.isDirective = resolution.isDirective;
|
|
123
|
+
this.isDuplicatable = resolution.isDuplicatable ?? this._astToken.isDuplicatable;
|
|
124
|
+
if (resolution.valueType) {
|
|
125
|
+
this.valueType = resolution.valueType;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
this.#potentialName = this.nameNode?.raw ?? '';
|
|
130
|
+
this.isDynamicValue = this._astToken.isDynamicValue;
|
|
131
|
+
this.isDirective = this._astToken.isDirective;
|
|
132
|
+
this.isDuplicatable = this._astToken.isDuplicatable;
|
|
133
|
+
}
|
|
134
|
+
// IDL attribute resolution (after directivePatterns)
|
|
135
|
+
if (ownElement.ownerMLDocument.specs.useIDLAttributeNames && !this.isDirective) {
|
|
136
|
+
const { contentAttrName, idlPropName } = searchIDLAttribute(this.#potentialName);
|
|
137
|
+
if (contentAttrName && contentAttrName !== this.#potentialName) {
|
|
138
|
+
this.#potentialName = contentAttrName;
|
|
139
|
+
}
|
|
140
|
+
// Set candidate for IDL naming suggestions (e.g., tabindex → tabIndex in JSX).
|
|
141
|
+
// Only when no directive pattern transformed the name.
|
|
142
|
+
if (!resolution && idlPropName) {
|
|
143
|
+
const rawName = this.nameNode?.raw ?? '';
|
|
144
|
+
if (rawName !== idlPropName) {
|
|
145
|
+
this.candidate = idlPropName;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// Parser-set potentialName takes precedence
|
|
152
|
+
this.#potentialName = this._astToken.potentialName;
|
|
153
|
+
this.isDynamicValue = this._astToken.isDynamicValue;
|
|
154
|
+
this.isDirective = this._astToken.isDirective;
|
|
155
|
+
this.isDuplicatable = this._astToken.isDuplicatable;
|
|
156
|
+
}
|
|
157
|
+
const ns = resolveNamespace(this.#potentialName, ownElement.namespaceURI);
|
|
158
|
+
this.#localName = ns.localName;
|
|
159
|
+
this.#namespaceURI = ns.namespaceURI;
|
|
71
160
|
}
|
|
72
161
|
/**
|
|
73
|
-
*
|
|
162
|
+
* Returns the local name portion of the attribute (without namespace prefix).
|
|
74
163
|
*
|
|
75
|
-
* @unsupported
|
|
76
164
|
* @implements DOM API: `Attr`
|
|
77
165
|
* @see https://dom.spec.whatwg.org/#ref-for-dom-attr-localname
|
|
78
166
|
*/
|
|
79
167
|
get localName() {
|
|
80
|
-
return
|
|
168
|
+
return this.#localName;
|
|
81
169
|
}
|
|
82
170
|
/**
|
|
171
|
+
* Returns the qualified attribute name (the potential name resolved by the parser).
|
|
83
172
|
*
|
|
84
173
|
* @implements DOM API: `Attr`
|
|
85
174
|
* @see https://dom.spec.whatwg.org/#dom-attr-name
|
|
86
175
|
*/
|
|
87
176
|
get name() {
|
|
88
|
-
return
|
|
177
|
+
return this.#potentialName;
|
|
89
178
|
}
|
|
90
179
|
/**
|
|
91
|
-
*
|
|
180
|
+
* Returns the namespace URI of this attribute, resolved from the attribute name.
|
|
92
181
|
*
|
|
93
|
-
* @unsupported
|
|
94
182
|
* @implements DOM API: `Attr`
|
|
95
183
|
* @see https://dom.spec.whatwg.org/#ref-for-dom-attr-namespaceuri
|
|
96
184
|
*/
|
|
97
185
|
get namespaceURI() {
|
|
98
|
-
return
|
|
186
|
+
return this.#namespaceURI;
|
|
99
187
|
}
|
|
100
188
|
/**
|
|
101
189
|
* Returns a string appropriate for the type of node as `Attr`
|
|
@@ -111,6 +199,12 @@ export class MLAttr extends MLNode {
|
|
|
111
199
|
get nodeType() {
|
|
112
200
|
return this.ATTRIBUTE_NODE;
|
|
113
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Returns the attribute value, equivalent to the `value` property.
|
|
204
|
+
*
|
|
205
|
+
* @implements DOM API: `Attr`
|
|
206
|
+
* @see https://dom.spec.whatwg.org/#dom-node-nodevalue
|
|
207
|
+
*/
|
|
114
208
|
get nodeValue() {
|
|
115
209
|
return this.value;
|
|
116
210
|
}
|
|
@@ -155,7 +249,7 @@ export class MLAttr extends MLNode {
|
|
|
155
249
|
* @see https://dom.spec.whatwg.org/#dom-attr-value
|
|
156
250
|
*/
|
|
157
251
|
get value() {
|
|
158
|
-
return
|
|
252
|
+
return this.#potentialValue;
|
|
159
253
|
}
|
|
160
254
|
/**
|
|
161
255
|
* Fixes the attribute value.
|
|
@@ -173,7 +267,12 @@ export class MLAttr extends MLNode {
|
|
|
173
267
|
this.valueNode?.fix(raw);
|
|
174
268
|
}
|
|
175
269
|
/**
|
|
270
|
+
* Returns a normalized string representation of the attribute,
|
|
271
|
+
* stripping extraneous whitespace around the name, equal sign, and value tokens.
|
|
272
|
+
* Falls back to the raw string if any token is missing.
|
|
273
|
+
*
|
|
176
274
|
* @implements `@markuplint/ml-core` API: `MLAttr`
|
|
275
|
+
* @returns The normalized attribute string
|
|
177
276
|
*/
|
|
178
277
|
toNormalizeString() {
|
|
179
278
|
if (this.nameNode && this.equal && this.startQuote && this.valueNode && this.endQuote) {
|
|
@@ -208,4 +307,3 @@ export class MLAttr extends MLNode {
|
|
|
208
307
|
return tokens.join('');
|
|
209
308
|
}
|
|
210
309
|
}
|
|
211
|
-
_MLAttr_localName = new WeakMap(), _MLAttr_namespaceURI = new WeakMap(), _MLAttr_potentialName = new WeakMap(), _MLAttr_potentialValue = new WeakMap();
|
|
@@ -1,12 +1,33 @@
|
|
|
1
1
|
import type { MLDocument } from './document.js';
|
|
2
2
|
import type { MLElement } from './element.js';
|
|
3
3
|
import type { MarkuplintPreprocessorBlockType } from './types.js';
|
|
4
|
-
import type { MLASTPreprocessorSpecificBlock,
|
|
4
|
+
import type { MLASTPreprocessorSpecificBlock, MLASTBlockBehavior } from '@markuplint/ml-ast';
|
|
5
5
|
import type { PlainData, RuleConfigValue } from '@markuplint/ml-config';
|
|
6
6
|
import { MLNode } from './node.js';
|
|
7
|
+
/**
|
|
8
|
+
* Represents a preprocessor-specific block node in the markuplint DOM tree.
|
|
9
|
+
* These nodes correspond to template engine constructs such as conditionals (`if`/`else`),
|
|
10
|
+
* loops (`each`), and other preprocessor directives that are not part of standard HTML.
|
|
11
|
+
*
|
|
12
|
+
* @template T - The rule configuration value type
|
|
13
|
+
* @template O - The rule options type
|
|
14
|
+
*/
|
|
7
15
|
export declare class MLBlock<T extends RuleConfigValue, O extends PlainData = undefined> extends MLNode<T, O, MLASTPreprocessorSpecificBlock> {
|
|
8
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Block behavior associated with this block, if any.
|
|
18
|
+
*/
|
|
19
|
+
readonly blockBehavior: MLASTBlockBehavior | null;
|
|
20
|
+
/**
|
|
21
|
+
* Whether this block is transparent, meaning its children are treated
|
|
22
|
+
* as belonging to the parent node for tree traversal purposes.
|
|
23
|
+
*/
|
|
9
24
|
readonly isTransparent: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a new MLBlock instance.
|
|
27
|
+
*
|
|
28
|
+
* @param astNode - The AST preprocessor block node to wrap
|
|
29
|
+
* @param document - The owning document
|
|
30
|
+
*/
|
|
10
31
|
constructor(astNode: MLASTPreprocessorSpecificBlock, document: MLDocument<T, O>);
|
|
11
32
|
/**
|
|
12
33
|
* Returns a string appropriate for the type of node as `MLBlock`
|
package/lib/ml-dom/node/block.js
CHANGED
|
@@ -1,13 +1,36 @@
|
|
|
1
1
|
import { after, before, remove, replaceWith } from '../manipulations/child-node-methods.js';
|
|
2
2
|
import { MLNode } from './node.js';
|
|
3
|
+
/**
|
|
4
|
+
* Represents a preprocessor-specific block node in the markuplint DOM tree.
|
|
5
|
+
* These nodes correspond to template engine constructs such as conditionals (`if`/`else`),
|
|
6
|
+
* loops (`each`), and other preprocessor directives that are not part of standard HTML.
|
|
7
|
+
*
|
|
8
|
+
* @template T - The rule configuration value type
|
|
9
|
+
* @template O - The rule options type
|
|
10
|
+
*/
|
|
3
11
|
export class MLBlock extends MLNode {
|
|
12
|
+
/**
|
|
13
|
+
* Block behavior associated with this block, if any.
|
|
14
|
+
*/
|
|
15
|
+
blockBehavior;
|
|
16
|
+
/**
|
|
17
|
+
* Whether this block is transparent, meaning its children are treated
|
|
18
|
+
* as belonging to the parent node for tree traversal purposes.
|
|
19
|
+
*/
|
|
20
|
+
isTransparent;
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new MLBlock instance.
|
|
23
|
+
*
|
|
24
|
+
* @param astNode - The AST preprocessor block node to wrap
|
|
25
|
+
* @param document - The owning document
|
|
26
|
+
*/
|
|
4
27
|
constructor(astNode,
|
|
5
28
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
6
29
|
document) {
|
|
7
30
|
super(astNode, document, astNode.isFragment);
|
|
8
31
|
// TODO:
|
|
9
32
|
this.isTransparent = true;
|
|
10
|
-
this.
|
|
33
|
+
this.blockBehavior = astNode.blockBehavior;
|
|
11
34
|
}
|
|
12
35
|
/**
|
|
13
36
|
* Returns a string appropriate for the type of node as `MLBlock`
|
|
@@ -15,4 +15,13 @@ import type { PlainData, RuleConfigValue } from '@markuplint/ml-config';
|
|
|
15
15
|
* @see https://dom.spec.whatwg.org/#idl-index
|
|
16
16
|
*/
|
|
17
17
|
export type MLChildNode<T extends RuleConfigValue, O extends PlainData = undefined> = MLDocumentType<T, O> | MLCharacterData<T, O> | MLElement<T, O> | MLBlock<T, O>;
|
|
18
|
+
/**
|
|
19
|
+
* Determines whether the given node is a child node type
|
|
20
|
+
* (DocumentType, CDATA, Comment, Text, Element, or preprocessor block).
|
|
21
|
+
*
|
|
22
|
+
* @template T - The rule configuration value type
|
|
23
|
+
* @template O - The rule options type
|
|
24
|
+
* @param node - The node to check
|
|
25
|
+
* @returns True if the node is one of the child node types
|
|
26
|
+
*/
|
|
18
27
|
export declare function isChildNode<T extends RuleConfigValue, O extends PlainData = undefined>(node: MLNode<T, O>): node is MLChildNode<T, O>;
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines whether the given node is a child node type
|
|
3
|
+
* (DocumentType, CDATA, Comment, Text, Element, or preprocessor block).
|
|
4
|
+
*
|
|
5
|
+
* @template T - The rule configuration value type
|
|
6
|
+
* @template O - The rule options type
|
|
7
|
+
* @param node - The node to check
|
|
8
|
+
* @returns True if the node is one of the child node types
|
|
9
|
+
*/
|
|
1
10
|
export function isChildNode(
|
|
2
11
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
3
12
|
node) {
|
|
@@ -2,6 +2,13 @@ import type { CommentNodeType } from './types.js';
|
|
|
2
2
|
import type { MLASTComment } from '@markuplint/ml-ast';
|
|
3
3
|
import type { PlainData, RuleConfigValue } from '@markuplint/ml-config';
|
|
4
4
|
import { MLCharacterData } from './character-data.js';
|
|
5
|
+
/**
|
|
6
|
+
* Represents a DOM Comment node wrapper in the markuplint DOM tree.
|
|
7
|
+
* Wraps an AST comment token and implements the standard DOM `Comment` interface.
|
|
8
|
+
*
|
|
9
|
+
* @template T - The rule configuration value type
|
|
10
|
+
* @template O - The rule options type
|
|
11
|
+
*/
|
|
5
12
|
export declare class MLComment<T extends RuleConfigValue, O extends PlainData = undefined> extends MLCharacterData<T, O, MLASTComment> implements Comment {
|
|
6
13
|
/**
|
|
7
14
|
* Returns a string appropriate for the type of node as `Attr`
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { MLCharacterData } from './character-data.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents a DOM Comment node wrapper in the markuplint DOM tree.
|
|
4
|
+
* Wraps an AST comment token and implements the standard DOM `Comment` interface.
|
|
5
|
+
*
|
|
6
|
+
* @template T - The rule configuration value type
|
|
7
|
+
* @template O - The rule options type
|
|
8
|
+
*/
|
|
2
9
|
export class MLComment extends MLCharacterData {
|
|
3
10
|
/**
|
|
4
11
|
* Returns a string appropriate for the type of node as `Attr`
|
|
@@ -2,6 +2,14 @@ import type { DocumentFragmentNodeType } from './types.js';
|
|
|
2
2
|
import type { MLASTNode } from '@markuplint/ml-ast';
|
|
3
3
|
import type { PlainData, RuleConfigValue } from '@markuplint/ml-config';
|
|
4
4
|
import { MLParentNode } from './parent-node.js';
|
|
5
|
+
/**
|
|
6
|
+
* Represents a DOM DocumentFragment node wrapper in the markuplint DOM tree.
|
|
7
|
+
* Used for JSX fragments and similar constructs where a set of nodes
|
|
8
|
+
* is grouped without a wrapping element.
|
|
9
|
+
*
|
|
10
|
+
* @template T - The rule configuration value type
|
|
11
|
+
* @template O - The rule options type
|
|
12
|
+
*/
|
|
5
13
|
export declare class MLDocumentFragment<T extends RuleConfigValue, O extends PlainData = undefined> extends MLParentNode<T, O, MLASTNode> implements DocumentFragment {
|
|
6
14
|
/**
|
|
7
15
|
* Returns a string appropriate for the type of node as `DocumentFragment`
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { MLParentNode } from './parent-node.js';
|
|
2
2
|
import { UnexpectedCallError } from './unexpected-call-error.js';
|
|
3
|
+
/**
|
|
4
|
+
* Represents a DOM DocumentFragment node wrapper in the markuplint DOM tree.
|
|
5
|
+
* Used for JSX fragments and similar constructs where a set of nodes
|
|
6
|
+
* is grouped without a wrapping element.
|
|
7
|
+
*
|
|
8
|
+
* @template T - The rule configuration value type
|
|
9
|
+
* @template O - The rule options type
|
|
10
|
+
*/
|
|
3
11
|
export class MLDocumentFragment extends MLParentNode {
|
|
4
12
|
/**
|
|
5
13
|
* Returns a string appropriate for the type of node as `DocumentFragment`
|