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/es/core.js
CHANGED
|
@@ -2,12 +2,12 @@ import Ajv from 'ajv';
|
|
|
2
2
|
import deepmerge from 'deepmerge';
|
|
3
3
|
import { e as entities$1, h as html5, b as bundledElements } from './elements.js';
|
|
4
4
|
import fs from 'fs';
|
|
5
|
-
import semver from 'semver';
|
|
6
|
-
import kleur from 'kleur';
|
|
7
5
|
import betterAjvErrors from '@sidvind/better-ajv-errors';
|
|
8
6
|
import { n as naturalJoin } from './utils/natural-join.js';
|
|
9
7
|
import { codeFrameColumns } from '@babel/code-frame';
|
|
8
|
+
import kleur from 'kleur';
|
|
10
9
|
import { stylish as stylish$2 } from '@html-validate/stylish';
|
|
10
|
+
import semver from 'semver';
|
|
11
11
|
|
|
12
12
|
const $schema$2 = "http://json-schema.org/draft-06/schema#";
|
|
13
13
|
const $id$2 = "http://json-schema.org/draft-06/schema#";
|
|
@@ -284,7 +284,7 @@ class NestedError extends Error {
|
|
|
284
284
|
super(message);
|
|
285
285
|
Error.captureStackTrace(this, NestedError);
|
|
286
286
|
this.name = NestedError.name;
|
|
287
|
-
if (nested
|
|
287
|
+
if (nested === null || nested === void 0 ? void 0 : nested.stack) {
|
|
288
288
|
this.stack += `\nCaused by: ${nested.stack}`;
|
|
289
289
|
}
|
|
290
290
|
}
|
|
@@ -1019,7 +1019,8 @@ function hasAttribute(node, attr) {
|
|
|
1019
1019
|
* Matches attribute against value.
|
|
1020
1020
|
*/
|
|
1021
1021
|
function matchAttribute(node, key, op, value) {
|
|
1022
|
-
|
|
1022
|
+
var _a;
|
|
1023
|
+
const nodeValue = ((_a = node.getAttributeValue(key)) !== null && _a !== void 0 ? _a : "").toLowerCase();
|
|
1023
1024
|
switch (op) {
|
|
1024
1025
|
case "!=":
|
|
1025
1026
|
return nodeValue !== value;
|
|
@@ -1381,6 +1382,16 @@ class Attribute {
|
|
|
1381
1382
|
get isDynamic() {
|
|
1382
1383
|
return this.value instanceof DynamicValue;
|
|
1383
1384
|
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Test attribute value.
|
|
1387
|
+
*
|
|
1388
|
+
* @param pattern - Pattern to match value against. Can be a RegExp, literal
|
|
1389
|
+
* string or an array of strings (returns true if any value matches the
|
|
1390
|
+
* array).
|
|
1391
|
+
* @param dynamicMatches - If true `DynamicValue` will always match, if false
|
|
1392
|
+
* it never matches.
|
|
1393
|
+
* @returns `true` if attribute value matches pattern.
|
|
1394
|
+
*/
|
|
1384
1395
|
valueMatches(pattern, dynamicMatches = true) {
|
|
1385
1396
|
if (this.value === null) {
|
|
1386
1397
|
return false;
|
|
@@ -1766,7 +1777,7 @@ class DOMTokenList extends Array {
|
|
|
1766
1777
|
this.value = value.expr;
|
|
1767
1778
|
}
|
|
1768
1779
|
else {
|
|
1769
|
-
this.value = value
|
|
1780
|
+
this.value = value !== null && value !== void 0 ? value : "";
|
|
1770
1781
|
}
|
|
1771
1782
|
}
|
|
1772
1783
|
item(n) {
|
|
@@ -1991,7 +2002,7 @@ class IdMatcher extends Matcher {
|
|
|
1991
2002
|
class AttrMatcher extends Matcher {
|
|
1992
2003
|
constructor(attr) {
|
|
1993
2004
|
super();
|
|
1994
|
-
const [, key, op, value] = attr.match(/^(.+?)(?:([~^$*|]?=)"([^"]+?)")?$/);
|
|
2005
|
+
const [, key, op, value] = attr.match(/^(.+?)(?:([~^$*|]?=)"([^"]+?)")?$/); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- will always match
|
|
1995
2006
|
this.key = key;
|
|
1996
2007
|
this.op = op;
|
|
1997
2008
|
this.value = value;
|
|
@@ -2028,11 +2039,11 @@ class PseudoClassMatcher extends Matcher {
|
|
|
2028
2039
|
}
|
|
2029
2040
|
class Pattern {
|
|
2030
2041
|
constructor(pattern) {
|
|
2031
|
-
const match = pattern.match(/^([~+\->]?)((?:[*]|[^.#[:]+)?)(.*)$/);
|
|
2042
|
+
const match = pattern.match(/^([~+\->]?)((?:[*]|[^.#[:]+)?)(.*)$/); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- will always match
|
|
2032
2043
|
match.shift(); /* remove full matched string */
|
|
2033
2044
|
this.selector = pattern;
|
|
2034
2045
|
this.combinator = parseCombinator(match.shift(), pattern);
|
|
2035
|
-
this.tagName = match.shift() || "*";
|
|
2046
|
+
this.tagName = match.shift() || "*"; // eslint-disable-line @typescript-eslint/prefer-nullish-coalescing -- empty string */
|
|
2036
2047
|
this.pattern = Array.from(splitPattern(match[0]), (it) => this.createMatcher(it));
|
|
2037
2048
|
}
|
|
2038
2049
|
match(node, context) {
|
|
@@ -2206,6 +2217,21 @@ function isElementNode(node) {
|
|
|
2206
2217
|
function isValidTagName(tagName) {
|
|
2207
2218
|
return Boolean(tagName !== "" && tagName !== "*");
|
|
2208
2219
|
}
|
|
2220
|
+
function createAdapter(node) {
|
|
2221
|
+
return {
|
|
2222
|
+
closest(selectors) {
|
|
2223
|
+
var _a;
|
|
2224
|
+
return (_a = node.closest(selectors)) === null || _a === void 0 ? void 0 : _a._adapter;
|
|
2225
|
+
},
|
|
2226
|
+
getAttribute(name) {
|
|
2227
|
+
var _a;
|
|
2228
|
+
return (_a = node.getAttribute(name)) === null || _a === void 0 ? void 0 : _a.value;
|
|
2229
|
+
},
|
|
2230
|
+
hasAttribute(name) {
|
|
2231
|
+
return node.hasAttribute(name);
|
|
2232
|
+
},
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2209
2235
|
/**
|
|
2210
2236
|
* @public
|
|
2211
2237
|
*/
|
|
@@ -2214,9 +2240,9 @@ class HtmlElement extends DOMNode {
|
|
|
2214
2240
|
const nodeType = tagName ? NodeType.ELEMENT_NODE : NodeType.DOCUMENT_NODE;
|
|
2215
2241
|
super(nodeType, tagName, location);
|
|
2216
2242
|
if (!isValidTagName(tagName)) {
|
|
2217
|
-
throw new Error(`The tag name provided ('${tagName
|
|
2243
|
+
throw new Error(`The tag name provided ('${tagName !== null && tagName !== void 0 ? tagName : ""}') is not a valid name`);
|
|
2218
2244
|
}
|
|
2219
|
-
this.tagName = tagName
|
|
2245
|
+
this.tagName = tagName !== null && tagName !== void 0 ? tagName : "#document";
|
|
2220
2246
|
this.parent = parent !== null && parent !== void 0 ? parent : null;
|
|
2221
2247
|
this.attr = {};
|
|
2222
2248
|
this.metaElement = meta !== null && meta !== void 0 ? meta : null;
|
|
@@ -2224,6 +2250,7 @@ class HtmlElement extends DOMNode {
|
|
|
2224
2250
|
this.voidElement = meta ? Boolean(meta.void) : false;
|
|
2225
2251
|
this.depth = 0;
|
|
2226
2252
|
this.annotation = null;
|
|
2253
|
+
this._adapter = createAdapter(this);
|
|
2227
2254
|
if (parent) {
|
|
2228
2255
|
parent.childNodes.push(this);
|
|
2229
2256
|
/* calculate depth in domtree */
|
|
@@ -2283,7 +2310,7 @@ class HtmlElement extends DOMNode {
|
|
|
2283
2310
|
*/
|
|
2284
2311
|
get ariaLabelledby() {
|
|
2285
2312
|
const attr = this.getAttribute("aria-labelledby");
|
|
2286
|
-
if (!attr ||
|
|
2313
|
+
if (!(attr === null || attr === void 0 ? void 0 : attr.value)) {
|
|
2287
2314
|
return null;
|
|
2288
2315
|
}
|
|
2289
2316
|
if (attr.value instanceof DynamicValue) {
|
|
@@ -2401,6 +2428,7 @@ class HtmlElement extends DOMNode {
|
|
|
2401
2428
|
setMetaProperty(this.metaElement, key, value);
|
|
2402
2429
|
}
|
|
2403
2430
|
else {
|
|
2431
|
+
/* eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- technical debt */
|
|
2404
2432
|
delete this.metaElement[key];
|
|
2405
2433
|
}
|
|
2406
2434
|
}
|
|
@@ -2676,11 +2704,12 @@ class DOMTree {
|
|
|
2676
2704
|
this.active = node;
|
|
2677
2705
|
}
|
|
2678
2706
|
popActive() {
|
|
2707
|
+
var _a;
|
|
2679
2708
|
if (this.active.isRootElement()) {
|
|
2680
2709
|
/* root element should never be popped, continue as if nothing happened */
|
|
2681
2710
|
return;
|
|
2682
2711
|
}
|
|
2683
|
-
this.active = this.active.parent
|
|
2712
|
+
this.active = (_a = this.active.parent) !== null && _a !== void 0 ? _a : this.root;
|
|
2684
2713
|
}
|
|
2685
2714
|
getActive() {
|
|
2686
2715
|
return this.active;
|
|
@@ -2689,7 +2718,9 @@ class DOMTree {
|
|
|
2689
2718
|
* Resolve dynamic meta expressions.
|
|
2690
2719
|
*/
|
|
2691
2720
|
resolveMeta(table) {
|
|
2692
|
-
this.visitDepthFirst((node) =>
|
|
2721
|
+
this.visitDepthFirst((node) => {
|
|
2722
|
+
table.resolve(node);
|
|
2723
|
+
});
|
|
2693
2724
|
}
|
|
2694
2725
|
getElementsByTagName(tagName) {
|
|
2695
2726
|
return this.root.getElementsByTagName(tagName);
|
|
@@ -2714,6 +2745,7 @@ const allowedKeys = ["exclude"];
|
|
|
2714
2745
|
*
|
|
2715
2746
|
* @public
|
|
2716
2747
|
*/
|
|
2748
|
+
/* eslint-disable-next-line @typescript-eslint/no-extraneous-class -- technical debt, should probably be plain functions maybe in an object */
|
|
2717
2749
|
class Validator {
|
|
2718
2750
|
/**
|
|
2719
2751
|
* Test if element is used in a proper context.
|
|
@@ -2755,7 +2787,7 @@ class Validator {
|
|
|
2755
2787
|
return false;
|
|
2756
2788
|
}
|
|
2757
2789
|
// Check if the rule has a quantifier
|
|
2758
|
-
const [, category, quantifier] = rule.match(/^(@?.*?)([?*]?)$/);
|
|
2790
|
+
const [, category, quantifier] = rule.match(/^(@?.*?)([?*]?)$/); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- will always match
|
|
2759
2791
|
const limit = category && quantifier && parseQuantifier(quantifier);
|
|
2760
2792
|
if (limit) {
|
|
2761
2793
|
const siblings = children.filter((cur) => Validator.validatePermittedCategory(cur, rule, true));
|
|
@@ -2801,6 +2833,7 @@ class Validator {
|
|
|
2801
2833
|
* In both of these cases no error should be reported. */
|
|
2802
2834
|
const orderSpecified = rules.find((cur) => Validator.validatePermittedCategory(node, cur, true));
|
|
2803
2835
|
if (orderSpecified) {
|
|
2836
|
+
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- technical debt, should never happen */
|
|
2804
2837
|
cb(node, prev);
|
|
2805
2838
|
return false;
|
|
2806
2839
|
}
|
|
@@ -2941,9 +2974,9 @@ class Validator {
|
|
|
2941
2974
|
*/
|
|
2942
2975
|
/* eslint-disable-next-line complexity -- rule does not like switch */
|
|
2943
2976
|
static validatePermittedCategory(node, category, defaultMatch) {
|
|
2944
|
-
const [, rawCategory] = category.match(/^(@?.*?)([?*]?)$/);
|
|
2977
|
+
const [, rawCategory] = category.match(/^(@?.*?)([?*]?)$/); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- will always match
|
|
2945
2978
|
/* match tagName when an explicit name is given */
|
|
2946
|
-
if (rawCategory
|
|
2979
|
+
if (!rawCategory.startsWith("@")) {
|
|
2947
2980
|
return node.tagName === rawCategory;
|
|
2948
2981
|
}
|
|
2949
2982
|
/* if the meta entry is missing assume any content model would match */
|
|
@@ -2966,9 +2999,9 @@ class Validator {
|
|
|
2966
2999
|
case "@interactive":
|
|
2967
3000
|
return node.meta.interactive;
|
|
2968
3001
|
case "@script":
|
|
2969
|
-
return node.meta.scriptSupporting;
|
|
3002
|
+
return Boolean(node.meta.scriptSupporting);
|
|
2970
3003
|
case "@form":
|
|
2971
|
-
return node.meta.form;
|
|
3004
|
+
return Boolean(node.meta.form);
|
|
2972
3005
|
default:
|
|
2973
3006
|
throw new Error(`Invalid content category "${category}"`);
|
|
2974
3007
|
}
|
|
@@ -3153,10 +3186,12 @@ var configurationSchema = {
|
|
|
3153
3186
|
properties: properties
|
|
3154
3187
|
};
|
|
3155
3188
|
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3189
|
+
/**
|
|
3190
|
+
* @internal
|
|
3191
|
+
*/
|
|
3192
|
+
const TRANSFORMER_API = {
|
|
3193
|
+
VERSION: 1,
|
|
3194
|
+
};
|
|
3160
3195
|
|
|
3161
3196
|
/**
|
|
3162
3197
|
* @public
|
|
@@ -3403,7 +3438,7 @@ function classifyNodeText(node, options = {}) {
|
|
|
3403
3438
|
const { accessible = false, ignoreHiddenRoot = false } = options;
|
|
3404
3439
|
const cacheKey = getCachekey(options);
|
|
3405
3440
|
if (node.cacheExists(cacheKey)) {
|
|
3406
|
-
return node.cacheGet(cacheKey);
|
|
3441
|
+
return node.cacheGet(cacheKey); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- has/get combo
|
|
3407
3442
|
}
|
|
3408
3443
|
if (!ignoreHiddenRoot && isHTMLHidden(node)) {
|
|
3409
3444
|
return node.cacheSet(cacheKey, TextClassification.EMPTY_TEXT);
|
|
@@ -3451,8 +3486,12 @@ function findTextNodes(node, options) {
|
|
|
3451
3486
|
|
|
3452
3487
|
function hasAltText(image) {
|
|
3453
3488
|
const alt = image.getAttribute("alt");
|
|
3454
|
-
/* missing
|
|
3455
|
-
if (alt
|
|
3489
|
+
/* missing attribute */
|
|
3490
|
+
if (!alt) {
|
|
3491
|
+
return false;
|
|
3492
|
+
}
|
|
3493
|
+
/* (incorrectly) set as boolean value */
|
|
3494
|
+
if (alt.value === null) {
|
|
3456
3495
|
return false;
|
|
3457
3496
|
}
|
|
3458
3497
|
return alt.isDynamic || alt.value.toString() !== "";
|
|
@@ -3460,8 +3499,12 @@ function hasAltText(image) {
|
|
|
3460
3499
|
|
|
3461
3500
|
function hasAriaLabel(node) {
|
|
3462
3501
|
const label = node.getAttribute("aria-label");
|
|
3463
|
-
/* missing
|
|
3464
|
-
if (label
|
|
3502
|
+
/* missing attribute */
|
|
3503
|
+
if (!label) {
|
|
3504
|
+
return false;
|
|
3505
|
+
}
|
|
3506
|
+
/* (incorrectly) set as boolean value */
|
|
3507
|
+
if (label.value === null) {
|
|
3465
3508
|
return false;
|
|
3466
3509
|
}
|
|
3467
3510
|
return label.isDynamic || label.value.toString() !== "";
|
|
@@ -3542,7 +3585,7 @@ class Rule {
|
|
|
3542
3585
|
this.options = options;
|
|
3543
3586
|
this.enabled = true;
|
|
3544
3587
|
this.blockers = [];
|
|
3545
|
-
this.severity =
|
|
3588
|
+
this.severity = Severity.DISABLED;
|
|
3546
3589
|
this.name = "";
|
|
3547
3590
|
}
|
|
3548
3591
|
getSeverity() {
|
|
@@ -3695,13 +3738,14 @@ class Rule {
|
|
|
3695
3738
|
}
|
|
3696
3739
|
}
|
|
3697
3740
|
findLocation(src) {
|
|
3741
|
+
var _a, _b;
|
|
3698
3742
|
if (src.location) {
|
|
3699
3743
|
return src.location;
|
|
3700
3744
|
}
|
|
3701
|
-
if (src.event
|
|
3745
|
+
if ((_a = src.event) === null || _a === void 0 ? void 0 : _a.location) {
|
|
3702
3746
|
return src.event.location;
|
|
3703
3747
|
}
|
|
3704
|
-
if (src.node
|
|
3748
|
+
if ((_b = src.node) === null || _b === void 0 ? void 0 : _b.location) {
|
|
3705
3749
|
return src.node.location;
|
|
3706
3750
|
}
|
|
3707
3751
|
return {};
|
|
@@ -3798,7 +3842,7 @@ var Style$1;
|
|
|
3798
3842
|
Style["ABSOLUTE"] = "absolute";
|
|
3799
3843
|
Style["ANCHOR"] = "anchor";
|
|
3800
3844
|
})(Style$1 || (Style$1 = {}));
|
|
3801
|
-
const defaults$
|
|
3845
|
+
const defaults$u = {
|
|
3802
3846
|
allowExternal: true,
|
|
3803
3847
|
allowRelative: true,
|
|
3804
3848
|
allowAbsolute: true,
|
|
@@ -3842,7 +3886,7 @@ function matchList(value, list) {
|
|
|
3842
3886
|
}
|
|
3843
3887
|
class AllowedLinks extends Rule {
|
|
3844
3888
|
constructor(options) {
|
|
3845
|
-
super({ ...defaults$
|
|
3889
|
+
super({ ...defaults$u, ...options });
|
|
3846
3890
|
this.allowExternal = parseAllow(this.options.allowExternal);
|
|
3847
3891
|
this.allowRelative = parseAllow(this.options.allowRelative);
|
|
3848
3892
|
this.allowAbsolute = parseAllow(this.options.allowAbsolute);
|
|
@@ -3874,7 +3918,8 @@ class AllowedLinks extends Rule {
|
|
|
3874
3918
|
};
|
|
3875
3919
|
}
|
|
3876
3920
|
documentation(context) {
|
|
3877
|
-
|
|
3921
|
+
var _a;
|
|
3922
|
+
const message = (_a = description[context]) !== null && _a !== void 0 ? _a : "This link type is not allowed by current configuration";
|
|
3878
3923
|
return {
|
|
3879
3924
|
description: message,
|
|
3880
3925
|
url: "https://html-validate.org/rules/allowed-links.html",
|
|
@@ -3990,7 +4035,7 @@ var RuleContext$1;
|
|
|
3990
4035
|
RuleContext["MISSING_ALT"] = "missing-alt";
|
|
3991
4036
|
RuleContext["MISSING_HREF"] = "missing-href";
|
|
3992
4037
|
})(RuleContext$1 || (RuleContext$1 = {}));
|
|
3993
|
-
const defaults$
|
|
4038
|
+
const defaults$t = {
|
|
3994
4039
|
accessible: true,
|
|
3995
4040
|
};
|
|
3996
4041
|
function findByTarget(target, siblings) {
|
|
@@ -4016,19 +4061,11 @@ function getDescription$1(context) {
|
|
|
4016
4061
|
"",
|
|
4017
4062
|
"Either add the `href` attribute or remove the `alt` attribute.",
|
|
4018
4063
|
];
|
|
4019
|
-
default:
|
|
4020
|
-
return [
|
|
4021
|
-
"The `alt` attribute must only be used together with the `href` attribute.",
|
|
4022
|
-
"It must be set if `href` is present and must be omitted if `href` is missing",
|
|
4023
|
-
"",
|
|
4024
|
-
"The attribute is used to provide an alternative text description for the area of the image map.",
|
|
4025
|
-
"The text should describe the purpose of area and the resource referenced by the `href` attribute.",
|
|
4026
|
-
];
|
|
4027
4064
|
}
|
|
4028
4065
|
}
|
|
4029
4066
|
class AreaAlt extends Rule {
|
|
4030
4067
|
constructor(options) {
|
|
4031
|
-
super({ ...defaults$
|
|
4068
|
+
super({ ...defaults$t, ...options });
|
|
4032
4069
|
}
|
|
4033
4070
|
static schema() {
|
|
4034
4071
|
return {
|
|
@@ -4146,7 +4183,7 @@ function isValidUsage(target, meta) {
|
|
|
4146
4183
|
return true;
|
|
4147
4184
|
}
|
|
4148
4185
|
/* interactive and labelable elements are valid */
|
|
4149
|
-
if (meta.interactive || meta.labelable) {
|
|
4186
|
+
if (Boolean(meta.interactive) || Boolean(meta.labelable)) {
|
|
4150
4187
|
return true;
|
|
4151
4188
|
}
|
|
4152
4189
|
return false;
|
|
@@ -4181,7 +4218,7 @@ class AriaLabelMisuse extends Rule {
|
|
|
4181
4218
|
}
|
|
4182
4219
|
validateElement(target) {
|
|
4183
4220
|
const attr = target.getAttribute("aria-label");
|
|
4184
|
-
if (!attr ||
|
|
4221
|
+
if (!(attr === null || attr === void 0 ? void 0 : attr.value) || attr.valueMatches("", false)) {
|
|
4185
4222
|
return;
|
|
4186
4223
|
}
|
|
4187
4224
|
/* ignore elements without meta */
|
|
@@ -4262,13 +4299,13 @@ class CaseStyle {
|
|
|
4262
4299
|
}
|
|
4263
4300
|
}
|
|
4264
4301
|
|
|
4265
|
-
const defaults$
|
|
4302
|
+
const defaults$s = {
|
|
4266
4303
|
style: "lowercase",
|
|
4267
4304
|
ignoreForeign: true,
|
|
4268
4305
|
};
|
|
4269
4306
|
class AttrCase extends Rule {
|
|
4270
4307
|
constructor(options) {
|
|
4271
|
-
super({ ...defaults$
|
|
4308
|
+
super({ ...defaults$s, ...options });
|
|
4272
4309
|
this.style = new CaseStyle(this.options.style, "attr-case");
|
|
4273
4310
|
}
|
|
4274
4311
|
static schema() {
|
|
@@ -4494,7 +4531,7 @@ class Lexer {
|
|
|
4494
4531
|
*/
|
|
4495
4532
|
enter(context, state, data) {
|
|
4496
4533
|
/* script/style tags require a different content model */
|
|
4497
|
-
if (state === State.TAG && data && data[0]
|
|
4534
|
+
if (state === State.TAG && data && data[0].startsWith("<")) {
|
|
4498
4535
|
if (data[0] === "<script") {
|
|
4499
4536
|
context.contentModel = ContentModel.SCRIPT;
|
|
4500
4537
|
}
|
|
@@ -4532,14 +4569,14 @@ class Lexer {
|
|
|
4532
4569
|
case ContentModel.TEXT:
|
|
4533
4570
|
return State.TEXT;
|
|
4534
4571
|
case ContentModel.SCRIPT:
|
|
4535
|
-
if (tagCloseToken && tagCloseToken.data[0]
|
|
4572
|
+
if (tagCloseToken && !tagCloseToken.data[0].startsWith("/")) {
|
|
4536
4573
|
return State.SCRIPT;
|
|
4537
4574
|
}
|
|
4538
4575
|
else {
|
|
4539
4576
|
return State.TEXT; /* <script/> (not legal but handle it anyway so the lexer doesn't choke on it) */
|
|
4540
4577
|
}
|
|
4541
4578
|
case ContentModel.STYLE:
|
|
4542
|
-
if (tagCloseToken && tagCloseToken.data[0]
|
|
4579
|
+
if (tagCloseToken && !tagCloseToken.data[0].startsWith("/")) {
|
|
4543
4580
|
return State.STYLE;
|
|
4544
4581
|
}
|
|
4545
4582
|
else {
|
|
@@ -4616,7 +4653,7 @@ class AttrDelimiter extends Rule {
|
|
|
4616
4653
|
}
|
|
4617
4654
|
|
|
4618
4655
|
const DEFAULT_PATTERN = "[a-z0-9-:]+";
|
|
4619
|
-
const defaults$
|
|
4656
|
+
const defaults$r = {
|
|
4620
4657
|
pattern: DEFAULT_PATTERN,
|
|
4621
4658
|
ignoreForeign: true,
|
|
4622
4659
|
};
|
|
@@ -4653,7 +4690,7 @@ function generateDescription(name, pattern) {
|
|
|
4653
4690
|
}
|
|
4654
4691
|
class AttrPattern extends Rule {
|
|
4655
4692
|
constructor(options) {
|
|
4656
|
-
super({ ...defaults$
|
|
4693
|
+
super({ ...defaults$r, ...options });
|
|
4657
4694
|
this.pattern = generateRegexp(this.options.pattern);
|
|
4658
4695
|
}
|
|
4659
4696
|
static schema() {
|
|
@@ -4714,7 +4751,7 @@ var QuoteStyle;
|
|
|
4714
4751
|
QuoteStyle["AUTO_QUOTE"] = "auto";
|
|
4715
4752
|
QuoteStyle["ANY_QUOTE"] = "any";
|
|
4716
4753
|
})(QuoteStyle || (QuoteStyle = {}));
|
|
4717
|
-
const defaults$
|
|
4754
|
+
const defaults$q = {
|
|
4718
4755
|
style: "auto",
|
|
4719
4756
|
unquoted: false,
|
|
4720
4757
|
};
|
|
@@ -4781,7 +4818,7 @@ class AttrQuotes extends Rule {
|
|
|
4781
4818
|
};
|
|
4782
4819
|
}
|
|
4783
4820
|
constructor(options) {
|
|
4784
|
-
super({ ...defaults$
|
|
4821
|
+
super({ ...defaults$q, ...options });
|
|
4785
4822
|
this.style = parseStyle$3(this.options.style);
|
|
4786
4823
|
}
|
|
4787
4824
|
setup() {
|
|
@@ -4791,7 +4828,7 @@ class AttrQuotes extends Rule {
|
|
|
4791
4828
|
return;
|
|
4792
4829
|
}
|
|
4793
4830
|
if (!event.quote) {
|
|
4794
|
-
if (this.options.unquoted
|
|
4831
|
+
if (!this.options.unquoted) {
|
|
4795
4832
|
const message = `Attribute "${event.key}" using unquoted value`;
|
|
4796
4833
|
const context = {
|
|
4797
4834
|
error: "unquoted",
|
|
@@ -4912,7 +4949,7 @@ class AttributeAllowedValues extends Rule {
|
|
|
4912
4949
|
const meta = node.meta;
|
|
4913
4950
|
/* ignore rule if element has no meta or meta does not specify attribute
|
|
4914
4951
|
* allowed values */
|
|
4915
|
-
if (!meta ||
|
|
4952
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes))
|
|
4916
4953
|
return;
|
|
4917
4954
|
for (const attr of node.attributes) {
|
|
4918
4955
|
if (Validator.validateAttribute(attr, meta.attributes)) {
|
|
@@ -4951,12 +4988,12 @@ class AttributeAllowedValues extends Rule {
|
|
|
4951
4988
|
}
|
|
4952
4989
|
}
|
|
4953
4990
|
|
|
4954
|
-
const defaults$
|
|
4991
|
+
const defaults$p = {
|
|
4955
4992
|
style: "omit",
|
|
4956
4993
|
};
|
|
4957
4994
|
class AttributeBooleanStyle extends Rule {
|
|
4958
4995
|
constructor(options) {
|
|
4959
|
-
super({ ...defaults$
|
|
4996
|
+
super({ ...defaults$p, ...options });
|
|
4960
4997
|
this.hasInvalidStyle = parseStyle$2(this.options.style);
|
|
4961
4998
|
}
|
|
4962
4999
|
static schema() {
|
|
@@ -4980,7 +5017,7 @@ class AttributeBooleanStyle extends Rule {
|
|
|
4980
5017
|
const meta = node.meta;
|
|
4981
5018
|
/* ignore rule if element has no meta or meta does not specify attribute
|
|
4982
5019
|
* allowed values */
|
|
4983
|
-
if (!meta ||
|
|
5020
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes))
|
|
4984
5021
|
return;
|
|
4985
5022
|
/* check all boolean attributes */
|
|
4986
5023
|
for (const attr of node.attributes) {
|
|
@@ -5032,12 +5069,12 @@ function reportMessage$1(attr, style) {
|
|
|
5032
5069
|
return "";
|
|
5033
5070
|
}
|
|
5034
5071
|
|
|
5035
|
-
const defaults$
|
|
5072
|
+
const defaults$o = {
|
|
5036
5073
|
style: "omit",
|
|
5037
5074
|
};
|
|
5038
5075
|
class AttributeEmptyStyle extends Rule {
|
|
5039
5076
|
constructor(options) {
|
|
5040
|
-
super({ ...defaults$
|
|
5077
|
+
super({ ...defaults$o, ...options });
|
|
5041
5078
|
this.hasInvalidStyle = parseStyle$1(this.options.style);
|
|
5042
5079
|
}
|
|
5043
5080
|
static schema() {
|
|
@@ -5061,7 +5098,7 @@ class AttributeEmptyStyle extends Rule {
|
|
|
5061
5098
|
const meta = node.meta;
|
|
5062
5099
|
/* ignore rule if element has no meta or meta does not specify attribute
|
|
5063
5100
|
* allowed values */
|
|
5064
|
-
if (!meta ||
|
|
5101
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes))
|
|
5065
5102
|
return;
|
|
5066
5103
|
/* check all boolean attributes */
|
|
5067
5104
|
for (const attr of node.attributes) {
|
|
@@ -5149,10 +5186,10 @@ class AttributeMisuse extends Rule {
|
|
|
5149
5186
|
});
|
|
5150
5187
|
}
|
|
5151
5188
|
validateAttr(node, attr, meta) {
|
|
5152
|
-
if (!meta ||
|
|
5189
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.allowed)) {
|
|
5153
5190
|
return;
|
|
5154
5191
|
}
|
|
5155
|
-
const details = meta.allowed(node, attr);
|
|
5192
|
+
const details = meta.allowed(node._adapter, attr.value);
|
|
5156
5193
|
if (details) {
|
|
5157
5194
|
this.report({
|
|
5158
5195
|
node,
|
|
@@ -5193,12 +5230,12 @@ function describePattern(pattern) {
|
|
|
5193
5230
|
}
|
|
5194
5231
|
}
|
|
5195
5232
|
|
|
5196
|
-
const defaults$
|
|
5233
|
+
const defaults$n = {
|
|
5197
5234
|
pattern: "kebabcase",
|
|
5198
5235
|
};
|
|
5199
5236
|
class ClassPattern extends Rule {
|
|
5200
5237
|
constructor(options) {
|
|
5201
|
-
super({ ...defaults$
|
|
5238
|
+
super({ ...defaults$n, ...options });
|
|
5202
5239
|
this.pattern = parsePattern(this.options.pattern);
|
|
5203
5240
|
}
|
|
5204
5241
|
static schema() {
|
|
@@ -5307,13 +5344,13 @@ class CloseOrder extends Rule {
|
|
|
5307
5344
|
}
|
|
5308
5345
|
}
|
|
5309
5346
|
|
|
5310
|
-
const defaults$
|
|
5347
|
+
const defaults$m = {
|
|
5311
5348
|
include: null,
|
|
5312
5349
|
exclude: null,
|
|
5313
5350
|
};
|
|
5314
5351
|
class Deprecated extends Rule {
|
|
5315
5352
|
constructor(options) {
|
|
5316
|
-
super({ ...defaults$
|
|
5353
|
+
super({ ...defaults$m, ...options });
|
|
5317
5354
|
}
|
|
5318
5355
|
static schema() {
|
|
5319
5356
|
return {
|
|
@@ -5476,12 +5513,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
|
|
|
5476
5513
|
}
|
|
5477
5514
|
};
|
|
5478
5515
|
|
|
5479
|
-
const defaults$
|
|
5516
|
+
const defaults$l = {
|
|
5480
5517
|
style: "uppercase",
|
|
5481
5518
|
};
|
|
5482
5519
|
class DoctypeStyle extends Rule {
|
|
5483
5520
|
constructor(options) {
|
|
5484
|
-
super({ ...defaults$
|
|
5521
|
+
super({ ...defaults$l, ...options });
|
|
5485
5522
|
}
|
|
5486
5523
|
static schema() {
|
|
5487
5524
|
return {
|
|
@@ -5513,12 +5550,12 @@ class DoctypeStyle extends Rule {
|
|
|
5513
5550
|
}
|
|
5514
5551
|
}
|
|
5515
5552
|
|
|
5516
|
-
const defaults$
|
|
5553
|
+
const defaults$k = {
|
|
5517
5554
|
style: "lowercase",
|
|
5518
5555
|
};
|
|
5519
5556
|
class ElementCase extends Rule {
|
|
5520
5557
|
constructor(options) {
|
|
5521
|
-
super({ ...defaults$
|
|
5558
|
+
super({ ...defaults$k, ...options });
|
|
5522
5559
|
this.style = new CaseStyle(this.options.style, "element-case");
|
|
5523
5560
|
}
|
|
5524
5561
|
static schema() {
|
|
@@ -5584,14 +5621,14 @@ class ElementCase extends Rule {
|
|
|
5584
5621
|
}
|
|
5585
5622
|
}
|
|
5586
5623
|
|
|
5587
|
-
const defaults$
|
|
5624
|
+
const defaults$j = {
|
|
5588
5625
|
pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
|
|
5589
5626
|
whitelist: [],
|
|
5590
5627
|
blacklist: [],
|
|
5591
5628
|
};
|
|
5592
5629
|
class ElementName extends Rule {
|
|
5593
5630
|
constructor(options) {
|
|
5594
|
-
super({ ...defaults$
|
|
5631
|
+
super({ ...defaults$j, ...options });
|
|
5595
5632
|
/* eslint-disable-next-line security/detect-non-literal-regexp -- expected to be a regexp */
|
|
5596
5633
|
this.pattern = new RegExp(this.options.pattern);
|
|
5597
5634
|
}
|
|
@@ -5632,7 +5669,7 @@ class ElementName extends Rule {
|
|
|
5632
5669
|
...context.blacklist.map((cur) => `- ${cur}`),
|
|
5633
5670
|
];
|
|
5634
5671
|
}
|
|
5635
|
-
if (context.pattern !== defaults$
|
|
5672
|
+
if (context.pattern !== defaults$j.pattern) {
|
|
5636
5673
|
return [
|
|
5637
5674
|
`<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
|
|
5638
5675
|
"",
|
|
@@ -5823,7 +5860,7 @@ class ElementPermittedOccurrences extends Rule {
|
|
|
5823
5860
|
this.on("dom:ready", (event) => {
|
|
5824
5861
|
const doc = event.document;
|
|
5825
5862
|
doc.visitDepthFirst((node) => {
|
|
5826
|
-
if (!node ||
|
|
5863
|
+
if (!(node === null || node === void 0 ? void 0 : node.meta)) {
|
|
5827
5864
|
return;
|
|
5828
5865
|
}
|
|
5829
5866
|
const rules = node.meta.permittedContent;
|
|
@@ -5868,7 +5905,7 @@ function isCategoryOrTag(value) {
|
|
|
5868
5905
|
return typeof value === "string";
|
|
5869
5906
|
}
|
|
5870
5907
|
function isCategory$1(value) {
|
|
5871
|
-
return value
|
|
5908
|
+
return value.startsWith("@");
|
|
5872
5909
|
}
|
|
5873
5910
|
function formatCategoryOrTag(value) {
|
|
5874
5911
|
return isCategory$1(value) ? value.slice(1) : `<${value}>`;
|
|
@@ -6028,7 +6065,7 @@ class ElementRequiredAttributes extends Rule {
|
|
|
6028
6065
|
const node = event.previous;
|
|
6029
6066
|
const meta = node.meta;
|
|
6030
6067
|
/* handle missing metadata and missing attributes */
|
|
6031
|
-
if (!meta ||
|
|
6068
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes)) {
|
|
6032
6069
|
return;
|
|
6033
6070
|
}
|
|
6034
6071
|
for (const [key, attr] of Object.entries(meta.attributes)) {
|
|
@@ -6048,7 +6085,7 @@ class ElementRequiredAttributes extends Rule {
|
|
|
6048
6085
|
}
|
|
6049
6086
|
|
|
6050
6087
|
function isCategory(value) {
|
|
6051
|
-
return value
|
|
6088
|
+
return value.startsWith("@");
|
|
6052
6089
|
}
|
|
6053
6090
|
class ElementRequiredContent extends Rule {
|
|
6054
6091
|
documentation(context) {
|
|
@@ -6176,7 +6213,7 @@ class EmptyTitle extends Rule {
|
|
|
6176
6213
|
}
|
|
6177
6214
|
}
|
|
6178
6215
|
|
|
6179
|
-
const defaults$
|
|
6216
|
+
const defaults$i = {
|
|
6180
6217
|
allowArrayBrackets: true,
|
|
6181
6218
|
shared: ["radio", "button", "reset", "submit"],
|
|
6182
6219
|
};
|
|
@@ -6209,7 +6246,7 @@ function getDocumentation(context) {
|
|
|
6209
6246
|
}
|
|
6210
6247
|
class FormDupName extends Rule {
|
|
6211
6248
|
constructor(options) {
|
|
6212
|
-
super({ ...defaults$
|
|
6249
|
+
super({ ...defaults$i, ...options });
|
|
6213
6250
|
}
|
|
6214
6251
|
static schema() {
|
|
6215
6252
|
return {
|
|
@@ -6340,7 +6377,7 @@ class FormDupName extends Rule {
|
|
|
6340
6377
|
const meta = this.getMetaFor(tagName);
|
|
6341
6378
|
/* istanbul ignore if: the earlier check for getTagsWithProperty ensures
|
|
6342
6379
|
* these will actually be set so this is just an untestable fallback */
|
|
6343
|
-
if (!meta ||
|
|
6380
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.formAssociated)) {
|
|
6344
6381
|
return false;
|
|
6345
6382
|
}
|
|
6346
6383
|
return meta.formAssociated.listed;
|
|
@@ -6369,7 +6406,7 @@ class FormDupName extends Rule {
|
|
|
6369
6406
|
}
|
|
6370
6407
|
}
|
|
6371
6408
|
|
|
6372
|
-
const defaults$
|
|
6409
|
+
const defaults$h = {
|
|
6373
6410
|
allowMultipleH1: false,
|
|
6374
6411
|
minInitialRank: "h1",
|
|
6375
6412
|
sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]'],
|
|
@@ -6400,7 +6437,7 @@ function parseMaxInitial(value) {
|
|
|
6400
6437
|
}
|
|
6401
6438
|
class HeadingLevel extends Rule {
|
|
6402
6439
|
constructor(options) {
|
|
6403
|
-
super({ ...defaults$
|
|
6440
|
+
super({ ...defaults$h, ...options });
|
|
6404
6441
|
this.stack = [];
|
|
6405
6442
|
this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
|
|
6406
6443
|
this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
|
|
@@ -6442,9 +6479,15 @@ class HeadingLevel extends Rule {
|
|
|
6442
6479
|
};
|
|
6443
6480
|
}
|
|
6444
6481
|
setup() {
|
|
6445
|
-
this.on("tag:start", isRelevant$3, (event) =>
|
|
6446
|
-
|
|
6447
|
-
|
|
6482
|
+
this.on("tag:start", isRelevant$3, (event) => {
|
|
6483
|
+
this.onTagStart(event);
|
|
6484
|
+
});
|
|
6485
|
+
this.on("tag:ready", (event) => {
|
|
6486
|
+
this.onTagReady(event);
|
|
6487
|
+
});
|
|
6488
|
+
this.on("tag:close", (event) => {
|
|
6489
|
+
this.onTagClose(event);
|
|
6490
|
+
});
|
|
6448
6491
|
}
|
|
6449
6492
|
onTagStart(event) {
|
|
6450
6493
|
/* extract heading level from tagName (e.g "h1" -> 1)*/
|
|
@@ -6558,12 +6601,12 @@ class HeadingLevel extends Rule {
|
|
|
6558
6601
|
}
|
|
6559
6602
|
}
|
|
6560
6603
|
|
|
6561
|
-
const defaults$
|
|
6604
|
+
const defaults$g = {
|
|
6562
6605
|
pattern: "kebabcase",
|
|
6563
6606
|
};
|
|
6564
6607
|
class IdPattern extends Rule {
|
|
6565
6608
|
constructor(options) {
|
|
6566
|
-
super({ ...defaults$
|
|
6609
|
+
super({ ...defaults$g, ...options });
|
|
6567
6610
|
this.pattern = parsePattern(this.options.pattern);
|
|
6568
6611
|
}
|
|
6569
6612
|
static schema() {
|
|
@@ -6582,7 +6625,7 @@ class IdPattern extends Rule {
|
|
|
6582
6625
|
}
|
|
6583
6626
|
setup() {
|
|
6584
6627
|
this.on("attr", (event) => {
|
|
6585
|
-
var _a;
|
|
6628
|
+
var _a, _b;
|
|
6586
6629
|
if (event.key.toLowerCase() !== "id") {
|
|
6587
6630
|
return;
|
|
6588
6631
|
}
|
|
@@ -6590,8 +6633,8 @@ class IdPattern extends Rule {
|
|
|
6590
6633
|
if (event.value instanceof DynamicValue) {
|
|
6591
6634
|
return;
|
|
6592
6635
|
}
|
|
6593
|
-
if (!event.value ||
|
|
6594
|
-
const value = (
|
|
6636
|
+
if (!((_a = event.value) === null || _a === void 0 ? void 0 : _a.match(this.pattern))) {
|
|
6637
|
+
const value = (_b = event.value) !== null && _b !== void 0 ? _b : "";
|
|
6595
6638
|
const pattern = this.pattern.toString();
|
|
6596
6639
|
const message = `ID "${value}" does not match required pattern "${pattern}"`;
|
|
6597
6640
|
this.report(event.target, message, event.valueLocation);
|
|
@@ -6965,12 +7008,12 @@ function findLabelByParent(el) {
|
|
|
6965
7008
|
return [];
|
|
6966
7009
|
}
|
|
6967
7010
|
|
|
6968
|
-
const defaults$
|
|
7011
|
+
const defaults$f = {
|
|
6969
7012
|
maxlength: 70,
|
|
6970
7013
|
};
|
|
6971
7014
|
class LongTitle extends Rule {
|
|
6972
7015
|
constructor(options) {
|
|
6973
|
-
super({ ...defaults$
|
|
7016
|
+
super({ ...defaults$f, ...options });
|
|
6974
7017
|
this.maxlength = this.options.maxlength;
|
|
6975
7018
|
}
|
|
6976
7019
|
static schema() {
|
|
@@ -7019,7 +7062,7 @@ class MetaRefresh extends Rule {
|
|
|
7019
7062
|
}
|
|
7020
7063
|
/* ensure content attribute is set */
|
|
7021
7064
|
const content = target.getAttribute("content");
|
|
7022
|
-
if (!content ||
|
|
7065
|
+
if (!(content === null || content === void 0 ? void 0 : content.value) || content.isDynamic) {
|
|
7023
7066
|
return;
|
|
7024
7067
|
}
|
|
7025
7068
|
/* ensure content attribute is valid */
|
|
@@ -7196,13 +7239,13 @@ class MultipleLabeledControls extends Rule {
|
|
|
7196
7239
|
}
|
|
7197
7240
|
}
|
|
7198
7241
|
|
|
7199
|
-
const defaults$
|
|
7242
|
+
const defaults$e = {
|
|
7200
7243
|
include: null,
|
|
7201
7244
|
exclude: null,
|
|
7202
7245
|
};
|
|
7203
7246
|
class NoAutoplay extends Rule {
|
|
7204
7247
|
constructor(options) {
|
|
7205
|
-
super({ ...defaults$
|
|
7248
|
+
super({ ...defaults$e, ...options });
|
|
7206
7249
|
}
|
|
7207
7250
|
documentation(context) {
|
|
7208
7251
|
const tagName = context ? ` on <${context.tagName}>` : "";
|
|
@@ -7298,7 +7341,7 @@ class NoDeprecatedAttr extends Rule {
|
|
|
7298
7341
|
if (meta === null) {
|
|
7299
7342
|
return;
|
|
7300
7343
|
}
|
|
7301
|
-
const metaAttribute = meta.attributes
|
|
7344
|
+
const metaAttribute = meta.attributes[attr];
|
|
7302
7345
|
if (!metaAttribute) {
|
|
7303
7346
|
return;
|
|
7304
7347
|
}
|
|
@@ -7378,7 +7421,7 @@ class NoDupID extends Rule {
|
|
|
7378
7421
|
for (const el of relevant) {
|
|
7379
7422
|
const attr = el.getAttribute("id");
|
|
7380
7423
|
/* istanbul ignore next: this has already been tested in isRelevant once but for type-safety it is checked again */
|
|
7381
|
-
if (!attr ||
|
|
7424
|
+
if (!(attr === null || attr === void 0 ? void 0 : attr.value)) {
|
|
7382
7425
|
continue;
|
|
7383
7426
|
}
|
|
7384
7427
|
const id = attr.value.toString();
|
|
@@ -7443,14 +7486,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
|
|
|
7443
7486
|
}
|
|
7444
7487
|
}
|
|
7445
7488
|
|
|
7446
|
-
const defaults$
|
|
7489
|
+
const defaults$d = {
|
|
7447
7490
|
include: null,
|
|
7448
7491
|
exclude: null,
|
|
7449
7492
|
allowedProperties: ["display"],
|
|
7450
7493
|
};
|
|
7451
7494
|
class NoInlineStyle extends Rule {
|
|
7452
7495
|
constructor(options) {
|
|
7453
|
-
super({ ...defaults$
|
|
7496
|
+
super({ ...defaults$d, ...options });
|
|
7454
7497
|
}
|
|
7455
7498
|
static schema() {
|
|
7456
7499
|
return {
|
|
@@ -7512,11 +7555,12 @@ class NoInlineStyle extends Rule {
|
|
|
7512
7555
|
});
|
|
7513
7556
|
}
|
|
7514
7557
|
isRelevant(event) {
|
|
7558
|
+
var _a;
|
|
7515
7559
|
if (event.key !== "style") {
|
|
7516
7560
|
return false;
|
|
7517
7561
|
}
|
|
7518
7562
|
const { include, exclude } = this.options;
|
|
7519
|
-
const key = event.originalAttribute
|
|
7563
|
+
const key = (_a = event.originalAttribute) !== null && _a !== void 0 ? _a : event.key;
|
|
7520
7564
|
/* ignore attributes not present in "include" */
|
|
7521
7565
|
if (include && !include.includes(key)) {
|
|
7522
7566
|
return false;
|
|
@@ -7652,7 +7696,7 @@ class NoMultipleMain extends Rule {
|
|
|
7652
7696
|
}
|
|
7653
7697
|
}
|
|
7654
7698
|
|
|
7655
|
-
const defaults$
|
|
7699
|
+
const defaults$c = {
|
|
7656
7700
|
relaxed: false,
|
|
7657
7701
|
};
|
|
7658
7702
|
const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
|
|
@@ -7669,7 +7713,7 @@ const replacementTable = {
|
|
|
7669
7713
|
};
|
|
7670
7714
|
class NoRawCharacters extends Rule {
|
|
7671
7715
|
constructor(options) {
|
|
7672
|
-
super({ ...defaults$
|
|
7716
|
+
super({ ...defaults$c, ...options });
|
|
7673
7717
|
this.relaxed = this.options.relaxed;
|
|
7674
7718
|
}
|
|
7675
7719
|
static schema() {
|
|
@@ -7710,7 +7754,8 @@ class NoRawCharacters extends Rule {
|
|
|
7710
7754
|
if (event.quote) {
|
|
7711
7755
|
return;
|
|
7712
7756
|
}
|
|
7713
|
-
this.findRawChars(event.target, event.value.toString(), event.valueLocation,
|
|
7757
|
+
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
|
|
7758
|
+
unquotedAttrRegexp);
|
|
7714
7759
|
});
|
|
7715
7760
|
}
|
|
7716
7761
|
/**
|
|
@@ -7743,6 +7788,39 @@ class NoRawCharacters extends Rule {
|
|
|
7743
7788
|
}
|
|
7744
7789
|
}
|
|
7745
7790
|
|
|
7791
|
+
const selectors = ["input[aria-label]", "textarea[aria-label]", "select[aria-label]"];
|
|
7792
|
+
class NoRedundantAriaLabel extends Rule {
|
|
7793
|
+
documentation() {
|
|
7794
|
+
return {
|
|
7795
|
+
description: "`aria-label` is redundant when an associated `<label>` element containing the same text exists.",
|
|
7796
|
+
url: "https://html-validate.org/rules/no-redundant-aria-label.html",
|
|
7797
|
+
};
|
|
7798
|
+
}
|
|
7799
|
+
setup() {
|
|
7800
|
+
this.on("dom:ready", (event) => {
|
|
7801
|
+
const { document } = event;
|
|
7802
|
+
const elements = document.querySelectorAll(selectors.join(","));
|
|
7803
|
+
for (const element of elements) {
|
|
7804
|
+
const ariaLabel = element.getAttribute("aria-label");
|
|
7805
|
+
const id = element.id;
|
|
7806
|
+
if (!id) {
|
|
7807
|
+
continue;
|
|
7808
|
+
}
|
|
7809
|
+
const label = document.querySelector(`label[for="${id}"]`);
|
|
7810
|
+
if (!ariaLabel || !label || label.textContent.trim() !== ariaLabel.value) {
|
|
7811
|
+
continue;
|
|
7812
|
+
}
|
|
7813
|
+
const message = "aria-label is redundant when label containing same text exists";
|
|
7814
|
+
this.report({
|
|
7815
|
+
message,
|
|
7816
|
+
node: element,
|
|
7817
|
+
location: ariaLabel.keyLocation,
|
|
7818
|
+
});
|
|
7819
|
+
}
|
|
7820
|
+
});
|
|
7821
|
+
}
|
|
7822
|
+
}
|
|
7823
|
+
|
|
7746
7824
|
class NoRedundantFor extends Rule {
|
|
7747
7825
|
documentation() {
|
|
7748
7826
|
return {
|
|
@@ -7847,13 +7925,13 @@ class NoRedundantRole extends Rule {
|
|
|
7847
7925
|
}
|
|
7848
7926
|
|
|
7849
7927
|
const xmlns = /^(.+):.+$/;
|
|
7850
|
-
const defaults$
|
|
7928
|
+
const defaults$b = {
|
|
7851
7929
|
ignoreForeign: true,
|
|
7852
7930
|
ignoreXML: true,
|
|
7853
7931
|
};
|
|
7854
7932
|
class NoSelfClosing extends Rule {
|
|
7855
7933
|
constructor(options) {
|
|
7856
|
-
super({ ...defaults$
|
|
7934
|
+
super({ ...defaults$b, ...options });
|
|
7857
7935
|
}
|
|
7858
7936
|
static schema() {
|
|
7859
7937
|
return {
|
|
@@ -7891,7 +7969,7 @@ class NoSelfClosing extends Rule {
|
|
|
7891
7969
|
function isRelevant(node, options) {
|
|
7892
7970
|
/* tags in XML namespaces are relevant only if ignoreXml is false, in which
|
|
7893
7971
|
* case assume all xml elements must not be self-closed */
|
|
7894
|
-
if (node.tagName
|
|
7972
|
+
if (node.tagName.match(xmlns)) {
|
|
7895
7973
|
return !options.ignoreXML;
|
|
7896
7974
|
}
|
|
7897
7975
|
/* nodes with missing metadata is assumed relevant */
|
|
@@ -7942,13 +8020,13 @@ class NoTrailingWhitespace extends Rule {
|
|
|
7942
8020
|
}
|
|
7943
8021
|
}
|
|
7944
8022
|
|
|
7945
|
-
const defaults$
|
|
8023
|
+
const defaults$a = {
|
|
7946
8024
|
include: null,
|
|
7947
8025
|
exclude: null,
|
|
7948
8026
|
};
|
|
7949
8027
|
class NoUnknownElements extends Rule {
|
|
7950
8028
|
constructor(options) {
|
|
7951
|
-
super({ ...defaults$
|
|
8029
|
+
super({ ...defaults$a, ...options });
|
|
7952
8030
|
}
|
|
7953
8031
|
static schema() {
|
|
7954
8032
|
return {
|
|
@@ -8004,9 +8082,7 @@ class NoUnknownElements extends Rule {
|
|
|
8004
8082
|
class NoUnusedDisable extends Rule {
|
|
8005
8083
|
documentation(context) {
|
|
8006
8084
|
return {
|
|
8007
|
-
description: context
|
|
8008
|
-
? `\`${context.ruleId}\` rule is disabled but no error was reported.`
|
|
8009
|
-
: "Rule is disabled but no error was reported.",
|
|
8085
|
+
description: `\`${context.ruleId}\` rule is disabled but no error was reported.`,
|
|
8010
8086
|
url: "https://html-validate.org/rules/no-unused-disable.html",
|
|
8011
8087
|
};
|
|
8012
8088
|
}
|
|
@@ -8060,13 +8136,13 @@ const replacement = {
|
|
|
8060
8136
|
reset: '<button type="reset">',
|
|
8061
8137
|
image: '<button type="button">',
|
|
8062
8138
|
};
|
|
8063
|
-
const defaults$
|
|
8139
|
+
const defaults$9 = {
|
|
8064
8140
|
include: null,
|
|
8065
8141
|
exclude: null,
|
|
8066
8142
|
};
|
|
8067
8143
|
class PreferButton extends Rule {
|
|
8068
8144
|
constructor(options) {
|
|
8069
|
-
super({ ...defaults$
|
|
8145
|
+
super({ ...defaults$9, ...options });
|
|
8070
8146
|
}
|
|
8071
8147
|
static schema() {
|
|
8072
8148
|
return {
|
|
@@ -8099,16 +8175,12 @@ class PreferButton extends Rule {
|
|
|
8099
8175
|
};
|
|
8100
8176
|
}
|
|
8101
8177
|
documentation(context) {
|
|
8102
|
-
const
|
|
8103
|
-
|
|
8178
|
+
const src = `<input type="${context.type}">`;
|
|
8179
|
+
const dst = replacement[context.type] || `<button>`;
|
|
8180
|
+
return {
|
|
8181
|
+
description: `Prefer to use \`${dst}\` instead of \`"${src}\`.`,
|
|
8104
8182
|
url: "https://html-validate.org/rules/prefer-button.html",
|
|
8105
8183
|
};
|
|
8106
|
-
if (context) {
|
|
8107
|
-
const src = `<input type="${context.type}">`;
|
|
8108
|
-
const dst = replacement[context.type] || `<button>`;
|
|
8109
|
-
doc.description = `Prefer to use \`${dst}\` instead of \`"${src}\`.`;
|
|
8110
|
-
}
|
|
8111
|
-
return doc;
|
|
8112
8184
|
}
|
|
8113
8185
|
setup() {
|
|
8114
8186
|
this.on("attr", (event) => {
|
|
@@ -8141,7 +8213,7 @@ class PreferButton extends Rule {
|
|
|
8141
8213
|
}
|
|
8142
8214
|
}
|
|
8143
8215
|
|
|
8144
|
-
const defaults$
|
|
8216
|
+
const defaults$8 = {
|
|
8145
8217
|
mapping: {
|
|
8146
8218
|
article: "article",
|
|
8147
8219
|
banner: "header",
|
|
@@ -8171,7 +8243,7 @@ const defaults$9 = {
|
|
|
8171
8243
|
};
|
|
8172
8244
|
class PreferNativeElement extends Rule {
|
|
8173
8245
|
constructor(options) {
|
|
8174
|
-
super({ ...defaults$
|
|
8246
|
+
super({ ...defaults$8, ...options });
|
|
8175
8247
|
}
|
|
8176
8248
|
static schema() {
|
|
8177
8249
|
return {
|
|
@@ -8207,14 +8279,10 @@ class PreferNativeElement extends Rule {
|
|
|
8207
8279
|
};
|
|
8208
8280
|
}
|
|
8209
8281
|
documentation(context) {
|
|
8210
|
-
|
|
8211
|
-
description: `Instead of using WAI-ARIA
|
|
8282
|
+
return {
|
|
8283
|
+
description: `Instead of using the WAI-ARIA role "${context.role}" prefer to use the native <${context.replacement}> element.`,
|
|
8212
8284
|
url: "https://html-validate.org/rules/prefer-native-element.html",
|
|
8213
8285
|
};
|
|
8214
|
-
if (context) {
|
|
8215
|
-
doc.description = `Instead of using the WAI-ARIA role "${context.role}" prefer to use the native <${context.replacement}> element.`;
|
|
8216
|
-
}
|
|
8217
|
-
return doc;
|
|
8218
8286
|
}
|
|
8219
8287
|
setup() {
|
|
8220
8288
|
const { mapping } = this.options;
|
|
@@ -8255,7 +8323,7 @@ class PreferNativeElement extends Rule {
|
|
|
8255
8323
|
}
|
|
8256
8324
|
getLocation(event) {
|
|
8257
8325
|
const begin = event.location;
|
|
8258
|
-
const end = event.valueLocation;
|
|
8326
|
+
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
|
|
8259
8327
|
const quote = event.quote ? 1 : 0;
|
|
8260
8328
|
const size = end.offset + end.size - begin.offset + quote;
|
|
8261
8329
|
return {
|
|
@@ -8291,12 +8359,12 @@ class PreferTbody extends Rule {
|
|
|
8291
8359
|
}
|
|
8292
8360
|
}
|
|
8293
8361
|
|
|
8294
|
-
const defaults$
|
|
8362
|
+
const defaults$7 = {
|
|
8295
8363
|
tags: ["script", "style"],
|
|
8296
8364
|
};
|
|
8297
8365
|
class RequireCSPNonce extends Rule {
|
|
8298
8366
|
constructor(options) {
|
|
8299
|
-
super({ ...defaults$
|
|
8367
|
+
super({ ...defaults$7, ...options });
|
|
8300
8368
|
}
|
|
8301
8369
|
static schema() {
|
|
8302
8370
|
return {
|
|
@@ -8329,7 +8397,7 @@ class RequireCSPNonce extends Rule {
|
|
|
8329
8397
|
const { tags } = this.options;
|
|
8330
8398
|
const node = event.previous;
|
|
8331
8399
|
/* ignore other tags */
|
|
8332
|
-
if (!
|
|
8400
|
+
if (!tags.includes(node.tagName)) {
|
|
8333
8401
|
return;
|
|
8334
8402
|
}
|
|
8335
8403
|
/* ignore if nonce is set to non-empty value (or dynamic) */
|
|
@@ -8347,7 +8415,7 @@ class RequireCSPNonce extends Rule {
|
|
|
8347
8415
|
}
|
|
8348
8416
|
}
|
|
8349
8417
|
|
|
8350
|
-
const defaults$
|
|
8418
|
+
const defaults$6 = {
|
|
8351
8419
|
target: "all",
|
|
8352
8420
|
include: null,
|
|
8353
8421
|
exclude: null,
|
|
@@ -8359,7 +8427,7 @@ const supportSri = {
|
|
|
8359
8427
|
};
|
|
8360
8428
|
class RequireSri extends Rule {
|
|
8361
8429
|
constructor(options) {
|
|
8362
|
-
super({ ...defaults$
|
|
8430
|
+
super({ ...defaults$6, ...options });
|
|
8363
8431
|
this.target = this.options.target;
|
|
8364
8432
|
}
|
|
8365
8433
|
static schema() {
|
|
@@ -8421,7 +8489,10 @@ class RequireSri extends Rule {
|
|
|
8421
8489
|
}
|
|
8422
8490
|
needSri(node) {
|
|
8423
8491
|
const attr = this.elementSourceAttr(node);
|
|
8424
|
-
if (!attr
|
|
8492
|
+
if (!attr) {
|
|
8493
|
+
return false;
|
|
8494
|
+
}
|
|
8495
|
+
if (attr.value === null || attr.value === "" || attr.isDynamic) {
|
|
8425
8496
|
return false;
|
|
8426
8497
|
}
|
|
8427
8498
|
const url = attr.value.toString();
|
|
@@ -8478,7 +8549,7 @@ class ScriptType extends Rule {
|
|
|
8478
8549
|
setup() {
|
|
8479
8550
|
this.on("tag:end", (event) => {
|
|
8480
8551
|
const node = event.previous;
|
|
8481
|
-
if (
|
|
8552
|
+
if (node.tagName !== "script") {
|
|
8482
8553
|
return;
|
|
8483
8554
|
}
|
|
8484
8555
|
const attr = node.getAttribute("type");
|
|
@@ -8521,7 +8592,7 @@ class SvgFocusable extends Rule {
|
|
|
8521
8592
|
}
|
|
8522
8593
|
}
|
|
8523
8594
|
|
|
8524
|
-
const defaults$
|
|
8595
|
+
const defaults$5 = {
|
|
8525
8596
|
characters: [
|
|
8526
8597
|
{ pattern: " ", replacement: " ", description: "non-breaking space" },
|
|
8527
8598
|
{ pattern: "-", replacement: "‑", description: "non-breaking hyphen" },
|
|
@@ -8560,7 +8631,7 @@ function matchAll(text, regexp) {
|
|
|
8560
8631
|
}
|
|
8561
8632
|
class TelNonBreaking extends Rule {
|
|
8562
8633
|
constructor(options) {
|
|
8563
|
-
super({ ...defaults$
|
|
8634
|
+
super({ ...defaults$5, ...options });
|
|
8564
8635
|
this.regex = constructRegex(this.options.characters);
|
|
8565
8636
|
}
|
|
8566
8637
|
static schema() {
|
|
@@ -8601,9 +8672,7 @@ class TelNonBreaking extends Rule {
|
|
|
8601
8672
|
});
|
|
8602
8673
|
return {
|
|
8603
8674
|
description: [
|
|
8604
|
-
context
|
|
8605
|
-
? `The \`${context.pattern}\` character should be replaced with \`${context.replacement}\` character (${context.description}) when used in a telephone number.`
|
|
8606
|
-
: `Replace this character with a non-breaking version.`,
|
|
8675
|
+
`The \`${context.pattern}\` character should be replaced with \`${context.replacement}\` character (${context.description}) when used in a telephone number.`,
|
|
8607
8676
|
"",
|
|
8608
8677
|
"Unless non-breaking characters is used there could be a line break inserted at that character.",
|
|
8609
8678
|
"Line breaks make is harder to read and understand the telephone number.",
|
|
@@ -8761,18 +8830,16 @@ class TextContent extends Rule {
|
|
|
8761
8830
|
description: `The textual content for this element is not valid.`,
|
|
8762
8831
|
url: "https://html-validate.org/rules/text-content.html",
|
|
8763
8832
|
};
|
|
8764
|
-
|
|
8765
|
-
|
|
8766
|
-
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
|
|
8770
|
-
|
|
8771
|
-
|
|
8772
|
-
|
|
8773
|
-
|
|
8774
|
-
break;
|
|
8775
|
-
}
|
|
8833
|
+
switch (context.textContent) {
|
|
8834
|
+
case TextContent$1.NONE:
|
|
8835
|
+
doc.description = `The \`<${context.tagName}>\` element must not have textual content.`;
|
|
8836
|
+
break;
|
|
8837
|
+
case TextContent$1.REQUIRED:
|
|
8838
|
+
doc.description = `The \`<${context.tagName}>\` element must have textual content.`;
|
|
8839
|
+
break;
|
|
8840
|
+
case TextContent$1.ACCESSIBLE:
|
|
8841
|
+
doc.description = `The \`<${context.tagName}>\` element must have accessible text.`;
|
|
8842
|
+
break;
|
|
8776
8843
|
}
|
|
8777
8844
|
return doc;
|
|
8778
8845
|
}
|
|
@@ -8848,7 +8915,7 @@ class TextContent extends Rule {
|
|
|
8848
8915
|
}
|
|
8849
8916
|
}
|
|
8850
8917
|
|
|
8851
|
-
const defaults$
|
|
8918
|
+
const defaults$4 = {
|
|
8852
8919
|
ignoreCase: false,
|
|
8853
8920
|
requireSemicolon: true,
|
|
8854
8921
|
};
|
|
@@ -8866,16 +8933,11 @@ function getLocation(location, entity, match) {
|
|
|
8866
8933
|
function getDescription(context, options) {
|
|
8867
8934
|
const url = "https://html.spec.whatwg.org/multipage/named-characters.html";
|
|
8868
8935
|
let message;
|
|
8869
|
-
if (context) {
|
|
8870
|
-
|
|
8871
|
-
message = `Unrecognized character reference \`${context.entity}\`.`;
|
|
8872
|
-
}
|
|
8873
|
-
else {
|
|
8874
|
-
message = `Character reference \`${context.entity}\` must be terminated by a semicolon.`;
|
|
8875
|
-
}
|
|
8936
|
+
if (context.terminated) {
|
|
8937
|
+
message = `Unrecognized character reference \`${context.entity}\`.`;
|
|
8876
8938
|
}
|
|
8877
8939
|
else {
|
|
8878
|
-
message = `
|
|
8940
|
+
message = `Character reference \`${context.entity}\` must be terminated by a semicolon.`;
|
|
8879
8941
|
}
|
|
8880
8942
|
return [
|
|
8881
8943
|
message,
|
|
@@ -8890,7 +8952,7 @@ function getDescription(context, options) {
|
|
|
8890
8952
|
}
|
|
8891
8953
|
class UnknownCharReference extends Rule {
|
|
8892
8954
|
constructor(options) {
|
|
8893
|
-
super({ ...defaults$
|
|
8955
|
+
super({ ...defaults$4, ...options });
|
|
8894
8956
|
}
|
|
8895
8957
|
static schema() {
|
|
8896
8958
|
return {
|
|
@@ -9007,12 +9069,12 @@ var RuleContext;
|
|
|
9007
9069
|
RuleContext[RuleContext["LEADING_CHARACTER"] = 3] = "LEADING_CHARACTER";
|
|
9008
9070
|
RuleContext[RuleContext["DISALLOWED_CHARACTER"] = 4] = "DISALLOWED_CHARACTER";
|
|
9009
9071
|
})(RuleContext || (RuleContext = {}));
|
|
9010
|
-
const defaults$
|
|
9072
|
+
const defaults$3 = {
|
|
9011
9073
|
relaxed: false,
|
|
9012
9074
|
};
|
|
9013
9075
|
class ValidID extends Rule {
|
|
9014
9076
|
constructor(options) {
|
|
9015
|
-
super({ ...defaults$
|
|
9077
|
+
super({ ...defaults$3, ...options });
|
|
9016
9078
|
}
|
|
9017
9079
|
static schema() {
|
|
9018
9080
|
return {
|
|
@@ -9023,9 +9085,9 @@ class ValidID extends Rule {
|
|
|
9023
9085
|
}
|
|
9024
9086
|
documentation(context) {
|
|
9025
9087
|
const { relaxed } = this.options;
|
|
9026
|
-
const message = context
|
|
9027
|
-
|
|
9028
|
-
|
|
9088
|
+
const message = this.messages[context]
|
|
9089
|
+
.replace("id", "ID")
|
|
9090
|
+
.replace(/^(.)/, (m) => m.toUpperCase());
|
|
9029
9091
|
const relaxedDescription = relaxed
|
|
9030
9092
|
? []
|
|
9031
9093
|
: [
|
|
@@ -9121,12 +9183,12 @@ var Style;
|
|
|
9121
9183
|
Style[Style["AlwaysOmit"] = 1] = "AlwaysOmit";
|
|
9122
9184
|
Style[Style["AlwaysSelfclose"] = 2] = "AlwaysSelfclose";
|
|
9123
9185
|
})(Style || (Style = {}));
|
|
9124
|
-
const defaults$
|
|
9186
|
+
const defaults$2 = {
|
|
9125
9187
|
style: "omit",
|
|
9126
9188
|
};
|
|
9127
9189
|
class VoidStyle extends Rule {
|
|
9128
9190
|
constructor(options) {
|
|
9129
|
-
super({ ...defaults$
|
|
9191
|
+
super({ ...defaults$2, ...options });
|
|
9130
9192
|
this.style = parseStyle(this.options.style);
|
|
9131
9193
|
}
|
|
9132
9194
|
static schema() {
|
|
@@ -9138,20 +9200,16 @@ class VoidStyle extends Rule {
|
|
|
9138
9200
|
};
|
|
9139
9201
|
}
|
|
9140
9202
|
documentation(context) {
|
|
9141
|
-
const
|
|
9142
|
-
|
|
9203
|
+
const [desc, end] = styleDescription(context.style);
|
|
9204
|
+
return {
|
|
9205
|
+
description: `The current configuration requires void elements to ${desc}, use <${context.tagName}${end}> instead.`,
|
|
9143
9206
|
url: "https://html-validate.org/rules/void-style.html",
|
|
9144
9207
|
};
|
|
9145
|
-
if (context) {
|
|
9146
|
-
const [desc, end] = styleDescription(context.style);
|
|
9147
|
-
doc.description = `The current configuration requires void elements to ${desc}, use <${context.tagName}${end}> instead.`;
|
|
9148
|
-
}
|
|
9149
|
-
return doc;
|
|
9150
9208
|
}
|
|
9151
9209
|
setup() {
|
|
9152
9210
|
this.on("tag:end", (event) => {
|
|
9153
9211
|
const active = event.previous; // The current active element (that is, the current element on the stack)
|
|
9154
|
-
if (active
|
|
9212
|
+
if (active.meta) {
|
|
9155
9213
|
this.validateActive(active);
|
|
9156
9214
|
}
|
|
9157
9215
|
});
|
|
@@ -9323,7 +9381,7 @@ class H36 extends Rule {
|
|
|
9323
9381
|
}
|
|
9324
9382
|
}
|
|
9325
9383
|
|
|
9326
|
-
const defaults$
|
|
9384
|
+
const defaults$1 = {
|
|
9327
9385
|
allowEmpty: true,
|
|
9328
9386
|
alias: [],
|
|
9329
9387
|
};
|
|
@@ -9344,7 +9402,7 @@ function getTag(node) {
|
|
|
9344
9402
|
}
|
|
9345
9403
|
class H37 extends Rule {
|
|
9346
9404
|
constructor(options) {
|
|
9347
|
-
super({ ...defaults$
|
|
9405
|
+
super({ ...defaults$1, ...options });
|
|
9348
9406
|
/* ensure alias is array */
|
|
9349
9407
|
if (!Array.isArray(this.options.alias)) {
|
|
9350
9408
|
this.options.alias = [this.options.alias];
|
|
@@ -9388,7 +9446,8 @@ class H37 extends Rule {
|
|
|
9388
9446
|
return;
|
|
9389
9447
|
}
|
|
9390
9448
|
/* validate plain alt-attribute */
|
|
9391
|
-
if (node.getAttributeValue("alt") ||
|
|
9449
|
+
if (Boolean(node.getAttributeValue("alt")) ||
|
|
9450
|
+
Boolean(node.hasAttribute("alt") && this.options.allowEmpty)) {
|
|
9392
9451
|
return;
|
|
9393
9452
|
}
|
|
9394
9453
|
/* validate if any non-empty alias is present */
|
|
@@ -9570,6 +9629,7 @@ const bundledRules = {
|
|
|
9570
9629
|
"no-missing-references": NoMissingReferences,
|
|
9571
9630
|
"no-multiple-main": NoMultipleMain,
|
|
9572
9631
|
"no-raw-characters": NoRawCharacters,
|
|
9632
|
+
"no-redundant-aria-label": NoRedundantAriaLabel,
|
|
9573
9633
|
"no-redundant-for": NoRedundantFor,
|
|
9574
9634
|
"no-redundant-role": NoRedundantRole,
|
|
9575
9635
|
"no-self-closing": NoSelfClosing,
|
|
@@ -9610,6 +9670,7 @@ const config$4 = {
|
|
|
9610
9670
|
"multiple-labeled-controls": "error",
|
|
9611
9671
|
"no-autoplay": ["error", { include: ["audio", "video"] }],
|
|
9612
9672
|
"no-dup-id": "error",
|
|
9673
|
+
"no-redundant-aria-label": "error",
|
|
9613
9674
|
"no-redundant-for": "error",
|
|
9614
9675
|
"no-redundant-role": "error",
|
|
9615
9676
|
"prefer-native-element": "error",
|
|
@@ -9692,6 +9753,7 @@ const config$1 = {
|
|
|
9692
9753
|
"no-inline-style": "error",
|
|
9693
9754
|
"no-multiple-main": "error",
|
|
9694
9755
|
"no-raw-characters": "error",
|
|
9756
|
+
"no-redundant-aria-label": "error",
|
|
9695
9757
|
"no-redundant-for": "error",
|
|
9696
9758
|
"no-redundant-role": "error",
|
|
9697
9759
|
"no-self-closing": "error",
|
|
@@ -9818,7 +9880,7 @@ class ResolvedConfig {
|
|
|
9818
9880
|
* @returns A list of transformed sources ready for validation.
|
|
9819
9881
|
*/
|
|
9820
9882
|
transformSource(source, filename) {
|
|
9821
|
-
const transformer = this.findTransformer(filename
|
|
9883
|
+
const transformer = this.findTransformer(filename !== null && filename !== void 0 ? filename : source.filename);
|
|
9822
9884
|
const context = {
|
|
9823
9885
|
hasChain: (filename) => {
|
|
9824
9886
|
return !!this.findTransformer(filename);
|
|
@@ -9830,9 +9892,10 @@ class ResolvedConfig {
|
|
|
9830
9892
|
if (transformer) {
|
|
9831
9893
|
try {
|
|
9832
9894
|
return Array.from(transformer.fn.call(context, source), (cur) => {
|
|
9895
|
+
var _a;
|
|
9833
9896
|
/* keep track of which transformers that has been run on this source
|
|
9834
9897
|
* by appending this entry to the transformedBy array */
|
|
9835
|
-
cur.transformedBy
|
|
9898
|
+
(_a = cur.transformedBy) !== null && _a !== void 0 ? _a : (cur.transformedBy = []);
|
|
9836
9899
|
cur.transformedBy.push(transformer.name);
|
|
9837
9900
|
return cur;
|
|
9838
9901
|
});
|
|
@@ -10004,7 +10067,7 @@ function mergeInternal(base, rhs) {
|
|
|
10004
10067
|
}
|
|
10005
10068
|
/* root property is merged with boolean "or" since it should always be truthy
|
|
10006
10069
|
* if any config has it set. */
|
|
10007
|
-
const root = base.root || rhs.root;
|
|
10070
|
+
const root = Boolean(base.root) || Boolean(rhs.root);
|
|
10008
10071
|
if (root) {
|
|
10009
10072
|
dst.root = root;
|
|
10010
10073
|
}
|
|
@@ -10091,7 +10154,7 @@ class Config {
|
|
|
10091
10154
|
* @internal
|
|
10092
10155
|
*/
|
|
10093
10156
|
constructor(resolvers, options) {
|
|
10094
|
-
var _a;
|
|
10157
|
+
var _a, _b;
|
|
10095
10158
|
this.transformers = [];
|
|
10096
10159
|
const initial = {
|
|
10097
10160
|
extends: [],
|
|
@@ -10104,18 +10167,18 @@ class Config {
|
|
|
10104
10167
|
this.initialized = false;
|
|
10105
10168
|
this.resolvers = toArray(resolvers);
|
|
10106
10169
|
/* load plugins */
|
|
10107
|
-
this.plugins = this.loadPlugins(this.config.plugins
|
|
10170
|
+
this.plugins = this.loadPlugins((_a = this.config.plugins) !== null && _a !== void 0 ? _a : []);
|
|
10108
10171
|
this.configurations = this.loadConfigurations(this.plugins);
|
|
10109
10172
|
this.extendMeta(this.plugins);
|
|
10110
10173
|
/* process extended configs */
|
|
10111
|
-
this.config = this.extendConfig((
|
|
10174
|
+
this.config = this.extendConfig((_b = this.config.extends) !== null && _b !== void 0 ? _b : []);
|
|
10112
10175
|
/* reset extends as we already processed them, this prevents the next config
|
|
10113
10176
|
* from reapplying config from extended config as well as duplicate entries
|
|
10114
10177
|
* when merging arrays */
|
|
10115
10178
|
this.config.extends = [];
|
|
10116
10179
|
/* rules explicitly set by passed options should have precedence over any
|
|
10117
10180
|
* extended rules, not the other way around. */
|
|
10118
|
-
if (options
|
|
10181
|
+
if (options === null || options === void 0 ? void 0 : options.rules) {
|
|
10119
10182
|
this.config = mergeInternal(this.config, { rules: options.rules });
|
|
10120
10183
|
}
|
|
10121
10184
|
}
|
|
@@ -10128,11 +10191,12 @@ class Config {
|
|
|
10128
10191
|
* @public
|
|
10129
10192
|
*/
|
|
10130
10193
|
init() {
|
|
10194
|
+
var _a;
|
|
10131
10195
|
if (this.initialized) {
|
|
10132
10196
|
return;
|
|
10133
10197
|
}
|
|
10134
10198
|
/* precompile transform patterns */
|
|
10135
|
-
this.transformers = this.precompileTransformers(this.config.transform
|
|
10199
|
+
this.transformers = this.precompileTransformers((_a = this.config.transform) !== null && _a !== void 0 ? _a : {});
|
|
10136
10200
|
this.initialized = true;
|
|
10137
10201
|
}
|
|
10138
10202
|
/**
|
|
@@ -10156,11 +10220,10 @@ class Config {
|
|
|
10156
10220
|
return this.config;
|
|
10157
10221
|
}
|
|
10158
10222
|
let base = {};
|
|
10159
|
-
for (
|
|
10160
|
-
const entry = entries[i];
|
|
10223
|
+
for (const entry of entries) {
|
|
10161
10224
|
let extended;
|
|
10162
10225
|
if (this.configurations.has(entry)) {
|
|
10163
|
-
extended = this.configurations.get(entry);
|
|
10226
|
+
extended = this.configurations.get(entry); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- map has/get combo
|
|
10164
10227
|
}
|
|
10165
10228
|
else {
|
|
10166
10229
|
extended = Config.fromFile(this.resolvers, entry).config;
|
|
@@ -10175,12 +10238,13 @@ class Config {
|
|
|
10175
10238
|
* @internal
|
|
10176
10239
|
*/
|
|
10177
10240
|
getMetaTable() {
|
|
10241
|
+
var _a;
|
|
10178
10242
|
/* use cached table if it exists */
|
|
10179
10243
|
if (this.metaTable) {
|
|
10180
10244
|
return this.metaTable;
|
|
10181
10245
|
}
|
|
10182
10246
|
const metaTable = new MetaTable();
|
|
10183
|
-
const source = this.config.elements
|
|
10247
|
+
const source = (_a = this.config.elements) !== null && _a !== void 0 ? _a : ["html5"];
|
|
10184
10248
|
/* extend validation schema from plugins */
|
|
10185
10249
|
for (const plugin of this.getPlugins()) {
|
|
10186
10250
|
if (plugin.elementSchema) {
|
|
@@ -10278,6 +10342,7 @@ class Config {
|
|
|
10278
10342
|
});
|
|
10279
10343
|
}
|
|
10280
10344
|
loadConfigurations(plugins) {
|
|
10345
|
+
var _a;
|
|
10281
10346
|
const configs = new Map();
|
|
10282
10347
|
/* builtin presets */
|
|
10283
10348
|
for (const [name, config] of Object.entries(Presets)) {
|
|
@@ -10286,7 +10351,7 @@ class Config {
|
|
|
10286
10351
|
}
|
|
10287
10352
|
/* presets from plugins */
|
|
10288
10353
|
for (const plugin of plugins) {
|
|
10289
|
-
for (const [name, config] of Object.entries(plugin.configs
|
|
10354
|
+
for (const [name, config] of Object.entries((_a = plugin.configs) !== null && _a !== void 0 ? _a : {})) {
|
|
10290
10355
|
if (!config)
|
|
10291
10356
|
continue;
|
|
10292
10357
|
Config.validate(config, name);
|
|
@@ -10651,10 +10716,11 @@ class Parser {
|
|
|
10651
10716
|
* stack when is allowed to omit.
|
|
10652
10717
|
*/
|
|
10653
10718
|
closeOptional(token) {
|
|
10719
|
+
var _a;
|
|
10654
10720
|
/* if the element doesn't have metadata it cannot have optional end
|
|
10655
10721
|
* tags. Period. */
|
|
10656
10722
|
const active = this.dom.getActive();
|
|
10657
|
-
if (!(active.meta
|
|
10723
|
+
if (!((_a = active.meta) === null || _a === void 0 ? void 0 : _a.implicitClosed)) {
|
|
10658
10724
|
return false;
|
|
10659
10725
|
}
|
|
10660
10726
|
const tagName = token.data[2];
|
|
@@ -10806,9 +10872,10 @@ class Parser {
|
|
|
10806
10872
|
}
|
|
10807
10873
|
}
|
|
10808
10874
|
processElement(node, source) {
|
|
10875
|
+
var _a;
|
|
10809
10876
|
/* enable cache on node now that it is fully constructed */
|
|
10810
10877
|
node.cacheEnable();
|
|
10811
|
-
if (source.hooks
|
|
10878
|
+
if ((_a = source.hooks) === null || _a === void 0 ? void 0 : _a.processElement) {
|
|
10812
10879
|
const processElement = source.hooks.processElement;
|
|
10813
10880
|
const metaTable = this.metaTable;
|
|
10814
10881
|
const context = {
|
|
@@ -10875,6 +10942,7 @@ class Parser {
|
|
|
10875
10942
|
* @internal
|
|
10876
10943
|
*/
|
|
10877
10944
|
consumeAttribute(source, node, token, next) {
|
|
10945
|
+
var _a;
|
|
10878
10946
|
const keyLocation = this.getAttributeKeyLocation(token);
|
|
10879
10947
|
const valueLocation = this.getAttributeValueLocation(next);
|
|
10880
10948
|
const location = this.getAttributeLocation(token, next);
|
|
@@ -10893,7 +10961,7 @@ class Parser {
|
|
|
10893
10961
|
* data right away but a transformer may override it to allow aliasing
|
|
10894
10962
|
* attributes, e.g ng-attr-foo or v-bind:foo */
|
|
10895
10963
|
let processAttribute = (attr) => [attr];
|
|
10896
|
-
if (source.hooks
|
|
10964
|
+
if ((_a = source.hooks) === null || _a === void 0 ? void 0 : _a.processAttribute) {
|
|
10897
10965
|
processAttribute = source.hooks.processAttribute;
|
|
10898
10966
|
}
|
|
10899
10967
|
/* handle deprecated callbacks */
|
|
@@ -11243,14 +11311,15 @@ class Reporter {
|
|
|
11243
11311
|
const report = {
|
|
11244
11312
|
valid: this.isValid(),
|
|
11245
11313
|
results: Object.keys(this.result).map((filePath) => {
|
|
11314
|
+
var _a;
|
|
11246
11315
|
const messages = Array.from(this.result[filePath], freeze).sort(messageSort);
|
|
11247
|
-
const source = (sources
|
|
11316
|
+
const source = (sources !== null && sources !== void 0 ? sources : []).find((source) => { var _a; return filePath === ((_a = source.filename) !== null && _a !== void 0 ? _a : ""); });
|
|
11248
11317
|
return {
|
|
11249
11318
|
filePath,
|
|
11250
11319
|
messages,
|
|
11251
11320
|
errorCount: countErrors(messages),
|
|
11252
11321
|
warningCount: countWarnings(messages),
|
|
11253
|
-
source: source ? source.originalData
|
|
11322
|
+
source: source ? (_a = source.originalData) !== null && _a !== void 0 ? _a : source.data : null,
|
|
11254
11323
|
};
|
|
11255
11324
|
}),
|
|
11256
11325
|
errorCount: 0,
|
|
@@ -11268,10 +11337,10 @@ class Reporter {
|
|
|
11268
11337
|
}
|
|
11269
11338
|
}
|
|
11270
11339
|
function countErrors(messages) {
|
|
11271
|
-
return messages.filter((m) => m.severity === Severity.ERROR).length;
|
|
11340
|
+
return messages.filter((m) => m.severity === Number(Severity.ERROR)).length;
|
|
11272
11341
|
}
|
|
11273
11342
|
function countWarnings(messages) {
|
|
11274
|
-
return messages.filter((m) => m.severity === Severity.WARN).length;
|
|
11343
|
+
return messages.filter((m) => m.severity === Number(Severity.WARN)).length;
|
|
11275
11344
|
}
|
|
11276
11345
|
function sumErrors(results) {
|
|
11277
11346
|
return results.reduce((sum, result) => {
|
|
@@ -11449,7 +11518,9 @@ class Engine {
|
|
|
11449
11518
|
else {
|
|
11450
11519
|
lines.push("(root)");
|
|
11451
11520
|
}
|
|
11452
|
-
node.childElements.forEach((child, index) =>
|
|
11521
|
+
node.childElements.forEach((child, index) => {
|
|
11522
|
+
writeNode(child, level + 1, index);
|
|
11523
|
+
});
|
|
11453
11524
|
}
|
|
11454
11525
|
writeNode(document, 0, 0);
|
|
11455
11526
|
return lines;
|
|
@@ -11614,9 +11685,10 @@ class Engine {
|
|
|
11614
11685
|
* between rule name and its constructor.
|
|
11615
11686
|
*/
|
|
11616
11687
|
initRules(config) {
|
|
11688
|
+
var _a;
|
|
11617
11689
|
const availableRules = {};
|
|
11618
11690
|
for (const plugin of config.getPlugins()) {
|
|
11619
|
-
for (const [name, rule] of Object.entries(plugin.rules
|
|
11691
|
+
for (const [name, rule] of Object.entries((_a = plugin.rules) !== null && _a !== void 0 ? _a : {})) {
|
|
11620
11692
|
if (!rule)
|
|
11621
11693
|
continue;
|
|
11622
11694
|
availableRules[name] = rule;
|
|
@@ -11719,7 +11791,7 @@ class StaticConfigLoader extends ConfigLoader {
|
|
|
11719
11791
|
}
|
|
11720
11792
|
}
|
|
11721
11793
|
getConfigFor(_handle, configOverride) {
|
|
11722
|
-
const override = this.loadFromObject(configOverride
|
|
11794
|
+
const override = this.loadFromObject(configOverride !== null && configOverride !== void 0 ? configOverride : {});
|
|
11723
11795
|
if (override.isRootFound()) {
|
|
11724
11796
|
override.init();
|
|
11725
11797
|
return override.resolve();
|
|
@@ -11763,6 +11835,7 @@ class HtmlValidate {
|
|
|
11763
11835
|
const [loader, config] = arg instanceof ConfigLoader ? [arg, undefined] : [undefined, arg];
|
|
11764
11836
|
this.configLoader = loader !== null && loader !== void 0 ? loader : new StaticConfigLoader(config);
|
|
11765
11837
|
}
|
|
11838
|
+
/* eslint-enable @typescript-eslint/unified-signatures */
|
|
11766
11839
|
validateString(str, arg1, arg2, arg3) {
|
|
11767
11840
|
const filename = typeof arg1 === "string" ? arg1 : "inline";
|
|
11768
11841
|
const options = isConfigData(arg1) ? arg1 : isConfigData(arg2) ? arg2 : undefined;
|
|
@@ -11777,6 +11850,7 @@ class HtmlValidate {
|
|
|
11777
11850
|
};
|
|
11778
11851
|
return this.validateSource(source, options);
|
|
11779
11852
|
}
|
|
11853
|
+
/* eslint-enable @typescript-eslint/unified-signatures */
|
|
11780
11854
|
validateStringSync(str, arg1, arg2, arg3) {
|
|
11781
11855
|
const filename = typeof arg1 === "string" ? arg1 : "inline";
|
|
11782
11856
|
const options = isConfigData(arg1) ? arg1 : isConfigData(arg2) ? arg2 : undefined;
|
|
@@ -12048,7 +12122,7 @@ class HtmlValidate {
|
|
|
12048
12122
|
* contextual details and suggestions.
|
|
12049
12123
|
*/
|
|
12050
12124
|
async getRuleDocumentation(ruleId, config = null, context = null) {
|
|
12051
|
-
const c = config
|
|
12125
|
+
const c = config !== null && config !== void 0 ? config : this.getConfigFor("inline");
|
|
12052
12126
|
const engine = new Engine(await c, Parser);
|
|
12053
12127
|
return engine.getRuleDocumentation({ ruleId, context });
|
|
12054
12128
|
}
|
|
@@ -12077,7 +12151,7 @@ class HtmlValidate {
|
|
|
12077
12151
|
* contextual details and suggestions.
|
|
12078
12152
|
*/
|
|
12079
12153
|
getRuleDocumentationSync(ruleId, config = null, context = null) {
|
|
12080
|
-
const c = config
|
|
12154
|
+
const c = config !== null && config !== void 0 ? config : this.getConfigForSync("inline");
|
|
12081
12155
|
const engine = new Engine(c, Parser);
|
|
12082
12156
|
return engine.getRuleDocumentation({ ruleId, context });
|
|
12083
12157
|
}
|
|
@@ -12133,7 +12207,7 @@ class HtmlValidate {
|
|
|
12133
12207
|
/** @public */
|
|
12134
12208
|
const name = "html-validate";
|
|
12135
12209
|
/** @public */
|
|
12136
|
-
const version = "8.0
|
|
12210
|
+
const version = "8.2.0";
|
|
12137
12211
|
/** @public */
|
|
12138
12212
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
12139
12213
|
|
|
@@ -12146,61 +12220,6 @@ function definePlugin(plugin) {
|
|
|
12146
12220
|
return plugin;
|
|
12147
12221
|
}
|
|
12148
12222
|
|
|
12149
|
-
const defaults$1 = {
|
|
12150
|
-
silent: false,
|
|
12151
|
-
version,
|
|
12152
|
-
logger(text) {
|
|
12153
|
-
/* eslint-disable-next-line no-console -- expected to log */
|
|
12154
|
-
console.error(kleur.red(text));
|
|
12155
|
-
},
|
|
12156
|
-
};
|
|
12157
|
-
/**
|
|
12158
|
-
* Tests if plugin is compatible with html-validate library. Unless the `silent`
|
|
12159
|
-
* option is used a warning is displayed on the console.
|
|
12160
|
-
*
|
|
12161
|
-
* @public
|
|
12162
|
-
* @since v5.0.0
|
|
12163
|
-
* @param name - Name of plugin
|
|
12164
|
-
* @param declared - What library versions the plugin support (e.g. declared peerDependencies)
|
|
12165
|
-
* @returns - `true` if version is compatible
|
|
12166
|
-
*/
|
|
12167
|
-
function compatibilityCheck(name, declared, options) {
|
|
12168
|
-
const { silent, version: current, logger } = { ...defaults$1, ...options };
|
|
12169
|
-
const valid = semver.satisfies(current, declared);
|
|
12170
|
-
if (valid || silent) {
|
|
12171
|
-
return valid;
|
|
12172
|
-
}
|
|
12173
|
-
const text = [
|
|
12174
|
-
"-----------------------------------------------------------------------------------------------------",
|
|
12175
|
-
`${name} requires html-validate version "${declared}" but current installed version is ${current}`,
|
|
12176
|
-
"This is not a supported configuration. Please install a supported version before reporting bugs.",
|
|
12177
|
-
"-----------------------------------------------------------------------------------------------------",
|
|
12178
|
-
].join("\n");
|
|
12179
|
-
logger(text);
|
|
12180
|
-
return false;
|
|
12181
|
-
}
|
|
12182
|
-
|
|
12183
|
-
/**
|
|
12184
|
-
* Similar to `require(..)` but removes the cached copy first.
|
|
12185
|
-
*/
|
|
12186
|
-
function requireUncached(require, moduleId) {
|
|
12187
|
-
const filename = require.resolve(moduleId);
|
|
12188
|
-
/* remove references from the parent module to prevent memory leak */
|
|
12189
|
-
const m = require.cache[filename];
|
|
12190
|
-
if (m && m.parent) {
|
|
12191
|
-
const { parent } = m;
|
|
12192
|
-
for (let i = parent.children.length - 1; i >= 0; i--) {
|
|
12193
|
-
if (parent.children[i].id === filename) {
|
|
12194
|
-
parent.children.splice(i, 1);
|
|
12195
|
-
}
|
|
12196
|
-
}
|
|
12197
|
-
}
|
|
12198
|
-
/* remove old module from cache */
|
|
12199
|
-
delete require.cache[filename];
|
|
12200
|
-
/* eslint-disable-next-line import/no-dynamic-require, security/detect-non-literal-require -- as expected but should be moved to upcoming resolver class */
|
|
12201
|
-
return require(filename);
|
|
12202
|
-
}
|
|
12203
|
-
|
|
12204
12223
|
const ruleIds = new Set(Object.keys(rules));
|
|
12205
12224
|
/**
|
|
12206
12225
|
* Returns true if given ruleId is an existing builtin rule. It does not handle
|
|
@@ -12467,5 +12486,24 @@ function getFormatter(name) {
|
|
|
12467
12486
|
return (_a = availableFormatters[name]) !== null && _a !== void 0 ? _a : null;
|
|
12468
12487
|
}
|
|
12469
12488
|
|
|
12470
|
-
|
|
12489
|
+
/**
|
|
12490
|
+
* @internal
|
|
12491
|
+
*/
|
|
12492
|
+
function compatibilityCheckImpl(name, declared, options) {
|
|
12493
|
+
const { silent, version: current, logger } = options;
|
|
12494
|
+
const valid = semver.satisfies(current, declared);
|
|
12495
|
+
if (valid || silent) {
|
|
12496
|
+
return valid;
|
|
12497
|
+
}
|
|
12498
|
+
const text = [
|
|
12499
|
+
"-----------------------------------------------------------------------------------------------------",
|
|
12500
|
+
`${name} requires html-validate version "${declared}" but current installed version is ${current}`,
|
|
12501
|
+
"This is not a supported configuration. Please install a supported version before reporting bugs.",
|
|
12502
|
+
"-----------------------------------------------------------------------------------------------------",
|
|
12503
|
+
].join("\n");
|
|
12504
|
+
logger(text);
|
|
12505
|
+
return false;
|
|
12506
|
+
}
|
|
12507
|
+
|
|
12508
|
+
export { Attribute as A, codeframe as B, Config as C, DOMNode as D, EventHandler as E, name as F, bugs as G, HtmlValidate as H, MetaCopyableProperty as M, NodeClosed as N, Presets as P, ResolvedConfig as R, Severity as S, TextNode as T, UserError as U, Validator as V, WrappedError as W, ConfigError as a, ConfigLoader as b, StaticConfigLoader as c, DOMTokenList as d, ensureError as e, DOMTree as f, getFormatter as g, DynamicValue as h, HtmlElement as i, NodeType as j, NestedError as k, SchemaValidationError as l, MetaTable as m, TextContent$1 as n, Rule as o, TextClassification as p, classifyNodeText as q, keywordPatternMatcher as r, staticResolver as s, sliceLocation as t, Reporter as u, version as v, definePlugin as w, Parser as x, ruleExists as y, compatibilityCheckImpl as z };
|
|
12471
12509
|
//# sourceMappingURL=core.js.map
|