@markuplint/rules 4.11.2 → 5.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -2
- package/SKILL.md +76 -0
- package/lib/attr-check.d.ts +46 -7
- package/lib/attr-check.js +42 -8
- package/lib/attr-duplication/index.d.ts +7 -0
- package/lib/attr-duplication/index.js +7 -0
- package/lib/attr-duplication/meta.d.ts +1 -0
- package/lib/attr-duplication/meta.js +1 -0
- package/lib/attr-value-quotes/index.d.ts +10 -0
- package/lib/attr-value-quotes/index.js +10 -0
- package/lib/attr-value-quotes/meta.d.ts +1 -0
- package/lib/attr-value-quotes/meta.js +1 -0
- package/lib/case-sensitive-attr-name/index.d.ts +9 -0
- package/lib/case-sensitive-attr-name/index.js +8 -0
- package/lib/case-sensitive-attr-name/meta.d.ts +1 -0
- package/lib/case-sensitive-attr-name/meta.js +1 -0
- package/lib/case-sensitive-tag-name/index.d.ts +9 -0
- package/lib/case-sensitive-tag-name/index.js +8 -0
- package/lib/case-sensitive-tag-name/meta.d.ts +1 -0
- package/lib/case-sensitive-tag-name/meta.js +1 -0
- package/lib/character-reference/index.d.ts +9 -0
- package/lib/character-reference/index.js +20 -0
- package/lib/character-reference/meta.d.ts +1 -0
- package/lib/character-reference/meta.js +1 -0
- package/lib/class-naming/index.d.ts +9 -0
- package/lib/class-naming/index.js +8 -0
- package/lib/class-naming/meta.d.ts +1 -0
- package/lib/class-naming/meta.js +1 -0
- package/lib/correct-aspect-ratio/index.d.ts +5 -0
- package/lib/correct-aspect-ratio/index.js +80 -0
- package/lib/correct-aspect-ratio/meta.d.ts +4 -0
- package/lib/correct-aspect-ratio/meta.js +3 -0
- package/lib/correct-aspect-ratio/resolve-image-size.d.ts +24 -0
- package/lib/correct-aspect-ratio/resolve-image-size.js +165 -0
- package/lib/create-message.d.ts +29 -2
- package/lib/create-message.js +60 -2
- package/lib/debug.d.ts +9 -0
- package/lib/debug.js +5 -0
- package/lib/deprecated-attr/index.d.ts +6 -0
- package/lib/deprecated-attr/index.js +6 -0
- package/lib/deprecated-attr/meta.d.ts +1 -0
- package/lib/deprecated-attr/meta.js +1 -0
- package/lib/deprecated-element/index.d.ts +6 -0
- package/lib/deprecated-element/index.js +8 -2
- package/lib/deprecated-element/meta.d.ts +1 -0
- package/lib/deprecated-element/meta.js +1 -0
- package/lib/disallowed-element/index.d.ts +7 -0
- package/lib/disallowed-element/index.js +7 -0
- package/lib/disallowed-element/meta.d.ts +1 -0
- package/lib/disallowed-element/meta.js +1 -0
- package/lib/doctype/index.d.ts +10 -0
- package/lib/doctype/index.js +8 -0
- package/lib/doctype/meta.d.ts +1 -0
- package/lib/doctype/meta.js +1 -0
- package/lib/end-tag/index.d.ts +7 -0
- package/lib/end-tag/index.js +8 -1
- package/lib/end-tag/meta.d.ts +1 -0
- package/lib/end-tag/meta.js +1 -0
- package/lib/heading-levels/index.d.ts +6 -0
- package/lib/heading-levels/index.js +6 -1
- package/lib/heading-levels/meta.d.ts +1 -0
- package/lib/heading-levels/meta.js +1 -0
- package/lib/helpers.d.ts +105 -0
- package/lib/helpers.js +112 -16
- package/lib/id-duplication/index.d.ts +7 -0
- package/lib/id-duplication/index.js +7 -0
- package/lib/id-duplication/meta.d.ts +1 -0
- package/lib/id-duplication/meta.js +1 -0
- package/lib/index.d.ts +43 -41
- package/lib/index.js +24 -0
- package/lib/ineffective-attr/index.d.ts +7 -0
- package/lib/ineffective-attr/index.js +7 -0
- package/lib/ineffective-attr/meta.d.ts +1 -0
- package/lib/ineffective-attr/meta.js +1 -0
- package/lib/invalid-attr/index.d.ts +29 -21
- package/lib/invalid-attr/index.js +60 -109
- package/lib/invalid-attr/meta.d.ts +1 -0
- package/lib/invalid-attr/meta.js +1 -0
- package/lib/label-has-control/index.d.ts +7 -0
- package/lib/label-has-control/index.js +11 -0
- package/lib/label-has-control/meta.d.ts +1 -0
- package/lib/label-has-control/meta.js +1 -0
- package/lib/landmark-roles/index.d.ts +14 -0
- package/lib/landmark-roles/index.js +21 -0
- package/lib/landmark-roles/meta.d.ts +1 -0
- package/lib/landmark-roles/meta.js +1 -0
- package/lib/link-types/index.d.ts +10 -0
- package/lib/link-types/index.js +180 -0
- package/lib/link-types/meta.d.ts +5 -0
- package/lib/link-types/meta.js +4 -0
- package/lib/neighbor-popovers/index.d.ts +8 -0
- package/lib/neighbor-popovers/index.js +28 -6
- package/lib/neighbor-popovers/meta.d.ts +1 -0
- package/lib/neighbor-popovers/meta.js +1 -0
- package/lib/no-ambiguous-navigable-target-names/index.d.ts +8 -0
- package/lib/no-ambiguous-navigable-target-names/index.js +8 -0
- package/lib/no-ambiguous-navigable-target-names/meta.d.ts +1 -0
- package/lib/no-ambiguous-navigable-target-names/meta.js +1 -0
- package/lib/no-boolean-attr-value/index.d.ts +7 -0
- package/lib/no-boolean-attr-value/index.js +7 -0
- package/lib/no-boolean-attr-value/meta.d.ts +1 -0
- package/lib/no-boolean-attr-value/meta.js +1 -0
- package/lib/no-consecutive-br/index.d.ts +8 -0
- package/lib/no-consecutive-br/index.js +8 -0
- package/lib/no-consecutive-br/meta.d.ts +1 -0
- package/lib/no-consecutive-br/meta.js +1 -0
- package/lib/no-default-value/index.d.ts +7 -0
- package/lib/no-default-value/index.js +7 -0
- package/lib/no-default-value/meta.d.ts +1 -0
- package/lib/no-default-value/meta.js +1 -0
- package/lib/no-duplicate-dt/index.d.ts +6 -0
- package/lib/no-duplicate-dt/index.js +6 -0
- package/lib/no-duplicate-dt/meta.d.ts +1 -0
- package/lib/no-duplicate-dt/meta.js +1 -0
- package/lib/no-empty-palpable-content/index.d.ts +13 -0
- package/lib/no-empty-palpable-content/index.js +12 -0
- package/lib/no-empty-palpable-content/meta.d.ts +1 -0
- package/lib/no-empty-palpable-content/meta.js +1 -0
- package/lib/no-hard-code-id/index.d.ts +8 -0
- package/lib/no-hard-code-id/index.js +8 -0
- package/lib/no-hard-code-id/meta.d.ts +1 -0
- package/lib/no-hard-code-id/meta.js +1 -0
- package/lib/no-orphaned-end-tag/index.d.ts +7 -0
- package/lib/no-orphaned-end-tag/index.js +8 -2
- package/lib/no-orphaned-end-tag/meta.d.ts +1 -0
- package/lib/no-orphaned-end-tag/meta.js +1 -0
- package/lib/no-refer-to-non-existent-id/index.d.ts +9 -1
- package/lib/no-refer-to-non-existent-id/index.js +11 -2
- package/lib/no-refer-to-non-existent-id/meta.d.ts +1 -0
- package/lib/no-refer-to-non-existent-id/meta.js +1 -0
- package/lib/no-unsupported-features/compat-data.d.ts +71 -0
- package/lib/no-unsupported-features/compat-data.js +204 -0
- package/lib/no-unsupported-features/index.d.ts +24 -0
- package/lib/no-unsupported-features/index.js +139 -0
- package/lib/no-unsupported-features/meta.d.ts +5 -0
- package/lib/no-unsupported-features/meta.js +4 -0
- package/lib/no-unsupported-features/resolve-browsers.d.ts +30 -0
- package/lib/no-unsupported-features/resolve-browsers.js +125 -0
- package/lib/no-use-event-handler-attr/index.d.ts +10 -0
- package/lib/no-use-event-handler-attr/index.js +8 -0
- package/lib/no-use-event-handler-attr/meta.d.ts +1 -0
- package/lib/no-use-event-handler-attr/meta.js +1 -0
- package/lib/permitted-contents/choice.d.ts +17 -0
- package/lib/permitted-contents/choice.js +31 -1
- package/lib/permitted-contents/complex-branch.d.ts +11 -7
- package/lib/permitted-contents/complex-branch.js +11 -7
- package/lib/permitted-contents/content-model.d.ts +11 -0
- package/lib/permitted-contents/content-model.js +32 -0
- package/lib/permitted-contents/count-pattern.d.ts +13 -7
- package/lib/permitted-contents/count-pattern.js +24 -8
- package/lib/permitted-contents/debug.browser.d.ts +12 -0
- package/lib/permitted-contents/debug.browser.js +12 -0
- package/lib/permitted-contents/debug.d.ts +12 -0
- package/lib/permitted-contents/debug.js +12 -0
- package/lib/permitted-contents/index.d.ts +12 -0
- package/lib/permitted-contents/index.js +21 -0
- package/lib/permitted-contents/matches-selector.d.ts +19 -0
- package/lib/permitted-contents/matches-selector.js +33 -0
- package/lib/permitted-contents/meta.d.ts +1 -0
- package/lib/permitted-contents/meta.js +1 -0
- package/lib/permitted-contents/order.d.ts +14 -7
- package/lib/permitted-contents/order.js +15 -8
- package/lib/permitted-contents/recursive-branch.d.ts +17 -0
- package/lib/permitted-contents/recursive-branch.js +17 -0
- package/lib/permitted-contents/represent-transparent-nodes.d.ts +54 -0
- package/lib/permitted-contents/represent-transparent-nodes.js +119 -12
- package/lib/permitted-contents/start.d.ts +12 -6
- package/lib/permitted-contents/start.js +12 -6
- package/lib/permitted-contents/transparent.d.ts +12 -0
- package/lib/permitted-contents/transparent.js +12 -0
- package/lib/permitted-contents/types.d.ts +67 -0
- package/lib/permitted-contents/utils.d.ts +160 -0
- package/lib/permitted-contents/utils.js +216 -35
- package/lib/placeholder-label-option/index.d.ts +7 -0
- package/lib/placeholder-label-option/index.js +19 -15
- package/lib/placeholder-label-option/meta.d.ts +1 -0
- package/lib/placeholder-label-option/meta.js +1 -0
- package/lib/redundant-accessible-name/index.d.ts +10 -0
- package/lib/redundant-accessible-name/index.js +123 -0
- package/lib/redundant-accessible-name/meta.d.ts +5 -0
- package/lib/redundant-accessible-name/meta.js +4 -0
- package/lib/require-accessible-name/index.d.ts +10 -4
- package/lib/require-accessible-name/index.js +13 -5
- package/lib/require-accessible-name/meta.d.ts +1 -0
- package/lib/require-accessible-name/meta.js +1 -0
- package/lib/require-datetime/index.d.ts +12 -0
- package/lib/require-datetime/index.js +8 -0
- package/lib/require-datetime/meta.d.ts +1 -0
- package/lib/require-datetime/meta.js +1 -0
- package/lib/require-datetime/types.d.ts +7 -0
- package/lib/require-datetime/utils.d.ts +18 -5
- package/lib/require-datetime/utils.js +53 -9
- package/lib/require-dialog-autofocus/index.d.ts +22 -0
- package/lib/require-dialog-autofocus/index.js +62 -0
- package/lib/require-dialog-autofocus/meta.d.ts +5 -0
- package/lib/require-dialog-autofocus/meta.js +4 -0
- package/lib/required-attr/index.d.ts +21 -1
- package/lib/required-attr/index.js +34 -4
- package/lib/required-attr/meta.d.ts +1 -0
- package/lib/required-attr/meta.js +1 -0
- package/lib/required-element/index.d.ts +14 -0
- package/lib/required-element/index.js +14 -2
- package/lib/required-element/meta.d.ts +1 -0
- package/lib/required-element/meta.js +1 -0
- package/lib/required-h1/index.d.ts +12 -0
- package/lib/required-h1/index.js +7 -0
- package/lib/required-h1/meta.d.ts +1 -0
- package/lib/required-h1/meta.js +1 -0
- package/lib/srcset-sizes-constraint/index.d.ts +6 -0
- package/lib/srcset-sizes-constraint/index.js +108 -0
- package/lib/srcset-sizes-constraint/meta.d.ts +5 -0
- package/lib/srcset-sizes-constraint/meta.js +4 -0
- package/lib/srcset-sizes-constraint/parse-srcset.d.ts +40 -0
- package/lib/srcset-sizes-constraint/parse-srcset.js +56 -0
- package/lib/table-row-column-alignment/find-children.d.ts +10 -0
- package/lib/table-row-column-alignment/find-children.js +11 -0
- package/lib/table-row-column-alignment/grid.d.ts +60 -0
- package/lib/table-row-column-alignment/grid.js +104 -26
- package/lib/table-row-column-alignment/index.d.ts +8 -0
- package/lib/table-row-column-alignment/index.js +8 -0
- package/lib/table-row-column-alignment/meta.d.ts +1 -0
- package/lib/table-row-column-alignment/meta.js +1 -0
- package/lib/table-row-column-alignment/types.d.ts +10 -0
- package/lib/use-list/index.d.ts +16 -0
- package/lib/use-list/index.js +20 -0
- package/lib/use-list/meta.d.ts +1 -0
- package/lib/use-list/meta.js +1 -0
- package/lib/wai-aria/checkings/abstract-role.d.ts +9 -0
- package/lib/wai-aria/checkings/abstract-role.js +14 -2
- package/lib/wai-aria/checkings/default-value.d.ts +11 -0
- package/lib/wai-aria/checkings/default-value.js +11 -0
- package/lib/wai-aria/checkings/deprecated-props.d.ts +11 -0
- package/lib/wai-aria/checkings/deprecated-props.js +11 -0
- package/lib/wai-aria/checkings/deprecated-role.d.ts +10 -0
- package/lib/wai-aria/checkings/deprecated-role.js +10 -0
- package/lib/wai-aria/checkings/disallowed-prop.d.ts +14 -0
- package/lib/wai-aria/checkings/disallowed-prop.js +19 -2
- package/lib/wai-aria/checkings/implicit-props.d.ts +13 -0
- package/lib/wai-aria/checkings/implicit-props.js +13 -0
- package/lib/wai-aria/checkings/implicit-role.d.ts +9 -0
- package/lib/wai-aria/checkings/implicit-role.js +14 -2
- package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +9 -0
- package/lib/wai-aria/checkings/interaction-in-hidden.js +15 -4
- package/lib/wai-aria/checkings/no-global-prop.d.ts +10 -0
- package/lib/wai-aria/checkings/no-global-prop.js +10 -0
- package/lib/wai-aria/checkings/non-existent-role.d.ts +11 -0
- package/lib/wai-aria/checkings/non-existent-role.js +19 -2
- package/lib/wai-aria/checkings/permitted-roles.d.ts +10 -0
- package/lib/wai-aria/checkings/permitted-roles.js +15 -2
- package/lib/wai-aria/checkings/presentational-children.d.ts +7 -1
- package/lib/wai-aria/checkings/presentational-children.js +17 -3
- package/lib/wai-aria/checkings/required-accessibility-parent-role.d.ts +25 -0
- package/lib/wai-aria/checkings/required-accessibility-parent-role.js +56 -0
- package/lib/wai-aria/checkings/required-owned-elements.d.ts +10 -1
- package/lib/wai-aria/checkings/required-owned-elements.js +69 -25
- package/lib/wai-aria/checkings/required-prop.d.ts +13 -0
- package/lib/wai-aria/checkings/required-prop.js +18 -2
- package/lib/wai-aria/checkings/value.d.ts +23 -0
- package/lib/wai-aria/checkings/value.js +32 -0
- package/lib/wai-aria/index.d.ts +10 -0
- package/lib/wai-aria/index.js +22 -4
- package/lib/wai-aria/meta.d.ts +1 -0
- package/lib/wai-aria/meta.js +1 -0
- package/lib/wai-aria/types.d.ts +25 -1
- package/package.json +16 -11
- package/schema.json +18 -0
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { createRule } from '@markuplint/ml-core';
|
|
2
2
|
import meta from './meta.js';
|
|
3
|
+
/**
|
|
4
|
+
* Rule that validates heading levels (h1-h6) are not skipped.
|
|
5
|
+
*
|
|
6
|
+
* Ensures that heading elements appear in a sequential order without
|
|
7
|
+
* gaps (e.g., an h4 must not follow an h2 directly without an h3 in between).
|
|
8
|
+
*/
|
|
3
9
|
export default createRule({
|
|
4
10
|
meta: meta,
|
|
5
|
-
defaultValue: true,
|
|
6
11
|
defaultOptions: null,
|
|
7
12
|
verify({ document, report, t }) {
|
|
8
13
|
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
package/lib/helpers.d.ts
CHANGED
|
@@ -4,7 +4,27 @@ import type { PlainData } from '@markuplint/ml-config';
|
|
|
4
4
|
import type { Element, RuleConfigValue, Document } from '@markuplint/ml-core';
|
|
5
5
|
import type { Attribute } from '@markuplint/ml-spec';
|
|
6
6
|
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
|
+
*/
|
|
7
18
|
export declare function attrMatches<T extends RuleConfigValue, O extends PlainData>(node: Element<T, O>, condition: Attribute['condition']): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Tests whether a string matches a given pattern. The pattern can be either
|
|
21
|
+
* a plain string (tested for exact equality) or a regular expression literal
|
|
22
|
+
* in the form `/pattern/flags`.
|
|
23
|
+
*
|
|
24
|
+
* @param needle - The string to test
|
|
25
|
+
* @param pattern - A plain string or a regex literal string (e.g. `/^foo/i`)
|
|
26
|
+
* @returns `true` if the needle matches the pattern
|
|
27
|
+
*/
|
|
8
28
|
export declare function match(needle: string, pattern: string): boolean;
|
|
9
29
|
/**
|
|
10
30
|
* PotentialCustomElementName
|
|
@@ -22,6 +42,22 @@ export declare function match(needle: string, pattern: string): boolean;
|
|
|
22
42
|
* 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.
|
|
23
43
|
*/
|
|
24
44
|
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
|
+
*/
|
|
25
61
|
export declare function isValidAttr(t: Translator, name: string, value: string, isDynamicValue: boolean, node: Element<any, any>, attrSpecs: readonly Attribute[], log?: Log): false | {
|
|
26
62
|
invalidType: "non-existent" | "invalid-value" | "disallowed-attr";
|
|
27
63
|
message: string;
|
|
@@ -39,14 +75,83 @@ export declare function isValidAttr(t: Translator, name: string, value: string,
|
|
|
39
75
|
col: number;
|
|
40
76
|
};
|
|
41
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
|
+
*/
|
|
42
88
|
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
|
+
*/
|
|
43
98
|
export declare function accnameMayBeMutable(el: Element<any, any>, document: Document<any, any>): boolean;
|
|
99
|
+
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
|
+
*/
|
|
44
112
|
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
|
+
*/
|
|
45
120
|
export declare class Collection<T> {
|
|
46
121
|
#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
|
+
*/
|
|
47
128
|
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
|
+
*/
|
|
48
134
|
[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
|
+
*/
|
|
49
141
|
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
|
+
*/
|
|
50
147
|
toArray(): readonly T[];
|
|
51
148
|
}
|
|
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
|
+
*/
|
|
52
157
|
export declare function deepCopy<T>(value: T): WritableDeep<T>;
|
package/lib/helpers.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
-
};
|
|
6
|
-
var _Collection_items;
|
|
7
|
-
// @ts-ignore
|
|
8
|
-
import structuredClone from '@ungap/structured-clone';
|
|
9
1
|
import { attrCheck } from './attr-check.js';
|
|
2
|
+
/**
|
|
3
|
+
* Tests whether an element matches the condition specified in an attribute spec.
|
|
4
|
+
* When the condition is `null` or `undefined`, the element is considered to match unconditionally.
|
|
5
|
+
*
|
|
6
|
+
* @template T - The rule configuration value type
|
|
7
|
+
* @template O - The rule options type
|
|
8
|
+
* @param node - The element to test against the condition
|
|
9
|
+
* @param condition - A CSS selector string or array of selector strings from the attribute specification;
|
|
10
|
+
* if `null`/`undefined`, the function returns `true`
|
|
11
|
+
* @returns `true` if the element matches the condition (or no condition is given), `false` otherwise
|
|
12
|
+
*/
|
|
10
13
|
export function attrMatches(
|
|
11
14
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
12
15
|
node, condition) {
|
|
@@ -16,6 +19,15 @@ node, condition) {
|
|
|
16
19
|
const condSelector = typeof condition === 'string' ? condition : condition.join(',');
|
|
17
20
|
return node.matches(condSelector);
|
|
18
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Tests whether a string matches a given pattern. The pattern can be either
|
|
24
|
+
* a plain string (tested for exact equality) or a regular expression literal
|
|
25
|
+
* in the form `/pattern/flags`.
|
|
26
|
+
*
|
|
27
|
+
* @param needle - The string to test
|
|
28
|
+
* @param pattern - A plain string or a regex literal string (e.g. `/^foo/i`)
|
|
29
|
+
* @returns `true` if the needle matches the pattern
|
|
30
|
+
*/
|
|
19
31
|
export function match(needle, pattern) {
|
|
20
32
|
const matches = pattern.match(/^\/(.*)\/([gim])*$/);
|
|
21
33
|
if (matches && matches[1]) {
|
|
@@ -60,15 +72,31 @@ export const rePCENChar = [
|
|
|
60
72
|
'[\uFDF0-\uFFFD]',
|
|
61
73
|
'[\uD800-\uDBFF][\uDC00-\uDFFF]',
|
|
62
74
|
].join('|');
|
|
75
|
+
/**
|
|
76
|
+
* Validates an attribute name/value pair against its specification.
|
|
77
|
+
* Checks attribute existence in the spec, value validity, conditional applicability,
|
|
78
|
+
* and skips validation for dynamic (template-interpolated) values when the error
|
|
79
|
+
* relates to an invalid value.
|
|
80
|
+
*
|
|
81
|
+
* @param t - The i18n translator for generating localized error messages
|
|
82
|
+
* @param name - The attribute name to validate
|
|
83
|
+
* @param value - The attribute value to validate
|
|
84
|
+
* @param isDynamicValue - Whether the value is dynamic (e.g. from a template expression);
|
|
85
|
+
* if `true`, invalid-value errors are suppressed
|
|
86
|
+
* @param node - The element that owns the attribute
|
|
87
|
+
* @param attrSpecs - The list of attribute specifications to validate against
|
|
88
|
+
* @param log - Optional debug logger for diagnostic output
|
|
89
|
+
* @returns `false` if valid, or an `Invalid` object (or array of them) describing the violation
|
|
90
|
+
*/
|
|
63
91
|
export function isValidAttr(t, name, value, isDynamicValue,
|
|
64
92
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
65
93
|
node, attrSpecs,
|
|
66
94
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
67
95
|
log) {
|
|
68
|
-
let invalid = false;
|
|
69
96
|
const spec = attrSpecs.find(s => s.name.toLowerCase() === name.toLowerCase());
|
|
70
97
|
log?.('Spec of the %s attr: %o', name, spec);
|
|
71
|
-
|
|
98
|
+
const allAttrNames = attrSpecs.map(s => s.name);
|
|
99
|
+
let invalid = attrCheck(t, name, value, false, spec, allAttrNames);
|
|
72
100
|
if (invalid === false &&
|
|
73
101
|
spec &&
|
|
74
102
|
spec.condition != null &&
|
|
@@ -84,6 +112,16 @@ log) {
|
|
|
84
112
|
}
|
|
85
113
|
return invalid;
|
|
86
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Normalizes an attribute value according to its specification rules.
|
|
117
|
+
* Applies case-folding, whitespace trimming, and separator normalization
|
|
118
|
+
* based on the attribute type definition.
|
|
119
|
+
*
|
|
120
|
+
* @param value - The raw attribute value to normalize
|
|
121
|
+
* @param spec - The attribute specification that defines normalization rules
|
|
122
|
+
* (case sensitivity, separator type, whitespace handling)
|
|
123
|
+
* @returns The normalized attribute value
|
|
124
|
+
*/
|
|
87
125
|
export function toNormalizedValue(value, spec) {
|
|
88
126
|
let normalized = value;
|
|
89
127
|
if (!spec.caseSensitive) {
|
|
@@ -112,6 +150,15 @@ export function toNormalizedValue(value, spec) {
|
|
|
112
150
|
}
|
|
113
151
|
return normalized;
|
|
114
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Determines whether an element's accessible name may change at runtime.
|
|
155
|
+
* Returns `true` if the element itself has mutable attributes or children,
|
|
156
|
+
* or if an associated `<label>` element has mutable content.
|
|
157
|
+
*
|
|
158
|
+
* @param el - The element whose accessible name stability is being checked
|
|
159
|
+
* @param document - The document containing the element, used to locate associated labels
|
|
160
|
+
* @returns `true` if the accessible name could change dynamically, `false` otherwise
|
|
161
|
+
*/
|
|
115
162
|
export function accnameMayBeMutable(
|
|
116
163
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
117
164
|
el,
|
|
@@ -126,7 +173,19 @@ document) {
|
|
|
126
173
|
}
|
|
127
174
|
return false;
|
|
128
175
|
}
|
|
129
|
-
const labelable = ['button', 'input:not([type=hidden])', 'meter', 'output', 'progress', 'select', 'textarea'];
|
|
176
|
+
export const labelable = ['button', 'input:not([type=hidden])', 'meter', 'output', 'progress', 'select', 'textarea'];
|
|
177
|
+
/**
|
|
178
|
+
* Finds the `<label>` element associated with a labelable form element.
|
|
179
|
+
* First checks for an ancestor `<label>`, then looks for a `<label>` whose
|
|
180
|
+
* `for` attribute references the element's `id`. Returns `null` if the
|
|
181
|
+
* element is not labelable or no associated label is found.
|
|
182
|
+
*
|
|
183
|
+
* @template V - The rule configuration value type
|
|
184
|
+
* @template O - The rule options type
|
|
185
|
+
* @param el - The element to find a label for (must be a labelable element)
|
|
186
|
+
* @param document - The document to search for labels with a matching `for` attribute
|
|
187
|
+
* @returns The associated `<label>` element, or `null` if none is found
|
|
188
|
+
*/
|
|
130
189
|
export function getOwnedLabel(
|
|
131
190
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
132
191
|
el,
|
|
@@ -144,26 +203,63 @@ document) {
|
|
|
144
203
|
}
|
|
145
204
|
return ownedLabel;
|
|
146
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* A generic, null-safe collection backed by a `Set`.
|
|
208
|
+
* Automatically filters out `null` and `undefined` values when items are added.
|
|
209
|
+
* Implements the iterable protocol so it can be used in `for...of` loops.
|
|
210
|
+
*
|
|
211
|
+
* @template T - The type of items stored in the collection
|
|
212
|
+
*/
|
|
147
213
|
export class Collection {
|
|
214
|
+
#items = new Set();
|
|
215
|
+
/**
|
|
216
|
+
* Creates a new collection, optionally pre-populated with the given items.
|
|
217
|
+
* Any `null` or `undefined` values are silently ignored.
|
|
218
|
+
*
|
|
219
|
+
* @param items - Initial items to add to the collection
|
|
220
|
+
*/
|
|
148
221
|
constructor(...items) {
|
|
149
|
-
_Collection_items.set(this, new Set());
|
|
150
222
|
this.add(...items);
|
|
151
223
|
}
|
|
152
|
-
|
|
153
|
-
|
|
224
|
+
/**
|
|
225
|
+
* Returns an iterator over the items in the collection.
|
|
226
|
+
*
|
|
227
|
+
* @returns An iterator that yields each item in insertion order
|
|
228
|
+
*/
|
|
229
|
+
[Symbol.iterator]() {
|
|
230
|
+
return this.#items.values();
|
|
154
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* Adds one or more items to the collection.
|
|
234
|
+
* Any `null` or `undefined` values are silently ignored.
|
|
235
|
+
*
|
|
236
|
+
* @param items - Items to add to the collection
|
|
237
|
+
*/
|
|
155
238
|
add(...items) {
|
|
156
239
|
for (const item of items) {
|
|
157
240
|
if (item == null) {
|
|
158
241
|
continue;
|
|
159
242
|
}
|
|
160
|
-
|
|
243
|
+
this.#items.add(item);
|
|
161
244
|
}
|
|
162
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* Returns a frozen array snapshot of the collection's contents.
|
|
248
|
+
*
|
|
249
|
+
* @returns A read-only array containing all items in insertion order
|
|
250
|
+
*/
|
|
163
251
|
toArray() {
|
|
164
|
-
return Object.freeze([...
|
|
252
|
+
return Object.freeze([...this.#items]);
|
|
165
253
|
}
|
|
166
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Creates a deep, writable copy of the given value using structured cloning.
|
|
257
|
+
* Strips read-only modifiers from the result type so the clone can be freely mutated.
|
|
258
|
+
*
|
|
259
|
+
* @template T - The type of the value to clone
|
|
260
|
+
* @param value - The value to deep-copy
|
|
261
|
+
* @returns A mutable deep clone of the input value
|
|
262
|
+
*/
|
|
167
263
|
export function deepCopy(value) {
|
|
168
264
|
return structuredClone(value);
|
|
169
265
|
}
|
|
@@ -1,2 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule that checks for duplicate `id` attribute values within a document.
|
|
3
|
+
*
|
|
4
|
+
* Walks all elements and collects `id` values, reporting any that have
|
|
5
|
+
* already been seen. Dynamic values and directive attributes are excluded
|
|
6
|
+
* from the check.
|
|
7
|
+
*/
|
|
1
8
|
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
2
9
|
export default _default;
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { createRule } from '@markuplint/ml-core';
|
|
2
2
|
import meta from './meta.js';
|
|
3
|
+
/**
|
|
4
|
+
* Rule that checks for duplicate `id` attribute values within a document.
|
|
5
|
+
*
|
|
6
|
+
* Walks all elements and collects `id` values, reporting any that have
|
|
7
|
+
* already been seen. Dynamic values and directive attributes are excluded
|
|
8
|
+
* from the check.
|
|
9
|
+
*/
|
|
3
10
|
export default createRule({
|
|
4
11
|
meta: meta,
|
|
5
12
|
async verify({ document, report, t }) {
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @markuplint/rules
|
|
3
|
+
*
|
|
4
|
+
* Built-in rules for markuplint. This module exports a registry of all
|
|
5
|
+
* core lint rules that ship with markuplint, keyed by their rule name.
|
|
6
|
+
* Each rule implements the {@link AnyRuleSeed} interface and covers
|
|
7
|
+
* areas such as accessibility, HTML validity, naming conventions, and coding style.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Registry of all built-in markuplint rules, mapping rule names to their seed definitions.
|
|
11
|
+
* Used by the markuplint core to initialize rule instances during linting.
|
|
12
|
+
*/
|
|
1
13
|
declare const rules: {
|
|
2
14
|
readonly 'attr-duplication': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
3
15
|
readonly 'attr-value-quotes': Readonly<import("@markuplint/ml-core").RuleSeed<import("./attr-value-quotes/index.js").Type, undefined>>;
|
|
@@ -5,6 +17,9 @@ declare const rules: {
|
|
|
5
17
|
readonly 'case-sensitive-tag-name': Readonly<import("@markuplint/ml-core").RuleSeed<import("./case-sensitive-tag-name/index.js").Value, undefined>>;
|
|
6
18
|
readonly 'character-reference': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
7
19
|
readonly 'class-naming': Readonly<import("@markuplint/ml-core").RuleSeed<import("./class-naming/index.js").Value, undefined>>;
|
|
20
|
+
readonly 'correct-aspect-ratio': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
21
|
+
readonly documentRoot?: string;
|
|
22
|
+
}>>;
|
|
8
23
|
readonly 'deprecated-attr': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
9
24
|
readonly 'deprecated-element': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
10
25
|
readonly 'disallowed-element': Readonly<import("@markuplint/ml-core").RuleSeed<string[], undefined>>;
|
|
@@ -18,53 +33,23 @@ declare const rules: {
|
|
|
18
33
|
readonly 'invalid-attr': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
19
34
|
allowAttrs?: (string | {
|
|
20
35
|
name: string;
|
|
21
|
-
value: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType | (
|
|
22
|
-
|
|
23
|
-
} | {
|
|
24
|
-
pattern: string;
|
|
25
|
-
} | {
|
|
26
|
-
type: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
27
|
-
});
|
|
28
|
-
})[] | Record<string, {
|
|
29
|
-
enum: [string, ...string[]];
|
|
30
|
-
} | {
|
|
31
|
-
pattern: string;
|
|
32
|
-
} | {
|
|
33
|
-
type: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
34
|
-
}>;
|
|
36
|
+
value: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType | import("packages/@markuplint/types/lib/types.schema.js").Pattern;
|
|
37
|
+
})[] | Record<string, import("packages/@markuplint/ml-spec/lib/index.js").AttributeType | import("packages/@markuplint/types/lib/types.schema.js").Pattern>;
|
|
35
38
|
disallowAttrs?: (string | {
|
|
36
39
|
name: string;
|
|
37
|
-
value: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType | (
|
|
38
|
-
|
|
39
|
-
} | {
|
|
40
|
-
pattern: string;
|
|
41
|
-
} | {
|
|
42
|
-
type: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
43
|
-
});
|
|
44
|
-
})[] | Record<string, {
|
|
45
|
-
enum: [string, ...string[]];
|
|
46
|
-
} | {
|
|
47
|
-
pattern: string;
|
|
48
|
-
} | {
|
|
49
|
-
type: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
50
|
-
}>;
|
|
40
|
+
value: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType | import("packages/@markuplint/types/lib/types.schema.js").Pattern;
|
|
41
|
+
})[] | Record<string, import("packages/@markuplint/ml-spec/lib/index.js").AttributeType | import("packages/@markuplint/types/lib/types.schema.js").Pattern>;
|
|
51
42
|
ignoreAttrNamePrefix?: string | string[];
|
|
52
43
|
allowToAddPropertiesForPretender?: boolean;
|
|
53
|
-
attrs?: Record<string, ({
|
|
54
|
-
enum: [string, ...string[]];
|
|
55
|
-
} | {
|
|
56
|
-
pattern: string;
|
|
57
|
-
} | {
|
|
58
|
-
type: import("packages/@markuplint/ml-spec/lib/index.js").AttributeType;
|
|
59
|
-
}) | {
|
|
60
|
-
disallowed: true;
|
|
61
|
-
}>;
|
|
62
44
|
}>>;
|
|
63
45
|
readonly 'label-has-control': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
64
46
|
readonly 'landmark-roles': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
65
47
|
ignoreRoles: (("banner" | "main" | "complementary" | "contentinfo") | "form" | "navigation" | "region")[];
|
|
66
48
|
labelEachArea: boolean;
|
|
67
49
|
}>>;
|
|
50
|
+
readonly 'link-types': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
51
|
+
readonly allowMicroformats?: boolean | readonly string[];
|
|
52
|
+
}>>;
|
|
68
53
|
readonly 'neighbor-popovers': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
69
54
|
readonly 'no-ambiguous-navigable-target-names': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, undefined>>;
|
|
70
55
|
readonly 'no-boolean-attr-value': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
@@ -78,28 +63,45 @@ declare const rules: {
|
|
|
78
63
|
readonly 'no-hard-code-id': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
79
64
|
readonly 'no-orphaned-end-tag': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, null>>;
|
|
80
65
|
readonly 'no-refer-to-non-existent-id': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, {
|
|
81
|
-
ariaVersion: import("packages/@markuplint/ml-spec/lib/index.js").ARIAVersion;
|
|
66
|
+
ariaVersion: import("packages/@markuplint/ml-spec/lib/index.js").ARIAVersion | undefined;
|
|
82
67
|
fragmentRefersNameAttr: boolean;
|
|
83
68
|
}>>;
|
|
69
|
+
readonly 'no-unsupported-features': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
70
|
+
readonly browserslist?: string | readonly string[];
|
|
71
|
+
readonly browserslistConfig?: string;
|
|
72
|
+
readonly browserslistEnv?: string;
|
|
73
|
+
readonly ignoreFeatures?: readonly string[];
|
|
74
|
+
readonly checkExperimental?: boolean;
|
|
75
|
+
readonly checkNonStandard?: boolean;
|
|
76
|
+
}>>;
|
|
84
77
|
readonly 'no-use-event-handler-attr': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
85
78
|
ignore?: string | string[];
|
|
86
79
|
}>>;
|
|
87
80
|
readonly 'permitted-contents': Readonly<import("@markuplint/ml-core").RuleSeed<import("./permitted-contents/types.js").TagRule[], import("./permitted-contents/types.js").Options>>;
|
|
88
81
|
readonly 'placeholder-label-option': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, undefined>>;
|
|
89
|
-
readonly '
|
|
90
|
-
|
|
82
|
+
readonly 'redundant-accessible-name': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, {
|
|
83
|
+
checkTitleFallback: boolean;
|
|
84
|
+
checkPlaceholderFallback: boolean;
|
|
85
|
+
}>>;
|
|
86
|
+
readonly 'require-accessible-name': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, {
|
|
87
|
+
ariaVersion: import("packages/@markuplint/ml-spec/lib/index.js").ARIAVersion | undefined;
|
|
91
88
|
}>>;
|
|
92
89
|
readonly 'require-datetime': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, {
|
|
93
90
|
langs?: import("./require-datetime/types.js").Lang[];
|
|
94
91
|
}>>;
|
|
92
|
+
readonly 'require-dialog-autofocus': Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
95
93
|
readonly 'required-attr': Readonly<import("@markuplint/ml-core").RuleSeed<string | (string | {
|
|
96
94
|
name: string;
|
|
97
95
|
value?: string | string[];
|
|
98
|
-
})[],
|
|
96
|
+
})[], {
|
|
97
|
+
readonly ignoreAttrs?: readonly string[];
|
|
98
|
+
}>>;
|
|
99
99
|
readonly 'required-element': Readonly<import("@markuplint/ml-core").RuleSeed<string[], {
|
|
100
100
|
ignoreHasMutableContents: boolean;
|
|
101
|
+
ignoreOmittedElements: boolean;
|
|
101
102
|
}>>;
|
|
102
103
|
readonly 'required-h1': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, import("./required-h1/index.js").Options>>;
|
|
104
|
+
readonly 'srcset-sizes-constraint': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, undefined>>;
|
|
103
105
|
readonly 'table-row-column-alignment': Readonly<import("@markuplint/ml-core").RuleSeed<boolean, undefined>>;
|
|
104
106
|
readonly 'use-list': Readonly<import("@markuplint/ml-core").RuleSeed<readonly string[], {
|
|
105
107
|
spaceNeededBullets?: string[];
|
package/lib/index.js
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @markuplint/rules
|
|
3
|
+
*
|
|
4
|
+
* Built-in rules for markuplint. This module exports a registry of all
|
|
5
|
+
* core lint rules that ship with markuplint, keyed by their rule name.
|
|
6
|
+
* Each rule implements the {@link AnyRuleSeed} interface and covers
|
|
7
|
+
* areas such as accessibility, HTML validity, naming conventions, and coding style.
|
|
8
|
+
*/
|
|
1
9
|
import AttrDuplication from './attr-duplication/index.js';
|
|
2
10
|
import AttrValueQuotes from './attr-value-quotes/index.js';
|
|
3
11
|
import CaseSensitiveAttrName from './case-sensitive-attr-name/index.js';
|
|
4
12
|
import CaseSensitiveTagName from './case-sensitive-tag-name/index.js';
|
|
5
13
|
import CharacterReference from './character-reference/index.js';
|
|
14
|
+
import CorrectAspectRatio from './correct-aspect-ratio/index.js';
|
|
6
15
|
import ClassNaming from './class-naming/index.js';
|
|
7
16
|
import DeprecatedAttr from './deprecated-attr/index.js';
|
|
8
17
|
import DeprecatedElement from './deprecated-element/index.js';
|
|
@@ -15,6 +24,7 @@ import IneffectiveAttr from './ineffective-attr/index.js';
|
|
|
15
24
|
import InvalidAttr from './invalid-attr/index.js';
|
|
16
25
|
import LabelHasControl from './label-has-control/index.js';
|
|
17
26
|
import LandmarkRoles from './landmark-roles/index.js';
|
|
27
|
+
import LinkTypes from './link-types/index.js';
|
|
18
28
|
import NeighborPopovers from './neighbor-popovers/index.js';
|
|
19
29
|
import NoAmbiguousNavigableTargetNames from './no-ambiguous-navigable-target-names/index.js';
|
|
20
30
|
import NoBooleanAttrValue from './no-boolean-attr-value/index.js';
|
|
@@ -25,17 +35,25 @@ import NoEmptyPalpableContent from './no-empty-palpable-content/index.js';
|
|
|
25
35
|
import NoHardCodeId from './no-hard-code-id/index.js';
|
|
26
36
|
import NoOrphanedEndTag from './no-orphaned-end-tag/index.js';
|
|
27
37
|
import NoReferToNonExistentId from './no-refer-to-non-existent-id/index.js';
|
|
38
|
+
import NoUnsupportedFeatures from './no-unsupported-features/index.js';
|
|
28
39
|
import NoUseEventHandlerAttr from './no-use-event-handler-attr/index.js';
|
|
29
40
|
import PermittedContents from './permitted-contents/index.js';
|
|
30
41
|
import PlaceholderLabelOption from './placeholder-label-option/index.js';
|
|
42
|
+
import RedundantAccessibleName from './redundant-accessible-name/index.js';
|
|
31
43
|
import RequireAccessibleName from './require-accessible-name/index.js';
|
|
32
44
|
import RequireDatetime from './require-datetime/index.js';
|
|
45
|
+
import RequireDialogAutofocus from './require-dialog-autofocus/index.js';
|
|
46
|
+
import SrcsetSizesConstraint from './srcset-sizes-constraint/index.js';
|
|
33
47
|
import RequiredAttr from './required-attr/index.js';
|
|
34
48
|
import RequiredElement from './required-element/index.js';
|
|
35
49
|
import RequiredH1 from './required-h1/index.js';
|
|
36
50
|
import TableRowColumnAlignment from './table-row-column-alignment/index.js';
|
|
37
51
|
import UseList from './use-list/index.js';
|
|
38
52
|
import WaiAria from './wai-aria/index.js';
|
|
53
|
+
/**
|
|
54
|
+
* Registry of all built-in markuplint rules, mapping rule names to their seed definitions.
|
|
55
|
+
* Used by the markuplint core to initialize rule instances during linting.
|
|
56
|
+
*/
|
|
39
57
|
const rules = {
|
|
40
58
|
'attr-duplication': AttrDuplication,
|
|
41
59
|
'attr-value-quotes': AttrValueQuotes,
|
|
@@ -43,6 +61,7 @@ const rules = {
|
|
|
43
61
|
'case-sensitive-tag-name': CaseSensitiveTagName,
|
|
44
62
|
'character-reference': CharacterReference,
|
|
45
63
|
'class-naming': ClassNaming,
|
|
64
|
+
'correct-aspect-ratio': CorrectAspectRatio,
|
|
46
65
|
'deprecated-attr': DeprecatedAttr,
|
|
47
66
|
'deprecated-element': DeprecatedElement,
|
|
48
67
|
'disallowed-element': DisallowedElement,
|
|
@@ -54,6 +73,7 @@ const rules = {
|
|
|
54
73
|
'invalid-attr': InvalidAttr,
|
|
55
74
|
'label-has-control': LabelHasControl,
|
|
56
75
|
'landmark-roles': LandmarkRoles,
|
|
76
|
+
'link-types': LinkTypes,
|
|
57
77
|
'neighbor-popovers': NeighborPopovers,
|
|
58
78
|
'no-ambiguous-navigable-target-names': NoAmbiguousNavigableTargetNames,
|
|
59
79
|
'no-boolean-attr-value': NoBooleanAttrValue,
|
|
@@ -64,14 +84,18 @@ const rules = {
|
|
|
64
84
|
'no-hard-code-id': NoHardCodeId,
|
|
65
85
|
'no-orphaned-end-tag': NoOrphanedEndTag,
|
|
66
86
|
'no-refer-to-non-existent-id': NoReferToNonExistentId,
|
|
87
|
+
'no-unsupported-features': NoUnsupportedFeatures,
|
|
67
88
|
'no-use-event-handler-attr': NoUseEventHandlerAttr,
|
|
68
89
|
'permitted-contents': PermittedContents,
|
|
69
90
|
'placeholder-label-option': PlaceholderLabelOption,
|
|
91
|
+
'redundant-accessible-name': RedundantAccessibleName,
|
|
70
92
|
'require-accessible-name': RequireAccessibleName,
|
|
71
93
|
'require-datetime': RequireDatetime,
|
|
94
|
+
'require-dialog-autofocus': RequireDialogAutofocus,
|
|
72
95
|
'required-attr': RequiredAttr,
|
|
73
96
|
'required-element': RequiredElement,
|
|
74
97
|
'required-h1': RequiredH1,
|
|
98
|
+
'srcset-sizes-constraint': SrcsetSizesConstraint,
|
|
75
99
|
'table-row-column-alignment': TableRowColumnAlignment,
|
|
76
100
|
'use-list': UseList,
|
|
77
101
|
'wai-aria': WaiAria,
|
|
@@ -1,2 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule that detects attributes that have no effect on their owner element.
|
|
3
|
+
*
|
|
4
|
+
* Checks each attribute's spec for ineffective conditions (CSS selectors)
|
|
5
|
+
* and reports when the owner element matches any of those conditions,
|
|
6
|
+
* meaning the attribute is present but has no practical effect.
|
|
7
|
+
*/
|
|
1
8
|
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
2
9
|
export default _default;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { createRule, getAttrSpecs } from '@markuplint/ml-core';
|
|
2
2
|
import { toNoEmptyStringArrayFromStringOrArray } from '@markuplint/shared';
|
|
3
3
|
import meta from './meta.js';
|
|
4
|
+
/**
|
|
5
|
+
* Rule that detects attributes that have no effect on their owner element.
|
|
6
|
+
*
|
|
7
|
+
* Checks each attribute's spec for ineffective conditions (CSS selectors)
|
|
8
|
+
* and reports when the owner element matches any of those conditions,
|
|
9
|
+
* meaning the attribute is present but has no practical effect.
|
|
10
|
+
*/
|
|
4
11
|
export default createRule({
|
|
5
12
|
meta: meta,
|
|
6
13
|
defaultSeverity: 'warning',
|