Skip to content

Commit ff60ebb

Browse files
authored
Merge pull request Expensify#65925 from software-mansion-labs/@jpiasecki/fix-display-contents-crash
[No QA] Fix yoga nodes with `display: contents` not updating shadow nodes
2 parents 384e542 + 6b14a2c commit ff60ebb

5 files changed

Lines changed: 135 additions & 8 deletions

File tree

ios/Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2847,7 +2847,7 @@ PODS:
28472847
- RNGoogleSignin (10.0.1):
28482848
- GoogleSignIn (~> 7.0)
28492849
- React-Core
2850-
- RNLiveMarkdown (0.1.288):
2850+
- RNLiveMarkdown (0.1.294):
28512851
- DoubleConversion
28522852
- glog
28532853
- hermes-engine
@@ -3716,7 +3716,7 @@ SPEC CHECKSUMS:
37163716
AirshipServiceExtension: 9c73369f426396d9fb9ff222d86d842fac76ba46
37173717
AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa
37183718
AppLogs: 3bc4e9b141dbf265b9464409caaa40416a9ee0e0
3719-
boost: 659a89341ea4ab3df8259733813b52f26d8be9a5
3719+
boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90
37203720
DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb
37213721
EXAV: 13d43af15268a3f448a6b994e91574c939f065e6
37223722
EXImageLoader: ab4fcf9240cf3636a83c00e3fc5229d692899428
@@ -3867,7 +3867,7 @@ SPEC CHECKSUMS:
38673867
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
38683868
RNGestureHandler: 5d8431415d4b8518e86e289e9ad5bb9be78f6dba
38693869
RNGoogleSignin: ccaa4a81582cf713eea562c5dd9dc1961a715fd0
3870-
RNLiveMarkdown: 1c09c5813366c29885b757b4c0a5e163a89f8d55
3870+
RNLiveMarkdown: 6e4972e95cf3b5ad0d164e08c72a6098d84e0b9d
38713871
RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81
38723872
rnmapbox-maps: ef00aafe2cbef8808f2aa6168e3f86ce103058bc
38733873
RNNitroSQLite: 44e596c1fb8f852f9a158eb07c647f706df13514

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
"@expensify/nitro-utils": "file:./modules/ExpensifyNitroUtils",
8787
"@expensify/react-native-background-task": "file:./modules/background-task",
8888
"@expensify/react-native-hybrid-app": "file:./modules/hybrid-app",
89-
"@expensify/react-native-live-markdown": "0.1.289",
89+
"@expensify/react-native-live-markdown": "0.1.294",
9090
"@expensify/react-native-wallet": "^0.1.5",
9191
"@expo/metro-runtime": "^5.0.4",
9292
"@firebase/app": "^0.10.10",

patches/react-native/details.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,10 @@
176176
- Upstream PR/issue: 🛑
177177
- E/App issue: 🛑
178178
- PR Introducing Patch: https://github.com/Expensify/App/pull/60421
179+
180+
### [react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch](react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch)
181+
182+
- Reason: This patch updates Yoga to correctly update the subtrees of `display: contents` nodes so that they are in sync with their React Native counterparts.
183+
- Upstream PR/issue: https://github.com/facebook/react-native/pull/52530
184+
- E/App issue: https://github.com/Expensify/App/issues/65268
185+
- PR introducing patch: [#65925](https://github.com/Expensify/App/pull/65925)
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
diff --git a/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp
2+
index 3618474..ab5b828 100644
3+
--- a/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp
4+
+++ b/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp
5+
@@ -476,16 +476,19 @@ static void zeroOutLayoutRecursively(yoga::Node* const node) {
6+
}
7+
8+
static void cleanupContentsNodesRecursively(yoga::Node* const node) {
9+
- for (auto child : node->getChildren()) {
10+
- if (child->style().display() == Display::Contents) {
11+
- child->getLayout() = {};
12+
- child->setLayoutDimension(0, Dimension::Width);
13+
- child->setLayoutDimension(0, Dimension::Height);
14+
- child->setHasNewLayout(true);
15+
- child->setDirty(false);
16+
- child->cloneChildrenIfNeeded();
17+
-
18+
- cleanupContentsNodesRecursively(child);
19+
+ if (node->hasContentsChildren()) [[unlikely]] {
20+
+ node->cloneContentsChildrenIfNeeded();
21+
+ for (auto child : node->getChildren()) {
22+
+ if (child->style().display() == Display::Contents) {
23+
+ child->getLayout() = {};
24+
+ child->setLayoutDimension(0, Dimension::Width);
25+
+ child->setLayoutDimension(0, Dimension::Height);
26+
+ child->setHasNewLayout(true);
27+
+ child->setDirty(false);
28+
+ child->cloneChildrenIfNeeded();
29+
+
30+
+ cleanupContentsNodesRecursively(child);
31+
+ }
32+
}
33+
}
34+
}
35+
diff --git a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp
36+
index dce42fb..f1bc5e8 100644
37+
--- a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp
38+
+++ b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp
39+
@@ -181,6 +181,17 @@ void Node::setDirty(bool isDirty) {
40+
}
41+
}
42+
43+
+void Node::setChildren(const std::vector<Node*>& children) {
44+
+ children_ = children;
45+
+
46+
+ contentsChildrenCount_ = 0;
47+
+ for (const auto& child : children) {
48+
+ if (child->style().display() == Display::Contents) {
49+
+ contentsChildrenCount_++;
50+
+ }
51+
+ }
52+
+}
53+
+
54+
bool Node::removeChild(Node* child) {
55+
auto p = std::find(children_.begin(), children_.end(), child);
56+
if (p != children_.end()) {
57+
@@ -379,6 +390,23 @@ void Node::cloneChildrenIfNeeded() {
58+
if (child->getOwner() != this) {
59+
child = resolveRef(config_->cloneNode(child, this, i));
60+
child->setOwner(this);
61+
+
62+
+ if (child->hasContentsChildren()) [[unlikely]] {
63+
+ child->cloneContentsChildrenIfNeeded();
64+
+ }
65+
+ }
66+
+ i += 1;
67+
+ }
68+
+}
69+
+
70+
+void Node::cloneContentsChildrenIfNeeded() {
71+
+ size_t i = 0;
72+
+ for (Node*& child : children_) {
73+
+ if (child->style().display() == Display::Contents &&
74+
+ child->getOwner() != this) {
75+
+ child = resolveRef(config_->cloneNode(child, this, i));
76+
+ child->setOwner(this);
77+
+ child->cloneChildrenIfNeeded();
78+
}
79+
i += 1;
80+
}
81+
diff --git a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h
82+
index 5ae7d43..3454d54 100644
83+
--- a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h
84+
+++ b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h
85+
@@ -96,6 +96,10 @@ class YG_EXPORT Node : public ::YGNode {
86+
return config_->hasErrata(errata);
87+
}
88+
89+
+ bool hasContentsChildren() const {
90+
+ return contentsChildrenCount_ != 0;
91+
+ }
92+
+
93+
YGDirtiedFunc getDirtiedFunc() const {
94+
return dirtiedFunc_;
95+
}
96+
@@ -244,15 +248,12 @@ class YG_EXPORT Node : public ::YGNode {
97+
owner_ = owner;
98+
}
99+
100+
- void setChildren(const std::vector<Node*>& children) {
101+
- children_ = children;
102+
- }
103+
-
104+
// TODO: rvalue override for setChildren
105+
106+
void setConfig(Config* config);
107+
108+
void setDirty(bool isDirty);
109+
+ void setChildren(const std::vector<Node*>& children);
110+
void setLayoutLastOwnerDirection(Direction direction);
111+
void setLayoutComputedFlexBasis(FloatOptional computedFlexBasis);
112+
void setLayoutComputedFlexBasisGeneration(
113+
@@ -286,6 +287,7 @@ class YG_EXPORT Node : public ::YGNode {
114+
void removeChild(size_t index);
115+
116+
void cloneChildrenIfNeeded();
117+
+ void cloneContentsChildrenIfNeeded();
118+
void markDirtyAndPropagate();
119+
float resolveFlexGrow() const;
120+
float resolveFlexShrink() const;

0 commit comments

Comments
 (0)