Fixing the edge case in Yoga with percentage absolute position and infinite constraint
Summary: Yoga has an edge case that cause layout to return NaN. This happened when we used absolute position with percentage and infinite constraint in that dimension. This diff fixes that case to default to border+padding Reviewed By: emilsjolander Differential Revision: D6199731 fbshipit-source-id: f40ddf00614b2f507848fb35f348a9dfef14b323
This commit is contained in:
committed by
Facebook Github Bot
parent
58d14ee557
commit
bfb4dabf0c
55
tests/YGInfiniteHeightTest.cpp
Normal file
55
tests/YGInfiniteHeightTest.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
// This test isn't correct from the Flexbox standard standpoint,
|
||||
// because percentages are calculated with parent constraints.
|
||||
// However, we need to make sure we fail gracefully in this case, not returning NaN
|
||||
TEST(YogaTest, percent_absolute_position_infinite_height) {
|
||||
const YGConfigRef config = YGConfigNew();
|
||||
|
||||
const YGNodeRef root = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
|
||||
YGNodeStyleSetWidth(root, 300);
|
||||
|
||||
const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetWidth(root_child0, 300);
|
||||
YGNodeStyleSetHeight(root_child0, 300);
|
||||
YGNodeInsertChild(root, root_child0, 0);
|
||||
|
||||
const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
|
||||
YGNodeStyleSetPositionType(root_child1, YGPositionTypeAbsolute);
|
||||
YGNodeStyleSetPositionPercent(root_child1, YGEdgeLeft, 20);
|
||||
YGNodeStyleSetPositionPercent(root_child1, YGEdgeTop, 20);
|
||||
YGNodeStyleSetWidthPercent(root_child1, 20);
|
||||
YGNodeStyleSetHeightPercent(root_child1, 20);
|
||||
YGNodeInsertChild(root, root_child1, 1);
|
||||
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
|
||||
ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root));
|
||||
ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root));
|
||||
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||
ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root_child0));
|
||||
ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child0));
|
||||
|
||||
ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
|
||||
ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child1));
|
||||
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1));
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
|
||||
YGConfigFree(config);
|
||||
}
|
@@ -2892,12 +2892,15 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
||||
// top/left/bottom/right
|
||||
// set, override all the previously computed positions to set it
|
||||
// correctly.
|
||||
if (YGNodeIsLeadingPosDefined(child, crossAxis)) {
|
||||
const bool isChildLeadingPosDefined = YGNodeIsLeadingPosDefined(child, crossAxis);
|
||||
if (isChildLeadingPosDefined) {
|
||||
child->layout.position[pos[crossAxis]] =
|
||||
YGNodeLeadingPosition(child, crossAxis, availableInnerCrossDim) +
|
||||
YGNodeLeadingBorder(node, crossAxis) +
|
||||
YGNodeLeadingMargin(child, crossAxis, availableInnerWidth);
|
||||
} else {
|
||||
}
|
||||
// If leading position is not defined or calculations result in Nan, default to border + margin
|
||||
if (!isChildLeadingPosDefined || YGFloatIsUndefined(child->layout.position[pos[crossAxis]])) {
|
||||
child->layout.position[pos[crossAxis]] =
|
||||
YGNodeLeadingBorder(node, crossAxis) +
|
||||
YGNodeLeadingMargin(child, crossAxis, availableInnerWidth);
|
||||
|
Reference in New Issue
Block a user