From c3b101301877fd95072b61a2fe11d9e6ef5f86dd Mon Sep 17 00:00:00 2001 From: Callum Law Date: Thu, 31 Jul 2025 00:14:04 +1200 Subject: [PATCH] LibWeb: Skip inverted non-canonical values when simplifying product node This matches the logic with the non-inverted children. Gains us 2 WPT tests. --- .../CSS/StyleValues/CalculatedStyleValue.cpp | 76 ++++++--------- ...calc-in-media-queries-with-mixed-units.txt | 18 ++++ .../getComputedStyle-calc-mixed-units-003.txt | 13 +++ ...alc-in-media-queries-with-mixed-units.html | 35 +++++++ ...getComputedStyle-calc-mixed-units-003.html | 97 +++++++++++++++++++ .../css-values/support/mixed-units-01.html | 16 +++ .../css-values/support/mixed-units-02.html | 16 +++ .../css-values/support/mixed-units-03.html | 16 +++ .../css-values/support/mixed-units-04.html | 16 +++ .../css-values/support/mixed-units-05.html | 16 +++ .../css-values/support/mixed-units-06.html | 16 +++ .../css-values/support/mixed-units-07.html | 16 +++ .../css-values/support/mixed-units-08.html | 16 +++ .../css-values/support/mixed-units-09.html | 16 +++ .../css-values/support/mixed-units-10.html | 16 +++ .../css-values/support/mixed-units-11.html | 16 +++ .../css-values/support/mixed-units-12.html | 16 +++ 17 files changed, 387 insertions(+), 44 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/css/css-values/calc-in-media-queries-with-mixed-units.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/css/css-values/getComputedStyle-calc-mixed-units-003.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/calc-in-media-queries-with-mixed-units.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/getComputedStyle-calc-mixed-units-003.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-01.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-02.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-03.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-04.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-05.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-06.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-07.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-08.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-09.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-10.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-11.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-12.html diff --git a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp index 758cd2c9b8c..cd8b834e02e 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp @@ -3304,32 +3304,39 @@ NonnullRefPtr simplify_a_calculation_tree(CalculationNode // its child’s value), expressed in the result’s canonical unit. Optional accumulated_result; bool is_valid = true; + + auto accumulate = [&accumulated_result, &resolution_context, &context](NumericCalculationNode const& numeric_child, bool invert) { + auto child_type = numeric_child.numeric_type(); + + if (!child_type.has_value()) + return false; + + // FIXME: The spec doesn't handle unresolved percentages here, but if we don't exit when we see one, + // we'll get a wrongly-typed value after multiplying the types. + // Same goes for other numerics with non-canonical units. + // Spec bug: https://github.com/w3c/csswg-drafts/issues/11588 + if ((numeric_child.value().has() && context.percentages_resolve_as.has_value()) || !numeric_child.is_in_canonical_unit()) + return false; + + auto child_value = CalculatedStyleValue::CalculationResult::from_value(numeric_child.value(), resolution_context, child_type); + + if (invert) + child_value.invert(); + + if (accumulated_result.has_value()) + accumulated_result->multiply_by(child_value); + else + accumulated_result = child_value; + + if (!accumulated_result->type().has_value()) + return false; + + return true; + }; + for (auto const& child : children) { if (child->type() == CalculationNode::Type::Numeric) { - auto const& numeric_child = as(*child); - auto child_type = numeric_child.numeric_type(); - if (!child_type.has_value()) { - is_valid = false; - break; - } - - // FIXME: The spec doesn't handle unresolved percentages here, but if we don't exit when we see one, - // we'll get a wrongly-typed value after multiplying the types. - // Same goes for other numerics with non-canonical units. - // Spec bug: https://github.com/w3c/csswg-drafts/issues/11588 - if ((numeric_child.value().has() && context.percentages_resolve_as.has_value()) - || !numeric_child.is_in_canonical_unit()) { - is_valid = false; - break; - } - - auto child_value = CalculatedStyleValue::CalculationResult::from_value(numeric_child.value(), resolution_context, child_type); - if (accumulated_result.has_value()) { - accumulated_result->multiply_by(child_value); - } else { - accumulated_result = move(child_value); - } - if (!accumulated_result->type().has_value()) { + if (!accumulate(as(*child), false)) { is_valid = false; break; } @@ -3337,26 +3344,7 @@ NonnullRefPtr simplify_a_calculation_tree(CalculationNode } if (child->type() == CalculationNode::Type::Invert) { auto const& invert_child = as(*child); - if (invert_child.child().type() != CalculationNode::Type::Numeric) { - is_valid = false; - break; - } - auto const& grandchild = as(invert_child.child()); - - auto child_type = child->numeric_type(); - if (!child_type.has_value()) { - is_valid = false; - break; - } - - auto child_value = CalculatedStyleValue::CalculationResult::from_value(grandchild.value(), resolution_context, grandchild.numeric_type()); - child_value.invert(); - if (accumulated_result.has_value()) { - accumulated_result->multiply_by(child_value); - } else { - accumulated_result = move(child_value); - } - if (!accumulated_result->type().has_value()) { + if (invert_child.child().type() != CalculationNode::Type::Numeric || !accumulate(as(invert_child.child()), true)) { is_valid = false; break; } diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/calc-in-media-queries-with-mixed-units.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/calc-in-media-queries-with-mixed-units.txt new file mode 100644 index 00000000000..c269714dd6f --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/calc-in-media-queries-with-mixed-units.txt @@ -0,0 +1,18 @@ +Harness status: OK + +Found 12 tests + +2 Pass +10 Fail +Pass box should be orange if the calc between px-em in @media was correct +Fail box should be orange if the calc between vh+em in @media was correct +Fail box should be orange if the calc between vw-em in @media was correct +Fail box should be orange if the calc between vw+vh in @media was correct +Fail box should be orange if the calc between vh+px in @media was correct +Fail box should be orange if the calc between vw+px in @media was correct +Pass box should be orange if the calc between px/em*em in @media was correct +Fail box should be orange if the calc between vh*em in @media was correct +Fail box should be orange if the calc between vh*vw/em*px/vh in @media was correct +Fail box should be orange if the calc between vw/px*vh in @media was correct +Fail box should be orange if the calc between vh*vw/em*px in @media was correct +Fail box should be orange if the calc between vw*vh*px*em/px/px/px in @media was correct \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/getComputedStyle-calc-mixed-units-003.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/getComputedStyle-calc-mixed-units-003.txt new file mode 100644 index 00000000000..ceb155c433b --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/getComputedStyle-calc-mixed-units-003.txt @@ -0,0 +1,13 @@ +Harness status: OK + +Found 7 tests + +5 Pass +2 Fail +Fail testing width: calc(5px * 10lh / 1px) +Pass testing width: calc(20% * 0.5em / 1px) +Pass testing width: calc(4px * 4em / 1px) +Fail testing width: calc(400px / 4lh * 1px) +Pass testing width: calc(20% / 0.5em * 1px) +Pass testing width: calc(52px * 1px / 10%) +Pass testing width: calc(100px * 1px / 1px / 1) \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/calc-in-media-queries-with-mixed-units.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/calc-in-media-queries-with-mixed-units.html new file mode 100644 index 00000000000..9e09cf30a65 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/calc-in-media-queries-with-mixed-units.html @@ -0,0 +1,35 @@ + + + + test calc with mixed units in media queries + + + + + + + + + + + + + + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/getComputedStyle-calc-mixed-units-003.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/getComputedStyle-calc-mixed-units-003.html new file mode 100644 index 00000000000..a44fca7380a --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/getComputedStyle-calc-mixed-units-003.html @@ -0,0 +1,97 @@ + + + + + CSS Values Test: computed value of calc() values using multiplication/division with mixed units + + + + + + + + + + + +
+ + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-01.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-01.html new file mode 100644 index 00000000000..1969d10b46c --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-01.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-02.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-02.html new file mode 100644 index 00000000000..cbef4633981 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-02.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-03.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-03.html new file mode 100644 index 00000000000..0a22fcb5e71 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-03.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-04.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-04.html new file mode 100644 index 00000000000..5c3560aaf94 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-04.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-05.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-05.html new file mode 100644 index 00000000000..d1a71b73e4e --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-05.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-06.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-06.html new file mode 100644 index 00000000000..787de9746b9 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-06.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-07.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-07.html new file mode 100644 index 00000000000..bd4bd4aecf4 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-07.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-08.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-08.html new file mode 100644 index 00000000000..1ae1d0c30c6 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-08.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-09.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-09.html new file mode 100644 index 00000000000..ee078c95dfe --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-09.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-10.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-10.html new file mode 100644 index 00000000000..43a4fd02f4b --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-10.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-11.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-11.html new file mode 100644 index 00000000000..1d63c899d84 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-11.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-12.html b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-12.html new file mode 100644 index 00000000000..bb623ff3ec5 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/css-values/support/mixed-units-12.html @@ -0,0 +1,16 @@ + + + + + + +