diff --git a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp index ced6911d3f1..87df71bc3b1 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp @@ -2362,6 +2362,55 @@ Optional RoundCalculationNode::run_oper auto a = maybe_a->value(); auto b = maybe_b->value(); + // https://drafts.csswg.org/css-values-4/#round-infinities + // In round(A, B), if B is 0, the result is NaN. If A and B are both infinite, the result is NaN. + if (b == 0 || (isinf(a) && isinf(b))) + return CalculatedStyleValue::CalculationResult { AK::NaN, consistent_type }; + + // If A is infinite but B is finite, the result is the same infinity. + if (isinf(a) && isfinite(b)) + return CalculatedStyleValue::CalculationResult { a, consistent_type }; + + // If A is finite but B is infinite, the result depends on the and the sign of A: + if (isfinite(a) && isinf(b)) { + FloatExtractor const extractor { .d = a }; + + switch (m_strategy) { + // nearest, to-zero: + case RoundingStrategy::Nearest: + case RoundingStrategy::ToZero: { + // If A is positive or 0⁺, return 0⁺. Otherwise, return 0⁻. + return CalculatedStyleValue::CalculationResult { !extractor.sign ? 0.0 : -0.0, consistent_type }; + } + // up: + case RoundingStrategy::Up: { + double result; + if (a > 0) { + // If A is positive(not zero), return +∞. + result = AK::Infinity; + } else { + // If A is 0⁺, return 0⁺. Otherwise, return 0⁻. + result = !extractor.sign ? 0.0 : -0.0; + } + + return CalculatedStyleValue::CalculationResult { result, consistent_type }; + } + // down: + case RoundingStrategy::Down: { + double result; + if (a < 0) { + // If A is negative (not zero), return −∞. + result = -AK::Infinity; + } else { + // If A is 0⁻, return 0⁻. Otherwise, return 0⁺. + result = extractor.sign ? -0.0 : 0.0; + } + + return CalculatedStyleValue::CalculationResult { result, consistent_type }; + } + } + } + // If A is exactly equal to an integer multiple of B, round() resolves to A exactly (preserving whether A is 0⁻ or // 0⁺, if relevant). if (fmod(a, b) == 0) diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/round-mod-rem-computed.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/round-mod-rem-computed.txt index e62e52e58f0..22714520331 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/round-mod-rem-computed.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/round-mod-rem-computed.txt @@ -2,8 +2,8 @@ Harness status: OK Found 229 tests -211 Pass -18 Fail +215 Pass +14 Fail Pass round(10,10) should be used-value-equivalent to 10 Pass mod(1,1) should be used-value-equivalent to 0 Pass rem(1,1) should be used-value-equivalent to 0 @@ -217,18 +217,18 @@ Pass round(to-zero, 0, -Infinity) should be used-value-equivalent to 0 Pass round(to-zero, 4, -Infinity) should be used-value-equivalent to 0 Pass round(to-zero, -0, -Infinity) should be used-value-equivalent to calc(-0) Pass round(to-zero, -4, -Infinity) should be used-value-equivalent to calc(-0) -Fail round(up, 1, Infinity) should be used-value-equivalent to calc(Infinity) +Pass round(up, 1, Infinity) should be used-value-equivalent to calc(Infinity) Pass round(up, 0, Infinity) should be used-value-equivalent to 0 Pass round(up, -1, Infinity) should be used-value-equivalent to calc(-0) -Fail round(up, 1, -Infinity) should be used-value-equivalent to calc(Infinity) +Pass round(up, 1, -Infinity) should be used-value-equivalent to calc(Infinity) Pass round(up, 0, -Infinity) should be used-value-equivalent to 0 Pass round(up, -1, -Infinity) should be used-value-equivalent to calc(-0) Pass round(down, 1, Infinity) should be used-value-equivalent to calc(-0) Pass round(down, 0, Infinity) should be used-value-equivalent to 0 -Fail round(down, -1, Infinity) should be used-value-equivalent to calc(-Infinity) +Pass round(down, -1, Infinity) should be used-value-equivalent to calc(-Infinity) Pass round(down, 1, -Infinity) should be used-value-equivalent to calc(-0) Pass round(down, 0, -Infinity) should be used-value-equivalent to 0 -Fail round(down, -1, -Infinity) should be used-value-equivalent to calc(-Infinity) +Pass round(down, -1, -Infinity) should be used-value-equivalent to calc(-Infinity) Pass mod(-0, Infinity) should be used-value-equivalent to calc(NaN) Pass mod(0, -Infinity) should be used-value-equivalent to calc(NaN) Pass mod(-4, Infinity) should be used-value-equivalent to calc(NaN) diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/signed-zero.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/signed-zero.txt index 8ea30e4d765..f4af39bad35 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/signed-zero.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/signed-zero.txt @@ -2,8 +2,8 @@ Harness status: OK Found 162 tests -154 Pass -8 Fail +156 Pass +6 Fail Pass sign(calc(-0)) should be used-value-equivalent to 0 Pass clamp(-1, 1 / sign(calc(-0)), 1) should be used-value-equivalent to -1 Pass sign(calc( 0)) should be used-value-equivalent to 0 @@ -79,7 +79,7 @@ Pass clamp(-1, 1 / sign(round(nearest, -0, infinity)), 1) should be used-value-e Pass sign(round(nearest, 0, infinity)) should be used-value-equivalent to 0 Pass clamp(-1, 1 / sign(round(nearest, 0, infinity)), 1) should be used-value-equivalent to 1 Pass sign(round(nearest, 1, infinity)) should be used-value-equivalent to 0 -Fail clamp(-1, 1 / sign(round(nearest, 1, infinity)), 1) should be used-value-equivalent to 1 +Pass clamp(-1, 1 / sign(round(nearest, 1, infinity)), 1) should be used-value-equivalent to 1 Pass sign(round(up, -1, infinity)) should be used-value-equivalent to 0 Pass clamp(-1, 1 / sign(round(up, -1, infinity)), 1) should be used-value-equivalent to -1 Pass sign(round(up, -0, infinity)) should be used-value-equivalent to 0 @@ -91,7 +91,7 @@ Pass clamp(-1, 1 / sign(round(down, -0, infinity)), 1) should be used-value-equi Pass sign(round(down, 0, infinity)) should be used-value-equivalent to 0 Pass clamp(-1, 1 / sign(round(down, 0, infinity)), 1) should be used-value-equivalent to 1 Pass sign(round(down, 1, infinity)) should be used-value-equivalent to 0 -Fail clamp(-1, 1 / sign(round(down, 1, infinity)), 1) should be used-value-equivalent to 1 +Pass clamp(-1, 1 / sign(round(down, 1, infinity)), 1) should be used-value-equivalent to 1 Pass sign(mod(-1, -1)) should be used-value-equivalent to 0 Fail clamp(-1, 1 / sign(mod(-1, -1)), 1) should be used-value-equivalent to -1 Pass sign(mod(-1, 1)) should be used-value-equivalent to 0