html-validate 7.8.0 → 7.9.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/browser.d.ts +1 -1
- package/dist/cjs/browser.js +1 -0
- package/dist/cjs/browser.js.map +1 -1
- package/dist/cjs/core.d.ts +8 -1
- package/dist/cjs/core.js +223 -66
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +822 -313
- package/dist/cjs/elements.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/es/browser.d.ts +1 -1
- package/dist/es/browser.js +1 -1
- package/dist/es/cli.js +1 -1
- package/dist/es/core.d.ts +8 -1
- package/dist/es/core.js +223 -67
- package/dist/es/core.js.map +1 -1
- package/dist/es/elements.js +822 -313
- package/dist/es/elements.js.map +1 -1
- package/dist/es/html-validate.js +1 -1
- package/dist/es/index.d.ts +1 -1
- package/dist/es/index.js +1 -1
- package/dist/es/jest-lib.js +1 -1
- package/dist/es/rules-helper.js +1 -1
- package/package.json +7 -7
package/dist/cjs/core.js
CHANGED
|
@@ -3565,7 +3565,7 @@ class Rule {
|
|
|
3565
3565
|
}
|
|
3566
3566
|
}
|
|
3567
3567
|
|
|
3568
|
-
const defaults$
|
|
3568
|
+
const defaults$u = {
|
|
3569
3569
|
allowExternal: true,
|
|
3570
3570
|
allowRelative: true,
|
|
3571
3571
|
allowAbsolute: true,
|
|
@@ -3609,7 +3609,7 @@ function matchList(value, list) {
|
|
|
3609
3609
|
}
|
|
3610
3610
|
class AllowedLinks extends Rule {
|
|
3611
3611
|
constructor(options) {
|
|
3612
|
-
super({ ...defaults$
|
|
3612
|
+
super({ ...defaults$u, ...options });
|
|
3613
3613
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
3614
3614
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
3615
3615
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -3757,7 +3757,7 @@ var RuleContext$1;
|
|
|
3757
3757
|
RuleContext["MISSING_ALT"] = "missing-alt";
|
|
3758
3758
|
RuleContext["MISSING_HREF"] = "missing-href";
|
|
3759
3759
|
})(RuleContext$1 || (RuleContext$1 = {}));
|
|
3760
|
-
const defaults$
|
|
3760
|
+
const defaults$t = {
|
|
3761
3761
|
accessible: true,
|
|
3762
3762
|
};
|
|
3763
3763
|
function findByTarget(target, siblings) {
|
|
@@ -3766,7 +3766,7 @@ function findByTarget(target, siblings) {
|
|
|
3766
3766
|
function getAltText(node) {
|
|
3767
3767
|
return node.getAttributeValue("alt");
|
|
3768
3768
|
}
|
|
3769
|
-
function getDescription(context) {
|
|
3769
|
+
function getDescription$1(context) {
|
|
3770
3770
|
switch (context) {
|
|
3771
3771
|
case RuleContext$1.MISSING_ALT:
|
|
3772
3772
|
return [
|
|
@@ -3795,7 +3795,7 @@ function getDescription(context) {
|
|
|
3795
3795
|
}
|
|
3796
3796
|
class AreaAlt extends Rule {
|
|
3797
3797
|
constructor(options) {
|
|
3798
|
-
super({ ...defaults$
|
|
3798
|
+
super({ ...defaults$t, ...options });
|
|
3799
3799
|
}
|
|
3800
3800
|
static schema() {
|
|
3801
3801
|
return {
|
|
@@ -3806,7 +3806,7 @@ class AreaAlt extends Rule {
|
|
|
3806
3806
|
}
|
|
3807
3807
|
documentation(context) {
|
|
3808
3808
|
return {
|
|
3809
|
-
description: getDescription(context).join("\n"),
|
|
3809
|
+
description: getDescription$1(context).join("\n"),
|
|
3810
3810
|
url: "https://html-validate.org/rules/area-alt.html",
|
|
3811
3811
|
};
|
|
3812
3812
|
}
|
|
@@ -3959,13 +3959,13 @@ class AriaLabelMisuse extends Rule {
|
|
|
3959
3959
|
class ConfigError extends UserError {
|
|
3960
3960
|
}
|
|
3961
3961
|
|
|
3962
|
-
const defaults$
|
|
3962
|
+
const defaults$s = {
|
|
3963
3963
|
style: "lowercase",
|
|
3964
3964
|
ignoreForeign: true,
|
|
3965
3965
|
};
|
|
3966
3966
|
class AttrCase extends Rule {
|
|
3967
3967
|
constructor(options) {
|
|
3968
|
-
super({ ...defaults$
|
|
3968
|
+
super({ ...defaults$s, ...options });
|
|
3969
3969
|
this.style = new rulesHelper.CaseStyle(this.options.style, "attr-case");
|
|
3970
3970
|
}
|
|
3971
3971
|
static schema() {
|
|
@@ -4310,7 +4310,7 @@ class AttrDelimiter extends Rule {
|
|
|
4310
4310
|
}
|
|
4311
4311
|
|
|
4312
4312
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
4313
|
-
const defaults$
|
|
4313
|
+
const defaults$r = {
|
|
4314
4314
|
pattern: DEFAULT_PATTERN,
|
|
4315
4315
|
ignoreForeign: true,
|
|
4316
4316
|
};
|
|
@@ -4347,7 +4347,7 @@ function generateDescription(name, pattern) {
|
|
|
4347
4347
|
}
|
|
4348
4348
|
class AttrPattern extends Rule {
|
|
4349
4349
|
constructor(options) {
|
|
4350
|
-
super({ ...defaults$
|
|
4350
|
+
super({ ...defaults$r, ...options });
|
|
4351
4351
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4352
4352
|
}
|
|
4353
4353
|
static schema() {
|
|
@@ -4408,7 +4408,7 @@ var QuoteStyle;
|
|
|
4408
4408
|
QuoteStyle["AUTO_QUOTE"] = "auto";
|
|
4409
4409
|
QuoteStyle["ANY_QUOTE"] = "any";
|
|
4410
4410
|
})(QuoteStyle || (QuoteStyle = {}));
|
|
4411
|
-
const defaults$
|
|
4411
|
+
const defaults$q = {
|
|
4412
4412
|
style: "auto",
|
|
4413
4413
|
unquoted: false,
|
|
4414
4414
|
};
|
|
@@ -4449,7 +4449,7 @@ function describeStyle(style, unquoted) {
|
|
|
4449
4449
|
}
|
|
4450
4450
|
class AttrQuotes extends Rule {
|
|
4451
4451
|
constructor(options) {
|
|
4452
|
-
super({ ...defaults$
|
|
4452
|
+
super({ ...defaults$q, ...options });
|
|
4453
4453
|
this.style = parseStyle$4(this.options.style);
|
|
4454
4454
|
}
|
|
4455
4455
|
static schema() {
|
|
@@ -4645,12 +4645,12 @@ class AttributeAllowedValues extends Rule {
|
|
|
4645
4645
|
}
|
|
4646
4646
|
}
|
|
4647
4647
|
|
|
4648
|
-
const defaults$
|
|
4648
|
+
const defaults$p = {
|
|
4649
4649
|
style: "omit",
|
|
4650
4650
|
};
|
|
4651
4651
|
class AttributeBooleanStyle extends Rule {
|
|
4652
4652
|
constructor(options) {
|
|
4653
|
-
super({ ...defaults$
|
|
4653
|
+
super({ ...defaults$p, ...options });
|
|
4654
4654
|
this.hasInvalidStyle = parseStyle$3(this.options.style);
|
|
4655
4655
|
}
|
|
4656
4656
|
static schema() {
|
|
@@ -4726,12 +4726,12 @@ function reportMessage$1(attr, style) {
|
|
|
4726
4726
|
return "";
|
|
4727
4727
|
}
|
|
4728
4728
|
|
|
4729
|
-
const defaults$
|
|
4729
|
+
const defaults$o = {
|
|
4730
4730
|
style: "omit",
|
|
4731
4731
|
};
|
|
4732
4732
|
class AttributeEmptyStyle extends Rule {
|
|
4733
4733
|
constructor(options) {
|
|
4734
|
-
super({ ...defaults$
|
|
4734
|
+
super({ ...defaults$o, ...options });
|
|
4735
4735
|
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
4736
4736
|
}
|
|
4737
4737
|
static schema() {
|
|
@@ -4887,12 +4887,12 @@ function describePattern(pattern) {
|
|
|
4887
4887
|
}
|
|
4888
4888
|
}
|
|
4889
4889
|
|
|
4890
|
-
const defaults$
|
|
4890
|
+
const defaults$n = {
|
|
4891
4891
|
pattern: "kebabcase",
|
|
4892
4892
|
};
|
|
4893
4893
|
class ClassPattern extends Rule {
|
|
4894
4894
|
constructor(options) {
|
|
4895
|
-
super({ ...defaults$
|
|
4895
|
+
super({ ...defaults$n, ...options });
|
|
4896
4896
|
this.pattern = parsePattern(this.options.pattern);
|
|
4897
4897
|
}
|
|
4898
4898
|
static schema() {
|
|
@@ -5001,13 +5001,13 @@ class CloseOrder extends Rule {
|
|
|
5001
5001
|
}
|
|
5002
5002
|
}
|
|
5003
5003
|
|
|
5004
|
-
const defaults$
|
|
5004
|
+
const defaults$m = {
|
|
5005
5005
|
include: null,
|
|
5006
5006
|
exclude: null,
|
|
5007
5007
|
};
|
|
5008
5008
|
class Deprecated extends Rule {
|
|
5009
5009
|
constructor(options) {
|
|
5010
|
-
super({ ...defaults$
|
|
5010
|
+
super({ ...defaults$m, ...options });
|
|
5011
5011
|
}
|
|
5012
5012
|
static schema() {
|
|
5013
5013
|
return {
|
|
@@ -5170,12 +5170,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
|
|
|
5170
5170
|
}
|
|
5171
5171
|
};
|
|
5172
5172
|
|
|
5173
|
-
const defaults$
|
|
5173
|
+
const defaults$l = {
|
|
5174
5174
|
style: "uppercase",
|
|
5175
5175
|
};
|
|
5176
5176
|
class DoctypeStyle extends Rule {
|
|
5177
5177
|
constructor(options) {
|
|
5178
|
-
super({ ...defaults$
|
|
5178
|
+
super({ ...defaults$l, ...options });
|
|
5179
5179
|
}
|
|
5180
5180
|
static schema() {
|
|
5181
5181
|
return {
|
|
@@ -5207,12 +5207,12 @@ class DoctypeStyle extends Rule {
|
|
|
5207
5207
|
}
|
|
5208
5208
|
}
|
|
5209
5209
|
|
|
5210
|
-
const defaults$
|
|
5210
|
+
const defaults$k = {
|
|
5211
5211
|
style: "lowercase",
|
|
5212
5212
|
};
|
|
5213
5213
|
class ElementCase extends Rule {
|
|
5214
5214
|
constructor(options) {
|
|
5215
|
-
super({ ...defaults$
|
|
5215
|
+
super({ ...defaults$k, ...options });
|
|
5216
5216
|
this.style = new rulesHelper.CaseStyle(this.options.style, "element-case");
|
|
5217
5217
|
}
|
|
5218
5218
|
static schema() {
|
|
@@ -5278,14 +5278,14 @@ class ElementCase extends Rule {
|
|
|
5278
5278
|
}
|
|
5279
5279
|
}
|
|
5280
5280
|
|
|
5281
|
-
const defaults$
|
|
5281
|
+
const defaults$j = {
|
|
5282
5282
|
pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
|
|
5283
5283
|
whitelist: [],
|
|
5284
5284
|
blacklist: [],
|
|
5285
5285
|
};
|
|
5286
5286
|
class ElementName extends Rule {
|
|
5287
5287
|
constructor(options) {
|
|
5288
|
-
super({ ...defaults$
|
|
5288
|
+
super({ ...defaults$j, ...options });
|
|
5289
5289
|
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
5290
5290
|
this.pattern = new RegExp(this.options.pattern);
|
|
5291
5291
|
}
|
|
@@ -5326,7 +5326,7 @@ class ElementName extends Rule {
|
|
|
5326
5326
|
...context.blacklist.map((cur) => `- ${cur}`),
|
|
5327
5327
|
];
|
|
5328
5328
|
}
|
|
5329
|
-
if (context.pattern !== defaults$
|
|
5329
|
+
if (context.pattern !== defaults$j.pattern) {
|
|
5330
5330
|
return [
|
|
5331
5331
|
`<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
|
|
5332
5332
|
"",
|
|
@@ -5874,7 +5874,7 @@ class EmptyTitle extends Rule {
|
|
|
5874
5874
|
}
|
|
5875
5875
|
}
|
|
5876
5876
|
|
|
5877
|
-
const defaults$
|
|
5877
|
+
const defaults$i = {
|
|
5878
5878
|
allowMultipleH1: false,
|
|
5879
5879
|
minInitialRank: "h1",
|
|
5880
5880
|
sectioningRoots: ["dialog", '[role="dialog"]'],
|
|
@@ -5905,7 +5905,7 @@ function parseMaxInitial(value) {
|
|
|
5905
5905
|
}
|
|
5906
5906
|
class HeadingLevel extends Rule {
|
|
5907
5907
|
constructor(options) {
|
|
5908
|
-
super({ ...defaults$
|
|
5908
|
+
super({ ...defaults$i, ...options });
|
|
5909
5909
|
this.stack = [];
|
|
5910
5910
|
this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
|
|
5911
5911
|
this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
|
|
@@ -6063,12 +6063,12 @@ class HeadingLevel extends Rule {
|
|
|
6063
6063
|
}
|
|
6064
6064
|
}
|
|
6065
6065
|
|
|
6066
|
-
const defaults$
|
|
6066
|
+
const defaults$h = {
|
|
6067
6067
|
pattern: "kebabcase",
|
|
6068
6068
|
};
|
|
6069
6069
|
class IdPattern extends Rule {
|
|
6070
6070
|
constructor(options) {
|
|
6071
|
-
super({ ...defaults$
|
|
6071
|
+
super({ ...defaults$h, ...options });
|
|
6072
6072
|
this.pattern = parsePattern(this.options.pattern);
|
|
6073
6073
|
}
|
|
6074
6074
|
static schema() {
|
|
@@ -6350,12 +6350,12 @@ function findLabelByParent(el) {
|
|
|
6350
6350
|
return [];
|
|
6351
6351
|
}
|
|
6352
6352
|
|
|
6353
|
-
const defaults$
|
|
6353
|
+
const defaults$g = {
|
|
6354
6354
|
maxlength: 70,
|
|
6355
6355
|
};
|
|
6356
6356
|
class LongTitle extends Rule {
|
|
6357
6357
|
constructor(options) {
|
|
6358
|
-
super({ ...defaults$
|
|
6358
|
+
super({ ...defaults$g, ...options });
|
|
6359
6359
|
this.maxlength = this.options.maxlength;
|
|
6360
6360
|
}
|
|
6361
6361
|
static schema() {
|
|
@@ -6438,6 +6438,49 @@ function parseContent(text) {
|
|
|
6438
6438
|
}
|
|
6439
6439
|
}
|
|
6440
6440
|
|
|
6441
|
+
function getName(attr) {
|
|
6442
|
+
const name = attr.value;
|
|
6443
|
+
if (!name || name instanceof DynamicValue) {
|
|
6444
|
+
return null;
|
|
6445
|
+
}
|
|
6446
|
+
return name;
|
|
6447
|
+
}
|
|
6448
|
+
class MapDupName extends Rule {
|
|
6449
|
+
documentation() {
|
|
6450
|
+
return {
|
|
6451
|
+
description: "`<map>` must have a unique name, it cannot be the same name as another `<map>` element",
|
|
6452
|
+
url: "https://html-validate.org/rules/map-dup-name.html",
|
|
6453
|
+
};
|
|
6454
|
+
}
|
|
6455
|
+
setup() {
|
|
6456
|
+
this.on("dom:ready", (event) => {
|
|
6457
|
+
const { document } = event;
|
|
6458
|
+
const maps = document.querySelectorAll("map[name]");
|
|
6459
|
+
const names = new Set();
|
|
6460
|
+
for (const map of maps) {
|
|
6461
|
+
const attr = map.getAttribute("name");
|
|
6462
|
+
/* istanbul ignore next -- should not happen as querySelector matches
|
|
6463
|
+
* only the elements with the name attribute */
|
|
6464
|
+
if (!attr) {
|
|
6465
|
+
continue;
|
|
6466
|
+
}
|
|
6467
|
+
const name = getName(attr);
|
|
6468
|
+
if (!name) {
|
|
6469
|
+
continue;
|
|
6470
|
+
}
|
|
6471
|
+
if (names.has(name)) {
|
|
6472
|
+
this.report({
|
|
6473
|
+
node: map,
|
|
6474
|
+
message: `<map> name must be unique`,
|
|
6475
|
+
location: attr.keyLocation,
|
|
6476
|
+
});
|
|
6477
|
+
}
|
|
6478
|
+
names.add(name);
|
|
6479
|
+
}
|
|
6480
|
+
});
|
|
6481
|
+
}
|
|
6482
|
+
}
|
|
6483
|
+
|
|
6441
6484
|
class MissingDoctype extends Rule {
|
|
6442
6485
|
documentation() {
|
|
6443
6486
|
return {
|
|
@@ -6502,13 +6545,13 @@ class MultipleLabeledControls extends Rule {
|
|
|
6502
6545
|
}
|
|
6503
6546
|
}
|
|
6504
6547
|
|
|
6505
|
-
const defaults$
|
|
6548
|
+
const defaults$f = {
|
|
6506
6549
|
include: null,
|
|
6507
6550
|
exclude: null,
|
|
6508
6551
|
};
|
|
6509
6552
|
class NoAutoplay extends Rule {
|
|
6510
6553
|
constructor(options) {
|
|
6511
|
-
super({ ...defaults$
|
|
6554
|
+
super({ ...defaults$f, ...options });
|
|
6512
6555
|
}
|
|
6513
6556
|
documentation(context) {
|
|
6514
6557
|
const tagName = context ? ` on <${context.tagName}>` : "";
|
|
@@ -6749,14 +6792,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
6749
6792
|
}
|
|
6750
6793
|
}
|
|
6751
6794
|
|
|
6752
|
-
const defaults$
|
|
6795
|
+
const defaults$e = {
|
|
6753
6796
|
include: null,
|
|
6754
6797
|
exclude: null,
|
|
6755
6798
|
allowedProperties: ["display"],
|
|
6756
6799
|
};
|
|
6757
6800
|
class NoInlineStyle extends Rule {
|
|
6758
6801
|
constructor(options) {
|
|
6759
|
-
super({ ...defaults$
|
|
6802
|
+
super({ ...defaults$e, ...options });
|
|
6760
6803
|
}
|
|
6761
6804
|
static schema() {
|
|
6762
6805
|
return {
|
|
@@ -6958,7 +7001,7 @@ class NoMultipleMain extends Rule {
|
|
|
6958
7001
|
}
|
|
6959
7002
|
}
|
|
6960
7003
|
|
|
6961
|
-
const defaults$
|
|
7004
|
+
const defaults$d = {
|
|
6962
7005
|
relaxed: false,
|
|
6963
7006
|
};
|
|
6964
7007
|
const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
|
|
@@ -6975,7 +7018,7 @@ const replacementTable = {
|
|
|
6975
7018
|
};
|
|
6976
7019
|
class NoRawCharacters extends Rule {
|
|
6977
7020
|
constructor(options) {
|
|
6978
|
-
super({ ...defaults$
|
|
7021
|
+
super({ ...defaults$d, ...options });
|
|
6979
7022
|
this.relaxed = this.options.relaxed;
|
|
6980
7023
|
}
|
|
6981
7024
|
static schema() {
|
|
@@ -7153,13 +7196,13 @@ class NoRedundantRole extends Rule {
|
|
|
7153
7196
|
}
|
|
7154
7197
|
|
|
7155
7198
|
const xmlns = /^(.+):.+$/;
|
|
7156
|
-
const defaults$
|
|
7199
|
+
const defaults$c = {
|
|
7157
7200
|
ignoreForeign: true,
|
|
7158
7201
|
ignoreXML: true,
|
|
7159
7202
|
};
|
|
7160
7203
|
class NoSelfClosing extends Rule {
|
|
7161
7204
|
constructor(options) {
|
|
7162
|
-
super({ ...defaults$
|
|
7205
|
+
super({ ...defaults$c, ...options });
|
|
7163
7206
|
}
|
|
7164
7207
|
static schema() {
|
|
7165
7208
|
return {
|
|
@@ -7292,13 +7335,13 @@ const replacement = {
|
|
|
7292
7335
|
reset: '<button type="reset">',
|
|
7293
7336
|
image: '<button type="button">',
|
|
7294
7337
|
};
|
|
7295
|
-
const defaults$
|
|
7338
|
+
const defaults$b = {
|
|
7296
7339
|
include: null,
|
|
7297
7340
|
exclude: null,
|
|
7298
7341
|
};
|
|
7299
7342
|
class PreferButton extends Rule {
|
|
7300
7343
|
constructor(options) {
|
|
7301
|
-
super({ ...defaults$
|
|
7344
|
+
super({ ...defaults$b, ...options });
|
|
7302
7345
|
}
|
|
7303
7346
|
static schema() {
|
|
7304
7347
|
return {
|
|
@@ -7373,7 +7416,7 @@ class PreferButton extends Rule {
|
|
|
7373
7416
|
}
|
|
7374
7417
|
}
|
|
7375
7418
|
|
|
7376
|
-
const defaults$
|
|
7419
|
+
const defaults$a = {
|
|
7377
7420
|
mapping: {
|
|
7378
7421
|
article: "article",
|
|
7379
7422
|
banner: "header",
|
|
@@ -7403,7 +7446,7 @@ const defaults$9 = {
|
|
|
7403
7446
|
};
|
|
7404
7447
|
class PreferNativeElement extends Rule {
|
|
7405
7448
|
constructor(options) {
|
|
7406
|
-
super({ ...defaults$
|
|
7449
|
+
super({ ...defaults$a, ...options });
|
|
7407
7450
|
}
|
|
7408
7451
|
static schema() {
|
|
7409
7452
|
return {
|
|
@@ -7523,12 +7566,12 @@ class PreferTbody extends Rule {
|
|
|
7523
7566
|
}
|
|
7524
7567
|
}
|
|
7525
7568
|
|
|
7526
|
-
const defaults$
|
|
7569
|
+
const defaults$9 = {
|
|
7527
7570
|
tags: ["script", "style"],
|
|
7528
7571
|
};
|
|
7529
7572
|
class RequireCSPNonce extends Rule {
|
|
7530
7573
|
constructor(options) {
|
|
7531
|
-
super({ ...defaults$
|
|
7574
|
+
super({ ...defaults$9, ...options });
|
|
7532
7575
|
}
|
|
7533
7576
|
static schema() {
|
|
7534
7577
|
return {
|
|
@@ -7579,7 +7622,7 @@ class RequireCSPNonce extends Rule {
|
|
|
7579
7622
|
}
|
|
7580
7623
|
}
|
|
7581
7624
|
|
|
7582
|
-
const defaults$
|
|
7625
|
+
const defaults$8 = {
|
|
7583
7626
|
target: "all",
|
|
7584
7627
|
include: null,
|
|
7585
7628
|
exclude: null,
|
|
@@ -7591,7 +7634,7 @@ const supportSri = {
|
|
|
7591
7634
|
};
|
|
7592
7635
|
class RequireSri extends Rule {
|
|
7593
7636
|
constructor(options) {
|
|
7594
|
-
super({ ...defaults$
|
|
7637
|
+
super({ ...defaults$8, ...options });
|
|
7595
7638
|
this.target = this.options.target;
|
|
7596
7639
|
}
|
|
7597
7640
|
static schema() {
|
|
@@ -7753,7 +7796,7 @@ class SvgFocusable extends Rule {
|
|
|
7753
7796
|
}
|
|
7754
7797
|
}
|
|
7755
7798
|
|
|
7756
|
-
const defaults$
|
|
7799
|
+
const defaults$7 = {
|
|
7757
7800
|
characters: [
|
|
7758
7801
|
{ pattern: " ", replacement: " ", description: "non-breaking space" },
|
|
7759
7802
|
{ pattern: "-", replacement: "‑", description: "non-breaking hyphen" },
|
|
@@ -7796,7 +7839,7 @@ function matchAll(text, regexp) {
|
|
|
7796
7839
|
}
|
|
7797
7840
|
class TelNonBreaking extends Rule {
|
|
7798
7841
|
constructor(options) {
|
|
7799
|
-
super({ ...defaults$
|
|
7842
|
+
super({ ...defaults$7, ...options });
|
|
7800
7843
|
this.regex = constructRegex(this.options.characters);
|
|
7801
7844
|
}
|
|
7802
7845
|
static schema() {
|
|
@@ -8084,11 +8127,63 @@ class TextContent extends Rule {
|
|
|
8084
8127
|
}
|
|
8085
8128
|
}
|
|
8086
8129
|
|
|
8087
|
-
const
|
|
8130
|
+
const defaults$6 = {
|
|
8131
|
+
ignoreCase: false,
|
|
8132
|
+
requireSemicolon: true,
|
|
8133
|
+
};
|
|
8134
|
+
const regexp$1 = /&(?:[a-z0-9]+|#x?[0-9a-f]+)(;|[^a-z0-9]|$)/gi;
|
|
8135
|
+
const lowercaseEntities = elements.entities.map((it) => it.toLowerCase());
|
|
8136
|
+
function isNumerical(entity) {
|
|
8137
|
+
return entity.startsWith("&#");
|
|
8138
|
+
}
|
|
8139
|
+
function getLocation(location, entity, match) {
|
|
8140
|
+
var _a;
|
|
8141
|
+
/* istanbul ignore next: never happens in practive */
|
|
8142
|
+
const index = (_a = match.index) !== null && _a !== void 0 ? _a : 0;
|
|
8143
|
+
return sliceLocation(location, index, index + entity.length);
|
|
8144
|
+
}
|
|
8145
|
+
function getDescription(context, options) {
|
|
8146
|
+
const url = "https://html.spec.whatwg.org/multipage/named-characters.html";
|
|
8147
|
+
let message;
|
|
8148
|
+
if (context) {
|
|
8149
|
+
if (context.terminated) {
|
|
8150
|
+
message = `Unrecognized character reference \`${context.entity}\`.`;
|
|
8151
|
+
}
|
|
8152
|
+
else {
|
|
8153
|
+
message = `Character reference \`${context.entity}\` must be terminated by a semicolon.`;
|
|
8154
|
+
}
|
|
8155
|
+
}
|
|
8156
|
+
else {
|
|
8157
|
+
message = `Unrecognized character reference.`;
|
|
8158
|
+
}
|
|
8159
|
+
return [
|
|
8160
|
+
message,
|
|
8161
|
+
`HTML5 defines a set of [valid character references](${url}) but this is not a valid one.`,
|
|
8162
|
+
"",
|
|
8163
|
+
"Ensure that:",
|
|
8164
|
+
"",
|
|
8165
|
+
"1. The character is one of the listed names.",
|
|
8166
|
+
...(options.ignoreCase ? [] : ["1. The case is correct (names are case sensitive)."]),
|
|
8167
|
+
...(options.requireSemicolon ? ["1. The name is terminated with a `;`."] : []),
|
|
8168
|
+
].join("\n");
|
|
8169
|
+
}
|
|
8088
8170
|
class UnknownCharReference extends Rule {
|
|
8171
|
+
constructor(options) {
|
|
8172
|
+
super({ ...defaults$6, ...options });
|
|
8173
|
+
}
|
|
8174
|
+
static schema() {
|
|
8175
|
+
return {
|
|
8176
|
+
ignoreCase: {
|
|
8177
|
+
type: "boolean",
|
|
8178
|
+
},
|
|
8179
|
+
requireSemicolon: {
|
|
8180
|
+
type: "boolean",
|
|
8181
|
+
},
|
|
8182
|
+
};
|
|
8183
|
+
}
|
|
8089
8184
|
documentation(context) {
|
|
8090
8185
|
return {
|
|
8091
|
-
description:
|
|
8186
|
+
description: getDescription(context, this.options),
|
|
8092
8187
|
url: "https://html-validate.org/rules/unrecognized-char-ref.html",
|
|
8093
8188
|
};
|
|
8094
8189
|
}
|
|
@@ -8100,7 +8195,9 @@ class UnknownCharReference extends Rule {
|
|
|
8100
8195
|
if (child.nodeType !== NodeType.TEXT_NODE) {
|
|
8101
8196
|
continue;
|
|
8102
8197
|
}
|
|
8103
|
-
this.findCharacterReferences(child.textContent, child.location
|
|
8198
|
+
this.findCharacterReferences(node, child.textContent, child.location, {
|
|
8199
|
+
isAttribute: false,
|
|
8200
|
+
});
|
|
8104
8201
|
}
|
|
8105
8202
|
});
|
|
8106
8203
|
this.on("attr", (event) => {
|
|
@@ -8108,25 +8205,72 @@ class UnknownCharReference extends Rule {
|
|
|
8108
8205
|
if (!event.value) {
|
|
8109
8206
|
return;
|
|
8110
8207
|
}
|
|
8111
|
-
this.findCharacterReferences(event.value.toString(), event.valueLocation
|
|
8208
|
+
this.findCharacterReferences(event.target, event.value.toString(), event.valueLocation, {
|
|
8209
|
+
isAttribute: true,
|
|
8210
|
+
});
|
|
8112
8211
|
});
|
|
8113
8212
|
}
|
|
8114
|
-
|
|
8213
|
+
get entities() {
|
|
8214
|
+
if (this.options.ignoreCase) {
|
|
8215
|
+
return lowercaseEntities;
|
|
8216
|
+
}
|
|
8217
|
+
else {
|
|
8218
|
+
return elements.entities;
|
|
8219
|
+
}
|
|
8220
|
+
}
|
|
8221
|
+
/* eslint-disable-next-line complexity */
|
|
8222
|
+
findCharacterReferences(node, text, location, { isAttribute }) {
|
|
8223
|
+
const { requireSemicolon } = this.options;
|
|
8224
|
+
const isQuerystring = isAttribute && text.includes("?");
|
|
8225
|
+
for (const { match, entity, raw, terminated } of this.getMatches(text)) {
|
|
8226
|
+
/* assume numeric entities are valid for now */
|
|
8227
|
+
if (isNumerical(entity)) {
|
|
8228
|
+
continue;
|
|
8229
|
+
}
|
|
8230
|
+
/* special case: when attributes use query parameters we skip checking
|
|
8231
|
+
* unterminated attributes */
|
|
8232
|
+
if (isQuerystring && !terminated) {
|
|
8233
|
+
continue;
|
|
8234
|
+
}
|
|
8235
|
+
const found = this.entities.includes(entity);
|
|
8236
|
+
/* ignore if this is a known character reference name */
|
|
8237
|
+
if (found && (terminated || !requireSemicolon)) {
|
|
8238
|
+
continue;
|
|
8239
|
+
}
|
|
8240
|
+
if (found && !terminated) {
|
|
8241
|
+
const entityLocation = getLocation(location, entity, match);
|
|
8242
|
+
const message = `Character reference "{{ entity }}" must be terminated by a semicolon`;
|
|
8243
|
+
const context = {
|
|
8244
|
+
entity: raw,
|
|
8245
|
+
terminated: false,
|
|
8246
|
+
};
|
|
8247
|
+
this.report(node, message, entityLocation, context);
|
|
8248
|
+
continue;
|
|
8249
|
+
}
|
|
8250
|
+
const entityLocation = getLocation(location, entity, match);
|
|
8251
|
+
const message = `Unrecognized character reference "{{ entity }}"`;
|
|
8252
|
+
const context = {
|
|
8253
|
+
entity: raw,
|
|
8254
|
+
terminated: true,
|
|
8255
|
+
};
|
|
8256
|
+
this.report(node, message, entityLocation, context);
|
|
8257
|
+
}
|
|
8258
|
+
}
|
|
8259
|
+
*getMatches(text) {
|
|
8115
8260
|
let match;
|
|
8116
8261
|
do {
|
|
8117
8262
|
match = regexp$1.exec(text);
|
|
8118
8263
|
if (match) {
|
|
8119
|
-
const
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8264
|
+
const terminator = match[1]; // === ";" ? match[1] : "";
|
|
8265
|
+
const terminated = terminator === ";";
|
|
8266
|
+
const needSlice = terminator !== ";" && terminator.length > 0;
|
|
8267
|
+
const entity = needSlice ? match[0].slice(0, -1) : match[0];
|
|
8268
|
+
if (this.options.ignoreCase) {
|
|
8269
|
+
yield { match, entity: entity.toLowerCase(), raw: entity, terminated };
|
|
8123
8270
|
}
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
continue;
|
|
8271
|
+
else {
|
|
8272
|
+
yield { match, entity, raw: entity, terminated };
|
|
8127
8273
|
}
|
|
8128
|
-
const entityLocation = sliceLocation(location, match.index, match.index + entity.length);
|
|
8129
|
-
this.report(null, `Unrecognized character reference "${entity}"`, entityLocation, entity);
|
|
8130
8274
|
}
|
|
8131
8275
|
} while (match);
|
|
8132
8276
|
}
|
|
@@ -8727,6 +8871,7 @@ const bundledRules = {
|
|
|
8727
8871
|
"input-attributes": InputAttributes,
|
|
8728
8872
|
"input-missing-label": InputMissingLabel,
|
|
8729
8873
|
"long-title": LongTitle,
|
|
8874
|
+
"map-dup-name": MapDupName,
|
|
8730
8875
|
"meta-refresh": MetaRefresh,
|
|
8731
8876
|
"missing-doctype": MissingDoctype,
|
|
8732
8877
|
"multiple-labeled-controls": MultipleLabeledControls,
|
|
@@ -8836,6 +8981,7 @@ const config$1 = {
|
|
|
8836
8981
|
"empty-title": "error",
|
|
8837
8982
|
"input-attributes": "error",
|
|
8838
8983
|
"long-title": "error",
|
|
8984
|
+
"map-dup-name": "error",
|
|
8839
8985
|
"meta-refresh": "error",
|
|
8840
8986
|
"multiple-labeled-controls": "error",
|
|
8841
8987
|
"no-autoplay": ["error", { include: ["audio", "video"] }],
|
|
@@ -8894,6 +9040,7 @@ const config = {
|
|
|
8894
9040
|
"element-required-ancestor": "error",
|
|
8895
9041
|
"element-required-attributes": "error",
|
|
8896
9042
|
"element-required-content": "error",
|
|
9043
|
+
"map-dup-name": "error",
|
|
8897
9044
|
"multiple-labeled-controls": "error",
|
|
8898
9045
|
"no-deprecated-attr": "error",
|
|
8899
9046
|
"no-dup-attr": "error",
|
|
@@ -10982,10 +11129,19 @@ class HtmlValidate {
|
|
|
10982
11129
|
/** @public */
|
|
10983
11130
|
const name = "html-validate";
|
|
10984
11131
|
/** @public */
|
|
10985
|
-
const version = "7.
|
|
11132
|
+
const version = "7.9.0";
|
|
10986
11133
|
/** @public */
|
|
10987
11134
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
10988
11135
|
|
|
11136
|
+
/**
|
|
11137
|
+
* Helper function to assist IDE with completion and type-checking.
|
|
11138
|
+
*
|
|
11139
|
+
* @public
|
|
11140
|
+
*/
|
|
11141
|
+
function definePlugin(plugin) {
|
|
11142
|
+
return plugin;
|
|
11143
|
+
}
|
|
11144
|
+
|
|
10989
11145
|
const defaults$1 = {
|
|
10990
11146
|
silent: false,
|
|
10991
11147
|
version,
|
|
@@ -11440,6 +11596,7 @@ exports.bugs = bugs;
|
|
|
11440
11596
|
exports.codeframe = codeframe;
|
|
11441
11597
|
exports.compatibilityCheck = compatibilityCheck;
|
|
11442
11598
|
exports.configDataFromFile = configDataFromFile;
|
|
11599
|
+
exports.definePlugin = definePlugin;
|
|
11443
11600
|
exports.ensureError = ensureError;
|
|
11444
11601
|
exports.generateIdSelector = generateIdSelector;
|
|
11445
11602
|
exports.getFormatter = getFormatter;
|