@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.
- package/CHANGELOG.md +98 -0
- package/CLAUDE.md +31 -2
- package/lib/{wai-aria-deprecated-role → aria-prop-requires-role}/index.d.ts +0 -1
- package/lib/{wai-aria-no-global-prop → aria-prop-requires-role}/index.js +0 -1
- package/lib/attr-check.d.ts +0 -48
- package/lib/attr-check.js +0 -36
- package/lib/attr-eligibility.d.ts +41 -0
- package/lib/attr-eligibility.js +60 -0
- package/lib/attr-value-quotes/index.d.ts +0 -7
- package/lib/attr-value-quotes/index.js +0 -7
- package/lib/attr-value-quotes/meta.d.ts +0 -1
- package/lib/attr-value-quotes/meta.js +0 -1
- package/lib/case-sensitive-attr-name/index.d.ts +0 -8
- package/lib/case-sensitive-attr-name/index.js +0 -8
- package/lib/case-sensitive-attr-name/meta.d.ts +0 -1
- package/lib/case-sensitive-attr-name/meta.js +0 -1
- package/lib/case-sensitive-tag-name/index.d.ts +0 -8
- package/lib/case-sensitive-tag-name/index.js +0 -8
- package/lib/case-sensitive-tag-name/meta.d.ts +0 -1
- package/lib/case-sensitive-tag-name/meta.js +0 -1
- package/lib/class-naming/index.d.ts +0 -8
- package/lib/class-naming/index.js +0 -8
- package/lib/class-naming/meta.d.ts +1 -2
- package/lib/class-naming/meta.js +1 -2
- package/lib/consistent-table-row-length/index.d.ts +14 -0
- package/lib/consistent-table-row-length/index.js +69 -0
- package/lib/consistent-table-row-length/meta.d.ts +4 -0
- package/lib/consistent-table-row-length/meta.js +3 -0
- package/lib/create-message.d.ts +2 -25
- package/lib/create-message.js +2 -53
- package/lib/debug.d.ts +1 -9
- package/lib/debug.js +1 -5
- package/lib/element-supports-aria-prop/index.d.ts +12 -0
- package/lib/element-supports-aria-prop/index.js +38 -0
- package/lib/form-attr-references-form/index.d.ts +12 -0
- package/lib/form-attr-references-form/index.js +64 -0
- package/lib/{correct-aspect-ratio → form-attr-references-form}/meta.d.ts +1 -1
- package/lib/form-attr-references-form/meta.js +3 -0
- package/lib/head-element-order/meta.d.ts +1 -1
- package/lib/head-element-order/meta.js +1 -1
- package/lib/helpers.d.ts +8 -138
- package/lib/helpers.js +24 -165
- package/lib/index.d.ts +135 -78
- package/lib/index.js +167 -82
- package/lib/input-list-references-datalist/index.d.ts +13 -0
- package/lib/input-list-references-datalist/index.js +46 -0
- package/lib/input-list-references-datalist/meta.d.ts +4 -0
- package/lib/input-list-references-datalist/meta.js +3 -0
- package/lib/itemprop-requires-itemscope/index.d.ts +21 -0
- package/lib/itemprop-requires-itemscope/index.js +53 -0
- package/lib/itemprop-requires-itemscope/meta.d.ts +4 -0
- package/lib/itemprop-requires-itemscope/meta.js +3 -0
- package/lib/label-for-references-labelable/index.d.ts +12 -0
- package/lib/label-for-references-labelable/index.js +68 -0
- package/lib/label-for-references-labelable/meta.d.ts +4 -0
- package/lib/label-for-references-labelable/meta.js +3 -0
- package/lib/label-has-control/index.d.ts +5 -5
- package/lib/label-has-control/index.js +5 -18
- package/lib/label-has-control/meta.d.ts +0 -1
- package/lib/label-has-control/meta.js +0 -1
- package/lib/label-no-multiple-controls/index.d.ts +31 -0
- package/lib/label-no-multiple-controls/index.js +104 -0
- package/lib/label-no-multiple-controls/meta.d.ts +4 -0
- package/lib/label-no-multiple-controls/meta.js +3 -0
- package/lib/landmark-roles/roles.d.ts +32 -0
- package/lib/landmark-roles/roles.js +73 -0
- package/lib/link-types/index.d.ts +0 -5
- package/lib/link-types/index.js +5 -6
- package/lib/link-types/meta.d.ts +1 -2
- package/lib/link-types/meta.js +1 -2
- package/lib/map-id-name-match/index.d.ts +10 -0
- package/lib/map-id-name-match/index.js +39 -0
- package/lib/map-id-name-match/meta.d.ts +4 -0
- package/lib/map-id-name-match/meta.js +3 -0
- package/lib/meta-charset-position/index.d.ts +15 -0
- package/lib/meta-charset-position/index.js +31 -0
- package/lib/meta-charset-position/meta.d.ts +4 -0
- package/lib/meta-charset-position/meta.js +3 -0
- package/lib/meter-value-bounds/index.d.ts +10 -0
- package/lib/meter-value-bounds/index.js +123 -0
- package/lib/meter-value-bounds/meta.d.ts +4 -0
- package/lib/meter-value-bounds/meta.js +3 -0
- package/lib/{wai-aria-required-props → no-abstract-role}/index.d.ts +0 -1
- package/lib/{wai-aria-abstract-role → no-abstract-role}/index.js +0 -1
- package/lib/no-always-matching-source/index.d.ts +13 -0
- package/lib/no-always-matching-source/index.js +100 -0
- package/lib/no-always-matching-source/meta.d.ts +4 -0
- package/lib/no-always-matching-source/meta.js +3 -0
- package/lib/no-ambiguous-navigable-target-names/index.d.ts +0 -8
- package/lib/no-ambiguous-navigable-target-names/index.js +0 -8
- package/lib/no-ambiguous-navigable-target-names/meta.d.ts +1 -2
- package/lib/no-ambiguous-navigable-target-names/meta.js +1 -2
- package/lib/{wai-aria-required-owned-elements → no-aria-on-presentational-children}/index.d.ts +0 -1
- package/lib/{wai-aria-presentational-children → no-aria-on-presentational-children}/index.js +0 -1
- package/lib/no-aria-on-unsupported-element/index.d.ts +11 -0
- package/lib/no-aria-on-unsupported-element/index.js +35 -0
- package/lib/no-aria-on-unsupported-element/meta.d.ts +9 -0
- package/lib/no-aria-on-unsupported-element/meta.js +8 -0
- package/lib/no-boolean-attr-value/index.d.ts +0 -7
- package/lib/no-boolean-attr-value/index.js +0 -7
- package/lib/no-boolean-attr-value/meta.d.ts +0 -1
- package/lib/no-boolean-attr-value/meta.js +0 -1
- package/lib/no-broken-fragment-link/index.d.ts +15 -0
- package/lib/no-broken-fragment-link/index.js +93 -0
- package/lib/no-broken-fragment-link/meta.d.ts +4 -0
- package/lib/no-broken-fragment-link/meta.js +3 -0
- package/lib/no-consecutive-br/index.d.ts +0 -8
- package/lib/no-consecutive-br/index.js +0 -8
- package/lib/no-consecutive-br/meta.d.ts +0 -1
- package/lib/no-consecutive-br/meta.js +0 -1
- package/lib/no-content-after-body/index.d.ts +25 -0
- package/lib/no-content-after-body/index.js +51 -0
- package/lib/no-content-after-body/meta.d.ts +4 -0
- package/lib/no-content-after-body/meta.js +3 -0
- package/lib/no-contradictory-aria-prop/index.d.ts +10 -0
- package/lib/no-contradictory-aria-prop/index.js +34 -0
- package/lib/{wai-aria-abstract-role → no-default-aria-value}/index.d.ts +0 -1
- package/lib/{wai-aria-default-value → no-default-aria-value}/index.js +0 -1
- package/lib/no-default-value/index.d.ts +0 -7
- package/lib/no-default-value/index.js +0 -7
- package/lib/no-default-value/meta.d.ts +0 -1
- package/lib/no-default-value/meta.js +0 -1
- package/lib/no-deprecated-aria-prop/index.d.ts +3 -0
- package/lib/{wai-aria-deprecated-props → no-deprecated-aria-prop}/index.js +0 -1
- package/lib/no-deprecated-attr/index.d.ts +2 -0
- package/lib/{deprecated-attr → no-deprecated-attr}/index.js +5 -9
- package/lib/no-deprecated-attr/meta.d.ts +4 -0
- package/lib/no-deprecated-attr/meta.js +3 -0
- package/lib/no-deprecated-element/index.d.ts +2 -0
- package/lib/no-deprecated-element/index.js +27 -0
- package/lib/no-deprecated-element/meta.d.ts +4 -0
- package/lib/no-deprecated-element/meta.js +3 -0
- package/lib/no-deprecated-role/index.d.ts +3 -0
- package/lib/{wai-aria-deprecated-role → no-deprecated-role}/index.js +0 -1
- package/lib/no-disallowed-ancestor/index.d.ts +2 -0
- package/lib/no-disallowed-ancestor/index.js +25 -0
- package/lib/no-disallowed-ancestor/meta.d.ts +4 -0
- package/lib/no-disallowed-ancestor/meta.js +3 -0
- package/lib/no-disallowed-attr/index.d.ts +28 -0
- package/lib/no-disallowed-attr/index.js +77 -0
- package/lib/no-disallowed-attr/meta.d.ts +4 -0
- package/lib/no-disallowed-attr/meta.js +3 -0
- package/lib/no-duplicate-attr/index.d.ts +2 -0
- package/lib/{attr-duplication → no-duplicate-attr}/index.js +0 -7
- package/lib/no-duplicate-attr/meta.d.ts +6 -0
- package/lib/no-duplicate-attr/meta.js +10 -0
- package/lib/no-duplicate-autofocus/index.d.ts +0 -5
- package/lib/no-duplicate-autofocus/index.js +20 -6
- package/lib/no-duplicate-autofocus/meta.d.ts +1 -1
- package/lib/no-duplicate-autofocus/meta.js +1 -1
- package/lib/no-duplicate-dt/index.d.ts +0 -6
- package/lib/no-duplicate-dt/index.js +1 -6
- package/lib/no-duplicate-dt/meta.d.ts +1 -2
- package/lib/no-duplicate-dt/meta.js +1 -2
- package/lib/no-duplicate-h1/index.d.ts +18 -0
- package/lib/no-duplicate-h1/index.js +41 -0
- package/lib/no-duplicate-h1/meta.d.ts +4 -0
- package/lib/no-duplicate-h1/meta.js +3 -0
- package/lib/no-duplicate-id/index.d.ts +2 -0
- package/lib/{id-duplication → no-duplicate-id}/index.js +0 -7
- package/lib/no-duplicate-id/meta.d.ts +4 -0
- package/lib/no-duplicate-id/meta.js +3 -0
- package/lib/no-duplicate-sibling-attr/index.d.ts +2 -0
- package/lib/no-duplicate-sibling-attr/index.js +35 -0
- package/lib/no-duplicate-sibling-attr/meta.d.ts +4 -0
- package/lib/no-duplicate-sibling-attr/meta.js +3 -0
- package/lib/no-duplicate-visible-main/index.d.ts +0 -1
- package/lib/no-duplicate-visible-main/index.js +0 -1
- package/lib/no-duplicate-visible-main/meta.d.ts +1 -1
- package/lib/no-duplicate-visible-main/meta.js +1 -1
- package/lib/no-empty-palpable-content/index.d.ts +0 -8
- package/lib/no-empty-palpable-content/index.js +0 -8
- package/lib/no-empty-palpable-content/meta.d.ts +1 -2
- package/lib/no-empty-palpable-content/meta.js +1 -2
- package/lib/no-empty-table-track/index.d.ts +12 -0
- package/lib/no-empty-table-track/index.js +42 -0
- package/lib/no-empty-table-track/meta.d.ts +4 -0
- package/lib/no-empty-table-track/meta.js +3 -0
- package/lib/no-event-handler-attr/index.d.ts +7 -0
- package/lib/{no-use-event-handler-attr → no-event-handler-attr}/index.js +0 -11
- package/lib/no-event-handler-attr/meta.d.ts +4 -0
- package/lib/no-event-handler-attr/meta.js +3 -0
- package/lib/no-experimental-features/index.d.ts +9 -0
- package/lib/no-experimental-features/index.js +53 -0
- package/lib/no-experimental-features/meta.d.ts +4 -0
- package/lib/no-experimental-features/meta.js +3 -0
- package/lib/no-extra-selected-options/index.d.ts +10 -0
- package/lib/no-extra-selected-options/index.js +37 -0
- package/lib/no-extra-selected-options/meta.d.ts +4 -0
- package/lib/no-extra-selected-options/meta.js +3 -0
- package/lib/no-focusable-in-aria-hidden/index.d.ts +3 -0
- package/lib/{wai-aria-interaction-in-hidden → no-focusable-in-aria-hidden}/index.js +0 -1
- package/lib/no-focusable-in-aria-hidden/meta.d.ts +4 -0
- package/lib/no-focusable-in-aria-hidden/meta.js +3 -0
- package/lib/no-hardcoded-id/index.d.ts +2 -0
- package/lib/{no-hard-code-id → no-hardcoded-id}/index.js +0 -8
- package/lib/no-hardcoded-id/meta.d.ts +4 -0
- package/lib/no-hardcoded-id/meta.js +3 -0
- package/lib/no-ineffective-attr/index.d.ts +2 -0
- package/lib/{ineffective-attr → no-ineffective-attr}/index.js +0 -7
- package/lib/no-ineffective-attr/meta.d.ts +5 -0
- package/lib/no-ineffective-attr/meta.js +4 -0
- package/lib/no-input-file-value/index.d.ts +10 -0
- package/lib/no-input-file-value/index.js +41 -0
- package/lib/no-input-file-value/meta.d.ts +4 -0
- package/lib/no-input-file-value/meta.js +3 -0
- package/lib/no-invalid-aria-prop-value/index.d.ts +3 -0
- package/lib/{wai-aria-value → no-invalid-aria-prop-value}/index.js +0 -1
- package/lib/no-invalid-aria-prop-value/meta.d.ts +4 -0
- package/lib/no-invalid-aria-prop-value/meta.js +3 -0
- package/lib/no-invalid-attr-value/index.d.ts +27 -0
- package/lib/no-invalid-attr-value/index.js +83 -0
- package/lib/no-invalid-attr-value/meta.d.ts +4 -0
- package/lib/no-invalid-attr-value/meta.js +3 -0
- package/lib/no-malformed-character-reference/index.d.ts +2 -0
- package/lib/no-malformed-character-reference/index.js +38 -0
- package/lib/no-malformed-character-reference/meta.d.ts +5 -0
- package/lib/no-malformed-character-reference/meta.js +20 -0
- package/lib/{correct-aspect-ratio → no-mismatched-aspect-ratio}/index.js +13 -3
- package/lib/no-mismatched-aspect-ratio/meta.d.ts +4 -0
- package/lib/no-mismatched-aspect-ratio/meta.js +3 -0
- package/lib/{correct-aspect-ratio → no-mismatched-aspect-ratio}/resolve-image-size.js +8 -2
- package/lib/no-mixed-srcset-descriptors/index.d.ts +12 -0
- package/lib/no-mixed-srcset-descriptors/index.js +47 -0
- package/lib/no-mixed-srcset-descriptors/meta.d.ts +4 -0
- package/lib/no-mixed-srcset-descriptors/meta.js +3 -0
- package/lib/no-nested-top-level-landmark/index.d.ts +10 -0
- package/lib/no-nested-top-level-landmark/index.js +52 -0
- package/lib/no-nested-top-level-landmark/meta.d.ts +4 -0
- package/lib/no-nested-top-level-landmark/meta.js +3 -0
- package/lib/no-nonstandard-features/index.d.ts +9 -0
- package/lib/no-nonstandard-features/index.js +53 -0
- package/lib/no-nonstandard-features/meta.d.ts +4 -0
- package/lib/no-nonstandard-features/meta.js +3 -0
- package/lib/no-obsolete-attr/index.d.ts +2 -0
- package/lib/no-obsolete-attr/index.js +27 -0
- package/lib/no-obsolete-attr/meta.d.ts +4 -0
- package/lib/no-obsolete-attr/meta.js +3 -0
- package/lib/no-obsolete-doctype/index.d.ts +2 -0
- package/lib/{doctype → no-obsolete-doctype}/index.js +9 -16
- package/lib/no-obsolete-doctype/meta.d.ts +4 -0
- package/lib/no-obsolete-doctype/meta.js +3 -0
- package/lib/no-obsolete-element/index.d.ts +2 -0
- package/lib/{deprecated-element → no-obsolete-element}/index.js +6 -10
- package/lib/no-obsolete-element/meta.d.ts +4 -0
- package/lib/no-obsolete-element/meta.js +3 -0
- package/lib/no-orphaned-end-tag/index.d.ts +0 -7
- package/lib/no-orphaned-end-tag/index.js +0 -7
- package/lib/no-orphaned-end-tag/meta.d.ts +2 -2
- package/lib/no-orphaned-end-tag/meta.js +5 -2
- package/lib/no-prohibited-naming/index.d.ts +8 -0
- package/lib/no-prohibited-naming/index.js +36 -0
- package/lib/no-prohibited-naming/meta.d.ts +4 -0
- package/lib/no-prohibited-naming/meta.js +3 -0
- package/lib/{use-list → no-pseudo-list}/index.d.ts +1 -8
- package/lib/{use-list → no-pseudo-list}/index.js +0 -7
- package/lib/no-pseudo-list/meta.d.ts +4 -0
- package/lib/no-pseudo-list/meta.js +3 -0
- package/lib/{redundant-accessible-name → no-redundant-accessible-name}/index.d.ts +0 -4
- package/lib/{redundant-accessible-name → no-redundant-accessible-name}/index.js +0 -4
- package/lib/no-redundant-accessible-name/meta.d.ts +4 -0
- package/lib/no-redundant-accessible-name/meta.js +3 -0
- package/lib/no-redundant-aria-prop/index.d.ts +10 -0
- package/lib/{wai-aria-implicit-props → no-redundant-aria-prop}/index.js +9 -3
- package/lib/no-redundant-aria-prop/meta.d.ts +4 -0
- package/lib/no-redundant-aria-prop/meta.js +3 -0
- package/lib/no-redundant-role/index.d.ts +3 -0
- package/lib/{wai-aria-implicit-role → no-redundant-role}/index.js +0 -1
- package/lib/no-redundant-role/meta.d.ts +4 -0
- package/lib/no-redundant-role/meta.js +3 -0
- package/lib/no-refer-to-non-existent-id/index.d.ts +0 -9
- package/lib/no-refer-to-non-existent-id/index.js +1 -62
- package/lib/no-refer-to-non-existent-id/meta.d.ts +1 -2
- package/lib/no-refer-to-non-existent-id/meta.js +1 -2
- package/lib/no-restricted-attr/index.d.ts +27 -0
- package/lib/no-restricted-attr/index.js +96 -0
- package/lib/no-restricted-attr/meta.d.ts +4 -0
- package/lib/no-restricted-attr/meta.js +3 -0
- package/lib/no-restricted-element/index.d.ts +2 -0
- package/lib/{disallowed-element → no-restricted-element}/index.js +7 -8
- package/lib/no-restricted-element/meta.d.ts +4 -0
- package/lib/no-restricted-element/meta.js +3 -0
- package/lib/no-skipped-heading-level/index.d.ts +13 -0
- package/lib/{heading-levels → no-skipped-heading-level}/index.js +10 -5
- package/lib/no-skipped-heading-level/meta.d.ts +4 -0
- package/lib/no-skipped-heading-level/meta.js +3 -0
- package/lib/no-stray-head-or-body-tag/index.d.ts +28 -0
- package/lib/no-stray-head-or-body-tag/index.js +61 -0
- package/lib/no-stray-head-or-body-tag/meta.d.ts +4 -0
- package/lib/no-stray-head-or-body-tag/meta.js +3 -0
- package/lib/no-table-cell-overlap/index.d.ts +12 -0
- package/lib/no-table-cell-overlap/index.js +30 -0
- package/lib/no-table-cell-overlap/meta.d.ts +4 -0
- package/lib/no-table-cell-overlap/meta.js +3 -0
- package/lib/no-table-span-overflow/index.d.ts +12 -0
- package/lib/no-table-span-overflow/index.js +37 -0
- package/lib/no-table-span-overflow/meta.d.ts +4 -0
- package/lib/no-table-span-overflow/meta.js +3 -0
- package/lib/no-unclosed-element-at-eof/index.d.ts +2 -0
- package/lib/no-unclosed-element-at-eof/index.js +86 -0
- package/lib/no-unclosed-element-at-eof/meta.d.ts +4 -0
- package/lib/no-unclosed-element-at-eof/meta.js +3 -0
- package/lib/no-unescaped-char/index.d.ts +14 -0
- package/lib/{character-reference → no-unescaped-char}/index.js +31 -20
- package/lib/no-unescaped-char/meta.d.ts +4 -0
- package/lib/no-unescaped-char/meta.js +3 -0
- package/lib/{invalid-attr → no-unknown-attr}/index.d.ts +4 -19
- package/lib/no-unknown-attr/index.js +91 -0
- package/lib/no-unknown-attr/meta.d.ts +4 -0
- package/lib/no-unknown-attr/meta.js +3 -0
- package/lib/no-unknown-role/index.d.ts +3 -0
- package/lib/{wai-aria-non-existent-role → no-unknown-role}/index.js +0 -1
- package/lib/no-unknown-role/meta.d.ts +4 -0
- package/lib/no-unknown-role/meta.js +3 -0
- package/lib/no-unpaired-srcset-sizes/index.d.ts +12 -0
- package/lib/no-unpaired-srcset-sizes/index.js +77 -0
- package/lib/no-unpaired-srcset-sizes/meta.d.ts +4 -0
- package/lib/no-unpaired-srcset-sizes/meta.js +3 -0
- package/lib/{no-unsupported-features → no-unsupported-browser-features}/index.d.ts +1 -10
- package/lib/no-unsupported-browser-features/index.js +81 -0
- package/lib/no-unsupported-browser-features/meta.d.ts +4 -0
- package/lib/no-unsupported-browser-features/meta.js +3 -0
- package/lib/permitted-contents/index.d.ts +0 -18
- package/lib/permitted-contents/index.js +0 -78
- package/lib/permitted-contents/meta.d.ts +1 -2
- package/lib/permitted-contents/meta.js +1 -2
- package/lib/permitted-contents/represent-transparent-nodes.js +15 -6
- package/lib/permitted-roles/index.d.ts +3 -0
- package/lib/{wai-aria-permitted-roles → permitted-roles}/index.js +0 -1
- package/lib/permitted-roles/meta.d.ts +4 -0
- package/lib/permitted-roles/meta.js +3 -0
- package/lib/placeholder-label-option/index.d.ts +10 -4
- package/lib/placeholder-label-option/index.js +30 -17
- package/lib/placeholder-label-option/meta.d.ts +1 -2
- package/lib/placeholder-label-option/meta.js +1 -2
- package/lib/progress-value-bounds/index.d.ts +10 -0
- package/lib/progress-value-bounds/index.js +59 -0
- package/lib/progress-value-bounds/meta.d.ts +4 -0
- package/lib/progress-value-bounds/meta.js +3 -0
- package/lib/require-accessible-name/index.d.ts +0 -7
- package/lib/require-accessible-name/index.js +0 -7
- package/lib/require-accessible-name/meta.d.ts +0 -1
- package/lib/require-accessible-name/meta.js +0 -1
- package/lib/require-adjacent-popover/index.d.ts +2 -0
- package/lib/{neighbor-popovers → require-adjacent-popover}/index.js +1 -8
- package/lib/require-adjacent-popover/meta.d.ts +4 -0
- package/lib/require-adjacent-popover/meta.js +3 -0
- package/lib/require-ancestor/index.d.ts +2 -0
- package/lib/require-ancestor/index.js +29 -0
- package/lib/require-ancestor/meta.d.ts +4 -0
- package/lib/require-ancestor/meta.js +3 -0
- package/lib/require-aria-prop/index.d.ts +3 -0
- package/lib/{wai-aria-required-props → require-aria-prop}/index.js +0 -1
- package/lib/require-aria-prop/meta.d.ts +4 -0
- package/lib/require-aria-prop/meta.js +3 -0
- package/lib/{required-attr → require-attr}/index.d.ts +2 -9
- package/lib/{required-attr → require-attr}/index.js +0 -7
- package/lib/require-attr/meta.d.ts +4 -0
- package/lib/require-attr/meta.js +3 -0
- package/lib/require-datetime/index.d.ts +0 -8
- package/lib/require-datetime/index.js +0 -8
- package/lib/require-datetime/meta.d.ts +1 -2
- package/lib/require-datetime/meta.js +1 -2
- package/lib/require-dialog-autofocus/index.d.ts +0 -10
- package/lib/require-dialog-autofocus/index.js +0 -10
- package/lib/require-dialog-autofocus/meta.d.ts +0 -1
- package/lib/require-dialog-autofocus/meta.js +0 -1
- package/lib/require-doctype/index.d.ts +2 -0
- package/lib/require-doctype/index.js +19 -0
- package/lib/require-doctype/meta.d.ts +5 -0
- package/lib/require-doctype/meta.js +10 -0
- package/lib/{required-element → require-element}/index.d.ts +1 -9
- package/lib/{required-element → require-element}/index.js +0 -8
- package/lib/require-element/meta.d.ts +4 -0
- package/lib/require-element/meta.js +3 -0
- package/lib/require-end-tag/index.d.ts +2 -0
- package/lib/{end-tag → require-end-tag}/index.js +0 -7
- package/lib/require-end-tag/meta.d.ts +4 -0
- package/lib/require-end-tag/meta.js +3 -0
- package/lib/require-h1/index.d.ts +17 -0
- package/lib/{required-h1 → require-h1}/index.js +6 -14
- package/lib/require-h1/meta.d.ts +4 -0
- package/lib/require-h1/meta.js +3 -0
- package/lib/require-landmark-label/index.d.ts +11 -0
- package/lib/require-landmark-label/index.js +55 -0
- package/lib/require-landmark-label/meta.d.ts +4 -0
- package/lib/require-landmark-label/meta.js +3 -0
- package/lib/require-owned-elements/index.d.ts +3 -0
- package/lib/{wai-aria-required-owned-elements → require-owned-elements}/index.js +0 -2
- package/lib/require-owned-elements/meta.d.ts +4 -0
- package/lib/require-owned-elements/meta.js +3 -0
- package/lib/require-parent-role/index.d.ts +3 -0
- package/lib/{wai-aria-required-parent-role → require-parent-role}/index.js +0 -1
- package/lib/require-parent-role/meta.d.ts +4 -0
- package/lib/require-parent-role/meta.js +3 -0
- package/lib/role-supports-aria-prop/index.d.ts +8 -0
- package/lib/{wai-aria-disallowed-props → role-supports-aria-prop}/index.js +11 -10
- package/lib/role-supports-aria-prop/meta.d.ts +4 -0
- package/lib/role-supports-aria-prop/meta.js +3 -0
- package/lib/rule-aliases.d.ts +2 -0
- package/lib/rule-aliases.js +325 -0
- package/lib/sizes-auto-requires-lazy-loading/index.d.ts +14 -0
- package/lib/sizes-auto-requires-lazy-loading/index.js +68 -0
- package/lib/sizes-auto-requires-lazy-loading/meta.d.ts +4 -0
- package/lib/sizes-auto-requires-lazy-loading/meta.js +3 -0
- package/lib/srcset-sizes-constraint/parse-srcset.d.ts +6 -0
- package/lib/srcset-sizes-constraint/parse-srcset.js +6 -0
- package/lib/srcset-sizes-constraint/sibling-helpers.d.ts +21 -0
- package/lib/srcset-sizes-constraint/sibling-helpers.js +37 -0
- package/lib/tab-requires-tabpanel/index.d.ts +3 -0
- package/lib/tab-requires-tabpanel/index.js +21 -0
- package/lib/tab-requires-tabpanel/meta.d.ts +4 -0
- package/lib/tab-requires-tabpanel/meta.js +3 -0
- package/lib/table-row-column-alignment/grid.d.ts +108 -52
- package/lib/table-row-column-alignment/grid.js +276 -203
- package/lib/table-row-column-alignment/types.d.ts +6 -8
- package/lib/usemap-references-map/index.d.ts +14 -0
- package/lib/usemap-references-map/index.js +46 -0
- package/lib/usemap-references-map/meta.d.ts +4 -0
- package/lib/usemap-references-map/meta.js +3 -0
- package/lib/valid-importmap/index.d.ts +2 -0
- package/lib/valid-importmap/index.js +176 -0
- package/lib/valid-importmap/meta.d.ts +4 -0
- package/lib/valid-importmap/meta.js +3 -0
- package/lib/valid-speculation-rules/index.d.ts +2 -0
- package/lib/valid-speculation-rules/index.js +292 -0
- package/lib/valid-speculation-rules/meta.d.ts +4 -0
- package/lib/valid-speculation-rules/meta.js +3 -0
- package/lib/wai-aria/checkings/contradictory-aria-prop.d.ts +23 -0
- package/lib/wai-aria/checkings/{implicit-props.js → contradictory-aria-prop.js} +22 -14
- package/lib/wai-aria/checkings/element-supports-aria-prop.d.ts +20 -0
- package/lib/wai-aria/checkings/element-supports-aria-prop.js +83 -0
- package/lib/wai-aria/checkings/prohibited-naming.d.ts +35 -0
- package/lib/wai-aria/checkings/prohibited-naming.js +64 -0
- package/lib/wai-aria/checkings/redundant-aria-prop.d.ts +23 -0
- package/lib/wai-aria/checkings/redundant-aria-prop.js +53 -0
- package/lib/wai-aria/checkings/required-prop.d.ts +4 -0
- package/lib/wai-aria/checkings/required-prop.js +16 -3
- package/lib/wai-aria/checkings/role-supports-aria-prop.d.ts +20 -0
- package/lib/wai-aria/checkings/role-supports-aria-prop.js +30 -0
- package/lib/wai-aria/checkings/tab-requires-tabpanel.d.ts +19 -0
- package/lib/wai-aria/checkings/tab-requires-tabpanel.js +56 -0
- package/lib/wai-aria/default-options.js +1 -0
- package/lib/wai-aria/types.d.ts +2 -0
- package/package.json +11 -10
- package/schema.json +275 -59
- package/SKILL.md +0 -77
- package/lib/attr-duplication/index.d.ts +0 -9
- package/lib/attr-duplication/meta.d.ts +0 -6
- package/lib/attr-duplication/meta.js +0 -5
- package/lib/character-reference/index.d.ts +0 -12
- package/lib/character-reference/meta.d.ts +0 -5
- package/lib/character-reference/meta.js +0 -4
- package/lib/correct-aspect-ratio/meta.js +0 -3
- package/lib/deprecated-attr/index.d.ts +0 -8
- package/lib/deprecated-attr/meta.d.ts +0 -5
- package/lib/deprecated-attr/meta.js +0 -4
- package/lib/deprecated-element/index.d.ts +0 -8
- package/lib/deprecated-element/meta.d.ts +0 -5
- package/lib/deprecated-element/meta.js +0 -4
- package/lib/disallowed-element/index.d.ts +0 -9
- package/lib/disallowed-element/meta.d.ts +0 -5
- package/lib/disallowed-element/meta.js +0 -4
- package/lib/doctype/index.d.ts +0 -15
- package/lib/doctype/meta.d.ts +0 -5
- package/lib/doctype/meta.js +0 -4
- package/lib/end-tag/index.d.ts +0 -9
- package/lib/end-tag/meta.d.ts +0 -5
- package/lib/end-tag/meta.js +0 -4
- package/lib/heading-levels/index.d.ts +0 -8
- package/lib/heading-levels/meta.d.ts +0 -5
- package/lib/heading-levels/meta.js +0 -4
- package/lib/id-duplication/index.d.ts +0 -9
- package/lib/id-duplication/meta.d.ts +0 -5
- package/lib/id-duplication/meta.js +0 -4
- package/lib/ineffective-attr/index.d.ts +0 -9
- package/lib/ineffective-attr/meta.d.ts +0 -6
- package/lib/ineffective-attr/meta.js +0 -5
- package/lib/invalid-attr/index.js +0 -207
- package/lib/invalid-attr/meta.d.ts +0 -5
- package/lib/invalid-attr/meta.js +0 -4
- package/lib/landmark-roles/index.d.ts +0 -22
- package/lib/landmark-roles/index.js +0 -142
- package/lib/landmark-roles/meta.d.ts +0 -5
- package/lib/landmark-roles/meta.js +0 -4
- package/lib/neighbor-popovers/index.d.ts +0 -10
- package/lib/neighbor-popovers/meta.d.ts +0 -5
- package/lib/neighbor-popovers/meta.js +0 -4
- package/lib/no-hard-code-id/index.d.ts +0 -10
- package/lib/no-hard-code-id/meta.d.ts +0 -5
- package/lib/no-hard-code-id/meta.js +0 -4
- package/lib/no-unsupported-features/index.js +0 -139
- package/lib/no-unsupported-features/meta.d.ts +0 -5
- package/lib/no-unsupported-features/meta.js +0 -4
- package/lib/no-use-event-handler-attr/index.d.ts +0 -18
- package/lib/no-use-event-handler-attr/meta.d.ts +0 -5
- package/lib/no-use-event-handler-attr/meta.js +0 -4
- package/lib/redundant-accessible-name/meta.d.ts +0 -5
- package/lib/redundant-accessible-name/meta.js +0 -4
- package/lib/required-attr/meta.d.ts +0 -5
- package/lib/required-attr/meta.js +0 -4
- package/lib/required-element/meta.d.ts +0 -5
- package/lib/required-element/meta.js +0 -4
- package/lib/required-h1/index.d.ts +0 -18
- package/lib/required-h1/meta.d.ts +0 -5
- package/lib/required-h1/meta.js +0 -4
- package/lib/srcset-sizes-constraint/index.d.ts +0 -6
- package/lib/srcset-sizes-constraint/index.js +0 -108
- package/lib/srcset-sizes-constraint/meta.d.ts +0 -5
- package/lib/srcset-sizes-constraint/meta.js +0 -4
- package/lib/table-row-column-alignment/index.d.ts +0 -10
- package/lib/table-row-column-alignment/index.js +0 -97
- package/lib/table-row-column-alignment/meta.d.ts +0 -5
- package/lib/table-row-column-alignment/meta.js +0 -4
- package/lib/use-list/meta.d.ts +0 -5
- package/lib/use-list/meta.js +0 -4
- package/lib/wai-aria/checkings/disallowed-prop.d.ts +0 -23
- package/lib/wai-aria/checkings/disallowed-prop.js +0 -84
- package/lib/wai-aria/checkings/implicit-props.d.ts +0 -20
- package/lib/wai-aria/index.d.ts +0 -13
- package/lib/wai-aria/index.js +0 -115
- package/lib/wai-aria/meta.d.ts +0 -5
- package/lib/wai-aria/meta.js +0 -4
- package/lib/wai-aria-default-value/index.d.ts +0 -4
- package/lib/wai-aria-default-value/meta.d.ts +0 -5
- package/lib/wai-aria-default-value/meta.js +0 -4
- package/lib/wai-aria-deprecated-props/index.d.ts +0 -4
- package/lib/wai-aria-deprecated-props/meta.d.ts +0 -5
- package/lib/wai-aria-deprecated-props/meta.js +0 -4
- package/lib/wai-aria-disallowed-props/index.d.ts +0 -4
- package/lib/wai-aria-disallowed-props/meta.d.ts +0 -5
- package/lib/wai-aria-disallowed-props/meta.js +0 -4
- package/lib/wai-aria-implicit-props/index.d.ts +0 -4
- package/lib/wai-aria-implicit-props/meta.d.ts +0 -5
- package/lib/wai-aria-implicit-props/meta.js +0 -4
- package/lib/wai-aria-implicit-role/index.d.ts +0 -4
- package/lib/wai-aria-interaction-in-hidden/index.d.ts +0 -4
- package/lib/wai-aria-interaction-in-hidden/meta.d.ts +0 -5
- package/lib/wai-aria-interaction-in-hidden/meta.js +0 -4
- package/lib/wai-aria-no-global-prop/index.d.ts +0 -4
- package/lib/wai-aria-no-global-prop/meta.d.ts +0 -5
- package/lib/wai-aria-no-global-prop/meta.js +0 -4
- package/lib/wai-aria-non-existent-role/index.d.ts +0 -4
- package/lib/wai-aria-permitted-roles/index.d.ts +0 -4
- package/lib/wai-aria-presentational-children/index.d.ts +0 -4
- package/lib/wai-aria-presentational-children/meta.d.ts +0 -5
- package/lib/wai-aria-presentational-children/meta.js +0 -4
- package/lib/wai-aria-required-parent-role/index.d.ts +0 -4
- package/lib/wai-aria-value/index.d.ts +0 -4
- package/lib/wai-aria-value/meta.d.ts +0 -5
- package/lib/wai-aria-value/meta.js +0 -4
- /package/lib/{wai-aria-abstract-role → aria-prop-requires-role}/meta.d.ts +0 -0
- /package/lib/{wai-aria-abstract-role → aria-prop-requires-role}/meta.js +0 -0
- /package/lib/{wai-aria-deprecated-role → element-supports-aria-prop}/meta.d.ts +0 -0
- /package/lib/{wai-aria-deprecated-role → element-supports-aria-prop}/meta.js +0 -0
- /package/lib/{wai-aria-implicit-role → no-abstract-role}/meta.d.ts +0 -0
- /package/lib/{wai-aria-implicit-role → no-abstract-role}/meta.js +0 -0
- /package/lib/{wai-aria-non-existent-role → no-aria-on-presentational-children}/meta.d.ts +0 -0
- /package/lib/{wai-aria-non-existent-role → no-aria-on-presentational-children}/meta.js +0 -0
- /package/lib/{wai-aria-permitted-roles → no-contradictory-aria-prop}/meta.d.ts +0 -0
- /package/lib/{wai-aria-permitted-roles → no-contradictory-aria-prop}/meta.js +0 -0
- /package/lib/{wai-aria-required-owned-elements → no-default-aria-value}/meta.d.ts +0 -0
- /package/lib/{wai-aria-required-owned-elements → no-default-aria-value}/meta.js +0 -0
- /package/lib/{wai-aria-required-parent-role → no-deprecated-aria-prop}/meta.d.ts +0 -0
- /package/lib/{wai-aria-required-parent-role → no-deprecated-aria-prop}/meta.js +0 -0
- /package/lib/{wai-aria-required-props → no-deprecated-role}/meta.d.ts +0 -0
- /package/lib/{wai-aria-required-props → no-deprecated-role}/meta.js +0 -0
- /package/lib/{correct-aspect-ratio → no-mismatched-aspect-ratio}/index.d.ts +0 -0
- /package/lib/{correct-aspect-ratio → no-mismatched-aspect-ratio}/resolve-image-size.d.ts +0 -0
- /package/lib/{no-unsupported-features → no-unsupported-browser-features}/compat-data.d.ts +0 -0
- /package/lib/{no-unsupported-features → no-unsupported-browser-features}/compat-data.js +0 -0
- /package/lib/{no-unsupported-features → no-unsupported-browser-features}/resolve-browsers.d.ts +0 -0
- /package/lib/{no-unsupported-features → no-unsupported-browser-features}/resolve-browsers.js +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createRule } from '@markuplint/ml-core';
|
|
2
|
+
import { findChildren } from '../table-row-column-alignment/find-children.js';
|
|
3
|
+
import { Grid, getIndexes } from '../table-row-column-alignment/grid.js';
|
|
4
|
+
import meta from './meta.js';
|
|
5
|
+
/**
|
|
6
|
+
* Flags rows whose width disagrees with the table's base column count.
|
|
7
|
+
*
|
|
8
|
+
* Unlike the sibling splits of `table-row-column-alignment`, this is not a table model error:
|
|
9
|
+
* HTML LS §4.9.12.1 Step 7 grows `xwidth` to fit a wider row, and a narrower row is only a table
|
|
10
|
+
* model error where {@link import('../no-empty-table-track/index.js')} already catches it (a
|
|
11
|
+
* column no cell ever anchors to). A ragged table is nevertheless almost always a mistake, which
|
|
12
|
+
* is why this check exists and why it stays a `warning` rather than the `error` of its siblings.
|
|
13
|
+
*
|
|
14
|
+
* Skips a table that `no-table-cell-overlap` already reports on — once two cells claim the same
|
|
15
|
+
* slot, row widths derived from the grid model are no longer reliable.
|
|
16
|
+
*/
|
|
17
|
+
export default createRule({
|
|
18
|
+
meta,
|
|
19
|
+
defaultSeverity: 'warning',
|
|
20
|
+
verify({ document, report, t }) {
|
|
21
|
+
const tables = document.querySelectorAll('table');
|
|
22
|
+
for (const table of tables) {
|
|
23
|
+
const grid = new Grid(table);
|
|
24
|
+
if (grid.hasOverlapped()) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const baseColLength = grid.getBaseColLength();
|
|
28
|
+
for (const row of grid.getRows()) {
|
|
29
|
+
if (row.anchorCount === 0) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const colLength = row.slots.length;
|
|
33
|
+
if (colLength === baseColLength) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const indexes = getIndexes(row.slots);
|
|
37
|
+
const cells = findChildren(row.element, 'th, td');
|
|
38
|
+
if (colLength > baseColLength) {
|
|
39
|
+
const index = indexes.slice(baseColLength)[0];
|
|
40
|
+
const unexpected = typeof index === 'number' ? cells[index] : null;
|
|
41
|
+
if (!unexpected) {
|
|
42
|
+
// The overshoot starts inside a spanned cell, so the `colspan` is the culprit.
|
|
43
|
+
const spanStart = cells.findLast(cell => Number.parseInt(cell.getAttribute('colspan') ?? '1') > 1);
|
|
44
|
+
const colSpan = spanStart?.getAttributeNode('colspan');
|
|
45
|
+
if (!colSpan) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
report({
|
|
49
|
+
scope: colSpan,
|
|
50
|
+
message: t('Exceeds the number of available {0}', 'columns'),
|
|
51
|
+
});
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const diff = colLength - baseColLength;
|
|
55
|
+
report({
|
|
56
|
+
scope: unexpected,
|
|
57
|
+
message: t('{0} extra {1} in {2}', t(`${diff}`), t(diff === 1 ? 'column' : 'columns'), t('a {0}', t('row'))),
|
|
58
|
+
});
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const diff = baseColLength - colLength;
|
|
62
|
+
report({
|
|
63
|
+
scope: row.element,
|
|
64
|
+
message: t('{0} missing {1} in {2}', t(`${diff}`), t(diff === 1 ? 'column' : 'columns'), t('a {0}', t('row'))),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
});
|
package/lib/create-message.d.ts
CHANGED
|
@@ -2,32 +2,9 @@ import type { Translator } from '@markuplint/i18n';
|
|
|
2
2
|
import type { AttributeType } from '@markuplint/ml-spec';
|
|
3
3
|
import type { UnmatchedResult, Type } from '@markuplint/types';
|
|
4
4
|
import type { ReadonlyDeep } from 'type-fest';
|
|
5
|
-
/**
|
|
6
|
-
* Builds a human-readable error message explaining why an attribute value
|
|
7
|
-
* does not match its expected type. Handles both plain types and list types
|
|
8
|
-
* (space-separated or comma-separated).
|
|
9
|
-
*
|
|
10
|
-
* @param t - The i18n translator for generating localized messages
|
|
11
|
-
* @param baseTarget - A human-readable description of the attribute being validated
|
|
12
|
-
* (e.g. `'the "href" attribute'`)
|
|
13
|
-
* @param type - The attribute type definition that the value was validated against
|
|
14
|
-
* @param matches - The result object from a failed type check, containing
|
|
15
|
-
* details about the mismatch (reason, candidate, part name, etc.)
|
|
16
|
-
* @returns A localized error message describing the expected value
|
|
17
|
-
*/
|
|
18
5
|
export declare function createMessageValueExpected(t: Translator, baseTarget: string, type: ReadonlyDeep<AttributeType | Type>, matches: UnmatchedResult): string;
|
|
19
6
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* candidate suggestion, and fallback parts into a single string.
|
|
23
|
-
*
|
|
24
|
-
* This is an internal helper exposed for testing and advanced use.
|
|
25
|
-
* The double-underscore prefix indicates it is not part of the stable public API.
|
|
26
|
-
*
|
|
27
|
-
* @param t - The i18n translator for generating localized messages
|
|
28
|
-
* @param baseTarget - A human-readable description of the validation target
|
|
29
|
-
* @param expected - A description of the expected value(s), or `null` if unknown
|
|
30
|
-
* @param matches - Partial match result containing reason, candidate, and other details
|
|
31
|
-
* @returns A localized error message string
|
|
7
|
+
* The double-underscore prefix marks this as exposed only for testing — not
|
|
8
|
+
* part of the stable public API.
|
|
32
9
|
*/
|
|
33
10
|
export declare function __createMessageValueExpected(t: Translator, baseTarget: string, expected: string | null, matches: Pick<UnmatchedResult, 'partName' | 'reason' | 'raw' | 'candidate' | 'ref' | 'extra' | 'fallbackTo'>): string;
|
package/lib/create-message.js
CHANGED
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
import { isList, isKeyword, isEnum, isNumber, isDirective, isPattern } from '@markuplint/types';
|
|
2
|
-
/**
|
|
3
|
-
* Builds a human-readable error message explaining why an attribute value
|
|
4
|
-
* does not match its expected type. Handles both plain types and list types
|
|
5
|
-
* (space-separated or comma-separated).
|
|
6
|
-
*
|
|
7
|
-
* @param t - The i18n translator for generating localized messages
|
|
8
|
-
* @param baseTarget - A human-readable description of the attribute being validated
|
|
9
|
-
* (e.g. `'the "href" attribute'`)
|
|
10
|
-
* @param type - The attribute type definition that the value was validated against
|
|
11
|
-
* @param matches - The result object from a failed type check, containing
|
|
12
|
-
* details about the mismatch (reason, candidate, part name, etc.)
|
|
13
|
-
* @returns A localized error message describing the expected value
|
|
14
|
-
*/
|
|
15
2
|
export function createMessageValueExpected(t, baseTarget, type, matches) {
|
|
16
3
|
let target = baseTarget;
|
|
17
4
|
let listDescriptionPart;
|
|
@@ -31,18 +18,8 @@ export function createMessageValueExpected(t, baseTarget, type, matches) {
|
|
|
31
18
|
return message;
|
|
32
19
|
}
|
|
33
20
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* candidate suggestion, and fallback parts into a single string.
|
|
37
|
-
*
|
|
38
|
-
* This is an internal helper exposed for testing and advanced use.
|
|
39
|
-
* The double-underscore prefix indicates it is not part of the stable public API.
|
|
40
|
-
*
|
|
41
|
-
* @param t - The i18n translator for generating localized messages
|
|
42
|
-
* @param baseTarget - A human-readable description of the validation target
|
|
43
|
-
* @param expected - A description of the expected value(s), or `null` if unknown
|
|
44
|
-
* @param matches - Partial match result containing reason, candidate, and other details
|
|
45
|
-
* @returns A localized error message string
|
|
21
|
+
* The double-underscore prefix marks this as exposed only for testing — not
|
|
22
|
+
* part of the stable public API.
|
|
46
23
|
*/
|
|
47
24
|
export function __createMessageValueExpected(t, baseTarget, expected, matches) {
|
|
48
25
|
let target = baseTarget;
|
|
@@ -226,17 +203,6 @@ export function __createMessageValueExpected(t, baseTarget, expected, matches) {
|
|
|
226
203
|
}
|
|
227
204
|
return message;
|
|
228
205
|
}
|
|
229
|
-
/**
|
|
230
|
-
* Derives a human-readable description of the expected value from an attribute
|
|
231
|
-
* type definition and the unmatched result. Inspects keywords, enums, numbers,
|
|
232
|
-
* directives, and explicit `expects` entries from the match result.
|
|
233
|
-
*
|
|
234
|
-
* @param type - The attribute type (excluding list wrappers)
|
|
235
|
-
* @param matches - The unmatched result containing optional `expects` hints
|
|
236
|
-
* @param t - The i18n translator
|
|
237
|
-
* @returns A localized string describing the expected value(s), or `null` if
|
|
238
|
-
* no expectation can be determined
|
|
239
|
-
*/
|
|
240
206
|
function createExpectedObject(type, matches, t) {
|
|
241
207
|
const expectedObject = [];
|
|
242
208
|
if (matches.expects && matches.expects.length > 0) {
|
|
@@ -268,14 +234,6 @@ function createExpectedObject(type, matches, t) {
|
|
|
268
234
|
: (expectedObject[0] ?? null);
|
|
269
235
|
return expects;
|
|
270
236
|
}
|
|
271
|
-
/**
|
|
272
|
-
* Converts a single `Expect` descriptor into a human-readable word or phrase.
|
|
273
|
-
*
|
|
274
|
-
* @param t - The i18n translator
|
|
275
|
-
* @param expect - The expectation descriptor from a type-check result
|
|
276
|
-
* @param type - The attribute type context for determining phrasing (e.g. CSS syntax)
|
|
277
|
-
* @returns A localized word or phrase describing the expected value
|
|
278
|
-
*/
|
|
279
237
|
function expectValueToWord(t, expect, type) {
|
|
280
238
|
switch (expect.type) {
|
|
281
239
|
case 'common': {
|
|
@@ -298,15 +256,6 @@ function expectValueToWord(t, expect, type) {
|
|
|
298
256
|
}
|
|
299
257
|
}
|
|
300
258
|
}
|
|
301
|
-
/**
|
|
302
|
-
* Builds a human-readable description of an expected numeric range
|
|
303
|
-
* from a `Number` type definition (e.g. "integer greater than or equal to 0").
|
|
304
|
-
*
|
|
305
|
-
* @param t - The i18n translator
|
|
306
|
-
* @param type - The number type definition containing range constraints
|
|
307
|
-
* (`gt`, `gte`, `lt`, `lte`) and the numeric type label
|
|
308
|
-
* @returns A localized description of the expected numeric range
|
|
309
|
-
*/
|
|
310
259
|
function createExpectedNumber(t, type) {
|
|
311
260
|
if (type.gt != null) {
|
|
312
261
|
if (type.lt != null) {
|
package/lib/debug.d.ts
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
import debug from 'debug';
|
|
2
|
-
/**
|
|
3
|
-
* Type alias for the debug logger function provided by the `debug` package.
|
|
4
|
-
* Used throughout the rules package for conditional diagnostic logging.
|
|
5
|
-
*/
|
|
6
2
|
export type Log = debug.Debugger;
|
|
7
|
-
/**
|
|
8
|
-
* Shared debug logger instance for the `@markuplint/rules` package.
|
|
9
|
-
* Enable by setting the `DEBUG` environment variable to include `ml-rules`
|
|
10
|
-
* (e.g. `DEBUG=ml-rules`).
|
|
11
|
-
*/
|
|
3
|
+
/** Enable by setting `DEBUG` to include `ml-rules` (e.g. `DEBUG=ml-rules`). */
|
|
12
4
|
export declare const log: debug.Debugger;
|
package/lib/debug.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
1
|
import debug from 'debug';
|
|
2
|
-
/**
|
|
3
|
-
* Shared debug logger instance for the `@markuplint/rules` package.
|
|
4
|
-
* Enable by setting the `DEBUG` environment variable to include `ml-rules`
|
|
5
|
-
* (e.g. `DEBUG=ml-rules`).
|
|
6
|
-
*/
|
|
2
|
+
/** Enable by setting `DEBUG` to include `ml-rules` (e.g. `DEBUG=ml-rules`). */
|
|
7
3
|
export const log = debug('ml-rules');
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Options } from '../wai-aria/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Split from the former `wai-aria-disallowed-props` rule (#3989): the ARIA in
|
|
4
|
+
* HTML element-specific `aria-*` restrictions alone. See
|
|
5
|
+
* `checkingElementSupportsAriaProp`'s JSDoc for the full spec citation.
|
|
6
|
+
*
|
|
7
|
+
* The former rule's `disallowSetImplicitProps` option gated this check; the
|
|
8
|
+
* split rule has no such option — disabling this rule entirely is how users
|
|
9
|
+
* opt out.
|
|
10
|
+
*/
|
|
11
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Options>>;
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { createRule, getComputedRole, ariaSpecs, getSpec } from '@markuplint/ml-core';
|
|
2
|
+
import { ARIA_RECOMMENDED_VERSION } from '@markuplint/ml-spec';
|
|
3
|
+
import { checkingElementSupportsAriaProp } from '../wai-aria/checkings/element-supports-aria-prop.js';
|
|
4
|
+
import { defaultOptions } from '../wai-aria/default-options.js';
|
|
5
|
+
import meta from './meta.js';
|
|
6
|
+
/**
|
|
7
|
+
* Split from the former `wai-aria-disallowed-props` rule (#3989): the ARIA in
|
|
8
|
+
* HTML element-specific `aria-*` restrictions alone. See
|
|
9
|
+
* `checkingElementSupportsAriaProp`'s JSDoc for the full spec citation.
|
|
10
|
+
*
|
|
11
|
+
* The former rule's `disallowSetImplicitProps` option gated this check; the
|
|
12
|
+
* split rule has no such option — disabling this rule entirely is how users
|
|
13
|
+
* opt out.
|
|
14
|
+
*/
|
|
15
|
+
export default createRule({
|
|
16
|
+
meta,
|
|
17
|
+
defaultOptions,
|
|
18
|
+
async verify({ document, report }) {
|
|
19
|
+
await document.walkOn('Element', el => {
|
|
20
|
+
const elSpec = getSpec(el, document.specs.specs);
|
|
21
|
+
// Autonomous custom elements have no spec.<el>.jsonc entry and no
|
|
22
|
+
// element-specific restriction to enforce here.
|
|
23
|
+
if (!elSpec)
|
|
24
|
+
return;
|
|
25
|
+
if (!elSpec.globalAttrs['#ARIAAttrs'])
|
|
26
|
+
return;
|
|
27
|
+
const propAttrs = el.attributes.filter(attr => /^aria-/i.test(attr.name));
|
|
28
|
+
if (propAttrs.length === 0)
|
|
29
|
+
return;
|
|
30
|
+
const ariaVersion = el.rule.options?.version ?? document.ruleCommonSettings?.ariaVersion ?? ARIA_RECOMMENDED_VERSION;
|
|
31
|
+
const computed = getComputedRole(document.specs, el, ariaVersion);
|
|
32
|
+
const { props: propSpecs } = ariaSpecs(document.specs, ariaVersion);
|
|
33
|
+
for (const attr of propAttrs) {
|
|
34
|
+
report(checkingElementSupportsAriaProp({ attr, role: computed.role, propSpecs }));
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Require the `form` attribute on a form-associated element to reference
|
|
3
|
+
* an actual `<form>` element by ID. Per HTML LS §4.10.18.6: "If
|
|
4
|
+
* specified, the value must be the ID of a form element in the
|
|
5
|
+
* element's tree." Existence of the ID itself is the responsibility of
|
|
6
|
+
* `no-refer-to-non-existent-id`; this rule only checks the element type
|
|
7
|
+
* when the ID resolves.
|
|
8
|
+
*
|
|
9
|
+
* @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form
|
|
10
|
+
*/
|
|
11
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, null>>;
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createRule } from '@markuplint/ml-core';
|
|
2
|
+
import meta from './meta.js';
|
|
3
|
+
/**
|
|
4
|
+
* Form-associated elements (HTML LS §4.10.2). Listed elements may carry
|
|
5
|
+
* a `form` attribute that explicitly associates them with a `<form>`
|
|
6
|
+
* element; the implicit ancestor-based association is otherwise used.
|
|
7
|
+
*
|
|
8
|
+
* @see https://html.spec.whatwg.org/multipage/forms.html#category-listed
|
|
9
|
+
*/
|
|
10
|
+
const FORM_ASSOCIATED_SELECTOR = [
|
|
11
|
+
'button',
|
|
12
|
+
'fieldset',
|
|
13
|
+
'input',
|
|
14
|
+
'label',
|
|
15
|
+
'meter',
|
|
16
|
+
'object',
|
|
17
|
+
'output',
|
|
18
|
+
'progress',
|
|
19
|
+
'select',
|
|
20
|
+
'textarea',
|
|
21
|
+
].join(',');
|
|
22
|
+
/**
|
|
23
|
+
* Require the `form` attribute on a form-associated element to reference
|
|
24
|
+
* an actual `<form>` element by ID. Per HTML LS §4.10.18.6: "If
|
|
25
|
+
* specified, the value must be the ID of a form element in the
|
|
26
|
+
* element's tree." Existence of the ID itself is the responsibility of
|
|
27
|
+
* `no-refer-to-non-existent-id`; this rule only checks the element type
|
|
28
|
+
* when the ID resolves.
|
|
29
|
+
*
|
|
30
|
+
* @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form
|
|
31
|
+
*/
|
|
32
|
+
export default createRule({
|
|
33
|
+
meta: meta,
|
|
34
|
+
defaultValue: true,
|
|
35
|
+
defaultOptions: null,
|
|
36
|
+
async verify({ document, report, t }) {
|
|
37
|
+
await document.walkOn('Element', el => {
|
|
38
|
+
if (!el.matches(FORM_ASSOCIATED_SELECTOR))
|
|
39
|
+
return;
|
|
40
|
+
if (el.pretenderContext?.type === 'pretender' && !el.hasAttribute('as'))
|
|
41
|
+
return;
|
|
42
|
+
const formAttr = el.getAttributeNode('form');
|
|
43
|
+
if (!formAttr)
|
|
44
|
+
return;
|
|
45
|
+
if (formAttr.isDynamicValue)
|
|
46
|
+
return;
|
|
47
|
+
const targetId = formAttr.value;
|
|
48
|
+
const target = [...document.querySelectorAll('[id]')].find(candidate => candidate.getAttribute('id') === targetId);
|
|
49
|
+
// Existence is checked by `no-refer-to-non-existent-id`. If the ID does not resolve
|
|
50
|
+
// here, leave that diagnostic to the dedicated rule and stay silent.
|
|
51
|
+
if (!target)
|
|
52
|
+
return;
|
|
53
|
+
if (target.localName !== 'form') {
|
|
54
|
+
report({
|
|
55
|
+
scope: formAttr,
|
|
56
|
+
line: formAttr.valueNode?.startLine,
|
|
57
|
+
col: formAttr.valueNode?.startCol,
|
|
58
|
+
raw: formAttr.valueNode?.raw,
|
|
59
|
+
message: t('The "{0}" attribute on a form-associated element must reference a "{1}" element', 'form', 'form'),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
});
|
package/lib/helpers.d.ts
CHANGED
|
@@ -1,30 +1,16 @@
|
|
|
1
|
-
import type { Log } from './debug.js';
|
|
2
|
-
import type { Translator } from '@markuplint/i18n';
|
|
3
1
|
import type { FixToken, IRuleFixer, PlainData, TextEdit } from '@markuplint/ml-config';
|
|
4
2
|
import type { Element, RuleConfigValue, Document } from '@markuplint/ml-core';
|
|
5
3
|
import type { Attribute } from '@markuplint/ml-spec';
|
|
6
4
|
import type { WritableDeep } from 'type-fest';
|
|
7
|
-
/**
|
|
8
|
-
* Tests whether an element matches the condition specified in an attribute spec.
|
|
9
|
-
* When the condition is `null` or `undefined`, the element is considered to match unconditionally.
|
|
10
|
-
*
|
|
11
|
-
* @template T - The rule configuration value type
|
|
12
|
-
* @template O - The rule options type
|
|
13
|
-
* @param node - The element to test against the condition
|
|
14
|
-
* @param condition - A CSS selector string or array of selector strings from the attribute specification;
|
|
15
|
-
* if `null`/`undefined`, the function returns `true`
|
|
16
|
-
* @returns `true` if the element matches the condition (or no condition is given), `false` otherwise
|
|
17
|
-
*/
|
|
5
|
+
/** A `null`/`undefined` condition means the attribute applies unconditionally. */
|
|
18
6
|
export declare function attrMatches<T extends RuleConfigValue, O extends PlainData>(node: Element<T, O>, condition: Attribute['condition']): boolean;
|
|
19
7
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* @param needle - The string to test
|
|
25
|
-
* @param pattern - A plain string or a regex literal string (e.g. `/^foo/i`)
|
|
26
|
-
* @returns `true` if the needle matches the pattern
|
|
8
|
+
* Conditions are evaluated against literal attribute values, so when a referenced
|
|
9
|
+
* attribute's value is dynamic (template-interpolated) the condition result is
|
|
10
|
+
* indeterminate and must not be used to report a violation.
|
|
27
11
|
*/
|
|
12
|
+
export declare function conditionDependsOnDynamicAttr<T extends RuleConfigValue, O extends PlainData>(node: Element<T, O>, condition: NonNullable<Attribute['condition']>): boolean;
|
|
13
|
+
/** `pattern` is a regex literal of the form `/pattern/flags` if it matches that shape, otherwise an exact string. */
|
|
28
14
|
export declare function match(needle: string, pattern: string): boolean;
|
|
29
15
|
/**
|
|
30
16
|
* PotentialCustomElementName
|
|
@@ -42,127 +28,20 @@ export declare function match(needle: string, pattern: string): boolean;
|
|
|
42
28
|
* Originally, it is not possible to define a name including ASCII upper alphas in the custom element, but it is not treated as illegal by the HTML parser.
|
|
43
29
|
*/
|
|
44
30
|
export declare const rePCENChar: string;
|
|
45
|
-
/**
|
|
46
|
-
* Validates an attribute name/value pair against its specification.
|
|
47
|
-
* Checks attribute existence in the spec, value validity, conditional applicability,
|
|
48
|
-
* and skips validation for dynamic (template-interpolated) values when the error
|
|
49
|
-
* relates to an invalid value.
|
|
50
|
-
*
|
|
51
|
-
* @param t - The i18n translator for generating localized error messages
|
|
52
|
-
* @param name - The attribute name to validate
|
|
53
|
-
* @param value - The attribute value to validate
|
|
54
|
-
* @param isDynamicValue - Whether the value is dynamic (e.g. from a template expression);
|
|
55
|
-
* if `true`, invalid-value errors are suppressed
|
|
56
|
-
* @param node - The element that owns the attribute
|
|
57
|
-
* @param attrSpecs - The list of attribute specifications to validate against
|
|
58
|
-
* @param log - Optional debug logger for diagnostic output
|
|
59
|
-
* @returns `false` if valid, or an `Invalid` object (or array of them) describing the violation
|
|
60
|
-
*/
|
|
61
|
-
export declare function isValidAttr(t: Translator, name: string, value: string, isDynamicValue: boolean, node: Element<any, any>, attrSpecs: readonly Attribute[], log?: Log): false | {
|
|
62
|
-
invalidType: "non-existent" | "invalid-value" | "disallowed-attr";
|
|
63
|
-
message: string;
|
|
64
|
-
loc?: {
|
|
65
|
-
raw: string;
|
|
66
|
-
line: number;
|
|
67
|
-
col: number;
|
|
68
|
-
};
|
|
69
|
-
} | {
|
|
70
|
-
invalidType: "invalid-value";
|
|
71
|
-
message: string;
|
|
72
|
-
loc?: {
|
|
73
|
-
raw: string;
|
|
74
|
-
line: number;
|
|
75
|
-
col: number;
|
|
76
|
-
};
|
|
77
|
-
}[];
|
|
78
|
-
/**
|
|
79
|
-
* Normalizes an attribute value according to its specification rules.
|
|
80
|
-
* Applies case-folding, whitespace trimming, and separator normalization
|
|
81
|
-
* based on the attribute type definition.
|
|
82
|
-
*
|
|
83
|
-
* @param value - The raw attribute value to normalize
|
|
84
|
-
* @param spec - The attribute specification that defines normalization rules
|
|
85
|
-
* (case sensitivity, separator type, whitespace handling)
|
|
86
|
-
* @returns The normalized attribute value
|
|
87
|
-
*/
|
|
88
31
|
export declare function toNormalizedValue(value: string, spec: Attribute): string;
|
|
89
|
-
/**
|
|
90
|
-
* Determines whether an element's accessible name may change at runtime.
|
|
91
|
-
* Returns `true` if the element itself has mutable attributes or children,
|
|
92
|
-
* or if an associated `<label>` element has mutable content.
|
|
93
|
-
*
|
|
94
|
-
* @param el - The element whose accessible name stability is being checked
|
|
95
|
-
* @param document - The document containing the element, used to locate associated labels
|
|
96
|
-
* @returns `true` if the accessible name could change dynamically, `false` otherwise
|
|
97
|
-
*/
|
|
98
32
|
export declare function accnameMayBeMutable(el: Element<any, any>, document: Document<any, any>): boolean;
|
|
99
33
|
export declare const labelable: string[];
|
|
100
|
-
/**
|
|
101
|
-
* Finds the `<label>` element associated with a labelable form element.
|
|
102
|
-
* First checks for an ancestor `<label>`, then looks for a `<label>` whose
|
|
103
|
-
* `for` attribute references the element's `id`. Returns `null` if the
|
|
104
|
-
* element is not labelable or no associated label is found.
|
|
105
|
-
*
|
|
106
|
-
* @template V - The rule configuration value type
|
|
107
|
-
* @template O - The rule options type
|
|
108
|
-
* @param el - The element to find a label for (must be a labelable element)
|
|
109
|
-
* @param document - The document to search for labels with a matching `for` attribute
|
|
110
|
-
* @returns The associated `<label>` element, or `null` if none is found
|
|
111
|
-
*/
|
|
112
34
|
export declare function getOwnedLabel<V extends RuleConfigValue, O extends PlainData>(el: Element<V, O>, document: Document<V, O>): Element<V, O> | null;
|
|
113
|
-
/**
|
|
114
|
-
* A generic, null-safe collection backed by a `Set`.
|
|
115
|
-
* Automatically filters out `null` and `undefined` values when items are added.
|
|
116
|
-
* Implements the iterable protocol so it can be used in `for...of` loops.
|
|
117
|
-
*
|
|
118
|
-
* @template T - The type of items stored in the collection
|
|
119
|
-
*/
|
|
35
|
+
/** `null`/`undefined` items are silently dropped on add. */
|
|
120
36
|
export declare class Collection<T> {
|
|
121
37
|
#private;
|
|
122
|
-
/**
|
|
123
|
-
* Creates a new collection, optionally pre-populated with the given items.
|
|
124
|
-
* Any `null` or `undefined` values are silently ignored.
|
|
125
|
-
*
|
|
126
|
-
* @param items - Initial items to add to the collection
|
|
127
|
-
*/
|
|
128
38
|
constructor(...items: readonly (T | null | undefined)[]);
|
|
129
|
-
/**
|
|
130
|
-
* Returns an iterator over the items in the collection.
|
|
131
|
-
*
|
|
132
|
-
* @returns An iterator that yields each item in insertion order
|
|
133
|
-
*/
|
|
134
39
|
[Symbol.iterator](): Iterator<T>;
|
|
135
|
-
/**
|
|
136
|
-
* Adds one or more items to the collection.
|
|
137
|
-
* Any `null` or `undefined` values are silently ignored.
|
|
138
|
-
*
|
|
139
|
-
* @param items - Items to add to the collection
|
|
140
|
-
*/
|
|
141
40
|
add(...items: readonly (T | null | undefined)[]): void;
|
|
142
|
-
/**
|
|
143
|
-
* Returns a frozen array snapshot of the collection's contents.
|
|
144
|
-
*
|
|
145
|
-
* @returns A read-only array containing all items in insertion order
|
|
146
|
-
*/
|
|
147
41
|
toArray(): readonly T[];
|
|
148
42
|
}
|
|
149
|
-
/**
|
|
150
|
-
* Creates a deep, writable copy of the given value using structured cloning.
|
|
151
|
-
* Strips read-only modifiers from the result type so the clone can be freely mutated.
|
|
152
|
-
*
|
|
153
|
-
* @template T - The type of the value to clone
|
|
154
|
-
* @param value - The value to deep-copy
|
|
155
|
-
* @returns A mutable deep clone of the input value
|
|
156
|
-
*/
|
|
43
|
+
/** Strips read-only modifiers from the result type so the clone can be freely mutated. */
|
|
157
44
|
export declare function deepCopy<T>(value: T): WritableDeep<T>;
|
|
158
|
-
/**
|
|
159
|
-
* Creates a fix that removes an entire attribute (name + value + surrounding whitespace).
|
|
160
|
-
* Used by rules that need to remove a whole attribute from an element.
|
|
161
|
-
*
|
|
162
|
-
* @param fixer - The rule fixer instance for building TextEdits
|
|
163
|
-
* @param attr - The attribute token parts to remove (from `spacesBeforeName` through `endQuote`)
|
|
164
|
-
* @returns A TextEdit (or empty array if no valid tokens exist) that removes the attribute
|
|
165
|
-
*/
|
|
166
45
|
export declare function removeAttr(fixer: IRuleFixer, attr: {
|
|
167
46
|
readonly spacesBeforeName: FixToken | null;
|
|
168
47
|
readonly nameNode: FixToken | null;
|
|
@@ -173,15 +52,6 @@ export declare function removeAttr(fixer: IRuleFixer, attr: {
|
|
|
173
52
|
readonly valueNode: FixToken | null;
|
|
174
53
|
readonly endQuote: FixToken | null;
|
|
175
54
|
}): TextEdit | TextEdit[];
|
|
176
|
-
/**
|
|
177
|
-
* Creates a fix that removes only the value portion of an attribute
|
|
178
|
-
* (equals sign, quotes, and value), keeping the attribute name.
|
|
179
|
-
* Used by `no-boolean-attr-value` to convert `disabled="disabled"` to `disabled`.
|
|
180
|
-
*
|
|
181
|
-
* @param fixer - The rule fixer instance for building TextEdits
|
|
182
|
-
* @param attr - The attribute token parts to remove (from `spacesBeforeEqual` through `endQuote`)
|
|
183
|
-
* @returns A TextEdit (or empty array if no valid tokens exist) that removes the value portion
|
|
184
|
-
*/
|
|
185
55
|
export declare function removeAttrValue(fixer: IRuleFixer, attr: {
|
|
186
56
|
readonly spacesBeforeEqual: FixToken | null;
|
|
187
57
|
readonly equal: FixToken | null;
|