html-validate 7.10.1 → 7.11.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/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 +4 -4
- package/dist/cjs/core.js +204 -107
- 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 +9 -2
- package/dist/cjs/html-validate.js.map +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 +4 -4
- package/dist/es/core.js +205 -108
- 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 +10 -3
- package/dist/es/html-validate.js.map +1 -1
- 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/dist/schema/elements.json +3 -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';
|
|
@@ -1640,6 +1640,7 @@ class NestedError extends Error {
|
|
|
1640
1640
|
constructor(message, nested) {
|
|
1641
1641
|
super(message);
|
|
1642
1642
|
Error.captureStackTrace(this, NestedError);
|
|
1643
|
+
this.name = NestedError.name;
|
|
1643
1644
|
if (nested && nested.stack) {
|
|
1644
1645
|
this.stack += `\nCaused by: ${nested.stack}`;
|
|
1645
1646
|
}
|
|
@@ -1650,6 +1651,44 @@ class NestedError extends Error {
|
|
|
1650
1651
|
* @public
|
|
1651
1652
|
*/
|
|
1652
1653
|
class UserError extends NestedError {
|
|
1654
|
+
constructor(message, nested) {
|
|
1655
|
+
super(message, nested);
|
|
1656
|
+
Error.captureStackTrace(this, UserError);
|
|
1657
|
+
this.name = UserError.name;
|
|
1658
|
+
}
|
|
1659
|
+
prettyFormat() {
|
|
1660
|
+
return undefined;
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
/**
|
|
1665
|
+
* @internal
|
|
1666
|
+
*/
|
|
1667
|
+
class InheritError extends UserError {
|
|
1668
|
+
constructor({ tagName, inherit }) {
|
|
1669
|
+
const message = `Element <${tagName}> cannot inherit from <${inherit}>: no such element`;
|
|
1670
|
+
super(message);
|
|
1671
|
+
Error.captureStackTrace(this, InheritError);
|
|
1672
|
+
this.name = InheritError.name;
|
|
1673
|
+
this.tagName = tagName;
|
|
1674
|
+
this.inherit = inherit;
|
|
1675
|
+
this.filename = null;
|
|
1676
|
+
}
|
|
1677
|
+
prettyFormat() {
|
|
1678
|
+
const { message, tagName, inherit } = this;
|
|
1679
|
+
const source = this.filename
|
|
1680
|
+
? ["", "This error occurred when loading element metadata from:", `"${this.filename}"`, ""]
|
|
1681
|
+
: [""];
|
|
1682
|
+
return [
|
|
1683
|
+
message,
|
|
1684
|
+
...source,
|
|
1685
|
+
"This usually occurs when the elements are defined in the wrong order, try one of the following:",
|
|
1686
|
+
"",
|
|
1687
|
+
` - Ensure the spelling of "${inherit}" is correct.`,
|
|
1688
|
+
` - Ensure the file containing "${inherit}" is loaded before the file containing "${tagName}".`,
|
|
1689
|
+
` - Move the definition of "${inherit}" above the definition for "${tagName}".`,
|
|
1690
|
+
].join("\n");
|
|
1691
|
+
}
|
|
1653
1692
|
}
|
|
1654
1693
|
|
|
1655
1694
|
function getSummary(schema, obj, errors) {
|
|
@@ -2073,6 +2112,9 @@ const definitions = {
|
|
|
2073
2112
|
items: {
|
|
2074
2113
|
type: "string"
|
|
2075
2114
|
}
|
|
2115
|
+
},
|
|
2116
|
+
{
|
|
2117
|
+
type: "null"
|
|
2076
2118
|
}
|
|
2077
2119
|
]
|
|
2078
2120
|
}
|
|
@@ -2383,6 +2425,10 @@ class MetaTable {
|
|
|
2383
2425
|
this.loadFromObject(data, filename);
|
|
2384
2426
|
}
|
|
2385
2427
|
catch (err) {
|
|
2428
|
+
if (err instanceof InheritError) {
|
|
2429
|
+
err.filename = filename;
|
|
2430
|
+
throw err;
|
|
2431
|
+
}
|
|
2386
2432
|
if (err instanceof SchemaValidationError) {
|
|
2387
2433
|
throw err;
|
|
2388
2434
|
}
|
|
@@ -2435,7 +2481,10 @@ class MetaTable {
|
|
|
2435
2481
|
const name = entry.inherit;
|
|
2436
2482
|
parent = this.elements[name];
|
|
2437
2483
|
if (!parent) {
|
|
2438
|
-
throw new
|
|
2484
|
+
throw new InheritError({
|
|
2485
|
+
tagName,
|
|
2486
|
+
inherit: name,
|
|
2487
|
+
});
|
|
2439
2488
|
}
|
|
2440
2489
|
}
|
|
2441
2490
|
/* merge all sources together */
|
|
@@ -2614,29 +2663,40 @@ class Validator {
|
|
|
2614
2663
|
*
|
|
2615
2664
|
* For instance, a `<table>` element can only contain a single `<tbody>`
|
|
2616
2665
|
* child. If multiple `<tbody>` exists this test will fail both nodes.
|
|
2666
|
+
* Note that this is called on the parent but will fail the children violating
|
|
2667
|
+
* the rule.
|
|
2617
2668
|
*
|
|
2618
|
-
* @param
|
|
2619
|
-
* @param rules - List of rules.
|
|
2620
|
-
* @
|
|
2621
|
-
* exists (including the element itself)
|
|
2622
|
-
* @returns `true` if the element passes the test.
|
|
2669
|
+
* @param children - Array of children to validate.
|
|
2670
|
+
* @param rules - List of rules of the parent element.
|
|
2671
|
+
* @returns `true` if the parent element of the children passes the test.
|
|
2623
2672
|
*/
|
|
2624
|
-
static validateOccurrences(
|
|
2673
|
+
static validateOccurrences(children, rules, cb) {
|
|
2625
2674
|
if (!rules) {
|
|
2626
2675
|
return true;
|
|
2627
2676
|
}
|
|
2628
|
-
|
|
2677
|
+
let valid = true;
|
|
2678
|
+
for (const rule of rules) {
|
|
2629
2679
|
/** @todo handle complex rules and not just plain arrays (but as of now
|
|
2630
2680
|
* there is no use-case for it) */
|
|
2631
2681
|
// istanbul ignore next
|
|
2632
|
-
if (typeof
|
|
2682
|
+
if (typeof rule !== "string") {
|
|
2633
2683
|
return false;
|
|
2634
2684
|
}
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2685
|
+
// Check if the rule has a quantifier
|
|
2686
|
+
const [, category, quantifier] = rule.match(/^(@?.*?)([?*]?)$/);
|
|
2687
|
+
const limit = category && quantifier && parseQuantifier(quantifier);
|
|
2688
|
+
if (limit) {
|
|
2689
|
+
const siblings = children.filter((cur) => Validator.validatePermittedCategory(cur, rule, true));
|
|
2690
|
+
if (siblings.length > limit) {
|
|
2691
|
+
// fail only the children above the limit (currently limit can only be 1)
|
|
2692
|
+
for (const child of siblings.slice(limit)) {
|
|
2693
|
+
cb(child, category);
|
|
2694
|
+
}
|
|
2695
|
+
valid = false;
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
return valid;
|
|
2640
2700
|
}
|
|
2641
2701
|
/**
|
|
2642
2702
|
* Validate elements order.
|
|
@@ -2698,14 +2758,15 @@ class Validator {
|
|
|
2698
2758
|
* Check if an element has the required set of elements. At least one of the
|
|
2699
2759
|
* selectors must match.
|
|
2700
2760
|
*
|
|
2701
|
-
* Returns [] when valid or a list of
|
|
2761
|
+
* Returns `[]` when valid or a list of required but missing tagnames or
|
|
2762
|
+
* categories.
|
|
2702
2763
|
*/
|
|
2703
2764
|
static validateRequiredContent(node, rules) {
|
|
2704
2765
|
if (!rules || rules.length === 0) {
|
|
2705
2766
|
return [];
|
|
2706
2767
|
}
|
|
2707
2768
|
return rules.filter((tagName) => {
|
|
2708
|
-
const haveMatchingChild = node.childElements.some((child) =>
|
|
2769
|
+
const haveMatchingChild = node.childElements.some((child) => Validator.validatePermittedCategory(child, tagName, false));
|
|
2709
2770
|
return !haveMatchingChild;
|
|
2710
2771
|
});
|
|
2711
2772
|
}
|
|
@@ -2809,16 +2870,16 @@ class Validator {
|
|
|
2809
2870
|
*/
|
|
2810
2871
|
// eslint-disable-next-line complexity
|
|
2811
2872
|
static validatePermittedCategory(node, category, defaultMatch) {
|
|
2873
|
+
const [, rawCategory] = category.match(/^(@?.*?)([?*]?)$/);
|
|
2812
2874
|
/* match tagName when an explicit name is given */
|
|
2813
|
-
if (
|
|
2814
|
-
|
|
2815
|
-
return node.tagName === tagName;
|
|
2875
|
+
if (rawCategory[0] !== "@") {
|
|
2876
|
+
return node.tagName === rawCategory;
|
|
2816
2877
|
}
|
|
2817
2878
|
/* if the meta entry is missing assume any content model would match */
|
|
2818
2879
|
if (!node.meta) {
|
|
2819
2880
|
return defaultMatch;
|
|
2820
2881
|
}
|
|
2821
|
-
switch (
|
|
2882
|
+
switch (rawCategory) {
|
|
2822
2883
|
case "@meta":
|
|
2823
2884
|
return node.meta.metadata;
|
|
2824
2885
|
case "@flow":
|
|
@@ -2850,23 +2911,15 @@ function validateKeys(rule) {
|
|
|
2850
2911
|
}
|
|
2851
2912
|
}
|
|
2852
2913
|
}
|
|
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) {
|
|
2914
|
+
function parseQuantifier(quantifier) {
|
|
2915
|
+
switch (quantifier) {
|
|
2861
2916
|
case "?":
|
|
2862
2917
|
return 1;
|
|
2863
|
-
case "":
|
|
2864
|
-
return null;
|
|
2865
2918
|
case "*":
|
|
2866
2919
|
return null;
|
|
2867
|
-
|
|
2920
|
+
// istanbul ignore next
|
|
2868
2921
|
default:
|
|
2869
|
-
throw new Error(`Invalid
|
|
2922
|
+
throw new Error(`Invalid quantifier "${quantifier}" used`);
|
|
2870
2923
|
}
|
|
2871
2924
|
}
|
|
2872
2925
|
|
|
@@ -3398,16 +3451,7 @@ class Rule {
|
|
|
3398
3451
|
* `exclude`.
|
|
3399
3452
|
*/
|
|
3400
3453
|
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;
|
|
3454
|
+
return isKeywordIgnored(this.options, keyword, matcher);
|
|
3411
3455
|
}
|
|
3412
3456
|
/**
|
|
3413
3457
|
* Find all tags which has enabled given property.
|
|
@@ -3533,7 +3577,7 @@ class Rule {
|
|
|
3533
3577
|
}
|
|
3534
3578
|
}
|
|
3535
3579
|
|
|
3536
|
-
const defaults$
|
|
3580
|
+
const defaults$v = {
|
|
3537
3581
|
allowExternal: true,
|
|
3538
3582
|
allowRelative: true,
|
|
3539
3583
|
allowAbsolute: true,
|
|
@@ -3577,7 +3621,7 @@ function matchList(value, list) {
|
|
|
3577
3621
|
}
|
|
3578
3622
|
class AllowedLinks extends Rule {
|
|
3579
3623
|
constructor(options) {
|
|
3580
|
-
super({ ...defaults$
|
|
3624
|
+
super({ ...defaults$v, ...options });
|
|
3581
3625
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
3582
3626
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
3583
3627
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -3725,7 +3769,7 @@ var RuleContext$1;
|
|
|
3725
3769
|
RuleContext["MISSING_ALT"] = "missing-alt";
|
|
3726
3770
|
RuleContext["MISSING_HREF"] = "missing-href";
|
|
3727
3771
|
})(RuleContext$1 || (RuleContext$1 = {}));
|
|
3728
|
-
const defaults$
|
|
3772
|
+
const defaults$u = {
|
|
3729
3773
|
accessible: true,
|
|
3730
3774
|
};
|
|
3731
3775
|
function findByTarget(target, siblings) {
|
|
@@ -3763,7 +3807,7 @@ function getDescription$1(context) {
|
|
|
3763
3807
|
}
|
|
3764
3808
|
class AreaAlt extends Rule {
|
|
3765
3809
|
constructor(options) {
|
|
3766
|
-
super({ ...defaults$
|
|
3810
|
+
super({ ...defaults$u, ...options });
|
|
3767
3811
|
}
|
|
3768
3812
|
static schema() {
|
|
3769
3813
|
return {
|
|
@@ -3925,15 +3969,20 @@ class AriaLabelMisuse extends Rule {
|
|
|
3925
3969
|
* @public
|
|
3926
3970
|
*/
|
|
3927
3971
|
class ConfigError extends UserError {
|
|
3972
|
+
constructor(message, nested) {
|
|
3973
|
+
super(message, nested);
|
|
3974
|
+
Error.captureStackTrace(this, ConfigError);
|
|
3975
|
+
this.name = ConfigError.name;
|
|
3976
|
+
}
|
|
3928
3977
|
}
|
|
3929
3978
|
|
|
3930
|
-
const defaults$
|
|
3979
|
+
const defaults$t = {
|
|
3931
3980
|
style: "lowercase",
|
|
3932
3981
|
ignoreForeign: true,
|
|
3933
3982
|
};
|
|
3934
3983
|
class AttrCase extends Rule {
|
|
3935
3984
|
constructor(options) {
|
|
3936
|
-
super({ ...defaults$
|
|
3985
|
+
super({ ...defaults$t, ...options });
|
|
3937
3986
|
this.style = new CaseStyle(this.options.style, "attr-case");
|
|
3938
3987
|
}
|
|
3939
3988
|
static schema() {
|
|
@@ -4278,7 +4327,7 @@ class AttrDelimiter extends Rule {
|
|
|
4278
4327
|
}
|
|
4279
4328
|
|
|
4280
4329
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
4281
|
-
const defaults$
|
|
4330
|
+
const defaults$s = {
|
|
4282
4331
|
pattern: DEFAULT_PATTERN,
|
|
4283
4332
|
ignoreForeign: true,
|
|
4284
4333
|
};
|
|
@@ -4315,7 +4364,7 @@ function generateDescription(name, pattern) {
|
|
|
4315
4364
|
}
|
|
4316
4365
|
class AttrPattern extends Rule {
|
|
4317
4366
|
constructor(options) {
|
|
4318
|
-
super({ ...defaults$
|
|
4367
|
+
super({ ...defaults$s, ...options });
|
|
4319
4368
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4320
4369
|
}
|
|
4321
4370
|
static schema() {
|
|
@@ -4376,7 +4425,7 @@ var QuoteStyle;
|
|
|
4376
4425
|
QuoteStyle["AUTO_QUOTE"] = "auto";
|
|
4377
4426
|
QuoteStyle["ANY_QUOTE"] = "any";
|
|
4378
4427
|
})(QuoteStyle || (QuoteStyle = {}));
|
|
4379
|
-
const defaults$
|
|
4428
|
+
const defaults$r = {
|
|
4380
4429
|
style: "auto",
|
|
4381
4430
|
unquoted: false,
|
|
4382
4431
|
};
|
|
@@ -4443,7 +4492,7 @@ class AttrQuotes extends Rule {
|
|
|
4443
4492
|
};
|
|
4444
4493
|
}
|
|
4445
4494
|
constructor(options) {
|
|
4446
|
-
super({ ...defaults$
|
|
4495
|
+
super({ ...defaults$r, ...options });
|
|
4447
4496
|
this.style = parseStyle$4(this.options.style);
|
|
4448
4497
|
}
|
|
4449
4498
|
setup() {
|
|
@@ -4613,12 +4662,12 @@ class AttributeAllowedValues extends Rule {
|
|
|
4613
4662
|
}
|
|
4614
4663
|
}
|
|
4615
4664
|
|
|
4616
|
-
const defaults$
|
|
4665
|
+
const defaults$q = {
|
|
4617
4666
|
style: "omit",
|
|
4618
4667
|
};
|
|
4619
4668
|
class AttributeBooleanStyle extends Rule {
|
|
4620
4669
|
constructor(options) {
|
|
4621
|
-
super({ ...defaults$
|
|
4670
|
+
super({ ...defaults$q, ...options });
|
|
4622
4671
|
this.hasInvalidStyle = parseStyle$3(this.options.style);
|
|
4623
4672
|
}
|
|
4624
4673
|
static schema() {
|
|
@@ -4694,12 +4743,12 @@ function reportMessage$1(attr, style) {
|
|
|
4694
4743
|
return "";
|
|
4695
4744
|
}
|
|
4696
4745
|
|
|
4697
|
-
const defaults$
|
|
4746
|
+
const defaults$p = {
|
|
4698
4747
|
style: "omit",
|
|
4699
4748
|
};
|
|
4700
4749
|
class AttributeEmptyStyle extends Rule {
|
|
4701
4750
|
constructor(options) {
|
|
4702
|
-
super({ ...defaults$
|
|
4751
|
+
super({ ...defaults$p, ...options });
|
|
4703
4752
|
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
4704
4753
|
}
|
|
4705
4754
|
static schema() {
|
|
@@ -4855,12 +4904,12 @@ function describePattern(pattern) {
|
|
|
4855
4904
|
}
|
|
4856
4905
|
}
|
|
4857
4906
|
|
|
4858
|
-
const defaults$
|
|
4907
|
+
const defaults$o = {
|
|
4859
4908
|
pattern: "kebabcase",
|
|
4860
4909
|
};
|
|
4861
4910
|
class ClassPattern extends Rule {
|
|
4862
4911
|
constructor(options) {
|
|
4863
|
-
super({ ...defaults$
|
|
4912
|
+
super({ ...defaults$o, ...options });
|
|
4864
4913
|
this.pattern = parsePattern(this.options.pattern);
|
|
4865
4914
|
}
|
|
4866
4915
|
static schema() {
|
|
@@ -4969,13 +5018,13 @@ class CloseOrder extends Rule {
|
|
|
4969
5018
|
}
|
|
4970
5019
|
}
|
|
4971
5020
|
|
|
4972
|
-
const defaults$
|
|
5021
|
+
const defaults$n = {
|
|
4973
5022
|
include: null,
|
|
4974
5023
|
exclude: null,
|
|
4975
5024
|
};
|
|
4976
5025
|
class Deprecated extends Rule {
|
|
4977
5026
|
constructor(options) {
|
|
4978
|
-
super({ ...defaults$
|
|
5027
|
+
super({ ...defaults$n, ...options });
|
|
4979
5028
|
}
|
|
4980
5029
|
static schema() {
|
|
4981
5030
|
return {
|
|
@@ -5138,12 +5187,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
|
|
|
5138
5187
|
}
|
|
5139
5188
|
};
|
|
5140
5189
|
|
|
5141
|
-
const defaults$
|
|
5190
|
+
const defaults$m = {
|
|
5142
5191
|
style: "uppercase",
|
|
5143
5192
|
};
|
|
5144
5193
|
class DoctypeStyle extends Rule {
|
|
5145
5194
|
constructor(options) {
|
|
5146
|
-
super({ ...defaults$
|
|
5195
|
+
super({ ...defaults$m, ...options });
|
|
5147
5196
|
}
|
|
5148
5197
|
static schema() {
|
|
5149
5198
|
return {
|
|
@@ -5175,12 +5224,12 @@ class DoctypeStyle extends Rule {
|
|
|
5175
5224
|
}
|
|
5176
5225
|
}
|
|
5177
5226
|
|
|
5178
|
-
const defaults$
|
|
5227
|
+
const defaults$l = {
|
|
5179
5228
|
style: "lowercase",
|
|
5180
5229
|
};
|
|
5181
5230
|
class ElementCase extends Rule {
|
|
5182
5231
|
constructor(options) {
|
|
5183
|
-
super({ ...defaults$
|
|
5232
|
+
super({ ...defaults$l, ...options });
|
|
5184
5233
|
this.style = new CaseStyle(this.options.style, "element-case");
|
|
5185
5234
|
}
|
|
5186
5235
|
static schema() {
|
|
@@ -5246,14 +5295,14 @@ class ElementCase extends Rule {
|
|
|
5246
5295
|
}
|
|
5247
5296
|
}
|
|
5248
5297
|
|
|
5249
|
-
const defaults$
|
|
5298
|
+
const defaults$k = {
|
|
5250
5299
|
pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
|
|
5251
5300
|
whitelist: [],
|
|
5252
5301
|
blacklist: [],
|
|
5253
5302
|
};
|
|
5254
5303
|
class ElementName extends Rule {
|
|
5255
5304
|
constructor(options) {
|
|
5256
|
-
super({ ...defaults$
|
|
5305
|
+
super({ ...defaults$k, ...options });
|
|
5257
5306
|
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
5258
5307
|
this.pattern = new RegExp(this.options.pattern);
|
|
5259
5308
|
}
|
|
@@ -5294,7 +5343,7 @@ class ElementName extends Rule {
|
|
|
5294
5343
|
...context.blacklist.map((cur) => `- ${cur}`),
|
|
5295
5344
|
];
|
|
5296
5345
|
}
|
|
5297
|
-
if (context.pattern !== defaults$
|
|
5346
|
+
if (context.pattern !== defaults$k.pattern) {
|
|
5298
5347
|
return [
|
|
5299
5348
|
`<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
|
|
5300
5349
|
"",
|
|
@@ -5485,24 +5534,16 @@ class ElementPermittedOccurrences extends Rule {
|
|
|
5485
5534
|
this.on("dom:ready", (event) => {
|
|
5486
5535
|
const doc = event.document;
|
|
5487
5536
|
doc.visitDepthFirst((node) => {
|
|
5488
|
-
|
|
5489
|
-
if (!parent || !parent.meta) {
|
|
5537
|
+
if (!node || !node.meta) {
|
|
5490
5538
|
return;
|
|
5491
5539
|
}
|
|
5492
|
-
const rules =
|
|
5540
|
+
const rules = node.meta.permittedContent;
|
|
5493
5541
|
if (!rules) {
|
|
5494
5542
|
return;
|
|
5495
5543
|
}
|
|
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
|
-
}
|
|
5544
|
+
Validator.validateOccurrences(node.childElements, rules, (child, category) => {
|
|
5545
|
+
this.report(child, `Element <${category}> can only appear once under ${node.annotatedName}`);
|
|
5546
|
+
});
|
|
5506
5547
|
});
|
|
5507
5548
|
});
|
|
5508
5549
|
}
|
|
@@ -5537,11 +5578,11 @@ class ElementPermittedOrder extends Rule {
|
|
|
5537
5578
|
function isCategoryOrTag(value) {
|
|
5538
5579
|
return typeof value === "string";
|
|
5539
5580
|
}
|
|
5540
|
-
function isCategory(value) {
|
|
5581
|
+
function isCategory$1(value) {
|
|
5541
5582
|
return value[0] === "@";
|
|
5542
5583
|
}
|
|
5543
5584
|
function formatCategoryOrTag(value) {
|
|
5544
|
-
return isCategory(value) ? value.slice(1) : `<${value}>`;
|
|
5585
|
+
return isCategory$1(value) ? value.slice(1) : `<${value}>`;
|
|
5545
5586
|
}
|
|
5546
5587
|
function isFormattable(rules) {
|
|
5547
5588
|
return rules.length > 0 && rules.every(isCategoryOrTag);
|
|
@@ -5554,7 +5595,7 @@ function getRuleDescription$1(context) {
|
|
|
5554
5595
|
const preamble = `The \`${child}\` element cannot have a \`${parent}\` element as parent.`;
|
|
5555
5596
|
if (isFormattable(rules)) {
|
|
5556
5597
|
const allowed = rules.filter(isCategoryOrTag).map((it) => {
|
|
5557
|
-
if (isCategory(it)) {
|
|
5598
|
+
if (isCategory$1(it)) {
|
|
5558
5599
|
return `- any ${it.slice(1)} element`;
|
|
5559
5600
|
}
|
|
5560
5601
|
else {
|
|
@@ -5717,6 +5758,9 @@ class ElementRequiredAttributes extends Rule {
|
|
|
5717
5758
|
}
|
|
5718
5759
|
}
|
|
5719
5760
|
|
|
5761
|
+
function isCategory(value) {
|
|
5762
|
+
return value[0] === "@";
|
|
5763
|
+
}
|
|
5720
5764
|
class ElementRequiredContent extends Rule {
|
|
5721
5765
|
documentation(context) {
|
|
5722
5766
|
if (context) {
|
|
@@ -5751,7 +5795,8 @@ class ElementRequiredContent extends Rule {
|
|
|
5751
5795
|
element: node.annotatedName,
|
|
5752
5796
|
missing: `<${missing}>`,
|
|
5753
5797
|
};
|
|
5754
|
-
const
|
|
5798
|
+
const tag = isCategory(missing) ? `${missing.slice(1)} element` : `<${missing}>`;
|
|
5799
|
+
const message = `${node.annotatedName} element must have ${tag} as content`;
|
|
5755
5800
|
this.report(node, message, null, context);
|
|
5756
5801
|
}
|
|
5757
5802
|
});
|
|
@@ -5842,7 +5887,7 @@ class EmptyTitle extends Rule {
|
|
|
5842
5887
|
}
|
|
5843
5888
|
}
|
|
5844
5889
|
|
|
5845
|
-
const defaults$
|
|
5890
|
+
const defaults$j = {
|
|
5846
5891
|
allowMultipleH1: false,
|
|
5847
5892
|
minInitialRank: "h1",
|
|
5848
5893
|
sectioningRoots: ["dialog", '[role="dialog"]'],
|
|
@@ -5873,7 +5918,7 @@ function parseMaxInitial(value) {
|
|
|
5873
5918
|
}
|
|
5874
5919
|
class HeadingLevel extends Rule {
|
|
5875
5920
|
constructor(options) {
|
|
5876
|
-
super({ ...defaults$
|
|
5921
|
+
super({ ...defaults$j, ...options });
|
|
5877
5922
|
this.stack = [];
|
|
5878
5923
|
this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
|
|
5879
5924
|
this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
|
|
@@ -6031,12 +6076,12 @@ class HeadingLevel extends Rule {
|
|
|
6031
6076
|
}
|
|
6032
6077
|
}
|
|
6033
6078
|
|
|
6034
|
-
const defaults$
|
|
6079
|
+
const defaults$i = {
|
|
6035
6080
|
pattern: "kebabcase",
|
|
6036
6081
|
};
|
|
6037
6082
|
class IdPattern extends Rule {
|
|
6038
6083
|
constructor(options) {
|
|
6039
|
-
super({ ...defaults$
|
|
6084
|
+
super({ ...defaults$i, ...options });
|
|
6040
6085
|
this.pattern = parsePattern(this.options.pattern);
|
|
6041
6086
|
}
|
|
6042
6087
|
static schema() {
|
|
@@ -6318,12 +6363,12 @@ function findLabelByParent(el) {
|
|
|
6318
6363
|
return [];
|
|
6319
6364
|
}
|
|
6320
6365
|
|
|
6321
|
-
const defaults$
|
|
6366
|
+
const defaults$h = {
|
|
6322
6367
|
maxlength: 70,
|
|
6323
6368
|
};
|
|
6324
6369
|
class LongTitle extends Rule {
|
|
6325
6370
|
constructor(options) {
|
|
6326
|
-
super({ ...defaults$
|
|
6371
|
+
super({ ...defaults$h, ...options });
|
|
6327
6372
|
this.maxlength = this.options.maxlength;
|
|
6328
6373
|
}
|
|
6329
6374
|
static schema() {
|
|
@@ -6513,13 +6558,13 @@ class MultipleLabeledControls extends Rule {
|
|
|
6513
6558
|
}
|
|
6514
6559
|
}
|
|
6515
6560
|
|
|
6516
|
-
const defaults$
|
|
6561
|
+
const defaults$g = {
|
|
6517
6562
|
include: null,
|
|
6518
6563
|
exclude: null,
|
|
6519
6564
|
};
|
|
6520
6565
|
class NoAutoplay extends Rule {
|
|
6521
6566
|
constructor(options) {
|
|
6522
|
-
super({ ...defaults$
|
|
6567
|
+
super({ ...defaults$g, ...options });
|
|
6523
6568
|
}
|
|
6524
6569
|
documentation(context) {
|
|
6525
6570
|
const tagName = context ? ` on <${context.tagName}>` : "";
|
|
@@ -6760,14 +6805,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
6760
6805
|
}
|
|
6761
6806
|
}
|
|
6762
6807
|
|
|
6763
|
-
const defaults$
|
|
6808
|
+
const defaults$f = {
|
|
6764
6809
|
include: null,
|
|
6765
6810
|
exclude: null,
|
|
6766
6811
|
allowedProperties: ["display"],
|
|
6767
6812
|
};
|
|
6768
6813
|
class NoInlineStyle extends Rule {
|
|
6769
6814
|
constructor(options) {
|
|
6770
|
-
super({ ...defaults$
|
|
6815
|
+
super({ ...defaults$f, ...options });
|
|
6771
6816
|
}
|
|
6772
6817
|
static schema() {
|
|
6773
6818
|
return {
|
|
@@ -6969,7 +7014,7 @@ class NoMultipleMain extends Rule {
|
|
|
6969
7014
|
}
|
|
6970
7015
|
}
|
|
6971
7016
|
|
|
6972
|
-
const defaults$
|
|
7017
|
+
const defaults$e = {
|
|
6973
7018
|
relaxed: false,
|
|
6974
7019
|
};
|
|
6975
7020
|
const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
|
|
@@ -6986,7 +7031,7 @@ const replacementTable = {
|
|
|
6986
7031
|
};
|
|
6987
7032
|
class NoRawCharacters extends Rule {
|
|
6988
7033
|
constructor(options) {
|
|
6989
|
-
super({ ...defaults$
|
|
7034
|
+
super({ ...defaults$e, ...options });
|
|
6990
7035
|
this.relaxed = this.options.relaxed;
|
|
6991
7036
|
}
|
|
6992
7037
|
static schema() {
|
|
@@ -7164,13 +7209,13 @@ class NoRedundantRole extends Rule {
|
|
|
7164
7209
|
}
|
|
7165
7210
|
|
|
7166
7211
|
const xmlns = /^(.+):.+$/;
|
|
7167
|
-
const defaults$
|
|
7212
|
+
const defaults$d = {
|
|
7168
7213
|
ignoreForeign: true,
|
|
7169
7214
|
ignoreXML: true,
|
|
7170
7215
|
};
|
|
7171
7216
|
class NoSelfClosing extends Rule {
|
|
7172
7217
|
constructor(options) {
|
|
7173
|
-
super({ ...defaults$
|
|
7218
|
+
super({ ...defaults$d, ...options });
|
|
7174
7219
|
}
|
|
7175
7220
|
static schema() {
|
|
7176
7221
|
return {
|
|
@@ -7259,7 +7304,44 @@ class NoTrailingWhitespace extends Rule {
|
|
|
7259
7304
|
}
|
|
7260
7305
|
}
|
|
7261
7306
|
|
|
7307
|
+
const defaults$c = {
|
|
7308
|
+
include: null,
|
|
7309
|
+
exclude: null,
|
|
7310
|
+
};
|
|
7262
7311
|
class NoUnknownElements extends Rule {
|
|
7312
|
+
constructor(options) {
|
|
7313
|
+
super({ ...defaults$c, ...options });
|
|
7314
|
+
}
|
|
7315
|
+
static schema() {
|
|
7316
|
+
return {
|
|
7317
|
+
exclude: {
|
|
7318
|
+
anyOf: [
|
|
7319
|
+
{
|
|
7320
|
+
items: {
|
|
7321
|
+
type: "string",
|
|
7322
|
+
},
|
|
7323
|
+
type: "array",
|
|
7324
|
+
},
|
|
7325
|
+
{
|
|
7326
|
+
type: "null",
|
|
7327
|
+
},
|
|
7328
|
+
],
|
|
7329
|
+
},
|
|
7330
|
+
include: {
|
|
7331
|
+
anyOf: [
|
|
7332
|
+
{
|
|
7333
|
+
items: {
|
|
7334
|
+
type: "string",
|
|
7335
|
+
},
|
|
7336
|
+
type: "array",
|
|
7337
|
+
},
|
|
7338
|
+
{
|
|
7339
|
+
type: "null",
|
|
7340
|
+
},
|
|
7341
|
+
],
|
|
7342
|
+
},
|
|
7343
|
+
};
|
|
7344
|
+
}
|
|
7263
7345
|
documentation(context) {
|
|
7264
7346
|
const element = context ? ` <${context}>` : "";
|
|
7265
7347
|
return {
|
|
@@ -7270,9 +7352,13 @@ class NoUnknownElements extends Rule {
|
|
|
7270
7352
|
setup() {
|
|
7271
7353
|
this.on("tag:start", (event) => {
|
|
7272
7354
|
const node = event.target;
|
|
7273
|
-
if (
|
|
7274
|
-
|
|
7355
|
+
if (node.meta) {
|
|
7356
|
+
return;
|
|
7275
7357
|
}
|
|
7358
|
+
if (this.isKeywordIgnored(node.tagName, keywordPatternMatcher)) {
|
|
7359
|
+
return;
|
|
7360
|
+
}
|
|
7361
|
+
this.report(node, `Unknown element <${node.tagName}>`, null, node.tagName);
|
|
7276
7362
|
});
|
|
7277
7363
|
}
|
|
7278
7364
|
}
|
|
@@ -8734,6 +8820,11 @@ class H37 extends Rule {
|
|
|
8734
8820
|
}
|
|
8735
8821
|
}
|
|
8736
8822
|
|
|
8823
|
+
var _a;
|
|
8824
|
+
/* istanbul ignore next: this will always be present for the <th>
|
|
8825
|
+
* attribute (or the tests would fail) */
|
|
8826
|
+
const { enum: validScopes } = (_a = html5.th.attributes) === null || _a === void 0 ? void 0 : _a.scope;
|
|
8827
|
+
const joinedScopes = naturalJoin(validScopes);
|
|
8737
8828
|
class H63 extends Rule {
|
|
8738
8829
|
documentation() {
|
|
8739
8830
|
return {
|
|
@@ -8743,19 +8834,25 @@ class H63 extends Rule {
|
|
|
8743
8834
|
}
|
|
8744
8835
|
setup() {
|
|
8745
8836
|
this.on("tag:ready", (event) => {
|
|
8746
|
-
var _a, _b
|
|
8837
|
+
var _a, _b;
|
|
8747
8838
|
const node = event.target;
|
|
8748
8839
|
/* only validate th */
|
|
8749
8840
|
if (!node || node.tagName !== "th") {
|
|
8750
8841
|
return;
|
|
8751
8842
|
}
|
|
8843
|
+
const scope = node.getAttribute("scope");
|
|
8844
|
+
const value = scope === null || scope === void 0 ? void 0 : scope.value;
|
|
8845
|
+
/* ignore dynamic scope */
|
|
8846
|
+
if (value instanceof DynamicValue) {
|
|
8847
|
+
return;
|
|
8848
|
+
}
|
|
8752
8849
|
/* 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))) {
|
|
8850
|
+
if (value && validScopes.includes(value)) {
|
|
8756
8851
|
return;
|
|
8757
8852
|
}
|
|
8758
|
-
|
|
8853
|
+
const message = `<th> element must have a valid scope attribute: ${joinedScopes}`;
|
|
8854
|
+
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;
|
|
8855
|
+
this.report(node, message, location);
|
|
8759
8856
|
});
|
|
8760
8857
|
}
|
|
8761
8858
|
}
|
|
@@ -11126,7 +11223,7 @@ class HtmlValidate {
|
|
|
11126
11223
|
/** @public */
|
|
11127
11224
|
const name = "html-validate";
|
|
11128
11225
|
/** @public */
|
|
11129
|
-
const version = "7.
|
|
11226
|
+
const version = "7.11.1";
|
|
11130
11227
|
/** @public */
|
|
11131
11228
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11132
11229
|
|