Skip to content

Commit 58790a9

Browse files
a11y: check if mouse events are accompanied by key events (#5938)
1 parent 50bff36 commit 58790a9

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

src/compiler/compile/nodes/Element.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,20 @@ export default class Element extends Node {
599599
});
600600
}
601601
}
602+
603+
if (handlers_map.has('mouseover') && !handlers_map.has('focus')) {
604+
component.warn(this, {
605+
code: 'a11y-mouse-events-have-key-events',
606+
message: 'A11y: on:mouseover must be accompanied by on:focus'
607+
});
608+
}
609+
610+
if (handlers_map.has('mouseout') && !handlers_map.has('blur')) {
611+
component.warn(this, {
612+
code: 'a11y-mouse-events-have-key-events',
613+
message: 'A11y: on:mouseout must be accompanied by on:blur'
614+
});
615+
}
602616
}
603617

604618
validate_bindings_foreign() {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script>
2+
// Even if otherProps contains onBlur and/or onFocus, the rule will still fail.
3+
// Props should be passed down explicitly for rule to pass.
4+
const otherProps = {
5+
onBlur: () => void 0,
6+
onFocus: () => void 0,
7+
};
8+
</script>
9+
10+
<div on:mouseover={() => void 0} />
11+
<div on:mouseover={() => void 0} on:focus={() => void 0} />
12+
<div on:mouseover={() => void 0} {...otherProps} />
13+
<div on:mouseout={() => void 0} />
14+
<div on:mouseout={() => void 0} on:blur={() => void 0} />
15+
<div on:mouseout={() => void 0} {...otherProps} />
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
[
2+
{
3+
"code": "a11y-mouse-events-have-key-events",
4+
"end": {
5+
"character": 272,
6+
"column": 35,
7+
"line": 10
8+
},
9+
"message": "A11y: on:mouseover must be accompanied by on:focus",
10+
"pos": 237,
11+
"start": {
12+
"character": 237,
13+
"column": 0,
14+
"line": 10
15+
}
16+
},
17+
{
18+
"code": "a11y-mouse-events-have-key-events",
19+
"end": {
20+
"character": 384,
21+
"column": 51,
22+
"line": 12
23+
},
24+
"message": "A11y: on:mouseover must be accompanied by on:focus",
25+
"pos": 333,
26+
"start": {
27+
"character": 333,
28+
"column": 0,
29+
"line": 12
30+
}
31+
},
32+
{
33+
"code": "a11y-mouse-events-have-key-events",
34+
"end": {
35+
"character": 419,
36+
"column": 34,
37+
"line": 13
38+
},
39+
"message": "A11y: on:mouseout must be accompanied by on:blur",
40+
"pos": 385,
41+
"start": {
42+
"character": 385,
43+
"column": 0,
44+
"line": 13
45+
}
46+
},
47+
{
48+
"code": "a11y-mouse-events-have-key-events",
49+
"end": {
50+
"character": 528,
51+
"column": 50,
52+
"line": 15
53+
},
54+
"message": "A11y: on:mouseout must be accompanied by on:blur",
55+
"pos": 478,
56+
"start": {
57+
"character": 478,
58+
"column": 0,
59+
"line": 15
60+
}
61+
}
62+
]

0 commit comments

Comments
 (0)