html-validate 8.0.5 → 8.2.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.js +4 -2
- package/dist/cjs/browser.js.map +1 -1
- package/dist/cjs/cli.js +41 -15
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core-browser.js +31 -0
- package/dist/cjs/core-browser.js.map +1 -0
- package/dist/cjs/{nodejs.js → core-nodejs.js} +54 -4
- package/dist/cjs/core-nodejs.js.map +1 -0
- package/dist/cjs/core.js +306 -269
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +24 -3
- package/dist/cjs/elements.js.map +1 -1
- package/dist/cjs/html-validate.js +6 -6
- package/dist/cjs/html-validate.js.map +1 -1
- package/dist/cjs/index.js +6 -6
- package/dist/cjs/jest-lib.js +6 -6
- package/dist/cjs/jest-lib.js.map +1 -1
- package/dist/cjs/jest.js +3 -3
- package/dist/cjs/meta-helper.js +16 -2
- package/dist/cjs/meta-helper.js.map +1 -1
- package/dist/cjs/test-utils.js +1 -1
- package/dist/cjs/test-utils.js.map +1 -1
- package/dist/cjs/tsdoc-metadata.json +1 -1
- package/dist/es/browser.js +4 -3
- package/dist/es/browser.js.map +1 -1
- package/dist/es/cli.js +39 -13
- package/dist/es/cli.js.map +1 -1
- package/dist/es/core-browser.js +29 -0
- package/dist/es/core-browser.js.map +1 -0
- package/dist/es/{nodejs.js → core-nodejs.js} +53 -5
- package/dist/es/core-nodejs.js.map +1 -0
- package/dist/es/core.js +304 -266
- package/dist/es/core.js.map +1 -1
- package/dist/es/elements.js +24 -3
- package/dist/es/elements.js.map +1 -1
- package/dist/es/html-validate.js +7 -7
- package/dist/es/html-validate.js.map +1 -1
- package/dist/es/index.js +4 -4
- package/dist/es/jest-lib.js +4 -4
- package/dist/es/jest-lib.js.map +1 -1
- package/dist/es/jest.js +3 -3
- package/dist/es/meta-helper.js +16 -2
- package/dist/es/meta-helper.js.map +1 -1
- package/dist/es/test-utils.js +1 -1
- package/dist/es/test-utils.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types/browser.d.ts +66 -74
- package/dist/types/index.d.ts +45 -77
- package/dist/types/jest.d.ts +4 -8
- package/package.json +22 -22
- package/dist/cjs/nodejs.js.map +0 -1
- package/dist/es/nodejs.js.map +0 -1
package/dist/cjs/core.js
CHANGED
|
@@ -4,21 +4,21 @@ var Ajv = require('ajv');
|
|
|
4
4
|
var deepmerge = require('deepmerge');
|
|
5
5
|
var elements = require('./elements.js');
|
|
6
6
|
var fs = require('fs');
|
|
7
|
-
var semver = require('semver');
|
|
8
|
-
var kleur = require('kleur');
|
|
9
7
|
var betterAjvErrors = require('@sidvind/better-ajv-errors');
|
|
10
8
|
var utils_naturalJoin = require('./utils/natural-join.js');
|
|
11
9
|
var codeFrame = require('@babel/code-frame');
|
|
10
|
+
var kleur = require('kleur');
|
|
12
11
|
var stylish$2 = require('@html-validate/stylish');
|
|
12
|
+
var semver = require('semver');
|
|
13
13
|
|
|
14
14
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
15
|
|
|
16
16
|
var Ajv__default = /*#__PURE__*/_interopDefault(Ajv);
|
|
17
17
|
var deepmerge__default = /*#__PURE__*/_interopDefault(deepmerge);
|
|
18
18
|
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
19
|
-
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
20
|
-
var kleur__default = /*#__PURE__*/_interopDefault(kleur);
|
|
21
19
|
var betterAjvErrors__default = /*#__PURE__*/_interopDefault(betterAjvErrors);
|
|
20
|
+
var kleur__default = /*#__PURE__*/_interopDefault(kleur);
|
|
21
|
+
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
22
22
|
|
|
23
23
|
const $schema$2 = "http://json-schema.org/draft-06/schema#";
|
|
24
24
|
const $id$2 = "http://json-schema.org/draft-06/schema#";
|
|
@@ -295,7 +295,7 @@ class NestedError extends Error {
|
|
|
295
295
|
super(message);
|
|
296
296
|
Error.captureStackTrace(this, NestedError);
|
|
297
297
|
this.name = NestedError.name;
|
|
298
|
-
if (nested
|
|
298
|
+
if (nested === null || nested === void 0 ? void 0 : nested.stack) {
|
|
299
299
|
this.stack += `\nCaused by: ${nested.stack}`;
|
|
300
300
|
}
|
|
301
301
|
}
|
|
@@ -1030,7 +1030,8 @@ function hasAttribute(node, attr) {
|
|
|
1030
1030
|
* Matches attribute against value.
|
|
1031
1031
|
*/
|
|
1032
1032
|
function matchAttribute(node, key, op, value) {
|
|
1033
|
-
|
|
1033
|
+
var _a;
|
|
1034
|
+
const nodeValue = ((_a = node.getAttributeValue(key)) !== null && _a !== void 0 ? _a : "").toLowerCase();
|
|
1034
1035
|
switch (op) {
|
|
1035
1036
|
case "!=":
|
|
1036
1037
|
return nodeValue !== value;
|
|
@@ -1392,6 +1393,16 @@ class Attribute {
|
|
|
1392
1393
|
get isDynamic() {
|
|
1393
1394
|
return this.value instanceof DynamicValue;
|
|
1394
1395
|
}
|
|
1396
|
+
/**
|
|
1397
|
+
* Test attribute value.
|
|
1398
|
+
*
|
|
1399
|
+
* @param pattern - Pattern to match value against. Can be a RegExp, literal
|
|
1400
|
+
* string or an array of strings (returns true if any value matches the
|
|
1401
|
+
* array).
|
|
1402
|
+
* @param dynamicMatches - If true `DynamicValue` will always match, if false
|
|
1403
|
+
* it never matches.
|
|
1404
|
+
* @returns `true` if attribute value matches pattern.
|
|
1405
|
+
*/
|
|
1395
1406
|
valueMatches(pattern, dynamicMatches = true) {
|
|
1396
1407
|
if (this.value === null) {
|
|
1397
1408
|
return false;
|
|
@@ -1777,7 +1788,7 @@ class DOMTokenList extends Array {
|
|
|
1777
1788
|
this.value = value.expr;
|
|
1778
1789
|
}
|
|
1779
1790
|
else {
|
|
1780
|
-
this.value = value
|
|
1791
|
+
this.value = value !== null && value !== void 0 ? value : "";
|
|
1781
1792
|
}
|
|
1782
1793
|
}
|
|
1783
1794
|
item(n) {
|
|
@@ -2002,7 +2013,7 @@ class IdMatcher extends Matcher {
|
|
|
2002
2013
|
class AttrMatcher extends Matcher {
|
|
2003
2014
|
constructor(attr) {
|
|
2004
2015
|
super();
|
|
2005
|
-
const [, key, op, value] = attr.match(/^(.+?)(?:([~^$*|]?=)"([^"]+?)")?$/);
|
|
2016
|
+
const [, key, op, value] = attr.match(/^(.+?)(?:([~^$*|]?=)"([^"]+?)")?$/); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- will always match
|
|
2006
2017
|
this.key = key;
|
|
2007
2018
|
this.op = op;
|
|
2008
2019
|
this.value = value;
|
|
@@ -2039,11 +2050,11 @@ class PseudoClassMatcher extends Matcher {
|
|
|
2039
2050
|
}
|
|
2040
2051
|
class Pattern {
|
|
2041
2052
|
constructor(pattern) {
|
|
2042
|
-
const match = pattern.match(/^([~+\->]?)((?:[*]|[^.#[:]+)?)(.*)$/);
|
|
2053
|
+
const match = pattern.match(/^([~+\->]?)((?:[*]|[^.#[:]+)?)(.*)$/); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- will always match
|
|
2043
2054
|
match.shift(); /* remove full matched string */
|
|
2044
2055
|
this.selector = pattern;
|
|
2045
2056
|
this.combinator = parseCombinator(match.shift(), pattern);
|
|
2046
|
-
this.tagName = match.shift() || "*";
|
|
2057
|
+
this.tagName = match.shift() || "*"; // eslint-disable-line @typescript-eslint/prefer-nullish-coalescing -- empty string */
|
|
2047
2058
|
this.pattern = Array.from(splitPattern(match[0]), (it) => this.createMatcher(it));
|
|
2048
2059
|
}
|
|
2049
2060
|
match(node, context) {
|
|
@@ -2217,6 +2228,21 @@ function isElementNode(node) {
|
|
|
2217
2228
|
function isValidTagName(tagName) {
|
|
2218
2229
|
return Boolean(tagName !== "" && tagName !== "*");
|
|
2219
2230
|
}
|
|
2231
|
+
function createAdapter(node) {
|
|
2232
|
+
return {
|
|
2233
|
+
closest(selectors) {
|
|
2234
|
+
var _a;
|
|
2235
|
+
return (_a = node.closest(selectors)) === null || _a === void 0 ? void 0 : _a._adapter;
|
|
2236
|
+
},
|
|
2237
|
+
getAttribute(name) {
|
|
2238
|
+
var _a;
|
|
2239
|
+
return (_a = node.getAttribute(name)) === null || _a === void 0 ? void 0 : _a.value;
|
|
2240
|
+
},
|
|
2241
|
+
hasAttribute(name) {
|
|
2242
|
+
return node.hasAttribute(name);
|
|
2243
|
+
},
|
|
2244
|
+
};
|
|
2245
|
+
}
|
|
2220
2246
|
/**
|
|
2221
2247
|
* @public
|
|
2222
2248
|
*/
|
|
@@ -2225,9 +2251,9 @@ class HtmlElement extends DOMNode {
|
|
|
2225
2251
|
const nodeType = tagName ? exports.NodeType.ELEMENT_NODE : exports.NodeType.DOCUMENT_NODE;
|
|
2226
2252
|
super(nodeType, tagName, location);
|
|
2227
2253
|
if (!isValidTagName(tagName)) {
|
|
2228
|
-
throw new Error(`The tag name provided ('${tagName
|
|
2254
|
+
throw new Error(`The tag name provided ('${tagName !== null && tagName !== void 0 ? tagName : ""}') is not a valid name`);
|
|
2229
2255
|
}
|
|
2230
|
-
this.tagName = tagName
|
|
2256
|
+
this.tagName = tagName !== null && tagName !== void 0 ? tagName : "#document";
|
|
2231
2257
|
this.parent = parent !== null && parent !== void 0 ? parent : null;
|
|
2232
2258
|
this.attr = {};
|
|
2233
2259
|
this.metaElement = meta !== null && meta !== void 0 ? meta : null;
|
|
@@ -2235,6 +2261,7 @@ class HtmlElement extends DOMNode {
|
|
|
2235
2261
|
this.voidElement = meta ? Boolean(meta.void) : false;
|
|
2236
2262
|
this.depth = 0;
|
|
2237
2263
|
this.annotation = null;
|
|
2264
|
+
this._adapter = createAdapter(this);
|
|
2238
2265
|
if (parent) {
|
|
2239
2266
|
parent.childNodes.push(this);
|
|
2240
2267
|
/* calculate depth in domtree */
|
|
@@ -2294,7 +2321,7 @@ class HtmlElement extends DOMNode {
|
|
|
2294
2321
|
*/
|
|
2295
2322
|
get ariaLabelledby() {
|
|
2296
2323
|
const attr = this.getAttribute("aria-labelledby");
|
|
2297
|
-
if (!attr ||
|
|
2324
|
+
if (!(attr === null || attr === void 0 ? void 0 : attr.value)) {
|
|
2298
2325
|
return null;
|
|
2299
2326
|
}
|
|
2300
2327
|
if (attr.value instanceof DynamicValue) {
|
|
@@ -2412,6 +2439,7 @@ class HtmlElement extends DOMNode {
|
|
|
2412
2439
|
setMetaProperty(this.metaElement, key, value);
|
|
2413
2440
|
}
|
|
2414
2441
|
else {
|
|
2442
|
+
/* eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- technical debt */
|
|
2415
2443
|
delete this.metaElement[key];
|
|
2416
2444
|
}
|
|
2417
2445
|
}
|
|
@@ -2687,11 +2715,12 @@ class DOMTree {
|
|
|
2687
2715
|
this.active = node;
|
|
2688
2716
|
}
|
|
2689
2717
|
popActive() {
|
|
2718
|
+
var _a;
|
|
2690
2719
|
if (this.active.isRootElement()) {
|
|
2691
2720
|
/* root element should never be popped, continue as if nothing happened */
|
|
2692
2721
|
return;
|
|
2693
2722
|
}
|
|
2694
|
-
this.active = this.active.parent
|
|
2723
|
+
this.active = (_a = this.active.parent) !== null && _a !== void 0 ? _a : this.root;
|
|
2695
2724
|
}
|
|
2696
2725
|
getActive() {
|
|
2697
2726
|
return this.active;
|
|
@@ -2700,7 +2729,9 @@ class DOMTree {
|
|
|
2700
2729
|
* Resolve dynamic meta expressions.
|
|
2701
2730
|
*/
|
|
2702
2731
|
resolveMeta(table) {
|
|
2703
|
-
this.visitDepthFirst((node) =>
|
|
2732
|
+
this.visitDepthFirst((node) => {
|
|
2733
|
+
table.resolve(node);
|
|
2734
|
+
});
|
|
2704
2735
|
}
|
|
2705
2736
|
getElementsByTagName(tagName) {
|
|
2706
2737
|
return this.root.getElementsByTagName(tagName);
|
|
@@ -2725,6 +2756,7 @@ const allowedKeys = ["exclude"];
|
|
|
2725
2756
|
*
|
|
2726
2757
|
* @public
|
|
2727
2758
|
*/
|
|
2759
|
+
/* eslint-disable-next-line @typescript-eslint/no-extraneous-class -- technical debt, should probably be plain functions maybe in an object */
|
|
2728
2760
|
class Validator {
|
|
2729
2761
|
/**
|
|
2730
2762
|
* Test if element is used in a proper context.
|
|
@@ -2766,7 +2798,7 @@ class Validator {
|
|
|
2766
2798
|
return false;
|
|
2767
2799
|
}
|
|
2768
2800
|
// Check if the rule has a quantifier
|
|
2769
|
-
const [, category, quantifier] = rule.match(/^(@?.*?)([?*]?)$/);
|
|
2801
|
+
const [, category, quantifier] = rule.match(/^(@?.*?)([?*]?)$/); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- will always match
|
|
2770
2802
|
const limit = category && quantifier && parseQuantifier(quantifier);
|
|
2771
2803
|
if (limit) {
|
|
2772
2804
|
const siblings = children.filter((cur) => Validator.validatePermittedCategory(cur, rule, true));
|
|
@@ -2812,6 +2844,7 @@ class Validator {
|
|
|
2812
2844
|
* In both of these cases no error should be reported. */
|
|
2813
2845
|
const orderSpecified = rules.find((cur) => Validator.validatePermittedCategory(node, cur, true));
|
|
2814
2846
|
if (orderSpecified) {
|
|
2847
|
+
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- technical debt, should never happen */
|
|
2815
2848
|
cb(node, prev);
|
|
2816
2849
|
return false;
|
|
2817
2850
|
}
|
|
@@ -2952,9 +2985,9 @@ class Validator {
|
|
|
2952
2985
|
*/
|
|
2953
2986
|
/* eslint-disable-next-line complexity -- rule does not like switch */
|
|
2954
2987
|
static validatePermittedCategory(node, category, defaultMatch) {
|
|
2955
|
-
const [, rawCategory] = category.match(/^(@?.*?)([?*]?)$/);
|
|
2988
|
+
const [, rawCategory] = category.match(/^(@?.*?)([?*]?)$/); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- will always match
|
|
2956
2989
|
/* match tagName when an explicit name is given */
|
|
2957
|
-
if (rawCategory
|
|
2990
|
+
if (!rawCategory.startsWith("@")) {
|
|
2958
2991
|
return node.tagName === rawCategory;
|
|
2959
2992
|
}
|
|
2960
2993
|
/* if the meta entry is missing assume any content model would match */
|
|
@@ -2977,9 +3010,9 @@ class Validator {
|
|
|
2977
3010
|
case "@interactive":
|
|
2978
3011
|
return node.meta.interactive;
|
|
2979
3012
|
case "@script":
|
|
2980
|
-
return node.meta.scriptSupporting;
|
|
3013
|
+
return Boolean(node.meta.scriptSupporting);
|
|
2981
3014
|
case "@form":
|
|
2982
|
-
return node.meta.form;
|
|
3015
|
+
return Boolean(node.meta.form);
|
|
2983
3016
|
default:
|
|
2984
3017
|
throw new Error(`Invalid content category "${category}"`);
|
|
2985
3018
|
}
|
|
@@ -3164,10 +3197,12 @@ var configurationSchema = {
|
|
|
3164
3197
|
properties: properties
|
|
3165
3198
|
};
|
|
3166
3199
|
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3200
|
+
/**
|
|
3201
|
+
* @internal
|
|
3202
|
+
*/
|
|
3203
|
+
const TRANSFORMER_API = {
|
|
3204
|
+
VERSION: 1,
|
|
3205
|
+
};
|
|
3171
3206
|
|
|
3172
3207
|
/**
|
|
3173
3208
|
* @public
|
|
@@ -3414,7 +3449,7 @@ function classifyNodeText(node, options = {}) {
|
|
|
3414
3449
|
const { accessible = false, ignoreHiddenRoot = false } = options;
|
|
3415
3450
|
const cacheKey = getCachekey(options);
|
|
3416
3451
|
if (node.cacheExists(cacheKey)) {
|
|
3417
|
-
return node.cacheGet(cacheKey);
|
|
3452
|
+
return node.cacheGet(cacheKey); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- has/get combo
|
|
3418
3453
|
}
|
|
3419
3454
|
if (!ignoreHiddenRoot && isHTMLHidden(node)) {
|
|
3420
3455
|
return node.cacheSet(cacheKey, exports.TextClassification.EMPTY_TEXT);
|
|
@@ -3462,8 +3497,12 @@ function findTextNodes(node, options) {
|
|
|
3462
3497
|
|
|
3463
3498
|
function hasAltText(image) {
|
|
3464
3499
|
const alt = image.getAttribute("alt");
|
|
3465
|
-
/* missing
|
|
3466
|
-
if (alt
|
|
3500
|
+
/* missing attribute */
|
|
3501
|
+
if (!alt) {
|
|
3502
|
+
return false;
|
|
3503
|
+
}
|
|
3504
|
+
/* (incorrectly) set as boolean value */
|
|
3505
|
+
if (alt.value === null) {
|
|
3467
3506
|
return false;
|
|
3468
3507
|
}
|
|
3469
3508
|
return alt.isDynamic || alt.value.toString() !== "";
|
|
@@ -3471,8 +3510,12 @@ function hasAltText(image) {
|
|
|
3471
3510
|
|
|
3472
3511
|
function hasAriaLabel(node) {
|
|
3473
3512
|
const label = node.getAttribute("aria-label");
|
|
3474
|
-
/* missing
|
|
3475
|
-
if (label
|
|
3513
|
+
/* missing attribute */
|
|
3514
|
+
if (!label) {
|
|
3515
|
+
return false;
|
|
3516
|
+
}
|
|
3517
|
+
/* (incorrectly) set as boolean value */
|
|
3518
|
+
if (label.value === null) {
|
|
3476
3519
|
return false;
|
|
3477
3520
|
}
|
|
3478
3521
|
return label.isDynamic || label.value.toString() !== "";
|
|
@@ -3553,7 +3596,7 @@ class Rule {
|
|
|
3553
3596
|
this.options = options;
|
|
3554
3597
|
this.enabled = true;
|
|
3555
3598
|
this.blockers = [];
|
|
3556
|
-
this.severity =
|
|
3599
|
+
this.severity = exports.Severity.DISABLED;
|
|
3557
3600
|
this.name = "";
|
|
3558
3601
|
}
|
|
3559
3602
|
getSeverity() {
|
|
@@ -3706,13 +3749,14 @@ class Rule {
|
|
|
3706
3749
|
}
|
|
3707
3750
|
}
|
|
3708
3751
|
findLocation(src) {
|
|
3752
|
+
var _a, _b;
|
|
3709
3753
|
if (src.location) {
|
|
3710
3754
|
return src.location;
|
|
3711
3755
|
}
|
|
3712
|
-
if (src.event
|
|
3756
|
+
if ((_a = src.event) === null || _a === void 0 ? void 0 : _a.location) {
|
|
3713
3757
|
return src.event.location;
|
|
3714
3758
|
}
|
|
3715
|
-
if (src.node
|
|
3759
|
+
if ((_b = src.node) === null || _b === void 0 ? void 0 : _b.location) {
|
|
3716
3760
|
return src.node.location;
|
|
3717
3761
|
}
|
|
3718
3762
|
return {};
|
|
@@ -3809,7 +3853,7 @@ var Style$1;
|
|
|
3809
3853
|
Style["ABSOLUTE"] = "absolute";
|
|
3810
3854
|
Style["ANCHOR"] = "anchor";
|
|
3811
3855
|
})(Style$1 || (Style$1 = {}));
|
|
3812
|
-
const defaults$
|
|
3856
|
+
const defaults$u = {
|
|
3813
3857
|
allowExternal: true,
|
|
3814
3858
|
allowRelative: true,
|
|
3815
3859
|
allowAbsolute: true,
|
|
@@ -3853,7 +3897,7 @@ function matchList(value, list) {
|
|
|
3853
3897
|
}
|
|
3854
3898
|
class AllowedLinks extends Rule {
|
|
3855
3899
|
constructor(options) {
|
|
3856
|
-
super({ ...defaults$
|
|
3900
|
+
super({ ...defaults$u, ...options });
|
|
3857
3901
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
3858
3902
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
3859
3903
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -3885,7 +3929,8 @@ class AllowedLinks extends Rule {
|
|
|
3885
3929
|
};
|
|
3886
3930
|
}
|
|
3887
3931
|
documentation(context) {
|
|
3888
|
-
|
|
3932
|
+
var _a;
|
|
3933
|
+
const message = (_a = description[context]) !== null && _a !== void 0 ? _a : "This link type is not allowed by current configuration";
|
|
3889
3934
|
return {
|
|
3890
3935
|
description: message,
|
|
3891
3936
|
url: "https://html-validate.org/rules/allowed-links.html",
|
|
@@ -4001,7 +4046,7 @@ var RuleContext$1;
|
|
|
4001
4046
|
RuleContext["MISSING_ALT"] = "missing-alt";
|
|
4002
4047
|
RuleContext["MISSING_HREF"] = "missing-href";
|
|
4003
4048
|
})(RuleContext$1 || (RuleContext$1 = {}));
|
|
4004
|
-
const defaults$
|
|
4049
|
+
const defaults$t = {
|
|
4005
4050
|
accessible: true,
|
|
4006
4051
|
};
|
|
4007
4052
|
function findByTarget(target, siblings) {
|
|
@@ -4027,19 +4072,11 @@ function getDescription$1(context) {
|
|
|
4027
4072
|
"",
|
|
4028
4073
|
"Either add the `href` attribute or remove the `alt` attribute.",
|
|
4029
4074
|
];
|
|
4030
|
-
default:
|
|
4031
|
-
return [
|
|
4032
|
-
"The `alt` attribute must only be used together with the `href` attribute.",
|
|
4033
|
-
"It must be set if `href` is present and must be omitted if `href` is missing",
|
|
4034
|
-
"",
|
|
4035
|
-
"The attribute is used to provide an alternative text description for the area of the image map.",
|
|
4036
|
-
"The text should describe the purpose of area and the resource referenced by the `href` attribute.",
|
|
4037
|
-
];
|
|
4038
4075
|
}
|
|
4039
4076
|
}
|
|
4040
4077
|
class AreaAlt extends Rule {
|
|
4041
4078
|
constructor(options) {
|
|
4042
|
-
super({ ...defaults$
|
|
4079
|
+
super({ ...defaults$t, ...options });
|
|
4043
4080
|
}
|
|
4044
4081
|
static schema() {
|
|
4045
4082
|
return {
|
|
@@ -4157,7 +4194,7 @@ function isValidUsage(target, meta) {
|
|
|
4157
4194
|
return true;
|
|
4158
4195
|
}
|
|
4159
4196
|
/* interactive and labelable elements are valid */
|
|
4160
|
-
if (meta.interactive || meta.labelable) {
|
|
4197
|
+
if (Boolean(meta.interactive) || Boolean(meta.labelable)) {
|
|
4161
4198
|
return true;
|
|
4162
4199
|
}
|
|
4163
4200
|
return false;
|
|
@@ -4192,7 +4229,7 @@ class AriaLabelMisuse extends Rule {
|
|
|
4192
4229
|
}
|
|
4193
4230
|
validateElement(target) {
|
|
4194
4231
|
const attr = target.getAttribute("aria-label");
|
|
4195
|
-
if (!attr ||
|
|
4232
|
+
if (!(attr === null || attr === void 0 ? void 0 : attr.value) || attr.valueMatches("", false)) {
|
|
4196
4233
|
return;
|
|
4197
4234
|
}
|
|
4198
4235
|
/* ignore elements without meta */
|
|
@@ -4273,13 +4310,13 @@ class CaseStyle {
|
|
|
4273
4310
|
}
|
|
4274
4311
|
}
|
|
4275
4312
|
|
|
4276
|
-
const defaults$
|
|
4313
|
+
const defaults$s = {
|
|
4277
4314
|
style: "lowercase",
|
|
4278
4315
|
ignoreForeign: true,
|
|
4279
4316
|
};
|
|
4280
4317
|
class AttrCase extends Rule {
|
|
4281
4318
|
constructor(options) {
|
|
4282
|
-
super({ ...defaults$
|
|
4319
|
+
super({ ...defaults$s, ...options });
|
|
4283
4320
|
this.style = new CaseStyle(this.options.style, "attr-case");
|
|
4284
4321
|
}
|
|
4285
4322
|
static schema() {
|
|
@@ -4505,7 +4542,7 @@ class Lexer {
|
|
|
4505
4542
|
*/
|
|
4506
4543
|
enter(context, state, data) {
|
|
4507
4544
|
/* script/style tags require a different content model */
|
|
4508
|
-
if (state === State.TAG && data && data[0]
|
|
4545
|
+
if (state === State.TAG && data && data[0].startsWith("<")) {
|
|
4509
4546
|
if (data[0] === "<script") {
|
|
4510
4547
|
context.contentModel = ContentModel.SCRIPT;
|
|
4511
4548
|
}
|
|
@@ -4543,14 +4580,14 @@ class Lexer {
|
|
|
4543
4580
|
case ContentModel.TEXT:
|
|
4544
4581
|
return State.TEXT;
|
|
4545
4582
|
case ContentModel.SCRIPT:
|
|
4546
|
-
if (tagCloseToken && tagCloseToken.data[0]
|
|
4583
|
+
if (tagCloseToken && !tagCloseToken.data[0].startsWith("/")) {
|
|
4547
4584
|
return State.SCRIPT;
|
|
4548
4585
|
}
|
|
4549
4586
|
else {
|
|
4550
4587
|
return State.TEXT; /* <script/> (not legal but handle it anyway so the lexer doesn't choke on it) */
|
|
4551
4588
|
}
|
|
4552
4589
|
case ContentModel.STYLE:
|
|
4553
|
-
if (tagCloseToken && tagCloseToken.data[0]
|
|
4590
|
+
if (tagCloseToken && !tagCloseToken.data[0].startsWith("/")) {
|
|
4554
4591
|
return State.STYLE;
|
|
4555
4592
|
}
|
|
4556
4593
|
else {
|
|
@@ -4627,7 +4664,7 @@ class AttrDelimiter extends Rule {
|
|
|
4627
4664
|
}
|
|
4628
4665
|
|
|
4629
4666
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
4630
|
-
const defaults$
|
|
4667
|
+
const defaults$r = {
|
|
4631
4668
|
pattern: DEFAULT_PATTERN,
|
|
4632
4669
|
ignoreForeign: true,
|
|
4633
4670
|
};
|
|
@@ -4664,7 +4701,7 @@ function generateDescription(name, pattern) {
|
|
|
4664
4701
|
}
|
|
4665
4702
|
class AttrPattern extends Rule {
|
|
4666
4703
|
constructor(options) {
|
|
4667
|
-
super({ ...defaults$
|
|
4704
|
+
super({ ...defaults$r, ...options });
|
|
4668
4705
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4669
4706
|
}
|
|
4670
4707
|
static schema() {
|
|
@@ -4725,7 +4762,7 @@ var QuoteStyle;
|
|
|
4725
4762
|
QuoteStyle["AUTO_QUOTE"] = "auto";
|
|
4726
4763
|
QuoteStyle["ANY_QUOTE"] = "any";
|
|
4727
4764
|
})(QuoteStyle || (QuoteStyle = {}));
|
|
4728
|
-
const defaults$
|
|
4765
|
+
const defaults$q = {
|
|
4729
4766
|
style: "auto",
|
|
4730
4767
|
unquoted: false,
|
|
4731
4768
|
};
|
|
@@ -4792,7 +4829,7 @@ class AttrQuotes extends Rule {
|
|
|
4792
4829
|
};
|
|
4793
4830
|
}
|
|
4794
4831
|
constructor(options) {
|
|
4795
|
-
super({ ...defaults$
|
|
4832
|
+
super({ ...defaults$q, ...options });
|
|
4796
4833
|
this.style = parseStyle$3(this.options.style);
|
|
4797
4834
|
}
|
|
4798
4835
|
setup() {
|
|
@@ -4802,7 +4839,7 @@ class AttrQuotes extends Rule {
|
|
|
4802
4839
|
return;
|
|
4803
4840
|
}
|
|
4804
4841
|
if (!event.quote) {
|
|
4805
|
-
if (this.options.unquoted
|
|
4842
|
+
if (!this.options.unquoted) {
|
|
4806
4843
|
const message = `Attribute "${event.key}" using unquoted value`;
|
|
4807
4844
|
const context = {
|
|
4808
4845
|
error: "unquoted",
|
|
@@ -4923,7 +4960,7 @@ class AttributeAllowedValues extends Rule {
|
|
|
4923
4960
|
const meta = node.meta;
|
|
4924
4961
|
/* ignore rule if element has no meta or meta does not specify attribute
|
|
4925
4962
|
* allowed values */
|
|
4926
|
-
if (!meta ||
|
|
4963
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes))
|
|
4927
4964
|
return;
|
|
4928
4965
|
for (const attr of node.attributes) {
|
|
4929
4966
|
if (Validator.validateAttribute(attr, meta.attributes)) {
|
|
@@ -4962,12 +4999,12 @@ class AttributeAllowedValues extends Rule {
|
|
|
4962
4999
|
}
|
|
4963
5000
|
}
|
|
4964
5001
|
|
|
4965
|
-
const defaults$
|
|
5002
|
+
const defaults$p = {
|
|
4966
5003
|
style: "omit",
|
|
4967
5004
|
};
|
|
4968
5005
|
class AttributeBooleanStyle extends Rule {
|
|
4969
5006
|
constructor(options) {
|
|
4970
|
-
super({ ...defaults$
|
|
5007
|
+
super({ ...defaults$p, ...options });
|
|
4971
5008
|
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
4972
5009
|
}
|
|
4973
5010
|
static schema() {
|
|
@@ -4991,7 +5028,7 @@ class AttributeBooleanStyle extends Rule {
|
|
|
4991
5028
|
const meta = node.meta;
|
|
4992
5029
|
/* ignore rule if element has no meta or meta does not specify attribute
|
|
4993
5030
|
* allowed values */
|
|
4994
|
-
if (!meta ||
|
|
5031
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes))
|
|
4995
5032
|
return;
|
|
4996
5033
|
/* check all boolean attributes */
|
|
4997
5034
|
for (const attr of node.attributes) {
|
|
@@ -5043,12 +5080,12 @@ function reportMessage$1(attr, style) {
|
|
|
5043
5080
|
return "";
|
|
5044
5081
|
}
|
|
5045
5082
|
|
|
5046
|
-
const defaults$
|
|
5083
|
+
const defaults$o = {
|
|
5047
5084
|
style: "omit",
|
|
5048
5085
|
};
|
|
5049
5086
|
class AttributeEmptyStyle extends Rule {
|
|
5050
5087
|
constructor(options) {
|
|
5051
|
-
super({ ...defaults$
|
|
5088
|
+
super({ ...defaults$o, ...options });
|
|
5052
5089
|
this.hasInvalidStyle = parseStyle$1(this.options.style);
|
|
5053
5090
|
}
|
|
5054
5091
|
static schema() {
|
|
@@ -5072,7 +5109,7 @@ class AttributeEmptyStyle extends Rule {
|
|
|
5072
5109
|
const meta = node.meta;
|
|
5073
5110
|
/* ignore rule if element has no meta or meta does not specify attribute
|
|
5074
5111
|
* allowed values */
|
|
5075
|
-
if (!meta ||
|
|
5112
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes))
|
|
5076
5113
|
return;
|
|
5077
5114
|
/* check all boolean attributes */
|
|
5078
5115
|
for (const attr of node.attributes) {
|
|
@@ -5160,10 +5197,10 @@ class AttributeMisuse extends Rule {
|
|
|
5160
5197
|
});
|
|
5161
5198
|
}
|
|
5162
5199
|
validateAttr(node, attr, meta) {
|
|
5163
|
-
if (!meta ||
|
|
5200
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.allowed)) {
|
|
5164
5201
|
return;
|
|
5165
5202
|
}
|
|
5166
|
-
const details = meta.allowed(node, attr);
|
|
5203
|
+
const details = meta.allowed(node._adapter, attr.value);
|
|
5167
5204
|
if (details) {
|
|
5168
5205
|
this.report({
|
|
5169
5206
|
node,
|
|
@@ -5204,12 +5241,12 @@ function describePattern(pattern) {
|
|
|
5204
5241
|
}
|
|
5205
5242
|
}
|
|
5206
5243
|
|
|
5207
|
-
const defaults$
|
|
5244
|
+
const defaults$n = {
|
|
5208
5245
|
pattern: "kebabcase",
|
|
5209
5246
|
};
|
|
5210
5247
|
class ClassPattern extends Rule {
|
|
5211
5248
|
constructor(options) {
|
|
5212
|
-
super({ ...defaults$
|
|
5249
|
+
super({ ...defaults$n, ...options });
|
|
5213
5250
|
this.pattern = parsePattern(this.options.pattern);
|
|
5214
5251
|
}
|
|
5215
5252
|
static schema() {
|
|
@@ -5318,13 +5355,13 @@ class CloseOrder extends Rule {
|
|
|
5318
5355
|
}
|
|
5319
5356
|
}
|
|
5320
5357
|
|
|
5321
|
-
const defaults$
|
|
5358
|
+
const defaults$m = {
|
|
5322
5359
|
include: null,
|
|
5323
5360
|
exclude: null,
|
|
5324
5361
|
};
|
|
5325
5362
|
class Deprecated extends Rule {
|
|
5326
5363
|
constructor(options) {
|
|
5327
|
-
super({ ...defaults$
|
|
5364
|
+
super({ ...defaults$m, ...options });
|
|
5328
5365
|
}
|
|
5329
5366
|
static schema() {
|
|
5330
5367
|
return {
|
|
@@ -5487,12 +5524,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
|
|
|
5487
5524
|
}
|
|
5488
5525
|
};
|
|
5489
5526
|
|
|
5490
|
-
const defaults$
|
|
5527
|
+
const defaults$l = {
|
|
5491
5528
|
style: "uppercase",
|
|
5492
5529
|
};
|
|
5493
5530
|
class DoctypeStyle extends Rule {
|
|
5494
5531
|
constructor(options) {
|
|
5495
|
-
super({ ...defaults$
|
|
5532
|
+
super({ ...defaults$l, ...options });
|
|
5496
5533
|
}
|
|
5497
5534
|
static schema() {
|
|
5498
5535
|
return {
|
|
@@ -5524,12 +5561,12 @@ class DoctypeStyle extends Rule {
|
|
|
5524
5561
|
}
|
|
5525
5562
|
}
|
|
5526
5563
|
|
|
5527
|
-
const defaults$
|
|
5564
|
+
const defaults$k = {
|
|
5528
5565
|
style: "lowercase",
|
|
5529
5566
|
};
|
|
5530
5567
|
class ElementCase extends Rule {
|
|
5531
5568
|
constructor(options) {
|
|
5532
|
-
super({ ...defaults$
|
|
5569
|
+
super({ ...defaults$k, ...options });
|
|
5533
5570
|
this.style = new CaseStyle(this.options.style, "element-case");
|
|
5534
5571
|
}
|
|
5535
5572
|
static schema() {
|
|
@@ -5595,14 +5632,14 @@ class ElementCase extends Rule {
|
|
|
5595
5632
|
}
|
|
5596
5633
|
}
|
|
5597
5634
|
|
|
5598
|
-
const defaults$
|
|
5635
|
+
const defaults$j = {
|
|
5599
5636
|
pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
|
|
5600
5637
|
whitelist: [],
|
|
5601
5638
|
blacklist: [],
|
|
5602
5639
|
};
|
|
5603
5640
|
class ElementName extends Rule {
|
|
5604
5641
|
constructor(options) {
|
|
5605
|
-
super({ ...defaults$
|
|
5642
|
+
super({ ...defaults$j, ...options });
|
|
5606
5643
|
/* eslint-disable-next-line security/detect-non-literal-regexp -- expected to be a regexp */
|
|
5607
5644
|
this.pattern = new RegExp(this.options.pattern);
|
|
5608
5645
|
}
|
|
@@ -5643,7 +5680,7 @@ class ElementName extends Rule {
|
|
|
5643
5680
|
...context.blacklist.map((cur) => `- ${cur}`),
|
|
5644
5681
|
];
|
|
5645
5682
|
}
|
|
5646
|
-
if (context.pattern !== defaults$
|
|
5683
|
+
if (context.pattern !== defaults$j.pattern) {
|
|
5647
5684
|
return [
|
|
5648
5685
|
`<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
|
|
5649
5686
|
"",
|
|
@@ -5834,7 +5871,7 @@ class ElementPermittedOccurrences extends Rule {
|
|
|
5834
5871
|
this.on("dom:ready", (event) => {
|
|
5835
5872
|
const doc = event.document;
|
|
5836
5873
|
doc.visitDepthFirst((node) => {
|
|
5837
|
-
if (!node ||
|
|
5874
|
+
if (!(node === null || node === void 0 ? void 0 : node.meta)) {
|
|
5838
5875
|
return;
|
|
5839
5876
|
}
|
|
5840
5877
|
const rules = node.meta.permittedContent;
|
|
@@ -5879,7 +5916,7 @@ function isCategoryOrTag(value) {
|
|
|
5879
5916
|
return typeof value === "string";
|
|
5880
5917
|
}
|
|
5881
5918
|
function isCategory$1(value) {
|
|
5882
|
-
return value
|
|
5919
|
+
return value.startsWith("@");
|
|
5883
5920
|
}
|
|
5884
5921
|
function formatCategoryOrTag(value) {
|
|
5885
5922
|
return isCategory$1(value) ? value.slice(1) : `<${value}>`;
|
|
@@ -6039,7 +6076,7 @@ class ElementRequiredAttributes extends Rule {
|
|
|
6039
6076
|
const node = event.previous;
|
|
6040
6077
|
const meta = node.meta;
|
|
6041
6078
|
/* handle missing metadata and missing attributes */
|
|
6042
|
-
if (!meta ||
|
|
6079
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes)) {
|
|
6043
6080
|
return;
|
|
6044
6081
|
}
|
|
6045
6082
|
for (const [key, attr] of Object.entries(meta.attributes)) {
|
|
@@ -6059,7 +6096,7 @@ class ElementRequiredAttributes extends Rule {
|
|
|
6059
6096
|
}
|
|
6060
6097
|
|
|
6061
6098
|
function isCategory(value) {
|
|
6062
|
-
return value
|
|
6099
|
+
return value.startsWith("@");
|
|
6063
6100
|
}
|
|
6064
6101
|
class ElementRequiredContent extends Rule {
|
|
6065
6102
|
documentation(context) {
|
|
@@ -6187,7 +6224,7 @@ class EmptyTitle extends Rule {
|
|
|
6187
6224
|
}
|
|
6188
6225
|
}
|
|
6189
6226
|
|
|
6190
|
-
const defaults$
|
|
6227
|
+
const defaults$i = {
|
|
6191
6228
|
allowArrayBrackets: true,
|
|
6192
6229
|
shared: ["radio", "button", "reset", "submit"],
|
|
6193
6230
|
};
|
|
@@ -6220,7 +6257,7 @@ function getDocumentation(context) {
|
|
|
6220
6257
|
}
|
|
6221
6258
|
class FormDupName extends Rule {
|
|
6222
6259
|
constructor(options) {
|
|
6223
|
-
super({ ...defaults$
|
|
6260
|
+
super({ ...defaults$i, ...options });
|
|
6224
6261
|
}
|
|
6225
6262
|
static schema() {
|
|
6226
6263
|
return {
|
|
@@ -6351,7 +6388,7 @@ class FormDupName extends Rule {
|
|
|
6351
6388
|
const meta = this.getMetaFor(tagName);
|
|
6352
6389
|
/* istanbul ignore if: the earlier check for getTagsWithProperty ensures
|
|
6353
6390
|
* these will actually be set so this is just an untestable fallback */
|
|
6354
|
-
if (!meta ||
|
|
6391
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.formAssociated)) {
|
|
6355
6392
|
return false;
|
|
6356
6393
|
}
|
|
6357
6394
|
return meta.formAssociated.listed;
|
|
@@ -6380,7 +6417,7 @@ class FormDupName extends Rule {
|
|
|
6380
6417
|
}
|
|
6381
6418
|
}
|
|
6382
6419
|
|
|
6383
|
-
const defaults$
|
|
6420
|
+
const defaults$h = {
|
|
6384
6421
|
allowMultipleH1: false,
|
|
6385
6422
|
minInitialRank: "h1",
|
|
6386
6423
|
sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]'],
|
|
@@ -6411,7 +6448,7 @@ function parseMaxInitial(value) {
|
|
|
6411
6448
|
}
|
|
6412
6449
|
class HeadingLevel extends Rule {
|
|
6413
6450
|
constructor(options) {
|
|
6414
|
-
super({ ...defaults$
|
|
6451
|
+
super({ ...defaults$h, ...options });
|
|
6415
6452
|
this.stack = [];
|
|
6416
6453
|
this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
|
|
6417
6454
|
this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
|
|
@@ -6453,9 +6490,15 @@ class HeadingLevel extends Rule {
|
|
|
6453
6490
|
};
|
|
6454
6491
|
}
|
|
6455
6492
|
setup() {
|
|
6456
|
-
this.on("tag:start", isRelevant$3, (event) =>
|
|
6457
|
-
|
|
6458
|
-
|
|
6493
|
+
this.on("tag:start", isRelevant$3, (event) => {
|
|
6494
|
+
this.onTagStart(event);
|
|
6495
|
+
});
|
|
6496
|
+
this.on("tag:ready", (event) => {
|
|
6497
|
+
this.onTagReady(event);
|
|
6498
|
+
});
|
|
6499
|
+
this.on("tag:close", (event) => {
|
|
6500
|
+
this.onTagClose(event);
|
|
6501
|
+
});
|
|
6459
6502
|
}
|
|
6460
6503
|
onTagStart(event) {
|
|
6461
6504
|
/* extract heading level from tagName (e.g "h1" -> 1)*/
|
|
@@ -6569,12 +6612,12 @@ class HeadingLevel extends Rule {
|
|
|
6569
6612
|
}
|
|
6570
6613
|
}
|
|
6571
6614
|
|
|
6572
|
-
const defaults$
|
|
6615
|
+
const defaults$g = {
|
|
6573
6616
|
pattern: "kebabcase",
|
|
6574
6617
|
};
|
|
6575
6618
|
class IdPattern extends Rule {
|
|
6576
6619
|
constructor(options) {
|
|
6577
|
-
super({ ...defaults$
|
|
6620
|
+
super({ ...defaults$g, ...options });
|
|
6578
6621
|
this.pattern = parsePattern(this.options.pattern);
|
|
6579
6622
|
}
|
|
6580
6623
|
static schema() {
|
|
@@ -6593,7 +6636,7 @@ class IdPattern extends Rule {
|
|
|
6593
6636
|
}
|
|
6594
6637
|
setup() {
|
|
6595
6638
|
this.on("attr", (event) => {
|
|
6596
|
-
var _a;
|
|
6639
|
+
var _a, _b;
|
|
6597
6640
|
if (event.key.toLowerCase() !== "id") {
|
|
6598
6641
|
return;
|
|
6599
6642
|
}
|
|
@@ -6601,8 +6644,8 @@ class IdPattern extends Rule {
|
|
|
6601
6644
|
if (event.value instanceof DynamicValue) {
|
|
6602
6645
|
return;
|
|
6603
6646
|
}
|
|
6604
|
-
if (!event.value ||
|
|
6605
|
-
const value = (
|
|
6647
|
+
if (!((_a = event.value) === null || _a === void 0 ? void 0 : _a.match(this.pattern))) {
|
|
6648
|
+
const value = (_b = event.value) !== null && _b !== void 0 ? _b : "";
|
|
6606
6649
|
const pattern = this.pattern.toString();
|
|
6607
6650
|
const message = `ID "${value}" does not match required pattern "${pattern}"`;
|
|
6608
6651
|
this.report(event.target, message, event.valueLocation);
|
|
@@ -6976,12 +7019,12 @@ function findLabelByParent(el) {
|
|
|
6976
7019
|
return [];
|
|
6977
7020
|
}
|
|
6978
7021
|
|
|
6979
|
-
const defaults$
|
|
7022
|
+
const defaults$f = {
|
|
6980
7023
|
maxlength: 70,
|
|
6981
7024
|
};
|
|
6982
7025
|
class LongTitle extends Rule {
|
|
6983
7026
|
constructor(options) {
|
|
6984
|
-
super({ ...defaults$
|
|
7027
|
+
super({ ...defaults$f, ...options });
|
|
6985
7028
|
this.maxlength = this.options.maxlength;
|
|
6986
7029
|
}
|
|
6987
7030
|
static schema() {
|
|
@@ -7030,7 +7073,7 @@ class MetaRefresh extends Rule {
|
|
|
7030
7073
|
}
|
|
7031
7074
|
/* ensure content attribute is set */
|
|
7032
7075
|
const content = target.getAttribute("content");
|
|
7033
|
-
if (!content ||
|
|
7076
|
+
if (!(content === null || content === void 0 ? void 0 : content.value) || content.isDynamic) {
|
|
7034
7077
|
return;
|
|
7035
7078
|
}
|
|
7036
7079
|
/* ensure content attribute is valid */
|
|
@@ -7207,13 +7250,13 @@ class MultipleLabeledControls extends Rule {
|
|
|
7207
7250
|
}
|
|
7208
7251
|
}
|
|
7209
7252
|
|
|
7210
|
-
const defaults$
|
|
7253
|
+
const defaults$e = {
|
|
7211
7254
|
include: null,
|
|
7212
7255
|
exclude: null,
|
|
7213
7256
|
};
|
|
7214
7257
|
class NoAutoplay extends Rule {
|
|
7215
7258
|
constructor(options) {
|
|
7216
|
-
super({ ...defaults$
|
|
7259
|
+
super({ ...defaults$e, ...options });
|
|
7217
7260
|
}
|
|
7218
7261
|
documentation(context) {
|
|
7219
7262
|
const tagName = context ? ` on <${context.tagName}>` : "";
|
|
@@ -7309,7 +7352,7 @@ class NoDeprecatedAttr extends Rule {
|
|
|
7309
7352
|
if (meta === null) {
|
|
7310
7353
|
return;
|
|
7311
7354
|
}
|
|
7312
|
-
const metaAttribute = meta.attributes
|
|
7355
|
+
const metaAttribute = meta.attributes[attr];
|
|
7313
7356
|
if (!metaAttribute) {
|
|
7314
7357
|
return;
|
|
7315
7358
|
}
|
|
@@ -7389,7 +7432,7 @@ class NoDupID extends Rule {
|
|
|
7389
7432
|
for (const el of relevant) {
|
|
7390
7433
|
const attr = el.getAttribute("id");
|
|
7391
7434
|
/* istanbul ignore next: this has already been tested in isRelevant once but for type-safety it is checked again */
|
|
7392
|
-
if (!attr ||
|
|
7435
|
+
if (!(attr === null || attr === void 0 ? void 0 : attr.value)) {
|
|
7393
7436
|
continue;
|
|
7394
7437
|
}
|
|
7395
7438
|
const id = attr.value.toString();
|
|
@@ -7454,14 +7497,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
7454
7497
|
}
|
|
7455
7498
|
}
|
|
7456
7499
|
|
|
7457
|
-
const defaults$
|
|
7500
|
+
const defaults$d = {
|
|
7458
7501
|
include: null,
|
|
7459
7502
|
exclude: null,
|
|
7460
7503
|
allowedProperties: ["display"],
|
|
7461
7504
|
};
|
|
7462
7505
|
class NoInlineStyle extends Rule {
|
|
7463
7506
|
constructor(options) {
|
|
7464
|
-
super({ ...defaults$
|
|
7507
|
+
super({ ...defaults$d, ...options });
|
|
7465
7508
|
}
|
|
7466
7509
|
static schema() {
|
|
7467
7510
|
return {
|
|
@@ -7523,11 +7566,12 @@ class NoInlineStyle extends Rule {
|
|
|
7523
7566
|
});
|
|
7524
7567
|
}
|
|
7525
7568
|
isRelevant(event) {
|
|
7569
|
+
var _a;
|
|
7526
7570
|
if (event.key !== "style") {
|
|
7527
7571
|
return false;
|
|
7528
7572
|
}
|
|
7529
7573
|
const { include, exclude } = this.options;
|
|
7530
|
-
const key = event.originalAttribute
|
|
7574
|
+
const key = (_a = event.originalAttribute) !== null && _a !== void 0 ? _a : event.key;
|
|
7531
7575
|
/* ignore attributes not present in "include" */
|
|
7532
7576
|
if (include && !include.includes(key)) {
|
|
7533
7577
|
return false;
|
|
@@ -7663,7 +7707,7 @@ class NoMultipleMain extends Rule {
|
|
|
7663
7707
|
}
|
|
7664
7708
|
}
|
|
7665
7709
|
|
|
7666
|
-
const defaults$
|
|
7710
|
+
const defaults$c = {
|
|
7667
7711
|
relaxed: false,
|
|
7668
7712
|
};
|
|
7669
7713
|
const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
|
|
@@ -7680,7 +7724,7 @@ const replacementTable = {
|
|
|
7680
7724
|
};
|
|
7681
7725
|
class NoRawCharacters extends Rule {
|
|
7682
7726
|
constructor(options) {
|
|
7683
|
-
super({ ...defaults$
|
|
7727
|
+
super({ ...defaults$c, ...options });
|
|
7684
7728
|
this.relaxed = this.options.relaxed;
|
|
7685
7729
|
}
|
|
7686
7730
|
static schema() {
|
|
@@ -7721,7 +7765,8 @@ class NoRawCharacters extends Rule {
|
|
|
7721
7765
|
if (event.quote) {
|
|
7722
7766
|
return;
|
|
7723
7767
|
}
|
|
7724
|
-
this.findRawChars(event.target, event.value.toString(), event.valueLocation,
|
|
7768
|
+
this.findRawChars(event.target, event.value.toString(), event.valueLocation, // eslint-disable-line @typescript-eslint/no-non-null-assertion -- technical debt, valueLocation is always set if a value is provided
|
|
7769
|
+
unquotedAttrRegexp);
|
|
7725
7770
|
});
|
|
7726
7771
|
}
|
|
7727
7772
|
/**
|
|
@@ -7754,6 +7799,39 @@ class NoRawCharacters extends Rule {
|
|
|
7754
7799
|
}
|
|
7755
7800
|
}
|
|
7756
7801
|
|
|
7802
|
+
const selectors = ["input[aria-label]", "textarea[aria-label]", "select[aria-label]"];
|
|
7803
|
+
class NoRedundantAriaLabel extends Rule {
|
|
7804
|
+
documentation() {
|
|
7805
|
+
return {
|
|
7806
|
+
description: "`aria-label` is redundant when an associated `<label>` element containing the same text exists.",
|
|
7807
|
+
url: "https://html-validate.org/rules/no-redundant-aria-label.html",
|
|
7808
|
+
};
|
|
7809
|
+
}
|
|
7810
|
+
setup() {
|
|
7811
|
+
this.on("dom:ready", (event) => {
|
|
7812
|
+
const { document } = event;
|
|
7813
|
+
const elements = document.querySelectorAll(selectors.join(","));
|
|
7814
|
+
for (const element of elements) {
|
|
7815
|
+
const ariaLabel = element.getAttribute("aria-label");
|
|
7816
|
+
const id = element.id;
|
|
7817
|
+
if (!id) {
|
|
7818
|
+
continue;
|
|
7819
|
+
}
|
|
7820
|
+
const label = document.querySelector(`label[for="${id}"]`);
|
|
7821
|
+
if (!ariaLabel || !label || label.textContent.trim() !== ariaLabel.value) {
|
|
7822
|
+
continue;
|
|
7823
|
+
}
|
|
7824
|
+
const message = "aria-label is redundant when label containing same text exists";
|
|
7825
|
+
this.report({
|
|
7826
|
+
message,
|
|
7827
|
+
node: element,
|
|
7828
|
+
location: ariaLabel.keyLocation,
|
|
7829
|
+
});
|
|
7830
|
+
}
|
|
7831
|
+
});
|
|
7832
|
+
}
|
|
7833
|
+
}
|
|
7834
|
+
|
|
7757
7835
|
class NoRedundantFor extends Rule {
|
|
7758
7836
|
documentation() {
|
|
7759
7837
|
return {
|
|
@@ -7858,13 +7936,13 @@ class NoRedundantRole extends Rule {
|
|
|
7858
7936
|
}
|
|
7859
7937
|
|
|
7860
7938
|
const xmlns = /^(.+):.+$/;
|
|
7861
|
-
const defaults$
|
|
7939
|
+
const defaults$b = {
|
|
7862
7940
|
ignoreForeign: true,
|
|
7863
7941
|
ignoreXML: true,
|
|
7864
7942
|
};
|
|
7865
7943
|
class NoSelfClosing extends Rule {
|
|
7866
7944
|
constructor(options) {
|
|
7867
|
-
super({ ...defaults$
|
|
7945
|
+
super({ ...defaults$b, ...options });
|
|
7868
7946
|
}
|
|
7869
7947
|
static schema() {
|
|
7870
7948
|
return {
|
|
@@ -7902,7 +7980,7 @@ class NoSelfClosing extends Rule {
|
|
|
7902
7980
|
function isRelevant(node, options) {
|
|
7903
7981
|
/* tags in XML namespaces are relevant only if ignoreXml is false, in which
|
|
7904
7982
|
* case assume all xml elements must not be self-closed */
|
|
7905
|
-
if (node.tagName
|
|
7983
|
+
if (node.tagName.match(xmlns)) {
|
|
7906
7984
|
return !options.ignoreXML;
|
|
7907
7985
|
}
|
|
7908
7986
|
/* nodes with missing metadata is assumed relevant */
|
|
@@ -7953,13 +8031,13 @@ class NoTrailingWhitespace extends Rule {
|
|
|
7953
8031
|
}
|
|
7954
8032
|
}
|
|
7955
8033
|
|
|
7956
|
-
const defaults$
|
|
8034
|
+
const defaults$a = {
|
|
7957
8035
|
include: null,
|
|
7958
8036
|
exclude: null,
|
|
7959
8037
|
};
|
|
7960
8038
|
class NoUnknownElements extends Rule {
|
|
7961
8039
|
constructor(options) {
|
|
7962
|
-
super({ ...defaults$
|
|
8040
|
+
super({ ...defaults$a, ...options });
|
|
7963
8041
|
}
|
|
7964
8042
|
static schema() {
|
|
7965
8043
|
return {
|
|
@@ -8015,9 +8093,7 @@ class NoUnknownElements extends Rule {
|
|
|
8015
8093
|
class NoUnusedDisable extends Rule {
|
|
8016
8094
|
documentation(context) {
|
|
8017
8095
|
return {
|
|
8018
|
-
description: context
|
|
8019
|
-
? `\`${context.ruleId}\` rule is disabled but no error was reported.`
|
|
8020
|
-
: "Rule is disabled but no error was reported.",
|
|
8096
|
+
description: `\`${context.ruleId}\` rule is disabled but no error was reported.`,
|
|
8021
8097
|
url: "https://html-validate.org/rules/no-unused-disable.html",
|
|
8022
8098
|
};
|
|
8023
8099
|
}
|
|
@@ -8071,13 +8147,13 @@ const replacement = {
|
|
|
8071
8147
|
reset: '<button type="reset">',
|
|
8072
8148
|
image: '<button type="button">',
|
|
8073
8149
|
};
|
|
8074
|
-
const defaults$
|
|
8150
|
+
const defaults$9 = {
|
|
8075
8151
|
include: null,
|
|
8076
8152
|
exclude: null,
|
|
8077
8153
|
};
|
|
8078
8154
|
class PreferButton extends Rule {
|
|
8079
8155
|
constructor(options) {
|
|
8080
|
-
super({ ...defaults$
|
|
8156
|
+
super({ ...defaults$9, ...options });
|
|
8081
8157
|
}
|
|
8082
8158
|
static schema() {
|
|
8083
8159
|
return {
|
|
@@ -8110,16 +8186,12 @@ class PreferButton extends Rule {
|
|
|
8110
8186
|
};
|
|
8111
8187
|
}
|
|
8112
8188
|
documentation(context) {
|
|
8113
|
-
const
|
|
8114
|
-
|
|
8189
|
+
const src = `<input type="${context.type}">`;
|
|
8190
|
+
const dst = replacement[context.type] || `<button>`;
|
|
8191
|
+
return {
|
|
8192
|
+
description: `Prefer to use \`${dst}\` instead of \`"${src}\`.`,
|
|
8115
8193
|
url: "https://html-validate.org/rules/prefer-button.html",
|
|
8116
8194
|
};
|
|
8117
|
-
if (context) {
|
|
8118
|
-
const src = `<input type="${context.type}">`;
|
|
8119
|
-
const dst = replacement[context.type] || `<button>`;
|
|
8120
|
-
doc.description = `Prefer to use \`${dst}\` instead of \`"${src}\`.`;
|
|
8121
|
-
}
|
|
8122
|
-
return doc;
|
|
8123
8195
|
}
|
|
8124
8196
|
setup() {
|
|
8125
8197
|
this.on("attr", (event) => {
|
|
@@ -8152,7 +8224,7 @@ class PreferButton extends Rule {
|
|
|
8152
8224
|
}
|
|
8153
8225
|
}
|
|
8154
8226
|
|
|
8155
|
-
const defaults$
|
|
8227
|
+
const defaults$8 = {
|
|
8156
8228
|
mapping: {
|
|
8157
8229
|
article: "article",
|
|
8158
8230
|
banner: "header",
|
|
@@ -8182,7 +8254,7 @@ const defaults$9 = {
|
|
|
8182
8254
|
};
|
|
8183
8255
|
class PreferNativeElement extends Rule {
|
|
8184
8256
|
constructor(options) {
|
|
8185
|
-
super({ ...defaults$
|
|
8257
|
+
super({ ...defaults$8, ...options });
|
|
8186
8258
|
}
|
|
8187
8259
|
static schema() {
|
|
8188
8260
|
return {
|
|
@@ -8218,14 +8290,10 @@ class PreferNativeElement extends Rule {
|
|
|
8218
8290
|
};
|
|
8219
8291
|
}
|
|
8220
8292
|
documentation(context) {
|
|
8221
|
-
|
|
8222
|
-
description: `Instead of using WAI-ARIA
|
|
8293
|
+
return {
|
|
8294
|
+
description: `Instead of using the WAI-ARIA role "${context.role}" prefer to use the native <${context.replacement}> element.`,
|
|
8223
8295
|
url: "https://html-validate.org/rules/prefer-native-element.html",
|
|
8224
8296
|
};
|
|
8225
|
-
if (context) {
|
|
8226
|
-
doc.description = `Instead of using the WAI-ARIA role "${context.role}" prefer to use the native <${context.replacement}> element.`;
|
|
8227
|
-
}
|
|
8228
|
-
return doc;
|
|
8229
8297
|
}
|
|
8230
8298
|
setup() {
|
|
8231
8299
|
const { mapping } = this.options;
|
|
@@ -8266,7 +8334,7 @@ class PreferNativeElement extends Rule {
|
|
|
8266
8334
|
}
|
|
8267
8335
|
getLocation(event) {
|
|
8268
8336
|
const begin = event.location;
|
|
8269
|
-
const end = event.valueLocation;
|
|
8337
|
+
const end = event.valueLocation; // eslint-disable-line @typescript-eslint/no-non-null-assertion -- technical debt, valueLocation will always be set when a value is provided
|
|
8270
8338
|
const quote = event.quote ? 1 : 0;
|
|
8271
8339
|
const size = end.offset + end.size - begin.offset + quote;
|
|
8272
8340
|
return {
|
|
@@ -8302,12 +8370,12 @@ class PreferTbody extends Rule {
|
|
|
8302
8370
|
}
|
|
8303
8371
|
}
|
|
8304
8372
|
|
|
8305
|
-
const defaults$
|
|
8373
|
+
const defaults$7 = {
|
|
8306
8374
|
tags: ["script", "style"],
|
|
8307
8375
|
};
|
|
8308
8376
|
class RequireCSPNonce extends Rule {
|
|
8309
8377
|
constructor(options) {
|
|
8310
|
-
super({ ...defaults$
|
|
8378
|
+
super({ ...defaults$7, ...options });
|
|
8311
8379
|
}
|
|
8312
8380
|
static schema() {
|
|
8313
8381
|
return {
|
|
@@ -8340,7 +8408,7 @@ class RequireCSPNonce extends Rule {
|
|
|
8340
8408
|
const { tags } = this.options;
|
|
8341
8409
|
const node = event.previous;
|
|
8342
8410
|
/* ignore other tags */
|
|
8343
|
-
if (!
|
|
8411
|
+
if (!tags.includes(node.tagName)) {
|
|
8344
8412
|
return;
|
|
8345
8413
|
}
|
|
8346
8414
|
/* ignore if nonce is set to non-empty value (or dynamic) */
|
|
@@ -8358,7 +8426,7 @@ class RequireCSPNonce extends Rule {
|
|
|
8358
8426
|
}
|
|
8359
8427
|
}
|
|
8360
8428
|
|
|
8361
|
-
const defaults$
|
|
8429
|
+
const defaults$6 = {
|
|
8362
8430
|
target: "all",
|
|
8363
8431
|
include: null,
|
|
8364
8432
|
exclude: null,
|
|
@@ -8370,7 +8438,7 @@ const supportSri = {
|
|
|
8370
8438
|
};
|
|
8371
8439
|
class RequireSri extends Rule {
|
|
8372
8440
|
constructor(options) {
|
|
8373
|
-
super({ ...defaults$
|
|
8441
|
+
super({ ...defaults$6, ...options });
|
|
8374
8442
|
this.target = this.options.target;
|
|
8375
8443
|
}
|
|
8376
8444
|
static schema() {
|
|
@@ -8432,7 +8500,10 @@ class RequireSri extends Rule {
|
|
|
8432
8500
|
}
|
|
8433
8501
|
needSri(node) {
|
|
8434
8502
|
const attr = this.elementSourceAttr(node);
|
|
8435
|
-
if (!attr
|
|
8503
|
+
if (!attr) {
|
|
8504
|
+
return false;
|
|
8505
|
+
}
|
|
8506
|
+
if (attr.value === null || attr.value === "" || attr.isDynamic) {
|
|
8436
8507
|
return false;
|
|
8437
8508
|
}
|
|
8438
8509
|
const url = attr.value.toString();
|
|
@@ -8489,7 +8560,7 @@ class ScriptType extends Rule {
|
|
|
8489
8560
|
setup() {
|
|
8490
8561
|
this.on("tag:end", (event) => {
|
|
8491
8562
|
const node = event.previous;
|
|
8492
|
-
if (
|
|
8563
|
+
if (node.tagName !== "script") {
|
|
8493
8564
|
return;
|
|
8494
8565
|
}
|
|
8495
8566
|
const attr = node.getAttribute("type");
|
|
@@ -8532,7 +8603,7 @@ class SvgFocusable extends Rule {
|
|
|
8532
8603
|
}
|
|
8533
8604
|
}
|
|
8534
8605
|
|
|
8535
|
-
const defaults$
|
|
8606
|
+
const defaults$5 = {
|
|
8536
8607
|
characters: [
|
|
8537
8608
|
{ pattern: " ", replacement: " ", description: "non-breaking space" },
|
|
8538
8609
|
{ pattern: "-", replacement: "‑", description: "non-breaking hyphen" },
|
|
@@ -8571,7 +8642,7 @@ function matchAll(text, regexp) {
|
|
|
8571
8642
|
}
|
|
8572
8643
|
class TelNonBreaking extends Rule {
|
|
8573
8644
|
constructor(options) {
|
|
8574
|
-
super({ ...defaults$
|
|
8645
|
+
super({ ...defaults$5, ...options });
|
|
8575
8646
|
this.regex = constructRegex(this.options.characters);
|
|
8576
8647
|
}
|
|
8577
8648
|
static schema() {
|
|
@@ -8612,9 +8683,7 @@ class TelNonBreaking extends Rule {
|
|
|
8612
8683
|
});
|
|
8613
8684
|
return {
|
|
8614
8685
|
description: [
|
|
8615
|
-
context
|
|
8616
|
-
? `The \`${context.pattern}\` character should be replaced with \`${context.replacement}\` character (${context.description}) when used in a telephone number.`
|
|
8617
|
-
: `Replace this character with a non-breaking version.`,
|
|
8686
|
+
`The \`${context.pattern}\` character should be replaced with \`${context.replacement}\` character (${context.description}) when used in a telephone number.`,
|
|
8618
8687
|
"",
|
|
8619
8688
|
"Unless non-breaking characters is used there could be a line break inserted at that character.",
|
|
8620
8689
|
"Line breaks make is harder to read and understand the telephone number.",
|
|
@@ -8772,18 +8841,16 @@ class TextContent extends Rule {
|
|
|
8772
8841
|
description: `The textual content for this element is not valid.`,
|
|
8773
8842
|
url: "https://html-validate.org/rules/text-content.html",
|
|
8774
8843
|
};
|
|
8775
|
-
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
|
|
8782
|
-
|
|
8783
|
-
|
|
8784
|
-
|
|
8785
|
-
break;
|
|
8786
|
-
}
|
|
8844
|
+
switch (context.textContent) {
|
|
8845
|
+
case exports.TextContent.NONE:
|
|
8846
|
+
doc.description = `The \`<${context.tagName}>\` element must not have textual content.`;
|
|
8847
|
+
break;
|
|
8848
|
+
case exports.TextContent.REQUIRED:
|
|
8849
|
+
doc.description = `The \`<${context.tagName}>\` element must have textual content.`;
|
|
8850
|
+
break;
|
|
8851
|
+
case exports.TextContent.ACCESSIBLE:
|
|
8852
|
+
doc.description = `The \`<${context.tagName}>\` element must have accessible text.`;
|
|
8853
|
+
break;
|
|
8787
8854
|
}
|
|
8788
8855
|
return doc;
|
|
8789
8856
|
}
|
|
@@ -8859,7 +8926,7 @@ class TextContent extends Rule {
|
|
|
8859
8926
|
}
|
|
8860
8927
|
}
|
|
8861
8928
|
|
|
8862
|
-
const defaults$
|
|
8929
|
+
const defaults$4 = {
|
|
8863
8930
|
ignoreCase: false,
|
|
8864
8931
|
requireSemicolon: true,
|
|
8865
8932
|
};
|
|
@@ -8877,16 +8944,11 @@ function getLocation(location, entity, match) {
|
|
|
8877
8944
|
function getDescription(context, options) {
|
|
8878
8945
|
const url = "https://html.spec.whatwg.org/multipage/named-characters.html";
|
|
8879
8946
|
let message;
|
|
8880
|
-
if (context) {
|
|
8881
|
-
|
|
8882
|
-
message = `Unrecognized character reference \`${context.entity}\`.`;
|
|
8883
|
-
}
|
|
8884
|
-
else {
|
|
8885
|
-
message = `Character reference \`${context.entity}\` must be terminated by a semicolon.`;
|
|
8886
|
-
}
|
|
8947
|
+
if (context.terminated) {
|
|
8948
|
+
message = `Unrecognized character reference \`${context.entity}\`.`;
|
|
8887
8949
|
}
|
|
8888
8950
|
else {
|
|
8889
|
-
message = `
|
|
8951
|
+
message = `Character reference \`${context.entity}\` must be terminated by a semicolon.`;
|
|
8890
8952
|
}
|
|
8891
8953
|
return [
|
|
8892
8954
|
message,
|
|
@@ -8901,7 +8963,7 @@ function getDescription(context, options) {
|
|
|
8901
8963
|
}
|
|
8902
8964
|
class UnknownCharReference extends Rule {
|
|
8903
8965
|
constructor(options) {
|
|
8904
|
-
super({ ...defaults$
|
|
8966
|
+
super({ ...defaults$4, ...options });
|
|
8905
8967
|
}
|
|
8906
8968
|
static schema() {
|
|
8907
8969
|
return {
|
|
@@ -9018,12 +9080,12 @@ var RuleContext;
|
|
|
9018
9080
|
RuleContext[RuleContext["LEADING_CHARACTER"] = 3] = "LEADING_CHARACTER";
|
|
9019
9081
|
RuleContext[RuleContext["DISALLOWED_CHARACTER"] = 4] = "DISALLOWED_CHARACTER";
|
|
9020
9082
|
})(RuleContext || (RuleContext = {}));
|
|
9021
|
-
const defaults$
|
|
9083
|
+
const defaults$3 = {
|
|
9022
9084
|
relaxed: false,
|
|
9023
9085
|
};
|
|
9024
9086
|
class ValidID extends Rule {
|
|
9025
9087
|
constructor(options) {
|
|
9026
|
-
super({ ...defaults$
|
|
9088
|
+
super({ ...defaults$3, ...options });
|
|
9027
9089
|
}
|
|
9028
9090
|
static schema() {
|
|
9029
9091
|
return {
|
|
@@ -9034,9 +9096,9 @@ class ValidID extends Rule {
|
|
|
9034
9096
|
}
|
|
9035
9097
|
documentation(context) {
|
|
9036
9098
|
const { relaxed } = this.options;
|
|
9037
|
-
const message = context
|
|
9038
|
-
|
|
9039
|
-
|
|
9099
|
+
const message = this.messages[context]
|
|
9100
|
+
.replace("id", "ID")
|
|
9101
|
+
.replace(/^(.)/, (m) => m.toUpperCase());
|
|
9040
9102
|
const relaxedDescription = relaxed
|
|
9041
9103
|
? []
|
|
9042
9104
|
: [
|
|
@@ -9132,12 +9194,12 @@ var Style;
|
|
|
9132
9194
|
Style[Style["AlwaysOmit"] = 1] = "AlwaysOmit";
|
|
9133
9195
|
Style[Style["AlwaysSelfclose"] = 2] = "AlwaysSelfclose";
|
|
9134
9196
|
})(Style || (Style = {}));
|
|
9135
|
-
const defaults$
|
|
9197
|
+
const defaults$2 = {
|
|
9136
9198
|
style: "omit",
|
|
9137
9199
|
};
|
|
9138
9200
|
class VoidStyle extends Rule {
|
|
9139
9201
|
constructor(options) {
|
|
9140
|
-
super({ ...defaults$
|
|
9202
|
+
super({ ...defaults$2, ...options });
|
|
9141
9203
|
this.style = parseStyle(this.options.style);
|
|
9142
9204
|
}
|
|
9143
9205
|
static schema() {
|
|
@@ -9149,20 +9211,16 @@ class VoidStyle extends Rule {
|
|
|
9149
9211
|
};
|
|
9150
9212
|
}
|
|
9151
9213
|
documentation(context) {
|
|
9152
|
-
const
|
|
9153
|
-
|
|
9214
|
+
const [desc, end] = styleDescription(context.style);
|
|
9215
|
+
return {
|
|
9216
|
+
description: `The current configuration requires void elements to ${desc}, use <${context.tagName}${end}> instead.`,
|
|
9154
9217
|
url: "https://html-validate.org/rules/void-style.html",
|
|
9155
9218
|
};
|
|
9156
|
-
if (context) {
|
|
9157
|
-
const [desc, end] = styleDescription(context.style);
|
|
9158
|
-
doc.description = `The current configuration requires void elements to ${desc}, use <${context.tagName}${end}> instead.`;
|
|
9159
|
-
}
|
|
9160
|
-
return doc;
|
|
9161
9219
|
}
|
|
9162
9220
|
setup() {
|
|
9163
9221
|
this.on("tag:end", (event) => {
|
|
9164
9222
|
const active = event.previous; // The current active element (that is, the current element on the stack)
|
|
9165
|
-
if (active
|
|
9223
|
+
if (active.meta) {
|
|
9166
9224
|
this.validateActive(active);
|
|
9167
9225
|
}
|
|
9168
9226
|
});
|
|
@@ -9334,7 +9392,7 @@ class H36 extends Rule {
|
|
|
9334
9392
|
}
|
|
9335
9393
|
}
|
|
9336
9394
|
|
|
9337
|
-
const defaults$
|
|
9395
|
+
const defaults$1 = {
|
|
9338
9396
|
allowEmpty: true,
|
|
9339
9397
|
alias: [],
|
|
9340
9398
|
};
|
|
@@ -9355,7 +9413,7 @@ function getTag(node) {
|
|
|
9355
9413
|
}
|
|
9356
9414
|
class H37 extends Rule {
|
|
9357
9415
|
constructor(options) {
|
|
9358
|
-
super({ ...defaults$
|
|
9416
|
+
super({ ...defaults$1, ...options });
|
|
9359
9417
|
/* ensure alias is array */
|
|
9360
9418
|
if (!Array.isArray(this.options.alias)) {
|
|
9361
9419
|
this.options.alias = [this.options.alias];
|
|
@@ -9399,7 +9457,8 @@ class H37 extends Rule {
|
|
|
9399
9457
|
return;
|
|
9400
9458
|
}
|
|
9401
9459
|
/* validate plain alt-attribute */
|
|
9402
|
-
if (node.getAttributeValue("alt") ||
|
|
9460
|
+
if (Boolean(node.getAttributeValue("alt")) ||
|
|
9461
|
+
Boolean(node.hasAttribute("alt") && this.options.allowEmpty)) {
|
|
9403
9462
|
return;
|
|
9404
9463
|
}
|
|
9405
9464
|
/* validate if any non-empty alias is present */
|
|
@@ -9581,6 +9640,7 @@ const bundledRules = {
|
|
|
9581
9640
|
"no-missing-references": NoMissingReferences,
|
|
9582
9641
|
"no-multiple-main": NoMultipleMain,
|
|
9583
9642
|
"no-raw-characters": NoRawCharacters,
|
|
9643
|
+
"no-redundant-aria-label": NoRedundantAriaLabel,
|
|
9584
9644
|
"no-redundant-for": NoRedundantFor,
|
|
9585
9645
|
"no-redundant-role": NoRedundantRole,
|
|
9586
9646
|
"no-self-closing": NoSelfClosing,
|
|
@@ -9621,6 +9681,7 @@ const config$4 = {
|
|
|
9621
9681
|
"multiple-labeled-controls": "error",
|
|
9622
9682
|
"no-autoplay": ["error", { include: ["audio", "video"] }],
|
|
9623
9683
|
"no-dup-id": "error",
|
|
9684
|
+
"no-redundant-aria-label": "error",
|
|
9624
9685
|
"no-redundant-for": "error",
|
|
9625
9686
|
"no-redundant-role": "error",
|
|
9626
9687
|
"prefer-native-element": "error",
|
|
@@ -9703,6 +9764,7 @@ const config$1 = {
|
|
|
9703
9764
|
"no-inline-style": "error",
|
|
9704
9765
|
"no-multiple-main": "error",
|
|
9705
9766
|
"no-raw-characters": "error",
|
|
9767
|
+
"no-redundant-aria-label": "error",
|
|
9706
9768
|
"no-redundant-for": "error",
|
|
9707
9769
|
"no-redundant-role": "error",
|
|
9708
9770
|
"no-self-closing": "error",
|
|
@@ -9829,7 +9891,7 @@ class ResolvedConfig {
|
|
|
9829
9891
|
* @returns A list of transformed sources ready for validation.
|
|
9830
9892
|
*/
|
|
9831
9893
|
transformSource(source, filename) {
|
|
9832
|
-
const transformer = this.findTransformer(filename
|
|
9894
|
+
const transformer = this.findTransformer(filename !== null && filename !== void 0 ? filename : source.filename);
|
|
9833
9895
|
const context = {
|
|
9834
9896
|
hasChain: (filename) => {
|
|
9835
9897
|
return !!this.findTransformer(filename);
|
|
@@ -9841,9 +9903,10 @@ class ResolvedConfig {
|
|
|
9841
9903
|
if (transformer) {
|
|
9842
9904
|
try {
|
|
9843
9905
|
return Array.from(transformer.fn.call(context, source), (cur) => {
|
|
9906
|
+
var _a;
|
|
9844
9907
|
/* keep track of which transformers that has been run on this source
|
|
9845
9908
|
* by appending this entry to the transformedBy array */
|
|
9846
|
-
cur.transformedBy
|
|
9909
|
+
(_a = cur.transformedBy) !== null && _a !== void 0 ? _a : (cur.transformedBy = []);
|
|
9847
9910
|
cur.transformedBy.push(transformer.name);
|
|
9848
9911
|
return cur;
|
|
9849
9912
|
});
|
|
@@ -10015,7 +10078,7 @@ function mergeInternal(base, rhs) {
|
|
|
10015
10078
|
}
|
|
10016
10079
|
/* root property is merged with boolean "or" since it should always be truthy
|
|
10017
10080
|
* if any config has it set. */
|
|
10018
|
-
const root = base.root || rhs.root;
|
|
10081
|
+
const root = Boolean(base.root) || Boolean(rhs.root);
|
|
10019
10082
|
if (root) {
|
|
10020
10083
|
dst.root = root;
|
|
10021
10084
|
}
|
|
@@ -10102,7 +10165,7 @@ class Config {
|
|
|
10102
10165
|
* @internal
|
|
10103
10166
|
*/
|
|
10104
10167
|
constructor(resolvers, options) {
|
|
10105
|
-
var _a;
|
|
10168
|
+
var _a, _b;
|
|
10106
10169
|
this.transformers = [];
|
|
10107
10170
|
const initial = {
|
|
10108
10171
|
extends: [],
|
|
@@ -10115,18 +10178,18 @@ class Config {
|
|
|
10115
10178
|
this.initialized = false;
|
|
10116
10179
|
this.resolvers = toArray(resolvers);
|
|
10117
10180
|
/* load plugins */
|
|
10118
|
-
this.plugins = this.loadPlugins(this.config.plugins
|
|
10181
|
+
this.plugins = this.loadPlugins((_a = this.config.plugins) !== null && _a !== void 0 ? _a : []);
|
|
10119
10182
|
this.configurations = this.loadConfigurations(this.plugins);
|
|
10120
10183
|
this.extendMeta(this.plugins);
|
|
10121
10184
|
/* process extended configs */
|
|
10122
|
-
this.config = this.extendConfig((
|
|
10185
|
+
this.config = this.extendConfig((_b = this.config.extends) !== null && _b !== void 0 ? _b : []);
|
|
10123
10186
|
/* reset extends as we already processed them, this prevents the next config
|
|
10124
10187
|
* from reapplying config from extended config as well as duplicate entries
|
|
10125
10188
|
* when merging arrays */
|
|
10126
10189
|
this.config.extends = [];
|
|
10127
10190
|
/* rules explicitly set by passed options should have precedence over any
|
|
10128
10191
|
* extended rules, not the other way around. */
|
|
10129
|
-
if (options
|
|
10192
|
+
if (options === null || options === void 0 ? void 0 : options.rules) {
|
|
10130
10193
|
this.config = mergeInternal(this.config, { rules: options.rules });
|
|
10131
10194
|
}
|
|
10132
10195
|
}
|
|
@@ -10139,11 +10202,12 @@ class Config {
|
|
|
10139
10202
|
* @public
|
|
10140
10203
|
*/
|
|
10141
10204
|
init() {
|
|
10205
|
+
var _a;
|
|
10142
10206
|
if (this.initialized) {
|
|
10143
10207
|
return;
|
|
10144
10208
|
}
|
|
10145
10209
|
/* precompile transform patterns */
|
|
10146
|
-
this.transformers = this.precompileTransformers(this.config.transform
|
|
10210
|
+
this.transformers = this.precompileTransformers((_a = this.config.transform) !== null && _a !== void 0 ? _a : {});
|
|
10147
10211
|
this.initialized = true;
|
|
10148
10212
|
}
|
|
10149
10213
|
/**
|
|
@@ -10167,11 +10231,10 @@ class Config {
|
|
|
10167
10231
|
return this.config;
|
|
10168
10232
|
}
|
|
10169
10233
|
let base = {};
|
|
10170
|
-
for (
|
|
10171
|
-
const entry = entries[i];
|
|
10234
|
+
for (const entry of entries) {
|
|
10172
10235
|
let extended;
|
|
10173
10236
|
if (this.configurations.has(entry)) {
|
|
10174
|
-
extended = this.configurations.get(entry);
|
|
10237
|
+
extended = this.configurations.get(entry); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- map has/get combo
|
|
10175
10238
|
}
|
|
10176
10239
|
else {
|
|
10177
10240
|
extended = Config.fromFile(this.resolvers, entry).config;
|
|
@@ -10186,12 +10249,13 @@ class Config {
|
|
|
10186
10249
|
* @internal
|
|
10187
10250
|
*/
|
|
10188
10251
|
getMetaTable() {
|
|
10252
|
+
var _a;
|
|
10189
10253
|
/* use cached table if it exists */
|
|
10190
10254
|
if (this.metaTable) {
|
|
10191
10255
|
return this.metaTable;
|
|
10192
10256
|
}
|
|
10193
10257
|
const metaTable = new MetaTable();
|
|
10194
|
-
const source = this.config.elements
|
|
10258
|
+
const source = (_a = this.config.elements) !== null && _a !== void 0 ? _a : ["html5"];
|
|
10195
10259
|
/* extend validation schema from plugins */
|
|
10196
10260
|
for (const plugin of this.getPlugins()) {
|
|
10197
10261
|
if (plugin.elementSchema) {
|
|
@@ -10289,6 +10353,7 @@ class Config {
|
|
|
10289
10353
|
});
|
|
10290
10354
|
}
|
|
10291
10355
|
loadConfigurations(plugins) {
|
|
10356
|
+
var _a;
|
|
10292
10357
|
const configs = new Map();
|
|
10293
10358
|
/* builtin presets */
|
|
10294
10359
|
for (const [name, config] of Object.entries(Presets)) {
|
|
@@ -10297,7 +10362,7 @@ class Config {
|
|
|
10297
10362
|
}
|
|
10298
10363
|
/* presets from plugins */
|
|
10299
10364
|
for (const plugin of plugins) {
|
|
10300
|
-
for (const [name, config] of Object.entries(plugin.configs
|
|
10365
|
+
for (const [name, config] of Object.entries((_a = plugin.configs) !== null && _a !== void 0 ? _a : {})) {
|
|
10301
10366
|
if (!config)
|
|
10302
10367
|
continue;
|
|
10303
10368
|
Config.validate(config, name);
|
|
@@ -10662,10 +10727,11 @@ class Parser {
|
|
|
10662
10727
|
* stack when is allowed to omit.
|
|
10663
10728
|
*/
|
|
10664
10729
|
closeOptional(token) {
|
|
10730
|
+
var _a;
|
|
10665
10731
|
/* if the element doesn't have metadata it cannot have optional end
|
|
10666
10732
|
* tags. Period. */
|
|
10667
10733
|
const active = this.dom.getActive();
|
|
10668
|
-
if (!(active.meta
|
|
10734
|
+
if (!((_a = active.meta) === null || _a === void 0 ? void 0 : _a.implicitClosed)) {
|
|
10669
10735
|
return false;
|
|
10670
10736
|
}
|
|
10671
10737
|
const tagName = token.data[2];
|
|
@@ -10817,9 +10883,10 @@ class Parser {
|
|
|
10817
10883
|
}
|
|
10818
10884
|
}
|
|
10819
10885
|
processElement(node, source) {
|
|
10886
|
+
var _a;
|
|
10820
10887
|
/* enable cache on node now that it is fully constructed */
|
|
10821
10888
|
node.cacheEnable();
|
|
10822
|
-
if (source.hooks
|
|
10889
|
+
if ((_a = source.hooks) === null || _a === void 0 ? void 0 : _a.processElement) {
|
|
10823
10890
|
const processElement = source.hooks.processElement;
|
|
10824
10891
|
const metaTable = this.metaTable;
|
|
10825
10892
|
const context = {
|
|
@@ -10886,6 +10953,7 @@ class Parser {
|
|
|
10886
10953
|
* @internal
|
|
10887
10954
|
*/
|
|
10888
10955
|
consumeAttribute(source, node, token, next) {
|
|
10956
|
+
var _a;
|
|
10889
10957
|
const keyLocation = this.getAttributeKeyLocation(token);
|
|
10890
10958
|
const valueLocation = this.getAttributeValueLocation(next);
|
|
10891
10959
|
const location = this.getAttributeLocation(token, next);
|
|
@@ -10904,7 +10972,7 @@ class Parser {
|
|
|
10904
10972
|
* data right away but a transformer may override it to allow aliasing
|
|
10905
10973
|
* attributes, e.g ng-attr-foo or v-bind:foo */
|
|
10906
10974
|
let processAttribute = (attr) => [attr];
|
|
10907
|
-
if (source.hooks
|
|
10975
|
+
if ((_a = source.hooks) === null || _a === void 0 ? void 0 : _a.processAttribute) {
|
|
10908
10976
|
processAttribute = source.hooks.processAttribute;
|
|
10909
10977
|
}
|
|
10910
10978
|
/* handle deprecated callbacks */
|
|
@@ -11254,14 +11322,15 @@ class Reporter {
|
|
|
11254
11322
|
const report = {
|
|
11255
11323
|
valid: this.isValid(),
|
|
11256
11324
|
results: Object.keys(this.result).map((filePath) => {
|
|
11325
|
+
var _a;
|
|
11257
11326
|
const messages = Array.from(this.result[filePath], freeze).sort(messageSort);
|
|
11258
|
-
const source = (sources
|
|
11327
|
+
const source = (sources !== null && sources !== void 0 ? sources : []).find((source) => { var _a; return filePath === ((_a = source.filename) !== null && _a !== void 0 ? _a : ""); });
|
|
11259
11328
|
return {
|
|
11260
11329
|
filePath,
|
|
11261
11330
|
messages,
|
|
11262
11331
|
errorCount: countErrors(messages),
|
|
11263
11332
|
warningCount: countWarnings(messages),
|
|
11264
|
-
source: source ? source.originalData
|
|
11333
|
+
source: source ? (_a = source.originalData) !== null && _a !== void 0 ? _a : source.data : null,
|
|
11265
11334
|
};
|
|
11266
11335
|
}),
|
|
11267
11336
|
errorCount: 0,
|
|
@@ -11279,10 +11348,10 @@ class Reporter {
|
|
|
11279
11348
|
}
|
|
11280
11349
|
}
|
|
11281
11350
|
function countErrors(messages) {
|
|
11282
|
-
return messages.filter((m) => m.severity === exports.Severity.ERROR).length;
|
|
11351
|
+
return messages.filter((m) => m.severity === Number(exports.Severity.ERROR)).length;
|
|
11283
11352
|
}
|
|
11284
11353
|
function countWarnings(messages) {
|
|
11285
|
-
return messages.filter((m) => m.severity === exports.Severity.WARN).length;
|
|
11354
|
+
return messages.filter((m) => m.severity === Number(exports.Severity.WARN)).length;
|
|
11286
11355
|
}
|
|
11287
11356
|
function sumErrors(results) {
|
|
11288
11357
|
return results.reduce((sum, result) => {
|
|
@@ -11460,7 +11529,9 @@ class Engine {
|
|
|
11460
11529
|
else {
|
|
11461
11530
|
lines.push("(root)");
|
|
11462
11531
|
}
|
|
11463
|
-
node.childElements.forEach((child, index) =>
|
|
11532
|
+
node.childElements.forEach((child, index) => {
|
|
11533
|
+
writeNode(child, level + 1, index);
|
|
11534
|
+
});
|
|
11464
11535
|
}
|
|
11465
11536
|
writeNode(document, 0, 0);
|
|
11466
11537
|
return lines;
|
|
@@ -11625,9 +11696,10 @@ class Engine {
|
|
|
11625
11696
|
* between rule name and its constructor.
|
|
11626
11697
|
*/
|
|
11627
11698
|
initRules(config) {
|
|
11699
|
+
var _a;
|
|
11628
11700
|
const availableRules = {};
|
|
11629
11701
|
for (const plugin of config.getPlugins()) {
|
|
11630
|
-
for (const [name, rule] of Object.entries(plugin.rules
|
|
11702
|
+
for (const [name, rule] of Object.entries((_a = plugin.rules) !== null && _a !== void 0 ? _a : {})) {
|
|
11631
11703
|
if (!rule)
|
|
11632
11704
|
continue;
|
|
11633
11705
|
availableRules[name] = rule;
|
|
@@ -11730,7 +11802,7 @@ class StaticConfigLoader extends ConfigLoader {
|
|
|
11730
11802
|
}
|
|
11731
11803
|
}
|
|
11732
11804
|
getConfigFor(_handle, configOverride) {
|
|
11733
|
-
const override = this.loadFromObject(configOverride
|
|
11805
|
+
const override = this.loadFromObject(configOverride !== null && configOverride !== void 0 ? configOverride : {});
|
|
11734
11806
|
if (override.isRootFound()) {
|
|
11735
11807
|
override.init();
|
|
11736
11808
|
return override.resolve();
|
|
@@ -11774,6 +11846,7 @@ class HtmlValidate {
|
|
|
11774
11846
|
const [loader, config] = arg instanceof ConfigLoader ? [arg, undefined] : [undefined, arg];
|
|
11775
11847
|
this.configLoader = loader !== null && loader !== void 0 ? loader : new StaticConfigLoader(config);
|
|
11776
11848
|
}
|
|
11849
|
+
/* eslint-enable @typescript-eslint/unified-signatures */
|
|
11777
11850
|
validateString(str, arg1, arg2, arg3) {
|
|
11778
11851
|
const filename = typeof arg1 === "string" ? arg1 : "inline";
|
|
11779
11852
|
const options = isConfigData(arg1) ? arg1 : isConfigData(arg2) ? arg2 : undefined;
|
|
@@ -11788,6 +11861,7 @@ class HtmlValidate {
|
|
|
11788
11861
|
};
|
|
11789
11862
|
return this.validateSource(source, options);
|
|
11790
11863
|
}
|
|
11864
|
+
/* eslint-enable @typescript-eslint/unified-signatures */
|
|
11791
11865
|
validateStringSync(str, arg1, arg2, arg3) {
|
|
11792
11866
|
const filename = typeof arg1 === "string" ? arg1 : "inline";
|
|
11793
11867
|
const options = isConfigData(arg1) ? arg1 : isConfigData(arg2) ? arg2 : undefined;
|
|
@@ -12059,7 +12133,7 @@ class HtmlValidate {
|
|
|
12059
12133
|
* contextual details and suggestions.
|
|
12060
12134
|
*/
|
|
12061
12135
|
async getRuleDocumentation(ruleId, config = null, context = null) {
|
|
12062
|
-
const c = config
|
|
12136
|
+
const c = config !== null && config !== void 0 ? config : this.getConfigFor("inline");
|
|
12063
12137
|
const engine = new Engine(await c, Parser);
|
|
12064
12138
|
return engine.getRuleDocumentation({ ruleId, context });
|
|
12065
12139
|
}
|
|
@@ -12088,7 +12162,7 @@ class HtmlValidate {
|
|
|
12088
12162
|
* contextual details and suggestions.
|
|
12089
12163
|
*/
|
|
12090
12164
|
getRuleDocumentationSync(ruleId, config = null, context = null) {
|
|
12091
|
-
const c = config
|
|
12165
|
+
const c = config !== null && config !== void 0 ? config : this.getConfigForSync("inline");
|
|
12092
12166
|
const engine = new Engine(c, Parser);
|
|
12093
12167
|
return engine.getRuleDocumentation({ ruleId, context });
|
|
12094
12168
|
}
|
|
@@ -12144,7 +12218,7 @@ class HtmlValidate {
|
|
|
12144
12218
|
/** @public */
|
|
12145
12219
|
const name = "html-validate";
|
|
12146
12220
|
/** @public */
|
|
12147
|
-
const version = "8.0
|
|
12221
|
+
const version = "8.2.0";
|
|
12148
12222
|
/** @public */
|
|
12149
12223
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
12150
12224
|
|
|
@@ -12157,61 +12231,6 @@ function definePlugin(plugin) {
|
|
|
12157
12231
|
return plugin;
|
|
12158
12232
|
}
|
|
12159
12233
|
|
|
12160
|
-
const defaults$1 = {
|
|
12161
|
-
silent: false,
|
|
12162
|
-
version,
|
|
12163
|
-
logger(text) {
|
|
12164
|
-
/* eslint-disable-next-line no-console -- expected to log */
|
|
12165
|
-
console.error(kleur__default.default.red(text));
|
|
12166
|
-
},
|
|
12167
|
-
};
|
|
12168
|
-
/**
|
|
12169
|
-
* Tests if plugin is compatible with html-validate library. Unless the `silent`
|
|
12170
|
-
* option is used a warning is displayed on the console.
|
|
12171
|
-
*
|
|
12172
|
-
* @public
|
|
12173
|
-
* @since v5.0.0
|
|
12174
|
-
* @param name - Name of plugin
|
|
12175
|
-
* @param declared - What library versions the plugin support (e.g. declared peerDependencies)
|
|
12176
|
-
* @returns - `true` if version is compatible
|
|
12177
|
-
*/
|
|
12178
|
-
function compatibilityCheck(name, declared, options) {
|
|
12179
|
-
const { silent, version: current, logger } = { ...defaults$1, ...options };
|
|
12180
|
-
const valid = semver__default.default.satisfies(current, declared);
|
|
12181
|
-
if (valid || silent) {
|
|
12182
|
-
return valid;
|
|
12183
|
-
}
|
|
12184
|
-
const text = [
|
|
12185
|
-
"-----------------------------------------------------------------------------------------------------",
|
|
12186
|
-
`${name} requires html-validate version "${declared}" but current installed version is ${current}`,
|
|
12187
|
-
"This is not a supported configuration. Please install a supported version before reporting bugs.",
|
|
12188
|
-
"-----------------------------------------------------------------------------------------------------",
|
|
12189
|
-
].join("\n");
|
|
12190
|
-
logger(text);
|
|
12191
|
-
return false;
|
|
12192
|
-
}
|
|
12193
|
-
|
|
12194
|
-
/**
|
|
12195
|
-
* Similar to `require(..)` but removes the cached copy first.
|
|
12196
|
-
*/
|
|
12197
|
-
function requireUncached(require, moduleId) {
|
|
12198
|
-
const filename = require.resolve(moduleId);
|
|
12199
|
-
/* remove references from the parent module to prevent memory leak */
|
|
12200
|
-
const m = require.cache[filename];
|
|
12201
|
-
if (m && m.parent) {
|
|
12202
|
-
const { parent } = m;
|
|
12203
|
-
for (let i = parent.children.length - 1; i >= 0; i--) {
|
|
12204
|
-
if (parent.children[i].id === filename) {
|
|
12205
|
-
parent.children.splice(i, 1);
|
|
12206
|
-
}
|
|
12207
|
-
}
|
|
12208
|
-
}
|
|
12209
|
-
/* remove old module from cache */
|
|
12210
|
-
delete require.cache[filename];
|
|
12211
|
-
/* eslint-disable-next-line import/no-dynamic-require, security/detect-non-literal-require -- as expected but should be moved to upcoming resolver class */
|
|
12212
|
-
return require(filename);
|
|
12213
|
-
}
|
|
12214
|
-
|
|
12215
12234
|
const ruleIds = new Set(Object.keys(rules));
|
|
12216
12235
|
/**
|
|
12217
12236
|
* Returns true if given ruleId is an existing builtin rule. It does not handle
|
|
@@ -12478,6 +12497,25 @@ function getFormatter(name) {
|
|
|
12478
12497
|
return (_a = availableFormatters[name]) !== null && _a !== void 0 ? _a : null;
|
|
12479
12498
|
}
|
|
12480
12499
|
|
|
12500
|
+
/**
|
|
12501
|
+
* @internal
|
|
12502
|
+
*/
|
|
12503
|
+
function compatibilityCheckImpl(name, declared, options) {
|
|
12504
|
+
const { silent, version: current, logger } = options;
|
|
12505
|
+
const valid = semver__default.default.satisfies(current, declared);
|
|
12506
|
+
if (valid || silent) {
|
|
12507
|
+
return valid;
|
|
12508
|
+
}
|
|
12509
|
+
const text = [
|
|
12510
|
+
"-----------------------------------------------------------------------------------------------------",
|
|
12511
|
+
`${name} requires html-validate version "${declared}" but current installed version is ${current}`,
|
|
12512
|
+
"This is not a supported configuration. Please install a supported version before reporting bugs.",
|
|
12513
|
+
"-----------------------------------------------------------------------------------------------------",
|
|
12514
|
+
].join("\n");
|
|
12515
|
+
logger(text);
|
|
12516
|
+
return false;
|
|
12517
|
+
}
|
|
12518
|
+
|
|
12481
12519
|
exports.Attribute = Attribute;
|
|
12482
12520
|
exports.Config = Config;
|
|
12483
12521
|
exports.ConfigError = ConfigError;
|
|
@@ -12506,13 +12544,12 @@ exports.WrappedError = WrappedError;
|
|
|
12506
12544
|
exports.bugs = bugs;
|
|
12507
12545
|
exports.classifyNodeText = classifyNodeText;
|
|
12508
12546
|
exports.codeframe = codeframe;
|
|
12509
|
-
exports.
|
|
12547
|
+
exports.compatibilityCheckImpl = compatibilityCheckImpl;
|
|
12510
12548
|
exports.definePlugin = definePlugin;
|
|
12511
12549
|
exports.ensureError = ensureError;
|
|
12512
12550
|
exports.getFormatter = getFormatter;
|
|
12513
12551
|
exports.keywordPatternMatcher = keywordPatternMatcher;
|
|
12514
12552
|
exports.name = name;
|
|
12515
|
-
exports.requireUncached = requireUncached;
|
|
12516
12553
|
exports.ruleExists = ruleExists;
|
|
12517
12554
|
exports.sliceLocation = sliceLocation;
|
|
12518
12555
|
exports.staticResolver = staticResolver;
|