[CSS Grid Layout] Skip items spanning flex tracks when sizing content based tracks
authorsvillar@igalia.com <svillar@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 Jan 2015 08:56:13 +0000 (08:56 +0000)
committersvillar@igalia.com <svillar@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 Jan 2015 08:56:13 +0000 (08:56 +0000)
https://bugs.webkit.org/show_bug.cgi?id=140720

Reviewed by David Hyatt.

Source/WebCore:

Section "11.5. Resolve Intrinsic Track Sizes" of the specs forces
us to ignore items spanning tracks with flex sizing functions when
resolving the content-based track sizing functions. Items with
span < 2 are not affected by this rule (as they will belong to a
single track). This way the algorithm ensures that min-content and
max-content restrictions are fulfilled before distributing the
extra space.

Test: fast/css-grid-layout/flex-and-content-sized-resolution-columns.html

* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::spanningItemCrossesFlexibleSizedTracks):
(WebCore::integerSpanForDirection):
(WebCore::RenderGrid::resolveContentBasedTrackSizingFunctions):
* rendering/RenderGrid.h:

LayoutTests:

* fast/css-grid-layout/flex-and-content-sized-resolution-columns-expected.txt: Added.
* fast/css-grid-layout/flex-and-content-sized-resolution-columns.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@178895 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/css-grid-layout/flex-and-content-sized-resolution-columns-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/flex-and-content-sized-resolution-columns.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderGrid.cpp
Source/WebCore/rendering/RenderGrid.h

index adf4e02..60e2eba 100644 (file)
@@ -1,3 +1,13 @@
+2015-01-21  Sergio Villar Senin  <svillar@igalia.com>
+
+        [CSS Grid Layout] Skip items spanning flex tracks when sizing content based tracks
+        https://bugs.webkit.org/show_bug.cgi?id=140720
+
+        Reviewed by David Hyatt.
+
+        * fast/css-grid-layout/flex-and-content-sized-resolution-columns-expected.txt: Added.
+        * fast/css-grid-layout/flex-and-content-sized-resolution-columns.html: Added.
+
 2015-01-22  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         put_by_val_direct need to check the property is index or not for using putDirect / putDirectIndex
diff --git a/LayoutTests/fast/css-grid-layout/flex-and-content-sized-resolution-columns-expected.txt b/LayoutTests/fast/css-grid-layout/flex-and-content-sized-resolution-columns-expected.txt
new file mode 100644 (file)
index 0000000..328eb16
--- /dev/null
@@ -0,0 +1,30 @@
+PASS window.getComputedStyle(gridFixedAndMinContentAndFlex, '').getPropertyValue('-webkit-grid-template-columns') is "20px 30px 50px"
+PASS window.getComputedStyle(gridFixedAndMinContentAndFlexMultipleOverlap, '').getPropertyValue('-webkit-grid-template-columns') is "20px 10px 70px"
+PASS window.getComputedStyle(gridMinMaxFixedFlexAndMaxContentAndAuto, '').getPropertyValue('-webkit-grid-template-columns') is "60px 20px 20px"
+PASS window.getComputedStyle(gridMinMaxFixedFlexAndMaxContentAndAutoNoFlexSpanningItems, '').getPropertyValue('-webkit-grid-template-columns') is "100px 0px 0px"
+PASS window.getComputedStyle(gridMinMaxFlexFixedAndMinContentAndFixed, '').getPropertyValue('-webkit-grid-template-columns') is "35px 5px 25px"
+PASS window.getComputedStyle(gridMinContentAndMinMaxFixedMinContentAndFlex, '').getPropertyValue('-webkit-grid-template-columns') is "20px 20px 60px"
+PASS window.getComputedStyle(gridMaxContentAndMinMaxFixedMaxContentAndFlex, '').getPropertyValue('-webkit-grid-template-columns') is "70px 20px 10px"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Test that resolving auto tracks on grid items works properly.
+
+XXXXXXXX
+XXXXX
+XXX XXX
+XXXX
+XXX XXX
+XXXX
+XXX XXX
+XXXX XXXX
+XXXX XXXX
+XXX XXX
+XXXXX XXXXX
+XX XX XX XX
+XXXXX
+XXX XXX XXX
+XXXX XXXX
+XXXXX
+XXX XXX XXX
+XXXX XXXX
diff --git a/LayoutTests/fast/css-grid-layout/flex-and-content-sized-resolution-columns.html b/LayoutTests/fast/css-grid-layout/flex-and-content-sized-resolution-columns.html
new file mode 100644 (file)
index 0000000..d4ec1b2
--- /dev/null
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link href="resources/grid.css" rel="stylesheet">
+<style>
+.grid {
+     font: 10px/1 Ahem;
+}
+
+.gridFixedAndMinContentAndFlex {
+     -webkit-grid-template-columns: 20px -webkit-min-content 1fr;
+}
+
+.gridMinMaxFixedFlexAndMaxContentAndAuto {
+     -webkit-grid-template-columns: minmax(20px, 1fr) -webkit-max-content auto;
+}
+
+.gridMinMaxFlexFixedAndMinContentAndFixed {
+     -webkit-grid-template-columns: minmax(0.5fr, 35px) -webkit-min-content 25px;
+}
+
+.gridMinContentAndMinMaxFixedMinContentAndFlex {
+     -webkit-grid-template-columns: -webkit-min-content minmax(20px, -webkit-min-content) 2fr;
+}
+
+.gridMaxContentAndMinMaxFixedMaxContentAndFlex {
+     -webkit-grid-template-columns: -webkit-max-content minmax(20px, -webkit-max-content) 1fr;
+}
+
+</style>
+<script src="../../resources/js-test.js"></script>
+</head>
+<body>
+
+<p>Test that resolving auto tracks on grid items works properly.</p>
+
+<div style="position: relative; width: 100px;">
+    <div id="gridFixedAndMinContentAndFlex" class="grid gridFixedAndMinContentAndFlex">
+       <div style="-webkit-grid-column: 2 / span 2;">XXXXXXXX</div>
+       <div style="-webkit-grid-column: 1 / span 2; -webkit-grid-row: 2;">XXXXX</div>
+    </div>
+</div>
+
+<div style="position: relative; width: 100px;">
+    <div id="gridFixedAndMinContentAndFlexMultipleOverlap" class="grid gridFixedAndMinContentAndFlex">
+       <div style="-webkit-grid-column: 1 / span 2;">XXX XXX</div>
+       <div style="-webkit-grid-column: 1 / -1; -webkit-grid-row: 2;">XXXX</div>
+    </div>
+</div>
+
+<div style="position: relative; width: 100px;">
+    <div id="gridMinMaxFixedFlexAndMaxContentAndAuto" class="grid gridMinMaxFixedFlexAndMaxContentAndAuto">
+       <div style="-webkit-grid-column: 1 / span 2;">XXX XXX</div>
+       <div style="-webkit-grid-column: 2 / span 2; -webkit-grid-row: 2;">XXXX</div>
+    </div>
+</div>
+
+<div style="position: relative; width: 100px;">
+    <div id="gridMinMaxFixedFlexAndMaxContentAndAutoNoFlexSpanningItems" class="grid gridMinMaxFixedFlexAndMaxContentAndAuto">
+       <div style="-webkit-grid-column: 1 / -1;">XXX XXX</div>
+       <div style="-webkit-grid-column: 1 / span 2; -webkit-grid-row: 2;">XXXX XXXX</div>
+    </div>
+</div>
+
+<div style="position: relative; width: 100px;">
+    <div id="gridMinMaxFlexFixedAndMinContentAndFixed" class="grid gridMinMaxFlexFixedAndMinContentAndFixed">
+       <div style="-webkit-grid-column: 1 / span 2;">XXXX XXXX</div>
+       <div style="-webkit-grid-column: 2 / span 2; -webkit-grid-row: 2;">XXX XXX</div>
+       <div style="-webkit-grid-column: 1 / -1; -webkit-grid-row: 3;">XXXXX XXXXX</div>
+       <div style="-webkit-grid-column: 2 / span 2; -webkit-grid-row: 4;">XX XX XX XX</div>
+    </div>
+</div>
+
+<div style="position: relative; width: 100px;">
+    <div id="gridMinContentAndMinMaxFixedMinContentAndFlex" class="grid gridMinContentAndMinMaxFixedMinContentAndFlex">
+       <div style="-webkit-grid-column: 2 / span 2;">XXXXX</div>
+       <div style="-webkit-grid-column: 1 / -1; -webkit-grid-row: 2;">XXX XXX XXX</div>
+       <div style="-webkit-grid-column: 1 / span 2; -webkit-grid-row: 3;">XXXX XXXX</div>
+    </div>
+</div>
+
+<div style="position: relative; width: 100px;">
+    <div id="gridMaxContentAndMinMaxFixedMaxContentAndFlex" class="grid gridMaxContentAndMinMaxFixedMaxContentAndFlex">
+       <div style="-webkit-grid-column: 2 / span 2;">XXXXX</div>
+       <div style="-webkit-grid-column: 1 / -1; -webkit-grid-row: 2;">XXX XXX XXX</div>
+       <div style="-webkit-grid-column: 1 / span 2; -webkit-grid-row: 3;">XXXX XXXX</div>
+    </div>
+</div>
+
+</body>
+<script src="resources/grid-definitions-parsing-utils.js"></script>
+<script>
+function checkColumns(gridId, columnValue)
+{
+     window.gridElement = document.getElementById(gridId);
+     shouldBeEqualToString("window.getComputedStyle(" + gridId + ", '').getPropertyValue('-webkit-grid-template-columns')", columnValue);
+}
+
+checkColumns("gridFixedAndMinContentAndFlex", "20px 30px 50px");
+checkColumns("gridFixedAndMinContentAndFlexMultipleOverlap", "20px 10px 70px");
+checkColumns("gridMinMaxFixedFlexAndMaxContentAndAuto", "60px 20px 20px");
+checkColumns("gridMinMaxFixedFlexAndMaxContentAndAutoNoFlexSpanningItems", "100px 0px 0px");
+checkColumns("gridMinMaxFlexFixedAndMinContentAndFixed", "35px 5px 25px");
+checkColumns("gridMinContentAndMinMaxFixedMinContentAndFlex", "20px 20px 60px");
+checkColumns("gridMaxContentAndMinMaxFixedMaxContentAndFlex", "70px 20px 10px");
+
+</script>
+</html>
index 3549e90..de3e569 100644 (file)
@@ -1,3 +1,26 @@
+2015-01-21  Sergio Villar Senin  <svillar@igalia.com>
+
+        [CSS Grid Layout] Skip items spanning flex tracks when sizing content based tracks
+        https://bugs.webkit.org/show_bug.cgi?id=140720
+
+        Reviewed by David Hyatt.
+
+        Section "11.5. Resolve Intrinsic Track Sizes" of the specs forces
+        us to ignore items spanning tracks with flex sizing functions when
+        resolving the content-based track sizing functions. Items with
+        span < 2 are not affected by this rule (as they will belong to a
+        single track). This way the algorithm ensures that min-content and
+        max-content restrictions are fulfilled before distributing the
+        extra space.
+
+        Test: fast/css-grid-layout/flex-and-content-sized-resolution-columns.html
+
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::spanningItemCrossesFlexibleSizedTracks):
+        (WebCore::integerSpanForDirection):
+        (WebCore::RenderGrid::resolveContentBasedTrackSizingFunctions):
+        * rendering/RenderGrid.h:
+
 2015-01-22  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         put_by_val_direct need to check the property is index or not for using putDirect / putDirectIndex
index 2a6e22f..84b61d9 100644 (file)
@@ -559,17 +559,37 @@ private:
     unsigned m_span;
 };
 
+bool RenderGrid::spanningItemCrossesFlexibleSizedTracks(const GridCoordinate& coordinate, GridTrackSizingDirection direction) const
+{
+    const GridSpan itemSpan = (direction == ForColumns) ? coordinate.columns : coordinate.rows;
+    for (auto trackPosition : itemSpan) {
+        const GridTrackSize& trackSize = gridTrackSize(direction, trackPosition.toInt());
+        if (trackSize.minTrackBreadth().isFlex() || trackSize.maxTrackBreadth().isFlex())
+            return true;
+    }
+
+    return false;
+}
+
+static inline unsigned integerSpanForDirection(const GridCoordinate& coordinate, GridTrackSizingDirection direction)
+{
+    return (direction == ForRows) ? coordinate.rows.integerSpan() : coordinate.columns.integerSpan();
+}
+
 void RenderGrid::resolveContentBasedTrackSizingFunctions(GridTrackSizingDirection direction, GridSizingData& sizingData)
 {
-    // FIXME: Split the grid tracks into groups that doesn't overlap a <flex> grid track.
     sizingData.itemsSortedByIncreasingSpan.shrink(0);
     HashSet<RenderBox*> itemsSet;
     for (auto trackIndex : sizingData.contentSizedTracksIndex) {
         GridIterator iterator(m_grid, direction, trackIndex);
 
         while (RenderBox* gridItem = iterator.nextGridItem()) {
-            if (itemsSet.add(gridItem).isNewEntry)
-                sizingData.itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, cachedGridCoordinate(*gridItem), direction));
+            if (itemsSet.add(gridItem).isNewEntry) {
+                const GridCoordinate& coordinate = cachedGridCoordinate(*gridItem);
+                // We should not include items spanning more than one track that span tracks with flexible sizing functions.
+                if (integerSpanForDirection(coordinate, direction) == 1 || !spanningItemCrossesFlexibleSizedTracks(coordinate, direction))
+                    sizingData.itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, coordinate, direction));
+            }
         }
     }
     std::sort(sizingData.itemsSortedByIncreasingSpan.begin(), sizingData.itemsSortedByIncreasingSpan.end());
index c846435..7f30188 100644 (file)
@@ -114,6 +114,8 @@ private:
 
     bool gridWasPopulated() const { return !m_grid.isEmpty() && !m_grid[0].isEmpty(); }
 
+    bool spanningItemCrossesFlexibleSizedTracks(const GridCoordinate&, GridTrackSizingDirection) const;
+
     unsigned gridColumnCount() const
     {
         ASSERT(gridWasPopulated());