@markuplint/rules 4.11.2 → 5.0.0-alpha.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 (266) hide show
  1. package/CHANGELOG.md +63 -2
  2. package/SKILL.md +76 -0
  3. package/lib/attr-check.d.ts +46 -7
  4. package/lib/attr-check.js +42 -8
  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 +9 -0
  22. package/lib/character-reference/index.js +20 -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/correct-aspect-ratio/index.d.ts +5 -0
  30. package/lib/correct-aspect-ratio/index.js +80 -0
  31. package/lib/correct-aspect-ratio/meta.d.ts +4 -0
  32. package/lib/correct-aspect-ratio/meta.js +3 -0
  33. package/lib/correct-aspect-ratio/resolve-image-size.d.ts +24 -0
  34. package/lib/correct-aspect-ratio/resolve-image-size.js +165 -0
  35. package/lib/create-message.d.ts +29 -2
  36. package/lib/create-message.js +60 -2
  37. package/lib/debug.d.ts +9 -0
  38. package/lib/debug.js +5 -0
  39. package/lib/deprecated-attr/index.d.ts +6 -0
  40. package/lib/deprecated-attr/index.js +6 -0
  41. package/lib/deprecated-attr/meta.d.ts +1 -0
  42. package/lib/deprecated-attr/meta.js +1 -0
  43. package/lib/deprecated-element/index.d.ts +6 -0
  44. package/lib/deprecated-element/index.js +8 -2
  45. package/lib/deprecated-element/meta.d.ts +1 -0
  46. package/lib/deprecated-element/meta.js +1 -0
  47. package/lib/disallowed-element/index.d.ts +7 -0
  48. package/lib/disallowed-element/index.js +7 -0
  49. package/lib/disallowed-element/meta.d.ts +1 -0
  50. package/lib/disallowed-element/meta.js +1 -0
  51. package/lib/doctype/index.d.ts +10 -0
  52. package/lib/doctype/index.js +8 -0
  53. package/lib/doctype/meta.d.ts +1 -0
  54. package/lib/doctype/meta.js +1 -0
  55. package/lib/end-tag/index.d.ts +7 -0
  56. package/lib/end-tag/index.js +8 -1
  57. package/lib/end-tag/meta.d.ts +1 -0
  58. package/lib/end-tag/meta.js +1 -0
  59. package/lib/heading-levels/index.d.ts +6 -0
  60. package/lib/heading-levels/index.js +6 -1
  61. package/lib/heading-levels/meta.d.ts +1 -0
  62. package/lib/heading-levels/meta.js +1 -0
  63. package/lib/helpers.d.ts +105 -0
  64. package/lib/helpers.js +112 -16
  65. package/lib/id-duplication/index.d.ts +7 -0
  66. package/lib/id-duplication/index.js +7 -0
  67. package/lib/id-duplication/meta.d.ts +1 -0
  68. package/lib/id-duplication/meta.js +1 -0
  69. package/lib/index.d.ts +43 -41
  70. package/lib/index.js +24 -0
  71. package/lib/ineffective-attr/index.d.ts +7 -0
  72. package/lib/ineffective-attr/index.js +7 -0
  73. package/lib/ineffective-attr/meta.d.ts +1 -0
  74. package/lib/ineffective-attr/meta.js +1 -0
  75. package/lib/invalid-attr/index.d.ts +29 -21
  76. package/lib/invalid-attr/index.js +60 -109
  77. package/lib/invalid-attr/meta.d.ts +1 -0
  78. package/lib/invalid-attr/meta.js +1 -0
  79. package/lib/label-has-control/index.d.ts +7 -0
  80. package/lib/label-has-control/index.js +11 -0
  81. package/lib/label-has-control/meta.d.ts +1 -0
  82. package/lib/label-has-control/meta.js +1 -0
  83. package/lib/landmark-roles/index.d.ts +14 -0
  84. package/lib/landmark-roles/index.js +21 -0
  85. package/lib/landmark-roles/meta.d.ts +1 -0
  86. package/lib/landmark-roles/meta.js +1 -0
  87. package/lib/link-types/index.d.ts +10 -0
  88. package/lib/link-types/index.js +180 -0
  89. package/lib/link-types/meta.d.ts +5 -0
  90. package/lib/link-types/meta.js +4 -0
  91. package/lib/neighbor-popovers/index.d.ts +8 -0
  92. package/lib/neighbor-popovers/index.js +28 -6
  93. package/lib/neighbor-popovers/meta.d.ts +1 -0
  94. package/lib/neighbor-popovers/meta.js +1 -0
  95. package/lib/no-ambiguous-navigable-target-names/index.d.ts +8 -0
  96. package/lib/no-ambiguous-navigable-target-names/index.js +8 -0
  97. package/lib/no-ambiguous-navigable-target-names/meta.d.ts +1 -0
  98. package/lib/no-ambiguous-navigable-target-names/meta.js +1 -0
  99. package/lib/no-boolean-attr-value/index.d.ts +7 -0
  100. package/lib/no-boolean-attr-value/index.js +7 -0
  101. package/lib/no-boolean-attr-value/meta.d.ts +1 -0
  102. package/lib/no-boolean-attr-value/meta.js +1 -0
  103. package/lib/no-consecutive-br/index.d.ts +8 -0
  104. package/lib/no-consecutive-br/index.js +8 -0
  105. package/lib/no-consecutive-br/meta.d.ts +1 -0
  106. package/lib/no-consecutive-br/meta.js +1 -0
  107. package/lib/no-default-value/index.d.ts +7 -0
  108. package/lib/no-default-value/index.js +7 -0
  109. package/lib/no-default-value/meta.d.ts +1 -0
  110. package/lib/no-default-value/meta.js +1 -0
  111. package/lib/no-duplicate-dt/index.d.ts +6 -0
  112. package/lib/no-duplicate-dt/index.js +6 -0
  113. package/lib/no-duplicate-dt/meta.d.ts +1 -0
  114. package/lib/no-duplicate-dt/meta.js +1 -0
  115. package/lib/no-empty-palpable-content/index.d.ts +13 -0
  116. package/lib/no-empty-palpable-content/index.js +12 -0
  117. package/lib/no-empty-palpable-content/meta.d.ts +1 -0
  118. package/lib/no-empty-palpable-content/meta.js +1 -0
  119. package/lib/no-hard-code-id/index.d.ts +8 -0
  120. package/lib/no-hard-code-id/index.js +8 -0
  121. package/lib/no-hard-code-id/meta.d.ts +1 -0
  122. package/lib/no-hard-code-id/meta.js +1 -0
  123. package/lib/no-orphaned-end-tag/index.d.ts +7 -0
  124. package/lib/no-orphaned-end-tag/index.js +8 -2
  125. package/lib/no-orphaned-end-tag/meta.d.ts +1 -0
  126. package/lib/no-orphaned-end-tag/meta.js +1 -0
  127. package/lib/no-refer-to-non-existent-id/index.d.ts +9 -1
  128. package/lib/no-refer-to-non-existent-id/index.js +11 -2
  129. package/lib/no-refer-to-non-existent-id/meta.d.ts +1 -0
  130. package/lib/no-refer-to-non-existent-id/meta.js +1 -0
  131. package/lib/no-unsupported-features/compat-data.d.ts +71 -0
  132. package/lib/no-unsupported-features/compat-data.js +204 -0
  133. package/lib/no-unsupported-features/index.d.ts +24 -0
  134. package/lib/no-unsupported-features/index.js +139 -0
  135. package/lib/no-unsupported-features/meta.d.ts +5 -0
  136. package/lib/no-unsupported-features/meta.js +4 -0
  137. package/lib/no-unsupported-features/resolve-browsers.d.ts +30 -0
  138. package/lib/no-unsupported-features/resolve-browsers.js +125 -0
  139. package/lib/no-use-event-handler-attr/index.d.ts +10 -0
  140. package/lib/no-use-event-handler-attr/index.js +8 -0
  141. package/lib/no-use-event-handler-attr/meta.d.ts +1 -0
  142. package/lib/no-use-event-handler-attr/meta.js +1 -0
  143. package/lib/permitted-contents/choice.d.ts +17 -0
  144. package/lib/permitted-contents/choice.js +31 -1
  145. package/lib/permitted-contents/complex-branch.d.ts +11 -7
  146. package/lib/permitted-contents/complex-branch.js +11 -7
  147. package/lib/permitted-contents/content-model.d.ts +11 -0
  148. package/lib/permitted-contents/content-model.js +32 -0
  149. package/lib/permitted-contents/count-pattern.d.ts +13 -7
  150. package/lib/permitted-contents/count-pattern.js +24 -8
  151. package/lib/permitted-contents/debug.browser.d.ts +12 -0
  152. package/lib/permitted-contents/debug.browser.js +12 -0
  153. package/lib/permitted-contents/debug.d.ts +12 -0
  154. package/lib/permitted-contents/debug.js +12 -0
  155. package/lib/permitted-contents/index.d.ts +12 -0
  156. package/lib/permitted-contents/index.js +21 -0
  157. package/lib/permitted-contents/matches-selector.d.ts +19 -0
  158. package/lib/permitted-contents/matches-selector.js +33 -0
  159. package/lib/permitted-contents/meta.d.ts +1 -0
  160. package/lib/permitted-contents/meta.js +1 -0
  161. package/lib/permitted-contents/order.d.ts +14 -7
  162. package/lib/permitted-contents/order.js +15 -8
  163. package/lib/permitted-contents/recursive-branch.d.ts +17 -0
  164. package/lib/permitted-contents/recursive-branch.js +17 -0
  165. package/lib/permitted-contents/represent-transparent-nodes.d.ts +54 -0
  166. package/lib/permitted-contents/represent-transparent-nodes.js +119 -12
  167. package/lib/permitted-contents/start.d.ts +12 -6
  168. package/lib/permitted-contents/start.js +12 -6
  169. package/lib/permitted-contents/transparent.d.ts +12 -0
  170. package/lib/permitted-contents/transparent.js +12 -0
  171. package/lib/permitted-contents/types.d.ts +67 -0
  172. package/lib/permitted-contents/utils.d.ts +160 -0
  173. package/lib/permitted-contents/utils.js +216 -35
  174. package/lib/placeholder-label-option/index.d.ts +7 -0
  175. package/lib/placeholder-label-option/index.js +19 -15
  176. package/lib/placeholder-label-option/meta.d.ts +1 -0
  177. package/lib/placeholder-label-option/meta.js +1 -0
  178. package/lib/redundant-accessible-name/index.d.ts +10 -0
  179. package/lib/redundant-accessible-name/index.js +123 -0
  180. package/lib/redundant-accessible-name/meta.d.ts +5 -0
  181. package/lib/redundant-accessible-name/meta.js +4 -0
  182. package/lib/require-accessible-name/index.d.ts +10 -4
  183. package/lib/require-accessible-name/index.js +13 -5
  184. package/lib/require-accessible-name/meta.d.ts +1 -0
  185. package/lib/require-accessible-name/meta.js +1 -0
  186. package/lib/require-datetime/index.d.ts +12 -0
  187. package/lib/require-datetime/index.js +8 -0
  188. package/lib/require-datetime/meta.d.ts +1 -0
  189. package/lib/require-datetime/meta.js +1 -0
  190. package/lib/require-datetime/types.d.ts +7 -0
  191. package/lib/require-datetime/utils.d.ts +18 -5
  192. package/lib/require-datetime/utils.js +53 -9
  193. package/lib/require-dialog-autofocus/index.d.ts +22 -0
  194. package/lib/require-dialog-autofocus/index.js +62 -0
  195. package/lib/require-dialog-autofocus/meta.d.ts +5 -0
  196. package/lib/require-dialog-autofocus/meta.js +4 -0
  197. package/lib/required-attr/index.d.ts +21 -1
  198. package/lib/required-attr/index.js +34 -4
  199. package/lib/required-attr/meta.d.ts +1 -0
  200. package/lib/required-attr/meta.js +1 -0
  201. package/lib/required-element/index.d.ts +14 -0
  202. package/lib/required-element/index.js +14 -2
  203. package/lib/required-element/meta.d.ts +1 -0
  204. package/lib/required-element/meta.js +1 -0
  205. package/lib/required-h1/index.d.ts +12 -0
  206. package/lib/required-h1/index.js +7 -0
  207. package/lib/required-h1/meta.d.ts +1 -0
  208. package/lib/required-h1/meta.js +1 -0
  209. package/lib/srcset-sizes-constraint/index.d.ts +6 -0
  210. package/lib/srcset-sizes-constraint/index.js +108 -0
  211. package/lib/srcset-sizes-constraint/meta.d.ts +5 -0
  212. package/lib/srcset-sizes-constraint/meta.js +4 -0
  213. package/lib/srcset-sizes-constraint/parse-srcset.d.ts +40 -0
  214. package/lib/srcset-sizes-constraint/parse-srcset.js +56 -0
  215. package/lib/table-row-column-alignment/find-children.d.ts +10 -0
  216. package/lib/table-row-column-alignment/find-children.js +11 -0
  217. package/lib/table-row-column-alignment/grid.d.ts +60 -0
  218. package/lib/table-row-column-alignment/grid.js +104 -26
  219. package/lib/table-row-column-alignment/index.d.ts +8 -0
  220. package/lib/table-row-column-alignment/index.js +8 -0
  221. package/lib/table-row-column-alignment/meta.d.ts +1 -0
  222. package/lib/table-row-column-alignment/meta.js +1 -0
  223. package/lib/table-row-column-alignment/types.d.ts +10 -0
  224. package/lib/use-list/index.d.ts +16 -0
  225. package/lib/use-list/index.js +20 -0
  226. package/lib/use-list/meta.d.ts +1 -0
  227. package/lib/use-list/meta.js +1 -0
  228. package/lib/wai-aria/checkings/abstract-role.d.ts +9 -0
  229. package/lib/wai-aria/checkings/abstract-role.js +14 -2
  230. package/lib/wai-aria/checkings/default-value.d.ts +11 -0
  231. package/lib/wai-aria/checkings/default-value.js +11 -0
  232. package/lib/wai-aria/checkings/deprecated-props.d.ts +11 -0
  233. package/lib/wai-aria/checkings/deprecated-props.js +11 -0
  234. package/lib/wai-aria/checkings/deprecated-role.d.ts +10 -0
  235. package/lib/wai-aria/checkings/deprecated-role.js +10 -0
  236. package/lib/wai-aria/checkings/disallowed-prop.d.ts +14 -0
  237. package/lib/wai-aria/checkings/disallowed-prop.js +19 -2
  238. package/lib/wai-aria/checkings/implicit-props.d.ts +13 -0
  239. package/lib/wai-aria/checkings/implicit-props.js +13 -0
  240. package/lib/wai-aria/checkings/implicit-role.d.ts +9 -0
  241. package/lib/wai-aria/checkings/implicit-role.js +14 -2
  242. package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +9 -0
  243. package/lib/wai-aria/checkings/interaction-in-hidden.js +15 -4
  244. package/lib/wai-aria/checkings/no-global-prop.d.ts +10 -0
  245. package/lib/wai-aria/checkings/no-global-prop.js +10 -0
  246. package/lib/wai-aria/checkings/non-existent-role.d.ts +11 -0
  247. package/lib/wai-aria/checkings/non-existent-role.js +19 -2
  248. package/lib/wai-aria/checkings/permitted-roles.d.ts +10 -0
  249. package/lib/wai-aria/checkings/permitted-roles.js +15 -2
  250. package/lib/wai-aria/checkings/presentational-children.d.ts +7 -1
  251. package/lib/wai-aria/checkings/presentational-children.js +17 -3
  252. package/lib/wai-aria/checkings/required-accessibility-parent-role.d.ts +25 -0
  253. package/lib/wai-aria/checkings/required-accessibility-parent-role.js +56 -0
  254. package/lib/wai-aria/checkings/required-owned-elements.d.ts +10 -1
  255. package/lib/wai-aria/checkings/required-owned-elements.js +69 -25
  256. package/lib/wai-aria/checkings/required-prop.d.ts +13 -0
  257. package/lib/wai-aria/checkings/required-prop.js +18 -2
  258. package/lib/wai-aria/checkings/value.d.ts +23 -0
  259. package/lib/wai-aria/checkings/value.js +32 -0
  260. package/lib/wai-aria/index.d.ts +10 -0
  261. package/lib/wai-aria/index.js +22 -4
  262. package/lib/wai-aria/meta.d.ts +1 -0
  263. package/lib/wai-aria/meta.js +1 -0
  264. package/lib/wai-aria/types.d.ts +25 -1
  265. package/package.json +16 -11
  266. package/schema.json +18 -0
@@ -1,14 +1,36 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
- import { mayBeFocusable } from '@markuplint/ml-spec';
2
+ import { ARIA_RECOMMENDED_VERSION, mayBeFocusable } from '@markuplint/ml-spec';
3
3
  import meta from './meta.js';
4
- // TODO: It will be received from config
5
- const ARIA_VERSION = '1.2';
4
+ /**
5
+ * Command values from the Invoker Commands API that relate to popover behavior.
6
+ * Comparison is case-insensitive per the HTML spec.
7
+ */
8
+ const POPOVER_COMMANDS = new Set(['toggle-popover', 'show-popover', 'hide-popover']);
9
+ /**
10
+ * Rule that detects perceptible content between a popover trigger and its target.
11
+ *
12
+ * When a `[popovertarget]` element or a `[commandfor]` element with a popover-related
13
+ * `command` attribute and its corresponding `[popover]` target exist in the DOM, any
14
+ * focusable elements, elements with accessible names, or non-whitespace text nodes
15
+ * between them are reported as violations.
16
+ */
6
17
  export default createRule({
7
18
  meta: meta,
8
19
  verify({ document, report, t }) {
9
- const triggers = document.querySelectorAll('[popovertarget]');
20
+ const ariaVersion = document.ruleCommonSettings?.ariaVersion ?? ARIA_RECOMMENDED_VERSION;
21
+ const triggers = document.querySelectorAll('[popovertarget], [commandfor]');
10
22
  Triggers: for (const trigger of triggers) {
11
- const targetId = trigger.getAttribute('popovertarget');
23
+ let targetId = null;
24
+ const popovertarget = trigger.getAttribute('popovertarget');
25
+ if (popovertarget) {
26
+ targetId = popovertarget;
27
+ }
28
+ else {
29
+ const command = trigger.getAttribute('command');
30
+ if (command && POPOVER_COMMANDS.has(command.toLowerCase())) {
31
+ targetId = trigger.getAttribute('commandfor');
32
+ }
33
+ }
12
34
  if (!targetId) {
13
35
  continue;
14
36
  }
@@ -26,7 +48,7 @@ export default createRule({
26
48
  }
27
49
  if ((node.is(node.ELEMENT_NODE) &&
28
50
  // Element has accessible name
29
- (node.getAccessibleName(ARIA_VERSION) ||
51
+ (node.getAccessibleName(ariaVersion) ||
30
52
  // Element is focusable
31
53
  mayBeFocusable(node, node.ownerMLDocument.specs))) ||
32
54
  (node.is(node.TEXT_NODE) &&
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `neighbor-popovers` rule, categorized as accessibility. */
1
2
  declare const _default: {
2
3
  readonly category: "a11y";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `neighbor-popovers` rule, categorized as accessibility. */
1
2
  export default {
2
3
  category: 'a11y',
3
4
  };
@@ -1,2 +1,10 @@
1
+ /**
2
+ * Rule that warns against ambiguous navigable target names.
3
+ *
4
+ * Detects attribute values (e.g., `target`) that look like browsing context
5
+ * keywords (such as `_blank`, `_self`) but are missing the leading underscore,
6
+ * which would make them navigable target names instead of keywords. Suggests
7
+ * adding the underscore prefix when applicable.
8
+ */
1
9
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, undefined>>;
2
10
  export default _default;
@@ -1,6 +1,14 @@
1
1
  import { createRule, getAttrSpecs } from '@markuplint/ml-core';
2
2
  import { valueCheck } from '../attr-check.js';
3
3
  import meta from './meta.js';
4
+ /**
5
+ * Rule that warns against ambiguous navigable target names.
6
+ *
7
+ * Detects attribute values (e.g., `target`) that look like browsing context
8
+ * keywords (such as `_blank`, `_self`) but are missing the leading underscore,
9
+ * which would make them navigable target names instead of keywords. Suggests
10
+ * adding the underscore prefix when applicable.
11
+ */
4
12
  export default createRule({
5
13
  meta: meta,
6
14
  defaultSeverity: 'warning',
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `no-ambiguous-navigable-target-names` rule, categorized as accessibility. */
1
2
  declare const _default: {
2
3
  readonly category: "a11y";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `no-ambiguous-navigable-target-names` rule, categorized as accessibility. */
1
2
  export default {
2
3
  category: 'a11y',
3
4
  };
@@ -1,2 +1,9 @@
1
+ /**
2
+ * Rule that disallows explicit values on boolean attributes.
3
+ *
4
+ * Checks each attribute against the HTML spec and reports when a boolean
5
+ * attribute (e.g., `disabled`, `checked`) is written with an explicit value
6
+ * such as `disabled="disabled"` instead of the bare attribute name.
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, getAttrSpecs } from '@markuplint/ml-core';
2
2
  import meta from './meta.js';
3
+ /**
4
+ * Rule that disallows explicit values on boolean attributes.
5
+ *
6
+ * Checks each attribute against the HTML spec and reports when a boolean
7
+ * attribute (e.g., `disabled`, `checked`) is written with an explicit value
8
+ * such as `disabled="disabled"` instead of the bare attribute name.
9
+ */
3
10
  export default createRule({
4
11
  meta: meta,
5
12
  defaultSeverity: 'warning',
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `no-boolean-attr-value`: 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 `no-boolean-attr-value`: categorized as a style rule. */
1
2
  export default {
2
3
  category: 'style',
3
4
  };
@@ -1,2 +1,10 @@
1
+ /**
2
+ * Rule that disallows consecutive `<br>` elements.
3
+ *
4
+ * Queries all `<br>` elements in the document and checks whether the next
5
+ * non-whitespace sibling is another `<br>`. Consecutive line breaks are
6
+ * typically a sign that a more semantic element (e.g., `<p>`) should be
7
+ * used instead, which is important for accessibility.
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 } from '@markuplint/ml-core';
2
2
  import meta from './meta.js';
3
+ /**
4
+ * Rule that disallows consecutive `<br>` elements.
5
+ *
6
+ * Queries all `<br>` elements in the document and checks whether the next
7
+ * non-whitespace sibling is another `<br>`. Consecutive line breaks are
8
+ * typically a sign that a more semantic element (e.g., `<p>`) should be
9
+ * used instead, which is important for accessibility.
10
+ */
3
11
  export default createRule({
4
12
  meta: meta,
5
13
  defaultSeverity: 'warning',
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `no-consecutive-br`: categorized as an accessibility rule. */
1
2
  declare const _default: {
2
3
  readonly category: "a11y";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `no-consecutive-br`: categorized as an accessibility rule. */
1
2
  export default {
2
3
  category: 'a11y',
3
4
  };
@@ -1,2 +1,9 @@
1
+ /**
2
+ * Rule that disallows explicitly setting an attribute to its default value.
3
+ *
4
+ * Looks up each attribute's default value from the spec and reports when
5
+ * the authored value matches the default, since the attribute can be
6
+ * omitted entirely for the same effect.
7
+ */
1
8
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
2
9
  export default _default;
@@ -1,6 +1,13 @@
1
1
  import { createRule, getAttrSpecs } from '@markuplint/ml-core';
2
2
  import { toNormalizedValue } from '../helpers.js';
3
3
  import meta from './meta.js';
4
+ /**
5
+ * Rule that disallows explicitly setting an attribute to its default value.
6
+ *
7
+ * Looks up each attribute's default value from the spec and reports when
8
+ * the authored value matches the default, since the attribute can be
9
+ * omitted entirely for the same effect.
10
+ */
4
11
  export default createRule({
5
12
  meta: meta,
6
13
  defaultSeverity: 'warning',
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `no-default-value`: 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 `no-default-value`: categorized as a style rule. */
1
2
  export default {
2
3
  category: 'style',
3
4
  };
@@ -1,2 +1,8 @@
1
+ /**
2
+ * Rule that validates there are no duplicate `<dt>` elements within a `<dl>`.
3
+ *
4
+ * Iterates through each definition list and checks that no two `<dt>` elements
5
+ * (direct children or wrapped in `<div>`) share the same text content.
6
+ */
1
7
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
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 there are no duplicate `<dt>` elements within a `<dl>`.
5
+ *
6
+ * Iterates through each definition list and checks that no two `<dt>` elements
7
+ * (direct children or wrapped in `<div>`) share the same text content.
8
+ */
3
9
  export default createRule({
4
10
  meta: meta,
5
11
  verify({ document, report, t }) {
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `no-duplicate-dt` 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 `no-duplicate-dt` rule, categorized as validation. */
1
2
  export default {
2
3
  category: 'validation',
3
4
  };
@@ -1,6 +1,19 @@
1
+ /**
2
+ * Configuration options for the no-empty-palpable-content rule.
3
+ */
1
4
  type Options = {
5
+ /** Whether to extend checking to exposable elements beyond standard palpable content. */
2
6
  extendsExposableElements?: boolean;
7
+ /** Whether to ignore elements marked with `aria-busy="true"`. */
3
8
  ignoreIfAriaBusy?: boolean;
4
9
  };
10
+ /**
11
+ * Rule that warns when palpable content elements are empty.
12
+ *
13
+ * Palpable content elements are expected to have visible or meaningful content.
14
+ * This rule reports elements that contain only whitespace text nodes, while
15
+ * excluding elements that are naturally empty (e.g., `<textarea>`, `<video>`)
16
+ * or have a nothing content model.
17
+ */
5
18
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Options>>;
6
19
  export default _default;
@@ -1,6 +1,10 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import { isNothingContentModel, isPalpableElement } from '@markuplint/ml-spec';
3
3
  import meta from './meta.js';
4
+ /**
5
+ * Elements that are allowed to be empty because they are filled by user
6
+ * interaction or are inherently palpable by themselves.
7
+ */
4
8
  const allowedElements = new Set([
5
9
  // These elements are possibly empty because it to be filled by user interaction.
6
10
  'textarea',
@@ -11,6 +15,14 @@ const allowedElements = new Set([
11
15
  'video',
12
16
  'img',
13
17
  ]);
18
+ /**
19
+ * Rule that warns when palpable content elements are empty.
20
+ *
21
+ * Palpable content elements are expected to have visible or meaningful content.
22
+ * This rule reports elements that contain only whitespace text nodes, while
23
+ * excluding elements that are naturally empty (e.g., `<textarea>`, `<video>`)
24
+ * or have a nothing content model.
25
+ */
14
26
  export default createRule({
15
27
  meta: meta,
16
28
  defaultSeverity: 'warning',
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `no-empty-palpable-content` 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 `no-empty-palpable-content` rule, categorized as validation. */
1
2
  export default {
2
3
  category: 'validation',
3
4
  };
@@ -1,2 +1,10 @@
1
+ /**
2
+ * Rule that disallows hard-coded `id` attribute values in document fragments.
3
+ *
4
+ * Only active for fragment documents (e.g., component templates). Reports
5
+ * any `id` attribute whose value is a static string rather than a dynamic
6
+ * or code-generated value, encouraging dynamic ID generation to avoid
7
+ * collisions when fragments are reused.
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 } from '@markuplint/ml-core';
2
2
  import meta from './meta.js';
3
+ /**
4
+ * Rule that disallows hard-coded `id` attribute values in document fragments.
5
+ *
6
+ * Only active for fragment documents (e.g., component templates). Reports
7
+ * any `id` attribute whose value is a static string rather than a dynamic
8
+ * or code-generated value, encouraging dynamic ID generation to avoid
9
+ * collisions when fragments are reused.
10
+ */
3
11
  export default createRule({
4
12
  meta: meta,
5
13
  defaultSeverity: 'warning',
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `no-hard-code-id`: categorized as a maintainability rule. */
1
2
  declare const _default: {
2
3
  readonly category: "maintainability";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `no-hard-code-id`: categorized as a maintainability rule. */
1
2
  export default {
2
3
  category: 'maintainability',
3
4
  };
@@ -1,2 +1,9 @@
1
+ /**
2
+ * Rule that detects orphaned end tags with no matching start tag.
3
+ *
4
+ * Scans text nodes and reports any that originated from invalid (bogus) AST
5
+ * nodes, which indicates a stray end tag that the parser could not match
6
+ * to an opening element.
7
+ */
1
8
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, null>>;
2
9
  export default _default;
@@ -1,11 +1,17 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import meta from './meta.js';
3
+ /**
4
+ * Rule that detects orphaned end tags with no matching start tag.
5
+ *
6
+ * Scans text nodes and reports any that originated from invalid (bogus) AST
7
+ * nodes, which indicates a stray end tag that the parser could not match
8
+ * to an opening element.
9
+ */
3
10
  export default createRule({
4
11
  meta,
5
12
  async verify({ document, report, t }) {
6
13
  await document.walkOn('Text', text => {
7
- const raw = text.raw.trim();
8
- if (/^<\//.test(raw)) {
14
+ if (text.isBogus) {
9
15
  report({
10
16
  scope: text,
11
17
  message: t('{0} detected', t('Orphaned end tag')),
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for `no-orphaned-end-tag`: 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 `no-orphaned-end-tag`: categorized as a validation rule. */
1
2
  export default {
2
3
  category: 'validation',
3
4
  };
@@ -1,6 +1,14 @@
1
1
  import type { ARIAVersion } from '@markuplint/ml-spec';
2
+ /**
3
+ * Rule that validates all ID references in attributes point to existing elements.
4
+ *
5
+ * Checks DOMID and DOMID-list attributes (e.g., `for`, `aria-labelledby`),
6
+ * ARIA ID reference properties, and fragment identifiers in hyperlinks (`href="#id"`).
7
+ * Reports any reference to an ID that does not exist in the document. Skips
8
+ * validation when dynamic IDs or preprocessor blocks are detected.
9
+ */
2
10
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, {
3
- ariaVersion: ARIAVersion;
11
+ ariaVersion: ARIAVersion | undefined;
4
12
  fragmentRefersNameAttr: boolean;
5
13
  }>>;
6
14
  export default _default;
@@ -2,11 +2,20 @@ import { createRule, getAttrSpecs, ariaSpecs } from '@markuplint/ml-core';
2
2
  import { ARIA_RECOMMENDED_VERSION } from '@markuplint/ml-spec';
3
3
  import { decodeEntities, decodeHref } from '@markuplint/shared';
4
4
  import meta from './meta.js';
5
+ /** CSS selector matching hyperlink elements that have an `href` attribute. */
5
6
  const HYPERLINK_SELECTOR = 'a[href], area[href]';
7
+ /**
8
+ * Rule that validates all ID references in attributes point to existing elements.
9
+ *
10
+ * Checks DOMID and DOMID-list attributes (e.g., `for`, `aria-labelledby`),
11
+ * ARIA ID reference properties, and fragment identifiers in hyperlinks (`href="#id"`).
12
+ * Reports any reference to an ID that does not exist in the document. Skips
13
+ * validation when dynamic IDs or preprocessor blocks are detected.
14
+ */
6
15
  export default createRule({
7
16
  meta: meta,
8
17
  defaultOptions: {
9
- ariaVersion: ARIA_RECOMMENDED_VERSION,
18
+ ariaVersion: undefined,
10
19
  fragmentRefersNameAttr: false,
11
20
  },
12
21
  async verify({ document, report, t }) {
@@ -91,7 +100,7 @@ export default createRule({
91
100
  }
92
101
  }
93
102
  }
94
- const { props } = ariaSpecs(document.specs, attr.rule.options.ariaVersion);
103
+ const { props } = ariaSpecs(document.specs, attr.rule.options.ariaVersion ?? document.ruleCommonSettings?.ariaVersion ?? ARIA_RECOMMENDED_VERSION);
95
104
  const aria = props.find(prop => prop.name === name);
96
105
  if (aria) {
97
106
  if (aria.value === 'ID reference' && !idList.has(value)) {
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `no-refer-to-non-existent-id` rule, categorized as accessibility. */
1
2
  declare const _default: {
2
3
  readonly category: "a11y";
3
4
  };
@@ -1,3 +1,4 @@
1
+ /** Rule metadata for the `no-refer-to-non-existent-id` rule, categorized as accessibility. */
1
2
  export default {
2
3
  category: 'a11y',
3
4
  };
@@ -0,0 +1,71 @@
1
+ import type { BrowserName, SupportStatement } from '@mdn/browser-compat-data';
2
+ /**
3
+ * Target browser with name and minimum version.
4
+ */
5
+ export interface TargetBrowser {
6
+ readonly browser: BrowserName;
7
+ readonly version: string;
8
+ readonly displayName: string;
9
+ }
10
+ /**
11
+ * Result of checking browser support for a feature.
12
+ */
13
+ export interface UnsupportedResult {
14
+ readonly browser: BrowserName;
15
+ readonly displayName: string;
16
+ readonly targetVersion: string;
17
+ readonly addedVersion: string | false;
18
+ readonly removedVersion?: string;
19
+ }
20
+ /**
21
+ * Convert a browserslist browser name to a BCD browser name.
22
+ *
23
+ * @param browserslistName - The browser name from browserslist (e.g., "and_chr")
24
+ * @returns The corresponding BCD browser name, or null if unknown
25
+ */
26
+ export declare function toBcdBrowserId(browserslistName: string): BrowserName | null;
27
+ /**
28
+ * Parse a version string into a comparable numeric tuple.
29
+ *
30
+ * Handles BCD version prefixes like "≤37" by stripping the prefix.
31
+ *
32
+ * @param version - Version string (e.g., "16.4", "≤37", "preview")
33
+ * @returns Tuple of [major, minor, patch]
34
+ */
35
+ export declare function parseVersion(version: string): readonly [number, number, number];
36
+ /**
37
+ * Check if the target browser version satisfies the required version.
38
+ *
39
+ * Returns true if the target version is greater than or equal to the
40
+ * version the feature was added in.
41
+ *
42
+ * @param targetVersion - The browser version the user targets
43
+ * @param addedVersion - The version the feature was added in
44
+ * @returns Whether the target version supports the feature
45
+ */
46
+ export declare function isVersionSatisfied(targetVersion: string, addedVersion: string): boolean;
47
+ /**
48
+ * Check if a feature is supported by a specific browser version.
49
+ *
50
+ * @param support - The BCD support statement for the feature
51
+ * @param target - The target browser to check
52
+ * @returns null if supported or unknown, UnsupportedResult if not supported
53
+ */
54
+ export declare function checkSupport(support: SupportStatement | undefined, target: TargetBrowser): UnsupportedResult | null;
55
+ /**
56
+ * Check browser support for an HTML element.
57
+ *
58
+ * @param elementName - The HTML element name (e.g., "dialog")
59
+ * @param targets - Array of target browsers to check
60
+ * @returns Array of unsupported results (empty if all supported)
61
+ */
62
+ export declare function checkElementSupport(elementName: string, targets: readonly TargetBrowser[]): Promise<readonly UnsupportedResult[]>;
63
+ /**
64
+ * Check browser support for an HTML attribute on a specific element.
65
+ *
66
+ * @param elementName - The HTML element name (e.g., "input")
67
+ * @param attrName - The attribute name (e.g., "list")
68
+ * @param targets - Array of target browsers to check
69
+ * @returns Array of unsupported results (empty if all supported)
70
+ */
71
+ export declare function checkAttributeSupport(elementName: string, attrName: string, targets: readonly TargetBrowser[]): Promise<readonly UnsupportedResult[]>;