diff --git a/csharp/tests/Facebook.Yoga/YGPercentageTest.cs b/csharp/tests/Facebook.Yoga/YGPercentageTest.cs index bbbff024..d35427e1 100644 --- a/csharp/tests/Facebook.Yoga/YGPercentageTest.cs +++ b/csharp/tests/Facebook.Yoga/YGPercentageTest.cs @@ -991,5 +991,85 @@ namespace Facebook.Yoga Assert.AreEqual(0f, root_child0.LayoutHeight); } + [Test] + public void Test_percent_within_flex_grow() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.Width = 350; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 100; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.FlexGrow = 1; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 100.Percent(); + root_child1.Insert(0, root_child1_child0); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 100; + root.Insert(2, root_child2); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(350f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(100f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(100f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(150f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(150f, root_child1_child0.LayoutWidth); + Assert.AreEqual(0f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(250f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(100f, root_child2.LayoutWidth); + Assert.AreEqual(100f, root_child2.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(350f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(250f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(100f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(100f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(150f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(150f, root_child1_child0.LayoutWidth); + Assert.AreEqual(0f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(100f, root_child2.LayoutWidth); + Assert.AreEqual(100f, root_child2.LayoutHeight); + } + } } diff --git a/gentest/fixtures/YGPercentageTest.html b/gentest/fixtures/YGPercentageTest.html index 5d09d77c..d86b04e7 100644 --- a/gentest/fixtures/YGPercentageTest.html +++ b/gentest/fixtures/YGPercentageTest.html @@ -83,3 +83,11 @@
+ +
+
+
+
+
+
+
\ No newline at end of file diff --git a/java/tests/com/facebook/yoga/YGPercentageTest.java b/java/tests/com/facebook/yoga/YGPercentageTest.java index f43ccb6b..8da5322f 100644 --- a/java/tests/com/facebook/yoga/YGPercentageTest.java +++ b/java/tests/com/facebook/yoga/YGPercentageTest.java @@ -973,4 +973,83 @@ public class YGPercentageTest { assertEquals(0f, root_child0.getLayoutHeight(), 0.0f); } + @Test + public void test_percent_within_flex_grow() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setWidth(350f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(100f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setFlexGrow(1f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidthPercent(100f); + root_child1.addChildAt(root_child1_child0, 0); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(100f); + root.addChildAt(root_child2, 2); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(350f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(100f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(150f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(150f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(250f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(100f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child2.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(350f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(250f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(100f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(150f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(150f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(100f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child2.getLayoutHeight(), 0.0f); + } + } diff --git a/javascript/tests/Facebook.Yoga/YGPercentageTest.js b/javascript/tests/Facebook.Yoga/YGPercentageTest.js index 5f7808bb..51efcdcc 100644 --- a/javascript/tests/Facebook.Yoga/YGPercentageTest.js +++ b/javascript/tests/Facebook.Yoga/YGPercentageTest.js @@ -1002,3 +1002,84 @@ it("percentage_width_height_undefined_parent_size", function () { } } }); +it("percent_within_flex_grow", function () { + try { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setWidth(350); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(100); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setFlexGrow(1); + root.insertChild(root_child1, 1); + + var root_child1_child0 = Yoga.Node.create(); + root_child1_child0.setWidth("100%"); + root_child1.insertChild(root_child1_child0, 0); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(100); + root.insertChild(root_child2, 2); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(350 === root.getComputedWidth(), "350 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(100 === root_child0.getComputedWidth(), "100 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(100 === root_child1.getComputedLeft(), "100 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(150 === root_child1.getComputedWidth(), "150 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child1_child0.getComputedLeft(), "0 === root_child1_child0.getComputedLeft() (" + root_child1_child0.getComputedLeft() + ")"); + console.assert(0 === root_child1_child0.getComputedTop(), "0 === root_child1_child0.getComputedTop() (" + root_child1_child0.getComputedTop() + ")"); + console.assert(150 === root_child1_child0.getComputedWidth(), "150 === root_child1_child0.getComputedWidth() (" + root_child1_child0.getComputedWidth() + ")"); + console.assert(0 === root_child1_child0.getComputedHeight(), "0 === root_child1_child0.getComputedHeight() (" + root_child1_child0.getComputedHeight() + ")"); + + console.assert(250 === root_child2.getComputedLeft(), "250 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(100 === root_child2.getComputedWidth(), "100 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(100 === root_child2.getComputedHeight(), "100 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(350 === root.getComputedWidth(), "350 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(250 === root_child0.getComputedLeft(), "250 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(100 === root_child0.getComputedWidth(), "100 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(100 === root_child1.getComputedLeft(), "100 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(150 === root_child1.getComputedWidth(), "150 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child1_child0.getComputedLeft(), "0 === root_child1_child0.getComputedLeft() (" + root_child1_child0.getComputedLeft() + ")"); + console.assert(0 === root_child1_child0.getComputedTop(), "0 === root_child1_child0.getComputedTop() (" + root_child1_child0.getComputedTop() + ")"); + console.assert(150 === root_child1_child0.getComputedWidth(), "150 === root_child1_child0.getComputedWidth() (" + root_child1_child0.getComputedWidth() + ")"); + console.assert(0 === root_child1_child0.getComputedHeight(), "0 === root_child1_child0.getComputedHeight() (" + root_child1_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(100 === root_child2.getComputedWidth(), "100 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(100 === root_child2.getComputedHeight(), "100 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + } finally { + if (typeof root !== "undefined") { + root.freeRecursive(); + } + } +}); diff --git a/tests/YGPercentageTest.cpp b/tests/YGPercentageTest.cpp index baa4b677..cbfb1e89 100644 --- a/tests/YGPercentageTest.cpp +++ b/tests/YGPercentageTest.cpp @@ -951,3 +951,81 @@ TEST(YogaTest, percentage_width_height_undefined_parent_size) { YGNodeFreeRecursive(root); } + +TEST(YogaTest, percent_within_flex_grow) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 350); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidthPercent(root_child1_child0, 100); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(350, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(350, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); +} diff --git a/yoga/Yoga.c b/yoga/Yoga.c index 074fd01c..a67b33d0 100644 --- a/yoga/Yoga.c +++ b/yoga/Yoga.c @@ -2045,7 +2045,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, } const bool flexBasisOverflows = - measureModeMainDim == YGMeasureModeUndefined ? false : totalFlexBasis > availableInnerMainDim; + measureModeMainDim == YGMeasureModeUndefined ? false : totalFlexBasis > availableInnerMainDim; if (isNodeFlexWrap && flexBasisOverflows && measureModeMainDim == YGMeasureModeAtMost) { measureModeMainDim = YGMeasureModeExactly; } @@ -2338,8 +2338,12 @@ static void YGNodelayoutImpl(const YGNodeRef node, childCrossSize = YGValueResolve(currentRelativeChild->resolvedDimensions[dim[crossAxis]], availableInnerCrossDim) + marginCross; - childCrossMeasureMode = - YGFloatIsUndefined(childCrossSize) ? YGMeasureModeUndefined : YGMeasureModeExactly; + const bool isLoosePercentageMeasurement = + currentRelativeChild->resolvedDimensions[dim[crossAxis]]->unit == YGUnitPercent && + measureModeCrossDim != YGMeasureModeExactly; + childCrossMeasureMode = YGFloatIsUndefined(childCrossSize) || isLoosePercentageMeasurement + ? YGMeasureModeUndefined + : YGMeasureModeExactly; } if (!YGFloatIsUndefined(currentRelativeChild->style.aspectRatio)) {