html-validate 7.10.1 → 7.11.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 +2 -1
- package/dist/cjs/browser.js.map +1 -1
- package/dist/cjs/cli.js +0 -1
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core.d.ts +1 -4
- package/dist/cjs/core.js +149 -106
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +5 -1
- package/dist/cjs/elements.js.map +1 -1
- package/dist/cjs/html-validate.js +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/jest-lib.js +0 -1
- package/dist/cjs/jest-lib.js.map +1 -1
- package/dist/cjs/jest.d.ts +1 -0
- package/dist/cjs/jest.js +2 -2
- package/dist/cjs/meta-helper.d.ts +1 -0
- package/dist/cjs/rules-helper.d.ts +10 -1
- package/dist/cjs/rules-helper.js +54 -1
- package/dist/cjs/rules-helper.js.map +1 -1
- package/dist/cjs/test-utils.d.ts +1 -0
- package/dist/es/browser.d.ts +1 -1
- package/dist/es/browser.js +2 -2
- package/dist/es/cli.js +0 -1
- package/dist/es/cli.js.map +1 -1
- package/dist/es/core.d.ts +1 -4
- package/dist/es/core.js +150 -107
- package/dist/es/core.js.map +1 -1
- package/dist/es/elements.js +5 -1
- package/dist/es/elements.js.map +1 -1
- package/dist/es/html-validate.js +2 -2
- package/dist/es/index.d.ts +1 -1
- package/dist/es/index.js +2 -2
- package/dist/es/jest-lib.js +0 -1
- package/dist/es/jest-lib.js.map +1 -1
- package/dist/es/jest.d.ts +1 -0
- package/dist/es/jest.js +2 -2
- package/dist/es/meta-helper.d.ts +1 -0
- package/dist/es/rules-helper.d.ts +10 -1
- package/dist/es/rules-helper.js +53 -2
- package/dist/es/rules-helper.js.map +1 -1
- package/dist/es/test-utils.d.ts +1 -0
- package/package.json +17 -17
package/dist/es/core.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import betterAjvErrors from '@sidvind/better-ajv-errors';
|
|
3
|
-
import { C as CaseStyle, n as naturalJoin, c as classifyNodeText, T as TextClassification, h as hasAltText,
|
|
3
|
+
import { i as isKeywordIgnored, C as CaseStyle, n as naturalJoin, c as classifyNodeText, T as TextClassification, h as hasAltText, a as isHTMLHidden, b as isAriaHidden, d as hasAccessibleName, k as keywordPatternMatcher, e as inAccessibilityTree, f as hasAriaLabel } from './rules-helper.js';
|
|
4
4
|
import Ajv from 'ajv';
|
|
5
5
|
import deepmerge from 'deepmerge';
|
|
6
6
|
import * as espree from 'espree';
|
|
7
7
|
import * as walk from 'acorn-walk';
|
|
8
|
-
import { e as entities$1, h as html5, b as bundledElements } from './elements.js';
|
|
9
8
|
import path from 'path';
|
|
10
9
|
import semver from 'semver';
|
|
11
10
|
import kleur from 'kleur';
|
|
11
|
+
import { e as entities$1, h as html5, b as bundledElements } from './elements.js';
|
|
12
12
|
import { createRequire } from 'module';
|
|
13
13
|
import { codeFrameColumns } from '@babel/code-frame';
|
|
14
14
|
import stylishImpl from '@html-validate/stylish';
|
|
@@ -2614,29 +2614,40 @@ class Validator {
|
|
|
2614
2614
|
*
|
|
2615
2615
|
* For instance, a `<table>` element can only contain a single `<tbody>`
|
|
2616
2616
|
* child. If multiple `<tbody>` exists this test will fail both nodes.
|
|
2617
|
+
* Note that this is called on the parent but will fail the children violating
|
|
2618
|
+
* the rule.
|
|
2617
2619
|
*
|
|
2618
|
-
* @param
|
|
2619
|
-
* @param rules - List of rules.
|
|
2620
|
-
* @
|
|
2621
|
-
* exists (including the element itself)
|
|
2622
|
-
* @returns `true` if the element passes the test.
|
|
2620
|
+
* @param children - Array of children to validate.
|
|
2621
|
+
* @param rules - List of rules of the parent element.
|
|
2622
|
+
* @returns `true` if the parent element of the children passes the test.
|
|
2623
2623
|
*/
|
|
2624
|
-
static validateOccurrences(
|
|
2624
|
+
static validateOccurrences(children, rules, cb) {
|
|
2625
2625
|
if (!rules) {
|
|
2626
2626
|
return true;
|
|
2627
2627
|
}
|
|
2628
|
-
|
|
2628
|
+
let valid = true;
|
|
2629
|
+
for (const rule of rules) {
|
|
2629
2630
|
/** @todo handle complex rules and not just plain arrays (but as of now
|
|
2630
2631
|
* there is no use-case for it) */
|
|
2631
2632
|
// istanbul ignore next
|
|
2632
|
-
if (typeof
|
|
2633
|
+
if (typeof rule !== "string") {
|
|
2633
2634
|
return false;
|
|
2634
2635
|
}
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2636
|
+
// Check if the rule has a quantifier
|
|
2637
|
+
const [, category, quantifier] = rule.match(/^(@?.*?)([?*]?)$/);
|
|
2638
|
+
const limit = category && quantifier && parseQuantifier(quantifier);
|
|
2639
|
+
if (limit) {
|
|
2640
|
+
const siblings = children.filter((cur) => Validator.validatePermittedCategory(cur, rule, true));
|
|
2641
|
+
if (siblings.length > limit) {
|
|
2642
|
+
// fail only the children above the limit (currently limit can only be 1)
|
|
2643
|
+
for (const child of siblings.slice(limit)) {
|
|
2644
|
+
cb(child, category);
|
|
2645
|
+
}
|
|
2646
|
+
valid = false;
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
return valid;
|
|
2640
2651
|
}
|
|
2641
2652
|
/**
|
|
2642
2653
|
* Validate elements order.
|
|
@@ -2698,14 +2709,15 @@ class Validator {
|
|
|
2698
2709
|
* Check if an element has the required set of elements. At least one of the
|
|
2699
2710
|
* selectors must match.
|
|
2700
2711
|
*
|
|
2701
|
-
* Returns [] when valid or a list of
|
|
2712
|
+
* Returns `[]` when valid or a list of required but missing tagnames or
|
|
2713
|
+
* categories.
|
|
2702
2714
|
*/
|
|
2703
2715
|
static validateRequiredContent(node, rules) {
|
|
2704
2716
|
if (!rules || rules.length === 0) {
|
|
2705
2717
|
return [];
|
|
2706
2718
|
}
|
|
2707
2719
|
return rules.filter((tagName) => {
|
|
2708
|
-
const haveMatchingChild = node.childElements.some((child) =>
|
|
2720
|
+
const haveMatchingChild = node.childElements.some((child) => Validator.validatePermittedCategory(child, tagName, false));
|
|
2709
2721
|
return !haveMatchingChild;
|
|
2710
2722
|
});
|
|
2711
2723
|
}
|
|
@@ -2809,16 +2821,16 @@ class Validator {
|
|
|
2809
2821
|
*/
|
|
2810
2822
|
// eslint-disable-next-line complexity
|
|
2811
2823
|
static validatePermittedCategory(node, category, defaultMatch) {
|
|
2824
|
+
const [, rawCategory] = category.match(/^(@?.*?)([?*]?)$/);
|
|
2812
2825
|
/* match tagName when an explicit name is given */
|
|
2813
|
-
if (
|
|
2814
|
-
|
|
2815
|
-
return node.tagName === tagName;
|
|
2826
|
+
if (rawCategory[0] !== "@") {
|
|
2827
|
+
return node.tagName === rawCategory;
|
|
2816
2828
|
}
|
|
2817
2829
|
/* if the meta entry is missing assume any content model would match */
|
|
2818
2830
|
if (!node.meta) {
|
|
2819
2831
|
return defaultMatch;
|
|
2820
2832
|
}
|
|
2821
|
-
switch (
|
|
2833
|
+
switch (rawCategory) {
|
|
2822
2834
|
case "@meta":
|
|
2823
2835
|
return node.meta.metadata;
|
|
2824
2836
|
case "@flow":
|
|
@@ -2850,23 +2862,15 @@ function validateKeys(rule) {
|
|
|
2850
2862
|
}
|
|
2851
2863
|
}
|
|
2852
2864
|
}
|
|
2853
|
-
function
|
|
2854
|
-
|
|
2855
|
-
/* content not allowed, catched by another rule so just assume unlimited
|
|
2856
|
-
* usage for this purpose */
|
|
2857
|
-
return null;
|
|
2858
|
-
}
|
|
2859
|
-
const [, qualifier] = category.match(/^.*?([?*]?)$/);
|
|
2860
|
-
switch (qualifier) {
|
|
2865
|
+
function parseQuantifier(quantifier) {
|
|
2866
|
+
switch (quantifier) {
|
|
2861
2867
|
case "?":
|
|
2862
2868
|
return 1;
|
|
2863
|
-
case "":
|
|
2864
|
-
return null;
|
|
2865
2869
|
case "*":
|
|
2866
2870
|
return null;
|
|
2867
|
-
|
|
2871
|
+
// istanbul ignore next
|
|
2868
2872
|
default:
|
|
2869
|
-
throw new Error(`Invalid
|
|
2873
|
+
throw new Error(`Invalid quantifier "${quantifier}" used`);
|
|
2870
2874
|
}
|
|
2871
2875
|
}
|
|
2872
2876
|
|
|
@@ -3398,16 +3402,7 @@ class Rule {
|
|
|
3398
3402
|
* `exclude`.
|
|
3399
3403
|
*/
|
|
3400
3404
|
isKeywordIgnored(keyword, matcher = (list, it) => list.includes(it)) {
|
|
3401
|
-
|
|
3402
|
-
/* ignore keyword if not present in "include" */
|
|
3403
|
-
if (include && !matcher(include, keyword)) {
|
|
3404
|
-
return true;
|
|
3405
|
-
}
|
|
3406
|
-
/* ignore keyword if present in "excludes" */
|
|
3407
|
-
if (exclude && matcher(exclude, keyword)) {
|
|
3408
|
-
return true;
|
|
3409
|
-
}
|
|
3410
|
-
return false;
|
|
3405
|
+
return isKeywordIgnored(this.options, keyword, matcher);
|
|
3411
3406
|
}
|
|
3412
3407
|
/**
|
|
3413
3408
|
* Find all tags which has enabled given property.
|
|
@@ -3533,7 +3528,7 @@ class Rule {
|
|
|
3533
3528
|
}
|
|
3534
3529
|
}
|
|
3535
3530
|
|
|
3536
|
-
const defaults$
|
|
3531
|
+
const defaults$v = {
|
|
3537
3532
|
allowExternal: true,
|
|
3538
3533
|
allowRelative: true,
|
|
3539
3534
|
allowAbsolute: true,
|
|
@@ -3577,7 +3572,7 @@ function matchList(value, list) {
|
|
|
3577
3572
|
}
|
|
3578
3573
|
class AllowedLinks extends Rule {
|
|
3579
3574
|
constructor(options) {
|
|
3580
|
-
super({ ...defaults$
|
|
3575
|
+
super({ ...defaults$v, ...options });
|
|
3581
3576
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
3582
3577
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
3583
3578
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -3725,7 +3720,7 @@ var RuleContext$1;
|
|
|
3725
3720
|
RuleContext["MISSING_ALT"] = "missing-alt";
|
|
3726
3721
|
RuleContext["MISSING_HREF"] = "missing-href";
|
|
3727
3722
|
})(RuleContext$1 || (RuleContext$1 = {}));
|
|
3728
|
-
const defaults$
|
|
3723
|
+
const defaults$u = {
|
|
3729
3724
|
accessible: true,
|
|
3730
3725
|
};
|
|
3731
3726
|
function findByTarget(target, siblings) {
|
|
@@ -3763,7 +3758,7 @@ function getDescription$1(context) {
|
|
|
3763
3758
|
}
|
|
3764
3759
|
class AreaAlt extends Rule {
|
|
3765
3760
|
constructor(options) {
|
|
3766
|
-
super({ ...defaults$
|
|
3761
|
+
super({ ...defaults$u, ...options });
|
|
3767
3762
|
}
|
|
3768
3763
|
static schema() {
|
|
3769
3764
|
return {
|
|
@@ -3927,13 +3922,13 @@ class AriaLabelMisuse extends Rule {
|
|
|
3927
3922
|
class ConfigError extends UserError {
|
|
3928
3923
|
}
|
|
3929
3924
|
|
|
3930
|
-
const defaults$
|
|
3925
|
+
const defaults$t = {
|
|
3931
3926
|
style: "lowercase",
|
|
3932
3927
|
ignoreForeign: true,
|
|
3933
3928
|
};
|
|
3934
3929
|
class AttrCase extends Rule {
|
|
3935
3930
|
constructor(options) {
|
|
3936
|
-
super({ ...defaults$
|
|
3931
|
+
super({ ...defaults$t, ...options });
|
|
3937
3932
|
this.style = new CaseStyle(this.options.style, "attr-case");
|
|
3938
3933
|
}
|
|
3939
3934
|
static schema() {
|
|
@@ -4278,7 +4273,7 @@ class AttrDelimiter extends Rule {
|
|
|
4278
4273
|
}
|
|
4279
4274
|
|
|
4280
4275
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
4281
|
-
const defaults$
|
|
4276
|
+
const defaults$s = {
|
|
4282
4277
|
pattern: DEFAULT_PATTERN,
|
|
4283
4278
|
ignoreForeign: true,
|
|
4284
4279
|
};
|
|
@@ -4315,7 +4310,7 @@ function generateDescription(name, pattern) {
|
|
|
4315
4310
|
}
|
|
4316
4311
|
class AttrPattern extends Rule {
|
|
4317
4312
|
constructor(options) {
|
|
4318
|
-
super({ ...defaults$
|
|
4313
|
+
super({ ...defaults$s, ...options });
|
|
4319
4314
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4320
4315
|
}
|
|
4321
4316
|
static schema() {
|
|
@@ -4376,7 +4371,7 @@ var QuoteStyle;
|
|
|
4376
4371
|
QuoteStyle["AUTO_QUOTE"] = "auto";
|
|
4377
4372
|
QuoteStyle["ANY_QUOTE"] = "any";
|
|
4378
4373
|
})(QuoteStyle || (QuoteStyle = {}));
|
|
4379
|
-
const defaults$
|
|
4374
|
+
const defaults$r = {
|
|
4380
4375
|
style: "auto",
|
|
4381
4376
|
unquoted: false,
|
|
4382
4377
|
};
|
|
@@ -4443,7 +4438,7 @@ class AttrQuotes extends Rule {
|
|
|
4443
4438
|
};
|
|
4444
4439
|
}
|
|
4445
4440
|
constructor(options) {
|
|
4446
|
-
super({ ...defaults$
|
|
4441
|
+
super({ ...defaults$r, ...options });
|
|
4447
4442
|
this.style = parseStyle$4(this.options.style);
|
|
4448
4443
|
}
|
|
4449
4444
|
setup() {
|
|
@@ -4613,12 +4608,12 @@ class AttributeAllowedValues extends Rule {
|
|
|
4613
4608
|
}
|
|
4614
4609
|
}
|
|
4615
4610
|
|
|
4616
|
-
const defaults$
|
|
4611
|
+
const defaults$q = {
|
|
4617
4612
|
style: "omit",
|
|
4618
4613
|
};
|
|
4619
4614
|
class AttributeBooleanStyle extends Rule {
|
|
4620
4615
|
constructor(options) {
|
|
4621
|
-
super({ ...defaults$
|
|
4616
|
+
super({ ...defaults$q, ...options });
|
|
4622
4617
|
this.hasInvalidStyle = parseStyle$3(this.options.style);
|
|
4623
4618
|
}
|
|
4624
4619
|
static schema() {
|
|
@@ -4694,12 +4689,12 @@ function reportMessage$1(attr, style) {
|
|
|
4694
4689
|
return "";
|
|
4695
4690
|
}
|
|
4696
4691
|
|
|
4697
|
-
const defaults$
|
|
4692
|
+
const defaults$p = {
|
|
4698
4693
|
style: "omit",
|
|
4699
4694
|
};
|
|
4700
4695
|
class AttributeEmptyStyle extends Rule {
|
|
4701
4696
|
constructor(options) {
|
|
4702
|
-
super({ ...defaults$
|
|
4697
|
+
super({ ...defaults$p, ...options });
|
|
4703
4698
|
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
4704
4699
|
}
|
|
4705
4700
|
static schema() {
|
|
@@ -4855,12 +4850,12 @@ function describePattern(pattern) {
|
|
|
4855
4850
|
}
|
|
4856
4851
|
}
|
|
4857
4852
|
|
|
4858
|
-
const defaults$
|
|
4853
|
+
const defaults$o = {
|
|
4859
4854
|
pattern: "kebabcase",
|
|
4860
4855
|
};
|
|
4861
4856
|
class ClassPattern extends Rule {
|
|
4862
4857
|
constructor(options) {
|
|
4863
|
-
super({ ...defaults$
|
|
4858
|
+
super({ ...defaults$o, ...options });
|
|
4864
4859
|
this.pattern = parsePattern(this.options.pattern);
|
|
4865
4860
|
}
|
|
4866
4861
|
static schema() {
|
|
@@ -4969,13 +4964,13 @@ class CloseOrder extends Rule {
|
|
|
4969
4964
|
}
|
|
4970
4965
|
}
|
|
4971
4966
|
|
|
4972
|
-
const defaults$
|
|
4967
|
+
const defaults$n = {
|
|
4973
4968
|
include: null,
|
|
4974
4969
|
exclude: null,
|
|
4975
4970
|
};
|
|
4976
4971
|
class Deprecated extends Rule {
|
|
4977
4972
|
constructor(options) {
|
|
4978
|
-
super({ ...defaults$
|
|
4973
|
+
super({ ...defaults$n, ...options });
|
|
4979
4974
|
}
|
|
4980
4975
|
static schema() {
|
|
4981
4976
|
return {
|
|
@@ -5138,12 +5133,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
|
|
|
5138
5133
|
}
|
|
5139
5134
|
};
|
|
5140
5135
|
|
|
5141
|
-
const defaults$
|
|
5136
|
+
const defaults$m = {
|
|
5142
5137
|
style: "uppercase",
|
|
5143
5138
|
};
|
|
5144
5139
|
class DoctypeStyle extends Rule {
|
|
5145
5140
|
constructor(options) {
|
|
5146
|
-
super({ ...defaults$
|
|
5141
|
+
super({ ...defaults$m, ...options });
|
|
5147
5142
|
}
|
|
5148
5143
|
static schema() {
|
|
5149
5144
|
return {
|
|
@@ -5175,12 +5170,12 @@ class DoctypeStyle extends Rule {
|
|
|
5175
5170
|
}
|
|
5176
5171
|
}
|
|
5177
5172
|
|
|
5178
|
-
const defaults$
|
|
5173
|
+
const defaults$l = {
|
|
5179
5174
|
style: "lowercase",
|
|
5180
5175
|
};
|
|
5181
5176
|
class ElementCase extends Rule {
|
|
5182
5177
|
constructor(options) {
|
|
5183
|
-
super({ ...defaults$
|
|
5178
|
+
super({ ...defaults$l, ...options });
|
|
5184
5179
|
this.style = new CaseStyle(this.options.style, "element-case");
|
|
5185
5180
|
}
|
|
5186
5181
|
static schema() {
|
|
@@ -5246,14 +5241,14 @@ class ElementCase extends Rule {
|
|
|
5246
5241
|
}
|
|
5247
5242
|
}
|
|
5248
5243
|
|
|
5249
|
-
const defaults$
|
|
5244
|
+
const defaults$k = {
|
|
5250
5245
|
pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
|
|
5251
5246
|
whitelist: [],
|
|
5252
5247
|
blacklist: [],
|
|
5253
5248
|
};
|
|
5254
5249
|
class ElementName extends Rule {
|
|
5255
5250
|
constructor(options) {
|
|
5256
|
-
super({ ...defaults$
|
|
5251
|
+
super({ ...defaults$k, ...options });
|
|
5257
5252
|
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
5258
5253
|
this.pattern = new RegExp(this.options.pattern);
|
|
5259
5254
|
}
|
|
@@ -5294,7 +5289,7 @@ class ElementName extends Rule {
|
|
|
5294
5289
|
...context.blacklist.map((cur) => `- ${cur}`),
|
|
5295
5290
|
];
|
|
5296
5291
|
}
|
|
5297
|
-
if (context.pattern !== defaults$
|
|
5292
|
+
if (context.pattern !== defaults$k.pattern) {
|
|
5298
5293
|
return [
|
|
5299
5294
|
`<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
|
|
5300
5295
|
"",
|
|
@@ -5485,24 +5480,16 @@ class ElementPermittedOccurrences extends Rule {
|
|
|
5485
5480
|
this.on("dom:ready", (event) => {
|
|
5486
5481
|
const doc = event.document;
|
|
5487
5482
|
doc.visitDepthFirst((node) => {
|
|
5488
|
-
|
|
5489
|
-
if (!parent || !parent.meta) {
|
|
5483
|
+
if (!node || !node.meta) {
|
|
5490
5484
|
return;
|
|
5491
5485
|
}
|
|
5492
|
-
const rules =
|
|
5486
|
+
const rules = node.meta.permittedContent;
|
|
5493
5487
|
if (!rules) {
|
|
5494
5488
|
return;
|
|
5495
5489
|
}
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
* subsequent occurrences should. */
|
|
5500
|
-
if (first) {
|
|
5501
|
-
return;
|
|
5502
|
-
}
|
|
5503
|
-
if (parent.meta && !Validator.validateOccurrences(node, rules, siblings.length)) {
|
|
5504
|
-
this.report(node, `Element <${node.tagName}> can only appear once under ${parent.annotatedName}`);
|
|
5505
|
-
}
|
|
5490
|
+
Validator.validateOccurrences(node.childElements, rules, (child, category) => {
|
|
5491
|
+
this.report(child, `Element <${category}> can only appear once under ${node.annotatedName}`);
|
|
5492
|
+
});
|
|
5506
5493
|
});
|
|
5507
5494
|
});
|
|
5508
5495
|
}
|
|
@@ -5537,11 +5524,11 @@ class ElementPermittedOrder extends Rule {
|
|
|
5537
5524
|
function isCategoryOrTag(value) {
|
|
5538
5525
|
return typeof value === "string";
|
|
5539
5526
|
}
|
|
5540
|
-
function isCategory(value) {
|
|
5527
|
+
function isCategory$1(value) {
|
|
5541
5528
|
return value[0] === "@";
|
|
5542
5529
|
}
|
|
5543
5530
|
function formatCategoryOrTag(value) {
|
|
5544
|
-
return isCategory(value) ? value.slice(1) : `<${value}>`;
|
|
5531
|
+
return isCategory$1(value) ? value.slice(1) : `<${value}>`;
|
|
5545
5532
|
}
|
|
5546
5533
|
function isFormattable(rules) {
|
|
5547
5534
|
return rules.length > 0 && rules.every(isCategoryOrTag);
|
|
@@ -5554,7 +5541,7 @@ function getRuleDescription$1(context) {
|
|
|
5554
5541
|
const preamble = `The \`${child}\` element cannot have a \`${parent}\` element as parent.`;
|
|
5555
5542
|
if (isFormattable(rules)) {
|
|
5556
5543
|
const allowed = rules.filter(isCategoryOrTag).map((it) => {
|
|
5557
|
-
if (isCategory(it)) {
|
|
5544
|
+
if (isCategory$1(it)) {
|
|
5558
5545
|
return `- any ${it.slice(1)} element`;
|
|
5559
5546
|
}
|
|
5560
5547
|
else {
|
|
@@ -5717,6 +5704,9 @@ class ElementRequiredAttributes extends Rule {
|
|
|
5717
5704
|
}
|
|
5718
5705
|
}
|
|
5719
5706
|
|
|
5707
|
+
function isCategory(value) {
|
|
5708
|
+
return value[0] === "@";
|
|
5709
|
+
}
|
|
5720
5710
|
class ElementRequiredContent extends Rule {
|
|
5721
5711
|
documentation(context) {
|
|
5722
5712
|
if (context) {
|
|
@@ -5751,7 +5741,8 @@ class ElementRequiredContent extends Rule {
|
|
|
5751
5741
|
element: node.annotatedName,
|
|
5752
5742
|
missing: `<${missing}>`,
|
|
5753
5743
|
};
|
|
5754
|
-
const
|
|
5744
|
+
const tag = isCategory(missing) ? `${missing.slice(1)} element` : `<${missing}>`;
|
|
5745
|
+
const message = `${node.annotatedName} element must have ${tag} as content`;
|
|
5755
5746
|
this.report(node, message, null, context);
|
|
5756
5747
|
}
|
|
5757
5748
|
});
|
|
@@ -5842,7 +5833,7 @@ class EmptyTitle extends Rule {
|
|
|
5842
5833
|
}
|
|
5843
5834
|
}
|
|
5844
5835
|
|
|
5845
|
-
const defaults$
|
|
5836
|
+
const defaults$j = {
|
|
5846
5837
|
allowMultipleH1: false,
|
|
5847
5838
|
minInitialRank: "h1",
|
|
5848
5839
|
sectioningRoots: ["dialog", '[role="dialog"]'],
|
|
@@ -5873,7 +5864,7 @@ function parseMaxInitial(value) {
|
|
|
5873
5864
|
}
|
|
5874
5865
|
class HeadingLevel extends Rule {
|
|
5875
5866
|
constructor(options) {
|
|
5876
|
-
super({ ...defaults$
|
|
5867
|
+
super({ ...defaults$j, ...options });
|
|
5877
5868
|
this.stack = [];
|
|
5878
5869
|
this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
|
|
5879
5870
|
this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
|
|
@@ -6031,12 +6022,12 @@ class HeadingLevel extends Rule {
|
|
|
6031
6022
|
}
|
|
6032
6023
|
}
|
|
6033
6024
|
|
|
6034
|
-
const defaults$
|
|
6025
|
+
const defaults$i = {
|
|
6035
6026
|
pattern: "kebabcase",
|
|
6036
6027
|
};
|
|
6037
6028
|
class IdPattern extends Rule {
|
|
6038
6029
|
constructor(options) {
|
|
6039
|
-
super({ ...defaults$
|
|
6030
|
+
super({ ...defaults$i, ...options });
|
|
6040
6031
|
this.pattern = parsePattern(this.options.pattern);
|
|
6041
6032
|
}
|
|
6042
6033
|
static schema() {
|
|
@@ -6318,12 +6309,12 @@ function findLabelByParent(el) {
|
|
|
6318
6309
|
return [];
|
|
6319
6310
|
}
|
|
6320
6311
|
|
|
6321
|
-
const defaults$
|
|
6312
|
+
const defaults$h = {
|
|
6322
6313
|
maxlength: 70,
|
|
6323
6314
|
};
|
|
6324
6315
|
class LongTitle extends Rule {
|
|
6325
6316
|
constructor(options) {
|
|
6326
|
-
super({ ...defaults$
|
|
6317
|
+
super({ ...defaults$h, ...options });
|
|
6327
6318
|
this.maxlength = this.options.maxlength;
|
|
6328
6319
|
}
|
|
6329
6320
|
static schema() {
|
|
@@ -6513,13 +6504,13 @@ class MultipleLabeledControls extends Rule {
|
|
|
6513
6504
|
}
|
|
6514
6505
|
}
|
|
6515
6506
|
|
|
6516
|
-
const defaults$
|
|
6507
|
+
const defaults$g = {
|
|
6517
6508
|
include: null,
|
|
6518
6509
|
exclude: null,
|
|
6519
6510
|
};
|
|
6520
6511
|
class NoAutoplay extends Rule {
|
|
6521
6512
|
constructor(options) {
|
|
6522
|
-
super({ ...defaults$
|
|
6513
|
+
super({ ...defaults$g, ...options });
|
|
6523
6514
|
}
|
|
6524
6515
|
documentation(context) {
|
|
6525
6516
|
const tagName = context ? ` on <${context.tagName}>` : "";
|
|
@@ -6760,14 +6751,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
6760
6751
|
}
|
|
6761
6752
|
}
|
|
6762
6753
|
|
|
6763
|
-
const defaults$
|
|
6754
|
+
const defaults$f = {
|
|
6764
6755
|
include: null,
|
|
6765
6756
|
exclude: null,
|
|
6766
6757
|
allowedProperties: ["display"],
|
|
6767
6758
|
};
|
|
6768
6759
|
class NoInlineStyle extends Rule {
|
|
6769
6760
|
constructor(options) {
|
|
6770
|
-
super({ ...defaults$
|
|
6761
|
+
super({ ...defaults$f, ...options });
|
|
6771
6762
|
}
|
|
6772
6763
|
static schema() {
|
|
6773
6764
|
return {
|
|
@@ -6969,7 +6960,7 @@ class NoMultipleMain extends Rule {
|
|
|
6969
6960
|
}
|
|
6970
6961
|
}
|
|
6971
6962
|
|
|
6972
|
-
const defaults$
|
|
6963
|
+
const defaults$e = {
|
|
6973
6964
|
relaxed: false,
|
|
6974
6965
|
};
|
|
6975
6966
|
const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
|
|
@@ -6986,7 +6977,7 @@ const replacementTable = {
|
|
|
6986
6977
|
};
|
|
6987
6978
|
class NoRawCharacters extends Rule {
|
|
6988
6979
|
constructor(options) {
|
|
6989
|
-
super({ ...defaults$
|
|
6980
|
+
super({ ...defaults$e, ...options });
|
|
6990
6981
|
this.relaxed = this.options.relaxed;
|
|
6991
6982
|
}
|
|
6992
6983
|
static schema() {
|
|
@@ -7164,13 +7155,13 @@ class NoRedundantRole extends Rule {
|
|
|
7164
7155
|
}
|
|
7165
7156
|
|
|
7166
7157
|
const xmlns = /^(.+):.+$/;
|
|
7167
|
-
const defaults$
|
|
7158
|
+
const defaults$d = {
|
|
7168
7159
|
ignoreForeign: true,
|
|
7169
7160
|
ignoreXML: true,
|
|
7170
7161
|
};
|
|
7171
7162
|
class NoSelfClosing extends Rule {
|
|
7172
7163
|
constructor(options) {
|
|
7173
|
-
super({ ...defaults$
|
|
7164
|
+
super({ ...defaults$d, ...options });
|
|
7174
7165
|
}
|
|
7175
7166
|
static schema() {
|
|
7176
7167
|
return {
|
|
@@ -7259,7 +7250,44 @@ class NoTrailingWhitespace extends Rule {
|
|
|
7259
7250
|
}
|
|
7260
7251
|
}
|
|
7261
7252
|
|
|
7253
|
+
const defaults$c = {
|
|
7254
|
+
include: null,
|
|
7255
|
+
exclude: null,
|
|
7256
|
+
};
|
|
7262
7257
|
class NoUnknownElements extends Rule {
|
|
7258
|
+
constructor(options) {
|
|
7259
|
+
super({ ...defaults$c, ...options });
|
|
7260
|
+
}
|
|
7261
|
+
static schema() {
|
|
7262
|
+
return {
|
|
7263
|
+
exclude: {
|
|
7264
|
+
anyOf: [
|
|
7265
|
+
{
|
|
7266
|
+
items: {
|
|
7267
|
+
type: "string",
|
|
7268
|
+
},
|
|
7269
|
+
type: "array",
|
|
7270
|
+
},
|
|
7271
|
+
{
|
|
7272
|
+
type: "null",
|
|
7273
|
+
},
|
|
7274
|
+
],
|
|
7275
|
+
},
|
|
7276
|
+
include: {
|
|
7277
|
+
anyOf: [
|
|
7278
|
+
{
|
|
7279
|
+
items: {
|
|
7280
|
+
type: "string",
|
|
7281
|
+
},
|
|
7282
|
+
type: "array",
|
|
7283
|
+
},
|
|
7284
|
+
{
|
|
7285
|
+
type: "null",
|
|
7286
|
+
},
|
|
7287
|
+
],
|
|
7288
|
+
},
|
|
7289
|
+
};
|
|
7290
|
+
}
|
|
7263
7291
|
documentation(context) {
|
|
7264
7292
|
const element = context ? ` <${context}>` : "";
|
|
7265
7293
|
return {
|
|
@@ -7270,9 +7298,13 @@ class NoUnknownElements extends Rule {
|
|
|
7270
7298
|
setup() {
|
|
7271
7299
|
this.on("tag:start", (event) => {
|
|
7272
7300
|
const node = event.target;
|
|
7273
|
-
if (
|
|
7274
|
-
|
|
7301
|
+
if (node.meta) {
|
|
7302
|
+
return;
|
|
7275
7303
|
}
|
|
7304
|
+
if (this.isKeywordIgnored(node.tagName, keywordPatternMatcher)) {
|
|
7305
|
+
return;
|
|
7306
|
+
}
|
|
7307
|
+
this.report(node, `Unknown element <${node.tagName}>`, null, node.tagName);
|
|
7276
7308
|
});
|
|
7277
7309
|
}
|
|
7278
7310
|
}
|
|
@@ -8734,6 +8766,11 @@ class H37 extends Rule {
|
|
|
8734
8766
|
}
|
|
8735
8767
|
}
|
|
8736
8768
|
|
|
8769
|
+
var _a;
|
|
8770
|
+
/* istanbul ignore next: this will always be present for the <th>
|
|
8771
|
+
* attribute (or the tests would fail) */
|
|
8772
|
+
const { enum: validScopes } = (_a = html5.th.attributes) === null || _a === void 0 ? void 0 : _a.scope;
|
|
8773
|
+
const joinedScopes = naturalJoin(validScopes);
|
|
8737
8774
|
class H63 extends Rule {
|
|
8738
8775
|
documentation() {
|
|
8739
8776
|
return {
|
|
@@ -8743,19 +8780,25 @@ class H63 extends Rule {
|
|
|
8743
8780
|
}
|
|
8744
8781
|
setup() {
|
|
8745
8782
|
this.on("tag:ready", (event) => {
|
|
8746
|
-
var _a, _b
|
|
8783
|
+
var _a, _b;
|
|
8747
8784
|
const node = event.target;
|
|
8748
8785
|
/* only validate th */
|
|
8749
8786
|
if (!node || node.tagName !== "th") {
|
|
8750
8787
|
return;
|
|
8751
8788
|
}
|
|
8789
|
+
const scope = node.getAttribute("scope");
|
|
8790
|
+
const value = scope === null || scope === void 0 ? void 0 : scope.value;
|
|
8791
|
+
/* ignore dynamic scope */
|
|
8792
|
+
if (value instanceof DynamicValue) {
|
|
8793
|
+
return;
|
|
8794
|
+
}
|
|
8752
8795
|
/* ignore elements with valid scope values */
|
|
8753
|
-
|
|
8754
|
-
const scopeMeta = (_b = (_a = html5 === null || html5 === void 0 ? void 0 : html5.th) === null || _a === void 0 ? void 0 : _a.attributes) === null || _b === void 0 ? void 0 : _b.scope;
|
|
8755
|
-
if (scope && ((_c = scopeMeta.enum) === null || _c === void 0 ? void 0 : _c.includes(scope))) {
|
|
8796
|
+
if (value && validScopes.includes(value)) {
|
|
8756
8797
|
return;
|
|
8757
8798
|
}
|
|
8758
|
-
|
|
8799
|
+
const message = `<th> element must have a valid scope attribute: ${joinedScopes}`;
|
|
8800
|
+
const location = (_b = (_a = scope === null || scope === void 0 ? void 0 : scope.valueLocation) !== null && _a !== void 0 ? _a : scope === null || scope === void 0 ? void 0 : scope.keyLocation) !== null && _b !== void 0 ? _b : node.location;
|
|
8801
|
+
this.report(node, message, location);
|
|
8759
8802
|
});
|
|
8760
8803
|
}
|
|
8761
8804
|
}
|
|
@@ -11126,7 +11169,7 @@ class HtmlValidate {
|
|
|
11126
11169
|
/** @public */
|
|
11127
11170
|
const name = "html-validate";
|
|
11128
11171
|
/** @public */
|
|
11129
|
-
const version = "7.
|
|
11172
|
+
const version = "7.11.0";
|
|
11130
11173
|
/** @public */
|
|
11131
11174
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11132
11175
|
|