| 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 2ce5335c7c952e25732ab4126a4289b13b10babe..755fb36ddc757dceb5a8cd6334d473663de8f2a5 100644
|
| --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
|
| @@ -691,6 +691,7 @@ void LayoutFlexibleBox::layoutFlexItems(bool relayoutChildren, SubtreeLayoutScop
|
| OrderedFlexItemList orderedChildren;
|
| LayoutUnit sumFlexBaseSize;
|
| double totalFlexGrow;
|
| + double totalFlexShrink;
|
| double totalWeightedFlexShrink;
|
| LayoutUnit sumHypotheticalMainSize;
|
|
|
| @@ -698,18 +699,22 @@ void LayoutFlexibleBox::layoutFlexItems(bool relayoutChildren, SubtreeLayoutScop
|
|
|
| m_orderIterator.first();
|
| LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore();
|
| - while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, totalWeightedFlexShrink, sumHypotheticalMainSize, relayoutChildren)) {
|
| + while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, sumHypotheticalMainSize, relayoutChildren)) {
|
| LayoutUnit containerMainInnerSize = mainAxisContentExtent(sumHypotheticalMainSize);
|
| + // availableFreeSpace is the initial amount of free space in this flexbox.
|
| + // remainingFreeSpace starts out at the same value but as we place and lay out
|
| + // flex items we subtract from it. Note that both values can be negative.
|
| LayoutUnit availableFreeSpace = containerMainInnerSize - sumFlexBaseSize;
|
| + LayoutUnit remainingFreeSpace = availableFreeSpace;
|
| FlexSign flexSign = (sumHypotheticalMainSize < containerMainInnerSize) ? PositiveFlexibility : NegativeFlexibility;
|
| InflexibleFlexItemSize inflexibleItems;
|
| childSizes.reserveCapacity(orderedChildren.size());
|
| - while (!resolveFlexibleLengths(flexSign, orderedChildren, availableFreeSpace, totalFlexGrow, totalWeightedFlexShrink, inflexibleItems, childSizes)) {
|
| + while (!resolveFlexibleLengths(flexSign, orderedChildren, availableFreeSpace, remainingFreeSpace, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, inflexibleItems, childSizes)) {
|
| ASSERT(totalFlexGrow >= 0 && totalWeightedFlexShrink >= 0);
|
| ASSERT(inflexibleItems.size() > 0);
|
| }
|
|
|
| - layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, availableFreeSpace, relayoutChildren, layoutScope, lineContexts);
|
| + layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, remainingFreeSpace, relayoutChildren, layoutScope, lineContexts);
|
| }
|
| if (hasLineIfEmpty()) {
|
| // Even if computeNextFlexLine returns true, the flexbox might not have
|
| @@ -927,11 +932,11 @@ LayoutUnit LayoutFlexibleBox::adjustChildSizeForMinAndMax(const LayoutBox& child
|
| return std::max(childSize, minExtent);
|
| }
|
|
|
| -bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool relayoutChildren)
|
| +bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool relayoutChildren)
|
| {
|
| orderedChildren.clear();
|
| sumFlexBaseSize = 0;
|
| - totalFlexGrow = totalWeightedFlexShrink = 0;
|
| + totalFlexGrow = totalFlexShrink = totalWeightedFlexShrink = 0;
|
| sumHypotheticalMainSize = 0;
|
|
|
| if (!m_orderIterator.currentChild())
|
| @@ -971,19 +976,21 @@ bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren
|
| lineHasInFlowItem = true;
|
| sumFlexBaseSize += childOuterFlexBaseSize;
|
| totalFlexGrow += child->style()->flexGrow();
|
| + totalFlexShrink += child->style()->flexShrink();
|
| totalWeightedFlexShrink += child->style()->flexShrink() * childInnerFlexBaseSize;
|
| sumHypotheticalMainSize += childHypotheticalMainSize;
|
| }
|
| return true;
|
| }
|
|
|
| -void LayoutFlexibleBox::freezeViolations(const Vector<Violation>& violations, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems)
|
| +void LayoutFlexibleBox::freezeViolations(const Vector<Violation>& violations, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems)
|
| {
|
| for (size_t i = 0; i < violations.size(); ++i) {
|
| LayoutBox* child = violations[i].child;
|
| LayoutUnit childSize = violations[i].childSize;
|
| availableFreeSpace -= childSize - violations[i].childInnerFlexBaseSize;
|
| totalFlexGrow -= child->style()->flexGrow();
|
| + totalFlexShrink -= child->style()->flexShrink();
|
| totalWeightedFlexShrink -= child->style()->flexShrink() * violations[i].childInnerFlexBaseSize;
|
| // totalWeightedFlexShrink can be negative when we exceed the precision of a double when we initially
|
| // calcuate totalWeightedFlexShrink. We then subtract each child's weighted flex shrink with full precision,
|
| @@ -994,13 +1001,21 @@ void LayoutFlexibleBox::freezeViolations(const Vector<Violation>& violations, La
|
| }
|
|
|
| // Returns true if we successfully ran the algorithm and sized the flex items.
|
| -bool LayoutFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, Vector<LayoutUnit, 16>& childSizes)
|
| +bool LayoutFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit availableFreeSpace, LayoutUnit& remainingFreeSpace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, Vector<LayoutUnit, 16>& childSizes)
|
| {
|
| childSizes.resize(0);
|
| LayoutUnit totalViolation = 0;
|
| LayoutUnit usedFreeSpace = 0;
|
| Vector<Violation> minViolations;
|
| Vector<Violation> maxViolations;
|
| +
|
| + double sumFlexFactors = (flexSign == PositiveFlexibility) ? totalFlexGrow : totalFlexShrink;
|
| + if (sumFlexFactors > 0 && sumFlexFactors < 1) {
|
| + LayoutUnit fractional = availableFreeSpace * sumFlexFactors;
|
| + if (fractional.abs() < remainingFreeSpace.abs())
|
| + remainingFreeSpace = fractional;
|
| + }
|
| +
|
| for (size_t i = 0; i < children.size(); ++i) {
|
| LayoutBox* child = children[i];
|
| if (child->isOutOfFlowPositioned()) {
|
| @@ -1014,13 +1029,10 @@ bool LayoutFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedF
|
| LayoutUnit childInnerFlexBaseSize = computeInnerFlexBaseSizeForChild(*child);
|
| LayoutUnit childSize = childInnerFlexBaseSize;
|
| double extraSpace = 0;
|
| - if (availableFreeSpace > 0 && totalFlexGrow > 0 && flexSign == PositiveFlexibility && std::isfinite(totalFlexGrow)) {
|
| - if (totalFlexGrow < 1)
|
| - extraSpace = availableFreeSpace * child->style()->flexGrow();
|
| - else
|
| - extraSpace = availableFreeSpace * child->style()->flexGrow() / totalFlexGrow;
|
| - } else if (availableFreeSpace < 0 && totalWeightedFlexShrink > 0 && flexSign == NegativeFlexibility && std::isfinite(totalWeightedFlexShrink) && child->style()->flexShrink()) {
|
| - extraSpace = availableFreeSpace * child->style()->flexShrink() * childInnerFlexBaseSize / totalWeightedFlexShrink;
|
| + if (remainingFreeSpace > 0 && totalFlexGrow > 0 && flexSign == PositiveFlexibility && std::isfinite(totalFlexGrow)) {
|
| + extraSpace = remainingFreeSpace * child->style()->flexGrow() / totalFlexGrow;
|
| + } else if (remainingFreeSpace < 0 && totalWeightedFlexShrink > 0 && flexSign == NegativeFlexibility && std::isfinite(totalWeightedFlexShrink) && child->style()->flexShrink()) {
|
| + extraSpace = remainingFreeSpace * child->style()->flexShrink() * childInnerFlexBaseSize / totalWeightedFlexShrink;
|
| }
|
| if (std::isfinite(extraSpace))
|
| childSize += LayoutUnit::fromFloatRound(extraSpace);
|
| @@ -1040,9 +1052,9 @@ bool LayoutFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedF
|
| }
|
|
|
| if (totalViolation)
|
| - freezeViolations(totalViolation < 0 ? maxViolations : minViolations, availableFreeSpace, totalFlexGrow, totalWeightedFlexShrink, inflexibleItems);
|
| + freezeViolations(totalViolation < 0 ? maxViolations : minViolations, remainingFreeSpace, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, inflexibleItems);
|
| else
|
| - availableFreeSpace -= usedFreeSpace;
|
| + remainingFreeSpace -= usedFreeSpace;
|
|
|
| return !totalViolation;
|
| }
|
|
|