<!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>[185059] trunk/Source/WebCore</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/185059">185059</a></dd>
<dt>Author</dt> <dd>svillar@igalia.com</dd>
<dt>Date</dt> <dd>2015-06-01 08:40:43 -0700 (Mon, 01 Jun 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[CSS Grid Layout] Simplify the interface of GridResolvedPosition
https://bugs.webkit.org/show_bug.cgi?id=139077

Reviewed by Darin Adler.

The interface of GridResolvedPosition is full of static methods
that are used only internally, we should not expose them.

Apart from that resolveGridPositionsFromStyle() do always return
a valid GridSpan from now on meaning that the caller has to ensure
that the resolution does not require running the auto-placement
algorithm. A new class called GridUnresolvedSpan was added for
that purpose.

No new tests as this is a refactoring.

* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::placeItemsOnGrid):
(WebCore::RenderGrid::populateExplicitGridAndOrderIterator):
(WebCore::RenderGrid::placeSpecifiedMajorAxisItemsOnGrid):
(WebCore::RenderGrid::placeAutoMajorAxisItemOnGrid):
* rendering/style/GridPosition.h:
* rendering/style/GridResolvedPosition.cpp:
(WebCore::gridLinesForSide):
(WebCore::implicitNamedGridLineForSide):
(WebCore::isNonExistentNamedLineOrArea):
(WebCore::GridUnresolvedSpan::requiresAutoPlacement):
(WebCore::GridUnresolvedSpan::adjustGridPositionsFromStyle):
(WebCore::adjustGridPositionForRowEndColumnEndSide):
(WebCore::adjustGridPositionForSide):
(WebCore::resolveNamedGridLinePositionFromStyle):
(WebCore::firstNamedGridLineBeforePosition):
(WebCore::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition):
(WebCore::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition):
(WebCore::resolveNamedGridLinePositionAgainstOppositePosition):
(WebCore::resolveGridPositionAgainstOppositePosition):
(WebCore::GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition):
(WebCore::resolveGridPositionFromStyle):
(WebCore::GridResolvedPosition::GridResolvedPosition):
(WebCore::GridResolvedPosition::unresolvedSpanFromStyle):
(WebCore::GridResolvedPosition::resolveGridPositionsFromStyle):
(WebCore::GridResolvedPosition::adjustGridPositionsFromStyle): Deleted.
(WebCore::GridResolvedPosition::resolveNamedGridLinePositionFromStyle): Deleted.
(WebCore::GridResolvedPosition::resolveGridPositionFromStyle): Deleted.
(WebCore::GridResolvedPosition::resolveGridPositionAgainstOppositePosition): Deleted.
(WebCore::GridResolvedPosition::resolveNamedGridLinePositionAgainstOppositePosition): Deleted.
(WebCore::GridResolvedPosition::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition): Deleted.
(WebCore::GridResolvedPosition::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition): Deleted.
* rendering/style/GridResolvedPosition.h:
(WebCore::GridUnresolvedSpan::GridUnresolvedSpan): New class.
(WebCore::GridUnresolvedSpan::initialPosition):
(WebCore::GridUnresolvedSpan::finalPosition):
(WebCore::GridUnresolvedSpan::initialPositionSide):
(WebCore::GridUnresolvedSpan::finalPositionSide):
(WebCore::GridResolvedPosition::adjustGridPositionForRowEndColumnEndSide): Deleted.
(WebCore::GridResolvedPosition::adjustGridPositionForSide): Deleted.
(WebCore::GridResolvedPosition::GridResolvedPosition): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<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="#trunkSourceWebCorerenderingstyleGridPositionh">trunk/Source/WebCore/rendering/style/GridPosition.h</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleGridResolvedPositioncpp">trunk/Source/WebCore/rendering/style/GridResolvedPosition.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleGridResolvedPositionh">trunk/Source/WebCore/rendering/style/GridResolvedPosition.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (185058 => 185059)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-06-01 15:28:49 UTC (rev 185058)
+++ trunk/Source/WebCore/ChangeLog        2015-06-01 15:40:43 UTC (rev 185059)
</span><span class="lines">@@ -1,3 +1,63 @@
</span><ins>+2015-06-01  Sergio Villar Senin  &lt;svillar@igalia.com&gt;
+
+        [CSS Grid Layout] Simplify the interface of GridResolvedPosition
+        https://bugs.webkit.org/show_bug.cgi?id=139077
+
+        Reviewed by Darin Adler.
+
+        The interface of GridResolvedPosition is full of static methods
+        that are used only internally, we should not expose them.
+
+        Apart from that resolveGridPositionsFromStyle() do always return
+        a valid GridSpan from now on meaning that the caller has to ensure
+        that the resolution does not require running the auto-placement
+        algorithm. A new class called GridUnresolvedSpan was added for
+        that purpose.
+
+        No new tests as this is a refactoring.
+
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::placeItemsOnGrid):
+        (WebCore::RenderGrid::populateExplicitGridAndOrderIterator):
+        (WebCore::RenderGrid::placeSpecifiedMajorAxisItemsOnGrid):
+        (WebCore::RenderGrid::placeAutoMajorAxisItemOnGrid):
+        * rendering/style/GridPosition.h:
+        * rendering/style/GridResolvedPosition.cpp:
+        (WebCore::gridLinesForSide):
+        (WebCore::implicitNamedGridLineForSide):
+        (WebCore::isNonExistentNamedLineOrArea):
+        (WebCore::GridUnresolvedSpan::requiresAutoPlacement):
+        (WebCore::GridUnresolvedSpan::adjustGridPositionsFromStyle):
+        (WebCore::adjustGridPositionForRowEndColumnEndSide):
+        (WebCore::adjustGridPositionForSide):
+        (WebCore::resolveNamedGridLinePositionFromStyle):
+        (WebCore::firstNamedGridLineBeforePosition):
+        (WebCore::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition):
+        (WebCore::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition):
+        (WebCore::resolveNamedGridLinePositionAgainstOppositePosition):
+        (WebCore::resolveGridPositionAgainstOppositePosition):
+        (WebCore::GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition):
+        (WebCore::resolveGridPositionFromStyle):
+        (WebCore::GridResolvedPosition::GridResolvedPosition):
+        (WebCore::GridResolvedPosition::unresolvedSpanFromStyle):
+        (WebCore::GridResolvedPosition::resolveGridPositionsFromStyle):
+        (WebCore::GridResolvedPosition::adjustGridPositionsFromStyle): Deleted.
+        (WebCore::GridResolvedPosition::resolveNamedGridLinePositionFromStyle): Deleted.
+        (WebCore::GridResolvedPosition::resolveGridPositionFromStyle): Deleted.
+        (WebCore::GridResolvedPosition::resolveGridPositionAgainstOppositePosition): Deleted.
+        (WebCore::GridResolvedPosition::resolveNamedGridLinePositionAgainstOppositePosition): Deleted.
+        (WebCore::GridResolvedPosition::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition): Deleted.
+        (WebCore::GridResolvedPosition::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition): Deleted.
+        * rendering/style/GridResolvedPosition.h:
+        (WebCore::GridUnresolvedSpan::GridUnresolvedSpan): New class.
+        (WebCore::GridUnresolvedSpan::initialPosition):
+        (WebCore::GridUnresolvedSpan::finalPosition):
+        (WebCore::GridUnresolvedSpan::initialPositionSide):
+        (WebCore::GridUnresolvedSpan::finalPositionSide):
+        (WebCore::GridResolvedPosition::adjustGridPositionForRowEndColumnEndSide): Deleted.
+        (WebCore::GridResolvedPosition::adjustGridPositionForSide): Deleted.
+        (WebCore::GridResolvedPosition::GridResolvedPosition): Deleted.
+
</ins><span class="cx"> 2015-06-01  Csaba Osztrogonác  &lt;ossy@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix the !ENABLE(VIDEO_TRACK) build after r184799
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderGridcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderGrid.cpp (185058 => 185059)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderGrid.cpp        2015-06-01 15:28:49 UTC (rev 185058)
+++ trunk/Source/WebCore/rendering/RenderGrid.cpp        2015-06-01 15:40:43 UTC (rev 185059)
</span><span class="lines">@@ -975,17 +975,22 @@
</span><span class="cx">     Vector&lt;RenderBox*&gt; autoMajorAxisAutoGridItems;
</span><span class="cx">     Vector&lt;RenderBox*&gt; specifiedMajorAxisAutoGridItems;
</span><span class="cx">     for (RenderBox* child = m_orderIterator.first(); child; child = m_orderIterator.next()) {
</span><del>-        std::unique_ptr&lt;GridSpan&gt; rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *child, ForRows);
-        std::unique_ptr&lt;GridSpan&gt; columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *child, ForColumns);
-        if (!rowPositions || !columnPositions) {
-            GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? columnPositions.get() : rowPositions.get();
-            if (!majorAxisPositions)
</del><ins>+        auto unresolvedRowPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), *child, ForRows);
+        auto unresolvedColumnPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), *child, ForColumns);
+
+        if (unresolvedRowPositions.requiresAutoPlacement() || unresolvedColumnPositions.requiresAutoPlacement()) {
+
+            bool majorAxisDirectionIsForColumns = autoPlacementMajorAxisDirection() == ForColumns;
+            if ((majorAxisDirectionIsForColumns &amp;&amp; unresolvedColumnPositions.requiresAutoPlacement())
+                || (!majorAxisDirectionIsForColumns &amp;&amp; unresolvedRowPositions.requiresAutoPlacement()))
</ins><span class="cx">                 autoMajorAxisAutoGridItems.append(child);
</span><span class="cx">             else
</span><span class="cx">                 specifiedMajorAxisAutoGridItems.append(child);
</span><span class="cx">             continue;
</span><span class="cx">         }
</span><del>-        insertItemIntoGrid(*child, GridCoordinate(*rowPositions, *columnPositions));
</del><ins>+        GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedRowPositions, style());
+        GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedColumnPositions, style());
+        insertItemIntoGrid(*child, GridCoordinate(rowPositions, columnPositions));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ASSERT(gridRowCount() &gt;= GridResolvedPosition::explicitGridRowCount(style()));
</span><span class="lines">@@ -1004,22 +1009,21 @@
</span><span class="cx">     for (RenderBox* child = firstChildBox(); child; child = child-&gt;nextSiblingBox()) {
</span><span class="cx">         populator.collectChild(*child);
</span><span class="cx"> 
</span><del>-        // This function bypasses the cache (cachedGridCoordinate()) as it is used to build it.
-        std::unique_ptr&lt;GridSpan&gt; rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *child, ForRows);
-        std::unique_ptr&lt;GridSpan&gt; columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *child, ForColumns);
-
-        // |positions| is 0 if we need to run the auto-placement algorithm.
-        if (rowPositions)
-            maximumRowIndex = std::max(maximumRowIndex, rowPositions-&gt;resolvedFinalPosition.next().toInt());
-        else {
</del><ins>+        auto unresolvedRowPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), *child, ForRows);
+        if (!unresolvedRowPositions.requiresAutoPlacement()) {
+            GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedRowPositions, style());
+            maximumRowIndex = std::max(maximumRowIndex, rowPositions.resolvedFinalPosition.next().toInt());
+        } else {
</ins><span class="cx">             // Grow the grid for items with a definite row span, getting the largest such span.
</span><span class="cx">             GridSpan positions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), *child, ForRows, GridResolvedPosition(0));
</span><span class="cx">             maximumRowIndex = std::max(maximumRowIndex, positions.resolvedFinalPosition.next().toInt());
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (columnPositions)
-            maximumColumnIndex = std::max(maximumColumnIndex, columnPositions-&gt;resolvedFinalPosition.next().toInt());
-        else {
</del><ins>+        auto unresolvedColumnPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), *child, ForColumns);
+        if (!unresolvedColumnPositions.requiresAutoPlacement()) {
+            GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedColumnPositions, style());
+            maximumColumnIndex = std::max(maximumColumnIndex, columnPositions.resolvedFinalPosition.next().toInt());
+        } else {
</ins><span class="cx">             // Grow the grid for items with a definite column span, getting the largest such span.
</span><span class="cx">             GridSpan positions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), *child, ForColumns, GridResolvedPosition(0));
</span><span class="cx">             maximumColumnIndex = std::max(maximumColumnIndex, positions.resolvedFinalPosition.next().toInt());
</span><span class="lines">@@ -1050,14 +1054,16 @@
</span><span class="cx">     HashMap&lt;unsigned, unsigned, DefaultHash&lt;unsigned&gt;::Hash, WTF::UnsignedWithZeroKeyHashTraits&lt;unsigned&gt;&gt; minorAxisCursors;
</span><span class="cx"> 
</span><span class="cx">     for (auto&amp; autoGridItem : autoGridItems) {
</span><del>-        std::unique_ptr&lt;GridSpan&gt; majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *autoGridItem, autoPlacementMajorAxisDirection());
</del><ins>+        auto unresolvedMajorAxisPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), *autoGridItem, autoPlacementMajorAxisDirection());
+        ASSERT(!unresolvedMajorAxisPositions.requiresAutoPlacement());
+        GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedMajorAxisPositions, style());
</ins><span class="cx">         GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), *autoGridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
</span><del>-        unsigned majorAxisInitialPosition = majorAxisPositions-&gt;resolvedInitialPosition.toInt();
</del><ins>+        unsigned majorAxisInitialPosition = majorAxisPositions.resolvedInitialPosition.toInt();
</ins><span class="cx"> 
</span><del>-        GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions-&gt;resolvedInitialPosition.toInt(), isGridAutoFlowDense ? 0 : minorAxisCursors.get(majorAxisInitialPosition));
-        std::unique_ptr&lt;GridCoordinate&gt; emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions-&gt;integerSpan(), minorAxisPositions.integerSpan());
</del><ins>+        GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions.resolvedInitialPosition.toInt(), isGridAutoFlowDense ? 0 : minorAxisCursors.get(majorAxisInitialPosition));
+        std::unique_ptr&lt;GridCoordinate&gt; emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions.integerSpan(), minorAxisPositions.integerSpan());
</ins><span class="cx">         if (!emptyGridArea)
</span><del>-            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(*autoGridItem, autoPlacementMajorAxisDirection(), *majorAxisPositions);
</del><ins>+            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(*autoGridItem, autoPlacementMajorAxisDirection(), majorAxisPositions);
</ins><span class="cx">         insertItemIntoGrid(*autoGridItem, *emptyGridArea);
</span><span class="cx"> 
</span><span class="cx">         if (!isGridAutoFlowDense)
</span><span class="lines">@@ -1082,8 +1088,7 @@
</span><span class="cx"> 
</span><span class="cx"> void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox&amp; gridItem, AutoPlacementCursor&amp; autoPlacementCursor)
</span><span class="cx"> {
</span><del>-    std::unique_ptr&lt;GridSpan&gt; minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), gridItem, autoPlacementMinorAxisDirection());
-    ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(style(), gridItem, autoPlacementMajorAxisDirection()));
</del><ins>+    ASSERT(GridResolvedPosition::unresolvedSpanFromStyle(style(), gridItem, autoPlacementMajorAxisDirection()).requiresAutoPlacement());
</ins><span class="cx">     GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), gridItem, autoPlacementMajorAxisDirection(), GridResolvedPosition(0));
</span><span class="cx"> 
</span><span class="cx">     const unsigned endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForColumns) ? gridColumnCount() : gridRowCount();
</span><span class="lines">@@ -1091,18 +1096,21 @@
</span><span class="cx">     unsigned minorAxisAutoPlacementCursor = autoPlacementMajorAxisDirection() == ForColumns ? autoPlacementCursor.first : autoPlacementCursor.second;
</span><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;GridCoordinate&gt; emptyGridArea;
</span><del>-    if (minorAxisPositions) {
</del><ins>+    auto unresolvedMinorAxisPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), gridItem, autoPlacementMinorAxisDirection());
+    if (!unresolvedMinorAxisPositions.requiresAutoPlacement()) {
+        GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedMinorAxisPositions, style());
+
</ins><span class="cx">         // Move to the next track in major axis if initial position in minor axis is before auto-placement cursor.
</span><del>-        if (minorAxisPositions-&gt;resolvedInitialPosition.toInt() &lt; minorAxisAutoPlacementCursor)
</del><ins>+        if (minorAxisPositions.resolvedInitialPosition.toInt() &lt; minorAxisAutoPlacementCursor)
</ins><span class="cx">             majorAxisAutoPlacementCursor++;
</span><span class="cx"> 
</span><span class="cx">         if (majorAxisAutoPlacementCursor &lt; endOfMajorAxis) {
</span><del>-            GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisPositions-&gt;resolvedInitialPosition.toInt(), majorAxisAutoPlacementCursor);
-            emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions-&gt;integerSpan(), majorAxisPositions.integerSpan());
</del><ins>+            GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisPositions.resolvedInitialPosition.toInt(), majorAxisAutoPlacementCursor);
+            emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions.integerSpan(), majorAxisPositions.integerSpan());
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (!emptyGridArea)
</span><del>-            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), *minorAxisPositions);
</del><ins>+            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), minorAxisPositions);
</ins><span class="cx">     } else {
</span><span class="cx">         GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), gridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleGridPositionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/GridPosition.h (185058 => 185059)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/GridPosition.h        2015-06-01 15:28:49 UTC (rev 185058)
+++ trunk/Source/WebCore/rendering/style/GridPosition.h        2015-06-01 15:40:43 UTC (rev 185059)
</span><span class="lines">@@ -45,6 +45,13 @@
</span><span class="cx">     NamedGridAreaPosition // &lt;ident&gt;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+enum GridPositionSide {
+    ColumnStartSide,
+    ColumnEndSide,
+    RowStartSide,
+    RowEndSide
+};
+
</ins><span class="cx"> class GridPosition {
</span><span class="cx"> public:
</span><span class="cx">     GridPosition()
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleGridResolvedPositioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/GridResolvedPosition.cpp (185058 => 185059)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/GridResolvedPosition.cpp        2015-06-01 15:28:49 UTC (rev 185058)
+++ trunk/Source/WebCore/rendering/style/GridResolvedPosition.cpp        2015-06-01 15:40:43 UTC (rev 185059)
</span><span class="lines">@@ -48,49 +48,12 @@
</span><span class="cx">     return side == ColumnStartSide || side == RowStartSide;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-unsigned GridResolvedPosition::explicitGridColumnCount(const RenderStyle&amp; gridContainerStyle)
</del><ins>+static const NamedGridLinesMap&amp; gridLinesForSide(const RenderStyle&amp; style, GridPositionSide side)
</ins><span class="cx"> {
</span><del>-    return std::min&lt;unsigned&gt;(gridContainerStyle.gridColumns().size(), kGridMaxTracks);
-}
-
-unsigned GridResolvedPosition::explicitGridRowCount(const RenderStyle&amp; gridContainerStyle)
-{
-    return std::min&lt;unsigned&gt;(gridContainerStyle.gridRows().size(), kGridMaxTracks);
-}
-
-static unsigned explicitGridSizeForSide(const RenderStyle&amp; gridContainerStyle, GridPositionSide side)
-{
-    return isColumnSide(side) ? GridResolvedPosition::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyle);
-}
-
-GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(const RenderStyle&amp; gridContainerStyle, const RenderBox&amp; gridItem, GridTrackSizingDirection direction, const GridResolvedPosition&amp; resolvedInitialPosition)
-{
-    GridPosition initialPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnStart() : gridItem.style().gridItemRowStart();
-    const GridPositionSide initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide;
-    GridPosition finalPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnEnd() : gridItem.style().gridItemRowEnd();
-    const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide;
-
-    adjustGridPositionsFromStyle(gridContainerStyle, initialPosition, finalPosition, initialPositionSide, finalPositionSide);
-
-    // This method will only be used when both positions need to be resolved against the opposite one.
-    ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() &amp;&amp; finalPosition.shouldBeResolvedAgainstOppositePosition());
-
-    GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition;
-
-    if (initialPosition.isSpan())
-        return *resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, initialPosition, finalPositionSide);
-    else if (finalPosition.isSpan())
-        return *resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, finalPosition, finalPositionSide);
-
-    return GridSpan(resolvedInitialPosition, resolvedFinalPosition);
-}
-
-static inline const NamedGridLinesMap&amp; gridLinesForSide(const RenderStyle&amp; style, GridPositionSide side)
-{
</del><span class="cx">     return isColumnSide(side) ? style.namedGridColumnLines() : style.namedGridRowLines();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline const String implicitNamedGridLineForSide(const String&amp; lineName, GridPositionSide side)
</del><ins>+static const String implicitNamedGridLineForSide(const String&amp; lineName, GridPositionSide side)
</ins><span class="cx"> {
</span><span class="cx">     return lineName + (isStartSide(side) ? &quot;-start&quot; : &quot;-end&quot;);
</span><span class="cx"> }
</span><span class="lines">@@ -101,67 +64,66 @@
</span><span class="cx">     return !gridLineNames.contains(implicitNamedGridLineForSide(lineName, side)) &amp;&amp; !gridLineNames.contains(lineName);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void GridResolvedPosition::adjustGridPositionsFromStyle(const RenderStyle&amp; gridContainerStyle, GridPosition&amp; initialPosition, GridPosition&amp; finalPosition, GridPositionSide initialPositionSide, GridPositionSide finalPositionSide)
</del><ins>+bool GridUnresolvedSpan::requiresAutoPlacement() const
</ins><span class="cx"> {
</span><del>-    ASSERT(isColumnSide(initialPositionSide) == isColumnSide(finalPositionSide));
</del><ins>+    return m_initialPosition.shouldBeResolvedAgainstOppositePosition() &amp;&amp; m_finalPosition.shouldBeResolvedAgainstOppositePosition();
+}
</ins><span class="cx"> 
</span><ins>+void GridUnresolvedSpan::adjustGridPositionsFromStyle(const RenderStyle&amp; gridContainerStyle)
+{
+    ASSERT(isColumnSide(m_initialPositionSide) == isColumnSide(m_finalPositionSide));
+
</ins><span class="cx">     // We must handle the placement error handling code here instead of in the StyleAdjuster because we don't want to
</span><span class="cx">     // overwrite the specified values.
</span><del>-    if (initialPosition.isSpan() &amp;&amp; finalPosition.isSpan())
-        finalPosition.setAutoPosition();
</del><ins>+    if (m_initialPosition.isSpan() &amp;&amp; m_finalPosition.isSpan())
+        m_finalPosition.setAutoPosition();
</ins><span class="cx"> 
</span><span class="cx">     // Try to early detect the case of non existing named grid lines. This way we could assume later that
</span><span class="cx">     // GridResolvedPosition::resolveGrisPositionFromStyle() won't require the autoplacement to run, i.e., it'll always return a
</span><span class="cx">     // valid resolved position.
</span><del>-    if (initialPosition.isNamedGridArea() &amp;&amp; isNonExistentNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide))
-        initialPosition.setAutoPosition();
</del><ins>+    if (m_initialPosition.isNamedGridArea() &amp;&amp; isNonExistentNamedLineOrArea(m_initialPosition.namedGridLine(), gridContainerStyle, m_initialPositionSide))
+        m_initialPosition.setAutoPosition();
</ins><span class="cx"> 
</span><del>-    if (finalPosition.isNamedGridArea() &amp;&amp; isNonExistentNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide))
-        finalPosition.setAutoPosition();
</del><ins>+    if (m_finalPosition.isNamedGridArea() &amp;&amp; isNonExistentNamedLineOrArea(m_finalPosition.namedGridLine(), gridContainerStyle, m_finalPositionSide))
+        m_finalPosition.setAutoPosition();
</ins><span class="cx"> 
</span><span class="cx">     // If the grid item has an automatic position and a grid span for a named line in a given dimension, instead treat the grid span as one.
</span><del>-    if (initialPosition.isAuto() &amp;&amp; finalPosition.isSpan() &amp;&amp; !finalPosition.namedGridLine().isNull())
-        finalPosition.setSpanPosition(1, String());
-    if (finalPosition.isAuto() &amp;&amp; initialPosition.isSpan() &amp;&amp; !initialPosition.namedGridLine().isNull())
-        initialPosition.setSpanPosition(1, String());
</del><ins>+    if (m_initialPosition.isAuto() &amp;&amp; m_finalPosition.isSpan() &amp;&amp; !m_finalPosition.namedGridLine().isNull())
+        m_finalPosition.setSpanPosition(1, String());
+    if (m_finalPosition.isAuto() &amp;&amp; m_initialPosition.isSpan() &amp;&amp; !m_initialPosition.namedGridLine().isNull())
+        m_initialPosition.setSpanPosition(1, String());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::unique_ptr&lt;GridSpan&gt; GridResolvedPosition::resolveGridPositionsFromStyle(const RenderStyle&amp; gridContainerStyle, const RenderBox&amp; gridItem, GridTrackSizingDirection direction)
</del><ins>+unsigned GridResolvedPosition::explicitGridColumnCount(const RenderStyle&amp; gridContainerStyle)
</ins><span class="cx"> {
</span><del>-    GridPosition initialPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnStart() : gridItem.style().gridItemRowStart();
-    const GridPositionSide initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide;
-    GridPosition finalPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnEnd() : gridItem.style().gridItemRowEnd();
-    const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide;
</del><ins>+    return std::min&lt;unsigned&gt;(gridContainerStyle.gridColumns().size(), kGridMaxTracks);
+}
</ins><span class="cx"> 
</span><del>-    adjustGridPositionsFromStyle(gridContainerStyle, initialPosition, finalPosition, initialPositionSide, finalPositionSide);
</del><ins>+unsigned GridResolvedPosition::explicitGridRowCount(const RenderStyle&amp; gridContainerStyle)
+{
+    return std::min&lt;unsigned&gt;(gridContainerStyle.gridRows().size(), kGridMaxTracks);
+}
</ins><span class="cx"> 
</span><del>-    // We can't get our grid positions without running the auto placement algorithm.
-    if (initialPosition.shouldBeResolvedAgainstOppositePosition() &amp;&amp; finalPosition.shouldBeResolvedAgainstOppositePosition())
-        return nullptr;
</del><ins>+static unsigned explicitGridSizeForSide(const RenderStyle&amp; gridContainerStyle, GridPositionSide side)
+{
+    return isColumnSide(side) ? GridResolvedPosition::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyle);
+}
</ins><span class="cx"> 
</span><del>-    if (initialPosition.shouldBeResolvedAgainstOppositePosition()) {
-        // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case).
-        const GridResolvedPosition finalResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalPositionSide);
-        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, finalResolvedPosition, initialPosition, initialPositionSide);
-    }
</del><ins>+static GridResolvedPosition adjustGridPositionForRowEndColumnEndSide(unsigned resolvedPosition)
+{
+    return resolvedPosition ? GridResolvedPosition(resolvedPosition - 1) : GridResolvedPosition(0);
+}
</ins><span class="cx"> 
</span><del>-    if (finalPosition.shouldBeResolvedAgainstOppositePosition()) {
-        // Infer our position from the initial position ('1 / auto' or '3 / span 2' case).
-        const GridResolvedPosition initialResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialPositionSide);
-        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, initialResolvedPosition, finalPosition, finalPositionSide);
-    }
</del><ins>+static GridResolvedPosition adjustGridPositionForSide(unsigned resolvedPosition, GridPositionSide side)
+{
+    // An item finishing on the N-th line belongs to the N-1-th cell.
+    if (side == ColumnEndSide || side == RowEndSide)
+        return adjustGridPositionForRowEndColumnEndSide(resolvedPosition);
</ins><span class="cx"> 
</span><del>-    GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialPositionSide);
-    GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalPositionSide);
-
-    // If 'grid-row-end' specifies a line at or before that specified by 'grid-row-start', it computes to 'span 1'.
-    if (resolvedFinalPosition &lt; resolvedInitialPosition)
-        resolvedFinalPosition = resolvedInitialPosition;
-
-    return std::make_unique&lt;GridSpan&gt;(resolvedInitialPosition, resolvedFinalPosition);
</del><ins>+    return GridResolvedPosition(resolvedPosition);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-GridResolvedPosition GridResolvedPosition::resolveNamedGridLinePositionFromStyle(const RenderStyle&amp; gridContainerStyle, const GridPosition&amp; position, GridPositionSide side)
</del><ins>+static GridResolvedPosition resolveNamedGridLinePositionFromStyle(const RenderStyle&amp; gridContainerStyle, const GridPosition&amp; position, GridPositionSide side)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!position.namedGridLine().isNull());
</span><span class="cx"> 
</span><span class="lines">@@ -171,7 +133,7 @@
</span><span class="cx">         if (position.isPositive())
</span><span class="cx">             return 0;
</span><span class="cx">         const unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side);
</span><del>-        return GridResolvedPosition::adjustGridPositionForSide(lastLine, side);
</del><ins>+        return adjustGridPositionForSide(lastLine, side);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     unsigned namedGridLineIndex;
</span><span class="lines">@@ -179,11 +141,111 @@
</span><span class="cx">         namedGridLineIndex = std::min&lt;unsigned&gt;(position.integerPosition(), it-&gt;value.size()) - 1;
</span><span class="cx">     else
</span><span class="cx">         namedGridLineIndex = std::max&lt;int&gt;(0, it-&gt;value.size() - abs(position.integerPosition()));
</span><del>-    return GridResolvedPosition::adjustGridPositionForSide(it-&gt;value[namedGridLineIndex], side);
</del><ins>+    return adjustGridPositionForSide(it-&gt;value[namedGridLineIndex], side);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const RenderStyle&amp; gridContainerStyle, const GridPosition&amp; position, GridPositionSide side)
</del><ins>+static inline unsigned firstNamedGridLineBeforePosition(unsigned position, const Vector&lt;unsigned&gt;&amp; gridLines)
</ins><span class="cx"> {
</span><ins>+    // The grid line inequality needs to be strict (which doesn't match the after / end case) because |position| is
+    // already converted to an index in our grid representation (ie one was removed from the grid line to account for
+    // the side).
+    unsigned firstLineBeforePositionIndex = 0;
+    auto firstLineBeforePosition = std::lower_bound(gridLines.begin(), gridLines.end(), position);
+    if (firstLineBeforePosition != gridLines.end()) {
+        if (*firstLineBeforePosition &gt; position &amp;&amp; firstLineBeforePosition != gridLines.begin())
+            --firstLineBeforePosition;
+
+        firstLineBeforePositionIndex = firstLineBeforePosition - gridLines.begin();
+    }
+    return firstLineBeforePositionIndex;
+}
+
+static GridSpan resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition&amp; resolvedOppositePosition, const GridPosition&amp; position, const Vector&lt;unsigned&gt;&amp; gridLines)
+{
+    unsigned gridLineIndex = std::max&lt;int&gt;(0, firstNamedGridLineBeforePosition(resolvedOppositePosition.toInt(), gridLines) - position.spanPosition() + 1);
+    GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition(gridLines[gridLineIndex]);
+    return GridSpan(std::min&lt;GridResolvedPosition&gt;(resolvedGridLinePosition, resolvedOppositePosition), resolvedOppositePosition);
+}
+
+static GridSpan resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition&amp; resolvedOppositePosition, const GridPosition&amp; position, const Vector&lt;unsigned&gt;&amp; gridLines)
+{
+    ASSERT(gridLines.size());
+    unsigned firstLineAfterOppositePositionIndex = gridLines.size() - 1;
+    const unsigned* firstLineAfterOppositePosition = std::upper_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition);
+    if (firstLineAfterOppositePosition != gridLines.end())
+        firstLineAfterOppositePositionIndex = firstLineAfterOppositePosition - gridLines.begin();
+
+    unsigned gridLineIndex = std::min&lt;unsigned&gt;(gridLines.size() - 1, firstLineAfterOppositePositionIndex + position.spanPosition() - 1);
+    GridResolvedPosition resolvedGridLinePosition = adjustGridPositionForRowEndColumnEndSide(gridLines[gridLineIndex]);
+    if (resolvedGridLinePosition &lt; resolvedOppositePosition)
+        resolvedGridLinePosition = resolvedOppositePosition;
+    return GridSpan(resolvedOppositePosition, resolvedGridLinePosition);
+}
+
+static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle&amp; gridContainerStyle, const GridResolvedPosition&amp; resolvedOppositePosition, const GridPosition&amp; position, GridPositionSide side)
+{
+    ASSERT(position.isSpan());
+    ASSERT(!position.namedGridLine().isNull());
+    // Negative positions are not allowed per the specification and should have been handled during parsing.
+    ASSERT(position.spanPosition() &gt; 0);
+
+    const NamedGridLinesMap&amp; gridLinesNames = isColumnSide(side) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines();
+    NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
+
+    // If there is no named grid line of that name, we resolve the position to 'auto' (which is equivalent to 'span 1' in this case).
+    // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html.
+    if (it == gridLinesNames.end())
+        return GridSpan(resolvedOppositePosition, resolvedOppositePosition);
+
+    if (side == RowStartSide || side == ColumnStartSide)
+        return resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it-&gt;value);
+
+    return resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it-&gt;value);
+}
+
+static GridSpan resolveGridPositionAgainstOppositePosition(const RenderStyle&amp; gridContainerStyle, const GridResolvedPosition&amp; resolvedOppositePosition, const GridPosition&amp; position, GridPositionSide side)
+{
+    if (position.isAuto())
+        return GridSpan(resolvedOppositePosition, resolvedOppositePosition);
+
+    ASSERT(position.isSpan());
+    ASSERT(position.spanPosition() &gt; 0);
+
+    if (!position.namedGridLine().isNull()) {
+        // span 2 'c' -&gt; we need to find the appropriate grid line before / after our opposite position.
+        return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, resolvedOppositePosition, position, side);
+    }
+
+    // 'span 1' is contained inside a single grid track regardless of the direction.
+    // That's why the CSS span value is one more than the offset we apply.
+    unsigned positionOffset = position.spanPosition() - 1;
+    if (isStartSide(side)) {
+        unsigned initialResolvedPosition = std::max&lt;int&gt;(0, resolvedOppositePosition.toInt() - positionOffset);
+        return GridSpan(initialResolvedPosition, resolvedOppositePosition);
+    }
+
+    return GridSpan(resolvedOppositePosition, resolvedOppositePosition.toInt() + positionOffset);
+}
+
+GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(const RenderStyle&amp; gridContainerStyle, const RenderBox&amp; gridItem, GridTrackSizingDirection direction, const GridResolvedPosition&amp; resolvedInitialPosition)
+{
+    GridUnresolvedSpan unresolvedSpan = unresolvedSpanFromStyle(gridContainerStyle, gridItem, direction);
+
+    // This method will only be used when both positions need to be resolved against the opposite one.
+    ASSERT(unresolvedSpan.requiresAutoPlacement());
+
+    GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition;
+
+    if (unresolvedSpan.initialPosition().isSpan())
+        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, unresolvedSpan.initialPosition(), unresolvedSpan.finalPositionSide());
+    if (unresolvedSpan.finalPosition().isSpan())
+        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide());
+
+    return GridSpan(resolvedInitialPosition, resolvedFinalPosition);
+}
+
+static GridResolvedPosition resolveGridPositionFromStyle(const RenderStyle&amp; gridContainerStyle, const GridPosition&amp; position, GridPositionSide side)
+{
</ins><span class="cx">     switch (position.type()) {
</span><span class="cx">     case ExplicitPosition: {
</span><span class="cx">         ASSERT(position.integerPosition());
</span><span class="lines">@@ -193,7 +255,7 @@
</span><span class="cx"> 
</span><span class="cx">         // Handle &lt;integer&gt; explicit position.
</span><span class="cx">         if (position.isPositive())
</span><del>-            return GridResolvedPosition::adjustGridPositionForSide(position.integerPosition() - 1, side);
</del><ins>+            return adjustGridPositionForSide(position.integerPosition() - 1, side);
</ins><span class="cx"> 
</span><span class="cx">         unsigned resolvedPosition = abs(position.integerPosition()) - 1;
</span><span class="cx">         const unsigned endOfTrack = explicitGridSizeForSide(gridContainerStyle, side);
</span><span class="lines">@@ -202,7 +264,7 @@
</span><span class="cx">         if (endOfTrack &lt; resolvedPosition)
</span><span class="cx">             return 0;
</span><span class="cx"> 
</span><del>-        return GridResolvedPosition::adjustGridPositionForSide(endOfTrack - resolvedPosition, side);
</del><ins>+        return adjustGridPositionForSide(endOfTrack - resolvedPosition, side);
</ins><span class="cx">     }
</span><span class="cx">     case NamedGridAreaPosition:
</span><span class="cx">     {
</span><span class="lines">@@ -215,13 +277,13 @@
</span><span class="cx">         const NamedGridLinesMap&amp; gridLineNames = gridLinesForSide(gridContainerStyle, side);
</span><span class="cx">         auto implicitLine = gridLineNames.find(implicitNamedGridLineForSide(namedGridLine, side));
</span><span class="cx">         if (implicitLine != gridLineNames.end())
</span><del>-            return GridResolvedPosition::adjustGridPositionForSide(implicitLine-&gt;value[0], side);
</del><ins>+            return adjustGridPositionForSide(implicitLine-&gt;value[0], side);
</ins><span class="cx"> 
</span><span class="cx">         // Otherwise, if there is a named line with the specified name, contributes the first such line to the grid
</span><span class="cx">         // item's placement.
</span><span class="cx">         auto explicitLine = gridLineNames.find(namedGridLine);
</span><span class="cx">         if (explicitLine != gridLineNames.end())
</span><del>-            return GridResolvedPosition::adjustGridPositionForSide(explicitLine-&gt;value[0], side);
</del><ins>+            return adjustGridPositionForSide(explicitLine-&gt;value[0], side);
</ins><span class="cx"> 
</span><span class="cx">         // If none of the above works specs mandate us to treat it as auto BUT we should have detected it before calling
</span><span class="cx">         // this function in resolveGridPositionsFromStyle(). We should be covered anyway by the ASSERT at the beginning
</span><span class="lines">@@ -239,89 +301,48 @@
</span><span class="cx">     return GridResolvedPosition(0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::unique_ptr&lt;GridSpan&gt; GridResolvedPosition::resolveGridPositionAgainstOppositePosition(const RenderStyle&amp; gridContainerStyle, const GridResolvedPosition&amp; resolvedOppositePosition, const GridPosition&amp; position, GridPositionSide side)
</del><ins>+GridResolvedPosition::GridResolvedPosition(const GridPosition&amp; position, GridPositionSide side)
</ins><span class="cx"> {
</span><del>-    if (position.isAuto())
-        return std::make_unique&lt;GridSpan&gt;(resolvedOppositePosition, resolvedOppositePosition);
</del><ins>+    ASSERT(position.integerPosition());
+    unsigned integerPosition = position.integerPosition() - 1;
</ins><span class="cx"> 
</span><del>-    ASSERT(position.isSpan());
-    ASSERT(position.spanPosition() &gt; 0);
-
-    if (!position.namedGridLine().isNull()) {
-        // span 2 'c' -&gt; we need to find the appropriate grid line before / after our opposite position.
-        return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, resolvedOppositePosition, position, side);
-    }
-
-    // 'span 1' is contained inside a single grid track regardless of the direction.
-    // That's why the CSS span value is one more than the offset we apply.
-    unsigned positionOffset = position.spanPosition() - 1;
-    if (isStartSide(side)) {
-        unsigned initialResolvedPosition = std::max&lt;int&gt;(0, resolvedOppositePosition.toInt() - positionOffset);
-        return std::make_unique&lt;GridSpan&gt;(initialResolvedPosition, resolvedOppositePosition);
-    }
-
-    return std::make_unique&lt;GridSpan&gt;(resolvedOppositePosition, resolvedOppositePosition.toInt() + positionOffset);
</del><ins>+    m_integerPosition = adjustGridPositionForSide(integerPosition, side).m_integerPosition;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::unique_ptr&lt;GridSpan&gt; GridResolvedPosition::resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle&amp; gridContainerStyle, const GridResolvedPosition&amp; resolvedOppositePosition, const GridPosition&amp; position, GridPositionSide side)
</del><ins>+GridUnresolvedSpan GridResolvedPosition::unresolvedSpanFromStyle(const RenderStyle&amp; gridContainerStyle, const RenderBox&amp; gridItem, GridTrackSizingDirection direction)
</ins><span class="cx"> {
</span><del>-    ASSERT(position.isSpan());
-    ASSERT(!position.namedGridLine().isNull());
-    // Negative positions are not allowed per the specification and should have been handled during parsing.
-    ASSERT(position.spanPosition() &gt; 0);
</del><ins>+    GridPosition initialPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnStart() : gridItem.style().gridItemRowStart();
+    auto initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide;
+    GridPosition finalPosition = (direction == ForColumns) ? gridItem.style().gridItemColumnEnd() : gridItem.style().gridItemRowEnd();
+    auto finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide;
</ins><span class="cx"> 
</span><del>-    const NamedGridLinesMap&amp; gridLinesNames = isColumnSide(side) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines();
-    NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
</del><ins>+    GridUnresolvedSpan unresolvedSpan(initialPosition, initialPositionSide, finalPosition, finalPositionSide);
+    unresolvedSpan.adjustGridPositionsFromStyle(gridContainerStyle);
</ins><span class="cx"> 
</span><del>-    // If there is no named grid line of that name, we resolve the position to 'auto' (which is equivalent to 'span 1' in this case).
-    // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html.
-    if (it == gridLinesNames.end())
-        return std::make_unique&lt;GridSpan&gt;(resolvedOppositePosition, resolvedOppositePosition);
-
-    if (side == RowStartSide || side == ColumnStartSide)
-        return resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it-&gt;value);
-
-    return resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it-&gt;value);
</del><ins>+    return unresolvedSpan;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline unsigned firstNamedGridLineBeforePosition(unsigned position, const Vector&lt;unsigned&gt;&amp; gridLines)
</del><ins>+GridSpan GridResolvedPosition::resolveGridPositionsFromStyle(const GridUnresolvedSpan&amp; unresolvedSpan, const RenderStyle&amp; gridContainerStyle)
</ins><span class="cx"> {
</span><del>-    // The grid line inequality needs to be strict (which doesn't match the after / end case) because |position| is
-    // already converted to an index in our grid representation (ie one was removed from the grid line to account for
-    // the side).
-    unsigned firstLineBeforePositionIndex = 0;
-    const unsigned* firstLineBeforePosition = std::lower_bound(gridLines.begin(), gridLines.end(), position);
-    if (firstLineBeforePosition != gridLines.end()) {
-        if (*firstLineBeforePosition &gt; position &amp;&amp; firstLineBeforePosition != gridLines.begin())
-            --firstLineBeforePosition;
</del><ins>+    ASSERT(!unresolvedSpan.requiresAutoPlacement());
</ins><span class="cx"> 
</span><del>-        firstLineBeforePositionIndex = firstLineBeforePosition - gridLines.begin();
</del><ins>+    if (unresolvedSpan.initialPosition().shouldBeResolvedAgainstOppositePosition()) {
+        // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case).
+        auto finalResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide());
+        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, finalResolvedPosition, unresolvedSpan.initialPosition(), unresolvedSpan.initialPositionSide());
</ins><span class="cx">     }
</span><del>-    return firstLineBeforePositionIndex;
-}
</del><span class="cx"> 
</span><del>-std::unique_ptr&lt;GridSpan&gt; GridResolvedPosition::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition&amp; resolvedOppositePosition, const GridPosition&amp; position, const Vector&lt;unsigned&gt;&amp; gridLines)
-{
-    unsigned gridLineIndex = std::max&lt;int&gt;(0, firstNamedGridLineBeforePosition(resolvedOppositePosition.toInt(), gridLines) - position.spanPosition() + 1);
-    GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition(gridLines[gridLineIndex]);
-    if (resolvedGridLinePosition &gt; resolvedOppositePosition)
-        resolvedGridLinePosition = resolvedOppositePosition;
-    return std::make_unique&lt;GridSpan&gt;(resolvedGridLinePosition, resolvedOppositePosition);
-}
</del><ins>+    if (unresolvedSpan.finalPosition().shouldBeResolvedAgainstOppositePosition()) {
+        // Infer our position from the initial position ('1 / auto' or '3 / span 2' case).
+        auto initialResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, unresolvedSpan.initialPosition(), unresolvedSpan.initialPositionSide());
+        return resolveGridPositionAgainstOppositePosition(gridContainerStyle, initialResolvedPosition, unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide());
+    }
</ins><span class="cx"> 
</span><del>-std::unique_ptr&lt;GridSpan&gt; GridResolvedPosition::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition&amp; resolvedOppositePosition, const GridPosition&amp; position, const Vector&lt;unsigned&gt;&amp; gridLines)
-{
-    ASSERT(gridLines.size());
-    unsigned firstLineAfterOppositePositionIndex = gridLines.size() - 1;
-    const unsigned* firstLineAfterOppositePosition = std::upper_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition);
-    if (firstLineAfterOppositePosition != gridLines.end())
-        firstLineAfterOppositePositionIndex = firstLineAfterOppositePosition - gridLines.begin();
</del><ins>+    GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerStyle, unresolvedSpan.initialPosition(), unresolvedSpan.initialPositionSide());
+    GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle, unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide());
</ins><span class="cx"> 
</span><del>-    unsigned gridLineIndex = std::min&lt;unsigned&gt;(gridLines.size() - 1, firstLineAfterOppositePositionIndex + position.spanPosition() - 1);
-    GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition::adjustGridPositionForRowEndColumnEndSide(gridLines[gridLineIndex]);
-    if (resolvedGridLinePosition &lt; resolvedOppositePosition)
-        resolvedGridLinePosition = resolvedOppositePosition;
-    return std::make_unique&lt;GridSpan&gt;(resolvedOppositePosition, resolvedGridLinePosition);
</del><ins>+    // If 'grid-row-end' specifies a line at or before that specified by 'grid-row-start', it computes to 'span 1'.
+    return GridSpan(resolvedInitialPosition, std::max&lt;GridResolvedPosition&gt;(resolvedInitialPosition, resolvedFinalPosition));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleGridResolvedPositionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/GridResolvedPosition.h (185058 => 185059)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/GridResolvedPosition.h        2015-06-01 15:28:49 UTC (rev 185058)
+++ trunk/Source/WebCore/rendering/style/GridResolvedPosition.h        2015-06-01 15:40:43 UTC (rev 185059)
</span><span class="lines">@@ -41,60 +41,47 @@
</span><span class="cx"> class RenderBox;
</span><span class="cx"> class RenderStyle;
</span><span class="cx"> 
</span><del>-enum GridPositionSide {
-    ColumnStartSide,
-    ColumnEndSide,
-    RowStartSide,
-    RowEndSide
-};
-
</del><span class="cx"> enum GridTrackSizingDirection {
</span><span class="cx">     ForColumns,
</span><span class="cx">     ForRows
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-// This class represents an index into one of the dimensions of the grid array.
-// Wraps an unsigned integer just for the purpose of knowing what we manipulate in the grid code.
-class GridResolvedPosition {
</del><ins>+class GridUnresolvedSpan {
</ins><span class="cx"> public:
</span><del>-    static GridResolvedPosition adjustGridPositionForRowEndColumnEndSide(unsigned resolvedPosition)
</del><ins>+    GridUnresolvedSpan(GridPosition initialPosition, GridPositionSide initialPositionSide, GridPosition finalPosition, GridPositionSide finalPositionSide)
+        : m_initialPosition(initialPosition)
+        , m_finalPosition(finalPosition)
+        , m_initialPositionSide(initialPositionSide)
+        , m_finalPositionSide(finalPositionSide)
</ins><span class="cx">     {
</span><del>-        return resolvedPosition ? GridResolvedPosition(resolvedPosition - 1) : GridResolvedPosition(0);
</del><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static GridResolvedPosition adjustGridPositionForSide(unsigned resolvedPosition, GridPositionSide side)
-    {
-        // An item finishing on the N-th line belongs to the N-1-th cell.
-        if (side == ColumnEndSide || side == RowEndSide)
-            return adjustGridPositionForRowEndColumnEndSide(resolvedPosition);
</del><ins>+    const GridPosition&amp; initialPosition() const { return m_initialPosition; }
+    const GridPosition&amp; finalPosition() const { return m_finalPosition; }
+    GridPositionSide initialPositionSide() const { return m_initialPositionSide; }
+    GridPositionSide finalPositionSide() const { return m_finalPositionSide; }
</ins><span class="cx"> 
</span><del>-        return GridResolvedPosition(resolvedPosition);
-    }
</del><ins>+    bool requiresAutoPlacement() const;
+    void adjustGridPositionsFromStyle(const RenderStyle&amp; gridContainerStyle);
</ins><span class="cx"> 
</span><del>-    static GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderStyle&amp;, const RenderBox&amp;, GridTrackSizingDirection, const GridResolvedPosition&amp;);
-    static void adjustNamedGridItemPosition(const RenderStyle&amp;, GridPosition&amp;, GridPositionSide);
-    static void adjustGridPositionsFromStyle(const RenderStyle&amp;, GridPosition&amp; initialPosition, GridPosition&amp; finalPosition, GridPositionSide initialPositionSide, GridPositionSide finalPositionSide);
-    static std::unique_ptr&lt;GridSpan&gt; resolveGridPositionsFromStyle(const RenderStyle&amp;, const RenderBox&amp;, GridTrackSizingDirection);
-    static GridResolvedPosition resolveNamedGridLinePositionFromStyle(const RenderStyle&amp;, const GridPosition&amp;, GridPositionSide);
-    static GridResolvedPosition resolveGridPositionFromStyle(const RenderStyle&amp;, const GridPosition&amp;, GridPositionSide);
-    static std::unique_ptr&lt;GridSpan&gt; resolveGridPositionAgainstOppositePosition(const RenderStyle&amp;, const GridResolvedPosition&amp;, const GridPosition&amp;, GridPositionSide);
-    static std::unique_ptr&lt;GridSpan&gt; resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle&amp;, const GridResolvedPosition&amp;, const GridPosition&amp;, GridPositionSide);
-    static std::unique_ptr&lt;GridSpan&gt; resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition&amp;, const GridPosition&amp;, const Vector&lt;unsigned&gt;&amp;);
-    static std::unique_ptr&lt;GridSpan&gt; resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition&amp;, const GridPosition&amp;, const Vector&lt;unsigned&gt;&amp;);
</del><ins>+private:
+    GridPosition m_initialPosition;
+    GridPosition m_finalPosition;
+    GridPositionSide m_initialPositionSide;
+    GridPositionSide m_finalPositionSide;
+};
</ins><span class="cx"> 
</span><ins>+// This class represents an index into one of the dimensions of the grid array.
+// Wraps an unsigned integer just for the purpose of knowing what we manipulate in the grid code.
+class GridResolvedPosition {
+public:
</ins><span class="cx">     GridResolvedPosition(unsigned position)
</span><span class="cx">         : m_integerPosition(position)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    GridResolvedPosition(const GridPosition&amp; position, GridPositionSide side)
-    {
-        ASSERT(position.integerPosition());
-        unsigned integerPosition = position.integerPosition() - 1;
</del><ins>+    GridResolvedPosition(const GridPosition&amp;, GridPositionSide);
</ins><span class="cx"> 
</span><del>-        m_integerPosition = adjustGridPositionForSide(integerPosition, side).m_integerPosition;
-    }
-
</del><span class="cx">     GridResolvedPosition&amp; operator*()
</span><span class="cx">     {
</span><span class="cx">         return *this;
</span><span class="lines">@@ -146,11 +133,13 @@
</span><span class="cx">         return GridResolvedPosition(m_integerPosition + 1);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    static GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderStyle&amp;, const RenderBox&amp;, GridTrackSizingDirection, const GridResolvedPosition&amp;);
+    static GridSpan resolveGridPositionsFromStyle(const GridUnresolvedSpan&amp;, const RenderStyle&amp;);
+    static GridUnresolvedSpan unresolvedSpanFromStyle(const RenderStyle&amp;, const RenderBox&amp;, GridTrackSizingDirection);
</ins><span class="cx">     static unsigned explicitGridColumnCount(const RenderStyle&amp;);
</span><span class="cx">     static unsigned explicitGridRowCount(const RenderStyle&amp;);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-
</del><span class="cx">     unsigned m_integerPosition;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>