@markuplint/rules 4.11.2 → 4.18.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.
Files changed (231) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/SKILL.md +76 -0
  3. package/lib/attr-check.d.ts +41 -5
  4. package/lib/attr-check.js +29 -5
  5. package/lib/attr-duplication/index.d.ts +7 -0
  6. package/lib/attr-duplication/index.js +7 -0
  7. package/lib/attr-duplication/meta.d.ts +1 -0
  8. package/lib/attr-duplication/meta.js +1 -0
  9. package/lib/attr-value-quotes/index.d.ts +10 -0
  10. package/lib/attr-value-quotes/index.js +10 -0
  11. package/lib/attr-value-quotes/meta.d.ts +1 -0
  12. package/lib/attr-value-quotes/meta.js +1 -0
  13. package/lib/case-sensitive-attr-name/index.d.ts +9 -0
  14. package/lib/case-sensitive-attr-name/index.js +8 -0
  15. package/lib/case-sensitive-attr-name/meta.d.ts +1 -0
  16. package/lib/case-sensitive-attr-name/meta.js +1 -0
  17. package/lib/case-sensitive-tag-name/index.d.ts +9 -0
  18. package/lib/case-sensitive-tag-name/index.js +8 -0
  19. package/lib/case-sensitive-tag-name/meta.d.ts +1 -0
  20. package/lib/case-sensitive-tag-name/meta.js +1 -0
  21. package/lib/character-reference/index.d.ts +8 -0
  22. package/lib/character-reference/index.js +16 -0
  23. package/lib/character-reference/meta.d.ts +1 -0
  24. package/lib/character-reference/meta.js +1 -0
  25. package/lib/class-naming/index.d.ts +9 -0
  26. package/lib/class-naming/index.js +8 -0
  27. package/lib/class-naming/meta.d.ts +1 -0
  28. package/lib/class-naming/meta.js +1 -0
  29. package/lib/create-message.d.ts +27 -0
  30. package/lib/create-message.js +56 -1
  31. package/lib/debug.d.ts +9 -0
  32. package/lib/debug.js +5 -0
  33. package/lib/deprecated-attr/index.d.ts +6 -0
  34. package/lib/deprecated-attr/index.js +6 -0
  35. package/lib/deprecated-attr/meta.d.ts +1 -0
  36. package/lib/deprecated-attr/meta.js +1 -0
  37. package/lib/deprecated-element/index.d.ts +8 -0
  38. package/lib/deprecated-element/index.js +8 -0
  39. package/lib/deprecated-element/meta.d.ts +1 -0
  40. package/lib/deprecated-element/meta.js +1 -0
  41. package/lib/disallowed-element/index.d.ts +7 -0
  42. package/lib/disallowed-element/index.js +7 -0
  43. package/lib/disallowed-element/meta.d.ts +1 -0
  44. package/lib/disallowed-element/meta.js +1 -0
  45. package/lib/doctype/index.d.ts +10 -0
  46. package/lib/doctype/index.js +8 -0
  47. package/lib/doctype/meta.d.ts +1 -0
  48. package/lib/doctype/meta.js +1 -0
  49. package/lib/end-tag/index.d.ts +7 -0
  50. package/lib/end-tag/index.js +7 -0
  51. package/lib/end-tag/meta.d.ts +1 -0
  52. package/lib/end-tag/meta.js +1 -0
  53. package/lib/heading-levels/index.d.ts +6 -0
  54. package/lib/heading-levels/index.js +6 -0
  55. package/lib/heading-levels/meta.d.ts +1 -0
  56. package/lib/heading-levels/meta.js +1 -0
  57. package/lib/helpers.d.ts +104 -0
  58. package/lib/helpers.js +105 -2
  59. package/lib/id-duplication/index.d.ts +7 -0
  60. package/lib/id-duplication/index.js +7 -0
  61. package/lib/id-duplication/meta.d.ts +1 -0
  62. package/lib/id-duplication/meta.js +1 -0
  63. package/lib/index.d.ts +23 -10
  64. package/lib/index.js +12 -0
  65. package/lib/ineffective-attr/index.d.ts +7 -0
  66. package/lib/ineffective-attr/index.js +7 -0
  67. package/lib/ineffective-attr/meta.d.ts +1 -0
  68. package/lib/ineffective-attr/meta.js +1 -0
  69. package/lib/invalid-attr/index.d.ts +24 -0
  70. package/lib/invalid-attr/index.js +17 -0
  71. package/lib/invalid-attr/meta.d.ts +1 -0
  72. package/lib/invalid-attr/meta.js +1 -0
  73. package/lib/label-has-control/index.d.ts +7 -0
  74. package/lib/label-has-control/index.js +11 -0
  75. package/lib/label-has-control/meta.d.ts +1 -0
  76. package/lib/label-has-control/meta.js +1 -0
  77. package/lib/landmark-roles/index.d.ts +14 -0
  78. package/lib/landmark-roles/index.js +21 -0
  79. package/lib/landmark-roles/meta.d.ts +1 -0
  80. package/lib/landmark-roles/meta.js +1 -0
  81. package/lib/neighbor-popovers/index.d.ts +8 -0
  82. package/lib/neighbor-popovers/index.js +26 -2
  83. package/lib/neighbor-popovers/meta.d.ts +1 -0
  84. package/lib/neighbor-popovers/meta.js +1 -0
  85. package/lib/no-ambiguous-navigable-target-names/index.d.ts +8 -0
  86. package/lib/no-ambiguous-navigable-target-names/index.js +8 -0
  87. package/lib/no-ambiguous-navigable-target-names/meta.d.ts +1 -0
  88. package/lib/no-ambiguous-navigable-target-names/meta.js +1 -0
  89. package/lib/no-boolean-attr-value/index.d.ts +7 -0
  90. package/lib/no-boolean-attr-value/index.js +7 -0
  91. package/lib/no-boolean-attr-value/meta.d.ts +1 -0
  92. package/lib/no-boolean-attr-value/meta.js +1 -0
  93. package/lib/no-consecutive-br/index.d.ts +8 -0
  94. package/lib/no-consecutive-br/index.js +8 -0
  95. package/lib/no-consecutive-br/meta.d.ts +1 -0
  96. package/lib/no-consecutive-br/meta.js +1 -0
  97. package/lib/no-default-value/index.d.ts +7 -0
  98. package/lib/no-default-value/index.js +7 -0
  99. package/lib/no-default-value/meta.d.ts +1 -0
  100. package/lib/no-default-value/meta.js +1 -0
  101. package/lib/no-duplicate-dt/index.d.ts +6 -0
  102. package/lib/no-duplicate-dt/index.js +6 -0
  103. package/lib/no-duplicate-dt/meta.d.ts +1 -0
  104. package/lib/no-duplicate-dt/meta.js +1 -0
  105. package/lib/no-empty-palpable-content/index.d.ts +13 -0
  106. package/lib/no-empty-palpable-content/index.js +12 -0
  107. package/lib/no-empty-palpable-content/meta.d.ts +1 -0
  108. package/lib/no-empty-palpable-content/meta.js +1 -0
  109. package/lib/no-hard-code-id/index.d.ts +8 -0
  110. package/lib/no-hard-code-id/index.js +8 -0
  111. package/lib/no-hard-code-id/meta.d.ts +1 -0
  112. package/lib/no-hard-code-id/meta.js +1 -0
  113. package/lib/no-orphaned-end-tag/index.d.ts +7 -0
  114. package/lib/no-orphaned-end-tag/index.js +7 -0
  115. package/lib/no-orphaned-end-tag/meta.d.ts +1 -0
  116. package/lib/no-orphaned-end-tag/meta.js +1 -0
  117. package/lib/no-refer-to-non-existent-id/index.d.ts +8 -0
  118. package/lib/no-refer-to-non-existent-id/index.js +9 -0
  119. package/lib/no-refer-to-non-existent-id/meta.d.ts +1 -0
  120. package/lib/no-refer-to-non-existent-id/meta.js +1 -0
  121. package/lib/no-use-event-handler-attr/index.d.ts +10 -0
  122. package/lib/no-use-event-handler-attr/index.js +8 -0
  123. package/lib/no-use-event-handler-attr/meta.d.ts +1 -0
  124. package/lib/no-use-event-handler-attr/meta.js +1 -0
  125. package/lib/permitted-contents/choice.d.ts +17 -0
  126. package/lib/permitted-contents/choice.js +30 -0
  127. package/lib/permitted-contents/complex-branch.d.ts +11 -7
  128. package/lib/permitted-contents/complex-branch.js +11 -7
  129. package/lib/permitted-contents/content-model.d.ts +11 -0
  130. package/lib/permitted-contents/content-model.js +32 -0
  131. package/lib/permitted-contents/count-pattern.d.ts +13 -7
  132. package/lib/permitted-contents/count-pattern.js +23 -7
  133. package/lib/permitted-contents/debug.browser.d.ts +12 -0
  134. package/lib/permitted-contents/debug.browser.js +12 -0
  135. package/lib/permitted-contents/debug.d.ts +12 -0
  136. package/lib/permitted-contents/debug.js +12 -0
  137. package/lib/permitted-contents/index.d.ts +12 -0
  138. package/lib/permitted-contents/index.js +21 -0
  139. package/lib/permitted-contents/matches-selector.d.ts +19 -0
  140. package/lib/permitted-contents/matches-selector.js +33 -0
  141. package/lib/permitted-contents/meta.d.ts +1 -0
  142. package/lib/permitted-contents/meta.js +1 -0
  143. package/lib/permitted-contents/order.d.ts +14 -7
  144. package/lib/permitted-contents/order.js +14 -7
  145. package/lib/permitted-contents/recursive-branch.d.ts +17 -0
  146. package/lib/permitted-contents/recursive-branch.js +17 -0
  147. package/lib/permitted-contents/represent-transparent-nodes.d.ts +29 -0
  148. package/lib/permitted-contents/represent-transparent-nodes.js +24 -0
  149. package/lib/permitted-contents/start.d.ts +12 -6
  150. package/lib/permitted-contents/start.js +12 -6
  151. package/lib/permitted-contents/transparent.d.ts +12 -0
  152. package/lib/permitted-contents/transparent.js +12 -0
  153. package/lib/permitted-contents/types.d.ts +67 -0
  154. package/lib/permitted-contents/utils.d.ts +160 -0
  155. package/lib/permitted-contents/utils.js +194 -0
  156. package/lib/placeholder-label-option/index.d.ts +7 -0
  157. package/lib/placeholder-label-option/index.js +19 -15
  158. package/lib/placeholder-label-option/meta.d.ts +1 -0
  159. package/lib/placeholder-label-option/meta.js +1 -0
  160. package/lib/require-accessible-name/index.d.ts +11 -0
  161. package/lib/require-accessible-name/index.js +7 -0
  162. package/lib/require-accessible-name/meta.d.ts +1 -0
  163. package/lib/require-accessible-name/meta.js +1 -0
  164. package/lib/require-datetime/index.d.ts +12 -0
  165. package/lib/require-datetime/index.js +8 -0
  166. package/lib/require-datetime/meta.d.ts +1 -0
  167. package/lib/require-datetime/meta.js +1 -0
  168. package/lib/require-datetime/types.d.ts +7 -0
  169. package/lib/require-datetime/utils.d.ts +18 -5
  170. package/lib/require-datetime/utils.js +53 -9
  171. package/lib/required-attr/index.d.ts +13 -0
  172. package/lib/required-attr/index.js +7 -0
  173. package/lib/required-attr/meta.d.ts +1 -0
  174. package/lib/required-attr/meta.js +1 -0
  175. package/lib/required-element/index.d.ts +14 -0
  176. package/lib/required-element/index.js +14 -2
  177. package/lib/required-element/meta.d.ts +1 -0
  178. package/lib/required-element/meta.js +1 -0
  179. package/lib/required-h1/index.d.ts +12 -0
  180. package/lib/required-h1/index.js +7 -0
  181. package/lib/required-h1/meta.d.ts +1 -0
  182. package/lib/required-h1/meta.js +1 -0
  183. package/lib/table-row-column-alignment/find-children.d.ts +10 -0
  184. package/lib/table-row-column-alignment/find-children.js +11 -0
  185. package/lib/table-row-column-alignment/grid.d.ts +60 -0
  186. package/lib/table-row-column-alignment/grid.js +85 -0
  187. package/lib/table-row-column-alignment/index.d.ts +8 -0
  188. package/lib/table-row-column-alignment/index.js +8 -0
  189. package/lib/table-row-column-alignment/meta.d.ts +1 -0
  190. package/lib/table-row-column-alignment/meta.js +1 -0
  191. package/lib/table-row-column-alignment/types.d.ts +10 -0
  192. package/lib/use-list/index.d.ts +16 -0
  193. package/lib/use-list/index.js +20 -0
  194. package/lib/use-list/meta.d.ts +1 -0
  195. package/lib/use-list/meta.js +1 -0
  196. package/lib/wai-aria/checkings/abstract-role.d.ts +9 -0
  197. package/lib/wai-aria/checkings/abstract-role.js +9 -0
  198. package/lib/wai-aria/checkings/default-value.d.ts +11 -0
  199. package/lib/wai-aria/checkings/default-value.js +11 -0
  200. package/lib/wai-aria/checkings/deprecated-props.d.ts +11 -0
  201. package/lib/wai-aria/checkings/deprecated-props.js +11 -0
  202. package/lib/wai-aria/checkings/deprecated-role.d.ts +10 -0
  203. package/lib/wai-aria/checkings/deprecated-role.js +10 -0
  204. package/lib/wai-aria/checkings/disallowed-prop.d.ts +14 -0
  205. package/lib/wai-aria/checkings/disallowed-prop.js +14 -0
  206. package/lib/wai-aria/checkings/implicit-props.d.ts +13 -0
  207. package/lib/wai-aria/checkings/implicit-props.js +13 -0
  208. package/lib/wai-aria/checkings/implicit-role.d.ts +9 -0
  209. package/lib/wai-aria/checkings/implicit-role.js +9 -0
  210. package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +9 -0
  211. package/lib/wai-aria/checkings/interaction-in-hidden.js +15 -4
  212. package/lib/wai-aria/checkings/no-global-prop.d.ts +10 -0
  213. package/lib/wai-aria/checkings/no-global-prop.js +10 -0
  214. package/lib/wai-aria/checkings/non-existent-role.d.ts +10 -0
  215. package/lib/wai-aria/checkings/non-existent-role.js +10 -0
  216. package/lib/wai-aria/checkings/permitted-roles.d.ts +10 -0
  217. package/lib/wai-aria/checkings/permitted-roles.js +10 -0
  218. package/lib/wai-aria/checkings/presentational-children.d.ts +7 -1
  219. package/lib/wai-aria/checkings/presentational-children.js +14 -1
  220. package/lib/wai-aria/checkings/required-owned-elements.d.ts +9 -1
  221. package/lib/wai-aria/checkings/required-owned-elements.js +16 -1
  222. package/lib/wai-aria/checkings/required-prop.d.ts +13 -0
  223. package/lib/wai-aria/checkings/required-prop.js +13 -0
  224. package/lib/wai-aria/checkings/value.d.ts +23 -0
  225. package/lib/wai-aria/checkings/value.js +32 -0
  226. package/lib/wai-aria/index.d.ts +10 -0
  227. package/lib/wai-aria/index.js +10 -0
  228. package/lib/wai-aria/meta.d.ts +1 -0
  229. package/lib/wai-aria/meta.js +1 -0
  230. package/lib/wai-aria/types.d.ts +17 -0
  231. package/package.json +11 -11
@@ -1,5 +1,11 @@
1
1
  import { createRule, getAttrSpecs } from '@markuplint/ml-core';
2
2
  import meta from './meta.js';
3
+ /**
4
+ * Rule that reports the use of deprecated or obsolete HTML attributes.
5
+ *
6
+ * Checks each attribute against the HTML spec and reports any that are
7
+ * marked as deprecated or obsolete.
8
+ */
3
9
  export default createRule({
4
10
  meta: meta,
5
11
  async verify({ document, report, t }) {
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `deprecated-attr`: categorized as a validation rule. */
1
2
  declare const _default: {
2
3
  readonly category: "validation";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `deprecated-attr`: categorized as a validation rule. */
1
2
  export default {
2
3
  category: 'validation',
3
4
  };
@@ -1,2 +1,10 @@
1
+ /**
2
+ * Rule that reports the use of deprecated, obsolete, or non-standard HTML
3
+ * elements.
4
+ *
5
+ * Walks HTML and SVG elements and checks their spec status. Reports any
6
+ * element that is marked as deprecated, obsolete, or non-standard in the
7
+ * HTML specification.
8
+ */
1
9
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
2
10
  export default _default;
@@ -1,5 +1,13 @@
1
1
  import { createRule, getSpec } from '@markuplint/ml-core';
2
2
  import meta from './meta.js';
3
+ /**
4
+ * Rule that reports the use of deprecated, obsolete, or non-standard HTML
5
+ * elements.
6
+ *
7
+ * Walks HTML and SVG elements and checks their spec status. Reports any
8
+ * element that is marked as deprecated, obsolete, or non-standard in the
9
+ * HTML specification.
10
+ */
3
11
  export default createRule({
4
12
  meta: meta,
5
13
  async verify({ document, report, t }) {
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `deprecated-element`: categorized as a validation rule. */
1
2
  declare const _default: {
2
3
  readonly category: "validation";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `deprecated-element`: categorized as a validation rule. */
1
2
  export default {
2
3
  category: 'validation',
3
4
  };
@@ -1,2 +1,9 @@
1
+ /**
2
+ * Rule that disallows elements matching the configured CSS selectors.
3
+ *
4
+ * Accepts an array of selector strings as its value. Queries the document
5
+ * (and per-element overrides) for matching elements and reports each one
6
+ * as disallowed.
7
+ */
1
8
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<string[], undefined>>;
2
9
  export default _default;
@@ -1,5 +1,12 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import meta from './meta.js';
3
+ /**
4
+ * Rule that disallows elements matching the configured CSS selectors.
5
+ *
6
+ * Accepts an array of selector strings as its value. Queries the document
7
+ * (and per-element overrides) for matching elements and reports each one
8
+ * as disallowed.
9
+ */
3
10
  export default createRule({
4
11
  meta: meta,
5
12
  defaultValue: [],
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `disallowed-element`: categorized as a validation rule. */
1
2
  declare const _default: {
2
3
  readonly category: "validation";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `disallowed-element`: categorized as a validation rule. */
1
2
  export default {
2
3
  category: 'validation',
3
4
  };
@@ -1,5 +1,15 @@
1
+ /** Configuration options for the doctype rule. */
1
2
  type Option = {
3
+ /** Whether to report obsolete doctypes that include a public or system identifier. */
2
4
  denyObsoleteType: boolean;
3
5
  };
6
+ /**
7
+ * Rule that validates the presence and correctness of the document's DOCTYPE
8
+ * declaration.
9
+ *
10
+ * Reports an error when no DOCTYPE is found (skipped for document fragments)
11
+ * and when an obsolete DOCTYPE (one with a public or system identifier) is
12
+ * declared.
13
+ */
4
14
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<"always", Option>>;
5
15
  export default _default;
@@ -1,5 +1,13 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import meta from './meta.js';
3
+ /**
4
+ * Rule that validates the presence and correctness of the document's DOCTYPE
5
+ * declaration.
6
+ *
7
+ * Reports an error when no DOCTYPE is found (skipped for document fragments)
8
+ * and when an obsolete DOCTYPE (one with a public or system identifier) is
9
+ * declared.
10
+ */
3
11
  export default createRule({
4
12
  meta: meta,
5
13
  defaultValue: 'always',
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `doctype`: categorized as a validation rule. */
1
2
  declare const _default: {
2
3
  readonly category: "validation";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `doctype`: categorized as a validation rule. */
1
2
  export default {
2
3
  category: 'validation',
3
4
  };
@@ -1,2 +1,9 @@
1
+ /**
2
+ * Rule that checks for missing end tags on non-void HTML elements.
3
+ *
4
+ * Reports elements that are neither void nor self-closing and have no
5
+ * closing tag. Omitted elements and elements in documents configured
6
+ * with `endTag: 'never'` are excluded.
7
+ */
1
8
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, undefined>>;
2
9
  export default _default;
@@ -1,6 +1,13 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import { isVoidElement } from '@markuplint/ml-spec';
3
3
  import meta from './meta.js';
4
+ /**
5
+ * Rule that checks for missing end tags on non-void HTML elements.
6
+ *
7
+ * Reports elements that are neither void nor self-closing and have no
8
+ * closing tag. Omitted elements and elements in documents configured
9
+ * with `endTag: 'never'` are excluded.
10
+ */
4
11
  export default createRule({
5
12
  meta: meta,
6
13
  defaultSeverity: 'warning',
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `end-tag`: categorized as a style rule. */
1
2
  declare const _default: {
2
3
  readonly category: "style";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `end-tag`: categorized as a style rule. */
1
2
  export default {
2
3
  category: 'style',
3
4
  };
@@ -1,2 +1,8 @@
1
+ /**
2
+ * Rule that validates heading levels (h1-h6) are not skipped.
3
+ *
4
+ * Ensures that heading elements appear in a sequential order without
5
+ * gaps (e.g., an h4 must not follow an h2 directly without an h3 in between).
6
+ */
1
7
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, null>>;
2
8
  export default _default;
@@ -1,5 +1,11 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import meta from './meta.js';
3
+ /**
4
+ * Rule that validates heading levels (h1-h6) are not skipped.
5
+ *
6
+ * Ensures that heading elements appear in a sequential order without
7
+ * gaps (e.g., an h4 must not follow an h2 directly without an h3 in between).
8
+ */
3
9
  export default createRule({
4
10
  meta: meta,
5
11
  defaultValue: true,
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `heading-levels` rule, categorized as validation. */
1
2
  declare const _default: {
2
3
  readonly category: "validation";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `heading-levels` rule, categorized as validation. */
1
2
  export default {
2
3
  category: 'validation',
3
4
  };
package/lib/helpers.d.ts CHANGED
@@ -4,7 +4,27 @@ import type { PlainData } from '@markuplint/ml-config';
4
4
  import type { Element, RuleConfigValue, Document } from '@markuplint/ml-core';
5
5
  import type { Attribute } from '@markuplint/ml-spec';
6
6
  import type { WritableDeep } from 'type-fest';
7
+ /**
8
+ * Tests whether an element matches the condition specified in an attribute spec.
9
+ * When the condition is `null` or `undefined`, the element is considered to match unconditionally.
10
+ *
11
+ * @template T - The rule configuration value type
12
+ * @template O - The rule options type
13
+ * @param node - The element to test against the condition
14
+ * @param condition - A CSS selector string or array of selector strings from the attribute specification;
15
+ * if `null`/`undefined`, the function returns `true`
16
+ * @returns `true` if the element matches the condition (or no condition is given), `false` otherwise
17
+ */
7
18
  export declare function attrMatches<T extends RuleConfigValue, O extends PlainData>(node: Element<T, O>, condition: Attribute['condition']): boolean;
19
+ /**
20
+ * Tests whether a string matches a given pattern. The pattern can be either
21
+ * a plain string (tested for exact equality) or a regular expression literal
22
+ * in the form `/pattern/flags`.
23
+ *
24
+ * @param needle - The string to test
25
+ * @param pattern - A plain string or a regex literal string (e.g. `/^foo/i`)
26
+ * @returns `true` if the needle matches the pattern
27
+ */
8
28
  export declare function match(needle: string, pattern: string): boolean;
9
29
  /**
10
30
  * PotentialCustomElementName
@@ -22,6 +42,22 @@ export declare function match(needle: string, pattern: string): boolean;
22
42
  * Originally, it is not possible to define a name including ASCII upper alphas in the custom element, but it is not treated as illegal by the HTML parser.
23
43
  */
24
44
  export declare const rePCENChar: string;
45
+ /**
46
+ * Validates an attribute name/value pair against its specification.
47
+ * Checks attribute existence in the spec, value validity, conditional applicability,
48
+ * and skips validation for dynamic (template-interpolated) values when the error
49
+ * relates to an invalid value.
50
+ *
51
+ * @param t - The i18n translator for generating localized error messages
52
+ * @param name - The attribute name to validate
53
+ * @param value - The attribute value to validate
54
+ * @param isDynamicValue - Whether the value is dynamic (e.g. from a template expression);
55
+ * if `true`, invalid-value errors are suppressed
56
+ * @param node - The element that owns the attribute
57
+ * @param attrSpecs - The list of attribute specifications to validate against
58
+ * @param log - Optional debug logger for diagnostic output
59
+ * @returns `false` if valid, or an `Invalid` object (or array of them) describing the violation
60
+ */
25
61
  export declare function isValidAttr(t: Translator, name: string, value: string, isDynamicValue: boolean, node: Element<any, any>, attrSpecs: readonly Attribute[], log?: Log): false | {
26
62
  invalidType: "non-existent" | "invalid-value" | "disallowed-attr";
27
63
  message: string;
@@ -39,14 +75,82 @@ export declare function isValidAttr(t: Translator, name: string, value: string,
39
75
  col: number;
40
76
  };
41
77
  }[];
78
+ /**
79
+ * Normalizes an attribute value according to its specification rules.
80
+ * Applies case-folding, whitespace trimming, and separator normalization
81
+ * based on the attribute type definition.
82
+ *
83
+ * @param value - The raw attribute value to normalize
84
+ * @param spec - The attribute specification that defines normalization rules
85
+ * (case sensitivity, separator type, whitespace handling)
86
+ * @returns The normalized attribute value
87
+ */
42
88
  export declare function toNormalizedValue(value: string, spec: Attribute): string;
89
+ /**
90
+ * Determines whether an element's accessible name may change at runtime.
91
+ * Returns `true` if the element itself has mutable attributes or children,
92
+ * or if an associated `<label>` element has mutable content.
93
+ *
94
+ * @param el - The element whose accessible name stability is being checked
95
+ * @param document - The document containing the element, used to locate associated labels
96
+ * @returns `true` if the accessible name could change dynamically, `false` otherwise
97
+ */
43
98
  export declare function accnameMayBeMutable(el: Element<any, any>, document: Document<any, any>): boolean;
99
+ /**
100
+ * Finds the `<label>` element associated with a labelable form element.
101
+ * First checks for an ancestor `<label>`, then looks for a `<label>` whose
102
+ * `for` attribute references the element's `id`. Returns `null` if the
103
+ * element is not labelable or no associated label is found.
104
+ *
105
+ * @template V - The rule configuration value type
106
+ * @template O - The rule options type
107
+ * @param el - The element to find a label for (must be a labelable element)
108
+ * @param document - The document to search for labels with a matching `for` attribute
109
+ * @returns The associated `<label>` element, or `null` if none is found
110
+ */
44
111
  export declare function getOwnedLabel<V extends RuleConfigValue, O extends PlainData>(el: Element<V, O>, document: Document<V, O>): Element<V, O> | null;
112
+ /**
113
+ * A generic, null-safe collection backed by a `Set`.
114
+ * Automatically filters out `null` and `undefined` values when items are added.
115
+ * Implements the iterable protocol so it can be used in `for...of` loops.
116
+ *
117
+ * @template T - The type of items stored in the collection
118
+ */
45
119
  export declare class Collection<T> {
46
120
  #private;
121
+ /**
122
+ * Creates a new collection, optionally pre-populated with the given items.
123
+ * Any `null` or `undefined` values are silently ignored.
124
+ *
125
+ * @param items - Initial items to add to the collection
126
+ */
47
127
  constructor(...items: readonly (T | null | undefined)[]);
128
+ /**
129
+ * Returns an iterator over the items in the collection.
130
+ *
131
+ * @returns An iterator that yields each item in insertion order
132
+ */
48
133
  [Symbol.iterator](): Iterator<T>;
134
+ /**
135
+ * Adds one or more items to the collection.
136
+ * Any `null` or `undefined` values are silently ignored.
137
+ *
138
+ * @param items - Items to add to the collection
139
+ */
49
140
  add(...items: readonly (T | null | undefined)[]): void;
141
+ /**
142
+ * Returns a frozen array snapshot of the collection's contents.
143
+ *
144
+ * @returns A read-only array containing all items in insertion order
145
+ */
50
146
  toArray(): readonly T[];
51
147
  }
148
+ /**
149
+ * Creates a deep, writable copy of the given value using structured cloning.
150
+ * Strips read-only modifiers from the result type so the clone can be freely mutated.
151
+ *
152
+ * @template T - The type of the value to clone
153
+ * @param value - The value to deep-copy
154
+ * @returns A mutable deep clone of the input value
155
+ */
52
156
  export declare function deepCopy<T>(value: T): WritableDeep<T>;
package/lib/helpers.js CHANGED
@@ -7,6 +7,17 @@ var _Collection_items;
7
7
  // @ts-ignore
8
8
  import structuredClone from '@ungap/structured-clone';
9
9
  import { attrCheck } from './attr-check.js';
10
+ /**
11
+ * Tests whether an element matches the condition specified in an attribute spec.
12
+ * When the condition is `null` or `undefined`, the element is considered to match unconditionally.
13
+ *
14
+ * @template T - The rule configuration value type
15
+ * @template O - The rule options type
16
+ * @param node - The element to test against the condition
17
+ * @param condition - A CSS selector string or array of selector strings from the attribute specification;
18
+ * if `null`/`undefined`, the function returns `true`
19
+ * @returns `true` if the element matches the condition (or no condition is given), `false` otherwise
20
+ */
10
21
  export function attrMatches(
11
22
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
12
23
  node, condition) {
@@ -16,6 +27,15 @@ node, condition) {
16
27
  const condSelector = typeof condition === 'string' ? condition : condition.join(',');
17
28
  return node.matches(condSelector);
18
29
  }
30
+ /**
31
+ * Tests whether a string matches a given pattern. The pattern can be either
32
+ * a plain string (tested for exact equality) or a regular expression literal
33
+ * in the form `/pattern/flags`.
34
+ *
35
+ * @param needle - The string to test
36
+ * @param pattern - A plain string or a regex literal string (e.g. `/^foo/i`)
37
+ * @returns `true` if the needle matches the pattern
38
+ */
19
39
  export function match(needle, pattern) {
20
40
  const matches = pattern.match(/^\/(.*)\/([gim])*$/);
21
41
  if (matches && matches[1]) {
@@ -60,15 +80,30 @@ export const rePCENChar = [
60
80
  '[\uFDF0-\uFFFD]',
61
81
  '[\uD800-\uDBFF][\uDC00-\uDFFF]',
62
82
  ].join('|');
83
+ /**
84
+ * Validates an attribute name/value pair against its specification.
85
+ * Checks attribute existence in the spec, value validity, conditional applicability,
86
+ * and skips validation for dynamic (template-interpolated) values when the error
87
+ * relates to an invalid value.
88
+ *
89
+ * @param t - The i18n translator for generating localized error messages
90
+ * @param name - The attribute name to validate
91
+ * @param value - The attribute value to validate
92
+ * @param isDynamicValue - Whether the value is dynamic (e.g. from a template expression);
93
+ * if `true`, invalid-value errors are suppressed
94
+ * @param node - The element that owns the attribute
95
+ * @param attrSpecs - The list of attribute specifications to validate against
96
+ * @param log - Optional debug logger for diagnostic output
97
+ * @returns `false` if valid, or an `Invalid` object (or array of them) describing the violation
98
+ */
63
99
  export function isValidAttr(t, name, value, isDynamicValue,
64
100
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
65
101
  node, attrSpecs,
66
102
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
67
103
  log) {
68
- let invalid = false;
69
104
  const spec = attrSpecs.find(s => s.name.toLowerCase() === name.toLowerCase());
70
105
  log?.('Spec of the %s attr: %o', name, spec);
71
- invalid = attrCheck(t, name, value, false, spec);
106
+ let invalid = attrCheck(t, name, value, false, spec);
72
107
  if (invalid === false &&
73
108
  spec &&
74
109
  spec.condition != null &&
@@ -84,6 +119,16 @@ log) {
84
119
  }
85
120
  return invalid;
86
121
  }
122
+ /**
123
+ * Normalizes an attribute value according to its specification rules.
124
+ * Applies case-folding, whitespace trimming, and separator normalization
125
+ * based on the attribute type definition.
126
+ *
127
+ * @param value - The raw attribute value to normalize
128
+ * @param spec - The attribute specification that defines normalization rules
129
+ * (case sensitivity, separator type, whitespace handling)
130
+ * @returns The normalized attribute value
131
+ */
87
132
  export function toNormalizedValue(value, spec) {
88
133
  let normalized = value;
89
134
  if (!spec.caseSensitive) {
@@ -112,6 +157,15 @@ export function toNormalizedValue(value, spec) {
112
157
  }
113
158
  return normalized;
114
159
  }
160
+ /**
161
+ * Determines whether an element's accessible name may change at runtime.
162
+ * Returns `true` if the element itself has mutable attributes or children,
163
+ * or if an associated `<label>` element has mutable content.
164
+ *
165
+ * @param el - The element whose accessible name stability is being checked
166
+ * @param document - The document containing the element, used to locate associated labels
167
+ * @returns `true` if the accessible name could change dynamically, `false` otherwise
168
+ */
115
169
  export function accnameMayBeMutable(
116
170
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
117
171
  el,
@@ -127,6 +181,18 @@ document) {
127
181
  return false;
128
182
  }
129
183
  const labelable = ['button', 'input:not([type=hidden])', 'meter', 'output', 'progress', 'select', 'textarea'];
184
+ /**
185
+ * Finds the `<label>` element associated with a labelable form element.
186
+ * First checks for an ancestor `<label>`, then looks for a `<label>` whose
187
+ * `for` attribute references the element's `id`. Returns `null` if the
188
+ * element is not labelable or no associated label is found.
189
+ *
190
+ * @template V - The rule configuration value type
191
+ * @template O - The rule options type
192
+ * @param el - The element to find a label for (must be a labelable element)
193
+ * @param document - The document to search for labels with a matching `for` attribute
194
+ * @returns The associated `<label>` element, or `null` if none is found
195
+ */
130
196
  export function getOwnedLabel(
131
197
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
132
198
  el,
@@ -144,14 +210,38 @@ document) {
144
210
  }
145
211
  return ownedLabel;
146
212
  }
213
+ /**
214
+ * A generic, null-safe collection backed by a `Set`.
215
+ * Automatically filters out `null` and `undefined` values when items are added.
216
+ * Implements the iterable protocol so it can be used in `for...of` loops.
217
+ *
218
+ * @template T - The type of items stored in the collection
219
+ */
147
220
  export class Collection {
221
+ /**
222
+ * Creates a new collection, optionally pre-populated with the given items.
223
+ * Any `null` or `undefined` values are silently ignored.
224
+ *
225
+ * @param items - Initial items to add to the collection
226
+ */
148
227
  constructor(...items) {
149
228
  _Collection_items.set(this, new Set());
150
229
  this.add(...items);
151
230
  }
231
+ /**
232
+ * Returns an iterator over the items in the collection.
233
+ *
234
+ * @returns An iterator that yields each item in insertion order
235
+ */
152
236
  [(_Collection_items = new WeakMap(), Symbol.iterator)]() {
153
237
  return __classPrivateFieldGet(this, _Collection_items, "f").values();
154
238
  }
239
+ /**
240
+ * Adds one or more items to the collection.
241
+ * Any `null` or `undefined` values are silently ignored.
242
+ *
243
+ * @param items - Items to add to the collection
244
+ */
155
245
  add(...items) {
156
246
  for (const item of items) {
157
247
  if (item == null) {
@@ -160,10 +250,23 @@ export class Collection {
160
250
  __classPrivateFieldGet(this, _Collection_items, "f").add(item);
161
251
  }
162
252
  }
253
+ /**
254
+ * Returns a frozen array snapshot of the collection's contents.
255
+ *
256
+ * @returns A read-only array containing all items in insertion order
257
+ */
163
258
  toArray() {
164
259
  return Object.freeze([...__classPrivateFieldGet(this, _Collection_items, "f")]);
165
260
  }
166
261
  }
262
+ /**
263
+ * Creates a deep, writable copy of the given value using structured cloning.
264
+ * Strips read-only modifiers from the result type so the clone can be freely mutated.
265
+ *
266
+ * @template T - The type of the value to clone
267
+ * @param value - The value to deep-copy
268
+ * @returns A mutable deep clone of the input value
269
+ */
167
270
  export function deepCopy(value) {
168
271
  return structuredClone(value);
169
272
  }
@@ -1,2 +1,9 @@
1
+ /**
2
+ * Rule that checks for duplicate `id` attribute values within a document.
3
+ *
4
+ * Walks all elements and collects `id` values, reporting any that have
5
+ * already been seen. Dynamic values and directive attributes are excluded
6
+ * from the check.
7
+ */
1
8
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
2
9
  export default _default;
@@ -1,5 +1,12 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import meta from './meta.js';
3
+ /**
4
+ * Rule that checks for duplicate `id` attribute values within a document.
5
+ *
6
+ * Walks all elements and collects `id` values, reporting any that have
7
+ * already been seen. Dynamic values and directive attributes are excluded
8
+ * from the check.
9
+ */
3
10
  export default createRule({
4
11
  meta: meta,
5
12
  async verify({ document, report, t }) {
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `id-duplication`: categorized as a validation rule. */
1
2
  declare const _default: {
2
3
  readonly category: "validation";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `id-duplication`: categorized as a validation rule. */
1
2
  export default {
2
3
  category: 'validation',
3
4
  };