Title: [283439] trunk
Revision
283439
Author
[email protected]
Date
2021-10-02 05:38:36 -0700 (Sat, 02 Oct 2021)

Log Message

[css-grid] Accommodate spanning items crossing flexible tracks
https://bugs.webkit.org/show_bug.cgi?id=230252

Reviewed by Sergio Villar Senin.

LayoutTests/imported/w3c:

Three tests are passing and the test expectation files are updated.

* web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt:
* web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt:
* web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-003-expected.txt:

Source/WebCore:

CSS spec has added one more step at https://drafts.csswg.org/css-grid/#algo-spanning-flex-items
for resolving intrinsic track sizes. Basically, increasing sizes to accommodate spanning items
crossing flexible tracks instead of ignoring their contents completely.

This patch is an import of obrufau's work in chromium. Initial CL is at
https://chromium-review.googlesource.com/c/chromium/src/+/1492337/16..20.
The performance issue caused by the patch were fixed at https://bugs.webkit.org/show_bug.cgi?id=207852
for webkit and https://bugs.chromium.org/p/chromium/issues/detail?id=1021929 for chromium.
This change also addresses web compat issue raised at https://github.com/w3c/csswg-drafts/issues/4783.

* rendering/GridTrackSizingAlgorithm.cpp:
(WebCore::GridTrackSizingAlgorithm::initialGrowthLimit const):
(WebCore::GridTrackSizingAlgorithm::spanningItemCrossesFlexibleSizedTracks const):
(WebCore::GridTrackSizingAlgorithm::increaseSizesToAccommodateSpanningItems):
(WebCore::getSizeDistributionWeight):
(WebCore::distributeItemIncurredIncreaseToTrack):
(WebCore::distributeItemIncurredIncreases):
(WebCore::GridTrackSizingAlgorithm::distributeSpaceToTracks const):
(WebCore::GridTrackSizingAlgorithmStrategy::minSizeForChild const):
(WebCore::GridTrackSizingAlgorithm::resolveIntrinsicTrackSizes):
* rendering/GridTrackSizingAlgorithm.h:
(WebCore::GridTrackSizingAlgorithmStrategy::distributeSpaceToTracks const):

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (283438 => 283439)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-10-02 11:57:48 UTC (rev 283438)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-10-02 12:38:36 UTC (rev 283439)
@@ -1,3 +1,16 @@
+2021-10-02  Ziran Sun  <[email protected]>
+
+        [css-grid] Accommodate spanning items crossing flexible tracks
+        https://bugs.webkit.org/show_bug.cgi?id=230252
+
+        Reviewed by Sergio Villar Senin.
+
+        Three tests are passing and the test expectation files are updated.
+
+        * web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt:
+        * web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt:
+        * web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-003-expected.txt:
+
 2021-10-02  Youenn Fablet  <[email protected]>
 
         Add support for ServiceWorkerGlobalScope push event handler

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt (283438 => 283439)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt	2021-10-02 11:57:48 UTC (rev 283438)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-001-expected.txt	2021-10-02 12:38:36 UTC (rev 283439)
@@ -7,24 +7,24 @@
 PASS 'grid' with: grid-template-columns: minmax(0, 1fr); and grid-template-rows: minmax(0, 1fr);
 PASS 'grid' with: grid-template-columns: minmax(0, 2fr); and grid-template-rows: minmax(0, 2fr);
 PASS 'grid' with: grid-template-columns: minmax(75px, 1fr); and grid-template-rows: minmax(75px, 1fr);
-FAIL 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["50px 50px"]
-FAIL 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["0px 100px"]
-FAIL 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
-FAIL 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr; assert_in_array: gridTemplateColumns value "25px 25px" not in array ["50px 50px"]
-FAIL 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr; assert_in_array: gridTemplateColumns value "12.5px 37.5px" not in array ["25px 75px"]
-FAIL 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 0px 50px" not in array ["50px 50px 0px"]
+PASS 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr;
+PASS 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr;
+PASS 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr;
+PASS 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr;
+PASS 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr;
+PASS 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr;
 PASS 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 0fr);
 PASS 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 1fr);
 PASS 'grid' with: grid-template-columns: minmax(15px, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(15px, 0fr) minmax(0, 1fr);
 PASS 'grid' with: grid-template-columns: minmax(20px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(20px, 1fr) minmax(0, 1fr);
 PASS 'grid' with: grid-template-columns: minmax(30px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(30px, 1fr) minmax(0, 1fr);
-FAIL 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr); assert_in_array: gridTemplateColumns value "0px 0px" not in array ["100px 0px"]
-FAIL 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "0px 50px" not in array ["100px 0px"]
-FAIL 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "25px 25px" not in array ["100px 0px"]
-FAIL 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr); assert_in_array: gridTemplateColumns value "25px 25px" not in array ["75px 25px"]
-FAIL 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto; assert_in_array: gridTemplateColumns value "0px 50px" not in array ["100px 0px"]
-FAIL 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
-FAIL 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content; assert_in_array: gridTemplateColumns value "50px 0px" not in array ["100px 0px"]
+PASS 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr);
+PASS 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr);
+PASS 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr);
+PASS 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr);
+PASS 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto;
+PASS 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto;
+PASS 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content;
 PASS 'grid' with: grid-template-columns: minmax(0, 0fr) auto; and grid-template-rows: minmax(0, 0fr) auto;
 PASS 'grid' with: grid-template-columns: minmax(0, 1fr) auto; and grid-template-rows: minmax(0, 1fr) auto;
 PASS 'grid' with: grid-template-columns: minmax(25px, 0fr) auto; and grid-template-rows: minmax(25px, 0fr) auto;

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt (283438 => 283439)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt	2021-10-02 11:57:48 UTC (rev 283438)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-002-expected.txt	2021-10-02 12:38:36 UTC (rev 283439)
@@ -1,7 +1,7 @@
 
-FAIL 'grid' with: grid-template-columns: 1fr auto auto auto; and grid-template-rows: 1fr auto auto auto; assert_in_array: gridTemplateColumns value "0px 50px 50px 50px" not in array ["10px 50px 50px 50px"]
+PASS 'grid' with: grid-template-columns: 1fr auto auto auto; and grid-template-rows: 1fr auto auto auto;
 PASS 'grid' with: grid-template-columns: minmax(0, 1fr) auto auto auto; and grid-template-rows: minmax(0, 1fr) auto auto auto;
-FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr 1fr; assert_in_array: gridTemplateColumns value "12.5px 12.5px 12.5px 12.5px" not in array ["30px 50px 50px 50px"]
-FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr 4fr; and grid-template-rows: 1fr 1fr 1fr 4fr; assert_in_array: gridTemplateColumns value "7.140625px 7.140625px 7.140625px 28.5625px" not in array ["30px 30px 25px 100px"]
-FAIL 'grid' with: grid-template-columns: 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr; assert_in_array: gridTemplateColumns value "60px 0px 0px" not in array ["60px 50px 50px"]
+PASS 'grid' with: grid-template-columns: 1fr 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr 1fr;
+PASS 'grid' with: grid-template-columns: 1fr 1fr 1fr 4fr; and grid-template-rows: 1fr 1fr 1fr 4fr;
+PASS 'grid' with: grid-template-columns: 1fr 1fr 1fr; and grid-template-rows: 1fr 1fr 1fr;
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-003-expected.txt (283438 => 283439)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-003-expected.txt	2021-10-02 11:57:48 UTC (rev 283438)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/layout-algorithm/grid-flex-track-intrinsic-sizes-003-expected.txt	2021-10-02 12:38:36 UTC (rev 283439)
@@ -41,27 +41,27 @@
 PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 1fr); and grid-template-rows: minmax(0, 1fr);
 PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 2fr); and grid-template-rows: minmax(0, 2fr);
 PASS min-content min item 'grid' with: grid-template-columns: minmax(75px, 1fr); and grid-template-rows: minmax(75px, 1fr);
-FAIL min-content min item 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["50px 50px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 60px" not in array ["0px 100px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr; assert_in_array: gridTemplateColumns value "60px 0px" not in array ["100px 0px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr; assert_in_array: gridTemplateColumns value "30px 30px" not in array ["50px 50px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr; assert_in_array: gridTemplateColumns value "15px 45px" not in array ["25px 75px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 0px 60px" not in array ["50px 50px 0px"]
+PASS min-content min item 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr;
+PASS min-content min item 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr;
+PASS min-content min item 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr;
+PASS min-content min item 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr;
+PASS min-content min item 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr;
+PASS min-content min item 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr;
 PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 0fr);
 PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 1fr);
 PASS min-content min item 'grid' with: grid-template-columns: minmax(15px, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(15px, 0fr) minmax(0, 1fr);
 PASS min-content min item 'grid' with: grid-template-columns: minmax(20px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(20px, 1fr) minmax(0, 1fr);
 PASS min-content min item 'grid' with: grid-template-columns: minmax(40px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(40px, 1fr) minmax(0, 1fr);
-FAIL min-content min item 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr); assert_in_array: gridTemplateColumns value "0px 0px" not in array ["100px 0px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "0px 60px" not in array ["100px 0px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "30px 30px" not in array ["100px 0px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr); assert_in_array: gridTemplateColumns value "30px 30px" not in array ["75px 25px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 0fr min-content; and grid-template-rows: 0fr min-content; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["100px 0px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto; assert_in_array: gridTemplateColumns value "0px 60px" not in array ["100px 0px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 0.5fr auto; and grid-template-rows: 0.5fr auto; assert_in_array: gridTemplateColumns value "30px 30px" not in array ["100px 0px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto; assert_in_array: gridTemplateColumns value "60px 0px" not in array ["100px 0px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content; assert_in_array: gridTemplateColumns value "60px 0px" not in array ["100px 0px"]
-FAIL min-content min item 'grid' with: grid-template-columns: 1fr min-content; and grid-template-rows: 1fr min-content; assert_in_array: gridTemplateColumns value "60px 0px" not in array ["100px 0px"]
+PASS min-content min item 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr);
+PASS min-content min item 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr);
+PASS min-content min item 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr);
+PASS min-content min item 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr);
+PASS min-content min item 'grid' with: grid-template-columns: 0fr min-content; and grid-template-rows: 0fr min-content;
+PASS min-content min item 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto;
+PASS min-content min item 'grid' with: grid-template-columns: 0.5fr auto; and grid-template-rows: 0.5fr auto;
+PASS min-content min item 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto;
+PASS min-content min item 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content;
+PASS min-content min item 'grid' with: grid-template-columns: 1fr min-content; and grid-template-rows: 1fr min-content;
 PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 0fr) min-content; and grid-template-rows: minmax(0, 0fr) min-content;
 PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 0fr) auto; and grid-template-rows: minmax(0, 0fr) auto;
 PASS min-content min item 'grid' with: grid-template-columns: minmax(0, 1fr) auto; and grid-template-rows: minmax(0, 1fr) auto;
@@ -75,24 +75,24 @@
 PASS 50px min item 'grid' with: grid-template-columns: minmax(0, 1fr); and grid-template-rows: minmax(0, 1fr);
 PASS 50px min item 'grid' with: grid-template-columns: minmax(0, 2fr); and grid-template-rows: minmax(0, 2fr);
 PASS 50px min item 'grid' with: grid-template-columns: minmax(75px, 1fr); and grid-template-rows: minmax(75px, 1fr);
-FAIL 50px min item 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["25px 25px"]
+PASS 50px min item 'grid' with: grid-template-columns: 0fr 0fr; and grid-template-rows: 0fr 0fr;
 PASS 50px min item 'grid' with: grid-template-columns: 0fr 1fr; and grid-template-rows: 0fr 1fr;
 PASS 50px min item 'grid' with: grid-template-columns: 1fr 0fr; and grid-template-rows: 1fr 0fr;
 PASS 50px min item 'grid' with: grid-template-columns: 1fr 1fr; and grid-template-rows: 1fr 1fr;
 PASS 50px min item 'grid' with: grid-template-columns: 1fr 3fr; and grid-template-rows: 1fr 3fr;
-FAIL 50px min item 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr; assert_in_array: gridTemplateColumns value "0px 0px 60px" not in array ["25px 25px 10px"]
+PASS 50px min item 'grid' with: grid-template-columns: 0fr 0fr 1fr; and grid-template-rows: 0fr 0fr 1fr;
 PASS 50px min item 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 0fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 0fr);
 PASS 50px min item 'grid' with: grid-template-columns: minmax(0, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(0, 0fr) minmax(0, 1fr);
 PASS 50px min item 'grid' with: grid-template-columns: minmax(15px, 0fr) minmax(0, 1fr); and grid-template-rows: minmax(15px, 0fr) minmax(0, 1fr);
 PASS 50px min item 'grid' with: grid-template-columns: minmax(20px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(20px, 1fr) minmax(0, 1fr);
 PASS 50px min item 'grid' with: grid-template-columns: minmax(40px, 1fr) minmax(0, 1fr); and grid-template-rows: minmax(40px, 1fr) minmax(0, 1fr);
-FAIL 50px min item 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr); assert_in_array: gridTemplateColumns value "0px 0px" not in array ["50px 0px"]
-FAIL 50px min item 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "0px 60px" not in array ["50px 10px"]
-FAIL 50px min item 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr); assert_in_array: gridTemplateColumns value "30px 30px" not in array ["50px 10px"]
+PASS 50px min item 'grid' with: grid-template-columns: 0fr minmax(0, 0fr); and grid-template-rows: 0fr minmax(0, 0fr);
+PASS 50px min item 'grid' with: grid-template-columns: 0fr minmax(0, 1fr); and grid-template-rows: 0fr minmax(0, 1fr);
+PASS 50px min item 'grid' with: grid-template-columns: 1fr minmax(0, 1fr); and grid-template-rows: 1fr minmax(0, 1fr);
 PASS 50px min item 'grid' with: grid-template-columns: 1fr minmax(25px, 1fr); and grid-template-rows: 1fr minmax(25px, 1fr);
-FAIL 50px min item 'grid' with: grid-template-columns: 0fr min-content; and grid-template-rows: 0fr min-content; assert_in_array: gridTemplateColumns value "0px 0px" not in array ["50px 0px"]
-FAIL 50px min item 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto; assert_in_array: gridTemplateColumns value "0px 60px" not in array ["50px 10px"]
-FAIL 50px min item 'grid' with: grid-template-columns: 0.5fr auto; and grid-template-rows: 0.5fr auto; assert_in_array: gridTemplateColumns value "30px 30px" not in array ["50px 10px"]
+PASS 50px min item 'grid' with: grid-template-columns: 0fr min-content; and grid-template-rows: 0fr min-content;
+PASS 50px min item 'grid' with: grid-template-columns: 0fr auto; and grid-template-rows: 0fr auto;
+PASS 50px min item 'grid' with: grid-template-columns: 0.5fr auto; and grid-template-rows: 0.5fr auto;
 PASS 50px min item 'grid' with: grid-template-columns: 1fr auto; and grid-template-rows: 1fr auto;
 PASS 50px min item 'grid' with: grid-template-columns: 1fr max-content; and grid-template-rows: 1fr max-content;
 PASS 50px min item 'grid' with: grid-template-columns: 1fr min-content; and grid-template-rows: 1fr min-content;

Modified: trunk/Source/WebCore/ChangeLog (283438 => 283439)


--- trunk/Source/WebCore/ChangeLog	2021-10-02 11:57:48 UTC (rev 283438)
+++ trunk/Source/WebCore/ChangeLog	2021-10-02 12:38:36 UTC (rev 283439)
@@ -1,3 +1,33 @@
+2021-10-02  Ziran Sun  <[email protected]>
+
+        [css-grid] Accommodate spanning items crossing flexible tracks
+        https://bugs.webkit.org/show_bug.cgi?id=230252
+
+        Reviewed by Sergio Villar Senin.
+
+        CSS spec has added one more step at https://drafts.csswg.org/css-grid/#algo-spanning-flex-items
+        for resolving intrinsic track sizes. Basically, increasing sizes to accommodate spanning items
+        crossing flexible tracks instead of ignoring their contents completely.
+
+        This patch is an import of obrufau's work in chromium. Initial CL is at
+        https://chromium-review.googlesource.com/c/chromium/src/+/1492337/16..20.
+        The performance issue caused by the patch were fixed at https://bugs.webkit.org/show_bug.cgi?id=207852
+        for webkit and https://bugs.chromium.org/p/chromium/issues/detail?id=1021929 for chromium.
+        This change also addresses web compat issue raised at https://github.com/w3c/csswg-drafts/issues/4783.       
+
+        * rendering/GridTrackSizingAlgorithm.cpp:
+        (WebCore::GridTrackSizingAlgorithm::initialGrowthLimit const):
+        (WebCore::GridTrackSizingAlgorithm::spanningItemCrossesFlexibleSizedTracks const):
+        (WebCore::GridTrackSizingAlgorithm::increaseSizesToAccommodateSpanningItems):
+        (WebCore::getSizeDistributionWeight):
+        (WebCore::distributeItemIncurredIncreaseToTrack):
+        (WebCore::distributeItemIncurredIncreases):
+        (WebCore::GridTrackSizingAlgorithm::distributeSpaceToTracks const):
+        (WebCore::GridTrackSizingAlgorithmStrategy::minSizeForChild const):
+        (WebCore::GridTrackSizingAlgorithm::resolveIntrinsicTrackSizes):
+        * rendering/GridTrackSizingAlgorithm.h:
+        (WebCore::GridTrackSizingAlgorithmStrategy::distributeSpaceToTracks const):
+
 2021-10-02  Youenn Fablet  <[email protected]>
 
         Add support for ServiceWorkerGlobalScope push event handler

Modified: trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp (283438 => 283439)


--- trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp	2021-10-02 11:57:48 UTC (rev 283438)
+++ trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp	2021-10-02 12:38:36 UTC (rev 283439)
@@ -227,7 +227,7 @@
 {
     const GridLength& gridLength = trackSize.maxTrackBreadth();
     if (gridLength.isFlex())
-        return baseSize;
+        return trackSize.minTrackBreadth().isContentSized() ? LayoutUnit(infinity) : baseSize;
 
     const Length& trackLength = gridLength.length();
     if (trackLength.isSpecified())
@@ -265,7 +265,7 @@
     const Vector<GridTrack>& trackList = tracks(m_direction);
     for (auto trackPosition : itemSpan) {
         const auto& trackSize = trackList[trackPosition].cachedTrackSize();
-        if (trackSize.maxTrackBreadth().isFlex())
+        if (trackSize.minTrackBreadth().isFlex() || trackSize.maxTrackBreadth().isFlex())
             return true;
     }
 
@@ -422,7 +422,7 @@
     ASSERT_NOT_REACHED();
 }
 
-template <TrackSizeComputationPhase phase>
+template <TrackSizeComputationVariant variant, TrackSizeComputationPhase phase>
 void GridTrackSizingAlgorithm::increaseSizesToAccommodateSpanningItems(const GridItemsSpanGroupRange& gridItemsWithSpan)
 {
     Vector<GridTrack>& allTracks = tracks(m_direction);
@@ -435,8 +435,8 @@
     Vector<GridTrack*> filteredTracks;
     for (auto it = gridItemsWithSpan.rangeStart; it != gridItemsWithSpan.rangeEnd; ++it) {
         GridItemWithSpan& gridItemWithSpan = *it;
-        ASSERT(gridItemWithSpan.span().integerSpan() > 1);
         const GridSpan& itemSpan = gridItemWithSpan.span();
+        ASSERT(variant == TrackSizeComputationVariant::CrossingFlexibleTracks || itemSpan.integerSpan() > 1u);
 
         filteredTracks.shrink(0);
         growBeyondGrowthLimitsTracks.shrink(0);
@@ -445,6 +445,8 @@
             GridTrack& track = allTracks[trackPosition];
             const auto& trackSize = track.cachedTrackSize();
             spanningTracksSize += trackSizeForTrackSizeComputationPhase(phase, track, ForbidInfinity);
+            if (variant == TrackSizeComputationVariant::CrossingFlexibleTracks && !trackSize.maxTrackBreadth().isFlex())
+                continue;
             if (!shouldProcessTrackForTrackSizeComputationPhase(phase, trackSize))
                 continue;
 
@@ -462,7 +464,7 @@
         LayoutUnit extraSpace = itemSizeForTrackSizeComputationPhase(phase, gridItemWithSpan.gridItem()) - spanningTracksSize;
         extraSpace = std::max<LayoutUnit>(extraSpace, 0);
         auto& tracksToGrowBeyondGrowthLimits = growBeyondGrowthLimitsTracks.isEmpty() ? filteredTracks : growBeyondGrowthLimitsTracks;
-        distributeSpaceToTracks<phase>(filteredTracks, &tracksToGrowBeyondGrowthLimits, extraSpace);
+        distributeSpaceToTracks<variant, phase>(filteredTracks, &tracksToGrowBeyondGrowthLimits, extraSpace);
     }
 
     for (const auto& trackIndex : m_contentSizedTracksIndex) {
@@ -472,6 +474,25 @@
     }
 }
 
+template <TrackSizeComputationVariant variant>
+void GridTrackSizingAlgorithm::increaseSizesToAccommodateSpanningItems(const GridItemsSpanGroupRange& gridItemsWithSpan)
+{
+    increaseSizesToAccommodateSpanningItems<variant, ResolveIntrinsicMinimums>(gridItemsWithSpan);
+    increaseSizesToAccommodateSpanningItems<variant, ResolveContentBasedMinimums>(gridItemsWithSpan);
+    increaseSizesToAccommodateSpanningItems<variant, ResolveMaxContentMinimums>(gridItemsWithSpan);
+    increaseSizesToAccommodateSpanningItems<variant, ResolveIntrinsicMaximums>(gridItemsWithSpan);
+    increaseSizesToAccommodateSpanningItems<variant, ResolveMaxContentMaximums>(gridItemsWithSpan);
+}
+
+template <TrackSizeComputationVariant variant>
+static double getSizeDistributionWeight(const GridTrack& track)
+{
+    if (variant != TrackSizeComputationVariant::CrossingFlexibleTracks)
+        return 0;
+    ASSERT(track.cachedTrackSize().maxTrackBreadth().isFlex());
+    return track.cachedTrackSize().maxTrackBreadth().flex();
+}
+
 static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTrack* track2)
 {
     // This check ensures that we respect the irreflexivity property of the strict weak ordering required by std::sort
@@ -502,7 +523,51 @@
     growthShare = std::min(growthShare, distanceToCap);
 }
 
-template <TrackSizeComputationPhase phase>
+template <TrackSizeComputationPhase phase, SpaceDistributionLimit limit>
+static void distributeItemIncurredIncreaseToTrack(GridTrack& track, LayoutUnit& freeSpace, double shareFraction)
+{
+    LayoutUnit freeSpaceShare(freeSpace / shareFraction);
+    LayoutUnit growthShare = limit == SpaceDistributionLimit::BeyondGrowthLimit || track.infiniteGrowthPotential() ? freeSpaceShare : std::min(freeSpaceShare, track.growthLimit() - trackSizeForTrackSizeComputationPhase(phase, track, ForbidInfinity));
+    clampGrowthShareIfNeeded(phase, track, growthShare);
+    ASSERT_WITH_MESSAGE(growthShare >= 0, "We must never shrink any grid track or else we can't guarantee we abide by our min-sizing function.");
+    track.growTempSize(growthShare);
+    freeSpace -= growthShare;
+}
+
+template <TrackSizeComputationVariant variant, TrackSizeComputationPhase phase, SpaceDistributionLimit limit>
+static void distributeItemIncurredIncreases(Vector<GridTrack*>& tracks, LayoutUnit& freeSpace)
+{
+    uint32_t tracksSize = tracks.size();
+    if (!tracksSize)
+        return;
+    if (variant == TrackSizeComputationVariant::NotCrossingFlexibleTracks) {
+        // We have to sort tracks according to their growth potential. This is necessary even when distributing beyond growth limits,
+        // because there might be tracks with growth limit caps (like the ones with fit-content()) which cannot indefinitely grow over the limits.
+        std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential);
+        for (uint32_t i = 0; i < tracksSize; ++i) {
+            ASSERT(!getSizeDistributionWeight<variant>(*tracks[i]));
+            distributeItemIncurredIncreaseToTrack<phase, limit>(*tracks[i], freeSpace, tracksSize - i);
+        }
+        return;
+    }
+    // We never grow flex tracks beyond growth limits, since they are infinite.
+    ASSERT(limit != SpaceDistributionLimit::BeyondGrowthLimit);
+    // For TrackSizeComputationVariant::CrossingFlexibleTracks we don't distribute equally, we need to take the weights into account.
+    Vector<double> fractionsOfRemainingSpace(tracksSize);
+    double weightSum = 0;
+    for (int32_t i = tracksSize - 1; i >= 0; --i) {
+        double weight = getSizeDistributionWeight<variant>(*tracks[i]);
+        weightSum += weight;
+        fractionsOfRemainingSpace[i] = weightSum > 0 ? weightSum / weight : tracksSize - i;
+    }
+    for (uint32_t i = 0; i < tracksSize; ++i) {
+        // Sorting is not needed for TrackSizeComputationVariant::CrossingFlexibleTracks, since all tracks have an infinite growth potential.
+        ASSERT(tracks[i]->growthLimitIsInfinite());  
+        distributeItemIncurredIncreaseToTrack<phase, limit>(*tracks[i], freeSpace, fractionsOfRemainingSpace[i]);
+    }
+}
+
+template <TrackSizeComputationVariant variant, TrackSizeComputationPhase phase>
 void GridTrackSizingAlgorithm::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<GridTrack*>* growBeyondGrowthLimitsTracks, LayoutUnit& freeSpace) const
 {
     ASSERT(freeSpace >= 0);
@@ -510,43 +575,12 @@
     for (auto* track : tracks)
         track->setTempSize(trackSizeForTrackSizeComputationPhase(phase, *track, ForbidInfinity));
 
-    if (freeSpace > 0) {
-        std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential);
+    if (freeSpace > 0)
+        distributeItemIncurredIncreases<variant, phase, SpaceDistributionLimit::UpToGrowthLimit>(tracks, freeSpace);
 
-        unsigned tracksSize = tracks.size();
-        for (unsigned i = 0; i < tracksSize; ++i) {
-            GridTrack& track = *tracks[i];
-            const LayoutUnit& trackBreadth = trackSizeForTrackSizeComputationPhase(phase, track, ForbidInfinity);
-            bool infiniteGrowthPotential = track.infiniteGrowthPotential();
-            LayoutUnit trackGrowthPotential = infiniteGrowthPotential ? track.growthLimit() : track.growthLimit() - trackBreadth;
-            // Let's avoid computing availableLogicalSpaceShare as much as possible as it's a hot spot in performance tests.
-            if (trackGrowthPotential > 0 || infiniteGrowthPotential) {
-                LayoutUnit availableLogicalSpaceShare = freeSpace / (tracksSize - i);
-                LayoutUnit growthShare = infiniteGrowthPotential ? availableLogicalSpaceShare : std::min(availableLogicalSpaceShare, trackGrowthPotential);
-                clampGrowthShareIfNeeded(phase, track, growthShare);
-                ASSERT_WITH_MESSAGE(growthShare >= 0, "We should never shrink any grid track or else we can't guarantee we abide by our min-sizing function. We can still have 0 as growthShare if the amount of tracks greatly exceeds the freeSpace.");
-                track.growTempSize(growthShare);
-                freeSpace -= growthShare;
-            }
-        }
-    }
-
-    if (freeSpace > 0 && growBeyondGrowthLimitsTracks) {
-        // We need to sort them because there might be tracks with growth limit caps (like the ones
-        // with fit-content()) which cannot indefinitely grow over the limits.
-        if (phase == ResolveMaxContentMaximums)
-            std::sort(growBeyondGrowthLimitsTracks->begin(), growBeyondGrowthLimitsTracks->end(), sortByGridTrackGrowthPotential);
-
-        unsigned tracksGrowingBeyondGrowthLimitsSize = growBeyondGrowthLimitsTracks->size();
-        for (unsigned i = 0; i < tracksGrowingBeyondGrowthLimitsSize; ++i) {
-            GridTrack* track = growBeyondGrowthLimitsTracks->at(i);
-            LayoutUnit growthShare = freeSpace / (tracksGrowingBeyondGrowthLimitsSize - i);
-            clampGrowthShareIfNeeded(phase, *track, growthShare);
-            track->growTempSize(growthShare);
-            freeSpace -= growthShare;
-        }
-    }
-
+    if (freeSpace > 0 && growBeyondGrowthLimitsTracks)
+        distributeItemIncurredIncreases<variant, phase, SpaceDistributionLimit::BeyondGrowthLimit>(*growBeyondGrowthLimitsTracks, freeSpace);
+    
     for (auto* track : tracks)
         track->setPlannedSize(track->plannedSize() == infinity ? track->tempSize() : std::max(track->plannedSize(), track->tempSize()));
 }
@@ -810,14 +844,22 @@
 
     if (childMinSize.isAuto() && overflowIsVisible) {
         auto minSize = minContentForChild(child);
+        const GridSpan& span = m_algorithm.grid().gridItemSpan(child, direction());
+
         LayoutUnit maxBreadth;
         auto allTracks = m_algorithm.tracks(direction());
-        for (auto trackPosition : m_algorithm.grid().gridItemSpan(child, direction())) {
+        bool allFixed = true;
+        for (auto trackPosition : span) {
             const auto& trackSize = allTracks[trackPosition].cachedTrackSize();
+            if (trackSize.maxTrackBreadth().isFlex() && span.integerSpan() > 1)
+                return { };
             if (!trackSize.hasFixedMaxTrackBreadth())
-                return minSize;
-            maxBreadth += valueForLength(trackSize.maxTrackBreadth().length(), availableSpace().value_or(0_lu));
+                allFixed = false;
+            else if (allFixed)
+                maxBreadth += valueForLength(trackSize.maxTrackBreadth().length(), availableSpace().value_or(0_lu));
         }
+        if (!allFixed)
+            return minSize;
         if (minSize > maxBreadth) {
             auto marginAndBorderAndPadding = GridLayoutFunctions::marginLogicalSizeForChild(*renderGrid(), direction(), child);
             marginAndBorderAndPadding += isRowAxis ? child.borderAndPaddingLogicalWidth() : child.borderAndPaddingLogicalHeight();
@@ -1163,6 +1205,7 @@
     }
 
     Vector<GridItemWithSpan> itemsSortedByIncreasingSpan;
+    Vector<GridItemWithSpan> itemsCrossingFlexibleTracks;
     HashSet<RenderBox*> itemsSet;
     if (m_grid.hasGridItems()) {
         for (auto trackIndex : m_contentSizedTracksIndex) {
@@ -1172,9 +1215,11 @@
             while (auto* gridItem = iterator.nextGridItem()) {
                 if (itemsSet.add(gridItem).isNewEntry) {
                     const GridSpan& span = m_grid.gridItemSpan(*gridItem, m_direction);
-                    if (span.integerSpan() == 1)
+                    if (spanningItemCrossesFlexibleSizedTracks(span))
+                        itemsCrossingFlexibleTracks.append(GridItemWithSpan(*gridItem, span));
+                    else if (span.integerSpan() == 1)
                         sizeTrackToFitNonSpanningItem(span, *gridItem, track);
-                    else if (!spanningItemCrossesFlexibleSizedTracks(span))
+                    else
                         itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, span));
                 }
             }
@@ -1186,13 +1231,11 @@
     auto end = itemsSortedByIncreasingSpan.end();
     while (it != end) {
         GridItemsSpanGroupRange spanGroupRange = { it, std::upper_bound(it, end, *it) };
-        increaseSizesToAccommodateSpanningItems<ResolveIntrinsicMinimums>(spanGroupRange);
-        increaseSizesToAccommodateSpanningItems<ResolveContentBasedMinimums>(spanGroupRange);
-        increaseSizesToAccommodateSpanningItems<ResolveMaxContentMinimums>(spanGroupRange);
-        increaseSizesToAccommodateSpanningItems<ResolveIntrinsicMaximums>(spanGroupRange);
-        increaseSizesToAccommodateSpanningItems<ResolveMaxContentMaximums>(spanGroupRange);
+        increaseSizesToAccommodateSpanningItems<TrackSizeComputationVariant::NotCrossingFlexibleTracks>(spanGroupRange);
         it = spanGroupRange.rangeEnd;
     }
+    GridItemsSpanGroupRange tracksGroupRange = { itemsCrossingFlexibleTracks.begin(), itemsCrossingFlexibleTracks.end() };
+    increaseSizesToAccommodateSpanningItems<TrackSizeComputationVariant::CrossingFlexibleTracks>(tracksGroupRange);
     handleInfinityGrowthLimit();
 }
 

Modified: trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h (283438 => 283439)


--- trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h	2021-10-02 11:57:48 UTC (rev 283438)
+++ trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h	2021-10-02 12:38:36 UTC (rev 283439)
@@ -35,6 +35,11 @@
 
 enum SizingOperation { TrackSizing, IntrinsicSizeComputation };
 
+enum class TrackSizeComputationVariant : uint8_t {
+    NotCrossingFlexibleTracks,
+    CrossingFlexibleTracks,
+};
+
 enum TrackSizeComputationPhase {
     ResolveIntrinsicMinimums,
     ResolveContentBasedMinimums,
@@ -44,6 +49,11 @@
     MaximizeTracks,
 };
 
+enum class SpaceDistributionLimit : uint8_t  {
+    UpToGrowthLimit,
+    BeyondGrowthLimit,
+};
+
 class GridTrackSizingAlgorithmStrategy;
 
 class GridTrack {
@@ -152,9 +162,11 @@
     void sizeTrackToFitNonSpanningItem(const GridSpan&, RenderBox& gridItem, GridTrack&);
     bool spanningItemCrossesFlexibleSizedTracks(const GridSpan&) const;
     typedef struct GridItemsSpanGroupRange GridItemsSpanGroupRange;
-    template <TrackSizeComputationPhase phase> void increaseSizesToAccommodateSpanningItems(const GridItemsSpanGroupRange& gridItemsWithSpan);
+    template <TrackSizeComputationVariant variant, TrackSizeComputationPhase phase> void increaseSizesToAccommodateSpanningItems(const GridItemsSpanGroupRange& gridItemsWithSpan);
+    template <TrackSizeComputationVariant variant> void increaseSizesToAccommodateSpanningItems(const GridItemsSpanGroupRange& gridItemsWithSpan);
     LayoutUnit itemSizeForTrackSizeComputationPhase(TrackSizeComputationPhase, RenderBox&) const;
-    template <TrackSizeComputationPhase phase> void distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<GridTrack*>* growBeyondGrowthLimitsTracks, LayoutUnit& availableLogicalSpace) const;
+    template <TrackSizeComputationVariant variant, TrackSizeComputationPhase phase> void distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<GridTrack*>* growBeyondGrowthLimitsTracks, LayoutUnit& freeSpace) const;
+
     std::optional<LayoutUnit> gridAreaBreadthForChild(const RenderBox&, GridTrackSizingDirection) const;
 
     void computeBaselineAlignmentContext();
@@ -274,7 +286,7 @@
     LayoutUnit computeTrackBasedSize() const { return m_algorithm.computeTrackBasedSize(); }
     GridTrackSizingDirection direction() const { return m_algorithm.m_direction; }
     double findFrUnitSize(const GridSpan& tracksSpan, LayoutUnit leftOverSpace) const { return m_algorithm.findFrUnitSize(tracksSpan, leftOverSpace); }
-    void distributeSpaceToTracks(Vector<GridTrack*>& tracks, LayoutUnit& availableLogicalSpace) const { m_algorithm.distributeSpaceToTracks<MaximizeTracks>(tracks, nullptr, availableLogicalSpace); }
+    void distributeSpaceToTracks(Vector<GridTrack*>& tracks, LayoutUnit& availableLogicalSpace) const { m_algorithm.distributeSpaceToTracks<TrackSizeComputationVariant::NotCrossingFlexibleTracks, MaximizeTracks>(tracks, nullptr, availableLogicalSpace); }
     const RenderGrid* renderGrid() const { return m_algorithm.m_renderGrid; }
     std::optional<LayoutUnit> availableSpace() const { return m_algorithm.availableSpace(); }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to