diff --git a/CSSLayout/CSSLayout.c b/CSSLayout/CSSLayout.c index f2d884b7..5cf642d9 100644 --- a/CSSLayout/CSSLayout.c +++ b/CSSLayout/CSSLayout.c @@ -2092,23 +2092,27 @@ static void layoutNodeImpl(const CSSNodeRef node, // If the user didn't specify a width or height for the node, set the // dimensions based on the children. - if (measureModeMainDim == CSSMeasureModeUndefined) { + if (measureModeMainDim == CSSMeasureModeUndefined || + (node->style.overflow != CSSOverflowScroll && measureModeMainDim == CSSMeasureModeAtMost)) { // Clamp the size to the min/max size, if specified, and make sure it // doesn't go below the padding and border amount. node->layout.measuredDimensions[dim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim); - } else if (measureModeMainDim == CSSMeasureModeAtMost) { + } else if (node->style.overflow == CSSOverflowScroll && + measureModeMainDim == CSSMeasureModeAtMost) { node->layout.measuredDimensions[dim[mainAxis]] = fmaxf(fminf(availableInnerMainDim + paddingAndBorderAxisMain, boundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim)), paddingAndBorderAxisMain); } - if (measureModeCrossDim == CSSMeasureModeUndefined) { + if (measureModeCrossDim == CSSMeasureModeUndefined || + (node->style.overflow != CSSOverflowScroll && measureModeCrossDim == CSSMeasureModeAtMost)) { // Clamp the size to the min/max size, if specified, and make sure it // doesn't go below the padding and border amount. node->layout.measuredDimensions[dim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross); - } else if (measureModeCrossDim == CSSMeasureModeAtMost) { + } else if (node->style.overflow == CSSOverflowScroll && + measureModeCrossDim == CSSMeasureModeAtMost) { node->layout.measuredDimensions[dim[crossAxis]] = fmaxf(fminf(availableInnerCrossDim + paddingAndBorderAxisCross, boundAxisWithinMinAndMax(node, diff --git a/csharp/tests/Facebook.CSSLayout/CSSSizeOverflowTest.cs b/csharp/tests/Facebook.CSSLayout/CSSSizeOverflowTest.cs new file mode 100644 index 00000000..bee15ef5 --- /dev/null +++ b/csharp/tests/Facebook.CSSLayout/CSSSizeOverflowTest.cs @@ -0,0 +1,140 @@ +/** + * 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. + */ + +/** + * @Generated by gentest/gentest.sh with the following input + * +
+
+
+
+
+ +
+
+
+
+
+ * + */ + +using System; +using NUnit.Framework; + +namespace Facebook.CSSLayout +{ + [TestFixture] + public class CSSSizeOverflowTest + { + [Test] + public void Test_nested_overflowing_child() + { + CSSNode root = new CSSNode(); + root.StyleWidth = 100; + root.StyleHeight = 100; + + CSSNode root_child0 = new CSSNode(); + root.Insert(0, root_child0); + + CSSNode root_child0_child0 = new CSSNode(); + root_child0_child0.StyleWidth = 200; + root_child0_child0.StyleHeight = 200; + root_child0.Insert(0, root_child0_child0); + root.StyleDirection = CSSDirection.LeftToRight; + root.CalculateLayout(); + + Assert.AreEqual(0, root.LayoutX); + Assert.AreEqual(0, root.LayoutY); + Assert.AreEqual(100, root.LayoutWidth); + Assert.AreEqual(100, root.LayoutHeight); + + Assert.AreEqual(0, root_child0.LayoutX); + Assert.AreEqual(0, root_child0.LayoutY); + Assert.AreEqual(100, root_child0.LayoutWidth); + Assert.AreEqual(200, root_child0.LayoutHeight); + + Assert.AreEqual(0, root_child0_child0.LayoutX); + Assert.AreEqual(0, root_child0_child0.LayoutY); + Assert.AreEqual(200, root_child0_child0.LayoutWidth); + Assert.AreEqual(200, root_child0_child0.LayoutHeight); + + root.StyleDirection = CSSDirection.RightToLeft; + root.CalculateLayout(); + + Assert.AreEqual(0, root.LayoutX); + Assert.AreEqual(0, root.LayoutY); + Assert.AreEqual(100, root.LayoutWidth); + Assert.AreEqual(100, root.LayoutHeight); + + Assert.AreEqual(0, root_child0.LayoutX); + Assert.AreEqual(0, root_child0.LayoutY); + Assert.AreEqual(100, root_child0.LayoutWidth); + Assert.AreEqual(200, root_child0.LayoutHeight); + + Assert.AreEqual(-100, root_child0_child0.LayoutX); + Assert.AreEqual(0, root_child0_child0.LayoutY); + Assert.AreEqual(200, root_child0_child0.LayoutWidth); + Assert.AreEqual(200, root_child0_child0.LayoutHeight); + } + + [Test] + public void Test_nested_overflowing_child_in_constraint_parent() + { + CSSNode root = new CSSNode(); + root.StyleWidth = 100; + root.StyleHeight = 100; + + CSSNode root_child0 = new CSSNode(); + root_child0.StyleWidth = 100; + root_child0.StyleHeight = 100; + root.Insert(0, root_child0); + + CSSNode root_child0_child0 = new CSSNode(); + root_child0_child0.StyleWidth = 200; + root_child0_child0.StyleHeight = 200; + root_child0.Insert(0, root_child0_child0); + root.StyleDirection = CSSDirection.LeftToRight; + root.CalculateLayout(); + + Assert.AreEqual(0, root.LayoutX); + Assert.AreEqual(0, root.LayoutY); + Assert.AreEqual(100, root.LayoutWidth); + Assert.AreEqual(100, root.LayoutHeight); + + Assert.AreEqual(0, root_child0.LayoutX); + Assert.AreEqual(0, root_child0.LayoutY); + Assert.AreEqual(100, root_child0.LayoutWidth); + Assert.AreEqual(100, root_child0.LayoutHeight); + + Assert.AreEqual(0, root_child0_child0.LayoutX); + Assert.AreEqual(0, root_child0_child0.LayoutY); + Assert.AreEqual(200, root_child0_child0.LayoutWidth); + Assert.AreEqual(200, root_child0_child0.LayoutHeight); + + root.StyleDirection = CSSDirection.RightToLeft; + root.CalculateLayout(); + + Assert.AreEqual(0, root.LayoutX); + Assert.AreEqual(0, root.LayoutY); + Assert.AreEqual(100, root.LayoutWidth); + Assert.AreEqual(100, root.LayoutHeight); + + Assert.AreEqual(0, root_child0.LayoutX); + Assert.AreEqual(0, root_child0.LayoutY); + Assert.AreEqual(100, root_child0.LayoutWidth); + Assert.AreEqual(100, root_child0.LayoutHeight); + + Assert.AreEqual(-100, root_child0_child0.LayoutX); + Assert.AreEqual(0, root_child0_child0.LayoutY); + Assert.AreEqual(200, root_child0_child0.LayoutWidth); + Assert.AreEqual(200, root_child0_child0.LayoutHeight); + } + + } +} diff --git a/gentest/fixtures/CSSSizeOverflowTest.html b/gentest/fixtures/CSSSizeOverflowTest.html new file mode 100644 index 00000000..fd06adba --- /dev/null +++ b/gentest/fixtures/CSSSizeOverflowTest.html @@ -0,0 +1,11 @@ +
+
+
+
+
+ +
+
+
+
+
diff --git a/java/tests/com/facebook/csslayout/CSSSizeOverflowTest.java b/java/tests/com/facebook/csslayout/CSSSizeOverflowTest.java new file mode 100644 index 00000000..5394fe75 --- /dev/null +++ b/java/tests/com/facebook/csslayout/CSSSizeOverflowTest.java @@ -0,0 +1,136 @@ +/** + * 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. + */ + +/** + * @Generated by gentest/gentest.sh with the following input + * +
+
+
+
+
+ +
+
+
+
+
+ * + */ + +package com.facebook.csslayout; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class CSSSizeOverflowTest { + @Test + public void test_nested_overflowing_child() { + final CSSNode root = new CSSNode(); + root.setStyleWidth(100); + root.setStyleHeight(100); + + final CSSNode root_child0 = new CSSNode(); + root.addChildAt(root_child0, 0); + + final CSSNode root_child0_child0 = new CSSNode(); + root_child0_child0.setStyleWidth(200); + root_child0_child0.setStyleHeight(200); + root_child0.addChildAt(root_child0_child0, 0); + root.setDirection(CSSDirection.LTR); + root.calculateLayout(null); + + assertEquals(0, root.getLayoutX(), 0.0f); + assertEquals(0, root.getLayoutY(), 0.0f); + assertEquals(100, root.getLayoutWidth(), 0.0f); + assertEquals(100, root.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0.getLayoutY(), 0.0f); + assertEquals(100, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(200, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(200, root_child0_child0.getLayoutHeight(), 0.0f); + + root.setDirection(CSSDirection.RTL); + root.calculateLayout(null); + + assertEquals(0, root.getLayoutX(), 0.0f); + assertEquals(0, root.getLayoutY(), 0.0f); + assertEquals(100, root.getLayoutWidth(), 0.0f); + assertEquals(100, root.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0.getLayoutY(), 0.0f); + assertEquals(100, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(-100, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(200, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(200, root_child0_child0.getLayoutHeight(), 0.0f); + } + + @Test + public void test_nested_overflowing_child_in_constraint_parent() { + final CSSNode root = new CSSNode(); + root.setStyleWidth(100); + root.setStyleHeight(100); + + final CSSNode root_child0 = new CSSNode(); + root_child0.setStyleWidth(100); + root_child0.setStyleHeight(100); + root.addChildAt(root_child0, 0); + + final CSSNode root_child0_child0 = new CSSNode(); + root_child0_child0.setStyleWidth(200); + root_child0_child0.setStyleHeight(200); + root_child0.addChildAt(root_child0_child0, 0); + root.setDirection(CSSDirection.LTR); + root.calculateLayout(null); + + assertEquals(0, root.getLayoutX(), 0.0f); + assertEquals(0, root.getLayoutY(), 0.0f); + assertEquals(100, root.getLayoutWidth(), 0.0f); + assertEquals(100, root.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0.getLayoutY(), 0.0f); + assertEquals(100, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(200, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(200, root_child0_child0.getLayoutHeight(), 0.0f); + + root.setDirection(CSSDirection.RTL); + root.calculateLayout(null); + + assertEquals(0, root.getLayoutX(), 0.0f); + assertEquals(0, root.getLayoutY(), 0.0f); + assertEquals(100, root.getLayoutWidth(), 0.0f); + assertEquals(100, root.getLayoutHeight(), 0.0f); + + assertEquals(0, root_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0.getLayoutY(), 0.0f); + assertEquals(100, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(-100, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(200, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(200, root_child0_child0.getLayoutHeight(), 0.0f); + } + +} diff --git a/tests/CSSSizeOverflowTest.cpp b/tests/CSSSizeOverflowTest.cpp new file mode 100644 index 00000000..14c23ff4 --- /dev/null +++ b/tests/CSSSizeOverflowTest.cpp @@ -0,0 +1,128 @@ +/** + * 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. + */ + +/** + * @Generated by gentest/gentest.sh with the following input + * +
+
+
+
+
+ +
+
+
+
+
+ * + */ + +#include +#include + +TEST(CSSLayoutTest, nested_overflowing_child) { + const CSSNodeRef root = CSSNodeNew(); + CSSNodeStyleSetWidth(root, 100); + CSSNodeStyleSetHeight(root, 100); + + const CSSNodeRef root_child0 = CSSNodeNew(); + CSSNodeInsertChild(root, root_child0, 0); + + const CSSNodeRef root_child0_child0 = CSSNodeNew(); + CSSNodeStyleSetWidth(root_child0_child0, 200); + CSSNodeStyleSetHeight(root_child0_child0, 200); + CSSNodeInsertChild(root_child0, root_child0_child0, 0); + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetHeight(root_child0_child0)); + + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(-100, CSSNodeLayoutGetLeft(root_child0_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetHeight(root_child0_child0)); + + CSSNodeFreeRecursive(root); +} + +TEST(CSSLayoutTest, nested_overflowing_child_in_constraint_parent) { + const CSSNodeRef root = CSSNodeNew(); + CSSNodeStyleSetWidth(root, 100); + CSSNodeStyleSetHeight(root, 100); + + const CSSNodeRef root_child0 = CSSNodeNew(); + CSSNodeStyleSetWidth(root_child0, 100); + CSSNodeStyleSetHeight(root_child0, 100); + CSSNodeInsertChild(root, root_child0, 0); + + const CSSNodeRef root_child0_child0 = CSSNodeNew(); + CSSNodeStyleSetWidth(root_child0_child0, 200); + CSSNodeStyleSetHeight(root_child0_child0, 200); + CSSNodeInsertChild(root_child0, root_child0_child0, 0); + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetHeight(root_child0_child0)); + + CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root)); + + ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, CSSNodeLayoutGetHeight(root_child0)); + + ASSERT_EQ(-100, CSSNodeLayoutGetLeft(root_child0_child0)); + ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0_child0)); + ASSERT_EQ(200, CSSNodeLayoutGetHeight(root_child0_child0)); + + CSSNodeFreeRecursive(root); +}