Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (291910 => 291911)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2022-03-26 01:38:42 UTC (rev 291910)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2022-03-26 01:45:25 UTC (rev 291911)
@@ -1,3 +1,15 @@
+2022-03-25 Nikolaos Mouchtaris <[email protected]>
+
+ Incorrect handling of NaN inside calc() for top-level calculation
+ https://bugs.webkit.org/show_bug.cgi?id=234176
+
+ Reviewed by Simon Fraser.
+
+ * web-platform-tests/css/css-values/calc-infinity-nan-computed-expected.txt: Added.
+ * web-platform-tests/css/css-values/calc-infinity-nan-computed.html: Added.
+ * web-platform-tests/css/css-values/round-function-expected.txt:
+ * web-platform-tests/css/css-values/round-function.html:
+
2022-03-25 Youenn Fablet <[email protected]>
Add support for focused and visible ServiceWorkerWindowClient states
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/calc-infinity-nan-computed-expected.txt (0 => 291911)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/calc-infinity-nan-computed-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/calc-infinity-nan-computed-expected.txt 2022-03-26 01:45:25 UTC (rev 291911)
@@ -0,0 +1,36 @@
+
+PASS Property width value 'calc(NaN * 1px)'
+PASS Property width value 'calc(infinity * 1px)'
+PASS Property width value 'calc(infinity * 1cm)'
+PASS Property width value 'calc(NaN * 1rem)'
+FAIL Property width value 'calc(infinity * 1px - infinity * 1%)' assert_greater_than_equal: calc(infinity * 1px - infinity * 1%) expected a number greater than or equal to 33554400 but got 0
+PASS Property width value 'calc(infinity * 1px + infinity * 1%)'
+PASS Property width value 'calc(min(NaN * 1px, infinity * 1px) + max(infinity * 1px, -infinity * 1px))'
+FAIL Property width value 'calc(infinity * 1px - max(infinity * 1%, 0%))' assert_greater_than_equal: calc(infinity * 1px - max(infinity * 1%, 0%)) expected a number greater than or equal to 33554400 but got 0
+PASS Property width value 'calc(max(infinity * 1px, 10px))'
+PASS Property margin-left value 'calc(-infinity * 1px)'
+PASS Property margin-left value 'calc(min(1px, -infinity * 1%))'
+PASS Property margin-left value 'calc(-infinity * 1%)'
+PASS Property margin-left value 'calc(max(10000px, 0px) + min(-infinity * 1px, infinity * 1px))'
+PASS Property margin-left value 'calc(-infinity * 1px - infinity * 1px)'
+PASS Property margin-left value 'calc(min(-infinity * 1px, 10px))'
+PASS Property animation-duration value 'calc(NaN * 1s)'
+PASS Property animation-duration value 'calc(infinity * 1s)'
+PASS Property animation-duration value 'calc(1 / 0 * 1s)'
+PASS Property animation-duration value 'calc(max(infinity * 1s, 10s)'
+PASS Property transition-delay value 'calc(-infinity* 1s)'
+PASS Property transition-delay value 'calc(max(10000s, 0s) + min(-infinity * 1s, infinity * 1s))'
+PASS Property transition-delay value 'calc(min(-infinity * 1s, 10s))'
+FAIL Property rotate(calc(infinity * 1deg)) value expected same with rotate(0deg) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+FAIL Property rotate(calc(-infinity * 1deg)) value expected same with rotate(0deg) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+FAIL Property rotate(calc(NaN * 1deg)) value expected same with rotate(0deg) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+FAIL Property rotate(calc(infinity * 1turn)) value expected same with rotate(0turn) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+FAIL Property rotate(calc(-infinity * 1turn)) value expected same with rotate(0turn) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+FAIL Property rotate(calc(NaN * 1turn)) value expected same with rotate(0turn) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+FAIL Property rotate(calc(infinity * 1rad)) value expected same with rotate(0rad) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+FAIL Property rotate(calc(-infinity * 1rad)) value expected same with rotate(0rad) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+FAIL Property rotate(calc(NaN * 1rad)) value expected same with rotate(0rad) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+FAIL Property rotate(calc(infinity * 1grad)) value expected same with rotate(0grad) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+FAIL Property rotate(calc(-infinity * 1grad)) value expected same with rotate(0grad) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+FAIL Property rotate(calc(NaN * 1grad)) value expected same with rotate(0grad) in +/-0.0001 assert_array_approx_equals: lengths differ, expected 6 got 16
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/calc-infinity-nan-computed.html (0 => 291911)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/calc-infinity-nan-computed.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/calc-infinity-nan-computed.html 2022-03-26 01:45:25 UTC (rev 291911)
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Infinity and NaN: calc() computed value.</title>
+<link rel="author" title="Seokho Song" href=""
+<link rel="help" href=""
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+<div id="target"></div>
+<script>
+const APPROX_INFINITY = 3.35544e+07;
+const APPROX_NEGATIVE_INFINITY = -APPROX_INFINITY;
+
+// For <length>
+test_computed_value_greater_or_lower_than("width", "calc(NaN * 1px)", APPROX_INFINITY);
+test_computed_value_greater_or_lower_than("width", "calc(infinity * 1px)", APPROX_INFINITY);
+test_computed_value_greater_or_lower_than("width", "calc(infinity * 1cm)", APPROX_INFINITY);
+test_computed_value_greater_or_lower_than("width", "calc(NaN * 1rem)", APPROX_INFINITY);
+
+test_computed_value_greater_or_lower_than("width", "calc(infinity * 1px - infinity * 1%)", APPROX_INFINITY);
+test_computed_value_greater_or_lower_than("width", "calc(infinity * 1px + infinity * 1%)", APPROX_INFINITY);
+test_computed_value_greater_or_lower_than("width", "calc(min(NaN * 1px, infinity * 1px) + max(infinity * 1px, -infinity * 1px))", APPROX_INFINITY);
+test_computed_value_greater_or_lower_than("width", "calc(infinity * 1px - max(infinity * 1%, 0%))", APPROX_INFINITY);
+
+test_computed_value_greater_or_lower_than("width", "calc(max(infinity * 1px, 10px))", APPROX_INFINITY);
+
+test_computed_value_greater_or_lower_than("margin-left", "calc(-infinity * 1px)", APPROX_NEGATIVE_INFINITY);
+test_computed_value_greater_or_lower_than("margin-left", "calc(min(1px, -infinity * 1%))", APPROX_NEGATIVE_INFINITY);
+
+test_computed_value_greater_or_lower_than("margin-left", "calc(-infinity * 1%)", APPROX_NEGATIVE_INFINITY);
+test_computed_value_greater_or_lower_than("margin-left", "calc(max(10000px, 0px) + min(-infinity * 1px, infinity * 1px))", APPROX_NEGATIVE_INFINITY);
+
+test_computed_value_greater_or_lower_than("margin-left", "calc(-infinity * 1px - infinity * 1px)", APPROX_NEGATIVE_INFINITY);
+test_computed_value_greater_or_lower_than("margin-left", "calc(min(-infinity * 1px, 10px))", APPROX_NEGATIVE_INFINITY);
+
+// For <time>
+test_computed_value_greater_or_lower_than("animation-duration", "calc(NaN * 1s)", APPROX_INFINITY);
+test_computed_value_greater_or_lower_than("animation-duration", "calc(infinity * 1s)", APPROX_INFINITY);
+test_computed_value_greater_or_lower_than("animation-duration", "calc(1 / 0 * 1s)", APPROX_INFINITY);
+test_computed_value_greater_or_lower_than("animation-duration", "calc(max(infinity * 1s, 10s)", APPROX_INFINITY);
+
+test_computed_value_greater_or_lower_than("transition-delay", "calc(-infinity* 1s)", APPROX_NEGATIVE_INFINITY);
+test_computed_value_greater_or_lower_than("transition-delay", "calc(max(10000s, 0s) + min(-infinity * 1s, infinity * 1s))", APPROX_NEGATIVE_INFINITY);
+test_computed_value_greater_or_lower_than("transition-delay", "calc(min(-infinity * 1s, 10s))", APPROX_NEGATIVE_INFINITY);
+
+// For <angle>
+compareValueCloseTo("transform", "rotate(calc(infinity * 1deg))", 0.0001, "rotate(0deg)" );
+compareValueCloseTo("transform", "rotate(calc(-infinity * 1deg))", 0.0001, "rotate(0deg)");
+compareValueCloseTo("transform", "rotate(calc(NaN * 1deg))", 0.0001, "rotate(0deg)");
+
+compareValueCloseTo("transform", "rotate(calc(infinity * 1turn))", 0.0001, "rotate(0turn)" );
+compareValueCloseTo("transform", "rotate(calc(-infinity * 1turn))", 0.0001, "rotate(0turn)");
+compareValueCloseTo("transform", "rotate(calc(NaN * 1turn))", 0.0001, "rotate(0turn)");
+
+compareValueCloseTo("transform", "rotate(calc(infinity * 1rad))", 0.0001, "rotate(0rad)" );
+compareValueCloseTo("transform", "rotate(calc(-infinity * 1rad))", 0.0001, "rotate(0rad)");
+compareValueCloseTo("transform", "rotate(calc(NaN * 1rad))", 0.0001, "rotate(0rad)");
+
+compareValueCloseTo("transform", "rotate(calc(infinity * 1grad))", 0.0001, "rotate(0grad)" );
+compareValueCloseTo("transform", "rotate(calc(-infinity * 1grad))", 0.0001, "rotate(0grad)");
+compareValueCloseTo("transform", "rotate(calc(NaN * 1grad))", 0.0001, "rotate(0grad)");
+
+</script>
+</body>
+</html>
\ No newline at end of file
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/round-function-expected.txt (291910 => 291911)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/round-function-expected.txt 2022-03-26 01:38:42 UTC (rev 291910)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/round-function-expected.txt 2022-03-26 01:45:25 UTC (rev 291911)
@@ -35,16 +35,11 @@
PASS round(13px, -10px) should be used-value-equivalent to 10px
PASS round(-13px, -10px) should be used-value-equivalent to -10px
PASS round(-18px, -10px) should be used-value-equivalent to -20px
-PASS round(5, 0) should be used-value-equivalent to calc(NaN)
-PASS calc(-1 * round(5, 0)) should be used-value-equivalent to calc(NaN)
-PASS round(infinity, infinity) should be used-value-equivalent to calc(NaN)
-PASS calc(-1 * round(infinity, infinity)) should be used-value-equivalent to calc(NaN)
-PASS round(infinity, -infinity) should be used-value-equivalent to calc(NaN)
-PASS calc(-1 * round(infinity, -infinity)) should be used-value-equivalent to calc(NaN)
-PASS round(-infinity, infinity) should be used-value-equivalent to calc(NaN)
-PASS calc(-1 * round(-infinity, infinity)) should be used-value-equivalent to calc(NaN)
-PASS round(-infinity, -infinity) should be used-value-equivalent to calc(NaN)
-PASS calc(-1 * round(-infinity, -infinity)) should be used-value-equivalent to calc(NaN)
+PASS round(5, 0) should be used-value-equivalent to calc(infinity)
+PASS round(infinity, infinity) should be used-value-equivalent to calc(infinity)
+PASS round(infinity, -infinity) should be used-value-equivalent to calc(infinity)
+PASS round(-infinity, infinity) should be used-value-equivalent to calc(infinity)
+PASS round(-infinity, -infinity) should be used-value-equivalent to calc(infinity)
PASS round(infinity, 5) should be used-value-equivalent to calc(infinity)
PASS round(infinity, -5) should be used-value-equivalent to calc(infinity)
PASS round(-infinity, 5) should be used-value-equivalent to calc(-infinity)
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/round-function.html (291910 => 291911)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/round-function.html 2022-03-26 01:38:42 UTC (rev 291910)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/round-function.html 2022-03-26 01:45:25 UTC (rev 291911)
@@ -61,12 +61,12 @@
// Extreme cases:
// 0 step is NaN
-test_nan("round(5, 0)");
+test_plus_infinity("round(5, 0)");
// both infinite is NaN
-test_nan("round(infinity, infinity)");
-test_nan("round(infinity, -infinity)");
-test_nan("round(-infinity, infinity)");
-test_nan("round(-infinity, -infinity)");
+test_plus_infinity("round(infinity, infinity)");
+test_plus_infinity("round(infinity, -infinity)");
+test_plus_infinity("round(-infinity, infinity)");
+test_plus_infinity("round(-infinity, -infinity)");
// infinite value with finite step is the same infinity
test_plus_infinity("round(infinity, 5)");
Modified: trunk/Source/WebCore/ChangeLog (291910 => 291911)
--- trunk/Source/WebCore/ChangeLog 2022-03-26 01:38:42 UTC (rev 291910)
+++ trunk/Source/WebCore/ChangeLog 2022-03-26 01:45:25 UTC (rev 291911)
@@ -1,3 +1,21 @@
+2022-03-25 Nikolaos Mouchtaris <[email protected]>
+
+ Incorrect handling of NaN inside calc() for top-level calculation
+ https://bugs.webkit.org/show_bug.cgi?id=234176
+
+ Reviewed by Simon Fraser.
+
+ Add function to convert any top level NaN values to infinity values as per the spec.
+ This only affects the computed value of the calc _expression_, not its serialization.
+
+ Test: imported/w3c/web-platform-tests/css/css-values/calc-infinity-nan-computed.html
+
+ * css/calc/CSSCalcOperationNode.cpp:
+ (WebCore::CSSCalcOperationNode::combineChildren):
+ (WebCore::convertToTopLevelValue):
+ (WebCore::CSSCalcOperationNode::evaluateOperator):
+ * css/calc/CSSCalcOperationNode.h:
+
2022-03-25 Chris Dumez <[email protected]>
Use StringView::split() instead of String::split() in more places
Modified: trunk/Source/WebCore/css/calc/CSSCalcOperationNode.cpp (291910 => 291911)
--- trunk/Source/WebCore/css/calc/CSSCalcOperationNode.cpp 2022-03-26 01:38:42 UTC (rev 291910)
+++ trunk/Source/WebCore/css/calc/CSSCalcOperationNode.cpp 2022-03-26 01:45:25 UTC (rev 291911)
@@ -623,7 +623,8 @@
{
if (isIdentity() || !m_children.size())
return;
-
+ m_isRoot = IsRoot::No;
+
if (m_children.size() < 2) {
if (m_children.size() == 1 && isTrigNode()) {
double resolvedValue = doubleValue(m_children[0]->primitiveType());
Modified: trunk/Source/WebCore/css/calc/CSSCalcOperationNode.h (291910 => 291911)
--- trunk/Source/WebCore/css/calc/CSSCalcOperationNode.h 2022-03-26 01:38:42 UTC (rev 291910)
+++ trunk/Source/WebCore/css/calc/CSSCalcOperationNode.h 2022-03-26 01:45:25 UTC (rev 291911)
@@ -33,6 +33,8 @@
class CSSCalcOperationNode final : public CSSCalcExpressionNode {
WTF_MAKE_FAST_ALLOCATED;
public:
+ enum class IsRoot : bool { No, Yes };
+
static RefPtr<CSSCalcOperationNode> create(CalcOperator, RefPtr<CSSCalcExpressionNode>&& leftSide, RefPtr<CSSCalcExpressionNode>&& rightSide);
static RefPtr<CSSCalcOperationNode> createSum(Vector<Ref<CSSCalcExpressionNode>>&& values);
static RefPtr<CSSCalcOperationNode> createProduct(Vector<Ref<CSSCalcExpressionNode>>&& values);
@@ -125,10 +127,18 @@
return &rightSide;
return nullptr;
}
-
+
+ static double convertToTopLevelValue(double value)
+ {
+ if (isnan(value))
+ value = std::numeric_limits<double>::infinity();
+ return value;
+ }
+
double evaluate(const Vector<double>& children) const
{
- return evaluateOperator(m_operator, children);
+ auto result = evaluateOperator(m_operator, children);
+ return m_isRoot == IsRoot::No ? result : convertToTopLevelValue(result);
}
static double evaluateOperator(CalcOperator, const Vector<double>&);
@@ -144,6 +154,7 @@
CalcOperator m_operator;
Vector<Ref<CSSCalcExpressionNode>> m_children;
bool m_allowsNegativePercentageReference = false;
+ IsRoot m_isRoot = IsRoot::Yes;
};
}