Skip to content

Commit 622bfc1

Browse files
committed
swtich to use aria-query
1 parent a85e5d3 commit 622bfc1

File tree

6 files changed

+61
-26
lines changed

6 files changed

+61
-26
lines changed

package-lock.json

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,14 @@
124124
"@rollup/plugin-typescript": "^2.0.1",
125125
"@rollup/plugin-virtual": "^2.0.0",
126126
"@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.8.0",
127+
"@types/aria-query": "^5.0.0",
127128
"@types/mocha": "^7.0.0",
128129
"@types/node": "^8.10.53",
129130
"@typescript-eslint/eslint-plugin": "^5.22.0",
130131
"@typescript-eslint/parser": "^5.22.0",
131132
"acorn": "^8.4.1",
132133
"agadoo": "^1.1.0",
134+
"aria-query": "^5.0.0",
133135
"code-red": "^0.2.5",
134136
"css-tree": "^1.1.2",
135137
"eslint": "^8.0.0",

src/compiler/compile/compiler_warnings.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ export default {
8080
code: 'a11y-no-redundant-roles',
8181
message: `A11y: Redundant role '${role}'`
8282
}),
83+
a11y_role_has_required_aria_props: (role: string, props: string[]) => ({
84+
code: 'a11y-role-has-required-aria-props',
85+
message: `A11y: Elements with the ARIA role "${role}" must have the following attributes defined: ${props.map(name => `"${name}"`).join(', ')}`
86+
}),
8387
a11y_accesskey: {
8488
code: 'a11y-accesskey',
8589
message: 'A11y: Avoid using accesskey'

src/compiler/compile/nodes/Element.ts

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { string_literal } from '../utils/stringify';
2323
import { Literal } from 'estree';
2424
import compiler_warnings from '../compiler_warnings';
2525
import compiler_errors from '../compiler_errors';
26+
import { ARIARoleDefintionKey, roles } from 'aria-query';
2627

2728
const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/;
2829

@@ -45,20 +46,6 @@ const a11y_required_attributes = {
4546
object: ['title', 'aria-label', 'aria-labelledby']
4647
};
4748

48-
const a11y_required_role_props = {
49-
checkbox: ['aria-checked'],
50-
combobox: ['aria-controls', 'aria-expanded'],
51-
heading: ['aria-level'],
52-
menuitemcheckbox: ['aria-checked'],
53-
menuitemradio: ['aria-checked'],
54-
meter: ['aria-valuemax', 'aria-valuemin', 'aria-valuenow'],
55-
option: ['aria-selected'],
56-
radio: ['aria-checked'],
57-
scrollbar: ['aria-controls', 'aria-valuenow'],
58-
slider: ['aria-valuenow'],
59-
switch: ['aria-checked']
60-
};
61-
6249
const a11y_distracting_elements = new Set([
6350
'blink',
6451
'marquee'
@@ -477,18 +464,14 @@ export default class Element extends Node {
477464
}
478465
}
479466

480-
// @ts-ignore
481-
const required_role_props = a11y_required_role_props[value];
482-
483467
// role-has-required-aria-props
484-
if (required_role_props) {
468+
const role = roles.get(value as ARIARoleDefintionKey);
469+
if (role) {
470+
const required_role_props = Object.keys(role.requiredProps);
485471
const has_missing_props = required_role_props.some(prop => !attributes.find(a => a.name === prop));
486472

487473
if (has_missing_props) {
488-
component.warn(attribute, {
489-
code: 'a11y-role-has-required-aria-props',
490-
message: `A11y: Elements with the ARIA role "${value}" must have the following attributes defined: ${String(required_role_props)}`
491-
});
474+
component.warn(attribute, compiler_warnings.a11y_role_has_required_aria_props(value as string, required_role_props));
492475
}
493476
}
494477
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
<div role="heading"></div>
22
<span role="checkbox"></span>
33
<div role="meter"></div>
4+
<div role="scrollbar"></div>
45

56
<div role="heading" aria-level="1"></div>
67
<span role="checkbox" aria-checked="false"></span>
7-
<div role="meter" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>
8+
<div role="meter" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>
9+
<div role="scrollbar" aria-controls="panel" aria-valuenow="50"></div>

test/validator/samples/a11y-role-has-required-aria-props/warnings.json

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[
22
{
33
"code": "a11y-role-has-required-aria-props",
4-
"message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: aria-level",
4+
"message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"",
55
"start": {
66
"line": 1,
77
"column": 5,
@@ -16,7 +16,7 @@
1616
},
1717
{
1818
"code": "a11y-role-has-required-aria-props",
19-
"message": "A11y: Elements with the ARIA role \"checkbox\" must have the following attributes defined: aria-checked",
19+
"message": "A11y: Elements with the ARIA role \"checkbox\" must have the following attributes defined: \"aria-checked\"",
2020
"start": {
2121
"line": 2,
2222
"column": 6,
@@ -31,7 +31,7 @@
3131
},
3232
{
3333
"code": "a11y-role-has-required-aria-props",
34-
"message": "A11y: Elements with the ARIA role \"meter\" must have the following attributes defined: aria-valuemax,aria-valuemin,aria-valuenow",
34+
"message": "A11y: Elements with the ARIA role \"meter\" must have the following attributes defined: \"aria-valuenow\"",
3535
"start": {
3636
"line": 3,
3737
"column": 5,
@@ -43,5 +43,20 @@
4343
"character": 74
4444
},
4545
"pos": 62
46+
},
47+
{
48+
"code": "a11y-role-has-required-aria-props",
49+
"message": "A11y: Elements with the ARIA role \"scrollbar\" must have the following attributes defined: \"aria-controls\", \"aria-valuenow\"",
50+
"start": {
51+
"character": 87,
52+
"column": 5,
53+
"line": 4
54+
},
55+
"end": {
56+
"character": 103,
57+
"column": 21,
58+
"line": 4
59+
},
60+
"pos": 87
4661
}
4762
]

0 commit comments

Comments
 (0)