html-validate 10.11.2 → 10.12.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.
Files changed (46) hide show
  1. package/dist/cjs/cli.js +1 -1
  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 +19 -19
  6. package/dist/cjs/core-nodejs.js.map +1 -1
  7. package/dist/cjs/core.js +178 -178
  8. package/dist/cjs/core.js.map +1 -1
  9. package/dist/cjs/html-validate.js.map +1 -1
  10. package/dist/cjs/jest-diff.js.map +1 -1
  11. package/dist/cjs/jest.js +7 -6
  12. package/dist/cjs/jest.js.map +1 -1
  13. package/dist/cjs/matcher-utils.js +36 -0
  14. package/dist/cjs/matcher-utils.js.map +1 -1
  15. package/dist/cjs/matchers-jestonly.js +17 -39
  16. package/dist/cjs/matchers-jestonly.js.map +1 -1
  17. package/dist/cjs/matchers.js +14 -8
  18. package/dist/cjs/matchers.js.map +1 -1
  19. package/dist/cjs/tsdoc-metadata.json +1 -1
  20. package/dist/cjs/vitest.js +3 -3
  21. package/dist/esm/cli.js +1 -1
  22. package/dist/esm/cli.js.map +1 -1
  23. package/dist/esm/core-browser.js +4 -4
  24. package/dist/esm/core-browser.js.map +1 -1
  25. package/dist/esm/core-nodejs.js +19 -19
  26. package/dist/esm/core-nodejs.js.map +1 -1
  27. package/dist/esm/core.js +176 -178
  28. package/dist/esm/core.js.map +1 -1
  29. package/dist/esm/html-validate.js +1 -1
  30. package/dist/esm/html-validate.js.map +1 -1
  31. package/dist/esm/jest-diff.js.map +1 -1
  32. package/dist/esm/jest.js +3 -2
  33. package/dist/esm/jest.js.map +1 -1
  34. package/dist/esm/matcher-utils.js +36 -1
  35. package/dist/esm/matcher-utils.js.map +1 -1
  36. package/dist/esm/matchers-jestonly.js +18 -36
  37. package/dist/esm/matchers-jestonly.js.map +1 -1
  38. package/dist/esm/matchers.js +15 -9
  39. package/dist/esm/matchers.js.map +1 -1
  40. package/dist/esm/vitest.js +3 -3
  41. package/dist/tsdoc-metadata.json +1 -1
  42. package/dist/types/browser.d.ts +2 -2
  43. package/dist/types/index.d.ts +2 -2
  44. package/dist/types/jest.d.ts +34 -2
  45. package/dist/types/vitest.d.ts +1 -1
  46. package/package.json +23 -19
package/dist/cjs/core.js CHANGED
@@ -1164,9 +1164,6 @@ const dynamicKeys = [
1164
1164
  "submitButton"
1165
1165
  ];
1166
1166
  const schemaCache = /* @__PURE__ */ new Map();
1167
- function clone(src) {
1168
- return JSON.parse(JSON.stringify(src));
1169
- }
1170
1167
  function overwriteMerge$1(_a, b) {
1171
1168
  return b;
1172
1169
  }
@@ -1178,7 +1175,7 @@ class MetaTable {
1178
1175
  */
1179
1176
  constructor() {
1180
1177
  this.elements = {};
1181
- this.schema = clone(schema);
1178
+ this.schema = structuredClone(schema);
1182
1179
  }
1183
1180
  /**
1184
1181
  * @internal
@@ -1530,82 +1527,6 @@ function sliceLocation(location, begin, end, wrap) {
1530
1527
  return sliced;
1531
1528
  }
1532
1529
 
1533
- var State = /* @__PURE__ */ ((State2) => {
1534
- State2[State2["INITIAL"] = 1] = "INITIAL";
1535
- State2[State2["DOCTYPE"] = 2] = "DOCTYPE";
1536
- State2[State2["TEXT"] = 3] = "TEXT";
1537
- State2[State2["TAG"] = 4] = "TAG";
1538
- State2[State2["ATTR"] = 5] = "ATTR";
1539
- State2[State2["CDATA"] = 6] = "CDATA";
1540
- State2[State2["SCRIPT"] = 7] = "SCRIPT";
1541
- State2[State2["STYLE"] = 8] = "STYLE";
1542
- State2[State2["TEXTAREA"] = 9] = "TEXTAREA";
1543
- State2[State2["TITLE"] = 10] = "TITLE";
1544
- return State2;
1545
- })(State || {});
1546
-
1547
- var ContentModel = /* @__PURE__ */ ((ContentModel2) => {
1548
- ContentModel2[ContentModel2["TEXT"] = 1] = "TEXT";
1549
- ContentModel2[ContentModel2["SCRIPT"] = 2] = "SCRIPT";
1550
- ContentModel2[ContentModel2["STYLE"] = 3] = "STYLE";
1551
- ContentModel2[ContentModel2["TEXTAREA"] = 4] = "TEXTAREA";
1552
- ContentModel2[ContentModel2["TITLE"] = 5] = "TITLE";
1553
- return ContentModel2;
1554
- })(ContentModel || {});
1555
- class Context {
1556
- contentModel;
1557
- state;
1558
- string;
1559
- filename;
1560
- offset;
1561
- line;
1562
- column;
1563
- constructor(source) {
1564
- this.state = State.INITIAL;
1565
- this.string = source.data;
1566
- this.filename = source.filename;
1567
- this.offset = source.offset;
1568
- this.line = source.line;
1569
- this.column = source.column;
1570
- this.contentModel = 1 /* TEXT */;
1571
- }
1572
- getTruncatedLine(n = 13) {
1573
- return JSON.stringify(this.string.length > n ? `${this.string.slice(0, 10)}...` : this.string);
1574
- }
1575
- consume(n, state) {
1576
- let consumed = this.string.slice(0, n);
1577
- let offset;
1578
- while ((offset = consumed.indexOf("\n")) >= 0) {
1579
- this.line++;
1580
- this.column = 1;
1581
- consumed = consumed.slice(offset + 1);
1582
- }
1583
- this.column += consumed.length;
1584
- this.offset += n;
1585
- this.string = this.string.slice(n);
1586
- this.state = state;
1587
- }
1588
- getLocation(size) {
1589
- return {
1590
- filename: this.filename,
1591
- offset: this.offset,
1592
- line: this.line,
1593
- column: this.column,
1594
- size
1595
- };
1596
- }
1597
- }
1598
-
1599
- function normalizeSource(source) {
1600
- return {
1601
- filename: "",
1602
- offset: 0,
1603
- line: 1,
1604
- column: 1,
1605
- ...source
1606
- };
1607
- }
1608
-
1609
1530
  var NodeType = /* @__PURE__ */ ((NodeType2) => {
1610
1531
  NodeType2[NodeType2["ELEMENT_NODE"] = 1] = "ELEMENT_NODE";
1611
1532
  NodeType2[NodeType2["TEXT_NODE"] = 3] = "TEXT_NODE";
@@ -1890,7 +1811,7 @@ class DOMTokenList extends Array {
1890
1811
  locations;
1891
1812
  constructor(value, location) {
1892
1813
  if (value && typeof value === "string") {
1893
- const normalized = value.replaceAll(/[\t\r\n]/g, " ");
1814
+ const normalized = value.replaceAll(/[\t\n\r]/g, " ");
1894
1815
  const { tokens, locations } = parse(normalized, location);
1895
1816
  super(...tokens);
1896
1817
  this.locations = locations;
@@ -2035,7 +1956,7 @@ class AttributeCondition extends Condition {
2035
1956
  value;
2036
1957
  constructor(attr) {
2037
1958
  super();
2038
- const [, key, op, value] = /^(.+?)(?:([~^$*|]?=)"([^"]+?)")?$/.exec(attr);
1959
+ const [, key, op, value] = /^(.+?)(?:([$*^|~]?=)"([^"]+?)")?$/.exec(attr);
2039
1960
  this.key = key;
2040
1961
  this.op = op;
2041
1962
  this.value = typeof value === "string" ? stripslashes(value) : value;
@@ -2075,10 +1996,10 @@ class PseudoClassCondition extends Condition {
2075
1996
  }
2076
1997
 
2077
1998
  function isDelimiter(ch) {
2078
- return /[.#[:]/.test(ch);
1999
+ return /[#.:[]/.test(ch);
2079
2000
  }
2080
2001
  function isQuotationMark(ch) {
2081
- return /['"]/.test(ch);
2002
+ return /["']/.test(ch);
2082
2003
  }
2083
2004
  function isPseudoElement(ch, buffer) {
2084
2005
  return ch === ":" && buffer === ":";
@@ -2130,7 +2051,7 @@ class Compound {
2130
2051
  selector;
2131
2052
  conditions;
2132
2053
  constructor(pattern) {
2133
- const match = /^([~+\->]?)((?:[*]|[^.#[:]+)?)([^]*)$/.exec(pattern);
2054
+ const match = /^([+>~-]?)((?:\*|[^#.:[]+)?)([^]*)$/.exec(pattern);
2134
2055
  if (!match) {
2135
2056
  throw new Error(`Failed to create selector pattern from "${pattern}"`);
2136
2057
  }
@@ -2277,7 +2198,7 @@ function unescapeCodepoint(value) {
2277
2198
  "\\d ": "\r"
2278
2199
  };
2279
2200
  return value.replaceAll(
2280
- /(\\[\u0039\u0061\u0064] )/g,
2201
+ /(\\[9ad] )/g,
2281
2202
  (_, codepoint) => replacement[codepoint]
2282
2203
  );
2283
2204
  }
@@ -2287,7 +2208,7 @@ function escapeSelectorComponent(text) {
2287
2208
  "\n": "\\a ",
2288
2209
  "\r": "\\d "
2289
2210
  };
2290
- return text.toString().replaceAll(/([\t\n\r]|[^a-z0-9_-])/gi, (_, ch) => {
2211
+ return text.toString().replaceAll(/([\t\n\r]|[^\w-])/gi, (_, ch) => {
2291
2212
  if (codepoints[ch]) {
2292
2213
  return codepoints[ch];
2293
2214
  } else {
@@ -2336,7 +2257,7 @@ class Selector {
2336
2257
  }
2337
2258
  }
2338
2259
  static parse(selector) {
2339
- selector = selector.replaceAll(/([+~>]) /g, "$1");
2260
+ selector = selector.replaceAll(/([+>~]) /g, "$1");
2340
2261
  return Array.from(splitSelectorElements(selector), (element) => {
2341
2262
  return new Compound(unescapeCodepoint(element));
2342
2263
  });
@@ -3138,7 +3059,7 @@ class Validator {
3138
3059
  if (typeof rule !== "string") {
3139
3060
  return false;
3140
3061
  }
3141
- const [, category, quantifier] = /^(@?.*?)([?*]?)$/.exec(rule);
3062
+ const [, category, quantifier] = /^(@?.*?)([*?]?)$/.exec(rule);
3142
3063
  const limit = category && quantifier && parseQuantifier(quantifier);
3143
3064
  if (limit) {
3144
3065
  const siblings = children.filter(
@@ -3306,7 +3227,7 @@ class Validator {
3306
3227
  */
3307
3228
  /* eslint-disable-next-line complexity -- rule does not like switch */
3308
3229
  static validatePermittedCategory(node, category, defaultMatch) {
3309
- const [, rawCategory] = /^(@?.*?)([?*]?)$/.exec(category);
3230
+ const [, rawCategory] = /^(@?.*?)([*?]?)$/.exec(category);
3310
3231
  if (!rawCategory.startsWith("@")) {
3311
3232
  return node.matches(rawCategory);
3312
3233
  }
@@ -3447,7 +3368,7 @@ function isInputDisabledImpl(node) {
3447
3368
 
3448
3369
  const patternCache = /* @__PURE__ */ new Map();
3449
3370
  function compileStringPattern(pattern) {
3450
- const regexp = pattern.replaceAll(/[*]+/g, ".+");
3371
+ const regexp = pattern.replaceAll(/\*+/g, ".+");
3451
3372
  return new RegExp(`^${regexp}$`);
3452
3373
  }
3453
3374
  function compileRegExpPattern(pattern) {
@@ -4634,6 +4555,82 @@ class AttrCase extends Rule {
4634
4555
  }
4635
4556
  }
4636
4557
 
4558
+ var State = /* @__PURE__ */ ((State2) => {
4559
+ State2[State2["INITIAL"] = 1] = "INITIAL";
4560
+ State2[State2["DOCTYPE"] = 2] = "DOCTYPE";
4561
+ State2[State2["TEXT"] = 3] = "TEXT";
4562
+ State2[State2["TAG"] = 4] = "TAG";
4563
+ State2[State2["ATTR"] = 5] = "ATTR";
4564
+ State2[State2["CDATA"] = 6] = "CDATA";
4565
+ State2[State2["SCRIPT"] = 7] = "SCRIPT";
4566
+ State2[State2["STYLE"] = 8] = "STYLE";
4567
+ State2[State2["TEXTAREA"] = 9] = "TEXTAREA";
4568
+ State2[State2["TITLE"] = 10] = "TITLE";
4569
+ return State2;
4570
+ })(State || {});
4571
+
4572
+ var ContentModel = /* @__PURE__ */ ((ContentModel2) => {
4573
+ ContentModel2[ContentModel2["TEXT"] = 1] = "TEXT";
4574
+ ContentModel2[ContentModel2["SCRIPT"] = 2] = "SCRIPT";
4575
+ ContentModel2[ContentModel2["STYLE"] = 3] = "STYLE";
4576
+ ContentModel2[ContentModel2["TEXTAREA"] = 4] = "TEXTAREA";
4577
+ ContentModel2[ContentModel2["TITLE"] = 5] = "TITLE";
4578
+ return ContentModel2;
4579
+ })(ContentModel || {});
4580
+ class Context {
4581
+ contentModel;
4582
+ state;
4583
+ string;
4584
+ filename;
4585
+ offset;
4586
+ line;
4587
+ column;
4588
+ constructor(source) {
4589
+ this.state = State.INITIAL;
4590
+ this.string = source.data;
4591
+ this.filename = source.filename;
4592
+ this.offset = source.offset;
4593
+ this.line = source.line;
4594
+ this.column = source.column;
4595
+ this.contentModel = 1 /* TEXT */;
4596
+ }
4597
+ getTruncatedLine(n = 13) {
4598
+ return JSON.stringify(this.string.length > n ? `${this.string.slice(0, 10)}...` : this.string);
4599
+ }
4600
+ consume(n, state) {
4601
+ let consumed = this.string.slice(0, n);
4602
+ let offset;
4603
+ while ((offset = consumed.indexOf("\n")) >= 0) {
4604
+ this.line++;
4605
+ this.column = 1;
4606
+ consumed = consumed.slice(offset + 1);
4607
+ }
4608
+ this.column += consumed.length;
4609
+ this.offset += n;
4610
+ this.string = this.string.slice(n);
4611
+ this.state = state;
4612
+ }
4613
+ getLocation(size) {
4614
+ return {
4615
+ filename: this.filename,
4616
+ offset: this.offset,
4617
+ line: this.line,
4618
+ column: this.column,
4619
+ size
4620
+ };
4621
+ }
4622
+ }
4623
+
4624
+ function normalizeSource(source) {
4625
+ return {
4626
+ filename: "",
4627
+ offset: 0,
4628
+ line: 1,
4629
+ column: 1,
4630
+ ...source
4631
+ };
4632
+ }
4633
+
4637
4634
  var TokenType = /* @__PURE__ */ ((TokenType2) => {
4638
4635
  TokenType2[TokenType2["UNICODE_BOM"] = 1] = "UNICODE_BOM";
4639
4636
  TokenType2[TokenType2["WHITESPACE"] = 2] = "WHITESPACE";
@@ -4656,20 +4653,20 @@ var TokenType = /* @__PURE__ */ ((TokenType2) => {
4656
4653
  })(TokenType || {});
4657
4654
 
4658
4655
  const MATCH_UNICODE_BOM = /^\uFEFF/;
4659
- const MATCH_WHITESPACE = /^(?:\r\n|\r|\n|[ \t]+(?:\r\n|\r|\n)?)/;
4660
- const MATCH_DOCTYPE_OPEN = /^<!(DOCTYPE)\s/i;
4656
+ const MATCH_WHITESPACE = /^(?:\r\n|\r|\n|[\t ]+(?:\r\n|\r|\n)?)/;
4657
+ const MATCH_DOCTYPE_OPEN = /^<!(doctype)\s/i;
4661
4658
  const MATCH_DOCTYPE_VALUE = /^[^>]+/;
4662
4659
  const MATCH_DOCTYPE_CLOSE = /^>/;
4663
4660
  const MATCH_XML_TAG = /^<\?xml.*?\?>\s+/;
4664
- const MATCH_TAG_OPEN = /^<(\/?)([a-zA-Z0-9\-_:]+)/;
4661
+ const MATCH_TAG_OPEN = /^<(\/?)([\w:\-]+)/;
4665
4662
  const MATCH_TAG_CLOSE = /^\/?>/;
4666
- const MATCH_TEXT = /^[^]*?(?=(?:[ \t]*(?:\r\n|\r|\n)|<[^ ]|$))/;
4663
+ const MATCH_TEXT = /^[^]*?(?=(?:[\t ]*(?:\r\n|\r|\n)|<[^ ]|$))/;
4667
4664
  const MATCH_TEMPLATING = /^(?:<%.*?%>|<\?.*?\?>|<\$.*?\$>)/s;
4668
4665
  const MATCH_TAG_LOOKAHEAD = /^[^]*?(?=<|$)/;
4669
- const MATCH_ATTR_START = /^([^\t\r\n\f \/><"'=]+)/;
4666
+ const MATCH_ATTR_START = /^([^\t\n\f\r "'/<=>]+)/;
4670
4667
  const MATCH_ATTR_SINGLE = /^(\s*=\s*)'([^']*?)(')/;
4671
4668
  const MATCH_ATTR_DOUBLE = /^(\s*=\s*)"([^"]*?)(")/;
4672
- const MATCH_ATTR_UNQUOTED = /^(\s*=\s*)([^\t\r\n\f "'<>][^\t\r\n\f <>]*)/;
4669
+ const MATCH_ATTR_UNQUOTED = /^(\s*=\s*)([^\t\n\f\r "'<>][^\t\n\f\r <>]*)/;
4673
4670
  const MATCH_CDATA_BEGIN = /^<!\[CDATA\[/;
4674
4671
  const MATCH_CDATA_END = /^[^]*?]]>/;
4675
4672
  const MATCH_SCRIPT_DATA = /^[^]*?(?=<\/script)/;
@@ -4680,9 +4677,9 @@ const MATCH_TEXTAREA_DATA = /^[^]*?(?=<\/textarea)/;
4680
4677
  const MATCH_TEXTAREA_END = /^<(\/)(textarea)/;
4681
4678
  const MATCH_TITLE_DATA = /^[^]*?(?=<\/title)/;
4682
4679
  const MATCH_TITLE_END = /^<(\/)(title)/;
4683
- const MATCH_DIRECTIVE = /^(<!--\s*\[?)(html-validate-)([a-z0-9-]+)(\s*)(.*?)(]?\s*-->)/;
4680
+ const MATCH_DIRECTIVE = /^(<!--\s*\[?)(html-validate-)([\da-z-]+)(\s*)(.*?)(]?\s*-->)/;
4684
4681
  const MATCH_COMMENT = /^<!--([^]*?)-->/;
4685
- const MATCH_CONDITIONAL = /^<!\[([^\]]*?)\]>/;
4682
+ const MATCH_CONDITIONAL = /^<!\[([^\]]*?)]>/;
4686
4683
  class InvalidTokenError extends Error {
4687
4684
  location;
4688
4685
  constructor(location, message) {
@@ -5622,12 +5619,12 @@ function parsePattern(pattern) {
5622
5619
  }
5623
5620
  switch (pattern) {
5624
5621
  case "kebabcase":
5625
- return { regexp: /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/, description: pattern };
5622
+ return { regexp: /^[a-z][\da-z]*(?:-[\da-z]+)*$/, description: pattern };
5626
5623
  case "camelcase":
5627
- return { regexp: /^[a-z][a-zA-Z0-9]*$/, description: pattern };
5624
+ return { regexp: /^[a-z][\dA-Za-z]*$/, description: pattern };
5628
5625
  case "snakecase":
5629
5626
  case "underscore":
5630
- return { regexp: /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/, description: pattern };
5627
+ return { regexp: /^[a-z][\da-z]*(?:_[\da-z]+)*$/, description: pattern };
5631
5628
  case "bem": {
5632
5629
  const block = "[a-z][a-z0-9]*(?:-[a-z0-9]+)*";
5633
5630
  const element = "(?:__[a-z0-9]+(?:-[a-z0-9]+)*)?";
@@ -5639,7 +5636,7 @@ function parsePattern(pattern) {
5639
5636
  }
5640
5637
  case "tailwind": {
5641
5638
  return {
5642
- regexp: /^!?(?:[-a-z[]|\d+xl:)[\w\-:./\\[\]()#'&>,!=%]*$/,
5639
+ regexp: /^!?(?:[[a-z-]|\d+xl:)[\w!#%&'(),./:=>[\\\]-]*$/,
5643
5640
  description: "tailwind"
5644
5641
  };
5645
5642
  }
@@ -6625,7 +6622,7 @@ class ElementPermittedParent extends Rule {
6625
6622
  }
6626
6623
 
6627
6624
  function isTagnameOnly(value) {
6628
- return /^[a-zA-Z0-9-]+$/.test(value);
6625
+ return /^[\dA-Za-z-]+$/.test(value);
6629
6626
  }
6630
6627
  function getRuleDescription(context) {
6631
6628
  const escaped = context.ancestor.map((it) => `\`${it}\``);
@@ -6832,14 +6829,14 @@ class EmptyTitle extends Rule {
6832
6829
  }
6833
6830
  switch (classifyNodeText(node)) {
6834
6831
  case TextClassification.DYNAMIC_TEXT:
6835
- case TextClassification.STATIC_TEXT:
6832
+ case TextClassification.STATIC_TEXT: {
6836
6833
  break;
6837
- case TextClassification.EMPTY_TEXT:
6838
- {
6839
- const message = `<${node.tagName}> cannot be empty, must have text content`;
6840
- this.report(node, message, node.location);
6841
- }
6834
+ }
6835
+ case TextClassification.EMPTY_TEXT: {
6836
+ const message = `<${node.tagName}> cannot be empty, must have text content`;
6837
+ this.report(node, message, node.location);
6842
6838
  break;
6839
+ }
6843
6840
  }
6844
6841
  });
6845
6842
  }
@@ -7081,7 +7078,7 @@ function isRelevant$5(event) {
7081
7078
  return Boolean(node.meta?.heading);
7082
7079
  }
7083
7080
  function extractLevel(node) {
7084
- const match = /^[hH](\d)$/.exec(node.tagName);
7081
+ const match = /^[Hh](\d)$/.exec(node.tagName);
7085
7082
  if (match) {
7086
7083
  return Number.parseInt(match[1], 10);
7087
7084
  } else {
@@ -8536,8 +8533,8 @@ class NoMultipleMain extends Rule {
8536
8533
  const defaults$f = {
8537
8534
  relaxed: false
8538
8535
  };
8539
- const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
8540
- const unquotedAttrRegexp = /([<>"'=`]|&(?![a-zA-Z0-9#]+;))/g;
8536
+ const textRegexp = /([<>]|&(?![\d#A-Za-z]+;))/g;
8537
+ const unquotedAttrRegexp = /(["'<=>`]|&(?![\d#A-Za-z]+;))/g;
8541
8538
  const matchTemplate = /^(<%.*?%>|<\?.*?\?>|<\$.*?\$>)$/s;
8542
8539
  const replacementTable = {
8543
8540
  '"': "&quot;",
@@ -8870,7 +8867,7 @@ class NoTrailingWhitespace extends Rule {
8870
8867
  }
8871
8868
  setup() {
8872
8869
  this.on("whitespace", (event) => {
8873
- if (/^[ \t]+\r?\n$/.test(event.text)) {
8870
+ if (/^[\t ]+\r?\n$/.test(event.text)) {
8874
8871
  this.report(null, "Trailing whitespace", event.location);
8875
8872
  }
8876
8873
  });
@@ -9873,7 +9870,7 @@ const defaults$5 = {
9873
9870
  ignoreCase: false,
9874
9871
  requireSemicolon: true
9875
9872
  };
9876
- const regexp$1 = /&(?:[a-z0-9]+|#x?[0-9a-f]+)(;|[^a-z0-9]|$)/gi;
9873
+ const regexp$1 = /&(?:[\da-z]+|#x?[\da-f]+)(;|[^\da-z]|$)/gi;
9877
9874
  const lowercaseEntities = elements.entities.map((it) => it.toLowerCase());
9878
9875
  function isNumerical(entity) {
9879
9876
  return entity.startsWith("&#");
@@ -9957,7 +9954,7 @@ class UnknownCharReference extends Rule {
9957
9954
  }
9958
9955
  }
9959
9956
  findCharacterReferences(node, text, location, { isAttribute }) {
9960
- const delimiter = text.search(/[?#]/);
9957
+ const delimiter = text.search(/[#?]/);
9961
9958
  for (const match of this.getMatches(text)) {
9962
9959
  const allowUnterminated = isAttribute && isAfterQueryOrFragment(delimiter, match);
9963
9960
  this.validateCharacterReference(node, location, match, {
@@ -10780,7 +10777,7 @@ class H30 extends Rule {
10780
10777
  }
10781
10778
  setup() {
10782
10779
  this.on("dom:ready", (event) => {
10783
- const links = event.document.getElementsByTagName("a");
10780
+ const links = event.document.querySelectorAll("a");
10784
10781
  for (const link of links) {
10785
10782
  if (!link.hasAttribute("href")) {
10786
10783
  continue;
@@ -11370,46 +11367,10 @@ var configurationSchema = {
11370
11367
  properties: properties
11371
11368
  };
11372
11369
 
11373
- function dumpTree(root) {
11374
- const lines = [];
11375
- function decoration(node) {
11376
- let output = "";
11377
- if (node.id) {
11378
- output += `#${node.id}`;
11379
- }
11380
- if (node.hasAttribute("class")) {
11381
- output += `.${node.classList.join(".")}`;
11382
- }
11383
- return output;
11384
- }
11385
- function writeNode(node, level, indent, sibling) {
11386
- const numSiblings = node.parent ? node.parent.childElements.length : 0;
11387
- const lastSibling = sibling === numSiblings - 1;
11388
- if (node.parent) {
11389
- const b = lastSibling ? "\u2514" : "\u251C";
11390
- lines.push(`${indent}${b}\u2500\u2500 ${node.tagName}${decoration(node)}`);
11391
- } else {
11392
- lines.push("(root)");
11393
- }
11394
- for (const [index, child] of node.childElements.entries()) {
11395
- const s = lastSibling ? " " : "\u2502";
11396
- const i = level > 0 ? `${indent}${s} ` : "";
11397
- writeNode(child, level + 1, i, index);
11398
- }
11399
- }
11400
- writeNode(root, 0, "", 0);
11401
- return lines;
11402
- }
11403
-
11404
11370
  function isThenable(value) {
11405
11371
  return value && typeof value === "object" && "then" in value && typeof value.then === "function";
11406
11372
  }
11407
11373
 
11408
- const ruleIds = new Set(Object.keys(bundledRules));
11409
- function ruleExists(ruleId) {
11410
- return ruleIds.has(ruleId);
11411
- }
11412
-
11413
11374
  var defaultConfig = {};
11414
11375
 
11415
11376
  const config$5 = {
@@ -12496,6 +12457,7 @@ class EventHandler {
12496
12457
  * @param event - Event name.
12497
12458
  * @param data - Event data.
12498
12459
  */
12460
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any -- technical debt, should be made typesafe */
12499
12461
  trigger(event, data) {
12500
12462
  for (const listener of this.getCallbacks(event)) {
12501
12463
  listener.call(null, event, data);
@@ -12510,7 +12472,7 @@ class EventHandler {
12510
12472
  }
12511
12473
 
12512
12474
  const name = "html-validate";
12513
- const version = "10.11.2";
12475
+ const version = "10.12.0";
12514
12476
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
12515
12477
 
12516
12478
  function freeze(src) {
@@ -12675,7 +12637,7 @@ function definePlugin(plugin) {
12675
12637
  return plugin;
12676
12638
  }
12677
12639
 
12678
- const regexp = /<!(?:--)?\[(.*?)\](?:--)?>/g;
12640
+ const regexp = /<!(?:--)?\[(.*?)](?:--)?>/g;
12679
12641
  function* parseConditionalComment(comment, commentLocation) {
12680
12642
  let match;
12681
12643
  while ((match = regexp.exec(comment)) !== null) {
@@ -13287,6 +13249,42 @@ class Parser {
13287
13249
  }
13288
13250
  }
13289
13251
 
13252
+ const ruleIds = new Set(Object.keys(bundledRules));
13253
+ function ruleExists(ruleId) {
13254
+ return ruleIds.has(ruleId);
13255
+ }
13256
+
13257
+ function dumpTree(root) {
13258
+ const lines = [];
13259
+ function decoration(node) {
13260
+ let output = "";
13261
+ if (node.id) {
13262
+ output += `#${node.id}`;
13263
+ }
13264
+ if (node.hasAttribute("class")) {
13265
+ output += `.${node.classList.join(".")}`;
13266
+ }
13267
+ return output;
13268
+ }
13269
+ function writeNode(node, level, indent, sibling) {
13270
+ const numSiblings = node.parent ? node.parent.childElements.length : 0;
13271
+ const lastSibling = sibling === numSiblings - 1;
13272
+ if (node.parent) {
13273
+ const b = lastSibling ? "\u2514" : "\u251C";
13274
+ lines.push(`${indent}${b}\u2500\u2500 ${node.tagName}${decoration(node)}`);
13275
+ } else {
13276
+ lines.push("(root)");
13277
+ }
13278
+ for (const [index, child] of node.childElements.entries()) {
13279
+ const s = lastSibling ? " " : "\u2502";
13280
+ const i = level > 0 ? `${indent}${s} ` : "";
13281
+ writeNode(child, level + 1, i, index);
13282
+ }
13283
+ }
13284
+ writeNode(root, 0, "", 0);
13285
+ return lines;
13286
+ }
13287
+
13290
13288
  let blockerCounter = 1;
13291
13289
  function createBlocker() {
13292
13290
  const id = blockerCounter++;
@@ -13547,6 +13545,7 @@ class Engine {
13547
13545
  * Initializes all rules from plugins and returns an object with a mapping
13548
13546
  * between rule name and its constructor.
13549
13547
  */
13548
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any -- should explicitly accept anything */
13550
13549
  initRules(config) {
13551
13550
  const availableRules = {};
13552
13551
  for (const plugin of config.getPlugins()) {
@@ -13846,7 +13845,7 @@ const entities = {
13846
13845
  "&": "&amp;"
13847
13846
  };
13848
13847
  function xmlescape(src) {
13849
- return src.toString().replaceAll(/[><'"&]/g, (match) => {
13848
+ return src.toString().replaceAll(/["&'<>]/g, (match) => {
13850
13849
  return entities[match];
13851
13850
  });
13852
13851
  }
@@ -13889,11 +13888,6 @@ function checkstyleFormatter(results) {
13889
13888
  }
13890
13889
  const formatter$2 = checkstyleFormatter;
13891
13890
 
13892
- const defaults = {
13893
- showLink: true,
13894
- showSummary: true,
13895
- showSelector: false
13896
- };
13897
13891
  const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
13898
13892
  function getMarkerLines(loc, source) {
13899
13893
  const startLoc = {
@@ -13969,15 +13963,7 @@ function codeFrameColumns(rawLines, loc) {
13969
13963
  }
13970
13964
  }).join("\n");
13971
13965
  }
13972
- function pluralize(word, count) {
13973
- return count === 1 ? word : `${word}s`;
13974
- }
13975
- function formatFilePath(filePath, line, column) {
13976
- if (line && column) {
13977
- filePath += `:${String(line)}:${String(column)}`;
13978
- }
13979
- return kleur__default.default.green(filePath);
13980
- }
13966
+
13981
13967
  function getStartLocation(message) {
13982
13968
  return {
13983
13969
  line: message.line,
@@ -13997,18 +13983,30 @@ function getEndLocation(message, source) {
13997
13983
  }
13998
13984
  return { line, column };
13999
13985
  }
13986
+
13987
+ const defaults = {
13988
+ showLink: true,
13989
+ showFilePath: true,
13990
+ showSummary: true,
13991
+ showSelector: false
13992
+ };
13993
+ function pluralize(word, count) {
13994
+ return count === 1 ? word : `${word}s`;
13995
+ }
13996
+ function formatFilePath(filePath, line, column) {
13997
+ if (line && column) {
13998
+ filePath += `:${String(line)}:${String(column)}`;
13999
+ }
14000
+ return kleur__default.default.green(filePath);
14001
+ }
14000
14002
  function formatMessage(message, parentResult, options) {
14001
14003
  const type = message.severity === 2 ? kleur__default.default.red("error") : kleur__default.default.yellow("warning");
14002
14004
  const msg = kleur__default.default.bold(message.message.replace(/([^ ])\.$/, "$1"));
14003
14005
  const ruleId = kleur__default.default.dim(`(${message.ruleId})`);
14004
14006
  const filePath = formatFilePath(parentResult.filePath, message.line, message.column);
14005
14007
  const sourceCode = parentResult.source;
14006
- const firstLine = [
14007
- `${type}:`,
14008
- msg,
14009
- ruleId ? ruleId : "",
14010
- sourceCode ? `at ${filePath}:` : `at ${filePath}`
14011
- ].filter(String).join(" ");
14008
+ const filePathPart = options.showFilePath ? `at ${filePath}:` : null;
14009
+ const firstLine = [`${type}:`, msg, ruleId ? ruleId : "", filePathPart].filter(Boolean).join(" ");
14012
14010
  const result = [firstLine];
14013
14011
  if (sourceCode) {
14014
14012
  const output = codeFrameColumns(sourceCode, {
@@ -14946,7 +14944,7 @@ var ignoreExports = /*@__PURE__*/ requireIgnore();
14946
14944
  var ignore = /*@__PURE__*/getDefaultExportFromCjs(ignoreExports);
14947
14945
 
14948
14946
  const engines = {
14949
- node: "^20.19.0 || >= 22.16.0"
14947
+ node: "^20.19.0 || ^22.16.0 || >= 24.0.0"
14950
14948
  };
14951
14949
 
14952
14950
  var workerPath = "./jest-worker.js";
@@ -14983,7 +14981,7 @@ exports.WrappedError = WrappedError;
14983
14981
  exports.ariaNaming = ariaNaming;
14984
14982
  exports.bugs = bugs;
14985
14983
  exports.classifyNodeText = classifyNodeText;
14986
- exports.codeframe = codeframe;
14984
+ exports.codeFrameColumns = codeFrameColumns;
14987
14985
  exports.compatibilityCheckImpl = compatibilityCheckImpl;
14988
14986
  exports.configurationSchema = configurationSchema;
14989
14987
  exports.deepmerge = deepmerge;
@@ -14991,7 +14989,9 @@ exports.defineConfig = defineConfig;
14991
14989
  exports.definePlugin = definePlugin;
14992
14990
  exports.engines = engines;
14993
14991
  exports.ensureError = ensureError;
14992
+ exports.getEndLocation = getEndLocation;
14994
14993
  exports.getFormatter = getFormatter;
14994
+ exports.getStartLocation = getStartLocation;
14995
14995
  exports.ignore = ignore;
14996
14996
  exports.isThenable = isThenable;
14997
14997
  exports.isUserError = isUserError;