Skip to content

Commit

Permalink
Merge pull request #22 from elisecodedestrucs/no-missing-print-css
Browse files Browse the repository at this point in the history
add rule provide-print-css
  • Loading branch information
utarwyn authored Sep 10, 2023
2 parents 88a4400 + dee4f3e commit 2886107
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#21](https://github.com/green-code-initiative/ecoCode-javascript/pull/21) Add rule `@ecocode/avoid-css-animations`
- [#18](https://github.com/green-code-initiative/ecoCode-javascript/pull/18) Add rule `@ecocode/limit-db-query-results`
- [#19](https://github.com/green-code-initiative/ecoCode-javascript/pull/19) Add rule `@ecocode/no-empty-image-src-attribute`
- [#22](https://github.com/green-code-initiative/ecoCode-javascript/pull/22) Add rule `@ecocode/provide-print-css`
- [#207](https://github.com/green-code-initiative/ecoCode/issues/207) Add release tag analyzis on SonarCloud

### Changed
Expand Down
1 change: 1 addition & 0 deletions eslint-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Add `@ecocode` to the `plugins` section of your `.eslintrc`, followed by rules c
| [no-multiple-access-dom-element](docs/rules/no-multiple-access-dom-element.md) | Disallow multiple access of same DOM element. ||
| [no-multiple-style-changes](docs/rules/no-multiple-style-changes.md) | Disallow multiple style changes at once. ||
| [prefer-collections-with-pagination](docs/rules/prefer-collections-with-pagination.md) | Prefer API collections with pagination. ||
| [provide-print-css](docs/rules/provide-print-css.md) | Enforce providing a print stylesheet ||

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

Expand Down
46 changes: 46 additions & 0 deletions eslint-plugin/docs/rules/provide-print-css.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Enforce providing a print stylesheet (`@ecocode/provide-print-css`)

⚠️ This rule _warns_ in the ✅ `recommended` config.

<!-- end auto-generated rule header -->

## Rule Details

This rule aims to remind developers to use CSS print to limit the number of pages printed therefore indirectly reducing
the impact of the web page.

## Examples

Examples of **non-compliant** code for this rule:

```html
<head>
<title>Web Page</title>
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
```

Examples of **compliant** code for this rule:

```html
<head>
<title>Web Page</title>
<link rel="stylesheet" media="print" type="text/css" href="print.css" />
</head>
```

```html
<head>
<title>Web Page</title>
<style>
@media print {
/* Print-specific styles */
}
</style>
</head>
```

## Further details

This recommendation is made by the
CNUMR: [Provide a print CSS](https://github.com/cnumr/best-practices/blob/main/chapters/BP_027_en.md)
81 changes: 81 additions & 0 deletions eslint-plugin/lib/rules/provide-print-css.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* Copyright (C) 2023 Green Code Initiative
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";

/** @type {import("eslint").Rule.RuleModule} */
module.exports = {
meta: {
type: "suggestion",
docs: {
description: "Enforce providing a print stylesheet",
category: "eco-design",
recommended: "warn",
},
messages: {
noPrintCSSProvided: "Provide a print CSS",
},
schema: [],
},
create(context) {
const isStyleWithPrintNode = (node) => {
return (
node.openingElement.name.name === "style" &&
node.children.some((child) => {
let element = null;
if (child.value != null) {
element = child.value;
} else if (child.expression != null) {
if (child.expression.value != null) {
element = child.expression.value;
} else if (
child.expression.quasis != null &&
child.expression.quasis.length > 0
) {
element = child.expression.quasis[0].value.cooked;
}
}
return element != null && element.includes("@media print");
})
);
};

const isLinkForPrintNode = (node) =>
node.openingElement.name.name === "link" &&
node.openingElement.attributes.some(
(attr) => attr.name.name === "media" && attr.value.value === "print",
);

return {
JSXElement(node) {
if (node.openingElement.name.name === "head") {
const hasValidElement = node.children.some(
(child) =>
child.openingElement != null &&
(isStyleWithPrintNode(child) || isLinkForPrintNode(child)),
);

if (!hasValidElement) {
context.report({
node: node,
messageId: "noPrintCSSProvided",
});
}
}
},
};
},
};
95 changes: 95 additions & 0 deletions eslint-plugin/tests/lib/rules/provide-print-css.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* Copyright (C) 2023 Green Code Initiative
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const rule = require("../../../lib/rules/provide-print-css");
const RuleTester = require("eslint").RuleTester;

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 6,
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
},
});

const expectedError = {
messageId: "noPrintCSSProvided",
type: "JSXElement",
};

ruleTester.run("provide-print-css", rule, {
valid: [
`
<head>
<title>Web Page</title>
<link rel="stylesheet" href="styles.css" media="print" />
</head>
`,
`
<head>
<title>Web Page</title>
<style>@media print {}</style>
</head>
`,
`
<head>
<title>Web Page</title>
<style>{'@media print {}'}</style>
</head>
`,
`
<head>
<title>Web Page</title>
<link rel="stylesheet" href="styles.css" media="print" />,
<style>{'@media print {}'}</style>
</head>
`,
"<head><style>{`@media print {}`}</style></head>",
`<link rel="stylesheet" href="styles.css" />`,
],
invalid: [
{
code: `
<head>
<title>Web Page</title>
<link rel="stylesheet" href="styles.css" />
</head>
`,
errors: [expectedError],
},
{
code: `
<head>
<title>Web Page</title>
<style>{'@media desktop {}'}</style>
</head>
`,
errors: [expectedError],
},
],
});

0 comments on commit 2886107

Please sign in to comment.