html-validate 9.6.1 → 9.7.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.
- package/dist/cjs/core.js +145 -77
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +1 -0
- package/dist/cjs/elements.js.map +1 -1
- package/dist/es/core.js +145 -77
- package/dist/es/core.js.map +1 -1
- package/dist/es/elements.js +1 -0
- package/dist/es/elements.js.map +1 -1
- package/dist/schema/elements.json +6 -0
- package/dist/types/browser.d.ts +16 -0
- package/dist/types/index.d.ts +16 -0
- package/elements/html5.d.ts +1 -1
- package/package.json +1 -1
package/dist/cjs/core.js
CHANGED
|
@@ -666,6 +666,11 @@ const patternProperties = {
|
|
|
666
666
|
}
|
|
667
667
|
]
|
|
668
668
|
},
|
|
669
|
+
templateRoot: {
|
|
670
|
+
title: "Mark element as an element ignoring DOM ancestry, i.e. <template>.",
|
|
671
|
+
description: "The <template> element can contain any elements.",
|
|
672
|
+
type: "boolean"
|
|
673
|
+
},
|
|
669
674
|
deprecatedAttributes: {
|
|
670
675
|
title: "List of deprecated attributes",
|
|
671
676
|
type: "array",
|
|
@@ -1107,6 +1112,7 @@ function migrateElement(src) {
|
|
|
1107
1112
|
textContent: src.textContent,
|
|
1108
1113
|
focusable: src.focusable ?? false,
|
|
1109
1114
|
implicitRole,
|
|
1115
|
+
templateRoot: src.templateRoot === true,
|
|
1110
1116
|
aria: {
|
|
1111
1117
|
implicitRole,
|
|
1112
1118
|
naming: normalizeAriaNaming(src.aria?.naming)
|
|
@@ -4113,7 +4119,7 @@ class Rule {
|
|
|
4113
4119
|
}
|
|
4114
4120
|
}
|
|
4115
4121
|
|
|
4116
|
-
const defaults$
|
|
4122
|
+
const defaults$y = {
|
|
4117
4123
|
allowExternal: true,
|
|
4118
4124
|
allowRelative: true,
|
|
4119
4125
|
allowAbsolute: true,
|
|
@@ -4157,7 +4163,7 @@ class AllowedLinks extends Rule {
|
|
|
4157
4163
|
allowRelative;
|
|
4158
4164
|
allowAbsolute;
|
|
4159
4165
|
constructor(options) {
|
|
4160
|
-
super({ ...defaults$
|
|
4166
|
+
super({ ...defaults$y, ...options });
|
|
4161
4167
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
4162
4168
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
4163
4169
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -4325,7 +4331,7 @@ class AllowedLinks extends Rule {
|
|
|
4325
4331
|
}
|
|
4326
4332
|
}
|
|
4327
4333
|
|
|
4328
|
-
const defaults$
|
|
4334
|
+
const defaults$x = {
|
|
4329
4335
|
accessible: true
|
|
4330
4336
|
};
|
|
4331
4337
|
function findByTarget(target, siblings) {
|
|
@@ -4355,7 +4361,7 @@ function getDescription$1(context) {
|
|
|
4355
4361
|
}
|
|
4356
4362
|
class AreaAlt extends Rule {
|
|
4357
4363
|
constructor(options) {
|
|
4358
|
-
super({ ...defaults$
|
|
4364
|
+
super({ ...defaults$x, ...options });
|
|
4359
4365
|
}
|
|
4360
4366
|
static schema() {
|
|
4361
4367
|
return {
|
|
@@ -4434,7 +4440,7 @@ class AriaHiddenBody extends Rule {
|
|
|
4434
4440
|
}
|
|
4435
4441
|
}
|
|
4436
4442
|
|
|
4437
|
-
const defaults$
|
|
4443
|
+
const defaults$w = {
|
|
4438
4444
|
allowAnyNamable: false
|
|
4439
4445
|
};
|
|
4440
4446
|
const whitelisted = [
|
|
@@ -4476,7 +4482,7 @@ function isValidUsage(target, meta) {
|
|
|
4476
4482
|
}
|
|
4477
4483
|
class AriaLabelMisuse extends Rule {
|
|
4478
4484
|
constructor(options) {
|
|
4479
|
-
super({ ...defaults$
|
|
4485
|
+
super({ ...defaults$w, ...options });
|
|
4480
4486
|
}
|
|
4481
4487
|
documentation() {
|
|
4482
4488
|
const valid = [
|
|
@@ -4587,14 +4593,14 @@ class CaseStyle {
|
|
|
4587
4593
|
}
|
|
4588
4594
|
}
|
|
4589
4595
|
|
|
4590
|
-
const defaults$
|
|
4596
|
+
const defaults$v = {
|
|
4591
4597
|
style: "lowercase",
|
|
4592
4598
|
ignoreForeign: true
|
|
4593
4599
|
};
|
|
4594
4600
|
class AttrCase extends Rule {
|
|
4595
4601
|
style;
|
|
4596
4602
|
constructor(options) {
|
|
4597
|
-
super({ ...defaults$
|
|
4603
|
+
super({ ...defaults$v, ...options });
|
|
4598
4604
|
this.style = new CaseStyle(this.options.style, "attr-case");
|
|
4599
4605
|
}
|
|
4600
4606
|
static schema() {
|
|
@@ -4952,7 +4958,7 @@ class AttrDelimiter extends Rule {
|
|
|
4952
4958
|
}
|
|
4953
4959
|
|
|
4954
4960
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
4955
|
-
const defaults$
|
|
4961
|
+
const defaults$u = {
|
|
4956
4962
|
pattern: DEFAULT_PATTERN,
|
|
4957
4963
|
ignoreForeign: true
|
|
4958
4964
|
};
|
|
@@ -4985,7 +4991,7 @@ function generateDescription(name, pattern) {
|
|
|
4985
4991
|
class AttrPattern extends Rule {
|
|
4986
4992
|
pattern;
|
|
4987
4993
|
constructor(options) {
|
|
4988
|
-
super({ ...defaults$
|
|
4994
|
+
super({ ...defaults$u, ...options });
|
|
4989
4995
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4990
4996
|
}
|
|
4991
4997
|
static schema() {
|
|
@@ -5032,7 +5038,7 @@ class AttrPattern extends Rule {
|
|
|
5032
5038
|
}
|
|
5033
5039
|
}
|
|
5034
5040
|
|
|
5035
|
-
const defaults$
|
|
5041
|
+
const defaults$t = {
|
|
5036
5042
|
style: "auto",
|
|
5037
5043
|
unquoted: false
|
|
5038
5044
|
};
|
|
@@ -5098,7 +5104,7 @@ class AttrQuotes extends Rule {
|
|
|
5098
5104
|
};
|
|
5099
5105
|
}
|
|
5100
5106
|
constructor(options) {
|
|
5101
|
-
super({ ...defaults$
|
|
5107
|
+
super({ ...defaults$t, ...options });
|
|
5102
5108
|
this.style = parseStyle$3(this.options.style);
|
|
5103
5109
|
}
|
|
5104
5110
|
setup() {
|
|
@@ -5255,13 +5261,13 @@ class AttributeAllowedValues extends Rule {
|
|
|
5255
5261
|
}
|
|
5256
5262
|
}
|
|
5257
5263
|
|
|
5258
|
-
const defaults$
|
|
5264
|
+
const defaults$s = {
|
|
5259
5265
|
style: "omit"
|
|
5260
5266
|
};
|
|
5261
5267
|
class AttributeBooleanStyle extends Rule {
|
|
5262
5268
|
hasInvalidStyle;
|
|
5263
5269
|
constructor(options) {
|
|
5264
|
-
super({ ...defaults$
|
|
5270
|
+
super({ ...defaults$s, ...options });
|
|
5265
5271
|
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
5266
5272
|
}
|
|
5267
5273
|
static schema() {
|
|
@@ -5327,13 +5333,13 @@ function reportMessage$1(attr, style) {
|
|
|
5327
5333
|
return "";
|
|
5328
5334
|
}
|
|
5329
5335
|
|
|
5330
|
-
const defaults$
|
|
5336
|
+
const defaults$r = {
|
|
5331
5337
|
style: "omit"
|
|
5332
5338
|
};
|
|
5333
5339
|
class AttributeEmptyStyle extends Rule {
|
|
5334
5340
|
hasInvalidStyle;
|
|
5335
5341
|
constructor(options) {
|
|
5336
|
-
super({ ...defaults$
|
|
5342
|
+
super({ ...defaults$r, ...options });
|
|
5337
5343
|
this.hasInvalidStyle = parseStyle$1(this.options.style);
|
|
5338
5344
|
}
|
|
5339
5345
|
static schema() {
|
|
@@ -5528,12 +5534,12 @@ class BasePatternRule extends Rule {
|
|
|
5528
5534
|
}
|
|
5529
5535
|
}
|
|
5530
5536
|
|
|
5531
|
-
const defaults$
|
|
5537
|
+
const defaults$q = {
|
|
5532
5538
|
pattern: "kebabcase"
|
|
5533
5539
|
};
|
|
5534
5540
|
class ClassPattern extends BasePatternRule {
|
|
5535
5541
|
constructor(options) {
|
|
5536
|
-
super("class", { ...defaults$
|
|
5542
|
+
super("class", { ...defaults$q, ...options });
|
|
5537
5543
|
}
|
|
5538
5544
|
static schema() {
|
|
5539
5545
|
return BasePatternRule.schema();
|
|
@@ -5680,13 +5686,13 @@ class CloseOrder extends Rule {
|
|
|
5680
5686
|
}
|
|
5681
5687
|
}
|
|
5682
5688
|
|
|
5683
|
-
const defaults$
|
|
5689
|
+
const defaults$p = {
|
|
5684
5690
|
include: null,
|
|
5685
5691
|
exclude: null
|
|
5686
5692
|
};
|
|
5687
5693
|
class Deprecated extends Rule {
|
|
5688
5694
|
constructor(options) {
|
|
5689
|
-
super({ ...defaults$
|
|
5695
|
+
super({ ...defaults$p, ...options });
|
|
5690
5696
|
}
|
|
5691
5697
|
static schema() {
|
|
5692
5698
|
return {
|
|
@@ -5840,12 +5846,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
|
|
|
5840
5846
|
}
|
|
5841
5847
|
};
|
|
5842
5848
|
|
|
5843
|
-
const defaults$
|
|
5849
|
+
const defaults$o = {
|
|
5844
5850
|
style: "uppercase"
|
|
5845
5851
|
};
|
|
5846
5852
|
class DoctypeStyle extends Rule {
|
|
5847
5853
|
constructor(options) {
|
|
5848
|
-
super({ ...defaults$
|
|
5854
|
+
super({ ...defaults$o, ...options });
|
|
5849
5855
|
}
|
|
5850
5856
|
static schema() {
|
|
5851
5857
|
return {
|
|
@@ -5873,13 +5879,13 @@ class DoctypeStyle extends Rule {
|
|
|
5873
5879
|
}
|
|
5874
5880
|
}
|
|
5875
5881
|
|
|
5876
|
-
const defaults$
|
|
5882
|
+
const defaults$n = {
|
|
5877
5883
|
style: "lowercase"
|
|
5878
5884
|
};
|
|
5879
5885
|
class ElementCase extends Rule {
|
|
5880
5886
|
style;
|
|
5881
5887
|
constructor(options) {
|
|
5882
|
-
super({ ...defaults$
|
|
5888
|
+
super({ ...defaults$n, ...options });
|
|
5883
5889
|
this.style = new CaseStyle(this.options.style, "element-case");
|
|
5884
5890
|
}
|
|
5885
5891
|
static schema() {
|
|
@@ -5939,7 +5945,7 @@ class ElementCase extends Rule {
|
|
|
5939
5945
|
}
|
|
5940
5946
|
}
|
|
5941
5947
|
|
|
5942
|
-
const defaults$
|
|
5948
|
+
const defaults$m = {
|
|
5943
5949
|
pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
|
|
5944
5950
|
whitelist: [],
|
|
5945
5951
|
blacklist: []
|
|
@@ -5947,7 +5953,7 @@ const defaults$l = {
|
|
|
5947
5953
|
class ElementName extends Rule {
|
|
5948
5954
|
pattern;
|
|
5949
5955
|
constructor(options) {
|
|
5950
|
-
super({ ...defaults$
|
|
5956
|
+
super({ ...defaults$m, ...options });
|
|
5951
5957
|
this.pattern = new RegExp(this.options.pattern);
|
|
5952
5958
|
}
|
|
5953
5959
|
static schema() {
|
|
@@ -5984,7 +5990,7 @@ class ElementName extends Rule {
|
|
|
5984
5990
|
...context.blacklist.map((cur) => `- ${cur}`)
|
|
5985
5991
|
];
|
|
5986
5992
|
}
|
|
5987
|
-
if (context.pattern !== defaults$
|
|
5993
|
+
if (context.pattern !== defaults$m.pattern) {
|
|
5988
5994
|
return [
|
|
5989
5995
|
`<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
|
|
5990
5996
|
"",
|
|
@@ -6030,7 +6036,8 @@ class ElementName extends Rule {
|
|
|
6030
6036
|
}
|
|
6031
6037
|
|
|
6032
6038
|
function isNativeTemplate(node) {
|
|
6033
|
-
|
|
6039
|
+
const { tagName, meta } = node;
|
|
6040
|
+
return Boolean(tagName === "template" && meta?.templateRoot && meta?.scriptSupporting);
|
|
6034
6041
|
}
|
|
6035
6042
|
function getTransparentChildren(node, transparent) {
|
|
6036
6043
|
if (typeof transparent === "boolean") {
|
|
@@ -6473,7 +6480,7 @@ class EmptyTitle extends Rule {
|
|
|
6473
6480
|
}
|
|
6474
6481
|
}
|
|
6475
6482
|
|
|
6476
|
-
const defaults$
|
|
6483
|
+
const defaults$l = {
|
|
6477
6484
|
allowArrayBrackets: true,
|
|
6478
6485
|
allowCheckboxDefault: true,
|
|
6479
6486
|
shared: ["radio", "button", "reset", "submit"]
|
|
@@ -6521,7 +6528,7 @@ function getDocumentation(context) {
|
|
|
6521
6528
|
}
|
|
6522
6529
|
class FormDupName extends Rule {
|
|
6523
6530
|
constructor(options) {
|
|
6524
|
-
super({ ...defaults$
|
|
6531
|
+
super({ ...defaults$l, ...options });
|
|
6525
6532
|
}
|
|
6526
6533
|
static schema() {
|
|
6527
6534
|
return {
|
|
@@ -6680,7 +6687,7 @@ class FormDupName extends Rule {
|
|
|
6680
6687
|
}
|
|
6681
6688
|
}
|
|
6682
6689
|
|
|
6683
|
-
const defaults$
|
|
6690
|
+
const defaults$k = {
|
|
6684
6691
|
allowMultipleH1: false,
|
|
6685
6692
|
minInitialRank: "h1",
|
|
6686
6693
|
sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]']
|
|
@@ -6712,7 +6719,7 @@ class HeadingLevel extends Rule {
|
|
|
6712
6719
|
sectionRoots;
|
|
6713
6720
|
stack = [];
|
|
6714
6721
|
constructor(options) {
|
|
6715
|
-
super({ ...defaults$
|
|
6722
|
+
super({ ...defaults$k, ...options });
|
|
6716
6723
|
this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
|
|
6717
6724
|
this.sectionRoots = this.options.sectioningRoots.map((it) => new Compound(it));
|
|
6718
6725
|
this.stack.push({
|
|
@@ -6949,12 +6956,12 @@ class HiddenFocusable extends Rule {
|
|
|
6949
6956
|
}
|
|
6950
6957
|
}
|
|
6951
6958
|
|
|
6952
|
-
const defaults$
|
|
6959
|
+
const defaults$j = {
|
|
6953
6960
|
pattern: "kebabcase"
|
|
6954
6961
|
};
|
|
6955
6962
|
class IdPattern extends BasePatternRule {
|
|
6956
6963
|
constructor(options) {
|
|
6957
|
-
super("id", { ...defaults$
|
|
6964
|
+
super("id", { ...defaults$j, ...options });
|
|
6958
6965
|
}
|
|
6959
6966
|
static schema() {
|
|
6960
6967
|
return BasePatternRule.schema();
|
|
@@ -7272,13 +7279,13 @@ function findLabelByParent(el) {
|
|
|
7272
7279
|
return [];
|
|
7273
7280
|
}
|
|
7274
7281
|
|
|
7275
|
-
const defaults$
|
|
7282
|
+
const defaults$i = {
|
|
7276
7283
|
maxlength: 70
|
|
7277
7284
|
};
|
|
7278
7285
|
class LongTitle extends Rule {
|
|
7279
7286
|
maxlength;
|
|
7280
7287
|
constructor(options) {
|
|
7281
|
-
super({ ...defaults$
|
|
7288
|
+
super({ ...defaults$i, ...options });
|
|
7282
7289
|
this.maxlength = this.options.maxlength;
|
|
7283
7290
|
}
|
|
7284
7291
|
static schema() {
|
|
@@ -7306,12 +7313,12 @@ class LongTitle extends Rule {
|
|
|
7306
7313
|
}
|
|
7307
7314
|
}
|
|
7308
7315
|
|
|
7309
|
-
const defaults$
|
|
7316
|
+
const defaults$h = {
|
|
7310
7317
|
allowLongDelay: false
|
|
7311
7318
|
};
|
|
7312
7319
|
class MetaRefresh extends Rule {
|
|
7313
7320
|
constructor(options) {
|
|
7314
|
-
super({ ...defaults$
|
|
7321
|
+
super({ ...defaults$h, ...options });
|
|
7315
7322
|
}
|
|
7316
7323
|
documentation() {
|
|
7317
7324
|
return {
|
|
@@ -7496,12 +7503,12 @@ class MultipleLabeledControls extends Rule {
|
|
|
7496
7503
|
}
|
|
7497
7504
|
}
|
|
7498
7505
|
|
|
7499
|
-
const defaults$
|
|
7506
|
+
const defaults$g = {
|
|
7500
7507
|
pattern: "camelcase"
|
|
7501
7508
|
};
|
|
7502
7509
|
class NamePattern extends BasePatternRule {
|
|
7503
7510
|
constructor(options) {
|
|
7504
|
-
super("name", { ...defaults$
|
|
7511
|
+
super("name", { ...defaults$g, ...options });
|
|
7505
7512
|
}
|
|
7506
7513
|
static schema() {
|
|
7507
7514
|
return BasePatternRule.schema();
|
|
@@ -7590,13 +7597,13 @@ class NoAbstractRole extends Rule {
|
|
|
7590
7597
|
}
|
|
7591
7598
|
}
|
|
7592
7599
|
|
|
7593
|
-
const defaults$
|
|
7600
|
+
const defaults$f = {
|
|
7594
7601
|
include: null,
|
|
7595
7602
|
exclude: null
|
|
7596
7603
|
};
|
|
7597
7604
|
class NoAutoplay extends Rule {
|
|
7598
7605
|
constructor(options) {
|
|
7599
|
-
super({ ...defaults$
|
|
7606
|
+
super({ ...defaults$f, ...options });
|
|
7600
7607
|
}
|
|
7601
7608
|
documentation(context) {
|
|
7602
7609
|
return {
|
|
@@ -7915,14 +7922,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
7915
7922
|
}
|
|
7916
7923
|
}
|
|
7917
7924
|
|
|
7918
|
-
const defaults$
|
|
7925
|
+
const defaults$e = {
|
|
7919
7926
|
include: null,
|
|
7920
7927
|
exclude: null,
|
|
7921
7928
|
allowedProperties: ["display"]
|
|
7922
7929
|
};
|
|
7923
7930
|
class NoInlineStyle extends Rule {
|
|
7924
7931
|
constructor(options) {
|
|
7925
|
-
super({ ...defaults$
|
|
7932
|
+
super({ ...defaults$e, ...options });
|
|
7926
7933
|
}
|
|
7927
7934
|
static schema() {
|
|
7928
7935
|
return {
|
|
@@ -8108,7 +8115,7 @@ class NoMultipleMain extends Rule {
|
|
|
8108
8115
|
}
|
|
8109
8116
|
}
|
|
8110
8117
|
|
|
8111
|
-
const defaults$
|
|
8118
|
+
const defaults$d = {
|
|
8112
8119
|
relaxed: false
|
|
8113
8120
|
};
|
|
8114
8121
|
const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
|
|
@@ -8126,7 +8133,7 @@ const replacementTable = {
|
|
|
8126
8133
|
class NoRawCharacters extends Rule {
|
|
8127
8134
|
relaxed;
|
|
8128
8135
|
constructor(options) {
|
|
8129
|
-
super({ ...defaults$
|
|
8136
|
+
super({ ...defaults$d, ...options });
|
|
8130
8137
|
this.relaxed = this.options.relaxed;
|
|
8131
8138
|
}
|
|
8132
8139
|
static schema() {
|
|
@@ -8299,13 +8306,13 @@ class NoRedundantRole extends Rule {
|
|
|
8299
8306
|
}
|
|
8300
8307
|
|
|
8301
8308
|
const xmlns = /^(.+):.+$/;
|
|
8302
|
-
const defaults$
|
|
8309
|
+
const defaults$c = {
|
|
8303
8310
|
ignoreForeign: true,
|
|
8304
8311
|
ignoreXML: true
|
|
8305
8312
|
};
|
|
8306
8313
|
class NoSelfClosing extends Rule {
|
|
8307
8314
|
constructor(options) {
|
|
8308
|
-
super({ ...defaults$
|
|
8315
|
+
super({ ...defaults$c, ...options });
|
|
8309
8316
|
}
|
|
8310
8317
|
static schema() {
|
|
8311
8318
|
return {
|
|
@@ -8389,13 +8396,13 @@ class NoTrailingWhitespace extends Rule {
|
|
|
8389
8396
|
}
|
|
8390
8397
|
}
|
|
8391
8398
|
|
|
8392
|
-
const defaults$
|
|
8399
|
+
const defaults$b = {
|
|
8393
8400
|
include: null,
|
|
8394
8401
|
exclude: null
|
|
8395
8402
|
};
|
|
8396
8403
|
class NoUnknownElements extends Rule {
|
|
8397
8404
|
constructor(options) {
|
|
8398
|
-
super({ ...defaults$
|
|
8405
|
+
super({ ...defaults$b, ...options });
|
|
8399
8406
|
}
|
|
8400
8407
|
static schema() {
|
|
8401
8408
|
return {
|
|
@@ -8501,13 +8508,13 @@ const replacement = {
|
|
|
8501
8508
|
reset: '<button type="reset">',
|
|
8502
8509
|
image: '<button type="button">'
|
|
8503
8510
|
};
|
|
8504
|
-
const defaults$
|
|
8511
|
+
const defaults$a = {
|
|
8505
8512
|
include: null,
|
|
8506
8513
|
exclude: null
|
|
8507
8514
|
};
|
|
8508
8515
|
class PreferButton extends Rule {
|
|
8509
8516
|
constructor(options) {
|
|
8510
|
-
super({ ...defaults$
|
|
8517
|
+
super({ ...defaults$a, ...options });
|
|
8511
8518
|
}
|
|
8512
8519
|
static schema() {
|
|
8513
8520
|
return {
|
|
@@ -8573,7 +8580,7 @@ class PreferButton extends Rule {
|
|
|
8573
8580
|
}
|
|
8574
8581
|
}
|
|
8575
8582
|
|
|
8576
|
-
const defaults$
|
|
8583
|
+
const defaults$9 = {
|
|
8577
8584
|
mapping: {
|
|
8578
8585
|
article: "article",
|
|
8579
8586
|
banner: "header",
|
|
@@ -8603,7 +8610,7 @@ const defaults$8 = {
|
|
|
8603
8610
|
};
|
|
8604
8611
|
class PreferNativeElement extends Rule {
|
|
8605
8612
|
constructor(options) {
|
|
8606
|
-
super({ ...defaults$
|
|
8613
|
+
super({ ...defaults$9, ...options });
|
|
8607
8614
|
}
|
|
8608
8615
|
static schema() {
|
|
8609
8616
|
return {
|
|
@@ -8717,12 +8724,12 @@ class PreferTbody extends Rule {
|
|
|
8717
8724
|
}
|
|
8718
8725
|
}
|
|
8719
8726
|
|
|
8720
|
-
const defaults$
|
|
8727
|
+
const defaults$8 = {
|
|
8721
8728
|
tags: ["script", "style"]
|
|
8722
8729
|
};
|
|
8723
8730
|
class RequireCSPNonce extends Rule {
|
|
8724
8731
|
constructor(options) {
|
|
8725
|
-
super({ ...defaults$
|
|
8732
|
+
super({ ...defaults$8, ...options });
|
|
8726
8733
|
}
|
|
8727
8734
|
static schema() {
|
|
8728
8735
|
return {
|
|
@@ -8769,7 +8776,7 @@ class RequireCSPNonce extends Rule {
|
|
|
8769
8776
|
}
|
|
8770
8777
|
}
|
|
8771
8778
|
|
|
8772
|
-
const defaults$
|
|
8779
|
+
const defaults$7 = {
|
|
8773
8780
|
target: "all",
|
|
8774
8781
|
include: null,
|
|
8775
8782
|
exclude: null
|
|
@@ -8798,7 +8805,7 @@ function linkSupportsSri(node) {
|
|
|
8798
8805
|
class RequireSri extends Rule {
|
|
8799
8806
|
target;
|
|
8800
8807
|
constructor(options) {
|
|
8801
|
-
super({ ...defaults$
|
|
8808
|
+
super({ ...defaults$7, ...options });
|
|
8802
8809
|
this.target = this.options.target;
|
|
8803
8810
|
}
|
|
8804
8811
|
static schema() {
|
|
@@ -8971,7 +8978,7 @@ class SvgFocusable extends Rule {
|
|
|
8971
8978
|
}
|
|
8972
8979
|
}
|
|
8973
8980
|
|
|
8974
|
-
const defaults$
|
|
8981
|
+
const defaults$6 = {
|
|
8975
8982
|
characters: [
|
|
8976
8983
|
{ pattern: " ", replacement: " ", description: "non-breaking space" },
|
|
8977
8984
|
{ pattern: "-", replacement: "‑", description: "non-breaking hyphen" }
|
|
@@ -9003,7 +9010,7 @@ function matchAll(text, regexp) {
|
|
|
9003
9010
|
class TelNonBreaking extends Rule {
|
|
9004
9011
|
regex;
|
|
9005
9012
|
constructor(options) {
|
|
9006
|
-
super({ ...defaults$
|
|
9013
|
+
super({ ...defaults$6, ...options });
|
|
9007
9014
|
this.regex = constructRegex(this.options.characters);
|
|
9008
9015
|
}
|
|
9009
9016
|
static schema() {
|
|
@@ -9378,7 +9385,7 @@ class UniqueLandmark extends Rule {
|
|
|
9378
9385
|
}
|
|
9379
9386
|
}
|
|
9380
9387
|
|
|
9381
|
-
const defaults$
|
|
9388
|
+
const defaults$5 = {
|
|
9382
9389
|
ignoreCase: false,
|
|
9383
9390
|
requireSemicolon: true
|
|
9384
9391
|
};
|
|
@@ -9412,7 +9419,7 @@ function getDescription(context, options) {
|
|
|
9412
9419
|
}
|
|
9413
9420
|
class UnknownCharReference extends Rule {
|
|
9414
9421
|
constructor(options) {
|
|
9415
|
-
super({ ...defaults$
|
|
9422
|
+
super({ ...defaults$5, ...options });
|
|
9416
9423
|
}
|
|
9417
9424
|
static schema() {
|
|
9418
9425
|
return {
|
|
@@ -10028,12 +10035,12 @@ class ValidAutocomplete extends Rule {
|
|
|
10028
10035
|
}
|
|
10029
10036
|
}
|
|
10030
10037
|
|
|
10031
|
-
const defaults$
|
|
10038
|
+
const defaults$4 = {
|
|
10032
10039
|
relaxed: false
|
|
10033
10040
|
};
|
|
10034
10041
|
class ValidID extends Rule {
|
|
10035
10042
|
constructor(options) {
|
|
10036
|
-
super({ ...defaults$
|
|
10043
|
+
super({ ...defaults$4, ...options });
|
|
10037
10044
|
}
|
|
10038
10045
|
static schema() {
|
|
10039
10046
|
return {
|
|
@@ -10139,13 +10146,13 @@ class VoidContent extends Rule {
|
|
|
10139
10146
|
}
|
|
10140
10147
|
}
|
|
10141
10148
|
|
|
10142
|
-
const defaults$
|
|
10149
|
+
const defaults$3 = {
|
|
10143
10150
|
style: "omit"
|
|
10144
10151
|
};
|
|
10145
10152
|
class VoidStyle extends Rule {
|
|
10146
10153
|
style;
|
|
10147
10154
|
constructor(options) {
|
|
10148
|
-
super({ ...defaults$
|
|
10155
|
+
super({ ...defaults$3, ...options });
|
|
10149
10156
|
this.style = parseStyle(this.options.style);
|
|
10150
10157
|
}
|
|
10151
10158
|
static schema() {
|
|
@@ -10346,13 +10353,13 @@ class H36 extends Rule {
|
|
|
10346
10353
|
}
|
|
10347
10354
|
}
|
|
10348
10355
|
|
|
10349
|
-
const defaults$
|
|
10356
|
+
const defaults$2 = {
|
|
10350
10357
|
allowEmpty: true,
|
|
10351
10358
|
alias: []
|
|
10352
10359
|
};
|
|
10353
10360
|
class H37 extends Rule {
|
|
10354
10361
|
constructor(options) {
|
|
10355
|
-
super({ ...defaults$
|
|
10362
|
+
super({ ...defaults$2, ...options });
|
|
10356
10363
|
if (!Array.isArray(this.options.alias)) {
|
|
10357
10364
|
this.options.alias = [this.options.alias];
|
|
10358
10365
|
}
|
|
@@ -10414,9 +10421,62 @@ class H37 extends Rule {
|
|
|
10414
10421
|
}
|
|
10415
10422
|
}
|
|
10416
10423
|
|
|
10424
|
+
const defaults$1 = {
|
|
10425
|
+
strict: false
|
|
10426
|
+
};
|
|
10417
10427
|
const { enum: validScopes } = elements.html5.th.attributes?.scope;
|
|
10418
10428
|
const joinedScopes = utils_naturalJoin.naturalJoin(validScopes);
|
|
10429
|
+
const td = 0;
|
|
10430
|
+
const th = 1;
|
|
10431
|
+
function getShape(cells) {
|
|
10432
|
+
const rows = cells.length;
|
|
10433
|
+
const cols = cells[0].length;
|
|
10434
|
+
return { rows, cols };
|
|
10435
|
+
}
|
|
10436
|
+
function isSimpleTable(table) {
|
|
10437
|
+
const haveHeadersAttr = table.querySelector("> tr > [headers], > tbody > tr > [headers]");
|
|
10438
|
+
if (haveHeadersAttr) {
|
|
10439
|
+
return false;
|
|
10440
|
+
}
|
|
10441
|
+
const rows = table.querySelectorAll("> tr, > thead > tr, > tbody > tr");
|
|
10442
|
+
if (rows.length === 0) {
|
|
10443
|
+
return false;
|
|
10444
|
+
}
|
|
10445
|
+
const cells = rows.map((tr) => tr.querySelectorAll("> *").map((el) => el.is("th") ? th : td));
|
|
10446
|
+
if (cells[0].length === 0) {
|
|
10447
|
+
return false;
|
|
10448
|
+
}
|
|
10449
|
+
const numColumns = cells[0].length;
|
|
10450
|
+
if (!cells.every((row) => row.length === numColumns)) {
|
|
10451
|
+
return false;
|
|
10452
|
+
}
|
|
10453
|
+
const shape = getShape(cells);
|
|
10454
|
+
const headersPerRow = cells.map((row) => row.reduce((sum, cell) => sum + cell, 0));
|
|
10455
|
+
const headersPerColumn = Array(shape.cols).fill(0).map((_, index) => {
|
|
10456
|
+
return cells.reduce((sum, it) => sum + it[index], 0);
|
|
10457
|
+
});
|
|
10458
|
+
const [firstRow, ...otherRows] = headersPerRow;
|
|
10459
|
+
if (firstRow === shape.cols && otherRows.every((row) => row === 0)) {
|
|
10460
|
+
return true;
|
|
10461
|
+
}
|
|
10462
|
+
const [firstCol, ...otherCols] = headersPerColumn;
|
|
10463
|
+
const haveThead = Boolean(table.querySelector("> thead"));
|
|
10464
|
+
if (firstCol === shape.rows && otherCols.every((col) => col === 0) && !haveThead) {
|
|
10465
|
+
return true;
|
|
10466
|
+
}
|
|
10467
|
+
return false;
|
|
10468
|
+
}
|
|
10419
10469
|
class H63 extends Rule {
|
|
10470
|
+
constructor(options) {
|
|
10471
|
+
super({ ...defaults$1, ...options });
|
|
10472
|
+
}
|
|
10473
|
+
static schema() {
|
|
10474
|
+
return {
|
|
10475
|
+
strict: {
|
|
10476
|
+
type: "boolean"
|
|
10477
|
+
}
|
|
10478
|
+
};
|
|
10479
|
+
}
|
|
10420
10480
|
documentation() {
|
|
10421
10481
|
return {
|
|
10422
10482
|
description: "H63: Using the scope attribute to associate header cells and data cells in data tables",
|
|
@@ -10424,23 +10484,31 @@ class H63 extends Rule {
|
|
|
10424
10484
|
};
|
|
10425
10485
|
}
|
|
10426
10486
|
setup() {
|
|
10427
|
-
|
|
10487
|
+
const { strict } = this.options;
|
|
10488
|
+
this.on("element:ready", (event) => {
|
|
10428
10489
|
const node = event.target;
|
|
10429
|
-
if (node.
|
|
10490
|
+
if (!node.is("table")) {
|
|
10430
10491
|
return;
|
|
10431
10492
|
}
|
|
10432
|
-
|
|
10493
|
+
if (strict || !isSimpleTable(node)) {
|
|
10494
|
+
this.validateTable(node);
|
|
10495
|
+
}
|
|
10496
|
+
});
|
|
10497
|
+
}
|
|
10498
|
+
validateTable(node) {
|
|
10499
|
+
for (const th2 of node.querySelectorAll("th")) {
|
|
10500
|
+
const scope = th2.getAttribute("scope");
|
|
10433
10501
|
const value = scope?.value;
|
|
10434
10502
|
if (value instanceof DynamicValue) {
|
|
10435
|
-
|
|
10503
|
+
continue;
|
|
10436
10504
|
}
|
|
10437
10505
|
if (value && validScopes.includes(value)) {
|
|
10438
|
-
|
|
10506
|
+
continue;
|
|
10439
10507
|
}
|
|
10440
10508
|
const message = `<th> element must have a valid scope attribute: ${joinedScopes}`;
|
|
10441
|
-
const location = scope?.valueLocation ?? scope?.keyLocation ??
|
|
10442
|
-
this.report(
|
|
10443
|
-
}
|
|
10509
|
+
const location = scope?.valueLocation ?? scope?.keyLocation ?? th2.location;
|
|
10510
|
+
this.report(th2, message, location);
|
|
10511
|
+
}
|
|
10444
10512
|
}
|
|
10445
10513
|
}
|
|
10446
10514
|
|
|
@@ -11732,7 +11800,7 @@ class EventHandler {
|
|
|
11732
11800
|
}
|
|
11733
11801
|
|
|
11734
11802
|
const name = "html-validate";
|
|
11735
|
-
const version = "9.
|
|
11803
|
+
const version = "9.7.0";
|
|
11736
11804
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11737
11805
|
|
|
11738
11806
|
function freeze(src) {
|