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.
This commit is contained in:
Andreas Kling 2025-05-20 12:18:28 +02:00 committed by Andreas Kling
commit d7cd8f0fc7
Notes: github-actions[bot] 2025-05-20 11:29:37 +00:00
2 changed files with 39 additions and 34 deletions

View file

@ -1384,26 +1384,31 @@ NonnullRefPtr<CalculationNode const> SignCalculationNode::with_simplified_childr
}
// https://drafts.csswg.org/css-values-4/#funcdef-sign
Optional<CalculatedStyleValue::CalculationResult> SignCalculationNode::run_operation_if_possible(CalculationContext const& context, CalculationResolutionContext const& resolution_context) const
Optional<CalculatedStyleValue::CalculationResult> SignCalculationNode::run_operation_if_possible(CalculationContext const&, CalculationResolutionContext const&) const
{
// The sign(A) function contains one calculation A, and returns -1 if As numeric value is negative,
// +1 if As numeric value is positive, 0⁺ if As numeric value is 0⁺, and 0⁻ if As numeric value is 0⁻.
// The return type is a <number>, made consistent with the input calculations 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<NumericCalculationNode>(*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<double> const extractor { .d = child_value->value() };
FloatExtractor<double> 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