@markuplint/html-spec 5.0.0-rc.2 → 5.0.0-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,570 +0,0 @@
1
- # Element Specification Format
2
-
3
- This document is a comprehensive reference for the JSON element specification file format
4
- used by `@markuplint/html-spec`. It covers file naming conventions, the full structure of
5
- element spec files, content model patterns, attribute definitions, ARIA integration, and
6
- the shared common files.
7
-
8
- ## File Naming Conventions
9
-
10
- ### HTML Elements
11
-
12
- Pattern: `src/spec.<tag>.jsonc` (e.g., `spec.div.jsonc`, `spec.table.jsonc`, `spec.input.jsonc`)
13
-
14
- ### SVG Elements
15
-
16
- Pattern: `src/spec.svg_<local>.jsonc` (e.g., `spec.svg_text.jsonc`, `spec.svg_circle.jsonc`)
17
-
18
- The local name preserves case (`svg_animateMotion.jsonc`). The element name is inferred
19
- at runtime as `svg:<local>` (e.g., `svg:text`, `svg:clipPath`).
20
-
21
- ### MathML Elements
22
-
23
- Pattern: `src/spec.mml_<local>.jsonc` (e.g., `spec.mml_math.jsonc`, `spec.mml_mfrac.jsonc`)
24
-
25
- The element name is inferred at runtime as `mml:<local>` (e.g., `mml:math`, `mml:mfrac`).
26
-
27
- ### Common Files
28
-
29
- - `spec-common.attributes.jsonc` -- Global attribute category definitions (20 categories)
30
- - `spec-common.contents.jsonc` -- Content model category macros
31
-
32
- ### JSON with Comments
33
-
34
- All spec files use the JSONC format (`.jsonc`) and support JavaScript-style comments (`//` and `/* */`) via `jsonc-parser`.
35
- Use comments to link to specification URLs at the top of each file:
36
-
37
- ```json
38
- // https://html.spec.whatwg.org/multipage/grouping-content.html#the-p-element
39
- // https://www.w3.org/TR/html-aria/#el-p
40
- { ... }
41
- ```
42
-
43
- ## Top-Level Structure
44
-
45
- Each element spec file is a JSON object with four required top-level fields:
46
-
47
- | Field | Type | Description |
48
- | -------------- | ------ | -------------------------------------- |
49
- | `contentModel` | object | Permitted content rules |
50
- | `globalAttrs` | object | Global attribute category inclusions |
51
- | `attributes` | object | Element-specific attribute definitions |
52
- | `aria` | object | ARIA role and property integration |
53
-
54
- An optional `omission` field may appear in the compiled `index.json` output. It is set
55
- from MDN data during the build process and is not authored manually in spec files.
56
-
57
- ## Content Model
58
-
59
- The `contentModel` object defines what children an element may contain.
60
-
61
- ### `contentModel.contents`
62
-
63
- Accepts one of three forms:
64
-
65
- - `false` -- Void element; no children allowed (e.g., `<input>`, `<br>`)
66
- - `true` -- Any content allowed (used for certain obsolete elements)
67
- - An array of content model patterns (see below)
68
-
69
- ### `contentModel.conditional`
70
-
71
- An optional array of context-dependent content model overrides. Each entry has a
72
- `condition` (CSS selector) and `contents` (array of patterns). When matched, the
73
- conditional content model replaces the default:
74
-
75
- ```json
76
- "conditional": [{
77
- "condition": "dl > div",
78
- "contents": [{
79
- "oneOrMore": [
80
- { "zeroOrMore": ":model(script-supporting)" },
81
- { "oneOrMore": "dt" },
82
- { "zeroOrMore": ":model(script-supporting)" },
83
- { "oneOrMore": "dd" },
84
- { "zeroOrMore": ":model(script-supporting)" }
85
- ]
86
- }]
87
- }]
88
- ```
89
-
90
- ### Cross-Package Relationships
91
-
92
- The content model definitions in these JSON files are part of a larger ecosystem:
93
-
94
- - **Schema validation** -- `@markuplint/ml-spec` provides `content-models.schema.json` which defines the valid structure of content model patterns (`require`, `optional`, `oneOrMore`, `zeroOrMore`, `choice`, `transparent`). Source JSON files are validated against this schema in tests.
95
- - **TypeScript types** -- `@markuplint/ml-spec` auto-generates `ContentModel`, `PermittedContentPattern`, and `Category` types from the schema (in `types/permitted-structures.ts`), enabling type-safe access throughout the codebase.
96
- - **Runtime algorithms** -- `@markuplint/ml-spec` provides `getContentModel()` which evaluates conditional content models at runtime, and `contentModelCategoryToTagNames()` which resolves category names (e.g., `#flow`) to concrete element lists using `def["#contentModels"]` from this package's `spec-common.contents.jsonc`.
97
- - **Lint rules** -- `@markuplint/rules` uses these definitions in the `permitted-contents` rule (validates element children against content model patterns) and the `no-empty-palpable-content` rule (uses `#palpable` category data to detect empty palpable elements).
98
-
99
- ## Content Model Patterns
100
-
101
- Each pattern uses exactly one key to describe cardinality or composition.
102
-
103
- ### Cardinality Patterns
104
-
105
- | Pattern | Meaning |
106
- | -------------------------------- | ---------------------------- |
107
- | `{ "require": "<selector>" }` | Exactly one required element |
108
- | `{ "optional": "<selector>" }` | Zero or one element |
109
- | `{ "oneOrMore": "<selector>" }` | One or more elements |
110
- | `{ "zeroOrMore": "<selector>" }` | Zero or more elements |
111
-
112
- The `oneOrMore` and `zeroOrMore` patterns also accept an array of nested patterns to
113
- describe a sequence (see the `<div>` conditional example above).
114
-
115
- ### Composition Patterns
116
-
117
- | Pattern | Meaning |
118
- | --------------------------------- | -------------------------------------------------------------- |
119
- | `{ "choice": [...] }` | One of the given options (each option is an array of patterns) |
120
- | `{ "transparent": "<selector>" }` | Transparent content model with an exclusion selector |
121
-
122
- The `choice` pattern contains an array of arrays. The `transparent` pattern means the
123
- element inherits its parent's content model, excluding elements matching the selector.
124
-
125
- ### Selector Syntax
126
-
127
- | Selector | Description |
128
- | -------------------------------------- | --------------------------- |
129
- | `"dt"`, `"li"`, `"div"` | Tag names |
130
- | `":model(flow)"`, `":model(phrasing)"` | Content category references |
131
- | `":not(:model(interactive), a)"` | Negation pseudo-class |
132
- | `":has(:model(interactive))"` | Has pseudo-class |
133
- | `"#text"` | Text nodes |
134
- | `"#custom"` | Custom elements |
135
- | `"svg\|a"`, `"svg\|circle"` | SVG namespace elements |
136
- | `"mml\|mi"`, `"mml\|mn"` | MathML namespace elements |
137
- | `"link[itemprop]"` | Attribute selectors |
138
-
139
- ## Global Attributes
140
-
141
- The `globalAttrs` object maps category names (prefixed with `#`) to inclusion rules:
142
-
143
- | Value | Meaning |
144
- | ---------- | ---------------------------------------------------- |
145
- | `true` | Include all attributes from the category |
146
- | `false` | Exclude the category entirely |
147
- | `string[]` | Include only the listed attributes from the category |
148
-
149
- ```json
150
- "globalAttrs": {
151
- "#HTMLGlobalAttrs": true,
152
- "#GlobalEventAttrs": true,
153
- "#ARIAAttrs": true,
154
- "#HTMLLinkAndFetchingAttrs": ["href", "target", "download", "ping", "rel"]
155
- }
156
- ```
157
-
158
- ### Available Categories (20)
159
-
160
- | Category | Description |
161
- | ----------------------------------- | ------------------------------------------------------------------- |
162
- | `#HTMLGlobalAttrs` | Standard HTML global attributes (accesskey, class, id, style, etc.) |
163
- | `#GlobalEventAttrs` | Event handler attributes (onclick, onload, onfocus, etc.) |
164
- | `#ARIAAttrs` | ARIA attributes (aria-\*, role) |
165
- | `#HTMLLinkAndFetchingAttrs` | Link and fetch attributes (href, target, download, etc.) |
166
- | `#HTMLEmbededAndMediaContentAttrs` | Embedded content attributes (src, height, width, etc.) |
167
- | `#HTMLFormControlElementAttrs` | Form control attributes (autocomplete, disabled, name, etc.) |
168
- | `#HTMLTableCellElementAttrs` | Table cell attributes (colspan, rowspan, headers, etc.) |
169
- | `#SVGAnimationAdditionAttrs` | SVG animation addition attributes |
170
- | `#SVGAnimationAttributeTargetAttrs` | SVG animation attribute target attributes |
171
- | `#SVGAnimationEventAttrs` | SVG animation event attributes |
172
- | `#SVGAnimationTargetElementAttrs` | SVG animation target element attributes |
173
- | `#SVGAnimationTimingAttrs` | SVG animation timing attributes |
174
- | `#SVGAnimationValueAttrs` | SVG animation value attributes |
175
- | `#SVGConditionalProcessingAttrs` | SVG conditional processing attributes |
176
- | `#SVGCoreAttrs` | SVG core attributes (id, tabindex, lang, class, style, etc.) |
177
- | `#SVGFilterPrimitiveAttrs` | SVG filter primitive attributes |
178
- | `#SVGPresentationAttrs` | SVG presentation attributes (fill, stroke, transform, etc.) |
179
- | `#SVGTransferFunctionAttrs` | SVG transfer function attributes |
180
- | `#XLinkAttrs` | XLink attributes (deprecated) |
181
- | `#MathMLGlobalAttrs` | MathML global attributes (dir, displaystyle, mathcolor, etc.) |
182
-
183
- ## Element-Specific Attributes
184
-
185
- The `attributes` object maps attribute names to definitions. Each definition may contain:
186
-
187
- | Field | Type | Description |
188
- | -------------- | -------------------- | ----------------------------------------------- |
189
- | `type` | various | Attribute value type (see below) |
190
- | `condition` | `string \| string[]` | CSS selector(s) for when the attribute is valid |
191
- | `required` | `boolean` | Whether the attribute is required |
192
- | `defaultValue` | `string` | Default value |
193
- | `description` | `string` | Human-readable description |
194
- | `animatable` | `boolean` | Whether the attribute is animatable (SVG) |
195
- | `deprecated` | `boolean` | Deprecated status flag (see below) |
196
- | `obsolete` | `boolean` | Obsolete status flag (see below) |
197
- | `experimental` | `boolean` | Experimental status flag (see below) |
198
- | `nonStandard` | `boolean` | Non-standard status flag (see below) |
199
-
200
- ### Status Flags
201
-
202
- These boolean flags indicate the standardization status of an attribute:
203
-
204
- | Flag | Meaning |
205
- | -------------- | ------------------------------------------------------------------------------------------------------------- |
206
- | `experimental` | Part of an emerging specification that is not yet stable. Browsers may have partial or prefixed support. |
207
- | `deprecated` | Officially discouraged by the specification. Still recognized by browsers but should not be used in new code. |
208
- | `obsolete` | Removed from the specification entirely. May not be recognized by modern browsers at all. |
209
- | `nonStandard` | Not part of any W3C or WHATWG specification. Vendor-specific or proprietary. |
210
-
211
- **`deprecated` vs `obsolete`:** `deprecated` means the spec still defines the attribute
212
- but discourages its use (e.g., `<table border>`). `obsolete` means the attribute has been
213
- removed from the specification altogether (e.g., legacy presentational attributes on
214
- elements that have been fully obsoleted). In practice, `deprecated` attributes usually
215
- still work in browsers, while `obsolete` attributes may not.
216
-
217
- **Flag precedence (spec > MDN):** When a flag is set in the manual spec file
218
- (`src/spec.*.jsonc`), it takes precedence over the MDN-scraped value. This allows you to
219
- correct cases where MDN data is inaccurate or lagging behind the specification. Flags
220
- from MDN are used only when the manual spec does not define the attribute or does not
221
- set that particular flag.
222
-
223
- **When to set flags manually:**
224
-
225
- - MDN flags an attribute as `experimental` but the spec has stabilized it -- set
226
- `"experimental": false` (or omit it) in the spec file to override
227
- - An attribute is deprecated in the spec but MDN has not yet updated -- set
228
- `"deprecated": true` in the spec file
229
- - A vendor-specific attribute needs to be marked -- set `"nonStandard": true`
230
-
231
- ### Attribute Value Types
232
-
233
- **Simple string types:**
234
-
235
- `"String"`, `"URL"`, `"Boolean"`, `"DOMID"`, `"Any"`, `"Number"`, `"Pattern"`,
236
- `"OneLineAny"`, `"CustomElementName"`, `"DateTime"`
237
-
238
- **Enumerated type:**
239
-
240
- ```json
241
- {
242
- "enum": ["hidden", "text", "search"],
243
- "invalidValueDefault": "text",
244
- "missingValueDefault": "text",
245
- "caseInsensitive": true,
246
- "disallowToSurroundBySpaces": true,
247
- "sameStates": { "none": ["off"] }
248
- }
249
- ```
250
-
251
- | Field | Description |
252
- | ---------------------------- | ------------------------------------------- |
253
- | `enum` | Array of allowed string values |
254
- | `invalidValueDefault` | Default state when the value is invalid |
255
- | `missingValueDefault` | Default state when the attribute is missing |
256
- | `caseInsensitive` | Whether matching is case-insensitive |
257
- | `disallowToSurroundBySpaces` | Whether surrounding spaces are disallowed |
258
- | `sameStates` | Maps canonical values to their aliases |
259
-
260
- **Token list type:**
261
-
262
- ```json
263
- { "token": "Accept", "separator": "comma", "unique": true, "caseInsensitive": true }
264
- ```
265
-
266
- | Field | Description |
267
- | ----------------- | ----------------------------------------------------------------------- |
268
- | `token` | Token type: a string (type name) or an object with `enum` (inline enum) |
269
- | `separator` | `"space"` or `"comma"` |
270
- | `unique` | Whether tokens must be unique |
271
- | `caseInsensitive` | Whether matching is case-insensitive |
272
- | `ordered` | Whether order matters |
273
- | `number` | Cardinality: `"zeroOrMore"`, `"oneOrMore"`, etc. |
274
-
275
- When `token` is a string, it references a named type (e.g., `"Accept"`, `"DOMID"`).
276
- When `token` is an object with `enum`, it defines an inline set of allowed keywords:
277
-
278
- ```json
279
- {
280
- "token": { "enum": ["allow-forms", "allow-scripts", "allow-popups"] },
281
- "separator": "space",
282
- "unique": true
283
- }
284
- ```
285
-
286
- **Number constraint type:**
287
-
288
- ```json
289
- { "type": "integer", "gt": 0 }
290
- ```
291
-
292
- Fields: `type` (`"integer"` or `"float"`), `gt`, `gte`, `lt`, `lte` for bounds.
293
-
294
- **Union type (array):** Multiple valid types -- `["DateTime", "Number"]` or
295
- `["<svg-length>", "<percentage>"]`.
296
-
297
- **CSS/SVG value types:** Angle-bracket strings like `"<text-coordinate>"`,
298
- `"<svg-length>"`, `"<percentage>"`, `"<list-of-numbers>"`, `"<number>"`.
299
-
300
- ### Conditional Attributes
301
-
302
- The `condition` field restricts an attribute to specific element states. It accepts a
303
- single CSS selector string or an array. The `i` flag enables case-insensitive matching:
304
-
305
- ```json
306
- "accept": { "type": { "token": "Accept", "separator": "comma" }, "condition": "[type='file' i]" },
307
- "checked": { "type": "Boolean", "condition": ["[type='checkbox' i]", "[type='radio' i]"] }
308
- ```
309
-
310
- ## ARIA Integration
311
-
312
- The `aria` object defines ARIA role and property integration.
313
-
314
- ### Top-Level ARIA Fields
315
-
316
- | Field | Type | Description |
317
- | ------------------ | ------------------------------------- | -------------------------------------- |
318
- | `implicitRole` | `string \| false` | Default ARIA role, or `false` for none |
319
- | `permittedRoles` | `true \| false \| string[] \| object` | Allowed explicit roles |
320
- | `namingProhibited` | `boolean` | Whether accessible name is prohibited |
321
- | `properties` | `object \| false` | ARIA property constraints |
322
- | `conditions` | `object` | Context-dependent ARIA overrides |
323
-
324
- ### Permitted Roles
325
-
326
- - `true` -- Any role is permitted
327
- - `false` -- No explicit roles permitted
328
- - `string[]` -- Specific permitted role names
329
- - Object with AAM references (SVG/MathML): `{ "core-aam": true, "graphics-aam": true }` or `{ "mathml-aam": true }`
330
-
331
- Role entries can also be objects: `{ "name": "directory", "deprecated": true }`.
332
-
333
- ### ARIA Properties
334
-
335
- | Field | Type | Description |
336
- | --------- | ------------------- | -------------------------------- |
337
- | `global` | `boolean` | Include global ARIA properties |
338
- | `role` | `boolean \| string` | Include role-specific properties |
339
- | `without` | `array` | Property restriction rules |
340
-
341
- When `properties` is `false`, no ARIA properties are allowed (e.g., `input[type=hidden]`).
342
-
343
- ### Property Restrictions (`without`)
344
-
345
- | Field | Type | Description |
346
- | ------- | -------- | ---------------------------------------------------- | ------------------------------------ |
347
- | `type` | `string` | `"must-not"`, `"should-not"`, or `"not-recommended"` |
348
- | `name` | `string` | ARIA property name (e.g., `"aria-checked"`) |
349
- | `value` | `string` | Optional: restrict only for this specific value |
350
- | `alt` | `object` | Optional: `{ "method": "set-attr" | "remove-attr", "target": "<attr>" }` |
351
-
352
- ### Conditional ARIA (`conditions`)
353
-
354
- Maps CSS selectors to ARIA overrides. Condition keys use the same CSS selector syntax:
355
-
356
- - `":not([href])"` -- element without `href`
357
- - `"[type='button' i]"` -- input with `type="button"`
358
- - `"dl > div"` -- div as direct child of dl
359
- - `"[type='checkbox' i][aria-pressed]"` -- compound selectors
360
-
361
- ### Version-Specific ARIA Overrides
362
-
363
- Use version keys (`"1.1"`, `"1.2"`) as sibling properties to override ARIA for specific
364
- spec versions. Version overrides can contain their own `conditions` object:
365
-
366
- ```json
367
- "aria": {
368
- "implicitRole": "paragraph",
369
- "permittedRoles": true,
370
- "1.1": { "implicitRole": false }
371
- }
372
- ```
373
-
374
- ## Common Files
375
-
376
- ### spec-common.attributes.jsonc
377
-
378
- Defines the 20 global attribute categories. Each category maps attribute names to
379
- definitions using the same format described in the attributes section.
380
-
381
- ### spec-common.contents.jsonc
382
-
383
- Defines content model category macros referenced via `:model()`. Structure:
384
-
385
- ```json
386
- { "models": { "#metadata": ["base", "link", ...], "#flow": ["a", "abbr", ...], ... } }
387
- ```
388
-
389
- ### Content Model Categories
390
-
391
- **HTML categories (9):**
392
-
393
- | Category | Description |
394
- | -------------------- | ---------------------------------------------------------- |
395
- | `#metadata` | Document metadata elements (base, link, meta, etc.) |
396
- | `#flow` | Most body-level elements |
397
- | `#sectioning` | Section elements (article, aside, nav, section) |
398
- | `#heading` | Heading elements (h1-h6, hgroup) |
399
- | `#phrasing` | Inline-level elements |
400
- | `#embedded` | Embedded content (audio, canvas, embed, iframe, img, etc.) |
401
- | `#interactive` | Interactive elements (a[href], button, details, etc.) |
402
- | `#palpable` | Elements that render visible content |
403
- | `#script-supporting` | Script-supporting elements (script, template) |
404
-
405
- **SVG categories (18):**
406
-
407
- | Category | Description |
408
- | -------------------------- | ----------------------------------------------------------------- |
409
- | `#SVGAnimation` | Animation elements (animate, animateMotion, set, etc.) |
410
- | `#SVGBasicShapes` | Basic shape elements (circle, ellipse, line, polygon, etc.) |
411
- | `#SVGContainer` | Container elements (a, defs, g, marker, svg, symbol, etc.) |
412
- | `#SVGDescriptive` | Descriptive elements (desc, metadata, title) |
413
- | `#SVGFilterPrimitive` | Filter primitive elements (feBlend, feColorMatrix, etc.) |
414
- | `#SVGFont` | Font elements (font, font-face, glyph, etc.) |
415
- | `#SVGGradient` | Gradient elements (linearGradient, radialGradient, stop) |
416
- | `#SVGGraphics` | Graphics elements (circle, image, path, text, use, etc.) |
417
- | `#SVGGraphicsReferencing` | Graphics referencing elements (use) |
418
- | `#SVGLightSource` | Light source elements (feDistantLight, fePointLight, feSpotLight) |
419
- | `#SVGNeverRendered` | Never-rendered elements (clipPath, defs, metadata, etc.) |
420
- | `#SVGPaintServer` | Paint server elements (linearGradient, pattern, etc.) |
421
- | `#SVGRenderable` | Renderable elements (a, circle, g, svg, text, etc.) |
422
- | `#SVGShape` | Shape elements (circle, ellipse, line, path, polygon, etc.) |
423
- | `#SVGStructural` | Structural elements (defs, g, svg, symbol, use) |
424
- | `#SVGStructurallyExternal` | Structurally external elements (currently empty) |
425
- | `#SVGTextContent` | Text content elements (text, textPath, tspan, etc.) |
426
- | `#SVGTextContentChild` | Text content child elements (textPath, tspan, etc.) |
427
-
428
- **MathML categories (3):**
429
-
430
- | Category | Description |
431
- | --------------------- | ------------------------------------------------------------- |
432
- | `#MathMLPresentation` | MathML presentation elements (mi, mn, mo, mfrac, msqrt, etc.) |
433
- | `#MathMLScript` | MathML script elements (msub, msup, msubsup, munder, mover) |
434
- | `#MathMLTabular` | MathML tabular elements (mtable, mtr, mtd) |
435
-
436
- ## Full Examples
437
-
438
- ### Simple HTML Element -- `<p>`
439
-
440
- ```json
441
- // https://html.spec.whatwg.org/multipage/grouping-content.html#the-p-element
442
- {
443
- "contentModel": {
444
- "contents": [{ "oneOrMore": ":model(phrasing)" }]
445
- },
446
- "globalAttrs": {
447
- "#HTMLGlobalAttrs": true,
448
- "#GlobalEventAttrs": true,
449
- "#ARIAAttrs": true
450
- },
451
- "attributes": {},
452
- "aria": {
453
- "implicitRole": "paragraph",
454
- "permittedRoles": true,
455
- "namingProhibited": true,
456
- "1.1": { "implicitRole": false }
457
- }
458
- }
459
- ```
460
-
461
- ### Complex HTML Element -- `<a>`
462
-
463
- ```json
464
- // https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element
465
- {
466
- "contentModel": {
467
- "contents": [
468
- { "transparent": ":not(:model(interactive), a, [tabindex], :has(:model(interactive), a, [tabindex]))" }
469
- ]
470
- },
471
- "globalAttrs": {
472
- "#HTMLGlobalAttrs": true,
473
- "#GlobalEventAttrs": true,
474
- "#ARIAAttrs": true,
475
- "#HTMLLinkAndFetchingAttrs": ["href", "target", "download", "ping", "rel", "hreflang", "type", "referrerpolicy"]
476
- },
477
- "attributes": {},
478
- "aria": {
479
- "implicitRole": "link",
480
- "permittedRoles": ["button", "checkbox", "menuitem", "option", "radio", "switch", "tab", "treeitem"],
481
- "properties": {
482
- "global": true,
483
- "role": true,
484
- "without": [
485
- {
486
- "type": "not-recommended",
487
- "name": "aria-disabled",
488
- "value": "true",
489
- "alt": { "method": "remove-attr", "target": "href" }
490
- }
491
- ]
492
- },
493
- "conditions": {
494
- ":not([href])": { "implicitRole": "generic", "permittedRoles": true, "namingProhibited": true }
495
- },
496
- "1.1": { "conditions": { ":not([href])": { "implicitRole": false } } }
497
- }
498
- }
499
- ```
500
-
501
- ### SVG Element -- `svg:text`
502
-
503
- ```json
504
- // https://svgwg.org/svg2-draft/text.html#TextElement
505
- {
506
- "contentModel": {
507
- "contents": [
508
- {
509
- "zeroOrMore": [
510
- "#text",
511
- ":model(SVGAnimation)",
512
- ":model(SVGDescriptive)",
513
- ":model(SVGPaintServer)",
514
- ":model(SVGTextContentChild)",
515
- "svg|a",
516
- "svg|clipPath",
517
- "svg|marker",
518
- "svg|mask",
519
- "svg|script",
520
- "svg|style"
521
- ]
522
- }
523
- ]
524
- },
525
- "globalAttrs": {
526
- "#HTMLGlobalAttrs": true,
527
- "#GlobalEventAttrs": true,
528
- "#ARIAAttrs": true,
529
- "#SVGConditionalProcessingAttrs": ["requiredExtensions", "systemLanguage"],
530
- "#SVGCoreAttrs": ["id", "tabindex", "autofocus", "lang", "xml:space", "class", "style"],
531
- "#SVGPresentationAttrs": ["alignment-baseline", "fill", "font-size", "stroke", "transform"]
532
- },
533
- "attributes": {
534
- "x": { "type": "<text-coordinate>", "defaultValue": "0", "animatable": true },
535
- "y": { "type": "<text-coordinate>", "defaultValue": "0", "animatable": true },
536
- "textLength": { "type": ["<svg-length>", "<percentage>"], "animatable": true },
537
- "lengthAdjust": {
538
- "type": { "enum": ["spacing", "spacingAndGlyphs"] },
539
- "defaultValue": "spacing",
540
- "animatable": true
541
- }
542
- },
543
- "aria": {
544
- "implicitRole": "group",
545
- "permittedRoles": { "core-aam": true, "graphics-aam": true }
546
- }
547
- }
548
- ```
549
-
550
- ### MathML Element -- `mml:mfrac`
551
-
552
- ```json
553
- // https://w3c.github.io/mathml-core/#fractions-mfrac
554
- {
555
- "contentModel": {
556
- "contents": [{ "oneOrMore": ":model(MathMLPresentation)", "max": 2 }]
557
- },
558
- "globalAttrs": {
559
- "#HTMLGlobalAttrs": true,
560
- "#GlobalEventAttrs": true,
561
- "#ARIAAttrs": true,
562
- "#MathMLGlobalAttrs": true
563
- },
564
- "attributes": {},
565
- "aria": {
566
- "implicitRole": false,
567
- "permittedRoles": { "mathml-aam": true }
568
- }
569
- }
570
- ```