Add support for display: contents style (#1726)

Summary:
X-link: https://github.com/facebook/react-native/pull/47035

This PR adds support for `display: contents` style by effectively skipping nodes with `display: contents` set during layout.

This required changes in the logic related to children traversal - before this PR a node would be always laid out in the context of its direct parent. After this PR that assumption is no longer true - `display: contents` allows nodes to be skipped, i.e.:

```html
<div id="node1">
  <div id="node2" style="display: contents;">
    <div id="node3" />
  </div>
</div>
```

`node3` will be laid out as if it were a child of `node1`.

Because of this, iterating over direct children of a node is no longer correct to achieve the correct layout. This PR introduces `LayoutableChildren::Iterator` which can traverse the subtree of a given node in a way that nodes with `display: contents` are replaced with their concrete children.

A tree like this:
```mermaid
flowchart TD
    A((A))
    B((B))
    C((C))
    D((D))
    E((E))
    F((F))
    G((G))
    H((H))
    I((I))
    J((J))

    A --> B
    A --> C
    B --> D
    B --> E
    C --> F
    D --> G
    F --> H
    G --> I
    H --> J

    style B fill:https://github.com/facebook/yoga/issues/050
    style C fill:https://github.com/facebook/yoga/issues/050
    style D fill:https://github.com/facebook/yoga/issues/050
    style H fill:https://github.com/facebook/yoga/issues/050
    style I fill:https://github.com/facebook/yoga/issues/050
```

would be laid out as if the green nodes (ones with `display: contents`) did not exist. It also changes the logic where children were accessed by index to use the iterator instead as random access would be non-trivial to implement and it's not really necessary - the iteration was always sequential and indices were only used as boundaries.

There's one place where knowledge of layoutable children is required to calculate the gap. An optimization for this is for a node to keep a counter of how many `display: contents` nodes are its children. If there are none, a short path of just returning the size of the children vector can be taken, otherwise it needs to iterate over layoutable children and count them, since the structure may be complex.

One more major change this PR introduces is `cleanupContentsNodesRecursively`. Since nodes with `display: contents` would be entirely skipped during the layout pass, they would keep previous metrics, would be kept as dirty, and, in the case of nested `contents` nodes, would not be cloned, breaking `doesOwn` relation. All of this is handled in the new method which clones `contents` nodes recursively, sets empty layout, and marks them as clean and having a new layout so that it can be used on the React Native side.

Relies on https://github.com/facebook/yoga/pull/1725

Changelog: [Internal]

Pull Request resolved: https://github.com/facebook/yoga/pull/1726

Test Plan: Added tests for `display: contents` based on existing tests for `display: none` and ensured that all the tests were passing.

Reviewed By: joevilches

Differential Revision: D64404340

Pulled By: NickGerleman

fbshipit-source-id: f6f6e9a6fad82873f18c8a0ead58aad897df5d09
This commit is contained in:
Jakub Piasecki
2024-10-18 22:05:41 -07:00
committed by Facebook GitHub Bot
parent 568718242d
commit 68bb2343d2
26 changed files with 2590 additions and 44 deletions

View File

@@ -31,7 +31,7 @@ ENUMS = {
"SpaceEvenly", "SpaceEvenly",
], ],
"PositionType": ["Static", "Relative", "Absolute"], "PositionType": ["Static", "Relative", "Absolute"],
"Display": ["Flex", "None"], "Display": ["Flex", "None", "Contents"],
"Wrap": ["NoWrap", "Wrap", "WrapReverse"], "Wrap": ["NoWrap", "Wrap", "WrapReverse"],
"BoxSizing": ["BorderBox", "ContentBox"], "BoxSizing": ["BorderBox", "ContentBox"],
"MeasureMode": ["Undefined", "Exactly", "AtMost"], "MeasureMode": ["Undefined", "Exactly", "AtMost"],

View File

@@ -29,3 +29,61 @@
<div id="display_none_with_position_absolute" style="width: 100px; height: 100px;"> <div id="display_none_with_position_absolute" style="width: 100px; height: 100px;">
<div style="display:none; position: absolute; width: 100px; height: 100px"></div> <div style="display:none; position: absolute; width: 100px; height: 100px"></div>
</div> </div>
<div id="display_contents" style="width: 100px; height: 100px; flex-direction: row;">
<div style="display: contents;">
<div style="flex: 1; height: 10px;"></div>
<div style="flex: 1; height: 20px;"></div>
</div>
</div>
<div id="display_contents_fixed_size" style="width: 100px; height: 100px; flex-direction: row;">
<div style="display: contents; width: 50px; height: 50px;">
<div style="flex: 1; height: 10px;"></div>
<div style="flex: 1; height: 20px;"></div>
</div>
</div>
<div id="display_contents_with_margin" style="width: 100px; height: 100px; flex-direction: row;">
<div style="width: 20px; height: 20px; display: contents; margin: 10px;"></div>
<div style="flex-grow: 1;"></div>
</div>
<div id="display_contents_with_padding" style="width: 100px; height: 100px; flex-direction: row;">
<div style="display: contents; padding: 10px;">
<div style="flex: 1; height: 10px;"></div>
<div style="flex: 1; height: 20px;"></div>
</div>
</div>
<div id="display_contents_with_position" style="width: 100px; height: 100px; flex-direction: row;">
<div style="display: contents; top: 10px;">
<div style="flex: 1; height: 10px;"></div>
<div style="flex: 1; height: 20px;"></div>
</div>
</div>
<div id="display_contents_with_position_absolute" style="width: 100px; height: 100px; flex-direction: row;">
<div style="display: contents; position: absolute; width: 50px; height: 50px;">
<div style="flex: 1; height: 10px;"></div>
<div style="flex: 1; height: 20px;"></div>
</div>
</div>
<div id="display_contents_nested" style="width: 100px; height: 100px; flex-direction: row;">
<div style="display: contents;">
<div style="display: contents;">
<div style="flex: 1; height: 10px;"></div>
<div style="flex: 1; height: 20px;"></div>
</div>
</div>
</div>
<div id="display_contents_with_siblings" style="width: 100px; height: 100px; flex-direction: row;">
<div style="flex: 1; height: 30px;"></div>
<div style="display: contents;">
<div style="flex: 1; height: 10px;"></div>
<div style="flex: 1; height: 20px;"></div>
</div>
<div style="flex: 1; height: 30px;"></div>
</div>

View File

@@ -160,6 +160,7 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, {
YGDisplayFlex: {value: 'YGDisplayFlex'}, YGDisplayFlex: {value: 'YGDisplayFlex'},
YGDisplayNone: {value: 'YGDisplayNone'}, YGDisplayNone: {value: 'YGDisplayNone'},
YGDisplayContents: {value: 'YGDisplayContents'},
YGAuto: {value: 'YGAuto'}, YGAuto: {value: 'YGAuto'},
YGNodeCalculateLayout: { YGNodeCalculateLayout: {

View File

@@ -195,6 +195,7 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, {
YGDisplayFlex: {value: 'YogaDisplay.FLEX'}, YGDisplayFlex: {value: 'YogaDisplay.FLEX'},
YGDisplayNone: {value: 'YogaDisplay.NONE'}, YGDisplayNone: {value: 'YogaDisplay.NONE'},
YGDisplayContents: {value: 'YogaDisplay.CONTENTS'},
YGAuto: {value: 'YogaConstants.AUTO'}, YGAuto: {value: 'YogaConstants.AUTO'},
YGWrapNoWrap: {value: 'YogaWrap.NO_WRAP'}, YGWrapNoWrap: {value: 'YogaWrap.NO_WRAP'},

View File

@@ -171,6 +171,7 @@ JavascriptEmitter.prototype = Object.create(Emitter.prototype, {
YGDisplayFlex: {value: 'Display.Flex'}, YGDisplayFlex: {value: 'Display.Flex'},
YGDisplayNone: {value: 'Display.None'}, YGDisplayNone: {value: 'Display.None'},
YGDisplayContents: {value: 'Display.Contents'},
YGBoxSizingBorderBox: {value: 'BoxSizing.BorderBox'}, YGBoxSizingBorderBox: {value: 'BoxSizing.BorderBox'},
YGBoxSizingContentBox: {value: 'BoxSizing.ContentBox'}, YGBoxSizingContentBox: {value: 'BoxSizing.ContentBox'},

View File

@@ -665,6 +665,8 @@ function displayValue(e, value) {
return e.YGDisplayFlex; return e.YGDisplayFlex;
case 'none': case 'none':
return e.YGDisplayNone; return e.YGDisplayNone;
case 'contents':
return e.YGDisplayContents;
} }
} }

View File

@@ -11,7 +11,8 @@ package com.facebook.yoga;
public enum YogaDisplay { public enum YogaDisplay {
FLEX(0), FLEX(0),
NONE(1); NONE(1),
CONTENTS(2);
private final int mIntValue; private final int mIntValue;
@@ -27,6 +28,7 @@ public enum YogaDisplay {
switch (value) { switch (value) {
case 0: return FLEX; case 0: return FLEX;
case 1: return NONE; case 1: return NONE;
case 2: return CONTENTS;
default: throw new IllegalArgumentException("Unknown enum value: " + value); default: throw new IllegalArgumentException("Unknown enum value: " + value);
} }
} }

View File

@@ -0,0 +1,107 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<be0d102e74e15f15050520f21afcaee1>>
* generated by gentest/gentest-driver.ts from gentest/fixtures/YGDisplayContentsTest.html
*/
package com.facebook.yoga;
import static org.junit.Assert.assertEquals;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import com.facebook.yoga.utils.TestUtils;
@RunWith(Parameterized.class)
public class YGDisplayContentsTest {
@Parameterized.Parameters(name = "{0}")
public static Iterable<TestParametrization.NodeFactory> nodeFactories() {
return TestParametrization.nodeFactories();
}
@Parameterized.Parameter public TestParametrization.NodeFactory mNodeFactory;
@Test
public void test_test1() {
YogaConfig config = YogaConfigFactory.create();
final YogaNode root = createNode(config);
root.setFlexDirection(YogaFlexDirection.ROW);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);
final YogaNode root_child0 = createNode(config);
root_child0.setDisplay(YogaDisplay.CONTENTS);
root.addChildAt(root_child0, 0);
final YogaNode root_child0_child0 = createNode(config);
root_child0_child0.setFlexGrow(1f);
root_child0_child0.setFlexShrink(1f);
root_child0_child0.setFlexBasisPercent(0f);
root_child0_child0.setHeight(10f);
root_child0.addChildAt(root_child0_child0, 0);
final YogaNode root_child0_child1 = createNode(config);
root_child0_child1.setFlexGrow(1f);
root_child0_child1.setFlexShrink(1f);
root_child0_child1.setFlexBasisPercent(0f);
root_child0_child1.setHeight(20f);
root_child0.addChildAt(root_child0_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.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(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.getLayoutHeight(), 0.0f);
}
private YogaNode createNode(YogaConfig config) {
return mNodeFactory.create(config);
}
}

View File

@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
* *
* @generated SignedSource<<8db61c1e5703262c1afcf489be4d6abf>> * @generated SignedSource<<4c1ad4613638039be1599a39a766a2bc>>
* generated by gentest/gentest-driver.ts from gentest/fixtures/YGDisplayTest.html * generated by gentest/gentest-driver.ts from gentest/fixtures/YGDisplayTest.html
*/ */
@@ -388,6 +388,642 @@ public class YGDisplayTest {
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f); assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
} }
@Test
public void test_display_contents() {
YogaConfig config = YogaConfigFactory.create();
final YogaNode root = createNode(config);
root.setFlexDirection(YogaFlexDirection.ROW);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);
final YogaNode root_child0 = createNode(config);
root_child0.setDisplay(YogaDisplay.CONTENTS);
root.addChildAt(root_child0, 0);
final YogaNode root_child0_child0 = createNode(config);
root_child0_child0.setFlexGrow(1f);
root_child0_child0.setFlexShrink(1f);
root_child0_child0.setFlexBasisPercent(0f);
root_child0_child0.setHeight(10f);
root_child0.addChildAt(root_child0_child0, 0);
final YogaNode root_child0_child1 = createNode(config);
root_child0_child1.setFlexGrow(1f);
root_child0_child1.setFlexShrink(1f);
root_child0_child1.setFlexBasisPercent(0f);
root_child0_child1.setHeight(20f);
root_child0.addChildAt(root_child0_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.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(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.getLayoutHeight(), 0.0f);
}
@Test
public void test_display_contents_fixed_size() {
YogaConfig config = YogaConfigFactory.create();
final YogaNode root = createNode(config);
root.setFlexDirection(YogaFlexDirection.ROW);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);
final YogaNode root_child0 = createNode(config);
root_child0.setWidth(50f);
root_child0.setHeight(50f);
root_child0.setDisplay(YogaDisplay.CONTENTS);
root.addChildAt(root_child0, 0);
final YogaNode root_child0_child0 = createNode(config);
root_child0_child0.setFlexGrow(1f);
root_child0_child0.setFlexShrink(1f);
root_child0_child0.setFlexBasisPercent(0f);
root_child0_child0.setHeight(10f);
root_child0.addChildAt(root_child0_child0, 0);
final YogaNode root_child0_child1 = createNode(config);
root_child0_child1.setFlexGrow(1f);
root_child0_child1.setFlexShrink(1f);
root_child0_child1.setFlexBasisPercent(0f);
root_child0_child1.setHeight(20f);
root_child0.addChildAt(root_child0_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.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(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.getLayoutHeight(), 0.0f);
}
@Test
public void test_display_contents_with_margin() {
YogaConfig config = YogaConfigFactory.create();
final YogaNode root = createNode(config);
root.setFlexDirection(YogaFlexDirection.ROW);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);
final YogaNode root_child0 = createNode(config);
root_child0.setMargin(YogaEdge.LEFT, 10f);
root_child0.setMargin(YogaEdge.TOP, 10f);
root_child0.setMargin(YogaEdge.RIGHT, 10f);
root_child0.setMargin(YogaEdge.BOTTOM, 10f);
root_child0.setWidth(20f);
root_child0.setHeight(20f);
root_child0.setDisplay(YogaDisplay.CONTENTS);
root.addChildAt(root_child0, 0);
final YogaNode root_child1 = createNode(config);
root_child1.setFlexGrow(1f);
root.addChildAt(root_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child1.getLayoutY(), 0.0f);
assertEquals(100f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(100f, root_child1.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(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child1.getLayoutY(), 0.0f);
assertEquals(100f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(100f, root_child1.getLayoutHeight(), 0.0f);
}
@Test
public void test_display_contents_with_padding() {
YogaConfig config = YogaConfigFactory.create();
final YogaNode root = createNode(config);
root.setFlexDirection(YogaFlexDirection.ROW);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);
final YogaNode root_child0 = createNode(config);
root_child0.setPadding(YogaEdge.LEFT, 10);
root_child0.setPadding(YogaEdge.TOP, 10);
root_child0.setPadding(YogaEdge.RIGHT, 10);
root_child0.setPadding(YogaEdge.BOTTOM, 10);
root_child0.setDisplay(YogaDisplay.CONTENTS);
root.addChildAt(root_child0, 0);
final YogaNode root_child0_child0 = createNode(config);
root_child0_child0.setFlexGrow(1f);
root_child0_child0.setFlexShrink(1f);
root_child0_child0.setFlexBasisPercent(0f);
root_child0_child0.setHeight(10f);
root_child0.addChildAt(root_child0_child0, 0);
final YogaNode root_child0_child1 = createNode(config);
root_child0_child1.setFlexGrow(1f);
root_child0_child1.setFlexShrink(1f);
root_child0_child1.setFlexBasisPercent(0f);
root_child0_child1.setHeight(20f);
root_child0.addChildAt(root_child0_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.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(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.getLayoutHeight(), 0.0f);
}
@Test
public void test_display_contents_with_position() {
YogaConfig config = YogaConfigFactory.create();
final YogaNode root = createNode(config);
root.setFlexDirection(YogaFlexDirection.ROW);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);
final YogaNode root_child0 = createNode(config);
root_child0.setPosition(YogaEdge.TOP, 10f);
root_child0.setDisplay(YogaDisplay.CONTENTS);
root.addChildAt(root_child0, 0);
final YogaNode root_child0_child0 = createNode(config);
root_child0_child0.setFlexGrow(1f);
root_child0_child0.setFlexShrink(1f);
root_child0_child0.setFlexBasisPercent(0f);
root_child0_child0.setHeight(10f);
root_child0.addChildAt(root_child0_child0, 0);
final YogaNode root_child0_child1 = createNode(config);
root_child0_child1.setFlexGrow(1f);
root_child0_child1.setFlexShrink(1f);
root_child0_child1.setFlexBasisPercent(0f);
root_child0_child1.setHeight(20f);
root_child0.addChildAt(root_child0_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.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(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.getLayoutHeight(), 0.0f);
}
@Test
public void test_display_contents_with_position_absolute() {
YogaConfig config = YogaConfigFactory.create();
final YogaNode root = createNode(config);
root.setFlexDirection(YogaFlexDirection.ROW);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);
final YogaNode root_child0 = createNode(config);
root_child0.setPositionType(YogaPositionType.ABSOLUTE);
root_child0.setWidth(50f);
root_child0.setHeight(50f);
root_child0.setDisplay(YogaDisplay.CONTENTS);
root.addChildAt(root_child0, 0);
final YogaNode root_child0_child0 = createNode(config);
root_child0_child0.setFlexGrow(1f);
root_child0_child0.setFlexShrink(1f);
root_child0_child0.setFlexBasisPercent(0f);
root_child0_child0.setHeight(10f);
root_child0.addChildAt(root_child0_child0, 0);
final YogaNode root_child0_child1 = createNode(config);
root_child0_child1.setFlexGrow(1f);
root_child0_child1.setFlexShrink(1f);
root_child0_child1.setFlexBasisPercent(0f);
root_child0_child1.setHeight(20f);
root_child0.addChildAt(root_child0_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.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(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child1.getLayoutHeight(), 0.0f);
}
@Test
public void test_display_contents_nested() {
YogaConfig config = YogaConfigFactory.create();
final YogaNode root = createNode(config);
root.setFlexDirection(YogaFlexDirection.ROW);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);
final YogaNode root_child0 = createNode(config);
root_child0.setDisplay(YogaDisplay.CONTENTS);
root.addChildAt(root_child0, 0);
final YogaNode root_child0_child0 = createNode(config);
root_child0_child0.setDisplay(YogaDisplay.CONTENTS);
root_child0.addChildAt(root_child0_child0, 0);
final YogaNode root_child0_child0_child0 = createNode(config);
root_child0_child0_child0.setFlexGrow(1f);
root_child0_child0_child0.setFlexShrink(1f);
root_child0_child0_child0.setFlexBasisPercent(0f);
root_child0_child0_child0.setHeight(10f);
root_child0_child0.addChildAt(root_child0_child0_child0, 0);
final YogaNode root_child0_child0_child1 = createNode(config);
root_child0_child0_child1.setFlexGrow(1f);
root_child0_child0_child1.setFlexShrink(1f);
root_child0_child0_child1.setFlexBasisPercent(0f);
root_child0_child0_child1.setHeight(20f);
root_child0_child0.addChildAt(root_child0_child0_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child0_child1.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(100f, 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(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child0_child0_child1.getLayoutHeight(), 0.0f);
}
@Test
public void test_display_contents_with_siblings() {
YogaConfig config = YogaConfigFactory.create();
final YogaNode root = createNode(config);
root.setFlexDirection(YogaFlexDirection.ROW);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);
final YogaNode root_child0 = createNode(config);
root_child0.setFlexGrow(1f);
root_child0.setFlexShrink(1f);
root_child0.setFlexBasisPercent(0f);
root_child0.setHeight(30f);
root.addChildAt(root_child0, 0);
final YogaNode root_child1 = createNode(config);
root_child1.setDisplay(YogaDisplay.CONTENTS);
root.addChildAt(root_child1, 1);
final YogaNode root_child1_child0 = createNode(config);
root_child1_child0.setFlexGrow(1f);
root_child1_child0.setFlexShrink(1f);
root_child1_child0.setFlexBasisPercent(0f);
root_child1_child0.setHeight(10f);
root_child1.addChildAt(root_child1_child0, 0);
final YogaNode root_child1_child1 = createNode(config);
root_child1_child1.setFlexGrow(1f);
root_child1_child1.setFlexShrink(1f);
root_child1_child1.setFlexBasisPercent(0f);
root_child1_child1.setHeight(20f);
root_child1.addChildAt(root_child1_child1, 1);
final YogaNode root_child2 = createNode(config);
root_child2.setFlexGrow(1f);
root_child2.setFlexShrink(1f);
root_child2.setFlexBasisPercent(0f);
root_child2.setHeight(30f);
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(100f, 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(25f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(30f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child1.getLayoutY(), 0.0f);
assertEquals(0f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child1.getLayoutHeight(), 0.0f);
assertEquals(25f, root_child1_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f);
assertEquals(25f, root_child1_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child1_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child1_child1.getLayoutY(), 0.0f);
assertEquals(25f, root_child1_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child1_child1.getLayoutHeight(), 0.0f);
assertEquals(75f, root_child2.getLayoutX(), 0.0f);
assertEquals(0f, root_child2.getLayoutY(), 0.0f);
assertEquals(25f, root_child2.getLayoutWidth(), 0.0f);
assertEquals(30f, 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(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);
assertEquals(75f, root_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
assertEquals(25f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(30f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child1.getLayoutY(), 0.0f);
assertEquals(0f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child1.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child1_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f);
assertEquals(25f, root_child1_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f);
assertEquals(25f, root_child1_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child1_child1.getLayoutY(), 0.0f);
assertEquals(25f, root_child1_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child1_child1.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child2.getLayoutX(), 0.0f);
assertEquals(0f, root_child2.getLayoutY(), 0.0f);
assertEquals(25f, root_child2.getLayoutWidth(), 0.0f);
assertEquals(30f, root_child2.getLayoutHeight(), 0.0f);
}
private YogaNode createNode(YogaConfig config) { private YogaNode createNode(YogaConfig config) {
return mNodeFactory.create(config); return mNodeFactory.create(config);
} }

View File

@@ -38,6 +38,7 @@ export enum Direction {
export enum Display { export enum Display {
Flex = 0, Flex = 0,
None = 1, None = 1,
Contents = 2,
} }
export enum Edge { export enum Edge {
@@ -151,6 +152,7 @@ const constants = {
DIRECTION_RTL: Direction.RTL, DIRECTION_RTL: Direction.RTL,
DISPLAY_FLEX: Display.Flex, DISPLAY_FLEX: Display.Flex,
DISPLAY_NONE: Display.None, DISPLAY_NONE: Display.None,
DISPLAY_CONTENTS: Display.Contents,
EDGE_LEFT: Edge.Left, EDGE_LEFT: Edge.Left,
EDGE_TOP: Edge.Top, EDGE_TOP: Edge.Top,
EDGE_RIGHT: Edge.Right, EDGE_RIGHT: Edge.Right,

View File

@@ -0,0 +1,109 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<64d58fa2d33230f4eafc9ecbb6012a0d>>
* generated by gentest/gentest-driver.ts from gentest/fixtures/YGDisplayContentsTest.html
*/
import { instrinsicSizeMeasureFunc } from '../tools/utils.ts'
import Yoga from 'yoga-layout';
import {
Align,
BoxSizing,
Direction,
Display,
Edge,
Errata,
ExperimentalFeature,
FlexDirection,
Gutter,
Justify,
MeasureMode,
Overflow,
PositionType,
Unit,
Wrap,
} from 'yoga-layout';
test('test1', () => {
const config = Yoga.Config.create();
let root;
try {
root = Yoga.Node.create(config);
root.setFlexDirection(FlexDirection.Row);
root.setPositionType(PositionType.Absolute);
root.setWidth(100);
root.setHeight(100);
const root_child0 = Yoga.Node.create(config);
root_child0.setDisplay(Display.Contents);
root.insertChild(root_child0, 0);
const root_child0_child0 = Yoga.Node.create(config);
root_child0_child0.setFlexGrow(1);
root_child0_child0.setFlexShrink(1);
root_child0_child0.setFlexBasis("0%");
root_child0_child0.setHeight(10);
root_child0.insertChild(root_child0_child0, 0);
const root_child0_child1 = Yoga.Node.create(config);
root_child0_child1.setFlexGrow(1);
root_child0_child1.setFlexShrink(1);
root_child0_child1.setFlexBasis("0%");
root_child0_child1.setHeight(20);
root_child0.insertChild(root_child0_child1, 1);
root.calculateLayout(undefined, undefined, Direction.LTR);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(0);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(50);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
root.calculateLayout(undefined, undefined, Direction.RTL);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(50);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(0);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
} finally {
if (typeof root !== 'undefined') {
root.freeRecursive();
}
config.free();
}
});

View File

@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
* *
* @generated SignedSource<<1f15f9628f43eed206466695ec6e683c>> * @generated SignedSource<<ef1ab99e8f13c0a59342ca17f63181ef>>
* generated by gentest/gentest-driver.ts from gentest/fixtures/YGDisplayTest.html * generated by gentest/gentest-driver.ts from gentest/fixtures/YGDisplayTest.html
*/ */
@@ -419,3 +419,679 @@ test('display_none_with_position_absolute', () => {
config.free(); config.free();
} }
}); });
test('display_contents', () => {
const config = Yoga.Config.create();
let root;
try {
root = Yoga.Node.create(config);
root.setFlexDirection(FlexDirection.Row);
root.setPositionType(PositionType.Absolute);
root.setWidth(100);
root.setHeight(100);
const root_child0 = Yoga.Node.create(config);
root_child0.setDisplay(Display.Contents);
root.insertChild(root_child0, 0);
const root_child0_child0 = Yoga.Node.create(config);
root_child0_child0.setFlexGrow(1);
root_child0_child0.setFlexShrink(1);
root_child0_child0.setFlexBasis("0%");
root_child0_child0.setHeight(10);
root_child0.insertChild(root_child0_child0, 0);
const root_child0_child1 = Yoga.Node.create(config);
root_child0_child1.setFlexGrow(1);
root_child0_child1.setFlexShrink(1);
root_child0_child1.setFlexBasis("0%");
root_child0_child1.setHeight(20);
root_child0.insertChild(root_child0_child1, 1);
root.calculateLayout(undefined, undefined, Direction.LTR);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(0);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(50);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
root.calculateLayout(undefined, undefined, Direction.RTL);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(50);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(0);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
} finally {
if (typeof root !== 'undefined') {
root.freeRecursive();
}
config.free();
}
});
test('display_contents_fixed_size', () => {
const config = Yoga.Config.create();
let root;
try {
root = Yoga.Node.create(config);
root.setFlexDirection(FlexDirection.Row);
root.setPositionType(PositionType.Absolute);
root.setWidth(100);
root.setHeight(100);
const root_child0 = Yoga.Node.create(config);
root_child0.setWidth(50);
root_child0.setHeight(50);
root_child0.setDisplay(Display.Contents);
root.insertChild(root_child0, 0);
const root_child0_child0 = Yoga.Node.create(config);
root_child0_child0.setFlexGrow(1);
root_child0_child0.setFlexShrink(1);
root_child0_child0.setFlexBasis("0%");
root_child0_child0.setHeight(10);
root_child0.insertChild(root_child0_child0, 0);
const root_child0_child1 = Yoga.Node.create(config);
root_child0_child1.setFlexGrow(1);
root_child0_child1.setFlexShrink(1);
root_child0_child1.setFlexBasis("0%");
root_child0_child1.setHeight(20);
root_child0.insertChild(root_child0_child1, 1);
root.calculateLayout(undefined, undefined, Direction.LTR);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(0);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(50);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
root.calculateLayout(undefined, undefined, Direction.RTL);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(50);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(0);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
} finally {
if (typeof root !== 'undefined') {
root.freeRecursive();
}
config.free();
}
});
test('display_contents_with_margin', () => {
const config = Yoga.Config.create();
let root;
try {
root = Yoga.Node.create(config);
root.setFlexDirection(FlexDirection.Row);
root.setPositionType(PositionType.Absolute);
root.setWidth(100);
root.setHeight(100);
const root_child0 = Yoga.Node.create(config);
root_child0.setMargin(Edge.Left, 10);
root_child0.setMargin(Edge.Top, 10);
root_child0.setMargin(Edge.Right, 10);
root_child0.setMargin(Edge.Bottom, 10);
root_child0.setWidth(20);
root_child0.setHeight(20);
root_child0.setDisplay(Display.Contents);
root.insertChild(root_child0, 0);
const root_child1 = Yoga.Node.create(config);
root_child1.setFlexGrow(1);
root.insertChild(root_child1, 1);
root.calculateLayout(undefined, undefined, Direction.LTR);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child1.getComputedLeft()).toBe(0);
expect(root_child1.getComputedTop()).toBe(0);
expect(root_child1.getComputedWidth()).toBe(100);
expect(root_child1.getComputedHeight()).toBe(100);
root.calculateLayout(undefined, undefined, Direction.RTL);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child1.getComputedLeft()).toBe(0);
expect(root_child1.getComputedTop()).toBe(0);
expect(root_child1.getComputedWidth()).toBe(100);
expect(root_child1.getComputedHeight()).toBe(100);
} finally {
if (typeof root !== 'undefined') {
root.freeRecursive();
}
config.free();
}
});
test('display_contents_with_padding', () => {
const config = Yoga.Config.create();
let root;
try {
root = Yoga.Node.create(config);
root.setFlexDirection(FlexDirection.Row);
root.setPositionType(PositionType.Absolute);
root.setWidth(100);
root.setHeight(100);
const root_child0 = Yoga.Node.create(config);
root_child0.setPadding(Edge.Left, 10);
root_child0.setPadding(Edge.Top, 10);
root_child0.setPadding(Edge.Right, 10);
root_child0.setPadding(Edge.Bottom, 10);
root_child0.setDisplay(Display.Contents);
root.insertChild(root_child0, 0);
const root_child0_child0 = Yoga.Node.create(config);
root_child0_child0.setFlexGrow(1);
root_child0_child0.setFlexShrink(1);
root_child0_child0.setFlexBasis("0%");
root_child0_child0.setHeight(10);
root_child0.insertChild(root_child0_child0, 0);
const root_child0_child1 = Yoga.Node.create(config);
root_child0_child1.setFlexGrow(1);
root_child0_child1.setFlexShrink(1);
root_child0_child1.setFlexBasis("0%");
root_child0_child1.setHeight(20);
root_child0.insertChild(root_child0_child1, 1);
root.calculateLayout(undefined, undefined, Direction.LTR);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(0);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(50);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
root.calculateLayout(undefined, undefined, Direction.RTL);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(50);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(0);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
} finally {
if (typeof root !== 'undefined') {
root.freeRecursive();
}
config.free();
}
});
test('display_contents_with_position', () => {
const config = Yoga.Config.create();
let root;
try {
root = Yoga.Node.create(config);
root.setFlexDirection(FlexDirection.Row);
root.setPositionType(PositionType.Absolute);
root.setWidth(100);
root.setHeight(100);
const root_child0 = Yoga.Node.create(config);
root_child0.setPosition(Edge.Top, 10);
root_child0.setDisplay(Display.Contents);
root.insertChild(root_child0, 0);
const root_child0_child0 = Yoga.Node.create(config);
root_child0_child0.setFlexGrow(1);
root_child0_child0.setFlexShrink(1);
root_child0_child0.setFlexBasis("0%");
root_child0_child0.setHeight(10);
root_child0.insertChild(root_child0_child0, 0);
const root_child0_child1 = Yoga.Node.create(config);
root_child0_child1.setFlexGrow(1);
root_child0_child1.setFlexShrink(1);
root_child0_child1.setFlexBasis("0%");
root_child0_child1.setHeight(20);
root_child0.insertChild(root_child0_child1, 1);
root.calculateLayout(undefined, undefined, Direction.LTR);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(0);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(50);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
root.calculateLayout(undefined, undefined, Direction.RTL);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(50);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(0);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
} finally {
if (typeof root !== 'undefined') {
root.freeRecursive();
}
config.free();
}
});
test('display_contents_with_position_absolute', () => {
const config = Yoga.Config.create();
let root;
try {
root = Yoga.Node.create(config);
root.setFlexDirection(FlexDirection.Row);
root.setPositionType(PositionType.Absolute);
root.setWidth(100);
root.setHeight(100);
const root_child0 = Yoga.Node.create(config);
root_child0.setPositionType(PositionType.Absolute);
root_child0.setWidth(50);
root_child0.setHeight(50);
root_child0.setDisplay(Display.Contents);
root.insertChild(root_child0, 0);
const root_child0_child0 = Yoga.Node.create(config);
root_child0_child0.setFlexGrow(1);
root_child0_child0.setFlexShrink(1);
root_child0_child0.setFlexBasis("0%");
root_child0_child0.setHeight(10);
root_child0.insertChild(root_child0_child0, 0);
const root_child0_child1 = Yoga.Node.create(config);
root_child0_child1.setFlexGrow(1);
root_child0_child1.setFlexShrink(1);
root_child0_child1.setFlexBasis("0%");
root_child0_child1.setHeight(20);
root_child0.insertChild(root_child0_child1, 1);
root.calculateLayout(undefined, undefined, Direction.LTR);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(0);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(50);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
root.calculateLayout(undefined, undefined, Direction.RTL);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(50);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child1.getComputedLeft()).toBe(0);
expect(root_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child1.getComputedHeight()).toBe(20);
} finally {
if (typeof root !== 'undefined') {
root.freeRecursive();
}
config.free();
}
});
test('display_contents_nested', () => {
const config = Yoga.Config.create();
let root;
try {
root = Yoga.Node.create(config);
root.setFlexDirection(FlexDirection.Row);
root.setPositionType(PositionType.Absolute);
root.setWidth(100);
root.setHeight(100);
const root_child0 = Yoga.Node.create(config);
root_child0.setDisplay(Display.Contents);
root.insertChild(root_child0, 0);
const root_child0_child0 = Yoga.Node.create(config);
root_child0_child0.setDisplay(Display.Contents);
root_child0.insertChild(root_child0_child0, 0);
const root_child0_child0_child0 = Yoga.Node.create(config);
root_child0_child0_child0.setFlexGrow(1);
root_child0_child0_child0.setFlexShrink(1);
root_child0_child0_child0.setFlexBasis("0%");
root_child0_child0_child0.setHeight(10);
root_child0_child0.insertChild(root_child0_child0_child0, 0);
const root_child0_child0_child1 = Yoga.Node.create(config);
root_child0_child0_child1.setFlexGrow(1);
root_child0_child0_child1.setFlexShrink(1);
root_child0_child0_child1.setFlexBasis("0%");
root_child0_child0_child1.setHeight(20);
root_child0_child0.insertChild(root_child0_child0_child1, 1);
root.calculateLayout(undefined, undefined, Direction.LTR);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(0);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(0);
expect(root_child0_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0_child0.getComputedLeft()).toBe(0);
expect(root_child0_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child0_child1.getComputedLeft()).toBe(50);
expect(root_child0_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child0_child1.getComputedHeight()).toBe(20);
root.calculateLayout(undefined, undefined, Direction.RTL);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(0);
expect(root_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0.getComputedLeft()).toBe(0);
expect(root_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0.getComputedWidth()).toBe(0);
expect(root_child0_child0.getComputedHeight()).toBe(0);
expect(root_child0_child0_child0.getComputedLeft()).toBe(50);
expect(root_child0_child0_child0.getComputedTop()).toBe(0);
expect(root_child0_child0_child0.getComputedWidth()).toBe(50);
expect(root_child0_child0_child0.getComputedHeight()).toBe(10);
expect(root_child0_child0_child1.getComputedLeft()).toBe(0);
expect(root_child0_child0_child1.getComputedTop()).toBe(0);
expect(root_child0_child0_child1.getComputedWidth()).toBe(50);
expect(root_child0_child0_child1.getComputedHeight()).toBe(20);
} finally {
if (typeof root !== 'undefined') {
root.freeRecursive();
}
config.free();
}
});
test('display_contents_with_siblings', () => {
const config = Yoga.Config.create();
let root;
try {
root = Yoga.Node.create(config);
root.setFlexDirection(FlexDirection.Row);
root.setPositionType(PositionType.Absolute);
root.setWidth(100);
root.setHeight(100);
const root_child0 = Yoga.Node.create(config);
root_child0.setFlexGrow(1);
root_child0.setFlexShrink(1);
root_child0.setFlexBasis("0%");
root_child0.setHeight(30);
root.insertChild(root_child0, 0);
const root_child1 = Yoga.Node.create(config);
root_child1.setDisplay(Display.Contents);
root.insertChild(root_child1, 1);
const root_child1_child0 = Yoga.Node.create(config);
root_child1_child0.setFlexGrow(1);
root_child1_child0.setFlexShrink(1);
root_child1_child0.setFlexBasis("0%");
root_child1_child0.setHeight(10);
root_child1.insertChild(root_child1_child0, 0);
const root_child1_child1 = Yoga.Node.create(config);
root_child1_child1.setFlexGrow(1);
root_child1_child1.setFlexShrink(1);
root_child1_child1.setFlexBasis("0%");
root_child1_child1.setHeight(20);
root_child1.insertChild(root_child1_child1, 1);
const root_child2 = Yoga.Node.create(config);
root_child2.setFlexGrow(1);
root_child2.setFlexShrink(1);
root_child2.setFlexBasis("0%");
root_child2.setHeight(30);
root.insertChild(root_child2, 2);
root.calculateLayout(undefined, undefined, Direction.LTR);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(0);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(25);
expect(root_child0.getComputedHeight()).toBe(30);
expect(root_child1.getComputedLeft()).toBe(0);
expect(root_child1.getComputedTop()).toBe(0);
expect(root_child1.getComputedWidth()).toBe(0);
expect(root_child1.getComputedHeight()).toBe(0);
expect(root_child1_child0.getComputedLeft()).toBe(25);
expect(root_child1_child0.getComputedTop()).toBe(0);
expect(root_child1_child0.getComputedWidth()).toBe(25);
expect(root_child1_child0.getComputedHeight()).toBe(10);
expect(root_child1_child1.getComputedLeft()).toBe(50);
expect(root_child1_child1.getComputedTop()).toBe(0);
expect(root_child1_child1.getComputedWidth()).toBe(25);
expect(root_child1_child1.getComputedHeight()).toBe(20);
expect(root_child2.getComputedLeft()).toBe(75);
expect(root_child2.getComputedTop()).toBe(0);
expect(root_child2.getComputedWidth()).toBe(25);
expect(root_child2.getComputedHeight()).toBe(30);
root.calculateLayout(undefined, undefined, Direction.RTL);
expect(root.getComputedLeft()).toBe(0);
expect(root.getComputedTop()).toBe(0);
expect(root.getComputedWidth()).toBe(100);
expect(root.getComputedHeight()).toBe(100);
expect(root_child0.getComputedLeft()).toBe(75);
expect(root_child0.getComputedTop()).toBe(0);
expect(root_child0.getComputedWidth()).toBe(25);
expect(root_child0.getComputedHeight()).toBe(30);
expect(root_child1.getComputedLeft()).toBe(0);
expect(root_child1.getComputedTop()).toBe(0);
expect(root_child1.getComputedWidth()).toBe(0);
expect(root_child1.getComputedHeight()).toBe(0);
expect(root_child1_child0.getComputedLeft()).toBe(50);
expect(root_child1_child0.getComputedTop()).toBe(0);
expect(root_child1_child0.getComputedWidth()).toBe(25);
expect(root_child1_child0.getComputedHeight()).toBe(10);
expect(root_child1_child1.getComputedLeft()).toBe(25);
expect(root_child1_child1.getComputedTop()).toBe(0);
expect(root_child1_child1.getComputedWidth()).toBe(25);
expect(root_child1_child1.getComputedHeight()).toBe(20);
expect(root_child2.getComputedLeft()).toBe(0);
expect(root_child2.getComputedTop()).toBe(0);
expect(root_child2.getComputedWidth()).toBe(25);
expect(root_child2.getComputedHeight()).toBe(30);
} finally {
if (typeof root !== 'undefined') {
root.freeRecursive();
}
config.free();
}
});

View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* clang-format off
* @generated SignedSource<<a314a86c9d90aabdfd6ac470fe385f06>>
* generated by gentest/gentest-driver.ts from gentest/fixtures/YGDisplayContentsTest.html
*/
#include <gtest/gtest.h>
#include <yoga/Yoga.h>
#include "../util/TestUtil.h"
TEST(YogaTest, test1) {
YGConfigRef config = YGConfigNew();
YGNodeRef root = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
YGNodeRef root_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetDisplay(root_child0, YGDisplayContents);
YGNodeInsertChild(root, root_child0, 0);
YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child0, 1);
YGNodeStyleSetFlexShrink(root_child0_child0, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0);
YGNodeStyleSetHeight(root_child0_child0, 10);
YGNodeInsertChild(root_child0, root_child0_child0, 0);
YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child1, 1);
YGNodeStyleSetFlexShrink(root_child0_child1, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0);
YGNodeStyleSetHeight(root_child0_child1, 20);
YGNodeInsertChild(root_child0, root_child0_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeFreeRecursive(root);
YGConfigFree(config);
}

View File

@@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
* *
* clang-format off * clang-format off
* @generated SignedSource<<69ab4deb447f7daa2a701ed648532b50>> * @generated SignedSource<<d91c4f580be7ed7ca61c5a3b98d47333>>
* generated by gentest/gentest-driver.ts from gentest/fixtures/YGDisplayTest.html * generated by gentest/gentest-driver.ts from gentest/fixtures/YGDisplayTest.html
*/ */
@@ -379,3 +379,647 @@ TEST(YogaTest, display_none_with_position_absolute) {
YGConfigFree(config); YGConfigFree(config);
} }
TEST(YogaTest, display_contents) {
YGConfigRef config = YGConfigNew();
YGNodeRef root = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
YGNodeRef root_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetDisplay(root_child0, YGDisplayContents);
YGNodeInsertChild(root, root_child0, 0);
YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child0, 1);
YGNodeStyleSetFlexShrink(root_child0_child0, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0);
YGNodeStyleSetHeight(root_child0_child0, 10);
YGNodeInsertChild(root_child0, root_child0_child0, 0);
YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child1, 1);
YGNodeStyleSetFlexShrink(root_child0_child1, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0);
YGNodeStyleSetHeight(root_child0_child1, 20);
YGNodeInsertChild(root_child0, root_child0_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeFreeRecursive(root);
YGConfigFree(config);
}
TEST(YogaTest, display_contents_fixed_size) {
YGConfigRef config = YGConfigNew();
YGNodeRef root = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
YGNodeRef root_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetWidth(root_child0, 50);
YGNodeStyleSetHeight(root_child0, 50);
YGNodeStyleSetDisplay(root_child0, YGDisplayContents);
YGNodeInsertChild(root, root_child0, 0);
YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child0, 1);
YGNodeStyleSetFlexShrink(root_child0_child0, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0);
YGNodeStyleSetHeight(root_child0_child0, 10);
YGNodeInsertChild(root_child0, root_child0_child0, 0);
YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child1, 1);
YGNodeStyleSetFlexShrink(root_child0_child1, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0);
YGNodeStyleSetHeight(root_child0_child1, 20);
YGNodeInsertChild(root_child0, root_child0_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeFreeRecursive(root);
YGConfigFree(config);
}
TEST(YogaTest, display_contents_with_margin) {
YGConfigRef config = YGConfigNew();
YGNodeRef root = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
YGNodeRef root_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 10);
YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10);
YGNodeStyleSetMargin(root_child0, YGEdgeRight, 10);
YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 10);
YGNodeStyleSetWidth(root_child0, 20);
YGNodeStyleSetHeight(root_child0, 20);
YGNodeStyleSetDisplay(root_child0, YGDisplayContents);
YGNodeInsertChild(root, root_child0, 0);
YGNodeRef root_child1 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child1, 1);
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(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1));
YGNodeFreeRecursive(root);
YGConfigFree(config);
}
TEST(YogaTest, display_contents_with_padding) {
YGConfigRef config = YGConfigNew();
YGNodeRef root = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
YGNodeRef root_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 10);
YGNodeStyleSetPadding(root_child0, YGEdgeTop, 10);
YGNodeStyleSetPadding(root_child0, YGEdgeRight, 10);
YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 10);
YGNodeStyleSetDisplay(root_child0, YGDisplayContents);
YGNodeInsertChild(root, root_child0, 0);
YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child0, 1);
YGNodeStyleSetFlexShrink(root_child0_child0, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0);
YGNodeStyleSetHeight(root_child0_child0, 10);
YGNodeInsertChild(root_child0, root_child0_child0, 0);
YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child1, 1);
YGNodeStyleSetFlexShrink(root_child0_child1, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0);
YGNodeStyleSetHeight(root_child0_child1, 20);
YGNodeInsertChild(root_child0, root_child0_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeFreeRecursive(root);
YGConfigFree(config);
}
TEST(YogaTest, display_contents_with_position) {
YGConfigRef config = YGConfigNew();
YGNodeRef root = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
YGNodeRef root_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10);
YGNodeStyleSetDisplay(root_child0, YGDisplayContents);
YGNodeInsertChild(root, root_child0, 0);
YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child0, 1);
YGNodeStyleSetFlexShrink(root_child0_child0, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0);
YGNodeStyleSetHeight(root_child0_child0, 10);
YGNodeInsertChild(root_child0, root_child0_child0, 0);
YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child1, 1);
YGNodeStyleSetFlexShrink(root_child0_child1, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0);
YGNodeStyleSetHeight(root_child0_child1, 20);
YGNodeInsertChild(root_child0, root_child0_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeFreeRecursive(root);
YGConfigFree(config);
}
TEST(YogaTest, display_contents_with_position_absolute) {
YGConfigRef config = YGConfigNew();
YGNodeRef root = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
YGNodeRef root_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute);
YGNodeStyleSetWidth(root_child0, 50);
YGNodeStyleSetHeight(root_child0, 50);
YGNodeStyleSetDisplay(root_child0, YGDisplayContents);
YGNodeInsertChild(root, root_child0, 0);
YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child0, 1);
YGNodeStyleSetFlexShrink(root_child0_child0, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0);
YGNodeStyleSetHeight(root_child0_child0, 10);
YGNodeInsertChild(root_child0, root_child0_child0, 0);
YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child1, 1);
YGNodeStyleSetFlexShrink(root_child0_child1, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0);
YGNodeStyleSetHeight(root_child0_child1, 20);
YGNodeInsertChild(root_child0, root_child0_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeFreeRecursive(root);
YGConfigFree(config);
}
TEST(YogaTest, display_contents_nested) {
YGConfigRef config = YGConfigNew();
YGNodeRef root = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
YGNodeRef root_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetDisplay(root_child0, YGDisplayContents);
YGNodeInsertChild(root, root_child0, 0);
YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetDisplay(root_child0_child0, YGDisplayContents);
YGNodeInsertChild(root_child0, root_child0_child0, 0);
YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child0_child0, 1);
YGNodeStyleSetFlexShrink(root_child0_child0_child0, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child0_child0, 0);
YGNodeStyleSetHeight(root_child0_child0_child0, 10);
YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0);
YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0_child0_child1, 1);
YGNodeStyleSetFlexShrink(root_child0_child0_child1, 1);
YGNodeStyleSetFlexBasisPercent(root_child0_child0_child1, 0);
YGNodeStyleSetHeight(root_child0_child0_child1, 20);
YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0_child1));
YGNodeFreeRecursive(root);
YGConfigFree(config);
}
TEST(YogaTest, display_contents_with_siblings) {
YGConfigRef config = YGConfigNew();
YGNodeRef root = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
YGNodeRef root_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child0, 1);
YGNodeStyleSetFlexShrink(root_child0, 1);
YGNodeStyleSetFlexBasisPercent(root_child0, 0);
YGNodeStyleSetHeight(root_child0, 30);
YGNodeInsertChild(root, root_child0, 0);
YGNodeRef root_child1 = YGNodeNewWithConfig(config);
YGNodeStyleSetDisplay(root_child1, YGDisplayContents);
YGNodeInsertChild(root, root_child1, 1);
YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child1_child0, 1);
YGNodeStyleSetFlexShrink(root_child1_child0, 1);
YGNodeStyleSetFlexBasisPercent(root_child1_child0, 0);
YGNodeStyleSetHeight(root_child1_child0, 10);
YGNodeInsertChild(root_child1, root_child1_child0, 0);
YGNodeRef root_child1_child1 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child1_child1, 1);
YGNodeStyleSetFlexShrink(root_child1_child1, 1);
YGNodeStyleSetFlexBasisPercent(root_child1_child1, 0);
YGNodeStyleSetHeight(root_child1_child1, 20);
YGNodeInsertChild(root_child1, root_child1_child1, 1);
YGNodeRef root_child2 = YGNodeNewWithConfig(config);
YGNodeStyleSetFlexGrow(root_child2, 1);
YGNodeStyleSetFlexShrink(root_child2, 1);
YGNodeStyleSetFlexBasisPercent(root_child2, 0);
YGNodeStyleSetHeight(root_child2, 30);
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(100, 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(25, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1));
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0));
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1));
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child1));
ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child2));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2));
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2));
ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0));
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0));
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0));
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1));
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1));
ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2));
ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2));
ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2));
YGNodeFreeRecursive(root);
YGConfigFree(config);
}

View File

@@ -71,6 +71,8 @@ const char* YGDisplayToString(const YGDisplay value) {
return "flex"; return "flex";
case YGDisplayNone: case YGDisplayNone:
return "none"; return "none";
case YGDisplayContents:
return "contents";
} }
return "unknown"; return "unknown";
} }

View File

@@ -43,7 +43,8 @@ YG_ENUM_DECL(
YG_ENUM_DECL( YG_ENUM_DECL(
YGDisplay, YGDisplay,
YGDisplayFlex, YGDisplayFlex,
YGDisplayNone) YGDisplayNone,
YGDisplayContents)
YG_ENUM_DECL( YG_ENUM_DECL(
YGEdge, YGEdge,

View File

@@ -434,7 +434,7 @@ bool layoutAbsoluteDescendants(
float containingNodeAvailableInnerWidth, float containingNodeAvailableInnerWidth,
float containingNodeAvailableInnerHeight) { float containingNodeAvailableInnerHeight) {
bool hasNewLayout = false; bool hasNewLayout = false;
for (auto child : currentNode->getChildren()) { for (auto child : currentNode->getLayoutChildren()) {
if (child->style().display() == Display::None) { if (child->style().display() == Display::None) {
continue; continue;
} else if (child->style().positionType() == PositionType::Absolute) { } else if (child->style().positionType() == PositionType::Absolute) {

View File

@@ -32,9 +32,7 @@ float calculateBaseline(const yoga::Node* node) {
} }
yoga::Node* baselineChild = nullptr; yoga::Node* baselineChild = nullptr;
const size_t childCount = node->getChildCount(); for (auto child : node->getLayoutChildren()) {
for (size_t i = 0; i < childCount; i++) {
auto child = node->getChild(i);
if (child->getLineIndex() > 0) { if (child->getLineIndex() > 0) {
break; break;
} }
@@ -67,9 +65,7 @@ bool isBaselineLayout(const yoga::Node* node) {
if (node->style().alignItems() == Align::Baseline) { if (node->style().alignItems() == Align::Baseline) {
return true; return true;
} }
const auto childCount = node->getChildCount(); for (auto child : node->getLayoutChildren()) {
for (size_t i = 0; i < childCount; i++) {
auto child = node->getChild(i);
if (child->style().positionType() != PositionType::Absolute && if (child->style().positionType() != PositionType::Absolute &&
child->style().alignSelf() == Align::Baseline) { child->style().alignSelf() == Align::Baseline) {
return true; return true;

View File

@@ -476,6 +476,21 @@ static void zeroOutLayoutRecursively(yoga::Node* const node) {
} }
} }
static void cleanupContentsNodesRecursively(yoga::Node* const node) {
for (auto child : node->getChildren()) {
if (child->style().display() == Display::Contents) {
child->getLayout() = {};
child->setLayoutDimension(0, Dimension::Width);
child->setLayoutDimension(0, Dimension::Height);
child->setHasNewLayout(true);
child->setDirty(false);
child->cloneChildrenIfNeeded();
cleanupContentsNodesRecursively(child);
}
}
}
static float calculateAvailableInnerDimension( static float calculateAvailableInnerDimension(
const yoga::Node* const node, const yoga::Node* const node,
const Direction direction, const Direction direction,
@@ -525,7 +540,7 @@ static float computeFlexBasisForChildren(
const uint32_t generationCount) { const uint32_t generationCount) {
float totalOuterFlexBasis = 0.0f; float totalOuterFlexBasis = 0.0f;
YGNodeRef singleFlexChild = nullptr; YGNodeRef singleFlexChild = nullptr;
const auto& children = node->getChildren(); const auto& children = node->getLayoutChildren();
SizingMode sizingModeMainDim = SizingMode sizingModeMainDim =
isRow(mainAxis) ? widthSizingMode : heightSizingMode; isRow(mainAxis) ? widthSizingMode : heightSizingMode;
// If there is only one child with flexGrow + flexShrink it means we can set // If there is only one child with flexGrow + flexShrink it means we can set
@@ -1316,7 +1331,7 @@ static void calculateLayoutImpl(
return; return;
} }
const auto childCount = node->getChildCount(); const auto childCount = node->getLayoutChildCount();
if (childCount == 0) { if (childCount == 0) {
measureNodeWithoutChildren( measureNodeWithoutChildren(
node, node,
@@ -1351,6 +1366,9 @@ static void calculateLayoutImpl(
// Reset layout flags, as they could have changed. // Reset layout flags, as they could have changed.
node->setLayoutHadOverflow(false); node->setLayoutHadOverflow(false);
// Clean and update all display: contents nodes with a direct path to the
// current node as they will not be traversed
cleanupContentsNodesRecursively(node);
// STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM
const FlexDirection mainAxis = const FlexDirection mainAxis =
resolveDirection(node->style().flexDirection(), direction); resolveDirection(node->style().flexDirection(), direction);
@@ -1436,9 +1454,9 @@ static void calculateLayoutImpl(
} }
// STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES
// Indexes of children that represent the first and last items in the line. // Iterator representing the beginning of the current line
size_t startOfLineIndex = 0; Node::LayoutableChildren::Iterator startOfLineIterator =
size_t endOfLineIndex = 0; node->getLayoutChildren().begin();
// Number of lines. // Number of lines.
size_t lineCount = 0; size_t lineCount = 0;
@@ -1451,8 +1469,7 @@ static void calculateLayoutImpl(
// Max main dimension of all the lines. // Max main dimension of all the lines.
float maxLineMainDim = 0; float maxLineMainDim = 0;
for (; endOfLineIndex < childCount; for (; startOfLineIterator != node->getLayoutChildren().end(); lineCount++) {
lineCount++, startOfLineIndex = endOfLineIndex) {
auto flexLine = calculateFlexLine( auto flexLine = calculateFlexLine(
node, node,
ownerDirection, ownerDirection,
@@ -1460,11 +1477,9 @@ static void calculateLayoutImpl(
mainAxisOwnerSize, mainAxisOwnerSize,
availableInnerWidth, availableInnerWidth,
availableInnerMainDim, availableInnerMainDim,
startOfLineIndex, startOfLineIterator,
lineCount); lineCount);
endOfLineIndex = flexLine.endOfLineIndex;
// If we don't need to measure the cross axis, we can skip the entire flex // If we don't need to measure the cross axis, we can skip the entire flex
// step. // step.
const bool canSkipFlex = const bool canSkipFlex =
@@ -1816,17 +1831,18 @@ static void calculateLayoutImpl(
case Align::Baseline: case Align::Baseline:
break; break;
} }
size_t endIndex = 0; Node::LayoutableChildren::Iterator endIterator =
node->getLayoutChildren().begin();
for (size_t i = 0; i < lineCount; i++) { for (size_t i = 0; i < lineCount; i++) {
const size_t startIndex = endIndex; const Node::LayoutableChildren::Iterator startIterator = endIterator;
size_t ii = startIndex; auto iterator = startIterator;
// compute the line's height and find the endIndex // compute the line's height and find the endIndex
float lineHeight = 0; float lineHeight = 0;
float maxAscentForCurrentLine = 0; float maxAscentForCurrentLine = 0;
float maxDescentForCurrentLine = 0; float maxDescentForCurrentLine = 0;
for (; ii < childCount; ii++) { for (; iterator != node->getLayoutChildren().end(); iterator++) {
const auto child = node->getChild(ii); const auto child = *iterator;
if (child->style().display() == Display::None) { if (child->style().display() == Display::None) {
continue; continue;
} }
@@ -1859,11 +1875,11 @@ static void calculateLayoutImpl(
} }
} }
} }
endIndex = ii; endIterator = iterator;
currentLead += i != 0 ? crossAxisGap : 0; currentLead += i != 0 ? crossAxisGap : 0;
for (ii = startIndex; ii < endIndex; ii++) { for (iterator = startIterator; iterator != endIterator; iterator++) {
const auto child = node->getChild(ii); const auto child = *iterator;
if (child->style().display() == Display::None) { if (child->style().display() == Display::None) {
continue; continue;
} }
@@ -2066,8 +2082,7 @@ static void calculateLayoutImpl(
// As we only wrapped in normal direction yet, we need to reverse the // As we only wrapped in normal direction yet, we need to reverse the
// positions on wrap-reverse. // positions on wrap-reverse.
if (performLayout && node->style().flexWrap() == Wrap::WrapReverse) { if (performLayout && node->style().flexWrap() == Wrap::WrapReverse) {
for (size_t i = 0; i < childCount; i++) { for (auto child : node->getLayoutChildren()) {
const auto child = node->getChild(i);
if (child->style().positionType() != PositionType::Absolute) { if (child->style().positionType() != PositionType::Absolute) {
child->setLayoutPosition( child->setLayoutPosition(
node->getLayout().measuredDimension(dimension(crossAxis)) - node->getLayout().measuredDimension(dimension(crossAxis)) -
@@ -2084,8 +2099,7 @@ static void calculateLayoutImpl(
const bool needsCrossTrailingPos = needsTrailingPosition(crossAxis); const bool needsCrossTrailingPos = needsTrailingPosition(crossAxis);
if (needsMainTrailingPos || needsCrossTrailingPos) { if (needsMainTrailingPos || needsCrossTrailingPos) {
for (size_t i = 0; i < childCount; i++) { for (auto child : node->getLayoutChildren()) {
const auto child = node->getChild(i);
// Absolute children will be handled by their containing block since we // Absolute children will be handled by their containing block since we
// cannot guarantee that their positions are set when their parents are // cannot guarantee that their positions are set when their parents are
// done with layout. // done with layout.

View File

@@ -20,17 +20,17 @@ FlexLine calculateFlexLine(
const float mainAxisownerSize, const float mainAxisownerSize,
const float availableInnerWidth, const float availableInnerWidth,
const float availableInnerMainDim, const float availableInnerMainDim,
const size_t startOfLineIndex, Node::LayoutableChildren::Iterator& iterator,
const size_t lineCount) { const size_t lineCount) {
std::vector<yoga::Node*> itemsInFlow; std::vector<yoga::Node*> itemsInFlow;
itemsInFlow.reserve(node->getChildren().size()); itemsInFlow.reserve(node->getChildCount());
float sizeConsumed = 0.0f; float sizeConsumed = 0.0f;
float totalFlexGrowFactors = 0.0f; float totalFlexGrowFactors = 0.0f;
float totalFlexShrinkScaledFactors = 0.0f; float totalFlexShrinkScaledFactors = 0.0f;
size_t numberOfAutoMargins = 0; size_t numberOfAutoMargins = 0;
size_t endOfLineIndex = startOfLineIndex; size_t endOfLineIndex = iterator.index();
size_t firstElementInLineIndex = startOfLineIndex; size_t firstElementInLineIndex = iterator.index();
float sizeConsumedIncludingMinConstraint = 0; float sizeConsumedIncludingMinConstraint = 0;
const Direction direction = node->resolveDirection(ownerDirection); const Direction direction = node->resolveDirection(ownerDirection);
@@ -41,8 +41,9 @@ FlexLine calculateFlexLine(
node->style().computeGapForAxis(mainAxis, availableInnerMainDim); node->style().computeGapForAxis(mainAxis, availableInnerMainDim);
// Add items to the current line until it's full or we run out of items. // Add items to the current line until it's full or we run out of items.
for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) { for (; iterator != node->getLayoutChildren().end();
auto child = node->getChild(endOfLineIndex); iterator++, endOfLineIndex = iterator.index()) {
auto child = *iterator;
if (child->style().display() == Display::None || if (child->style().display() == Display::None ||
child->style().positionType() == PositionType::Absolute) { child->style().positionType() == PositionType::Absolute) {
if (firstElementInLineIndex == endOfLineIndex) { if (firstElementInLineIndex == endOfLineIndex) {

View File

@@ -72,7 +72,7 @@ FlexLine calculateFlexLine(
float mainAxisownerSize, float mainAxisownerSize,
float availableInnerWidth, float availableInnerWidth,
float availableInnerMainDim, float availableInnerMainDim,
size_t startOfLineIndex, Node::LayoutableChildren::Iterator& iterator,
size_t lineCount); size_t lineCount);
} // namespace facebook::yoga } // namespace facebook::yoga

View File

@@ -124,7 +124,7 @@ void roundLayoutResultsToPixelGrid(
Dimension::Height); Dimension::Height);
} }
for (yoga::Node* child : node->getChildren()) { for (yoga::Node* child : node->getLayoutChildren()) {
roundLayoutResultsToPixelGrid(child, absoluteNodeLeft, absoluteNodeTop); roundLayoutResultsToPixelGrid(child, absoluteNodeLeft, absoluteNodeTop);
} }
} }

View File

@@ -18,11 +18,12 @@ namespace facebook::yoga {
enum class Display : uint8_t { enum class Display : uint8_t {
Flex = YGDisplayFlex, Flex = YGDisplayFlex,
None = YGDisplayNone, None = YGDisplayNone,
Contents = YGDisplayContents,
}; };
template <> template <>
constexpr int32_t ordinalCount<Display>() { constexpr int32_t ordinalCount<Display>() {
return 2; return 3;
} }
constexpr Display scopedEnum(YGDisplay unscoped) { constexpr Display scopedEnum(YGDisplay unscoped) {

View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <cstdint>
#include <vector>
#include <yoga/enums/Display.h>
namespace facebook::yoga {
class Node;
template <typename T>
class LayoutableChildren {
public:
using Backtrack = std::vector<std::pair<const T*, size_t>>;
struct Iterator {
using iterator_category = std::input_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = T*;
using pointer = T*;
using reference = T*;
Iterator() = default;
Iterator(const T* node, size_t childIndex)
: node_(node), childIndex_(childIndex) {}
Iterator(const T* node, size_t childIndex, Backtrack&& backtrack)
: node_(node),
childIndex_(childIndex),
backtrack_(std::move(backtrack)) {}
T* operator*() const {
return node_->getChild(childIndex_);
}
Iterator& operator++() {
next();
currentNodeIndex_++;
return *this;
}
Iterator operator++(int) {
Iterator tmp = *this;
++(*this);
return tmp;
}
size_t index() const {
return currentNodeIndex_;
}
friend bool operator==(const Iterator& a, const Iterator& b) {
return a.node_ == b.node_ && a.childIndex_ == b.childIndex_;
}
friend bool operator!=(const Iterator& a, const Iterator& b) {
return a.node_ != b.node_ || a.childIndex_ != b.childIndex_;
}
private:
void next() {
if (childIndex_ + 1 >= node_->getChildCount()) {
// if the current node has no more children, try to backtrack and
// visit its successor
if (backtrack_.empty()) {
// if there are no nodes to backtrack to, the last node has been
// visited
*this = Iterator{};
} else {
// pop and restore the latest backtrack entry
const auto back = backtrack_.back();
backtrack_.pop_back();
node_ = back.first;
childIndex_ = back.second;
// go to the next node
next();
}
} else {
// current node has more children to visit, go to next
++childIndex_;
// skip all display: contents nodes, possibly going deeper into the
// tree
skipContentsNodes();
}
}
void skipContentsNodes() {
// get the node that would be returned from the iterator
auto currentNode = node_->getChild(childIndex_);
while (currentNode->style().display() == Display::Contents &&
currentNode->getChildCount() > 0) {
// if it has display: contents set, it shouldn't be returned but its
// children should in its place push the current node and child index
// so that the current state can be restored when backtracking
backtrack_.push_back({node_, childIndex_});
// traverse the child
node_ = currentNode;
childIndex_ = 0;
// repeat until a node without display: contents is found in the
// subtree or a leaf is reached
currentNode = currentNode->getChild(childIndex_);
}
// if no node without display: contents was found, try to backtrack
if (currentNode->style().display() == Display::Contents) {
next();
}
}
const T* node_{nullptr};
size_t childIndex_{0};
size_t currentNodeIndex_{0};
Backtrack backtrack_;
friend LayoutableChildren;
};
explicit LayoutableChildren(const T* node) : node_(node) {
static_assert(std::input_iterator<LayoutableChildren<T>::Iterator>);
static_assert(
std::is_base_of<Node, T>::value,
"Type parameter of LayoutableChildren must derive from yoga::Node");
}
Iterator begin() const {
if (node_->getChildCount() > 0) {
auto result = Iterator(node_, 0);
result.skipContentsNodes();
return result;
} else {
return Iterator{};
}
}
Iterator end() const {
return Iterator{};
}
private:
const T* node_;
};
} // namespace facebook::yoga

View File

@@ -41,6 +41,7 @@ Node::Node(Node&& node) noexcept
style_(std::move(node.style_)), style_(std::move(node.style_)),
layout_(node.layout_), layout_(node.layout_),
lineIndex_(node.lineIndex_), lineIndex_(node.lineIndex_),
contentsChildrenCount_(node.contentsChildrenCount_),
owner_(node.owner_), owner_(node.owner_),
children_(std::move(node.children_)), children_(std::move(node.children_)),
config_(node.config_), config_(node.config_),
@@ -116,14 +117,37 @@ void Node::setMeasureFunc(YGMeasureFunc measureFunc) {
} }
void Node::replaceChild(Node* child, size_t index) { void Node::replaceChild(Node* child, size_t index) {
auto previousChild = children_[index];
if (previousChild->style().display() == Display::Contents &&
child->style().display() != Display::Contents) {
contentsChildrenCount_--;
} else if (
previousChild->style().display() != Display::Contents &&
child->style().display() == Display::Contents) {
contentsChildrenCount_++;
}
children_[index] = child; children_[index] = child;
} }
void Node::replaceChild(Node* oldChild, Node* newChild) { void Node::replaceChild(Node* oldChild, Node* newChild) {
if (oldChild->style().display() == Display::Contents &&
newChild->style().display() != Display::Contents) {
contentsChildrenCount_--;
} else if (
oldChild->style().display() != Display::Contents &&
newChild->style().display() == Display::Contents) {
contentsChildrenCount_++;
}
std::replace(children_.begin(), children_.end(), oldChild, newChild); std::replace(children_.begin(), children_.end(), oldChild, newChild);
} }
void Node::insertChild(Node* child, size_t index) { void Node::insertChild(Node* child, size_t index) {
if (child->style().display() == Display::Contents) {
contentsChildrenCount_++;
}
children_.insert(children_.begin() + static_cast<ptrdiff_t>(index), child); children_.insert(children_.begin() + static_cast<ptrdiff_t>(index), child);
} }
@@ -160,6 +184,10 @@ void Node::setDirty(bool isDirty) {
bool Node::removeChild(Node* child) { bool Node::removeChild(Node* child) {
auto p = std::find(children_.begin(), children_.end(), child); auto p = std::find(children_.begin(), children_.end(), child);
if (p != children_.end()) { if (p != children_.end()) {
if (child->style().display() == Display::Contents) {
contentsChildrenCount_--;
}
children_.erase(p); children_.erase(p);
return true; return true;
} }
@@ -167,6 +195,10 @@ bool Node::removeChild(Node* child) {
} }
void Node::removeChild(size_t index) { void Node::removeChild(size_t index) {
if (children_[index]->style().display() == Display::Contents) {
contentsChildrenCount_--;
}
children_.erase(children_.begin() + static_cast<ptrdiff_t>(index)); children_.erase(children_.begin() + static_cast<ptrdiff_t>(index));
} }

View File

@@ -12,6 +12,7 @@
#include <vector> #include <vector>
#include <yoga/Yoga.h> #include <yoga/Yoga.h>
#include <yoga/node/LayoutableChildren.h>
#include <yoga/config/Config.h> #include <yoga/config/Config.h>
#include <yoga/enums/Dimension.h> #include <yoga/enums/Dimension.h>
@@ -31,6 +32,7 @@ namespace facebook::yoga {
class YG_EXPORT Node : public ::YGNode { class YG_EXPORT Node : public ::YGNode {
public: public:
using LayoutableChildren = yoga::LayoutableChildren<Node>;
Node(); Node();
explicit Node(const Config* config); explicit Node(const Config* config);
@@ -144,6 +146,24 @@ class YG_EXPORT Node : public ::YGNode {
return children_.size(); return children_.size();
} }
LayoutableChildren getLayoutChildren() const {
return LayoutableChildren(this);
}
size_t getLayoutChildCount() const {
if (contentsChildrenCount_ == 0) {
return children_.size();
} else {
size_t count = 0;
for (auto iter = getLayoutChildren().begin();
iter != getLayoutChildren().end();
iter++) {
count++;
}
return count;
}
}
const Config* getConfig() const { const Config* getConfig() const {
return config_; return config_;
} }
@@ -298,6 +318,7 @@ class YG_EXPORT Node : public ::YGNode {
Style style_; Style style_;
LayoutResults layout_; LayoutResults layout_;
size_t lineIndex_ = 0; size_t lineIndex_ = 0;
size_t contentsChildrenCount_ = 0;
Node* owner_ = nullptr; Node* owner_ = nullptr;
std::vector<Node*> children_; std::vector<Node*> children_;
const Config* config_; const Config* config_;