Skip to content

Commit a14c77c

Browse files
chihebtalandianecdrutarwyn
authored
Add rule GCI36 "Avoid autoplay for videos and audio content" (#40)
Co-authored-by: Diane Cordier <[email protected]> Co-authored-by: utarwyn <[email protected]>
1 parent 858f078 commit a14c77c

File tree

9 files changed

+251
-1
lines changed

9 files changed

+251
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- [#40](https://github.com/green-code-initiative/creedengo-javascript/pull/40) Add rule `@creedengo/avoid-autoplay` (GCI36)
13+
1014
## [2.0.0] - 2025-01-22
1115

1216
### Added

eslint-plugin/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ Add `@creedengo` to the `plugins` section of your `.eslintrc`, followed by rules
7676

7777
| Name | Description | ⚠️ |
7878
| :------------------------------------------------------------------------------------- | :-------------------------------------------------------- | :- |
79+
| [avoid-autoplay](docs/rules/avoid-autoplay.md) | Avoid autoplay for videos and audio content ||
7980
| [avoid-brightness-override](docs/rules/avoid-brightness-override.md) | Should avoid to override brightness ||
8081
| [avoid-css-animations](docs/rules/avoid-css-animations.md) | Avoid usage of CSS animations ||
8182
| [avoid-high-accuracy-geolocation](docs/rules/avoid-high-accuracy-geolocation.md) | Avoid using high accuracy geolocation in web applications ||
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Avoid autoplay for videos and audio content (`@creedengo/avoid-autoplay`)
2+
3+
⚠️ This rule _warns_ in the ✅ `recommended` config.
4+
5+
<!-- end auto-generated rule header -->
6+
7+
## Why is this an issue?
8+
9+
Automatic videos and audio files activation (autoplay) during web pages loading uses resources on each tier (device,
10+
network, data center). In many cases, automatic playback is not necessary. Moreover, it can draw users' attention and
11+
distract them from the initially requested service. Therefore, whenever possible, these playbacks should be initiated by
12+
the users and by not using the autoplay attributes in the `<audio>` and `<video>` elements.
13+
14+
Nevertheless, some parts of the video or audio files may be downloaded even if autoplay is not activated. Moreover, data
15+
will be unnecessarily downloaded even if users do not start the video playback. It is therefore necessary to force
16+
browsers not to preload anything by setting the `preload` attribute to `none`.
17+
18+
```jsx
19+
return (
20+
<>
21+
<video src="video.mp4" autoplay/> // Non-compliant
22+
<video src="video.mp4" preload="auto"/> // Non-compliant
23+
<video src="video.mp4" autoplay preload="auto"/> // Non-compliant
24+
<video src="video.mp4" preload="none"/> // Compliant
25+
</>
26+
)
27+
```
28+
29+
This rule is build for [React](https://react.dev/) and JSX.
30+
31+
## Resources
32+
33+
### Documentation
34+
35+
- [Mozilla Web Technology for Developers](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/autoplay) -
36+
Autoplay in HTML
37+
- [Mozilla Web Technology for Developers](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) - Video and
38+
audio content
39+
- [Mozilla Web Technology for Developers](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#attr-preload) -
40+
Preload in HTML
41+
- [W3C](https://w3c.github.io/sustyweb/star.html#UX16-1) - Autoplay attribute
42+
- [RGESN](https://www.arcep.fr/mes-demarches-et-services/entreprises/fiches-pratiques/referentiel-general-ecoconception-services-numeriques.html) - Reference Rule 4.1
43+
44+
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* creedengo JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
3+
* Copyright © 2023 Green Code Initiative (https://green-code-initiative.org)
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
"use strict";
20+
21+
/** @type {import("eslint").Rule.RuleModule} */
22+
module.exports = {
23+
meta: {
24+
type: "suggestion",
25+
docs: {
26+
description: "Avoid autoplay for videos and audio content",
27+
category: "eco-design",
28+
recommended: "warn",
29+
},
30+
messages: {
31+
NoAutoplay: "Avoid autoplay for video and audio elements.",
32+
EnforcePreloadNone: "Set preload='none' for video and audio elements.",
33+
NoAutoplayAndEnforcePreloadNone:
34+
"Avoid autoplay and set preload='none' for video and audio elements.",
35+
},
36+
schema: [],
37+
},
38+
create(context) {
39+
return {
40+
JSXOpeningElement(node) {
41+
if (node.name.name === "video" || node.name.name === "audio") {
42+
const autoplayAttr = node.attributes.find(
43+
(attr) => attr.name?.name.toLowerCase() === "autoplay",
44+
);
45+
const preloadAttr = node.attributes.find(
46+
(attr) => attr.name?.name.toLowerCase() === "preload",
47+
);
48+
if (
49+
autoplayAttr &&
50+
(!preloadAttr || preloadAttr.value.value !== "none")
51+
) {
52+
context.report({
53+
node: autoplayAttr || preloadAttr,
54+
messageId: "NoAutoplayAndEnforcePreloadNone",
55+
});
56+
} else {
57+
if (autoplayAttr) {
58+
context.report({
59+
node: autoplayAttr,
60+
messageId: "NoAutoplay",
61+
});
62+
}
63+
64+
if (!preloadAttr || preloadAttr.value.value !== "none") {
65+
context.report({
66+
node: preloadAttr || node,
67+
messageId: "EnforcePreloadNone",
68+
});
69+
}
70+
}
71+
}
72+
},
73+
};
74+
},
75+
};
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* creedengo JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
3+
* Copyright © 2023 Green Code Initiative (https://green-code-initiative.org)
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
"use strict";
20+
21+
//------------------------------------------------------------------------------
22+
// Requirements
23+
//------------------------------------------------------------------------------
24+
25+
const rule = require("../../../lib/rules/avoid-autoplay");
26+
const RuleTester = require("eslint").RuleTester;
27+
28+
//------------------------------------------------------------------------------
29+
// Tests
30+
//------------------------------------------------------------------------------
31+
32+
const ruleTester = new RuleTester({
33+
parserOptions: {
34+
ecmaVersion: 2021,
35+
sourceType: "module",
36+
ecmaFeatures: {
37+
jsx: true,
38+
},
39+
},
40+
});
41+
42+
const noAutoplayError = {
43+
messageId: "NoAutoplay",
44+
type: "JSXAttribute",
45+
};
46+
const enforcePreloadNoneError = {
47+
messageId: "EnforcePreloadNone",
48+
type: "JSXAttribute",
49+
};
50+
const BothError = {
51+
messageId: "NoAutoplayAndEnforcePreloadNone",
52+
type: "JSXAttribute",
53+
};
54+
55+
ruleTester.run("autoplay-audio-video-attribute-not-present", rule, {
56+
valid: [
57+
'<audio preload="none"></audio>',
58+
'<video preload="none"></video>',
59+
'<video preload="none" {...props}></video>',
60+
],
61+
invalid: [
62+
{
63+
code: "<audio autoplay></audio>",
64+
errors: [BothError],
65+
},
66+
{
67+
code: "<audio autoPlay></audio>",
68+
errors: [BothError],
69+
},
70+
{
71+
code: "<audio autoPlay={true}></audio>",
72+
errors: [BothError],
73+
},
74+
{
75+
code: '<video autoplay preload="auto"></video>',
76+
errors: [BothError],
77+
},
78+
{
79+
code: '<video autoplay preload="none"></video>',
80+
errors: [noAutoplayError],
81+
},
82+
{
83+
code: '<audio preload="auto"></audio>',
84+
errors: [enforcePreloadNoneError],
85+
},
86+
],
87+
});

sonar-plugin/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
<project.build.sourceEncoding>${encoding}</project.build.sourceEncoding>
5050
<project.reporting.outputEncoding>${encoding}</project.reporting.outputEncoding>
5151

52-
<version.creedengo-rules-specifications>2.1.0</version.creedengo-rules-specifications>
52+
<version.creedengo-rules-specifications>2.2.1</version.creedengo-rules-specifications>
5353
<version.sonarqube>9.14.0.375</version.sonarqube>
5454
<version.sonar-javascript>9.13.0.20537</version.sonar-javascript>
5555
<version.sonar-packaging>1.23.0.740</version.sonar-packaging>

sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/CheckList.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ private CheckList() {
3434

3535
public static List<Class<? extends JavaScriptCheck>> getAllChecks() {
3636
return Arrays.asList(
37+
AvoidAutoPlay.class,
3738
AvoidBrightnessOverride.class,
3839
AvoidCSSAnimations.class,
3940
AvoidHighAccuracyGeolocation.class,
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Creedengo JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
3+
* Copyright © 2023 Green Code Initiative (https://green-code-initiative.org)
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package org.greencodeinitiative.creedengo.javascript.checks;
19+
20+
import org.sonar.check.Rule;
21+
import org.sonar.plugins.javascript.api.EslintBasedCheck;
22+
import org.sonar.plugins.javascript.api.JavaScriptRule;
23+
import org.sonar.plugins.javascript.api.TypeScriptRule;
24+
25+
@JavaScriptRule
26+
@TypeScriptRule
27+
@Rule(key = AvoidAutoPlay.RULE_KEY)
28+
public class AvoidAutoPlay implements EslintBasedCheck {
29+
30+
public static final String RULE_KEY = "GCI36";
31+
32+
@Override
33+
public String eslintKey() {
34+
return "@creedengo/avoid-autoplay";
35+
}
36+
37+
}

sonar-plugin/src/main/resources/org/greencodeinitiative/creedengo/profiles/javascript_profile.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"GCI26",
1010
"GCI29",
1111
"GCI30",
12+
"GCI36",
1213
"GCI523",
1314
"GCI530"
1415
]

0 commit comments

Comments
 (0)