html-validate 8.0.5 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/core.js CHANGED
@@ -4,21 +4,21 @@ var Ajv = require('ajv');
4
4
  var deepmerge = require('deepmerge');
5
5
  var elements = require('./elements.js');
6
6
  var fs = require('fs');
7
- var semver = require('semver');
8
- var kleur = require('kleur');
9
7
  var betterAjvErrors = require('@sidvind/better-ajv-errors');
10
8
  var utils_naturalJoin = require('./utils/natural-join.js');
11
9
  var codeFrame = require('@babel/code-frame');
10
+ var kleur = require('kleur');
12
11
  var stylish$2 = require('@html-validate/stylish');
12
+ var semver = require('semver');
13
13
 
14
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
15
 
16
16
  var Ajv__default = /*#__PURE__*/_interopDefault(Ajv);
17
17
  var deepmerge__default = /*#__PURE__*/_interopDefault(deepmerge);
18
18
  var fs__default = /*#__PURE__*/_interopDefault(fs);
19
- var semver__default = /*#__PURE__*/_interopDefault(semver);
20
- var kleur__default = /*#__PURE__*/_interopDefault(kleur);
21
19
  var betterAjvErrors__default = /*#__PURE__*/_interopDefault(betterAjvErrors);
20
+ var kleur__default = /*#__PURE__*/_interopDefault(kleur);
21
+ var semver__default = /*#__PURE__*/_interopDefault(semver);
22
22
 
23
23
  const $schema$2 = "http://json-schema.org/draft-06/schema#";
24
24
  const $id$2 = "http://json-schema.org/draft-06/schema#";
@@ -2700,7 +2700,9 @@ class DOMTree {
2700
2700
  * Resolve dynamic meta expressions.
2701
2701
  */
2702
2702
  resolveMeta(table) {
2703
- this.visitDepthFirst((node) => table.resolve(node));
2703
+ this.visitDepthFirst((node) => {
2704
+ table.resolve(node);
2705
+ });
2704
2706
  }
2705
2707
  getElementsByTagName(tagName) {
2706
2708
  return this.root.getElementsByTagName(tagName);
@@ -2954,7 +2956,7 @@ class Validator {
2954
2956
  static validatePermittedCategory(node, category, defaultMatch) {
2955
2957
  const [, rawCategory] = category.match(/^(@?.*?)([?*]?)$/);
2956
2958
  /* match tagName when an explicit name is given */
2957
- if (rawCategory[0] !== "@") {
2959
+ if (!rawCategory.startsWith("@")) {
2958
2960
  return node.tagName === rawCategory;
2959
2961
  }
2960
2962
  /* if the meta entry is missing assume any content model would match */
@@ -3809,7 +3811,7 @@ var Style$1;
3809
3811
  Style["ABSOLUTE"] = "absolute";
3810
3812
  Style["ANCHOR"] = "anchor";
3811
3813
  })(Style$1 || (Style$1 = {}));
3812
- const defaults$v = {
3814
+ const defaults$u = {
3813
3815
  allowExternal: true,
3814
3816
  allowRelative: true,
3815
3817
  allowAbsolute: true,
@@ -3853,7 +3855,7 @@ function matchList(value, list) {
3853
3855
  }
3854
3856
  class AllowedLinks extends Rule {
3855
3857
  constructor(options) {
3856
- super({ ...defaults$v, ...options });
3858
+ super({ ...defaults$u, ...options });
3857
3859
  this.allowExternal = parseAllow(this.options.allowExternal);
3858
3860
  this.allowRelative = parseAllow(this.options.allowRelative);
3859
3861
  this.allowAbsolute = parseAllow(this.options.allowAbsolute);
@@ -4001,7 +4003,7 @@ var RuleContext$1;
4001
4003
  RuleContext["MISSING_ALT"] = "missing-alt";
4002
4004
  RuleContext["MISSING_HREF"] = "missing-href";
4003
4005
  })(RuleContext$1 || (RuleContext$1 = {}));
4004
- const defaults$u = {
4006
+ const defaults$t = {
4005
4007
  accessible: true,
4006
4008
  };
4007
4009
  function findByTarget(target, siblings) {
@@ -4027,19 +4029,11 @@ function getDescription$1(context) {
4027
4029
  "",
4028
4030
  "Either add the `href` attribute or remove the `alt` attribute.",
4029
4031
  ];
4030
- default:
4031
- return [
4032
- "The `alt` attribute must only be used together with the `href` attribute.",
4033
- "It must be set if `href` is present and must be omitted if `href` is missing",
4034
- "",
4035
- "The attribute is used to provide an alternative text description for the area of the image map.",
4036
- "The text should describe the purpose of area and the resource referenced by the `href` attribute.",
4037
- ];
4038
4032
  }
4039
4033
  }
4040
4034
  class AreaAlt extends Rule {
4041
4035
  constructor(options) {
4042
- super({ ...defaults$u, ...options });
4036
+ super({ ...defaults$t, ...options });
4043
4037
  }
4044
4038
  static schema() {
4045
4039
  return {
@@ -4273,13 +4267,13 @@ class CaseStyle {
4273
4267
  }
4274
4268
  }
4275
4269
 
4276
- const defaults$t = {
4270
+ const defaults$s = {
4277
4271
  style: "lowercase",
4278
4272
  ignoreForeign: true,
4279
4273
  };
4280
4274
  class AttrCase extends Rule {
4281
4275
  constructor(options) {
4282
- super({ ...defaults$t, ...options });
4276
+ super({ ...defaults$s, ...options });
4283
4277
  this.style = new CaseStyle(this.options.style, "attr-case");
4284
4278
  }
4285
4279
  static schema() {
@@ -4505,7 +4499,7 @@ class Lexer {
4505
4499
  */
4506
4500
  enter(context, state, data) {
4507
4501
  /* script/style tags require a different content model */
4508
- if (state === State.TAG && data && data[0][0] === "<") {
4502
+ if (state === State.TAG && data && data[0].startsWith("<")) {
4509
4503
  if (data[0] === "<script") {
4510
4504
  context.contentModel = ContentModel.SCRIPT;
4511
4505
  }
@@ -4543,14 +4537,14 @@ class Lexer {
4543
4537
  case ContentModel.TEXT:
4544
4538
  return State.TEXT;
4545
4539
  case ContentModel.SCRIPT:
4546
- if (tagCloseToken && tagCloseToken.data[0][0] !== "/") {
4540
+ if (tagCloseToken && !tagCloseToken.data[0].startsWith("/")) {
4547
4541
  return State.SCRIPT;
4548
4542
  }
4549
4543
  else {
4550
4544
  return State.TEXT; /* <script/> (not legal but handle it anyway so the lexer doesn't choke on it) */
4551
4545
  }
4552
4546
  case ContentModel.STYLE:
4553
- if (tagCloseToken && tagCloseToken.data[0][0] !== "/") {
4547
+ if (tagCloseToken && !tagCloseToken.data[0].startsWith("/")) {
4554
4548
  return State.STYLE;
4555
4549
  }
4556
4550
  else {
@@ -4627,7 +4621,7 @@ class AttrDelimiter extends Rule {
4627
4621
  }
4628
4622
 
4629
4623
  const DEFAULT_PATTERN = "[a-z0-9-:]+";
4630
- const defaults$s = {
4624
+ const defaults$r = {
4631
4625
  pattern: DEFAULT_PATTERN,
4632
4626
  ignoreForeign: true,
4633
4627
  };
@@ -4664,7 +4658,7 @@ function generateDescription(name, pattern) {
4664
4658
  }
4665
4659
  class AttrPattern extends Rule {
4666
4660
  constructor(options) {
4667
- super({ ...defaults$s, ...options });
4661
+ super({ ...defaults$r, ...options });
4668
4662
  this.pattern = generateRegexp(this.options.pattern);
4669
4663
  }
4670
4664
  static schema() {
@@ -4725,7 +4719,7 @@ var QuoteStyle;
4725
4719
  QuoteStyle["AUTO_QUOTE"] = "auto";
4726
4720
  QuoteStyle["ANY_QUOTE"] = "any";
4727
4721
  })(QuoteStyle || (QuoteStyle = {}));
4728
- const defaults$r = {
4722
+ const defaults$q = {
4729
4723
  style: "auto",
4730
4724
  unquoted: false,
4731
4725
  };
@@ -4792,7 +4786,7 @@ class AttrQuotes extends Rule {
4792
4786
  };
4793
4787
  }
4794
4788
  constructor(options) {
4795
- super({ ...defaults$r, ...options });
4789
+ super({ ...defaults$q, ...options });
4796
4790
  this.style = parseStyle$3(this.options.style);
4797
4791
  }
4798
4792
  setup() {
@@ -4802,7 +4796,7 @@ class AttrQuotes extends Rule {
4802
4796
  return;
4803
4797
  }
4804
4798
  if (!event.quote) {
4805
- if (this.options.unquoted === false) {
4799
+ if (!this.options.unquoted) {
4806
4800
  const message = `Attribute "${event.key}" using unquoted value`;
4807
4801
  const context = {
4808
4802
  error: "unquoted",
@@ -4962,12 +4956,12 @@ class AttributeAllowedValues extends Rule {
4962
4956
  }
4963
4957
  }
4964
4958
 
4965
- const defaults$q = {
4959
+ const defaults$p = {
4966
4960
  style: "omit",
4967
4961
  };
4968
4962
  class AttributeBooleanStyle extends Rule {
4969
4963
  constructor(options) {
4970
- super({ ...defaults$q, ...options });
4964
+ super({ ...defaults$p, ...options });
4971
4965
  this.hasInvalidStyle = parseStyle$2(this.options.style);
4972
4966
  }
4973
4967
  static schema() {
@@ -5043,12 +5037,12 @@ function reportMessage$1(attr, style) {
5043
5037
  return "";
5044
5038
  }
5045
5039
 
5046
- const defaults$p = {
5040
+ const defaults$o = {
5047
5041
  style: "omit",
5048
5042
  };
5049
5043
  class AttributeEmptyStyle extends Rule {
5050
5044
  constructor(options) {
5051
- super({ ...defaults$p, ...options });
5045
+ super({ ...defaults$o, ...options });
5052
5046
  this.hasInvalidStyle = parseStyle$1(this.options.style);
5053
5047
  }
5054
5048
  static schema() {
@@ -5204,12 +5198,12 @@ function describePattern(pattern) {
5204
5198
  }
5205
5199
  }
5206
5200
 
5207
- const defaults$o = {
5201
+ const defaults$n = {
5208
5202
  pattern: "kebabcase",
5209
5203
  };
5210
5204
  class ClassPattern extends Rule {
5211
5205
  constructor(options) {
5212
- super({ ...defaults$o, ...options });
5206
+ super({ ...defaults$n, ...options });
5213
5207
  this.pattern = parsePattern(this.options.pattern);
5214
5208
  }
5215
5209
  static schema() {
@@ -5318,13 +5312,13 @@ class CloseOrder extends Rule {
5318
5312
  }
5319
5313
  }
5320
5314
 
5321
- const defaults$n = {
5315
+ const defaults$m = {
5322
5316
  include: null,
5323
5317
  exclude: null,
5324
5318
  };
5325
5319
  class Deprecated extends Rule {
5326
5320
  constructor(options) {
5327
- super({ ...defaults$n, ...options });
5321
+ super({ ...defaults$m, ...options });
5328
5322
  }
5329
5323
  static schema() {
5330
5324
  return {
@@ -5487,12 +5481,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
5487
5481
  }
5488
5482
  };
5489
5483
 
5490
- const defaults$m = {
5484
+ const defaults$l = {
5491
5485
  style: "uppercase",
5492
5486
  };
5493
5487
  class DoctypeStyle extends Rule {
5494
5488
  constructor(options) {
5495
- super({ ...defaults$m, ...options });
5489
+ super({ ...defaults$l, ...options });
5496
5490
  }
5497
5491
  static schema() {
5498
5492
  return {
@@ -5524,12 +5518,12 @@ class DoctypeStyle extends Rule {
5524
5518
  }
5525
5519
  }
5526
5520
 
5527
- const defaults$l = {
5521
+ const defaults$k = {
5528
5522
  style: "lowercase",
5529
5523
  };
5530
5524
  class ElementCase extends Rule {
5531
5525
  constructor(options) {
5532
- super({ ...defaults$l, ...options });
5526
+ super({ ...defaults$k, ...options });
5533
5527
  this.style = new CaseStyle(this.options.style, "element-case");
5534
5528
  }
5535
5529
  static schema() {
@@ -5595,14 +5589,14 @@ class ElementCase extends Rule {
5595
5589
  }
5596
5590
  }
5597
5591
 
5598
- const defaults$k = {
5592
+ const defaults$j = {
5599
5593
  pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
5600
5594
  whitelist: [],
5601
5595
  blacklist: [],
5602
5596
  };
5603
5597
  class ElementName extends Rule {
5604
5598
  constructor(options) {
5605
- super({ ...defaults$k, ...options });
5599
+ super({ ...defaults$j, ...options });
5606
5600
  /* eslint-disable-next-line security/detect-non-literal-regexp -- expected to be a regexp */
5607
5601
  this.pattern = new RegExp(this.options.pattern);
5608
5602
  }
@@ -5643,7 +5637,7 @@ class ElementName extends Rule {
5643
5637
  ...context.blacklist.map((cur) => `- ${cur}`),
5644
5638
  ];
5645
5639
  }
5646
- if (context.pattern !== defaults$k.pattern) {
5640
+ if (context.pattern !== defaults$j.pattern) {
5647
5641
  return [
5648
5642
  `<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
5649
5643
  "",
@@ -5879,7 +5873,7 @@ function isCategoryOrTag(value) {
5879
5873
  return typeof value === "string";
5880
5874
  }
5881
5875
  function isCategory$1(value) {
5882
- return value[0] === "@";
5876
+ return value.startsWith("@");
5883
5877
  }
5884
5878
  function formatCategoryOrTag(value) {
5885
5879
  return isCategory$1(value) ? value.slice(1) : `<${value}>`;
@@ -6059,7 +6053,7 @@ class ElementRequiredAttributes extends Rule {
6059
6053
  }
6060
6054
 
6061
6055
  function isCategory(value) {
6062
- return value[0] === "@";
6056
+ return value.startsWith("@");
6063
6057
  }
6064
6058
  class ElementRequiredContent extends Rule {
6065
6059
  documentation(context) {
@@ -6187,7 +6181,7 @@ class EmptyTitle extends Rule {
6187
6181
  }
6188
6182
  }
6189
6183
 
6190
- const defaults$j = {
6184
+ const defaults$i = {
6191
6185
  allowArrayBrackets: true,
6192
6186
  shared: ["radio", "button", "reset", "submit"],
6193
6187
  };
@@ -6220,7 +6214,7 @@ function getDocumentation(context) {
6220
6214
  }
6221
6215
  class FormDupName extends Rule {
6222
6216
  constructor(options) {
6223
- super({ ...defaults$j, ...options });
6217
+ super({ ...defaults$i, ...options });
6224
6218
  }
6225
6219
  static schema() {
6226
6220
  return {
@@ -6380,7 +6374,7 @@ class FormDupName extends Rule {
6380
6374
  }
6381
6375
  }
6382
6376
 
6383
- const defaults$i = {
6377
+ const defaults$h = {
6384
6378
  allowMultipleH1: false,
6385
6379
  minInitialRank: "h1",
6386
6380
  sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]'],
@@ -6411,7 +6405,7 @@ function parseMaxInitial(value) {
6411
6405
  }
6412
6406
  class HeadingLevel extends Rule {
6413
6407
  constructor(options) {
6414
- super({ ...defaults$i, ...options });
6408
+ super({ ...defaults$h, ...options });
6415
6409
  this.stack = [];
6416
6410
  this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
6417
6411
  this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
@@ -6453,9 +6447,15 @@ class HeadingLevel extends Rule {
6453
6447
  };
6454
6448
  }
6455
6449
  setup() {
6456
- this.on("tag:start", isRelevant$3, (event) => this.onTagStart(event));
6457
- this.on("tag:ready", (event) => this.onTagReady(event));
6458
- this.on("tag:close", (event) => this.onTagClose(event));
6450
+ this.on("tag:start", isRelevant$3, (event) => {
6451
+ this.onTagStart(event);
6452
+ });
6453
+ this.on("tag:ready", (event) => {
6454
+ this.onTagReady(event);
6455
+ });
6456
+ this.on("tag:close", (event) => {
6457
+ this.onTagClose(event);
6458
+ });
6459
6459
  }
6460
6460
  onTagStart(event) {
6461
6461
  /* extract heading level from tagName (e.g "h1" -> 1)*/
@@ -6569,12 +6569,12 @@ class HeadingLevel extends Rule {
6569
6569
  }
6570
6570
  }
6571
6571
 
6572
- const defaults$h = {
6572
+ const defaults$g = {
6573
6573
  pattern: "kebabcase",
6574
6574
  };
6575
6575
  class IdPattern extends Rule {
6576
6576
  constructor(options) {
6577
- super({ ...defaults$h, ...options });
6577
+ super({ ...defaults$g, ...options });
6578
6578
  this.pattern = parsePattern(this.options.pattern);
6579
6579
  }
6580
6580
  static schema() {
@@ -6976,12 +6976,12 @@ function findLabelByParent(el) {
6976
6976
  return [];
6977
6977
  }
6978
6978
 
6979
- const defaults$g = {
6979
+ const defaults$f = {
6980
6980
  maxlength: 70,
6981
6981
  };
6982
6982
  class LongTitle extends Rule {
6983
6983
  constructor(options) {
6984
- super({ ...defaults$g, ...options });
6984
+ super({ ...defaults$f, ...options });
6985
6985
  this.maxlength = this.options.maxlength;
6986
6986
  }
6987
6987
  static schema() {
@@ -7207,13 +7207,13 @@ class MultipleLabeledControls extends Rule {
7207
7207
  }
7208
7208
  }
7209
7209
 
7210
- const defaults$f = {
7210
+ const defaults$e = {
7211
7211
  include: null,
7212
7212
  exclude: null,
7213
7213
  };
7214
7214
  class NoAutoplay extends Rule {
7215
7215
  constructor(options) {
7216
- super({ ...defaults$f, ...options });
7216
+ super({ ...defaults$e, ...options });
7217
7217
  }
7218
7218
  documentation(context) {
7219
7219
  const tagName = context ? ` on <${context.tagName}>` : "";
@@ -7454,14 +7454,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
7454
7454
  }
7455
7455
  }
7456
7456
 
7457
- const defaults$e = {
7457
+ const defaults$d = {
7458
7458
  include: null,
7459
7459
  exclude: null,
7460
7460
  allowedProperties: ["display"],
7461
7461
  };
7462
7462
  class NoInlineStyle extends Rule {
7463
7463
  constructor(options) {
7464
- super({ ...defaults$e, ...options });
7464
+ super({ ...defaults$d, ...options });
7465
7465
  }
7466
7466
  static schema() {
7467
7467
  return {
@@ -7663,7 +7663,7 @@ class NoMultipleMain extends Rule {
7663
7663
  }
7664
7664
  }
7665
7665
 
7666
- const defaults$d = {
7666
+ const defaults$c = {
7667
7667
  relaxed: false,
7668
7668
  };
7669
7669
  const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
@@ -7680,7 +7680,7 @@ const replacementTable = {
7680
7680
  };
7681
7681
  class NoRawCharacters extends Rule {
7682
7682
  constructor(options) {
7683
- super({ ...defaults$d, ...options });
7683
+ super({ ...defaults$c, ...options });
7684
7684
  this.relaxed = this.options.relaxed;
7685
7685
  }
7686
7686
  static schema() {
@@ -7754,6 +7754,39 @@ class NoRawCharacters extends Rule {
7754
7754
  }
7755
7755
  }
7756
7756
 
7757
+ const selectors = ["input[aria-label]", "textarea[aria-label]", "select[aria-label]"];
7758
+ class NoRedundantAriaLabel extends Rule {
7759
+ documentation() {
7760
+ return {
7761
+ description: "`aria-label` is redundant when an associated `<label>` element containing the same text exists.",
7762
+ url: "https://html-validate.org/rules/no-redundant-aria-label.html",
7763
+ };
7764
+ }
7765
+ setup() {
7766
+ this.on("dom:ready", (event) => {
7767
+ const { document } = event;
7768
+ const elements = document.querySelectorAll(selectors.join(","));
7769
+ for (const element of elements) {
7770
+ const ariaLabel = element.getAttribute("aria-label");
7771
+ const id = element.id;
7772
+ if (!id) {
7773
+ continue;
7774
+ }
7775
+ const label = document.querySelector(`label[for="${id}"]`);
7776
+ if (!ariaLabel || !label || label.textContent.trim() !== ariaLabel.value) {
7777
+ continue;
7778
+ }
7779
+ const message = "aria-label is redundant when label containing same text exists";
7780
+ this.report({
7781
+ message,
7782
+ node: element,
7783
+ location: ariaLabel.keyLocation,
7784
+ });
7785
+ }
7786
+ });
7787
+ }
7788
+ }
7789
+
7757
7790
  class NoRedundantFor extends Rule {
7758
7791
  documentation() {
7759
7792
  return {
@@ -7858,13 +7891,13 @@ class NoRedundantRole extends Rule {
7858
7891
  }
7859
7892
 
7860
7893
  const xmlns = /^(.+):.+$/;
7861
- const defaults$c = {
7894
+ const defaults$b = {
7862
7895
  ignoreForeign: true,
7863
7896
  ignoreXML: true,
7864
7897
  };
7865
7898
  class NoSelfClosing extends Rule {
7866
7899
  constructor(options) {
7867
- super({ ...defaults$c, ...options });
7900
+ super({ ...defaults$b, ...options });
7868
7901
  }
7869
7902
  static schema() {
7870
7903
  return {
@@ -7953,13 +7986,13 @@ class NoTrailingWhitespace extends Rule {
7953
7986
  }
7954
7987
  }
7955
7988
 
7956
- const defaults$b = {
7989
+ const defaults$a = {
7957
7990
  include: null,
7958
7991
  exclude: null,
7959
7992
  };
7960
7993
  class NoUnknownElements extends Rule {
7961
7994
  constructor(options) {
7962
- super({ ...defaults$b, ...options });
7995
+ super({ ...defaults$a, ...options });
7963
7996
  }
7964
7997
  static schema() {
7965
7998
  return {
@@ -8015,9 +8048,7 @@ class NoUnknownElements extends Rule {
8015
8048
  class NoUnusedDisable extends Rule {
8016
8049
  documentation(context) {
8017
8050
  return {
8018
- description: context
8019
- ? `\`${context.ruleId}\` rule is disabled but no error was reported.`
8020
- : "Rule is disabled but no error was reported.",
8051
+ description: `\`${context.ruleId}\` rule is disabled but no error was reported.`,
8021
8052
  url: "https://html-validate.org/rules/no-unused-disable.html",
8022
8053
  };
8023
8054
  }
@@ -8071,13 +8102,13 @@ const replacement = {
8071
8102
  reset: '<button type="reset">',
8072
8103
  image: '<button type="button">',
8073
8104
  };
8074
- const defaults$a = {
8105
+ const defaults$9 = {
8075
8106
  include: null,
8076
8107
  exclude: null,
8077
8108
  };
8078
8109
  class PreferButton extends Rule {
8079
8110
  constructor(options) {
8080
- super({ ...defaults$a, ...options });
8111
+ super({ ...defaults$9, ...options });
8081
8112
  }
8082
8113
  static schema() {
8083
8114
  return {
@@ -8152,7 +8183,7 @@ class PreferButton extends Rule {
8152
8183
  }
8153
8184
  }
8154
8185
 
8155
- const defaults$9 = {
8186
+ const defaults$8 = {
8156
8187
  mapping: {
8157
8188
  article: "article",
8158
8189
  banner: "header",
@@ -8182,7 +8213,7 @@ const defaults$9 = {
8182
8213
  };
8183
8214
  class PreferNativeElement extends Rule {
8184
8215
  constructor(options) {
8185
- super({ ...defaults$9, ...options });
8216
+ super({ ...defaults$8, ...options });
8186
8217
  }
8187
8218
  static schema() {
8188
8219
  return {
@@ -8302,12 +8333,12 @@ class PreferTbody extends Rule {
8302
8333
  }
8303
8334
  }
8304
8335
 
8305
- const defaults$8 = {
8336
+ const defaults$7 = {
8306
8337
  tags: ["script", "style"],
8307
8338
  };
8308
8339
  class RequireCSPNonce extends Rule {
8309
8340
  constructor(options) {
8310
- super({ ...defaults$8, ...options });
8341
+ super({ ...defaults$7, ...options });
8311
8342
  }
8312
8343
  static schema() {
8313
8344
  return {
@@ -8358,7 +8389,7 @@ class RequireCSPNonce extends Rule {
8358
8389
  }
8359
8390
  }
8360
8391
 
8361
- const defaults$7 = {
8392
+ const defaults$6 = {
8362
8393
  target: "all",
8363
8394
  include: null,
8364
8395
  exclude: null,
@@ -8370,7 +8401,7 @@ const supportSri = {
8370
8401
  };
8371
8402
  class RequireSri extends Rule {
8372
8403
  constructor(options) {
8373
- super({ ...defaults$7, ...options });
8404
+ super({ ...defaults$6, ...options });
8374
8405
  this.target = this.options.target;
8375
8406
  }
8376
8407
  static schema() {
@@ -8532,7 +8563,7 @@ class SvgFocusable extends Rule {
8532
8563
  }
8533
8564
  }
8534
8565
 
8535
- const defaults$6 = {
8566
+ const defaults$5 = {
8536
8567
  characters: [
8537
8568
  { pattern: " ", replacement: "&nbsp;", description: "non-breaking space" },
8538
8569
  { pattern: "-", replacement: "&#8209;", description: "non-breaking hyphen" },
@@ -8571,7 +8602,7 @@ function matchAll(text, regexp) {
8571
8602
  }
8572
8603
  class TelNonBreaking extends Rule {
8573
8604
  constructor(options) {
8574
- super({ ...defaults$6, ...options });
8605
+ super({ ...defaults$5, ...options });
8575
8606
  this.regex = constructRegex(this.options.characters);
8576
8607
  }
8577
8608
  static schema() {
@@ -8612,9 +8643,7 @@ class TelNonBreaking extends Rule {
8612
8643
  });
8613
8644
  return {
8614
8645
  description: [
8615
- context
8616
- ? `The \`${context.pattern}\` character should be replaced with \`${context.replacement}\` character (${context.description}) when used in a telephone number.`
8617
- : `Replace this character with a non-breaking version.`,
8646
+ `The \`${context.pattern}\` character should be replaced with \`${context.replacement}\` character (${context.description}) when used in a telephone number.`,
8618
8647
  "",
8619
8648
  "Unless non-breaking characters is used there could be a line break inserted at that character.",
8620
8649
  "Line breaks make is harder to read and understand the telephone number.",
@@ -8859,7 +8888,7 @@ class TextContent extends Rule {
8859
8888
  }
8860
8889
  }
8861
8890
 
8862
- const defaults$5 = {
8891
+ const defaults$4 = {
8863
8892
  ignoreCase: false,
8864
8893
  requireSemicolon: true,
8865
8894
  };
@@ -8877,16 +8906,11 @@ function getLocation(location, entity, match) {
8877
8906
  function getDescription(context, options) {
8878
8907
  const url = "https://html.spec.whatwg.org/multipage/named-characters.html";
8879
8908
  let message;
8880
- if (context) {
8881
- if (context.terminated) {
8882
- message = `Unrecognized character reference \`${context.entity}\`.`;
8883
- }
8884
- else {
8885
- message = `Character reference \`${context.entity}\` must be terminated by a semicolon.`;
8886
- }
8909
+ if (context.terminated) {
8910
+ message = `Unrecognized character reference \`${context.entity}\`.`;
8887
8911
  }
8888
8912
  else {
8889
- message = `Unrecognized character reference.`;
8913
+ message = `Character reference \`${context.entity}\` must be terminated by a semicolon.`;
8890
8914
  }
8891
8915
  return [
8892
8916
  message,
@@ -8901,7 +8925,7 @@ function getDescription(context, options) {
8901
8925
  }
8902
8926
  class UnknownCharReference extends Rule {
8903
8927
  constructor(options) {
8904
- super({ ...defaults$5, ...options });
8928
+ super({ ...defaults$4, ...options });
8905
8929
  }
8906
8930
  static schema() {
8907
8931
  return {
@@ -9018,12 +9042,12 @@ var RuleContext;
9018
9042
  RuleContext[RuleContext["LEADING_CHARACTER"] = 3] = "LEADING_CHARACTER";
9019
9043
  RuleContext[RuleContext["DISALLOWED_CHARACTER"] = 4] = "DISALLOWED_CHARACTER";
9020
9044
  })(RuleContext || (RuleContext = {}));
9021
- const defaults$4 = {
9045
+ const defaults$3 = {
9022
9046
  relaxed: false,
9023
9047
  };
9024
9048
  class ValidID extends Rule {
9025
9049
  constructor(options) {
9026
- super({ ...defaults$4, ...options });
9050
+ super({ ...defaults$3, ...options });
9027
9051
  }
9028
9052
  static schema() {
9029
9053
  return {
@@ -9034,9 +9058,9 @@ class ValidID extends Rule {
9034
9058
  }
9035
9059
  documentation(context) {
9036
9060
  const { relaxed } = this.options;
9037
- const message = context
9038
- ? this.messages[context].replace("id", "ID").replace(/^(.)/, (m) => m.toUpperCase())
9039
- : "Element ID is not valid";
9061
+ const message = this.messages[context]
9062
+ .replace("id", "ID")
9063
+ .replace(/^(.)/, (m) => m.toUpperCase());
9040
9064
  const relaxedDescription = relaxed
9041
9065
  ? []
9042
9066
  : [
@@ -9132,12 +9156,12 @@ var Style;
9132
9156
  Style[Style["AlwaysOmit"] = 1] = "AlwaysOmit";
9133
9157
  Style[Style["AlwaysSelfclose"] = 2] = "AlwaysSelfclose";
9134
9158
  })(Style || (Style = {}));
9135
- const defaults$3 = {
9159
+ const defaults$2 = {
9136
9160
  style: "omit",
9137
9161
  };
9138
9162
  class VoidStyle extends Rule {
9139
9163
  constructor(options) {
9140
- super({ ...defaults$3, ...options });
9164
+ super({ ...defaults$2, ...options });
9141
9165
  this.style = parseStyle(this.options.style);
9142
9166
  }
9143
9167
  static schema() {
@@ -9334,7 +9358,7 @@ class H36 extends Rule {
9334
9358
  }
9335
9359
  }
9336
9360
 
9337
- const defaults$2 = {
9361
+ const defaults$1 = {
9338
9362
  allowEmpty: true,
9339
9363
  alias: [],
9340
9364
  };
@@ -9355,7 +9379,7 @@ function getTag(node) {
9355
9379
  }
9356
9380
  class H37 extends Rule {
9357
9381
  constructor(options) {
9358
- super({ ...defaults$2, ...options });
9382
+ super({ ...defaults$1, ...options });
9359
9383
  /* ensure alias is array */
9360
9384
  if (!Array.isArray(this.options.alias)) {
9361
9385
  this.options.alias = [this.options.alias];
@@ -9581,6 +9605,7 @@ const bundledRules = {
9581
9605
  "no-missing-references": NoMissingReferences,
9582
9606
  "no-multiple-main": NoMultipleMain,
9583
9607
  "no-raw-characters": NoRawCharacters,
9608
+ "no-redundant-aria-label": NoRedundantAriaLabel,
9584
9609
  "no-redundant-for": NoRedundantFor,
9585
9610
  "no-redundant-role": NoRedundantRole,
9586
9611
  "no-self-closing": NoSelfClosing,
@@ -9621,6 +9646,7 @@ const config$4 = {
9621
9646
  "multiple-labeled-controls": "error",
9622
9647
  "no-autoplay": ["error", { include: ["audio", "video"] }],
9623
9648
  "no-dup-id": "error",
9649
+ "no-redundant-aria-label": "error",
9624
9650
  "no-redundant-for": "error",
9625
9651
  "no-redundant-role": "error",
9626
9652
  "prefer-native-element": "error",
@@ -9703,6 +9729,7 @@ const config$1 = {
9703
9729
  "no-inline-style": "error",
9704
9730
  "no-multiple-main": "error",
9705
9731
  "no-raw-characters": "error",
9732
+ "no-redundant-aria-label": "error",
9706
9733
  "no-redundant-for": "error",
9707
9734
  "no-redundant-role": "error",
9708
9735
  "no-self-closing": "error",
@@ -10167,8 +10194,7 @@ class Config {
10167
10194
  return this.config;
10168
10195
  }
10169
10196
  let base = {};
10170
- for (let i = 0; i < entries.length; i++) {
10171
- const entry = entries[i];
10197
+ for (const entry of entries) {
10172
10198
  let extended;
10173
10199
  if (this.configurations.has(entry)) {
10174
10200
  extended = this.configurations.get(entry);
@@ -11460,7 +11486,9 @@ class Engine {
11460
11486
  else {
11461
11487
  lines.push("(root)");
11462
11488
  }
11463
- node.childElements.forEach((child, index) => writeNode(child, level + 1, index));
11489
+ node.childElements.forEach((child, index) => {
11490
+ writeNode(child, level + 1, index);
11491
+ });
11464
11492
  }
11465
11493
  writeNode(document, 0, 0);
11466
11494
  return lines;
@@ -12144,7 +12172,7 @@ class HtmlValidate {
12144
12172
  /** @public */
12145
12173
  const name = "html-validate";
12146
12174
  /** @public */
12147
- const version = "8.0.5";
12175
+ const version = "8.1.0";
12148
12176
  /** @public */
12149
12177
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
12150
12178
 
@@ -12157,61 +12185,6 @@ function definePlugin(plugin) {
12157
12185
  return plugin;
12158
12186
  }
12159
12187
 
12160
- const defaults$1 = {
12161
- silent: false,
12162
- version,
12163
- logger(text) {
12164
- /* eslint-disable-next-line no-console -- expected to log */
12165
- console.error(kleur__default.default.red(text));
12166
- },
12167
- };
12168
- /**
12169
- * Tests if plugin is compatible with html-validate library. Unless the `silent`
12170
- * option is used a warning is displayed on the console.
12171
- *
12172
- * @public
12173
- * @since v5.0.0
12174
- * @param name - Name of plugin
12175
- * @param declared - What library versions the plugin support (e.g. declared peerDependencies)
12176
- * @returns - `true` if version is compatible
12177
- */
12178
- function compatibilityCheck(name, declared, options) {
12179
- const { silent, version: current, logger } = { ...defaults$1, ...options };
12180
- const valid = semver__default.default.satisfies(current, declared);
12181
- if (valid || silent) {
12182
- return valid;
12183
- }
12184
- const text = [
12185
- "-----------------------------------------------------------------------------------------------------",
12186
- `${name} requires html-validate version "${declared}" but current installed version is ${current}`,
12187
- "This is not a supported configuration. Please install a supported version before reporting bugs.",
12188
- "-----------------------------------------------------------------------------------------------------",
12189
- ].join("\n");
12190
- logger(text);
12191
- return false;
12192
- }
12193
-
12194
- /**
12195
- * Similar to `require(..)` but removes the cached copy first.
12196
- */
12197
- function requireUncached(require, moduleId) {
12198
- const filename = require.resolve(moduleId);
12199
- /* remove references from the parent module to prevent memory leak */
12200
- const m = require.cache[filename];
12201
- if (m && m.parent) {
12202
- const { parent } = m;
12203
- for (let i = parent.children.length - 1; i >= 0; i--) {
12204
- if (parent.children[i].id === filename) {
12205
- parent.children.splice(i, 1);
12206
- }
12207
- }
12208
- }
12209
- /* remove old module from cache */
12210
- delete require.cache[filename];
12211
- /* eslint-disable-next-line import/no-dynamic-require, security/detect-non-literal-require -- as expected but should be moved to upcoming resolver class */
12212
- return require(filename);
12213
- }
12214
-
12215
12188
  const ruleIds = new Set(Object.keys(rules));
12216
12189
  /**
12217
12190
  * Returns true if given ruleId is an existing builtin rule. It does not handle
@@ -12478,6 +12451,25 @@ function getFormatter(name) {
12478
12451
  return (_a = availableFormatters[name]) !== null && _a !== void 0 ? _a : null;
12479
12452
  }
12480
12453
 
12454
+ /**
12455
+ * @internal
12456
+ */
12457
+ function compatibilityCheckImpl(name, declared, options) {
12458
+ const { silent, version: current, logger } = options;
12459
+ const valid = semver__default.default.satisfies(current, declared);
12460
+ if (valid || silent) {
12461
+ return valid;
12462
+ }
12463
+ const text = [
12464
+ "-----------------------------------------------------------------------------------------------------",
12465
+ `${name} requires html-validate version "${declared}" but current installed version is ${current}`,
12466
+ "This is not a supported configuration. Please install a supported version before reporting bugs.",
12467
+ "-----------------------------------------------------------------------------------------------------",
12468
+ ].join("\n");
12469
+ logger(text);
12470
+ return false;
12471
+ }
12472
+
12481
12473
  exports.Attribute = Attribute;
12482
12474
  exports.Config = Config;
12483
12475
  exports.ConfigError = ConfigError;
@@ -12506,13 +12498,12 @@ exports.WrappedError = WrappedError;
12506
12498
  exports.bugs = bugs;
12507
12499
  exports.classifyNodeText = classifyNodeText;
12508
12500
  exports.codeframe = codeframe;
12509
- exports.compatibilityCheck = compatibilityCheck;
12501
+ exports.compatibilityCheckImpl = compatibilityCheckImpl;
12510
12502
  exports.definePlugin = definePlugin;
12511
12503
  exports.ensureError = ensureError;
12512
12504
  exports.getFormatter = getFormatter;
12513
12505
  exports.keywordPatternMatcher = keywordPatternMatcher;
12514
12506
  exports.name = name;
12515
- exports.requireUncached = requireUncached;
12516
12507
  exports.ruleExists = ruleExists;
12517
12508
  exports.sliceLocation = sliceLocation;
12518
12509
  exports.staticResolver = staticResolver;