Modified: trunk/Source/WebCore/rendering/RenderGrid.cpp (185058 => 185059)
--- 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)
@@ -975,17 +975,22 @@
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 @@
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 @@
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::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 @@
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));
Modified: trunk/Source/WebCore/rendering/style/GridResolvedPosition.cpp (185058 => 185059)
--- 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)
@@ -48,49 +48,12 @@
return side == ColumnStartSide || side == RowStartSide;
}
-unsigned GridResolvedPosition::explicitGridColumnCount(const RenderStyle& gridContainerStyle)
+static const NamedGridLinesMap& gridLinesForSide(const RenderStyle& style, GridPositionSide side)
{
- 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)
-{
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 @@
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
{
- ASSERT(isColumnSide(initialPositionSide) == isColumnSide(finalPositionSide));
+ return m_initialPosition.shouldBeResolvedAgainstOppositePosition() && m_finalPosition.shouldBeResolvedAgainstOppositePosition();
+}
+void GridUnresolvedSpan::adjustGridPositionsFromStyle(const RenderStyle& gridContainerStyle)
+{
+ 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;
+ return std::min<unsigned>(gridContainerStyle.gridColumns().size(), kGridMaxTracks);
+}
- adjustGridPositionsFromStyle(gridContainerStyle, initialPosition, finalPosition, initialPositionSide, finalPositionSide);
+unsigned GridResolvedPosition::explicitGridRowCount(const RenderStyle& gridContainerStyle)
+{
+ return std::min<unsigned>(gridContainerStyle.gridRows().size(), kGridMaxTracks);
+}
- // We can't get our grid positions without running the auto placement algorithm.
- if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition())
- return nullptr;
+static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side)
+{
+ return isColumnSide(side) ? GridResolvedPosition::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyle);
+}
- 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);
- }
+static GridResolvedPosition adjustGridPositionForRowEndColumnEndSide(unsigned resolvedPosition)
+{
+ return resolvedPosition ? GridResolvedPosition(resolvedPosition - 1) : GridResolvedPosition(0);
+}
- 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 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);
- 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 < resolvedInitialPosition)
- resolvedFinalPosition = resolvedInitialPosition;
-
- 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 @@
if (position.isPositive())
return 0;
const unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side);
- return GridResolvedPosition::adjustGridPositionForSide(lastLine, side);
+ return adjustGridPositionForSide(lastLine, side);
}
unsigned namedGridLineIndex;
@@ -179,11 +141,111 @@
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);
}
-GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide 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);
+}
+
+static GridResolvedPosition resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
+{
switch (position.type()) {
case ExplicitPosition: {
ASSERT(position.integerPosition());
@@ -193,7 +255,7 @@
// 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 @@
if (endOfTrack < resolvedPosition)
return 0;
- return GridResolvedPosition::adjustGridPositionForSide(endOfTrack - resolvedPosition, side);
+ return adjustGridPositionForSide(endOfTrack - resolvedPosition, side);
}
case NamedGridAreaPosition:
{
@@ -215,13 +277,13 @@
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 @@
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.integerPosition());
+ unsigned integerPosition = position.integerPosition() - 1;
- 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 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);
+ 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;
- const NamedGridLinesMap& gridLinesNames = isColumnSide(side) ? gridContainerStyle.namedGridColumnLines() : gridContainerStyle.namedGridRowLines();
- NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
+ GridUnresolvedSpan unresolvedSpan(initialPosition, initialPositionSide, finalPosition, finalPositionSide);
+ unresolvedSpan.adjustGridPositionsFromStyle(gridContainerStyle);
- // 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);
-
- if (side == RowStartSide || side == ColumnStartSide)
- return resolveRowStartColumnStartNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, it->value);
-
- 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
Modified: trunk/Source/WebCore/rendering/style/GridResolvedPosition.h (185058 => 185059)
--- 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)
@@ -41,60 +41,47 @@
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;
+ GridResolvedPosition(const GridPosition&, GridPositionSide);
- m_integerPosition = adjustGridPositionForSide(integerPosition, side).m_integerPosition;
- }
-
GridResolvedPosition& operator*()
{
return *this;
@@ -146,11 +133,13 @@
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;
};