From d7cd8f0fc700d3c850c39043674371329f77042c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 20 May 2025 12:18:28 +0200 Subject: [PATCH] LibWeb: Make CSS sign(A) ignore A's unit and just look at the raw value This allows stuff like sign(1em) even when we don't have something to resolve the em unit against. +25 new WPT subtest passes. --- .../CSS/StyleValues/CalculatedStyleValue.cpp | 19 ++++--- .../css/css-values/signs-abs-computed.txt | 54 +++++++++---------- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp index 520ce650e47..a230bff43e2 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp @@ -1384,26 +1384,31 @@ NonnullRefPtr SignCalculationNode::with_simplified_childr } // https://drafts.csswg.org/css-values-4/#funcdef-sign -Optional SignCalculationNode::run_operation_if_possible(CalculationContext const& context, CalculationResolutionContext const& resolution_context) const +Optional SignCalculationNode::run_operation_if_possible(CalculationContext const&, CalculationResolutionContext const&) const { // The sign(A) function contains one calculation A, and returns -1 if A’s numeric value is negative, // +1 if A’s numeric value is positive, 0⁺ if A’s numeric value is 0⁺, and 0⁻ if A’s numeric value is 0⁻. // The return type is a , made consistent with the input calculation’s type. - auto child_value = try_get_value_with_canonical_unit(m_value, context, resolution_context); - if (!child_value.has_value()) + + if (m_value->type() != CalculationNode::Type::Numeric) return {}; + auto const& numeric_child = as(*m_value); + double raw_value = numeric_child.value().visit( + [](Number const& number) { return number.value(); }, + [](Percentage const& percentage) { return percentage.as_fraction(); }, + [](auto const& dimension) { return dimension.raw_value(); }); double sign = 0; - if (child_value->value() < 0) { + if (raw_value < 0) { sign = -1; - } else if (child_value->value() > 0) { + } else if (raw_value > 0) { sign = 1; } else { - FloatExtractor const extractor { .d = child_value->value() }; + FloatExtractor const extractor { .d = raw_value }; sign = extractor.sign ? -0.0 : 0.0; } - return CalculatedStyleValue::CalculationResult { sign, CSSNumericType {}.made_consistent_with(child_value->type().value()) }; + return CalculatedStyleValue::CalculationResult { sign, CSSNumericType {}.made_consistent_with(numeric_child.numeric_type().value_or({})) }; } void SignCalculationNode::dump(StringBuilder& builder, int indent) const diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/signs-abs-computed.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/signs-abs-computed.txt index 6327d242d9b..e80b2a31de4 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/signs-abs-computed.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/signs-abs-computed.txt @@ -2,8 +2,8 @@ Harness status: OK Found 233 tests -181 Pass -52 Fail +206 Pass +27 Fail Pass abs(1) should be used-value-equivalent to 1 Pass sign(1) should be used-value-equivalent to 1 Pass abs(-1) should be used-value-equivalent to 1 @@ -46,14 +46,14 @@ Pass sign(1Q) should be used-value-equivalent to 1 Pass sign(1in) should be used-value-equivalent to 1 Pass sign(1pc) should be used-value-equivalent to 1 Pass sign(1pt) should be used-value-equivalent to 1 -Fail sign(1em) should be used-value-equivalent to 1 -Fail sign(1ex) should be used-value-equivalent to 1 -Fail sign(1ch) should be used-value-equivalent to 1 -Fail sign(1rem) should be used-value-equivalent to 1 -Fail sign(1vh) should be used-value-equivalent to 1 -Fail sign(1vw) should be used-value-equivalent to 1 -Fail sign(1vmin) should be used-value-equivalent to 1 -Fail sign(1vmax) should be used-value-equivalent to 1 +Pass sign(1em) should be used-value-equivalent to 1 +Pass sign(1ex) should be used-value-equivalent to 1 +Pass sign(1ch) should be used-value-equivalent to 1 +Pass sign(1rem) should be used-value-equivalent to 1 +Pass sign(1vh) should be used-value-equivalent to 1 +Pass sign(1vw) should be used-value-equivalent to 1 +Pass sign(1vmin) should be used-value-equivalent to 1 +Pass sign(1vmax) should be used-value-equivalent to 1 Pass sign(-1px) should be used-value-equivalent to -1 Pass sign(-1cm) should be used-value-equivalent to -1 Pass sign(-1mm) should be used-value-equivalent to -1 @@ -61,14 +61,14 @@ Pass sign(-1Q) should be used-value-equivalent to -1 Pass sign(-1in) should be used-value-equivalent to -1 Pass sign(-1pc) should be used-value-equivalent to -1 Pass sign(-1pt) should be used-value-equivalent to -1 -Fail sign(-1em) should be used-value-equivalent to -1 -Fail sign(-1ex) should be used-value-equivalent to -1 -Fail sign(-1ch) should be used-value-equivalent to -1 -Fail sign(-1rem) should be used-value-equivalent to -1 -Fail sign(-1vh) should be used-value-equivalent to -1 -Fail sign(-1vw) should be used-value-equivalent to -1 -Fail sign(-1vmin) should be used-value-equivalent to -1 -Fail sign(-1vmax) should be used-value-equivalent to -1 +Pass sign(-1em) should be used-value-equivalent to -1 +Pass sign(-1ex) should be used-value-equivalent to -1 +Pass sign(-1ch) should be used-value-equivalent to -1 +Pass sign(-1rem) should be used-value-equivalent to -1 +Pass sign(-1vh) should be used-value-equivalent to -1 +Pass sign(-1vw) should be used-value-equivalent to -1 +Pass sign(-1vmin) should be used-value-equivalent to -1 +Pass sign(-1vmax) should be used-value-equivalent to -1 Pass sign(1s) should be used-value-equivalent to 1 Pass sign(1ms) should be used-value-equivalent to 1 Pass sign(-1s) should be used-value-equivalent to -1 @@ -112,7 +112,7 @@ Pass clamp(-1, calc( 1 / sign(sign(0vmin))), 1) should be used-value-equivalent Pass calc(sign(0vmax)) should be used-value-equivalent to 0 Pass clamp(-1, calc( 1 / sign(sign(0vmax))), 1) should be used-value-equivalent to 1 Pass calc(sign(-0px)) should be used-value-equivalent to 0 -Fail clamp(-1, calc( 1 / sign(sign(-0px))), 1) should be used-value-equivalent to -1 +Pass clamp(-1, calc( 1 / sign(sign(-0px))), 1) should be used-value-equivalent to -1 Pass calc(sign(-0cm)) should be used-value-equivalent to 0 Fail clamp(-1, calc( 1 / sign(sign(-0cm))), 1) should be used-value-equivalent to -1 Pass calc(sign(-0mm)) should be used-value-equivalent to 0 @@ -126,21 +126,21 @@ Fail clamp(-1, calc( 1 / sign(sign(-0pc))), 1) should be used-value-equivalent t Pass calc(sign(-0pt)) should be used-value-equivalent to 0 Fail clamp(-1, calc( 1 / sign(sign(-0pt))), 1) should be used-value-equivalent to -1 Pass calc(sign(-0em)) should be used-value-equivalent to 0 -Fail clamp(-1, calc( 1 / sign(sign(-0em))), 1) should be used-value-equivalent to -1 +Pass clamp(-1, calc( 1 / sign(sign(-0em))), 1) should be used-value-equivalent to -1 Pass calc(sign(-0ex)) should be used-value-equivalent to 0 -Fail clamp(-1, calc( 1 / sign(sign(-0ex))), 1) should be used-value-equivalent to -1 +Pass clamp(-1, calc( 1 / sign(sign(-0ex))), 1) should be used-value-equivalent to -1 Pass calc(sign(-0ch)) should be used-value-equivalent to 0 -Fail clamp(-1, calc( 1 / sign(sign(-0ch))), 1) should be used-value-equivalent to -1 +Pass clamp(-1, calc( 1 / sign(sign(-0ch))), 1) should be used-value-equivalent to -1 Pass calc(sign(-0rem)) should be used-value-equivalent to 0 -Fail clamp(-1, calc( 1 / sign(sign(-0rem))), 1) should be used-value-equivalent to -1 +Pass clamp(-1, calc( 1 / sign(sign(-0rem))), 1) should be used-value-equivalent to -1 Pass calc(sign(-0vh)) should be used-value-equivalent to 0 -Fail clamp(-1, calc( 1 / sign(sign(-0vh))), 1) should be used-value-equivalent to -1 +Pass clamp(-1, calc( 1 / sign(sign(-0vh))), 1) should be used-value-equivalent to -1 Pass calc(sign(-0vw)) should be used-value-equivalent to 0 -Fail clamp(-1, calc( 1 / sign(sign(-0vw))), 1) should be used-value-equivalent to -1 +Pass clamp(-1, calc( 1 / sign(sign(-0vw))), 1) should be used-value-equivalent to -1 Pass calc(sign(-0vmin)) should be used-value-equivalent to 0 -Fail clamp(-1, calc( 1 / sign(sign(-0vmin))), 1) should be used-value-equivalent to -1 +Pass clamp(-1, calc( 1 / sign(sign(-0vmin))), 1) should be used-value-equivalent to -1 Pass calc(sign(-0vmax)) should be used-value-equivalent to 0 -Fail clamp(-1, calc( 1 / sign(sign(-0vmax))), 1) should be used-value-equivalent to -1 +Pass clamp(-1, calc( 1 / sign(sign(-0vmax))), 1) should be used-value-equivalent to -1 Pass calc(sign(0s)) should be used-value-equivalent to 0 Pass clamp(-1, calc( 1 / sign(sign(0s))), 1) should be used-value-equivalent to 1 Pass calc(sign(0ms)) should be used-value-equivalent to 0