From c2ca7124062411ee71e073f6297e84dc0a5a57c7 Mon Sep 17 00:00:00 2001 From: Callum Law Date: Tue, 28 Oct 2025 20:50:20 +1300 Subject: [PATCH] LibWeb: Properly simplify sum nodes containing negated sum nodes This is ad-hoc, see https://github.com/w3c/csswg-drafts/issues/13020 Gains us 5 WPT tests --- .../CSS/StyleValues/CalculatedStyleValue.cpp | 16 ++++ .../css/css-values/calc-nesting-002.txt | 16 ++++ .../css/css-values/calc-nesting-002.html | 88 +++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/css/css-values/calc-nesting-002.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/calc-nesting-002.html diff --git a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp index 9de0fede3f1..279ebb399c5 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp @@ -3070,6 +3070,22 @@ NonnullRefPtr simplify_a_calculation_tree(CalculationNode if (child.type() == CalculationNode::Type::Negate) return as(child).child(); + // AD-HOC: Convert negated sums into sums of negated nodes - see https://github.com/w3c/csswg-drafts/issues/13020 + if (child.type() == CalculationNode::Type::Sum) { + Vector> negated_sum_components; + + for (auto const& sum_child : child.children()) { + if (sum_child->type() == CalculationNode::Type::Numeric) + negated_sum_components.append(as(*sum_child).negated(context)); + else if (sum_child->type() == CalculationNode::Type::Negate) + negated_sum_components.append(as(*sum_child).child()); + else + negated_sum_components.append(NegateCalculationNode::create(sum_child)); + } + + return SumCalculationNode::create(negated_sum_components); + } + // 3. Return root. // NOTE: Because our root is immutable, we have to return a new node if the child was modified. if (&child == &root_negate.child()) diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/calc-nesting-002.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/calc-nesting-002.txt new file mode 100644 index 00000000000..1ce320f338c --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/calc-nesting-002.txt @@ -0,0 +1,16 @@ +Harness status: OK + +Found 11 tests + +11 Pass +Pass testing calc(20px + calc(80px)) +Pass testing calc(calc(100px)) +Pass testing calc(calc(2) * calc(50px) +Pass testing calc(calc(150px*2/3) +Pass testing calc(calc(2 * calc(calc(3)) + 4) * 10px) +Pass testing calc(50px + calc(40%)) +Pass testing calc(calc(300px - 1 * (0% + 100px))) +Pass testing calc(calc(300px - (0% + 100px) * 1)) +Pass testing calc(calc(300px - (0% + 100px) * -1)) +Pass testing calc(calc(300px - -1 * (0% + 100px))) +Pass testing calc(calc(300px - 1 * (0% - 100px))) \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/calc-nesting-002.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/calc-nesting-002.html new file mode 100644 index 00000000000..2cca72231d5 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/calc-nesting-002.html @@ -0,0 +1,88 @@ + + + + + CSS Values and Units Test: serialization of summation involving nested calc() + + + + + + + + + + + + +
+ +