Fix positioning of items with min/max width/height

We found a case where a flexible item with a max width that was supposed
to be centered was positioned in the wrong location.

The problem was with our 2 pass approach for sizing flexible items with
a min/max width/height. Items sized in the first pass were being double
counted when calculating the remainingFreeSpace. Specifically, their
sizes were being subtracted from remainingFreeSpace in both the first
and second passes.

I also noticed a second unrelated bug. We weren't correctly calculating
deltaFreeSpace in the first pass. When calculating deltaFreeSpace, we
need to take into account the flex basis like we do in the second pass.
Consequently, in the first pass I changed this:
  deltaFreeSpace -= boundMainSize;

To this:
  deltaFreeSpace -= boundMainSize - childFlexBasis;

The problem there was that we'd end up double counting childFlexBasis
in the remainingFreeSpace.
This commit is contained in:
Adam Comella
2016-04-28 17:07:34 -07:00
committed by Adam Comella
parent f3dd51ab97
commit 8779d942ea
13 changed files with 411 additions and 118 deletions

View File

@@ -916,7 +916,8 @@ var computeLayout = (function() {
remainingFreeSpace = -sizeConsumedOnCurrentLine;
}
var/*float*/ remainingFreeSpaceAfterFlex = remainingFreeSpace;
var/*float*/ originalRemainingFreeSpace = remainingFreeSpace;
var/*float*/ deltaFreeSpace = 0;
if (!canSkipFlex) {
var/*float*/ childFlexBasis;
@@ -939,7 +940,6 @@ var computeLayout = (function() {
// concerns because we know exactly how many passes it'll do.
// First pass: detect the flex items whose min/max constraints trigger
var/*float*/ deltaFreeSpace = 0;
var/*float*/ deltaFlexShrinkScaledFactors = 0;
var/*float*/ deltaFlexGrowFactors = 0;
currentRelativeChild = firstRelativeChild;
@@ -958,7 +958,7 @@ var computeLayout = (function() {
// By excluding this item's size and flex factor from remaining, this item's
// min/max constraints should also trigger in the second pass resulting in the
// item's size calculation being identical in the first and second passes.
deltaFreeSpace -= boundMainSize;
deltaFreeSpace -= boundMainSize - childFlexBasis;
deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor;
}
}
@@ -974,7 +974,7 @@ var computeLayout = (function() {
// By excluding this item's size and flex factor from remaining, this item's
// min/max constraints should also trigger in the second pass resulting in the
// item's size calculation being identical in the first and second passes.
deltaFreeSpace -= boundMainSize;
deltaFreeSpace -= boundMainSize - childFlexBasis;
deltaFlexGrowFactors -= flexGrowFactor;
}
}
@@ -986,9 +986,9 @@ var computeLayout = (function() {
totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors;
totalFlexGrowFactors += deltaFlexGrowFactors;
remainingFreeSpace += deltaFreeSpace;
remainingFreeSpaceAfterFlex = remainingFreeSpace;
// Second pass: resolve the sizes of the flexible items
deltaFreeSpace = 0;
currentRelativeChild = firstRelativeChild;
while (currentRelativeChild !== undefined) {
childFlexBasis = currentRelativeChild.layout.flexBasis;
@@ -1012,7 +1012,7 @@ var computeLayout = (function() {
}
}
remainingFreeSpaceAfterFlex -= updatedMainSize - childFlexBasis;
deltaFreeSpace -= updatedMainSize - childFlexBasis;
if (isMainAxisRow) {
childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW);
@@ -1048,7 +1048,7 @@ var computeLayout = (function() {
}
}
remainingFreeSpace = remainingFreeSpaceAfterFlex;
remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace;
// STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION