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