diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d6a949..de014b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#69](https://github.com/green-code-initiative/creedengo-javascript/pull/69) Only support string literals (GCI11) - [#70](https://github.com/green-code-initiative/creedengo-javascript/pull/70) Only support SQL queries within standard methods (GCI24) - [#71](https://github.com/green-code-initiative/creedengo-javascript/pull/71) Avoid triggering an exception (GCI12) +- [#73](https://github.com/green-code-initiative/creedengo-javascript/pull/73) Avoid false-positive with nested objects (GCI12) ## [2.0.0] - 2025-01-22 diff --git a/eslint-plugin/lib/rules/no-multiple-style-changes.js b/eslint-plugin/lib/rules/no-multiple-style-changes.js index fba0183..3f0877e 100644 --- a/eslint-plugin/lib/rules/no-multiple-style-changes.js +++ b/eslint-plugin/lib/rules/no-multiple-style-changes.js @@ -37,11 +37,23 @@ module.exports = { const isNodeUseStyleProperty = (node) => node?.object?.property?.name === "style"; + const getNodeFullName = (node) => { + let names = []; + do { + names.unshift(node.name ?? node.property.name); + node = node.object; + } while (node); + return names.join("."); + }; + return { AssignmentExpression(node) { - // Are we checking an assignation on a style property - if (isNodeUseStyleProperty(node.left)) { - const domElementName = node.left.object.object.name; + // Check if there is a literal assignation on a style property + if ( + node.right.type === "Literal" && + isNodeUseStyleProperty(node.left) + ) { + const domElementName = getNodeFullName(node.left.object.object); const currentRangestart = node.left.object.object.range[0]; /** @@ -58,7 +70,8 @@ module.exports = { e.type === "ExpressionStatement" && e.expression.type === "AssignmentExpression" && isNodeUseStyleProperty(e.expression.left) && - e.expression.left.object.object.name === domElementName, + getNodeFullName(e.expression.left.object.object) === + domElementName, ); // De-duplication, prevents multiple alerts for each line involved diff --git a/eslint-plugin/tests/lib/rules/no-multiple-style-changes.js b/eslint-plugin/tests/lib/rules/no-multiple-style-changes.js index e5e724d..507d70b 100644 --- a/eslint-plugin/tests/lib/rules/no-multiple-style-changes.js +++ b/eslint-plugin/tests/lib/rules/no-multiple-style-changes.js @@ -29,7 +29,12 @@ const RuleTester = require("eslint").RuleTester; // Tests //------------------------------------------------------------------------------ -const ruleTester = new RuleTester(); +const ruleTester = new RuleTester({ + parserOptions: { + ecmaVersion: 2021, + sourceType: "module", + }, +}); const expectedError = { messageId: "UseClassInstead", type: "AssignmentExpression", @@ -52,6 +57,22 @@ ruleTester.run("no-multiple-style-changes", rule, { function a() { element.style.width = "800px"; } `, }, + { + name: "should not report on different elements in same object", + code: ` + var elements = { element1, element2 }; + elements.element1.style.height = "800px"; + elements.element2.style.height = "800px"; + `, + }, + { + code: ` + var offsetWidth = 5; + var offsetLeft = 3; + element.style.width = \`\${offsetWidth}px\`; + element.style.left = \`\${offsetLeft}px\`; + `, + }, ], invalid: [ @@ -71,6 +92,14 @@ ruleTester.run("no-multiple-style-changes", rule, { `, errors: [expectedError], }, + { + code: ` + var elements = { element1 }; + elements.element1.style.height = "800px"; + elements.element1.style.height = "800px"; + `, + errors: [expectedError], + }, { code: ` function changeStyle()