mirror of
https://github.com/swc-project/swc.git
synced 2024-12-25 22:56:11 +03:00
feat(css/minifier): Handle nested calc()
(#6153)
This commit is contained in:
parent
30f3de2fe2
commit
d4a733d764
@ -184,6 +184,20 @@ impl CalcSumContext {
|
||||
let mut sum = s.clone();
|
||||
self.nested_fold(operator, &mut sum);
|
||||
}
|
||||
CalcValueOrOperator::Value(CalcValue::Function(Function {
|
||||
name, value, ..
|
||||
})) if is_calc_function_name(name) && value.len() == 1 => {
|
||||
match &value[0] {
|
||||
ComponentValue::CalcSum(calc_sum) => {
|
||||
let mut sum = calc_sum.clone();
|
||||
self.nested_fold(operator, &mut sum);
|
||||
}
|
||||
_ => {
|
||||
// Other cases (constant, function...), just push the data
|
||||
self.push(operator, operand);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Other cases (constant, function...), just push the data
|
||||
self.push(operator, operand);
|
||||
@ -970,39 +984,23 @@ impl Compressor {
|
||||
ComponentValue::CalcSum(CalcSum {
|
||||
expressions: calc_sum_expressions,
|
||||
..
|
||||
}) if calc_sum_expressions.len() == 1 => {
|
||||
match &calc_sum_expressions[0] {
|
||||
}) if calc_sum_expressions.len() == 1 => match &calc_sum_expressions[0] {
|
||||
CalcProductOrOperator::Product(CalcProduct {
|
||||
expressions: calc_product_expressions,
|
||||
..
|
||||
}) if calc_product_expressions.len() == 1 => {
|
||||
match &calc_product_expressions[0] {
|
||||
CalcValueOrOperator::Value(CalcValue::Sum(_)) => {
|
||||
// Do nothing, we cannot transform a
|
||||
// CalcSum into a ComponentValue
|
||||
}
|
||||
CalcValueOrOperator::Value(CalcValue::Constant(_)) => {
|
||||
// https://www.w3.org/TR/css-values-4/#calc-constants
|
||||
// "These keywords are only usable
|
||||
// within a calculation"
|
||||
// "If used outside of a calculation,
|
||||
// they’re treated like any other
|
||||
// keyword"
|
||||
}
|
||||
// `calc` and other math functions can be used in `@supports` to
|
||||
// check availability, we should leave them as is
|
||||
CalcValueOrOperator::Value(calc_value)
|
||||
if !self.in_supports_conidition =>
|
||||
if let CalcValueOrOperator::Value(calc_value) =
|
||||
&calc_product_expressions[0]
|
||||
{
|
||||
*component_value =
|
||||
transform_calc_value_into_component_value(calc_value);
|
||||
if let Some(cv) =
|
||||
transform_calc_value_into_component_value(calc_value)
|
||||
{
|
||||
*component_value = cv;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -13,46 +13,30 @@ impl Compressor {
|
||||
ComponentValue::CalcSum(CalcSum {
|
||||
expressions: calc_sum_expressions,
|
||||
..
|
||||
}) if calc_sum_expressions.len() == 1 => {
|
||||
match &calc_sum_expressions[0] {
|
||||
}) if calc_sum_expressions.len() == 1 => match &calc_sum_expressions[0] {
|
||||
CalcProductOrOperator::Product(CalcProduct {
|
||||
expressions: calc_product_expressions,
|
||||
..
|
||||
}) if calc_product_expressions.len() == 1 => {
|
||||
match &calc_product_expressions[0] {
|
||||
CalcValueOrOperator::Value(CalcValue::Sum(_)) => {
|
||||
// Do nothing, we cannot transform a
|
||||
// CalcSum into a ComponentValue
|
||||
}
|
||||
CalcValueOrOperator::Value(CalcValue::Constant(_)) => {
|
||||
// https://www.w3.org/TR/css-values-4/#calc-constants
|
||||
// "These keywords are only usable
|
||||
// within a calculation"
|
||||
// "If used outside of a calculation,
|
||||
// they’re treated like any other
|
||||
// keyword"
|
||||
}
|
||||
CalcValueOrOperator::Value(calc_value) => {
|
||||
match transform_calc_value_into_component_value(calc_value)
|
||||
if let CalcValueOrOperator::Value(calc_value) =
|
||||
&calc_product_expressions[0]
|
||||
{
|
||||
ComponentValue::Function(function) => {
|
||||
match transform_calc_value_into_component_value(calc_value) {
|
||||
Some(ComponentValue::Function(function)) => {
|
||||
*n = SizeFeatureValue::Function(function);
|
||||
}
|
||||
ComponentValue::Dimension(dimension) => {
|
||||
Some(ComponentValue::Dimension(dimension)) => {
|
||||
*n = SizeFeatureValue::Dimension(dimension);
|
||||
}
|
||||
ComponentValue::Number(number) => {
|
||||
Some(ComponentValue::Number(number)) => {
|
||||
*n = SizeFeatureValue::Number(number);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -7,72 +7,76 @@ pub fn is_calc_function_name(ident: &Ident) -> bool {
|
||||
|| ident.value.to_ascii_lowercase() == js_word!("-moz-calc")
|
||||
}
|
||||
|
||||
pub fn transform_calc_value_into_component_value(calc_value: &CalcValue) -> ComponentValue {
|
||||
pub fn transform_calc_value_into_component_value(calc_value: &CalcValue) -> Option<ComponentValue> {
|
||||
match &calc_value {
|
||||
CalcValue::Number(n) => ComponentValue::Number(n.clone()),
|
||||
CalcValue::Number(n) => Some(ComponentValue::Number(n.clone())),
|
||||
CalcValue::Dimension(Dimension::Length(l)) => {
|
||||
ComponentValue::Dimension(Dimension::Length(Length {
|
||||
Some(ComponentValue::Dimension(Dimension::Length(Length {
|
||||
span: l.span,
|
||||
value: l.value.clone(),
|
||||
unit: l.unit.clone(),
|
||||
}))
|
||||
})))
|
||||
}
|
||||
CalcValue::Dimension(Dimension::Angle(a)) => {
|
||||
ComponentValue::Dimension(Dimension::Angle(Angle {
|
||||
Some(ComponentValue::Dimension(Dimension::Angle(Angle {
|
||||
span: a.span,
|
||||
value: a.value.clone(),
|
||||
unit: a.unit.clone(),
|
||||
}))
|
||||
})))
|
||||
}
|
||||
CalcValue::Dimension(Dimension::Time(t)) => {
|
||||
ComponentValue::Dimension(Dimension::Time(Time {
|
||||
Some(ComponentValue::Dimension(Dimension::Time(Time {
|
||||
span: t.span,
|
||||
value: t.value.clone(),
|
||||
unit: t.unit.clone(),
|
||||
}))
|
||||
})))
|
||||
}
|
||||
CalcValue::Dimension(Dimension::Frequency(f)) => {
|
||||
ComponentValue::Dimension(Dimension::Frequency(Frequency {
|
||||
Some(ComponentValue::Dimension(Dimension::Frequency(Frequency {
|
||||
span: f.span,
|
||||
value: f.value.clone(),
|
||||
unit: f.unit.clone(),
|
||||
}))
|
||||
})))
|
||||
}
|
||||
CalcValue::Dimension(Dimension::Resolution(r)) => {
|
||||
ComponentValue::Dimension(Dimension::Resolution(Resolution {
|
||||
CalcValue::Dimension(Dimension::Resolution(r)) => Some(ComponentValue::Dimension(
|
||||
Dimension::Resolution(Resolution {
|
||||
span: r.span,
|
||||
value: r.value.clone(),
|
||||
unit: r.unit.clone(),
|
||||
}))
|
||||
}
|
||||
}),
|
||||
)),
|
||||
CalcValue::Dimension(Dimension::Flex(f)) => {
|
||||
ComponentValue::Dimension(Dimension::Flex(Flex {
|
||||
Some(ComponentValue::Dimension(Dimension::Flex(Flex {
|
||||
span: f.span,
|
||||
value: f.value.clone(),
|
||||
unit: f.unit.clone(),
|
||||
}))
|
||||
})))
|
||||
}
|
||||
CalcValue::Dimension(Dimension::UnknownDimension(u)) => {
|
||||
ComponentValue::Dimension(Dimension::UnknownDimension(UnknownDimension {
|
||||
CalcValue::Dimension(Dimension::UnknownDimension(u)) => Some(ComponentValue::Dimension(
|
||||
Dimension::UnknownDimension(UnknownDimension {
|
||||
span: u.span,
|
||||
value: u.value.clone(),
|
||||
unit: u.unit.clone(),
|
||||
}))
|
||||
}
|
||||
CalcValue::Percentage(p) => ComponentValue::Percentage(Percentage {
|
||||
}),
|
||||
)),
|
||||
CalcValue::Percentage(p) => Some(ComponentValue::Percentage(Percentage {
|
||||
span: p.span,
|
||||
value: p.value.clone(),
|
||||
}),
|
||||
CalcValue::Function(f) => ComponentValue::Function(Function {
|
||||
})),
|
||||
CalcValue::Function(f) => Some(ComponentValue::Function(Function {
|
||||
span: f.span,
|
||||
name: f.name.clone(),
|
||||
value: f.value.to_vec(),
|
||||
}),
|
||||
})),
|
||||
CalcValue::Constant(_) => {
|
||||
unreachable!("CalcValue::Constant cannot be transformed into a ComponentValue per spec")
|
||||
// https://www.w3.org/TR/css-values-4/#calc-constants
|
||||
// "These keywords are only usable within a calculation"
|
||||
// "If used outside of a calculation, they’re treated like any other keyword"
|
||||
None
|
||||
}
|
||||
CalcValue::Sum(_) => {
|
||||
unreachable!("CalcValue::Sum cannot be transformed into a ComponentValue")
|
||||
// Do nothing, we cannot transform a CalcSum into a ComponentValue
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -339,46 +339,30 @@ impl Compressor {
|
||||
ComponentValue::CalcSum(CalcSum {
|
||||
expressions: calc_sum_expressions,
|
||||
..
|
||||
}) if calc_sum_expressions.len() == 1 => {
|
||||
match &calc_sum_expressions[0] {
|
||||
}) if calc_sum_expressions.len() == 1 => match &calc_sum_expressions[0] {
|
||||
CalcProductOrOperator::Product(CalcProduct {
|
||||
expressions: calc_product_expressions,
|
||||
..
|
||||
}) if calc_product_expressions.len() == 1 => {
|
||||
match &calc_product_expressions[0] {
|
||||
CalcValueOrOperator::Value(CalcValue::Sum(_)) => {
|
||||
// Do nothing, we cannot transform a
|
||||
// CalcSum into a ComponentValue
|
||||
}
|
||||
CalcValueOrOperator::Value(CalcValue::Constant(_)) => {
|
||||
// https://www.w3.org/TR/css-values-4/#calc-constants
|
||||
// "These keywords are only usable
|
||||
// within a calculation"
|
||||
// "If used outside of a calculation,
|
||||
// they’re treated like any other
|
||||
// keyword"
|
||||
}
|
||||
CalcValueOrOperator::Value(calc_value) => {
|
||||
match transform_calc_value_into_component_value(calc_value)
|
||||
if let CalcValueOrOperator::Value(calc_value) =
|
||||
&calc_product_expressions[0]
|
||||
{
|
||||
ComponentValue::Function(function) => {
|
||||
match transform_calc_value_into_component_value(calc_value) {
|
||||
Some(ComponentValue::Function(function)) => {
|
||||
*n = MediaFeatureValue::Function(function);
|
||||
}
|
||||
ComponentValue::Dimension(dimension) => {
|
||||
Some(ComponentValue::Dimension(dimension)) => {
|
||||
*n = MediaFeatureValue::Dimension(dimension);
|
||||
}
|
||||
ComponentValue::Number(number) => {
|
||||
Some(ComponentValue::Number(number)) => {
|
||||
*n = MediaFeatureValue::Number(number);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
@container(inline-size>=0){h2{font-size:2cqw}}@container(inline-size>=0){h2{font-size:2cqh}}@container(inline-size>=0){h2{font-size:2cqi}}@container(inline-size>=0){h2{font-size:2cqb}}@container(inline-size>=0){h2{font-size:2cqmin}}@container(inline-size>=0){h2{font-size:2cqmax}}@container(inline-size>=200px){h2{font-size:2cqw}}@container(inline-size>=calc(200px)){h2{font-size:2cqw}}
|
||||
@container(inline-size>=0){h2{font-size:2cqw}}@container(inline-size>=0){h2{font-size:2cqh}}@container(inline-size>=0){h2{font-size:2cqi}}@container(inline-size>=0){h2{font-size:2cqb}}@container(inline-size>=0){h2{font-size:2cqmin}}@container(inline-size>=0){h2{font-size:2cqmax}}@container(inline-size>=200px){h2{font-size:2cqw}}@container(inline-size>=200px){h2{font-size:2cqw}}
|
||||
|
@ -1 +1 @@
|
||||
.class1{width:calc(var(--mouseX)*1px)}.class2{width:calc(10px - 100px*var(--mouseX))}.class3{width:calc(-90px - var(--mouseX))}.class4{width:calc(10px - 100px/var(--mouseX))}.class5{width:calc(-90px + var(--mouseX))}.class6{width:calc(var(--popupHeight)/2)}.class7{width:calc(var(--popupHeight)/2 + var(--popupWidth)/2)}.class8{--foo:calc(var(--bar) / 8)}.class9{transform:translatey(calc(-100% - var(--tooltip-calculated-offset)))}.class10{width:calc(var(--xxx,var(--yyy))/2)}.class11{width:var(--foo)}.class12{width:calc(var(--foo))}.class13{width:calc(var(--foo) + 10px)}.class14{width:calc(var(--foo) + var(--bar))}.class15{width:calc(calc(var(--foo) + var(--bar)) + var(--baz))}.class16{width:calc(var(--foo) + calc(var(--bar) + var(--baz)))}.class17{width:calc(calc(var(--foo) - var(--bar)) - var(--baz))}.class18{width:calc(var(--foo) - calc(var(--bar) - var(--baz)))}.class19{width:calc(calc(var(--foo) + var(--bar)) - var(--baz))}.class20{width:calc(var(--foo) + calc(var(--bar) - var(--baz)))}.class21{width:calc(var(--foo) - calc(var(--bar) + var(--baz)))}.class22{width:calc(calc(var(--foo) + var(--bar))*var(--baz))}.class23{width:calc(var(--foo)*calc(var(--bar) + var(--baz)))}.class24{width:calc(calc(var(--foo) + var(--bar))/var(--baz))}.class25{width:calc(var(--foo)/calc(var(--bar) + var(--baz)))}
|
||||
.class1{width:calc(var(--mouseX)*1px)}.class2{width:calc(10px - 100px*var(--mouseX))}.class3{width:calc(-90px - var(--mouseX))}.class4{width:calc(10px - 100px/var(--mouseX))}.class5{width:calc(-90px + var(--mouseX))}.class6{width:calc(var(--popupHeight)/2)}.class7{width:calc(var(--popupHeight)/2 + var(--popupWidth)/2)}.class8{--foo:calc(var(--bar) / 8)}.class9{transform:translatey(calc(-100% - var(--tooltip-calculated-offset)))}.class10{width:calc(var(--xxx,var(--yyy))/2)}.class11{width:var(--foo)}.class12{width:var(--foo)}.class13{width:calc(var(--foo) + 10px)}.class14{width:calc(var(--foo) + var(--bar))}.class15{width:calc(var(--foo) + var(--bar) + var(--baz))}.class16{width:calc(var(--foo) + var(--bar) + var(--baz))}.class17{width:calc(var(--foo) - var(--bar) - var(--baz))}.class18{width:calc(var(--foo) - var(--bar) + var(--baz))}.class19{width:calc(var(--foo) + var(--bar) - var(--baz))}.class20{width:calc(var(--foo) + var(--bar) - var(--baz))}.class21{width:calc(var(--foo) - var(--bar) - var(--baz))}.class22{width:calc(calc(var(--foo) + var(--bar))*var(--baz))}.class23{width:calc(var(--foo)*calc(var(--bar) + var(--baz)))}.class24{width:calc(calc(var(--foo) + var(--bar))/var(--baz))}.class25{width:calc(var(--foo)/calc(var(--bar) + var(--baz)))}
|
||||
|
@ -1 +1 @@
|
||||
.class1{width:calc(100vw/2 - 6px)}.class2{width:500px}.class3{width:calc(0 - 10px)}.class4{width:calc(0 - calc(1px + 1em))}.class5{width:calc(0 - (100vw - 10px)/2)}.class6{width:calc(10px - 100vw)}.class7{width:calc(0px - (100vw - 10px)*2)}.class8{width:calc(-10px - 100vw)}.class9{width:calc(0px - var(--foo,4px)/2)}
|
||||
.class1{width:calc(100vw/2 - 6px)}.class2{width:500px}.class3{width:calc(0 - 10px)}.class4{width:calc(0 - 1px - 1em)}.class5{width:calc(0 - (100vw - 10px)/2)}.class6{width:calc(10px - 100vw)}.class7{width:calc(0px - (100vw - 10px)*2)}.class8{width:calc(-10px - 100vw)}.class9{width:calc(0px - var(--foo,4px)/2)}
|
||||
|
@ -1 +1 @@
|
||||
@media(min-width:20px){.class1{color:red}}@media(min-width:calc(20px)){.class1{color:red}}@media(color:1){.class1{color:red}}@media(min-width:0){.class1{color:red}}@media(min-width:0){.class1{color:red}}
|
||||
@media(min-width:20px){.class1{color:red}}@media(min-width:20px){.class1{color:red}}@media(color:1){.class1{color:red}}@media(min-width:0){.class1{color:red}}@media(min-width:0){.class1{color:red}}
|
||||
|
@ -1 +1 @@
|
||||
.class1{width:calc(100% - calc(50% + 25px))}.class2{width:calc(1px + calc(2px/2))}.class3{width:calc((1em - calc(10px + 1em))/2)}.class4{width:calc(calc(2.25rem + 2px) - 2px)}.class5{width:calc(100vh - 5rem - calc(10rem + 100px))}.class6{width:calc(100% - calc(10px + 2vw))}.class7{width:calc(100% - calc(10px - 2vw))}.class8{width:calc(100px + calc(200px))}
|
||||
.class1{width:calc(50% - 25px)}.class2{width:calc(1px + 2px/2)}.class3{width:calc((0em - 10px)/2)}.class4{width:calc(2.25rem - 0px)}.class5{width:calc(100vh - 15rem - 100px)}.class6{width:calc(100% - 10px - 2vw)}.class7{width:calc(100% - 10px + 2vw)}.class8{width:300px}
|
||||
|
@ -1 +1 @@
|
||||
.class1{width:2px}.class2{width:2px;height:5px}.class3{width:1.5rem}.class4{width:2em}.class5{width:calc(2ex/2)}.class6{width:60px}.class7{width:calc(-0px + 100%)}.class8{width:calc(200px - 100%)}.class9{width:2px}.class10{width:2px}.class11{width:3rem}.class12{width:calc(100% + 1px)}.class13{width:calc(2rem - .14285em)}@supports(width:calc(100% - constant(safe-area-inset-left))){.class14{width:calc(100% - constant(safe-area-inset-left))}}.class15{width:calc(100% + 1163.5px - 75.37%)}.class16{width:calc(((100% + 123.5px)/.7537 - 100vw + 60px)/2 + 30px)}.class17{width:calc(75.37% - 763.5px)}.class18{width:calc(1163.5px - 10%)}.class19{width:calc((1em - calc(10px + 1em))/2)}.class20{width:200px}.class21{width:0}.class22{width:200px}.class23{width:calc(200px/1)}.class24{width:-200px}.class25{width:0}.class26{width:-200px}.class27{width:calc(200px/-1)}.class28{width:200px}.class29{width:200px}.class30{width:200px}.class31{width:22px}.class32{width:200px}.class33{width:22e9px}.class34{width:90px}.class35{width:100%}.class36{width:22px}.class37{width:calc(calc(200px))}
|
||||
.class1{width:2px}.class2{width:2px;height:5px}.class3{width:1.5rem}.class4{width:2em}.class5{width:calc(2ex/2)}.class6{width:60px}.class7{width:calc(-0px + 100%)}.class8{width:calc(200px - 100%)}.class9{width:2px}.class10{width:2px}.class11{width:3rem}.class12{width:calc(100% + 1px)}.class13{width:calc(2rem - .14285em)}@supports(width:calc(100% - constant(safe-area-inset-left))){.class14{width:calc(100% - constant(safe-area-inset-left))}}.class15{width:calc(100% + 1163.5px - 75.37%)}.class16{width:calc(((100% + 123.5px)/.7537 - 100vw + 60px)/2 + 30px)}.class17{width:calc(75.37% - 763.5px)}.class18{width:calc(1163.5px - 10%)}.class19{width:calc((0em - 10px)/2)}.class20{width:200px}.class21{width:0}.class22{width:200px}.class23{width:calc(200px/1)}.class24{width:-200px}.class25{width:0}.class26{width:-200px}.class27{width:calc(200px/-1)}.class28{width:200px}.class29{width:200px}.class30{width:200px}.class31{width:22px}.class32{width:200px}.class33{width:22e9px}.class34{width:90px}.class35{width:100%}.class36{width:22px}.class37{width:200px}
|
||||
|
@ -1 +1 @@
|
||||
@supports(width:calc(200px)){div{background:red}}@supports(width:calc(calc(200px))){div{background:red}}@supports(width:calc(0px)){div{background:red}}@supports(width:calc(0px)){div{background:red}}
|
||||
@supports(width:200px){div{background:red}}@supports(width:200px){div{background:red}}@supports(width:0){div{background:red}}@supports(width:0){div{background:red}}
|
||||
|
@ -1 +1 @@
|
||||
.class1{width:2px}.class2{width:2px}.class3{width:-webkit-calc(100% - -webkit-calc(50% + 25px))}.class4{width:-webkit-calc(1px + -webkit-calc(2px/2))}.class5{width:2px}.class6{width:2px}
|
||||
.class1{width:2px}.class2{width:2px}.class3{width:-webkit-calc(50% - 25px)}.class4{width:-webkit-calc(1px + 2px/2)}.class5{width:2px}.class6{width:2px}
|
||||
|
Loading…
Reference in New Issue
Block a user