html-validate 10.6.0 → 10.7.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
@@ -4008,7 +4008,7 @@ class Rule {
4008
4008
  }
4009
4009
  }
4010
4010
 
4011
- const defaults$y = {
4011
+ const defaults$z = {
4012
4012
  allowExternal: true,
4013
4013
  allowRelative: true,
4014
4014
  allowAbsolute: true,
@@ -4052,7 +4052,7 @@ class AllowedLinks extends Rule {
4052
4052
  allowRelative;
4053
4053
  allowAbsolute;
4054
4054
  constructor(options) {
4055
- super({ ...defaults$y, ...options });
4055
+ super({ ...defaults$z, ...options });
4056
4056
  this.allowExternal = parseAllow(this.options.allowExternal);
4057
4057
  this.allowRelative = parseAllow(this.options.allowRelative);
4058
4058
  this.allowAbsolute = parseAllow(this.options.allowAbsolute);
@@ -4220,7 +4220,7 @@ class AllowedLinks extends Rule {
4220
4220
  }
4221
4221
  }
4222
4222
 
4223
- const defaults$x = {
4223
+ const defaults$y = {
4224
4224
  accessible: true
4225
4225
  };
4226
4226
  function findByTarget(target, siblings) {
@@ -4250,7 +4250,7 @@ function getDescription$1(context) {
4250
4250
  }
4251
4251
  class AreaAlt extends Rule {
4252
4252
  constructor(options) {
4253
- super({ ...defaults$x, ...options });
4253
+ super({ ...defaults$y, ...options });
4254
4254
  }
4255
4255
  static schema() {
4256
4256
  return {
@@ -4329,8 +4329,12 @@ class AriaHiddenBody extends Rule {
4329
4329
  }
4330
4330
  }
4331
4331
 
4332
- const defaults$w = {
4333
- allowAnyNamable: false
4332
+ const defaults$x = {
4333
+ allowAnyNamable: false,
4334
+ elements: {
4335
+ include: null,
4336
+ exclude: null
4337
+ }
4334
4338
  };
4335
4339
  const allowlist = /* @__PURE__ */ new Set([
4336
4340
  "main",
@@ -4373,7 +4377,26 @@ function isValidUsage(target, meta) {
4373
4377
  }
4374
4378
  class AriaLabelMisuse extends Rule {
4375
4379
  constructor(options) {
4376
- super({ ...defaults$w, ...options });
4380
+ super({ ...defaults$x, ...options });
4381
+ }
4382
+ static schema() {
4383
+ return {
4384
+ allowAnyNamable: {
4385
+ type: "boolean"
4386
+ },
4387
+ elements: {
4388
+ type: "object",
4389
+ properties: {
4390
+ include: {
4391
+ anyOf: [{ type: "array", items: { type: "string" } }, { type: "null" }]
4392
+ },
4393
+ exclude: {
4394
+ anyOf: [{ type: "array", items: { type: "string" } }, { type: "null" }]
4395
+ }
4396
+ },
4397
+ additionalProperties: false
4398
+ }
4399
+ };
4377
4400
  }
4378
4401
  documentation(context) {
4379
4402
  const valid = [
@@ -4431,6 +4454,9 @@ class AriaLabelMisuse extends Rule {
4431
4454
  if (!meta) {
4432
4455
  return;
4433
4456
  }
4457
+ if (this.shouldIgnoreElement(target)) {
4458
+ return;
4459
+ }
4434
4460
  if (isValidUsage(target, meta)) {
4435
4461
  return;
4436
4462
  }
@@ -4455,6 +4481,9 @@ class AriaLabelMisuse extends Rule {
4455
4481
  });
4456
4482
  }
4457
4483
  }
4484
+ shouldIgnoreElement(target) {
4485
+ return isKeywordIgnored(this.options.elements, target.tagName, keywordPatternMatcher);
4486
+ }
4458
4487
  }
4459
4488
 
4460
4489
  class ConfigError extends UserError {
@@ -4517,14 +4546,14 @@ class CaseStyle {
4517
4546
  }
4518
4547
  }
4519
4548
 
4520
- const defaults$v = {
4549
+ const defaults$w = {
4521
4550
  style: "lowercase",
4522
4551
  ignoreForeign: true
4523
4552
  };
4524
4553
  class AttrCase extends Rule {
4525
4554
  style;
4526
4555
  constructor(options) {
4527
- super({ ...defaults$v, ...options });
4556
+ super({ ...defaults$w, ...options });
4528
4557
  this.style = new CaseStyle(this.options.style, "attr-case");
4529
4558
  }
4530
4559
  static schema() {
@@ -4631,7 +4660,7 @@ const MATCH_TEXTAREA_DATA = /^[^]*?(?=<\/textarea)/;
4631
4660
  const MATCH_TEXTAREA_END = /^<(\/)(textarea)/;
4632
4661
  const MATCH_TITLE_DATA = /^[^]*?(?=<\/title)/;
4633
4662
  const MATCH_TITLE_END = /^<(\/)(title)/;
4634
- const MATCH_DIRECTIVE = /^(<!--\s*\[html-validate-)([a-z0-9-]+)(\s*)(.*?)(]?\s*-->)/;
4663
+ const MATCH_DIRECTIVE = /^(<!--\s*\[?)(html-validate-)([a-z0-9-]+)(\s*)(.*?)(]?\s*-->)/;
4635
4664
  const MATCH_COMMENT = /^<!--([^]*?)-->/;
4636
4665
  const MATCH_CONDITIONAL = /^<!\[([^\]]*?)\]>/;
4637
4666
  class InvalidTokenError extends Error {
@@ -4929,7 +4958,7 @@ class AttrDelimiter extends Rule {
4929
4958
  }
4930
4959
 
4931
4960
  const DEFAULT_PATTERN = "[a-z0-9-:]+";
4932
- const defaults$u = {
4961
+ const defaults$v = {
4933
4962
  pattern: DEFAULT_PATTERN,
4934
4963
  ignoreForeign: true
4935
4964
  };
@@ -4962,7 +4991,7 @@ function generateDescription(name, pattern) {
4962
4991
  class AttrPattern extends Rule {
4963
4992
  pattern;
4964
4993
  constructor(options) {
4965
- super({ ...defaults$u, ...options });
4994
+ super({ ...defaults$v, ...options });
4966
4995
  this.pattern = generateRegexp(this.options.pattern);
4967
4996
  }
4968
4997
  static schema() {
@@ -5009,7 +5038,7 @@ class AttrPattern extends Rule {
5009
5038
  }
5010
5039
  }
5011
5040
 
5012
- const defaults$t = {
5041
+ const defaults$u = {
5013
5042
  style: "auto",
5014
5043
  unquoted: false
5015
5044
  };
@@ -5075,7 +5104,7 @@ class AttrQuotes extends Rule {
5075
5104
  };
5076
5105
  }
5077
5106
  constructor(options) {
5078
- super({ ...defaults$t, ...options });
5107
+ super({ ...defaults$u, ...options });
5079
5108
  this.style = parseStyle$3(this.options.style);
5080
5109
  }
5081
5110
  setup() {
@@ -5231,13 +5260,13 @@ class AttributeAllowedValues extends Rule {
5231
5260
  }
5232
5261
  }
5233
5262
 
5234
- const defaults$s = {
5263
+ const defaults$t = {
5235
5264
  style: "omit"
5236
5265
  };
5237
5266
  class AttributeBooleanStyle extends Rule {
5238
5267
  hasInvalidStyle;
5239
5268
  constructor(options) {
5240
- super({ ...defaults$s, ...options });
5269
+ super({ ...defaults$t, ...options });
5241
5270
  this.hasInvalidStyle = parseStyle$2(this.options.style);
5242
5271
  }
5243
5272
  static schema() {
@@ -5307,13 +5336,13 @@ function reportMessage$1(attr, style) {
5307
5336
  return "";
5308
5337
  }
5309
5338
 
5310
- const defaults$r = {
5339
+ const defaults$s = {
5311
5340
  style: "omit"
5312
5341
  };
5313
5342
  class AttributeEmptyStyle extends Rule {
5314
5343
  hasInvalidStyle;
5315
5344
  constructor(options) {
5316
- super({ ...defaults$r, ...options });
5345
+ super({ ...defaults$s, ...options });
5317
5346
  this.hasInvalidStyle = parseStyle$1(this.options.style);
5318
5347
  }
5319
5348
  static schema() {
@@ -5561,7 +5590,7 @@ class BasePatternRule extends Rule {
5561
5590
  }
5562
5591
  }
5563
5592
 
5564
- const defaults$q = {
5593
+ const defaults$r = {
5565
5594
  pattern: "kebabcase"
5566
5595
  };
5567
5596
  class ClassPattern extends BasePatternRule {
@@ -5569,7 +5598,7 @@ class ClassPattern extends BasePatternRule {
5569
5598
  super({
5570
5599
  ruleId: "class-pattern",
5571
5600
  attr: "class",
5572
- options: { ...defaults$q, ...options },
5601
+ options: { ...defaults$r, ...options },
5573
5602
  allowedPatterns: patternNames
5574
5603
  // allow all patterns
5575
5604
  });
@@ -5719,13 +5748,13 @@ class CloseOrder extends Rule {
5719
5748
  }
5720
5749
  }
5721
5750
 
5722
- const defaults$p = {
5751
+ const defaults$q = {
5723
5752
  include: null,
5724
5753
  exclude: null
5725
5754
  };
5726
5755
  class Deprecated extends Rule {
5727
5756
  constructor(options) {
5728
- super({ ...defaults$p, ...options });
5757
+ super({ ...defaults$q, ...options });
5729
5758
  }
5730
5759
  static schema() {
5731
5760
  return {
@@ -5879,12 +5908,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
5879
5908
  }
5880
5909
  };
5881
5910
 
5882
- const defaults$o = {
5911
+ const defaults$p = {
5883
5912
  style: "uppercase"
5884
5913
  };
5885
5914
  class DoctypeStyle extends Rule {
5886
5915
  constructor(options) {
5887
- super({ ...defaults$o, ...options });
5916
+ super({ ...defaults$p, ...options });
5888
5917
  }
5889
5918
  static schema() {
5890
5919
  return {
@@ -5912,13 +5941,13 @@ class DoctypeStyle extends Rule {
5912
5941
  }
5913
5942
  }
5914
5943
 
5915
- const defaults$n = {
5944
+ const defaults$o = {
5916
5945
  style: "lowercase"
5917
5946
  };
5918
5947
  class ElementCase extends Rule {
5919
5948
  style;
5920
5949
  constructor(options) {
5921
- super({ ...defaults$n, ...options });
5950
+ super({ ...defaults$o, ...options });
5922
5951
  this.style = new CaseStyle(this.options.style, "element-case");
5923
5952
  }
5924
5953
  static schema() {
@@ -5978,7 +6007,7 @@ class ElementCase extends Rule {
5978
6007
  }
5979
6008
  }
5980
6009
 
5981
- const defaults$m = {
6010
+ const defaults$n = {
5982
6011
  pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
5983
6012
  whitelist: [],
5984
6013
  blacklist: []
@@ -5986,7 +6015,7 @@ const defaults$m = {
5986
6015
  class ElementName extends Rule {
5987
6016
  pattern;
5988
6017
  constructor(options) {
5989
- super({ ...defaults$m, ...options });
6018
+ super({ ...defaults$n, ...options });
5990
6019
  this.pattern = new RegExp(this.options.pattern);
5991
6020
  }
5992
6021
  static schema() {
@@ -6023,7 +6052,7 @@ class ElementName extends Rule {
6023
6052
  ...context.blacklist.map((cur) => `- ${cur}`)
6024
6053
  ];
6025
6054
  }
6026
- if (context.pattern !== defaults$m.pattern) {
6055
+ if (context.pattern !== defaults$n.pattern) {
6027
6056
  return [
6028
6057
  `<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
6029
6058
  "",
@@ -6540,7 +6569,7 @@ class EmptyTitle extends Rule {
6540
6569
  }
6541
6570
  }
6542
6571
 
6543
- const defaults$l = {
6572
+ const defaults$m = {
6544
6573
  allowArrayBrackets: true,
6545
6574
  allowCheckboxDefault: true,
6546
6575
  shared: ["radio", "button", "reset", "submit"]
@@ -6600,7 +6629,7 @@ function getDocumentation(context) {
6600
6629
  }
6601
6630
  class FormDupName extends Rule {
6602
6631
  constructor(options) {
6603
- super({ ...defaults$l, ...options });
6632
+ super({ ...defaults$m, ...options });
6604
6633
  }
6605
6634
  static schema() {
6606
6635
  return {
@@ -6759,7 +6788,7 @@ class FormDupName extends Rule {
6759
6788
  }
6760
6789
  }
6761
6790
 
6762
- const defaults$k = {
6791
+ const defaults$l = {
6763
6792
  allowMultipleH1: false,
6764
6793
  minInitialRank: "h1",
6765
6794
  sectioningRoots: ["dialog", '[role="dialog"]', '[role="alertdialog"]']
@@ -6791,7 +6820,7 @@ class HeadingLevel extends Rule {
6791
6820
  sectionRoots;
6792
6821
  stack = [];
6793
6822
  constructor(options) {
6794
- super({ ...defaults$k, ...options });
6823
+ super({ ...defaults$l, ...options });
6795
6824
  this.minInitialRank = parseMaxInitial(this.options.minInitialRank);
6796
6825
  this.sectionRoots = this.options.sectioningRoots.map((it) => new Compound(it));
6797
6826
  this.stack.push({
@@ -7030,7 +7059,7 @@ class HiddenFocusable extends Rule {
7030
7059
  }
7031
7060
  }
7032
7061
 
7033
- const defaults$j = {
7062
+ const defaults$k = {
7034
7063
  pattern: "kebabcase"
7035
7064
  };
7036
7065
  function exclude$1(set, ...values) {
@@ -7046,7 +7075,7 @@ class IdPattern extends BasePatternRule {
7046
7075
  super({
7047
7076
  ruleId: "id-pattern",
7048
7077
  attr: "id",
7049
- options: { ...defaults$j, ...options },
7078
+ options: { ...defaults$k, ...options },
7050
7079
  allowedPatterns
7051
7080
  });
7052
7081
  }
@@ -7368,13 +7397,13 @@ function findLabelByParent(el) {
7368
7397
  return [];
7369
7398
  }
7370
7399
 
7371
- const defaults$i = {
7400
+ const defaults$j = {
7372
7401
  maxlength: 70
7373
7402
  };
7374
7403
  class LongTitle extends Rule {
7375
7404
  maxlength;
7376
7405
  constructor(options) {
7377
- super({ ...defaults$i, ...options });
7406
+ super({ ...defaults$j, ...options });
7378
7407
  this.maxlength = this.options.maxlength;
7379
7408
  }
7380
7409
  static schema() {
@@ -7478,12 +7507,12 @@ class MapIdName extends Rule {
7478
7507
  }
7479
7508
  }
7480
7509
 
7481
- const defaults$h = {
7510
+ const defaults$i = {
7482
7511
  allowLongDelay: false
7483
7512
  };
7484
7513
  class MetaRefresh extends Rule {
7485
7514
  constructor(options) {
7486
- super({ ...defaults$h, ...options });
7515
+ super({ ...defaults$i, ...options });
7487
7516
  }
7488
7517
  documentation() {
7489
7518
  return {
@@ -7594,7 +7623,7 @@ class MultipleLabeledControls extends Rule {
7594
7623
  }
7595
7624
  }
7596
7625
 
7597
- const defaults$g = {
7626
+ const defaults$h = {
7598
7627
  pattern: "camelcase"
7599
7628
  };
7600
7629
  function exclude(set, ...values) {
@@ -7610,7 +7639,7 @@ class NamePattern extends BasePatternRule {
7610
7639
  super({
7611
7640
  ruleId: "name-pattern",
7612
7641
  attr: "name",
7613
- options: { ...defaults$g, ...options },
7642
+ options: { ...defaults$h, ...options },
7614
7643
  allowedPatterns
7615
7644
  });
7616
7645
  }
@@ -7701,13 +7730,13 @@ class NoAbstractRole extends Rule {
7701
7730
  }
7702
7731
  }
7703
7732
 
7704
- const defaults$f = {
7733
+ const defaults$g = {
7705
7734
  include: null,
7706
7735
  exclude: null
7707
7736
  };
7708
7737
  class NoAutoplay extends Rule {
7709
7738
  constructor(options) {
7710
- super({ ...defaults$f, ...options });
7739
+ super({ ...defaults$g, ...options });
7711
7740
  }
7712
7741
  documentation(context) {
7713
7742
  return {
@@ -8029,14 +8058,14 @@ class NoImplicitInputType extends Rule {
8029
8058
  }
8030
8059
  }
8031
8060
 
8032
- const defaults$e = {
8061
+ const defaults$f = {
8033
8062
  include: null,
8034
8063
  exclude: null,
8035
8064
  allowedProperties: ["display"]
8036
8065
  };
8037
8066
  class NoInlineStyle extends Rule {
8038
8067
  constructor(options) {
8039
- super({ ...defaults$e, ...options });
8068
+ super({ ...defaults$f, ...options });
8040
8069
  }
8041
8070
  static schema() {
8042
8071
  return {
@@ -8222,7 +8251,7 @@ class NoMultipleMain extends Rule {
8222
8251
  }
8223
8252
  }
8224
8253
 
8225
- const defaults$d = {
8254
+ const defaults$e = {
8226
8255
  relaxed: false
8227
8256
  };
8228
8257
  const textRegexp = /([<>]|&(?![a-zA-Z0-9#]+;))/g;
@@ -8240,7 +8269,7 @@ const replacementTable = {
8240
8269
  class NoRawCharacters extends Rule {
8241
8270
  relaxed;
8242
8271
  constructor(options) {
8243
- super({ ...defaults$d, ...options });
8272
+ super({ ...defaults$e, ...options });
8244
8273
  this.relaxed = this.options.relaxed;
8245
8274
  }
8246
8275
  static schema() {
@@ -8420,13 +8449,13 @@ class NoRedundantRole extends Rule {
8420
8449
  }
8421
8450
 
8422
8451
  const xmlns = /^(.+):.+$/;
8423
- const defaults$c = {
8452
+ const defaults$d = {
8424
8453
  ignoreForeign: true,
8425
8454
  ignoreXML: true
8426
8455
  };
8427
8456
  class NoSelfClosing extends Rule {
8428
8457
  constructor(options) {
8429
- super({ ...defaults$c, ...options });
8458
+ super({ ...defaults$d, ...options });
8430
8459
  }
8431
8460
  static schema() {
8432
8461
  return {
@@ -8476,7 +8505,20 @@ function isRelevant(node, options) {
8476
8505
  return true;
8477
8506
  }
8478
8507
 
8508
+ const defaults$c = {
8509
+ allowTemplate: true
8510
+ };
8479
8511
  class NoStyleTag extends Rule {
8512
+ constructor(options) {
8513
+ super({ ...defaults$c, ...options });
8514
+ }
8515
+ static schema() {
8516
+ return {
8517
+ allowTemplate: {
8518
+ type: "boolean"
8519
+ }
8520
+ };
8521
+ }
8480
8522
  documentation() {
8481
8523
  return {
8482
8524
  description: "Prefer to use external stylesheets with the `<link>` tag instead of inlining the styling.",
@@ -8484,9 +8526,13 @@ class NoStyleTag extends Rule {
8484
8526
  };
8485
8527
  }
8486
8528
  setup() {
8529
+ const { allowTemplate } = this.options;
8487
8530
  this.on("tag:start", (event) => {
8488
8531
  const node = event.target;
8489
8532
  if (node.tagName === "style") {
8533
+ if (allowTemplate && node.parent?.is("template")) {
8534
+ return;
8535
+ }
8490
8536
  this.report(node, "Use external stylesheet with <link> instead of <style> tag");
8491
8537
  }
8492
8538
  });
@@ -9393,7 +9439,7 @@ function getTextFromReference(document, id) {
9393
9439
  if (!id || id instanceof DynamicValue) {
9394
9440
  return id;
9395
9441
  }
9396
- const selector = `#${id}`;
9442
+ const selector = generateIdSelector(id);
9397
9443
  const ref = document.querySelector(selector);
9398
9444
  if (ref) {
9399
9445
  return ref.textContent;
@@ -12132,7 +12178,7 @@ class EventHandler {
12132
12178
  }
12133
12179
 
12134
12180
  const name = "html-validate";
12135
- const version = "10.6.0";
12181
+ const version = "10.7.0";
12136
12182
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
12137
12183
 
12138
12184
  function freeze(src) {
@@ -12678,31 +12724,34 @@ class Parser {
12678
12724
  * @internal
12679
12725
  */
12680
12726
  consumeDirective(token) {
12681
- const [text, preamble, action, separator1, directive, postamble] = token.data;
12682
- if (!postamble.startsWith("]")) {
12683
- throw new ParserError(token.location, `Missing end bracket "]" on directive "${text}"`);
12727
+ const [text, preamble, prefix, action, separator1, directive, postamble] = token.data;
12728
+ const hasStartBracket = preamble.includes("[");
12729
+ const hasEndBracket = postamble.startsWith("]");
12730
+ if (hasStartBracket && !hasEndBracket) {
12731
+ this.trigger("parse:error", {
12732
+ location: sliceLocation(token.location, preamble.length - 1, -postamble.length),
12733
+ message: `Missing end bracket "]" on directive "${text}"`
12734
+ });
12735
+ return;
12684
12736
  }
12685
12737
  const match = /^(.*?)(?:(\s*(?:--|:)\s*)(.*))?$/.exec(directive);
12686
12738
  if (!match) {
12687
12739
  throw new Error(`Failed to parse directive "${text}"`);
12688
12740
  }
12689
12741
  if (!isValidDirective(action)) {
12742
+ const begin = preamble.length;
12743
+ const end = preamble.length + prefix.length + action.length;
12690
12744
  this.trigger("parse:error", {
12691
- location: token.location,
12745
+ location: sliceLocation(token.location, begin, -text.length + end),
12692
12746
  message: `Unknown directive "${action}"`
12693
12747
  });
12694
12748
  return;
12695
12749
  }
12696
12750
  const [, data, separator2, comment] = match;
12697
- const prefix = "html-validate-";
12698
- const actionOffset = preamble.length;
12751
+ const actionOffset = preamble.length + prefix.length;
12699
12752
  const optionsOffset = actionOffset + action.length + separator1.length;
12700
12753
  const commentOffset = optionsOffset + data.length + (separator2 || "").length;
12701
- const location = sliceLocation(
12702
- token.location,
12703
- preamble.length - prefix.length - 1,
12704
- -postamble.length + 1
12705
- );
12754
+ const location = sliceLocation(token.location, preamble.length - 1, -postamble.length + 1);
12706
12755
  const actionLocation = sliceLocation(
12707
12756
  token.location,
12708
12757
  actionOffset,