[CSS Grid Layout] Simplify the interface of GridResolvedPosition
authorsvillar@igalia.com <svillar@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Jun 2015 15:40:43 +0000 (15:40 +0000)
committersvillar@igalia.com <svillar@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Jun 2015 15:40:43 +0000 (15:40 +0000)
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.

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

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderGrid.cpp
Source/WebCore/rendering/style/GridPosition.h
Source/WebCore/rendering/style/GridResolvedPosition.cpp
Source/WebCore/rendering/style/GridResolvedPosition.h

index 9faa043..f663c92 100644 (file)
@@ -1,3 +1,63 @@
+2015-06-01  Sergio Villar Senin  <svillar@igalia.com>
+
+        [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.
+
 2015-06-01  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         Fix the !ENABLE(VIDEO_TRACK) build after r184799
index 1398460..3bd26a5 100644 (file)
@@ -975,17 +975,22 @@ void RenderGrid::placeItemsOnGrid()
     Vector<RenderBox*> autoMajorAxisAutoGridItems;
     Vector<RenderBox*> specifiedMajorAxisAutoGridItems;
     for (RenderBox* child = m_orderIterator.first(); child; child = m_orderIterator.next()) {
-        std::unique_ptr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *child, ForRows);
-        std::unique_ptr<GridSpan> columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *child, ForColumns);
-        if (!rowPositions || !columnPositions) {
-            GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? columnPositions.get() : rowPositions.get();
-            if (!majorAxisPositions)
+        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 && unresolvedColumnPositions.requiresAutoPlacement())
+                || (!majorAxisDirectionIsForColumns && unresolvedRowPositions.requiresAutoPlacement()))
                 autoMajorAxisAutoGridItems.append(child);
             else
                 specifiedMajorAxisAutoGridItems.append(child);
             continue;
         }
-        insertItemIntoGrid(*child, GridCoordinate(*rowPositions, *columnPositions));
+        GridSpan rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedRowPositions, style());
+        GridSpan columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedColumnPositions, style());
+        insertItemIntoGrid(*child, GridCoordinate(rowPositions, columnPositions));
     }
 
     ASSERT(gridRowCount() >= GridResolvedPosition::explicitGridRowCount(style()));
@@ -1004,22 +1009,21 @@ void RenderGrid::populateExplicitGridAndOrderIterator()
     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
         populator.collectChild(*child);
 
-        // This function bypasses the cache (cachedGridCoordinate()) as it is used to build it.
-        std::unique_ptr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *child, ForRows);
-        std::unique_ptr<GridSpan> 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->resolvedFinalPosition.next().toInt());
-        else {
+        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 {
             // Grow the grid for items with a definite row span, getting the largest such span.
             GridSpan positions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), *child, ForRows, GridResolvedPosition(0));
             maximumRowIndex = std::max(maximumRowIndex, positions.resolvedFinalPosition.next().toInt());
         }
 
-        if (columnPositions)
-            maximumColumnIndex = std::max(maximumColumnIndex, columnPositions->resolvedFinalPosition.next().toInt());
-        else {
+        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 {
             // Grow the grid for items with a definite column span, getting the largest such span.
             GridSpan positions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), *child, ForColumns, GridResolvedPosition(0));
             maximumColumnIndex = std::max(maximumColumnIndex, positions.resolvedFinalPosition.next().toInt());
@@ -1050,14 +1054,16 @@ void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& au
     HashMap<unsigned, unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> minorAxisCursors;
 
     for (auto& autoGridItem : autoGridItems) {
-        std::unique_ptr<GridSpan> majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), *autoGridItem, autoPlacementMajorAxisDirection());
+        auto unresolvedMajorAxisPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), *autoGridItem, autoPlacementMajorAxisDirection());
+        ASSERT(!unresolvedMajorAxisPositions.requiresAutoPlacement());
+        GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedMajorAxisPositions, style());
         GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), *autoGridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
-        unsigned majorAxisInitialPosition = majorAxisPositions->resolvedInitialPosition.toInt();
+        unsigned majorAxisInitialPosition = majorAxisPositions.resolvedInitialPosition.toInt();
 
-        GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions->resolvedInitialPosition.toInt(), isGridAutoFlowDense ? 0 : minorAxisCursors.get(majorAxisInitialPosition));
-        std::unique_ptr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions->integerSpan(), minorAxisPositions.integerSpan());
+        GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions.resolvedInitialPosition.toInt(), isGridAutoFlowDense ? 0 : minorAxisCursors.get(majorAxisInitialPosition));
+        std::unique_ptr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions.integerSpan(), minorAxisPositions.integerSpan());
         if (!emptyGridArea)
-            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(*autoGridItem, autoPlacementMajorAxisDirection(), *majorAxisPositions);
+            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(*autoGridItem, autoPlacementMajorAxisDirection(), majorAxisPositions);
         insertItemIntoGrid(*autoGridItem, *emptyGridArea);
 
         if (!isGridAutoFlowDense)
@@ -1082,8 +1088,7 @@ void RenderGrid::placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGri
 
 void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox& gridItem, AutoPlacementCursor& autoPlacementCursor)
 {
-    std::unique_ptr<GridSpan> minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(style(), gridItem, autoPlacementMinorAxisDirection());
-    ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(style(), gridItem, autoPlacementMajorAxisDirection()));
+    ASSERT(GridResolvedPosition::unresolvedSpanFromStyle(style(), gridItem, autoPlacementMajorAxisDirection()).requiresAutoPlacement());
     GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), gridItem, autoPlacementMajorAxisDirection(), GridResolvedPosition(0));
 
     const unsigned endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForColumns) ? gridColumnCount() : gridRowCount();
@@ -1091,18 +1096,21 @@ void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox& gridItem, AutoPlacement
     unsigned minorAxisAutoPlacementCursor = autoPlacementMajorAxisDirection() == ForColumns ? autoPlacementCursor.first : autoPlacementCursor.second;
 
     std::unique_ptr<GridCoordinate> emptyGridArea;
-    if (minorAxisPositions) {
+    auto unresolvedMinorAxisPositions = GridResolvedPosition::unresolvedSpanFromStyle(style(), gridItem, autoPlacementMinorAxisDirection());
+    if (!unresolvedMinorAxisPositions.requiresAutoPlacement()) {
+        GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(unresolvedMinorAxisPositions, style());
+
         // Move to the next track in major axis if initial position in minor axis is before auto-placement cursor.
-        if (minorAxisPositions->resolvedInitialPosition.toInt() < minorAxisAutoPlacementCursor)
+        if (minorAxisPositions.resolvedInitialPosition.toInt() < minorAxisAutoPlacementCursor)
             majorAxisAutoPlacementCursor++;
 
         if (majorAxisAutoPlacementCursor < endOfMajorAxis) {
-            GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisPositions->resolvedInitialPosition.toInt(), majorAxisAutoPlacementCursor);
-            emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions->integerSpan(), majorAxisPositions.integerSpan());
+            GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisPositions.resolvedInitialPosition.toInt(), majorAxisAutoPlacementCursor);
+            emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions.integerSpan(), majorAxisPositions.integerSpan());
         }
 
         if (!emptyGridArea)
-            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), *minorAxisPositions);
+            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), minorAxisPositions);
     } else {
         GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(style(), gridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
 
index 5a0af9e..074ae68 100644 (file)
@@ -45,6 +45,13 @@ enum GridPositionType {
     NamedGridAreaPosition // <ident>
 };
 
+enum GridPositionSide {
+    ColumnStartSide,
+    ColumnEndSide,
+    RowStartSide,
+    RowEndSide
+};
+
 class GridPosition {
 public:
     GridPosition()
index 35f9bfe..22a84b2 100644 (file)
@@ -48,49 +48,12 @@ static inline bool isStartSide(GridPositionSide side)
     return side == ColumnStartSide || side == RowStartSide;
 }
 
-unsigned GridResolvedPosition::explicitGridColumnCount(const RenderStyle& gridContainerStyle)
-{
-    return std::min<unsigned>(gridContainerStyle.gridColumns().size(), kGridMaxTracks);
-}
-
-unsigned GridResolvedPosition::explicitGridRowCount(const RenderStyle& gridContainerStyle)
-{
-    return std::min<unsigned>(gridContainerStyle.gridRows().size(), kGridMaxTracks);
-}
-
-static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side)
-{
-    return isColumnSide(side) ? GridResolvedPosition::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyle);
-}
-
-GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, const GridResolvedPosition& 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() && 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& gridLinesForSide(const RenderStyle& style, GridPositionSide side)
+static const NamedGridLinesMap& gridLinesForSide(const RenderStyle& style, GridPositionSide side)
 {
     return isColumnSide(side) ? style.namedGridColumnLines() : style.namedGridRowLines();
 }
 
-static inline const String implicitNamedGridLineForSide(const String& lineName, GridPositionSide side)
+static const String implicitNamedGridLineForSide(const String& lineName, GridPositionSide side)
 {
     return lineName + (isStartSide(side) ? "-start" : "-end");
 }
@@ -101,67 +64,66 @@ static bool isNonExistentNamedLineOrArea(const String& lineName, const RenderSty
     return !gridLineNames.contains(implicitNamedGridLineForSide(lineName, side)) && !gridLineNames.contains(lineName);
 }
 
-void GridResolvedPosition::adjustGridPositionsFromStyle(const RenderStyle& gridContainerStyle, GridPosition& initialPosition, GridPosition& finalPosition, GridPositionSide initialPositionSide, GridPositionSide finalPositionSide)
+bool GridUnresolvedSpan::requiresAutoPlacement() const
+{
+    return m_initialPosition.shouldBeResolvedAgainstOppositePosition() && m_finalPosition.shouldBeResolvedAgainstOppositePosition();
+}
+
+void GridUnresolvedSpan::adjustGridPositionsFromStyle(const RenderStyle& gridContainerStyle)
 {
-    ASSERT(isColumnSide(initialPositionSide) == isColumnSide(finalPositionSide));
+    ASSERT(isColumnSide(m_initialPositionSide) == isColumnSide(m_finalPositionSide));
 
     // We must handle the placement error handling code here instead of in the StyleAdjuster because we don't want to
     // overwrite the specified values.
-    if (initialPosition.isSpan() && finalPosition.isSpan())
-        finalPosition.setAutoPosition();
+    if (m_initialPosition.isSpan() && m_finalPosition.isSpan())
+        m_finalPosition.setAutoPosition();
 
     // Try to early detect the case of non existing named grid lines. This way we could assume later that
     // GridResolvedPosition::resolveGrisPositionFromStyle() won't require the autoplacement to run, i.e., it'll always return a
     // valid resolved position.
-    if (initialPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide))
-        initialPosition.setAutoPosition();
+    if (m_initialPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(m_initialPosition.namedGridLine(), gridContainerStyle, m_initialPositionSide))
+        m_initialPosition.setAutoPosition();
 
-    if (finalPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide))
-        finalPosition.setAutoPosition();
+    if (m_finalPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(m_finalPosition.namedGridLine(), gridContainerStyle, m_finalPositionSide))
+        m_finalPosition.setAutoPosition();
 
     // 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.
-    if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.namedGridLine().isNull())
-        finalPosition.setSpanPosition(1, String());
-    if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.namedGridLine().isNull())
-        initialPosition.setSpanPosition(1, String());
+    if (m_initialPosition.isAuto() && m_finalPosition.isSpan() && !m_finalPosition.namedGridLine().isNull())
+        m_finalPosition.setSpanPosition(1, String());
+    if (m_finalPosition.isAuto() && m_initialPosition.isSpan() && !m_initialPosition.namedGridLine().isNull())
+        m_initialPosition.setSpanPosition(1, String());
 }
 
-std::unique_ptr<GridSpan> GridResolvedPosition::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction)
+unsigned GridResolvedPosition::explicitGridColumnCount(const RenderStyle& gridContainerStyle)
 {
-    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);
-
-    // We can't get our grid positions without running the auto placement algorithm.
-    if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition())
-        return nullptr;
+    return std::min<unsigned>(gridContainerStyle.gridColumns().size(), kGridMaxTracks);
+}
 
-    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);
-    }
+unsigned GridResolvedPosition::explicitGridRowCount(const RenderStyle& gridContainerStyle)
+{
+    return std::min<unsigned>(gridContainerStyle.gridRows().size(), kGridMaxTracks);
+}
 
-    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);
-    }
+static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side)
+{
+    return isColumnSide(side) ? GridResolvedPosition::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyle);
+}
 
-    GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialPositionSide);
-    GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalPositionSide);
+static GridResolvedPosition adjustGridPositionForRowEndColumnEndSide(unsigned resolvedPosition)
+{
+    return resolvedPosition ? GridResolvedPosition(resolvedPosition - 1) : GridResolvedPosition(0);
+}
 
-    // If 'grid-row-end' specifies a line at or before that specified by 'grid-row-start', it computes to 'span 1'.
-    if (resolvedFinalPosition < resolvedInitialPosition)
-        resolvedFinalPosition = resolvedInitialPosition;
+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);
 
-    return std::make_unique<GridSpan>(resolvedInitialPosition, resolvedFinalPosition);
+    return GridResolvedPosition(resolvedPosition);
 }
 
-GridResolvedPosition GridResolvedPosition::resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
+static GridResolvedPosition resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
 {
     ASSERT(!position.namedGridLine().isNull());
 
@@ -171,7 +133,7 @@ GridResolvedPosition GridResolvedPosition::resolveNamedGridLinePositionFromStyle
         if (position.isPositive())
             return 0;
         const unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side);
-        return GridResolvedPosition::adjustGridPositionForSide(lastLine, side);
+        return adjustGridPositionForSide(lastLine, side);
     }
 
     unsigned namedGridLineIndex;
@@ -179,10 +141,110 @@ GridResolvedPosition GridResolvedPosition::resolveNamedGridLinePositionFromStyle
         namedGridLineIndex = std::min<unsigned>(position.integerPosition(), it->value.size()) - 1;
     else
         namedGridLineIndex = std::max<int>(0, it->value.size() - abs(position.integerPosition()));
-    return GridResolvedPosition::adjustGridPositionForSide(it->value[namedGridLineIndex], side);
+    return adjustGridPositionForSide(it->value[namedGridLineIndex], side);
+}
+
+static inline unsigned firstNamedGridLineBeforePosition(unsigned position, const Vector<unsigned>& gridLines)
+{
+    // 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 > position && firstLineBeforePosition != gridLines.begin())
+            --firstLineBeforePosition;
+
+        firstLineBeforePositionIndex = firstLineBeforePosition - gridLines.begin();
+    }
+    return firstLineBeforePositionIndex;
+}
+
+static GridSpan resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<unsigned>& gridLines)
+{
+    unsigned gridLineIndex = std::max<int>(0, firstNamedGridLineBeforePosition(resolvedOppositePosition.toInt(), gridLines) - position.spanPosition() + 1);
+    GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition(gridLines[gridLineIndex]);
+    return GridSpan(std::min<GridResolvedPosition>(resolvedGridLinePosition, resolvedOppositePosition), resolvedOppositePosition);
+}
+
+static GridSpan resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<unsigned>& 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<unsigned>(gridLines.size() - 1, firstLineAfterOppositePositionIndex + position.spanPosition() - 1);
+    GridResolvedPosition resolvedGridLinePosition = adjustGridPositionForRowEndColumnEndSide(gridLines[gridLineIndex]);
+    if (resolvedGridLinePosition < resolvedOppositePosition)
+        resolvedGridLinePosition = resolvedOppositePosition;
+    return GridSpan(resolvedOppositePosition, resolvedGridLinePosition);
+}
+
+static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& 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() > 0);
+
+    const NamedGridLinesMap& 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->value);
+
+    return resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value);
+}
+
+static GridSpan resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+{
+    if (position.isAuto())
+        return GridSpan(resolvedOppositePosition, resolvedOppositePosition);
+
+    ASSERT(position.isSpan());
+    ASSERT(position.spanPosition() > 0);
+
+    if (!position.namedGridLine().isNull()) {
+        // span 2 'c' -> 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<int>(0, resolvedOppositePosition.toInt() - positionOffset);
+        return GridSpan(initialResolvedPosition, resolvedOppositePosition);
+    }
+
+    return GridSpan(resolvedOppositePosition, resolvedOppositePosition.toInt() + positionOffset);
+}
+
+GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, const GridResolvedPosition& 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);
 }
 
-GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
+static GridResolvedPosition resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
 {
     switch (position.type()) {
     case ExplicitPosition: {
@@ -193,7 +255,7 @@ GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const Re
 
         // Handle <integer> explicit position.
         if (position.isPositive())
-            return GridResolvedPosition::adjustGridPositionForSide(position.integerPosition() - 1, side);
+            return adjustGridPositionForSide(position.integerPosition() - 1, side);
 
         unsigned resolvedPosition = abs(position.integerPosition()) - 1;
         const unsigned endOfTrack = explicitGridSizeForSide(gridContainerStyle, side);
@@ -202,7 +264,7 @@ GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const Re
         if (endOfTrack < resolvedPosition)
             return 0;
 
-        return GridResolvedPosition::adjustGridPositionForSide(endOfTrack - resolvedPosition, side);
+        return adjustGridPositionForSide(endOfTrack - resolvedPosition, side);
     }
     case NamedGridAreaPosition:
     {
@@ -215,13 +277,13 @@ GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const Re
         const NamedGridLinesMap& gridLineNames = gridLinesForSide(gridContainerStyle, side);
         auto implicitLine = gridLineNames.find(implicitNamedGridLineForSide(namedGridLine, side));
         if (implicitLine != gridLineNames.end())
-            return GridResolvedPosition::adjustGridPositionForSide(implicitLine->value[0], side);
+            return adjustGridPositionForSide(implicitLine->value[0], side);
 
         // Otherwise, if there is a named line with the specified name, contributes the first such line to the grid
         // item's placement.
         auto explicitLine = gridLineNames.find(namedGridLine);
         if (explicitLine != gridLineNames.end())
-            return GridResolvedPosition::adjustGridPositionForSide(explicitLine->value[0], side);
+            return adjustGridPositionForSide(explicitLine->value[0], side);
 
         // If none of the above works specs mandate us to treat it as auto BUT we should have detected it before calling
         // this function in resolveGridPositionsFromStyle(). We should be covered anyway by the ASSERT at the beginning
@@ -239,89 +301,48 @@ GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const Re
     return GridResolvedPosition(0);
 }
 
-std::unique_ptr<GridSpan> GridResolvedPosition::resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+GridResolvedPosition::GridResolvedPosition(const GridPosition& position, GridPositionSide side)
 {
-    if (position.isAuto())
-        return std::make_unique<GridSpan>(resolvedOppositePosition, resolvedOppositePosition);
-
-    ASSERT(position.isSpan());
-    ASSERT(position.spanPosition() > 0);
-
-    if (!position.namedGridLine().isNull()) {
-        // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position.
-        return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, resolvedOppositePosition, position, side);
-    }
+    ASSERT(position.integerPosition());
+    unsigned integerPosition = position.integerPosition() - 1;
 
-    // '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<int>(0, resolvedOppositePosition.toInt() - positionOffset);
-        return std::make_unique<GridSpan>(initialResolvedPosition, resolvedOppositePosition);
-    }
-
-    return std::make_unique<GridSpan>(resolvedOppositePosition, resolvedOppositePosition.toInt() + positionOffset);
+    m_integerPosition = adjustGridPositionForSide(integerPosition, side).m_integerPosition;
 }
 
-std::unique_ptr<GridSpan> GridResolvedPosition::resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+GridUnresolvedSpan GridResolvedPosition::unresolvedSpanFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction)
 {
-    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() > 0);
-
-    const NamedGridLinesMap& 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 std::make_unique<GridSpan>(resolvedOppositePosition, resolvedOppositePosition);
+    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;
 
-    if (side == RowStartSide || side == ColumnStartSide)
-        return resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value);
+    GridUnresolvedSpan unresolvedSpan(initialPosition, initialPositionSide, finalPosition, finalPositionSide);
+    unresolvedSpan.adjustGridPositionsFromStyle(gridContainerStyle);
 
-    return resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value);
+    return unresolvedSpan;
 }
 
-static inline unsigned firstNamedGridLineBeforePosition(unsigned position, const Vector<unsigned>& gridLines)
+GridSpan GridResolvedPosition::resolveGridPositionsFromStyle(const GridUnresolvedSpan& unresolvedSpan, const RenderStyle& gridContainerStyle)
 {
-    // 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 > position && firstLineBeforePosition != gridLines.begin())
-            --firstLineBeforePosition;
+    ASSERT(!unresolvedSpan.requiresAutoPlacement());
 
-        firstLineBeforePositionIndex = firstLineBeforePosition - gridLines.begin();
+    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());
     }
-    return firstLineBeforePositionIndex;
-}
 
-std::unique_ptr<GridSpan> GridResolvedPosition::resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<unsigned>& gridLines)
-{
-    unsigned gridLineIndex = std::max<int>(0, firstNamedGridLineBeforePosition(resolvedOppositePosition.toInt(), gridLines) - position.spanPosition() + 1);
-    GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition(gridLines[gridLineIndex]);
-    if (resolvedGridLinePosition > resolvedOppositePosition)
-        resolvedGridLinePosition = resolvedOppositePosition;
-    return std::make_unique<GridSpan>(resolvedGridLinePosition, resolvedOppositePosition);
-}
+    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());
+    }
 
-std::unique_ptr<GridSpan> GridResolvedPosition::resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<unsigned>& 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();
+    GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerStyle, unresolvedSpan.initialPosition(), unresolvedSpan.initialPositionSide());
+    GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle, unresolvedSpan.finalPosition(), unresolvedSpan.finalPositionSide());
 
-    unsigned gridLineIndex = std::min<unsigned>(gridLines.size() - 1, firstLineAfterOppositePositionIndex + position.spanPosition() - 1);
-    GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition::adjustGridPositionForRowEndColumnEndSide(gridLines[gridLineIndex]);
-    if (resolvedGridLinePosition < resolvedOppositePosition)
-        resolvedGridLinePosition = resolvedOppositePosition;
-    return std::make_unique<GridSpan>(resolvedOppositePosition, resolvedGridLinePosition);
+    // 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<GridResolvedPosition>(resolvedInitialPosition, resolvedFinalPosition));
 }
 
 } // namespace WebCore
index 95556cd..9752b36 100644 (file)
@@ -41,59 +41,46 @@ class GridSpan;
 class RenderBox;
 class RenderStyle;
 
-enum GridPositionSide {
-    ColumnStartSide,
-    ColumnEndSide,
-    RowStartSide,
-    RowEndSide
-};
-
 enum GridTrackSizingDirection {
     ForColumns,
     ForRows
 };
 
-// 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 {
+class GridUnresolvedSpan {
 public:
-    static GridResolvedPosition adjustGridPositionForRowEndColumnEndSide(unsigned resolvedPosition)
+    GridUnresolvedSpan(GridPosition initialPosition, GridPositionSide initialPositionSide, GridPosition finalPosition, GridPositionSide finalPositionSide)
+        : m_initialPosition(initialPosition)
+        , m_finalPosition(finalPosition)
+        , m_initialPositionSide(initialPositionSide)
+        , m_finalPositionSide(finalPositionSide)
     {
-        return resolvedPosition ? GridResolvedPosition(resolvedPosition - 1) : GridResolvedPosition(0);
     }
 
-    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);
+    const GridPosition& initialPosition() const { return m_initialPosition; }
+    const GridPosition& finalPosition() const { return m_finalPosition; }
+    GridPositionSide initialPositionSide() const { return m_initialPositionSide; }
+    GridPositionSide finalPositionSide() const { return m_finalPositionSide; }
 
-        return GridResolvedPosition(resolvedPosition);
-    }
+    bool requiresAutoPlacement() const;
+    void adjustGridPositionsFromStyle(const RenderStyle& gridContainerStyle);
 
-    static GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderStyle&, const RenderBox&, GridTrackSizingDirection, const GridResolvedPosition&);
-    static void adjustNamedGridItemPosition(const RenderStyle&, GridPosition&, GridPositionSide);
-    static void adjustGridPositionsFromStyle(const RenderStyle&, GridPosition& initialPosition, GridPosition& finalPosition, GridPositionSide initialPositionSide, GridPositionSide finalPositionSide);
-    static std::unique_ptr<GridSpan> resolveGridPositionsFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection);
-    static GridResolvedPosition resolveNamedGridLinePositionFromStyle(const RenderStyle&, const GridPosition&, GridPositionSide);
-    static GridResolvedPosition resolveGridPositionFromStyle(const RenderStyle&, const GridPosition&, GridPositionSide);
-    static std::unique_ptr<GridSpan> resolveGridPositionAgainstOppositePosition(const RenderStyle&, const GridResolvedPosition&, const GridPosition&, GridPositionSide);
-    static std::unique_ptr<GridSpan> resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle&, const GridResolvedPosition&, const GridPosition&, GridPositionSide);
-    static std::unique_ptr<GridSpan> resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition&, const GridPosition&, const Vector<unsigned>&);
-    static std::unique_ptr<GridSpan> resolveRowEndColumnEndNamedGridLinePositionAgainstOppositePosition(const GridResolvedPosition&, const GridPosition&, const Vector<unsigned>&);
+private:
+    GridPosition m_initialPosition;
+    GridPosition m_finalPosition;
+    GridPositionSide m_initialPositionSide;
+    GridPositionSide m_finalPositionSide;
+};
 
+// 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:
     GridResolvedPosition(unsigned position)
         : m_integerPosition(position)
     {
     }
 
-    GridResolvedPosition(const GridPosition& position, GridPositionSide side)
-    {
-        ASSERT(position.integerPosition());
-        unsigned integerPosition = position.integerPosition() - 1;
-
-        m_integerPosition = adjustGridPositionForSide(integerPosition, side).m_integerPosition;
-    }
+    GridResolvedPosition(const GridPosition&, GridPositionSide);
 
     GridResolvedPosition& operator*()
     {
@@ -146,11 +133,13 @@ public:
         return GridResolvedPosition(m_integerPosition + 1);
     }
 
+    static GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderStyle&, const RenderBox&, GridTrackSizingDirection, const GridResolvedPosition&);
+    static GridSpan resolveGridPositionsFromStyle(const GridUnresolvedSpan&, const RenderStyle&);
+    static GridUnresolvedSpan unresolvedSpanFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection);
     static unsigned explicitGridColumnCount(const RenderStyle&);
     static unsigned explicitGridRowCount(const RenderStyle&);
 
 private:
-
     unsigned m_integerPosition;
 };