diff --git a/csharp/tests/Facebook.Yoga/YGPercentageTest.cs b/csharp/tests/Facebook.Yoga/YGPercentageTest.cs
index 251ce823..bbbff024 100644
--- a/csharp/tests/Facebook.Yoga/YGPercentageTest.cs
+++ b/csharp/tests/Facebook.Yoga/YGPercentageTest.cs
@@ -955,5 +955,41 @@ namespace Facebook.Yoga
YogaNode.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, false);
}
+ [Test]
+ public void Test_percentage_width_height_undefined_parent_size()
+ {
+ YogaNode root = new YogaNode();
+
+ YogaNode root_child0 = new YogaNode();
+ root_child0.Width = 50.Percent();
+ root_child0.Height = 50.Percent();
+ root.Insert(0, root_child0);
+ root.StyleDirection = YogaDirection.LTR;
+ root.CalculateLayout();
+
+ Assert.AreEqual(0f, root.LayoutX);
+ Assert.AreEqual(0f, root.LayoutY);
+ Assert.AreEqual(0f, root.LayoutWidth);
+ Assert.AreEqual(0f, root.LayoutHeight);
+
+ Assert.AreEqual(0f, root_child0.LayoutX);
+ Assert.AreEqual(0f, root_child0.LayoutY);
+ Assert.AreEqual(0f, root_child0.LayoutWidth);
+ Assert.AreEqual(0f, root_child0.LayoutHeight);
+
+ root.StyleDirection = YogaDirection.RTL;
+ root.CalculateLayout();
+
+ Assert.AreEqual(0f, root.LayoutX);
+ Assert.AreEqual(0f, root.LayoutY);
+ Assert.AreEqual(0f, root.LayoutWidth);
+ Assert.AreEqual(0f, root.LayoutHeight);
+
+ Assert.AreEqual(0f, root_child0.LayoutX);
+ Assert.AreEqual(0f, root_child0.LayoutY);
+ Assert.AreEqual(0f, root_child0.LayoutWidth);
+ Assert.AreEqual(0f, root_child0.LayoutHeight);
+ }
+
}
}
diff --git a/gentest/fixtures/YGPercentageTest.html b/gentest/fixtures/YGPercentageTest.html
index 1aa99012..5d09d77c 100644
--- a/gentest/fixtures/YGPercentageTest.html
+++ b/gentest/fixtures/YGPercentageTest.html
@@ -79,3 +79,7 @@
+
+
diff --git a/java/tests/com/facebook/yoga/YGPercentageTest.java b/java/tests/com/facebook/yoga/YGPercentageTest.java
index c04a34dc..f87981ca 100644
--- a/java/tests/com/facebook/yoga/YGPercentageTest.java
+++ b/java/tests/com/facebook/yoga/YGPercentageTest.java
@@ -938,4 +938,39 @@ public class YGPercentageTest {
YogaNode.setExperimentalFeatureEnabled(YogaExperimentalFeature.ROUNDING, false);
}
+ @Test
+ public void test_percentage_width_height_undefined_parent_size() {
+ final YogaNode root = new YogaNode();
+
+ final YogaNode root_child0 = new YogaNode();
+ root_child0.setWidthPercent(50f);
+ root_child0.setHeightPercent(50f);
+ root.addChildAt(root_child0, 0);
+ root.setDirection(YogaDirection.LTR);
+ root.calculateLayout();
+
+ assertEquals(0f, root.getLayoutX(), 0.0f);
+ assertEquals(0f, root.getLayoutY(), 0.0f);
+ assertEquals(0f, root.getLayoutWidth(), 0.0f);
+ assertEquals(0f, root.getLayoutHeight(), 0.0f);
+
+ assertEquals(0f, root_child0.getLayoutX(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutY(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutWidth(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
+
+ root.setDirection(YogaDirection.RTL);
+ root.calculateLayout();
+
+ assertEquals(0f, root.getLayoutX(), 0.0f);
+ assertEquals(0f, root.getLayoutY(), 0.0f);
+ assertEquals(0f, root.getLayoutWidth(), 0.0f);
+ assertEquals(0f, root.getLayoutHeight(), 0.0f);
+
+ assertEquals(0f, root_child0.getLayoutX(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutY(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutWidth(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
+ }
+
}
diff --git a/javascript/tests/Facebook.Yoga/YGPercentageTest.js b/javascript/tests/Facebook.Yoga/YGPercentageTest.js
index 615cb905..3b8d5d44 100644
--- a/javascript/tests/Facebook.Yoga/YGPercentageTest.js
+++ b/javascript/tests/Facebook.Yoga/YGPercentageTest.js
@@ -965,3 +965,40 @@ it("percentage_absolute_position", function () {
Yoga.setExperimentalFeatureEnabled(Yoga.FEATURE_ROUNDING, false);
});
+it("percentage_width_height_undefined_parent_size", function () {
+ var root = Yoga.Node.create();
+
+ var root_child0 = Yoga.Node.create();
+ root_child0.setWidth("50%");
+ root_child0.setHeight("50%");
+ root.insertChild(root_child0, 0);
+ 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(0 === root.getComputedWidth(), "0 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
+ console.assert(0 === root.getComputedHeight(), "0 === 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(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
+ console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.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(0 === root.getComputedWidth(), "0 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
+ console.assert(0 === root.getComputedHeight(), "0 === 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(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
+ console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
+
+ if (typeof root !== "undefined")
+ root.freeRecursive();
+
+ (typeof gc !== "undefined") && gc();
+ console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")");
+});
diff --git a/tests/YGPercentageTest.cpp b/tests/YGPercentageTest.cpp
index b29e6a63..baa4b677 100644
--- a/tests/YGPercentageTest.cpp
+++ b/tests/YGPercentageTest.cpp
@@ -917,3 +917,37 @@ TEST(YogaTest, percentage_absolute_position) {
YGSetExperimentalFeatureEnabled(YGExperimentalFeatureRounding, false);
}
+
+TEST(YogaTest, percentage_width_height_undefined_parent_size) {
+ const YGNodeRef root = YGNodeNew();
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetWidthPercent(root_child0, 50);
+ YGNodeStyleSetHeightPercent(root_child0, 50);
+ YGNodeInsertChild(root, root_child0, 0);
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeFreeRecursive(root);
+}
diff --git a/yoga/Yoga.c b/yoga/Yoga.c
index 1163e870..c476b47d 100644
--- a/yoga/Yoga.c
+++ b/yoga/Yoga.c
@@ -256,12 +256,16 @@ static inline const YGValue *YGComputedEdgeValue(const YGValue edges[YGEdgeCount
return defaultValue;
}
-static inline float YGValueResolve(const YGValue *const unit, const float parentSize) {
- if (unit->unit == YGUnitPixel) {
- return unit->value;
- } else {
- return unit->value * parentSize / 100.0f;
+static inline float YGValueResolve(const YGValue *const value, const float parentSize) {
+ switch (value->unit) {
+ case YGUnitUndefined:
+ return YGUndefined;
+ case YGUnitPixel:
+ return value->value;
+ case YGUnitPercent:
+ return value->value * parentSize / 100.0f;
}
+ return YGUndefined;
}
int32_t gNodeInstanceCount = 0;
@@ -2253,7 +2257,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
childHeight = YGValueResolve(¤tRelativeChild->style.dimensions[YGDimensionHeight],
availableInnerHeight) +
marginColumn;
- childHeightMeasureMode = YGMeasureModeExactly;
+ childHeightMeasureMode =
+ YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined : YGMeasureModeExactly;
}
} else {
childHeight = updatedMainSize + marginColumn;
@@ -2277,7 +2282,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
childWidth = YGValueResolve(¤tRelativeChild->style.dimensions[YGDimensionWidth],
availableInnerWidth) +
marginRow;
- childWidthMeasureMode = YGMeasureModeExactly;
+ childWidthMeasureMode =
+ YGFloatIsUndefined(childWidth) ? YGMeasureModeUndefined : YGMeasureModeExactly;
}
}