Skip to content

Commit ddb4d69

Browse files
committed
a11y: implement media-has-caption rule
1 parent 2548877 commit ddb4d69

File tree

5 files changed

+199
-5
lines changed

5 files changed

+199
-5
lines changed

src/compiler/compile/nodes/Element.ts

+23
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,29 @@ export default class Element extends Node {
276276
}
277277
}
278278

279+
if (this.is_media_node()) {
280+
const has_muted_attribute = this.attributes.some(attr => attr.name === 'muted');
281+
282+
if (has_muted_attribute) {
283+
return;
284+
}
285+
286+
const is_track = (child: INode) => child.type === 'Element' && child.name === 'track';
287+
const is_caption = (attr: Attribute) =>
288+
attr.name === 'kind' &&
289+
attr.get_static_value().toString().toLowerCase() === 'captions';
290+
const has_captions = this.children.some(
291+
child => !is_track(child) ? false : child.attributes.some(is_caption)
292+
);
293+
294+
if (!has_captions) {
295+
this.component.warn(this, {
296+
code: `a11y-media-has-caption`,
297+
message: `A11y: <${this.name}> should have a <track> for captions`
298+
});
299+
}
300+
}
301+
279302
this.validate_attributes();
280303
this.validate_special_cases();
281304
this.validate_bindings();
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
<div><video class="svelte-xyz" autoplay></video>
2-
<video></video></div>
1+
<div><video class="svelte-xyz" autoplay muted></video>
2+
<video muted></video></div>
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<div>
2-
<video autoplay></video>
3-
<video></video>
2+
<video autoplay muted></video>
3+
<video muted></video>
44
</div>
55

66
<style>
77
[autoplay] {
88
color: red;
99
}
10-
</style>
10+
</style>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<script>
2+
export let x;
3+
</script>
4+
5+
<!-- valid -->
6+
<audio>
7+
<track kind="captions" />
8+
</audio>
9+
<audio>
10+
<track kind="Captions" />
11+
</audio>
12+
<audio>
13+
<track kind="Captions" />
14+
<track kind="subtitles" />
15+
</audio>
16+
<audio muted />
17+
<audio muted={x} />
18+
19+
<video>
20+
<track kind="captions" />
21+
</video>
22+
<video>
23+
<track kind="Captions" />
24+
</video>
25+
<video>
26+
<track kind="Captions" />
27+
<track kind="subtitles" />
28+
</video>
29+
<video muted />
30+
<video muted={x} />
31+
32+
<!-- invalid -->
33+
<audio>
34+
<track />
35+
</audio>
36+
<audio>
37+
<track kind="subtitles" />
38+
</audio>
39+
<audio />
40+
<audio>Foo</audio>
41+
42+
<video>
43+
<track />
44+
</video>
45+
<video>
46+
<track kind="subtitles" />
47+
</video>
48+
<video />
49+
<video>Foo</video>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
[
2+
{
3+
"code": "a11y-media-has-caption",
4+
"message": "A11y: <audio> should have a <track> for captions",
5+
"pos": 470,
6+
"start": {
7+
"character": 470,
8+
"column": 0,
9+
"line": 33
10+
},
11+
"end": {
12+
"character": 498,
13+
"column": 8,
14+
"line": 35
15+
}
16+
},
17+
{
18+
"code": "a11y-media-has-caption",
19+
"message": "A11y: <audio> should have a <track> for captions",
20+
"pos": 499,
21+
"start": {
22+
"character": 499,
23+
"column": 0,
24+
"line": 36
25+
},
26+
"end": {
27+
"character": 544,
28+
"column": 8,
29+
"line": 38
30+
}
31+
},
32+
{
33+
"code": "a11y-media-has-caption",
34+
"message": "A11y: <audio> should have a <track> for captions",
35+
"pos": 545,
36+
"start": {
37+
"character": 545,
38+
"column": 0,
39+
"line": 39
40+
},
41+
"end": {
42+
"character": 554,
43+
"column": 9,
44+
"line": 39
45+
}
46+
},
47+
{
48+
"code": "a11y-media-has-caption",
49+
"message": "A11y: <audio> should have a <track> for captions",
50+
"pos": 555,
51+
"start": {
52+
"character": 555,
53+
"column": 0,
54+
"line": 40
55+
},
56+
"end": {
57+
"character": 573,
58+
"column": 18,
59+
"line": 40
60+
}
61+
},
62+
{
63+
"code": "a11y-media-has-caption",
64+
"message": "A11y: <video> should have a <track> for captions",
65+
"pos": 575,
66+
"start": {
67+
"character": 575,
68+
"column": 0,
69+
"line": 42
70+
},
71+
"end": {
72+
"character": 603,
73+
"column": 8,
74+
"line": 44
75+
}
76+
},
77+
{
78+
"code": "a11y-media-has-caption",
79+
"message": "A11y: <video> should have a <track> for captions",
80+
"pos": 604,
81+
"start": {
82+
"character": 604,
83+
"column": 0,
84+
"line": 45
85+
},
86+
"end": {
87+
"character": 649,
88+
"column": 8,
89+
"line": 47
90+
}
91+
},
92+
{
93+
"code": "a11y-media-has-caption",
94+
"message": "A11y: <video> should have a <track> for captions",
95+
"pos": 650,
96+
"start": {
97+
"character": 650,
98+
"column": 0,
99+
"line": 48
100+
},
101+
"end": {
102+
"character": 659,
103+
"column": 9,
104+
"line": 48
105+
}
106+
},
107+
{
108+
"code": "a11y-media-has-caption",
109+
"message": "A11y: <video> should have a <track> for captions",
110+
"pos": 660,
111+
"start": {
112+
"character": 660,
113+
"column": 0,
114+
"line": 49
115+
},
116+
"end": {
117+
"character": 678,
118+
"column": 18,
119+
"line": 49
120+
}
121+
}
122+
]

0 commit comments

Comments
 (0)