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