@markuplint/ml-spec 4.10.1 → 4.18.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 +253 -0
- package/ARCHITECTURE.md +253 -0
- package/CHANGELOG.md +16 -2
- package/README.md +4 -186
- package/SKILL.md +116 -0
- package/docs/aria-algorithms.ja.md +651 -0
- package/docs/aria-algorithms.md +651 -0
- package/docs/html-algorithms.ja.md +469 -0
- package/docs/html-algorithms.md +469 -0
- package/docs/maintenance.ja.md +340 -0
- package/docs/maintenance.md +340 -0
- package/docs/spec-resolution.ja.md +540 -0
- package/docs/spec-resolution.md +551 -0
- package/docs/type-definitions.ja.md +561 -0
- package/docs/type-definitions.md +561 -0
- package/lib/algorithm/aria/accname-computation.d.ts +7 -0
- package/lib/algorithm/aria/accname-computation.js +7 -0
- package/lib/algorithm/aria/aria-specs.d.ts +7 -0
- package/lib/algorithm/aria/aria-specs.js +7 -0
- package/lib/algorithm/aria/get-aria.d.ts +12 -0
- package/lib/algorithm/aria/get-aria.js +12 -0
- package/lib/algorithm/aria/get-computed-aria-props.d.ts +22 -0
- package/lib/algorithm/aria/get-computed-aria-props.js +10 -0
- package/lib/algorithm/aria/get-computed-role.d.ts +12 -0
- package/lib/algorithm/aria/get-computed-role.js +12 -0
- package/lib/algorithm/aria/get-implicit-role.d.ts +18 -0
- package/lib/algorithm/aria/get-implicit-role.js +18 -0
- package/lib/algorithm/aria/get-permitted-roles.d.ts +9 -0
- package/lib/algorithm/aria/get-permitted-roles.js +9 -0
- package/lib/algorithm/aria/get-role-spec.d.ts +11 -0
- package/lib/algorithm/aria/get-role-spec.js +11 -0
- package/lib/algorithm/aria/has-required-owned-elements.d.ts +23 -0
- package/lib/algorithm/aria/has-required-owned-elements.js +23 -0
- package/lib/algorithm/aria/is-exposed.d.ts +7 -4
- package/lib/algorithm/aria/is-exposed.js +7 -4
- package/lib/algorithm/aria/is-presentational.d.ts +8 -0
- package/lib/algorithm/aria/is-presentational.js +8 -0
- package/lib/algorithm/aria/matches-context-role.d.ts +11 -0
- package/lib/algorithm/aria/matches-context-role.js +11 -0
- package/lib/algorithm/html/content-model-category-to-tag-names.d.ts +9 -0
- package/lib/algorithm/html/content-model-category-to-tag-names.js +9 -0
- package/lib/algorithm/html/get-content-model.d.ts +12 -1
- package/lib/algorithm/html/get-content-model.js +9 -0
- package/lib/algorithm/html/get-selectors-by-content-model-category.d.ts +8 -0
- package/lib/algorithm/html/get-selectors-by-content-model-category.js +8 -0
- package/lib/algorithm/html/is-nothing-content-model.d.ts +7 -0
- package/lib/algorithm/html/is-nothing-content-model.js +7 -0
- package/lib/algorithm/html/is-palpable-elements.d.ts +13 -0
- package/lib/algorithm/html/is-palpable-elements.js +13 -0
- package/lib/algorithm/html/is-void-element.d.ts +9 -0
- package/lib/algorithm/html/is-void-element.js +9 -0
- package/lib/algorithm/html/may-be-focusable.d.ts +10 -0
- package/lib/algorithm/html/may-be-focusable.js +10 -0
- package/lib/types/index.d.ts +54 -0
- package/lib/utils/aria-version.d.ts +6 -0
- package/lib/utils/aria-version.js +6 -0
- package/lib/utils/get-attr-specs-spec.d.ts +18 -0
- package/lib/utils/get-attr-specs-spec.js +18 -0
- package/lib/utils/get-attr-specs.d.ts +9 -0
- package/lib/utils/get-attr-specs.js +9 -0
- package/lib/utils/get-spec-by-tag-name.d.ts +11 -0
- package/lib/utils/get-spec-by-tag-name.js +11 -0
- package/lib/utils/get-spec.d.ts +10 -0
- package/lib/utils/get-spec.js +10 -0
- package/lib/utils/resolve-namespace.d.ts +13 -0
- package/lib/utils/resolve-namespace.js +10 -0
- package/lib/utils/schema-to-spec.d.ts +5 -2
- package/lib/utils/schema-to-spec.js +11 -6
- package/lib/utils/validate-aria-version.d.ts +7 -0
- package/lib/utils/validate-aria-version.js +7 -0
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -126,195 +126,13 @@ yarn add @markuplint/ml-spec
|
|
|
126
126
|
- "HTML Schema" and "Specs" are used interchangeably in markuplint to mean the JSON Schema that
|
|
127
127
|
describes HTML element specs (attributes, ARIA, content models, etc) and their TypeScript types.
|
|
128
128
|
|
|
129
|
-
###
|
|
129
|
+
### Contributing
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
For schema editing workflows, generation commands, common recipes, dependency management, and troubleshooting, see the [Maintenance Guide](docs/maintenance.md).
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
`AttributeJSON`/`GlobalAttributes` (because `attributes.schema.json` is generated).
|
|
135
|
-
- ARIA schema shape: edit `schemas/aria.schema.json`.
|
|
136
|
-
- Content model schema shape: edit `schemas/content-models.schema.json`.
|
|
137
|
-
- Element schema aggregator: edit `schemas/element.schema.json` (it composes refs to the above).
|
|
138
|
-
- Global attribute categories/sets: edit `gen/global-attribute.data.*`, then regenerate via the commands below.
|
|
133
|
+
For schema merging and spec extension details, see [Spec Resolution](docs/spec-resolution.md).
|
|
139
134
|
|
|
140
|
-
|
|
141
|
-
entries), update `@markuplint/html-spec` (and, if necessary, `@markuplint/spec-generator`).
|
|
142
|
-
|
|
143
|
-
2. Regenerate schemas and types
|
|
144
|
-
|
|
145
|
-
From the repository root (recommended):
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
yarn up:schema
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
or only for this package:
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
yarn workspace @markuplint/ml-spec run schema
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
This will:
|
|
158
|
-
|
|
159
|
-
- Run `gen/gen.ts` to output `global-attributes.schema.json` and `attributes.schema.json`
|
|
160
|
-
- Convert JSON Schema to TypeScript via `json2ts` into `src/types/*.ts`
|
|
161
|
-
- Format with Prettier and ESLint
|
|
162
|
-
|
|
163
|
-
#### What `yarn up:schema` does
|
|
164
|
-
|
|
165
|
-
From the repository root, this executes schema maintenance across packages in order:
|
|
166
|
-
|
|
167
|
-
1. `@markuplint/types`
|
|
168
|
-
|
|
169
|
-
- Run `gen/types.ts` to build `types.schema.json` from css-tree keywords/types and
|
|
170
|
-
`gen/specific-schema.json`
|
|
171
|
-
- Generate TypeScript types: `types.schema.json` → `src/types.schema.ts` (via `json2ts`)
|
|
172
|
-
- Format (`prettier`/`eslint`) and build the package
|
|
173
|
-
|
|
174
|
-
2. `@markuplint/ml-spec` (this package)
|
|
175
|
-
|
|
176
|
-
- Run `gen/gen.ts` to output `schemas/global-attributes.schema.json` and `schemas/attributes.schema.json`
|
|
177
|
-
- Generate TypeScript types from schemas:
|
|
178
|
-
- `schemas/content-models.schema.json` → `src/types/permitted-structures.ts`
|
|
179
|
-
- `schemas/attributes.schema.json` → `src/types/attributes.ts`
|
|
180
|
-
- `schemas/aria.schema.json` → `src/types/aria.ts`
|
|
181
|
-
- Format (`prettier`/`eslint`)
|
|
182
|
-
|
|
183
|
-
Dependency note: `schemas/attributes.schema.json` references
|
|
184
|
-
`@markuplint/types/types.schema.json#/definitions/type`. Updating types first ensures references stay
|
|
185
|
-
consistent; `yarn up:schema` takes care of this order.
|
|
186
|
-
|
|
187
|
-
3. Build (optional) and sanity-check
|
|
188
|
-
|
|
189
|
-
```bash
|
|
190
|
-
yarn build
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### Do not edit generated files
|
|
194
|
-
|
|
195
|
-
- Do not modify files under `src/types/*.ts` or `schemas/attributes.schema.json` directly.
|
|
196
|
-
Change the source schema or generator instead and re-run the generation scripts.
|
|
197
|
-
|
|
198
|
-
### How schema merging works (Specs extension)
|
|
199
|
-
|
|
200
|
-
At runtime, markuplint can merge multiple specs. The merger in
|
|
201
|
-
`src/utils/schema-to-spec.ts` follows these rules:
|
|
202
|
-
|
|
203
|
-
- `def.#globalAttrs.#extends` from an extended spec augments the base `#HTMLGlobalAttrs` map.
|
|
204
|
-
- For a given element, if both base and extended specs define the same attribute, the extended spec
|
|
205
|
-
wins on conflicting fields (shallow override per attribute). Arrays like `categories` are merged.
|
|
206
|
-
|
|
207
|
-
This enables framework-specific specs (Vue/React/Svelte, etc.) to extend the HTML spec safely.
|
|
208
|
-
|
|
209
|
-
### Relationship to @markuplint/types
|
|
210
|
-
|
|
211
|
-
- Attribute value types (CSS keywords, extended types such as `URL`, `JSON`, etc.) are defined in
|
|
212
|
-
`@markuplint/types` and exposed via `types.schema.json`.
|
|
213
|
-
- If you need a new attribute value type, modify `@markuplint/types` (e.g.
|
|
214
|
-
`packages/@markuplint/types/gen/specific-schema.json`) and regenerate that package first. Then
|
|
215
|
-
regenerate this package so references stay consistent.
|
|
216
|
-
|
|
217
|
-
### Versioning policy
|
|
218
|
-
|
|
219
|
-
- HTML Schema/Specs are not part of the public API surface of markuplint. Changes here are treated
|
|
220
|
-
as a minor release. Publishing is handled by Lerna during the normal release process.
|
|
221
|
-
|
|
222
|
-
### Common tasks (quick recipes)
|
|
223
|
-
|
|
224
|
-
- Add a new global attribute category or items
|
|
225
|
-
- Edit `gen/global-attribute.data.*`
|
|
226
|
-
- Run the generation script (see above)
|
|
227
|
-
|
|
228
|
-
- Add a new optional field to `AttributeJSON`
|
|
229
|
-
- Update the shape in `gen/gen.ts` under `AttributeJSON`
|
|
230
|
-
- Regenerate and ensure the new field appears in `schemas/attributes.schema.json` and in
|
|
231
|
-
`src/types/attributes.ts`
|
|
232
|
-
|
|
233
|
-
- Adjust ARIA fields (e.g., `permittedRoles` variants)
|
|
234
|
-
- Edit `schemas/aria.schema.json`
|
|
235
|
-
- Regenerate types via the schema scripts
|
|
236
|
-
|
|
237
|
-
### Content model quick reference
|
|
238
|
-
|
|
239
|
-
Content models describe allowed children for each element. See the JSON Schema
|
|
240
|
-
`schemas/content-models.schema.json` and the generated TS types `src/types/permitted-structures.ts`.
|
|
241
|
-
Also refer to the website docs: [Rule: permitted-contents](https://markuplint.dev/rules/permitted-contents).
|
|
242
|
-
|
|
243
|
-
- Basic categories (strings): `"#flow"`, `"#phrasing"`, `"#interactive"`, …
|
|
244
|
-
- Model item forms:
|
|
245
|
-
- `require` | `optional` | `oneOrMore` | `zeroOrMore`: a string, category, or nested patterns
|
|
246
|
-
- `choice`: 2–5 alternative pattern arrays
|
|
247
|
-
- `transparent`: inherits parent model filtered by selector string
|
|
248
|
-
|
|
249
|
-
Examples:
|
|
250
|
-
|
|
251
|
-
```json
|
|
252
|
-
{
|
|
253
|
-
"contentModel": {
|
|
254
|
-
"contents": [{ "require": "#phrasing" }, { "optional": [{ "oneOrMore": "#interactive" }] }]
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
Transparent selector syntax
|
|
260
|
-
|
|
261
|
-
- A CSS-like selector string with an extra pseudo: `:model(<CATEGORY>)`
|
|
262
|
-
- You can combine standard selectors: type, class, id, attribute selectors, `:not(...)`, `:has(...)`,
|
|
263
|
-
combinators, etc.
|
|
264
|
-
- `:model(<CATEGORY>)` matches any element belonging to the specified content category.
|
|
265
|
-
|
|
266
|
-
Examples:
|
|
267
|
-
|
|
268
|
-
```text
|
|
269
|
-
:not(:model(interactive))
|
|
270
|
-
:has(:model(interactive), a, [tabindex])
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
SVG categories
|
|
274
|
-
|
|
275
|
-
The following categories are available for SVG elements (see `schemas/content-models.schema.json`):
|
|
276
|
-
|
|
277
|
-
- `#SVGAnimation`
|
|
278
|
-
- `#SVGBasicShapes`
|
|
279
|
-
- `#SVGContainer`
|
|
280
|
-
- `#SVGDescriptive`
|
|
281
|
-
- `#SVGFilterPrimitive`
|
|
282
|
-
- `#SVGFont`
|
|
283
|
-
- `#SVGGradient`
|
|
284
|
-
- `#SVGGraphics`
|
|
285
|
-
- `#SVGGraphicsReferencing`
|
|
286
|
-
- `#SVGLightSource`
|
|
287
|
-
- `#SVGNeverRendered`
|
|
288
|
-
- `#SVGNone`
|
|
289
|
-
- `#SVGPaintServer`
|
|
290
|
-
- `#SVGRenderable`
|
|
291
|
-
- `#SVGShape`
|
|
292
|
-
- `#SVGStructural`
|
|
293
|
-
- `#SVGStructurallyExternal`
|
|
294
|
-
- `#SVGTextContent`
|
|
295
|
-
- `#SVGTextContentChild`
|
|
296
|
-
|
|
297
|
-
```json
|
|
298
|
-
{
|
|
299
|
-
"contentModel": {
|
|
300
|
-
"contents": [{ "choice": [[{ "oneOrMore": "#flow" }], [{ "require": "#phrasing" }]] }]
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
```json
|
|
306
|
-
{
|
|
307
|
-
"contentModel": {
|
|
308
|
-
"contents": [{ "transparent": ":not(:model(interactive))" }],
|
|
309
|
-
"conditional": [
|
|
310
|
-
{
|
|
311
|
-
"condition": "[type=button]",
|
|
312
|
-
"contents": [{ "require": "#phrasing" }]
|
|
313
|
-
}
|
|
314
|
-
]
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
```
|
|
135
|
+
For content model categories and pattern format, see [HTML Algorithms](docs/html-algorithms.md).
|
|
318
136
|
|
|
319
137
|
### License
|
|
320
138
|
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Verify documentation claims against web standards and source code
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# verify-docs
|
|
6
|
+
|
|
7
|
+
Verify that documentation claims in `@markuplint/ml-spec` are accurate by cross-referencing them against official web standards (WAI-ARIA, HTML-AAM, SVG-AAM, AccName, HTML Living Standard) and the actual source code implementation.
|
|
8
|
+
|
|
9
|
+
## Input
|
|
10
|
+
|
|
11
|
+
`$ARGUMENTS` specifies the target: a package name (e.g., `@markuplint/ml-spec`) or a specific documentation file path. If omitted, defaults to all `docs/*.md` files in `packages/@markuplint/ml-spec/`.
|
|
12
|
+
|
|
13
|
+
## Phase 1: Discovery
|
|
14
|
+
|
|
15
|
+
Read all target documentation files and extract every claim that references an external specification. Look for:
|
|
16
|
+
|
|
17
|
+
- Specification URLs (e.g., `https://www.w3.org/TR/wai-aria-1.2/...`, `https://html.spec.whatwg.org/...`)
|
|
18
|
+
- WAI-ARIA algorithm descriptions (role computation, presentational conflict resolution)
|
|
19
|
+
- HTML-AAM implicit role mappings
|
|
20
|
+
- SVG-AAM accessibility tree inclusion rules
|
|
21
|
+
- AccName computation references
|
|
22
|
+
- Content model category claims (element counts, category membership)
|
|
23
|
+
- Specific numeric claims (e.g., "13 void elements", "11 error codes")
|
|
24
|
+
- Function behavior claims ("returns X when Y")
|
|
25
|
+
- Statements like "Implements the X spec" or "according to Y specification"
|
|
26
|
+
|
|
27
|
+
Collect each claim as a structured item:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
{ file, line, claim, specDomain, specURL }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Phase 2: Categorize
|
|
34
|
+
|
|
35
|
+
Group extracted claims by specification domain:
|
|
36
|
+
|
|
37
|
+
| Domain | Examples |
|
|
38
|
+
| ------------- | ------------------------------------------------------------------------------ |
|
|
39
|
+
| WAI-ARIA | Role computation, presentational roles conflict resolution, accessibility tree |
|
|
40
|
+
| HTML-AAM | Implicit role mappings, permitted roles, ARIA property defaults |
|
|
41
|
+
| AccName | Accessible name computation algorithm, placeholder fallback |
|
|
42
|
+
| SVG-AAM | SVG element inclusion rules, graphics ARIA roles |
|
|
43
|
+
| HTML Standard | Content models, void elements, interactive content, palpable content |
|
|
44
|
+
|
|
45
|
+
## Phase 3: Parallel Verification
|
|
46
|
+
|
|
47
|
+
For each domain group, launch a parallel agent using the **Task tool** with `subagent_type: "general-purpose"`. Each agent:
|
|
48
|
+
|
|
49
|
+
1. **Searches the official specification** using WebSearch to find the authoritative definition
|
|
50
|
+
2. **Compares the documentation claim** against the spec definition
|
|
51
|
+
3. **Reads the corresponding source code** to confirm the implementation matches
|
|
52
|
+
4. **Assigns a verdict** to each claim:
|
|
53
|
+
- **PASS** — Documentation accurately describes the spec and matches the implementation
|
|
54
|
+
- **FAIL** — Documentation is inaccurate (wrong number, incorrect algorithm, misleading description)
|
|
55
|
+
- **WARN** — Documentation is technically correct but potentially misleading or incomplete
|
|
56
|
+
|
|
57
|
+
Each agent returns its results as a structured list:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
| # | File:Line | Claim | Spec Source | Verdict | Notes |
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Phase 4: Report
|
|
64
|
+
|
|
65
|
+
Collect results from all parallel agents and produce a consolidated PASS/FAIL table:
|
|
66
|
+
|
|
67
|
+
```markdown
|
|
68
|
+
## Verification Report
|
|
69
|
+
|
|
70
|
+
| # | Domain | File:Line | Claim Summary | Verdict | Notes |
|
|
71
|
+
| --- | ------------- | ---------------------- | ----------------------------- | ------- | -------------------------------------- |
|
|
72
|
+
| 1 | WAI-ARIA | aria-algorithms.md:125 | 11 RoleComputationError codes | PASS | Matches source types/index.ts |
|
|
73
|
+
| 2 | HTML Standard | html-algorithms.md:45 | 13 void elements | PASS | Matches is-void-element.ts Set |
|
|
74
|
+
| 3 | HTML-AAM | aria-algorithms.md:200 | getImplicitRole returns false | WARN | Returns ImplicitRole (false or string) |
|
|
75
|
+
| ... | ... | ... | ... | ... | ... |
|
|
76
|
+
|
|
77
|
+
**Summary:** X PASS / Y FAIL / Z WARN out of N total claims
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Phase 5: Correction Plan
|
|
81
|
+
|
|
82
|
+
For every FAIL item, produce a concrete correction instruction:
|
|
83
|
+
|
|
84
|
+
```markdown
|
|
85
|
+
### Correction 1: [Brief description]
|
|
86
|
+
|
|
87
|
+
- **File:** `path/to/file.md`
|
|
88
|
+
- **Line:** 125
|
|
89
|
+
- **Current:** `(11 error codes)`
|
|
90
|
+
- **Corrected:** `(12 error codes)`
|
|
91
|
+
- **Reason:** Source code `types/index.ts` contains 12 entries in `RoleComputationError` union
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
For WARN items, produce an advisory note with a suggested improvement (not mandatory).
|
|
95
|
+
|
|
96
|
+
## Rules
|
|
97
|
+
|
|
98
|
+
1. **Source code is the source of truth for implementation behavior.** If the docs say "implements X" but the code does something slightly different, the docs should be corrected to accurately describe what the code does.
|
|
99
|
+
2. **Specification is the source of truth for what the standard defines.** If the code intentionally deviates from the spec, the docs should note the deviation explicitly.
|
|
100
|
+
3. **Code bugs are a separate category.** If the code itself doesn't match the spec, flag it as a code issue (not a documentation issue) and note it separately.
|
|
101
|
+
4. **Numeric claims must be exact.** Count arrays, enum values, union members, and Set entries in the source code to verify numbers stated in documentation.
|
|
102
|
+
5. **Algorithm descriptions must match the actual code flow.** Verify that documented step orders, condition checks, and branching logic correspond to the implementation.
|
|
103
|
+
6. **Use WebSearch for spec verification.** Always fetch the latest version of the referenced specification — do not rely on cached knowledge.
|
|
104
|
+
|
|
105
|
+
## Hardcoded Test Data
|
|
106
|
+
|
|
107
|
+
The following test files contain hardcoded spec data that must stay in sync
|
|
108
|
+
with `@markuplint/html-spec`:
|
|
109
|
+
|
|
110
|
+
| Test file | Data | Trigger |
|
|
111
|
+
| ----------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------- |
|
|
112
|
+
| `src/algorithm/aria/get-permitted-roles-spec.spec.ts` | `permittedRoles` arrays for img, button, input, form, etc. | `permittedRoles` changes in `html-spec/src/spec.*.json` |
|
|
113
|
+
|
|
114
|
+
When `@markuplint/html-spec` ARIA mappings change, update these arrays.
|
|
115
|
+
The arrays are version-specific — update only the correct version's expectations
|
|
116
|
+
(e.g., `'1.2'` tests but not `'1.1'` tests for newly added roles).
|