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/es/core.js
CHANGED
|
@@ -657,6 +657,11 @@ const patternProperties = {
|
|
|
657
657
|
}
|
|
658
658
|
]
|
|
659
659
|
},
|
|
660
|
+
templateRoot: {
|
|
661
|
+
title: "Mark element as an element ignoring DOM ancestry, i.e. <template>.",
|
|
662
|
+
description: "The <template> element can contain any elements.",
|
|
663
|
+
type: "boolean"
|
|
664
|
+
},
|
|
660
665
|
deprecatedAttributes: {
|
|
661
666
|
title: "List of deprecated attributes",
|
|
662
667
|
type: "array",
|
|
@@ -1098,6 +1103,7 @@ function migrateElement(src) {
|
|
|
1098
1103
|
textContent: src.textContent,
|
|
1099
1104
|
focusable: src.focusable ?? false,
|
|
1100
1105
|
implicitRole,
|
|
1106
|
+
templateRoot: src.templateRoot === true,
|
|
1101
1107
|
aria: {
|
|
1102
1108
|
implicitRole,
|
|
1103
1109
|
naming: normalizeAriaNaming(src.aria?.naming)
|
|
@@ -4104,7 +4110,7 @@ class Rule {
|
|
|
4104
4110
|
}
|
|
4105
4111
|
}
|
|
4106
4112
|
|
|
4107
|
-
const defaults$
|
|
4113
|
+
const defaults$y = {
|
|
4108
4114
|
allowExternal: true,
|
|
4109
4115
|
allowRelative: true,
|
|
4110
4116
|
allowAbsolute: true,
|
|
@@ -4148,7 +4154,7 @@ class AllowedLinks extends Rule {
|
|
|
4148
4154
|
allowRelative;
|
|
4149
4155
|
allowAbsolute;
|
|
4150
4156
|
constructor(options) {
|
|
4151
|
-
super({ ...defaults$
|
|
4157
|
+
super({ ...defaults$y, ...options });
|
|
4152
4158
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
4153
4159
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
4154
4160
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -4316,7 +4322,7 @@ class AllowedLinks extends Rule {
|
|
|
4316
4322
|
}
|
|
4317
4323
|
}
|
|
4318
4324
|
|
|
4319
|
-
const defaults$
|
|
4325
|
+
const defaults$x = {
|
|
4320
4326
|
accessible: true
|
|
4321
4327
|
};
|
|
4322
4328
|
function findByTarget(target, siblings) {
|
|
@@ -4346,7 +4352,7 @@ function getDescription$1(context) {
|
|
|
4346
4352
|
}
|
|
4347
4353
|
class AreaAlt extends Rule {
|
|
4348
4354
|
constructor(options) {
|
|
4349
|
-
super({ ...defaults$
|
|
4355
|
+
super({ ...defaults$x, ...options });
|
|
4350
4356
|
}
|
|
4351
4357
|
static schema() {
|
|
4352
4358
|
return {
|
|
@@ -4425,7 +4431,7 @@ class AriaHiddenBody extends Rule {
|
|
|
4425
4431
|
}
|
|
4426
4432
|
}
|
|
4427
4433
|
|
|
4428
|
-
const defaults$
|
|
4434
|
+
const defaults$w = {
|
|
4429
4435
|
allowAnyNamable: false
|
|
4430
4436
|
};
|
|
4431
4437
|
const whitelisted = [
|
|
@@ -4467,7 +4473,7 @@ function isValidUsage(target, meta) {
|
|
|
4467
4473
|
}
|
|
4468
4474
|
class AriaLabelMisuse extends Rule {
|
|
4469
4475
|
constructor(options) {
|
|
4470
|
-
super({ ...defaults$
|
|
4476
|
+
super({ ...defaults$w, ...options });
|
|
4471
4477
|
}
|
|
4472
4478
|
documentation() {
|
|
4473
4479
|
const valid = [
|
|
@@ -4578,14 +4584,14 @@ class CaseStyle {
|
|
|
4578
4584
|
}
|
|
4579
4585
|
}
|
|
4580
4586
|
|
|
4581
|
-
const defaults$
|
|
4587
|
+
const defaults$v = {
|
|
4582
4588
|
style: "lowercase",
|
|
4583
4589
|
ignoreForeign: true
|
|
4584
4590
|
};
|
|
4585
4591
|
class AttrCase extends Rule {
|
|
4586
4592
|
style;
|
|
4587
4593
|
constructor(options) {
|
|
4588
|
-
super({ ...defaults$
|
|
4594
|
+
super({ ...defaults$v, ...options });
|
|
4589
4595
|
this.style = new CaseStyle(this.options.style, "attr-case");
|
|
4590
4596
|
}
|
|
4591
4597
|
static schema() {
|
|
@@ -4943,7 +4949,7 @@ class AttrDelimiter extends Rule {
|
|
|
4943
4949
|
}
|
|
4944
4950
|
|
|
4945
4951
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
4946
|
-
const defaults$
|
|
4952
|
+
const defaults$u = {
|
|
4947
4953
|
pattern: DEFAULT_PATTERN,
|
|
4948
4954
|
ignoreForeign: true
|
|
4949
4955
|
};
|
|
@@ -4976,7 +4982,7 @@ function generateDescription(name, pattern) {
|
|
|
4976
4982
|
class AttrPattern extends Rule {
|
|
4977
4983
|
pattern;
|
|
4978
4984
|
constructor(options) {
|
|
4979
|
-
super({ ...defaults$
|
|
4985
|
+
super({ ...defaults$u, ...options });
|
|
4980
4986
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4981
4987
|
}
|
|
4982
4988
|
static schema() {
|
|
@@ -5023,7 +5029,7 @@ class AttrPattern extends Rule {
|
|
|
5023
5029
|
}
|
|
5024
5030
|
}
|
|
5025
5031
|
|
|
5026
|
-
const defaults$
|
|
5032
|
+
const defaults$t = {
|
|
5027
5033
|
style: "auto",
|
|
5028
5034
|
unquoted: false
|
|
5029
5035
|
};
|
|
@@ -5089,7 +5095,7 @@ class AttrQuotes extends Rule {
|
|
|
5089
5095
|
};
|
|
5090
5096
|
}
|
|
5091
5097
|
constructor(options) {
|
|
5092
|
-
super({ ...defaults$
|
|
5098
|
+
super({ ...defaults$t, ...options });
|
|
5093
5099
|
this.style = parseStyle$3(this.options.style);
|
|
5094
5100
|
}
|
|
5095
5101
|
setup() {
|
|
@@ -5246,13 +5252,13 @@ class AttributeAllowedValues extends Rule {
|
|
|
5246
5252
|
}
|
|
5247
5253
|
}
|
|
5248
5254
|
|
|
5249
|
-
const defaults$
|
|
5255
|
+
const defaults$s = {
|
|
5250
5256
|
style: "omit"
|
|
5251
5257
|
};
|
|
5252
5258
|
class AttributeBooleanStyle extends Rule {
|
|
5253
5259
|
hasInvalidStyle;
|
|
5254
5260
|
constructor(options) {
|
|
5255
|
-
super({ ...defaults$
|
|
5261
|
+
super({ ...defaults$s, ...options });
|
|
5256
5262
|
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
5257
5263
|
}
|
|
5258
5264
|
static schema() {
|
|
@@ -5318,13 +5324,13 @@ function reportMessage$1(attr, style) {
|
|
|
5318
5324
|
return "";
|
|
5319
5325
|
}
|
|
5320
5326
|
|
|
5321
|
-
const defaults$
|
|
5327
|
+
const defaults$r = {
|
|
5322
5328
|
style: "omit"
|
|
5323
5329
|
};
|
|
5324
5330
|
class AttributeEmptyStyle extends Rule {
|
|
5325
5331
|
hasInvalidStyle;
|
|
5326
5332
|
constructor(options) {
|
|
5327
|
-
super({ ...defaults$
|
|
5333
|
+
super({ ...defaults$r, ...options });
|
|
5328
5334
|
this.hasInvalidStyle = parseStyle$1(this.options.style);
|
|
5329
5335
|
}
|
|
5330
5336
|
static schema() {
|
|
@@ -5519,12 +5525,12 @@ class BasePatternRule extends Rule {
|
|
|
5519
5525
|
}
|
|
5520
5526
|
}
|
|
5521
5527
|
|
|
5522
|
-
const defaults$
|
|
5528
|
+
const defaults$q = {
|
|
5523
5529
|
pattern: "kebabcase"
|
|
5524
5530
|
};
|
|
5525
5531
|
class ClassPattern extends BasePatternRule {
|
|
5526
5532
|
constructor(options) {
|
|
5527
|
-
super("class", { ...defaults$
|
|
5533
|
+
super("class", { ...defaults$q, ...options });
|
|
5528
5534
|
}
|
|
5529
5535
|
static schema() {
|
|
5530
5536
|
return BasePatternRule.schema();
|
|
@@ -5671,13 +5677,13 @@ class CloseOrder extends Rule {
|
|
|
5671
5677
|
}
|
|
5672
5678
|
}
|
|
5673
5679
|
|
|
5674
|
-
const defaults$
|
|
5680
|
+
const defaults$p = {
|
|
5675
5681
|
include: null,
|
|
5676
5682
|
exclude: null
|
|
5677
5683
|
};
|
|
5678
5684
|
class Deprecated extends Rule {
|
|
5679
5685
|
constructor(options) {
|
|
5680
|
-
super({ ...defaults$
|
|
5686
|
+
super({ ...defaults$p, ...options });
|
|
5681
5687
|
}
|
|
5682
5688
|
static schema() {
|
|
5683
5689
|
return {
|
|
@@ -5831,12 +5837,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
|
|
|
5831
5837
|
}
|
|
5832
5838
|
};
|
|
5833
5839
|
|
|
5834
|
-
const defaults$
|
|
5840
|
+
const defaults$o = {
|
|
5835
5841
|
style: "uppercase"
|
|
5836
5842
|
};
|
|
5837
5843
|
class DoctypeStyle extends Rule {
|
|
5838
5844
|
constructor(options) {
|
|
5839
|
-
super({ ...defaults$
|
|
5845
|
+
super({ ...defaults$o, ...options });
|
|
5840
5846
|
}
|
|
5841
5847
|
static schema() {
|
|
5842
5848
|
return {
|
|
@@ -5864,13 +5870,13 @@ class DoctypeStyle extends Rule {
|
|
|
5864
5870
|
}
|
|
5865
5871
|
}
|
|
5866
5872
|
|
|
5867
|
-
const defaults$
|
|
5873
|
+
const defaults$n = {
|
|
5868
5874
|
style: "lowercase"
|
|
5869
5875
|
};
|
|
5870
5876
|
class ElementCase extends Rule {
|
|
5871
5877
|
style;
|
|
5872
5878
|
constructor(options) {
|
|
5873
|
-
super({ ...defaults$
|
|
5879
|
+
super({ ...defaults$n, ...options });
|
|
5874
5880
|
this.style = new CaseStyle(this.options.style, "element-case");
|
|
5875
5881
|
}
|
|
5876
5882
|
static schema() {
|
|
@@ -5930,7 +5936,7 @@ class ElementCase extends Rule {
|
|
|
5930
5936
|
}
|
|
5931
5937
|
}
|
|
5932
5938
|
|
|
5933
|
-
const defaults$
|
|
5939
|
+
const defaults$m = {
|
|
5934
5940
|
pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
|
|
5935
5941
|
whitelist: [],
|
|
5936
5942
|
blacklist: []
|
|
@@ -5938,7 +5944,7 @@ const defaults$l = {
|
|
|
5938
5944
|
class ElementName extends Rule {
|
|
5939
5945
|
pattern;
|
|
5940
5946
|
constructor(options) {
|
|
5941
|
-
super({ ...defaults$
|
|
5947
|
+
super({ ...defaults$m, ...options });
|
|
5942
5948
|
this.pattern = new RegExp(this.options.pattern);
|
|
5943
5949
|
}
|
|
5944
5950
|
static schema() {
|
|
@@ -5975,7 +5981,7 @@ class ElementName extends Rule {
|
|
|
5975
5981
|
...context.blacklist.map((cur) => `- ${cur}`)
|
|
5976
5982
|
];
|
|
5977
5983
|
}
|
|
5978
|
-
if (context.pattern !== defaults$
|
|
5984
|
+
if (context.pattern !== defaults$m.pattern) {
|
|
5979
5985
|
return [
|
|
5980
5986
|
`<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
|
|
5981
5987
|
"",
|
|
@@ -6021,7 +6027,8 @@ class ElementName extends Rule {
|
|
|
6021
6027
|
}
|
|
6022
6028
|
|
|
6023
6029
|
function isNativeTemplate(node) {
|
|
6024
|
-
|
|
6030
|
+
const { tagName, meta } = node;
|
|
6031
|
+
return Boolean(tagName === "template" && meta?.templateRoot && meta?.scriptSupporting);
|
|
6025
6032
|
}
|
|
6026
6033
|
function getTransparentChildren(node, transparent) {
|
|
6027
6034
|
if (typeof transparent === "boolean") {
|
|
@@ -6464,7 +6471,7 @@ class EmptyTitle extends Rule {
|
|
|
6464
6471
|
}
|
|
6465
6472
|
}
|
|
6466
6473
|
|
|
6467
|
-
const defaults$
|
|
6474
|
+
const defaults$l = {
|
|
6468
6475
|
allowArrayBrackets: true,
|
|
6469
6476
|
allowCheckboxDefault: true,
|
|
6470
6477
|
shared: ["radio", "button", "reset", "submit"]
|
|
@@ -6512,7 +6519,7 @@ function getDocumentation(context) {
|
|
|
6512
6519
|
}
|
|
6513
6520
|
class FormDupName extends Rule {
|
|
6514
6521
|
constructor(options) {
|
|
6515
|
-
super({ ...defaults$
|
|
6522
|
+
super({ ...defaults$l, ...options });
|
|
6516
6523
|
}
|
|
6517
6524
|
static schema() {
|
|
6518
6525
|
return {
|
|
@@ -6671,7 +6678,7 @@ class FormDupName extends Rule {
|
|
|
6671
6678
|
}
|
|
6672
6679
|
}
|
|
6673
6680
|
|
|
6674
|
-
const defaults$
|
|
6681
|
+
const defaults$k = {
|
|
6675
6682
|
allowMultipleH1: false,
|
|
6676
6683
|
minInitialRank: "h1",
|
|
6677
6684
|
sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]']
|
|
@@ -6703,7 +6710,7 @@ class HeadingLevel extends Rule {
|
|
|
6703
6710
|
sectionRoots;
|
|
6704
6711
|
stack = [];
|
|
6705
6712
|
constructor(options) {
|
|
6706
|
-
super({ ...defaults$
|
|
6713
|
+
super({ ...defaults$k, ...options });
|
|
6707
6714
|
this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
|
|
6708
6715
|
this.sectionRoots = this.options.sectioningRoots.map((it) => new Compound(it));
|
|
6709
6716
|
this.stack.push({
|
|
@@ -6940,12 +6947,12 @@ class HiddenFocusable extends Rule {
|
|
|
6940
6947
|
}
|
|
6941
6948
|
}
|
|
6942
6949
|
|
|
6943
|
-
const defaults$
|
|
6950
|
+
const defaults$j = {
|
|
6944
6951
|
pattern: "kebabcase"
|
|
6945
6952
|
};
|
|
6946
6953
|
class IdPattern extends BasePatternRule {
|
|
6947
6954
|
constructor(options) {
|
|
6948
|
-
super("id", { ...defaults$
|
|
6955
|
+
super("id", { ...defaults$j, ...options });
|
|
6949
6956
|
}
|
|
6950
6957
|
static schema() {
|
|
6951
6958
|
return BasePatternRule.schema();
|
|
@@ -7263,13 +7270,13 @@ function findLabelByParent(el) {
|
|
|
7263
7270
|
return [];
|
|
7264
7271
|
}
|
|
7265
7272
|
|
|
7266
|
-
const defaults$
|
|
7273
|
+
const defaults$i = {
|
|
7267
7274
|
maxlength: 70
|
|
7268
7275
|
};
|
|
7269
7276
|
class LongTitle extends Rule {
|
|
7270
7277
|
maxlength;
|
|
7271
7278
|
constructor(options) {
|
|
7272
|
-
super({ ...defaults$
|
|
7279
|
+
super({ ...defaults$i, ...options });
|
|
7273
7280
|
this.maxlength = this.options.maxlength;
|
|
7274
7281
|
}
|
|
7275
7282
|
static schema() {
|
|
@@ -7297,12 +7304,12 @@ class LongTitle extends Rule {
|
|
|
7297
7304
|
}
|
|
7298
7305
|
}
|
|
7299
7306
|
|
|
7300
|
-
const defaults$
|
|
7307
|
+
const defaults$h = {
|
|
7301
7308
|
allowLongDelay: false
|
|
7302
7309
|
};
|
|
7303
7310
|
class MetaRefresh extends Rule {
|
|
7304
7311
|
constructor(options) {
|
|
7305
|
-
super({ ...defaults$
|
|
7312
|
+
super({ ...defaults$h, ...options });
|
|
7306
7313
|
}
|
|
7307
7314
|
documentation() {
|
|
7308
7315
|
return {
|
|
@@ -7487,12 +7494,12 @@ class MultipleLabeledControls extends Rule {
|
|
|
7487
7494
|
}
|
|
7488
7495
|
}
|
|
7489
7496
|
|
|
7490
|
-
const defaults$
|
|
7497
|
+
const defaults$g = {
|
|
7491
7498
|
pattern: "camelcase"
|
|
7492
7499
|
};
|
|
7493
7500
|
class NamePattern extends BasePatternRule {
|
|
7494
7501
|
constructor(options) {
|
|
7495
|
-
super("name", { ...defaults$
|
|
7502
|
+
super("name", { ...defaults$g, ...options });
|
|
7496
7503
|
}
|
|
7497
7504
|
static schema() {
|
|
7498
7505
|
return BasePatternRule.schema();
|
|
@@ -7581,13 +7588,13 @@ class NoAbstractRole extends Rule {
|
|
|
7581
7588
|
}
|
|
7582
7589
|
}
|
|
7583
7590
|
|
|
7584
|
-
const defaults$
|
|
7591
|
+
const defaults$f = {
|
|
7585
7592
|
include: null,
|
|
7586
7593
|
exclude: null
|
|
7587
7594
|
};
|
|
7588
7595
|
class NoAutoplay extends Rule {
|
|
7589
7596
|
constructor(options) {
|
|
7590
|
-
super({ ...defaults$
|
|
7597
|
+
super({ ...defaults$f, ...options });
|
|
7591
7598
|
}
|
|
7592
7599
|
documentation(context) {
|
|
7593
7600
|
return {
|
|
@@ -7906,14 +7913,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
7906
7913
|
}
|
|
7907
7914
|
}
|
|
7908
7915
|
|
|
7909
|
-
const defaults$
|
|
7916
|
+
const defaults$e = {
|
|
7910
7917
|
include: null,
|
|
7911
7918
|
exclude: null,
|
|
7912
7919
|
allowedProperties: ["display"]
|
|
7913
7920
|
};
|
|
7914
7921
|
class NoInlineStyle extends Rule {
|
|
7915
7922
|
constructor(options) {
|
|
7916
|
-
super({ ...defaults$
|
|
7923
|
+
super({ ...defaults$e, ...options });
|
|
7917
7924
|
}
|
|
7918
7925
|
static schema() {
|
|
7919
7926
|
return {
|
|
@@ -8099,7 +8106,7 @@ class NoMultipleMain extends Rule {
|
|
|
8099
8106
|
}
|
|
8100
8107
|
}
|
|
8101
8108
|
|
|
8102
|
-
const defaults$
|
|
8109
|
+
const defaults$d = {
|
|
8103
8110
|
relaxed: false
|
|
8104
8111
|
};
|
|
8105
8112
|
const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
|
|
@@ -8117,7 +8124,7 @@ const replacementTable = {
|
|
|
8117
8124
|
class NoRawCharacters extends Rule {
|
|
8118
8125
|
relaxed;
|
|
8119
8126
|
constructor(options) {
|
|
8120
|
-
super({ ...defaults$
|
|
8127
|
+
super({ ...defaults$d, ...options });
|
|
8121
8128
|
this.relaxed = this.options.relaxed;
|
|
8122
8129
|
}
|
|
8123
8130
|
static schema() {
|
|
@@ -8290,13 +8297,13 @@ class NoRedundantRole extends Rule {
|
|
|
8290
8297
|
}
|
|
8291
8298
|
|
|
8292
8299
|
const xmlns = /^(.+):.+$/;
|
|
8293
|
-
const defaults$
|
|
8300
|
+
const defaults$c = {
|
|
8294
8301
|
ignoreForeign: true,
|
|
8295
8302
|
ignoreXML: true
|
|
8296
8303
|
};
|
|
8297
8304
|
class NoSelfClosing extends Rule {
|
|
8298
8305
|
constructor(options) {
|
|
8299
|
-
super({ ...defaults$
|
|
8306
|
+
super({ ...defaults$c, ...options });
|
|
8300
8307
|
}
|
|
8301
8308
|
static schema() {
|
|
8302
8309
|
return {
|
|
@@ -8380,13 +8387,13 @@ class NoTrailingWhitespace extends Rule {
|
|
|
8380
8387
|
}
|
|
8381
8388
|
}
|
|
8382
8389
|
|
|
8383
|
-
const defaults$
|
|
8390
|
+
const defaults$b = {
|
|
8384
8391
|
include: null,
|
|
8385
8392
|
exclude: null
|
|
8386
8393
|
};
|
|
8387
8394
|
class NoUnknownElements extends Rule {
|
|
8388
8395
|
constructor(options) {
|
|
8389
|
-
super({ ...defaults$
|
|
8396
|
+
super({ ...defaults$b, ...options });
|
|
8390
8397
|
}
|
|
8391
8398
|
static schema() {
|
|
8392
8399
|
return {
|
|
@@ -8492,13 +8499,13 @@ const replacement = {
|
|
|
8492
8499
|
reset: '<button type="reset">',
|
|
8493
8500
|
image: '<button type="button">'
|
|
8494
8501
|
};
|
|
8495
|
-
const defaults$
|
|
8502
|
+
const defaults$a = {
|
|
8496
8503
|
include: null,
|
|
8497
8504
|
exclude: null
|
|
8498
8505
|
};
|
|
8499
8506
|
class PreferButton extends Rule {
|
|
8500
8507
|
constructor(options) {
|
|
8501
|
-
super({ ...defaults$
|
|
8508
|
+
super({ ...defaults$a, ...options });
|
|
8502
8509
|
}
|
|
8503
8510
|
static schema() {
|
|
8504
8511
|
return {
|
|
@@ -8564,7 +8571,7 @@ class PreferButton extends Rule {
|
|
|
8564
8571
|
}
|
|
8565
8572
|
}
|
|
8566
8573
|
|
|
8567
|
-
const defaults$
|
|
8574
|
+
const defaults$9 = {
|
|
8568
8575
|
mapping: {
|
|
8569
8576
|
article: "article",
|
|
8570
8577
|
banner: "header",
|
|
@@ -8594,7 +8601,7 @@ const defaults$8 = {
|
|
|
8594
8601
|
};
|
|
8595
8602
|
class PreferNativeElement extends Rule {
|
|
8596
8603
|
constructor(options) {
|
|
8597
|
-
super({ ...defaults$
|
|
8604
|
+
super({ ...defaults$9, ...options });
|
|
8598
8605
|
}
|
|
8599
8606
|
static schema() {
|
|
8600
8607
|
return {
|
|
@@ -8708,12 +8715,12 @@ class PreferTbody extends Rule {
|
|
|
8708
8715
|
}
|
|
8709
8716
|
}
|
|
8710
8717
|
|
|
8711
|
-
const defaults$
|
|
8718
|
+
const defaults$8 = {
|
|
8712
8719
|
tags: ["script", "style"]
|
|
8713
8720
|
};
|
|
8714
8721
|
class RequireCSPNonce extends Rule {
|
|
8715
8722
|
constructor(options) {
|
|
8716
|
-
super({ ...defaults$
|
|
8723
|
+
super({ ...defaults$8, ...options });
|
|
8717
8724
|
}
|
|
8718
8725
|
static schema() {
|
|
8719
8726
|
return {
|
|
@@ -8760,7 +8767,7 @@ class RequireCSPNonce extends Rule {
|
|
|
8760
8767
|
}
|
|
8761
8768
|
}
|
|
8762
8769
|
|
|
8763
|
-
const defaults$
|
|
8770
|
+
const defaults$7 = {
|
|
8764
8771
|
target: "all",
|
|
8765
8772
|
include: null,
|
|
8766
8773
|
exclude: null
|
|
@@ -8789,7 +8796,7 @@ function linkSupportsSri(node) {
|
|
|
8789
8796
|
class RequireSri extends Rule {
|
|
8790
8797
|
target;
|
|
8791
8798
|
constructor(options) {
|
|
8792
|
-
super({ ...defaults$
|
|
8799
|
+
super({ ...defaults$7, ...options });
|
|
8793
8800
|
this.target = this.options.target;
|
|
8794
8801
|
}
|
|
8795
8802
|
static schema() {
|
|
@@ -8962,7 +8969,7 @@ class SvgFocusable extends Rule {
|
|
|
8962
8969
|
}
|
|
8963
8970
|
}
|
|
8964
8971
|
|
|
8965
|
-
const defaults$
|
|
8972
|
+
const defaults$6 = {
|
|
8966
8973
|
characters: [
|
|
8967
8974
|
{ pattern: " ", replacement: " ", description: "non-breaking space" },
|
|
8968
8975
|
{ pattern: "-", replacement: "‑", description: "non-breaking hyphen" }
|
|
@@ -8994,7 +9001,7 @@ function matchAll(text, regexp) {
|
|
|
8994
9001
|
class TelNonBreaking extends Rule {
|
|
8995
9002
|
regex;
|
|
8996
9003
|
constructor(options) {
|
|
8997
|
-
super({ ...defaults$
|
|
9004
|
+
super({ ...defaults$6, ...options });
|
|
8998
9005
|
this.regex = constructRegex(this.options.characters);
|
|
8999
9006
|
}
|
|
9000
9007
|
static schema() {
|
|
@@ -9369,7 +9376,7 @@ class UniqueLandmark extends Rule {
|
|
|
9369
9376
|
}
|
|
9370
9377
|
}
|
|
9371
9378
|
|
|
9372
|
-
const defaults$
|
|
9379
|
+
const defaults$5 = {
|
|
9373
9380
|
ignoreCase: false,
|
|
9374
9381
|
requireSemicolon: true
|
|
9375
9382
|
};
|
|
@@ -9403,7 +9410,7 @@ function getDescription(context, options) {
|
|
|
9403
9410
|
}
|
|
9404
9411
|
class UnknownCharReference extends Rule {
|
|
9405
9412
|
constructor(options) {
|
|
9406
|
-
super({ ...defaults$
|
|
9413
|
+
super({ ...defaults$5, ...options });
|
|
9407
9414
|
}
|
|
9408
9415
|
static schema() {
|
|
9409
9416
|
return {
|
|
@@ -10019,12 +10026,12 @@ class ValidAutocomplete extends Rule {
|
|
|
10019
10026
|
}
|
|
10020
10027
|
}
|
|
10021
10028
|
|
|
10022
|
-
const defaults$
|
|
10029
|
+
const defaults$4 = {
|
|
10023
10030
|
relaxed: false
|
|
10024
10031
|
};
|
|
10025
10032
|
class ValidID extends Rule {
|
|
10026
10033
|
constructor(options) {
|
|
10027
|
-
super({ ...defaults$
|
|
10034
|
+
super({ ...defaults$4, ...options });
|
|
10028
10035
|
}
|
|
10029
10036
|
static schema() {
|
|
10030
10037
|
return {
|
|
@@ -10130,13 +10137,13 @@ class VoidContent extends Rule {
|
|
|
10130
10137
|
}
|
|
10131
10138
|
}
|
|
10132
10139
|
|
|
10133
|
-
const defaults$
|
|
10140
|
+
const defaults$3 = {
|
|
10134
10141
|
style: "omit"
|
|
10135
10142
|
};
|
|
10136
10143
|
class VoidStyle extends Rule {
|
|
10137
10144
|
style;
|
|
10138
10145
|
constructor(options) {
|
|
10139
|
-
super({ ...defaults$
|
|
10146
|
+
super({ ...defaults$3, ...options });
|
|
10140
10147
|
this.style = parseStyle(this.options.style);
|
|
10141
10148
|
}
|
|
10142
10149
|
static schema() {
|
|
@@ -10337,13 +10344,13 @@ class H36 extends Rule {
|
|
|
10337
10344
|
}
|
|
10338
10345
|
}
|
|
10339
10346
|
|
|
10340
|
-
const defaults$
|
|
10347
|
+
const defaults$2 = {
|
|
10341
10348
|
allowEmpty: true,
|
|
10342
10349
|
alias: []
|
|
10343
10350
|
};
|
|
10344
10351
|
class H37 extends Rule {
|
|
10345
10352
|
constructor(options) {
|
|
10346
|
-
super({ ...defaults$
|
|
10353
|
+
super({ ...defaults$2, ...options });
|
|
10347
10354
|
if (!Array.isArray(this.options.alias)) {
|
|
10348
10355
|
this.options.alias = [this.options.alias];
|
|
10349
10356
|
}
|
|
@@ -10405,9 +10412,62 @@ class H37 extends Rule {
|
|
|
10405
10412
|
}
|
|
10406
10413
|
}
|
|
10407
10414
|
|
|
10415
|
+
const defaults$1 = {
|
|
10416
|
+
strict: false
|
|
10417
|
+
};
|
|
10408
10418
|
const { enum: validScopes } = html5.th.attributes?.scope;
|
|
10409
10419
|
const joinedScopes = naturalJoin(validScopes);
|
|
10420
|
+
const td = 0;
|
|
10421
|
+
const th = 1;
|
|
10422
|
+
function getShape(cells) {
|
|
10423
|
+
const rows = cells.length;
|
|
10424
|
+
const cols = cells[0].length;
|
|
10425
|
+
return { rows, cols };
|
|
10426
|
+
}
|
|
10427
|
+
function isSimpleTable(table) {
|
|
10428
|
+
const haveHeadersAttr = table.querySelector("> tr > [headers], > tbody > tr > [headers]");
|
|
10429
|
+
if (haveHeadersAttr) {
|
|
10430
|
+
return false;
|
|
10431
|
+
}
|
|
10432
|
+
const rows = table.querySelectorAll("> tr, > thead > tr, > tbody > tr");
|
|
10433
|
+
if (rows.length === 0) {
|
|
10434
|
+
return false;
|
|
10435
|
+
}
|
|
10436
|
+
const cells = rows.map((tr) => tr.querySelectorAll("> *").map((el) => el.is("th") ? th : td));
|
|
10437
|
+
if (cells[0].length === 0) {
|
|
10438
|
+
return false;
|
|
10439
|
+
}
|
|
10440
|
+
const numColumns = cells[0].length;
|
|
10441
|
+
if (!cells.every((row) => row.length === numColumns)) {
|
|
10442
|
+
return false;
|
|
10443
|
+
}
|
|
10444
|
+
const shape = getShape(cells);
|
|
10445
|
+
const headersPerRow = cells.map((row) => row.reduce((sum, cell) => sum + cell, 0));
|
|
10446
|
+
const headersPerColumn = Array(shape.cols).fill(0).map((_, index) => {
|
|
10447
|
+
return cells.reduce((sum, it) => sum + it[index], 0);
|
|
10448
|
+
});
|
|
10449
|
+
const [firstRow, ...otherRows] = headersPerRow;
|
|
10450
|
+
if (firstRow === shape.cols && otherRows.every((row) => row === 0)) {
|
|
10451
|
+
return true;
|
|
10452
|
+
}
|
|
10453
|
+
const [firstCol, ...otherCols] = headersPerColumn;
|
|
10454
|
+
const haveThead = Boolean(table.querySelector("> thead"));
|
|
10455
|
+
if (firstCol === shape.rows && otherCols.every((col) => col === 0) && !haveThead) {
|
|
10456
|
+
return true;
|
|
10457
|
+
}
|
|
10458
|
+
return false;
|
|
10459
|
+
}
|
|
10410
10460
|
class H63 extends Rule {
|
|
10461
|
+
constructor(options) {
|
|
10462
|
+
super({ ...defaults$1, ...options });
|
|
10463
|
+
}
|
|
10464
|
+
static schema() {
|
|
10465
|
+
return {
|
|
10466
|
+
strict: {
|
|
10467
|
+
type: "boolean"
|
|
10468
|
+
}
|
|
10469
|
+
};
|
|
10470
|
+
}
|
|
10411
10471
|
documentation() {
|
|
10412
10472
|
return {
|
|
10413
10473
|
description: "H63: Using the scope attribute to associate header cells and data cells in data tables",
|
|
@@ -10415,23 +10475,31 @@ class H63 extends Rule {
|
|
|
10415
10475
|
};
|
|
10416
10476
|
}
|
|
10417
10477
|
setup() {
|
|
10418
|
-
|
|
10478
|
+
const { strict } = this.options;
|
|
10479
|
+
this.on("element:ready", (event) => {
|
|
10419
10480
|
const node = event.target;
|
|
10420
|
-
if (node.
|
|
10481
|
+
if (!node.is("table")) {
|
|
10421
10482
|
return;
|
|
10422
10483
|
}
|
|
10423
|
-
|
|
10484
|
+
if (strict || !isSimpleTable(node)) {
|
|
10485
|
+
this.validateTable(node);
|
|
10486
|
+
}
|
|
10487
|
+
});
|
|
10488
|
+
}
|
|
10489
|
+
validateTable(node) {
|
|
10490
|
+
for (const th2 of node.querySelectorAll("th")) {
|
|
10491
|
+
const scope = th2.getAttribute("scope");
|
|
10424
10492
|
const value = scope?.value;
|
|
10425
10493
|
if (value instanceof DynamicValue) {
|
|
10426
|
-
|
|
10494
|
+
continue;
|
|
10427
10495
|
}
|
|
10428
10496
|
if (value && validScopes.includes(value)) {
|
|
10429
|
-
|
|
10497
|
+
continue;
|
|
10430
10498
|
}
|
|
10431
10499
|
const message = `<th> element must have a valid scope attribute: ${joinedScopes}`;
|
|
10432
|
-
const location = scope?.valueLocation ?? scope?.keyLocation ??
|
|
10433
|
-
this.report(
|
|
10434
|
-
}
|
|
10500
|
+
const location = scope?.valueLocation ?? scope?.keyLocation ?? th2.location;
|
|
10501
|
+
this.report(th2, message, location);
|
|
10502
|
+
}
|
|
10435
10503
|
}
|
|
10436
10504
|
}
|
|
10437
10505
|
|
|
@@ -11723,7 +11791,7 @@ class EventHandler {
|
|
|
11723
11791
|
}
|
|
11724
11792
|
|
|
11725
11793
|
const name = "html-validate";
|
|
11726
|
-
const version = "9.
|
|
11794
|
+
const version = "9.7.0";
|
|
11727
11795
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11728
11796
|
|
|
11729
11797
|
function freeze(src) {
|