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/cjs/core.js
CHANGED
|
@@ -397,11 +397,11 @@ var deepmerge = /*@__PURE__*/getDefaultExportFromCjs(cjsExports);
|
|
|
397
397
|
function stringify(value) {
|
|
398
398
|
if (typeof value === "string") {
|
|
399
399
|
return value;
|
|
400
|
-
} else {
|
|
401
|
-
return JSON.stringify(value);
|
|
402
400
|
}
|
|
401
|
+
return JSON.stringify(value);
|
|
403
402
|
}
|
|
404
403
|
class WrappedError extends Error {
|
|
404
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
405
405
|
constructor(message) {
|
|
406
406
|
super(stringify(message));
|
|
407
407
|
this.name = "WrappedError";
|
|
@@ -411,12 +411,12 @@ class WrappedError extends Error {
|
|
|
411
411
|
function ensureError(value) {
|
|
412
412
|
if (value instanceof Error) {
|
|
413
413
|
return value;
|
|
414
|
-
} else {
|
|
415
|
-
return new WrappedError(value);
|
|
416
414
|
}
|
|
415
|
+
return new WrappedError(value);
|
|
417
416
|
}
|
|
418
417
|
|
|
419
418
|
class NestedError extends Error {
|
|
419
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
420
420
|
constructor(message, nested) {
|
|
421
421
|
super(message);
|
|
422
422
|
this.name = "NestedError";
|
|
@@ -429,6 +429,7 @@ Caused by: ${nested.stack}`;
|
|
|
429
429
|
}
|
|
430
430
|
|
|
431
431
|
class UserError extends NestedError {
|
|
432
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
432
433
|
constructor(message, nested) {
|
|
433
434
|
super(message, nested);
|
|
434
435
|
this.name = "UserError";
|
|
@@ -1129,11 +1130,11 @@ const CONTROL_ESCAPES = /* @__PURE__ */ new Map([
|
|
|
1129
1130
|
["\r", "r"]
|
|
1130
1131
|
]);
|
|
1131
1132
|
const OTHER_PUNCTUATORS = /^[!"#%&',:;<=>@`~-]$/;
|
|
1132
|
-
const WHITE_SPACE = /^[\t\v\f\
|
|
1133
|
+
const WHITE_SPACE = /^[\t\v\f\u{FEFF}\p{Zs}]$/u;
|
|
1133
1134
|
const LINE_TERMINATOR = /^[\n\r\u2028\u2029]$/;
|
|
1134
1135
|
const SURROGATE = /^[\uD800-\uDFFF]$/;
|
|
1135
1136
|
function isDecimalDigitOrASCIILetter(ch) {
|
|
1136
|
-
return /^[\dA-
|
|
1137
|
+
return /^[\dA-Z]$/i.test(ch);
|
|
1137
1138
|
}
|
|
1138
1139
|
function needEscape(ch) {
|
|
1139
1140
|
return OTHER_PUNCTUATORS.test(ch) || WHITE_SPACE.test(ch) || LINE_TERMINATOR.test(ch) || SURROGATE.test(ch);
|
|
@@ -1201,9 +1202,8 @@ function migrateSingleAttribute(src, key) {
|
|
|
1201
1202
|
}
|
|
1202
1203
|
}
|
|
1203
1204
|
return stripUndefined(result);
|
|
1204
|
-
} else {
|
|
1205
|
-
return stripUndefined({ ...result, ...attr });
|
|
1206
1205
|
}
|
|
1206
|
+
return stripUndefined({ ...result, ...attr });
|
|
1207
1207
|
}
|
|
1208
1208
|
function isPatternAttribute$1(key) {
|
|
1209
1209
|
return key.includes("*");
|
|
@@ -1217,7 +1217,7 @@ function migrateAttributes(src) {
|
|
|
1217
1217
|
...Object.keys(src.attributes ?? {}),
|
|
1218
1218
|
...src.requiredAttributes ?? [],
|
|
1219
1219
|
...src.deprecatedAttributes ?? []
|
|
1220
|
-
].filter((key) => !isPatternAttribute$1(key)).toSorted();
|
|
1220
|
+
].filter((key) => !isPatternAttribute$1(key)).toSorted((a, b) => a.localeCompare(b));
|
|
1221
1221
|
const entries = keys.map((key) => {
|
|
1222
1222
|
return [key, migrateSingleAttribute(src, key)];
|
|
1223
1223
|
});
|
|
@@ -1297,11 +1297,10 @@ const dynamicKeys = [
|
|
|
1297
1297
|
];
|
|
1298
1298
|
const schemaCache = /* @__PURE__ */ new Map();
|
|
1299
1299
|
function clone(value) {
|
|
1300
|
-
if (globalThis
|
|
1301
|
-
return
|
|
1302
|
-
} else {
|
|
1303
|
-
return JSON.parse(JSON.stringify(value));
|
|
1300
|
+
if (Object.hasOwn(globalThis, "structuredClone")) {
|
|
1301
|
+
return structuredClone(value);
|
|
1304
1302
|
}
|
|
1303
|
+
return JSON.parse(JSON.stringify(value));
|
|
1305
1304
|
}
|
|
1306
1305
|
class MetaTable {
|
|
1307
1306
|
elements;
|
|
@@ -1391,9 +1390,8 @@ class MetaTable {
|
|
|
1391
1390
|
const meta = this.elements[tagName.toLowerCase()] ?? this.elements["*"];
|
|
1392
1391
|
if (meta) {
|
|
1393
1392
|
return { ...meta };
|
|
1394
|
-
} else {
|
|
1395
|
-
return null;
|
|
1396
1393
|
}
|
|
1394
|
+
return null;
|
|
1397
1395
|
}
|
|
1398
1396
|
/**
|
|
1399
1397
|
* Find all tags which has enabled given property.
|
|
@@ -1435,16 +1433,15 @@ class MetaTable {
|
|
|
1435
1433
|
const cached = schemaCache.get(hash);
|
|
1436
1434
|
if (cached) {
|
|
1437
1435
|
return cached;
|
|
1438
|
-
} else {
|
|
1439
|
-
const ajv = new Ajv__default.default({ strict: true, strictTuples: true, strictTypes: true });
|
|
1440
|
-
ajv.addMetaSchema(ajvSchemaDraft);
|
|
1441
|
-
ajv.addKeyword(ajvFunctionKeyword);
|
|
1442
|
-
ajv.addKeyword(ajvRegexpKeyword);
|
|
1443
|
-
ajv.addKeyword({ keyword: "copyable" });
|
|
1444
|
-
const validate = ajv.compile(this.schema);
|
|
1445
|
-
schemaCache.set(hash, validate);
|
|
1446
|
-
return validate;
|
|
1447
1436
|
}
|
|
1437
|
+
const ajv = new Ajv__default.default({ strict: true, strictTuples: true, strictTypes: true });
|
|
1438
|
+
ajv.addMetaSchema(ajvSchemaDraft);
|
|
1439
|
+
ajv.addKeyword(ajvFunctionKeyword);
|
|
1440
|
+
ajv.addKeyword(ajvRegexpKeyword);
|
|
1441
|
+
ajv.addKeyword({ keyword: "copyable" });
|
|
1442
|
+
const validate = ajv.compile(this.schema);
|
|
1443
|
+
schemaCache.set(hash, validate);
|
|
1444
|
+
return validate;
|
|
1448
1445
|
}
|
|
1449
1446
|
/**
|
|
1450
1447
|
* @public
|
|
@@ -1526,14 +1523,13 @@ function expandProperties(node, entry) {
|
|
|
1526
1523
|
}
|
|
1527
1524
|
}
|
|
1528
1525
|
function compileRegexString(value) {
|
|
1529
|
-
const match = /^\/(.*
|
|
1526
|
+
const match = /^\/(.*)\/(i?)$/.exec(value);
|
|
1530
1527
|
if (match) {
|
|
1531
1528
|
const [, expr, flags] = match;
|
|
1532
1529
|
if (expr.startsWith("^") || expr.endsWith("$")) {
|
|
1533
1530
|
return new RegExp(expr, flags);
|
|
1534
|
-
} else {
|
|
1535
|
-
return new RegExp(`^${expr}$`, flags);
|
|
1536
1531
|
}
|
|
1532
|
+
return new RegExp(`^${expr}$`, flags);
|
|
1537
1533
|
}
|
|
1538
1534
|
return null;
|
|
1539
1535
|
}
|
|
@@ -1594,7 +1590,7 @@ class Attribute {
|
|
|
1594
1590
|
* @param keyLocation - Source location of attribute name.
|
|
1595
1591
|
* @param valueLocation - Source location of attribute value.
|
|
1596
1592
|
* @param originalAttribute - If this attribute was dynamically added via a
|
|
1597
|
-
* transformation (e.g.
|
|
1593
|
+
* transformation (e.g. Vue.js `:id` generating the `id` attribute) this
|
|
1598
1594
|
* parameter should be set to the attribute name of the source attribute (`:id`).
|
|
1599
1595
|
*/
|
|
1600
1596
|
constructor(key, value, keyLocation, valueLocation, originalAttribute) {
|
|
@@ -1638,9 +1634,8 @@ class Attribute {
|
|
|
1638
1634
|
}
|
|
1639
1635
|
if (pattern instanceof RegExp) {
|
|
1640
1636
|
return this.value.match(pattern) !== null;
|
|
1641
|
-
} else {
|
|
1642
|
-
return this.value === pattern;
|
|
1643
1637
|
}
|
|
1638
|
+
return this.value === pattern;
|
|
1644
1639
|
}
|
|
1645
1640
|
}
|
|
1646
1641
|
|
|
@@ -1716,7 +1711,9 @@ const Node = {
|
|
|
1716
1711
|
|
|
1717
1712
|
const DOCUMENT_NODE_NAME = "#document";
|
|
1718
1713
|
const TEXT_CONTENT = /* @__PURE__ */ Symbol("textContent");
|
|
1719
|
-
|
|
1714
|
+
const state$1 = {
|
|
1715
|
+
counter: 0
|
|
1716
|
+
};
|
|
1720
1717
|
class DOMNode {
|
|
1721
1718
|
nodeName;
|
|
1722
1719
|
nodeType;
|
|
@@ -1755,7 +1752,7 @@ class DOMNode {
|
|
|
1755
1752
|
this.disabledRules = /* @__PURE__ */ new Set();
|
|
1756
1753
|
this.blockedRules = /* @__PURE__ */ new Map();
|
|
1757
1754
|
this.childNodes = [];
|
|
1758
|
-
this.unique = counter++;
|
|
1755
|
+
this.unique = state$1.counter++;
|
|
1759
1756
|
this.cache = null;
|
|
1760
1757
|
}
|
|
1761
1758
|
/**
|
|
@@ -1771,9 +1768,8 @@ class DOMNode {
|
|
|
1771
1768
|
cacheGet(key) {
|
|
1772
1769
|
if (this.cache) {
|
|
1773
1770
|
return this.cache.get(key);
|
|
1774
|
-
} else {
|
|
1775
|
-
return void 0;
|
|
1776
1771
|
}
|
|
1772
|
+
return void 0;
|
|
1777
1773
|
}
|
|
1778
1774
|
cacheSet(key, value) {
|
|
1779
1775
|
if (this.cache) {
|
|
@@ -1789,9 +1785,8 @@ class DOMNode {
|
|
|
1789
1785
|
cacheRemove(key) {
|
|
1790
1786
|
if (this.cache) {
|
|
1791
1787
|
return this.cache.delete(key);
|
|
1792
|
-
} else {
|
|
1793
|
-
return false;
|
|
1794
1788
|
}
|
|
1789
|
+
return false;
|
|
1795
1790
|
}
|
|
1796
1791
|
/**
|
|
1797
1792
|
* Check if key exists in cache.
|
|
@@ -2011,9 +2006,8 @@ class DOMTokenList extends Array {
|
|
|
2011
2006
|
location(n) {
|
|
2012
2007
|
if (this.locations) {
|
|
2013
2008
|
return this.locations[n];
|
|
2014
|
-
} else {
|
|
2015
|
-
throw new Error("Trying to access DOMTokenList location when base location isn't set");
|
|
2016
2009
|
}
|
|
2010
|
+
throw new Error("Trying to access DOMTokenList location when base location isn't set");
|
|
2017
2011
|
}
|
|
2018
2012
|
contains(token) {
|
|
2019
2013
|
return this.includes(token);
|
|
@@ -2081,7 +2075,7 @@ function nthChild(node, args) {
|
|
|
2081
2075
|
if (!args) {
|
|
2082
2076
|
throw new Error("Missing argument to nth-child");
|
|
2083
2077
|
}
|
|
2084
|
-
const n =
|
|
2078
|
+
const n = Math.trunc(Number(args.trim()));
|
|
2085
2079
|
const cur = getNthChild(node);
|
|
2086
2080
|
return cur === n;
|
|
2087
2081
|
}
|
|
@@ -2100,9 +2094,8 @@ function factory(name, context) {
|
|
|
2100
2094
|
const fn = table[name];
|
|
2101
2095
|
if (fn) {
|
|
2102
2096
|
return fn.bind(context);
|
|
2103
|
-
} else {
|
|
2104
|
-
throw new Error(`Pseudo-class "${name}" is not implemented`);
|
|
2105
2097
|
}
|
|
2098
|
+
throw new Error(`Pseudo-class "${name}" is not implemented`);
|
|
2106
2099
|
}
|
|
2107
2100
|
|
|
2108
2101
|
function stripslashes(value) {
|
|
@@ -2128,7 +2121,7 @@ function createIdCondition(raw) {
|
|
|
2128
2121
|
};
|
|
2129
2122
|
}
|
|
2130
2123
|
function createAttributeCondition(attr) {
|
|
2131
|
-
const match = /^(.+?)(?:([$*^|~]?=)"([^"]
|
|
2124
|
+
const match = /^(.+?)(?:([$*^|~]?=)"([^"]+)")?$/.exec(attr);
|
|
2132
2125
|
const key = match[1];
|
|
2133
2126
|
const op = match[2];
|
|
2134
2127
|
const rawValue = match[3];
|
|
@@ -2191,7 +2184,6 @@ function* splitCompound(pattern) {
|
|
|
2191
2184
|
let quoted = false;
|
|
2192
2185
|
while (cur < end) {
|
|
2193
2186
|
const ch = pattern[cur];
|
|
2194
|
-
const buffer = pattern.slice(begin, cur);
|
|
2195
2187
|
if (ch === "\\") {
|
|
2196
2188
|
cur += 2;
|
|
2197
2189
|
continue;
|
|
@@ -2208,6 +2200,7 @@ function* splitCompound(pattern) {
|
|
|
2208
2200
|
cur += 1;
|
|
2209
2201
|
continue;
|
|
2210
2202
|
}
|
|
2203
|
+
const buffer = pattern.slice(begin, cur);
|
|
2211
2204
|
if (isPseudoElement(ch, buffer)) {
|
|
2212
2205
|
cur += 1;
|
|
2213
2206
|
continue;
|
|
@@ -2228,7 +2221,7 @@ class Compound {
|
|
|
2228
2221
|
selector;
|
|
2229
2222
|
conditions;
|
|
2230
2223
|
constructor(pattern) {
|
|
2231
|
-
const match = /^([+>~-]?)((?:\*|[^#.:[]+)?)([
|
|
2224
|
+
const match = /^([+>~-]?)((?:\*|[^#.:[]+)?)([\s\S]*)$/.exec(pattern);
|
|
2232
2225
|
if (!match) {
|
|
2233
2226
|
throw new Error(`Failed to create selector pattern from "${pattern}"`);
|
|
2234
2227
|
}
|
|
@@ -2242,7 +2235,7 @@ class Compound {
|
|
|
2242
2235
|
return node.is(this.tagName) && this.conditions.every((cur) => cur.match(node, context));
|
|
2243
2236
|
}
|
|
2244
2237
|
createCondition(pattern) {
|
|
2245
|
-
switch (pattern
|
|
2238
|
+
switch (pattern.at(0)) {
|
|
2246
2239
|
case ".":
|
|
2247
2240
|
return createClassCondition(pattern.slice(1));
|
|
2248
2241
|
case "#":
|
|
@@ -2435,9 +2428,9 @@ class ComplexSelector {
|
|
|
2435
2428
|
case Combinator.CHILD:
|
|
2436
2429
|
return root.childElements.filter((node) => node.is(pattern.tagName));
|
|
2437
2430
|
case Combinator.ADJACENT_SIBLING:
|
|
2438
|
-
return
|
|
2431
|
+
return this.findAdjacentSibling(root);
|
|
2439
2432
|
case Combinator.GENERAL_SIBLING:
|
|
2440
|
-
return
|
|
2433
|
+
return this.findGeneralSibling(root);
|
|
2441
2434
|
case Combinator.SCOPE:
|
|
2442
2435
|
return [root];
|
|
2443
2436
|
}
|
|
@@ -2475,12 +2468,11 @@ const codepoints = {
|
|
|
2475
2468
|
"\r": "\\d "
|
|
2476
2469
|
};
|
|
2477
2470
|
function escapeSelectorComponent(text) {
|
|
2478
|
-
return text.toString().replaceAll(/([
|
|
2479
|
-
if (codepoints
|
|
2471
|
+
return text.toString().replaceAll(/([^\w-])/g, (_, ch) => {
|
|
2472
|
+
if (Object.hasOwn(codepoints, ch)) {
|
|
2480
2473
|
return codepoints[ch];
|
|
2481
|
-
} else {
|
|
2482
|
-
return `\\${ch}`;
|
|
2483
2474
|
}
|
|
2475
|
+
return `\\${ch}`;
|
|
2484
2476
|
});
|
|
2485
2477
|
}
|
|
2486
2478
|
|
|
@@ -2643,10 +2635,10 @@ class HtmlElement extends DOMNode {
|
|
|
2643
2635
|
*/
|
|
2644
2636
|
static fromTokens(startToken, endToken, parent, metaTable, namespace = "") {
|
|
2645
2637
|
const name = startToken.data[2];
|
|
2646
|
-
const tagName = namespace ? `${namespace}:${name}` : name;
|
|
2647
2638
|
if (!name) {
|
|
2648
2639
|
throw new Error("tagName cannot be empty");
|
|
2649
2640
|
}
|
|
2641
|
+
const tagName = namespace ? `${namespace}:${name}` : name;
|
|
2650
2642
|
const meta = metaTable ? metaTable.getMetaFor(tagName) : null;
|
|
2651
2643
|
const open = startToken.data[1] !== "/";
|
|
2652
2644
|
const closed = isClosed(endToken, meta);
|
|
@@ -2668,9 +2660,8 @@ class HtmlElement extends DOMNode {
|
|
|
2668
2660
|
get annotatedName() {
|
|
2669
2661
|
if (this.annotation) {
|
|
2670
2662
|
return this.annotation;
|
|
2671
|
-
} else {
|
|
2672
|
-
return `<${this.tagName}>`;
|
|
2673
2663
|
}
|
|
2664
|
+
return `<${this.tagName}>`;
|
|
2674
2665
|
}
|
|
2675
2666
|
/**
|
|
2676
2667
|
* Get list of IDs referenced by `aria-labelledby`.
|
|
@@ -2889,13 +2880,13 @@ class HtmlElement extends DOMNode {
|
|
|
2889
2880
|
if (!tabindex) {
|
|
2890
2881
|
return this.cacheSet(TABINDEX, null);
|
|
2891
2882
|
}
|
|
2892
|
-
if (tabindex.value === null) {
|
|
2883
|
+
if (tabindex.value === null || tabindex.value === "") {
|
|
2893
2884
|
return this.cacheSet(TABINDEX, null);
|
|
2894
2885
|
}
|
|
2895
2886
|
if (tabindex.value instanceof DynamicValue) {
|
|
2896
2887
|
return this.cacheSet(TABINDEX, 0);
|
|
2897
2888
|
}
|
|
2898
|
-
const parsed =
|
|
2889
|
+
const parsed = Math.trunc(Number(tabindex.value));
|
|
2899
2890
|
if (Number.isNaN(parsed)) {
|
|
2900
2891
|
return this.cacheSet(TABINDEX, null);
|
|
2901
2892
|
}
|
|
@@ -2911,11 +2902,11 @@ class HtmlElement extends DOMNode {
|
|
|
2911
2902
|
const tagName = this.tagName.toLowerCase();
|
|
2912
2903
|
if (tagName === "script") {
|
|
2913
2904
|
return "script";
|
|
2914
|
-
}
|
|
2905
|
+
}
|
|
2906
|
+
if (tagName === "style") {
|
|
2915
2907
|
return "css";
|
|
2916
|
-
} else {
|
|
2917
|
-
return "text";
|
|
2918
2908
|
}
|
|
2909
|
+
return "text";
|
|
2919
2910
|
}
|
|
2920
2911
|
/**
|
|
2921
2912
|
* Get a list of all attributes on this node.
|
|
@@ -2927,16 +2918,15 @@ class HtmlElement extends DOMNode {
|
|
|
2927
2918
|
}
|
|
2928
2919
|
hasAttribute(key) {
|
|
2929
2920
|
key = key.toLowerCase();
|
|
2930
|
-
return
|
|
2921
|
+
return Object.hasOwn(this.attr, key);
|
|
2931
2922
|
}
|
|
2932
2923
|
getAttribute(key, all = false) {
|
|
2933
2924
|
key = key.toLowerCase();
|
|
2934
|
-
if (
|
|
2925
|
+
if (Object.hasOwn(this.attr, key)) {
|
|
2935
2926
|
const matches = this.attr[key];
|
|
2936
2927
|
return all ? matches : matches[0];
|
|
2937
|
-
} else {
|
|
2938
|
-
return all ? [] : null;
|
|
2939
2928
|
}
|
|
2929
|
+
return all ? [] : null;
|
|
2940
2930
|
}
|
|
2941
2931
|
/**
|
|
2942
2932
|
* Get attribute value.
|
|
@@ -2954,17 +2944,17 @@ class HtmlElement extends DOMNode {
|
|
|
2954
2944
|
const attr = this.getAttribute(key);
|
|
2955
2945
|
if (attr) {
|
|
2956
2946
|
return attr.value !== null ? attr.value.toString() : null;
|
|
2957
|
-
} else {
|
|
2958
|
-
return null;
|
|
2959
2947
|
}
|
|
2948
|
+
return null;
|
|
2960
2949
|
}
|
|
2961
|
-
/**
|
|
2962
|
-
* Add text as a child node to this element.
|
|
2963
|
-
*
|
|
2964
|
-
* @param text - Text to add.
|
|
2965
|
-
* @param location - Source code location of this text.
|
|
2966
|
-
*/
|
|
2967
2950
|
appendText(text, location) {
|
|
2951
|
+
if (typeof text !== "string") {
|
|
2952
|
+
if ("dynamic" in text) {
|
|
2953
|
+
text = new DynamicValue(text.dynamic);
|
|
2954
|
+
} else {
|
|
2955
|
+
text = new DynamicValue(text.expr);
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2968
2958
|
this.childNodes.push(new TextNode(text, location));
|
|
2969
2959
|
}
|
|
2970
2960
|
/**
|
|
@@ -3034,14 +3024,13 @@ class HtmlElement extends DOMNode {
|
|
|
3034
3024
|
const next = it.next();
|
|
3035
3025
|
if (next.done) {
|
|
3036
3026
|
return null;
|
|
3037
|
-
} else {
|
|
3038
|
-
return next.value;
|
|
3039
3027
|
}
|
|
3028
|
+
return next.value;
|
|
3040
3029
|
}
|
|
3041
3030
|
querySelectorAll(selector) {
|
|
3042
3031
|
const it = this.querySelectorImpl(selector);
|
|
3043
3032
|
const unique = new Set(it);
|
|
3044
|
-
return Array.from(unique
|
|
3033
|
+
return Array.from(unique);
|
|
3045
3034
|
}
|
|
3046
3035
|
*querySelectorImpl(selectorList) {
|
|
3047
3036
|
if (!selectorList) {
|
|
@@ -3062,9 +3051,8 @@ class HtmlElement extends DOMNode {
|
|
|
3062
3051
|
function visit(node) {
|
|
3063
3052
|
if (callback(node)) {
|
|
3064
3053
|
return true;
|
|
3065
|
-
} else {
|
|
3066
|
-
return node.childElements.some(visit);
|
|
3067
3054
|
}
|
|
3055
|
+
return node.childElements.some(visit);
|
|
3068
3056
|
}
|
|
3069
3057
|
}
|
|
3070
3058
|
/**
|
|
@@ -3239,7 +3227,7 @@ class Validator {
|
|
|
3239
3227
|
return true;
|
|
3240
3228
|
}
|
|
3241
3229
|
return rules.some((rule) => {
|
|
3242
|
-
return
|
|
3230
|
+
return this.validatePermittedRule(node, rule);
|
|
3243
3231
|
});
|
|
3244
3232
|
}
|
|
3245
3233
|
/**
|
|
@@ -3266,9 +3254,7 @@ class Validator {
|
|
|
3266
3254
|
const [, category, quantifier] = /^(@?.*?)([*?]?)$/.exec(rule);
|
|
3267
3255
|
const limit = category && quantifier && parseQuantifier(quantifier);
|
|
3268
3256
|
if (limit) {
|
|
3269
|
-
const siblings = children.filter(
|
|
3270
|
-
(cur) => Validator.validatePermittedCategory(cur, rule, true)
|
|
3271
|
-
);
|
|
3257
|
+
const siblings = children.filter((cur) => this.validatePermittedCategory(cur, rule, true));
|
|
3272
3258
|
if (siblings.length > limit) {
|
|
3273
3259
|
for (const child of siblings.slice(limit)) {
|
|
3274
3260
|
cb(child, category);
|
|
@@ -3299,12 +3285,12 @@ class Validator {
|
|
|
3299
3285
|
let prev = null;
|
|
3300
3286
|
for (const node of children) {
|
|
3301
3287
|
const old = i;
|
|
3302
|
-
while (rules[i] && !
|
|
3288
|
+
while (rules[i] && !this.validatePermittedCategory(node, rules[i], true)) {
|
|
3303
3289
|
i++;
|
|
3304
3290
|
}
|
|
3305
3291
|
if (i >= rules.length) {
|
|
3306
|
-
const orderSpecified = rules.
|
|
3307
|
-
(cur) =>
|
|
3292
|
+
const orderSpecified = rules.some(
|
|
3293
|
+
(cur) => this.validatePermittedCategory(node, cur, true)
|
|
3308
3294
|
);
|
|
3309
3295
|
if (orderSpecified) {
|
|
3310
3296
|
cb(node, prev);
|
|
@@ -3343,7 +3329,7 @@ class Validator {
|
|
|
3343
3329
|
}
|
|
3344
3330
|
return rules.filter((tagName) => {
|
|
3345
3331
|
const haveMatchingChild = node.childElements.some(
|
|
3346
|
-
(child) =>
|
|
3332
|
+
(child) => this.validatePermittedCategory(child, tagName, false)
|
|
3347
3333
|
);
|
|
3348
3334
|
return !haveMatchingChild;
|
|
3349
3335
|
});
|
|
@@ -3390,36 +3376,35 @@ class Validator {
|
|
|
3390
3376
|
return rule.enum.some((entry) => {
|
|
3391
3377
|
if (typeof entry === "string") {
|
|
3392
3378
|
return caseInsensitiveValue === entry;
|
|
3393
|
-
}
|
|
3379
|
+
}
|
|
3380
|
+
if (entry instanceof RegExp) {
|
|
3394
3381
|
return entry.test(value);
|
|
3395
|
-
}
|
|
3382
|
+
}
|
|
3383
|
+
if (entry.pattern instanceof RegExp) {
|
|
3396
3384
|
return entry.pattern.test(value);
|
|
3397
|
-
} else {
|
|
3398
|
-
throw new TypeError("RegExp was not precompiled when it should have been");
|
|
3399
3385
|
}
|
|
3386
|
+
throw new TypeError("RegExp was not precompiled when it should have been");
|
|
3400
3387
|
});
|
|
3401
3388
|
}
|
|
3402
3389
|
static validatePermittedRule(node, rule, isExclude = false) {
|
|
3403
3390
|
if (typeof rule === "string") {
|
|
3404
|
-
return
|
|
3405
|
-
}
|
|
3391
|
+
return this.validatePermittedCategory(node, rule, !isExclude);
|
|
3392
|
+
}
|
|
3393
|
+
if (Array.isArray(rule)) {
|
|
3406
3394
|
return rule.every((inner) => {
|
|
3407
|
-
return
|
|
3395
|
+
return this.validatePermittedRule(node, inner, isExclude);
|
|
3408
3396
|
});
|
|
3409
|
-
}
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
} else {
|
|
3417
|
-
return !Validator.validatePermittedRule(node, rule.exclude, true);
|
|
3418
|
-
}
|
|
3419
|
-
} else {
|
|
3420
|
-
return true;
|
|
3397
|
+
}
|
|
3398
|
+
validateKeys(rule);
|
|
3399
|
+
if (rule.exclude) {
|
|
3400
|
+
if (Array.isArray(rule.exclude)) {
|
|
3401
|
+
return rule.exclude.every((inner) => {
|
|
3402
|
+
return !this.validatePermittedRule(node, inner, true);
|
|
3403
|
+
});
|
|
3421
3404
|
}
|
|
3405
|
+
return !this.validatePermittedRule(node, rule.exclude, true);
|
|
3422
3406
|
}
|
|
3407
|
+
return true;
|
|
3423
3408
|
}
|
|
3424
3409
|
/**
|
|
3425
3410
|
* Validate node against a content category.
|
|
@@ -3435,7 +3420,7 @@ class Validator {
|
|
|
3435
3420
|
*/
|
|
3436
3421
|
/* eslint-disable-next-line complexity -- rule does not like switch */
|
|
3437
3422
|
static validatePermittedCategory(node, category, defaultMatch) {
|
|
3438
|
-
const [, rawCategory] = /^(@?.*?)
|
|
3423
|
+
const [, rawCategory] = /^(@?.*?)[*?]?$/.exec(category);
|
|
3439
3424
|
if (!rawCategory.startsWith("@")) {
|
|
3440
3425
|
return node.matches(rawCategory);
|
|
3441
3426
|
}
|
|
@@ -3468,10 +3453,11 @@ class Validator {
|
|
|
3468
3453
|
}
|
|
3469
3454
|
function validateKeys(rule) {
|
|
3470
3455
|
for (const key of Object.keys(rule)) {
|
|
3471
|
-
if (
|
|
3472
|
-
|
|
3473
|
-
throw new Error(`Permitted rule "${str}" contains unknown property "${key}"`);
|
|
3456
|
+
if (allowedKeys.has(key)) {
|
|
3457
|
+
continue;
|
|
3474
3458
|
}
|
|
3459
|
+
const str = JSON.stringify(rule);
|
|
3460
|
+
throw new Error(`Permitted rule "${str}" contains unknown property "${key}"`);
|
|
3475
3461
|
}
|
|
3476
3462
|
}
|
|
3477
3463
|
function parseQuantifier(quantifier) {
|
|
@@ -3538,9 +3524,8 @@ function ariaNaming(element) {
|
|
|
3538
3524
|
if (role) {
|
|
3539
3525
|
if (role instanceof DynamicValue) {
|
|
3540
3526
|
return element.cacheSet(cacheKey, defaultValue);
|
|
3541
|
-
} else {
|
|
3542
|
-
return element.cacheSet(cacheKey, byRole(role));
|
|
3543
3527
|
}
|
|
3528
|
+
return element.cacheSet(cacheKey, byRole(role));
|
|
3544
3529
|
}
|
|
3545
3530
|
const meta = element.meta;
|
|
3546
3531
|
if (!meta) {
|
|
@@ -3725,9 +3710,8 @@ function isPresentation(node) {
|
|
|
3725
3710
|
const role = node.getAttribute("role");
|
|
3726
3711
|
if (role && (role.value === "presentation" || role.value === "none")) {
|
|
3727
3712
|
return node.cacheSet(ROLE_PRESENTATION_CACHE, true);
|
|
3728
|
-
} else {
|
|
3729
|
-
return node.cacheSet(ROLE_PRESENTATION_CACHE, false);
|
|
3730
3713
|
}
|
|
3714
|
+
return node.cacheSet(ROLE_PRESENTATION_CACHE, false);
|
|
3731
3715
|
}
|
|
3732
3716
|
|
|
3733
3717
|
const cachePrefix = classifyNodeText.name;
|
|
@@ -3745,13 +3729,14 @@ function getCachekey(options) {
|
|
|
3745
3729
|
const { accessible = false, ignoreHiddenRoot = false } = options;
|
|
3746
3730
|
if (accessible && ignoreHiddenRoot) {
|
|
3747
3731
|
return IGNORE_HIDDEN_ROOT_A11Y_CACHE_KEY;
|
|
3748
|
-
}
|
|
3732
|
+
}
|
|
3733
|
+
if (ignoreHiddenRoot) {
|
|
3749
3734
|
return IGNORE_HIDDEN_ROOT_HTML_CACHE_KEY;
|
|
3750
|
-
}
|
|
3735
|
+
}
|
|
3736
|
+
if (accessible) {
|
|
3751
3737
|
return A11Y_CACHE_KEY;
|
|
3752
|
-
} else {
|
|
3753
|
-
return HTML_CACHE_KEY;
|
|
3754
3738
|
}
|
|
3739
|
+
return HTML_CACHE_KEY;
|
|
3755
3740
|
}
|
|
3756
3741
|
function isSpecialEmpty(node) {
|
|
3757
3742
|
return node.is("select") || node.is("textarea");
|
|
@@ -3783,7 +3768,7 @@ function classifyNodeText(node, options = {}) {
|
|
|
3783
3768
|
}
|
|
3784
3769
|
function findTextNodes(node, options) {
|
|
3785
3770
|
const { accessible = false } = options;
|
|
3786
|
-
|
|
3771
|
+
const text = [];
|
|
3787
3772
|
for (const child of node.childNodes) {
|
|
3788
3773
|
if (isTextNode(child)) {
|
|
3789
3774
|
text.push(child);
|
|
@@ -3794,7 +3779,7 @@ function findTextNodes(node, options) {
|
|
|
3794
3779
|
if (accessible && isAriaHidden(child, true).bySelf) {
|
|
3795
3780
|
continue;
|
|
3796
3781
|
}
|
|
3797
|
-
text
|
|
3782
|
+
text.push(...findTextNodes(child, options));
|
|
3798
3783
|
}
|
|
3799
3784
|
}
|
|
3800
3785
|
return text;
|
|
@@ -3855,14 +3840,17 @@ function format(value, quote = false) {
|
|
|
3855
3840
|
return String(value);
|
|
3856
3841
|
}
|
|
3857
3842
|
function interpolate(text, data) {
|
|
3858
|
-
return text.replaceAll(
|
|
3843
|
+
return text.replaceAll(/\{\{\s*([^\s{}]+)\s*\}\}/g, (match, key) => {
|
|
3859
3844
|
return data[key] !== void 0 ? format(data[key]) : match;
|
|
3860
3845
|
});
|
|
3861
3846
|
}
|
|
3862
3847
|
|
|
3863
|
-
const ajv$1 =
|
|
3864
|
-
|
|
3865
|
-
|
|
3848
|
+
const ajv$1 = (() => {
|
|
3849
|
+
const ajv2 = new Ajv__default.default({ strict: true, strictTuples: true, strictTypes: true });
|
|
3850
|
+
ajv2.addMetaSchema(ajvSchemaDraft);
|
|
3851
|
+
ajv2.addKeyword(ajvRegexpKeyword);
|
|
3852
|
+
return ajv2;
|
|
3853
|
+
})();
|
|
3866
3854
|
function getSchemaValidator(ruleId, properties) {
|
|
3867
3855
|
const $id = `rule/${ruleId}`;
|
|
3868
3856
|
const cached = ajv$1.getSchema($id);
|
|
@@ -3883,10 +3871,9 @@ function isErrorDescriptor(value) {
|
|
|
3883
3871
|
function unpackErrorDescriptor(value) {
|
|
3884
3872
|
if (isErrorDescriptor(value)) {
|
|
3885
3873
|
return value[0];
|
|
3886
|
-
} else {
|
|
3887
|
-
const [node, message, location, context] = value;
|
|
3888
|
-
return { node, message, location, context };
|
|
3889
3874
|
}
|
|
3875
|
+
const [node, message, location, context] = value;
|
|
3876
|
+
return { node, message, location, context };
|
|
3890
3877
|
}
|
|
3891
3878
|
class Rule {
|
|
3892
3879
|
reporter;
|
|
@@ -4092,17 +4079,18 @@ class Rule {
|
|
|
4092
4079
|
const callback = args.pop();
|
|
4093
4080
|
const filter = args.pop() ?? (() => true);
|
|
4094
4081
|
return this.parser.on(event, (_event, data) => {
|
|
4095
|
-
if (this.isEnabled()
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4082
|
+
if (!this.isEnabled() || !filter(data)) {
|
|
4083
|
+
return;
|
|
4084
|
+
}
|
|
4085
|
+
this.event = data;
|
|
4086
|
+
const { tracker } = this;
|
|
4087
|
+
if (tracker) {
|
|
4088
|
+
const start = performance.now();
|
|
4089
|
+
callback(data);
|
|
4090
|
+
const end = performance.now();
|
|
4091
|
+
tracker.trackRule(this.name, end - start);
|
|
4092
|
+
} else {
|
|
4093
|
+
callback(data);
|
|
4106
4094
|
}
|
|
4107
4095
|
});
|
|
4108
4096
|
}
|
|
@@ -4172,7 +4160,7 @@ class Rule {
|
|
|
4172
4160
|
* @public
|
|
4173
4161
|
* @virtual
|
|
4174
4162
|
* @param context - Error context given by a reported error.
|
|
4175
|
-
* @returns Rule documentation and
|
|
4163
|
+
* @returns Rule documentation and URL with additional details or `null` if no
|
|
4176
4164
|
* additional documentation is available.
|
|
4177
4165
|
*/
|
|
4178
4166
|
documentation(_context) {
|
|
@@ -4211,7 +4199,7 @@ function parseAllow(value) {
|
|
|
4211
4199
|
};
|
|
4212
4200
|
}
|
|
4213
4201
|
function matchList(value, list) {
|
|
4214
|
-
if (list.include
|
|
4202
|
+
if (list.include?.every((it) => !it.test(value))) {
|
|
4215
4203
|
return false;
|
|
4216
4204
|
}
|
|
4217
4205
|
if (list.exclude?.some((it) => it.test(value))) {
|
|
@@ -4296,10 +4284,10 @@ class AllowedLinks extends Rule {
|
|
|
4296
4284
|
return Boolean(attr && attr === key);
|
|
4297
4285
|
}
|
|
4298
4286
|
getStyle(value) {
|
|
4299
|
-
if (/^([a-z]+:)
|
|
4287
|
+
if (/^(?:[a-z]+:)?\/\//.test(value)) {
|
|
4300
4288
|
return "external" /* EXTERNAL */;
|
|
4301
4289
|
}
|
|
4302
|
-
switch (value
|
|
4290
|
+
switch (value.at(0)) {
|
|
4303
4291
|
/* /foo/bar */
|
|
4304
4292
|
case "/":
|
|
4305
4293
|
return "absolute" /* ABSOLUTE */;
|
|
@@ -4318,7 +4306,8 @@ class AllowedLinks extends Rule {
|
|
|
4318
4306
|
const { allowAbsolute } = this;
|
|
4319
4307
|
if (allowAbsolute === true) {
|
|
4320
4308
|
return;
|
|
4321
|
-
}
|
|
4309
|
+
}
|
|
4310
|
+
if (allowAbsolute === false) {
|
|
4322
4311
|
this.report(
|
|
4323
4312
|
event.target,
|
|
4324
4313
|
"Link destination must not be absolute url",
|
|
@@ -4338,7 +4327,8 @@ class AllowedLinks extends Rule {
|
|
|
4338
4327
|
const { allowExternal } = this;
|
|
4339
4328
|
if (allowExternal === true) {
|
|
4340
4329
|
return;
|
|
4341
|
-
}
|
|
4330
|
+
}
|
|
4331
|
+
if (allowExternal === false) {
|
|
4342
4332
|
this.report(
|
|
4343
4333
|
event.target,
|
|
4344
4334
|
"Link destination must not be external url",
|
|
@@ -4358,7 +4348,8 @@ class AllowedLinks extends Rule {
|
|
|
4358
4348
|
const { allowRelative } = this;
|
|
4359
4349
|
if (allowRelative === true) {
|
|
4360
4350
|
return false;
|
|
4361
|
-
}
|
|
4351
|
+
}
|
|
4352
|
+
if (allowRelative === false) {
|
|
4362
4353
|
this.report(
|
|
4363
4354
|
event.target,
|
|
4364
4355
|
"Link destination must not be relative url",
|
|
@@ -4366,7 +4357,8 @@ class AllowedLinks extends Rule {
|
|
|
4366
4357
|
style
|
|
4367
4358
|
);
|
|
4368
4359
|
return true;
|
|
4369
|
-
}
|
|
4360
|
+
}
|
|
4361
|
+
if (!matchList(target, allowRelative)) {
|
|
4370
4362
|
this.report(
|
|
4371
4363
|
event.target,
|
|
4372
4364
|
"Relative link to this destination is not allowed by current configuration",
|
|
@@ -4381,7 +4373,8 @@ class AllowedLinks extends Rule {
|
|
|
4381
4373
|
const { allowBase } = this.options;
|
|
4382
4374
|
if (this.handleRelativePath(target, event, style)) {
|
|
4383
4375
|
return;
|
|
4384
|
-
}
|
|
4376
|
+
}
|
|
4377
|
+
if (!allowBase) {
|
|
4385
4378
|
this.report(
|
|
4386
4379
|
event.target,
|
|
4387
4380
|
"Relative links must be relative to current folder",
|
|
@@ -4599,12 +4592,11 @@ class AriaLabelMisuse extends Rule {
|
|
|
4599
4592
|
].join("\n"),
|
|
4600
4593
|
url
|
|
4601
4594
|
};
|
|
4602
|
-
} else {
|
|
4603
|
-
return {
|
|
4604
|
-
description: [`\`${context.attr}\` can only be used on:`, "", ...lines].join("\n"),
|
|
4605
|
-
url
|
|
4606
|
-
};
|
|
4607
4595
|
}
|
|
4596
|
+
return {
|
|
4597
|
+
description: [`\`${context.attr}\` can only be used on:`, "", ...lines].join("\n"),
|
|
4598
|
+
url
|
|
4599
|
+
};
|
|
4608
4600
|
}
|
|
4609
4601
|
setup() {
|
|
4610
4602
|
this.on("dom:ready", (event) => {
|
|
@@ -4662,6 +4654,7 @@ class AriaLabelMisuse extends Rule {
|
|
|
4662
4654
|
}
|
|
4663
4655
|
|
|
4664
4656
|
class ConfigError extends UserError {
|
|
4657
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
4665
4658
|
constructor(message, nested) {
|
|
4666
4659
|
super(message, nested);
|
|
4667
4660
|
this.name = "ConfigError";
|
|
@@ -4782,9 +4775,8 @@ class AttrCase extends Rule {
|
|
|
4782
4775
|
isIgnored(node) {
|
|
4783
4776
|
if (this.options.ignoreForeign) {
|
|
4784
4777
|
return Boolean(node.meta?.foreign);
|
|
4785
|
-
} else {
|
|
4786
|
-
return false;
|
|
4787
4778
|
}
|
|
4779
|
+
return false;
|
|
4788
4780
|
}
|
|
4789
4781
|
}
|
|
4790
4782
|
|
|
@@ -4834,10 +4826,11 @@ class Context {
|
|
|
4834
4826
|
let lastNewline = -1;
|
|
4835
4827
|
let newlines = 0;
|
|
4836
4828
|
for (let i = 0; i < n; i++) {
|
|
4837
|
-
if (this.string[i]
|
|
4838
|
-
|
|
4839
|
-
lastNewline = i;
|
|
4829
|
+
if (this.string[i] !== "\n") {
|
|
4830
|
+
continue;
|
|
4840
4831
|
}
|
|
4832
|
+
newlines++;
|
|
4833
|
+
lastNewline = i;
|
|
4841
4834
|
}
|
|
4842
4835
|
if (newlines > 0) {
|
|
4843
4836
|
this.line += newlines;
|
|
@@ -4899,28 +4892,29 @@ const MATCH_DOCTYPE_CLOSE = /^>/;
|
|
|
4899
4892
|
const MATCH_XML_TAG = /^<\?xml.*?\?>\s+/;
|
|
4900
4893
|
const MATCH_TAG_OPEN = /^<(\/?)([\w:\-]+)/;
|
|
4901
4894
|
const MATCH_TAG_CLOSE = /^\/?>/;
|
|
4902
|
-
const MATCH_TEXT = /^[
|
|
4895
|
+
const MATCH_TEXT = /^[\s\S]*?(?=[\t ]*(?:\r\n|\r|\n)|<[^ ]|$)/;
|
|
4903
4896
|
const MATCH_TEMPLATING = /^(?:<%.*?%>|<\?.*?\?>|<\$.*?\$>)/s;
|
|
4904
|
-
const MATCH_TAG_LOOKAHEAD = /^[
|
|
4897
|
+
const MATCH_TAG_LOOKAHEAD = /^[\s\S]*?(?=<|$)/;
|
|
4905
4898
|
const MATCH_ATTR_START = /^([^\t\n\f\r "'/<=>]+)/;
|
|
4906
|
-
const MATCH_ATTR_SINGLE = /^(\s*=\s*)'([^']
|
|
4907
|
-
const MATCH_ATTR_DOUBLE = /^(\s*=\s*)"([^"]
|
|
4899
|
+
const MATCH_ATTR_SINGLE = /^(\s*=\s*)'([^']*)(')/;
|
|
4900
|
+
const MATCH_ATTR_DOUBLE = /^(\s*=\s*)"([^"]*)(")/;
|
|
4908
4901
|
const MATCH_ATTR_UNQUOTED = /^(\s*=\s*)([^\t\n\f\r "'<>][^\t\n\f\r <>]*)/;
|
|
4909
4902
|
const MATCH_CDATA_BEGIN = /^<!\[CDATA\[/;
|
|
4910
|
-
const MATCH_CDATA_END = /^[
|
|
4911
|
-
const MATCH_SCRIPT_DATA = /^[
|
|
4903
|
+
const MATCH_CDATA_END = /^[\s\S]*?\]\]>/;
|
|
4904
|
+
const MATCH_SCRIPT_DATA = /^[\s\S]*?(?=<\/script)/;
|
|
4912
4905
|
const MATCH_SCRIPT_END = /^<(\/)(script)/;
|
|
4913
|
-
const MATCH_STYLE_DATA = /^[
|
|
4906
|
+
const MATCH_STYLE_DATA = /^[\s\S]*?(?=<\/style)/;
|
|
4914
4907
|
const MATCH_STYLE_END = /^<(\/)(style)/;
|
|
4915
|
-
const MATCH_TEXTAREA_DATA = /^[
|
|
4908
|
+
const MATCH_TEXTAREA_DATA = /^[\s\S]*?(?=<\/textarea)/;
|
|
4916
4909
|
const MATCH_TEXTAREA_END = /^<(\/)(textarea)/;
|
|
4917
|
-
const MATCH_TITLE_DATA = /^[
|
|
4910
|
+
const MATCH_TITLE_DATA = /^[\s\S]*?(?=<\/title)/;
|
|
4918
4911
|
const MATCH_TITLE_END = /^<(\/)(title)/;
|
|
4919
|
-
const MATCH_DIRECTIVE = /^(<!--\s*\[?)(html-validate-)([\da-z-]+)(\s*)(.*?)(]?\s*-->)/;
|
|
4920
|
-
const MATCH_COMMENT = /^<!--([
|
|
4921
|
-
const MATCH_CONDITIONAL = /^<!\[([^\]]
|
|
4912
|
+
const MATCH_DIRECTIVE = /^(<!--\s*\[?)(html-validate-)([\da-z-]+)(\s*)(.*?)(\]?\s*-->)/;
|
|
4913
|
+
const MATCH_COMMENT = /^<!--([\s\S]*?)-->/;
|
|
4914
|
+
const MATCH_CONDITIONAL = /^<!\[([^\]]*)\]>/;
|
|
4922
4915
|
class InvalidTokenError extends Error {
|
|
4923
4916
|
location;
|
|
4917
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
4924
4918
|
constructor(location, message) {
|
|
4925
4919
|
super(message);
|
|
4926
4920
|
this.name = "InvalidTokenError";
|
|
@@ -5004,9 +4998,8 @@ class Lexer {
|
|
|
5004
4998
|
evalNextState(nextState, token) {
|
|
5005
4999
|
if (typeof nextState === "function") {
|
|
5006
5000
|
return nextState(token);
|
|
5007
|
-
} else {
|
|
5008
|
-
return nextState;
|
|
5009
5001
|
}
|
|
5002
|
+
return nextState;
|
|
5010
5003
|
}
|
|
5011
5004
|
*match(context, tests, error) {
|
|
5012
5005
|
const n = tests.length;
|
|
@@ -5093,27 +5086,26 @@ class Lexer {
|
|
|
5093
5086
|
case ContentModel.SCRIPT:
|
|
5094
5087
|
if (selfClosed) {
|
|
5095
5088
|
return State.SCRIPT;
|
|
5096
|
-
} else {
|
|
5097
|
-
return State.TEXT;
|
|
5098
5089
|
}
|
|
5090
|
+
return State.TEXT;
|
|
5091
|
+
/* <script/> (not legal but handle it anyway so the lexer doesn't choke on it) */
|
|
5099
5092
|
case ContentModel.STYLE:
|
|
5100
5093
|
if (selfClosed) {
|
|
5101
5094
|
return State.STYLE;
|
|
5102
|
-
} else {
|
|
5103
|
-
return State.TEXT;
|
|
5104
5095
|
}
|
|
5096
|
+
return State.TEXT;
|
|
5097
|
+
/* <style/> */
|
|
5105
5098
|
case ContentModel.TEXTAREA:
|
|
5106
5099
|
if (selfClosed) {
|
|
5107
5100
|
return State.TEXTAREA;
|
|
5108
|
-
} else {
|
|
5109
|
-
return State.TEXT;
|
|
5110
5101
|
}
|
|
5102
|
+
return State.TEXT;
|
|
5103
|
+
/* <textarea/> */
|
|
5111
5104
|
case ContentModel.TITLE:
|
|
5112
5105
|
if (selfClosed) {
|
|
5113
5106
|
return State.TITLE;
|
|
5114
|
-
} else {
|
|
5115
|
-
return State.TEXT;
|
|
5116
5107
|
}
|
|
5108
|
+
return State.TEXT;
|
|
5117
5109
|
}
|
|
5118
5110
|
}
|
|
5119
5111
|
yield* this.match(
|
|
@@ -5200,7 +5192,7 @@ class Lexer {
|
|
|
5200
5192
|
}
|
|
5201
5193
|
}
|
|
5202
5194
|
|
|
5203
|
-
const whitespace =
|
|
5195
|
+
const whitespace = /\s+/;
|
|
5204
5196
|
class AttrDelimiter extends Rule {
|
|
5205
5197
|
documentation() {
|
|
5206
5198
|
return {
|
|
@@ -5232,17 +5224,15 @@ const defaults$y = {
|
|
|
5232
5224
|
function generateRegexp(pattern) {
|
|
5233
5225
|
if (Array.isArray(pattern)) {
|
|
5234
5226
|
return new RegExp(`^(${pattern.join("|")})$`, "i");
|
|
5235
|
-
} else {
|
|
5236
|
-
return new RegExp(`^${pattern}$`, "i");
|
|
5237
5227
|
}
|
|
5228
|
+
return new RegExp(`^${pattern}$`, "i");
|
|
5238
5229
|
}
|
|
5239
5230
|
function generateMessage(name, pattern) {
|
|
5240
5231
|
if (Array.isArray(pattern)) {
|
|
5241
5232
|
const patterns = pattern.map((it) => `/${it}/`).join(", ");
|
|
5242
5233
|
return `Attribute "${name}" should match one of [${patterns}]`;
|
|
5243
|
-
} else {
|
|
5244
|
-
return `Attribute "${name}" should match /${pattern}/`;
|
|
5245
5234
|
}
|
|
5235
|
+
return `Attribute "${name}" should match /${pattern}/`;
|
|
5246
5236
|
}
|
|
5247
5237
|
function generateDescription(name, pattern) {
|
|
5248
5238
|
if (Array.isArray(pattern)) {
|
|
@@ -5251,9 +5241,8 @@ function generateDescription(name, pattern) {
|
|
|
5251
5241
|
"",
|
|
5252
5242
|
...pattern.map((it) => `- \`/${it}/\``)
|
|
5253
5243
|
].join("\n");
|
|
5254
|
-
} else {
|
|
5255
|
-
return `Attribute "${name}" should match the regular expression \`/${pattern}/\``;
|
|
5256
5244
|
}
|
|
5245
|
+
return `Attribute "${name}" should match the regular expression \`/${pattern}/\``;
|
|
5257
5246
|
}
|
|
5258
5247
|
class AttrPattern extends Rule {
|
|
5259
5248
|
pattern;
|
|
@@ -5299,9 +5288,8 @@ class AttrPattern extends Rule {
|
|
|
5299
5288
|
isIgnored(node) {
|
|
5300
5289
|
if (this.options.ignoreForeign) {
|
|
5301
5290
|
return Boolean(node.meta?.foreign);
|
|
5302
|
-
} else {
|
|
5303
|
-
return false;
|
|
5304
5291
|
}
|
|
5292
|
+
return false;
|
|
5305
5293
|
}
|
|
5306
5294
|
}
|
|
5307
5295
|
|
|
@@ -5412,9 +5400,8 @@ class AttrQuotes extends Rule {
|
|
|
5412
5400
|
resolveQuotemark(value, style) {
|
|
5413
5401
|
if (style === "auto" /* AUTO_QUOTE */) {
|
|
5414
5402
|
return value.includes('"') ? "'" : '"';
|
|
5415
|
-
} else {
|
|
5416
|
-
return style;
|
|
5417
5403
|
}
|
|
5404
|
+
return style;
|
|
5418
5405
|
}
|
|
5419
5406
|
}
|
|
5420
5407
|
function parseStyle$3(style) {
|
|
@@ -5472,11 +5459,11 @@ class AttributeAllowedValues extends Rule {
|
|
|
5472
5459
|
const allowedList = allowed.enum.map((value2) => {
|
|
5473
5460
|
if (typeof value2 === "string") {
|
|
5474
5461
|
return `- \`"${value2}"\``;
|
|
5475
|
-
}
|
|
5462
|
+
}
|
|
5463
|
+
if (value2 instanceof RegExp) {
|
|
5476
5464
|
return `- \`${value2.toString()}\``;
|
|
5477
|
-
} else {
|
|
5478
|
-
return `- ${value2.name}`;
|
|
5479
5465
|
}
|
|
5466
|
+
return `- ${value2.name}`;
|
|
5480
5467
|
});
|
|
5481
5468
|
docs.description = [
|
|
5482
5469
|
`The \`<${element}>\` element does not allow the attribute \`${attribute}\` to have the value \`"${value}"\`.`,
|
|
@@ -5520,9 +5507,8 @@ class AttributeAllowedValues extends Rule {
|
|
|
5520
5507
|
const { key, value } = attr;
|
|
5521
5508
|
if (value !== null) {
|
|
5522
5509
|
return `Attribute "${key}" has invalid value "${value.toString()}"`;
|
|
5523
|
-
} else {
|
|
5524
|
-
return `Attribute "${key}" is missing value`;
|
|
5525
5510
|
}
|
|
5511
|
+
return `Attribute "${key}" is missing value`;
|
|
5526
5512
|
}
|
|
5527
5513
|
getLocation(attr) {
|
|
5528
5514
|
return attr.valueLocation ?? attr.keyLocation;
|
|
@@ -5809,10 +5795,10 @@ class AutocompletePassword extends Rule {
|
|
|
5809
5795
|
const tokens = new DOMTokenList(raw, autocomplete.valueLocation);
|
|
5810
5796
|
const index = tokens.findIndex((token) => !isGroupingToken(token));
|
|
5811
5797
|
const value = tokens.item(index);
|
|
5812
|
-
const location = tokens.location(index);
|
|
5813
5798
|
if (!value) {
|
|
5814
5799
|
return;
|
|
5815
5800
|
}
|
|
5801
|
+
const location = tokens.location(index);
|
|
5816
5802
|
if (value === "off") {
|
|
5817
5803
|
const context = { kind: "off" };
|
|
5818
5804
|
this.report({
|
|
@@ -5897,9 +5883,8 @@ function parsePattern(pattern) {
|
|
|
5897
5883
|
function toArray$2(value) {
|
|
5898
5884
|
if (Array.isArray(value)) {
|
|
5899
5885
|
return value;
|
|
5900
|
-
} else {
|
|
5901
|
-
return [value];
|
|
5902
5886
|
}
|
|
5887
|
+
return [value];
|
|
5903
5888
|
}
|
|
5904
5889
|
function validateAllowedPatterns(patterns, allowedPatterns, ruleId) {
|
|
5905
5890
|
const extraneous = patterns.filter(isNamedPattern).filter((p) => !allowedPatterns.has(p));
|
|
@@ -5985,7 +5970,7 @@ class ClassPattern extends BasePatternRule {
|
|
|
5985
5970
|
});
|
|
5986
5971
|
}
|
|
5987
5972
|
static schema() {
|
|
5988
|
-
return
|
|
5973
|
+
return super.schema();
|
|
5989
5974
|
}
|
|
5990
5975
|
documentation(context) {
|
|
5991
5976
|
return {
|
|
@@ -6066,10 +6051,10 @@ class CloseOrder extends Rule {
|
|
|
6066
6051
|
});
|
|
6067
6052
|
this.on("tag:end", (event) => {
|
|
6068
6053
|
const current = event.target;
|
|
6069
|
-
const active = event.previous;
|
|
6070
6054
|
if (current) {
|
|
6071
6055
|
return;
|
|
6072
6056
|
}
|
|
6057
|
+
const active = event.previous;
|
|
6073
6058
|
for (const ancestor of ancestors(active)) {
|
|
6074
6059
|
if (ancestor.isRootElement() || reported.has(ancestor.unique)) {
|
|
6075
6060
|
continue;
|
|
@@ -6080,13 +6065,13 @@ class CloseOrder extends Rule {
|
|
|
6080
6065
|
});
|
|
6081
6066
|
this.on("tag:end", (event) => {
|
|
6082
6067
|
const current = event.target;
|
|
6083
|
-
const active = event.previous;
|
|
6084
6068
|
if (!current) {
|
|
6085
6069
|
return;
|
|
6086
6070
|
}
|
|
6087
6071
|
if (current.voidElement) {
|
|
6088
6072
|
return;
|
|
6089
6073
|
}
|
|
6074
|
+
const active = event.previous;
|
|
6090
6075
|
if (active.closed === Node.CLOSED_IMPLICIT_CLOSED) {
|
|
6091
6076
|
return;
|
|
6092
6077
|
}
|
|
@@ -6181,7 +6166,7 @@ class Deprecated extends Rule {
|
|
|
6181
6166
|
text.push(context.documentation);
|
|
6182
6167
|
}
|
|
6183
6168
|
const doc = {
|
|
6184
|
-
description: text.map((cur) => cur.replaceAll("$tagname", context.tagName)).join("\n\n"),
|
|
6169
|
+
description: text.map((cur) => cur.replaceAll("$tagname", () => context.tagName)).join("\n\n"),
|
|
6185
6170
|
url: "https://html-validate.org/rules/deprecated.html"
|
|
6186
6171
|
};
|
|
6187
6172
|
return doc;
|
|
@@ -6580,7 +6565,7 @@ class ElementName extends Rule {
|
|
|
6580
6565
|
];
|
|
6581
6566
|
}
|
|
6582
6567
|
setup() {
|
|
6583
|
-
const xmlns = /^
|
|
6568
|
+
const xmlns = /^[^:]+:.+$/;
|
|
6584
6569
|
this.on("tag:start", (event) => {
|
|
6585
6570
|
const target = event.target;
|
|
6586
6571
|
const tagName = target.tagName;
|
|
@@ -6619,13 +6604,12 @@ function isNativeTemplate(node) {
|
|
|
6619
6604
|
function getTransparentChildren(node, transparent) {
|
|
6620
6605
|
if (typeof transparent === "boolean") {
|
|
6621
6606
|
return node.childElements;
|
|
6622
|
-
} else {
|
|
6623
|
-
return node.childElements.filter((it) => {
|
|
6624
|
-
return transparent.some((category) => {
|
|
6625
|
-
return Validator.validatePermittedCategory(it, category, false);
|
|
6626
|
-
});
|
|
6627
|
-
});
|
|
6628
6607
|
}
|
|
6608
|
+
return node.childElements.filter((it) => {
|
|
6609
|
+
return transparent.some((category) => {
|
|
6610
|
+
return Validator.validatePermittedCategory(it, category, false);
|
|
6611
|
+
});
|
|
6612
|
+
});
|
|
6629
6613
|
}
|
|
6630
6614
|
function getRuleDescription$2(context) {
|
|
6631
6615
|
switch (context.kind) {
|
|
@@ -6657,6 +6641,7 @@ class ElementPermittedContent extends Rule {
|
|
|
6657
6641
|
[
|
|
6658
6642
|
() => this.validatePermittedContent(node, parent),
|
|
6659
6643
|
() => this.validatePermittedDescendant(node, parent)
|
|
6644
|
+
/* eslint-disable-next-line unicorn/no-unused-array-method-return -- technical debt, should use iterator helpers */
|
|
6660
6645
|
].some((fn) => fn());
|
|
6661
6646
|
});
|
|
6662
6647
|
});
|
|
@@ -6802,14 +6787,12 @@ function getRuleDescription$1(context) {
|
|
|
6802
6787
|
const allowed = rules.filter(isCategoryOrTag).map((it) => {
|
|
6803
6788
|
if (isCategory$1(it)) {
|
|
6804
6789
|
return `- any ${it.slice(1)} element`;
|
|
6805
|
-
} else {
|
|
6806
|
-
return `- \`<${it}>\``;
|
|
6807
6790
|
}
|
|
6791
|
+
return `- \`<${it}>\``;
|
|
6808
6792
|
});
|
|
6809
6793
|
return [preamble, "", "Allowed parents one of:", "", ...allowed];
|
|
6810
|
-
} else {
|
|
6811
|
-
return [preamble];
|
|
6812
6794
|
}
|
|
6795
|
+
return [preamble];
|
|
6813
6796
|
}
|
|
6814
6797
|
function formatMessage$1(node, parent, rules) {
|
|
6815
6798
|
const nodeName = node.annotatedName;
|
|
@@ -6861,7 +6844,7 @@ class ElementPermittedParent extends Rule {
|
|
|
6861
6844
|
}
|
|
6862
6845
|
|
|
6863
6846
|
function isTagnameOnly(value) {
|
|
6864
|
-
return /^[\dA-
|
|
6847
|
+
return /^[\dA-Z-]+$/i.test(value);
|
|
6865
6848
|
}
|
|
6866
6849
|
function getRuleDescription(context) {
|
|
6867
6850
|
const escaped = context.ancestor.map((it) => `\`${it}\``);
|
|
@@ -6924,9 +6907,8 @@ function normalizeRequired(element, attr) {
|
|
|
6924
6907
|
default:
|
|
6925
6908
|
return result;
|
|
6926
6909
|
}
|
|
6927
|
-
} else {
|
|
6928
|
-
return required ? defaultMessage : false;
|
|
6929
6910
|
}
|
|
6911
|
+
return required ? defaultMessage : false;
|
|
6930
6912
|
}
|
|
6931
6913
|
class ElementRequiredAttributes extends Rule {
|
|
6932
6914
|
documentation(context) {
|
|
@@ -7008,7 +6990,8 @@ const selector = ["h1", "h2", "h3", "h4", "h5", "h6"].join(",");
|
|
|
7008
6990
|
function hasImgAltText$1(node) {
|
|
7009
6991
|
if (node.is("img")) {
|
|
7010
6992
|
return hasAltText(node);
|
|
7011
|
-
}
|
|
6993
|
+
}
|
|
6994
|
+
if (node.is("svg")) {
|
|
7012
6995
|
return node.textContent.trim() !== "";
|
|
7013
6996
|
}
|
|
7014
6997
|
return false;
|
|
@@ -7289,21 +7272,19 @@ class FormDupName extends Rule {
|
|
|
7289
7272
|
const existing = group.cacheGet(UNIQUE_CACHE_KEY);
|
|
7290
7273
|
if (existing) {
|
|
7291
7274
|
return existing;
|
|
7292
|
-
} else {
|
|
7293
|
-
const elements = /* @__PURE__ */ new Map();
|
|
7294
|
-
group.cacheSet(UNIQUE_CACHE_KEY, elements);
|
|
7295
|
-
return elements;
|
|
7296
7275
|
}
|
|
7276
|
+
const elements = /* @__PURE__ */ new Map();
|
|
7277
|
+
group.cacheSet(UNIQUE_CACHE_KEY, elements);
|
|
7278
|
+
return elements;
|
|
7297
7279
|
}
|
|
7298
7280
|
getSharedElements(group) {
|
|
7299
7281
|
const existing = group.cacheGet(SHARED_CACHE_KEY);
|
|
7300
7282
|
if (existing) {
|
|
7301
7283
|
return existing;
|
|
7302
|
-
} else {
|
|
7303
|
-
const elements = /* @__PURE__ */ new Map();
|
|
7304
|
-
group.cacheSet(SHARED_CACHE_KEY, elements);
|
|
7305
|
-
return elements;
|
|
7306
7284
|
}
|
|
7285
|
+
const elements = /* @__PURE__ */ new Map();
|
|
7286
|
+
group.cacheSet(SHARED_CACHE_KEY, elements);
|
|
7287
|
+
return elements;
|
|
7307
7288
|
}
|
|
7308
7289
|
}
|
|
7309
7290
|
|
|
@@ -7317,12 +7298,11 @@ function isRelevant$5(event) {
|
|
|
7317
7298
|
return Boolean(node.meta?.heading);
|
|
7318
7299
|
}
|
|
7319
7300
|
function extractLevel(node) {
|
|
7320
|
-
const match = /^
|
|
7301
|
+
const match = /^H(\d)$/i.exec(node.tagName);
|
|
7321
7302
|
if (match) {
|
|
7322
|
-
return
|
|
7323
|
-
} else {
|
|
7324
|
-
return null;
|
|
7303
|
+
return Math.trunc(Number(match[1]));
|
|
7325
7304
|
}
|
|
7305
|
+
return null;
|
|
7326
7306
|
}
|
|
7327
7307
|
function parseMaxInitial(value) {
|
|
7328
7308
|
if (value === false || value === "any") {
|
|
@@ -7332,7 +7312,7 @@ function parseMaxInitial(value) {
|
|
|
7332
7312
|
if (!match) {
|
|
7333
7313
|
return 1;
|
|
7334
7314
|
}
|
|
7335
|
-
return
|
|
7315
|
+
return Math.trunc(Number(match[1]));
|
|
7336
7316
|
}
|
|
7337
7317
|
class HeadingLevel extends Rule {
|
|
7338
7318
|
minInitialRank;
|
|
@@ -7599,7 +7579,7 @@ class IdPattern extends BasePatternRule {
|
|
|
7599
7579
|
});
|
|
7600
7580
|
}
|
|
7601
7581
|
static schema() {
|
|
7602
|
-
return
|
|
7582
|
+
return super.schema();
|
|
7603
7583
|
}
|
|
7604
7584
|
documentation(context) {
|
|
7605
7585
|
return {
|
|
@@ -7821,24 +7801,23 @@ function isHidden(node, context) {
|
|
|
7821
7801
|
const { reference } = context;
|
|
7822
7802
|
if (reference?.isSameNode(node)) {
|
|
7823
7803
|
return false;
|
|
7824
|
-
} else {
|
|
7825
|
-
return !inAccessibilityTree(node);
|
|
7826
7804
|
}
|
|
7805
|
+
return !inAccessibilityTree(node);
|
|
7827
7806
|
}
|
|
7828
7807
|
function hasImgAltText(node, context) {
|
|
7829
7808
|
if (node.is("img")) {
|
|
7830
7809
|
return hasAltText(node);
|
|
7831
|
-
}
|
|
7810
|
+
}
|
|
7811
|
+
if (node.is("svg")) {
|
|
7832
7812
|
return node.textContent.trim() !== "";
|
|
7833
|
-
}
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
}
|
|
7813
|
+
}
|
|
7814
|
+
for (const img of node.querySelectorAll("img, svg")) {
|
|
7815
|
+
const hasName = hasAccessibleNameImpl(img, context);
|
|
7816
|
+
if (hasName) {
|
|
7817
|
+
return true;
|
|
7839
7818
|
}
|
|
7840
|
-
return false;
|
|
7841
7819
|
}
|
|
7820
|
+
return false;
|
|
7842
7821
|
}
|
|
7843
7822
|
function hasLabel(node) {
|
|
7844
7823
|
const value = node.getAttributeValue("aria-label") ?? "";
|
|
@@ -7969,7 +7948,7 @@ class InputMissingLabel extends Rule {
|
|
|
7969
7948
|
this.report(elem, `<${elem.tagName}> element has <label> but <label> element is hidden`);
|
|
7970
7949
|
return;
|
|
7971
7950
|
}
|
|
7972
|
-
if (
|
|
7951
|
+
if (labels.every((label) => !hasAccessibleName(root, label))) {
|
|
7973
7952
|
this.report(elem, `<${elem.tagName}> element has <label> but <label> has no text`);
|
|
7974
7953
|
}
|
|
7975
7954
|
}
|
|
@@ -8156,12 +8135,11 @@ function parseContent(text) {
|
|
|
8156
8135
|
const match = /^(\d+)(?:\s*;\s*url=(.*))?/i.exec(text);
|
|
8157
8136
|
if (match) {
|
|
8158
8137
|
return {
|
|
8159
|
-
delay:
|
|
8138
|
+
delay: Math.trunc(Number(match[1])),
|
|
8160
8139
|
url: match[2]
|
|
8161
8140
|
};
|
|
8162
|
-
} else {
|
|
8163
|
-
return null;
|
|
8164
8141
|
}
|
|
8142
|
+
return null;
|
|
8165
8143
|
}
|
|
8166
8144
|
|
|
8167
8145
|
class MissingDoctype extends Rule {
|
|
@@ -8238,7 +8216,7 @@ class NamePattern extends BasePatternRule {
|
|
|
8238
8216
|
});
|
|
8239
8217
|
}
|
|
8240
8218
|
static schema() {
|
|
8241
|
-
return
|
|
8219
|
+
return super.schema();
|
|
8242
8220
|
}
|
|
8243
8221
|
documentation(context) {
|
|
8244
8222
|
return {
|
|
@@ -8421,10 +8399,10 @@ class NoDeprecatedAttr extends Rule {
|
|
|
8421
8399
|
this.on("attr", (event) => {
|
|
8422
8400
|
const node = event.target;
|
|
8423
8401
|
const meta = node.meta;
|
|
8424
|
-
const attr = event.key.toLowerCase();
|
|
8425
8402
|
if (meta === null) {
|
|
8426
8403
|
return;
|
|
8427
8404
|
}
|
|
8405
|
+
const attr = event.key.toLowerCase();
|
|
8428
8406
|
const metaAttribute = meta.attributes[attr];
|
|
8429
8407
|
if (!metaAttribute) {
|
|
8430
8408
|
return;
|
|
@@ -8458,7 +8436,7 @@ class NoDupAttr extends Rule {
|
|
|
8458
8436
|
return;
|
|
8459
8437
|
}
|
|
8460
8438
|
const name = event.key.toLowerCase();
|
|
8461
|
-
if (name
|
|
8439
|
+
if (Object.hasOwn(attr, name)) {
|
|
8462
8440
|
this.report(event.target, `Attribute "${name}" duplicated`, event.keyLocation);
|
|
8463
8441
|
}
|
|
8464
8442
|
attr[event.key] = true;
|
|
@@ -8531,10 +8509,9 @@ function getExisting(element, root) {
|
|
|
8531
8509
|
const existing = group.cacheGet(CACHE_KEY);
|
|
8532
8510
|
if (existing) {
|
|
8533
8511
|
return existing;
|
|
8534
|
-
} else {
|
|
8535
|
-
const existing2 = /* @__PURE__ */ new Set();
|
|
8536
|
-
return group.cacheSet(CACHE_KEY, existing2);
|
|
8537
8512
|
}
|
|
8513
|
+
const value = /* @__PURE__ */ new Set();
|
|
8514
|
+
return group.cacheSet(CACHE_KEY, value);
|
|
8538
8515
|
}
|
|
8539
8516
|
|
|
8540
8517
|
function isRelevant$2(event) {
|
|
@@ -8805,10 +8782,11 @@ class NoMissingReferences extends Rule {
|
|
|
8805
8782
|
}
|
|
8806
8783
|
}
|
|
8807
8784
|
validateSingle(document, node, attr, id) {
|
|
8808
|
-
if (idMissing(document, id)) {
|
|
8809
|
-
|
|
8810
|
-
this.report(node, `Element references missing id "${id}"`, attr.valueLocation, context);
|
|
8785
|
+
if (!idMissing(document, id)) {
|
|
8786
|
+
return;
|
|
8811
8787
|
}
|
|
8788
|
+
const context = { key: attr.key, value: id };
|
|
8789
|
+
this.report(node, `Element references missing id "${id}"`, attr.valueLocation, context);
|
|
8812
8790
|
}
|
|
8813
8791
|
validateList(document, node, attr, values) {
|
|
8814
8792
|
const parsed = new DOMTokenList(values, attr.valueLocation);
|
|
@@ -8848,9 +8826,9 @@ class NoMultipleMain extends Rule {
|
|
|
8848
8826
|
const defaults$f = {
|
|
8849
8827
|
relaxed: false
|
|
8850
8828
|
};
|
|
8851
|
-
const textRegexp = /(<|&(?![\d#A-
|
|
8852
|
-
const unquotedAttrRegexp = /(["'<=>`]|&(?![\d#A-
|
|
8853
|
-
const matchTemplate = /^(
|
|
8829
|
+
const textRegexp = /(<|&(?![\d#A-Z]+;))/gi;
|
|
8830
|
+
const unquotedAttrRegexp = /(["'<=>`]|&(?![\d#A-Z]+;))/gi;
|
|
8831
|
+
const matchTemplate = /^(?:<%.*?%>|<\?.*?\?>|<\$.*?\$>)$/s;
|
|
8854
8832
|
const replacementTable = {
|
|
8855
8833
|
'"': """,
|
|
8856
8834
|
"&": "&",
|
|
@@ -9082,7 +9060,7 @@ class NoRedundantRole extends Rule {
|
|
|
9082
9060
|
}
|
|
9083
9061
|
}
|
|
9084
9062
|
|
|
9085
|
-
const xmlns = /^
|
|
9063
|
+
const xmlns = /^[^:]+:.+$/;
|
|
9086
9064
|
const defaults$d = {
|
|
9087
9065
|
ignoreForeign: true,
|
|
9088
9066
|
ignoreXML: true
|
|
@@ -9204,11 +9182,11 @@ class NoUnknownAttributes extends Rule {
|
|
|
9204
9182
|
this.on("attr", (event) => {
|
|
9205
9183
|
const node = event.target;
|
|
9206
9184
|
const meta = node.meta;
|
|
9207
|
-
const attr = event.key.toLowerCase();
|
|
9208
9185
|
if (meta === null) {
|
|
9209
9186
|
return;
|
|
9210
9187
|
}
|
|
9211
|
-
|
|
9188
|
+
const attr = event.key.toLowerCase();
|
|
9189
|
+
if (Object.hasOwn(meta.attributes, attr)) {
|
|
9212
9190
|
return;
|
|
9213
9191
|
}
|
|
9214
9192
|
if (isPatternAttribute(attr, meta.patternAttributes)) {
|
|
@@ -9615,7 +9593,7 @@ const defaults$7 = {
|
|
|
9615
9593
|
include: null,
|
|
9616
9594
|
exclude: null
|
|
9617
9595
|
};
|
|
9618
|
-
const crossorigin =
|
|
9596
|
+
const crossorigin = /^(?:\w+:\/\/|\/\/)/;
|
|
9619
9597
|
const supportSri = {
|
|
9620
9598
|
link: "href",
|
|
9621
9599
|
script: "src"
|
|
@@ -9828,7 +9806,10 @@ function constructRegex(characters) {
|
|
|
9828
9806
|
return new RegExp(pattern, "g");
|
|
9829
9807
|
}
|
|
9830
9808
|
function getText(node) {
|
|
9831
|
-
const match = /^(\s*)(.*)$/.exec(node.textContent);
|
|
9809
|
+
const match = /^(\s*)(\S.*)$/.exec(node.textContent);
|
|
9810
|
+
if (!match) {
|
|
9811
|
+
return [0, ""];
|
|
9812
|
+
}
|
|
9832
9813
|
const [, leading, text] = match;
|
|
9833
9814
|
return [leading.length, text.trimEnd()];
|
|
9834
9815
|
}
|
|
@@ -9981,9 +9962,8 @@ function hasDefaultText(node) {
|
|
|
9981
9962
|
function isNonEmptyText(node) {
|
|
9982
9963
|
if (isTextNode(node)) {
|
|
9983
9964
|
return node.isDynamic || node.textContent.trim() !== "";
|
|
9984
|
-
} else {
|
|
9985
|
-
return false;
|
|
9986
9965
|
}
|
|
9966
|
+
return false;
|
|
9987
9967
|
}
|
|
9988
9968
|
function haveAccessibleText(node) {
|
|
9989
9969
|
if (!inAccessibilityTree(node)) {
|
|
@@ -10118,15 +10098,14 @@ function getTextFromReference(document, id) {
|
|
|
10118
10098
|
const ref = document.querySelector(selector);
|
|
10119
10099
|
if (ref) {
|
|
10120
10100
|
return ref.textContent;
|
|
10121
|
-
} else {
|
|
10122
|
-
return selector;
|
|
10123
10101
|
}
|
|
10102
|
+
return selector;
|
|
10124
10103
|
}
|
|
10125
10104
|
function groupBy(values, callback) {
|
|
10126
10105
|
const result = {};
|
|
10127
10106
|
for (const value of values) {
|
|
10128
10107
|
const key = callback(value);
|
|
10129
|
-
if (key
|
|
10108
|
+
if (Object.hasOwn(result, key)) {
|
|
10130
10109
|
result[key].push(value);
|
|
10131
10110
|
} else {
|
|
10132
10111
|
result[key] = [value];
|
|
@@ -10226,7 +10205,7 @@ const defaults$5 = {
|
|
|
10226
10205
|
ignoreCase: false,
|
|
10227
10206
|
requireSemicolon: true
|
|
10228
10207
|
};
|
|
10229
|
-
const regexp$1 = /&(?:[\da-z]+|#x?[\da-f]+)(
|
|
10208
|
+
const regexp$1 = /&(?:[\da-z]+|#x?[\da-f]+)([^\da-z]|$)/gi;
|
|
10230
10209
|
const lowercaseEntities = elements.entities.map((it) => it.toLowerCase());
|
|
10231
10210
|
function isNumerical(entity) {
|
|
10232
10211
|
return entity.startsWith("&#");
|
|
@@ -10305,9 +10284,8 @@ class UnknownCharReference extends Rule {
|
|
|
10305
10284
|
get entities() {
|
|
10306
10285
|
if (this.options.ignoreCase) {
|
|
10307
10286
|
return lowercaseEntities;
|
|
10308
|
-
} else {
|
|
10309
|
-
return elements.entities;
|
|
10310
10287
|
}
|
|
10288
|
+
return elements.entities;
|
|
10311
10289
|
}
|
|
10312
10290
|
findCharacterReferences(node, text, location, { isAttribute }) {
|
|
10313
10291
|
const delimiter = text.search(/[#?]/);
|
|
@@ -10673,7 +10651,6 @@ class ValidAutocomplete extends Rule {
|
|
|
10673
10651
|
}
|
|
10674
10652
|
validateControlAutocomplete(node, tokens, keyLocation) {
|
|
10675
10653
|
const type = node.getAttributeValue("type") ?? "text";
|
|
10676
|
-
const mantle = type !== "hidden" ? "expectation" : "anchor";
|
|
10677
10654
|
if (isDisallowedType(node, type)) {
|
|
10678
10655
|
const context = {
|
|
10679
10656
|
msg: 0 /* InvalidAttribute */,
|
|
@@ -10688,6 +10665,7 @@ class ValidAutocomplete extends Rule {
|
|
|
10688
10665
|
return;
|
|
10689
10666
|
}
|
|
10690
10667
|
if (tokens.includes("on") || tokens.includes("off")) {
|
|
10668
|
+
const mantle = type !== "hidden" ? "expectation" : "anchor";
|
|
10691
10669
|
this.validateOnOff(node, mantle, tokens);
|
|
10692
10670
|
return;
|
|
10693
10671
|
}
|
|
@@ -10811,44 +10789,46 @@ class ValidAutocomplete extends Rule {
|
|
|
10811
10789
|
* Ensure contact token is only used with field names from the second list.
|
|
10812
10790
|
*/
|
|
10813
10791
|
validateContact(node, tokens, order) {
|
|
10814
|
-
if (order.includes("contact")
|
|
10815
|
-
|
|
10816
|
-
|
|
10792
|
+
if (!order.includes("contact") || !order.includes("field1")) {
|
|
10793
|
+
return;
|
|
10794
|
+
}
|
|
10795
|
+
const a = order.indexOf("field1");
|
|
10796
|
+
const b = order.indexOf("contact");
|
|
10797
|
+
const context = {
|
|
10798
|
+
msg: 4 /* InvalidCombination */,
|
|
10799
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion -- it must be present of it wouldn't be found */
|
|
10800
|
+
first: tokens.item(a),
|
|
10801
|
+
second: tokens.item(b)
|
|
10802
|
+
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
10803
|
+
};
|
|
10804
|
+
this.report({
|
|
10805
|
+
node,
|
|
10806
|
+
message: getTerminalMessage(context),
|
|
10807
|
+
location: tokens.location(b),
|
|
10808
|
+
context
|
|
10809
|
+
});
|
|
10810
|
+
}
|
|
10811
|
+
validateOrder(node, tokens, order) {
|
|
10812
|
+
const indicies = order.map((it) => expectedOrder.indexOf(it));
|
|
10813
|
+
for (let i = 0; i < indicies.length - 1; i++) {
|
|
10814
|
+
if (indicies[0] <= indicies[i + 1]) {
|
|
10815
|
+
continue;
|
|
10816
|
+
}
|
|
10817
10817
|
const context = {
|
|
10818
|
-
msg:
|
|
10818
|
+
msg: 2 /* InvalidOrder */,
|
|
10819
10819
|
/* eslint-disable @typescript-eslint/no-non-null-assertion -- it must be present of it wouldn't be found */
|
|
10820
|
-
first: tokens.item(
|
|
10821
|
-
second: tokens.item(
|
|
10820
|
+
first: tokens.item(i),
|
|
10821
|
+
second: tokens.item(i + 1)
|
|
10822
10822
|
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
10823
10823
|
};
|
|
10824
10824
|
this.report({
|
|
10825
10825
|
node,
|
|
10826
10826
|
message: getTerminalMessage(context),
|
|
10827
|
-
location: tokens.location(
|
|
10827
|
+
location: tokens.location(i + 1),
|
|
10828
10828
|
context
|
|
10829
10829
|
});
|
|
10830
10830
|
}
|
|
10831
10831
|
}
|
|
10832
|
-
validateOrder(node, tokens, order) {
|
|
10833
|
-
const indicies = order.map((it) => expectedOrder.indexOf(it));
|
|
10834
|
-
for (let i = 0; i < indicies.length - 1; i++) {
|
|
10835
|
-
if (indicies[0] > indicies[i + 1]) {
|
|
10836
|
-
const context = {
|
|
10837
|
-
msg: 2 /* InvalidOrder */,
|
|
10838
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion -- it must be present of it wouldn't be found */
|
|
10839
|
-
first: tokens.item(i),
|
|
10840
|
-
second: tokens.item(i + 1)
|
|
10841
|
-
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
10842
|
-
};
|
|
10843
|
-
this.report({
|
|
10844
|
-
node,
|
|
10845
|
-
message: getTerminalMessage(context),
|
|
10846
|
-
location: tokens.location(i + 1),
|
|
10847
|
-
context
|
|
10848
|
-
});
|
|
10849
|
-
}
|
|
10850
|
-
}
|
|
10851
|
-
}
|
|
10852
10832
|
validateControlGroup(node, tokens, fieldTokens) {
|
|
10853
10833
|
const numFields = fieldTokens.filter(Boolean).length;
|
|
10854
10834
|
if (numFields === 0) {
|
|
@@ -10940,7 +10920,7 @@ class ValidID extends Rule {
|
|
|
10940
10920
|
documentation(context) {
|
|
10941
10921
|
const { relaxed } = this.options;
|
|
10942
10922
|
const { kind, id } = context;
|
|
10943
|
-
const message = this.messages[kind].replace(`"{{ id }}"`, "`{{ id }}`").replace("id", "ID").replace(
|
|
10923
|
+
const message = this.messages[kind].replace(`"{{ id }}"`, "`{{ id }}`").replace("id", "ID").replace(/^./, (m) => m.toUpperCase());
|
|
10944
10924
|
const relaxedDescription = relaxed ? [] : [
|
|
10945
10925
|
" - ID must begin with a letter",
|
|
10946
10926
|
" - ID must only contain letters, digits, `-` and `_`"
|
|
@@ -10978,7 +10958,7 @@ class ValidID extends Rule {
|
|
|
10978
10958
|
if (relaxed) {
|
|
10979
10959
|
return;
|
|
10980
10960
|
}
|
|
10981
|
-
if (
|
|
10961
|
+
if (new RegExp("^\\P{L}", "u").test(value)) {
|
|
10982
10962
|
const context = { kind: 3 /* LEADING_CHARACTER */, id: value };
|
|
10983
10963
|
this.report(event.target, this.messages[context.kind], event.valueLocation, context);
|
|
10984
10964
|
return;
|
|
@@ -11339,7 +11319,7 @@ function isSimpleTable(table) {
|
|
|
11339
11319
|
return false;
|
|
11340
11320
|
}
|
|
11341
11321
|
const numColumns = cells[0].length;
|
|
11342
|
-
if (
|
|
11322
|
+
if (cells.some((row) => row.length !== numColumns)) {
|
|
11343
11323
|
return false;
|
|
11344
11324
|
}
|
|
11345
11325
|
const shape = getShape(cells);
|
|
@@ -11993,7 +11973,7 @@ class ResolvedConfig {
|
|
|
11993
11973
|
}
|
|
11994
11974
|
|
|
11995
11975
|
function haveResolver(key, value) {
|
|
11996
|
-
return key
|
|
11976
|
+
return Object.hasOwn(value, key);
|
|
11997
11977
|
}
|
|
11998
11978
|
function haveConfigResolver(value) {
|
|
11999
11979
|
return haveResolver("resolveConfig", value);
|
|
@@ -12008,7 +11988,10 @@ function haveTransformerResolver(value) {
|
|
|
12008
11988
|
return haveResolver("resolveTransformer", value);
|
|
12009
11989
|
}
|
|
12010
11990
|
function resolveConfig(resolvers, id, options) {
|
|
12011
|
-
for (const resolver of resolvers
|
|
11991
|
+
for (const resolver of resolvers) {
|
|
11992
|
+
if (!haveConfigResolver(resolver)) {
|
|
11993
|
+
continue;
|
|
11994
|
+
}
|
|
12012
11995
|
const config = resolver.resolveConfig(id, options);
|
|
12013
11996
|
if (isThenable(config)) {
|
|
12014
11997
|
return resolveConfigAsync(resolvers, id, options);
|
|
@@ -12020,7 +12003,10 @@ function resolveConfig(resolvers, id, options) {
|
|
|
12020
12003
|
throw new UserError(`Failed to load configuration from "${id}"`);
|
|
12021
12004
|
}
|
|
12022
12005
|
async function resolveConfigAsync(resolvers, id, options) {
|
|
12023
|
-
for (const resolver of resolvers
|
|
12006
|
+
for (const resolver of resolvers) {
|
|
12007
|
+
if (!haveConfigResolver(resolver)) {
|
|
12008
|
+
continue;
|
|
12009
|
+
}
|
|
12024
12010
|
const config = await resolver.resolveConfig(id, options);
|
|
12025
12011
|
if (config) {
|
|
12026
12012
|
return config;
|
|
@@ -12029,7 +12015,10 @@ async function resolveConfigAsync(resolvers, id, options) {
|
|
|
12029
12015
|
throw new UserError(`Failed to load configuration from "${id}"`);
|
|
12030
12016
|
}
|
|
12031
12017
|
function resolveElements(resolvers, id, options) {
|
|
12032
|
-
for (const resolver of resolvers
|
|
12018
|
+
for (const resolver of resolvers) {
|
|
12019
|
+
if (!haveElementsResolver(resolver)) {
|
|
12020
|
+
continue;
|
|
12021
|
+
}
|
|
12033
12022
|
const elements = resolver.resolveElements(id, options);
|
|
12034
12023
|
if (isThenable(elements)) {
|
|
12035
12024
|
return resolveElementsAsync(resolvers, id, options);
|
|
@@ -12041,7 +12030,10 @@ function resolveElements(resolvers, id, options) {
|
|
|
12041
12030
|
throw new UserError(`Failed to load elements from "${id}"`);
|
|
12042
12031
|
}
|
|
12043
12032
|
async function resolveElementsAsync(resolvers, id, options) {
|
|
12044
|
-
for (const resolver of resolvers
|
|
12033
|
+
for (const resolver of resolvers) {
|
|
12034
|
+
if (!haveElementsResolver(resolver)) {
|
|
12035
|
+
continue;
|
|
12036
|
+
}
|
|
12045
12037
|
const elements = await resolver.resolveElements(id, options);
|
|
12046
12038
|
if (elements) {
|
|
12047
12039
|
return elements;
|
|
@@ -12050,7 +12042,10 @@ async function resolveElementsAsync(resolvers, id, options) {
|
|
|
12050
12042
|
throw new UserError(`Failed to load elements from "${id}"`);
|
|
12051
12043
|
}
|
|
12052
12044
|
function resolvePlugin(resolvers, id, options) {
|
|
12053
|
-
for (const resolver of resolvers
|
|
12045
|
+
for (const resolver of resolvers) {
|
|
12046
|
+
if (!havePluginResolver(resolver)) {
|
|
12047
|
+
continue;
|
|
12048
|
+
}
|
|
12054
12049
|
const plugin = resolver.resolvePlugin(id, options);
|
|
12055
12050
|
if (isThenable(plugin)) {
|
|
12056
12051
|
return resolvePluginAsync(resolvers, id, options);
|
|
@@ -12062,7 +12057,10 @@ function resolvePlugin(resolvers, id, options) {
|
|
|
12062
12057
|
throw new UserError(`Failed to load plugin from "${id}"`);
|
|
12063
12058
|
}
|
|
12064
12059
|
async function resolvePluginAsync(resolvers, id, options) {
|
|
12065
|
-
for (const resolver of resolvers
|
|
12060
|
+
for (const resolver of resolvers) {
|
|
12061
|
+
if (!havePluginResolver(resolver)) {
|
|
12062
|
+
continue;
|
|
12063
|
+
}
|
|
12066
12064
|
const plugin = await resolver.resolvePlugin(id, options);
|
|
12067
12065
|
if (plugin) {
|
|
12068
12066
|
return plugin;
|
|
@@ -12071,7 +12069,10 @@ async function resolvePluginAsync(resolvers, id, options) {
|
|
|
12071
12069
|
throw new UserError(`Failed to load plugin from "${id}"`);
|
|
12072
12070
|
}
|
|
12073
12071
|
function resolveTransformer(resolvers, id, options) {
|
|
12074
|
-
for (const resolver of resolvers
|
|
12072
|
+
for (const resolver of resolvers) {
|
|
12073
|
+
if (!haveTransformerResolver(resolver)) {
|
|
12074
|
+
continue;
|
|
12075
|
+
}
|
|
12075
12076
|
const transformer = resolver.resolveTransformer(id, options);
|
|
12076
12077
|
if (isThenable(transformer)) {
|
|
12077
12078
|
return resolveTransformerAsync(resolvers, id, options);
|
|
@@ -12083,7 +12084,10 @@ function resolveTransformer(resolvers, id, options) {
|
|
|
12083
12084
|
throw new UserError(`Failed to load transformer from "${id}"`);
|
|
12084
12085
|
}
|
|
12085
12086
|
async function resolveTransformerAsync(resolvers, id, options) {
|
|
12086
|
-
for (const resolver of resolvers
|
|
12087
|
+
for (const resolver of resolvers) {
|
|
12088
|
+
if (!haveTransformerResolver(resolver)) {
|
|
12089
|
+
continue;
|
|
12090
|
+
}
|
|
12087
12091
|
const transformer = await resolver.resolveTransformer(id, options);
|
|
12088
12092
|
if (transformer) {
|
|
12089
12093
|
return transformer;
|
|
@@ -12123,9 +12127,12 @@ function staticResolver(map = {}) {
|
|
|
12123
12127
|
};
|
|
12124
12128
|
}
|
|
12125
12129
|
|
|
12126
|
-
const ajv =
|
|
12127
|
-
|
|
12128
|
-
|
|
12130
|
+
const ajv = (() => {
|
|
12131
|
+
const ajv2 = new Ajv__default.default({ strict: true, strictTuples: true, strictTypes: true });
|
|
12132
|
+
ajv2.addMetaSchema(ajvSchemaDraft);
|
|
12133
|
+
ajv2.addKeyword(ajvFunctionKeyword);
|
|
12134
|
+
return ajv2;
|
|
12135
|
+
})();
|
|
12129
12136
|
const validator = ajv.compile(configurationSchema);
|
|
12130
12137
|
function overwriteMerge(_a, b) {
|
|
12131
12138
|
return b;
|
|
@@ -12144,18 +12151,16 @@ function mergeInternal(base, rhs) {
|
|
|
12144
12151
|
function toArray$1(value) {
|
|
12145
12152
|
if (Array.isArray(value)) {
|
|
12146
12153
|
return value;
|
|
12147
|
-
} else {
|
|
12148
|
-
return [value];
|
|
12149
12154
|
}
|
|
12155
|
+
return [value];
|
|
12150
12156
|
}
|
|
12151
12157
|
function transformerEntries(transform) {
|
|
12152
12158
|
return Object.entries(transform).map(([pattern, value]) => {
|
|
12153
12159
|
const regex = new RegExp(pattern);
|
|
12154
12160
|
if (typeof value === "string") {
|
|
12155
12161
|
return { kind: "import", pattern: regex, name: value };
|
|
12156
|
-
} else {
|
|
12157
|
-
return { kind: "function", pattern: regex, function: value };
|
|
12158
12162
|
}
|
|
12163
|
+
return { kind: "function", pattern: regex, function: value };
|
|
12159
12164
|
});
|
|
12160
12165
|
}
|
|
12161
12166
|
class Config {
|
|
@@ -12180,8 +12185,8 @@ class Config {
|
|
|
12180
12185
|
* Create configuration from object.
|
|
12181
12186
|
*/
|
|
12182
12187
|
static fromObject(resolvers, options, filename = null) {
|
|
12183
|
-
|
|
12184
|
-
return
|
|
12188
|
+
this.validate(options, filename);
|
|
12189
|
+
return this.create(resolvers, options);
|
|
12185
12190
|
}
|
|
12186
12191
|
/**
|
|
12187
12192
|
* Read configuration from filename.
|
|
@@ -12195,10 +12200,9 @@ class Config {
|
|
|
12195
12200
|
static fromFile(resolvers, filename) {
|
|
12196
12201
|
const configData = resolveConfig(toArray$1(resolvers), filename, { cache: false });
|
|
12197
12202
|
if (isThenable(configData)) {
|
|
12198
|
-
return configData.then((configData2) =>
|
|
12199
|
-
} else {
|
|
12200
|
-
return Config.fromObject(resolvers, configData, filename);
|
|
12203
|
+
return configData.then((configData2) => this.fromObject(resolvers, configData2, filename));
|
|
12201
12204
|
}
|
|
12205
|
+
return this.fromObject(resolvers, configData, filename);
|
|
12202
12206
|
}
|
|
12203
12207
|
/**
|
|
12204
12208
|
* Validate configuration data.
|
|
@@ -12220,8 +12224,8 @@ class Config {
|
|
|
12220
12224
|
);
|
|
12221
12225
|
}
|
|
12222
12226
|
if (configData.rules) {
|
|
12223
|
-
const normalizedRules =
|
|
12224
|
-
for (const [ruleId, [, ruleOptions]] of normalizedRules
|
|
12227
|
+
const normalizedRules = this.getRulesObject(configData.rules);
|
|
12228
|
+
for (const [ruleId, [, ruleOptions]] of normalizedRules) {
|
|
12225
12229
|
const cls = bundledRules[ruleId];
|
|
12226
12230
|
const path = `/rules/${ruleId}/1`;
|
|
12227
12231
|
Rule.validateOptions(cls, ruleId, path, ruleOptions, filename, configData);
|
|
@@ -12244,9 +12248,8 @@ class Config {
|
|
|
12244
12248
|
return plugins.then((plugins2) => {
|
|
12245
12249
|
return instance.init(options, plugins2);
|
|
12246
12250
|
});
|
|
12247
|
-
} else {
|
|
12248
|
-
return instance.init(options, plugins);
|
|
12249
12251
|
}
|
|
12252
|
+
return instance.init(options, plugins);
|
|
12250
12253
|
}
|
|
12251
12254
|
init(options, plugins) {
|
|
12252
12255
|
this.plugins = plugins;
|
|
@@ -12263,9 +12266,8 @@ class Config {
|
|
|
12263
12266
|
const extendedConfig = this.extendConfig(this.config.extends ?? []);
|
|
12264
12267
|
if (isThenable(extendedConfig)) {
|
|
12265
12268
|
return extendedConfig.then((extended) => update(extended));
|
|
12266
|
-
} else {
|
|
12267
|
-
return update(extendedConfig);
|
|
12268
12269
|
}
|
|
12270
|
+
return update(extendedConfig);
|
|
12269
12271
|
}
|
|
12270
12272
|
/**
|
|
12271
12273
|
* @internal
|
|
@@ -12307,12 +12309,11 @@ class Config {
|
|
|
12307
12309
|
instance.extendMeta(instance.plugins);
|
|
12308
12310
|
return instance;
|
|
12309
12311
|
});
|
|
12310
|
-
} else {
|
|
12311
|
-
instance.plugins = plugins;
|
|
12312
|
-
instance.configurations = instance.loadConfigurations(instance.plugins);
|
|
12313
|
-
instance.extendMeta(instance.plugins);
|
|
12314
|
-
return instance;
|
|
12315
12312
|
}
|
|
12313
|
+
instance.plugins = plugins;
|
|
12314
|
+
instance.configurations = instance.loadConfigurations(instance.plugins);
|
|
12315
|
+
instance.extendMeta(instance.plugins);
|
|
12316
|
+
return instance;
|
|
12316
12317
|
}
|
|
12317
12318
|
extendConfig(entries) {
|
|
12318
12319
|
if (entries.length === 0) {
|
|
@@ -12368,20 +12369,19 @@ class Config {
|
|
|
12368
12369
|
const result = this.getElementsFromEntry(entry);
|
|
12369
12370
|
if (isThenable(result)) {
|
|
12370
12371
|
return result.then((result2) => {
|
|
12371
|
-
const [
|
|
12372
|
-
metaTable.loadFromObject(
|
|
12373
|
-
const
|
|
12374
|
-
if (
|
|
12375
|
-
return loadEntry(
|
|
12372
|
+
const [obj2, filename2] = result2;
|
|
12373
|
+
metaTable.loadFromObject(obj2, filename2);
|
|
12374
|
+
const next3 = source.shift();
|
|
12375
|
+
if (next3) {
|
|
12376
|
+
return loadEntry(next3);
|
|
12376
12377
|
}
|
|
12377
12378
|
});
|
|
12378
|
-
}
|
|
12379
|
-
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
}
|
|
12379
|
+
}
|
|
12380
|
+
const [obj, filename] = result;
|
|
12381
|
+
metaTable.loadFromObject(obj, filename);
|
|
12382
|
+
const next2 = source.shift();
|
|
12383
|
+
if (next2) {
|
|
12384
|
+
return loadEntry(next2);
|
|
12385
12385
|
}
|
|
12386
12386
|
};
|
|
12387
12387
|
const next = source.shift();
|
|
@@ -12411,9 +12411,8 @@ class Config {
|
|
|
12411
12411
|
return obj.then((obj2) => {
|
|
12412
12412
|
return [obj2, entry];
|
|
12413
12413
|
});
|
|
12414
|
-
} else {
|
|
12415
|
-
return [obj, entry];
|
|
12416
12414
|
}
|
|
12415
|
+
return [obj, entry];
|
|
12417
12416
|
} catch (err) {
|
|
12418
12417
|
const message = err instanceof Error ? err.message : String(err);
|
|
12419
12418
|
throw new ConfigError(
|
|
@@ -12475,7 +12474,7 @@ class Config {
|
|
|
12475
12474
|
const loadPlugin = (entry, index) => {
|
|
12476
12475
|
if (typeof entry !== "string") {
|
|
12477
12476
|
const plugin = entry;
|
|
12478
|
-
plugin.name
|
|
12477
|
+
plugin.name ||= `:unnamedPlugin@${String(index + 1)}`;
|
|
12479
12478
|
plugin.originalName = `:unnamedPlugin@${String(index + 1)}`;
|
|
12480
12479
|
loaded.push(plugin);
|
|
12481
12480
|
const next2 = loading.shift();
|
|
@@ -12487,22 +12486,21 @@ class Config {
|
|
|
12487
12486
|
const plugin = resolvePlugin(this.resolvers, entry, { cache: true });
|
|
12488
12487
|
if (isThenable(plugin)) {
|
|
12489
12488
|
return plugin.then((plugin2) => {
|
|
12490
|
-
plugin2.name
|
|
12489
|
+
plugin2.name ||= entry;
|
|
12491
12490
|
plugin2.originalName = entry;
|
|
12492
12491
|
loaded.push(plugin2);
|
|
12493
|
-
const
|
|
12494
|
-
if (
|
|
12495
|
-
return loadPlugin(
|
|
12492
|
+
const next3 = loading.shift();
|
|
12493
|
+
if (next3) {
|
|
12494
|
+
return loadPlugin(next3, index + 1);
|
|
12496
12495
|
}
|
|
12497
12496
|
});
|
|
12498
|
-
}
|
|
12499
|
-
|
|
12500
|
-
|
|
12501
|
-
|
|
12502
|
-
|
|
12503
|
-
|
|
12504
|
-
|
|
12505
|
-
}
|
|
12497
|
+
}
|
|
12498
|
+
plugin.name ||= entry;
|
|
12499
|
+
plugin.originalName = entry;
|
|
12500
|
+
loaded.push(plugin);
|
|
12501
|
+
const next2 = loading.shift();
|
|
12502
|
+
if (next2) {
|
|
12503
|
+
return loadPlugin(next2, index + 1);
|
|
12506
12504
|
}
|
|
12507
12505
|
} catch (err) {
|
|
12508
12506
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -12528,7 +12526,8 @@ class Config {
|
|
|
12528
12526
|
configs.set(name, config);
|
|
12529
12527
|
}
|
|
12530
12528
|
for (const plugin of plugins) {
|
|
12531
|
-
|
|
12529
|
+
const entries = Object.entries(plugin.configs ?? {});
|
|
12530
|
+
for (const [name, config] of entries) {
|
|
12532
12531
|
if (!config) {
|
|
12533
12532
|
continue;
|
|
12534
12533
|
}
|
|
@@ -12572,9 +12571,8 @@ class Config {
|
|
|
12572
12571
|
return resolveData.then((resolveData2) => {
|
|
12573
12572
|
return new ResolvedConfig(resolveData2, this.get());
|
|
12574
12573
|
});
|
|
12575
|
-
} else {
|
|
12576
|
-
return new ResolvedConfig(resolveData, this.get());
|
|
12577
12574
|
}
|
|
12575
|
+
return new ResolvedConfig(resolveData, this.get());
|
|
12578
12576
|
}
|
|
12579
12577
|
/**
|
|
12580
12578
|
* Same as [[resolve]] but returns the raw configuration data instead of
|
|
@@ -12593,14 +12591,13 @@ class Config {
|
|
|
12593
12591
|
transformers: this.transformers
|
|
12594
12592
|
};
|
|
12595
12593
|
});
|
|
12596
|
-
} else {
|
|
12597
|
-
return {
|
|
12598
|
-
metaTable,
|
|
12599
|
-
plugins: this.getPlugins(),
|
|
12600
|
-
rules: this.getRules(),
|
|
12601
|
-
transformers: this.transformers
|
|
12602
|
-
};
|
|
12603
12594
|
}
|
|
12595
|
+
return {
|
|
12596
|
+
metaTable,
|
|
12597
|
+
plugins: this.getPlugins(),
|
|
12598
|
+
rules: this.getRules(),
|
|
12599
|
+
transformers: this.transformers
|
|
12600
|
+
};
|
|
12604
12601
|
}
|
|
12605
12602
|
}
|
|
12606
12603
|
|
|
@@ -12644,10 +12641,9 @@ class ConfigLoader {
|
|
|
12644
12641
|
this._globalConfig = config2;
|
|
12645
12642
|
return this._globalConfig;
|
|
12646
12643
|
});
|
|
12647
|
-
} else {
|
|
12648
|
-
this._globalConfig = config;
|
|
12649
|
-
return this._globalConfig;
|
|
12650
12644
|
}
|
|
12645
|
+
this._globalConfig = config;
|
|
12646
|
+
return this._globalConfig;
|
|
12651
12647
|
}
|
|
12652
12648
|
/**
|
|
12653
12649
|
* Get the global configuration.
|
|
@@ -12729,9 +12725,8 @@ class StaticConfigLoader extends ConfigLoader {
|
|
|
12729
12725
|
const override = this.loadFromObject(configOverride ?? {});
|
|
12730
12726
|
if (isThenable(override)) {
|
|
12731
12727
|
return override.then((override2) => this._resolveConfig(override2));
|
|
12732
|
-
} else {
|
|
12733
|
-
return this._resolveConfig(override);
|
|
12734
12728
|
}
|
|
12729
|
+
return this._resolveConfig(override);
|
|
12735
12730
|
}
|
|
12736
12731
|
flushCache() {
|
|
12737
12732
|
}
|
|
@@ -12748,25 +12743,22 @@ class StaticConfigLoader extends ConfigLoader {
|
|
|
12748
12743
|
const globalConfig = this.getGlobalConfig();
|
|
12749
12744
|
if (isThenable(globalConfig)) {
|
|
12750
12745
|
return globalConfig.then((globalConfig2) => {
|
|
12751
|
-
const
|
|
12752
|
-
if (isThenable(
|
|
12753
|
-
return
|
|
12754
|
-
return
|
|
12746
|
+
const merged2 = globalConfig2.merge(this.resolvers, override);
|
|
12747
|
+
if (isThenable(merged2)) {
|
|
12748
|
+
return merged2.then((merged3) => {
|
|
12749
|
+
return merged3.resolve();
|
|
12755
12750
|
});
|
|
12756
|
-
} else {
|
|
12757
|
-
return merged.resolve();
|
|
12758
12751
|
}
|
|
12752
|
+
return merged2.resolve();
|
|
12753
|
+
});
|
|
12754
|
+
}
|
|
12755
|
+
const merged = globalConfig.merge(this.resolvers, override);
|
|
12756
|
+
if (isThenable(merged)) {
|
|
12757
|
+
return merged.then((merged2) => {
|
|
12758
|
+
return merged2.resolve();
|
|
12759
12759
|
});
|
|
12760
|
-
} else {
|
|
12761
|
-
const merged = globalConfig.merge(this.resolvers, override);
|
|
12762
|
-
if (isThenable(merged)) {
|
|
12763
|
-
return merged.then((merged2) => {
|
|
12764
|
-
return merged2.resolve();
|
|
12765
|
-
});
|
|
12766
|
-
} else {
|
|
12767
|
-
return merged.resolve();
|
|
12768
|
-
}
|
|
12769
12760
|
}
|
|
12761
|
+
return merged.resolve();
|
|
12770
12762
|
}
|
|
12771
12763
|
}
|
|
12772
12764
|
|
|
@@ -12853,7 +12845,7 @@ class EventHandler {
|
|
|
12853
12845
|
}
|
|
12854
12846
|
|
|
12855
12847
|
const name = "html-validate";
|
|
12856
|
-
const version = "11.5.
|
|
12848
|
+
const version = "11.5.5";
|
|
12857
12849
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
12858
12850
|
|
|
12859
12851
|
function freeze(src) {
|
|
@@ -12891,7 +12883,7 @@ class Reporter {
|
|
|
12891
12883
|
for (const report of reports) {
|
|
12892
12884
|
for (const result of report.results) {
|
|
12893
12885
|
const key = result.filePath;
|
|
12894
|
-
if (key
|
|
12886
|
+
if (Object.hasOwn(merged, key)) {
|
|
12895
12887
|
merged[key].messages = [...merged[key].messages, ...result.messages];
|
|
12896
12888
|
} else {
|
|
12897
12889
|
merged[key] = { ...result };
|
|
@@ -12915,7 +12907,7 @@ class Reporter {
|
|
|
12915
12907
|
*/
|
|
12916
12908
|
add(options) {
|
|
12917
12909
|
const { rule, message, severity, node, location, context } = options;
|
|
12918
|
-
if (!(location.filename
|
|
12910
|
+
if (!Object.hasOwn(this.result, location.filename)) {
|
|
12919
12911
|
this.result[location.filename] = [];
|
|
12920
12912
|
}
|
|
12921
12913
|
const ruleUrl = rule.documentation(context)?.url;
|
|
@@ -12943,7 +12935,7 @@ class Reporter {
|
|
|
12943
12935
|
* @internal
|
|
12944
12936
|
*/
|
|
12945
12937
|
addManual(filename, message) {
|
|
12946
|
-
if (!(
|
|
12938
|
+
if (!Object.hasOwn(this.result, filename)) {
|
|
12947
12939
|
this.result[filename] = [];
|
|
12948
12940
|
}
|
|
12949
12941
|
this.result[filename].push(message);
|
|
@@ -12954,6 +12946,7 @@ class Reporter {
|
|
|
12954
12946
|
save(sources) {
|
|
12955
12947
|
const report = {
|
|
12956
12948
|
valid: this.isValid(),
|
|
12949
|
+
/* eslint-disable-next-line unicorn/prefer-object-iterable-methods -- technical debt */
|
|
12957
12950
|
results: Object.keys(this.result).map((filePath) => {
|
|
12958
12951
|
const messages = Array.from(this.result[filePath], freeze).toSorted(messageSort);
|
|
12959
12952
|
const source = (sources ?? []).find((source2) => filePath === source2.filename);
|
|
@@ -13018,7 +13011,7 @@ function definePlugin(plugin) {
|
|
|
13018
13011
|
return plugin;
|
|
13019
13012
|
}
|
|
13020
13013
|
|
|
13021
|
-
const regexp = /<!(?:--)?\[(.*?)](?:--)?>/g;
|
|
13014
|
+
const regexp = /<!(?:--)?\[(.*?)\](?:--)?>/g;
|
|
13022
13015
|
function* parseConditionalComment(comment, commentLocation) {
|
|
13023
13016
|
let match;
|
|
13024
13017
|
while ((match = regexp.exec(comment)) !== null) {
|
|
@@ -13035,6 +13028,7 @@ function* parseConditionalComment(comment, commentLocation) {
|
|
|
13035
13028
|
|
|
13036
13029
|
class ParserError extends Error {
|
|
13037
13030
|
location;
|
|
13031
|
+
/* eslint-disable-next-line unicorn/custom-error-definition -- technical debt */
|
|
13038
13032
|
constructor(location, message) {
|
|
13039
13033
|
super(message);
|
|
13040
13034
|
this.name = "ParserError";
|
|
@@ -13198,9 +13192,8 @@ class Parser {
|
|
|
13198
13192
|
const open = !token.data[1];
|
|
13199
13193
|
if (open) {
|
|
13200
13194
|
return this.wouldCloseElement(token, active);
|
|
13201
|
-
} else {
|
|
13202
|
-
return this.closeOptionalEndTag(token, active);
|
|
13203
13195
|
}
|
|
13196
|
+
return this.closeOptionalEndTag(token, active);
|
|
13204
13197
|
}
|
|
13205
13198
|
/**
|
|
13206
13199
|
* Returns `true` if the element’s end tag may be omitted, either because
|
|
@@ -13552,9 +13545,8 @@ class Parser {
|
|
|
13552
13545
|
const quote = token.data[3];
|
|
13553
13546
|
if (quote) {
|
|
13554
13547
|
return sliceLocation(token.location, 2, -1);
|
|
13555
|
-
} else {
|
|
13556
|
-
return sliceLocation(token.location, 1);
|
|
13557
13548
|
}
|
|
13549
|
+
return sliceLocation(token.location, 1);
|
|
13558
13550
|
}
|
|
13559
13551
|
/**
|
|
13560
13552
|
* Take attribute key and value token an returns a new location referring to
|
|
@@ -13842,13 +13834,14 @@ class PerformanceTracker {
|
|
|
13842
13834
|
*/
|
|
13843
13835
|
getResult() {
|
|
13844
13836
|
const events = Array.from(
|
|
13845
|
-
this.eventData
|
|
13837
|
+
this.eventData,
|
|
13846
13838
|
([event, { count, time }]) => ({ event, count, time })
|
|
13847
13839
|
).toSorted((a, b) => b.time - a.time);
|
|
13848
|
-
const rules = Array.from(
|
|
13849
|
-
|
|
13850
|
-
|
|
13851
|
-
|
|
13840
|
+
const rules = Array.from(this.ruleData, ([rule, { count, time }]) => ({
|
|
13841
|
+
rule,
|
|
13842
|
+
count,
|
|
13843
|
+
time
|
|
13844
|
+
})).toSorted((a, b) => b.time - a.time);
|
|
13852
13845
|
return {
|
|
13853
13846
|
events,
|
|
13854
13847
|
rules,
|
|
@@ -13895,9 +13888,11 @@ function dumpTree(root) {
|
|
|
13895
13888
|
return lines;
|
|
13896
13889
|
}
|
|
13897
13890
|
|
|
13898
|
-
|
|
13891
|
+
const state = {
|
|
13892
|
+
blockerCounter: 1
|
|
13893
|
+
};
|
|
13899
13894
|
function createBlocker() {
|
|
13900
|
-
const id = blockerCounter++;
|
|
13895
|
+
const id = state.blockerCounter++;
|
|
13901
13896
|
return id;
|
|
13902
13897
|
}
|
|
13903
13898
|
|
|
@@ -14033,9 +14028,8 @@ class Engine {
|
|
|
14033
14028
|
const [, options] = ruleData;
|
|
14034
14029
|
const rule = this.instantiateRule(ruleId, options);
|
|
14035
14030
|
return rule.documentation(context);
|
|
14036
|
-
} else {
|
|
14037
|
-
return null;
|
|
14038
14031
|
}
|
|
14032
|
+
return null;
|
|
14039
14033
|
}
|
|
14040
14034
|
/**
|
|
14041
14035
|
* Create a new parser instance with the current configuration.
|
|
@@ -14164,7 +14158,8 @@ class Engine {
|
|
|
14164
14158
|
initRules(config) {
|
|
14165
14159
|
const availableRules = {};
|
|
14166
14160
|
for (const plugin of config.getPlugins()) {
|
|
14167
|
-
|
|
14161
|
+
const entries = Object.entries(plugin.rules ?? {});
|
|
14162
|
+
for (const [name, rule] of entries) {
|
|
14168
14163
|
if (!rule) {
|
|
14169
14164
|
continue;
|
|
14170
14165
|
}
|
|
@@ -14192,7 +14187,7 @@ class Engine {
|
|
|
14192
14187
|
*/
|
|
14193
14188
|
setupRules(config, parser) {
|
|
14194
14189
|
const rules = {};
|
|
14195
|
-
for (const [ruleId, [severity, options]] of config.getRules()
|
|
14190
|
+
for (const [ruleId, [severity, options]] of config.getRules()) {
|
|
14196
14191
|
rules[ruleId] = this.loadRule(ruleId, config, severity, options, parser, this.report);
|
|
14197
14192
|
}
|
|
14198
14193
|
return rules;
|
|
@@ -14216,9 +14211,8 @@ class Engine {
|
|
|
14216
14211
|
if (this.availableRules[name]) {
|
|
14217
14212
|
const RuleConstructor = this.availableRules[name];
|
|
14218
14213
|
return new RuleConstructor(options);
|
|
14219
|
-
} else {
|
|
14220
|
-
return this.missingRule(name);
|
|
14221
14214
|
}
|
|
14215
|
+
return this.missingRule(name);
|
|
14222
14216
|
}
|
|
14223
14217
|
missingRule(name) {
|
|
14224
14218
|
return new class MissingRule extends Rule {
|
|
@@ -14314,34 +14308,30 @@ function getTransformerFunction(resolvers, name, plugins) {
|
|
|
14314
14308
|
validateTransformer(transformer2);
|
|
14315
14309
|
return transformer2;
|
|
14316
14310
|
});
|
|
14317
|
-
} else {
|
|
14318
|
-
validateTransformer(transformer);
|
|
14319
|
-
return transformer;
|
|
14320
14311
|
}
|
|
14312
|
+
validateTransformer(transformer);
|
|
14313
|
+
return transformer;
|
|
14321
14314
|
} catch (err) {
|
|
14322
14315
|
if (err instanceof ConfigError) {
|
|
14323
14316
|
throw new ConfigError(`Failed to load transformer "${name}": ${err.message}`, err);
|
|
14324
|
-
} else {
|
|
14325
|
-
throw new ConfigError(`Failed to load transformer "${name}"`, ensureError(err));
|
|
14326
14317
|
}
|
|
14318
|
+
throw new ConfigError(`Failed to load transformer "${name}"`, ensureError(err));
|
|
14327
14319
|
}
|
|
14328
14320
|
}
|
|
14329
14321
|
function getCachedTransformerFunction(cache, resolvers, name, plugins) {
|
|
14330
14322
|
const cached = cache.get(name);
|
|
14331
14323
|
if (cached) {
|
|
14332
14324
|
return cached;
|
|
14333
|
-
} else {
|
|
14334
|
-
const transformer = getTransformerFunction(resolvers, name, plugins);
|
|
14335
|
-
if (isThenable(transformer)) {
|
|
14336
|
-
return transformer.then((transformer2) => {
|
|
14337
|
-
cache.set(name, transformer2);
|
|
14338
|
-
return transformer2;
|
|
14339
|
-
});
|
|
14340
|
-
} else {
|
|
14341
|
-
cache.set(name, transformer);
|
|
14342
|
-
return transformer;
|
|
14343
|
-
}
|
|
14344
14325
|
}
|
|
14326
|
+
const transformer = getTransformerFunction(resolvers, name, plugins);
|
|
14327
|
+
if (isThenable(transformer)) {
|
|
14328
|
+
return transformer.then((transformer2) => {
|
|
14329
|
+
cache.set(name, transformer2);
|
|
14330
|
+
return transformer2;
|
|
14331
|
+
});
|
|
14332
|
+
}
|
|
14333
|
+
cache.set(name, transformer);
|
|
14334
|
+
return transformer;
|
|
14345
14335
|
}
|
|
14346
14336
|
|
|
14347
14337
|
function isIterable(value) {
|
|
@@ -14357,6 +14347,9 @@ const asyncInSyncTransformError = "Cannot use async transformer from sync functi
|
|
|
14357
14347
|
async function transformSource(resolvers, config, source, filename) {
|
|
14358
14348
|
const { cache } = config;
|
|
14359
14349
|
const transformer = config.findTransformer(filename ?? source.filename);
|
|
14350
|
+
if (!transformer) {
|
|
14351
|
+
return [source];
|
|
14352
|
+
}
|
|
14360
14353
|
const context = {
|
|
14361
14354
|
hasChain(filename2) {
|
|
14362
14355
|
return config.canTransform(filename2);
|
|
@@ -14365,9 +14358,6 @@ async function transformSource(resolvers, config, source, filename) {
|
|
|
14365
14358
|
return transformSource(resolvers, config, source2, filename2);
|
|
14366
14359
|
}
|
|
14367
14360
|
};
|
|
14368
|
-
if (!transformer) {
|
|
14369
|
-
return [source];
|
|
14370
|
-
}
|
|
14371
14361
|
const fn = transformer.kind === "import" ? await getCachedTransformerFunction(cache, resolvers, transformer.name, config.getPlugins()) : transformer.function;
|
|
14372
14362
|
const name = transformer.kind === "import" ? transformer.name : transformer.function.name;
|
|
14373
14363
|
try {
|
|
@@ -14386,6 +14376,9 @@ async function transformSource(resolvers, config, source, filename) {
|
|
|
14386
14376
|
function transformSourceSync(resolvers, config, source, filename) {
|
|
14387
14377
|
const { cache } = config;
|
|
14388
14378
|
const transformer = config.findTransformer(filename ?? source.filename);
|
|
14379
|
+
if (!transformer) {
|
|
14380
|
+
return [source];
|
|
14381
|
+
}
|
|
14389
14382
|
const context = {
|
|
14390
14383
|
hasChain(filename2) {
|
|
14391
14384
|
return config.canTransform(filename2);
|
|
@@ -14394,14 +14387,11 @@ function transformSourceSync(resolvers, config, source, filename) {
|
|
|
14394
14387
|
return transformSourceSync(resolvers, config, source2, filename2);
|
|
14395
14388
|
}
|
|
14396
14389
|
};
|
|
14397
|
-
if (!transformer) {
|
|
14398
|
-
return [source];
|
|
14399
|
-
}
|
|
14400
14390
|
const fn = transformer.kind === "import" ? getCachedTransformerFunction(cache, resolvers, transformer.name, config.getPlugins()) : transformer.function;
|
|
14401
|
-
const name = transformer.kind === "import" ? transformer.name : transformer.function.name;
|
|
14402
14391
|
if (isThenable(fn)) {
|
|
14403
14392
|
throw new UserError(asyncInSyncTransformError);
|
|
14404
14393
|
}
|
|
14394
|
+
const name = transformer.kind === "import" ? transformer.name : transformer.function.name;
|
|
14405
14395
|
try {
|
|
14406
14396
|
const result = fn.call(context, source);
|
|
14407
14397
|
if (isThenable(result)) {
|
|
@@ -14503,7 +14493,7 @@ function checkstyleFormatter(results) {
|
|
|
14503
14493
|
`;
|
|
14504
14494
|
for (const message of messages) {
|
|
14505
14495
|
const ruleId = xmlescape(`htmlvalidate.rules.${message.ruleId}`);
|
|
14506
|
-
output += "
|
|
14496
|
+
output += " ".repeat(4);
|
|
14507
14497
|
output += [
|
|
14508
14498
|
`<error line="${xmlescape(message.line)}"`,
|
|
14509
14499
|
`column="${xmlescape(message.column)}"`,
|
|
@@ -14590,9 +14580,8 @@ function codeFrameColumns(rawLines, loc) {
|
|
|
14590
14580
|
].join("");
|
|
14591
14581
|
}
|
|
14592
14582
|
return [">", gutter, line.length > 0 ? ` ${line}` : "", markerLine].join("");
|
|
14593
|
-
} else {
|
|
14594
|
-
return [" ", gutter, line.length > 0 ? ` ${line}` : ""].join("");
|
|
14595
14583
|
}
|
|
14584
|
+
return [" ", gutter, line.length > 0 ? ` ${line}` : ""].join("");
|
|
14596
14585
|
}).join("\n");
|
|
14597
14586
|
}
|
|
14598
14587
|
|