From f8252f6d346fcce2fbc14acf6090b7d127fdb60e Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Fri, 11 Jul 2025 12:00:05 +0200 Subject: [PATCH 1/3] Fix display contents not updating nodes --- ios/Podfile.lock | 26 +--- package-lock.json | 8 +- package.json | 2 +- ...-display-contents-not-updating-nodes.patch | 120 ++++++++++++++++++ 4 files changed, 131 insertions(+), 25 deletions(-) create mode 100644 patches/react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6a614a30b637..800f10332475 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -487,7 +487,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -506,7 +505,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -524,7 +522,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -544,7 +541,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -563,7 +559,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -582,7 +577,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -601,7 +595,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -620,7 +613,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -639,7 +631,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -658,7 +649,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -677,7 +667,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -696,7 +685,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -715,7 +703,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -734,7 +721,6 @@ PODS: - React-jsinspector - React-jsitooling - React-perflogger - - React-rendererconsistency - React-runtimescheduler - React-utils - SocketRocket (= 0.7.1) @@ -2847,7 +2833,7 @@ PODS: - RNGoogleSignin (10.0.1): - GoogleSignIn (~> 7.0) - React-Core - - RNLiveMarkdown (0.1.288): + - RNLiveMarkdown (0.1.292): - DoubleConversion - glog - hermes-engine @@ -3716,7 +3702,7 @@ SPEC CHECKSUMS: AirshipServiceExtension: 9c73369f426396d9fb9ff222d86d842fac76ba46 AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa AppLogs: 3bc4e9b141dbf265b9464409caaa40416a9ee0e0 - boost: 659a89341ea4ab3df8259733813b52f26d8be9a5 + boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb EXAV: 13d43af15268a3f448a6b994e91574c939f065e6 EXImageLoader: ab4fcf9240cf3636a83c00e3fc5229d692899428 @@ -3776,7 +3762,7 @@ SPEC CHECKSUMS: RCTTypeSafety: 659ae318c09de0477fd27bbc9e140071c7ea5c93 React: c2d3aa44c49bb34e4dfd49d3ee92da5ebacc1c1c React-callinvoker: 1bdfb7549b5af266d85757193b5069f60659ef9d - React-Core: 7e3642ef83e1032df3d25ebc840868c0c54381ca + React-Core: 7150cf9b6a5af063b37003062689f1691e79c020 React-CoreModules: 15a85e6665d61678942da6ae485b351f4c699049 React-cxxreact: 74f9de59259ac951923f5726aa14f0398f167af9 React-debug: e74e76912b91e08d580c481c34881899ccf63da9 @@ -3825,7 +3811,7 @@ SPEC CHECKSUMS: react-native-webview: 0f56a0e7348f945abdc92546dc62ce93d083fa75 React-NativeModulesApple: 452b86b29fae99ed0a4015dca3ad9cd222f88abf React-oscompat: ef5df1c734f19b8003e149317d041b8ce1f7d29c - React-perflogger: 005c6dfd4aa335fd527c94cc4591ed9b509f0486 + React-perflogger: 6fd2f6811533e9c19a61e855c3033eecbf4ad2a0 React-performancetimeline: abf31259d794c9274b3ea19c5016186925eec6c4 React-RCTActionSheet: a499b0d6d9793886b67ba3e16046a3fef2cdbbc3 React-RCTAnimation: 2595dcb10a82216a511b54742f8c28d793852ac6 @@ -3840,7 +3826,7 @@ SPEC CHECKSUMS: React-RCTSettings: a060c7e381a3896104761b8eed7e284d95e37df3 React-RCTText: 4f272b72dbb61f390d8c8274528f9fdbff983806 React-RCTVibration: 0e5326220719aca12473d703aa46693e3b4ce67a - React-rendererconsistency: 3a8c9e0828a14d477b44958581034915d86c1517 + React-rendererconsistency: 351fdbc5c1fe4da24243d939094a80f0e149c7a1 React-renderercss: d333f2ada83969591100d91ec6b23ca2e17e1507 React-rendererdebug: 039e5949b72ba63c703de020701e3fd152434c61 React-rncore: 57ed480649bb678d8bdc386d20fee8bf2b0c307c @@ -3867,7 +3853,7 @@ SPEC CHECKSUMS: RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 RNGestureHandler: 5d8431415d4b8518e86e289e9ad5bb9be78f6dba RNGoogleSignin: ccaa4a81582cf713eea562c5dd9dc1961a715fd0 - RNLiveMarkdown: 1c09c5813366c29885b757b4c0a5e163a89f8d55 + RNLiveMarkdown: fe4ccb190153d536c607735211c3ef16e5068042 RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81 rnmapbox-maps: ef00aafe2cbef8808f2aa6168e3f86ce103058bc RNNitroSQLite: 44e596c1fb8f852f9a158eb07c647f706df13514 diff --git a/package-lock.json b/package-lock.json index a17a18f1c41f..4609298fbce1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@expensify/nitro-utils": "file:./modules/ExpensifyNitroUtils", "@expensify/react-native-background-task": "file:./modules/background-task", "@expensify/react-native-hybrid-app": "file:./modules/hybrid-app", - "@expensify/react-native-live-markdown": "0.1.289", + "@expensify/react-native-live-markdown": "0.1.292", "@expensify/react-native-wallet": "^0.1.5", "@expo/metro-runtime": "^5.0.4", "@firebase/app": "^0.10.10", @@ -4372,9 +4372,9 @@ "link": true }, "node_modules/@expensify/react-native-live-markdown": { - "version": "0.1.289", - "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.289.tgz", - "integrity": "sha512-U+QHKDIEXDGvvk+zKthKncc+hrVD/9fdBBzjtV0rvA4aegU9plFkWJNkwfscVSAKzQCyiPSHaeSqa/ZSFjv68g==", + "version": "0.1.292", + "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.292.tgz", + "integrity": "sha512-qI6nf0YS9MXb5jsC323B/XmRAEAtZvNx/6FWWWUjEneCZa2nmoMhv3vfJJEDuHUJoUZxxjpnHO7kqEMDE5k3aQ==", "license": "MIT", "workspaces": [ "./example", diff --git a/package.json b/package.json index 8c40086e0133..e5d879cd7c8c 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "@expensify/nitro-utils": "file:./modules/ExpensifyNitroUtils", "@expensify/react-native-background-task": "file:./modules/background-task", "@expensify/react-native-hybrid-app": "file:./modules/hybrid-app", - "@expensify/react-native-live-markdown": "0.1.289", + "@expensify/react-native-live-markdown": "0.1.292", "@expensify/react-native-wallet": "^0.1.5", "@expo/metro-runtime": "^5.0.4", "@firebase/app": "^0.10.10", diff --git a/patches/react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch b/patches/react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch new file mode 100644 index 000000000000..c541fac08831 --- /dev/null +++ b/patches/react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch @@ -0,0 +1,120 @@ +diff --git a/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +index 3618474..ab5b828 100644 +--- a/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp ++++ b/node_modules/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +@@ -476,16 +476,19 @@ 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); ++ if (node->hasContentsChildren()) [[unlikely]] { ++ node->cloneContentsChildrenIfNeeded(); ++ 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); ++ } + } + } + } +diff --git a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp +index dce42fb..f1bc5e8 100644 +--- a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp ++++ b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.cpp +@@ -181,6 +181,17 @@ void Node::setDirty(bool isDirty) { + } + } + ++void Node::setChildren(const std::vector& children) { ++ children_ = children; ++ ++ contentsChildrenCount_ = 0; ++ for (const auto& child : children) { ++ if (child->style().display() == Display::Contents) { ++ contentsChildrenCount_++; ++ } ++ } ++} ++ + bool Node::removeChild(Node* child) { + auto p = std::find(children_.begin(), children_.end(), child); + if (p != children_.end()) { +@@ -379,6 +390,23 @@ void Node::cloneChildrenIfNeeded() { + if (child->getOwner() != this) { + child = resolveRef(config_->cloneNode(child, this, i)); + child->setOwner(this); ++ ++ if (child->hasContentsChildren()) [[unlikely]] { ++ child->cloneContentsChildrenIfNeeded(); ++ } ++ } ++ i += 1; ++ } ++} ++ ++void Node::cloneContentsChildrenIfNeeded() { ++ size_t i = 0; ++ for (Node*& child : children_) { ++ if (child->style().display() == Display::Contents && ++ child->getOwner() != this) { ++ child = resolveRef(config_->cloneNode(child, this, i)); ++ child->setOwner(this); ++ child->cloneChildrenIfNeeded(); + } + i += 1; + } +diff --git a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h +index 5ae7d43..3454d54 100644 +--- a/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h ++++ b/node_modules/react-native/ReactCommon/yoga/yoga/node/Node.h +@@ -96,6 +96,10 @@ class YG_EXPORT Node : public ::YGNode { + return config_->hasErrata(errata); + } + ++ bool hasContentsChildren() const { ++ return contentsChildrenCount_ != 0; ++ } ++ + YGDirtiedFunc getDirtiedFunc() const { + return dirtiedFunc_; + } +@@ -244,15 +248,12 @@ class YG_EXPORT Node : public ::YGNode { + owner_ = owner; + } + +- void setChildren(const std::vector& children) { +- children_ = children; +- } +- + // TODO: rvalue override for setChildren + + void setConfig(Config* config); + + void setDirty(bool isDirty); ++ void setChildren(const std::vector& children); + void setLayoutLastOwnerDirection(Direction direction); + void setLayoutComputedFlexBasis(FloatOptional computedFlexBasis); + void setLayoutComputedFlexBasisGeneration( +@@ -286,6 +287,7 @@ class YG_EXPORT Node : public ::YGNode { + void removeChild(size_t index); + + void cloneChildrenIfNeeded(); ++ void cloneContentsChildrenIfNeeded(); + void markDirtyAndPropagate(); + float resolveFlexGrow() const; + float resolveFlexShrink() const; From 344d718f838f0bcc33f555ca098231f5c6db4bb5 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Fri, 11 Jul 2025 12:25:30 +0200 Subject: [PATCH 2/3] Add patch details --- patches/react-native/details.md | 14 ++++++++++++++ ...5+fix-display-contents-not-updating-nodes.patch | 0 2 files changed, 14 insertions(+) create mode 100644 patches/react-native/details.md rename patches/{ => react-native}/react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch (100%) diff --git a/patches/react-native/details.md b/patches/react-native/details.md new file mode 100644 index 000000000000..a8ba894b601d --- /dev/null +++ b/patches/react-native/details.md @@ -0,0 +1,14 @@ +# `react-native` patches + +### [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) + +- 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. + ``` + +- Upstream PR/issue: https://github.com/facebook/react-native/pull/52530 +- E/App issue: https://github.com/Expensify/App/issues/65268 +- PR introducing patch: [#65925](https://github.com/Expensify/App/pull/65925) \ No newline at end of file diff --git a/patches/react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch b/patches/react-native/react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch similarity index 100% rename from patches/react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch rename to patches/react-native/react-native+0.79.2+025+fix-display-contents-not-updating-nodes.patch From 6b14a2c074fdf96eff1ee66aae0b65c65ee92f6f Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Wed, 16 Jul 2025 12:33:22 +0200 Subject: [PATCH 3/3] Bump markdown --- ios/Podfile.lock | 4 ++-- package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 0463bae687d9..661ace6a1118 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2847,7 +2847,7 @@ PODS: - RNGoogleSignin (10.0.1): - GoogleSignIn (~> 7.0) - React-Core - - RNLiveMarkdown (0.1.292): + - RNLiveMarkdown (0.1.294): - DoubleConversion - glog - hermes-engine @@ -3867,7 +3867,7 @@ SPEC CHECKSUMS: RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 RNGestureHandler: 5d8431415d4b8518e86e289e9ad5bb9be78f6dba RNGoogleSignin: ccaa4a81582cf713eea562c5dd9dc1961a715fd0 - RNLiveMarkdown: fe4ccb190153d536c607735211c3ef16e5068042 + RNLiveMarkdown: 6e4972e95cf3b5ad0d164e08c72a6098d84e0b9d RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81 rnmapbox-maps: ef00aafe2cbef8808f2aa6168e3f86ce103058bc RNNitroSQLite: 44e596c1fb8f852f9a158eb07c647f706df13514 diff --git a/package-lock.json b/package-lock.json index 6683436ec232..05590293629d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@expensify/nitro-utils": "file:./modules/ExpensifyNitroUtils", "@expensify/react-native-background-task": "file:./modules/background-task", "@expensify/react-native-hybrid-app": "file:./modules/hybrid-app", - "@expensify/react-native-live-markdown": "0.1.292", + "@expensify/react-native-live-markdown": "0.1.294", "@expensify/react-native-wallet": "^0.1.5", "@expo/metro-runtime": "^5.0.4", "@firebase/app": "^0.10.10", @@ -4372,9 +4372,9 @@ "link": true }, "node_modules/@expensify/react-native-live-markdown": { - "version": "0.1.292", - "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.292.tgz", - "integrity": "sha512-qI6nf0YS9MXb5jsC323B/XmRAEAtZvNx/6FWWWUjEneCZa2nmoMhv3vfJJEDuHUJoUZxxjpnHO7kqEMDE5k3aQ==", + "version": "0.1.294", + "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.294.tgz", + "integrity": "sha512-wH2h9P8GUvHJpr+yF8hG4ZTklcb2/qHI90oQr86LKDQL8jOth54jCcho5IZ3RsCE1gi3SeeP+a/JnE65TRFO8Q==", "license": "MIT", "workspaces": [ "./example", diff --git a/package.json b/package.json index fc25dab14ce6..81cb3c768169 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "@expensify/nitro-utils": "file:./modules/ExpensifyNitroUtils", "@expensify/react-native-background-task": "file:./modules/background-task", "@expensify/react-native-hybrid-app": "file:./modules/hybrid-app", - "@expensify/react-native-live-markdown": "0.1.292", + "@expensify/react-native-live-markdown": "0.1.294", "@expensify/react-native-wallet": "^0.1.5", "@expo/metro-runtime": "^5.0.4", "@firebase/app": "^0.10.10",