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

Unified Diff: third_party/WebKit/Source/core/layout/LayoutGrid.cpp

Issue 815833005: [css-grid] Handle min-content/max-content with orthogonal flows (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Patch rebased. Created 5 years, 2 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
Index: third_party/WebKit/Source/core/layout/LayoutGrid.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index 867d8516eeba7ac0a8013c69b4e258fb9882ca1a..7fdbf34e812320746a8cb9a2b3752aa6adf06e8d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -604,28 +604,29 @@ GridTrackSize LayoutGrid::gridTrackSize(GridTrackSizingDirection direction, size
return GridTrackSize(minTrackBreadth, maxTrackBreadth);
}
-LayoutUnit LayoutGrid::logicalHeightForChild(LayoutBox& child, Vector<GridTrack>& columnTracks)
+LayoutUnit LayoutGrid::overrideContainingBlockLogicalBreadthInlineDirection(const LayoutBox& child) const
cbiesinger 2015/11/13 03:25:48 Hmm, this is the grid's inline direction, not the
{
- SubtreeLayoutScope layoutScope(child);
- LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child.hasOverrideContainingBlockLogicalWidth() ? child.overrideContainingBlockContentLogicalWidth() : LayoutUnit();
- LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForChild(child, ForColumns, columnTracks);
- if (child.hasRelativeLogicalHeight() || oldOverrideContainingBlockContentLogicalWidth != overrideContainingBlockContentLogicalWidth) {
- layoutScope.setNeedsLayout(&child, LayoutInvalidationReason::GridChanged);
- }
-
- bool hasOverrideHeight = child.hasOverrideLogicalContentHeight();
- // We need to clear the stretched height to properly compute logical height during layout.
- if (hasOverrideHeight && child.needsLayout())
- child.clearOverrideLogicalContentHeight();
+ bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
+ if (hasOrthogonalWritingMode)
+ return child.hasOverrideContainingBlockLogicalHeight() ? child.overrideContainingBlockContentLogicalHeight() : LayoutUnit();
+ return child.hasOverrideContainingBlockLogicalWidth() ? child.overrideContainingBlockContentLogicalWidth() : LayoutUnit();
+}
- child.setOverrideContainingBlockContentLogicalWidth(overrideContainingBlockContentLogicalWidth);
- // If |child| has a relative logical height, we shouldn't let it override its intrinsic height, which is
- // what we are interested in here. Thus we need to set the override logical height to -1 (no possible resolution).
- if (child.hasRelativeLogicalHeight())
- child.setOverrideContainingBlockContentLogicalHeight(-1);
- child.layoutIfNeeded();
- // If the child was stretched we should use its intrinsic height.
- return (hasOverrideHeight ? childIntrinsicHeight(child) : child.logicalHeight()) + child.marginLogicalHeight();
+void LayoutGrid::setOverrideContainingBlockLogicalBreadthInlineDirection(LayoutBox& child, LayoutUnit breadthInLine)
+{
+ bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
+ bool hasRelativeBreadthInBlockDirection = hasOrthogonalWritingMode ? child.hasRelativeLogicalWidth() : child.hasRelativeLogicalHeight();
+ // If |child| has a percentage logical breadth in block direction, we shouldn't let it override its intrinsic size, which is
+ // what we are interested in here. Thus we need to set the override logical height/width to -1 (no possible resolution).
+ if (hasOrthogonalWritingMode) {
+ child.setOverrideContainingBlockContentLogicalHeight(breadthInLine);
+ if (hasRelativeBreadthInBlockDirection)
+ child.setOverrideContainingBlockContentLogicalWidth(-1);
+ } else {
+ child.setOverrideContainingBlockContentLogicalWidth(breadthInLine);
+ if (hasRelativeBreadthInBlockDirection)
+ child.setOverrideContainingBlockContentLogicalHeight(-1);
+ }
}
LayoutUnit LayoutGrid::minSizeForChild(LayoutBox& child, GridTrackSizingDirection direction, Vector<GridTrack>& columnTracks)
@@ -647,12 +648,40 @@ LayoutUnit LayoutGrid::minSizeForChild(LayoutBox& child, GridTrackSizingDirectio
return child.computeContentLogicalHeight(MinSize, childMinSize, child.logicalHeight()) + child.scrollbarLogicalHeight();
}
-LayoutUnit LayoutGrid::minContentForChild(LayoutBox& child, GridTrackSizingDirection direction, Vector<GridTrack>& columnTracks)
+LayoutUnit LayoutGrid::gridAreaBreadthForChildInlineDirection(const LayoutBox& child, Vector<GridTrack>& tracksInlineDirection) const
{
bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
- // FIXME: Properly support orthogonal writing mode.
if (hasOrthogonalWritingMode)
- return 0;
+ return gridAreaBreadthForChild(child, ForRows, tracksInlineDirection);
+ return gridAreaBreadthForChild(child, ForColumns, tracksInlineDirection);
+}
+
+
+LayoutUnit LayoutGrid::logicalHeightForChild(LayoutBox& child, Vector<GridTrack>& tracksInlineDirection)
+{
+ SubtreeLayoutScope layoutScope(child);
+ LayoutUnit oldOverrideContainingBlockContentLogicalBreadthInlineDirection = overrideContainingBlockLogicalBreadthInlineDirection(child);
+ LayoutUnit overrideContainingBlockContentLogicalBreadthInlineDirection = gridAreaBreadthForChildInlineDirection(child, tracksInlineDirection);
esprehn 2015/10/30 23:21:31 longest variable names ever :P
+ if (child.hasRelativeLogicalHeight() || oldOverrideContainingBlockContentLogicalBreadthInlineDirection != overrideContainingBlockContentLogicalBreadthInlineDirection) {
+ layoutScope.setNeedsLayout(&child, LayoutInvalidationReason::GridChanged);
+ }
+
+ bool hasOverrideHeight = child.hasOverrideLogicalContentHeight();
+ // We need to clear the stretched height to properly compute logical height during layout.
+ if (hasOverrideHeight && child.needsLayout())
+ child.clearOverrideLogicalContentHeight();
+
+ setOverrideContainingBlockLogicalBreadthInlineDirection(child, overrideContainingBlockContentLogicalBreadthInlineDirection);
+ child.layoutIfNeeded();
+ // If the child was stretched we should use its intrinsic height.
+ return (hasOverrideHeight ? childIntrinsicHeight(child) : child.logicalHeight()) + child.marginLogicalHeight();
esprehn 2015/10/30 23:21:31 I find this ternary + expr thing hard to read, can
+}
+
+LayoutUnit LayoutGrid::minContentForChild(LayoutBox& child, GridTrackSizingDirection direction, Vector<GridTrack>& tracksInTheInlineDirection)
+{
+ bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
+ if (hasOrthogonalWritingMode)
+ direction = direction == ForColumns ? ForRows : ForColumns;
if (direction == ForColumns) {
// If |child| has a relative logical width, we shouldn't let it override its intrinsic width, which is
@@ -665,15 +694,14 @@ LayoutUnit LayoutGrid::minContentForChild(LayoutBox& child, GridTrackSizingDirec
return child.minPreferredLogicalWidth() + marginIntrinsicLogicalWidthForChild(child);
}
- return logicalHeightForChild(child, columnTracks);
+ return logicalHeightForChild(child, tracksInTheInlineDirection);
}
-LayoutUnit LayoutGrid::maxContentForChild(LayoutBox& child, GridTrackSizingDirection direction, Vector<GridTrack>& columnTracks)
+LayoutUnit LayoutGrid::maxContentForChild(LayoutBox& child, GridTrackSizingDirection direction, Vector<GridTrack>& tracksInlineDirection)
{
bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
- // FIXME: Properly support orthogonal writing mode.
if (hasOrthogonalWritingMode)
- return LayoutUnit();
+ direction = direction == ForColumns ? ForRows : ForColumns;
if (direction == ForColumns) {
// If |child| has a relative logical width, we shouldn't let it override its intrinsic width, which is
@@ -686,7 +714,7 @@ LayoutUnit LayoutGrid::maxContentForChild(LayoutBox& child, GridTrackSizingDirec
return child.maxPreferredLogicalWidth() + marginIntrinsicLogicalWidthForChild(child);
}
- return logicalHeightForChild(child, columnTracks);
+ return logicalHeightForChild(child, tracksInlineDirection);
}
// We're basically using a class instead of a std::pair for two reasons. First of all, accessing gridItem() or
@@ -745,10 +773,11 @@ void LayoutGrid::resolveContentBasedTrackSizingFunctions(GridTrackSizingDirectio
GridIterator iterator(m_grid, direction, trackIndex);
GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndex] : sizingData.rowTracks[trackIndex];
while (LayoutBox* gridItem = iterator.nextGridItem()) {
+ bool hasOrthogonalWritingMode = gridItem->isHorizontalWritingMode() != isHorizontalWritingMode();
if (itemsSet.add(gridItem).isNewEntry) {
const GridCoordinate& coordinate = cachedGridCoordinate(*gridItem);
if (integerSpanForDirection(coordinate, direction) == 1) {
- resolveContentBasedTrackSizingFunctionsForNonSpanningItems(direction, coordinate, *gridItem, track, sizingData.columnTracks);
+ resolveContentBasedTrackSizingFunctionsForNonSpanningItems(direction, coordinate, *gridItem, track, hasOrthogonalWritingMode ? sizingData.rowTracks : sizingData.columnTracks);
} else if (!spanningItemCrossesFlexibleSizedTracks(coordinate, direction)) {
sizingData.itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, coordinate, direction));
}
@@ -776,22 +805,22 @@ void LayoutGrid::resolveContentBasedTrackSizingFunctions(GridTrackSizingDirectio
}
}
-void LayoutGrid::resolveContentBasedTrackSizingFunctionsForNonSpanningItems(GridTrackSizingDirection direction, const GridCoordinate& coordinate, LayoutBox& gridItem, GridTrack& track, Vector<GridTrack>& columnTracks)
+void LayoutGrid::resolveContentBasedTrackSizingFunctionsForNonSpanningItems(GridTrackSizingDirection direction, const GridCoordinate& coordinate, LayoutBox& gridItem, GridTrack& track, Vector<GridTrack>& tracksInlineDirection)
{
const GridResolvedPosition trackPosition = (direction == ForColumns) ? coordinate.columns.resolvedInitialPosition : coordinate.rows.resolvedInitialPosition;
GridTrackSize trackSize = gridTrackSize(direction, trackPosition.toInt());
if (trackSize.hasMinContentMinTrackBreadth())
- track.setBaseSize(std::max(track.baseSize(), minContentForChild(gridItem, direction, columnTracks)));
+ track.setBaseSize(std::max(track.baseSize(), minContentForChild(gridItem, direction, tracksInlineDirection)));
else if (trackSize.hasMaxContentMinTrackBreadth())
- track.setBaseSize(std::max(track.baseSize(), maxContentForChild(gridItem, direction, columnTracks)));
+ track.setBaseSize(std::max(track.baseSize(), maxContentForChild(gridItem, direction, tracksInlineDirection)));
else if (trackSize.hasAutoMinTrackBreadth())
- track.setBaseSize(std::max(track.baseSize(), minSizeForChild(gridItem, direction, columnTracks)));
+ track.setBaseSize(std::max(track.baseSize(), minSizeForChild(gridItem, direction, tracksInlineDirection)));
if (trackSize.hasMinContentMaxTrackBreadth())
- track.setGrowthLimit(std::max(track.growthLimit(), minContentForChild(gridItem, direction, columnTracks)));
+ track.setGrowthLimit(std::max(track.growthLimit(), minContentForChild(gridItem, direction, tracksInlineDirection)));
else if (trackSize.hasMaxContentOrAutoMaxTrackBreadth())
- track.setGrowthLimit(std::max(track.growthLimit(), maxContentForChild(gridItem, direction, columnTracks)));
+ track.setGrowthLimit(std::max(track.growthLimit(), maxContentForChild(gridItem, direction, tracksInlineDirection)));
}
static const LayoutUnit& trackSizeForTrackSizeComputationPhase(TrackSizeComputationPhase phase, const GridTrack& track, TrackSizeRestriction restriction)
@@ -955,7 +984,8 @@ void LayoutGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing
spanningTracksSize += guttersSize(direction, itemSpan.integerSpan());
- LayoutUnit extraSpace = currentItemSizeForTrackSizeComputationPhase(phase, gridItemWithSpan.gridItem(), direction, sizingData.columnTracks) - spanningTracksSize;
+ bool hasOrthogonalWritingMode = gridItemWithSpan.gridItem().isHorizontalWritingMode() != isHorizontalWritingMode();
+ LayoutUnit extraSpace = currentItemSizeForTrackSizeComputationPhase(phase, gridItemWithSpan.gridItem(), direction, hasOrthogonalWritingMode ? sizingData.rowTracks : sizingData.columnTracks) - spanningTracksSize;
extraSpace = std::max<LayoutUnit>(extraSpace, 0);
auto& tracksToGrowBeyondGrowthLimits = sizingData.growBeyondGrowthLimitsTracks.isEmpty() ? sizingData.filteredTracks : sizingData.growBeyondGrowthLimitsTracks;
distributeSpaceToTracks<phase>(sizingData.filteredTracks, &tracksToGrowBeyondGrowthLimits, sizingData, extraSpace);
@@ -1310,6 +1340,18 @@ void LayoutGrid::applyStretchAlignmentToTracksIfNeeded(GridTrackSizingDirection
availableSpace = 0;
}
+bool LayoutGrid::childOverflowingContainingBlockHeight(const LayoutBox& child) const
esprehn 2015/10/30 23:21:31 static? or static and file level?
+{
+ LayoutUnit containingBlockContentHeight = child.hasOverrideContainingBlockHeight() ? child.overrideContainingBlockContentHeight() : LayoutUnit();
+ return child.size().height() > containingBlockContentHeight;
+}
+
+bool LayoutGrid::childOverflowingContainingBlockWidth(const LayoutBox& child) const
esprehn 2015/10/30 23:21:31 these methods don't appear to use any internal sta
+{
+ LayoutUnit containingBlockContentWidth = child.hasOverrideContainingBlockWidth() ? child.overrideContainingBlockContentWidth() : LayoutUnit();
+ return child.size().width() > containingBlockContentWidth;
+}
+
void LayoutGrid::layoutGridItems()
{
placeItemsOnGrid();
@@ -1322,10 +1364,28 @@ void LayoutGrid::layoutGridItems()
availableSpaceForRows -= guttersSize(ForRows, gridRowCount());
GridSizingData sizingData(gridColumnCount(), gridRowCount(), availableSpaceForColumns, availableSpaceForRows);
+ // 1- First, the track sizing algorithm is used to resolve the sizes of the grid columns.
computeUsedBreadthOfGridTracks(ForColumns, sizingData);
ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks));
+ // 2- Next, the track sizing algorithm resolves the sizes of the grid rows, using the
+ // grid column sizes calculated in the previous step.
computeUsedBreadthOfGridTracks(ForRows, sizingData);
ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks));
+ // 3- If the min-content contribution of any grid items have changed based on the row
+ // sizes calculated in step 2, steps 1 and 2 are repeated with the new min-content
+ // contribution (once only).
+ for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+ bool hasOrthogonalWritingMode = child->isHorizontalWritingMode() != isHorizontalWritingMode();
+ // In orthogonal flow cases column tracks size is determined based on the computed
+ // row track sizes, hence we need to repeat computeUsedBreadthOfGridTracks for columns.
+ if (hasOrthogonalWritingMode) {
+ LayoutUnit& currentAvailableSpaceForColumns = sizingData.freeSpaceForDirection(ForColumns);
+ currentAvailableSpaceForColumns = availableSpaceForColumns;
+ computeUsedBreadthOfGridTracks(ForColumns, sizingData);
+ ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks));
+ break;
+ }
+ }
applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData);
applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData);
@@ -1373,9 +1433,10 @@ void LayoutGrid::layoutGridItems()
child->setLogicalLocation(findChildLogicalPosition(*child, sizingData));
// Keep track of children overflowing their grid area as we might need to paint them even if the grid-area is
- // not visible
- if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight
- || child->logicalWidth() > overrideContainingBlockContentLogicalWidth)
+ // not visible.
+ // Using physical dimensions for simplicity, so we can forget about orthogonalty.
+ if (childOverflowingContainingBlockHeight(*child)
+ || childOverflowingContainingBlockWidth(*child))
m_gridItemsOverflowingGridArea.append(child);
}
@@ -1658,12 +1719,14 @@ void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child)
bool canShrinkToFitInRowAxisForChild = !hasAutoMinSizeInRowAxis || child.minPreferredLogicalWidth() <= child.overrideContainingBlockContentLogicalWidth();
// TODO(lajava): how to handle orthogonality in this case ?.
// TODO(lajava): grid track sizing and positioning do not support orthogonal modes yet.
- if (hasAutoSizeInRowAxis && canShrinkToFitInRowAxisForChild) {
- LayoutUnit childWidthToFitContent = std::max(std::min(child.maxPreferredLogicalWidth(), child.overrideContainingBlockContentLogicalWidth() - child.marginLogicalWidth()), child.minPreferredLogicalWidth());
- LayoutUnit desiredLogicalWidth = child.constrainLogicalHeightByMinMax(childWidthToFitContent, -1);
- child.setOverrideLogicalContentWidth(desiredLogicalWidth - child.borderAndPaddingLogicalWidth());
- if (desiredLogicalWidth != child.logicalWidth())
- child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
+ if (child.isHorizontalWritingMode() == isHorizontalMode) {
+ if (hasAutoSizeInRowAxis && canShrinkToFitInRowAxisForChild) {
+ LayoutUnit childWidthToFitContent = std::max(std::min(child.maxPreferredLogicalWidth(), child.overrideContainingBlockContentLogicalWidth() - child.marginLogicalWidth()), child.minPreferredLogicalWidth());
+ LayoutUnit desiredLogicalWidth = child.constrainLogicalHeightByMinMax(childWidthToFitContent, -1);
+ child.setOverrideLogicalContentWidth(desiredLogicalWidth - child.borderAndPaddingLogicalWidth());
+ if (desiredLogicalWidth != child.logicalWidth())
+ child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
+ }
}
}
@@ -2020,8 +2083,9 @@ ContentAlignmentData LayoutGrid::computeContentPositionAndDistributionOffset(Gri
LayoutPoint LayoutGrid::findChildLogicalPosition(const LayoutBox& child, GridSizingData& sizingData) const
{
+ LayoutUnit columnAxisOffset = columnAxisOffsetForChild(child);
LayoutUnit rowAxisOffset = rowAxisOffsetForChild(child);
- // We stored m_columnPosition s's data ignoring the direction, hence we might need now
+ // We stored m_columnPositions's data ignoring the direction, hence we might need now
// to translate positions from RTL to LTR, as it's more convenient for painting.
if (!style()->isLeftToRightDirection()) {
LayoutUnit alignmentOffset = m_columnPositions[0] - borderAndPaddingStart();
@@ -2029,7 +2093,14 @@ LayoutPoint LayoutGrid::findChildLogicalPosition(const LayoutBox& child, GridSiz
rowAxisOffset = rightGridEdgePosition - (rowAxisOffset + child.logicalWidth());
}
- return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child));
+
+ // "In the positioning phase [...] calculations are performed according to the writing mode
+ // of the containing block of the box establishing the orthogonal flow." However, the
+ // resulting LayoutPoint will be used in 'setLogicalPosition' in order to set the child's
+ // logical position, which will only take into account the child's writing-mode.
+ LayoutPoint childLocation(rowAxisOffset, columnAxisOffset);
+ bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
+ return hasOrthogonalWritingMode ? childLocation.transposedPoint() : childLocation;
}
void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) const

Powered by Google App Engine
This is Rietveld 408576698