html-validate 10.3.1 → 10.5.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
@@ -863,8 +863,15 @@ const definitions = {
863
863
  title: "Set to true if this attribute can optionally omit its value"
864
864
  },
865
865
  required: {
866
- type: "boolean",
867
- title: "Set to true if this attribute is required"
866
+ title: "Set to true or a function to evaluate if this attribute is required",
867
+ oneOf: [
868
+ {
869
+ type: "boolean"
870
+ },
871
+ {
872
+ "function": true
873
+ }
874
+ ]
868
875
  }
869
876
  }
870
877
  },
@@ -1592,7 +1599,7 @@ var NodeType = /* @__PURE__ */ ((NodeType2) => {
1592
1599
  })(NodeType || {});
1593
1600
 
1594
1601
  const DOCUMENT_NODE_NAME = "#document";
1595
- const TEXT_CONTENT = Symbol("textContent");
1602
+ const TEXT_CONTENT = /* @__PURE__ */ Symbol("textContent");
1596
1603
  let counter = 0;
1597
1604
  class DOMNode {
1598
1605
  nodeName;
@@ -2395,8 +2402,8 @@ class TextNode extends DOMNode {
2395
2402
  }
2396
2403
  }
2397
2404
 
2398
- const ROLE = Symbol("role");
2399
- const TABINDEX = Symbol("tabindex");
2405
+ const ROLE = /* @__PURE__ */ Symbol("role");
2406
+ const TABINDEX = /* @__PURE__ */ Symbol("tabindex");
2400
2407
  var NodeClosed = /* @__PURE__ */ ((NodeClosed2) => {
2401
2408
  NodeClosed2[NodeClosed2["Open"] = 0] = "Open";
2402
2409
  NodeClosed2[NodeClosed2["EndTag"] = 1] = "EndTag";
@@ -3352,7 +3359,7 @@ function parseSeverity(value) {
3352
3359
  }
3353
3360
  }
3354
3361
 
3355
- const cacheKey = Symbol("aria-naming");
3362
+ const cacheKey = /* @__PURE__ */ Symbol("aria-naming");
3356
3363
  const defaultValue = "allowed";
3357
3364
  const prohibitedRoles = [
3358
3365
  "caption",
@@ -3571,10 +3578,10 @@ function isPresentation(node) {
3571
3578
  }
3572
3579
 
3573
3580
  const cachePrefix = classifyNodeText.name;
3574
- const HTML_CACHE_KEY = Symbol(`${cachePrefix}|html`);
3575
- const A11Y_CACHE_KEY = Symbol(`${cachePrefix}|a11y`);
3576
- const IGNORE_HIDDEN_ROOT_HTML_CACHE_KEY = Symbol(`${cachePrefix}|html|ignore-hidden-root`);
3577
- const IGNORE_HIDDEN_ROOT_A11Y_CACHE_KEY = Symbol(`${cachePrefix}|a11y|ignore-hidden-root`);
3581
+ const HTML_CACHE_KEY = /* @__PURE__ */ Symbol(`${cachePrefix}|html`);
3582
+ const A11Y_CACHE_KEY = /* @__PURE__ */ Symbol(`${cachePrefix}|a11y`);
3583
+ const IGNORE_HIDDEN_ROOT_HTML_CACHE_KEY = /* @__PURE__ */ Symbol(`${cachePrefix}|html|ignore-hidden-root`);
3584
+ const IGNORE_HIDDEN_ROOT_A11Y_CACHE_KEY = /* @__PURE__ */ Symbol(`${cachePrefix}|a11y|ignore-hidden-root`);
3578
3585
  var TextClassification = /* @__PURE__ */ ((TextClassification2) => {
3579
3586
  TextClassification2[TextClassification2["EMPTY_TEXT"] = 0] = "EMPTY_TEXT";
3580
3587
  TextClassification2[TextClassification2["DYNAMIC_TEXT"] = 1] = "DYNAMIC_TEXT";
@@ -6287,10 +6294,30 @@ class ElementRequiredAncestor extends Rule {
6287
6294
  }
6288
6295
  }
6289
6296
 
6297
+ const defaultMessage = `{{ tagName }} is missing required "{{ attr }}" attribute`;
6298
+ function normalizeRequired(element, attr) {
6299
+ const { required } = attr;
6300
+ if (typeof required === "function") {
6301
+ const result = required(element._adapter);
6302
+ switch (result) {
6303
+ case void 0:
6304
+ case null:
6305
+ case false:
6306
+ case "":
6307
+ return false;
6308
+ case true:
6309
+ return defaultMessage;
6310
+ default:
6311
+ return result;
6312
+ }
6313
+ } else {
6314
+ return required ? defaultMessage : false;
6315
+ }
6316
+ }
6290
6317
  class ElementRequiredAttributes extends Rule {
6291
6318
  documentation(context) {
6292
6319
  return {
6293
- description: `The \`<${context.element}>\` element is required to have a \`${context.attribute}\` attribute.`,
6320
+ description: `The \`${context.tagName}\` element is required to have a \`${context.attr}\` attribute.`,
6294
6321
  url: "https://html-validate.org/rules/element-required-attributes.html"
6295
6322
  };
6296
6323
  }
@@ -6302,23 +6329,29 @@ class ElementRequiredAttributes extends Rule {
6302
6329
  return;
6303
6330
  }
6304
6331
  for (const [key, attr] of Object.entries(meta.attributes)) {
6305
- if (!attr.required) {
6332
+ const required = normalizeRequired(node, attr);
6333
+ if (!required) {
6306
6334
  continue;
6307
6335
  }
6308
- if (node.hasAttribute(key)) continue;
6309
- const context = {
6310
- element: node.tagName,
6311
- attribute: key
6312
- };
6313
- this.report(
6314
- node,
6315
- `${node.annotatedName} is missing required "${key}" attribute`,
6316
- node.location,
6317
- context
6318
- );
6336
+ this.validateRequiredAttribute(node, key, required);
6319
6337
  }
6320
6338
  });
6321
6339
  }
6340
+ validateRequiredAttribute(node, attr, message) {
6341
+ if (node.hasAttribute(attr)) {
6342
+ return;
6343
+ }
6344
+ const context = {
6345
+ tagName: node.annotatedName,
6346
+ attr
6347
+ };
6348
+ this.report({
6349
+ node,
6350
+ message,
6351
+ location: node.location,
6352
+ context
6353
+ });
6354
+ }
6322
6355
  }
6323
6356
 
6324
6357
  function isCategory(value) {
@@ -6437,8 +6470,8 @@ const defaults$l = {
6437
6470
  allowCheckboxDefault: true,
6438
6471
  shared: ["radio", "button", "reset", "submit"]
6439
6472
  };
6440
- const UNIQUE_CACHE_KEY = Symbol("form-elements-unique");
6441
- const SHARED_CACHE_KEY = Symbol("form-elements-shared");
6473
+ const UNIQUE_CACHE_KEY = /* @__PURE__ */ Symbol("form-elements-unique");
6474
+ const SHARED_CACHE_KEY = /* @__PURE__ */ Symbol("form-elements-shared");
6442
6475
  function isEnabled(element) {
6443
6476
  if (isHTMLHidden(element)) {
6444
6477
  return false;
@@ -7728,7 +7761,7 @@ class NoDupClass extends Rule {
7728
7761
  }
7729
7762
  }
7730
7763
 
7731
- const CACHE_KEY = Symbol("no-dup-id");
7764
+ const CACHE_KEY = /* @__PURE__ */ Symbol("no-dup-id");
7732
7765
  class NoDupID extends Rule {
7733
7766
  documentation() {
7734
7767
  return {
@@ -11945,7 +11978,7 @@ class EventHandler {
11945
11978
  }
11946
11979
 
11947
11980
  const name = "html-validate";
11948
- const version = "10.3.1";
11981
+ const version = "10.5.0";
11949
11982
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
11950
11983
 
11951
11984
  function freeze(src) {