html-validate 8.1.0 → 8.3.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/cli.js +36 -10
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core-nodejs.js +3 -2
- package/dist/cjs/core-nodejs.js.map +1 -1
- package/dist/cjs/core.js +198 -114
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +29 -5
- package/dist/cjs/elements.js.map +1 -1
- package/dist/cjs/html-validate.js +2 -2
- package/dist/cjs/html-validate.js.map +1 -1
- package/dist/cjs/jest-lib.js +3 -3
- package/dist/cjs/jest-lib.js.map +1 -1
- 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 +1 -1
- package/dist/es/cli.js +36 -10
- package/dist/es/cli.js.map +1 -1
- package/dist/es/core-nodejs.js +3 -2
- package/dist/es/core-nodejs.js.map +1 -1
- package/dist/es/core.js +199 -115
- package/dist/es/core.js.map +1 -1
- package/dist/es/elements.js +29 -5
- package/dist/es/elements.js.map +1 -1
- package/dist/es/html-validate.js +3 -3
- package/dist/es/html-validate.js.map +1 -1
- package/dist/es/index.js +1 -1
- package/dist/es/jest-lib.js +3 -3
- package/dist/es/jest-lib.js.map +1 -1
- 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 +33 -56
- package/dist/types/index.d.ts +33 -56
- package/dist/types/jest.d.ts +4 -8
- package/package.json +19 -19
package/dist/es/core.js
CHANGED
|
@@ -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;
|
|
@@ -2716,6 +2745,7 @@ const allowedKeys = ["exclude"];
|
|
|
2716
2745
|
*
|
|
2717
2746
|
* @public
|
|
2718
2747
|
*/
|
|
2748
|
+
/* eslint-disable-next-line @typescript-eslint/no-extraneous-class -- technical debt, should probably be plain functions maybe in an object */
|
|
2719
2749
|
class Validator {
|
|
2720
2750
|
/**
|
|
2721
2751
|
* Test if element is used in a proper context.
|
|
@@ -2757,7 +2787,7 @@ class Validator {
|
|
|
2757
2787
|
return false;
|
|
2758
2788
|
}
|
|
2759
2789
|
// Check if the rule has a quantifier
|
|
2760
|
-
const [, category, quantifier] = rule.match(/^(@?.*?)([?*]?)$/);
|
|
2790
|
+
const [, category, quantifier] = rule.match(/^(@?.*?)([?*]?)$/); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- will always match
|
|
2761
2791
|
const limit = category && quantifier && parseQuantifier(quantifier);
|
|
2762
2792
|
if (limit) {
|
|
2763
2793
|
const siblings = children.filter((cur) => Validator.validatePermittedCategory(cur, rule, true));
|
|
@@ -2803,6 +2833,7 @@ class Validator {
|
|
|
2803
2833
|
* In both of these cases no error should be reported. */
|
|
2804
2834
|
const orderSpecified = rules.find((cur) => Validator.validatePermittedCategory(node, cur, true));
|
|
2805
2835
|
if (orderSpecified) {
|
|
2836
|
+
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- technical debt, should never happen */
|
|
2806
2837
|
cb(node, prev);
|
|
2807
2838
|
return false;
|
|
2808
2839
|
}
|
|
@@ -2943,7 +2974,7 @@ class Validator {
|
|
|
2943
2974
|
*/
|
|
2944
2975
|
/* eslint-disable-next-line complexity -- rule does not like switch */
|
|
2945
2976
|
static validatePermittedCategory(node, category, defaultMatch) {
|
|
2946
|
-
const [, rawCategory] = category.match(/^(@?.*?)([?*]?)$/);
|
|
2977
|
+
const [, rawCategory] = category.match(/^(@?.*?)([?*]?)$/); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- will always match
|
|
2947
2978
|
/* match tagName when an explicit name is given */
|
|
2948
2979
|
if (!rawCategory.startsWith("@")) {
|
|
2949
2980
|
return node.tagName === rawCategory;
|
|
@@ -2968,9 +2999,9 @@ class Validator {
|
|
|
2968
2999
|
case "@interactive":
|
|
2969
3000
|
return node.meta.interactive;
|
|
2970
3001
|
case "@script":
|
|
2971
|
-
return node.meta.scriptSupporting;
|
|
3002
|
+
return Boolean(node.meta.scriptSupporting);
|
|
2972
3003
|
case "@form":
|
|
2973
|
-
return node.meta.form;
|
|
3004
|
+
return Boolean(node.meta.form);
|
|
2974
3005
|
default:
|
|
2975
3006
|
throw new Error(`Invalid content category "${category}"`);
|
|
2976
3007
|
}
|
|
@@ -3155,10 +3186,12 @@ var configurationSchema = {
|
|
|
3155
3186
|
properties: properties
|
|
3156
3187
|
};
|
|
3157
3188
|
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3189
|
+
/**
|
|
3190
|
+
* @internal
|
|
3191
|
+
*/
|
|
3192
|
+
const TRANSFORMER_API = {
|
|
3193
|
+
VERSION: 1,
|
|
3194
|
+
};
|
|
3162
3195
|
|
|
3163
3196
|
/**
|
|
3164
3197
|
* @public
|
|
@@ -3405,7 +3438,7 @@ function classifyNodeText(node, options = {}) {
|
|
|
3405
3438
|
const { accessible = false, ignoreHiddenRoot = false } = options;
|
|
3406
3439
|
const cacheKey = getCachekey(options);
|
|
3407
3440
|
if (node.cacheExists(cacheKey)) {
|
|
3408
|
-
return node.cacheGet(cacheKey);
|
|
3441
|
+
return node.cacheGet(cacheKey); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- has/get combo
|
|
3409
3442
|
}
|
|
3410
3443
|
if (!ignoreHiddenRoot && isHTMLHidden(node)) {
|
|
3411
3444
|
return node.cacheSet(cacheKey, TextClassification.EMPTY_TEXT);
|
|
@@ -3453,8 +3486,12 @@ function findTextNodes(node, options) {
|
|
|
3453
3486
|
|
|
3454
3487
|
function hasAltText(image) {
|
|
3455
3488
|
const alt = image.getAttribute("alt");
|
|
3456
|
-
/* missing
|
|
3457
|
-
if (alt
|
|
3489
|
+
/* missing attribute */
|
|
3490
|
+
if (!alt) {
|
|
3491
|
+
return false;
|
|
3492
|
+
}
|
|
3493
|
+
/* (incorrectly) set as boolean value */
|
|
3494
|
+
if (alt.value === null) {
|
|
3458
3495
|
return false;
|
|
3459
3496
|
}
|
|
3460
3497
|
return alt.isDynamic || alt.value.toString() !== "";
|
|
@@ -3462,8 +3499,12 @@ function hasAltText(image) {
|
|
|
3462
3499
|
|
|
3463
3500
|
function hasAriaLabel(node) {
|
|
3464
3501
|
const label = node.getAttribute("aria-label");
|
|
3465
|
-
/* missing
|
|
3466
|
-
if (label
|
|
3502
|
+
/* missing attribute */
|
|
3503
|
+
if (!label) {
|
|
3504
|
+
return false;
|
|
3505
|
+
}
|
|
3506
|
+
/* (incorrectly) set as boolean value */
|
|
3507
|
+
if (label.value === null) {
|
|
3467
3508
|
return false;
|
|
3468
3509
|
}
|
|
3469
3510
|
return label.isDynamic || label.value.toString() !== "";
|
|
@@ -3544,7 +3585,7 @@ class Rule {
|
|
|
3544
3585
|
this.options = options;
|
|
3545
3586
|
this.enabled = true;
|
|
3546
3587
|
this.blockers = [];
|
|
3547
|
-
this.severity =
|
|
3588
|
+
this.severity = Severity.DISABLED;
|
|
3548
3589
|
this.name = "";
|
|
3549
3590
|
}
|
|
3550
3591
|
getSeverity() {
|
|
@@ -3697,13 +3738,14 @@ class Rule {
|
|
|
3697
3738
|
}
|
|
3698
3739
|
}
|
|
3699
3740
|
findLocation(src) {
|
|
3741
|
+
var _a, _b;
|
|
3700
3742
|
if (src.location) {
|
|
3701
3743
|
return src.location;
|
|
3702
3744
|
}
|
|
3703
|
-
if (src.event
|
|
3745
|
+
if ((_a = src.event) === null || _a === void 0 ? void 0 : _a.location) {
|
|
3704
3746
|
return src.event.location;
|
|
3705
3747
|
}
|
|
3706
|
-
if (src.node
|
|
3748
|
+
if ((_b = src.node) === null || _b === void 0 ? void 0 : _b.location) {
|
|
3707
3749
|
return src.node.location;
|
|
3708
3750
|
}
|
|
3709
3751
|
return {};
|
|
@@ -3876,7 +3918,8 @@ class AllowedLinks extends Rule {
|
|
|
3876
3918
|
};
|
|
3877
3919
|
}
|
|
3878
3920
|
documentation(context) {
|
|
3879
|
-
|
|
3921
|
+
var _a;
|
|
3922
|
+
const message = (_a = description[context]) !== null && _a !== void 0 ? _a : "This link type is not allowed by current configuration";
|
|
3880
3923
|
return {
|
|
3881
3924
|
description: message,
|
|
3882
3925
|
url: "https://html-validate.org/rules/allowed-links.html",
|
|
@@ -4140,7 +4183,7 @@ function isValidUsage(target, meta) {
|
|
|
4140
4183
|
return true;
|
|
4141
4184
|
}
|
|
4142
4185
|
/* interactive and labelable elements are valid */
|
|
4143
|
-
if (meta.interactive || meta.labelable) {
|
|
4186
|
+
if (Boolean(meta.interactive) || Boolean(meta.labelable)) {
|
|
4144
4187
|
return true;
|
|
4145
4188
|
}
|
|
4146
4189
|
return false;
|
|
@@ -4175,7 +4218,7 @@ class AriaLabelMisuse extends Rule {
|
|
|
4175
4218
|
}
|
|
4176
4219
|
validateElement(target) {
|
|
4177
4220
|
const attr = target.getAttribute("aria-label");
|
|
4178
|
-
if (!attr ||
|
|
4221
|
+
if (!(attr === null || attr === void 0 ? void 0 : attr.value) || attr.valueMatches("", false)) {
|
|
4179
4222
|
return;
|
|
4180
4223
|
}
|
|
4181
4224
|
/* ignore elements without meta */
|
|
@@ -4906,7 +4949,7 @@ class AttributeAllowedValues extends Rule {
|
|
|
4906
4949
|
const meta = node.meta;
|
|
4907
4950
|
/* ignore rule if element has no meta or meta does not specify attribute
|
|
4908
4951
|
* allowed values */
|
|
4909
|
-
if (!meta ||
|
|
4952
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes))
|
|
4910
4953
|
return;
|
|
4911
4954
|
for (const attr of node.attributes) {
|
|
4912
4955
|
if (Validator.validateAttribute(attr, meta.attributes)) {
|
|
@@ -4974,7 +5017,7 @@ class AttributeBooleanStyle extends Rule {
|
|
|
4974
5017
|
const meta = node.meta;
|
|
4975
5018
|
/* ignore rule if element has no meta or meta does not specify attribute
|
|
4976
5019
|
* allowed values */
|
|
4977
|
-
if (!meta ||
|
|
5020
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes))
|
|
4978
5021
|
return;
|
|
4979
5022
|
/* check all boolean attributes */
|
|
4980
5023
|
for (const attr of node.attributes) {
|
|
@@ -5055,7 +5098,7 @@ class AttributeEmptyStyle extends Rule {
|
|
|
5055
5098
|
const meta = node.meta;
|
|
5056
5099
|
/* ignore rule if element has no meta or meta does not specify attribute
|
|
5057
5100
|
* allowed values */
|
|
5058
|
-
if (!meta ||
|
|
5101
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes))
|
|
5059
5102
|
return;
|
|
5060
5103
|
/* check all boolean attributes */
|
|
5061
5104
|
for (const attr of node.attributes) {
|
|
@@ -5143,10 +5186,10 @@ class AttributeMisuse extends Rule {
|
|
|
5143
5186
|
});
|
|
5144
5187
|
}
|
|
5145
5188
|
validateAttr(node, attr, meta) {
|
|
5146
|
-
if (!meta ||
|
|
5189
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.allowed)) {
|
|
5147
5190
|
return;
|
|
5148
5191
|
}
|
|
5149
|
-
const details = meta.allowed(node, attr);
|
|
5192
|
+
const details = meta.allowed(node._adapter, attr.value);
|
|
5150
5193
|
if (details) {
|
|
5151
5194
|
this.report({
|
|
5152
5195
|
node,
|
|
@@ -5817,7 +5860,7 @@ class ElementPermittedOccurrences extends Rule {
|
|
|
5817
5860
|
this.on("dom:ready", (event) => {
|
|
5818
5861
|
const doc = event.document;
|
|
5819
5862
|
doc.visitDepthFirst((node) => {
|
|
5820
|
-
if (!node ||
|
|
5863
|
+
if (!(node === null || node === void 0 ? void 0 : node.meta)) {
|
|
5821
5864
|
return;
|
|
5822
5865
|
}
|
|
5823
5866
|
const rules = node.meta.permittedContent;
|
|
@@ -6022,7 +6065,7 @@ class ElementRequiredAttributes extends Rule {
|
|
|
6022
6065
|
const node = event.previous;
|
|
6023
6066
|
const meta = node.meta;
|
|
6024
6067
|
/* handle missing metadata and missing attributes */
|
|
6025
|
-
if (!meta ||
|
|
6068
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.attributes)) {
|
|
6026
6069
|
return;
|
|
6027
6070
|
}
|
|
6028
6071
|
for (const [key, attr] of Object.entries(meta.attributes)) {
|
|
@@ -6334,7 +6377,7 @@ class FormDupName extends Rule {
|
|
|
6334
6377
|
const meta = this.getMetaFor(tagName);
|
|
6335
6378
|
/* istanbul ignore if: the earlier check for getTagsWithProperty ensures
|
|
6336
6379
|
* these will actually be set so this is just an untestable fallback */
|
|
6337
|
-
if (!meta ||
|
|
6380
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.formAssociated)) {
|
|
6338
6381
|
return false;
|
|
6339
6382
|
}
|
|
6340
6383
|
return meta.formAssociated.listed;
|
|
@@ -6368,7 +6411,7 @@ const defaults$h = {
|
|
|
6368
6411
|
minInitialRank: "h1",
|
|
6369
6412
|
sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]'],
|
|
6370
6413
|
};
|
|
6371
|
-
function isRelevant$
|
|
6414
|
+
function isRelevant$4(event) {
|
|
6372
6415
|
const node = event.target;
|
|
6373
6416
|
return Boolean(node.meta && node.meta.heading);
|
|
6374
6417
|
}
|
|
@@ -6436,7 +6479,7 @@ class HeadingLevel extends Rule {
|
|
|
6436
6479
|
};
|
|
6437
6480
|
}
|
|
6438
6481
|
setup() {
|
|
6439
|
-
this.on("tag:start", isRelevant$
|
|
6482
|
+
this.on("tag:start", isRelevant$4, (event) => {
|
|
6440
6483
|
this.onTagStart(event);
|
|
6441
6484
|
});
|
|
6442
6485
|
this.on("tag:ready", (event) => {
|
|
@@ -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);
|
|
@@ -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 */
|
|
@@ -7096,7 +7139,7 @@ class MapDupName extends Rule {
|
|
|
7096
7139
|
}
|
|
7097
7140
|
}
|
|
7098
7141
|
|
|
7099
|
-
function isRelevant$
|
|
7142
|
+
function isRelevant$3(event) {
|
|
7100
7143
|
return event.target.is("map");
|
|
7101
7144
|
}
|
|
7102
7145
|
function hasStaticValue(attr) {
|
|
@@ -7110,7 +7153,7 @@ class MapIdName extends Rule {
|
|
|
7110
7153
|
};
|
|
7111
7154
|
}
|
|
7112
7155
|
setup() {
|
|
7113
|
-
this.on("tag:ready", isRelevant$
|
|
7156
|
+
this.on("tag:ready", isRelevant$3, (event) => {
|
|
7114
7157
|
var _a;
|
|
7115
7158
|
const { target } = event;
|
|
7116
7159
|
const id = target.getAttribute("id");
|
|
@@ -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
|
}
|
|
@@ -7374,11 +7417,11 @@ class NoDupID extends Rule {
|
|
|
7374
7417
|
const { document } = event;
|
|
7375
7418
|
const existing = new Set();
|
|
7376
7419
|
const elements = document.querySelectorAll("[id]");
|
|
7377
|
-
const relevant = elements.filter(isRelevant$
|
|
7420
|
+
const relevant = elements.filter(isRelevant$2);
|
|
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();
|
|
@@ -7390,7 +7433,7 @@ class NoDupID extends Rule {
|
|
|
7390
7433
|
});
|
|
7391
7434
|
}
|
|
7392
7435
|
}
|
|
7393
|
-
function isRelevant$
|
|
7436
|
+
function isRelevant$2(element) {
|
|
7394
7437
|
const attr = element.getAttribute("id");
|
|
7395
7438
|
/* istanbul ignore next: can not really happen as querySelector will only return elements with id present */
|
|
7396
7439
|
if (!attr) {
|
|
@@ -7407,6 +7450,41 @@ function isRelevant$1(element) {
|
|
|
7407
7450
|
return true;
|
|
7408
7451
|
}
|
|
7409
7452
|
|
|
7453
|
+
function isRelevant$1(event) {
|
|
7454
|
+
return event.target.is("button");
|
|
7455
|
+
}
|
|
7456
|
+
class NoImplicitButtonType extends Rule {
|
|
7457
|
+
documentation() {
|
|
7458
|
+
return {
|
|
7459
|
+
description: [
|
|
7460
|
+
"`<button>` is missing required `type` attribute",
|
|
7461
|
+
"",
|
|
7462
|
+
"When the `type` attribute is omitted it defaults to `submit`.",
|
|
7463
|
+
"Submit buttons are triggered when a keyboard user presses <kbd>Enter</kbd>.",
|
|
7464
|
+
"",
|
|
7465
|
+
"As this may or may not be inteded this rule enforces that the `type` attribute be explicitly set to one of the valid types:",
|
|
7466
|
+
"",
|
|
7467
|
+
"- `button` - a generic button.",
|
|
7468
|
+
"- `submit` - a submit button.",
|
|
7469
|
+
"- `reset`- a button to reset form fields.",
|
|
7470
|
+
].join("\n"),
|
|
7471
|
+
url: "https://html-validate.org/rules/no-implicit-button-type.html",
|
|
7472
|
+
};
|
|
7473
|
+
}
|
|
7474
|
+
setup() {
|
|
7475
|
+
this.on("element:ready", isRelevant$1, (event) => {
|
|
7476
|
+
const { target } = event;
|
|
7477
|
+
const attr = target.getAttribute("type");
|
|
7478
|
+
if (!attr) {
|
|
7479
|
+
this.report({
|
|
7480
|
+
node: event.target,
|
|
7481
|
+
message: `<button> is missing required "type" attribute`,
|
|
7482
|
+
});
|
|
7483
|
+
}
|
|
7484
|
+
});
|
|
7485
|
+
}
|
|
7486
|
+
}
|
|
7487
|
+
|
|
7410
7488
|
class NoImplicitClose extends Rule {
|
|
7411
7489
|
documentation() {
|
|
7412
7490
|
return {
|
|
@@ -7512,11 +7590,12 @@ class NoInlineStyle extends Rule {
|
|
|
7512
7590
|
});
|
|
7513
7591
|
}
|
|
7514
7592
|
isRelevant(event) {
|
|
7593
|
+
var _a;
|
|
7515
7594
|
if (event.key !== "style") {
|
|
7516
7595
|
return false;
|
|
7517
7596
|
}
|
|
7518
7597
|
const { include, exclude } = this.options;
|
|
7519
|
-
const key = event.originalAttribute
|
|
7598
|
+
const key = (_a = event.originalAttribute) !== null && _a !== void 0 ? _a : event.key;
|
|
7520
7599
|
/* ignore attributes not present in "include" */
|
|
7521
7600
|
if (include && !include.includes(key)) {
|
|
7522
7601
|
return false;
|
|
@@ -7710,7 +7789,8 @@ class NoRawCharacters extends Rule {
|
|
|
7710
7789
|
if (event.quote) {
|
|
7711
7790
|
return;
|
|
7712
7791
|
}
|
|
7713
|
-
this.findRawChars(event.target, event.value.toString(), event.valueLocation,
|
|
7792
|
+
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
|
|
7793
|
+
unquotedAttrRegexp);
|
|
7714
7794
|
});
|
|
7715
7795
|
}
|
|
7716
7796
|
/**
|
|
@@ -7924,7 +8004,7 @@ class NoSelfClosing extends Rule {
|
|
|
7924
8004
|
function isRelevant(node, options) {
|
|
7925
8005
|
/* tags in XML namespaces are relevant only if ignoreXml is false, in which
|
|
7926
8006
|
* case assume all xml elements must not be self-closed */
|
|
7927
|
-
if (node.tagName
|
|
8007
|
+
if (node.tagName.match(xmlns)) {
|
|
7928
8008
|
return !options.ignoreXML;
|
|
7929
8009
|
}
|
|
7930
8010
|
/* nodes with missing metadata is assumed relevant */
|
|
@@ -8130,16 +8210,12 @@ class PreferButton extends Rule {
|
|
|
8130
8210
|
};
|
|
8131
8211
|
}
|
|
8132
8212
|
documentation(context) {
|
|
8133
|
-
const
|
|
8134
|
-
|
|
8213
|
+
const src = `<input type="${context.type}">`;
|
|
8214
|
+
const dst = replacement[context.type] || `<button>`;
|
|
8215
|
+
return {
|
|
8216
|
+
description: `Prefer to use \`${dst}\` instead of \`"${src}\`.`,
|
|
8135
8217
|
url: "https://html-validate.org/rules/prefer-button.html",
|
|
8136
8218
|
};
|
|
8137
|
-
if (context) {
|
|
8138
|
-
const src = `<input type="${context.type}">`;
|
|
8139
|
-
const dst = replacement[context.type] || `<button>`;
|
|
8140
|
-
doc.description = `Prefer to use \`${dst}\` instead of \`"${src}\`.`;
|
|
8141
|
-
}
|
|
8142
|
-
return doc;
|
|
8143
8219
|
}
|
|
8144
8220
|
setup() {
|
|
8145
8221
|
this.on("attr", (event) => {
|
|
@@ -8238,14 +8314,10 @@ class PreferNativeElement extends Rule {
|
|
|
8238
8314
|
};
|
|
8239
8315
|
}
|
|
8240
8316
|
documentation(context) {
|
|
8241
|
-
|
|
8242
|
-
description: `Instead of using WAI-ARIA
|
|
8317
|
+
return {
|
|
8318
|
+
description: `Instead of using the WAI-ARIA role "${context.role}" prefer to use the native <${context.replacement}> element.`,
|
|
8243
8319
|
url: "https://html-validate.org/rules/prefer-native-element.html",
|
|
8244
8320
|
};
|
|
8245
|
-
if (context) {
|
|
8246
|
-
doc.description = `Instead of using the WAI-ARIA role "${context.role}" prefer to use the native <${context.replacement}> element.`;
|
|
8247
|
-
}
|
|
8248
|
-
return doc;
|
|
8249
8321
|
}
|
|
8250
8322
|
setup() {
|
|
8251
8323
|
const { mapping } = this.options;
|
|
@@ -8286,7 +8358,7 @@ class PreferNativeElement extends Rule {
|
|
|
8286
8358
|
}
|
|
8287
8359
|
getLocation(event) {
|
|
8288
8360
|
const begin = event.location;
|
|
8289
|
-
const end = event.valueLocation;
|
|
8361
|
+
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
|
|
8290
8362
|
const quote = event.quote ? 1 : 0;
|
|
8291
8363
|
const size = end.offset + end.size - begin.offset + quote;
|
|
8292
8364
|
return {
|
|
@@ -8360,7 +8432,7 @@ class RequireCSPNonce extends Rule {
|
|
|
8360
8432
|
const { tags } = this.options;
|
|
8361
8433
|
const node = event.previous;
|
|
8362
8434
|
/* ignore other tags */
|
|
8363
|
-
if (!
|
|
8435
|
+
if (!tags.includes(node.tagName)) {
|
|
8364
8436
|
return;
|
|
8365
8437
|
}
|
|
8366
8438
|
/* ignore if nonce is set to non-empty value (or dynamic) */
|
|
@@ -8452,7 +8524,10 @@ class RequireSri extends Rule {
|
|
|
8452
8524
|
}
|
|
8453
8525
|
needSri(node) {
|
|
8454
8526
|
const attr = this.elementSourceAttr(node);
|
|
8455
|
-
if (!attr
|
|
8527
|
+
if (!attr) {
|
|
8528
|
+
return false;
|
|
8529
|
+
}
|
|
8530
|
+
if (attr.value === null || attr.value === "" || attr.isDynamic) {
|
|
8456
8531
|
return false;
|
|
8457
8532
|
}
|
|
8458
8533
|
const url = attr.value.toString();
|
|
@@ -8509,7 +8584,7 @@ class ScriptType extends Rule {
|
|
|
8509
8584
|
setup() {
|
|
8510
8585
|
this.on("tag:end", (event) => {
|
|
8511
8586
|
const node = event.previous;
|
|
8512
|
-
if (
|
|
8587
|
+
if (node.tagName !== "script") {
|
|
8513
8588
|
return;
|
|
8514
8589
|
}
|
|
8515
8590
|
const attr = node.getAttribute("type");
|
|
@@ -8790,18 +8865,16 @@ class TextContent extends Rule {
|
|
|
8790
8865
|
description: `The textual content for this element is not valid.`,
|
|
8791
8866
|
url: "https://html-validate.org/rules/text-content.html",
|
|
8792
8867
|
};
|
|
8793
|
-
|
|
8794
|
-
|
|
8795
|
-
|
|
8796
|
-
|
|
8797
|
-
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
|
|
8803
|
-
break;
|
|
8804
|
-
}
|
|
8868
|
+
switch (context.textContent) {
|
|
8869
|
+
case TextContent$1.NONE:
|
|
8870
|
+
doc.description = `The \`<${context.tagName}>\` element must not have textual content.`;
|
|
8871
|
+
break;
|
|
8872
|
+
case TextContent$1.REQUIRED:
|
|
8873
|
+
doc.description = `The \`<${context.tagName}>\` element must have textual content.`;
|
|
8874
|
+
break;
|
|
8875
|
+
case TextContent$1.ACCESSIBLE:
|
|
8876
|
+
doc.description = `The \`<${context.tagName}>\` element must have accessible text.`;
|
|
8877
|
+
break;
|
|
8805
8878
|
}
|
|
8806
8879
|
return doc;
|
|
8807
8880
|
}
|
|
@@ -9162,20 +9235,16 @@ class VoidStyle extends Rule {
|
|
|
9162
9235
|
};
|
|
9163
9236
|
}
|
|
9164
9237
|
documentation(context) {
|
|
9165
|
-
const
|
|
9166
|
-
|
|
9238
|
+
const [desc, end] = styleDescription(context.style);
|
|
9239
|
+
return {
|
|
9240
|
+
description: `The current configuration requires void elements to ${desc}, use <${context.tagName}${end}> instead.`,
|
|
9167
9241
|
url: "https://html-validate.org/rules/void-style.html",
|
|
9168
9242
|
};
|
|
9169
|
-
if (context) {
|
|
9170
|
-
const [desc, end] = styleDescription(context.style);
|
|
9171
|
-
doc.description = `The current configuration requires void elements to ${desc}, use <${context.tagName}${end}> instead.`;
|
|
9172
|
-
}
|
|
9173
|
-
return doc;
|
|
9174
9243
|
}
|
|
9175
9244
|
setup() {
|
|
9176
9245
|
this.on("tag:end", (event) => {
|
|
9177
9246
|
const active = event.previous; // The current active element (that is, the current element on the stack)
|
|
9178
|
-
if (active
|
|
9247
|
+
if (active.meta) {
|
|
9179
9248
|
this.validateActive(active);
|
|
9180
9249
|
}
|
|
9181
9250
|
});
|
|
@@ -9412,7 +9481,8 @@ class H37 extends Rule {
|
|
|
9412
9481
|
return;
|
|
9413
9482
|
}
|
|
9414
9483
|
/* validate plain alt-attribute */
|
|
9415
|
-
if (node.getAttributeValue("alt") ||
|
|
9484
|
+
if (Boolean(node.getAttributeValue("alt")) ||
|
|
9485
|
+
Boolean(node.hasAttribute("alt") && this.options.allowEmpty)) {
|
|
9416
9486
|
return;
|
|
9417
9487
|
}
|
|
9418
9488
|
/* validate if any non-empty alias is present */
|
|
@@ -9589,6 +9659,7 @@ const bundledRules = {
|
|
|
9589
9659
|
"no-dup-attr": NoDupAttr,
|
|
9590
9660
|
"no-dup-class": NoDupClass,
|
|
9591
9661
|
"no-dup-id": NoDupID,
|
|
9662
|
+
"no-implicit-button-type": NoImplicitButtonType,
|
|
9592
9663
|
"no-implicit-close": NoImplicitClose,
|
|
9593
9664
|
"no-inline-style": NoInlineStyle,
|
|
9594
9665
|
"no-missing-references": NoMissingReferences,
|
|
@@ -9635,6 +9706,7 @@ const config$4 = {
|
|
|
9635
9706
|
"multiple-labeled-controls": "error",
|
|
9636
9707
|
"no-autoplay": ["error", { include: ["audio", "video"] }],
|
|
9637
9708
|
"no-dup-id": "error",
|
|
9709
|
+
"no-implicit-button-type": "error",
|
|
9638
9710
|
"no-redundant-aria-label": "error",
|
|
9639
9711
|
"no-redundant-for": "error",
|
|
9640
9712
|
"no-redundant-role": "error",
|
|
@@ -9714,6 +9786,7 @@ const config$1 = {
|
|
|
9714
9786
|
"no-dup-attr": "error",
|
|
9715
9787
|
"no-dup-class": "error",
|
|
9716
9788
|
"no-dup-id": "error",
|
|
9789
|
+
"no-implicit-button-type": "error",
|
|
9717
9790
|
"no-implicit-close": "error",
|
|
9718
9791
|
"no-inline-style": "error",
|
|
9719
9792
|
"no-multiple-main": "error",
|
|
@@ -9845,7 +9918,7 @@ class ResolvedConfig {
|
|
|
9845
9918
|
* @returns A list of transformed sources ready for validation.
|
|
9846
9919
|
*/
|
|
9847
9920
|
transformSource(source, filename) {
|
|
9848
|
-
const transformer = this.findTransformer(filename
|
|
9921
|
+
const transformer = this.findTransformer(filename !== null && filename !== void 0 ? filename : source.filename);
|
|
9849
9922
|
const context = {
|
|
9850
9923
|
hasChain: (filename) => {
|
|
9851
9924
|
return !!this.findTransformer(filename);
|
|
@@ -9857,9 +9930,10 @@ class ResolvedConfig {
|
|
|
9857
9930
|
if (transformer) {
|
|
9858
9931
|
try {
|
|
9859
9932
|
return Array.from(transformer.fn.call(context, source), (cur) => {
|
|
9933
|
+
var _a;
|
|
9860
9934
|
/* keep track of which transformers that has been run on this source
|
|
9861
9935
|
* by appending this entry to the transformedBy array */
|
|
9862
|
-
cur.transformedBy
|
|
9936
|
+
(_a = cur.transformedBy) !== null && _a !== void 0 ? _a : (cur.transformedBy = []);
|
|
9863
9937
|
cur.transformedBy.push(transformer.name);
|
|
9864
9938
|
return cur;
|
|
9865
9939
|
});
|
|
@@ -10031,7 +10105,7 @@ function mergeInternal(base, rhs) {
|
|
|
10031
10105
|
}
|
|
10032
10106
|
/* root property is merged with boolean "or" since it should always be truthy
|
|
10033
10107
|
* if any config has it set. */
|
|
10034
|
-
const root = base.root || rhs.root;
|
|
10108
|
+
const root = Boolean(base.root) || Boolean(rhs.root);
|
|
10035
10109
|
if (root) {
|
|
10036
10110
|
dst.root = root;
|
|
10037
10111
|
}
|
|
@@ -10118,7 +10192,7 @@ class Config {
|
|
|
10118
10192
|
* @internal
|
|
10119
10193
|
*/
|
|
10120
10194
|
constructor(resolvers, options) {
|
|
10121
|
-
var _a;
|
|
10195
|
+
var _a, _b;
|
|
10122
10196
|
this.transformers = [];
|
|
10123
10197
|
const initial = {
|
|
10124
10198
|
extends: [],
|
|
@@ -10131,18 +10205,18 @@ class Config {
|
|
|
10131
10205
|
this.initialized = false;
|
|
10132
10206
|
this.resolvers = toArray(resolvers);
|
|
10133
10207
|
/* load plugins */
|
|
10134
|
-
this.plugins = this.loadPlugins(this.config.plugins
|
|
10208
|
+
this.plugins = this.loadPlugins((_a = this.config.plugins) !== null && _a !== void 0 ? _a : []);
|
|
10135
10209
|
this.configurations = this.loadConfigurations(this.plugins);
|
|
10136
10210
|
this.extendMeta(this.plugins);
|
|
10137
10211
|
/* process extended configs */
|
|
10138
|
-
this.config = this.extendConfig((
|
|
10212
|
+
this.config = this.extendConfig((_b = this.config.extends) !== null && _b !== void 0 ? _b : []);
|
|
10139
10213
|
/* reset extends as we already processed them, this prevents the next config
|
|
10140
10214
|
* from reapplying config from extended config as well as duplicate entries
|
|
10141
10215
|
* when merging arrays */
|
|
10142
10216
|
this.config.extends = [];
|
|
10143
10217
|
/* rules explicitly set by passed options should have precedence over any
|
|
10144
10218
|
* extended rules, not the other way around. */
|
|
10145
|
-
if (options
|
|
10219
|
+
if (options === null || options === void 0 ? void 0 : options.rules) {
|
|
10146
10220
|
this.config = mergeInternal(this.config, { rules: options.rules });
|
|
10147
10221
|
}
|
|
10148
10222
|
}
|
|
@@ -10155,11 +10229,12 @@ class Config {
|
|
|
10155
10229
|
* @public
|
|
10156
10230
|
*/
|
|
10157
10231
|
init() {
|
|
10232
|
+
var _a;
|
|
10158
10233
|
if (this.initialized) {
|
|
10159
10234
|
return;
|
|
10160
10235
|
}
|
|
10161
10236
|
/* precompile transform patterns */
|
|
10162
|
-
this.transformers = this.precompileTransformers(this.config.transform
|
|
10237
|
+
this.transformers = this.precompileTransformers((_a = this.config.transform) !== null && _a !== void 0 ? _a : {});
|
|
10163
10238
|
this.initialized = true;
|
|
10164
10239
|
}
|
|
10165
10240
|
/**
|
|
@@ -10186,7 +10261,7 @@ class Config {
|
|
|
10186
10261
|
for (const entry of entries) {
|
|
10187
10262
|
let extended;
|
|
10188
10263
|
if (this.configurations.has(entry)) {
|
|
10189
|
-
extended = this.configurations.get(entry);
|
|
10264
|
+
extended = this.configurations.get(entry); // eslint-disable-line @typescript-eslint/no-non-null-assertion -- map has/get combo
|
|
10190
10265
|
}
|
|
10191
10266
|
else {
|
|
10192
10267
|
extended = Config.fromFile(this.resolvers, entry).config;
|
|
@@ -10201,12 +10276,13 @@ class Config {
|
|
|
10201
10276
|
* @internal
|
|
10202
10277
|
*/
|
|
10203
10278
|
getMetaTable() {
|
|
10279
|
+
var _a;
|
|
10204
10280
|
/* use cached table if it exists */
|
|
10205
10281
|
if (this.metaTable) {
|
|
10206
10282
|
return this.metaTable;
|
|
10207
10283
|
}
|
|
10208
10284
|
const metaTable = new MetaTable();
|
|
10209
|
-
const source = this.config.elements
|
|
10285
|
+
const source = (_a = this.config.elements) !== null && _a !== void 0 ? _a : ["html5"];
|
|
10210
10286
|
/* extend validation schema from plugins */
|
|
10211
10287
|
for (const plugin of this.getPlugins()) {
|
|
10212
10288
|
if (plugin.elementSchema) {
|
|
@@ -10304,6 +10380,7 @@ class Config {
|
|
|
10304
10380
|
});
|
|
10305
10381
|
}
|
|
10306
10382
|
loadConfigurations(plugins) {
|
|
10383
|
+
var _a;
|
|
10307
10384
|
const configs = new Map();
|
|
10308
10385
|
/* builtin presets */
|
|
10309
10386
|
for (const [name, config] of Object.entries(Presets)) {
|
|
@@ -10312,7 +10389,7 @@ class Config {
|
|
|
10312
10389
|
}
|
|
10313
10390
|
/* presets from plugins */
|
|
10314
10391
|
for (const plugin of plugins) {
|
|
10315
|
-
for (const [name, config] of Object.entries(plugin.configs
|
|
10392
|
+
for (const [name, config] of Object.entries((_a = plugin.configs) !== null && _a !== void 0 ? _a : {})) {
|
|
10316
10393
|
if (!config)
|
|
10317
10394
|
continue;
|
|
10318
10395
|
Config.validate(config, name);
|
|
@@ -10677,10 +10754,11 @@ class Parser {
|
|
|
10677
10754
|
* stack when is allowed to omit.
|
|
10678
10755
|
*/
|
|
10679
10756
|
closeOptional(token) {
|
|
10757
|
+
var _a;
|
|
10680
10758
|
/* if the element doesn't have metadata it cannot have optional end
|
|
10681
10759
|
* tags. Period. */
|
|
10682
10760
|
const active = this.dom.getActive();
|
|
10683
|
-
if (!(active.meta
|
|
10761
|
+
if (!((_a = active.meta) === null || _a === void 0 ? void 0 : _a.implicitClosed)) {
|
|
10684
10762
|
return false;
|
|
10685
10763
|
}
|
|
10686
10764
|
const tagName = token.data[2];
|
|
@@ -10832,9 +10910,10 @@ class Parser {
|
|
|
10832
10910
|
}
|
|
10833
10911
|
}
|
|
10834
10912
|
processElement(node, source) {
|
|
10913
|
+
var _a;
|
|
10835
10914
|
/* enable cache on node now that it is fully constructed */
|
|
10836
10915
|
node.cacheEnable();
|
|
10837
|
-
if (source.hooks
|
|
10916
|
+
if ((_a = source.hooks) === null || _a === void 0 ? void 0 : _a.processElement) {
|
|
10838
10917
|
const processElement = source.hooks.processElement;
|
|
10839
10918
|
const metaTable = this.metaTable;
|
|
10840
10919
|
const context = {
|
|
@@ -10901,6 +10980,7 @@ class Parser {
|
|
|
10901
10980
|
* @internal
|
|
10902
10981
|
*/
|
|
10903
10982
|
consumeAttribute(source, node, token, next) {
|
|
10983
|
+
var _a;
|
|
10904
10984
|
const keyLocation = this.getAttributeKeyLocation(token);
|
|
10905
10985
|
const valueLocation = this.getAttributeValueLocation(next);
|
|
10906
10986
|
const location = this.getAttributeLocation(token, next);
|
|
@@ -10919,7 +10999,7 @@ class Parser {
|
|
|
10919
10999
|
* data right away but a transformer may override it to allow aliasing
|
|
10920
11000
|
* attributes, e.g ng-attr-foo or v-bind:foo */
|
|
10921
11001
|
let processAttribute = (attr) => [attr];
|
|
10922
|
-
if (source.hooks
|
|
11002
|
+
if ((_a = source.hooks) === null || _a === void 0 ? void 0 : _a.processAttribute) {
|
|
10923
11003
|
processAttribute = source.hooks.processAttribute;
|
|
10924
11004
|
}
|
|
10925
11005
|
/* handle deprecated callbacks */
|
|
@@ -11269,14 +11349,15 @@ class Reporter {
|
|
|
11269
11349
|
const report = {
|
|
11270
11350
|
valid: this.isValid(),
|
|
11271
11351
|
results: Object.keys(this.result).map((filePath) => {
|
|
11352
|
+
var _a;
|
|
11272
11353
|
const messages = Array.from(this.result[filePath], freeze).sort(messageSort);
|
|
11273
|
-
const source = (sources
|
|
11354
|
+
const source = (sources !== null && sources !== void 0 ? sources : []).find((source) => { var _a; return filePath === ((_a = source.filename) !== null && _a !== void 0 ? _a : ""); });
|
|
11274
11355
|
return {
|
|
11275
11356
|
filePath,
|
|
11276
11357
|
messages,
|
|
11277
11358
|
errorCount: countErrors(messages),
|
|
11278
11359
|
warningCount: countWarnings(messages),
|
|
11279
|
-
source: source ? source.originalData
|
|
11360
|
+
source: source ? (_a = source.originalData) !== null && _a !== void 0 ? _a : source.data : null,
|
|
11280
11361
|
};
|
|
11281
11362
|
}),
|
|
11282
11363
|
errorCount: 0,
|
|
@@ -11294,10 +11375,10 @@ class Reporter {
|
|
|
11294
11375
|
}
|
|
11295
11376
|
}
|
|
11296
11377
|
function countErrors(messages) {
|
|
11297
|
-
return messages.filter((m) => m.severity === Severity.ERROR).length;
|
|
11378
|
+
return messages.filter((m) => m.severity === Number(Severity.ERROR)).length;
|
|
11298
11379
|
}
|
|
11299
11380
|
function countWarnings(messages) {
|
|
11300
|
-
return messages.filter((m) => m.severity === Severity.WARN).length;
|
|
11381
|
+
return messages.filter((m) => m.severity === Number(Severity.WARN)).length;
|
|
11301
11382
|
}
|
|
11302
11383
|
function sumErrors(results) {
|
|
11303
11384
|
return results.reduce((sum, result) => {
|
|
@@ -11642,9 +11723,10 @@ class Engine {
|
|
|
11642
11723
|
* between rule name and its constructor.
|
|
11643
11724
|
*/
|
|
11644
11725
|
initRules(config) {
|
|
11726
|
+
var _a;
|
|
11645
11727
|
const availableRules = {};
|
|
11646
11728
|
for (const plugin of config.getPlugins()) {
|
|
11647
|
-
for (const [name, rule] of Object.entries(plugin.rules
|
|
11729
|
+
for (const [name, rule] of Object.entries((_a = plugin.rules) !== null && _a !== void 0 ? _a : {})) {
|
|
11648
11730
|
if (!rule)
|
|
11649
11731
|
continue;
|
|
11650
11732
|
availableRules[name] = rule;
|
|
@@ -11747,7 +11829,7 @@ class StaticConfigLoader extends ConfigLoader {
|
|
|
11747
11829
|
}
|
|
11748
11830
|
}
|
|
11749
11831
|
getConfigFor(_handle, configOverride) {
|
|
11750
|
-
const override = this.loadFromObject(configOverride
|
|
11832
|
+
const override = this.loadFromObject(configOverride !== null && configOverride !== void 0 ? configOverride : {});
|
|
11751
11833
|
if (override.isRootFound()) {
|
|
11752
11834
|
override.init();
|
|
11753
11835
|
return override.resolve();
|
|
@@ -11791,6 +11873,7 @@ class HtmlValidate {
|
|
|
11791
11873
|
const [loader, config] = arg instanceof ConfigLoader ? [arg, undefined] : [undefined, arg];
|
|
11792
11874
|
this.configLoader = loader !== null && loader !== void 0 ? loader : new StaticConfigLoader(config);
|
|
11793
11875
|
}
|
|
11876
|
+
/* eslint-enable @typescript-eslint/unified-signatures */
|
|
11794
11877
|
validateString(str, arg1, arg2, arg3) {
|
|
11795
11878
|
const filename = typeof arg1 === "string" ? arg1 : "inline";
|
|
11796
11879
|
const options = isConfigData(arg1) ? arg1 : isConfigData(arg2) ? arg2 : undefined;
|
|
@@ -11805,6 +11888,7 @@ class HtmlValidate {
|
|
|
11805
11888
|
};
|
|
11806
11889
|
return this.validateSource(source, options);
|
|
11807
11890
|
}
|
|
11891
|
+
/* eslint-enable @typescript-eslint/unified-signatures */
|
|
11808
11892
|
validateStringSync(str, arg1, arg2, arg3) {
|
|
11809
11893
|
const filename = typeof arg1 === "string" ? arg1 : "inline";
|
|
11810
11894
|
const options = isConfigData(arg1) ? arg1 : isConfigData(arg2) ? arg2 : undefined;
|
|
@@ -12076,7 +12160,7 @@ class HtmlValidate {
|
|
|
12076
12160
|
* contextual details and suggestions.
|
|
12077
12161
|
*/
|
|
12078
12162
|
async getRuleDocumentation(ruleId, config = null, context = null) {
|
|
12079
|
-
const c = config
|
|
12163
|
+
const c = config !== null && config !== void 0 ? config : this.getConfigFor("inline");
|
|
12080
12164
|
const engine = new Engine(await c, Parser);
|
|
12081
12165
|
return engine.getRuleDocumentation({ ruleId, context });
|
|
12082
12166
|
}
|
|
@@ -12105,7 +12189,7 @@ class HtmlValidate {
|
|
|
12105
12189
|
* contextual details and suggestions.
|
|
12106
12190
|
*/
|
|
12107
12191
|
getRuleDocumentationSync(ruleId, config = null, context = null) {
|
|
12108
|
-
const c = config
|
|
12192
|
+
const c = config !== null && config !== void 0 ? config : this.getConfigForSync("inline");
|
|
12109
12193
|
const engine = new Engine(c, Parser);
|
|
12110
12194
|
return engine.getRuleDocumentation({ ruleId, context });
|
|
12111
12195
|
}
|
|
@@ -12161,7 +12245,7 @@ class HtmlValidate {
|
|
|
12161
12245
|
/** @public */
|
|
12162
12246
|
const name = "html-validate";
|
|
12163
12247
|
/** @public */
|
|
12164
|
-
const version = "8.
|
|
12248
|
+
const version = "8.3.0";
|
|
12165
12249
|
/** @public */
|
|
12166
12250
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
12167
12251
|
|
|
@@ -12459,5 +12543,5 @@ function compatibilityCheckImpl(name, declared, options) {
|
|
|
12459
12543
|
return false;
|
|
12460
12544
|
}
|
|
12461
12545
|
|
|
12462
|
-
export { Attribute as A, codeframe as B, Config as C,
|
|
12546
|
+
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 };
|
|
12463
12547
|
//# sourceMappingURL=core.js.map
|