html-validate 8.7.4 → 8.9.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.
Files changed (74) hide show
  1. package/dist/cjs/browser.js +7 -21
  2. package/dist/cjs/browser.js.map +1 -1
  3. package/dist/cjs/cli.js +483 -451
  4. package/dist/cjs/cli.js.map +1 -1
  5. package/dist/cjs/core-browser.js +9 -20
  6. package/dist/cjs/core-browser.js.map +1 -1
  7. package/dist/cjs/core-nodejs.js +203 -297
  8. package/dist/cjs/core-nodejs.js.map +1 -1
  9. package/dist/cjs/core.js +9735 -10454
  10. package/dist/cjs/core.js.map +1 -1
  11. package/dist/cjs/elements.js +2311 -2296
  12. package/dist/cjs/elements.js.map +1 -1
  13. package/dist/cjs/html-validate.js +148 -169
  14. package/dist/cjs/html-validate.js.map +1 -1
  15. package/dist/cjs/html5.js.map +1 -1
  16. package/dist/cjs/index.js +8 -21
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/jest-diff.js +26 -36
  19. package/dist/cjs/jest-diff.js.map +1 -1
  20. package/dist/cjs/jest.js +8 -8
  21. package/dist/cjs/jest.js.map +1 -1
  22. package/dist/cjs/matcher-utils.js +12 -28
  23. package/dist/cjs/matcher-utils.js.map +1 -1
  24. package/dist/cjs/matchers-jestonly.js +38 -47
  25. package/dist/cjs/matchers-jestonly.js.map +1 -1
  26. package/dist/cjs/matchers.js +196 -196
  27. package/dist/cjs/matchers.js.map +1 -1
  28. package/dist/cjs/meta-helper.js +40 -60
  29. package/dist/cjs/meta-helper.js.map +1 -1
  30. package/dist/cjs/test-utils.js +26 -47
  31. package/dist/cjs/test-utils.js.map +1 -1
  32. package/dist/cjs/tsdoc-metadata.json +1 -1
  33. package/dist/cjs/utils/natural-join.js +10 -23
  34. package/dist/cjs/utils/natural-join.js.map +1 -1
  35. package/dist/cjs/vitest.js +6 -6
  36. package/dist/cjs/vitest.js.map +1 -1
  37. package/dist/es/browser.js +2 -2
  38. package/dist/es/cli.js +482 -454
  39. package/dist/es/cli.js.map +1 -1
  40. package/dist/es/core-browser.js +10 -21
  41. package/dist/es/core-browser.js.map +1 -1
  42. package/dist/es/core-nodejs.js +204 -299
  43. package/dist/es/core-nodejs.js.map +1 -1
  44. package/dist/es/core.js +9730 -10455
  45. package/dist/es/core.js.map +1 -1
  46. package/dist/es/elements.js +2311 -2296
  47. package/dist/es/elements.js.map +1 -1
  48. package/dist/es/html-validate.js +150 -171
  49. package/dist/es/html-validate.js.map +1 -1
  50. package/dist/es/html5.js.map +1 -1
  51. package/dist/es/index.js +3 -3
  52. package/dist/es/jest-diff.js +11 -21
  53. package/dist/es/jest-diff.js.map +1 -1
  54. package/dist/es/jest.js +8 -8
  55. package/dist/es/jest.js.map +1 -1
  56. package/dist/es/matcher-utils.js +12 -28
  57. package/dist/es/matcher-utils.js.map +1 -1
  58. package/dist/es/matchers-jestonly.js +39 -48
  59. package/dist/es/matchers-jestonly.js.map +1 -1
  60. package/dist/es/matchers.js +196 -196
  61. package/dist/es/matchers.js.map +1 -1
  62. package/dist/es/meta-helper.js +40 -60
  63. package/dist/es/meta-helper.js.map +1 -1
  64. package/dist/es/test-utils.js +26 -47
  65. package/dist/es/test-utils.js.map +1 -1
  66. package/dist/es/utils/natural-join.js +10 -23
  67. package/dist/es/utils/natural-join.js.map +1 -1
  68. package/dist/es/vitest.js +6 -6
  69. package/dist/es/vitest.js.map +1 -1
  70. package/dist/schema/elements.json +6 -0
  71. package/dist/tsdoc-metadata.json +1 -1
  72. package/dist/types/browser.d.ts +78 -32
  73. package/dist/types/index.d.ts +105 -34
  74. package/package.json +15 -15
@@ -1,2308 +1,2323 @@
1
1
  import { d as defineMetadata, m as metadataHelper } from './meta-helper.js';
2
2
 
3
- /* eslint-disable sonarjs/no-duplicate-string -- easier to read without constants */
4
- const { allowedIfAttributeIsPresent, allowedIfAttributeIsAbsent, allowedIfAttributeHasValue, allowedIfParentIsPresent, } = metadataHelper;
3
+ const {
4
+ allowedIfAttributeIsPresent,
5
+ allowedIfAttributeIsAbsent,
6
+ allowedIfAttributeHasValue,
7
+ allowedIfParentIsPresent
8
+ } = metadataHelper;
5
9
  const validId = "/\\S+/";
6
10
  const ReferrerPolicy = [
7
- "",
8
- "no-referrer",
9
- "no-referrer-when-downgrade",
10
- "same-origin",
11
- "origin",
12
- "strict-origin",
13
- "origin-when-cross-origin",
14
- "strict-origin-when-cross-origin",
15
- "unsafe-url",
11
+ "",
12
+ "no-referrer",
13
+ "no-referrer-when-downgrade",
14
+ "same-origin",
15
+ "origin",
16
+ "strict-origin",
17
+ "origin-when-cross-origin",
18
+ "strict-origin-when-cross-origin",
19
+ "unsafe-url"
16
20
  ];
17
21
  var html5 = defineMetadata({
18
- "*": {
19
- attributes: {
20
- contenteditable: {
21
- omit: true,
22
- enum: ["true", "false"],
23
- },
24
- contextmenu: {
25
- deprecated: true,
26
- },
27
- dir: {
28
- enum: ["ltr", "rtl", "auto"],
29
- },
30
- draggable: {
31
- enum: ["true", "false"],
32
- },
33
- hidden: {
34
- boolean: true,
35
- },
36
- id: {
37
- enum: [validId],
38
- },
39
- tabindex: {
40
- enum: ["/-?\\d+/"],
41
- },
42
- },
43
- },
44
- a: {
45
- flow: true,
46
- phrasing: true,
47
- interactive: true,
48
- transparent: true,
49
- attributes: {
50
- charset: {
51
- deprecated: true,
52
- },
53
- coords: {
54
- deprecated: true,
55
- },
56
- datafld: {
57
- deprecated: true,
58
- },
59
- datasrc: {
60
- deprecated: true,
61
- },
62
- download: {
63
- allowed: allowedIfAttributeIsPresent("href"),
64
- omit: true,
65
- enum: ["/.+/"],
66
- },
67
- href: {
68
- enum: ["/.*/"],
69
- },
70
- hreflang: {
71
- allowed: allowedIfAttributeIsPresent("href"),
72
- },
73
- itemprop: {
74
- allowed: allowedIfAttributeIsPresent("href"),
75
- },
76
- methods: {
77
- deprecated: true,
78
- },
79
- name: {
80
- deprecated: true,
81
- },
82
- ping: {
83
- allowed: allowedIfAttributeIsPresent("href"),
84
- },
85
- referrerpolicy: {
86
- allowed: allowedIfAttributeIsPresent("href"),
87
- enum: ReferrerPolicy,
88
- },
89
- rel: {
90
- allowed: allowedIfAttributeIsPresent("href"),
91
- },
92
- shape: {
93
- deprecated: true,
94
- },
95
- target: {
96
- allowed: allowedIfAttributeIsPresent("href"),
97
- enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"],
98
- },
99
- type: {
100
- allowed: allowedIfAttributeIsPresent("href"),
101
- },
102
- urn: {
103
- deprecated: true,
104
- },
105
- },
106
- permittedDescendants: [{ exclude: "@interactive" }],
107
- implicitRole(node) {
108
- return node.hasAttribute("href") ? "link" : null;
109
- },
110
- },
111
- abbr: {
112
- flow: true,
113
- phrasing: true,
114
- permittedContent: ["@phrasing"],
115
- },
116
- acronym: {
117
- deprecated: {
118
- message: "use <abbr> instead",
119
- documentation: "`<abbr>` can be used as a replacement.",
120
- source: "html5",
121
- },
122
- },
123
- address: {
124
- flow: true,
125
- implicitRole() {
126
- return "group";
127
- },
128
- permittedContent: ["@flow"],
129
- permittedDescendants: [{ exclude: ["address", "header", "footer", "@heading", "@sectioning"] }],
130
- },
131
- applet: {
132
- deprecated: {
133
- source: "html5",
134
- },
135
- attributes: {
136
- datafld: {
137
- deprecated: true,
138
- },
139
- datasrc: {
140
- deprecated: true,
141
- },
142
- },
143
- },
144
- area: {
145
- flow: ["isDescendant", "map"],
146
- phrasing: ["isDescendant", "map"],
147
- void: true,
148
- attributes: {
149
- alt: {},
150
- coords: {
151
- allowed(node) {
152
- const attr = node.getAttribute("shape");
153
- if (attr === "default") {
154
- return `cannot be used when "shape" attribute is "default"`;
155
- }
156
- else {
157
- return null;
158
- }
159
- },
160
- },
161
- download: {
162
- allowed: allowedIfAttributeIsPresent("href"),
163
- },
164
- nohref: {
165
- deprecated: true,
166
- },
167
- itemprop: {
168
- allowed: allowedIfAttributeIsPresent("href"),
169
- },
170
- ping: {
171
- allowed: allowedIfAttributeIsPresent("href"),
172
- },
173
- referrerpolicy: {
174
- allowed: allowedIfAttributeIsPresent("href"),
175
- enum: ReferrerPolicy,
176
- },
177
- rel: {
178
- allowed: allowedIfAttributeIsPresent("href"),
179
- },
180
- shape: {
181
- allowed(node, attr) {
182
- const shape = attr !== null && attr !== void 0 ? attr : "rect";
183
- switch (shape) {
184
- case "circ":
185
- case "circle":
186
- case "poly":
187
- case "polygon":
188
- case "rect":
189
- case "rectangle":
190
- return allowedIfAttributeIsPresent("coords")(node, attr);
191
- default:
192
- return null;
193
- }
194
- },
195
- enum: ["rect", "circle", "poly", "default"],
196
- },
197
- target: {
198
- allowed: allowedIfAttributeIsPresent("href"),
199
- enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"],
200
- },
201
- },
202
- implicitRole(node) {
203
- return node.hasAttribute("href") ? "link" : null;
204
- },
205
- requiredAncestors: ["map"],
206
- },
207
- article: {
208
- flow: true,
209
- sectioning: true,
210
- permittedContent: ["@flow"],
211
- permittedDescendants: [{ exclude: ["main"] }],
212
- implicitRole() {
213
- return "article";
214
- },
215
- },
216
- aside: {
217
- flow: true,
218
- sectioning: true,
219
- permittedContent: ["@flow"],
220
- permittedDescendants: [{ exclude: ["main"] }],
221
- implicitRole() {
222
- return "complementary";
223
- },
224
- },
225
- audio: {
226
- flow: true,
227
- phrasing: true,
228
- embedded: true,
229
- interactive: ["hasAttribute", "controls"],
230
- transparent: ["@flow"],
231
- attributes: {
232
- crossorigin: {
233
- omit: true,
234
- enum: ["anonymous", "use-credentials"],
235
- },
236
- itemprop: {
237
- allowed: allowedIfAttributeIsPresent("src"),
238
- },
239
- preload: {
240
- omit: true,
241
- enum: ["none", "metadata", "auto"],
242
- },
243
- },
244
- permittedContent: ["@flow", "track", "source"],
245
- permittedDescendants: [{ exclude: ["audio", "video"] }],
246
- permittedOrder: ["source", "track", "@flow"],
247
- },
248
- b: {
249
- flow: true,
250
- phrasing: true,
251
- permittedContent: ["@phrasing"],
252
- },
253
- base: {
254
- metadata: true,
255
- void: true,
256
- permittedParent: ["head"],
257
- },
258
- basefont: {
259
- deprecated: {
260
- message: "use CSS instead",
261
- documentation: "Use CSS `font-size` property instead.",
262
- source: "html4",
263
- },
264
- },
265
- bdi: {
266
- flow: true,
267
- phrasing: true,
268
- permittedContent: ["@phrasing"],
269
- },
270
- bdo: {
271
- flow: true,
272
- phrasing: true,
273
- permittedContent: ["@phrasing"],
274
- },
275
- bgsound: {
276
- deprecated: {
277
- message: "use <audio> instead",
278
- documentation: "Use the `<audio>` element instead but consider accessibility concerns with autoplaying sounds.",
279
- source: "non-standard",
280
- },
281
- },
282
- big: {
283
- deprecated: {
284
- message: "use CSS instead",
285
- documentation: "Use CSS `font-size` property instead.",
286
- source: "html5",
287
- },
288
- },
289
- blink: {
290
- deprecated: {
291
- documentation: "`<blink>` has no direct replacement and blinking text is frowned upon by accessibility standards.",
292
- source: "non-standard",
293
- },
294
- },
295
- blockquote: {
296
- flow: true,
297
- sectioning: true,
298
- implicitRole() {
299
- return "blockquote";
300
- },
301
- permittedContent: ["@flow"],
302
- },
303
- body: {
304
- permittedContent: ["@flow"],
305
- permittedParent: ["html"],
306
- attributes: {
307
- alink: {
308
- deprecated: true,
309
- },
310
- background: {
311
- deprecated: true,
312
- },
313
- bgcolor: {
314
- deprecated: true,
315
- },
316
- link: {
317
- deprecated: true,
318
- },
319
- marginbottom: {
320
- deprecated: true,
321
- },
322
- marginheight: {
323
- deprecated: true,
324
- },
325
- marginleft: {
326
- deprecated: true,
327
- },
328
- marginright: {
329
- deprecated: true,
330
- },
331
- margintop: {
332
- deprecated: true,
333
- },
334
- marginwidth: {
335
- deprecated: true,
336
- },
337
- text: {
338
- deprecated: true,
339
- },
340
- vlink: {
341
- deprecated: true,
342
- },
343
- },
344
- },
345
- br: {
346
- flow: true,
347
- phrasing: true,
348
- void: true,
349
- attributes: {
350
- clear: {
351
- deprecated: true,
352
- },
353
- },
354
- },
355
- button: {
356
- flow: true,
357
- phrasing: true,
358
- interactive: true,
359
- formAssociated: {
360
- listed: true,
361
- },
362
- labelable: true,
363
- attributes: {
364
- autofocus: {
365
- boolean: true,
366
- },
367
- datafld: {
368
- deprecated: true,
369
- },
370
- dataformatas: {
371
- deprecated: true,
372
- },
373
- datasrc: {
374
- deprecated: true,
375
- },
376
- disabled: {
377
- boolean: true,
378
- },
379
- formaction: {
380
- allowed: allowedIfAttributeHasValue("type", ["submit"], { defaultValue: "submit" }),
381
- },
382
- formenctype: {
383
- allowed: allowedIfAttributeHasValue("type", ["submit"], { defaultValue: "submit" }),
384
- },
385
- formmethod: {
386
- allowed: allowedIfAttributeHasValue("type", ["submit"], { defaultValue: "submit" }),
387
- enum: ["get", "post", "dialog"],
388
- },
389
- formnovalidate: {
390
- allowed: allowedIfAttributeHasValue("type", ["submit"], { defaultValue: "submit" }),
391
- boolean: true,
392
- },
393
- formtarget: {
394
- allowed: allowedIfAttributeHasValue("type", ["submit"], { defaultValue: "submit" }),
395
- enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"],
396
- },
397
- type: {
398
- enum: ["submit", "reset", "button"],
399
- },
400
- },
401
- implicitRole() {
402
- return "button";
403
- },
404
- permittedContent: ["@phrasing"],
405
- permittedDescendants: [{ exclude: ["@interactive"] }],
406
- textContent: "accessible",
407
- },
408
- canvas: {
409
- flow: true,
410
- phrasing: true,
411
- embedded: true,
412
- transparent: true,
413
- },
414
- caption: {
415
- permittedContent: ["@flow"],
416
- permittedDescendants: [{ exclude: ["table"] }],
417
- attributes: {
418
- align: {
419
- deprecated: true,
420
- },
421
- },
422
- },
423
- center: {
424
- deprecated: {
425
- message: "use CSS instead",
426
- documentation: "Use the CSS `text-align` or `margin: auto` properties instead.",
427
- source: "html4",
428
- },
429
- },
430
- cite: {
431
- flow: true,
432
- phrasing: true,
433
- permittedContent: ["@phrasing"],
434
- },
435
- code: {
436
- flow: true,
437
- phrasing: true,
438
- permittedContent: ["@phrasing"],
439
- },
440
- col: {
441
- attributes: {
442
- align: {
443
- deprecated: true,
444
- },
445
- char: {
446
- deprecated: true,
447
- },
448
- charoff: {
449
- deprecated: true,
450
- },
451
- span: {
452
- enum: ["/\\d+/"],
453
- },
454
- valign: {
455
- deprecated: true,
456
- },
457
- width: {
458
- deprecated: true,
459
- },
460
- },
461
- void: true,
462
- },
463
- colgroup: {
464
- implicitClosed: ["colgroup"],
465
- attributes: {
466
- span: {
467
- enum: ["/\\d+/"],
468
- },
469
- },
470
- permittedContent: ["col", "template"],
471
- },
472
- data: {
473
- flow: true,
474
- phrasing: true,
475
- permittedContent: ["@phrasing"],
476
- },
477
- datalist: {
478
- flow: true,
479
- phrasing: true,
480
- implicitRole() {
481
- return "listbox";
482
- },
483
- permittedContent: ["@phrasing", "option"],
484
- },
485
- dd: {
486
- implicitClosed: ["dd", "dt"],
487
- permittedContent: ["@flow"],
488
- requiredAncestors: ["dl > dd", "dl > div > dd"],
489
- },
490
- del: {
491
- flow: true,
492
- phrasing: true,
493
- transparent: true,
494
- },
495
- details: {
496
- flow: true,
497
- sectioning: true,
498
- interactive: true,
499
- attributes: {
500
- open: {
501
- boolean: true,
502
- },
503
- },
504
- implicitRole() {
505
- return "group";
506
- },
507
- permittedContent: ["summary", "@flow"],
508
- permittedOrder: ["summary", "@flow"],
509
- requiredContent: ["summary"],
510
- },
511
- dfn: {
512
- flow: true,
513
- phrasing: true,
514
- implicitRole() {
515
- return "term";
516
- },
517
- permittedContent: ["@phrasing"],
518
- permittedDescendants: [{ exclude: ["dfn"] }],
519
- },
520
- dialog: {
521
- flow: true,
522
- permittedContent: ["@flow"],
523
- attributes: {
524
- open: {
525
- boolean: true,
526
- },
527
- },
528
- implicitRole() {
529
- return "dialog";
530
- },
531
- },
532
- dir: {
533
- deprecated: {
534
- documentation: "The non-standard `<dir>` element has no direct replacement but MDN recommends replacing with `<ul>` and CSS.",
535
- source: "html4",
536
- },
537
- },
538
- div: {
539
- flow: true,
540
- permittedContent: ["@flow", "dt", "dd"],
541
- attributes: {
542
- align: {
543
- deprecated: true,
544
- },
545
- datafld: {
546
- deprecated: true,
547
- },
548
- dataformatas: {
549
- deprecated: true,
550
- },
551
- datasrc: {
552
- deprecated: true,
553
- },
554
- },
555
- },
556
- dl: {
557
- flow: true,
558
- permittedContent: ["@script", "dt", "dd", "div"],
559
- attributes: {
560
- compact: {
561
- deprecated: true,
562
- },
563
- },
564
- },
565
- dt: {
566
- implicitClosed: ["dd", "dt"],
567
- permittedContent: ["@flow"],
568
- permittedDescendants: [{ exclude: ["header", "footer", "@sectioning", "@heading"] }],
569
- requiredAncestors: ["dl > dt", "dl > div > dt"],
570
- },
571
- em: {
572
- flow: true,
573
- phrasing: true,
574
- permittedContent: ["@phrasing"],
575
- },
576
- embed: {
577
- flow: true,
578
- phrasing: true,
579
- embedded: true,
580
- interactive: true,
581
- void: true,
582
- attributes: {
583
- src: {
584
- required: true,
585
- enum: ["/.+/"],
586
- },
587
- title: {
588
- required: true,
589
- },
590
- },
591
- },
592
- fieldset: {
593
- flow: true,
594
- formAssociated: {
595
- listed: true,
596
- },
597
- attributes: {
598
- datafld: {
599
- deprecated: true,
600
- },
601
- disabled: {
602
- boolean: true,
603
- },
604
- },
605
- implicitRole() {
606
- return "group";
607
- },
608
- permittedContent: ["@flow", "legend?"],
609
- permittedOrder: ["legend", "@flow"],
610
- },
611
- figcaption: {
612
- permittedContent: ["@flow"],
613
- },
614
- figure: {
615
- flow: true,
616
- implicitRole() {
617
- return "figure";
618
- },
619
- permittedContent: ["@flow", "figcaption?"],
620
- permittedOrder: ["figcaption", "@flow", "figcaption"],
621
- },
622
- font: {
623
- deprecated: {
624
- message: "use CSS instead",
625
- documentation: "Use CSS font properties instead.",
626
- source: "html4",
627
- },
628
- },
629
- footer: {
630
- flow: true,
631
- implicitRole(node) {
632
- const selectors = [
633
- "article",
634
- "aside",
635
- "main",
636
- "nav",
637
- "section",
638
- '[role="article"]',
639
- '[role="complementary"]',
640
- '[role="main"]',
641
- '[role="navigation"]',
642
- '[role="region"]',
643
- ];
644
- if (node.closest(selectors.join(","))) {
645
- return null;
646
- }
647
- else {
648
- return "contentinfo";
649
- }
650
- },
651
- permittedContent: ["@flow"],
652
- permittedDescendants: [{ exclude: ["header", "footer", "main"] }],
653
- },
654
- form: {
655
- flow: true,
656
- form: true,
657
- attributes: {
658
- action: {
659
- enum: [/^\s*\S+\s*$/],
660
- },
661
- accept: {
662
- deprecated: true,
663
- },
664
- autocomplete: {
665
- enum: ["on", "off"],
666
- },
667
- method: {
668
- enum: ["get", "post", "dialog"],
669
- },
670
- novalidate: {
671
- boolean: true,
672
- },
673
- target: {
674
- enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"],
675
- },
676
- },
677
- implicitRole() {
678
- return "form";
679
- },
680
- permittedContent: ["@flow"],
681
- permittedDescendants: [{ exclude: ["@form"] }],
682
- },
683
- frame: {
684
- deprecated: {
685
- documentation: "The `<frame>` element can be replaced with the `<iframe>` element but a better solution is to remove usage of frames entirely.",
686
- source: "html5",
687
- },
688
- attributes: {
689
- datafld: {
690
- deprecated: true,
691
- },
692
- datasrc: {
693
- deprecated: true,
694
- },
695
- title: {
696
- required: true,
697
- },
698
- },
699
- },
700
- frameset: {
701
- deprecated: {
702
- documentation: "The `<frameset>` element can be replaced with the `<iframe>` element but a better solution is to remove usage of frames entirely.",
703
- source: "html5",
704
- },
705
- },
706
- h1: {
707
- flow: true,
708
- heading: true,
709
- permittedContent: ["@phrasing"],
710
- attributes: {
711
- align: {
712
- deprecated: true,
713
- },
714
- },
715
- implicitRole() {
716
- return "heading";
717
- },
718
- },
719
- h2: {
720
- flow: true,
721
- heading: true,
722
- permittedContent: ["@phrasing"],
723
- attributes: {
724
- align: {
725
- deprecated: true,
726
- },
727
- },
728
- implicitRole() {
729
- return "heading";
730
- },
731
- },
732
- h3: {
733
- flow: true,
734
- heading: true,
735
- permittedContent: ["@phrasing"],
736
- attributes: {
737
- align: {
738
- deprecated: true,
739
- },
740
- },
741
- implicitRole() {
742
- return "heading";
743
- },
744
- },
745
- h4: {
746
- flow: true,
747
- heading: true,
748
- permittedContent: ["@phrasing"],
749
- attributes: {
750
- align: {
751
- deprecated: true,
752
- },
753
- },
754
- implicitRole() {
755
- return "heading";
756
- },
757
- },
758
- h5: {
759
- flow: true,
760
- heading: true,
761
- permittedContent: ["@phrasing"],
762
- attributes: {
763
- align: {
764
- deprecated: true,
765
- },
766
- },
767
- implicitRole() {
768
- return "heading";
769
- },
770
- },
771
- h6: {
772
- flow: true,
773
- heading: true,
774
- permittedContent: ["@phrasing"],
775
- attributes: {
776
- align: {
777
- deprecated: true,
778
- },
779
- },
780
- implicitRole() {
781
- return "heading";
782
- },
783
- },
784
- head: {
785
- permittedContent: ["base?", "title?", "@meta"],
786
- permittedParent: ["html"],
787
- requiredContent: ["title"],
788
- attributes: {
789
- profile: {
790
- deprecated: true,
791
- },
792
- },
793
- },
794
- header: {
795
- flow: true,
796
- implicitRole(node) {
797
- const selectors = [
798
- "article",
799
- "aside",
800
- "main",
801
- "nav",
802
- "section",
803
- '[role="article"]',
804
- '[role="complementary"]',
805
- '[role="main"]',
806
- '[role="navigation"]',
807
- '[role="region"]',
808
- ];
809
- if (node.closest(selectors.join(","))) {
810
- return null;
811
- }
812
- else {
813
- return "banner";
814
- }
815
- },
816
- permittedContent: ["@flow"],
817
- permittedDescendants: [{ exclude: ["header", "footer", "main"] }],
818
- },
819
- hgroup: {
820
- flow: true,
821
- heading: true,
822
- permittedContent: ["p", "@heading?"],
823
- permittedDescendants: [{ exclude: ["hgroup"] }],
824
- requiredContent: ["@heading"],
825
- },
826
- hr: {
827
- flow: true,
828
- void: true,
829
- attributes: {
830
- align: {
831
- deprecated: true,
832
- },
833
- color: {
834
- deprecated: true,
835
- },
836
- noshade: {
837
- deprecated: true,
838
- },
839
- size: {
840
- deprecated: true,
841
- },
842
- width: {
843
- deprecated: true,
844
- },
845
- },
846
- implicitRole() {
847
- return "separator";
848
- },
849
- },
850
- html: {
851
- permittedContent: ["head?", "body?"],
852
- permittedOrder: ["head", "body"],
853
- requiredContent: ["head", "body"],
854
- attributes: {
855
- lang: {
856
- required: true,
857
- },
858
- version: {
859
- deprecated: true,
860
- },
861
- },
862
- implicitRole() {
863
- return "document";
864
- },
865
- },
866
- i: {
867
- flow: true,
868
- phrasing: true,
869
- permittedContent: ["@phrasing"],
870
- },
871
- iframe: {
872
- flow: true,
873
- phrasing: true,
874
- embedded: true,
875
- interactive: true,
876
- attributes: {
877
- align: {
878
- deprecated: true,
879
- },
880
- allowtransparency: {
881
- deprecated: true,
882
- },
883
- datafld: {
884
- deprecated: true,
885
- },
886
- datasrc: {
887
- deprecated: true,
888
- },
889
- frameborder: {
890
- deprecated: true,
891
- },
892
- hspace: {
893
- deprecated: true,
894
- },
895
- marginheight: {
896
- deprecated: true,
897
- },
898
- marginwidth: {
899
- deprecated: true,
900
- },
901
- referrerpolicy: {
902
- enum: ReferrerPolicy,
903
- },
904
- scrolling: {
905
- deprecated: true,
906
- },
907
- src: {
908
- enum: ["/.+/"],
909
- },
910
- title: {
911
- required: true,
912
- },
913
- vspace: {
914
- deprecated: true,
915
- },
916
- },
917
- permittedContent: [],
918
- },
919
- img: {
920
- flow: true,
921
- phrasing: true,
922
- embedded: true,
923
- interactive: ["hasAttribute", "usemap"],
924
- void: true,
925
- attributes: {
926
- align: {
927
- deprecated: true,
928
- },
929
- border: {
930
- deprecated: true,
931
- },
932
- crossorigin: {
933
- omit: true,
934
- enum: ["anonymous", "use-credentials"],
935
- },
936
- datafld: {
937
- deprecated: true,
938
- },
939
- datasrc: {
940
- deprecated: true,
941
- },
942
- decoding: {
943
- enum: ["sync", "async", "auto"],
944
- },
945
- hspace: {
946
- deprecated: true,
947
- },
948
- ismap: {
949
- boolean: true,
950
- },
951
- lowsrc: {
952
- deprecated: true,
953
- },
954
- name: {
955
- deprecated: true,
956
- },
957
- referrerpolicy: {
958
- enum: ReferrerPolicy,
959
- },
960
- src: {
961
- required: true,
962
- enum: ["/.+/"],
963
- },
964
- srcset: {
965
- enum: ["/[^]+/"],
966
- },
967
- vspace: {
968
- deprecated: true,
969
- },
970
- },
971
- implicitRole(node) {
972
- const alt = node.getAttribute("alt");
973
- if (alt === "") {
974
- return "presentation";
975
- }
976
- else {
977
- return "img";
978
- }
979
- },
980
- },
981
- input: {
982
- flow: true,
983
- phrasing: true,
984
- interactive: ["matchAttribute", ["type", "!=", "hidden"]],
985
- void: true,
986
- formAssociated: {
987
- listed: true,
988
- },
989
- labelable: ["matchAttribute", ["type", "!=", "hidden"]],
990
- attributes: {
991
- align: {
992
- deprecated: true,
993
- },
994
- autofocus: {
995
- boolean: true,
996
- },
997
- capture: {
998
- omit: true,
999
- enum: ["environment", "user"],
1000
- },
1001
- checked: {
1002
- boolean: true,
1003
- },
1004
- datafld: {
1005
- deprecated: true,
1006
- },
1007
- dataformatas: {
1008
- deprecated: true,
1009
- },
1010
- datasrc: {
1011
- deprecated: true,
1012
- },
1013
- disabled: {
1014
- boolean: true,
1015
- },
1016
- formaction: {
1017
- allowed: allowedIfAttributeHasValue("type", ["submit", "image"], {
1018
- defaultValue: "submit",
1019
- }),
1020
- },
1021
- formenctype: {
1022
- allowed: allowedIfAttributeHasValue("type", ["submit", "image"], {
1023
- defaultValue: "submit",
1024
- }),
1025
- },
1026
- formmethod: {
1027
- allowed: allowedIfAttributeHasValue("type", ["submit", "image"], {
1028
- defaultValue: "submit",
1029
- }),
1030
- enum: ["get", "post", "dialog"],
1031
- },
1032
- formnovalidate: {
1033
- allowed: allowedIfAttributeHasValue("type", ["submit", "image"], {
1034
- defaultValue: "submit",
1035
- }),
1036
- boolean: true,
1037
- },
1038
- formtarget: {
1039
- allowed: allowedIfAttributeHasValue("type", ["submit", "image"], {
1040
- defaultValue: "submit",
1041
- }),
1042
- enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"],
1043
- },
1044
- hspace: {
1045
- deprecated: true,
1046
- },
1047
- inputmode: {
1048
- enum: ["none", "text", "decimal", "numeric", "tel", "search", "email", "url"],
1049
- },
1050
- ismap: {
1051
- deprecated: true,
1052
- },
1053
- multiple: {
1054
- boolean: true,
1055
- },
1056
- readonly: {
1057
- boolean: true,
1058
- },
1059
- required: {
1060
- boolean: true,
1061
- },
1062
- spellcheck: {
1063
- enum: ["default", "false", "true"],
1064
- },
1065
- type: {
1066
- required: true,
1067
- enum: [
1068
- "button",
1069
- "checkbox",
1070
- "color",
1071
- "date",
1072
- "datetime-local",
1073
- "email",
1074
- "file",
1075
- "hidden",
1076
- "image",
1077
- "month",
1078
- "number",
1079
- "password",
1080
- "radio",
1081
- "range",
1082
- "reset",
1083
- "search",
1084
- "submit",
1085
- "tel",
1086
- "text",
1087
- "time",
1088
- "url",
1089
- "week",
1090
- ],
1091
- },
1092
- usemap: {
1093
- deprecated: true,
1094
- },
1095
- vspace: {
1096
- deprecated: true,
1097
- },
1098
- },
1099
- /* eslint-disable-next-line complexity -- the standard is complicated */
1100
- implicitRole(node) {
1101
- const list = node.hasAttribute("list");
1102
- if (list) {
1103
- return "combobox";
1104
- }
1105
- const type = node.getAttribute("type");
1106
- switch (type) {
1107
- case "button":
1108
- return "button";
1109
- case "checkbox":
1110
- return "checkbox";
1111
- case "email":
1112
- return "textbox";
1113
- case "image":
1114
- return "button";
1115
- case "number":
1116
- return "spinbutton";
1117
- case "radio":
1118
- return "radio";
1119
- case "range":
1120
- return "slider";
1121
- case "reset":
1122
- return "button";
1123
- case "search":
1124
- return "searchbox";
1125
- case "submit":
1126
- return "button";
1127
- case "tel":
1128
- return "textbox";
1129
- case "text":
1130
- return "textbox";
1131
- case "url":
1132
- return "textbox";
1133
- default:
1134
- return "textbox";
1135
- }
1136
- },
1137
- },
1138
- ins: {
1139
- flow: true,
1140
- phrasing: true,
1141
- transparent: true,
1142
- },
1143
- isindex: {
1144
- deprecated: {
1145
- source: "html4",
1146
- },
1147
- },
1148
- kbd: {
1149
- flow: true,
1150
- phrasing: true,
1151
- permittedContent: ["@phrasing"],
1152
- },
1153
- keygen: {
1154
- flow: true,
1155
- phrasing: true,
1156
- interactive: true,
1157
- void: true,
1158
- labelable: true,
1159
- deprecated: true,
1160
- },
1161
- label: {
1162
- flow: true,
1163
- phrasing: true,
1164
- interactive: true,
1165
- permittedContent: ["@phrasing"],
1166
- permittedDescendants: [{ exclude: ["label"] }],
1167
- attributes: {
1168
- datafld: {
1169
- deprecated: true,
1170
- },
1171
- dataformatas: {
1172
- deprecated: true,
1173
- },
1174
- datasrc: {
1175
- deprecated: true,
1176
- },
1177
- for: {
1178
- enum: [validId],
1179
- },
1180
- },
1181
- },
1182
- legend: {
1183
- permittedContent: ["@phrasing", "@heading"],
1184
- attributes: {
1185
- align: {
1186
- deprecated: true,
1187
- },
1188
- datafld: {
1189
- deprecated: true,
1190
- },
1191
- dataformatas: {
1192
- deprecated: true,
1193
- },
1194
- datasrc: {
1195
- deprecated: true,
1196
- },
1197
- },
1198
- },
1199
- li: {
1200
- implicitClosed: ["li"],
1201
- permittedContent: ["@flow"],
1202
- permittedParent: ["ul", "ol", "menu", "template"],
1203
- attributes: {
1204
- type: {
1205
- deprecated: true,
1206
- },
1207
- },
1208
- implicitRole(node) {
1209
- return node.closest("ul, ol, menu") ? "listitem" : null;
1210
- },
1211
- },
1212
- link: {
1213
- metadata: true,
1214
- void: true,
1215
- attributes: {
1216
- as: {
1217
- allowed: allowedIfAttributeHasValue("rel", ["prefetch", "preload", "modulepreload"]),
1218
- enum: [
1219
- "audio",
1220
- "audioworklet",
1221
- "document",
1222
- "embed",
1223
- "fetch",
1224
- "font",
1225
- "frame",
1226
- "iframe",
1227
- "image",
1228
- "manifest",
1229
- "object",
1230
- "paintworklet",
1231
- "report",
1232
- "script",
1233
- "serviceworker",
1234
- "sharedworker",
1235
- "style",
1236
- "track",
1237
- "video",
1238
- "webidentity",
1239
- "worker",
1240
- "xslt",
1241
- ],
1242
- },
1243
- blocking: {
1244
- allowed: allowedIfAttributeHasValue("rel", ["stylesheet", "preload", "modulepreload"]),
1245
- list: true,
1246
- enum: ["render"],
1247
- },
1248
- charset: {
1249
- deprecated: true,
1250
- },
1251
- crossorigin: {
1252
- omit: true,
1253
- enum: ["anonymous", "use-credentials"],
1254
- },
1255
- disabled: {
1256
- allowed: allowedIfAttributeHasValue("rel", ["stylesheet"]),
1257
- boolean: true,
1258
- },
1259
- href: {
1260
- required: true,
1261
- enum: ["/.+/"],
1262
- },
1263
- integrity: {
1264
- allowed: allowedIfAttributeHasValue("rel", ["stylesheet", "preload", "modulepreload"]),
1265
- enum: ["/.+/"],
1266
- },
1267
- methods: {
1268
- deprecated: true,
1269
- },
1270
- referrerpolicy: {
1271
- enum: ReferrerPolicy,
1272
- },
1273
- target: {
1274
- deprecated: true,
1275
- },
1276
- urn: {
1277
- deprecated: true,
1278
- },
1279
- },
1280
- },
1281
- listing: {
1282
- deprecated: {
1283
- source: "html32",
1284
- },
1285
- },
1286
- main: {
1287
- flow: true,
1288
- implicitRole() {
1289
- return "main";
1290
- },
1291
- },
1292
- map: {
1293
- flow: true,
1294
- phrasing: true,
1295
- transparent: true,
1296
- attributes: {
1297
- name: {
1298
- required: true,
1299
- enum: ["/\\S+/"],
1300
- },
1301
- },
1302
- },
1303
- mark: {
1304
- flow: true,
1305
- phrasing: true,
1306
- permittedContent: ["@phrasing"],
1307
- },
1308
- marquee: {
1309
- deprecated: {
1310
- documentation: "Marked as obsolete by both W3C and WHATWG standards but still implemented in most browsers. Animated text should be avoided for accessibility reasons as well.",
1311
- source: "html5",
1312
- },
1313
- attributes: {
1314
- datafld: {
1315
- deprecated: true,
1316
- },
1317
- dataformatas: {
1318
- deprecated: true,
1319
- },
1320
- datasrc: {
1321
- deprecated: true,
1322
- },
1323
- },
1324
- },
1325
- math: {
1326
- flow: true,
1327
- foreign: true,
1328
- phrasing: true,
1329
- embedded: true,
1330
- attributes: {
1331
- align: {
1332
- deprecated: true,
1333
- },
1334
- dir: {
1335
- enum: ["ltr", "rtl"],
1336
- },
1337
- display: {
1338
- enum: ["block", "inline"],
1339
- },
1340
- hspace: {
1341
- deprecated: true,
1342
- },
1343
- name: {
1344
- deprecated: true,
1345
- },
1346
- overflow: {
1347
- enum: ["linebreak", "scroll", "elide", "truncate", "scale"],
1348
- },
1349
- vspace: {
1350
- deprecated: true,
1351
- },
1352
- },
1353
- implicitRole() {
1354
- return "math";
1355
- },
1356
- },
1357
- menu: {
1358
- flow: true,
1359
- implicitRole() {
1360
- return "list";
1361
- },
1362
- permittedContent: ["@script", "li"],
1363
- },
1364
- meta: {
1365
- flow: ["hasAttribute", "itemprop"],
1366
- phrasing: ["hasAttribute", "itemprop"],
1367
- metadata: true,
1368
- void: true,
1369
- attributes: {
1370
- charset: {
1371
- enum: ["utf-8"],
1372
- },
1373
- content: {
1374
- allowed: allowedIfAttributeIsPresent("name", "http-equiv", "itemprop", "property"),
1375
- },
1376
- itemprop: {
1377
- allowed: allowedIfAttributeIsAbsent("http-equiv", "name"),
1378
- },
1379
- name: {
1380
- allowed: allowedIfAttributeIsAbsent("http-equiv", "itemprop"),
1381
- },
1382
- "http-equiv": {
1383
- allowed: allowedIfAttributeIsAbsent("name", "itemprop"),
1384
- },
1385
- scheme: {
1386
- deprecated: true,
1387
- },
1388
- },
1389
- },
1390
- meter: {
1391
- flow: true,
1392
- phrasing: true,
1393
- labelable: true,
1394
- implicitRole() {
1395
- return "meter";
1396
- },
1397
- permittedContent: ["@phrasing"],
1398
- permittedDescendants: [{ exclude: "meter" }],
1399
- },
1400
- multicol: {
1401
- deprecated: {
1402
- message: "use CSS instead",
1403
- documentation: "Use CSS columns instead.",
1404
- source: "html5",
1405
- },
1406
- },
1407
- nav: {
1408
- flow: true,
1409
- sectioning: true,
1410
- implicitRole() {
1411
- return "navigation";
1412
- },
1413
- permittedContent: ["@flow"],
1414
- permittedDescendants: [{ exclude: "main" }],
1415
- },
1416
- nextid: {
1417
- deprecated: {
1418
- source: "html32",
1419
- },
1420
- },
1421
- nobr: {
1422
- deprecated: {
1423
- message: "use CSS instead",
1424
- documentation: "Use CSS `white-space` property instead.",
1425
- source: "non-standard",
1426
- },
1427
- },
1428
- noembed: {
1429
- deprecated: {
1430
- source: "non-standard",
1431
- },
1432
- },
1433
- noframes: {
1434
- deprecated: {
1435
- source: "html5",
1436
- },
1437
- },
1438
- noscript: {
1439
- metadata: true,
1440
- flow: true,
1441
- phrasing: true,
1442
- transparent: true,
1443
- permittedDescendants: [{ exclude: "noscript" }],
1444
- },
1445
- object: {
1446
- flow: true,
1447
- phrasing: true,
1448
- embedded: true,
1449
- interactive: ["hasAttribute", "usemap"],
1450
- transparent: true,
1451
- formAssociated: {
1452
- listed: true,
1453
- },
1454
- attributes: {
1455
- align: {
1456
- deprecated: true,
1457
- },
1458
- archive: {
1459
- deprecated: true,
1460
- },
1461
- blocking: {
1462
- list: true,
1463
- enum: ["render"],
1464
- },
1465
- border: {
1466
- deprecated: true,
1467
- },
1468
- classid: {
1469
- deprecated: true,
1470
- },
1471
- code: {
1472
- deprecated: true,
1473
- },
1474
- codebase: {
1475
- deprecated: true,
1476
- },
1477
- codetype: {
1478
- deprecated: true,
1479
- },
1480
- data: {
1481
- enum: ["/.+/"],
1482
- required: true,
1483
- },
1484
- datafld: {
1485
- deprecated: true,
1486
- },
1487
- dataformatas: {
1488
- deprecated: true,
1489
- },
1490
- datasrc: {
1491
- deprecated: true,
1492
- },
1493
- declare: {
1494
- deprecated: true,
1495
- },
1496
- hspace: {
1497
- deprecated: true,
1498
- },
1499
- name: {
1500
- enum: ["/[^_].*/"],
1501
- },
1502
- standby: {
1503
- deprecated: true,
1504
- },
1505
- vspace: {
1506
- deprecated: true,
1507
- },
1508
- },
1509
- permittedContent: ["param", "@flow"],
1510
- permittedOrder: ["param", "@flow"],
1511
- },
1512
- ol: {
1513
- flow: true,
1514
- attributes: {
1515
- compact: {
1516
- deprecated: true,
1517
- },
1518
- reversed: {
1519
- boolean: true,
1520
- },
1521
- type: {
1522
- enum: ["a", "A", "i", "I", "1"],
1523
- },
1524
- },
1525
- implicitRole() {
1526
- return "list";
1527
- },
1528
- permittedContent: ["@script", "li"],
1529
- },
1530
- optgroup: {
1531
- implicitClosed: ["optgroup"],
1532
- attributes: {
1533
- disabled: {
1534
- boolean: true,
1535
- },
1536
- },
1537
- implicitRole() {
1538
- return "group";
1539
- },
1540
- permittedContent: ["@script", "option"],
1541
- },
1542
- option: {
1543
- implicitClosed: ["option"],
1544
- attributes: {
1545
- dataformatas: {
1546
- deprecated: true,
1547
- },
1548
- datasrc: {
1549
- deprecated: true,
1550
- },
1551
- disabled: {
1552
- boolean: true,
1553
- },
1554
- name: {
1555
- deprecated: true,
1556
- },
1557
- selected: {
1558
- boolean: true,
1559
- },
1560
- },
1561
- implicitRole() {
1562
- return "option";
1563
- },
1564
- permittedContent: [],
1565
- },
1566
- output: {
1567
- flow: true,
1568
- phrasing: true,
1569
- formAssociated: {
1570
- listed: true,
1571
- },
1572
- labelable: true,
1573
- implicitRole() {
1574
- return "status";
1575
- },
1576
- permittedContent: ["@phrasing"],
1577
- },
1578
- p: {
1579
- flow: true,
1580
- implicitClosed: [
1581
- "address",
1582
- "article",
1583
- "aside",
1584
- "blockquote",
1585
- "div",
1586
- "dl",
1587
- "fieldset",
1588
- "footer",
1589
- "form",
1590
- "h1",
1591
- "h2",
1592
- "h3",
1593
- "h4",
1594
- "h5",
1595
- "h6",
1596
- "header",
1597
- "hgroup",
1598
- "hr",
1599
- "main",
1600
- "nav",
1601
- "ol",
1602
- "p",
1603
- "pre",
1604
- "section",
1605
- "table",
1606
- "ul",
1607
- ],
1608
- permittedContent: ["@phrasing"],
1609
- attributes: {
1610
- align: {
1611
- deprecated: true,
1612
- },
1613
- },
1614
- },
1615
- param: {
1616
- void: true,
1617
- attributes: {
1618
- datafld: {
1619
- deprecated: true,
1620
- },
1621
- type: {
1622
- deprecated: true,
1623
- },
1624
- valuetype: {
1625
- deprecated: true,
1626
- },
1627
- },
1628
- },
1629
- picture: {
1630
- flow: true,
1631
- phrasing: true,
1632
- embedded: true,
1633
- permittedContent: ["@script", "source", "img"],
1634
- permittedOrder: ["source", "img"],
1635
- },
1636
- plaintext: {
1637
- deprecated: {
1638
- message: "use <pre> or CSS instead",
1639
- documentation: "Use the `<pre>` element or use CSS to set a monospace font.",
1640
- source: "html2",
1641
- },
1642
- },
1643
- pre: {
1644
- flow: true,
1645
- permittedContent: ["@phrasing"],
1646
- attributes: {
1647
- width: {
1648
- deprecated: true,
1649
- },
1650
- },
1651
- },
1652
- progress: {
1653
- flow: true,
1654
- phrasing: true,
1655
- labelable: true,
1656
- implicitRole() {
1657
- return "progressbar";
1658
- },
1659
- permittedContent: ["@phrasing"],
1660
- permittedDescendants: [{ exclude: "progress" }],
1661
- },
1662
- q: {
1663
- flow: true,
1664
- phrasing: true,
1665
- permittedContent: ["@phrasing"],
1666
- },
1667
- rb: {
1668
- implicitClosed: ["rb", "rt", "rtc", "rp"],
1669
- permittedContent: ["@phrasing"],
1670
- },
1671
- rp: {
1672
- implicitClosed: ["rb", "rt", "rtc", "rp"],
1673
- permittedContent: ["@phrasing"],
1674
- },
1675
- rt: {
1676
- implicitClosed: ["rb", "rt", "rtc", "rp"],
1677
- permittedContent: ["@phrasing"],
1678
- },
1679
- rtc: {
1680
- implicitClosed: ["rb", "rtc", "rp"],
1681
- permittedContent: ["@phrasing", "rt"],
1682
- },
1683
- ruby: {
1684
- flow: true,
1685
- phrasing: true,
1686
- permittedContent: ["@phrasing", "rb", "rp", "rt", "rtc"],
1687
- },
1688
- s: {
1689
- flow: true,
1690
- phrasing: true,
1691
- permittedContent: ["@phrasing"],
1692
- },
1693
- samp: {
1694
- flow: true,
1695
- phrasing: true,
1696
- permittedContent: ["@phrasing"],
1697
- },
1698
- script: {
1699
- metadata: true,
1700
- flow: true,
1701
- phrasing: true,
1702
- scriptSupporting: true,
1703
- attributes: {
1704
- async: {
1705
- boolean: true,
1706
- },
1707
- crossorigin: {
1708
- omit: true,
1709
- enum: ["anonymous", "use-credentials"],
1710
- },
1711
- defer: {
1712
- boolean: true,
1713
- },
1714
- event: {
1715
- deprecated: true,
1716
- },
1717
- for: {
1718
- deprecated: true,
1719
- },
1720
- integrity: {
1721
- allowed: allowedIfAttributeIsPresent("src"),
1722
- enum: ["/.+/"],
1723
- },
1724
- language: {
1725
- deprecated: true,
1726
- },
1727
- nomodule: {
1728
- boolean: true,
1729
- },
1730
- referrerpolicy: {
1731
- enum: ReferrerPolicy,
1732
- },
1733
- src: {
1734
- enum: ["/.+/"],
1735
- },
1736
- },
1737
- },
1738
- search: {
1739
- flow: true,
1740
- implicitRole() {
1741
- return "search";
1742
- },
1743
- },
1744
- section: {
1745
- flow: true,
1746
- sectioning: true,
1747
- implicitRole() {
1748
- return "region";
1749
- },
1750
- permittedContent: ["@flow"],
1751
- },
1752
- select: {
1753
- flow: true,
1754
- phrasing: true,
1755
- interactive: true,
1756
- formAssociated: {
1757
- listed: true,
1758
- },
1759
- labelable: true,
1760
- attributes: {
1761
- autofocus: {
1762
- boolean: true,
1763
- },
1764
- disabled: {
1765
- boolean: true,
1766
- },
1767
- multiple: {
1768
- boolean: true,
1769
- },
1770
- required: {
1771
- boolean: true,
1772
- },
1773
- size: {
1774
- enum: ["/\\d+/"],
1775
- },
1776
- },
1777
- implicitRole(node) {
1778
- const multiple = node.hasAttribute("multiple");
1779
- if (multiple) {
1780
- return "listbox";
1781
- }
1782
- const size = node.getAttribute("size");
1783
- if (typeof size === "string") {
1784
- const parsed = parseInt(size, 10);
1785
- if (parsed > 1) {
1786
- return "listbox";
1787
- }
1788
- }
1789
- return "combobox";
1790
- },
1791
- permittedContent: ["@script", "datasrc", "datafld", "dataformatas", "option", "optgroup"],
1792
- },
1793
- slot: {
1794
- flow: true,
1795
- phrasing: true,
1796
- transparent: true,
1797
- },
1798
- small: {
1799
- flow: true,
1800
- phrasing: true,
1801
- permittedContent: ["@phrasing"],
1802
- },
1803
- source: {
1804
- void: true,
1805
- attributes: {
1806
- type: {},
1807
- media: {},
1808
- src: {
1809
- allowed: allowedIfParentIsPresent("audio", "video"),
1810
- },
1811
- srcset: {
1812
- allowed: allowedIfParentIsPresent("picture"),
1813
- },
1814
- sizes: {
1815
- allowed: allowedIfParentIsPresent("picture"),
1816
- },
1817
- width: {
1818
- allowed: allowedIfParentIsPresent("picture"),
1819
- enum: ["/\\d+/"],
1820
- },
1821
- height: {
1822
- allowed: allowedIfParentIsPresent("picture"),
1823
- enum: ["/\\d+/"],
1824
- },
1825
- },
1826
- },
1827
- spacer: {
1828
- deprecated: {
1829
- message: "use CSS instead",
1830
- documentation: "Use CSS margin or padding instead.",
1831
- source: "non-standard",
1832
- },
1833
- },
1834
- span: {
1835
- flow: true,
1836
- phrasing: true,
1837
- permittedContent: ["@phrasing"],
1838
- attributes: {
1839
- datafld: {
1840
- deprecated: true,
1841
- },
1842
- dataformatas: {
1843
- deprecated: true,
1844
- },
1845
- datasrc: {
1846
- deprecated: true,
1847
- },
1848
- },
1849
- },
1850
- strike: {
1851
- deprecated: {
1852
- message: "use <del> or <s> instead",
1853
- documentation: "Use the `<del>` or `<s>` element instead.",
1854
- source: "html5",
1855
- },
1856
- },
1857
- strong: {
1858
- flow: true,
1859
- phrasing: true,
1860
- permittedContent: ["@phrasing"],
1861
- },
1862
- style: {
1863
- metadata: true,
1864
- },
1865
- sub: {
1866
- flow: true,
1867
- phrasing: true,
1868
- permittedContent: ["@phrasing"],
1869
- },
1870
- summary: {
1871
- permittedContent: ["@phrasing", "@heading"],
1872
- },
1873
- sup: {
1874
- flow: true,
1875
- phrasing: true,
1876
- permittedContent: ["@phrasing"],
1877
- },
1878
- svg: {
1879
- flow: true,
1880
- foreign: true,
1881
- phrasing: true,
1882
- embedded: true,
1883
- },
1884
- /* while not part of HTML 5 specification these two elements are handled as
1885
- * special cases to allow them as accessible text and to avoid issues with
1886
- * "no-unknown-elements" they are added here */
1887
- "svg:desc": {},
1888
- "svg:title": {},
1889
- table: {
1890
- flow: true,
1891
- permittedContent: ["@script", "caption?", "colgroup", "tbody", "tfoot?", "thead?", "tr"],
1892
- permittedOrder: ["caption", "colgroup", "thead", "tbody", "tr", "tfoot"],
1893
- attributes: {
1894
- align: {
1895
- deprecated: true,
1896
- },
1897
- background: {
1898
- deprecated: true,
1899
- },
1900
- bgcolor: {
1901
- deprecated: true,
1902
- },
1903
- bordercolor: {
1904
- deprecated: true,
1905
- },
1906
- cellpadding: {
1907
- deprecated: true,
1908
- },
1909
- cellspacing: {
1910
- deprecated: true,
1911
- },
1912
- dataformatas: {
1913
- deprecated: true,
1914
- },
1915
- datapagesize: {
1916
- deprecated: true,
1917
- },
1918
- datasrc: {
1919
- deprecated: true,
1920
- },
1921
- frame: {
1922
- deprecated: true,
1923
- },
1924
- rules: {
1925
- deprecated: true,
1926
- },
1927
- summary: {
1928
- deprecated: true,
1929
- },
1930
- width: {
1931
- deprecated: true,
1932
- },
1933
- },
1934
- implicitRole() {
1935
- return "table";
1936
- },
1937
- },
1938
- tbody: {
1939
- implicitClosed: ["tbody", "tfoot"],
1940
- permittedContent: ["@script", "tr"],
1941
- attributes: {
1942
- align: {
1943
- deprecated: true,
1944
- },
1945
- background: {
1946
- deprecated: true,
1947
- },
1948
- char: {
1949
- deprecated: true,
1950
- },
1951
- charoff: {
1952
- deprecated: true,
1953
- },
1954
- valign: {
1955
- deprecated: true,
1956
- },
1957
- },
1958
- implicitRole() {
1959
- return "rowgroup";
1960
- },
1961
- },
1962
- td: {
1963
- flow: true,
1964
- implicitClosed: ["td", "th"],
1965
- attributes: {
1966
- align: {
1967
- deprecated: true,
1968
- },
1969
- axis: {
1970
- deprecated: true,
1971
- },
1972
- background: {
1973
- deprecated: true,
1974
- },
1975
- bgcolor: {
1976
- deprecated: true,
1977
- },
1978
- char: {
1979
- deprecated: true,
1980
- },
1981
- charoff: {
1982
- deprecated: true,
1983
- },
1984
- colspan: {
1985
- enum: ["/\\d+/"],
1986
- },
1987
- height: {
1988
- deprecated: true,
1989
- },
1990
- nowrap: {
1991
- deprecated: true,
1992
- },
1993
- rowspan: {
1994
- enum: ["/\\d+/"],
1995
- },
1996
- scope: {
1997
- deprecated: true,
1998
- },
1999
- valign: {
2000
- deprecated: true,
2001
- },
2002
- width: {
2003
- deprecated: true,
2004
- },
2005
- },
2006
- implicitRole(node) {
2007
- if (node.closest('table[role="grid"], table[role="treegrid"]')) {
2008
- return "gridcell";
2009
- }
2010
- else if (node.closest("table")) {
2011
- return "cell";
2012
- }
2013
- else {
2014
- return null;
2015
- }
2016
- },
2017
- permittedContent: ["@flow"],
2018
- },
2019
- template: {
2020
- metadata: true,
2021
- flow: true,
2022
- phrasing: true,
2023
- scriptSupporting: true,
2024
- },
2025
- textarea: {
2026
- flow: true,
2027
- phrasing: true,
2028
- interactive: true,
2029
- formAssociated: {
2030
- listed: true,
2031
- },
2032
- labelable: true,
2033
- attributes: {
2034
- autocomplete: {
2035
- enum: ["on", "off"],
2036
- },
2037
- autofocus: {
2038
- boolean: true,
2039
- },
2040
- cols: {
2041
- enum: ["/\\d+/"],
2042
- },
2043
- datafld: {
2044
- deprecated: true,
2045
- },
2046
- datasrc: {
2047
- deprecated: true,
2048
- },
2049
- disabled: {
2050
- boolean: true,
2051
- },
2052
- maxlength: {
2053
- enum: ["/\\d+/"],
2054
- },
2055
- minlength: {
2056
- enum: ["/\\d+/"],
2057
- },
2058
- readonly: {
2059
- boolean: true,
2060
- },
2061
- required: {
2062
- boolean: true,
2063
- },
2064
- rows: {
2065
- enum: ["/\\d+/"],
2066
- },
2067
- spellcheck: {
2068
- enum: ["true", "default", "false"],
2069
- },
2070
- wrap: {
2071
- enum: ["hard", "soft"],
2072
- },
2073
- },
2074
- implicitRole() {
2075
- return "textbox";
2076
- },
2077
- permittedContent: [],
2078
- },
2079
- tfoot: {
2080
- implicitClosed: ["tbody"],
2081
- permittedContent: ["@script", "tr"],
2082
- attributes: {
2083
- align: {
2084
- deprecated: true,
2085
- },
2086
- background: {
2087
- deprecated: true,
2088
- },
2089
- char: {
2090
- deprecated: true,
2091
- },
2092
- charoff: {
2093
- deprecated: true,
2094
- },
2095
- valign: {
2096
- deprecated: true,
2097
- },
2098
- },
2099
- implicitRole() {
2100
- return "rowgroup";
2101
- },
2102
- },
2103
- th: {
2104
- flow: true,
2105
- implicitClosed: ["td", "th"],
2106
- attributes: {
2107
- align: {
2108
- deprecated: true,
2109
- },
2110
- axis: {
2111
- deprecated: true,
2112
- },
2113
- background: {
2114
- deprecated: true,
2115
- },
2116
- bgcolor: {
2117
- deprecated: true,
2118
- },
2119
- char: {
2120
- deprecated: true,
2121
- },
2122
- charoff: {
2123
- deprecated: true,
2124
- },
2125
- colspan: {
2126
- enum: ["/\\d+/"],
2127
- },
2128
- height: {
2129
- deprecated: true,
2130
- },
2131
- nowrap: {
2132
- deprecated: true,
2133
- },
2134
- rowspan: {
2135
- enum: ["/\\d+/"],
2136
- },
2137
- scope: {
2138
- enum: ["row", "col", "rowgroup", "colgroup"],
2139
- },
2140
- valign: {
2141
- deprecated: true,
2142
- },
2143
- width: {
2144
- deprecated: true,
2145
- },
2146
- },
2147
- implicitRole(node) {
2148
- var _a;
2149
- const table = node.closest("table");
2150
- if (!table) {
2151
- return null;
2152
- }
2153
- const tableRole = (_a = table.getAttribute("role")) !== null && _a !== void 0 ? _a : "table";
2154
- if (typeof tableRole !== "string" || !["table", "grid", "treegrid"].includes(tableRole)) {
2155
- return null;
2156
- }
2157
- const scope = node.getAttribute("scope");
2158
- switch (scope) {
2159
- case "col":
2160
- return "columnheader";
2161
- case "row":
2162
- return "rowheader";
2163
- default:
2164
- return tableRole === "table" ? "cell" : "gridcell";
2165
- }
2166
- },
2167
- permittedContent: ["@flow"],
2168
- permittedDescendants: [{ exclude: ["header", "footer", "@sectioning", "@heading"] }],
2169
- },
2170
- thead: {
2171
- implicitClosed: ["tbody", "tfoot"],
2172
- permittedContent: ["@script", "tr"],
2173
- attributes: {
2174
- align: {
2175
- deprecated: true,
2176
- },
2177
- background: {
2178
- deprecated: true,
2179
- },
2180
- char: {
2181
- deprecated: true,
2182
- },
2183
- charoff: {
2184
- deprecated: true,
2185
- },
2186
- valign: {
2187
- deprecated: true,
2188
- },
2189
- },
2190
- implicitRole() {
2191
- return "rowgroup";
2192
- },
2193
- },
2194
- time: {
2195
- flow: true,
2196
- phrasing: true,
2197
- implicitRole() {
2198
- return "time";
2199
- },
2200
- permittedContent: ["@phrasing"],
2201
- },
2202
- title: {
2203
- metadata: true,
2204
- permittedContent: [],
2205
- permittedParent: ["head"],
2206
- },
2207
- tr: {
2208
- implicitClosed: ["tr"],
2209
- permittedContent: ["@script", "td", "th"],
2210
- attributes: {
2211
- align: {
2212
- deprecated: true,
2213
- },
2214
- background: {
2215
- deprecated: true,
2216
- },
2217
- bgcolor: {
2218
- deprecated: true,
2219
- },
2220
- char: {
2221
- deprecated: true,
2222
- },
2223
- charoff: {
2224
- deprecated: true,
2225
- },
2226
- valign: {
2227
- deprecated: true,
2228
- },
2229
- },
2230
- implicitRole() {
2231
- return "row";
2232
- },
2233
- },
2234
- track: {
2235
- void: true,
2236
- },
2237
- tt: {
2238
- deprecated: {
2239
- documentation: "Use a more semantically correct element such as `<code>`, `<var>` or `<pre>`.",
2240
- source: "html4",
2241
- },
2242
- },
2243
- u: {
2244
- flow: true,
2245
- phrasing: true,
2246
- permittedContent: ["@phrasing"],
2247
- },
2248
- ul: {
2249
- flow: true,
2250
- permittedContent: ["@script", "li"],
2251
- attributes: {
2252
- compact: {
2253
- deprecated: true,
2254
- },
2255
- type: {
2256
- deprecated: true,
2257
- },
2258
- },
2259
- implicitRole() {
2260
- return "list";
2261
- },
2262
- },
2263
- var: {
2264
- flow: true,
2265
- phrasing: true,
2266
- permittedContent: ["@phrasing"],
2267
- },
2268
- video: {
2269
- flow: true,
2270
- phrasing: true,
2271
- embedded: true,
2272
- interactive: ["hasAttribute", "controls"],
2273
- transparent: ["@flow"],
2274
- attributes: {
2275
- crossorigin: {
2276
- omit: true,
2277
- enum: ["anonymous", "use-credentials"],
2278
- },
2279
- itemprop: {
2280
- allowed: allowedIfAttributeIsPresent("src"),
2281
- },
2282
- preload: {
2283
- omit: true,
2284
- enum: ["none", "metadata", "auto"],
2285
- },
2286
- },
2287
- permittedContent: ["@flow", "track", "source"],
2288
- permittedDescendants: [{ exclude: ["audio", "video"] }],
2289
- permittedOrder: ["source", "track", "@flow"],
2290
- },
2291
- wbr: {
2292
- flow: true,
2293
- phrasing: true,
2294
- void: true,
2295
- },
2296
- xmp: {
2297
- deprecated: {
2298
- documentation: "Use `<pre>` or `<code>` and escape content using HTML entities instead.",
2299
- source: "html32",
2300
- },
2301
- },
22
+ "*": {
23
+ attributes: {
24
+ contenteditable: {
25
+ omit: true,
26
+ enum: ["true", "false"]
27
+ },
28
+ contextmenu: {
29
+ deprecated: true
30
+ },
31
+ dir: {
32
+ enum: ["ltr", "rtl", "auto"]
33
+ },
34
+ draggable: {
35
+ enum: ["true", "false"]
36
+ },
37
+ hidden: {
38
+ boolean: true
39
+ },
40
+ id: {
41
+ enum: [validId]
42
+ },
43
+ tabindex: {
44
+ enum: ["/-?\\d+/"]
45
+ }
46
+ }
47
+ },
48
+ a: {
49
+ flow: true,
50
+ focusable(node) {
51
+ return node.hasAttribute("href");
52
+ },
53
+ phrasing: true,
54
+ interactive: true,
55
+ transparent: true,
56
+ attributes: {
57
+ charset: {
58
+ deprecated: true
59
+ },
60
+ coords: {
61
+ deprecated: true
62
+ },
63
+ datafld: {
64
+ deprecated: true
65
+ },
66
+ datasrc: {
67
+ deprecated: true
68
+ },
69
+ download: {
70
+ allowed: allowedIfAttributeIsPresent("href"),
71
+ omit: true,
72
+ enum: ["/.+/"]
73
+ },
74
+ href: {
75
+ enum: ["/.*/"]
76
+ },
77
+ hreflang: {
78
+ allowed: allowedIfAttributeIsPresent("href")
79
+ },
80
+ itemprop: {
81
+ allowed: allowedIfAttributeIsPresent("href")
82
+ },
83
+ methods: {
84
+ deprecated: true
85
+ },
86
+ name: {
87
+ deprecated: true
88
+ },
89
+ ping: {
90
+ allowed: allowedIfAttributeIsPresent("href")
91
+ },
92
+ referrerpolicy: {
93
+ allowed: allowedIfAttributeIsPresent("href"),
94
+ enum: ReferrerPolicy
95
+ },
96
+ rel: {
97
+ allowed: allowedIfAttributeIsPresent("href")
98
+ },
99
+ shape: {
100
+ deprecated: true
101
+ },
102
+ target: {
103
+ allowed: allowedIfAttributeIsPresent("href"),
104
+ enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"]
105
+ },
106
+ type: {
107
+ allowed: allowedIfAttributeIsPresent("href")
108
+ },
109
+ urn: {
110
+ deprecated: true
111
+ }
112
+ },
113
+ permittedDescendants: [{ exclude: "@interactive" }],
114
+ implicitRole(node) {
115
+ return node.hasAttribute("href") ? "link" : null;
116
+ }
117
+ },
118
+ abbr: {
119
+ flow: true,
120
+ phrasing: true,
121
+ permittedContent: ["@phrasing"]
122
+ },
123
+ acronym: {
124
+ deprecated: {
125
+ message: "use <abbr> instead",
126
+ documentation: "`<abbr>` can be used as a replacement.",
127
+ source: "html5"
128
+ }
129
+ },
130
+ address: {
131
+ flow: true,
132
+ implicitRole() {
133
+ return "group";
134
+ },
135
+ permittedContent: ["@flow"],
136
+ permittedDescendants: [{ exclude: ["address", "header", "footer", "@heading", "@sectioning"] }]
137
+ },
138
+ applet: {
139
+ deprecated: {
140
+ source: "html5"
141
+ },
142
+ attributes: {
143
+ datafld: {
144
+ deprecated: true
145
+ },
146
+ datasrc: {
147
+ deprecated: true
148
+ }
149
+ }
150
+ },
151
+ area: {
152
+ flow: ["isDescendant", "map"],
153
+ focusable(node) {
154
+ return node.hasAttribute("href");
155
+ },
156
+ phrasing: ["isDescendant", "map"],
157
+ void: true,
158
+ attributes: {
159
+ alt: {},
160
+ coords: {
161
+ allowed(node) {
162
+ const attr = node.getAttribute("shape");
163
+ if (attr === "default") {
164
+ return `cannot be used when "shape" attribute is "default"`;
165
+ } else {
166
+ return null;
167
+ }
168
+ }
169
+ },
170
+ download: {
171
+ allowed: allowedIfAttributeIsPresent("href")
172
+ },
173
+ nohref: {
174
+ deprecated: true
175
+ },
176
+ itemprop: {
177
+ allowed: allowedIfAttributeIsPresent("href")
178
+ },
179
+ ping: {
180
+ allowed: allowedIfAttributeIsPresent("href")
181
+ },
182
+ referrerpolicy: {
183
+ allowed: allowedIfAttributeIsPresent("href"),
184
+ enum: ReferrerPolicy
185
+ },
186
+ rel: {
187
+ allowed: allowedIfAttributeIsPresent("href")
188
+ },
189
+ shape: {
190
+ allowed(node, attr) {
191
+ const shape = attr ?? "rect";
192
+ switch (shape) {
193
+ case "circ":
194
+ case "circle":
195
+ case "poly":
196
+ case "polygon":
197
+ case "rect":
198
+ case "rectangle":
199
+ return allowedIfAttributeIsPresent("coords")(node, attr);
200
+ default:
201
+ return null;
202
+ }
203
+ },
204
+ enum: ["rect", "circle", "poly", "default"]
205
+ },
206
+ target: {
207
+ allowed: allowedIfAttributeIsPresent("href"),
208
+ enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"]
209
+ }
210
+ },
211
+ implicitRole(node) {
212
+ return node.hasAttribute("href") ? "link" : null;
213
+ },
214
+ requiredAncestors: ["map"]
215
+ },
216
+ article: {
217
+ flow: true,
218
+ sectioning: true,
219
+ permittedContent: ["@flow"],
220
+ permittedDescendants: [{ exclude: ["main"] }],
221
+ implicitRole() {
222
+ return "article";
223
+ }
224
+ },
225
+ aside: {
226
+ flow: true,
227
+ sectioning: true,
228
+ permittedContent: ["@flow"],
229
+ permittedDescendants: [{ exclude: ["main"] }],
230
+ implicitRole() {
231
+ return "complementary";
232
+ }
233
+ },
234
+ audio: {
235
+ flow: true,
236
+ focusable(node) {
237
+ return node.hasAttribute("controls");
238
+ },
239
+ phrasing: true,
240
+ embedded: true,
241
+ interactive: ["hasAttribute", "controls"],
242
+ transparent: ["@flow"],
243
+ attributes: {
244
+ crossorigin: {
245
+ omit: true,
246
+ enum: ["anonymous", "use-credentials"]
247
+ },
248
+ itemprop: {
249
+ allowed: allowedIfAttributeIsPresent("src")
250
+ },
251
+ preload: {
252
+ omit: true,
253
+ enum: ["none", "metadata", "auto"]
254
+ }
255
+ },
256
+ permittedContent: ["@flow", "track", "source"],
257
+ permittedDescendants: [{ exclude: ["audio", "video"] }],
258
+ permittedOrder: ["source", "track", "@flow"]
259
+ },
260
+ b: {
261
+ flow: true,
262
+ phrasing: true,
263
+ permittedContent: ["@phrasing"]
264
+ },
265
+ base: {
266
+ metadata: true,
267
+ void: true,
268
+ permittedParent: ["head"]
269
+ },
270
+ basefont: {
271
+ deprecated: {
272
+ message: "use CSS instead",
273
+ documentation: "Use CSS `font-size` property instead.",
274
+ source: "html4"
275
+ }
276
+ },
277
+ bdi: {
278
+ flow: true,
279
+ phrasing: true,
280
+ permittedContent: ["@phrasing"]
281
+ },
282
+ bdo: {
283
+ flow: true,
284
+ phrasing: true,
285
+ permittedContent: ["@phrasing"]
286
+ },
287
+ bgsound: {
288
+ deprecated: {
289
+ message: "use <audio> instead",
290
+ documentation: "Use the `<audio>` element instead but consider accessibility concerns with autoplaying sounds.",
291
+ source: "non-standard"
292
+ }
293
+ },
294
+ big: {
295
+ deprecated: {
296
+ message: "use CSS instead",
297
+ documentation: "Use CSS `font-size` property instead.",
298
+ source: "html5"
299
+ }
300
+ },
301
+ blink: {
302
+ deprecated: {
303
+ documentation: "`<blink>` has no direct replacement and blinking text is frowned upon by accessibility standards.",
304
+ source: "non-standard"
305
+ }
306
+ },
307
+ blockquote: {
308
+ flow: true,
309
+ sectioning: true,
310
+ implicitRole() {
311
+ return "blockquote";
312
+ },
313
+ permittedContent: ["@flow"]
314
+ },
315
+ body: {
316
+ permittedContent: ["@flow"],
317
+ permittedParent: ["html"],
318
+ attributes: {
319
+ alink: {
320
+ deprecated: true
321
+ },
322
+ background: {
323
+ deprecated: true
324
+ },
325
+ bgcolor: {
326
+ deprecated: true
327
+ },
328
+ link: {
329
+ deprecated: true
330
+ },
331
+ marginbottom: {
332
+ deprecated: true
333
+ },
334
+ marginheight: {
335
+ deprecated: true
336
+ },
337
+ marginleft: {
338
+ deprecated: true
339
+ },
340
+ marginright: {
341
+ deprecated: true
342
+ },
343
+ margintop: {
344
+ deprecated: true
345
+ },
346
+ marginwidth: {
347
+ deprecated: true
348
+ },
349
+ text: {
350
+ deprecated: true
351
+ },
352
+ vlink: {
353
+ deprecated: true
354
+ }
355
+ }
356
+ },
357
+ br: {
358
+ flow: true,
359
+ phrasing: true,
360
+ void: true,
361
+ attributes: {
362
+ clear: {
363
+ deprecated: true
364
+ }
365
+ }
366
+ },
367
+ button: {
368
+ flow: true,
369
+ focusable: true,
370
+ phrasing: true,
371
+ interactive: true,
372
+ formAssociated: {
373
+ listed: true
374
+ },
375
+ labelable: true,
376
+ attributes: {
377
+ autofocus: {
378
+ boolean: true
379
+ },
380
+ datafld: {
381
+ deprecated: true
382
+ },
383
+ dataformatas: {
384
+ deprecated: true
385
+ },
386
+ datasrc: {
387
+ deprecated: true
388
+ },
389
+ disabled: {
390
+ boolean: true
391
+ },
392
+ formaction: {
393
+ allowed: allowedIfAttributeHasValue("type", ["submit"], { defaultValue: "submit" })
394
+ },
395
+ formenctype: {
396
+ allowed: allowedIfAttributeHasValue("type", ["submit"], { defaultValue: "submit" })
397
+ },
398
+ formmethod: {
399
+ allowed: allowedIfAttributeHasValue("type", ["submit"], { defaultValue: "submit" }),
400
+ enum: ["get", "post", "dialog"]
401
+ },
402
+ formnovalidate: {
403
+ allowed: allowedIfAttributeHasValue("type", ["submit"], { defaultValue: "submit" }),
404
+ boolean: true
405
+ },
406
+ formtarget: {
407
+ allowed: allowedIfAttributeHasValue("type", ["submit"], { defaultValue: "submit" }),
408
+ enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"]
409
+ },
410
+ type: {
411
+ enum: ["submit", "reset", "button"]
412
+ }
413
+ },
414
+ implicitRole() {
415
+ return "button";
416
+ },
417
+ permittedContent: ["@phrasing"],
418
+ permittedDescendants: [{ exclude: ["@interactive"] }],
419
+ textContent: "accessible"
420
+ },
421
+ canvas: {
422
+ flow: true,
423
+ phrasing: true,
424
+ embedded: true,
425
+ transparent: true
426
+ },
427
+ caption: {
428
+ permittedContent: ["@flow"],
429
+ permittedDescendants: [{ exclude: ["table"] }],
430
+ attributes: {
431
+ align: {
432
+ deprecated: true
433
+ }
434
+ }
435
+ },
436
+ center: {
437
+ deprecated: {
438
+ message: "use CSS instead",
439
+ documentation: "Use the CSS `text-align` or `margin: auto` properties instead.",
440
+ source: "html4"
441
+ }
442
+ },
443
+ cite: {
444
+ flow: true,
445
+ phrasing: true,
446
+ permittedContent: ["@phrasing"]
447
+ },
448
+ code: {
449
+ flow: true,
450
+ phrasing: true,
451
+ permittedContent: ["@phrasing"]
452
+ },
453
+ col: {
454
+ attributes: {
455
+ align: {
456
+ deprecated: true
457
+ },
458
+ char: {
459
+ deprecated: true
460
+ },
461
+ charoff: {
462
+ deprecated: true
463
+ },
464
+ span: {
465
+ enum: ["/\\d+/"]
466
+ },
467
+ valign: {
468
+ deprecated: true
469
+ },
470
+ width: {
471
+ deprecated: true
472
+ }
473
+ },
474
+ void: true
475
+ },
476
+ colgroup: {
477
+ implicitClosed: ["colgroup"],
478
+ attributes: {
479
+ span: {
480
+ enum: ["/\\d+/"]
481
+ }
482
+ },
483
+ permittedContent: ["col", "template"]
484
+ },
485
+ data: {
486
+ flow: true,
487
+ phrasing: true,
488
+ permittedContent: ["@phrasing"]
489
+ },
490
+ datalist: {
491
+ flow: true,
492
+ phrasing: true,
493
+ implicitRole() {
494
+ return "listbox";
495
+ },
496
+ permittedContent: ["@phrasing", "option"]
497
+ },
498
+ dd: {
499
+ implicitClosed: ["dd", "dt"],
500
+ permittedContent: ["@flow"],
501
+ requiredAncestors: ["dl > dd", "dl > div > dd"]
502
+ },
503
+ del: {
504
+ flow: true,
505
+ phrasing: true,
506
+ transparent: true
507
+ },
508
+ details: {
509
+ flow: true,
510
+ sectioning: true,
511
+ interactive: true,
512
+ attributes: {
513
+ open: {
514
+ boolean: true
515
+ }
516
+ },
517
+ implicitRole() {
518
+ return "group";
519
+ },
520
+ permittedContent: ["summary", "@flow"],
521
+ permittedOrder: ["summary", "@flow"],
522
+ requiredContent: ["summary"]
523
+ },
524
+ dfn: {
525
+ flow: true,
526
+ phrasing: true,
527
+ implicitRole() {
528
+ return "term";
529
+ },
530
+ permittedContent: ["@phrasing"],
531
+ permittedDescendants: [{ exclude: ["dfn"] }]
532
+ },
533
+ dialog: {
534
+ flow: true,
535
+ permittedContent: ["@flow"],
536
+ attributes: {
537
+ open: {
538
+ boolean: true
539
+ }
540
+ },
541
+ implicitRole() {
542
+ return "dialog";
543
+ }
544
+ },
545
+ dir: {
546
+ deprecated: {
547
+ documentation: "The non-standard `<dir>` element has no direct replacement but MDN recommends replacing with `<ul>` and CSS.",
548
+ source: "html4"
549
+ }
550
+ },
551
+ div: {
552
+ flow: true,
553
+ permittedContent: ["@flow", "dt", "dd"],
554
+ attributes: {
555
+ align: {
556
+ deprecated: true
557
+ },
558
+ datafld: {
559
+ deprecated: true
560
+ },
561
+ dataformatas: {
562
+ deprecated: true
563
+ },
564
+ datasrc: {
565
+ deprecated: true
566
+ }
567
+ }
568
+ },
569
+ dl: {
570
+ flow: true,
571
+ permittedContent: ["@script", "dt", "dd", "div"],
572
+ attributes: {
573
+ compact: {
574
+ deprecated: true
575
+ }
576
+ }
577
+ },
578
+ dt: {
579
+ implicitClosed: ["dd", "dt"],
580
+ permittedContent: ["@flow"],
581
+ permittedDescendants: [{ exclude: ["header", "footer", "@sectioning", "@heading"] }],
582
+ requiredAncestors: ["dl > dt", "dl > div > dt"]
583
+ },
584
+ em: {
585
+ flow: true,
586
+ phrasing: true,
587
+ permittedContent: ["@phrasing"]
588
+ },
589
+ embed: {
590
+ flow: true,
591
+ phrasing: true,
592
+ embedded: true,
593
+ interactive: true,
594
+ void: true,
595
+ attributes: {
596
+ src: {
597
+ required: true,
598
+ enum: ["/.+/"]
599
+ },
600
+ title: {
601
+ required: true
602
+ }
603
+ }
604
+ },
605
+ fieldset: {
606
+ flow: true,
607
+ formAssociated: {
608
+ listed: true
609
+ },
610
+ attributes: {
611
+ datafld: {
612
+ deprecated: true
613
+ },
614
+ disabled: {
615
+ boolean: true
616
+ }
617
+ },
618
+ implicitRole() {
619
+ return "group";
620
+ },
621
+ permittedContent: ["@flow", "legend?"],
622
+ permittedOrder: ["legend", "@flow"]
623
+ },
624
+ figcaption: {
625
+ permittedContent: ["@flow"]
626
+ },
627
+ figure: {
628
+ flow: true,
629
+ implicitRole() {
630
+ return "figure";
631
+ },
632
+ permittedContent: ["@flow", "figcaption?"],
633
+ permittedOrder: ["figcaption", "@flow", "figcaption"]
634
+ },
635
+ font: {
636
+ deprecated: {
637
+ message: "use CSS instead",
638
+ documentation: "Use CSS font properties instead.",
639
+ source: "html4"
640
+ }
641
+ },
642
+ footer: {
643
+ flow: true,
644
+ implicitRole(node) {
645
+ const selectors = [
646
+ "article",
647
+ "aside",
648
+ "main",
649
+ "nav",
650
+ "section",
651
+ '[role="article"]',
652
+ '[role="complementary"]',
653
+ '[role="main"]',
654
+ '[role="navigation"]',
655
+ '[role="region"]'
656
+ ];
657
+ if (node.closest(selectors.join(","))) {
658
+ return null;
659
+ } else {
660
+ return "contentinfo";
661
+ }
662
+ },
663
+ permittedContent: ["@flow"],
664
+ permittedDescendants: [{ exclude: ["header", "footer", "main"] }]
665
+ },
666
+ form: {
667
+ flow: true,
668
+ form: true,
669
+ attributes: {
670
+ action: {
671
+ enum: [/^\s*\S+\s*$/]
672
+ },
673
+ accept: {
674
+ deprecated: true
675
+ },
676
+ autocomplete: {
677
+ enum: ["on", "off"]
678
+ },
679
+ method: {
680
+ enum: ["get", "post", "dialog"]
681
+ },
682
+ novalidate: {
683
+ boolean: true
684
+ },
685
+ target: {
686
+ enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"]
687
+ }
688
+ },
689
+ implicitRole() {
690
+ return "form";
691
+ },
692
+ permittedContent: ["@flow"],
693
+ permittedDescendants: [{ exclude: ["@form"] }]
694
+ },
695
+ frame: {
696
+ deprecated: {
697
+ documentation: "The `<frame>` element can be replaced with the `<iframe>` element but a better solution is to remove usage of frames entirely.",
698
+ source: "html5"
699
+ },
700
+ attributes: {
701
+ datafld: {
702
+ deprecated: true
703
+ },
704
+ datasrc: {
705
+ deprecated: true
706
+ },
707
+ title: {
708
+ required: true
709
+ }
710
+ }
711
+ },
712
+ frameset: {
713
+ deprecated: {
714
+ documentation: "The `<frameset>` element can be replaced with the `<iframe>` element but a better solution is to remove usage of frames entirely.",
715
+ source: "html5"
716
+ }
717
+ },
718
+ h1: {
719
+ flow: true,
720
+ heading: true,
721
+ permittedContent: ["@phrasing"],
722
+ attributes: {
723
+ align: {
724
+ deprecated: true
725
+ }
726
+ },
727
+ implicitRole() {
728
+ return "heading";
729
+ }
730
+ },
731
+ h2: {
732
+ flow: true,
733
+ heading: true,
734
+ permittedContent: ["@phrasing"],
735
+ attributes: {
736
+ align: {
737
+ deprecated: true
738
+ }
739
+ },
740
+ implicitRole() {
741
+ return "heading";
742
+ }
743
+ },
744
+ h3: {
745
+ flow: true,
746
+ heading: true,
747
+ permittedContent: ["@phrasing"],
748
+ attributes: {
749
+ align: {
750
+ deprecated: true
751
+ }
752
+ },
753
+ implicitRole() {
754
+ return "heading";
755
+ }
756
+ },
757
+ h4: {
758
+ flow: true,
759
+ heading: true,
760
+ permittedContent: ["@phrasing"],
761
+ attributes: {
762
+ align: {
763
+ deprecated: true
764
+ }
765
+ },
766
+ implicitRole() {
767
+ return "heading";
768
+ }
769
+ },
770
+ h5: {
771
+ flow: true,
772
+ heading: true,
773
+ permittedContent: ["@phrasing"],
774
+ attributes: {
775
+ align: {
776
+ deprecated: true
777
+ }
778
+ },
779
+ implicitRole() {
780
+ return "heading";
781
+ }
782
+ },
783
+ h6: {
784
+ flow: true,
785
+ heading: true,
786
+ permittedContent: ["@phrasing"],
787
+ attributes: {
788
+ align: {
789
+ deprecated: true
790
+ }
791
+ },
792
+ implicitRole() {
793
+ return "heading";
794
+ }
795
+ },
796
+ head: {
797
+ permittedContent: ["base?", "title?", "@meta"],
798
+ permittedParent: ["html"],
799
+ requiredContent: ["title"],
800
+ attributes: {
801
+ profile: {
802
+ deprecated: true
803
+ }
804
+ }
805
+ },
806
+ header: {
807
+ flow: true,
808
+ implicitRole(node) {
809
+ const selectors = [
810
+ "article",
811
+ "aside",
812
+ "main",
813
+ "nav",
814
+ "section",
815
+ '[role="article"]',
816
+ '[role="complementary"]',
817
+ '[role="main"]',
818
+ '[role="navigation"]',
819
+ '[role="region"]'
820
+ ];
821
+ if (node.closest(selectors.join(","))) {
822
+ return null;
823
+ } else {
824
+ return "banner";
825
+ }
826
+ },
827
+ permittedContent: ["@flow"],
828
+ permittedDescendants: [{ exclude: ["header", "footer", "main"] }]
829
+ },
830
+ hgroup: {
831
+ flow: true,
832
+ heading: true,
833
+ permittedContent: ["p", "@heading?"],
834
+ permittedDescendants: [{ exclude: ["hgroup"] }],
835
+ requiredContent: ["@heading"]
836
+ },
837
+ hr: {
838
+ flow: true,
839
+ void: true,
840
+ attributes: {
841
+ align: {
842
+ deprecated: true
843
+ },
844
+ color: {
845
+ deprecated: true
846
+ },
847
+ noshade: {
848
+ deprecated: true
849
+ },
850
+ size: {
851
+ deprecated: true
852
+ },
853
+ width: {
854
+ deprecated: true
855
+ }
856
+ },
857
+ implicitRole() {
858
+ return "separator";
859
+ }
860
+ },
861
+ html: {
862
+ permittedContent: ["head?", "body?"],
863
+ permittedOrder: ["head", "body"],
864
+ requiredContent: ["head", "body"],
865
+ attributes: {
866
+ lang: {
867
+ required: true
868
+ },
869
+ version: {
870
+ deprecated: true
871
+ }
872
+ },
873
+ implicitRole() {
874
+ return "document";
875
+ }
876
+ },
877
+ i: {
878
+ flow: true,
879
+ phrasing: true,
880
+ permittedContent: ["@phrasing"]
881
+ },
882
+ iframe: {
883
+ flow: true,
884
+ phrasing: true,
885
+ embedded: true,
886
+ interactive: true,
887
+ attributes: {
888
+ align: {
889
+ deprecated: true
890
+ },
891
+ allowtransparency: {
892
+ deprecated: true
893
+ },
894
+ datafld: {
895
+ deprecated: true
896
+ },
897
+ datasrc: {
898
+ deprecated: true
899
+ },
900
+ frameborder: {
901
+ deprecated: true
902
+ },
903
+ hspace: {
904
+ deprecated: true
905
+ },
906
+ marginheight: {
907
+ deprecated: true
908
+ },
909
+ marginwidth: {
910
+ deprecated: true
911
+ },
912
+ referrerpolicy: {
913
+ enum: ReferrerPolicy
914
+ },
915
+ scrolling: {
916
+ deprecated: true
917
+ },
918
+ src: {
919
+ enum: ["/.+/"]
920
+ },
921
+ title: {
922
+ required: true
923
+ },
924
+ vspace: {
925
+ deprecated: true
926
+ }
927
+ },
928
+ permittedContent: []
929
+ },
930
+ img: {
931
+ flow: true,
932
+ phrasing: true,
933
+ embedded: true,
934
+ interactive: ["hasAttribute", "usemap"],
935
+ void: true,
936
+ attributes: {
937
+ align: {
938
+ deprecated: true
939
+ },
940
+ border: {
941
+ deprecated: true
942
+ },
943
+ crossorigin: {
944
+ omit: true,
945
+ enum: ["anonymous", "use-credentials"]
946
+ },
947
+ datafld: {
948
+ deprecated: true
949
+ },
950
+ datasrc: {
951
+ deprecated: true
952
+ },
953
+ decoding: {
954
+ enum: ["sync", "async", "auto"]
955
+ },
956
+ hspace: {
957
+ deprecated: true
958
+ },
959
+ ismap: {
960
+ boolean: true
961
+ },
962
+ lowsrc: {
963
+ deprecated: true
964
+ },
965
+ name: {
966
+ deprecated: true
967
+ },
968
+ referrerpolicy: {
969
+ enum: ReferrerPolicy
970
+ },
971
+ src: {
972
+ required: true,
973
+ enum: ["/.+/"]
974
+ },
975
+ srcset: {
976
+ enum: ["/[^]+/"]
977
+ },
978
+ vspace: {
979
+ deprecated: true
980
+ }
981
+ },
982
+ implicitRole(node) {
983
+ const alt = node.getAttribute("alt");
984
+ if (alt === "") {
985
+ return "presentation";
986
+ } else {
987
+ return "img";
988
+ }
989
+ }
990
+ },
991
+ input: {
992
+ flow: true,
993
+ focusable(node) {
994
+ return node.getAttribute("type") !== "hidden";
995
+ },
996
+ phrasing: true,
997
+ interactive: ["matchAttribute", ["type", "!=", "hidden"]],
998
+ void: true,
999
+ formAssociated: {
1000
+ listed: true
1001
+ },
1002
+ labelable: ["matchAttribute", ["type", "!=", "hidden"]],
1003
+ attributes: {
1004
+ align: {
1005
+ deprecated: true
1006
+ },
1007
+ autofocus: {
1008
+ boolean: true
1009
+ },
1010
+ capture: {
1011
+ omit: true,
1012
+ enum: ["environment", "user"]
1013
+ },
1014
+ checked: {
1015
+ boolean: true
1016
+ },
1017
+ datafld: {
1018
+ deprecated: true
1019
+ },
1020
+ dataformatas: {
1021
+ deprecated: true
1022
+ },
1023
+ datasrc: {
1024
+ deprecated: true
1025
+ },
1026
+ disabled: {
1027
+ boolean: true
1028
+ },
1029
+ formaction: {
1030
+ allowed: allowedIfAttributeHasValue("type", ["submit", "image"], {
1031
+ defaultValue: "submit"
1032
+ })
1033
+ },
1034
+ formenctype: {
1035
+ allowed: allowedIfAttributeHasValue("type", ["submit", "image"], {
1036
+ defaultValue: "submit"
1037
+ })
1038
+ },
1039
+ formmethod: {
1040
+ allowed: allowedIfAttributeHasValue("type", ["submit", "image"], {
1041
+ defaultValue: "submit"
1042
+ }),
1043
+ enum: ["get", "post", "dialog"]
1044
+ },
1045
+ formnovalidate: {
1046
+ allowed: allowedIfAttributeHasValue("type", ["submit", "image"], {
1047
+ defaultValue: "submit"
1048
+ }),
1049
+ boolean: true
1050
+ },
1051
+ formtarget: {
1052
+ allowed: allowedIfAttributeHasValue("type", ["submit", "image"], {
1053
+ defaultValue: "submit"
1054
+ }),
1055
+ enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"]
1056
+ },
1057
+ hspace: {
1058
+ deprecated: true
1059
+ },
1060
+ inputmode: {
1061
+ enum: ["none", "text", "decimal", "numeric", "tel", "search", "email", "url"]
1062
+ },
1063
+ ismap: {
1064
+ deprecated: true
1065
+ },
1066
+ multiple: {
1067
+ boolean: true
1068
+ },
1069
+ readonly: {
1070
+ boolean: true
1071
+ },
1072
+ required: {
1073
+ boolean: true
1074
+ },
1075
+ spellcheck: {
1076
+ enum: ["default", "false", "true"]
1077
+ },
1078
+ type: {
1079
+ required: true,
1080
+ enum: [
1081
+ "button",
1082
+ "checkbox",
1083
+ "color",
1084
+ "date",
1085
+ "datetime-local",
1086
+ "email",
1087
+ "file",
1088
+ "hidden",
1089
+ "image",
1090
+ "month",
1091
+ "number",
1092
+ "password",
1093
+ "radio",
1094
+ "range",
1095
+ "reset",
1096
+ "search",
1097
+ "submit",
1098
+ "tel",
1099
+ "text",
1100
+ "time",
1101
+ "url",
1102
+ "week"
1103
+ ]
1104
+ },
1105
+ usemap: {
1106
+ deprecated: true
1107
+ },
1108
+ vspace: {
1109
+ deprecated: true
1110
+ }
1111
+ },
1112
+ /* eslint-disable-next-line complexity -- the standard is complicated */
1113
+ implicitRole(node) {
1114
+ const list = node.hasAttribute("list");
1115
+ if (list) {
1116
+ return "combobox";
1117
+ }
1118
+ const type = node.getAttribute("type");
1119
+ switch (type) {
1120
+ case "button":
1121
+ return "button";
1122
+ case "checkbox":
1123
+ return "checkbox";
1124
+ case "email":
1125
+ return "textbox";
1126
+ case "image":
1127
+ return "button";
1128
+ case "number":
1129
+ return "spinbutton";
1130
+ case "radio":
1131
+ return "radio";
1132
+ case "range":
1133
+ return "slider";
1134
+ case "reset":
1135
+ return "button";
1136
+ case "search":
1137
+ return "searchbox";
1138
+ case "submit":
1139
+ return "button";
1140
+ case "tel":
1141
+ return "textbox";
1142
+ case "text":
1143
+ return "textbox";
1144
+ case "url":
1145
+ return "textbox";
1146
+ default:
1147
+ return "textbox";
1148
+ }
1149
+ }
1150
+ },
1151
+ ins: {
1152
+ flow: true,
1153
+ phrasing: true,
1154
+ transparent: true
1155
+ },
1156
+ isindex: {
1157
+ deprecated: {
1158
+ source: "html4"
1159
+ }
1160
+ },
1161
+ kbd: {
1162
+ flow: true,
1163
+ phrasing: true,
1164
+ permittedContent: ["@phrasing"]
1165
+ },
1166
+ keygen: {
1167
+ flow: true,
1168
+ phrasing: true,
1169
+ interactive: true,
1170
+ void: true,
1171
+ labelable: true,
1172
+ deprecated: true
1173
+ },
1174
+ label: {
1175
+ flow: true,
1176
+ phrasing: true,
1177
+ interactive: true,
1178
+ permittedContent: ["@phrasing"],
1179
+ permittedDescendants: [{ exclude: ["label"] }],
1180
+ attributes: {
1181
+ datafld: {
1182
+ deprecated: true
1183
+ },
1184
+ dataformatas: {
1185
+ deprecated: true
1186
+ },
1187
+ datasrc: {
1188
+ deprecated: true
1189
+ },
1190
+ for: {
1191
+ enum: [validId]
1192
+ }
1193
+ }
1194
+ },
1195
+ legend: {
1196
+ permittedContent: ["@phrasing", "@heading"],
1197
+ attributes: {
1198
+ align: {
1199
+ deprecated: true
1200
+ },
1201
+ datafld: {
1202
+ deprecated: true
1203
+ },
1204
+ dataformatas: {
1205
+ deprecated: true
1206
+ },
1207
+ datasrc: {
1208
+ deprecated: true
1209
+ }
1210
+ }
1211
+ },
1212
+ li: {
1213
+ implicitClosed: ["li"],
1214
+ permittedContent: ["@flow"],
1215
+ permittedParent: ["ul", "ol", "menu", "template"],
1216
+ attributes: {
1217
+ type: {
1218
+ deprecated: true
1219
+ }
1220
+ },
1221
+ implicitRole(node) {
1222
+ return node.closest("ul, ol, menu") ? "listitem" : null;
1223
+ }
1224
+ },
1225
+ link: {
1226
+ metadata: true,
1227
+ void: true,
1228
+ attributes: {
1229
+ as: {
1230
+ allowed: allowedIfAttributeHasValue("rel", ["prefetch", "preload", "modulepreload"]),
1231
+ enum: [
1232
+ "audio",
1233
+ "audioworklet",
1234
+ "document",
1235
+ "embed",
1236
+ "fetch",
1237
+ "font",
1238
+ "frame",
1239
+ "iframe",
1240
+ "image",
1241
+ "manifest",
1242
+ "object",
1243
+ "paintworklet",
1244
+ "report",
1245
+ "script",
1246
+ "serviceworker",
1247
+ "sharedworker",
1248
+ "style",
1249
+ "track",
1250
+ "video",
1251
+ "webidentity",
1252
+ "worker",
1253
+ "xslt"
1254
+ ]
1255
+ },
1256
+ blocking: {
1257
+ allowed: allowedIfAttributeHasValue("rel", ["stylesheet", "preload", "modulepreload"]),
1258
+ list: true,
1259
+ enum: ["render"]
1260
+ },
1261
+ charset: {
1262
+ deprecated: true
1263
+ },
1264
+ crossorigin: {
1265
+ omit: true,
1266
+ enum: ["anonymous", "use-credentials"]
1267
+ },
1268
+ disabled: {
1269
+ allowed: allowedIfAttributeHasValue("rel", ["stylesheet"]),
1270
+ boolean: true
1271
+ },
1272
+ href: {
1273
+ required: true,
1274
+ enum: ["/.+/"]
1275
+ },
1276
+ integrity: {
1277
+ allowed: allowedIfAttributeHasValue("rel", ["stylesheet", "preload", "modulepreload"]),
1278
+ enum: ["/.+/"]
1279
+ },
1280
+ methods: {
1281
+ deprecated: true
1282
+ },
1283
+ referrerpolicy: {
1284
+ enum: ReferrerPolicy
1285
+ },
1286
+ target: {
1287
+ deprecated: true
1288
+ },
1289
+ urn: {
1290
+ deprecated: true
1291
+ }
1292
+ }
1293
+ },
1294
+ listing: {
1295
+ deprecated: {
1296
+ source: "html32"
1297
+ }
1298
+ },
1299
+ main: {
1300
+ flow: true,
1301
+ implicitRole() {
1302
+ return "main";
1303
+ }
1304
+ },
1305
+ map: {
1306
+ flow: true,
1307
+ phrasing: true,
1308
+ transparent: true,
1309
+ attributes: {
1310
+ name: {
1311
+ required: true,
1312
+ enum: ["/\\S+/"]
1313
+ }
1314
+ }
1315
+ },
1316
+ mark: {
1317
+ flow: true,
1318
+ phrasing: true,
1319
+ permittedContent: ["@phrasing"]
1320
+ },
1321
+ marquee: {
1322
+ deprecated: {
1323
+ documentation: "Marked as obsolete by both W3C and WHATWG standards but still implemented in most browsers. Animated text should be avoided for accessibility reasons as well.",
1324
+ source: "html5"
1325
+ },
1326
+ attributes: {
1327
+ datafld: {
1328
+ deprecated: true
1329
+ },
1330
+ dataformatas: {
1331
+ deprecated: true
1332
+ },
1333
+ datasrc: {
1334
+ deprecated: true
1335
+ }
1336
+ }
1337
+ },
1338
+ math: {
1339
+ flow: true,
1340
+ foreign: true,
1341
+ phrasing: true,
1342
+ embedded: true,
1343
+ attributes: {
1344
+ align: {
1345
+ deprecated: true
1346
+ },
1347
+ dir: {
1348
+ enum: ["ltr", "rtl"]
1349
+ },
1350
+ display: {
1351
+ enum: ["block", "inline"]
1352
+ },
1353
+ hspace: {
1354
+ deprecated: true
1355
+ },
1356
+ name: {
1357
+ deprecated: true
1358
+ },
1359
+ overflow: {
1360
+ enum: ["linebreak", "scroll", "elide", "truncate", "scale"]
1361
+ },
1362
+ vspace: {
1363
+ deprecated: true
1364
+ }
1365
+ },
1366
+ implicitRole() {
1367
+ return "math";
1368
+ }
1369
+ },
1370
+ menu: {
1371
+ flow: true,
1372
+ implicitRole() {
1373
+ return "list";
1374
+ },
1375
+ permittedContent: ["@script", "li"]
1376
+ },
1377
+ meta: {
1378
+ flow: ["hasAttribute", "itemprop"],
1379
+ phrasing: ["hasAttribute", "itemprop"],
1380
+ metadata: true,
1381
+ void: true,
1382
+ attributes: {
1383
+ charset: {
1384
+ enum: ["utf-8"]
1385
+ },
1386
+ content: {
1387
+ allowed: allowedIfAttributeIsPresent("name", "http-equiv", "itemprop", "property")
1388
+ },
1389
+ itemprop: {
1390
+ allowed: allowedIfAttributeIsAbsent("http-equiv", "name")
1391
+ },
1392
+ name: {
1393
+ allowed: allowedIfAttributeIsAbsent("http-equiv", "itemprop")
1394
+ },
1395
+ "http-equiv": {
1396
+ allowed: allowedIfAttributeIsAbsent("name", "itemprop")
1397
+ },
1398
+ scheme: {
1399
+ deprecated: true
1400
+ }
1401
+ }
1402
+ },
1403
+ meter: {
1404
+ flow: true,
1405
+ phrasing: true,
1406
+ labelable: true,
1407
+ implicitRole() {
1408
+ return "meter";
1409
+ },
1410
+ permittedContent: ["@phrasing"],
1411
+ permittedDescendants: [{ exclude: "meter" }]
1412
+ },
1413
+ multicol: {
1414
+ deprecated: {
1415
+ message: "use CSS instead",
1416
+ documentation: "Use CSS columns instead.",
1417
+ source: "html5"
1418
+ }
1419
+ },
1420
+ nav: {
1421
+ flow: true,
1422
+ sectioning: true,
1423
+ implicitRole() {
1424
+ return "navigation";
1425
+ },
1426
+ permittedContent: ["@flow"],
1427
+ permittedDescendants: [{ exclude: "main" }]
1428
+ },
1429
+ nextid: {
1430
+ deprecated: {
1431
+ source: "html32"
1432
+ }
1433
+ },
1434
+ nobr: {
1435
+ deprecated: {
1436
+ message: "use CSS instead",
1437
+ documentation: "Use CSS `white-space` property instead.",
1438
+ source: "non-standard"
1439
+ }
1440
+ },
1441
+ noembed: {
1442
+ deprecated: {
1443
+ source: "non-standard"
1444
+ }
1445
+ },
1446
+ noframes: {
1447
+ deprecated: {
1448
+ source: "html5"
1449
+ }
1450
+ },
1451
+ noscript: {
1452
+ metadata: true,
1453
+ flow: true,
1454
+ phrasing: true,
1455
+ transparent: true,
1456
+ permittedDescendants: [{ exclude: "noscript" }]
1457
+ },
1458
+ object: {
1459
+ flow: true,
1460
+ phrasing: true,
1461
+ embedded: true,
1462
+ interactive: ["hasAttribute", "usemap"],
1463
+ transparent: true,
1464
+ formAssociated: {
1465
+ listed: true
1466
+ },
1467
+ attributes: {
1468
+ align: {
1469
+ deprecated: true
1470
+ },
1471
+ archive: {
1472
+ deprecated: true
1473
+ },
1474
+ blocking: {
1475
+ list: true,
1476
+ enum: ["render"]
1477
+ },
1478
+ border: {
1479
+ deprecated: true
1480
+ },
1481
+ classid: {
1482
+ deprecated: true
1483
+ },
1484
+ code: {
1485
+ deprecated: true
1486
+ },
1487
+ codebase: {
1488
+ deprecated: true
1489
+ },
1490
+ codetype: {
1491
+ deprecated: true
1492
+ },
1493
+ data: {
1494
+ enum: ["/.+/"],
1495
+ required: true
1496
+ },
1497
+ datafld: {
1498
+ deprecated: true
1499
+ },
1500
+ dataformatas: {
1501
+ deprecated: true
1502
+ },
1503
+ datasrc: {
1504
+ deprecated: true
1505
+ },
1506
+ declare: {
1507
+ deprecated: true
1508
+ },
1509
+ hspace: {
1510
+ deprecated: true
1511
+ },
1512
+ name: {
1513
+ enum: ["/[^_].*/"]
1514
+ },
1515
+ standby: {
1516
+ deprecated: true
1517
+ },
1518
+ vspace: {
1519
+ deprecated: true
1520
+ }
1521
+ },
1522
+ permittedContent: ["param", "@flow"],
1523
+ permittedOrder: ["param", "@flow"]
1524
+ },
1525
+ ol: {
1526
+ flow: true,
1527
+ attributes: {
1528
+ compact: {
1529
+ deprecated: true
1530
+ },
1531
+ reversed: {
1532
+ boolean: true
1533
+ },
1534
+ type: {
1535
+ enum: ["a", "A", "i", "I", "1"]
1536
+ }
1537
+ },
1538
+ implicitRole() {
1539
+ return "list";
1540
+ },
1541
+ permittedContent: ["@script", "li"]
1542
+ },
1543
+ optgroup: {
1544
+ implicitClosed: ["optgroup"],
1545
+ attributes: {
1546
+ disabled: {
1547
+ boolean: true
1548
+ }
1549
+ },
1550
+ implicitRole() {
1551
+ return "group";
1552
+ },
1553
+ permittedContent: ["@script", "option"]
1554
+ },
1555
+ option: {
1556
+ implicitClosed: ["option"],
1557
+ attributes: {
1558
+ dataformatas: {
1559
+ deprecated: true
1560
+ },
1561
+ datasrc: {
1562
+ deprecated: true
1563
+ },
1564
+ disabled: {
1565
+ boolean: true
1566
+ },
1567
+ name: {
1568
+ deprecated: true
1569
+ },
1570
+ selected: {
1571
+ boolean: true
1572
+ }
1573
+ },
1574
+ implicitRole() {
1575
+ return "option";
1576
+ },
1577
+ permittedContent: []
1578
+ },
1579
+ output: {
1580
+ flow: true,
1581
+ phrasing: true,
1582
+ formAssociated: {
1583
+ listed: true
1584
+ },
1585
+ labelable: true,
1586
+ implicitRole() {
1587
+ return "status";
1588
+ },
1589
+ permittedContent: ["@phrasing"]
1590
+ },
1591
+ p: {
1592
+ flow: true,
1593
+ implicitClosed: [
1594
+ "address",
1595
+ "article",
1596
+ "aside",
1597
+ "blockquote",
1598
+ "div",
1599
+ "dl",
1600
+ "fieldset",
1601
+ "footer",
1602
+ "form",
1603
+ "h1",
1604
+ "h2",
1605
+ "h3",
1606
+ "h4",
1607
+ "h5",
1608
+ "h6",
1609
+ "header",
1610
+ "hgroup",
1611
+ "hr",
1612
+ "main",
1613
+ "nav",
1614
+ "ol",
1615
+ "p",
1616
+ "pre",
1617
+ "section",
1618
+ "table",
1619
+ "ul"
1620
+ ],
1621
+ permittedContent: ["@phrasing"],
1622
+ attributes: {
1623
+ align: {
1624
+ deprecated: true
1625
+ }
1626
+ }
1627
+ },
1628
+ param: {
1629
+ void: true,
1630
+ attributes: {
1631
+ datafld: {
1632
+ deprecated: true
1633
+ },
1634
+ type: {
1635
+ deprecated: true
1636
+ },
1637
+ valuetype: {
1638
+ deprecated: true
1639
+ }
1640
+ }
1641
+ },
1642
+ picture: {
1643
+ flow: true,
1644
+ phrasing: true,
1645
+ embedded: true,
1646
+ permittedContent: ["@script", "source", "img"],
1647
+ permittedOrder: ["source", "img"]
1648
+ },
1649
+ plaintext: {
1650
+ deprecated: {
1651
+ message: "use <pre> or CSS instead",
1652
+ documentation: "Use the `<pre>` element or use CSS to set a monospace font.",
1653
+ source: "html2"
1654
+ }
1655
+ },
1656
+ pre: {
1657
+ flow: true,
1658
+ permittedContent: ["@phrasing"],
1659
+ attributes: {
1660
+ width: {
1661
+ deprecated: true
1662
+ }
1663
+ }
1664
+ },
1665
+ progress: {
1666
+ flow: true,
1667
+ phrasing: true,
1668
+ labelable: true,
1669
+ implicitRole() {
1670
+ return "progressbar";
1671
+ },
1672
+ permittedContent: ["@phrasing"],
1673
+ permittedDescendants: [{ exclude: "progress" }]
1674
+ },
1675
+ q: {
1676
+ flow: true,
1677
+ phrasing: true,
1678
+ permittedContent: ["@phrasing"]
1679
+ },
1680
+ rb: {
1681
+ implicitClosed: ["rb", "rt", "rtc", "rp"],
1682
+ permittedContent: ["@phrasing"]
1683
+ },
1684
+ rp: {
1685
+ implicitClosed: ["rb", "rt", "rtc", "rp"],
1686
+ permittedContent: ["@phrasing"]
1687
+ },
1688
+ rt: {
1689
+ implicitClosed: ["rb", "rt", "rtc", "rp"],
1690
+ permittedContent: ["@phrasing"]
1691
+ },
1692
+ rtc: {
1693
+ implicitClosed: ["rb", "rtc", "rp"],
1694
+ permittedContent: ["@phrasing", "rt"]
1695
+ },
1696
+ ruby: {
1697
+ flow: true,
1698
+ phrasing: true,
1699
+ permittedContent: ["@phrasing", "rb", "rp", "rt", "rtc"]
1700
+ },
1701
+ s: {
1702
+ flow: true,
1703
+ phrasing: true,
1704
+ permittedContent: ["@phrasing"]
1705
+ },
1706
+ samp: {
1707
+ flow: true,
1708
+ phrasing: true,
1709
+ permittedContent: ["@phrasing"]
1710
+ },
1711
+ script: {
1712
+ metadata: true,
1713
+ flow: true,
1714
+ phrasing: true,
1715
+ scriptSupporting: true,
1716
+ attributes: {
1717
+ async: {
1718
+ boolean: true
1719
+ },
1720
+ crossorigin: {
1721
+ omit: true,
1722
+ enum: ["anonymous", "use-credentials"]
1723
+ },
1724
+ defer: {
1725
+ boolean: true
1726
+ },
1727
+ event: {
1728
+ deprecated: true
1729
+ },
1730
+ for: {
1731
+ deprecated: true
1732
+ },
1733
+ integrity: {
1734
+ allowed: allowedIfAttributeIsPresent("src"),
1735
+ enum: ["/.+/"]
1736
+ },
1737
+ language: {
1738
+ deprecated: true
1739
+ },
1740
+ nomodule: {
1741
+ boolean: true
1742
+ },
1743
+ referrerpolicy: {
1744
+ enum: ReferrerPolicy
1745
+ },
1746
+ src: {
1747
+ enum: ["/.+/"]
1748
+ }
1749
+ }
1750
+ },
1751
+ search: {
1752
+ flow: true,
1753
+ implicitRole() {
1754
+ return "search";
1755
+ }
1756
+ },
1757
+ section: {
1758
+ flow: true,
1759
+ sectioning: true,
1760
+ implicitRole() {
1761
+ return "region";
1762
+ },
1763
+ permittedContent: ["@flow"]
1764
+ },
1765
+ select: {
1766
+ flow: true,
1767
+ focusable: true,
1768
+ phrasing: true,
1769
+ interactive: true,
1770
+ formAssociated: {
1771
+ listed: true
1772
+ },
1773
+ labelable: true,
1774
+ attributes: {
1775
+ autofocus: {
1776
+ boolean: true
1777
+ },
1778
+ disabled: {
1779
+ boolean: true
1780
+ },
1781
+ multiple: {
1782
+ boolean: true
1783
+ },
1784
+ required: {
1785
+ boolean: true
1786
+ },
1787
+ size: {
1788
+ enum: ["/\\d+/"]
1789
+ }
1790
+ },
1791
+ implicitRole(node) {
1792
+ const multiple = node.hasAttribute("multiple");
1793
+ if (multiple) {
1794
+ return "listbox";
1795
+ }
1796
+ const size = node.getAttribute("size");
1797
+ if (typeof size === "string") {
1798
+ const parsed = parseInt(size, 10);
1799
+ if (parsed > 1) {
1800
+ return "listbox";
1801
+ }
1802
+ }
1803
+ return "combobox";
1804
+ },
1805
+ permittedContent: ["@script", "datasrc", "datafld", "dataformatas", "option", "optgroup"]
1806
+ },
1807
+ slot: {
1808
+ flow: true,
1809
+ phrasing: true,
1810
+ transparent: true
1811
+ },
1812
+ small: {
1813
+ flow: true,
1814
+ phrasing: true,
1815
+ permittedContent: ["@phrasing"]
1816
+ },
1817
+ source: {
1818
+ void: true,
1819
+ attributes: {
1820
+ type: {},
1821
+ media: {},
1822
+ src: {
1823
+ allowed: allowedIfParentIsPresent("audio", "video")
1824
+ },
1825
+ srcset: {
1826
+ allowed: allowedIfParentIsPresent("picture")
1827
+ },
1828
+ sizes: {
1829
+ allowed: allowedIfParentIsPresent("picture")
1830
+ },
1831
+ width: {
1832
+ allowed: allowedIfParentIsPresent("picture"),
1833
+ enum: ["/\\d+/"]
1834
+ },
1835
+ height: {
1836
+ allowed: allowedIfParentIsPresent("picture"),
1837
+ enum: ["/\\d+/"]
1838
+ }
1839
+ }
1840
+ },
1841
+ spacer: {
1842
+ deprecated: {
1843
+ message: "use CSS instead",
1844
+ documentation: "Use CSS margin or padding instead.",
1845
+ source: "non-standard"
1846
+ }
1847
+ },
1848
+ span: {
1849
+ flow: true,
1850
+ phrasing: true,
1851
+ permittedContent: ["@phrasing"],
1852
+ attributes: {
1853
+ datafld: {
1854
+ deprecated: true
1855
+ },
1856
+ dataformatas: {
1857
+ deprecated: true
1858
+ },
1859
+ datasrc: {
1860
+ deprecated: true
1861
+ }
1862
+ }
1863
+ },
1864
+ strike: {
1865
+ deprecated: {
1866
+ message: "use <del> or <s> instead",
1867
+ documentation: "Use the `<del>` or `<s>` element instead.",
1868
+ source: "html5"
1869
+ }
1870
+ },
1871
+ strong: {
1872
+ flow: true,
1873
+ phrasing: true,
1874
+ permittedContent: ["@phrasing"]
1875
+ },
1876
+ style: {
1877
+ metadata: true
1878
+ },
1879
+ sub: {
1880
+ flow: true,
1881
+ phrasing: true,
1882
+ permittedContent: ["@phrasing"]
1883
+ },
1884
+ summary: {
1885
+ permittedContent: ["@phrasing", "@heading"]
1886
+ },
1887
+ sup: {
1888
+ flow: true,
1889
+ phrasing: true,
1890
+ permittedContent: ["@phrasing"]
1891
+ },
1892
+ svg: {
1893
+ flow: true,
1894
+ foreign: true,
1895
+ phrasing: true,
1896
+ embedded: true
1897
+ },
1898
+ /* while not part of HTML 5 specification these two elements are handled as
1899
+ * special cases to allow them as accessible text and to avoid issues with
1900
+ * "no-unknown-elements" they are added here */
1901
+ "svg:desc": {},
1902
+ "svg:title": {},
1903
+ table: {
1904
+ flow: true,
1905
+ permittedContent: ["@script", "caption?", "colgroup", "tbody", "tfoot?", "thead?", "tr"],
1906
+ permittedOrder: ["caption", "colgroup", "thead", "tbody", "tr", "tfoot"],
1907
+ attributes: {
1908
+ align: {
1909
+ deprecated: true
1910
+ },
1911
+ background: {
1912
+ deprecated: true
1913
+ },
1914
+ bgcolor: {
1915
+ deprecated: true
1916
+ },
1917
+ bordercolor: {
1918
+ deprecated: true
1919
+ },
1920
+ cellpadding: {
1921
+ deprecated: true
1922
+ },
1923
+ cellspacing: {
1924
+ deprecated: true
1925
+ },
1926
+ dataformatas: {
1927
+ deprecated: true
1928
+ },
1929
+ datapagesize: {
1930
+ deprecated: true
1931
+ },
1932
+ datasrc: {
1933
+ deprecated: true
1934
+ },
1935
+ frame: {
1936
+ deprecated: true
1937
+ },
1938
+ rules: {
1939
+ deprecated: true
1940
+ },
1941
+ summary: {
1942
+ deprecated: true
1943
+ },
1944
+ width: {
1945
+ deprecated: true
1946
+ }
1947
+ },
1948
+ implicitRole() {
1949
+ return "table";
1950
+ }
1951
+ },
1952
+ tbody: {
1953
+ implicitClosed: ["tbody", "tfoot"],
1954
+ permittedContent: ["@script", "tr"],
1955
+ attributes: {
1956
+ align: {
1957
+ deprecated: true
1958
+ },
1959
+ background: {
1960
+ deprecated: true
1961
+ },
1962
+ char: {
1963
+ deprecated: true
1964
+ },
1965
+ charoff: {
1966
+ deprecated: true
1967
+ },
1968
+ valign: {
1969
+ deprecated: true
1970
+ }
1971
+ },
1972
+ implicitRole() {
1973
+ return "rowgroup";
1974
+ }
1975
+ },
1976
+ td: {
1977
+ flow: true,
1978
+ implicitClosed: ["td", "th"],
1979
+ attributes: {
1980
+ align: {
1981
+ deprecated: true
1982
+ },
1983
+ axis: {
1984
+ deprecated: true
1985
+ },
1986
+ background: {
1987
+ deprecated: true
1988
+ },
1989
+ bgcolor: {
1990
+ deprecated: true
1991
+ },
1992
+ char: {
1993
+ deprecated: true
1994
+ },
1995
+ charoff: {
1996
+ deprecated: true
1997
+ },
1998
+ colspan: {
1999
+ enum: ["/\\d+/"]
2000
+ },
2001
+ height: {
2002
+ deprecated: true
2003
+ },
2004
+ nowrap: {
2005
+ deprecated: true
2006
+ },
2007
+ rowspan: {
2008
+ enum: ["/\\d+/"]
2009
+ },
2010
+ scope: {
2011
+ deprecated: true
2012
+ },
2013
+ valign: {
2014
+ deprecated: true
2015
+ },
2016
+ width: {
2017
+ deprecated: true
2018
+ }
2019
+ },
2020
+ implicitRole(node) {
2021
+ if (node.closest('table[role="grid"], table[role="treegrid"]')) {
2022
+ return "gridcell";
2023
+ } else if (node.closest("table")) {
2024
+ return "cell";
2025
+ } else {
2026
+ return null;
2027
+ }
2028
+ },
2029
+ permittedContent: ["@flow"]
2030
+ },
2031
+ template: {
2032
+ metadata: true,
2033
+ flow: true,
2034
+ phrasing: true,
2035
+ scriptSupporting: true
2036
+ },
2037
+ textarea: {
2038
+ flow: true,
2039
+ focusable: true,
2040
+ phrasing: true,
2041
+ interactive: true,
2042
+ formAssociated: {
2043
+ listed: true
2044
+ },
2045
+ labelable: true,
2046
+ attributes: {
2047
+ autocomplete: {
2048
+ enum: ["on", "off"]
2049
+ },
2050
+ autofocus: {
2051
+ boolean: true
2052
+ },
2053
+ cols: {
2054
+ enum: ["/\\d+/"]
2055
+ },
2056
+ datafld: {
2057
+ deprecated: true
2058
+ },
2059
+ datasrc: {
2060
+ deprecated: true
2061
+ },
2062
+ disabled: {
2063
+ boolean: true
2064
+ },
2065
+ maxlength: {
2066
+ enum: ["/\\d+/"]
2067
+ },
2068
+ minlength: {
2069
+ enum: ["/\\d+/"]
2070
+ },
2071
+ readonly: {
2072
+ boolean: true
2073
+ },
2074
+ required: {
2075
+ boolean: true
2076
+ },
2077
+ rows: {
2078
+ enum: ["/\\d+/"]
2079
+ },
2080
+ spellcheck: {
2081
+ enum: ["true", "default", "false"]
2082
+ },
2083
+ wrap: {
2084
+ enum: ["hard", "soft"]
2085
+ }
2086
+ },
2087
+ implicitRole() {
2088
+ return "textbox";
2089
+ },
2090
+ permittedContent: []
2091
+ },
2092
+ tfoot: {
2093
+ implicitClosed: ["tbody"],
2094
+ permittedContent: ["@script", "tr"],
2095
+ attributes: {
2096
+ align: {
2097
+ deprecated: true
2098
+ },
2099
+ background: {
2100
+ deprecated: true
2101
+ },
2102
+ char: {
2103
+ deprecated: true
2104
+ },
2105
+ charoff: {
2106
+ deprecated: true
2107
+ },
2108
+ valign: {
2109
+ deprecated: true
2110
+ }
2111
+ },
2112
+ implicitRole() {
2113
+ return "rowgroup";
2114
+ }
2115
+ },
2116
+ th: {
2117
+ flow: true,
2118
+ implicitClosed: ["td", "th"],
2119
+ attributes: {
2120
+ align: {
2121
+ deprecated: true
2122
+ },
2123
+ axis: {
2124
+ deprecated: true
2125
+ },
2126
+ background: {
2127
+ deprecated: true
2128
+ },
2129
+ bgcolor: {
2130
+ deprecated: true
2131
+ },
2132
+ char: {
2133
+ deprecated: true
2134
+ },
2135
+ charoff: {
2136
+ deprecated: true
2137
+ },
2138
+ colspan: {
2139
+ enum: ["/\\d+/"]
2140
+ },
2141
+ height: {
2142
+ deprecated: true
2143
+ },
2144
+ nowrap: {
2145
+ deprecated: true
2146
+ },
2147
+ rowspan: {
2148
+ enum: ["/\\d+/"]
2149
+ },
2150
+ scope: {
2151
+ enum: ["row", "col", "rowgroup", "colgroup"]
2152
+ },
2153
+ valign: {
2154
+ deprecated: true
2155
+ },
2156
+ width: {
2157
+ deprecated: true
2158
+ }
2159
+ },
2160
+ implicitRole(node) {
2161
+ const table = node.closest("table");
2162
+ if (!table) {
2163
+ return null;
2164
+ }
2165
+ const tableRole = table.getAttribute("role") ?? "table";
2166
+ if (typeof tableRole !== "string" || !["table", "grid", "treegrid"].includes(tableRole)) {
2167
+ return null;
2168
+ }
2169
+ const scope = node.getAttribute("scope");
2170
+ switch (scope) {
2171
+ case "col":
2172
+ return "columnheader";
2173
+ case "row":
2174
+ return "rowheader";
2175
+ default:
2176
+ return tableRole === "table" ? "cell" : "gridcell";
2177
+ }
2178
+ },
2179
+ permittedContent: ["@flow"],
2180
+ permittedDescendants: [{ exclude: ["header", "footer", "@sectioning", "@heading"] }]
2181
+ },
2182
+ thead: {
2183
+ implicitClosed: ["tbody", "tfoot"],
2184
+ permittedContent: ["@script", "tr"],
2185
+ attributes: {
2186
+ align: {
2187
+ deprecated: true
2188
+ },
2189
+ background: {
2190
+ deprecated: true
2191
+ },
2192
+ char: {
2193
+ deprecated: true
2194
+ },
2195
+ charoff: {
2196
+ deprecated: true
2197
+ },
2198
+ valign: {
2199
+ deprecated: true
2200
+ }
2201
+ },
2202
+ implicitRole() {
2203
+ return "rowgroup";
2204
+ }
2205
+ },
2206
+ time: {
2207
+ flow: true,
2208
+ phrasing: true,
2209
+ implicitRole() {
2210
+ return "time";
2211
+ },
2212
+ permittedContent: ["@phrasing"]
2213
+ },
2214
+ title: {
2215
+ metadata: true,
2216
+ permittedContent: [],
2217
+ permittedParent: ["head"]
2218
+ },
2219
+ tr: {
2220
+ implicitClosed: ["tr"],
2221
+ permittedContent: ["@script", "td", "th"],
2222
+ attributes: {
2223
+ align: {
2224
+ deprecated: true
2225
+ },
2226
+ background: {
2227
+ deprecated: true
2228
+ },
2229
+ bgcolor: {
2230
+ deprecated: true
2231
+ },
2232
+ char: {
2233
+ deprecated: true
2234
+ },
2235
+ charoff: {
2236
+ deprecated: true
2237
+ },
2238
+ valign: {
2239
+ deprecated: true
2240
+ }
2241
+ },
2242
+ implicitRole() {
2243
+ return "row";
2244
+ }
2245
+ },
2246
+ track: {
2247
+ void: true
2248
+ },
2249
+ tt: {
2250
+ deprecated: {
2251
+ documentation: "Use a more semantically correct element such as `<code>`, `<var>` or `<pre>`.",
2252
+ source: "html4"
2253
+ }
2254
+ },
2255
+ u: {
2256
+ flow: true,
2257
+ phrasing: true,
2258
+ permittedContent: ["@phrasing"]
2259
+ },
2260
+ ul: {
2261
+ flow: true,
2262
+ permittedContent: ["@script", "li"],
2263
+ attributes: {
2264
+ compact: {
2265
+ deprecated: true
2266
+ },
2267
+ type: {
2268
+ deprecated: true
2269
+ }
2270
+ },
2271
+ implicitRole() {
2272
+ return "list";
2273
+ }
2274
+ },
2275
+ var: {
2276
+ flow: true,
2277
+ phrasing: true,
2278
+ permittedContent: ["@phrasing"]
2279
+ },
2280
+ video: {
2281
+ flow: true,
2282
+ focusable(node) {
2283
+ return node.hasAttribute("controls");
2284
+ },
2285
+ phrasing: true,
2286
+ embedded: true,
2287
+ interactive: ["hasAttribute", "controls"],
2288
+ transparent: ["@flow"],
2289
+ attributes: {
2290
+ crossorigin: {
2291
+ omit: true,
2292
+ enum: ["anonymous", "use-credentials"]
2293
+ },
2294
+ itemprop: {
2295
+ allowed: allowedIfAttributeIsPresent("src")
2296
+ },
2297
+ preload: {
2298
+ omit: true,
2299
+ enum: ["none", "metadata", "auto"]
2300
+ }
2301
+ },
2302
+ permittedContent: ["@flow", "track", "source"],
2303
+ permittedDescendants: [{ exclude: ["audio", "video"] }],
2304
+ permittedOrder: ["source", "track", "@flow"]
2305
+ },
2306
+ wbr: {
2307
+ flow: true,
2308
+ phrasing: true,
2309
+ void: true
2310
+ },
2311
+ xmp: {
2312
+ deprecated: {
2313
+ documentation: "Use `<pre>` or `<code>` and escape content using HTML entities instead.",
2314
+ source: "html32"
2315
+ }
2316
+ }
2302
2317
  });
2303
2318
 
2304
2319
  const bundledElements = {
2305
- html5,
2320
+ html5
2306
2321
  };
2307
2322
 
2308
2323
  var entities = [