From 90b3b11e3bffceef8b600c3555dc3402825bf542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20L=C3=B6wenstein?= Date: Mon, 26 Jun 2023 23:41:27 +0200 Subject: [PATCH 1/3] added css variable minification for calc expressions with one argument --- src/lib.rs | 5 +++++ src/properties/custom.rs | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index fe6ad684..fc43456e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7462,6 +7462,11 @@ mod tests { ".foo{transform:rotateX(-40deg)rotateY(50deg)}", ); minify_test(".foo { width: calc(10px * mod(18, 5)) }", ".foo{width:30px}"); + minify_test(":root { --foo: calc(1px)}",":root{--foo:1px}"); + //TODO implement + //minify_test(":root { --foo: calc(1px + 2px)}",":root{--foo:3px}"); + //TODO implement + //minify_test(":root { --foo: calc(1px + 2px + var(--foo))}",":root{--foo:calc(3px + var(--foo))}"); } #[test] diff --git a/src/properties/custom.rs b/src/properties/custom.rs index 8795dee7..d03660a0 100644 --- a/src/properties/custom.rs +++ b/src/properties/custom.rs @@ -393,6 +393,20 @@ impl<'i> TokenList<'i> { tokens.push(TokenOrValue::Url(Url::parse(input)?)); last_is_delim = false; last_is_whitespace = false; + } else if f == "calc" { + let arguments = input.parse_nested_block(|input| TokenList::parse(input, options, depth + 1))?; + if arguments.0.len() == 1 { + tokens.push(arguments.0.first().unwrap().clone()); + } else { + //TODO simple calc with multiple values of the same unit (1px + 2px) + //TODO retain any var functions or other unknown expressions + tokens.push(TokenOrValue::Function(Function { + name: Ident(f), + arguments, + })); + } + last_is_delim = true; // Whitespace is not required after any of these chars. + last_is_whitespace = false; } else if f == "var" { let var = input.parse_nested_block(|input| { let var = Variable::parse(input, options, depth + 1)?; From cc41dec2409c60fddb3764433bcbf961a8262bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20L=C3=B6wenstein?= Date: Thu, 29 Jun 2023 23:51:11 +0200 Subject: [PATCH 2/3] added removal of nested calc function --- src/lib.rs | 4 +++- src/properties/custom.rs | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fc43456e..7484f8b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7462,7 +7462,9 @@ mod tests { ".foo{transform:rotateX(-40deg)rotateY(50deg)}", ); minify_test(".foo { width: calc(10px * mod(18, 5)) }", ".foo{width:30px}"); - minify_test(":root { --foo: calc(1px)}",":root{--foo:1px}"); + minify_test(".foo { --foo: calc(1px)}",".foo{--foo:1px}"); + minify_test(".foo { --foo: calc(calc(1px + 2px) + 2px)}",".foo{--foo:calc((1px + 2px) + 2px)}"); + minify_test(".foo { --foo: calc(max(1px, 2px) + 2px)}",".foo{--foo:calc(max(1px,2px) + 2px)}"); //TODO implement //minify_test(":root { --foo: calc(1px + 2px)}",":root{--foo:3px}"); //TODO implement diff --git a/src/properties/custom.rs b/src/properties/custom.rs index d03660a0..39c13a15 100644 --- a/src/properties/custom.rs +++ b/src/properties/custom.rs @@ -398,11 +398,26 @@ impl<'i> TokenList<'i> { if arguments.0.len() == 1 { tokens.push(arguments.0.first().unwrap().clone()); } else { - //TODO simple calc with multiple values of the same unit (1px + 2px) - //TODO retain any var functions or other unknown expressions + let mut new_arguments = vec![]; + for argument in arguments.0.iter() { + match argument { + TokenOrValue::Function(inner_f) => { + if inner_f.name == "calc" { + new_arguments.push(TokenOrValue::Token(Token::ParenthesisBlock)); + new_arguments.append(&mut inner_f.arguments.0.to_vec()); + new_arguments.push(TokenOrValue::Token(Token::CloseParenthesis)); + } else { + new_arguments.push(argument.clone()); + } + }, + _ => { + new_arguments.push(argument.clone()); + } + } + } tokens.push(TokenOrValue::Function(Function { name: Ident(f), - arguments, + arguments: TokenList(new_arguments) })); } last_is_delim = true; // Whitespace is not required after any of these chars. From 61b3fb4007bb46c183a4a1bb126ae783abed82e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20L=C3=B6wenstein?= Date: Fri, 30 Jun 2023 19:22:10 +0200 Subject: [PATCH 3/3] add removal of parenthesis around single token in calc function --- src/lib.rs | 3 ++- src/properties/custom.rs | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7484f8b7..082c3863 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7464,7 +7464,8 @@ mod tests { minify_test(".foo { width: calc(10px * mod(18, 5)) }", ".foo{width:30px}"); minify_test(".foo { --foo: calc(1px)}",".foo{--foo:1px}"); minify_test(".foo { --foo: calc(calc(1px + 2px) + 2px)}",".foo{--foo:calc((1px + 2px) + 2px)}"); - minify_test(".foo { --foo: calc(max(1px, 2px) + 2px)}",".foo{--foo:calc(max(1px,2px) + 2px)}"); + minify_test(".foo { --foo: calc(max(20px, 1em) + 2px)}",".foo{--foo:calc(max(20px,1em) + 2px)}"); + minify_test(".foo { --foo: calc(2px + (2px))}",".foo{--foo:calc(2px + 2px)}"); //TODO implement //minify_test(":root { --foo: calc(1px + 2px)}",":root{--foo:3px}"); //TODO implement diff --git a/src/properties/custom.rs b/src/properties/custom.rs index 39c13a15..8b603246 100644 --- a/src/properties/custom.rs +++ b/src/properties/custom.rs @@ -395,12 +395,28 @@ impl<'i> TokenList<'i> { last_is_whitespace = false; } else if f == "calc" { let arguments = input.parse_nested_block(|input| TokenList::parse(input, options, depth + 1))?; - if arguments.0.len() == 1 { + if arguments.0.len() == 0 { + // this is invalid css + tokens.push(TokenOrValue::Function(Function { + name: Ident(f), + arguments + })); + } else if arguments.0.len() == 1 { tokens.push(arguments.0.first().unwrap().clone()); } else { let mut new_arguments = vec![]; - for argument in arguments.0.iter() { + let mut n = 0; + while n < arguments.0.len() { + let argument = &arguments.0[n]; match argument { + TokenOrValue::Token(Token::ParenthesisBlock) => { + if n + 2 < arguments.0.len() && arguments.0[n + 2] == TokenOrValue::Token(Token::CloseParenthesis) { + new_arguments.push(arguments.0[n + 1].clone()); + n += 2; + } else { + new_arguments.push(argument.clone()); + } + } TokenOrValue::Function(inner_f) => { if inner_f.name == "calc" { new_arguments.push(TokenOrValue::Token(Token::ParenthesisBlock)); @@ -414,6 +430,7 @@ impl<'i> TokenList<'i> { new_arguments.push(argument.clone()); } } + n += 1; } tokens.push(TokenOrValue::Function(Function { name: Ident(f),