html-validate 11.5.3 → 11.5.4
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 +11 -14
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core-browser.js +4 -4
- package/dist/cjs/core-browser.js.map +1 -1
- package/dist/cjs/core-nodejs.js +17 -25
- package/dist/cjs/core-nodejs.js.map +1 -1
- package/dist/cjs/core.js +420 -435
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +11 -22
- package/dist/cjs/elements.js.map +1 -1
- package/dist/cjs/html-validate.js +1 -1
- package/dist/cjs/html-validate.js.map +1 -1
- package/dist/cjs/jest-matchers.js +49 -55
- package/dist/cjs/jest-matchers.js.map +1 -1
- package/dist/cjs/jest-utils.js +1 -2
- package/dist/cjs/jest-utils.js.map +1 -1
- package/dist/cjs/jest-worker.js.map +1 -1
- package/dist/cjs/test-utils.js +1 -2
- package/dist/cjs/test-utils.js.map +2 -2
- package/dist/cjs/tsdoc-metadata.json +1 -1
- package/dist/cjs/utils/parse-image-candidate-string.js +2 -2
- package/dist/cjs/utils/parse-image-candidate-string.js.map +1 -1
- package/dist/cjs/vitest-matchers.js +46 -50
- package/dist/cjs/vitest-matchers.js.map +1 -1
- package/dist/cjs/vitest-utils.js +1 -2
- package/dist/cjs/vitest-utils.js.map +1 -1
- package/dist/cjs/vitest-worker.js.map +1 -1
- package/dist/esm/cli.js +11 -14
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/core-browser.js +4 -4
- package/dist/esm/core-browser.js.map +1 -1
- package/dist/esm/core-nodejs.js +17 -25
- package/dist/esm/core-nodejs.js.map +1 -1
- package/dist/esm/core.js +420 -435
- package/dist/esm/core.js.map +1 -1
- package/dist/esm/elements.js +11 -22
- package/dist/esm/elements.js.map +1 -1
- package/dist/esm/html-validate.js +1 -1
- package/dist/esm/html-validate.js.map +1 -1
- package/dist/esm/jest-matchers.js +49 -55
- package/dist/esm/jest-matchers.js.map +1 -1
- package/dist/esm/jest-utils.js +1 -2
- package/dist/esm/jest-utils.js.map +1 -1
- package/dist/esm/jest-worker.js.map +1 -1
- package/dist/esm/test-utils.js +1 -2
- package/dist/esm/test-utils.js.map +2 -2
- package/dist/esm/utils/parse-image-candidate-string.js +2 -2
- package/dist/esm/utils/parse-image-candidate-string.js.map +1 -1
- package/dist/esm/vitest-matchers.js +46 -50
- package/dist/esm/vitest-matchers.js.map +1 -1
- package/dist/esm/vitest-utils.js +1 -2
- package/dist/esm/vitest-utils.js.map +1 -1
- package/dist/esm/vitest-worker.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types/browser.d.ts +21 -11
- package/dist/types/index.d.ts +23 -13
- package/package.json +1 -1
package/dist/esm/core.js
CHANGED
|
@@ -388,11 +388,11 @@ var deepmerge = /*@__PURE__*/getDefaultExportFromCjs(cjsExports);
|
|
|
388
388
|
function stringify(value) {
|
|
389
389
|
if (typeof value === "string") {
|
|
390
390
|
return value;
|
|
391
|
-
} else {
|
|
392
|
-
return JSON.stringify(value);
|
|
393
391
|
}
|
|
392
|
+
return JSON.stringify(value);
|
|
394
393
|
}
|
|
395
394
|
class WrappedError extends Error {
|
|
395
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
396
396
|
constructor(message) {
|
|
397
397
|
super(stringify(message));
|
|
398
398
|
this.name = "WrappedError";
|
|
@@ -402,12 +402,12 @@ class WrappedError extends Error {
|
|
|
402
402
|
function ensureError(value) {
|
|
403
403
|
if (value instanceof Error) {
|
|
404
404
|
return value;
|
|
405
|
-
} else {
|
|
406
|
-
return new WrappedError(value);
|
|
407
405
|
}
|
|
406
|
+
return new WrappedError(value);
|
|
408
407
|
}
|
|
409
408
|
|
|
410
409
|
class NestedError extends Error {
|
|
410
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
411
411
|
constructor(message, nested) {
|
|
412
412
|
super(message);
|
|
413
413
|
this.name = "NestedError";
|
|
@@ -420,6 +420,7 @@ Caused by: ${nested.stack}`;
|
|
|
420
420
|
}
|
|
421
421
|
|
|
422
422
|
class UserError extends NestedError {
|
|
423
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
423
424
|
constructor(message, nested) {
|
|
424
425
|
super(message, nested);
|
|
425
426
|
this.name = "UserError";
|
|
@@ -1120,11 +1121,11 @@ const CONTROL_ESCAPES = /* @__PURE__ */ new Map([
|
|
|
1120
1121
|
["\r", "r"]
|
|
1121
1122
|
]);
|
|
1122
1123
|
const OTHER_PUNCTUATORS = /^[!"#%&',:;<=>@`~-]$/;
|
|
1123
|
-
const WHITE_SPACE = /^[\t\v\f\
|
|
1124
|
+
const WHITE_SPACE = /^[\t\v\f\u{FEFF}\p{Zs}]$/u;
|
|
1124
1125
|
const LINE_TERMINATOR = /^[\n\r\u2028\u2029]$/;
|
|
1125
1126
|
const SURROGATE = /^[\uD800-\uDFFF]$/;
|
|
1126
1127
|
function isDecimalDigitOrASCIILetter(ch) {
|
|
1127
|
-
return /^[\dA-
|
|
1128
|
+
return /^[\dA-Z]$/i.test(ch);
|
|
1128
1129
|
}
|
|
1129
1130
|
function needEscape(ch) {
|
|
1130
1131
|
return OTHER_PUNCTUATORS.test(ch) || WHITE_SPACE.test(ch) || LINE_TERMINATOR.test(ch) || SURROGATE.test(ch);
|
|
@@ -1192,9 +1193,8 @@ function migrateSingleAttribute(src, key) {
|
|
|
1192
1193
|
}
|
|
1193
1194
|
}
|
|
1194
1195
|
return stripUndefined(result);
|
|
1195
|
-
} else {
|
|
1196
|
-
return stripUndefined({ ...result, ...attr });
|
|
1197
1196
|
}
|
|
1197
|
+
return stripUndefined({ ...result, ...attr });
|
|
1198
1198
|
}
|
|
1199
1199
|
function isPatternAttribute$1(key) {
|
|
1200
1200
|
return key.includes("*");
|
|
@@ -1208,7 +1208,7 @@ function migrateAttributes(src) {
|
|
|
1208
1208
|
...Object.keys(src.attributes ?? {}),
|
|
1209
1209
|
...src.requiredAttributes ?? [],
|
|
1210
1210
|
...src.deprecatedAttributes ?? []
|
|
1211
|
-
].filter((key) => !isPatternAttribute$1(key)).toSorted();
|
|
1211
|
+
].filter((key) => !isPatternAttribute$1(key)).toSorted((a, b) => a.localeCompare(b));
|
|
1212
1212
|
const entries = keys.map((key) => {
|
|
1213
1213
|
return [key, migrateSingleAttribute(src, key)];
|
|
1214
1214
|
});
|
|
@@ -1288,11 +1288,10 @@ const dynamicKeys = [
|
|
|
1288
1288
|
];
|
|
1289
1289
|
const schemaCache = /* @__PURE__ */ new Map();
|
|
1290
1290
|
function clone(value) {
|
|
1291
|
-
if (globalThis
|
|
1292
|
-
return
|
|
1293
|
-
} else {
|
|
1294
|
-
return JSON.parse(JSON.stringify(value));
|
|
1291
|
+
if (Object.hasOwn(globalThis, "structuredClone")) {
|
|
1292
|
+
return structuredClone(value);
|
|
1295
1293
|
}
|
|
1294
|
+
return JSON.parse(JSON.stringify(value));
|
|
1296
1295
|
}
|
|
1297
1296
|
class MetaTable {
|
|
1298
1297
|
elements;
|
|
@@ -1382,9 +1381,8 @@ class MetaTable {
|
|
|
1382
1381
|
const meta = this.elements[tagName.toLowerCase()] ?? this.elements["*"];
|
|
1383
1382
|
if (meta) {
|
|
1384
1383
|
return { ...meta };
|
|
1385
|
-
} else {
|
|
1386
|
-
return null;
|
|
1387
1384
|
}
|
|
1385
|
+
return null;
|
|
1388
1386
|
}
|
|
1389
1387
|
/**
|
|
1390
1388
|
* Find all tags which has enabled given property.
|
|
@@ -1426,16 +1424,15 @@ class MetaTable {
|
|
|
1426
1424
|
const cached = schemaCache.get(hash);
|
|
1427
1425
|
if (cached) {
|
|
1428
1426
|
return cached;
|
|
1429
|
-
} else {
|
|
1430
|
-
const ajv = new Ajv({ strict: true, strictTuples: true, strictTypes: true });
|
|
1431
|
-
ajv.addMetaSchema(ajvSchemaDraft);
|
|
1432
|
-
ajv.addKeyword(ajvFunctionKeyword);
|
|
1433
|
-
ajv.addKeyword(ajvRegexpKeyword);
|
|
1434
|
-
ajv.addKeyword({ keyword: "copyable" });
|
|
1435
|
-
const validate = ajv.compile(this.schema);
|
|
1436
|
-
schemaCache.set(hash, validate);
|
|
1437
|
-
return validate;
|
|
1438
1427
|
}
|
|
1428
|
+
const ajv = new Ajv({ strict: true, strictTuples: true, strictTypes: true });
|
|
1429
|
+
ajv.addMetaSchema(ajvSchemaDraft);
|
|
1430
|
+
ajv.addKeyword(ajvFunctionKeyword);
|
|
1431
|
+
ajv.addKeyword(ajvRegexpKeyword);
|
|
1432
|
+
ajv.addKeyword({ keyword: "copyable" });
|
|
1433
|
+
const validate = ajv.compile(this.schema);
|
|
1434
|
+
schemaCache.set(hash, validate);
|
|
1435
|
+
return validate;
|
|
1439
1436
|
}
|
|
1440
1437
|
/**
|
|
1441
1438
|
* @public
|
|
@@ -1517,14 +1514,13 @@ function expandProperties(node, entry) {
|
|
|
1517
1514
|
}
|
|
1518
1515
|
}
|
|
1519
1516
|
function compileRegexString(value) {
|
|
1520
|
-
const match = /^\/(.*
|
|
1517
|
+
const match = /^\/(.*)\/(i?)$/.exec(value);
|
|
1521
1518
|
if (match) {
|
|
1522
1519
|
const [, expr, flags] = match;
|
|
1523
1520
|
if (expr.startsWith("^") || expr.endsWith("$")) {
|
|
1524
1521
|
return new RegExp(expr, flags);
|
|
1525
|
-
} else {
|
|
1526
|
-
return new RegExp(`^${expr}$`, flags);
|
|
1527
1522
|
}
|
|
1523
|
+
return new RegExp(`^${expr}$`, flags);
|
|
1528
1524
|
}
|
|
1529
1525
|
return null;
|
|
1530
1526
|
}
|
|
@@ -1585,7 +1581,7 @@ class Attribute {
|
|
|
1585
1581
|
* @param keyLocation - Source location of attribute name.
|
|
1586
1582
|
* @param valueLocation - Source location of attribute value.
|
|
1587
1583
|
* @param originalAttribute - If this attribute was dynamically added via a
|
|
1588
|
-
* transformation (e.g.
|
|
1584
|
+
* transformation (e.g. Vue.js `:id` generating the `id` attribute) this
|
|
1589
1585
|
* parameter should be set to the attribute name of the source attribute (`:id`).
|
|
1590
1586
|
*/
|
|
1591
1587
|
constructor(key, value, keyLocation, valueLocation, originalAttribute) {
|
|
@@ -1629,9 +1625,8 @@ class Attribute {
|
|
|
1629
1625
|
}
|
|
1630
1626
|
if (pattern instanceof RegExp) {
|
|
1631
1627
|
return this.value.match(pattern) !== null;
|
|
1632
|
-
} else {
|
|
1633
|
-
return this.value === pattern;
|
|
1634
1628
|
}
|
|
1629
|
+
return this.value === pattern;
|
|
1635
1630
|
}
|
|
1636
1631
|
}
|
|
1637
1632
|
|
|
@@ -1707,7 +1702,9 @@ const Node = {
|
|
|
1707
1702
|
|
|
1708
1703
|
const DOCUMENT_NODE_NAME = "#document";
|
|
1709
1704
|
const TEXT_CONTENT = /* @__PURE__ */ Symbol("textContent");
|
|
1710
|
-
|
|
1705
|
+
const state$1 = {
|
|
1706
|
+
counter: 0
|
|
1707
|
+
};
|
|
1711
1708
|
class DOMNode {
|
|
1712
1709
|
nodeName;
|
|
1713
1710
|
nodeType;
|
|
@@ -1746,7 +1743,7 @@ class DOMNode {
|
|
|
1746
1743
|
this.disabledRules = /* @__PURE__ */ new Set();
|
|
1747
1744
|
this.blockedRules = /* @__PURE__ */ new Map();
|
|
1748
1745
|
this.childNodes = [];
|
|
1749
|
-
this.unique = counter++;
|
|
1746
|
+
this.unique = state$1.counter++;
|
|
1750
1747
|
this.cache = null;
|
|
1751
1748
|
}
|
|
1752
1749
|
/**
|
|
@@ -1762,9 +1759,8 @@ class DOMNode {
|
|
|
1762
1759
|
cacheGet(key) {
|
|
1763
1760
|
if (this.cache) {
|
|
1764
1761
|
return this.cache.get(key);
|
|
1765
|
-
} else {
|
|
1766
|
-
return void 0;
|
|
1767
1762
|
}
|
|
1763
|
+
return void 0;
|
|
1768
1764
|
}
|
|
1769
1765
|
cacheSet(key, value) {
|
|
1770
1766
|
if (this.cache) {
|
|
@@ -1780,9 +1776,8 @@ class DOMNode {
|
|
|
1780
1776
|
cacheRemove(key) {
|
|
1781
1777
|
if (this.cache) {
|
|
1782
1778
|
return this.cache.delete(key);
|
|
1783
|
-
} else {
|
|
1784
|
-
return false;
|
|
1785
1779
|
}
|
|
1780
|
+
return false;
|
|
1786
1781
|
}
|
|
1787
1782
|
/**
|
|
1788
1783
|
* Check if key exists in cache.
|
|
@@ -2002,9 +1997,8 @@ class DOMTokenList extends Array {
|
|
|
2002
1997
|
location(n) {
|
|
2003
1998
|
if (this.locations) {
|
|
2004
1999
|
return this.locations[n];
|
|
2005
|
-
} else {
|
|
2006
|
-
throw new Error("Trying to access DOMTokenList location when base location isn't set");
|
|
2007
2000
|
}
|
|
2001
|
+
throw new Error("Trying to access DOMTokenList location when base location isn't set");
|
|
2008
2002
|
}
|
|
2009
2003
|
contains(token) {
|
|
2010
2004
|
return this.includes(token);
|
|
@@ -2072,7 +2066,7 @@ function nthChild(node, args) {
|
|
|
2072
2066
|
if (!args) {
|
|
2073
2067
|
throw new Error("Missing argument to nth-child");
|
|
2074
2068
|
}
|
|
2075
|
-
const n =
|
|
2069
|
+
const n = Math.trunc(Number(args.trim()));
|
|
2076
2070
|
const cur = getNthChild(node);
|
|
2077
2071
|
return cur === n;
|
|
2078
2072
|
}
|
|
@@ -2091,9 +2085,8 @@ function factory(name, context) {
|
|
|
2091
2085
|
const fn = table[name];
|
|
2092
2086
|
if (fn) {
|
|
2093
2087
|
return fn.bind(context);
|
|
2094
|
-
} else {
|
|
2095
|
-
throw new Error(`Pseudo-class "${name}" is not implemented`);
|
|
2096
2088
|
}
|
|
2089
|
+
throw new Error(`Pseudo-class "${name}" is not implemented`);
|
|
2097
2090
|
}
|
|
2098
2091
|
|
|
2099
2092
|
function stripslashes(value) {
|
|
@@ -2119,7 +2112,7 @@ function createIdCondition(raw) {
|
|
|
2119
2112
|
};
|
|
2120
2113
|
}
|
|
2121
2114
|
function createAttributeCondition(attr) {
|
|
2122
|
-
const match = /^(.+?)(?:([$*^|~]?=)"([^"]
|
|
2115
|
+
const match = /^(.+?)(?:([$*^|~]?=)"([^"]+)")?$/.exec(attr);
|
|
2123
2116
|
const key = match[1];
|
|
2124
2117
|
const op = match[2];
|
|
2125
2118
|
const rawValue = match[3];
|
|
@@ -2182,7 +2175,6 @@ function* splitCompound(pattern) {
|
|
|
2182
2175
|
let quoted = false;
|
|
2183
2176
|
while (cur < end) {
|
|
2184
2177
|
const ch = pattern[cur];
|
|
2185
|
-
const buffer = pattern.slice(begin, cur);
|
|
2186
2178
|
if (ch === "\\") {
|
|
2187
2179
|
cur += 2;
|
|
2188
2180
|
continue;
|
|
@@ -2199,6 +2191,7 @@ function* splitCompound(pattern) {
|
|
|
2199
2191
|
cur += 1;
|
|
2200
2192
|
continue;
|
|
2201
2193
|
}
|
|
2194
|
+
const buffer = pattern.slice(begin, cur);
|
|
2202
2195
|
if (isPseudoElement(ch, buffer)) {
|
|
2203
2196
|
cur += 1;
|
|
2204
2197
|
continue;
|
|
@@ -2219,7 +2212,7 @@ class Compound {
|
|
|
2219
2212
|
selector;
|
|
2220
2213
|
conditions;
|
|
2221
2214
|
constructor(pattern) {
|
|
2222
|
-
const match = /^([+>~-]?)((?:\*|[^#.:[]+)?)([
|
|
2215
|
+
const match = /^([+>~-]?)((?:\*|[^#.:[]+)?)([\s\S]*)$/.exec(pattern);
|
|
2223
2216
|
if (!match) {
|
|
2224
2217
|
throw new Error(`Failed to create selector pattern from "${pattern}"`);
|
|
2225
2218
|
}
|
|
@@ -2233,7 +2226,7 @@ class Compound {
|
|
|
2233
2226
|
return node.is(this.tagName) && this.conditions.every((cur) => cur.match(node, context));
|
|
2234
2227
|
}
|
|
2235
2228
|
createCondition(pattern) {
|
|
2236
|
-
switch (pattern
|
|
2229
|
+
switch (pattern.at(0)) {
|
|
2237
2230
|
case ".":
|
|
2238
2231
|
return createClassCondition(pattern.slice(1));
|
|
2239
2232
|
case "#":
|
|
@@ -2426,9 +2419,9 @@ class ComplexSelector {
|
|
|
2426
2419
|
case Combinator.CHILD:
|
|
2427
2420
|
return root.childElements.filter((node) => node.is(pattern.tagName));
|
|
2428
2421
|
case Combinator.ADJACENT_SIBLING:
|
|
2429
|
-
return
|
|
2422
|
+
return this.findAdjacentSibling(root);
|
|
2430
2423
|
case Combinator.GENERAL_SIBLING:
|
|
2431
|
-
return
|
|
2424
|
+
return this.findGeneralSibling(root);
|
|
2432
2425
|
case Combinator.SCOPE:
|
|
2433
2426
|
return [root];
|
|
2434
2427
|
}
|
|
@@ -2466,12 +2459,11 @@ const codepoints = {
|
|
|
2466
2459
|
"\r": "\\d "
|
|
2467
2460
|
};
|
|
2468
2461
|
function escapeSelectorComponent(text) {
|
|
2469
|
-
return text.toString().replaceAll(/([
|
|
2470
|
-
if (codepoints
|
|
2462
|
+
return text.toString().replaceAll(/([^\w-])/g, (_, ch) => {
|
|
2463
|
+
if (Object.hasOwn(codepoints, ch)) {
|
|
2471
2464
|
return codepoints[ch];
|
|
2472
|
-
} else {
|
|
2473
|
-
return `\\${ch}`;
|
|
2474
2465
|
}
|
|
2466
|
+
return `\\${ch}`;
|
|
2475
2467
|
});
|
|
2476
2468
|
}
|
|
2477
2469
|
|
|
@@ -2634,10 +2626,10 @@ class HtmlElement extends DOMNode {
|
|
|
2634
2626
|
*/
|
|
2635
2627
|
static fromTokens(startToken, endToken, parent, metaTable, namespace = "") {
|
|
2636
2628
|
const name = startToken.data[2];
|
|
2637
|
-
const tagName = namespace ? `${namespace}:${name}` : name;
|
|
2638
2629
|
if (!name) {
|
|
2639
2630
|
throw new Error("tagName cannot be empty");
|
|
2640
2631
|
}
|
|
2632
|
+
const tagName = namespace ? `${namespace}:${name}` : name;
|
|
2641
2633
|
const meta = metaTable ? metaTable.getMetaFor(tagName) : null;
|
|
2642
2634
|
const open = startToken.data[1] !== "/";
|
|
2643
2635
|
const closed = isClosed(endToken, meta);
|
|
@@ -2659,9 +2651,8 @@ class HtmlElement extends DOMNode {
|
|
|
2659
2651
|
get annotatedName() {
|
|
2660
2652
|
if (this.annotation) {
|
|
2661
2653
|
return this.annotation;
|
|
2662
|
-
} else {
|
|
2663
|
-
return `<${this.tagName}>`;
|
|
2664
2654
|
}
|
|
2655
|
+
return `<${this.tagName}>`;
|
|
2665
2656
|
}
|
|
2666
2657
|
/**
|
|
2667
2658
|
* Get list of IDs referenced by `aria-labelledby`.
|
|
@@ -2880,13 +2871,13 @@ class HtmlElement extends DOMNode {
|
|
|
2880
2871
|
if (!tabindex) {
|
|
2881
2872
|
return this.cacheSet(TABINDEX, null);
|
|
2882
2873
|
}
|
|
2883
|
-
if (tabindex.value === null) {
|
|
2874
|
+
if (tabindex.value === null || tabindex.value === "") {
|
|
2884
2875
|
return this.cacheSet(TABINDEX, null);
|
|
2885
2876
|
}
|
|
2886
2877
|
if (tabindex.value instanceof DynamicValue) {
|
|
2887
2878
|
return this.cacheSet(TABINDEX, 0);
|
|
2888
2879
|
}
|
|
2889
|
-
const parsed =
|
|
2880
|
+
const parsed = Math.trunc(Number(tabindex.value));
|
|
2890
2881
|
if (Number.isNaN(parsed)) {
|
|
2891
2882
|
return this.cacheSet(TABINDEX, null);
|
|
2892
2883
|
}
|
|
@@ -2902,11 +2893,11 @@ class HtmlElement extends DOMNode {
|
|
|
2902
2893
|
const tagName = this.tagName.toLowerCase();
|
|
2903
2894
|
if (tagName === "script") {
|
|
2904
2895
|
return "script";
|
|
2905
|
-
}
|
|
2896
|
+
}
|
|
2897
|
+
if (tagName === "style") {
|
|
2906
2898
|
return "css";
|
|
2907
|
-
} else {
|
|
2908
|
-
return "text";
|
|
2909
2899
|
}
|
|
2900
|
+
return "text";
|
|
2910
2901
|
}
|
|
2911
2902
|
/**
|
|
2912
2903
|
* Get a list of all attributes on this node.
|
|
@@ -2918,16 +2909,15 @@ class HtmlElement extends DOMNode {
|
|
|
2918
2909
|
}
|
|
2919
2910
|
hasAttribute(key) {
|
|
2920
2911
|
key = key.toLowerCase();
|
|
2921
|
-
return
|
|
2912
|
+
return Object.hasOwn(this.attr, key);
|
|
2922
2913
|
}
|
|
2923
2914
|
getAttribute(key, all = false) {
|
|
2924
2915
|
key = key.toLowerCase();
|
|
2925
|
-
if (
|
|
2916
|
+
if (Object.hasOwn(this.attr, key)) {
|
|
2926
2917
|
const matches = this.attr[key];
|
|
2927
2918
|
return all ? matches : matches[0];
|
|
2928
|
-
} else {
|
|
2929
|
-
return all ? [] : null;
|
|
2930
2919
|
}
|
|
2920
|
+
return all ? [] : null;
|
|
2931
2921
|
}
|
|
2932
2922
|
/**
|
|
2933
2923
|
* Get attribute value.
|
|
@@ -2945,17 +2935,13 @@ class HtmlElement extends DOMNode {
|
|
|
2945
2935
|
const attr = this.getAttribute(key);
|
|
2946
2936
|
if (attr) {
|
|
2947
2937
|
return attr.value !== null ? attr.value.toString() : null;
|
|
2948
|
-
} else {
|
|
2949
|
-
return null;
|
|
2950
2938
|
}
|
|
2939
|
+
return null;
|
|
2951
2940
|
}
|
|
2952
|
-
/**
|
|
2953
|
-
* Add text as a child node to this element.
|
|
2954
|
-
*
|
|
2955
|
-
* @param text - Text to add.
|
|
2956
|
-
* @param location - Source code location of this text.
|
|
2957
|
-
*/
|
|
2958
2941
|
appendText(text, location) {
|
|
2942
|
+
if (typeof text === "object" && "dynamic" in text) {
|
|
2943
|
+
text = new DynamicValue(text.dynamic);
|
|
2944
|
+
}
|
|
2959
2945
|
this.childNodes.push(new TextNode(text, location));
|
|
2960
2946
|
}
|
|
2961
2947
|
/**
|
|
@@ -3025,14 +3011,13 @@ class HtmlElement extends DOMNode {
|
|
|
3025
3011
|
const next = it.next();
|
|
3026
3012
|
if (next.done) {
|
|
3027
3013
|
return null;
|
|
3028
|
-
} else {
|
|
3029
|
-
return next.value;
|
|
3030
3014
|
}
|
|
3015
|
+
return next.value;
|
|
3031
3016
|
}
|
|
3032
3017
|
querySelectorAll(selector) {
|
|
3033
3018
|
const it = this.querySelectorImpl(selector);
|
|
3034
3019
|
const unique = new Set(it);
|
|
3035
|
-
return Array.from(unique
|
|
3020
|
+
return Array.from(unique);
|
|
3036
3021
|
}
|
|
3037
3022
|
*querySelectorImpl(selectorList) {
|
|
3038
3023
|
if (!selectorList) {
|
|
@@ -3053,9 +3038,8 @@ class HtmlElement extends DOMNode {
|
|
|
3053
3038
|
function visit(node) {
|
|
3054
3039
|
if (callback(node)) {
|
|
3055
3040
|
return true;
|
|
3056
|
-
} else {
|
|
3057
|
-
return node.childElements.some(visit);
|
|
3058
3041
|
}
|
|
3042
|
+
return node.childElements.some(visit);
|
|
3059
3043
|
}
|
|
3060
3044
|
}
|
|
3061
3045
|
/**
|
|
@@ -3230,7 +3214,7 @@ class Validator {
|
|
|
3230
3214
|
return true;
|
|
3231
3215
|
}
|
|
3232
3216
|
return rules.some((rule) => {
|
|
3233
|
-
return
|
|
3217
|
+
return this.validatePermittedRule(node, rule);
|
|
3234
3218
|
});
|
|
3235
3219
|
}
|
|
3236
3220
|
/**
|
|
@@ -3257,9 +3241,7 @@ class Validator {
|
|
|
3257
3241
|
const [, category, quantifier] = /^(@?.*?)([*?]?)$/.exec(rule);
|
|
3258
3242
|
const limit = category && quantifier && parseQuantifier(quantifier);
|
|
3259
3243
|
if (limit) {
|
|
3260
|
-
const siblings = children.filter(
|
|
3261
|
-
(cur) => Validator.validatePermittedCategory(cur, rule, true)
|
|
3262
|
-
);
|
|
3244
|
+
const siblings = children.filter((cur) => this.validatePermittedCategory(cur, rule, true));
|
|
3263
3245
|
if (siblings.length > limit) {
|
|
3264
3246
|
for (const child of siblings.slice(limit)) {
|
|
3265
3247
|
cb(child, category);
|
|
@@ -3290,12 +3272,12 @@ class Validator {
|
|
|
3290
3272
|
let prev = null;
|
|
3291
3273
|
for (const node of children) {
|
|
3292
3274
|
const old = i;
|
|
3293
|
-
while (rules[i] && !
|
|
3275
|
+
while (rules[i] && !this.validatePermittedCategory(node, rules[i], true)) {
|
|
3294
3276
|
i++;
|
|
3295
3277
|
}
|
|
3296
3278
|
if (i >= rules.length) {
|
|
3297
|
-
const orderSpecified = rules.
|
|
3298
|
-
(cur) =>
|
|
3279
|
+
const orderSpecified = rules.some(
|
|
3280
|
+
(cur) => this.validatePermittedCategory(node, cur, true)
|
|
3299
3281
|
);
|
|
3300
3282
|
if (orderSpecified) {
|
|
3301
3283
|
cb(node, prev);
|
|
@@ -3334,7 +3316,7 @@ class Validator {
|
|
|
3334
3316
|
}
|
|
3335
3317
|
return rules.filter((tagName) => {
|
|
3336
3318
|
const haveMatchingChild = node.childElements.some(
|
|
3337
|
-
(child) =>
|
|
3319
|
+
(child) => this.validatePermittedCategory(child, tagName, false)
|
|
3338
3320
|
);
|
|
3339
3321
|
return !haveMatchingChild;
|
|
3340
3322
|
});
|
|
@@ -3381,36 +3363,35 @@ class Validator {
|
|
|
3381
3363
|
return rule.enum.some((entry) => {
|
|
3382
3364
|
if (typeof entry === "string") {
|
|
3383
3365
|
return caseInsensitiveValue === entry;
|
|
3384
|
-
}
|
|
3366
|
+
}
|
|
3367
|
+
if (entry instanceof RegExp) {
|
|
3385
3368
|
return entry.test(value);
|
|
3386
|
-
}
|
|
3369
|
+
}
|
|
3370
|
+
if (entry.pattern instanceof RegExp) {
|
|
3387
3371
|
return entry.pattern.test(value);
|
|
3388
|
-
} else {
|
|
3389
|
-
throw new TypeError("RegExp was not precompiled when it should have been");
|
|
3390
3372
|
}
|
|
3373
|
+
throw new TypeError("RegExp was not precompiled when it should have been");
|
|
3391
3374
|
});
|
|
3392
3375
|
}
|
|
3393
3376
|
static validatePermittedRule(node, rule, isExclude = false) {
|
|
3394
3377
|
if (typeof rule === "string") {
|
|
3395
|
-
return
|
|
3396
|
-
}
|
|
3378
|
+
return this.validatePermittedCategory(node, rule, !isExclude);
|
|
3379
|
+
}
|
|
3380
|
+
if (Array.isArray(rule)) {
|
|
3397
3381
|
return rule.every((inner) => {
|
|
3398
|
-
return
|
|
3382
|
+
return this.validatePermittedRule(node, inner, isExclude);
|
|
3399
3383
|
});
|
|
3400
|
-
}
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
} else {
|
|
3408
|
-
return !Validator.validatePermittedRule(node, rule.exclude, true);
|
|
3409
|
-
}
|
|
3410
|
-
} else {
|
|
3411
|
-
return true;
|
|
3384
|
+
}
|
|
3385
|
+
validateKeys(rule);
|
|
3386
|
+
if (rule.exclude) {
|
|
3387
|
+
if (Array.isArray(rule.exclude)) {
|
|
3388
|
+
return rule.exclude.every((inner) => {
|
|
3389
|
+
return !this.validatePermittedRule(node, inner, true);
|
|
3390
|
+
});
|
|
3412
3391
|
}
|
|
3392
|
+
return !this.validatePermittedRule(node, rule.exclude, true);
|
|
3413
3393
|
}
|
|
3394
|
+
return true;
|
|
3414
3395
|
}
|
|
3415
3396
|
/**
|
|
3416
3397
|
* Validate node against a content category.
|
|
@@ -3426,7 +3407,7 @@ class Validator {
|
|
|
3426
3407
|
*/
|
|
3427
3408
|
/* eslint-disable-next-line complexity -- rule does not like switch */
|
|
3428
3409
|
static validatePermittedCategory(node, category, defaultMatch) {
|
|
3429
|
-
const [, rawCategory] = /^(@?.*?)
|
|
3410
|
+
const [, rawCategory] = /^(@?.*?)[*?]?$/.exec(category);
|
|
3430
3411
|
if (!rawCategory.startsWith("@")) {
|
|
3431
3412
|
return node.matches(rawCategory);
|
|
3432
3413
|
}
|
|
@@ -3459,10 +3440,11 @@ class Validator {
|
|
|
3459
3440
|
}
|
|
3460
3441
|
function validateKeys(rule) {
|
|
3461
3442
|
for (const key of Object.keys(rule)) {
|
|
3462
|
-
if (
|
|
3463
|
-
|
|
3464
|
-
throw new Error(`Permitted rule "${str}" contains unknown property "${key}"`);
|
|
3443
|
+
if (allowedKeys.has(key)) {
|
|
3444
|
+
continue;
|
|
3465
3445
|
}
|
|
3446
|
+
const str = JSON.stringify(rule);
|
|
3447
|
+
throw new Error(`Permitted rule "${str}" contains unknown property "${key}"`);
|
|
3466
3448
|
}
|
|
3467
3449
|
}
|
|
3468
3450
|
function parseQuantifier(quantifier) {
|
|
@@ -3529,9 +3511,8 @@ function ariaNaming(element) {
|
|
|
3529
3511
|
if (role) {
|
|
3530
3512
|
if (role instanceof DynamicValue) {
|
|
3531
3513
|
return element.cacheSet(cacheKey, defaultValue);
|
|
3532
|
-
} else {
|
|
3533
|
-
return element.cacheSet(cacheKey, byRole(role));
|
|
3534
3514
|
}
|
|
3515
|
+
return element.cacheSet(cacheKey, byRole(role));
|
|
3535
3516
|
}
|
|
3536
3517
|
const meta = element.meta;
|
|
3537
3518
|
if (!meta) {
|
|
@@ -3716,9 +3697,8 @@ function isPresentation(node) {
|
|
|
3716
3697
|
const role = node.getAttribute("role");
|
|
3717
3698
|
if (role && (role.value === "presentation" || role.value === "none")) {
|
|
3718
3699
|
return node.cacheSet(ROLE_PRESENTATION_CACHE, true);
|
|
3719
|
-
} else {
|
|
3720
|
-
return node.cacheSet(ROLE_PRESENTATION_CACHE, false);
|
|
3721
3700
|
}
|
|
3701
|
+
return node.cacheSet(ROLE_PRESENTATION_CACHE, false);
|
|
3722
3702
|
}
|
|
3723
3703
|
|
|
3724
3704
|
const cachePrefix = classifyNodeText.name;
|
|
@@ -3736,13 +3716,14 @@ function getCachekey(options) {
|
|
|
3736
3716
|
const { accessible = false, ignoreHiddenRoot = false } = options;
|
|
3737
3717
|
if (accessible && ignoreHiddenRoot) {
|
|
3738
3718
|
return IGNORE_HIDDEN_ROOT_A11Y_CACHE_KEY;
|
|
3739
|
-
}
|
|
3719
|
+
}
|
|
3720
|
+
if (ignoreHiddenRoot) {
|
|
3740
3721
|
return IGNORE_HIDDEN_ROOT_HTML_CACHE_KEY;
|
|
3741
|
-
}
|
|
3722
|
+
}
|
|
3723
|
+
if (accessible) {
|
|
3742
3724
|
return A11Y_CACHE_KEY;
|
|
3743
|
-
} else {
|
|
3744
|
-
return HTML_CACHE_KEY;
|
|
3745
3725
|
}
|
|
3726
|
+
return HTML_CACHE_KEY;
|
|
3746
3727
|
}
|
|
3747
3728
|
function isSpecialEmpty(node) {
|
|
3748
3729
|
return node.is("select") || node.is("textarea");
|
|
@@ -3774,7 +3755,7 @@ function classifyNodeText(node, options = {}) {
|
|
|
3774
3755
|
}
|
|
3775
3756
|
function findTextNodes(node, options) {
|
|
3776
3757
|
const { accessible = false } = options;
|
|
3777
|
-
|
|
3758
|
+
const text = [];
|
|
3778
3759
|
for (const child of node.childNodes) {
|
|
3779
3760
|
if (isTextNode(child)) {
|
|
3780
3761
|
text.push(child);
|
|
@@ -3785,7 +3766,7 @@ function findTextNodes(node, options) {
|
|
|
3785
3766
|
if (accessible && isAriaHidden(child, true).bySelf) {
|
|
3786
3767
|
continue;
|
|
3787
3768
|
}
|
|
3788
|
-
text
|
|
3769
|
+
text.push(...findTextNodes(child, options));
|
|
3789
3770
|
}
|
|
3790
3771
|
}
|
|
3791
3772
|
return text;
|
|
@@ -3846,14 +3827,17 @@ function format(value, quote = false) {
|
|
|
3846
3827
|
return String(value);
|
|
3847
3828
|
}
|
|
3848
3829
|
function interpolate(text, data) {
|
|
3849
|
-
return text.replaceAll(
|
|
3830
|
+
return text.replaceAll(/\{\{\s*([^\s{}]+)\s*\}\}/g, (match, key) => {
|
|
3850
3831
|
return data[key] !== void 0 ? format(data[key]) : match;
|
|
3851
3832
|
});
|
|
3852
3833
|
}
|
|
3853
3834
|
|
|
3854
|
-
const ajv$1 =
|
|
3855
|
-
|
|
3856
|
-
|
|
3835
|
+
const ajv$1 = (() => {
|
|
3836
|
+
const ajv2 = new Ajv({ strict: true, strictTuples: true, strictTypes: true });
|
|
3837
|
+
ajv2.addMetaSchema(ajvSchemaDraft);
|
|
3838
|
+
ajv2.addKeyword(ajvRegexpKeyword);
|
|
3839
|
+
return ajv2;
|
|
3840
|
+
})();
|
|
3857
3841
|
function getSchemaValidator(ruleId, properties) {
|
|
3858
3842
|
const $id = `rule/${ruleId}`;
|
|
3859
3843
|
const cached = ajv$1.getSchema($id);
|
|
@@ -3874,10 +3858,9 @@ function isErrorDescriptor(value) {
|
|
|
3874
3858
|
function unpackErrorDescriptor(value) {
|
|
3875
3859
|
if (isErrorDescriptor(value)) {
|
|
3876
3860
|
return value[0];
|
|
3877
|
-
} else {
|
|
3878
|
-
const [node, message, location, context] = value;
|
|
3879
|
-
return { node, message, location, context };
|
|
3880
3861
|
}
|
|
3862
|
+
const [node, message, location, context] = value;
|
|
3863
|
+
return { node, message, location, context };
|
|
3881
3864
|
}
|
|
3882
3865
|
class Rule {
|
|
3883
3866
|
reporter;
|
|
@@ -4083,17 +4066,18 @@ class Rule {
|
|
|
4083
4066
|
const callback = args.pop();
|
|
4084
4067
|
const filter = args.pop() ?? (() => true);
|
|
4085
4068
|
return this.parser.on(event, (_event, data) => {
|
|
4086
|
-
if (this.isEnabled()
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4069
|
+
if (!this.isEnabled() || !filter(data)) {
|
|
4070
|
+
return;
|
|
4071
|
+
}
|
|
4072
|
+
this.event = data;
|
|
4073
|
+
const { tracker } = this;
|
|
4074
|
+
if (tracker) {
|
|
4075
|
+
const start = performance.now();
|
|
4076
|
+
callback(data);
|
|
4077
|
+
const end = performance.now();
|
|
4078
|
+
tracker.trackRule(this.name, end - start);
|
|
4079
|
+
} else {
|
|
4080
|
+
callback(data);
|
|
4097
4081
|
}
|
|
4098
4082
|
});
|
|
4099
4083
|
}
|
|
@@ -4163,7 +4147,7 @@ class Rule {
|
|
|
4163
4147
|
* @public
|
|
4164
4148
|
* @virtual
|
|
4165
4149
|
* @param context - Error context given by a reported error.
|
|
4166
|
-
* @returns Rule documentation and
|
|
4150
|
+
* @returns Rule documentation and URL with additional details or `null` if no
|
|
4167
4151
|
* additional documentation is available.
|
|
4168
4152
|
*/
|
|
4169
4153
|
documentation(_context) {
|
|
@@ -4202,7 +4186,7 @@ function parseAllow(value) {
|
|
|
4202
4186
|
};
|
|
4203
4187
|
}
|
|
4204
4188
|
function matchList(value, list) {
|
|
4205
|
-
if (list.include
|
|
4189
|
+
if (list.include?.every((it) => !it.test(value))) {
|
|
4206
4190
|
return false;
|
|
4207
4191
|
}
|
|
4208
4192
|
if (list.exclude?.some((it) => it.test(value))) {
|
|
@@ -4287,10 +4271,10 @@ class AllowedLinks extends Rule {
|
|
|
4287
4271
|
return Boolean(attr && attr === key);
|
|
4288
4272
|
}
|
|
4289
4273
|
getStyle(value) {
|
|
4290
|
-
if (/^([a-z]+:)
|
|
4274
|
+
if (/^(?:[a-z]+:)?\/\//.test(value)) {
|
|
4291
4275
|
return "external" /* EXTERNAL */;
|
|
4292
4276
|
}
|
|
4293
|
-
switch (value
|
|
4277
|
+
switch (value.at(0)) {
|
|
4294
4278
|
/* /foo/bar */
|
|
4295
4279
|
case "/":
|
|
4296
4280
|
return "absolute" /* ABSOLUTE */;
|
|
@@ -4309,7 +4293,8 @@ class AllowedLinks extends Rule {
|
|
|
4309
4293
|
const { allowAbsolute } = this;
|
|
4310
4294
|
if (allowAbsolute === true) {
|
|
4311
4295
|
return;
|
|
4312
|
-
}
|
|
4296
|
+
}
|
|
4297
|
+
if (allowAbsolute === false) {
|
|
4313
4298
|
this.report(
|
|
4314
4299
|
event.target,
|
|
4315
4300
|
"Link destination must not be absolute url",
|
|
@@ -4329,7 +4314,8 @@ class AllowedLinks extends Rule {
|
|
|
4329
4314
|
const { allowExternal } = this;
|
|
4330
4315
|
if (allowExternal === true) {
|
|
4331
4316
|
return;
|
|
4332
|
-
}
|
|
4317
|
+
}
|
|
4318
|
+
if (allowExternal === false) {
|
|
4333
4319
|
this.report(
|
|
4334
4320
|
event.target,
|
|
4335
4321
|
"Link destination must not be external url",
|
|
@@ -4349,7 +4335,8 @@ class AllowedLinks extends Rule {
|
|
|
4349
4335
|
const { allowRelative } = this;
|
|
4350
4336
|
if (allowRelative === true) {
|
|
4351
4337
|
return false;
|
|
4352
|
-
}
|
|
4338
|
+
}
|
|
4339
|
+
if (allowRelative === false) {
|
|
4353
4340
|
this.report(
|
|
4354
4341
|
event.target,
|
|
4355
4342
|
"Link destination must not be relative url",
|
|
@@ -4357,7 +4344,8 @@ class AllowedLinks extends Rule {
|
|
|
4357
4344
|
style
|
|
4358
4345
|
);
|
|
4359
4346
|
return true;
|
|
4360
|
-
}
|
|
4347
|
+
}
|
|
4348
|
+
if (!matchList(target, allowRelative)) {
|
|
4361
4349
|
this.report(
|
|
4362
4350
|
event.target,
|
|
4363
4351
|
"Relative link to this destination is not allowed by current configuration",
|
|
@@ -4372,7 +4360,8 @@ class AllowedLinks extends Rule {
|
|
|
4372
4360
|
const { allowBase } = this.options;
|
|
4373
4361
|
if (this.handleRelativePath(target, event, style)) {
|
|
4374
4362
|
return;
|
|
4375
|
-
}
|
|
4363
|
+
}
|
|
4364
|
+
if (!allowBase) {
|
|
4376
4365
|
this.report(
|
|
4377
4366
|
event.target,
|
|
4378
4367
|
"Relative links must be relative to current folder",
|
|
@@ -4590,12 +4579,11 @@ class AriaLabelMisuse extends Rule {
|
|
|
4590
4579
|
].join("\n"),
|
|
4591
4580
|
url
|
|
4592
4581
|
};
|
|
4593
|
-
} else {
|
|
4594
|
-
return {
|
|
4595
|
-
description: [`\`${context.attr}\` can only be used on:`, "", ...lines].join("\n"),
|
|
4596
|
-
url
|
|
4597
|
-
};
|
|
4598
4582
|
}
|
|
4583
|
+
return {
|
|
4584
|
+
description: [`\`${context.attr}\` can only be used on:`, "", ...lines].join("\n"),
|
|
4585
|
+
url
|
|
4586
|
+
};
|
|
4599
4587
|
}
|
|
4600
4588
|
setup() {
|
|
4601
4589
|
this.on("dom:ready", (event) => {
|
|
@@ -4653,6 +4641,7 @@ class AriaLabelMisuse extends Rule {
|
|
|
4653
4641
|
}
|
|
4654
4642
|
|
|
4655
4643
|
class ConfigError extends UserError {
|
|
4644
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
4656
4645
|
constructor(message, nested) {
|
|
4657
4646
|
super(message, nested);
|
|
4658
4647
|
this.name = "ConfigError";
|
|
@@ -4773,9 +4762,8 @@ class AttrCase extends Rule {
|
|
|
4773
4762
|
isIgnored(node) {
|
|
4774
4763
|
if (this.options.ignoreForeign) {
|
|
4775
4764
|
return Boolean(node.meta?.foreign);
|
|
4776
|
-
} else {
|
|
4777
|
-
return false;
|
|
4778
4765
|
}
|
|
4766
|
+
return false;
|
|
4779
4767
|
}
|
|
4780
4768
|
}
|
|
4781
4769
|
|
|
@@ -4825,10 +4813,11 @@ class Context {
|
|
|
4825
4813
|
let lastNewline = -1;
|
|
4826
4814
|
let newlines = 0;
|
|
4827
4815
|
for (let i = 0; i < n; i++) {
|
|
4828
|
-
if (this.string[i]
|
|
4829
|
-
|
|
4830
|
-
lastNewline = i;
|
|
4816
|
+
if (this.string[i] !== "\n") {
|
|
4817
|
+
continue;
|
|
4831
4818
|
}
|
|
4819
|
+
newlines++;
|
|
4820
|
+
lastNewline = i;
|
|
4832
4821
|
}
|
|
4833
4822
|
if (newlines > 0) {
|
|
4834
4823
|
this.line += newlines;
|
|
@@ -4890,28 +4879,29 @@ const MATCH_DOCTYPE_CLOSE = /^>/;
|
|
|
4890
4879
|
const MATCH_XML_TAG = /^<\?xml.*?\?>\s+/;
|
|
4891
4880
|
const MATCH_TAG_OPEN = /^<(\/?)([\w:\-]+)/;
|
|
4892
4881
|
const MATCH_TAG_CLOSE = /^\/?>/;
|
|
4893
|
-
const MATCH_TEXT = /^[
|
|
4882
|
+
const MATCH_TEXT = /^[\s\S]*?(?=[\t ]*(?:\r\n|\r|\n)|<[^ ]|$)/;
|
|
4894
4883
|
const MATCH_TEMPLATING = /^(?:<%.*?%>|<\?.*?\?>|<\$.*?\$>)/s;
|
|
4895
|
-
const MATCH_TAG_LOOKAHEAD = /^[
|
|
4884
|
+
const MATCH_TAG_LOOKAHEAD = /^[\s\S]*?(?=<|$)/;
|
|
4896
4885
|
const MATCH_ATTR_START = /^([^\t\n\f\r "'/<=>]+)/;
|
|
4897
|
-
const MATCH_ATTR_SINGLE = /^(\s*=\s*)'([^']
|
|
4898
|
-
const MATCH_ATTR_DOUBLE = /^(\s*=\s*)"([^"]
|
|
4886
|
+
const MATCH_ATTR_SINGLE = /^(\s*=\s*)'([^']*)(')/;
|
|
4887
|
+
const MATCH_ATTR_DOUBLE = /^(\s*=\s*)"([^"]*)(")/;
|
|
4899
4888
|
const MATCH_ATTR_UNQUOTED = /^(\s*=\s*)([^\t\n\f\r "'<>][^\t\n\f\r <>]*)/;
|
|
4900
4889
|
const MATCH_CDATA_BEGIN = /^<!\[CDATA\[/;
|
|
4901
|
-
const MATCH_CDATA_END = /^[
|
|
4902
|
-
const MATCH_SCRIPT_DATA = /^[
|
|
4890
|
+
const MATCH_CDATA_END = /^[\s\S]*?\]\]>/;
|
|
4891
|
+
const MATCH_SCRIPT_DATA = /^[\s\S]*?(?=<\/script)/;
|
|
4903
4892
|
const MATCH_SCRIPT_END = /^<(\/)(script)/;
|
|
4904
|
-
const MATCH_STYLE_DATA = /^[
|
|
4893
|
+
const MATCH_STYLE_DATA = /^[\s\S]*?(?=<\/style)/;
|
|
4905
4894
|
const MATCH_STYLE_END = /^<(\/)(style)/;
|
|
4906
|
-
const MATCH_TEXTAREA_DATA = /^[
|
|
4895
|
+
const MATCH_TEXTAREA_DATA = /^[\s\S]*?(?=<\/textarea)/;
|
|
4907
4896
|
const MATCH_TEXTAREA_END = /^<(\/)(textarea)/;
|
|
4908
|
-
const MATCH_TITLE_DATA = /^[
|
|
4897
|
+
const MATCH_TITLE_DATA = /^[\s\S]*?(?=<\/title)/;
|
|
4909
4898
|
const MATCH_TITLE_END = /^<(\/)(title)/;
|
|
4910
|
-
const MATCH_DIRECTIVE = /^(<!--\s*\[?)(html-validate-)([\da-z-]+)(\s*)(.*?)(]?\s*-->)/;
|
|
4911
|
-
const MATCH_COMMENT = /^<!--([
|
|
4912
|
-
const MATCH_CONDITIONAL = /^<!\[([^\]]
|
|
4899
|
+
const MATCH_DIRECTIVE = /^(<!--\s*\[?)(html-validate-)([\da-z-]+)(\s*)(.*?)(\]?\s*-->)/;
|
|
4900
|
+
const MATCH_COMMENT = /^<!--([\s\S]*?)-->/;
|
|
4901
|
+
const MATCH_CONDITIONAL = /^<!\[([^\]]*)\]>/;
|
|
4913
4902
|
class InvalidTokenError extends Error {
|
|
4914
4903
|
location;
|
|
4904
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
4915
4905
|
constructor(location, message) {
|
|
4916
4906
|
super(message);
|
|
4917
4907
|
this.name = "InvalidTokenError";
|
|
@@ -4995,9 +4985,8 @@ class Lexer {
|
|
|
4995
4985
|
evalNextState(nextState, token) {
|
|
4996
4986
|
if (typeof nextState === "function") {
|
|
4997
4987
|
return nextState(token);
|
|
4998
|
-
} else {
|
|
4999
|
-
return nextState;
|
|
5000
4988
|
}
|
|
4989
|
+
return nextState;
|
|
5001
4990
|
}
|
|
5002
4991
|
*match(context, tests, error) {
|
|
5003
4992
|
const n = tests.length;
|
|
@@ -5084,27 +5073,26 @@ class Lexer {
|
|
|
5084
5073
|
case ContentModel.SCRIPT:
|
|
5085
5074
|
if (selfClosed) {
|
|
5086
5075
|
return State.SCRIPT;
|
|
5087
|
-
} else {
|
|
5088
|
-
return State.TEXT;
|
|
5089
5076
|
}
|
|
5077
|
+
return State.TEXT;
|
|
5078
|
+
/* <script/> (not legal but handle it anyway so the lexer doesn't choke on it) */
|
|
5090
5079
|
case ContentModel.STYLE:
|
|
5091
5080
|
if (selfClosed) {
|
|
5092
5081
|
return State.STYLE;
|
|
5093
|
-
} else {
|
|
5094
|
-
return State.TEXT;
|
|
5095
5082
|
}
|
|
5083
|
+
return State.TEXT;
|
|
5084
|
+
/* <style/> */
|
|
5096
5085
|
case ContentModel.TEXTAREA:
|
|
5097
5086
|
if (selfClosed) {
|
|
5098
5087
|
return State.TEXTAREA;
|
|
5099
|
-
} else {
|
|
5100
|
-
return State.TEXT;
|
|
5101
5088
|
}
|
|
5089
|
+
return State.TEXT;
|
|
5090
|
+
/* <textarea/> */
|
|
5102
5091
|
case ContentModel.TITLE:
|
|
5103
5092
|
if (selfClosed) {
|
|
5104
5093
|
return State.TITLE;
|
|
5105
|
-
} else {
|
|
5106
|
-
return State.TEXT;
|
|
5107
5094
|
}
|
|
5095
|
+
return State.TEXT;
|
|
5108
5096
|
}
|
|
5109
5097
|
}
|
|
5110
5098
|
yield* this.match(
|
|
@@ -5191,7 +5179,7 @@ class Lexer {
|
|
|
5191
5179
|
}
|
|
5192
5180
|
}
|
|
5193
5181
|
|
|
5194
|
-
const whitespace =
|
|
5182
|
+
const whitespace = /\s+/;
|
|
5195
5183
|
class AttrDelimiter extends Rule {
|
|
5196
5184
|
documentation() {
|
|
5197
5185
|
return {
|
|
@@ -5223,17 +5211,15 @@ const defaults$y = {
|
|
|
5223
5211
|
function generateRegexp(pattern) {
|
|
5224
5212
|
if (Array.isArray(pattern)) {
|
|
5225
5213
|
return new RegExp(`^(${pattern.join("|")})$`, "i");
|
|
5226
|
-
} else {
|
|
5227
|
-
return new RegExp(`^${pattern}$`, "i");
|
|
5228
5214
|
}
|
|
5215
|
+
return new RegExp(`^${pattern}$`, "i");
|
|
5229
5216
|
}
|
|
5230
5217
|
function generateMessage(name, pattern) {
|
|
5231
5218
|
if (Array.isArray(pattern)) {
|
|
5232
5219
|
const patterns = pattern.map((it) => `/${it}/`).join(", ");
|
|
5233
5220
|
return `Attribute "${name}" should match one of [${patterns}]`;
|
|
5234
|
-
} else {
|
|
5235
|
-
return `Attribute "${name}" should match /${pattern}/`;
|
|
5236
5221
|
}
|
|
5222
|
+
return `Attribute "${name}" should match /${pattern}/`;
|
|
5237
5223
|
}
|
|
5238
5224
|
function generateDescription(name, pattern) {
|
|
5239
5225
|
if (Array.isArray(pattern)) {
|
|
@@ -5242,9 +5228,8 @@ function generateDescription(name, pattern) {
|
|
|
5242
5228
|
"",
|
|
5243
5229
|
...pattern.map((it) => `- \`/${it}/\``)
|
|
5244
5230
|
].join("\n");
|
|
5245
|
-
} else {
|
|
5246
|
-
return `Attribute "${name}" should match the regular expression \`/${pattern}/\``;
|
|
5247
5231
|
}
|
|
5232
|
+
return `Attribute "${name}" should match the regular expression \`/${pattern}/\``;
|
|
5248
5233
|
}
|
|
5249
5234
|
class AttrPattern extends Rule {
|
|
5250
5235
|
pattern;
|
|
@@ -5290,9 +5275,8 @@ class AttrPattern extends Rule {
|
|
|
5290
5275
|
isIgnored(node) {
|
|
5291
5276
|
if (this.options.ignoreForeign) {
|
|
5292
5277
|
return Boolean(node.meta?.foreign);
|
|
5293
|
-
} else {
|
|
5294
|
-
return false;
|
|
5295
5278
|
}
|
|
5279
|
+
return false;
|
|
5296
5280
|
}
|
|
5297
5281
|
}
|
|
5298
5282
|
|
|
@@ -5403,9 +5387,8 @@ class AttrQuotes extends Rule {
|
|
|
5403
5387
|
resolveQuotemark(value, style) {
|
|
5404
5388
|
if (style === "auto" /* AUTO_QUOTE */) {
|
|
5405
5389
|
return value.includes('"') ? "'" : '"';
|
|
5406
|
-
} else {
|
|
5407
|
-
return style;
|
|
5408
5390
|
}
|
|
5391
|
+
return style;
|
|
5409
5392
|
}
|
|
5410
5393
|
}
|
|
5411
5394
|
function parseStyle$3(style) {
|
|
@@ -5463,11 +5446,11 @@ class AttributeAllowedValues extends Rule {
|
|
|
5463
5446
|
const allowedList = allowed.enum.map((value2) => {
|
|
5464
5447
|
if (typeof value2 === "string") {
|
|
5465
5448
|
return `- \`"${value2}"\``;
|
|
5466
|
-
}
|
|
5449
|
+
}
|
|
5450
|
+
if (value2 instanceof RegExp) {
|
|
5467
5451
|
return `- \`${value2.toString()}\``;
|
|
5468
|
-
} else {
|
|
5469
|
-
return `- ${value2.name}`;
|
|
5470
5452
|
}
|
|
5453
|
+
return `- ${value2.name}`;
|
|
5471
5454
|
});
|
|
5472
5455
|
docs.description = [
|
|
5473
5456
|
`The \`<${element}>\` element does not allow the attribute \`${attribute}\` to have the value \`"${value}"\`.`,
|
|
@@ -5511,9 +5494,8 @@ class AttributeAllowedValues extends Rule {
|
|
|
5511
5494
|
const { key, value } = attr;
|
|
5512
5495
|
if (value !== null) {
|
|
5513
5496
|
return `Attribute "${key}" has invalid value "${value.toString()}"`;
|
|
5514
|
-
} else {
|
|
5515
|
-
return `Attribute "${key}" is missing value`;
|
|
5516
5497
|
}
|
|
5498
|
+
return `Attribute "${key}" is missing value`;
|
|
5517
5499
|
}
|
|
5518
5500
|
getLocation(attr) {
|
|
5519
5501
|
return attr.valueLocation ?? attr.keyLocation;
|
|
@@ -5800,10 +5782,10 @@ class AutocompletePassword extends Rule {
|
|
|
5800
5782
|
const tokens = new DOMTokenList(raw, autocomplete.valueLocation);
|
|
5801
5783
|
const index = tokens.findIndex((token) => !isGroupingToken(token));
|
|
5802
5784
|
const value = tokens.item(index);
|
|
5803
|
-
const location = tokens.location(index);
|
|
5804
5785
|
if (!value) {
|
|
5805
5786
|
return;
|
|
5806
5787
|
}
|
|
5788
|
+
const location = tokens.location(index);
|
|
5807
5789
|
if (value === "off") {
|
|
5808
5790
|
const context = { kind: "off" };
|
|
5809
5791
|
this.report({
|
|
@@ -5888,9 +5870,8 @@ function parsePattern(pattern) {
|
|
|
5888
5870
|
function toArray$2(value) {
|
|
5889
5871
|
if (Array.isArray(value)) {
|
|
5890
5872
|
return value;
|
|
5891
|
-
} else {
|
|
5892
|
-
return [value];
|
|
5893
5873
|
}
|
|
5874
|
+
return [value];
|
|
5894
5875
|
}
|
|
5895
5876
|
function validateAllowedPatterns(patterns, allowedPatterns, ruleId) {
|
|
5896
5877
|
const extraneous = patterns.filter(isNamedPattern).filter((p) => !allowedPatterns.has(p));
|
|
@@ -5976,7 +5957,7 @@ class ClassPattern extends BasePatternRule {
|
|
|
5976
5957
|
});
|
|
5977
5958
|
}
|
|
5978
5959
|
static schema() {
|
|
5979
|
-
return
|
|
5960
|
+
return super.schema();
|
|
5980
5961
|
}
|
|
5981
5962
|
documentation(context) {
|
|
5982
5963
|
return {
|
|
@@ -6057,10 +6038,10 @@ class CloseOrder extends Rule {
|
|
|
6057
6038
|
});
|
|
6058
6039
|
this.on("tag:end", (event) => {
|
|
6059
6040
|
const current = event.target;
|
|
6060
|
-
const active = event.previous;
|
|
6061
6041
|
if (current) {
|
|
6062
6042
|
return;
|
|
6063
6043
|
}
|
|
6044
|
+
const active = event.previous;
|
|
6064
6045
|
for (const ancestor of ancestors(active)) {
|
|
6065
6046
|
if (ancestor.isRootElement() || reported.has(ancestor.unique)) {
|
|
6066
6047
|
continue;
|
|
@@ -6071,13 +6052,13 @@ class CloseOrder extends Rule {
|
|
|
6071
6052
|
});
|
|
6072
6053
|
this.on("tag:end", (event) => {
|
|
6073
6054
|
const current = event.target;
|
|
6074
|
-
const active = event.previous;
|
|
6075
6055
|
if (!current) {
|
|
6076
6056
|
return;
|
|
6077
6057
|
}
|
|
6078
6058
|
if (current.voidElement) {
|
|
6079
6059
|
return;
|
|
6080
6060
|
}
|
|
6061
|
+
const active = event.previous;
|
|
6081
6062
|
if (active.closed === Node.CLOSED_IMPLICIT_CLOSED) {
|
|
6082
6063
|
return;
|
|
6083
6064
|
}
|
|
@@ -6172,7 +6153,7 @@ class Deprecated extends Rule {
|
|
|
6172
6153
|
text.push(context.documentation);
|
|
6173
6154
|
}
|
|
6174
6155
|
const doc = {
|
|
6175
|
-
description: text.map((cur) => cur.replaceAll("$tagname", context.tagName)).join("\n\n"),
|
|
6156
|
+
description: text.map((cur) => cur.replaceAll("$tagname", () => context.tagName)).join("\n\n"),
|
|
6176
6157
|
url: "https://html-validate.org/rules/deprecated.html"
|
|
6177
6158
|
};
|
|
6178
6159
|
return doc;
|
|
@@ -6571,7 +6552,7 @@ class ElementName extends Rule {
|
|
|
6571
6552
|
];
|
|
6572
6553
|
}
|
|
6573
6554
|
setup() {
|
|
6574
|
-
const xmlns = /^
|
|
6555
|
+
const xmlns = /^[^:]+:.+$/;
|
|
6575
6556
|
this.on("tag:start", (event) => {
|
|
6576
6557
|
const target = event.target;
|
|
6577
6558
|
const tagName = target.tagName;
|
|
@@ -6610,13 +6591,12 @@ function isNativeTemplate(node) {
|
|
|
6610
6591
|
function getTransparentChildren(node, transparent) {
|
|
6611
6592
|
if (typeof transparent === "boolean") {
|
|
6612
6593
|
return node.childElements;
|
|
6613
|
-
} else {
|
|
6614
|
-
return node.childElements.filter((it) => {
|
|
6615
|
-
return transparent.some((category) => {
|
|
6616
|
-
return Validator.validatePermittedCategory(it, category, false);
|
|
6617
|
-
});
|
|
6618
|
-
});
|
|
6619
6594
|
}
|
|
6595
|
+
return node.childElements.filter((it) => {
|
|
6596
|
+
return transparent.some((category) => {
|
|
6597
|
+
return Validator.validatePermittedCategory(it, category, false);
|
|
6598
|
+
});
|
|
6599
|
+
});
|
|
6620
6600
|
}
|
|
6621
6601
|
function getRuleDescription$2(context) {
|
|
6622
6602
|
switch (context.kind) {
|
|
@@ -6648,6 +6628,7 @@ class ElementPermittedContent extends Rule {
|
|
|
6648
6628
|
[
|
|
6649
6629
|
() => this.validatePermittedContent(node, parent),
|
|
6650
6630
|
() => this.validatePermittedDescendant(node, parent)
|
|
6631
|
+
/* eslint-disable-next-line unicorn/no-unused-array-method-return -- technical debt, should use iterator helpers */
|
|
6651
6632
|
].some((fn) => fn());
|
|
6652
6633
|
});
|
|
6653
6634
|
});
|
|
@@ -6793,14 +6774,12 @@ function getRuleDescription$1(context) {
|
|
|
6793
6774
|
const allowed = rules.filter(isCategoryOrTag).map((it) => {
|
|
6794
6775
|
if (isCategory$1(it)) {
|
|
6795
6776
|
return `- any ${it.slice(1)} element`;
|
|
6796
|
-
} else {
|
|
6797
|
-
return `- \`<${it}>\``;
|
|
6798
6777
|
}
|
|
6778
|
+
return `- \`<${it}>\``;
|
|
6799
6779
|
});
|
|
6800
6780
|
return [preamble, "", "Allowed parents one of:", "", ...allowed];
|
|
6801
|
-
} else {
|
|
6802
|
-
return [preamble];
|
|
6803
6781
|
}
|
|
6782
|
+
return [preamble];
|
|
6804
6783
|
}
|
|
6805
6784
|
function formatMessage$1(node, parent, rules) {
|
|
6806
6785
|
const nodeName = node.annotatedName;
|
|
@@ -6852,7 +6831,7 @@ class ElementPermittedParent extends Rule {
|
|
|
6852
6831
|
}
|
|
6853
6832
|
|
|
6854
6833
|
function isTagnameOnly(value) {
|
|
6855
|
-
return /^[\dA-
|
|
6834
|
+
return /^[\dA-Z-]+$/i.test(value);
|
|
6856
6835
|
}
|
|
6857
6836
|
function getRuleDescription(context) {
|
|
6858
6837
|
const escaped = context.ancestor.map((it) => `\`${it}\``);
|
|
@@ -6915,9 +6894,8 @@ function normalizeRequired(element, attr) {
|
|
|
6915
6894
|
default:
|
|
6916
6895
|
return result;
|
|
6917
6896
|
}
|
|
6918
|
-
} else {
|
|
6919
|
-
return required ? defaultMessage : false;
|
|
6920
6897
|
}
|
|
6898
|
+
return required ? defaultMessage : false;
|
|
6921
6899
|
}
|
|
6922
6900
|
class ElementRequiredAttributes extends Rule {
|
|
6923
6901
|
documentation(context) {
|
|
@@ -6999,7 +6977,8 @@ const selector = ["h1", "h2", "h3", "h4", "h5", "h6"].join(",");
|
|
|
6999
6977
|
function hasImgAltText$1(node) {
|
|
7000
6978
|
if (node.is("img")) {
|
|
7001
6979
|
return hasAltText(node);
|
|
7002
|
-
}
|
|
6980
|
+
}
|
|
6981
|
+
if (node.is("svg")) {
|
|
7003
6982
|
return node.textContent.trim() !== "";
|
|
7004
6983
|
}
|
|
7005
6984
|
return false;
|
|
@@ -7280,21 +7259,19 @@ class FormDupName extends Rule {
|
|
|
7280
7259
|
const existing = group.cacheGet(UNIQUE_CACHE_KEY);
|
|
7281
7260
|
if (existing) {
|
|
7282
7261
|
return existing;
|
|
7283
|
-
} else {
|
|
7284
|
-
const elements = /* @__PURE__ */ new Map();
|
|
7285
|
-
group.cacheSet(UNIQUE_CACHE_KEY, elements);
|
|
7286
|
-
return elements;
|
|
7287
7262
|
}
|
|
7263
|
+
const elements = /* @__PURE__ */ new Map();
|
|
7264
|
+
group.cacheSet(UNIQUE_CACHE_KEY, elements);
|
|
7265
|
+
return elements;
|
|
7288
7266
|
}
|
|
7289
7267
|
getSharedElements(group) {
|
|
7290
7268
|
const existing = group.cacheGet(SHARED_CACHE_KEY);
|
|
7291
7269
|
if (existing) {
|
|
7292
7270
|
return existing;
|
|
7293
|
-
} else {
|
|
7294
|
-
const elements = /* @__PURE__ */ new Map();
|
|
7295
|
-
group.cacheSet(SHARED_CACHE_KEY, elements);
|
|
7296
|
-
return elements;
|
|
7297
7271
|
}
|
|
7272
|
+
const elements = /* @__PURE__ */ new Map();
|
|
7273
|
+
group.cacheSet(SHARED_CACHE_KEY, elements);
|
|
7274
|
+
return elements;
|
|
7298
7275
|
}
|
|
7299
7276
|
}
|
|
7300
7277
|
|
|
@@ -7308,12 +7285,11 @@ function isRelevant$5(event) {
|
|
|
7308
7285
|
return Boolean(node.meta?.heading);
|
|
7309
7286
|
}
|
|
7310
7287
|
function extractLevel(node) {
|
|
7311
|
-
const match = /^
|
|
7288
|
+
const match = /^H(\d)$/i.exec(node.tagName);
|
|
7312
7289
|
if (match) {
|
|
7313
|
-
return
|
|
7314
|
-
} else {
|
|
7315
|
-
return null;
|
|
7290
|
+
return Math.trunc(Number(match[1]));
|
|
7316
7291
|
}
|
|
7292
|
+
return null;
|
|
7317
7293
|
}
|
|
7318
7294
|
function parseMaxInitial(value) {
|
|
7319
7295
|
if (value === false || value === "any") {
|
|
@@ -7323,7 +7299,7 @@ function parseMaxInitial(value) {
|
|
|
7323
7299
|
if (!match) {
|
|
7324
7300
|
return 1;
|
|
7325
7301
|
}
|
|
7326
|
-
return
|
|
7302
|
+
return Math.trunc(Number(match[1]));
|
|
7327
7303
|
}
|
|
7328
7304
|
class HeadingLevel extends Rule {
|
|
7329
7305
|
minInitialRank;
|
|
@@ -7590,7 +7566,7 @@ class IdPattern extends BasePatternRule {
|
|
|
7590
7566
|
});
|
|
7591
7567
|
}
|
|
7592
7568
|
static schema() {
|
|
7593
|
-
return
|
|
7569
|
+
return super.schema();
|
|
7594
7570
|
}
|
|
7595
7571
|
documentation(context) {
|
|
7596
7572
|
return {
|
|
@@ -7812,24 +7788,23 @@ function isHidden(node, context) {
|
|
|
7812
7788
|
const { reference } = context;
|
|
7813
7789
|
if (reference?.isSameNode(node)) {
|
|
7814
7790
|
return false;
|
|
7815
|
-
} else {
|
|
7816
|
-
return !inAccessibilityTree(node);
|
|
7817
7791
|
}
|
|
7792
|
+
return !inAccessibilityTree(node);
|
|
7818
7793
|
}
|
|
7819
7794
|
function hasImgAltText(node, context) {
|
|
7820
7795
|
if (node.is("img")) {
|
|
7821
7796
|
return hasAltText(node);
|
|
7822
|
-
}
|
|
7797
|
+
}
|
|
7798
|
+
if (node.is("svg")) {
|
|
7823
7799
|
return node.textContent.trim() !== "";
|
|
7824
|
-
}
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
}
|
|
7800
|
+
}
|
|
7801
|
+
for (const img of node.querySelectorAll("img, svg")) {
|
|
7802
|
+
const hasName = hasAccessibleNameImpl(img, context);
|
|
7803
|
+
if (hasName) {
|
|
7804
|
+
return true;
|
|
7830
7805
|
}
|
|
7831
|
-
return false;
|
|
7832
7806
|
}
|
|
7807
|
+
return false;
|
|
7833
7808
|
}
|
|
7834
7809
|
function hasLabel(node) {
|
|
7835
7810
|
const value = node.getAttributeValue("aria-label") ?? "";
|
|
@@ -7960,7 +7935,7 @@ class InputMissingLabel extends Rule {
|
|
|
7960
7935
|
this.report(elem, `<${elem.tagName}> element has <label> but <label> element is hidden`);
|
|
7961
7936
|
return;
|
|
7962
7937
|
}
|
|
7963
|
-
if (
|
|
7938
|
+
if (labels.every((label) => !hasAccessibleName(root, label))) {
|
|
7964
7939
|
this.report(elem, `<${elem.tagName}> element has <label> but <label> has no text`);
|
|
7965
7940
|
}
|
|
7966
7941
|
}
|
|
@@ -8147,12 +8122,11 @@ function parseContent(text) {
|
|
|
8147
8122
|
const match = /^(\d+)(?:\s*;\s*url=(.*))?/i.exec(text);
|
|
8148
8123
|
if (match) {
|
|
8149
8124
|
return {
|
|
8150
|
-
delay:
|
|
8125
|
+
delay: Math.trunc(Number(match[1])),
|
|
8151
8126
|
url: match[2]
|
|
8152
8127
|
};
|
|
8153
|
-
} else {
|
|
8154
|
-
return null;
|
|
8155
8128
|
}
|
|
8129
|
+
return null;
|
|
8156
8130
|
}
|
|
8157
8131
|
|
|
8158
8132
|
class MissingDoctype extends Rule {
|
|
@@ -8229,7 +8203,7 @@ class NamePattern extends BasePatternRule {
|
|
|
8229
8203
|
});
|
|
8230
8204
|
}
|
|
8231
8205
|
static schema() {
|
|
8232
|
-
return
|
|
8206
|
+
return super.schema();
|
|
8233
8207
|
}
|
|
8234
8208
|
documentation(context) {
|
|
8235
8209
|
return {
|
|
@@ -8412,10 +8386,10 @@ class NoDeprecatedAttr extends Rule {
|
|
|
8412
8386
|
this.on("attr", (event) => {
|
|
8413
8387
|
const node = event.target;
|
|
8414
8388
|
const meta = node.meta;
|
|
8415
|
-
const attr = event.key.toLowerCase();
|
|
8416
8389
|
if (meta === null) {
|
|
8417
8390
|
return;
|
|
8418
8391
|
}
|
|
8392
|
+
const attr = event.key.toLowerCase();
|
|
8419
8393
|
const metaAttribute = meta.attributes[attr];
|
|
8420
8394
|
if (!metaAttribute) {
|
|
8421
8395
|
return;
|
|
@@ -8449,7 +8423,7 @@ class NoDupAttr extends Rule {
|
|
|
8449
8423
|
return;
|
|
8450
8424
|
}
|
|
8451
8425
|
const name = event.key.toLowerCase();
|
|
8452
|
-
if (name
|
|
8426
|
+
if (Object.hasOwn(attr, name)) {
|
|
8453
8427
|
this.report(event.target, `Attribute "${name}" duplicated`, event.keyLocation);
|
|
8454
8428
|
}
|
|
8455
8429
|
attr[event.key] = true;
|
|
@@ -8522,10 +8496,9 @@ function getExisting(element, root) {
|
|
|
8522
8496
|
const existing = group.cacheGet(CACHE_KEY);
|
|
8523
8497
|
if (existing) {
|
|
8524
8498
|
return existing;
|
|
8525
|
-
} else {
|
|
8526
|
-
const existing2 = /* @__PURE__ */ new Set();
|
|
8527
|
-
return group.cacheSet(CACHE_KEY, existing2);
|
|
8528
8499
|
}
|
|
8500
|
+
const value = /* @__PURE__ */ new Set();
|
|
8501
|
+
return group.cacheSet(CACHE_KEY, value);
|
|
8529
8502
|
}
|
|
8530
8503
|
|
|
8531
8504
|
function isRelevant$2(event) {
|
|
@@ -8796,10 +8769,11 @@ class NoMissingReferences extends Rule {
|
|
|
8796
8769
|
}
|
|
8797
8770
|
}
|
|
8798
8771
|
validateSingle(document, node, attr, id) {
|
|
8799
|
-
if (idMissing(document, id)) {
|
|
8800
|
-
|
|
8801
|
-
this.report(node, `Element references missing id "${id}"`, attr.valueLocation, context);
|
|
8772
|
+
if (!idMissing(document, id)) {
|
|
8773
|
+
return;
|
|
8802
8774
|
}
|
|
8775
|
+
const context = { key: attr.key, value: id };
|
|
8776
|
+
this.report(node, `Element references missing id "${id}"`, attr.valueLocation, context);
|
|
8803
8777
|
}
|
|
8804
8778
|
validateList(document, node, attr, values) {
|
|
8805
8779
|
const parsed = new DOMTokenList(values, attr.valueLocation);
|
|
@@ -8839,9 +8813,9 @@ class NoMultipleMain extends Rule {
|
|
|
8839
8813
|
const defaults$f = {
|
|
8840
8814
|
relaxed: false
|
|
8841
8815
|
};
|
|
8842
|
-
const textRegexp = /(<|&(?![\d#A-
|
|
8843
|
-
const unquotedAttrRegexp = /(["'<=>`]|&(?![\d#A-
|
|
8844
|
-
const matchTemplate = /^(
|
|
8816
|
+
const textRegexp = /(<|&(?![\d#A-Z]+;))/gi;
|
|
8817
|
+
const unquotedAttrRegexp = /(["'<=>`]|&(?![\d#A-Z]+;))/gi;
|
|
8818
|
+
const matchTemplate = /^(?:<%.*?%>|<\?.*?\?>|<\$.*?\$>)$/s;
|
|
8845
8819
|
const replacementTable = {
|
|
8846
8820
|
'"': """,
|
|
8847
8821
|
"&": "&",
|
|
@@ -9073,7 +9047,7 @@ class NoRedundantRole extends Rule {
|
|
|
9073
9047
|
}
|
|
9074
9048
|
}
|
|
9075
9049
|
|
|
9076
|
-
const xmlns = /^
|
|
9050
|
+
const xmlns = /^[^:]+:.+$/;
|
|
9077
9051
|
const defaults$d = {
|
|
9078
9052
|
ignoreForeign: true,
|
|
9079
9053
|
ignoreXML: true
|
|
@@ -9195,11 +9169,11 @@ class NoUnknownAttributes extends Rule {
|
|
|
9195
9169
|
this.on("attr", (event) => {
|
|
9196
9170
|
const node = event.target;
|
|
9197
9171
|
const meta = node.meta;
|
|
9198
|
-
const attr = event.key.toLowerCase();
|
|
9199
9172
|
if (meta === null) {
|
|
9200
9173
|
return;
|
|
9201
9174
|
}
|
|
9202
|
-
|
|
9175
|
+
const attr = event.key.toLowerCase();
|
|
9176
|
+
if (Object.hasOwn(meta.attributes, attr)) {
|
|
9203
9177
|
return;
|
|
9204
9178
|
}
|
|
9205
9179
|
if (isPatternAttribute(attr, meta.patternAttributes)) {
|
|
@@ -9606,7 +9580,7 @@ const defaults$7 = {
|
|
|
9606
9580
|
include: null,
|
|
9607
9581
|
exclude: null
|
|
9608
9582
|
};
|
|
9609
|
-
const crossorigin =
|
|
9583
|
+
const crossorigin = /^(?:\w+:\/\/|\/\/)/;
|
|
9610
9584
|
const supportSri = {
|
|
9611
9585
|
link: "href",
|
|
9612
9586
|
script: "src"
|
|
@@ -9819,7 +9793,10 @@ function constructRegex(characters) {
|
|
|
9819
9793
|
return new RegExp(pattern, "g");
|
|
9820
9794
|
}
|
|
9821
9795
|
function getText(node) {
|
|
9822
|
-
const match = /^(\s*)(.*)$/.exec(node.textContent);
|
|
9796
|
+
const match = /^(\s*)(\S.*)$/.exec(node.textContent);
|
|
9797
|
+
if (!match) {
|
|
9798
|
+
return [0, ""];
|
|
9799
|
+
}
|
|
9823
9800
|
const [, leading, text] = match;
|
|
9824
9801
|
return [leading.length, text.trimEnd()];
|
|
9825
9802
|
}
|
|
@@ -9972,9 +9949,8 @@ function hasDefaultText(node) {
|
|
|
9972
9949
|
function isNonEmptyText(node) {
|
|
9973
9950
|
if (isTextNode(node)) {
|
|
9974
9951
|
return node.isDynamic || node.textContent.trim() !== "";
|
|
9975
|
-
} else {
|
|
9976
|
-
return false;
|
|
9977
9952
|
}
|
|
9953
|
+
return false;
|
|
9978
9954
|
}
|
|
9979
9955
|
function haveAccessibleText(node) {
|
|
9980
9956
|
if (!inAccessibilityTree(node)) {
|
|
@@ -10109,15 +10085,14 @@ function getTextFromReference(document, id) {
|
|
|
10109
10085
|
const ref = document.querySelector(selector);
|
|
10110
10086
|
if (ref) {
|
|
10111
10087
|
return ref.textContent;
|
|
10112
|
-
} else {
|
|
10113
|
-
return selector;
|
|
10114
10088
|
}
|
|
10089
|
+
return selector;
|
|
10115
10090
|
}
|
|
10116
10091
|
function groupBy(values, callback) {
|
|
10117
10092
|
const result = {};
|
|
10118
10093
|
for (const value of values) {
|
|
10119
10094
|
const key = callback(value);
|
|
10120
|
-
if (key
|
|
10095
|
+
if (Object.hasOwn(result, key)) {
|
|
10121
10096
|
result[key].push(value);
|
|
10122
10097
|
} else {
|
|
10123
10098
|
result[key] = [value];
|
|
@@ -10217,7 +10192,7 @@ const defaults$5 = {
|
|
|
10217
10192
|
ignoreCase: false,
|
|
10218
10193
|
requireSemicolon: true
|
|
10219
10194
|
};
|
|
10220
|
-
const regexp$1 = /&(?:[\da-z]+|#x?[\da-f]+)(
|
|
10195
|
+
const regexp$1 = /&(?:[\da-z]+|#x?[\da-f]+)([^\da-z]|$)/gi;
|
|
10221
10196
|
const lowercaseEntities = entities$1.map((it) => it.toLowerCase());
|
|
10222
10197
|
function isNumerical(entity) {
|
|
10223
10198
|
return entity.startsWith("&#");
|
|
@@ -10296,9 +10271,8 @@ class UnknownCharReference extends Rule {
|
|
|
10296
10271
|
get entities() {
|
|
10297
10272
|
if (this.options.ignoreCase) {
|
|
10298
10273
|
return lowercaseEntities;
|
|
10299
|
-
} else {
|
|
10300
|
-
return entities$1;
|
|
10301
10274
|
}
|
|
10275
|
+
return entities$1;
|
|
10302
10276
|
}
|
|
10303
10277
|
findCharacterReferences(node, text, location, { isAttribute }) {
|
|
10304
10278
|
const delimiter = text.search(/[#?]/);
|
|
@@ -10664,7 +10638,6 @@ class ValidAutocomplete extends Rule {
|
|
|
10664
10638
|
}
|
|
10665
10639
|
validateControlAutocomplete(node, tokens, keyLocation) {
|
|
10666
10640
|
const type = node.getAttributeValue("type") ?? "text";
|
|
10667
|
-
const mantle = type !== "hidden" ? "expectation" : "anchor";
|
|
10668
10641
|
if (isDisallowedType(node, type)) {
|
|
10669
10642
|
const context = {
|
|
10670
10643
|
msg: 0 /* InvalidAttribute */,
|
|
@@ -10679,6 +10652,7 @@ class ValidAutocomplete extends Rule {
|
|
|
10679
10652
|
return;
|
|
10680
10653
|
}
|
|
10681
10654
|
if (tokens.includes("on") || tokens.includes("off")) {
|
|
10655
|
+
const mantle = type !== "hidden" ? "expectation" : "anchor";
|
|
10682
10656
|
this.validateOnOff(node, mantle, tokens);
|
|
10683
10657
|
return;
|
|
10684
10658
|
}
|
|
@@ -10802,44 +10776,46 @@ class ValidAutocomplete extends Rule {
|
|
|
10802
10776
|
* Ensure contact token is only used with field names from the second list.
|
|
10803
10777
|
*/
|
|
10804
10778
|
validateContact(node, tokens, order) {
|
|
10805
|
-
if (order.includes("contact")
|
|
10806
|
-
|
|
10807
|
-
|
|
10779
|
+
if (!order.includes("contact") || !order.includes("field1")) {
|
|
10780
|
+
return;
|
|
10781
|
+
}
|
|
10782
|
+
const a = order.indexOf("field1");
|
|
10783
|
+
const b = order.indexOf("contact");
|
|
10784
|
+
const context = {
|
|
10785
|
+
msg: 4 /* InvalidCombination */,
|
|
10786
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion -- it must be present of it wouldn't be found */
|
|
10787
|
+
first: tokens.item(a),
|
|
10788
|
+
second: tokens.item(b)
|
|
10789
|
+
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
10790
|
+
};
|
|
10791
|
+
this.report({
|
|
10792
|
+
node,
|
|
10793
|
+
message: getTerminalMessage(context),
|
|
10794
|
+
location: tokens.location(b),
|
|
10795
|
+
context
|
|
10796
|
+
});
|
|
10797
|
+
}
|
|
10798
|
+
validateOrder(node, tokens, order) {
|
|
10799
|
+
const indicies = order.map((it) => expectedOrder.indexOf(it));
|
|
10800
|
+
for (let i = 0; i < indicies.length - 1; i++) {
|
|
10801
|
+
if (indicies[0] <= indicies[i + 1]) {
|
|
10802
|
+
continue;
|
|
10803
|
+
}
|
|
10808
10804
|
const context = {
|
|
10809
|
-
msg:
|
|
10805
|
+
msg: 2 /* InvalidOrder */,
|
|
10810
10806
|
/* eslint-disable @typescript-eslint/no-non-null-assertion -- it must be present of it wouldn't be found */
|
|
10811
|
-
first: tokens.item(
|
|
10812
|
-
second: tokens.item(
|
|
10807
|
+
first: tokens.item(i),
|
|
10808
|
+
second: tokens.item(i + 1)
|
|
10813
10809
|
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
10814
10810
|
};
|
|
10815
10811
|
this.report({
|
|
10816
10812
|
node,
|
|
10817
10813
|
message: getTerminalMessage(context),
|
|
10818
|
-
location: tokens.location(
|
|
10814
|
+
location: tokens.location(i + 1),
|
|
10819
10815
|
context
|
|
10820
10816
|
});
|
|
10821
10817
|
}
|
|
10822
10818
|
}
|
|
10823
|
-
validateOrder(node, tokens, order) {
|
|
10824
|
-
const indicies = order.map((it) => expectedOrder.indexOf(it));
|
|
10825
|
-
for (let i = 0; i < indicies.length - 1; i++) {
|
|
10826
|
-
if (indicies[0] > indicies[i + 1]) {
|
|
10827
|
-
const context = {
|
|
10828
|
-
msg: 2 /* InvalidOrder */,
|
|
10829
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion -- it must be present of it wouldn't be found */
|
|
10830
|
-
first: tokens.item(i),
|
|
10831
|
-
second: tokens.item(i + 1)
|
|
10832
|
-
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
10833
|
-
};
|
|
10834
|
-
this.report({
|
|
10835
|
-
node,
|
|
10836
|
-
message: getTerminalMessage(context),
|
|
10837
|
-
location: tokens.location(i + 1),
|
|
10838
|
-
context
|
|
10839
|
-
});
|
|
10840
|
-
}
|
|
10841
|
-
}
|
|
10842
|
-
}
|
|
10843
10819
|
validateControlGroup(node, tokens, fieldTokens) {
|
|
10844
10820
|
const numFields = fieldTokens.filter(Boolean).length;
|
|
10845
10821
|
if (numFields === 0) {
|
|
@@ -10931,7 +10907,7 @@ class ValidID extends Rule {
|
|
|
10931
10907
|
documentation(context) {
|
|
10932
10908
|
const { relaxed } = this.options;
|
|
10933
10909
|
const { kind, id } = context;
|
|
10934
|
-
const message = this.messages[kind].replace(`"{{ id }}"`, "`{{ id }}`").replace("id", "ID").replace(
|
|
10910
|
+
const message = this.messages[kind].replace(`"{{ id }}"`, "`{{ id }}`").replace("id", "ID").replace(/^./, (m) => m.toUpperCase());
|
|
10935
10911
|
const relaxedDescription = relaxed ? [] : [
|
|
10936
10912
|
" - ID must begin with a letter",
|
|
10937
10913
|
" - ID must only contain letters, digits, `-` and `_`"
|
|
@@ -10969,7 +10945,7 @@ class ValidID extends Rule {
|
|
|
10969
10945
|
if (relaxed) {
|
|
10970
10946
|
return;
|
|
10971
10947
|
}
|
|
10972
|
-
if (
|
|
10948
|
+
if (new RegExp("^\\P{L}", "u").test(value)) {
|
|
10973
10949
|
const context = { kind: 3 /* LEADING_CHARACTER */, id: value };
|
|
10974
10950
|
this.report(event.target, this.messages[context.kind], event.valueLocation, context);
|
|
10975
10951
|
return;
|
|
@@ -11330,7 +11306,7 @@ function isSimpleTable(table) {
|
|
|
11330
11306
|
return false;
|
|
11331
11307
|
}
|
|
11332
11308
|
const numColumns = cells[0].length;
|
|
11333
|
-
if (
|
|
11309
|
+
if (cells.some((row) => row.length !== numColumns)) {
|
|
11334
11310
|
return false;
|
|
11335
11311
|
}
|
|
11336
11312
|
const shape = getShape(cells);
|
|
@@ -11984,7 +11960,7 @@ class ResolvedConfig {
|
|
|
11984
11960
|
}
|
|
11985
11961
|
|
|
11986
11962
|
function haveResolver(key, value) {
|
|
11987
|
-
return key
|
|
11963
|
+
return Object.hasOwn(value, key);
|
|
11988
11964
|
}
|
|
11989
11965
|
function haveConfigResolver(value) {
|
|
11990
11966
|
return haveResolver("resolveConfig", value);
|
|
@@ -11999,7 +11975,10 @@ function haveTransformerResolver(value) {
|
|
|
11999
11975
|
return haveResolver("resolveTransformer", value);
|
|
12000
11976
|
}
|
|
12001
11977
|
function resolveConfig(resolvers, id, options) {
|
|
12002
|
-
for (const resolver of resolvers
|
|
11978
|
+
for (const resolver of resolvers) {
|
|
11979
|
+
if (!haveConfigResolver(resolver)) {
|
|
11980
|
+
continue;
|
|
11981
|
+
}
|
|
12003
11982
|
const config = resolver.resolveConfig(id, options);
|
|
12004
11983
|
if (isThenable(config)) {
|
|
12005
11984
|
return resolveConfigAsync(resolvers, id, options);
|
|
@@ -12011,7 +11990,10 @@ function resolveConfig(resolvers, id, options) {
|
|
|
12011
11990
|
throw new UserError(`Failed to load configuration from "${id}"`);
|
|
12012
11991
|
}
|
|
12013
11992
|
async function resolveConfigAsync(resolvers, id, options) {
|
|
12014
|
-
for (const resolver of resolvers
|
|
11993
|
+
for (const resolver of resolvers) {
|
|
11994
|
+
if (!haveConfigResolver(resolver)) {
|
|
11995
|
+
continue;
|
|
11996
|
+
}
|
|
12015
11997
|
const config = await resolver.resolveConfig(id, options);
|
|
12016
11998
|
if (config) {
|
|
12017
11999
|
return config;
|
|
@@ -12020,7 +12002,10 @@ async function resolveConfigAsync(resolvers, id, options) {
|
|
|
12020
12002
|
throw new UserError(`Failed to load configuration from "${id}"`);
|
|
12021
12003
|
}
|
|
12022
12004
|
function resolveElements(resolvers, id, options) {
|
|
12023
|
-
for (const resolver of resolvers
|
|
12005
|
+
for (const resolver of resolvers) {
|
|
12006
|
+
if (!haveElementsResolver(resolver)) {
|
|
12007
|
+
continue;
|
|
12008
|
+
}
|
|
12024
12009
|
const elements = resolver.resolveElements(id, options);
|
|
12025
12010
|
if (isThenable(elements)) {
|
|
12026
12011
|
return resolveElementsAsync(resolvers, id, options);
|
|
@@ -12032,7 +12017,10 @@ function resolveElements(resolvers, id, options) {
|
|
|
12032
12017
|
throw new UserError(`Failed to load elements from "${id}"`);
|
|
12033
12018
|
}
|
|
12034
12019
|
async function resolveElementsAsync(resolvers, id, options) {
|
|
12035
|
-
for (const resolver of resolvers
|
|
12020
|
+
for (const resolver of resolvers) {
|
|
12021
|
+
if (!haveElementsResolver(resolver)) {
|
|
12022
|
+
continue;
|
|
12023
|
+
}
|
|
12036
12024
|
const elements = await resolver.resolveElements(id, options);
|
|
12037
12025
|
if (elements) {
|
|
12038
12026
|
return elements;
|
|
@@ -12041,7 +12029,10 @@ async function resolveElementsAsync(resolvers, id, options) {
|
|
|
12041
12029
|
throw new UserError(`Failed to load elements from "${id}"`);
|
|
12042
12030
|
}
|
|
12043
12031
|
function resolvePlugin(resolvers, id, options) {
|
|
12044
|
-
for (const resolver of resolvers
|
|
12032
|
+
for (const resolver of resolvers) {
|
|
12033
|
+
if (!havePluginResolver(resolver)) {
|
|
12034
|
+
continue;
|
|
12035
|
+
}
|
|
12045
12036
|
const plugin = resolver.resolvePlugin(id, options);
|
|
12046
12037
|
if (isThenable(plugin)) {
|
|
12047
12038
|
return resolvePluginAsync(resolvers, id, options);
|
|
@@ -12053,7 +12044,10 @@ function resolvePlugin(resolvers, id, options) {
|
|
|
12053
12044
|
throw new UserError(`Failed to load plugin from "${id}"`);
|
|
12054
12045
|
}
|
|
12055
12046
|
async function resolvePluginAsync(resolvers, id, options) {
|
|
12056
|
-
for (const resolver of resolvers
|
|
12047
|
+
for (const resolver of resolvers) {
|
|
12048
|
+
if (!havePluginResolver(resolver)) {
|
|
12049
|
+
continue;
|
|
12050
|
+
}
|
|
12057
12051
|
const plugin = await resolver.resolvePlugin(id, options);
|
|
12058
12052
|
if (plugin) {
|
|
12059
12053
|
return plugin;
|
|
@@ -12062,7 +12056,10 @@ async function resolvePluginAsync(resolvers, id, options) {
|
|
|
12062
12056
|
throw new UserError(`Failed to load plugin from "${id}"`);
|
|
12063
12057
|
}
|
|
12064
12058
|
function resolveTransformer(resolvers, id, options) {
|
|
12065
|
-
for (const resolver of resolvers
|
|
12059
|
+
for (const resolver of resolvers) {
|
|
12060
|
+
if (!haveTransformerResolver(resolver)) {
|
|
12061
|
+
continue;
|
|
12062
|
+
}
|
|
12066
12063
|
const transformer = resolver.resolveTransformer(id, options);
|
|
12067
12064
|
if (isThenable(transformer)) {
|
|
12068
12065
|
return resolveTransformerAsync(resolvers, id, options);
|
|
@@ -12074,7 +12071,10 @@ function resolveTransformer(resolvers, id, options) {
|
|
|
12074
12071
|
throw new UserError(`Failed to load transformer from "${id}"`);
|
|
12075
12072
|
}
|
|
12076
12073
|
async function resolveTransformerAsync(resolvers, id, options) {
|
|
12077
|
-
for (const resolver of resolvers
|
|
12074
|
+
for (const resolver of resolvers) {
|
|
12075
|
+
if (!haveTransformerResolver(resolver)) {
|
|
12076
|
+
continue;
|
|
12077
|
+
}
|
|
12078
12078
|
const transformer = await resolver.resolveTransformer(id, options);
|
|
12079
12079
|
if (transformer) {
|
|
12080
12080
|
return transformer;
|
|
@@ -12114,9 +12114,12 @@ function staticResolver(map = {}) {
|
|
|
12114
12114
|
};
|
|
12115
12115
|
}
|
|
12116
12116
|
|
|
12117
|
-
const ajv =
|
|
12118
|
-
|
|
12119
|
-
|
|
12117
|
+
const ajv = (() => {
|
|
12118
|
+
const ajv2 = new Ajv({ strict: true, strictTuples: true, strictTypes: true });
|
|
12119
|
+
ajv2.addMetaSchema(ajvSchemaDraft);
|
|
12120
|
+
ajv2.addKeyword(ajvFunctionKeyword);
|
|
12121
|
+
return ajv2;
|
|
12122
|
+
})();
|
|
12120
12123
|
const validator = ajv.compile(configurationSchema);
|
|
12121
12124
|
function overwriteMerge(_a, b) {
|
|
12122
12125
|
return b;
|
|
@@ -12135,18 +12138,16 @@ function mergeInternal(base, rhs) {
|
|
|
12135
12138
|
function toArray$1(value) {
|
|
12136
12139
|
if (Array.isArray(value)) {
|
|
12137
12140
|
return value;
|
|
12138
|
-
} else {
|
|
12139
|
-
return [value];
|
|
12140
12141
|
}
|
|
12142
|
+
return [value];
|
|
12141
12143
|
}
|
|
12142
12144
|
function transformerEntries(transform) {
|
|
12143
12145
|
return Object.entries(transform).map(([pattern, value]) => {
|
|
12144
12146
|
const regex = new RegExp(pattern);
|
|
12145
12147
|
if (typeof value === "string") {
|
|
12146
12148
|
return { kind: "import", pattern: regex, name: value };
|
|
12147
|
-
} else {
|
|
12148
|
-
return { kind: "function", pattern: regex, function: value };
|
|
12149
12149
|
}
|
|
12150
|
+
return { kind: "function", pattern: regex, function: value };
|
|
12150
12151
|
});
|
|
12151
12152
|
}
|
|
12152
12153
|
class Config {
|
|
@@ -12171,8 +12172,8 @@ class Config {
|
|
|
12171
12172
|
* Create configuration from object.
|
|
12172
12173
|
*/
|
|
12173
12174
|
static fromObject(resolvers, options, filename = null) {
|
|
12174
|
-
|
|
12175
|
-
return
|
|
12175
|
+
this.validate(options, filename);
|
|
12176
|
+
return this.create(resolvers, options);
|
|
12176
12177
|
}
|
|
12177
12178
|
/**
|
|
12178
12179
|
* Read configuration from filename.
|
|
@@ -12186,10 +12187,9 @@ class Config {
|
|
|
12186
12187
|
static fromFile(resolvers, filename) {
|
|
12187
12188
|
const configData = resolveConfig(toArray$1(resolvers), filename, { cache: false });
|
|
12188
12189
|
if (isThenable(configData)) {
|
|
12189
|
-
return configData.then((configData2) =>
|
|
12190
|
-
} else {
|
|
12191
|
-
return Config.fromObject(resolvers, configData, filename);
|
|
12190
|
+
return configData.then((configData2) => this.fromObject(resolvers, configData2, filename));
|
|
12192
12191
|
}
|
|
12192
|
+
return this.fromObject(resolvers, configData, filename);
|
|
12193
12193
|
}
|
|
12194
12194
|
/**
|
|
12195
12195
|
* Validate configuration data.
|
|
@@ -12211,8 +12211,8 @@ class Config {
|
|
|
12211
12211
|
);
|
|
12212
12212
|
}
|
|
12213
12213
|
if (configData.rules) {
|
|
12214
|
-
const normalizedRules =
|
|
12215
|
-
for (const [ruleId, [, ruleOptions]] of normalizedRules
|
|
12214
|
+
const normalizedRules = this.getRulesObject(configData.rules);
|
|
12215
|
+
for (const [ruleId, [, ruleOptions]] of normalizedRules) {
|
|
12216
12216
|
const cls = bundledRules[ruleId];
|
|
12217
12217
|
const path = `/rules/${ruleId}/1`;
|
|
12218
12218
|
Rule.validateOptions(cls, ruleId, path, ruleOptions, filename, configData);
|
|
@@ -12235,9 +12235,8 @@ class Config {
|
|
|
12235
12235
|
return plugins.then((plugins2) => {
|
|
12236
12236
|
return instance.init(options, plugins2);
|
|
12237
12237
|
});
|
|
12238
|
-
} else {
|
|
12239
|
-
return instance.init(options, plugins);
|
|
12240
12238
|
}
|
|
12239
|
+
return instance.init(options, plugins);
|
|
12241
12240
|
}
|
|
12242
12241
|
init(options, plugins) {
|
|
12243
12242
|
this.plugins = plugins;
|
|
@@ -12254,9 +12253,8 @@ class Config {
|
|
|
12254
12253
|
const extendedConfig = this.extendConfig(this.config.extends ?? []);
|
|
12255
12254
|
if (isThenable(extendedConfig)) {
|
|
12256
12255
|
return extendedConfig.then((extended) => update(extended));
|
|
12257
|
-
} else {
|
|
12258
|
-
return update(extendedConfig);
|
|
12259
12256
|
}
|
|
12257
|
+
return update(extendedConfig);
|
|
12260
12258
|
}
|
|
12261
12259
|
/**
|
|
12262
12260
|
* @internal
|
|
@@ -12298,12 +12296,11 @@ class Config {
|
|
|
12298
12296
|
instance.extendMeta(instance.plugins);
|
|
12299
12297
|
return instance;
|
|
12300
12298
|
});
|
|
12301
|
-
} else {
|
|
12302
|
-
instance.plugins = plugins;
|
|
12303
|
-
instance.configurations = instance.loadConfigurations(instance.plugins);
|
|
12304
|
-
instance.extendMeta(instance.plugins);
|
|
12305
|
-
return instance;
|
|
12306
12299
|
}
|
|
12300
|
+
instance.plugins = plugins;
|
|
12301
|
+
instance.configurations = instance.loadConfigurations(instance.plugins);
|
|
12302
|
+
instance.extendMeta(instance.plugins);
|
|
12303
|
+
return instance;
|
|
12307
12304
|
}
|
|
12308
12305
|
extendConfig(entries) {
|
|
12309
12306
|
if (entries.length === 0) {
|
|
@@ -12359,20 +12356,19 @@ class Config {
|
|
|
12359
12356
|
const result = this.getElementsFromEntry(entry);
|
|
12360
12357
|
if (isThenable(result)) {
|
|
12361
12358
|
return result.then((result2) => {
|
|
12362
|
-
const [
|
|
12363
|
-
metaTable.loadFromObject(
|
|
12364
|
-
const
|
|
12365
|
-
if (
|
|
12366
|
-
return loadEntry(
|
|
12359
|
+
const [obj2, filename2] = result2;
|
|
12360
|
+
metaTable.loadFromObject(obj2, filename2);
|
|
12361
|
+
const next3 = source.shift();
|
|
12362
|
+
if (next3) {
|
|
12363
|
+
return loadEntry(next3);
|
|
12367
12364
|
}
|
|
12368
12365
|
});
|
|
12369
|
-
}
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12375
|
-
}
|
|
12366
|
+
}
|
|
12367
|
+
const [obj, filename] = result;
|
|
12368
|
+
metaTable.loadFromObject(obj, filename);
|
|
12369
|
+
const next2 = source.shift();
|
|
12370
|
+
if (next2) {
|
|
12371
|
+
return loadEntry(next2);
|
|
12376
12372
|
}
|
|
12377
12373
|
};
|
|
12378
12374
|
const next = source.shift();
|
|
@@ -12402,9 +12398,8 @@ class Config {
|
|
|
12402
12398
|
return obj.then((obj2) => {
|
|
12403
12399
|
return [obj2, entry];
|
|
12404
12400
|
});
|
|
12405
|
-
} else {
|
|
12406
|
-
return [obj, entry];
|
|
12407
12401
|
}
|
|
12402
|
+
return [obj, entry];
|
|
12408
12403
|
} catch (err) {
|
|
12409
12404
|
const message = err instanceof Error ? err.message : String(err);
|
|
12410
12405
|
throw new ConfigError(
|
|
@@ -12466,7 +12461,7 @@ class Config {
|
|
|
12466
12461
|
const loadPlugin = (entry, index) => {
|
|
12467
12462
|
if (typeof entry !== "string") {
|
|
12468
12463
|
const plugin = entry;
|
|
12469
|
-
plugin.name
|
|
12464
|
+
plugin.name ||= `:unnamedPlugin@${String(index + 1)}`;
|
|
12470
12465
|
plugin.originalName = `:unnamedPlugin@${String(index + 1)}`;
|
|
12471
12466
|
loaded.push(plugin);
|
|
12472
12467
|
const next2 = loading.shift();
|
|
@@ -12478,22 +12473,21 @@ class Config {
|
|
|
12478
12473
|
const plugin = resolvePlugin(this.resolvers, entry, { cache: true });
|
|
12479
12474
|
if (isThenable(plugin)) {
|
|
12480
12475
|
return plugin.then((plugin2) => {
|
|
12481
|
-
plugin2.name
|
|
12476
|
+
plugin2.name ||= entry;
|
|
12482
12477
|
plugin2.originalName = entry;
|
|
12483
12478
|
loaded.push(plugin2);
|
|
12484
|
-
const
|
|
12485
|
-
if (
|
|
12486
|
-
return loadPlugin(
|
|
12479
|
+
const next3 = loading.shift();
|
|
12480
|
+
if (next3) {
|
|
12481
|
+
return loadPlugin(next3, index + 1);
|
|
12487
12482
|
}
|
|
12488
12483
|
});
|
|
12489
|
-
}
|
|
12490
|
-
|
|
12491
|
-
|
|
12492
|
-
|
|
12493
|
-
|
|
12494
|
-
|
|
12495
|
-
|
|
12496
|
-
}
|
|
12484
|
+
}
|
|
12485
|
+
plugin.name ||= entry;
|
|
12486
|
+
plugin.originalName = entry;
|
|
12487
|
+
loaded.push(plugin);
|
|
12488
|
+
const next2 = loading.shift();
|
|
12489
|
+
if (next2) {
|
|
12490
|
+
return loadPlugin(next2, index + 1);
|
|
12497
12491
|
}
|
|
12498
12492
|
} catch (err) {
|
|
12499
12493
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -12519,7 +12513,8 @@ class Config {
|
|
|
12519
12513
|
configs.set(name, config);
|
|
12520
12514
|
}
|
|
12521
12515
|
for (const plugin of plugins) {
|
|
12522
|
-
|
|
12516
|
+
const entries = Object.entries(plugin.configs ?? {});
|
|
12517
|
+
for (const [name, config] of entries) {
|
|
12523
12518
|
if (!config) {
|
|
12524
12519
|
continue;
|
|
12525
12520
|
}
|
|
@@ -12563,9 +12558,8 @@ class Config {
|
|
|
12563
12558
|
return resolveData.then((resolveData2) => {
|
|
12564
12559
|
return new ResolvedConfig(resolveData2, this.get());
|
|
12565
12560
|
});
|
|
12566
|
-
} else {
|
|
12567
|
-
return new ResolvedConfig(resolveData, this.get());
|
|
12568
12561
|
}
|
|
12562
|
+
return new ResolvedConfig(resolveData, this.get());
|
|
12569
12563
|
}
|
|
12570
12564
|
/**
|
|
12571
12565
|
* Same as [[resolve]] but returns the raw configuration data instead of
|
|
@@ -12584,14 +12578,13 @@ class Config {
|
|
|
12584
12578
|
transformers: this.transformers
|
|
12585
12579
|
};
|
|
12586
12580
|
});
|
|
12587
|
-
} else {
|
|
12588
|
-
return {
|
|
12589
|
-
metaTable,
|
|
12590
|
-
plugins: this.getPlugins(),
|
|
12591
|
-
rules: this.getRules(),
|
|
12592
|
-
transformers: this.transformers
|
|
12593
|
-
};
|
|
12594
12581
|
}
|
|
12582
|
+
return {
|
|
12583
|
+
metaTable,
|
|
12584
|
+
plugins: this.getPlugins(),
|
|
12585
|
+
rules: this.getRules(),
|
|
12586
|
+
transformers: this.transformers
|
|
12587
|
+
};
|
|
12595
12588
|
}
|
|
12596
12589
|
}
|
|
12597
12590
|
|
|
@@ -12635,10 +12628,9 @@ class ConfigLoader {
|
|
|
12635
12628
|
this._globalConfig = config2;
|
|
12636
12629
|
return this._globalConfig;
|
|
12637
12630
|
});
|
|
12638
|
-
} else {
|
|
12639
|
-
this._globalConfig = config;
|
|
12640
|
-
return this._globalConfig;
|
|
12641
12631
|
}
|
|
12632
|
+
this._globalConfig = config;
|
|
12633
|
+
return this._globalConfig;
|
|
12642
12634
|
}
|
|
12643
12635
|
/**
|
|
12644
12636
|
* Get the global configuration.
|
|
@@ -12720,9 +12712,8 @@ class StaticConfigLoader extends ConfigLoader {
|
|
|
12720
12712
|
const override = this.loadFromObject(configOverride ?? {});
|
|
12721
12713
|
if (isThenable(override)) {
|
|
12722
12714
|
return override.then((override2) => this._resolveConfig(override2));
|
|
12723
|
-
} else {
|
|
12724
|
-
return this._resolveConfig(override);
|
|
12725
12715
|
}
|
|
12716
|
+
return this._resolveConfig(override);
|
|
12726
12717
|
}
|
|
12727
12718
|
flushCache() {
|
|
12728
12719
|
}
|
|
@@ -12739,25 +12730,22 @@ class StaticConfigLoader extends ConfigLoader {
|
|
|
12739
12730
|
const globalConfig = this.getGlobalConfig();
|
|
12740
12731
|
if (isThenable(globalConfig)) {
|
|
12741
12732
|
return globalConfig.then((globalConfig2) => {
|
|
12742
|
-
const
|
|
12743
|
-
if (isThenable(
|
|
12744
|
-
return
|
|
12745
|
-
return
|
|
12733
|
+
const merged2 = globalConfig2.merge(this.resolvers, override);
|
|
12734
|
+
if (isThenable(merged2)) {
|
|
12735
|
+
return merged2.then((merged3) => {
|
|
12736
|
+
return merged3.resolve();
|
|
12746
12737
|
});
|
|
12747
|
-
} else {
|
|
12748
|
-
return merged.resolve();
|
|
12749
12738
|
}
|
|
12739
|
+
return merged2.resolve();
|
|
12740
|
+
});
|
|
12741
|
+
}
|
|
12742
|
+
const merged = globalConfig.merge(this.resolvers, override);
|
|
12743
|
+
if (isThenable(merged)) {
|
|
12744
|
+
return merged.then((merged2) => {
|
|
12745
|
+
return merged2.resolve();
|
|
12750
12746
|
});
|
|
12751
|
-
} else {
|
|
12752
|
-
const merged = globalConfig.merge(this.resolvers, override);
|
|
12753
|
-
if (isThenable(merged)) {
|
|
12754
|
-
return merged.then((merged2) => {
|
|
12755
|
-
return merged2.resolve();
|
|
12756
|
-
});
|
|
12757
|
-
} else {
|
|
12758
|
-
return merged.resolve();
|
|
12759
|
-
}
|
|
12760
12747
|
}
|
|
12748
|
+
return merged.resolve();
|
|
12761
12749
|
}
|
|
12762
12750
|
}
|
|
12763
12751
|
|
|
@@ -12844,7 +12832,7 @@ class EventHandler {
|
|
|
12844
12832
|
}
|
|
12845
12833
|
|
|
12846
12834
|
const name = "html-validate";
|
|
12847
|
-
const version = "11.5.
|
|
12835
|
+
const version = "11.5.4";
|
|
12848
12836
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
12849
12837
|
|
|
12850
12838
|
function freeze(src) {
|
|
@@ -12882,7 +12870,7 @@ class Reporter {
|
|
|
12882
12870
|
for (const report of reports) {
|
|
12883
12871
|
for (const result of report.results) {
|
|
12884
12872
|
const key = result.filePath;
|
|
12885
|
-
if (key
|
|
12873
|
+
if (Object.hasOwn(merged, key)) {
|
|
12886
12874
|
merged[key].messages = [...merged[key].messages, ...result.messages];
|
|
12887
12875
|
} else {
|
|
12888
12876
|
merged[key] = { ...result };
|
|
@@ -12906,7 +12894,7 @@ class Reporter {
|
|
|
12906
12894
|
*/
|
|
12907
12895
|
add(options) {
|
|
12908
12896
|
const { rule, message, severity, node, location, context } = options;
|
|
12909
|
-
if (!(location.filename
|
|
12897
|
+
if (!Object.hasOwn(this.result, location.filename)) {
|
|
12910
12898
|
this.result[location.filename] = [];
|
|
12911
12899
|
}
|
|
12912
12900
|
const ruleUrl = rule.documentation(context)?.url;
|
|
@@ -12934,7 +12922,7 @@ class Reporter {
|
|
|
12934
12922
|
* @internal
|
|
12935
12923
|
*/
|
|
12936
12924
|
addManual(filename, message) {
|
|
12937
|
-
if (!(
|
|
12925
|
+
if (!Object.hasOwn(this.result, filename)) {
|
|
12938
12926
|
this.result[filename] = [];
|
|
12939
12927
|
}
|
|
12940
12928
|
this.result[filename].push(message);
|
|
@@ -12945,6 +12933,7 @@ class Reporter {
|
|
|
12945
12933
|
save(sources) {
|
|
12946
12934
|
const report = {
|
|
12947
12935
|
valid: this.isValid(),
|
|
12936
|
+
/* eslint-disable-next-line unicorn/prefer-object-iterable-methods -- technical debt */
|
|
12948
12937
|
results: Object.keys(this.result).map((filePath) => {
|
|
12949
12938
|
const messages = Array.from(this.result[filePath], freeze).toSorted(messageSort);
|
|
12950
12939
|
const source = (sources ?? []).find((source2) => filePath === source2.filename);
|
|
@@ -13009,7 +12998,7 @@ function definePlugin(plugin) {
|
|
|
13009
12998
|
return plugin;
|
|
13010
12999
|
}
|
|
13011
13000
|
|
|
13012
|
-
const regexp = /<!(?:--)?\[(.*?)](?:--)?>/g;
|
|
13001
|
+
const regexp = /<!(?:--)?\[(.*?)\](?:--)?>/g;
|
|
13013
13002
|
function* parseConditionalComment(comment, commentLocation) {
|
|
13014
13003
|
let match;
|
|
13015
13004
|
while ((match = regexp.exec(comment)) !== null) {
|
|
@@ -13026,6 +13015,7 @@ function* parseConditionalComment(comment, commentLocation) {
|
|
|
13026
13015
|
|
|
13027
13016
|
class ParserError extends Error {
|
|
13028
13017
|
location;
|
|
13018
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
13029
13019
|
constructor(location, message) {
|
|
13030
13020
|
super(message);
|
|
13031
13021
|
this.name = "ParserError";
|
|
@@ -13189,9 +13179,8 @@ class Parser {
|
|
|
13189
13179
|
const open = !token.data[1];
|
|
13190
13180
|
if (open) {
|
|
13191
13181
|
return this.wouldCloseElement(token, active);
|
|
13192
|
-
} else {
|
|
13193
|
-
return this.closeOptionalEndTag(token, active);
|
|
13194
13182
|
}
|
|
13183
|
+
return this.closeOptionalEndTag(token, active);
|
|
13195
13184
|
}
|
|
13196
13185
|
/**
|
|
13197
13186
|
* Returns `true` if the element’s end tag may be omitted, either because
|
|
@@ -13543,9 +13532,8 @@ class Parser {
|
|
|
13543
13532
|
const quote = token.data[3];
|
|
13544
13533
|
if (quote) {
|
|
13545
13534
|
return sliceLocation(token.location, 2, -1);
|
|
13546
|
-
} else {
|
|
13547
|
-
return sliceLocation(token.location, 1);
|
|
13548
13535
|
}
|
|
13536
|
+
return sliceLocation(token.location, 1);
|
|
13549
13537
|
}
|
|
13550
13538
|
/**
|
|
13551
13539
|
* Take attribute key and value token an returns a new location referring to
|
|
@@ -13833,13 +13821,14 @@ class PerformanceTracker {
|
|
|
13833
13821
|
*/
|
|
13834
13822
|
getResult() {
|
|
13835
13823
|
const events = Array.from(
|
|
13836
|
-
this.eventData
|
|
13824
|
+
this.eventData,
|
|
13837
13825
|
([event, { count, time }]) => ({ event, count, time })
|
|
13838
13826
|
).toSorted((a, b) => b.time - a.time);
|
|
13839
|
-
const rules = Array.from(
|
|
13840
|
-
|
|
13841
|
-
|
|
13842
|
-
|
|
13827
|
+
const rules = Array.from(this.ruleData, ([rule, { count, time }]) => ({
|
|
13828
|
+
rule,
|
|
13829
|
+
count,
|
|
13830
|
+
time
|
|
13831
|
+
})).toSorted((a, b) => b.time - a.time);
|
|
13843
13832
|
return {
|
|
13844
13833
|
events,
|
|
13845
13834
|
rules,
|
|
@@ -13886,9 +13875,11 @@ function dumpTree(root) {
|
|
|
13886
13875
|
return lines;
|
|
13887
13876
|
}
|
|
13888
13877
|
|
|
13889
|
-
|
|
13878
|
+
const state = {
|
|
13879
|
+
blockerCounter: 1
|
|
13880
|
+
};
|
|
13890
13881
|
function createBlocker() {
|
|
13891
|
-
const id = blockerCounter++;
|
|
13882
|
+
const id = state.blockerCounter++;
|
|
13892
13883
|
return id;
|
|
13893
13884
|
}
|
|
13894
13885
|
|
|
@@ -14024,9 +14015,8 @@ class Engine {
|
|
|
14024
14015
|
const [, options] = ruleData;
|
|
14025
14016
|
const rule = this.instantiateRule(ruleId, options);
|
|
14026
14017
|
return rule.documentation(context);
|
|
14027
|
-
} else {
|
|
14028
|
-
return null;
|
|
14029
14018
|
}
|
|
14019
|
+
return null;
|
|
14030
14020
|
}
|
|
14031
14021
|
/**
|
|
14032
14022
|
* Create a new parser instance with the current configuration.
|
|
@@ -14155,7 +14145,8 @@ class Engine {
|
|
|
14155
14145
|
initRules(config) {
|
|
14156
14146
|
const availableRules = {};
|
|
14157
14147
|
for (const plugin of config.getPlugins()) {
|
|
14158
|
-
|
|
14148
|
+
const entries = Object.entries(plugin.rules ?? {});
|
|
14149
|
+
for (const [name, rule] of entries) {
|
|
14159
14150
|
if (!rule) {
|
|
14160
14151
|
continue;
|
|
14161
14152
|
}
|
|
@@ -14183,7 +14174,7 @@ class Engine {
|
|
|
14183
14174
|
*/
|
|
14184
14175
|
setupRules(config, parser) {
|
|
14185
14176
|
const rules = {};
|
|
14186
|
-
for (const [ruleId, [severity, options]] of config.getRules()
|
|
14177
|
+
for (const [ruleId, [severity, options]] of config.getRules()) {
|
|
14187
14178
|
rules[ruleId] = this.loadRule(ruleId, config, severity, options, parser, this.report);
|
|
14188
14179
|
}
|
|
14189
14180
|
return rules;
|
|
@@ -14207,9 +14198,8 @@ class Engine {
|
|
|
14207
14198
|
if (this.availableRules[name]) {
|
|
14208
14199
|
const RuleConstructor = this.availableRules[name];
|
|
14209
14200
|
return new RuleConstructor(options);
|
|
14210
|
-
} else {
|
|
14211
|
-
return this.missingRule(name);
|
|
14212
14201
|
}
|
|
14202
|
+
return this.missingRule(name);
|
|
14213
14203
|
}
|
|
14214
14204
|
missingRule(name) {
|
|
14215
14205
|
return new class MissingRule extends Rule {
|
|
@@ -14305,34 +14295,30 @@ function getTransformerFunction(resolvers, name, plugins) {
|
|
|
14305
14295
|
validateTransformer(transformer2);
|
|
14306
14296
|
return transformer2;
|
|
14307
14297
|
});
|
|
14308
|
-
} else {
|
|
14309
|
-
validateTransformer(transformer);
|
|
14310
|
-
return transformer;
|
|
14311
14298
|
}
|
|
14299
|
+
validateTransformer(transformer);
|
|
14300
|
+
return transformer;
|
|
14312
14301
|
} catch (err) {
|
|
14313
14302
|
if (err instanceof ConfigError) {
|
|
14314
14303
|
throw new ConfigError(`Failed to load transformer "${name}": ${err.message}`, err);
|
|
14315
|
-
} else {
|
|
14316
|
-
throw new ConfigError(`Failed to load transformer "${name}"`, ensureError(err));
|
|
14317
14304
|
}
|
|
14305
|
+
throw new ConfigError(`Failed to load transformer "${name}"`, ensureError(err));
|
|
14318
14306
|
}
|
|
14319
14307
|
}
|
|
14320
14308
|
function getCachedTransformerFunction(cache, resolvers, name, plugins) {
|
|
14321
14309
|
const cached = cache.get(name);
|
|
14322
14310
|
if (cached) {
|
|
14323
14311
|
return cached;
|
|
14324
|
-
} else {
|
|
14325
|
-
const transformer = getTransformerFunction(resolvers, name, plugins);
|
|
14326
|
-
if (isThenable(transformer)) {
|
|
14327
|
-
return transformer.then((transformer2) => {
|
|
14328
|
-
cache.set(name, transformer2);
|
|
14329
|
-
return transformer2;
|
|
14330
|
-
});
|
|
14331
|
-
} else {
|
|
14332
|
-
cache.set(name, transformer);
|
|
14333
|
-
return transformer;
|
|
14334
|
-
}
|
|
14335
14312
|
}
|
|
14313
|
+
const transformer = getTransformerFunction(resolvers, name, plugins);
|
|
14314
|
+
if (isThenable(transformer)) {
|
|
14315
|
+
return transformer.then((transformer2) => {
|
|
14316
|
+
cache.set(name, transformer2);
|
|
14317
|
+
return transformer2;
|
|
14318
|
+
});
|
|
14319
|
+
}
|
|
14320
|
+
cache.set(name, transformer);
|
|
14321
|
+
return transformer;
|
|
14336
14322
|
}
|
|
14337
14323
|
|
|
14338
14324
|
function isIterable(value) {
|
|
@@ -14348,6 +14334,9 @@ const asyncInSyncTransformError = "Cannot use async transformer from sync functi
|
|
|
14348
14334
|
async function transformSource(resolvers, config, source, filename) {
|
|
14349
14335
|
const { cache } = config;
|
|
14350
14336
|
const transformer = config.findTransformer(filename ?? source.filename);
|
|
14337
|
+
if (!transformer) {
|
|
14338
|
+
return [source];
|
|
14339
|
+
}
|
|
14351
14340
|
const context = {
|
|
14352
14341
|
hasChain(filename2) {
|
|
14353
14342
|
return config.canTransform(filename2);
|
|
@@ -14356,9 +14345,6 @@ async function transformSource(resolvers, config, source, filename) {
|
|
|
14356
14345
|
return transformSource(resolvers, config, source2, filename2);
|
|
14357
14346
|
}
|
|
14358
14347
|
};
|
|
14359
|
-
if (!transformer) {
|
|
14360
|
-
return [source];
|
|
14361
|
-
}
|
|
14362
14348
|
const fn = transformer.kind === "import" ? await getCachedTransformerFunction(cache, resolvers, transformer.name, config.getPlugins()) : transformer.function;
|
|
14363
14349
|
const name = transformer.kind === "import" ? transformer.name : transformer.function.name;
|
|
14364
14350
|
try {
|
|
@@ -14377,6 +14363,9 @@ async function transformSource(resolvers, config, source, filename) {
|
|
|
14377
14363
|
function transformSourceSync(resolvers, config, source, filename) {
|
|
14378
14364
|
const { cache } = config;
|
|
14379
14365
|
const transformer = config.findTransformer(filename ?? source.filename);
|
|
14366
|
+
if (!transformer) {
|
|
14367
|
+
return [source];
|
|
14368
|
+
}
|
|
14380
14369
|
const context = {
|
|
14381
14370
|
hasChain(filename2) {
|
|
14382
14371
|
return config.canTransform(filename2);
|
|
@@ -14385,14 +14374,11 @@ function transformSourceSync(resolvers, config, source, filename) {
|
|
|
14385
14374
|
return transformSourceSync(resolvers, config, source2, filename2);
|
|
14386
14375
|
}
|
|
14387
14376
|
};
|
|
14388
|
-
if (!transformer) {
|
|
14389
|
-
return [source];
|
|
14390
|
-
}
|
|
14391
14377
|
const fn = transformer.kind === "import" ? getCachedTransformerFunction(cache, resolvers, transformer.name, config.getPlugins()) : transformer.function;
|
|
14392
|
-
const name = transformer.kind === "import" ? transformer.name : transformer.function.name;
|
|
14393
14378
|
if (isThenable(fn)) {
|
|
14394
14379
|
throw new UserError(asyncInSyncTransformError);
|
|
14395
14380
|
}
|
|
14381
|
+
const name = transformer.kind === "import" ? transformer.name : transformer.function.name;
|
|
14396
14382
|
try {
|
|
14397
14383
|
const result = fn.call(context, source);
|
|
14398
14384
|
if (isThenable(result)) {
|
|
@@ -14494,7 +14480,7 @@ function checkstyleFormatter(results) {
|
|
|
14494
14480
|
`;
|
|
14495
14481
|
for (const message of messages) {
|
|
14496
14482
|
const ruleId = xmlescape(`htmlvalidate.rules.${message.ruleId}`);
|
|
14497
|
-
output += "
|
|
14483
|
+
output += " ".repeat(4);
|
|
14498
14484
|
output += [
|
|
14499
14485
|
`<error line="${xmlescape(message.line)}"`,
|
|
14500
14486
|
`column="${xmlescape(message.column)}"`,
|
|
@@ -14581,9 +14567,8 @@ function codeFrameColumns(rawLines, loc) {
|
|
|
14581
14567
|
].join("");
|
|
14582
14568
|
}
|
|
14583
14569
|
return [">", gutter, line.length > 0 ? ` ${line}` : "", markerLine].join("");
|
|
14584
|
-
} else {
|
|
14585
|
-
return [" ", gutter, line.length > 0 ? ` ${line}` : ""].join("");
|
|
14586
14570
|
}
|
|
14571
|
+
return [" ", gutter, line.length > 0 ? ` ${line}` : ""].join("");
|
|
14587
14572
|
}).join("\n");
|
|
14588
14573
|
}
|
|
14589
14574
|
|