Skip to content

Fix node ownership when display: contents is used (#56422)#56422

Closed
j-piasecki wants to merge 1 commit into
react:mainfrom
j-piasecki:export-D100581579
Closed

Fix node ownership when display: contents is used (#56422)#56422
j-piasecki wants to merge 1 commit into
react:mainfrom
j-piasecki:export-D100581579

Conversation

@j-piasecki

@j-piasecki j-piasecki commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Summary:

Changelog: [GENERAL][FIXED] Fixed Yoga node ownership when display: contents is used in absolutely positioned subtrees

Fixes an edge case where nodes with display: contents weren't cloned properly inside absolutely positioned subtrees.

Adds a test case covering this scenario.

X-link: react/yoga#1924

Reviewed By: NickGerleman

Differential Revision: D100581579

Pulled By: j-piasecki

@meta-codesync

meta-codesync Bot commented Apr 13, 2026

Copy link
Copy Markdown

@j-piasecki has exported this pull request. If you are a Meta employee, you can view the originating Diff in D100581579.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Apr 13, 2026
@facebook-github-tools facebook-github-tools Bot added p: Software Mansion Partner: Software Mansion Partner p: Facebook Partner: Facebook labels Apr 13, 2026

@harikishan-45 harikishan-45 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okieeee

@meta-codesync meta-codesync Bot changed the title Fix node ownership when display: contents is used Fix node ownership when display: contents is used (#56422) Apr 20, 2026
@j-piasecki j-piasecki force-pushed the export-D100581579 branch 9 times, most recently from cc5b1dc to a65842e Compare April 20, 2026 12:32
Summary:

Changelog: [GENERAL][FIXED] Fixed Yoga node ownership when `display: contents` is used in absolutely positioned subtrees

Fixes an edge case where nodes with `display: contents` weren't cloned properly inside absolutely positioned subtrees.

Adds a test case covering this scenario.

X-link: react/yoga#1924

Reviewed By: NickGerleman

Differential Revision: D100581579

Pulled By: j-piasecki
j-piasecki added a commit to j-piasecki/yoga that referenced this pull request Apr 21, 2026
Summary:
X-link: react/react-native#56422

Changelog: [GENERAL][FIXED] Fixed Yoga node ownership when `display: contents` is used in absolutely positioned subtrees

Fixes an edge case where nodes with `display: contents` weren't cloned properly inside absolutely positioned subtrees.

Adds a test case covering this scenario.


Reviewed By: NickGerleman

Differential Revision: D100581579

Pulled By: j-piasecki
meta-codesync Bot pushed a commit to react/yoga that referenced this pull request Apr 21, 2026
Summary:
X-link: react/react-native#56422

Changelog: [GENERAL][FIXED] Fixed Yoga node ownership when `display: contents` is used in absolutely positioned subtrees

Fixes an edge case where nodes with `display: contents` weren't cloned properly inside absolutely positioned subtrees.

Adds a test case covering this scenario.

Pull Request resolved: #1924

Reviewed By: NickGerleman

Differential Revision: D100581579

Pulled By: j-piasecki

fbshipit-source-id: e05e9a4076bd11a71be438ef910a262044659a9b
@meta-codesync meta-codesync Bot closed this in f2f9209 Apr 21, 2026
@react-native-bot react-native-bot added the Merged This PR has been merged. label Apr 21, 2026
@react-native-bot

Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @j-piasecki in f2f9209

When will my fix make it into a release? | How to file a pick request?

@meta-codesync

meta-codesync Bot commented Apr 21, 2026

Copy link
Copy Markdown

@j-piasecki merged this pull request in f2f9209.

gabrieldonadel pushed a commit that referenced this pull request Jun 23, 2026
#57241)

* Expose cleanupContentsNodesRecursively for backport

Backport prerequisite: make cleanupContentsNodesRecursively externally
linkable and declare it in CalculateLayout.h so AbsoluteLayout.cpp can
call it. This mirrors the relevant slice of #55876 (26cef64), which
is not present on this branch, and is required before applying #56422
and #57103.

* Fix node ownership when `display: contents` is used (#56422)

Summary:
Pull Request resolved: #56422

Changelog: [GENERAL][FIXED] Fixed Yoga node ownership when `display: contents` is used in absolutely positioned subtrees

Fixes an edge case where nodes with `display: contents` weren't cloned properly inside absolutely positioned subtrees.

Adds a test case covering this scenario.

X-link: react/yoga#1924

Reviewed By: NickGerleman

Differential Revision: D100581579

Pulled By: j-piasecki

fbshipit-source-id: e05e9a4076bd11a71be438ef910a262044659a9b

* Fix `display: contents` nodes having `hasNewLayout` set incorrectly (#57103)

Summary:
Pull Request resolved: #57103

Changelog: [General][Fixed] Fixed `display: contents` nodes having `hasNewLayout` set incorrectly

`cleanupContentsNodesRecursively` unconditionally sets `hasNewLayout=true` on `display: contents` children, including on code paths where their parent's layout was not actually performed in this pass. The stale flag can survive across layout passes and, in clone-on-write renderers (e.g. React Native Fabric), be observed by a subsequent pass whose parent was cloned but whose layout was served from cache, leaving the contents child's owner pointing at the previous parent revision.

There are two paths through which the cleanup could stamp a contents child whose parent's `hasNewLayout` would end up false:

1. Measure-phase visit. Inside `calculateLayoutImpl`, the cleanup ran with no knowledge of `performLayout`. When the parent's `calculateLayoutImpl` was invoked only with `performLayout=false` (cache miss on measure, cache hit on layout), the cleanup stamped contents children even though the parent itself never had its `hasNewLayout` set.

2. Absolute-layout walk. `layoutAbsoluteDescendants` walks every static layout descendant of the containing block - including ones whose own `calculateLayoutImpl` was skipped via the layout-phase cache. The cleanup invoked along that walk unconditionally stamped contents children, but the parent's `hasNewLayout` was only updated when the recursion actually found new layout downstream.

In both cases, the result is the same invariant violation: a contents node with `hasNewLayout=true` whose parent has `hasNewLayout=false`. A consumer iterating the tree via `hasNewLayout` skips the parent and never clears the stale flag.

X-link: react/yoga#1970

Test Plan:
Added `YGContentsNodeHasNewLayoutTest.cpp` with regression tests:
- `contents_child_hasNewLayout_not_stamped_on_measure_only_visit` - pins the measure-phase fix
- `absolute_descendant_through_contents_is_reachable_via_hasNewLayout` - pins the positive case for absolute-layout path
- `absolute_phase_cleanup_does_not_stamp_when_parent_layout_skipped` - pins the negative case for absolute-layout path

Reviewed By: javache

Differential Revision: D107854528

Pulled By: j-piasecki

fbshipit-source-id: cae5e889622296e8b6380a6428509b5ffea3e9ae
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. meta-exported p: Facebook Partner: Facebook p: Software Mansion Partner: Software Mansion Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants