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

Unified Diff: Source/core/rendering/RenderGrid.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: Utility functions for orthogonality. Created 5 years, 10 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') | no next file » | 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 e4628969db7ef4037f9ddaf53914562ae6114bc8..75b241282ec7827eaee305a788f845c76210930f 100644
--- a/Source/core/rendering/RenderGrid.cpp
+++ b/Source/core/rendering/RenderGrid.cpp
@@ -610,30 +610,61 @@ GridTrackSize RenderGrid::gridTrackSize(GridTrackSizingDirection direction, size
return trackSize;
}
-LayoutUnit RenderGrid::logicalHeightForChild(RenderBox& child, Vector<GridTrack>& columnTracks)
+LayoutUnit RenderGrid::overrideContainingBlockLogicalBreadthInlineDirection(const RenderBox& child) const
+{
+ bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
+ if (hasOrthogonalWritingMode)
+ return child.hasOverrideContainingBlockLogicalHeight() ? child.overrideContainingBlockContentLogicalHeight() : LayoutUnit();
+ return child.hasOverrideContainingBlockLogicalWidth() ? child.overrideContainingBlockContentLogicalWidth() : LayoutUnit();
+}
+
+void RenderGrid::setOverrideContainingBlockLogicalBreadthInlineDirection(RenderBox& child, LayoutUnit breadth)
+{
+ bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
+ if (hasOrthogonalWritingMode)
+ child.setOverrideContainingBlockContentLogicalHeight(breadth);
+ else
+ child.setOverrideContainingBlockContentLogicalWidth(breadth);
+ // If |child| has a percentage 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/width to -1 (no possible resolution).
+ if (child.style()->logicalHeight().isPercent()) {
+ if (hasOrthogonalWritingMode)
+ child.setOverrideContainingBlockContentLogicalWidth(-1);
+ else
+ child.setOverrideContainingBlockContentLogicalHeight(-1);
Julien - ping for review 2015/02/18 23:00:07 We do 2 hash lookups in the percentage logical hei
jfernandez 2015/02/23 18:51:58 Actually we don't; we need to set both, xxxLogical
+ }
+}
+
+LayoutUnit RenderGrid::gridAreaBreadthForChildInlineDirection(const RenderBox& child, Vector<GridTrack>& tracksInlineDirection) const
Julien - ping for review 2015/02/18 23:00:07 This name is confusing and I still am unsure I und
jfernandez 2015/02/23 18:51:58 I took the name inspired by other methods like com
+{
+ bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
+ if (hasOrthogonalWritingMode)
+ return gridAreaBreadthForChild(child, ForRows, tracksInlineDirection);
+ return gridAreaBreadthForChild(child, ForColumns, tracksInlineDirection);
+}
+
+
+LayoutUnit RenderGrid::logicalHeightForChild(RenderBox& child, Vector<GridTrack>& tracksInlineDirection)
{
SubtreeLayoutScope layoutScope(child);
- LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child.hasOverrideContainingBlockLogicalWidth() ? child.overrideContainingBlockContentLogicalWidth() : LayoutUnit();
- LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForChild(child, ForColumns, columnTracks);
- if (child.style()->logicalHeight().isPercent() || oldOverrideContainingBlockContentLogicalWidth != overrideContainingBlockContentLogicalWidth)
+ LayoutUnit oldOverrideContainingBlockContentLogicalBreadthInlineDirection = overrideContainingBlockLogicalBreadthInlineDirection(child);
+ LayoutUnit overrideContainingBlockContentLogicalBreadthInlineDirection = gridAreaBreadthForChildInlineDirection(child, tracksInlineDirection);
+ if (child.style()->logicalHeight().isPercent() || oldOverrideContainingBlockContentLogicalBreadthInlineDirection != overrideContainingBlockContentLogicalBreadthInlineDirection)
layoutScope.setNeedsLayout(&child);
+ // Needed to properly implement the stretch logic.
child.clearOverrideLogicalContentHeight();
- child.setOverrideContainingBlockContentLogicalWidth(overrideContainingBlockContentLogicalWidth);
- // If |child| has a percentage 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).
- child.setOverrideContainingBlockContentLogicalHeight(-1);
+ setOverrideContainingBlockLogicalBreadthInlineDirection(child, overrideContainingBlockContentLogicalBreadthInlineDirection);
child.layoutIfNeeded();
return child.logicalHeight() + child.marginLogicalHeight();
}
-LayoutUnit RenderGrid::minContentForChild(RenderBox& child, GridTrackSizingDirection direction, Vector<GridTrack>& columnTracks)
+LayoutUnit RenderGrid::minContentForChild(RenderBox& child, GridTrackSizingDirection direction, Vector<GridTrack>& tracksInlineDirection)
Julien - ping for review 2015/02/18 23:00:07 In correct English, this would be tracksInInlineDi
jfernandez 2015/02/23 18:51:58 That s right. However, I saw source code using jus
{
bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
- // FIXME: Properly support orthogonal writing mode.
if (hasOrthogonalWritingMode)
- return 0;
+ direction = direction == ForColumns ? ForRows : ForColumns;
if (direction == ForColumns) {
// FIXME: It's unclear if we should return the intrinsic width or the preferred width.
@@ -641,15 +672,14 @@ LayoutUnit RenderGrid::minContentForChild(RenderBox& child, GridTrackSizingDirec
return child.minPreferredLogicalWidth() + marginIntrinsicLogicalWidthForChild(child);
}
- return logicalHeightForChild(child, columnTracks);
+ return logicalHeightForChild(child, tracksInlineDirection);
}
-LayoutUnit RenderGrid::maxContentForChild(RenderBox& child, GridTrackSizingDirection direction, Vector<GridTrack>& columnTracks)
+LayoutUnit RenderGrid::maxContentForChild(RenderBox& 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) {
// FIXME: It's unclear if we should return the intrinsic width or the preferred width.
@@ -657,7 +687,7 @@ LayoutUnit RenderGrid::maxContentForChild(RenderBox& 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
@@ -716,10 +746,11 @@ void RenderGrid::resolveContentBasedTrackSizingFunctions(GridTrackSizingDirectio
GridIterator iterator(m_grid, direction, trackIndex);
GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndex] : sizingData.rowTracks[trackIndex];
while (RenderBox* 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));
}
@@ -744,20 +775,20 @@ void RenderGrid::resolveContentBasedTrackSizingFunctions(GridTrackSizingDirectio
}
}
-void RenderGrid::resolveContentBasedTrackSizingFunctionsForNonSpanningItems(GridTrackSizingDirection direction, const GridCoordinate& coordinate, RenderBox& gridItem, GridTrack& track, Vector<GridTrack>& columnTracks)
+void RenderGrid::resolveContentBasedTrackSizingFunctionsForNonSpanningItems(GridTrackSizingDirection direction, const GridCoordinate& coordinate, RenderBox& 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)));
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.hasMaxContentMaxTrackBreadth())
- track.setGrowthLimit(std::max(track.growthLimit(), maxContentForChild(gridItem, direction, columnTracks)));
+ track.setGrowthLimit(std::max(track.growthLimit(), maxContentForChild(gridItem, direction, tracksInlineDirection)));
}
void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizingDirection direction, GridSizingData& sizingData, GridItemWithSpan& gridItemWithSpan, FilterFunction filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction, FilterFunction growAboveMaxBreadthFilterFunction)
@@ -787,7 +818,8 @@ void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing
// Specs mandate to floor extraSpace to 0. Instead we directly avoid the function call in those cases as it will be
// a noop in terms of track sizing.
- LayoutUnit extraSpace = (this->*sizingFunction)(gridItemWithSpan.gridItem(), direction, sizingData.columnTracks) - spanningTracksSize;
+ bool hasOrthogonalWritingMode = gridItemWithSpan.gridItem().isHorizontalWritingMode() != isHorizontalWritingMode();
+ LayoutUnit extraSpace = (this->*sizingFunction)(gridItemWithSpan.gridItem(), direction, hasOrthogonalWritingMode ? sizingData.rowTracks : sizingData.columnTracks) - spanningTracksSize;
if (extraSpace > 0) {
Vector<GridTrack*>* tracksToGrowBeyondGrowthLimits = sizingData.growBeyondGrowthLimitsTracks.isEmpty() ? &sizingData.filteredTracks : &sizingData.growBeyondGrowthLimitsTracks;
distributeSpaceToTracks(sizingData.filteredTracks, tracksToGrowBeyondGrowthLimits, trackGetter, trackGrowthFunction, sizingData, extraSpace);
@@ -1079,6 +1111,22 @@ void RenderGrid::dirtyGrid()
m_gridItemsIndexesMap.clear();
}
+bool RenderGrid::childOverflowingContainingBlockHeight(const RenderBox& child) const
+{
+ bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
+ LayoutUnit overrideContainingBlockContentLogicalHeight = child.hasOverrideContainingBlockLogicalHeight() ? child.overrideContainingBlockContentLogicalHeight() : LayoutUnit();
+
+ return hasOrthogonalWritingMode ? child.logicalWidth() > overrideContainingBlockContentLogicalHeight : child.logicalHeight() > overrideContainingBlockContentLogicalHeight;
+}
Julien - ping for review 2015/02/18 23:00:07 This seems super complicated to me. We don't *need
jfernandez 2015/02/23 18:51:58 Oh, you are so right. I'll implement it that way i
+
+bool RenderGrid::childOverflowingContainingBlockWidth(const RenderBox& child) const
+{
+ bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
+ LayoutUnit overrideContainingBlockContentLogicalWidth = child.hasOverrideContainingBlockLogicalWidth() ? child.overrideContainingBlockContentLogicalWidth() : LayoutUnit();
+
+ return hasOrthogonalWritingMode ? child.logicalHeight() > overrideContainingBlockContentLogicalWidth : child.logicalHeight() > overrideContainingBlockContentLogicalWidth;
+}
+
void RenderGrid::layoutGridItems()
{
placeItemsOnGrid();
@@ -1086,10 +1134,27 @@ void RenderGrid::layoutGridItems()
LayoutUnit availableSpaceForColumns = availableLogicalWidth();
LayoutUnit availableSpaceForRows = availableLogicalHeight(IncludeMarginBorderPadding);
GridSizingData sizingData(gridColumnCount(), gridRowCount());
+ // 1- First, the track sizing algorithm is used to resolve the sizes of the grid columns.
computeUsedBreadthOfGridTracks(ForColumns, sizingData, availableSpaceForColumns);
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, availableSpaceForRows);
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 (RenderBox* 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) {
+ availableSpaceForColumns = availableLogicalWidth();
+ computeUsedBreadthOfGridTracks(ForColumns, sizingData, availableSpaceForColumns);
+ ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks));
+ break;
+ }
+ }
populateGridPositions(sizingData, availableSpaceForColumns, availableSpaceForRows);
m_gridItemsOverflowingGridArea.resize(0);
@@ -1135,8 +1200,8 @@ void RenderGrid::layoutGridItems()
// 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)
+ if (childOverflowingContainingBlockHeight(*child)
+ || childOverflowingContainingBlockWidth(*child))
m_gridItemsOverflowingGridArea.append(child);
}
@@ -1711,7 +1776,12 @@ LayoutPoint RenderGrid::findChildLogicalPosition(const RenderBox& child, LayoutS
LayoutPoint childLocation(columnPosition, rowPositionForChild(child));
childLocation.move(contentAlignmentOffset);
- return childLocation;
+ // "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.
+ bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
+ return hasOrthogonalWritingMode ? childLocation.transposedPoint() : childLocation;
}
void RenderGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
« no previous file with comments | « Source/core/rendering/RenderGrid.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698