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..fa5babc3 100644 --- a/tests/rules/no-invalid-properties.test.js +++ b/tests/rules/no-invalid-properties.test.js @@ -55,6 +55,29 @@ 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); }", + ":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: { @@ -69,6 +92,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 +104,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 @@ -295,6 +326,36 @@ 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 { --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: [ @@ -310,6 +371,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: [ @@ -592,5 +668,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, + }, + ], + }, ], });