html-validate 7.7.1 → 7.9.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 (58) hide show
  1. package/dist/cjs/browser.d.ts +4 -2
  2. package/dist/cjs/browser.js +12 -7
  3. package/dist/cjs/browser.js.map +1 -1
  4. package/dist/cjs/cli.js +2 -0
  5. package/dist/cjs/cli.js.map +1 -1
  6. package/dist/cjs/core.d.ts +33 -67
  7. package/dist/cjs/core.js +410 -2452
  8. package/dist/cjs/core.js.map +1 -1
  9. package/dist/cjs/elements.js +4213 -0
  10. package/dist/cjs/elements.js.map +1 -0
  11. package/dist/cjs/html-validate.js +3 -0
  12. package/dist/cjs/html-validate.js.map +1 -1
  13. package/dist/cjs/index.d.ts +5 -3
  14. package/dist/cjs/index.js +12 -7
  15. package/dist/cjs/index.js.map +1 -1
  16. package/dist/cjs/jest-lib.js +1 -0
  17. package/dist/cjs/jest-lib.js.map +1 -1
  18. package/dist/cjs/jest.d.ts +1 -1
  19. package/dist/cjs/jest.js +3 -0
  20. package/dist/cjs/jest.js.map +1 -1
  21. package/dist/cjs/meta-helper.d.ts +27 -0
  22. package/dist/cjs/meta-helper.js +64 -0
  23. package/dist/cjs/meta-helper.js.map +1 -0
  24. package/dist/cjs/rules-helper.d.ts +45 -0
  25. package/dist/cjs/rules-helper.js +408 -0
  26. package/dist/cjs/rules-helper.js.map +1 -0
  27. package/dist/cjs/test-utils.d.ts +1 -1
  28. package/dist/es/browser.d.ts +4 -2
  29. package/dist/es/browser.js +4 -2
  30. package/dist/es/browser.js.map +1 -1
  31. package/dist/es/cli.js +3 -1
  32. package/dist/es/cli.js.map +1 -1
  33. package/dist/es/core.d.ts +33 -67
  34. package/dist/es/core.js +377 -2422
  35. package/dist/es/core.js.map +1 -1
  36. package/dist/es/elements.js +4210 -0
  37. package/dist/es/elements.js.map +1 -0
  38. package/dist/es/html-validate.js +4 -2
  39. package/dist/es/html-validate.js.map +1 -1
  40. package/dist/es/index.d.ts +5 -3
  41. package/dist/es/index.js +4 -2
  42. package/dist/es/index.js.map +1 -1
  43. package/dist/es/jest-lib.js +2 -1
  44. package/dist/es/jest-lib.js.map +1 -1
  45. package/dist/es/jest.d.ts +1 -1
  46. package/dist/es/jest.js +3 -1
  47. package/dist/es/jest.js.map +1 -1
  48. package/dist/es/meta-helper.d.ts +27 -0
  49. package/dist/es/meta-helper.js +61 -0
  50. package/dist/es/meta-helper.js.map +1 -0
  51. package/dist/es/rules-helper.d.ts +45 -0
  52. package/dist/es/rules-helper.js +398 -0
  53. package/dist/es/rules-helper.js.map +1 -0
  54. package/dist/es/test-utils.d.ts +1 -1
  55. package/elements/html5.js +1 -2119
  56. package/package.json +14 -13
  57. package/elements/README.md +0 -49
  58. package/elements/entities.json +0 -1724
package/dist/cjs/core.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  var fs = require('fs');
4
4
  var betterAjvErrors = require('@sidvind/better-ajv-errors');
5
+ var rulesHelper = require('./rules-helper.js');
5
6
  var Ajv = require('ajv');
6
7
  var deepmerge = require('deepmerge');
7
8
  var espree = require('espree');
@@ -9,6 +10,7 @@ var walk = require('acorn-walk');
9
10
  var path = require('path');
10
11
  var semver = require('semver');
11
12
  var kleur = require('kleur');
13
+ var elements = require('./elements.js');
12
14
  var codeFrame = require('@babel/code-frame');
13
15
  var stylishImpl = require('@html-validate/stylish');
14
16
 
@@ -274,104 +276,6 @@ var ajvSchemaDraft = {
274
276
  }
275
277
  };
276
278
 
277
- function stringify(value) {
278
- if (typeof value === "string") {
279
- return String(value);
280
- }
281
- else {
282
- return JSON.stringify(value);
283
- }
284
- }
285
- /**
286
- * Represents an `Error` created from arbitrary values.
287
- *
288
- * @public
289
- */
290
- class WrappedError extends Error {
291
- constructor(message) {
292
- super(stringify(message));
293
- }
294
- }
295
-
296
- /**
297
- * Ensures the value is an Error.
298
- *
299
- * If the passed value is not an `Error` instance a [[WrappedError]] is
300
- * constructed with the stringified value.
301
- *
302
- * @internal
303
- */
304
- function ensureError(value) {
305
- if (value instanceof Error) {
306
- return value;
307
- }
308
- else {
309
- return new WrappedError(value);
310
- }
311
- }
312
-
313
- class NestedError extends Error {
314
- constructor(message, nested) {
315
- super(message);
316
- Error.captureStackTrace(this, NestedError);
317
- if (nested && nested.stack) {
318
- this.stack += `\nCaused by: ${nested.stack}`;
319
- }
320
- }
321
- }
322
-
323
- /**
324
- * @public
325
- */
326
- class UserError extends NestedError {
327
- }
328
-
329
- function getSummary(schema, obj, errors) {
330
- const output = betterAjvErrors__default.default(schema, obj, errors, {
331
- format: "js",
332
- });
333
- // istanbul ignore next: for safety only
334
- return output.length > 0 ? output[0].error : "unknown validation error";
335
- }
336
- /**
337
- * @public
338
- */
339
- class SchemaValidationError extends UserError {
340
- constructor(filename, message, obj, schema, errors) {
341
- const summary = getSummary(schema, obj, errors);
342
- super(`${message}: ${summary}`);
343
- this.filename = filename;
344
- this.obj = obj;
345
- this.schema = schema;
346
- this.errors = errors;
347
- }
348
- prettyError() {
349
- const json = this.getRawJSON();
350
- return betterAjvErrors__default.default(this.schema, this.obj, this.errors, {
351
- format: "cli",
352
- indent: 2,
353
- json,
354
- });
355
- }
356
- getRawJSON() {
357
- if (this.filename && fs__default.default.existsSync(this.filename)) {
358
- return fs__default.default.readFileSync(this.filename, "utf-8");
359
- }
360
- else {
361
- return null;
362
- }
363
- }
364
- }
365
-
366
- /**
367
- * Helper function to assist IDE with completion and type-checking.
368
- *
369
- * @public
370
- */
371
- function defineMetadata(metatable) {
372
- return metatable;
373
- }
374
-
375
279
  /**
376
280
  * @public
377
281
  */
@@ -1728,273 +1632,94 @@ class DOMTree {
1728
1632
  }
1729
1633
  }
1730
1634
 
1731
- const ARIA_HIDDEN_CACHE = Symbol(isAriaHidden.name);
1732
- const HTML_HIDDEN_CACHE = Symbol(isHTMLHidden.name);
1733
- const ROLE_PRESENTATION_CACHE = Symbol(isPresentation.name);
1734
- /**
1735
- * Tests if this element is present in the accessibility tree.
1736
- *
1737
- * In practice it tests whenever the element or its parents has
1738
- * `role="presentation"` or `aria-hidden="false"`. Dynamic values counts as
1739
- * visible since the element might be in the visibility tree sometimes.
1740
- */
1741
- function inAccessibilityTree(node) {
1742
- return !isAriaHidden(node) && !isPresentation(node);
1743
- }
1744
- function isAriaHiddenImpl(node) {
1745
- const isHidden = (node) => {
1746
- const ariaHidden = node.getAttribute("aria-hidden");
1747
- return Boolean(ariaHidden && ariaHidden.value === "true");
1748
- };
1749
- return {
1750
- byParent: node.parent ? isAriaHidden(node.parent) : false,
1751
- bySelf: isHidden(node),
1752
- };
1753
- }
1754
- function isAriaHidden(node, details) {
1755
- const cached = node.cacheGet(ARIA_HIDDEN_CACHE);
1756
- if (cached) {
1757
- return details ? cached : cached.byParent || cached.bySelf;
1635
+ function stringify(value) {
1636
+ if (typeof value === "string") {
1637
+ return String(value);
1758
1638
  }
1759
- const result = node.cacheSet(ARIA_HIDDEN_CACHE, isAriaHiddenImpl(node));
1760
- return details ? result : result.byParent || result.bySelf;
1761
- }
1762
- function isHTMLHiddenImpl(node) {
1763
- const isHidden = (node) => {
1764
- const hidden = node.getAttribute("hidden");
1765
- return hidden !== null && hidden.isStatic;
1766
- };
1767
- return {
1768
- byParent: node.parent ? isHTMLHidden(node.parent) : false,
1769
- bySelf: isHidden(node),
1770
- };
1771
- }
1772
- function isHTMLHidden(node, details) {
1773
- const cached = node.cacheGet(HTML_HIDDEN_CACHE);
1774
- if (cached) {
1775
- return details ? cached : cached.byParent || cached.bySelf;
1639
+ else {
1640
+ return JSON.stringify(value);
1776
1641
  }
1777
- const result = node.cacheSet(HTML_HIDDEN_CACHE, isHTMLHiddenImpl(node));
1778
- return details ? result : result.byParent || result.bySelf;
1779
1642
  }
1780
1643
  /**
1781
- * Tests if this element or a parent element has role="presentation".
1644
+ * Represents an `Error` created from arbitrary values.
1782
1645
  *
1783
- * Dynamic values yields `false` just as if the attribute wasn't present.
1784
- */
1785
- function isPresentation(node) {
1786
- if (node.cacheExists(ROLE_PRESENTATION_CACHE)) {
1787
- return Boolean(node.cacheGet(ROLE_PRESENTATION_CACHE));
1788
- }
1789
- let cur = node;
1790
- do {
1791
- const role = cur.getAttribute("role");
1792
- /* role="presentation" */
1793
- if (role && role.value === "presentation") {
1794
- return cur.cacheSet(ROLE_PRESENTATION_CACHE, true);
1795
- }
1796
- /* sanity check: break if no parent is present, normally not an issue as the
1797
- * root element should be found first */
1798
- if (!cur.parent) {
1799
- break;
1800
- }
1801
- /* check parents */
1802
- cur = cur.parent;
1803
- } while (!cur.isRootElement());
1804
- return node.cacheSet(ROLE_PRESENTATION_CACHE, false);
1805
- }
1806
-
1807
- const cachePrefix = classifyNodeText.name;
1808
- const HTML_CACHE_KEY = Symbol(`${cachePrefix}|html`);
1809
- const A11Y_CACHE_KEY = Symbol(`${cachePrefix}|a11y`);
1810
- const IGNORE_HIDDEN_ROOT_HTML_CACHE_KEY = Symbol(`${cachePrefix}|html|ignore-hidden-root`);
1811
- const IGNORE_HIDDEN_ROOT_A11Y_CACHE_KEY = Symbol(`${cachePrefix}|a11y|ignore-hidden-root`);
1812
- /**
1813
1646
  * @public
1814
1647
  */
1815
- exports.TextClassification = void 0;
1816
- (function (TextClassification) {
1817
- TextClassification[TextClassification["EMPTY_TEXT"] = 0] = "EMPTY_TEXT";
1818
- TextClassification[TextClassification["DYNAMIC_TEXT"] = 1] = "DYNAMIC_TEXT";
1819
- TextClassification[TextClassification["STATIC_TEXT"] = 2] = "STATIC_TEXT";
1820
- })(exports.TextClassification || (exports.TextClassification = {}));
1821
- function getCachekey(options = {}) {
1822
- const { accessible = false, ignoreHiddenRoot = false } = options;
1823
- if (accessible && ignoreHiddenRoot) {
1824
- return IGNORE_HIDDEN_ROOT_A11Y_CACHE_KEY;
1825
- }
1826
- else if (ignoreHiddenRoot) {
1827
- return IGNORE_HIDDEN_ROOT_HTML_CACHE_KEY;
1828
- }
1829
- else if (accessible) {
1830
- return A11Y_CACHE_KEY;
1831
- }
1832
- else {
1833
- return HTML_CACHE_KEY;
1648
+ class WrappedError extends Error {
1649
+ constructor(message) {
1650
+ super(stringify(message));
1834
1651
  }
1835
1652
  }
1836
- /* While I cannot find a reference about this in the standard the <select>
1837
- * element kinda acts as if there is no text content, most particularly it
1838
- * doesn't receive and accessible name. The `.textContent` property does
1839
- * however include the <option> childrens text. But for the sake of the
1840
- * validator it is probably best if the classification acts as if there is no
1841
- * text as I think that is what is expected of the return values. Might have
1842
- * to revisit this at some point or if someone could clarify what section of
1843
- * the standard deals with this. */
1844
- function isSpecialEmpty(node) {
1845
- return node.is("select") || node.is("textarea");
1846
- }
1653
+
1847
1654
  /**
1848
- * Checks text content of an element.
1849
- *
1850
- * Any text is considered including text from descendant elements. Whitespace is
1851
- * ignored.
1655
+ * Ensures the value is an Error.
1852
1656
  *
1853
- * If any text is dynamic `TextClassification.DYNAMIC_TEXT` is returned.
1657
+ * If the passed value is not an `Error` instance a [[WrappedError]] is
1658
+ * constructed with the stringified value.
1854
1659
  *
1855
- * @public
1660
+ * @internal
1856
1661
  */
1857
- function classifyNodeText(node, options = {}) {
1858
- const { accessible = false, ignoreHiddenRoot = false } = options;
1859
- const cacheKey = getCachekey(options);
1860
- if (node.cacheExists(cacheKey)) {
1861
- return node.cacheGet(cacheKey);
1862
- }
1863
- if (!ignoreHiddenRoot && isHTMLHidden(node)) {
1864
- return node.cacheSet(cacheKey, exports.TextClassification.EMPTY_TEXT);
1865
- }
1866
- if (!ignoreHiddenRoot && accessible && isAriaHidden(node)) {
1867
- return node.cacheSet(cacheKey, exports.TextClassification.EMPTY_TEXT);
1868
- }
1869
- if (isSpecialEmpty(node)) {
1870
- return node.cacheSet(cacheKey, exports.TextClassification.EMPTY_TEXT);
1871
- }
1872
- const text = findTextNodes(node, {
1873
- ...options,
1874
- ignoreHiddenRoot: false,
1875
- });
1876
- /* if any text is dynamic classify as dynamic */
1877
- if (text.some((cur) => cur.isDynamic)) {
1878
- return node.cacheSet(cacheKey, exports.TextClassification.DYNAMIC_TEXT);
1879
- }
1880
- /* if any text has non-whitespace character classify as static */
1881
- if (text.some((cur) => cur.textContent.match(/\S/) !== null)) {
1882
- return node.cacheSet(cacheKey, exports.TextClassification.STATIC_TEXT);
1883
- }
1884
- /* default to empty */
1885
- return node.cacheSet(cacheKey, exports.TextClassification.EMPTY_TEXT);
1886
- }
1887
- function findTextNodes(node, options) {
1888
- const { accessible = false } = options;
1889
- let text = [];
1890
- for (const child of node.childNodes) {
1891
- if (isTextNode(child)) {
1892
- text.push(child);
1893
- }
1894
- else if (isElementNode(child)) {
1895
- if (isHTMLHidden(child, true).bySelf) {
1896
- continue;
1897
- }
1898
- if (accessible && isAriaHidden(child, true).bySelf) {
1899
- continue;
1900
- }
1901
- text = text.concat(findTextNodes(child, options));
1902
- }
1662
+ function ensureError(value) {
1663
+ if (value instanceof Error) {
1664
+ return value;
1903
1665
  }
1904
- return text;
1905
- }
1906
-
1907
- function hasAltText(image) {
1908
- const alt = image.getAttribute("alt");
1909
- /* missing or boolean */
1910
- if (alt === null || alt.value === null) {
1911
- return false;
1666
+ else {
1667
+ return new WrappedError(value);
1912
1668
  }
1913
- return alt.isDynamic || alt.value.toString() !== "";
1914
1669
  }
1915
1670
 
1916
- function hasAriaLabel(node) {
1917
- const label = node.getAttribute("aria-label");
1918
- /* missing or boolean */
1919
- if (label === null || label.value === null) {
1920
- return false;
1671
+ class NestedError extends Error {
1672
+ constructor(message, nested) {
1673
+ super(message);
1674
+ Error.captureStackTrace(this, NestedError);
1675
+ if (nested && nested.stack) {
1676
+ this.stack += `\nCaused by: ${nested.stack}`;
1677
+ }
1921
1678
  }
1922
- return label.isDynamic || label.value.toString() !== "";
1923
1679
  }
1924
1680
 
1925
1681
  /**
1926
- * Joins a list of words into natural language.
1927
- *
1928
- * - `["foo"]` becomes `"foo"`
1929
- * - `["foo", "bar"]` becomes `"foo or bar"`
1930
- * - `["foo", "bar", "baz"]` becomes `"foo, bar or baz"`
1931
- * - and so on...
1932
- *
1933
- * @internal
1934
- * @param values - List of words to join
1935
- * @param conjunction - Conjunction for the last element.
1936
- * @returns String with the words naturally joined with a conjunction.
1682
+ * @public
1937
1683
  */
1938
- function naturalJoin(values, conjunction = "or") {
1939
- switch (values.length) {
1940
- case 0:
1941
- return "";
1942
- case 1:
1943
- return values[0];
1944
- case 2:
1945
- return `${values[0]} ${conjunction} ${values[1]}`;
1946
- default:
1947
- return `${values.slice(0, -1).join(", ")} ${conjunction} ${values.slice(-1)[0]}`;
1948
- }
1684
+ class UserError extends NestedError {
1949
1685
  }
1950
1686
 
1951
- /**
1952
- * @internal
1953
- */
1954
- function allowedIfAttributeIsPresent(...attr) {
1955
- return (node) => {
1956
- if (attr.some((it) => node.hasAttribute(it))) {
1957
- return null;
1958
- }
1959
- const expected = naturalJoin(attr.map((it) => `"${it}"`));
1960
- return `requires ${expected} attribute to be present`;
1961
- };
1962
- }
1963
- /**
1964
- * @internal
1965
- */
1966
- function allowedIfAttributeIsAbsent(...attr) {
1967
- return (node) => {
1968
- const present = attr.filter((it) => node.hasAttribute(it));
1969
- if (present.length === 0) {
1970
- return null;
1971
- }
1972
- const expected = naturalJoin(present.map((it) => `"${it}"`));
1973
- return `cannot be used at the same time as ${expected}`;
1974
- };
1687
+ function getSummary(schema, obj, errors) {
1688
+ const output = betterAjvErrors__default.default(schema, obj, errors, {
1689
+ format: "js",
1690
+ });
1691
+ // istanbul ignore next: for safety only
1692
+ return output.length > 0 ? output[0].error : "unknown validation error";
1975
1693
  }
1976
1694
  /**
1977
- * @internal
1695
+ * @public
1978
1696
  */
1979
- function allowedIfAttributeHasValue(key, expectedValue, { defaultValue } = {}) {
1980
- return (node) => {
1981
- const attr = node.getAttribute(key);
1982
- if (attr === null || attr === void 0 ? void 0 : attr.isDynamic) {
1983
- return null;
1697
+ class SchemaValidationError extends UserError {
1698
+ constructor(filename, message, obj, schema, errors) {
1699
+ const summary = getSummary(schema, obj, errors);
1700
+ super(`${message}: ${summary}`);
1701
+ this.filename = filename;
1702
+ this.obj = obj;
1703
+ this.schema = schema;
1704
+ this.errors = errors;
1705
+ }
1706
+ prettyError() {
1707
+ const json = this.getRawJSON();
1708
+ return betterAjvErrors__default.default(this.schema, this.obj, this.errors, {
1709
+ format: "cli",
1710
+ indent: 2,
1711
+ json,
1712
+ });
1713
+ }
1714
+ getRawJSON() {
1715
+ if (this.filename && fs__default.default.existsSync(this.filename)) {
1716
+ return fs__default.default.readFileSync(this.filename, "utf-8");
1984
1717
  }
1985
- const actualValue = (attr === null || attr === void 0 ? void 0 : attr.value) ? attr.value.toString() : defaultValue;
1986
- if (actualValue && expectedValue.includes(actualValue.toLocaleLowerCase())) {
1718
+ else {
1987
1719
  return null;
1988
1720
  }
1989
- const expected = naturalJoin(expectedValue.map((it) => `"${it}"`));
1990
- return `"${key}" attribute must be ${expected}`;
1991
- };
1721
+ }
1992
1722
  }
1993
- const metadataHelper = {
1994
- allowedIfAttributeIsPresent,
1995
- allowedIfAttributeIsAbsent,
1996
- allowedIfAttributeHasValue,
1997
- };
1998
1723
 
1999
1724
  /**
2000
1725
  * Computes hash for given string.
@@ -2022,9 +1747,7 @@ function cyrb53(str) {
2022
1747
  }
2023
1748
  const computeHash = cyrb53;
2024
1749
 
2025
- const projectRoot = path__default.default.resolve(__dirname, "../../");
2026
- const legacyRequire = require;
2027
- const distFolder = path__default.default.resolve(projectRoot, "dist/cjs");
1750
+ const legacyRequire = require;
2028
1751
 
2029
1752
  /**
2030
1753
  * Similar to `require(..)` but removes the cached copy first.
@@ -3533,16 +3256,6 @@ var TRANSFORMER_API;
3533
3256
  TRANSFORMER_API[TRANSFORMER_API["VERSION"] = 1] = "VERSION";
3534
3257
  })(TRANSFORMER_API || (TRANSFORMER_API = {}));
3535
3258
 
3536
- /* generated file, changes will be overwritten */
3537
- /** @public */
3538
- const name = "html-validate";
3539
- /** @public */
3540
- const version = "7.7.1";
3541
- /** @public */
3542
- const homepage = "https://html-validate.org";
3543
- /** @public */
3544
- const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
3545
-
3546
3259
  /**
3547
3260
  * @public
3548
3261
  */
@@ -3851,22 +3564,8 @@ class Rule {
3851
3564
  return null;
3852
3565
  }
3853
3566
  }
3854
- /**
3855
- * @internal
3856
- */
3857
- function ruleDocumentationUrl(filename) {
3858
- /* during bundling all "@/rule.ts"'s are converted to paths relative to the src
3859
- * folder and with the @/ prefix, by replacing the @ with the dist folder we
3860
- * can resolve the path properly */
3861
- filename = filename.replace("@", distFolder);
3862
- const p = path__default.default.parse(filename);
3863
- const root = path__default.default.join(distFolder, "rules");
3864
- const rel = path__default.default.relative(root, path__default.default.join(p.dir, p.name));
3865
- const normalized = rel.replace(/\\/g, "/");
3866
- return `${homepage}/rules/${normalized}.html`;
3867
- }
3868
3567
 
3869
- const defaults$t = {
3568
+ const defaults$u = {
3870
3569
  allowExternal: true,
3871
3570
  allowRelative: true,
3872
3571
  allowAbsolute: true,
@@ -3910,7 +3609,7 @@ function matchList(value, list) {
3910
3609
  }
3911
3610
  class AllowedLinks extends Rule {
3912
3611
  constructor(options) {
3913
- super({ ...defaults$t, ...options });
3612
+ super({ ...defaults$u, ...options });
3914
3613
  this.allowExternal = parseAllow(this.options.allowExternal);
3915
3614
  this.allowRelative = parseAllow(this.options.allowRelative);
3916
3615
  this.allowAbsolute = parseAllow(this.options.allowAbsolute);
@@ -3945,7 +3644,7 @@ class AllowedLinks extends Rule {
3945
3644
  const message = description[context] || "This link type is not allowed by current configuration";
3946
3645
  return {
3947
3646
  description: message,
3948
- url: ruleDocumentationUrl("@/rules/allowed-links.ts"),
3647
+ url: "https://html-validate.org/rules/allowed-links.html",
3949
3648
  };
3950
3649
  }
3951
3650
  setup() {
@@ -4058,7 +3757,7 @@ var RuleContext$1;
4058
3757
  RuleContext["MISSING_ALT"] = "missing-alt";
4059
3758
  RuleContext["MISSING_HREF"] = "missing-href";
4060
3759
  })(RuleContext$1 || (RuleContext$1 = {}));
4061
- const defaults$s = {
3760
+ const defaults$t = {
4062
3761
  accessible: true,
4063
3762
  };
4064
3763
  function findByTarget(target, siblings) {
@@ -4067,7 +3766,7 @@ function findByTarget(target, siblings) {
4067
3766
  function getAltText(node) {
4068
3767
  return node.getAttributeValue("alt");
4069
3768
  }
4070
- function getDescription(context) {
3769
+ function getDescription$1(context) {
4071
3770
  switch (context) {
4072
3771
  case RuleContext$1.MISSING_ALT:
4073
3772
  return [
@@ -4096,7 +3795,7 @@ function getDescription(context) {
4096
3795
  }
4097
3796
  class AreaAlt extends Rule {
4098
3797
  constructor(options) {
4099
- super({ ...defaults$s, ...options });
3798
+ super({ ...defaults$t, ...options });
4100
3799
  }
4101
3800
  static schema() {
4102
3801
  return {
@@ -4107,8 +3806,8 @@ class AreaAlt extends Rule {
4107
3806
  }
4108
3807
  documentation(context) {
4109
3808
  return {
4110
- description: getDescription(context).join("\n"),
4111
- url: ruleDocumentationUrl("@/rules/area-alt.ts"),
3809
+ description: getDescription$1(context).join("\n"),
3810
+ url: "https://html-validate.org/rules/area-alt.html",
4112
3811
  };
4113
3812
  }
4114
3813
  setup() {
@@ -4160,7 +3859,7 @@ class AriaHiddenBody extends Rule {
4160
3859
  documentation() {
4161
3860
  return {
4162
3861
  description: "`aria-hidden` must not be used on the `<body>` element as it makes the page inaccessible to assistive technology such as screenreaders",
4163
- url: ruleDocumentationUrl("@/rules/aria-hidden-body.ts"),
3862
+ url: "https://html-validate.org/rules/aria-hidden-body.html",
4164
3863
  };
4165
3864
  }
4166
3865
  setup() {
@@ -4213,7 +3912,7 @@ class AriaLabelMisuse extends Rule {
4213
3912
  const lines = valid.map((it) => `- ${it}\n`).join("");
4214
3913
  return {
4215
3914
  description: `\`aria-label\` can only be used on:\n\n${lines}`,
4216
- url: ruleDocumentationUrl("@/rules/aria-label-misuse.ts"),
3915
+ url: "https://html-validate.org/rules/aria-label-misuse.html",
4217
3916
  };
4218
3917
  }
4219
3918
  setup() {
@@ -4260,68 +3959,14 @@ class AriaLabelMisuse extends Rule {
4260
3959
  class ConfigError extends UserError {
4261
3960
  }
4262
3961
 
4263
- /**
4264
- * Represents casing for a name, e.g. lowercase, uppercase, etc.
4265
- */
4266
- class CaseStyle {
4267
- /**
4268
- * @param style - Name of a valid case style.
4269
- */
4270
- constructor(style, ruleId) {
4271
- if (!Array.isArray(style)) {
4272
- style = [style];
4273
- }
4274
- if (style.length === 0) {
4275
- throw new ConfigError(`Missing style for ${ruleId} rule`);
4276
- }
4277
- this.styles = this.parseStyle(style, ruleId);
4278
- }
4279
- /**
4280
- * Test if a text matches this case style.
4281
- */
4282
- match(text) {
4283
- return this.styles.some((style) => text.match(style.pattern));
4284
- }
4285
- get name() {
4286
- const names = this.styles.map((style) => style.name);
4287
- switch (this.styles.length) {
4288
- case 1:
4289
- return names[0];
4290
- case 2:
4291
- return names.join(" or ");
4292
- default: {
4293
- const last = names.slice(-1);
4294
- const rest = names.slice(0, -1);
4295
- return `${rest.join(", ")} or ${last[0]}`;
4296
- }
4297
- }
4298
- }
4299
- parseStyle(style, ruleId) {
4300
- return style.map((cur) => {
4301
- switch (cur.toLowerCase()) {
4302
- case "lowercase":
4303
- return { pattern: /^[a-z]*$/, name: "lowercase" };
4304
- case "uppercase":
4305
- return { pattern: /^[A-Z]*$/, name: "uppercase" };
4306
- case "pascalcase":
4307
- return { pattern: /^[A-Z][A-Za-z]*$/, name: "PascalCase" };
4308
- case "camelcase":
4309
- return { pattern: /^[a-z][A-Za-z]*$/, name: "camelCase" };
4310
- default:
4311
- throw new ConfigError(`Invalid style "${cur}" for ${ruleId} rule`);
4312
- }
4313
- });
4314
- }
4315
- }
4316
-
4317
- const defaults$r = {
3962
+ const defaults$s = {
4318
3963
  style: "lowercase",
4319
3964
  ignoreForeign: true,
4320
3965
  };
4321
3966
  class AttrCase extends Rule {
4322
3967
  constructor(options) {
4323
- super({ ...defaults$r, ...options });
4324
- this.style = new CaseStyle(this.options.style, "attr-case");
3968
+ super({ ...defaults$s, ...options });
3969
+ this.style = new rulesHelper.CaseStyle(this.options.style, "attr-case");
4325
3970
  }
4326
3971
  static schema() {
4327
3972
  const styleEnum = ["lowercase", "uppercase", "pascalcase", "camelcase"];
@@ -4352,7 +3997,7 @@ class AttrCase extends Rule {
4352
3997
  description: Array.isArray(style)
4353
3998
  ? [`Attribute name must be in one of:`, "", ...style.map((it) => `- ${it}`)].join("\n")
4354
3999
  : `Attribute name must be in ${style}.`,
4355
- url: ruleDocumentationUrl("@/rules/attr-case.ts"),
4000
+ url: "https://html-validate.org/rules/attr-case.html",
4356
4001
  };
4357
4002
  }
4358
4003
  setup() {
@@ -4645,7 +4290,7 @@ class AttrDelimiter extends Rule {
4645
4290
  documentation() {
4646
4291
  return {
4647
4292
  description: `Attribute value must not be separated by whitespace.`,
4648
- url: ruleDocumentationUrl("@/rules/attr-delimiter.ts"),
4293
+ url: "https://html-validate.org/rules/attr-delimiter.html",
4649
4294
  };
4650
4295
  }
4651
4296
  setup() {
@@ -4665,7 +4310,7 @@ class AttrDelimiter extends Rule {
4665
4310
  }
4666
4311
 
4667
4312
  const DEFAULT_PATTERN = "[a-z0-9-:]+";
4668
- const defaults$q = {
4313
+ const defaults$r = {
4669
4314
  pattern: DEFAULT_PATTERN,
4670
4315
  ignoreForeign: true,
4671
4316
  };
@@ -4702,7 +4347,7 @@ function generateDescription(name, pattern) {
4702
4347
  }
4703
4348
  class AttrPattern extends Rule {
4704
4349
  constructor(options) {
4705
- super({ ...defaults$q, ...options });
4350
+ super({ ...defaults$r, ...options });
4706
4351
  this.pattern = generateRegexp(this.options.pattern);
4707
4352
  }
4708
4353
  static schema() {
@@ -4725,7 +4370,7 @@ class AttrPattern extends Rule {
4725
4370
  }
4726
4371
  return {
4727
4372
  description,
4728
- url: ruleDocumentationUrl("@/rules/attr-pattern.ts"),
4373
+ url: "https://html-validate.org/rules/attr-pattern.html",
4729
4374
  };
4730
4375
  }
4731
4376
  setup() {
@@ -4763,7 +4408,7 @@ var QuoteStyle;
4763
4408
  QuoteStyle["AUTO_QUOTE"] = "auto";
4764
4409
  QuoteStyle["ANY_QUOTE"] = "any";
4765
4410
  })(QuoteStyle || (QuoteStyle = {}));
4766
- const defaults$p = {
4411
+ const defaults$q = {
4767
4412
  style: "auto",
4768
4413
  unquoted: false,
4769
4414
  };
@@ -4804,7 +4449,7 @@ function describeStyle(style, unquoted) {
4804
4449
  }
4805
4450
  class AttrQuotes extends Rule {
4806
4451
  constructor(options) {
4807
- super({ ...defaults$p, ...options });
4452
+ super({ ...defaults$q, ...options });
4808
4453
  this.style = parseStyle$4(this.options.style);
4809
4454
  }
4810
4455
  static schema() {
@@ -4830,7 +4475,7 @@ class AttrQuotes extends Rule {
4830
4475
  ];
4831
4476
  return {
4832
4477
  description: description.join("\n"),
4833
- url: ruleDocumentationUrl("@/rules/attr-quotes.ts"),
4478
+ url: "https://html-validate.org/rules/attr-quotes.html",
4834
4479
  };
4835
4480
  }
4836
4481
  setup() {
@@ -4898,7 +4543,7 @@ class AttrSpacing extends Rule {
4898
4543
  documentation() {
4899
4544
  return {
4900
4545
  description: `No space between attributes. At least one whitespace character (commonly space) must be used to separate attributes.`,
4901
- url: ruleDocumentationUrl("@/rules/attr-spacing.ts"),
4546
+ url: "https://html-validate.org/rules/attr-spacing.html",
4902
4547
  };
4903
4548
  }
4904
4549
  setup() {
@@ -4926,7 +4571,7 @@ class AttributeAllowedValues extends Rule {
4926
4571
  documentation(context) {
4927
4572
  const docs = {
4928
4573
  description: "Attribute has invalid value.",
4929
- url: ruleDocumentationUrl("@/rules/attribute-allowed-values.ts"),
4574
+ url: "https://html-validate.org/rules/attribute-allowed-values.html",
4930
4575
  };
4931
4576
  if (!context) {
4932
4577
  return docs;
@@ -5000,12 +4645,12 @@ class AttributeAllowedValues extends Rule {
5000
4645
  }
5001
4646
  }
5002
4647
 
5003
- const defaults$o = {
4648
+ const defaults$p = {
5004
4649
  style: "omit",
5005
4650
  };
5006
4651
  class AttributeBooleanStyle extends Rule {
5007
4652
  constructor(options) {
5008
- super({ ...defaults$o, ...options });
4653
+ super({ ...defaults$p, ...options });
5009
4654
  this.hasInvalidStyle = parseStyle$3(this.options.style);
5010
4655
  }
5011
4656
  static schema() {
@@ -5019,7 +4664,7 @@ class AttributeBooleanStyle extends Rule {
5019
4664
  documentation() {
5020
4665
  return {
5021
4666
  description: "Require a specific style when writing boolean attributes.",
5022
- url: ruleDocumentationUrl("@/rules/attribute-boolean-style.ts"),
4667
+ url: "https://html-validate.org/rules/attribute-boolean-style.html",
5023
4668
  };
5024
4669
  }
5025
4670
  setup() {
@@ -5081,12 +4726,12 @@ function reportMessage$1(attr, style) {
5081
4726
  return "";
5082
4727
  }
5083
4728
 
5084
- const defaults$n = {
4729
+ const defaults$o = {
5085
4730
  style: "omit",
5086
4731
  };
5087
4732
  class AttributeEmptyStyle extends Rule {
5088
4733
  constructor(options) {
5089
- super({ ...defaults$n, ...options });
4734
+ super({ ...defaults$o, ...options });
5090
4735
  this.hasInvalidStyle = parseStyle$2(this.options.style);
5091
4736
  }
5092
4737
  static schema() {
@@ -5100,7 +4745,7 @@ class AttributeEmptyStyle extends Rule {
5100
4745
  documentation() {
5101
4746
  return {
5102
4747
  description: "Require a specific style for attributes with empty values.",
5103
- url: ruleDocumentationUrl("@/rules/attribute-empty-style.ts"),
4748
+ url: "https://html-validate.org/rules/attribute-empty-style.html",
5104
4749
  };
5105
4750
  }
5106
4751
  setup() {
@@ -5181,7 +4826,7 @@ class AttributeMisuse extends Rule {
5181
4826
  documentation(context) {
5182
4827
  return {
5183
4828
  description: ruleDescription(context),
5184
- url: ruleDocumentationUrl("@/rules/attribute-misuse.ts"),
4829
+ url: "https://html-validate.org/rules/attribute-misuse.html",
5185
4830
  };
5186
4831
  }
5187
4832
  setup() {
@@ -5242,12 +4887,12 @@ function describePattern(pattern) {
5242
4887
  }
5243
4888
  }
5244
4889
 
5245
- const defaults$m = {
4890
+ const defaults$n = {
5246
4891
  pattern: "kebabcase",
5247
4892
  };
5248
4893
  class ClassPattern extends Rule {
5249
4894
  constructor(options) {
5250
- super({ ...defaults$m, ...options });
4895
+ super({ ...defaults$n, ...options });
5251
4896
  this.pattern = parsePattern(this.options.pattern);
5252
4897
  }
5253
4898
  static schema() {
@@ -5261,7 +4906,7 @@ class ClassPattern extends Rule {
5261
4906
  const pattern = describePattern(this.options.pattern);
5262
4907
  return {
5263
4908
  description: `For consistency all classes are required to match the pattern ${pattern}.`,
5264
- url: ruleDocumentationUrl("@/rules/class-pattern.ts"),
4909
+ url: "https://html-validate.org/rules/class-pattern.html",
5265
4910
  };
5266
4911
  }
5267
4912
  setup() {
@@ -5286,7 +4931,7 @@ class CloseAttr extends Rule {
5286
4931
  documentation() {
5287
4932
  return {
5288
4933
  description: "HTML disallows end tags to have attributes.",
5289
- url: ruleDocumentationUrl("@/rules/close-attr.ts"),
4934
+ url: "https://html-validate.org/rules/close-attr.html",
5290
4935
  };
5291
4936
  }
5292
4937
  setup() {
@@ -5312,7 +4957,7 @@ class CloseOrder extends Rule {
5312
4957
  documentation() {
5313
4958
  return {
5314
4959
  description: "HTML requires elements to be closed in the same order as they were opened.",
5315
- url: ruleDocumentationUrl("@/rules/close-order.ts"),
4960
+ url: "https://html-validate.org/rules/close-order.html",
5316
4961
  };
5317
4962
  }
5318
4963
  setup() {
@@ -5356,13 +5001,13 @@ class CloseOrder extends Rule {
5356
5001
  }
5357
5002
  }
5358
5003
 
5359
- const defaults$l = {
5004
+ const defaults$m = {
5360
5005
  include: null,
5361
5006
  exclude: null,
5362
5007
  };
5363
5008
  class Deprecated extends Rule {
5364
5009
  constructor(options) {
5365
- super({ ...defaults$l, ...options });
5010
+ super({ ...defaults$m, ...options });
5366
5011
  }
5367
5012
  static schema() {
5368
5013
  return {
@@ -5397,7 +5042,7 @@ class Deprecated extends Rule {
5397
5042
  documentation(context) {
5398
5043
  const doc = {
5399
5044
  description: "This element is deprecated and should not be used in new code.",
5400
- url: ruleDocumentationUrl("@/rules/deprecated.ts"),
5045
+ url: "https://html-validate.org/rules/deprecated.html",
5401
5046
  };
5402
5047
  if (context) {
5403
5048
  const text = [];
@@ -5484,7 +5129,7 @@ class DeprecatedRule extends Rule {
5484
5129
  const preamble = context ? `The rule "${context}"` : "This rule";
5485
5130
  return {
5486
5131
  description: `${preamble} is deprecated and should not be used any longer, consult documentation for further information.`,
5487
- url: ruleDocumentationUrl("@/rules/deprecated-rule.ts"),
5132
+ url: "https://html-validate.org/rules/deprecated-rule.html",
5488
5133
  };
5489
5134
  }
5490
5135
  setup() {
@@ -5512,7 +5157,7 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
5512
5157
  "<!DOCTYPE html>",
5513
5158
  "```",
5514
5159
  ].join("\n"),
5515
- url: ruleDocumentationUrl("@/rules/doctype-html.ts"),
5160
+ url: "https://html-validate.org/rules/doctype-html.html",
5516
5161
  };
5517
5162
  }
5518
5163
  setup() {
@@ -5525,12 +5170,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
5525
5170
  }
5526
5171
  };
5527
5172
 
5528
- const defaults$k = {
5173
+ const defaults$l = {
5529
5174
  style: "uppercase",
5530
5175
  };
5531
5176
  class DoctypeStyle extends Rule {
5532
5177
  constructor(options) {
5533
- super({ ...defaults$k, ...options });
5178
+ super({ ...defaults$l, ...options });
5534
5179
  }
5535
5180
  static schema() {
5536
5181
  return {
@@ -5543,7 +5188,7 @@ class DoctypeStyle extends Rule {
5543
5188
  documentation(context) {
5544
5189
  const doc = {
5545
5190
  description: `While DOCTYPE is case-insensitive in the standard the current configuration requires a specific style.`,
5546
- url: ruleDocumentationUrl("@/rules/doctype-style.ts"),
5191
+ url: "https://html-validate.org/rules/doctype-style.html",
5547
5192
  };
5548
5193
  if (context) {
5549
5194
  doc.description = `While DOCTYPE is case-insensitive in the standard the current configuration requires it to be ${context.style}`;
@@ -5562,13 +5207,13 @@ class DoctypeStyle extends Rule {
5562
5207
  }
5563
5208
  }
5564
5209
 
5565
- const defaults$j = {
5210
+ const defaults$k = {
5566
5211
  style: "lowercase",
5567
5212
  };
5568
5213
  class ElementCase extends Rule {
5569
5214
  constructor(options) {
5570
- super({ ...defaults$j, ...options });
5571
- this.style = new CaseStyle(this.options.style, "element-case");
5215
+ super({ ...defaults$k, ...options });
5216
+ this.style = new rulesHelper.CaseStyle(this.options.style, "element-case");
5572
5217
  }
5573
5218
  static schema() {
5574
5219
  const styleEnum = ["lowercase", "uppercase", "pascalcase", "camelcase"];
@@ -5596,7 +5241,7 @@ class ElementCase extends Rule {
5596
5241
  description: Array.isArray(style)
5597
5242
  ? [`Element tagname must be in one of:`, "", ...style.map((it) => `- ${it}`)].join("\n")
5598
5243
  : `Element tagname must be in ${style}.`,
5599
- url: ruleDocumentationUrl("@/rules/element-case.ts"),
5244
+ url: "https://html-validate.org/rules/element-case.html",
5600
5245
  };
5601
5246
  }
5602
5247
  setup() {
@@ -5633,14 +5278,14 @@ class ElementCase extends Rule {
5633
5278
  }
5634
5279
  }
5635
5280
 
5636
- const defaults$i = {
5281
+ const defaults$j = {
5637
5282
  pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
5638
5283
  whitelist: [],
5639
5284
  blacklist: [],
5640
5285
  };
5641
5286
  class ElementName extends Rule {
5642
5287
  constructor(options) {
5643
- super({ ...defaults$i, ...options });
5288
+ super({ ...defaults$j, ...options });
5644
5289
  // eslint-disable-next-line security/detect-non-literal-regexp
5645
5290
  this.pattern = new RegExp(this.options.pattern);
5646
5291
  }
@@ -5666,7 +5311,7 @@ class ElementName extends Rule {
5666
5311
  documentation(context) {
5667
5312
  return {
5668
5313
  description: this.documentationMessages(context).join("\n"),
5669
- url: ruleDocumentationUrl("@/rules/element-name.ts"),
5314
+ url: "https://html-validate.org/rules/element-name.html",
5670
5315
  };
5671
5316
  }
5672
5317
  documentationMessages(context) {
@@ -5681,7 +5326,7 @@ class ElementName extends Rule {
5681
5326
  ...context.blacklist.map((cur) => `- ${cur}`),
5682
5327
  ];
5683
5328
  }
5684
- if (context.pattern !== defaults$i.pattern) {
5329
+ if (context.pattern !== defaults$j.pattern) {
5685
5330
  return [
5686
5331
  `<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
5687
5332
  "",
@@ -5772,7 +5417,7 @@ class ElementPermittedContent extends Rule {
5772
5417
  documentation(context) {
5773
5418
  return {
5774
5419
  description: getRuleDescription$2(context).join("\n"),
5775
- url: ruleDocumentationUrl("@/rules/element-permitted-content.ts"),
5420
+ url: "https://html-validate.org/rules/element-permitted-content.html",
5776
5421
  };
5777
5422
  }
5778
5423
  setup() {
@@ -5865,7 +5510,7 @@ class ElementPermittedOccurrences extends Rule {
5865
5510
  documentation() {
5866
5511
  return {
5867
5512
  description: "Some elements may only be used a fixed amount of times in given context.",
5868
- url: ruleDocumentationUrl("@/rules/element-permitted-occurrences.ts"),
5513
+ url: "https://html-validate.org/rules/element-permitted-occurrences.html",
5869
5514
  };
5870
5515
  }
5871
5516
  setup() {
@@ -5899,7 +5544,7 @@ class ElementPermittedOrder extends Rule {
5899
5544
  documentation() {
5900
5545
  return {
5901
5546
  description: "Some elements has a specific order the children must use.",
5902
- url: ruleDocumentationUrl("@/rules/element-permitted-order.ts"),
5547
+ url: "https://html-validate.org/rules/element-permitted-order.html",
5903
5548
  };
5904
5549
  }
5905
5550
  setup() {
@@ -5960,14 +5605,14 @@ function formatMessage$1(node, parent, rules) {
5960
5605
  if (!isFormattable(rules)) {
5961
5606
  return `${nodeName} element cannot have ${parentName} element as parent`;
5962
5607
  }
5963
- const allowed = naturalJoin(rules.filter(isCategoryOrTag).map(formatCategoryOrTag));
5608
+ const allowed = rulesHelper.naturalJoin(rules.filter(isCategoryOrTag).map(formatCategoryOrTag));
5964
5609
  return `${nodeName} element requires a ${allowed} element as parent`;
5965
5610
  }
5966
5611
  class ElementPermittedParent extends Rule {
5967
5612
  documentation(context) {
5968
5613
  return {
5969
5614
  description: getRuleDescription$1(context).join("\n"),
5970
- url: ruleDocumentationUrl("@/rules/element-permitted-parent.ts"),
5615
+ url: "https://html-validate.org/rules/element-permitted-parent.html",
5971
5616
  };
5972
5617
  }
5973
5618
  setup() {
@@ -6024,13 +5669,13 @@ function getRuleDescription(context) {
6024
5669
  ];
6025
5670
  }
6026
5671
  const escaped = context.ancestor.map((it) => `\`${it}\``);
6027
- return [`The \`${context.child}\` element requires a ${naturalJoin(escaped)} ancestor.`];
5672
+ return [`The \`${context.child}\` element requires a ${rulesHelper.naturalJoin(escaped)} ancestor.`];
6028
5673
  }
6029
5674
  class ElementRequiredAncestor extends Rule {
6030
5675
  documentation(context) {
6031
5676
  return {
6032
5677
  description: getRuleDescription(context).join("\n"),
6033
- url: ruleDocumentationUrl("@/rules/element-required-ancestor.ts"),
5678
+ url: "https://html-validate.org/rules/element-required-ancestor.html",
6034
5679
  };
6035
5680
  }
6036
5681
  setup() {
@@ -6060,7 +5705,7 @@ class ElementRequiredAncestor extends Rule {
6060
5705
  }
6061
5706
  const ancestor = rules.map((it) => (isTagnameOnly(it) ? `<${it}>` : `"${it}"`));
6062
5707
  const child = `<${node.tagName}>`;
6063
- const message = `<${node.tagName}> element requires a ${naturalJoin(ancestor)} ancestor`;
5708
+ const message = `<${node.tagName}> element requires a ${rulesHelper.naturalJoin(ancestor)} ancestor`;
6064
5709
  const context = {
6065
5710
  ancestor,
6066
5711
  child,
@@ -6073,7 +5718,7 @@ class ElementRequiredAttributes extends Rule {
6073
5718
  documentation(context) {
6074
5719
  const docs = {
6075
5720
  description: "Element is missing a required attribute",
6076
- url: ruleDocumentationUrl("@/rules/element-required-attributes.ts"),
5721
+ url: "https://html-validate.org/rules/element-required-attributes.html",
6077
5722
  };
6078
5723
  if (context) {
6079
5724
  docs.description = `The <${context.element}> element is required to have a "${context.attribute}" attribute.`;
@@ -6110,13 +5755,13 @@ class ElementRequiredContent extends Rule {
6110
5755
  const { element, missing } = context;
6111
5756
  return {
6112
5757
  description: `The \`${element}\` element requires a \`${missing}\` to be present as content.`,
6113
- url: ruleDocumentationUrl("@/rules/element-required-content.ts"),
5758
+ url: "https://html-validate.org/rules/element-required-content.html",
6114
5759
  };
6115
5760
  }
6116
5761
  else {
6117
5762
  return {
6118
5763
  description: "Some elements has requirements on content that must be present.",
6119
- url: ruleDocumentationUrl("@/rules/element-required-content.ts"),
5764
+ url: "https://html-validate.org/rules/element-required-content.html",
6120
5765
  };
6121
5766
  }
6122
5767
  }
@@ -6147,9 +5792,9 @@ class ElementRequiredContent extends Rule {
6147
5792
  }
6148
5793
 
6149
5794
  const selector = ["h1", "h2", "h3", "h4", "h5", "h6"].join(",");
6150
- function hasImgAltText$1(node) {
5795
+ function hasImgAltText(node) {
6151
5796
  if (node.is("img")) {
6152
- return hasAltText(node);
5797
+ return rulesHelper.hasAltText(node);
6153
5798
  }
6154
5799
  else if (node.is("svg")) {
6155
5800
  return node.textContent.trim() !== "";
@@ -6162,7 +5807,7 @@ class EmptyHeading extends Rule {
6162
5807
  documentation() {
6163
5808
  return {
6164
5809
  description: `Assistive technology such as screen readers require textual content in headings. Whitespace only is considered empty.`,
6165
- url: ruleDocumentationUrl("@/rules/empty-heading.ts"),
5810
+ url: "https://html-validate.org/rules/empty-heading.html",
6166
5811
  };
6167
5812
  }
6168
5813
  setup() {
@@ -6176,16 +5821,16 @@ class EmptyHeading extends Rule {
6176
5821
  validateHeading(heading) {
6177
5822
  const images = heading.querySelectorAll("img, svg");
6178
5823
  for (const child of images) {
6179
- if (hasImgAltText$1(child)) {
5824
+ if (hasImgAltText(child)) {
6180
5825
  return;
6181
5826
  }
6182
5827
  }
6183
- switch (classifyNodeText(heading)) {
6184
- case exports.TextClassification.DYNAMIC_TEXT:
6185
- case exports.TextClassification.STATIC_TEXT:
5828
+ switch (rulesHelper.classifyNodeText(heading)) {
5829
+ case rulesHelper.TextClassification.DYNAMIC_TEXT:
5830
+ case rulesHelper.TextClassification.STATIC_TEXT:
6186
5831
  /* have some text content, consider ok */
6187
5832
  break;
6188
- case exports.TextClassification.EMPTY_TEXT:
5833
+ case rulesHelper.TextClassification.EMPTY_TEXT:
6189
5834
  /* no content or whitespace only */
6190
5835
  this.report(heading, `<${heading.tagName}> cannot be empty, must have text content`);
6191
5836
  break;
@@ -6204,7 +5849,7 @@ class EmptyTitle extends Rule {
6204
5849
  "",
6205
5850
  "Whitespace is ignored.",
6206
5851
  ].join("\n"),
6207
- url: ruleDocumentationUrl("@/rules/empty-title.ts"),
5852
+ url: "https://html-validate.org/rules/empty-title.html",
6208
5853
  };
6209
5854
  }
6210
5855
  setup() {
@@ -6212,12 +5857,12 @@ class EmptyTitle extends Rule {
6212
5857
  const node = event.previous;
6213
5858
  if (node.tagName !== "title")
6214
5859
  return;
6215
- switch (classifyNodeText(node)) {
6216
- case exports.TextClassification.DYNAMIC_TEXT:
6217
- case exports.TextClassification.STATIC_TEXT:
5860
+ switch (rulesHelper.classifyNodeText(node)) {
5861
+ case rulesHelper.TextClassification.DYNAMIC_TEXT:
5862
+ case rulesHelper.TextClassification.STATIC_TEXT:
6218
5863
  /* have some text content, consider ok */
6219
5864
  break;
6220
- case exports.TextClassification.EMPTY_TEXT:
5865
+ case rulesHelper.TextClassification.EMPTY_TEXT:
6221
5866
  /* no content or whitespace only */
6222
5867
  {
6223
5868
  const message = `<${node.tagName}> cannot be empty, must have text content`;
@@ -6229,7 +5874,7 @@ class EmptyTitle extends Rule {
6229
5874
  }
6230
5875
  }
6231
5876
 
6232
- const defaults$h = {
5877
+ const defaults$i = {
6233
5878
  allowMultipleH1: false,
6234
5879
  minInitialRank: "h1",
6235
5880
  sectioningRoots: ["dialog", '[role="dialog"]'],
@@ -6260,7 +5905,7 @@ function parseMaxInitial(value) {
6260
5905
  }
6261
5906
  class HeadingLevel extends Rule {
6262
5907
  constructor(options) {
6263
- super({ ...defaults$h, ...options });
5908
+ super({ ...defaults$i, ...options });
6264
5909
  this.stack = [];
6265
5910
  this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
6266
5911
  this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
@@ -6298,7 +5943,7 @@ class HeadingLevel extends Rule {
6298
5943
  }
6299
5944
  return {
6300
5945
  description: text.join("\n"),
6301
- url: ruleDocumentationUrl("@/rules/heading-level.ts"),
5946
+ url: "https://html-validate.org/rules/heading-level.html",
6302
5947
  };
6303
5948
  }
6304
5949
  setup() {
@@ -6418,12 +6063,12 @@ class HeadingLevel extends Rule {
6418
6063
  }
6419
6064
  }
6420
6065
 
6421
- const defaults$g = {
6066
+ const defaults$h = {
6422
6067
  pattern: "kebabcase",
6423
6068
  };
6424
6069
  class IdPattern extends Rule {
6425
6070
  constructor(options) {
6426
- super({ ...defaults$g, ...options });
6071
+ super({ ...defaults$h, ...options });
6427
6072
  this.pattern = parsePattern(this.options.pattern);
6428
6073
  }
6429
6074
  static schema() {
@@ -6437,7 +6082,7 @@ class IdPattern extends Rule {
6437
6082
  const pattern = describePattern(this.options.pattern);
6438
6083
  return {
6439
6084
  description: `For consistency all IDs are required to match the pattern ${pattern}.`,
6440
- url: ruleDocumentationUrl("@/rules/id-pattern.ts"),
6085
+ url: "https://html-validate.org/rules/id-pattern.html",
6441
6086
  };
6442
6087
  }
6443
6088
  setup() {
@@ -6569,13 +6214,13 @@ class InputAttributes extends Rule {
6569
6214
  const list = (_b = (_a = restricted.get(attribute)) === null || _a === void 0 ? void 0 : _a.map((it) => `- \`${it}\``)) !== null && _b !== void 0 ? _b : [];
6570
6215
  return {
6571
6216
  description: [summary, details, ...list].join("\n"),
6572
- url: ruleDocumentationUrl("@/rules/input-attributes.ts"),
6217
+ url: "https://html-validate.org/rules/input-attributes.html",
6573
6218
  };
6574
6219
  }
6575
6220
  else {
6576
6221
  return {
6577
6222
  description: `This attribute cannot be used with this input type.`,
6578
- url: ruleDocumentationUrl("@/rules/input-attributes.ts"),
6223
+ url: "https://html-validate.org/rules/input-attributes.html",
6579
6224
  };
6580
6225
  }
6581
6226
  }
@@ -6606,126 +6251,6 @@ class InputAttributes extends Rule {
6606
6251
  }
6607
6252
  }
6608
6253
 
6609
- const HAS_ACCESSIBLE_TEXT_CACHE = Symbol(hasAccessibleName.name);
6610
- function isHidden(node, context) {
6611
- const { reference } = context;
6612
- if (reference && reference.isSameNode(node)) {
6613
- return false;
6614
- }
6615
- else {
6616
- return isHTMLHidden(node) || !inAccessibilityTree(node);
6617
- }
6618
- }
6619
- function hasImgAltText(node, context) {
6620
- if (node.is("img")) {
6621
- return hasAltText(node);
6622
- }
6623
- else if (node.is("svg")) {
6624
- return node.textContent.trim() !== "";
6625
- }
6626
- else {
6627
- for (const img of node.querySelectorAll("img, svg")) {
6628
- const hasName = hasAccessibleNameImpl(img, context);
6629
- if (hasName) {
6630
- return true;
6631
- }
6632
- }
6633
- return false;
6634
- }
6635
- }
6636
- function hasLabel(node) {
6637
- var _a;
6638
- const value = (_a = node.getAttributeValue("aria-label")) !== null && _a !== void 0 ? _a : "";
6639
- return Boolean(value.trim());
6640
- }
6641
- function isLabelledby(node, context) {
6642
- const { document, reference } = context;
6643
- /* if we already have resolved one level of reference we don't resolve another
6644
- * level (as per accname step 2B) */
6645
- if (reference) {
6646
- return false;
6647
- }
6648
- const ariaLabelledby = node.ariaLabelledby;
6649
- /* consider dynamic aria-labelledby as having a name as we cannot resolve it
6650
- * so no way to prove correctness */
6651
- if (ariaLabelledby instanceof DynamicValue) {
6652
- return true;
6653
- }
6654
- /* ignore elements without aria-labelledby */
6655
- if (ariaLabelledby === null) {
6656
- return false;
6657
- }
6658
- return ariaLabelledby.some((id) => {
6659
- const selector = generateIdSelector(id);
6660
- return document.querySelectorAll(selector).some((child) => {
6661
- return hasAccessibleNameImpl(child, {
6662
- document,
6663
- reference: child,
6664
- });
6665
- });
6666
- });
6667
- }
6668
- /**
6669
- * This algorithm is based on ["Accessible Name and Description Computation
6670
- * 1.2"][accname] with some exceptions:
6671
- *
6672
- * It doesn't compute the actual name but only the presence of one, e.g. if a
6673
- * non-empty flat string is present the algorithm terminates with a positive
6674
- * result.
6675
- *
6676
- * It takes some optimization shortcuts such as starting with step F as it
6677
- * would be more common usage and as there is no actual name being computed
6678
- * the order wont matter.
6679
- *
6680
- * [accname]: https://w3c.github.io/accname
6681
- */
6682
- function hasAccessibleNameImpl(current, context) {
6683
- const { reference } = context;
6684
- /* if this element is hidden (see function for exceptions) it does not have an accessible name */
6685
- if (isHidden(current, context)) {
6686
- return false;
6687
- }
6688
- /* special case: when this element is directly referenced by aria-labelledby
6689
- * we ignore `hidden` */
6690
- const ignoreHiddenRoot = Boolean(reference && reference.isSameNode(current));
6691
- const text = classifyNodeText(current, { accessible: true, ignoreHiddenRoot });
6692
- if (text !== exports.TextClassification.EMPTY_TEXT) {
6693
- return true;
6694
- }
6695
- if (hasImgAltText(current, context)) {
6696
- return true;
6697
- }
6698
- if (hasLabel(current)) {
6699
- return true;
6700
- }
6701
- if (isLabelledby(current, context)) {
6702
- return true;
6703
- }
6704
- return false;
6705
- }
6706
- /**
6707
- * Returns `true` if the element has an accessible name.
6708
- *
6709
- * It does not yet consider if the elements role prohibits naming, e.g. a `<p>`
6710
- * element will still show up as having an accessible name.
6711
- *
6712
- * @public
6713
- * @param document - Document element.
6714
- * @param current - The element to get accessible name for
6715
- * @returns `true` if the element has an accessible name.
6716
- */
6717
- function hasAccessibleName(document, current) {
6718
- /* istanbul ignore next: we're not testing cache */
6719
- if (current.cacheExists(HAS_ACCESSIBLE_TEXT_CACHE)) {
6720
- return Boolean(current.cacheGet(HAS_ACCESSIBLE_TEXT_CACHE));
6721
- }
6722
- const result = hasAccessibleNameImpl(current, {
6723
- document,
6724
- reference: null,
6725
- });
6726
- return current.cacheSet(HAS_ACCESSIBLE_TEXT_CACHE, result);
6727
- }
6728
-
6729
6254
  function isIgnored(node) {
6730
6255
  var _a;
6731
6256
  if (node.is("input")) {
@@ -6748,7 +6273,7 @@ class InputMissingLabel extends Rule {
6748
6273
  " - Use a nested `<label>` as parent element.",
6749
6274
  " - Use `aria-label` or `aria-labelledby` attributes.",
6750
6275
  ].join("\n"),
6751
- url: ruleDocumentationUrl("@/rules/input-missing-label.ts"),
6276
+ url: "https://html-validate.org/rules/input-missing-label.html",
6752
6277
  };
6753
6278
  }
6754
6279
  setup() {
@@ -6760,14 +6285,14 @@ class InputMissingLabel extends Rule {
6760
6285
  });
6761
6286
  }
6762
6287
  validateInput(root, elem) {
6763
- if (isHTMLHidden(elem) || isAriaHidden(elem)) {
6288
+ if (rulesHelper.isHTMLHidden(elem) || rulesHelper.isAriaHidden(elem)) {
6764
6289
  return;
6765
6290
  }
6766
6291
  /* hidden, submit, reset or button should not have label */
6767
6292
  if (isIgnored(elem)) {
6768
6293
  return;
6769
6294
  }
6770
- if (hasAccessibleName(root, elem)) {
6295
+ if (rulesHelper.hasAccessibleName(root, elem)) {
6771
6296
  return;
6772
6297
  }
6773
6298
  let label = [];
@@ -6800,13 +6325,13 @@ class InputMissingLabel extends Rule {
6800
6325
  this.report(elem, `<${elem.tagName}> element has <label> but <label> element is hidden`);
6801
6326
  return;
6802
6327
  }
6803
- if (!labels.some((label) => hasAccessibleName(root, label))) {
6328
+ if (!labels.some((label) => rulesHelper.hasAccessibleName(root, label))) {
6804
6329
  this.report(elem, `<${elem.tagName}> element has <label> but <label> has no text`);
6805
6330
  }
6806
6331
  }
6807
6332
  }
6808
6333
  function isVisible(elem) {
6809
- const hidden = isHTMLHidden(elem) || isAriaHidden(elem);
6334
+ const hidden = rulesHelper.isHTMLHidden(elem) || rulesHelper.isAriaHidden(elem);
6810
6335
  return !hidden;
6811
6336
  }
6812
6337
  function findLabelById(root, id) {
@@ -6825,12 +6350,12 @@ function findLabelByParent(el) {
6825
6350
  return [];
6826
6351
  }
6827
6352
 
6828
- const defaults$f = {
6353
+ const defaults$g = {
6829
6354
  maxlength: 70,
6830
6355
  };
6831
6356
  class LongTitle extends Rule {
6832
6357
  constructor(options) {
6833
- super({ ...defaults$f, ...options });
6358
+ super({ ...defaults$g, ...options });
6834
6359
  this.maxlength = this.options.maxlength;
6835
6360
  }
6836
6361
  static schema() {
@@ -6843,7 +6368,7 @@ class LongTitle extends Rule {
6843
6368
  documentation() {
6844
6369
  return {
6845
6370
  description: `Search engines truncates titles with long text, possibly down-ranking the page in the process.`,
6846
- url: ruleDocumentationUrl("@/rules/long-title.ts"),
6371
+ url: "https://html-validate.org/rules/long-title.html",
6847
6372
  };
6848
6373
  }
6849
6374
  setup() {
@@ -6863,7 +6388,7 @@ class MetaRefresh extends Rule {
6863
6388
  documentation() {
6864
6389
  return {
6865
6390
  description: `Meta refresh directive must use the \`0;url=...\` format. Non-zero values for time interval is disallowed as people with assistive technology might be unable to read and understand the page content before automatically reloading. For the same reason skipping the url is disallowed as it would put the browser in an infinite loop reloading the same page over and over again.`,
6866
- url: ruleDocumentationUrl("@/rules/meta-refresh.ts"),
6391
+ url: "https://html-validate.org/rules/meta-refresh.html",
6867
6392
  };
6868
6393
  }
6869
6394
  setup() {
@@ -6913,11 +6438,54 @@ function parseContent(text) {
6913
6438
  }
6914
6439
  }
6915
6440
 
6441
+ function getName(attr) {
6442
+ const name = attr.value;
6443
+ if (!name || name instanceof DynamicValue) {
6444
+ return null;
6445
+ }
6446
+ return name;
6447
+ }
6448
+ class MapDupName extends Rule {
6449
+ documentation() {
6450
+ return {
6451
+ description: "`<map>` must have a unique name, it cannot be the same name as another `<map>` element",
6452
+ url: "https://html-validate.org/rules/map-dup-name.html",
6453
+ };
6454
+ }
6455
+ setup() {
6456
+ this.on("dom:ready", (event) => {
6457
+ const { document } = event;
6458
+ const maps = document.querySelectorAll("map[name]");
6459
+ const names = new Set();
6460
+ for (const map of maps) {
6461
+ const attr = map.getAttribute("name");
6462
+ /* istanbul ignore next -- should not happen as querySelector matches
6463
+ * only the elements with the name attribute */
6464
+ if (!attr) {
6465
+ continue;
6466
+ }
6467
+ const name = getName(attr);
6468
+ if (!name) {
6469
+ continue;
6470
+ }
6471
+ if (names.has(name)) {
6472
+ this.report({
6473
+ node: map,
6474
+ message: `<map> name must be unique`,
6475
+ location: attr.keyLocation,
6476
+ });
6477
+ }
6478
+ names.add(name);
6479
+ }
6480
+ });
6481
+ }
6482
+ }
6483
+
6916
6484
  class MissingDoctype extends Rule {
6917
6485
  documentation() {
6918
6486
  return {
6919
6487
  description: "Requires that the document contains a doctype.",
6920
- url: ruleDocumentationUrl("@/rules/missing-doctype.ts"),
6488
+ url: "https://html-validate.org/rules/missing-doctype.html",
6921
6489
  };
6922
6490
  }
6923
6491
  setup() {
@@ -6938,7 +6506,7 @@ class MultipleLabeledControls extends Rule {
6938
6506
  documentation() {
6939
6507
  return {
6940
6508
  description: `A \`<label>\` element can only be associated with one control at a time.`,
6941
- url: ruleDocumentationUrl("@/rules/multiple-labeled-controls.ts"),
6509
+ url: "https://html-validate.org/rules/multiple-labeled-controls.html",
6942
6510
  };
6943
6511
  }
6944
6512
  setup() {
@@ -6977,13 +6545,13 @@ class MultipleLabeledControls extends Rule {
6977
6545
  }
6978
6546
  }
6979
6547
 
6980
- const defaults$e = {
6548
+ const defaults$f = {
6981
6549
  include: null,
6982
6550
  exclude: null,
6983
6551
  };
6984
6552
  class NoAutoplay extends Rule {
6985
6553
  constructor(options) {
6986
- super({ ...defaults$e, ...options });
6554
+ super({ ...defaults$f, ...options });
6987
6555
  }
6988
6556
  documentation(context) {
6989
6557
  const tagName = context ? ` on <${context.tagName}>` : "";
@@ -6993,7 +6561,7 @@ class NoAutoplay extends Rule {
6993
6561
  "Autoplaying content can be disruptive for users and has accessibilty concerns.",
6994
6562
  "Prefer to let the user control playback.",
6995
6563
  ].join("\n"),
6996
- url: ruleDocumentationUrl("@/rules/no-autoplay.ts"),
6564
+ url: "https://html-validate.org/rules/no-autoplay.html",
6997
6565
  };
6998
6566
  }
6999
6567
  static schema() {
@@ -7053,7 +6621,7 @@ class NoConditionalComment extends Rule {
7053
6621
  documentation() {
7054
6622
  return {
7055
6623
  description: "Microsoft Internet Explorer previously supported using special HTML comments (conditional comments) for targeting specific versions of IE but since IE 10 it is deprecated and not supported in standards mode.",
7056
- url: ruleDocumentationUrl("@/rules/no-conditional-comment.ts"),
6624
+ url: "https://html-validate.org/rules/no-conditional-comment.html",
7057
6625
  };
7058
6626
  }
7059
6627
  setup() {
@@ -7067,7 +6635,7 @@ class NoDeprecatedAttr extends Rule {
7067
6635
  documentation() {
7068
6636
  return {
7069
6637
  description: "HTML5 deprecated many old attributes.",
7070
- url: ruleDocumentationUrl("@/rules/no-deprecated-attr.ts"),
6638
+ url: "https://html-validate.org/rules/no-deprecated-attr.html",
7071
6639
  };
7072
6640
  }
7073
6641
  setup() {
@@ -7095,7 +6663,7 @@ class NoDupAttr extends Rule {
7095
6663
  documentation() {
7096
6664
  return {
7097
6665
  description: "HTML disallows two or more attributes with the same (case-insensitive) name.",
7098
- url: ruleDocumentationUrl("@/rules/no-dup-attr.ts"),
6666
+ url: "https://html-validate.org/rules/no-dup-attr.html",
7099
6667
  };
7100
6668
  }
7101
6669
  setup() {
@@ -7122,7 +6690,7 @@ class NoDupClass extends Rule {
7122
6690
  documentation() {
7123
6691
  return {
7124
6692
  description: "Prevents unnecessary duplication of class names.",
7125
- url: ruleDocumentationUrl("@/rules/no-dup-class.ts"),
6693
+ url: "https://html-validate.org/rules/no-dup-class.html",
7126
6694
  };
7127
6695
  }
7128
6696
  setup() {
@@ -7147,7 +6715,7 @@ class NoDupID extends Rule {
7147
6715
  documentation() {
7148
6716
  return {
7149
6717
  description: "The ID of an element must be unique.",
7150
- url: ruleDocumentationUrl("@/rules/no-dup-id.ts"),
6718
+ url: "https://html-validate.org/rules/no-dup-id.html",
7151
6719
  };
7152
6720
  }
7153
6721
  setup() {
@@ -7194,7 +6762,7 @@ class NoImplicitClose extends Rule {
7194
6762
  description: `Some elements in HTML has optional end tags. When an optional tag is omitted a browser must handle it as if the end tag was present.
7195
6763
 
7196
6764
  Omitted end tags can be ambigious for humans to read and many editors have trouble formatting the markup.`,
7197
- url: ruleDocumentationUrl("@/rules/no-implicit-close.ts"),
6765
+ url: "https://html-validate.org/rules/no-implicit-close.html",
7198
6766
  };
7199
6767
  }
7200
6768
  setup() {
@@ -7224,14 +6792,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
7224
6792
  }
7225
6793
  }
7226
6794
 
7227
- const defaults$d = {
6795
+ const defaults$e = {
7228
6796
  include: null,
7229
6797
  exclude: null,
7230
6798
  allowedProperties: ["display"],
7231
6799
  };
7232
6800
  class NoInlineStyle extends Rule {
7233
6801
  constructor(options) {
7234
- super({ ...defaults$d, ...options });
6802
+ super({ ...defaults$e, ...options });
7235
6803
  }
7236
6804
  static schema() {
7237
6805
  return {
@@ -7280,7 +6848,7 @@ class NoInlineStyle extends Rule {
7280
6848
  }
7281
6849
  return {
7282
6850
  description: text.join("\n"),
7283
- url: ruleDocumentationUrl("@/rules/no-inline-style.ts"),
6851
+ url: "https://html-validate.org/rules/no-inline-style.html",
7284
6852
  };
7285
6853
  }
7286
6854
  setup() {
@@ -7341,13 +6909,13 @@ class NoMissingReferences extends Rule {
7341
6909
  if (context) {
7342
6910
  return {
7343
6911
  description: `The element ID "${context.value}" referenced by the ${context.key} attribute must point to an existing element.`,
7344
- url: ruleDocumentationUrl("@/rules/no-missing-references.ts"),
6912
+ url: "https://html-validate.org/rules/no-missing-references.html",
7345
6913
  };
7346
6914
  }
7347
6915
  else {
7348
6916
  return {
7349
6917
  description: `The element ID referenced by the attribute must point to an existing element.`,
7350
- url: ruleDocumentationUrl("@/rules/no-missing-references.ts"),
6918
+ url: "https://html-validate.org/rules/no-missing-references.html",
7351
6919
  };
7352
6920
  }
7353
6921
  }
@@ -7417,7 +6985,7 @@ class NoMultipleMain extends Rule {
7417
6985
  "",
7418
6986
  "Multiple `<main>` can be present in the DOM as long the others are hidden using the HTML5 `hidden` attribute.",
7419
6987
  ].join("\n"),
7420
- url: ruleDocumentationUrl("@/rules/no-multiple-main.ts"),
6988
+ url: "https://html-validate.org/rules/no-multiple-main.html",
7421
6989
  };
7422
6990
  }
7423
6991
  setup() {
@@ -7433,7 +7001,7 @@ class NoMultipleMain extends Rule {
7433
7001
  }
7434
7002
  }
7435
7003
 
7436
- const defaults$c = {
7004
+ const defaults$d = {
7437
7005
  relaxed: false,
7438
7006
  };
7439
7007
  const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
@@ -7450,7 +7018,7 @@ const replacementTable = {
7450
7018
  };
7451
7019
  class NoRawCharacters extends Rule {
7452
7020
  constructor(options) {
7453
- super({ ...defaults$c, ...options });
7021
+ super({ ...defaults$d, ...options });
7454
7022
  this.relaxed = this.options.relaxed;
7455
7023
  }
7456
7024
  static schema() {
@@ -7463,7 +7031,7 @@ class NoRawCharacters extends Rule {
7463
7031
  documentation() {
7464
7032
  return {
7465
7033
  description: `Some characters such as \`<\`, \`>\` and \`&\` hold special meaning in HTML and must be escaped using a character reference (html entity).`,
7466
- url: ruleDocumentationUrl("@/rules/no-raw-characters.ts"),
7034
+ url: "https://html-validate.org/rules/no-raw-characters.html",
7467
7035
  };
7468
7036
  }
7469
7037
  setup() {
@@ -7528,7 +7096,7 @@ class NoRedundantFor extends Rule {
7528
7096
  documentation() {
7529
7097
  return {
7530
7098
  description: `When the \`<label>\` element wraps the labelable control the \`for\` attribute is redundant and better left out.`,
7531
- url: ruleDocumentationUrl("@/rules/no-redundant-for.ts"),
7099
+ url: "https://html-validate.org/rules/no-redundant-for.html",
7532
7100
  };
7533
7101
  }
7534
7102
  setup() {
@@ -7590,7 +7158,7 @@ class NoRedundantRole extends Rule {
7590
7158
  documentation(context) {
7591
7159
  const doc = {
7592
7160
  description: `Using this role is redundant as it is already implied by the element.`,
7593
- url: ruleDocumentationUrl("@/rules/no-redundant-role.ts"),
7161
+ url: "https://html-validate.org/rules/no-redundant-role.html",
7594
7162
  };
7595
7163
  if (context) {
7596
7164
  doc.description = `Using the "${context.role}" role is redundant as it is already implied by the <${context.tagname}> element.`;
@@ -7628,13 +7196,13 @@ class NoRedundantRole extends Rule {
7628
7196
  }
7629
7197
 
7630
7198
  const xmlns = /^(.+):.+$/;
7631
- const defaults$b = {
7199
+ const defaults$c = {
7632
7200
  ignoreForeign: true,
7633
7201
  ignoreXML: true,
7634
7202
  };
7635
7203
  class NoSelfClosing extends Rule {
7636
7204
  constructor(options) {
7637
- super({ ...defaults$b, ...options });
7205
+ super({ ...defaults$c, ...options });
7638
7206
  }
7639
7207
  static schema() {
7640
7208
  return {
@@ -7650,7 +7218,7 @@ class NoSelfClosing extends Rule {
7650
7218
  tagName = tagName || "element";
7651
7219
  return {
7652
7220
  description: `Self-closing elements are disallowed. Use regular end tag <${tagName}></${tagName}> instead of self-closing <${tagName}/>.`,
7653
- url: ruleDocumentationUrl("@/rules/no-self-closing.ts"),
7221
+ url: "https://html-validate.org/rules/no-self-closing.html",
7654
7222
  };
7655
7223
  }
7656
7224
  setup() {
@@ -7694,7 +7262,7 @@ class NoStyleTag extends Rule {
7694
7262
  documentation() {
7695
7263
  return {
7696
7264
  description: "Prefer to use external stylesheets with the `<link>` tag instead of inlining the styling.",
7697
- url: ruleDocumentationUrl("@/rules/no-style-tag.ts"),
7265
+ url: "https://html-validate.org/rules/no-style-tag.html",
7698
7266
  };
7699
7267
  }
7700
7268
  setup() {
@@ -7711,7 +7279,7 @@ class NoTrailingWhitespace extends Rule {
7711
7279
  documentation() {
7712
7280
  return {
7713
7281
  description: "Lines with trailing whitespace cause unnessecary diff when using version control and usually serve no special purpose in HTML.",
7714
- url: ruleDocumentationUrl("@/rules/no-trailing-whitespace.ts"),
7282
+ url: "https://html-validate.org/rules/no-trailing-whitespace.html",
7715
7283
  };
7716
7284
  }
7717
7285
  setup() {
@@ -7728,7 +7296,7 @@ class NoUnknownElements extends Rule {
7728
7296
  const element = context ? ` <${context}>` : "";
7729
7297
  return {
7730
7298
  description: `An unknown element${element} was used. If this is a Custom Element you need to supply element metadata for it.`,
7731
- url: ruleDocumentationUrl("@/rules/no-unknown-elements.ts"),
7299
+ url: "https://html-validate.org/rules/no-unknown-elements.html",
7732
7300
  };
7733
7301
  }
7734
7302
  setup() {
@@ -7745,7 +7313,7 @@ class NoUtf8Bom extends Rule {
7745
7313
  documentation() {
7746
7314
  return {
7747
7315
  description: `This file is saved with the UTF-8 byte order mark (BOM) present. It is neither required or recommended to use.\n\nInstead the document should be served with the \`Content-Type: application/javascript; charset=utf-8\` header.`,
7748
- url: ruleDocumentationUrl("@/rules/no-utf8-bom.ts"),
7316
+ url: "https://html-validate.org/rules/no-utf8-bom.html",
7749
7317
  };
7750
7318
  }
7751
7319
  setup() {
@@ -7767,13 +7335,13 @@ const replacement = {
7767
7335
  reset: '<button type="reset">',
7768
7336
  image: '<button type="button">',
7769
7337
  };
7770
- const defaults$a = {
7338
+ const defaults$b = {
7771
7339
  include: null,
7772
7340
  exclude: null,
7773
7341
  };
7774
7342
  class PreferButton extends Rule {
7775
7343
  constructor(options) {
7776
- super({ ...defaults$a, ...options });
7344
+ super({ ...defaults$b, ...options });
7777
7345
  }
7778
7346
  static schema() {
7779
7347
  return {
@@ -7808,7 +7376,7 @@ class PreferButton extends Rule {
7808
7376
  documentation(context) {
7809
7377
  const doc = {
7810
7378
  description: `Prefer to use the generic \`<button>\` element instead of \`<input>\`.`,
7811
- url: ruleDocumentationUrl("@/rules/prefer-button.ts"),
7379
+ url: "https://html-validate.org/rules/prefer-button.html",
7812
7380
  };
7813
7381
  if (context) {
7814
7382
  const src = `<input type="${context.type}">`;
@@ -7848,7 +7416,7 @@ class PreferButton extends Rule {
7848
7416
  }
7849
7417
  }
7850
7418
 
7851
- const defaults$9 = {
7419
+ const defaults$a = {
7852
7420
  mapping: {
7853
7421
  article: "article",
7854
7422
  banner: "header",
@@ -7878,7 +7446,7 @@ const defaults$9 = {
7878
7446
  };
7879
7447
  class PreferNativeElement extends Rule {
7880
7448
  constructor(options) {
7881
- super({ ...defaults$9, ...options });
7449
+ super({ ...defaults$a, ...options });
7882
7450
  }
7883
7451
  static schema() {
7884
7452
  return {
@@ -7916,7 +7484,7 @@ class PreferNativeElement extends Rule {
7916
7484
  documentation(context) {
7917
7485
  const doc = {
7918
7486
  description: `Instead of using WAI-ARIA roles prefer to use the native HTML elements.`,
7919
- url: ruleDocumentationUrl("@/rules/prefer-native-element.ts"),
7487
+ url: "https://html-validate.org/rules/prefer-native-element.html",
7920
7488
  };
7921
7489
  if (context) {
7922
7490
  doc.description = `Instead of using the WAI-ARIA role "${context.role}" prefer to use the native <${context.replacement}> element.`;
@@ -7979,7 +7547,7 @@ class PreferTbody extends Rule {
7979
7547
  documentation() {
7980
7548
  return {
7981
7549
  description: `While \`<tbody>\` is optional is relays semantic information about its contents. Where applicable it should also be combined with \`<thead>\` and \`<tfoot>\`.`,
7982
- url: ruleDocumentationUrl("@/rules/prefer-tbody.ts"),
7550
+ url: "https://html-validate.org/rules/prefer-tbody.html",
7983
7551
  };
7984
7552
  }
7985
7553
  setup() {
@@ -7998,12 +7566,12 @@ class PreferTbody extends Rule {
7998
7566
  }
7999
7567
  }
8000
7568
 
8001
- const defaults$8 = {
7569
+ const defaults$9 = {
8002
7570
  tags: ["script", "style"],
8003
7571
  };
8004
7572
  class RequireCSPNonce extends Rule {
8005
7573
  constructor(options) {
8006
- super({ ...defaults$8, ...options });
7574
+ super({ ...defaults$9, ...options });
8007
7575
  }
8008
7576
  static schema() {
8009
7577
  return {
@@ -8027,7 +7595,7 @@ class RequireCSPNonce extends Rule {
8027
7595
  "The nonce should be unique per each request and set to a cryptography secure random token.",
8028
7596
  "It is used to prevent cross site scripting (XSS) by preventing malicious actors from injecting scripts onto the page.",
8029
7597
  ].join("\n"),
8030
- url: ruleDocumentationUrl("@/rules/require-csp-nonce.ts"),
7598
+ url: "https://html-validate.org/rules/require-csp-nonce.html",
8031
7599
  };
8032
7600
  }
8033
7601
  setup() {
@@ -8054,7 +7622,7 @@ class RequireCSPNonce extends Rule {
8054
7622
  }
8055
7623
  }
8056
7624
 
8057
- const defaults$7 = {
7625
+ const defaults$8 = {
8058
7626
  target: "all",
8059
7627
  include: null,
8060
7628
  exclude: null,
@@ -8066,7 +7634,7 @@ const supportSri = {
8066
7634
  };
8067
7635
  class RequireSri extends Rule {
8068
7636
  constructor(options) {
8069
- super({ ...defaults$7, ...options });
7637
+ super({ ...defaults$8, ...options });
8070
7638
  this.target = this.options.target;
8071
7639
  }
8072
7640
  static schema() {
@@ -8106,7 +7674,7 @@ class RequireSri extends Rule {
8106
7674
  documentation() {
8107
7675
  return {
8108
7676
  description: `Subresource Integrity (SRI) \`integrity\` attribute is required to prevent manipulation from Content Delivery Networks or other third-party hosting.`,
8109
- url: ruleDocumentationUrl("@/rules/require-sri.ts"),
7677
+ url: "https://html-validate.org/rules/require-sri.html",
8110
7678
  };
8111
7679
  }
8112
7680
  setup() {
@@ -8152,7 +7720,7 @@ class ScriptElement extends Rule {
8152
7720
  documentation() {
8153
7721
  return {
8154
7722
  description: "The end tag for `<script>` is a hard requirement and must never be omitted even when using the `src` attribute.",
8155
- url: ruleDocumentationUrl("@/rules/script-element.ts"),
7723
+ url: "https://html-validate.org/rules/script-element.html",
8156
7724
  };
8157
7725
  }
8158
7726
  setup() {
@@ -8179,7 +7747,7 @@ class ScriptType extends Rule {
8179
7747
  documentation() {
8180
7748
  return {
8181
7749
  description: "While valid the HTML5 standard encourages authors to omit the type element for JavaScript resources.",
8182
- url: ruleDocumentationUrl("@/rules/script-type.ts"),
7750
+ url: "https://html-validate.org/rules/script-type.html",
8183
7751
  };
8184
7752
  }
8185
7753
  setup() {
@@ -8210,7 +7778,7 @@ class SvgFocusable extends Rule {
8210
7778
  documentation() {
8211
7779
  return {
8212
7780
  description: `Inline SVG elements in IE are focusable by default which may cause issues with tab-ordering. The \`focusable\` attribute should explicitly be set to avoid unintended behaviour.`,
8213
- url: ruleDocumentationUrl("@/rules/svg-focusable.ts"),
7781
+ url: "https://html-validate.org/rules/svg-focusable.html",
8214
7782
  };
8215
7783
  }
8216
7784
  setup() {
@@ -8228,7 +7796,7 @@ class SvgFocusable extends Rule {
8228
7796
  }
8229
7797
  }
8230
7798
 
8231
- const defaults$6 = {
7799
+ const defaults$7 = {
8232
7800
  characters: [
8233
7801
  { pattern: " ", replacement: "&nbsp;", description: "non-breaking space" },
8234
7802
  { pattern: "-", replacement: "&#8209;", description: "non-breaking hyphen" },
@@ -8271,7 +7839,7 @@ function matchAll(text, regexp) {
8271
7839
  }
8272
7840
  class TelNonBreaking extends Rule {
8273
7841
  constructor(options) {
8274
- super({ ...defaults$6, ...options });
7842
+ super({ ...defaults$7, ...options });
8275
7843
  this.regex = constructRegex(this.options.characters);
8276
7844
  }
8277
7845
  static schema() {
@@ -8323,7 +7891,7 @@ class TelNonBreaking extends Rule {
8323
7891
  "",
8324
7892
  ...replacements,
8325
7893
  ].join("\n"),
8326
- url: ruleDocumentationUrl("@/rules/tel-non-breaking.ts"),
7894
+ url: "https://html-validate.org/rules/tel-non-breaking.html",
8327
7895
  };
8328
7896
  }
8329
7897
  setup() {
@@ -8442,7 +8010,7 @@ function isNonEmptyText(node) {
8442
8010
  * - Elements with default text
8443
8011
  */
8444
8012
  function haveAccessibleText(node) {
8445
- if (!inAccessibilityTree(node)) {
8013
+ if (!rulesHelper.inAccessibilityTree(node)) {
8446
8014
  return false;
8447
8015
  }
8448
8016
  /* check direct descendants for non-empty or dynamic text */
@@ -8470,7 +8038,7 @@ class TextContent extends Rule {
8470
8038
  documentation(context) {
8471
8039
  const doc = {
8472
8040
  description: `The textual content for this element is not valid.`,
8473
- url: ruleDocumentationUrl("@/rules/text-content.ts"),
8041
+ url: "https://html-validate.org/rules/text-content.html",
8474
8042
  };
8475
8043
  if (context === null || context === void 0 ? void 0 : context.textContent) {
8476
8044
  switch (context.textContent) {
@@ -8521,7 +8089,7 @@ class TextContent extends Rule {
8521
8089
  * Validate element has empty text (inter-element whitespace is not considered text)
8522
8090
  */
8523
8091
  validateNone(node) {
8524
- if (classifyNodeText(node) === exports.TextClassification.EMPTY_TEXT) {
8092
+ if (rulesHelper.classifyNodeText(node) === rulesHelper.TextClassification.EMPTY_TEXT) {
8525
8093
  return;
8526
8094
  }
8527
8095
  this.reportError(node, node.meta, `${node.annotatedName} must not have text content`);
@@ -8530,7 +8098,7 @@ class TextContent extends Rule {
8530
8098
  * Validate element has any text (inter-element whitespace is not considered text)
8531
8099
  */
8532
8100
  validateRequired(node) {
8533
- if (classifyNodeText(node) !== exports.TextClassification.EMPTY_TEXT) {
8101
+ if (rulesHelper.classifyNodeText(node) !== rulesHelper.TextClassification.EMPTY_TEXT) {
8534
8102
  return;
8535
8103
  }
8536
8104
  this.reportError(node, node.meta, `${node.annotatedName} must have text content`);
@@ -8541,7 +8109,7 @@ class TextContent extends Rule {
8541
8109
  */
8542
8110
  validateAccessible(node) {
8543
8111
  /* skip this element if the element isn't present in accessibility tree */
8544
- if (!inAccessibilityTree(node)) {
8112
+ if (!rulesHelper.inAccessibilityTree(node)) {
8545
8113
  return;
8546
8114
  }
8547
8115
  /* if the element or a child has aria-label, alt or default text, etc the
@@ -8559,1737 +8127,64 @@ class TextContent extends Rule {
8559
8127
  }
8560
8128
  }
8561
8129
 
8562
- var entities$1 = [
8563
- "&aacute;",
8564
- "&abreve;",
8565
- "&ac;",
8566
- "&acd;",
8567
- "&ace;",
8568
- "&acirc;",
8569
- "&acute;",
8570
- "&acy;",
8571
- "&aelig;",
8572
- "&af;",
8573
- "&afr;",
8574
- "&agrave;",
8575
- "&alefsym;",
8576
- "&aleph;",
8577
- "&alpha;",
8578
- "&amacr;",
8579
- "&amalg;",
8580
- "&amp;",
8581
- "&and;",
8582
- "&andand;",
8583
- "&andd;",
8584
- "&andslope;",
8585
- "&andv;",
8586
- "&ang;",
8587
- "&ange;",
8588
- "&angle;",
8589
- "&angmsd;",
8590
- "&angmsdaa;",
8591
- "&angmsdab;",
8592
- "&angmsdac;",
8593
- "&angmsdad;",
8594
- "&angmsdae;",
8595
- "&angmsdaf;",
8596
- "&angmsdag;",
8597
- "&angmsdah;",
8598
- "&angrt;",
8599
- "&angrtvb;",
8600
- "&angrtvbd;",
8601
- "&angsph;",
8602
- "&angst;",
8603
- "&angzarr;",
8604
- "&aogon;",
8605
- "&aopf;",
8606
- "&ap;",
8607
- "&apacir;",
8608
- "&ape;",
8609
- "&apid;",
8610
- "&apos;",
8611
- "&applyfunction;",
8612
- "&approx;",
8613
- "&approxeq;",
8614
- "&aring;",
8615
- "&ascr;",
8616
- "&assign;",
8617
- "&ast;",
8618
- "&asymp;",
8619
- "&asympeq;",
8620
- "&atilde;",
8621
- "&auml;",
8622
- "&awconint;",
8623
- "&awint;",
8624
- "&backcong;",
8625
- "&backepsilon;",
8626
- "&backprime;",
8627
- "&backsim;",
8628
- "&backsimeq;",
8629
- "&backslash;",
8630
- "&barv;",
8631
- "&barvee;",
8632
- "&barwed;",
8633
- "&barwedge;",
8634
- "&bbrk;",
8635
- "&bbrktbrk;",
8636
- "&bcong;",
8637
- "&bcy;",
8638
- "&bdquo;",
8639
- "&becaus;",
8640
- "&because;",
8641
- "&bemptyv;",
8642
- "&bepsi;",
8643
- "&bernou;",
8644
- "&bernoullis;",
8645
- "&beta;",
8646
- "&beth;",
8647
- "&between;",
8648
- "&bfr;",
8649
- "&bigcap;",
8650
- "&bigcirc;",
8651
- "&bigcup;",
8652
- "&bigodot;",
8653
- "&bigoplus;",
8654
- "&bigotimes;",
8655
- "&bigsqcup;",
8656
- "&bigstar;",
8657
- "&bigtriangledown;",
8658
- "&bigtriangleup;",
8659
- "&biguplus;",
8660
- "&bigvee;",
8661
- "&bigwedge;",
8662
- "&bkarow;",
8663
- "&blacklozenge;",
8664
- "&blacksquare;",
8665
- "&blacktriangle;",
8666
- "&blacktriangledown;",
8667
- "&blacktriangleleft;",
8668
- "&blacktriangleright;",
8669
- "&blank;",
8670
- "&blk12;",
8671
- "&blk14;",
8672
- "&blk34;",
8673
- "&block;",
8674
- "&bne;",
8675
- "&bnequiv;",
8676
- "&bnot;",
8677
- "&bopf;",
8678
- "&bot;",
8679
- "&bottom;",
8680
- "&bowtie;",
8681
- "&boxbox;",
8682
- "&boxdl;",
8683
- "&boxdr;",
8684
- "&boxh;",
8685
- "&boxhd;",
8686
- "&boxhu;",
8687
- "&boxminus;",
8688
- "&boxplus;",
8689
- "&boxtimes;",
8690
- "&boxul;",
8691
- "&boxur;",
8692
- "&boxv;",
8693
- "&boxvh;",
8694
- "&boxvl;",
8695
- "&boxvr;",
8696
- "&bprime;",
8697
- "&breve;",
8698
- "&brvbar;",
8699
- "&bscr;",
8700
- "&bsemi;",
8701
- "&bsim;",
8702
- "&bsime;",
8703
- "&bsol;",
8704
- "&bsolb;",
8705
- "&bsolhsub;",
8706
- "&bull;",
8707
- "&bullet;",
8708
- "&bump;",
8709
- "&bumpe;",
8710
- "&bumpeq;",
8711
- "&cacute;",
8712
- "&cap;",
8713
- "&capand;",
8714
- "&capbrcup;",
8715
- "&capcap;",
8716
- "&capcup;",
8717
- "&capdot;",
8718
- "&capitaldifferentiald;",
8719
- "&caps;",
8720
- "&caret;",
8721
- "&caron;",
8722
- "&cayleys;",
8723
- "&ccaps;",
8724
- "&ccaron;",
8725
- "&ccedil;",
8726
- "&ccirc;",
8727
- "&cconint;",
8728
- "&ccups;",
8729
- "&ccupssm;",
8730
- "&cdot;",
8731
- "&cedil;",
8732
- "&cedilla;",
8733
- "&cemptyv;",
8734
- "&cent;",
8735
- "&centerdot;",
8736
- "&cfr;",
8737
- "&chcy;",
8738
- "&check;",
8739
- "&checkmark;",
8740
- "&chi;",
8741
- "&cir;",
8742
- "&circ;",
8743
- "&circeq;",
8744
- "&circlearrowleft;",
8745
- "&circlearrowright;",
8746
- "&circledast;",
8747
- "&circledcirc;",
8748
- "&circleddash;",
8749
- "&circledot;",
8750
- "&circledr;",
8751
- "&circleds;",
8752
- "&circleminus;",
8753
- "&circleplus;",
8754
- "&circletimes;",
8755
- "&cire;",
8756
- "&cirfnint;",
8757
- "&cirmid;",
8758
- "&cirscir;",
8759
- "&clockwisecontourintegral;",
8760
- "&closecurlydoublequote;",
8761
- "&closecurlyquote;",
8762
- "&clubs;",
8763
- "&clubsuit;",
8764
- "&colon;",
8765
- "&colone;",
8766
- "&coloneq;",
8767
- "&comma;",
8768
- "&commat;",
8769
- "&comp;",
8770
- "&compfn;",
8771
- "&complement;",
8772
- "&complexes;",
8773
- "&cong;",
8774
- "&congdot;",
8775
- "&congruent;",
8776
- "&conint;",
8777
- "&contourintegral;",
8778
- "&copf;",
8779
- "&coprod;",
8780
- "&coproduct;",
8781
- "&copy;",
8782
- "&copysr;",
8783
- "&counterclockwisecontourintegral;",
8784
- "&crarr;",
8785
- "&cross;",
8786
- "&cscr;",
8787
- "&csub;",
8788
- "&csube;",
8789
- "&csup;",
8790
- "&csupe;",
8791
- "&ctdot;",
8792
- "&cudarrl;",
8793
- "&cudarrr;",
8794
- "&cuepr;",
8795
- "&cuesc;",
8796
- "&cularr;",
8797
- "&cularrp;",
8798
- "&cup;",
8799
- "&cupbrcap;",
8800
- "&cupcap;",
8801
- "&cupcup;",
8802
- "&cupdot;",
8803
- "&cupor;",
8804
- "&cups;",
8805
- "&curarr;",
8806
- "&curarrm;",
8807
- "&curlyeqprec;",
8808
- "&curlyeqsucc;",
8809
- "&curlyvee;",
8810
- "&curlywedge;",
8811
- "&curren;",
8812
- "&curvearrowleft;",
8813
- "&curvearrowright;",
8814
- "&cuvee;",
8815
- "&cuwed;",
8816
- "&cwconint;",
8817
- "&cwint;",
8818
- "&cylcty;",
8819
- "&dagger;",
8820
- "&daleth;",
8821
- "&darr;",
8822
- "&dash;",
8823
- "&dashv;",
8824
- "&dbkarow;",
8825
- "&dblac;",
8826
- "&dcaron;",
8827
- "&dcy;",
8828
- "&dd;",
8829
- "&ddagger;",
8830
- "&ddarr;",
8831
- "&ddotrahd;",
8832
- "&ddotseq;",
8833
- "&deg;",
8834
- "&del;",
8835
- "&delta;",
8836
- "&demptyv;",
8837
- "&dfisht;",
8838
- "&dfr;",
8839
- "&dhar;",
8840
- "&dharl;",
8841
- "&dharr;",
8842
- "&diacriticalacute;",
8843
- "&diacriticaldot;",
8844
- "&diacriticaldoubleacute;",
8845
- "&diacriticalgrave;",
8846
- "&diacriticaltilde;",
8847
- "&diam;",
8848
- "&diamond;",
8849
- "&diamondsuit;",
8850
- "&diams;",
8851
- "&die;",
8852
- "&differentiald;",
8853
- "&digamma;",
8854
- "&disin;",
8855
- "&div;",
8856
- "&divide;",
8857
- "&divideontimes;",
8858
- "&divonx;",
8859
- "&djcy;",
8860
- "&dlcorn;",
8861
- "&dlcrop;",
8862
- "&dollar;",
8863
- "&dopf;",
8864
- "&dot;",
8865
- "&dotdot;",
8866
- "&doteq;",
8867
- "&doteqdot;",
8868
- "&dotequal;",
8869
- "&dotminus;",
8870
- "&dotplus;",
8871
- "&dotsquare;",
8872
- "&doublebarwedge;",
8873
- "&doublecontourintegral;",
8874
- "&doubledot;",
8875
- "&doubledownarrow;",
8876
- "&doubleleftarrow;",
8877
- "&doubleleftrightarrow;",
8878
- "&doublelefttee;",
8879
- "&doublelongleftarrow;",
8880
- "&doublelongleftrightarrow;",
8881
- "&doublelongrightarrow;",
8882
- "&doublerightarrow;",
8883
- "&doublerighttee;",
8884
- "&doubleuparrow;",
8885
- "&doubleupdownarrow;",
8886
- "&doubleverticalbar;",
8887
- "&downarrow;",
8888
- "&downarrowbar;",
8889
- "&downarrowuparrow;",
8890
- "&downbreve;",
8891
- "&downdownarrows;",
8892
- "&downharpoonleft;",
8893
- "&downharpoonright;",
8894
- "&downleftrightvector;",
8895
- "&downleftteevector;",
8896
- "&downleftvector;",
8897
- "&downleftvectorbar;",
8898
- "&downrightteevector;",
8899
- "&downrightvector;",
8900
- "&downrightvectorbar;",
8901
- "&downtee;",
8902
- "&downteearrow;",
8903
- "&drbkarow;",
8904
- "&drcorn;",
8905
- "&drcrop;",
8906
- "&dscr;",
8907
- "&dscy;",
8908
- "&dsol;",
8909
- "&dstrok;",
8910
- "&dtdot;",
8911
- "&dtri;",
8912
- "&dtrif;",
8913
- "&duarr;",
8914
- "&duhar;",
8915
- "&dwangle;",
8916
- "&dzcy;",
8917
- "&dzigrarr;",
8918
- "&eacute;",
8919
- "&easter;",
8920
- "&ecaron;",
8921
- "&ecir;",
8922
- "&ecirc;",
8923
- "&ecolon;",
8924
- "&ecy;",
8925
- "&eddot;",
8926
- "&edot;",
8927
- "&ee;",
8928
- "&efdot;",
8929
- "&efr;",
8930
- "&eg;",
8931
- "&egrave;",
8932
- "&egs;",
8933
- "&egsdot;",
8934
- "&el;",
8935
- "&element;",
8936
- "&elinters;",
8937
- "&ell;",
8938
- "&els;",
8939
- "&elsdot;",
8940
- "&emacr;",
8941
- "&empty;",
8942
- "&emptyset;",
8943
- "&emptysmallsquare;",
8944
- "&emptyv;",
8945
- "&emptyverysmallsquare;",
8946
- "&emsp13;",
8947
- "&emsp14;",
8948
- "&emsp;",
8949
- "&eng;",
8950
- "&ensp;",
8951
- "&eogon;",
8952
- "&eopf;",
8953
- "&epar;",
8954
- "&eparsl;",
8955
- "&eplus;",
8956
- "&epsi;",
8957
- "&epsilon;",
8958
- "&epsiv;",
8959
- "&eqcirc;",
8960
- "&eqcolon;",
8961
- "&eqsim;",
8962
- "&eqslantgtr;",
8963
- "&eqslantless;",
8964
- "&equal;",
8965
- "&equals;",
8966
- "&equaltilde;",
8967
- "&equest;",
8968
- "&equilibrium;",
8969
- "&equiv;",
8970
- "&equivdd;",
8971
- "&eqvparsl;",
8972
- "&erarr;",
8973
- "&erdot;",
8974
- "&escr;",
8975
- "&esdot;",
8976
- "&esim;",
8977
- "&eta;",
8978
- "&eth;",
8979
- "&euml;",
8980
- "&euro;",
8981
- "&excl;",
8982
- "&exist;",
8983
- "&exists;",
8984
- "&expectation;",
8985
- "&exponentiale;",
8986
- "&fallingdotseq;",
8987
- "&fcy;",
8988
- "&female;",
8989
- "&ffilig;",
8990
- "&fflig;",
8991
- "&ffllig;",
8992
- "&ffr;",
8993
- "&filig;",
8994
- "&filledsmallsquare;",
8995
- "&filledverysmallsquare;",
8996
- "&fjlig;",
8997
- "&flat;",
8998
- "&fllig;",
8999
- "&fltns;",
9000
- "&fnof;",
9001
- "&fopf;",
9002
- "&forall;",
9003
- "&fork;",
9004
- "&forkv;",
9005
- "&fouriertrf;",
9006
- "&fpartint;",
9007
- "&frac12;",
9008
- "&frac13;",
9009
- "&frac14;",
9010
- "&frac15;",
9011
- "&frac16;",
9012
- "&frac18;",
9013
- "&frac23;",
9014
- "&frac25;",
9015
- "&frac34;",
9016
- "&frac35;",
9017
- "&frac38;",
9018
- "&frac45;",
9019
- "&frac56;",
9020
- "&frac58;",
9021
- "&frac78;",
9022
- "&frasl;",
9023
- "&frown;",
9024
- "&fscr;",
9025
- "&gacute;",
9026
- "&gamma;",
9027
- "&gammad;",
9028
- "&gap;",
9029
- "&gbreve;",
9030
- "&gcedil;",
9031
- "&gcirc;",
9032
- "&gcy;",
9033
- "&gdot;",
9034
- "&ge;",
9035
- "&gel;",
9036
- "&geq;",
9037
- "&geqq;",
9038
- "&geqslant;",
9039
- "&ges;",
9040
- "&gescc;",
9041
- "&gesdot;",
9042
- "&gesdoto;",
9043
- "&gesdotol;",
9044
- "&gesl;",
9045
- "&gesles;",
9046
- "&gfr;",
9047
- "&gg;",
9048
- "&ggg;",
9049
- "&gimel;",
9050
- "&gjcy;",
9051
- "&gl;",
9052
- "&gla;",
9053
- "&gle;",
9054
- "&glj;",
9055
- "&gnap;",
9056
- "&gnapprox;",
9057
- "&gne;",
9058
- "&gneq;",
9059
- "&gneqq;",
9060
- "&gnsim;",
9061
- "&gopf;",
9062
- "&grave;",
9063
- "&greaterequal;",
9064
- "&greaterequalless;",
9065
- "&greaterfullequal;",
9066
- "&greatergreater;",
9067
- "&greaterless;",
9068
- "&greaterslantequal;",
9069
- "&greatertilde;",
9070
- "&gscr;",
9071
- "&gsim;",
9072
- "&gsime;",
9073
- "&gsiml;",
9074
- "&gt;",
9075
- "&gtcc;",
9076
- "&gtcir;",
9077
- "&gtdot;",
9078
- "&gtlpar;",
9079
- "&gtquest;",
9080
- "&gtrapprox;",
9081
- "&gtrarr;",
9082
- "&gtrdot;",
9083
- "&gtreqless;",
9084
- "&gtreqqless;",
9085
- "&gtrless;",
9086
- "&gtrsim;",
9087
- "&gvertneqq;",
9088
- "&gvne;",
9089
- "&hacek;",
9090
- "&hairsp;",
9091
- "&half;",
9092
- "&hamilt;",
9093
- "&hardcy;",
9094
- "&harr;",
9095
- "&harrcir;",
9096
- "&harrw;",
9097
- "&hat;",
9098
- "&hbar;",
9099
- "&hcirc;",
9100
- "&hearts;",
9101
- "&heartsuit;",
9102
- "&hellip;",
9103
- "&hercon;",
9104
- "&hfr;",
9105
- "&hilbertspace;",
9106
- "&hksearow;",
9107
- "&hkswarow;",
9108
- "&hoarr;",
9109
- "&homtht;",
9110
- "&hookleftarrow;",
9111
- "&hookrightarrow;",
9112
- "&hopf;",
9113
- "&horbar;",
9114
- "&horizontalline;",
9115
- "&hscr;",
9116
- "&hslash;",
9117
- "&hstrok;",
9118
- "&humpdownhump;",
9119
- "&humpequal;",
9120
- "&hybull;",
9121
- "&hyphen;",
9122
- "&iacute;",
9123
- "&ic;",
9124
- "&icirc;",
9125
- "&icy;",
9126
- "&idot;",
9127
- "&iecy;",
9128
- "&iexcl;",
9129
- "&iff;",
9130
- "&ifr;",
9131
- "&igrave;",
9132
- "&ii;",
9133
- "&iiiint;",
9134
- "&iiint;",
9135
- "&iinfin;",
9136
- "&iiota;",
9137
- "&ijlig;",
9138
- "&im;",
9139
- "&imacr;",
9140
- "&image;",
9141
- "&imaginaryi;",
9142
- "&imagline;",
9143
- "&imagpart;",
9144
- "&imath;",
9145
- "&imof;",
9146
- "&imped;",
9147
- "&implies;",
9148
- "&in;",
9149
- "&incare;",
9150
- "&infin;",
9151
- "&infintie;",
9152
- "&inodot;",
9153
- "&int;",
9154
- "&intcal;",
9155
- "&integers;",
9156
- "&integral;",
9157
- "&intercal;",
9158
- "&intersection;",
9159
- "&intlarhk;",
9160
- "&intprod;",
9161
- "&invisiblecomma;",
9162
- "&invisibletimes;",
9163
- "&iocy;",
9164
- "&iogon;",
9165
- "&iopf;",
9166
- "&iota;",
9167
- "&iprod;",
9168
- "&iquest;",
9169
- "&iscr;",
9170
- "&isin;",
9171
- "&isindot;",
9172
- "&isine;",
9173
- "&isins;",
9174
- "&isinsv;",
9175
- "&isinv;",
9176
- "&it;",
9177
- "&itilde;",
9178
- "&iukcy;",
9179
- "&iuml;",
9180
- "&jcirc;",
9181
- "&jcy;",
9182
- "&jfr;",
9183
- "&jmath;",
9184
- "&jopf;",
9185
- "&jscr;",
9186
- "&jsercy;",
9187
- "&jukcy;",
9188
- "&kappa;",
9189
- "&kappav;",
9190
- "&kcedil;",
9191
- "&kcy;",
9192
- "&kfr;",
9193
- "&kgreen;",
9194
- "&khcy;",
9195
- "&kjcy;",
9196
- "&kopf;",
9197
- "&kscr;",
9198
- "&laarr;",
9199
- "&lacute;",
9200
- "&laemptyv;",
9201
- "&lagran;",
9202
- "&lambda;",
9203
- "&lang;",
9204
- "&langd;",
9205
- "&langle;",
9206
- "&lap;",
9207
- "&laplacetrf;",
9208
- "&laquo;",
9209
- "&larr;",
9210
- "&larrb;",
9211
- "&larrbfs;",
9212
- "&larrfs;",
9213
- "&larrhk;",
9214
- "&larrlp;",
9215
- "&larrpl;",
9216
- "&larrsim;",
9217
- "&larrtl;",
9218
- "&lat;",
9219
- "&latail;",
9220
- "&late;",
9221
- "&lates;",
9222
- "&lbarr;",
9223
- "&lbbrk;",
9224
- "&lbrace;",
9225
- "&lbrack;",
9226
- "&lbrke;",
9227
- "&lbrksld;",
9228
- "&lbrkslu;",
9229
- "&lcaron;",
9230
- "&lcedil;",
9231
- "&lceil;",
9232
- "&lcub;",
9233
- "&lcy;",
9234
- "&ldca;",
9235
- "&ldquo;",
9236
- "&ldquor;",
9237
- "&ldrdhar;",
9238
- "&ldrushar;",
9239
- "&ldsh;",
9240
- "&le;",
9241
- "&leftanglebracket;",
9242
- "&leftarrow;",
9243
- "&leftarrowbar;",
9244
- "&leftarrowrightarrow;",
9245
- "&leftarrowtail;",
9246
- "&leftceiling;",
9247
- "&leftdoublebracket;",
9248
- "&leftdownteevector;",
9249
- "&leftdownvector;",
9250
- "&leftdownvectorbar;",
9251
- "&leftfloor;",
9252
- "&leftharpoondown;",
9253
- "&leftharpoonup;",
9254
- "&leftleftarrows;",
9255
- "&leftrightarrow;",
9256
- "&leftrightarrows;",
9257
- "&leftrightharpoons;",
9258
- "&leftrightsquigarrow;",
9259
- "&leftrightvector;",
9260
- "&lefttee;",
9261
- "&leftteearrow;",
9262
- "&leftteevector;",
9263
- "&leftthreetimes;",
9264
- "&lefttriangle;",
9265
- "&lefttrianglebar;",
9266
- "&lefttriangleequal;",
9267
- "&leftupdownvector;",
9268
- "&leftupteevector;",
9269
- "&leftupvector;",
9270
- "&leftupvectorbar;",
9271
- "&leftvector;",
9272
- "&leftvectorbar;",
9273
- "&leg;",
9274
- "&leq;",
9275
- "&leqq;",
9276
- "&leqslant;",
9277
- "&les;",
9278
- "&lescc;",
9279
- "&lesdot;",
9280
- "&lesdoto;",
9281
- "&lesdotor;",
9282
- "&lesg;",
9283
- "&lesges;",
9284
- "&lessapprox;",
9285
- "&lessdot;",
9286
- "&lesseqgtr;",
9287
- "&lesseqqgtr;",
9288
- "&lessequalgreater;",
9289
- "&lessfullequal;",
9290
- "&lessgreater;",
9291
- "&lessgtr;",
9292
- "&lessless;",
9293
- "&lesssim;",
9294
- "&lessslantequal;",
9295
- "&lesstilde;",
9296
- "&lfisht;",
9297
- "&lfloor;",
9298
- "&lfr;",
9299
- "&lg;",
9300
- "&lge;",
9301
- "&lhar;",
9302
- "&lhard;",
9303
- "&lharu;",
9304
- "&lharul;",
9305
- "&lhblk;",
9306
- "&ljcy;",
9307
- "&ll;",
9308
- "&llarr;",
9309
- "&llcorner;",
9310
- "&lleftarrow;",
9311
- "&llhard;",
9312
- "&lltri;",
9313
- "&lmidot;",
9314
- "&lmoust;",
9315
- "&lmoustache;",
9316
- "&lnap;",
9317
- "&lnapprox;",
9318
- "&lne;",
9319
- "&lneq;",
9320
- "&lneqq;",
9321
- "&lnsim;",
9322
- "&loang;",
9323
- "&loarr;",
9324
- "&lobrk;",
9325
- "&longleftarrow;",
9326
- "&longleftrightarrow;",
9327
- "&longmapsto;",
9328
- "&longrightarrow;",
9329
- "&looparrowleft;",
9330
- "&looparrowright;",
9331
- "&lopar;",
9332
- "&lopf;",
9333
- "&loplus;",
9334
- "&lotimes;",
9335
- "&lowast;",
9336
- "&lowbar;",
9337
- "&lowerleftarrow;",
9338
- "&lowerrightarrow;",
9339
- "&loz;",
9340
- "&lozenge;",
9341
- "&lozf;",
9342
- "&lpar;",
9343
- "&lparlt;",
9344
- "&lrarr;",
9345
- "&lrcorner;",
9346
- "&lrhar;",
9347
- "&lrhard;",
9348
- "&lrm;",
9349
- "&lrtri;",
9350
- "&lsaquo;",
9351
- "&lscr;",
9352
- "&lsh;",
9353
- "&lsim;",
9354
- "&lsime;",
9355
- "&lsimg;",
9356
- "&lsqb;",
9357
- "&lsquo;",
9358
- "&lsquor;",
9359
- "&lstrok;",
9360
- "&lt;",
9361
- "&ltcc;",
9362
- "&ltcir;",
9363
- "&ltdot;",
9364
- "&lthree;",
9365
- "&ltimes;",
9366
- "&ltlarr;",
9367
- "&ltquest;",
9368
- "&ltri;",
9369
- "&ltrie;",
9370
- "&ltrif;",
9371
- "&ltrpar;",
9372
- "&lurdshar;",
9373
- "&luruhar;",
9374
- "&lvertneqq;",
9375
- "&lvne;",
9376
- "&macr;",
9377
- "&male;",
9378
- "&malt;",
9379
- "&maltese;",
9380
- "&map;",
9381
- "&mapsto;",
9382
- "&mapstodown;",
9383
- "&mapstoleft;",
9384
- "&mapstoup;",
9385
- "&marker;",
9386
- "&mcomma;",
9387
- "&mcy;",
9388
- "&mdash;",
9389
- "&mddot;",
9390
- "&measuredangle;",
9391
- "&mediumspace;",
9392
- "&mellintrf;",
9393
- "&mfr;",
9394
- "&mho;",
9395
- "&micro;",
9396
- "&mid;",
9397
- "&midast;",
9398
- "&midcir;",
9399
- "&middot;",
9400
- "&minus;",
9401
- "&minusb;",
9402
- "&minusd;",
9403
- "&minusdu;",
9404
- "&minusplus;",
9405
- "&mlcp;",
9406
- "&mldr;",
9407
- "&mnplus;",
9408
- "&models;",
9409
- "&mopf;",
9410
- "&mp;",
9411
- "&mscr;",
9412
- "&mstpos;",
9413
- "&mu;",
9414
- "&multimap;",
9415
- "&mumap;",
9416
- "&nabla;",
9417
- "&nacute;",
9418
- "&nang;",
9419
- "&nap;",
9420
- "&nape;",
9421
- "&napid;",
9422
- "&napos;",
9423
- "&napprox;",
9424
- "&natur;",
9425
- "&natural;",
9426
- "&naturals;",
9427
- "&nbsp;",
9428
- "&nbump;",
9429
- "&nbumpe;",
9430
- "&ncap;",
9431
- "&ncaron;",
9432
- "&ncedil;",
9433
- "&ncong;",
9434
- "&ncongdot;",
9435
- "&ncup;",
9436
- "&ncy;",
9437
- "&ndash;",
9438
- "&ne;",
9439
- "&nearhk;",
9440
- "&nearr;",
9441
- "&nearrow;",
9442
- "&nedot;",
9443
- "&negativemediumspace;",
9444
- "&negativethickspace;",
9445
- "&negativethinspace;",
9446
- "&negativeverythinspace;",
9447
- "&nequiv;",
9448
- "&nesear;",
9449
- "&nesim;",
9450
- "&nestedgreatergreater;",
9451
- "&nestedlessless;",
9452
- "&newline;",
9453
- "&nexist;",
9454
- "&nexists;",
9455
- "&nfr;",
9456
- "&nge;",
9457
- "&ngeq;",
9458
- "&ngeqq;",
9459
- "&ngeqslant;",
9460
- "&nges;",
9461
- "&ngg;",
9462
- "&ngsim;",
9463
- "&ngt;",
9464
- "&ngtr;",
9465
- "&ngtv;",
9466
- "&nharr;",
9467
- "&nhpar;",
9468
- "&ni;",
9469
- "&nis;",
9470
- "&nisd;",
9471
- "&niv;",
9472
- "&njcy;",
9473
- "&nlarr;",
9474
- "&nldr;",
9475
- "&nle;",
9476
- "&nleftarrow;",
9477
- "&nleftrightarrow;",
9478
- "&nleq;",
9479
- "&nleqq;",
9480
- "&nleqslant;",
9481
- "&nles;",
9482
- "&nless;",
9483
- "&nll;",
9484
- "&nlsim;",
9485
- "&nlt;",
9486
- "&nltri;",
9487
- "&nltrie;",
9488
- "&nltv;",
9489
- "&nmid;",
9490
- "&nobreak;",
9491
- "&nonbreakingspace;",
9492
- "&nopf;",
9493
- "&not;",
9494
- "&notcongruent;",
9495
- "&notcupcap;",
9496
- "&notdoubleverticalbar;",
9497
- "&notelement;",
9498
- "&notequal;",
9499
- "&notequaltilde;",
9500
- "&notexists;",
9501
- "&notgreater;",
9502
- "&notgreaterequal;",
9503
- "&notgreaterfullequal;",
9504
- "&notgreatergreater;",
9505
- "&notgreaterless;",
9506
- "&notgreaterslantequal;",
9507
- "&notgreatertilde;",
9508
- "&nothumpdownhump;",
9509
- "&nothumpequal;",
9510
- "&notin;",
9511
- "&notindot;",
9512
- "&notine;",
9513
- "&notinva;",
9514
- "&notinvb;",
9515
- "&notinvc;",
9516
- "&notlefttriangle;",
9517
- "&notlefttrianglebar;",
9518
- "&notlefttriangleequal;",
9519
- "&notless;",
9520
- "&notlessequal;",
9521
- "&notlessgreater;",
9522
- "&notlessless;",
9523
- "&notlessslantequal;",
9524
- "&notlesstilde;",
9525
- "&notnestedgreatergreater;",
9526
- "&notnestedlessless;",
9527
- "&notni;",
9528
- "&notniva;",
9529
- "&notnivb;",
9530
- "&notnivc;",
9531
- "&notprecedes;",
9532
- "&notprecedesequal;",
9533
- "&notprecedesslantequal;",
9534
- "&notreverseelement;",
9535
- "&notrighttriangle;",
9536
- "&notrighttrianglebar;",
9537
- "&notrighttriangleequal;",
9538
- "&notsquaresubset;",
9539
- "&notsquaresubsetequal;",
9540
- "&notsquaresuperset;",
9541
- "&notsquaresupersetequal;",
9542
- "&notsubset;",
9543
- "&notsubsetequal;",
9544
- "&notsucceeds;",
9545
- "&notsucceedsequal;",
9546
- "&notsucceedsslantequal;",
9547
- "&notsucceedstilde;",
9548
- "&notsuperset;",
9549
- "&notsupersetequal;",
9550
- "&nottilde;",
9551
- "&nottildeequal;",
9552
- "&nottildefullequal;",
9553
- "&nottildetilde;",
9554
- "&notverticalbar;",
9555
- "&npar;",
9556
- "&nparallel;",
9557
- "&nparsl;",
9558
- "&npart;",
9559
- "&npolint;",
9560
- "&npr;",
9561
- "&nprcue;",
9562
- "&npre;",
9563
- "&nprec;",
9564
- "&npreceq;",
9565
- "&nrarr;",
9566
- "&nrarrc;",
9567
- "&nrarrw;",
9568
- "&nrightarrow;",
9569
- "&nrtri;",
9570
- "&nrtrie;",
9571
- "&nsc;",
9572
- "&nsccue;",
9573
- "&nsce;",
9574
- "&nscr;",
9575
- "&nshortmid;",
9576
- "&nshortparallel;",
9577
- "&nsim;",
9578
- "&nsime;",
9579
- "&nsimeq;",
9580
- "&nsmid;",
9581
- "&nspar;",
9582
- "&nsqsube;",
9583
- "&nsqsupe;",
9584
- "&nsub;",
9585
- "&nsube;",
9586
- "&nsubset;",
9587
- "&nsubseteq;",
9588
- "&nsubseteqq;",
9589
- "&nsucc;",
9590
- "&nsucceq;",
9591
- "&nsup;",
9592
- "&nsupe;",
9593
- "&nsupset;",
9594
- "&nsupseteq;",
9595
- "&nsupseteqq;",
9596
- "&ntgl;",
9597
- "&ntilde;",
9598
- "&ntlg;",
9599
- "&ntriangleleft;",
9600
- "&ntrianglelefteq;",
9601
- "&ntriangleright;",
9602
- "&ntrianglerighteq;",
9603
- "&nu;",
9604
- "&num;",
9605
- "&numero;",
9606
- "&numsp;",
9607
- "&nvap;",
9608
- "&nvdash;",
9609
- "&nvge;",
9610
- "&nvgt;",
9611
- "&nvharr;",
9612
- "&nvinfin;",
9613
- "&nvlarr;",
9614
- "&nvle;",
9615
- "&nvlt;",
9616
- "&nvltrie;",
9617
- "&nvrarr;",
9618
- "&nvrtrie;",
9619
- "&nvsim;",
9620
- "&nwarhk;",
9621
- "&nwarr;",
9622
- "&nwarrow;",
9623
- "&nwnear;",
9624
- "&oacute;",
9625
- "&oast;",
9626
- "&ocir;",
9627
- "&ocirc;",
9628
- "&ocy;",
9629
- "&odash;",
9630
- "&odblac;",
9631
- "&odiv;",
9632
- "&odot;",
9633
- "&odsold;",
9634
- "&oelig;",
9635
- "&ofcir;",
9636
- "&ofr;",
9637
- "&ogon;",
9638
- "&ograve;",
9639
- "&ogt;",
9640
- "&ohbar;",
9641
- "&ohm;",
9642
- "&oint;",
9643
- "&olarr;",
9644
- "&olcir;",
9645
- "&olcross;",
9646
- "&oline;",
9647
- "&olt;",
9648
- "&omacr;",
9649
- "&omega;",
9650
- "&omicron;",
9651
- "&omid;",
9652
- "&ominus;",
9653
- "&oopf;",
9654
- "&opar;",
9655
- "&opencurlydoublequote;",
9656
- "&opencurlyquote;",
9657
- "&operp;",
9658
- "&oplus;",
9659
- "&or;",
9660
- "&orarr;",
9661
- "&ord;",
9662
- "&order;",
9663
- "&orderof;",
9664
- "&ordf;",
9665
- "&ordm;",
9666
- "&origof;",
9667
- "&oror;",
9668
- "&orslope;",
9669
- "&orv;",
9670
- "&os;",
9671
- "&oscr;",
9672
- "&oslash;",
9673
- "&osol;",
9674
- "&otilde;",
9675
- "&otimes;",
9676
- "&otimesas;",
9677
- "&ouml;",
9678
- "&ovbar;",
9679
- "&overbar;",
9680
- "&overbrace;",
9681
- "&overbracket;",
9682
- "&overparenthesis;",
9683
- "&par;",
9684
- "&para;",
9685
- "&parallel;",
9686
- "&parsim;",
9687
- "&parsl;",
9688
- "&part;",
9689
- "&partiald;",
9690
- "&pcy;",
9691
- "&percnt;",
9692
- "&period;",
9693
- "&permil;",
9694
- "&perp;",
9695
- "&pertenk;",
9696
- "&pfr;",
9697
- "&phi;",
9698
- "&phiv;",
9699
- "&phmmat;",
9700
- "&phone;",
9701
- "&pi;",
9702
- "&pitchfork;",
9703
- "&piv;",
9704
- "&planck;",
9705
- "&planckh;",
9706
- "&plankv;",
9707
- "&plus;",
9708
- "&plusacir;",
9709
- "&plusb;",
9710
- "&pluscir;",
9711
- "&plusdo;",
9712
- "&plusdu;",
9713
- "&pluse;",
9714
- "&plusminus;",
9715
- "&plusmn;",
9716
- "&plussim;",
9717
- "&plustwo;",
9718
- "&pm;",
9719
- "&poincareplane;",
9720
- "&pointint;",
9721
- "&popf;",
9722
- "&pound;",
9723
- "&pr;",
9724
- "&prap;",
9725
- "&prcue;",
9726
- "&pre;",
9727
- "&prec;",
9728
- "&precapprox;",
9729
- "&preccurlyeq;",
9730
- "&precedes;",
9731
- "&precedesequal;",
9732
- "&precedesslantequal;",
9733
- "&precedestilde;",
9734
- "&preceq;",
9735
- "&precnapprox;",
9736
- "&precneqq;",
9737
- "&precnsim;",
9738
- "&precsim;",
9739
- "&prime;",
9740
- "&primes;",
9741
- "&prnap;",
9742
- "&prne;",
9743
- "&prnsim;",
9744
- "&prod;",
9745
- "&product;",
9746
- "&profalar;",
9747
- "&profline;",
9748
- "&profsurf;",
9749
- "&prop;",
9750
- "&proportion;",
9751
- "&proportional;",
9752
- "&propto;",
9753
- "&prsim;",
9754
- "&prurel;",
9755
- "&pscr;",
9756
- "&psi;",
9757
- "&puncsp;",
9758
- "&qfr;",
9759
- "&qint;",
9760
- "&qopf;",
9761
- "&qprime;",
9762
- "&qscr;",
9763
- "&quaternions;",
9764
- "&quatint;",
9765
- "&quest;",
9766
- "&questeq;",
9767
- "&quot;",
9768
- "&raarr;",
9769
- "&race;",
9770
- "&racute;",
9771
- "&radic;",
9772
- "&raemptyv;",
9773
- "&rang;",
9774
- "&rangd;",
9775
- "&range;",
9776
- "&rangle;",
9777
- "&raquo;",
9778
- "&rarr;",
9779
- "&rarrap;",
9780
- "&rarrb;",
9781
- "&rarrbfs;",
9782
- "&rarrc;",
9783
- "&rarrfs;",
9784
- "&rarrhk;",
9785
- "&rarrlp;",
9786
- "&rarrpl;",
9787
- "&rarrsim;",
9788
- "&rarrtl;",
9789
- "&rarrw;",
9790
- "&ratail;",
9791
- "&ratio;",
9792
- "&rationals;",
9793
- "&rbarr;",
9794
- "&rbbrk;",
9795
- "&rbrace;",
9796
- "&rbrack;",
9797
- "&rbrke;",
9798
- "&rbrksld;",
9799
- "&rbrkslu;",
9800
- "&rcaron;",
9801
- "&rcedil;",
9802
- "&rceil;",
9803
- "&rcub;",
9804
- "&rcy;",
9805
- "&rdca;",
9806
- "&rdldhar;",
9807
- "&rdquo;",
9808
- "&rdquor;",
9809
- "&rdsh;",
9810
- "&re;",
9811
- "&real;",
9812
- "&realine;",
9813
- "&realpart;",
9814
- "&reals;",
9815
- "&rect;",
9816
- "&reg;",
9817
- "&reverseelement;",
9818
- "&reverseequilibrium;",
9819
- "&reverseupequilibrium;",
9820
- "&rfisht;",
9821
- "&rfloor;",
9822
- "&rfr;",
9823
- "&rhar;",
9824
- "&rhard;",
9825
- "&rharu;",
9826
- "&rharul;",
9827
- "&rho;",
9828
- "&rhov;",
9829
- "&rightanglebracket;",
9830
- "&rightarrow;",
9831
- "&rightarrowbar;",
9832
- "&rightarrowleftarrow;",
9833
- "&rightarrowtail;",
9834
- "&rightceiling;",
9835
- "&rightdoublebracket;",
9836
- "&rightdownteevector;",
9837
- "&rightdownvector;",
9838
- "&rightdownvectorbar;",
9839
- "&rightfloor;",
9840
- "&rightharpoondown;",
9841
- "&rightharpoonup;",
9842
- "&rightleftarrows;",
9843
- "&rightleftharpoons;",
9844
- "&rightrightarrows;",
9845
- "&rightsquigarrow;",
9846
- "&righttee;",
9847
- "&rightteearrow;",
9848
- "&rightteevector;",
9849
- "&rightthreetimes;",
9850
- "&righttriangle;",
9851
- "&righttrianglebar;",
9852
- "&righttriangleequal;",
9853
- "&rightupdownvector;",
9854
- "&rightupteevector;",
9855
- "&rightupvector;",
9856
- "&rightupvectorbar;",
9857
- "&rightvector;",
9858
- "&rightvectorbar;",
9859
- "&ring;",
9860
- "&risingdotseq;",
9861
- "&rlarr;",
9862
- "&rlhar;",
9863
- "&rlm;",
9864
- "&rmoust;",
9865
- "&rmoustache;",
9866
- "&rnmid;",
9867
- "&roang;",
9868
- "&roarr;",
9869
- "&robrk;",
9870
- "&ropar;",
9871
- "&ropf;",
9872
- "&roplus;",
9873
- "&rotimes;",
9874
- "&roundimplies;",
9875
- "&rpar;",
9876
- "&rpargt;",
9877
- "&rppolint;",
9878
- "&rrarr;",
9879
- "&rrightarrow;",
9880
- "&rsaquo;",
9881
- "&rscr;",
9882
- "&rsh;",
9883
- "&rsqb;",
9884
- "&rsquo;",
9885
- "&rsquor;",
9886
- "&rthree;",
9887
- "&rtimes;",
9888
- "&rtri;",
9889
- "&rtrie;",
9890
- "&rtrif;",
9891
- "&rtriltri;",
9892
- "&ruledelayed;",
9893
- "&ruluhar;",
9894
- "&rx;",
9895
- "&sacute;",
9896
- "&sbquo;",
9897
- "&sc;",
9898
- "&scap;",
9899
- "&scaron;",
9900
- "&sccue;",
9901
- "&sce;",
9902
- "&scedil;",
9903
- "&scirc;",
9904
- "&scnap;",
9905
- "&scne;",
9906
- "&scnsim;",
9907
- "&scpolint;",
9908
- "&scsim;",
9909
- "&scy;",
9910
- "&sdot;",
9911
- "&sdotb;",
9912
- "&sdote;",
9913
- "&searhk;",
9914
- "&searr;",
9915
- "&searrow;",
9916
- "&sect;",
9917
- "&semi;",
9918
- "&seswar;",
9919
- "&setminus;",
9920
- "&setmn;",
9921
- "&sext;",
9922
- "&sfr;",
9923
- "&sfrown;",
9924
- "&sharp;",
9925
- "&shchcy;",
9926
- "&shcy;",
9927
- "&shortdownarrow;",
9928
- "&shortleftarrow;",
9929
- "&shortmid;",
9930
- "&shortparallel;",
9931
- "&shortrightarrow;",
9932
- "&shortuparrow;",
9933
- "&shy;",
9934
- "&sigma;",
9935
- "&sigmaf;",
9936
- "&sigmav;",
9937
- "&sim;",
9938
- "&simdot;",
9939
- "&sime;",
9940
- "&simeq;",
9941
- "&simg;",
9942
- "&simge;",
9943
- "&siml;",
9944
- "&simle;",
9945
- "&simne;",
9946
- "&simplus;",
9947
- "&simrarr;",
9948
- "&slarr;",
9949
- "&smallcircle;",
9950
- "&smallsetminus;",
9951
- "&smashp;",
9952
- "&smeparsl;",
9953
- "&smid;",
9954
- "&smile;",
9955
- "&smt;",
9956
- "&smte;",
9957
- "&smtes;",
9958
- "&softcy;",
9959
- "&sol;",
9960
- "&solb;",
9961
- "&solbar;",
9962
- "&sopf;",
9963
- "&spades;",
9964
- "&spadesuit;",
9965
- "&spar;",
9966
- "&sqcap;",
9967
- "&sqcaps;",
9968
- "&sqcup;",
9969
- "&sqcups;",
9970
- "&sqrt;",
9971
- "&sqsub;",
9972
- "&sqsube;",
9973
- "&sqsubset;",
9974
- "&sqsubseteq;",
9975
- "&sqsup;",
9976
- "&sqsupe;",
9977
- "&sqsupset;",
9978
- "&sqsupseteq;",
9979
- "&squ;",
9980
- "&square;",
9981
- "&squareintersection;",
9982
- "&squaresubset;",
9983
- "&squaresubsetequal;",
9984
- "&squaresuperset;",
9985
- "&squaresupersetequal;",
9986
- "&squareunion;",
9987
- "&squarf;",
9988
- "&squf;",
9989
- "&srarr;",
9990
- "&sscr;",
9991
- "&ssetmn;",
9992
- "&ssmile;",
9993
- "&sstarf;",
9994
- "&star;",
9995
- "&starf;",
9996
- "&straightepsilon;",
9997
- "&straightphi;",
9998
- "&strns;",
9999
- "&sub;",
10000
- "&subdot;",
10001
- "&sube;",
10002
- "&subedot;",
10003
- "&submult;",
10004
- "&subne;",
10005
- "&subplus;",
10006
- "&subrarr;",
10007
- "&subset;",
10008
- "&subseteq;",
10009
- "&subseteqq;",
10010
- "&subsetequal;",
10011
- "&subsetneq;",
10012
- "&subsetneqq;",
10013
- "&subsim;",
10014
- "&subsub;",
10015
- "&subsup;",
10016
- "&succ;",
10017
- "&succapprox;",
10018
- "&succcurlyeq;",
10019
- "&succeeds;",
10020
- "&succeedsequal;",
10021
- "&succeedsslantequal;",
10022
- "&succeedstilde;",
10023
- "&succeq;",
10024
- "&succnapprox;",
10025
- "&succneqq;",
10026
- "&succnsim;",
10027
- "&succsim;",
10028
- "&suchthat;",
10029
- "&sum;",
10030
- "&sung;",
10031
- "&sup1;",
10032
- "&sup2;",
10033
- "&sup3;",
10034
- "&sup;",
10035
- "&supdot;",
10036
- "&supdsub;",
10037
- "&supe;",
10038
- "&supedot;",
10039
- "&superset;",
10040
- "&supersetequal;",
10041
- "&suphsol;",
10042
- "&suphsub;",
10043
- "&suplarr;",
10044
- "&supmult;",
10045
- "&supne;",
10046
- "&supplus;",
10047
- "&supset;",
10048
- "&supseteq;",
10049
- "&supseteqq;",
10050
- "&supsetneq;",
10051
- "&supsetneqq;",
10052
- "&supsim;",
10053
- "&supsub;",
10054
- "&supsup;",
10055
- "&swarhk;",
10056
- "&swarr;",
10057
- "&swarrow;",
10058
- "&swnwar;",
10059
- "&szlig;",
10060
- "&tab;",
10061
- "&target;",
10062
- "&tau;",
10063
- "&tbrk;",
10064
- "&tcaron;",
10065
- "&tcedil;",
10066
- "&tcy;",
10067
- "&tdot;",
10068
- "&telrec;",
10069
- "&tfr;",
10070
- "&there4;",
10071
- "&therefore;",
10072
- "&theta;",
10073
- "&thetasym;",
10074
- "&thetav;",
10075
- "&thickapprox;",
10076
- "&thicksim;",
10077
- "&thickspace;",
10078
- "&thinsp;",
10079
- "&thinspace;",
10080
- "&thkap;",
10081
- "&thksim;",
10082
- "&thorn;",
10083
- "&tilde;",
10084
- "&tildeequal;",
10085
- "&tildefullequal;",
10086
- "&tildetilde;",
10087
- "&times;",
10088
- "&timesb;",
10089
- "&timesbar;",
10090
- "&timesd;",
10091
- "&tint;",
10092
- "&toea;",
10093
- "&top;",
10094
- "&topbot;",
10095
- "&topcir;",
10096
- "&topf;",
10097
- "&topfork;",
10098
- "&tosa;",
10099
- "&tprime;",
10100
- "&trade;",
10101
- "&triangle;",
10102
- "&triangledown;",
10103
- "&triangleleft;",
10104
- "&trianglelefteq;",
10105
- "&triangleq;",
10106
- "&triangleright;",
10107
- "&trianglerighteq;",
10108
- "&tridot;",
10109
- "&trie;",
10110
- "&triminus;",
10111
- "&tripledot;",
10112
- "&triplus;",
10113
- "&trisb;",
10114
- "&tritime;",
10115
- "&trpezium;",
10116
- "&tscr;",
10117
- "&tscy;",
10118
- "&tshcy;",
10119
- "&tstrok;",
10120
- "&twixt;",
10121
- "&twoheadleftarrow;",
10122
- "&twoheadrightarrow;",
10123
- "&uacute;",
10124
- "&uarr;",
10125
- "&uarrocir;",
10126
- "&ubrcy;",
10127
- "&ubreve;",
10128
- "&ucirc;",
10129
- "&ucy;",
10130
- "&udarr;",
10131
- "&udblac;",
10132
- "&udhar;",
10133
- "&ufisht;",
10134
- "&ufr;",
10135
- "&ugrave;",
10136
- "&uhar;",
10137
- "&uharl;",
10138
- "&uharr;",
10139
- "&uhblk;",
10140
- "&ulcorn;",
10141
- "&ulcorner;",
10142
- "&ulcrop;",
10143
- "&ultri;",
10144
- "&umacr;",
10145
- "&uml;",
10146
- "&underbar;",
10147
- "&underbrace;",
10148
- "&underbracket;",
10149
- "&underparenthesis;",
10150
- "&union;",
10151
- "&unionplus;",
10152
- "&uogon;",
10153
- "&uopf;",
10154
- "&uparrow;",
10155
- "&uparrowbar;",
10156
- "&uparrowdownarrow;",
10157
- "&updownarrow;",
10158
- "&upequilibrium;",
10159
- "&upharpoonleft;",
10160
- "&upharpoonright;",
10161
- "&uplus;",
10162
- "&upperleftarrow;",
10163
- "&upperrightarrow;",
10164
- "&upsi;",
10165
- "&upsih;",
10166
- "&upsilon;",
10167
- "&uptee;",
10168
- "&upteearrow;",
10169
- "&upuparrows;",
10170
- "&urcorn;",
10171
- "&urcorner;",
10172
- "&urcrop;",
10173
- "&uring;",
10174
- "&urtri;",
10175
- "&uscr;",
10176
- "&utdot;",
10177
- "&utilde;",
10178
- "&utri;",
10179
- "&utrif;",
10180
- "&uuarr;",
10181
- "&uuml;",
10182
- "&uwangle;",
10183
- "&vangrt;",
10184
- "&varepsilon;",
10185
- "&varkappa;",
10186
- "&varnothing;",
10187
- "&varphi;",
10188
- "&varpi;",
10189
- "&varpropto;",
10190
- "&varr;",
10191
- "&varrho;",
10192
- "&varsigma;",
10193
- "&varsubsetneq;",
10194
- "&varsubsetneqq;",
10195
- "&varsupsetneq;",
10196
- "&varsupsetneqq;",
10197
- "&vartheta;",
10198
- "&vartriangleleft;",
10199
- "&vartriangleright;",
10200
- "&vbar;",
10201
- "&vbarv;",
10202
- "&vcy;",
10203
- "&vdash;",
10204
- "&vdashl;",
10205
- "&vee;",
10206
- "&veebar;",
10207
- "&veeeq;",
10208
- "&vellip;",
10209
- "&verbar;",
10210
- "&vert;",
10211
- "&verticalbar;",
10212
- "&verticalline;",
10213
- "&verticalseparator;",
10214
- "&verticaltilde;",
10215
- "&verythinspace;",
10216
- "&vfr;",
10217
- "&vltri;",
10218
- "&vnsub;",
10219
- "&vnsup;",
10220
- "&vopf;",
10221
- "&vprop;",
10222
- "&vrtri;",
10223
- "&vscr;",
10224
- "&vsubne;",
10225
- "&vsupne;",
10226
- "&vvdash;",
10227
- "&vzigzag;",
10228
- "&wcirc;",
10229
- "&wedbar;",
10230
- "&wedge;",
10231
- "&wedgeq;",
10232
- "&weierp;",
10233
- "&wfr;",
10234
- "&wopf;",
10235
- "&wp;",
10236
- "&wr;",
10237
- "&wreath;",
10238
- "&wscr;",
10239
- "&xcap;",
10240
- "&xcirc;",
10241
- "&xcup;",
10242
- "&xdtri;",
10243
- "&xfr;",
10244
- "&xharr;",
10245
- "&xi;",
10246
- "&xlarr;",
10247
- "&xmap;",
10248
- "&xnis;",
10249
- "&xodot;",
10250
- "&xopf;",
10251
- "&xoplus;",
10252
- "&xotime;",
10253
- "&xrarr;",
10254
- "&xscr;",
10255
- "&xsqcup;",
10256
- "&xuplus;",
10257
- "&xutri;",
10258
- "&xvee;",
10259
- "&xwedge;",
10260
- "&yacute;",
10261
- "&yacy;",
10262
- "&ycirc;",
10263
- "&ycy;",
10264
- "&yen;",
10265
- "&yfr;",
10266
- "&yicy;",
10267
- "&yopf;",
10268
- "&yscr;",
10269
- "&yucy;",
10270
- "&yuml;",
10271
- "&zacute;",
10272
- "&zcaron;",
10273
- "&zcy;",
10274
- "&zdot;",
10275
- "&zeetrf;",
10276
- "&zerowidthspace;",
10277
- "&zeta;",
10278
- "&zfr;",
10279
- "&zhcy;",
10280
- "&zigrarr;",
10281
- "&zopf;",
10282
- "&zscr;",
10283
- "&zwj;",
10284
- "&zwnj;"
10285
- ];
10286
-
10287
- const regexp$1 = /&([a-z0-9]+|#x?[0-9a-f]+);/gi;
8130
+ const defaults$6 = {
8131
+ ignoreCase: false,
8132
+ requireSemicolon: true,
8133
+ };
8134
+ const regexp$1 = /&(?:[a-z0-9]+|#x?[0-9a-f]+)(;|[^a-z0-9]|$)/gi;
8135
+ const lowercaseEntities = elements.entities.map((it) => it.toLowerCase());
8136
+ function isNumerical(entity) {
8137
+ return entity.startsWith("&#");
8138
+ }
8139
+ function getLocation(location, entity, match) {
8140
+ var _a;
8141
+ /* istanbul ignore next: never happens in practive */
8142
+ const index = (_a = match.index) !== null && _a !== void 0 ? _a : 0;
8143
+ return sliceLocation(location, index, index + entity.length);
8144
+ }
8145
+ function getDescription(context, options) {
8146
+ const url = "https://html.spec.whatwg.org/multipage/named-characters.html";
8147
+ let message;
8148
+ if (context) {
8149
+ if (context.terminated) {
8150
+ message = `Unrecognized character reference \`${context.entity}\`.`;
8151
+ }
8152
+ else {
8153
+ message = `Character reference \`${context.entity}\` must be terminated by a semicolon.`;
8154
+ }
8155
+ }
8156
+ else {
8157
+ message = `Unrecognized character reference.`;
8158
+ }
8159
+ return [
8160
+ message,
8161
+ `HTML5 defines a set of [valid character references](${url}) but this is not a valid one.`,
8162
+ "",
8163
+ "Ensure that:",
8164
+ "",
8165
+ "1. The character is one of the listed names.",
8166
+ ...(options.ignoreCase ? [] : ["1. The case is correct (names are case sensitive)."]),
8167
+ ...(options.requireSemicolon ? ["1. The name is terminated with a `;`."] : []),
8168
+ ].join("\n");
8169
+ }
10288
8170
  class UnknownCharReference extends Rule {
8171
+ constructor(options) {
8172
+ super({ ...defaults$6, ...options });
8173
+ }
8174
+ static schema() {
8175
+ return {
8176
+ ignoreCase: {
8177
+ type: "boolean",
8178
+ },
8179
+ requireSemicolon: {
8180
+ type: "boolean",
8181
+ },
8182
+ };
8183
+ }
10289
8184
  documentation(context) {
10290
8185
  return {
10291
- description: `HTML defines a set of valid character references but ${context || "this"} is not a valid one.`,
10292
- url: ruleDocumentationUrl("@/rules/unrecognized-char-ref.ts"),
8186
+ description: getDescription(context, this.options),
8187
+ url: "https://html-validate.org/rules/unrecognized-char-ref.html",
10293
8188
  };
10294
8189
  }
10295
8190
  setup() {
@@ -10300,7 +8195,9 @@ class UnknownCharReference extends Rule {
10300
8195
  if (child.nodeType !== NodeType.TEXT_NODE) {
10301
8196
  continue;
10302
8197
  }
10303
- this.findCharacterReferences(child.textContent, child.location);
8198
+ this.findCharacterReferences(node, child.textContent, child.location, {
8199
+ isAttribute: false,
8200
+ });
10304
8201
  }
10305
8202
  });
10306
8203
  this.on("attr", (event) => {
@@ -10308,25 +8205,72 @@ class UnknownCharReference extends Rule {
10308
8205
  if (!event.value) {
10309
8206
  return;
10310
8207
  }
10311
- this.findCharacterReferences(event.value.toString(), event.valueLocation);
8208
+ this.findCharacterReferences(event.target, event.value.toString(), event.valueLocation, {
8209
+ isAttribute: true,
8210
+ });
10312
8211
  });
10313
8212
  }
10314
- findCharacterReferences(text, location) {
8213
+ get entities() {
8214
+ if (this.options.ignoreCase) {
8215
+ return lowercaseEntities;
8216
+ }
8217
+ else {
8218
+ return elements.entities;
8219
+ }
8220
+ }
8221
+ /* eslint-disable-next-line complexity */
8222
+ findCharacterReferences(node, text, location, { isAttribute }) {
8223
+ const { requireSemicolon } = this.options;
8224
+ const isQuerystring = isAttribute && text.includes("?");
8225
+ for (const { match, entity, raw, terminated } of this.getMatches(text)) {
8226
+ /* assume numeric entities are valid for now */
8227
+ if (isNumerical(entity)) {
8228
+ continue;
8229
+ }
8230
+ /* special case: when attributes use query parameters we skip checking
8231
+ * unterminated attributes */
8232
+ if (isQuerystring && !terminated) {
8233
+ continue;
8234
+ }
8235
+ const found = this.entities.includes(entity);
8236
+ /* ignore if this is a known character reference name */
8237
+ if (found && (terminated || !requireSemicolon)) {
8238
+ continue;
8239
+ }
8240
+ if (found && !terminated) {
8241
+ const entityLocation = getLocation(location, entity, match);
8242
+ const message = `Character reference "{{ entity }}" must be terminated by a semicolon`;
8243
+ const context = {
8244
+ entity: raw,
8245
+ terminated: false,
8246
+ };
8247
+ this.report(node, message, entityLocation, context);
8248
+ continue;
8249
+ }
8250
+ const entityLocation = getLocation(location, entity, match);
8251
+ const message = `Unrecognized character reference "{{ entity }}"`;
8252
+ const context = {
8253
+ entity: raw,
8254
+ terminated: true,
8255
+ };
8256
+ this.report(node, message, entityLocation, context);
8257
+ }
8258
+ }
8259
+ *getMatches(text) {
10315
8260
  let match;
10316
8261
  do {
10317
8262
  match = regexp$1.exec(text);
10318
8263
  if (match) {
10319
- const entity = match[0];
10320
- /* assume numeric entities are valid for now */
10321
- if (entity.startsWith("&#")) {
10322
- continue;
8264
+ const terminator = match[1]; // === ";" ? match[1] : "";
8265
+ const terminated = terminator === ";";
8266
+ const needSlice = terminator !== ";" && terminator.length > 0;
8267
+ const entity = needSlice ? match[0].slice(0, -1) : match[0];
8268
+ if (this.options.ignoreCase) {
8269
+ yield { match, entity: entity.toLowerCase(), raw: entity, terminated };
10323
8270
  }
10324
- /* ignore if this is a known character reference name */
10325
- if (entities$1.includes(entity)) {
10326
- continue;
8271
+ else {
8272
+ yield { match, entity, raw: entity, terminated };
10327
8273
  }
10328
- const entityLocation = sliceLocation(location, match.index, match.index + entity.length);
10329
- this.report(null, `Unrecognized character reference "${entity}"`, entityLocation, entity);
10330
8274
  }
10331
8275
  } while (match);
10332
8276
  }
@@ -10374,7 +8318,7 @@ class ValidID extends Rule {
10374
8318
  " - ID must not contain any whitespace characters",
10375
8319
  ...relaxedDescription,
10376
8320
  ].join("\n"),
10377
- url: ruleDocumentationUrl("@/rules/valid-id.ts"),
8321
+ url: "https://html-validate.org/rules/valid-id.html",
10378
8322
  };
10379
8323
  }
10380
8324
  setup() {
@@ -10449,7 +8393,7 @@ class Void extends Rule {
10449
8393
  documentation() {
10450
8394
  return {
10451
8395
  description: "HTML void elements cannot have any content and must not have an end tag.",
10452
- url: ruleDocumentationUrl("@/rules/void.ts"),
8396
+ url: "https://html-validate.org/rules/void.html",
10453
8397
  };
10454
8398
  }
10455
8399
  setup() {
@@ -10505,7 +8449,7 @@ class VoidContent extends Rule {
10505
8449
  documentation(tagName) {
10506
8450
  const doc = {
10507
8451
  description: "HTML void elements cannot have any content and must not have content or end tag.",
10508
- url: ruleDocumentationUrl("@/rules/void-content.ts"),
8452
+ url: "https://html-validate.org/rules/void-content.html",
10509
8453
  };
10510
8454
  if (tagName) {
10511
8455
  doc.description = `<${tagName}> is a void element and must not have content or end tag.`;
@@ -10552,7 +8496,7 @@ class VoidStyle extends Rule {
10552
8496
  documentation(context) {
10553
8497
  const doc = {
10554
8498
  description: "The current configuration requires a specific style for ending void elements.",
10555
- url: ruleDocumentationUrl("@/rules/void-style.ts"),
8499
+ url: "https://html-validate.org/rules/void-style.html",
10556
8500
  };
10557
8501
  if (context) {
10558
8502
  const [desc, end] = styleDescription(context.style);
@@ -10622,7 +8566,7 @@ class H30 extends Rule {
10622
8566
  documentation() {
10623
8567
  return {
10624
8568
  description: "WCAG 2.1 requires each `<a>` anchor link to have a text describing the purpose of the link using either plain text or an `<img>` with the `alt` attribute set.",
10625
- url: ruleDocumentationUrl("@/rules/wcag/h30.ts"),
8569
+ url: "https://html-validate.org/rules/wcag/h30.html",
10626
8570
  };
10627
8571
  }
10628
8572
  setup() {
@@ -10630,22 +8574,22 @@ class H30 extends Rule {
10630
8574
  const links = event.document.getElementsByTagName("a");
10631
8575
  for (const link of links) {
10632
8576
  /* ignore links with aria-hidden="true" */
10633
- if (!inAccessibilityTree(link)) {
8577
+ if (!rulesHelper.inAccessibilityTree(link)) {
10634
8578
  continue;
10635
8579
  }
10636
8580
  /* check if text content is present (or dynamic) */
10637
- const textClassification = classifyNodeText(link);
10638
- if (textClassification !== exports.TextClassification.EMPTY_TEXT) {
8581
+ const textClassification = rulesHelper.classifyNodeText(link);
8582
+ if (textClassification !== rulesHelper.TextClassification.EMPTY_TEXT) {
10639
8583
  continue;
10640
8584
  }
10641
8585
  /* check if image with alt-text is present */
10642
8586
  const images = link.querySelectorAll("img");
10643
- if (images.some((image) => hasAltText(image))) {
8587
+ if (images.some((image) => rulesHelper.hasAltText(image))) {
10644
8588
  continue;
10645
8589
  }
10646
8590
  /* check if aria-label is present on either the <a> element or a descendant */
10647
8591
  const labels = link.querySelectorAll("[aria-label]");
10648
- if (hasAriaLabel(link) || labels.some((cur) => hasAriaLabel(cur))) {
8592
+ if (rulesHelper.hasAriaLabel(link) || labels.some((cur) => rulesHelper.hasAriaLabel(cur))) {
10649
8593
  continue;
10650
8594
  }
10651
8595
  this.report(link, "Anchor link must have a text describing its purpose");
@@ -10658,7 +8602,7 @@ class H32 extends Rule {
10658
8602
  documentation() {
10659
8603
  return {
10660
8604
  description: "WCAG 2.1 requires each `<form>` element to have at least one submit button.",
10661
- url: ruleDocumentationUrl("@/rules/wcag/h32.ts"),
8605
+ url: "https://html-validate.org/rules/wcag/h32.html",
10662
8606
  };
10663
8607
  }
10664
8608
  setup() {
@@ -10715,7 +8659,7 @@ class H36 extends Rule {
10715
8659
  documentation() {
10716
8660
  return {
10717
8661
  description: 'WCAG 2.1 requires all images used as submit buttons to have a textual description using the alt attribute. The alt text cannot be empty (`alt=""`).',
10718
- url: ruleDocumentationUrl("@/rules/wcag/h36.ts"),
8662
+ url: "https://html-validate.org/rules/wcag/h36.html",
10719
8663
  };
10720
8664
  }
10721
8665
  setup() {
@@ -10728,7 +8672,7 @@ class H36 extends Rule {
10728
8672
  if (node.getAttributeValue("type") !== "image") {
10729
8673
  return;
10730
8674
  }
10731
- if (!hasAltText(node)) {
8675
+ if (!rulesHelper.hasAltText(node)) {
10732
8676
  this.report(node, "image used as submit button must have alt text");
10733
8677
  }
10734
8678
  });
@@ -10785,7 +8729,7 @@ class H37 extends Rule {
10785
8729
  documentation() {
10786
8730
  return {
10787
8731
  description: "Both HTML5 and WCAG 2.0 requires images to have a alternative text for each image.",
10788
- url: ruleDocumentationUrl("@/rules/wcag/h37.ts"),
8732
+ url: "https://html-validate.org/rules/wcag/h37.html",
10789
8733
  };
10790
8734
  }
10791
8735
  setup() {
@@ -10796,7 +8740,7 @@ class H37 extends Rule {
10796
8740
  return;
10797
8741
  }
10798
8742
  /* ignore images with aria-hidden="true" or role="presentation" */
10799
- if (!inAccessibilityTree(node)) {
8743
+ if (!rulesHelper.inAccessibilityTree(node)) {
10800
8744
  return;
10801
8745
  }
10802
8746
  /* validate plain alt-attribute */
@@ -10826,7 +8770,7 @@ class H67 extends Rule {
10826
8770
  documentation() {
10827
8771
  return {
10828
8772
  description: "A decorative image cannot have a title attribute. Either remove `title` or add a descriptive `alt` text.",
10829
- url: ruleDocumentationUrl("@/rules/wcag/h67.ts"),
8773
+ url: "https://html-validate.org/rules/wcag/h67.html",
10830
8774
  };
10831
8775
  }
10832
8776
  setup() {
@@ -10855,7 +8799,7 @@ class H71 extends Rule {
10855
8799
  documentation() {
10856
8800
  return {
10857
8801
  description: "H71: Providing a description for groups of form controls using fieldset and legend elements",
10858
- url: ruleDocumentationUrl("@/rules/wcag/h71.ts"),
8802
+ url: "https://html-validate.org/rules/wcag/h71.html",
10859
8803
  };
10860
8804
  }
10861
8805
  setup() {
@@ -10927,6 +8871,7 @@ const bundledRules = {
10927
8871
  "input-attributes": InputAttributes,
10928
8872
  "input-missing-label": InputMissingLabel,
10929
8873
  "long-title": LongTitle,
8874
+ "map-dup-name": MapDupName,
10930
8875
  "meta-refresh": MetaRefresh,
10931
8876
  "missing-doctype": MissingDoctype,
10932
8877
  "multiple-labeled-controls": MultipleLabeledControls,
@@ -11036,6 +8981,7 @@ const config$1 = {
11036
8981
  "empty-title": "error",
11037
8982
  "input-attributes": "error",
11038
8983
  "long-title": "error",
8984
+ "map-dup-name": "error",
11039
8985
  "meta-refresh": "error",
11040
8986
  "multiple-labeled-controls": "error",
11041
8987
  "no-autoplay": ["error", { include: ["audio", "video"] }],
@@ -11094,6 +9040,7 @@ const config = {
11094
9040
  "element-required-ancestor": "error",
11095
9041
  "element-required-attributes": "error",
11096
9042
  "element-required-content": "error",
9043
+ "map-dup-name": "error",
11097
9044
  "multiple-labeled-controls": "error",
11098
9045
  "no-deprecated-attr": "error",
11099
9046
  "no-dup-attr": "error",
@@ -11437,15 +9384,14 @@ class Config {
11437
9384
  metaTable.loadFromObject(entry);
11438
9385
  continue;
11439
9386
  }
11440
- let filename;
11441
9387
  /* try searching builtin metadata */
11442
- filename = path__default.default.join(projectRoot, "elements", `${entry}.js`);
11443
- if (fs__default.default.existsSync(filename)) {
11444
- metaTable.loadFromFile(filename);
9388
+ const bundled = elements.bundledElements[entry];
9389
+ if (bundled) {
9390
+ metaTable.loadFromObject(bundled);
11445
9391
  continue;
11446
9392
  }
11447
9393
  /* try as regular file */
11448
- filename = entry.replace("<rootDir>", this.rootDir);
9394
+ const filename = entry.replace("<rootDir>", this.rootDir);
11449
9395
  if (fs__default.default.existsSync(filename)) {
11450
9396
  metaTable.loadFromFile(filename);
11451
9397
  continue;
@@ -13179,6 +11125,23 @@ class HtmlValidate {
13179
11125
  }
13180
11126
  }
13181
11127
 
11128
+ /* generated file, changes will be overwritten */
11129
+ /** @public */
11130
+ const name = "html-validate";
11131
+ /** @public */
11132
+ const version = "7.9.0";
11133
+ /** @public */
11134
+ const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
11135
+
11136
+ /**
11137
+ * Helper function to assist IDE with completion and type-checking.
11138
+ *
11139
+ * @public
11140
+ */
11141
+ function definePlugin(plugin) {
11142
+ return plugin;
11143
+ }
11144
+
13182
11145
  const defaults$1 = {
13183
11146
  silent: false,
13184
11147
  version,
@@ -13604,13 +11567,6 @@ const availableFormatters = {
13604
11567
  stylish: formatter$1,
13605
11568
  text: formatter,
13606
11569
  };
13607
- /**
13608
- * Get formatter function by name.
13609
- *
13610
- * @internal
13611
- * @param name - Name of formatter.
13612
- * @returns Formatter function or null if it doesn't exist.
13613
- */
13614
11570
  function getFormatter(name) {
13615
11571
  var _a;
13616
11572
  return (_a = availableFormatters[name]) !== null && _a !== void 0 ? _a : null;
@@ -13637,17 +11593,19 @@ exports.TextNode = TextNode;
13637
11593
  exports.UserError = UserError;
13638
11594
  exports.WrappedError = WrappedError;
13639
11595
  exports.bugs = bugs;
13640
- exports.classifyNodeText = classifyNodeText;
13641
11596
  exports.codeframe = codeframe;
13642
11597
  exports.compatibilityCheck = compatibilityCheck;
13643
11598
  exports.configDataFromFile = configDataFromFile;
13644
- exports.defineMetadata = defineMetadata;
11599
+ exports.definePlugin = definePlugin;
13645
11600
  exports.ensureError = ensureError;
11601
+ exports.generateIdSelector = generateIdSelector;
13646
11602
  exports.getFormatter = getFormatter;
11603
+ exports.isElementNode = isElementNode;
11604
+ exports.isTextNode = isTextNode;
13647
11605
  exports.legacyRequire = legacyRequire;
13648
- exports.metadataHelper = metadataHelper;
13649
11606
  exports.name = name;
13650
11607
  exports.presets = presets;
13651
11608
  exports.ruleExists = ruleExists;
11609
+ exports.sliceLocation = sliceLocation;
13652
11610
  exports.version = version;
13653
11611
  //# sourceMappingURL=core.js.map