<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[201510] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/201510">201510</a></dd>
<dt>Author</dt> <dd>svillar@igalia.com</dd>
<dt>Date</dt> <dd>2016-05-31 08:17:03 -0700 (Tue, 31 May 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[css-grid] Empty grid without explicit tracks shouldn't have any size
https://bugs.webkit.org/show_bug.cgi?id=155197

Reviewed by Darin Adler.

Source/WebCore:

The internal representation of the grid is a Vector of Vector representing rows and
columns. Because of that it was not possible to have columns without having at least one
row. That forced us to have a 1x1 internal representation of the grid even if it was
actually empty. That works for most of the cases except when the grid is actually empty.

By changing the way we compute the sizes we can overcome that implementation
restriction. This allowed us also to thighten the conditions under we could use the
GridIterator. From now on it won't be possible to use it on empty grids so callers should
enforce that restriction.

A new bool was added to verify that placeItemsOnGrid() has been already called. The previous
code was relying on the fact that there were items in the internal representation, which is
wrong, as there might be no items in the grid.

Test: fast/css-grid-layout/empty-grid.html

* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::GridIterator::GridIterator): Added ASSERTs.
(WebCore::RenderGrid::GridIterator::nextGridItem): Ditto.
(WebCore::RenderGrid::GridIterator::isEmptyAreaEnough): Ditto.
(WebCore::RenderGrid::GridIterator::nextEmptyGridArea): Ditto.
(WebCore::RenderGrid::gridColumnCount): Use the style to resolve the number of columns if
the internal representation is empty.
(WebCore::RenderGrid::gridRowCount):
(WebCore::RenderGrid::guttersSize): Allow to pass 0 as span, this permits using the return
value of gridColumnCount|gridRowCount directly to call this method.
(WebCore::RenderGrid::computeIntrinsicLogicalWidths): Use m_gridIsDirty.
(WebCore::RenderGrid::computeUsedBreadthOfGridTracks): Do not examine the contents of grid
tracks if there are no items in the grid.
(WebCore::RenderGrid::resolveContentBasedTrackSizingFunctions): Ditto.
(WebCore::RenderGrid::placeItemsOnGrid): Set m_gridIsDirty to false.
(WebCore::RenderGrid::populateExplicitGridAndOrderIterator):
(WebCore::RenderGrid::clearGrid):
(WebCore::RenderGrid::populateGridPositionsForDirection):
* rendering/RenderGrid.h: Moved gridColumnCount/gridRowCount to cpp file.

LayoutTests:

Make sure that empty grids (and grids with one empty axis) are properly handled. Do also
verify that removing all the items from a grid also generates an correct empty grid.

* fast/css-grid-layout/empty-grid-expected.txt: Added.
* fast/css-grid-layout/empty-grid.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderGridcpp">trunk/Source/WebCore/rendering/RenderGrid.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderGridh">trunk/Source/WebCore/rendering/RenderGrid.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastcssgridlayoutemptygridexpectedtxt">trunk/LayoutTests/fast/css-grid-layout/empty-grid-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcssgridlayoutemptygridhtml">trunk/LayoutTests/fast/css-grid-layout/empty-grid.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (201509 => 201510)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-05-31 10:34:29 UTC (rev 201509)
+++ trunk/LayoutTests/ChangeLog        2016-05-31 15:17:03 UTC (rev 201510)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-05-25  Sergio Villar Senin  &lt;svillar@igalia.com&gt;
+
+        [css-grid] Empty grid without explicit tracks shouldn't have any size
+        https://bugs.webkit.org/show_bug.cgi?id=155197
+
+        Reviewed by Darin Adler.
+
+        Make sure that empty grids (and grids with one empty axis) are properly handled. Do also
+        verify that removing all the items from a grid also generates an correct empty grid.
+
+        * fast/css-grid-layout/empty-grid-expected.txt: Added.
+        * fast/css-grid-layout/empty-grid.html: Added.
+
</ins><span class="cx"> 2016-05-30  Per Arne Vollan  &lt;pvollan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed test gardening.
</span></span></pre></div>
<a id="trunkLayoutTestsfastcssgridlayoutemptygridexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css-grid-layout/empty-grid-expected.txt (0 => 201510)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css-grid-layout/empty-grid-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/empty-grid-expected.txt        2016-05-31 15:17:03 UTC (rev 201510)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+This test checks that grids with no in-flow items are actually empty.
+
+PASS
+XXXX
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/css-grid-layout/empty-grid-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkLayoutTestsfastcssgridlayoutemptygridhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css-grid-layout/empty-grid.html (0 => 201510)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css-grid-layout/empty-grid.html                                (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/empty-grid.html        2016-05-31 15:17:03 UTC (rev 201510)
</span><span class="lines">@@ -0,0 +1,61 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;link href=&quot;resources/grid.css&quot; rel=&quot;stylesheet&quot;&gt;
+&lt;link href=&quot;../css-intrinsic-dimensions/resources/width-keyword-classes.css&quot; rel=stylesheet&gt;
+&lt;style&gt;
+.gridWithAbsolutePositionedItem {
+    /* Ensures that the grid container is the containing block of the absolutely positioned grid children. */
+    position: relative;
+}
+
+.grid {
+    grid-auto-columns: 200px;
+    grid-auto-rows: 200px;
+}
+
+.item {
+    position: absolute;
+    font: 10px/1 Ahem;
+}
+
+&lt;/style&gt;
+
+&lt;script&gt;
+function addRemoveItem()
+{
+    var gridItem = document.createElement(&quot;div&quot;);
+    gridItem.style.width = &quot;100px&quot;;
+    gridItem.style.height = &quot;100px&quot;;
+    gridItem.style.backgroundColor = &quot;red&quot;;
+    var gridElement = document.getElementById(&quot;dynamicGrid&quot;);
+    gridElement.appendChild(gridItem);
+    gridElement.removeChild(gridItem);
+}
+
+function doTest() {
+     addRemoveItem();
+     checkLayout(&quot;.grid&quot;);
+}
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/check-layout.js&quot;&gt;&lt;/script&gt;
+
+&lt;body onload=&quot;doTest()&quot;&gt;
+
+&lt;p&gt;This test checks that grids with no in-flow items are actually empty.&lt;/p&gt;
+
+&lt;div class=&quot;grid min-content&quot; data-expected-width=&quot;0&quot; data-expected-height=&quot;0&quot;&gt;&lt;/div&gt;
+
+&lt;div class=&quot;grid min-content gridWithAbsolutePositionedItem&quot; data-expected-width=&quot;0&quot; data-expected-height=&quot;0&quot;&gt;
+    &lt;div class=&quot;item&quot; data-expected-width=&quot;40&quot; data-expected-height=&quot;10&quot;&gt;XXXX&lt;/div&gt;
+&lt;/div&gt;
+
+&lt;div id=&quot;dynamicGrid&quot; class=&quot;grid min-content&quot; data-expected-width=&quot;0&quot; data-expected-height=&quot;0&quot;&gt;&lt;/div&gt;
+
+&lt;div class=&quot;grid min-content&quot; style=&quot;grid-template-rows: 100px;&quot; data-expected-width=&quot;0&quot; data-expected-height=&quot;100&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;grid min-content&quot; style=&quot;grid-template-rows: auto;&quot; data-expected-width=&quot;0&quot; data-expected-height=&quot;0&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;grid min-content&quot; style=&quot;grid-template-rows: 1fr;&quot; data-expected-width=&quot;0&quot; data-expected-height=&quot;0&quot;&gt;&lt;/div&gt;
+
+&lt;div class=&quot;grid min-content&quot; style=&quot;grid-template-columns: 100px;&quot; data-expected-width=&quot;100&quot; data-expected-height=&quot;0&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;grid min-content&quot; style=&quot;grid-template-columns: auto;&quot; data-expected-width=&quot;0&quot; data-expected-height=&quot;0&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;grid min-content&quot; style=&quot;grid-template-columns: 1fr;&quot; data-expected-width=&quot;0&quot; data-expected-height=&quot;0&quot;&gt;&lt;/div&gt;
+
+&lt;/body&gt;
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/css-grid-layout/empty-grid.html
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (201509 => 201510)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-05-31 10:34:29 UTC (rev 201509)
+++ trunk/Source/WebCore/ChangeLog        2016-05-31 15:17:03 UTC (rev 201510)
</span><span class="lines">@@ -1,3 +1,46 @@
</span><ins>+2016-05-25  Sergio Villar Senin  &lt;svillar@igalia.com&gt;
+
+        [css-grid] Empty grid without explicit tracks shouldn't have any size
+        https://bugs.webkit.org/show_bug.cgi?id=155197
+
+        Reviewed by Darin Adler.
+
+        The internal representation of the grid is a Vector of Vector representing rows and
+        columns. Because of that it was not possible to have columns without having at least one
+        row. That forced us to have a 1x1 internal representation of the grid even if it was
+        actually empty. That works for most of the cases except when the grid is actually empty.
+
+        By changing the way we compute the sizes we can overcome that implementation
+        restriction. This allowed us also to thighten the conditions under we could use the
+        GridIterator. From now on it won't be possible to use it on empty grids so callers should
+        enforce that restriction.
+
+        A new bool was added to verify that placeItemsOnGrid() has been already called. The previous
+        code was relying on the fact that there were items in the internal representation, which is
+        wrong, as there might be no items in the grid.
+
+        Test: fast/css-grid-layout/empty-grid.html
+
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::GridIterator::GridIterator): Added ASSERTs.
+        (WebCore::RenderGrid::GridIterator::nextGridItem): Ditto.
+        (WebCore::RenderGrid::GridIterator::isEmptyAreaEnough): Ditto.
+        (WebCore::RenderGrid::GridIterator::nextEmptyGridArea): Ditto.
+        (WebCore::RenderGrid::gridColumnCount): Use the style to resolve the number of columns if
+        the internal representation is empty.
+        (WebCore::RenderGrid::gridRowCount):
+        (WebCore::RenderGrid::guttersSize): Allow to pass 0 as span, this permits using the return
+        value of gridColumnCount|gridRowCount directly to call this method.
+        (WebCore::RenderGrid::computeIntrinsicLogicalWidths): Use m_gridIsDirty.
+        (WebCore::RenderGrid::computeUsedBreadthOfGridTracks): Do not examine the contents of grid
+        tracks if there are no items in the grid.
+        (WebCore::RenderGrid::resolveContentBasedTrackSizingFunctions): Ditto.
+        (WebCore::RenderGrid::placeItemsOnGrid): Set m_gridIsDirty to false.
+        (WebCore::RenderGrid::populateExplicitGridAndOrderIterator):
+        (WebCore::RenderGrid::clearGrid):
+        (WebCore::RenderGrid::populateGridPositionsForDirection):
+        * rendering/RenderGrid.h: Moved gridColumnCount/gridRowCount to cpp file.
+
</ins><span class="cx"> 2016-05-30  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Move CrossThreadCopier/CrossThreadTask to WTF.
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderGridcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderGrid.cpp (201509 => 201510)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderGrid.cpp        2016-05-31 10:34:29 UTC (rev 201509)
+++ trunk/Source/WebCore/rendering/RenderGrid.cpp        2016-05-31 15:17:03 UTC (rev 201510)
</span><span class="lines">@@ -139,14 +139,16 @@
</span><span class="cx">         , m_columnIndex((direction == ForColumns) ? fixedTrackIndex : varyingTrackIndex)
</span><span class="cx">         , m_childIndex(0)
</span><span class="cx">     {
</span><ins>+        ASSERT(!m_grid.isEmpty());
+        ASSERT(!m_grid[0].isEmpty());
</ins><span class="cx">         ASSERT(m_rowIndex &lt; m_grid.size());
</span><span class="cx">         ASSERT(m_columnIndex &lt; m_grid[0].size());
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     RenderBox* nextGridItem()
</span><span class="cx">     {
</span><del>-        if (!m_grid.size())
-            return 0;
</del><ins>+        ASSERT(!m_grid.isEmpty());
+        ASSERT(!m_grid[0].isEmpty());
</ins><span class="cx"> 
</span><span class="cx">         unsigned&amp; varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m_columnIndex;
</span><span class="cx">         const unsigned endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size();
</span><span class="lines">@@ -162,6 +164,9 @@
</span><span class="cx"> 
</span><span class="cx">     bool isEmptyAreaEnough(unsigned rowSpan, unsigned columnSpan) const
</span><span class="cx">     {
</span><ins>+        ASSERT(!m_grid.isEmpty());
+        ASSERT(!m_grid[0].isEmpty());
+
</ins><span class="cx">         // Ignore cells outside current grid as we will grow it later if needed.
</span><span class="cx">         unsigned maxRows = std::min&lt;unsigned&gt;(m_rowIndex + rowSpan, m_grid.size());
</span><span class="cx">         unsigned maxColumns = std::min&lt;unsigned&gt;(m_columnIndex + columnSpan, m_grid[0].size());
</span><span class="lines">@@ -180,7 +185,10 @@
</span><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;GridArea&gt; nextEmptyGridArea(unsigned fixedTrackSpan, unsigned varyingTrackSpan)
</span><span class="cx">     {
</span><del>-        ASSERT(fixedTrackSpan &gt;= 1 &amp;&amp; varyingTrackSpan &gt;= 1);
</del><ins>+        ASSERT(!m_grid.isEmpty());
+        ASSERT(!m_grid[0].isEmpty());
+        ASSERT(fixedTrackSpan &gt;= 1);
+        ASSERT(varyingTrackSpan &gt;= 1);
</ins><span class="cx"> 
</span><span class="cx">         if (m_grid.isEmpty())
</span><span class="cx">             return nullptr;
</span><span class="lines">@@ -319,6 +327,23 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+unsigned RenderGrid::gridColumnCount() const
+{
+    ASSERT(!m_gridIsDirty);
+    // Due to limitations in our internal representation, we cannot know the number of columns from
+    // m_grid *if* there is no row (because m_grid would be empty). That's why in that case we need
+    // to get it from the style. Note that we know for sure that there are't any implicit tracks,
+    // because not having rows implies that there are no &quot;normal&quot; children (out-of-flow children are
+    // not stored in m_grid).
+    return m_grid.size() ? m_grid[0].size() : GridPositionsResolver::explicitGridColumnCount(style(), m_autoRepeatColumns);
+}
+
+unsigned RenderGrid::gridRowCount() const
+{
+    ASSERT(!m_gridIsDirty);
+    return m_grid.size();
+}
+
</ins><span class="cx"> LayoutUnit RenderGrid::computeTrackBasedLogicalHeight(const GridSizingData&amp; sizingData) const
</span><span class="cx"> {
</span><span class="cx">     LayoutUnit logicalHeight;
</span><span class="lines">@@ -420,9 +445,7 @@
</span><span class="cx"> 
</span><span class="cx"> LayoutUnit RenderGrid::guttersSize(GridTrackSizingDirection direction, unsigned span) const
</span><span class="cx"> {
</span><del>-    ASSERT(span &gt;= 1);
-
-    if (span == 1)
</del><ins>+    if (span &lt;= 1)
</ins><span class="cx">         return { };
</span><span class="cx"> 
</span><span class="cx">     const Length&amp; trackGap = direction == ForColumns ? style().gridColumnGap() : style().gridRowGap();
</span><span class="lines">@@ -436,7 +459,7 @@
</span><span class="cx"> 
</span><span class="cx"> void RenderGrid::computeIntrinsicLogicalWidths(LayoutUnit&amp; minLogicalWidth, LayoutUnit&amp; maxLogicalWidth) const
</span><span class="cx"> {
</span><del>-    bool wasPopulated = gridWasPopulated();
</del><ins>+    bool wasPopulated = !m_gridIsDirty;
</ins><span class="cx">     if (!wasPopulated)
</span><span class="cx">         const_cast&lt;RenderGrid*&gt;(this)-&gt;placeItemsOnGrid();
</span><span class="cx"> 
</span><span class="lines">@@ -589,16 +612,18 @@
</span><span class="cx">         for (const auto&amp; trackIndex : flexibleSizedTracksIndex)
</span><span class="cx">             flexFraction = std::max(flexFraction, normalizedFlexFraction(tracks[trackIndex], gridTrackSize(direction, trackIndex).maxTrackBreadth().flex()));
</span><span class="cx"> 
</span><del>-        for (unsigned i = 0; i &lt; flexibleSizedTracksIndex.size(); ++i) {
-            GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i]);
-            while (RenderBox* gridItem = iterator.nextGridItem()) {
-                const GridSpan span = cachedGridSpan(*gridItem, direction);
</del><ins>+        if (!m_gridItemArea.isEmpty()) {
+            for (unsigned i = 0; i &lt; flexibleSizedTracksIndex.size(); ++i) {
+                GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i]);
+                while (auto* gridItem = iterator.nextGridItem()) {
+                    GridSpan&amp; span = cachedGridSpan(*gridItem, direction);
</ins><span class="cx"> 
</span><del>-                // Do not include already processed items.
-                if (i &gt; 0 &amp;&amp; span.startLine() &lt;= flexibleSizedTracksIndex[i - 1])
-                    continue;
</del><ins>+                    // Do not include already processed items.
+                    if (i &gt; 0 &amp;&amp; span.startLine() &lt;= flexibleSizedTracksIndex[i - 1])
+                        continue;
</ins><span class="cx"> 
</span><del>-                flexFraction = std::max(flexFraction, findFlexFactorUnitSize(tracks, span, direction, maxContentForChild(*gridItem, direction, sizingData)));
</del><ins>+                    flexFraction = std::max(flexFraction, findFlexFactorUnitSize(tracks, span, direction, maxContentForChild(*gridItem, direction, sizingData)));
+                }
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -898,21 +923,23 @@
</span><span class="cx"> {
</span><span class="cx">     sizingData.itemsSortedByIncreasingSpan.shrink(0);
</span><span class="cx">     HashSet&lt;RenderBox*&gt; itemsSet;
</span><del>-    for (auto trackIndex : sizingData.contentSizedTracksIndex) {
-        GridIterator iterator(m_grid, direction, trackIndex);
-        GridTrack&amp; track = (direction == ForColumns) ? sizingData.columnTracks[trackIndex] : sizingData.rowTracks[trackIndex];
</del><ins>+    if (!m_gridItemArea.isEmpty()) {
+        for (auto trackIndex : sizingData.contentSizedTracksIndex) {
+            GridIterator iterator(m_grid, direction, trackIndex);
+            GridTrack&amp; track = (direction == ForColumns) ? sizingData.columnTracks[trackIndex] : sizingData.rowTracks[trackIndex];
</ins><span class="cx"> 
</span><del>-        while (RenderBox* gridItem = iterator.nextGridItem()) {
-            if (itemsSet.add(gridItem).isNewEntry) {
-                const GridSpan&amp; span = cachedGridSpan(*gridItem, direction);
-                if (span.integerSpan() == 1)
-                    resolveContentBasedTrackSizingFunctionsForNonSpanningItems(direction, span, *gridItem, track, sizingData);
-                else if (!spanningItemCrossesFlexibleSizedTracks(span, direction))
-                    sizingData.itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, span));
</del><ins>+            while (auto* gridItem = iterator.nextGridItem()) {
+                if (itemsSet.add(gridItem).isNewEntry) {
+                    GridSpan&amp; span = cachedGridSpan(*gridItem, direction);
+                    if (span.integerSpan() == 1)
+                        resolveContentBasedTrackSizingFunctionsForNonSpanningItems(direction, span, *gridItem, track, sizingData);
+                    else if (!spanningItemCrossesFlexibleSizedTracks(span, direction))
+                        sizingData.itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, span));
+                }
</ins><span class="cx">             }
</span><span class="cx">         }
</span><ins>+        std::sort(sizingData.itemsSortedByIncreasingSpan.begin(), sizingData.itemsSortedByIncreasingSpan.end());
</ins><span class="cx">     }
</span><del>-    std::sort(sizingData.itemsSortedByIncreasingSpan.begin(), sizingData.itemsSortedByIncreasingSpan.end());
</del><span class="cx"> 
</span><span class="cx">     auto it = sizingData.itemsSortedByIncreasingSpan.begin();
</span><span class="cx">     auto end = sizingData.itemsSortedByIncreasingSpan.end();
</span><span class="lines">@@ -1295,13 +1322,14 @@
</span><span class="cx"> 
</span><span class="cx"> void RenderGrid::placeItemsOnGrid()
</span><span class="cx"> {
</span><del>-    ASSERT(!gridWasPopulated());
</del><ins>+    ASSERT(m_gridIsDirty);
</ins><span class="cx">     ASSERT(m_gridItemArea.isEmpty());
</span><span class="cx"> 
</span><span class="cx">     m_autoRepeatColumns = computeAutoRepeatTracksCount(ForColumns);
</span><span class="cx">     m_autoRepeatRows = computeAutoRepeatTracksCount(ForRows);
</span><span class="cx"> 
</span><span class="cx">     populateExplicitGridAndOrderIterator();
</span><ins>+    m_gridIsDirty = false;
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;RenderBox*&gt; autoMajorAxisAutoGridItems;
</span><span class="cx">     Vector&lt;RenderBox*&gt; specifiedMajorAxisAutoGridItems;
</span><span class="lines">@@ -1349,8 +1377,8 @@
</span><span class="cx"> {
</span><span class="cx">     OrderIteratorPopulator populator(m_orderIterator);
</span><span class="cx">     m_smallestRowStart = m_smallestColumnStart = 0;
</span><del>-    unsigned maximumRowIndex = std::max&lt;unsigned&gt;(1, GridPositionsResolver::explicitGridRowCount(style(), m_autoRepeatRows));
-    unsigned maximumColumnIndex = std::max&lt;unsigned&gt;(1, GridPositionsResolver::explicitGridColumnCount(style(), m_autoRepeatColumns));
</del><ins>+    unsigned maximumRowIndex = GridPositionsResolver::explicitGridRowCount(style(), m_autoRepeatRows);
+    unsigned maximumColumnIndex = GridPositionsResolver::explicitGridColumnCount(style(), m_autoRepeatColumns);
</ins><span class="cx"> 
</span><span class="cx">     for (RenderBox* child = firstChildBox(); child; child = child-&gt;nextSiblingBox()) {
</span><span class="cx">         if (child-&gt;isOutOfFlowPositioned())
</span><span class="lines">@@ -1510,6 +1538,7 @@
</span><span class="cx"> {
</span><span class="cx">     m_grid.clear();
</span><span class="cx">     m_gridItemArea.clear();
</span><ins>+    m_gridIsDirty = true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static const StyleContentAlignmentData&amp; contentAlignmentNormalBehaviorGrid()
</span><span class="lines">@@ -1767,16 +1796,19 @@
</span><span class="cx">     unsigned numberOfTracks = tracks.size();
</span><span class="cx">     unsigned numberOfLines = numberOfTracks + 1;
</span><span class="cx">     unsigned lastLine = numberOfLines - 1;
</span><del>-    unsigned nextToLastLine = numberOfLines - 2;
</del><ins>+
</ins><span class="cx">     ContentAlignmentData offset = computeContentPositionAndDistributionOffset(direction, sizingData.freeSpaceForDirection(direction).value(), numberOfTracks);
</span><span class="cx">     LayoutUnit trackGap = guttersSize(direction, 2);
</span><span class="cx">     auto&amp; positions = isRowAxis ? m_columnPositions : m_rowPositions;
</span><span class="cx">     positions.resize(numberOfLines);
</span><span class="cx">     auto borderAndPadding = isRowAxis ? borderAndPaddingLogicalLeft() : borderAndPaddingBefore();
</span><span class="cx">     positions[0] = borderAndPadding + offset.positionOffset;
</span><del>-    for (unsigned i = 0; i &lt; nextToLastLine; ++i)
-        positions[i + 1] = positions[i] + offset.distributionOffset + tracks[i].baseSize() + trackGap;
-    positions[lastLine] = positions[nextToLastLine] + tracks[nextToLastLine].baseSize();
</del><ins>+    if (numberOfLines &gt; 1) {
+        unsigned nextToLastLine = numberOfLines - 2;
+        for (unsigned i = 0; i &lt; nextToLastLine; ++i)
+            positions[i + 1] = positions[i] + offset.distributionOffset + tracks[i].baseSize() + trackGap;
+        positions[lastLine] = positions[nextToLastLine] + tracks[nextToLastLine].baseSize();
+    }
</ins><span class="cx">     auto&amp; offsetBetweenTracks = isRowAxis ? m_offsetBetweenColumns : m_offsetBetweenRows;
</span><span class="cx">     offsetBetweenTracks = offset.distributionOffset;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderGridh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderGrid.h (201509 => 201510)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderGrid.h        2016-05-31 10:34:29 UTC (rev 201509)
+++ trunk/Source/WebCore/rendering/RenderGrid.h        2016-05-31 15:17:03 UTC (rev 201510)
</span><span class="lines">@@ -173,20 +173,10 @@
</span><span class="cx">     bool tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection, GridSizingData&amp;);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    bool gridWasPopulated() const { return !m_grid.isEmpty() &amp;&amp; !m_grid[0].isEmpty(); }
-
</del><span class="cx">     bool spanningItemCrossesFlexibleSizedTracks(const GridSpan&amp;, GridTrackSizingDirection) const;
</span><span class="cx"> 
</span><del>-    unsigned gridColumnCount() const
-    {
-        ASSERT(gridWasPopulated());
-        return m_grid[0].size();
-    }
-    unsigned gridRowCount() const
-    {
-        ASSERT(gridWasPopulated());
-        return m_grid.size();
-    }
</del><ins>+    unsigned gridColumnCount() const;
+    unsigned gridRowCount() const;
</ins><span class="cx"> 
</span><span class="cx">     bool hasDefiniteLogicalSize(GridTrackSizingDirection) const;
</span><span class="cx">     LayoutUnit translateRTLCoordinate(LayoutUnit) const;
</span><span class="lines">@@ -207,6 +197,8 @@
</span><span class="cx"> 
</span><span class="cx">     unsigned m_autoRepeatColumns { 0 };
</span><span class="cx">     unsigned m_autoRepeatRows { 0 };
</span><ins>+
+    bool m_gridIsDirty { true };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> size_t inline RenderGrid::autoRepeatCountForDirection(GridTrackSizingDirection direction) const
</span></span></pre>
</div>
</div>

</body>
</html>