@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
@@ -2,24 +2,6 @@ import { createRule } from '@markuplint/ml-core';
2
2
  import { contentModel } from './content-model.js';
3
3
  import meta from './meta.js';
4
4
  import { transparentMode } from './represent-transparent-nodes.js';
5
- /**
6
- * The `permitted-contents` rule validates that each element's child nodes conform
7
- * to the HTML content model specification. It is the most complex rule in markuplint,
8
- * implementing a full content model validation engine that handles ordered sequences,
9
- * quantified patterns (require, optional, oneOrMore, zeroOrMore), choice alternations,
10
- * transparent content models, and conditional child node branches.
11
- *
12
- * For each element, it resolves the applicable content model (from the HTML spec or
13
- * user-defined tag rules), evaluates the element's children against that model, and
14
- * reports violations such as unexpected elements, missing required elements, or
15
- * disallowed content through transparent models. It also checks forbidden ancestor
16
- * constraints — elements like `<header>`, `<footer>`, `<main>`, and `<address>` must
17
- * not appear as descendants of certain other elements as defined by the HTML spec.
18
- * Additionally, it enforces required ancestor constraints (`descendantOf`) — certain
19
- * elements must appear as descendants of specific other elements. It also validates
20
- * sibling-unique attribute constraints (`uniqueAttrs`) — certain attributes must not
21
- * appear on more than one element of the same type within the same parent.
22
- */
23
5
  export default createRule({
24
6
  meta: meta,
25
7
  defaultValue: [],
@@ -29,66 +11,6 @@ export default createRule({
29
11
  },
30
12
  async verify({ document, report, t }) {
31
13
  await document.walkOn('Element', el => {
32
- // Check forbidden ancestors
33
- const elSpec = document.specs.specs.find(s => s.name === el.localName);
34
- const forbiddenAncestors = elSpec?.contentModel?.forbiddenAncestors;
35
- if (forbiddenAncestors && forbiddenAncestors.length > 0) {
36
- let ancestor = el.parentElement;
37
- while (ancestor) {
38
- if (forbiddenAncestors.some(selector => ancestor.matches(selector))) {
39
- report({
40
- scope: el,
41
- message: t('{0} must not appear as a descendant of {1}', t('the "{0}" {1}', el.localName, 'element'), t('the "{0}" {1}', ancestor.localName, 'element')),
42
- });
43
- break;
44
- }
45
- ancestor = ancestor.parentElement;
46
- }
47
- }
48
- // Check required ancestor (descendantOf)
49
- const descendantOf = elSpec?.contentModel?.descendantOf;
50
- if (descendantOf) {
51
- let ancestor = el.parentElement;
52
- let found = false;
53
- while (ancestor) {
54
- if (ancestor.matches(descendantOf)) {
55
- found = true;
56
- break;
57
- }
58
- ancestor = ancestor.parentElement;
59
- }
60
- if (!found) {
61
- report({
62
- scope: el,
63
- message: t('{0} must appear as a descendant of {1}', t('the "{0}" {1}', el.localName, 'element'), t('the "{0}" {1}', descendantOf, 'element')),
64
- });
65
- }
66
- }
67
- // Check unique attributes among siblings of the same type
68
- const uniqueAttrs = elSpec?.contentModel?.uniqueAttrs;
69
- if (uniqueAttrs && uniqueAttrs.length > 0) {
70
- for (const attrName of uniqueAttrs) {
71
- if (!el.hasAttribute(attrName)) {
72
- continue;
73
- }
74
- const parent = el.parentElement;
75
- if (!parent) {
76
- continue;
77
- }
78
- // Only report on the second (and subsequent) element that has the attribute
79
- const precedingSiblings = [...parent.children];
80
- const elIndex = precedingSiblings.indexOf(el);
81
- const hasPrecedingDuplicate = precedingSiblings
82
- .slice(0, elIndex)
83
- .some(child => child.localName === el.localName && child.hasAttribute(attrName));
84
- if (hasPrecedingDuplicate) {
85
- report({
86
- scope: el,
87
- message: t('The "{0}" attribute must not appear on more than one "{1}" element within the same parent', attrName, el.localName),
88
- });
89
- }
90
- }
91
- }
92
14
  // Build the mode list. `'pretended'` always runs and preserves the historical
93
15
  // behaviour. `'origin'` additionally fires when the element is pretending and
94
16
  // the user has declared a content model keyed on its original AST name, so
@@ -1,5 +1,4 @@
1
- /** Rule metadata for the `permitted-contents` validation rule. */
2
1
  declare const _default: {
3
- readonly category: "validation";
2
+ readonly category: "structure";
4
3
  };
5
4
  export default _default;
@@ -1,4 +1,3 @@
1
- /** Rule metadata for the `permitted-contents` validation rule. */
2
1
  export default {
3
- category: 'validation',
2
+ category: 'structure',
4
3
  };
@@ -1,4 +1,5 @@
1
1
  import { resolveContentModel } from './content-model.js';
2
+ import { cmLog } from './debug.js';
2
3
  import { order } from './order.js';
3
4
  import { Collection, isTransparent, matches } from './utils.js';
4
5
  /**
@@ -155,28 +156,36 @@ childNodes, rules, specs, options, mode) {
155
156
  }
156
157
  branchGroups.push(branchChildren);
157
158
  }
158
- if (branchGroups.every(g => g.length === 0)) {
159
- continue;
160
- }
159
+ // The transparent element itself is still a child of the current parent
160
+ // and must be evaluated against the parent's own content model (e.g., a
161
+ // `<button>` must reject an `<a href>` descendant even though `<a>`'s
162
+ // children are also transparently checked). It is pushed exactly once
163
+ // per resulting pattern below — never once per branch group — so
164
+ // conditional (`v-if`/`v-else`) branches don't multiply it.
165
+ // See https://github.com/markuplint/markuplint/issues/3928
161
166
  if (branchGroups.length === 1) {
162
167
  const singleGroup = branchGroups[0];
163
168
  for (const p of patterns) {
164
- p.push(...singleGroup);
169
+ p.push(childNode, ...singleGroup);
165
170
  }
166
171
  }
167
172
  else if (patterns.length * branchGroups.length <= MAX_PATTERNS) {
168
173
  const newPatterns = [];
169
174
  for (const p of patterns) {
170
175
  for (const group of branchGroups) {
171
- newPatterns.push([...p, ...group]);
176
+ newPatterns.push([...p, childNode, ...group]);
172
177
  }
173
178
  }
174
179
  patterns = newPatterns;
175
180
  }
176
181
  else {
182
+ // Cap exceeded (#3895): fall back to the conservative
183
+ // over-approximation documented on MAX_PATTERNS. False negatives
184
+ // are possible beyond this point, so leave a debug trace.
185
+ cmLog('Transparent pattern cap exceeded on <%s> (%d patterns x %d branches > %d): merging all branch children into every pattern; false negatives are possible', childNode.nodeName, patterns.length, branchGroups.length, MAX_PATTERNS);
177
186
  const allChildren = branchGroups.flat();
178
187
  for (const p of patterns) {
179
- p.push(...allChildren);
188
+ p.push(childNode, ...allChildren);
180
189
  }
181
190
  }
182
191
  }
@@ -0,0 +1,3 @@
1
+ import type { Options } from '../wai-aria/types.js';
2
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Options>>;
3
+ export default _default;
@@ -2,7 +2,6 @@ import { createRule, getSpec } from '@markuplint/ml-core';
2
2
  import { checkingPermittedRoles } from '../wai-aria/checkings/permitted-roles.js';
3
3
  import { defaultOptions } from '../wai-aria/default-options.js';
4
4
  import meta from './meta.js';
5
- /** Warns when a role is not permitted on the element according to ARIA in HTML. */
6
5
  export default createRule({
7
6
  meta,
8
7
  defaultOptions,
@@ -0,0 +1,4 @@
1
+ declare const _default: {
2
+ readonly category: "a11y";
3
+ };
4
+ export default _default;
@@ -0,0 +1,3 @@
1
+ export default {
2
+ category: 'a11y',
3
+ };
@@ -1,9 +1,15 @@
1
1
  /**
2
- * Rule that validates required `<select>` elements have a placeholder label option.
2
+ * HTML LS §4.10.7 The select element:
3
3
  *
4
- * Per the HTML spec, a `<select>` with `required`, without `multiple`, and with a
5
- * display size of 1 must have a placeholder label option (first `<option>` with
6
- * an empty value directly under `<select>`).
4
+ * > If a select element has a required attribute specified, does not have a
5
+ * > multiple attribute specified, and has a display size of 1, then the
6
+ * > select element must have a placeholder label option.
7
+ *
8
+ * `hasPlaceholderLabelOption` decides whether an existing option already
9
+ * satisfies the requirement; `needPlaceholderLabelOption` gates whether the
10
+ * requirement applies to this `<select>`.
11
+ *
12
+ * @see https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element
7
13
  */
8
14
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, undefined>>;
9
15
  export default _default;
@@ -1,11 +1,17 @@
1
1
  import { createRule } from '@markuplint/ml-core';
2
2
  import meta from './meta.js';
3
3
  /**
4
- * Rule that validates required `<select>` elements have a placeholder label option.
4
+ * HTML LS §4.10.7 The select element:
5
5
  *
6
- * Per the HTML spec, a `<select>` with `required`, without `multiple`, and with a
7
- * display size of 1 must have a placeholder label option (first `<option>` with
8
- * an empty value directly under `<select>`).
6
+ * > If a select element has a required attribute specified, does not have a
7
+ * > multiple attribute specified, and has a display size of 1, then the
8
+ * > select element must have a placeholder label option.
9
+ *
10
+ * `hasPlaceholderLabelOption` decides whether an existing option already
11
+ * satisfies the requirement; `needPlaceholderLabelOption` gates whether the
12
+ * requirement applies to this `<select>`.
13
+ *
14
+ * @see https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element
9
15
  */
10
16
  export default createRule({
11
17
  meta: meta,
@@ -25,13 +31,13 @@ export default createRule({
25
31
  },
26
32
  });
27
33
  /**
28
- * Determines whether a `<select>` element requires a placeholder label option.
34
+ * HTML LS §4.10.7 The select element:
29
35
  *
30
- * Per the HTML spec, a select element needs a placeholder label option when it
31
- * has `required`, does not have `multiple`, and has a display size of 1.
36
+ * > If a select element has a required attribute specified, does not have a
37
+ * > multiple attribute specified, and has a display size of 1, then the
38
+ * > select element must have a placeholder label option.
32
39
  *
33
- * @param select - The `<select>` element to evaluate.
34
- * @returns `true` if the select element requires a placeholder label option.
40
+ * @see https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element
35
41
  */
36
42
  function needPlaceholderLabelOption(
37
43
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
@@ -51,13 +57,20 @@ select) {
51
57
  return true;
52
58
  }
53
59
  /**
54
- * Checks whether a `<select>` element already has a valid placeholder label option.
60
+ * HTML LS §4.10.7 The select element placeholder label option definition:
55
61
  *
56
- * A placeholder label option is the first `<option>` whose value is the empty string
57
- * and whose parent is the `<select>` element itself (not an `<optgroup>`).
62
+ * > If a select element has a required attribute specified, and has a
63
+ * > display size of 1; and if the value of the first option element in the
64
+ * > select element's list of options (if any) is the empty string, and that
65
+ * > option element's parent node is the select element (and not an optgroup
66
+ * > element), then that option is the select element's placeholder label
67
+ * > option.
58
68
  *
59
- * @param select - The `<select>` element to check.
60
- * @returns `true` if the element has a valid placeholder label option.
69
+ * The "(if any)" clause requires a first option to exist for the placeholder
70
+ * label option to exist at all; an empty `<select>` therefore has no
71
+ * placeholder label option and must be reported by `verify`.
72
+ *
73
+ * @see https://html.spec.whatwg.org/multipage/form-elements.html#placeholder-label-option
61
74
  */
62
75
  function hasPlaceholderLabelOption(
63
76
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
@@ -75,11 +88,11 @@ select) {
75
88
  if (size !== '1') {
76
89
  return false;
77
90
  }
78
- // > in the select element's list of options (if any) is the empty string
91
+ // > the value of the first option element in the select element's list of options is the empty string
92
+ // No first option → no placeholder label option exists.
79
93
  const firstOption = select.querySelector('option');
80
94
  if (!firstOption) {
81
- // if any
82
- return true;
95
+ return false;
83
96
  }
84
97
  // > that option element's parent node is the select element (and not an optgroup element)
85
98
  if (firstOption.parentElement?.localName === 'optgroup') {
@@ -1,5 +1,4 @@
1
- /** Rule metadata for the `placeholder-label-option` rule, categorized as validation. */
2
1
  declare const _default: {
3
- readonly category: "validation";
2
+ readonly category: "forms";
4
3
  };
5
4
  export default _default;
@@ -1,4 +1,3 @@
1
- /** Rule metadata for the `placeholder-label-option` rule, categorized as validation. */
2
1
  export default {
3
- category: 'validation',
2
+ category: 'forms',
4
3
  };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Enforce HTML LS §4.10.14 inequalities for `<progress>`:
3
+ * `value ≤ max` when both attributes are present, and `value ≤ 1` when
4
+ * `max` is absent. Authored-but-unparsable values, out-of-range `max`
5
+ * (≤ 0), and negative `value` are deferred to `no-invalid-attr-value`.
6
+ *
7
+ * @see https://html.spec.whatwg.org/multipage/form-elements.html#the-progress-element
8
+ */
9
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, null>>;
10
+ export default _default;
@@ -0,0 +1,59 @@
1
+ import { createRule } from '@markuplint/ml-core';
2
+ import meta from './meta.js';
3
+ const DEFAULT_MAX = 1;
4
+ function parseFloatAttr(raw) {
5
+ if (raw === undefined)
6
+ return null;
7
+ const trimmed = raw.trim();
8
+ if (trimmed === '')
9
+ return null;
10
+ const n = Number(trimmed);
11
+ return Number.isFinite(n) ? n : null;
12
+ }
13
+ /**
14
+ * Enforce HTML LS §4.10.14 inequalities for `<progress>`:
15
+ * `value ≤ max` when both attributes are present, and `value ≤ 1` when
16
+ * `max` is absent. Authored-but-unparsable values, out-of-range `max`
17
+ * (≤ 0), and negative `value` are deferred to `no-invalid-attr-value`.
18
+ *
19
+ * @see https://html.spec.whatwg.org/multipage/form-elements.html#the-progress-element
20
+ */
21
+ export default createRule({
22
+ meta: meta,
23
+ defaultValue: true,
24
+ defaultOptions: null,
25
+ async verify({ document, report, t }) {
26
+ await document.walkOn('Element', el => {
27
+ if (el.localName !== 'progress')
28
+ return;
29
+ // Pretender progresses with no `as` pin: attributes are unknown until typed.
30
+ if (el.pretenderContext?.type === 'pretender' && !el.hasAttribute('as'))
31
+ return;
32
+ const valueAttr = el.getAttributeNode('value');
33
+ const maxAttr = el.getAttributeNode('max');
34
+ if (valueAttr === null)
35
+ return;
36
+ if (valueAttr.isDynamicValue || maxAttr?.isDynamicValue)
37
+ return;
38
+ const valueNum = parseFloatAttr(valueAttr.value);
39
+ const maxNum = parseFloatAttr(maxAttr?.value);
40
+ if (valueNum === null)
41
+ return;
42
+ if (maxAttr && maxNum === null)
43
+ return;
44
+ const maxValue = maxNum ?? DEFAULT_MAX;
45
+ if (valueNum <= maxValue)
46
+ return;
47
+ const message = maxAttr
48
+ ? t('The value of the "{0}" attribute must be less than or equal to {1}', 'value', t('the value of the "{0}" attribute', 'max'))
49
+ : t('The value of the "{0}" attribute must be less than or equal to {1}', 'value', t('{0} when the "{1}" attribute is absent', 'one', 'max'));
50
+ report({
51
+ scope: valueAttr,
52
+ line: valueAttr.valueNode?.startLine,
53
+ col: valueAttr.valueNode?.startCol,
54
+ raw: valueAttr.valueNode?.raw,
55
+ message: message,
56
+ });
57
+ });
58
+ },
59
+ });
@@ -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,11 +1,4 @@
1
1
  import type { ARIAVersion } from '@markuplint/ml-spec';
2
- /**
3
- * Rule that requires elements with roles that need accessible names to have one.
4
- *
5
- * For each element exposed to the accessibility tree whose computed ARIA role
6
- * has `accessibleNameRequired` set to `true`, this rule verifies that the element
7
- * provides a non-empty accessible name.
8
- */
9
2
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, {
10
3
  ariaVersion: ARIAVersion | undefined;
11
4
  }>>;
@@ -2,13 +2,6 @@ import { createRule, getRoleSpec, getComputedRole } from '@markuplint/ml-core';
2
2
  import { ARIA_RECOMMENDED_VERSION, isExposed } from '@markuplint/ml-spec';
3
3
  import { accnameMayBeMutable } from '../helpers.js';
4
4
  import meta from './meta.js';
5
- /**
6
- * Rule that requires elements with roles that need accessible names to have one.
7
- *
8
- * For each element exposed to the accessibility tree whose computed ARIA role
9
- * has `accessibleNameRequired` set to `true`, this rule verifies that the element
10
- * provides a non-empty accessible name.
11
- */
12
5
  export default createRule({
13
6
  meta: meta,
14
7
  defaultOptions: {
@@ -1,4 +1,3 @@
1
- /** Rule metadata for the `require-accessible-name` rule, categorized as accessibility. */
2
1
  declare const _default: {
3
2
  readonly category: "a11y";
4
3
  };
@@ -1,4 +1,3 @@
1
- /** Rule metadata for the `require-accessible-name` rule, categorized as accessibility. */
2
1
  export default {
3
2
  category: 'a11y',
4
3
  };
@@ -0,0 +1,2 @@
1
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
2
+ export default _default;
@@ -6,16 +6,9 @@ import meta from './meta.js';
6
6
  * Comparison is case-insensitive per the HTML spec.
7
7
  */
8
8
  const POPOVER_COMMANDS = new Set(['toggle-popover', 'show-popover', 'hide-popover']);
9
- /**
10
- * Rule that detects perceptible content between a popover trigger and its target.
11
- *
12
- * When a `[popovertarget]` element or a `[commandfor]` element with a popover-related
13
- * `command` attribute and its corresponding `[popover]` target exist in the DOM, any
14
- * focusable elements, elements with accessible names, or non-whitespace text nodes
15
- * between them are reported as violations.
16
- */
17
9
  export default createRule({
18
10
  meta: meta,
11
+ defaultSeverity: 'warning',
19
12
  verify({ document, report, t }) {
20
13
  const ariaVersion = document.ruleCommonSettings?.ariaVersion ?? ARIA_RECOMMENDED_VERSION;
21
14
  const triggers = document.querySelectorAll('[popovertarget], [commandfor]');
@@ -0,0 +1,4 @@
1
+ declare const _default: {
2
+ readonly category: "a11y";
3
+ };
4
+ export default _default;
@@ -0,0 +1,3 @@
1
+ export default {
2
+ category: 'a11y',
3
+ };
@@ -0,0 +1,2 @@
1
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
2
+ export default _default;
@@ -0,0 +1,29 @@
1
+ import { createRule } from '@markuplint/ml-core';
2
+ import meta from './meta.js';
3
+ export default createRule({
4
+ meta: meta,
5
+ async verify({ document, report, t }) {
6
+ await document.walkOn('Element', el => {
7
+ const elSpec = document.specs.specs.find(s => s.name === el.localName);
8
+ const descendantOf = elSpec?.contentModel?.descendantOf;
9
+ if (!descendantOf) {
10
+ return;
11
+ }
12
+ let ancestor = el.parentElement;
13
+ let found = false;
14
+ while (ancestor) {
15
+ if (ancestor.matches(descendantOf)) {
16
+ found = true;
17
+ break;
18
+ }
19
+ ancestor = ancestor.parentElement;
20
+ }
21
+ if (!found) {
22
+ report({
23
+ scope: el,
24
+ message: t('{0} must appear as a descendant of {1}', t('the "{0}" {1}', el.localName, 'element'), t('the "{0}" {1}', descendantOf, 'element')),
25
+ });
26
+ }
27
+ });
28
+ },
29
+ });
@@ -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,3 @@
1
+ import type { Options } from '../wai-aria/types.js';
2
+ declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Options>>;
3
+ export default _default;
@@ -3,7 +3,6 @@ import { ARIA_RECOMMENDED_VERSION } from '@markuplint/ml-spec';
3
3
  import { checkingRequiredProp } from '../wai-aria/checkings/required-prop.js';
4
4
  import { defaultOptions } from '../wai-aria/default-options.js';
5
5
  import meta from './meta.js';
6
- /** Warns when required ARIA properties for a role are missing. */
7
6
  export default createRule({
8
7
  meta,
9
8
  defaultOptions,
@@ -0,0 +1,4 @@
1
+ declare const _default: {
2
+ readonly category: "a11y";
3
+ };
4
+ export default _default;
@@ -0,0 +1,3 @@
1
+ export default {
2
+ category: 'a11y',
3
+ };
@@ -10,18 +10,11 @@ type Attr = {
10
10
  value?: string | string[];
11
11
  };
12
12
  /**
13
- * Configuration options for the `required-attr` rule.
13
+ * Configuration options for the `require-attr` rule.
14
14
  */
15
15
  type Options = {
16
- /** Attribute names to exclude from required-attribute checks. */
16
+ /** Attribute names to exclude from require-attribute checks. */
17
17
  readonly ignoreAttrs?: readonly string[];
18
18
  };
19
- /**
20
- * Rule that validates elements have all required attributes.
21
- *
22
- * Checks both HTML-spec-defined required attributes and custom required attributes
23
- * specified in the rule configuration. Also validates that required attribute values
24
- * match expected patterns when value constraints are provided.
25
- */
26
19
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<RequiredAttributes, Options>>;
27
20
  export default _default;
@@ -1,13 +1,6 @@
1
1
  import { createRule, getAttrSpecs } from '@markuplint/ml-core';
2
2
  import { attrMatches, match } from '../helpers.js';
3
3
  import meta from './meta.js';
4
- /**
5
- * Rule that validates elements have all required attributes.
6
- *
7
- * Checks both HTML-spec-defined required attributes and custom required attributes
8
- * specified in the rule configuration. Also validates that required attribute values
9
- * match expected patterns when value constraints are provided.
10
- */
11
4
  export default createRule({
12
5
  meta: meta,
13
6
  defaultValue: [],
@@ -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
+ };
@@ -6,13 +6,5 @@ type Options = {
6
6
  /** Languages to use when parsing natural language date/time text content. */
7
7
  langs?: Lang[];
8
8
  };
9
- /**
10
- * Rule that validates `<time>` elements without a `datetime` attribute have
11
- * machine-readable date/time content.
12
- *
13
- * When a `<time>` element lacks the `datetime` attribute, this rule checks
14
- * whether the text content is a valid datetime string. If not, it attempts
15
- * to parse the content as natural language and suggests a `datetime` value.
16
- */
17
9
  declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Options>>;
18
10
  export default _default;
@@ -2,14 +2,6 @@ import { createRule } from '@markuplint/ml-core';
2
2
  import { check } from '@markuplint/types';
3
3
  import meta from './meta.js';
4
4
  import { getCandidateDatetimeString } from './utils.js';
5
- /**
6
- * Rule that validates `<time>` elements without a `datetime` attribute have
7
- * machine-readable date/time content.
8
- *
9
- * When a `<time>` element lacks the `datetime` attribute, this rule checks
10
- * whether the text content is a valid datetime string. If not, it attempts
11
- * to parse the content as natural language and suggests a `datetime` value.
12
- */
13
5
  export default createRule({
14
6
  meta: meta,
15
7
  defaultOptions: {
@@ -1,5 +1,4 @@
1
- /** Rule metadata for the `require-datetime` 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 `require-datetime` rule, categorized as validation. */
2
1
  export default {
3
- category: 'validation',
2
+ category: 'attributes',
4
3
  };