Skip to content

Commit ca2c607

Browse files
woehrl01facebook-github-bot
authored andcommitted
The total flex factores need to be a minimum of 1 if any
Summary: The only thing I found in the spec for this change is the following. Not exactly sure if this is the thing this PR is about: > For each flex item, subtract its outer flex base size from its max-content contribution size. If that result is not zero, divide it by (if the result was positive) its **flex grow factor floored at 1** or (if the result was negative) by its scaled flex shrink factor, having **floored the flex shrink factor at 1**. This is the item’s max-content flex fraction. But at least it seems a required change. Fixes #566 Closes #572 Differential Revision: D5264388 Pulled By: emilsjolander fbshipit-source-id: 0004d1c3b9bad070a98cd6766c1adc06a54475f8
1 parent 6c67684 commit ca2c607

File tree

6 files changed

+290
-0
lines changed

6 files changed

+290
-0
lines changed

csharp/tests/Facebook.Yoga/YGFlexTest.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,5 +429,73 @@ public void Test_flex_grow_shrink_at_most()
429429
Assert.AreEqual(0f, root_child0_child0.LayoutHeight);
430430
}
431431

432+
[Test]
433+
public void Test_flex_grow_less_than_factor_one()
434+
{
435+
YogaConfig config = new YogaConfig();
436+
437+
YogaNode root = new YogaNode(config);
438+
root.Width = 200;
439+
root.Height = 500;
440+
441+
YogaNode root_child0 = new YogaNode(config);
442+
root_child0.FlexGrow = 0.2f;
443+
root_child0.FlexBasis = 40;
444+
root.Insert(0, root_child0);
445+
446+
YogaNode root_child1 = new YogaNode(config);
447+
root_child1.FlexGrow = 0.2f;
448+
root.Insert(1, root_child1);
449+
450+
YogaNode root_child2 = new YogaNode(config);
451+
root_child2.FlexGrow = 0.4f;
452+
root.Insert(2, root_child2);
453+
root.StyleDirection = YogaDirection.LTR;
454+
root.CalculateLayout();
455+
456+
Assert.AreEqual(0f, root.LayoutX);
457+
Assert.AreEqual(0f, root.LayoutY);
458+
Assert.AreEqual(200f, root.LayoutWidth);
459+
Assert.AreEqual(500f, root.LayoutHeight);
460+
461+
Assert.AreEqual(0f, root_child0.LayoutX);
462+
Assert.AreEqual(0f, root_child0.LayoutY);
463+
Assert.AreEqual(200f, root_child0.LayoutWidth);
464+
Assert.AreEqual(132f, root_child0.LayoutHeight);
465+
466+
Assert.AreEqual(0f, root_child1.LayoutX);
467+
Assert.AreEqual(132f, root_child1.LayoutY);
468+
Assert.AreEqual(200f, root_child1.LayoutWidth);
469+
Assert.AreEqual(92f, root_child1.LayoutHeight);
470+
471+
Assert.AreEqual(0f, root_child2.LayoutX);
472+
Assert.AreEqual(224f, root_child2.LayoutY);
473+
Assert.AreEqual(200f, root_child2.LayoutWidth);
474+
Assert.AreEqual(184f, root_child2.LayoutHeight);
475+
476+
root.StyleDirection = YogaDirection.RTL;
477+
root.CalculateLayout();
478+
479+
Assert.AreEqual(0f, root.LayoutX);
480+
Assert.AreEqual(0f, root.LayoutY);
481+
Assert.AreEqual(200f, root.LayoutWidth);
482+
Assert.AreEqual(500f, root.LayoutHeight);
483+
484+
Assert.AreEqual(0f, root_child0.LayoutX);
485+
Assert.AreEqual(0f, root_child0.LayoutY);
486+
Assert.AreEqual(200f, root_child0.LayoutWidth);
487+
Assert.AreEqual(132f, root_child0.LayoutHeight);
488+
489+
Assert.AreEqual(0f, root_child1.LayoutX);
490+
Assert.AreEqual(132f, root_child1.LayoutY);
491+
Assert.AreEqual(200f, root_child1.LayoutWidth);
492+
Assert.AreEqual(92f, root_child1.LayoutHeight);
493+
494+
Assert.AreEqual(0f, root_child2.LayoutX);
495+
Assert.AreEqual(224f, root_child2.LayoutY);
496+
Assert.AreEqual(200f, root_child2.LayoutWidth);
497+
Assert.AreEqual(184f, root_child2.LayoutHeight);
498+
}
499+
432500
}
433501
}

gentest/fixtures/YGFlexTest.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,9 @@
3535
<div style="flex-grow:1; flex-shrink:1;"></div>
3636
</div>
3737
</div>
38+
39+
<div id="flex_grow_less_than_factor_one" style="height: 500px; width: 200px; flex-direction:column;">
40+
<div style="flex-grow:0.2; flex-shrink:0; flex-basis: 40px;"></div>
41+
<div style="flex-grow:0.2; flex-shrink:0;"></div>
42+
<div style="flex-grow:0.4; flex-shrink:0;"></div>
43+
</div>

java/tests/com/facebook/yoga/YGFlexTest.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,4 +421,71 @@ public void test_flex_grow_shrink_at_most() {
421421
assertEquals(0f, root_child0_child0.getLayoutHeight(), 0.0f);
422422
}
423423

424+
@Test
425+
public void test_flex_grow_less_than_factor_one() {
426+
YogaConfig config = new YogaConfig();
427+
428+
final YogaNode root = new YogaNode(config);
429+
root.setWidth(200f);
430+
root.setHeight(500f);
431+
432+
final YogaNode root_child0 = new YogaNode(config);
433+
root_child0.setFlexGrow(0.2f);
434+
root_child0.setFlexBasis(40f);
435+
root.addChildAt(root_child0, 0);
436+
437+
final YogaNode root_child1 = new YogaNode(config);
438+
root_child1.setFlexGrow(0.2f);
439+
root.addChildAt(root_child1, 1);
440+
441+
final YogaNode root_child2 = new YogaNode(config);
442+
root_child2.setFlexGrow(0.4f);
443+
root.addChildAt(root_child2, 2);
444+
root.setDirection(YogaDirection.LTR);
445+
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
446+
447+
assertEquals(0f, root.getLayoutX(), 0.0f);
448+
assertEquals(0f, root.getLayoutY(), 0.0f);
449+
assertEquals(200f, root.getLayoutWidth(), 0.0f);
450+
assertEquals(500f, root.getLayoutHeight(), 0.0f);
451+
452+
assertEquals(0f, root_child0.getLayoutX(), 0.0f);
453+
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
454+
assertEquals(200f, root_child0.getLayoutWidth(), 0.0f);
455+
assertEquals(132f, root_child0.getLayoutHeight(), 0.0f);
456+
457+
assertEquals(0f, root_child1.getLayoutX(), 0.0f);
458+
assertEquals(132f, root_child1.getLayoutY(), 0.0f);
459+
assertEquals(200f, root_child1.getLayoutWidth(), 0.0f);
460+
assertEquals(92f, root_child1.getLayoutHeight(), 0.0f);
461+
462+
assertEquals(0f, root_child2.getLayoutX(), 0.0f);
463+
assertEquals(224f, root_child2.getLayoutY(), 0.0f);
464+
assertEquals(200f, root_child2.getLayoutWidth(), 0.0f);
465+
assertEquals(184f, root_child2.getLayoutHeight(), 0.0f);
466+
467+
root.setDirection(YogaDirection.RTL);
468+
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
469+
470+
assertEquals(0f, root.getLayoutX(), 0.0f);
471+
assertEquals(0f, root.getLayoutY(), 0.0f);
472+
assertEquals(200f, root.getLayoutWidth(), 0.0f);
473+
assertEquals(500f, root.getLayoutHeight(), 0.0f);
474+
475+
assertEquals(0f, root_child0.getLayoutX(), 0.0f);
476+
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
477+
assertEquals(200f, root_child0.getLayoutWidth(), 0.0f);
478+
assertEquals(132f, root_child0.getLayoutHeight(), 0.0f);
479+
480+
assertEquals(0f, root_child1.getLayoutX(), 0.0f);
481+
assertEquals(132f, root_child1.getLayoutY(), 0.0f);
482+
assertEquals(200f, root_child1.getLayoutWidth(), 0.0f);
483+
assertEquals(92f, root_child1.getLayoutHeight(), 0.0f);
484+
485+
assertEquals(0f, root_child2.getLayoutX(), 0.0f);
486+
assertEquals(224f, root_child2.getLayoutY(), 0.0f);
487+
assertEquals(200f, root_child2.getLayoutWidth(), 0.0f);
488+
assertEquals(184f, root_child2.getLayoutHeight(), 0.0f);
489+
}
490+
424491
}

javascript/tests/Facebook.Yoga/YGFlexTest.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,3 +444,74 @@ it("flex_grow_shrink_at_most", function () {
444444
config.free();
445445
}
446446
});
447+
it("flex_grow_less_than_factor_one", function () {
448+
var config = Yoga.Config.create();
449+
450+
try {
451+
var root = Yoga.Node.create(config);
452+
root.setWidth(200);
453+
root.setHeight(500);
454+
455+
var root_child0 = Yoga.Node.create(config);
456+
root_child0.setFlexGrow(0.2);
457+
root_child0.setFlexBasis(40);
458+
root.insertChild(root_child0, 0);
459+
460+
var root_child1 = Yoga.Node.create(config);
461+
root_child1.setFlexGrow(0.2);
462+
root.insertChild(root_child1, 1);
463+
464+
var root_child2 = Yoga.Node.create(config);
465+
root_child2.setFlexGrow(0.4);
466+
root.insertChild(root_child2, 2);
467+
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR);
468+
469+
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
470+
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
471+
console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
472+
console.assert(500 === root.getComputedHeight(), "500 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
473+
474+
console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
475+
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
476+
console.assert(200 === root_child0.getComputedWidth(), "200 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
477+
console.assert(132 === root_child0.getComputedHeight(), "132 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
478+
479+
console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")");
480+
console.assert(132 === root_child1.getComputedTop(), "132 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")");
481+
console.assert(200 === root_child1.getComputedWidth(), "200 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")");
482+
console.assert(92 === root_child1.getComputedHeight(), "92 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")");
483+
484+
console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")");
485+
console.assert(224 === root_child2.getComputedTop(), "224 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")");
486+
console.assert(200 === root_child2.getComputedWidth(), "200 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")");
487+
console.assert(184 === root_child2.getComputedHeight(), "184 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")");
488+
489+
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL);
490+
491+
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
492+
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
493+
console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
494+
console.assert(500 === root.getComputedHeight(), "500 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
495+
496+
console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
497+
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
498+
console.assert(200 === root_child0.getComputedWidth(), "200 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
499+
console.assert(132 === root_child0.getComputedHeight(), "132 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
500+
501+
console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")");
502+
console.assert(132 === root_child1.getComputedTop(), "132 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")");
503+
console.assert(200 === root_child1.getComputedWidth(), "200 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")");
504+
console.assert(92 === root_child1.getComputedHeight(), "92 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")");
505+
506+
console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")");
507+
console.assert(224 === root_child2.getComputedTop(), "224 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")");
508+
console.assert(200 === root_child2.getComputedWidth(), "200 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")");
509+
console.assert(184 === root_child2.getComputedHeight(), "184 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")");
510+
} finally {
511+
if (typeof root !== "undefined") {
512+
root.freeRecursive();
513+
}
514+
515+
config.free();
516+
}
517+
});

tests/YGFlexTest.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,3 +423,71 @@ TEST(YogaTest, flex_grow_shrink_at_most) {
423423

424424
YGConfigFree(config);
425425
}
426+
427+
TEST(YogaTest, flex_grow_less_than_factor_one) {
428+
const YGConfigRef config = YGConfigNew();
429+
430+
const YGNodeRef root = YGNodeNewWithConfig(config);
431+
YGNodeStyleSetWidth(root, 200);
432+
YGNodeStyleSetHeight(root, 500);
433+
434+
const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
435+
YGNodeStyleSetFlexGrow(root_child0, 0.2f);
436+
YGNodeStyleSetFlexBasis(root_child0, 40);
437+
YGNodeInsertChild(root, root_child0, 0);
438+
439+
const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
440+
YGNodeStyleSetFlexGrow(root_child1, 0.2f);
441+
YGNodeInsertChild(root, root_child1, 1);
442+
443+
const YGNodeRef root_child2 = YGNodeNewWithConfig(config);
444+
YGNodeStyleSetFlexGrow(root_child2, 0.4f);
445+
YGNodeInsertChild(root, root_child2, 2);
446+
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
447+
448+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
449+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
450+
ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root));
451+
ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root));
452+
453+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
454+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
455+
ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0));
456+
ASSERT_FLOAT_EQ(132, YGNodeLayoutGetHeight(root_child0));
457+
458+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
459+
ASSERT_FLOAT_EQ(132, YGNodeLayoutGetTop(root_child1));
460+
ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1));
461+
ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child1));
462+
463+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2));
464+
ASSERT_FLOAT_EQ(224, YGNodeLayoutGetTop(root_child2));
465+
ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child2));
466+
ASSERT_FLOAT_EQ(184, YGNodeLayoutGetHeight(root_child2));
467+
468+
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
469+
470+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
471+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
472+
ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root));
473+
ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root));
474+
475+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
476+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
477+
ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0));
478+
ASSERT_FLOAT_EQ(132, YGNodeLayoutGetHeight(root_child0));
479+
480+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
481+
ASSERT_FLOAT_EQ(132, YGNodeLayoutGetTop(root_child1));
482+
ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1));
483+
ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child1));
484+
485+
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2));
486+
ASSERT_FLOAT_EQ(224, YGNodeLayoutGetTop(root_child2));
487+
ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child2));
488+
ASSERT_FLOAT_EQ(184, YGNodeLayoutGetHeight(root_child2));
489+
490+
YGNodeFreeRecursive(root);
491+
492+
YGConfigFree(config);
493+
}

yoga/Yoga.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2278,6 +2278,16 @@ static void YGNodelayoutImpl(const YGNodeRef node,
22782278
}
22792279
}
22802280

2281+
// The total flex factor needs to be floored to 1.
2282+
if (totalFlexGrowFactors > 0 && totalFlexGrowFactors < 1) {
2283+
totalFlexGrowFactors = 1;
2284+
}
2285+
2286+
// The total flex shrink factor needs to be floored to 1.
2287+
if (totalFlexShrinkScaledFactors > 0 && totalFlexShrinkScaledFactors < 1) {
2288+
totalFlexShrinkScaledFactors = 1;
2289+
}
2290+
22812291
// If we don't need to measure the cross axis, we can skip the entire flex
22822292
// step.
22832293
const bool canSkipFlex = !performLayout && measureModeCrossDim == YGMeasureModeExactly;

0 commit comments

Comments
 (0)