Skip to content

Commit e77f74c

Browse files
committed
Fix ownership with display contents
1 parent 8c5ea16 commit e77f74c

3 files changed

Lines changed: 49 additions & 1 deletion

File tree

tests/YGCloneNodeTest.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,48 @@ TEST(YogaTest, absolute_node_cloned_with_static_parent) {
4545
YGNodeFreeRecursive(clonedRoot);
4646
}
4747

48+
TEST(YogaTest, absolute_node_cloned_through_nested_display_contents) {
49+
YGNodeRef root = YGNodeNew();
50+
YGNodeStyleSetWidth(root, 100);
51+
YGNodeStyleSetHeight(root, 100);
52+
53+
YGNodeRef wrapper = YGNodeNew();
54+
YGNodeStyleSetPositionType(wrapper, YGPositionTypeStatic);
55+
YGNodeStyleSetWidth(wrapper, 50);
56+
YGNodeStyleSetHeight(wrapper, 50);
57+
YGNodeInsertChild(root, wrapper, 0);
58+
59+
YGNodeRef static1 = YGNodeNew();
60+
YGNodeStyleSetPositionType(static1, YGPositionTypeStatic);
61+
YGNodeStyleSetFlexGrow(static1, 1);
62+
YGNodeInsertChild(wrapper, static1, 0);
63+
64+
YGNodeRef contents1 = YGNodeNew();
65+
YGNodeStyleSetDisplay(contents1, YGDisplayContents);
66+
YGNodeInsertChild(static1, contents1, 0);
67+
68+
YGNodeRef contents2 = YGNodeNew();
69+
YGNodeStyleSetDisplay(contents2, YGDisplayContents);
70+
YGNodeInsertChild(contents1, contents2, 0);
71+
72+
YGNodeRef absolute = YGNodeNew();
73+
YGNodeStyleSetPositionType(absolute, YGPositionTypeAbsolute);
74+
YGNodeStyleSetWidthPercent(absolute, 50);
75+
YGNodeStyleSetHeight(absolute, 1);
76+
YGNodeInsertChild(contents2, absolute, 0);
77+
78+
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
79+
80+
YGNodeRef clonedRoot = YGNodeClone(root);
81+
YGNodeStyleSetWidth(clonedRoot, 200);
82+
YGNodeCalculateLayout(clonedRoot, YGUndefined, YGUndefined, YGDirectionLTR);
83+
84+
recursivelyAssertProperNodeOwnership(clonedRoot);
85+
86+
YGNodeFreeRecursive(root);
87+
YGNodeFreeRecursive(clonedRoot);
88+
}
89+
4890
TEST(YogaTest, absolute_node_cloned_with_static_ancestors) {
4991
YGNodeRef root = YGNodeNew();
5092
YGNodeStyleSetWidth(root, 100);

yoga/algorithm/AbsoluteLayout.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ bool layoutAbsoluteDescendants(
558558
// we need to mutate these descendents. Make sure the path of
559559
// nodes to them is mutable before positioning.
560560
child->cloneChildrenIfNeeded();
561+
cleanupContentsNodesRecursively(child);
561562
const Direction childDirection =
562563
child->resolveDirection(currentNodeDirection);
563564
// By now all descendants of the containing block that are not absolute

yoga/node/Node.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,12 @@ void Node::cloneChildrenIfNeeded() {
392392
child = resolveRef(config_->cloneNode(child, this, i));
393393
child->setOwner(this);
394394

395-
if (child->hasContentsChildren()) [[unlikely]] {
395+
if (child->style().display() == Display::Contents) [[unlikely]] {
396+
// The contents node's children are treated as children of the
397+
// contents node's parent for layout purposes, so they need
398+
// to be cloned as well.
399+
child->cloneChildrenIfNeeded();
400+
} else if (child->hasContentsChildren()) [[unlikely]] {
396401
child->cloneContentsChildrenIfNeeded();
397402
}
398403
}

0 commit comments

Comments
 (0)