Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp |
| diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp |
| index b517444e81864051b7b341e750143b5522341242..5a8aa056b0ca68ef2865584c8243c99fdade4762 100644 |
| --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp |
| +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp |
| @@ -269,6 +269,8 @@ void LayoutFlexibleBox::layoutBlock(bool relayoutChildren) |
| if (!relayoutChildren && simplifiedLayout()) |
| return; |
| + m_relaidOutChildren.clear(); |
| + |
| if (updateLogicalWidthAndColumnWidth()) |
| relayoutChildren = true; |
| @@ -736,6 +738,7 @@ void LayoutFlexibleBox::cacheChildMainSize(const LayoutBox& child) |
| mainSize = child.maxPreferredLogicalWidth() + child.scrollbarLogicalWidth() - child.intrinsicScrollbarLogicalWidth(); |
| } |
| m_intrinsicSizeAlongMainAxis.set(&child, mainSize); |
| + m_relaidOutChildren.add(&child); |
| } |
| void LayoutFlexibleBox::clearCachedMainSizeForChild(const LayoutBox& child) |
| @@ -787,6 +790,8 @@ void LayoutFlexibleBox::layoutFlexItems(bool relayoutChildren, SubtreeLayoutScop |
| Vector<LayoutUnit, 16> childSizes; |
| + dirtyForLayoutFromPercentageHeightDescendants(layoutScope); |
|
leviw_travelin_and_unemployed
2016/04/13 20:10:22
Why this change? Is it necessary?
|
| + |
| m_orderIterator.first(); |
| LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore(); |
| while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, sumHypotheticalMainSize, relayoutChildren)) { |
| @@ -1067,37 +1072,20 @@ LayoutUnit LayoutFlexibleBox::computeDefiniteLogicalHeight() |
| LayoutUnit LayoutFlexibleBox::crossSizeForPercentageResolution(const LayoutBox& child) |
| { |
| - // This function implements section 9.8. Definite and Indefinite Sizes, case |
| - // 1) of the flexbox spec. |
| - // We need to check for multiline and a definite cross size of the flexbox |
| - // per https://drafts.csswg.org/css-flexbox/#definite-sizes, and for |
| - // stretch, auto margins, and an indefinite cross size of the flex item per |
| - // https://drafts.csswg.org/css-flexbox/#stretched (linked from that |
| - // section) |
| - if (isMultiline() || alignmentForChild(child) != ItemPositionStretch || hasAutoMarginsInCrossAxis(child)) |
| - return LayoutUnit(-1); |
| - |
| - const Length& childCrossLength = isHorizontalFlow() ? child.styleRef().height() : child.styleRef().width(); |
| - if (crossAxisLengthIsDefinite(child, childCrossLength)) |
| + if (alignmentForChild(child) != ItemPositionStretch) |
| return LayoutUnit(-1); |
| - LayoutUnit childCrossSize; |
| + // Here we implement https://drafts.csswg.org/css-flexbox/#algo-stretch |
| + if (hasOrthogonalFlow(child) && child.hasOverrideLogicalContentWidth()) |
| + return child.overrideLogicalContentWidth(); |
| + if (!hasOrthogonalFlow(child) && child.hasOverrideLogicalContentHeight()) |
| + return child.overrideLogicalContentHeight(); |
| - if (isColumnFlow()) { |
| - LayoutUnit definiteWidth = computeDefiniteLogicalWidth(); |
| - if (definiteWidth == LayoutUnit(-1)) |
| - return definiteWidth; |
| - childCrossSize = definiteWidth - borderAndPaddingLogicalWidth() - scrollbarLogicalWidth(); |
| - childCrossSize = child.constrainLogicalWidthByMinMax(childCrossSize, childCrossSize, this) - child.scrollbarLogicalWidth() - child.borderAndPaddingLogicalWidth(); |
| - } else { |
| - LayoutUnit definiteHeight = computeDefiniteLogicalHeight(); |
| - if (definiteHeight == LayoutUnit(-1)) |
| - return definiteHeight; |
| - |
| - childCrossSize = definiteHeight - borderAndPaddingLogicalHeight() - scrollbarLogicalHeight(); |
| - childCrossSize = child.constrainLogicalHeightByMinMax(childCrossSize, LayoutUnit(-1)) - child.scrollbarLogicalHeight() - child.borderAndPaddingLogicalHeight(); |
| - } |
| - return childCrossSize; |
| + // We don't currently implement the optimization from https://drafts.csswg.org/css-flexbox/#definite-sizes |
| + // case 1. While that could speed up a specialized case, it requires determining if we have a definite |
| + // size, which itself is not cheap. We can consider implementing it at a later time. |
| + // (The correctness is ensured by redoing layout in applyStretchAlignmentToChild) |
| + return LayoutUnit(-1); |
| } |
| LayoutUnit LayoutFlexibleBox::mainSizeForPercentageResolution(const LayoutBox& child) |
| @@ -1458,11 +1446,6 @@ void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons |
| LayoutUnit childPreferredSize = childSizes[i] + mainAxisBorderAndPaddingExtentForChild(*child); |
| setOverrideMainAxisSizeForChild(*child, childPreferredSize); |
| if (childPreferredSize != mainAxisExtentForChild(*child)) { |
| - // We will correctly handle percentage sizing even without re-laying out here, because |
| - // if our size was already correct, then percentage resolution was also correct due |
| - // to the way percentage sizing is defined by flexbox (ie. it requires a definite flex basis) |
| - // TODO(cbiesinger): When flex-basis is used instead of width/height, this is not the case. That |
| - // problem is not limited to percentages. See http://crbug.com/531656#c11 |
| child->setChildNeedsLayout(MarkOnlyThis); |
| } else { |
| // To avoid double applying margin changes in updateAutoMarginsInCrossAxis, we reset the margins here. |
| @@ -1470,9 +1453,17 @@ void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons |
| } |
| // We may have already forced relayout for orthogonal flowing children in computeInnerFlexBaseSizeForChild. |
| bool forceChildRelayout = relayoutChildren && !childFlexBaseSizeRequiresLayout(*child); |
| + if (child->isLayoutBlock() && toLayoutBlock(*child).hasPercentHeightDescendants() && m_relaidOutChildren.contains(child)) { |
| + // Have to force another relayout even though the child is sized correctly, because |
| + // its descendants are not sized correctly yet. Our previous layout of the child was |
| + // done without an override height set. So, redo it here. |
| + forceChildRelayout = true; |
| + } |
| updateBlockChildDirtyBitsBeforeLayout(forceChildRelayout, *child); |
| if (!child->needsLayout()) |
| child->markForPaginationRelayoutIfNeeded(layoutScope); |
| + if (child->needsLayout()) |
| + m_relaidOutChildren.add(child); |
| child->layoutIfNeeded(); |
| updateAutoMarginsInMainAxis(*child, autoMarginOffset); |
| @@ -1730,6 +1721,12 @@ void LayoutFlexibleBox::applyStretchAlignmentToChild(LayoutBox& child, LayoutUni |
| // FIXME: Can avoid laying out here in some cases. See https://webkit.org/b/87905. |
| bool childNeedsRelayout = desiredLogicalHeight != child.logicalHeight(); |
| + if (child.isLayoutBlock() && toLayoutBlock(child).hasPercentHeightDescendants() && m_relaidOutChildren.contains(&child)) { |
| + // Have to force another relayout even though the child is sized correctly, because |
| + // its descendants are not sized correctly yet. Our previous layout of the child was |
| + // done without an override height set. So, redo it here. |
| + childNeedsRelayout = true; |
| + } |
| if (childNeedsRelayout || !child.hasOverrideLogicalContentHeight()) |
| child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.borderAndPaddingLogicalHeight()); |
| if (childNeedsRelayout) { |