html-validate 9.6.1 → 9.7.1
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/cli.js.map +1 -1
- package/dist/cjs/core-browser.js.map +1 -1
- package/dist/cjs/core-nodejs.js.map +1 -1
- package/dist/cjs/core.js +151 -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/cjs/html-validate.js.map +1 -1
- package/dist/cjs/html5.js.map +1 -1
- package/dist/cjs/jest-diff.js.map +1 -1
- package/dist/cjs/jest-worker.js.map +1 -1
- package/dist/cjs/jest.js.map +1 -1
- package/dist/cjs/matcher-utils.js.map +1 -1
- package/dist/cjs/matchers-jestonly.js.map +1 -1
- package/dist/cjs/matchers.js.map +1 -1
- package/dist/cjs/meta-helper.js.map +1 -1
- package/dist/cjs/utils/natural-join.js.map +1 -1
- package/dist/cjs/vitest.js.map +1 -1
- package/dist/es/cli.js.map +1 -1
- package/dist/es/core-browser.js.map +1 -1
- package/dist/es/core-nodejs.js.map +1 -1
- package/dist/es/core.js +151 -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/es/html-validate.js.map +1 -1
- package/dist/es/html5.js.map +1 -1
- package/dist/es/jest-diff.js.map +1 -1
- package/dist/es/jest-worker.js.map +1 -1
- package/dist/es/jest.js.map +1 -1
- package/dist/es/matcher-utils.js.map +1 -1
- package/dist/es/matchers-jestonly.js.map +1 -1
- package/dist/es/matchers.js.map +1 -1
- package/dist/es/meta-helper.js.map +1 -1
- package/dist/es/utils/natural-join.js.map +1 -1
- package/dist/es/vitest.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/dist/types/vitest.d.ts +1 -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 = [
|
|
@@ -4448,6 +4454,7 @@ const whitelisted = [
|
|
|
4448
4454
|
"footer",
|
|
4449
4455
|
"section",
|
|
4450
4456
|
"article",
|
|
4457
|
+
"dialog",
|
|
4451
4458
|
"form",
|
|
4452
4459
|
"img",
|
|
4453
4460
|
"area",
|
|
@@ -4476,7 +4483,7 @@ function isValidUsage(target, meta) {
|
|
|
4476
4483
|
}
|
|
4477
4484
|
class AriaLabelMisuse extends Rule {
|
|
4478
4485
|
constructor(options) {
|
|
4479
|
-
super({ ...defaults$
|
|
4486
|
+
super({ ...defaults$w, ...options });
|
|
4480
4487
|
}
|
|
4481
4488
|
documentation() {
|
|
4482
4489
|
const valid = [
|
|
@@ -4485,6 +4492,7 @@ class AriaLabelMisuse extends Rule {
|
|
|
4485
4492
|
"Landmark elements",
|
|
4486
4493
|
"Elements with roles inheriting from widget",
|
|
4487
4494
|
"`<area>`",
|
|
4495
|
+
"`<dialog>`",
|
|
4488
4496
|
"`<form>` and `<fieldset>`",
|
|
4489
4497
|
"`<iframe>`",
|
|
4490
4498
|
"`<img>` and `<figure>`",
|
|
@@ -4587,14 +4595,14 @@ class CaseStyle {
|
|
|
4587
4595
|
}
|
|
4588
4596
|
}
|
|
4589
4597
|
|
|
4590
|
-
const defaults$
|
|
4598
|
+
const defaults$v = {
|
|
4591
4599
|
style: "lowercase",
|
|
4592
4600
|
ignoreForeign: true
|
|
4593
4601
|
};
|
|
4594
4602
|
class AttrCase extends Rule {
|
|
4595
4603
|
style;
|
|
4596
4604
|
constructor(options) {
|
|
4597
|
-
super({ ...defaults$
|
|
4605
|
+
super({ ...defaults$v, ...options });
|
|
4598
4606
|
this.style = new CaseStyle(this.options.style, "attr-case");
|
|
4599
4607
|
}
|
|
4600
4608
|
static schema() {
|
|
@@ -4952,7 +4960,7 @@ class AttrDelimiter extends Rule {
|
|
|
4952
4960
|
}
|
|
4953
4961
|
|
|
4954
4962
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
4955
|
-
const defaults$
|
|
4963
|
+
const defaults$u = {
|
|
4956
4964
|
pattern: DEFAULT_PATTERN,
|
|
4957
4965
|
ignoreForeign: true
|
|
4958
4966
|
};
|
|
@@ -4985,7 +4993,7 @@ function generateDescription(name, pattern) {
|
|
|
4985
4993
|
class AttrPattern extends Rule {
|
|
4986
4994
|
pattern;
|
|
4987
4995
|
constructor(options) {
|
|
4988
|
-
super({ ...defaults$
|
|
4996
|
+
super({ ...defaults$u, ...options });
|
|
4989
4997
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4990
4998
|
}
|
|
4991
4999
|
static schema() {
|
|
@@ -5032,7 +5040,7 @@ class AttrPattern extends Rule {
|
|
|
5032
5040
|
}
|
|
5033
5041
|
}
|
|
5034
5042
|
|
|
5035
|
-
const defaults$
|
|
5043
|
+
const defaults$t = {
|
|
5036
5044
|
style: "auto",
|
|
5037
5045
|
unquoted: false
|
|
5038
5046
|
};
|
|
@@ -5098,7 +5106,7 @@ class AttrQuotes extends Rule {
|
|
|
5098
5106
|
};
|
|
5099
5107
|
}
|
|
5100
5108
|
constructor(options) {
|
|
5101
|
-
super({ ...defaults$
|
|
5109
|
+
super({ ...defaults$t, ...options });
|
|
5102
5110
|
this.style = parseStyle$3(this.options.style);
|
|
5103
5111
|
}
|
|
5104
5112
|
setup() {
|
|
@@ -5255,13 +5263,13 @@ class AttributeAllowedValues extends Rule {
|
|
|
5255
5263
|
}
|
|
5256
5264
|
}
|
|
5257
5265
|
|
|
5258
|
-
const defaults$
|
|
5266
|
+
const defaults$s = {
|
|
5259
5267
|
style: "omit"
|
|
5260
5268
|
};
|
|
5261
5269
|
class AttributeBooleanStyle extends Rule {
|
|
5262
5270
|
hasInvalidStyle;
|
|
5263
5271
|
constructor(options) {
|
|
5264
|
-
super({ ...defaults$
|
|
5272
|
+
super({ ...defaults$s, ...options });
|
|
5265
5273
|
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
5266
5274
|
}
|
|
5267
5275
|
static schema() {
|
|
@@ -5327,13 +5335,13 @@ function reportMessage$1(attr, style) {
|
|
|
5327
5335
|
return "";
|
|
5328
5336
|
}
|
|
5329
5337
|
|
|
5330
|
-
const defaults$
|
|
5338
|
+
const defaults$r = {
|
|
5331
5339
|
style: "omit"
|
|
5332
5340
|
};
|
|
5333
5341
|
class AttributeEmptyStyle extends Rule {
|
|
5334
5342
|
hasInvalidStyle;
|
|
5335
5343
|
constructor(options) {
|
|
5336
|
-
super({ ...defaults$
|
|
5344
|
+
super({ ...defaults$r, ...options });
|
|
5337
5345
|
this.hasInvalidStyle = parseStyle$1(this.options.style);
|
|
5338
5346
|
}
|
|
5339
5347
|
static schema() {
|
|
@@ -5528,12 +5536,12 @@ class BasePatternRule extends Rule {
|
|
|
5528
5536
|
}
|
|
5529
5537
|
}
|
|
5530
5538
|
|
|
5531
|
-
const defaults$
|
|
5539
|
+
const defaults$q = {
|
|
5532
5540
|
pattern: "kebabcase"
|
|
5533
5541
|
};
|
|
5534
5542
|
class ClassPattern extends BasePatternRule {
|
|
5535
5543
|
constructor(options) {
|
|
5536
|
-
super("class", { ...defaults$
|
|
5544
|
+
super("class", { ...defaults$q, ...options });
|
|
5537
5545
|
}
|
|
5538
5546
|
static schema() {
|
|
5539
5547
|
return BasePatternRule.schema();
|
|
@@ -5680,13 +5688,13 @@ class CloseOrder extends Rule {
|
|
|
5680
5688
|
}
|
|
5681
5689
|
}
|
|
5682
5690
|
|
|
5683
|
-
const defaults$
|
|
5691
|
+
const defaults$p = {
|
|
5684
5692
|
include: null,
|
|
5685
5693
|
exclude: null
|
|
5686
5694
|
};
|
|
5687
5695
|
class Deprecated extends Rule {
|
|
5688
5696
|
constructor(options) {
|
|
5689
|
-
super({ ...defaults$
|
|
5697
|
+
super({ ...defaults$p, ...options });
|
|
5690
5698
|
}
|
|
5691
5699
|
static schema() {
|
|
5692
5700
|
return {
|
|
@@ -5840,12 +5848,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
|
|
|
5840
5848
|
}
|
|
5841
5849
|
};
|
|
5842
5850
|
|
|
5843
|
-
const defaults$
|
|
5851
|
+
const defaults$o = {
|
|
5844
5852
|
style: "uppercase"
|
|
5845
5853
|
};
|
|
5846
5854
|
class DoctypeStyle extends Rule {
|
|
5847
5855
|
constructor(options) {
|
|
5848
|
-
super({ ...defaults$
|
|
5856
|
+
super({ ...defaults$o, ...options });
|
|
5849
5857
|
}
|
|
5850
5858
|
static schema() {
|
|
5851
5859
|
return {
|
|
@@ -5873,13 +5881,13 @@ class DoctypeStyle extends Rule {
|
|
|
5873
5881
|
}
|
|
5874
5882
|
}
|
|
5875
5883
|
|
|
5876
|
-
const defaults$
|
|
5884
|
+
const defaults$n = {
|
|
5877
5885
|
style: "lowercase"
|
|
5878
5886
|
};
|
|
5879
5887
|
class ElementCase extends Rule {
|
|
5880
5888
|
style;
|
|
5881
5889
|
constructor(options) {
|
|
5882
|
-
super({ ...defaults$
|
|
5890
|
+
super({ ...defaults$n, ...options });
|
|
5883
5891
|
this.style = new CaseStyle(this.options.style, "element-case");
|
|
5884
5892
|
}
|
|
5885
5893
|
static schema() {
|
|
@@ -5939,7 +5947,7 @@ class ElementCase extends Rule {
|
|
|
5939
5947
|
}
|
|
5940
5948
|
}
|
|
5941
5949
|
|
|
5942
|
-
const defaults$
|
|
5950
|
+
const defaults$m = {
|
|
5943
5951
|
pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
|
|
5944
5952
|
whitelist: [],
|
|
5945
5953
|
blacklist: []
|
|
@@ -5947,7 +5955,7 @@ const defaults$l = {
|
|
|
5947
5955
|
class ElementName extends Rule {
|
|
5948
5956
|
pattern;
|
|
5949
5957
|
constructor(options) {
|
|
5950
|
-
super({ ...defaults$
|
|
5958
|
+
super({ ...defaults$m, ...options });
|
|
5951
5959
|
this.pattern = new RegExp(this.options.pattern);
|
|
5952
5960
|
}
|
|
5953
5961
|
static schema() {
|
|
@@ -5984,7 +5992,7 @@ class ElementName extends Rule {
|
|
|
5984
5992
|
...context.blacklist.map((cur) => `- ${cur}`)
|
|
5985
5993
|
];
|
|
5986
5994
|
}
|
|
5987
|
-
if (context.pattern !== defaults$
|
|
5995
|
+
if (context.pattern !== defaults$m.pattern) {
|
|
5988
5996
|
return [
|
|
5989
5997
|
`<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
|
|
5990
5998
|
"",
|
|
@@ -6030,7 +6038,8 @@ class ElementName extends Rule {
|
|
|
6030
6038
|
}
|
|
6031
6039
|
|
|
6032
6040
|
function isNativeTemplate(node) {
|
|
6033
|
-
|
|
6041
|
+
const { tagName, meta } = node;
|
|
6042
|
+
return Boolean(tagName === "template" && meta?.templateRoot && meta?.scriptSupporting);
|
|
6034
6043
|
}
|
|
6035
6044
|
function getTransparentChildren(node, transparent) {
|
|
6036
6045
|
if (typeof transparent === "boolean") {
|
|
@@ -6473,7 +6482,7 @@ class EmptyTitle extends Rule {
|
|
|
6473
6482
|
}
|
|
6474
6483
|
}
|
|
6475
6484
|
|
|
6476
|
-
const defaults$
|
|
6485
|
+
const defaults$l = {
|
|
6477
6486
|
allowArrayBrackets: true,
|
|
6478
6487
|
allowCheckboxDefault: true,
|
|
6479
6488
|
shared: ["radio", "button", "reset", "submit"]
|
|
@@ -6521,7 +6530,7 @@ function getDocumentation(context) {
|
|
|
6521
6530
|
}
|
|
6522
6531
|
class FormDupName extends Rule {
|
|
6523
6532
|
constructor(options) {
|
|
6524
|
-
super({ ...defaults$
|
|
6533
|
+
super({ ...defaults$l, ...options });
|
|
6525
6534
|
}
|
|
6526
6535
|
static schema() {
|
|
6527
6536
|
return {
|
|
@@ -6680,7 +6689,7 @@ class FormDupName extends Rule {
|
|
|
6680
6689
|
}
|
|
6681
6690
|
}
|
|
6682
6691
|
|
|
6683
|
-
const defaults$
|
|
6692
|
+
const defaults$k = {
|
|
6684
6693
|
allowMultipleH1: false,
|
|
6685
6694
|
minInitialRank: "h1",
|
|
6686
6695
|
sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]']
|
|
@@ -6712,7 +6721,7 @@ class HeadingLevel extends Rule {
|
|
|
6712
6721
|
sectionRoots;
|
|
6713
6722
|
stack = [];
|
|
6714
6723
|
constructor(options) {
|
|
6715
|
-
super({ ...defaults$
|
|
6724
|
+
super({ ...defaults$k, ...options });
|
|
6716
6725
|
this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
|
|
6717
6726
|
this.sectionRoots = this.options.sectioningRoots.map((it) => new Compound(it));
|
|
6718
6727
|
this.stack.push({
|
|
@@ -6949,12 +6958,12 @@ class HiddenFocusable extends Rule {
|
|
|
6949
6958
|
}
|
|
6950
6959
|
}
|
|
6951
6960
|
|
|
6952
|
-
const defaults$
|
|
6961
|
+
const defaults$j = {
|
|
6953
6962
|
pattern: "kebabcase"
|
|
6954
6963
|
};
|
|
6955
6964
|
class IdPattern extends BasePatternRule {
|
|
6956
6965
|
constructor(options) {
|
|
6957
|
-
super("id", { ...defaults$
|
|
6966
|
+
super("id", { ...defaults$j, ...options });
|
|
6958
6967
|
}
|
|
6959
6968
|
static schema() {
|
|
6960
6969
|
return BasePatternRule.schema();
|
|
@@ -7272,13 +7281,13 @@ function findLabelByParent(el) {
|
|
|
7272
7281
|
return [];
|
|
7273
7282
|
}
|
|
7274
7283
|
|
|
7275
|
-
const defaults$
|
|
7284
|
+
const defaults$i = {
|
|
7276
7285
|
maxlength: 70
|
|
7277
7286
|
};
|
|
7278
7287
|
class LongTitle extends Rule {
|
|
7279
7288
|
maxlength;
|
|
7280
7289
|
constructor(options) {
|
|
7281
|
-
super({ ...defaults$
|
|
7290
|
+
super({ ...defaults$i, ...options });
|
|
7282
7291
|
this.maxlength = this.options.maxlength;
|
|
7283
7292
|
}
|
|
7284
7293
|
static schema() {
|
|
@@ -7306,12 +7315,12 @@ class LongTitle extends Rule {
|
|
|
7306
7315
|
}
|
|
7307
7316
|
}
|
|
7308
7317
|
|
|
7309
|
-
const defaults$
|
|
7318
|
+
const defaults$h = {
|
|
7310
7319
|
allowLongDelay: false
|
|
7311
7320
|
};
|
|
7312
7321
|
class MetaRefresh extends Rule {
|
|
7313
7322
|
constructor(options) {
|
|
7314
|
-
super({ ...defaults$
|
|
7323
|
+
super({ ...defaults$h, ...options });
|
|
7315
7324
|
}
|
|
7316
7325
|
documentation() {
|
|
7317
7326
|
return {
|
|
@@ -7496,12 +7505,12 @@ class MultipleLabeledControls extends Rule {
|
|
|
7496
7505
|
}
|
|
7497
7506
|
}
|
|
7498
7507
|
|
|
7499
|
-
const defaults$
|
|
7508
|
+
const defaults$g = {
|
|
7500
7509
|
pattern: "camelcase"
|
|
7501
7510
|
};
|
|
7502
7511
|
class NamePattern extends BasePatternRule {
|
|
7503
7512
|
constructor(options) {
|
|
7504
|
-
super("name", { ...defaults$
|
|
7513
|
+
super("name", { ...defaults$g, ...options });
|
|
7505
7514
|
}
|
|
7506
7515
|
static schema() {
|
|
7507
7516
|
return BasePatternRule.schema();
|
|
@@ -7590,13 +7599,13 @@ class NoAbstractRole extends Rule {
|
|
|
7590
7599
|
}
|
|
7591
7600
|
}
|
|
7592
7601
|
|
|
7593
|
-
const defaults$
|
|
7602
|
+
const defaults$f = {
|
|
7594
7603
|
include: null,
|
|
7595
7604
|
exclude: null
|
|
7596
7605
|
};
|
|
7597
7606
|
class NoAutoplay extends Rule {
|
|
7598
7607
|
constructor(options) {
|
|
7599
|
-
super({ ...defaults$
|
|
7608
|
+
super({ ...defaults$f, ...options });
|
|
7600
7609
|
}
|
|
7601
7610
|
documentation(context) {
|
|
7602
7611
|
return {
|
|
@@ -7915,14 +7924,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
7915
7924
|
}
|
|
7916
7925
|
}
|
|
7917
7926
|
|
|
7918
|
-
const defaults$
|
|
7927
|
+
const defaults$e = {
|
|
7919
7928
|
include: null,
|
|
7920
7929
|
exclude: null,
|
|
7921
7930
|
allowedProperties: ["display"]
|
|
7922
7931
|
};
|
|
7923
7932
|
class NoInlineStyle extends Rule {
|
|
7924
7933
|
constructor(options) {
|
|
7925
|
-
super({ ...defaults$
|
|
7934
|
+
super({ ...defaults$e, ...options });
|
|
7926
7935
|
}
|
|
7927
7936
|
static schema() {
|
|
7928
7937
|
return {
|
|
@@ -8108,7 +8117,7 @@ class NoMultipleMain extends Rule {
|
|
|
8108
8117
|
}
|
|
8109
8118
|
}
|
|
8110
8119
|
|
|
8111
|
-
const defaults$
|
|
8120
|
+
const defaults$d = {
|
|
8112
8121
|
relaxed: false
|
|
8113
8122
|
};
|
|
8114
8123
|
const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
|
|
@@ -8126,7 +8135,7 @@ const replacementTable = {
|
|
|
8126
8135
|
class NoRawCharacters extends Rule {
|
|
8127
8136
|
relaxed;
|
|
8128
8137
|
constructor(options) {
|
|
8129
|
-
super({ ...defaults$
|
|
8138
|
+
super({ ...defaults$d, ...options });
|
|
8130
8139
|
this.relaxed = this.options.relaxed;
|
|
8131
8140
|
}
|
|
8132
8141
|
static schema() {
|
|
@@ -8156,12 +8165,16 @@ class NoRawCharacters extends Rule {
|
|
|
8156
8165
|
}
|
|
8157
8166
|
});
|
|
8158
8167
|
this.on("attr", (event) => {
|
|
8168
|
+
const { meta } = event;
|
|
8159
8169
|
if (!event.value) {
|
|
8160
8170
|
return;
|
|
8161
8171
|
}
|
|
8162
8172
|
if (event.quote) {
|
|
8163
8173
|
return;
|
|
8164
8174
|
}
|
|
8175
|
+
if (meta?.boolean) {
|
|
8176
|
+
return;
|
|
8177
|
+
}
|
|
8165
8178
|
this.findRawChars(
|
|
8166
8179
|
event.target,
|
|
8167
8180
|
event.value.toString(),
|
|
@@ -8299,13 +8312,13 @@ class NoRedundantRole extends Rule {
|
|
|
8299
8312
|
}
|
|
8300
8313
|
|
|
8301
8314
|
const xmlns = /^(.+):.+$/;
|
|
8302
|
-
const defaults$
|
|
8315
|
+
const defaults$c = {
|
|
8303
8316
|
ignoreForeign: true,
|
|
8304
8317
|
ignoreXML: true
|
|
8305
8318
|
};
|
|
8306
8319
|
class NoSelfClosing extends Rule {
|
|
8307
8320
|
constructor(options) {
|
|
8308
|
-
super({ ...defaults$
|
|
8321
|
+
super({ ...defaults$c, ...options });
|
|
8309
8322
|
}
|
|
8310
8323
|
static schema() {
|
|
8311
8324
|
return {
|
|
@@ -8389,13 +8402,13 @@ class NoTrailingWhitespace extends Rule {
|
|
|
8389
8402
|
}
|
|
8390
8403
|
}
|
|
8391
8404
|
|
|
8392
|
-
const defaults$
|
|
8405
|
+
const defaults$b = {
|
|
8393
8406
|
include: null,
|
|
8394
8407
|
exclude: null
|
|
8395
8408
|
};
|
|
8396
8409
|
class NoUnknownElements extends Rule {
|
|
8397
8410
|
constructor(options) {
|
|
8398
|
-
super({ ...defaults$
|
|
8411
|
+
super({ ...defaults$b, ...options });
|
|
8399
8412
|
}
|
|
8400
8413
|
static schema() {
|
|
8401
8414
|
return {
|
|
@@ -8501,13 +8514,13 @@ const replacement = {
|
|
|
8501
8514
|
reset: '<button type="reset">',
|
|
8502
8515
|
image: '<button type="button">'
|
|
8503
8516
|
};
|
|
8504
|
-
const defaults$
|
|
8517
|
+
const defaults$a = {
|
|
8505
8518
|
include: null,
|
|
8506
8519
|
exclude: null
|
|
8507
8520
|
};
|
|
8508
8521
|
class PreferButton extends Rule {
|
|
8509
8522
|
constructor(options) {
|
|
8510
|
-
super({ ...defaults$
|
|
8523
|
+
super({ ...defaults$a, ...options });
|
|
8511
8524
|
}
|
|
8512
8525
|
static schema() {
|
|
8513
8526
|
return {
|
|
@@ -8573,7 +8586,7 @@ class PreferButton extends Rule {
|
|
|
8573
8586
|
}
|
|
8574
8587
|
}
|
|
8575
8588
|
|
|
8576
|
-
const defaults$
|
|
8589
|
+
const defaults$9 = {
|
|
8577
8590
|
mapping: {
|
|
8578
8591
|
article: "article",
|
|
8579
8592
|
banner: "header",
|
|
@@ -8603,7 +8616,7 @@ const defaults$8 = {
|
|
|
8603
8616
|
};
|
|
8604
8617
|
class PreferNativeElement extends Rule {
|
|
8605
8618
|
constructor(options) {
|
|
8606
|
-
super({ ...defaults$
|
|
8619
|
+
super({ ...defaults$9, ...options });
|
|
8607
8620
|
}
|
|
8608
8621
|
static schema() {
|
|
8609
8622
|
return {
|
|
@@ -8717,12 +8730,12 @@ class PreferTbody extends Rule {
|
|
|
8717
8730
|
}
|
|
8718
8731
|
}
|
|
8719
8732
|
|
|
8720
|
-
const defaults$
|
|
8733
|
+
const defaults$8 = {
|
|
8721
8734
|
tags: ["script", "style"]
|
|
8722
8735
|
};
|
|
8723
8736
|
class RequireCSPNonce extends Rule {
|
|
8724
8737
|
constructor(options) {
|
|
8725
|
-
super({ ...defaults$
|
|
8738
|
+
super({ ...defaults$8, ...options });
|
|
8726
8739
|
}
|
|
8727
8740
|
static schema() {
|
|
8728
8741
|
return {
|
|
@@ -8769,7 +8782,7 @@ class RequireCSPNonce extends Rule {
|
|
|
8769
8782
|
}
|
|
8770
8783
|
}
|
|
8771
8784
|
|
|
8772
|
-
const defaults$
|
|
8785
|
+
const defaults$7 = {
|
|
8773
8786
|
target: "all",
|
|
8774
8787
|
include: null,
|
|
8775
8788
|
exclude: null
|
|
@@ -8798,7 +8811,7 @@ function linkSupportsSri(node) {
|
|
|
8798
8811
|
class RequireSri extends Rule {
|
|
8799
8812
|
target;
|
|
8800
8813
|
constructor(options) {
|
|
8801
|
-
super({ ...defaults$
|
|
8814
|
+
super({ ...defaults$7, ...options });
|
|
8802
8815
|
this.target = this.options.target;
|
|
8803
8816
|
}
|
|
8804
8817
|
static schema() {
|
|
@@ -8971,7 +8984,7 @@ class SvgFocusable extends Rule {
|
|
|
8971
8984
|
}
|
|
8972
8985
|
}
|
|
8973
8986
|
|
|
8974
|
-
const defaults$
|
|
8987
|
+
const defaults$6 = {
|
|
8975
8988
|
characters: [
|
|
8976
8989
|
{ pattern: " ", replacement: " ", description: "non-breaking space" },
|
|
8977
8990
|
{ pattern: "-", replacement: "‑", description: "non-breaking hyphen" }
|
|
@@ -9003,7 +9016,7 @@ function matchAll(text, regexp) {
|
|
|
9003
9016
|
class TelNonBreaking extends Rule {
|
|
9004
9017
|
regex;
|
|
9005
9018
|
constructor(options) {
|
|
9006
|
-
super({ ...defaults$
|
|
9019
|
+
super({ ...defaults$6, ...options });
|
|
9007
9020
|
this.regex = constructRegex(this.options.characters);
|
|
9008
9021
|
}
|
|
9009
9022
|
static schema() {
|
|
@@ -9378,7 +9391,7 @@ class UniqueLandmark extends Rule {
|
|
|
9378
9391
|
}
|
|
9379
9392
|
}
|
|
9380
9393
|
|
|
9381
|
-
const defaults$
|
|
9394
|
+
const defaults$5 = {
|
|
9382
9395
|
ignoreCase: false,
|
|
9383
9396
|
requireSemicolon: true
|
|
9384
9397
|
};
|
|
@@ -9412,7 +9425,7 @@ function getDescription(context, options) {
|
|
|
9412
9425
|
}
|
|
9413
9426
|
class UnknownCharReference extends Rule {
|
|
9414
9427
|
constructor(options) {
|
|
9415
|
-
super({ ...defaults$
|
|
9428
|
+
super({ ...defaults$5, ...options });
|
|
9416
9429
|
}
|
|
9417
9430
|
static schema() {
|
|
9418
9431
|
return {
|
|
@@ -10028,12 +10041,12 @@ class ValidAutocomplete extends Rule {
|
|
|
10028
10041
|
}
|
|
10029
10042
|
}
|
|
10030
10043
|
|
|
10031
|
-
const defaults$
|
|
10044
|
+
const defaults$4 = {
|
|
10032
10045
|
relaxed: false
|
|
10033
10046
|
};
|
|
10034
10047
|
class ValidID extends Rule {
|
|
10035
10048
|
constructor(options) {
|
|
10036
|
-
super({ ...defaults$
|
|
10049
|
+
super({ ...defaults$4, ...options });
|
|
10037
10050
|
}
|
|
10038
10051
|
static schema() {
|
|
10039
10052
|
return {
|
|
@@ -10139,13 +10152,13 @@ class VoidContent extends Rule {
|
|
|
10139
10152
|
}
|
|
10140
10153
|
}
|
|
10141
10154
|
|
|
10142
|
-
const defaults$
|
|
10155
|
+
const defaults$3 = {
|
|
10143
10156
|
style: "omit"
|
|
10144
10157
|
};
|
|
10145
10158
|
class VoidStyle extends Rule {
|
|
10146
10159
|
style;
|
|
10147
10160
|
constructor(options) {
|
|
10148
|
-
super({ ...defaults$
|
|
10161
|
+
super({ ...defaults$3, ...options });
|
|
10149
10162
|
this.style = parseStyle(this.options.style);
|
|
10150
10163
|
}
|
|
10151
10164
|
static schema() {
|
|
@@ -10346,13 +10359,13 @@ class H36 extends Rule {
|
|
|
10346
10359
|
}
|
|
10347
10360
|
}
|
|
10348
10361
|
|
|
10349
|
-
const defaults$
|
|
10362
|
+
const defaults$2 = {
|
|
10350
10363
|
allowEmpty: true,
|
|
10351
10364
|
alias: []
|
|
10352
10365
|
};
|
|
10353
10366
|
class H37 extends Rule {
|
|
10354
10367
|
constructor(options) {
|
|
10355
|
-
super({ ...defaults$
|
|
10368
|
+
super({ ...defaults$2, ...options });
|
|
10356
10369
|
if (!Array.isArray(this.options.alias)) {
|
|
10357
10370
|
this.options.alias = [this.options.alias];
|
|
10358
10371
|
}
|
|
@@ -10414,9 +10427,62 @@ class H37 extends Rule {
|
|
|
10414
10427
|
}
|
|
10415
10428
|
}
|
|
10416
10429
|
|
|
10430
|
+
const defaults$1 = {
|
|
10431
|
+
strict: false
|
|
10432
|
+
};
|
|
10417
10433
|
const { enum: validScopes } = elements.html5.th.attributes?.scope;
|
|
10418
10434
|
const joinedScopes = utils_naturalJoin.naturalJoin(validScopes);
|
|
10435
|
+
const td = 0;
|
|
10436
|
+
const th = 1;
|
|
10437
|
+
function getShape(cells) {
|
|
10438
|
+
const rows = cells.length;
|
|
10439
|
+
const cols = cells[0].length;
|
|
10440
|
+
return { rows, cols };
|
|
10441
|
+
}
|
|
10442
|
+
function isSimpleTable(table) {
|
|
10443
|
+
const haveHeadersAttr = table.querySelector("> tr > [headers], > tbody > tr > [headers]");
|
|
10444
|
+
if (haveHeadersAttr) {
|
|
10445
|
+
return false;
|
|
10446
|
+
}
|
|
10447
|
+
const rows = table.querySelectorAll("> tr, > thead > tr, > tbody > tr");
|
|
10448
|
+
if (rows.length === 0) {
|
|
10449
|
+
return false;
|
|
10450
|
+
}
|
|
10451
|
+
const cells = rows.map((tr) => tr.querySelectorAll("> *").map((el) => el.is("th") ? th : td));
|
|
10452
|
+
if (cells[0].length === 0) {
|
|
10453
|
+
return false;
|
|
10454
|
+
}
|
|
10455
|
+
const numColumns = cells[0].length;
|
|
10456
|
+
if (!cells.every((row) => row.length === numColumns)) {
|
|
10457
|
+
return false;
|
|
10458
|
+
}
|
|
10459
|
+
const shape = getShape(cells);
|
|
10460
|
+
const headersPerRow = cells.map((row) => row.reduce((sum, cell) => sum + cell, 0));
|
|
10461
|
+
const headersPerColumn = Array(shape.cols).fill(0).map((_, index) => {
|
|
10462
|
+
return cells.reduce((sum, it) => sum + it[index], 0);
|
|
10463
|
+
});
|
|
10464
|
+
const [firstRow, ...otherRows] = headersPerRow;
|
|
10465
|
+
if (firstRow === shape.cols && otherRows.every((row) => row === 0)) {
|
|
10466
|
+
return true;
|
|
10467
|
+
}
|
|
10468
|
+
const [firstCol, ...otherCols] = headersPerColumn;
|
|
10469
|
+
const haveThead = Boolean(table.querySelector("> thead"));
|
|
10470
|
+
if (firstCol === shape.rows && otherCols.every((col) => col === 0) && !haveThead) {
|
|
10471
|
+
return true;
|
|
10472
|
+
}
|
|
10473
|
+
return false;
|
|
10474
|
+
}
|
|
10419
10475
|
class H63 extends Rule {
|
|
10476
|
+
constructor(options) {
|
|
10477
|
+
super({ ...defaults$1, ...options });
|
|
10478
|
+
}
|
|
10479
|
+
static schema() {
|
|
10480
|
+
return {
|
|
10481
|
+
strict: {
|
|
10482
|
+
type: "boolean"
|
|
10483
|
+
}
|
|
10484
|
+
};
|
|
10485
|
+
}
|
|
10420
10486
|
documentation() {
|
|
10421
10487
|
return {
|
|
10422
10488
|
description: "H63: Using the scope attribute to associate header cells and data cells in data tables",
|
|
@@ -10424,23 +10490,31 @@ class H63 extends Rule {
|
|
|
10424
10490
|
};
|
|
10425
10491
|
}
|
|
10426
10492
|
setup() {
|
|
10427
|
-
|
|
10493
|
+
const { strict } = this.options;
|
|
10494
|
+
this.on("element:ready", (event) => {
|
|
10428
10495
|
const node = event.target;
|
|
10429
|
-
if (node.
|
|
10496
|
+
if (!node.is("table")) {
|
|
10430
10497
|
return;
|
|
10431
10498
|
}
|
|
10432
|
-
|
|
10499
|
+
if (strict || !isSimpleTable(node)) {
|
|
10500
|
+
this.validateTable(node);
|
|
10501
|
+
}
|
|
10502
|
+
});
|
|
10503
|
+
}
|
|
10504
|
+
validateTable(node) {
|
|
10505
|
+
for (const th2 of node.querySelectorAll("th")) {
|
|
10506
|
+
const scope = th2.getAttribute("scope");
|
|
10433
10507
|
const value = scope?.value;
|
|
10434
10508
|
if (value instanceof DynamicValue) {
|
|
10435
|
-
|
|
10509
|
+
continue;
|
|
10436
10510
|
}
|
|
10437
10511
|
if (value && validScopes.includes(value)) {
|
|
10438
|
-
|
|
10512
|
+
continue;
|
|
10439
10513
|
}
|
|
10440
10514
|
const message = `<th> element must have a valid scope attribute: ${joinedScopes}`;
|
|
10441
|
-
const location = scope?.valueLocation ?? scope?.keyLocation ??
|
|
10442
|
-
this.report(
|
|
10443
|
-
}
|
|
10515
|
+
const location = scope?.valueLocation ?? scope?.keyLocation ?? th2.location;
|
|
10516
|
+
this.report(th2, message, location);
|
|
10517
|
+
}
|
|
10444
10518
|
}
|
|
10445
10519
|
}
|
|
10446
10520
|
|
|
@@ -11732,7 +11806,7 @@ class EventHandler {
|
|
|
11732
11806
|
}
|
|
11733
11807
|
|
|
11734
11808
|
const name = "html-validate";
|
|
11735
|
-
const version = "9.
|
|
11809
|
+
const version = "9.7.1";
|
|
11736
11810
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11737
11811
|
|
|
11738
11812
|
function freeze(src) {
|