html-validate 8.16.0 → 8.17.1

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.
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.42.3"
8
+ "packageVersion": "7.43.0"
9
9
  }
10
10
  ]
11
11
  }
package/dist/es/core.js CHANGED
@@ -1390,10 +1390,14 @@ function expandRegexValue(value) {
1390
1390
  if (value instanceof RegExp) {
1391
1391
  return value;
1392
1392
  }
1393
- const match = value.match(/^\/\^?([^/$]*)\$?\/([i]*)$/);
1393
+ const match = value.match(/^\/(.*(?=\/))\/(i?)$/);
1394
1394
  if (match) {
1395
1395
  const [, expr, flags] = match;
1396
- return new RegExp(`^${expr}$`, flags);
1396
+ if (expr.startsWith("^") || expr.endsWith("$")) {
1397
+ return new RegExp(expr, flags);
1398
+ } else {
1399
+ return new RegExp(`^${expr}$`, flags);
1400
+ }
1397
1401
  } else {
1398
1402
  return value;
1399
1403
  }
@@ -3431,13 +3435,13 @@ function inAccessibilityTree(node) {
3431
3435
  return true;
3432
3436
  }
3433
3437
  function isAriaHiddenImpl(node) {
3434
- const isHidden = (node2) => {
3438
+ const getAriaHiddenAttr = (node2) => {
3435
3439
  const ariaHidden = node2.getAttribute("aria-hidden");
3436
3440
  return Boolean(ariaHidden && ariaHidden.value === "true");
3437
3441
  };
3438
3442
  return {
3439
3443
  byParent: node.parent ? isAriaHidden(node.parent) : false,
3440
- bySelf: isHidden(node)
3444
+ bySelf: getAriaHiddenAttr(node)
3441
3445
  };
3442
3446
  }
3443
3447
  function isAriaHidden(node, details) {
@@ -3449,13 +3453,13 @@ function isAriaHidden(node, details) {
3449
3453
  return details ? result : result.byParent || result.bySelf;
3450
3454
  }
3451
3455
  function isHTMLHiddenImpl(node) {
3452
- const isHidden = (node2) => {
3456
+ const getHiddenAttr = (node2) => {
3453
3457
  const hidden = node2.getAttribute("hidden");
3454
3458
  return hidden !== null && hidden.isStatic;
3455
3459
  };
3456
3460
  return {
3457
3461
  byParent: node.parent ? isHTMLHidden(node.parent) : false,
3458
- bySelf: isHidden(node)
3462
+ bySelf: getHiddenAttr(node)
3459
3463
  };
3460
3464
  }
3461
3465
  function isHTMLHidden(node, details) {
@@ -3467,13 +3471,13 @@ function isHTMLHidden(node, details) {
3467
3471
  return details ? result : result.byParent || result.bySelf;
3468
3472
  }
3469
3473
  function isInertImpl(node) {
3470
- const isInert2 = (node2) => {
3474
+ const getInertAttr = (node2) => {
3471
3475
  const inert = node2.getAttribute("inert");
3472
3476
  return inert !== null && inert.isStatic;
3473
3477
  };
3474
3478
  return {
3475
- byParent: node.parent ? isInert2(node.parent) : false,
3476
- bySelf: isInert2(node)
3479
+ byParent: node.parent ? isInert(node.parent) : false,
3480
+ bySelf: getInertAttr(node)
3477
3481
  };
3478
3482
  }
3479
3483
  function isInert(node, details) {
@@ -3485,13 +3489,13 @@ function isInert(node, details) {
3485
3489
  return details ? result : result.byParent || result.bySelf;
3486
3490
  }
3487
3491
  function isStyleHiddenImpl(node) {
3488
- const isHidden = (node2) => {
3492
+ const getStyleAttr = (node2) => {
3489
3493
  const style = node2.getAttribute("style");
3490
3494
  const { display, visibility } = parseCssDeclaration(style == null ? void 0 : style.value);
3491
3495
  return display === "none" || visibility === "hidden";
3492
3496
  };
3493
3497
  const byParent = node.parent ? isStyleHidden(node.parent) : false;
3494
- const bySelf = isHidden(node);
3498
+ const bySelf = getStyleAttr(node);
3495
3499
  return byParent || bySelf;
3496
3500
  }
3497
3501
  function isStyleHidden(node) {
@@ -3909,7 +3913,7 @@ class Rule {
3909
3913
  }
3910
3914
  }
3911
3915
 
3912
- const defaults$w = {
3916
+ const defaults$x = {
3913
3917
  allowExternal: true,
3914
3918
  allowRelative: true,
3915
3919
  allowAbsolute: true,
@@ -3950,7 +3954,7 @@ function matchList(value, list) {
3950
3954
  }
3951
3955
  class AllowedLinks extends Rule {
3952
3956
  constructor(options) {
3953
- super({ ...defaults$w, ...options });
3957
+ super({ ...defaults$x, ...options });
3954
3958
  this.allowExternal = parseAllow(this.options.allowExternal);
3955
3959
  this.allowRelative = parseAllow(this.options.allowRelative);
3956
3960
  this.allowAbsolute = parseAllow(this.options.allowAbsolute);
@@ -4114,7 +4118,7 @@ class AllowedLinks extends Rule {
4114
4118
  }
4115
4119
  }
4116
4120
 
4117
- const defaults$v = {
4121
+ const defaults$w = {
4118
4122
  accessible: true
4119
4123
  };
4120
4124
  function findByTarget(target, siblings) {
@@ -4144,7 +4148,7 @@ function getDescription$1(context) {
4144
4148
  }
4145
4149
  class AreaAlt extends Rule {
4146
4150
  constructor(options) {
4147
- super({ ...defaults$v, ...options });
4151
+ super({ ...defaults$w, ...options });
4148
4152
  }
4149
4153
  static schema() {
4150
4154
  return {
@@ -4223,7 +4227,7 @@ class AriaHiddenBody extends Rule {
4223
4227
  }
4224
4228
  }
4225
4229
 
4226
- const defaults$u = {
4230
+ const defaults$v = {
4227
4231
  allowAnyNamable: false
4228
4232
  };
4229
4233
  const whitelisted = [
@@ -4265,7 +4269,7 @@ function isValidUsage(target, meta) {
4265
4269
  }
4266
4270
  class AriaLabelMisuse extends Rule {
4267
4271
  constructor(options) {
4268
- super({ ...defaults$u, ...options });
4272
+ super({ ...defaults$v, ...options });
4269
4273
  }
4270
4274
  documentation() {
4271
4275
  const valid = [
@@ -4375,13 +4379,13 @@ class CaseStyle {
4375
4379
  }
4376
4380
  }
4377
4381
 
4378
- const defaults$t = {
4382
+ const defaults$u = {
4379
4383
  style: "lowercase",
4380
4384
  ignoreForeign: true
4381
4385
  };
4382
4386
  class AttrCase extends Rule {
4383
4387
  constructor(options) {
4384
- super({ ...defaults$t, ...options });
4388
+ super({ ...defaults$u, ...options });
4385
4389
  this.style = new CaseStyle(this.options.style, "attr-case");
4386
4390
  }
4387
4391
  static schema() {
@@ -4737,7 +4741,7 @@ class AttrDelimiter extends Rule {
4737
4741
  }
4738
4742
 
4739
4743
  const DEFAULT_PATTERN = "[a-z0-9-:]+";
4740
- const defaults$s = {
4744
+ const defaults$t = {
4741
4745
  pattern: DEFAULT_PATTERN,
4742
4746
  ignoreForeign: true
4743
4747
  };
@@ -4769,7 +4773,7 @@ function generateDescription(name, pattern) {
4769
4773
  }
4770
4774
  class AttrPattern extends Rule {
4771
4775
  constructor(options) {
4772
- super({ ...defaults$s, ...options });
4776
+ super({ ...defaults$t, ...options });
4773
4777
  this.pattern = generateRegexp(this.options.pattern);
4774
4778
  }
4775
4779
  static schema() {
@@ -4816,7 +4820,7 @@ class AttrPattern extends Rule {
4816
4820
  }
4817
4821
  }
4818
4822
 
4819
- const defaults$r = {
4823
+ const defaults$s = {
4820
4824
  style: "auto",
4821
4825
  unquoted: false
4822
4826
  };
@@ -4855,7 +4859,7 @@ function describeStyle(style, unquoted) {
4855
4859
  }
4856
4860
  class AttrQuotes extends Rule {
4857
4861
  constructor(options) {
4858
- super({ ...defaults$r, ...options });
4862
+ super({ ...defaults$s, ...options });
4859
4863
  this.style = parseStyle$3(this.options.style);
4860
4864
  }
4861
4865
  static schema() {
@@ -5039,12 +5043,12 @@ class AttributeAllowedValues extends Rule {
5039
5043
  }
5040
5044
  }
5041
5045
 
5042
- const defaults$q = {
5046
+ const defaults$r = {
5043
5047
  style: "omit"
5044
5048
  };
5045
5049
  class AttributeBooleanStyle extends Rule {
5046
5050
  constructor(options) {
5047
- super({ ...defaults$q, ...options });
5051
+ super({ ...defaults$r, ...options });
5048
5052
  this.hasInvalidStyle = parseStyle$2(this.options.style);
5049
5053
  }
5050
5054
  static schema() {
@@ -5111,12 +5115,12 @@ function reportMessage$1(attr, style) {
5111
5115
  return "";
5112
5116
  }
5113
5117
 
5114
- const defaults$p = {
5118
+ const defaults$q = {
5115
5119
  style: "omit"
5116
5120
  };
5117
5121
  class AttributeEmptyStyle extends Rule {
5118
5122
  constructor(options) {
5119
- super({ ...defaults$p, ...options });
5123
+ super({ ...defaults$q, ...options });
5120
5124
  this.hasInvalidStyle = parseStyle$1(this.options.style);
5121
5125
  }
5122
5126
  static schema() {
@@ -5234,64 +5238,95 @@ class AttributeMisuse extends Rule {
5234
5238
  function parsePattern(pattern) {
5235
5239
  switch (pattern) {
5236
5240
  case "kebabcase":
5237
- return /^[a-z0-9-]+$/;
5241
+ return { regexp: /^[a-z0-9-]+$/, description: pattern };
5238
5242
  case "camelcase":
5239
- return /^[a-z][a-zA-Z0-9]+$/;
5243
+ return { regexp: /^[a-z][a-zA-Z0-9]+$/, description: pattern };
5240
5244
  case "underscore":
5241
- return /^[a-z0-9_]+$/;
5242
- default:
5243
- return new RegExp(pattern);
5245
+ return { regexp: /^[a-z0-9_]+$/, description: pattern };
5246
+ default: {
5247
+ const regexp = new RegExp(pattern);
5248
+ return { regexp, description: regexp.toString() };
5249
+ }
5244
5250
  }
5245
5251
  }
5246
- function describePattern(pattern) {
5247
- const regexp = parsePattern(pattern).toString();
5248
- switch (pattern) {
5249
- case "kebabcase":
5250
- case "camelcase":
5251
- case "underscore": {
5252
- return `${regexp} (${pattern})`;
5252
+
5253
+ function toArray$1(value) {
5254
+ return Array.isArray(value) ? value : [value];
5255
+ }
5256
+ class BasePatternRule extends Rule {
5257
+ /**
5258
+ * @param attr - Attribute holding the value.
5259
+ * @param options - Rule options with defaults expanded.
5260
+ */
5261
+ constructor(attr, options) {
5262
+ super(options);
5263
+ const { pattern } = this.options;
5264
+ this.attr = attr;
5265
+ this.patterns = toArray$1(pattern).map((it) => parsePattern(it));
5266
+ }
5267
+ static schema() {
5268
+ return {
5269
+ pattern: {
5270
+ oneOf: [{ type: "array", items: { type: "string" }, minItems: 1 }, { type: "string" }]
5271
+ }
5272
+ };
5273
+ }
5274
+ description(context) {
5275
+ const { attr, patterns } = this;
5276
+ const { value } = context;
5277
+ const lead = patterns.length === 1 ? `The \`${attr}\` attribute value \`"${value}"\` does not match the configured pattern.` : `The \`${attr}\` attribute value \`"${value}"\` does not match either of the configured patterns.`;
5278
+ return [
5279
+ lead,
5280
+ "For consistency within the codebase the `${attr}` is required to match one or more of the following patterns:",
5281
+ "",
5282
+ ...patterns.map((it) => `- \`${it.description}\``)
5283
+ ].join("\n");
5284
+ }
5285
+ validateValue(node, value, location) {
5286
+ const { attr, patterns } = this;
5287
+ const matches = patterns.some((it) => it.regexp.test(value));
5288
+ if (matches) {
5289
+ return;
5253
5290
  }
5254
- default:
5255
- return regexp;
5291
+ const allowed = naturalJoin(patterns.map((it) => `"${it.description}"`));
5292
+ const message = patterns.length === 1 ? `${attr} "${value}" does not match the configured pattern ${allowed}` : `${attr} "${value}" does not match either of the configured patterns: ${allowed}`;
5293
+ this.report({
5294
+ node,
5295
+ message,
5296
+ location,
5297
+ context: {
5298
+ value
5299
+ }
5300
+ });
5256
5301
  }
5257
5302
  }
5258
5303
 
5259
- const defaults$o = {
5304
+ const defaults$p = {
5260
5305
  pattern: "kebabcase"
5261
5306
  };
5262
- class ClassPattern extends Rule {
5307
+ class ClassPattern extends BasePatternRule {
5263
5308
  constructor(options) {
5264
- super({ ...defaults$o, ...options });
5265
- this.pattern = parsePattern(this.options.pattern);
5309
+ super("class", { ...defaults$p, ...options });
5266
5310
  }
5267
5311
  static schema() {
5268
- return {
5269
- pattern: {
5270
- type: "string"
5271
- }
5272
- };
5312
+ return BasePatternRule.schema();
5273
5313
  }
5274
- documentation() {
5275
- const pattern = describePattern(this.options.pattern);
5314
+ documentation(context) {
5276
5315
  return {
5277
- description: `For consistency all classes are required to match the pattern ${pattern}.`,
5316
+ description: this.description(context),
5278
5317
  url: "https://html-validate.org/rules/class-pattern.html"
5279
5318
  };
5280
5319
  }
5281
5320
  setup() {
5282
5321
  this.on("attr", (event) => {
5283
- if (event.key.toLowerCase() !== "class") {
5322
+ const { target, key, value, valueLocation } = event;
5323
+ if (key.toLowerCase() !== "class") {
5284
5324
  return;
5285
5325
  }
5286
- const classes = new DOMTokenList(event.value, event.valueLocation);
5287
- classes.forEach((cur, index) => {
5288
- if (!cur.match(this.pattern)) {
5289
- const location = classes.location(index);
5290
- const pattern = this.pattern.toString();
5291
- const message = `Class "${cur}" does not match required pattern "${pattern}"`;
5292
- this.report(event.target, message, location);
5293
- }
5294
- });
5326
+ const classes = new DOMTokenList(value, valueLocation);
5327
+ for (const { item, location } of classes.iterator()) {
5328
+ this.validateValue(target, item, location);
5329
+ }
5295
5330
  });
5296
5331
  }
5297
5332
  }
@@ -5367,13 +5402,13 @@ class CloseOrder extends Rule {
5367
5402
  }
5368
5403
  }
5369
5404
 
5370
- const defaults$n = {
5405
+ const defaults$o = {
5371
5406
  include: null,
5372
5407
  exclude: null
5373
5408
  };
5374
5409
  class Deprecated extends Rule {
5375
5410
  constructor(options) {
5376
- super({ ...defaults$n, ...options });
5411
+ super({ ...defaults$o, ...options });
5377
5412
  }
5378
5413
  static schema() {
5379
5414
  return {
@@ -5527,12 +5562,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
5527
5562
  }
5528
5563
  };
5529
5564
 
5530
- const defaults$m = {
5565
+ const defaults$n = {
5531
5566
  style: "uppercase"
5532
5567
  };
5533
5568
  class DoctypeStyle extends Rule {
5534
5569
  constructor(options) {
5535
- super({ ...defaults$m, ...options });
5570
+ super({ ...defaults$n, ...options });
5536
5571
  }
5537
5572
  static schema() {
5538
5573
  return {
@@ -5560,12 +5595,12 @@ class DoctypeStyle extends Rule {
5560
5595
  }
5561
5596
  }
5562
5597
 
5563
- const defaults$l = {
5598
+ const defaults$m = {
5564
5599
  style: "lowercase"
5565
5600
  };
5566
5601
  class ElementCase extends Rule {
5567
5602
  constructor(options) {
5568
- super({ ...defaults$l, ...options });
5603
+ super({ ...defaults$m, ...options });
5569
5604
  this.style = new CaseStyle(this.options.style, "element-case");
5570
5605
  }
5571
5606
  static schema() {
@@ -5625,14 +5660,14 @@ class ElementCase extends Rule {
5625
5660
  }
5626
5661
  }
5627
5662
 
5628
- const defaults$k = {
5663
+ const defaults$l = {
5629
5664
  pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
5630
5665
  whitelist: [],
5631
5666
  blacklist: []
5632
5667
  };
5633
5668
  class ElementName extends Rule {
5634
5669
  constructor(options) {
5635
- super({ ...defaults$k, ...options });
5670
+ super({ ...defaults$l, ...options });
5636
5671
  this.pattern = new RegExp(this.options.pattern);
5637
5672
  }
5638
5673
  static schema() {
@@ -5669,7 +5704,7 @@ class ElementName extends Rule {
5669
5704
  ...context.blacklist.map((cur) => `- ${cur}`)
5670
5705
  ];
5671
5706
  }
5672
- if (context.pattern !== defaults$k.pattern) {
5707
+ if (context.pattern !== defaults$l.pattern) {
5673
5708
  return [
5674
5709
  `<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
5675
5710
  "",
@@ -6158,7 +6193,7 @@ class EmptyTitle extends Rule {
6158
6193
  }
6159
6194
  }
6160
6195
 
6161
- const defaults$j = {
6196
+ const defaults$k = {
6162
6197
  allowArrayBrackets: true,
6163
6198
  shared: ["radio", "button", "reset", "submit"]
6164
6199
  };
@@ -6186,7 +6221,7 @@ function getDocumentation(context) {
6186
6221
  }
6187
6222
  class FormDupName extends Rule {
6188
6223
  constructor(options) {
6189
- super({ ...defaults$j, ...options });
6224
+ super({ ...defaults$k, ...options });
6190
6225
  }
6191
6226
  static schema() {
6192
6227
  return {
@@ -6335,7 +6370,7 @@ class FormDupName extends Rule {
6335
6370
  }
6336
6371
  }
6337
6372
 
6338
- const defaults$i = {
6373
+ const defaults$j = {
6339
6374
  allowMultipleH1: false,
6340
6375
  minInitialRank: "h1",
6341
6376
  sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]']
@@ -6364,7 +6399,7 @@ function parseMaxInitial(value) {
6364
6399
  }
6365
6400
  class HeadingLevel extends Rule {
6366
6401
  constructor(options) {
6367
- super({ ...defaults$i, ...options });
6402
+ super({ ...defaults$j, ...options });
6368
6403
  this.stack = [];
6369
6404
  this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
6370
6405
  this.sectionRoots = this.options.sectioningRoots.map((it) => new Pattern(it));
@@ -6600,43 +6635,35 @@ class HiddenFocusable extends Rule {
6600
6635
  }
6601
6636
  }
6602
6637
 
6603
- const defaults$h = {
6638
+ const defaults$i = {
6604
6639
  pattern: "kebabcase"
6605
6640
  };
6606
- class IdPattern extends Rule {
6641
+ class IdPattern extends BasePatternRule {
6607
6642
  constructor(options) {
6608
- super({ ...defaults$h, ...options });
6609
- this.pattern = parsePattern(this.options.pattern);
6643
+ super("id", { ...defaults$i, ...options });
6610
6644
  }
6611
6645
  static schema() {
6612
- return {
6613
- pattern: {
6614
- type: "string"
6615
- }
6616
- };
6646
+ return BasePatternRule.schema();
6617
6647
  }
6618
- documentation() {
6619
- const pattern = describePattern(this.options.pattern);
6648
+ documentation(context) {
6620
6649
  return {
6621
- description: `For consistency all IDs are required to match the pattern ${pattern}.`,
6650
+ description: this.description(context),
6622
6651
  url: "https://html-validate.org/rules/id-pattern.html"
6623
6652
  };
6624
6653
  }
6625
6654
  setup() {
6626
6655
  this.on("attr", (event) => {
6627
- var _a;
6628
- if (event.key.toLowerCase() !== "id") {
6656
+ const { target, key, value, valueLocation } = event;
6657
+ if (key.toLowerCase() !== "id") {
6629
6658
  return;
6630
6659
  }
6631
- if (event.value instanceof DynamicValue) {
6660
+ if (value instanceof DynamicValue) {
6632
6661
  return;
6633
6662
  }
6634
- if (!((_a = event.value) == null ? void 0 : _a.match(this.pattern))) {
6635
- const value = event.value ?? "";
6636
- const pattern = this.pattern.toString();
6637
- const message = `ID "${value}" does not match required pattern "${pattern}"`;
6638
- this.report(event.target, message, event.valueLocation);
6663
+ if (value === null) {
6664
+ return;
6639
6665
  }
6666
+ this.validateValue(target, value, valueLocation);
6640
6667
  });
6641
6668
  }
6642
6669
  }
@@ -6875,7 +6902,7 @@ class InputMissingLabel extends Rule {
6875
6902
  });
6876
6903
  }
6877
6904
  validateInput(root, elem) {
6878
- if (isHTMLHidden(elem) || isAriaHidden(elem)) {
6905
+ if (!inAccessibilityTree(elem)) {
6879
6906
  return;
6880
6907
  }
6881
6908
  if (isIgnored(elem)) {
@@ -6908,7 +6935,7 @@ class InputMissingLabel extends Rule {
6908
6935
  * Reports error if none of the labels are accessible.
6909
6936
  */
6910
6937
  validateLabel(root, elem, labels) {
6911
- const visible = labels.filter(isVisible);
6938
+ const visible = labels.filter(inAccessibilityTree);
6912
6939
  if (visible.length === 0) {
6913
6940
  this.report(elem, `<${elem.tagName}> element has <label> but <label> element is hidden`);
6914
6941
  return;
@@ -6918,10 +6945,6 @@ class InputMissingLabel extends Rule {
6918
6945
  }
6919
6946
  }
6920
6947
  }
6921
- function isVisible(elem) {
6922
- const hidden = isHTMLHidden(elem) || isAriaHidden(elem);
6923
- return !hidden;
6924
- }
6925
6948
  function findLabelById(root, id) {
6926
6949
  if (!id)
6927
6950
  return [];
@@ -6938,12 +6961,12 @@ function findLabelByParent(el) {
6938
6961
  return [];
6939
6962
  }
6940
6963
 
6941
- const defaults$g = {
6964
+ const defaults$h = {
6942
6965
  maxlength: 70
6943
6966
  };
6944
6967
  class LongTitle extends Rule {
6945
6968
  constructor(options) {
6946
- super({ ...defaults$g, ...options });
6969
+ super({ ...defaults$h, ...options });
6947
6970
  this.maxlength = this.options.maxlength;
6948
6971
  }
6949
6972
  static schema() {
@@ -6972,12 +6995,12 @@ class LongTitle extends Rule {
6972
6995
  }
6973
6996
  }
6974
6997
 
6975
- const defaults$f = {
6998
+ const defaults$g = {
6976
6999
  allowLongDelay: false
6977
7000
  };
6978
7001
  class MetaRefresh extends Rule {
6979
7002
  constructor(options) {
6980
- super({ ...defaults$f, ...options });
7003
+ super({ ...defaults$g, ...options });
6981
7004
  }
6982
7005
  documentation() {
6983
7006
  return {
@@ -7165,6 +7188,45 @@ class MultipleLabeledControls extends Rule {
7165
7188
  }
7166
7189
  }
7167
7190
 
7191
+ const defaults$f = {
7192
+ pattern: "camelcase"
7193
+ };
7194
+ class NamePattern extends BasePatternRule {
7195
+ constructor(options) {
7196
+ super("name", { ...defaults$f, ...options });
7197
+ }
7198
+ static schema() {
7199
+ return BasePatternRule.schema();
7200
+ }
7201
+ documentation(context) {
7202
+ return {
7203
+ description: this.description(context),
7204
+ url: "https://html-validate.org/rules/name-pattern.html"
7205
+ };
7206
+ }
7207
+ setup() {
7208
+ this.on("attr", (event) => {
7209
+ var _a;
7210
+ const { target, key, value, valueLocation } = event;
7211
+ const { meta } = target;
7212
+ if (!((_a = meta == null ? void 0 : meta.formAssociated) == null ? void 0 : _a.listed)) {
7213
+ return;
7214
+ }
7215
+ if (key.toLowerCase() !== "name") {
7216
+ return;
7217
+ }
7218
+ if (value instanceof DynamicValue) {
7219
+ return;
7220
+ }
7221
+ if (value === null) {
7222
+ return;
7223
+ }
7224
+ const name = value.endsWith("[]") ? value.slice(0, -2) : value;
7225
+ this.validateValue(target, name, valueLocation);
7226
+ });
7227
+ }
7228
+ }
7229
+
7168
7230
  const abstractRoles = [
7169
7231
  "command",
7170
7232
  "composite",
@@ -10146,6 +10208,7 @@ const bundledRules = {
10146
10208
  "meta-refresh": MetaRefresh,
10147
10209
  "missing-doctype": MissingDoctype,
10148
10210
  "multiple-labeled-controls": MultipleLabeledControls,
10211
+ "name-pattern": NamePattern,
10149
10212
  "no-abstract-role": NoAbstractRole,
10150
10213
  "no-autoplay": NoAutoplay,
10151
10214
  "no-conditional-comment": NoConditionalComment,
@@ -12586,7 +12649,7 @@ class HtmlValidate {
12586
12649
  }
12587
12650
 
12588
12651
  const name = "html-validate";
12589
- const version = "8.16.0";
12652
+ const version = "8.17.1";
12590
12653
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
12591
12654
 
12592
12655
  function definePlugin(plugin) {