@markuplint/rules 3.15.0 → 4.0.0-alpha.10
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/.eslintrc +5 -0
- package/LICENSE +1 -1
- package/lib/attr-check.d.ts +8 -19
- package/lib/attr-check.js +16 -21
- package/lib/attr-duplication/index.d.ts +1 -3
- package/lib/attr-duplication/index.js +6 -6
- package/lib/attr-value-quotes/index.d.ts +2 -2
- package/lib/attr-value-quotes/index.js +8 -10
- package/lib/case-sensitive-attr-name/index.d.ts +1 -1
- package/lib/case-sensitive-attr-name/index.js +12 -13
- package/lib/case-sensitive-tag-name/index.d.ts +1 -1
- package/lib/case-sensitive-tag-name/index.js +5 -4
- package/lib/character-reference/index.d.ts +1 -1
- package/lib/character-reference/index.js +13 -12
- package/lib/class-naming/index.d.ts +1 -1
- package/lib/class-naming/index.js +14 -13
- package/lib/create-message.d.ts +2 -12
- package/lib/create-message.js +26 -26
- package/lib/debug.js +2 -6
- package/lib/deprecated-attr/index.d.ts +1 -3
- package/lib/deprecated-attr/index.js +9 -9
- package/lib/deprecated-element/index.d.ts +1 -3
- package/lib/deprecated-element/index.js +7 -6
- package/lib/disallowed-element/index.d.ts +1 -1
- package/lib/disallowed-element/index.js +9 -8
- package/lib/doctype/index.d.ts +2 -2
- package/lib/doctype/index.js +5 -4
- package/lib/end-tag/index.d.ts +1 -1
- package/lib/end-tag/index.js +8 -8
- package/lib/helpers.d.ts +17 -35
- package/lib/helpers.js +25 -32
- package/lib/id-duplication/index.d.ts +1 -3
- package/lib/id-duplication/index.js +5 -4
- package/lib/index.d.ts +21 -17
- package/lib/index.js +63 -66
- package/lib/ineffective-attr/index.d.ts +1 -3
- package/lib/ineffective-attr/index.js +8 -7
- package/lib/invalid-attr/index.d.ts +31 -38
- package/lib/invalid-attr/index.js +33 -33
- package/lib/label-has-control/index.d.ts +1 -3
- package/lib/label-has-control/index.js +5 -4
- package/lib/landmark-roles/index.d.ts +3 -3
- package/lib/landmark-roles/index.js +16 -18
- package/lib/no-boolean-attr-value/index.d.ts +1 -3
- package/lib/no-boolean-attr-value/index.js +9 -9
- package/lib/no-default-value/index.d.ts +1 -3
- package/lib/no-default-value/index.js +12 -12
- package/lib/no-empty-palpable-content/index.d.ts +3 -3
- package/lib/no-empty-palpable-content/index.js +9 -8
- package/lib/no-hard-code-id/index.d.ts +1 -3
- package/lib/no-hard-code-id/index.js +5 -4
- package/lib/no-refer-to-non-existent-id/index.d.ts +1 -1
- package/lib/no-refer-to-non-existent-id/index.js +37 -38
- package/lib/no-use-event-handler-attr/index.d.ts +2 -2
- package/lib/no-use-event-handler-attr/index.js +7 -6
- package/lib/permitted-contents/choice.d.ts +2 -8
- package/lib/permitted-contents/choice.js +14 -19
- package/lib/permitted-contents/complex-branch.d.ts +2 -8
- package/lib/permitted-contents/complex-branch.js +10 -14
- package/lib/permitted-contents/content-model.d.ts +1 -1
- package/lib/permitted-contents/content-model.js +10 -11
- package/lib/permitted-contents/count-pattern.d.ts +3 -18
- package/lib/permitted-contents/count-pattern.js +19 -24
- package/lib/permitted-contents/debug.browser.d.ts +16 -16
- package/lib/permitted-contents/debug.browser.js +9 -12
- package/lib/permitted-contents/debug.d.ts +10 -3
- package/lib/permitted-contents/debug.js +12 -13
- package/lib/permitted-contents/index.d.ts +2 -2
- package/lib/permitted-contents/index.js +13 -13
- package/lib/permitted-contents/matches-selector.d.ts +2 -7
- package/lib/permitted-contents/matches-selector.js +13 -18
- package/lib/permitted-contents/order.d.ts +2 -8
- package/lib/permitted-contents/order.js +19 -24
- package/lib/permitted-contents/recursive-branch.d.ts +3 -9
- package/lib/permitted-contents/recursive-branch.js +9 -13
- package/lib/permitted-contents/represent-transparent-nodes.d.ts +4 -8
- package/lib/permitted-contents/represent-transparent-nodes.js +15 -20
- package/lib/permitted-contents/start.d.ts +2 -7
- package/lib/permitted-contents/start.js +13 -21
- package/lib/permitted-contents/transparent.d.ts +1 -1
- package/lib/permitted-contents/transparent.js +6 -11
- package/lib/permitted-contents/types.d.ts +29 -29
- package/lib/permitted-contents/types.js +1 -2
- package/lib/permitted-contents/utils.d.ts +42 -79
- package/lib/permitted-contents/utils.js +72 -82
- package/lib/placeholder-label-option/index.d.ts +1 -1
- package/lib/placeholder-label-option/index.js +12 -13
- package/lib/require-accessible-name/index.d.ts +2 -2
- package/lib/require-accessible-name/index.js +12 -15
- package/lib/require-datetime/index.d.ts +3 -3
- package/lib/require-datetime/index.js +14 -13
- package/lib/require-datetime/types.d.ts +2 -2
- package/lib/require-datetime/types.js +1 -2
- package/lib/require-datetime/utils.d.ts +1 -1
- package/lib/require-datetime/utils.js +5 -12
- package/lib/required-attr/index.d.ts +3 -3
- package/lib/required-attr/index.js +11 -11
- package/lib/required-element/index.d.ts +2 -2
- package/lib/required-element/index.js +7 -7
- package/lib/required-h1/index.d.ts +3 -3
- package/lib/required-h1/index.js +6 -6
- package/lib/use-list/index.d.ts +6 -2
- package/lib/use-list/index.js +27 -11
- package/lib/wai-aria/checkings/abstract-role.d.ts +1 -1
- package/lib/wai-aria/checkings/abstract-role.js +5 -10
- package/lib/wai-aria/checkings/default-value.d.ts +4 -8
- package/lib/wai-aria/checkings/default-value.js +2 -6
- package/lib/wai-aria/checkings/deprecated-props.d.ts +5 -9
- package/lib/wai-aria/checkings/deprecated-props.js +3 -8
- package/lib/wai-aria/checkings/disallowed-prop.d.ts +5 -9
- package/lib/wai-aria/checkings/disallowed-prop.js +7 -12
- package/lib/wai-aria/checkings/implicit-props.d.ts +5 -9
- package/lib/wai-aria/checkings/implicit-props.js +12 -17
- package/lib/wai-aria/checkings/implicit-role.d.ts +1 -1
- package/lib/wai-aria/checkings/implicit-role.js +4 -9
- package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +1 -1
- package/lib/wai-aria/checkings/interaction-in-hidden.js +4 -8
- package/lib/wai-aria/checkings/no-global-prop.d.ts +4 -8
- package/lib/wai-aria/checkings/no-global-prop.js +2 -7
- package/lib/wai-aria/checkings/non-existent-role.d.ts +1 -1
- package/lib/wai-aria/checkings/non-existent-role.js +4 -9
- package/lib/wai-aria/checkings/permitted-roles.d.ts +1 -1
- package/lib/wai-aria/checkings/permitted-roles.js +4 -9
- package/lib/wai-aria/checkings/presentational-children.d.ts +1 -1
- package/lib/wai-aria/checkings/presentational-children.js +5 -10
- package/lib/wai-aria/checkings/required-owned-elements.d.ts +4 -8
- package/lib/wai-aria/checkings/required-owned-elements.js +7 -11
- package/lib/wai-aria/checkings/required-prop.d.ts +7 -13
- package/lib/wai-aria/checkings/required-prop.js +2 -7
- package/lib/wai-aria/checkings/value.d.ts +7 -16
- package/lib/wai-aria/checkings/value.js +7 -13
- package/lib/wai-aria/index.d.ts +2 -2
- package/lib/wai-aria/index.js +41 -40
- package/lib/wai-aria/types.d.ts +10 -10
- package/lib/wai-aria/types.js +1 -2
- package/package.json +17 -13
- package/test/attr-check.spec.js +0 -77
- package/test/attr-duplication/index.spec.js +0 -159
- package/test/attr-value-quotes/index.spec.js +0 -133
- package/test/case-sensitive-attr-name/index.spec.js +0 -65
- package/test/case-sensitive-tag-name/index.spec.js +0 -80
- package/test/character-reference/index.spec.js +0 -72
- package/test/class-naming/index.spec.js +0 -470
- package/test/create-message.spec.js +0 -497
- package/test/deprecated-attr/index.spec.js +0 -48
- package/test/deprecated-element/index.spec.js +0 -35
- package/test/disallowed-element/index.spec.js +0 -90
- package/test/doctype/index.spec.js +0 -50
- package/test/end-tag/index.spec.js +0 -162
- package/test/id-duplication/index.spec.js +0 -47
- package/test/ineffective-attr/index.spec.js +0 -31
- package/test/invalid-attr/index.spec.js +0 -1631
- package/test/label-has-control/index.spec.js +0 -29
- package/test/landmark-roles/index.spec.js +0 -187
- package/test/no-boolean-attr-value/index.spec.js +0 -41
- package/test/no-default-value/index.spec.js +0 -74
- package/test/no-empty-palpable-content/index.spec.js +0 -115
- package/test/no-hard-code-id/index.spec.js +0 -100
- package/test/no-refer-to-non-existent-id/index.spec.js +0 -254
- package/test/no-use-event-handler-attr/index.spec.js +0 -57
- package/test/permitted-contents/choice.spec.js +0 -174
- package/test/permitted-contents/count-pattern.spec.js +0 -308
- package/test/permitted-contents/index.spec.js +0 -1395
- package/test/permitted-contents/matches-selector.spec.js +0 -59
- package/test/permitted-contents/order.spec.js +0 -351
- package/test/permitted-contents/recursive-branch.spec.js +0 -41
- package/test/permitted-contents/represent-transparent-nodes.spec.js +0 -24
- package/test/permitted-contents/start.spec.js +0 -67
- package/test/placeholder-label-option/index.spec.js +0 -113
- package/test/require-accessible-name/index.spec.js +0 -444
- package/test/require-datetime/index.spec.js +0 -54
- package/test/require-datetime/utils.spec.js +0 -52
- package/test/required-attr/index.spec.js +0 -414
- package/test/required-element/index.spec.js +0 -188
- package/test/required-h1/index.spec.js +0 -69
- package/test/use-list/index.spec.js +0 -109
- package/test/wai-aria/checkings/value.spec.js +0 -33
- package/test/wai-aria/index.spec.js +0 -1203
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { createRule, getAttrSpecs } from '@markuplint/ml-core';
|
|
2
|
+
import { toNoEmptyStringArrayFromStringOrArray } from '@markuplint/shared';
|
|
3
|
+
export default createRule({
|
|
4
|
+
meta: {
|
|
5
|
+
category: 'style',
|
|
6
|
+
},
|
|
6
7
|
defaultSeverity: 'warning',
|
|
7
8
|
async verify({ document, report, t }) {
|
|
8
9
|
await document.walkOn('Attr', attr => {
|
|
9
|
-
const attrSpec =
|
|
10
|
+
const attrSpec = getAttrSpecs(attr.ownerElement, document.specs);
|
|
10
11
|
if (!attrSpec) {
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
@@ -15,7 +16,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
15
16
|
if (!spec) {
|
|
16
17
|
return;
|
|
17
18
|
}
|
|
18
|
-
const ineffectiveConditions =
|
|
19
|
+
const ineffectiveConditions = toNoEmptyStringArrayFromStringOrArray(spec.ineffective);
|
|
19
20
|
if (ineffectiveConditions.some(selector => attr.ownerElement.matches(selector))) {
|
|
20
21
|
report({
|
|
21
22
|
scope: attr,
|
|
@@ -1,44 +1,37 @@
|
|
|
1
1
|
import type { AttributeType } from '@markuplint/ml-spec';
|
|
2
2
|
type Option = {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
| {
|
|
25
|
-
disallowed: true;
|
|
26
|
-
}
|
|
27
|
-
>;
|
|
3
|
+
/**
|
|
4
|
+
* @since 3.7.0
|
|
5
|
+
*/
|
|
6
|
+
allowAttrs?: (string | Attr)[] | Record<string, ValueRule>;
|
|
7
|
+
/**
|
|
8
|
+
* @since 3.7.0
|
|
9
|
+
*/
|
|
10
|
+
disallowAttrs?: (string | Attr)[] | Record<string, ValueRule>;
|
|
11
|
+
ignoreAttrNamePrefix?: string | string[];
|
|
12
|
+
allowToAddPropertiesForPretender?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated Since version 3.7.0. Use `allowAttrs` or `disallowAttrs` instead.
|
|
15
|
+
* This option (`attr`) is now considered ambiguous and may lead to confusion.
|
|
16
|
+
* Please use the more explicit `allowAttrs` or `disallowAttrs` option
|
|
17
|
+
* to specify allowed attributes for the `invalid-attr` rule.
|
|
18
|
+
* @see {@link Option.allowAttrs}
|
|
19
|
+
* @see {@link Option.disallowAttrs}
|
|
20
|
+
*/
|
|
21
|
+
attrs?: Record<string, ValueRule | {
|
|
22
|
+
disallowed: true;
|
|
23
|
+
}>;
|
|
28
24
|
};
|
|
29
25
|
type Attr = {
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
name: string;
|
|
27
|
+
value: AttributeType | ValueRule;
|
|
32
28
|
};
|
|
33
|
-
type ValueRule =
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
type: AttributeType;
|
|
42
|
-
};
|
|
43
|
-
declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, Option>>;
|
|
29
|
+
type ValueRule = {
|
|
30
|
+
enum: [string, ...string[]];
|
|
31
|
+
} | {
|
|
32
|
+
pattern: string;
|
|
33
|
+
} | {
|
|
34
|
+
type: AttributeType;
|
|
35
|
+
};
|
|
36
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Option>>;
|
|
44
37
|
export default _default;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { createRule, getAttrSpecs, getSpec } from '@markuplint/ml-core';
|
|
2
|
+
import { attrCheck } from '../attr-check.js';
|
|
3
|
+
import { log as ruleLog } from '../debug.js';
|
|
4
|
+
import { isValidAttr, match } from '../helpers.js';
|
|
5
|
+
const log = ruleLog.extend('invalid-attr');
|
|
6
|
+
export default createRule({
|
|
7
|
+
meta: {
|
|
8
|
+
category: 'validation',
|
|
9
|
+
},
|
|
9
10
|
defaultOptions: {},
|
|
10
11
|
async verify({ document, report, t }) {
|
|
11
12
|
await document.walkOn('Attr', attr => {
|
|
12
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
13
13
|
// Default
|
|
14
|
-
const allowToAddPropertiesForPretender =
|
|
14
|
+
const allowToAddPropertiesForPretender = attr.rule.options.allowToAddPropertiesForPretender ?? true;
|
|
15
15
|
if (attr.isDirective) {
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
|
-
const attrSpecs =
|
|
18
|
+
const attrSpecs = getAttrSpecs(attr.ownerElement, document.specs);
|
|
19
19
|
const attrName = attr.nameNode;
|
|
20
20
|
const name = attr.name;
|
|
21
21
|
if (attr.ownerElement.elementType === 'html' && attr.candidate) {
|
|
@@ -24,9 +24,9 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
24
24
|
t('Did you mean "{0}"?', attr.candidate);
|
|
25
25
|
report({
|
|
26
26
|
scope: attr,
|
|
27
|
-
line: attrName
|
|
28
|
-
col: attrName
|
|
29
|
-
raw: attrName
|
|
27
|
+
line: attrName?.startLine,
|
|
28
|
+
col: attrName?.startCol,
|
|
29
|
+
raw: attrName?.raw,
|
|
30
30
|
message: message,
|
|
31
31
|
});
|
|
32
32
|
return;
|
|
@@ -94,11 +94,11 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
-
const allowValue =
|
|
98
|
-
const disallowValue =
|
|
97
|
+
const allowValue = allowAttrs[name] ?? null;
|
|
98
|
+
const disallowValue = disallowAttrs[name] ?? null;
|
|
99
99
|
if (allowValue) {
|
|
100
100
|
if ('enum' in allowValue) {
|
|
101
|
-
invalid =
|
|
101
|
+
invalid = attrCheck(t, name.toLowerCase(), value, true, {
|
|
102
102
|
name,
|
|
103
103
|
type: {
|
|
104
104
|
enum: allowValue.enum,
|
|
@@ -107,7 +107,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
109
|
else if ('pattern' in allowValue) {
|
|
110
|
-
if (!
|
|
110
|
+
if (!match(value, allowValue.pattern)) {
|
|
111
111
|
invalid = {
|
|
112
112
|
invalidType: 'invalid-value',
|
|
113
113
|
message: t('{0} is unmatched with the below patterns: {1}', t('the "{0*}" {1}', name, 'attribute'), allowValue.pattern),
|
|
@@ -115,12 +115,12 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
else if ('type' in allowValue) {
|
|
118
|
-
invalid =
|
|
118
|
+
invalid = attrCheck(t, name, value, true, { name, type: allowValue.type, description: '' });
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
else if (disallowValue) {
|
|
122
122
|
if ('enum' in disallowValue) {
|
|
123
|
-
const checkResult =
|
|
123
|
+
const checkResult = attrCheck(t, name.toLowerCase(), value, true, {
|
|
124
124
|
name,
|
|
125
125
|
type: {
|
|
126
126
|
enum: disallowValue.enum,
|
|
@@ -135,7 +135,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
else if ('pattern' in disallowValue) {
|
|
138
|
-
if (
|
|
138
|
+
if (match(value, disallowValue.pattern)) {
|
|
139
139
|
invalid = {
|
|
140
140
|
invalidType: 'invalid-value',
|
|
141
141
|
message: t('{0} is matched with the below disallowed patterns: {1}', t('the "{0*}" {1}', name, 'attribute'), disallowValue.pattern),
|
|
@@ -150,7 +150,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
152
|
else {
|
|
153
|
-
const checkResult =
|
|
153
|
+
const checkResult = attrCheck(t, name, value, true, {
|
|
154
154
|
name,
|
|
155
155
|
type: disallowValue.type,
|
|
156
156
|
description: '',
|
|
@@ -166,7 +166,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
166
166
|
}
|
|
167
167
|
else if (attr.ownerElement.elementType === 'html' && attrSpecs) {
|
|
168
168
|
log('Checking %s[%s="%s"]', attr.nodeName, name, value);
|
|
169
|
-
invalid =
|
|
169
|
+
invalid = isValidAttr(t, name, value, attr.isDynamicValue || false, attr.ownerElement, attrSpecs, log);
|
|
170
170
|
}
|
|
171
171
|
if (invalid !== false) {
|
|
172
172
|
switch (invalid.invalidType) {
|
|
@@ -184,28 +184,28 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
184
184
|
report({
|
|
185
185
|
scope: attr,
|
|
186
186
|
message: invalid.message,
|
|
187
|
-
line: (
|
|
187
|
+
line: (valueNode?.startLine ?? 0) + (invalid.loc?.line ?? 0),
|
|
188
188
|
col: invalid.loc && invalid.loc.line > 0
|
|
189
|
-
?
|
|
190
|
-
: (
|
|
191
|
-
raw:
|
|
189
|
+
? invalid.loc?.col + 1
|
|
190
|
+
: (valueNode?.startCol ?? 0) + (invalid.loc?.col ?? 0),
|
|
191
|
+
raw: invalid.loc?.raw ?? value,
|
|
192
192
|
});
|
|
193
193
|
break;
|
|
194
194
|
}
|
|
195
195
|
case 'non-existent': {
|
|
196
|
-
if (allowToAddPropertiesForPretender &&
|
|
196
|
+
if (allowToAddPropertiesForPretender && attr.ownerElement.pretenderContext?.type === 'origin') {
|
|
197
197
|
return;
|
|
198
198
|
}
|
|
199
|
-
const spec =
|
|
200
|
-
if (spec
|
|
199
|
+
const spec = getSpec(attr.ownerElement, document.specs.specs);
|
|
200
|
+
if (spec?.possibleToAddProperties) {
|
|
201
201
|
return;
|
|
202
202
|
}
|
|
203
203
|
report({
|
|
204
204
|
scope: attr,
|
|
205
205
|
message: invalid.message,
|
|
206
|
-
line: attrName
|
|
207
|
-
col: attrName
|
|
208
|
-
raw: attrName
|
|
206
|
+
line: attrName?.startLine,
|
|
207
|
+
col: attrName?.startCol,
|
|
208
|
+
raw: attrName?.raw,
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
}
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
declare const _default: Readonly<
|
|
2
|
-
import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
|
|
3
|
-
>;
|
|
1
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
4
2
|
export default _default;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const ml_core_1 = require("@markuplint/ml-core");
|
|
1
|
+
import { createRule } from '@markuplint/ml-core';
|
|
4
2
|
const controlSelector = ["input:not([type='hidden' i])", 'select', 'textarea'].join(',');
|
|
5
|
-
|
|
3
|
+
export default createRule({
|
|
4
|
+
meta: {
|
|
5
|
+
category: 'a11y',
|
|
6
|
+
},
|
|
6
7
|
defaultSeverity: 'warning',
|
|
7
8
|
async verify({ document, report, t }) {
|
|
8
9
|
await document.walkOn('Element', el => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
type Options = {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
ignoreRoles: Roles[];
|
|
3
|
+
labelEachArea: boolean;
|
|
4
4
|
};
|
|
5
5
|
type TopLevelRoles = 'banner' | 'main' | 'complementary' | 'contentinfo';
|
|
6
6
|
type Roles = TopLevelRoles | 'form' | 'navigation' | 'region';
|
|
7
|
-
declare const _default: Readonly<import(
|
|
7
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Options>>;
|
|
8
8
|
export default _default;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const ml_core_1 = require("@markuplint/ml-core");
|
|
1
|
+
import { createRule } from '@markuplint/ml-core';
|
|
4
2
|
const selectors = {
|
|
5
3
|
complementary: ['[role="complementary"]', 'aside'],
|
|
6
4
|
contentinfo: ['[role="contentinfo"]'],
|
|
@@ -11,25 +9,27 @@ const selectors = {
|
|
|
11
9
|
region: ['[role="region"]', 'section[aria-labelledby]', 'section[aria-label]', 'section[title]'],
|
|
12
10
|
};
|
|
13
11
|
const topLevelRoles = ['banner', 'main', 'complementary', 'contentinfo'];
|
|
14
|
-
|
|
12
|
+
export default createRule({
|
|
13
|
+
meta: {
|
|
14
|
+
category: 'a11y',
|
|
15
|
+
},
|
|
15
16
|
defaultSeverity: 'warning',
|
|
16
17
|
defaultOptions: {
|
|
17
18
|
ignoreRoles: [],
|
|
18
19
|
labelEachArea: true,
|
|
19
20
|
},
|
|
20
21
|
verify({ document, report, t }) {
|
|
21
|
-
var _a;
|
|
22
22
|
if (document.isFragment) {
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
const roles = {
|
|
26
|
-
complementary:
|
|
27
|
-
contentinfo:
|
|
28
|
-
form:
|
|
29
|
-
banner:
|
|
30
|
-
main:
|
|
31
|
-
navigation:
|
|
32
|
-
region:
|
|
26
|
+
complementary: [...document.querySelectorAll(selectors.complementary.join(','))],
|
|
27
|
+
contentinfo: [...document.querySelectorAll(selectors.contentinfo.join(','))],
|
|
28
|
+
form: [...document.querySelectorAll(selectors.form.join(','))],
|
|
29
|
+
banner: [...document.querySelectorAll(selectors.banner.join(','))],
|
|
30
|
+
main: [...document.querySelectorAll(selectors.main.join(','))],
|
|
31
|
+
navigation: [...document.querySelectorAll(selectors.navigation.join(','))],
|
|
32
|
+
region: [...document.querySelectorAll(selectors.region.join(','))],
|
|
33
33
|
};
|
|
34
34
|
/**
|
|
35
35
|
* `<header>`
|
|
@@ -43,7 +43,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
43
43
|
* > - nav
|
|
44
44
|
* > - section
|
|
45
45
|
*/
|
|
46
|
-
const headers =
|
|
46
|
+
const headers = [...document.querySelectorAll('header')].filter(header => {
|
|
47
47
|
return !header.closest('article, aside, main, nav, section');
|
|
48
48
|
});
|
|
49
49
|
roles.banner.push(...headers);
|
|
@@ -59,7 +59,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
59
59
|
* > - nav
|
|
60
60
|
* > - section
|
|
61
61
|
*/
|
|
62
|
-
const footers =
|
|
62
|
+
const footers = [...document.querySelectorAll('footer')].filter(footer => {
|
|
63
63
|
return !footer.closest('article, aside, main, nav, section');
|
|
64
64
|
});
|
|
65
65
|
roles.contentinfo.push(...footers);
|
|
@@ -72,7 +72,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
72
72
|
if (el.rule.disabled) {
|
|
73
73
|
continue;
|
|
74
74
|
}
|
|
75
|
-
if (
|
|
75
|
+
if (el.rule.options.ignoreRoles?.includes(role)) {
|
|
76
76
|
continue;
|
|
77
77
|
}
|
|
78
78
|
if (el.isDescendantByUUIDList(uuidList)) {
|
|
@@ -109,9 +109,7 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
109
109
|
function landmarkRoleElementUUIDList(
|
|
110
110
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
111
111
|
roleset) {
|
|
112
|
-
return Object.values(roleset)
|
|
113
|
-
.map(elements => elements.map(element => element.uuid))
|
|
114
|
-
.flat();
|
|
112
|
+
return Object.values(roleset).flatMap(elements => elements.map(element => element.uuid));
|
|
115
113
|
}
|
|
116
114
|
function hasLabel(
|
|
117
115
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
declare const _default: Readonly<
|
|
2
|
-
import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
|
|
3
|
-
>;
|
|
1
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
4
2
|
export default _default;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { createRule, getAttrSpecs } from '@markuplint/ml-core';
|
|
2
|
+
export default createRule({
|
|
3
|
+
meta: {
|
|
4
|
+
category: 'style',
|
|
5
|
+
},
|
|
5
6
|
defaultSeverity: 'warning',
|
|
6
7
|
async verify({ document, report, t }) {
|
|
7
8
|
await document.walkOn('Attr', attr => {
|
|
8
|
-
|
|
9
|
-
const attrSpec = (0, ml_core_1.getAttrSpecs)(attr.ownerElement, document.specs);
|
|
9
|
+
const attrSpec = getAttrSpecs(attr.ownerElement, document.specs);
|
|
10
10
|
if (!attrSpec) {
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
@@ -29,12 +29,12 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
29
29
|
attr.valueNode,
|
|
30
30
|
attr.endQuote,
|
|
31
31
|
];
|
|
32
|
-
const extraRaw = extraTokens.reduce((raw, t) =>
|
|
32
|
+
const extraRaw = extraTokens.reduce((raw, t) => raw + (t?.raw ?? ''), '');
|
|
33
33
|
if (extraRaw) {
|
|
34
34
|
report({
|
|
35
35
|
scope: attr,
|
|
36
|
-
line:
|
|
37
|
-
col:
|
|
36
|
+
line: attr.spacesBeforeEqual?.startLine,
|
|
37
|
+
col: attr.spacesBeforeEqual?.startCol,
|
|
38
38
|
raw: extraRaw,
|
|
39
39
|
message: t('{0} is {1}', t('the "{0*}" {1}', name, 'attribute'), t('a {0}', 'boolean attribute')) +
|
|
40
40
|
t('. ') +
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
declare const _default: Readonly<
|
|
2
|
-
import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
|
|
3
|
-
>;
|
|
1
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
4
2
|
export default _default;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { createRule, getAttrSpecs } from '@markuplint/ml-core';
|
|
2
|
+
import { toNormalizedValue } from '../helpers.js';
|
|
3
|
+
export default createRule({
|
|
4
|
+
meta: {
|
|
5
|
+
category: 'style',
|
|
6
|
+
},
|
|
6
7
|
defaultSeverity: 'warning',
|
|
7
8
|
async verify({ document, report, t }) {
|
|
8
9
|
await document.walkOn('Attr', attr => {
|
|
9
|
-
|
|
10
|
-
const attrSpec = (0, ml_core_1.getAttrSpecs)(attr.ownerElement, document.specs);
|
|
10
|
+
const attrSpec = getAttrSpecs(attr.ownerElement, document.specs);
|
|
11
11
|
if (!attrSpec) {
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
@@ -18,14 +18,14 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
18
18
|
if (!spec.defaultValue) {
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
|
-
const normalizedValue =
|
|
22
|
-
const defaultValue =
|
|
21
|
+
const normalizedValue = toNormalizedValue(attr.value, spec);
|
|
22
|
+
const defaultValue = toNormalizedValue(spec.defaultValue, spec);
|
|
23
23
|
if (defaultValue === normalizedValue) {
|
|
24
24
|
report({
|
|
25
25
|
scope: attr,
|
|
26
|
-
line:
|
|
27
|
-
col:
|
|
28
|
-
raw:
|
|
26
|
+
line: attr.valueNode?.startLine,
|
|
27
|
+
col: attr.valueNode?.startCol,
|
|
28
|
+
raw: attr.valueNode?.raw,
|
|
29
29
|
message: t('It is {0}', t('the {0}', 'default value')),
|
|
30
30
|
});
|
|
31
31
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
type Options = {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
extendsExposableElements?: boolean;
|
|
3
|
+
ignoreIfAriaBusy?: boolean;
|
|
4
4
|
};
|
|
5
|
-
declare const _default: Readonly<import(
|
|
5
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Options>>;
|
|
6
6
|
export default _default;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { createRule } from '@markuplint/ml-core';
|
|
2
|
+
import { isNothingContentModel, isPalpableElement } from '@markuplint/ml-spec';
|
|
3
|
+
export default createRule({
|
|
4
|
+
meta: {
|
|
5
|
+
category: 'validation',
|
|
6
|
+
},
|
|
6
7
|
defaultSeverity: 'warning',
|
|
7
8
|
defaultOptions: {
|
|
8
9
|
extendsExposableElements: true,
|
|
@@ -18,19 +19,19 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
18
19
|
if (el.localName === 'textarea') {
|
|
19
20
|
return;
|
|
20
21
|
}
|
|
21
|
-
if (!
|
|
22
|
+
if (!isPalpableElement(el, el.ownerMLDocument.specs, {
|
|
22
23
|
extendsSvg: false,
|
|
23
24
|
extendsExposableElements: el.rule.options.extendsExposableElements,
|
|
24
25
|
})) {
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
27
|
-
if (
|
|
28
|
+
if (isNothingContentModel(el)) {
|
|
28
29
|
return;
|
|
29
30
|
}
|
|
30
31
|
if (el.rule.options.ignoreIfAriaBusy && el.getAttribute('aria-busy') === 'true') {
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
33
|
-
const isEmpty =
|
|
34
|
+
const isEmpty = [...el.childNodes].every(node => node.is(node.TEXT_NODE) && node.isWhitespace());
|
|
34
35
|
if (isEmpty) {
|
|
35
36
|
report({
|
|
36
37
|
scope: el,
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
declare const _default: Readonly<
|
|
2
|
-
import('@markuplint/ml-core').RuleSeed<import('@markuplint/ml-core').RuleConfigValue, undefined>
|
|
3
|
-
>;
|
|
1
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<import("@markuplint/ml-core").RuleConfigValue, undefined>>;
|
|
4
2
|
export default _default;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { createRule } from '@markuplint/ml-core';
|
|
2
|
+
export default createRule({
|
|
3
|
+
meta: {
|
|
4
|
+
category: 'maintainability',
|
|
5
|
+
},
|
|
5
6
|
defaultSeverity: 'warning',
|
|
6
7
|
async verify({ document, report, t }) {
|
|
7
8
|
if (!document.isFragment) {
|