html-validate 7.12.0 → 7.12.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.
package/README.md CHANGED
@@ -16,7 +16,7 @@ Offline HTML5 validator. Validates either a full document or a smaller
16
16
  ## Usage
17
17
 
18
18
  npm install -g html-validate
19
- html-validate FILENAME..
19
+ html-validate [OPTIONS] [FILENAME..] [DIR..]
20
20
 
21
21
  ## Configuration
22
22
 
package/dist/cjs/core.js CHANGED
@@ -5963,17 +5963,14 @@ class EmptyTitle extends Rule {
5963
5963
  }
5964
5964
  }
5965
5965
 
5966
- const CACHE_KEY = Symbol("form-elements");
5966
+ const UNIQUE_CACHE_KEY = Symbol("form-elements-unique");
5967
+ const SHARED_CACHE_KEY = Symbol("form-elements-shared");
5967
5968
  function haveName(name) {
5968
5969
  return typeof name === "string" && name !== "";
5969
5970
  }
5970
- function isRelevant$4(node) {
5971
- if (node.is("input")) {
5972
- /* ignore radiobuttons and checkboxes */
5973
- const type = node.getAttribute("type");
5974
- return !type || !type.valueMatches(["radio", "checkbox"], true);
5975
- }
5976
- return true;
5971
+ function allowSharedName(node) {
5972
+ const type = node.getAttribute("type");
5973
+ return Boolean(type && type.valueMatches(["radio", "checkbox"], false));
5977
5974
  }
5978
5975
  class FormDupName extends Rule {
5979
5976
  documentation() {
@@ -5985,21 +5982,36 @@ class FormDupName extends Rule {
5985
5982
  setup() {
5986
5983
  const selector = this.getSelector();
5987
5984
  this.on("dom:ready", (event) => {
5988
- var _a;
5985
+ var _a, _b;
5989
5986
  const { document } = event;
5990
- const controls = document.querySelectorAll(selector).filter(isRelevant$4);
5991
- for (const control of controls) {
5987
+ const controls = document.querySelectorAll(selector);
5988
+ const [sharedControls, uniqueControls] = rulesHelper.partition(controls, allowSharedName);
5989
+ /* validate all form controls which require unique elements first so each
5990
+ * form has a populated list of unique names */
5991
+ for (const control of uniqueControls) {
5992
+ const attr = control.getAttribute("name");
5993
+ const name = attr === null || attr === void 0 ? void 0 : attr.value;
5994
+ if (!attr || !haveName(name)) {
5995
+ continue;
5996
+ }
5997
+ const form = (_a = control.closest("form")) !== null && _a !== void 0 ? _a : document.root;
5998
+ this.validateUniqueName(control, form, attr, name);
5999
+ }
6000
+ /* validate all form controls which allows shared names to ensure there is
6001
+ * no collision with other form controls */
6002
+ for (const control of sharedControls) {
5992
6003
  const attr = control.getAttribute("name");
5993
6004
  const name = attr === null || attr === void 0 ? void 0 : attr.value;
5994
- if (attr && haveName(name)) {
5995
- const form = (_a = control.closest("form")) !== null && _a !== void 0 ? _a : document.root;
5996
- this.validateName(control, form, attr, name);
6005
+ if (!attr || !haveName(name)) {
6006
+ continue;
5997
6007
  }
6008
+ const form = (_b = control.closest("form")) !== null && _b !== void 0 ? _b : document.root;
6009
+ this.validateSharedName(control, form, attr, name);
5998
6010
  }
5999
6011
  });
6000
6012
  }
6001
- validateName(control, form, attr, name) {
6002
- const elements = this.getElements(form);
6013
+ validateUniqueName(control, form, attr, name) {
6014
+ const elements = this.getUniqueElements(form);
6003
6015
  if (elements.has(name)) {
6004
6016
  const context = {
6005
6017
  name,
@@ -6015,6 +6027,26 @@ class FormDupName extends Rule {
6015
6027
  elements.add(name);
6016
6028
  }
6017
6029
  }
6030
+ validateSharedName(control, form, attr, name) {
6031
+ var _a;
6032
+ const uniqueElements = this.getUniqueElements(form);
6033
+ const sharedElements = this.getSharedElements(form);
6034
+ /* istanbul ignore next: type will always be set or shared name wouldn't be allowed */
6035
+ const type = (_a = control.getAttributeValue("type")) !== null && _a !== void 0 ? _a : "";
6036
+ if (uniqueElements.has(name) ||
6037
+ (sharedElements.has(name) && sharedElements.get(name) !== type)) {
6038
+ const context = {
6039
+ name,
6040
+ };
6041
+ this.report({
6042
+ node: control,
6043
+ location: attr.valueLocation,
6044
+ message: 'Duplicate form control name "{{ name }}"',
6045
+ context,
6046
+ });
6047
+ }
6048
+ sharedElements.set(name, type);
6049
+ }
6018
6050
  getSelector() {
6019
6051
  const tags = this.getTagsWithProperty("formAssociated").filter((it) => {
6020
6052
  return this.isListedElement(it);
@@ -6030,14 +6062,25 @@ class FormDupName extends Rule {
6030
6062
  }
6031
6063
  return meta.formAssociated.listed;
6032
6064
  }
6033
- getElements(form) {
6034
- const existing = form.cacheGet(CACHE_KEY);
6065
+ getUniqueElements(form) {
6066
+ const existing = form.cacheGet(UNIQUE_CACHE_KEY);
6035
6067
  if (existing) {
6036
6068
  return existing;
6037
6069
  }
6038
6070
  else {
6039
6071
  const elements = new Set();
6040
- form.cacheSet(CACHE_KEY, elements);
6072
+ form.cacheSet(UNIQUE_CACHE_KEY, elements);
6073
+ return elements;
6074
+ }
6075
+ }
6076
+ getSharedElements(form) {
6077
+ const existing = form.cacheGet(SHARED_CACHE_KEY);
6078
+ if (existing) {
6079
+ return existing;
6080
+ }
6081
+ else {
6082
+ const elements = new Map();
6083
+ form.cacheSet(SHARED_CACHE_KEY, elements);
6041
6084
  return elements;
6042
6085
  }
6043
6086
  }
@@ -11424,7 +11467,7 @@ class HtmlValidate {
11424
11467
  /** @public */
11425
11468
  const name = "html-validate";
11426
11469
  /** @public */
11427
- const version = "7.12.0";
11470
+ const version = "7.12.1";
11428
11471
  /** @public */
11429
11472
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
11430
11473