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 b2205b79aab9ab159f6fff8407c6f05288f09743..e76c0529af35c6c60ec81bc40d6eb70b0f77445f 100644 |
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp |
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp |
@@ -255,6 +255,8 @@ LayoutGrid::LayoutGrid(Element* element) |
: LayoutBlock(element) |
, m_gridIsDirty(true) |
, m_orderIterator(this) |
+ , m_minContentHeight(-1) |
+ , m_maxContentHeight(-1) |
{ |
ASSERT(!childrenInline()); |
} |
@@ -308,6 +310,38 @@ bool LayoutGrid::namedGridLinesDefinitionDidChange(const ComputedStyle& oldStyle |
|| oldStyle.namedGridColumnLines() != styleRef().namedGridColumnLines(); |
} |
+void LayoutGrid::computeGridTrackSizes(GridSizingData& sizingData, LayoutUnit& freeSpaceForColumns, LayoutUnit& freeSpaceForRows) |
+{ |
+ freeSpaceForColumns = contentLogicalWidth(); |
+ computeUsedBreadthOfGridTracks(ForColumns, sizingData, freeSpaceForColumns); |
+ ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks)); |
+ |
+ freeSpaceForRows = computeContentAndScrollbarLogicalHeightUsing(MainOrPreferredSize, style()->logicalHeight(), -1); |
+ computeUsedBreadthOfGridTracks(ForRows, sizingData, freeSpaceForRows); |
+ ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks)); |
+} |
+ |
+LayoutUnit LayoutGrid::computeTrackBasedLogicalHeight(const GridSizingData& sizingData) const |
+{ |
+ LayoutUnit logicalHeight = borderAndPaddingLogicalHeight() + scrollbarLogicalHeight(); |
+ |
+ for (const auto& row : sizingData.rowTracks) |
+ logicalHeight += row.baseSize(); |
+ |
+ return logicalHeight; |
+} |
+ |
+void LayoutGrid::updateLogicalHeightDependentGridTracks(const LayoutUnit& trackBasedLogicalHeight, GridSizingData& sizingData, LayoutUnit& availableSpaceForRows) |
jfernandez
2015/10/19 10:46:22
Which are those dependent tracks ? This function w
svillar
2015/10/19 12:14:20
We need to rerun the algorithm, and it'll indeed u
|
+{ |
+ LayoutUnit contentHeight = contentLogicalHeight(); |
+ if (trackBasedLogicalHeight == contentHeight) |
+ return; |
+ |
+ availableSpaceForRows = contentHeight; |
+ computeUsedBreadthOfGridTracks(ForRows, sizingData, availableSpaceForRows); |
+ ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks)); |
+} |
+ |
void LayoutGrid::layoutBlock(bool relayoutChildren) |
{ |
ASSERT(needsLayout()); |
@@ -315,8 +349,6 @@ void LayoutGrid::layoutBlock(bool relayoutChildren) |
if (!relayoutChildren && simplifiedLayout()) |
return; |
- // FIXME: Much of this method is boiler plate that matches LayoutBox::layoutBlock and Layout*FlexibleBox::layoutBlock. |
- // It would be nice to refactor some of the duplicate code. |
{ |
// LayoutState needs this deliberate scope to pop before updating scroll information (which |
// may trigger relayout). |
@@ -324,16 +356,33 @@ void LayoutGrid::layoutBlock(bool relayoutChildren) |
LayoutSize previousSize = size(); |
- setLogicalHeight(0); |
updateLogicalWidth(); |
TextAutosizer::LayoutScope textAutosizerLayoutScope(this); |
- layoutGridItems(); |
+ placeItemsOnGrid(); |
+ |
+ // TODO(svillar): move freeSpaceRows|Columns to GridSizingData. |
+ LayoutUnit freeSpaceForRows; |
+ LayoutUnit freeSpaceForColumns; |
+ GridSizingData sizingData(gridColumnCount(), gridRowCount()); |
+ computeGridTrackSizes(sizingData, freeSpaceForColumns, freeSpaceForRows); |
LayoutUnit oldClientAfterEdge = clientLogicalBottom(); |
+ LayoutUnit trackBasedLogicalHeight = computeTrackBasedLogicalHeight(sizingData); |
+ setLogicalHeight(trackBasedLogicalHeight); |
+ |
updateLogicalHeight(); |
+ // The above call might have changed the grid's logical height depending on min|max height restrictions. |
+ // Update the sizes of the rows whose size depends on the logical height (also on definite|indefinite sizes). |
+ updateLogicalHeightDependentGridTracks(trackBasedLogicalHeight, sizingData, freeSpaceForRows); |
+ |
+ applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData, freeSpaceForColumns); |
+ applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData, freeSpaceForRows); |
+ |
+ layoutGridItems(sizingData, freeSpaceForColumns, freeSpaceForRows); |
+ |
if (size() != previousSize) |
relayoutChildren = true; |
@@ -369,6 +418,37 @@ void LayoutGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Layo |
maxLogicalWidth += scrollbarWidth; |
} |
+LayoutUnit LayoutGrid::computeIntrinsicLogicalContentHeightUsing(const Length& logicalHeightLength, LayoutUnit intrinsicContentHeight, LayoutUnit borderAndPadding) const |
+{ |
+ if (logicalHeightLength.isMinContent()) |
+ return m_minContentHeight; |
+ |
+ if (logicalHeightLength.isMaxContent()) |
jfernandez
2015/10/19 10:46:22
Current LayoutBox: logic doesn't implement the new
svillar
2015/10/19 12:14:20
Yes it does implement the min/max-content, it's ju
|
+ return m_maxContentHeight; |
+ |
+ if (logicalHeightLength.isFitContent()) { |
+ LayoutUnit fillAvailableExtent = containingBlock()->availableLogicalHeight(ExcludeMarginBorderPadding); |
+ return std::min<LayoutUnit>(m_maxContentHeight, std::max<LayoutUnit>(m_minContentHeight, fillAvailableExtent)); |
+ } |
+ |
+ if (logicalHeightLength.isFillAvailable()) |
+ return containingBlock()->availableLogicalHeight(ExcludeMarginBorderPadding) - borderAndPadding; |
+ ASSERT_NOT_REACHED(); |
+ return 0; |
+} |
+ |
+LayoutUnit LayoutGrid::computeContentAndScrollbarLogicalHeightUsing(SizeType heightType, const Length& height, LayoutUnit intrinsicContentHeight) const |
+{ |
+ // The grid container’s auto block size is its max-content size. |
+ if (height.isAuto()) |
+ return heightType == MinSize ? LayoutUnit(0) : m_maxContentHeight + scrollbarLogicalHeight(); |
+ |
+ if (height.isIntrinsic()) |
+ return computeIntrinsicLogicalContentHeightUsing(height, intrinsicContentHeight, borderAndPaddingLogicalHeight()) + scrollbarLogicalHeight(); |
+ |
+ return LayoutBox::computeContentAndScrollbarLogicalHeightUsing(heightType, height, intrinsicContentHeight); |
+} |
+ |
bool LayoutGrid::gridElementIsShrinkToFit() |
{ |
return isFloatingOrOutOfFlowPositioned(); |
@@ -407,13 +487,29 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi |
if (!sizingData.contentSizedTracksIndex.isEmpty()) |
resolveContentBasedTrackSizingFunctions(direction, sizingData); |
+ LayoutUnit totalBaseSizes = 0; |
+ LayoutUnit totalGrowthLimits = 0; |
+ |
for (const auto& track: tracks) { |
ASSERT(!track.infiniteGrowthPotential()); |
- freeSpace -= track.baseSize(); |
+ totalBaseSizes += track.baseSize(); |
+ totalGrowthLimits += track.growthLimit(); |
} |
+ freeSpace = initialFreeSpace - totalBaseSizes; |
- const bool hasUndefinedRemainingSpace = (direction == ForRows) ? style()->logicalHeight().isAuto() : gridElementIsShrinkToFit(); |
+ // Cache our intrinisc heights so that we could resolve them properly in computeIntrinsicLogicalContentHeightUsing(). |
+ if (direction == ForRows) { |
+ m_minContentHeight = totalBaseSizes; |
+ m_maxContentHeight = totalGrowthLimits; |
+ } |
+ |
+ // Grid container should have the minimum height of a line if it's editable. That does not affect track sizing though. |
+ if (hasLineIfEmpty()) { |
Manuel Rego
2015/10/09 14:38:35
Do we need this if "direction == ForColumns"?
Oth
svillar
2015/10/19 12:14:20
Will do that.
|
+ m_minContentHeight = std::max(m_minContentHeight, minimumLogicalHeightForEmptyLine()); |
+ m_maxContentHeight = std::max(m_maxContentHeight, m_minContentHeight); |
+ } |
+ const bool hasUndefinedRemainingSpace = (direction == ForRows) ? initialFreeSpace == -1 : false; |
if (!hasUndefinedRemainingSpace && freeSpace <= 0) |
return; |
@@ -464,9 +560,15 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi |
for (const auto& trackIndex : flexibleSizedTracksIndex) { |
GridTrackSize trackSize = gridTrackSize(direction, trackIndex); |
- LayoutUnit baseSize = std::max<LayoutUnit>(tracks[trackIndex].baseSize(), flexFraction * trackSize.maxTrackBreadth().flex()); |
- tracks[trackIndex].setBaseSize(baseSize); |
- freeSpace -= baseSize; |
+ LayoutUnit oldBaseSize = tracks[trackIndex].baseSize(); |
+ LayoutUnit baseSize = std::max<LayoutUnit>(oldBaseSize, flexFraction * trackSize.maxTrackBreadth().flex()); |
+ if (LayoutUnit increment = baseSize - oldBaseSize) { |
+ tracks[trackIndex].setBaseSize(baseSize); |
+ freeSpace -= increment; |
Manuel Rego
2015/10/09 14:38:35
We're changing this regarding the previous code
th
jfernandez
2015/10/19 10:46:22
Wow, that changes seems like a bug fix, but why we
svillar
2015/10/19 12:14:20
Because we need very specific tests for that, as t
|
+ |
+ if (direction == ForRows) |
+ m_maxContentHeight += increment; |
+ } |
} |
// FIXME: Should ASSERT flexible tracks exhaust the freeSpace ? (see issue 739613002). |
@@ -1286,22 +1388,9 @@ void LayoutGrid::applyStretchAlignmentToTracksIfNeeded(GridTrackSizingDirection |
} |
} |
-void LayoutGrid::layoutGridItems() |
+void LayoutGrid::layoutGridItems(GridSizingData& sizingData, LayoutUnit& freeSpaceForColumns, LayoutUnit& freeSpaceForRows) |
{ |
- placeItemsOnGrid(); |
- |
- LayoutUnit availableSpaceForColumns = availableLogicalWidth(); |
- LayoutUnit availableSpaceForRows = availableLogicalHeight(IncludeMarginBorderPadding); |
- GridSizingData sizingData(gridColumnCount(), gridRowCount()); |
- computeUsedBreadthOfGridTracks(ForColumns, sizingData, availableSpaceForColumns); |
- ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks)); |
- computeUsedBreadthOfGridTracks(ForRows, sizingData, availableSpaceForRows); |
- ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks)); |
- |
- applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData, availableSpaceForColumns); |
- applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData, availableSpaceForRows); |
- |
- populateGridPositions(sizingData, availableSpaceForColumns, availableSpaceForRows); |
+ populateGridPositions(sizingData, freeSpaceForColumns, freeSpaceForRows); |
m_gridItemsOverflowingGridArea.resize(0); |
for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
@@ -1345,16 +1434,6 @@ void LayoutGrid::layoutGridItems() |
|| child->logicalWidth() > overrideContainingBlockContentLogicalWidth) |
m_gridItemsOverflowingGridArea.append(child); |
} |
- |
- for (const auto& row : sizingData.rowTracks) |
- setLogicalHeight(logicalHeight() + row.baseSize()); |
- |
- LayoutUnit height = logicalHeight() + borderAndPaddingLogicalHeight() + scrollbarLogicalHeight(); |
- if (hasLineIfEmpty()) |
- height = std::max(height, minimumLogicalHeightForEmptyLine()); |
- |
- // Min / max logical height is handled by the call to updateLogicalHeight in layoutBlock. |
- setLogicalHeight(height); |
} |
void LayoutGrid::prepareChildForPositionedLayout(LayoutBox& child) |