html-validate 10.3.1 → 10.4.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
  },
@@ -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) {
@@ -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.4.0";
11949
11982
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
11950
11983
 
11951
11984
  function freeze(src) {