html-validate 10.9.0 → 10.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/cli.js +10 -10
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/core-browser.js +1 -1
- package/dist/cjs/core-browser.js.map +1 -1
- package/dist/cjs/core-nodejs.js +1 -1
- package/dist/cjs/core-nodejs.js.map +1 -1
- package/dist/cjs/core.js +179 -120
- package/dist/cjs/core.js.map +1 -1
- package/dist/cjs/elements.js +24 -16
- package/dist/cjs/elements.js.map +1 -1
- package/dist/cjs/html-validate.js +23 -15
- package/dist/cjs/html-validate.js.map +1 -1
- package/dist/cjs/matchers-jestonly.js +2 -2
- package/dist/cjs/matchers-jestonly.js.map +1 -1
- package/dist/cjs/tsdoc-metadata.json +1 -1
- package/dist/cjs/utils/natural-join.js +1 -1
- package/dist/cjs/utils/natural-join.js.map +1 -1
- package/dist/esm/cli.js +10 -10
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/core-browser.js +1 -1
- package/dist/esm/core-browser.js.map +1 -1
- package/dist/esm/core-nodejs.js +1 -1
- package/dist/esm/core-nodejs.js.map +1 -1
- package/dist/esm/core.js +179 -120
- package/dist/esm/core.js.map +1 -1
- package/dist/esm/elements.js +24 -16
- package/dist/esm/elements.js.map +1 -1
- package/dist/esm/html-validate.js +24 -16
- package/dist/esm/html-validate.js.map +1 -1
- package/dist/esm/matchers-jestonly.js +2 -2
- package/dist/esm/matchers-jestonly.js.map +1 -1
- package/dist/esm/utils/natural-join.js +1 -1
- package/dist/esm/utils/natural-join.js.map +1 -1
- package/dist/schema/elements.json +6 -0
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types/browser.d.ts +24 -9
- package/dist/types/index.d.ts +24 -9
- package/package.json +3 -3
package/dist/cjs/core.js
CHANGED
|
@@ -404,6 +404,7 @@ function stringify(value) {
|
|
|
404
404
|
class WrappedError extends Error {
|
|
405
405
|
constructor(message) {
|
|
406
406
|
super(stringify(message));
|
|
407
|
+
this.name = "WrappedError";
|
|
407
408
|
}
|
|
408
409
|
}
|
|
409
410
|
|
|
@@ -418,8 +419,7 @@ function ensureError(value) {
|
|
|
418
419
|
class NestedError extends Error {
|
|
419
420
|
constructor(message, nested) {
|
|
420
421
|
super(message);
|
|
421
|
-
|
|
422
|
-
this.name = NestedError.name;
|
|
422
|
+
this.name = "NestedError";
|
|
423
423
|
if (nested?.stack) {
|
|
424
424
|
this.stack ??= "";
|
|
425
425
|
this.stack += `
|
|
@@ -431,8 +431,7 @@ Caused by: ${nested.stack}`;
|
|
|
431
431
|
class UserError extends NestedError {
|
|
432
432
|
constructor(message, nested) {
|
|
433
433
|
super(message, nested);
|
|
434
|
-
|
|
435
|
-
this.name = UserError.name;
|
|
434
|
+
this.name = "UserError";
|
|
436
435
|
Object.defineProperty(this, "isUserError", {
|
|
437
436
|
value: true,
|
|
438
437
|
enumerable: false,
|
|
@@ -455,8 +454,7 @@ class InheritError extends UserError {
|
|
|
455
454
|
constructor({ tagName, inherit }) {
|
|
456
455
|
const message = `Element <${tagName}> cannot inherit from <${inherit}>: no such element`;
|
|
457
456
|
super(message);
|
|
458
|
-
|
|
459
|
-
this.name = InheritError.name;
|
|
457
|
+
this.name = "InheritError";
|
|
460
458
|
this.tagName = tagName;
|
|
461
459
|
this.inherit = inherit;
|
|
462
460
|
this.filename = null;
|
|
@@ -498,6 +496,7 @@ class SchemaValidationError extends UserError {
|
|
|
498
496
|
constructor(filename, message, obj, schema, errors) {
|
|
499
497
|
const summary = getSummary(schema, obj, errors);
|
|
500
498
|
super(`${message}: ${summary}`);
|
|
499
|
+
this.name = "SchemaValidationError";
|
|
501
500
|
this.filename = filename;
|
|
502
501
|
this.obj = obj;
|
|
503
502
|
this.schema = schema;
|
|
@@ -645,6 +644,18 @@ const patternProperties = {
|
|
|
645
644
|
}
|
|
646
645
|
]
|
|
647
646
|
},
|
|
647
|
+
submitButton: {
|
|
648
|
+
title: "Mark this element as a submit button",
|
|
649
|
+
description: "This element can be used to submit forms.",
|
|
650
|
+
anyOf: [
|
|
651
|
+
{
|
|
652
|
+
type: "boolean"
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
"function": true
|
|
656
|
+
}
|
|
657
|
+
]
|
|
658
|
+
},
|
|
648
659
|
templateRoot: {
|
|
649
660
|
title: "Mark element as an element ignoring DOM ancestry, i.e. <template>.",
|
|
650
661
|
description: "The <template> element can contain any elements.",
|
|
@@ -1028,6 +1039,7 @@ const MetaCopyableProperty = [
|
|
|
1028
1039
|
"form",
|
|
1029
1040
|
"formAssociated",
|
|
1030
1041
|
"labelable",
|
|
1042
|
+
"submitButton",
|
|
1031
1043
|
"attributes",
|
|
1032
1044
|
"aria",
|
|
1033
1045
|
"permittedContent",
|
|
@@ -1042,7 +1054,7 @@ function setMetaProperty(dst, key, value) {
|
|
|
1042
1054
|
}
|
|
1043
1055
|
|
|
1044
1056
|
function isSet(value) {
|
|
1045
|
-
return
|
|
1057
|
+
return value !== void 0;
|
|
1046
1058
|
}
|
|
1047
1059
|
function flag(value) {
|
|
1048
1060
|
return value ? true : void 0;
|
|
@@ -1057,7 +1069,7 @@ function migrateSingleAttribute(src, key) {
|
|
|
1057
1069
|
result.required = flag(src.requiredAttributes?.includes(key));
|
|
1058
1070
|
result.omit = void 0;
|
|
1059
1071
|
const attr = src.attributes ? src.attributes[key] : void 0;
|
|
1060
|
-
if (
|
|
1072
|
+
if (attr === void 0) {
|
|
1061
1073
|
return stripUndefined(result);
|
|
1062
1074
|
}
|
|
1063
1075
|
if (attr === null) {
|
|
@@ -1084,7 +1096,7 @@ function migrateAttributes(src) {
|
|
|
1084
1096
|
...src.requiredAttributes ?? [],
|
|
1085
1097
|
...src.deprecatedAttributes ?? []
|
|
1086
1098
|
/* eslint-disable-next-line sonarjs/no-alphabetical-sort -- not really needed in this case, this is a-z anyway */
|
|
1087
|
-
].
|
|
1099
|
+
].toSorted();
|
|
1088
1100
|
const entries = keys.map((key) => {
|
|
1089
1101
|
return [key, migrateSingleAttribute(src, key)];
|
|
1090
1102
|
});
|
|
@@ -1112,9 +1124,7 @@ function migrateElement(src) {
|
|
|
1112
1124
|
const implicitRole = normalizeAriaImplicitRole(src.implicitRole ?? src.aria?.implicitRole);
|
|
1113
1125
|
const result = {
|
|
1114
1126
|
...src,
|
|
1115
|
-
|
|
1116
|
-
formAssociated: void 0
|
|
1117
|
-
},
|
|
1127
|
+
formAssociated: void 0,
|
|
1118
1128
|
attributes: migrateAttributes(src),
|
|
1119
1129
|
textContent: src.textContent,
|
|
1120
1130
|
focusable: src.focusable ?? false,
|
|
@@ -1149,7 +1159,8 @@ const dynamicKeys = [
|
|
|
1149
1159
|
"phrasing",
|
|
1150
1160
|
"embedded",
|
|
1151
1161
|
"interactive",
|
|
1152
|
-
"labelable"
|
|
1162
|
+
"labelable",
|
|
1163
|
+
"submitButton"
|
|
1153
1164
|
];
|
|
1154
1165
|
const schemaCache = /* @__PURE__ */ new Map();
|
|
1155
1166
|
function clone(src) {
|
|
@@ -1419,13 +1430,10 @@ class Attribute {
|
|
|
1419
1430
|
*/
|
|
1420
1431
|
constructor(key, value, keyLocation, valueLocation, originalAttribute) {
|
|
1421
1432
|
this.key = key;
|
|
1422
|
-
this.value = value;
|
|
1433
|
+
this.value = value ?? null;
|
|
1423
1434
|
this.keyLocation = keyLocation;
|
|
1424
1435
|
this.valueLocation = valueLocation;
|
|
1425
1436
|
this.originalAttribute = originalAttribute;
|
|
1426
|
-
if (typeof this.value === "undefined") {
|
|
1427
|
-
this.value = null;
|
|
1428
|
-
}
|
|
1429
1437
|
}
|
|
1430
1438
|
/**
|
|
1431
1439
|
* Flag set to true if the attribute value is static.
|
|
@@ -1569,11 +1577,11 @@ class Context {
|
|
|
1569
1577
|
while ((offset = consumed.indexOf("\n")) >= 0) {
|
|
1570
1578
|
this.line++;
|
|
1571
1579
|
this.column = 1;
|
|
1572
|
-
consumed = consumed.
|
|
1580
|
+
consumed = consumed.slice(offset + 1);
|
|
1573
1581
|
}
|
|
1574
1582
|
this.column += consumed.length;
|
|
1575
1583
|
this.offset += n;
|
|
1576
|
-
this.string = this.string.
|
|
1584
|
+
this.string = this.string.slice(n);
|
|
1577
1585
|
this.state = state;
|
|
1578
1586
|
}
|
|
1579
1587
|
getLocation(size) {
|
|
@@ -1751,7 +1759,7 @@ class DOMNode {
|
|
|
1751
1759
|
* node has no children.
|
|
1752
1760
|
*/
|
|
1753
1761
|
get lastChild() {
|
|
1754
|
-
return this.childNodes
|
|
1762
|
+
return this.childNodes.at(-1) ?? null;
|
|
1755
1763
|
}
|
|
1756
1764
|
/**
|
|
1757
1765
|
* @internal
|
|
@@ -1866,7 +1874,7 @@ function parse(text, baseLocation) {
|
|
|
1866
1874
|
begin++;
|
|
1867
1875
|
continue;
|
|
1868
1876
|
}
|
|
1869
|
-
const token = text.
|
|
1877
|
+
const token = text.slice(begin, end);
|
|
1870
1878
|
tokens.push(token);
|
|
1871
1879
|
if (locations && baseLocation) {
|
|
1872
1880
|
const location = sliceLocation(baseLocation, begin, end);
|
|
@@ -1881,7 +1889,7 @@ class DOMTokenList extends Array {
|
|
|
1881
1889
|
locations;
|
|
1882
1890
|
constructor(value, location) {
|
|
1883
1891
|
if (value && typeof value === "string") {
|
|
1884
|
-
const normalized = value.
|
|
1892
|
+
const normalized = value.replaceAll(/[\t\r\n]/g, " ");
|
|
1885
1893
|
const { tokens, locations } = parse(normalized, location);
|
|
1886
1894
|
super(...tokens);
|
|
1887
1895
|
this.locations = locations;
|
|
@@ -1971,7 +1979,7 @@ function nthChild(node, args) {
|
|
|
1971
1979
|
if (!args) {
|
|
1972
1980
|
throw new Error("Missing argument to nth-child");
|
|
1973
1981
|
}
|
|
1974
|
-
const n = parseInt(args.trim(), 10);
|
|
1982
|
+
const n = Number.parseInt(args.trim(), 10);
|
|
1975
1983
|
const cur = getNthChild(node);
|
|
1976
1984
|
return cur === n;
|
|
1977
1985
|
}
|
|
@@ -1996,7 +2004,7 @@ function factory(name, context) {
|
|
|
1996
2004
|
}
|
|
1997
2005
|
|
|
1998
2006
|
function stripslashes(value) {
|
|
1999
|
-
return value.
|
|
2007
|
+
return value.replaceAll(/\\(.)/g, "$1");
|
|
2000
2008
|
}
|
|
2001
2009
|
class Condition {
|
|
2002
2010
|
}
|
|
@@ -2195,7 +2203,7 @@ function candidatesFromCombinator(element, combinator) {
|
|
|
2195
2203
|
}
|
|
2196
2204
|
}
|
|
2197
2205
|
function matchElement(element, compounds, context) {
|
|
2198
|
-
const last = compounds
|
|
2206
|
+
const last = compounds.at(-1);
|
|
2199
2207
|
if (!last.match(element, context)) {
|
|
2200
2208
|
return false;
|
|
2201
2209
|
}
|
|
@@ -2212,7 +2220,7 @@ function matchElement(element, compounds, context) {
|
|
|
2212
2220
|
return false;
|
|
2213
2221
|
}
|
|
2214
2222
|
|
|
2215
|
-
const escapedCodepoints = ["9", "a", "d"];
|
|
2223
|
+
const escapedCodepoints = /* @__PURE__ */ new Set(["9", "a", "d"]);
|
|
2216
2224
|
function* splitSelectorElements(selector) {
|
|
2217
2225
|
let begin = 0;
|
|
2218
2226
|
let end = 0;
|
|
@@ -2227,7 +2235,7 @@ function* splitSelectorElements(selector) {
|
|
|
2227
2235
|
return 0 /* INITIAL */;
|
|
2228
2236
|
}
|
|
2229
2237
|
function escapedState(ch) {
|
|
2230
|
-
if (escapedCodepoints.
|
|
2238
|
+
if (escapedCodepoints.has(ch)) {
|
|
2231
2239
|
return 1 /* ESCAPED */;
|
|
2232
2240
|
}
|
|
2233
2241
|
return 0 /* INITIAL */;
|
|
@@ -2267,7 +2275,7 @@ function unescapeCodepoint(value) {
|
|
|
2267
2275
|
"\\a ": "\n",
|
|
2268
2276
|
"\\d ": "\r"
|
|
2269
2277
|
};
|
|
2270
|
-
return value.
|
|
2278
|
+
return value.replaceAll(
|
|
2271
2279
|
/(\\[\u0039\u0061\u0064] )/g,
|
|
2272
2280
|
(_, codepoint) => replacement[codepoint]
|
|
2273
2281
|
);
|
|
@@ -2278,7 +2286,7 @@ function escapeSelectorComponent(text) {
|
|
|
2278
2286
|
"\n": "\\a ",
|
|
2279
2287
|
"\r": "\\d "
|
|
2280
2288
|
};
|
|
2281
|
-
return text.toString().
|
|
2289
|
+
return text.toString().replaceAll(/([\t\n\r]|[^a-z0-9_-])/gi, (_, ch) => {
|
|
2282
2290
|
if (codepoints[ch]) {
|
|
2283
2291
|
return codepoints[ch];
|
|
2284
2292
|
} else {
|
|
@@ -2327,7 +2335,7 @@ class Selector {
|
|
|
2327
2335
|
}
|
|
2328
2336
|
}
|
|
2329
2337
|
static parse(selector) {
|
|
2330
|
-
selector = selector.
|
|
2338
|
+
selector = selector.replaceAll(/([+~>]) /g, "$1");
|
|
2331
2339
|
return Array.from(splitSelectorElements(selector), (element) => {
|
|
2332
2340
|
return new Compound(unescapeCodepoint(element));
|
|
2333
2341
|
});
|
|
@@ -2623,7 +2631,7 @@ class HtmlElement extends DOMNode {
|
|
|
2623
2631
|
}
|
|
2624
2632
|
parts.push(`${cur.tagName.toLowerCase()}:nth-child(${String(index + 1)})`);
|
|
2625
2633
|
}
|
|
2626
|
-
return parts.
|
|
2634
|
+
return parts.toReversed().join(" > ");
|
|
2627
2635
|
}
|
|
2628
2636
|
/**
|
|
2629
2637
|
* Tests if this element has given tagname.
|
|
@@ -2665,7 +2673,7 @@ class HtmlElement extends DOMNode {
|
|
|
2665
2673
|
this.metaElement ??= {};
|
|
2666
2674
|
for (const key of MetaCopyableProperty) {
|
|
2667
2675
|
const value = meta[key];
|
|
2668
|
-
if (
|
|
2676
|
+
if (value !== void 0) {
|
|
2669
2677
|
setMetaProperty(this.metaElement, key, value);
|
|
2670
2678
|
} else {
|
|
2671
2679
|
delete this.metaElement[key];
|
|
@@ -2769,8 +2777,8 @@ class HtmlElement extends DOMNode {
|
|
|
2769
2777
|
if (tabindex.value instanceof DynamicValue) {
|
|
2770
2778
|
return this.cacheSet(TABINDEX, 0);
|
|
2771
2779
|
}
|
|
2772
|
-
const parsed = parseInt(tabindex.value, 10);
|
|
2773
|
-
if (isNaN(parsed)) {
|
|
2780
|
+
const parsed = Number.parseInt(tabindex.value, 10);
|
|
2781
|
+
if (Number.isNaN(parsed)) {
|
|
2774
2782
|
return this.cacheSet(TABINDEX, null);
|
|
2775
2783
|
}
|
|
2776
2784
|
return this.cacheSet(TABINDEX, parsed);
|
|
@@ -2874,7 +2882,10 @@ class HtmlElement extends DOMNode {
|
|
|
2874
2882
|
*/
|
|
2875
2883
|
get lastElementChild() {
|
|
2876
2884
|
const children = this.childElements;
|
|
2877
|
-
return children.length > 0 ?
|
|
2885
|
+
return children.length > 0 ? (
|
|
2886
|
+
/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- it is checked right before this */
|
|
2887
|
+
children.at(-1)
|
|
2888
|
+
) : null;
|
|
2878
2889
|
}
|
|
2879
2890
|
get siblings() {
|
|
2880
2891
|
return this.parent ? this.parent.childElements : [this];
|
|
@@ -2997,7 +3008,9 @@ function depthFirst(root, callback) {
|
|
|
2997
3008
|
root = root.root;
|
|
2998
3009
|
}
|
|
2999
3010
|
function visit(node) {
|
|
3000
|
-
node.childElements
|
|
3011
|
+
for (const child of node.childElements) {
|
|
3012
|
+
visit(child);
|
|
3013
|
+
}
|
|
3001
3014
|
if (!node.isRootElement()) {
|
|
3002
3015
|
callback(node);
|
|
3003
3016
|
}
|
|
@@ -3086,7 +3099,7 @@ class DOMTree {
|
|
|
3086
3099
|
}
|
|
3087
3100
|
}
|
|
3088
3101
|
|
|
3089
|
-
const allowedKeys = ["exclude"];
|
|
3102
|
+
const allowedKeys = /* @__PURE__ */ new Set(["exclude"]);
|
|
3090
3103
|
class Validator {
|
|
3091
3104
|
/**
|
|
3092
3105
|
* Test if element is used in a proper context.
|
|
@@ -3325,7 +3338,7 @@ class Validator {
|
|
|
3325
3338
|
}
|
|
3326
3339
|
function validateKeys(rule) {
|
|
3327
3340
|
for (const key of Object.keys(rule)) {
|
|
3328
|
-
if (!allowedKeys.
|
|
3341
|
+
if (!allowedKeys.has(key)) {
|
|
3329
3342
|
const str = JSON.stringify(rule);
|
|
3330
3343
|
throw new Error(`Permitted rule "${str}" contains unknown property "${key}"`);
|
|
3331
3344
|
}
|
|
@@ -3367,7 +3380,7 @@ function parseSeverity(value) {
|
|
|
3367
3380
|
|
|
3368
3381
|
const cacheKey = /* @__PURE__ */ Symbol("aria-naming");
|
|
3369
3382
|
const defaultValue = "allowed";
|
|
3370
|
-
const prohibitedRoles = [
|
|
3383
|
+
const prohibitedRoles = /* @__PURE__ */ new Set([
|
|
3371
3384
|
"caption",
|
|
3372
3385
|
"code",
|
|
3373
3386
|
"deletion",
|
|
@@ -3379,9 +3392,9 @@ const prohibitedRoles = [
|
|
|
3379
3392
|
"strong",
|
|
3380
3393
|
"subscript",
|
|
3381
3394
|
"superscript"
|
|
3382
|
-
];
|
|
3395
|
+
]);
|
|
3383
3396
|
function byRole(role) {
|
|
3384
|
-
return prohibitedRoles.
|
|
3397
|
+
return prohibitedRoles.has(role) ? "prohibited" : "allowed";
|
|
3385
3398
|
}
|
|
3386
3399
|
function byMeta(element, meta) {
|
|
3387
3400
|
return meta.aria.naming(element._adapter);
|
|
@@ -3433,7 +3446,7 @@ function isInputDisabledImpl(node) {
|
|
|
3433
3446
|
|
|
3434
3447
|
const patternCache = /* @__PURE__ */ new Map();
|
|
3435
3448
|
function compileStringPattern(pattern) {
|
|
3436
|
-
const regexp = pattern.
|
|
3449
|
+
const regexp = pattern.replaceAll(/[*]+/g, ".+");
|
|
3437
3450
|
return new RegExp(`^${regexp}$`);
|
|
3438
3451
|
}
|
|
3439
3452
|
function compileRegExpPattern(pattern) {
|
|
@@ -3708,8 +3721,8 @@ function format(value, quote = false) {
|
|
|
3708
3721
|
return String(value);
|
|
3709
3722
|
}
|
|
3710
3723
|
function interpolate(text, data) {
|
|
3711
|
-
return text.
|
|
3712
|
-
return
|
|
3724
|
+
return text.replaceAll(/{{\s*([^\s{}]+)\s*}}/g, (match, key) => {
|
|
3725
|
+
return data[key] !== void 0 ? format(data[key]) : match;
|
|
3713
3726
|
});
|
|
3714
3727
|
}
|
|
3715
3728
|
|
|
@@ -3917,7 +3930,14 @@ class Rule {
|
|
|
3917
3930
|
});
|
|
3918
3931
|
if (enabled && !blocked) {
|
|
3919
3932
|
const interpolated = interpolate(message, context ?? {});
|
|
3920
|
-
this.reporter.add(
|
|
3933
|
+
this.reporter.add({
|
|
3934
|
+
rule: this,
|
|
3935
|
+
message: interpolated,
|
|
3936
|
+
severity: this.severity,
|
|
3937
|
+
node,
|
|
3938
|
+
location: where,
|
|
3939
|
+
context
|
|
3940
|
+
});
|
|
3921
3941
|
}
|
|
3922
3942
|
}
|
|
3923
3943
|
findLocation(src) {
|
|
@@ -4489,8 +4509,7 @@ class AriaLabelMisuse extends Rule {
|
|
|
4489
4509
|
class ConfigError extends UserError {
|
|
4490
4510
|
constructor(message, nested) {
|
|
4491
4511
|
super(message, nested);
|
|
4492
|
-
|
|
4493
|
-
this.name = ConfigError.name;
|
|
4512
|
+
this.name = "ConfigError";
|
|
4494
4513
|
}
|
|
4495
4514
|
}
|
|
4496
4515
|
|
|
@@ -4594,7 +4613,7 @@ class AttrCase extends Rule {
|
|
|
4594
4613
|
if (event.originalAttribute) {
|
|
4595
4614
|
return;
|
|
4596
4615
|
}
|
|
4597
|
-
const letters = event.key.
|
|
4616
|
+
const letters = event.key.replaceAll(/[^a-z]+/gi, "");
|
|
4598
4617
|
if (this.style.match(letters)) {
|
|
4599
4618
|
return;
|
|
4600
4619
|
}
|
|
@@ -4667,6 +4686,7 @@ class InvalidTokenError extends Error {
|
|
|
4667
4686
|
location;
|
|
4668
4687
|
constructor(location, message) {
|
|
4669
4688
|
super(message);
|
|
4689
|
+
this.name = "InvalidTokenError";
|
|
4670
4690
|
this.location = location;
|
|
4671
4691
|
}
|
|
4672
4692
|
}
|
|
@@ -4776,16 +4796,26 @@ class Lexer {
|
|
|
4776
4796
|
*/
|
|
4777
4797
|
enter(context, state, data) {
|
|
4778
4798
|
if (state === State.TAG && data?.[0].startsWith("<")) {
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4799
|
+
switch (data[0]) {
|
|
4800
|
+
case "<script": {
|
|
4801
|
+
context.contentModel = ContentModel.SCRIPT;
|
|
4802
|
+
break;
|
|
4803
|
+
}
|
|
4804
|
+
case "<style": {
|
|
4805
|
+
context.contentModel = ContentModel.STYLE;
|
|
4806
|
+
break;
|
|
4807
|
+
}
|
|
4808
|
+
case "<textarea": {
|
|
4809
|
+
context.contentModel = ContentModel.TEXTAREA;
|
|
4810
|
+
break;
|
|
4811
|
+
}
|
|
4812
|
+
case "<title": {
|
|
4813
|
+
context.contentModel = ContentModel.TITLE;
|
|
4814
|
+
break;
|
|
4815
|
+
}
|
|
4816
|
+
default: {
|
|
4817
|
+
context.contentModel = ContentModel.TEXT;
|
|
4818
|
+
}
|
|
4789
4819
|
}
|
|
4790
4820
|
}
|
|
4791
4821
|
}
|
|
@@ -5186,10 +5216,10 @@ class AttrSpacing extends Rule {
|
|
|
5186
5216
|
|
|
5187
5217
|
function pick(attr) {
|
|
5188
5218
|
const result = {};
|
|
5189
|
-
if (
|
|
5219
|
+
if (attr.enum !== void 0) {
|
|
5190
5220
|
result.enum = attr.enum;
|
|
5191
5221
|
}
|
|
5192
|
-
if (
|
|
5222
|
+
if (attr.boolean !== void 0) {
|
|
5193
5223
|
result.boolean = attr.boolean;
|
|
5194
5224
|
}
|
|
5195
5225
|
return result;
|
|
@@ -5916,7 +5946,7 @@ class Deprecated extends Rule {
|
|
|
5916
5946
|
text.push(context.documentation);
|
|
5917
5947
|
}
|
|
5918
5948
|
const doc = {
|
|
5919
|
-
description: text.map((cur) => cur.
|
|
5949
|
+
description: text.map((cur) => cur.replaceAll("$tagname", context.tagName)).join("\n\n"),
|
|
5920
5950
|
url: "https://html-validate.org/rules/deprecated.html"
|
|
5921
5951
|
};
|
|
5922
5952
|
return doc;
|
|
@@ -6235,7 +6265,7 @@ class ElementCase extends Rule {
|
|
|
6235
6265
|
});
|
|
6236
6266
|
}
|
|
6237
6267
|
validateCase(target, targetLocation) {
|
|
6238
|
-
const letters = target.tagName.
|
|
6268
|
+
const letters = target.tagName.replaceAll(/[^a-z]+/gi, "");
|
|
6239
6269
|
if (!this.style.match(letters)) {
|
|
6240
6270
|
const location = sliceLocation(targetLocation, 1);
|
|
6241
6271
|
this.report(target, `Element "${target.tagName}" should be ${this.style.name}`, location);
|
|
@@ -6839,8 +6869,8 @@ function haveName(name) {
|
|
|
6839
6869
|
return typeof name === "string" && name !== "";
|
|
6840
6870
|
}
|
|
6841
6871
|
function allowSharedName(node, shared) {
|
|
6842
|
-
const type = node
|
|
6843
|
-
return
|
|
6872
|
+
const type = getControlType(node);
|
|
6873
|
+
return shared.includes(type);
|
|
6844
6874
|
}
|
|
6845
6875
|
function isInputHidden(element) {
|
|
6846
6876
|
return element.is("input") && element.getAttributeValue("type") === "hidden";
|
|
@@ -6848,6 +6878,13 @@ function isInputHidden(element) {
|
|
|
6848
6878
|
function isInputCheckbox(element) {
|
|
6849
6879
|
return element.is("input") && element.getAttributeValue("type") === "checkbox";
|
|
6850
6880
|
}
|
|
6881
|
+
function getControlType(element) {
|
|
6882
|
+
const type = element.getAttributeValue("type") ?? "";
|
|
6883
|
+
if (element.is("button") && type === "") {
|
|
6884
|
+
return "submit";
|
|
6885
|
+
}
|
|
6886
|
+
return type;
|
|
6887
|
+
}
|
|
6851
6888
|
function isCheckboxWithDefault(control, previous, options) {
|
|
6852
6889
|
const { allowCheckboxDefault } = options;
|
|
6853
6890
|
if (!allowCheckboxDefault) {
|
|
@@ -6985,7 +7022,7 @@ class FormDupName extends Rule {
|
|
|
6985
7022
|
validateSharedName(control, group, attr, name) {
|
|
6986
7023
|
const uniqueElements = this.getUniqueElements(group);
|
|
6987
7024
|
const sharedElements = this.getSharedElements(group);
|
|
6988
|
-
const type = control
|
|
7025
|
+
const type = getControlType(control);
|
|
6989
7026
|
if (uniqueElements.has(name) || sharedElements.has(name) && sharedElements.get(name) !== type) {
|
|
6990
7027
|
const context = {
|
|
6991
7028
|
name,
|
|
@@ -7047,7 +7084,7 @@ function isRelevant$5(event) {
|
|
|
7047
7084
|
function extractLevel(node) {
|
|
7048
7085
|
const match = /^[hH](\d)$/.exec(node.tagName);
|
|
7049
7086
|
if (match) {
|
|
7050
|
-
return parseInt(match[1], 10);
|
|
7087
|
+
return Number.parseInt(match[1], 10);
|
|
7051
7088
|
} else {
|
|
7052
7089
|
return null;
|
|
7053
7090
|
}
|
|
@@ -7060,7 +7097,7 @@ function parseMaxInitial(value) {
|
|
|
7060
7097
|
if (!match) {
|
|
7061
7098
|
return 1;
|
|
7062
7099
|
}
|
|
7063
|
-
return parseInt(match[1], 10);
|
|
7100
|
+
return Number.parseInt(match[1], 10);
|
|
7064
7101
|
}
|
|
7065
7102
|
class HeadingLevel extends Rule {
|
|
7066
7103
|
minInitialRank;
|
|
@@ -7209,10 +7246,10 @@ class HeadingLevel extends Rule {
|
|
|
7209
7246
|
this.stack.pop();
|
|
7210
7247
|
}
|
|
7211
7248
|
getPrevRoot() {
|
|
7212
|
-
return this.stack
|
|
7249
|
+
return this.stack.at(-2);
|
|
7213
7250
|
}
|
|
7214
7251
|
getCurrentRoot() {
|
|
7215
|
-
return this.stack
|
|
7252
|
+
return this.stack.at(-1);
|
|
7216
7253
|
}
|
|
7217
7254
|
isSectioningRoot(node) {
|
|
7218
7255
|
const context = {
|
|
@@ -7809,7 +7846,7 @@ function parseContent(text) {
|
|
|
7809
7846
|
const match = /^(\d+)(?:\s*;\s*url=(.*))?/i.exec(text);
|
|
7810
7847
|
if (match) {
|
|
7811
7848
|
return {
|
|
7812
|
-
delay: parseInt(match[1], 10),
|
|
7849
|
+
delay: Number.parseInt(match[1], 10),
|
|
7813
7850
|
url: match[2]
|
|
7814
7851
|
};
|
|
7815
7852
|
} else {
|
|
@@ -8133,13 +8170,12 @@ class NoDupClass extends Rule {
|
|
|
8133
8170
|
}
|
|
8134
8171
|
const classes = new DOMTokenList(event.value, event.valueLocation);
|
|
8135
8172
|
const unique = /* @__PURE__ */ new Set();
|
|
8136
|
-
classes.
|
|
8137
|
-
if (unique.has(
|
|
8138
|
-
|
|
8139
|
-
this.report(event.target, `Class "${cur}" duplicated`, location);
|
|
8173
|
+
for (const { item, location } of classes.iterator()) {
|
|
8174
|
+
if (unique.has(item)) {
|
|
8175
|
+
this.report(event.target, `Class "${item}" duplicated`, location);
|
|
8140
8176
|
}
|
|
8141
|
-
unique.add(
|
|
8142
|
-
}
|
|
8177
|
+
unique.add(item);
|
|
8178
|
+
}
|
|
8143
8179
|
});
|
|
8144
8180
|
}
|
|
8145
8181
|
}
|
|
@@ -8871,7 +8907,7 @@ class NoUnusedDisable extends Rule {
|
|
|
8871
8907
|
setup() {
|
|
8872
8908
|
}
|
|
8873
8909
|
reportUnused(unused, options, location) {
|
|
8874
|
-
const tokens = new DOMTokenList(options.
|
|
8910
|
+
const tokens = new DOMTokenList(options.replaceAll(",", " "), location);
|
|
8875
8911
|
for (const ruleId of unused) {
|
|
8876
8912
|
const index = tokens.indexOf(ruleId);
|
|
8877
8913
|
const tokenLocation = index >= 0 ? tokens.location(index) : location;
|
|
@@ -9192,19 +9228,19 @@ const supportSri = {
|
|
|
9192
9228
|
link: "href",
|
|
9193
9229
|
script: "src"
|
|
9194
9230
|
};
|
|
9195
|
-
const supportedRel = ["stylesheet", "preload", "modulepreload"];
|
|
9196
|
-
const supportedPreload = ["style", "script"];
|
|
9231
|
+
const supportedRel = /* @__PURE__ */ new Set(["stylesheet", "preload", "modulepreload"]);
|
|
9232
|
+
const supportedPreload = /* @__PURE__ */ new Set(["style", "script"]);
|
|
9197
9233
|
function linkSupportsSri(node) {
|
|
9198
9234
|
const rel = node.getAttribute("rel");
|
|
9199
9235
|
if (typeof rel?.value !== "string") {
|
|
9200
9236
|
return false;
|
|
9201
9237
|
}
|
|
9202
|
-
if (!supportedRel.
|
|
9238
|
+
if (!supportedRel.has(rel.value)) {
|
|
9203
9239
|
return false;
|
|
9204
9240
|
}
|
|
9205
9241
|
if (rel.value === "preload") {
|
|
9206
9242
|
const as = node.getAttribute("as");
|
|
9207
|
-
return typeof as?.value === "string" && supportedPreload.
|
|
9243
|
+
return typeof as?.value === "string" && supportedPreload.has(as.value);
|
|
9208
9244
|
}
|
|
9209
9245
|
return true;
|
|
9210
9246
|
}
|
|
@@ -9321,13 +9357,13 @@ class ScriptElement extends Rule {
|
|
|
9321
9357
|
}
|
|
9322
9358
|
}
|
|
9323
9359
|
|
|
9324
|
-
const javascript = [
|
|
9360
|
+
const javascript = /* @__PURE__ */ new Set([
|
|
9325
9361
|
"",
|
|
9326
9362
|
"application/ecmascript",
|
|
9327
9363
|
"application/javascript",
|
|
9328
9364
|
"text/ecmascript",
|
|
9329
9365
|
"text/javascript"
|
|
9330
|
-
];
|
|
9366
|
+
]);
|
|
9331
9367
|
class ScriptType extends Rule {
|
|
9332
9368
|
documentation() {
|
|
9333
9369
|
return {
|
|
@@ -9358,7 +9394,7 @@ class ScriptType extends Rule {
|
|
|
9358
9394
|
}
|
|
9359
9395
|
isJavascript(mime) {
|
|
9360
9396
|
const type = mime.replace(/;.*/, "");
|
|
9361
|
-
return javascript.
|
|
9397
|
+
return javascript.has(type);
|
|
9362
9398
|
}
|
|
9363
9399
|
}
|
|
9364
9400
|
|
|
@@ -9934,7 +9970,7 @@ class UnknownCharReference extends Rule {
|
|
|
9934
9970
|
}
|
|
9935
9971
|
|
|
9936
9972
|
const expectedOrder = ["section", "hint", "contact", "field1", "field2", "webauthn"];
|
|
9937
|
-
const fieldNames1 = [
|
|
9973
|
+
const fieldNames1 = /* @__PURE__ */ new Set([
|
|
9938
9974
|
"name",
|
|
9939
9975
|
"honorific-prefix",
|
|
9940
9976
|
"given-name",
|
|
@@ -9979,8 +10015,8 @@ const fieldNames1 = [
|
|
|
9979
10015
|
"sex",
|
|
9980
10016
|
"url",
|
|
9981
10017
|
"photo"
|
|
9982
|
-
];
|
|
9983
|
-
const fieldNames2 = [
|
|
10018
|
+
]);
|
|
10019
|
+
const fieldNames2 = /* @__PURE__ */ new Set([
|
|
9984
10020
|
"tel",
|
|
9985
10021
|
"tel-country-code",
|
|
9986
10022
|
"tel-national",
|
|
@@ -9991,7 +10027,7 @@ const fieldNames2 = [
|
|
|
9991
10027
|
"tel-extension",
|
|
9992
10028
|
"email",
|
|
9993
10029
|
"impp"
|
|
9994
|
-
];
|
|
10030
|
+
]);
|
|
9995
10031
|
const fieldNameGroup = {
|
|
9996
10032
|
name: "text",
|
|
9997
10033
|
"honorific-prefix": "text",
|
|
@@ -10056,14 +10092,14 @@ function matchHint(token) {
|
|
|
10056
10092
|
return token === "shipping" || token === "billing";
|
|
10057
10093
|
}
|
|
10058
10094
|
function matchFieldNames1(token) {
|
|
10059
|
-
return fieldNames1.
|
|
10095
|
+
return fieldNames1.has(token);
|
|
10060
10096
|
}
|
|
10061
10097
|
function matchContact(token) {
|
|
10062
10098
|
const haystack = ["home", "work", "mobile", "fax", "pager"];
|
|
10063
10099
|
return haystack.includes(token);
|
|
10064
10100
|
}
|
|
10065
10101
|
function matchFieldNames2(token) {
|
|
10066
|
-
return fieldNames2.
|
|
10102
|
+
return fieldNames2.has(token);
|
|
10067
10103
|
}
|
|
10068
10104
|
function matchWebauthn(token) {
|
|
10069
10105
|
return token === "webauthn";
|
|
@@ -10734,11 +10770,13 @@ class H32 extends Rule {
|
|
|
10734
10770
|
setup() {
|
|
10735
10771
|
const formTags = this.getTagsWithProperty("form");
|
|
10736
10772
|
const formSelector = formTags.join(",");
|
|
10773
|
+
const submitButtonTags = this.getTagsWithProperty("submitButton");
|
|
10774
|
+
const submitButtonSelector = submitButtonTags.join(",");
|
|
10737
10775
|
this.on("dom:ready", (event) => {
|
|
10738
10776
|
const { document } = event;
|
|
10739
10777
|
const forms = document.querySelectorAll(formSelector);
|
|
10740
10778
|
for (const form of forms) {
|
|
10741
|
-
if (hasNestedSubmit(form)) {
|
|
10779
|
+
if (hasNestedSubmit(form, submitButtonSelector)) {
|
|
10742
10780
|
continue;
|
|
10743
10781
|
}
|
|
10744
10782
|
if (hasAssociatedSubmit(document, form)) {
|
|
@@ -10750,15 +10788,15 @@ class H32 extends Rule {
|
|
|
10750
10788
|
}
|
|
10751
10789
|
}
|
|
10752
10790
|
function isSubmit(node) {
|
|
10753
|
-
const
|
|
10754
|
-
return
|
|
10791
|
+
const meta = node.meta;
|
|
10792
|
+
return Boolean(meta?.submitButton);
|
|
10755
10793
|
}
|
|
10756
10794
|
function isAssociated(id, node) {
|
|
10757
10795
|
const form = node.getAttribute("form");
|
|
10758
10796
|
return Boolean(form?.valueMatches(id, true));
|
|
10759
10797
|
}
|
|
10760
|
-
function hasNestedSubmit(form) {
|
|
10761
|
-
const matches = form.querySelectorAll(
|
|
10798
|
+
function hasNestedSubmit(form, submitButtonSelector) {
|
|
10799
|
+
const matches = form.querySelectorAll(submitButtonSelector).filter(isSubmit).filter((node) => !node.hasAttribute("form"));
|
|
10762
10800
|
return matches.length > 0;
|
|
10763
10801
|
}
|
|
10764
10802
|
function hasAssociatedSubmit(document, form) {
|
|
@@ -11307,11 +11345,11 @@ function dumpTree(root) {
|
|
|
11307
11345
|
} else {
|
|
11308
11346
|
lines.push("(root)");
|
|
11309
11347
|
}
|
|
11310
|
-
node.childElements.
|
|
11348
|
+
for (const [index, child] of node.childElements.entries()) {
|
|
11311
11349
|
const s = lastSibling ? " " : "\u2502";
|
|
11312
11350
|
const i = level > 0 ? `${indent}${s} ` : "";
|
|
11313
11351
|
writeNode(child, level + 1, i, index);
|
|
11314
|
-
}
|
|
11352
|
+
}
|
|
11315
11353
|
}
|
|
11316
11354
|
writeNode(root, 0, "", 0);
|
|
11317
11355
|
return lines;
|
|
@@ -12426,7 +12464,7 @@ class EventHandler {
|
|
|
12426
12464
|
}
|
|
12427
12465
|
|
|
12428
12466
|
const name = "html-validate";
|
|
12429
|
-
const version = "10.
|
|
12467
|
+
const version = "10.10.0";
|
|
12430
12468
|
const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
|
|
12431
12469
|
|
|
12432
12470
|
function freeze(src) {
|
|
@@ -12442,7 +12480,13 @@ function isThenableArray(value) {
|
|
|
12442
12480
|
return isThenable(value[0]);
|
|
12443
12481
|
}
|
|
12444
12482
|
class Reporter {
|
|
12483
|
+
/**
|
|
12484
|
+
* @internal
|
|
12485
|
+
*/
|
|
12445
12486
|
result;
|
|
12487
|
+
/**
|
|
12488
|
+
* @internal
|
|
12489
|
+
*/
|
|
12446
12490
|
constructor() {
|
|
12447
12491
|
this.result = {};
|
|
12448
12492
|
}
|
|
@@ -12455,16 +12499,16 @@ class Reporter {
|
|
|
12455
12499
|
}
|
|
12456
12500
|
const valid = reports.every((report) => report.valid);
|
|
12457
12501
|
const merged = {};
|
|
12458
|
-
|
|
12459
|
-
report.results
|
|
12502
|
+
for (const report of reports) {
|
|
12503
|
+
for (const result of report.results) {
|
|
12460
12504
|
const key = result.filePath;
|
|
12461
12505
|
if (key in merged) {
|
|
12462
12506
|
merged[key].messages = [...merged[key].messages, ...result.messages];
|
|
12463
12507
|
} else {
|
|
12464
12508
|
merged[key] = { ...result };
|
|
12465
12509
|
}
|
|
12466
|
-
}
|
|
12467
|
-
}
|
|
12510
|
+
}
|
|
12511
|
+
}
|
|
12468
12512
|
const results = Object.values(merged).map((result) => {
|
|
12469
12513
|
result.errorCount = countErrors(result.messages);
|
|
12470
12514
|
result.warningCount = countWarnings(result.messages);
|
|
@@ -12477,8 +12521,11 @@ class Reporter {
|
|
|
12477
12521
|
warningCount: sumWarnings(results)
|
|
12478
12522
|
};
|
|
12479
12523
|
}
|
|
12480
|
-
|
|
12481
|
-
|
|
12524
|
+
/**
|
|
12525
|
+
* @internal
|
|
12526
|
+
*/
|
|
12527
|
+
add(options) {
|
|
12528
|
+
const { rule, message, severity, node, location, context } = options;
|
|
12482
12529
|
if (!(location.filename in this.result)) {
|
|
12483
12530
|
this.result[location.filename] = [];
|
|
12484
12531
|
}
|
|
@@ -12503,17 +12550,23 @@ class Reporter {
|
|
|
12503
12550
|
}
|
|
12504
12551
|
this.result[location.filename].push(entry);
|
|
12505
12552
|
}
|
|
12553
|
+
/**
|
|
12554
|
+
* @internal
|
|
12555
|
+
*/
|
|
12506
12556
|
addManual(filename, message) {
|
|
12507
12557
|
if (!(filename in this.result)) {
|
|
12508
12558
|
this.result[filename] = [];
|
|
12509
12559
|
}
|
|
12510
12560
|
this.result[filename].push(message);
|
|
12511
12561
|
}
|
|
12562
|
+
/**
|
|
12563
|
+
* @internal
|
|
12564
|
+
*/
|
|
12512
12565
|
save(sources) {
|
|
12513
12566
|
const report = {
|
|
12514
12567
|
valid: this.isValid(),
|
|
12515
12568
|
results: Object.keys(this.result).map((filePath) => {
|
|
12516
|
-
const messages = Array.from(this.result[filePath], freeze).
|
|
12569
|
+
const messages = Array.from(this.result[filePath], freeze).toSorted(messageSort);
|
|
12517
12570
|
const source = (sources ?? []).find((source2) => filePath === source2.filename);
|
|
12518
12571
|
return {
|
|
12519
12572
|
filePath,
|
|
@@ -12530,6 +12583,9 @@ class Reporter {
|
|
|
12530
12583
|
report.warningCount = sumWarnings(report.results);
|
|
12531
12584
|
return report;
|
|
12532
12585
|
}
|
|
12586
|
+
/**
|
|
12587
|
+
* @internal
|
|
12588
|
+
*/
|
|
12533
12589
|
isValid() {
|
|
12534
12590
|
const numErrors = Object.values(this.result).reduce((sum, messages) => {
|
|
12535
12591
|
return sum + countErrors(messages);
|
|
@@ -12592,6 +12648,7 @@ class ParserError extends Error {
|
|
|
12592
12648
|
location;
|
|
12593
12649
|
constructor(location, message) {
|
|
12594
12650
|
super(message);
|
|
12651
|
+
this.name = "ParserError";
|
|
12595
12652
|
this.location = location;
|
|
12596
12653
|
}
|
|
12597
12654
|
}
|
|
@@ -12748,7 +12805,7 @@ class Parser {
|
|
|
12748
12805
|
const tokens = Array.from(
|
|
12749
12806
|
this.consumeUntil(tokenStream, TokenType.TAG_CLOSE, startToken.location)
|
|
12750
12807
|
);
|
|
12751
|
-
const endToken = tokens.
|
|
12808
|
+
const endToken = tokens.at(-1);
|
|
12752
12809
|
const closeOptional = this.closeOptional(startToken);
|
|
12753
12810
|
const parent = closeOptional ? this.dom.getActive().parent : this.dom.getActive();
|
|
12754
12811
|
const node = HtmlElement.fromTokens(
|
|
@@ -12866,7 +12923,7 @@ class Parser {
|
|
|
12866
12923
|
const endTokens = Array.from(
|
|
12867
12924
|
this.consumeUntil(tokenStream, TokenType.TAG_CLOSE, last.location)
|
|
12868
12925
|
);
|
|
12869
|
-
endToken = endTokens.
|
|
12926
|
+
endToken = endTokens.at(-1);
|
|
12870
12927
|
const selfClosed = endToken.data[0] === "/>";
|
|
12871
12928
|
if (tagClosed) {
|
|
12872
12929
|
startToken = last;
|
|
@@ -13148,7 +13205,7 @@ class Parser {
|
|
|
13148
13205
|
this.event.once("*", cb);
|
|
13149
13206
|
}
|
|
13150
13207
|
trigger(event, data) {
|
|
13151
|
-
if (
|
|
13208
|
+
if (data.location === void 0) {
|
|
13152
13209
|
throw new Error("Triggered event must contain location");
|
|
13153
13210
|
}
|
|
13154
13211
|
this.event.trigger(event, data);
|
|
@@ -13276,7 +13333,9 @@ class Engine {
|
|
|
13276
13333
|
}
|
|
13277
13334
|
lines.push({ event, data });
|
|
13278
13335
|
});
|
|
13279
|
-
|
|
13336
|
+
for (const src of source) {
|
|
13337
|
+
parser.parseHtml(src);
|
|
13338
|
+
}
|
|
13280
13339
|
return lines;
|
|
13281
13340
|
}
|
|
13282
13341
|
dumpTokens(source) {
|
|
@@ -13741,7 +13800,7 @@ const entities = {
|
|
|
13741
13800
|
"&": "&"
|
|
13742
13801
|
};
|
|
13743
13802
|
function xmlescape(src) {
|
|
13744
|
-
return src.toString().
|
|
13803
|
+
return src.toString().replaceAll(/[><'"&]/g, (match) => {
|
|
13745
13804
|
return entities[match];
|
|
13746
13805
|
});
|
|
13747
13806
|
}
|
|
@@ -13761,11 +13820,11 @@ function checkstyleFormatter(results) {
|
|
|
13761
13820
|
`;
|
|
13762
13821
|
output += `<checkstyle version="4.3">
|
|
13763
13822
|
`;
|
|
13764
|
-
|
|
13823
|
+
for (const result of results) {
|
|
13765
13824
|
const messages = result.messages;
|
|
13766
13825
|
output += ` <file name="${xmlescape(result.filePath)}">
|
|
13767
13826
|
`;
|
|
13768
|
-
|
|
13827
|
+
for (const message of messages) {
|
|
13769
13828
|
const ruleId = xmlescape(`htmlvalidate.rules.${message.ruleId}`);
|
|
13770
13829
|
output += " ";
|
|
13771
13830
|
output += [
|
|
@@ -13776,9 +13835,9 @@ function checkstyleFormatter(results) {
|
|
|
13776
13835
|
`source="${ruleId}" />`
|
|
13777
13836
|
].join(" ");
|
|
13778
13837
|
output += "\n";
|
|
13779
|
-
}
|
|
13838
|
+
}
|
|
13780
13839
|
output += " </file>\n";
|
|
13781
|
-
}
|
|
13840
|
+
}
|
|
13782
13841
|
output += "</checkstyle>\n";
|
|
13783
13842
|
return output;
|
|
13784
13843
|
}
|
|
@@ -13848,11 +13907,11 @@ function codeFrameColumns(rawLines, loc) {
|
|
|
13848
13907
|
if (hasMarker) {
|
|
13849
13908
|
let markerLine = "";
|
|
13850
13909
|
if (Array.isArray(hasMarker)) {
|
|
13851
|
-
const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).
|
|
13910
|
+
const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replaceAll(/[^\t]/g, " ");
|
|
13852
13911
|
const numberOfMarkers = hasMarker[1] || 1;
|
|
13853
13912
|
markerLine = [
|
|
13854
13913
|
"\n ",
|
|
13855
|
-
gutter.
|
|
13914
|
+
gutter.replaceAll(/\d/g, " "),
|
|
13856
13915
|
" ",
|
|
13857
13916
|
markerSpacing,
|
|
13858
13917
|
"^".repeat(numberOfMarkers)
|
|
@@ -13990,10 +14049,10 @@ function stylish(results) {
|
|
|
13990
14049
|
function textFormatter(results) {
|
|
13991
14050
|
let output = "";
|
|
13992
14051
|
let total = 0;
|
|
13993
|
-
|
|
14052
|
+
for (const result of results) {
|
|
13994
14053
|
const messages = result.messages;
|
|
13995
14054
|
if (messages.length === 0) {
|
|
13996
|
-
|
|
14055
|
+
continue;
|
|
13997
14056
|
}
|
|
13998
14057
|
total += messages.length;
|
|
13999
14058
|
output += messages.map((message) => {
|
|
@@ -14009,7 +14068,7 @@ function textFormatter(results) {
|
|
|
14009
14068
|
return `${location}: ${messageType} [${message.ruleId}] ${message.message}
|
|
14010
14069
|
`;
|
|
14011
14070
|
}).join("");
|
|
14012
|
-
}
|
|
14071
|
+
}
|
|
14013
14072
|
return total > 0 ? output : "";
|
|
14014
14073
|
}
|
|
14015
14074
|
const formatter = textFormatter;
|
|
@@ -14841,7 +14900,7 @@ var ignoreExports = /*@__PURE__*/ requireIgnore();
|
|
|
14841
14900
|
var ignore = /*@__PURE__*/getDefaultExportFromCjs(ignoreExports);
|
|
14842
14901
|
|
|
14843
14902
|
const engines = {
|
|
14844
|
-
node: "^20.19.0 || >= 22.
|
|
14903
|
+
node: "^20.19.0 || >= 22.16.0"
|
|
14845
14904
|
};
|
|
14846
14905
|
|
|
14847
14906
|
var workerPath = "./jest-worker.js";
|