html-validate 7.12.1 → 7.12.2

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
@@ -3653,7 +3653,7 @@ class Rule {
3653
3653
  }
3654
3654
  }
3655
3655
 
3656
- const defaults$v = {
3656
+ const defaults$w = {
3657
3657
  allowExternal: true,
3658
3658
  allowRelative: true,
3659
3659
  allowAbsolute: true,
@@ -3697,7 +3697,7 @@ function matchList(value, list) {
3697
3697
  }
3698
3698
  class AllowedLinks extends Rule {
3699
3699
  constructor(options) {
3700
- super({ ...defaults$v, ...options });
3700
+ super({ ...defaults$w, ...options });
3701
3701
  this.allowExternal = parseAllow(this.options.allowExternal);
3702
3702
  this.allowRelative = parseAllow(this.options.allowRelative);
3703
3703
  this.allowAbsolute = parseAllow(this.options.allowAbsolute);
@@ -3845,7 +3845,7 @@ var RuleContext$1;
3845
3845
  RuleContext["MISSING_ALT"] = "missing-alt";
3846
3846
  RuleContext["MISSING_HREF"] = "missing-href";
3847
3847
  })(RuleContext$1 || (RuleContext$1 = {}));
3848
- const defaults$u = {
3848
+ const defaults$v = {
3849
3849
  accessible: true,
3850
3850
  };
3851
3851
  function findByTarget(target, siblings) {
@@ -3883,7 +3883,7 @@ function getDescription$1(context) {
3883
3883
  }
3884
3884
  class AreaAlt extends Rule {
3885
3885
  constructor(options) {
3886
- super({ ...defaults$u, ...options });
3886
+ super({ ...defaults$v, ...options });
3887
3887
  }
3888
3888
  static schema() {
3889
3889
  return {
@@ -4052,13 +4052,13 @@ class ConfigError extends UserError {
4052
4052
  }
4053
4053
  }
4054
4054
 
4055
- const defaults$t = {
4055
+ const defaults$u = {
4056
4056
  style: "lowercase",
4057
4057
  ignoreForeign: true,
4058
4058
  };
4059
4059
  class AttrCase extends Rule {
4060
4060
  constructor(options) {
4061
- super({ ...defaults$t, ...options });
4061
+ super({ ...defaults$u, ...options });
4062
4062
  this.style = new rulesHelper.CaseStyle(this.options.style, "attr-case");
4063
4063
  }
4064
4064
  static schema() {
@@ -4403,7 +4403,7 @@ class AttrDelimiter extends Rule {
4403
4403
  }
4404
4404
 
4405
4405
  const DEFAULT_PATTERN = "[a-z0-9-:]+";
4406
- const defaults$s = {
4406
+ const defaults$t = {
4407
4407
  pattern: DEFAULT_PATTERN,
4408
4408
  ignoreForeign: true,
4409
4409
  };
@@ -4440,7 +4440,7 @@ function generateDescription(name, pattern) {
4440
4440
  }
4441
4441
  class AttrPattern extends Rule {
4442
4442
  constructor(options) {
4443
- super({ ...defaults$s, ...options });
4443
+ super({ ...defaults$t, ...options });
4444
4444
  this.pattern = generateRegexp(this.options.pattern);
4445
4445
  }
4446
4446
  static schema() {
@@ -4501,7 +4501,7 @@ var QuoteStyle;
4501
4501
  QuoteStyle["AUTO_QUOTE"] = "auto";
4502
4502
  QuoteStyle["ANY_QUOTE"] = "any";
4503
4503
  })(QuoteStyle || (QuoteStyle = {}));
4504
- const defaults$r = {
4504
+ const defaults$s = {
4505
4505
  style: "auto",
4506
4506
  unquoted: false,
4507
4507
  };
@@ -4568,7 +4568,7 @@ class AttrQuotes extends Rule {
4568
4568
  };
4569
4569
  }
4570
4570
  constructor(options) {
4571
- super({ ...defaults$r, ...options });
4571
+ super({ ...defaults$s, ...options });
4572
4572
  this.style = parseStyle$4(this.options.style);
4573
4573
  }
4574
4574
  setup() {
@@ -4738,12 +4738,12 @@ class AttributeAllowedValues extends Rule {
4738
4738
  }
4739
4739
  }
4740
4740
 
4741
- const defaults$q = {
4741
+ const defaults$r = {
4742
4742
  style: "omit",
4743
4743
  };
4744
4744
  class AttributeBooleanStyle extends Rule {
4745
4745
  constructor(options) {
4746
- super({ ...defaults$q, ...options });
4746
+ super({ ...defaults$r, ...options });
4747
4747
  this.hasInvalidStyle = parseStyle$3(this.options.style);
4748
4748
  }
4749
4749
  static schema() {
@@ -4819,12 +4819,12 @@ function reportMessage$1(attr, style) {
4819
4819
  return "";
4820
4820
  }
4821
4821
 
4822
- const defaults$p = {
4822
+ const defaults$q = {
4823
4823
  style: "omit",
4824
4824
  };
4825
4825
  class AttributeEmptyStyle extends Rule {
4826
4826
  constructor(options) {
4827
- super({ ...defaults$p, ...options });
4827
+ super({ ...defaults$q, ...options });
4828
4828
  this.hasInvalidStyle = parseStyle$2(this.options.style);
4829
4829
  }
4830
4830
  static schema() {
@@ -4980,12 +4980,12 @@ function describePattern(pattern) {
4980
4980
  }
4981
4981
  }
4982
4982
 
4983
- const defaults$o = {
4983
+ const defaults$p = {
4984
4984
  pattern: "kebabcase",
4985
4985
  };
4986
4986
  class ClassPattern extends Rule {
4987
4987
  constructor(options) {
4988
- super({ ...defaults$o, ...options });
4988
+ super({ ...defaults$p, ...options });
4989
4989
  this.pattern = parsePattern(this.options.pattern);
4990
4990
  }
4991
4991
  static schema() {
@@ -5094,13 +5094,13 @@ class CloseOrder extends Rule {
5094
5094
  }
5095
5095
  }
5096
5096
 
5097
- const defaults$n = {
5097
+ const defaults$o = {
5098
5098
  include: null,
5099
5099
  exclude: null,
5100
5100
  };
5101
5101
  class Deprecated extends Rule {
5102
5102
  constructor(options) {
5103
- super({ ...defaults$n, ...options });
5103
+ super({ ...defaults$o, ...options });
5104
5104
  }
5105
5105
  static schema() {
5106
5106
  return {
@@ -5263,12 +5263,12 @@ let NoStyleTag$1 = class NoStyleTag extends Rule {
5263
5263
  }
5264
5264
  };
5265
5265
 
5266
- const defaults$m = {
5266
+ const defaults$n = {
5267
5267
  style: "uppercase",
5268
5268
  };
5269
5269
  class DoctypeStyle extends Rule {
5270
5270
  constructor(options) {
5271
- super({ ...defaults$m, ...options });
5271
+ super({ ...defaults$n, ...options });
5272
5272
  }
5273
5273
  static schema() {
5274
5274
  return {
@@ -5300,12 +5300,12 @@ class DoctypeStyle extends Rule {
5300
5300
  }
5301
5301
  }
5302
5302
 
5303
- const defaults$l = {
5303
+ const defaults$m = {
5304
5304
  style: "lowercase",
5305
5305
  };
5306
5306
  class ElementCase extends Rule {
5307
5307
  constructor(options) {
5308
- super({ ...defaults$l, ...options });
5308
+ super({ ...defaults$m, ...options });
5309
5309
  this.style = new rulesHelper.CaseStyle(this.options.style, "element-case");
5310
5310
  }
5311
5311
  static schema() {
@@ -5371,14 +5371,14 @@ class ElementCase extends Rule {
5371
5371
  }
5372
5372
  }
5373
5373
 
5374
- const defaults$k = {
5374
+ const defaults$l = {
5375
5375
  pattern: "^[a-z][a-z0-9\\-._]*-[a-z0-9\\-._]*$",
5376
5376
  whitelist: [],
5377
5377
  blacklist: [],
5378
5378
  };
5379
5379
  class ElementName extends Rule {
5380
5380
  constructor(options) {
5381
- super({ ...defaults$k, ...options });
5381
+ super({ ...defaults$l, ...options });
5382
5382
  // eslint-disable-next-line security/detect-non-literal-regexp
5383
5383
  this.pattern = new RegExp(this.options.pattern);
5384
5384
  }
@@ -5419,7 +5419,7 @@ class ElementName extends Rule {
5419
5419
  ...context.blacklist.map((cur) => `- ${cur}`),
5420
5420
  ];
5421
5421
  }
5422
- if (context.pattern !== defaults$k.pattern) {
5422
+ if (context.pattern !== defaults$l.pattern) {
5423
5423
  return [
5424
5424
  `<${context.tagName}> is not a valid element name. This project is configured to only allow names matching the following regular expression:`,
5425
5425
  "",
@@ -5963,29 +5963,70 @@ class EmptyTitle extends Rule {
5963
5963
  }
5964
5964
  }
5965
5965
 
5966
+ const defaults$k = {
5967
+ allowArrayBrackets: true,
5968
+ shared: ["radio"],
5969
+ };
5966
5970
  const UNIQUE_CACHE_KEY = Symbol("form-elements-unique");
5967
5971
  const SHARED_CACHE_KEY = Symbol("form-elements-shared");
5968
5972
  function haveName(name) {
5969
5973
  return typeof name === "string" && name !== "";
5970
5974
  }
5971
- function allowSharedName(node) {
5975
+ function allowSharedName(node, shared) {
5972
5976
  const type = node.getAttribute("type");
5973
- return Boolean(type && type.valueMatches(["radio", "checkbox"], false));
5977
+ return Boolean(type && type.valueMatches(shared, false));
5978
+ }
5979
+ function getDocumentation(context) {
5980
+ const trailer = "Each form control must have a unique name.";
5981
+ if (!context) {
5982
+ return trailer;
5983
+ }
5984
+ else {
5985
+ const { name } = context;
5986
+ switch (context.kind) {
5987
+ case "duplicate":
5988
+ return [`Duplicate form control name "${name}"`, trailer].join("\n");
5989
+ case "mix":
5990
+ return [
5991
+ `Form control name cannot mix regular name "{{ name }}" with array brackets "{{ name }}[]"`,
5992
+ trailer,
5993
+ ].join("\n");
5994
+ }
5995
+ }
5974
5996
  }
5975
5997
  class FormDupName extends Rule {
5976
- documentation() {
5998
+ constructor(options) {
5999
+ super({ ...defaults$k, ...options });
6000
+ }
6001
+ static schema() {
5977
6002
  return {
5978
- description: "Each form control must have a unique name.",
6003
+ allowArrayBrackets: {
6004
+ type: "boolean",
6005
+ },
6006
+ shared: {
6007
+ type: "array",
6008
+ items: {
6009
+ enum: ["radio", "checkbox", "submit"],
6010
+ },
6011
+ },
6012
+ };
6013
+ }
6014
+ documentation(context) {
6015
+ return {
6016
+ description: getDocumentation(context),
5979
6017
  url: "https://html-validate.org/rules/form-dup-name.html",
5980
6018
  };
5981
6019
  }
5982
6020
  setup() {
5983
6021
  const selector = this.getSelector();
6022
+ const { shared } = this.options;
5984
6023
  this.on("dom:ready", (event) => {
5985
6024
  var _a, _b;
5986
6025
  const { document } = event;
5987
6026
  const controls = document.querySelectorAll(selector);
5988
- const [sharedControls, uniqueControls] = rulesHelper.partition(controls, allowSharedName);
6027
+ const [sharedControls, uniqueControls] = rulesHelper.partition(controls, (it) => {
6028
+ return allowSharedName(it, shared);
6029
+ });
5989
6030
  /* validate all form controls which require unique elements first so each
5990
6031
  * form has a populated list of unique names */
5991
6032
  for (const control of uniqueControls) {
@@ -6012,9 +6053,35 @@ class FormDupName extends Rule {
6012
6053
  }
6013
6054
  validateUniqueName(control, form, attr, name) {
6014
6055
  const elements = this.getUniqueElements(form);
6056
+ const { allowArrayBrackets } = this.options;
6057
+ if (allowArrayBrackets) {
6058
+ const isarray = name.endsWith("[]");
6059
+ const basename = isarray ? name.slice(0, -2) : name;
6060
+ const details = elements.get(basename);
6061
+ if (details && details.array !== isarray) {
6062
+ const context = {
6063
+ name: basename,
6064
+ kind: "mix",
6065
+ };
6066
+ this.report({
6067
+ node: control,
6068
+ location: attr.valueLocation,
6069
+ message: 'Cannot mix "{{ name }}[]" and "{{ name }}"',
6070
+ context,
6071
+ });
6072
+ return;
6073
+ }
6074
+ else if (!details && isarray) {
6075
+ elements.set(basename, {
6076
+ array: true,
6077
+ });
6078
+ return;
6079
+ }
6080
+ }
6015
6081
  if (elements.has(name)) {
6016
6082
  const context = {
6017
6083
  name,
6084
+ kind: "duplicate",
6018
6085
  };
6019
6086
  this.report({
6020
6087
  node: control,
@@ -6024,7 +6091,9 @@ class FormDupName extends Rule {
6024
6091
  });
6025
6092
  }
6026
6093
  else {
6027
- elements.add(name);
6094
+ elements.set(name, {
6095
+ array: false,
6096
+ });
6028
6097
  }
6029
6098
  }
6030
6099
  validateSharedName(control, form, attr, name) {
@@ -6037,6 +6106,7 @@ class FormDupName extends Rule {
6037
6106
  (sharedElements.has(name) && sharedElements.get(name) !== type)) {
6038
6107
  const context = {
6039
6108
  name,
6109
+ kind: "duplicate",
6040
6110
  };
6041
6111
  this.report({
6042
6112
  node: control,
@@ -6068,7 +6138,7 @@ class FormDupName extends Rule {
6068
6138
  return existing;
6069
6139
  }
6070
6140
  else {
6071
- const elements = new Set();
6141
+ const elements = new Map();
6072
6142
  form.cacheSet(UNIQUE_CACHE_KEY, elements);
6073
6143
  return elements;
6074
6144
  }
@@ -11467,7 +11537,7 @@ class HtmlValidate {
11467
11537
  /** @public */
11468
11538
  const name = "html-validate";
11469
11539
  /** @public */
11470
- const version = "7.12.1";
11540
+ const version = "7.12.2";
11471
11541
  /** @public */
11472
11542
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
11473
11543