Skip to content

Commit 4f1705e

Browse files
committed
Add rule "Avoid autoplay"
Co-authored-by: [email protected]
1 parent b80b84e commit 4f1705e

File tree

10 files changed

+293
-15
lines changed

10 files changed

+293
-15
lines changed

eslint-plugin/README.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,19 @@ Add `@ecocode` to the `plugins` section of your `.eslintrc`, followed by rules c
6767
⚠️ Configurations set to warn in.\
6868
✅ Set in the `recommended` configuration.
6969

70-
| Name | Description | ⚠️ |
71-
| :------------------------------------------------------------------------------------- | :--------------------------------------------------------- | :- |
72-
| [avoid-css-animations](docs/rules/avoid-css-animations.md) | Avoid usage of CSS animations ||
73-
| [avoid-high-accuracy-geolocation](docs/rules/avoid-high-accuracy-geolocation.md) | Avoid using high accuracy geolocation in web applications. ||
74-
| [limit-db-query-results](docs/rules/limit-db-query-results.md) | Should limit the number of returns for a SQL query ||
75-
| [no-empty-image-src-attribute](docs/rules/no-empty-image-src-attribute.md) | Disallow usage of image with empty source attribute ||
76-
| [no-import-all-from-library](docs/rules/no-import-all-from-library.md) | Should not import all from library ||
77-
| [no-multiple-access-dom-element](docs/rules/no-multiple-access-dom-element.md) | Disallow multiple access of same DOM element. ||
78-
| [no-multiple-style-changes](docs/rules/no-multiple-style-changes.md) | Disallow multiple style changes at once. ||
79-
| [prefer-collections-with-pagination](docs/rules/prefer-collections-with-pagination.md) | Prefer API collections with pagination. ||
80-
| [prefer-shorthand-css-notations](docs/rules/prefer-shorthand-css-notations.md) | Encourage usage of shorthand CSS notations ||
81-
| [provide-print-css](docs/rules/provide-print-css.md) | Enforce providing a print stylesheet ||
70+
| Name                               | Description | ⚠️ |
71+
| :------------------------------------------------------------------------------------- | :------------------------------------------------------------------------ | :- |
72+
| [avoid-autoplay](docs/rules/avoid-autoplay.md) | Disallow autoplay and enforce preload='none' for video and audio elements ||
73+
| [avoid-css-animations](docs/rules/avoid-css-animations.md) | Avoid usage of CSS animations ||
74+
| [avoid-high-accuracy-geolocation](docs/rules/avoid-high-accuracy-geolocation.md) | Avoid using high accuracy geolocation in web applications. ||
75+
| [limit-db-query-results](docs/rules/limit-db-query-results.md) | Should limit the number of returns for a SQL query ||
76+
| [no-empty-image-src-attribute](docs/rules/no-empty-image-src-attribute.md) | Disallow usage of image with empty source attribute ||
77+
| [no-import-all-from-library](docs/rules/no-import-all-from-library.md) | Should not import all from library ||
78+
| [no-multiple-access-dom-element](docs/rules/no-multiple-access-dom-element.md) | Disallow multiple access of same DOM element. ||
79+
| [no-multiple-style-changes](docs/rules/no-multiple-style-changes.md) | Disallow multiple style changes at once. ||
80+
| [prefer-collections-with-pagination](docs/rules/prefer-collections-with-pagination.md) | Prefer API collections with pagination. ||
81+
| [prefer-shorthand-css-notations](docs/rules/prefer-shorthand-css-notations.md) | Encourage usage of shorthand CSS notations ||
82+
| [provide-print-css](docs/rules/provide-print-css.md) | Enforce providing a print stylesheet ||
8283

8384
<!-- end auto-generated rules list -->
8485

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Disallow autoplay and enforce preload='none' for video and audio elements (`@ecocode/avoid-autoplay`)
2+
3+
⚠️ This rule _warns_ in the ✅ `recommended` config.
4+
5+
<!-- end auto-generated rule header -->
6+
7+
⚠️ This rule _warns_ in the ✅ `recommended` config.
8+
9+
<!-- end auto-generated rule header -->
10+
11+
## Why is this an issue?
12+
13+
Automatic videos and audio files activation (autoplay) during web pages loading uses resources on each tier (device,
14+
network, data center). In many cases, automatic playback is not necessary. Moreover, it can draw users' attention and
15+
distract them from the initially requested service. Therefore, whenever possible, these playbacks should be initiated by
16+
the users and by not using the autoplay attributes in the `<audio>` and `<video>` elements.
17+
18+
Nevertheless, some parts of the video or audio files may be downloaded even if autoplay is not activated. Moreover, data
19+
will be unnecessarily downloaded even if users do not start the video playback. It is therefore necessary to force
20+
browsers not to preload anything by setting the `preload` attribute to `none`.
21+
22+
```jsx
23+
return (
24+
<>
25+
<video src="video.mp4" autoplay/> // Non-compliant
26+
<video src="video.mp4" preload="auto"/> // Non-compliant
27+
<video src="video.mp4" autoplay preload="auto"/> // Non-compliant
28+
<video src="video.mp4" preload="none"/> // Compliant
29+
</>
30+
)
31+
```
32+
33+
This rule is build for [React](https://react.dev/) and JSX.
34+
35+
## Resources
36+
37+
### Documentation
38+
39+
- [Mozilla Web Technology for Developers](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/autoplay) -
40+
Autoplay in HTML
41+
- [Mozilla Web Technology for Developers](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) - Video and
42+
audio content
43+
- [Mozilla Web Technology for Developers](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#attr-preload) -
44+
Preload in HTML
45+
46+
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* ecoCode JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
3+
* Copyright © 2023 Green Code Initiative (https://www.ecocode.io)
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:
27+
"Disallow autoplay and enforce preload='none' for video and audio elements",
28+
category: "eco-design",
29+
recommended: "warn",
30+
},
31+
messages: {
32+
NoAutoplay:
33+
"Avoid using autoplay attribute for <video> and <audio> elements. Reference to Rule RGESN 4.1 : https://www.arcep.fr/mes-demarches-et-services/entreprises/fiches-pratiques/referentiel-general-ecoconception-services-numeriques.html",
34+
EnforcePreloadNone:
35+
"Set preload='none' for <video> and <audio> elements. Reference to Rule RGESN 4.1 : https://www.arcep.fr/mes-demarches-et-services/entreprises/fiches-pratiques/referentiel-general-ecoconception-services-numeriques.html",
36+
NoAutoplay_EnforcePreloadNone:
37+
"Avoid using autoplay attribute and set preload='none' for <video> and <audio> elements. Reference to Rule RGESN 4.1 : https://www.arcep.fr/mes-demarches-et-services/entreprises/fiches-pratiques/referentiel-general-ecoconception-services-numeriques.html ",
38+
},
39+
schema: [],
40+
},
41+
create(context) {
42+
return {
43+
JSXOpeningElement(node) {
44+
if (node.name.name === "video" || node.name.name === "audio") {
45+
const autoplayAttr = node.attributes.find(
46+
(attr) => attr.name.name === "autoplay",
47+
);
48+
const preloadAttr = node.attributes.find(
49+
(attr) => attr.name.name === "preload",
50+
);
51+
if (
52+
autoplayAttr &&
53+
(!preloadAttr || preloadAttr.value.value !== "none")
54+
) {
55+
context.report({
56+
node: autoplayAttr || preloadAttr,
57+
messageId: "NoAutoplay_EnforcePreloadNone",
58+
});
59+
} else {
60+
if (autoplayAttr) {
61+
context.report({
62+
node: autoplayAttr,
63+
messageId: "NoAutoplay",
64+
});
65+
}
66+
67+
if (!preloadAttr || preloadAttr.value.value !== "none") {
68+
context.report({
69+
node: preloadAttr || node,
70+
messageId: "EnforcePreloadNone",
71+
});
72+
}
73+
}
74+
}
75+
},
76+
};
77+
},
78+
};
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* ecoCode JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
3+
* Copyright © 2023 Green Code Initiative (https://www.ecocode.io)
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+
const expectedError1 = {
42+
messageId: "NoAutoplay",
43+
type: "JSXAttribute",
44+
};
45+
const expectedError2 = {
46+
messageId: "EnforcePreloadNone",
47+
type: "JSXAttribute",
48+
};
49+
const expectedError3 = {
50+
messageId: "NoAutoplay_EnforcePreloadNone",
51+
type: "JSXAttribute",
52+
};
53+
54+
ruleTester.run("autoplay-audio-video-attribute-not-present", rule, {
55+
valid: [
56+
`
57+
<audio preload="none"></audio>
58+
`,
59+
'<video preload="none"></video>',
60+
],
61+
62+
invalid: [
63+
{
64+
code: `
65+
<audio autoplay></audio>
66+
`,
67+
errors: [expectedError3],
68+
},
69+
{
70+
code: `
71+
<video autoplay preload="auto"></video>
72+
`,
73+
errors: [expectedError3],
74+
},
75+
{
76+
code: '<video autoplay preload="none"></video>',
77+
errors: [expectedError1],
78+
},
79+
{
80+
code: '<audio preload="auto"></audio>',
81+
errors: [expectedError2],
82+
},
83+
],
84+
});

sonar-plugin/src/main/java/io/ecocode/javascript/CheckList.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ public static List<Class<? extends JavaScriptCheck>> getAllChecks() {
4343
NoMultipleStyleChanges.class,
4444
PreferCollectionsWithPagination.class,
4545
PreferShorthandCSSNotations.class,
46-
ProvidePrintCSS.class
46+
ProvidePrintCSS.class,
47+
AvoidAutoPlay.class
4748
);
4849
}
4950

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* ecoCode JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
3+
* Copyright © 2023 Green Code Initiative (https://www.ecocode.io)
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 io.ecocode.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+
@JavaScriptRule
25+
@TypeScriptRule
26+
@Rule(key = AvoidAutoPlay.RULE_KEY)
27+
public class AvoidAutoPlay implements EslintBasedCheck {
28+
public static final String RULE_KEY = "EC36";
29+
30+
@Override
31+
public String eslintKey() {
32+
return "@ecocode/avoid-autoplay";
33+
}
34+
}

sonar-plugin/src/main/resources/io/ecocode/profiles/ecocode_javascript_profile.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"EC25",
1010
"EC26",
1111
"EC29",
12-
"EC30"
12+
"EC30",
13+
"EC36"
1314
]
1415
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"name": "ecoCode",
33
"ruleKeys": [
4-
"EC13"
4+
"EC13",
5+
"EC36"
56
]
67
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Title</title>
6+
</head>
7+
<body>
8+
9+
</body>
10+
</html>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"title": "Avoid autoplay for videos and audio content",
3+
"type": "CODE_SMELL",
4+
"code": {
5+
"impacts": {
6+
"MAINTAINABILITY": "MEDIUM"
7+
},
8+
"attribute": "EFFICIENT"
9+
},
10+
"status": "ready",
11+
"remediation": {
12+
"func": "Constant\/Issue",
13+
"constantCost": "5min"
14+
},
15+
"tags": [
16+
"ecocode",
17+
"eco-design",
18+
"video",
19+
"audio"
20+
],
21+
"defaultSeverity": "Major"
22+
}

0 commit comments

Comments
 (0)