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

Unified Diff: third_party/WebKit/Source/core/style/GridResolvedPosition.cpp

Issue 1576993003: [css-grid] Fix placement for unknown named grid lines (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing last review comments Created 4 years, 11 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 | « third_party/WebKit/LayoutTests/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-resolution.html ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/style/GridResolvedPosition.cpp
diff --git a/third_party/WebKit/Source/core/style/GridResolvedPosition.cpp b/third_party/WebKit/Source/core/style/GridResolvedPosition.cpp
index 1f28d5a2cf32a0f6d1bf4b5c0d1090db12c3a67e..d002ce670f236a18160f689db7694b5b1a01ccaa 100644
--- a/third_party/WebKit/Source/core/style/GridResolvedPosition.cpp
+++ b/third_party/WebKit/Source/core/style/GridResolvedPosition.cpp
@@ -47,13 +47,14 @@ static void initialAndFinalPositionsFromStyle(const ComputedStyle& gridContainer
if (initialPosition.isSpan() && finalPosition.isSpan())
finalPosition.setAutoPosition();
- // Try to early detect the case of non existing named grid lines. This way we could assume later that
- // GridResolvedPosition::resolveGrisPositionFromStyle() always return a valid resolved position.
- if (initialPosition.isNamedGridArea() && !GridResolvedPosition::isValidNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, GridResolvedPosition::initialPositionSide(direction)))
- initialPosition.setAutoPosition();
+ if (gridItem.isOutOfFlowPositioned()) {
+ // Early detect the case of non existing named grid lines for positioned items.
+ if (initialPosition.isNamedGridArea() && !GridResolvedPosition::isValidNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, GridResolvedPosition::initialPositionSide(direction)))
+ initialPosition.setAutoPosition();
- if (finalPosition.isNamedGridArea() && !GridResolvedPosition::isValidNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, GridResolvedPosition::finalPositionSide(direction)))
- finalPosition.setAutoPosition();
+ if (finalPosition.isNamedGridArea() && !GridResolvedPosition::isValidNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, GridResolvedPosition::finalPositionSide(direction)))
+ 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())
@@ -62,46 +63,80 @@ static void initialAndFinalPositionsFromStyle(const ComputedStyle& gridContainer
initialPosition.setSpanPosition(1, String());
}
-static GridSpan definiteGridSpanWithInitialNamedSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
+static size_t lookAheadForNamedGridLine(int start, size_t numberOfLines, const Vector<size_t>* namedGridLinesIndexes, size_t gridLastLine)
{
- if (resolvedOppositePosition == 0)
- return GridSpan::untranslatedDefiniteGridSpan(resolvedOppositePosition, resolvedOppositePosition + 1);
+ ASSERT(numberOfLines);
+
+ // Only implicit lines on the search direction are assumed to have the given name, so we can start to look from first line.
+ // See: https://drafts.csswg.org/css-grid/#grid-placement-span-int
+ size_t end = std::max(start, 0);
+
+ if (!namedGridLinesIndexes) {
+ end = std::max(end, gridLastLine + 1);
+ return end + numberOfLines - 1;
+ }
+
+ for (; numberOfLines; ++end) {
+ if (end > gridLastLine || namedGridLinesIndexes->contains(end))
+ numberOfLines--;
+ }
- size_t firstLineBeforeOppositePositionIndex = 0;
- const size_t* firstLineBeforeOppositePosition = std::lower_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition);
- if (firstLineBeforeOppositePosition != gridLines.end())
- firstLineBeforeOppositePositionIndex = firstLineBeforeOppositePosition - gridLines.begin();
- size_t gridLineIndex = std::max<int>(0, firstLineBeforeOppositePositionIndex - position.spanPosition());
- size_t resolvedGridLinePosition = gridLines[gridLineIndex];
- if (resolvedGridLinePosition >= resolvedOppositePosition)
- resolvedGridLinePosition = resolvedOppositePosition - 1;
- return GridSpan::untranslatedDefiniteGridSpan(resolvedGridLinePosition, resolvedOppositePosition);
+ ASSERT(end);
+ return end - 1;
}
-static GridSpan definiteGridSpanWithFinalNamedSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
+static int lookBackForNamedGridLine(int end, size_t numberOfLines, const Vector<size_t>* namedGridLinesIndexes, int gridLastLine)
{
- ASSERT(gridLines.size());
- size_t firstLineAfterOppositePositionIndex = gridLines.size() - 1;
- const size_t* firstLineAfterOppositePosition = std::upper_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition);
- if (firstLineAfterOppositePosition != gridLines.end())
- firstLineAfterOppositePositionIndex = firstLineAfterOppositePosition - gridLines.begin();
- size_t gridLineIndex = std::min(gridLines.size() - 1, firstLineAfterOppositePositionIndex + position.spanPosition() - 1);
- size_t resolvedGridLinePosition = gridLines[gridLineIndex];
- if (resolvedGridLinePosition <= resolvedOppositePosition)
- resolvedGridLinePosition = resolvedOppositePosition + 1;
-
- return GridSpan::untranslatedDefiniteGridSpan(resolvedOppositePosition, resolvedGridLinePosition);
+ ASSERT(numberOfLines);
+
+ // Only implicit lines on the search direction are assumed to have the given name, so we can start to look from last line.
+ // See: https://drafts.csswg.org/css-grid/#grid-placement-span-int
+ int start = std::min(end, gridLastLine);
+
+ if (!namedGridLinesIndexes) {
+ start = std::min(start, -1);
+ return start - numberOfLines + 1;
+ }
+
+ for (; numberOfLines; --start) {
+ if (start < 0 || namedGridLinesIndexes->contains(static_cast<size_t>(start)))
+ numberOfLines--;
+ }
+
+ return start + 1;
}
-static GridSpan definiteGridSpanWithNamedSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side, const Vector<size_t>& gridLines)
+static GridSpan definiteGridSpanWithNamedSpanAgainstOpposite(int resolvedOppositePosition, const GridPosition& position, GridPositionSide side, const Vector<size_t>* gridLines, int lastLine)
{
- if (side == RowStartSide || side == ColumnStartSide)
- return definiteGridSpanWithInitialNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
+ int start, end;
+
+ if (side == RowStartSide || side == ColumnStartSide) {
+ start = lookBackForNamedGridLine(resolvedOppositePosition - 1, position.spanPosition(), gridLines, lastLine);
+ end = resolvedOppositePosition;
+ } else {
+ start = resolvedOppositePosition;
+ end = lookAheadForNamedGridLine(resolvedOppositePosition + 1, position.spanPosition(), gridLines, lastLine);
+ }
- return definiteGridSpanWithFinalNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
+ return GridSpan::untranslatedDefiniteGridSpan(start, end);
}
-static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+size_t GridResolvedPosition::explicitGridColumnCount(const ComputedStyle& gridContainerStyle)
+{
+ return std::min<size_t>(gridContainerStyle.gridTemplateColumns().size(), kGridMaxTracks);
+}
+
+size_t GridResolvedPosition::explicitGridRowCount(const ComputedStyle& gridContainerStyle)
+{
+ return std::min<size_t>(gridContainerStyle.gridTemplateRows().size(), kGridMaxTracks);
+}
+
+static size_t explicitGridSizeForSide(const ComputedStyle& gridContainerStyle, GridPositionSide side)
+{
+ return (side == ColumnStartSide || side == ColumnEndSide) ? GridResolvedPosition::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyle);
+}
+
+static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, int resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
{
ASSERT(position.isSpan());
ASSERT(!position.namedGridLine().isNull());
@@ -110,16 +145,9 @@ static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const Comput
const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyle, 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).
- // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html.
- if (it == gridLinesNames.end()) {
- if ((side == ColumnStartSide || side == RowStartSide) && resolvedOppositePosition)
- return GridSpan::untranslatedDefiniteGridSpan(resolvedOppositePosition - 1, resolvedOppositePosition);
- return GridSpan::untranslatedDefiniteGridSpan(resolvedOppositePosition, resolvedOppositePosition + 1);
- }
-
- return definiteGridSpanWithNamedSpanAgainstOpposite(resolvedOppositePosition, position, side, it->value);
+ const Vector<size_t>* gridLines = it == gridLinesNames.end() ? nullptr : &it->value;
+ size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side);
+ return definiteGridSpanWithNamedSpanAgainstOpposite(resolvedOppositePosition, position, side, gridLines, lastLine);
}
static GridSpan definiteGridSpanWithSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
@@ -131,7 +159,7 @@ static GridSpan definiteGridSpanWithSpanAgainstOpposite(size_t resolvedOppositeP
return GridSpan::untranslatedDefiniteGridSpan(resolvedOppositePosition, resolvedOppositePosition + positionOffset);
}
-static GridSpan resolveGridPositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+static GridSpan resolveGridPositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, int resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
{
if (position.isAuto()) {
if (side == ColumnStartSide || side == RowStartSide)
@@ -167,40 +195,18 @@ size_t GridResolvedPosition::spanSizeForAutoPlacedItem(const ComputedStyle& grid
return position.spanPosition();
}
-size_t GridResolvedPosition::explicitGridColumnCount(const ComputedStyle& gridContainerStyle)
-{
- return std::min<size_t>(gridContainerStyle.gridTemplateColumns().size(), kGridMaxTracks);
-}
-
-size_t GridResolvedPosition::explicitGridRowCount(const ComputedStyle& gridContainerStyle)
-{
- return std::min<size_t>(gridContainerStyle.gridTemplateRows().size(), kGridMaxTracks);
-}
-
-static size_t explicitGridSizeForSide(const ComputedStyle& gridContainerStyle, GridPositionSide side)
-{
- return (side == ColumnStartSide || side == ColumnEndSide) ? GridResolvedPosition::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyle);
-}
-
-static size_t resolveNamedGridLinePositionFromStyle(const ComputedStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
+static int resolveNamedGridLinePositionFromStyle(const ComputedStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
{
ASSERT(!position.namedGridLine().isNull());
const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyle, side);
NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
- if (it == gridLinesNames.end()) {
- if (position.isPositive())
- return 0;
- size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side);
- return lastLine;
- }
-
- size_t namedGridLineIndex;
+ const Vector<size_t>* gridLines = it == gridLinesNames.end() ? nullptr : &it->value;
+ size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side);
if (position.isPositive())
- namedGridLineIndex = std::min<size_t>(position.integerPosition(), it->value.size()) - 1;
+ return lookAheadForNamedGridLine(0, abs(position.integerPosition()), gridLines, lastLine);
else
- namedGridLineIndex = std::max<int>(it->value.size() - abs(position.integerPosition()), 0);
- return it->value[namedGridLineIndex];
+ return lookBackForNamedGridLine(lastLine, abs(position.integerPosition()), gridLines, lastLine);
}
static int resolveGridPositionFromStyle(const ComputedStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
@@ -227,7 +233,7 @@ static int resolveGridPositionFromStyle(const ComputedStyle& gridContainerStyle,
// ''<custom-ident>-start (for grid-*-start) / <custom-ident>-end'' (for grid-*-end), contributes the first such
// line to the grid item's placement.
String namedGridLine = position.namedGridLine();
- ASSERT(GridResolvedPosition::isValidNamedLineOrArea(namedGridLine, gridContainerStyle, side));
+ ASSERT(!position.namedGridLine().isNull());
const NamedGridLinesMap& gridLineNames = gridLinesForSide(gridContainerStyle, side);
NamedGridLinesMap::const_iterator implicitLineIter = gridLineNames.find(implicitNamedGridLineForSide(namedGridLine, side));
@@ -240,11 +246,10 @@ static int resolveGridPositionFromStyle(const ComputedStyle& gridContainerStyle,
if (explicitLineIter != gridLineNames.end())
return explicitLineIter->value[0];
- // 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 GridResolvedPosition::resolveGridPositionsFromStyle(). We should be also covered by the
- // ASSERT at the beginning of this block.
- ASSERT_NOT_REACHED();
- return 0;
+ ASSERT(!GridResolvedPosition::isValidNamedLineOrArea(namedGridLine, gridContainerStyle, side));
+ // If none of the above works specs mandate to assume that all the lines in the implicit grid have this name.
+ size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side);
+ return lastLine + 1;
}
case AutoPosition:
case SpanPosition:
« no previous file with comments | « third_party/WebKit/LayoutTests/fast/css-grid-layout/named-grid-lines-with-named-grid-areas-resolution.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698