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). |