From 9c3970dd75490c95e16ad44ca5804c594d9b877c Mon Sep 17 00:00:00 2001 From: Emil Sjolander Date: Tue, 18 Oct 2016 09:19:22 -0700 Subject: [PATCH] Fix flex-shrink when shrinking to zero size Summary: Fix flex-shrink when shrinking to zero size Reviewed By: gkassabli Differential Revision: D4036345 fbshipit-source-id: f6848d7a316a694426f761d5e51d972bd379d90e --- CSSLayout/CSSLayout.c | 18 ++++++---- tests/CSSLayoutFlexTest.cpp | 72 +++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/CSSLayout/CSSLayout.c b/CSSLayout/CSSLayout.c index f28e0f5d..3d2e2717 100644 --- a/CSSLayout/CSSLayout.c +++ b/CSSLayout/CSSLayout.c @@ -1550,14 +1550,20 @@ static void layoutNodeImpl(const CSSNodeRef node, if (remainingFreeSpace < 0) { flexShrinkScaledFactor = -currentRelativeChild->style.flexShrink * childFlexBasis; - // Is this child able to shrink? if (flexShrinkScaledFactor != 0) { - updatedMainSize = boundAxis(currentRelativeChild, - mainAxis, - childFlexBasis + - remainingFreeSpace / totalFlexShrinkScaledFactors * - flexShrinkScaledFactor); + float childSize; + + if (totalFlexShrinkScaledFactors == 0) { + childSize = childFlexBasis + flexShrinkScaledFactor; + } else { + childSize = + childFlexBasis + + (remainingFreeSpace / totalFlexShrinkScaledFactors) * + flexShrinkScaledFactor; + } + + updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childSize); } } else if (remainingFreeSpace > 0) { flexGrowFactor = currentRelativeChild->style.flexGrow; diff --git a/tests/CSSLayoutFlexTest.cpp b/tests/CSSLayoutFlexTest.cpp index 402d5143..5ce2d618 100644 --- a/tests/CSSLayoutFlexTest.cpp +++ b/tests/CSSLayoutFlexTest.cpp @@ -29,6 +29,12 @@
+ +
+
+
+
+
* */ @@ -236,3 +242,69 @@ TEST(CSSLayoutTest, flex_basis_flex_shrink_row) { CSSNodeFreeRecursive(root); } + +TEST(CSSLayoutTest, flex_shrink_to_zero) { + const CSSNodeRef root = CSSNodeNew(); + CSSNodeStyleSetHeight(root, 75); + + const CSSNodeRef root_child0 = CSSNodeNew(); + CSSNodeStyleSetWidth(root_child0, 50); + CSSNodeStyleSetHeight(root_child0, 50); + CSSNodeInsertChild(root, root_child0, 0); + + const CSSNodeRef root_child1 = CSSNodeNew(); + CSSNodeStyleSetFlexShrink(root_child1, 1); + CSSNodeStyleSetWidth(root_child1, 50); + CSSNodeStyleSetHeight(root_child1, 50); + CSSNodeInsertChild(root, root_child1, 1); + + const CSSNodeRef root_child2 = CSSNodeNew(); + CSSNodeStyleSetWidth(root_child2, 50); + CSSNodeStyleSetHeight(root_child2, 50); + CSSNodeInsertChild(root, root_child2, 2); + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(75, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1)); + ASSERT_EQ(50, CSSNodeLayoutGetTop(root_child1)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child1)); + ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child1)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child2)); + ASSERT_EQ(50, CSSNodeLayoutGetTop(root_child2)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child2)); + ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child2)); + + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(75, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1)); + ASSERT_EQ(50, CSSNodeLayoutGetTop(root_child1)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child1)); + ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child1)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child2)); + ASSERT_EQ(50, CSSNodeLayoutGetTop(root_child2)); + ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child2)); + ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child2)); + + CSSNodeFreeRecursive(root); +}