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/es/core.js CHANGED
@@ -2,12 +2,12 @@ import Ajv from 'ajv';
2
2
  import deepmerge from 'deepmerge';
3
3
  import { e as entities$1, h as html5, b as bundledElements } from './elements.js';
4
4
  import fs from 'fs';
5
- import semver from 'semver';
6
- import kleur from 'kleur';
7
5
  import betterAjvErrors from '@sidvind/better-ajv-errors';
8
6
  import { n as naturalJoin } from './utils/natural-join.js';
9
7
  import { codeFrameColumns } from '@babel/code-frame';
8
+ import kleur from 'kleur';
10
9
  import { stylish as stylish$2 } from '@html-validate/stylish';
10
+ import semver from 'semver';
11
11
 
12
12
  const $schema$2 = "http://json-schema.org/draft-06/schema#";
13
13
  const $id$2 = "http://json-schema.org/draft-06/schema#";
@@ -2689,7 +2689,9 @@ class DOMTree {
2689
2689
  * Resolve dynamic meta expressions.
2690
2690
  */
2691
2691
  resolveMeta(table) {
2692
- this.visitDepthFirst((node) => table.resolve(node));
2692
+ this.visitDepthFirst((node) => {
2693
+ table.resolve(node);
2694
+ });
2693
2695
  }
2694
2696
  getElementsByTagName(tagName) {
2695
2697
  return this.root.getElementsByTagName(tagName);
@@ -2943,7 +2945,7 @@ class Validator {
2943
2945
  static validatePermittedCategory(node, category, defaultMatch) {
2944
2946
  const [, rawCategory] = category.match(/^(@?.*?)([?*]?)$/);
2945
2947
  /* match tagName when an explicit name is given */
2946
- if (rawCategory[0] !== "@") {
2948
+ if (!rawCategory.startsWith("@")) {
2947
2949
  return node.tagName === rawCategory;
2948
2950
  }
2949
2951
  /* if the meta entry is missing assume any content model would match */
@@ -3798,7 +3800,7 @@ var Style$1;
3798
3800
  Style["ABSOLUTE"] = "absolute";
3799
3801
  Style["ANCHOR"] = "anchor";
3800
3802
  })(Style$1 || (Style$1 = {}));
3801
- const defaults$v = {
3803
+ const defaults$u = {
3802
3804
  allowExternal: true,
3803
3805
  allowRelative: true,
3804
3806
  allowAbsolute: true,
@@ -3842,7 +3844,7 @@ function matchList(value, list) {
3842
3844
  }
3843
3845
  class AllowedLinks extends Rule {
3844
3846
  constructor(options) {
3845
- super({ ...defaults$v, ...options });
3847
+ super({ ...defaults$u, ...options });
3846
3848
  this.allowExternal = parseAllow(this.options.allowExternal);
3847
3849
  this.allowRelative = parseAllow(this.options.allowRelative);
3848
3850
  this.allowAbsolute = parseAllow(this.options.allowAbsolute);
@@ -3990,7 +3992,7 @@ var RuleContext$1;
3990
3992
  RuleContext["MISSING_ALT"] = "missing-alt";
3991
3993
  RuleContext["MISSING_HREF"] = "missing-href";
3992
3994
  })(RuleContext$1 || (RuleContext$1 = {}));
3993
- const defaults$u = {
3995
+ const defaults$t = {
3994
3996
  accessible: true,
3995
3997
  };
3996
3998
  function findByTarget(target, siblings) {
@@ -4016,19 +4018,11 @@ function getDescription$1(context) {
4016
4018
  "",
4017
4019
  "Either add the `href` attribute or remove the `alt` attribute.",
4018
4020
  ];
4019
- default:
4020
- return [
4021
- "The `alt` attribute must only be used together with the `href` attribute.",
4022
- "It must be set if `href` is present and must be omitted if `href` is missing",
4023
- "",
4024
- "The attribute is used to provide an alternative text description for the area of the image map.",
4025
- "The text should describe the purpose of area and the resource referenced by the `href` attribute.",
4026
- ];
4027
4021
  }
4028
4022
  }
4029
4023
  class AreaAlt extends Rule {
4030
4024
  constructor(options) {
4031
- super({ ...defaults$u, ...options });
4025
+ super({ ...defaults$t, ...options });
4032
4026
  }
4033
4027
  static schema() {
4034
4028
  return {
@@ -4262,13 +4256,13 @@ class CaseStyle {
4262
4256
  }
4263
4257
  }
4264
4258
 
4265
- const defaults$t = {
4259
+ const defaults$s = {
4266
4260
  style: "lowercase",
4267
4261
  ignoreForeign: true,
4268
4262
  };
4269
4263
  class AttrCase extends Rule {
4270
4264
  constructor(options) {
4271
- super({ ...defaults$t, ...options });
4265
+ super({ ...defaults$s, ...options });
4272
4266
  this.style = new CaseStyle(this.options.style, "attr-case");
4273
4267
  }
4274
4268
  static schema() {
@@ -4494,7 +4488,7 @@ class Lexer {
4494
4488
  */
4495
4489
  enter(context, state, data) {
4496
4490
  /* script/style tags require a different content model */
4497
- if (state === State.TAG && data && data[0][0] === "<") {
4491
+ if (state === State.TAG && data && data[0].startsWith("<")) {
4498
4492
  if (data[0] === "<script") {
4499
4493
  context.contentModel = ContentModel.SCRIPT;
4500
4494
  }
@@ -4532,14 +4526,14 @@ class Lexer {
4532
4526
  case ContentModel.TEXT:
4533
4527
  return State.TEXT;
4534
4528
  case ContentModel.SCRIPT:
4535
- if (tagCloseToken && tagCloseToken.data[0][0] !== "/") {
4529
+ if (tagCloseToken && !tagCloseToken.data[0].startsWith("/")) {
4536
4530
  return State.SCRIPT;
4537
4531
  }
4538
4532
  else {
4539
4533
  return State.TEXT; /* <script/> (not legal but handle it anyway so the lexer doesn't choke on it) */
4540
4534
  }
4541
4535
  case ContentModel.STYLE:
4542
- if (tagCloseToken && tagCloseToken.data[0][0] !== "/") {
4536
+ if (tagCloseToken && !tagCloseToken.data[0].startsWith("/")) {
4543
4537
  return State.STYLE;
4544
4538
  }
4545
4539
  else {
@@ -4616,7 +4610,7 @@ class AttrDelimiter extends Rule {
4616
4610
  }
4617
4611
 
4618
4612
  const DEFAULT_PATTERN = "[a-z0-9-:]+";
4619
- const defaults$s = {
4613
+ const defaults$r = {
4620
4614
  pattern: DEFAULT_PATTERN,
4621
4615
  ignoreForeign: true,
4622
4616
  };
@@ -4653,7 +4647,7 @@ function generateDescription(name, pattern) {
4653
4647
  }
4654
4648
  class AttrPattern extends Rule {
4655
4649
  constructor(options) {
4656
- super({ ...defaults$s, ...options });
4650
+ super({ ...defaults$r, ...options });
4657
4651
  this.pattern = generateRegexp(this.options.pattern);
4658
4652
  }
4659
4653
  static schema() {
@@ -4714,7 +4708,7 @@ var QuoteStyle;
4714
4708
  QuoteStyle["AUTO_QUOTE"] = "auto";
4715
4709
  QuoteStyle["ANY_QUOTE"] = "any";
4716
4710
  })(QuoteStyle || (QuoteStyle = {}));
4717
- const defaults$r = {
4711
+ const defaults$q = {
4718
4712
  style: "auto",
4719
4713
  unquoted: false,
4720
4714
  };
@@ -4781,7 +4775,7 @@ class AttrQuotes extends Rule {
4781
4775
  };
4782
4776
  }
4783
4777
  constructor(options) {
4784
- super({ ...defaults$r, ...options });
4778
+ super({ ...defaults$q, ...options });
4785
4779
  this.style = parseStyle$3(this.options.style);
4786
4780
  }
4787
4781
  setup() {
@@ -4791,7 +4785,7 @@ class AttrQuotes extends Rule {
4791
4785
  return;
4792
4786
  }
4793
4787
  if (!event.quote) {
4794
- if (this.options.unquoted === false) {
4788
+ if (!this.options.unquoted) {
4795
4789
  const message = `Attribute "${event.key}" using unquoted value`;
4796
4790
  const context = {
4797
4791
  error: "unquoted",
@@ -4951,12 +4945,12 @@ class AttributeAllowedValues extends Rule {
4951
4945
  }
4952
4946
  }
4953
4947
 
4954
- const defaults$q = {
4948
+ const defaults$p = {
4955
4949
  style: "omit",
4956
4950
  };
4957
4951
  class AttributeBooleanStyle extends Rule {
4958
4952
  constructor(options) {
4959
- super({ ...defaults$q, ...options });
4953
+ super({ ...defaults$p, ...options });
4960
4954
  this.hasInvalidStyle = parseStyle$2(this.options.style);
4961
4955
  }
4962
4956
  static schema() {
@@ -5032,12 +5026,12 @@ function reportMessage$1(attr, style) {
5032
5026
  return "";
5033
5027
  }
5034
5028
 
5035
- const defaults$p = {
5029
+ const defaults$o = {
5036
5030
  style: "omit",
5037
5031
  };
5038
5032
  class AttributeEmptyStyle extends Rule {
5039
5033
  constructor(options) {
5040
- super({ ...defaults$p, ...options });
5034
+ super({ ...defaults$o, ...options });
5041
5035
  this.hasInvalidStyle = parseStyle$1(this.options.style);
5042
5036
  }
5043
5037
  static schema() {
@@ -5193,12 +5187,12 @@ function describePattern(pattern) {
5193
5187
  }
5194
5188
  }
5195
5189
 
5196
- const defaults$o = {
5190
+ const defaults$n = {
5197
5191
  pattern: "kebabcase",
5198
5192
  };
5199
5193
  class ClassPattern extends Rule {
5200
5194
  constructor(options) {
5201
- super({ ...defaults$o, ...options });
5195
+ super({ ...defaults$n, ...options });
5202
5196
  this.pattern = parsePattern(this.options.pattern);
5203
5197
  }
5204
5198
  static schema() {
@@ -5307,13 +5301,13 @@ class CloseOrder extends Rule {
5307
5301
  }
5308
5302
  }
5309
5303
 
5310
- const defaults$n = {
5304
+ const defaults$m = {
5311
5305
  include: null,
5312
5306
  exclude: null,
5313
5307
  };
5314
5308
  class Deprecated extends Rule {
5315
5309
  constructor(options) {
5316
- super({ ...defaults$n, ...options });
5310
+ super({ ...defaults$m, ...options });
5317
5311
  }
5318
5312
  static schema() {
5319
5313
  return {
@@ -5476,12 +5470,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
5476
5470
  }
5477
5471
  };
5478
5472
 
5479
- const defaults$m = {
5473
+ const defaults$l = {
5480
5474
  style: "uppercase",
5481
5475
  };
5482
5476
  class DoctypeStyle extends Rule {
5483
5477
  constructor(options) {
5484
- super({ ...defaults$m, ...options });
5478
+ super({ ...defaults$l, ...options });
5485
5479
  }
5486
5480
  static schema() {
5487
5481
  return {
@@ -5513,12 +5507,12 @@ class DoctypeStyle extends Rule {
5513
5507
  }
5514
5508
  }
5515
5509
 
5516
- const defaults$l = {
5510
+ const defaults$k = {
5517
5511
  style: "lowercase",
5518
5512
  };
5519
5513
  class ElementCase extends Rule {
5520
5514
  constructor(options) {
5521
- super({ ...defaults$l, ...options });
5515
+ super({ ...defaults$k, ...options });
5522
5516
  this.style = new CaseStyle(this.options.style, "element-case");
5523
5517
  }
5524
5518
  static schema() {
@@ -5584,14 +5578,14 @@ class ElementCase extends Rule {
5584
5578
  }
5585
5579
  }
5586
5580
 
5587
- const defaults$k = {
5581
+ const defaults$j = {
5588
5582
  pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
5589
5583
  whitelist: [],
5590
5584
  blacklist: [],
5591
5585
  };
5592
5586
  class ElementName extends Rule {
5593
5587
  constructor(options) {
5594
- super({ ...defaults$k, ...options });
5588
+ super({ ...defaults$j, ...options });
5595
5589
  /* eslint-disable-next-line security/detect-non-literal-regexp -- expected to be a regexp */
5596
5590
  this.pattern = new RegExp(this.options.pattern);
5597
5591
  }
@@ -5632,7 +5626,7 @@ class ElementName extends Rule {
5632
5626
  ...context.blacklist.map((cur) => `- ${cur}`),
5633
5627
  ];
5634
5628
  }
5635
- if (context.pattern !== defaults$k.pattern) {
5629
+ if (context.pattern !== defaults$j.pattern) {
5636
5630
  return [
5637
5631
  `<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
5638
5632
  "",
@@ -5868,7 +5862,7 @@ function isCategoryOrTag(value) {
5868
5862
  return typeof value === "string";
5869
5863
  }
5870
5864
  function isCategory$1(value) {
5871
- return value[0] === "@";
5865
+ return value.startsWith("@");
5872
5866
  }
5873
5867
  function formatCategoryOrTag(value) {
5874
5868
  return isCategory$1(value) ? value.slice(1) : `<${value}>`;
@@ -6048,7 +6042,7 @@ class ElementRequiredAttributes extends Rule {
6048
6042
  }
6049
6043
 
6050
6044
  function isCategory(value) {
6051
- return value[0] === "@";
6045
+ return value.startsWith("@");
6052
6046
  }
6053
6047
  class ElementRequiredContent extends Rule {
6054
6048
  documentation(context) {
@@ -6176,7 +6170,7 @@ class EmptyTitle extends Rule {
6176
6170
  }
6177
6171
  }
6178
6172
 
6179
- const defaults$j = {
6173
+ const defaults$i = {
6180
6174
  allowArrayBrackets: true,
6181
6175
  shared: ["radio", "button", "reset", "submit"],
6182
6176
  };
@@ -6209,7 +6203,7 @@ function getDocumentation(context) {
6209
6203
  }
6210
6204
  class FormDupName extends Rule {
6211
6205
  constructor(options) {
6212
- super({ ...defaults$j, ...options });
6206
+ super({ ...defaults$i, ...options });
6213
6207
  }
6214
6208
  static schema() {
6215
6209
  return {
@@ -6369,7 +6363,7 @@ class FormDupName extends Rule {
6369
6363
  }
6370
6364
  }
6371
6365
 
6372
- const defaults$i = {
6366
+ const defaults$h = {
6373
6367
  allowMultipleH1: false,
6374
6368
  minInitialRank: "h1",
6375
6369
  sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]'],
@@ -6400,7 +6394,7 @@ function parseMaxInitial(value) {
6400
6394
  }
6401
6395
  class HeadingLevel extends Rule {
6402
6396
  constructor(options) {
6403
- super({ ...defaults$i, ...options });
6397
+ super({ ...defaults$h, ...options });
6404
6398
  this.stack = [];
6405
6399
  this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
6406
6400
  this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
@@ -6442,9 +6436,15 @@ class HeadingLevel extends Rule {
6442
6436
  };
6443
6437
  }
6444
6438
  setup() {
6445
- this.on("tag:start", isRelevant$3, (event) => this.onTagStart(event));
6446
- this.on("tag:ready", (event) => this.onTagReady(event));
6447
- this.on("tag:close", (event) => this.onTagClose(event));
6439
+ this.on("tag:start", isRelevant$3, (event) => {
6440
+ this.onTagStart(event);
6441
+ });
6442
+ this.on("tag:ready", (event) => {
6443
+ this.onTagReady(event);
6444
+ });
6445
+ this.on("tag:close", (event) => {
6446
+ this.onTagClose(event);
6447
+ });
6448
6448
  }
6449
6449
  onTagStart(event) {
6450
6450
  /* extract heading level from tagName (e.g "h1" -> 1)*/
@@ -6558,12 +6558,12 @@ class HeadingLevel extends Rule {
6558
6558
  }
6559
6559
  }
6560
6560
 
6561
- const defaults$h = {
6561
+ const defaults$g = {
6562
6562
  pattern: "kebabcase",
6563
6563
  };
6564
6564
  class IdPattern extends Rule {
6565
6565
  constructor(options) {
6566
- super({ ...defaults$h, ...options });
6566
+ super({ ...defaults$g, ...options });
6567
6567
  this.pattern = parsePattern(this.options.pattern);
6568
6568
  }
6569
6569
  static schema() {
@@ -6965,12 +6965,12 @@ function findLabelByParent(el) {
6965
6965
  return [];
6966
6966
  }
6967
6967
 
6968
- const defaults$g = {
6968
+ const defaults$f = {
6969
6969
  maxlength: 70,
6970
6970
  };
6971
6971
  class LongTitle extends Rule {
6972
6972
  constructor(options) {
6973
- super({ ...defaults$g, ...options });
6973
+ super({ ...defaults$f, ...options });
6974
6974
  this.maxlength = this.options.maxlength;
6975
6975
  }
6976
6976
  static schema() {
@@ -7196,13 +7196,13 @@ class MultipleLabeledControls extends Rule {
7196
7196
  }
7197
7197
  }
7198
7198
 
7199
- const defaults$f = {
7199
+ const defaults$e = {
7200
7200
  include: null,
7201
7201
  exclude: null,
7202
7202
  };
7203
7203
  class NoAutoplay extends Rule {
7204
7204
  constructor(options) {
7205
- super({ ...defaults$f, ...options });
7205
+ super({ ...defaults$e, ...options });
7206
7206
  }
7207
7207
  documentation(context) {
7208
7208
  const tagName = context ? ` on <${context.tagName}>` : "";
@@ -7443,14 +7443,14 @@ Omitted end tags can be ambigious for humans to read and many editors have troub
7443
7443
  }
7444
7444
  }
7445
7445
 
7446
- const defaults$e = {
7446
+ const defaults$d = {
7447
7447
  include: null,
7448
7448
  exclude: null,
7449
7449
  allowedProperties: ["display"],
7450
7450
  };
7451
7451
  class NoInlineStyle extends Rule {
7452
7452
  constructor(options) {
7453
- super({ ...defaults$e, ...options });
7453
+ super({ ...defaults$d, ...options });
7454
7454
  }
7455
7455
  static schema() {
7456
7456
  return {
@@ -7652,7 +7652,7 @@ class NoMultipleMain extends Rule {
7652
7652
  }
7653
7653
  }
7654
7654
 
7655
- const defaults$d = {
7655
+ const defaults$c = {
7656
7656
  relaxed: false,
7657
7657
  };
7658
7658
  const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
@@ -7669,7 +7669,7 @@ const replacementTable = {
7669
7669
  };
7670
7670
  class NoRawCharacters extends Rule {
7671
7671
  constructor(options) {
7672
- super({ ...defaults$d, ...options });
7672
+ super({ ...defaults$c, ...options });
7673
7673
  this.relaxed = this.options.relaxed;
7674
7674
  }
7675
7675
  static schema() {
@@ -7743,6 +7743,39 @@ class NoRawCharacters extends Rule {
7743
7743
  }
7744
7744
  }
7745
7745
 
7746
+ const selectors = ["input[aria-label]", "textarea[aria-label]", "select[aria-label]"];
7747
+ class NoRedundantAriaLabel extends Rule {
7748
+ documentation() {
7749
+ return {
7750
+ description: "`aria-label` is redundant when an associated `<label>` element containing the same text exists.",
7751
+ url: "https://html-validate.org/rules/no-redundant-aria-label.html",
7752
+ };
7753
+ }
7754
+ setup() {
7755
+ this.on("dom:ready", (event) => {
7756
+ const { document } = event;
7757
+ const elements = document.querySelectorAll(selectors.join(","));
7758
+ for (const element of elements) {
7759
+ const ariaLabel = element.getAttribute("aria-label");
7760
+ const id = element.id;
7761
+ if (!id) {
7762
+ continue;
7763
+ }
7764
+ const label = document.querySelector(`label[for="${id}"]`);
7765
+ if (!ariaLabel || !label || label.textContent.trim() !== ariaLabel.value) {
7766
+ continue;
7767
+ }
7768
+ const message = "aria-label is redundant when label containing same text exists";
7769
+ this.report({
7770
+ message,
7771
+ node: element,
7772
+ location: ariaLabel.keyLocation,
7773
+ });
7774
+ }
7775
+ });
7776
+ }
7777
+ }
7778
+
7746
7779
  class NoRedundantFor extends Rule {
7747
7780
  documentation() {
7748
7781
  return {
@@ -7847,13 +7880,13 @@ class NoRedundantRole extends Rule {
7847
7880
  }
7848
7881
 
7849
7882
  const xmlns = /^(.+):.+$/;
7850
- const defaults$c = {
7883
+ const defaults$b = {
7851
7884
  ignoreForeign: true,
7852
7885
  ignoreXML: true,
7853
7886
  };
7854
7887
  class NoSelfClosing extends Rule {
7855
7888
  constructor(options) {
7856
- super({ ...defaults$c, ...options });
7889
+ super({ ...defaults$b, ...options });
7857
7890
  }
7858
7891
  static schema() {
7859
7892
  return {
@@ -7942,13 +7975,13 @@ class NoTrailingWhitespace extends Rule {
7942
7975
  }
7943
7976
  }
7944
7977
 
7945
- const defaults$b = {
7978
+ const defaults$a = {
7946
7979
  include: null,
7947
7980
  exclude: null,
7948
7981
  };
7949
7982
  class NoUnknownElements extends Rule {
7950
7983
  constructor(options) {
7951
- super({ ...defaults$b, ...options });
7984
+ super({ ...defaults$a, ...options });
7952
7985
  }
7953
7986
  static schema() {
7954
7987
  return {
@@ -8004,9 +8037,7 @@ class NoUnknownElements extends Rule {
8004
8037
  class NoUnusedDisable extends Rule {
8005
8038
  documentation(context) {
8006
8039
  return {
8007
- description: context
8008
- ? `\`${context.ruleId}\` rule is disabled but no error was reported.`
8009
- : "Rule is disabled but no error was reported.",
8040
+ description: `\`${context.ruleId}\` rule is disabled but no error was reported.`,
8010
8041
  url: "https://html-validate.org/rules/no-unused-disable.html",
8011
8042
  };
8012
8043
  }
@@ -8060,13 +8091,13 @@ const replacement = {
8060
8091
  reset: '<button type="reset">',
8061
8092
  image: '<button type="button">',
8062
8093
  };
8063
- const defaults$a = {
8094
+ const defaults$9 = {
8064
8095
  include: null,
8065
8096
  exclude: null,
8066
8097
  };
8067
8098
  class PreferButton extends Rule {
8068
8099
  constructor(options) {
8069
- super({ ...defaults$a, ...options });
8100
+ super({ ...defaults$9, ...options });
8070
8101
  }
8071
8102
  static schema() {
8072
8103
  return {
@@ -8141,7 +8172,7 @@ class PreferButton extends Rule {
8141
8172
  }
8142
8173
  }
8143
8174
 
8144
- const defaults$9 = {
8175
+ const defaults$8 = {
8145
8176
  mapping: {
8146
8177
  article: "article",
8147
8178
  banner: "header",
@@ -8171,7 +8202,7 @@ const defaults$9 = {
8171
8202
  };
8172
8203
  class PreferNativeElement extends Rule {
8173
8204
  constructor(options) {
8174
- super({ ...defaults$9, ...options });
8205
+ super({ ...defaults$8, ...options });
8175
8206
  }
8176
8207
  static schema() {
8177
8208
  return {
@@ -8291,12 +8322,12 @@ class PreferTbody extends Rule {
8291
8322
  }
8292
8323
  }
8293
8324
 
8294
- const defaults$8 = {
8325
+ const defaults$7 = {
8295
8326
  tags: ["script", "style"],
8296
8327
  };
8297
8328
  class RequireCSPNonce extends Rule {
8298
8329
  constructor(options) {
8299
- super({ ...defaults$8, ...options });
8330
+ super({ ...defaults$7, ...options });
8300
8331
  }
8301
8332
  static schema() {
8302
8333
  return {
@@ -8347,7 +8378,7 @@ class RequireCSPNonce extends Rule {
8347
8378
  }
8348
8379
  }
8349
8380
 
8350
- const defaults$7 = {
8381
+ const defaults$6 = {
8351
8382
  target: "all",
8352
8383
  include: null,
8353
8384
  exclude: null,
@@ -8359,7 +8390,7 @@ const supportSri = {
8359
8390
  };
8360
8391
  class RequireSri extends Rule {
8361
8392
  constructor(options) {
8362
- super({ ...defaults$7, ...options });
8393
+ super({ ...defaults$6, ...options });
8363
8394
  this.target = this.options.target;
8364
8395
  }
8365
8396
  static schema() {
@@ -8521,7 +8552,7 @@ class SvgFocusable extends Rule {
8521
8552
  }
8522
8553
  }
8523
8554
 
8524
- const defaults$6 = {
8555
+ const defaults$5 = {
8525
8556
  characters: [
8526
8557
  { pattern: " ", replacement: "&nbsp;", description: "non-breaking space" },
8527
8558
  { pattern: "-", replacement: "&#8209;", description: "non-breaking hyphen" },
@@ -8560,7 +8591,7 @@ function matchAll(text, regexp) {
8560
8591
  }
8561
8592
  class TelNonBreaking extends Rule {
8562
8593
  constructor(options) {
8563
- super({ ...defaults$6, ...options });
8594
+ super({ ...defaults$5, ...options });
8564
8595
  this.regex = constructRegex(this.options.characters);
8565
8596
  }
8566
8597
  static schema() {
@@ -8601,9 +8632,7 @@ class TelNonBreaking extends Rule {
8601
8632
  });
8602
8633
  return {
8603
8634
  description: [
8604
- context
8605
- ? `The \`${context.pattern}\` character should be replaced with \`${context.replacement}\` character (${context.description}) when used in a telephone number.`
8606
- : `Replace this character with a non-breaking version.`,
8635
+ `The \`${context.pattern}\` character should be replaced with \`${context.replacement}\` character (${context.description}) when used in a telephone number.`,
8607
8636
  "",
8608
8637
  "Unless non-breaking characters is used there could be a line break inserted at that character.",
8609
8638
  "Line breaks make is harder to read and understand the telephone number.",
@@ -8848,7 +8877,7 @@ class TextContent extends Rule {
8848
8877
  }
8849
8878
  }
8850
8879
 
8851
- const defaults$5 = {
8880
+ const defaults$4 = {
8852
8881
  ignoreCase: false,
8853
8882
  requireSemicolon: true,
8854
8883
  };
@@ -8866,16 +8895,11 @@ function getLocation(location, entity, match) {
8866
8895
  function getDescription(context, options) {
8867
8896
  const url = "https://html.spec.whatwg.org/multipage/named-characters.html";
8868
8897
  let message;
8869
- if (context) {
8870
- if (context.terminated) {
8871
- message = `Unrecognized character reference \`${context.entity}\`.`;
8872
- }
8873
- else {
8874
- message = `Character reference \`${context.entity}\` must be terminated by a semicolon.`;
8875
- }
8898
+ if (context.terminated) {
8899
+ message = `Unrecognized character reference \`${context.entity}\`.`;
8876
8900
  }
8877
8901
  else {
8878
- message = `Unrecognized character reference.`;
8902
+ message = `Character reference \`${context.entity}\` must be terminated by a semicolon.`;
8879
8903
  }
8880
8904
  return [
8881
8905
  message,
@@ -8890,7 +8914,7 @@ function getDescription(context, options) {
8890
8914
  }
8891
8915
  class UnknownCharReference extends Rule {
8892
8916
  constructor(options) {
8893
- super({ ...defaults$5, ...options });
8917
+ super({ ...defaults$4, ...options });
8894
8918
  }
8895
8919
  static schema() {
8896
8920
  return {
@@ -9007,12 +9031,12 @@ var RuleContext;
9007
9031
  RuleContext[RuleContext["LEADING_CHARACTER"] = 3] = "LEADING_CHARACTER";
9008
9032
  RuleContext[RuleContext["DISALLOWED_CHARACTER"] = 4] = "DISALLOWED_CHARACTER";
9009
9033
  })(RuleContext || (RuleContext = {}));
9010
- const defaults$4 = {
9034
+ const defaults$3 = {
9011
9035
  relaxed: false,
9012
9036
  };
9013
9037
  class ValidID extends Rule {
9014
9038
  constructor(options) {
9015
- super({ ...defaults$4, ...options });
9039
+ super({ ...defaults$3, ...options });
9016
9040
  }
9017
9041
  static schema() {
9018
9042
  return {
@@ -9023,9 +9047,9 @@ class ValidID extends Rule {
9023
9047
  }
9024
9048
  documentation(context) {
9025
9049
  const { relaxed } = this.options;
9026
- const message = context
9027
- ? this.messages[context].replace("id", "ID").replace(/^(.)/, (m) => m.toUpperCase())
9028
- : "Element ID is not valid";
9050
+ const message = this.messages[context]
9051
+ .replace("id", "ID")
9052
+ .replace(/^(.)/, (m) => m.toUpperCase());
9029
9053
  const relaxedDescription = relaxed
9030
9054
  ? []
9031
9055
  : [
@@ -9121,12 +9145,12 @@ var Style;
9121
9145
  Style[Style["AlwaysOmit"] = 1] = "AlwaysOmit";
9122
9146
  Style[Style["AlwaysSelfclose"] = 2] = "AlwaysSelfclose";
9123
9147
  })(Style || (Style = {}));
9124
- const defaults$3 = {
9148
+ const defaults$2 = {
9125
9149
  style: "omit",
9126
9150
  };
9127
9151
  class VoidStyle extends Rule {
9128
9152
  constructor(options) {
9129
- super({ ...defaults$3, ...options });
9153
+ super({ ...defaults$2, ...options });
9130
9154
  this.style = parseStyle(this.options.style);
9131
9155
  }
9132
9156
  static schema() {
@@ -9323,7 +9347,7 @@ class H36 extends Rule {
9323
9347
  }
9324
9348
  }
9325
9349
 
9326
- const defaults$2 = {
9350
+ const defaults$1 = {
9327
9351
  allowEmpty: true,
9328
9352
  alias: [],
9329
9353
  };
@@ -9344,7 +9368,7 @@ function getTag(node) {
9344
9368
  }
9345
9369
  class H37 extends Rule {
9346
9370
  constructor(options) {
9347
- super({ ...defaults$2, ...options });
9371
+ super({ ...defaults$1, ...options });
9348
9372
  /* ensure alias is array */
9349
9373
  if (!Array.isArray(this.options.alias)) {
9350
9374
  this.options.alias = [this.options.alias];
@@ -9570,6 +9594,7 @@ const bundledRules = {
9570
9594
  "no-missing-references": NoMissingReferences,
9571
9595
  "no-multiple-main": NoMultipleMain,
9572
9596
  "no-raw-characters": NoRawCharacters,
9597
+ "no-redundant-aria-label": NoRedundantAriaLabel,
9573
9598
  "no-redundant-for": NoRedundantFor,
9574
9599
  "no-redundant-role": NoRedundantRole,
9575
9600
  "no-self-closing": NoSelfClosing,
@@ -9610,6 +9635,7 @@ const config$4 = {
9610
9635
  "multiple-labeled-controls": "error",
9611
9636
  "no-autoplay": ["error", { include: ["audio", "video"] }],
9612
9637
  "no-dup-id": "error",
9638
+ "no-redundant-aria-label": "error",
9613
9639
  "no-redundant-for": "error",
9614
9640
  "no-redundant-role": "error",
9615
9641
  "prefer-native-element": "error",
@@ -9692,6 +9718,7 @@ const config$1 = {
9692
9718
  "no-inline-style": "error",
9693
9719
  "no-multiple-main": "error",
9694
9720
  "no-raw-characters": "error",
9721
+ "no-redundant-aria-label": "error",
9695
9722
  "no-redundant-for": "error",
9696
9723
  "no-redundant-role": "error",
9697
9724
  "no-self-closing": "error",
@@ -10156,8 +10183,7 @@ class Config {
10156
10183
  return this.config;
10157
10184
  }
10158
10185
  let base = {};
10159
- for (let i = 0; i < entries.length; i++) {
10160
- const entry = entries[i];
10186
+ for (const entry of entries) {
10161
10187
  let extended;
10162
10188
  if (this.configurations.has(entry)) {
10163
10189
  extended = this.configurations.get(entry);
@@ -11449,7 +11475,9 @@ class Engine {
11449
11475
  else {
11450
11476
  lines.push("(root)");
11451
11477
  }
11452
- node.childElements.forEach((child, index) => writeNode(child, level + 1, index));
11478
+ node.childElements.forEach((child, index) => {
11479
+ writeNode(child, level + 1, index);
11480
+ });
11453
11481
  }
11454
11482
  writeNode(document, 0, 0);
11455
11483
  return lines;
@@ -12133,7 +12161,7 @@ class HtmlValidate {
12133
12161
  /** @public */
12134
12162
  const name = "html-validate";
12135
12163
  /** @public */
12136
- const version = "8.0.5";
12164
+ const version = "8.1.0";
12137
12165
  /** @public */
12138
12166
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
12139
12167
 
@@ -12146,61 +12174,6 @@ function definePlugin(plugin) {
12146
12174
  return plugin;
12147
12175
  }
12148
12176
 
12149
- const defaults$1 = {
12150
- silent: false,
12151
- version,
12152
- logger(text) {
12153
- /* eslint-disable-next-line no-console -- expected to log */
12154
- console.error(kleur.red(text));
12155
- },
12156
- };
12157
- /**
12158
- * Tests if plugin is compatible with html-validate library. Unless the `silent`
12159
- * option is used a warning is displayed on the console.
12160
- *
12161
- * @public
12162
- * @since v5.0.0
12163
- * @param name - Name of plugin
12164
- * @param declared - What library versions the plugin support (e.g. declared peerDependencies)
12165
- * @returns - `true` if version is compatible
12166
- */
12167
- function compatibilityCheck(name, declared, options) {
12168
- const { silent, version: current, logger } = { ...defaults$1, ...options };
12169
- const valid = semver.satisfies(current, declared);
12170
- if (valid || silent) {
12171
- return valid;
12172
- }
12173
- const text = [
12174
- "-----------------------------------------------------------------------------------------------------",
12175
- `${name} requires html-validate version "${declared}" but current installed version is ${current}`,
12176
- "This is not a supported configuration. Please install a supported version before reporting bugs.",
12177
- "-----------------------------------------------------------------------------------------------------",
12178
- ].join("\n");
12179
- logger(text);
12180
- return false;
12181
- }
12182
-
12183
- /**
12184
- * Similar to `require(..)` but removes the cached copy first.
12185
- */
12186
- function requireUncached(require, moduleId) {
12187
- const filename = require.resolve(moduleId);
12188
- /* remove references from the parent module to prevent memory leak */
12189
- const m = require.cache[filename];
12190
- if (m && m.parent) {
12191
- const { parent } = m;
12192
- for (let i = parent.children.length - 1; i >= 0; i--) {
12193
- if (parent.children[i].id === filename) {
12194
- parent.children.splice(i, 1);
12195
- }
12196
- }
12197
- }
12198
- /* remove old module from cache */
12199
- delete require.cache[filename];
12200
- /* eslint-disable-next-line import/no-dynamic-require, security/detect-non-literal-require -- as expected but should be moved to upcoming resolver class */
12201
- return require(filename);
12202
- }
12203
-
12204
12177
  const ruleIds = new Set(Object.keys(rules));
12205
12178
  /**
12206
12179
  * Returns true if given ruleId is an existing builtin rule. It does not handle
@@ -12467,5 +12440,24 @@ function getFormatter(name) {
12467
12440
  return (_a = availableFormatters[name]) !== null && _a !== void 0 ? _a : null;
12468
12441
  }
12469
12442
 
12470
- export { Attribute as A, codeframe as B, Config as C, DynamicValue as D, EventHandler as E, requireUncached as F, name as G, HtmlValidate as H, bugs as I, MetaTable as M, NodeClosed as N, Presets as P, ResolvedConfig as R, Severity as S, TextNode as T, UserError as U, Validator as V, WrappedError as W, ConfigError as a, ConfigLoader as b, StaticConfigLoader as c, DOMTokenList as d, HtmlElement as e, DOMNode as f, DOMTree as g, NodeType as h, SchemaValidationError as i, NestedError as j, TextContent$1 as k, MetaCopyableProperty as l, Rule as m, TextClassification as n, classifyNodeText as o, keywordPatternMatcher as p, sliceLocation as q, Reporter as r, staticResolver as s, definePlugin as t, Parser as u, version as v, ruleExists as w, getFormatter as x, ensureError as y, compatibilityCheck as z };
12443
+ /**
12444
+ * @internal
12445
+ */
12446
+ function compatibilityCheckImpl(name, declared, options) {
12447
+ const { silent, version: current, logger } = options;
12448
+ const valid = semver.satisfies(current, declared);
12449
+ if (valid || silent) {
12450
+ return valid;
12451
+ }
12452
+ const text = [
12453
+ "-----------------------------------------------------------------------------------------------------",
12454
+ `${name} requires html-validate version "${declared}" but current installed version is ${current}`,
12455
+ "This is not a supported configuration. Please install a supported version before reporting bugs.",
12456
+ "-----------------------------------------------------------------------------------------------------",
12457
+ ].join("\n");
12458
+ logger(text);
12459
+ return false;
12460
+ }
12461
+
12462
+ export { Attribute as A, codeframe as B, Config as C, DynamicValue as D, EventHandler as E, name as F, bugs as G, HtmlValidate as H, MetaTable as M, NodeClosed as N, Presets as P, ResolvedConfig as R, Severity as S, TextNode as T, UserError as U, Validator as V, WrappedError as W, ConfigError as a, ConfigLoader as b, StaticConfigLoader as c, DOMTokenList as d, ensureError as e, HtmlElement as f, getFormatter as g, DOMNode as h, DOMTree as i, NodeType as j, SchemaValidationError as k, NestedError as l, TextContent$1 as m, MetaCopyableProperty as n, Rule as o, TextClassification as p, classifyNodeText as q, keywordPatternMatcher as r, staticResolver as s, sliceLocation as t, Reporter as u, version as v, definePlugin as w, Parser as x, ruleExists as y, compatibilityCheckImpl as z };
12471
12463
  //# sourceMappingURL=core.js.map