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

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: New version after spec changes 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..78377193ef7ddf38e5c1c1c3823668d5ab42f6c6 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,75 @@ 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 int lookAheadForNamedGridLine(int start, int numberOfLines, const Vector<size_t>& namedGridLinesIndexes, int gridLastLine)
{
- if (resolvedOppositePosition == 0)
- return GridSpan::untranslatedDefiniteGridSpan(resolvedOppositePosition, resolvedOppositePosition + 1);
+ ASSERT(numberOfLines > 0);
+ if (start > gridLastLine)
+ return start + (numberOfLines - 1);
+ if (start < 0)
+ start = 0;
svillar 2016/01/26 09:29:37 Not sure I understand this condition.
Manuel Rego 2016/01/26 11:07:35 This is needed because of the last change on the s
+
+ for (int end = start; numberOfLines > 0; end++) {
+ if (end > gridLastLine || end < 0 || namedGridLinesIndexes.contains(static_cast<size_t>(end))) {
+ numberOfLines--;
+ if (!numberOfLines)
+ return end;
+ }
+ }
svillar 2016/01/26 09:29:37 This loop looks terribly confusing, we're using a
Manuel Rego 2016/01/26 11:07:35 I've tried a different approach, I think it's a bi
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+static int lookBackForNamedGridLine(int end, int numberOfLines, const Vector<size_t>& namedGridLinesIndexes, int gridLastLine)
+{
+ ASSERT(numberOfLines > 0);
+ if (end < 0)
+ return end - (numberOfLines - 1);
+ if (end > gridLastLine)
+ end = gridLastLine;
+
+ for (int start = end; numberOfLines > 0; start--) {
+ if (start > gridLastLine || start < 0 || namedGridLinesIndexes.contains(static_cast<size_t>(start))) {
+ numberOfLines--;
+ if (!numberOfLines)
+ return start;
+ }
+ }
svillar 2016/01/26 09:29:37 Same comments than in lookAhead
Manuel Rego 2016/01/26 11:07:35 Acknowledged.
+ ASSERT_NOT_REACHED();
+ return 0;
+}
- 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);
+static GridSpan definiteGridSpanWithNamedSpanAgainstOpposite(int resolvedOppositePosition, const GridPosition& position, GridPositionSide side, const Vector<size_t>& gridLines, int lastLine)
+{
+ int start, end;
+
+ if (side == RowStartSide || side == ColumnStartSide) {
svillar 2016/01/26 09:29:37 I think we had a isStartSide() or something like t
Manuel Rego 2016/01/26 11:07:35 Mmmm, I cannot find it. We can add it if needed,
+ start = lookBackForNamedGridLine(resolvedOppositePosition - 1, position.spanPosition(), gridLines, lastLine);
+ end = resolvedOppositePosition;
+ } else {
+ start = resolvedOppositePosition;
+ end = lookAheadForNamedGridLine(resolvedOppositePosition + 1, position.spanPosition(), gridLines, lastLine);
+ }
+
+ return GridSpan::untranslatedDefiniteGridSpan(start, end);
}
-static GridSpan definiteGridSpanWithFinalNamedSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
+size_t GridResolvedPosition::explicitGridColumnCount(const ComputedStyle& gridContainerStyle)
{
- 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);
+ return std::min<size_t>(gridContainerStyle.gridTemplateColumns().size(), kGridMaxTracks);
}
-static GridSpan definiteGridSpanWithNamedSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side, const Vector<size_t>& gridLines)
+size_t GridResolvedPosition::explicitGridRowCount(const ComputedStyle& gridContainerStyle)
{
- if (side == RowStartSide || side == ColumnStartSide)
- return definiteGridSpanWithInitialNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
+ return std::min<size_t>(gridContainerStyle.gridTemplateRows().size(), kGridMaxTracks);
+}
- return definiteGridSpanWithFinalNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
+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, size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const ComputedStyle& gridContainerStyle, int resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
{
ASSERT(position.isSpan());
ASSERT(!position.namedGridLine().isNull());
@@ -110,16 +140,8 @@ 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);
+ size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side);
+ return definiteGridSpanWithNamedSpanAgainstOpposite(resolvedOppositePosition, position, side, it == gridLinesNames.end() ? Vector<size_t>() : it->value, lastLine);
svillar 2016/01/26 09:29:37 Uhu, so each time it == gridLinesNames.end() then
Manuel Rego 2016/01/26 11:07:35 True, changed to use pointers.
}
static GridSpan definiteGridSpanWithSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
@@ -131,7 +153,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 +189,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() ? Vector<size_t>() : it->value;
svillar 2016/01/26 09:29:37 Same thing about creating Vectors.
Manuel Rego 2016/01/26 11:07:35 Done.
+ 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 +227,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 +240,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