html-validate 8.2.0 → 8.4.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.
@@ -4,6 +4,7 @@ var metaHelper = require('./meta-helper.js');
4
4
 
5
5
  /* eslint-disable sonarjs/no-duplicate-string -- easier to read without constants */
6
6
  const { allowedIfAttributeIsPresent, allowedIfAttributeIsAbsent, allowedIfAttributeHasValue, allowedIfParentIsPresent, } = metaHelper.metadataHelper;
7
+ const validId = "/\\S+/";
7
8
  var html5 = metaHelper.defineMetadata({
8
9
  "*": {
9
10
  attributes: {
@@ -24,7 +25,7 @@ var html5 = metaHelper.defineMetadata({
24
25
  boolean: true,
25
26
  },
26
27
  id: {
27
- enum: ["/\\S+/"],
28
+ enum: [validId],
28
29
  },
29
30
  tabindex: {
30
31
  enum: ["/-?\\d+/"],
@@ -93,6 +94,9 @@ var html5 = metaHelper.defineMetadata({
93
94
  },
94
95
  },
95
96
  permittedDescendants: [{ exclude: "@interactive" }],
97
+ implicitRole(node) {
98
+ return node.hasAttribute("href") ? "link" : null;
99
+ },
96
100
  },
97
101
  abbr: {
98
102
  flow: true,
@@ -108,6 +112,9 @@ var html5 = metaHelper.defineMetadata({
108
112
  },
109
113
  address: {
110
114
  flow: true,
115
+ implicitRole() {
116
+ return "group";
117
+ },
111
118
  permittedContent: ["@flow"],
112
119
  permittedDescendants: [{ exclude: ["address", "header", "footer", "@heading", "@sectioning"] }],
113
120
  },
@@ -181,6 +188,9 @@ var html5 = metaHelper.defineMetadata({
181
188
  enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"],
182
189
  },
183
190
  },
191
+ implicitRole(node) {
192
+ return node.hasAttribute("href") ? "link" : null;
193
+ },
184
194
  requiredAncestors: ["map"],
185
195
  },
186
196
  article: {
@@ -188,12 +198,18 @@ var html5 = metaHelper.defineMetadata({
188
198
  sectioning: true,
189
199
  permittedContent: ["@flow"],
190
200
  permittedDescendants: [{ exclude: ["main"] }],
201
+ implicitRole() {
202
+ return "article";
203
+ },
191
204
  },
192
205
  aside: {
193
206
  flow: true,
194
207
  sectioning: true,
195
208
  permittedContent: ["@flow"],
196
209
  permittedDescendants: [{ exclude: ["main"] }],
210
+ implicitRole() {
211
+ return "complementary";
212
+ },
197
213
  },
198
214
  audio: {
199
215
  flow: true,
@@ -268,6 +284,9 @@ var html5 = metaHelper.defineMetadata({
268
284
  blockquote: {
269
285
  flow: true,
270
286
  sectioning: true,
287
+ implicitRole() {
288
+ return "blockquote";
289
+ },
271
290
  permittedContent: ["@flow"],
272
291
  },
273
292
  body: {
@@ -365,10 +384,12 @@ var html5 = metaHelper.defineMetadata({
365
384
  enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"],
366
385
  },
367
386
  type: {
368
- required: true,
369
387
  enum: ["submit", "reset", "button"],
370
388
  },
371
389
  },
390
+ implicitRole() {
391
+ return "button";
392
+ },
372
393
  permittedContent: ["@phrasing"],
373
394
  permittedDescendants: [{ exclude: ["@interactive"] }],
374
395
  textContent: "accessible",
@@ -445,6 +466,9 @@ var html5 = metaHelper.defineMetadata({
445
466
  datalist: {
446
467
  flow: true,
447
468
  phrasing: true,
469
+ implicitRole() {
470
+ return "listbox";
471
+ },
448
472
  permittedContent: ["@phrasing", "option"],
449
473
  },
450
474
  dd: {
@@ -466,6 +490,9 @@ var html5 = metaHelper.defineMetadata({
466
490
  boolean: true,
467
491
  },
468
492
  },
493
+ implicitRole() {
494
+ return "group";
495
+ },
469
496
  permittedContent: ["summary", "@flow"],
470
497
  permittedOrder: ["summary", "@flow"],
471
498
  requiredContent: ["summary"],
@@ -473,6 +500,9 @@ var html5 = metaHelper.defineMetadata({
473
500
  dfn: {
474
501
  flow: true,
475
502
  phrasing: true,
503
+ implicitRole() {
504
+ return "term";
505
+ },
476
506
  permittedContent: ["@phrasing"],
477
507
  permittedDescendants: [{ exclude: ["dfn"] }],
478
508
  },
@@ -484,6 +514,9 @@ var html5 = metaHelper.defineMetadata({
484
514
  boolean: true,
485
515
  },
486
516
  },
517
+ implicitRole() {
518
+ return "dialog";
519
+ },
487
520
  },
488
521
  dir: {
489
522
  deprecated: {
@@ -558,6 +591,9 @@ var html5 = metaHelper.defineMetadata({
558
591
  boolean: true,
559
592
  },
560
593
  },
594
+ implicitRole() {
595
+ return "group";
596
+ },
561
597
  permittedContent: ["@flow", "legend?"],
562
598
  permittedOrder: ["legend", "@flow"],
563
599
  },
@@ -566,6 +602,9 @@ var html5 = metaHelper.defineMetadata({
566
602
  },
567
603
  figure: {
568
604
  flow: true,
605
+ implicitRole() {
606
+ return "figure";
607
+ },
569
608
  permittedContent: ["@flow", "figcaption?"],
570
609
  permittedOrder: ["figcaption", "@flow", "figcaption"],
571
610
  },
@@ -578,6 +617,26 @@ var html5 = metaHelper.defineMetadata({
578
617
  },
579
618
  footer: {
580
619
  flow: true,
620
+ implicitRole(node) {
621
+ const selectors = [
622
+ "article",
623
+ "aside",
624
+ "main",
625
+ "nav",
626
+ "section",
627
+ '[role="article"]',
628
+ '[role="complementary"]',
629
+ '[role="main"]',
630
+ '[role="navigation"]',
631
+ '[role="region"]',
632
+ ];
633
+ if (node.closest(selectors.join(","))) {
634
+ return null;
635
+ }
636
+ else {
637
+ return "contentinfo";
638
+ }
639
+ },
581
640
  permittedContent: ["@flow"],
582
641
  permittedDescendants: [{ exclude: ["header", "footer", "main"] }],
583
642
  },
@@ -604,6 +663,9 @@ var html5 = metaHelper.defineMetadata({
604
663
  enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"],
605
664
  },
606
665
  },
666
+ implicitRole() {
667
+ return "form";
668
+ },
607
669
  permittedContent: ["@flow"],
608
670
  permittedDescendants: [{ exclude: ["@form"] }],
609
671
  },
@@ -639,6 +701,9 @@ var html5 = metaHelper.defineMetadata({
639
701
  deprecated: true,
640
702
  },
641
703
  },
704
+ implicitRole() {
705
+ return "heading";
706
+ },
642
707
  },
643
708
  h2: {
644
709
  flow: true,
@@ -649,6 +714,9 @@ var html5 = metaHelper.defineMetadata({
649
714
  deprecated: true,
650
715
  },
651
716
  },
717
+ implicitRole() {
718
+ return "heading";
719
+ },
652
720
  },
653
721
  h3: {
654
722
  flow: true,
@@ -659,6 +727,9 @@ var html5 = metaHelper.defineMetadata({
659
727
  deprecated: true,
660
728
  },
661
729
  },
730
+ implicitRole() {
731
+ return "heading";
732
+ },
662
733
  },
663
734
  h4: {
664
735
  flow: true,
@@ -669,6 +740,9 @@ var html5 = metaHelper.defineMetadata({
669
740
  deprecated: true,
670
741
  },
671
742
  },
743
+ implicitRole() {
744
+ return "heading";
745
+ },
672
746
  },
673
747
  h5: {
674
748
  flow: true,
@@ -679,6 +753,9 @@ var html5 = metaHelper.defineMetadata({
679
753
  deprecated: true,
680
754
  },
681
755
  },
756
+ implicitRole() {
757
+ return "heading";
758
+ },
682
759
  },
683
760
  h6: {
684
761
  flow: true,
@@ -689,6 +766,9 @@ var html5 = metaHelper.defineMetadata({
689
766
  deprecated: true,
690
767
  },
691
768
  },
769
+ implicitRole() {
770
+ return "heading";
771
+ },
692
772
  },
693
773
  head: {
694
774
  permittedContent: ["base?", "title?", "@meta"],
@@ -702,6 +782,26 @@ var html5 = metaHelper.defineMetadata({
702
782
  },
703
783
  header: {
704
784
  flow: true,
785
+ implicitRole(node) {
786
+ const selectors = [
787
+ "article",
788
+ "aside",
789
+ "main",
790
+ "nav",
791
+ "section",
792
+ '[role="article"]',
793
+ '[role="complementary"]',
794
+ '[role="main"]',
795
+ '[role="navigation"]',
796
+ '[role="region"]',
797
+ ];
798
+ if (node.closest(selectors.join(","))) {
799
+ return null;
800
+ }
801
+ else {
802
+ return "banner";
803
+ }
804
+ },
705
805
  permittedContent: ["@flow"],
706
806
  permittedDescendants: [{ exclude: ["header", "footer", "main"] }],
707
807
  },
@@ -732,6 +832,9 @@ var html5 = metaHelper.defineMetadata({
732
832
  deprecated: true,
733
833
  },
734
834
  },
835
+ implicitRole() {
836
+ return "separator";
837
+ },
735
838
  },
736
839
  html: {
737
840
  permittedContent: ["head?", "body?"],
@@ -745,6 +848,9 @@ var html5 = metaHelper.defineMetadata({
745
848
  deprecated: true,
746
849
  },
747
850
  },
851
+ implicitRole() {
852
+ return "document";
853
+ },
748
854
  },
749
855
  i: {
750
856
  flow: true,
@@ -845,6 +951,15 @@ var html5 = metaHelper.defineMetadata({
845
951
  deprecated: true,
846
952
  },
847
953
  },
954
+ implicitRole(node) {
955
+ const alt = node.getAttribute("alt");
956
+ if (alt === "") {
957
+ return "presentation";
958
+ }
959
+ else {
960
+ return "img";
961
+ }
962
+ },
848
963
  },
849
964
  input: {
850
965
  flow: true,
@@ -964,6 +1079,44 @@ var html5 = metaHelper.defineMetadata({
964
1079
  deprecated: true,
965
1080
  },
966
1081
  },
1082
+ /* eslint-disable-next-line complexity -- the standard is complicated */
1083
+ implicitRole(node) {
1084
+ const list = node.hasAttribute("list");
1085
+ if (list) {
1086
+ return "combobox";
1087
+ }
1088
+ const type = node.getAttribute("type");
1089
+ switch (type) {
1090
+ case "button":
1091
+ return "button";
1092
+ case "checkbox":
1093
+ return "checkbox";
1094
+ case "email":
1095
+ return "textbox";
1096
+ case "image":
1097
+ return "button";
1098
+ case "number":
1099
+ return "spinbutton";
1100
+ case "radio":
1101
+ return "radio";
1102
+ case "range":
1103
+ return "slider";
1104
+ case "reset":
1105
+ return "button";
1106
+ case "search":
1107
+ return "searchbox";
1108
+ case "submit":
1109
+ return "button";
1110
+ case "tel":
1111
+ return "textbox";
1112
+ case "text":
1113
+ return "textbox";
1114
+ case "url":
1115
+ return "textbox";
1116
+ default:
1117
+ return "textbox";
1118
+ }
1119
+ },
967
1120
  },
968
1121
  ins: {
969
1122
  flow: true,
@@ -1004,6 +1157,9 @@ var html5 = metaHelper.defineMetadata({
1004
1157
  datasrc: {
1005
1158
  deprecated: true,
1006
1159
  },
1160
+ for: {
1161
+ enum: [validId],
1162
+ },
1007
1163
  },
1008
1164
  },
1009
1165
  legend: {
@@ -1032,6 +1188,9 @@ var html5 = metaHelper.defineMetadata({
1032
1188
  deprecated: true,
1033
1189
  },
1034
1190
  },
1191
+ implicitRole(node) {
1192
+ return node.closest("ul, ol, menu") ? "listitem" : null;
1193
+ },
1035
1194
  },
1036
1195
  link: {
1037
1196
  metadata: true,
@@ -1106,6 +1265,9 @@ var html5 = metaHelper.defineMetadata({
1106
1265
  },
1107
1266
  main: {
1108
1267
  flow: true,
1268
+ implicitRole() {
1269
+ return "main";
1270
+ },
1109
1271
  },
1110
1272
  map: {
1111
1273
  flow: true,
@@ -1168,9 +1330,15 @@ var html5 = metaHelper.defineMetadata({
1168
1330
  deprecated: true,
1169
1331
  },
1170
1332
  },
1333
+ implicitRole() {
1334
+ return "math";
1335
+ },
1171
1336
  },
1172
1337
  menu: {
1173
1338
  flow: true,
1339
+ implicitRole() {
1340
+ return "list";
1341
+ },
1174
1342
  permittedContent: ["@script", "li"],
1175
1343
  },
1176
1344
  meta: {
@@ -1203,6 +1371,9 @@ var html5 = metaHelper.defineMetadata({
1203
1371
  flow: true,
1204
1372
  phrasing: true,
1205
1373
  labelable: true,
1374
+ implicitRole() {
1375
+ return "meter";
1376
+ },
1206
1377
  permittedContent: ["@phrasing"],
1207
1378
  permittedDescendants: [{ exclude: "meter" }],
1208
1379
  },
@@ -1216,6 +1387,9 @@ var html5 = metaHelper.defineMetadata({
1216
1387
  nav: {
1217
1388
  flow: true,
1218
1389
  sectioning: true,
1390
+ implicitRole() {
1391
+ return "navigation";
1392
+ },
1219
1393
  permittedContent: ["@flow"],
1220
1394
  permittedDescendants: [{ exclude: "main" }],
1221
1395
  },
@@ -1328,6 +1502,9 @@ var html5 = metaHelper.defineMetadata({
1328
1502
  enum: ["a", "A", "i", "I", "1"],
1329
1503
  },
1330
1504
  },
1505
+ implicitRole() {
1506
+ return "list";
1507
+ },
1331
1508
  permittedContent: ["@script", "li"],
1332
1509
  },
1333
1510
  optgroup: {
@@ -1337,6 +1514,9 @@ var html5 = metaHelper.defineMetadata({
1337
1514
  boolean: true,
1338
1515
  },
1339
1516
  },
1517
+ implicitRole() {
1518
+ return "group";
1519
+ },
1340
1520
  permittedContent: ["@script", "option"],
1341
1521
  },
1342
1522
  option: {
@@ -1358,6 +1538,9 @@ var html5 = metaHelper.defineMetadata({
1358
1538
  boolean: true,
1359
1539
  },
1360
1540
  },
1541
+ implicitRole() {
1542
+ return "option";
1543
+ },
1361
1544
  permittedContent: [],
1362
1545
  },
1363
1546
  output: {
@@ -1367,6 +1550,9 @@ var html5 = metaHelper.defineMetadata({
1367
1550
  listed: true,
1368
1551
  },
1369
1552
  labelable: true,
1553
+ implicitRole() {
1554
+ return "status";
1555
+ },
1370
1556
  permittedContent: ["@phrasing"],
1371
1557
  },
1372
1558
  p: {
@@ -1447,6 +1633,9 @@ var html5 = metaHelper.defineMetadata({
1447
1633
  flow: true,
1448
1634
  phrasing: true,
1449
1635
  labelable: true,
1636
+ implicitRole() {
1637
+ return "progressbar";
1638
+ },
1450
1639
  permittedContent: ["@phrasing"],
1451
1640
  permittedDescendants: [{ exclude: "progress" }],
1452
1641
  },
@@ -1523,9 +1712,18 @@ var html5 = metaHelper.defineMetadata({
1523
1712
  },
1524
1713
  },
1525
1714
  },
1715
+ search: {
1716
+ flow: true,
1717
+ implicitRole() {
1718
+ return "search";
1719
+ },
1720
+ },
1526
1721
  section: {
1527
1722
  flow: true,
1528
1723
  sectioning: true,
1724
+ implicitRole() {
1725
+ return "region";
1726
+ },
1529
1727
  permittedContent: ["@flow"],
1530
1728
  },
1531
1729
  select: {
@@ -1553,6 +1751,20 @@ var html5 = metaHelper.defineMetadata({
1553
1751
  enum: ["/\\d+/"],
1554
1752
  },
1555
1753
  },
1754
+ implicitRole(node) {
1755
+ const multiple = node.hasAttribute("multiple");
1756
+ if (multiple) {
1757
+ return "listbox";
1758
+ }
1759
+ const size = node.getAttribute("size");
1760
+ if (typeof size === "string") {
1761
+ const parsed = parseInt(size, 10);
1762
+ if (parsed > 1) {
1763
+ return "listbox";
1764
+ }
1765
+ }
1766
+ return "combobox";
1767
+ },
1556
1768
  permittedContent: ["@script", "datasrc", "datafld", "dataformatas", "option", "optgroup"],
1557
1769
  },
1558
1770
  slot: {
@@ -1696,6 +1908,9 @@ var html5 = metaHelper.defineMetadata({
1696
1908
  deprecated: true,
1697
1909
  },
1698
1910
  },
1911
+ implicitRole() {
1912
+ return "table";
1913
+ },
1699
1914
  },
1700
1915
  tbody: {
1701
1916
  implicitClosed: ["tbody", "tfoot"],
@@ -1717,6 +1932,9 @@ var html5 = metaHelper.defineMetadata({
1717
1932
  deprecated: true,
1718
1933
  },
1719
1934
  },
1935
+ implicitRole() {
1936
+ return "rowgroup";
1937
+ },
1720
1938
  },
1721
1939
  td: {
1722
1940
  flow: true,
@@ -1762,6 +1980,17 @@ var html5 = metaHelper.defineMetadata({
1762
1980
  deprecated: true,
1763
1981
  },
1764
1982
  },
1983
+ implicitRole(node) {
1984
+ if (node.closest('table[role="grid"], table[role="treegrid"]')) {
1985
+ return "gridcell";
1986
+ }
1987
+ else if (node.closest("table")) {
1988
+ return "cell";
1989
+ }
1990
+ else {
1991
+ return null;
1992
+ }
1993
+ },
1765
1994
  permittedContent: ["@flow"],
1766
1995
  },
1767
1996
  template: {
@@ -1819,6 +2048,9 @@ var html5 = metaHelper.defineMetadata({
1819
2048
  enum: ["hard", "soft"],
1820
2049
  },
1821
2050
  },
2051
+ implicitRole() {
2052
+ return "textbox";
2053
+ },
1822
2054
  permittedContent: [],
1823
2055
  },
1824
2056
  tfoot: {
@@ -1841,6 +2073,9 @@ var html5 = metaHelper.defineMetadata({
1841
2073
  deprecated: true,
1842
2074
  },
1843
2075
  },
2076
+ implicitRole() {
2077
+ return "rowgroup";
2078
+ },
1844
2079
  },
1845
2080
  th: {
1846
2081
  flow: true,
@@ -1886,6 +2121,26 @@ var html5 = metaHelper.defineMetadata({
1886
2121
  deprecated: true,
1887
2122
  },
1888
2123
  },
2124
+ implicitRole(node) {
2125
+ var _a;
2126
+ const table = node.closest("table");
2127
+ if (!table) {
2128
+ return null;
2129
+ }
2130
+ const tableRole = (_a = table.getAttribute("role")) !== null && _a !== void 0 ? _a : "table";
2131
+ if (typeof tableRole !== "string" || !["table", "grid", "treegrid"].includes(tableRole)) {
2132
+ return null;
2133
+ }
2134
+ const scope = node.getAttribute("scope");
2135
+ switch (scope) {
2136
+ case "col":
2137
+ return "columnheader";
2138
+ case "row":
2139
+ return "rowheader";
2140
+ default:
2141
+ return tableRole === "table" ? "cell" : "gridcell";
2142
+ }
2143
+ },
1889
2144
  permittedContent: ["@flow"],
1890
2145
  permittedDescendants: [{ exclude: ["header", "footer", "@sectioning", "@heading"] }],
1891
2146
  },
@@ -1909,10 +2164,16 @@ var html5 = metaHelper.defineMetadata({
1909
2164
  deprecated: true,
1910
2165
  },
1911
2166
  },
2167
+ implicitRole() {
2168
+ return "rowgroup";
2169
+ },
1912
2170
  },
1913
2171
  time: {
1914
2172
  flow: true,
1915
2173
  phrasing: true,
2174
+ implicitRole() {
2175
+ return "time";
2176
+ },
1916
2177
  permittedContent: ["@phrasing"],
1917
2178
  },
1918
2179
  title: {
@@ -1943,6 +2204,9 @@ var html5 = metaHelper.defineMetadata({
1943
2204
  deprecated: true,
1944
2205
  },
1945
2206
  },
2207
+ implicitRole() {
2208
+ return "row";
2209
+ },
1946
2210
  },
1947
2211
  track: {
1948
2212
  void: true,
@@ -1969,6 +2233,9 @@ var html5 = metaHelper.defineMetadata({
1969
2233
  deprecated: true,
1970
2234
  },
1971
2235
  },
2236
+ implicitRole() {
2237
+ return "list";
2238
+ },
1972
2239
  },
1973
2240
  var: {
1974
2241
  flow: true,