html-validate 10.6.0 → 10.8.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/esm/core.js CHANGED
@@ -3999,7 +3999,7 @@ class Rule {
3999
3999
  }
4000
4000
  }
4001
4001
 
4002
- const defaults$y = {
4002
+ const defaults$A = {
4003
4003
  allowExternal: true,
4004
4004
  allowRelative: true,
4005
4005
  allowAbsolute: true,
@@ -4043,7 +4043,7 @@ class AllowedLinks extends Rule {
4043
4043
  allowRelative;
4044
4044
  allowAbsolute;
4045
4045
  constructor(options) {
4046
- super({ ...defaults$y, ...options });
4046
+ super({ ...defaults$A, ...options });
4047
4047
  this.allowExternal = parseAllow(this.options.allowExternal);
4048
4048
  this.allowRelative = parseAllow(this.options.allowRelative);
4049
4049
  this.allowAbsolute = parseAllow(this.options.allowAbsolute);
@@ -4211,7 +4211,7 @@ class AllowedLinks extends Rule {
4211
4211
  }
4212
4212
  }
4213
4213
 
4214
- const defaults$x = {
4214
+ const defaults$z = {
4215
4215
  accessible: true
4216
4216
  };
4217
4217
  function findByTarget(target, siblings) {
@@ -4241,7 +4241,7 @@ function getDescription$1(context) {
4241
4241
  }
4242
4242
  class AreaAlt extends Rule {
4243
4243
  constructor(options) {
4244
- super({ ...defaults$x, ...options });
4244
+ super({ ...defaults$z, ...options });
4245
4245
  }
4246
4246
  static schema() {
4247
4247
  return {
@@ -4320,8 +4320,12 @@ class AriaHiddenBody extends Rule {
4320
4320
  }
4321
4321
  }
4322
4322
 
4323
- const defaults$w = {
4324
- allowAnyNamable: false
4323
+ const defaults$y = {
4324
+ allowAnyNamable: false,
4325
+ elements: {
4326
+ include: null,
4327
+ exclude: null
4328
+ }
4325
4329
  };
4326
4330
  const allowlist = /* @__PURE__ */ new Set([
4327
4331
  "main",
@@ -4364,7 +4368,26 @@ function isValidUsage(target, meta) {
4364
4368
  }
4365
4369
  class AriaLabelMisuse extends Rule {
4366
4370
  constructor(options) {
4367
- super({ ...defaults$w, ...options });
4371
+ super({ ...defaults$y, ...options });
4372
+ }
4373
+ static schema() {
4374
+ return {
4375
+ allowAnyNamable: {
4376
+ type: "boolean"
4377
+ },
4378
+ elements: {
4379
+ type: "object",
4380
+ properties: {
4381
+ include: {
4382
+ anyOf: [{ type: "array", items: { type: "string" } }, { type: "null" }]
4383
+ },
4384
+ exclude: {
4385
+ anyOf: [{ type: "array", items: { type: "string" } }, { type: "null" }]
4386
+ }
4387
+ },
4388
+ additionalProperties: false
4389
+ }
4390
+ };
4368
4391
  }
4369
4392
  documentation(context) {
4370
4393
  const valid = [
@@ -4422,6 +4445,9 @@ class AriaLabelMisuse extends Rule {
4422
4445
  if (!meta) {
4423
4446
  return;
4424
4447
  }
4448
+ if (this.shouldIgnoreElement(target)) {
4449
+ return;
4450
+ }
4425
4451
  if (isValidUsage(target, meta)) {
4426
4452
  return;
4427
4453
  }
@@ -4446,6 +4472,9 @@ class AriaLabelMisuse extends Rule {
4446
4472
  });
4447
4473
  }
4448
4474
  }
4475
+ shouldIgnoreElement(target) {
4476
+ return isKeywordIgnored(this.options.elements, target.tagName, keywordPatternMatcher);
4477
+ }
4449
4478
  }
4450
4479
 
4451
4480
  class ConfigError extends UserError {
@@ -4508,14 +4537,14 @@ class CaseStyle {
4508
4537
  }
4509
4538
  }
4510
4539
 
4511
- const defaults$v = {
4540
+ const defaults$x = {
4512
4541
  style: "lowercase",
4513
4542
  ignoreForeign: true
4514
4543
  };
4515
4544
  class AttrCase extends Rule {
4516
4545
  style;
4517
4546
  constructor(options) {
4518
- super({ ...defaults$v, ...options });
4547
+ super({ ...defaults$x, ...options });
4519
4548
  this.style = new CaseStyle(this.options.style, "attr-case");
4520
4549
  }
4521
4550
  static schema() {
@@ -4622,7 +4651,7 @@ const MATCH_TEXTAREA_DATA = /^[^]*?(?=<\/textarea)/;
4622
4651
  const MATCH_TEXTAREA_END = /^<(\/)(textarea)/;
4623
4652
  const MATCH_TITLE_DATA = /^[^]*?(?=<\/title)/;
4624
4653
  const MATCH_TITLE_END = /^<(\/)(title)/;
4625
- const MATCH_DIRECTIVE = /^(<!--\s*\[html-validate-)([a-z0-9-]+)(\s*)(.*?)(]?\s*-->)/;
4654
+ const MATCH_DIRECTIVE = /^(<!--\s*\[?)(html-validate-)([a-z0-9-]+)(\s*)(.*?)(]?\s*-->)/;
4626
4655
  const MATCH_COMMENT = /^<!--([^]*?)-->/;
4627
4656
  const MATCH_CONDITIONAL = /^<!\[([^\]]*?)\]>/;
4628
4657
  class InvalidTokenError extends Error {
@@ -4920,7 +4949,7 @@ class AttrDelimiter extends Rule {
4920
4949
  }
4921
4950
 
4922
4951
  const DEFAULT_PATTERN = "[a-z0-9-:]+";
4923
- const defaults$u = {
4952
+ const defaults$w = {
4924
4953
  pattern: DEFAULT_PATTERN,
4925
4954
  ignoreForeign: true
4926
4955
  };
@@ -4953,7 +4982,7 @@ function generateDescription(name, pattern) {
4953
4982
  class AttrPattern extends Rule {
4954
4983
  pattern;
4955
4984
  constructor(options) {
4956
- super({ ...defaults$u, ...options });
4985
+ super({ ...defaults$w, ...options });
4957
4986
  this.pattern = generateRegexp(this.options.pattern);
4958
4987
  }
4959
4988
  static schema() {
@@ -5000,7 +5029,7 @@ class AttrPattern extends Rule {
5000
5029
  }
5001
5030
  }
5002
5031
 
5003
- const defaults$t = {
5032
+ const defaults$v = {
5004
5033
  style: "auto",
5005
5034
  unquoted: false
5006
5035
  };
@@ -5066,7 +5095,7 @@ class AttrQuotes extends Rule {
5066
5095
  };
5067
5096
  }
5068
5097
  constructor(options) {
5069
- super({ ...defaults$t, ...options });
5098
+ super({ ...defaults$v, ...options });
5070
5099
  this.style = parseStyle$3(this.options.style);
5071
5100
  }
5072
5101
  setup() {
@@ -5222,13 +5251,13 @@ class AttributeAllowedValues extends Rule {
5222
5251
  }
5223
5252
  }
5224
5253
 
5225
- const defaults$s = {
5254
+ const defaults$u = {
5226
5255
  style: "omit"
5227
5256
  };
5228
5257
  class AttributeBooleanStyle extends Rule {
5229
5258
  hasInvalidStyle;
5230
5259
  constructor(options) {
5231
- super({ ...defaults$s, ...options });
5260
+ super({ ...defaults$u, ...options });
5232
5261
  this.hasInvalidStyle = parseStyle$2(this.options.style);
5233
5262
  }
5234
5263
  static schema() {
@@ -5298,13 +5327,13 @@ function reportMessage$1(attr, style) {
5298
5327
  return "";
5299
5328
  }
5300
5329
 
5301
- const defaults$r = {
5330
+ const defaults$t = {
5302
5331
  style: "omit"
5303
5332
  };
5304
5333
  class AttributeEmptyStyle extends Rule {
5305
5334
  hasInvalidStyle;
5306
5335
  constructor(options) {
5307
- super({ ...defaults$r, ...options });
5336
+ super({ ...defaults$t, ...options });
5308
5337
  this.hasInvalidStyle = parseStyle$1(this.options.style);
5309
5338
  }
5310
5339
  static schema() {
@@ -5421,6 +5450,122 @@ class AttributeMisuse extends Rule {
5421
5450
  }
5422
5451
  }
5423
5452
 
5453
+ const defaults$s = {
5454
+ preferred: void 0
5455
+ };
5456
+ function isPasswordInput(event) {
5457
+ const { target } = event;
5458
+ if (!target.is("input")) {
5459
+ return false;
5460
+ }
5461
+ const type = target.getAttribute("type");
5462
+ return type?.value?.toString().toLowerCase() === "password";
5463
+ }
5464
+ function isGroupingToken(token) {
5465
+ return token.startsWith("section-") || token === "shipping" || token === "billing";
5466
+ }
5467
+ class AutocompletePassword extends Rule {
5468
+ preferred;
5469
+ constructor(options) {
5470
+ super({ ...defaults$s, ...options });
5471
+ this.preferred = options.preferred?.toLowerCase();
5472
+ }
5473
+ static schema() {
5474
+ return {
5475
+ preferred: {
5476
+ type: "string"
5477
+ }
5478
+ };
5479
+ }
5480
+ documentation(context) {
5481
+ const url = "https://html-validate.org/rules/autocomplete-password.html";
5482
+ switch (context.kind) {
5483
+ case "preferred-mismatch":
5484
+ return {
5485
+ description: [
5486
+ `\`<input type="password">\` should use \`autocomplete="${context.preferred}"\`.`,
5487
+ "",
5488
+ `The configured preferred autocomplete value is \`"${context.preferred}"\` but the element uses \`"${context.value}"\`.`
5489
+ ].join("\n"),
5490
+ url
5491
+ };
5492
+ case "off":
5493
+ case "missing":
5494
+ default: {
5495
+ const error = context.kind === "off" ? '`<input type="password">` should not use `autocomplete="off"`.' : '`<input type="password">` must have the `autocomplete` attribute.';
5496
+ return {
5497
+ description: [
5498
+ error,
5499
+ "",
5500
+ "Browsers and password managers often ignore the absence of autocomplete and autofill password fields anyway, which can lead to unexpected behavior where users unknowingly submit autofilled passwords for unrelated fields.",
5501
+ "",
5502
+ "Use one of the following values:",
5503
+ "",
5504
+ '- `autocomplete="new-password"` for password creation forms',
5505
+ '- `autocomplete="current-password"` for login forms'
5506
+ ].join("\n"),
5507
+ url
5508
+ };
5509
+ }
5510
+ }
5511
+ }
5512
+ setup() {
5513
+ this.on("tag:ready", isPasswordInput, (event) => {
5514
+ const { preferred } = this;
5515
+ const { target } = event;
5516
+ const autocomplete = target.getAttribute("autocomplete");
5517
+ if (!autocomplete) {
5518
+ const context = { kind: "missing" };
5519
+ this.report({
5520
+ node: target,
5521
+ message: '<input type="password"> is missing required "autocomplete" attribute',
5522
+ location: target.location,
5523
+ context
5524
+ });
5525
+ return;
5526
+ }
5527
+ if (autocomplete.isDynamic || !autocomplete.value) {
5528
+ return;
5529
+ }
5530
+ const raw = autocomplete.value.toString().toLowerCase();
5531
+ const tokens = new DOMTokenList(raw, autocomplete.valueLocation);
5532
+ const index = tokens.findIndex((token) => !isGroupingToken(token));
5533
+ const value = tokens.item(index);
5534
+ const location = tokens.location(index);
5535
+ if (!value) {
5536
+ return;
5537
+ }
5538
+ if (value === "off") {
5539
+ const context = { kind: "off" };
5540
+ this.report({
5541
+ node: target,
5542
+ message: '<input type="password"> should not use autocomplete="off"',
5543
+ /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- location must be present if value is */
5544
+ location,
5545
+ context
5546
+ });
5547
+ return;
5548
+ }
5549
+ if (preferred) {
5550
+ if (value !== preferred) {
5551
+ const context = {
5552
+ kind: "preferred-mismatch",
5553
+ value,
5554
+ preferred
5555
+ };
5556
+ this.report({
5557
+ node: target,
5558
+ message: `<input type="password"> should use autocomplete="${preferred}"`,
5559
+ /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- location must be present if value is */
5560
+ location,
5561
+ context
5562
+ });
5563
+ }
5564
+ }
5565
+ });
5566
+ }
5567
+ }
5568
+
5424
5569
  const patternNamesValues = [
5425
5570
  "kebabcase",
5426
5571
  "camelcase",
@@ -5552,7 +5697,7 @@ class BasePatternRule extends Rule {
5552
5697
  }
5553
5698
  }
5554
5699
 
5555
- const defaults$q = {
5700
+ const defaults$r = {
5556
5701
  pattern: "kebabcase"
5557
5702
  };
5558
5703
  class ClassPattern extends BasePatternRule {
@@ -5560,7 +5705,7 @@ class ClassPattern extends BasePatternRule {
5560
5705
  super({
5561
5706
  ruleId: "class-pattern",
5562
5707
  attr: "class",
5563
- options: { ...defaults$q, ...options },
5708
+ options: { ...defaults$r, ...options },
5564
5709
  allowedPatterns: patternNames
5565
5710
  // allow all patterns
5566
5711
  });
@@ -5710,13 +5855,13 @@ class CloseOrder extends Rule {
5710
5855
  }
5711
5856
  }
5712
5857
 
5713
- const defaults$p = {
5858
+ const defaults$q = {
5714
5859
  include: null,
5715
5860
  exclude: null
5716
5861
  };
5717
5862
  class Deprecated extends Rule {
5718
5863
  constructor(options) {
5719
- super({ ...defaults$p, ...options });
5864
+ super({ ...defaults$q, ...options });
5720
5865
  }
5721
5866
  static schema() {
5722
5867
  return {
@@ -5870,12 +6015,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
5870
6015
  }
5871
6016
  };
5872
6017
 
5873
- const defaults$o = {
6018
+ const defaults$p = {
5874
6019
  style: "uppercase"
5875
6020
  };
5876
6021
  class DoctypeStyle extends Rule {
5877
6022
  constructor(options) {
5878
- super({ ...defaults$o, ...options });
6023
+ super({ ...defaults$p, ...options });
5879
6024
  }
5880
6025
  static schema() {
5881
6026
  return {
@@ -5903,13 +6048,13 @@ class DoctypeStyle extends Rule {
5903
6048
  }
5904
6049
  }
5905
6050
 
5906
- const defaults$n = {
6051
+ const defaults$o = {
5907
6052
  style: "lowercase"
5908
6053
  };
5909
6054
  class ElementCase extends Rule {
5910
6055
  style;
5911
6056
  constructor(options) {
5912
- super({ ...defaults$n, ...options });
6057
+ super({ ...defaults$o, ...options });
5913
6058
  this.style = new CaseStyle(this.options.style, "element-case");
5914
6059
  }
5915
6060
  static schema() {
@@ -5969,7 +6114,7 @@ class ElementCase extends Rule {
5969
6114
  }
5970
6115
  }
5971
6116
 
5972
- const defaults$m = {
6117
+ const defaults$n = {
5973
6118
  pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
5974
6119
  whitelist: [],
5975
6120
  blacklist: []
@@ -5977,7 +6122,7 @@ const defaults$m = {
5977
6122
  class ElementName extends Rule {
5978
6123
  pattern;
5979
6124
  constructor(options) {
5980
- super({ ...defaults$m, ...options });
6125
+ super({ ...defaults$n, ...options });
5981
6126
  this.pattern = new RegExp(this.options.pattern);
5982
6127
  }
5983
6128
  static schema() {
@@ -6014,7 +6159,7 @@ class ElementName extends Rule {
6014
6159
  ...context.blacklist.map((cur) => `- ${cur}`)
6015
6160
  ];
6016
6161
  }
6017
- if (context.pattern !== defaults$m.pattern) {
6162
+ if (context.pattern !== defaults$n.pattern) {
6018
6163
  return [
6019
6164
  `<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
6020
6165
  "",
@@ -6531,7 +6676,7 @@ class EmptyTitle extends Rule {
6531
6676
  }
6532
6677
  }
6533
6678
 
6534
- const defaults$l = {
6679
+ const defaults$m = {
6535
6680
  allowArrayBrackets: true,
6536
6681
  allowCheckboxDefault: true,
6537
6682
  shared: ["radio", "button", "reset", "submit"]
@@ -6591,7 +6736,7 @@ function getDocumentation(context) {
6591
6736
  }
6592
6737
  class FormDupName extends Rule {
6593
6738
  constructor(options) {
6594
- super({ ...defaults$l, ...options });
6739
+ super({ ...defaults$m, ...options });
6595
6740
  }
6596
6741
  static schema() {
6597
6742
  return {
@@ -6750,7 +6895,7 @@ class FormDupName extends Rule {
6750
6895
  }
6751
6896
  }
6752
6897
 
6753
- const defaults$k = {
6898
+ const defaults$l = {
6754
6899
  allowMultipleH1: false,
6755
6900
  minInitialRank: "h1",
6756
6901
  sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]']
@@ -6782,7 +6927,7 @@ class HeadingLevel extends Rule {
6782
6927
  sectionRoots;
6783
6928
  stack = [];
6784
6929
  constructor(options) {
6785
- super({ ...defaults$k, ...options });
6930
+ super({ ...defaults$l, ...options });
6786
6931
  this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
6787
6932
  this.sectionRoots = this.options.sectioningRoots.map((it) => new Compound(it));
6788
6933
  this.stack.push({
@@ -7021,7 +7166,7 @@ class HiddenFocusable extends Rule {
7021
7166
  }
7022
7167
  }
7023
7168
 
7024
- const defaults$j = {
7169
+ const defaults$k = {
7025
7170
  pattern: "kebabcase"
7026
7171
  };
7027
7172
  function exclude$1(set, ...values) {
@@ -7037,7 +7182,7 @@ class IdPattern extends BasePatternRule {
7037
7182
  super({
7038
7183
  ruleId: "id-pattern",
7039
7184
  attr: "id",
7040
- options: { ...defaults$j, ...options },
7185
+ options: { ...defaults$k, ...options },
7041
7186
  allowedPatterns
7042
7187
  });
7043
7188
  }
@@ -7359,13 +7504,13 @@ function findLabelByParent(el) {
7359
7504
  return [];
7360
7505
  }
7361
7506
 
7362
- const defaults$i = {
7507
+ const defaults$j = {
7363
7508
  maxlength: 70
7364
7509
  };
7365
7510
  class LongTitle extends Rule {
7366
7511
  maxlength;
7367
7512
  constructor(options) {
7368
- super({ ...defaults$i, ...options });
7513
+ super({ ...defaults$j, ...options });
7369
7514
  this.maxlength = this.options.maxlength;
7370
7515
  }
7371
7516
  static schema() {
@@ -7469,12 +7614,12 @@ class MapIdName extends Rule {
7469
7614
  }
7470
7615
  }
7471
7616
 
7472
- const defaults$h = {
7617
+ const defaults$i = {
7473
7618
  allowLongDelay: false
7474
7619
  };
7475
7620
  class MetaRefresh extends Rule {
7476
7621
  constructor(options) {
7477
- super({ ...defaults$h, ...options });
7622
+ super({ ...defaults$i, ...options });
7478
7623
  }
7479
7624
  documentation() {
7480
7625
  return {
@@ -7585,7 +7730,7 @@ class MultipleLabeledControls extends Rule {
7585
7730
  }
7586
7731
  }
7587
7732
 
7588
- const defaults$g = {
7733
+ const defaults$h = {
7589
7734
  pattern: "camelcase"
7590
7735
  };
7591
7736
  function exclude(set, ...values) {
@@ -7601,7 +7746,7 @@ class NamePattern extends BasePatternRule {
7601
7746
  super({
7602
7747
  ruleId: "name-pattern",
7603
7748
  attr: "name",
7604
- options: { ...defaults$g, ...options },
7749
+ options: { ...defaults$h, ...options },
7605
7750
  allowedPatterns
7606
7751
  });
7607
7752
  }
@@ -7692,13 +7837,13 @@ class NoAbstractRole extends Rule {
7692
7837
  }
7693
7838
  }
7694
7839
 
7695
- const defaults$f = {
7840
+ const defaults$g = {
7696
7841
  include: null,
7697
7842
  exclude: null
7698
7843
  };
7699
7844
  class NoAutoplay extends Rule {
7700
7845
  constructor(options) {
7701
- super({ ...defaults$f, ...options });
7846
+ super({ ...defaults$g, ...options });
7702
7847
  }
7703
7848
  documentation(context) {
7704
7849
  return {
@@ -8020,14 +8165,14 @@ class NoImplicitInputType extends Rule {
8020
8165
  }
8021
8166
  }
8022
8167
 
8023
- const defaults$e = {
8168
+ const defaults$f = {
8024
8169
  include: null,
8025
8170
  exclude: null,
8026
8171
  allowedProperties: ["display"]
8027
8172
  };
8028
8173
  class NoInlineStyle extends Rule {
8029
8174
  constructor(options) {
8030
- super({ ...defaults$e, ...options });
8175
+ super({ ...defaults$f, ...options });
8031
8176
  }
8032
8177
  static schema() {
8033
8178
  return {
@@ -8213,7 +8358,7 @@ class NoMultipleMain extends Rule {
8213
8358
  }
8214
8359
  }
8215
8360
 
8216
- const defaults$d = {
8361
+ const defaults$e = {
8217
8362
  relaxed: false
8218
8363
  };
8219
8364
  const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
@@ -8231,7 +8376,7 @@ const replacementTable = {
8231
8376
  class NoRawCharacters extends Rule {
8232
8377
  relaxed;
8233
8378
  constructor(options) {
8234
- super({ ...defaults$d, ...options });
8379
+ super({ ...defaults$e, ...options });
8235
8380
  this.relaxed = this.options.relaxed;
8236
8381
  }
8237
8382
  static schema() {
@@ -8411,13 +8556,13 @@ class NoRedundantRole extends Rule {
8411
8556
  }
8412
8557
 
8413
8558
  const xmlns = /^(.+):.+$/;
8414
- const defaults$c = {
8559
+ const defaults$d = {
8415
8560
  ignoreForeign: true,
8416
8561
  ignoreXML: true
8417
8562
  };
8418
8563
  class NoSelfClosing extends Rule {
8419
8564
  constructor(options) {
8420
- super({ ...defaults$c, ...options });
8565
+ super({ ...defaults$d, ...options });
8421
8566
  }
8422
8567
  static schema() {
8423
8568
  return {
@@ -8467,7 +8612,20 @@ function isRelevant(node, options) {
8467
8612
  return true;
8468
8613
  }
8469
8614
 
8615
+ const defaults$c = {
8616
+ allowTemplate: true
8617
+ };
8470
8618
  class NoStyleTag extends Rule {
8619
+ constructor(options) {
8620
+ super({ ...defaults$c, ...options });
8621
+ }
8622
+ static schema() {
8623
+ return {
8624
+ allowTemplate: {
8625
+ type: "boolean"
8626
+ }
8627
+ };
8628
+ }
8471
8629
  documentation() {
8472
8630
  return {
8473
8631
  description: "Prefer to use external stylesheets with the `<link>` tag instead of inlining the styling.",
@@ -8475,9 +8633,13 @@ class NoStyleTag extends Rule {
8475
8633
  };
8476
8634
  }
8477
8635
  setup() {
8636
+ const { allowTemplate } = this.options;
8478
8637
  this.on("tag:start", (event) => {
8479
8638
  const node = event.target;
8480
8639
  if (node.tagName === "style") {
8640
+ if (allowTemplate && node.parent?.is("template")) {
8641
+ return;
8642
+ }
8481
8643
  this.report(node, "Use external stylesheet with <link> instead of <style> tag");
8482
8644
  }
8483
8645
  });
@@ -9384,7 +9546,7 @@ function getTextFromReference(document, id) {
9384
9546
  if (!id || id instanceof DynamicValue) {
9385
9547
  return id;
9386
9548
  }
9387
- const selector = `#${id}`;
9549
+ const selector = generateIdSelector(id);
9388
9550
  const ref = document.querySelector(selector);
9389
9551
  if (ref) {
9390
9552
  return ref.textContent;
@@ -9700,9 +9862,7 @@ const fieldNameGroup = {
9700
9862
  nickname: "text",
9701
9863
  username: "username",
9702
9864
  "new-password": "password",
9703
- // eslint-disable-line sonarjs/no-hardcoded-passwords -- false positive, it is not used as a password
9704
9865
  "current-password": "password",
9705
- // eslint-disable-line sonarjs/no-hardcoded-passwords -- false positive, it is not used as a password
9706
9866
  "one-time-code": "password",
9707
9867
  "organization-title": "text",
9708
9868
  organization: "text",
@@ -10744,6 +10904,7 @@ const bundledRules = {
10744
10904
  "attribute-boolean-style": AttributeBooleanStyle,
10745
10905
  "attribute-empty-style": AttributeEmptyStyle,
10746
10906
  "attribute-misuse": AttributeMisuse,
10907
+ "autocomplete-password": AutocompletePassword,
10747
10908
  "class-pattern": ClassPattern,
10748
10909
  "close-attr": CloseAttr,
10749
10910
  "close-order": CloseOrder,
@@ -11109,6 +11270,7 @@ const config$1 = {
11109
11270
  "attribute-boolean-style": "error",
11110
11271
  "attribute-empty-style": "error",
11111
11272
  "attribute-misuse": "error",
11273
+ "autocomplete-password": "error",
11112
11274
  "close-attr": "error",
11113
11275
  "close-order": "error",
11114
11276
  deprecated: "error",
@@ -12123,7 +12285,7 @@ class EventHandler {
12123
12285
  }
12124
12286
 
12125
12287
  const name = "html-validate";
12126
- const version = "10.6.0";
12288
+ const version = "10.8.0";
12127
12289
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
12128
12290
 
12129
12291
  function freeze(src) {
@@ -12669,31 +12831,34 @@ class Parser {
12669
12831
  * @internal
12670
12832
  */
12671
12833
  consumeDirective(token) {
12672
- const [text, preamble, action, separator1, directive, postamble] = token.data;
12673
- if (!postamble.startsWith("]")) {
12674
- throw new ParserError(token.location, `Missing end bracket "]" on directive "${text}"`);
12834
+ const [text, preamble, prefix, action, separator1, directive, postamble] = token.data;
12835
+ const hasStartBracket = preamble.includes("[");
12836
+ const hasEndBracket = postamble.startsWith("]");
12837
+ if (hasStartBracket && !hasEndBracket) {
12838
+ this.trigger("parse:error", {
12839
+ location: sliceLocation(token.location, preamble.length - 1, -postamble.length),
12840
+ message: `Missing end bracket "]" on directive "${text}"`
12841
+ });
12842
+ return;
12675
12843
  }
12676
12844
  const match = /^(.*?)(?:(\s*(?:--|:)\s*)(.*))?$/.exec(directive);
12677
12845
  if (!match) {
12678
12846
  throw new Error(`Failed to parse directive "${text}"`);
12679
12847
  }
12680
12848
  if (!isValidDirective(action)) {
12849
+ const begin = preamble.length;
12850
+ const end = preamble.length + prefix.length + action.length;
12681
12851
  this.trigger("parse:error", {
12682
- location: token.location,
12852
+ location: sliceLocation(token.location, begin, -text.length + end),
12683
12853
  message: `Unknown directive "${action}"`
12684
12854
  });
12685
12855
  return;
12686
12856
  }
12687
12857
  const [, data, separator2, comment] = match;
12688
- const prefix = "html-validate-";
12689
- const actionOffset = preamble.length;
12858
+ const actionOffset = preamble.length + prefix.length;
12690
12859
  const optionsOffset = actionOffset + action.length + separator1.length;
12691
12860
  const commentOffset = optionsOffset + data.length + (separator2 || "").length;
12692
- const location = sliceLocation(
12693
- token.location,
12694
- preamble.length - prefix.length - 1,
12695
- -postamble.length + 1
12696
- );
12861
+ const location = sliceLocation(token.location, preamble.length - 1, -postamble.length + 1);
12697
12862
  const actionLocation = sliceLocation(
12698
12863
  token.location,
12699
12864
  actionOffset,
@@ -14540,5 +14705,5 @@ const engines = {
14540
14705
 
14541
14706
  var workerPath = "./jest-worker.js";
14542
14707
 
14543
- export { compatibilityCheckImpl as $, Attribute as A, Reporter as B, Config as C, DOMNode as D, definePlugin as E, ruleExists as F, walk as G, HtmlElement as H, EventHandler as I, engines as J, normalizeSource as K, transformSource as L, MetaCopyableProperty as M, NodeClosed as N, Engine as O, Parser as P, transformSourceSync as Q, ResolvedConfig as R, Severity as S, TextNode as T, UserError as U, Validator as V, WrappedError as W, transformFilename as X, transformFilenameSync as Y, configurationSchema as Z, isThenable as _, ConfigError as a, workerPath as a0, codeframe as a1, name as a2, bugs as a3, ConfigLoader as b, defineConfig as c, deepmerge as d, ensureError as e, StaticConfigLoader as f, getFormatter as g, DOMTokenList as h, ignore as i, DOMTree as j, DynamicValue as k, NodeType as l, NestedError as m, SchemaValidationError as n, isUserError as o, presets as p, MetaTable as q, TextContent$1 as r, staticResolver as s, Rule as t, TextClassification as u, version as v, ariaNaming as w, classifyNodeText as x, keywordPatternMatcher as y, sliceLocation as z };
14708
+ export { engines as $, Attribute as A, TextContent$1 as B, ConfigLoader as C, DOMNode as D, Engine as E, TextNode as F, ariaNaming as G, HtmlElement as H, classifyNodeText as I, presets as J, defineConfig as K, definePlugin as L, MetaCopyableProperty as M, NestedError as N, isUserError as O, Parser as P, keywordPatternMatcher as Q, Reporter as R, StaticConfigLoader as S, TextClassification as T, UserError as U, Validator as V, WrappedError as W, ruleExists as X, sliceLocation as Y, staticResolver as Z, walk as _, transformSourceSync as a, workerPath as a0, codeframe as a1, name as a2, bugs as a3, transformFilename as b, transformFilenameSync as c, configurationSchema as d, ConfigError as e, Config as f, compatibilityCheckImpl as g, ensureError as h, isThenable as i, getFormatter as j, deepmerge as k, ignore as l, DOMTokenList as m, normalizeSource as n, DOMTree as o, DynamicValue as p, EventHandler as q, MetaTable as r, NodeClosed as s, transformSource as t, NodeType as u, version as v, ResolvedConfig as w, Rule as x, SchemaValidationError as y, Severity as z };
14544
14709
  //# sourceMappingURL=core.js.map