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.
Files changed (57) hide show
  1. package/dist/cjs/cli.js +11 -14
  2. package/dist/cjs/cli.js.map +1 -1
  3. package/dist/cjs/core-browser.js +4 -4
  4. package/dist/cjs/core-browser.js.map +1 -1
  5. package/dist/cjs/core-nodejs.js +17 -25
  6. package/dist/cjs/core-nodejs.js.map +1 -1
  7. package/dist/cjs/core.js +424 -435
  8. package/dist/cjs/core.js.map +1 -1
  9. package/dist/cjs/elements.js +11 -22
  10. package/dist/cjs/elements.js.map +1 -1
  11. package/dist/cjs/html-validate.js +1 -1
  12. package/dist/cjs/html-validate.js.map +1 -1
  13. package/dist/cjs/jest-matchers.js +49 -55
  14. package/dist/cjs/jest-matchers.js.map +1 -1
  15. package/dist/cjs/jest-utils.js +1 -2
  16. package/dist/cjs/jest-utils.js.map +1 -1
  17. package/dist/cjs/jest-worker.js.map +1 -1
  18. package/dist/cjs/test-utils.js +1 -2
  19. package/dist/cjs/test-utils.js.map +2 -2
  20. package/dist/cjs/tsdoc-metadata.json +1 -1
  21. package/dist/cjs/utils/parse-image-candidate-string.js +2 -2
  22. package/dist/cjs/utils/parse-image-candidate-string.js.map +1 -1
  23. package/dist/cjs/vitest-matchers.js +46 -50
  24. package/dist/cjs/vitest-matchers.js.map +1 -1
  25. package/dist/cjs/vitest-utils.js +1 -2
  26. package/dist/cjs/vitest-utils.js.map +1 -1
  27. package/dist/cjs/vitest-worker.js.map +1 -1
  28. package/dist/esm/cli.js +11 -14
  29. package/dist/esm/cli.js.map +1 -1
  30. package/dist/esm/core-browser.js +4 -4
  31. package/dist/esm/core-browser.js.map +1 -1
  32. package/dist/esm/core-nodejs.js +17 -25
  33. package/dist/esm/core-nodejs.js.map +1 -1
  34. package/dist/esm/core.js +424 -435
  35. package/dist/esm/core.js.map +1 -1
  36. package/dist/esm/elements.js +11 -22
  37. package/dist/esm/elements.js.map +1 -1
  38. package/dist/esm/html-validate.js +1 -1
  39. package/dist/esm/html-validate.js.map +1 -1
  40. package/dist/esm/jest-matchers.js +49 -55
  41. package/dist/esm/jest-matchers.js.map +1 -1
  42. package/dist/esm/jest-utils.js +1 -2
  43. package/dist/esm/jest-utils.js.map +1 -1
  44. package/dist/esm/jest-worker.js.map +1 -1
  45. package/dist/esm/test-utils.js +1 -2
  46. package/dist/esm/test-utils.js.map +2 -2
  47. package/dist/esm/utils/parse-image-candidate-string.js +2 -2
  48. package/dist/esm/utils/parse-image-candidate-string.js.map +1 -1
  49. package/dist/esm/vitest-matchers.js +46 -50
  50. package/dist/esm/vitest-matchers.js.map +1 -1
  51. package/dist/esm/vitest-utils.js +1 -2
  52. package/dist/esm/vitest-utils.js.map +1 -1
  53. package/dist/esm/vitest-worker.js.map +1 -1
  54. package/dist/tsdoc-metadata.json +1 -1
  55. package/dist/types/browser.d.ts +23 -11
  56. package/dist/types/index.d.ts +25 -13
  57. 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\uFEFF\p{Zs}]$/u;
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-Za-z]$/.test(ch);
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.structuredClone) {
1301
- return globalThis.structuredClone(value);
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 = /^\/(.*(?=\/))\/(i?)$/.exec(value);
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. vuejs `:id` generating the `id` attribute) this
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
- let counter = 0;
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 = Number.parseInt(args.trim(), 10);
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 = /^(.+?)(?:([$*^|~]?=)"([^"]+?)")?$/.exec(attr);
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 = /^([+>~-]?)((?:\*|[^#.:[]+)?)([^]*)$/.exec(pattern);
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[0]) {
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 ComplexSelector.findAdjacentSibling(root);
2431
+ return this.findAdjacentSibling(root);
2439
2432
  case Combinator.GENERAL_SIBLING:
2440
- return ComplexSelector.findGeneralSibling(root);
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(/([\t\n\r]|[^\w-])/gi, (_, ch) => {
2479
- if (codepoints[ch]) {
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 = Number.parseInt(tabindex.value, 10);
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
- } else if (tagName === "style") {
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 key in this.attr;
2921
+ return Object.hasOwn(this.attr, key);
2931
2922
  }
2932
2923
  getAttribute(key, all = false) {
2933
2924
  key = key.toLowerCase();
2934
- if (key in this.attr) {
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.values());
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 Validator.validatePermittedRule(node, rule);
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] && !Validator.validatePermittedCategory(node, rules[i], true)) {
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.find(
3307
- (cur) => Validator.validatePermittedCategory(node, cur, true)
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) => Validator.validatePermittedCategory(child, tagName, false)
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
- } else if (entry instanceof RegExp) {
3379
+ }
3380
+ if (entry instanceof RegExp) {
3394
3381
  return entry.test(value);
3395
- } else if (entry.pattern instanceof RegExp) {
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 Validator.validatePermittedCategory(node, rule, !isExclude);
3405
- } else if (Array.isArray(rule)) {
3391
+ return this.validatePermittedCategory(node, rule, !isExclude);
3392
+ }
3393
+ if (Array.isArray(rule)) {
3406
3394
  return rule.every((inner) => {
3407
- return Validator.validatePermittedRule(node, inner, isExclude);
3395
+ return this.validatePermittedRule(node, inner, isExclude);
3408
3396
  });
3409
- } else {
3410
- validateKeys(rule);
3411
- if (rule.exclude) {
3412
- if (Array.isArray(rule.exclude)) {
3413
- return !rule.exclude.some((inner) => {
3414
- return Validator.validatePermittedRule(node, inner, true);
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] = /^(@?.*?)([*?]?)$/.exec(category);
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 (!allowedKeys.has(key)) {
3472
- const str = JSON.stringify(rule);
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
- } else if (ignoreHiddenRoot) {
3732
+ }
3733
+ if (ignoreHiddenRoot) {
3749
3734
  return IGNORE_HIDDEN_ROOT_HTML_CACHE_KEY;
3750
- } else if (accessible) {
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
- let text = [];
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 = text.concat(findTextNodes(child, options));
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(/{{\s*([^\s{}]+)\s*}}/g, (match, key) => {
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 = new Ajv__default.default({ strict: true, strictTuples: true, strictTypes: true });
3864
- ajv$1.addMetaSchema(ajvSchemaDraft);
3865
- ajv$1.addKeyword(ajvRegexpKeyword);
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() && filter(data)) {
4096
- this.event = data;
4097
- const { tracker } = this;
4098
- if (tracker) {
4099
- const start = performance.now();
4100
- callback(data);
4101
- const end = performance.now();
4102
- tracker.trackRule(this.name, end - start);
4103
- } else {
4104
- callback(data);
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 url with additional details or `null` if no
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 && !list.include.some((it) => it.test(value))) {
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]+:)?\/\//g.test(value)) {
4287
+ if (/^(?:[a-z]+:)?\/\//.test(value)) {
4300
4288
  return "external" /* EXTERNAL */;
4301
4289
  }
4302
- switch (value[0]) {
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
- } else if (allowAbsolute === false) {
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
- } else if (allowExternal === false) {
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
- } else if (allowRelative === false) {
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
- } else if (!matchList(target, allowRelative)) {
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
- } else if (!allowBase) {
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] === "\n") {
4838
- newlines++;
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 = /^[^]*?(?=(?:[\t ]*(?:\r\n|\r|\n)|<[^ ]|$))/;
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 = /^[^]*?(?=<\/script)/;
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 = /^[^]*?(?=<\/style)/;
4906
+ const MATCH_STYLE_DATA = /^[\s\S]*?(?=<\/style)/;
4914
4907
  const MATCH_STYLE_END = /^<(\/)(style)/;
4915
- const MATCH_TEXTAREA_DATA = /^[^]*?(?=<\/textarea)/;
4908
+ const MATCH_TEXTAREA_DATA = /^[\s\S]*?(?=<\/textarea)/;
4916
4909
  const MATCH_TEXTAREA_END = /^<(\/)(textarea)/;
4917
- const MATCH_TITLE_DATA = /^[^]*?(?=<\/title)/;
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 = /(\s+)/;
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
- } else if (value2 instanceof RegExp) {
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 BasePatternRule.schema();
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-Za-z-]+$/.test(value);
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
- } else if (node.is("svg")) {
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 = /^[Hh](\d)$/.exec(node.tagName);
7301
+ const match = /^H(\d)$/i.exec(node.tagName);
7321
7302
  if (match) {
7322
- return Number.parseInt(match[1], 10);
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 Number.parseInt(match[1], 10);
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 BasePatternRule.schema();
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
- } else if (node.is("svg")) {
7810
+ }
7811
+ if (node.is("svg")) {
7832
7812
  return node.textContent.trim() !== "";
7833
- } else {
7834
- for (const img of node.querySelectorAll("img, svg")) {
7835
- const hasName = hasAccessibleNameImpl(img, context);
7836
- if (hasName) {
7837
- return true;
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 (!labels.some((label) => hasAccessibleName(root, label))) {
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: Number.parseInt(match[1], 10),
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 BasePatternRule.schema();
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 in attr) {
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
- const context = { key: attr.key, value: id };
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-Za-z]+;))/g;
8852
- const unquotedAttrRegexp = /(["'<=>`]|&(?![\d#A-Za-z]+;))/g;
8853
- const matchTemplate = /^(<%.*?%>|<\?.*?\?>|<\$.*?\$>)$/s;
8829
+ const textRegexp = /(<|&(?![\d#A-Z]+;))/gi;
8830
+ const unquotedAttrRegexp = /(["'<=>`]|&(?![\d#A-Z]+;))/gi;
8831
+ const matchTemplate = /^(?:<%.*?%>|<\?.*?\?>|<\$.*?\$>)$/s;
8854
8832
  const replacementTable = {
8855
8833
  '"': "&quot;",
8856
8834
  "&": "&amp;",
@@ -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
- if (attr in meta.attributes) {
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 = new RegExp("^(\\w+://|//)");
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 in result) {
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]+)(;|[^\da-z]|$)/gi;
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") && order.includes("field1")) {
10815
- const a = order.indexOf("field1");
10816
- const b = order.indexOf("contact");
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: 4 /* InvalidCombination */,
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(a),
10821
- second: tokens.item(b)
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(b),
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(/^(.)/, (m) => m.toUpperCase());
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 (/^[^\p{L}]/u.test(value)) {
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 (!cells.every((row) => row.length === numColumns)) {
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 in value;
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.filter(haveConfigResolver)) {
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.filter(haveConfigResolver)) {
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.filter(haveElementsResolver)) {
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.filter(haveElementsResolver)) {
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.filter(havePluginResolver)) {
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.filter(havePluginResolver)) {
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.filter(haveTransformerResolver)) {
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.filter(haveTransformerResolver)) {
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 = new Ajv__default.default({ strict: true, strictTuples: true, strictTypes: true });
12127
- ajv.addMetaSchema(ajvSchemaDraft);
12128
- ajv.addKeyword(ajvFunctionKeyword);
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
- Config.validate(options, filename);
12184
- return Config.create(resolvers, options);
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) => Config.fromObject(resolvers, configData2, filename));
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 = Config.getRulesObject(configData.rules);
12224
- for (const [ruleId, [, ruleOptions]] of normalizedRules.entries()) {
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 [obj, filename] = result2;
12372
- metaTable.loadFromObject(obj, filename);
12373
- const next2 = source.shift();
12374
- if (next2) {
12375
- return loadEntry(next2);
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
- } else {
12379
- const [obj, filename] = result;
12380
- metaTable.loadFromObject(obj, filename);
12381
- const next2 = source.shift();
12382
- if (next2) {
12383
- return loadEntry(next2);
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 = plugin.name || `:unnamedPlugin@${String(index + 1)}`;
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 = plugin2.name || entry;
12489
+ plugin2.name ||= entry;
12491
12490
  plugin2.originalName = entry;
12492
12491
  loaded.push(plugin2);
12493
- const next2 = loading.shift();
12494
- if (next2) {
12495
- return loadPlugin(next2, index + 1);
12492
+ const next3 = loading.shift();
12493
+ if (next3) {
12494
+ return loadPlugin(next3, index + 1);
12496
12495
  }
12497
12496
  });
12498
- } else {
12499
- plugin.name = plugin.name || entry;
12500
- plugin.originalName = entry;
12501
- loaded.push(plugin);
12502
- const next2 = loading.shift();
12503
- if (next2) {
12504
- return loadPlugin(next2, index + 1);
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
- for (const [name, config] of Object.entries(plugin.configs ?? {})) {
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 merged = globalConfig2.merge(this.resolvers, override);
12752
- if (isThenable(merged)) {
12753
- return merged.then((merged2) => {
12754
- return merged2.resolve();
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.3";
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 in merged) {
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 in this.result)) {
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 (!(filename in this.result)) {
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.entries(),
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
- this.ruleData.entries(),
13850
- ([rule, { count, time }]) => ({ rule, count, time })
13851
- ).toSorted((a, b) => b.time - a.time);
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
- let blockerCounter = 1;
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
- for (const [name, rule] of Object.entries(plugin.rules ?? {})) {
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().entries()) {
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