html-validate 8.12.0 → 8.13.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.
@@ -35,6 +35,29 @@ function isInsideLandmark(node) {
35
35
  ];
36
36
  return Boolean(node.closest(selectors.join(",")));
37
37
  }
38
+ function linkBodyOk(node) {
39
+ if (node.hasAttribute("itemprop")) {
40
+ return true;
41
+ }
42
+ const rel = node.getAttribute("rel");
43
+ if (!rel) {
44
+ return false;
45
+ }
46
+ if (typeof rel !== "string") {
47
+ return false;
48
+ }
49
+ const bodyOk = [
50
+ "dns-prefetch",
51
+ "modulepreload",
52
+ "pingback",
53
+ "preconnect",
54
+ "prefetch",
55
+ "preload",
56
+ "stylesheet"
57
+ ];
58
+ const tokens = rel.toLowerCase().split(/\s+/);
59
+ return tokens.some((keyword) => bodyOk.includes(keyword));
60
+ }
38
61
  var html5 = metaHelper.defineMetadata({
39
62
  "*": {
40
63
  attributes: {
@@ -111,7 +134,74 @@ var html5 = metaHelper.defineMetadata({
111
134
  enum: ReferrerPolicy
112
135
  },
113
136
  rel: {
114
- allowed: allowedIfAttributeIsPresent("href")
137
+ allowed(node, attr) {
138
+ if (!node.hasAttribute("href")) {
139
+ return `requires "href" attribute to be present`;
140
+ }
141
+ if (!attr || attr === "" || typeof attr !== "string") {
142
+ return null;
143
+ }
144
+ const disallowed = [
145
+ /* whatwg */
146
+ "canonical",
147
+ "dns-prefetch",
148
+ "expect",
149
+ "icon",
150
+ "manifest",
151
+ "modulepreload",
152
+ "pingback",
153
+ "preconnect",
154
+ "prefetch",
155
+ "preload",
156
+ "stylesheet",
157
+ /* microformats.org */
158
+ "apple-touch-icon",
159
+ "apple-touch-icon-precomposed",
160
+ "apple-touch-startup-image",
161
+ "authorization_endpoint",
162
+ "component",
163
+ "chrome-webstore-item",
164
+ "dns-prefetch",
165
+ "edit",
166
+ "gbfs",
167
+ "gtfs-static",
168
+ "gtfs-realtime",
169
+ "import",
170
+ "mask-icon",
171
+ "meta",
172
+ "micropub",
173
+ "openid.delegate",
174
+ "openid.server",
175
+ "openid2.local_id",
176
+ "openid2.provider",
177
+ "p3pv1",
178
+ "pgpkey",
179
+ "schema.dcterms",
180
+ "service",
181
+ "shortlink",
182
+ "sitemap",
183
+ "subresource",
184
+ "sword",
185
+ "timesheet",
186
+ "token_endpoint",
187
+ "wlwmanifest",
188
+ "stylesheet/less",
189
+ "token_endpoint",
190
+ "yandex-tableau-widget"
191
+ ];
192
+ const tokens = attr.toLowerCase().split(/\s+/);
193
+ for (const keyword of tokens) {
194
+ if (disallowed.includes(keyword)) {
195
+ return `<a> does not allow rel="${keyword}"`;
196
+ }
197
+ if (keyword.startsWith("dcterms.")) {
198
+ return `<a> does not allow rel="${keyword}"`;
199
+ }
200
+ }
201
+ return null;
202
+ },
203
+ list: true,
204
+ enum: ["/.+/"]
115
205
  },
116
206
  shape: {
117
207
  deprecated: true
@@ -209,7 +299,72 @@ var html5 = metaHelper.defineMetadata({
209
299
  enum: ReferrerPolicy
210
300
  },
211
301
  rel: {
212
- allowed: allowedIfAttributeIsPresent("href")
302
+ allowed(node, attr) {
303
+ if (!node.hasAttribute("href")) {
304
+ return `requires "href" attribute to be present`;
305
+ }
306
+ if (!attr || attr === "" || typeof attr !== "string") {
307
+ return null;
308
+ }
309
+ const disallowed = [
310
+ /* whatwg */
311
+ "canonical",
312
+ "dns-prefetch",
313
+ "expect",
314
+ "icon",
315
+ "manifest",
316
+ "modulepreload",
317
+ "pingback",
318
+ "preconnect",
319
+ "prefetch",
320
+ "preload",
321
+ "stylesheet",
322
+ /* microformats.org */
323
+ "apple-touch-icon",
324
+ "apple-touch-icon-precomposed",
325
+ "apple-touch-startup-image",
326
+ "authorization_endpoint",
327
+ "component",
328
+ "chrome-webstore-item",
329
+ "dns-prefetch",
330
+ "edit",
331
+ "gbfs",
332
+ "gtfs-static",
333
+ "gtfs-realtime",
334
+ "import",
335
+ "mask-icon",
336
+ "meta",
337
+ "micropub",
338
+ "openid.delegate",
339
+ "openid.server",
340
+ "openid2.local_id",
341
+ "openid2.provider",
342
+ "p3pv1",
343
+ "pgpkey",
344
+ "schema.dcterms",
345
+ "service",
346
+ "shortlink",
347
+ "sitemap",
348
+ "subresource",
349
+ "sword",
350
+ "timesheet",
351
+ "token_endpoint",
352
+ "wlwmanifest",
353
+ "stylesheet/less",
354
+ "token_endpoint",
355
+ "yandex-tableau-widget"
356
+ ];
357
+ const tokens = attr.toLowerCase().split(/\s+/);
358
+ for (const keyword of tokens) {
359
+ if (disallowed.includes(keyword)) {
360
+ return `<area> does not allow rel="${keyword}"`;
361
+ }
362
+ if (keyword.startsWith("dcterms.")) {
363
+ return `<area> does not allow rel="${keyword}"`;
364
+ }
365
+ }
366
+ return null;
367
+ }
213
368
  },
214
369
  shape: {
215
370
  allowed(node, attr) {
@@ -768,6 +923,42 @@ var html5 = metaHelper.defineMetadata({
768
923
  novalidate: {
769
924
  boolean: true
770
925
  },
926
+ rel: {
927
+ allowed(_, attr) {
928
+ if (!attr || attr === "" || typeof attr !== "string") {
929
+ return null;
930
+ }
931
+ const disallowed = [
932
+ /* whatwg */
933
+ "alternate",
934
+ "canonical",
935
+ "author",
936
+ "bookmark",
937
+ "dns-prefetch",
938
+ "expect",
939
+ "icon",
940
+ "manifest",
941
+ "modulepreload",
942
+ "pingback",
943
+ "preconnect",
944
+ "prefetch",
945
+ "preload",
946
+ "privacy-policy",
947
+ "stylesheet",
948
+ "tag",
949
+ "terms-of-service"
950
+ ];
951
+ const tokens = attr.toLowerCase().split(/\s+/);
952
+ for (const keyword of tokens) {
953
+ if (disallowed.includes(keyword)) {
954
+ return `<form> does not allow rel="${keyword}"`;
955
+ }
956
+ }
957
+ return null;
958
+ },
959
+ list: true,
960
+ enum: ["/.+/"]
961
+ },
771
962
  target: {
772
963
  enum: ["/[^_].*/", "_blank", "_self", "_parent", "_top"]
773
964
  }
@@ -1371,6 +1562,12 @@ var html5 = metaHelper.defineMetadata({
1371
1562
  },
1372
1563
  link: {
1373
1564
  metadata: true,
1565
+ flow(node) {
1566
+ return linkBodyOk(node);
1567
+ },
1568
+ phrasing(node) {
1569
+ return linkBodyOk(node);
1570
+ },
1374
1571
  void: true,
1375
1572
  attributes: {
1376
1573
  as: {
@@ -1430,6 +1627,37 @@ var html5 = metaHelper.defineMetadata({
1430
1627
  referrerpolicy: {
1431
1628
  enum: ReferrerPolicy
1432
1629
  },
1630
+ rel: {
1631
+ allowed(_, attr) {
1632
+ if (!attr || attr === "" || typeof attr !== "string") {
1633
+ return null;
1634
+ }
1635
+ const disallowed = [
1636
+ /* whatwg */
1637
+ "bookmark",
1638
+ "external",
1639
+ "nofollow",
1640
+ "noopener",
1641
+ "noreferrer",
1642
+ "opener",
1643
+ "tag",
1644
+ /* microformats.org */
1645
+ "disclosure",
1646
+ "entry-content",
1647
+ "lightbox",
1648
+ "lightvideo"
1649
+ ];
1650
+ const tokens = attr.toLowerCase().split(/\s+/);
1651
+ for (const keyword of tokens) {
1652
+ if (disallowed.includes(keyword)) {
1653
+ return `<link> does not allow rel="${keyword}"`;
1654
+ }
1655
+ }
1656
+ return null;
1657
+ },
1658
+ list: true,
1659
+ enum: ["/.+/"]
1660
+ },
1433
1661
  target: {
1434
1662
  deprecated: true
1435
1663
  },