@markuplint/rules 5.0.0-rc.2 → 5.0.0-rc.5

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 (573) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/CLAUDE.md +31 -2
  3. package/lib/{wai-aria-deprecated-role → aria-prop-requires-role}/index.d.ts +0 -1
  4. package/lib/{wai-aria-no-global-prop → aria-prop-requires-role}/index.js +0 -1
  5. package/lib/attr-check.d.ts +0 -48
  6. package/lib/attr-check.js +0 -36
  7. package/lib/attr-eligibility.d.ts +41 -0
  8. package/lib/attr-eligibility.js +60 -0
  9. package/lib/attr-value-quotes/index.d.ts +0 -7
  10. package/lib/attr-value-quotes/index.js +0 -7
  11. package/lib/attr-value-quotes/meta.d.ts +0 -1
  12. package/lib/attr-value-quotes/meta.js +0 -1
  13. package/lib/case-sensitive-attr-name/index.d.ts +0 -8
  14. package/lib/case-sensitive-attr-name/index.js +0 -8
  15. package/lib/case-sensitive-attr-name/meta.d.ts +0 -1
  16. package/lib/case-sensitive-attr-name/meta.js +0 -1
  17. package/lib/case-sensitive-tag-name/index.d.ts +0 -8
  18. package/lib/case-sensitive-tag-name/index.js +0 -8
  19. package/lib/case-sensitive-tag-name/meta.d.ts +0 -1
  20. package/lib/case-sensitive-tag-name/meta.js +0 -1
  21. package/lib/class-naming/index.d.ts +0 -8
  22. package/lib/class-naming/index.js +0 -8
  23. package/lib/class-naming/meta.d.ts +1 -2
  24. package/lib/class-naming/meta.js +1 -2
  25. package/lib/consistent-table-row-length/index.d.ts +14 -0
  26. package/lib/consistent-table-row-length/index.js +69 -0
  27. package/lib/consistent-table-row-length/meta.d.ts +4 -0
  28. package/lib/consistent-table-row-length/meta.js +3 -0
  29. package/lib/create-message.d.ts +2 -25
  30. package/lib/create-message.js +2 -53
  31. package/lib/debug.d.ts +1 -9
  32. package/lib/debug.js +1 -5
  33. package/lib/element-supports-aria-prop/index.d.ts +12 -0
  34. package/lib/element-supports-aria-prop/index.js +38 -0
  35. package/lib/form-attr-references-form/index.d.ts +12 -0
  36. package/lib/form-attr-references-form/index.js +64 -0
  37. package/lib/{correct-aspect-ratio → form-attr-references-form}/meta.d.ts +1 -1
  38. package/lib/form-attr-references-form/meta.js +3 -0
  39. package/lib/head-element-order/meta.d.ts +1 -1
  40. package/lib/head-element-order/meta.js +1 -1
  41. package/lib/helpers.d.ts +8 -138
  42. package/lib/helpers.js +24 -165
  43. package/lib/index.d.ts +135 -78
  44. package/lib/index.js +167 -82
  45. package/lib/input-list-references-datalist/index.d.ts +13 -0
  46. package/lib/input-list-references-datalist/index.js +46 -0
  47. package/lib/input-list-references-datalist/meta.d.ts +4 -0
  48. package/lib/input-list-references-datalist/meta.js +3 -0
  49. package/lib/itemprop-requires-itemscope/index.d.ts +21 -0
  50. package/lib/itemprop-requires-itemscope/index.js +53 -0
  51. package/lib/itemprop-requires-itemscope/meta.d.ts +4 -0
  52. package/lib/itemprop-requires-itemscope/meta.js +3 -0
  53. package/lib/label-for-references-labelable/index.d.ts +12 -0
  54. package/lib/label-for-references-labelable/index.js +68 -0
  55. package/lib/label-for-references-labelable/meta.d.ts +4 -0
  56. package/lib/label-for-references-labelable/meta.js +3 -0
  57. package/lib/label-has-control/index.d.ts +5 -5
  58. package/lib/label-has-control/index.js +5 -18
  59. package/lib/label-has-control/meta.d.ts +0 -1
  60. package/lib/label-has-control/meta.js +0 -1
  61. package/lib/label-no-multiple-controls/index.d.ts +31 -0
  62. package/lib/label-no-multiple-controls/index.js +104 -0
  63. package/lib/label-no-multiple-controls/meta.d.ts +4 -0
  64. package/lib/label-no-multiple-controls/meta.js +3 -0
  65. package/lib/landmark-roles/roles.d.ts +32 -0
  66. package/lib/landmark-roles/roles.js +73 -0
  67. package/lib/link-types/index.d.ts +0 -5
  68. package/lib/link-types/index.js +5 -6
  69. package/lib/link-types/meta.d.ts +1 -2
  70. package/lib/link-types/meta.js +1 -2
  71. package/lib/map-id-name-match/index.d.ts +10 -0
  72. package/lib/map-id-name-match/index.js +39 -0
  73. package/lib/map-id-name-match/meta.d.ts +4 -0
  74. package/lib/map-id-name-match/meta.js +3 -0
  75. package/lib/meta-charset-position/index.d.ts +15 -0
  76. package/lib/meta-charset-position/index.js +31 -0
  77. package/lib/meta-charset-position/meta.d.ts +4 -0
  78. package/lib/meta-charset-position/meta.js +3 -0
  79. package/lib/meter-value-bounds/index.d.ts +10 -0
  80. package/lib/meter-value-bounds/index.js +123 -0
  81. package/lib/meter-value-bounds/meta.d.ts +4 -0
  82. package/lib/meter-value-bounds/meta.js +3 -0
  83. package/lib/{wai-aria-required-props → no-abstract-role}/index.d.ts +0 -1
  84. package/lib/{wai-aria-abstract-role → no-abstract-role}/index.js +0 -1
  85. package/lib/no-always-matching-source/index.d.ts +13 -0
  86. package/lib/no-always-matching-source/index.js +100 -0
  87. package/lib/no-always-matching-source/meta.d.ts +4 -0
  88. package/lib/no-always-matching-source/meta.js +3 -0
  89. package/lib/no-ambiguous-navigable-target-names/index.d.ts +0 -8
  90. package/lib/no-ambiguous-navigable-target-names/index.js +0 -8
  91. package/lib/no-ambiguous-navigable-target-names/meta.d.ts +1 -2
  92. package/lib/no-ambiguous-navigable-target-names/meta.js +1 -2
  93. package/lib/{wai-aria-required-owned-elements → no-aria-on-presentational-children}/index.d.ts +0 -1
  94. package/lib/{wai-aria-presentational-children → no-aria-on-presentational-children}/index.js +0 -1
  95. package/lib/no-aria-on-unsupported-element/index.d.ts +11 -0
  96. package/lib/no-aria-on-unsupported-element/index.js +35 -0
  97. package/lib/no-aria-on-unsupported-element/meta.d.ts +9 -0
  98. package/lib/no-aria-on-unsupported-element/meta.js +8 -0
  99. package/lib/no-boolean-attr-value/index.d.ts +0 -7
  100. package/lib/no-boolean-attr-value/index.js +0 -7
  101. package/lib/no-boolean-attr-value/meta.d.ts +0 -1
  102. package/lib/no-boolean-attr-value/meta.js +0 -1
  103. package/lib/no-broken-fragment-link/index.d.ts +15 -0
  104. package/lib/no-broken-fragment-link/index.js +93 -0
  105. package/lib/no-broken-fragment-link/meta.d.ts +4 -0
  106. package/lib/no-broken-fragment-link/meta.js +3 -0
  107. package/lib/no-consecutive-br/index.d.ts +0 -8
  108. package/lib/no-consecutive-br/index.js +0 -8
  109. package/lib/no-consecutive-br/meta.d.ts +0 -1
  110. package/lib/no-consecutive-br/meta.js +0 -1
  111. package/lib/no-content-after-body/index.d.ts +25 -0
  112. package/lib/no-content-after-body/index.js +51 -0
  113. package/lib/no-content-after-body/meta.d.ts +4 -0
  114. package/lib/no-content-after-body/meta.js +3 -0
  115. package/lib/no-contradictory-aria-prop/index.d.ts +10 -0
  116. package/lib/no-contradictory-aria-prop/index.js +34 -0
  117. package/lib/{wai-aria-abstract-role → no-default-aria-value}/index.d.ts +0 -1
  118. package/lib/{wai-aria-default-value → no-default-aria-value}/index.js +0 -1
  119. package/lib/no-default-value/index.d.ts +0 -7
  120. package/lib/no-default-value/index.js +0 -7
  121. package/lib/no-default-value/meta.d.ts +0 -1
  122. package/lib/no-default-value/meta.js +0 -1
  123. package/lib/no-deprecated-aria-prop/index.d.ts +3 -0
  124. package/lib/{wai-aria-deprecated-props → no-deprecated-aria-prop}/index.js +0 -1
  125. package/lib/no-deprecated-attr/index.d.ts +2 -0
  126. package/lib/{deprecated-attr → no-deprecated-attr}/index.js +5 -9
  127. package/lib/no-deprecated-attr/meta.d.ts +4 -0
  128. package/lib/no-deprecated-attr/meta.js +3 -0
  129. package/lib/no-deprecated-element/index.d.ts +2 -0
  130. package/lib/no-deprecated-element/index.js +27 -0
  131. package/lib/no-deprecated-element/meta.d.ts +4 -0
  132. package/lib/no-deprecated-element/meta.js +3 -0
  133. package/lib/no-deprecated-role/index.d.ts +3 -0
  134. package/lib/{wai-aria-deprecated-role → no-deprecated-role}/index.js +0 -1
  135. package/lib/no-disallowed-ancestor/index.d.ts +2 -0
  136. package/lib/no-disallowed-ancestor/index.js +25 -0
  137. package/lib/no-disallowed-ancestor/meta.d.ts +4 -0
  138. package/lib/no-disallowed-ancestor/meta.js +3 -0
  139. package/lib/no-disallowed-attr/index.d.ts +28 -0
  140. package/lib/no-disallowed-attr/index.js +77 -0
  141. package/lib/no-disallowed-attr/meta.d.ts +4 -0
  142. package/lib/no-disallowed-attr/meta.js +3 -0
  143. package/lib/no-duplicate-attr/index.d.ts +2 -0
  144. package/lib/{attr-duplication → no-duplicate-attr}/index.js +0 -7
  145. package/lib/no-duplicate-attr/meta.d.ts +6 -0
  146. package/lib/no-duplicate-attr/meta.js +10 -0
  147. package/lib/no-duplicate-autofocus/index.d.ts +0 -5
  148. package/lib/no-duplicate-autofocus/index.js +20 -6
  149. package/lib/no-duplicate-autofocus/meta.d.ts +1 -1
  150. package/lib/no-duplicate-autofocus/meta.js +1 -1
  151. package/lib/no-duplicate-dt/index.d.ts +0 -6
  152. package/lib/no-duplicate-dt/index.js +1 -6
  153. package/lib/no-duplicate-dt/meta.d.ts +1 -2
  154. package/lib/no-duplicate-dt/meta.js +1 -2
  155. package/lib/no-duplicate-h1/index.d.ts +18 -0
  156. package/lib/no-duplicate-h1/index.js +41 -0
  157. package/lib/no-duplicate-h1/meta.d.ts +4 -0
  158. package/lib/no-duplicate-h1/meta.js +3 -0
  159. package/lib/no-duplicate-id/index.d.ts +2 -0
  160. package/lib/{id-duplication → no-duplicate-id}/index.js +0 -7
  161. package/lib/no-duplicate-id/meta.d.ts +4 -0
  162. package/lib/no-duplicate-id/meta.js +3 -0
  163. package/lib/no-duplicate-sibling-attr/index.d.ts +2 -0
  164. package/lib/no-duplicate-sibling-attr/index.js +35 -0
  165. package/lib/no-duplicate-sibling-attr/meta.d.ts +4 -0
  166. package/lib/no-duplicate-sibling-attr/meta.js +3 -0
  167. package/lib/no-duplicate-visible-main/index.d.ts +0 -1
  168. package/lib/no-duplicate-visible-main/index.js +0 -1
  169. package/lib/no-duplicate-visible-main/meta.d.ts +1 -1
  170. package/lib/no-duplicate-visible-main/meta.js +1 -1
  171. package/lib/no-empty-palpable-content/index.d.ts +0 -8
  172. package/lib/no-empty-palpable-content/index.js +0 -8
  173. package/lib/no-empty-palpable-content/meta.d.ts +1 -2
  174. package/lib/no-empty-palpable-content/meta.js +1 -2
  175. package/lib/no-empty-table-track/index.d.ts +12 -0
  176. package/lib/no-empty-table-track/index.js +42 -0
  177. package/lib/no-empty-table-track/meta.d.ts +4 -0
  178. package/lib/no-empty-table-track/meta.js +3 -0
  179. package/lib/no-event-handler-attr/index.d.ts +7 -0
  180. package/lib/{no-use-event-handler-attr → no-event-handler-attr}/index.js +0 -11
  181. package/lib/no-event-handler-attr/meta.d.ts +4 -0
  182. package/lib/no-event-handler-attr/meta.js +3 -0
  183. package/lib/no-experimental-features/index.d.ts +9 -0
  184. package/lib/no-experimental-features/index.js +53 -0
  185. package/lib/no-experimental-features/meta.d.ts +4 -0
  186. package/lib/no-experimental-features/meta.js +3 -0
  187. package/lib/no-extra-selected-options/index.d.ts +10 -0
  188. package/lib/no-extra-selected-options/index.js +37 -0
  189. package/lib/no-extra-selected-options/meta.d.ts +4 -0
  190. package/lib/no-extra-selected-options/meta.js +3 -0
  191. package/lib/no-focusable-in-aria-hidden/index.d.ts +3 -0
  192. package/lib/{wai-aria-interaction-in-hidden → no-focusable-in-aria-hidden}/index.js +0 -1
  193. package/lib/no-focusable-in-aria-hidden/meta.d.ts +4 -0
  194. package/lib/no-focusable-in-aria-hidden/meta.js +3 -0
  195. package/lib/no-hardcoded-id/index.d.ts +2 -0
  196. package/lib/{no-hard-code-id → no-hardcoded-id}/index.js +0 -8
  197. package/lib/no-hardcoded-id/meta.d.ts +4 -0
  198. package/lib/no-hardcoded-id/meta.js +3 -0
  199. package/lib/no-ineffective-attr/index.d.ts +2 -0
  200. package/lib/{ineffective-attr → no-ineffective-attr}/index.js +0 -7
  201. package/lib/no-ineffective-attr/meta.d.ts +5 -0
  202. package/lib/no-ineffective-attr/meta.js +4 -0
  203. package/lib/no-input-file-value/index.d.ts +10 -0
  204. package/lib/no-input-file-value/index.js +41 -0
  205. package/lib/no-input-file-value/meta.d.ts +4 -0
  206. package/lib/no-input-file-value/meta.js +3 -0
  207. package/lib/no-invalid-aria-prop-value/index.d.ts +3 -0
  208. package/lib/{wai-aria-value → no-invalid-aria-prop-value}/index.js +0 -1
  209. package/lib/no-invalid-aria-prop-value/meta.d.ts +4 -0
  210. package/lib/no-invalid-aria-prop-value/meta.js +3 -0
  211. package/lib/no-invalid-attr-value/index.d.ts +27 -0
  212. package/lib/no-invalid-attr-value/index.js +83 -0
  213. package/lib/no-invalid-attr-value/meta.d.ts +4 -0
  214. package/lib/no-invalid-attr-value/meta.js +3 -0
  215. package/lib/no-malformed-character-reference/index.d.ts +2 -0
  216. package/lib/no-malformed-character-reference/index.js +38 -0
  217. package/lib/no-malformed-character-reference/meta.d.ts +5 -0
  218. package/lib/no-malformed-character-reference/meta.js +20 -0
  219. package/lib/{correct-aspect-ratio → no-mismatched-aspect-ratio}/index.js +13 -3
  220. package/lib/no-mismatched-aspect-ratio/meta.d.ts +4 -0
  221. package/lib/no-mismatched-aspect-ratio/meta.js +3 -0
  222. package/lib/{correct-aspect-ratio → no-mismatched-aspect-ratio}/resolve-image-size.js +8 -2
  223. package/lib/no-mixed-srcset-descriptors/index.d.ts +12 -0
  224. package/lib/no-mixed-srcset-descriptors/index.js +47 -0
  225. package/lib/no-mixed-srcset-descriptors/meta.d.ts +4 -0
  226. package/lib/no-mixed-srcset-descriptors/meta.js +3 -0
  227. package/lib/no-nested-top-level-landmark/index.d.ts +10 -0
  228. package/lib/no-nested-top-level-landmark/index.js +52 -0
  229. package/lib/no-nested-top-level-landmark/meta.d.ts +4 -0
  230. package/lib/no-nested-top-level-landmark/meta.js +3 -0
  231. package/lib/no-nonstandard-features/index.d.ts +9 -0
  232. package/lib/no-nonstandard-features/index.js +53 -0
  233. package/lib/no-nonstandard-features/meta.d.ts +4 -0
  234. package/lib/no-nonstandard-features/meta.js +3 -0
  235. package/lib/no-obsolete-attr/index.d.ts +2 -0
  236. package/lib/no-obsolete-attr/index.js +27 -0
  237. package/lib/no-obsolete-attr/meta.d.ts +4 -0
  238. package/lib/no-obsolete-attr/meta.js +3 -0
  239. package/lib/no-obsolete-doctype/index.d.ts +2 -0
  240. package/lib/{doctype → no-obsolete-doctype}/index.js +9 -16
  241. package/lib/no-obsolete-doctype/meta.d.ts +4 -0
  242. package/lib/no-obsolete-doctype/meta.js +3 -0
  243. package/lib/no-obsolete-element/index.d.ts +2 -0
  244. package/lib/{deprecated-element → no-obsolete-element}/index.js +6 -10
  245. package/lib/no-obsolete-element/meta.d.ts +4 -0
  246. package/lib/no-obsolete-element/meta.js +3 -0
  247. package/lib/no-orphaned-end-tag/index.d.ts +0 -7
  248. package/lib/no-orphaned-end-tag/index.js +0 -7
  249. package/lib/no-orphaned-end-tag/meta.d.ts +2 -2
  250. package/lib/no-orphaned-end-tag/meta.js +5 -2
  251. package/lib/no-prohibited-naming/index.d.ts +8 -0
  252. package/lib/no-prohibited-naming/index.js +36 -0
  253. package/lib/no-prohibited-naming/meta.d.ts +4 -0
  254. package/lib/no-prohibited-naming/meta.js +3 -0
  255. package/lib/{use-list → no-pseudo-list}/index.d.ts +1 -8
  256. package/lib/{use-list → no-pseudo-list}/index.js +0 -7
  257. package/lib/no-pseudo-list/meta.d.ts +4 -0
  258. package/lib/no-pseudo-list/meta.js +3 -0
  259. package/lib/{redundant-accessible-name → no-redundant-accessible-name}/index.d.ts +0 -4
  260. package/lib/{redundant-accessible-name → no-redundant-accessible-name}/index.js +0 -4
  261. package/lib/no-redundant-accessible-name/meta.d.ts +4 -0
  262. package/lib/no-redundant-accessible-name/meta.js +3 -0
  263. package/lib/no-redundant-aria-prop/index.d.ts +10 -0
  264. package/lib/{wai-aria-implicit-props → no-redundant-aria-prop}/index.js +9 -3
  265. package/lib/no-redundant-aria-prop/meta.d.ts +4 -0
  266. package/lib/no-redundant-aria-prop/meta.js +3 -0
  267. package/lib/no-redundant-role/index.d.ts +3 -0
  268. package/lib/{wai-aria-implicit-role → no-redundant-role}/index.js +0 -1
  269. package/lib/no-redundant-role/meta.d.ts +4 -0
  270. package/lib/no-redundant-role/meta.js +3 -0
  271. package/lib/no-refer-to-non-existent-id/index.d.ts +0 -9
  272. package/lib/no-refer-to-non-existent-id/index.js +1 -62
  273. package/lib/no-refer-to-non-existent-id/meta.d.ts +1 -2
  274. package/lib/no-refer-to-non-existent-id/meta.js +1 -2
  275. package/lib/no-restricted-attr/index.d.ts +27 -0
  276. package/lib/no-restricted-attr/index.js +96 -0
  277. package/lib/no-restricted-attr/meta.d.ts +4 -0
  278. package/lib/no-restricted-attr/meta.js +3 -0
  279. package/lib/no-restricted-element/index.d.ts +2 -0
  280. package/lib/{disallowed-element → no-restricted-element}/index.js +7 -8
  281. package/lib/no-restricted-element/meta.d.ts +4 -0
  282. package/lib/no-restricted-element/meta.js +3 -0
  283. package/lib/no-skipped-heading-level/index.d.ts +13 -0
  284. package/lib/{heading-levels → no-skipped-heading-level}/index.js +10 -5
  285. package/lib/no-skipped-heading-level/meta.d.ts +4 -0
  286. package/lib/no-skipped-heading-level/meta.js +3 -0
  287. package/lib/no-stray-head-or-body-tag/index.d.ts +28 -0
  288. package/lib/no-stray-head-or-body-tag/index.js +61 -0
  289. package/lib/no-stray-head-or-body-tag/meta.d.ts +4 -0
  290. package/lib/no-stray-head-or-body-tag/meta.js +3 -0
  291. package/lib/no-table-cell-overlap/index.d.ts +12 -0
  292. package/lib/no-table-cell-overlap/index.js +30 -0
  293. package/lib/no-table-cell-overlap/meta.d.ts +4 -0
  294. package/lib/no-table-cell-overlap/meta.js +3 -0
  295. package/lib/no-table-span-overflow/index.d.ts +12 -0
  296. package/lib/no-table-span-overflow/index.js +37 -0
  297. package/lib/no-table-span-overflow/meta.d.ts +4 -0
  298. package/lib/no-table-span-overflow/meta.js +3 -0
  299. package/lib/no-unclosed-element-at-eof/index.d.ts +2 -0
  300. package/lib/no-unclosed-element-at-eof/index.js +86 -0
  301. package/lib/no-unclosed-element-at-eof/meta.d.ts +4 -0
  302. package/lib/no-unclosed-element-at-eof/meta.js +3 -0
  303. package/lib/no-unescaped-char/index.d.ts +14 -0
  304. package/lib/{character-reference → no-unescaped-char}/index.js +31 -20
  305. package/lib/no-unescaped-char/meta.d.ts +4 -0
  306. package/lib/no-unescaped-char/meta.js +3 -0
  307. package/lib/{invalid-attr → no-unknown-attr}/index.d.ts +4 -19
  308. package/lib/no-unknown-attr/index.js +91 -0
  309. package/lib/no-unknown-attr/meta.d.ts +4 -0
  310. package/lib/no-unknown-attr/meta.js +3 -0
  311. package/lib/no-unknown-role/index.d.ts +3 -0
  312. package/lib/{wai-aria-non-existent-role → no-unknown-role}/index.js +0 -1
  313. package/lib/no-unknown-role/meta.d.ts +4 -0
  314. package/lib/no-unknown-role/meta.js +3 -0
  315. package/lib/no-unpaired-srcset-sizes/index.d.ts +12 -0
  316. package/lib/no-unpaired-srcset-sizes/index.js +77 -0
  317. package/lib/no-unpaired-srcset-sizes/meta.d.ts +4 -0
  318. package/lib/no-unpaired-srcset-sizes/meta.js +3 -0
  319. package/lib/{no-unsupported-features → no-unsupported-browser-features}/index.d.ts +1 -10
  320. package/lib/no-unsupported-browser-features/index.js +81 -0
  321. package/lib/no-unsupported-browser-features/meta.d.ts +4 -0
  322. package/lib/no-unsupported-browser-features/meta.js +3 -0
  323. package/lib/permitted-contents/index.d.ts +0 -18
  324. package/lib/permitted-contents/index.js +0 -78
  325. package/lib/permitted-contents/meta.d.ts +1 -2
  326. package/lib/permitted-contents/meta.js +1 -2
  327. package/lib/permitted-contents/represent-transparent-nodes.js +15 -6
  328. package/lib/permitted-roles/index.d.ts +3 -0
  329. package/lib/{wai-aria-permitted-roles → permitted-roles}/index.js +0 -1
  330. package/lib/permitted-roles/meta.d.ts +4 -0
  331. package/lib/permitted-roles/meta.js +3 -0
  332. package/lib/placeholder-label-option/index.d.ts +10 -4
  333. package/lib/placeholder-label-option/index.js +30 -17
  334. package/lib/placeholder-label-option/meta.d.ts +1 -2
  335. package/lib/placeholder-label-option/meta.js +1 -2
  336. package/lib/progress-value-bounds/index.d.ts +10 -0
  337. package/lib/progress-value-bounds/index.js +59 -0
  338. package/lib/progress-value-bounds/meta.d.ts +4 -0
  339. package/lib/progress-value-bounds/meta.js +3 -0
  340. package/lib/require-accessible-name/index.d.ts +0 -7
  341. package/lib/require-accessible-name/index.js +0 -7
  342. package/lib/require-accessible-name/meta.d.ts +0 -1
  343. package/lib/require-accessible-name/meta.js +0 -1
  344. package/lib/require-adjacent-popover/index.d.ts +2 -0
  345. package/lib/{neighbor-popovers → require-adjacent-popover}/index.js +1 -8
  346. package/lib/require-adjacent-popover/meta.d.ts +4 -0
  347. package/lib/require-adjacent-popover/meta.js +3 -0
  348. package/lib/require-ancestor/index.d.ts +2 -0
  349. package/lib/require-ancestor/index.js +29 -0
  350. package/lib/require-ancestor/meta.d.ts +4 -0
  351. package/lib/require-ancestor/meta.js +3 -0
  352. package/lib/require-aria-prop/index.d.ts +3 -0
  353. package/lib/{wai-aria-required-props → require-aria-prop}/index.js +0 -1
  354. package/lib/require-aria-prop/meta.d.ts +4 -0
  355. package/lib/require-aria-prop/meta.js +3 -0
  356. package/lib/{required-attr → require-attr}/index.d.ts +2 -9
  357. package/lib/{required-attr → require-attr}/index.js +0 -7
  358. package/lib/require-attr/meta.d.ts +4 -0
  359. package/lib/require-attr/meta.js +3 -0
  360. package/lib/require-datetime/index.d.ts +0 -8
  361. package/lib/require-datetime/index.js +0 -8
  362. package/lib/require-datetime/meta.d.ts +1 -2
  363. package/lib/require-datetime/meta.js +1 -2
  364. package/lib/require-dialog-autofocus/index.d.ts +0 -10
  365. package/lib/require-dialog-autofocus/index.js +0 -10
  366. package/lib/require-dialog-autofocus/meta.d.ts +0 -1
  367. package/lib/require-dialog-autofocus/meta.js +0 -1
  368. package/lib/require-doctype/index.d.ts +2 -0
  369. package/lib/require-doctype/index.js +19 -0
  370. package/lib/require-doctype/meta.d.ts +5 -0
  371. package/lib/require-doctype/meta.js +10 -0
  372. package/lib/{required-element → require-element}/index.d.ts +1 -9
  373. package/lib/{required-element → require-element}/index.js +0 -8
  374. package/lib/require-element/meta.d.ts +4 -0
  375. package/lib/require-element/meta.js +3 -0
  376. package/lib/require-end-tag/index.d.ts +2 -0
  377. package/lib/{end-tag → require-end-tag}/index.js +0 -7
  378. package/lib/require-end-tag/meta.d.ts +4 -0
  379. package/lib/require-end-tag/meta.js +3 -0
  380. package/lib/require-h1/index.d.ts +17 -0
  381. package/lib/{required-h1 → require-h1}/index.js +6 -14
  382. package/lib/require-h1/meta.d.ts +4 -0
  383. package/lib/require-h1/meta.js +3 -0
  384. package/lib/require-landmark-label/index.d.ts +11 -0
  385. package/lib/require-landmark-label/index.js +55 -0
  386. package/lib/require-landmark-label/meta.d.ts +4 -0
  387. package/lib/require-landmark-label/meta.js +3 -0
  388. package/lib/require-owned-elements/index.d.ts +3 -0
  389. package/lib/{wai-aria-required-owned-elements → require-owned-elements}/index.js +0 -2
  390. package/lib/require-owned-elements/meta.d.ts +4 -0
  391. package/lib/require-owned-elements/meta.js +3 -0
  392. package/lib/require-parent-role/index.d.ts +3 -0
  393. package/lib/{wai-aria-required-parent-role → require-parent-role}/index.js +0 -1
  394. package/lib/require-parent-role/meta.d.ts +4 -0
  395. package/lib/require-parent-role/meta.js +3 -0
  396. package/lib/role-supports-aria-prop/index.d.ts +8 -0
  397. package/lib/{wai-aria-disallowed-props → role-supports-aria-prop}/index.js +11 -10
  398. package/lib/role-supports-aria-prop/meta.d.ts +4 -0
  399. package/lib/role-supports-aria-prop/meta.js +3 -0
  400. package/lib/rule-aliases.d.ts +2 -0
  401. package/lib/rule-aliases.js +325 -0
  402. package/lib/sizes-auto-requires-lazy-loading/index.d.ts +14 -0
  403. package/lib/sizes-auto-requires-lazy-loading/index.js +68 -0
  404. package/lib/sizes-auto-requires-lazy-loading/meta.d.ts +4 -0
  405. package/lib/sizes-auto-requires-lazy-loading/meta.js +3 -0
  406. package/lib/srcset-sizes-constraint/parse-srcset.d.ts +6 -0
  407. package/lib/srcset-sizes-constraint/parse-srcset.js +6 -0
  408. package/lib/srcset-sizes-constraint/sibling-helpers.d.ts +21 -0
  409. package/lib/srcset-sizes-constraint/sibling-helpers.js +37 -0
  410. package/lib/tab-requires-tabpanel/index.d.ts +3 -0
  411. package/lib/tab-requires-tabpanel/index.js +21 -0
  412. package/lib/tab-requires-tabpanel/meta.d.ts +4 -0
  413. package/lib/tab-requires-tabpanel/meta.js +3 -0
  414. package/lib/table-row-column-alignment/grid.d.ts +108 -52
  415. package/lib/table-row-column-alignment/grid.js +276 -203
  416. package/lib/table-row-column-alignment/types.d.ts +6 -8
  417. package/lib/usemap-references-map/index.d.ts +14 -0
  418. package/lib/usemap-references-map/index.js +46 -0
  419. package/lib/usemap-references-map/meta.d.ts +4 -0
  420. package/lib/usemap-references-map/meta.js +3 -0
  421. package/lib/valid-importmap/index.d.ts +2 -0
  422. package/lib/valid-importmap/index.js +176 -0
  423. package/lib/valid-importmap/meta.d.ts +4 -0
  424. package/lib/valid-importmap/meta.js +3 -0
  425. package/lib/valid-speculation-rules/index.d.ts +2 -0
  426. package/lib/valid-speculation-rules/index.js +292 -0
  427. package/lib/valid-speculation-rules/meta.d.ts +4 -0
  428. package/lib/valid-speculation-rules/meta.js +3 -0
  429. package/lib/wai-aria/checkings/contradictory-aria-prop.d.ts +23 -0
  430. package/lib/wai-aria/checkings/{implicit-props.js → contradictory-aria-prop.js} +22 -14
  431. package/lib/wai-aria/checkings/element-supports-aria-prop.d.ts +20 -0
  432. package/lib/wai-aria/checkings/element-supports-aria-prop.js +83 -0
  433. package/lib/wai-aria/checkings/prohibited-naming.d.ts +35 -0
  434. package/lib/wai-aria/checkings/prohibited-naming.js +64 -0
  435. package/lib/wai-aria/checkings/redundant-aria-prop.d.ts +23 -0
  436. package/lib/wai-aria/checkings/redundant-aria-prop.js +53 -0
  437. package/lib/wai-aria/checkings/required-prop.d.ts +4 -0
  438. package/lib/wai-aria/checkings/required-prop.js +16 -3
  439. package/lib/wai-aria/checkings/role-supports-aria-prop.d.ts +20 -0
  440. package/lib/wai-aria/checkings/role-supports-aria-prop.js +30 -0
  441. package/lib/wai-aria/checkings/tab-requires-tabpanel.d.ts +19 -0
  442. package/lib/wai-aria/checkings/tab-requires-tabpanel.js +56 -0
  443. package/lib/wai-aria/default-options.js +1 -0
  444. package/lib/wai-aria/types.d.ts +2 -0
  445. package/package.json +11 -10
  446. package/schema.json +275 -59
  447. package/SKILL.md +0 -77
  448. package/lib/attr-duplication/index.d.ts +0 -9
  449. package/lib/attr-duplication/meta.d.ts +0 -6
  450. package/lib/attr-duplication/meta.js +0 -5
  451. package/lib/character-reference/index.d.ts +0 -12
  452. package/lib/character-reference/meta.d.ts +0 -5
  453. package/lib/character-reference/meta.js +0 -4
  454. package/lib/correct-aspect-ratio/meta.js +0 -3
  455. package/lib/deprecated-attr/index.d.ts +0 -8
  456. package/lib/deprecated-attr/meta.d.ts +0 -5
  457. package/lib/deprecated-attr/meta.js +0 -4
  458. package/lib/deprecated-element/index.d.ts +0 -8
  459. package/lib/deprecated-element/meta.d.ts +0 -5
  460. package/lib/deprecated-element/meta.js +0 -4
  461. package/lib/disallowed-element/index.d.ts +0 -9
  462. package/lib/disallowed-element/meta.d.ts +0 -5
  463. package/lib/disallowed-element/meta.js +0 -4
  464. package/lib/doctype/index.d.ts +0 -15
  465. package/lib/doctype/meta.d.ts +0 -5
  466. package/lib/doctype/meta.js +0 -4
  467. package/lib/end-tag/index.d.ts +0 -9
  468. package/lib/end-tag/meta.d.ts +0 -5
  469. package/lib/end-tag/meta.js +0 -4
  470. package/lib/heading-levels/index.d.ts +0 -8
  471. package/lib/heading-levels/meta.d.ts +0 -5
  472. package/lib/heading-levels/meta.js +0 -4
  473. package/lib/id-duplication/index.d.ts +0 -9
  474. package/lib/id-duplication/meta.d.ts +0 -5
  475. package/lib/id-duplication/meta.js +0 -4
  476. package/lib/ineffective-attr/index.d.ts +0 -9
  477. package/lib/ineffective-attr/meta.d.ts +0 -6
  478. package/lib/ineffective-attr/meta.js +0 -5
  479. package/lib/invalid-attr/index.js +0 -207
  480. package/lib/invalid-attr/meta.d.ts +0 -5
  481. package/lib/invalid-attr/meta.js +0 -4
  482. package/lib/landmark-roles/index.d.ts +0 -22
  483. package/lib/landmark-roles/index.js +0 -142
  484. package/lib/landmark-roles/meta.d.ts +0 -5
  485. package/lib/landmark-roles/meta.js +0 -4
  486. package/lib/neighbor-popovers/index.d.ts +0 -10
  487. package/lib/neighbor-popovers/meta.d.ts +0 -5
  488. package/lib/neighbor-popovers/meta.js +0 -4
  489. package/lib/no-hard-code-id/index.d.ts +0 -10
  490. package/lib/no-hard-code-id/meta.d.ts +0 -5
  491. package/lib/no-hard-code-id/meta.js +0 -4
  492. package/lib/no-unsupported-features/index.js +0 -139
  493. package/lib/no-unsupported-features/meta.d.ts +0 -5
  494. package/lib/no-unsupported-features/meta.js +0 -4
  495. package/lib/no-use-event-handler-attr/index.d.ts +0 -18
  496. package/lib/no-use-event-handler-attr/meta.d.ts +0 -5
  497. package/lib/no-use-event-handler-attr/meta.js +0 -4
  498. package/lib/redundant-accessible-name/meta.d.ts +0 -5
  499. package/lib/redundant-accessible-name/meta.js +0 -4
  500. package/lib/required-attr/meta.d.ts +0 -5
  501. package/lib/required-attr/meta.js +0 -4
  502. package/lib/required-element/meta.d.ts +0 -5
  503. package/lib/required-element/meta.js +0 -4
  504. package/lib/required-h1/index.d.ts +0 -18
  505. package/lib/required-h1/meta.d.ts +0 -5
  506. package/lib/required-h1/meta.js +0 -4
  507. package/lib/srcset-sizes-constraint/index.d.ts +0 -6
  508. package/lib/srcset-sizes-constraint/index.js +0 -108
  509. package/lib/srcset-sizes-constraint/meta.d.ts +0 -5
  510. package/lib/srcset-sizes-constraint/meta.js +0 -4
  511. package/lib/table-row-column-alignment/index.d.ts +0 -10
  512. package/lib/table-row-column-alignment/index.js +0 -97
  513. package/lib/table-row-column-alignment/meta.d.ts +0 -5
  514. package/lib/table-row-column-alignment/meta.js +0 -4
  515. package/lib/use-list/meta.d.ts +0 -5
  516. package/lib/use-list/meta.js +0 -4
  517. package/lib/wai-aria/checkings/disallowed-prop.d.ts +0 -23
  518. package/lib/wai-aria/checkings/disallowed-prop.js +0 -84
  519. package/lib/wai-aria/checkings/implicit-props.d.ts +0 -20
  520. package/lib/wai-aria/index.d.ts +0 -13
  521. package/lib/wai-aria/index.js +0 -115
  522. package/lib/wai-aria/meta.d.ts +0 -5
  523. package/lib/wai-aria/meta.js +0 -4
  524. package/lib/wai-aria-default-value/index.d.ts +0 -4
  525. package/lib/wai-aria-default-value/meta.d.ts +0 -5
  526. package/lib/wai-aria-default-value/meta.js +0 -4
  527. package/lib/wai-aria-deprecated-props/index.d.ts +0 -4
  528. package/lib/wai-aria-deprecated-props/meta.d.ts +0 -5
  529. package/lib/wai-aria-deprecated-props/meta.js +0 -4
  530. package/lib/wai-aria-disallowed-props/index.d.ts +0 -4
  531. package/lib/wai-aria-disallowed-props/meta.d.ts +0 -5
  532. package/lib/wai-aria-disallowed-props/meta.js +0 -4
  533. package/lib/wai-aria-implicit-props/index.d.ts +0 -4
  534. package/lib/wai-aria-implicit-props/meta.d.ts +0 -5
  535. package/lib/wai-aria-implicit-props/meta.js +0 -4
  536. package/lib/wai-aria-implicit-role/index.d.ts +0 -4
  537. package/lib/wai-aria-interaction-in-hidden/index.d.ts +0 -4
  538. package/lib/wai-aria-interaction-in-hidden/meta.d.ts +0 -5
  539. package/lib/wai-aria-interaction-in-hidden/meta.js +0 -4
  540. package/lib/wai-aria-no-global-prop/index.d.ts +0 -4
  541. package/lib/wai-aria-no-global-prop/meta.d.ts +0 -5
  542. package/lib/wai-aria-no-global-prop/meta.js +0 -4
  543. package/lib/wai-aria-non-existent-role/index.d.ts +0 -4
  544. package/lib/wai-aria-permitted-roles/index.d.ts +0 -4
  545. package/lib/wai-aria-presentational-children/index.d.ts +0 -4
  546. package/lib/wai-aria-presentational-children/meta.d.ts +0 -5
  547. package/lib/wai-aria-presentational-children/meta.js +0 -4
  548. package/lib/wai-aria-required-parent-role/index.d.ts +0 -4
  549. package/lib/wai-aria-value/index.d.ts +0 -4
  550. package/lib/wai-aria-value/meta.d.ts +0 -5
  551. package/lib/wai-aria-value/meta.js +0 -4
  552. /package/lib/{wai-aria-abstract-role → aria-prop-requires-role}/meta.d.ts +0 -0
  553. /package/lib/{wai-aria-abstract-role → aria-prop-requires-role}/meta.js +0 -0
  554. /package/lib/{wai-aria-deprecated-role → element-supports-aria-prop}/meta.d.ts +0 -0
  555. /package/lib/{wai-aria-deprecated-role → element-supports-aria-prop}/meta.js +0 -0
  556. /package/lib/{wai-aria-implicit-role → no-abstract-role}/meta.d.ts +0 -0
  557. /package/lib/{wai-aria-implicit-role → no-abstract-role}/meta.js +0 -0
  558. /package/lib/{wai-aria-non-existent-role → no-aria-on-presentational-children}/meta.d.ts +0 -0
  559. /package/lib/{wai-aria-non-existent-role → no-aria-on-presentational-children}/meta.js +0 -0
  560. /package/lib/{wai-aria-permitted-roles → no-contradictory-aria-prop}/meta.d.ts +0 -0
  561. /package/lib/{wai-aria-permitted-roles → no-contradictory-aria-prop}/meta.js +0 -0
  562. /package/lib/{wai-aria-required-owned-elements → no-default-aria-value}/meta.d.ts +0 -0
  563. /package/lib/{wai-aria-required-owned-elements → no-default-aria-value}/meta.js +0 -0
  564. /package/lib/{wai-aria-required-parent-role → no-deprecated-aria-prop}/meta.d.ts +0 -0
  565. /package/lib/{wai-aria-required-parent-role → no-deprecated-aria-prop}/meta.js +0 -0
  566. /package/lib/{wai-aria-required-props → no-deprecated-role}/meta.d.ts +0 -0
  567. /package/lib/{wai-aria-required-props → no-deprecated-role}/meta.js +0 -0
  568. /package/lib/{correct-aspect-ratio → no-mismatched-aspect-ratio}/index.d.ts +0 -0
  569. /package/lib/{correct-aspect-ratio → no-mismatched-aspect-ratio}/resolve-image-size.d.ts +0 -0
  570. /package/lib/{no-unsupported-features → no-unsupported-browser-features}/compat-data.d.ts +0 -0
  571. /package/lib/{no-unsupported-features → no-unsupported-browser-features}/compat-data.js +0 -0
  572. /package/lib/{no-unsupported-features → no-unsupported-browser-features}/resolve-browsers.d.ts +0 -0
  573. /package/lib/{no-unsupported-features → no-unsupported-browser-features}/resolve-browsers.js +0 -0
@@ -0,0 +1,69 @@
1
+ import { createRule } from '@markuplint/ml-core';
2
+ import { findChildren } from '../table-row-column-alignment/find-children.js';
3
+ import { Grid, getIndexes } from '../table-row-column-alignment/grid.js';
4
+ import meta from './meta.js';
5
+ /**
6
+ * Flags rows whose width disagrees with the table's base column count.
7
+ *
8
+ * Unlike the sibling splits of `table-row-column-alignment`, this is not a table model error:
9
+ * HTML LS §4.9.12.1 Step 7 grows `xwidth` to fit a wider row, and a narrower row is only a table
10
+ * model error where {@link import('../no-empty-table-track/index.js')} already catches it (a
11
+ * column no cell ever anchors to). A ragged table is nevertheless almost always a mistake, which
12
+ * is why this check exists and why it stays a `warning` rather than the `error` of its siblings.
13
+ *
14
+ * Skips a table that `no-table-cell-overlap` already reports on — once two cells claim the same
15
+ * slot, row widths derived from the grid model are no longer reliable.
16
+ */
17
+ export default createRule({
18
+ meta,
19
+ defaultSeverity: 'warning',
20
+ verify({ document, report, t }) {
21
+ const tables = document.querySelectorAll('table');
22
+ for (const table of tables) {
23
+ const grid = new Grid(table);
24
+ if (grid.hasOverlapped()) {
25
+ continue;
26
+ }
27
+ const baseColLength = grid.getBaseColLength();
28
+ for (const row of grid.getRows()) {
29
+ if (row.anchorCount === 0) {
30
+ continue;
31
+ }
32
+ const colLength = row.slots.length;
33
+ if (colLength === baseColLength) {
34
+ continue;
35
+ }
36
+ const indexes = getIndexes(row.slots);
37
+ const cells = findChildren(row.element, 'th, td');
38
+ if (colLength > baseColLength) {
39
+ const index = indexes.slice(baseColLength)[0];
40
+ const unexpected = typeof index === 'number' ? cells[index] : null;
41
+ if (!unexpected) {
42
+ // The overshoot starts inside a spanned cell, so the `colspan` is the culprit.
43
+ const spanStart = cells.findLast(cell => Number.parseInt(cell.getAttribute('colspan') ?? '1') > 1);
44
+ const colSpan = spanStart?.getAttributeNode('colspan');
45
+ if (!colSpan) {
46
+ continue;
47
+ }
48
+ report({
49
+ scope: colSpan,
50
+ message: t('Exceeds the number of available {0}', 'columns'),
51
+ });
52
+ continue;
53
+ }
54
+ const diff = colLength - baseColLength;
55
+ report({
56
+ scope: unexpected,
57
+ message: t('{0} extra {1} in {2}', t(`${diff}`), t(diff === 1 ? 'column' : 'columns'), t('a {0}', t('row'))),
58
+ });
59
+ continue;
60
+ }
61
+ const diff = baseColLength - colLength;
62
+ report({
63
+ scope: row.element,
64
+ message: t('{0} missing {1} in {2}', t(`${diff}`), t(diff === 1 ? 'column' : 'columns'), t('a {0}', t('row'))),
65
+ });
66
+ }
67
+ }
68
+ },
69
+ });
@@ -0,0 +1,4 @@
1
+ declare const _default: {
2
+ readonly category: "structure";
3
+ };
4
+ export default _default;
@@ -0,0 +1,3 @@
1
+ export default {
2
+ category: 'structure',
3
+ };
@@ -2,32 +2,9 @@ import type { Translator } from '@markuplint/i18n';
2
2
  import type { AttributeType } from '@markuplint/ml-spec';
3
3
  import type { UnmatchedResult, Type } from '@markuplint/types';
4
4
  import type { ReadonlyDeep } from 'type-fest';
5
- /**
6
- * Builds a human-readable error message explaining why an attribute value
7
- * does not match its expected type. Handles both plain types and list types
8
- * (space-separated or comma-separated).
9
- *
10
- * @param t - The i18n translator for generating localized messages
11
- * @param baseTarget - A human-readable description of the attribute being validated
12
- * (e.g. `'the "href" attribute'`)
13
- * @param type - The attribute type definition that the value was validated against
14
- * @param matches - The result object from a failed type check, containing
15
- * details about the mismatch (reason, candidate, part name, etc.)
16
- * @returns A localized error message describing the expected value
17
- */
18
5
  export declare function createMessageValueExpected(t: Translator, baseTarget: string, type: ReadonlyDeep<AttributeType | Type>, matches: UnmatchedResult): string;
19
6
  /**
20
- * Assembles the detailed portion of a value-expected error message by
21
- * inspecting the mismatch reason and composing reason, expectation,
22
- * candidate suggestion, and fallback parts into a single string.
23
- *
24
- * This is an internal helper exposed for testing and advanced use.
25
- * The double-underscore prefix indicates it is not part of the stable public API.
26
- *
27
- * @param t - The i18n translator for generating localized messages
28
- * @param baseTarget - A human-readable description of the validation target
29
- * @param expected - A description of the expected value(s), or `null` if unknown
30
- * @param matches - Partial match result containing reason, candidate, and other details
31
- * @returns A localized error message string
7
+ * The double-underscore prefix marks this as exposed only for testing — not
8
+ * part of the stable public API.
32
9
  */
33
10
  export declare function __createMessageValueExpected(t: Translator, baseTarget: string, expected: string | null, matches: Pick<UnmatchedResult, 'partName' | 'reason' | 'raw' | 'candidate' | 'ref' | 'extra' | 'fallbackTo'>): string;
@@ -1,17 +1,4 @@
1
1
  import { isList, isKeyword, isEnum, isNumber, isDirective, isPattern } from '@markuplint/types';
2
- /**
3
- * Builds a human-readable error message explaining why an attribute value
4
- * does not match its expected type. Handles both plain types and list types
5
- * (space-separated or comma-separated).
6
- *
7
- * @param t - The i18n translator for generating localized messages
8
- * @param baseTarget - A human-readable description of the attribute being validated
9
- * (e.g. `'the "href" attribute'`)
10
- * @param type - The attribute type definition that the value was validated against
11
- * @param matches - The result object from a failed type check, containing
12
- * details about the mismatch (reason, candidate, part name, etc.)
13
- * @returns A localized error message describing the expected value
14
- */
15
2
  export function createMessageValueExpected(t, baseTarget, type, matches) {
16
3
  let target = baseTarget;
17
4
  let listDescriptionPart;
@@ -31,18 +18,8 @@ export function createMessageValueExpected(t, baseTarget, type, matches) {
31
18
  return message;
32
19
  }
33
20
  /**
34
- * Assembles the detailed portion of a value-expected error message by
35
- * inspecting the mismatch reason and composing reason, expectation,
36
- * candidate suggestion, and fallback parts into a single string.
37
- *
38
- * This is an internal helper exposed for testing and advanced use.
39
- * The double-underscore prefix indicates it is not part of the stable public API.
40
- *
41
- * @param t - The i18n translator for generating localized messages
42
- * @param baseTarget - A human-readable description of the validation target
43
- * @param expected - A description of the expected value(s), or `null` if unknown
44
- * @param matches - Partial match result containing reason, candidate, and other details
45
- * @returns A localized error message string
21
+ * The double-underscore prefix marks this as exposed only for testing — not
22
+ * part of the stable public API.
46
23
  */
47
24
  export function __createMessageValueExpected(t, baseTarget, expected, matches) {
48
25
  let target = baseTarget;
@@ -226,17 +203,6 @@ export function __createMessageValueExpected(t, baseTarget, expected, matches) {
226
203
  }
227
204
  return message;
228
205
  }
229
- /**
230
- * Derives a human-readable description of the expected value from an attribute
231
- * type definition and the unmatched result. Inspects keywords, enums, numbers,
232
- * directives, and explicit `expects` entries from the match result.
233
- *
234
- * @param type - The attribute type (excluding list wrappers)
235
- * @param matches - The unmatched result containing optional `expects` hints
236
- * @param t - The i18n translator
237
- * @returns A localized string describing the expected value(s), or `null` if
238
- * no expectation can be determined
239
- */
240
206
  function createExpectedObject(type, matches, t) {
241
207
  const expectedObject = [];
242
208
  if (matches.expects && matches.expects.length > 0) {
@@ -268,14 +234,6 @@ function createExpectedObject(type, matches, t) {
268
234
  : (expectedObject[0] ?? null);
269
235
  return expects;
270
236
  }
271
- /**
272
- * Converts a single `Expect` descriptor into a human-readable word or phrase.
273
- *
274
- * @param t - The i18n translator
275
- * @param expect - The expectation descriptor from a type-check result
276
- * @param type - The attribute type context for determining phrasing (e.g. CSS syntax)
277
- * @returns A localized word or phrase describing the expected value
278
- */
279
237
  function expectValueToWord(t, expect, type) {
280
238
  switch (expect.type) {
281
239
  case 'common': {
@@ -298,15 +256,6 @@ function expectValueToWord(t, expect, type) {
298
256
  }
299
257
  }
300
258
  }
301
- /**
302
- * Builds a human-readable description of an expected numeric range
303
- * from a `Number` type definition (e.g. "integer greater than or equal to 0").
304
- *
305
- * @param t - The i18n translator
306
- * @param type - The number type definition containing range constraints
307
- * (`gt`, `gte`, `lt`, `lte`) and the numeric type label
308
- * @returns A localized description of the expected numeric range
309
- */
310
259
  function createExpectedNumber(t, type) {
311
260
  if (type.gt != null) {
312
261
  if (type.lt != null) {
package/lib/debug.d.ts CHANGED
@@ -1,12 +1,4 @@
1
1
  import debug from 'debug';
2
- /**
3
- * Type alias for the debug logger function provided by the `debug` package.
4
- * Used throughout the rules package for conditional diagnostic logging.
5
- */
6
2
  export type Log = debug.Debugger;
7
- /**
8
- * Shared debug logger instance for the `@markuplint/rules` package.
9
- * Enable by setting the `DEBUG` environment variable to include `ml-rules`
10
- * (e.g. `DEBUG=ml-rules`).
11
- */
3
+ /** Enable by setting `DEBUG` to include `ml-rules` (e.g. `DEBUG=ml-rules`). */
12
4
  export declare const log: debug.Debugger;
package/lib/debug.js CHANGED
@@ -1,7 +1,3 @@
1
1
  import debug from 'debug';
2
- /**
3
- * Shared debug logger instance for the `@markuplint/rules` package.
4
- * Enable by setting the `DEBUG` environment variable to include `ml-rules`
5
- * (e.g. `DEBUG=ml-rules`).
6
- */
2
+ /** Enable by setting `DEBUG` to include `ml-rules` (e.g. `DEBUG=ml-rules`). */
7
3
  export const log = debug('ml-rules');
@@ -0,0 +1,12 @@
1
+ import type { Options } from '../wai-aria/types.js';
2
+ /**
3
+ * Split from the former `wai-aria-disallowed-props` rule (#3989): the ARIA in
4
+ * HTML element-specific `aria-*` restrictions alone. See
5
+ * `checkingElementSupportsAriaProp`'s JSDoc for the full spec citation.
6
+ *
7
+ * The former rule's `disallowSetImplicitProps` option gated this check; the
8
+ * split rule has no such option — disabling this rule entirely is how users
9
+ * opt out.
10
+ */
11
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Options>>;
12
+ export default _default;
@@ -0,0 +1,38 @@
1
+ import { createRule, getComputedRole, ariaSpecs, getSpec } from '@markuplint/ml-core';
2
+ import { ARIA_RECOMMENDED_VERSION } from '@markuplint/ml-spec';
3
+ import { checkingElementSupportsAriaProp } from '../wai-aria/checkings/element-supports-aria-prop.js';
4
+ import { defaultOptions } from '../wai-aria/default-options.js';
5
+ import meta from './meta.js';
6
+ /**
7
+ * Split from the former `wai-aria-disallowed-props` rule (#3989): the ARIA in
8
+ * HTML element-specific `aria-*` restrictions alone. See
9
+ * `checkingElementSupportsAriaProp`'s JSDoc for the full spec citation.
10
+ *
11
+ * The former rule's `disallowSetImplicitProps` option gated this check; the
12
+ * split rule has no such option — disabling this rule entirely is how users
13
+ * opt out.
14
+ */
15
+ export default createRule({
16
+ meta,
17
+ defaultOptions,
18
+ async verify({ document, report }) {
19
+ await document.walkOn('Element', el => {
20
+ const elSpec = getSpec(el, document.specs.specs);
21
+ // Autonomous custom elements have no spec.<el>.jsonc entry and no
22
+ // element-specific restriction to enforce here.
23
+ if (!elSpec)
24
+ return;
25
+ if (!elSpec.globalAttrs['#ARIAAttrs'])
26
+ return;
27
+ const propAttrs = el.attributes.filter(attr => /^aria-/i.test(attr.name));
28
+ if (propAttrs.length === 0)
29
+ return;
30
+ const ariaVersion = el.rule.options?.version ?? document.ruleCommonSettings?.ariaVersion ?? ARIA_RECOMMENDED_VERSION;
31
+ const computed = getComputedRole(document.specs, el, ariaVersion);
32
+ const { props: propSpecs } = ariaSpecs(document.specs, ariaVersion);
33
+ for (const attr of propAttrs) {
34
+ report(checkingElementSupportsAriaProp({ attr, role: computed.role, propSpecs }));
35
+ }
36
+ });
37
+ },
38
+ });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Require the `form` attribute on a form-associated element to reference
3
+ * an actual `<form>` element by ID. Per HTML LS §4.10.18.6: "If
4
+ * specified, the value must be the ID of a form element in the
5
+ * element's tree." Existence of the ID itself is the responsibility of
6
+ * `no-refer-to-non-existent-id`; this rule only checks the element type
7
+ * when the ID resolves.
8
+ *
9
+ * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form
10
+ */
11
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, null>>;
12
+ export default _default;
@@ -0,0 +1,64 @@
1
+ import { createRule } from '@markuplint/ml-core';
2
+ import meta from './meta.js';
3
+ /**
4
+ * Form-associated elements (HTML LS §4.10.2). Listed elements may carry
5
+ * a `form` attribute that explicitly associates them with a `<form>`
6
+ * element; the implicit ancestor-based association is otherwise used.
7
+ *
8
+ * @see https://html.spec.whatwg.org/multipage/forms.html#category-listed
9
+ */
10
+ const FORM_ASSOCIATED_SELECTOR = [
11
+ 'button',
12
+ 'fieldset',
13
+ 'input',
14
+ 'label',
15
+ 'meter',
16
+ 'object',
17
+ 'output',
18
+ 'progress',
19
+ 'select',
20
+ 'textarea',
21
+ ].join(',');
22
+ /**
23
+ * Require the `form` attribute on a form-associated element to reference
24
+ * an actual `<form>` element by ID. Per HTML LS §4.10.18.6: "If
25
+ * specified, the value must be the ID of a form element in the
26
+ * element's tree." Existence of the ID itself is the responsibility of
27
+ * `no-refer-to-non-existent-id`; this rule only checks the element type
28
+ * when the ID resolves.
29
+ *
30
+ * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form
31
+ */
32
+ export default createRule({
33
+ meta: meta,
34
+ defaultValue: true,
35
+ defaultOptions: null,
36
+ async verify({ document, report, t }) {
37
+ await document.walkOn('Element', el => {
38
+ if (!el.matches(FORM_ASSOCIATED_SELECTOR))
39
+ return;
40
+ if (el.pretenderContext?.type === 'pretender' && !el.hasAttribute('as'))
41
+ return;
42
+ const formAttr = el.getAttributeNode('form');
43
+ if (!formAttr)
44
+ return;
45
+ if (formAttr.isDynamicValue)
46
+ return;
47
+ const targetId = formAttr.value;
48
+ const target = [...document.querySelectorAll('[id]')].find(candidate => candidate.getAttribute('id') === targetId);
49
+ // Existence is checked by `no-refer-to-non-existent-id`. If the ID does not resolve
50
+ // here, leave that diagnostic to the dedicated rule and stay silent.
51
+ if (!target)
52
+ return;
53
+ if (target.localName !== 'form') {
54
+ report({
55
+ scope: formAttr,
56
+ line: formAttr.valueNode?.startLine,
57
+ col: formAttr.valueNode?.startCol,
58
+ raw: formAttr.valueNode?.raw,
59
+ message: t('The "{0}" attribute on a form-associated element must reference a "{1}" element', 'form', 'form'),
60
+ });
61
+ }
62
+ });
63
+ },
64
+ });
@@ -1,4 +1,4 @@
1
1
  declare const _default: {
2
- readonly category: "validation";
2
+ readonly category: "references";
3
3
  };
4
4
  export default _default;
@@ -0,0 +1,3 @@
1
+ export default {
2
+ category: 'references',
3
+ };
@@ -1,5 +1,5 @@
1
1
  declare const _default: {
2
- readonly category: "style";
2
+ readonly category: "structure";
3
3
  readonly fixable: true;
4
4
  };
5
5
  export default _default;
@@ -1,4 +1,4 @@
1
1
  export default {
2
- category: 'style',
2
+ category: 'structure',
3
3
  fixable: true,
4
4
  };
package/lib/helpers.d.ts CHANGED
@@ -1,30 +1,16 @@
1
- import type { Log } from './debug.js';
2
- import type { Translator } from '@markuplint/i18n';
3
1
  import type { FixToken, IRuleFixer, PlainData, TextEdit } from '@markuplint/ml-config';
4
2
  import type { Element, RuleConfigValue, Document } from '@markuplint/ml-core';
5
3
  import type { Attribute } from '@markuplint/ml-spec';
6
4
  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
- */
5
+ /** A `null`/`undefined` condition means the attribute applies unconditionally. */
18
6
  export declare function attrMatches<T extends RuleConfigValue, O extends PlainData>(node: Element<T, O>, condition: Attribute['condition']): boolean;
19
7
  /**
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
8
+ * Conditions are evaluated against literal attribute values, so when a referenced
9
+ * attribute's value is dynamic (template-interpolated) the condition result is
10
+ * indeterminate and must not be used to report a violation.
27
11
  */
12
+ export declare function conditionDependsOnDynamicAttr<T extends RuleConfigValue, O extends PlainData>(node: Element<T, O>, condition: NonNullable<Attribute['condition']>): boolean;
13
+ /** `pattern` is a regex literal of the form `/pattern/flags` if it matches that shape, otherwise an exact string. */
28
14
  export declare function match(needle: string, pattern: string): boolean;
29
15
  /**
30
16
  * PotentialCustomElementName
@@ -42,127 +28,20 @@ export declare function match(needle: string, pattern: string): boolean;
42
28
  * 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.
43
29
  */
44
30
  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
- */
61
- export declare function isValidAttr(t: Translator, name: string, value: string, isDynamicValue: boolean, node: Element<any, any>, attrSpecs: readonly Attribute[], log?: Log): false | {
62
- invalidType: "non-existent" | "invalid-value" | "disallowed-attr";
63
- message: string;
64
- loc?: {
65
- raw: string;
66
- line: number;
67
- col: number;
68
- };
69
- } | {
70
- invalidType: "invalid-value";
71
- message: string;
72
- loc?: {
73
- raw: string;
74
- line: number;
75
- col: number;
76
- };
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
- */
88
31
  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
- */
98
32
  export declare function accnameMayBeMutable(el: Element<any, any>, document: Document<any, any>): boolean;
99
33
  export declare const labelable: string[];
100
- /**
101
- * Finds the `<label>` element associated with a labelable form element.
102
- * First checks for an ancestor `<label>`, then looks for a `<label>` whose
103
- * `for` attribute references the element's `id`. Returns `null` if the
104
- * element is not labelable or no associated label is found.
105
- *
106
- * @template V - The rule configuration value type
107
- * @template O - The rule options type
108
- * @param el - The element to find a label for (must be a labelable element)
109
- * @param document - The document to search for labels with a matching `for` attribute
110
- * @returns The associated `<label>` element, or `null` if none is found
111
- */
112
34
  export declare function getOwnedLabel<V extends RuleConfigValue, O extends PlainData>(el: Element<V, O>, document: Document<V, O>): Element<V, O> | null;
113
- /**
114
- * A generic, null-safe collection backed by a `Set`.
115
- * Automatically filters out `null` and `undefined` values when items are added.
116
- * Implements the iterable protocol so it can be used in `for...of` loops.
117
- *
118
- * @template T - The type of items stored in the collection
119
- */
35
+ /** `null`/`undefined` items are silently dropped on add. */
120
36
  export declare class Collection<T> {
121
37
  #private;
122
- /**
123
- * Creates a new collection, optionally pre-populated with the given items.
124
- * Any `null` or `undefined` values are silently ignored.
125
- *
126
- * @param items - Initial items to add to the collection
127
- */
128
38
  constructor(...items: readonly (T | null | undefined)[]);
129
- /**
130
- * Returns an iterator over the items in the collection.
131
- *
132
- * @returns An iterator that yields each item in insertion order
133
- */
134
39
  [Symbol.iterator](): Iterator<T>;
135
- /**
136
- * Adds one or more items to the collection.
137
- * Any `null` or `undefined` values are silently ignored.
138
- *
139
- * @param items - Items to add to the collection
140
- */
141
40
  add(...items: readonly (T | null | undefined)[]): void;
142
- /**
143
- * Returns a frozen array snapshot of the collection's contents.
144
- *
145
- * @returns A read-only array containing all items in insertion order
146
- */
147
41
  toArray(): readonly T[];
148
42
  }
149
- /**
150
- * Creates a deep, writable copy of the given value using structured cloning.
151
- * Strips read-only modifiers from the result type so the clone can be freely mutated.
152
- *
153
- * @template T - The type of the value to clone
154
- * @param value - The value to deep-copy
155
- * @returns A mutable deep clone of the input value
156
- */
43
+ /** Strips read-only modifiers from the result type so the clone can be freely mutated. */
157
44
  export declare function deepCopy<T>(value: T): WritableDeep<T>;
158
- /**
159
- * Creates a fix that removes an entire attribute (name + value + surrounding whitespace).
160
- * Used by rules that need to remove a whole attribute from an element.
161
- *
162
- * @param fixer - The rule fixer instance for building TextEdits
163
- * @param attr - The attribute token parts to remove (from `spacesBeforeName` through `endQuote`)
164
- * @returns A TextEdit (or empty array if no valid tokens exist) that removes the attribute
165
- */
166
45
  export declare function removeAttr(fixer: IRuleFixer, attr: {
167
46
  readonly spacesBeforeName: FixToken | null;
168
47
  readonly nameNode: FixToken | null;
@@ -173,15 +52,6 @@ export declare function removeAttr(fixer: IRuleFixer, attr: {
173
52
  readonly valueNode: FixToken | null;
174
53
  readonly endQuote: FixToken | null;
175
54
  }): TextEdit | TextEdit[];
176
- /**
177
- * Creates a fix that removes only the value portion of an attribute
178
- * (equals sign, quotes, and value), keeping the attribute name.
179
- * Used by `no-boolean-attr-value` to convert `disabled="disabled"` to `disabled`.
180
- *
181
- * @param fixer - The rule fixer instance for building TextEdits
182
- * @param attr - The attribute token parts to remove (from `spacesBeforeEqual` through `endQuote`)
183
- * @returns A TextEdit (or empty array if no valid tokens exist) that removes the value portion
184
- */
185
55
  export declare function removeAttrValue(fixer: IRuleFixer, attr: {
186
56
  readonly spacesBeforeEqual: FixToken | null;
187
57
  readonly equal: FixToken | null;