@markuplint/ml-core 4.13.3 → 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 +92 -35
- package/ARCHITECTURE.md +85 -28
- package/CHANGELOG.md +50 -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/docs/ml-dom/block.ja.md
CHANGED
|
@@ -15,19 +15,19 @@ MLBlock はテンプレート構文と HTML コンテンツモデル検証の橋
|
|
|
15
15
|
|
|
16
16
|
## プロパティ
|
|
17
17
|
|
|
18
|
-
| プロパティ
|
|
19
|
-
|
|
|
20
|
-
| `
|
|
21
|
-
| `isTransparent`
|
|
22
|
-
| `isFragment`
|
|
18
|
+
| プロパティ | 型 | 説明 |
|
|
19
|
+
| --------------- | ---------------------------- | -------------------------------------------------------------------------------------------- |
|
|
20
|
+
| `blockBehavior` | `MLASTBlockBehavior \| null` | ブロックの動作を示す構文の種類(下表参照)、非条件ブロックの場合は `null` |
|
|
21
|
+
| `isTransparent` | `boolean` | ツリー走査で透過的かどうか。現在は常に `true`(ソースの TODO を参照) |
|
|
22
|
+
| `isFragment` | `boolean` | ブロックが透過フラグメントとして機能するか(MLNode から継承、`astNode.isFragment` から設定) |
|
|
23
23
|
|
|
24
|
-
##
|
|
24
|
+
## blockBehavior の型
|
|
25
25
|
|
|
26
|
-
`
|
|
26
|
+
`blockBehavior` は、ブロックが条件分岐子ノードパターン生成にどのように参加するかを決定します(後述の[条件分岐子ノード](#条件分岐子ノード)を参照)。`type` プロパティを持つオブジェクト、または非条件ブロックの場合は `null` です。
|
|
27
27
|
|
|
28
28
|
### 条件グループ
|
|
29
29
|
|
|
30
|
-
認識された `
|
|
30
|
+
認識された `blockBehavior.type` を持つブロックは条件グループを形成します。各グループは「開始」型で始まり、「分岐」型を含む場合があります:
|
|
31
31
|
|
|
32
32
|
| グループ | 開始 | 分岐 | 終了 |
|
|
33
33
|
| ---------- | --------------- | ------------------------------- | ------------------ |
|
|
@@ -38,20 +38,20 @@ MLBlock はテンプレート構文と HTML コンテンツモデル検証の橋
|
|
|
38
38
|
|
|
39
39
|
### すべての値
|
|
40
40
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
| `'if'`
|
|
44
|
-
| `'if:elseif'`
|
|
45
|
-
| `'if:else'`
|
|
46
|
-
| `'switch:case'`
|
|
47
|
-
| `'switch:default'`
|
|
48
|
-
| `'each'`
|
|
49
|
-
| `'each:empty'`
|
|
50
|
-
| `'await'`
|
|
51
|
-
| `'await:then'`
|
|
52
|
-
| `'await:catch'`
|
|
53
|
-
| `'end'`
|
|
54
|
-
| `null`
|
|
41
|
+
| `blockBehavior.type` | 説明 | 役割 |
|
|
42
|
+
| -------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------- |
|
|
43
|
+
| `'if'` | 条件ブロックの開始 | 新しい条件グループを開始 |
|
|
44
|
+
| `'if:elseif'` | 代替条件分岐 | 新しい条件グループを開始(パターン生成では `'if'` と同じ扱い) |
|
|
45
|
+
| `'if:else'` | デフォルト(else)分岐 | 現在のグループ内の分岐 |
|
|
46
|
+
| `'switch:case'` | switch の case 分岐 | 新しい条件グループを開始 |
|
|
47
|
+
| `'switch:default'` | switch のデフォルト分岐 | 現在のグループ内の分岐 |
|
|
48
|
+
| `'each'` | イテレーション(ループ)ブロックの開始 | 新しい条件グループを開始 |
|
|
49
|
+
| `'each:empty'` | イテレーションブロックの空状態 | 現在のグループ内の分岐 |
|
|
50
|
+
| `'await'` | 非同期ブロック(pending 状態) | 現在のグループ内の分岐 |
|
|
51
|
+
| `'await:then'` | 非同期ブロックの resolved 状態 | 現在のグループ内の分岐 |
|
|
52
|
+
| `'await:catch'` | 非同期ブロックの rejected 状態 | 現在のグループ内の分岐 |
|
|
53
|
+
| `'end'` | ブロック終了マーカー | 無視される(switch の `default` でフィルタされる) |
|
|
54
|
+
| `null` | ブロック動作なし(例: `{value}` のような式出力) | 条件グループではない。ミュータブルな子として扱われる(`blockBehavior` が `null`) |
|
|
55
55
|
|
|
56
56
|
## 透過性
|
|
57
57
|
|
|
@@ -111,17 +111,17 @@ if (parentNode.is(parentNode.MARKUPLINT_PREPROCESSOR_BLOCK)) {
|
|
|
111
111
|
|
|
112
112
|
## 条件分岐子ノード
|
|
113
113
|
|
|
114
|
-
`MLNode` の `conditionalChildNodes()` メソッドは、MLBlock の `
|
|
114
|
+
`MLNode` の `conditionalChildNodes()` メソッドは、MLBlock の `blockBehavior?.type` を使用して、レンダリングされた出力に現れうるすべての子ノードパターンを列挙します。これはテンプレート分岐がある場合のコンテンツモデル検証に不可欠です。
|
|
115
115
|
|
|
116
116
|
### アルゴリズム
|
|
117
117
|
|
|
118
118
|
1. 現在のノードの `childNodes` を走査する
|
|
119
|
-
2. 認識された `
|
|
120
|
-
- `mode` を判定(`'if'
|
|
119
|
+
2. 認識された `blockBehavior?.type` を持つ各 MLBlock 子に対して:
|
|
120
|
+
- `mode` を判定(`'if'` または `'switch'`)。`'each'` ブロックは新しいモードを開始しない
|
|
121
121
|
- ブロックに対して再帰的に `conditionalChildNodes()` を呼び出してサブパターンを取得
|
|
122
122
|
- すべての分岐の代替を `subBranches` 配列に収集
|
|
123
123
|
3. 条件グループ終了後に非ブロックの子が出現したとき:
|
|
124
|
-
- mode が `'if'
|
|
124
|
+
- mode が `'if'` または `'switch'` の場合:`null` をセンチネルとしてプッシュ(どの分岐もレンダリングされない「空」ケースを表現)
|
|
125
125
|
- 現在のグループを閉じ、`subBranches` を `branches` にプッシュ
|
|
126
126
|
4. 空白のみのテキストノードはスキップ
|
|
127
127
|
5. 非ブロックの子は直接 `branches` に追加
|
|
@@ -162,9 +162,9 @@ AST 構造:
|
|
|
162
162
|
|
|
163
163
|
```
|
|
164
164
|
MLElement <ul>
|
|
165
|
-
├── MLBlock (
|
|
165
|
+
├── MLBlock (blockBehavior.type: 'if')
|
|
166
166
|
│ └── MLElement <li>A</li>
|
|
167
|
-
├── MLBlock (
|
|
167
|
+
├── MLBlock (blockBehavior.type: 'if:else')
|
|
168
168
|
│ └── MLElement <li>B</li>
|
|
169
169
|
└── MLElement <li>C</li>
|
|
170
170
|
```
|
|
@@ -203,15 +203,15 @@ branches = [[<li>A</li>, <li>B</li>, null], <li>C</li>]
|
|
|
203
203
|
|
|
204
204
|
## `hasMutableChildren()` との相互作用
|
|
205
205
|
|
|
206
|
-
`MLElement.hasMutableChildren()` は `
|
|
206
|
+
`MLElement.hasMutableChildren()` は `blockBehavior` を使用して MLBlock を2つのカテゴリに区別します:
|
|
207
207
|
|
|
208
|
-
- **`
|
|
209
|
-
- **`
|
|
208
|
+
- **`blockBehavior` を持つブロック**(例: type `'if'`、`'each'`、`'switch:case'`):スキップ(`continue`)— `conditionalChildNodes()` がすべての可能なパターンを列挙して処理する
|
|
209
|
+
- **`blockBehavior` を持たないブロック**(`null`):即座に `true` を返す — `{value}` のような式出力やその他の非条件テンプレート構文を表し、内容が静的に決定できない
|
|
210
210
|
|
|
211
211
|
```typescript
|
|
212
212
|
for (const child of this.getPureChildNodes()) {
|
|
213
213
|
if (child.is(child.MARKUPLINT_PREPROCESSOR_BLOCK)) {
|
|
214
|
-
if (child.
|
|
214
|
+
if (child.blockBehavior) {
|
|
215
215
|
continue; // 条件セマンティクスあり → 別の場所で処理
|
|
216
216
|
}
|
|
217
217
|
return true; // 条件セマンティクスなし → 本当にミュータブル
|
|
@@ -230,7 +230,7 @@ MLBlock はリンティングパイプラインの複数のレベルで参加し
|
|
|
230
230
|
|
|
231
231
|
テンプレートエンジンパーサー(Svelte、Nunjucks、EJS、Pug など)が `MLASTPreprocessorSpecificBlock` AST ノードを生成します。各パーサーは以下を担当します:
|
|
232
232
|
|
|
233
|
-
- `
|
|
233
|
+
- `blockBehavior` の適切な設定(例: Svelte `{#if}` → `{ type: 'if' }`、`{#each}` → `{ type: 'each' }`)
|
|
234
234
|
- ブロック内への子 AST ノードのネスト
|
|
235
235
|
- フラグメントコンテナとして機能すべきブロックの `isFragment` 設定
|
|
236
236
|
|
package/docs/ml-dom/block.md
CHANGED
|
@@ -15,19 +15,19 @@ MLBlock serves as the bridge between template syntax and HTML content model vali
|
|
|
15
15
|
|
|
16
16
|
## Properties
|
|
17
17
|
|
|
18
|
-
| Property
|
|
19
|
-
|
|
|
20
|
-
| `
|
|
21
|
-
| `isTransparent`
|
|
22
|
-
| `isFragment`
|
|
18
|
+
| Property | Type | Description |
|
|
19
|
+
| --------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
20
|
+
| `blockBehavior` | `MLASTBlockBehavior \| null` | The block behavior describing the type of construct (see table below), or `null` for non-conditional blocks |
|
|
21
|
+
| `isTransparent` | `boolean` | Whether the block is transparent in tree traversal; currently always `true` (see source TODO) |
|
|
22
|
+
| `isFragment` | `boolean` | Whether this block acts as a transparent fragment (inherited from MLNode, set from `astNode.isFragment`) |
|
|
23
23
|
|
|
24
|
-
##
|
|
24
|
+
## blockBehavior Types
|
|
25
25
|
|
|
26
|
-
`
|
|
26
|
+
`blockBehavior` determines how the block participates in conditional child node pattern generation (see [Conditional Child Nodes](#conditional-child-nodes) below). It is an object with a `type` property, or `null` for non-conditional blocks.
|
|
27
27
|
|
|
28
28
|
### Conditional Groups
|
|
29
29
|
|
|
30
|
-
Blocks with a recognized `
|
|
30
|
+
Blocks with a recognized `blockBehavior.type` form conditional groups. Each group starts with a "start" type and may include "branch" types:
|
|
31
31
|
|
|
32
32
|
| Group | Start | Branches | End |
|
|
33
33
|
| ---------- | --------------- | ------------------------------- | ------------------- |
|
|
@@ -38,20 +38,20 @@ Blocks with a recognized `conditionalType` form conditional groups. Each group s
|
|
|
38
38
|
|
|
39
39
|
### All Values
|
|
40
40
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
| `'if'`
|
|
44
|
-
| `'if:elseif'`
|
|
45
|
-
| `'if:else'`
|
|
46
|
-
| `'switch:case'`
|
|
47
|
-
| `'switch:default'`
|
|
48
|
-
| `'each'`
|
|
49
|
-
| `'each:empty'`
|
|
50
|
-
| `'await'`
|
|
51
|
-
| `'await:then'`
|
|
52
|
-
| `'await:catch'`
|
|
53
|
-
| `'end'`
|
|
54
|
-
| `null`
|
|
41
|
+
| `blockBehavior.type` | Description | Role |
|
|
42
|
+
| -------------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
|
43
|
+
| `'if'` | Start of conditional block | Starts a new conditional group |
|
|
44
|
+
| `'if:elseif'` | Alternative conditional branch | Starts a new conditional group (treated the same as `'if'` in pattern generation) |
|
|
45
|
+
| `'if:else'` | Default (else) branch | Branch within current group |
|
|
46
|
+
| `'switch:case'` | Switch case branch | Starts a new conditional group |
|
|
47
|
+
| `'switch:default'` | Switch default branch | Branch within current group |
|
|
48
|
+
| `'each'` | Start of iteration (loop) block | Continues in current mode (no new mode set); flattened into `childNodes` |
|
|
49
|
+
| `'each:empty'` | Empty state for an iteration block | Branch within current group |
|
|
50
|
+
| `'await'` | Asynchronous block (pending state) | Branch within current group |
|
|
51
|
+
| `'await:then'` | Resolved state of async block | Branch within current group |
|
|
52
|
+
| `'await:catch'` | Rejected state of async block | Branch within current group |
|
|
53
|
+
| `'end'` | Closing block marker | Ignored (filtered out by `default` in the switch) |
|
|
54
|
+
| `null` | No block behavior (e.g., expression output like `{value}`) | Not a conditional group; treated as a mutable child (`blockBehavior` is `null`) |
|
|
55
55
|
|
|
56
56
|
## Transparency
|
|
57
57
|
|
|
@@ -111,17 +111,17 @@ This ensures that rules validating parent-child relationships (like `permitted-c
|
|
|
111
111
|
|
|
112
112
|
## Conditional Child Nodes
|
|
113
113
|
|
|
114
|
-
The `conditionalChildNodes()` method on `MLNode` uses MLBlock's `
|
|
114
|
+
The `conditionalChildNodes()` method on `MLNode` uses MLBlock's `blockBehavior?.type` to enumerate all possible child node patterns that could appear in the rendered output. This is critical for content model validation in the presence of template branching.
|
|
115
115
|
|
|
116
116
|
### Algorithm
|
|
117
117
|
|
|
118
118
|
1. Walk through `childNodes` of the current node
|
|
119
|
-
2. For each MLBlock child with a recognized `
|
|
120
|
-
- Determine the `mode` (`'if'
|
|
119
|
+
2. For each MLBlock child with a recognized `blockBehavior?.type`:
|
|
120
|
+
- Determine the `mode` (`'if'` or `'switch'`); `'each'` blocks do not start a new mode
|
|
121
121
|
- Recursively call `conditionalChildNodes()` on the block to get its sub-patterns
|
|
122
122
|
- Collect all branch alternatives into a `subBranches` array
|
|
123
123
|
3. When a non-block child is encountered after a conditional group ends:
|
|
124
|
-
- If the mode was `'if'
|
|
124
|
+
- If the mode was `'if'` or `'switch'`: push `null` as a sentinel (representing the "empty" case where none of the branches render)
|
|
125
125
|
- Close the current group and push `subBranches` to `branches`
|
|
126
126
|
4. Skip whitespace-only text nodes
|
|
127
127
|
5. Non-block children are added directly to `branches`
|
|
@@ -162,9 +162,9 @@ The AST structure is:
|
|
|
162
162
|
|
|
163
163
|
```
|
|
164
164
|
MLElement <ul>
|
|
165
|
-
├── MLBlock (
|
|
165
|
+
├── MLBlock (blockBehavior.type: 'if')
|
|
166
166
|
│ └── MLElement <li>A</li>
|
|
167
|
-
├── MLBlock (
|
|
167
|
+
├── MLBlock (blockBehavior.type: 'if:else')
|
|
168
168
|
│ └── MLElement <li>B</li>
|
|
169
169
|
└── MLElement <li>C</li>
|
|
170
170
|
```
|
|
@@ -203,15 +203,15 @@ The inner `{#if b}` block recursively generates its patterns `[<span>X</span>]`,
|
|
|
203
203
|
|
|
204
204
|
## Interaction with `hasMutableChildren()`
|
|
205
205
|
|
|
206
|
-
`MLElement.hasMutableChildren()` uses `
|
|
206
|
+
`MLElement.hasMutableChildren()` uses `blockBehavior` to distinguish between two categories of MLBlock:
|
|
207
207
|
|
|
208
|
-
- **Blocks WITH `
|
|
209
|
-
- **Blocks WITHOUT `
|
|
208
|
+
- **Blocks WITH `blockBehavior`** (e.g., type `'if'`, `'switch:case'`): Skipped (`continue`) — these are handled by `conditionalChildNodes()` which enumerates all possible patterns. Note that `'each'` and `'end'` blocks are flattened into `childNodes` (their children are inlined), so they do not reach `hasMutableChildren()` as blocks
|
|
209
|
+
- **Blocks WITHOUT `blockBehavior`** (`null`): Return `true` immediately — these represent expression outputs like `{value}` or other non-conditional template constructs whose content cannot be statically determined
|
|
210
210
|
|
|
211
211
|
```typescript
|
|
212
212
|
for (const child of this.getPureChildNodes()) {
|
|
213
213
|
if (child.is(child.MARKUPLINT_PREPROCESSOR_BLOCK)) {
|
|
214
|
-
if (child.
|
|
214
|
+
if (child.blockBehavior) {
|
|
215
215
|
continue; // Has conditional semantics → handled elsewhere
|
|
216
216
|
}
|
|
217
217
|
return true; // No conditional semantics → truly mutable
|
|
@@ -230,7 +230,7 @@ MLBlock participates at multiple levels of the linting pipeline:
|
|
|
230
230
|
|
|
231
231
|
Template engine parsers (Svelte, Nunjucks, EJS, Pug, etc.) produce `MLASTPreprocessorSpecificBlock` AST nodes. Each parser is responsible for:
|
|
232
232
|
|
|
233
|
-
- Setting `
|
|
233
|
+
- Setting `blockBehavior` appropriately (e.g., Svelte `{#if}` → `{ type: 'if' }`, `{#each}` → `{ type: 'each' }`)
|
|
234
234
|
- Nesting child AST nodes within the block
|
|
235
235
|
- Setting `isFragment` when the block should act as a fragment container
|
|
236
236
|
|
|
@@ -110,7 +110,7 @@ Pretender システムのアーキテクチャ、初期化フロー、プロパ
|
|
|
110
110
|
|
|
111
111
|
要素の子が非決定的な場合に `true` を返します。`getPureChildNodes()` を反復します:
|
|
112
112
|
|
|
113
|
-
- `
|
|
113
|
+
- `blockBehavior` を**持たない** `MLBlock` の子が存在する(つまり `blockBehavior` が `null` -- `'if'` や `'each'` のような認識されたブロック動作型を持つブロックは `conditionalChildNodes()` で処理されるためスキップされる)
|
|
114
114
|
- `<slot>` の子要素が存在する(コンテンツは実行時に注入される)
|
|
115
115
|
- `attr` が `true` の場合:子要素のいずれかが `hasMutableAttributes() === true` を持つ
|
|
116
116
|
- 子要素に対して再帰的に `hasMutableChildren()` をチェックする
|
|
@@ -139,10 +139,9 @@ Pretender システムのアーキテクチャ、初期化フロー、プロパ
|
|
|
139
139
|
|
|
140
140
|
## 閉じタグ
|
|
141
141
|
|
|
142
|
-
| プロパティ
|
|
143
|
-
|
|
|
144
|
-
| `closeTag`
|
|
145
|
-
| `selfClosingSolidus` | `MLToken \| null` | `<br />` の `/` トークン。自己閉じでない場合は `null` |
|
|
142
|
+
| プロパティ | 型 | 説明 |
|
|
143
|
+
| ---------- | --------------------------- | ------------------------------------------------------------------------------------ |
|
|
144
|
+
| `closeTag` | `MLElementCloseTag \| null` | ペアの閉じタグ。void 要素、自己閉じ要素、または `endTag === 'never'` の場合は `null` |
|
|
146
145
|
|
|
147
146
|
## `toString(fixed?)`
|
|
148
147
|
|
|
@@ -162,15 +161,16 @@ Fixed: <div class="foo" >
|
|
|
162
161
|
|
|
163
162
|
## その他のプロパティ
|
|
164
163
|
|
|
165
|
-
| プロパティ | 型
|
|
166
|
-
| ------------------ |
|
|
167
|
-
| `namespaceURI` | `NamespaceURI`
|
|
168
|
-
| `isForeignElement` | `boolean`
|
|
169
|
-
| `elementType` | `ElementType`
|
|
170
|
-
| `isOmitted` | `boolean`
|
|
171
|
-
| `
|
|
172
|
-
| `
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
176
|
-
| `
|
|
164
|
+
| プロパティ | 型 | 説明 |
|
|
165
|
+
| ------------------ | ---------------------------- | --------------------------------------------- |
|
|
166
|
+
| `namespaceURI` | `NamespaceURI` | 要素の名前空間(HTML, SVG, MathML) |
|
|
167
|
+
| `isForeignElement` | `boolean` | SVG/MathML 要素の場合 `true` |
|
|
168
|
+
| `elementType` | `ElementType` | `'html'` \| `'web-component'` \| `'authored'` |
|
|
169
|
+
| `isOmitted` | `boolean` | 暗黙的に挿入された要素の場合 `true` |
|
|
170
|
+
| `blockBehavior` | `MLASTBlockBehavior \| null` | AST からのブロック動作(存在する場合) |
|
|
171
|
+
| `classList` | `MLDomTokenList` | `class` 属性からの CSS クラスリスト |
|
|
172
|
+
| `className` | `string` | class 属性値 |
|
|
173
|
+
| `id` | `string` | ID 属性値(存在しない場合は空文字列) |
|
|
174
|
+
| `hasSpreadAttr` | `boolean` | 要素にスプレッド属性があるかどうか |
|
|
175
|
+
| `tagOpenChar` | `string` | 開始タグ区切り文字(例: `<` または `<%`) |
|
|
176
|
+
| `tagCloseChar` | `string` | 閉じタグ区切り文字(例: `>` または `%>`) |
|
package/docs/ml-dom/element.md
CHANGED
|
@@ -110,7 +110,7 @@ For comprehensive documentation on the pretender system's architecture, initiali
|
|
|
110
110
|
|
|
111
111
|
Returns `true` if the element's children are non-deterministic. Iterates `getPureChildNodes()`:
|
|
112
112
|
|
|
113
|
-
- An `MLBlock` child exists **without** a `
|
|
113
|
+
- An `MLBlock` child exists **without** a `blockBehavior` (i.e., `blockBehavior` is `null` -- blocks with recognized block behavior types like `'if'`, `'each'` are skipped because they are handled by `conditionalChildNodes()`)
|
|
114
114
|
- A `<slot>` child element exists (content is injected at runtime)
|
|
115
115
|
- If `attr` is `true`: any child element has `hasMutableAttributes() === true`
|
|
116
116
|
- Recursively checks `hasMutableChildren()` on child elements
|
|
@@ -139,10 +139,9 @@ Elements with `isOmitted === true` were implicitly inserted by the parser (e.g.,
|
|
|
139
139
|
|
|
140
140
|
## Close Tag
|
|
141
141
|
|
|
142
|
-
| Property
|
|
143
|
-
|
|
|
144
|
-
| `closeTag`
|
|
145
|
-
| `selfClosingSolidus` | `MLToken \| null` | The `/` token in `<br />`. `null` if not self-closing. |
|
|
142
|
+
| Property | Type | Description |
|
|
143
|
+
| ---------- | --------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
144
|
+
| `closeTag` | `MLElementCloseTag \| null` | Paired close tag. `null` for void elements, self-closing elements, or when `endTag === 'never'`. |
|
|
146
145
|
|
|
147
146
|
## `toString(fixed?)`
|
|
148
147
|
|
|
@@ -162,15 +161,16 @@ Fixed: <div class="foo" >
|
|
|
162
161
|
|
|
163
162
|
## Other Properties
|
|
164
163
|
|
|
165
|
-
| Property | Type
|
|
166
|
-
| ------------------ |
|
|
167
|
-
| `namespaceURI` | `NamespaceURI`
|
|
168
|
-
| `isForeignElement` | `boolean`
|
|
169
|
-
| `elementType` | `ElementType`
|
|
170
|
-
| `isOmitted` | `boolean`
|
|
171
|
-
| `
|
|
172
|
-
| `
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
176
|
-
| `
|
|
164
|
+
| Property | Type | Description |
|
|
165
|
+
| ------------------ | ---------------------------- | --------------------------------------------- |
|
|
166
|
+
| `namespaceURI` | `NamespaceURI` | Element namespace (HTML, SVG, MathML) |
|
|
167
|
+
| `isForeignElement` | `boolean` | `true` for SVG/MathML elements |
|
|
168
|
+
| `elementType` | `ElementType` | `'html'` \| `'web-component'` \| `'authored'` |
|
|
169
|
+
| `isOmitted` | `boolean` | `true` for implicitly inserted elements |
|
|
170
|
+
| `blockBehavior` | `MLASTBlockBehavior \| null` | Block behavior from the AST, if any |
|
|
171
|
+
| `classList` | `MLDomTokenList` | CSS class list from `class` attribute |
|
|
172
|
+
| `className` | `string` | Class attribute value |
|
|
173
|
+
| `id` | `string` | ID attribute value (empty string if absent) |
|
|
174
|
+
| `hasSpreadAttr` | `boolean` | Whether element has spread attributes |
|
|
175
|
+
| `tagOpenChar` | `string` | Opening tag delimiter (e.g., `<` or `<%`) |
|
|
176
|
+
| `tagCloseChar` | `string` | Closing tag delimiter (e.g., `>` or `%>`) |
|
package/docs/ml-dom/node.ja.md
CHANGED
|
@@ -103,16 +103,15 @@ div
|
|
|
103
103
|
#### アルゴリズム
|
|
104
104
|
|
|
105
105
|
1. `childNodes` を順番に走査する
|
|
106
|
-
2. `MLBlock` に遭遇した場合、その `
|
|
106
|
+
2. `MLBlock` に遭遇した場合、その `blockBehavior?.type` から分岐 `mode` を決定する:
|
|
107
107
|
- `'if'` または `'if:elseif'` → mode `'if'`
|
|
108
|
-
- `'each'` → mode `'each'`
|
|
109
108
|
- `'switch:case'` → mode `'switch'`
|
|
110
|
-
- `'if:else'`、`'each:empty'`、`'switch:default'`、`'await'`、`'await:catch'`、`'await:then'` →
|
|
109
|
+
- `'if:else'`、`'each'`、`'each:empty'`、`'switch:default'`、`'await'`、`'await:catch'`、`'await:then'` → 現在のモードを継続(新しいモードは設定されない)
|
|
111
110
|
- その他の型 → スキップ(条件分岐ではない)
|
|
112
111
|
3. ブロックに対して再帰的に `conditionalChildNodes()` を呼び出し、サブパターンを取得する
|
|
113
112
|
4. 分岐を収集する。非ブロックの子に到達したら、現在の分岐グループを閉じる
|
|
114
113
|
5. 空白のみのテキストノードはスキップされる
|
|
115
|
-
6. `'if'`、`'
|
|
114
|
+
6. `'if'`、`'switch'` モードの場合:「空の分岐」(何もレンダリングされないケース)を表す `null` センチネルが追加される
|
|
116
115
|
7. 収集した分岐を `branchesToPatterns()` に渡し、すべての組み合わせの直積を生成する
|
|
117
116
|
|
|
118
117
|
#### 例
|
|
@@ -168,7 +167,7 @@ function processNode(node: MLNode<any, any>) {
|
|
|
168
167
|
console.log(node.isWhitespace());
|
|
169
168
|
} else if (node.is(node.MARKUPLINT_PREPROCESSOR_BLOCK)) {
|
|
170
169
|
// node は MLBlock<any, any> に絞り込まれる
|
|
171
|
-
console.log(node.
|
|
170
|
+
console.log(node.blockBehavior?.type);
|
|
172
171
|
}
|
|
173
172
|
}
|
|
174
173
|
```
|
package/docs/ml-dom/node.md
CHANGED
|
@@ -103,16 +103,15 @@ Generates all possible child node combinations from template engine conditional
|
|
|
103
103
|
#### Algorithm
|
|
104
104
|
|
|
105
105
|
1. Walk `childNodes` sequentially
|
|
106
|
-
2. When an `MLBlock` is encountered, determine the branch `mode` from its `
|
|
106
|
+
2. When an `MLBlock` is encountered, determine the branch `mode` from its `blockBehavior?.type`:
|
|
107
107
|
- `'if'` or `'if:elseif'` → mode `'if'`
|
|
108
|
-
- `'each'` → mode `'each'`
|
|
109
108
|
- `'switch:case'` → mode `'switch'`
|
|
110
|
-
- `'if:else'`, `'each:empty'`, `'switch:default'`, `'await'`, `'await:catch'`, `'await:then'` → continue in current mode
|
|
109
|
+
- `'if:else'`, `'each'`, `'each:empty'`, `'switch:default'`, `'await'`, `'await:catch'`, `'await:then'` → continue in current mode (no new mode set)
|
|
111
110
|
- Other types → skip (not a conditional branch)
|
|
112
111
|
3. Recursively call `conditionalChildNodes()` on the block to get its sub-patterns
|
|
113
112
|
4. Collect branches; when a non-block child is reached, close the current branch group
|
|
114
113
|
5. Whitespace-only text nodes are skipped
|
|
115
|
-
6. For `'if'
|
|
114
|
+
6. For `'if'` and `'switch'` modes: a `null` sentinel is appended to represent the "empty branch" (the case where nothing is rendered)
|
|
116
115
|
7. Pass the collected branches to `branchesToPatterns()` to generate the Cartesian product of all combinations
|
|
117
116
|
|
|
118
117
|
#### Example
|
|
@@ -168,7 +167,7 @@ function processNode(node: MLNode<any, any>) {
|
|
|
168
167
|
console.log(node.isWhitespace());
|
|
169
168
|
} else if (node.is(node.MARKUPLINT_PREPROCESSOR_BLOCK)) {
|
|
170
169
|
// node is narrowed to MLBlock<any, any>
|
|
171
|
-
console.log(node.
|
|
170
|
+
console.log(node.blockBehavior?.type);
|
|
172
171
|
}
|
|
173
172
|
}
|
|
174
173
|
```
|
package/docs/ml-dom/others.ja.md
CHANGED
|
@@ -27,8 +27,9 @@ MLBlock のドキュメントは専用の [MLBlock](./block.ja.md) リファレ
|
|
|
27
27
|
- `nodeName`: `'#text'`
|
|
28
28
|
- `nodeType`: `3`(`TEXT_NODE`)
|
|
29
29
|
|
|
30
|
-
| メソッド
|
|
30
|
+
| プロパティ / メソッド | 戻り値 | 説明 |
|
|
31
31
|
| --------------------------- | --------- | -------------------------------------------------- |
|
|
32
|
+
| `isBogus` | `boolean` | 不正な AST ノードから生成されたノードの場合 `true` |
|
|
32
33
|
| `isWhitespace()` | `boolean` | テキストが `/^\s+$/` にマッチする場合 `true` |
|
|
33
34
|
| `isRawTextElementContent()` | `boolean` | 親要素が `<script>` または `<style>` の場合 `true` |
|
|
34
35
|
|
package/docs/ml-dom/others.md
CHANGED
|
@@ -27,10 +27,11 @@ Text node. Extends `MLCharacterData` and implements DOM `Text`.
|
|
|
27
27
|
- `nodeName`: `'#text'`
|
|
28
28
|
- `nodeType`: `3` (`TEXT_NODE`)
|
|
29
29
|
|
|
30
|
-
| Method
|
|
31
|
-
| --------------------------- | --------- |
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
30
|
+
| Property / Method | Returns | Description |
|
|
31
|
+
| --------------------------- | --------- | ------------------------------------------------------- |
|
|
32
|
+
| `isBogus` | `boolean` | `true` if this node originated from an invalid AST node |
|
|
33
|
+
| `isWhitespace()` | `boolean` | `true` if text matches `/^\s+$/` |
|
|
34
|
+
| `isRawTextElementContent()` | `boolean` | `true` if parent element is `<script>` or `<style>` |
|
|
34
35
|
|
|
35
36
|
## MLComment
|
|
36
37
|
|
package/docs/rule-system.ja.md
CHANGED
|
@@ -93,12 +93,15 @@ constructor(o: Readonly<RuleSeed<T, O>> & { readonly name: string })
|
|
|
93
93
|
|
|
94
94
|
### プロパティ
|
|
95
95
|
|
|
96
|
-
| プロパティ | 型
|
|
97
|
-
| ----------------- |
|
|
98
|
-
| `name` | `string`
|
|
99
|
-
| `defaultSeverity` | `Severity`
|
|
100
|
-
| `defaultValue` | `T`
|
|
101
|
-
| `defaultOptions` | `O`
|
|
96
|
+
| プロパティ | 型 | 説明 |
|
|
97
|
+
| ----------------- | ------------------------------ | ------------------------------------------------------------------ |
|
|
98
|
+
| `name` | `string` | ルール識別子(例: `"attr-duplication"` または `"a11y/html-lang"`) |
|
|
99
|
+
| `defaultSeverity` | `Severity` | デフォルトの重大度レベル(シードまたは `'error'`) |
|
|
100
|
+
| `defaultValue` | `T` | デフォルト設定値(シードまたは `true`) |
|
|
101
|
+
| `defaultOptions` | `O` | デフォルトオプション(シードから) |
|
|
102
|
+
| `baseRuleId` | `string \| undefined` | 仮想ルールの場合: ベースルール名(例: `"required-attr"`) |
|
|
103
|
+
| `groupName` | `string \| undefined` | 複数エントリ仮想ルールの場合: 一括無効化用のグループ名 |
|
|
104
|
+
| `specConformance` | `SpecConformance \| undefined` | 仮想ルールの場合: `'normative'` または `'non-normative'` |
|
|
102
105
|
|
|
103
106
|
### メソッド
|
|
104
107
|
|
|
@@ -135,6 +138,20 @@ constructor(o: Readonly<RuleSeed<T, O>> & { readonly name: string })
|
|
|
135
138
|
}
|
|
136
139
|
```
|
|
137
140
|
|
|
141
|
+
#### `createAlias(aliasName, options?): MLRule<T, O>`
|
|
142
|
+
|
|
143
|
+
このルールの verify/fix ロジックを別名で再利用する仮想ルールを作成します。named nodeRules を実装するために `expandNamedNodeRules()` が内部的に使用します。
|
|
144
|
+
|
|
145
|
+
オプション:
|
|
146
|
+
|
|
147
|
+
| オプション | 型 | 説明 |
|
|
148
|
+
| ----------------- | ----------------- | ------------------------------------------------------------------------------------------------------ |
|
|
149
|
+
| `defaultSeverity` | `Severity` | ベースルールのデフォルト重大度をオーバーライド(明示的な指定のみ。specConformance による自動設定なし) |
|
|
150
|
+
| `specConformance` | `SpecConformance` | `'normative'` または `'non-normative'` |
|
|
151
|
+
| `groupName` | `string` | 複数エントリ named nodeRule のグループ名 |
|
|
152
|
+
|
|
153
|
+
エイリアスルールはベースルールの verify/fix 関数、meta、デフォルト値を継承します。`baseRuleId` プロパティでベースルール名を返します。
|
|
154
|
+
|
|
138
155
|
#### `optimizeOption(configSettings): RuleInfo<T, O>`
|
|
139
156
|
|
|
140
157
|
生のルール設定を解決済み `RuleInfo` に正規化します。
|
package/docs/rule-system.md
CHANGED
|
@@ -93,12 +93,15 @@ constructor(o: Readonly<RuleSeed<T, O>> & { readonly name: string })
|
|
|
93
93
|
|
|
94
94
|
### Properties
|
|
95
95
|
|
|
96
|
-
| Property | Type
|
|
97
|
-
| ----------------- |
|
|
98
|
-
| `name` | `string`
|
|
99
|
-
| `defaultSeverity` | `Severity`
|
|
100
|
-
| `defaultValue` | `T`
|
|
101
|
-
| `defaultOptions` | `O`
|
|
96
|
+
| Property | Type | Description |
|
|
97
|
+
| ----------------- | ------------------------------ | ------------------------------------------------------------------ |
|
|
98
|
+
| `name` | `string` | Rule identifier (e.g., `"attr-duplication"` or `"a11y/html-lang"`) |
|
|
99
|
+
| `defaultSeverity` | `Severity` | Default severity level (from seed or `'error'`) |
|
|
100
|
+
| `defaultValue` | `T` | Default config value (from seed or `true`) |
|
|
101
|
+
| `defaultOptions` | `O` | Default options (from seed) |
|
|
102
|
+
| `baseRuleId` | `string \| undefined` | For virtual rules: the base rule's name (e.g., `"required-attr"`) |
|
|
103
|
+
| `groupName` | `string \| undefined` | For multi-entry virtual rules: group name for batch disable |
|
|
104
|
+
| `specConformance` | `SpecConformance \| undefined` | For virtual rules: `'normative'` or `'non-normative'` |
|
|
102
105
|
|
|
103
106
|
### Methods
|
|
104
107
|
|
|
@@ -135,6 +138,20 @@ Returns:
|
|
|
135
138
|
}
|
|
136
139
|
```
|
|
137
140
|
|
|
141
|
+
#### `createAlias(aliasName, options?): MLRule<T, O>`
|
|
142
|
+
|
|
143
|
+
Creates a virtual rule that reuses this rule's verify/fix logic under a different name. Used internally by `expandNamedNodeRules()` to implement named nodeRules.
|
|
144
|
+
|
|
145
|
+
Options:
|
|
146
|
+
|
|
147
|
+
| Option | Type | Description |
|
|
148
|
+
| ----------------- | ----------------- | ------------------------------------------------------------------------------------- |
|
|
149
|
+
| `defaultSeverity` | `Severity` | Override the base rule's default severity (explicit only; not set by specConformance) |
|
|
150
|
+
| `specConformance` | `SpecConformance` | `'normative'` or `'non-normative'` |
|
|
151
|
+
| `groupName` | `string` | Group name for multi-entry named nodeRules |
|
|
152
|
+
|
|
153
|
+
The alias rule inherits the base rule's verify/fix functions, meta, and defaults. Its `baseRuleId` property returns the base rule's name.
|
|
154
|
+
|
|
138
155
|
#### `optimizeOption(configSettings): RuleInfo<T, O>`
|
|
139
156
|
|
|
140
157
|
Normalizes raw rule settings into resolved `RuleInfo`.
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { RuleInfo, RuleConfig, RuleConfigValue } from '@markuplint/ml-config';
|
|
1
|
+
export type { RuleInfo, RuleConfig, RuleConfigValue } from '@markuplint/ml-config';
|
|
2
2
|
export { ariaSpecs, contentModelCategoryToTagNames, getAttrSpecs, getComputedRole, getImplicitRole, getPermittedRoles, getRoleSpec, getSpec, resolveNamespace, } from '@markuplint/ml-spec';
|
|
3
3
|
export { Ruleset } from './ruleset/index.js';
|
|
4
4
|
export { enableDebug } from './debug.js';
|
|
@@ -9,7 +9,8 @@ export * from './ml-dom/index.js';
|
|
|
9
9
|
export * from './ml-rule/index.js';
|
|
10
10
|
export * from './plugin/index.js';
|
|
11
11
|
export * from './test/index.js';
|
|
12
|
-
export * from './types.js';
|
|
12
|
+
export type * from './types.js';
|
|
13
13
|
export * from './utils/index.js';
|
|
14
14
|
export * from './violation-collector.js';
|
|
15
|
-
export
|
|
15
|
+
export * from './virtual-rule.js';
|
|
16
|
+
export type { AccessibilityProperties } from './ml-dom/node/types.js';
|
package/lib/index.js
CHANGED
|
@@ -8,6 +8,6 @@ export * from './ml-dom/index.js';
|
|
|
8
8
|
export * from './ml-rule/index.js';
|
|
9
9
|
export * from './plugin/index.js';
|
|
10
10
|
export * from './test/index.js';
|
|
11
|
-
export * from './types.js';
|
|
12
11
|
export * from './utils/index.js';
|
|
13
12
|
export * from './violation-collector.js';
|
|
13
|
+
export * from './virtual-rule.js';
|
package/lib/ml-core.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export type MLCoreParams = {
|
|
|
22
22
|
*/
|
|
23
23
|
export declare class MLCore {
|
|
24
24
|
#private;
|
|
25
|
-
constructor({ parser, sourceCode, ruleset, rules, locale, schemas, parserOptions, severity, pretenders, filename, debug, configErrors, }: MLCoreParams);
|
|
25
|
+
constructor({ parser, sourceCode, ruleset, rules, locale, schemas, ruleCommonSettings, parserOptions, severity, pretenders, filename, debug, configErrors, }: MLCoreParams);
|
|
26
26
|
/**
|
|
27
27
|
* The parsed document, or a {@link ParserError} if parsing failed.
|
|
28
28
|
*/
|