Skip to content

fix: make no-invalid-properties var() case-insensitive #232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/rules/no-invalid-properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
205 changes: 205 additions & 0 deletions tests/rules/no-invalid-properties.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -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 }],
Expand All @@ -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
Expand Down Expand Up @@ -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: [
Expand All @@ -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: [
Expand Down Expand Up @@ -592,5 +668,134 @@ ruleTester.run("no-invalid-properties", rule, {
},
],
},
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CSS variables --my-color is not case sensitive, can we please add a few cases to verify the rule is working as expected for them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are case-sensitive. From MDN:

Note: Custom property names are case sensitive — --my-color will be treated as a separate custom property to --My-color.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry! I meant case sensitive only, just add a case where it is working as expected

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-width> || <line-style> || <color>",
},
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-width> || <line-style> || <color>",
},
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-width> || <line-style> || <color>",
},
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-width> || <line-style> || <color>",
},
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,
},
],
},
],
});
Loading