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/cjs/core.js
CHANGED
|
@@ -7,10 +7,10 @@ var Ajv = require('ajv');
|
|
|
7
7
|
var deepmerge = require('deepmerge');
|
|
8
8
|
var espree = require('espree');
|
|
9
9
|
var walk = require('acorn-walk');
|
|
10
|
-
var elements = require('./elements.js');
|
|
11
10
|
var path = require('path');
|
|
12
11
|
var semver = require('semver');
|
|
13
12
|
var kleur = require('kleur');
|
|
13
|
+
var elements = require('./elements.js');
|
|
14
14
|
var codeFrame = require('@babel/code-frame');
|
|
15
15
|
var stylishImpl = require('@html-validate/stylish');
|
|
16
16
|
|
|
@@ -1672,6 +1672,7 @@ class NestedError extends Error {
|
|
|
1672
1672
|
constructor(message, nested) {
|
|
1673
1673
|
super(message);
|
|
1674
1674
|
Error.captureStackTrace(this, NestedError);
|
|
1675
|
+
this.name = NestedError.name;
|
|
1675
1676
|
if (nested && nested.stack) {
|
|
1676
1677
|
this.stack += `\nCaused by: ${nested.stack}`;
|
|
1677
1678
|
}
|
|
@@ -1682,6 +1683,44 @@ class NestedError extends Error {
|
|
|
1682
1683
|
* @public
|
|
1683
1684
|
*/
|
|
1684
1685
|
class UserError extends NestedError {
|
|
1686
|
+
constructor(message, nested) {
|
|
1687
|
+
super(message, nested);
|
|
1688
|
+
Error.captureStackTrace(this, UserError);
|
|
1689
|
+
this.name = UserError.name;
|
|
1690
|
+
}
|
|
1691
|
+
prettyFormat() {
|
|
1692
|
+
return undefined;
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
/**
|
|
1697
|
+
* @internal
|
|
1698
|
+
*/
|
|
1699
|
+
class InheritError extends UserError {
|
|
1700
|
+
constructor({ tagName, inherit }) {
|
|
1701
|
+
const message = `Element <${tagName}> cannot inherit from <${inherit}>: no such element`;
|
|
1702
|
+
super(message);
|
|
1703
|
+
Error.captureStackTrace(this, InheritError);
|
|
1704
|
+
this.name = InheritError.name;
|
|
1705
|
+
this.tagName = tagName;
|
|
1706
|
+
this.inherit = inherit;
|
|
1707
|
+
this.filename = null;
|
|
1708
|
+
}
|
|
1709
|
+
prettyFormat() {
|
|
1710
|
+
const { message, tagName, inherit } = this;
|
|
1711
|
+
const source = this.filename
|
|
1712
|
+
? ["", "This error occurred when loading element metadata from:", `"${this.filename}"`, ""]
|
|
1713
|
+
: [""];
|
|
1714
|
+
return [
|
|
1715
|
+
message,
|
|
1716
|
+
...source,
|
|
1717
|
+
"This usually occurs when the elements are defined in the wrong order, try one of the following:",
|
|
1718
|
+
"",
|
|
1719
|
+
` - Ensure the spelling of "${inherit}" is correct.`,
|
|
1720
|
+
` - Ensure the file containing "${inherit}" is loaded before the file containing "${tagName}".`,
|
|
1721
|
+
` - Move the definition of "${inherit}" above the definition for "${tagName}".`,
|
|
1722
|
+
].join("\n");
|
|
1723
|
+
}
|
|
1685
1724
|
}
|
|
1686
1725
|
|
|
1687
1726
|
function getSummary(schema, obj, errors) {
|
|
@@ -2105,6 +2144,9 @@ const definitions = {
|
|
|
2105
2144
|
items: {
|
|
2106
2145
|
type: "string"
|
|
2107
2146
|
}
|
|
2147
|
+
},
|
|
2148
|
+
{
|
|
2149
|
+
type: "null"
|
|
2108
2150
|
}
|
|
2109
2151
|
]
|
|
2110
2152
|
}
|
|
@@ -2415,6 +2457,10 @@ class MetaTable {
|
|
|
2415
2457
|
this.loadFromObject(data, filename);
|
|
2416
2458
|
}
|
|
2417
2459
|
catch (err) {
|
|
2460
|
+
if (err instanceof InheritError) {
|
|
2461
|
+
err.filename = filename;
|
|
2462
|
+
throw err;
|
|
2463
|
+
}
|
|
2418
2464
|
if (err instanceof SchemaValidationError) {
|
|
2419
2465
|
throw err;
|
|
2420
2466
|
}
|
|
@@ -2467,7 +2513,10 @@ class MetaTable {
|
|
|
2467
2513
|
const name = entry.inherit;
|
|
2468
2514
|
parent = this.elements[name];
|
|
2469
2515
|
if (!parent) {
|
|
2470
|
-
throw new
|
|
2516
|
+
throw new InheritError({
|
|
2517
|
+
tagName,
|
|
2518
|
+
inherit: name,
|
|
2519
|
+
});
|
|
2471
2520
|
}
|
|
2472
2521
|
}
|
|
2473
2522
|
/* merge all sources together */
|
|
@@ -2646,29 +2695,40 @@ class Validator {
|
|
|
2646
2695
|
*
|
|
2647
2696
|
* For instance, a `<table>` element can only contain a single `<tbody>`
|
|
2648
2697
|
* child. If multiple `<tbody>` exists this test will fail both nodes.
|
|
2698
|
+
* Note that this is called on the parent but will fail the children violating
|
|
2699
|
+
* the rule.
|
|
2649
2700
|
*
|
|
2650
|
-
* @param
|
|
2651
|
-
* @param rules - List of rules.
|
|
2652
|
-
* @
|
|
2653
|
-
* exists (including the element itself)
|
|
2654
|
-
* @returns `true` if the element passes the test.
|
|
2701
|
+
* @param children - Array of children to validate.
|
|
2702
|
+
* @param rules - List of rules of the parent element.
|
|
2703
|
+
* @returns `true` if the parent element of the children passes the test.
|
|
2655
2704
|
*/
|
|
2656
|
-
static validateOccurrences(
|
|
2705
|
+
static validateOccurrences(children, rules, cb) {
|
|
2657
2706
|
if (!rules) {
|
|
2658
2707
|
return true;
|
|
2659
2708
|
}
|
|
2660
|
-
|
|
2709
|
+
let valid = true;
|
|
2710
|
+
for (const rule of rules) {
|
|
2661
2711
|
/** @todo handle complex rules and not just plain arrays (but as of now
|
|
2662
2712
|
* there is no use-case for it) */
|
|
2663
2713
|
// istanbul ignore next
|
|
2664
|
-
if (typeof
|
|
2714
|
+
if (typeof rule !== "string") {
|
|
2665
2715
|
return false;
|
|
2666
2716
|
}
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2717
|
+
// Check if the rule has a quantifier
|
|
2718
|
+
const [, category, quantifier] = rule.match(/^(@?.*?)([?*]?)$/);
|
|
2719
|
+
const limit = category && quantifier && parseQuantifier(quantifier);
|
|
2720
|
+
if (limit) {
|
|
2721
|
+
const siblings = children.filter((cur) => Validator.validatePermittedCategory(cur, rule, true));
|
|
2722
|
+
if (siblings.length > limit) {
|
|
2723
|
+
// fail only the children above the limit (currently limit can only be 1)
|
|
2724
|
+
for (const child of siblings.slice(limit)) {
|
|
2725
|
+
cb(child, category);
|
|
2726
|
+
}
|
|
2727
|
+
valid = false;
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
return valid;
|
|
2672
2732
|
}
|
|
2673
2733
|
/**
|
|
2674
2734
|
* Validate elements order.
|
|
@@ -2730,14 +2790,15 @@ class Validator {
|
|
|
2730
2790
|
* Check if an element has the required set of elements. At least one of the
|
|
2731
2791
|
* selectors must match.
|
|
2732
2792
|
*
|
|
2733
|
-
* Returns [] when valid or a list of
|
|
2793
|
+
* Returns `[]` when valid or a list of required but missing tagnames or
|
|
2794
|
+
* categories.
|
|
2734
2795
|
*/
|
|
2735
2796
|
static validateRequiredContent(node, rules) {
|
|
2736
2797
|
if (!rules || rules.length === 0) {
|
|
2737
2798
|
return [];
|
|
2738
2799
|
}
|
|
2739
2800
|
return rules.filter((tagName) => {
|
|
2740
|
-
const haveMatchingChild = node.childElements.some((child) =>
|
|
2801
|
+
const haveMatchingChild = node.childElements.some((child) => Validator.validatePermittedCategory(child, tagName, false));
|
|
2741
2802
|
return !haveMatchingChild;
|
|
2742
2803
|
});
|
|
2743
2804
|
}
|
|
@@ -2841,16 +2902,16 @@ class Validator {
|
|
|
2841
2902
|
*/
|
|
2842
2903
|
// eslint-disable-next-line complexity
|
|
2843
2904
|
static validatePermittedCategory(node, category, defaultMatch) {
|
|
2905
|
+
const [, rawCategory] = category.match(/^(@?.*?)([?*]?)$/);
|
|
2844
2906
|
/* match tagName when an explicit name is given */
|
|
2845
|
-
if (
|
|
2846
|
-
|
|
2847
|
-
return node.tagName === tagName;
|
|
2907
|
+
if (rawCategory[0] !== "@") {
|
|
2908
|
+
return node.tagName === rawCategory;
|
|
2848
2909
|
}
|
|
2849
2910
|
/* if the meta entry is missing assume any content model would match */
|
|
2850
2911
|
if (!node.meta) {
|
|
2851
2912
|
return defaultMatch;
|
|
2852
2913
|
}
|
|
2853
|
-
switch (
|
|
2914
|
+
switch (rawCategory) {
|
|
2854
2915
|
case "@meta":
|
|
2855
2916
|
return node.meta.metadata;
|
|
2856
2917
|
case "@flow":
|
|
@@ -2882,23 +2943,15 @@ function validateKeys(rule) {
|
|
|
2882
2943
|
}
|
|
2883
2944
|
}
|
|
2884
2945
|
}
|
|
2885
|
-
function
|
|
2886
|
-
|
|
2887
|
-
/* content not allowed, catched by another rule so just assume unlimited
|
|
2888
|
-
* usage for this purpose */
|
|
2889
|
-
return null;
|
|
2890
|
-
}
|
|
2891
|
-
const [, qualifier] = category.match(/^.*?([?*]?)$/);
|
|
2892
|
-
switch (qualifier) {
|
|
2946
|
+
function parseQuantifier(quantifier) {
|
|
2947
|
+
switch (quantifier) {
|
|
2893
2948
|
case "?":
|
|
2894
2949
|
return 1;
|
|
2895
|
-
case "":
|
|
2896
|
-
return null;
|
|
2897
2950
|
case "*":
|
|
2898
2951
|
return null;
|
|
2899
|
-
|
|
2952
|
+
// istanbul ignore next
|
|
2900
2953
|
default:
|
|
2901
|
-
throw new Error(`Invalid
|
|
2954
|
+
throw new Error(`Invalid quantifier "${quantifier}" used`);
|
|
2902
2955
|
}
|
|
2903
2956
|
}
|
|
2904
2957
|
|
|
@@ -3430,16 +3483,7 @@ class Rule {
|
|
|
3430
3483
|
* `exclude`.
|
|
3431
3484
|
*/
|
|
3432
3485
|
isKeywordIgnored(keyword, matcher = (list, it) => list.includes(it)) {
|
|
3433
|
-
|
|
3434
|
-
/* ignore keyword if not present in "include" */
|
|
3435
|
-
if (include && !matcher(include, keyword)) {
|
|
3436
|
-
return true;
|
|
3437
|
-
}
|
|
3438
|
-
/* ignore keyword if present in "excludes" */
|
|
3439
|
-
if (exclude && matcher(exclude, keyword)) {
|
|
3440
|
-
return true;
|
|
3441
|
-
}
|
|
3442
|
-
return false;
|
|
3486
|
+
return rulesHelper.isKeywordIgnored(this.options, keyword, matcher);
|
|
3443
3487
|
}
|
|
3444
3488
|
/**
|
|
3445
3489
|
* Find all tags which has enabled given property.
|
|
@@ -3565,7 +3609,7 @@ class Rule {
|
|
|
3565
3609
|
}
|
|
3566
3610
|
}
|
|
3567
3611
|
|
|
3568
|
-
const defaults$
|
|
3612
|
+
const defaults$v = {
|
|
3569
3613
|
allowExternal: true,
|
|
3570
3614
|
allowRelative: true,
|
|
3571
3615
|
allowAbsolute: true,
|
|
@@ -3609,7 +3653,7 @@ function matchList(value, list) {
|
|
|
3609
3653
|
}
|
|
3610
3654
|
class AllowedLinks extends Rule {
|
|
3611
3655
|
constructor(options) {
|
|
3612
|
-
super({ ...defaults$
|
|
3656
|
+
super({ ...defaults$v, ...options });
|
|
3613
3657
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
3614
3658
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
3615
3659
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -3757,7 +3801,7 @@ var RuleContext$1;
|
|
|
3757
3801
|
RuleContext["MISSING_ALT"] = "missing-alt";
|
|
3758
3802
|
RuleContext["MISSING_HREF"] = "missing-href";
|
|
3759
3803
|
})(RuleContext$1 || (RuleContext$1 = {}));
|
|
3760
|
-
const defaults$
|
|
3804
|
+
const defaults$u = {
|
|
3761
3805
|
accessible: true,
|
|
3762
3806
|
};
|
|
3763
3807
|
function findByTarget(target, siblings) {
|
|
@@ -3795,7 +3839,7 @@ function getDescription$1(context) {
|
|
|
3795
3839
|
}
|
|
3796
3840
|
class AreaAlt extends Rule {
|
|
3797
3841
|
constructor(options) {
|
|
3798
|
-
super({ ...defaults$
|
|
3842
|
+
super({ ...defaults$u, ...options });
|
|
3799
3843
|
}
|
|
3800
3844
|
static schema() {
|
|
3801
3845
|
return {
|
|
@@ -3957,15 +4001,20 @@ class AriaLabelMisuse extends Rule {
|
|
|
3957
4001
|
* @public
|
|
3958
4002
|
*/
|
|
3959
4003
|
class ConfigError extends UserError {
|
|
4004
|
+
constructor(message, nested) {
|
|
4005
|
+
super(message, nested);
|
|
4006
|
+
Error.captureStackTrace(this, ConfigError);
|
|
4007
|
+
this.name = ConfigError.name;
|
|
4008
|
+
}
|
|
3960
4009
|
}
|
|
3961
4010
|
|
|
3962
|
-
const defaults$
|
|
4011
|
+
const defaults$t = {
|
|
3963
4012
|
style: "lowercase",
|
|
3964
4013
|
ignoreForeign: true,
|
|
3965
4014
|
};
|
|
3966
4015
|
class AttrCase extends Rule {
|
|
3967
4016
|
constructor(options) {
|
|
3968
|
-
super({ ...defaults$
|
|
4017
|
+
super({ ...defaults$t, ...options });
|
|
3969
4018
|
this.style = new rulesHelper.CaseStyle(this.options.style, "attr-case");
|
|
3970
4019
|
}
|
|
3971
4020
|
static schema() {
|
|
@@ -4310,7 +4359,7 @@ class AttrDelimiter extends Rule {
|
|
|
4310
4359
|
}
|
|
4311
4360
|
|
|
4312
4361
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
4313
|
-
const defaults$
|
|
4362
|
+
const defaults$s = {
|
|
4314
4363
|
pattern: DEFAULT_PATTERN,
|
|
4315
4364
|
ignoreForeign: true,
|
|
4316
4365
|
};
|
|
@@ -4347,7 +4396,7 @@ function generateDescription(name, pattern) {
|
|
|
4347
4396
|
}
|
|
4348
4397
|
class AttrPattern extends Rule {
|
|
4349
4398
|
constructor(options) {
|
|
4350
|
-
super({ ...defaults$
|
|
4399
|
+
super({ ...defaults$s, ...options });
|
|
4351
4400
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4352
4401
|
}
|
|
4353
4402
|
static schema() {
|
|
@@ -4408,7 +4457,7 @@ var QuoteStyle;
|
|
|
4408
4457
|
QuoteStyle["AUTO_QUOTE"] = "auto";
|
|
4409
4458
|
QuoteStyle["ANY_QUOTE"] = "any";
|
|
4410
4459
|
})(QuoteStyle || (QuoteStyle = {}));
|
|
4411
|
-
const defaults$
|
|
4460
|
+
const defaults$r = {
|
|
4412
4461
|
style: "auto",
|
|
4413
4462
|
unquoted: false,
|
|
4414
4463
|
};
|
|
@@ -4475,7 +4524,7 @@ class AttrQuotes extends Rule {
|
|
|
4475
4524
|
};
|
|
4476
4525
|
}
|
|
4477
4526
|
constructor(options) {
|
|
4478
|
-
super({ ...defaults$
|
|
4527
|
+
super({ ...defaults$r, ...options });
|
|
4479
4528
|
this.style = parseStyle$4(this.options.style);
|
|
4480
4529
|
}
|
|
4481
4530
|
setup() {
|
|
@@ -4645,12 +4694,12 @@ class AttributeAllowedValues extends Rule {
|
|
|
4645
4694
|
}
|
|
4646
4695
|
}
|
|
4647
4696
|
|
|
4648
|
-
const defaults$
|
|
4697
|
+
const defaults$q = {
|
|
4649
4698
|
style: "omit",
|
|
4650
4699
|
};
|
|
4651
4700
|
class AttributeBooleanStyle extends Rule {
|
|
4652
4701
|
constructor(options) {
|
|
4653
|
-
super({ ...defaults$
|
|
4702
|
+
super({ ...defaults$q, ...options });
|
|
4654
4703
|
this.hasInvalidStyle = parseStyle$3(this.options.style);
|
|
4655
4704
|
}
|
|
4656
4705
|
static schema() {
|
|
@@ -4726,12 +4775,12 @@ function reportMessage$1(attr, style) {
|
|
|
4726
4775
|
return "";
|
|
4727
4776
|
}
|
|
4728
4777
|
|
|
4729
|
-
const defaults$
|
|
4778
|
+
const defaults$p = {
|
|
4730
4779
|
style: "omit",
|
|
4731
4780
|
};
|
|
4732
4781
|
class AttributeEmptyStyle extends Rule {
|
|
4733
4782
|
constructor(options) {
|
|
4734
|
-
super({ ...defaults$
|
|
4783
|
+
super({ ...defaults$p, ...options });
|
|
4735
4784
|
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
4736
4785
|
}
|
|
4737
4786
|
static schema() {
|
|
@@ -4887,12 +4936,12 @@ function describePattern(pattern) {
|
|
|
4887
4936
|
}
|
|
4888
4937
|
}
|
|
4889
4938
|
|
|
4890
|
-
const defaults$
|
|
4939
|
+
const defaults$o = {
|
|
4891
4940
|
pattern: "kebabcase",
|
|
4892
4941
|
};
|
|
4893
4942
|
class ClassPattern extends Rule {
|
|
4894
4943
|
constructor(options) {
|
|
4895
|
-
super({ ...defaults$
|
|
4944
|
+
super({ ...defaults$o, ...options });
|
|
4896
4945
|
this.pattern = parsePattern(this.options.pattern);
|
|
4897
4946
|
}
|
|
4898
4947
|
static schema() {
|
|
@@ -5001,13 +5050,13 @@ class CloseOrder extends Rule {
|
|
|
5001
5050
|
}
|
|
5002
5051
|
}
|
|
5003
5052
|
|
|
5004
|
-
const defaults$
|
|
5053
|
+
const defaults$n = {
|
|
5005
5054
|
include: null,
|
|
5006
5055
|
exclude: null,
|
|
5007
5056
|
};
|
|
5008
5057
|
class Deprecated extends Rule {
|
|
5009
5058
|
constructor(options) {
|
|
5010
|
-
super({ ...defaults$
|
|
5059
|
+
super({ ...defaults$n, ...options });
|
|
5011
5060
|
}
|
|
5012
5061
|
static schema() {
|
|
5013
5062
|
return {
|
|
@@ -5170,12 +5219,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
|
|
|
5170
5219
|
}
|
|
5171
5220
|
};
|
|
5172
5221
|
|
|
5173
|
-
const defaults$
|
|
5222
|
+
const defaults$m = {
|
|
5174
5223
|
style: "uppercase",
|
|
5175
5224
|
};
|
|
5176
5225
|
class DoctypeStyle extends Rule {
|
|
5177
5226
|
constructor(options) {
|
|
5178
|
-
super({ ...defaults$
|
|
5227
|
+
super({ ...defaults$m, ...options });
|
|
5179
5228
|
}
|
|
5180
5229
|
static schema() {
|
|
5181
5230
|
return {
|
|
@@ -5207,12 +5256,12 @@ class DoctypeStyle extends Rule {
|
|
|
5207
5256
|
}
|
|
5208
5257
|
}
|
|
5209
5258
|
|
|
5210
|
-
const defaults$
|
|
5259
|
+
const defaults$l = {
|
|
5211
5260
|
style: "lowercase",
|
|
5212
5261
|
};
|
|
5213
5262
|
class ElementCase extends Rule {
|
|
5214
5263
|
constructor(options) {
|
|
5215
|
-
super({ ...defaults$
|
|
5264
|
+
super({ ...defaults$l, ...options });
|
|
5216
5265
|
this.style = new rulesHelper.CaseStyle(this.options.style, "element-case");
|
|
5217
5266
|
}
|
|
5218
5267
|
static schema() {
|
|
@@ -5278,14 +5327,14 @@ class ElementCase extends Rule {
|
|
|
5278
5327
|
}
|
|
5279
5328
|
}
|
|
5280
5329
|
|
|
5281
|
-
const defaults$
|
|
5330
|
+
const defaults$k = {
|
|
5282
5331
|
pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
|
|
5283
5332
|
whitelist: [],
|
|
5284
5333
|
blacklist: [],
|
|
5285
5334
|
};
|
|
5286
5335
|
class ElementName extends Rule {
|
|
5287
5336
|
constructor(options) {
|
|
5288
|
-
super({ ...defaults$
|
|
5337
|
+
super({ ...defaults$k, ...options });
|
|
5289
5338
|
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
5290
5339
|
this.pattern = new RegExp(this.options.pattern);
|
|
5291
5340
|
}
|
|
@@ -5326,7 +5375,7 @@ class ElementName extends Rule {
|
|
|
5326
5375
|
...context.blacklist.map((cur) => `- ${cur}`),
|
|
5327
5376
|
];
|
|
5328
5377
|
}
|
|
5329
|
-
if (context.pattern !== defaults$
|
|
5378
|
+
if (context.pattern !== defaults$k.pattern) {
|
|
5330
5379
|
return [
|
|
5331
5380
|
`<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
|
|
5332
5381
|
"",
|
|
@@ -5517,24 +5566,16 @@ class ElementPermittedOccurrences extends Rule {
|
|
|
5517
5566
|
this.on("dom:ready", (event) => {
|
|
5518
5567
|
const doc = event.document;
|
|
5519
5568
|
doc.visitDepthFirst((node) => {
|
|
5520
|
-
|
|
5521
|
-
if (!parent || !parent.meta) {
|
|
5569
|
+
if (!node || !node.meta) {
|
|
5522
5570
|
return;
|
|
5523
5571
|
}
|
|
5524
|
-
const rules =
|
|
5572
|
+
const rules = node.meta.permittedContent;
|
|
5525
5573
|
if (!rules) {
|
|
5526
5574
|
return;
|
|
5527
5575
|
}
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
* subsequent occurrences should. */
|
|
5532
|
-
if (first) {
|
|
5533
|
-
return;
|
|
5534
|
-
}
|
|
5535
|
-
if (parent.meta && !Validator.validateOccurrences(node, rules, siblings.length)) {
|
|
5536
|
-
this.report(node, `Element <${node.tagName}> can only appear once under ${parent.annotatedName}`);
|
|
5537
|
-
}
|
|
5576
|
+
Validator.validateOccurrences(node.childElements, rules, (child, category) => {
|
|
5577
|
+
this.report(child, `Element <${category}> can only appear once under ${node.annotatedName}`);
|
|
5578
|
+
});
|
|
5538
5579
|
});
|
|
5539
5580
|
});
|
|
5540
5581
|
}
|
|
@@ -5569,11 +5610,11 @@ class ElementPermittedOrder extends Rule {
|
|
|
5569
5610
|
function isCategoryOrTag(value) {
|
|
5570
5611
|
return typeof value === "string";
|
|
5571
5612
|
}
|
|
5572
|
-
function isCategory(value) {
|
|
5613
|
+
function isCategory$1(value) {
|
|
5573
5614
|
return value[0] === "@";
|
|
5574
5615
|
}
|
|
5575
5616
|
function formatCategoryOrTag(value) {
|
|
5576
|
-
return isCategory(value) ? value.slice(1) : `<${value}>`;
|
|
5617
|
+
return isCategory$1(value) ? value.slice(1) : `<${value}>`;
|
|
5577
5618
|
}
|
|
5578
5619
|
function isFormattable(rules) {
|
|
5579
5620
|
return rules.length > 0 && rules.every(isCategoryOrTag);
|
|
@@ -5586,7 +5627,7 @@ function getRuleDescription$1(context) {
|
|
|
5586
5627
|
const preamble = `The \`${child}\` element cannot have a \`${parent}\` element as parent.`;
|
|
5587
5628
|
if (isFormattable(rules)) {
|
|
5588
5629
|
const allowed = rules.filter(isCategoryOrTag).map((it) => {
|
|
5589
|
-
if (isCategory(it)) {
|
|
5630
|
+
if (isCategory$1(it)) {
|
|
5590
5631
|
return `- any ${it.slice(1)} element`;
|
|
5591
5632
|
}
|
|
5592
5633
|
else {
|
|
@@ -5749,6 +5790,9 @@ class ElementRequiredAttributes extends Rule {
|
|
|
5749
5790
|
}
|
|
5750
5791
|
}
|
|
5751
5792
|
|
|
5793
|
+
function isCategory(value) {
|
|
5794
|
+
return value[0] === "@";
|
|
5795
|
+
}
|
|
5752
5796
|
class ElementRequiredContent extends Rule {
|
|
5753
5797
|
documentation(context) {
|
|
5754
5798
|
if (context) {
|
|
@@ -5783,7 +5827,8 @@ class ElementRequiredContent extends Rule {
|
|
|
5783
5827
|
element: node.annotatedName,
|
|
5784
5828
|
missing: `<${missing}>`,
|
|
5785
5829
|
};
|
|
5786
|
-
const
|
|
5830
|
+
const tag = isCategory(missing) ? `${missing.slice(1)} element` : `<${missing}>`;
|
|
5831
|
+
const message = `${node.annotatedName} element must have ${tag} as content`;
|
|
5787
5832
|
this.report(node, message, null, context);
|
|
5788
5833
|
}
|
|
5789
5834
|
});
|
|
@@ -5874,7 +5919,7 @@ class EmptyTitle extends Rule {
|
|
|
5874
5919
|
}
|
|
5875
5920
|
}
|
|
5876
5921
|
|
|
5877
|
-
const defaults$
|
|
5922
|
+
const defaults$j = {
|
|
5878
5923
|
allowMultipleH1: false,
|
|
5879
5924
|
minInitialRank: "h1",
|
|
5880
5925
|
sectioningRoots: ["dialog", '[role="dialog"]'],
|
|
@@ -5905,7 +5950,7 @@ function parseMaxInitial(value) {
|
|
|
5905
5950
|
}
|
|
5906
5951
|
class HeadingLevel extends Rule {
|
|
5907
5952
|
constructor(options) {
|
|
5908
|
-
super({ ...defaults$
|
|
5953
|
+
super({ ...defaults$j, ...options });
|
|
5909
5954
|
this.stack = [];
|
|
5910
5955
|
this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
|
|
5911
5956
|
this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
|
|
@@ -6063,12 +6108,12 @@ class HeadingLevel extends Rule {
|
|
|
6063
6108
|
}
|
|
6064
6109
|
}
|
|
6065
6110
|
|
|
6066
|
-
const defaults$
|
|
6111
|
+
const defaults$i = {
|
|
6067
6112
|
pattern: "kebabcase",
|
|
6068
6113
|
};
|
|
6069
6114
|
class IdPattern extends Rule {
|
|
6070
6115
|
constructor(options) {
|
|
6071
|
-
super({ ...defaults$
|
|
6116
|
+
super({ ...defaults$i, ...options });
|
|
6072
6117
|
this.pattern = parsePattern(this.options.pattern);
|
|
6073
6118
|
}
|
|
6074
6119
|
static schema() {
|
|
@@ -6350,12 +6395,12 @@ function findLabelByParent(el) {
|
|
|
6350
6395
|
return [];
|
|
6351
6396
|
}
|
|
6352
6397
|
|
|
6353
|
-
const defaults$
|
|
6398
|
+
const defaults$h = {
|
|
6354
6399
|
maxlength: 70,
|
|
6355
6400
|
};
|
|
6356
6401
|
class LongTitle extends Rule {
|
|
6357
6402
|
constructor(options) {
|
|
6358
|
-
super({ ...defaults$
|
|
6403
|
+
super({ ...defaults$h, ...options });
|
|
6359
6404
|
this.maxlength = this.options.maxlength;
|
|
6360
6405
|
}
|
|
6361
6406
|
static schema() {
|
|
@@ -6545,13 +6590,13 @@ class MultipleLabeledControls extends Rule {
|
|
|
6545
6590
|
}
|
|
6546
6591
|
}
|
|
6547
6592
|
|
|
6548
|
-
const defaults$
|
|
6593
|
+
const defaults$g = {
|
|
6549
6594
|
include: null,
|
|
6550
6595
|
exclude: null,
|
|
6551
6596
|
};
|
|
6552
6597
|
class NoAutoplay extends Rule {
|
|
6553
6598
|
constructor(options) {
|
|
6554
|
-
super({ ...defaults$
|
|
6599
|
+
super({ ...defaults$g, ...options });
|
|
6555
6600
|
}
|
|
6556
6601
|
documentation(context) {
|
|
6557
6602
|
const tagName = context ? ` on <${context.tagName}>` : "";
|
|
@@ -6792,14 +6837,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
6792
6837
|
}
|
|
6793
6838
|
}
|
|
6794
6839
|
|
|
6795
|
-
const defaults$
|
|
6840
|
+
const defaults$f = {
|
|
6796
6841
|
include: null,
|
|
6797
6842
|
exclude: null,
|
|
6798
6843
|
allowedProperties: ["display"],
|
|
6799
6844
|
};
|
|
6800
6845
|
class NoInlineStyle extends Rule {
|
|
6801
6846
|
constructor(options) {
|
|
6802
|
-
super({ ...defaults$
|
|
6847
|
+
super({ ...defaults$f, ...options });
|
|
6803
6848
|
}
|
|
6804
6849
|
static schema() {
|
|
6805
6850
|
return {
|
|
@@ -7001,7 +7046,7 @@ class NoMultipleMain extends Rule {
|
|
|
7001
7046
|
}
|
|
7002
7047
|
}
|
|
7003
7048
|
|
|
7004
|
-
const defaults$
|
|
7049
|
+
const defaults$e = {
|
|
7005
7050
|
relaxed: false,
|
|
7006
7051
|
};
|
|
7007
7052
|
const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
|
|
@@ -7018,7 +7063,7 @@ const replacementTable = {
|
|
|
7018
7063
|
};
|
|
7019
7064
|
class NoRawCharacters extends Rule {
|
|
7020
7065
|
constructor(options) {
|
|
7021
|
-
super({ ...defaults$
|
|
7066
|
+
super({ ...defaults$e, ...options });
|
|
7022
7067
|
this.relaxed = this.options.relaxed;
|
|
7023
7068
|
}
|
|
7024
7069
|
static schema() {
|
|
@@ -7196,13 +7241,13 @@ class NoRedundantRole extends Rule {
|
|
|
7196
7241
|
}
|
|
7197
7242
|
|
|
7198
7243
|
const xmlns = /^(.+):.+$/;
|
|
7199
|
-
const defaults$
|
|
7244
|
+
const defaults$d = {
|
|
7200
7245
|
ignoreForeign: true,
|
|
7201
7246
|
ignoreXML: true,
|
|
7202
7247
|
};
|
|
7203
7248
|
class NoSelfClosing extends Rule {
|
|
7204
7249
|
constructor(options) {
|
|
7205
|
-
super({ ...defaults$
|
|
7250
|
+
super({ ...defaults$d, ...options });
|
|
7206
7251
|
}
|
|
7207
7252
|
static schema() {
|
|
7208
7253
|
return {
|
|
@@ -7291,7 +7336,44 @@ class NoTrailingWhitespace extends Rule {
|
|
|
7291
7336
|
}
|
|
7292
7337
|
}
|
|
7293
7338
|
|
|
7339
|
+
const defaults$c = {
|
|
7340
|
+
include: null,
|
|
7341
|
+
exclude: null,
|
|
7342
|
+
};
|
|
7294
7343
|
class NoUnknownElements extends Rule {
|
|
7344
|
+
constructor(options) {
|
|
7345
|
+
super({ ...defaults$c, ...options });
|
|
7346
|
+
}
|
|
7347
|
+
static schema() {
|
|
7348
|
+
return {
|
|
7349
|
+
exclude: {
|
|
7350
|
+
anyOf: [
|
|
7351
|
+
{
|
|
7352
|
+
items: {
|
|
7353
|
+
type: "string",
|
|
7354
|
+
},
|
|
7355
|
+
type: "array",
|
|
7356
|
+
},
|
|
7357
|
+
{
|
|
7358
|
+
type: "null",
|
|
7359
|
+
},
|
|
7360
|
+
],
|
|
7361
|
+
},
|
|
7362
|
+
include: {
|
|
7363
|
+
anyOf: [
|
|
7364
|
+
{
|
|
7365
|
+
items: {
|
|
7366
|
+
type: "string",
|
|
7367
|
+
},
|
|
7368
|
+
type: "array",
|
|
7369
|
+
},
|
|
7370
|
+
{
|
|
7371
|
+
type: "null",
|
|
7372
|
+
},
|
|
7373
|
+
],
|
|
7374
|
+
},
|
|
7375
|
+
};
|
|
7376
|
+
}
|
|
7295
7377
|
documentation(context) {
|
|
7296
7378
|
const element = context ? ` <${context}>` : "";
|
|
7297
7379
|
return {
|
|
@@ -7302,9 +7384,13 @@ class NoUnknownElements extends Rule {
|
|
|
7302
7384
|
setup() {
|
|
7303
7385
|
this.on("tag:start", (event) => {
|
|
7304
7386
|
const node = event.target;
|
|
7305
|
-
if (
|
|
7306
|
-
|
|
7387
|
+
if (node.meta) {
|
|
7388
|
+
return;
|
|
7307
7389
|
}
|
|
7390
|
+
if (this.isKeywordIgnored(node.tagName, rulesHelper.keywordPatternMatcher)) {
|
|
7391
|
+
return;
|
|
7392
|
+
}
|
|
7393
|
+
this.report(node, `Unknown element <${node.tagName}>`, null, node.tagName);
|
|
7308
7394
|
});
|
|
7309
7395
|
}
|
|
7310
7396
|
}
|
|
@@ -8766,6 +8852,11 @@ class H37 extends Rule {
|
|
|
8766
8852
|
}
|
|
8767
8853
|
}
|
|
8768
8854
|
|
|
8855
|
+
var _a;
|
|
8856
|
+
/* istanbul ignore next: this will always be present for the <th>
|
|
8857
|
+
* attribute (or the tests would fail) */
|
|
8858
|
+
const { enum: validScopes } = (_a = elements.html5.th.attributes) === null || _a === void 0 ? void 0 : _a.scope;
|
|
8859
|
+
const joinedScopes = rulesHelper.naturalJoin(validScopes);
|
|
8769
8860
|
class H63 extends Rule {
|
|
8770
8861
|
documentation() {
|
|
8771
8862
|
return {
|
|
@@ -8775,19 +8866,25 @@ class H63 extends Rule {
|
|
|
8775
8866
|
}
|
|
8776
8867
|
setup() {
|
|
8777
8868
|
this.on("tag:ready", (event) => {
|
|
8778
|
-
var _a, _b
|
|
8869
|
+
var _a, _b;
|
|
8779
8870
|
const node = event.target;
|
|
8780
8871
|
/* only validate th */
|
|
8781
8872
|
if (!node || node.tagName !== "th") {
|
|
8782
8873
|
return;
|
|
8783
8874
|
}
|
|
8875
|
+
const scope = node.getAttribute("scope");
|
|
8876
|
+
const value = scope === null || scope === void 0 ? void 0 : scope.value;
|
|
8877
|
+
/* ignore dynamic scope */
|
|
8878
|
+
if (value instanceof DynamicValue) {
|
|
8879
|
+
return;
|
|
8880
|
+
}
|
|
8784
8881
|
/* ignore elements with valid scope values */
|
|
8785
|
-
|
|
8786
|
-
const scopeMeta = (_b = (_a = elements.html5 === null || elements.html5 === void 0 ? void 0 : elements.html5.th) === null || _a === void 0 ? void 0 : _a.attributes) === null || _b === void 0 ? void 0 : _b.scope;
|
|
8787
|
-
if (scope && ((_c = scopeMeta.enum) === null || _c === void 0 ? void 0 : _c.includes(scope))) {
|
|
8882
|
+
if (value && validScopes.includes(value)) {
|
|
8788
8883
|
return;
|
|
8789
8884
|
}
|
|
8790
|
-
|
|
8885
|
+
const message = `<th> element must have a valid scope attribute: ${joinedScopes}`;
|
|
8886
|
+
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;
|
|
8887
|
+
this.report(node, message, location);
|
|
8791
8888
|
});
|
|
8792
8889
|
}
|
|
8793
8890
|
}
|
|
@@ -11158,7 +11255,7 @@ class HtmlValidate {
|
|
|
11158
11255
|
/** @public */
|
|
11159
11256
|
const name = "html-validate";
|
|
11160
11257
|
/** @public */
|
|
11161
|
-
const version = "7.
|
|
11258
|
+
const version = "7.11.1";
|
|
11162
11259
|
/** @public */
|
|
11163
11260
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
11164
11261
|
|