Chromium Code Reviews| 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 |