html-validate 11.5.3 → 11.5.5
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 +424 -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 +424 -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 +23 -11
- package/dist/types/index.d.ts +25 -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,17 @@ 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 !== "string") {
|
|
2943
|
+
if ("dynamic" in text) {
|
|
2944
|
+
text = new DynamicValue(text.dynamic);
|
|
2945
|
+
} else {
|
|
2946
|
+
text = new DynamicValue(text.expr);
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2959
2949
|
this.childNodes.push(new TextNode(text, location));
|
|
2960
2950
|
}
|
|
2961
2951
|
/**
|
|
@@ -3025,14 +3015,13 @@ class HtmlElement extends DOMNode {
|
|
|
3025
3015
|
const next = it.next();
|
|
3026
3016
|
if (next.done) {
|
|
3027
3017
|
return null;
|
|
3028
|
-
} else {
|
|
3029
|
-
return next.value;
|
|
3030
3018
|
}
|
|
3019
|
+
return next.value;
|
|
3031
3020
|
}
|
|
3032
3021
|
querySelectorAll(selector) {
|
|
3033
3022
|
const it = this.querySelectorImpl(selector);
|
|
3034
3023
|
const unique = new Set(it);
|
|
3035
|
-
return Array.from(unique
|
|
3024
|
+
return Array.from(unique);
|
|
3036
3025
|
}
|
|
3037
3026
|
*querySelectorImpl(selectorList) {
|
|
3038
3027
|
if (!selectorList) {
|
|
@@ -3053,9 +3042,8 @@ class HtmlElement extends DOMNode {
|
|
|
3053
3042
|
function visit(node) {
|
|
3054
3043
|
if (callback(node)) {
|
|
3055
3044
|
return true;
|
|
3056
|
-
} else {
|
|
3057
|
-
return node.childElements.some(visit);
|
|
3058
3045
|
}
|
|
3046
|
+
return node.childElements.some(visit);
|
|
3059
3047
|
}
|
|
3060
3048
|
}
|
|
3061
3049
|
/**
|
|
@@ -3230,7 +3218,7 @@ class Validator {
|
|
|
3230
3218
|
return true;
|
|
3231
3219
|
}
|
|
3232
3220
|
return rules.some((rule) => {
|
|
3233
|
-
return
|
|
3221
|
+
return this.validatePermittedRule(node, rule);
|
|
3234
3222
|
});
|
|
3235
3223
|
}
|
|
3236
3224
|
/**
|
|
@@ -3257,9 +3245,7 @@ class Validator {
|
|
|
3257
3245
|
const [, category, quantifier] = /^(@?.*?)([*?]?)$/.exec(rule);
|
|
3258
3246
|
const limit = category && quantifier && parseQuantifier(quantifier);
|
|
3259
3247
|
if (limit) {
|
|
3260
|
-
const siblings = children.filter(
|
|
3261
|
-
(cur) => Validator.validatePermittedCategory(cur, rule, true)
|
|
3262
|
-
);
|
|
3248
|
+
const siblings = children.filter((cur) => this.validatePermittedCategory(cur, rule, true));
|
|
3263
3249
|
if (siblings.length > limit) {
|
|
3264
3250
|
for (const child of siblings.slice(limit)) {
|
|
3265
3251
|
cb(child, category);
|
|
@@ -3290,12 +3276,12 @@ class Validator {
|
|
|
3290
3276
|
let prev = null;
|
|
3291
3277
|
for (const node of children) {
|
|
3292
3278
|
const old = i;
|
|
3293
|
-
while (rules[i] && !
|
|
3279
|
+
while (rules[i] && !this.validatePermittedCategory(node, rules[i], true)) {
|
|
3294
3280
|
i++;
|
|
3295
3281
|
}
|
|
3296
3282
|
if (i >= rules.length) {
|
|
3297
|
-
const orderSpecified = rules.
|
|
3298
|
-
(cur) =>
|
|
3283
|
+
const orderSpecified = rules.some(
|
|
3284
|
+
(cur) => this.validatePermittedCategory(node, cur, true)
|
|
3299
3285
|
);
|
|
3300
3286
|
if (orderSpecified) {
|
|
3301
3287
|
cb(node, prev);
|
|
@@ -3334,7 +3320,7 @@ class Validator {
|
|
|
3334
3320
|
}
|
|
3335
3321
|
return rules.filter((tagName) => {
|
|
3336
3322
|
const haveMatchingChild = node.childElements.some(
|
|
3337
|
-
(child) =>
|
|
3323
|
+
(child) => this.validatePermittedCategory(child, tagName, false)
|
|
3338
3324
|
);
|
|
3339
3325
|
return !haveMatchingChild;
|
|
3340
3326
|
});
|
|
@@ -3381,36 +3367,35 @@ class Validator {
|
|
|
3381
3367
|
return rule.enum.some((entry) => {
|
|
3382
3368
|
if (typeof entry === "string") {
|
|
3383
3369
|
return caseInsensitiveValue === entry;
|
|
3384
|
-
}
|
|
3370
|
+
}
|
|
3371
|
+
if (entry instanceof RegExp) {
|
|
3385
3372
|
return entry.test(value);
|
|
3386
|
-
}
|
|
3373
|
+
}
|
|
3374
|
+
if (entry.pattern instanceof RegExp) {
|
|
3387
3375
|
return entry.pattern.test(value);
|
|
3388
|
-
} else {
|
|
3389
|
-
throw new TypeError("RegExp was not precompiled when it should have been");
|
|
3390
3376
|
}
|
|
3377
|
+
throw new TypeError("RegExp was not precompiled when it should have been");
|
|
3391
3378
|
});
|
|
3392
3379
|
}
|
|
3393
3380
|
static validatePermittedRule(node, rule, isExclude = false) {
|
|
3394
3381
|
if (typeof rule === "string") {
|
|
3395
|
-
return
|
|
3396
|
-
}
|
|
3382
|
+
return this.validatePermittedCategory(node, rule, !isExclude);
|
|
3383
|
+
}
|
|
3384
|
+
if (Array.isArray(rule)) {
|
|
3397
3385
|
return rule.every((inner) => {
|
|
3398
|
-
return
|
|
3386
|
+
return this.validatePermittedRule(node, inner, isExclude);
|
|
3399
3387
|
});
|
|
3400
|
-
}
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
} else {
|
|
3408
|
-
return !Validator.validatePermittedRule(node, rule.exclude, true);
|
|
3409
|
-
}
|
|
3410
|
-
} else {
|
|
3411
|
-
return true;
|
|
3388
|
+
}
|
|
3389
|
+
validateKeys(rule);
|
|
3390
|
+
if (rule.exclude) {
|
|
3391
|
+
if (Array.isArray(rule.exclude)) {
|
|
3392
|
+
return rule.exclude.every((inner) => {
|
|
3393
|
+
return !this.validatePermittedRule(node, inner, true);
|
|
3394
|
+
});
|
|
3412
3395
|
}
|
|
3396
|
+
return !this.validatePermittedRule(node, rule.exclude, true);
|
|
3413
3397
|
}
|
|
3398
|
+
return true;
|
|
3414
3399
|
}
|
|
3415
3400
|
/**
|
|
3416
3401
|
* Validate node against a content category.
|
|
@@ -3426,7 +3411,7 @@ class Validator {
|
|
|
3426
3411
|
*/
|
|
3427
3412
|
/* eslint-disable-next-line complexity -- rule does not like switch */
|
|
3428
3413
|
static validatePermittedCategory(node, category, defaultMatch) {
|
|
3429
|
-
const [, rawCategory] = /^(@?.*?)
|
|
3414
|
+
const [, rawCategory] = /^(@?.*?)[*?]?$/.exec(category);
|
|
3430
3415
|
if (!rawCategory.startsWith("@")) {
|
|
3431
3416
|
return node.matches(rawCategory);
|
|
3432
3417
|
}
|
|
@@ -3459,10 +3444,11 @@ class Validator {
|
|
|
3459
3444
|
}
|
|
3460
3445
|
function validateKeys(rule) {
|
|
3461
3446
|
for (const key of Object.keys(rule)) {
|
|
3462
|
-
if (
|
|
3463
|
-
|
|
3464
|
-
throw new Error(`Permitted rule "${str}" contains unknown property "${key}"`);
|
|
3447
|
+
if (allowedKeys.has(key)) {
|
|
3448
|
+
continue;
|
|
3465
3449
|
}
|
|
3450
|
+
const str = JSON.stringify(rule);
|
|
3451
|
+
throw new Error(`Permitted rule "${str}" contains unknown property "${key}"`);
|
|
3466
3452
|
}
|
|
3467
3453
|
}
|
|
3468
3454
|
function parseQuantifier(quantifier) {
|
|
@@ -3529,9 +3515,8 @@ function ariaNaming(element) {
|
|
|
3529
3515
|
if (role) {
|
|
3530
3516
|
if (role instanceof DynamicValue) {
|
|
3531
3517
|
return element.cacheSet(cacheKey, defaultValue);
|
|
3532
|
-
} else {
|
|
3533
|
-
return element.cacheSet(cacheKey, byRole(role));
|
|
3534
3518
|
}
|
|
3519
|
+
return element.cacheSet(cacheKey, byRole(role));
|
|
3535
3520
|
}
|
|
3536
3521
|
const meta = element.meta;
|
|
3537
3522
|
if (!meta) {
|
|
@@ -3716,9 +3701,8 @@ function isPresentation(node) {
|
|
|
3716
3701
|
const role = node.getAttribute("role");
|
|
3717
3702
|
if (role && (role.value === "presentation" || role.value === "none")) {
|
|
3718
3703
|
return node.cacheSet(ROLE_PRESENTATION_CACHE, true);
|
|
3719
|
-
} else {
|
|
3720
|
-
return node.cacheSet(ROLE_PRESENTATION_CACHE, false);
|
|
3721
3704
|
}
|
|
3705
|
+
return node.cacheSet(ROLE_PRESENTATION_CACHE, false);
|
|
3722
3706
|
}
|
|
3723
3707
|
|
|
3724
3708
|
const cachePrefix = classifyNodeText.name;
|
|
@@ -3736,13 +3720,14 @@ function getCachekey(options) {
|
|
|
3736
3720
|
const { accessible = false, ignoreHiddenRoot = false } = options;
|
|
3737
3721
|
if (accessible && ignoreHiddenRoot) {
|
|
3738
3722
|
return IGNORE_HIDDEN_ROOT_A11Y_CACHE_KEY;
|
|
3739
|
-
}
|
|
3723
|
+
}
|
|
3724
|
+
if (ignoreHiddenRoot) {
|
|
3740
3725
|
return IGNORE_HIDDEN_ROOT_HTML_CACHE_KEY;
|
|
3741
|
-
}
|
|
3726
|
+
}
|
|
3727
|
+
if (accessible) {
|
|
3742
3728
|
return A11Y_CACHE_KEY;
|
|
3743
|
-
} else {
|
|
3744
|
-
return HTML_CACHE_KEY;
|
|
3745
3729
|
}
|
|
3730
|
+
return HTML_CACHE_KEY;
|
|
3746
3731
|
}
|
|
3747
3732
|
function isSpecialEmpty(node) {
|
|
3748
3733
|
return node.is("select") || node.is("textarea");
|
|
@@ -3774,7 +3759,7 @@ function classifyNodeText(node, options = {}) {
|
|
|
3774
3759
|
}
|
|
3775
3760
|
function findTextNodes(node, options) {
|
|
3776
3761
|
const { accessible = false } = options;
|
|
3777
|
-
|
|
3762
|
+
const text = [];
|
|
3778
3763
|
for (const child of node.childNodes) {
|
|
3779
3764
|
if (isTextNode(child)) {
|
|
3780
3765
|
text.push(child);
|
|
@@ -3785,7 +3770,7 @@ function findTextNodes(node, options) {
|
|
|
3785
3770
|
if (accessible && isAriaHidden(child, true).bySelf) {
|
|
3786
3771
|
continue;
|
|
3787
3772
|
}
|
|
3788
|
-
text
|
|
3773
|
+
text.push(...findTextNodes(child, options));
|
|
3789
3774
|
}
|
|
3790
3775
|
}
|
|
3791
3776
|
return text;
|
|
@@ -3846,14 +3831,17 @@ function format(value, quote = false) {
|
|
|
3846
3831
|
return String(value);
|
|
3847
3832
|
}
|
|
3848
3833
|
function interpolate(text, data) {
|
|
3849
|
-
return text.replaceAll(
|
|
3834
|
+
return text.replaceAll(/\{\{\s*([^\s{}]+)\s*\}\}/g, (match, key) => {
|
|
3850
3835
|
return data[key] !== void 0 ? format(data[key]) : match;
|
|
3851
3836
|
});
|
|
3852
3837
|
}
|
|
3853
3838
|
|
|
3854
|
-
const ajv$1 =
|
|
3855
|
-
|
|
3856
|
-
|
|
3839
|
+
const ajv$1 = (() => {
|
|
3840
|
+
const ajv2 = new Ajv({ strict: true, strictTuples: true, strictTypes: true });
|
|
3841
|
+
ajv2.addMetaSchema(ajvSchemaDraft);
|
|
3842
|
+
ajv2.addKeyword(ajvRegexpKeyword);
|
|
3843
|
+
return ajv2;
|
|
3844
|
+
})();
|
|
3857
3845
|
function getSchemaValidator(ruleId, properties) {
|
|
3858
3846
|
const $id = `rule/${ruleId}`;
|
|
3859
3847
|
const cached = ajv$1.getSchema($id);
|
|
@@ -3874,10 +3862,9 @@ function isErrorDescriptor(value) {
|
|
|
3874
3862
|
function unpackErrorDescriptor(value) {
|
|
3875
3863
|
if (isErrorDescriptor(value)) {
|
|
3876
3864
|
return value[0];
|
|
3877
|
-
} else {
|
|
3878
|
-
const [node, message, location, context] = value;
|
|
3879
|
-
return { node, message, location, context };
|
|
3880
3865
|
}
|
|
3866
|
+
const [node, message, location, context] = value;
|
|
3867
|
+
return { node, message, location, context };
|
|
3881
3868
|
}
|
|
3882
3869
|
class Rule {
|
|
3883
3870
|
reporter;
|
|
@@ -4083,17 +4070,18 @@ class Rule {
|
|
|
4083
4070
|
const callback = args.pop();
|
|
4084
4071
|
const filter = args.pop() ?? (() => true);
|
|
4085
4072
|
return this.parser.on(event, (_event, data) => {
|
|
4086
|
-
if (this.isEnabled()
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4073
|
+
if (!this.isEnabled() || !filter(data)) {
|
|
4074
|
+
return;
|
|
4075
|
+
}
|
|
4076
|
+
this.event = data;
|
|
4077
|
+
const { tracker } = this;
|
|
4078
|
+
if (tracker) {
|
|
4079
|
+
const start = performance.now();
|
|
4080
|
+
callback(data);
|
|
4081
|
+
const end = performance.now();
|
|
4082
|
+
tracker.trackRule(this.name, end - start);
|
|
4083
|
+
} else {
|
|
4084
|
+
callback(data);
|
|
4097
4085
|
}
|
|
4098
4086
|
});
|
|
4099
4087
|
}
|
|
@@ -4163,7 +4151,7 @@ class Rule {
|
|
|
4163
4151
|
* @public
|
|
4164
4152
|
* @virtual
|
|
4165
4153
|
* @param context - Error context given by a reported error.
|
|
4166
|
-
* @returns Rule documentation and
|
|
4154
|
+
* @returns Rule documentation and URL with additional details or `null` if no
|
|
4167
4155
|
* additional documentation is available.
|
|
4168
4156
|
*/
|
|
4169
4157
|
documentation(_context) {
|
|
@@ -4202,7 +4190,7 @@ function parseAllow(value) {
|
|
|
4202
4190
|
};
|
|
4203
4191
|
}
|
|
4204
4192
|
function matchList(value, list) {
|
|
4205
|
-
if (list.include
|
|
4193
|
+
if (list.include?.every((it) => !it.test(value))) {
|
|
4206
4194
|
return false;
|
|
4207
4195
|
}
|
|
4208
4196
|
if (list.exclude?.some((it) => it.test(value))) {
|
|
@@ -4287,10 +4275,10 @@ class AllowedLinks extends Rule {
|
|
|
4287
4275
|
return Boolean(attr && attr === key);
|
|
4288
4276
|
}
|
|
4289
4277
|
getStyle(value) {
|
|
4290
|
-
if (/^([a-z]+:)
|
|
4278
|
+
if (/^(?:[a-z]+:)?\/\//.test(value)) {
|
|
4291
4279
|
return "external" /* EXTERNAL */;
|
|
4292
4280
|
}
|
|
4293
|
-
switch (value
|
|
4281
|
+
switch (value.at(0)) {
|
|
4294
4282
|
/* /foo/bar */
|
|
4295
4283
|
case "/":
|
|
4296
4284
|
return "absolute" /* ABSOLUTE */;
|
|
@@ -4309,7 +4297,8 @@ class AllowedLinks extends Rule {
|
|
|
4309
4297
|
const { allowAbsolute } = this;
|
|
4310
4298
|
if (allowAbsolute === true) {
|
|
4311
4299
|
return;
|
|
4312
|
-
}
|
|
4300
|
+
}
|
|
4301
|
+
if (allowAbsolute === false) {
|
|
4313
4302
|
this.report(
|
|
4314
4303
|
event.target,
|
|
4315
4304
|
"Link destination must not be absolute url",
|
|
@@ -4329,7 +4318,8 @@ class AllowedLinks extends Rule {
|
|
|
4329
4318
|
const { allowExternal } = this;
|
|
4330
4319
|
if (allowExternal === true) {
|
|
4331
4320
|
return;
|
|
4332
|
-
}
|
|
4321
|
+
}
|
|
4322
|
+
if (allowExternal === false) {
|
|
4333
4323
|
this.report(
|
|
4334
4324
|
event.target,
|
|
4335
4325
|
"Link destination must not be external url",
|
|
@@ -4349,7 +4339,8 @@ class AllowedLinks extends Rule {
|
|
|
4349
4339
|
const { allowRelative } = this;
|
|
4350
4340
|
if (allowRelative === true) {
|
|
4351
4341
|
return false;
|
|
4352
|
-
}
|
|
4342
|
+
}
|
|
4343
|
+
if (allowRelative === false) {
|
|
4353
4344
|
this.report(
|
|
4354
4345
|
event.target,
|
|
4355
4346
|
"Link destination must not be relative url",
|
|
@@ -4357,7 +4348,8 @@ class AllowedLinks extends Rule {
|
|
|
4357
4348
|
style
|
|
4358
4349
|
);
|
|
4359
4350
|
return true;
|
|
4360
|
-
}
|
|
4351
|
+
}
|
|
4352
|
+
if (!matchList(target, allowRelative)) {
|
|
4361
4353
|
this.report(
|
|
4362
4354
|
event.target,
|
|
4363
4355
|
"Relative link to this destination is not allowed by current configuration",
|
|
@@ -4372,7 +4364,8 @@ class AllowedLinks extends Rule {
|
|
|
4372
4364
|
const { allowBase } = this.options;
|
|
4373
4365
|
if (this.handleRelativePath(target, event, style)) {
|
|
4374
4366
|
return;
|
|
4375
|
-
}
|
|
4367
|
+
}
|
|
4368
|
+
if (!allowBase) {
|
|
4376
4369
|
this.report(
|
|
4377
4370
|
event.target,
|
|
4378
4371
|
"Relative links must be relative to current folder",
|
|
@@ -4590,12 +4583,11 @@ class AriaLabelMisuse extends Rule {
|
|
|
4590
4583
|
].join("\n"),
|
|
4591
4584
|
url
|
|
4592
4585
|
};
|
|
4593
|
-
} else {
|
|
4594
|
-
return {
|
|
4595
|
-
description: [`\`${context.attr}\` can only be used on:`, "", ...lines].join("\n"),
|
|
4596
|
-
url
|
|
4597
|
-
};
|
|
4598
4586
|
}
|
|
4587
|
+
return {
|
|
4588
|
+
description: [`\`${context.attr}\` can only be used on:`, "", ...lines].join("\n"),
|
|
4589
|
+
url
|
|
4590
|
+
};
|
|
4599
4591
|
}
|
|
4600
4592
|
setup() {
|
|
4601
4593
|
this.on("dom:ready", (event) => {
|
|
@@ -4653,6 +4645,7 @@ class AriaLabelMisuse extends Rule {
|
|
|
4653
4645
|
}
|
|
4654
4646
|
|
|
4655
4647
|
class ConfigError extends UserError {
|
|
4648
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
4656
4649
|
constructor(message, nested) {
|
|
4657
4650
|
super(message, nested);
|
|
4658
4651
|
this.name = "ConfigError";
|
|
@@ -4773,9 +4766,8 @@ class AttrCase extends Rule {
|
|
|
4773
4766
|
isIgnored(node) {
|
|
4774
4767
|
if (this.options.ignoreForeign) {
|
|
4775
4768
|
return Boolean(node.meta?.foreign);
|
|
4776
|
-
} else {
|
|
4777
|
-
return false;
|
|
4778
4769
|
}
|
|
4770
|
+
return false;
|
|
4779
4771
|
}
|
|
4780
4772
|
}
|
|
4781
4773
|
|
|
@@ -4825,10 +4817,11 @@ class Context {
|
|
|
4825
4817
|
let lastNewline = -1;
|
|
4826
4818
|
let newlines = 0;
|
|
4827
4819
|
for (let i = 0; i < n; i++) {
|
|
4828
|
-
if (this.string[i]
|
|
4829
|
-
|
|
4830
|
-
lastNewline = i;
|
|
4820
|
+
if (this.string[i] !== "\n") {
|
|
4821
|
+
continue;
|
|
4831
4822
|
}
|
|
4823
|
+
newlines++;
|
|
4824
|
+
lastNewline = i;
|
|
4832
4825
|
}
|
|
4833
4826
|
if (newlines > 0) {
|
|
4834
4827
|
this.line += newlines;
|
|
@@ -4890,28 +4883,29 @@ const MATCH_DOCTYPE_CLOSE = /^>/;
|
|
|
4890
4883
|
const MATCH_XML_TAG = /^<\?xml.*?\?>\s+/;
|
|
4891
4884
|
const MATCH_TAG_OPEN = /^<(\/?)([\w:\-]+)/;
|
|
4892
4885
|
const MATCH_TAG_CLOSE = /^\/?>/;
|
|
4893
|
-
const MATCH_TEXT = /^[
|
|
4886
|
+
const MATCH_TEXT = /^[\s\S]*?(?=[\t ]*(?:\r\n|\r|\n)|<[^ ]|$)/;
|
|
4894
4887
|
const MATCH_TEMPLATING = /^(?:<%.*?%>|<\?.*?\?>|<\$.*?\$>)/s;
|
|
4895
|
-
const MATCH_TAG_LOOKAHEAD = /^[
|
|
4888
|
+
const MATCH_TAG_LOOKAHEAD = /^[\s\S]*?(?=<|$)/;
|
|
4896
4889
|
const MATCH_ATTR_START = /^([^\t\n\f\r "'/<=>]+)/;
|
|
4897
|
-
const MATCH_ATTR_SINGLE = /^(\s*=\s*)'([^']
|
|
4898
|
-
const MATCH_ATTR_DOUBLE = /^(\s*=\s*)"([^"]
|
|
4890
|
+
const MATCH_ATTR_SINGLE = /^(\s*=\s*)'([^']*)(')/;
|
|
4891
|
+
const MATCH_ATTR_DOUBLE = /^(\s*=\s*)"([^"]*)(")/;
|
|
4899
4892
|
const MATCH_ATTR_UNQUOTED = /^(\s*=\s*)([^\t\n\f\r "'<>][^\t\n\f\r <>]*)/;
|
|
4900
4893
|
const MATCH_CDATA_BEGIN = /^<!\[CDATA\[/;
|
|
4901
|
-
const MATCH_CDATA_END = /^[
|
|
4902
|
-
const MATCH_SCRIPT_DATA = /^[
|
|
4894
|
+
const MATCH_CDATA_END = /^[\s\S]*?\]\]>/;
|
|
4895
|
+
const MATCH_SCRIPT_DATA = /^[\s\S]*?(?=<\/script)/;
|
|
4903
4896
|
const MATCH_SCRIPT_END = /^<(\/)(script)/;
|
|
4904
|
-
const MATCH_STYLE_DATA = /^[
|
|
4897
|
+
const MATCH_STYLE_DATA = /^[\s\S]*?(?=<\/style)/;
|
|
4905
4898
|
const MATCH_STYLE_END = /^<(\/)(style)/;
|
|
4906
|
-
const MATCH_TEXTAREA_DATA = /^[
|
|
4899
|
+
const MATCH_TEXTAREA_DATA = /^[\s\S]*?(?=<\/textarea)/;
|
|
4907
4900
|
const MATCH_TEXTAREA_END = /^<(\/)(textarea)/;
|
|
4908
|
-
const MATCH_TITLE_DATA = /^[
|
|
4901
|
+
const MATCH_TITLE_DATA = /^[\s\S]*?(?=<\/title)/;
|
|
4909
4902
|
const MATCH_TITLE_END = /^<(\/)(title)/;
|
|
4910
|
-
const MATCH_DIRECTIVE = /^(<!--\s*\[?)(html-validate-)([\da-z-]+)(\s*)(.*?)(]?\s*-->)/;
|
|
4911
|
-
const MATCH_COMMENT = /^<!--([
|
|
4912
|
-
const MATCH_CONDITIONAL = /^<!\[([^\]]
|
|
4903
|
+
const MATCH_DIRECTIVE = /^(<!--\s*\[?)(html-validate-)([\da-z-]+)(\s*)(.*?)(\]?\s*-->)/;
|
|
4904
|
+
const MATCH_COMMENT = /^<!--([\s\S]*?)-->/;
|
|
4905
|
+
const MATCH_CONDITIONAL = /^<!\[([^\]]*)\]>/;
|
|
4913
4906
|
class InvalidTokenError extends Error {
|
|
4914
4907
|
location;
|
|
4908
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
4915
4909
|
constructor(location, message) {
|
|
4916
4910
|
super(message);
|
|
4917
4911
|
this.name = "InvalidTokenError";
|
|
@@ -4995,9 +4989,8 @@ class Lexer {
|
|
|
4995
4989
|
evalNextState(nextState, token) {
|
|
4996
4990
|
if (typeof nextState === "function") {
|
|
4997
4991
|
return nextState(token);
|
|
4998
|
-
} else {
|
|
4999
|
-
return nextState;
|
|
5000
4992
|
}
|
|
4993
|
+
return nextState;
|
|
5001
4994
|
}
|
|
5002
4995
|
*match(context, tests, error) {
|
|
5003
4996
|
const n = tests.length;
|
|
@@ -5084,27 +5077,26 @@ class Lexer {
|
|
|
5084
5077
|
case ContentModel.SCRIPT:
|
|
5085
5078
|
if (selfClosed) {
|
|
5086
5079
|
return State.SCRIPT;
|
|
5087
|
-
} else {
|
|
5088
|
-
return State.TEXT;
|
|
5089
5080
|
}
|
|
5081
|
+
return State.TEXT;
|
|
5082
|
+
/* <script/> (not legal but handle it anyway so the lexer doesn't choke on it) */
|
|
5090
5083
|
case ContentModel.STYLE:
|
|
5091
5084
|
if (selfClosed) {
|
|
5092
5085
|
return State.STYLE;
|
|
5093
|
-
} else {
|
|
5094
|
-
return State.TEXT;
|
|
5095
5086
|
}
|
|
5087
|
+
return State.TEXT;
|
|
5088
|
+
/* <style/> */
|
|
5096
5089
|
case ContentModel.TEXTAREA:
|
|
5097
5090
|
if (selfClosed) {
|
|
5098
5091
|
return State.TEXTAREA;
|
|
5099
|
-
} else {
|
|
5100
|
-
return State.TEXT;
|
|
5101
5092
|
}
|
|
5093
|
+
return State.TEXT;
|
|
5094
|
+
/* <textarea/> */
|
|
5102
5095
|
case ContentModel.TITLE:
|
|
5103
5096
|
if (selfClosed) {
|
|
5104
5097
|
return State.TITLE;
|
|
5105
|
-
} else {
|
|
5106
|
-
return State.TEXT;
|
|
5107
5098
|
}
|
|
5099
|
+
return State.TEXT;
|
|
5108
5100
|
}
|
|
5109
5101
|
}
|
|
5110
5102
|
yield* this.match(
|
|
@@ -5191,7 +5183,7 @@ class Lexer {
|
|
|
5191
5183
|
}
|
|
5192
5184
|
}
|
|
5193
5185
|
|
|
5194
|
-
const whitespace =
|
|
5186
|
+
const whitespace = /\s+/;
|
|
5195
5187
|
class AttrDelimiter extends Rule {
|
|
5196
5188
|
documentation() {
|
|
5197
5189
|
return {
|
|
@@ -5223,17 +5215,15 @@ const defaults$y = {
|
|
|
5223
5215
|
function generateRegexp(pattern) {
|
|
5224
5216
|
if (Array.isArray(pattern)) {
|
|
5225
5217
|
return new RegExp(`^(${pattern.join("|")})$`, "i");
|
|
5226
|
-
} else {
|
|
5227
|
-
return new RegExp(`^${pattern}$`, "i");
|
|
5228
5218
|
}
|
|
5219
|
+
return new RegExp(`^${pattern}$`, "i");
|
|
5229
5220
|
}
|
|
5230
5221
|
function generateMessage(name, pattern) {
|
|
5231
5222
|
if (Array.isArray(pattern)) {
|
|
5232
5223
|
const patterns = pattern.map((it) => `/${it}/`).join(", ");
|
|
5233
5224
|
return `Attribute "${name}" should match one of [${patterns}]`;
|
|
5234
|
-
} else {
|
|
5235
|
-
return `Attribute "${name}" should match /${pattern}/`;
|
|
5236
5225
|
}
|
|
5226
|
+
return `Attribute "${name}" should match /${pattern}/`;
|
|
5237
5227
|
}
|
|
5238
5228
|
function generateDescription(name, pattern) {
|
|
5239
5229
|
if (Array.isArray(pattern)) {
|
|
@@ -5242,9 +5232,8 @@ function generateDescription(name, pattern) {
|
|
|
5242
5232
|
"",
|
|
5243
5233
|
...pattern.map((it) => `- \`/${it}/\``)
|
|
5244
5234
|
].join("\n");
|
|
5245
|
-
} else {
|
|
5246
|
-
return `Attribute "${name}" should match the regular expression \`/${pattern}/\``;
|
|
5247
5235
|
}
|
|
5236
|
+
return `Attribute "${name}" should match the regular expression \`/${pattern}/\``;
|
|
5248
5237
|
}
|
|
5249
5238
|
class AttrPattern extends Rule {
|
|
5250
5239
|
pattern;
|
|
@@ -5290,9 +5279,8 @@ class AttrPattern extends Rule {
|
|
|
5290
5279
|
isIgnored(node) {
|
|
5291
5280
|
if (this.options.ignoreForeign) {
|
|
5292
5281
|
return Boolean(node.meta?.foreign);
|
|
5293
|
-
} else {
|
|
5294
|
-
return false;
|
|
5295
5282
|
}
|
|
5283
|
+
return false;
|
|
5296
5284
|
}
|
|
5297
5285
|
}
|
|
5298
5286
|
|
|
@@ -5403,9 +5391,8 @@ class AttrQuotes extends Rule {
|
|
|
5403
5391
|
resolveQuotemark(value, style) {
|
|
5404
5392
|
if (style === "auto" /* AUTO_QUOTE */) {
|
|
5405
5393
|
return value.includes('"') ? "'" : '"';
|
|
5406
|
-
} else {
|
|
5407
|
-
return style;
|
|
5408
5394
|
}
|
|
5395
|
+
return style;
|
|
5409
5396
|
}
|
|
5410
5397
|
}
|
|
5411
5398
|
function parseStyle$3(style) {
|
|
@@ -5463,11 +5450,11 @@ class AttributeAllowedValues extends Rule {
|
|
|
5463
5450
|
const allowedList = allowed.enum.map((value2) => {
|
|
5464
5451
|
if (typeof value2 === "string") {
|
|
5465
5452
|
return `- \`"${value2}"\``;
|
|
5466
|
-
}
|
|
5453
|
+
}
|
|
5454
|
+
if (value2 instanceof RegExp) {
|
|
5467
5455
|
return `- \`${value2.toString()}\``;
|
|
5468
|
-
} else {
|
|
5469
|
-
return `- ${value2.name}`;
|
|
5470
5456
|
}
|
|
5457
|
+
return `- ${value2.name}`;
|
|
5471
5458
|
});
|
|
5472
5459
|
docs.description = [
|
|
5473
5460
|
`The \`<${element}>\` element does not allow the attribute \`${attribute}\` to have the value \`"${value}"\`.`,
|
|
@@ -5511,9 +5498,8 @@ class AttributeAllowedValues extends Rule {
|
|
|
5511
5498
|
const { key, value } = attr;
|
|
5512
5499
|
if (value !== null) {
|
|
5513
5500
|
return `Attribute "${key}" has invalid value "${value.toString()}"`;
|
|
5514
|
-
} else {
|
|
5515
|
-
return `Attribute "${key}" is missing value`;
|
|
5516
5501
|
}
|
|
5502
|
+
return `Attribute "${key}" is missing value`;
|
|
5517
5503
|
}
|
|
5518
5504
|
getLocation(attr) {
|
|
5519
5505
|
return attr.valueLocation ?? attr.keyLocation;
|
|
@@ -5800,10 +5786,10 @@ class AutocompletePassword extends Rule {
|
|
|
5800
5786
|
const tokens = new DOMTokenList(raw, autocomplete.valueLocation);
|
|
5801
5787
|
const index = tokens.findIndex((token) => !isGroupingToken(token));
|
|
5802
5788
|
const value = tokens.item(index);
|
|
5803
|
-
const location = tokens.location(index);
|
|
5804
5789
|
if (!value) {
|
|
5805
5790
|
return;
|
|
5806
5791
|
}
|
|
5792
|
+
const location = tokens.location(index);
|
|
5807
5793
|
if (value === "off") {
|
|
5808
5794
|
const context = { kind: "off" };
|
|
5809
5795
|
this.report({
|
|
@@ -5888,9 +5874,8 @@ function parsePattern(pattern) {
|
|
|
5888
5874
|
function toArray$2(value) {
|
|
5889
5875
|
if (Array.isArray(value)) {
|
|
5890
5876
|
return value;
|
|
5891
|
-
} else {
|
|
5892
|
-
return [value];
|
|
5893
5877
|
}
|
|
5878
|
+
return [value];
|
|
5894
5879
|
}
|
|
5895
5880
|
function validateAllowedPatterns(patterns, allowedPatterns, ruleId) {
|
|
5896
5881
|
const extraneous = patterns.filter(isNamedPattern).filter((p) => !allowedPatterns.has(p));
|
|
@@ -5976,7 +5961,7 @@ class ClassPattern extends BasePatternRule {
|
|
|
5976
5961
|
});
|
|
5977
5962
|
}
|
|
5978
5963
|
static schema() {
|
|
5979
|
-
return
|
|
5964
|
+
return super.schema();
|
|
5980
5965
|
}
|
|
5981
5966
|
documentation(context) {
|
|
5982
5967
|
return {
|
|
@@ -6057,10 +6042,10 @@ class CloseOrder extends Rule {
|
|
|
6057
6042
|
});
|
|
6058
6043
|
this.on("tag:end", (event) => {
|
|
6059
6044
|
const current = event.target;
|
|
6060
|
-
const active = event.previous;
|
|
6061
6045
|
if (current) {
|
|
6062
6046
|
return;
|
|
6063
6047
|
}
|
|
6048
|
+
const active = event.previous;
|
|
6064
6049
|
for (const ancestor of ancestors(active)) {
|
|
6065
6050
|
if (ancestor.isRootElement() || reported.has(ancestor.unique)) {
|
|
6066
6051
|
continue;
|
|
@@ -6071,13 +6056,13 @@ class CloseOrder extends Rule {
|
|
|
6071
6056
|
});
|
|
6072
6057
|
this.on("tag:end", (event) => {
|
|
6073
6058
|
const current = event.target;
|
|
6074
|
-
const active = event.previous;
|
|
6075
6059
|
if (!current) {
|
|
6076
6060
|
return;
|
|
6077
6061
|
}
|
|
6078
6062
|
if (current.voidElement) {
|
|
6079
6063
|
return;
|
|
6080
6064
|
}
|
|
6065
|
+
const active = event.previous;
|
|
6081
6066
|
if (active.closed === Node.CLOSED_IMPLICIT_CLOSED) {
|
|
6082
6067
|
return;
|
|
6083
6068
|
}
|
|
@@ -6172,7 +6157,7 @@ class Deprecated extends Rule {
|
|
|
6172
6157
|
text.push(context.documentation);
|
|
6173
6158
|
}
|
|
6174
6159
|
const doc = {
|
|
6175
|
-
description: text.map((cur) => cur.replaceAll("$tagname", context.tagName)).join("\n\n"),
|
|
6160
|
+
description: text.map((cur) => cur.replaceAll("$tagname", () => context.tagName)).join("\n\n"),
|
|
6176
6161
|
url: "https://html-validate.org/rules/deprecated.html"
|
|
6177
6162
|
};
|
|
6178
6163
|
return doc;
|
|
@@ -6571,7 +6556,7 @@ class ElementName extends Rule {
|
|
|
6571
6556
|
];
|
|
6572
6557
|
}
|
|
6573
6558
|
setup() {
|
|
6574
|
-
const xmlns = /^
|
|
6559
|
+
const xmlns = /^[^:]+:.+$/;
|
|
6575
6560
|
this.on("tag:start", (event) => {
|
|
6576
6561
|
const target = event.target;
|
|
6577
6562
|
const tagName = target.tagName;
|
|
@@ -6610,13 +6595,12 @@ function isNativeTemplate(node) {
|
|
|
6610
6595
|
function getTransparentChildren(node, transparent) {
|
|
6611
6596
|
if (typeof transparent === "boolean") {
|
|
6612
6597
|
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
6598
|
}
|
|
6599
|
+
return node.childElements.filter((it) => {
|
|
6600
|
+
return transparent.some((category) => {
|
|
6601
|
+
return Validator.validatePermittedCategory(it, category, false);
|
|
6602
|
+
});
|
|
6603
|
+
});
|
|
6620
6604
|
}
|
|
6621
6605
|
function getRuleDescription$2(context) {
|
|
6622
6606
|
switch (context.kind) {
|
|
@@ -6648,6 +6632,7 @@ class ElementPermittedContent extends Rule {
|
|
|
6648
6632
|
[
|
|
6649
6633
|
() => this.validatePermittedContent(node, parent),
|
|
6650
6634
|
() => this.validatePermittedDescendant(node, parent)
|
|
6635
|
+
/* eslint-disable-next-line unicorn/no-unused-array-method-return -- technical debt, should use iterator helpers */
|
|
6651
6636
|
].some((fn) => fn());
|
|
6652
6637
|
});
|
|
6653
6638
|
});
|
|
@@ -6793,14 +6778,12 @@ function getRuleDescription$1(context) {
|
|
|
6793
6778
|
const allowed = rules.filter(isCategoryOrTag).map((it) => {
|
|
6794
6779
|
if (isCategory$1(it)) {
|
|
6795
6780
|
return `- any ${it.slice(1)} element`;
|
|
6796
|
-
} else {
|
|
6797
|
-
return `- \`<${it}>\``;
|
|
6798
6781
|
}
|
|
6782
|
+
return `- \`<${it}>\``;
|
|
6799
6783
|
});
|
|
6800
6784
|
return [preamble, "", "Allowed parents one of:", "", ...allowed];
|
|
6801
|
-
} else {
|
|
6802
|
-
return [preamble];
|
|
6803
6785
|
}
|
|
6786
|
+
return [preamble];
|
|
6804
6787
|
}
|
|
6805
6788
|
function formatMessage$1(node, parent, rules) {
|
|
6806
6789
|
const nodeName = node.annotatedName;
|
|
@@ -6852,7 +6835,7 @@ class ElementPermittedParent extends Rule {
|
|
|
6852
6835
|
}
|
|
6853
6836
|
|
|
6854
6837
|
function isTagnameOnly(value) {
|
|
6855
|
-
return /^[\dA-
|
|
6838
|
+
return /^[\dA-Z-]+$/i.test(value);
|
|
6856
6839
|
}
|
|
6857
6840
|
function getRuleDescription(context) {
|
|
6858
6841
|
const escaped = context.ancestor.map((it) => `\`${it}\``);
|
|
@@ -6915,9 +6898,8 @@ function normalizeRequired(element, attr) {
|
|
|
6915
6898
|
default:
|
|
6916
6899
|
return result;
|
|
6917
6900
|
}
|
|
6918
|
-
} else {
|
|
6919
|
-
return required ? defaultMessage : false;
|
|
6920
6901
|
}
|
|
6902
|
+
return required ? defaultMessage : false;
|
|
6921
6903
|
}
|
|
6922
6904
|
class ElementRequiredAttributes extends Rule {
|
|
6923
6905
|
documentation(context) {
|
|
@@ -6999,7 +6981,8 @@ const selector = ["h1", "h2", "h3", "h4", "h5", "h6"].join(",");
|
|
|
6999
6981
|
function hasImgAltText$1(node) {
|
|
7000
6982
|
if (node.is("img")) {
|
|
7001
6983
|
return hasAltText(node);
|
|
7002
|
-
}
|
|
6984
|
+
}
|
|
6985
|
+
if (node.is("svg")) {
|
|
7003
6986
|
return node.textContent.trim() !== "";
|
|
7004
6987
|
}
|
|
7005
6988
|
return false;
|
|
@@ -7280,21 +7263,19 @@ class FormDupName extends Rule {
|
|
|
7280
7263
|
const existing = group.cacheGet(UNIQUE_CACHE_KEY);
|
|
7281
7264
|
if (existing) {
|
|
7282
7265
|
return existing;
|
|
7283
|
-
} else {
|
|
7284
|
-
const elements = /* @__PURE__ */ new Map();
|
|
7285
|
-
group.cacheSet(UNIQUE_CACHE_KEY, elements);
|
|
7286
|
-
return elements;
|
|
7287
7266
|
}
|
|
7267
|
+
const elements = /* @__PURE__ */ new Map();
|
|
7268
|
+
group.cacheSet(UNIQUE_CACHE_KEY, elements);
|
|
7269
|
+
return elements;
|
|
7288
7270
|
}
|
|
7289
7271
|
getSharedElements(group) {
|
|
7290
7272
|
const existing = group.cacheGet(SHARED_CACHE_KEY);
|
|
7291
7273
|
if (existing) {
|
|
7292
7274
|
return existing;
|
|
7293
|
-
} else {
|
|
7294
|
-
const elements = /* @__PURE__ */ new Map();
|
|
7295
|
-
group.cacheSet(SHARED_CACHE_KEY, elements);
|
|
7296
|
-
return elements;
|
|
7297
7275
|
}
|
|
7276
|
+
const elements = /* @__PURE__ */ new Map();
|
|
7277
|
+
group.cacheSet(SHARED_CACHE_KEY, elements);
|
|
7278
|
+
return elements;
|
|
7298
7279
|
}
|
|
7299
7280
|
}
|
|
7300
7281
|
|
|
@@ -7308,12 +7289,11 @@ function isRelevant$5(event) {
|
|
|
7308
7289
|
return Boolean(node.meta?.heading);
|
|
7309
7290
|
}
|
|
7310
7291
|
function extractLevel(node) {
|
|
7311
|
-
const match = /^
|
|
7292
|
+
const match = /^H(\d)$/i.exec(node.tagName);
|
|
7312
7293
|
if (match) {
|
|
7313
|
-
return
|
|
7314
|
-
} else {
|
|
7315
|
-
return null;
|
|
7294
|
+
return Math.trunc(Number(match[1]));
|
|
7316
7295
|
}
|
|
7296
|
+
return null;
|
|
7317
7297
|
}
|
|
7318
7298
|
function parseMaxInitial(value) {
|
|
7319
7299
|
if (value === false || value === "any") {
|
|
@@ -7323,7 +7303,7 @@ function parseMaxInitial(value) {
|
|
|
7323
7303
|
if (!match) {
|
|
7324
7304
|
return 1;
|
|
7325
7305
|
}
|
|
7326
|
-
return
|
|
7306
|
+
return Math.trunc(Number(match[1]));
|
|
7327
7307
|
}
|
|
7328
7308
|
class HeadingLevel extends Rule {
|
|
7329
7309
|
minInitialRank;
|
|
@@ -7590,7 +7570,7 @@ class IdPattern extends BasePatternRule {
|
|
|
7590
7570
|
});
|
|
7591
7571
|
}
|
|
7592
7572
|
static schema() {
|
|
7593
|
-
return
|
|
7573
|
+
return super.schema();
|
|
7594
7574
|
}
|
|
7595
7575
|
documentation(context) {
|
|
7596
7576
|
return {
|
|
@@ -7812,24 +7792,23 @@ function isHidden(node, context) {
|
|
|
7812
7792
|
const { reference } = context;
|
|
7813
7793
|
if (reference?.isSameNode(node)) {
|
|
7814
7794
|
return false;
|
|
7815
|
-
} else {
|
|
7816
|
-
return !inAccessibilityTree(node);
|
|
7817
7795
|
}
|
|
7796
|
+
return !inAccessibilityTree(node);
|
|
7818
7797
|
}
|
|
7819
7798
|
function hasImgAltText(node, context) {
|
|
7820
7799
|
if (node.is("img")) {
|
|
7821
7800
|
return hasAltText(node);
|
|
7822
|
-
}
|
|
7801
|
+
}
|
|
7802
|
+
if (node.is("svg")) {
|
|
7823
7803
|
return node.textContent.trim() !== "";
|
|
7824
|
-
}
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
}
|
|
7804
|
+
}
|
|
7805
|
+
for (const img of node.querySelectorAll("img, svg")) {
|
|
7806
|
+
const hasName = hasAccessibleNameImpl(img, context);
|
|
7807
|
+
if (hasName) {
|
|
7808
|
+
return true;
|
|
7830
7809
|
}
|
|
7831
|
-
return false;
|
|
7832
7810
|
}
|
|
7811
|
+
return false;
|
|
7833
7812
|
}
|
|
7834
7813
|
function hasLabel(node) {
|
|
7835
7814
|
const value = node.getAttributeValue("aria-label") ?? "";
|
|
@@ -7960,7 +7939,7 @@ class InputMissingLabel extends Rule {
|
|
|
7960
7939
|
this.report(elem, `<${elem.tagName}> element has <label> but <label> element is hidden`);
|
|
7961
7940
|
return;
|
|
7962
7941
|
}
|
|
7963
|
-
if (
|
|
7942
|
+
if (labels.every((label) => !hasAccessibleName(root, label))) {
|
|
7964
7943
|
this.report(elem, `<${elem.tagName}> element has <label> but <label> has no text`);
|
|
7965
7944
|
}
|
|
7966
7945
|
}
|
|
@@ -8147,12 +8126,11 @@ function parseContent(text) {
|
|
|
8147
8126
|
const match = /^(\d+)(?:\s*;\s*url=(.*))?/i.exec(text);
|
|
8148
8127
|
if (match) {
|
|
8149
8128
|
return {
|
|
8150
|
-
delay:
|
|
8129
|
+
delay: Math.trunc(Number(match[1])),
|
|
8151
8130
|
url: match[2]
|
|
8152
8131
|
};
|
|
8153
|
-
} else {
|
|
8154
|
-
return null;
|
|
8155
8132
|
}
|
|
8133
|
+
return null;
|
|
8156
8134
|
}
|
|
8157
8135
|
|
|
8158
8136
|
class MissingDoctype extends Rule {
|
|
@@ -8229,7 +8207,7 @@ class NamePattern extends BasePatternRule {
|
|
|
8229
8207
|
});
|
|
8230
8208
|
}
|
|
8231
8209
|
static schema() {
|
|
8232
|
-
return
|
|
8210
|
+
return super.schema();
|
|
8233
8211
|
}
|
|
8234
8212
|
documentation(context) {
|
|
8235
8213
|
return {
|
|
@@ -8412,10 +8390,10 @@ class NoDeprecatedAttr extends Rule {
|
|
|
8412
8390
|
this.on("attr", (event) => {
|
|
8413
8391
|
const node = event.target;
|
|
8414
8392
|
const meta = node.meta;
|
|
8415
|
-
const attr = event.key.toLowerCase();
|
|
8416
8393
|
if (meta === null) {
|
|
8417
8394
|
return;
|
|
8418
8395
|
}
|
|
8396
|
+
const attr = event.key.toLowerCase();
|
|
8419
8397
|
const metaAttribute = meta.attributes[attr];
|
|
8420
8398
|
if (!metaAttribute) {
|
|
8421
8399
|
return;
|
|
@@ -8449,7 +8427,7 @@ class NoDupAttr extends Rule {
|
|
|
8449
8427
|
return;
|
|
8450
8428
|
}
|
|
8451
8429
|
const name = event.key.toLowerCase();
|
|
8452
|
-
if (name
|
|
8430
|
+
if (Object.hasOwn(attr, name)) {
|
|
8453
8431
|
this.report(event.target, `Attribute "${name}" duplicated`, event.keyLocation);
|
|
8454
8432
|
}
|
|
8455
8433
|
attr[event.key] = true;
|
|
@@ -8522,10 +8500,9 @@ function getExisting(element, root) {
|
|
|
8522
8500
|
const existing = group.cacheGet(CACHE_KEY);
|
|
8523
8501
|
if (existing) {
|
|
8524
8502
|
return existing;
|
|
8525
|
-
} else {
|
|
8526
|
-
const existing2 = /* @__PURE__ */ new Set();
|
|
8527
|
-
return group.cacheSet(CACHE_KEY, existing2);
|
|
8528
8503
|
}
|
|
8504
|
+
const value = /* @__PURE__ */ new Set();
|
|
8505
|
+
return group.cacheSet(CACHE_KEY, value);
|
|
8529
8506
|
}
|
|
8530
8507
|
|
|
8531
8508
|
function isRelevant$2(event) {
|
|
@@ -8796,10 +8773,11 @@ class NoMissingReferences extends Rule {
|
|
|
8796
8773
|
}
|
|
8797
8774
|
}
|
|
8798
8775
|
validateSingle(document, node, attr, id) {
|
|
8799
|
-
if (idMissing(document, id)) {
|
|
8800
|
-
|
|
8801
|
-
this.report(node, `Element references missing id "${id}"`, attr.valueLocation, context);
|
|
8776
|
+
if (!idMissing(document, id)) {
|
|
8777
|
+
return;
|
|
8802
8778
|
}
|
|
8779
|
+
const context = { key: attr.key, value: id };
|
|
8780
|
+
this.report(node, `Element references missing id "${id}"`, attr.valueLocation, context);
|
|
8803
8781
|
}
|
|
8804
8782
|
validateList(document, node, attr, values) {
|
|
8805
8783
|
const parsed = new DOMTokenList(values, attr.valueLocation);
|
|
@@ -8839,9 +8817,9 @@ class NoMultipleMain extends Rule {
|
|
|
8839
8817
|
const defaults$f = {
|
|
8840
8818
|
relaxed: false
|
|
8841
8819
|
};
|
|
8842
|
-
const textRegexp = /(<|&(?![\d#A-
|
|
8843
|
-
const unquotedAttrRegexp = /(["'<=>`]|&(?![\d#A-
|
|
8844
|
-
const matchTemplate = /^(
|
|
8820
|
+
const textRegexp = /(<|&(?![\d#A-Z]+;))/gi;
|
|
8821
|
+
const unquotedAttrRegexp = /(["'<=>`]|&(?![\d#A-Z]+;))/gi;
|
|
8822
|
+
const matchTemplate = /^(?:<%.*?%>|<\?.*?\?>|<\$.*?\$>)$/s;
|
|
8845
8823
|
const replacementTable = {
|
|
8846
8824
|
'"': """,
|
|
8847
8825
|
"&": "&",
|
|
@@ -9073,7 +9051,7 @@ class NoRedundantRole extends Rule {
|
|
|
9073
9051
|
}
|
|
9074
9052
|
}
|
|
9075
9053
|
|
|
9076
|
-
const xmlns = /^
|
|
9054
|
+
const xmlns = /^[^:]+:.+$/;
|
|
9077
9055
|
const defaults$d = {
|
|
9078
9056
|
ignoreForeign: true,
|
|
9079
9057
|
ignoreXML: true
|
|
@@ -9195,11 +9173,11 @@ class NoUnknownAttributes extends Rule {
|
|
|
9195
9173
|
this.on("attr", (event) => {
|
|
9196
9174
|
const node = event.target;
|
|
9197
9175
|
const meta = node.meta;
|
|
9198
|
-
const attr = event.key.toLowerCase();
|
|
9199
9176
|
if (meta === null) {
|
|
9200
9177
|
return;
|
|
9201
9178
|
}
|
|
9202
|
-
|
|
9179
|
+
const attr = event.key.toLowerCase();
|
|
9180
|
+
if (Object.hasOwn(meta.attributes, attr)) {
|
|
9203
9181
|
return;
|
|
9204
9182
|
}
|
|
9205
9183
|
if (isPatternAttribute(attr, meta.patternAttributes)) {
|
|
@@ -9606,7 +9584,7 @@ const defaults$7 = {
|
|
|
9606
9584
|
include: null,
|
|
9607
9585
|
exclude: null
|
|
9608
9586
|
};
|
|
9609
|
-
const crossorigin =
|
|
9587
|
+
const crossorigin = /^(?:\w+:\/\/|\/\/)/;
|
|
9610
9588
|
const supportSri = {
|
|
9611
9589
|
link: "href",
|
|
9612
9590
|
script: "src"
|
|
@@ -9819,7 +9797,10 @@ function constructRegex(characters) {
|
|
|
9819
9797
|
return new RegExp(pattern, "g");
|
|
9820
9798
|
}
|
|
9821
9799
|
function getText(node) {
|
|
9822
|
-
const match = /^(\s*)(.*)$/.exec(node.textContent);
|
|
9800
|
+
const match = /^(\s*)(\S.*)$/.exec(node.textContent);
|
|
9801
|
+
if (!match) {
|
|
9802
|
+
return [0, ""];
|
|
9803
|
+
}
|
|
9823
9804
|
const [, leading, text] = match;
|
|
9824
9805
|
return [leading.length, text.trimEnd()];
|
|
9825
9806
|
}
|
|
@@ -9972,9 +9953,8 @@ function hasDefaultText(node) {
|
|
|
9972
9953
|
function isNonEmptyText(node) {
|
|
9973
9954
|
if (isTextNode(node)) {
|
|
9974
9955
|
return node.isDynamic || node.textContent.trim() !== "";
|
|
9975
|
-
} else {
|
|
9976
|
-
return false;
|
|
9977
9956
|
}
|
|
9957
|
+
return false;
|
|
9978
9958
|
}
|
|
9979
9959
|
function haveAccessibleText(node) {
|
|
9980
9960
|
if (!inAccessibilityTree(node)) {
|
|
@@ -10109,15 +10089,14 @@ function getTextFromReference(document, id) {
|
|
|
10109
10089
|
const ref = document.querySelector(selector);
|
|
10110
10090
|
if (ref) {
|
|
10111
10091
|
return ref.textContent;
|
|
10112
|
-
} else {
|
|
10113
|
-
return selector;
|
|
10114
10092
|
}
|
|
10093
|
+
return selector;
|
|
10115
10094
|
}
|
|
10116
10095
|
function groupBy(values, callback) {
|
|
10117
10096
|
const result = {};
|
|
10118
10097
|
for (const value of values) {
|
|
10119
10098
|
const key = callback(value);
|
|
10120
|
-
if (key
|
|
10099
|
+
if (Object.hasOwn(result, key)) {
|
|
10121
10100
|
result[key].push(value);
|
|
10122
10101
|
} else {
|
|
10123
10102
|
result[key] = [value];
|
|
@@ -10217,7 +10196,7 @@ const defaults$5 = {
|
|
|
10217
10196
|
ignoreCase: false,
|
|
10218
10197
|
requireSemicolon: true
|
|
10219
10198
|
};
|
|
10220
|
-
const regexp$1 = /&(?:[\da-z]+|#x?[\da-f]+)(
|
|
10199
|
+
const regexp$1 = /&(?:[\da-z]+|#x?[\da-f]+)([^\da-z]|$)/gi;
|
|
10221
10200
|
const lowercaseEntities = entities$1.map((it) => it.toLowerCase());
|
|
10222
10201
|
function isNumerical(entity) {
|
|
10223
10202
|
return entity.startsWith("&#");
|
|
@@ -10296,9 +10275,8 @@ class UnknownCharReference extends Rule {
|
|
|
10296
10275
|
get entities() {
|
|
10297
10276
|
if (this.options.ignoreCase) {
|
|
10298
10277
|
return lowercaseEntities;
|
|
10299
|
-
} else {
|
|
10300
|
-
return entities$1;
|
|
10301
10278
|
}
|
|
10279
|
+
return entities$1;
|
|
10302
10280
|
}
|
|
10303
10281
|
findCharacterReferences(node, text, location, { isAttribute }) {
|
|
10304
10282
|
const delimiter = text.search(/[#?]/);
|
|
@@ -10664,7 +10642,6 @@ class ValidAutocomplete extends Rule {
|
|
|
10664
10642
|
}
|
|
10665
10643
|
validateControlAutocomplete(node, tokens, keyLocation) {
|
|
10666
10644
|
const type = node.getAttributeValue("type") ?? "text";
|
|
10667
|
-
const mantle = type !== "hidden" ? "expectation" : "anchor";
|
|
10668
10645
|
if (isDisallowedType(node, type)) {
|
|
10669
10646
|
const context = {
|
|
10670
10647
|
msg: 0 /* InvalidAttribute */,
|
|
@@ -10679,6 +10656,7 @@ class ValidAutocomplete extends Rule {
|
|
|
10679
10656
|
return;
|
|
10680
10657
|
}
|
|
10681
10658
|
if (tokens.includes("on") || tokens.includes("off")) {
|
|
10659
|
+
const mantle = type !== "hidden" ? "expectation" : "anchor";
|
|
10682
10660
|
this.validateOnOff(node, mantle, tokens);
|
|
10683
10661
|
return;
|
|
10684
10662
|
}
|
|
@@ -10802,44 +10780,46 @@ class ValidAutocomplete extends Rule {
|
|
|
10802
10780
|
* Ensure contact token is only used with field names from the second list.
|
|
10803
10781
|
*/
|
|
10804
10782
|
validateContact(node, tokens, order) {
|
|
10805
|
-
if (order.includes("contact")
|
|
10806
|
-
|
|
10807
|
-
|
|
10783
|
+
if (!order.includes("contact") || !order.includes("field1")) {
|
|
10784
|
+
return;
|
|
10785
|
+
}
|
|
10786
|
+
const a = order.indexOf("field1");
|
|
10787
|
+
const b = order.indexOf("contact");
|
|
10788
|
+
const context = {
|
|
10789
|
+
msg: 4 /* InvalidCombination */,
|
|
10790
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion -- it must be present of it wouldn't be found */
|
|
10791
|
+
first: tokens.item(a),
|
|
10792
|
+
second: tokens.item(b)
|
|
10793
|
+
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
10794
|
+
};
|
|
10795
|
+
this.report({
|
|
10796
|
+
node,
|
|
10797
|
+
message: getTerminalMessage(context),
|
|
10798
|
+
location: tokens.location(b),
|
|
10799
|
+
context
|
|
10800
|
+
});
|
|
10801
|
+
}
|
|
10802
|
+
validateOrder(node, tokens, order) {
|
|
10803
|
+
const indicies = order.map((it) => expectedOrder.indexOf(it));
|
|
10804
|
+
for (let i = 0; i < indicies.length - 1; i++) {
|
|
10805
|
+
if (indicies[0] <= indicies[i + 1]) {
|
|
10806
|
+
continue;
|
|
10807
|
+
}
|
|
10808
10808
|
const context = {
|
|
10809
|
-
msg:
|
|
10809
|
+
msg: 2 /* InvalidOrder */,
|
|
10810
10810
|
/* 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(
|
|
10811
|
+
first: tokens.item(i),
|
|
10812
|
+
second: tokens.item(i + 1)
|
|
10813
10813
|
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
10814
10814
|
};
|
|
10815
10815
|
this.report({
|
|
10816
10816
|
node,
|
|
10817
10817
|
message: getTerminalMessage(context),
|
|
10818
|
-
location: tokens.location(
|
|
10818
|
+
location: tokens.location(i + 1),
|
|
10819
10819
|
context
|
|
10820
10820
|
});
|
|
10821
10821
|
}
|
|
10822
10822
|
}
|
|
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
10823
|
validateControlGroup(node, tokens, fieldTokens) {
|
|
10844
10824
|
const numFields = fieldTokens.filter(Boolean).length;
|
|
10845
10825
|
if (numFields === 0) {
|
|
@@ -10931,7 +10911,7 @@ class ValidID extends Rule {
|
|
|
10931
10911
|
documentation(context) {
|
|
10932
10912
|
const { relaxed } = this.options;
|
|
10933
10913
|
const { kind, id } = context;
|
|
10934
|
-
const message = this.messages[kind].replace(`"{{ id }}"`, "`{{ id }}`").replace("id", "ID").replace(
|
|
10914
|
+
const message = this.messages[kind].replace(`"{{ id }}"`, "`{{ id }}`").replace("id", "ID").replace(/^./, (m) => m.toUpperCase());
|
|
10935
10915
|
const relaxedDescription = relaxed ? [] : [
|
|
10936
10916
|
" - ID must begin with a letter",
|
|
10937
10917
|
" - ID must only contain letters, digits, `-` and `_`"
|
|
@@ -10969,7 +10949,7 @@ class ValidID extends Rule {
|
|
|
10969
10949
|
if (relaxed) {
|
|
10970
10950
|
return;
|
|
10971
10951
|
}
|
|
10972
|
-
if (
|
|
10952
|
+
if (new RegExp("^\\P{L}", "u").test(value)) {
|
|
10973
10953
|
const context = { kind: 3 /* LEADING_CHARACTER */, id: value };
|
|
10974
10954
|
this.report(event.target, this.messages[context.kind], event.valueLocation, context);
|
|
10975
10955
|
return;
|
|
@@ -11330,7 +11310,7 @@ function isSimpleTable(table) {
|
|
|
11330
11310
|
return false;
|
|
11331
11311
|
}
|
|
11332
11312
|
const numColumns = cells[0].length;
|
|
11333
|
-
if (
|
|
11313
|
+
if (cells.some((row) => row.length !== numColumns)) {
|
|
11334
11314
|
return false;
|
|
11335
11315
|
}
|
|
11336
11316
|
const shape = getShape(cells);
|
|
@@ -11984,7 +11964,7 @@ class ResolvedConfig {
|
|
|
11984
11964
|
}
|
|
11985
11965
|
|
|
11986
11966
|
function haveResolver(key, value) {
|
|
11987
|
-
return key
|
|
11967
|
+
return Object.hasOwn(value, key);
|
|
11988
11968
|
}
|
|
11989
11969
|
function haveConfigResolver(value) {
|
|
11990
11970
|
return haveResolver("resolveConfig", value);
|
|
@@ -11999,7 +11979,10 @@ function haveTransformerResolver(value) {
|
|
|
11999
11979
|
return haveResolver("resolveTransformer", value);
|
|
12000
11980
|
}
|
|
12001
11981
|
function resolveConfig(resolvers, id, options) {
|
|
12002
|
-
for (const resolver of resolvers
|
|
11982
|
+
for (const resolver of resolvers) {
|
|
11983
|
+
if (!haveConfigResolver(resolver)) {
|
|
11984
|
+
continue;
|
|
11985
|
+
}
|
|
12003
11986
|
const config = resolver.resolveConfig(id, options);
|
|
12004
11987
|
if (isThenable(config)) {
|
|
12005
11988
|
return resolveConfigAsync(resolvers, id, options);
|
|
@@ -12011,7 +11994,10 @@ function resolveConfig(resolvers, id, options) {
|
|
|
12011
11994
|
throw new UserError(`Failed to load configuration from "${id}"`);
|
|
12012
11995
|
}
|
|
12013
11996
|
async function resolveConfigAsync(resolvers, id, options) {
|
|
12014
|
-
for (const resolver of resolvers
|
|
11997
|
+
for (const resolver of resolvers) {
|
|
11998
|
+
if (!haveConfigResolver(resolver)) {
|
|
11999
|
+
continue;
|
|
12000
|
+
}
|
|
12015
12001
|
const config = await resolver.resolveConfig(id, options);
|
|
12016
12002
|
if (config) {
|
|
12017
12003
|
return config;
|
|
@@ -12020,7 +12006,10 @@ async function resolveConfigAsync(resolvers, id, options) {
|
|
|
12020
12006
|
throw new UserError(`Failed to load configuration from "${id}"`);
|
|
12021
12007
|
}
|
|
12022
12008
|
function resolveElements(resolvers, id, options) {
|
|
12023
|
-
for (const resolver of resolvers
|
|
12009
|
+
for (const resolver of resolvers) {
|
|
12010
|
+
if (!haveElementsResolver(resolver)) {
|
|
12011
|
+
continue;
|
|
12012
|
+
}
|
|
12024
12013
|
const elements = resolver.resolveElements(id, options);
|
|
12025
12014
|
if (isThenable(elements)) {
|
|
12026
12015
|
return resolveElementsAsync(resolvers, id, options);
|
|
@@ -12032,7 +12021,10 @@ function resolveElements(resolvers, id, options) {
|
|
|
12032
12021
|
throw new UserError(`Failed to load elements from "${id}"`);
|
|
12033
12022
|
}
|
|
12034
12023
|
async function resolveElementsAsync(resolvers, id, options) {
|
|
12035
|
-
for (const resolver of resolvers
|
|
12024
|
+
for (const resolver of resolvers) {
|
|
12025
|
+
if (!haveElementsResolver(resolver)) {
|
|
12026
|
+
continue;
|
|
12027
|
+
}
|
|
12036
12028
|
const elements = await resolver.resolveElements(id, options);
|
|
12037
12029
|
if (elements) {
|
|
12038
12030
|
return elements;
|
|
@@ -12041,7 +12033,10 @@ async function resolveElementsAsync(resolvers, id, options) {
|
|
|
12041
12033
|
throw new UserError(`Failed to load elements from "${id}"`);
|
|
12042
12034
|
}
|
|
12043
12035
|
function resolvePlugin(resolvers, id, options) {
|
|
12044
|
-
for (const resolver of resolvers
|
|
12036
|
+
for (const resolver of resolvers) {
|
|
12037
|
+
if (!havePluginResolver(resolver)) {
|
|
12038
|
+
continue;
|
|
12039
|
+
}
|
|
12045
12040
|
const plugin = resolver.resolvePlugin(id, options);
|
|
12046
12041
|
if (isThenable(plugin)) {
|
|
12047
12042
|
return resolvePluginAsync(resolvers, id, options);
|
|
@@ -12053,7 +12048,10 @@ function resolvePlugin(resolvers, id, options) {
|
|
|
12053
12048
|
throw new UserError(`Failed to load plugin from "${id}"`);
|
|
12054
12049
|
}
|
|
12055
12050
|
async function resolvePluginAsync(resolvers, id, options) {
|
|
12056
|
-
for (const resolver of resolvers
|
|
12051
|
+
for (const resolver of resolvers) {
|
|
12052
|
+
if (!havePluginResolver(resolver)) {
|
|
12053
|
+
continue;
|
|
12054
|
+
}
|
|
12057
12055
|
const plugin = await resolver.resolvePlugin(id, options);
|
|
12058
12056
|
if (plugin) {
|
|
12059
12057
|
return plugin;
|
|
@@ -12062,7 +12060,10 @@ async function resolvePluginAsync(resolvers, id, options) {
|
|
|
12062
12060
|
throw new UserError(`Failed to load plugin from "${id}"`);
|
|
12063
12061
|
}
|
|
12064
12062
|
function resolveTransformer(resolvers, id, options) {
|
|
12065
|
-
for (const resolver of resolvers
|
|
12063
|
+
for (const resolver of resolvers) {
|
|
12064
|
+
if (!haveTransformerResolver(resolver)) {
|
|
12065
|
+
continue;
|
|
12066
|
+
}
|
|
12066
12067
|
const transformer = resolver.resolveTransformer(id, options);
|
|
12067
12068
|
if (isThenable(transformer)) {
|
|
12068
12069
|
return resolveTransformerAsync(resolvers, id, options);
|
|
@@ -12074,7 +12075,10 @@ function resolveTransformer(resolvers, id, options) {
|
|
|
12074
12075
|
throw new UserError(`Failed to load transformer from "${id}"`);
|
|
12075
12076
|
}
|
|
12076
12077
|
async function resolveTransformerAsync(resolvers, id, options) {
|
|
12077
|
-
for (const resolver of resolvers
|
|
12078
|
+
for (const resolver of resolvers) {
|
|
12079
|
+
if (!haveTransformerResolver(resolver)) {
|
|
12080
|
+
continue;
|
|
12081
|
+
}
|
|
12078
12082
|
const transformer = await resolver.resolveTransformer(id, options);
|
|
12079
12083
|
if (transformer) {
|
|
12080
12084
|
return transformer;
|
|
@@ -12114,9 +12118,12 @@ function staticResolver(map = {}) {
|
|
|
12114
12118
|
};
|
|
12115
12119
|
}
|
|
12116
12120
|
|
|
12117
|
-
const ajv =
|
|
12118
|
-
|
|
12119
|
-
|
|
12121
|
+
const ajv = (() => {
|
|
12122
|
+
const ajv2 = new Ajv({ strict: true, strictTuples: true, strictTypes: true });
|
|
12123
|
+
ajv2.addMetaSchema(ajvSchemaDraft);
|
|
12124
|
+
ajv2.addKeyword(ajvFunctionKeyword);
|
|
12125
|
+
return ajv2;
|
|
12126
|
+
})();
|
|
12120
12127
|
const validator = ajv.compile(configurationSchema);
|
|
12121
12128
|
function overwriteMerge(_a, b) {
|
|
12122
12129
|
return b;
|
|
@@ -12135,18 +12142,16 @@ function mergeInternal(base, rhs) {
|
|
|
12135
12142
|
function toArray$1(value) {
|
|
12136
12143
|
if (Array.isArray(value)) {
|
|
12137
12144
|
return value;
|
|
12138
|
-
} else {
|
|
12139
|
-
return [value];
|
|
12140
12145
|
}
|
|
12146
|
+
return [value];
|
|
12141
12147
|
}
|
|
12142
12148
|
function transformerEntries(transform) {
|
|
12143
12149
|
return Object.entries(transform).map(([pattern, value]) => {
|
|
12144
12150
|
const regex = new RegExp(pattern);
|
|
12145
12151
|
if (typeof value === "string") {
|
|
12146
12152
|
return { kind: "import", pattern: regex, name: value };
|
|
12147
|
-
} else {
|
|
12148
|
-
return { kind: "function", pattern: regex, function: value };
|
|
12149
12153
|
}
|
|
12154
|
+
return { kind: "function", pattern: regex, function: value };
|
|
12150
12155
|
});
|
|
12151
12156
|
}
|
|
12152
12157
|
class Config {
|
|
@@ -12171,8 +12176,8 @@ class Config {
|
|
|
12171
12176
|
* Create configuration from object.
|
|
12172
12177
|
*/
|
|
12173
12178
|
static fromObject(resolvers, options, filename = null) {
|
|
12174
|
-
|
|
12175
|
-
return
|
|
12179
|
+
this.validate(options, filename);
|
|
12180
|
+
return this.create(resolvers, options);
|
|
12176
12181
|
}
|
|
12177
12182
|
/**
|
|
12178
12183
|
* Read configuration from filename.
|
|
@@ -12186,10 +12191,9 @@ class Config {
|
|
|
12186
12191
|
static fromFile(resolvers, filename) {
|
|
12187
12192
|
const configData = resolveConfig(toArray$1(resolvers), filename, { cache: false });
|
|
12188
12193
|
if (isThenable(configData)) {
|
|
12189
|
-
return configData.then((configData2) =>
|
|
12190
|
-
} else {
|
|
12191
|
-
return Config.fromObject(resolvers, configData, filename);
|
|
12194
|
+
return configData.then((configData2) => this.fromObject(resolvers, configData2, filename));
|
|
12192
12195
|
}
|
|
12196
|
+
return this.fromObject(resolvers, configData, filename);
|
|
12193
12197
|
}
|
|
12194
12198
|
/**
|
|
12195
12199
|
* Validate configuration data.
|
|
@@ -12211,8 +12215,8 @@ class Config {
|
|
|
12211
12215
|
);
|
|
12212
12216
|
}
|
|
12213
12217
|
if (configData.rules) {
|
|
12214
|
-
const normalizedRules =
|
|
12215
|
-
for (const [ruleId, [, ruleOptions]] of normalizedRules
|
|
12218
|
+
const normalizedRules = this.getRulesObject(configData.rules);
|
|
12219
|
+
for (const [ruleId, [, ruleOptions]] of normalizedRules) {
|
|
12216
12220
|
const cls = bundledRules[ruleId];
|
|
12217
12221
|
const path = `/rules/${ruleId}/1`;
|
|
12218
12222
|
Rule.validateOptions(cls, ruleId, path, ruleOptions, filename, configData);
|
|
@@ -12235,9 +12239,8 @@ class Config {
|
|
|
12235
12239
|
return plugins.then((plugins2) => {
|
|
12236
12240
|
return instance.init(options, plugins2);
|
|
12237
12241
|
});
|
|
12238
|
-
} else {
|
|
12239
|
-
return instance.init(options, plugins);
|
|
12240
12242
|
}
|
|
12243
|
+
return instance.init(options, plugins);
|
|
12241
12244
|
}
|
|
12242
12245
|
init(options, plugins) {
|
|
12243
12246
|
this.plugins = plugins;
|
|
@@ -12254,9 +12257,8 @@ class Config {
|
|
|
12254
12257
|
const extendedConfig = this.extendConfig(this.config.extends ?? []);
|
|
12255
12258
|
if (isThenable(extendedConfig)) {
|
|
12256
12259
|
return extendedConfig.then((extended) => update(extended));
|
|
12257
|
-
} else {
|
|
12258
|
-
return update(extendedConfig);
|
|
12259
12260
|
}
|
|
12261
|
+
return update(extendedConfig);
|
|
12260
12262
|
}
|
|
12261
12263
|
/**
|
|
12262
12264
|
* @internal
|
|
@@ -12298,12 +12300,11 @@ class Config {
|
|
|
12298
12300
|
instance.extendMeta(instance.plugins);
|
|
12299
12301
|
return instance;
|
|
12300
12302
|
});
|
|
12301
|
-
} else {
|
|
12302
|
-
instance.plugins = plugins;
|
|
12303
|
-
instance.configurations = instance.loadConfigurations(instance.plugins);
|
|
12304
|
-
instance.extendMeta(instance.plugins);
|
|
12305
|
-
return instance;
|
|
12306
12303
|
}
|
|
12304
|
+
instance.plugins = plugins;
|
|
12305
|
+
instance.configurations = instance.loadConfigurations(instance.plugins);
|
|
12306
|
+
instance.extendMeta(instance.plugins);
|
|
12307
|
+
return instance;
|
|
12307
12308
|
}
|
|
12308
12309
|
extendConfig(entries) {
|
|
12309
12310
|
if (entries.length === 0) {
|
|
@@ -12359,20 +12360,19 @@ class Config {
|
|
|
12359
12360
|
const result = this.getElementsFromEntry(entry);
|
|
12360
12361
|
if (isThenable(result)) {
|
|
12361
12362
|
return result.then((result2) => {
|
|
12362
|
-
const [
|
|
12363
|
-
metaTable.loadFromObject(
|
|
12364
|
-
const
|
|
12365
|
-
if (
|
|
12366
|
-
return loadEntry(
|
|
12363
|
+
const [obj2, filename2] = result2;
|
|
12364
|
+
metaTable.loadFromObject(obj2, filename2);
|
|
12365
|
+
const next3 = source.shift();
|
|
12366
|
+
if (next3) {
|
|
12367
|
+
return loadEntry(next3);
|
|
12367
12368
|
}
|
|
12368
12369
|
});
|
|
12369
|
-
}
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12375
|
-
}
|
|
12370
|
+
}
|
|
12371
|
+
const [obj, filename] = result;
|
|
12372
|
+
metaTable.loadFromObject(obj, filename);
|
|
12373
|
+
const next2 = source.shift();
|
|
12374
|
+
if (next2) {
|
|
12375
|
+
return loadEntry(next2);
|
|
12376
12376
|
}
|
|
12377
12377
|
};
|
|
12378
12378
|
const next = source.shift();
|
|
@@ -12402,9 +12402,8 @@ class Config {
|
|
|
12402
12402
|
return obj.then((obj2) => {
|
|
12403
12403
|
return [obj2, entry];
|
|
12404
12404
|
});
|
|
12405
|
-
} else {
|
|
12406
|
-
return [obj, entry];
|
|
12407
12405
|
}
|
|
12406
|
+
return [obj, entry];
|
|
12408
12407
|
} catch (err) {
|
|
12409
12408
|
const message = err instanceof Error ? err.message : String(err);
|
|
12410
12409
|
throw new ConfigError(
|
|
@@ -12466,7 +12465,7 @@ class Config {
|
|
|
12466
12465
|
const loadPlugin = (entry, index) => {
|
|
12467
12466
|
if (typeof entry !== "string") {
|
|
12468
12467
|
const plugin = entry;
|
|
12469
|
-
plugin.name
|
|
12468
|
+
plugin.name ||= `:unnamedPlugin@${String(index + 1)}`;
|
|
12470
12469
|
plugin.originalName = `:unnamedPlugin@${String(index + 1)}`;
|
|
12471
12470
|
loaded.push(plugin);
|
|
12472
12471
|
const next2 = loading.shift();
|
|
@@ -12478,22 +12477,21 @@ class Config {
|
|
|
12478
12477
|
const plugin = resolvePlugin(this.resolvers, entry, { cache: true });
|
|
12479
12478
|
if (isThenable(plugin)) {
|
|
12480
12479
|
return plugin.then((plugin2) => {
|
|
12481
|
-
plugin2.name
|
|
12480
|
+
plugin2.name ||= entry;
|
|
12482
12481
|
plugin2.originalName = entry;
|
|
12483
12482
|
loaded.push(plugin2);
|
|
12484
|
-
const
|
|
12485
|
-
if (
|
|
12486
|
-
return loadPlugin(
|
|
12483
|
+
const next3 = loading.shift();
|
|
12484
|
+
if (next3) {
|
|
12485
|
+
return loadPlugin(next3, index + 1);
|
|
12487
12486
|
}
|
|
12488
12487
|
});
|
|
12489
|
-
}
|
|
12490
|
-
|
|
12491
|
-
|
|
12492
|
-
|
|
12493
|
-
|
|
12494
|
-
|
|
12495
|
-
|
|
12496
|
-
}
|
|
12488
|
+
}
|
|
12489
|
+
plugin.name ||= entry;
|
|
12490
|
+
plugin.originalName = entry;
|
|
12491
|
+
loaded.push(plugin);
|
|
12492
|
+
const next2 = loading.shift();
|
|
12493
|
+
if (next2) {
|
|
12494
|
+
return loadPlugin(next2, index + 1);
|
|
12497
12495
|
}
|
|
12498
12496
|
} catch (err) {
|
|
12499
12497
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -12519,7 +12517,8 @@ class Config {
|
|
|
12519
12517
|
configs.set(name, config);
|
|
12520
12518
|
}
|
|
12521
12519
|
for (const plugin of plugins) {
|
|
12522
|
-
|
|
12520
|
+
const entries = Object.entries(plugin.configs ?? {});
|
|
12521
|
+
for (const [name, config] of entries) {
|
|
12523
12522
|
if (!config) {
|
|
12524
12523
|
continue;
|
|
12525
12524
|
}
|
|
@@ -12563,9 +12562,8 @@ class Config {
|
|
|
12563
12562
|
return resolveData.then((resolveData2) => {
|
|
12564
12563
|
return new ResolvedConfig(resolveData2, this.get());
|
|
12565
12564
|
});
|
|
12566
|
-
} else {
|
|
12567
|
-
return new ResolvedConfig(resolveData, this.get());
|
|
12568
12565
|
}
|
|
12566
|
+
return new ResolvedConfig(resolveData, this.get());
|
|
12569
12567
|
}
|
|
12570
12568
|
/**
|
|
12571
12569
|
* Same as [[resolve]] but returns the raw configuration data instead of
|
|
@@ -12584,14 +12582,13 @@ class Config {
|
|
|
12584
12582
|
transformers: this.transformers
|
|
12585
12583
|
};
|
|
12586
12584
|
});
|
|
12587
|
-
} else {
|
|
12588
|
-
return {
|
|
12589
|
-
metaTable,
|
|
12590
|
-
plugins: this.getPlugins(),
|
|
12591
|
-
rules: this.getRules(),
|
|
12592
|
-
transformers: this.transformers
|
|
12593
|
-
};
|
|
12594
12585
|
}
|
|
12586
|
+
return {
|
|
12587
|
+
metaTable,
|
|
12588
|
+
plugins: this.getPlugins(),
|
|
12589
|
+
rules: this.getRules(),
|
|
12590
|
+
transformers: this.transformers
|
|
12591
|
+
};
|
|
12595
12592
|
}
|
|
12596
12593
|
}
|
|
12597
12594
|
|
|
@@ -12635,10 +12632,9 @@ class ConfigLoader {
|
|
|
12635
12632
|
this._globalConfig = config2;
|
|
12636
12633
|
return this._globalConfig;
|
|
12637
12634
|
});
|
|
12638
|
-
} else {
|
|
12639
|
-
this._globalConfig = config;
|
|
12640
|
-
return this._globalConfig;
|
|
12641
12635
|
}
|
|
12636
|
+
this._globalConfig = config;
|
|
12637
|
+
return this._globalConfig;
|
|
12642
12638
|
}
|
|
12643
12639
|
/**
|
|
12644
12640
|
* Get the global configuration.
|
|
@@ -12720,9 +12716,8 @@ class StaticConfigLoader extends ConfigLoader {
|
|
|
12720
12716
|
const override = this.loadFromObject(configOverride ?? {});
|
|
12721
12717
|
if (isThenable(override)) {
|
|
12722
12718
|
return override.then((override2) => this._resolveConfig(override2));
|
|
12723
|
-
} else {
|
|
12724
|
-
return this._resolveConfig(override);
|
|
12725
12719
|
}
|
|
12720
|
+
return this._resolveConfig(override);
|
|
12726
12721
|
}
|
|
12727
12722
|
flushCache() {
|
|
12728
12723
|
}
|
|
@@ -12739,25 +12734,22 @@ class StaticConfigLoader extends ConfigLoader {
|
|
|
12739
12734
|
const globalConfig = this.getGlobalConfig();
|
|
12740
12735
|
if (isThenable(globalConfig)) {
|
|
12741
12736
|
return globalConfig.then((globalConfig2) => {
|
|
12742
|
-
const
|
|
12743
|
-
if (isThenable(
|
|
12744
|
-
return
|
|
12745
|
-
return
|
|
12737
|
+
const merged2 = globalConfig2.merge(this.resolvers, override);
|
|
12738
|
+
if (isThenable(merged2)) {
|
|
12739
|
+
return merged2.then((merged3) => {
|
|
12740
|
+
return merged3.resolve();
|
|
12746
12741
|
});
|
|
12747
|
-
} else {
|
|
12748
|
-
return merged.resolve();
|
|
12749
12742
|
}
|
|
12743
|
+
return merged2.resolve();
|
|
12744
|
+
});
|
|
12745
|
+
}
|
|
12746
|
+
const merged = globalConfig.merge(this.resolvers, override);
|
|
12747
|
+
if (isThenable(merged)) {
|
|
12748
|
+
return merged.then((merged2) => {
|
|
12749
|
+
return merged2.resolve();
|
|
12750
12750
|
});
|
|
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
12751
|
}
|
|
12752
|
+
return merged.resolve();
|
|
12761
12753
|
}
|
|
12762
12754
|
}
|
|
12763
12755
|
|
|
@@ -12844,7 +12836,7 @@ class EventHandler {
|
|
|
12844
12836
|
}
|
|
12845
12837
|
|
|
12846
12838
|
const name = "html-validate";
|
|
12847
|
-
const version = "11.5.
|
|
12839
|
+
const version = "11.5.5";
|
|
12848
12840
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
12849
12841
|
|
|
12850
12842
|
function freeze(src) {
|
|
@@ -12882,7 +12874,7 @@ class Reporter {
|
|
|
12882
12874
|
for (const report of reports) {
|
|
12883
12875
|
for (const result of report.results) {
|
|
12884
12876
|
const key = result.filePath;
|
|
12885
|
-
if (key
|
|
12877
|
+
if (Object.hasOwn(merged, key)) {
|
|
12886
12878
|
merged[key].messages = [...merged[key].messages, ...result.messages];
|
|
12887
12879
|
} else {
|
|
12888
12880
|
merged[key] = { ...result };
|
|
@@ -12906,7 +12898,7 @@ class Reporter {
|
|
|
12906
12898
|
*/
|
|
12907
12899
|
add(options) {
|
|
12908
12900
|
const { rule, message, severity, node, location, context } = options;
|
|
12909
|
-
if (!(location.filename
|
|
12901
|
+
if (!Object.hasOwn(this.result, location.filename)) {
|
|
12910
12902
|
this.result[location.filename] = [];
|
|
12911
12903
|
}
|
|
12912
12904
|
const ruleUrl = rule.documentation(context)?.url;
|
|
@@ -12934,7 +12926,7 @@ class Reporter {
|
|
|
12934
12926
|
* @internal
|
|
12935
12927
|
*/
|
|
12936
12928
|
addManual(filename, message) {
|
|
12937
|
-
if (!(
|
|
12929
|
+
if (!Object.hasOwn(this.result, filename)) {
|
|
12938
12930
|
this.result[filename] = [];
|
|
12939
12931
|
}
|
|
12940
12932
|
this.result[filename].push(message);
|
|
@@ -12945,6 +12937,7 @@ class Reporter {
|
|
|
12945
12937
|
save(sources) {
|
|
12946
12938
|
const report = {
|
|
12947
12939
|
valid: this.isValid(),
|
|
12940
|
+
/* eslint-disable-next-line unicorn/prefer-object-iterable-methods -- technical debt */
|
|
12948
12941
|
results: Object.keys(this.result).map((filePath) => {
|
|
12949
12942
|
const messages = Array.from(this.result[filePath], freeze).toSorted(messageSort);
|
|
12950
12943
|
const source = (sources ?? []).find((source2) => filePath === source2.filename);
|
|
@@ -13009,7 +13002,7 @@ function definePlugin(plugin) {
|
|
|
13009
13002
|
return plugin;
|
|
13010
13003
|
}
|
|
13011
13004
|
|
|
13012
|
-
const regexp = /<!(?:--)?\[(.*?)](?:--)?>/g;
|
|
13005
|
+
const regexp = /<!(?:--)?\[(.*?)\](?:--)?>/g;
|
|
13013
13006
|
function* parseConditionalComment(comment, commentLocation) {
|
|
13014
13007
|
let match;
|
|
13015
13008
|
while ((match = regexp.exec(comment)) !== null) {
|
|
@@ -13026,6 +13019,7 @@ function* parseConditionalComment(comment, commentLocation) {
|
|
|
13026
13019
|
|
|
13027
13020
|
class ParserError extends Error {
|
|
13028
13021
|
location;
|
|
13022
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
13029
13023
|
constructor(location, message) {
|
|
13030
13024
|
super(message);
|
|
13031
13025
|
this.name = "ParserError";
|
|
@@ -13189,9 +13183,8 @@ class Parser {
|
|
|
13189
13183
|
const open = !token.data[1];
|
|
13190
13184
|
if (open) {
|
|
13191
13185
|
return this.wouldCloseElement(token, active);
|
|
13192
|
-
} else {
|
|
13193
|
-
return this.closeOptionalEndTag(token, active);
|
|
13194
13186
|
}
|
|
13187
|
+
return this.closeOptionalEndTag(token, active);
|
|
13195
13188
|
}
|
|
13196
13189
|
/**
|
|
13197
13190
|
* Returns `true` if the element’s end tag may be omitted, either because
|
|
@@ -13543,9 +13536,8 @@ class Parser {
|
|
|
13543
13536
|
const quote = token.data[3];
|
|
13544
13537
|
if (quote) {
|
|
13545
13538
|
return sliceLocation(token.location, 2, -1);
|
|
13546
|
-
} else {
|
|
13547
|
-
return sliceLocation(token.location, 1);
|
|
13548
13539
|
}
|
|
13540
|
+
return sliceLocation(token.location, 1);
|
|
13549
13541
|
}
|
|
13550
13542
|
/**
|
|
13551
13543
|
* Take attribute key and value token an returns a new location referring to
|
|
@@ -13833,13 +13825,14 @@ class PerformanceTracker {
|
|
|
13833
13825
|
*/
|
|
13834
13826
|
getResult() {
|
|
13835
13827
|
const events = Array.from(
|
|
13836
|
-
this.eventData
|
|
13828
|
+
this.eventData,
|
|
13837
13829
|
([event, { count, time }]) => ({ event, count, time })
|
|
13838
13830
|
).toSorted((a, b) => b.time - a.time);
|
|
13839
|
-
const rules = Array.from(
|
|
13840
|
-
|
|
13841
|
-
|
|
13842
|
-
|
|
13831
|
+
const rules = Array.from(this.ruleData, ([rule, { count, time }]) => ({
|
|
13832
|
+
rule,
|
|
13833
|
+
count,
|
|
13834
|
+
time
|
|
13835
|
+
})).toSorted((a, b) => b.time - a.time);
|
|
13843
13836
|
return {
|
|
13844
13837
|
events,
|
|
13845
13838
|
rules,
|
|
@@ -13886,9 +13879,11 @@ function dumpTree(root) {
|
|
|
13886
13879
|
return lines;
|
|
13887
13880
|
}
|
|
13888
13881
|
|
|
13889
|
-
|
|
13882
|
+
const state = {
|
|
13883
|
+
blockerCounter: 1
|
|
13884
|
+
};
|
|
13890
13885
|
function createBlocker() {
|
|
13891
|
-
const id = blockerCounter++;
|
|
13886
|
+
const id = state.blockerCounter++;
|
|
13892
13887
|
return id;
|
|
13893
13888
|
}
|
|
13894
13889
|
|
|
@@ -14024,9 +14019,8 @@ class Engine {
|
|
|
14024
14019
|
const [, options] = ruleData;
|
|
14025
14020
|
const rule = this.instantiateRule(ruleId, options);
|
|
14026
14021
|
return rule.documentation(context);
|
|
14027
|
-
} else {
|
|
14028
|
-
return null;
|
|
14029
14022
|
}
|
|
14023
|
+
return null;
|
|
14030
14024
|
}
|
|
14031
14025
|
/**
|
|
14032
14026
|
* Create a new parser instance with the current configuration.
|
|
@@ -14155,7 +14149,8 @@ class Engine {
|
|
|
14155
14149
|
initRules(config) {
|
|
14156
14150
|
const availableRules = {};
|
|
14157
14151
|
for (const plugin of config.getPlugins()) {
|
|
14158
|
-
|
|
14152
|
+
const entries = Object.entries(plugin.rules ?? {});
|
|
14153
|
+
for (const [name, rule] of entries) {
|
|
14159
14154
|
if (!rule) {
|
|
14160
14155
|
continue;
|
|
14161
14156
|
}
|
|
@@ -14183,7 +14178,7 @@ class Engine {
|
|
|
14183
14178
|
*/
|
|
14184
14179
|
setupRules(config, parser) {
|
|
14185
14180
|
const rules = {};
|
|
14186
|
-
for (const [ruleId, [severity, options]] of config.getRules()
|
|
14181
|
+
for (const [ruleId, [severity, options]] of config.getRules()) {
|
|
14187
14182
|
rules[ruleId] = this.loadRule(ruleId, config, severity, options, parser, this.report);
|
|
14188
14183
|
}
|
|
14189
14184
|
return rules;
|
|
@@ -14207,9 +14202,8 @@ class Engine {
|
|
|
14207
14202
|
if (this.availableRules[name]) {
|
|
14208
14203
|
const RuleConstructor = this.availableRules[name];
|
|
14209
14204
|
return new RuleConstructor(options);
|
|
14210
|
-
} else {
|
|
14211
|
-
return this.missingRule(name);
|
|
14212
14205
|
}
|
|
14206
|
+
return this.missingRule(name);
|
|
14213
14207
|
}
|
|
14214
14208
|
missingRule(name) {
|
|
14215
14209
|
return new class MissingRule extends Rule {
|
|
@@ -14305,34 +14299,30 @@ function getTransformerFunction(resolvers, name, plugins) {
|
|
|
14305
14299
|
validateTransformer(transformer2);
|
|
14306
14300
|
return transformer2;
|
|
14307
14301
|
});
|
|
14308
|
-
} else {
|
|
14309
|
-
validateTransformer(transformer);
|
|
14310
|
-
return transformer;
|
|
14311
14302
|
}
|
|
14303
|
+
validateTransformer(transformer);
|
|
14304
|
+
return transformer;
|
|
14312
14305
|
} catch (err) {
|
|
14313
14306
|
if (err instanceof ConfigError) {
|
|
14314
14307
|
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
14308
|
}
|
|
14309
|
+
throw new ConfigError(`Failed to load transformer "${name}"`, ensureError(err));
|
|
14318
14310
|
}
|
|
14319
14311
|
}
|
|
14320
14312
|
function getCachedTransformerFunction(cache, resolvers, name, plugins) {
|
|
14321
14313
|
const cached = cache.get(name);
|
|
14322
14314
|
if (cached) {
|
|
14323
14315
|
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
14316
|
}
|
|
14317
|
+
const transformer = getTransformerFunction(resolvers, name, plugins);
|
|
14318
|
+
if (isThenable(transformer)) {
|
|
14319
|
+
return transformer.then((transformer2) => {
|
|
14320
|
+
cache.set(name, transformer2);
|
|
14321
|
+
return transformer2;
|
|
14322
|
+
});
|
|
14323
|
+
}
|
|
14324
|
+
cache.set(name, transformer);
|
|
14325
|
+
return transformer;
|
|
14336
14326
|
}
|
|
14337
14327
|
|
|
14338
14328
|
function isIterable(value) {
|
|
@@ -14348,6 +14338,9 @@ const asyncInSyncTransformError = "Cannot use async transformer from sync functi
|
|
|
14348
14338
|
async function transformSource(resolvers, config, source, filename) {
|
|
14349
14339
|
const { cache } = config;
|
|
14350
14340
|
const transformer = config.findTransformer(filename ?? source.filename);
|
|
14341
|
+
if (!transformer) {
|
|
14342
|
+
return [source];
|
|
14343
|
+
}
|
|
14351
14344
|
const context = {
|
|
14352
14345
|
hasChain(filename2) {
|
|
14353
14346
|
return config.canTransform(filename2);
|
|
@@ -14356,9 +14349,6 @@ async function transformSource(resolvers, config, source, filename) {
|
|
|
14356
14349
|
return transformSource(resolvers, config, source2, filename2);
|
|
14357
14350
|
}
|
|
14358
14351
|
};
|
|
14359
|
-
if (!transformer) {
|
|
14360
|
-
return [source];
|
|
14361
|
-
}
|
|
14362
14352
|
const fn = transformer.kind === "import" ? await getCachedTransformerFunction(cache, resolvers, transformer.name, config.getPlugins()) : transformer.function;
|
|
14363
14353
|
const name = transformer.kind === "import" ? transformer.name : transformer.function.name;
|
|
14364
14354
|
try {
|
|
@@ -14377,6 +14367,9 @@ async function transformSource(resolvers, config, source, filename) {
|
|
|
14377
14367
|
function transformSourceSync(resolvers, config, source, filename) {
|
|
14378
14368
|
const { cache } = config;
|
|
14379
14369
|
const transformer = config.findTransformer(filename ?? source.filename);
|
|
14370
|
+
if (!transformer) {
|
|
14371
|
+
return [source];
|
|
14372
|
+
}
|
|
14380
14373
|
const context = {
|
|
14381
14374
|
hasChain(filename2) {
|
|
14382
14375
|
return config.canTransform(filename2);
|
|
@@ -14385,14 +14378,11 @@ function transformSourceSync(resolvers, config, source, filename) {
|
|
|
14385
14378
|
return transformSourceSync(resolvers, config, source2, filename2);
|
|
14386
14379
|
}
|
|
14387
14380
|
};
|
|
14388
|
-
if (!transformer) {
|
|
14389
|
-
return [source];
|
|
14390
|
-
}
|
|
14391
14381
|
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
14382
|
if (isThenable(fn)) {
|
|
14394
14383
|
throw new UserError(asyncInSyncTransformError);
|
|
14395
14384
|
}
|
|
14385
|
+
const name = transformer.kind === "import" ? transformer.name : transformer.function.name;
|
|
14396
14386
|
try {
|
|
14397
14387
|
const result = fn.call(context, source);
|
|
14398
14388
|
if (isThenable(result)) {
|
|
@@ -14494,7 +14484,7 @@ function checkstyleFormatter(results) {
|
|
|
14494
14484
|
`;
|
|
14495
14485
|
for (const message of messages) {
|
|
14496
14486
|
const ruleId = xmlescape(`htmlvalidate.rules.${message.ruleId}`);
|
|
14497
|
-
output += "
|
|
14487
|
+
output += " ".repeat(4);
|
|
14498
14488
|
output += [
|
|
14499
14489
|
`<error line="${xmlescape(message.line)}"`,
|
|
14500
14490
|
`column="${xmlescape(message.column)}"`,
|
|
@@ -14581,9 +14571,8 @@ function codeFrameColumns(rawLines, loc) {
|
|
|
14581
14571
|
].join("");
|
|
14582
14572
|
}
|
|
14583
14573
|
return [">", gutter, line.length > 0 ? ` ${line}` : "", markerLine].join("");
|
|
14584
|
-
} else {
|
|
14585
|
-
return [" ", gutter, line.length > 0 ? ` ${line}` : ""].join("");
|
|
14586
14574
|
}
|
|
14575
|
+
return [" ", gutter, line.length > 0 ? ` ${line}` : ""].join("");
|
|
14587
14576
|
}).join("\n");
|
|
14588
14577
|
}
|
|
14589
14578
|
|