Chromium Code Reviews| Index: Source/core/rendering/RenderGrid.cpp |
| diff --git a/Source/core/rendering/RenderGrid.cpp b/Source/core/rendering/RenderGrid.cpp |
| index 351881084b582f24de06651ade28f7fd5595239d..b914aed44a109689af752b48e4d8d146738dc96a 100644 |
| --- a/Source/core/rendering/RenderGrid.cpp |
| +++ b/Source/core/rendering/RenderGrid.cpp |
| @@ -219,9 +219,46 @@ void RenderGrid::removeChild(RenderObject* child) |
| dirtyGrid(); |
| } |
| +void RenderGrid::createGridLineNamesMapsForDirection(GridTrackSizingDirection direction) |
| +{ |
| + NamedGridLinesMap& gridLinesMap = (direction == ForColumns) ? m_namedGridColumnLines : m_namedGridRowLines; |
| + const OrderedNamedGridLines& orderedLinesMap = (direction == ForColumns) ? style()->orderedNamedGridColumnLines() : style()->orderedNamedGridRowLines(); |
| + |
| + gridLinesMap.clear(); |
| + OrderedNamedGridLines::const_iterator orderedLinesEnd = orderedLinesMap.end(); |
| + for (OrderedNamedGridLines::const_iterator it = orderedLinesMap.begin(); it != orderedLinesEnd; ++it) { |
| + const Vector<String> gridLineNames = it->value; |
| + for (size_t i = 0; i < gridLineNames.size(); ++i) { |
| + NamedGridLinesMap::AddResult result = gridLinesMap.add(gridLineNames[i], Vector<size_t>()); |
| + result.storedValue->value.append(it->key); |
| + } |
| + } |
| + |
| + NamedGridAreaMap::const_iterator gridAreasEnd = style()->namedGridArea().end(); |
| + for (NamedGridAreaMap::const_iterator it = style()->namedGridArea().begin(); it != gridAreasEnd; ++it) { |
| + GridSpan areaSpan = direction == ForRows ? it->value.rows : it->value.columns; |
| + |
| + NamedGridLinesMap::AddResult startResult = gridLinesMap.add(it->key + "-start", Vector<size_t>()); |
| + startResult.storedValue->value.append(areaSpan.initialPositionIndex); |
| + NamedGridLinesMap::AddResult endResult = gridLinesMap.add(it->key + "-end", Vector<size_t>()); |
| + endResult.storedValue->value.append(areaSpan.finalPositionIndex + 1); |
| + } |
| + |
| + NamedGridLinesMap::const_iterator namedLinesEnd = gridLinesMap.end(); |
| + for (NamedGridLinesMap::iterator it = gridLinesMap.begin(); it != namedLinesEnd; ++it) |
| + std::sort(it->value.begin(), it->value.end()); |
| +} |
| + |
| void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) |
| { |
| RenderBlock::styleDidChange(diff, oldStyle); |
| + |
| + bool gridLinesDefinitionChanged = namedGridLinesDefinitionDidChange(oldStyle); |
| + if (gridLinesDefinitionChanged) { |
| + createGridLineNamesMapsForDirection(ForColumns); |
| + createGridLineNamesMapsForDirection(ForRows); |
| + } |
| + |
| if (!oldStyle) |
| return; |
| @@ -230,9 +267,7 @@ void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl |
| // - named grid lines only impact grid items with named grid lines. |
| // - auto-flow changes only impacts auto-placed children. |
| - if (explicitGridDidResize(oldStyle) |
| - || namedGridLinesDefinitionDidChange(oldStyle) |
| - || oldStyle->gridAutoFlow() != style()->gridAutoFlow()) |
| + if (explicitGridDidResize(oldStyle) || gridLinesDefinitionChanged || oldStyle->gridAutoFlow() != style()->gridAutoFlow()) |
| dirtyGrid(); |
| } |
| @@ -244,8 +279,12 @@ bool RenderGrid::explicitGridDidResize(const RenderStyle* oldStyle) const |
| bool RenderGrid::namedGridLinesDefinitionDidChange(const RenderStyle* oldStyle) const |
| { |
| - return oldStyle->namedGridRowLines() != style()->namedGridRowLines() |
| - || oldStyle->namedGridColumnLines() != style()->namedGridColumnLines(); |
| + if (!oldStyle) |
| + return true; |
| + |
| + return oldStyle->orderedNamedGridRowLines() != style()->orderedNamedGridRowLines() |
| + || oldStyle->orderedNamedGridColumnLines() != style()->orderedNamedGridColumnLines() |
| + || oldStyle->namedGridArea() != style()->namedGridArea(); |
| } |
| void RenderGrid::layoutBlock(bool relayoutChildren) |
| @@ -968,22 +1007,31 @@ GridSpan RenderGrid::resolveGridPositionsFromAutoPlacementPosition(const RenderB |
| return GridSpan(initialPosition, initialPosition); |
| } |
| +static bool isNonExistentNamedLineOrArea(GridPosition& position, RenderStyle& style, const NamedGridLinesMap& gridLinesMap) |
| +{ |
| + ASSERT(position.isNamedGridArea()); |
| + String lineName = position.namedGridLine(); |
| + |
| + return !style.namedGridArea().contains(lineName) && !gridLinesMap.contains(lineName); |
| +} |
| + |
| PassOwnPtr<GridSpan> RenderGrid::resolveGridPositionsFromStyle(const RenderBox* gridItem, GridTrackSizingDirection direction) const |
| { |
| GridPosition initialPosition = (direction == ForColumns) ? gridItem->style()->gridColumnStart() : gridItem->style()->gridRowStart(); |
| const GridPositionSide initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide; |
| GridPosition finalPosition = (direction == ForColumns) ? gridItem->style()->gridColumnEnd() : gridItem->style()->gridRowEnd(); |
| const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide; |
| + const NamedGridLinesMap& gridLines = (direction == ForColumns) ? m_namedGridColumnLines : m_namedGridRowLines; |
| // 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 (initialPosition.isNamedGridArea() && !style()->namedGridArea().contains(initialPosition.namedGridLine())) |
| + if (initialPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(initialPosition, *style(), gridLines)) |
| initialPosition.setAutoPosition(); |
| - if (finalPosition.isNamedGridArea() && !style()->namedGridArea().contains(finalPosition.namedGridLine())) |
| + if (finalPosition.isNamedGridArea() && isNonExistentNamedLineOrArea(finalPosition, *style(), gridLines)) |
| finalPosition.setAutoPosition(); |
| if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()) { |
| @@ -1020,7 +1068,7 @@ size_t RenderGrid::resolveNamedGridLinePositionFromStyle(const GridPosition& pos |
| { |
| ASSERT(!position.namedGridLine().isNull()); |
| - const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side == ColumnEndSide) ? style()->namedGridColumnLines() : style()->namedGridRowLines(); |
| + const NamedGridLinesMap& gridLinesNames = gridLinesForSide(side); |
| NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine()); |
| if (it == gridLinesNames.end()) { |
| if (position.isPositive()) |
| @@ -1039,53 +1087,43 @@ size_t RenderGrid::resolveNamedGridLinePositionFromStyle(const GridPosition& pos |
| size_t RenderGrid::resolveGridPositionFromStyle(const GridPosition& position, GridPositionSide side) const |
| { |
| - switch (position.type()) { |
| - case ExplicitPosition: { |
| - ASSERT(position.integerPosition()); |
| - |
| - if (!position.namedGridLine().isNull()) |
| - return resolveNamedGridLinePositionFromStyle(position, side); |
| + ASSERT(position.type() == NamedGridAreaPosition || position.type() == ExplicitPosition); |
| - // Handle <integer> explicit position. |
| - if (position.isPositive()) |
| - return GridPosition::adjustGridPositionForSide(position.integerPosition() - 1, side); |
| + GridPosition adjustedPosition = position; |
| - size_t resolvedPosition = abs(position.integerPosition()) - 1; |
| - const size_t endOfTrack = explicitGridSizeForSide(side); |
| + if (position.type() == NamedGridAreaPosition) { |
| + NamedGridAreaMap::const_iterator areaIter = style()->namedGridArea().find(position.namedGridLine()); |
|
Julien - ping for review
2014/03/20 18:14:42
I think it would be worth a FIXME / comment about
|
| + if (areaIter != style()->namedGridArea().end()) { |
| + String implicitNamedGridLine = position.namedGridLine() + ((side == ColumnStartSide || side == RowStartSide) ? "-start" : "-end"); |
| + const NamedGridLinesMap& gridLineNames = gridLinesForSide(side); |
| + NamedGridLinesMap::const_iterator lineIter = gridLineNames.find(implicitNamedGridLine); |
| - // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line. |
| - if (endOfTrack < resolvedPosition) |
| - return 0; |
| + if (lineIter != gridLineNames.end()) |
| + return GridPosition::adjustGridPositionForSide(lineIter->value[0], side); |
| - return GridPosition::adjustGridPositionForSide(endOfTrack - resolvedPosition, side); |
| - } |
| - case NamedGridAreaPosition: |
| - { |
| - NamedGridAreaMap::const_iterator it = style()->namedGridArea().find(position.namedGridLine()); |
| - // Unknown grid area should have been computed to 'auto' by now. |
| - ASSERT_WITH_SECURITY_IMPLICATION(it != style()->namedGridArea().end()); |
| - const GridCoordinate& gridAreaCoordinate = it->value; |
| - switch (side) { |
| - case ColumnStartSide: |
| - return gridAreaCoordinate.columns.initialPositionIndex; |
| - case ColumnEndSide: |
| - return gridAreaCoordinate.columns.finalPositionIndex; |
| - case RowStartSide: |
| - return gridAreaCoordinate.rows.initialPositionIndex; |
| - case RowEndSide: |
| - return gridAreaCoordinate.rows.finalPositionIndex; |
| + return areaIter->value.positionForSide(side); |
| } |
| - ASSERT_NOT_REACHED(); |
| - return 0; |
| + // Fallback to a grid line position if there is no grid area with that name. |
| + adjustedPosition.setExplicitPosition(1, position.namedGridLine()); |
| } |
| - case AutoPosition: |
| - case SpanPosition: |
| - // 'auto' and span depend on the opposite position for resolution (e.g. grid-row: auto / 1 or grid-column: span 3 / "myHeader"). |
|
Julien - ping for review
2014/03/20 18:14:42
I liked this comment as it explained why we should
|
| - ASSERT_NOT_REACHED(); |
| + |
| + ASSERT(adjustedPosition.integerPosition()); |
|
Julien - ping for review
2014/03/20 18:14:42
This really looks like we should move it to a func
|
| + |
| + if (!adjustedPosition.namedGridLine().isNull()) |
| + return resolveNamedGridLinePositionFromStyle(adjustedPosition, side); |
| + |
| + // Handle <integer> explicit position. |
| + if (adjustedPosition.isPositive()) |
| + return GridPosition::adjustGridPositionForSide(adjustedPosition.integerPosition() - 1, side); |
| + |
| + size_t resolvedPosition = abs(adjustedPosition.integerPosition()) - 1; |
| + const size_t endOfTrack = explicitGridSizeForSide(side); |
| + |
| + // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line. |
| + if (endOfTrack < resolvedPosition) |
| return 0; |
| - } |
| - ASSERT_NOT_REACHED(); |
| - return 0; |
| + |
| + return GridPosition::adjustGridPositionForSide(endOfTrack - resolvedPosition, side); |
| } |
| PassOwnPtr<GridSpan> RenderGrid::resolveGridPositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side) const |
| @@ -1111,7 +1149,7 @@ PassOwnPtr<GridSpan> RenderGrid::resolveNamedGridLinePositionAgainstOppositePosi |
| // Negative positions are not allowed per the specification and should have been handled during parsing. |
| ASSERT(position.spanPosition() > 0); |
| - const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side == ColumnEndSide) ? style()->namedGridColumnLines() : style()->namedGridRowLines(); |
| + const NamedGridLinesMap& gridLinesNames = gridLinesForSide(side); |
| 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). |