From 673155a87fabe393b6736f1eb7b09bc5b3a0fac7 Mon Sep 17 00:00:00 2001 From: thecalamiity Date: Fri, 8 Aug 2025 20:04:37 +0300 Subject: [PATCH 1/3] fix: make no-invalid-properties var() case-insensitive --- src/rules/no-invalid-properties.js | 11 +- tests/rules/no-invalid-properties.test.js | 155 ++++++++++++++++++++++ 2 files changed, 162 insertions(+), 4 deletions(-) diff --git a/src/rules/no-invalid-properties.js b/src/rules/no-invalid-properties.js index 104d236b..cc7c0810 100644 --- a/src/rules/no-invalid-properties.js +++ b/src/rules/no-invalid-properties.js @@ -37,7 +37,7 @@ function getVarFallbackList(value) { while (true) { const match = currentValue.match( - /var\(\s*(--[^,\s)]+)\s*(?:,\s*(.+))?\)/u, + /var\(\s*(--[^,\s)]+)\s*(?:,\s*(.+))?\)/iu, ); if (!match) { @@ -54,7 +54,7 @@ function getVarFallbackList(value) { } // If fallback is not another var(), we're done - if (!fallback.includes("var(")) { + if (!fallback.toLowerCase().includes("var(")) { list.push(fallback); break; } @@ -129,7 +129,7 @@ export default { replacements.push(new Map()); }, - "Function[name=var]"(node) { + "Function[name=/^var$/i]"(node) { const map = replacements.at(-1); if (!map) { return; @@ -166,7 +166,10 @@ export default { // When `var()` is used, we store all the values to `valueList` with the replacement of `var()` with there values or fallback values for (const child of valueNodes) { // If value is a function starts with `var()` - if (child.type === "Function" && child.name === "var") { + if ( + child.type === "Function" && + child.name.toLowerCase() === "var" + ) { const varValue = vars.get(child.children[0].name); // If the variable is found, use its value, otherwise check for fallback values diff --git a/tests/rules/no-invalid-properties.test.js b/tests/rules/no-invalid-properties.test.js index d8768749..44294c6d 100644 --- a/tests/rules/no-invalid-properties.test.js +++ b/tests/rules/no-invalid-properties.test.js @@ -55,6 +55,24 @@ ruleTester.run("no-invalid-properties", rule, { ":root { --my-color: red; }\na { color: var(--my-color, var(--fallback-color, var(--foo, var(--bar)))) }", ":root { --my-color: red; }\na { color: var(--my-color, var(--fallback-color, var(--foo, var(--bar, blue)))) }", ":root { --color: red }\na { border-top: 1px var(--style, var(--fallback, solid)) var(--color, blue); }", + "a { color: VAR(--my-color, red) }", + ":root { --my-heading: 3rem; }\na { color: vAr(--my-color, red) }", + ":root { --my-heading: 3rem; --foo: red }\na { color: VAR(--my-color, VAR(--foo, blue)) }", + ":root { --my-heading: 3rem; }\na { color: VAR(--my-color, vAr(--foo, blue)) }", + "a { color: vAR(--my-color, VaR(--foo, VAR(--bar, blue))) }", + ":root { --my-color: red; }\na { color: Var(--my-color, blue) }", + ":root { --my-fallback: red; }\na { color: var(--my-color, VAR(--my-fallback)) }", + ":root { --my-fallback: red; }\na { color: VAR(--my-color, var(--my-fallback, blue)) }", + ":root { --foo: red; }\na { color: vAr(--my-color, VAR(--my-fallback, VaR(--foo))) }", + "a { color: VAR(--my-color, vAr(--my-fallback, VAR(--foo, blue))) }", + ":root { --my-color: red; }\na { color: Var(--my-color, VAR(--fallback-color)) }", + ":root { --my-color: red; --fallback-color: blue; }\na { color: VAR(--my-color, var(--fallback-color)) }", + ":root { --my-color: red; }\na { color: var(--my-color, VaR(--fallback-color, blue)) }", + ":root { --my-color: red; }\na { color: VAR(--my-color, vAr(--fallback-color, VAR(--foo))) }", + ":root { --my-color: red; }\na { color: vAr(--my-color, VAR(--fallback-color, var(--foo, blue))) }", + ":root { --my-color: red; }\na { color: VAR(--my-color, vAr(--fallback-color, VAR(--foo, var(--bar)))) }", + ":root { --my-color: red; }\na { color: vAr(--my-color, VAR(--fallback-color, var(--foo, VaR(--bar, blue)))) }", + ":root { --color: red }\na { border-top: 1px VAR(--style, vAr(--fallback, solid)) VaR(--color, blue); }", { code: "a { my-custom-color: red; }", languageOptions: { @@ -69,6 +87,10 @@ ruleTester.run("no-invalid-properties", rule, { code: "a { color: var(--my-color); }", options: [{ allowUnknownVariables: true }], }, + { + code: "a { color: VAR(--my-color); }", + options: [{ allowUnknownVariables: true }], + }, { code: "a { --my-color: red; color: var(--my-color); background-color: var(--unknown-var); }", options: [{ allowUnknownVariables: true }], @@ -77,6 +99,10 @@ ruleTester.run("no-invalid-properties", rule, { code: ":root { --color: red }\na { border-top: 1px var(--style, var(--fallback)) var(--color, blue); }", options: [{ allowUnknownVariables: true }], }, + { + code: ":root { --color: red }\na { border-top: 1px VAR(--style, VAR(--fallback)) VAR(--color, blue); }", + options: [{ allowUnknownVariables: true }], + }, /* * CSSTree doesn't currently support custom functions properly, so leaving @@ -592,5 +618,134 @@ ruleTester.run("no-invalid-properties", rule, { }, ], }, + { + code: "a { color: VAR(--my-color); }", + errors: [ + { + messageId: "unknownVar", + data: { + var: "--my-color", + }, + line: 1, + column: 16, + endLine: 1, + endColumn: 26, + }, + ], + }, + { + code: "a { border-top: 1px vAr(--style, solid) VaR(--color); }", + errors: [ + { + messageId: "unknownVar", + data: { + var: "--color", + }, + line: 1, + column: 45, + endLine: 1, + endColumn: 52, + }, + ], + }, + { + code: ":root { --style: foo }\na { border-top: 1px VAR(--style) VAR(--color, red); }", + errors: [ + { + messageId: "invalidPropertyValue", + data: { + property: "border-top", + value: "foo", + expected: " || || ", + }, + line: 2, + column: 21, + endLine: 2, + endColumn: 33, + }, + ], + }, + { + code: ":root { --style: foo }\na { border-top: 1px VAR(--style, solid) VAR(--color, red); }", + errors: [ + { + messageId: "invalidPropertyValue", + data: { + property: "border-top", + value: "foo", + expected: " || || ", + }, + line: 2, + column: 21, + endLine: 2, + endColumn: 40, + }, + ], + }, + { + code: ":root { --color: foo }\na { border-top: 1px VAR(--style, VAR(--fallback, solid)) VAR(--color); }", + errors: [ + { + messageId: "invalidPropertyValue", + data: { + property: "border-top", + value: "foo", + expected: " || || ", + }, + line: 2, + column: 58, + endLine: 2, + endColumn: 70, + }, + ], + }, + { + code: ":root { --color: foo }\na { border-top: 1px VAR(--style, VAR(--fallback)) VAR(--color); }", + options: [{ allowUnknownVariables: true }], + errors: [ + { + messageId: "invalidPropertyValue", + data: { + property: "border-top", + value: "foo", + expected: " || || ", + }, + line: 2, + column: 51, + endLine: 2, + endColumn: 63, + }, + ], + }, + { + code: ":root { --color: foo }\na { border-top: 1px VAR(--style, VAR(--fallback)) VAR(--color); }", + errors: [ + { + messageId: "unknownVar", + data: { + var: "--style", + }, + line: 2, + column: 25, + endLine: 2, + endColumn: 32, + }, + ], + }, + { + code: ":root { --color: red }\na { colorr: VAR(--color, blue); }", + errors: [ + { + messageId: "unknownProperty", + data: { + property: "colorr", + }, + line: 2, + column: 5, + endLine: 2, + endColumn: 11, + }, + ], + }, ], }); From 8aed4ade2d5b5ac84c32e94222aa9946154a51d9 Mon Sep 17 00:00:00 2001 From: thecalamiity Date: Sat, 9 Aug 2025 17:36:04 +0300 Subject: [PATCH 2/3] add case-sensitivity tests for variables --- tests/rules/no-invalid-properties.test.js | 35 +++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/rules/no-invalid-properties.test.js b/tests/rules/no-invalid-properties.test.js index 44294c6d..2b2a9cad 100644 --- a/tests/rules/no-invalid-properties.test.js +++ b/tests/rules/no-invalid-properties.test.js @@ -73,6 +73,11 @@ ruleTester.run("no-invalid-properties", rule, { ":root { --my-color: red; }\na { color: VAR(--my-color, vAr(--fallback-color, VAR(--foo, var(--bar)))) }", ":root { --my-color: red; }\na { color: vAr(--my-color, VAR(--fallback-color, var(--foo, VaR(--bar, blue)))) }", ":root { --color: red }\na { border-top: 1px VAR(--style, vAr(--fallback, solid)) VaR(--color, blue); }", + ":root { --MY-COLOR: red; }\na { color: var(--MY-COLOR) }", + ":root { --my-color: red; }\na { color: var(--MY-COLOR, red) }", + ":root { --MY-COLOR: red; }\na { color: var(--my-color, blue) }", + ":root { --FALLBACK-COLOR: blue; }\na { color: var(--MY-COLOR, var(--FALLBACK-COLOR)) }", + ":root { --fallback-color: blue; }\na { color: VAR(--MY-COLOR, VaR(--fallback-color)) }", { code: "a { my-custom-color: red; }", languageOptions: { @@ -321,6 +326,21 @@ ruleTester.run("no-invalid-properties", rule, { }, ], }, + { + code: "a { color: var(--MY-COLOR); }", + errors: [ + { + messageId: "unknownVar", + data: { + var: "--MY-COLOR", + }, + line: 1, + column: 16, + endLine: 1, + endColumn: 26, + }, + ], + }, { code: "a { .foo { color: var(--undefined-var); } }", errors: [ @@ -336,6 +356,21 @@ ruleTester.run("no-invalid-properties", rule, { }, ], }, + { + code: "a { color: var(--MY-COLOR, var(--FALLBACK-COLOR)); }", + errors: [ + { + messageId: "unknownVar", + data: { + var: "--MY-COLOR", + }, + line: 1, + column: 16, + endLine: 1, + endColumn: 26, + }, + ], + }, { code: "a { --my-color: 10px; color: var(--my-color); }", errors: [ From cfccf345d80a8657b99755f853b335a82d30a5bd Mon Sep 17 00:00:00 2001 From: thecalamiity Date: Sat, 9 Aug 2025 17:44:18 +0300 Subject: [PATCH 3/3] include an additional test --- tests/rules/no-invalid-properties.test.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/rules/no-invalid-properties.test.js b/tests/rules/no-invalid-properties.test.js index 2b2a9cad..fa5babc3 100644 --- a/tests/rules/no-invalid-properties.test.js +++ b/tests/rules/no-invalid-properties.test.js @@ -341,6 +341,21 @@ ruleTester.run("no-invalid-properties", rule, { }, ], }, + { + code: "a { --my-color: red; color: var(--MY-COLOR); }", + errors: [ + { + messageId: "unknownVar", + data: { + var: "--MY-COLOR", + }, + line: 1, + column: 33, + endLine: 1, + endColumn: 43, + }, + ], + }, { code: "a { .foo { color: var(--undefined-var); } }", errors: [