@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,9 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.checkingImplicitProps = void 0;
|
|
4
|
-
const helpers_1 = require("../../helpers");
|
|
5
|
-
const checkingImplicitProps = ({ attr, propSpecs, attrSpecs }) => t => {
|
|
6
|
-
var _a;
|
|
1
|
+
import { isValidAttr } from '../../helpers.js';
|
|
2
|
+
export const checkingImplicitProps = ({ attr, propSpecs, attrSpecs }) => t => {
|
|
7
3
|
if (!attrSpecs) {
|
|
8
4
|
return;
|
|
9
5
|
}
|
|
@@ -11,12 +7,12 @@ const checkingImplicitProps = ({ attr, propSpecs, attrSpecs }) => t => {
|
|
|
11
7
|
return;
|
|
12
8
|
}
|
|
13
9
|
const propSpec = propSpecs.find(p => p.name === attr.name);
|
|
14
|
-
if (!
|
|
10
|
+
if (!propSpec?.equivalentHtmlAttrs) {
|
|
15
11
|
return;
|
|
16
12
|
}
|
|
17
13
|
for (const equivalentHtmlAttr of propSpec.equivalentHtmlAttrs) {
|
|
18
14
|
const htmlAttrSpec = attrSpecs.find(a => a.name === equivalentHtmlAttr.htmlAttrName);
|
|
19
|
-
const isValid =
|
|
15
|
+
const isValid = isValidAttr(t, equivalentHtmlAttr.htmlAttrName, equivalentHtmlAttr.value ?? '', false, attr.ownerElement, attrSpecs);
|
|
20
16
|
if (isValid !== false && isValid.invalidType === 'non-existent') {
|
|
21
17
|
continue;
|
|
22
18
|
}
|
|
@@ -30,7 +26,7 @@ const checkingImplicitProps = ({ attr, propSpecs, attrSpecs }) => t => {
|
|
|
30
26
|
message: t('{0} has {1}', t('the "{0*}" {1}', attr.name, `ARIA ${propSpec.type}`), t('the same {0} as {1}', 'semantics', t('{0} or {1}', t('the current "{0}" {1}', equivalentHtmlAttr.htmlAttrName, 'attribute'), t('the implicit "{0}" {1}', equivalentHtmlAttr.htmlAttrName, 'attribute')))),
|
|
31
27
|
};
|
|
32
28
|
}
|
|
33
|
-
if (
|
|
29
|
+
if (htmlAttrSpec?.type === 'Boolean' && value !== 'false') {
|
|
34
30
|
continue;
|
|
35
31
|
}
|
|
36
32
|
return {
|
|
@@ -38,14 +34,13 @@ const checkingImplicitProps = ({ attr, propSpecs, attrSpecs }) => t => {
|
|
|
38
34
|
message: t('{0} contradicts {1}', t('the "{0*}" {1}', attr.name, `ARIA ${propSpec.type}`), t('the current "{0}" {1}', equivalentHtmlAttr.htmlAttrName, 'attribute')),
|
|
39
35
|
};
|
|
40
36
|
}
|
|
41
|
-
else if (value === 'true'
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
}
|
|
37
|
+
else if (value === 'true' &&
|
|
38
|
+
!equivalentHtmlAttr.isNotStrictEquivalent &&
|
|
39
|
+
htmlAttrSpec?.type === 'Boolean') {
|
|
40
|
+
return {
|
|
41
|
+
scope: attr,
|
|
42
|
+
message: t('{0} contradicts {1}', t('the "{0*}" {1}', attr.name, `ARIA ${propSpec.type}`), t('the implicit "{0}" {1}', equivalentHtmlAttr.htmlAttrName, 'attribute')),
|
|
43
|
+
};
|
|
48
44
|
}
|
|
49
45
|
}
|
|
50
46
|
};
|
|
51
|
-
exports.checkingImplicitProps = checkingImplicitProps;
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const checkingImplicitRole = ({ attr }) => t => {
|
|
6
|
-
var _a;
|
|
7
|
-
const implicitRole = (0, ml_spec_1.getImplicitRoleName)(attr.ownerElement, attr.rule.options.version, attr.ownerMLDocument.specs);
|
|
8
|
-
const tokens = (_a = attr.tokenList) === null || _a === void 0 ? void 0 : _a.allTokens();
|
|
1
|
+
import { getImplicitRoleName } from '@markuplint/ml-spec';
|
|
2
|
+
export const checkingImplicitRole = ({ attr }) => t => {
|
|
3
|
+
const implicitRole = getImplicitRoleName(attr.ownerElement, attr.rule.options.version, attr.ownerMLDocument.specs);
|
|
4
|
+
const tokens = attr.tokenList?.allTokens();
|
|
9
5
|
if (!tokens) {
|
|
10
6
|
return;
|
|
11
7
|
}
|
|
@@ -18,4 +14,3 @@ const checkingImplicitRole = ({ attr }) => t => {
|
|
|
18
14
|
}
|
|
19
15
|
}
|
|
20
16
|
};
|
|
21
|
-
exports.checkingImplicitRole = checkingImplicitRole;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkingInteractionInHidden = void 0;
|
|
4
|
-
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
1
|
+
import { mayBeFocusable } from '@markuplint/ml-spec';
|
|
5
2
|
/**
|
|
6
3
|
* Including Elements in the Accessibility Tree
|
|
7
4
|
*
|
|
@@ -14,8 +11,8 @@ const ml_spec_1 = require("@markuplint/ml-spec");
|
|
|
14
11
|
// なので、aria-hidden=trueの子孫要素で且つインタラクティブ要素である場合、
|
|
15
12
|
// それは開発者にとってはほとんどの場合、意図しないことが多いはずなので、
|
|
16
13
|
// 仕様上不正にはならないが、十分に注意しなければならない状態である。
|
|
17
|
-
const checkingInteractionInHidden = ({ el }) => t => {
|
|
18
|
-
if (!
|
|
14
|
+
export const checkingInteractionInHidden = ({ el }) => t => {
|
|
15
|
+
if (!mayBeFocusable(el, el.ownerMLDocument.specs)) {
|
|
19
16
|
return;
|
|
20
17
|
}
|
|
21
18
|
const ariaHidden = getClosestAriaHidden(el);
|
|
@@ -33,14 +30,13 @@ const checkingInteractionInHidden = ({ el }) => t => {
|
|
|
33
30
|
message: t('It may be focusable in spite of it has the ancestor that has aria-hidden=true'),
|
|
34
31
|
};
|
|
35
32
|
};
|
|
36
|
-
exports.checkingInteractionInHidden = checkingInteractionInHidden;
|
|
37
33
|
function getClosestAriaHidden(
|
|
38
34
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
39
35
|
el) {
|
|
40
36
|
let current = el;
|
|
41
37
|
while (current) {
|
|
42
38
|
const ariaHidden = current.getAttributeNode('aria-hidden');
|
|
43
|
-
if (
|
|
39
|
+
if (ariaHidden?.value === 'true') {
|
|
44
40
|
return ariaHidden;
|
|
45
41
|
}
|
|
46
42
|
current = current.parentElement;
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import type { Options } from '../types';
|
|
1
|
+
import type { Options } from '../types.js';
|
|
2
2
|
import type { AttrChecker } from '@markuplint/ml-core';
|
|
3
3
|
import type { ARIAProperty } from '@markuplint/ml-spec';
|
|
4
|
-
export declare const checkingNoGlobalProp: AttrChecker<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
{
|
|
8
|
-
propSpecs: readonly ARIAProperty[];
|
|
9
|
-
}
|
|
10
|
-
>;
|
|
4
|
+
export declare const checkingNoGlobalProp: AttrChecker<boolean, Options, {
|
|
5
|
+
propSpecs: readonly ARIAProperty[];
|
|
6
|
+
}>;
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkingNoGlobalProp = void 0;
|
|
4
|
-
const checkingNoGlobalProp = ({ attr, propSpecs }) => t => {
|
|
5
|
-
var _a, _b;
|
|
1
|
+
export const checkingNoGlobalProp = ({ attr, propSpecs }) => t => {
|
|
6
2
|
const propSpec = propSpecs.find(prop => prop.name === attr.name);
|
|
7
3
|
if (propSpec && !propSpec.isGlobal) {
|
|
8
4
|
return {
|
|
9
5
|
scope: attr,
|
|
10
|
-
message: t('{0} is not {1}', t('the "{0*}" {1}', attr.name, `ARIA ${
|
|
6
|
+
message: t('{0} is not {1}', t('the "{0*}" {1}', attr.name, `ARIA ${propSpec.type ?? 'property'}`), `global ${propSpec.type ?? 'property'}`),
|
|
11
7
|
};
|
|
12
8
|
}
|
|
13
9
|
};
|
|
14
|
-
exports.checkingNoGlobalProp = checkingNoGlobalProp;
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const checkingNonExistentRole = ({ attr }) => t => {
|
|
6
|
-
var _a;
|
|
7
|
-
const { roles, graphicsRoles } = (0, ml_spec_1.ariaSpecs)(attr.ownerMLDocument.specs, attr.rule.options.version);
|
|
8
|
-
const tokens = (_a = attr.tokenList) === null || _a === void 0 ? void 0 : _a.allTokens();
|
|
1
|
+
import { ariaSpecs } from '@markuplint/ml-spec';
|
|
2
|
+
export const checkingNonExistentRole = ({ attr }) => t => {
|
|
3
|
+
const { roles, graphicsRoles } = ariaSpecs(attr.ownerMLDocument.specs, attr.rule.options.version);
|
|
4
|
+
const tokens = attr.tokenList?.allTokens();
|
|
9
5
|
if (!tokens) {
|
|
10
6
|
return;
|
|
11
7
|
}
|
|
@@ -25,4 +21,3 @@ const checkingNonExistentRole = ({ attr }) => t => {
|
|
|
25
21
|
}
|
|
26
22
|
}
|
|
27
23
|
};
|
|
28
|
-
exports.checkingNonExistentRole = checkingNonExistentRole;
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.checkingPermittedRoles = void 0;
|
|
4
|
-
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
5
|
-
const checkingPermittedRoles = ({ attr }) => t => {
|
|
6
|
-
var _a;
|
|
1
|
+
import { getPermittedRoles } from '@markuplint/ml-spec';
|
|
2
|
+
export const checkingPermittedRoles = ({ attr }) => t => {
|
|
7
3
|
const el = attr.ownerElement;
|
|
8
|
-
const permittedRoles =
|
|
4
|
+
const permittedRoles = getPermittedRoles(el, el.rule.options.version, attr.ownerMLDocument.specs);
|
|
9
5
|
if (permittedRoles.length === 0) {
|
|
10
6
|
return {
|
|
11
7
|
scope: attr,
|
|
12
8
|
message: t('{0} according to {1}', t('Cannot overwrite {0}', t('{0} of {1}', t('the {0}', 'role'), t('the "{0*}" {1}', el.localName, 'element'))), 'ARIA in HTML specification'),
|
|
13
9
|
};
|
|
14
10
|
}
|
|
15
|
-
const tokens =
|
|
11
|
+
const tokens = attr.tokenList?.allTokens();
|
|
16
12
|
if (!tokens) {
|
|
17
13
|
return;
|
|
18
14
|
}
|
|
@@ -25,4 +21,3 @@ const checkingPermittedRoles = ({ attr }) => t => {
|
|
|
25
21
|
}
|
|
26
22
|
}
|
|
27
23
|
};
|
|
28
|
-
exports.checkingPermittedRoles = checkingPermittedRoles;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkingPresentationalChildren = void 0;
|
|
4
|
-
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
1
|
+
import { getComputedRole } from '@markuplint/ml-spec';
|
|
5
2
|
/**
|
|
6
3
|
* Presentational Children
|
|
7
4
|
*
|
|
@@ -28,7 +25,7 @@ const ml_spec_1 = require("@markuplint/ml-spec");
|
|
|
28
25
|
* > may still be used in the name and description computation
|
|
29
26
|
* > even when not included in the accessibility tree.
|
|
30
27
|
*/
|
|
31
|
-
const checkingPresentationalChildren = ({ el }) => t => {
|
|
28
|
+
export const checkingPresentationalChildren = ({ el }) => t => {
|
|
32
29
|
const ancestor = getAncestorHasPresentationalChildren(el);
|
|
33
30
|
if (!ancestor) {
|
|
34
31
|
return;
|
|
@@ -36,7 +33,7 @@ const checkingPresentationalChildren = ({ el }) => t => {
|
|
|
36
33
|
if (!ancestor.role) {
|
|
37
34
|
return;
|
|
38
35
|
}
|
|
39
|
-
const hasAriaAttr =
|
|
36
|
+
const hasAriaAttr = [...el.attributes].some(attr => /^aria-|^role$/i.test(attr.name));
|
|
40
37
|
if (!hasAriaAttr) {
|
|
41
38
|
return;
|
|
42
39
|
}
|
|
@@ -45,15 +42,13 @@ const checkingPresentationalChildren = ({ el }) => t => {
|
|
|
45
42
|
message: t('it may be ineffective because {0}', t("it has {0} as an ancestor that doesn't expose its descendants to the accessibility tree", t('the "{0*}" {1}', ancestor.role.name, 'role'))),
|
|
46
43
|
};
|
|
47
44
|
};
|
|
48
|
-
exports.checkingPresentationalChildren = checkingPresentationalChildren;
|
|
49
45
|
function getAncestorHasPresentationalChildren(
|
|
50
46
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
51
47
|
el) {
|
|
52
|
-
var _a;
|
|
53
48
|
let current = el.parentElement;
|
|
54
49
|
while (current) {
|
|
55
|
-
const computed =
|
|
56
|
-
if (
|
|
50
|
+
const computed = getComputedRole(el.ownerMLDocument.specs, current, el.rule.options.version);
|
|
51
|
+
if (computed.role?.childrenPresentational) {
|
|
57
52
|
return computed;
|
|
58
53
|
}
|
|
59
54
|
current = current.parentElement;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Options } from '../types';
|
|
1
|
+
import type { Options } from '../types.js';
|
|
2
2
|
import type { ElementChecker } from '@markuplint/ml-core';
|
|
3
3
|
import type { ARIARole } from '@markuplint/ml-spec';
|
|
4
4
|
/**
|
|
@@ -6,10 +6,6 @@ import type { ARIARole } from '@markuplint/ml-spec';
|
|
|
6
6
|
*
|
|
7
7
|
* @see https://w3c.github.io/aria/#mustContain
|
|
8
8
|
*/
|
|
9
|
-
export declare const checkingRequiredOwnedElements: ElementChecker<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
{
|
|
13
|
-
role?: ARIARole | null;
|
|
14
|
-
}
|
|
15
|
-
>;
|
|
9
|
+
export declare const checkingRequiredOwnedElements: ElementChecker<boolean, Options, {
|
|
10
|
+
role?: ARIARole | null;
|
|
11
|
+
}>;
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkingRequiredOwnedElements = void 0;
|
|
4
|
-
const ml_spec_1 = require("@markuplint/ml-spec");
|
|
1
|
+
import { getComputedRole, isRequiredOwnedElement } from '@markuplint/ml-spec';
|
|
5
2
|
/**
|
|
6
3
|
* Required Owned Elements
|
|
7
4
|
*
|
|
8
5
|
* @see https://w3c.github.io/aria/#mustContain
|
|
9
6
|
*/
|
|
10
|
-
const checkingRequiredOwnedElements = ({ el, role }) => t => {
|
|
7
|
+
export const checkingRequiredOwnedElements = ({ el, role }) => t => {
|
|
11
8
|
if (!role) {
|
|
12
9
|
return;
|
|
13
10
|
}
|
|
@@ -28,13 +25,13 @@ const checkingRequiredOwnedElements = ({ el, role }) => t => {
|
|
|
28
25
|
return;
|
|
29
26
|
}
|
|
30
27
|
// TODO: Needs to resolve `aria-own`
|
|
31
|
-
const children =
|
|
28
|
+
const children = [...el.childNodes].map(child => {
|
|
32
29
|
if (child.is(child.ELEMENT_NODE)) {
|
|
33
30
|
if (child.matches('[aria-busy="true" i]')) {
|
|
34
31
|
return [child, 'BUSY'];
|
|
35
32
|
}
|
|
36
|
-
const computedChild =
|
|
37
|
-
if (role.requiredOwnedElements.some(ownedRole =>
|
|
33
|
+
const computedChild = getComputedRole(child.ownerMLDocument.specs, child, child.rule.options.version);
|
|
34
|
+
if (role.requiredOwnedElements.some(ownedRole => isRequiredOwnedElement(computedChild.el, computedChild.role, ownedRole, child.ownerMLDocument.specs, child.rule.options.version))) {
|
|
38
35
|
return [child, 'REQUIRED'];
|
|
39
36
|
}
|
|
40
37
|
return [child, 'OTHER'];
|
|
@@ -78,7 +75,7 @@ const checkingRequiredOwnedElements = ({ el, role }) => t => {
|
|
|
78
75
|
if (mayBeBeforeCreated(el)) {
|
|
79
76
|
return {
|
|
80
77
|
scope: el,
|
|
81
|
-
message: t('{0}. Or, {1}', t('
|
|
78
|
+
message: t('{0}. Or, {1}', t('{0} requires {1}', t('the {0}', 'child element'), role.requiredOwnedElements.length === 1 && role.requiredOwnedElements[0]
|
|
82
79
|
? t('the "{0*}" {1}', role.requiredOwnedElements[0], 'role')
|
|
83
80
|
: t('the {0}', 'roles') + `: ${t(role.requiredOwnedElements)}`), t('require {0}', 'aria-busy="true"')),
|
|
84
81
|
};
|
|
@@ -90,14 +87,13 @@ const checkingRequiredOwnedElements = ({ el, role }) => t => {
|
|
|
90
87
|
: t('the {0}', 'roles') + `: ${t(role.requiredOwnedElements)}`),
|
|
91
88
|
};
|
|
92
89
|
};
|
|
93
|
-
exports.checkingRequiredOwnedElements = checkingRequiredOwnedElements;
|
|
94
90
|
function mayBeBeforeCreated(
|
|
95
91
|
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
96
92
|
el) {
|
|
97
93
|
if (el.isEmpty()) {
|
|
98
94
|
return true;
|
|
99
95
|
}
|
|
100
|
-
return
|
|
96
|
+
return [...el.children].every(child => {
|
|
101
97
|
return ['script', 'template'].includes(child.localName);
|
|
102
98
|
});
|
|
103
99
|
}
|
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import type { Options } from '../types';
|
|
1
|
+
import type { Options } from '../types.js';
|
|
2
2
|
import type { ElementChecker } from '@markuplint/ml-core';
|
|
3
3
|
import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
|
|
4
|
-
export declare const checkingRequiredProp: ElementChecker<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
isImplicit?: boolean;
|
|
11
|
-
})
|
|
12
|
-
| null;
|
|
13
|
-
propSpecs: readonly ARIAProperty[];
|
|
14
|
-
}
|
|
15
|
-
>;
|
|
4
|
+
export declare const checkingRequiredProp: ElementChecker<boolean, Options, {
|
|
5
|
+
role?: (ARIARole & {
|
|
6
|
+
isImplicit?: boolean;
|
|
7
|
+
}) | null;
|
|
8
|
+
propSpecs: readonly ARIAProperty[];
|
|
9
|
+
}>;
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkingRequiredProp = void 0;
|
|
4
|
-
const checkingRequiredProp = ({ el, role, propSpecs }) => t => {
|
|
5
|
-
var _a;
|
|
1
|
+
export const checkingRequiredProp = ({ el, role, propSpecs }) => t => {
|
|
6
2
|
if (!role) {
|
|
7
3
|
return;
|
|
8
4
|
}
|
|
@@ -19,9 +15,8 @@ const checkingRequiredProp = ({ el, role, propSpecs }) => t => {
|
|
|
19
15
|
const propSpec = propSpecs.find(p => p.name === requiredProp);
|
|
20
16
|
return {
|
|
21
17
|
scope: el,
|
|
22
|
-
message: t('{0:c} on {1}', t('Require {0}', t('the "{0*}" {1}', requiredProp, `ARIA ${
|
|
18
|
+
message: t('{0:c} on {1}', t('Require {0}', t('the "{0*}" {1}', requiredProp, `ARIA ${propSpec?.type ?? 'property'}`)), t('the "{0*}" {1}', role.name, 'role')),
|
|
23
19
|
};
|
|
24
20
|
}
|
|
25
21
|
}
|
|
26
22
|
};
|
|
27
|
-
exports.checkingRequiredProp = checkingRequiredProp;
|
|
@@ -1,22 +1,13 @@
|
|
|
1
|
-
import type { Options } from '../types';
|
|
1
|
+
import type { Options } from '../types.js';
|
|
2
2
|
import type { AttrChecker } from '@markuplint/ml-core';
|
|
3
3
|
import type { ARIAProperty, ARIARole } from '@markuplint/ml-spec';
|
|
4
|
-
export declare const checkingValue: AttrChecker<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
propSpecs: readonly ARIAProperty[];
|
|
10
|
-
booleanish?: boolean;
|
|
11
|
-
}
|
|
12
|
-
>;
|
|
4
|
+
export declare const checkingValue: AttrChecker<boolean, Options, {
|
|
5
|
+
role?: ARIARole | null;
|
|
6
|
+
propSpecs: readonly ARIAProperty[];
|
|
7
|
+
booleanish?: boolean;
|
|
8
|
+
}>;
|
|
13
9
|
/**
|
|
14
10
|
*
|
|
15
11
|
* @see https://www.w3.org/TR/wai-aria-1.2/#propcharacteristic_value
|
|
16
12
|
*/
|
|
17
|
-
export declare function checkAriaValue(
|
|
18
|
-
type: string,
|
|
19
|
-
value: string,
|
|
20
|
-
tokenEnum: readonly string[],
|
|
21
|
-
booleanish?: boolean,
|
|
22
|
-
): boolean;
|
|
13
|
+
export declare function checkAriaValue(type: string, value: string, tokenEnum: readonly string[], booleanish?: boolean): boolean;
|
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkAriaValue = exports.checkingValue = void 0;
|
|
4
|
-
const checkingValue = ({ attr, role, propSpecs, booleanish }) => t => {
|
|
5
|
-
var _a;
|
|
1
|
+
export const checkingValue = ({ attr, role, propSpecs, booleanish }) => t => {
|
|
6
2
|
if (attr.isDynamicValue) {
|
|
7
3
|
return;
|
|
8
4
|
}
|
|
9
5
|
const propSpec = propSpecs.find(p => p.name === attr.name);
|
|
10
|
-
const result = checkAria(propSpec, attr.value, role
|
|
6
|
+
const result = checkAria(propSpec, attr.value, role?.name, booleanish);
|
|
11
7
|
if (result.isValid) {
|
|
12
8
|
return;
|
|
13
9
|
}
|
|
14
10
|
return {
|
|
15
11
|
scope: attr,
|
|
16
|
-
message: t('{0:c} on {1}', t('{0} is {1:c}', t('the "{0}"', attr.value), 'disallowed'), t('the "{0*}" {1}', attr.name, `ARIA ${
|
|
12
|
+
message: t('{0:c} on {1}', t('{0} is {1:c}', t('the "{0}"', attr.value), 'disallowed'), t('the "{0*}" {1}', attr.name, `ARIA ${propSpec?.type ?? 'property'}`)) +
|
|
17
13
|
('enum' in result && result.enum.length > 0
|
|
18
14
|
? t('. ') + t('Allowed values are: {0}', t(result.enum))
|
|
19
15
|
: ''),
|
|
20
16
|
};
|
|
21
17
|
};
|
|
22
|
-
exports.checkingValue = checkingValue;
|
|
23
18
|
function checkAria(propSpec, currentValue, role, booleanish) {
|
|
24
19
|
if (!propSpec) {
|
|
25
20
|
return {
|
|
@@ -48,13 +43,13 @@ function checkAria(propSpec, currentValue, role, booleanish) {
|
|
|
48
43
|
*
|
|
49
44
|
* @see https://www.w3.org/TR/wai-aria-1.2/#propcharacteristic_value
|
|
50
45
|
*/
|
|
51
|
-
function checkAriaValue(type, value, tokenEnum, booleanish) {
|
|
46
|
+
export function checkAriaValue(type, value, tokenEnum, booleanish) {
|
|
52
47
|
switch (type) {
|
|
53
48
|
case 'token': {
|
|
54
49
|
return tokenEnum.includes(value);
|
|
55
50
|
}
|
|
56
51
|
case 'token list': {
|
|
57
|
-
const list = value.split(/\s+/
|
|
52
|
+
const list = value.split(/\s+/).map(s => s.trim());
|
|
58
53
|
return list.every(token => tokenEnum.includes(token));
|
|
59
54
|
}
|
|
60
55
|
case 'string':
|
|
@@ -81,13 +76,12 @@ function checkAriaValue(type, value, tokenEnum, booleanish) {
|
|
|
81
76
|
return ['true', 'false', 'undefined'].includes(value);
|
|
82
77
|
}
|
|
83
78
|
case 'integer': {
|
|
84
|
-
return parseInt(value).toString() === value;
|
|
79
|
+
return Number.parseInt(value).toString() === value;
|
|
85
80
|
}
|
|
86
81
|
case 'number': {
|
|
87
|
-
return parseFloat(value).toString() === value;
|
|
82
|
+
return Number.parseFloat(value).toString() === value;
|
|
88
83
|
}
|
|
89
84
|
}
|
|
90
85
|
// For skipping checking
|
|
91
86
|
return true;
|
|
92
87
|
}
|
|
93
|
-
exports.checkAriaValue = checkAriaValue;
|
package/lib/wai-aria/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { Options } from './types';
|
|
2
|
-
declare const _default: Readonly<import(
|
|
1
|
+
import type { Options } from './types.js';
|
|
2
|
+
declare const _default: Readonly<import("@markuplint/ml-core").RuleSeed<boolean, Options>>;
|
|
3
3
|
export default _default;
|
package/lib/wai-aria/index.js
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import { createRule, getAttrSpecs, getComputedRole, ariaSpecs, getSpec } from '@markuplint/ml-core';
|
|
2
|
+
import { ARIA_RECOMMENDED_VERSION } from '@markuplint/ml-spec';
|
|
3
|
+
import { Collection } from '../helpers.js';
|
|
4
|
+
import { checkingAbstractRole } from './checkings/abstract-role.js';
|
|
5
|
+
import { checkingDefaultValue } from './checkings/default-value.js';
|
|
6
|
+
import { checkingDeprecatedProps } from './checkings/deprecated-props.js';
|
|
7
|
+
import { checkingDisallowedProp } from './checkings/disallowed-prop.js';
|
|
8
|
+
import { checkingImplicitProps } from './checkings/implicit-props.js';
|
|
9
|
+
import { checkingImplicitRole } from './checkings/implicit-role.js';
|
|
10
|
+
import { checkingInteractionInHidden } from './checkings/interaction-in-hidden.js';
|
|
11
|
+
import { checkingNoGlobalProp } from './checkings/no-global-prop.js';
|
|
12
|
+
import { checkingNonExistentRole } from './checkings/non-existent-role.js';
|
|
13
|
+
import { checkingPermittedRoles } from './checkings/permitted-roles.js';
|
|
14
|
+
import { checkingPresentationalChildren } from './checkings/presentational-children.js';
|
|
15
|
+
import { checkingRequiredOwnedElements } from './checkings/required-owned-elements.js';
|
|
16
|
+
import { checkingRequiredProp } from './checkings/required-prop.js';
|
|
17
|
+
import { checkingValue } from './checkings/value.js';
|
|
18
|
+
export default createRule({
|
|
19
|
+
meta: {
|
|
20
|
+
category: 'a11y',
|
|
21
|
+
},
|
|
21
22
|
defaultOptions: {
|
|
22
23
|
checkingValue: true,
|
|
23
24
|
checkingDeprecatedProps: true,
|
|
@@ -28,14 +29,14 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
28
29
|
disallowSetImplicitRole: true,
|
|
29
30
|
disallowSetImplicitProps: true,
|
|
30
31
|
disallowDefaultValue: false,
|
|
31
|
-
version:
|
|
32
|
+
version: ARIA_RECOMMENDED_VERSION,
|
|
32
33
|
},
|
|
33
34
|
async verify({ document, report, t }) {
|
|
34
35
|
await document.walkOn('Element', el => {
|
|
35
36
|
const roleAttr = el.getAttributeNode('role');
|
|
36
37
|
const propAttrs = el.attributes.filter(attr => /^aria-/i.test(attr.name));
|
|
37
|
-
const ariaAttrs = new
|
|
38
|
-
const elSpec =
|
|
38
|
+
const ariaAttrs = new Collection(roleAttr, ...propAttrs);
|
|
39
|
+
const elSpec = getSpec(el, document.specs.specs);
|
|
39
40
|
if (!elSpec) {
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
@@ -48,50 +49,50 @@ exports.default = (0, ml_core_1.createRule)({
|
|
|
48
49
|
}
|
|
49
50
|
return;
|
|
50
51
|
}
|
|
51
|
-
const computed =
|
|
52
|
-
const { props: propSpecs } =
|
|
52
|
+
const computed = getComputedRole(document.specs, el, el.rule.options.version);
|
|
53
|
+
const { props: propSpecs } = ariaSpecs(document.specs, el.rule.options.version);
|
|
53
54
|
if (roleAttr) {
|
|
54
|
-
if (report(
|
|
55
|
+
if (report(checkingNonExistentRole({ attr: roleAttr }))) {
|
|
55
56
|
return;
|
|
56
57
|
}
|
|
57
|
-
if (report(
|
|
58
|
+
if (report(checkingAbstractRole({ attr: roleAttr }))) {
|
|
58
59
|
return;
|
|
59
60
|
}
|
|
60
|
-
report(
|
|
61
|
+
report(checkingRequiredProp({ el, role: computed.role, propSpecs }));
|
|
61
62
|
if (el.rule.options.disallowSetImplicitRole) {
|
|
62
|
-
report(
|
|
63
|
+
report(checkingImplicitRole({ attr: roleAttr }));
|
|
63
64
|
}
|
|
64
65
|
if (el.rule.options.permittedAriaRoles) {
|
|
65
|
-
report(
|
|
66
|
+
report(checkingPermittedRoles({ attr: roleAttr }));
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
for (const attr of propAttrs) {
|
|
69
|
-
report(
|
|
70
|
+
report(checkingDisallowedProp({ attr, role: computed.role, propSpecs }));
|
|
70
71
|
if (el.rule.options.checkingDeprecatedProps) {
|
|
71
|
-
report(
|
|
72
|
+
report(checkingDeprecatedProps({ attr, role: computed.role, propSpecs }));
|
|
72
73
|
}
|
|
73
74
|
if (el.rule.options.disallowSetImplicitProps) {
|
|
74
|
-
const attrSpecs =
|
|
75
|
-
report(
|
|
75
|
+
const attrSpecs = getAttrSpecs(el, document.specs);
|
|
76
|
+
report(checkingImplicitProps({ attr, propSpecs, attrSpecs }));
|
|
76
77
|
}
|
|
77
78
|
if (el.rule.options.checkingValue) {
|
|
78
|
-
report(
|
|
79
|
+
report(checkingValue({ attr, role: computed.role, propSpecs, booleanish: document.booleanish }));
|
|
79
80
|
}
|
|
80
81
|
if (el.rule.options.disallowDefaultValue) {
|
|
81
|
-
report(
|
|
82
|
+
report(checkingDefaultValue({ attr, propSpecs }));
|
|
82
83
|
}
|
|
83
84
|
if (!computed.role) {
|
|
84
|
-
report(
|
|
85
|
+
report(checkingNoGlobalProp({ attr, propSpecs }));
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
if (el.rule.options.checkingRequiredOwnedElements) {
|
|
88
|
-
report(
|
|
89
|
+
report(checkingRequiredOwnedElements({ el, role: computed.role }));
|
|
89
90
|
}
|
|
90
91
|
if (el.rule.options.checkingPresentationalChildren) {
|
|
91
|
-
report(
|
|
92
|
+
report(checkingPresentationalChildren({ el }));
|
|
92
93
|
}
|
|
93
94
|
if (el.rule.options.checkingInteractionInHidden) {
|
|
94
|
-
report(
|
|
95
|
+
report(checkingInteractionInHidden({ el }));
|
|
95
96
|
}
|
|
96
97
|
});
|
|
97
98
|
},
|