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 fc5aa6d6f0a9b1923406f12b6936ff71a7b446b3..4b4c0581790f235aa554fdc203dd4039e8379ade 100644 |
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp |
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp |
@@ -1355,6 +1355,10 @@ void LayoutGrid::layoutGridItems() |
child->layoutIfNeeded(); |
+ // We need pending layouts to be done in order to compute auto-margins properly. |
+ updateAutoMarginsInColumnAxisIfNeeded(*child); |
+ updateAutoMarginsInRowAxisIfNeeded(*child); |
+ |
#if ENABLE(ASSERT) |
const GridCoordinate& coordinate = cachedGridCoordinate(*child); |
ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.columnTracks.size()); |
@@ -1611,15 +1615,10 @@ LayoutUnit LayoutGrid::computeMarginLogicalHeightForChild(const LayoutBox& child |
LayoutUnit LayoutGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUnit gridAreaBreadthForChild, const LayoutBox& child) const |
{ |
- LayoutUnit childMarginLogicalHeight = marginLogicalHeightForChild(child); |
- |
// Because we want to avoid multiple layouts, stretching logic might be performed before |
// children are laid out, so we can't use the child cached values. Hence, we need to |
// compute margins in order to determine the available height before stretching. |
- if (childMarginLogicalHeight == 0) |
- childMarginLogicalHeight = computeMarginLogicalHeightForChild(child); |
- |
- return gridAreaBreadthForChild - childMarginLogicalHeight; |
+ return gridAreaBreadthForChild - (child.needsLayout() ? computeMarginLogicalHeightForChild(child) : marginLogicalHeightForChild(child)); |
} |
// FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to LayoutBox. |
@@ -1666,6 +1665,64 @@ void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) |
} |
} |
+// TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be moved to LayoutBox. |
+bool LayoutGrid::hasAutoMarginsInColumnAxis(const LayoutBox& child) const |
+{ |
+ if (isHorizontalWritingMode()) |
+ return child.style()->marginTop().isAuto() || child.style()->marginBottom().isAuto(); |
+ return child.style()->marginLeft().isAuto() || child.style()->marginRight().isAuto(); |
+} |
+ |
+// TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be moved to LayoutBox. |
+bool LayoutGrid::hasAutoMarginsInRowAxis(const LayoutBox& child) const |
+{ |
+ if (isHorizontalWritingMode()) |
+ return child.style()->marginLeft().isAuto() || child.style()->marginRight().isAuto(); |
+ return child.style()->marginTop().isAuto() || child.style()->marginBottom().isAuto(); |
+} |
+ |
+// TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be moved to LayoutBox. |
+void LayoutGrid::updateAutoMarginsInRowAxisIfNeeded(LayoutBox& child) |
+{ |
+ ASSERT(!child.isOutOfFlowPositioned()); |
+ |
+ LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLogicalWidth() - child.logicalWidth(); |
+ if (availableAlignmentSpace <= 0) |
+ return; |
+ |
+ Length marginStart = child.style()->marginStartUsing(style()); |
+ Length marginEnd = child.style()->marginEndUsing(style()); |
+ if (marginStart.isAuto() && marginEnd.isAuto()) { |
+ child.setMarginStart(availableAlignmentSpace / 2, style()); |
+ child.setMarginEnd(availableAlignmentSpace / 2, style()); |
+ } else if (marginStart.isAuto()) { |
+ child.setMarginStart(availableAlignmentSpace, style()); |
+ } else if (marginEnd.isAuto()) { |
+ child.setMarginEnd(availableAlignmentSpace, style()); |
+ } |
+} |
+ |
+// TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be moved to LayoutBox. |
+void LayoutGrid::updateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child) |
+{ |
+ ASSERT(!child.isOutOfFlowPositioned()); |
+ |
+ LayoutUnit availableAlignmentSpace = child.overrideContainingBlockContentLogicalHeight() - child.logicalHeight(); |
+ if (availableAlignmentSpace <= 0) |
+ return; |
+ |
+ Length marginBefore = child.style()->marginBeforeUsing(style()); |
+ Length marginAfter = child.style()->marginAfterUsing(style()); |
+ if (marginBefore.isAuto() && marginAfter.isAuto()) { |
+ child.setMarginBefore(availableAlignmentSpace / 2, style()); |
+ child.setMarginAfter(availableAlignmentSpace / 2, style()); |
+ } else if (marginBefore.isAuto()) { |
+ child.setMarginBefore(availableAlignmentSpace, style()); |
+ } else if (marginAfter.isAuto()) { |
+ child.setMarginAfter(availableAlignmentSpace, style()); |
+ } |
+} |
+ |
GridAxisPosition LayoutGrid::columnAxisPositionForChild(const LayoutBox& child) const |
{ |
bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode(); |
@@ -1763,6 +1820,8 @@ LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const |
const GridCoordinate& coordinate = cachedGridCoordinate(child); |
LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPosition.toInt()]; |
LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); |
+ if (hasAutoMarginsInColumnAxis(child)) |
+ return startPosition; |
GridAxisPosition axisPosition = columnAxisPositionForChild(child); |
switch (axisPosition) { |
case GridAxisStart: |
@@ -1784,6 +1843,8 @@ LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const |
const GridCoordinate& coordinate = cachedGridCoordinate(child); |
LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInitialPosition.toInt()]; |
LayoutUnit startPosition = startOfColumn + marginStartForChild(child); |
+ if (hasAutoMarginsInRowAxis(child)) |
+ return startPosition; |
GridAxisPosition axisPosition = rowAxisPositionForChild(child); |
switch (axisPosition) { |
case GridAxisStart: |