@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,31 @@
1
+ /**
2
+ * Enforce the descendant-control constraints on a `<label>` element.
3
+ *
4
+ * Per HTML LS §4.10.4 content model: "Phrasing content, but with no
5
+ * descendant labelable elements unless it is the element's labeled
6
+ * control, and no descendant label elements." The labeled control is
7
+ * either the element whose ID equals the `for` attribute (when set to
8
+ * a labelable element in the same tree) or the first labelable
9
+ * descendant in tree order.
10
+ *
11
+ * Two branches follow from that definition:
12
+ *
13
+ * - `for` resolves to an external labelable element → no descendant
14
+ * form control may appear inside the label (the labeled control is
15
+ * outside).
16
+ * - Otherwise → at most one descendant form control; the first in tree
17
+ * order is the labeled control, any subsequent ones are excess.
18
+ *
19
+ * ID existence itself is delegated to `no-refer-to-non-existent-id`;
20
+ * `for` referencing a non-labelable element is delegated to
21
+ * `label-for-references-labelable`. This rule only inspects the label
22
+ * subtree once the target's category has been classified.
23
+ *
24
+ * The `for` target lookup uses `document.querySelectorAll('[id]')` per
25
+ * matching label, not a cached id map. Kept in sync with
26
+ * `label-for-references-labelable` on purpose — the number of `<label>`
27
+ * elements per document is typically small, so a shared id-index would
28
+ * amortize poorly and split rule ownership across a helper module.
29
+ */
30
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, null>>;
31
+ export default _default;
@@ -0,0 +1,104 @@
1
+ import { createRule } from '@markuplint/ml-core';
2
+ import meta from './meta.js';
3
+ /**
4
+ * The HTML LS list of form-control descendants that may appear under a
5
+ * `<label>` element. Per the spec only one of these may exist per label,
6
+ * and only when the label is not already bound to an external labeled
7
+ * control via `for`.
8
+ *
9
+ * @see https://html.spec.whatwg.org/multipage/forms.html#the-label-element
10
+ */
11
+ const FORM_CONTROL_SELECTOR = ['button', 'input', 'meter', 'output', 'progress', 'select', 'textarea'].join(',');
12
+ /**
13
+ * Labelable elements per HTML LS §4.10.2 *Categories: Labelable elements*.
14
+ * The set matches `label-for-references-labelable`; kept in sync to
15
+ * classify the target of `for` consistently across both rules.
16
+ *
17
+ * @see https://html.spec.whatwg.org/multipage/forms.html#category-label
18
+ */
19
+ const LABELABLE_SELECTOR = [
20
+ 'button',
21
+ 'input:not([type="hidden" i])',
22
+ 'meter',
23
+ 'output',
24
+ 'progress',
25
+ 'select',
26
+ 'textarea',
27
+ ].join(',');
28
+ /**
29
+ * Enforce the descendant-control constraints on a `<label>` element.
30
+ *
31
+ * Per HTML LS §4.10.4 content model: "Phrasing content, but with no
32
+ * descendant labelable elements unless it is the element's labeled
33
+ * control, and no descendant label elements." The labeled control is
34
+ * either the element whose ID equals the `for` attribute (when set to
35
+ * a labelable element in the same tree) or the first labelable
36
+ * descendant in tree order.
37
+ *
38
+ * Two branches follow from that definition:
39
+ *
40
+ * - `for` resolves to an external labelable element → no descendant
41
+ * form control may appear inside the label (the labeled control is
42
+ * outside).
43
+ * - Otherwise → at most one descendant form control; the first in tree
44
+ * order is the labeled control, any subsequent ones are excess.
45
+ *
46
+ * ID existence itself is delegated to `no-refer-to-non-existent-id`;
47
+ * `for` referencing a non-labelable element is delegated to
48
+ * `label-for-references-labelable`. This rule only inspects the label
49
+ * subtree once the target's category has been classified.
50
+ *
51
+ * The `for` target lookup uses `document.querySelectorAll('[id]')` per
52
+ * matching label, not a cached id map. Kept in sync with
53
+ * `label-for-references-labelable` on purpose — the number of `<label>`
54
+ * elements per document is typically small, so a shared id-index would
55
+ * amortize poorly and split rule ownership across a helper module.
56
+ */
57
+ export default createRule({
58
+ meta: meta,
59
+ defaultValue: true,
60
+ defaultOptions: null,
61
+ async verify({ document, report, t }) {
62
+ await document.walkOn('Element', el => {
63
+ if (el.localName !== 'label')
64
+ return;
65
+ // Pretender labels have unknown descendants until the `as` attribute pins the type.
66
+ if (el.pretenderContext?.type === 'pretender' && !el.hasAttribute('as'))
67
+ return;
68
+ const controls = [...el.querySelectorAll(FORM_CONTROL_SELECTOR)];
69
+ if (controls.length === 0)
70
+ return;
71
+ const forAttr = el.getAttributeNode('for');
72
+ const hasExternalLabeledControl = (() => {
73
+ if (!forAttr || forAttr.isDynamicValue)
74
+ return false;
75
+ const target = [...document.querySelectorAll('[id]')].find(candidate => candidate.getAttribute('id') === forAttr.value);
76
+ if (!target)
77
+ return false;
78
+ // A descendant with a matching id is still the label's labeled control
79
+ // per the same-tree resolution rule; treat only truly external targets
80
+ // as the external-labeled-control case.
81
+ if (el.contains(target))
82
+ return false;
83
+ return target.matches(LABELABLE_SELECTOR);
84
+ })();
85
+ if (hasExternalLabeledControl) {
86
+ for (const control of controls) {
87
+ report({
88
+ scope: control,
89
+ message: t('The "{0}" element must not contain a form-control descendant when the "{1}" attribute references an external labelable element', 'label', 'for'),
90
+ });
91
+ }
92
+ return;
93
+ }
94
+ if (controls.length <= 1)
95
+ return;
96
+ for (const control of controls.slice(1)) {
97
+ report({
98
+ scope: control,
99
+ message: t('The "{0}" element may contain at most one form-control descendant ({1})', 'label', 'button, input, meter, output, progress, select, or textarea'),
100
+ });
101
+ }
102
+ });
103
+ },
104
+ });
@@ -0,0 +1,4 @@
1
+ declare const _default: {
2
+ readonly category: "forms";
3
+ };
4
+ export default _default;
@@ -0,0 +1,3 @@
1
+ export default {
2
+ category: 'forms',
3
+ };
@@ -0,0 +1,32 @@
1
+ import type { Element } from '@markuplint/ml-core';
2
+ import type { PlainData } from '@markuplint/ml-config';
3
+ /**
4
+ * Shared by the two rules split out of the former `landmark-roles` rule:
5
+ * `no-nested-top-level-landmark` and `require-landmark-label`. Both need the
6
+ * same set of landmark-role elements; only what each rule does with that set
7
+ * differs.
8
+ */
9
+ /** Landmark roles that APG requires to be top-level (not nested in another landmark). */
10
+ export type TopLevelRoles = 'banner' | 'main' | 'contentinfo' | 'complementary';
11
+ /** All recognized ARIA landmark roles for these rules. */
12
+ export type Roles = TopLevelRoles | 'form' | 'navigation' | 'region';
13
+ /** A mapping from each landmark role to its matched elements in the document. */
14
+ export type RoleSet<O extends PlainData> = {
15
+ [role in Roles]: Element<boolean, O>[];
16
+ };
17
+ /**
18
+ * Collects every landmark-role element in the document, keyed by role.
19
+ *
20
+ * @param document - The document to search.
21
+ * @returns The mapping from role to its matched elements.
22
+ */
23
+ export declare function computeLandmarkRoles<O extends PlainData>(document: {
24
+ querySelectorAll(selector: string): Iterable<Element<boolean, O>>;
25
+ }): RoleSet<O>;
26
+ /**
27
+ * Collects all UUIDs of elements that have landmark roles.
28
+ *
29
+ * @param roleset - The mapping of roles to their matched elements.
30
+ * @returns A flat array of UUIDs for all landmark role elements.
31
+ */
32
+ export declare function landmarkRoleElementUUIDList<O extends PlainData>(roleset: RoleSet<O>): string[];
@@ -0,0 +1,73 @@
1
+ /** CSS selectors used to identify elements with each landmark role. */
2
+ const selectors = {
3
+ complementary: ['[role="complementary"]', 'aside'],
4
+ contentinfo: ['[role="contentinfo"]'],
5
+ form: ['[role="form"]', 'form[aria-labelledby]', 'form[aria-label]', 'form[title]'],
6
+ banner: ['[role="banner"]'],
7
+ main: ['[role="main"]', 'main'],
8
+ navigation: ['[role="navigation"]', 'nav'],
9
+ region: ['[role="region"]', 'section[aria-labelledby]', 'section[aria-label]', 'section[title]'],
10
+ };
11
+ /**
12
+ * Collects every landmark-role element in the document, keyed by role.
13
+ *
14
+ * @param document - The document to search.
15
+ * @returns The mapping from role to its matched elements.
16
+ */
17
+ export function computeLandmarkRoles(
18
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
19
+ document) {
20
+ const roles = {
21
+ complementary: [...document.querySelectorAll(selectors.complementary.join(','))],
22
+ contentinfo: [...document.querySelectorAll(selectors.contentinfo.join(','))],
23
+ form: [...document.querySelectorAll(selectors.form.join(','))],
24
+ banner: [...document.querySelectorAll(selectors.banner.join(','))],
25
+ main: [...document.querySelectorAll(selectors.main.join(','))],
26
+ navigation: [...document.querySelectorAll(selectors.navigation.join(','))],
27
+ region: [...document.querySelectorAll(selectors.region.join(','))],
28
+ };
29
+ /**
30
+ * `<header>`
31
+ *
32
+ * @cite https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/
33
+ *
34
+ * > When in context of the body element. The header element is not a banner landmark when it is a descendant of the following HTML sectioning elements:
35
+ * > - article
36
+ * > - aside
37
+ * > - main
38
+ * > - nav
39
+ * > - section
40
+ */
41
+ const headers = [...document.querySelectorAll('header')].filter(header => {
42
+ return !header.closest('article, aside, main, nav, section');
43
+ });
44
+ roles.banner.push(...headers);
45
+ /**
46
+ * `<footer>`
47
+ *
48
+ * @cite https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/
49
+ *
50
+ * > When in context of the body element. The footer element is not a contentinfo landmark when it is a descendant of the following HTML sectioning elements:
51
+ * > - article
52
+ * > - aside
53
+ * > - main
54
+ * > - nav
55
+ * > - section
56
+ */
57
+ const footers = [...document.querySelectorAll('footer')].filter(footer => {
58
+ return !footer.closest('article, aside, main, nav, section');
59
+ });
60
+ roles.contentinfo.push(...footers);
61
+ return roles;
62
+ }
63
+ /**
64
+ * Collects all UUIDs of elements that have landmark roles.
65
+ *
66
+ * @param roleset - The mapping of roles to their matched elements.
67
+ * @returns A flat array of UUIDs for all landmark role elements.
68
+ */
69
+ export function landmarkRoleElementUUIDList(
70
+ // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
71
+ roleset) {
72
+ return Object.values(roleset).flatMap(elements => elements.map(element => element.uuid));
73
+ }
@@ -1,10 +1,5 @@
1
1
  type Options = {
2
2
  readonly allowMicroformats?: boolean | readonly string[];
3
3
  };
4
- /**
5
- * Rule that validates link type keywords in the `rel` attribute on
6
- * `<link>`, `<a>`, `<area>`, and `<form>` elements against the WHATWG
7
- * standard and optionally the Microformats registry.
8
- */
9
4
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Options>>;
10
5
  export default _default;
@@ -2,15 +2,14 @@ import { createRule } from '@markuplint/ml-core';
2
2
  import { DEF_LINK_TYPE_WHATWG, ALLOWED_LINK_TYPE_MICROFORMATS, DEF_LINK_TYPE_MICROFORMATS_DROPPED, DEF_LINK_TYPE_MICROFORMATS_DROPPED_WITHOUT_PREJUDICE, DEF_LINK_TYPE_MICROFORMATS_REJECTED, DEF_LINK_TYPE_MICROFORMATS_NON_HTML_REL_VALUES, } from '@markuplint/types';
3
3
  import meta from './meta.js';
4
4
  const TARGET_ELEMENTS = new Set(['link', 'a', 'area', 'form']);
5
- /**
6
- * Rule that validates link type keywords in the `rel` attribute on
7
- * `<link>`, `<a>`, `<area>`, and `<form>` elements against the WHATWG
8
- * standard and optionally the Microformats registry.
9
- */
10
5
  export default createRule({
11
6
  meta: meta,
7
+ // HTML LS §4.6.6 the rel attribute requires conformance checkers to accept
8
+ // keywords registered on the microformats wiki (proposed or ratified) as
9
+ // extensions to this specification, so accepting them is the spec-conformant
10
+ // default rather than an opt-in.
12
11
  defaultOptions: {
13
- allowMicroformats: false,
12
+ allowMicroformats: true,
14
13
  },
15
14
  async verify({ document, report, t }) {
16
15
  await document.walkOn('Element', el => {
@@ -1,5 +1,4 @@
1
- /** Rule metadata for the `link-types` rule, categorized as validation. */
2
1
  declare const _default: {
3
- readonly category: "validation";
2
+ readonly category: "attributes";
4
3
  };
5
4
  export default _default;
@@ -1,4 +1,3 @@
1
- /** Rule metadata for the `link-types` rule, categorized as validation. */
2
1
  export default {
3
- category: 'validation',
2
+ category: 'attributes',
4
3
  };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Require that a `<map>` element's `id` attribute, when present, has
3
+ * the same value as its `name` attribute. Per HTML LS §4.8.13:
4
+ * "If the id attribute is also specified, both attributes must have
5
+ * the same value."
6
+ *
7
+ * @see https://html.spec.whatwg.org/multipage/image-maps.html#the-map-element
8
+ */
9
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, null>>;
10
+ export default _default;
@@ -0,0 +1,39 @@
1
+ import { createRule } from '@markuplint/ml-core';
2
+ import meta from './meta.js';
3
+ /**
4
+ * Require that a `<map>` element's `id` attribute, when present, has
5
+ * the same value as its `name` attribute. Per HTML LS §4.8.13:
6
+ * "If the id attribute is also specified, both attributes must have
7
+ * the same value."
8
+ *
9
+ * @see https://html.spec.whatwg.org/multipage/image-maps.html#the-map-element
10
+ */
11
+ export default createRule({
12
+ meta: meta,
13
+ defaultValue: true,
14
+ defaultOptions: null,
15
+ async verify({ document, report, t }) {
16
+ await document.walkOn('Element', el => {
17
+ if (el.localName !== 'map')
18
+ return;
19
+ // Pretender maps with no `as` pin: attributes are unknown until typed.
20
+ if (el.pretenderContext?.type === 'pretender' && !el.hasAttribute('as'))
21
+ return;
22
+ const idAttr = el.getAttributeNode('id');
23
+ const nameAttr = el.getAttributeNode('name');
24
+ if (!idAttr || !nameAttr)
25
+ return;
26
+ if (idAttr.isDynamicValue || nameAttr.isDynamicValue)
27
+ return;
28
+ if (idAttr.value === nameAttr.value)
29
+ return;
30
+ report({
31
+ scope: idAttr,
32
+ line: idAttr.valueNode?.startLine,
33
+ col: idAttr.valueNode?.startCol,
34
+ raw: idAttr.valueNode?.raw,
35
+ message: t('The "{0}" attribute on a "{1}" element must have the same value as the "{2}" attribute', 'id', 'map', 'name'),
36
+ });
37
+ });
38
+ },
39
+ });
@@ -0,0 +1,4 @@
1
+ declare const _default: {
2
+ readonly category: "attributes";
3
+ };
4
+ export default _default;
@@ -0,0 +1,3 @@
1
+ export default {
2
+ category: 'attributes',
3
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * HTML LS §4.2.5.4 Specifying the document's character encoding:
3
+ *
4
+ * > The element containing the character encoding declaration must be
5
+ * > serialized completely within the first 1024 bytes of the document.
6
+ *
7
+ * The limit is a byte count, not a character count — `Buffer.byteLength`
8
+ * measures the UTF-8-encoded prefix rather than `String#length`, so
9
+ * multi-byte characters before the declaration are counted at their actual
10
+ * encoded size.
11
+ *
12
+ * @see https://html.spec.whatwg.org/multipage/semantics.html#charset
13
+ */
14
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, undefined>>;
15
+ export default _default;
@@ -0,0 +1,31 @@
1
+ import { createRule } from '@markuplint/ml-core';
2
+ import meta from './meta.js';
3
+ const BYTE_LIMIT = 1024;
4
+ /**
5
+ * HTML LS §4.2.5.4 Specifying the document's character encoding:
6
+ *
7
+ * > The element containing the character encoding declaration must be
8
+ * > serialized completely within the first 1024 bytes of the document.
9
+ *
10
+ * The limit is a byte count, not a character count — `Buffer.byteLength`
11
+ * measures the UTF-8-encoded prefix rather than `String#length`, so
12
+ * multi-byte characters before the declaration are counted at their actual
13
+ * encoded size.
14
+ *
15
+ * @see https://html.spec.whatwg.org/multipage/semantics.html#charset
16
+ */
17
+ export default createRule({
18
+ meta: meta,
19
+ verify({ document, report, t }) {
20
+ const declarations = document.querySelectorAll('meta[charset], meta[http-equiv="content-type" i]');
21
+ for (const el of declarations) {
22
+ const byteOffset = Buffer.byteLength(document.raw.slice(0, el.startOffset), 'utf8');
23
+ if (byteOffset < BYTE_LIMIT)
24
+ continue;
25
+ report({
26
+ scope: el,
27
+ message: t('The character encoding declaration must be within the first {0} bytes of the document', String(BYTE_LIMIT)),
28
+ });
29
+ }
30
+ },
31
+ });
@@ -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
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Enforce HTML LS §4.10.14 inequalities for `<meter>`:
3
+ * minimum ≤ value ≤ maximum, plus minimum ≤ low/high/optimum ≤ maximum
4
+ * and low ≤ high when both are specified. Defaults: min=0, max=1,
5
+ * value=min.
6
+ *
7
+ * @see https://html.spec.whatwg.org/multipage/form-elements.html#the-meter-element
8
+ */
9
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, null>>;
10
+ export default _default;
@@ -0,0 +1,123 @@
1
+ import { createRule } from '@markuplint/ml-core';
2
+ import meta from './meta.js';
3
+ const DEFAULT_MIN = 0;
4
+ const DEFAULT_MAX = 1;
5
+ function parseFloatAttr(raw) {
6
+ if (raw === undefined)
7
+ return null;
8
+ const trimmed = raw.trim();
9
+ if (trimmed === '')
10
+ return null;
11
+ const n = Number(trimmed);
12
+ return Number.isFinite(n) ? n : null;
13
+ }
14
+ /**
15
+ * Enforce HTML LS §4.10.14 inequalities for `<meter>`:
16
+ * minimum ≤ value ≤ maximum, plus minimum ≤ low/high/optimum ≤ maximum
17
+ * and low ≤ high when both are specified. Defaults: min=0, max=1,
18
+ * value=min.
19
+ *
20
+ * @see https://html.spec.whatwg.org/multipage/form-elements.html#the-meter-element
21
+ */
22
+ export default createRule({
23
+ meta: meta,
24
+ defaultValue: true,
25
+ defaultOptions: null,
26
+ async verify({ document, report, t }) {
27
+ await document.walkOn('Element', el => {
28
+ if (el.localName !== 'meter')
29
+ return;
30
+ // Pretender meters with no `as` pin: descendants/attributes are unknown until typed.
31
+ if (el.pretenderContext?.type === 'pretender' && !el.hasAttribute('as'))
32
+ return;
33
+ const valueAttr = el.getAttributeNode('value');
34
+ const minAttr = el.getAttributeNode('min');
35
+ const maxAttr = el.getAttributeNode('max');
36
+ const lowAttr = el.getAttributeNode('low');
37
+ const highAttr = el.getAttributeNode('high');
38
+ const optimumAttr = el.getAttributeNode('optimum');
39
+ if (valueAttr?.isDynamicValue ||
40
+ minAttr?.isDynamicValue ||
41
+ maxAttr?.isDynamicValue ||
42
+ lowAttr?.isDynamicValue ||
43
+ highAttr?.isDynamicValue ||
44
+ optimumAttr?.isDynamicValue) {
45
+ return;
46
+ }
47
+ const valueNum = parseFloatAttr(valueAttr?.value);
48
+ const minNum = parseFloatAttr(minAttr?.value);
49
+ const maxNum = parseFloatAttr(maxAttr?.value);
50
+ const lowNum = parseFloatAttr(lowAttr?.value);
51
+ const highNum = parseFloatAttr(highAttr?.value);
52
+ const optimumNum = parseFloatAttr(optimumAttr?.value);
53
+ // Authored-but-unparsable values are reported by `no-invalid-attr-value`; skip the bounds
54
+ // check entirely so we don't compound the diagnostic noise.
55
+ if ((valueAttr && valueNum === null) ||
56
+ (minAttr && minNum === null) ||
57
+ (maxAttr && maxNum === null) ||
58
+ (lowAttr && lowNum === null) ||
59
+ (highAttr && highNum === null) ||
60
+ (optimumAttr && optimumNum === null)) {
61
+ return;
62
+ }
63
+ const minValue = minNum ?? DEFAULT_MIN;
64
+ const maxValue = maxNum ?? DEFAULT_MAX;
65
+ const valueValue = valueNum ?? minValue;
66
+ const reportLE = (lowerName, lowerAttr, upperName, upperAttr, upperDefault) => {
67
+ const upperDesc = upperAttr
68
+ ? t('the value of the "{0}" attribute', upperName)
69
+ : t('{0} when the "{1}" attribute is absent', upperDefault === 1 ? 'one' : String(upperDefault), upperName);
70
+ const message = t('The value of the "{0}" attribute must be less than or equal to {1}', lowerName, upperDesc);
71
+ const scope = lowerAttr ?? upperAttr;
72
+ if (scope) {
73
+ report({
74
+ scope: scope,
75
+ line: scope.valueNode?.startLine,
76
+ col: scope.valueNode?.startCol,
77
+ raw: scope.valueNode?.raw,
78
+ message: message,
79
+ });
80
+ }
81
+ else {
82
+ report({ scope: el, message: message });
83
+ }
84
+ };
85
+ if (minValue > maxValue) {
86
+ reportLE('min', minAttr, 'max', maxAttr, DEFAULT_MAX);
87
+ }
88
+ if (minValue > valueValue) {
89
+ reportLE('min', minAttr, 'value', valueAttr, DEFAULT_MIN);
90
+ }
91
+ if (valueValue > maxValue) {
92
+ reportLE('value', valueAttr, 'max', maxAttr, DEFAULT_MAX);
93
+ }
94
+ if (lowAttr && lowNum !== null) {
95
+ if (minValue > lowNum) {
96
+ reportLE('min', minAttr, 'low', lowAttr, DEFAULT_MIN);
97
+ }
98
+ if (lowNum > maxValue) {
99
+ reportLE('low', lowAttr, 'max', maxAttr, DEFAULT_MAX);
100
+ }
101
+ }
102
+ if (highAttr && highNum !== null) {
103
+ if (minValue > highNum) {
104
+ reportLE('min', minAttr, 'high', highAttr, DEFAULT_MIN);
105
+ }
106
+ if (highNum > maxValue) {
107
+ reportLE('high', highAttr, 'max', maxAttr, DEFAULT_MAX);
108
+ }
109
+ }
110
+ if (optimumAttr && optimumNum !== null) {
111
+ if (minValue > optimumNum) {
112
+ reportLE('min', minAttr, 'optimum', optimumAttr, DEFAULT_MIN);
113
+ }
114
+ if (optimumNum > maxValue) {
115
+ reportLE('optimum', optimumAttr, 'max', maxAttr, DEFAULT_MAX);
116
+ }
117
+ }
118
+ if (lowAttr && highAttr && lowNum !== null && highNum !== null && lowNum > highNum) {
119
+ reportLE('low', lowAttr, 'high', highAttr, 0);
120
+ }
121
+ });
122
+ },
123
+ });
@@ -0,0 +1,4 @@
1
+ declare const _default: {
2
+ readonly category: "attributes";
3
+ };
4
+ export default _default;
@@ -0,0 +1,3 @@
1
+ export default {
2
+ category: 'attributes',
3
+ };
@@ -1,4 +1,3 @@
1
1
  import type { Options } from '../wai-aria/types.js';
2
- /** Warns when required ARIA properties for a role are missing. */
3
2
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Options>>;
4
3
  export default _default;
@@ -2,7 +2,6 @@ import { createRule, getSpec } from '@markuplint/ml-core';
2
2
  import { checkingAbstractRole } from '../wai-aria/checkings/abstract-role.js';
3
3
  import { defaultOptions } from '../wai-aria/default-options.js';
4
4
  import meta from './meta.js';
5
- /** Warns when an abstract WAI-ARIA role is used directly in content. */
6
5
  export default createRule({
7
6
  meta,
8
7
  defaultOptions,
@@ -0,0 +1,13 @@
1
+ /**
2
+ * HTML LS § the source element: when a `<source>` has a following sibling
3
+ * `<source>` or `<img>` element with a `srcset` attribute specified, it must
4
+ * have a usable `media` and/or `type` attribute, otherwise it "always
5
+ * matches" and shadows the following candidates. Split out of the former
6
+ * `srcset-sizes-constraint` rule's Check 6.
7
+ *
8
+ * Whether the current `<source>` itself has a `srcset` is irrelevant — the
9
+ * requirement is about distinguishing it from what follows, not about its
10
+ * own candidates.
11
+ */
12
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, undefined>>;
13
+ export default _default;