Skip to content

Commit c2ca712

Browse files
Calme1709AtkinsSJ
authored andcommitted
LibWeb: Properly simplify sum nodes containing negated sum nodes
This is ad-hoc, see w3c/csswg-drafts#13020 Gains us 5 WPT tests
1 parent 9c06d58 commit c2ca712

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3070,6 +3070,22 @@ NonnullRefPtr<CalculationNode const> simplify_a_calculation_tree(CalculationNode
30703070
if (child.type() == CalculationNode::Type::Negate)
30713071
return as<NegateCalculationNode>(child).child();
30723072

3073+
// AD-HOC: Convert negated sums into sums of negated nodes - see https://github.com/w3c/csswg-drafts/issues/13020
3074+
if (child.type() == CalculationNode::Type::Sum) {
3075+
Vector<NonnullRefPtr<CalculationNode const>> negated_sum_components;
3076+
3077+
for (auto const& sum_child : child.children()) {
3078+
if (sum_child->type() == CalculationNode::Type::Numeric)
3079+
negated_sum_components.append(as<NumericCalculationNode>(*sum_child).negated(context));
3080+
else if (sum_child->type() == CalculationNode::Type::Negate)
3081+
negated_sum_components.append(as<NegateCalculationNode>(*sum_child).child());
3082+
else
3083+
negated_sum_components.append(NegateCalculationNode::create(sum_child));
3084+
}
3085+
3086+
return SumCalculationNode::create(negated_sum_components);
3087+
}
3088+
30733089
// 3. Return root.
30743090
// NOTE: Because our root is immutable, we have to return a new node if the child was modified.
30753091
if (&child == &root_negate.child())
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Harness status: OK
2+
3+
Found 11 tests
4+
5+
11 Pass
6+
Pass testing calc(20px + calc(80px))
7+
Pass testing calc(calc(100px))
8+
Pass testing calc(calc(2) * calc(50px)
9+
Pass testing calc(calc(150px*2/3)
10+
Pass testing calc(calc(2 * calc(calc(3)) + 4) * 10px)
11+
Pass testing calc(50px + calc(40%))
12+
Pass testing calc(calc(300px - 1 * (0% + 100px)))
13+
Pass testing calc(calc(300px - (0% + 100px) * 1))
14+
Pass testing calc(calc(300px - (0% + 100px) * -1))
15+
Pass testing calc(calc(300px - -1 * (0% + 100px)))
16+
Pass testing calc(calc(300px - 1 * (0% - 100px)))
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<!DOCTYPE html>
2+
3+
<meta charset="UTF-8">
4+
5+
<title>CSS Values and Units Test: serialization of summation involving nested calc()</title>
6+
7+
<!--
8+
9+
This test is an adapted version of the portion of the original test
10+
11+
https://chromium.googlesource.com/chromium/src/+/c825d655f6aaf73484f9d56e9012793f5b9668cc/third_party/WebKit/LayoutTests/css3/calc/calc-nesting.html
12+
13+
which required using property-parsing-test.js
14+
15+
-->
16+
17+
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
18+
<link rel="help" href="https://www.w3.org/TR/css-values-4/#math-function-simplify-an-expression">
19+
20+
<meta content="This test checks that how a summation involving one or more nested calc() is performed and serialized." name="assert">
21+
22+
<script src="../../resources/testharness.js"></script>
23+
24+
<script src="../../resources/testharnessreport.js"></script>
25+
26+
<div id="target"></div>
27+
28+
<script>
29+
function startTesting()
30+
{
31+
32+
var targetElement = document.getElementById("target");
33+
34+
function verifySerialization(specified_value, serialization_expected, description)
35+
{
36+
37+
test(function()
38+
{
39+
40+
targetElement.style.left = specified_value;
41+
42+
assert_equals(targetElement.style.left, serialization_expected);
43+
44+
}, description);
45+
}
46+
47+
verifySerialization("calc(20px + calc(80px))", "calc(100px)", "testing calc(20px + calc(80px))");
48+
49+
verifySerialization("calc(calc(100px))", "calc(100px)", "testing calc(calc(100px))");
50+
51+
verifySerialization("calc(calc(2) * calc(50px)", "calc(100px)", "testing calc(calc(2) * calc(50px)");
52+
53+
verifySerialization("calc(calc(150px*2/3)", "calc(100px)", "testing calc(calc(150px*2/3)");
54+
55+
verifySerialization("calc(calc(2 * calc(calc(3)) + 4) * 10px)", "calc(100px)", "testing calc(calc(2 * calc(calc(3)) + 4) * 10px)");
56+
57+
verifySerialization("calc(50px + calc(40%))", "calc(40% + 50px)", "testing calc(50px + calc(40%))");
58+
59+
verifySerialization("calc(calc(300px - 1 * (0% + 100px)))", "calc(0% + 200px)", "testing calc(calc(300px - 1 * (0% + 100px)))");
60+
61+
verifySerialization("calc(calc(300px - (0% + 100px) * 1))", "calc(0% + 200px)", "testing calc(calc(300px - (0% + 100px) * 1))");
62+
63+
verifySerialization("calc(calc(300px - (0% + 100px) * -1))", "calc(0% + 400px)", "testing calc(calc(300px - (0% + 100px) * -1))");
64+
65+
verifySerialization("calc(calc(300px - -1 * (0% + 100px)))", "calc(0% + 400px)", "testing calc(calc(300px - -1 * (0% + 100px)))");
66+
67+
verifySerialization("calc(calc(300px - 1 * (0% - 100px)))", "calc(0% + 400px)", "testing calc(calc(300px - 1 * (0% - 100px)))");
68+
69+
/*
70+
71+
"
72+
Sort the terms in the following order:
73+
74+
The number, if present
75+
76+
The percentage, if present
77+
78+
The dimensions, ordered by their units ASCII case-insensitive alphabetically
79+
"
80+
https://www.w3.org/TR/css-values-4/#math-function-serialize-a-summation
81+
82+
*/
83+
84+
}
85+
86+
startTesting();
87+
88+
</script>

0 commit comments

Comments
 (0)