Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Unified Diff: Source/core/rendering/RenderGrid.cpp

Issue 148293008: [CSS Grid Layout] Add support to place items using named grid lines (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: New approach Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/rendering/RenderGrid.h ('k') | Source/core/rendering/style/GridCoordinate.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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).
« no previous file with comments | « Source/core/rendering/RenderGrid.h ('k') | Source/core/rendering/style/GridCoordinate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698