diff --git a/.eslintrc.js b/.eslintrc.js index 4c434aab38a98b..e8a43917d698b3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -30,6 +30,7 @@ module.exports = { // These rules are not required with hermes-eslint 'ft-flow/define-flow-type': 0, 'ft-flow/use-flow-type': 0, + 'lint/sort-imports': 1, // flow handles this check for us, so it's not required 'no-undef': 0, }, diff --git a/.flowconfig b/.flowconfig index 957cbb08256045..3dd17a921b2e74 100644 --- a/.flowconfig +++ b/.flowconfig @@ -90,4 +90,4 @@ untyped-import untyped-type-import [version] -^0.249.0 +^0.250.0 diff --git a/.github/actions/build-hermes-macos/action.yml b/.github/actions/build-hermes-macos/action.yml index 4e0b3721eca71f..18afd8b98b0b4e 100644 --- a/.github/actions/build-hermes-macos/action.yml +++ b/.github/actions/build-hermes-macos/action.yml @@ -22,7 +22,7 @@ runs: - name: Restore Cached Artifacts uses: actions/cache/restore@v4 with: - key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes/utils/build-apple-frameworks.sh') }} + key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }} path: | /tmp/hermes/osx-bin/${{ inputs.flavor }} /tmp/hermes/dSYM/${{ inputs.flavor }} @@ -119,6 +119,8 @@ runs: mv build_macosx_${{ inputs.flavor }} build_macosx mv build_iphoneos_${{ inputs.flavor }} build_iphoneos mv build_iphonesimulator_${{ inputs.flavor }} build_iphonesimulator + mv build_appletvos_${{ inputs.flavor }} build_appletvos + mv build_appletvsimulator_${{ inputs.flavor }} build_appletvsimulator mv build_catalyst_${{ inputs.flavor }} build_catalyst mv build_xros_${{ inputs.flavor }} build_xros mv build_xrsimulator_${{ inputs.flavor }} build_xrsimulator @@ -177,6 +179,8 @@ runs: mkdir -p "$WORKING_DIR/catalyst" mkdir -p "$WORKING_DIR/iphoneos" mkdir -p "$WORKING_DIR/iphonesimulator" + mkdir -p "$WORKING_DIR/appletvos" + mkdir -p "$WORKING_DIR/appletvsimulator" mkdir -p "$WORKING_DIR/xros" mkdir -p "$WORKING_DIR/xrsimulator" @@ -187,6 +191,8 @@ runs: cp -r build_catalyst/$DSYM_FILE_PATH "$WORKING_DIR/catalyst/" cp -r build_iphoneos/$DSYM_FILE_PATH "$WORKING_DIR/iphoneos/" cp -r build_iphonesimulator/$DSYM_FILE_PATH "$WORKING_DIR/iphonesimulator/" + cp -r build_appletvos/$DSYM_FILE_PATH "$WORKING_DIR/appletvos/" + cp -r build_appletvsimulator/$DSYM_FILE_PATH "$WORKING_DIR/appletvsimulator/" cp -r build_xros/$DSYM_FILE_PATH "$WORKING_DIR/xros/" cp -r build_xrsimulator/$DSYM_FILE_PATH "$WORKING_DIR/xrsimulator/" @@ -214,7 +220,7 @@ runs: uses: actions/cache/save@v4 if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode. with: - key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes/utils/build-apple-frameworks.sh') }} + key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashFiles('./packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }} path: | /tmp/hermes/osx-bin/${{ inputs.flavor }} /tmp/hermes/dSYM/${{ inputs.flavor }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 83563779ecd2ac..f0051aca6c63d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,488 +1,310 @@ # Changelog -## v0.76.0-rc.4 +## v0.76.0 ### Breaking -#### Android specific - -- Update ReactNativeFlipper deprecation to ERROR ([531657b394](https://github.com/facebook/react-native/commit/531657b394aa0fac70f26d9facdb32d23a1b05d6) by [@cortinico](https://github.com/cortinico)) - -#### iOS specific - -- Add ability to control bundle loading on the new architecture similar to `loadSourceForBridge`. Removed some properties from the `RCTRootViewFactory`. ([7487a2c277](https://github.com/facebook/react-native/commit/7487a2c27713a0129ef2db70efc2fa543a8c185e) by [@alanjhughes](https://github.com/alanjhughes)) - -### Added - -- Expose `MetroConfig` type directly from `react-native/metro-config`. ([cc6d1eb844](https://github.com/facebook/react-native/commit/cc6d1eb8449c25fe3c76aaf4da5cd38b3ac0783d) by [@tjzel](https://github.com/tjzel)) - -#### iOS specific - -- Improve RCTAppDelegate usage for brownfield, add `automaticallyLoadReactNativeWindow` flag ([391680fe84](https://github.com/facebook/react-native/commit/391680fe844aad887e497912378c699aed13464b) by [@okwasniewski](https://github.com/okwasniewski)) - -### Changed +- **Animation** Stop sending state updates to React in looping animation ([8af5e893c8](https://github.com/facebook/react-native/commit/8af5e893c89b24dca972afe36ef442fd509d5804) by [@dmytrorykun](https://github.com/dmytrorykun)) +- **devtools:** Remove Inspector Panel perf + network tabs under New Arch (see https://github.com/react-native-community/discussions-and-proposals/pull/777) ([f220bde4d7](https://github.com/facebook/react-native/commit/f220bde4d7d556b3be83cccff0eec5da22921aba) by [@huntie](https://github.com/huntie)) +- **flow:** Eliminate a few React.Element type that will be synced to react-native ([39c338ff8d](https://github.com/facebook/react-native/commit/39c338ff8d3a65ec3f7a45f0b8319f70115e2fc1) by [@SamChou19815](https://github.com/SamChou19815)) +- **infra** Projects that intend to use the community CLI will now have to declare that dependency instead of transitively having the react-native package include it. ([bd3a3e3de0](https://github.com/facebook/react-native/commit/bd3a3e3de08e334db6f1f248241df8ea4680724c) by [@blakef](https://github.com/blakef)) +- **infra** Remove react-native-community dependencies from react-native ([9269429bb9](https://github.com/facebook/react-native/commit/9269429bb955d47088793a2e32454fddb712152b) by [@blakef](https://github.com/blakef)) +- **infra:** TurboModules will be looked up as TurboModules first, and fallback to legacy modules after. ([5a62606ab3](https://github.com/facebook/react-native/commit/5a62606ab36edaffb0a5c760d2b0ed0c8e3808a8) by [@javache](https://github.com/javache)) +- **text engine** Always use AttributedStringBox instead of AttributedString in TextLayoutManager ([ee597bfe2bf](https://github.com/facebook/react-native/commit/ee597bfe2bf7f11ac60dab87f47dbcb6e840749c)) by [@NickGerleman](https://github.com/NickGerleman)) -- Update debugger-frontend from e8c7943...ce5d32a ([7a601f428e](https://github.com/facebook/react-native/commit/7a601f428e171827ecb79cb0829d018835229d92) by [@huntie](https://github.com/huntie)) -- Use Metro terminal reporter for dev-middleware logs ([2f04dfe795](https://github.com/facebook/react-native/commit/2f04dfe7951e5f4c63f94c74d7ad10cd53969da0) by [@huntie](https://github.com/huntie)) -- Simplify key handling in start command ([5a0df6d0bf](https://github.com/facebook/react-native/commit/5a0df6d0bf5e84d3f7d2a6f000e617e00b8bef02) by [@huntie](https://github.com/huntie)) -- Add CLI selection of multiple debug targets ([6a24df7eaa](https://github.com/facebook/react-native/commit/6a24df7eaab2420e91b9a4fc9202c175c0802441) by [@huntie](https://github.com/huntie)) -- Update Metro to 0.81.0-alpha.2 ([2a344a9580](https://github.com/facebook/react-native/commit/2a344a95806c62bbc708b5466760b009eae0c579) by [@huntie](https://github.com/huntie)) - -#### iOS specific - -- Rename `RCTUIGraphicsImageRenderer` to `RCTMakeUIGraphicsImageRenderer` ([6a09fc09af](https://github.com/facebook/react-native/commit/6a09fc09af8eedbf409ab870d5714e44892b2a16) by [@Saadnajmi](https://github.com/Saadnajmi)) -- Passed correct title and titleColor prop to updateTitle function ([5c7a166dca](https://github.com/facebook/react-native/commit/5c7a166dcaf5400fbc4c12d4c8b451228157c036) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) - -### Fixed - -- Fix ReactFragment on New Architecture ([52322fbd0e](https://github.com/facebook/react-native/commit/52322fbd0e641726b224b2b9b89d99d93dbc6e33) by [@cortinico](https://github.com/cortinico)) -- Fix logbox reporting React errors as Warnings ([cbb313253f](https://github.com/facebook/react-native/commit/cbb313253fdf96c4fca06a24ed4cbd3f3df9db80) by [@rickhanlonii](https://github.com/rickhanlonii)) -- Respond with status code `200` when successfully launching RNDT ([eeb6122f39](https://github.com/facebook/react-native/commit/eeb6122f390d355191182eaee6cf126468e7b4d4) by [@byCedric](https://github.com/byCedric)) -- Fix parsing of modern Flow syntax when `transformer.hermesParser = false` is configured in Metro config ([1387f521fd](https://github.com/facebook/react-native/commit/1387f521fdd8f187eab7a4a6a05d4d75a96b4f88) by [@huntie](https://github.com/huntie)) -- Restore Metro log forwarding, change notice to signal future removal ([6047f9cc09](https://github.com/facebook/react-native/commit/6047f9cc09a7a86b79084a3ff1b4303c4583d2ce) by [@huntie](https://github.com/huntie)) #### Android specific -- Add missing Android implementation for DevMenu Module ([1bdae07d89](https://github.com/facebook/react-native/commit/1bdae07d89fdda486d3f9dbcc4aa5cbb026fc8b6) by [@cortinico](https://github.com/cortinico)) -- Fix measuring text with incorrect hyphenationFrequency ([fc8224036b](https://github.com/facebook/react-native/commit/fc8224036b4b5880c881f471e432ee5b47113b0b) by [@NickGerleman](https://github.com/NickGerleman)) -- Properly set `REACTNATIVE_MERGED_SO` for autolinked libraries ([c005609b01](https://github.com/facebook/react-native/commit/c005609b0155223f3ae778c5cd96bc78c4dfe399) by [@cortinico](https://github.com/cortinico)) +- **bridging:** Deleted LongArray ([471445eb17](https://github.com/facebook/react-native/commit/471445eb1770dcb773eb463af99c9556cb070abc) by Thomas Nardone) +- **Flipper:** Update ReactNativeFlipper deprecation to ERROR ([531657b394](https://github.com/facebook/react-native/commit/531657b394aa0fac70f26d9facdb32d23a1b05d6) by [@cortinico](https://github.com/cortinico)) +- **infra** Remove several libs from default App CMake setup ([52de8c70f2](https://github.com/facebook/react-native/commit/52de8c70f2d8826789e4118b0c81aa4397e833fc) by [@cortinico](https://github.com/cortinico)) +- **infra:** Merge all the remaining .so libraries into libreactnative.so ([db80d78d7a](https://github.com/facebook/react-native/commit/db80d78d7a3d61d5bd6871258513f778851059f5) by [@cortinico](https://github.com/cortinico)) +- **infra:** Remove several unnecessary android prefab targets. Use ReactAndroid::reactnative instead ([6e5227bd83](https://github.com/facebook/react-native/commit/6e5227bd8357dcbe12038b21066cf414e3f97e03) by [@cortinico](https://github.com/cortinico)) +- **infra:** Do not depend on OSS SoLoader anymore and do not expose Fresco `api` dependency. ([6dc01dad09](https://github.com/facebook/react-native/commit/6dc01dad09c6ee2ac6793db1b11cb98faada9c3b) by [@cortinico](https://github.com/cortinico)) +- **infra:** Updating `minSdkVersion` to API 24 (Android 7) ([270951a212](https://github.com/facebook/react-native/commit/270951a2123b5c51567b72a8f1a8a1608cba43d7) by [@alanleedev](https://github.com/alanleedev)) +- **initialization:** `ReactNativeHost` invalidates the instance manager on `clear()`, rather than merely destroying the instance. ([986cf18dd2](https://github.com/facebook/react-native/commit/986cf18dd2f0d6ea491d521549c0bf9a323e189b) by [@motiz88](https://github.com/motiz88)) +- **layout engine:** Do not implicitly convert parsed LengthPercentage to pixels ([9e48976bc2](https://github.com/facebook/react-native/commit/9e48976bc2864c6ef6995179a7dc8d1c453dcf39) by [@NickGerleman](https://github.com/NickGerleman)) +- **rendering:** Set "enableBackgroundStyleApplicator" by default ([5f14963da0](https://github.com/facebook/react-native/commit/5f14963da081deeac2fb540d58c8667c2d2c5d08) by [@NickGerleman](https://github.com/NickGerleman)) #### iOS specific -- Properly retain/release backgroundColor in RCTBorderDrawing ([47748c7935](https://github.com/facebook/react-native/commit/47748c7935540014abed03b4d2ff809b471c4fe3) by [@Saadnajmi](https://github.com/Saadnajmi)) -- Fix applying of tintColor and progressViewOffset props for RefreshControl component with New Architecture enabled ([19d468fed9](https://github.com/facebook/react-native/commit/19d468fed966f2adb973ad3f19a97a5ec0372e3a) by [@TuTejsy](https://github.com/TuTejsy)) +- **initialization:** Add ability to control bundle loading on the new architecture similar to `loadSourceForBridge`. Removed some properties from the `RCTRootViewFactory`. ([7487a2c277](https://github.com/facebook/react-native/commit/7487a2c27713a0129ef2db70efc2fa543a8c185e) by [@alanjhughes](https://github.com/alanjhughes)) +- **turbomodule** [iOS] Remove Macro for autolinking pure Cxx module([184646e491](https://github.com/facebook/react-native/commit/184646e49169110842bafa6c02e52f6eec1e0ffa) by [@philIip](https://github.com/philIip)) -## v0.76.0-rc.3 ### Added -- Add CLI selection of multiple debug targets ([6a24df7eaa](https://github.com/facebook/react-native/commit/6a24df7eaab2420e91b9a4fc9202c175c0802441) by [@huntie](https://github.com/huntie)) - -#### iOS specific - -- Improve RCTAppDelegate usage for brownfield, add `automaticallyLoadReactNativeWindow` flag ([391680fe84](https://github.com/facebook/react-native/commit/391680fe844aad887e497912378c699aed13464b) by [@okwasniewski](https://github.com/okwasniewski)) +- **style** Add official `filter` CSSProperty. ([6b369a40d9](https://github.com/facebook/react-native/commit/6b369a40d98c2bb7f933415f62b1e2b8f4da86ed) by [@jorge-cab](https://github.com/jorge-cab)) +- **style** Add official `boxShadow` CSSProperty. ([2241c3146f](https://github.com/facebook/react-native/commit/2241c3146ffbfb8b77f54599b7cebb717537c15a) by [@jorge-cab](https://github.com/jorge-cab)) +- **codegen:** Add EventEmitter Code-gen support for Java and ObjC Turbo Modules ([ad3df84668](https://github.com/facebook/react-native/commit/ad3df84668f1624e830396364c331783c6f99948) by [@christophpurrer](https://github.com/christophpurrer)) +- **devtools:** support for rendering Error object previews in Chrome DevTools console ([cae9ae5b48](https://github.com/facebook/react-native/commit/cae9ae5b486d04b889af9d1685bcbbb33557c791) by [@EdmondChuiHW](https://github.com/EdmondChuiHW)) +- **devtools:** support for rendering Error objects in Chrome DevTools console ([1740a56a46](https://github.com/facebook/react-native/commit/1740a56a46ef4a364c88cebe373b4b3a5679248a) by [@EdmondChuiHW](https://github.com/EdmondChuiHW)) +- **devtools** Add upper case keys to the debug key handler ([6390cf67d0](https://github.com/facebook/react-native/commit/6390cf67d065727c810fcf4ef32b0cac7efac8e2) by [@wh201906](https://github.com/wh201906)) +- **devtools:** Debugger: Support text responses to CDP `IO.read` requests ([c085180264](https://github.com/facebook/react-native/commit/c085180264ea68f71b050cbb6b9a8274e36c3fbf) by [@robhogan](https://github.com/robhogan)) +- **devtools:** Debugging: implement common C++ layer of CDP `Network.loadNetworkResource` ([193cdc36f7](https://github.com/facebook/react-native/commit/193cdc36f7de5524b509e38da8feb209d214634c) by [@robhogan](https://github.com/robhogan)) +- **devtools:**: Inspector: Support `/open-debugger` specifying `target` param ([88ba9a6042](https://github.com/facebook/react-native/commit/88ba9a60428697f5957f269e85fbef3d0afc5046) by [@robhogan](https://github.com/robhogan)) +- **infra:** Use PackagerAsset resolver instead of Platform.OS when its provided. ([baa366654e](https://github.com/facebook/react-native/commit/baa366654e9ee98e0400b493e7fc9578851d60d1) by [@andrewdacenko](https://github.com/andrewdacenko)) +- **infra:** Add optional `PackagerAsset.resolver` prop so AssetSourceResolver can use it instead of `Platform.OS` to identify where asset is stored on device. ([3f3a85b3c5](https://github.com/facebook/react-native/commit/3f3a85b3c5be3f9fdbd63a3acfe8456b6adeb100) by [@andrewdacenko](https://github.com/andrewdacenko)) +- **initialization** Add experimental api to JSRuntimeFactory to initialize runtime on js thread ([c9fbc05bbc](https://github.com/facebook/react-native/commit/c9fbc05bbca803032914be4b38ac4c9608852963) by Benoit Girard) +- **metro:** Expose `MetroConfig` type directly from `react-native/metro-config`. ([cc6d1eb844](https://github.com/facebook/react-native/commit/cc6d1eb8449c25fe3c76aaf4da5cd38b3ac0783d) by [@tjzel](https://github.com/tjzel)) +- **rsc** Added support for importing `react-native` in a `react-server` environment for React Server Components support. ([8989c9b71d](https://github.com/facebook/react-native/commit/8989c9b71dcca3f39b37a32945364025732eb2c3) by [@EvanBacon](https://github.com/EvanBacon)) +- **style:** Add support for `texAlignment: 'start'` ([a2cb34371e](https://github.com/facebook/react-native/commit/a2cb34371e6e52305ee58f23d3b2fefc1e8c7157) by [@javache](https://github.com/javache)) +- **style:** Unhide new arch layout props ([2d6c59e1d4](https://github.com/facebook/react-native/commit/2d6c59e1d4f6ddb46373ed10c915aed4ce0c030c) by [@NickGerleman](https://github.com/NickGerleman)) + +#### Android specific + +- **devtools:** Enable React Native DevTools in OSS debug builds ([143f1ad298](https://github.com/facebook/react-native/commit/143f1ad29874c1e8e9561abae263cb08f4859407) by [@robhogan](https://github.com/robhogan)) +- **codegen** Add support for handling `com.facebook.react.bridge.Dynamic` as parameter type in TurboModules ([d01f1b3214](https://github.com/facebook/react-native/commit/d01f1b3214b435d436fd6cf145d8e450a188301c) by [@cortinico](https://github.com/cortinico)) +- **error handling:** Provide default implementation for ReactHostDelegate.handleInstanceException() ([34e3a6cc88](https://github.com/facebook/react-native/commit/34e3a6cc885a68148b1d2209adc70c8109a56a66) by [@alanleedev](https://github.com/alanleedev)) +- **Image** Added support for rendering XML assets provided to `Image` ([aad9240fd4](https://github.com/facebook/react-native/commit/aad9240fd435d549812b5075767c5ea39a8fbb4f) by Peter Abbondanzo) +- **Runtime** Allow DefaultReactHost to load the js bundle via regular file urls ([7522336412](https://github.com/facebook/react-native/commit/752233641210a0b2e6bc1438f82d0aa193c2ef0d) by [@RSNara](https://github.com/RSNara)) +- **runtime** Make ReactInstanceEventListener available on ReactHost ([80e1dd70b0](https://github.com/facebook/react-native/commit/80e1dd70b0b27195b9b71ea531728eef9799caa9) by [@RSNara](https://github.com/RSNara)) +- **runtime** Add `invalidate()` method to ReactHost and ReactInstanceManager that destroys the `ReactHost`, including the `ReactInstance`. ([a3db352e25](https://github.com/facebook/react-native/commit/a3db352e25c01614ade3e42637e3d5726e582308) by [@motiz88](https://github.com/motiz88)) +- **runtime:** Added `onUserLeaveHint` support into `ReactActivityDelegate` ([27ba369f23](https://github.com/facebook/react-native/commit/27ba369f2325db5678aaf6a18927c127921840e0) by [@behenate](https://github.com/behenate)) +- **runtime:** Added a conditional check in the `resolveThemeAttribute` function to reattempt resource resolution with the "android" package name if the resource ID is 0. ([6365df54db](https://github.com/facebook/react-native/commit/6365df54dbd0a7e185cfe113a9cf0026b2bb12ef) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) +- **style** Add BackgroundStyleApplicator for managing view backgrounds ([1a78477ce5](https://github.com/facebook/react-native/commit/1a78477ce528b36a97602d0210bd4ea8446804dc) by [@NickGerleman](https://github.com/NickGerleman)) +- **style:** Linear gradient ([bd0aedc8c3](https://github.com/facebook/react-native/commit/bd0aedc8c3dbebf96e123fd1bd33f515d09e2579) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway)) +- **style:** Support simple opacity in nested text ([a2d53d5ea0](https://github.com/facebook/react-native/commit/a2d53d5ea08959da0bbce3c494e06634e3d52d2a) by [@NickGerleman](https://github.com/NickGerleman)) + +#### iOS specific + +- **accessibility:** Support LargeContentViewer on iOS for better accessibility ([6cc44d765a](https://github.com/facebook/react-native/commit/6cc44d765a1127aa4998a490e3ff90b741ef9441) by [@bacarybruno](https://github.com/bacarybruno)) +- **Animated:** Declare the `onUserDrivenAnimationEnded` in the old Architecture ([f8c13f601d](https://github.com/facebook/react-native/commit/f8c13f601d5f7f159dd7a0e42b9fcc877d48d69b) by [@cipolleschi](https://github.com/cipolleschi)) +- **Animated:** Retrieve the tags of the nodes connected by the animation and send them to JS ([fd748ae84c](https://github.com/facebook/react-native/commit/fd748ae84cf18c1c204a936af45bb4883d476cd7) by [@cipolleschi](https://github.com/cipolleschi)) +- **brownfield:** Improve RCTAppDelegate usage for brownfield, add `automaticallyLoadReactNativeWindow` flag ([391680fe84](https://github.com/facebook/react-native/commit/391680fe844aad887e497912378c699aed13464b) by [@okwasniewski](https://github.com/okwasniewski)) +- **codegen** Code-generate an optional base class to use for every NativeModule ([ed5f558a6c](https://github.com/facebook/react-native/commit/ed5f558a6cb5ff597870e7013150113b9460c0dc) by [@christophpurrer](https://github.com/christophpurrer)) +- **devtools** Debugger: Implement CDP methods for loading network resources through the debug target. ([c720583f6c](https://github.com/facebook/react-native/commit/c720583f6c071959e7898befb62cd36f84c581dc) by [@robhogan](https://github.com/robhogan)) +- **infra** Enable third-party podspec sources to be fetched from mirrored git repositories ([53969cb8d0](https://github.com/facebook/react-native/commit/53969cb8d0460ccb2e899ec290135f447ed5dc65) by [@RailByteOEBB](https://github.com/RailByteOEBB)) +- **runtime** Added RCTUIInterfaceOrientation helper method ([cf015f93ef](https://github.com/facebook/react-native/commit/cf015f93efa888be61150915b18ae8cd12d11232) by [@Biki-das](https://github.com/Biki-das)) +- **ScrollView** Send onScrollEnded event to NativeTurboAnimatedModule ([7af743236f](https://github.com/facebook/react-native/commit/7af743236f25ee03b674baf46f6506dbbc2e4fc0) by [@cipolleschi](https://github.com/cipolleschi)) +- **ScrollView:** Fire onMomentumScrollEnd when UIScrollView is removed from window ([b98b9f1fa7](https://github.com/facebook/react-native/commit/b98b9f1fa7717283f368eb182a51d971b8776c80) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) +- **style** Linear gradient ([b99675d78a](https://github.com/facebook/react-native/commit/b99675d78a8269403b68d7eae8dc67ec85aea3e6) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway)) +- **TextInput** Add line break mode for TextInput components. ([fe941a8f4c](https://github.com/facebook/react-native/commit/fe941a8f4c92fa9b1f07d2dd94050c81d63c77e8) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) +- **TextInput** Line break mode for TextInput components. ([6cab6c2a13](https://github.com/facebook/react-native/commit/6cab6c2a13b89cbee1a2c1957ea561f82cb6700a) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) +- **TextInput** Add support for missing text content types ([d7a3e48032](https://github.com/facebook/react-native/commit/d7a3e48032fe76d118c2b5c14032d7a73319adf8) by [@krozniata](https://github.com/krozniata)) +- **TextInput** Added handling of `showSoftInputOnFocus` props for new arch. ([ead50d6b11](https://github.com/facebook/react-native/commit/ead50d6b1180dbe9f8b49d646cc34f83aae41c74) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) ### Changed -- Use Metro terminal reporter for dev-middleware logs ([2f04dfe795](https://github.com/facebook/react-native/commit/2f04dfe7951e5f4c63f94c74d7ad10cd53969da0) by [@huntie](https://github.com/huntie)) -- Simplify key handling in start command ([5a0df6d0bf](https://github.com/facebook/react-native/commit/5a0df6d0bf5e84d3f7d2a6f000e617e00b8bef02) by [@huntie](https://github.com/huntie)) -- Update Metro to 0.81.0-alpha.2 ([2a344a9580](https://github.com/facebook/react-native/commit/2a344a95806c62bbc708b5466760b009eae0c579) by [@huntie](https://github.com/huntie)) - -### Fixed - -- Fix parsing of modern Flow syntax when `transformer.hermesParser = false` is configured in Metro config ([1387f521fd](https://github.com/facebook/react-native/commit/1387f521fdd8f187eab7a4a6a05d4d75a96b4f88) by [@huntie](https://github.com/huntie)) -- Fix ReactFragment on New Architecture ([52322fbd0e](https://github.com/facebook/react-native/commit/52322fbd0e641726b224b2b9b89d99d93dbc6e33) by [@cortinico](https://github.com/cortinico)) -#### Android specific - -- Add missing Android implementation for DevMenu Module ([1bdae07d89](https://github.com/facebook/react-native/commit/1bdae07d89fdda486d3f9dbcc4aa5cbb026fc8b6) by [@cortinico](https://github.com/cortinico)) -- Fix measuring text with incorrect hyphenationFrequency ([fc8224036b](https://github.com/facebook/react-native/commit/fc8224036b4b5880c881f471e432ee5b47113b0b) by [@NickGerleman](https://github.com/NickGerleman)) -- Properly set `REACTNATIVE_MERGED_SO` for autolinked libraries ([c005609b01](https://github.com/facebook/react-native/commit/c005609b0155223f3ae778c5cd96bc78c4dfe399) by [@cortinico](https://github.com/cortinico)) - -#### iOS specific - -- Fix applying of tintColor and progressViewOffset props for RefreshControl component with New Architecture enabled ([19d468fed9](https://github.com/facebook/react-native/commit/19d468fed966f2adb973ad3f19a97a5ec0372e3a) by [@TuTejsy](https://github.com/TuTejsy)) -- Convert `NSNull` to `nil` before checking `type` in `readAsDataURL` ([99ab845a5c](https://github.com/facebook/react-native/commit/99ab845a5cf0fe3463ff39b03373b95d4f5c0fac) by [@haileyok](https://github.com/haileyok)) -- Fix `` with floating keyboard on iPadOS ([3c54e1ee45](https://github.com/facebook/react-native/commit/3c54e1ee4522b26698bb3f99262a2a621b26fb64) by [@renchap](https://github.com/renchap)) - -## v0.76.0-rc.2 - -### Added - -#### iOS specific - -- Fire onMomentumScrollEnd when UIScrollView is removed from window ([b98b9f1fa7](https://github.com/facebook/react-native/commit/b98b9f1fa7717283f368eb182a51d971b8776c80) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) - -### Fixed - -- Throttle reload command ([42bad68220](https://github.com/facebook/react-native/commit/42bad68220d288ef2436609ee50ad993c239b362) by [@coado](https://github.com/coado)) - -#### iOS specific - -- Fixed a crash when navigating away from a screen that contains a scrollView ([c6f32828b9](https://github.com/facebook/react-native/commit/c6f32828b9487381dab27f645aedcdbae9dcbc7e) by [@cipolleschi](https://github.com/cipolleschi)) -- Allow pods mixte type settings on post-install ([1e59f2e3f8](https://github.com/facebook/react-native/commit/1e59f2e3f8f0ab3ee4173bddaa089bbecf61d1eb) by [@MasGaNo](https://github.com/MasGaNo)) -- Add back the BUNDLE_COMMAND ([cf42288181](https://github.com/facebook/react-native/commit/cf422881819decccdd2b486fbb73f2192b9ec522) by [@Vin-Xi](https://github.com/Vin-Xi)) -- Fix SVC for lineBreakModeIOS ([1099c0ccf7](https://github.com/facebook/react-native/commit/1099c0ccf7ea4f5d2e5caafd56b4e92faa367dc6) by [@cipolleschi](https://github.com/cipolleschi)) - -## v0.76.0-rc.1 - -### Breaking - -#### iOS specific - -- Unbreak `RCTHermesInstance` constructor breaking change ([aec6666bfa](https://github.com/facebook/react-native/commit/aec6666bfabf93cde70fa869b3eea68590998dee) by [@tido64](https://github.com/tido64)) - -### Added - -- Unhide new arch layout props ([2d6c59e1d4](https://github.com/facebook/react-native/commit/2d6c59e1d4f6ddb46373ed10c915aed4ce0c030c) by [@NickGerleman](https://github.com/NickGerleman)) - -### Changed - -- AnimatedNode (and its subclasses) once again implement `toJSON()`. ([7bd4a54968](https://github.com/facebook/react-native/commit/7bd4a5496815943b031b68ca46792560d8d798d8) by [@yungsters](https://github.com/yungsters)) -- Add official `filter` CSSProperty. ([6b369a40d9](https://github.com/facebook/react-native/commit/6b369a40d98c2bb7f933415f62b1e2b8f4da86ed) by [@jorge-cab](https://github.com/jorge-cab)) -- Add official `boxShadow` CSSProperty. ([2241c3146f](https://github.com/facebook/react-native/commit/2241c3146ffbfb8b77f54599b7cebb717537c15a) by [@jorge-cab](https://github.com/jorge-cab)) -- [0.76] Bump Metro to 0.81.0-alpha ([4126ce844d](https://github.com/facebook/react-native/commit/4126ce844d91612d83a1b2118a4859cac5bb480f) by [@robhogan](https://github.com/robhogan)) - -#### Android specific - -- Expose jsctooling via prefab ([e91690d929](https://github.com/facebook/react-native/commit/e91690d929d7c8b251964cae282ad8e1d95aa39a) by [@tomekzaw](https://github.com/tomekzaw)) -- Expose hermestooling via prefab ([f41af55958](https://github.com/facebook/react-native/commit/f41af55958dfbc39c536d433c3a27db329dd05f1) by [@cortinico](https://github.com/cortinico)) - -### Fixed - -#### Android specific - -- Fix Headless Crash `Tried to finish non-existent task with id` ([b4532adad4](https://github.com/facebook/react-native/commit/b4532adad4e38e1237631778f7b8c917a9ccf746) by [@RodolfoGS](https://github.com/RodolfoGS)) -- Expose `react_timing` headers in `reactnative` prefab ([b1d42c8ef2](https://github.com/facebook/react-native/commit/b1d42c8ef2eb54af48ad27d3dc121e15c07d3dba) by [@tomekzaw](https://github.com/tomekzaw)) -- RNGP - Sanitize the output of the config command ([d7884a6bb8](https://github.com/facebook/react-native/commit/d7884a6bb8f2d8fd08dfd7d2817a4fc25f61a57c) by [@cortinico](https://github.com/cortinico)) - -#### iOS specific - -- Don't reference PrivacyInfo.xcprivacy twice for new projects ([cadd41b1a2](https://github.com/facebook/react-native/commit/cadd41b1a2e16b1c77a8d3022f4ccbdbd5ea295f) by [@okwasniewski](https://github.com/okwasniewski)) -- Fixed warnings when validating SVC ([de39a204c3](https://github.com/facebook/react-native/commit/de39a204c3588a3c02dc2e72464174c75b3a6749) by [@cipolleschi](https://github.com/cipolleschi)) -- Solved SVC warnings for RNTester ([fad4a0783b](https://github.com/facebook/react-native/commit/fad4a0783b0a0478c147d9bde2ef9ab082a08297) by [@cipolleschi](https://github.com/cipolleschi)) - -## v0.76.0-rc.0 - -### Breaking - -- Remove Inspector Panel perf + network tabs under New Arch (see https://github.com/react-native-community/discussions-and-proposals/pull/777) ([f220bde4d7](https://github.com/facebook/react-native/commit/f220bde4d7d556b3be83cccff0eec5da22921aba) by [@huntie](https://github.com/huntie)) -- Always use AttributedStringBox instead of AttributedString in TextLayoutManager ([ee597bfe2b](https://github.com/facebook/react-native/commit/ee597bfe2bf7f11ac60dab87f47dbcb6e840749c) by [@NickGerleman](https://github.com/NickGerleman)) -- Projects that intend to use the community CLI will now have to declare that dependency instead of transitively having the react-native package handle this. ([bd3a3e3de0](https://github.com/facebook/react-native/commit/bd3a3e3de08e334db6f1f248241df8ea4680724c) by [@blakef](https://github.com/blakef)) -- - [iOS] RCTTurboModuleWithJSIBindings: https://github.com/facebook/react-native/pull/44486 ([184646e491](https://github.com/facebook/react-native/commit/184646e49169110842bafa6c02e52f6eec1e0ffa) by [@philIip](https://github.com/philIip)) -- Remove several libs from default App CMake setup ([52de8c70f2](https://github.com/facebook/react-native/commit/52de8c70f2d8826789e4118b0c81aa4397e833fc) by [@cortinico](https://github.com/cortinico)) -- Looping animations will not send React state updates. ([8af5e893c8](https://github.com/facebook/react-native/commit/8af5e893c89b24dca972afe36ef442fd509d5804) by [@dmytrorykun](https://github.com/dmytrorykun)) -- React-native isn't dependend on react-native-community/* ([9269429bb9](https://github.com/facebook/react-native/commit/9269429bb955d47088793a2e32454fddb712152b) by [@blakef](https://github.com/blakef)) - -#### Android specific - -- ([e881a1184c](https://github.com/facebook/react-native/commit/e881a1184cadd45321b781d07c6154a14332c5f6) by [@philIip](https://github.com/philIip)) -- Merge all the remaining .so libraries into libreactnative.so ([db80d78d7a](https://github.com/facebook/react-native/commit/db80d78d7a3d61d5bd6871258513f778851059f5) by [@cortinico](https://github.com/cortinico)) -- Remove several unnecessary android prefab targets. Use ReactAndroid::reactnative instead ([6e5227bd83](https://github.com/facebook/react-native/commit/6e5227bd8357dcbe12038b21066cf414e3f97e03) by [@cortinico](https://github.com/cortinico)) -- Do not depend on OSS SoLoader anymore and do not expose Fresco `api` dependency. ([6dc01dad09](https://github.com/facebook/react-native/commit/6dc01dad09c6ee2ac6793db1b11cb98faada9c3b) by [@cortinico](https://github.com/cortinico)) -- Do not implicitly convert parsed LengthPercentage to pixels ([9e48976bc2](https://github.com/facebook/react-native/commit/9e48976bc2864c6ef6995179a7dc8d1c453dcf39) by [@NickGerleman](https://github.com/NickGerleman)) -- Deleted LongArray ([471445eb17](https://github.com/facebook/react-native/commit/471445eb1770dcb773eb463af99c9556cb070abc) by Thomas Nardone) -- Updating `minSdkVersion` to API 24 (Android 7) ([270951a212](https://github.com/facebook/react-native/commit/270951a2123b5c51567b72a8f1a8a1608cba43d7) by [@alanleedev](https://github.com/alanleedev)) -- Set "enableBackgroundStyleApplicator" by default ([5f14963da0](https://github.com/facebook/react-native/commit/5f14963da081deeac2fb540d58c8667c2d2c5d08) by [@NickGerleman](https://github.com/NickGerleman)) -- Undo a breaking change with ResourceDrawableIdHelper.instance ([3f8340975b](https://github.com/facebook/react-native/commit/3f8340975b35767b192e3118f05d2b039676052e) by [@cortinico](https://github.com/cortinico)) -- Undo a breaking change with I18nUtil.instance ([221755c495](https://github.com/facebook/react-native/commit/221755c495ba1e8b27400ae4178c6b0085a2ace5) by [@cortinico](https://github.com/cortinico)) -- Undo breaking change for ReadableMap.entryIterator for Kotlin consumers ([b24d47a9a7](https://github.com/facebook/react-native/commit/b24d47a9a759954915629e6fa320a379cc29193d) by [@cortinico](https://github.com/cortinico)) -- Undo breaking change on Dynamic.type and Dynamic.isNull ([5e31b45fc7](https://github.com/facebook/react-native/commit/5e31b45fc7bea37ecb3703fac6b2abaccae2cbae) by [@cortinico](https://github.com/cortinico)) -- Undo breaking change on `CatalystInstance.getJsCallInvokerHolder` ([2ea9c360dc](https://github.com/facebook/react-native/commit/2ea9c360dc42a75f224e5d161163d65ef197ac24) by [@cortinico](https://github.com/cortinico)) -- `ReactNativeHost` invalidates the instance manager on `clear()` ([986cf18dd2](https://github.com/facebook/react-native/commit/986cf18dd2f0d6ea491d521549c0bf9a323e189b) by [@motiz88](https://github.com/motiz88)) - -#### iOS specific - - - -### Added - -- Update babel and fix tests accordingly ([b37101486b](https://github.com/facebook/react-native/commit/b37101486bd4dc26f6ec4e646e12d1484ec9479f) by [@vzaidman](https://github.com/vzaidman)) -- Add C++ Turbo Module enum Event Emitter example ([6340662d4f](https://github.com/facebook/react-native/commit/6340662d4f0d44d1f34ad407faa550f7f35e216c) by [@christophpurrer](https://github.com/christophpurrer)) -- : support for rendering Error object previews in Chrome DevTools console ([cae9ae5b48](https://github.com/facebook/react-native/commit/cae9ae5b486d04b889af9d1685bcbbb33557c791) by [@EdmondChuiHW](https://github.com/EdmondChuiHW)) -- : support for rendering Error objects in Chrome DevTools console ([1740a56a46](https://github.com/facebook/react-native/commit/1740a56a46ef4a364c88cebe373b4b3a5679248a) by [@EdmondChuiHW](https://github.com/EdmondChuiHW)) -- Use PackagerAsset resolver instead of Platform.OS when its provided. ([baa366654e](https://github.com/facebook/react-native/commit/baa366654e9ee98e0400b493e7fc9578851d60d1) by [@andrewdacenko](https://github.com/andrewdacenko)) -- Add optional `PackagerAsset.resolver` prop so AssetSourceResolver can use it instead of `Platform.OS` to identify where asset is stored on device. ([3f3a85b3c5](https://github.com/facebook/react-native/commit/3f3a85b3c5be3f9fdbd63a3acfe8456b6adeb100) by [@andrewdacenko](https://github.com/andrewdacenko)) -- Add upper case keys to the debug key handler ([6390cf67d0](https://github.com/facebook/react-native/commit/6390cf67d065727c810fcf4ef32b0cac7efac8e2) by [@wh201906](https://github.com/wh201906)) -- Debugger: Support text responses to CDP `IO.read` requests ([c085180264](https://github.com/facebook/react-native/commit/c085180264ea68f71b050cbb6b9a8274e36c3fbf) by [@robhogan](https://github.com/robhogan)) -- Add example in RNTester to show that pressability works properly with NativeDrivers ([050006a7a7](https://github.com/facebook/react-native/commit/050006a7a78fee0d54950e7ef672c73f8d680053) by [@cipolleschi](https://github.com/cipolleschi)) -- Trigger template publish ([4e14c5eeab](https://github.com/facebook/react-native/commit/4e14c5eeab86a188663c2eddf301f753c317235b) by [@blakef](https://github.com/blakef)) -- Debugging: implement common C++ layer of CDP `Network.loadNetworkResource` ([193cdc36f7](https://github.com/facebook/react-native/commit/193cdc36f7de5524b509e38da8feb209d214634c) by [@robhogan](https://github.com/robhogan)) -- Add experimental api to JSRuntimeFactory to initialize runtime on js thread ([c9fbc05bbc](https://github.com/facebook/react-native/commit/c9fbc05bbca803032914be4b38ac4c9608852963) by Benoit Girard) -- Added support for importing `react-native` in a `react-server` environment for React Server Components support. ([8989c9b71d](https://github.com/facebook/react-native/commit/8989c9b71dcca3f39b37a32945364025732eb2c3) by [@EvanBacon](https://github.com/EvanBacon)) -- Add changelog lines for RC2 ([e6dd44d6e5](https://github.com/facebook/react-native/commit/e6dd44d6e5dca07d2fcd37eba7625fec75de7fd6) by [@cipolleschi](https://github.com/cipolleschi)) -- : Inspector: Support `/open-debugger` specifying `target` param ([88ba9a6042](https://github.com/facebook/react-native/commit/88ba9a60428697f5957f269e85fbef3d0afc5046) by [@robhogan](https://github.com/robhogan)) -- Add support for `texAlignment: 'start'` ([a2cb34371e](https://github.com/facebook/react-native/commit/a2cb34371e6e52305ee58f23d3b2fefc1e8c7157) by [@javache](https://github.com/javache)) - -#### Android specific - -- Enable React Native DevTools in OSS debug builds ([143f1ad298](https://github.com/facebook/react-native/commit/143f1ad29874c1e8e9561abae263cb08f4859407) by [@robhogan](https://github.com/robhogan)) -- Support simple opacity in nested text ([a2d53d5ea0](https://github.com/facebook/react-native/commit/a2d53d5ea08959da0bbce3c494e06634e3d52d2a) by [@NickGerleman](https://github.com/NickGerleman)) -- Update compileSdk to 35 ([1333e0ee6a](https://github.com/facebook/react-native/commit/1333e0ee6ac78ad856b7f86234ec2606fcc48a7e) by [@alanleedev](https://github.com/alanleedev)) -- Added a conditional check in the `resolveThemeAttribute` function to reattempt resource resolution with the "android" package name if the resource ID is 0. ([6365df54db](https://github.com/facebook/react-native/commit/6365df54dbd0a7e185cfe113a9cf0026b2bb12ef) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) -- Add support for handling `com.facebook.react.bridge.Dynamic` as parameter type in TurboModules ([d01f1b3214](https://github.com/facebook/react-native/commit/d01f1b3214b435d436fd6cf145d8e450a188301c) by [@cortinico](https://github.com/cortinico)) -- Linear gradient ([bd0aedc8c3](https://github.com/facebook/react-native/commit/bd0aedc8c3dbebf96e123fd1bd33f515d09e2579) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway)) -- Provide default implementation for ReactHostDelegate.handleInstanceException() ([34e3a6cc88](https://github.com/facebook/react-native/commit/34e3a6cc885a68148b1d2209adc70c8109a56a66) by [@alanleedev](https://github.com/alanleedev)) -- Add BackgroundStyleApplicator for managing view backgrounds ([1a78477ce5](https://github.com/facebook/react-native/commit/1a78477ce528b36a97602d0210bd4ea8446804dc) by [@NickGerleman](https://github.com/NickGerleman)) -- Added support for rendering XML assets provided to `Image` ([aad9240fd4](https://github.com/facebook/react-native/commit/aad9240fd435d549812b5075767c5ea39a8fbb4f) by Peter Abbondanzo) -- Introduce Systrace.beginSection with arguments ([384983025a](https://github.com/facebook/react-native/commit/384983025a5afcc1e470817a1ccfa3bb8df6a936) by [@mdvacca](https://github.com/mdvacca)) -- Added `onUserLeaveHint` support into `ReactActivityDelegate` ([27ba369f23](https://github.com/facebook/react-native/commit/27ba369f2325db5678aaf6a18927c127921840e0) by [@behenate](https://github.com/behenate)) -- Add Java Turbo Module Event Emitter example ([84a9f5e6c8](https://github.com/facebook/react-native/commit/84a9f5e6c8e3af97e7d084ccb8ffdef44dcc87fb) by [@christophpurrer](https://github.com/christophpurrer)) -- Allow js bundle file urls ([7522336412](https://github.com/facebook/react-native/commit/752233641210a0b2e6bc1438f82d0aa193c2ef0d) by [@RSNara](https://github.com/RSNara)) -- Make ReactInstanceEventListener available on ReactHost ([80e1dd70b0](https://github.com/facebook/react-native/commit/80e1dd70b0b27195b9b71ea531728eef9799caa9) by [@RSNara](https://github.com/RSNara)) -- Add `invalidate()` method to ReactHost and ReactInstanceManager ([a3db352e25](https://github.com/facebook/react-native/commit/a3db352e25c01614ade3e42637e3d5726e582308) by [@motiz88](https://github.com/motiz88)) - -#### iOS specific - -- Line break mode for TextInput components. **This includes iOS updates to consume new cpp functions.** ([fe941a8f4c](https://github.com/facebook/react-native/commit/fe941a8f4c92fa9b1f07d2dd94050c81d63c77e8) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) -- Line break mode for TextInput components. **This includes cpp changes and new functions.** ([6cab6c2a13](https://github.com/facebook/react-native/commit/6cab6c2a13b89cbee1a2c1957ea561f82cb6700a) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) -- Add support for missing text content types ([d7a3e48032](https://github.com/facebook/react-native/commit/d7a3e48032fe76d118c2b5c14032d7a73319adf8) by [@krozniata](https://github.com/krozniata)) -- Support LargeContentViewer on iOS for better accessibility ([6cc44d765a](https://github.com/facebook/react-native/commit/6cc44d765a1127aa4998a490e3ff90b741ef9441) by [@bacarybruno](https://github.com/bacarybruno)) -- Enable third-party podspec sources to be fetched from mirrored git repositories ([53969cb8d0](https://github.com/facebook/react-native/commit/53969cb8d0460ccb2e899ec290135f447ed5dc65) by [@RailByteOEBB](https://github.com/RailByteOEBB)) -- Declare the `onUserDrivenAnimationEnded` in the old Architecture ([4faafb0aa4](https://github.com/facebook/react-native/commit/4faafb0aa42dbe51a84b5c59e82d753bef0d5fc2) by [@cipolleschi](https://github.com/cipolleschi)) -- Debugger: Implement CDP methods for loading network resources through the debug target. ([c720583f6c](https://github.com/facebook/react-native/commit/c720583f6c071959e7898befb62cd36f84c581dc) by [@robhogan](https://github.com/robhogan)) -- Linear gradient ([b99675d78a](https://github.com/facebook/react-native/commit/b99675d78a8269403b68d7eae8dc67ec85aea3e6) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway)) -- Declare the `onUserDrivenAnimationEnded` in the old Architecture ([f8c13f601d](https://github.com/facebook/react-native/commit/f8c13f601d5f7f159dd7a0e42b9fcc877d48d69b) by [@cipolleschi](https://github.com/cipolleschi)) -- Retrieve the tags of the nodes connected by the animation and send them to JS ([fd748ae84c](https://github.com/facebook/react-native/commit/fd748ae84cf18c1c204a936af45bb4883d476cd7) by [@cipolleschi](https://github.com/cipolleschi)) -- Send onScrollEnded event to NativeTurboAnimatedModule ([7af743236f](https://github.com/facebook/react-native/commit/7af743236f25ee03b674baf46f6506dbbc2e4fc0) by [@cipolleschi](https://github.com/cipolleschi)) -- Added handling of `showSoftInputOnFocus` props for new arch. ([ead50d6b11](https://github.com/facebook/react-native/commit/ead50d6b1180dbe9f8b49d646cc34f83aae41c74) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) -- Add EventEmitter Code-gen support for Java and ObjC Turbo Modules ([ad3df84668](https://github.com/facebook/react-native/commit/ad3df84668f1624e830396364c331783c6f99948) by [@christophpurrer](https://github.com/christophpurrer)) -- Add ObjC Turbo Module Event Emitter example ([f473a2f8f4](https://github.com/facebook/react-native/commit/f473a2f8f48ed8ce94a1f8a3181a5dabb4c6ad8d) by [@christophpurrer](https://github.com/christophpurrer)) -- Code-generate an optional base class to use for every NativeModule ([ed5f558a6c](https://github.com/facebook/react-native/commit/ed5f558a6cb5ff597870e7013150113b9460c0dc) by [@christophpurrer](https://github.com/christophpurrer)) -- Added RCTUIInterfaceOrientation helper method ([cf015f93ef](https://github.com/facebook/react-native/commit/cf015f93efa888be61150915b18ae8cd12d11232) by [@Biki-das](https://github.com/Biki-das)) - -### Changed - -- Bump cli dependencies to 15.0.0-alpha.2 ([148066e8f9](https://github.com/facebook/react-native/commit/148066e8f9e74fb0b5423fd31c02e1ad02c74d6d) by [@cipolleschi](https://github.com/cipolleschi)) -- Bring back CxxTurboModule autolinking function, but remove `RCT_EXPORT_CXX_MODULE_EXPERIMENTAL` macro ([e629a8552d](https://github.com/facebook/react-native/commit/e629a8552d5562115cd0d1eea7ab45e6fc4a5b07) by [@mrousavy](https://github.com/mrousavy)) -- Improved runtime performance of `Animated` ([d1ebe02c19](https://github.com/facebook/react-native/commit/d1ebe02c19a4ae78f54e2647d5b18e6bf93079c1) by [@yungsters](https://github.com/yungsters)) -- Changed Metro default config to use Hermes parser, enabling the use of advanced Flow syntax in React Native. ([320963c7cb](https://github.com/facebook/react-native/commit/320963c7cb394ccd8768003ad40c9767fdb7f4e3) by [@yungsters](https://github.com/yungsters)) -- Changed `Animated` props validation to soft errors instead of thrown errors ([0a1ba02273](https://github.com/facebook/react-native/commit/0a1ba02273693ffd605ca2aebce90746c1745a9c) by [@yungsters](https://github.com/yungsters)) -- Improved error message for invalid filter values ([4094ce0718](https://github.com/facebook/react-native/commit/4094ce0718c54a2c9a326cc2962ea00e30b7bdf6) by [@yungsters](https://github.com/yungsters)) -- Add official `boxShadow` and `filter` CSS properties ([6fa54f9b5d](https://github.com/facebook/react-native/commit/6fa54f9b5d73f0f347754921898e75b56ae12cb6) by [@jorge-cab](https://github.com/jorge-cab)) -- Upgrade pretty-format to 29.7.0 ([7bc9244d0c](https://github.com/facebook/react-native/commit/7bc9244d0cbebc310116b6b2a2baf0781073d0f5) by [@dprevost-LMI](https://github.com/dprevost-LMI)) -- Remove `--experimental-debugger` option from start command ([94e7a87f23](https://github.com/facebook/react-native/commit/94e7a87f2344c2024817ea7e928ab81e7f57aa76) by [@huntie](https://github.com/huntie)) -- Improve `Appearance` performance overhead by lazily initializing the NativeModule ([b86e8ef95f](https://github.com/facebook/react-native/commit/b86e8ef95fc6d7e35b2e20529a52bb74780dcf1a) by [@yungsters](https://github.com/yungsters)) -- Improved `Appearance.getColorScheme` performance ([8f0f50f7a1](https://github.com/facebook/react-native/commit/8f0f50f7a1729019b1b0957076edfee58a146c56) by [@yungsters](https://github.com/yungsters)) -- Move init deprecation notice 30 Sept → 31 Dec ([014370d825](https://github.com/facebook/react-native/commit/014370d825b273bc96464e84ba2d57ae5cf37eda) by [@blakef](https://github.com/blakef)) -- Upgrade `react-native-community/cli` to `13.6.9` ([353d88d54e](https://github.com/facebook/react-native/commit/353d88d54ef2f78f9112c4e56e4d00405cc501b9) by [@szymonrybczak](https://github.com/szymonrybczak)) -- TurboModules will be looked up as TurboModules first, and fallback to legacy modules after. ([5a62606ab3](https://github.com/facebook/react-native/commit/5a62606ab36edaffb0a5c760d2b0ed0c8e3808a8) by [@javache](https://github.com/javache)) -- Drop `node-fetch` in favor of Node's built-in fetch from `undici` in `react-native/dev-middleware` ([30a3e6e8df](https://github.com/facebook/react-native/commit/30a3e6e8dfcfc9597873578b8332ec027ccf1b84) by [@byCedric](https://github.com/byCedric)) -- Fixed native component mocking in Jest unit tests to support functional components ([fb58494283](https://github.com/facebook/react-native/commit/fb58494283102a67bcecda3265f70f010764a126) by [@yungsters](https://github.com/yungsters)) -- Bumps the CLI to alpha 11 ([c0b5e2e031](https://github.com/facebook/react-native/commit/c0b5e2e031f0e471b57640be13fe086d36c48a99) by [@cipolleschi](https://github.com/cipolleschi)) -- Improve LogBox safe area insets styling ([18302831c4](https://github.com/facebook/react-native/commit/18302831c49299d326935f875655c439cc4fbe0d) by [@yungsters](https://github.com/yungsters)) -- : Inspector: Enforce device and appId filters if both are given to /open-debugger ([c7970379a1](https://github.com/facebook/react-native/commit/c7970379a1e9be87be22ddcdec38752257059450) by [@robhogan](https://github.com/robhogan)) -- Timer functions `timeout` argument is now coerced to a number ([af04eb773c](https://github.com/facebook/react-native/commit/af04eb773cf7531323c6a34a276098e84c6041a9) by [@robik](https://github.com/robik)) -- RN CLI to 14.0.0-alpha.7 ([3dcf86b802](https://github.com/facebook/react-native/commit/3dcf86b8022090e766c93aed062e4d1d849299a1) by [@blakef](https://github.com/blakef)) -- Debugger: `j` opens most recent (not first) target. ([2a6a895b17](https://github.com/facebook/react-native/commit/2a6a895b17fdd4112349853e08a50c4c90886cb8) by [@robhogan](https://github.com/robhogan)) -- Debugger: Make `/json/list` return connection-addition-ordered targets. ([53951d7fec](https://github.com/facebook/react-native/commit/53951d7fec2997487d1ee948304ab904c21338aa) by [@robhogan](https://github.com/robhogan)) - -#### Android specific - -- Bump AGP to 8.6.0 ([aca31eb610](https://github.com/facebook/react-native/commit/aca31eb610c2c4d433311b1cdaf20af94fd54622) by [@cortinico](https://github.com/cortinico)) -- Gradle to 8.10 ([d0a5f8ff51](https://github.com/facebook/react-native/commit/d0a5f8ff5167d1deac85f2b9a0595abc9dd4a554) by [@cortinico](https://github.com/cortinico)) -- Modify LogBox to be usable on Android 15 ([5fe7660439](https://github.com/facebook/react-native/commit/5fe76604393a7e931559a3ef82564619885dbe43) by [@alanleedev](https://github.com/alanleedev)) -- Adding padding for RNTester on Android 15 forced edge-to-edge ([f7479e6a1c](https://github.com/facebook/react-native/commit/f7479e6a1ca5b6bc07a50a59a7d9fcd43bddcdef) by [@alanleedev](https://github.com/alanleedev)) -- Move `experimental_boxShadow` and `experimental_backgroundImage` to BaseViewConfig ([03801f275e](https://github.com/facebook/react-native/commit/03801f275e81c27a09f717bf48322f9ab1a54fc1) by [@NickGerleman](https://github.com/NickGerleman)) -- Revamp InsetBoxShadowDrawable ([d9f684b1cf](https://github.com/facebook/react-native/commit/d9f684b1cf7fb6824e25e1e948bfb30dec450464) by [@NickGerleman](https://github.com/NickGerleman)) -- Support OutsetBoxShadowDrawable on Android 9+ ([f905f90468](https://github.com/facebook/react-native/commit/f905f904685cc67a948349e0d58dce8b7f524069) by [@NickGerleman](https://github.com/NickGerleman)) -- Merge libuimanagerjni.so inside libreactnative.so ([7916f7e120](https://github.com/facebook/react-native/commit/7916f7e12014c42b2bc9bfcfe053e37358fc39a4) by [@cortinico](https://github.com/cortinico)) -- Move libyoga.so and libturbomodulejsijni.so inside libreactnative.so ([80c3aea48d](https://github.com/facebook/react-native/commit/80c3aea48d584b49fab8df3a417558cf5c5c3b12) by [@cortinico](https://github.com/cortinico)) -- Move more libraries to so-merging: rninstance, react_featureflagsjni, hermesinstancejni, fabricjni ([e864910a4d](https://github.com/facebook/react-native/commit/e864910a4d805a23244365b96e1f5e207a45a4a9) by [@cortinico](https://github.com/cortinico)) -- Move libmapbufferjni.so inside libreactnative.so ([5b761ff15c](https://github.com/facebook/react-native/commit/5b761ff15cdb2501862f07650912cbd26eaafdef) by [@cortinico](https://github.com/cortinico)) -- Move libreact_newarchdefaults.so inside libreactnative.so ([0caf3e824d](https://github.com/facebook/react-native/commit/0caf3e824d81689034ddf96d86d2362c9911d389) by [@cortinico](https://github.com/cortinico)) -- Make `setPointerEvents` public ([010e0010a3](https://github.com/facebook/react-native/commit/010e0010a38e111df110584ebacaabe210c3f137) by [@jakex7](https://github.com/jakex7)) -- Avoid image ofscreen render ([620b1221fa](https://github.com/facebook/react-native/commit/620b1221fa7d4e0e8e070031f65fdf786e3342d0) by [@NickGerleman](https://github.com/NickGerleman)) -- Migrated ReactSwitch to Kotlin ([03c0e5e2af](https://github.com/facebook/react-native/commit/03c0e5e2af288e96f39fa044cbbe8ebef91bdb1e) by [@blakef](https://github.com/blakef)) -- Summary: Changelog: [Android][Changed] AdditionalAnimatedNode.java → Kotlin ([8689aa48bb](https://github.com/facebook/react-native/commit/8689aa48bb5fac6b96144c08d49b15359ef141a1) by [@blakef](https://github.com/blakef)) -- Migrated `packages/gradle-plugin/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/PrepareJSCTaskTest.kt` to assertj. ([2b39e6307e](https://github.com/facebook/react-native/commit/2b39e6307ea8abafe0c84a4a2e838b40e82e32e0) by [@BogiKay](https://github.com/BogiKay)) -- #### [Android] [Changed] - Migrated ```ReactActivityDelegateTest``` ([3b76c8441d](https://github.com/facebook/react-native/commit/3b76c8441d2161ce13d411dd0b3cac068396054b) by [@gustavoabel](https://github.com/gustavoabel)) -- Migrated `ShareModuleTest` from junit.Assert to assertj.core.api.Assertions. ([e2d9ff8538](https://github.com/facebook/react-native/commit/e2d9ff8538c2bb39db498a6f39bcedeb3f983ea9) by [@migueldaipre](https://github.com/migueldaipre)) -- #### [Android] [Changed] - Migrated ```HeaderUtilTest``` ([d32444600c](https://github.com/facebook/react-native/commit/d32444600cac983551af78fc4770c270c794aaa6) by [@gustavoabel](https://github.com/gustavoabel)) -- Migrated `BuildCodegenCLITaskTest`, `PrepareGlogTaskTest` from junit.Assert to assertj.core.api.Assertions. ([053865bd80](https://github.com/facebook/react-native/commit/053865bd80d1a3433f3fe9f2a9795b55096a0339) by [@migueldaipre](https://github.com/migueldaipre)) -- Migrated `DefaultNewArchitectureEntryPointTest`, `InteropEventEmitterTest`, `InteropModuleRegistryTest` from junit.Assert to assertj.core.api.Assertions. ([7aff1b9bd8](https://github.com/facebook/react-native/commit/7aff1b9bd8bcdad942f107eb9a1af5baa4222be6) by [@migueldaipre](https://github.com/migueldaipre)) -- Deprecate DeveloperSettings.isStartSamplingProfilerOnInit ([52237838dc](https://github.com/facebook/react-native/commit/52237838dc65fd97ec5498e2eac268808bd7fa9a) by [@cortinico](https://github.com/cortinico)) -- Gradle to 8.9 ([b82d7e100c](https://github.com/facebook/react-native/commit/b82d7e100c7a6b03295ed87915f54c477b00c983) by [@cortinico](https://github.com/cortinico)) -- Modules marked with needsEagerInit = true will now be created on the mqt_native thread. ([c4a6bbc8fd](https://github.com/facebook/react-native/commit/c4a6bbc8fd8992059abdcfae2bc483bd29f31e79) by [@javache](https://github.com/javache)) -- Log a SoftException on SurfaceMountingManager.addRootView ([3429dc1ccf](https://github.com/facebook/react-native/commit/3429dc1ccf32b6b23f4f0ad3cfdf0d5697af665f) by [@psionic12](https://github.com/psionic12)) -- Extracted common parts related to calculating text layout to a helper ([2eaf0b0848](https://github.com/facebook/react-native/commit/2eaf0b0848d660eb19fde2921570f9e8bd2bd1de) by [@j-piasecki](https://github.com/j-piasecki)) - -#### iOS specific - -- Changed border display ([94407f56d1](https://github.com/facebook/react-native/commit/94407f56d133b2ba46dc5b31679e9500470e1770) by [@coado](https://github.com/coado)) -- Don't include C++ bridging header in RCTTurboModule.h ([3fc7ebb311](https://github.com/facebook/react-native/commit/3fc7ebb311e86cf2e3e78efacb1860deadd54216) by [@christophpurrer](https://github.com/christophpurrer)) -- Refactor supportedInterfaceOrientations method to use RCTKeyWindow() ([815c415fb9](https://github.com/facebook/react-native/commit/815c415fb90944db89552a503eb53059e9f0d20b) by [@okwasniewski](https://github.com/okwasniewski)) +- **Animated:** Improved runtime performance of `Animated` ([d1ebe02c19](https://github.com/facebook/react-native/commit/d1ebe02c19a4ae78f54e2647d5b18e6bf93079c1) by [@yungsters](https://github.com/yungsters)) +- **Animated:** Changed `Animated` props validation to soft errors instead of thrown errors ([0a1ba02273](https://github.com/facebook/react-native/commit/0a1ba02273693ffd605ca2aebce90746c1745a9c) by [@yungsters](https://github.com/yungsters)) +- **Appearance:** Improved `Appearance.getColorScheme` performance ([8f0f50f7a1](https://github.com/facebook/react-native/commit/8f0f50f7a1729019b1b0957076edfee58a146c56) by [@yungsters](https://github.com/yungsters)) +- **c++:** Removed using namespace std::placeholders ([194b642633](https://github.com/facebook/react-native/commit/194b642633d944b9e73e55b947284eabd42d55a2) by [@r-barnes](https://github.com/r-barnes)) +- **devtools:** Remove `--experimental-debugger` option from start command ([94e7a87f23](https://github.com/facebook/react-native/commit/94e7a87f2344c2024817ea7e928ab81e7f57aa76) by [@huntie](https://github.com/huntie)) +- **devtools:** Inspector: Enforce device and appId filters if both are given to /open-debugger ([c7970379a1](https://github.com/facebook/react-native/commit/c7970379a1e9be87be22ddcdec38752257059450) by [@robhogan](https://github.com/robhogan)) +- **devtools:** Debugger: `j` opens most recent (not first) target. ([2a6a895b17](https://github.com/facebook/react-native/commit/2a6a895b17fdd4112349853e08a50c4c90886cb8) by [@robhogan](https://github.com/robhogan)) +- **devtools:** Debugger: Make `/json/list` return connection-addition-ordered targets. ([53951d7fec](https://github.com/facebook/react-native/commit/53951d7fec2997487d1ee948304ab904c21338aa) by @robhogan) +- **devtools** Add Fusebox support for saving traces to disk ([1bd4a11736](https://github.com/facebook/react-native/commit/1bd4a11736c2916c9114df55395d474a801ee63b) by Benoit Girard) +- **devtools:** Simplify key handling in start command ([5a0df6d0bf](https://github.com/facebook/react-native/commit/5a0df6d0bf5e84d3f7d2a6f000e617e00b8bef02) by [@huntie](https://github.com/huntie)) +- **error handling:** Improved error message for invalid filter values ([4094ce0718](https://github.com/facebook/react-native/commit/4094ce0718c54a2c9a326cc2962ea00e30b7bdf6) by [@yungsters](https://github.com/yungsters)) +- **error handling:** Improve LogBox safe area insets styling ([18302831c4](https://github.com/facebook/react-native/commit/18302831c49299d326935f875655c439cc4fbe0d) by [@yungsters](https://github.com/yungsters)) +- **infra:** Update all babel packages and fix tests accordingly ([b37101486b](https://github.com/facebook/react-native/commit/b37101486bd4dc26f6ec4e646e12d1484ec9479f) by [@vzaidman](https://github.com/vzaidman)) +- **infra:** Upgrade pretty-format to 29.7.0 ([7bc9244d0c](https://github.com/facebook/react-native/commit/7bc9244d0cbebc310116b6b2a2baf0781073d0f5) by [@dprevost-LMI](https://github.com/dprevost-LMI)) +- **infra:** Move init deprecation notice 30 Sept → 31 Dec, to give users more time to update their infrastructure ([014370d825](https://github.com/facebook/react-native/commit/014370d825b273bc96464e84ba2d57ae5cf37eda) by [@blakef](https://github.com/blakef)) +- **infra:** Drop `node-fetch` in favor of Node's built-in fetch from `undici` in `react-native/dev-middleware` ([30a3e6e8df](https://github.com/facebook/react-native/commit/30a3e6e8dfcfc9597873578b8332ec027ccf1b84) by [@byCedric](https://github.com/byCedric)) +- **infra:** Allow use without @react-native-community/cli-server-api ([24997dc5ae](https://github.com/facebook/react-native/commit/24997dc5ae4ed85d3965cbc6796423f5012e4eb1) by @blakef) +- **infra:** Add CLI selection of multiple debug targets ([6a24df7eaa](https://github.com/facebook/react-native/commit/6a24df7eaab2420e91b9a4fc9202c175c0802441) by [@huntie](https://github.com/huntie)) +- **infra** Update Metro to "^0.81.0" ([3f8d1fa286](https://github.com/facebook/react-native/commit/3f8d1fa2862814cc8e2b091786e80231670bb876) by [@robhogan](https://github.com/robhogan)) +- **initialization:** Improve `Appearance` performance overhead by lazily initializing the NativeModule ([b86e8ef95f](https://github.com/facebook/react-native/commit/b86e8ef95fc6d7e35b2e20529a52bb74780dcf1a) by [@yungsters](https://github.com/yungsters)) +- **metro:** Changed Metro default config to use Hermes parser, enabling the use of advanced Flow syntax in React Native. ([320963c7cb](https://github.com/facebook/react-native/commit/320963c7cb394ccd8768003ad40c9767fdb7f4e3) by [@yungsters](https://github.com/yungsters)) +- **metro:** Use Metro terminal reporter for dev-middleware logs ([2f04dfe795](https://github.com/facebook/react-native/commit/2f04dfe7951e5f4c63f94c74d7ad10cd53969da0) by [@huntie](https://github.com/huntie)) +- **metro:** Fix server.end() usage following Metro bump ([02b879b1e2](https://github.com/facebook/react-native/commit/02b879b1e22dd03f52ff77d82cac3fe167aaea84) by [@huntie](https://github.com/huntie)) +- **runtime:** Timer functions `timeout` argument is now coerced to a number ([af04eb773c](https://github.com/facebook/react-native/commit/af04eb773cf7531323c6a34a276098e84c6041a9) by [@robik](https://github.com/robik)) +- **turbomodules:** Replace TurboReactPackage with BaseReactPackage ([e881a1184c](https://github.com/facebook/react-native/commit/e881a1184cadd45321b781d07c6154a14332c5f6) by [@philIip](https://github.com/philIip)) +- **yoga** Replace YogaConstants.UNDEFINED with Float.NaN ([8bd9952eaf](https://github.com/facebook/react-native/commit/8bd9952eaf28fe8feca7490293656caeefe7897e) by Jingbo Yang) + + +#### Android specific + +- **DevTools** Make PackagerConnectionSettings class open again ([4dd47eeb9e](https://github.com/facebook/react-native/commit/4dd47eeb9ea91455efcd0db23a02162ab338a53f) by [@gabrieldonadel](https://github.com/gabrieldonadel)) +- **infra:** Update compileSdk to 35 ([1333e0ee6a](https://github.com/facebook/react-native/commit/1333e0ee6ac78ad856b7f86234ec2606fcc48a7e) by [@alanleedev](https://github.com/alanleedev)) +- **infra:** Expose jsc tooling via prefab ([e91690d929](https://github.com/facebook/react-native/commit/e91690d929d7c8b251964cae282ad8e1d95aa39a) by [@tomekzaw](https://github.com/tomekzaw)) +- **infra:**Expose hermes tooling via prefab ([f41af55958](https://github.com/facebook/react-native/commit/f41af55958dfbc39c536d433c3a27db329dd05f1) by [@cortinico](https://github.com/cortinico)) +- **infra:** Bump AGP to 8.6.0 ([aca31eb610](https://github.com/facebook/react-native/commit/aca31eb610c2c4d433311b1cdaf20af94fd54622) by [@cortinico](https://github.com/cortinico)) +- **infra:** Gradle to 8.10.2 ([60a2706e97](https://github.com/facebook/react-native/commit/60a2706e9716d955fc0d7e15b02ad0d6efe58fc2) by [@cortinico](https://github.com/cortinico)) +- **LogBox:** Modify LogBox to be usable on Android 15 ([5fe7660439](https://github.com/facebook/react-native/commit/5fe76604393a7e931559a3ef82564619885dbe43) by [@alanleedev](https://github.com/alanleedev)) +- **Modal** Fix crash for Modal not attached to window manager ([73ce1984e8](https://github.com/facebook/react-native/commit/73ce1984e8411a6b4aec440a5e7aa9d2b7474984) by [@alanleedev](https://github.com/alanleedev)) +- **style:** Move `experimental_boxShadow` and `experimental_backgroundImage` to BaseViewConfig ([03801f275e](https://github.com/facebook/react-native/commit/03801f275e81c27a09f717bf48322f9ab1a54fc1) by [@NickGerleman](https://github.com/NickGerleman)) +- **style:** Revamp InsetBoxShadowDrawable ([d9f684b1cf](https://github.com/facebook/react-native/commit/d9f684b1cf7fb6824e25e1e948bfb30dec450464) by [@NickGerleman](https://github.com/NickGerleman)) +- **style:** Support OutsetBoxShadowDrawable on Android 9+ ([f905f90468](https://github.com/facebook/react-native/commit/f905f904685cc67a948349e0d58dce8b7f524069) by [@NickGerleman](https://github.com/NickGerleman)) +- **infra:** Merge libuimanagerjni.so inside libreactnative.so ([7916f7e120](https://github.com/facebook/react-native/commit/7916f7e12014c42b2bc9bfcfe053e37358fc39a4) by [@cortinico](https://github.com/cortinico)) +- **infra:** Move libyoga.so and libturbomodulejsijni.so inside libreactnative.so ([80c3aea48d](https://github.com/facebook/react-native/commit/80c3aea48d584b49fab8df3a417558cf5c5c3b12) by [@cortinico](https://github.com/cortinico)) +- **infra:** Move more libraries to so-merging: rninstance, react_featureflagsjni, hermesinstancejni, fabricjni ([e864910a4d](https://github.com/facebook/react-native/commit/e864910a4d805a23244365b96e1f5e207a45a4a9) by [@cortinico](https://github.com/cortinico)) +- **infra:** Move libmapbufferjni.so inside libreactnative.so ([5b761ff15c](https://github.com/facebook/react-native/commit/5b761ff15cdb2501862f07650912cbd26eaafdef) by [@cortinico](https://github.com/cortinico)) +- **infra:** Move libreact_newarchdefaults.so inside libreactnative.so ([0caf3e824d](https://github.com/facebook/react-native/commit/0caf3e824d81689034ddf96d86d2362c9911d389) by [@cortinico](https://github.com/cortinico)) +- **runtime:** Make `setPointerEvents` public ([010e0010a3](https://github.com/facebook/react-native/commit/010e0010a38e111df110584ebacaabe210c3f137) by [@jakex7](https://github.com/jakex7)) +- **runtime:** Avoid image off-screen render ([620b1221fa](https://github.com/facebook/react-native/commit/620b1221fa7d4e0e8e070031f65fdf786e3342d0) by [@NickGerleman](https://github.com/NickGerleman)) +- **kotlin:** Migrated ReactSwitch to Kotlin ([03c0e5e2af](https://github.com/facebook/react-native/commit/03c0e5e2af288e96f39fa044cbbe8ebef91bdb1e) by [@blakef](https://github.com/blakef)) +- **kotlin** Migrated AdditionalAnimatedNode.java to Kotlin ([8689aa48bb](https://github.com/facebook/react-native/commit/8689aa48bb5fac6b96144c08d49b15359ef141a1) by [@blakef](https://github.com/blakef)) +- **turbomodule:** Modules marked with needsEagerInit = true will now be +created on the mqt_native thread. ([c4a6bbc8fd](https://github.com/facebook/react-native/commit/c4a6bbc8fd8992059abdcfae2bc483bd29f31e79) by [@javache](https://github.com/javache)) +- **error handling** Log a SoftException on SurfaceMountingManager.addRootView ([3429dc1ccf](https://github.com/facebook/react-native/commit/3429dc1ccf32b6b23f4f0ad3cfdf0d5697af665f) by [@psionic12](https://github.com/psionic12)) +- **layout:** Extracted common parts related to calculating text layout to a helper ([2eaf0b0848](https://github.com/facebook/react-native/commit/2eaf0b0848d660eb19fde2921570f9e8bd2bd1de) by @j-piasecki) +- **kotlin:** Migrate StyleAnimatedNode.java to Kotlin ([ef9149b4fc](https://github.com/facebook/react-native/commit/ef9149b4fc989827ad4b781fa89f556a1fd20db4) by [@rshest](https://github.com/rshest)) + +#### iOS specific + +- **infra** Don't include C++ bridging header in RCTTurboModule.h ([3fc7ebb311](https://github.com/facebook/react-native/commit/3fc7ebb311e86cf2e3e78efacb1860deadd54216) by [@christophpurrer](https://github.com/christophpurrer)) +- **infra** Bump iOS min version for CI ([b93c2b2412](https://github.com/facebook/react-native/commit/b93c2b241247d0a7d9b79eda76af0a7bca0ac745) by [@realsoelynn](https://github.com/realsoelynn)) +- **infra** Update RNTester and HelloWorld template app to `min iOS 15.1` ([e1a1cdacf2](https://github.com/facebook/react-native/commit/e1a1cdacf2d210353c06e7ab65f971f6592e8c00) by [@realsoelynn](https://github.com/realsoelynn)) +- **infra** Enforce we use the correct C++ version for all, even if dependency tries to set it ([d7a8aae9ac](https://github.com/facebook/react-native/commit/d7a8aae9acc441d9b6c52484e35ba158e90b4b60) by [@Titozzz](https://github.com/Titozzz)) +- **renderer** Changed border display ([94407f56d1](https://github.com/facebook/react-native/commit/94407f56d133b2ba46dc5b31679e9500470e1770) by [@coado](https://github.com/coado)) +- **runtime** Refactor supportedInterfaceOrientations method to use RCTKeyWindow() ([815c415fb9](https://github.com/facebook/react-native/commit/815c415fb90944db89552a503eb53059e9f0d20b) by [@okwasniewski](https://github.com/okwasniewski)) ### Deprecated - #### Android specific -- Deprecate ReactFeatureFlags.enableBridgelessArchitecture ([10c91e9a38](https://github.com/facebook/react-native/commit/10c91e9a3862510a24a51bcb951b2230edd3529a) by [@mdvacca](https://github.com/mdvacca)) -- Deprecate ReactFeatureFlags.useTurboModules ([0e91400857](https://github.com/facebook/react-native/commit/0e914008575bad2f8021cda2da6feb2d187e4224) by [@mdvacca](https://github.com/mdvacca)) -- Deprecate ReactFeatureFlags.enableFabricRenderer ([3f35217856](https://github.com/facebook/react-native/commit/3f35217856002d25c415b69b672ff71dc29c157b) by [@mdvacca](https://github.com/mdvacca)) -- Deprecate MapBuilder ([a696d2ed6b](https://github.com/facebook/react-native/commit/a696d2ed6b95c07229bc0fd00aca344951689bbd) by Thomas Nardone) +- **bridging:** Deprecate MapBuilder ([a696d2ed6b](https://github.com/facebook/react-native/commit/a696d2ed6b95c07229bc0fd00aca344951689bbd) by Thomas Nardone) #### iOS specific -- Add newArchEnabled method to RCTAppDelegate ([3621606c44](https://github.com/facebook/react-native/commit/3621606c4486051de8b443c443cd87f6b822d1a0) by [@okwasniewski](https://github.com/okwasniewski)) -- Deprecated StatusBar.setNetworkActivityIndicatorVisible ([8a390ba9b8](https://github.com/facebook/react-native/commit/8a390ba9b8c1b8889dd0933fe1477083a24ff71d) by Ingrid Wang) +- **initialization:** Deprecate turboModuleEnabled, fabricEnabled and bridgelessEnabled for the new newArchEnabled property. ([3621606c44](https://github.com/facebook/react-native/commit/3621606c4486051de8b443c443cd87f6b822d1a0) by [@okwasniewski](https://github.com/okwasniewski)) +- **runtime** Deprecated StatusBar.setNetworkActivityIndicatorVisible ([8a390ba9b8](https://github.com/facebook/react-native/commit/8a390ba9b8c1b8889dd0933fe1477083a24ff71d) by Ingrid Wang) ### Removed -- Remove sampling profiler from dev menu ([f57740c0fb](https://github.com/facebook/react-native/commit/f57740c0fbd431991bf90f83dac5770fa74d13cf) by [@blakef](https://github.com/blakef)) -- Removed enableArchitectureIndicator API which is only used internally. ([9b67547bec](https://github.com/facebook/react-native/commit/9b67547bec36cae2b4d9f99f66938fbe6b1466bf) by [@javache](https://github.com/javache)) - -#### Android specific - -- Removed HasJavascriptExceptionMetadata as a marker interface. Use JavascriptExecption directly ([cb00ca954d](https://github.com/facebook/react-native/commit/cb00ca954d1a7647900c8ff6b5792eb342735140) by [@javache](https://github.com/javache)) -- Unused jsEngineResolutionAlgorithm from ReactHost ([f1b6218608](https://github.com/facebook/react-native/commit/f1b6218608ea968f032f8344d4648651617482cf) by [@javache](https://github.com/javache)) -- React_newarchdefaults is no longer a prefab, instead use fabricjni ([c68f35d444](https://github.com/facebook/react-native/commit/c68f35d4441c8a03541da17e3adc03f355e8c45e) by [@javache](https://github.com/javache)) -- CoreComponentsRegistry is now fully replaced by DefaultComponentRegistry. ([de7976c69d](https://github.com/facebook/react-native/commit/de7976c69d9f837729e8822f2b89e6d08ea6883a) by [@javache](https://github.com/javache)) - -#### iOS specific - -- Fix position of RCTPerfMonitor in landscape mode & expanded mode ([258f41a30f](https://github.com/facebook/react-native/commit/258f41a30f5a797c0cfdb256a6824b7284dcc8e2) by [@krozniata](https://github.com/krozniata)) -- Remove `[RCTConvert UIBarStyle:]` ([a557a81f96](https://github.com/facebook/react-native/commit/a557a81f963041351e02f3b79489c6ee394ebe48) by [@Saadnajmi](https://github.com/Saadnajmi)) - -### Fixed - -- Upstream fixes for build errors in React Native Windows ([c722ec7c37](https://github.com/facebook/react-native/commit/c722ec7c372c44ade8439f4765b1b6470c27f470) by [@chiaramooney](https://github.com/chiaramooney)) -- Allow readonly array type for transform property ([c16defaff2](https://github.com/facebook/react-native/commit/c16defaff2964a2b30656def35eb3450cff9cd71) by [@tjzel](https://github.com/tjzel)) -- Removed noisy ENOENT error message upon launching the debugger ([5bbf5a4878](https://github.com/facebook/react-native/commit/5bbf5a4878fd3bab7b70f91e049bb6b986fd183b) by [@EdmondChuiHW](https://github.com/EdmondChuiHW)) -- Fixed undefined behavior in certain scenarios when `ReactElement` objects are supplied to Animated components ([56937d646c](https://github.com/facebook/react-native/commit/56937d646c741b32826a92a76193eadc8dc59031) by [@yungsters](https://github.com/yungsters)) -- Ensure `--build-output` destination exists ([396bdd87d8](https://github.com/facebook/react-native/commit/396bdd87d8021902ad78b817314fdc5b6207c2ea) by [@szymonrybczak](https://github.com/szymonrybczak)) -- Fix handling 'auto' checks in absolute layout ([3596019489](https://github.com/facebook/react-native/commit/359601948923baf7304d223260be3926c5b81db0) by [@coado](https://github.com/coado)) -- Fixed fontWeight number value error for text optimized ([2a230694c4](https://github.com/facebook/react-native/commit/2a230694c421bf338699506a0044c26fd4c1eb55) by [@meetdhanani17](https://github.com/meetdhanani17)) -- : [General] [Fixed] - Undefined behavior fix in MethodInvoker ([09e88448ce](https://github.com/facebook/react-native/commit/09e88448ce3a3047112b6f71218305d5bfe2e8bc) by Riley Berton) -- Limit HermesPerfetto tracing to the top 25 and bottom 25 frames, allowing you to see both sides ([5561457c98](https://github.com/facebook/react-native/commit/5561457c98df9c2d6adcc4c3d7836323304e4aba) by Benoit Girard) -- Linear gradient color stop spec. ([1a49892d57](https://github.com/facebook/react-native/commit/1a49892d574e3b77a75df8cfc77307a7d5daab35) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway)) -- Fixes findNodeAtPoint when views were inverted ([1d1646afd1](https://github.com/facebook/react-native/commit/1d1646afd1ff4f068fc41d8b142b08d53e6cd91a) by [@zhongwuzw](https://github.com/zhongwuzw)) -- Change RawPropsParser logs from ERROR level to WARNING ([68c0720e34](https://github.com/facebook/react-native/commit/68c0720e3438f9230f6dc28956c93b58ce1f2482) by Bowen Xie) -- Fix codegen failing in a pnpm monorepo because of missing `yargs` ([3e084bc159](https://github.com/facebook/react-native/commit/3e084bc15994cf5b549d1104e906e5dbb2df4417) by [@tido64](https://github.com/tido64)) -- Fix "C4715 not all control paths return a value" warning in MSVC when building ReactCommon ([c30e35fb44](https://github.com/facebook/react-native/commit/c30e35fb44affb179c9a208cf0a3e4575347e76f) by [@jonthysell](https://github.com/jonthysell)) -- Reallign the shadow tree and the native tree when the user finishes interacting with the app. ([a8786fc1df](https://github.com/facebook/react-native/commit/a8786fc1df60426000013bdcfb3a61bd201b6dac) by [@cipolleschi](https://github.com/cipolleschi)) -- Update the react-native/jest-preset mock of AccessibilityInfo to better match its API ([8d6ec66b48](https://github.com/facebook/react-native/commit/8d6ec66b480ef57f324cd1e68e05f976ea163ed5) by [@krosenberg](https://github.com/krosenberg)) -- Reallign the shadow tree and the native tree when the user finishes interacting with the app. ([afa887b622](https://github.com/facebook/react-native/commit/afa887b6225352d35ed99eb5271bef8a3fe1c7d6) by [@cipolleschi](https://github.com/cipolleschi)) -- Add missing `submitBehavior` prop and mark `blurOnSubmit` prop as deprecated in Typescript declaration file of `TextInput` ([1dcbf41725](https://github.com/facebook/react-native/commit/1dcbf41725a7296c0a0f33c4e0cc3a11e8780889) by [@thisisgit](https://github.com/thisisgit)) -- Fixed `alignItems: 'baseline'` not working correctly on the new architecture ([2932c0f71f](https://github.com/facebook/react-native/commit/2932c0f71f1882607d9e579e5c09db28e131a4c9) by [@j-piasecki](https://github.com/j-piasecki)) -- Updated comments for `~ShadowNodeWrapper()` and `~ShadowNodeListWrapper()` ([778fcecf35](https://github.com/facebook/react-native/commit/778fcecf357b92f8dd5bab07914aa8563796d0f7) by [@tomekzaw](https://github.com/tomekzaw)) -- Loosen SectionList `renderItem` required return type ([12b64b7824](https://github.com/facebook/react-native/commit/12b64b78247f2db929c6d421262bdec1f6402e0b) by [@NickGerleman](https://github.com/NickGerleman)) -- Fix Platform.constants.reactNativeVersion type ([95d9cdf228](https://github.com/facebook/react-native/commit/95d9cdf228e33d5651f41ebf5e14e80962fae118) by [@NickGerleman](https://github.com/NickGerleman)) -- Add missing methods to the WithRuntimeDecorator class. ([993f9fd8db](https://github.com/facebook/react-native/commit/993f9fd8db5fe4df495b3a3454273b0e11fef489) by [@neildhar](https://github.com/neildhar)) -- Reconnecting to an unknown inspector page no longer results in a zombie connection ([a7adfef0bb](https://github.com/facebook/react-native/commit/a7adfef0bb3df03517935e446ea0c6b506f7ed90) by [@motiz88](https://github.com/motiz88)) -- Avoid a zombie state when opening a second debugger frontend concurrently. ([e55ea2daf1](https://github.com/facebook/react-native/commit/e55ea2daf11bb527f500323e3f1bb71f10cbe1c5) by [@motiz88](https://github.com/motiz88)) -- Inspector-proxy no longer accidentally detaches connected devices. ([4c6bff01b3](https://github.com/facebook/react-native/commit/4c6bff01b384d7d899dd9d3beef12b878918704e) by [@motiz88](https://github.com/motiz88)) - -#### Android specific - -- Ensure Appearance change listener does not skip events ([7041ed28f0](https://github.com/facebook/react-native/commit/7041ed28f092e7c6c1dac35f0ce6af095cd9a072) by [@vonovak](https://github.com/vonovak)) -- RedBox content overlapping with system bars on Android 15 forced edge-to-edge ([97b661c3f0](https://github.com/facebook/react-native/commit/97b661c3f07ab0269b707b209139d5c1648d1e03) by [@alanleedev](https://github.com/alanleedev)) -- Deprecating ModalHostShadowNode and ModalHostHelper classes ([77b3a8bdd6](https://github.com/facebook/react-native/commit/77b3a8bdd6164b4c2407e53cb0e27075c3ea7213) by [@alanleedev](https://github.com/alanleedev)) -- Optimize BaseViewManager#setTransform to ignore duplicate values ([3df0f3b9ff](https://github.com/facebook/react-native/commit/3df0f3b9ff4cc9cd6846ef02101baf8e9605d6a0) by [@javache](https://github.com/javache)) -- Don't use mGapBetweenPaths if not drawing a border ([8501b6396b](https://github.com/facebook/react-native/commit/8501b6396b0a4fd7a9bd2add2b3c8b9c755c27ae) by [@knappam](https://github.com/knappam)) -- Linear gradient border styles ([20e3f4518f](https://github.com/facebook/react-native/commit/20e3f4518feac70e8ac9b1cc4fc1cbb029df96e4) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway)) -- Make getUri and isResource open ([8c81ffa60a](https://github.com/facebook/react-native/commit/8c81ffa60a211e4ae7db50cd04de0e4a4c29df04) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) -- PointerEvents from Modal would not be dispatched correctly in new architecture. ([75114e3672](https://github.com/facebook/react-native/commit/75114e36726979625674b2c75a77ac330fccc4d6) by [@javache](https://github.com/javache)) -- Fixed black strip coming when hiding status bar ([f6b6d001a0](https://github.com/facebook/react-native/commit/f6b6d001a0e0241a9d637cd5e532f0d8610d9ee1) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) -- Make Imagesource `open` for inheritance ([0e805a953d](https://github.com/facebook/react-native/commit/0e805a953d8c2e91790a2f9fa2da7850478231b7) by [@cortinico](https://github.com/cortinico)) -- Fix issue with `NativeDevSettings.setIsDebuggingRemotely` where the app would keep on restarting if remote debugging was invoked from an action / component that was called on app start. ([beebf4a0a3](https://github.com/facebook/react-native/commit/beebf4a0a36c4ee9dc52631afdf2b25745a1b0f2) by [@Sushant-Sardeshpande](https://github.com/Sushant-Sardeshpande)) -- Do not destroy views when there is a touch going on for New Architecture ([6b7f68240e](https://github.com/facebook/react-native/commit/6b7f68240e08c64ced29ed3d7a1f95db96a6eef4) by [@cortinico](https://github.com/cortinico)) -- Anntate ReactRootView.createRootView with nullable ([6a1ecbb2bb](https://github.com/facebook/react-native/commit/6a1ecbb2bb3942e7487532262f2a4fc55f94fcad) by [@shwanton](https://github.com/shwanton)) -- Gracefully handle unexpected overlow values ([82094dd9e3](https://github.com/facebook/react-native/commit/82094dd9e33d94f65fd2548f5b04a19fb89bad0f) by [@NickGerleman](https://github.com/NickGerleman)) -- Fix "setTranslucentBackgroundDrawable()" deprecation version ([35d9a18b81](https://github.com/facebook/react-native/commit/35d9a18b81ff9448459c9fb033f4fea1fa17dab3) by [@NickGerleman](https://github.com/NickGerleman)) -- Fix uploading GIF URI ([48669af562](https://github.com/facebook/react-native/commit/48669af562d6d3ed7835816d60a2fb400a22a19b) by [@s77rt](https://github.com/s77rt)) -- ([087193c98e](https://github.com/facebook/react-native/commit/087193c98ead8f12ec4f839dd077d5bd63075d6f) by [@NickGerleman](https://github.com/NickGerleman)) -- Add borderStartWidth and borderEndWidth support ([92dca53702](https://github.com/facebook/react-native/commit/92dca5370239f2c9881455b683ff384e2187430f) by [@NickGerleman](https://github.com/NickGerleman)) -- Made several methods in ReactNativeHost.java thread-safe to avoid race conditions ([f9ac5b737a](https://github.com/facebook/react-native/commit/f9ac5b737a0e14c76f35840efcf348f1c7704363) by Jack Su) -- Fix scheduled animated operations not being executed in some cases ([dc8c8ebc5b](https://github.com/facebook/react-native/commit/dc8c8ebc5b7b6315b3c8e79028a80611a796ea7e) by [@j-piasecki](https://github.com/j-piasecki)) -- Adds a null check in react context getter ([aeb020dfa3](https://github.com/facebook/react-native/commit/aeb020dfa34d06b63fa0151be302287d0a3fb84f) by Peter Abbondanzo) -- Sync the Shadow Tree and the Native Tree with Native animation when scroll is driving the animation ([394aae1c1c](https://github.com/facebook/react-native/commit/394aae1c1cc354eaefb762455e2bbeeec0503038) by [@cipolleschi](https://github.com/cipolleschi)) -- : fixed select text on auto focus for TextInput ([18d6028ff9](https://github.com/facebook/react-native/commit/18d6028ff908eef99aae363d8ee9a6789d264284) by [@kunalchavhan](https://github.com/kunalchavhan)) -- Fix AlertDialog title accessibility ([80a3ed7d0c](https://github.com/facebook/react-native/commit/80a3ed7d0c9b0ecd0cce6045672453887b5efbaf) by Peter Abbondanzo) -- Fix Android removeClippedSubviews in RTL ([ea6928fcb9](https://github.com/facebook/react-native/commit/ea6928fcb95c19e84f8f2851f28d0cd4343c6a26) by [@NickGerleman](https://github.com/NickGerleman)) -- Fixed text shadow rendering with artifacts when `backgroundColor` was set on the `TextInput` ([83716298f8](https://github.com/facebook/react-native/commit/83716298f8dd6a1f3128965225858b4c6d3b2477) by [@j-piasecki](https://github.com/j-piasecki)) -- Fixed Headless JS tasks in New Architecture ([9a1ae97c22](https://github.com/facebook/react-native/commit/9a1ae97c22868a312000f3ac50dacf9a8125d273) by [@robik](https://github.com/robik)) -- Fix ReactImageView.hasOverlappingRendering() ([2bed2ab1a6](https://github.com/facebook/react-native/commit/2bed2ab1a658230cb6fa23fdcb4e5a962f496e18) by [@NickGerleman](https://github.com/NickGerleman)) -- Fix LogModule to create view when show is called ([0847384a45](https://github.com/facebook/react-native/commit/0847384a4598d9bbc8987788047bc58d7596881d) by [@fannnzhang](https://github.com/fannnzhang)) -- Fix NPE in FileReaderModule ([fd4531fe23](https://github.com/facebook/react-native/commit/fd4531fe234149f4f078a1e73ec68145f9da20b3) by [@cortinico](https://github.com/cortinico)) -- Fix default for `showsHorizontalScrollIndicator` and `showsVerticalScrollIndicator` ([3af01a8a44](https://github.com/facebook/react-native/commit/3af01a8a44853246d3deb957c4a1c65e43848bb5) by [@NickGerleman](https://github.com/NickGerleman)) -- **Changelog:** [Android][Fixed] - TextInput's `contextMenuHidden` prop bug fix ([8a3ffb6d23](https://github.com/facebook/react-native/commit/8a3ffb6d23f169752891eddc7dad9e34cb2d861c) by [@alanleedev](https://github.com/alanleedev)) - -#### iOS specific - -- React_native_post_install script no longer adds duplicate entries to HEADER_SEARCH_PATHS ([d687d38987](https://github.com/facebook/react-native/commit/d687d389872f50fa11cbdd44ab3d68bdd392425b) by [@dirkpostma](https://github.com/dirkpostma)) -- Codegen will start looking for codegen-enabled dependencies from the project root. ([46d17efa62](https://github.com/facebook/react-native/commit/46d17efa626cd546e839648e1a95f43a3802051c) by [@dmytrorykun](https://github.com/dmytrorykun)) -- Resolve Hermes prebuilt version based on react-native packge ([b10ed0e19d](https://github.com/facebook/react-native/commit/b10ed0e19d8eec388305962667561e0cb95a3f25) by [@okwasniewski](https://github.com/okwasniewski)) -- Support bundle install from outside the ios folder using --project-directory ([b22970e3cf](https://github.com/facebook/react-native/commit/b22970e3cfbe603bffea5b1c3bbf150887e3d7b8) by [@blakef](https://github.com/blakef)) -- Fixes race condition when setup image loader ([6b104bbe01](https://github.com/facebook/react-native/commit/6b104bbe015c93a40a73232fdb92a99e3799b7ac) by [@zhongwuzw](https://github.com/zhongwuzw)) -- Fixed an issue where the refresh control would not behave correctly if it was offscreen. ([a8be335a37](https://github.com/facebook/react-native/commit/a8be335a37eb792a7c6ccb7f577459020a2fc43c) by [@deepanshushuklad11](https://github.com/deepanshushuklad11)) -- Fixes NSDataBigString length calculation ([bb3c51dc84](https://github.com/facebook/react-native/commit/bb3c51dc84e9514f55ca8a1e3abb1af140563c7b) by Tzvetan Mikov) -- Fixed baseline attachment position in multiline text ([9bfbf948df](https://github.com/facebook/react-native/commit/9bfbf948dfd23c891233e747cbaeeb6480f5fa41) by [@j-piasecki](https://github.com/j-piasecki)) -- Clean up RCTParagraphComponentView & RCTParagraphTextView ([9239ad1c6b](https://github.com/facebook/react-native/commit/9239ad1c6bac2c2400f940708d823d7b2c2457c4) by [@zhongwuzw](https://github.com/zhongwuzw)) -- Use CONFIG_CMD if set ([774fe0cf6f](https://github.com/facebook/react-native/commit/774fe0cf6f22f832b756c166599973d9db6a93de) by [@krystofwoldrich](https://github.com/krystofwoldrich)) -- Fixes Appearance user interface style when app run from background ([efa9711e35](https://github.com/facebook/react-native/commit/efa9711e35f528245cdfb6c7028129c97ae10192) by [@zhongwuzw](https://github.com/zhongwuzw)) -- App crash happening when navigate to a new app screen with a displaying modal ([52888c0c1e](https://github.com/facebook/react-native/commit/52888c0c1e722a799f233c2f502e01b9dd4a7174) by Zhi Zhou) -- Fix imports from RCTAppSetupUtils when Hermes is active ([143437a837](https://github.com/facebook/react-native/commit/143437a83732d3d0dcee13a54b8550f55d5daf90) by [@rocketraman](https://github.com/rocketraman)) -- Fixes Italic text not work ([9cfd9dd1c7](https://github.com/facebook/react-native/commit/9cfd9dd1c7f8c37c156f1a9ff812183f80d67926) by [@zhongwuzw](https://github.com/zhongwuzw)) -- Add missing pod dependency of jserrorhandler ([a77f26827f](https://github.com/facebook/react-native/commit/a77f26827fee0fc18a11faccd0b5e51d1b222735) by [@zhongwuzw](https://github.com/zhongwuzw)) -- Mac Catalyst crash in RCTRedBox ([84fe531952](https://github.com/facebook/react-native/commit/84fe531952d4b97c3cb0d84322abdf8953382ad6) by [@sbuggay](https://github.com/sbuggay)) -- Data race related to read/write on `ReactMarker::logTaggedMarkerImpl` ([7e41ea4c9d](https://github.com/facebook/react-native/commit/7e41ea4c9de943a5c73ca9821bf552d39aa49dcd) by [@hakonk](https://github.com/hakonk)) -- Implement automicallyAdjustsKeyboardInsets for new arch ([e4e461c9cf](https://github.com/facebook/react-native/commit/e4e461c9cf969e1a1dfca6448ca6084b7f45ef7d) by [@okwasniewski](https://github.com/okwasniewski)) -- Fixes FORCE_BUNDLING error when bundle js ([089e8289ba](https://github.com/facebook/react-native/commit/089e8289ba6cba0821b76207a2dce316b1621c3d) by [@zhongwuzw](https://github.com/zhongwuzw)) -- Include x86_64 slice when building for visionOS simulator ([05dec917f2](https://github.com/facebook/react-native/commit/05dec917f2e5f8288c0d9f31bc50c10bd0c0eab3) by [@okwasniewski](https://github.com/okwasniewski)) -- Implement automicallyAdjustsKeyboardInsets for new arch ([21bdce7286](https://github.com/facebook/react-native/commit/21bdce7286fc493b9601add3bf67d549b792d29b) by [@okwasniewski](https://github.com/okwasniewski)) -- Fixed crash in RCTImageUtils ([3572ef3f1b](https://github.com/facebook/react-native/commit/3572ef3f1b5b11c1ecfa21f0246cbba5941bbe0f) by [@pavelgurkovskiy](https://github.com/pavelgurkovskiy)) -- Fixes typo of function callFunctionOnBufferedRumtimeExecutor ([4e12c2e37c](https://github.com/facebook/react-native/commit/4e12c2e37cb168f09f8768941cb915e4024a1c34) by [@zhongwuzw](https://github.com/zhongwuzw)) -- Fixes main thread stuck when reload in bridgeless mode ([a778979ed6](https://github.com/facebook/react-native/commit/a778979ed604d1dc7707faf4a3836e3deba136c6) by [@zhongwuzw](https://github.com/zhongwuzw)) -- : Fixing maxLength check which was firing onChange multiple times ([d88dd14507](https://github.com/facebook/react-native/commit/d88dd145074ee84de0cc4207de02a3cd79c9ceff) by [@deepanshushuklad11](https://github.com/deepanshushuklad11)) -- Use std::atomic for eliminating races in RCTCxxBridge. ([8204134024](https://github.com/facebook/react-native/commit/8204134024e81947969bd8c2ba337dc931e54bd9) by [@hakonk](https://github.com/hakonk)) -- Fix legacy view interop apis not available in view method ([19cffab383](https://github.com/facebook/react-native/commit/19cffab3837c24f2e8470a31bbd8e8338d1c1b6c) by [@janicduplessis](https://github.com/janicduplessis)) -- Hermes prepare_command fails with space in path ([fbcb8f6b2b](https://github.com/facebook/react-native/commit/fbcb8f6b2b2d2edeed872de704c6e152064ee319) by [@okwasniewski](https://github.com/okwasniewski)) -- Data race in `RCTImageLoader` related to assignment of cancellation block. ([0f051f6034](https://github.com/facebook/react-native/commit/0f051f603492f97a85e051f112d96180352bba77) by [@hakonk](https://github.com/hakonk)) -- Message ([b243d343fa](https://github.com/facebook/react-native/commit/b243d343fa741de94537d8535f76714ff2985101) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) -- TestID wasn't propogating to accessibilityIdentifier ([ab485c6a94](https://github.com/facebook/react-native/commit/ab485c6a943a3b096aaa8a22d16abf506fae5b76) by [@blakef](https://github.com/blakef)) -- Don't set empty string when remove ccache ([c5b87aba7c](https://github.com/facebook/react-native/commit/c5b87aba7c6fd9f73aa55a7b57ed018967695ffe) by [@zhongwuzw](https://github.com/zhongwuzw)) -- Fixes ellipsis carries background from trimmed text ([fcb6cdc710](https://github.com/facebook/react-native/commit/fcb6cdc7108103527268aef42a77e530f9482668) by [@zhongwuzw](https://github.com/zhongwuzw)) -- Fix: on iOS not getting 304 from `If-None-Match` request ([b8ab0fe703](https://github.com/facebook/react-native/commit/b8ab0fe703f1a0aca796bc15641d029a2036105f) by [@huzhanbo1996](https://github.com/huzhanbo1996)) -- Fix data race related to access on `RCTNetworkTask.status`. ([b1ec698dc4](https://github.com/facebook/react-native/commit/b1ec698dc4baf34ba2e31b7ad43dff97c229bf99) by [@hakonk](https://github.com/hakonk)) -- Data race related to access of `AllocationTestModule.valid` ([dba25fa966](https://github.com/facebook/react-native/commit/dba25fa96643bdadc9bad85b20d35e106885f8e7) by [@hakonk](https://github.com/hakonk)) -- Fix rendering `RCTRedBoxExtraData` ([c9d589dab5](https://github.com/facebook/react-native/commit/c9d589dab5148cbd192078967f743d38b8048c6e) by [@krozniata](https://github.com/krozniata)) -- Fixes Image load event in new arch ([7698cd0953](https://github.com/facebook/react-native/commit/7698cd09536ebf99c3b56696a7bb75d714abfb18) by [@zhongwuzw](https://github.com/zhongwuzw)) -- Fixes TextInput crash when undo if text longer than maxLength ([9b9c780cc8](https://github.com/facebook/react-native/commit/9b9c780cc8b54e2c1cd61f9fac0554488f68dea8) by [@zhongwuzw](https://github.com/zhongwuzw)) -- Set proper framework dependencies for built-in pods ([6bb75c7b13](https://github.com/facebook/react-native/commit/6bb75c7b133c9be5f613c3310aa918e5a28cec7f) by [@okwasniewski](https://github.com/okwasniewski)) -- Retrieve status bar size using RCTUIStatusBarManager ([34cd195d9f](https://github.com/facebook/react-native/commit/34cd195d9fbd075a161afbfac842f896355991e1) by [@okwasniewski](https://github.com/okwasniewski)) -- Bump cocoapods version to 1.15.2 excluding 1.15.0, 1.15.1 ([a7b2555644](https://github.com/facebook/react-native/commit/a7b25556449db64d7211c163bdd2e5437c1ad5a6) by [@okwasniewski](https://github.com/okwasniewski)) -- Fixed text baseline being moved upwards in certain cases ([01f7ab814f](https://github.com/facebook/react-native/commit/01f7ab814f847eb3038efa7120d81e92e3ff4187) by [@j-piasecki](https://github.com/j-piasecki)) +- **devtools** Remove sampling profiler from dev menu ([f57740c0fb](https://github.com/facebook/react-native/commit/f57740c0fbd431991bf90f83dac5770fa74d13cf) by [@blakef](https://github.com/blakef)) + +#### Android specific + +- **components** CoreComponentsRegistry is now fully replaced by DefaultComponentRegistry. ([de7976c69d](https://github.com/facebook/react-native/commit/de7976c69d9f837729e8822f2b89e6d08ea6883a) by [@javache](https://github.com/javache)) +- **error handling** Removed HasJavascriptExceptionMetadata as a marker interface. Use JavascriptExecption directly ([cb00ca954d](https://github.com/facebook/react-native/commit/cb00ca954d1a7647900c8ff6b5792eb342735140) by [@javache](https://github.com/javache)) +- **initialization** Unused jsEngineResolutionAlgorithm from ReactHost ([f1b6218608](https://github.com/facebook/react-native/commit/f1b6218608ea968f032f8344d4648651617482cf) by [@javache](https://github.com/javache)) +- **infra** React_newarchdefaults is no longer a prefab, instead use fabricjni ([c68f35d444](https://github.com/facebook/react-native/commit/c68f35d4441c8a03541da17e3adc03f355e8c45e) by [@javache](https://github.com/javache)) + +#### iOS specific + +- **runtime:** Remove `[RCTConvert UIBarStyle:]` ([a557a81f96](https://github.com/facebook/react-native/commit/a557a81f963041351e02f3b79489c6ee394ebe48) by [@Saadnajmi](https://github.com/Saadnajmi)) + +### Fixed + +- **Animated:** Fixed undefined behavior in certain scenarios when `ReactElement` objects are supplied to Animated components ([56937d646c](https://github.com/facebook/react-native/commit/56937d646c741b32826a92a76193eadc8dc59031) by [@yungsters](https://github.com/yungsters)) +- **Animated:** Realign the shadow tree and the native tree when the user finishes interacting with the app. ([a8786fc1df](https://github.com/facebook/react-native/commit/a8786fc1df60426000013bdcfb3a61bd201b6dac) by [@cipolleschi](https://github.com/cipolleschi)) +- **codegen:** Fix codegen failing in a pnpm monorepo because of missing `yargs` ([3e084bc159](https://github.com/facebook/react-native/commit/3e084bc15994cf5b549d1104e906e5dbb2df4417) by [@tido64](https://github.com/tido64)) +- **c++:** Upstream fixes for build errors in React Native Windows ([c722ec7c37](https://github.com/facebook/react-native/commit/c722ec7c372c44ade8439f4765b1b6470c27f470) by [@chiaramooney](https://github.com/chiaramooney)) +- **c++:** Undefined behavior fix in MethodInvoker ([09e88448ce](https://github.com/facebook/react-native/commit/09e88448ce3a3047112b6f71218305d5bfe2e8bc) by Riley Berton) +- **c++:** Fix "C4715 not all control paths return a value" warning in MSVC when building ReactCommon ([c30e35fb44](https://github.com/facebook/react-native/commit/c30e35fb44affb179c9a208cf0a3e4575347e76f) by [@jonthysell](https://github.com/jonthysell)) +- **c++:** Updated comments for `~ShadowNodeWrapper()` and `~ShadowNodeListWrapper()` ([778fcecf35](https://github.com/facebook/react-native/commit/778fcecf357b92f8dd5bab07914aa8563796d0f7) by [@tomekzaw](https://github.com/tomekzaw)) +- **c++:** Change RawPropsParser logs from ERROR level to WARNING ([68c0720e34](https://github.com/facebook/react-native/commit/68c0720e3438f9230f6dc28956c93b58ce1f2482) by Bowen Xie) +- **devtools:** Reconnecting to an unknown inspector page no longer results in a zombie connection ([a7adfef0bb](https://github.com/facebook/react-native/commit/a7adfef0bb3df03517935e446ea0c6b506f7ed90) by [@motiz88](https://github.com/motiz88)) +- **devtools:** Avoid a zombie state when opening a second debugger frontend concurrently. ([e55ea2daf1](https://github.com/facebook/react-native/commit/e55ea2daf11bb527f500323e3f1bb71f10cbe1c5) by [@motiz88](https://github.com/motiz88)) +- **devtools:** Inspector-proxy no longer accidentally detaches connected devices. ([4c6bff01b3](https://github.com/facebook/react-native/commit/4c6bff01b384d7d899dd9d3beef12b878918704e) by @motiz88) +- **devtools:** Throttle reload command ([42bad68220](https://github.com/facebook/react-native/commit/42bad68220d288ef2436609ee50ad993c239b362) by [@coado](https://github.com/coado)) +- **devtools** Respond with status code `200` when successfully launching RNDT ([eeb6122f39](https://github.com/facebook/react-native/commit/eeb6122f390d355191182eaee6cf126468e7b4d4) by [@byCedric](https://github.com/byCedric)) +- **error reporting:** Fix logbox reporting React errors as Warnings ([cbb313253f](https://github.com/facebook/react-native/commit/cbb313253fdf96c4fca06a24ed4cbd3f3df9db80) by [@rickhanlonii](https://github.com/rickhanlonii)) +- **error reporting** Restore Metro log forwarding, change notice to signal future removal ([6047f9cc09](https://github.com/facebook/react-native/commit/6047f9cc09a7a86b79084a3ff1b4303c4583d2ce) by [@huntie](https://github.com/huntie)) +- **flow:** Fix parsing of modern Flow syntax when `transformer.hermesParser = false` is configured in Metro config ([1387f521fd](https://github.com/facebook/react-native/commit/1387f521fdd8f187eab7a4a6a05d4d75a96b4f88) by [@huntie](https://github.com/huntie)) +- **infra:** Removed noisy ENOENT error message upon launching the debugger ([5bbf5a4878](https://github.com/facebook/react-native/commit/5bbf5a4878fd3bab7b70f91e049bb6b986fd183b) by [@EdmondChuiHW](https://github.com/EdmondChuiHW)) +- **infra:** Ensure `--build-output` destination exists ([396bdd87d8](https://github.com/facebook/react-native/commit/396bdd87d8021902ad78b817314fdc5b6207c2ea) by [@szymonrybczak](https://github.com/szymonrybczak)) +- **infra:** Fix Platform.constants.reactNativeVersion type ([95d9cdf228](https://github.com/facebook/react-native/commit/95d9cdf228e33d5651f41ebf5e14e80962fae118) by [@NickGerleman](https://github.com/NickGerleman)) +- **js:** Fixes findNodeAtPoint when views were inverted ([1d1646afd1](https://github.com/facebook/react-native/commit/1d1646afd1ff4f068fc41d8b142b08d53e6cd91a) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **layout:** Fix handling 'auto' checks in absolute layout ([3596019489](https://github.com/facebook/react-native/commit/359601948923baf7304d223260be3926c5b81db0) by [@coado](https://github.com/coado)) +- **runtime** Add missing methods to the WithRuntimeDecorator class. ([993f9fd8db](https://github.com/facebook/react-native/commit/993f9fd8db5fe4df495b3a3454273b0e11fef489) by [@neildhar](https://github.com/neildhar)) +- **runtime:** Undo breaking change on ViewManagerDelegate.kt String params (ce1620616c by @cortinico) +- **runtime:** Undo breaking change on UIManager eventDispatcher accessor (55671c00e5 by @cortinico) +- **Scrollview:** Properly make ScrollView compatible with React 19 ([b395208303](https://github.com/facebook/react-native/commit/b39520830341cae8c3785250cbaf2ec99958ba69) by [@cipolleschi](https://github.com/cipolleschi)) +- **Scrollview:** Make ScrollView compatible with React 19 ([8041e410e3](https://github.com/facebook/react-native/commit/8041e410e3b8ea135dc5f08daddd5ceface24439) by [@cipolleschi](https://github.com/cipolleschi)) +- **SectionList:** Loosen SectionList `renderItem` required return type ([12b64b7824](https://github.com/facebook/react-native/commit/12b64b78247f2db929c6d421262bdec1f6402e0b) by [@NickGerleman](https://github.com/NickGerleman)) +- **style:** Fixed `alignItems: 'baseline'` not working correctly on the new architecture ([2932c0f71f](https://github.com/facebook/react-native/commit/2932c0f71f1882607d9e579e5c09db28e131a4c9) by [@j-piasecki](https://github.com/j-piasecki)) +- **style:** Linear gradient color stop spec. ([1a49892d57](https://github.com/facebook/react-native/commit/1a49892d574e3b77a75df8cfc77307a7d5daab35) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway)) +- **TextInput:** Fixed fontWeight number value error for text optimized ([2a230694c4](https://github.com/facebook/react-native/commit/2a230694c421bf338699506a0044c26fd4c1eb55) by [@meetdhanani17](https://github.com/meetdhanani17)) +- **typescript:** Allow read only array type for transform property ([c16defaff2](https://github.com/facebook/react-native/commit/c16defaff2964a2b30656def35eb3450cff9cd71) by [@tjzel](https://github.com/tjzel)) +- **typescript:** Add missing `submitBehavior` prop and mark `blurOnSubmit` prop as deprecated in Typescript declaration file of `TextInput` ([1dcbf41725](https://github.com/facebook/react-native/commit/1dcbf41725a7296c0a0f33c4e0cc3a11e8780889) by [@thisisgit](https://github.com/thisisgit)) + +#### Android specific + +- **Animated:** Fix scheduled animated operations not being executed in some cases ([dc8c8ebc5b](https://github.com/facebook/react-native/commit/dc8c8ebc5b7b6315b3c8e79028a80611a796ea7e) by [@j-piasecki](https://github.com/j-piasecki)) +- **Animated** Sync the Shadow Tree and the Native Tree with Native animation when scroll is driving the animation ([394aae1c1c](https://github.com/facebook/react-native/commit/394aae1c1cc354eaefb762455e2bbeeec0503038) by [@cipolleschi](https://github.com/cipolleschi)) +- **Appearance:** Ensure Appearance change listener does not skip events ([7041ed28f0](https://github.com/facebook/react-native/commit/7041ed28f092e7c6c1dac35f0ce6af095cd9a072) by [@vonovak](https://github.com/vonovak)) +- **DevMenu:** Add missing Android implementation for DevMenu Module ([1bdae07d89](https://github.com/facebook/react-native/commit/1bdae07d89fdda486d3f9dbcc4aa5cbb026fc8b6) by [@cortinico](https://github.com/cortinico)) +- **devtools** Fix issue with `NativeDevSettings.setIsDebuggingRemotely` where the app would keep on restarting if remote debugging was invoked from an action / component that was called on app start. ([beebf4a0a3](https://github.com/facebook/react-native/commit/beebf4a0a36c4ee9dc52631afdf2b25745a1b0f2) by [@Sushant-Sardeshpande](https://github.com/Sushant-Sardeshpande)) +- **Image** Make Imagesource `open` for inheritance ([0e805a953d](https://github.com/facebook/react-native/commit/0e805a953d8c2e91790a2f9fa2da7850478231b7) by [@cortinico](https://github.com/cortinico)) +- **Image** Fix ReactImageView.hasOverlappingRendering() ([2bed2ab1a6](https://github.com/facebook/react-native/commit/2bed2ab1a658230cb6fa23fdcb4e5a962f496e18) by [@NickGerleman](https://github.com/NickGerleman)) +- **infra:** Expose `react_timing` headers in `reactnative` prefab ([b1d42c8ef2](https://github.com/facebook/react-native/commit/b1d42c8ef2eb54af48ad27d3dc121e15c07d3dba) by [@tomekzaw](https://github.com/tomekzaw)) +- **infra:** RNGP - Sanitize the output of the config command ([d7884a6bb8](https://github.com/facebook/react-native/commit/d7884a6bb8f2d8fd08dfd7d2817a4fc25f61a57c) by [@cortinico](https://github.com/cortinico)) +- **infra** Fix NPE in FileReaderModule ([fd4531fe23](https://github.com/facebook/react-native/commit/fd4531fe234149f4f078a1e73ec68145f9da20b3) by [@cortinico](https://github.com/cortinico)) +- **infra** Properly set `REACTNATIVE_MERGED_SO` for autolinked libraries ([c005609b01](https://github.com/facebook/react-native/commit/c005609b0155223f3ae778c5cd96bc78c4dfe399) by [@cortinico](https://github.com/cortinico)) +- **logging** Fix LogModule to create view when show is called ([0847384a45](https://github.com/facebook/react-native/commit/0847384a4598d9bbc8987788047bc58d7596881d) by [@fannnzhang](https://github.com/fannnzhang)) +- **Modal**: Deprecating ModalHostShadowNode and ModalHostHelper classes ([77b3a8bdd6](https://github.com/facebook/react-native/commit/77b3a8bdd6164b4c2407e53cb0e27075c3ea7213) by [@alanleedev](https://github.com/alanleedev)) +- **Modal** PointerEvents from Modal would not be dispatched correctly in new architecture. ([75114e3672](https://github.com/facebook/react-native/commit/75114e36726979625674b2c75a77ac330fccc4d6) by [@javache](https://github.com/javache)) +- **networking** Fix uploading GIF URI ([48669af562](https://github.com/facebook/react-native/commit/48669af562d6d3ed7835816d60a2fb400a22a19b) by [@s77rt](https://github.com/s77rt)) +- **RedBox:** RedBox content overlapping with system bars on Android 15 forced edge-to-edge ([97b661c3f0](https://github.com/facebook/react-native/commit/97b661c3f07ab0269b707b209139d5c1648d1e03) by [@alanleedev](https://github.com/alanleedev)) +- **renderer** Fixed black strip coming when hiding status bar ([f6b6d001a0](https://github.com/facebook/react-native/commit/f6b6d001a0e0241a9d637cd5e532f0d8610d9ee1) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) +- **renderer** Fix Android removeClippedSubviews in RTL ([ea6928fcb9](https://github.com/facebook/react-native/commit/ea6928fcb95c19e84f8f2851f28d0cd4343c6a26) by [@NickGerleman](https://github.com/NickGerleman)) +- **runtime:** Fix Headless Crash `Tried to finish non-existent task with id` ([b4532adad4](https://github.com/facebook/react-native/commit/b4532adad4e38e1237631778f7b8c917a9ccf746) by [@RodolfoGS](https://github.com/RodolfoGS)) +- **runtime** Optimize BaseViewManager#setTransform to ignore duplicate values ([3df0f3b9ff](https://github.com/facebook/react-native/commit/3df0f3b9ff4cc9cd6846ef02101baf8e9605d6a0) by [@javache](https://github.com/javache)) +- **runtime** Make getUri and isResource open ([8c81ffa60a](https://github.com/facebook/react-native/commit/8c81ffa60a211e4ae7db50cd04de0e4a4c29df04) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) +- **runtime** Do not destroy views when there is a touch going on for New Architecture ([6b7f68240e](https://github.com/facebook/react-native/commit/6b7f68240e08c64ced29ed3d7a1f95db96a6eef4) by [@cortinico](https://github.com/cortinico)) +- **runtime** Annotate ReactRootView.createRootView with nullable ([6a1ecbb2bb](https://github.com/facebook/react-native/commit/6a1ecbb2bb3942e7487532262f2a4fc55f94fcad) by [@shwanton](https://github.com/shwanton)) +- **runtime** Made several methods in ReactNativeHost.java thread-safe to avoid race conditions ([f9ac5b737a](https://github.com/facebook/react-native/commit/f9ac5b737a0e14c76f35840efcf348f1c7704363) by Jack Su) +- **runtime** Fixed Headless JS tasks in New Architecture ([9a1ae97c22](https://github.com/facebook/react-native/commit/9a1ae97c22868a312000f3ac50dacf9a8125d273) by [@robik](https://github.com/robik)) +- **runtime** Fix default for `showsHorizontalScrollIndicator` and `showsVerticalScrollIndicator` ([3af01a8a44](https://github.com/facebook/react-native/commit/3af01a8a44853246d3deb957c4a1c65e43848bb5) by [@NickGerleman](https://github.com/NickGerleman)) +- **runtime:** Adds a null check in react context getter ([aeb020dfa3](https://github.com/facebook/react-native/commit/aeb020dfa34d06b63fa0151be302287d0a3fb84f) by Peter Abbondanzo) +- **runtime** Fix ReactFragment on New Architecture ([52322fbd0e](https://github.com/facebook/react-native/commit/52322fbd0e641726b224b2b9b89d99d93dbc6e33) by [@cortinico](https://github.com/cortinico)) +- **style** Don't use mGapBetweenPaths if not drawing a border ([8501b6396b](https://github.com/facebook/react-native/commit/8501b6396b0a4fd7a9bd2add2b3c8b9c755c27ae) by [@knappam](https://github.com/knappam)) +- **style** Linear gradient border styles ([20e3f4518f](https://github.com/facebook/react-native/commit/20e3f4518feac70e8ac9b1cc4fc1cbb029df96e4) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway)) +- **style** Gracefully handle unexpected overflow values ([82094dd9e3](https://github.com/facebook/react-native/commit/82094dd9e33d94f65fd2548f5b04a19fb89bad0f) by [@NickGerleman](https://github.com/NickGerleman)) +- **style** Fix "setTranslucentBackgroundDrawable()" deprecation version ([35d9a18b81](https://github.com/facebook/react-native/commit/35d9a18b81ff9448459c9fb033f4fea1fa17dab3) by [@NickGerleman](https://github.com/NickGerleman)) +- **style:** Add missing invalidate() to setOverflow() ([087193c98e](https://github.com/facebook/react-native/commit/087193c98ead8f12ec4f839dd077d5bd63075d6f) by [@NickGerleman](https://github.com/NickGerleman)) +- **style:** Add borderStartWidth and borderEndWidth support ([92dca53702](https://github.com/facebook/react-native/commit/92dca5370239f2c9881455b683ff384e2187430f) by [@NickGerleman](https://github.com/NickGerleman)) +- **style** Fixed text shadow rendering with artifacts when `backgroundColor` was set on the `TextInput` ([83716298f8](https://github.com/facebook/react-native/commit/83716298f8dd6a1f3128965225858b4c6d3b2477) by [@j-piasecki](https://github.com/j-piasecki)) +- **Text** Fix measuring text with incorrect hyphenationFrequency ([fc8224036b](https://github.com/facebook/react-native/commit/fc8224036b4b5880c881f471e432ee5b47113b0b) by [@NickGerleman](https://github.com/NickGerleman)) +- **TextInput:** fixed select text on auto focus for TextInput ([18d6028ff9](https://github.com/facebook/react-native/commit/18d6028ff908eef99aae363d8ee9a6789d264284) by [@kunalchavhan](https://github.com/kunalchavhan)) +- **TextInput** TextInput's `contextMenuHidden` prop bug fix ([8a3ffb6d23](https://github.com/facebook/react-native/commit/8a3ffb6d23f169752891eddc7dad9e34cb2d861c) by [@alanleedev](https://github.com/alanleedev)) + +#### iOS specific + +- **devtools** Fix position of RCTPerfMonitor in landscape mode & expanded mode ([258f41a30f](https://github.com/facebook/react-native/commit/258f41a30f5a797c0cfdb256a6824b7284dcc8e2) by [@krozniata](https://github.com/krozniata)) +- **Appearance** Fixes Appearance user interface style when app run from background ([efa9711e35](https://github.com/facebook/react-native/commit/efa9711e35f528245cdfb6c7028129c97ae10192) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **c++** Fixes NSDataBigString length calculation ([bb3c51dc84](https://github.com/facebook/react-native/commit/bb3c51dc84e9514f55ca8a1e3abb1af140563c7b) by Tzvetan Mikov) +- **codegen** Codegen will start looking for codegen-enabled dependencies from the project root. ([46d17efa62](https://github.com/facebook/react-native/commit/46d17efa626cd546e839648e1a95f43a3802051c) by [@dmytrorykun](https://github.com/dmytrorykun)) +- **Hermes**: Exclude dSYM from the archive ([7e14ec5177f](https://github.com/facebook/react-native/commit/7e14ec5177fd17ca9f1db384026b26ae90ab0b00) by [@cipolleschi](https://github.com/cipolleschi)) +- **Image** Fixes race condition when setup image loader ([6b104bbe01](https://github.com/facebook/react-native/commit/6b104bbe015c93a40a73232fdb92a99e3799b7ac) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **Image** Fixed crash in RCTImageUtils ([3572ef3f1b](https://github.com/facebook/react-native/commit/3572ef3f1b5b11c1ecfa21f0246cbba5941bbe0f) by [@pavelgurkovskiy](https://github.com/pavelgurkovskiy)) +- **Image** Data race in `RCTImageLoader` related to assignment of cancellation block. ([0f051f6034](https://github.com/facebook/react-native/commit/0f051f603492f97a85e051f112d96180352bba77) by [@hakonk](https://github.com/hakonk)) +- **Image** Fixes Image load event in new arch ([7698cd0953](https://github.com/facebook/react-native/commit/7698cd09536ebf99c3b56696a7bb75d714abfb18) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **infra** Add back the BUNDLE_COMMAND ([cf42288181](https://github.com/facebook/react-native/commit/cf422881819decccdd2b486fbb73f2192b9ec522) by [@Vin-Xi](https://github.com/Vin-Xi)) +- **infra** Resolve Hermes prebuilt version based on react-native package ([b10ed0e19d](https://github.com/facebook/react-native/commit/b10ed0e19d8eec388305962667561e0cb95a3f25) by [@okwasniewski](https://github.com/okwasniewski)) +- **infra** Support bundle install from outside the ios folder using --project-directory ([b22970e3cf](https://github.com/facebook/react-native/commit/b22970e3cfbe603bffea5b1c3bbf150887e3d7b8) by [@blakef](https://github.com/blakef)) +- **infra** Use CONFIG_CMD if set ([774fe0cf6f](https://github.com/facebook/react-native/commit/774fe0cf6f22f832b756c166599973d9db6a93de) by [@krystofwoldrich](https://github.com/krystofwoldrich)) +- **infra** Fixes FORCE_BUNDLING error when bundle js ([089e8289ba](https://github.com/facebook/react-native/commit/089e8289ba6cba0821b76207a2dce316b1621c3d) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **Modal** App crash happening when navigate to a new app screen with a displaying modal ([52888c0c1e](https://github.com/facebook/react-native/commit/52888c0c1e722a799f233c2f502e01b9dd4a7174) by Zhi Zhou) +- **Networking:** Fix: on iOS not getting 304 from `If-None-Match` request ([b8ab0fe703](https://github.com/facebook/react-native/commit/b8ab0fe703f1a0aca796bc15641d029a2036105f) by [@huzhanbo1996](https://github.com/huzhanbo1996)) +- **Networking** Fix data race related to access on `RCTNetworkTask.status`. ([b1ec698dc4](https://github.com/facebook/react-native/commit/b1ec698dc4baf34ba2e31b7ad43dff97c229bf99) by [@hakonk](https://github.com/hakonk)) +- **RedBox** Mac Catalyst crash in RCTRedBox ([84fe531952](https://github.com/facebook/react-native/commit/84fe531952d4b97c3cb0d84322abdf8953382ad6) by [@sbuggay](https://github.com/sbuggay)) +- **RedBox** Fix rendering `RCTRedBoxExtraData` ([c9d589dab5](https://github.com/facebook/react-native/commit/c9d589dab5148cbd192078967f743d38b8048c6e) by [@krozniata](https://github.com/krozniata)) +- **rendering:** Properly retain/release backgroundColor in RCTBorderDrawing ([47748c7935](https://github.com/facebook/react-native/commit/47748c7935540014abed03b4d2ff809b471c4fe3) by [@Saadnajmi](https://github.com/Saadnajmi)) +- **RefreshControl:** Fixed an issue where the refresh control would not behave correctly if it was offscreen. ([a8be335a37](https://github.com/facebook/react-native/commit/a8be335a37eb792a7c6ccb7f577459020a2fc43c) by [@deepanshushuklad11](https://github.com/deepanshushuklad11)) +- **RefreshControl:** Fix applying of tintColor and progressViewOffset props for RefreshControl component with New Architecture enabled ([19d468fed9](https://github.com/facebook/react-native/commit/19d468fed966f2adb973ad3f19a97a5ec0372e3a) by [@TuTejsy](https://github.com/TuTejsy)) +- **RefreshControl:** Passed correct title and titleColor prop to updateTitle function ([5c7a166dca](https://github.com/facebook/react-native/commit/5c7a166dcaf5400fbc4c12d4c8b451228157c036) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) +- **runtime** Fixed a crash when navigating away from a screen that contains a scrollView ([c6f32828b9](https://github.com/facebook/react-native/commit/c6f32828b9487381dab27f645aedcdbae9dcbc7e) by [@cipolleschi](https://github.com/cipolleschi)) +- **runtime** Data race related to read/write on `ReactMarker::logTaggedMarkerImpl` ([7e41ea4c9d](https://github.com/facebook/react-native/commit/7e41ea4c9de943a5c73ca9821bf552d39aa49dcd) by [@hakonk](https://github.com/hakonk)) +- **runtime** Fixes typo of function callFunctionOnBufferedRumtimeExecutor ([4e12c2e37c](https://github.com/facebook/react-native/commit/4e12c2e37cb168f09f8768941cb915e4024a1c34) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **runtime** Fixes main thread stuck when reload in bridgeless mode ([a778979ed6](https://github.com/facebook/react-native/commit/a778979ed604d1dc7707faf4a3836e3deba136c6) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **runtime** Fixing maxLength check which was firing onChange multiple times ([d88dd14507](https://github.com/facebook/react-native/commit/d88dd145074ee84de0cc4207de02a3cd79c9ceff) by [@deepanshushuklad11](https://github.com/deepanshushuklad11)) +- **runtime** Use std::atomic for eliminating races in RCTCxxBridge. ([8204134024](https://github.com/facebook/react-native/commit/8204134024e81947969bd8c2ba337dc931e54bd9) by [@hakonk](https://github.com/hakonk)) +- **runtime** Fix legacy view interop apis not available in view method ([19cffab383](https://github.com/facebook/react-native/commit/19cffab3837c24f2e8470a31bbd8e8338d1c1b6c) by [@janicduplessis](https://github.com/janicduplessis)) +- **ScrollView** Implement automicallyAdjustsKeyboardInsets for new arch ([e4e461c9cf](https://github.com/facebook/react-native/commit/e4e461c9cf969e1a1dfca6448ca6084b7f45ef7d) by [@okwasniewski](https://github.com/okwasniewski)) +- **ScrollView** Implement automicallyAdjustsKeyboardInsets for new arch ([21bdce7286](https://github.com/facebook/react-native/commit/21bdce7286fc493b9601add3bf67d549b792d29b) by [@okwasniewski](https://github.com/okwasniewski)) +- **StatusBarManager** Retrieve status bar size using RCTUIStatusBarManager ([34cd195d9f](https://github.com/facebook/react-native/commit/34cd195d9fbd075a161afbfac842f896355991e1) by [@okwasniewski](https://github.com/okwasniewski)) +- **style** fix: background color fix when border is dotted and dashed ([b243d343fa](https://github.com/facebook/react-native/commit/b243d343fa741de94537d8535f76714ff2985101) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) +- **style** Fixes ellipsis carries background from trimmed text ([9e2f8859c4](https://github.com/facebook/react-native/commit/9e2f8859c4d237ae2bee4679da45038405b7074e) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **Text** Fixed baseline attachment position in multiline text ([9bfbf948df](https://github.com/facebook/react-native/commit/9bfbf948dfd23c891233e747cbaeeb6480f5fa41) by [@j-piasecki](https://github.com/j-piasecki)) +- **Text** Clean up RCTParagraphComponentView & RCTParagraphTextView ([9239ad1c6b](https://github.com/facebook/react-native/commit/9239ad1c6bac2c2400f940708d823d7b2c2457c4) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **Text** Fixes Italic text not work ([9cfd9dd1c7](https://github.com/facebook/react-native/commit/9cfd9dd1c7f8c37c156f1a9ff812183f80d67926) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **Text** Fixes ellipsis carries background from trimmed text ([fcb6cdc710](https://github.com/facebook/react-native/commit/fcb6cdc7108103527268aef42a77e530f9482668) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **Text** Fixed text baseline being moved upwards in certain cases ([01f7ab814f](https://github.com/facebook/react-native/commit/01f7ab814f847eb3038efa7120d81e92e3ff4187) by [@j-piasecki](https://github.com/j-piasecki)) +- **TextInput** Fixes TextInput crash when undo if text longer than maxLength ([9b9c780cc8](https://github.com/facebook/react-native/commit/9b9c780cc8b54e2c1cd61f9fac0554488f68dea8) by [@zhongwuzw](https://github.com/zhongwuzw)) ### Security -- Upgrade grpc/grpc-js from 1.7.0 to 1.10.9 (CVE-2024-37168) ([295626bc35](https://github.com/facebook/react-native/commit/295626bc35326cc68c127ff515dcbb8e9d7d44e3) by [@GijsWeterings](https://github.com/GijsWeterings)) -- Upgrade braces from 3.0.2 to 3.0.3 (CVE-2024-4068) ([d538879e08](https://github.com/facebook/react-native/commit/d538879e08360b8230410fc893a50489bad5cf60) by [@GijsWeterings](https://github.com/GijsWeterings)) -- Update ws from 7.5.1 to 7.5.10 (CVE-2024-37890) ([13f1b9e10f](https://github.com/facebook/react-native/commit/13f1b9e10f6045421808714f7e62aa17bfb3e891) by [@GijsWeterings](https://github.com/GijsWeterings)) -- Update ws from 6.2.2 to 6.2.3 (CVE-2024-37890) ([80cfacef78](https://github.com/facebook/react-native/commit/80cfacef78f34d3786d955084a8bf4d42ea37f1b) by [@GijsWeterings](https://github.com/GijsWeterings)) - -#### Android specific - - - -#### iOS specific - - - -### Unknown - -- Release 0.76.0-rc.0 ([f60fbc15ae](https://github.com/facebook/react-native/commit/f60fbc15ae62d901f52162864b0c5a0f307ca46c) by [@react-native-bot](https://github.com/react-native-bot)) -- Fix wrong command for publishing of external-artifacts ([cf5d04d3e1](https://github.com/facebook/react-native/commit/cf5d04d3e12578be009ab0eb6ecad02d6e2f183b) by [@cortinico](https://github.com/cortinico)) -- Release 0.76.0-rc.0 ([1e3c583d73](https://github.com/facebook/react-native/commit/1e3c583d73d7ee69a17ff35eed3f4ab44f4da414) by [@react-native-bot](https://github.com/react-native-bot)) -- Properly make ScrollView compatible with React19 ([b395208303](https://github.com/facebook/react-native/commit/b39520830341cae8c3785250cbaf2ec99958ba69) by [@cipolleschi](https://github.com/cipolleschi)) -- Make ScrollView compatible with React 18.3.1 ([8041e410e3](https://github.com/facebook/react-native/commit/8041e410e3b8ea135dc5f08daddd5ceface24439) by [@cipolleschi](https://github.com/cipolleschi)) -- Bump hermes version ([f55759e633](https://github.com/facebook/react-native/commit/f55759e633aaa8f5c0f312836b57ed43af2a68ee) by [@cipolleschi](https://github.com/cipolleschi)) -- Add Fusebox support for saving traces to disk ([1bd4a11736](https://github.com/facebook/react-native/commit/1bd4a11736c2916c9114df55395d474a801ee63b) by Benoit Girard) -- Fix using namespace issues in xplat ([194b642633](https://github.com/facebook/react-native/commit/194b642633d944b9e73e55b947284eabd42d55a2) by [@r-barnes](https://github.com/r-barnes)) -- Eliminate a few React.Element type that will be synced to react-native ([39c338ff8d](https://github.com/facebook/react-native/commit/39c338ff8d3a65ec3f7a45f0b8319f70115e2fc1) by [@SamChou19815](https://github.com/SamChou19815)) -- RSD sync ([8f548be91c](https://github.com/facebook/react-native/commit/8f548be91c2e0ac10e61535154b9db19dad7f3b7) by [@necolas](https://github.com/necolas)) -- Replace YogaConstants.UNDEFINED with Float.NaN ([8bd9952eaf](https://github.com/facebook/react-native/commit/8bd9952eaf28fe8feca7490293656caeefe7897e) by Jingbo Yang) -- Increase the buffer size and try kStall to avoid dropping samples ([8a6508c623](https://github.com/facebook/react-native/commit/8a6508c62314a73fd08913cd1d03a98baaa4f1d8) by Benoit Girard) - -#### Android Unknown - -- Fix testing script to use debug versions of the Android APK ([026fd325ab](https://github.com/facebook/react-native/commit/026fd325abd53fbfe37fcdee341202192d2c3fcd) by [@cipolleschi](https://github.com/cipolleschi)) -- GHA: create a reaper job to keep the cache < 10GB ([17cbe7d974](https://github.com/facebook/react-native/commit/17cbe7d9745667798c0bfbb5edd9cbda56607d6f) by [@blakef](https://github.com/blakef)) - -#### iOS Unknown - -- Allow use without @react-native-community/cli-server-api ([24997dc5ae](https://github.com/facebook/react-native/commit/24997dc5ae4ed85d3965cbc6796423f5012e4eb1) by [@blakef](https://github.com/blakef)) - -#### Failed to parse - -- Add E2E test cases for Flat/SectionList to RNTester ([17d0345fdf](https://github.com/facebook/react-native/commit/17d0345fdfe27148900d34cc613836cfcff6b2da) by [@shwanton](https://github.com/shwanton)) -- Bump iOS min version for CI ([b93c2b2412](https://github.com/facebook/react-native/commit/b93c2b241247d0a7d9b79eda76af0a7bca0ac745) by [@realsoelynn](https://github.com/realsoelynn)) -- Bump OSS Build infra to min iOS 15.1 ([d11c99922c](https://github.com/facebook/react-native/commit/d11c99922c0f27c30897615b4cf506c310cb01e9) by [@realsoelynn](https://github.com/realsoelynn)) -- Update RNTester and HelloWorld template app to `min iOS 15.1` ([e1a1cdacf2](https://github.com/facebook/react-native/commit/e1a1cdacf2d210353c06e7ab65f971f6592e8c00) by [@realsoelynn](https://github.com/realsoelynn)) -- Ve[RN][Android] Convert StyleAnimatedNode.java->.kt ([ef9149b4fc](https://github.com/facebook/react-native/commit/ef9149b4fc989827ad4b781fa89f556a1fd20db4) by [@rshest](https://github.com/rshest)) -- Fixes ellipsis carries background from trimmed text ([9e2f8859c4](https://github.com/facebook/react-native/commit/9e2f8859c4d237ae2bee4679da45038405b7074e) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **infra:** Upgrade grpc/grpc-js from 1.7.0 to 1.10.9 (CVE-2024-37168) ([295626bc35](https://github.com/facebook/react-native/commit/295626bc35326cc68c127ff515dcbb8e9d7d44e3) by [@GijsWeterings](https://github.com/GijsWeterings)) +- **infra:** Upgrade braces from 3.0.2 to 3.0.3 (CVE-2024-4068) ([d538879e08](https://github.com/facebook/react-native/commit/d538879e08360b8230410fc893a50489bad5cf60) by [@GijsWeterings](https://github.com/GijsWeterings)) +- **infra:** Update ws from 7.5.1 to 7.5.10 (CVE-2024-37890) ([13f1b9e10f](https://github.com/facebook/react-native/commit/13f1b9e10f6045421808714f7e62aa17bfb3e891) by [@GijsWeterings](https://github.com/GijsWeterings)) +- **infra:** Update ws from 6.2.2 to 6.2.3 (CVE-2024-37890) ([80cfacef78](https://github.com/facebook/react-native/commit/80cfacef78f34d3786d955084a8bf4d42ea37f1b) by [@GijsWeterings](https://github.com/GijsWeterings)) ## v0.75.4 diff --git a/jest/preprocessor.js b/jest/preprocessor.js index c9591220759070..22b3ab40c87cbe 100644 --- a/jest/preprocessor.js +++ b/jest/preprocessor.js @@ -12,16 +12,16 @@ 'use strict'; -const metroBabelRegister = require('metro-babel-register'); -const nullthrows = require('nullthrows'); -const createCacheKeyFunction = - require('@jest/create-cache-key-function').default; - +// eslint-disable-next-line lint/sort-imports const { - transformSync: babelTransformSync, transformFromAstSync: babelTransformFromAstSync, + transformSync: babelTransformSync, } = require('@babel/core'); const generate = require('@babel/generator').default; +const createCacheKeyFunction = + require('@jest/create-cache-key-function').default; +const metroBabelRegister = require('metro-babel-register'); +const nullthrows = require('nullthrows'); if (process.env.FBSOURCE_ENV === '1') { // If we're running in the Meta-internal monorepo, use the central Babel diff --git a/package.json b/package.json index 61402e78e7b3c7..272657946e286a 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "private": true, "version": "1000.0.0", "license": "MIT", + "packageManager": "yarn@1.22.22", "scripts": { "android": "cd packages/rn-tester && npm run android", "build-android": "./gradlew :packages:react-native:ReactAndroid:build", @@ -77,7 +78,7 @@ "eslint-plugin-redundant-undefined": "^0.4.0", "eslint-plugin-relay": "^1.8.3", "flow-api-translator": "0.24.0", - "flow-bin": "^0.249.0", + "flow-bin": "^0.250.0", "glob": "^7.1.1", "hermes-eslint": "0.24.0", "hermes-transform": "0.24.0", diff --git a/packages/babel-plugin-codegen/index.js b/packages/babel-plugin-codegen/index.js index 6dc382c4d2258f..494688379d3cfb 100644 --- a/packages/babel-plugin-codegen/index.js +++ b/packages/babel-plugin-codegen/index.js @@ -11,8 +11,8 @@ let FlowParser, TypeScriptParser, RNCodegen; -const {basename} = require('path'); const {cheap: traverseCheap} = require('@babel/traverse').default; +const {basename} = require('path'); try { FlowParser = diff --git a/packages/debugger-frontend/BUILD_INFO b/packages/debugger-frontend/BUILD_INFO index 785ca7a3628124..50211110ee2778 100644 --- a/packages/debugger-frontend/BUILD_INFO +++ b/packages/debugger-frontend/BUILD_INFO @@ -1,5 +1,5 @@ -@generated SignedSource<> -Git revision: a897db88e79f5369ed844bccb48f03c43d61d070 +@generated SignedSource<> +Git revision: ff343d805527223750fafb8573ee48f8e2fb0d1e Built with --nohooks: false Is local checkout: false Remote URL: https://github.com/facebookexperimental/rn-chrome-devtools-frontend diff --git a/packages/debugger-frontend/dist/third-party/front_end/models/react_native/react_native.js b/packages/debugger-frontend/dist/third-party/front_end/models/react_native/react_native.js index 8fa74fd43d4c28..c9393af699b189 100644 --- a/packages/debugger-frontend/dist/third-party/front_end/models/react_native/react_native.js +++ b/packages/debugger-frontend/dist/third-party/front_end/models/react_native/react_native.js @@ -1 +1 @@ -import*as e from"../../core/sdk/sdk.js";const t="main",i="__FUSEBOX_REACT_DEVTOOLS_DISPATCHER__";class n extends e.SDKModel.SDKModel{domainToListeners=new Map;messagingBindingName=null;enabled=!1;fuseboxDispatcherIsInitialized=!1;domainToMessageQueue=new Map;dispose(){this.domainToListeners.clear(),this.domainToMessageQueue.clear();const t=this.target().model(e.RuntimeModel.RuntimeModel);t?.removeEventListener(e.RuntimeModel.Events.BindingCalled,this.bindingCalled,this),t?.removeEventListener(e.RuntimeModel.Events.ExecutionContextCreated,this.onExecutionContextCreated,this),t?.removeEventListener(e.RuntimeModel.Events.ExecutionContextDestroyed,this.onExecutionContextDestroyed,this)}bindingCalled(e){if(null===this.messagingBindingName||e.data.name!==this.messagingBindingName)return;const t=e.data.payload;let i=null;try{i=JSON.parse(t)}catch(e){throw new Error("Failed to parse bindingCalled event payload",{cause:e})}if(i){const e=i.domain;if(this.fuseboxDispatcherIsInitialized){if(!this.isDomainMessagesQueueEmpty(e))throw new Error(`Attempted to send a message to domain ${e} while queue is not empty`);this.dispatchMessageToDomainEventListeners(e,i.message)}else this.queueMessageForDomain(e,i.message)}}queueMessageForDomain(e,t){let i=this.domainToMessageQueue.get(e);i||(i=[],this.domainToMessageQueue.set(e,i)),i.push(t)}flushOutDomainMessagesQueues(){for(const[e,t]of this.domainToMessageQueue.entries())if(0!==t.length){for(const i of t)this.dispatchMessageToDomainEventListeners(e,i);t.splice(0,t.length)}}isDomainMessagesQueueEmpty(e){const t=this.domainToMessageQueue.get(e);return void 0===t||0===t.length}subscribeToDomainMessages(e,t){let i=this.domainToListeners.get(e);i||(i=new Set,this.domainToListeners.set(e,i)),i.add(t)}unsubscribeFromDomainMessages(e,t){const i=this.domainToListeners.get(e);i&&i.delete(t)}dispatchMessageToDomainEventListeners(e,t){const i=this.domainToListeners.get(e);if(!i)return;const n=[];for(const e of i)try{e(t)}catch(e){n.push(e)}if(n.length>0)throw new AggregateError(n,`Error occurred in ReactDevToolsBindingsModel while calling event listeners for domain ${e}`)}async initializeDomain(t){const n=this.target().model(e.RuntimeModel.RuntimeModel);if(!n)throw new Error(`Failed to initialize domain ${t} for ReactDevToolsBindingsModel: runtime model is not available`);await n.agent.invoke_evaluate({expression:`void ${i}.initializeDomain('${t}')`})}async sendMessage(t,n){if(!this.fuseboxDispatcherIsInitialized)return;const o=this.target().model(e.RuntimeModel.RuntimeModel);if(!o)throw new Error(`Failed to send message from ReactDevToolsBindingsModel for domain ${t}: runtime model is not available`);const s=JSON.stringify(n),a=`${i}.sendMessage('${t}', '${s}')`;await o.agent.invoke_evaluate({expression:`void setTimeout(() => ${a}, 0)`})}async enable(){if(this.enabled)throw new Error("ReactDevToolsBindingsModel is already enabled");const t=this.target().model(e.RuntimeModel.RuntimeModel);if(!t)throw new Error("Failed to enable ReactDevToolsBindingsModel: runtime model is not available");await this.waitForFuseboxDispatcherToBeInitialized().then((()=>t.agent.invoke_evaluate({expression:`${i}.BINDING_NAME`}))).then((e=>{if(e.exceptionDetails)throw new Error("Failed to get binding name for ReactDevToolsBindingsModel on a global: "+e.exceptionDetails.text);if(null===e.result.value||void 0===e.result.value)throw new Error("Failed to get binding name for ReactDevToolsBindingsModel on a global: returned value is "+String(e.result.value));if(""===e.result.value)throw new Error("Failed to get binding name for ReactDevToolsBindingsModel on a global: returned value is an empty string");return e.result.value})).then((i=>(this.messagingBindingName=i,t.addEventListener(e.RuntimeModel.Events.BindingCalled,this.bindingCalled,this),t.agent.invoke_addBinding({name:i})))).then((e=>{const t=e.getError();if(t)throw new Error("Failed to add binding for ReactDevToolsBindingsModel: "+t);this.enabled=!0,this.initializeExecutionContextListeners()}))}isEnabled(){return this.enabled}initializeExecutionContextListeners(){const t=this.target().model(e.RuntimeModel.RuntimeModel);if(!t)throw new Error("Failed to initialize execution context listeners for ReactDevToolsBindingsModel: runtime model is not available");t.addEventListener(e.RuntimeModel.Events.ExecutionContextCreated,this.onExecutionContextCreated,this),t.addEventListener(e.RuntimeModel.Events.ExecutionContextDestroyed,this.onExecutionContextDestroyed,this)}onExecutionContextCreated({data:e}){e.name===t&&this.waitForFuseboxDispatcherToBeInitialized().then((()=>{this.dispatchEventToListeners("BackendExecutionContextCreated"),this.flushOutDomainMessagesQueues()})).catch((e=>this.dispatchEventToListeners("BackendExecutionContextUnavailable",e.message)))}onExecutionContextDestroyed({data:e}){e.name===t&&(this.fuseboxDispatcherIsInitialized=!1,this.dispatchEventToListeners("BackendExecutionContextDestroyed"))}async waitForFuseboxDispatcherToBeInitialized(t=1){if(t>=20)throw new Error("Failed to wait for initialization: it took too long");const n=this.target().model(e.RuntimeModel.RuntimeModel);if(!n)throw new Error("Failed to wait for React DevTools dispatcher initialization: runtime model is not available");await n.agent.invoke_evaluate({expression:`globalThis.${i} != undefined`,returnByValue:!0}).then((e=>{if(e.exceptionDetails)throw new Error("Failed to wait for React DevTools dispatcher initialization: "+e.exceptionDetails.text);if(!1===e.result.value)return new Promise((e=>setTimeout(e,250))).then((()=>this.waitForFuseboxDispatcherToBeInitialized(t+1)));this.fuseboxDispatcherIsInitialized=!0}))}}e.SDKModel.SDKModel.register(n,{capabilities:4,autostart:!1});var o=Object.freeze({__proto__:null,ReactDevToolsBindingsModel:n});export{o as ReactDevToolsBindingsModel}; +import*as e from"../../core/sdk/sdk.js";const t="main",i="__FUSEBOX_REACT_DEVTOOLS_DISPATCHER__";class n extends e.SDKModel.SDKModel{domainToListeners=new Map;messagingBindingName=null;enabled=!1;fuseboxDispatcherIsInitialized=!1;domainToMessageQueue=new Map;dispose(){this.domainToListeners.clear(),this.domainToMessageQueue.clear();const t=this.target().model(e.RuntimeModel.RuntimeModel);t?.removeEventListener(e.RuntimeModel.Events.BindingCalled,this.bindingCalled,this),t?.removeEventListener(e.RuntimeModel.Events.ExecutionContextCreated,this.onExecutionContextCreated,this),t?.removeEventListener(e.RuntimeModel.Events.ExecutionContextDestroyed,this.onExecutionContextDestroyed,this)}bindingCalled(e){if(null===this.messagingBindingName||e.data.name!==this.messagingBindingName)return;const t=e.data.payload;let i=null;try{i=JSON.parse(t)}catch(e){throw new Error("Failed to parse bindingCalled event payload",{cause:e})}if(i){const e=i.domain;if(this.fuseboxDispatcherIsInitialized){if(!this.isDomainMessagesQueueEmpty(e))throw new Error(`Attempted to send a message to domain ${e} while queue is not empty`);this.dispatchMessageToDomainEventListeners(e,i.message)}else this.queueMessageForDomain(e,i.message)}}queueMessageForDomain(e,t){let i=this.domainToMessageQueue.get(e);i||(i=[],this.domainToMessageQueue.set(e,i)),i.push(t)}flushOutDomainMessagesQueues(){for(const[e,t]of this.domainToMessageQueue.entries())if(0!==t.length){for(const i of t)this.dispatchMessageToDomainEventListeners(e,i);t.splice(0,t.length)}}isDomainMessagesQueueEmpty(e){const t=this.domainToMessageQueue.get(e);return void 0===t||0===t.length}subscribeToDomainMessages(e,t){let i=this.domainToListeners.get(e);i||(i=new Set,this.domainToListeners.set(e,i)),i.add(t)}unsubscribeFromDomainMessages(e,t){const i=this.domainToListeners.get(e);i&&i.delete(t)}dispatchMessageToDomainEventListeners(e,t){const i=this.domainToListeners.get(e);if(!i)return;const n=[];for(const e of i)try{e(t)}catch(e){n.push(e)}if(n.length>0)throw new AggregateError(n,`Error occurred in ReactDevToolsBindingsModel while calling event listeners for domain ${e}`)}async initializeDomain(t){const n=this.target().model(e.RuntimeModel.RuntimeModel);if(!n)throw new Error(`Failed to initialize domain ${t} for ReactDevToolsBindingsModel: runtime model is not available`);await n.agent.invoke_evaluate({expression:`void ${i}.initializeDomain('${t}')`})}async sendMessage(t,n){if(!this.fuseboxDispatcherIsInitialized)return;const o=this.target().model(e.RuntimeModel.RuntimeModel);if(!o)throw new Error(`Failed to send message from ReactDevToolsBindingsModel for domain ${t}: runtime model is not available`);const s=JSON.stringify(n);await o.agent.invoke_evaluate({expression:`${i}.sendMessage('${t}', '${s}')`})}async enable(){if(this.enabled)throw new Error("ReactDevToolsBindingsModel is already enabled");const t=this.target().model(e.RuntimeModel.RuntimeModel);if(!t)throw new Error("Failed to enable ReactDevToolsBindingsModel: runtime model is not available");await this.waitForFuseboxDispatcherToBeInitialized().then((()=>t.agent.invoke_evaluate({expression:`${i}.BINDING_NAME`}))).then((e=>{if(e.exceptionDetails)throw new Error("Failed to get binding name for ReactDevToolsBindingsModel on a global: "+e.exceptionDetails.text);if(null===e.result.value||void 0===e.result.value)throw new Error("Failed to get binding name for ReactDevToolsBindingsModel on a global: returned value is "+String(e.result.value));if(""===e.result.value)throw new Error("Failed to get binding name for ReactDevToolsBindingsModel on a global: returned value is an empty string");return e.result.value})).then((i=>(this.messagingBindingName=i,t.addEventListener(e.RuntimeModel.Events.BindingCalled,this.bindingCalled,this),t.agent.invoke_addBinding({name:i})))).then((e=>{const t=e.getError();if(t)throw new Error("Failed to add binding for ReactDevToolsBindingsModel: "+t);this.enabled=!0,this.initializeExecutionContextListeners()}))}isEnabled(){return this.enabled}initializeExecutionContextListeners(){const t=this.target().model(e.RuntimeModel.RuntimeModel);if(!t)throw new Error("Failed to initialize execution context listeners for ReactDevToolsBindingsModel: runtime model is not available");t.addEventListener(e.RuntimeModel.Events.ExecutionContextCreated,this.onExecutionContextCreated,this),t.addEventListener(e.RuntimeModel.Events.ExecutionContextDestroyed,this.onExecutionContextDestroyed,this)}onExecutionContextCreated({data:e}){e.name===t&&this.waitForFuseboxDispatcherToBeInitialized().then((()=>{this.dispatchEventToListeners("BackendExecutionContextCreated"),this.flushOutDomainMessagesQueues()})).catch((e=>this.dispatchEventToListeners("BackendExecutionContextUnavailable",e.message)))}onExecutionContextDestroyed({data:e}){e.name===t&&(this.fuseboxDispatcherIsInitialized=!1,this.dispatchEventToListeners("BackendExecutionContextDestroyed"))}async waitForFuseboxDispatcherToBeInitialized(t=1){if(t>=20)throw new Error("Failed to wait for initialization: it took too long");const n=this.target().model(e.RuntimeModel.RuntimeModel);if(!n)throw new Error("Failed to wait for React DevTools dispatcher initialization: runtime model is not available");await n.agent.invoke_evaluate({expression:`globalThis.${i} != undefined`,returnByValue:!0}).then((e=>{if(e.exceptionDetails)throw new Error("Failed to wait for React DevTools dispatcher initialization: "+e.exceptionDetails.text);if(!1===e.result.value)return new Promise((e=>setTimeout(e,250))).then((()=>this.waitForFuseboxDispatcherToBeInitialized(t+1)));this.fuseboxDispatcherIsInitialized=!0}))}}e.SDKModel.SDKModel.register(n,{capabilities:4,autostart:!1});var o=Object.freeze({__proto__:null,ReactDevToolsBindingsModel:n});export{o as ReactDevToolsBindingsModel}; diff --git a/packages/debugger-frontend/dist/third-party/front_end/panels/react_devtools/react_devtools.js b/packages/debugger-frontend/dist/third-party/front_end/panels/react_devtools/react_devtools.js index fd4c555bda5f5d..f04ddcb6978731 100644 --- a/packages/debugger-frontend/dist/third-party/front_end/panels/react_devtools/react_devtools.js +++ b/packages/debugger-frontend/dist/third-party/front_end/panels/react_devtools/react_devtools.js @@ -1 +1 @@ -import*as e from"../../core/i18n/i18n.js";import*as t from"../../ui/legacy/legacy.js";import*as i from"../../core/sdk/sdk.js";import*as n from"../../third_party/react-devtools/react-devtools.js";import*as o from"../../core/common/common.js";import*as s from"../../models/workspace/workspace.js";import*as r from"../../models/bindings/bindings.js";import*as a from"../../models/logs/logs.js";import*as l from"../../core/host/host.js";import*as d from"../../models/react_native/react_native.js";class c extends i.SDKModel.SDKModel{static FUSEBOX_BINDING_NAMESPACE="react-devtools";#e;#t;#i=new Set;#n=!1;#o=!1;#s=null;#r=null;constructor(e){super(e),this.#e={listen:e=>(this.#i.add(e),()=>{this.#i.delete(e)}),send:(e,t)=>{this.#a({event:e,payload:t})}};const t=e.model(d.ReactDevToolsBindingsModel.ReactDevToolsBindingsModel);if(null===t)throw new Error("Failed to construct ReactDevToolsModel: ReactDevToolsBindingsModel was null");this.#t=t,t.addEventListener("BackendExecutionContextCreated",this.#l,this),t.addEventListener("BackendExecutionContextUnavailable",this.#d,this),t.addEventListener("BackendExecutionContextDestroyed",this.#c,this),window.addEventListener("beforeunload",this.#h)}dispose(){this.#s?.removeListener("reloadAppForProfiling",this.#u),this.#s?.shutdown(),this.#t.removeEventListener("BackendExecutionContextCreated",this.#l,this),this.#t.removeEventListener("BackendExecutionContextUnavailable",this.#d,this),this.#t.removeEventListener("BackendExecutionContextDestroyed",this.#c,this),window.removeEventListener("beforeunload",this.#h),this.#s=null,this.#r=null,this.#i.clear()}ensureInitialized(){this.#n||(this.#n=!0,this.#m())}async#m(){try{const e=this.#t;await e.enable(),e.subscribeToDomainMessages(c.FUSEBOX_BINDING_NAMESPACE,(e=>this.#g(e))),await e.initializeDomain(c.FUSEBOX_BINDING_NAMESPACE),this.#o=!0,this.#p()}catch(e){this.dispatchEventToListeners("InitializationFailed",e.message)}}isInitialized(){return this.#o}getBridgeOrThrow(){if(null===this.#s)throw new Error("Failed to get bridge from ReactDevToolsModel: bridge was null");return this.#s}getStoreOrThrow(){if(null===this.#r)throw new Error("Failed to get store from ReactDevToolsModel: store was null");return this.#r}#g(e){if(e)for(const t of this.#i)t(e)}async#a(e){const t=this.#t;if(!t)throw new Error("Failed to send message from ReactDevToolsModel: ReactDevToolsBindingsModel was null");return t.sendMessage(c.FUSEBOX_BINDING_NAMESPACE,e)}#h=()=>{this.#s?.shutdown()};#l(){const e=this.#t;if(!e)throw new Error("ReactDevToolsModel failed to handle BackendExecutionContextCreated event: ReactDevToolsBindingsModel was null");e.isEnabled()?this.#p():this.ensureInitialized()}#p(){this.#s=n.createBridge(this.#e),this.#r=n.createStore(this.#s,{supportsReloadAndProfile:!0}),this.#s.addListener("reloadAppForProfiling",this.#u),this.dispatchEventToListeners("InitializationCompleted")}#u(){i.ResourceTreeModel.ResourceTreeModel.reloadAllPages(!1)}#d({data:e}){this.dispatchEventToListeners("InitializationFailed",e)}#c(){this.#s?.shutdown(),this.#s=null,this.#r=null,this.#i.clear(),this.dispatchEventToListeners("Destroyed")}}i.SDKModel.SDKModel.register(c,{capabilities:4,autostart:!1});var h=Object.freeze({__proto__:null,ReactDevToolsModel:c});const u={sendFeedback:"[FB-only] Send feedback"},m=e.i18n.registerUIStrings("panels/react_devtools/ReactDevToolsViewBase.ts",u),g=e.i18n.getLocalizedString.bind(void 0,m);function p(e,t){const{sourceURL:i,line:n,column:l}=t||e;!async function(e,t,i){const n=s.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(e);if(n){const e=await r.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().normalizeUILocation(n.uiLocation(t,i));return void o.Revealer.reveal(e)}const l=r.ResourceUtils.resourceForURL(e);if(l)return void o.Revealer.reveal(l);const d=a.NetworkLog.NetworkLog.instance().requestForURL(e);if(!d)throw new Error("Could not find resource for "+e);o.Revealer.reveal(d)}(i,n-1,l-1)}class v extends t.View.SimpleView{#v;#w=null;constructor(e,t){super(t),this.#v=e,this.#E(),i.TargetManager.TargetManager.instance().observeModels(c,this)}wasShown(){super.wasShown(),this.registerCSSFiles([n.CSS])}modelAdded(e){this.#w=e,e.addEventListener("InitializationCompleted",this.#f,this),e.addEventListener("InitializationFailed",this.#b,this),e.addEventListener("Destroyed",this.#C,this),e.isInitialized()?this.#D():e.ensureInitialized()}modelRemoved(e){e.removeEventListener("InitializationCompleted",this.#f,this),e.removeEventListener("InitializationFailed",this.#b,this),e.removeEventListener("Destroyed",this.#C,this)}#f(){this.#D()}#b({data:e}){this.#B(e)}#C(){this.#E()}#D(){this.#x();const e=this.#w;if(null===e)throw new Error("Attempted to render React DevTools panel, but the model was null");const t=window.matchMedia("(prefers-color-scheme: dark)").matches;("components"===this.#v?n.initializeComponents:n.initializeProfiler)(this.contentElement,{bridge:e.getBridgeOrThrow(),store:e.getStoreOrThrow(),theme:t?"dark":"light",canViewElementSourceFunction:()=>!0,viewElementSourceFunction:p})}#E(){this.#x();const e=document.createElement("div");e.setAttribute("style","display: flex; flex: 1; justify-content: center; align-items: center");const t=document.createElement("span");t.classList.add("spinner"),e.appendChild(t),this.contentElement.appendChild(e)}#B(e){this.#x();const i=document.createElement("div");i.setAttribute("style","display: flex; flex: 1; flex-direction: column; justify-content: center; align-items: center");const n=document.createElement("div");n.setAttribute("style","font-size: 3rem"),n.innerHTML="❗";const o=document.createElement("p");if(o.setAttribute("style","user-select: all"),o.innerHTML=e,i.appendChild(n),i.appendChild(o),this.contentElement.appendChild(i),globalThis.FB_ONLY__reactNativeFeedbackLink){const e=globalThis.FB_ONLY__reactNativeFeedbackLink,n=t.UIUtils.createTextButton(g(u.sendFeedback),(()=>{l.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(e)}),{className:"primary-button",jslogContext:"sendFeedback"});i.appendChild(n)}}#x(){this.contentElement.removeChildren()}}const w={title:"⚛️ Components (React DevTools)"},E=e.i18n.registerUIStrings("panels/react_devtools/ReactDevToolsComponentsView.ts",w),f=e.i18n.getLocalizedString.bind(void 0,E);var b=Object.freeze({__proto__:null,ReactDevToolsComponentsViewImpl:class extends v{constructor(){super("components",f(w.title))}}});const C={title:"⚛️ Profiler (React DevTools)"},D=e.i18n.registerUIStrings("panels/react_devtools/ReactDevToolsProfilerView.ts",C),B=e.i18n.getLocalizedString.bind(void 0,D);var x=Object.freeze({__proto__:null,ReactDevToolsProfilerViewImpl:class extends v{constructor(){super("profiler",B(C.title))}}});export{b as ReactDevToolsComponentsView,h as ReactDevToolsModel,x as ReactDevToolsProfilerView}; +import*as e from"../../core/i18n/i18n.js";import*as t from"../../ui/legacy/legacy.js";import*as i from"../../core/sdk/sdk.js";import*as n from"../../third_party/react-devtools/react-devtools.js";import*as o from"../../core/common/common.js";import*as s from"../../models/workspace/workspace.js";import*as r from"../../models/bindings/bindings.js";import*as a from"../../models/logs/logs.js";import*as l from"../../core/host/host.js";import*as d from"../../models/react_native/react_native.js";class c extends i.SDKModel.SDKModel{static FUSEBOX_BINDING_NAMESPACE="react-devtools";#e;#t;#i=new Set;#n=!1;#o=!1;#s=null;#r=null;constructor(e){super(e),this.#e={listen:e=>(this.#i.add(e),()=>{this.#i.delete(e)}),send:(e,t)=>{this.#a({event:e,payload:t})}};const t=e.model(d.ReactDevToolsBindingsModel.ReactDevToolsBindingsModel);if(null===t)throw new Error("Failed to construct ReactDevToolsModel: ReactDevToolsBindingsModel was null");this.#t=t,t.addEventListener("BackendExecutionContextCreated",this.#l,this),t.addEventListener("BackendExecutionContextUnavailable",this.#d,this),t.addEventListener("BackendExecutionContextDestroyed",this.#c,this),window.addEventListener("beforeunload",this.#h)}dispose(){this.#s?.removeListener("reloadAppForProfiling",this.#u),this.#s?.shutdown(),this.#t.removeEventListener("BackendExecutionContextCreated",this.#l,this),this.#t.removeEventListener("BackendExecutionContextUnavailable",this.#d,this),this.#t.removeEventListener("BackendExecutionContextDestroyed",this.#c,this),window.removeEventListener("beforeunload",this.#h),this.#s=null,this.#r=null,this.#i.clear()}ensureInitialized(){this.#n||(this.#n=!0,this.#m())}async#m(){try{const e=this.#t;await e.enable(),e.subscribeToDomainMessages(c.FUSEBOX_BINDING_NAMESPACE,(e=>this.#g(e))),await e.initializeDomain(c.FUSEBOX_BINDING_NAMESPACE),this.#o=!0,this.#p()}catch(e){this.dispatchEventToListeners("InitializationFailed",e.message)}}isInitialized(){return this.#o}getBridgeOrThrow(){if(null===this.#s)throw new Error("Failed to get bridge from ReactDevToolsModel: bridge was null");return this.#s}getStoreOrThrow(){if(null===this.#r)throw new Error("Failed to get store from ReactDevToolsModel: store was null");return this.#r}#g(e){if(e)for(const t of this.#i)t(e)}async#a(e){const t=this.#t;if(!t)throw new Error("Failed to send message from ReactDevToolsModel: ReactDevToolsBindingsModel was null");return t.sendMessage(c.FUSEBOX_BINDING_NAMESPACE,e)}#h=()=>{this.#s?.shutdown()};#l(){const e=this.#t;if(!e)throw new Error("ReactDevToolsModel failed to handle BackendExecutionContextCreated event: ReactDevToolsBindingsModel was null");e.isEnabled()?this.#p():this.ensureInitialized()}#p(){this.#s=n.createBridge(this.#e),this.#r=n.createStore(this.#s,{supportsReloadAndProfile:!0}),this.#s.addListener("reloadAppForProfiling",this.#u),this.dispatchEventToListeners("InitializationCompleted")}#u(){i.ResourceTreeModel.ResourceTreeModel.reloadAllPages(!1)}#d({data:e}){this.dispatchEventToListeners("InitializationFailed",e)}#c(){this.#s?.shutdown(),this.#s=null,this.#r=null,this.#i.clear(),this.dispatchEventToListeners("Destroyed")}}i.SDKModel.SDKModel.register(c,{capabilities:4,autostart:!1});var h=Object.freeze({__proto__:null,ReactDevToolsModel:c});const u={sendFeedback:"[FB-only] Send feedback"},m=e.i18n.registerUIStrings("panels/react_devtools/ReactDevToolsViewBase.ts",u),g=e.i18n.getLocalizedString.bind(void 0,m);function p(e,t){const{sourceURL:i,line:n,column:l}=t||e;!async function(e,t,i){const n=s.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(e);if(n){const e=await r.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().normalizeUILocation(n.uiLocation(t,i));return void o.Revealer.reveal(e)}const l=r.ResourceUtils.resourceForURL(e);if(l)return void o.Revealer.reveal(l);const d=a.NetworkLog.NetworkLog.instance().requestForURL(e);if(!d)throw new Error("Could not find resource for "+e);o.Revealer.reveal(d)}(i,n-1,l-1)}class v extends t.View.SimpleView{#v;#w=null;constructor(e,t){super(t),this.#v=e,this.#E(),i.TargetManager.TargetManager.instance().observeModels(c,this),this.element.style.userSelect="text"}wasShown(){super.wasShown(),this.registerCSSFiles([n.CSS])}modelAdded(e){this.#w=e,e.addEventListener("InitializationCompleted",this.#f,this),e.addEventListener("InitializationFailed",this.#b,this),e.addEventListener("Destroyed",this.#C,this),e.isInitialized()?this.#D():e.ensureInitialized()}modelRemoved(e){e.removeEventListener("InitializationCompleted",this.#f,this),e.removeEventListener("InitializationFailed",this.#b,this),e.removeEventListener("Destroyed",this.#C,this)}#f(){this.#D()}#b({data:e}){this.#x(e)}#C(){this.#E()}#D(){this.#B();const e=this.#w;if(null===e)throw new Error("Attempted to render React DevTools panel, but the model was null");const t=window.matchMedia("(prefers-color-scheme: dark)").matches;("components"===this.#v?n.initializeComponents:n.initializeProfiler)(this.contentElement,{bridge:e.getBridgeOrThrow(),store:e.getStoreOrThrow(),theme:t?"dark":"light",canViewElementSourceFunction:()=>!0,viewElementSourceFunction:p})}#E(){this.#B();const e=document.createElement("div");e.setAttribute("style","display: flex; flex: 1; justify-content: center; align-items: center");const t=document.createElement("span");t.classList.add("spinner"),e.appendChild(t),this.contentElement.appendChild(e)}#x(e){this.#B();const i=document.createElement("div");i.setAttribute("style","display: flex; flex: 1; flex-direction: column; justify-content: center; align-items: center");const n=document.createElement("div");n.setAttribute("style","font-size: 3rem"),n.innerHTML="❗";const o=document.createElement("p");if(o.setAttribute("style","user-select: all"),o.innerHTML=e,i.appendChild(n),i.appendChild(o),this.contentElement.appendChild(i),globalThis.FB_ONLY__reactNativeFeedbackLink){const e=globalThis.FB_ONLY__reactNativeFeedbackLink,n=t.UIUtils.createTextButton(g(u.sendFeedback),(()=>{l.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(e)}),{className:"primary-button",jslogContext:"sendFeedback"});i.appendChild(n)}}#B(){this.contentElement.removeChildren()}}const w={title:"⚛️ Components (React DevTools)"},E=e.i18n.registerUIStrings("panels/react_devtools/ReactDevToolsComponentsView.ts",w),f=e.i18n.getLocalizedString.bind(void 0,E);var b=Object.freeze({__proto__:null,ReactDevToolsComponentsViewImpl:class extends v{constructor(){super("components",f(w.title))}}});const C={title:"⚛️ Profiler (React DevTools)"},D=e.i18n.registerUIStrings("panels/react_devtools/ReactDevToolsProfilerView.ts",C),x=e.i18n.getLocalizedString.bind(void 0,D);var B=Object.freeze({__proto__:null,ReactDevToolsProfilerViewImpl:class extends v{constructor(){super("profiler",x(C.title))}}});export{b as ReactDevToolsComponentsView,h as ReactDevToolsModel,B as ReactDevToolsProfilerView}; diff --git a/packages/dev-middleware/README.md b/packages/dev-middleware/README.md index 417f87e1de5219..fe2fd38b2402cb 100644 --- a/packages/dev-middleware/README.md +++ b/packages/dev-middleware/README.md @@ -64,12 +64,16 @@ Subpaths of this endpoint are reserved to serve the JavaScript debugger frontend #### POST `/open-debugger` -Open the JavaScript debugger for a given CDP target (direct Hermes debugging). +Open the JavaScript debugger for a given CDP target. Must be provided with one of the following query params: + +- `device`‌ — An ID unique to a combination of device and app, stable across installs. Implemented by `getInspectorDeviceId` on each native platform. +- `target` — The target page ID as returned by `/json/list` for the current dev server session. +- `appId` (deprecated, legacy only) — The application bundle identifier to match (non-unique across multiple connected devices). This param will only match legacy Hermes debugger targets.
Example - curl -X POST 'http://localhost:8081/open-debugger?appId=com.meta.RNTester' + curl -X POST 'http://localhost:8081/open-debugger?target='
### WebSocket endpoints diff --git a/packages/dev-middleware/src/__tests__/InspectorProxyHttpApi-test.js b/packages/dev-middleware/src/__tests__/InspectorProxyHttpApi-test.js index 52a53de214b049..d87c3a526f4682 100644 --- a/packages/dev-middleware/src/__tests__/InspectorProxyHttpApi-test.js +++ b/packages/dev-middleware/src/__tests__/InspectorProxyHttpApi-test.js @@ -14,11 +14,11 @@ import type { JsonVersionResponse, } from '../inspector-proxy/types'; +import DefaultBrowserLauncher from '../utils/DefaultBrowserLauncher'; import {fetchJson, fetchLocal} from './FetchUtils'; import {createDeviceMock} from './InspectorDeviceUtils'; import {withAbortSignalForEachTest} from './ResourceUtils'; import {withServerForEachTest} from './ServerUtils'; -import DefaultBrowserLauncher from '../utils/DefaultBrowserLauncher'; // Must be greater than or equal to PAGES_POLLING_INTERVAL in `InspectorProxy.js`. const PAGES_POLLING_DELAY = 1000; @@ -185,6 +185,7 @@ describe('inspector proxy HTTP API', () => { ); expect(json).toEqual([ { + appId: 'bar-app', description: 'bar-app', deviceName: 'foo', devtoolsFrontendUrl: expect.any(String), @@ -199,6 +200,7 @@ describe('inspector proxy HTTP API', () => { webSocketDebuggerUrl: expect.any(String), }, { + appId: 'bar-app', description: 'bar-app', deviceName: 'foo', devtoolsFrontendUrl: expect.any(String), @@ -371,7 +373,7 @@ describe('inspector proxy HTTP API', () => { }); describe('/open-debugger endpoint', () => { - it('opens requested device using appId, device, and target', async () => { + test('opens requested device using device and target query params', async () => { // Connect a device to use when opening the debugger const device = await createDeviceMock( `${serverRef.serverBaseWsUrl}/inspector/device?device=device1&name=foo&app=bar`, @@ -407,7 +409,6 @@ describe('inspector proxy HTTP API', () => { // Build the URL for the debugger const openUrl = new URL('/open-debugger', serverRef.serverBaseUrl); - openUrl.searchParams.set('appId', firstPage.description); openUrl.searchParams.set( 'device', firstPage.reactNative.logicalDeviceId, diff --git a/packages/dev-middleware/src/inspector-proxy/InspectorProxy.js b/packages/dev-middleware/src/inspector-proxy/InspectorProxy.js index f0f6257afcd445..c24fb758312e10 100644 --- a/packages/dev-middleware/src/inspector-proxy/InspectorProxy.js +++ b/packages/dev-middleware/src/inspector-proxy/InspectorProxy.js @@ -161,6 +161,7 @@ export default class InspectorProxy implements InspectorProxyQueries { id: `${deviceId}-${page.id}`, title: page.title, description: page.description ?? page.app, + appId: page.app, type: 'node', devtoolsFrontendUrl, webSocketDebuggerUrl, diff --git a/packages/dev-middleware/src/inspector-proxy/types.js b/packages/dev-middleware/src/inspector-proxy/types.js index dd26e3dd7f1a51..ee3374bad5eb4e 100644 --- a/packages/dev-middleware/src/inspector-proxy/types.js +++ b/packages/dev-middleware/src/inspector-proxy/types.js @@ -18,9 +18,10 @@ export type TargetCapabilityFlags = $ReadOnly<{ * The target supports a stable page representation across reloads. * * In the proxy, this disables legacy page reload emulation and the - * additional '(Experimental)' target in `/json/list`. + * additional 'React Native Experimental' target in `/json/list`. * - * In the launch flow, this allows targets to be matched directly by `appId`. + * In the launch flow, this allows targets to be matched directly by + * `logicalDeviceId`. */ nativePageReloads?: boolean, @@ -115,6 +116,7 @@ export type MessageToDevice = export type PageDescription = $ReadOnly<{ id: string, title: string, + appId: string, description: string, type: string, devtoolsFrontendUrl: string, diff --git a/packages/dev-middleware/src/middleware/openDebuggerMiddleware.js b/packages/dev-middleware/src/middleware/openDebuggerMiddleware.js index 97fcb9c984f3d4..8936e42119ef7b 100644 --- a/packages/dev-middleware/src/middleware/openDebuggerMiddleware.js +++ b/packages/dev-middleware/src/middleware/openDebuggerMiddleware.js @@ -20,6 +20,9 @@ import type {IncomingMessage, ServerResponse} from 'http'; import getDevToolsFrontendUrl from '../utils/getDevToolsFrontendUrl'; import url from 'url'; +const LEGACY_SYNTHETIC_PAGE_TITLE = + 'React Native Experimental (Improved Chrome Reloads)'; + type Options = $ReadOnly<{ serverBaseUrl: string, logger?: Logger, @@ -32,8 +35,8 @@ type Options = $ReadOnly<{ /** * Open the debugger frontend for a given CDP target. * - * Currently supports Hermes targets, opening debugger websocket URL in Chrome - * DevTools. + * Currently supports React Native DevTools (rn_fusebox.html) and legacy Hermes + * (rn_inspector.html) targets. * * @see https://chromedevtools.github.io/devtools-protocol/ */ @@ -61,6 +64,7 @@ export default function openDebuggerMiddleware({ launchId, target: targetId, }: { + /** @deprecated Will only match legacy Hermes targets */ appId?: string, device?: string, launchId?: string, @@ -71,7 +75,7 @@ export default function openDebuggerMiddleware({ const targets = inspectorProxy.getPageDescriptions().filter( // Only use targets with better reloading support app => - app.title === 'React Native Experimental (Improved Chrome Reloads)' || + app.title === LEGACY_SYNTHETIC_PAGE_TITLE || app.reactNative.capabilities?.nativePageReloads === true, ); @@ -92,7 +96,9 @@ export default function openDebuggerMiddleware({ target = targets.find( _target => (targetId == null || _target.id === targetId) && - (appId == null || _target.description === appId) && + (appId == null || + (_target.appId === appId && + _target.title === LEGACY_SYNTHETIC_PAGE_TITLE)) && (device == null || _target.reactNative.logicalDeviceId === device), ); } else if (targets.length > 0) { @@ -156,6 +162,7 @@ export default function openDebuggerMiddleware({ appId: appId ?? null, deviceId: device ?? null, resolvedTargetDescription: target.description, + resolvedTargetAppId: target.appId, prefersFuseboxFrontend: useFuseboxEntryPoint ?? false, }); return; diff --git a/packages/dev-middleware/src/types/EventReporter.js b/packages/dev-middleware/src/types/EventReporter.js index f578f745cf3a6f..8c4bc2b52aed49 100644 --- a/packages/dev-middleware/src/types/EventReporter.js +++ b/packages/dev-middleware/src/types/EventReporter.js @@ -41,6 +41,7 @@ export type ReportableEvent = appId: string | null, deviceId: string | null, resolvedTargetDescription: string, + resolvedTargetAppId: string, prefersFuseboxFrontend: boolean, }> | ErrorResult diff --git a/packages/helloworld/App.jsx b/packages/helloworld/App.jsx index 4d427afdaf916f..adf0fd1254f226 100644 --- a/packages/helloworld/App.jsx +++ b/packages/helloworld/App.jsx @@ -14,10 +14,9 @@ import { StatusBar, StyleSheet, Text, - useColorScheme, View, + useColorScheme, } from 'react-native'; - import {Colors, Header} from 'react-native/Libraries/NewAppScreen'; function App(): React.JSX.Element { diff --git a/packages/helloworld/android/build.gradle b/packages/helloworld/android/build.gradle index b51b5dffbbf05f..45ad5c70a1a2b7 100644 --- a/packages/helloworld/android/build.gradle +++ b/packages/helloworld/android/build.gradle @@ -11,7 +11,7 @@ buildscript { minSdkVersion = 24 compileSdkVersion = 35 targetSdkVersion = 34 - ndkVersion = "26.1.10909125" + ndkVersion = "27.1.12297006" kotlinVersion = "2.0.21" } repositories { diff --git a/packages/helloworld/cli.js b/packages/helloworld/cli.js index 3e950d5e85bfbe..b5ba1ed3c55579 100644 --- a/packages/helloworld/cli.js +++ b/packages/helloworld/cli.js @@ -13,6 +13,7 @@ import {Command} from 'commander'; */ +// eslint-disable-next-line lint/sort-imports const {patchCoreCLIUtilsPackageJSON} = require('./scripts/monorepo'); function injectCoreCLIUtilsRuntimePatch() { diff --git a/packages/metro-config/src/index.flow.js b/packages/metro-config/src/index.flow.js index 49ae81f261c327..29398b89f65cf6 100644 --- a/packages/metro-config/src/index.flow.js +++ b/packages/metro-config/src/index.flow.js @@ -11,10 +11,10 @@ import type {ConfigT} from 'metro-config'; -export type {MetroConfig} from 'metro-config'; - import {getDefaultConfig as getBaseConfig, mergeConfig} from 'metro-config'; +export type {MetroConfig} from 'metro-config'; + const INTERNAL_CALLSITES_REGEX = new RegExp( [ '/Libraries/BatchedBridge/MessageQueue\\.js$', diff --git a/packages/react-native-bots/dangerfile.js b/packages/react-native-bots/dangerfile.js index b71ec9923e03a7..2f7a7165e28cdb 100644 --- a/packages/react-native-bots/dangerfile.js +++ b/packages/react-native-bots/dangerfile.js @@ -8,11 +8,8 @@ */ 'use strict'; - const {danger, fail, /*message,*/ warn} = require('danger'); const includes = require('lodash.includes'); -const {validate: validateChangelog} = - require('@rnx-kit/rn-changelog-generator').default; const isFromPhabricator = danger.github.pr.body && @@ -60,7 +57,9 @@ if (!includesTestPlan && !isFromPhabricator) { // Check if there is a changelog and validate it if (!isFromPhabricator) { - const status = validateChangelog(danger.github.pr.body); + const status = require('@rnx-kit/rn-changelog-generator').default.validate( + danger.github.pr.body, + ); const changelogInstructions = 'See Changelog format'; if (status === 'missing') { diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 4398919e77501b..6b3097804fa435 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -71,7 +71,7 @@ export type MixedTypeAnnotation = $ReadOnly<{ type: 'MixedTypeAnnotation', }>; -type EventEmitterTypeAnnotation = $ReadOnly<{ +export type EventEmitterTypeAnnotation = $ReadOnly<{ type: 'EventEmitterTypeAnnotation', typeAnnotation: NativeModuleEventEmitterTypeAnnotation | $FlowFixMe, }>; @@ -424,4 +424,5 @@ export type CompleteTypeAnnotation = | NativeModuleTypeAnnotation | NativeModuleFunctionTypeAnnotation | NullableTypeAnnotation + | EventEmitterTypeAnnotation | UnsafeAnyTypeAnnotation; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js index 2792697aec1faa..295514ca52653f 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js @@ -11,22 +11,22 @@ 'use strict'; import type { - NativeModuleArrayTypeAnnotation, - NativeModuleBaseTypeAnnotation, BooleanTypeAnnotation, DoubleTypeAnnotation, - NativeModuleEnumDeclaration, FloatTypeAnnotation, - NativeModuleGenericObjectTypeAnnotation, Int32TypeAnnotation, + NativeModuleArrayTypeAnnotation, + NativeModuleBaseTypeAnnotation, + NativeModuleEnumDeclaration, + NativeModuleGenericObjectTypeAnnotation, NativeModuleNumberTypeAnnotation, NativeModuleObjectTypeAnnotation, - StringTypeAnnotation, - StringLiteralTypeAnnotation, - StringLiteralUnionTypeAnnotation, NativeModuleTypeAliasTypeAnnotation, Nullable, ReservedTypeAnnotation, + StringLiteralTypeAnnotation, + StringLiteralUnionTypeAnnotation, + StringTypeAnnotation, } from '../../../CodegenSchema'; import type {AliasResolver} from '../Utils'; diff --git a/packages/react-native-codegen/src/parsers/parsers-primitives.js b/packages/react-native-codegen/src/parsers/parsers-primitives.js index 1a6957e0ae1d13..5e366960201d8d 100644 --- a/packages/react-native-codegen/src/parsers/parsers-primitives.js +++ b/packages/react-native-codegen/src/parsers/parsers-primitives.js @@ -14,13 +14,13 @@ import type { BooleanTypeAnnotation, DoubleTypeAnnotation, EventTypeAnnotation, + FloatTypeAnnotation, Int32TypeAnnotation, NamedShape, NativeModuleAliasMap, NativeModuleBaseTypeAnnotation, NativeModuleEnumDeclaration, NativeModuleEnumMap, - FloatTypeAnnotation, NativeModuleFunctionTypeAnnotation, NativeModuleGenericObjectTypeAnnotation, NativeModuleMixedTypeAnnotation, @@ -33,9 +33,9 @@ import type { Nullable, ObjectTypeAnnotation, ReservedTypeAnnotation, - StringTypeAnnotation, StringLiteralTypeAnnotation, StringLiteralUnionTypeAnnotation, + StringTypeAnnotation, VoidTypeAnnotation, } from '../CodegenSchema'; import type {Parser} from './parser'; diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/index.js b/packages/react-native-codegen/src/parsers/typescript/modules/index.js index 8a6ebcee35f39a..8c4da2de883dfb 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/index.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/index.js @@ -39,8 +39,8 @@ const { emitFunction, emitPromise, emitRootTag, - emitUnion, emitStringLiteral, + emitUnion, translateArrayTypeAnnotation, typeAliasResolution, typeEnumResolution, diff --git a/packages/react-native/Libraries/Animated/AnimatedEvent.js b/packages/react-native/Libraries/Animated/AnimatedEvent.js index 39b25807b9be9d..52e732e4070e19 100644 --- a/packages/react-native/Libraries/Animated/AnimatedEvent.js +++ b/packages/react-native/Libraries/Animated/AnimatedEvent.js @@ -12,8 +12,8 @@ import type {PlatformConfig} from './AnimatedPlatformConfig'; -import {findNodeHandle} from '../ReactNative/RendererProxy'; import NativeAnimatedHelper from '../../src/private/animated/NativeAnimatedHelper'; +import {findNodeHandle} from '../ReactNative/RendererProxy'; import AnimatedValue from './nodes/AnimatedValue'; import AnimatedValueXY from './nodes/AnimatedValueXY'; import invariant from 'invariant'; diff --git a/packages/react-native/Libraries/Animated/animations/Animation.js b/packages/react-native/Libraries/Animated/animations/Animation.js index 28ba043b8c7bda..ad5163b8ab4101 100644 --- a/packages/react-native/Libraries/Animated/animations/Animation.js +++ b/packages/react-native/Libraries/Animated/animations/Animation.js @@ -12,8 +12,8 @@ import type {PlatformConfig} from '../AnimatedPlatformConfig'; import type AnimatedNode from '../nodes/AnimatedNode'; import type AnimatedValue from '../nodes/AnimatedValue'; -import * as ReactNativeFeatureFlags from '../../../src/private/featureflags/ReactNativeFeatureFlags'; import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper'; +import * as ReactNativeFeatureFlags from '../../../src/private/featureflags/ReactNativeFeatureFlags'; import AnimatedProps from '../nodes/AnimatedProps'; export type EndResult = {finished: boolean, value?: number, ...}; diff --git a/packages/react-native/Libraries/Animated/createAnimatedComponent.js b/packages/react-native/Libraries/Animated/createAnimatedComponent.js index fc9153f27cb714..cef22cd810fd45 100644 --- a/packages/react-native/Libraries/Animated/createAnimatedComponent.js +++ b/packages/react-native/Libraries/Animated/createAnimatedComponent.js @@ -35,18 +35,18 @@ export type StrictAnimatedProps = $ReadOnly<{ passthroughAnimatedPropExplicitValues?: ?Props, }>; -export type AnimatedComponentType< - Props: {...}, - +Instance = mixed, -> = React.AbstractComponent, Instance>; +export type AnimatedComponentType = component( + ref: React.RefSetter, + ...AnimatedProps +); export type StrictAnimatedComponentType< Props: {...}, +Instance = mixed, -> = React.AbstractComponent, Instance>; +> = component(ref: React.RefSetter, ...StrictAnimatedProps); export default function createAnimatedComponent( - Component: React.AbstractComponent, + Component: component(ref: React.RefSetter, ...TProps), ): AnimatedComponentType { return unstable_createAnimatedComponentWithAllowlist(Component, null); } @@ -55,7 +55,7 @@ export function unstable_createAnimatedComponentWithAllowlist< TProps: {...}, TInstance, >( - Component: React.AbstractComponent, + Component: component(ref: React.RefSetter, ...TProps), allowlist: ?AnimatedPropsAllowlist, ): StrictAnimatedComponentType { const AnimatedComponent = React.forwardRef< diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedColor.js b/packages/react-native/Libraries/Animated/nodes/AnimatedColor.js index 4485df1f3fd664..ed6874f03a998b 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedColor.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedColor.js @@ -15,9 +15,9 @@ import type {ColorValue} from '../../StyleSheet/StyleSheet'; import type {NativeColorValue} from '../../StyleSheet/StyleSheetTypes'; import type {PlatformConfig} from '../AnimatedPlatformConfig'; +import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper'; import normalizeColor from '../../StyleSheet/normalizeColor'; import {processColorObject} from '../../StyleSheet/PlatformColorValueTypes'; -import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper'; import AnimatedValue, {flushValue} from './AnimatedValue'; import AnimatedWithChildren from './AnimatedWithChildren'; diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedInterpolation.js b/packages/react-native/Libraries/Animated/nodes/AnimatedInterpolation.js index 7d191938ab0abc..e9f593e8452797 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedInterpolation.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedInterpolation.js @@ -15,11 +15,11 @@ import type {PlatformConfig} from '../AnimatedPlatformConfig'; import type AnimatedNode from './AnimatedNode'; +import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper'; import {validateInterpolation} from '../../../src/private/animated/NativeAnimatedValidation'; import normalizeColor from '../../StyleSheet/normalizeColor'; import processColor from '../../StyleSheet/processColor'; import Easing from '../Easing'; -import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper'; import AnimatedWithChildren from './AnimatedWithChildren'; import invariant from 'invariant'; diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedProps.js b/packages/react-native/Libraries/Animated/nodes/AnimatedProps.js index d1a1593f3320b1..44b234f505f9f7 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedProps.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedProps.js @@ -11,9 +11,9 @@ import type {PlatformConfig} from '../AnimatedPlatformConfig'; import type {AnimatedStyleAllowlist} from './AnimatedStyle'; +import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper'; import {findNodeHandle} from '../../ReactNative/RendererProxy'; import {AnimatedEvent} from '../AnimatedEvent'; -import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper'; import AnimatedNode from './AnimatedNode'; import AnimatedObject from './AnimatedObject'; import AnimatedStyle from './AnimatedStyle'; diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedTransform.js b/packages/react-native/Libraries/Animated/nodes/AnimatedTransform.js index 50f484e3b76d5b..fc675169774322 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedTransform.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedTransform.js @@ -12,8 +12,8 @@ import type {PlatformConfig} from '../AnimatedPlatformConfig'; -import {validateTransform} from '../../../src/private/animated/NativeAnimatedValidation'; import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper'; +import {validateTransform} from '../../../src/private/animated/NativeAnimatedValidation'; import AnimatedNode from './AnimatedNode'; import AnimatedWithChildren from './AnimatedWithChildren'; diff --git a/packages/react-native/Libraries/Animated/nodes/AnimatedValue.js b/packages/react-native/Libraries/Animated/nodes/AnimatedValue.js index 15fcd4ec3817d4..76a984fe4f1d41 100644 --- a/packages/react-native/Libraries/Animated/nodes/AnimatedValue.js +++ b/packages/react-native/Libraries/Animated/nodes/AnimatedValue.js @@ -15,8 +15,8 @@ import type {InterpolationConfigType} from './AnimatedInterpolation'; import type AnimatedNode from './AnimatedNode'; import type AnimatedTracking from './AnimatedTracking'; -import InteractionManager from '../../Interaction/InteractionManager'; import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper'; +import InteractionManager from '../../Interaction/InteractionManager'; import AnimatedInterpolation from './AnimatedInterpolation'; import AnimatedWithChildren from './AnimatedWithChildren'; diff --git a/packages/react-native/Libraries/Animated/useAnimatedProps.js b/packages/react-native/Libraries/Animated/useAnimatedProps.js index e4dd4f7791f0ec..134234dacbf57c 100644 --- a/packages/react-native/Libraries/Animated/useAnimatedProps.js +++ b/packages/react-native/Libraries/Animated/useAnimatedProps.js @@ -8,14 +8,15 @@ * @format */ -import type {AnimatedPropsAllowlist} from './nodes/AnimatedProps'; import type {EventSubscription} from '../EventEmitter/NativeEventEmitter'; +import type {AnimatedPropsAllowlist} from './nodes/AnimatedProps'; +import NativeAnimatedHelper from '../../src/private/animated/NativeAnimatedHelper'; +import {useAnimatedPropsMemo} from '../../src/private/animated/useAnimatedPropsMemo'; import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags'; import {isPublicInstance as isFabricPublicInstance} from '../ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstanceUtils'; import useRefEffect from '../Utilities/useRefEffect'; import {AnimatedEvent} from './AnimatedEvent'; -import NativeAnimatedHelper from '../../src/private/animated/NativeAnimatedHelper'; import AnimatedNode from './nodes/AnimatedNode'; import AnimatedProps from './nodes/AnimatedProps'; import AnimatedValue from './nodes/AnimatedValue'; @@ -28,7 +29,6 @@ import { useReducer, useRef, } from 'react'; -import {useAnimatedPropsMemo} from '../../src/private/animated/useAnimatedPropsMemo'; type ReducedProps = { ...TProps, diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm index 9c1a1f7ca49111..baca356003be7f 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm @@ -308,18 +308,6 @@ - (RCTRootViewFactory *)createRCTRootViewFactory class RCTAppDelegateBridgelessFeatureFlags : public facebook::react::ReactNativeFeatureFlagsDefaults { public: - bool useModernRuntimeScheduler() override - { - return true; - } - bool enableMicrotasks() override - { - return true; - } - bool batchRenderingUpdatesInEventLoop() override - { - return true; - } bool enableBridgelessArchitecture() override { return true; diff --git a/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec b/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec index e9e16bcbbe1ecd..b54f1e41af5c40 100644 --- a/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec +++ b/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec @@ -32,6 +32,7 @@ header_search_paths = [ "$(PODS_ROOT)/Headers/Private/React-Core", "$(PODS_ROOT)/boost", "$(PODS_ROOT)/DoubleConversion", + "$(PODS_ROOT)/fast_float/include", "$(PODS_ROOT)/fmt/include", "$(PODS_ROOT)/RCT-Folly", "${PODS_ROOT}/Headers/Public/FlipperKit", @@ -63,7 +64,7 @@ Pod::Spec.new do |s| "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), "DEFINES_MODULE" => "YES" } - s.user_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\""} + s.user_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\" \"$(PODS_ROOT)/Headers/Private/Yoga\""} s.dependency "React-Core" s.dependency "RCT-Folly", folly_version diff --git a/packages/react-native/Libraries/Blob/React-RCTBlob.podspec b/packages/react-native/Libraries/Blob/React-RCTBlob.podspec index ad640869869984..c592234ed13394 100644 --- a/packages/react-native/Libraries/Blob/React-RCTBlob.podspec +++ b/packages/react-native/Libraries/Blob/React-RCTBlob.podspec @@ -24,6 +24,7 @@ header_search_paths = [ "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/boost\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"", "\"${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\"", ] @@ -48,7 +49,8 @@ Pod::Spec.new do |s| } s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" s.dependency "RCT-Folly", folly_version s.dependency "React-jsi" s.dependency "React-Core/RCTBlobHeaders" diff --git a/packages/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.js b/packages/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.js index 8cdceda9e9a8af..2855cf47ffd6ae 100644 --- a/packages/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.js +++ b/packages/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.js @@ -154,7 +154,7 @@ const ActivityIndicator = ( */ const ActivityIndicatorWithRef: component( - ref: React.RefSetter>, + ref: React.RefSetter>, ...props: Props ) = React.forwardRef(ActivityIndicator); ActivityIndicatorWithRef.displayName = 'ActivityIndicator'; diff --git a/packages/react-native/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js b/packages/react-native/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js index d69f981ea47108..f806848bbc7f7f 100644 --- a/packages/react-native/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js +++ b/packages/react-native/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js @@ -14,8 +14,9 @@ import type {HostComponent} from '../../../Renderer/shims/ReactNativeTypes'; import requireNativeComponent from '../../../ReactNative/requireNativeComponent'; import * as React from 'react'; -const RCTRefreshControl: HostComponent = - requireNativeComponent('RCTRefreshControl'); +const RCTRefreshControl: HostComponent<{}> = requireNativeComponent<{}>( + 'RCTRefreshControl', +); class RefreshControlMock extends React.Component<{...}> { static latestRef: ?RefreshControlMock; diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js index 39740a8ae593ad..ac218c0fd208a5 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js @@ -371,10 +371,10 @@ type AndroidProps = $ReadOnly<{| fadingEdgeLength?: ?number, |}>; -type StickyHeaderComponentType = React.AbstractComponent< - ScrollViewStickyHeaderProps, - $ReadOnly void}>, ->; +type StickyHeaderComponentType = component( + ref?: React.RefSetter<$ReadOnly void}>>, + ...ScrollViewStickyHeaderProps +); export type Props = $ReadOnly<{| ...ViewProps, diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewCommands.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewCommands.js index 6ff89b42017f40..2e5385d25abe6c 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewCommands.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewCommands.js @@ -14,7 +14,7 @@ import type {Double} from '../../Types/CodegenTypes'; import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; import * as React from 'react'; -type ScrollViewNativeComponentType = HostComponent; +type ScrollViewNativeComponentType = HostComponent<{...}>; interface NativeCommands { +flashScrollIndicators: ( viewRef: React.ElementRef, diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewContext.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewContext.js index 4c194ad54941e5..e08fda8bc656f5 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewContext.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewContext.js @@ -18,5 +18,7 @@ if (__DEV__) { } export default ScrollViewContext; +// $FlowFixMe[incompatible-type] frozen objects are readonly export const HORIZONTAL: Value = Object.freeze({horizontal: true}); +// $FlowFixMe[incompatible-type] frozen objects are readonly export const VERTICAL: Value = Object.freeze({horizontal: false}); diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollViewStickyHeader.js b/packages/react-native/Libraries/Components/ScrollView/ScrollViewStickyHeader.js index d60e87f4ec7a8e..d83abfe57a2b6e 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollViewStickyHeader.js @@ -275,12 +275,12 @@ const ScrollViewStickyHeaderWithForwardedRef: component( : null; return ( - /* $FlowFixMe[prop-missing] passthroughAnimatedPropExplicitValues isn't properly - included in the Animated.View flow type. */ ; -const InputAccessoryView: React.AbstractComponent = (props: Props) => { +const InputAccessoryView: React.ComponentType = (props: Props) => { const {width} = useWindowDimensions(); if (Platform.OS === 'ios') { diff --git a/packages/react-native/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js b/packages/react-native/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js index ccccc928a05c19..595006b1c40287 100644 --- a/packages/react-native/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js +++ b/packages/react-native/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js @@ -18,7 +18,7 @@ import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentR import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; import RCTTextInputViewConfig from './RCTTextInputViewConfig'; -type NativeType = HostComponent; +type NativeType = HostComponent<{...}>; type NativeCommands = TextInputNativeCommands; @@ -35,11 +35,11 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = { }, }; -const MultilineTextInputNativeComponent: HostComponent = - NativeComponentRegistry.get( +const MultilineTextInputNativeComponent: HostComponent<{...}> = + NativeComponentRegistry.get<{...}>( 'RCTMultilineTextInputView', () => __INTERNAL_VIEW_CONFIG, ); // flowlint-next-line unclear-type:off -export default ((MultilineTextInputNativeComponent: any): HostComponent); +export default ((MultilineTextInputNativeComponent: any): HostComponent<{...}>); diff --git a/packages/react-native/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js b/packages/react-native/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js index 8ec1f49441c4b5..306b30bde4d3f2 100644 --- a/packages/react-native/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js +++ b/packages/react-native/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js @@ -18,7 +18,7 @@ import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentR import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; import RCTTextInputViewConfig from './RCTTextInputViewConfig'; -type NativeType = HostComponent; +type NativeType = HostComponent<{...}>; type NativeCommands = TextInputNativeCommands; @@ -31,11 +31,13 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = { ...RCTTextInputViewConfig, }; -const SinglelineTextInputNativeComponent: HostComponent = - NativeComponentRegistry.get( +const SinglelineTextInputNativeComponent: HostComponent<{...}> = + NativeComponentRegistry.get<{...}>( 'RCTSinglelineTextInputView', () => __INTERNAL_VIEW_CONFIG, ); // flowlint-next-line unclear-type:off -export default ((SinglelineTextInputNativeComponent: any): HostComponent); +export default ((SinglelineTextInputNativeComponent: any): HostComponent<{ + ... +}>); diff --git a/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js b/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js index 4b082ceec8bd7e..ee86dd32cc9100 100644 --- a/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js +++ b/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js @@ -1086,7 +1086,10 @@ type ImperativeMethods = $ReadOnly<{| * or control this param programmatically with native code. * */ -type InternalTextInput = (props: Props) => React.Node; +type InternalTextInput = component( + ref: React.RefSetter<$ReadOnly<{...HostInstance, ...ImperativeMethods}>>, + ...Props +); export type TextInputComponentStatics = $ReadOnly<{| State: $ReadOnly<{| @@ -1097,11 +1100,4 @@ export type TextInputComponentStatics = $ReadOnly<{| |}>, |}>; -export type TextInputType = React.AbstractComponent< - React.ElementConfig, - $ReadOnly<{| - ...HostInstance, - ...ImperativeMethods, - |}>, -> & - TextInputComponentStatics; +export type TextInputType = InternalTextInput & TextInputComponentStatics; diff --git a/packages/react-native/Libraries/Components/Touchable/TouchableBounce.js b/packages/react-native/Libraries/Components/Touchable/TouchableBounce.js index 9a2bdfff23b283..7c9f5a4b6867f1 100644 --- a/packages/react-native/Libraries/Components/Touchable/TouchableBounce.js +++ b/packages/react-native/Libraries/Components/Touchable/TouchableBounce.js @@ -189,6 +189,7 @@ class TouchableBounce extends React.Component { this.props.onPress !== undefined && !this.props.disabled } + // $FlowFixMe[prop-missing] ref={this.props.hostRef} {...eventHandlersWithoutBlurAndFocus}> {this.props.children} diff --git a/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js b/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js index 92eea6cb3fc7f7..ef9b2572b69cb8 100644 --- a/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js +++ b/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js @@ -291,6 +291,7 @@ class TouchableOpacity extends React.Component { this.props.onPress !== undefined && !this.props.disabled } + // $FlowFixMe[prop-missing] ref={this.props.hostRef} {...eventHandlersWithoutBlurAndFocus}> {this.props.children} diff --git a/packages/react-native/Libraries/Components/View/ViewNativeComponent.js b/packages/react-native/Libraries/Components/View/ViewNativeComponent.js index 4597b57908a433..b32b9065db73ec 100644 --- a/packages/react-native/Libraries/Components/View/ViewNativeComponent.js +++ b/packages/react-native/Libraries/Components/View/ViewNativeComponent.js @@ -11,101 +11,16 @@ import type { HostComponent, HostInstance, - PartialViewConfig, } from '../../Renderer/shims/ReactNativeTypes'; import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry'; import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; -import Platform from '../../Utilities/Platform'; import {type ViewProps as Props} from './ViewPropTypes'; -export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = - Platform.OS === 'android' - ? { - uiViewClassName: 'RCTView', - validAttributes: { - // ReactClippingViewManager @ReactProps - removeClippedSubviews: true, - - // ReactViewManager @ReactProps - accessible: true, - hasTVPreferredFocus: true, - nextFocusDown: true, - nextFocusForward: true, - nextFocusLeft: true, - nextFocusRight: true, - nextFocusUp: true, - - borderRadius: true, - borderTopLeftRadius: true, - borderTopRightRadius: true, - borderBottomRightRadius: true, - borderBottomLeftRadius: true, - borderTopStartRadius: true, - borderTopEndRadius: true, - borderBottomStartRadius: true, - borderBottomEndRadius: true, - borderEndEndRadius: true, - borderEndStartRadius: true, - borderStartEndRadius: true, - borderStartStartRadius: true, - borderStyle: true, - hitSlop: true, - pointerEvents: true, - nativeBackgroundAndroid: true, - nativeForegroundAndroid: true, - needsOffscreenAlphaCompositing: true, - - borderWidth: true, - borderLeftWidth: true, - borderRightWidth: true, - borderTopWidth: true, - borderBottomWidth: true, - borderStartWidth: true, - borderEndWidth: true, - - borderColor: { - process: require('../../StyleSheet/processColor').default, - }, - borderLeftColor: { - process: require('../../StyleSheet/processColor').default, - }, - borderRightColor: { - process: require('../../StyleSheet/processColor').default, - }, - borderTopColor: { - process: require('../../StyleSheet/processColor').default, - }, - borderBottomColor: { - process: require('../../StyleSheet/processColor').default, - }, - borderStartColor: { - process: require('../../StyleSheet/processColor').default, - }, - borderEndColor: { - process: require('../../StyleSheet/processColor').default, - }, - borderBlockColor: { - process: require('../../StyleSheet/processColor').default, - }, - borderBlockEndColor: { - process: require('../../StyleSheet/processColor').default, - }, - borderBlockStartColor: { - process: require('../../StyleSheet/processColor').default, - }, - focusable: true, - overflow: true, - backfaceVisibility: true, - experimental_layoutConformance: true, - }, - } - : { - uiViewClassName: 'RCTView', - }; - const ViewNativeComponent: HostComponent = - NativeComponentRegistry.get('RCTView', () => __INTERNAL_VIEW_CONFIG); + NativeComponentRegistry.get('RCTView', () => ({ + uiViewClassName: 'RCTView', + })); interface NativeCommands { +hotspotUpdate: (viewRef: HostInstance, x: number, y: number) => void; diff --git a/packages/react-native/Libraries/Core/ExceptionsManager.js b/packages/react-native/Libraries/Core/ExceptionsManager.js index e64a3a0fd6e54f..09c5941f06240f 100644 --- a/packages/react-native/Libraries/Core/ExceptionsManager.js +++ b/packages/react-native/Libraries/Core/ExceptionsManager.js @@ -141,24 +141,27 @@ let inExceptionHandler = false; * Logs exceptions to the (native) console and displays them */ function handleException(e: mixed, isFatal: boolean) { - let error: Error; - if (e instanceof Error) { - error = e; - } else { - // Workaround for reporting errors caused by `throw 'some string'` - // Unfortunately there is no way to figure out the stacktrace in this - // case, so if you ended up here trying to trace an error, look for - // `throw ''` somewhere in your codebase. - error = new SyntheticError(e); - } - try { - inExceptionHandler = true; - /* $FlowFixMe[class-object-subtyping] added when improving typing for this - * parameters */ - // $FlowFixMe[incompatible-call] - reportException(error, isFatal, /*reportToConsole*/ true); - } finally { - inExceptionHandler = false; + // TODO(T196834299): We should really use a c++ turbomodule for this + if (!global.RN$handleException || !global.RN$handleException(e, isFatal)) { + let error: Error; + if (e instanceof Error) { + error = e; + } else { + // Workaround for reporting errors caused by `throw 'some string'` + // Unfortunately there is no way to figure out the stacktrace in this + // case, so if you ended up here trying to trace an error, look for + // `throw ''` somewhere in your codebase. + error = new SyntheticError(e); + } + try { + inExceptionHandler = true; + /* $FlowFixMe[class-object-subtyping] added when improving typing for this + * parameters */ + // $FlowFixMe[incompatible-call] + reportException(error, isFatal, /*reportToConsole*/ true); + } finally { + inExceptionHandler = false; + } } } diff --git a/packages/react-native/Libraries/Core/__mocks__/NativeExceptionsManager.js b/packages/react-native/Libraries/Core/__mocks__/NativeExceptionsManager.js index a43017ce012eee..cfe7f55e61b119 100644 --- a/packages/react-native/Libraries/Core/__mocks__/NativeExceptionsManager.js +++ b/packages/react-native/Libraries/Core/__mocks__/NativeExceptionsManager.js @@ -14,7 +14,6 @@ import typeof NativeExceptionsManager from '../NativeExceptionsManager'; export default ({ reportFatalException: jest.fn(), reportSoftException: jest.fn(), - updateExceptionMessage: jest.fn(), dismissRedbox: jest.fn(), reportException: jest.fn(), }: NativeExceptionsManager); diff --git a/packages/react-native/Libraries/Core/__tests__/ExceptionsManager-test.js b/packages/react-native/Libraries/Core/__tests__/ExceptionsManager-test.js index 2dde1759c3df05..ee4bf4ebfb66ee 100644 --- a/packages/react-native/Libraries/Core/__tests__/ExceptionsManager-test.js +++ b/packages/react-native/Libraries/Core/__tests__/ExceptionsManager-test.js @@ -67,8 +67,6 @@ function runExceptionsManagerTests() { return { default: { reportException: jest.fn(), - // Used to show symbolicated messages, not part of this test. - updateExceptionMessage: () => {}, }, }; }); diff --git a/packages/react-native/Libraries/Core/setUpErrorHandling.js b/packages/react-native/Libraries/Core/setUpErrorHandling.js index d1aaad73794060..32846d42f83506 100644 --- a/packages/react-native/Libraries/Core/setUpErrorHandling.js +++ b/packages/react-native/Libraries/Core/setUpErrorHandling.js @@ -21,13 +21,7 @@ ExceptionsManager.installConsoleErrorReporter(); if (!global.__fbDisableExceptionsManager) { const handleError = (e: mixed, isFatal: boolean) => { try { - // TODO(T196834299): We should really use a c++ turbomodule for this - if ( - !global.RN$handleException || - !global.RN$handleException(e, isFatal) - ) { - ExceptionsManager.handleException(e, isFatal); - } + ExceptionsManager.handleException(e, isFatal); } catch (ee) { console.log('Failed to print error: ', ee.message); throw e; diff --git a/packages/react-native/Libraries/Core/setUpTimers.js b/packages/react-native/Libraries/Core/setUpTimers.js index 43481c931cdd4b..486ff03646cef8 100644 --- a/packages/react-native/Libraries/Core/setUpTimers.js +++ b/packages/react-native/Libraries/Core/setUpTimers.js @@ -21,6 +21,25 @@ if (__DEV__) { } } +const isEventLoopEnabled = (() => { + if (NativeReactNativeFeatureFlags == null) { + return false; + } + + if (NativeReactNativeFeatureFlags.disableEventLoopOnBridgeless == null) { + // Flags not unified yet + return ( + ReactNativeFeatureFlags.useModernRuntimeScheduler() && + ReactNativeFeatureFlags.enableMicrotasks() + ); + } else { + return ( + ReactNativeFeatureFlags.enableBridgelessArchitecture() && + !ReactNativeFeatureFlags.disableEventLoopOnBridgeless() + ); + } +})(); + // In bridgeless mode, timers are host functions installed from cpp. if (global.RN$Bridgeless !== true) { /** @@ -48,12 +67,7 @@ if (global.RN$Bridgeless !== true) { defineLazyTimer('cancelAnimationFrame'); defineLazyTimer('requestIdleCallback'); defineLazyTimer('cancelIdleCallback'); -} else if ( - // TODO remove this condition when bridgeless == modern scheduler everywhere. - NativeReactNativeFeatureFlags != null && - // eslint-disable-next-line react-hooks/rules-of-hooks -- false positive due to `use` prefix - ReactNativeFeatureFlags.useModernRuntimeScheduler() -) { +} else if (isEventLoopEnabled) { polyfillGlobal( 'requestIdleCallback', () => @@ -72,10 +86,7 @@ if (global.RN$Bridgeless !== true) { // We need to check if the native module is available before accessing the // feature flag, because otherwise the API would throw an error in the legacy // architecture in OSS, where the native module isn't available. -if ( - NativeReactNativeFeatureFlags != null && - ReactNativeFeatureFlags.enableMicrotasks() -) { +if (isEventLoopEnabled) { // This is the flag that tells React to use `queueMicrotask` to batch state // updates, instead of using the scheduler to schedule a regular task. // We use a global variable because we don't currently have any other diff --git a/packages/react-native/Libraries/Image/Image.android.js b/packages/react-native/Libraries/Image/Image.android.js index 4fa0bdc087a1ce..998270b1cfc3be 100644 --- a/packages/react-native/Libraries/Image/Image.android.js +++ b/packages/react-native/Libraries/Image/Image.android.js @@ -166,11 +166,9 @@ let BaseImage: AbstractImageAndroid = React.forwardRef( sources = [source]; } - const {height, width, ...restProps} = props; - const {onLoadStart, onLoad, onLoadEnd, onError} = props; const nativeProps = { - ...restProps, + ...props, style, shouldNotifyLoadEvents: !!(onLoadStart || onLoad || onLoadEnd || onError), // Both iOS and C++ sides expect to have "source" prop, whereas on Android it's "src" diff --git a/packages/react-native/Libraries/Image/Image.ios.js b/packages/react-native/Libraries/Image/Image.ios.js index a0054db5fff72e..b3b9e61e50b9ba 100644 --- a/packages/react-native/Libraries/Image/Image.ios.js +++ b/packages/react-native/Libraries/Image/Image.ios.js @@ -145,9 +145,7 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => { 'aria-disabled': ariaDisabled, 'aria-expanded': ariaExpanded, 'aria-selected': ariaSelected, - height, src, - width, ...restProps } = props; diff --git a/packages/react-native/Libraries/Inspector/Inspector.js b/packages/react-native/Libraries/Inspector/Inspector.js index e05ebde6e84dcb..d18216df0b1fbb 100644 --- a/packages/react-native/Libraries/Inspector/Inspector.js +++ b/packages/react-native/Libraries/Inspector/Inspector.js @@ -17,6 +17,7 @@ import type { } from '../Renderer/shims/ReactNativeTypes'; import type {ViewStyleProp} from '../StyleSheet/StyleSheet'; import type {ReactDevToolsAgent} from '../Types/ReactDevToolsTypes'; + import SafeAreaView from '../../src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE'; const View = require('../Components/View/View'); diff --git a/packages/react-native/Libraries/Lists/SectionListModern.js b/packages/react-native/Libraries/Lists/SectionListModern.js index 7f93d04f0bae7b..788eead2c914ed 100644 --- a/packages/react-native/Libraries/Lists/SectionListModern.js +++ b/packages/react-native/Libraries/Lists/SectionListModern.js @@ -16,7 +16,7 @@ import type { SectionBase as _SectionBase, VirtualizedSectionListProps, } from '@react-native/virtualized-lists'; -import type {AbstractComponent, ElementRef} from 'react'; +import type {ElementRef} from 'react'; import Platform from '../Utilities/Platform'; import {VirtualizedSectionList} from '@react-native/virtualized-lists'; @@ -93,7 +93,7 @@ type OptionalProps> = {| removeClippedSubviews?: boolean, |}; -export type Props = {| +export type Props> = $ReadOnly<{| ...$Diff< VirtualizedSectionListProps, { @@ -115,7 +115,7 @@ export type Props = {| >, ...RequiredProps, ...OptionalProps, -|}; +|}>; /** * A performant interface for rendering sectioned lists, supporting the most handy features: @@ -172,10 +172,10 @@ export type Props = {| * Alternatively, you can provide a custom `keyExtractor` prop. * */ -const SectionList: AbstractComponent>, any> = forwardRef< - Props>, - any, ->((props, ref) => { +const SectionList: component( + ref?: React.RefSetter, + ...Props> +) = forwardRef>, any>((props, ref) => { const propsWithDefaults = { stickySectionHeadersEnabled: Platform.OS === 'ios', ...props, diff --git a/packages/react-native/Libraries/LogBox/Data/LogBoxData.js b/packages/react-native/Libraries/LogBox/Data/LogBoxData.js index f32af9dbb39b71..85b7cc7ecc7281 100644 --- a/packages/react-native/Libraries/LogBox/Data/LogBoxData.js +++ b/packages/react-native/Libraries/LogBox/Data/LogBoxData.js @@ -421,7 +421,7 @@ type State = $ReadOnly<{| selectedLogIndex: number, |}>; -type SubscribedComponent = React.AbstractComponent< +type SubscribedComponent = React.ComponentType< $ReadOnly<{| logs: $ReadOnlyArray, isDisabled: boolean, @@ -431,7 +431,7 @@ type SubscribedComponent = React.AbstractComponent< export function withSubscription( WrappedComponent: SubscribedComponent, -): React.AbstractComponent<{||}> { +): React.ComponentType<{||}> { class LogBoxStateSubscription extends React.Component { static getDerivedStateFromError(): {hasError: boolean} { return {hasError: true}; diff --git a/packages/react-native/Libraries/LogBox/LogBoxInspectorContainer.js b/packages/react-native/Libraries/LogBox/LogBoxInspectorContainer.js index 142cccaf44bfc2..3ffaab83616e60 100644 --- a/packages/react-native/Libraries/LogBox/LogBoxInspectorContainer.js +++ b/packages/react-native/Libraries/LogBox/LogBoxInspectorContainer.js @@ -65,4 +65,4 @@ export class _LogBoxInspectorContainer extends React.Component { export default (LogBoxData.withSubscription( _LogBoxInspectorContainer, -): React.AbstractComponent<{||}>); +): React.ComponentType<{||}>); diff --git a/packages/react-native/Libraries/LogBox/LogBoxNotificationContainer.js b/packages/react-native/Libraries/LogBox/LogBoxNotificationContainer.js index 8b498cea070b38..6f3a8918592459 100644 --- a/packages/react-native/Libraries/LogBox/LogBoxNotificationContainer.js +++ b/packages/react-native/Libraries/LogBox/LogBoxNotificationContainer.js @@ -8,13 +8,13 @@ * @format */ +import SafeAreaView from '../../src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE'; import View from '../Components/View/View'; import StyleSheet from '../StyleSheet/StyleSheet'; import * as LogBoxData from './Data/LogBoxData'; import LogBoxLog from './Data/LogBoxLog'; import LogBoxLogNotification from './UI/LogBoxNotification'; import * as React from 'react'; -import SafeAreaView from '../../src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE'; type Props = $ReadOnly<{| logs: $ReadOnlyArray, @@ -102,4 +102,4 @@ const styles = StyleSheet.create({ export default (LogBoxData.withSubscription( _LogBoxNotificationContainer, -): React.AbstractComponent<{||}>); +): React.ComponentType<{||}>); diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js index 5637d6ae9efc4d..35a60c70026ca2 100644 --- a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js @@ -27,7 +27,7 @@ type Props = $ReadOnly<{ level: LogLevel, }>; -const LogBoxInspectorHeaderSafeArea: React.AbstractComponent = +const LogBoxInspectorHeaderSafeArea: React.ComponentType = Platform.OS === 'android' ? View : SafeAreaView; export default function LogBoxInspectorHeader(props: Props): React.Node { diff --git a/packages/react-native/Libraries/LogBox/__tests__/LogBox-integration-test.js b/packages/react-native/Libraries/LogBox/__tests__/LogBox-integration-test.js index 1e64e5e11efd8d..00dd5859fc228e 100644 --- a/packages/react-native/Libraries/LogBox/__tests__/LogBox-integration-test.js +++ b/packages/react-native/Libraries/LogBox/__tests__/LogBox-integration-test.js @@ -16,11 +16,10 @@ import { } from './__fixtures__/ReactWarningFixtures'; import * as React from 'react'; +const ExceptionsManager = require('../../Core/ExceptionsManager.js'); const LogBoxData = require('../Data/LogBoxData'); const TestRenderer = require('react-test-renderer'); -const ExceptionsManager = require('../../Core/ExceptionsManager.js'); - const installLogBox = () => { const LogBox = require('../LogBox').default; LogBox.install(); diff --git a/packages/react-native/Libraries/LogBox/__tests__/LogBox-test.js b/packages/react-native/Libraries/LogBox/__tests__/LogBox-test.js index 86d909f269c2b5..79e611c9fe84d4 100644 --- a/packages/react-native/Libraries/LogBox/__tests__/LogBox-test.js +++ b/packages/react-native/Libraries/LogBox/__tests__/LogBox-test.js @@ -11,9 +11,9 @@ 'use strict'; +const ExceptionsManager = require('../../Core/ExceptionsManager.js'); const LogBoxData = require('../Data/LogBoxData'); const LogBox = require('../LogBox').default; -const ExceptionsManager = require('../../Core/ExceptionsManager.js'); declare var console: any; diff --git a/packages/react-native/Libraries/Modal/Modal.js b/packages/react-native/Libraries/Modal/Modal.js index 303e3ea3b9a1e9..cc0a0622ff6b36 100644 --- a/packages/react-native/Libraries/Modal/Modal.js +++ b/packages/react-native/Libraries/Modal/Modal.js @@ -224,6 +224,9 @@ class Modal extends React.Component { } componentWillUnmount() { + if (Platform.OS === 'ios') { + this.setState({isRendered: false}); + } if (this._eventSubscription) { this._eventSubscription.remove(); } @@ -339,8 +342,7 @@ const styles = StyleSheet.create({ }, }); -const ExportedModal: React.AbstractComponent< - React.ElementConfig, -> = ModalInjection.unstable_Modal ?? Modal; +const ExportedModal: React.ComponentType> = + ModalInjection.unstable_Modal ?? Modal; module.exports = ExportedModal; diff --git a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js index 3c7aedb1948900..0fc6e8dc2d71c5 100644 --- a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js +++ b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js @@ -294,6 +294,71 @@ const validAttributesForNonEventProps = { style: ReactNativeStyleAttributes, experimental_layoutConformance: true, + + // ReactClippingViewManager @ReactProps + removeClippedSubviews: true, + + // ReactViewManager @ReactProps + accessible: true, + hasTVPreferredFocus: true, + nextFocusDown: true, + nextFocusForward: true, + nextFocusLeft: true, + nextFocusRight: true, + nextFocusUp: true, + + borderRadius: true, + borderTopLeftRadius: true, + borderTopRightRadius: true, + borderBottomRightRadius: true, + borderBottomLeftRadius: true, + borderTopStartRadius: true, + borderTopEndRadius: true, + borderBottomStartRadius: true, + borderBottomEndRadius: true, + borderEndEndRadius: true, + borderEndStartRadius: true, + borderStartEndRadius: true, + borderStartStartRadius: true, + borderStyle: true, + hitSlop: true, + pointerEvents: true, + nativeBackgroundAndroid: true, + nativeForegroundAndroid: true, + needsOffscreenAlphaCompositing: true, + + borderColor: { + process: require('../StyleSheet/processColor').default, + }, + borderLeftColor: { + process: require('../StyleSheet/processColor').default, + }, + borderRightColor: { + process: require('../StyleSheet/processColor').default, + }, + borderTopColor: { + process: require('../StyleSheet/processColor').default, + }, + borderBottomColor: { + process: require('../StyleSheet/processColor').default, + }, + borderStartColor: { + process: require('../StyleSheet/processColor').default, + }, + borderEndColor: { + process: require('../StyleSheet/processColor').default, + }, + borderBlockColor: { + process: require('../StyleSheet/processColor').default, + }, + borderBlockEndColor: { + process: require('../StyleSheet/processColor').default, + }, + borderBlockStartColor: { + process: require('../StyleSheet/processColor').default, + }, + focusable: true, + backfaceVisibility: true, }; // Props for bubbling and direct events diff --git a/packages/react-native/Libraries/NativeComponent/NativeComponentRegistry.js b/packages/react-native/Libraries/NativeComponent/NativeComponentRegistry.js index 68695660da1312..a8842884bf6807 100644 --- a/packages/react-native/Libraries/NativeComponent/NativeComponentRegistry.js +++ b/packages/react-native/Libraries/NativeComponent/NativeComponentRegistry.js @@ -48,7 +48,7 @@ export function setRuntimeConfigProvider( * The supplied `viewConfigProvider` may or may not be invoked and utilized, * depending on how `setRuntimeConfigProvider` is configured. */ -export function get( +export function get( name: string, viewConfigProvider: () => PartialViewConfig, ): HostComponent { @@ -121,10 +121,10 @@ export function get( * that the return value of this is not `HostComponent` because the returned * component instance is not guaranteed to have native methods. */ -export function getWithFallback_DEPRECATED( +export function getWithFallback_DEPRECATED( name: string, viewConfigProvider: () => PartialViewConfig, -): React.AbstractComponent { +): React.ComponentType { if (getRuntimeConfig == null) { // `getRuntimeConfig == null` when static view configs are disabled // If `setRuntimeConfigProvider` is not configured, use native reflection. diff --git a/packages/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js b/packages/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js index fa9497607b4423..3a1964886a5e15 100644 --- a/packages/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js +++ b/packages/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js @@ -88,7 +88,7 @@ const PERMISSIONS = Object.freeze({ */ class PermissionsAndroid { - PERMISSIONS: {| + PERMISSIONS: $ReadOnly<{| ACCEPT_HANDOVER: string, ACCESS_BACKGROUND_LOCATION: string, ACCESS_COARSE_LOCATION: string, @@ -132,12 +132,12 @@ class PermissionsAndroid { WRITE_CALL_LOG: string, WRITE_CONTACTS: string, WRITE_EXTERNAL_STORAGE: string, - |} = PERMISSIONS; - RESULTS: {| + |}> = PERMISSIONS; + RESULTS: $ReadOnly<{| DENIED: 'denied', GRANTED: 'granted', NEVER_ASK_AGAIN: 'never_ask_again', - |} = PERMISSION_REQUEST_RESULT; + |}> = PERMISSION_REQUEST_RESULT; /** * DEPRECATED - use check diff --git a/packages/react-native/Libraries/ReactNative/AppContainer.js b/packages/react-native/Libraries/ReactNative/AppContainer.js index 91a51cd8f48a31..afea7ca8631d01 100644 --- a/packages/react-native/Libraries/ReactNative/AppContainer.js +++ b/packages/react-native/Libraries/ReactNative/AppContainer.js @@ -24,7 +24,7 @@ export type Props = $ReadOnly<{| internal_excludeInspector?: boolean, |}>; -const AppContainer: React.AbstractComponent = __DEV__ +const AppContainer: component(...Props) = __DEV__ ? require('./AppContainer-dev').default : require('./AppContainer-prod').default; diff --git a/packages/react-native/Libraries/ReactNative/AppRegistry.js b/packages/react-native/Libraries/ReactNative/AppRegistry.js index 29c12fc109d5bf..79e2bdc97d50ae 100644 --- a/packages/react-native/Libraries/ReactNative/AppRegistry.js +++ b/packages/react-native/Libraries/ReactNative/AppRegistry.js @@ -13,8 +13,8 @@ import type {RootTag} from '../Types/RootTagTypes'; import type {IPerformanceLogger} from '../Utilities/createPerformanceLogger'; import type {DisplayModeType} from './DisplayMode'; -import registerCallableModule from '../Core/registerCallableModule'; import BugReporting from '../BugReporting/BugReporting'; +import registerCallableModule from '../Core/registerCallableModule'; import createPerformanceLogger from '../Utilities/createPerformanceLogger'; import infoLog from '../Utilities/infoLog'; import SceneTracker from '../Utilities/SceneTracker'; diff --git a/packages/react-native/Libraries/ReactNative/DisplayMode.js b/packages/react-native/Libraries/ReactNative/DisplayMode.js index 2bf55dc6976ea5..4de3035833b69b 100644 --- a/packages/react-native/Libraries/ReactNative/DisplayMode.js +++ b/packages/react-native/Libraries/ReactNative/DisplayMode.js @@ -12,7 +12,7 @@ export opaque type DisplayModeType = number; /** DisplayMode should be in sync with the method displayModeToInt from * react/renderer/uimanager/primitives.h. */ -const DisplayMode: {[string]: DisplayModeType} = Object.freeze({ +const DisplayMode: {+[string]: DisplayModeType} = Object.freeze({ VISIBLE: 1, SUSPENDED: 2, HIDDEN: 3, diff --git a/packages/react-native/Libraries/ReactNative/RendererImplementation.js b/packages/react-native/Libraries/ReactNative/RendererImplementation.js index 0938d89db4c7c0..1ca9a011515d4c 100644 --- a/packages/react-native/Libraries/ReactNative/RendererImplementation.js +++ b/packages/react-native/Libraries/ReactNative/RendererImplementation.js @@ -136,8 +136,8 @@ export function isProfilingRenderer(): boolean { } export function isChildPublicInstance( - parentInstance: ReactFabricHostComponent | HostComponent, - childInstance: ReactFabricHostComponent | HostComponent, + parentInstance: ReactFabricHostComponent | HostComponent, + childInstance: ReactFabricHostComponent | HostComponent, ): boolean { return require('../Renderer/shims/ReactNative').isChildPublicInstance( parentInstance, diff --git a/packages/react-native/Libraries/ReactNative/getCachedComponentWithDebugName.js b/packages/react-native/Libraries/ReactNative/getCachedComponentWithDebugName.js index 34aaea169261c0..6b581185d1149f 100644 --- a/packages/react-native/Libraries/ReactNative/getCachedComponentWithDebugName.js +++ b/packages/react-native/Libraries/ReactNative/getCachedComponentWithDebugName.js @@ -8,11 +8,9 @@ * @format */ -import type {AbstractComponent} from 'react'; - import * as React from 'react'; -type NoopComponent = AbstractComponent<{children: React.Node}>; +type NoopComponent = component(children: React.Node); const cache: Map< string, // displayName diff --git a/packages/react-native/Libraries/ReactNative/renderApplication.js b/packages/react-native/Libraries/ReactNative/renderApplication.js index c483082f919d4c..782014a52dd584 100644 --- a/packages/react-native/Libraries/ReactNative/renderApplication.js +++ b/packages/react-native/Libraries/ReactNative/renderApplication.js @@ -23,10 +23,12 @@ import * as React from 'react'; // require BackHandler so it sets the default handler that exits the app if no listeners respond import '../Utilities/BackHandler'; -type ActivityType = React.AbstractComponent<{ - mode: 'visible' | 'hidden', - children: React.Node, -}>; +type ActivityType = component( + ...{ + mode: 'visible' | 'hidden', + children: React.Node, + } +); export default function renderApplication( RootComponent: React.ComponentType, diff --git a/packages/react-native/Libraries/ReactNative/requireNativeComponent.js b/packages/react-native/Libraries/ReactNative/requireNativeComponent.js index e9be731df0a181..42592b75d5953e 100644 --- a/packages/react-native/Libraries/ReactNative/requireNativeComponent.js +++ b/packages/react-native/Libraries/ReactNative/requireNativeComponent.js @@ -24,7 +24,9 @@ const getNativeComponentAttributes = require('./getNativeComponentAttributes'); * */ -const requireNativeComponent = (uiViewClassName: string): HostComponent => +const requireNativeComponent = ( + uiViewClassName: string, +): HostComponent => ((createReactNativeComponentClass(uiViewClassName, () => getNativeComponentAttributes(uiViewClassName), ): any): HostComponent); diff --git a/packages/react-native/Libraries/Renderer/shims/ReactNativeTypes.js b/packages/react-native/Libraries/Renderer/shims/ReactNativeTypes.js index 26ca18db040216..26ab3007d020bf 100644 --- a/packages/react-native/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/packages/react-native/Libraries/Renderer/shims/ReactNativeTypes.js @@ -7,15 +7,10 @@ * @noformat * @nolint * @flow strict - * @generated SignedSource<<9e6c8931d3b0c36d35ad5da90b721b85>> + * @generated SignedSource<<9cf3e28d6ca0299bc0bb5caa75b19556>> */ -import type { - ElementRef, - ElementType, - MixedElement, - AbstractComponent, -} from 'react'; +import type {ElementRef, ElementType, MixedElement} from 'react'; export type MeasureOnSuccessCallback = ( x: number, @@ -138,14 +133,9 @@ declare const ensureNativeMethodsAreSynced: NativeMethods; (ensureNativeMethodsAreSynced: INativeMethods); export type HostInstance = NativeMethods; -export type HostComponent = AbstractComponent; - -type SecretInternalsType = { - computeComponentStackForErrorReporting(tag: number): string, - // TODO (bvaughn) Decide which additional types to expose here? - // And how much information to fill in for the above types. - ... -}; +/*:: +export type HostComponent = component(ref: React$RefSetter, ...Config); +*/ type InspectorDataProps = $ReadOnly<{ [propName: string]: string, @@ -216,8 +206,10 @@ export type ReactNativeType = { componentOrHandle: ?(ElementRef | number), ): ?number, isChildPublicInstance( - parent: PublicInstance | HostComponent, - child: PublicInstance | HostComponent, + // eslint-disable-next-line no-undef + parent: PublicInstance | HostComponent, + // eslint-disable-next-line no-undef + child: PublicInstance | HostComponent, ): boolean, dispatchCommand( handle: HostInstance, @@ -234,7 +226,6 @@ export type ReactNativeType = { unmountComponentAtNode(containerTag: number): void, unmountComponentAtNodeAndRemoveContainer(containerTag: number): void, +unstable_batchedUpdates: (fn: (T) => void, bookkeeping: T) => void, - +__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: SecretInternalsType, ... }; diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheet.js b/packages/react-native/Libraries/StyleSheet/StyleSheet.js index b588fae9007265..c8531f9950dc3a 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheet.js +++ b/packages/react-native/Libraries/StyleSheet/StyleSheet.js @@ -170,7 +170,13 @@ if (hairlineWidth === 0) { hairlineWidth = 1 / PixelRatio.get(); } -const absoluteFill = { +const absoluteFill: { + +bottom: 0, + +left: 0, + +position: 'absolute', + +right: 0, + +top: 0, +} = { position: 'absolute', left: 0, right: 0, diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts index 88f80f23a11ff8..19ea741ae11364 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts @@ -56,7 +56,7 @@ export interface FlexStyle { borderWidth?: number | undefined; bottom?: DimensionValue | undefined; boxSizing?: 'border-box' | 'content-box' | undefined; - display?: 'none' | 'flex' | undefined; + display?: 'none' | 'flex' | 'contents' | undefined; end?: DimensionValue | undefined; flex?: number | undefined; flexBasis?: DimensionValue | undefined; diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js index d6902bc8bcd3d2..ebc1dfa98b09c7 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js @@ -58,7 +58,7 @@ type ____LayoutStyle_Internal = $ReadOnly<{ * It works similarly to `display` in CSS, but only support 'flex' and 'none'. * 'flex' is the default. */ - display?: 'none' | 'flex', + display?: 'none' | 'flex' | 'contents', /** `width` sets the width of this component. * diff --git a/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-test.js b/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-test.js index 8a649157662323..d5a90b9dff1eba 100644 --- a/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-test.js +++ b/packages/react-native/Libraries/StyleSheet/__tests__/processBackgroundImage-test.js @@ -11,6 +11,7 @@ 'use strict'; import processBackgroundImage from '../processBackgroundImage'; + const {OS} = require('../../Utilities/Platform'); const PlatformColorAndroid = require('../PlatformColorValueTypes.android').PlatformColor; diff --git a/packages/react-native/Libraries/Text/RCTTextAttributes.h b/packages/react-native/Libraries/Text/RCTTextAttributes.h index c6923928d2d224..1b72abe51df44e 100644 --- a/packages/react-native/Libraries/Text/RCTTextAttributes.h +++ b/packages/react-native/Libraries/Text/RCTTextAttributes.h @@ -9,8 +9,7 @@ #import #import - -#import "RCTTextTransform.h" +#import NS_ASSUME_NONNULL_BEGIN diff --git a/packages/react-native/Libraries/Text/RCTTextAttributes.mm b/packages/react-native/Libraries/Text/RCTTextAttributes.mm index 57283d1820a60c..43dd1f7c18ee0e 100644 --- a/packages/react-native/Libraries/Text/RCTTextAttributes.mm +++ b/packages/react-native/Libraries/Text/RCTTextAttributes.mm @@ -278,19 +278,15 @@ - (UIColor *)effectiveBackgroundColor static NSString *capitalizeText(NSString *text) { - NSArray *words = [text componentsSeparatedByString:@" "]; - NSMutableArray *newWords = [NSMutableArray new]; - NSNumberFormatter *num = [NSNumberFormatter new]; - for (NSString *item in words) { - NSString *word; - if ([item length] > 0 && [num numberFromString:[item substringWithRange:NSMakeRange(0, 1)]] == nil) { - word = [item capitalizedString]; - } else { - word = [item lowercaseString]; - } - [newWords addObject:word]; - } - return [newWords componentsJoinedByString:@" "]; + NSMutableString *result = [[NSMutableString alloc] initWithString:text]; + [result + enumerateSubstringsInRange:NSMakeRange(0, text.length) + options:NSStringEnumerationByWords + usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { + [result replaceCharactersInRange:NSMakeRange(substringRange.location, 1) + withString:[[substring substringToIndex:1] uppercaseString]]; + }]; + return result; } - (NSString *)applyTextAttributesToText:(NSString *)text diff --git a/packages/react-native/Libraries/Utilities/codegenNativeComponent.js b/packages/react-native/Libraries/Utilities/codegenNativeComponent.js index 3f9187f8fe173a..cd2d9ee5998fa2 100644 --- a/packages/react-native/Libraries/Utilities/codegenNativeComponent.js +++ b/packages/react-native/Libraries/Utilities/codegenNativeComponent.js @@ -31,7 +31,7 @@ export type NativeComponentType = HostComponent; // `requireNativeComponent` is not available in Bridgeless mode. // e.g. This function runs at runtime if `codegenNativeComponent` was not called // from a file suffixed with NativeComponent.js. -function codegenNativeComponent( +function codegenNativeComponent( componentName: string, options?: Options, ): NativeComponentType { diff --git a/packages/react-native/Libraries/__flowtests__/ReactNativeTypes-flowtest.js b/packages/react-native/Libraries/__flowtests__/ReactNativeTypes-flowtest.js index a6fdb2d1cd8ea0..18b72069229db7 100644 --- a/packages/react-native/Libraries/__flowtests__/ReactNativeTypes-flowtest.js +++ b/packages/react-native/Libraries/__flowtests__/ReactNativeTypes-flowtest.js @@ -17,7 +17,7 @@ import * as React from 'react'; function takesHostComponentInstance(instance: HostInstance | null): void {} -const MyHostComponent = (('Host': any): HostComponent); +const MyHostComponent = (('Host': any): HostComponent<{...}>); { diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 2a3e150a95c615..be62dda6a61b79 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -744,22 +744,22 @@ export type StrictAnimatedProps = $ReadOnly<{ export type AnimatedComponentType< Props: { ... }, +Instance = mixed, -> = React.AbstractComponent, Instance>; +> = component(ref: React.RefSetter, ...AnimatedProps); export type StrictAnimatedComponentType< Props: { ... }, +Instance = mixed, -> = React.AbstractComponent, Instance>; +> = component(ref: React.RefSetter, ...StrictAnimatedProps); declare export default function createAnimatedComponent< TProps: { ... }, TInstance, >( - Component: React.AbstractComponent + Component: component(ref: React.RefSetter, ...TProps) ): AnimatedComponentType; declare export function unstable_createAnimatedComponentWithAllowlist< TProps: { ... }, TInstance, >( - Component: React.AbstractComponent, + Component: component(ref: React.RefSetter, ...TProps), allowlist: ?AnimatedPropsAllowlist ): StrictAnimatedComponentType; " @@ -1658,7 +1658,7 @@ type Props = $ReadOnly<{| size?: ?IndicatorSize, |}>; declare const ActivityIndicatorWithRef: component( - ref: React.RefSetter>, + ref: React.RefSetter>, ...props: Props ); declare export default typeof ActivityIndicatorWithRef; @@ -2084,10 +2084,12 @@ type AndroidProps = $ReadOnly<{| persistentScrollbar?: ?boolean, fadingEdgeLength?: ?number, |}>; -type StickyHeaderComponentType = React.AbstractComponent< - ScrollViewStickyHeaderProps, - $ReadOnly void }>, ->; +type StickyHeaderComponentType = component( + ref?: React.RefSetter< + $ReadOnly void }>, + >, + ...ScrollViewStickyHeaderProps +); export type Props = $ReadOnly<{| ...ViewProps, ...IOSProps, @@ -2267,7 +2269,7 @@ declare module.exports: typeof Wrapper & ScrollViewComponentStatics; `; exports[`public API should not change unintentionally Libraries/Components/ScrollView/ScrollViewCommands.js 1`] = ` -"type ScrollViewNativeComponentType = HostComponent; +"type ScrollViewNativeComponentType = HostComponent<{ ... }>; interface NativeCommands { +flashScrollIndicators: ( viewRef: React.ElementRef @@ -2751,7 +2753,7 @@ exports[`public API should not change unintentionally Libraries/Components/TextI style?: ?ViewStyleProp, backgroundColor?: ?ColorValue, |}>; -declare const InputAccessoryView: React.AbstractComponent; +declare const InputAccessoryView: React.ComponentType; declare export default typeof InputAccessoryView; " `; @@ -2763,20 +2765,20 @@ declare export default typeof RCTInputAccessoryViewNativeComponent; `; exports[`public API should not change unintentionally Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js 1`] = ` -"type NativeType = HostComponent; +"type NativeType = HostComponent<{ ... }>; type NativeCommands = TextInputNativeCommands; declare export const Commands: NativeCommands; declare export const __INTERNAL_VIEW_CONFIG: PartialViewConfig; -declare export default HostComponent; +declare export default HostComponent<{ ... }>; " `; exports[`public API should not change unintentionally Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js 1`] = ` -"type NativeType = HostComponent; +"type NativeType = HostComponent<{ ... }>; type NativeCommands = TextInputNativeCommands; declare export const Commands: NativeCommands; declare export const __INTERNAL_VIEW_CONFIG: PartialViewConfig; -declare export default HostComponent; +declare export default HostComponent<{ ... }>; " `; @@ -3119,7 +3121,10 @@ type ImperativeMethods = $ReadOnly<{| getNativeRef: () => ?HostInstance, setSelection: (start: number, end: number) => void, |}>; -type InternalTextInput = (props: Props) => React.Node; +type InternalTextInput = component( + ref: React.RefSetter<$ReadOnly<{ ...HostInstance, ...ImperativeMethods }>>, + ...Props +); export type TextInputComponentStatics = $ReadOnly<{| State: $ReadOnly<{| currentlyFocusedInput: () => ?HostInstance, @@ -3128,14 +3133,7 @@ export type TextInputComponentStatics = $ReadOnly<{| blurTextInput: (textField: ?HostInstance) => void, |}>, |}>; -export type TextInputType = React.AbstractComponent< - React.ElementConfig, - $ReadOnly<{| - ...HostInstance, - ...ImperativeMethods, - |}>, -> & - TextInputComponentStatics; +export type TextInputType = InternalTextInput & TextInputComponentStatics; " `; @@ -4071,8 +4069,7 @@ export type AccessibilityValue = $ReadOnly<{| `; exports[`public API should not change unintentionally Libraries/Components/View/ViewNativeComponent.js 1`] = ` -"declare export const __INTERNAL_VIEW_CONFIG: PartialViewConfig; -declare const ViewNativeComponent: HostComponent; +"declare const ViewNativeComponent: HostComponent; interface NativeCommands { +hotspotUpdate: (viewRef: HostInstance, x: number, y: number) => void; +setPressed: (viewRef: HostInstance, pressed: boolean) => void; @@ -5843,7 +5840,7 @@ type OptionalProps> = {| onEndReached?: ?(info: { distanceFromEnd: number, ... }) => void, removeClippedSubviews?: boolean, |}; -export type Props = {| +export type Props> = $ReadOnly<{| ...$Diff< VirtualizedSectionListProps, { @@ -5865,8 +5862,11 @@ export type Props = {| >, ...RequiredProps, ...OptionalProps, -|}; -declare const SectionList: AbstractComponent>, any>; +|}>; +declare const SectionList: component( + ref?: React.RefSetter, + ...Props> +); declare export default typeof SectionList; " `; @@ -5980,7 +5980,7 @@ declare export function addIgnorePatterns( declare export function setDisabled(value: boolean): void; declare export function isDisabled(): boolean; declare export function observe(observer: Observer): Subscription; -type SubscribedComponent = React.AbstractComponent< +type SubscribedComponent = React.ComponentType< $ReadOnly<{| logs: $ReadOnlyArray, isDisabled: boolean, @@ -5989,7 +5989,7 @@ type SubscribedComponent = React.AbstractComponent< >; declare export function withSubscription( WrappedComponent: SubscribedComponent -): React.AbstractComponent<{||}>; +): React.ComponentType<{||}>; " `; @@ -6149,7 +6149,7 @@ declare export class _LogBoxInspectorContainer extends React.Component { _handleMinimize: $FlowFixMe; _handleSetSelectedLog: $FlowFixMe; } -declare export default React.AbstractComponent<{||}>; +declare export default React.ComponentType<{||}>; " `; @@ -6160,7 +6160,7 @@ exports[`public API should not change unintentionally Libraries/LogBox/LogBoxNot isDisabled?: ?boolean, |}>; declare export function _LogBoxNotificationContainer(props: Props): React.Node; -declare export default React.AbstractComponent<{||}>; +declare export default React.ComponentType<{||}>; " `; @@ -6442,7 +6442,7 @@ declare class Modal extends React.Component { render(): React.Node; _shouldSetResponder(): boolean; } -declare const ExportedModal: React.AbstractComponent< +declare const ExportedModal: React.ComponentType< React.ElementConfig, >; declare module.exports: ExportedModal; @@ -6479,14 +6479,14 @@ exports[`public API should not change unintentionally Libraries/NativeComponent/ verify: boolean, } ): void; -declare export function get( +declare export function get( name: string, viewConfigProvider: () => PartialViewConfig ): HostComponent; -declare export function getWithFallback_DEPRECATED( +declare export function getWithFallback_DEPRECATED( name: string, viewConfigProvider: () => PartialViewConfig -): React.AbstractComponent; +): React.ComponentType; declare export function unstable_hasStaticViewConfig(name: string): boolean; " `; @@ -6977,7 +6977,7 @@ exports[`public API should not change unintentionally Libraries/PermissionsAndro ... }; declare class PermissionsAndroid { - PERMISSIONS: {| + PERMISSIONS: $ReadOnly<{| ACCEPT_HANDOVER: string, ACCESS_BACKGROUND_LOCATION: string, ACCESS_COARSE_LOCATION: string, @@ -7021,12 +7021,12 @@ declare class PermissionsAndroid { WRITE_CALL_LOG: string, WRITE_CONTACTS: string, WRITE_EXTERNAL_STORAGE: string, - |}; - RESULTS: {| + |}>; + RESULTS: $ReadOnly<{| DENIED: \\"denied\\", GRANTED: \\"granted\\", NEVER_ASK_AGAIN: \\"never_ask_again\\", - |}; + |}>; checkPermission(permission: PermissionType): Promise; check(permission: PermissionType): Promise; requestPermission( @@ -7305,7 +7305,7 @@ exports[`public API should not change unintentionally Libraries/ReactNative/AppC internal_excludeLogBox?: boolean, internal_excludeInspector?: boolean, |}>; -declare const AppContainer: React.AbstractComponent; +declare const AppContainer: component(...Props); declare module.exports: AppContainer; " `; @@ -7419,7 +7419,7 @@ declare module.exports: UIManagerJS; exports[`public API should not change unintentionally Libraries/ReactNative/DisplayMode.js 1`] = ` "declare export opaque type DisplayModeType; -declare const DisplayMode: { [string]: DisplayModeType }; +declare const DisplayMode: { +[string]: DisplayModeType }; declare export function coerceDisplayMode(value: ?number): DisplayModeType; declare export default typeof DisplayMode; " @@ -7659,8 +7659,8 @@ declare export function unstable_batchedUpdates( ): void; declare export function isProfilingRenderer(): boolean; declare export function isChildPublicInstance( - parentInstance: ReactFabricHostComponent | HostComponent, - childInstance: ReactFabricHostComponent | HostComponent + parentInstance: ReactFabricHostComponent | HostComponent, + childInstance: ReactFabricHostComponent | HostComponent ): boolean; declare export function getNodeFromInternalInstanceHandle( internalInstanceHandle: InternalInstanceHandle @@ -7695,7 +7695,7 @@ exports[`public API should not change unintentionally Libraries/ReactNative/UIMa `; exports[`public API should not change unintentionally Libraries/ReactNative/getCachedComponentWithDebugName.js 1`] = ` -"type NoopComponent = AbstractComponent<{ children: React.Node }>; +"type NoopComponent = component(children: React.Node); declare export default function getCachedComponentWithDisplayName( displayName: string ): NoopComponent; @@ -7727,7 +7727,7 @@ exports[`public API should not change unintentionally Libraries/ReactNative/rend `; exports[`public API should not change unintentionally Libraries/ReactNative/requireNativeComponent.js 1`] = ` -"declare const requireNativeComponent: ( +"declare const requireNativeComponent: ( uiViewClassName: string ) => HostComponent; declare export default typeof requireNativeComponent; @@ -7889,11 +7889,11 @@ export type ImageStyle = ____ImageStyle_Internal; export type DangerouslyImpreciseStyle = ____DangerouslyImpreciseStyle_Internal; declare let hairlineWidth: number; declare const absoluteFill: { - position: \\"absolute\\", - left: 0, - right: 0, - top: 0, - bottom: 0, + +bottom: 0, + +left: 0, + +position: \\"absolute\\", + +right: 0, + +top: 0, }; declare module.exports: { hairlineWidth: hairlineWidth, @@ -7928,7 +7928,7 @@ export type DimensionValue = number | string | \\"auto\\" | AnimatedNode | null; export type AnimatableNumericValue = number | AnimatedNode; export type CursorValue = \\"auto\\" | \\"pointer\\"; type ____LayoutStyle_Internal = $ReadOnly<{ - display?: \\"none\\" | \\"flex\\", + display?: \\"none\\" | \\"flex\\" | \\"contents\\", width?: DimensionValue, height?: DimensionValue, bottom?: DimensionValue, @@ -9280,7 +9280,7 @@ exports[`public API should not change unintentionally Libraries/Utilities/codege excludedPlatforms?: $ReadOnlyArray<\\"iOS\\" | \\"android\\">, |}>; export type NativeComponentType = HostComponent; -declare function codegenNativeComponent( +declare function codegenNativeComponent( componentName: string, options?: Options ): NativeComponentType; @@ -9702,7 +9702,7 @@ declare module.exports: { get Platform(): Platform, get PlatformColor(): PlatformColor, get processColor(): processColor, - get requireNativeComponent(): ( + get requireNativeComponent(): ( uiViewClassName: string ) => HostComponent, get RootTagContext(): RootTagContext, diff --git a/packages/react-native/React-Core.podspec b/packages/react-native/React-Core.podspec index 079075e8ed49a0..285793b8e1b2c7 100644 --- a/packages/react-native/React-Core.podspec +++ b/packages/react-native/React-Core.podspec @@ -21,10 +21,10 @@ folly_compiler_flags = folly_config[:compiler_flags] folly_version = folly_config[:version] socket_rocket_config = get_socket_rocket_config() -socket_rocket_version = socket_rocket_config[:version] +socket_rocket_version = socket_rocket_config[:version] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] use_hermes = ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == '1' use_hermes_flag = use_hermes ? "-DUSE_HERMES=1" : "" @@ -50,6 +50,7 @@ header_search_paths = [ "$(PODS_TARGET_SRCROOT)/ReactCommon", "$(PODS_ROOT)/boost", "$(PODS_ROOT)/DoubleConversion", + "$(PODS_ROOT)/fast_float/include", "$(PODS_ROOT)/fmt/include", "$(PODS_ROOT)/RCT-Folly", "${PODS_ROOT}/Headers/Public/FlipperKit", diff --git a/packages/react-native/React/Base/RCTBridge.mm b/packages/react-native/React/Base/RCTBridge.mm index 9aaf79bd0b9931..e5f9b8a5982bad 100644 --- a/packages/react-native/React/Base/RCTBridge.mm +++ b/packages/react-native/React/Base/RCTBridge.mm @@ -148,16 +148,6 @@ void RCTSetTurboModuleInteropBridgeProxyLogLevel(RCTBridgeProxyLoggingLevel logL bridgeProxyLoggingLevel = logLevel; } -static BOOL useTurboModuleInteropForAllTurboModules = NO; -BOOL RCTTurboModuleInteropForAllTurboModulesEnabled(void) -{ - return useTurboModuleInteropForAllTurboModules; -} -void RCTEnableTurboModuleInteropForAllTurboModules(BOOL enabled) -{ - useTurboModuleInteropForAllTurboModules = enabled; -} - // Turn on TurboModule sync execution of void methods static BOOL gTurboModuleEnableSyncVoidMethods = NO; BOOL RCTTurboModuleSyncVoidMethodsEnabled(void) diff --git a/packages/react-native/React/CoreModules/RCTExceptionsManager.h b/packages/react-native/React/CoreModules/RCTExceptionsManager.h index f23bb2153b809e..d4b350961c5abd 100644 --- a/packages/react-native/React/CoreModules/RCTExceptionsManager.h +++ b/packages/react-native/React/CoreModules/RCTExceptionsManager.h @@ -11,7 +11,6 @@ NS_ASSUME_NONNULL_BEGIN @protocol RCTExceptionsManagerDelegate - - (void)handleSoftJSExceptionWithMessage:(nullable NSString *)message stack:(nullable NSArray *)stack exceptionId:(NSNumber *)exceptionId @@ -20,12 +19,6 @@ NS_ASSUME_NONNULL_BEGIN stack:(nullable NSArray *)stack exceptionId:(NSNumber *)exceptionId extraDataAsJSON:(nullable NSString *)extraDataAsJSON; - -@optional -- (void)updateJSExceptionWithMessage:(nullable NSString *)message - stack:(nullable NSArray *)stack - exceptionId:(NSNumber *)exceptionId; - @end @interface RCTExceptionsManager : NSObject diff --git a/packages/react-native/React/CoreModules/RCTExceptionsManager.mm b/packages/react-native/React/CoreModules/RCTExceptionsManager.mm index 7a5de3849e2b92..d7f8f647604a90 100644 --- a/packages/react-native/React/CoreModules/RCTExceptionsManager.mm +++ b/packages/react-native/React/CoreModules/RCTExceptionsManager.mm @@ -99,27 +99,6 @@ - (void)reportFatal:(NSString *)message [self reportFatal:message stack:stack exceptionId:exceptionId extraDataAsJSON:nil]; } -RCT_EXPORT_METHOD(updateExceptionMessage - : (NSString *)message stack - : (NSArray *)stack exceptionId - : (double)exceptionId) -{ - if (RCTRedBoxGetEnabled()) { - RCTRedBox *redbox = [_moduleRegistry moduleForName:"RedBox"]; - [redbox updateErrorMessage:message withStack:stack errorCookie:(int)exceptionId]; - } - - if (_delegate && [_delegate respondsToSelector:@selector(updateJSExceptionWithMessage:stack:exceptionId:)]) { - [_delegate updateJSExceptionWithMessage:message stack:stack exceptionId:[NSNumber numberWithDouble:exceptionId]]; - } -} - -// Deprecated. Use reportFatalException directly instead. -RCT_EXPORT_METHOD(reportUnhandledException : (NSString *)message stack : (NSArray *)stack) -{ - [self reportFatalException:message stack:stack exceptionId:-1]; -} - RCT_EXPORT_METHOD(dismissRedbox) {} RCT_EXPORT_METHOD(reportException : (JS::NativeExceptionsManager::ExceptionData &)data) diff --git a/packages/react-native/React/CoreModules/React-CoreModules.podspec b/packages/react-native/React/CoreModules/React-CoreModules.podspec index f85a2365f6e40f..43ef20bc2e989f 100644 --- a/packages/react-native/React/CoreModules/React-CoreModules.podspec +++ b/packages/react-native/React/CoreModules/React-CoreModules.podspec @@ -21,13 +21,14 @@ folly_compiler_flags = folly_config[:compiler_flags] folly_version = folly_config[:version] socket_rocket_config = get_socket_rocket_config() -socket_rocket_version = socket_rocket_config[:version] +socket_rocket_version = socket_rocket_config[:version] header_search_paths = [ "\"$(PODS_ROOT)/boost\"", "\"$(PODS_TARGET_SRCROOT)/React/CoreModules\"", "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"", "\"${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\"", ] @@ -47,7 +48,7 @@ Pod::Spec.new do |s| s.ios.exclude_files = "PlatformStubs/**/*" exclude_files = ["RCTStatusBarManager.mm"] - s.macos.exclude_files = exclude_files + s.macos.exclude_files = exclude_files s.visionos.exclude_files = exclude_files s.tvos.exclude_files = exclude_files @@ -59,7 +60,8 @@ Pod::Spec.new do |s| } s.framework = "UIKit" s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" s.dependency "RCT-Folly", folly_version s.dependency "RCTTypeSafety", version s.dependency "React-Core/CoreModulesHeaders", version diff --git a/packages/react-native/React/DevSupport/RCTInspectorDevServerHelper.mm b/packages/react-native/React/DevSupport/RCTInspectorDevServerHelper.mm index 0f83d9b9e5bc10..bb0bd469adb629 100644 --- a/packages/react-native/React/DevSupport/RCTInspectorDevServerHelper.mm +++ b/packages/react-native/React/DevSupport/RCTInspectorDevServerHelper.mm @@ -142,15 +142,11 @@ + (BOOL)isPackagerDisconnected + (void)openDebugger:(NSURL *)bundleURL withErrorMessage:(NSString *)errorMessage { - NSString *appId = [[[NSBundle mainBundle] bundleIdentifier] - stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet]; - NSString *escapedInspectorDeviceId = [getInspectorDeviceId() stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet]; - NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@/open-debugger?appId=%@&device=%@", + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@/open-debugger?device=%@", getServerHost(bundleURL), - appId, escapedInspectorDeviceId]]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"POST"]; diff --git a/packages/react-native/React/Fabric/AppleEventBeat.cpp b/packages/react-native/React/Fabric/AppleEventBeat.cpp new file mode 100644 index 00000000000000..f172cbcd785da5 --- /dev/null +++ b/packages/react-native/React/Fabric/AppleEventBeat.cpp @@ -0,0 +1,31 @@ +/* + * 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 "AppleEventBeat.h" + +#include + +namespace facebook::react { + +AppleEventBeat::AppleEventBeat( + std::shared_ptr ownerBox, + std::unique_ptr uiRunLoopObserver, + RuntimeExecutor runtimeExecutor) + : EventBeat(std::move(ownerBox), std::move(runtimeExecutor)), + uiRunLoopObserver_(std::move(uiRunLoopObserver)) { + uiRunLoopObserver_->setDelegate(this); + uiRunLoopObserver_->enable(); +} + +void AppleEventBeat::activityDidChange( + const RunLoopObserver::Delegate* delegate, + RunLoopObserver::Activity /*activity*/) const noexcept { + react_native_assert(delegate == this); + induce(); +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.h b/packages/react-native/React/Fabric/AppleEventBeat.h similarity index 68% rename from packages/react-native/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.h rename to packages/react-native/React/Fabric/AppleEventBeat.h index af877980b00dae..d842d4f63d6112 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.h +++ b/packages/react-native/React/Fabric/AppleEventBeat.h @@ -18,15 +18,13 @@ namespace facebook::react { * The beat is called on `RuntimeExecutor`'s thread induced by the UI thread * event loop. */ -class AsynchronousEventBeat : public EventBeat, - public RunLoopObserver::Delegate { +class AppleEventBeat : public EventBeat, public RunLoopObserver::Delegate { public: - AsynchronousEventBeat( - RunLoopObserver::Unique uiRunLoopObserver, + AppleEventBeat( + std::shared_ptr ownerBox, + std::unique_ptr uiRunLoopObserver, RuntimeExecutor runtimeExecutor); - void induce() const override; - #pragma mark - RunLoopObserver::Delegate void activityDidChange( @@ -34,10 +32,7 @@ class AsynchronousEventBeat : public EventBeat, RunLoopObserver::Activity activity) const noexcept override; private: - RunLoopObserver::Unique uiRunLoopObserver_; - RuntimeExecutor runtimeExecutor_; - - mutable std::atomic isBeatCallbackScheduled_{false}; + std::unique_ptr uiRunLoopObserver_; }; } // namespace facebook::react diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm index 665b2979a79fff..d924d3ae4a2f2e 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm @@ -16,7 +16,6 @@ #import #import #import -#import using namespace facebook::react; diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index 87983b0dbc1315..8b4b87996862e2 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -894,6 +894,8 @@ - (void)invalidateLayer _backgroundColorLayer.mask = maskLayer; _backgroundColorLayer.cornerRadius = 0; } + + [_backgroundColorLayer removeAllAnimations]; } // borders diff --git a/packages/react-native/React/Fabric/Mounting/RCTMountingManager.h b/packages/react-native/React/Fabric/Mounting/RCTMountingManager.h index 127b06fd474a67..d9b2c79bb3f87e 100644 --- a/packages/react-native/React/Fabric/Mounting/RCTMountingManager.h +++ b/packages/react-native/React/Fabric/Mounting/RCTMountingManager.h @@ -48,7 +48,7 @@ NS_ASSUME_NONNULL_BEGIN * Schedule a mounting transaction to be performed on the main thread. * Can be called from any thread. */ -- (void)scheduleTransaction:(facebook::react::MountingCoordinator::Shared)mountingCoordinator; +- (void)scheduleTransaction:(std::shared_ptr)mountingCoordinator; /** * Dispatch a command to be performed on the main thread. diff --git a/packages/react-native/React/Fabric/Mounting/RCTMountingManager.mm b/packages/react-native/React/Fabric/Mounting/RCTMountingManager.mm index ec4354583ac04f..38a304bf115923 100644 --- a/packages/react-native/React/Fabric/Mounting/RCTMountingManager.mm +++ b/packages/react-native/React/Fabric/Mounting/RCTMountingManager.mm @@ -20,7 +20,6 @@ #import #import #import -#import #import #import @@ -187,7 +186,7 @@ - (void)detachSurfaceFromView:(UIView *)view surfaceId:(SurfaceId)surfaceId componentViewDescriptor:rootViewDescriptor]; } -- (void)scheduleTransaction:(MountingCoordinator::Shared)mountingCoordinator +- (void)scheduleTransaction:(std::shared_ptr)mountingCoordinator { if (RCTIsMainQueue()) { // Already on the proper thread, so: diff --git a/packages/react-native/React/Fabric/RCTScheduler.h b/packages/react-native/React/Fabric/RCTScheduler.h index 379db1a6cbf415..f5df6a938c98cf 100644 --- a/packages/react-native/React/Fabric/RCTScheduler.h +++ b/packages/react-native/React/Fabric/RCTScheduler.h @@ -26,9 +26,10 @@ NS_ASSUME_NONNULL_BEGIN */ @protocol RCTSchedulerDelegate -- (void)schedulerDidFinishTransaction:(facebook::react::MountingCoordinator::Shared)mountingCoordinator; +- (void)schedulerDidFinishTransaction:(std::shared_ptr)mountingCoordinator; -- (void)schedulerShouldRenderTransactions:(facebook::react::MountingCoordinator::Shared)mountingCoordinator; +- (void)schedulerShouldRenderTransactions: + (std::shared_ptr)mountingCoordinator; - (void)schedulerDidDispatchCommand:(const facebook::react::ShadowView &)shadowView commandName:(const std::string &)commandName diff --git a/packages/react-native/React/Fabric/RCTScheduler.mm b/packages/react-native/React/Fabric/RCTScheduler.mm index 29ea406343dde1..016af6dd209648 100644 --- a/packages/react-native/React/Fabric/RCTScheduler.mm +++ b/packages/react-native/React/Fabric/RCTScheduler.mm @@ -26,13 +26,13 @@ public: SchedulerDelegateProxy(void *scheduler) : scheduler_(scheduler) {} - void schedulerDidFinishTransaction(const MountingCoordinator::Shared &mountingCoordinator) override + void schedulerDidFinishTransaction(const std::shared_ptr &mountingCoordinator) override { RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_; [scheduler.delegate schedulerDidFinishTransaction:mountingCoordinator]; } - void schedulerShouldRenderTransactions(const MountingCoordinator::Shared &mountingCoordinator) override + void schedulerShouldRenderTransactions(const std::shared_ptr &mountingCoordinator) override { RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_; [scheduler.delegate schedulerShouldRenderTransactions:mountingCoordinator]; @@ -106,9 +106,9 @@ void activityDidChange(const RunLoopObserver::Delegate *delegate, RunLoopObserve @implementation RCTScheduler { std::unique_ptr _scheduler; std::shared_ptr _animationDriver; - std::shared_ptr _delegateProxy; + std::unique_ptr _delegateProxy; std::shared_ptr _layoutAnimationDelegateProxy; - RunLoopObserver::Unique _uiRunLoopObserver; + std::unique_ptr _uiRunLoopObserver; } - (instancetype)initWithToolbox:(SchedulerToolbox)toolbox @@ -117,7 +117,7 @@ - (instancetype)initWithToolbox:(SchedulerToolbox)toolbox auto reactNativeConfig = toolbox.contextContainer->at>("ReactNativeConfig"); - _delegateProxy = std::make_shared((__bridge void *)self); + _delegateProxy = std::make_unique((__bridge void *)self); if (ReactNativeFeatureFlags::enableLayoutAnimationsOnIOS()) { _layoutAnimationDelegateProxy = std::make_shared((__bridge void *)self); diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm index 5d24d70de628c4..b3c6340765f105 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm +++ b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm @@ -31,11 +31,10 @@ #import #import #import -#import #import #import -#import #import +#import "AppleEventBeat.h" #import "PlatformRunLoopObserver.h" #import "RCTConversions.h" @@ -229,10 +228,6 @@ - (RCTScheduler *)_createScheduler { auto reactNativeConfig = _contextContainer->at>("ReactNativeConfig"); - if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_cpp_props_iterator_setter_ios")) { - CoreFeatures::enablePropIteratorSetter = true; - } - auto componentRegistryFactory = [factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)]( const EventDispatcher::Weak &eventDispatcher, const ContextContainer::Shared &contextContainer) { @@ -257,11 +252,11 @@ - (RCTScheduler *)_createScheduler toolbox.runtimeExecutor = runtimeExecutor; toolbox.bridgelessBindingsExecutor = _bridgelessBindingsExecutor; - toolbox.asynchronousEventBeatFactory = - [runtimeExecutor](const EventBeat::SharedOwnerBox &ownerBox) -> std::unique_ptr { + toolbox.eventBeatFactory = + [runtimeExecutor](std::shared_ptr ownerBox) -> std::unique_ptr { auto runLoopObserver = std::make_unique(RunLoopObserver::Activity::BeforeWaiting, ownerBox->owner); - return std::make_unique(std::move(runLoopObserver), runtimeExecutor); + return std::make_unique(std::move(ownerBox), std::move(runLoopObserver), runtimeExecutor); }; RCTScheduler *scheduler = [[RCTScheduler alloc] initWithToolbox:toolbox]; @@ -297,12 +292,12 @@ - (void)_applicationWillTerminate #pragma mark - RCTSchedulerDelegate -- (void)schedulerDidFinishTransaction:(MountingCoordinator::Shared)mountingCoordinator +- (void)schedulerDidFinishTransaction:(std::shared_ptr)mountingCoordinator { // no-op, we will flush the transaction from schedulerShouldRenderTransactions } -- (void)schedulerShouldRenderTransactions:(MountingCoordinator::Shared)mountingCoordinator +- (void)schedulerShouldRenderTransactions:(std::shared_ptr)mountingCoordinator { [_mountingManager scheduleTransaction:mountingCoordinator]; } diff --git a/packages/react-native/React/Fabric/Utils/PlatformRunLoopObserver.h b/packages/react-native/React/Fabric/Utils/PlatformRunLoopObserver.h index d8e456619a2857..4f097aaac50695 100644 --- a/packages/react-native/React/Fabric/Utils/PlatformRunLoopObserver.h +++ b/packages/react-native/React/Fabric/Utils/PlatformRunLoopObserver.h @@ -22,7 +22,7 @@ class PlatformRunLoopObserver : public RunLoopObserver { public: PlatformRunLoopObserver( RunLoopObserver::Activity activities, - const RunLoopObserver::WeakOwner& owner, + RunLoopObserver::WeakOwner owner, CFRunLoopRef runLoop); ~PlatformRunLoopObserver(); @@ -45,8 +45,11 @@ class MainRunLoopObserver final : public PlatformRunLoopObserver { public: MainRunLoopObserver( RunLoopObserver::Activity activities, - const RunLoopObserver::WeakOwner& owner) - : PlatformRunLoopObserver(activities, owner, CFRunLoopGetMain()) {} + RunLoopObserver::WeakOwner owner) + : PlatformRunLoopObserver( + activities, + std::move(owner), + CFRunLoopGetMain()) {} }; } // namespace facebook::react diff --git a/packages/react-native/React/Fabric/Utils/PlatformRunLoopObserver.mm b/packages/react-native/React/Fabric/Utils/PlatformRunLoopObserver.mm index d243c8f912ad40..65f48b48a4f6c6 100644 --- a/packages/react-native/React/Fabric/Utils/PlatformRunLoopObserver.mm +++ b/packages/react-native/React/Fabric/Utils/PlatformRunLoopObserver.mm @@ -45,13 +45,10 @@ static CFRunLoopActivity toCFRunLoopActivity(RunLoopObserver::Activity activity) PlatformRunLoopObserver::PlatformRunLoopObserver( RunLoopObserver::Activity activities, - const RunLoopObserver::WeakOwner &owner, + RunLoopObserver::WeakOwner owner, CFRunLoopRef runLoop) : RunLoopObserver(activities, owner), runLoop_(runLoop) { - // A value (not a reference) to be captured by the block. - auto weakOwner = owner; - // The documentation for `CFRunLoop` family API states that all of the methods are thread-safe. // See "Thread Safety and Run Loop Objects" section of the "Threading Programming Guide" for more details. mainRunLoopObserver_ = CFRunLoopObserverCreateWithHandler( @@ -60,7 +57,7 @@ static CFRunLoopActivity toCFRunLoopActivity(RunLoopObserver::Activity activity) true /* repeats */, 0 /* order */, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { - auto strongOwner = weakOwner.lock(); + auto strongOwner = owner.lock(); if (!strongOwner) { return; } diff --git a/packages/react-native/React/Inspector/RCTCxxInspectorWebSocketAdapter.mm b/packages/react-native/React/Inspector/RCTCxxInspectorWebSocketAdapter.mm index 46cfb11fa1c817..a7a2fcbd9f7c1b 100644 --- a/packages/react-native/React/Inspector/RCTCxxInspectorWebSocketAdapter.mm +++ b/packages/react-native/React/Inspector/RCTCxxInspectorWebSocketAdapter.mm @@ -50,7 +50,7 @@ - (void)send:(std::string_view)message dispatch_async(dispatch_get_main_queue(), ^{ RCTCxxInspectorWebSocketAdapter *strongSelf = weakSelf; if (strongSelf) { - [strongSelf->_webSocket send:messageStr]; + [strongSelf->_webSocket sendString:messageStr error:NULL]; } }); } diff --git a/packages/react-native/React/React-RCTFabric.podspec b/packages/react-native/React/React-RCTFabric.podspec index 1ba879da33c693..c80fe3568ac20b 100644 --- a/packages/react-native/React/React-RCTFabric.podspec +++ b/packages/react-native/React/React-RCTFabric.podspec @@ -20,13 +20,14 @@ folly_config = get_folly_config() folly_compiler_flags = folly_config[:compiler_flags] folly_version = folly_config[:version] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] new_arch_flags = ENV['RCT_NEW_ARCH_ENABLED'] == '1' ? ' -DRCT_NEW_ARCH_ENABLED=1' : '' header_search_paths = [ "\"$(PODS_TARGET_SRCROOT)/ReactCommon\"", "\"$(PODS_ROOT)/boost\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"", "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/Headers/Private/React-Core\"", diff --git a/packages/react-native/React/Tests/Text/RCTTextAttributesTest.mm b/packages/react-native/React/Tests/Text/RCTTextAttributesTest.mm new file mode 100644 index 00000000000000..227cd12beb4335 --- /dev/null +++ b/packages/react-native/React/Tests/Text/RCTTextAttributesTest.mm @@ -0,0 +1,49 @@ +/* + * 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. + */ + +#import +#import + +#import + +@interface RCTTextAttributesTest : XCTestCase + +@end + +@implementation RCTTextAttributesTest + +- (void)testCapitalize +{ + RCTTextAttributes *attrs = [RCTTextAttributes new]; + attrs.textTransform = RCTTextTransformCapitalize; + + NSString *input = @"hello WORLD from ReAcT nAtIvE 2a !b c"; + NSString *output = @"Hello WORLD From ReAcT NAtIvE 2a !B C"; + XCTAssertEqualObjects([attrs applyTextAttributesToText:input], output); +} + +- (void)testUppercase +{ + RCTTextAttributes *attrs = [RCTTextAttributes new]; + attrs.textTransform = RCTTextTransformUppercase; + + NSString *input = @"hello WORLD from ReAcT nAtIvE 2a !b c"; + NSString *output = @"HELLO WORLD FROM REACT NATIVE 2A !B C"; + XCTAssertEqualObjects([attrs applyTextAttributesToText:input], output); +} + +- (void)testLowercase +{ + RCTTextAttributes *attrs = [RCTTextAttributes new]; + attrs.textTransform = RCTTextTransformLowercase; + + NSString *input = @"hello WORLD from ReAcT nAtIvE 2a !b c"; + NSString *output = @"hello world from react native 2a !b c"; + XCTAssertEqualObjects([attrs applyTextAttributesToText:input], output); +} + +@end diff --git a/packages/react-native/React/Views/RCTLayout.m b/packages/react-native/React/Views/RCTLayout.m index e11d7e4b8189a9..85c8994511a032 100644 --- a/packages/react-native/React/Views/RCTLayout.m +++ b/packages/react-native/React/Views/RCTLayout.m @@ -132,5 +132,8 @@ RCTDisplayType RCTReactDisplayTypeFromYogaDisplayType(YGDisplay displayType) return RCTDisplayTypeFlex; case YGDisplayNone: return RCTDisplayTypeNone; + case YGDisplayContents: + RCTAssert(NO, @"YGDisplayContents cannot be converted to RCTDisplayType value."); + return RCTDisplayTypeNone; } } diff --git a/packages/react-native/React/third-party.xcconfig b/packages/react-native/React/third-party.xcconfig index 273b6c537714cb..137c6a5da00e9f 100644 --- a/packages/react-native/React/third-party.xcconfig +++ b/packages/react-native/React/third-party.xcconfig @@ -8,5 +8,5 @@ // LICENSE file in the root directory of this source tree. // -HEADER_SEARCH_PATHS = $(SRCROOT)/../third-party/boost_1_83_0 $(SRCROOT)/../third-party/folly-2024.01.01.00 $(SRCROOT)/../third-party/glog-0.3.5/src +HEADER_SEARCH_PATHS = $(SRCROOT)/../third-party/boost_1_83_0 $(SRCROOT)/../third-party/folly-2024.10.14.00 $(SRCROOT)/../third-party/glog-0.3.5/src OTHER_CFLAGS = -DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_CFG_NO_COROUTINES=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 861e38046f1467..9dac0c2d58ade9 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -7,23 +7,6 @@ public abstract class com/facebook/react/BaseReactPackage : com/facebook/react/R protected fun getViewManagers (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/List; } -public class com/facebook/react/CompositeReactPackage : com/facebook/react/ReactPackage, com/facebook/react/ViewManagerOnDemandReactPackage { - public fun (Lcom/facebook/react/ReactPackage;Lcom/facebook/react/ReactPackage;[Lcom/facebook/react/ReactPackage;)V - public fun createNativeModules (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/List; - public fun createViewManager (Lcom/facebook/react/bridge/ReactApplicationContext;Ljava/lang/String;)Lcom/facebook/react/uimanager/ViewManager; - public fun createViewManagers (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/List; - public fun getViewManagerNames (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/Collection; -} - -public class com/facebook/react/CompositeReactPackageTurboModuleManagerDelegate : com/facebook/react/ReactPackageTurboModuleManagerDelegate { - protected fun initHybrid ()Lcom/facebook/jni/HybridData; -} - -public class com/facebook/react/CompositeReactPackageTurboModuleManagerDelegate$Builder : com/facebook/react/ReactPackageTurboModuleManagerDelegate$Builder { - public fun (Ljava/util/List;)V - protected fun build (Lcom/facebook/react/bridge/ReactApplicationContext;Ljava/util/List;)Lcom/facebook/react/ReactPackageTurboModuleManagerDelegate; -} - public class com/facebook/react/CoreModulesPackage$$ReactModuleInfoProvider : com/facebook/react/module/model/ReactModuleInfoProvider { public fun ()V public fun getReactModuleInfos ()Ljava/util/Map; @@ -97,6 +80,7 @@ public abstract class com/facebook/react/ReactActivity : androidx/appcompat/app/ protected fun getMainComponentName ()Ljava/lang/String; public fun getReactActivityDelegate ()Lcom/facebook/react/ReactActivityDelegate; public fun getReactDelegate ()Lcom/facebook/react/ReactDelegate; + protected fun getReactHost ()Lcom/facebook/react/ReactHost; protected final fun getReactInstanceManager ()Lcom/facebook/react/ReactInstanceManager; protected final fun getReactNativeHost ()Lcom/facebook/react/ReactNativeHost; public fun invokeDefaultOnBackPressed ()V @@ -127,6 +111,7 @@ public class com/facebook/react/ReactActivityDelegate { protected fun getLaunchOptions ()Landroid/os/Bundle; public fun getMainComponentName ()Ljava/lang/String; protected fun getPlainActivity ()Landroid/app/Activity; + protected fun getReactActivity ()Lcom/facebook/react/ReactActivity; protected fun getReactDelegate ()Lcom/facebook/react/ReactDelegate; public fun getReactHost ()Lcom/facebook/react/ReactHost; public fun getReactInstanceManager ()Lcom/facebook/react/ReactInstanceManager; @@ -2042,7 +2027,6 @@ public final class com/facebook/react/common/network/OkHttpCallUtil { public class com/facebook/react/config/ReactFeatureFlags { public static field dispatchPointerEvents Z - public static field enableCppPropsIteratorSetter Z public fun ()V } @@ -2074,8 +2058,8 @@ public class com/facebook/react/defaults/DefaultReactActivityDelegate : com/face public final class com/facebook/react/defaults/DefaultReactHost { public static final field INSTANCE Lcom/facebook/react/defaults/DefaultReactHost; public static final fun getDefaultReactHost (Landroid/content/Context;Lcom/facebook/react/ReactNativeHost;)Lcom/facebook/react/ReactHost; - public static final fun getDefaultReactHost (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;)Lcom/facebook/react/ReactHost; - public static synthetic fun getDefaultReactHost$default (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;ILjava/lang/Object;)Lcom/facebook/react/ReactHost; + public static final fun getDefaultReactHost (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lcom/facebook/react/bridge/JSBundleLoader;)Lcom/facebook/react/ReactHost; + public static synthetic fun getDefaultReactHost$default (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lcom/facebook/react/bridge/JSBundleLoader;ILjava/lang/Object;)Lcom/facebook/react/ReactHost; } public abstract class com/facebook/react/defaults/DefaultReactNativeHost : com/facebook/react/ReactNativeHost { @@ -2228,7 +2212,6 @@ public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/ public fun startInspector ()V public fun stopInspector ()V public fun toggleElementInspector ()V - public fun updateJSError (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;I)V } public abstract interface class com/facebook/react/devsupport/DevSupportManagerBase$CallbackWithBundleLoader { @@ -2396,7 +2379,6 @@ public class com/facebook/react/devsupport/ReleaseDevSupportManager : com/facebo public fun startInspector ()V public fun stopInspector ()V public fun toggleElementInspector ()V - public fun updateJSError (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;I)V } public class com/facebook/react/devsupport/StackTraceHelper { @@ -2532,7 +2514,6 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevSupp public abstract fun startInspector ()V public abstract fun stopInspector ()V public abstract fun toggleElementInspector ()V - public abstract fun updateJSError (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;I)V } public abstract interface class com/facebook/react/devsupport/interfaces/DevSupportManager$PackagerLocationCustomizer { @@ -3027,22 +3008,6 @@ public abstract interface class com/facebook/react/module/model/ReactModuleInfoP public abstract fun getReactModuleInfos ()Ljava/util/Map; } -public final class com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule : com/facebook/fbreact/specs/NativeAccessibilityInfoSpec, com/facebook/react/bridge/LifecycleEventListener { - public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V - public fun announceForAccessibility (Ljava/lang/String;)V - public fun getRecommendedTimeoutMillis (DLcom/facebook/react/bridge/Callback;)V - public fun initialize ()V - public fun invalidate ()V - public fun isAccessibilityServiceEnabled (Lcom/facebook/react/bridge/Callback;)V - public fun isHighTextContrastEnabled (Lcom/facebook/react/bridge/Callback;)V - public fun isReduceMotionEnabled (Lcom/facebook/react/bridge/Callback;)V - public fun isTouchExplorationEnabled (Lcom/facebook/react/bridge/Callback;)V - public fun onHostDestroy ()V - public fun onHostPause ()V - public fun onHostResume ()V - public fun setAccessibilityFocus (D)V -} - public final class com/facebook/react/modules/appearance/AppearanceModule : com/facebook/fbreact/specs/NativeAppearanceSpec { public static final field Companion Lcom/facebook/react/modules/appearance/AppearanceModule$Companion; public static final field NAME Ljava/lang/String; @@ -3070,26 +3035,6 @@ public abstract interface class com/facebook/react/modules/appregistry/AppRegist public abstract fun unmountApplicationComponentAtRootTag (I)V } -public final class com/facebook/react/modules/appstate/AppStateModule : com/facebook/fbreact/specs/NativeAppStateSpec, com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/bridge/WindowFocusChangeListener { - public static final field APP_STATE_ACTIVE Ljava/lang/String; - public static final field APP_STATE_BACKGROUND Ljava/lang/String; - public static final field Companion Lcom/facebook/react/modules/appstate/AppStateModule$Companion; - public static final field NAME Ljava/lang/String; - public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V - public fun addListener (Ljava/lang/String;)V - public fun getCurrentAppState (Lcom/facebook/react/bridge/Callback;Lcom/facebook/react/bridge/Callback;)V - public fun getTypedExportedConstants ()Ljava/util/Map; - public fun invalidate ()V - public fun onHostDestroy ()V - public fun onHostPause ()V - public fun onHostResume ()V - public fun onWindowFocusChange (Z)V - public fun removeListeners (D)V -} - -public final class com/facebook/react/modules/appstate/AppStateModule$Companion { -} - public class com/facebook/react/modules/blob/BlobModule : com/facebook/fbreact/specs/NativeBlobModuleSpec { public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun addNetworkingHandler ()V @@ -3190,7 +3135,6 @@ public class com/facebook/react/modules/core/ExceptionsManagerModule : com/faceb public fun reportException (Lcom/facebook/react/bridge/ReadableMap;)V public fun reportFatalException (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;D)V public fun reportSoftException (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;D)V - public fun updateExceptionMessage (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;D)V } public class com/facebook/react/modules/core/HeadlessJsTaskSupportModule : com/facebook/fbreact/specs/NativeHeadlessJsTaskSupportSpec { @@ -3387,11 +3331,16 @@ public final class com/facebook/react/modules/devloading/DevLoadingModule$Compan } public final class com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule : com/facebook/fbreact/specs/NativeReactDevToolsRuntimeSettingsModuleSpec { + public static final field Companion Lcom/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule$Companion; + public static final field NAME Ljava/lang/String; public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun getReloadAndProfileConfig ()Lcom/facebook/react/bridge/WritableMap; public fun setReloadAndProfileConfig (Lcom/facebook/react/bridge/ReadableMap;)V } +public final class com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule$Companion { +} + public class com/facebook/react/modules/dialog/AlertFragment : androidx/fragment/app/DialogFragment, android/content/DialogInterface$OnClickListener { public fun ()V public fun (Lcom/facebook/react/modules/dialog/DialogModule$AlertFragmentListener;Landroid/os/Bundle;)V @@ -3414,6 +3363,7 @@ public class com/facebook/react/modules/dialog/DialogModule : com/facebook/fbrea public class com/facebook/react/modules/fresco/FrescoModule : com/facebook/react/bridge/ReactContextBaseJavaModule, com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/modules/common/ModuleDataCleaner$Cleanable, com/facebook/react/turbomodule/core/interfaces/TurboModule { public static final field Companion Lcom/facebook/react/modules/fresco/FrescoModule$Companion; + public static final field NAME Ljava/lang/String; public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun (Lcom/facebook/react/bridge/ReactApplicationContext;Lcom/facebook/imagepipeline/core/ImagePipeline;)V public fun (Lcom/facebook/react/bridge/ReactApplicationContext;Lcom/facebook/imagepipeline/core/ImagePipeline;Z)V @@ -3469,6 +3419,8 @@ public final class com/facebook/react/modules/fresco/XmlFormat { } public final class com/facebook/react/modules/i18nmanager/I18nManagerModule : com/facebook/fbreact/specs/NativeI18nManagerSpec { + public static final field Companion Lcom/facebook/react/modules/i18nmanager/I18nManagerModule$Companion; + public static final field NAME Ljava/lang/String; public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun allowRTL (Z)V public fun forceRTL (Z)V @@ -3476,6 +3428,9 @@ public final class com/facebook/react/modules/i18nmanager/I18nManagerModule : co public fun swapLeftAndRightInRTL (Z)V } +public final class com/facebook/react/modules/i18nmanager/I18nManagerModule$Companion { +} + public final class com/facebook/react/modules/i18nmanager/I18nUtil { public static final field Companion Lcom/facebook/react/modules/i18nmanager/I18nUtil$Companion; public final fun allowRTL (Landroid/content/Context;Z)V @@ -3647,6 +3602,8 @@ public class com/facebook/react/modules/network/TLSSocketFactory : javax/net/ssl } public final class com/facebook/react/modules/permissions/PermissionsModule : com/facebook/fbreact/specs/NativePermissionsAndroidSpec, com/facebook/react/modules/core/PermissionListener { + public static final field Companion Lcom/facebook/react/modules/permissions/PermissionsModule$Companion; + public static final field NAME Ljava/lang/String; public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun checkPermission (Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V public fun onRequestPermissionsResult (I[Ljava/lang/String;[I)Z @@ -3655,15 +3612,24 @@ public final class com/facebook/react/modules/permissions/PermissionsModule : co public fun shouldShowRequestPermissionRationale (Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V } +public final class com/facebook/react/modules/permissions/PermissionsModule$Companion { +} + public final class com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule : com/facebook/fbreact/specs/NativeReactDevToolsSettingsManagerSpec { + public static final field Companion Lcom/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule$Companion; + public static final field NAME Ljava/lang/String; public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun getGlobalHookSettings ()Ljava/lang/String; public fun setGlobalHookSettings (Ljava/lang/String;)V } +public final class com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule$Companion { +} + public final class com/facebook/react/modules/share/ShareModule : com/facebook/fbreact/specs/NativeShareModuleSpec { public static final field Companion Lcom/facebook/react/modules/share/ShareModule$Companion; public static final field ERROR_INVALID_CONTENT Ljava/lang/String; + public static final field NAME Ljava/lang/String; public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun share (Lcom/facebook/react/bridge/ReadableMap;Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V } @@ -3672,10 +3638,15 @@ public final class com/facebook/react/modules/share/ShareModule$Companion { } public final class com/facebook/react/modules/sound/SoundManagerModule : com/facebook/fbreact/specs/NativeSoundManagerSpec { + public static final field Companion Lcom/facebook/react/modules/sound/SoundManagerModule$Companion; + public static final field NAME Ljava/lang/String; public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun playTouchSound ()V } +public final class com/facebook/react/modules/sound/SoundManagerModule$Companion { +} + public final class com/facebook/react/modules/statusbar/StatusBarModule : com/facebook/fbreact/specs/NativeStatusBarManagerAndroidSpec { public static final field Companion Lcom/facebook/react/modules/statusbar/StatusBarModule$Companion; public static final field NAME Ljava/lang/String; @@ -3729,12 +3700,17 @@ public final class com/facebook/react/modules/toast/ToastModule$Companion { } public final class com/facebook/react/modules/vibration/VibrationModule : com/facebook/fbreact/specs/NativeVibrationSpec { + public static final field Companion Lcom/facebook/react/modules/vibration/VibrationModule$Companion; + public static final field NAME Ljava/lang/String; public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun cancel ()V public fun vibrate (D)V public fun vibrateByPattern (Lcom/facebook/react/bridge/ReadableArray;D)V } +public final class com/facebook/react/modules/vibration/VibrationModule$Companion { +} + public final class com/facebook/react/modules/websocket/WebSocketModule : com/facebook/fbreact/specs/NativeWebSocketModuleSpec { public fun (Lcom/facebook/react/bridge/ReactApplicationContext;)V public fun addListener (Ljava/lang/String;)V @@ -4022,16 +3998,17 @@ public final class com/facebook/react/shell/MainPackageConfig { public final fun getFrescoConfig ()Lcom/facebook/imagepipeline/core/ImagePipelineConfig; } -public class com/facebook/react/shell/MainReactPackage : com/facebook/react/BaseReactPackage, com/facebook/react/ViewManagerOnDemandReactPackage { +public final class com/facebook/react/shell/MainReactPackage : com/facebook/react/BaseReactPackage, com/facebook/react/ViewManagerOnDemandReactPackage { public fun ()V public fun (Lcom/facebook/react/shell/MainPackageConfig;)V + public synthetic fun (Lcom/facebook/react/shell/MainPackageConfig;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun createViewManager (Lcom/facebook/react/bridge/ReactApplicationContext;Ljava/lang/String;)Lcom/facebook/react/uimanager/ViewManager; public fun createViewManagers (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/List; public fun getModule (Ljava/lang/String;Lcom/facebook/react/bridge/ReactApplicationContext;)Lcom/facebook/react/bridge/NativeModule; public fun getReactModuleInfoProvider ()Lcom/facebook/react/module/model/ReactModuleInfoProvider; public fun getViewManagerNames (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/Collection; public fun getViewManagers (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/List; - public fun getViewManagersMap ()Ljava/util/Map; + public final fun getViewManagersMap ()Ljava/util/Map; } public class com/facebook/react/shell/MainReactPackage$$ReactModuleInfoProvider : com/facebook/react/module/model/ReactModuleInfoProvider { @@ -6150,6 +6127,7 @@ public final class com/facebook/react/uimanager/style/ComputedBorderRadius { public final fun getTopRight ()Lcom/facebook/react/uimanager/style/CornerRadii; public final fun hasRoundedBorders ()Z public fun hashCode ()I + public final fun isUniform ()Z public fun toString ()Ljava/lang/String; } @@ -7248,7 +7226,9 @@ public final class com/facebook/react/views/scroll/ReactScrollViewHelper { public static final field SNAP_ALIGNMENT_DISABLED I public static final field SNAP_ALIGNMENT_END I public static final field SNAP_ALIGNMENT_START I + public static final fun addLayoutChangeListener (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$LayoutChangeListener;)V public static final fun addScrollListener (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ScrollListener;)V + public static final fun emitLayoutChangeEvent (Landroid/view/ViewGroup;)V public static final fun emitLayoutEvent (Landroid/view/ViewGroup;)V public static final fun emitScrollBeginDragEvent (Landroid/view/ViewGroup;)V public static final fun emitScrollEndDragEvent (Landroid/view/ViewGroup;FF)V @@ -7262,6 +7242,7 @@ public final class com/facebook/react/views/scroll/ReactScrollViewHelper { public static final fun parseSnapToAlignment (Ljava/lang/String;)I public static final fun predictFinalScrollPosition (Landroid/view/ViewGroup;IIII)Landroid/graphics/Point; public final fun registerFlingAnimator (Landroid/view/ViewGroup;)V + public static final fun removeLayoutChangeListener (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$LayoutChangeListener;)V public static final fun removeScrollListener (Lcom/facebook/react/views/scroll/ReactScrollViewHelper$ScrollListener;)V public static final fun smoothScrollTo (Landroid/view/ViewGroup;II)V public static final fun updateFabricScrollState (Landroid/view/ViewGroup;)V @@ -7296,6 +7277,10 @@ public abstract interface class com/facebook/react/views/scroll/ReactScrollViewH public abstract fun getStateWrapper ()Lcom/facebook/react/uimanager/StateWrapper; } +public abstract interface class com/facebook/react/views/scroll/ReactScrollViewHelper$LayoutChangeListener { + public abstract fun onLayoutChange (Landroid/view/ViewGroup;)V +} + public final class com/facebook/react/views/scroll/ReactScrollViewHelper$ReactScrollViewScrollState { public fun (I)V public final fun getDecelerationRate ()F diff --git a/packages/react-native/ReactAndroid/build.gradle.kts b/packages/react-native/ReactAndroid/build.gradle.kts index cd4d907728d615..492072f567ef05 100644 --- a/packages/react-native/ReactAndroid/build.gradle.kts +++ b/packages/react-native/ReactAndroid/build.gradle.kts @@ -66,6 +66,7 @@ val prefabHeadersDir = project.file("$buildDir/prefab-headers") // Native versions which are defined inside the version catalog (libs.versions.toml) val BOOST_VERSION = libs.versions.boost.get() val DOUBLE_CONVERSION_VERSION = libs.versions.doubleconversion.get() +val FAST_FLOAT_VERSION = libs.versions.fastFloat.get() val FMT_VERSION = libs.versions.fmt.get() val FOLLY_VERSION = libs.versions.folly.get() val GLOG_VERSION = libs.versions.glog.get() @@ -183,6 +184,7 @@ val preparePrefab by // react_nativemodule_core Pair(File(buildDir, "third-party-ndk/boost/boost_1_83_0/").absolutePath, ""), Pair(File(buildDir, "third-party-ndk/double-conversion/").absolutePath, ""), + Pair(File(buildDir, "third-party-ndk/fast_float/include/").absolutePath, ""), Pair(File(buildDir, "third-party-ndk/fmt/include/").absolutePath, ""), Pair(File(buildDir, "third-party-ndk/folly/").absolutePath, ""), Pair(File(buildDir, "third-party-ndk/glog/exported/").absolutePath, ""), @@ -312,6 +314,28 @@ val prepareFolly by into("$thirdPartyNdkDir/folly") } +val downloadFastFloat by + tasks.creating(Download::class) { + dependsOn(createNativeDepsDirectories) + src("https://github.com/fastfloat/fast_float/archive/v${FAST_FLOAT_VERSION}.tar.gz") + onlyIfModified(true) + overwrite(false) + retries(5) + quiet(true) + dest(File(downloadsDir, "fast_float-${FAST_FLOAT_VERSION}.tar.gz")) + } + +val prepareFastFloat by + tasks.registering(Copy::class) { + dependsOn(if (dependenciesPath != null) emptyList() else listOf(downloadFastFloat)) + from(dependenciesPath ?: tarTree(downloadFastFloat.dest)) + from("src/main/jni/third-party/fast_float/") + include("fast_float-${FAST_FLOAT_VERSION}/include/**/*", "CMakeLists.txt") + eachFile { this.path = this.path.removePrefix("fast_float-${FAST_FLOAT_VERSION}/") } + includeEmptyDirs = false + into("$thirdPartyNdkDir/fast_float") + } + val downloadFmt by tasks.creating(Download::class) { dependsOn(createNativeDepsDirectories) @@ -549,6 +573,7 @@ android { "generateCodegenArtifactsFromSchema", prepareBoost, prepareDoubleConversion, + prepareFastFloat, prepareFmt, prepareFolly, prepareGlog, @@ -680,6 +705,8 @@ kotlin { explicitApi() } +tasks.withType { jvmArgs = listOf("-Xshare:off") } + /* Publishing Configuration */ apply(from = "./publish.gradle") diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackage.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackage.java deleted file mode 100644 index eb3a4ece75881a..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackage.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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. - */ - -package com.facebook.react; - -import androidx.annotation.Nullable; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.module.model.ReactModuleInfo; -import com.facebook.react.module.model.ReactModuleInfoProvider; -import com.facebook.react.uimanager.ViewManager; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Set; - -/** - * {@code CompositeReactPackage} allows to create a single package composed of views and modules - * from several other packages. - * - * @deprecated - */ -@Deprecated( - since = "CompositeReactPackage is deprecated and will be deleted, use ReactPackage instead", - forRemoval = true) -public class CompositeReactPackage implements ViewManagerOnDemandReactPackage, ReactPackage { - - private final List mChildReactPackages = new ArrayList<>(); - - /** - * The order in which packages are passed matters. It may happen that a NativeModule or a - * ViewManager exists in two or more ReactPackages. In that case the latter will win i.e. the - * latter will overwrite the former. This re-occurrence is detected by comparing a name of a - * module. - */ - public CompositeReactPackage(ReactPackage arg1, ReactPackage arg2, ReactPackage... args) { - mChildReactPackages.add(arg1); - mChildReactPackages.add(arg2); - - Collections.addAll(mChildReactPackages, args); - } - - /** {@inheritDoc} */ - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - // This is for backward compatibility. - final Map moduleMap = new HashMap<>(); - for (ReactPackage reactPackage : mChildReactPackages) { - /** - * For now, we eagerly initialize the NativeModules inside BaseReactPackages. Ultimately, we - * should turn CompositeReactPackage into a BaseReactPackage and remove this eager - * initialization. - * - *

TODO: T45627020 - */ - if (reactPackage instanceof BaseReactPackage) { - BaseReactPackage baseReactPackage = (BaseReactPackage) reactPackage; - ReactModuleInfoProvider moduleInfoProvider = baseReactPackage.getReactModuleInfoProvider(); - Map moduleInfos = moduleInfoProvider.getReactModuleInfos(); - - for (final String moduleName : moduleInfos.keySet()) { - moduleMap.put(moduleName, baseReactPackage.getModule(moduleName, reactContext)); - } - - continue; - } - - for (NativeModule nativeModule : reactPackage.createNativeModules(reactContext)) { - moduleMap.put(nativeModule.getName(), nativeModule); - } - } - return new ArrayList<>(moduleMap.values()); - } - - /** {@inheritDoc} */ - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - final Map viewManagerMap = new HashMap<>(); - for (ReactPackage reactPackage : mChildReactPackages) { - for (ViewManager viewManager : reactPackage.createViewManagers(reactContext)) { - viewManagerMap.put(viewManager.getName(), viewManager); - } - } - return new ArrayList<>(viewManagerMap.values()); - } - - /** {@inheritDoc} */ - @Override - public Collection getViewManagerNames(ReactApplicationContext reactContext) { - Set uniqueNames = new HashSet<>(); - for (ReactPackage reactPackage : mChildReactPackages) { - if (reactPackage instanceof ViewManagerOnDemandReactPackage) { - Collection names = - ((ViewManagerOnDemandReactPackage) reactPackage).getViewManagerNames(reactContext); - if (names != null) { - uniqueNames.addAll(names); - } - } - } - return uniqueNames; - } - - /** {@inheritDoc} */ - @Override - public @Nullable ViewManager createViewManager( - ReactApplicationContext reactContext, String viewManagerName) { - ListIterator iterator = - mChildReactPackages.listIterator(mChildReactPackages.size()); - while (iterator.hasPrevious()) { - ReactPackage reactPackage = iterator.previous(); - if (reactPackage instanceof ViewManagerOnDemandReactPackage) { - ViewManager viewManager = - ((ViewManagerOnDemandReactPackage) reactPackage) - .createViewManager(reactContext, viewManagerName); - if (viewManager != null) { - return viewManager; - } - } - } - return null; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackageTurboModuleManagerDelegate.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackageTurboModuleManagerDelegate.java deleted file mode 100644 index 9ca49e89e207c2..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackageTurboModuleManagerDelegate.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - */ - -package com.facebook.react; - -import androidx.annotation.NonNull; -import com.facebook.jni.HybridData; -import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.internal.turbomodule.core.TurboModuleManagerDelegate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@Deprecated( - since = - "CompositeReactPackageTurboModuleManagerDelegate is deprecated and will be deleted in the" - + " future. Please use ReactPackage interface or BaseReactPackage instead.") -@DoNotStrip -public class CompositeReactPackageTurboModuleManagerDelegate - extends ReactPackageTurboModuleManagerDelegate { - - protected native HybridData initHybrid(); - - private CompositeReactPackageTurboModuleManagerDelegate( - ReactApplicationContext context, - List packages, - List delegates) { - super(context, packages); - for (TurboModuleManagerDelegate delegate : delegates) { - addTurboModuleManagerDelegate(delegate); - } - } - - private native void addTurboModuleManagerDelegate(TurboModuleManagerDelegate delegates); - - public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder { - private final List mDelegatesBuilder; - - public Builder(@NonNull List delegatesBuilder) { - mDelegatesBuilder = delegatesBuilder; - } - - protected ReactPackageTurboModuleManagerDelegate build( - ReactApplicationContext context, List packages) { - List delegates = new ArrayList<>(); - for (ReactPackageTurboModuleManagerDelegate.Builder delegatesBuilder : mDelegatesBuilder) { - delegates.add(delegatesBuilder.build(context, Collections.emptyList())); - } - return new CompositeReactPackageTurboModuleManagerDelegate(context, packages, delegates); - } - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java index 864b0454d5d0f2..757ba90d5be7a7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java @@ -148,6 +148,10 @@ protected final ReactNativeHost getReactNativeHost() { return mDelegate.getReactNativeHost(); } + protected ReactHost getReactHost() { + return mDelegate.getReactHost(); + } + protected final ReactInstanceManager getReactInstanceManager() { return mDelegate.getReactInstanceManager(); } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java index 8630a29723b000..766aa856cd803c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java @@ -76,8 +76,8 @@ public ReactActivityDelegate( } /** - * Get the {@link ReactNativeHost} used by this app. By default, assumes {@link - * Activity#getApplication()} is an instance of {@link ReactApplication} and calls {@link + * Get the {@link ReactNativeHost} used by this app with Bridge enabled. By default, assumes + * {@link Activity#getApplication()} is an instance of {@link ReactApplication} and calls {@link * ReactApplication#getReactNativeHost()}. Override this method if your application class does not * implement {@code ReactApplication} or you simply have a different mechanism for storing a * {@code ReactNativeHost}, e.g. as a static field somewhere. @@ -86,6 +86,13 @@ protected ReactNativeHost getReactNativeHost() { return ((ReactApplication) getPlainActivity().getApplication()).getReactNativeHost(); } + /** + * Get the {@link ReactHost} used by this app with Bridgeless enabled. By default, assumes {@link + * Activity#getApplication()} is an instance of {@link ReactApplication} and calls {@link + * ReactApplication#getReactHost()}. Override this method if your application class does not + * implement {@code ReactApplication} or you simply have a different mechanism for storing a + * {@code ReactHost}, e.g. as a static field somewhere. + */ public ReactHost getReactHost() { return ((ReactApplication) getPlainActivity().getApplication()).getReactHost(); } @@ -226,6 +233,10 @@ protected Activity getPlainActivity() { return ((Activity) getContext()); } + protected ReactActivity getReactActivity() { + return ((ReactActivity) getContext()); + } + /** * Override this method if you wish to selectively toggle Fabric for a specific surface. This will * also control if Concurrent Root (React 18) should be enabled or not. diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt index add1f767f917df..b5a88b70574272 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt @@ -84,7 +84,7 @@ public interface ReactHost { context: Context, moduleName: String, initialProps: Bundle? - ): ReactSurface? + ): ReactSurface /** * This function can be used to initialize the ReactInstance in a background thread before a diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java index 6fd291bbbdfcec..b3f9c642f46553 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java @@ -91,7 +91,8 @@ public void initializeEventListenerForUIManagerType(@UIManagerType final int uiM UIManager uiManager = UIManagerHelper.getUIManager(mReactApplicationContext, uiManagerType); if (uiManager != null) { - uiManager.getEventDispatcher().addListener(this); + EventDispatcher eventDispatcher = (EventDispatcher) uiManager.getEventDispatcher(); + eventDispatcher.addListener(this); if (uiManagerType == UIManagerType.FABRIC) { mEventListenerInitializedForFabric = true; } else { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt index 6aab9810556cd2..f893f0ea209f8c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.kt @@ -78,7 +78,7 @@ public interface UIManager : PerformanceCounter { public fun dispatchCommand(reactTag: Int, commandId: String, commandArgs: ReadableArray?) /** @return the [EventDispatcher] object that is used by this class. */ - public fun getEventDispatcher(): T + public val eventDispatcher: Any? /** * Used by native animated module to bypass the process of updating the values through the shadow diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index 68a65b32704a24..353ed2aebfd5fd 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -23,9 +23,4 @@ public class ReactFeatureFlags { public static boolean dispatchPointerEvents = false; - - /** - * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). - */ - public static boolean enableCppPropsIteratorSetter = false; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactHost.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactHost.kt index 428d715d57aa29..0ae71ba9458029 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactHost.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactHost.kt @@ -45,6 +45,7 @@ public object DefaultReactHost { * @param useDevSupport whether to enable dev support, default to ReactBuildConfig.DEBUG. * @param cxxReactPackageProviders a list of cxxreactpackage providers (to register c++ turbo * modules) + * @param jsBundleLoader a [JSBundleLoader] to use for creating the [ReactHost] * * TODO(T186951312): Should this be @UnstableReactNativeAPI? */ @@ -59,25 +60,28 @@ public object DefaultReactHost { isHermesEnabled: Boolean = true, useDevSupport: Boolean = ReactBuildConfig.DEBUG, cxxReactPackageProviders: List<(ReactContext) -> CxxReactPackage> = emptyList(), + jsBundleLoader: JSBundleLoader? = null, ): ReactHost { if (reactHost == null) { - val jsBundleLoader = - if (jsBundleFilePath != null) { - if (jsBundleFilePath.startsWith("assets://")) { - JSBundleLoader.createAssetLoader(context, jsBundleFilePath, true) - } else { - JSBundleLoader.createFileLoader(jsBundleFilePath) - } - } else { - JSBundleLoader.createAssetLoader(context, "assets://$jsBundleAssetPath", true) - } + + val bundleLoader = + jsBundleLoader + ?: if (jsBundleFilePath != null) { + if (jsBundleFilePath.startsWith("assets://")) { + JSBundleLoader.createAssetLoader(context, jsBundleFilePath, true) + } else { + JSBundleLoader.createFileLoader(jsBundleFilePath) + } + } else { + JSBundleLoader.createAssetLoader(context, "assets://$jsBundleAssetPath", true) + } val jsRuntimeFactory = if (isHermesEnabled) HermesInstance() else JSCInstance() val defaultTmmDelegateBuilder = DefaultTurboModuleManagerDelegate.Builder() cxxReactPackageProviders.forEach { defaultTmmDelegateBuilder.addCxxReactPackage(it) } val defaultReactHostDelegate = DefaultReactHostDelegate( jsMainModulePath = jsMainModulePath, - jsBundleLoader = jsBundleLoader, + jsBundleLoader = bundleLoader, reactPackages = packageList, jsRuntimeFactory = jsRuntimeFactory, turboModuleManagerDelegateBuilder = defaultTmmDelegateBuilder) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt index dac36e139efef7..b85923b3f19ded 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt @@ -111,7 +111,7 @@ protected constructor( packages, jsMainModuleName, bundleAssetName ?: "index", - null, + jsBundleFile, isHermesEnabled ?: true, useDeveloperSupport, ) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgelessDevSupportManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgelessDevSupportManager.java index 676a8620e0d397..355a88d1a0dda5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgelessDevSupportManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/BridgelessDevSupportManager.java @@ -100,6 +100,7 @@ public void onSuccess(final JSBundleLoader bundleLoader) { } callback.onSuccess(); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new RuntimeException( "[BridgelessDevSupportManager]: Got interrupted while loading bundle", e); } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java index 6856884aa62889..a7a2b421be8195 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java @@ -520,9 +520,8 @@ public void openDebugger(@Nullable final ReactContext context, final String erro String requestUrl = String.format( Locale.US, - "http://%s/open-debugger?appId=%s&device=%s", + "http://%s/open-debugger?device=%s", mPackagerConnectionSettings.getDebugServerHost(), - Uri.encode(mPackageName), Uri.encode(getInspectorDeviceId())); Request request = new Request.Builder().url(requestUrl).method("POST", RequestBody.create(null, "")).build(); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java index 35dba5ee6e3e26..f91d9add84937c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java @@ -279,26 +279,6 @@ public Pair processErrorCustomizers(Pair { - // Since we only show the first JS error in a succession of JS errors, make sure we only - // update the error message for that error message. This assumes that updateJSError - // belongs to the most recent showNewJSError - if ((mRedBoxSurfaceDelegate != null && !mRedBoxSurfaceDelegate.isShowing()) - || errorCookie != mLastErrorCookie) { - return; - } - - // The RedBox surface delegate will always show the latest error - updateLastErrorInfo( - message, StackTraceHelper.convertJsStackTrace(details), errorCookie, ErrorType.JS); - mRedBoxSurfaceDelegate.show(); - }); - } - @Override public void hideRedboxDialog() { if (mRedBoxSurfaceDelegate == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/ReleaseDevSupportManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/ReleaseDevSupportManager.kt index ba9e0aa03c5220..02398843112d28 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/ReleaseDevSupportManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/ReleaseDevSupportManager.kt @@ -53,12 +53,6 @@ public open class ReleaseDevSupportManager : DevSupportManager { override public fun destroyRootView(rootView: View?): Unit = Unit - override public fun updateJSError( - message: String?, - details: ReadableArray?, - errorCookie: Int - ): Unit = Unit - override public fun hideRedboxDialog(): Unit = Unit override public fun showDevOptionsDialog(): Unit = Unit diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevSupportManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevSupportManager.kt index 67bc3b0e21bf60..a778ac54577676 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevSupportManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevSupportManager.kt @@ -48,8 +48,6 @@ public interface DevSupportManager : JSExceptionHandler { public fun showNewJSError(message: String?, details: ReadableArray?, errorCookie: Int) - public fun updateJSError(message: String?, details: ReadableArray?, errorCookie: Int) - public fun hideRedboxDialog() public fun showDevOptionsDialog() diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index e73cdff47d3cb5..8ad955bc966e4c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -1025,7 +1025,6 @@ public void onHostResume() { @Override @NonNull - @SuppressWarnings("unchecked") public EventDispatcher getEventDispatcher() { return mEventDispatcher; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/interfaces/fabric/ReactSurface.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/interfaces/fabric/ReactSurface.kt index 5f2e13b55e51e2..6121b3c1639bac 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/interfaces/fabric/ReactSurface.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/interfaces/fabric/ReactSurface.kt @@ -17,33 +17,33 @@ public interface ReactSurface { // the API of this interface will be completed as we analyze and refactor API of ReactSurface, // ReactRootView, etc. - // Returns surface ID of this surface + /** Returns surface ID of this surface */ public val surfaceID: Int - // Returns module name of this surface + /** Returns module name of this surface */ public val moduleName: String - // Returns whether the surface is running or not + /** Returns whether the surface is running or not */ public val isRunning: Boolean - // Returns React root view of this surface + /** Returns React root view of this surface */ public val view: ViewGroup? - // Returns context associated with the surface + /** Returns context associated with the surface */ public val context: Context - // Prerender this surface + /** Prerender this surface */ public fun prerender(): TaskInterface - // Start running this surface + /** Start running this surface */ public fun start(): TaskInterface - // Stop running this surface + /** Stop running this surface */ public fun stop(): TaskInterface - // Clear surface + /** Clear surface */ public fun clear() - // Detach surface from Host + /** Detach surface from Host */ public fun detach() } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 3f76b06c1199c4..cffb38e37ee343 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7d0c7d2dac41c4a64c3c8301b3865fdd>> + * @generated SignedSource<> */ /** @@ -41,16 +41,16 @@ public object ReactNativeFeatureFlags { public fun allowRecursiveCommitsWithSynchronousMountOnAndroid(): Boolean = accessor.allowRecursiveCommitsWithSynchronousMountOnAndroid() /** - * When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop. + * Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android */ @JvmStatic - public fun batchRenderingUpdatesInEventLoop(): Boolean = accessor.batchRenderingUpdatesInEventLoop() + public fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean = accessor.completeReactInstanceCreationOnBgThreadOnAndroid() /** - * Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android + * The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances. */ @JvmStatic - public fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean = accessor.completeReactInstanceCreationOnBgThreadOnAndroid() + public fun disableEventLoopOnBridgeless(): Boolean = accessor.disableEventLoopOnBridgeless() /** * Kill-switch to turn off support for aling-items:baseline on Fabric iOS. @@ -76,6 +76,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableCleanTextInputYogaNode(): Boolean = accessor.enableCleanTextInputYogaNode() + /** + * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). + */ + @JvmStatic + public fun enableCppPropsIteratorSetter(): Boolean = accessor.enableCppPropsIteratorSetter() + /** * Deletes views that were pre-allocated but never mounted on the screen. */ @@ -143,10 +149,10 @@ public object ReactNativeFeatureFlags { public fun enableLongTaskAPI(): Boolean = accessor.enableLongTaskAPI() /** - * Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution). + * Use BackgroundDrawable and BorderDrawable instead of CSSBackgroundDrawable */ @JvmStatic - public fun enableMicrotasks(): Boolean = accessor.enableMicrotasks() + public fun enableNewBackgroundAndBorderDrawables(): Boolean = accessor.enableNewBackgroundAndBorderDrawables() /** * Moves execution of pre-mount items to outside the choregrapher in the main thread, so we can estimate idle time more precisely (Android only). @@ -268,12 +274,6 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun useImmediateExecutorInAndroidBridgeless(): Boolean = accessor.useImmediateExecutorInAndroidBridgeless() - /** - * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. - */ - @JvmStatic - public fun useModernRuntimeScheduler(): Boolean = accessor.useModernRuntimeScheduler() - /** * When enabled, the native view configs are used in bridgeless mode. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index 62cfcd32f052ed..6951d052b2f2ff 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<6b3d3512d88c836dd809204cad636211>> */ /** @@ -22,12 +22,13 @@ package com.facebook.react.internal.featureflags public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor { private var commonTestFlagCache: Boolean? = null private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null - private var batchRenderingUpdatesInEventLoopCache: Boolean? = null private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null + private var disableEventLoopOnBridgelessCache: Boolean? = null private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null private var enableAndroidLineHeightCenteringCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null private var enableCleanTextInputYogaNodeCache: Boolean? = null + private var enableCppPropsIteratorSetterCache: Boolean? = null private var enableDeletionOfUnmountedViewsCache: Boolean? = null private var enableEagerRootViewAttachmentCache: Boolean? = null private var enableEventEmitterRetentionDuringGesturesOnAndroidCache: Boolean? = null @@ -39,7 +40,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var enableLayoutAnimationsOnAndroidCache: Boolean? = null private var enableLayoutAnimationsOnIOSCache: Boolean? = null private var enableLongTaskAPICache: Boolean? = null - private var enableMicrotasksCache: Boolean? = null + private var enableNewBackgroundAndBorderDrawablesCache: Boolean? = null private var enablePreciseSchedulingForPremountItemsOnAndroidCache: Boolean? = null private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null private var enableReportEventPaintTimeCache: Boolean? = null @@ -60,7 +61,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null private var useFabricInteropCache: Boolean? = null private var useImmediateExecutorInAndroidBridgelessCache: Boolean? = null - private var useModernRuntimeSchedulerCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useOptimisedViewPreallocationOnAndroidCache: Boolean? = null private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null @@ -86,20 +86,20 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } - override fun batchRenderingUpdatesInEventLoop(): Boolean { - var cached = batchRenderingUpdatesInEventLoopCache + override fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean { + var cached = completeReactInstanceCreationOnBgThreadOnAndroidCache if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.batchRenderingUpdatesInEventLoop() - batchRenderingUpdatesInEventLoopCache = cached + cached = ReactNativeFeatureFlagsCxxInterop.completeReactInstanceCreationOnBgThreadOnAndroid() + completeReactInstanceCreationOnBgThreadOnAndroidCache = cached } return cached } - override fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean { - var cached = completeReactInstanceCreationOnBgThreadOnAndroidCache + override fun disableEventLoopOnBridgeless(): Boolean { + var cached = disableEventLoopOnBridgelessCache if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.completeReactInstanceCreationOnBgThreadOnAndroid() - completeReactInstanceCreationOnBgThreadOnAndroidCache = cached + cached = ReactNativeFeatureFlagsCxxInterop.disableEventLoopOnBridgeless() + disableEventLoopOnBridgelessCache = cached } return cached } @@ -140,6 +140,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun enableCppPropsIteratorSetter(): Boolean { + var cached = enableCppPropsIteratorSetterCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableCppPropsIteratorSetter() + enableCppPropsIteratorSetterCache = cached + } + return cached + } + override fun enableDeletionOfUnmountedViews(): Boolean { var cached = enableDeletionOfUnmountedViewsCache if (cached == null) { @@ -239,11 +248,11 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } - override fun enableMicrotasks(): Boolean { - var cached = enableMicrotasksCache + override fun enableNewBackgroundAndBorderDrawables(): Boolean { + var cached = enableNewBackgroundAndBorderDrawablesCache if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.enableMicrotasks() - enableMicrotasksCache = cached + cached = ReactNativeFeatureFlagsCxxInterop.enableNewBackgroundAndBorderDrawables() + enableNewBackgroundAndBorderDrawablesCache = cached } return cached } @@ -428,15 +437,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } - override fun useModernRuntimeScheduler(): Boolean { - var cached = useModernRuntimeSchedulerCache - if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.useModernRuntimeScheduler() - useModernRuntimeSchedulerCache = cached - } - return cached - } - override fun useNativeViewConfigsInBridgelessMode(): Boolean { var cached = useNativeViewConfigsInBridgelessModeCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index a0922e9bc8de02..beb07351efe7be 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<0ef9a66ccabeb0357f4b15c3e897f8fb>> */ /** @@ -32,10 +32,10 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun allowRecursiveCommitsWithSynchronousMountOnAndroid(): Boolean - @DoNotStrip @JvmStatic public external fun batchRenderingUpdatesInEventLoop(): Boolean - @DoNotStrip @JvmStatic public external fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun disableEventLoopOnBridgeless(): Boolean + @DoNotStrip @JvmStatic public external fun enableAlignItemsBaselineOnFabricIOS(): Boolean @DoNotStrip @JvmStatic public external fun enableAndroidLineHeightCentering(): Boolean @@ -44,6 +44,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableCleanTextInputYogaNode(): Boolean + @DoNotStrip @JvmStatic public external fun enableCppPropsIteratorSetter(): Boolean + @DoNotStrip @JvmStatic public external fun enableDeletionOfUnmountedViews(): Boolean @DoNotStrip @JvmStatic public external fun enableEagerRootViewAttachment(): Boolean @@ -66,7 +68,7 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableLongTaskAPI(): Boolean - @DoNotStrip @JvmStatic public external fun enableMicrotasks(): Boolean + @DoNotStrip @JvmStatic public external fun enableNewBackgroundAndBorderDrawables(): Boolean @DoNotStrip @JvmStatic public external fun enablePreciseSchedulingForPremountItemsOnAndroid(): Boolean @@ -108,8 +110,6 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun useImmediateExecutorInAndroidBridgeless(): Boolean - @DoNotStrip @JvmStatic public external fun useModernRuntimeScheduler(): Boolean - @DoNotStrip @JvmStatic public external fun useNativeViewConfigsInBridgelessMode(): Boolean @DoNotStrip @JvmStatic public external fun useOptimisedViewPreallocationOnAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 153a3d250fe580..cd29e014259de9 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5613f8d9d9403d005becbbd9348882c6>> + * @generated SignedSource<> */ /** @@ -27,10 +27,10 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun allowRecursiveCommitsWithSynchronousMountOnAndroid(): Boolean = false - override fun batchRenderingUpdatesInEventLoop(): Boolean = false - override fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean = false + override fun disableEventLoopOnBridgeless(): Boolean = false + override fun enableAlignItemsBaselineOnFabricIOS(): Boolean = true override fun enableAndroidLineHeightCentering(): Boolean = false @@ -39,6 +39,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableCleanTextInputYogaNode(): Boolean = false + override fun enableCppPropsIteratorSetter(): Boolean = false + override fun enableDeletionOfUnmountedViews(): Boolean = false override fun enableEagerRootViewAttachment(): Boolean = false @@ -61,7 +63,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableLongTaskAPI(): Boolean = false - override fun enableMicrotasks(): Boolean = false + override fun enableNewBackgroundAndBorderDrawables(): Boolean = false override fun enablePreciseSchedulingForPremountItemsOnAndroid(): Boolean = false @@ -103,8 +105,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun useImmediateExecutorInAndroidBridgeless(): Boolean = false - override fun useModernRuntimeScheduler(): Boolean = false - override fun useNativeViewConfigsInBridgelessMode(): Boolean = false override fun useOptimisedViewPreallocationOnAndroid(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 883dd08688de2e..c8674af73cf3e3 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<29d21f7f4928086a912088a14cdbd3db>> + * @generated SignedSource<<949f5cdf6d0a4015fbd680ba718dce6d>> */ /** @@ -26,12 +26,13 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var commonTestFlagCache: Boolean? = null private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null - private var batchRenderingUpdatesInEventLoopCache: Boolean? = null private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null + private var disableEventLoopOnBridgelessCache: Boolean? = null private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null private var enableAndroidLineHeightCenteringCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null private var enableCleanTextInputYogaNodeCache: Boolean? = null + private var enableCppPropsIteratorSetterCache: Boolean? = null private var enableDeletionOfUnmountedViewsCache: Boolean? = null private var enableEagerRootViewAttachmentCache: Boolean? = null private var enableEventEmitterRetentionDuringGesturesOnAndroidCache: Boolean? = null @@ -43,7 +44,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var enableLayoutAnimationsOnAndroidCache: Boolean? = null private var enableLayoutAnimationsOnIOSCache: Boolean? = null private var enableLongTaskAPICache: Boolean? = null - private var enableMicrotasksCache: Boolean? = null + private var enableNewBackgroundAndBorderDrawablesCache: Boolean? = null private var enablePreciseSchedulingForPremountItemsOnAndroidCache: Boolean? = null private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null private var enableReportEventPaintTimeCache: Boolean? = null @@ -64,7 +65,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null private var useFabricInteropCache: Boolean? = null private var useImmediateExecutorInAndroidBridgelessCache: Boolean? = null - private var useModernRuntimeSchedulerCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useOptimisedViewPreallocationOnAndroidCache: Boolean? = null private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null @@ -92,16 +92,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun batchRenderingUpdatesInEventLoop(): Boolean { - var cached = batchRenderingUpdatesInEventLoopCache - if (cached == null) { - cached = currentProvider.batchRenderingUpdatesInEventLoop() - accessedFeatureFlags.add("batchRenderingUpdatesInEventLoop") - batchRenderingUpdatesInEventLoopCache = cached - } - return cached - } - override fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean { var cached = completeReactInstanceCreationOnBgThreadOnAndroidCache if (cached == null) { @@ -112,6 +102,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun disableEventLoopOnBridgeless(): Boolean { + var cached = disableEventLoopOnBridgelessCache + if (cached == null) { + cached = currentProvider.disableEventLoopOnBridgeless() + accessedFeatureFlags.add("disableEventLoopOnBridgeless") + disableEventLoopOnBridgelessCache = cached + } + return cached + } + override fun enableAlignItemsBaselineOnFabricIOS(): Boolean { var cached = enableAlignItemsBaselineOnFabricIOSCache if (cached == null) { @@ -152,6 +152,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableCppPropsIteratorSetter(): Boolean { + var cached = enableCppPropsIteratorSetterCache + if (cached == null) { + cached = currentProvider.enableCppPropsIteratorSetter() + accessedFeatureFlags.add("enableCppPropsIteratorSetter") + enableCppPropsIteratorSetterCache = cached + } + return cached + } + override fun enableDeletionOfUnmountedViews(): Boolean { var cached = enableDeletionOfUnmountedViewsCache if (cached == null) { @@ -262,12 +272,12 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun enableMicrotasks(): Boolean { - var cached = enableMicrotasksCache + override fun enableNewBackgroundAndBorderDrawables(): Boolean { + var cached = enableNewBackgroundAndBorderDrawablesCache if (cached == null) { - cached = currentProvider.enableMicrotasks() - accessedFeatureFlags.add("enableMicrotasks") - enableMicrotasksCache = cached + cached = currentProvider.enableNewBackgroundAndBorderDrawables() + accessedFeatureFlags.add("enableNewBackgroundAndBorderDrawables") + enableNewBackgroundAndBorderDrawablesCache = cached } return cached } @@ -472,16 +482,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun useModernRuntimeScheduler(): Boolean { - var cached = useModernRuntimeSchedulerCache - if (cached == null) { - cached = currentProvider.useModernRuntimeScheduler() - accessedFeatureFlags.add("useModernRuntimeScheduler") - useModernRuntimeSchedulerCache = cached - } - return cached - } - override fun useNativeViewConfigsInBridgelessMode(): Boolean { var cached = useNativeViewConfigsInBridgelessModeCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index e7551a3a6072f6..36e8db344f06d1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<4e42e76c98b7434273e4f11212f0527b>> */ /** @@ -27,10 +27,10 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun allowRecursiveCommitsWithSynchronousMountOnAndroid(): Boolean - @DoNotStrip public fun batchRenderingUpdatesInEventLoop(): Boolean - @DoNotStrip public fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean + @DoNotStrip public fun disableEventLoopOnBridgeless(): Boolean + @DoNotStrip public fun enableAlignItemsBaselineOnFabricIOS(): Boolean @DoNotStrip public fun enableAndroidLineHeightCentering(): Boolean @@ -39,6 +39,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableCleanTextInputYogaNode(): Boolean + @DoNotStrip public fun enableCppPropsIteratorSetter(): Boolean + @DoNotStrip public fun enableDeletionOfUnmountedViews(): Boolean @DoNotStrip public fun enableEagerRootViewAttachment(): Boolean @@ -61,7 +63,7 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableLongTaskAPI(): Boolean - @DoNotStrip public fun enableMicrotasks(): Boolean + @DoNotStrip public fun enableNewBackgroundAndBorderDrawables(): Boolean @DoNotStrip public fun enablePreciseSchedulingForPremountItemsOnAndroid(): Boolean @@ -103,8 +105,6 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun useImmediateExecutorInAndroidBridgeless(): Boolean - @DoNotStrip public fun useModernRuntimeScheduler(): Boolean - @DoNotStrip public fun useNativeViewConfigsInBridgelessMode(): Boolean @DoNotStrip public fun useOptimisedViewPreallocationOnAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeNewArchitectureFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeNewArchitectureFeatureFlagsDefaults.kt index e365b5cd1b530c..f3d84db7c7ad2c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeNewArchitectureFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeNewArchitectureFeatureFlagsDefaults.kt @@ -23,21 +23,19 @@ package com.facebook.react.internal.featureflags public open class ReactNativeNewArchitectureFeatureFlagsDefaults( private val newArchitectureEnabled: Boolean = true ) : ReactNativeFeatureFlagsDefaults() { - - override fun batchRenderingUpdatesInEventLoop(): Boolean = - newArchitectureEnabled || super.batchRenderingUpdatesInEventLoop() - override fun enableBridgelessArchitecture(): Boolean = newArchitectureEnabled - override fun enableMicrotasks(): Boolean = newArchitectureEnabled || super.enableMicrotasks() + override fun enableDeletionOfUnmountedViews(): Boolean = newArchitectureEnabled + + // We turn this feature flag to true to fix #44610 and #45126 and other + // similar bugs related to pressable. + override fun enableEventEmitterRetentionDuringGesturesOnAndroid(): Boolean = + newArchitectureEnabled override fun enableFabricRenderer(): Boolean = newArchitectureEnabled override fun useFabricInterop(): Boolean = newArchitectureEnabled - override fun useModernRuntimeScheduler(): Boolean = - newArchitectureEnabled || super.useModernRuntimeScheduler() - override fun useNativeViewConfigsInBridgelessMode(): Boolean = newArchitectureEnabled || super.useNativeViewConfigsInBridgelessMode() diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt index 3c975a464d458d..6a44b60ed51091 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/AccessibilityInfoModule.kt @@ -28,7 +28,7 @@ import com.facebook.react.module.annotations.ReactModule * device. For API >= 19. */ @ReactModule(name = NativeAccessibilityInfoSpec.NAME) -public class AccessibilityInfoModule(context: ReactApplicationContext) : +internal class AccessibilityInfoModule(context: ReactApplicationContext) : NativeAccessibilityInfoSpec(context), LifecycleEventListener { @TargetApi(Build.VERSION_CODES.LOLLIPOP) private inner class ReactTouchExplorationStateChangeListener : @@ -255,7 +255,8 @@ public class AccessibilityInfoModule(context: ReactApplicationContext) : successCallback.invoke(recommendedTimeout) } - private companion object { + public companion object { + public const val NAME: String = NativeAccessibilityInfoSpec.NAME private const val REDUCE_MOTION_EVENT_NAME = "reduceMotionDidChange" private const val HIGH_TEXT_CONTRAST_EVENT_NAME = "highTextContrastDidChange" private const val TOUCH_EXPLORATION_EVENT_NAME = "touchExplorationDidChange" diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appstate/AppStateModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appstate/AppStateModule.kt index 86177fae8521f3..543ab79fba8677 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appstate/AppStateModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appstate/AppStateModule.kt @@ -18,7 +18,7 @@ import com.facebook.react.common.LifecycleState import com.facebook.react.module.annotations.ReactModule @ReactModule(name = NativeAppStateSpec.NAME) -public class AppStateModule(reactContext: ReactApplicationContext) : +internal class AppStateModule(reactContext: ReactApplicationContext) : NativeAppStateSpec(reactContext), LifecycleEventListener, WindowFocusChangeListener { private var appState: String diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/ExceptionsManagerModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/ExceptionsManagerModule.kt index 60c143a2eb3409..863c87b33eb0a1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/ExceptionsManagerModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/ExceptionsManagerModule.kt @@ -60,17 +60,6 @@ public open class ExceptionsManagerModule(private val devSupportManager: DevSupp } } - override fun updateExceptionMessage( - title: String?, - details: ReadableArray?, - exceptionIdDouble: Double - ) { - val exceptionId = exceptionIdDouble.toInt() - if (devSupportManager.devSupportEnabled) { - devSupportManager.updateJSError(title, details, exceptionId) - } - } - override fun dismissRedbox() { if (devSupportManager.devSupportEnabled) { devSupportManager.hideRedboxDialog() diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule.kt index 63e30b7cd96383..216bbcefb56b61 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule.kt @@ -25,9 +25,10 @@ private class Settings { public class ReactDevToolsRuntimeSettingsModule(reactContext: ReactApplicationContext?) : NativeReactDevToolsRuntimeSettingsModuleSpec(reactContext) { - // static to persist across Turbo Module reloads - private companion object { + public companion object { + // static to persist across Turbo Module reloads private val settings = Settings() + public const val NAME: String = NativeReactDevToolsRuntimeSettingsModuleSpec.NAME } override fun setReloadAndProfileConfig(map: ReadableMap) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/DialogTitle.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/DialogTitle.kt new file mode 100644 index 00000000000000..2dfad101298034 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/DialogTitle.kt @@ -0,0 +1,55 @@ +/* + * 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. + */ + +package com.facebook.react.modules.dialog + +import android.content.Context +import android.util.AttributeSet +import android.widget.TextView + +/** + * Reimplementation of Android's internal DialogTitle. This class will attempt to render titles on + * two lines if they are too long, applying ellipsis as necessary. + * + * @see + * https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/com/android/internal/widget/DialogTitle.java + */ +internal class DialogTitle : TextView { + + constructor( + context: Context, + attrs: AttributeSet, + defStyleAttr: Int, + defStyleRes: Int, + ) : super(context, attrs, defStyleAttr, defStyleRes) + + constructor( + context: Context, + attrs: AttributeSet, + defStyleAttr: Int, + ) : super(context, attrs, defStyleAttr) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context) : super(context) + + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec) + val layout = layout + if (layout != null) { + val lineCount = layout.lineCount + if (lineCount > 0) { + val ellipsisCount = layout.getEllipsisCount(lineCount - 1) + if (ellipsisCount > 0) { + setSingleLine(false) + setMaxLines(2) + super.onMeasure(widthMeasureSpec, heightMeasureSpec) + } + } + } + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.kt index 915d8830f34220..fcdff87bad9dee 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.kt @@ -132,7 +132,7 @@ constructor( } public companion object { - internal const val NAME = "FrescoModule" + public const val NAME: String = "FrescoModule" private var hasBeenInitialized = false /** diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nManagerModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nManagerModule.kt index 6b3b22565b5e6d..946accfae0374f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nManagerModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/I18nManagerModule.kt @@ -35,4 +35,8 @@ public class I18nManagerModule(context: ReactApplicationContext?) : NativeI18nMa override fun swapLeftAndRightInRTL(value: Boolean) { I18nUtil.instance.swapLeftAndRightInRTL(getReactApplicationContext(), value) } + + public companion object { + public const val NAME: String = NativeI18nManagerSpec.NAME + } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/PermissionsModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/PermissionsModule.kt index 5de54bd0752b0e..8920c22af8f7b7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/PermissionsModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/PermissionsModule.kt @@ -183,7 +183,8 @@ public class PermissionsModule(reactContext: ReactApplicationContext?) : return activity } - private companion object { + public companion object { + public const val NAME: String = NativePermissionsAndroidSpec.NAME private const val ERROR_INVALID_ACTIVITY = "E_INVALID_ACTIVITY" } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule.kt index fc4b24e4fd3732..5746061a0f30ab 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule.kt @@ -26,7 +26,8 @@ public class ReactDevToolsSettingsManagerModule(reactContext: ReactApplicationCo public override fun getGlobalHookSettings(): String? = sharedPreferences.getString(KEY_HOOK_SETTINGS, null) - private companion object { + public companion object { + public const val NAME: String = NativeReactDevToolsSettingsManagerSpec.NAME private const val SHARED_PREFERENCES_PREFIX = "ReactNative__DevToolsSettings" private const val KEY_HOOK_SETTINGS = "HookSettings" } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/share/ShareModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/share/ShareModule.kt index 05fef67b2cfc5c..2ee48db643f230 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/share/ShareModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/share/ShareModule.kt @@ -59,6 +59,7 @@ public class ShareModule(reactContext: ReactApplicationContext) : } public companion object { + public const val NAME: String = NativeShareModuleSpec.NAME const private val ACTION_SHARED: String = "sharedAction" const public val ERROR_INVALID_CONTENT: String = "E_INVALID_CONTENT" const private val ERROR_UNABLE_TO_OPEN_DIALOG: String = "E_UNABLE_TO_OPEN_DIALOG" diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/sound/SoundManagerModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/sound/SoundManagerModule.kt index df45543102d59f..9f996d69f4a65e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/sound/SoundManagerModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/sound/SoundManagerModule.kt @@ -23,4 +23,8 @@ public class SoundManagerModule(reactContext: ReactApplicationContext?) : getReactApplicationContext().getSystemService(Context.AUDIO_SERVICE) as AudioManager audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK) } + + public companion object { + public const val NAME: String = NativeSoundManagerSpec.NAME + } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/VibrationModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/VibrationModule.kt index 8f91ee9fbe21d8..2056bbb274915b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/VibrationModule.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/VibrationModule.kt @@ -61,4 +61,8 @@ public class VibrationModule(reactContext: ReactApplicationContext) : @Suppress("DEPRECATION") getReactApplicationContext().getSystemService(Context.VIBRATOR_SERVICE) as Vibrator? } + + public companion object { + public const val NAME: String = NativeVibrationSpec.NAME + } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java index a5732d3c893c13..b9fc10da9d0705 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java @@ -923,6 +923,17 @@ private Task getOrCreateStartTask() { final String method = "getOrCreateStartTask()"; if (mStartTask == null) { log(method, "Schedule"); + Assertions.assertCondition( + ReactNativeFeatureFlags.enableBridgelessArchitecture(), + "enableBridgelessArchitecture FeatureFlag must be set to start ReactNative."); + + Assertions.assertCondition( + ReactNativeFeatureFlags.enableFabricRenderer(), + "enableFabricRenderer FeatureFlag must be set to start ReactNative."); + + Assertions.assertCondition( + ReactNativeFeatureFlags.useTurboModules(), + "useTurboModules FeatureFlag must be set to start ReactNative."); mStartTask = waitThenCallGetOrCreateReactInstanceTask() .continueWithTask( diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java deleted file mode 100644 index 089c0b2e523c7f..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * 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. - */ - -package com.facebook.react.shell; - -import android.annotation.SuppressLint; -import androidx.annotation.Nullable; -import com.facebook.react.BaseReactPackage; -import com.facebook.react.ViewManagerOnDemandReactPackage; -import com.facebook.react.animated.NativeAnimatedModule; -import com.facebook.react.bridge.ModuleSpec; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.common.ClassFinder; -import com.facebook.react.module.annotations.ReactModule; -import com.facebook.react.module.annotations.ReactModuleList; -import com.facebook.react.module.model.ReactModuleInfo; -import com.facebook.react.module.model.ReactModuleInfoProvider; -import com.facebook.react.modules.accessibilityinfo.AccessibilityInfoModule; -import com.facebook.react.modules.appearance.AppearanceModule; -import com.facebook.react.modules.appstate.AppStateModule; -import com.facebook.react.modules.blob.BlobModule; -import com.facebook.react.modules.blob.FileReaderModule; -import com.facebook.react.modules.camera.ImageStoreManager; -import com.facebook.react.modules.clipboard.ClipboardModule; -import com.facebook.react.modules.devloading.DevLoadingModule; -import com.facebook.react.modules.devtoolsruntimesettings.ReactDevToolsRuntimeSettingsModule; -import com.facebook.react.modules.dialog.DialogModule; -import com.facebook.react.modules.fresco.FrescoModule; -import com.facebook.react.modules.i18nmanager.I18nManagerModule; -import com.facebook.react.modules.image.ImageLoaderModule; -import com.facebook.react.modules.intent.IntentModule; -import com.facebook.react.modules.network.NetworkingModule; -import com.facebook.react.modules.permissions.PermissionsModule; -import com.facebook.react.modules.reactdevtoolssettings.ReactDevToolsSettingsManagerModule; -import com.facebook.react.modules.share.ShareModule; -import com.facebook.react.modules.sound.SoundManagerModule; -import com.facebook.react.modules.statusbar.StatusBarModule; -import com.facebook.react.modules.toast.ToastModule; -import com.facebook.react.modules.vibration.VibrationModule; -import com.facebook.react.modules.websocket.WebSocketModule; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.ViewManager; -import com.facebook.react.views.drawer.ReactDrawerLayoutManager; -import com.facebook.react.views.image.ReactImageManager; -import com.facebook.react.views.modal.ReactModalHostManager; -import com.facebook.react.views.progressbar.ReactProgressBarViewManager; -import com.facebook.react.views.safeareaview.ReactSafeAreaViewManager; -import com.facebook.react.views.scroll.ReactHorizontalScrollContainerViewManager; -import com.facebook.react.views.scroll.ReactHorizontalScrollViewManager; -import com.facebook.react.views.scroll.ReactScrollViewManager; -import com.facebook.react.views.swiperefresh.SwipeRefreshLayoutManager; -import com.facebook.react.views.switchview.ReactSwitchManager; -import com.facebook.react.views.text.ReactRawTextManager; -import com.facebook.react.views.text.ReactTextViewManager; -import com.facebook.react.views.text.ReactVirtualTextViewManager; -import com.facebook.react.views.text.frescosupport.FrescoBasedReactTextInlineImageViewManager; -import com.facebook.react.views.textinput.ReactTextInputManager; -import com.facebook.react.views.unimplementedview.ReactUnimplementedViewManager; -import com.facebook.react.views.view.ReactViewManager; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.inject.Provider; - -/** Package defining basic modules and view managers. */ -@ReactModuleList( - nativeModules = { - AccessibilityInfoModule.class, - AppearanceModule.class, - AppStateModule.class, - BlobModule.class, - DevLoadingModule.class, - FileReaderModule.class, - ClipboardModule.class, - DialogModule.class, - FrescoModule.class, - I18nManagerModule.class, - ImageLoaderModule.class, - ImageStoreManager.class, - IntentModule.class, - NativeAnimatedModule.class, - NetworkingModule.class, - PermissionsModule.class, - ReactDevToolsSettingsManagerModule.class, - ReactDevToolsRuntimeSettingsModule.class, - ShareModule.class, - SoundManagerModule.class, - StatusBarModule.class, - ToastModule.class, - VibrationModule.class, - WebSocketModule.class, - }) -public class MainReactPackage extends BaseReactPackage implements ViewManagerOnDemandReactPackage { - - private MainPackageConfig mConfig; - private @Nullable Map mViewManagers; - - public MainReactPackage() {} - - /** Create a new package with configuration */ - public MainReactPackage(MainPackageConfig config) { - mConfig = config; - } - - @Override - public @Nullable NativeModule getModule(String name, ReactApplicationContext context) { - switch (name) { - case AccessibilityInfoModule.NAME: - return new AccessibilityInfoModule(context); - case AppearanceModule.NAME: - return new AppearanceModule(context); - case AppStateModule.NAME: - return new AppStateModule(context); - case BlobModule.NAME: - return new BlobModule(context); - case DevLoadingModule.NAME: - return new DevLoadingModule(context); - case FileReaderModule.NAME: - return new FileReaderModule(context); - case ClipboardModule.NAME: - return new ClipboardModule(context); - case DialogModule.NAME: - return new DialogModule(context); - case FrescoModule.NAME: - return new FrescoModule(context, true, mConfig != null ? mConfig.getFrescoConfig() : null); - case I18nManagerModule.NAME: - return new I18nManagerModule(context); - case ImageLoaderModule.NAME: - return new ImageLoaderModule(context); - case ImageStoreManager.NAME: - return new ImageStoreManager(context); - case IntentModule.NAME: - return new IntentModule(context); - case NativeAnimatedModule.NAME: - return new NativeAnimatedModule(context); - case NetworkingModule.NAME: - return new NetworkingModule(context); - case PermissionsModule.NAME: - return new PermissionsModule(context); - case ShareModule.NAME: - return new ShareModule(context); - case StatusBarModule.NAME: - return new StatusBarModule(context); - case SoundManagerModule.NAME: - return new SoundManagerModule(context); - case ToastModule.NAME: - return new ToastModule(context); - case VibrationModule.NAME: - return new VibrationModule(context); - case WebSocketModule.NAME: - return new WebSocketModule(context); - case ReactDevToolsSettingsManagerModule.NAME: - return new ReactDevToolsSettingsManagerModule(context); - case ReactDevToolsRuntimeSettingsModule.NAME: - return new ReactDevToolsRuntimeSettingsModule(context); - default: - return null; - } - } - - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - List viewManagers = new ArrayList<>(); - - viewManagers.add(new ReactDrawerLayoutManager()); - viewManagers.add(new ReactHorizontalScrollViewManager()); - viewManagers.add(new ReactHorizontalScrollContainerViewManager()); - viewManagers.add(new ReactProgressBarViewManager()); - viewManagers.add(new ReactScrollViewManager()); - viewManagers.add(new ReactSwitchManager()); - viewManagers.add(new ReactSafeAreaViewManager()); - viewManagers.add(new SwipeRefreshLayoutManager()); - - // Native equivalents - viewManagers.add(new FrescoBasedReactTextInlineImageViewManager()); - viewManagers.add(new ReactImageManager()); - viewManagers.add(new ReactModalHostManager()); - viewManagers.add(new ReactRawTextManager()); - viewManagers.add(new ReactTextInputManager()); - viewManagers.add(new ReactTextViewManager()); - viewManagers.add(new ReactViewManager()); - viewManagers.add(new ReactVirtualTextViewManager()); - - viewManagers.add(new ReactUnimplementedViewManager()); - - return viewManagers; - } - - private static void appendMap( - Map map, String name, Provider provider) { - map.put(name, ModuleSpec.viewManagerSpec(provider)); - } - - /** - * @return a map of view managers that should be registered with {@link UIManagerModule} - */ - @SuppressLint("VisibleForTests") - public Map getViewManagersMap() { - if (mViewManagers == null) { - Map viewManagers = new HashMap<>(); - appendMap(viewManagers, ReactDrawerLayoutManager.REACT_CLASS, ReactDrawerLayoutManager::new); - appendMap( - viewManagers, - ReactHorizontalScrollViewManager.REACT_CLASS, - ReactHorizontalScrollViewManager::new); - appendMap( - viewManagers, - ReactHorizontalScrollContainerViewManager.REACT_CLASS, - ReactHorizontalScrollContainerViewManager::new); - appendMap( - viewManagers, ReactProgressBarViewManager.REACT_CLASS, ReactProgressBarViewManager::new); - appendMap(viewManagers, ReactSafeAreaViewManager.REACT_CLASS, ReactSafeAreaViewManager::new); - appendMap(viewManagers, ReactScrollViewManager.REACT_CLASS, ReactScrollViewManager::new); - appendMap(viewManagers, ReactSwitchManager.REACT_CLASS, ReactSwitchManager::new); - appendMap( - viewManagers, SwipeRefreshLayoutManager.REACT_CLASS, SwipeRefreshLayoutManager::new); - appendMap( - viewManagers, - FrescoBasedReactTextInlineImageViewManager.REACT_CLASS, - FrescoBasedReactTextInlineImageViewManager::new); - appendMap(viewManagers, ReactImageManager.REACT_CLASS, ReactImageManager::new); - appendMap(viewManagers, ReactModalHostManager.REACT_CLASS, ReactModalHostManager::new); - appendMap(viewManagers, ReactRawTextManager.REACT_CLASS, ReactRawTextManager::new); - appendMap(viewManagers, ReactTextInputManager.REACT_CLASS, ReactTextInputManager::new); - appendMap(viewManagers, ReactTextViewManager.REACT_CLASS, ReactTextViewManager::new); - appendMap(viewManagers, ReactViewManager.REACT_CLASS, ReactViewManager::new); - appendMap( - viewManagers, ReactVirtualTextViewManager.REACT_CLASS, ReactVirtualTextViewManager::new); - appendMap( - viewManagers, - ReactUnimplementedViewManager.REACT_CLASS, - ReactUnimplementedViewManager::new); - mViewManagers = viewManagers; - } - return mViewManagers; - } - - @Override - public List getViewManagers(ReactApplicationContext reactContext) { - return new ArrayList<>(getViewManagersMap().values()); - } - - @Override - public Collection getViewManagerNames(ReactApplicationContext reactContext) { - return getViewManagersMap().keySet(); - } - - @Override - public @Nullable ViewManager createViewManager( - ReactApplicationContext reactContext, String viewManagerName) { - ModuleSpec spec = getViewManagersMap().get(viewManagerName); - return spec != null ? (ViewManager) spec.getProvider().get() : null; - } - - @Override - public ReactModuleInfoProvider getReactModuleInfoProvider() { - if (!ClassFinder.canLoadClassesFromAnnotationProcessors()) { - return fallbackForMissingClass(); - } - try { - Class reactModuleInfoProviderClass = - ClassFinder.findClass( - "com.facebook.react.shell.MainReactPackage$$ReactModuleInfoProvider"); - return (ReactModuleInfoProvider) reactModuleInfoProviderClass.newInstance(); - } catch (ClassNotFoundException e) { - return fallbackForMissingClass(); - } catch (InstantiationException e) { - throw new RuntimeException( - "No ReactModuleInfoProvider for" - + " com.facebook.react.shell.MainReactPackage$$ReactModuleInfoProvider", - e); - } catch (IllegalAccessException e) { - throw new RuntimeException( - "No ReactModuleInfoProvider for" - + " com.facebook.react.shell.MainReactPackage$$ReactModuleInfoProvider", - e); - } - } - - private ReactModuleInfoProvider fallbackForMissingClass() { - // In the OSS case, the annotation processor does not run. - // We fall back to creating this by hand - Class[] moduleList = - new Class[] { - AccessibilityInfoModule.class, - AppearanceModule.class, - AppStateModule.class, - BlobModule.class, - DevLoadingModule.class, - FileReaderModule.class, - ClipboardModule.class, - DialogModule.class, - FrescoModule.class, - I18nManagerModule.class, - ImageLoaderModule.class, - ImageStoreManager.class, - IntentModule.class, - NativeAnimatedModule.class, - NetworkingModule.class, - PermissionsModule.class, - ReactDevToolsSettingsManagerModule.class, - ReactDevToolsRuntimeSettingsModule.class, - ShareModule.class, - StatusBarModule.class, - SoundManagerModule.class, - ToastModule.class, - VibrationModule.class, - WebSocketModule.class - }; - - final Map reactModuleInfoMap = new HashMap<>(); - for (Class moduleClass : moduleList) { - ReactModule reactModule = moduleClass.getAnnotation(ReactModule.class); - if (reactModule != null) { - reactModuleInfoMap.put( - reactModule.name(), - new ReactModuleInfo( - reactModule.name(), - moduleClass.getName(), - reactModule.canOverrideExistingModule(), - reactModule.needsEagerInit(), - reactModule.isCxxModule(), - ReactModuleInfo.classIsTurboModule(moduleClass))); - } - } - return () -> reactModuleInfoMap; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.kt new file mode 100644 index 00000000000000..a7efbecb07443f --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.kt @@ -0,0 +1,272 @@ +/* + * 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. + */ + +package com.facebook.react.shell + +import android.annotation.SuppressLint +import com.facebook.react.BaseReactPackage +import com.facebook.react.ViewManagerOnDemandReactPackage +import com.facebook.react.animated.NativeAnimatedModule +import com.facebook.react.bridge.ModuleSpec +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.common.ClassFinder +import com.facebook.react.module.annotations.ReactModule +import com.facebook.react.module.annotations.ReactModuleList +import com.facebook.react.module.model.ReactModuleInfo +import com.facebook.react.module.model.ReactModuleInfo.Companion.classIsTurboModule +import com.facebook.react.module.model.ReactModuleInfoProvider +import com.facebook.react.modules.accessibilityinfo.AccessibilityInfoModule +import com.facebook.react.modules.appearance.AppearanceModule +import com.facebook.react.modules.appstate.AppStateModule +import com.facebook.react.modules.blob.BlobModule +import com.facebook.react.modules.blob.FileReaderModule +import com.facebook.react.modules.camera.ImageStoreManager +import com.facebook.react.modules.clipboard.ClipboardModule +import com.facebook.react.modules.devloading.DevLoadingModule +import com.facebook.react.modules.devtoolsruntimesettings.ReactDevToolsRuntimeSettingsModule +import com.facebook.react.modules.dialog.DialogModule +import com.facebook.react.modules.fresco.FrescoModule +import com.facebook.react.modules.i18nmanager.I18nManagerModule +import com.facebook.react.modules.image.ImageLoaderModule +import com.facebook.react.modules.intent.IntentModule +import com.facebook.react.modules.network.NetworkingModule +import com.facebook.react.modules.permissions.PermissionsModule +import com.facebook.react.modules.reactdevtoolssettings.ReactDevToolsSettingsManagerModule +import com.facebook.react.modules.share.ShareModule +import com.facebook.react.modules.sound.SoundManagerModule +import com.facebook.react.modules.statusbar.StatusBarModule +import com.facebook.react.modules.toast.ToastModule +import com.facebook.react.modules.vibration.VibrationModule +import com.facebook.react.modules.websocket.WebSocketModule +import com.facebook.react.uimanager.ViewManager +import com.facebook.react.views.drawer.ReactDrawerLayoutManager +import com.facebook.react.views.image.ReactImageManager +import com.facebook.react.views.modal.ReactModalHostManager +import com.facebook.react.views.progressbar.ReactProgressBarViewManager +import com.facebook.react.views.safeareaview.ReactSafeAreaViewManager +import com.facebook.react.views.scroll.ReactHorizontalScrollContainerViewManager +import com.facebook.react.views.scroll.ReactHorizontalScrollViewManager +import com.facebook.react.views.scroll.ReactScrollViewManager +import com.facebook.react.views.swiperefresh.SwipeRefreshLayoutManager +import com.facebook.react.views.switchview.ReactSwitchManager +import com.facebook.react.views.text.ReactRawTextManager +import com.facebook.react.views.text.ReactTextViewManager +import com.facebook.react.views.text.ReactVirtualTextViewManager +import com.facebook.react.views.text.frescosupport.FrescoBasedReactTextInlineImageViewManager +import com.facebook.react.views.textinput.ReactTextInputManager +import com.facebook.react.views.unimplementedview.ReactUnimplementedViewManager +import com.facebook.react.views.view.ReactViewManager + +/** + * Package defining basic modules and view managers. + * + * @param config configuration for the Main package. + */ +@ReactModuleList( + nativeModules = + [ + AccessibilityInfoModule::class, + AppearanceModule::class, + AppStateModule::class, + BlobModule::class, + DevLoadingModule::class, + FileReaderModule::class, + ClipboardModule::class, + DialogModule::class, + FrescoModule::class, + I18nManagerModule::class, + ImageLoaderModule::class, + ImageStoreManager::class, + IntentModule::class, + NativeAnimatedModule::class, + NetworkingModule::class, + PermissionsModule::class, + ReactDevToolsSettingsManagerModule::class, + ReactDevToolsRuntimeSettingsModule::class, + ShareModule::class, + SoundManagerModule::class, + StatusBarModule::class, + ToastModule::class, + VibrationModule::class, + WebSocketModule::class, + ]) +public class MainReactPackage +@JvmOverloads +constructor(private val config: MainPackageConfig? = null) : + BaseReactPackage(), ViewManagerOnDemandReactPackage { + + override fun getModule(name: String, context: ReactApplicationContext): NativeModule? = + when (name) { + AccessibilityInfoModule.NAME -> AccessibilityInfoModule(context) + AppearanceModule.NAME -> AppearanceModule(context) + AppStateModule.NAME -> AppStateModule(context) + BlobModule.NAME -> BlobModule(context) + DevLoadingModule.NAME -> DevLoadingModule(context) + FileReaderModule.NAME -> FileReaderModule(context) + ClipboardModule.NAME -> ClipboardModule(context) + DialogModule.NAME -> DialogModule(context) + FrescoModule.NAME -> FrescoModule(context, true, config?.frescoConfig) + I18nManagerModule.NAME -> I18nManagerModule(context) + ImageLoaderModule.NAME -> ImageLoaderModule(context) + ImageStoreManager.NAME -> ImageStoreManager(context) + IntentModule.NAME -> IntentModule(context) + NativeAnimatedModule.NAME -> NativeAnimatedModule(context) + NetworkingModule.NAME -> NetworkingModule(context) + PermissionsModule.NAME -> PermissionsModule(context) + ShareModule.NAME -> ShareModule(context) + StatusBarModule.NAME -> StatusBarModule(context) + SoundManagerModule.NAME -> SoundManagerModule(context) + ToastModule.NAME -> ToastModule(context) + VibrationModule.NAME -> VibrationModule(context) + WebSocketModule.NAME -> WebSocketModule(context) + ReactDevToolsSettingsManagerModule.NAME -> ReactDevToolsSettingsManagerModule(context) + ReactDevToolsRuntimeSettingsModule.NAME -> ReactDevToolsRuntimeSettingsModule(context) + else -> null + } + + override fun createViewManagers(reactContext: ReactApplicationContext): List> = + listOf( + ReactDrawerLayoutManager(), + ReactHorizontalScrollViewManager(), + ReactHorizontalScrollContainerViewManager(), + ReactProgressBarViewManager(), + ReactScrollViewManager(), + ReactSwitchManager(), + ReactSafeAreaViewManager(), + SwipeRefreshLayoutManager(), + // Native equivalents + FrescoBasedReactTextInlineImageViewManager(), + ReactImageManager(), + ReactModalHostManager(), + ReactRawTextManager(), + ReactTextInputManager(), + ReactTextViewManager(), + ReactViewManager(), + ReactVirtualTextViewManager(), + ReactUnimplementedViewManager()) + + /** + * A map of view managers that should be registered with + * [com.facebook.react.uimanager.UIManagerModule] + */ + @SuppressLint("VisibleForTests") + public val viewManagersMap: Map = + mapOf( + ReactDrawerLayoutManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { ReactDrawerLayoutManager() }, + ReactHorizontalScrollViewManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { ReactHorizontalScrollViewManager() }, + ReactHorizontalScrollContainerViewManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { ReactHorizontalScrollContainerViewManager() }, + ReactProgressBarViewManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { ReactProgressBarViewManager() }, + ReactSafeAreaViewManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { ReactSafeAreaViewManager() }, + ReactScrollViewManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { ReactScrollViewManager() }, + ReactSwitchManager.REACT_CLASS to ModuleSpec.viewManagerSpec { ReactSwitchManager() }, + SwipeRefreshLayoutManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { SwipeRefreshLayoutManager() }, + FrescoBasedReactTextInlineImageViewManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { FrescoBasedReactTextInlineImageViewManager() }, + ReactImageManager.REACT_CLASS to ModuleSpec.viewManagerSpec { ReactImageManager() }, + ReactModalHostManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { ReactModalHostManager() }, + ReactRawTextManager.REACT_CLASS to ModuleSpec.viewManagerSpec { ReactRawTextManager() }, + ReactTextInputManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { ReactTextInputManager() }, + ReactTextViewManager.REACT_CLASS to ModuleSpec.viewManagerSpec { ReactTextViewManager() }, + ReactViewManager.REACT_CLASS to ModuleSpec.viewManagerSpec { ReactViewManager() }, + ReactVirtualTextViewManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { ReactVirtualTextViewManager() }, + ReactUnimplementedViewManager.REACT_CLASS to + ModuleSpec.viewManagerSpec { ReactUnimplementedViewManager() }) + + public override fun getViewManagers(reactContext: ReactApplicationContext): List = + viewManagersMap.values.toList() + + override fun getViewManagerNames(reactContext: ReactApplicationContext): Collection = + viewManagersMap.keys + + override fun createViewManager( + reactContext: ReactApplicationContext, + viewManagerName: String + ): ViewManager<*, *>? { + val spec = viewManagersMap[viewManagerName] + return spec?.provider?.get() as? ViewManager<*, *> + } + + override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { + if (!ClassFinder.canLoadClassesFromAnnotationProcessors()) { + return fallbackForMissingClass() + } + try { + val reactModuleInfoProviderClass = + ClassFinder.findClass( + "com.facebook.react.shell.MainReactPackage$\$ReactModuleInfoProvider") + @Suppress("DEPRECATION") + return reactModuleInfoProviderClass?.newInstance() as? ReactModuleInfoProvider + ?: fallbackForMissingClass() + } catch (e: ClassNotFoundException) { + return fallbackForMissingClass() + } catch (e: InstantiationException) { + throw RuntimeException( + "No ReactModuleInfoProvider for MainReactPackage$\$ReactModuleInfoProvider", e) + } catch (e: IllegalAccessException) { + throw RuntimeException( + "No ReactModuleInfoProvider for MainReactPackage$\$ReactModuleInfoProvider", e) + } + } + + private fun fallbackForMissingClass(): ReactModuleInfoProvider { + // In the OSS case, the annotation processor does not run. + // We fall back to creating this by hand + val moduleList: Array> = + arrayOf( + AccessibilityInfoModule::class.java, + AppearanceModule::class.java, + AppStateModule::class.java, + BlobModule::class.java, + DevLoadingModule::class.java, + FileReaderModule::class.java, + ClipboardModule::class.java, + DialogModule::class.java, + FrescoModule::class.java, + I18nManagerModule::class.java, + ImageLoaderModule::class.java, + ImageStoreManager::class.java, + IntentModule::class.java, + NativeAnimatedModule::class.java, + NetworkingModule::class.java, + PermissionsModule::class.java, + ReactDevToolsSettingsManagerModule::class.java, + ReactDevToolsRuntimeSettingsModule::class.java, + ShareModule::class.java, + StatusBarModule::class.java, + SoundManagerModule::class.java, + ToastModule::class.java, + VibrationModule::class.java, + WebSocketModule::class.java) + + val moduleMap = + moduleList + .filter { it.isAnnotationPresent(ReactModule::class.java) } + .associate { moduleClass -> + val reactModule = checkNotNull(moduleClass.getAnnotation(ReactModule::class.java)) + reactModule.name to + ReactModuleInfo( + reactModule.name, + moduleClass.name, + reactModule.canOverrideExistingModule, + reactModule.needsEagerInit, + reactModule.isCxxModule, + classIsTurboModule(moduleClass)) + } + return ReactModuleInfoProvider { moduleMap } + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt index 50724f23a6f764..a4cd613b6dbd98 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt @@ -9,17 +9,23 @@ package com.facebook.react.uimanager import android.graphics.Canvas import android.graphics.Color +import android.graphics.Path import android.graphics.Rect +import android.graphics.RectF import android.graphics.drawable.Drawable import android.os.Build import android.view.View +import android.widget.ImageView import androidx.annotation.ColorInt import com.facebook.react.bridge.ReadableArray import com.facebook.react.common.annotations.UnstableReactNativeAPI +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags import com.facebook.react.uimanager.PixelUtil.dpToPx import com.facebook.react.uimanager.PixelUtil.pxToDp import com.facebook.react.uimanager.common.UIManagerType import com.facebook.react.uimanager.common.ViewUtil +import com.facebook.react.uimanager.drawable.BackgroundDrawable +import com.facebook.react.uimanager.drawable.BorderDrawable import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable import com.facebook.react.uimanager.drawable.CompositeBackgroundDrawable import com.facebook.react.uimanager.drawable.InsetBoxShadowDrawable @@ -51,7 +57,11 @@ public object BackgroundStyleApplicator { return } - ensureCSSBackground(view).color = color ?: Color.TRANSPARENT + if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + ensureBackgroundDrawable(view).backgroundColor = color ?: Color.TRANSPARENT + } else { + ensureCSSBackground(view).color = color ?: Color.TRANSPARENT + } } @JvmStatic @@ -59,19 +69,43 @@ public object BackgroundStyleApplicator { view: View, backgroundImageLayers: List? ): Unit { - ensureCSSBackground(view).setBackgroundImage(backgroundImageLayers) + if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + ensureBackgroundDrawable(view).backgroundImageLayers = backgroundImageLayers + } else { + ensureCSSBackground(view).setBackgroundImage(backgroundImageLayers) + } } @JvmStatic @ColorInt - public fun getBackgroundColor(view: View): Int? = getCSSBackground(view)?.color + public fun getBackgroundColor(view: View): Int? { + return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + getBackground(view)?.backgroundColor + } else { + getCSSBackground(view)?.color + } + } @JvmStatic public fun setBorderWidth(view: View, edge: LogicalEdge, width: Float?): Unit { - ensureCSSBackground(view).setBorderWidth(edge.toSpacingType(), width?.dpToPx() ?: Float.NaN) + val composite = ensureCompositeBackgroundDrawable(view) + composite.borderInsets = composite.borderInsets ?: BorderInsets() + composite.borderInsets?.setBorderWidth(edge, width) + + if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + ensureBorderDrawable(view).setBorderWidth(edge.toSpacingType(), width?.dpToPx() ?: Float.NaN) + composite.background?.borderInsets = composite.borderInsets + composite.border?.borderInsets = composite.borderInsets + + composite.background?.invalidateSelf() + composite.border?.invalidateSelf() + } else { + ensureCSSBackground(view).setBorderWidth(edge.toSpacingType(), width?.dpToPx() ?: Float.NaN) + } + composite.borderInsets = composite.borderInsets ?: BorderInsets() + composite.borderInsets?.setBorderWidth(edge, width) if (Build.VERSION.SDK_INT >= MIN_INSET_BOX_SHADOW_SDK_VERSION) { - val composite = ensureCompositeBackgroundDrawable(view) composite.borderInsets = composite.borderInsets ?: BorderInsets() composite.borderInsets?.setBorderWidth(edge, width) @@ -84,18 +118,33 @@ public object BackgroundStyleApplicator { @JvmStatic public fun getBorderWidth(view: View, edge: LogicalEdge): Float? { - val width = getCSSBackground(view)?.getBorderWidth(edge.toSpacingType()) - return if (width == null || width.isNaN()) null else width.pxToDp() + return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + val width = getBorder(view)?.borderWidth?.getRaw(edge.toSpacingType()) + if (width == null || width.isNaN()) null else width.pxToDp() + } else { + val width = getCSSBackground(view)?.getBorderWidth(edge.toSpacingType()) + if (width == null || width.isNaN()) null else width.pxToDp() + } } @JvmStatic - public fun setBorderColor(view: View, edge: LogicalEdge, @ColorInt color: Int?): Unit = + public fun setBorderColor(view: View, edge: LogicalEdge, @ColorInt color: Int?): Unit { + if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + ensureBorderDrawable(view).setBorderColor(edge, color) + } else { ensureCSSBackground(view).setBorderColor(edge.toSpacingType(), color) + } + } @JvmStatic @ColorInt - public fun getBorderColor(view: View, edge: LogicalEdge): Int? = + public fun getBorderColor(view: View, edge: LogicalEdge): Int? { + return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + getBorder(view)?.getBorderColor(edge) + } else { getCSSBackground(view)?.getBorderColor(edge.toSpacingType()) + } + } @JvmStatic public fun setBorderRadius( @@ -103,15 +152,29 @@ public object BackgroundStyleApplicator { corner: BorderRadiusProp, radius: LengthPercentage? ): Unit { - ensureCSSBackground(view).setBorderRadius(corner, radius) val compositeBackgroundDrawable = ensureCompositeBackgroundDrawable(view) + compositeBackgroundDrawable.borderRadius = + compositeBackgroundDrawable.borderRadius ?: BorderRadiusStyle() + compositeBackgroundDrawable.borderRadius?.set(corner, radius) + + if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + if (view is ImageView) { + ensureBackgroundDrawable(view) + } + compositeBackgroundDrawable.background?.borderRadius = + compositeBackgroundDrawable.borderRadius + compositeBackgroundDrawable.border?.borderRadius = compositeBackgroundDrawable.borderRadius + + compositeBackgroundDrawable.background?.invalidateSelf() + compositeBackgroundDrawable.border?.invalidateSelf() + } else { + ensureCSSBackground(view).setBorderRadius(corner, radius) + } if (Build.VERSION.SDK_INT >= MIN_OUTSET_BOX_SHADOW_SDK_VERSION) { for (shadow in compositeBackgroundDrawable.outerShadows) { if (shadow is OutsetBoxShadowDrawable) { - shadow.borderRadius = shadow.borderRadius ?: BorderRadiusStyle() - shadow.borderRadius?.set(corner, radius) - shadow.invalidateSelf() + shadow.borderRadius = compositeBackgroundDrawable.borderRadius } } } @@ -119,32 +182,42 @@ public object BackgroundStyleApplicator { if (Build.VERSION.SDK_INT >= MIN_INSET_BOX_SHADOW_SDK_VERSION) { for (shadow in compositeBackgroundDrawable.innerShadows) { if (shadow is InsetBoxShadowDrawable) { - shadow.borderRadius = shadow.borderRadius ?: BorderRadiusStyle() - shadow.borderRadius?.set(corner, radius) - shadow.invalidateSelf() + shadow.borderRadius = compositeBackgroundDrawable.borderRadius } } } - val outline = compositeBackgroundDrawable.outline - if (outline != null) { - outline.borderRadius = outline.borderRadius ?: BorderRadiusStyle() - outline.borderRadius?.set(corner, radius) - outline.invalidateSelf() - } + compositeBackgroundDrawable.outline?.borderRadius = compositeBackgroundDrawable.borderRadius + compositeBackgroundDrawable.invalidateSelf() } @JvmStatic - public fun getBorderRadius(view: View, corner: BorderRadiusProp): LengthPercentage? = + public fun getBorderRadius(view: View, corner: BorderRadiusProp): LengthPercentage? { + + return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + getCompositeBackgroundDrawable(view)?.borderRadius?.get(corner) + } else { getCSSBackground(view)?.borderRadius?.get(corner) + } + } @JvmStatic public fun setBorderStyle(view: View, borderStyle: BorderStyle?): Unit { - ensureCSSBackground(view).borderStyle = borderStyle + if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + ensureBorderDrawable(view).borderStyle = borderStyle + } else { + ensureCSSBackground(view).borderStyle = borderStyle + } } @JvmStatic - public fun getBorderStyle(view: View): BorderStyle? = getCSSBackground(view)?.borderStyle + public fun getBorderStyle(view: View): BorderStyle? { + return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + getBorder(view)?.borderStyle + } else { + getCSSBackground(view)?.borderStyle + } + } @JvmStatic public fun setOutlineColor(view: View, @ColorInt outlineColor: Int?): Unit { @@ -207,7 +280,9 @@ public object BackgroundStyleApplicator { val outerShadows = mutableListOf() val innerShadows = mutableListOf() - val borderInsets = ensureCompositeBackgroundDrawable(view).borderInsets + val compositeBackgroundDrawable = ensureCompositeBackgroundDrawable(view) + val borderInsets = compositeBackgroundDrawable.borderInsets + val borderRadius = compositeBackgroundDrawable.borderRadius for (boxShadow in shadows) { val offsetX = boxShadow.offsetX @@ -221,7 +296,7 @@ public object BackgroundStyleApplicator { innerShadows.add( InsetBoxShadowDrawable( context = view.context, - borderRadius = ensureCSSBackground(view).borderRadius, + borderRadius = borderRadius, borderInsets = borderInsets, shadowColor = color, offsetX = offsetX, @@ -232,7 +307,7 @@ public object BackgroundStyleApplicator { outerShadows.add( OutsetBoxShadowDrawable( context = view.context, - borderRadius = ensureCSSBackground(view).borderRadius, + borderRadius = borderRadius, shadowColor = color, offsetX = offsetX, offsetY = offsetY, @@ -262,29 +337,66 @@ public object BackgroundStyleApplicator { @JvmStatic public fun setFeedbackUnderlay(view: View, drawable: Drawable?): Unit { - view.background = ensureCompositeBackgroundDrawable(view).withNewFeedbackUnderlay(drawable) + if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + + ensureCompositeBackgroundDrawable(view).withNewFeedbackUnderlay(drawable) + } else { + view.background = ensureCompositeBackgroundDrawable(view).withNewFeedbackUnderlay(drawable) + } } @JvmStatic public fun clipToPaddingBox(view: View, canvas: Canvas): Unit { // The canvas may be scrolled, so we need to offset - val drawingRect = Rect() - view.getDrawingRect(drawingRect) + if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + val drawingRect = Rect() + view.getDrawingRect(drawingRect) + val composite = ensureCompositeBackgroundDrawable(view) + val paddingBoxRect = RectF() + + val computedBorderInsets = + composite.borderInsets?.resolve(composite.layoutDirection, view.context) + + paddingBoxRect.left = composite.bounds.left + (computedBorderInsets?.left?.dpToPx() ?: 0f) + paddingBoxRect.top = composite.bounds.top + (computedBorderInsets?.top?.dpToPx() ?: 0f) + paddingBoxRect.right = composite.bounds.right - (computedBorderInsets?.right?.dpToPx() ?: 0f) + paddingBoxRect.bottom = + composite.bounds.bottom - (computedBorderInsets?.bottom?.dpToPx() ?: 0f) + + if (composite.borderRadius?.hasRoundedBorders() == true) { + val paddingBoxPath = + createPaddingBoxPath( + view, + composite, + paddingBoxRect, + computedBorderInsets, + ) + + paddingBoxPath.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat()) + canvas.clipPath(paddingBoxPath) + } else { + paddingBoxRect.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat()) + canvas.clipRect(paddingBoxRect) + } + } else { + val drawingRect = Rect() + view.getDrawingRect(drawingRect) - val cssBackground = getCSSBackground(view) - if (cssBackground == null) { - canvas.clipRect(drawingRect) - return - } + val cssBackground = getCSSBackground(view) + if (cssBackground == null) { + canvas.clipRect(drawingRect) + return + } - val paddingBoxPath = cssBackground.paddingBoxPath - if (paddingBoxPath != null) { - paddingBoxPath.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat()) - canvas.clipPath(paddingBoxPath) - } else { - val paddingBoxRect = cssBackground.paddingBoxRect - paddingBoxRect.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat()) - canvas.clipRect(paddingBoxRect) + val paddingBoxPath = cssBackground.paddingBoxPath + if (paddingBoxPath != null) { + paddingBoxPath.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat()) + canvas.clipPath(paddingBoxPath) + } else { + val paddingBoxRect = cssBackground.paddingBoxRect + paddingBoxRect.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat()) + canvas.clipRect(paddingBoxRect) + } } } @@ -300,7 +412,8 @@ public object BackgroundStyleApplicator { return view.background as CompositeBackgroundDrawable } - val compositeDrawable = CompositeBackgroundDrawable(originalBackground = view.background) + val compositeDrawable = + CompositeBackgroundDrawable(context = view.context, originalBackground = view.background) view.background = compositeDrawable return compositeDrawable } @@ -310,31 +423,81 @@ public object BackgroundStyleApplicator { private fun ensureCSSBackground(view: View): CSSBackgroundDrawable { val compositeBackgroundDrawable = ensureCompositeBackgroundDrawable(view) - if (compositeBackgroundDrawable.cssBackground != null) { - return compositeBackgroundDrawable.cssBackground + var cssBackground = compositeBackgroundDrawable.cssBackground + + return if (cssBackground != null) { + return cssBackground } else { - val cssBackground = CSSBackgroundDrawable(view.context) + cssBackground = CSSBackgroundDrawable(view.context) view.background = compositeBackgroundDrawable.withNewCssBackground(cssBackground) - return cssBackground + cssBackground + } + } + + private fun ensureBackgroundDrawable(view: View): BackgroundDrawable { + val compositeBackgroundDrawable = ensureCompositeBackgroundDrawable(view) + var background = compositeBackgroundDrawable.background + + return if (background != null) { + background + } else { + background = + BackgroundDrawable( + view.context, + compositeBackgroundDrawable.borderRadius, + compositeBackgroundDrawable.borderInsets) + view.background = compositeBackgroundDrawable.withNewBackground(background) + background } } private fun getCSSBackground(view: View): CSSBackgroundDrawable? = getCompositeBackgroundDrawable(view)?.cssBackground + private fun getBackground(view: View): BackgroundDrawable? = + getCompositeBackgroundDrawable(view)?.background + + private fun getBorder(view: View): BorderDrawable? = getCompositeBackgroundDrawable(view)?.border + + private fun ensureBorderDrawable(view: View): BorderDrawable { + val compositeBackgroundDrawable = ensureCompositeBackgroundDrawable(view) + var border = compositeBackgroundDrawable.border + if (border == null) { + border = + BorderDrawable( + context = view.context, + borderRadius = compositeBackgroundDrawable.borderRadius, + borderWidth = Spacing(0f), + borderStyle = BorderStyle.SOLID, + borderInsets = compositeBackgroundDrawable.borderInsets, + ) + view.background = compositeBackgroundDrawable.withNewBorder(border) + } + + return border + } + private fun ensureOutlineDrawable(view: View): OutlineDrawable { val compositeBackgroundDrawable = ensureCompositeBackgroundDrawable(view) var outline = compositeBackgroundDrawable.outline if (outline == null) { + val borderRadius = + if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) { + compositeBackgroundDrawable.borderRadius + } else { + ensureCSSBackground(view).borderRadius + } + outline = OutlineDrawable( context = view.context, - borderRadius = ensureCSSBackground(view).borderRadius.copy(), + borderRadius = borderRadius, outlineColor = Color.BLACK, outlineOffset = 0f, outlineStyle = OutlineStyle.SOLID, outlineWidth = 0f, ) + view.background = compositeBackgroundDrawable.withNewOutline(outline) } @@ -343,4 +506,75 @@ public object BackgroundStyleApplicator { private fun getOutlineDrawable(view: View): OutlineDrawable? = getCompositeBackgroundDrawable(view)?.outline + + /** + * Here, "inner" refers to the border radius on the inside of the border. So it ends up being the + * "outer" border radius inset by the respective width. + */ + private fun getInnerBorderRadius(computedRadius: Float?, borderWidth: Float?): Float { + return ((computedRadius ?: 0f) - (borderWidth ?: 0f)).coerceAtLeast(0f) + } + + private fun createPaddingBoxPath( + view: View, + composite: CompositeBackgroundDrawable, + paddingBoxRect: RectF, + computedBorderInsets: RectF? + ): Path { + val computedBorderRadius = + composite.borderRadius?.resolve( + composite.layoutDirection, + view.context, + PixelUtil.toDIPFromPixel(composite.bounds.width().toFloat()), + PixelUtil.toDIPFromPixel(composite.bounds.height().toFloat()), + ) + + val paddingBoxPath = Path() + + val innerTopLeftRadiusX = + getInnerBorderRadius( + computedBorderRadius?.topLeft?.horizontal?.dpToPx(), + computedBorderInsets?.left?.dpToPx()) + val innerTopLeftRadiusY = + getInnerBorderRadius( + computedBorderRadius?.topLeft?.vertical?.dpToPx(), computedBorderInsets?.top?.dpToPx()) + val innerTopRightRadiusX = + getInnerBorderRadius( + computedBorderRadius?.topRight?.horizontal?.dpToPx(), + computedBorderInsets?.right?.dpToPx()) + val innerTopRightRadiusY = + getInnerBorderRadius( + computedBorderRadius?.topRight?.vertical?.dpToPx(), computedBorderInsets?.top?.dpToPx()) + val innerBottomRightRadiusX = + getInnerBorderRadius( + computedBorderRadius?.bottomRight?.horizontal?.dpToPx(), + computedBorderInsets?.right?.dpToPx()) + val innerBottomRightRadiusY = + getInnerBorderRadius( + computedBorderRadius?.bottomRight?.vertical?.dpToPx(), + computedBorderInsets?.bottom?.dpToPx()) + val innerBottomLeftRadiusX = + getInnerBorderRadius( + computedBorderRadius?.bottomLeft?.horizontal?.dpToPx(), + computedBorderInsets?.left?.dpToPx()) + val innerBottomLeftRadiusY = + getInnerBorderRadius( + computedBorderRadius?.bottomLeft?.vertical?.dpToPx(), + computedBorderInsets?.bottom?.dpToPx()) + + paddingBoxPath.addRoundRect( + paddingBoxRect, + floatArrayOf( + innerTopLeftRadiusX, + innerTopLeftRadiusY, + innerTopRightRadiusX, + innerTopRightRadiusY, + innerBottomRightRadiusX, + innerBottomRightRadiusY, + innerBottomLeftRadiusX, + innerBottomLeftRadiusY, + ), + Path.Direction.CW) + return paddingBoxPath + } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.kt index 0903d4ae21e1f0..d110900aeb1f72 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.kt @@ -24,7 +24,7 @@ public abstract class BaseViewManagerDelegate< @Suppress("NoHungarianNotation") @JvmField protected val mViewManager: U ) : ViewManagerDelegate { @Suppress("DEPRECATION") - override public fun setProperty(view: T, propName: String, value: Any?) { + override public fun setProperty(view: T, propName: String?, value: Any?) { when (propName) { ViewProps.ACCESSIBILITY_ACTIONS -> mViewManager.setAccessibilityActions(view, value as ReadableArray?) @@ -143,6 +143,6 @@ public abstract class BaseViewManagerDelegate< } } - override public fun receiveCommand(view: T, commandName: String, args: ReadableArray?): Unit = + override public fun receiveCommand(view: T, commandName: String?, args: ReadableArray?): Unit = Unit } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java index 2152d87657c470..76b604715ceb34 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java @@ -577,20 +577,19 @@ public boolean performAccessibilityAction(View host, int action, Bundle args) { UIManager uiManager = UIManagerHelper.getUIManager(reactContext, ViewUtil.getUIManagerType(reactTag)); if (uiManager != null) { - uiManager - .getEventDispatcher() - .dispatchEvent( - new Event(surfaceId, reactTag) { - @Override - public String getEventName() { - return TOP_ACCESSIBILITY_ACTION_EVENT; - } - - @Override - protected WritableMap getEventData() { - return event; - } - }); + EventDispatcher eventDispatcher = (EventDispatcher) uiManager.getEventDispatcher(); + eventDispatcher.dispatchEvent( + new Event(surfaceId, reactTag) { + @Override + public String getEventName() { + return TOP_ACCESSIBILITY_ACTION_EVENT; + } + + @Override + protected WritableMap getEventData() { + return event; + } + }); } } else { ReactSoftExceptionLogger.logSoftException( diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagerDelegate.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagerDelegate.kt index 7fe89ee54bd255..53b96e54673601 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagerDelegate.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagerDelegate.kt @@ -18,7 +18,24 @@ import com.facebook.react.bridge.ReadableArray * @param the type of the view supported by this delegate */ public interface ViewManagerDelegate { - public fun setProperty(view: T, propName: String, value: Any?) - public fun receiveCommand(view: T, commandName: String, args: ReadableArray?) + /** + * Sets a property on a view managed by this view manager. + * + * @param view the view to set the property on + * @param propName the name of the property to set (NOTE: should be `String` but is kept as + * `String?` to avoid breaking changes) + * @param value the value to set the property to + */ + public fun setProperty(view: T, propName: String?, value: Any?) + + /** + * Executes a command from JS to the view + * + * @param view the view to execute the command on + * @param commandName the name of the command to execute (NOTE: should be `String` but is kept as + * `String?` to avoid breaking changes) + * @param args the arguments to pass to the command + */ + public fun receiveCommand(view: T, commandName: String?, args: ReadableArray?) } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BackgroundDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BackgroundDrawable.kt new file mode 100644 index 00000000000000..cf93a29bf45770 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BackgroundDrawable.kt @@ -0,0 +1,260 @@ +/* + * 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. + */ + +package com.facebook.react.uimanager.drawable + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.ColorFilter +import android.graphics.ComposeShader +import android.graphics.Paint +import android.graphics.Path +import android.graphics.PixelFormat +import android.graphics.PorterDuff +import android.graphics.Rect +import android.graphics.RectF +import android.graphics.Shader +import android.graphics.drawable.Drawable +import com.facebook.react.uimanager.PixelUtil.dpToPx +import com.facebook.react.uimanager.PixelUtil.toDIPFromPixel +import com.facebook.react.uimanager.style.BackgroundImageLayer +import com.facebook.react.uimanager.style.BorderInsets +import com.facebook.react.uimanager.style.BorderRadiusStyle +import com.facebook.react.uimanager.style.ComputedBorderRadius +import kotlin.math.roundToInt + +internal class BackgroundDrawable( + private val context: Context, + /* + * We assume borderRadius & borderInsets to be shared across multiple drawables + * therefore we should manually invalidate this drawable when changing either of them + */ + var borderRadius: BorderRadiusStyle? = null, + var borderInsets: BorderInsets? = null, +) : Drawable() { + /** + * There is a small gap between the edges of adjacent paths, such as between its Border and its + * Outline. The smallest amount (found to be 0.8f) is used to shrink outline's path, overlapping + * them and closing the visible gap. + */ + private val gapBetweenPaths = 0.8f + private var computedBorderInsets: RectF? = null + private var computedBorderRadius: ComputedBorderRadius? = null + private var needUpdatePath = true + + var backgroundColor: Int = Color.TRANSPARENT + set(value) { + if (field != value) { + field = value + backgroundPaint.color = value + invalidateSelf() + } + } + + private var paddingBoxRect: RectF = RectF() + private var paddingBoxRenderPath: Path? = null + + var backgroundImageLayers: List? = null + set(value) { + if (field != value) { + field = value + invalidateSelf() + } + } + + private val backgroundPaint: Paint = + Paint(Paint.ANTI_ALIAS_FLAG).apply { + style = Paint.Style.FILL + color = backgroundColor + } + + override fun invalidateSelf() { + needUpdatePath = true + super.invalidateSelf() + } + + override fun onBoundsChange(bounds: Rect) { + super.onBoundsChange(bounds) + needUpdatePath = true + } + + override fun setAlpha(alpha: Int) { + backgroundPaint.alpha = + (((alpha / 255f) * (Color.alpha(backgroundColor) / 255f)) * 255f).roundToInt() + invalidateSelf() + } + + override fun setColorFilter(colorFilter: ColorFilter?) { + // do nothing + } + + @Deprecated("Deprecated in Java") + override fun getOpacity(): Int { + val alpha = backgroundPaint.alpha + return when (alpha) { + 255 -> PixelFormat.OPAQUE + in 1..254 -> PixelFormat.TRANSLUCENT + else -> PixelFormat.TRANSPARENT + } + } + + override fun draw(canvas: Canvas) { + updatePath() + canvas.save() + + var innerRadiusX = 0f + var innerRadiusY = 0f + // Draws the View without its border first (with background color fill) + if (backgroundPaint.alpha != 0) { + if (computedBorderRadius?.isUniform() == true && borderRadius?.hasRoundedBorders() == true) { + innerRadiusX = + getInnerBorderRadius( + computedBorderRadius?.topLeft?.horizontal?.dpToPx(), computedBorderInsets?.left) + innerRadiusY = + getInnerBorderRadius( + computedBorderRadius?.topLeft?.vertical?.dpToPx(), computedBorderInsets?.top) + canvas.drawRoundRect(paddingBoxRect, innerRadiusX, innerRadiusY, backgroundPaint) + } else if (borderRadius?.hasRoundedBorders() != true) { + canvas.drawRect(bounds, backgroundPaint) + } else { + canvas.drawPath(checkNotNull(paddingBoxRenderPath), backgroundPaint) + } + } + + if (backgroundImageLayers != null && backgroundImageLayers?.isNotEmpty() == true) { + backgroundPaint.setShader(getBackgroundImageShader()) + if (computedBorderRadius?.isUniform() == true && borderRadius?.hasRoundedBorders() == true) { + canvas.drawRoundRect(paddingBoxRect, innerRadiusX, innerRadiusY, backgroundPaint) + } else if (borderRadius?.hasRoundedBorders() != true) { + canvas.drawRect(paddingBoxRect, backgroundPaint) + } else { + canvas.drawPath(checkNotNull(paddingBoxRenderPath), backgroundPaint) + } + backgroundPaint.setShader(null) + } + canvas.restore() + } + + private fun computeBorderInsets(): RectF = + borderInsets?.resolve(layoutDirection, context).let { + RectF( + it?.left?.dpToPx() ?: 0f, + it?.top?.dpToPx() ?: 0f, + it?.right?.dpToPx() ?: 0f, + it?.bottom?.dpToPx() ?: 0f) + } + + private fun getBackgroundImageShader(): Shader? { + backgroundImageLayers?.let { layers -> + var compositeShader: Shader? = null + for (backgroundImageLayer in layers) { + val currentShader = backgroundImageLayer.getShader(bounds) ?: continue + + compositeShader = + if (compositeShader == null) { + currentShader + } else { + ComposeShader(currentShader, compositeShader, PorterDuff.Mode.SRC_OVER) + } + } + return compositeShader + } + return null + } + + /** + * Here, "inner" refers to the border radius on the inside of the border. So it ends up being the + * "outer" border radius inset by the respective width. + */ + private fun getInnerBorderRadius(computedRadius: Float?, borderWidth: Float?): Float { + return ((computedRadius ?: 0f) - (borderWidth ?: 0f)).coerceAtLeast(0f) + } + + private fun updatePath() { + if (!needUpdatePath) { + return + } + needUpdatePath = false + + computedBorderInsets = computeBorderInsets() + computedBorderRadius = + borderRadius?.resolve( + layoutDirection, + context, + toDIPFromPixel(bounds.width().toFloat()), + toDIPFromPixel(bounds.height().toFloat())) + + if (computedBorderRadius?.hasRoundedBorders() == true && + computedBorderRadius?.isUniform() == false) { + paddingBoxRenderPath = paddingBoxRenderPath ?: Path() + paddingBoxRenderPath?.reset() + } + + // only close gap between border and background if we draw the border, otherwise + // we wind up pixelating small pixel-radius curves + var pathAdjustment = 0f + if (computedBorderInsets != null && + (computedBorderInsets?.left != 0f || + computedBorderInsets?.top != 0f || + computedBorderInsets?.right != 0f || + computedBorderInsets?.bottom != 0f)) { + pathAdjustment = gapBetweenPaths + } + + // There is a small gap between backgroundDrawable and + // borderDrawable. pathAdjustment is used to slightly enlarge the rectangle + // (paddingBoxRect), ensuring the border can be + // drawn on top without the gap. + paddingBoxRect.left = bounds.left + (computedBorderInsets?.left ?: 0f) - pathAdjustment + paddingBoxRect.top = bounds.top + (computedBorderInsets?.top ?: 0f) - pathAdjustment + paddingBoxRect.right = bounds.right - (computedBorderInsets?.right ?: 0f) + pathAdjustment + paddingBoxRect.bottom = bounds.bottom - (computedBorderInsets?.bottom ?: 0f) + pathAdjustment + + if (borderRadius?.hasRoundedBorders() == true && computedBorderRadius?.isUniform() != true) { + + val innerTopLeftRadiusX = + getInnerBorderRadius( + computedBorderRadius?.topLeft?.horizontal?.dpToPx(), computedBorderInsets?.left) + val innerTopLeftRadiusY = + getInnerBorderRadius( + computedBorderRadius?.topLeft?.vertical?.dpToPx(), computedBorderInsets?.top) + val innerTopRightRadiusX = + getInnerBorderRadius( + computedBorderRadius?.topRight?.horizontal?.dpToPx(), computedBorderInsets?.right) + val innerTopRightRadiusY = + getInnerBorderRadius( + computedBorderRadius?.topRight?.vertical?.dpToPx(), computedBorderInsets?.top) + val innerBottomRightRadiusX = + getInnerBorderRadius( + computedBorderRadius?.bottomRight?.horizontal?.dpToPx(), computedBorderInsets?.right) + val innerBottomRightRadiusY = + getInnerBorderRadius( + computedBorderRadius?.bottomRight?.vertical?.dpToPx(), computedBorderInsets?.bottom) + val innerBottomLeftRadiusX = + getInnerBorderRadius( + computedBorderRadius?.bottomLeft?.horizontal?.dpToPx(), computedBorderInsets?.left) + val innerBottomLeftRadiusY = + getInnerBorderRadius( + computedBorderRadius?.bottomLeft?.vertical?.dpToPx(), computedBorderInsets?.bottom) + + paddingBoxRenderPath?.addRoundRect( + paddingBoxRect, + floatArrayOf( + innerTopLeftRadiusX, + innerTopLeftRadiusY, + innerTopRightRadiusX, + innerTopRightRadiusY, + innerBottomRightRadiusX, + innerBottomRightRadiusY, + innerBottomLeftRadiusX, + innerBottomLeftRadiusY, + ), + Path.Direction.CW) + } + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt new file mode 100644 index 00000000000000..a6c331df7d3380 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BorderDrawable.kt @@ -0,0 +1,1071 @@ +/* + * 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. + */ + +package com.facebook.react.uimanager.drawable + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.ColorFilter +import android.graphics.DashPathEffect +import android.graphics.Paint +import android.graphics.Path +import android.graphics.PathEffect +import android.graphics.PixelFormat +import android.graphics.PointF +import android.graphics.Rect +import android.graphics.RectF +import android.graphics.Region +import android.graphics.drawable.Drawable +import android.os.Build +import com.facebook.react.uimanager.FloatUtil.floatsEqual +import com.facebook.react.uimanager.LengthPercentage +import com.facebook.react.uimanager.PixelUtil +import com.facebook.react.uimanager.PixelUtil.dpToPx +import com.facebook.react.uimanager.Spacing +import com.facebook.react.uimanager.style.BorderColors +import com.facebook.react.uimanager.style.BorderInsets +import com.facebook.react.uimanager.style.BorderRadiusProp +import com.facebook.react.uimanager.style.BorderRadiusStyle +import com.facebook.react.uimanager.style.BorderStyle +import com.facebook.react.uimanager.style.ColorEdges +import com.facebook.react.uimanager.style.ComputedBorderRadius +import com.facebook.react.uimanager.style.CornerRadii +import com.facebook.react.uimanager.style.LogicalEdge +import kotlin.math.abs +import kotlin.math.pow +import kotlin.math.roundToInt +import kotlin.math.sqrt +import kotlin.properties.ObservableProperty +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty + +// 0.inv() == 0xFFFFFFFF, all bits set to 1. +private const val ALL_BITS_SET = 0.inv() +// 0 == 0x00000000, all bits set to 0. +private const val ALL_BITS_UNSET = 0 + +internal class BorderDrawable( + private val context: Context, + val borderWidth: Spacing?, + /* + * We assume borderRadius & borderInsets to be shared across multiple drawables + * therefore user should invalidate this drawable when changing either of them + */ + var borderRadius: BorderRadiusStyle?, + var borderInsets: BorderInsets?, + borderStyle: BorderStyle?, +) : Drawable() { + private fun invalidatingAndPathChange(initialValue: T): ReadWriteProperty = + object : ObservableProperty(initialValue) { + override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) { + if (oldValue != newValue) { + needUpdatePath = true + invalidateSelf() + } + } + } + + /** Border Properties */ + var borderStyle: BorderStyle? by invalidatingAndPathChange(borderStyle) + + private var borderColors: BorderColors? = null + private var computedBorderColors: ColorEdges = ColorEdges() + private var computedBorderRadius: ComputedBorderRadius? = null + private var borderAlpha: Int = 255 + + /** + * There is a small gap between the edges of adjacent paths, such as between its Border and its + * Outline. The smallest amount (found to be 0.8f) is used to shrink outline's path, overlapping + * them and closing the visible gap. + */ + private val gapBetweenPaths = 0.8f + private var pathForBorder: Path? = null + + private val borderPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG) + + private var needUpdatePath: Boolean = true + + private var pathForSingleBorder: Path? = null + private var pathForOutline: Path? = null + + private var centerDrawPath: Path? = null + private var outerClipPathForBorderRadius: Path? = null + var innerClipPathForBorderRadius: Path? = null + private set + + /** + * Points that represent the inner point of the quadrilateral gotten from the intersection of L + * with the border-radius forming ellipse + */ + private var innerBottomLeftCorner: PointF? = null + private var innerBottomRightCorner: PointF? = null + private var innerTopLeftCorner: PointF? = null + private var innerTopRightCorner: PointF? = null + + private var innerClipTempRectForBorderRadius: RectF? = null + private var outerClipTempRectForBorderRadius: RectF? = null + private var tempRectForCenterDrawPath: RectF? = null + + override fun invalidateSelf() { + needUpdatePath = true + super.invalidateSelf() + } + + override fun onBoundsChange(bounds: Rect) { + super.onBoundsChange(bounds) + needUpdatePath = true + } + + override fun setAlpha(alpha: Int) { + /* + * borderAlpha proportionally affects the alpha each borderColor edge + * for example if borderColor's alpha originally is 255 and borderAlpha is set to 128 + * then the resulting alpha for that borderColor will be 128 + */ + borderAlpha = alpha + invalidateSelf() + } + + override fun setColorFilter(colorFilter: ColorFilter?) { + // do nothing + } + + @Deprecated("Deprecated in Java") + override fun getOpacity(): Int { + val maxBorderAlpha = + minOf( + (Color.alpha(multiplyColorAlpha(computedBorderColors.left, borderAlpha))), + (Color.alpha(multiplyColorAlpha(computedBorderColors.top, borderAlpha))), + (Color.alpha(multiplyColorAlpha(computedBorderColors.right, borderAlpha))), + (Color.alpha(multiplyColorAlpha(computedBorderColors.bottom, borderAlpha)))) + + // If the highest alpha value of all border edges is 0, then the drawable is TRANSPARENT. + if (maxBorderAlpha == 0) { + return PixelFormat.TRANSPARENT + } + + val minBorderAlpha = + minOf( + (Color.alpha(multiplyColorAlpha(computedBorderColors.left, borderAlpha))), + (Color.alpha(multiplyColorAlpha(computedBorderColors.top, borderAlpha))), + (Color.alpha(multiplyColorAlpha(computedBorderColors.right, borderAlpha))), + (Color.alpha(multiplyColorAlpha(computedBorderColors.bottom, borderAlpha)))) + + /* + * If the lowest alpha value of all border edges is 255, then the drawable is OPAQUE. + * else the drawable is TRANSLUCENT. + */ + return when (minBorderAlpha) { + 255 -> PixelFormat.OPAQUE + else -> PixelFormat.TRANSLUCENT + } + } + + override fun draw(canvas: Canvas) { + updatePathEffect() + computedBorderColors = borderColors?.resolve(layoutDirection, context) ?: computedBorderColors + if (borderRadius?.hasRoundedBorders() == true) { + drawRoundedBorders(canvas) + } else { + drawRectangularBorders(canvas) + } + } + + /** + * Here, "inner" refers to the border radius on the inside of the border. So it ends up being the + * "outer" border radius inset by the respective width. + */ + private fun getInnerBorderRadius(computedRadius: Float, borderWidth: Float): Float { + return (computedRadius - borderWidth).coerceAtLeast(0f) + } + + fun setBorderWidth(position: Int, width: Float) { + if (!floatsEqual(this.borderWidth?.getRaw(position), width)) { + this.borderWidth?.set(position, width) + when (position) { + Spacing.ALL, + Spacing.LEFT, + Spacing.BOTTOM, + Spacing.RIGHT, + Spacing.TOP, + Spacing.START, + Spacing.END -> needUpdatePath = true + } + invalidateSelf() + } + } + + fun setBorderRadius(property: BorderRadiusProp, radius: LengthPercentage?) { + if (radius != borderRadius?.get(property)) { + borderRadius?.set(property, radius) + needUpdatePath = true + invalidateSelf() + } + } + + fun setBorderStyle(style: String?) { + val borderStyle = if (style == null) null else BorderStyle.valueOf(style.uppercase()) + this.borderStyle = borderStyle + needUpdatePath = true + invalidateSelf() + } + + fun setBorderColor(position: LogicalEdge, color: Int?) { + borderColors = borderColors ?: BorderColors() + + borderColors?.edgeColors?.set(position.ordinal, color) + needUpdatePath = true + invalidateSelf() + } + + fun getBorderColor(position: LogicalEdge): Int { + return borderColors?.edgeColors?.get(position.ordinal) ?: Color.BLACK + } + + public fun invalidateSelfAndUpdatePath() { + needUpdatePath = true + invalidateSelf() + } + + private fun drawRectangularBorders(canvas: Canvas) { + val borderWidth = computeBorderInsets() + val borderLeft = borderWidth.left.roundToInt() + val borderTop = borderWidth.top.roundToInt() + val borderRight = borderWidth.right.roundToInt() + val borderBottom = borderWidth.bottom.roundToInt() + + // maybe draw borders? + if (borderLeft > 0 || borderRight > 0 || borderTop > 0 || borderBottom > 0) { + val bounds = bounds + val left = bounds.left + val top = bounds.top + + // Check for fast path to border drawing. + val fastBorderColor = + fastBorderCompatibleColorOrZero( + borderLeft, + borderTop, + borderRight, + borderBottom, + computedBorderColors.left, + computedBorderColors.top, + computedBorderColors.right, + computedBorderColors.bottom) + if (fastBorderColor != 0) { + if (Color.alpha(fastBorderColor) != 0) { + // Border color is not transparent. + val right = bounds.right + val bottom = bounds.bottom + borderPaint.color = multiplyColorAlpha(fastBorderColor, borderAlpha) + borderPaint.style = Paint.Style.STROKE + pathForSingleBorder = Path() + if (borderLeft > 0) { + pathForSingleBorder?.reset() + val width = borderWidth.left.roundToInt() + updatePathEffect(width) + borderPaint.strokeWidth = width.toFloat() + pathForSingleBorder?.moveTo((left + width / 2).toFloat(), top.toFloat()) + pathForSingleBorder?.lineTo((left + width / 2).toFloat(), bottom.toFloat()) + pathForSingleBorder?.let { canvas.drawPath(it, borderPaint) } + } + if (borderTop > 0) { + pathForSingleBorder?.reset() + val width = borderWidth.top.roundToInt() + updatePathEffect(width) + borderPaint.strokeWidth = width.toFloat() + pathForSingleBorder?.moveTo(left.toFloat(), (top + width / 2).toFloat()) + pathForSingleBorder?.lineTo(right.toFloat(), (top + width / 2).toFloat()) + pathForSingleBorder?.let { canvas.drawPath(it, borderPaint) } + } + if (borderRight > 0) { + pathForSingleBorder?.reset() + val width = borderWidth.right.roundToInt() + updatePathEffect(width) + borderPaint.strokeWidth = width.toFloat() + pathForSingleBorder?.moveTo((right - width / 2).toFloat(), top.toFloat()) + pathForSingleBorder?.lineTo((right - width / 2).toFloat(), bottom.toFloat()) + pathForSingleBorder?.let { canvas.drawPath(it, borderPaint) } + } + if (borderBottom > 0) { + pathForSingleBorder?.reset() + val width = borderWidth.bottom.roundToInt() + updatePathEffect(width) + borderPaint.strokeWidth = width.toFloat() + pathForSingleBorder?.moveTo(left.toFloat(), (bottom - width / 2).toFloat()) + pathForSingleBorder?.lineTo(right.toFloat(), (bottom - width / 2).toFloat()) + pathForSingleBorder?.let { canvas.drawPath(it, borderPaint) } + } + } + } else { + /** + * If the path drawn previously is of the same color, there would be a slight white space + * between borders with anti-alias set to true. Therefore we need to disable anti-alias, and + * after drawing is done, we will re-enable it. + */ + borderPaint.isAntiAlias = false + val width = bounds.width() + val height = bounds.height() + if (borderLeft > 0) { + val x1 = left.toFloat() + val y1 = top.toFloat() + val x2 = (left + borderLeft).toFloat() + val y2 = (top + borderTop).toFloat() + val x3 = (left + borderLeft).toFloat() + val y3 = (top + height - borderBottom).toFloat() + val x4 = left.toFloat() + val y4 = (top + height).toFloat() + drawQuadrilateral(canvas, computedBorderColors.left, x1, y1, x2, y2, x3, y3, x4, y4) + } + if (borderTop > 0) { + val x1 = left.toFloat() + val y1 = top.toFloat() + val x2 = (left + borderLeft).toFloat() + val y2 = (top + borderTop).toFloat() + val x3 = (left + width - borderRight).toFloat() + val y3 = (top + borderTop).toFloat() + val x4 = (left + width).toFloat() + val y4 = top.toFloat() + drawQuadrilateral(canvas, computedBorderColors.top, x1, y1, x2, y2, x3, y3, x4, y4) + } + if (borderRight > 0) { + val x1 = (left + width).toFloat() + val y1 = top.toFloat() + val x2 = (left + width).toFloat() + val y2 = (top + height).toFloat() + val x3 = (left + width - borderRight).toFloat() + val y3 = (top + height - borderBottom).toFloat() + val x4 = (left + width - borderRight).toFloat() + val y4 = (top + borderTop).toFloat() + drawQuadrilateral(canvas, computedBorderColors.right, x1, y1, x2, y2, x3, y3, x4, y4) + } + if (borderBottom > 0) { + val x1 = left.toFloat() + val y1 = (top + height).toFloat() + val x2 = (left + width).toFloat() + val y2 = (top + height).toFloat() + val x3 = (left + width - borderRight).toFloat() + val y3 = (top + height - borderBottom).toFloat() + val x4 = (left + borderLeft).toFloat() + val y4 = (top + height - borderBottom).toFloat() + drawQuadrilateral(canvas, computedBorderColors.bottom, x1, y1, x2, y2, x3, y3, x4, y4) + } + + // re-enable anti alias + borderPaint.isAntiAlias = true + } + } + } + + private fun drawRoundedBorders(canvas: Canvas) { + updatePath() + canvas.save() + + // Clip outer border + canvas.clipPath(checkNotNull(outerClipPathForBorderRadius)) + + val borderWidth = computeBorderInsets() + if (borderWidth.top > 0 || + borderWidth.bottom > 0 || + borderWidth.left > 0 || + borderWidth.right > 0) { + + // If it's a full and even border draw inner rect path with stroke + val fullBorderWidth: Float = getFullBorderWidth() + val borderColor = getBorderColor(LogicalEdge.ALL) + + if (borderWidth.top == fullBorderWidth && + borderWidth.bottom == fullBorderWidth && + borderWidth.left == fullBorderWidth && + borderWidth.right == fullBorderWidth && + computedBorderColors.left == borderColor && + computedBorderColors.top == borderColor && + computedBorderColors.right == borderColor && + computedBorderColors.bottom == borderColor) { + if (fullBorderWidth > 0) { + borderPaint.color = multiplyColorAlpha(borderColor, borderAlpha) + borderPaint.style = Paint.Style.STROKE + borderPaint.strokeWidth = fullBorderWidth + if (computedBorderRadius?.isUniform() == true) { + tempRectForCenterDrawPath?.let { + canvas.drawRoundRect( + it, + ((computedBorderRadius?.topLeft?.toPixelFromDIP()?.horizontal ?: 0f) - + borderWidth.left * 0.5f), + ((computedBorderRadius?.topLeft?.toPixelFromDIP()?.vertical ?: 0f) - + borderWidth.top * 0.5f), + borderPaint) + } + } else { + canvas.drawPath(checkNotNull(centerDrawPath), borderPaint) + } + } + } + // In the case of uneven border widths/colors draw quadrilateral in each direction + else { + borderPaint.style = Paint.Style.FILL + + // Clip inner border + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + canvas.clipOutPath(checkNotNull(innerClipPathForBorderRadius)) + } else { + @Suppress("DEPRECATION") + canvas.clipPath(checkNotNull(innerClipPathForBorderRadius), Region.Op.DIFFERENCE) + } + val outerClipTempRect = checkNotNull(outerClipTempRectForBorderRadius) + val left = outerClipTempRect.left + val right = outerClipTempRect.right + val top = outerClipTempRect.top + val bottom = outerClipTempRect.bottom + + val innerTopLeftCorner = checkNotNull(this.innerTopLeftCorner) + val innerTopRightCorner = checkNotNull(this.innerTopRightCorner) + val innerBottomLeftCorner = checkNotNull(this.innerBottomLeftCorner) + val innerBottomRightCorner = checkNotNull(this.innerBottomRightCorner) + + /** + * gapBetweenPaths is used to close the gap between the diagonal edges of the quadrilaterals + * on adjacent sides of the rectangle + */ + if (borderWidth.left > 0) { + val x1 = left + val y1: Float = top - gapBetweenPaths + val x2 = innerTopLeftCorner.x + val y2: Float = innerTopLeftCorner.y - gapBetweenPaths + val x3 = innerBottomLeftCorner.x + val y3: Float = innerBottomLeftCorner.y + gapBetweenPaths + val x4 = left + val y4: Float = bottom + gapBetweenPaths + drawQuadrilateral(canvas, computedBorderColors.left, x1, y1, x2, y2, x3, y3, x4, y4) + } + if (borderWidth.top > 0) { + val x1: Float = left - gapBetweenPaths + val y1 = top + val x2: Float = innerTopLeftCorner.x - gapBetweenPaths + val y2 = innerTopLeftCorner.y + val x3: Float = innerTopRightCorner.x + gapBetweenPaths + val y3 = innerTopRightCorner.y + val x4: Float = right + gapBetweenPaths + val y4 = top + drawQuadrilateral(canvas, computedBorderColors.top, x1, y1, x2, y2, x3, y3, x4, y4) + } + if (borderWidth.right > 0) { + val x1 = right + val y1: Float = top - gapBetweenPaths + val x2 = innerTopRightCorner.x + val y2: Float = innerTopRightCorner.y - gapBetweenPaths + val x3 = innerBottomRightCorner.x + val y3: Float = innerBottomRightCorner.y + gapBetweenPaths + val x4 = right + val y4: Float = bottom + gapBetweenPaths + drawQuadrilateral(canvas, computedBorderColors.right, x1, y1, x2, y2, x3, y3, x4, y4) + } + if (borderWidth.bottom > 0) { + val x1: Float = left - gapBetweenPaths + val y1 = bottom + val x2: Float = innerBottomLeftCorner.x - gapBetweenPaths + val y2 = innerBottomLeftCorner.y + val x3: Float = innerBottomRightCorner.x + gapBetweenPaths + val y3 = innerBottomRightCorner.y + val x4: Float = right + gapBetweenPaths + val y4 = bottom + drawQuadrilateral(canvas, computedBorderColors.bottom, x1, y1, x2, y2, x3, y3, x4, y4) + } + } + } + canvas.restore() + } + + private fun fastBorderCompatibleColorOrZero( + borderLeft: Int, + borderTop: Int, + borderRight: Int, + borderBottom: Int, + colorLeft: Int, + colorTop: Int, + colorRight: Int, + colorBottom: Int + ): Int { + val andSmear = + ((if (borderLeft > 0) colorLeft else ALL_BITS_SET) and + (if (borderTop > 0) colorTop else ALL_BITS_SET) and + (if (borderRight > 0) colorRight else ALL_BITS_SET) and + if (borderBottom > 0) colorBottom else ALL_BITS_SET) + val orSmear = + ((if (borderLeft > 0) colorLeft else ALL_BITS_UNSET) or + (if (borderTop > 0) colorTop else ALL_BITS_UNSET) or + (if (borderRight > 0) colorRight else ALL_BITS_UNSET) or + if (borderBottom > 0) colorBottom else ALL_BITS_UNSET) + return if (andSmear == orSmear) andSmear else 0 + } + + private fun drawQuadrilateral( + canvas: Canvas, + fillColor: Int, + x1: Float, + y1: Float, + x2: Float, + y2: Float, + x3: Float, + y3: Float, + x4: Float, + y4: Float + ) { + if (fillColor == Color.TRANSPARENT) { + return + } + + if (this.pathForBorder == null) { + this.pathForBorder = Path() + } + + borderPaint.color = multiplyColorAlpha(fillColor, borderAlpha) + this.pathForBorder?.reset() + this.pathForBorder?.moveTo(x1, y1) + this.pathForBorder?.lineTo(x2, y2) + this.pathForBorder?.lineTo(x3, y3) + this.pathForBorder?.lineTo(x4, y4) + this.pathForBorder?.lineTo(x1, y1) + this.pathForBorder?.let { canvas.drawPath(it, borderPaint) } + } + + private fun computeBorderInsets(): RectF { + borderInsets?.resolve(layoutDirection, context)?.let { + return RectF( + if (it.left.isNaN()) 0f else it.left.dpToPx(), + if (it.top.isNaN()) 0f else it.top.dpToPx(), + if (it.right.isNaN()) 0f else it.right.dpToPx(), + if (it.bottom.isNaN()) 0f else it.bottom.dpToPx(), + ) + } + return RectF(0f, 0f, 0f, 0f) + } + + /** For rounded borders we use default "borderWidth" property. */ + private fun getFullBorderWidth(): Float { + val borderWidth = this.borderWidth?.getRaw(Spacing.ALL) ?: Float.NaN + return if (!borderWidth.isNaN()) borderWidth else 0f + } + + private fun updatePathEffect() { + /** Used for rounded border and rounded background. */ + this.borderStyle?.let { style -> + val pathEffectForBorderStyle = + if (this.borderStyle != null) getPathEffect(style, getFullBorderWidth()) else null + borderPaint.setPathEffect(pathEffectForBorderStyle) + } + } + + private fun updatePathEffect(borderWidth: Int) { + this.borderStyle?.let { style -> + val pathEffectForBorderStyle = + if (this.borderStyle != null) getPathEffect(style, borderWidth.toFloat()) else null + borderPaint.setPathEffect(pathEffectForBorderStyle) + } + } + + private fun getPathEffect(style: BorderStyle, borderWidth: Float): PathEffect? { + return when (style) { + BorderStyle.SOLID -> null + BorderStyle.DASHED -> + DashPathEffect( + floatArrayOf(borderWidth * 3, borderWidth * 3, borderWidth * 3, borderWidth * 3), 0f) + BorderStyle.DOTTED -> + DashPathEffect(floatArrayOf(borderWidth, borderWidth, borderWidth, borderWidth), 0f) + } + } + + private fun getEllipseIntersectionWithLine( + ellipseBoundsLeft: Double, + ellipseBoundsTop: Double, + ellipseBoundsRight: Double, + ellipseBoundsBottom: Double, + lineStartX: Double, + lineStartY: Double, + lineEndX: Double, + lineEndY: Double, + result: PointF + ) { + var _lineStartX = lineStartX + var _lineStartY = lineStartY + var _lineEndX = lineEndX + var _lineEndY = lineEndY + val ellipseCenterX = (ellipseBoundsLeft + ellipseBoundsRight) / 2 + val ellipseCenterY = (ellipseBoundsTop + ellipseBoundsBottom) / 2 + /** + * Step 1: + * + * Translate the line so that the ellipse is at the origin. + * + * Why? It makes the math easier by changing the ellipse equation from ((x - + * ellipseCenterX)/a)^2 + ((y - ellipseCenterY)/b)^2 = 1 to (x/a)^2 + (y/b)^2 = 1. + */ + _lineStartX -= ellipseCenterX + _lineStartY -= ellipseCenterY + _lineEndX -= ellipseCenterX + _lineEndY -= ellipseCenterY + /** + * Step 2: + * + * Ellipse equation: (x/a)^2 + (y/b)^2 = 1 Line equation: y = mx + c + */ + val a = abs(ellipseBoundsRight - ellipseBoundsLeft) / 2 + val b = abs(ellipseBoundsBottom - ellipseBoundsTop) / 2 + val m = (_lineEndY - _lineStartY) / (_lineEndX - _lineStartX) + val c = _lineStartY - m * _lineStartX // Just a point on the line + /** + * Step 3: + * + * Substitute the Line equation into the Ellipse equation. Solve for x. Eventually, you'll have + * to use the quadratic formula. + * + * Quadratic formula: Ax^2 + Bx + C = 0 + */ + val A = b * b + a * a * m * m + val B = 2 * a * a * c * m + val C = a * a * (c * c - b * b) + /** + * Step 4: + * + * Apply Quadratic formula. D = determinant / 2A + */ + val D = sqrt(-C / A + (B / (2 * A)).pow(2.0)) + val x2 = -B / (2 * A) - D + val y2 = m * x2 + c + /** + * Step 5: + * + * Undo the space transformation in Step 5. + */ + val x = x2 + ellipseCenterX + val y = y2 + ellipseCenterY + if (!x.isNaN() && !y.isNaN()) { + result.x = x.toFloat() + result.y = y.toFloat() + } + } + + private fun updatePath() { + if (!needUpdatePath) { + return + } + + needUpdatePath = false + + // Path + innerClipPathForBorderRadius = innerClipPathForBorderRadius ?: Path() + outerClipPathForBorderRadius = outerClipPathForBorderRadius ?: Path() + pathForOutline = Path() + + // RectF + innerClipTempRectForBorderRadius = innerClipTempRectForBorderRadius ?: RectF() + outerClipTempRectForBorderRadius = outerClipTempRectForBorderRadius ?: RectF() + tempRectForCenterDrawPath = tempRectForCenterDrawPath ?: RectF() + + innerClipPathForBorderRadius?.reset() + outerClipPathForBorderRadius?.reset() + + innerClipTempRectForBorderRadius?.set(bounds) + outerClipTempRectForBorderRadius?.set(bounds) + tempRectForCenterDrawPath?.set(bounds) + + val borderWidth = computeBorderInsets() + + // Clip border ONLY if its color is non transparent + if (Color.alpha(computedBorderColors.left) != 0 && + Color.alpha(computedBorderColors.top) != 0 && + Color.alpha(computedBorderColors.right) != 0 && + Color.alpha(computedBorderColors.bottom) != 0) { + innerClipTempRectForBorderRadius?.top = + innerClipTempRectForBorderRadius?.top?.plus(borderWidth.top) ?: 0f + innerClipTempRectForBorderRadius?.bottom = + innerClipTempRectForBorderRadius?.bottom?.minus(borderWidth.bottom) ?: 0f + innerClipTempRectForBorderRadius?.left = + innerClipTempRectForBorderRadius?.left?.plus(borderWidth.left) ?: 0f + innerClipTempRectForBorderRadius?.right = + innerClipTempRectForBorderRadius?.right?.minus(borderWidth.right) ?: 0f + } + + tempRectForCenterDrawPath?.top = + tempRectForCenterDrawPath?.top?.plus(borderWidth.top * 0.5f) ?: 0f + tempRectForCenterDrawPath?.bottom = + tempRectForCenterDrawPath?.bottom?.minus(borderWidth.bottom * 0.5f) ?: 0f + tempRectForCenterDrawPath?.left = + tempRectForCenterDrawPath?.left?.plus(borderWidth.left * 0.5f) ?: 0f + tempRectForCenterDrawPath?.right = + tempRectForCenterDrawPath?.right?.minus(borderWidth.right * 0.5f) ?: 0f + + computedBorderRadius = + this.borderRadius?.resolve( + layoutDirection, + this.context, + PixelUtil.toDIPFromPixel(outerClipTempRectForBorderRadius?.width() ?: 0f), + PixelUtil.toDIPFromPixel(outerClipTempRectForBorderRadius?.height() ?: 0f), + ) + + val topLeftRadius = computedBorderRadius?.topLeft?.toPixelFromDIP() ?: CornerRadii(0f, 0f) + val topRightRadius = computedBorderRadius?.topRight?.toPixelFromDIP() ?: CornerRadii(0f, 0f) + val bottomLeftRadius = computedBorderRadius?.bottomLeft?.toPixelFromDIP() ?: CornerRadii(0f, 0f) + val bottomRightRadius = + computedBorderRadius?.bottomRight?.toPixelFromDIP() ?: CornerRadii(0f, 0f) + + val innerTopLeftRadiusX: Float = + getInnerBorderRadius(topLeftRadius.horizontal, borderWidth.left) + val innerTopLeftRadiusY: Float = getInnerBorderRadius(topLeftRadius.vertical, borderWidth.top) + val innerTopRightRadiusX: Float = + getInnerBorderRadius(topRightRadius.horizontal, borderWidth.right) + val innerTopRightRadiusY: Float = getInnerBorderRadius(topRightRadius.vertical, borderWidth.top) + val innerBottomRightRadiusX: Float = + getInnerBorderRadius(bottomRightRadius.horizontal, borderWidth.right) + val innerBottomRightRadiusY: Float = + getInnerBorderRadius(bottomRightRadius.vertical, borderWidth.bottom) + val innerBottomLeftRadiusX: Float = + getInnerBorderRadius(bottomLeftRadius.horizontal, borderWidth.left) + val innerBottomLeftRadiusY: Float = + getInnerBorderRadius(bottomLeftRadius.vertical, borderWidth.bottom) + + innerClipTempRectForBorderRadius?.let { + innerClipPathForBorderRadius?.addRoundRect( + it, + floatArrayOf( + innerTopLeftRadiusX, + innerTopLeftRadiusY, + innerTopRightRadiusX, + innerTopRightRadiusY, + innerBottomRightRadiusX, + innerBottomRightRadiusY, + innerBottomLeftRadiusX, + innerBottomLeftRadiusY), + Path.Direction.CW) + } + + outerClipTempRectForBorderRadius?.let { + outerClipPathForBorderRadius?.addRoundRect( + it, + floatArrayOf( + topLeftRadius.horizontal, + topLeftRadius.vertical, + topRightRadius.horizontal, + topRightRadius.vertical, + bottomRightRadius.horizontal, + bottomRightRadius.vertical, + bottomLeftRadius.horizontal, + bottomLeftRadius.vertical), + Path.Direction.CW) + } + + var extraRadiusForOutline = 0f + + if (this.borderWidth != null) { + extraRadiusForOutline = this.borderWidth[Spacing.ALL] / 2f + } + + pathForOutline?.addRoundRect( + RectF(bounds), + floatArrayOf( + topLeftRadius.horizontal + extraRadiusForOutline, + topLeftRadius.vertical + extraRadiusForOutline, + topRightRadius.horizontal + extraRadiusForOutline, + topRightRadius.vertical + extraRadiusForOutline, + bottomRightRadius.horizontal + extraRadiusForOutline, + bottomRightRadius.vertical + extraRadiusForOutline, + bottomLeftRadius.horizontal + extraRadiusForOutline, + bottomLeftRadius.vertical + extraRadiusForOutline), + Path.Direction.CW) + + if (computedBorderRadius?.isUniform() != true) { + centerDrawPath = centerDrawPath ?: Path() + centerDrawPath?.reset() + tempRectForCenterDrawPath?.let { + centerDrawPath?.addRoundRect( + it, + floatArrayOf( + topLeftRadius.horizontal - borderWidth.left * 0.5f, + topLeftRadius.vertical - borderWidth.top * 0.5f, + topRightRadius.horizontal - borderWidth.right * 0.5f, + topRightRadius.vertical - borderWidth.top * 0.5f, + bottomRightRadius.horizontal - borderWidth.right * 0.5f, + bottomRightRadius.vertical - borderWidth.bottom * 0.5f, + bottomLeftRadius.horizontal - borderWidth.left * 0.5f, + bottomLeftRadius.vertical - borderWidth.bottom * 0.5f), + Path.Direction.CW) + } + } + + /** + * Rounded Multi-Colored Border Algorithm: + * + *

Let O (for outer) = (top, left, bottom, right) be the rectangle that represents the size + * and position of a view V. Since the box-sizing of all React Native views is border-box, any + * border of V will render inside O. + * + *

Let BorderWidth = (borderTop, borderLeft, borderBottom, borderRight). + * + *

Let I (for inner) = O - BorderWidth. + * + *

Then, remembering that O and I are rectangles and that I is inside O, O - I gives us the + * border of V. Therefore, we can use canvas.clipPath/clipOutPath to draw V's border. + * + *

canvas.clipPath(O); + * + *

canvas.clipOutPath(I); + * + *

canvas.drawRect(O, paint); + * + *

This lets us draw non-rounded single-color borders. + * + *

To extend this algorithm to rounded single-color borders, we: + * + *

1. Curve the corners of O by the (border radii of V) using Path#addRoundRect. + * + *

2. Curve the corners of I by (border radii of V - border widths of V) using + * Path#addRoundRect. + * + *

Let O' = curve(O, border radii of V). + * + *

Let I' = curve(I, border radii of V - border widths of V) + * + *

The rationale behind this decision is the (first sentence of the) following section in the + * CSS Backgrounds and Borders Module Level 3: + * https://www.w3.org/TR/css3-background/#the-border-radius. + * + *

After both O and I have been curved, we can execute the following lines once again to + * render curved single-color borders: + * + *

canvas.clipPath(O); + * + *

canvas.clipOutPath(I); + * + *

canvas.drawRect(O, paint); + * + *

To extend this algorithm to rendering multi-colored rounded borders, we render each side + * of the border as its own quadrilateral. Suppose that we were handling the case where all the + * border radii are 0. Then, the four quadrilaterals would be: + * + *

Left: (O.left, O.top), (I.left, I.top), (I.left, I.bottom), (O.left, O.bottom) + * + *

Top: (O.left, O.top), (I.left, I.top), (I.right, I.top), (O.right, O.top) + * + *

Right: (O.right, O.top), (I.right, I.top), (I.right, I.bottom), (O.right, O.bottom) + * + *

Bottom: (O.right, O.bottom), (I.right, I.bottom), (I.left, I.bottom), (O.left, O.bottom) + * + *

Now, lets consider what happens when we render a rounded border (radii != 0). For the sake + * of simplicity, let's focus on the top edge of the Left border: + * + *

Let borderTopLeftRadius = 5. Let borderLeftWidth = 1. Let borderTopWidth = 2. + * + *

We know that O is curved by the ellipse E_O (a = 5, b = 5). We know that I is curved by + * the ellipse E_I (a = 5 - 1, b = 5 - 2). + * + *

Since we have clipping, it should be safe to set the top-left point of the Left + * quadrilateral's top edge to (O.left, O.top). + * + *

But, what should the top-right point be? + * + *

The fact that the border is curved shouldn't change the slope (nor the position) of the + * line connecting the top-left and top-right points of the Left quadrilateral's top edge. + * Therefore, The top-right point should lie somewhere on the line L = (1 - a) * (O.left, O.top) + * + a * (I.left, I.top). + * + *

a != 0, because then the top-left and top-right points would be the same and + * borderLeftWidth = 1. a != 1, because then the top-right point would not touch an edge of the + * ellipse E_I. We want the top-right point to touch an edge of the inner ellipse because the + * border curves with E_I on the top-left corner of V. + * + *

Therefore, it must be the case that a > 1. Two natural locations of the top-right point + * exist: 1. The first intersection of L with E_I. 2. The second intersection of L with E_I. + * + *

We choose the top-right point of the top edge of the Left quadrilateral to be an arbitrary + * intersection of L with E_I. + */ + /** + * Rounded Multi-Colored Border Algorithm: + * + * Let O (for outer) = (top, left, bottom, right) be the rectangle that represents the size and + * position of a view V. Since the box-sizing of all React Native views is border-box, any + * border of V will render inside O. + * + * Let BorderWidth = (borderTop, borderLeft, borderBottom, borderRight). + * + * Let I (for inner) = O - BorderWidth. + * + * Then, remembering that O and I are rectangles and that I is inside O, O - I gives us the + * border of V. Therefore, we can use canvas.clipPath to draw V's border. + * + * canvas.clipPath(O, Region.OP.INTERSECT); + * + * canvas.clipPath(I, Region.OP.DIFFERENCE); + * + * canvas.drawRect(O, paint); + * + * This lets us draw non-rounded single-color borders. + * + * To extend this algorithm to rounded single-color borders, we: + * 1. Curve the corners of O by the (border radii of V) using Path#addRoundRect. + * 2. Curve the corners of I by (border radii of V - border widths of V) using + * Path#addRoundRect. + * + * Let O' = curve(O, border radii of V). + * + * Let I' = curve(I, border radii of V - border widths of V) + * + * The rationale behind this decision is the (first sentence of the) following section in the + * CSS Backgrounds and Borders Module Level 3: + * https://www.w3.org/TR/css3-background/#the-border-radius. + * + * After both O and I have been curved, we can execute the following lines once again to render + * curved single-color borders: + * + * canvas.clipPath(O); + * + * canvas.clipOutPath(I); + * + * canvas.drawRect(O, paint); + * + * To extend this algorithm to rendering multi-colored rounded borders, we render each side of + * the border as its own quadrilateral. Suppose that we were handling the case where all the + * border radii are 0. Then, the four quadrilaterals would be: + * + * Left: (O.left, O.top), (I.left, I.top), (I.left, I.bottom), (O.left, O.bottom) + * + * Top: (O.left, O.top), (I.left, I.top), (I.right, I.top), (O.right, O.top) + * + * Right: (O.right, O.top), (I.right, I.top), (I.right, I.bottom), (O.right, O.bottom) + * + * Bottom: (O.right, O.bottom), (I.right, I.bottom), (I.left, I.bottom), (O.left, O.bottom) + * + * Now, lets consider what happens when we render a rounded border (radii != 0). For the sake of + * simplicity, let's focus on the top edge of the Left border: + * + * Let borderTopLeftRadius = 5. Let borderLeftWidth = 1. Let borderTopWidth = 2. + * + * We know that O is curved by the ellipse E_O (a = 5, b = 5). We know that I is curved by the + * ellipse E_I (a = 5 - 1, b = 5 - 2). + * + * Since we have clipping, it should be safe to set the top-left point of the Left + * quadrilateral's top edge to (O.left, O.top). + * + * But, what should the top-right point be? + * + * The fact that the border is curved shouldn't change the slope (nor the position) of the line + * connecting the top-left and top-right points of the Left quadrilateral's top edge. Therefore, + * The top-right point should lie somewhere on the line L = (1 - a) * (O.left, O.top) + * + a * (I.left, I.top). + * + * a != 0, because then the top-left and top-right points would be the same and borderLeftWidth + * = 1. a != 1, because then the top-right point would not touch an edge of the ellipse E_I. We + * want the top-right point to touch an edge of the inner ellipse because the border curves with + * E_I on the top-left corner of V. + * + * Therefore, it must be the case that a > 1. Two natural locations of the top-right point + * exist: 1. The first intersection of L with E_I. 2. The second intersection of L with E_I. + * + * We choose the top-right point of the top edge of the Left quadrilateral to be an arbitrary + * intersection of L with E_I. + */ + val innerRect = innerClipTempRectForBorderRadius + val outerRect = outerClipTempRectForBorderRadius + + if (innerRect != null && outerRect != null) { + /** Compute innerTopLeftCorner */ + innerTopLeftCorner = innerTopLeftCorner ?: PointF() + + innerTopLeftCorner?.x = innerRect.left + innerTopLeftCorner?.y = innerRect.top + + innerTopLeftCorner?.let { + getEllipseIntersectionWithLine( // Ellipse Bounds + innerRect.left.toDouble(), + innerRect.top.toDouble(), + (innerRect.left + 2 * innerTopLeftRadiusX).toDouble(), + (innerRect.top + 2 * innerTopLeftRadiusY).toDouble(), // Line Start + outerRect.left.toDouble(), + outerRect.top.toDouble(), // Line End + innerRect.left.toDouble(), + innerRect.top.toDouble(), // Result + it) + } + + /** Compute innerBottomLeftCorner */ + innerBottomLeftCorner = innerBottomLeftCorner ?: PointF() + + innerBottomLeftCorner?.x = innerRect.left + innerBottomLeftCorner?.y = innerRect.bottom + innerBottomLeftCorner?.let { + getEllipseIntersectionWithLine( // Ellipse Bounds + innerRect.left.toDouble(), + (innerRect.bottom - 2 * innerBottomLeftRadiusY).toDouble(), + (innerRect.left + 2 * innerBottomLeftRadiusX).toDouble(), + innerRect.bottom.toDouble(), // Line Start + outerRect.left.toDouble(), + outerRect.bottom.toDouble(), // Line End + innerRect.left.toDouble(), + innerRect.bottom.toDouble(), // Result + it) + } + + /** Compute innerTopRightCorner */ + innerTopRightCorner = innerTopRightCorner ?: PointF() + + innerTopRightCorner?.x = innerRect.right + innerTopRightCorner?.y = innerRect.top + + innerTopRightCorner?.let { + getEllipseIntersectionWithLine( // Ellipse Bounds + (innerRect.right - 2 * innerTopRightRadiusX).toDouble(), + innerRect.top.toDouble(), + innerRect.right.toDouble(), + (innerRect.top + 2 * innerTopRightRadiusY).toDouble(), // Line Start + outerRect.right.toDouble(), + outerRect.top.toDouble(), // Line End + innerRect.right.toDouble(), + innerRect.top.toDouble(), // Result + it) + } + + /** Compute innerBottomRightCorner */ + innerBottomRightCorner = innerBottomRightCorner ?: PointF() + + innerBottomRightCorner?.x = innerRect.right + innerBottomRightCorner?.y = innerRect.bottom + + innerBottomRightCorner?.let { + getEllipseIntersectionWithLine( // Ellipse Bounds + (innerRect.right - 2 * innerBottomRightRadiusX).toDouble(), + (innerRect.bottom - 2 * innerBottomRightRadiusY).toDouble(), + innerRect.right.toDouble(), + innerRect.bottom.toDouble(), // Line Start + outerRect.right.toDouble(), + outerRect.bottom.toDouble(), // Line End + innerRect.right.toDouble(), + innerRect.bottom.toDouble(), // Result + it) + } + } + } + + /** + * Multiplies the color with the given alpha. + * + * @param color color to be multiplied + * @param alpha value between 0 and 255 + * @return multiplied color + */ + private fun multiplyColorAlpha(color: Int, rawAlpha: Int): Int { + if (rawAlpha == 255) { + return color + } + if (rawAlpha == 0) { + return color and 0x00FFFFFF + } + val alpha = rawAlpha + (rawAlpha shr 7) // make it 0..256 + val colorAlpha = color ushr 24 + val multipliedAlpha = colorAlpha * (alpha shr 7) shr 8 + return (multipliedAlpha shl 24) or (color and 0x00FFFFFF) + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java index 6c0f91b6c591de..506b9c89304209 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java @@ -18,6 +18,7 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.PathEffect; +import android.graphics.PixelFormat; import android.graphics.PointF; import android.graphics.PorterDuff; import android.graphics.Rect; @@ -189,7 +190,15 @@ public int getLayoutDirection() { @Override public int getOpacity() { - return (Color.alpha(mColor) * mAlpha) >> 8; + int alpha = (Color.alpha(mColor) * mAlpha) >> 8; + switch (alpha) { + case 255: + return PixelFormat.OPAQUE; + case 0: + return PixelFormat.TRANSPARENT; + default: + return PixelFormat.TRANSLUCENT; + } } /* Android's elevation implementation requires this to be implemented to know where to draw the shadow. */ @@ -385,7 +394,7 @@ private void drawRoundedBackgroundWithBorders(Canvas canvas) { canvas.clipPath(Preconditions.checkNotNull(mOuterClipPathForBorderRadius), Region.Op.INTERSECT); // Draws the View without its border first (with background color fill) - int useColor = ColorUtils.setAlphaComponent(mColor, getOpacity()); + int useColor = ColorUtils.setAlphaComponent(mColor, (Color.alpha(mColor) * mAlpha) >> 8); if (Color.alpha(useColor) != 0) { mPaint.setColor(useColor); mPaint.setStyle(Paint.Style.FILL); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CompositeBackgroundDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CompositeBackgroundDrawable.kt index adf57cc7c53f8b..b8b22fb414135d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CompositeBackgroundDrawable.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CompositeBackgroundDrawable.kt @@ -7,10 +7,16 @@ package com.facebook.react.uimanager.drawable +import android.content.Context +import android.graphics.Outline +import android.graphics.Path +import android.graphics.RectF import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable +import android.os.Build import com.facebook.react.common.annotations.UnstableReactNativeAPI import com.facebook.react.uimanager.style.BorderInsets +import com.facebook.react.uimanager.style.BorderRadiusStyle /** * CompositeBackgroundDrawable can overlay multiple different layers, shadows, and native effects @@ -18,6 +24,7 @@ import com.facebook.react.uimanager.style.BorderInsets */ @OptIn(UnstableReactNativeAPI::class) internal class CompositeBackgroundDrawable( + private val context: Context, /** * Any non-react-managed background already part of the view, like one set as Android style on a * TextInput @@ -35,6 +42,12 @@ internal class CompositeBackgroundDrawable( */ public val cssBackground: CSSBackgroundDrawable? = null, + /** Background rendering Layer */ + public val background: BackgroundDrawable? = null, + + /** Border rendering Layer */ + public val border: BorderDrawable? = null, + /** TouchableNativeFeeback set selection background, like "SelectableBackground" */ public val feedbackUnderlay: Drawable? = null, @@ -52,6 +65,8 @@ internal class CompositeBackgroundDrawable( // https://drafts.csswg.org/css-backgrounds/#shadow-layers *outerShadows.asReversed().toTypedArray(), cssBackground, + background, + border, feedbackUnderlay, *innerShadows.asReversed().toTypedArray(), outline) @@ -59,6 +74,8 @@ internal class CompositeBackgroundDrawable( // Holder value for currently set insets public var borderInsets: BorderInsets? = null + // Holder value for currently set border radius + public var borderRadius: BorderRadiusStyle? = null init { // We want to overlay drawables, instead of placing future drawables within the content area of @@ -71,7 +88,36 @@ internal class CompositeBackgroundDrawable( cssBackground: CSSBackgroundDrawable? ): CompositeBackgroundDrawable { return CompositeBackgroundDrawable( - originalBackground, outerShadows, cssBackground, feedbackUnderlay, innerShadows, outline) + context, + originalBackground, + outerShadows, + cssBackground, + background, + border, + feedbackUnderlay, + innerShadows, + outline) + .also { composite -> + composite.borderInsets = this.borderInsets + composite.borderRadius = this.borderRadius + } + } + + public fun withNewBackground(background: BackgroundDrawable?): CompositeBackgroundDrawable { + return CompositeBackgroundDrawable( + context, + originalBackground, + outerShadows, + cssBackground, + background, + border, + feedbackUnderlay, + innerShadows, + outline) + .also { composite -> + composite.borderInsets = this.borderInsets + composite.borderRadius = this.borderRadius + } } public fun withNewShadows( @@ -79,16 +125,106 @@ internal class CompositeBackgroundDrawable( innerShadows: List ): CompositeBackgroundDrawable { return CompositeBackgroundDrawable( - originalBackground, outerShadows, cssBackground, feedbackUnderlay, innerShadows, outline) + context, + originalBackground, + outerShadows, + cssBackground, + background, + border, + feedbackUnderlay, + innerShadows, + outline) + .also { composite -> + composite.borderInsets = this.borderInsets + composite.borderRadius = this.borderRadius + } + } + + public fun withNewBorder(border: BorderDrawable): CompositeBackgroundDrawable { + return CompositeBackgroundDrawable( + context, + originalBackground, + outerShadows, + cssBackground, + background, + border, + feedbackUnderlay, + innerShadows, + outline) + .also { composite -> + composite.borderInsets = this.borderInsets + composite.borderRadius = this.borderRadius + } } public fun withNewOutline(outline: OutlineDrawable): CompositeBackgroundDrawable { return CompositeBackgroundDrawable( - originalBackground, outerShadows, cssBackground, feedbackUnderlay, innerShadows, outline) + context, + originalBackground, + outerShadows, + cssBackground, + background, + border, + feedbackUnderlay, + innerShadows, + outline) + .also { composite -> + composite.borderInsets = this.borderInsets + composite.borderRadius = this.borderRadius + } } public fun withNewFeedbackUnderlay(newUnderlay: Drawable?): CompositeBackgroundDrawable { return CompositeBackgroundDrawable( - originalBackground, outerShadows, cssBackground, newUnderlay, innerShadows, outline) + context, + originalBackground, + outerShadows, + cssBackground, + background, + border, + newUnderlay, + innerShadows, + outline) + .also { composite -> + composite.borderInsets = this.borderInsets + composite.borderRadius = this.borderRadius + } + } + + /* Android's elevation implementation requires this to be implemented to know where to draw the + elevation shadow. */ + override fun getOutline(outline: Outline) { + if (borderRadius?.hasRoundedBorders() == true) { + val pathForOutline = Path() + + val computedBorderRadius = + borderRadius?.resolve( + layoutDirection, context, bounds.width().toFloat(), bounds.height().toFloat()) + + val computedBorderInsets = borderInsets?.resolve(layoutDirection, context) + + computedBorderRadius?.let { + pathForOutline.addRoundRect( + RectF(bounds), + floatArrayOf( + it.topLeft.horizontal + (computedBorderInsets?.left ?: 0f), + it.topLeft.vertical + (computedBorderInsets?.top ?: 0f), + it.topRight.horizontal + (computedBorderInsets?.right ?: 0f), + it.topRight.vertical + (computedBorderInsets?.top ?: 0f), + it.bottomRight.horizontal + (computedBorderInsets?.right ?: 0f), + it.bottomRight.vertical + (computedBorderInsets?.bottom ?: 0f), + it.bottomLeft.horizontal + (computedBorderInsets?.left ?: 0f), + it.bottomLeft.vertical) + (computedBorderInsets?.bottom ?: 0f), + Path.Direction.CW) + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + outline.setPath(pathForOutline) + } else { + @Suppress("DEPRECATION") outline.setConvexPath(pathForOutline) + } + } else { + outline.setRect(bounds) + } } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/InsetBoxShadowDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/InsetBoxShadowDrawable.kt index a241468a7149d3..a16eaa23d50652 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/InsetBoxShadowDrawable.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/InsetBoxShadowDrawable.kt @@ -40,30 +40,18 @@ private val ZERO_RADII = floatArrayOf(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f) @RequiresApi(MIN_INSET_BOX_SHADOW_SDK_VERSION) internal class InsetBoxShadowDrawable( private val context: Context, - borderRadius: BorderRadiusStyle? = null, - borderInsets: BorderInsets? = null, private val shadowColor: Int, private val offsetX: Float, private val offsetY: Float, private val blurRadius: Float, private val spread: Float, + /* + * We assume borderRadius & borderInsets to be shared across multiple drawables + * therefore user should invalidate this drawable when changing either of them + */ + var borderInsets: BorderInsets? = null, + var borderRadius: BorderRadiusStyle? = null, ) : Drawable() { - public var borderRadius = borderRadius - set(value) { - if (value != field) { - field = value - invalidateSelf() - } - } - - public var borderInsets = borderInsets - set(value) { - if (value != field) { - field = value - invalidateSelf() - } - } - private val shadowPaint = Paint().apply { color = shadowColor @@ -87,9 +75,12 @@ internal class InsetBoxShadowDrawable( @Deprecated("Deprecated in Java") override fun getOpacity(): Int { - val alpha = Color.alpha(shadowColor) - return if (alpha == 0) PixelFormat.TRANSPARENT - else ((shadowPaint.alpha / 255f) / (alpha / 255f) * 255f).roundToInt() + val alpha = shadowPaint.alpha + return when (alpha) { + 255 -> PixelFormat.OPAQUE + in 1..254 -> PixelFormat.TRANSLUCENT + else -> PixelFormat.TRANSPARENT + } } override fun draw(canvas: Canvas) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutlineDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutlineDrawable.kt index 7e0454a2cfac2c..cdc0edde2d8847 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutlineDrawable.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutlineDrawable.kt @@ -15,6 +15,7 @@ import android.graphics.DashPathEffect import android.graphics.Paint import android.graphics.Path import android.graphics.PathEffect +import android.graphics.PixelFormat import android.graphics.RectF import android.graphics.drawable.Drawable import com.facebook.react.uimanager.PixelUtil.dpToPx @@ -23,14 +24,15 @@ import com.facebook.react.uimanager.style.ComputedBorderRadius import com.facebook.react.uimanager.style.CornerRadii import com.facebook.react.uimanager.style.OutlineStyle import kotlin.math.roundToInt -import kotlin.properties.ObservableProperty -import kotlin.properties.ReadWriteProperty -import kotlin.reflect.KProperty /** Draws outline https://drafts.csswg.org/css-ui/#outline */ internal class OutlineDrawable( private val context: Context, - borderRadius: BorderRadiusStyle? = null, + /* + * We assume borderRadius to be shared across multiple drawables + * therefore we should manually invalidate this drawable when changing it + */ + var borderRadius: BorderRadiusStyle? = null, outlineColor: Int, outlineOffset: Float, outlineStyle: OutlineStyle, @@ -43,17 +45,14 @@ internal class OutlineDrawable( */ private val gapBetweenPaths = 0.8f - private fun invalidatingChange(initialValue: T): ReadWriteProperty = - object : ObservableProperty(initialValue) { - override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) { - if (oldValue != newValue) { - invalidateSelf() - } - } + public var outlineOffset: Float = outlineOffset + set(value) { + if (value != field) { + field = value + invalidateSelf() } + } - public var borderRadius: BorderRadiusStyle? by invalidatingChange(borderRadius) - public var outlineOffset: Float by invalidatingChange(outlineOffset) public var outlineStyle: OutlineStyle = outlineStyle set(value) { if (value != field) { @@ -106,8 +105,14 @@ internal class OutlineDrawable( } @Deprecated("Deprecated in Java") - override fun getOpacity(): Int = - ((outlinePaint.alpha / 255f) / (Color.alpha(outlineColor) / 255f) * 255f).roundToInt() + override fun getOpacity(): Int { + val alpha = outlinePaint.alpha + return when (alpha) { + 255 -> PixelFormat.OPAQUE + in 1..254 -> PixelFormat.TRANSLUCENT + else -> PixelFormat.TRANSPARENT + } + } override fun draw(canvas: Canvas) { if (outlineWidth == 0f) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutsetBoxShadowDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutsetBoxShadowDrawable.kt index 3d4a433d908dda..3f1f9acdb01b58 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutsetBoxShadowDrawable.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/OutsetBoxShadowDrawable.kt @@ -37,21 +37,17 @@ private const val BLUR_RADIUS_SIGMA_SCALE = 0.5f @RequiresApi(MIN_OUTSET_BOX_SHADOW_SDK_VERSION) internal class OutsetBoxShadowDrawable( private val context: Context, - borderRadius: BorderRadiusStyle? = null, private val shadowColor: Int, private val offsetX: Float, private val offsetY: Float, private val blurRadius: Float, private val spread: Float, + /* + * We assume borderRadius to be shared across multiple drawables + * therefore we should manually invalidate this drawable when changing it + */ + var borderRadius: BorderRadiusStyle? = null, ) : Drawable() { - public var borderRadius = borderRadius - set(value) { - if (value != field) { - field = value - invalidateSelf() - } - } - private val shadowPaint = Paint().apply { color = shadowColor @@ -75,9 +71,12 @@ internal class OutsetBoxShadowDrawable( @Deprecated("Deprecated in Java") override fun getOpacity(): Int { - val alpha = Color.alpha(shadowColor) - return if (alpha == 0) PixelFormat.TRANSPARENT - else ((shadowPaint.alpha / 255f) / (alpha / 255f) * 255f).roundToInt() + val alpha = shadowPaint.alpha + return when (alpha) { + 255 -> PixelFormat.OPAQUE + in 1..254 -> PixelFormat.TRANSLUCENT + else -> PixelFormat.TRANSPARENT + } } override fun draw(canvas: Canvas) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderColors.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderColors.kt new file mode 100644 index 00000000000000..e4d0f408a87852 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderColors.kt @@ -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. + */ + +package com.facebook.react.uimanager.style + +import android.content.Context +import android.graphics.Color +import android.util.LayoutDirection +import androidx.annotation.ColorInt +import com.facebook.react.modules.i18nmanager.I18nUtil + +internal data class ColorEdges( + @ColorInt val left: Int = Color.BLACK, + @ColorInt val top: Int = Color.BLACK, + @ColorInt val right: Int = Color.BLACK, + @ColorInt val bottom: Int = Color.BLACK, +) + +@JvmInline +internal value class BorderColors( + @ColorInt val edgeColors: Array = arrayOfNulls(LogicalEdge.values().size) +) { + + public fun resolve(layoutDirection: Int, context: Context): ColorEdges { + return when (layoutDirection) { + LayoutDirection.LTR -> + ColorEdges( + edgeColors[LogicalEdge.START.ordinal] + ?: edgeColors[LogicalEdge.LEFT.ordinal] + ?: edgeColors[LogicalEdge.HORIZONTAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK, + edgeColors[LogicalEdge.BLOCK_START.ordinal] + ?: edgeColors[LogicalEdge.TOP.ordinal] + ?: edgeColors[LogicalEdge.BLOCK.ordinal] + ?: edgeColors[LogicalEdge.VERTICAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK, + edgeColors[LogicalEdge.END.ordinal] + ?: edgeColors[LogicalEdge.RIGHT.ordinal] + ?: edgeColors[LogicalEdge.HORIZONTAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK, + edgeColors[LogicalEdge.BLOCK_END.ordinal] + ?: edgeColors[LogicalEdge.BOTTOM.ordinal] + ?: edgeColors[LogicalEdge.BLOCK.ordinal] + ?: edgeColors[LogicalEdge.VERTICAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK) + LayoutDirection.RTL -> + if (I18nUtil.instance.doLeftAndRightSwapInRTL(context)) { + ColorEdges( + edgeColors[LogicalEdge.END.ordinal] + ?: edgeColors[LogicalEdge.RIGHT.ordinal] + ?: edgeColors[LogicalEdge.HORIZONTAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK, + edgeColors[LogicalEdge.BLOCK_START.ordinal] + ?: edgeColors[LogicalEdge.TOP.ordinal] + ?: edgeColors[LogicalEdge.BLOCK.ordinal] + ?: edgeColors[LogicalEdge.VERTICAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK, + edgeColors[LogicalEdge.START.ordinal] + ?: edgeColors[LogicalEdge.LEFT.ordinal] + ?: edgeColors[LogicalEdge.HORIZONTAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK, + edgeColors[LogicalEdge.BLOCK_END.ordinal] + ?: edgeColors[LogicalEdge.BOTTOM.ordinal] + ?: edgeColors[LogicalEdge.BLOCK.ordinal] + ?: edgeColors[LogicalEdge.VERTICAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK) + } else { + ColorEdges( + edgeColors[LogicalEdge.END.ordinal] + ?: edgeColors[LogicalEdge.LEFT.ordinal] + ?: edgeColors[LogicalEdge.HORIZONTAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK, + edgeColors[LogicalEdge.BLOCK_START.ordinal] + ?: edgeColors[LogicalEdge.TOP.ordinal] + ?: edgeColors[LogicalEdge.BLOCK.ordinal] + ?: edgeColors[LogicalEdge.VERTICAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK, + edgeColors[LogicalEdge.START.ordinal] + ?: edgeColors[LogicalEdge.RIGHT.ordinal] + ?: edgeColors[LogicalEdge.HORIZONTAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK, + edgeColors[LogicalEdge.BLOCK_END.ordinal] + ?: edgeColors[LogicalEdge.BOTTOM.ordinal] + ?: edgeColors[LogicalEdge.BLOCK.ordinal] + ?: edgeColors[LogicalEdge.VERTICAL.ordinal] + ?: edgeColors[LogicalEdge.ALL.ordinal] + ?: Color.BLACK) + } + else -> throw IllegalArgumentException("Expected resolved layout direction") + } + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/ComputedBorderRadius.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/ComputedBorderRadius.kt index a16c951510e267..234f04bd4f2cee 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/ComputedBorderRadius.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/ComputedBorderRadius.kt @@ -15,7 +15,7 @@ public enum class ComputedBorderRadiusProp { COMPUTED_BORDER_BOTTOM_LEFT_RADIUS, } -/** Phsysical edge lengths (in DIPs) for a border-radius. */ +/** Physical edge lengths (in DIPs) for a border-radius. */ public data class ComputedBorderRadius( val topLeft: CornerRadii, val topRight: CornerRadii, @@ -32,6 +32,10 @@ public data class ComputedBorderRadius( bottomRight.horizontal > 0f } + public fun isUniform(): Boolean { + return topLeft == topRight && topLeft == bottomLeft && topLeft == bottomRight + } + public fun get(property: ComputedBorderRadiusProp): CornerRadii { return when (property) { ComputedBorderRadiusProp.COMPUTED_BORDER_TOP_LEFT_RADIUS -> topLeft diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java index bfa9da9b0c1af4..26c9aebc8388ad 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper.java @@ -115,9 +115,7 @@ private void updateScrollPositionInternal() { firstVisibleView.getHitRect(newFrame); if (mHorizontal) { - int deltaX = - (newFrame.left - mPrevFirstVisibleFrame.left) - + (newFrame.width() - mPrevFirstVisibleFrame.width()); + int deltaX = newFrame.left - mPrevFirstVisibleFrame.left; if (deltaX != 0) { int scrollX = mScrollView.getScrollX(); mScrollView.scrollToPreservingMomentum(scrollX + deltaX, mScrollView.getScrollY()); @@ -128,9 +126,7 @@ private void updateScrollPositionInternal() { } } } else { - int deltaY = - (newFrame.top - mPrevFirstVisibleFrame.top) - + (newFrame.height() - mPrevFirstVisibleFrame.height()); + int deltaY = newFrame.top - mPrevFirstVisibleFrame.top; if (deltaY != 0) { int scrollY = mScrollView.getScrollY(); mScrollView.scrollToPreservingMomentum(mScrollView.getScrollX(), scrollY + deltaY); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index 919777a11fd068..279868be6b4967 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -1444,6 +1444,7 @@ public void onLayoutChange( } else if (mMaintainVisibleContentPositionHelper != null) { mMaintainVisibleContentPositionHelper.updateScrollPosition(); } + ReactScrollViewHelper.emitLayoutChangeEvent(this); } /** diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index 3d18ba1986b103..7203f62ac8b8ad 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -1246,6 +1246,8 @@ public void onLayoutChange( scrollTo(getScrollX(), maxScrollY); } } + + ReactScrollViewHelper.emitLayoutChangeEvent(this); } @Override diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt index 5877312d0e39a8..39867529645f90 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.kt @@ -47,6 +47,7 @@ public object ReactScrollViewHelper { // Support global native listeners for scroll events private val scrollListeners = CopyOnWriteArrayList>() + private val layoutChangeListeners = CopyOnWriteArrayList>() // If all else fails, this is the hardcoded value in OverScroller.java, in AOSP. // The default is defined here (as of this diff): @@ -151,6 +152,13 @@ public object ReactScrollViewHelper { } } + @JvmStatic + public fun emitLayoutChangeEvent(scrollView: ViewGroup) { + for (listener in layoutChangeListeners) { + listener.get()?.onLayoutChange(scrollView) + } + } + @JvmStatic public fun parseOverScrollMode(jsOverScrollMode: String?): Int { return if (jsOverScrollMode == null || jsOverScrollMode == AUTO) { @@ -214,6 +222,16 @@ public object ReactScrollViewHelper { scrollListeners.remove(WeakReference(listener)) } + @JvmStatic + public fun addLayoutChangeListener(listener: LayoutChangeListener) { + layoutChangeListeners.add(WeakReference(listener)) + } + + @JvmStatic + public fun removeLayoutChangeListener(listener: LayoutChangeListener) { + layoutChangeListeners.remove(WeakReference(listener)) + } + /** * Scroll the given view to the location (x, y), with provided initial velocity. This method works * by calculate the "would be" initial velocity with internal friction to move to the point (x, @@ -456,6 +474,10 @@ public object ReactScrollViewHelper { public fun onLayout(scrollView: ViewGroup?) } + public interface LayoutChangeListener { + public fun onLayoutChange(scrollView: ViewGroup) + } + public interface HasStateWrapper { public val stateWrapper: StateWrapper? } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java index 6e22ae9f409651..63bb805fcac1c4 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java @@ -432,10 +432,11 @@ private static Layout createLayout( private static void updateTextPaint( TextPaint paint, TextAttributeProps baseTextAttributes, Context context) { // TextPaint attributes will be used for content outside the Spannable, like for the - // hypothetical height of a new line after a trailing newline charater (considered part of the + // hypothetical height of a new line after a trailing newline character (considered part of the // previous line). paint.reset(); paint.setAntiAlias(true); + if (baseTextAttributes.getEffectiveFontSize() != ReactConstants.UNSET) { paint.setTextSize(baseTextAttributes.getEffectiveFontSize()); } @@ -459,6 +460,8 @@ private static void updateTextPaint( paint.setFakeBoldText((missingStyle & Typeface.BOLD) != 0); paint.setTextSkewX((missingStyle & Typeface.ITALIC) != 0 ? -0.25f : 0); } + } else { + paint.setTypeface(null); } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.java index 364b52401c8198..6670ec5247e5f4 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextTransform.java @@ -48,13 +48,8 @@ private static String capitalize(String text) { StringBuilder res = new StringBuilder(text.length()); int start = wordIterator.first(); for (int end = wordIterator.next(); end != BreakIterator.DONE; end = wordIterator.next()) { - String word = text.substring(start, end); - if (Character.isLetterOrDigit(word.charAt(0))) { - res.append(Character.toUpperCase(word.charAt(0))); - res.append(word.substring(1).toLowerCase()); - } else { - res.append(word); - } + res.append(Character.toUpperCase(text.charAt(start))); + res.append(text.substring(start + 1, end)); start = end; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/CanvasUtil.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/CanvasUtil.kt index d3c41676e67e1d..cca90cc2e9d3dd 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/CanvasUtil.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/CanvasUtil.kt @@ -10,11 +10,6 @@ package com.facebook.react.views.view import android.annotation.SuppressLint import android.graphics.Canvas import android.os.Build -import android.os.Build.VERSION -import android.os.Build.VERSION.SDK_INT -import android.os.Build.VERSION_CODES -import android.os.Build.VERSION_CODES.P -import android.os.Build.VERSION_CODES.Q import java.lang.reflect.InvocationTargetException import java.lang.reflect.Method diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaDisplay.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaDisplay.java index d4c4685fcb220d..4dae871936e65a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaDisplay.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaDisplay.java @@ -11,7 +11,8 @@ public enum YogaDisplay { FLEX(0), - NONE(1); + NONE(1), + CONTENTS(2); private final int mIntValue; @@ -27,6 +28,7 @@ public static YogaDisplay fromInt(int value) { switch (value) { case 0: return FLEX; case 1: return NONE; + case 2: return CONTENTS; default: throw new IllegalArgumentException("Unknown enum value: " + value); } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java index a0f26bf2a930cc..e0521b3fbb52b4 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java @@ -12,7 +12,7 @@ public enum YogaErrata { NONE(0), STRETCH_FLEX_BASIS(1), - ABSOLUTE_POSITIONING_INCORRECT(2), + ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING(2), ABSOLUTE_PERCENT_AGAINST_INNER_SIZE(4), ALL(2147483647), CLASSIC(2147483646); @@ -31,7 +31,7 @@ public static YogaErrata fromInt(int value) { switch (value) { case 0: return NONE; case 1: return STRETCH_FLEX_BASIS; - case 2: return ABSOLUTE_POSITIONING_INCORRECT; + case 2: return ABSOLUTE_POSITION_WITHOUT_INSETS_EXCLUDES_PADDING; case 4: return ABSOLUTE_PERCENT_AGAINST_INNER_SIZE; case 2147483647: return ALL; case 2147483646: return CLASSIC; diff --git a/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt b/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt index eeab0dc871341a..c88061c56288b6 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt +++ b/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt @@ -49,6 +49,7 @@ add_library(fbjni ALIAS fbjni::fbjni) add_react_third_party_ndk_subdir(glog) add_react_third_party_ndk_subdir(boost) add_react_third_party_ndk_subdir(double-conversion) +add_react_third_party_ndk_subdir(fast_float) add_react_third_party_ndk_subdir(fmt) add_react_third_party_ndk_subdir(folly) add_react_third_party_ndk_subdir(jsc) diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AsyncEventBeat.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp similarity index 58% rename from packages/react-native/ReactAndroid/src/main/jni/react/fabric/AsyncEventBeat.cpp rename to packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp index 4160e35da17df7..cd902c0d3d2a4e 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AsyncEventBeat.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp @@ -9,52 +9,30 @@ #include #include -#include "AsyncEventBeat.h" +#include "AndroidEventBeat.h" namespace facebook::react { -AsyncEventBeat::AsyncEventBeat( - const EventBeat::SharedOwnerBox& ownerBox, +AndroidEventBeat::AndroidEventBeat( + std::shared_ptr ownerBox, EventBeatManager* eventBeatManager, RuntimeExecutor runtimeExecutor, jni::global_ref javaUIManager) - : EventBeat(ownerBox), + : EventBeat(std::move(ownerBox), std::move(runtimeExecutor)), eventBeatManager_(eventBeatManager), - runtimeExecutor_(std::move(runtimeExecutor)), javaUIManager_(std::move(javaUIManager)) { eventBeatManager->addObserver(*this); } -AsyncEventBeat::~AsyncEventBeat() { +AndroidEventBeat::~AndroidEventBeat() { eventBeatManager_->removeObserver(*this); } -void AsyncEventBeat::tick() const { - if (!isRequested_ || isBeatCallbackScheduled_) { - return; - } - - isRequested_ = false; - isBeatCallbackScheduled_ = true; - - runtimeExecutor_([this, ownerBox = ownerBox_](jsi::Runtime& runtime) { - auto owner = ownerBox->owner.lock(); - if (!owner) { - return; - } - - isBeatCallbackScheduled_ = false; - if (beatCallback_) { - beatCallback_(runtime); - } - }); -} - -void AsyncEventBeat::induce() const { - tick(); +void AndroidEventBeat::tick() const { + induce(); } -void AsyncEventBeat::request() const { +void AndroidEventBeat::request() const { bool alreadyRequested = isRequested_; EventBeat::request(); if (!alreadyRequested) { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AsyncEventBeat.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h similarity index 67% rename from packages/react-native/ReactAndroid/src/main/jni/react/fabric/AsyncEventBeat.h rename to packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h index a45567a3948997..bd4540bf5887a0 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AsyncEventBeat.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h @@ -13,27 +13,24 @@ namespace facebook::react { -class AsyncEventBeat final : public EventBeat, public EventBeatManagerObserver { +class AndroidEventBeat final : public EventBeat, + public EventBeatManagerObserver { public: - AsyncEventBeat( - const EventBeat::SharedOwnerBox& ownerBox, + AndroidEventBeat( + std::shared_ptr ownerBox, EventBeatManager* eventBeatManager, RuntimeExecutor runtimeExecutor, jni::global_ref javaUIManager); - ~AsyncEventBeat() override; + ~AndroidEventBeat() override; void tick() const override; - void induce() const override; - void request() const override; private: EventBeatManager* eventBeatManager_; - RuntimeExecutor runtimeExecutor_; jni::global_ref javaUIManager_; - mutable std::atomic isBeatCallbackScheduled_{false}; }; } // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp index fc8bcd1eed05f4..b5eb6c64bd238e 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp index 76384785d33d2e..cac043ee3a65e9 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp @@ -7,7 +7,7 @@ #include "FabricUIManagerBinding.h" -#include "AsyncEventBeat.h" +#include "AndroidEventBeat.h" #include "ComponentFactory.h" #include "EventBeatManager.h" #include "EventEmitterWrapper.h" @@ -30,7 +30,6 @@ #include #include #include -#include namespace facebook::react { @@ -73,16 +72,6 @@ FabricUIManagerBinding::getInspectorDataForInstance( return ReadableNativeMap::newObjectCxxArgs(result); } -constexpr static auto kReactFeatureFlagsJavaDescriptor = - "com/facebook/react/config/ReactFeatureFlags"; - -static bool getFeatureFlagValue(const char* name) { - static const auto reactFeatureFlagsClass = - jni::findClassStatic(kReactFeatureFlagsJavaDescriptor); - const auto field = reactFeatureFlagsClass->getStaticField(name); - return reactFeatureFlagsClass->getStaticFieldValue(field) != 0; -} - void FabricUIManagerBinding::setPixelDensity(float pointScaleFactor) { pointScaleFactor_ = pointScaleFactor; } @@ -485,12 +474,15 @@ void FabricUIManagerBinding::installFabricUIManager( } } - EventBeat::Factory asynchronousBeatFactory = + EventBeat::Factory eventBeatFactory = [eventBeatManager, runtimeExecutor, globalJavaUiManager]( - const EventBeat::SharedOwnerBox& ownerBox) + std::shared_ptr ownerBox) -> std::unique_ptr { - return std::make_unique( - ownerBox, eventBeatManager, runtimeExecutor, globalJavaUiManager); + return std::make_unique( + std::move(ownerBox), + eventBeatManager, + runtimeExecutor, + globalJavaUiManager); }; contextContainer->insert("ReactNativeConfig", config); @@ -499,11 +491,6 @@ void FabricUIManagerBinding::installFabricUIManager( // Keep reference to config object and cache some feature flags here reactNativeConfig_ = config; - CoreFeatures::enablePropIteratorSetter = - getFeatureFlagValue("enableCppPropsIteratorSetter"); - CoreFeatures::excludeYogaFromRawProps = - ReactNativeFeatureFlags::excludeYogaFromRawProps(); - auto toolbox = SchedulerToolbox{}; toolbox.contextContainer = contextContainer; toolbox.componentRegistryFactory = componentsRegistry->buildRegistryFunction; @@ -513,7 +500,7 @@ void FabricUIManagerBinding::installFabricUIManager( toolbox.bridgelessBindingsExecutor = std::nullopt; toolbox.runtimeExecutor = runtimeExecutor; - toolbox.asynchronousEventBeatFactory = asynchronousBeatFactory; + toolbox.eventBeatFactory = eventBeatFactory; animationDriver_ = std::make_shared( runtimeExecutor, contextContainer, this); @@ -548,7 +535,7 @@ FabricUIManagerBinding::getMountingManager(const char* locationHint) { } void FabricUIManagerBinding::schedulerDidFinishTransaction( - const MountingCoordinator::Shared& mountingCoordinator) { + const std::shared_ptr& mountingCoordinator) { // We shouldn't be pulling the transaction here (which triggers diffing of // the trees to determine the mutations to run on the host platform), // but we have to due to current limitations in the Android implementation. @@ -577,7 +564,8 @@ void FabricUIManagerBinding::schedulerDidFinishTransaction( } void FabricUIManagerBinding::schedulerShouldRenderTransactions( - const MountingCoordinator::Shared& /* mountingCoordinator */) { + const std::shared_ptr< + const MountingCoordinator>& /* mountingCoordinator */) { auto mountingManager = getMountingManager("schedulerShouldRenderTransactions"); if (!mountingManager) { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h index 28941791ee7fc2..817c256c4d7675 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h @@ -101,10 +101,12 @@ class FabricUIManagerBinding : public jni::HybridClass, jni::alias_ref surfaceHandler); void schedulerDidFinishTransaction( - const MountingCoordinator::Shared& mountingCoordinator) override; + const std::shared_ptr& mountingCoordinator) + override; void schedulerShouldRenderTransactions( - const MountingCoordinator::Shared& mountingCoordinator) override; + const std::shared_ptr& mountingCoordinator) + override; void schedulerDidRequestPreliminaryViewAllocation( const ShadowNode& shadowNode) override; diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 948f6c159b18f5..704015059f6d40 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<3898770919a834c4c4466d0b2797ba8b>> + * @generated SignedSource<<732d1ea726d8a08859bd153dc767ec7a>> */ /** @@ -51,15 +51,15 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } - bool batchRenderingUpdatesInEventLoop() override { + bool completeReactInstanceCreationOnBgThreadOnAndroid() override { static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("batchRenderingUpdatesInEventLoop"); + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("completeReactInstanceCreationOnBgThreadOnAndroid"); return method(javaProvider_); } - bool completeReactInstanceCreationOnBgThreadOnAndroid() override { + bool disableEventLoopOnBridgeless() override { static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("completeReactInstanceCreationOnBgThreadOnAndroid"); + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("disableEventLoopOnBridgeless"); return method(javaProvider_); } @@ -87,6 +87,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool enableCppPropsIteratorSetter() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableCppPropsIteratorSetter"); + return method(javaProvider_); + } + bool enableDeletionOfUnmountedViews() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableDeletionOfUnmountedViews"); @@ -153,9 +159,9 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } - bool enableMicrotasks() override { + bool enableNewBackgroundAndBorderDrawables() override { static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableMicrotasks"); + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableNewBackgroundAndBorderDrawables"); return method(javaProvider_); } @@ -279,12 +285,6 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } - bool useModernRuntimeScheduler() override { - static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useModernRuntimeScheduler"); - return method(javaProvider_); - } - bool useNativeViewConfigsInBridgelessMode() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useNativeViewConfigsInBridgelessMode"); @@ -335,14 +335,14 @@ bool JReactNativeFeatureFlagsCxxInterop::allowRecursiveCommitsWithSynchronousMou return ReactNativeFeatureFlags::allowRecursiveCommitsWithSynchronousMountOnAndroid(); } -bool JReactNativeFeatureFlagsCxxInterop::batchRenderingUpdatesInEventLoop( +bool JReactNativeFeatureFlagsCxxInterop::completeReactInstanceCreationOnBgThreadOnAndroid( facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop(); + return ReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAndroid(); } -bool JReactNativeFeatureFlagsCxxInterop::completeReactInstanceCreationOnBgThreadOnAndroid( +bool JReactNativeFeatureFlagsCxxInterop::disableEventLoopOnBridgeless( facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAndroid(); + return ReactNativeFeatureFlags::disableEventLoopOnBridgeless(); } bool JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS( @@ -365,6 +365,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableCleanTextInputYogaNode( return ReactNativeFeatureFlags::enableCleanTextInputYogaNode(); } +bool JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableCppPropsIteratorSetter(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableDeletionOfUnmountedViews( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableDeletionOfUnmountedViews(); @@ -420,9 +425,9 @@ bool JReactNativeFeatureFlagsCxxInterop::enableLongTaskAPI( return ReactNativeFeatureFlags::enableLongTaskAPI(); } -bool JReactNativeFeatureFlagsCxxInterop::enableMicrotasks( +bool JReactNativeFeatureFlagsCxxInterop::enableNewBackgroundAndBorderDrawables( facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::enableMicrotasks(); + return ReactNativeFeatureFlags::enableNewBackgroundAndBorderDrawables(); } bool JReactNativeFeatureFlagsCxxInterop::enablePreciseSchedulingForPremountItemsOnAndroid( @@ -525,11 +530,6 @@ bool JReactNativeFeatureFlagsCxxInterop::useImmediateExecutorInAndroidBridgeless return ReactNativeFeatureFlags::useImmediateExecutorInAndroidBridgeless(); } -bool JReactNativeFeatureFlagsCxxInterop::useModernRuntimeScheduler( - facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::useModernRuntimeScheduler(); -} - bool JReactNativeFeatureFlagsCxxInterop::useNativeViewConfigsInBridgelessMode( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::useNativeViewConfigsInBridgelessMode(); @@ -597,12 +597,12 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "allowRecursiveCommitsWithSynchronousMountOnAndroid", JReactNativeFeatureFlagsCxxInterop::allowRecursiveCommitsWithSynchronousMountOnAndroid), - makeNativeMethod( - "batchRenderingUpdatesInEventLoop", - JReactNativeFeatureFlagsCxxInterop::batchRenderingUpdatesInEventLoop), makeNativeMethod( "completeReactInstanceCreationOnBgThreadOnAndroid", JReactNativeFeatureFlagsCxxInterop::completeReactInstanceCreationOnBgThreadOnAndroid), + makeNativeMethod( + "disableEventLoopOnBridgeless", + JReactNativeFeatureFlagsCxxInterop::disableEventLoopOnBridgeless), makeNativeMethod( "enableAlignItemsBaselineOnFabricIOS", JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS), @@ -615,6 +615,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableCleanTextInputYogaNode", JReactNativeFeatureFlagsCxxInterop::enableCleanTextInputYogaNode), + makeNativeMethod( + "enableCppPropsIteratorSetter", + JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter), makeNativeMethod( "enableDeletionOfUnmountedViews", JReactNativeFeatureFlagsCxxInterop::enableDeletionOfUnmountedViews), @@ -649,8 +652,8 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { "enableLongTaskAPI", JReactNativeFeatureFlagsCxxInterop::enableLongTaskAPI), makeNativeMethod( - "enableMicrotasks", - JReactNativeFeatureFlagsCxxInterop::enableMicrotasks), + "enableNewBackgroundAndBorderDrawables", + JReactNativeFeatureFlagsCxxInterop::enableNewBackgroundAndBorderDrawables), makeNativeMethod( "enablePreciseSchedulingForPremountItemsOnAndroid", JReactNativeFeatureFlagsCxxInterop::enablePreciseSchedulingForPremountItemsOnAndroid), @@ -711,9 +714,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "useImmediateExecutorInAndroidBridgeless", JReactNativeFeatureFlagsCxxInterop::useImmediateExecutorInAndroidBridgeless), - makeNativeMethod( - "useModernRuntimeScheduler", - JReactNativeFeatureFlagsCxxInterop::useModernRuntimeScheduler), makeNativeMethod( "useNativeViewConfigsInBridgelessMode", JReactNativeFeatureFlagsCxxInterop::useNativeViewConfigsInBridgelessMode), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index 0ff427ce4d7b59..e480193163af18 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<88fc1d08894dc2f774ed8c64b20bdaeb>> */ /** @@ -36,10 +36,10 @@ class JReactNativeFeatureFlagsCxxInterop static bool allowRecursiveCommitsWithSynchronousMountOnAndroid( facebook::jni::alias_ref); - static bool batchRenderingUpdatesInEventLoop( + static bool completeReactInstanceCreationOnBgThreadOnAndroid( facebook::jni::alias_ref); - static bool completeReactInstanceCreationOnBgThreadOnAndroid( + static bool disableEventLoopOnBridgeless( facebook::jni::alias_ref); static bool enableAlignItemsBaselineOnFabricIOS( @@ -54,6 +54,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableCleanTextInputYogaNode( facebook::jni::alias_ref); + static bool enableCppPropsIteratorSetter( + facebook::jni::alias_ref); + static bool enableDeletionOfUnmountedViews( facebook::jni::alias_ref); @@ -87,7 +90,7 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableLongTaskAPI( facebook::jni::alias_ref); - static bool enableMicrotasks( + static bool enableNewBackgroundAndBorderDrawables( facebook::jni::alias_ref); static bool enablePreciseSchedulingForPremountItemsOnAndroid( @@ -150,9 +153,6 @@ class JReactNativeFeatureFlagsCxxInterop static bool useImmediateExecutorInAndroidBridgeless( facebook::jni::alias_ref); - static bool useModernRuntimeScheduler( - facebook::jni::alias_ref); - static bool useNativeViewConfigsInBridgelessMode( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/CMakeLists.txt b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/CMakeLists.txt index 7b117afd85ae8b..7fa081c724a71d 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/CMakeLists.txt +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/CMakeLists.txt @@ -47,7 +47,6 @@ add_library( turbomodulejsijni OBJECT ReactCommon/BindingsInstallerHolder.cpp - ReactCommon/CompositeTurboModuleManagerDelegate.cpp ReactCommon/OnLoad.cpp ReactCommon/TurboModuleManager.cpp $ diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.cpp deleted file mode 100644 index a8e37e77e40c13..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 "CompositeTurboModuleManagerDelegate.h" - -namespace facebook::react { - -jni::local_ref -CompositeTurboModuleManagerDelegate::initHybrid(jni::alias_ref) { - return makeCxxInstance(); -} - -void CompositeTurboModuleManagerDelegate::registerNatives() { - registerHybrid({ - makeNativeMethod( - "initHybrid", CompositeTurboModuleManagerDelegate::initHybrid), - makeNativeMethod( - "addTurboModuleManagerDelegate", - CompositeTurboModuleManagerDelegate::addTurboModuleManagerDelegate), - }); -} - -std::shared_ptr -CompositeTurboModuleManagerDelegate::getTurboModule( - const std::string& moduleName, - const std::shared_ptr& jsInvoker) { - for (auto delegate : mDelegates_) { - if (auto turboModule = - delegate->cthis()->getTurboModule(moduleName, jsInvoker)) { - return turboModule; - } - } - return nullptr; -} - -std::shared_ptr -CompositeTurboModuleManagerDelegate::getTurboModule( - const std::string& moduleName, - const JavaTurboModule::InitParams& params) { - for (auto delegate : mDelegates_) { - if (auto turboModule = - delegate->cthis()->getTurboModule(moduleName, params)) { - return turboModule; - } - } - return nullptr; -} - -void CompositeTurboModuleManagerDelegate::addTurboModuleManagerDelegate( - jni::alias_ref delegate) { - mDelegates_.push_back(jni::make_global(delegate)); -} - -} // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.h b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.h deleted file mode 100644 index 52b24cc8b1e2cc..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/CompositeTurboModuleManagerDelegate.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - */ - -#pragma once - -#include -#include -#include -#include -#include - -namespace facebook::react { - -class CompositeTurboModuleManagerDelegate - : public jni::HybridClass< - CompositeTurboModuleManagerDelegate, - TurboModuleManagerDelegate> { - public: - static auto constexpr kJavaDescriptor = - "Lcom/facebook/react/CompositeReactPackageTurboModuleManagerDelegate;"; - - static jni::local_ref initHybrid(jni::alias_ref); - - static void registerNatives(); - - std::shared_ptr getTurboModule( - const std::string& moduleName, - const std::shared_ptr& jsInvoker) override; - - std::shared_ptr getTurboModule( - const std::string& moduleName, - const JavaTurboModule::InitParams& params) override; - - private: - friend HybridBase; - using HybridBase::HybridBase; - std::vector> - mDelegates_; - - void addTurboModuleManagerDelegate( - jni::alias_ref delegate); -}; - -} // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/OnLoad.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/OnLoad.cpp index 013e2ca94f0764..bb33972bbfb910 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/OnLoad.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/OnLoad.cpp @@ -9,7 +9,6 @@ #include #include -#include "CompositeTurboModuleManagerDelegate.h" #include "TurboModuleManager.h" void jniEnableCppLogging( @@ -26,8 +25,6 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { // "ComponentDescriptorFactory" is defined in Fabric facebook::react::TurboModuleManager::registerNatives(); - facebook::react::CompositeTurboModuleManagerDelegate::registerNatives(); - facebook::jni::registerNatives( "com/facebook/react/internal/turbomodule/core/TurboModulePerfLogger", {makeNativeMethod("jniEnableCppLogging", jniEnableCppLogging)}); diff --git a/packages/react-native/ReactAndroid/src/main/jni/third-party/fast_float/CMakeLists.txt b/packages/react-native/ReactAndroid/src/main/jni/third-party/fast_float/CMakeLists.txt new file mode 100644 index 00000000000000..1b9d34f9ba6b7f --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/jni/third-party/fast_float/CMakeLists.txt @@ -0,0 +1,13 @@ +# 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. + +cmake_minimum_required(VERSION 3.13) +set(CMAKE_VERBOSE_MAKEFILE on) + +add_compile_options(-std=c++20 -fexceptions) + +add_library(fast_float INTERFACE) + +target_include_directories(fast_float INTERFACE include) diff --git a/packages/react-native/ReactAndroid/src/main/jni/third-party/folly/CMakeLists.txt b/packages/react-native/ReactAndroid/src/main/jni/third-party/folly/CMakeLists.txt index 58040e3024c53b..f86871b32f6e59 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/third-party/folly/CMakeLists.txt +++ b/packages/react-native/ReactAndroid/src/main/jni/third-party/folly/CMakeLists.txt @@ -26,11 +26,8 @@ SET(folly_FLAGS SET(folly_runtime_SRC folly/Conv.cpp folly/Demangle.cpp - folly/dynamic.cpp folly/FileUtil.cpp folly/Format.cpp - folly/json_pointer.cpp - folly/json.cpp folly/ScopeGuard.cpp folly/SharedMutex.cpp folly/String.cpp @@ -42,6 +39,9 @@ SET(folly_runtime_SRC folly/detail/SplitStringSimd.cpp folly/detail/UniqueInstance.cpp folly/hash/SpookyHashV2.cpp + folly/json/dynamic.cpp + folly/json/json_pointer.cpp + folly/json/json.cpp folly/lang/CString.cpp folly/lang/SafeAssert.cpp folly/lang/ToAscii.cpp @@ -51,8 +51,7 @@ SET(folly_runtime_SRC folly/synchronization/SanitizeThread.cpp folly/synchronization/ParkingLot.cpp folly/system/AtFork.cpp - folly/system/ThreadId.cpp - folly/system/ThreadName.cpp) + folly/system/ThreadId.cpp) add_library(folly_runtime STATIC ${folly_runtime_SRC}) @@ -67,4 +66,4 @@ target_compile_options(folly_runtime target_compile_options(folly_runtime PUBLIC ${folly_FLAGS}) target_include_directories(folly_runtime PUBLIC .) -target_link_libraries(folly_runtime glog double-conversion boost fmt) +target_link_libraries(folly_runtime glog double-conversion boost fmt fast_float) diff --git a/packages/react-native/ReactAndroid/src/main/res/views/alert/layout/alert_title_layout.xml b/packages/react-native/ReactAndroid/src/main/res/views/alert/layout/alert_title_layout.xml index 0677d76b4b0601..1814ab47fc85ac 100644 --- a/packages/react-native/ReactAndroid/src/main/res/views/alert/layout/alert_title_layout.xml +++ b/packages/react-native/ReactAndroid/src/main/res/views/alert/layout/alert_title_layout.xml @@ -6,9 +6,10 @@ android:orientation="horizontal" android:paddingStart="?android:attr/dialogPreferredPadding" android:paddingTop="18dp" - android:paddingEnd="?android:attr/dialogPreferredPadding"> + android:paddingEnd="?android:attr/dialogPreferredPadding" + > - + /> diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/CompositeReactPackageTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/CompositeReactPackageTest.kt deleted file mode 100644 index 74607b2c5452a3..00000000000000 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/CompositeReactPackageTest.kt +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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. - */ - -package com.facebook.react - -import com.facebook.react.bridge.BridgeReactContext -import com.facebook.react.bridge.NativeModule -import com.facebook.react.bridge.ReactApplicationContext -import com.facebook.react.uimanager.ViewManager -import org.assertj.core.api.Assertions.assertThat -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito.mock -import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` as whenever -import org.robolectric.RobolectricTestRunner -import org.robolectric.RuntimeEnvironment - -@RunWith(RobolectricTestRunner::class) -class CompositeReactPackageTest { - private lateinit var packageNo1: ReactPackage - private lateinit var packageNo2: ReactPackage - private lateinit var packageNo3: ReactPackage - private lateinit var reactContext: ReactApplicationContext - - @Before - fun setUp() { - packageNo1 = mock(ReactPackage::class.java) - packageNo2 = mock(ReactPackage::class.java) - packageNo3 = mock(ReactPackage::class.java) - reactContext = BridgeReactContext(RuntimeEnvironment.getApplication()) - } - - @Test - @Suppress("DEPRECATION") - fun testThatCreateNativeModulesIsCalledOnAllPackages() { - // Given - val composite = CompositeReactPackage(packageNo1, packageNo2, packageNo3) - - // When - composite.createNativeModules(reactContext) - - // Then - verify(packageNo1).createNativeModules(reactContext) - verify(packageNo2).createNativeModules(reactContext) - verify(packageNo3).createNativeModules(reactContext) - } - - @Test - @Suppress("DEPRECATION") - fun testThatCreateViewManagersIsCalledOnAllPackages() { - // Given - val composite = CompositeReactPackage(packageNo1, packageNo2, packageNo3) - - // When - composite.createViewManagers(reactContext) - - // Then - verify(packageNo1).createViewManagers(reactContext) - verify(packageNo2).createViewManagers(reactContext) - verify(packageNo3).createViewManagers(reactContext) - } - - @Test - @Suppress("DEPRECATION") - fun testThatCompositeReturnsASumOfNativeModules() { - // Given - val composite = CompositeReactPackage(packageNo1, packageNo2) - val moduleNo1 = mock(NativeModule::class.java) - whenever(moduleNo1.name).thenReturn("ModuleNo1") - - // module2 and module3 will share same name, composite should return only the latter one - val sameModuleName = "SameModuleName" - val moduleNo2 = mock(NativeModule::class.java) - whenever(moduleNo2.name).thenReturn(sameModuleName) - val moduleNo3 = mock(NativeModule::class.java) - whenever(moduleNo3.name).thenReturn(sameModuleName) - val moduleNo4 = mock(NativeModule::class.java) - whenever(moduleNo4.name).thenReturn("ModuleNo4") - whenever(packageNo1.createNativeModules(reactContext)).thenReturn(listOf(moduleNo1, moduleNo2)) - whenever(packageNo2.createNativeModules(reactContext)).thenReturn(listOf(moduleNo3, moduleNo4)) - - // When - val compositeModules = composite.createNativeModules(reactContext) - - // Then - - // Wrapping lists into sets to be order-independent. - // Note that there should be no module2 returned. - val expected: Set = setOf(moduleNo1, moduleNo3, moduleNo4) - val actual: Set = compositeModules.toSet() - assertThat(actual).isEqualTo(expected) - } - - @Test - @Suppress("DEPRECATION") - fun testThatCompositeReturnsASumOfViewManagers() { - // Given - val composite = CompositeReactPackage(packageNo1, packageNo2) - val managerNo1 = mock(ViewManager::class.java) - whenever(managerNo1.name).thenReturn("ManagerNo1") - - // managerNo2 and managerNo3 will share same name, composite should return only the latter - // one - val sameModuleName = "SameModuleName" - val managerNo2 = mock(ViewManager::class.java) - whenever(managerNo2.name).thenReturn(sameModuleName) - val managerNo3 = mock(ViewManager::class.java) - whenever(managerNo3.name).thenReturn(sameModuleName) - val managerNo4 = mock(ViewManager::class.java) - whenever(managerNo4.name).thenReturn("ManagerNo4") - whenever(packageNo1.createViewManagers(reactContext)).thenReturn(listOf(managerNo1, managerNo2)) - whenever(packageNo2.createViewManagers(reactContext)).thenReturn(listOf(managerNo3, managerNo4)) - - // When - val compositeModules = composite.createViewManagers(reactContext) - - // Then - - // Wrapping lists into sets to be order-independent. - // Note that there should be no managerNo2 returned. - val expected: Set> = setOf(managerNo1, managerNo3, managerNo4) - val actual: Set> = compositeModules.toSet() - assertThat(actual).isEqualTo(expected) - } -} diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.kt index c68e1bbedb1e78..4285a84fb127e6 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.kt @@ -92,7 +92,7 @@ class RootViewTest { val eventEmitterModuleMock = mock(RCTEventEmitter::class.java) whenever(catalystInstanceMock.getNativeModule(UIManagerModule::class.java)) .thenReturn(uiManager) - whenever(uiManager.getEventDispatcher()).thenReturn(eventDispatcher) + whenever(uiManager.eventDispatcher).thenReturn(eventDispatcher) // RootView IDs is React Native follow the 11, 21, 31, ... progression. val rootViewId = 11 diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.kt index 5807188f02af1d..514f817f07d95a 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/animated/NativeAnimatedNodeTraversalTest.kt @@ -86,7 +86,7 @@ class NativeAnimatedNodeTraversalTest { uiManagerMock = mock(UIManagerModule::class.java) eventDispatcherMock = mock(EventDispatcher::class.java) - whenever(uiManagerMock.getEventDispatcher()).thenAnswer { eventDispatcherMock } + whenever(uiManagerMock.eventDispatcher).thenAnswer { eventDispatcherMock } whenever(uiManagerMock.constants).thenAnswer { mapOf("customDirectEventTypes" to emptyMap()) } diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/events/TouchEventDispatchTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/events/TouchEventDispatchTest.kt index 454982113c346d..4ecd8ef01de480 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/events/TouchEventDispatchTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/events/TouchEventDispatchTest.kt @@ -488,7 +488,7 @@ class TouchEventDispatchTest { spy(FabricUIManager(reactContext, viewManagerRegistry, batchEventDispatchedListener)) uiManager.initialize() - eventDispatcher = uiManager.getEventDispatcher() + eventDispatcher = uiManager.eventDispatcher // Ignore scheduled choreographer work val reactChoreographerMock = mock(ReactChoreographer::class.java) diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextTransformTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextTransformTest.kt new file mode 100644 index 00000000000000..6bd1c2dbe09db5 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextTransformTest.kt @@ -0,0 +1,37 @@ +/* + * 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. + */ + +package com.facebook.react.views.text + +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class TextTransformTest { + @Test + fun textTransformCapitalize() { + val input = "hello WORLD from ReAcT nAtIvE 2a !b c" + val output = "Hello WORLD From ReAcT NAtIvE 2a !B C" + assertThat(TextTransform.apply(input, TextTransform.CAPITALIZE)).isEqualTo(output) + } + + @Test + fun textTransformUppercase() { + val input = "hello WORLD from ReAcT nAtIvE 2a !b c" + val output = "HELLO WORLD FROM REACT NATIVE 2A !B C" + assertThat(TextTransform.apply(input, TextTransform.UPPERCASE)).isEqualTo(output) + } + + @Test + fun textTransformLowercase() { + val input = "hello WORLD from ReAcT nAtIvE 2a !b c" + val output = "hello world from react native 2a !b c" + assertThat(TextTransform.apply(input, TextTransform.LOWERCASE)).isEqualTo(output) + } +} diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt index 55f287820a5803..b37693bd51fc17 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/fakes/FakeUIManager.kt @@ -65,9 +65,8 @@ class FakeUIManager : UIManager, UIBlockViewResolver { error("Not yet implemented") } - override fun getEventDispatcher(): T { - error("Not yet implemented") - } + override val eventDispatcher: Any? + get() = TODO("Not yet implemented") override fun synchronouslyUpdateViewOnUIThread(reactTag: Int, props: ReadableMap?) { error("Not yet implemented") diff --git a/packages/react-native/ReactCommon/React-Fabric.podspec b/packages/react-native/ReactCommon/React-Fabric.podspec index 90952c98df5f42..bd71203db101ed 100644 --- a/packages/react-native/ReactCommon/React-Fabric.podspec +++ b/packages/react-native/ReactCommon/React-Fabric.podspec @@ -22,7 +22,7 @@ folly_version = folly_config[:version] folly_dep_name = folly_config[:dep_name] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] react_native_path = ".." Pod::Spec.new do |s| @@ -54,7 +54,8 @@ Pod::Spec.new do |s| s.dependency "React-logger" s.dependency "glog" s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" s.dependency "React-Core" s.dependency "React-debug" s.dependency "React-featureflags" diff --git a/packages/react-native/ReactCommon/React-FabricComponents.podspec b/packages/react-native/ReactCommon/React-FabricComponents.podspec index 0681668f1e6b3b..0ee540321355b0 100644 --- a/packages/react-native/ReactCommon/React-FabricComponents.podspec +++ b/packages/react-native/ReactCommon/React-FabricComponents.podspec @@ -22,7 +22,7 @@ folly_version = folly_config[:version] folly_dep_name = folly_config[:dep_name] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] react_native_path = ".." Pod::Spec.new do |s| @@ -34,6 +34,7 @@ Pod::Spec.new do |s| "\"$(PODS_ROOT)/Headers/Private/Yoga\"", "\"$(PODS_TARGET_SRCROOT)\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"", ] @@ -75,7 +76,8 @@ Pod::Spec.new do |s| s.dependency "React-logger" s.dependency "glog" s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" s.dependency "React-Core" s.dependency "React-debug" s.dependency "React-featureflags" diff --git a/packages/react-native/ReactCommon/React-FabricImage.podspec b/packages/react-native/ReactCommon/React-FabricImage.podspec index c6098086f1d759..c8e975a3e0aa95 100644 --- a/packages/react-native/ReactCommon/React-FabricImage.podspec +++ b/packages/react-native/ReactCommon/React-FabricImage.podspec @@ -22,7 +22,7 @@ folly_version = folly_config[:version] folly_dep_name = folly_config[:dep_name] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] react_native_path = ".." header_search_path = [ @@ -31,6 +31,7 @@ header_search_path = [ "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/Headers/Private/Yoga\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"", ] @@ -75,7 +76,9 @@ Pod::Spec.new do |s| s.dependency "React-logger" s.dependency "glog" s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" + s.dependency "React-featureflags" s.dependency "React-ImageManager" s.dependency "React-utils" s.dependency "Yoga" diff --git a/packages/react-native/ReactCommon/ReactCommon.podspec b/packages/react-native/ReactCommon/ReactCommon.podspec index fa0b905badb413..a6020da9fa8ce7 100644 --- a/packages/react-native/ReactCommon/ReactCommon.podspec +++ b/packages/react-native/ReactCommon/ReactCommon.podspec @@ -20,7 +20,7 @@ folly_config = get_folly_config() folly_compiler_flags = folly_config[:compiler_flags] folly_version = folly_config[:version] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] using_hermes = ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == "1" Pod::Spec.new do |s| @@ -35,7 +35,7 @@ Pod::Spec.new do |s| s.source = source s.header_dir = "ReactCommon" # Use global header_dir for all subspecs for use_frameworks! compatibility s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags - s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\" \"$(PODS_ROOT)/Headers/Private/React-Core\"", + s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\" \"$(PODS_ROOT)/Headers/Private/React-Core\"", "USE_HEADERMAP" => "YES", "DEFINES_MODULE" => "YES", "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), @@ -54,7 +54,8 @@ Pod::Spec.new do |s| ss.dependency "RCT-Folly", folly_version ss.dependency "React-logger", version ss.dependency "DoubleConversion" - ss.dependency "fmt", "9.1.0" + ss.dependency "fast_float", "6.1.4" + ss.dependency "fmt", "11.0.2" ss.dependency "glog" if using_hermes ss.dependency "hermes-engine" diff --git a/packages/react-native/ReactCommon/cxxreact/React-cxxreact.podspec b/packages/react-native/ReactCommon/cxxreact/React-cxxreact.podspec index 6ee6c635cd73cb..2f05b75b71463d 100644 --- a/packages/react-native/ReactCommon/cxxreact/React-cxxreact.podspec +++ b/packages/react-native/ReactCommon/cxxreact/React-cxxreact.podspec @@ -21,7 +21,7 @@ folly_config = get_folly_config() folly_compiler_flags = folly_config[:compiler_flags] folly_version = folly_config[:version] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] Pod::Spec.new do |s| s.name = "React-cxxreact" @@ -36,14 +36,15 @@ Pod::Spec.new do |s| s.exclude_files = "SampleCxxModule.*" s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-debug/React_debug.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-runtimeexecutor/React_runtimeexecutor.framework/Headers\"", + "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fas_float/include\" \"$(PODS_ROOT)/fmt/include\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-debug/React_debug.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-runtimeexecutor/React_runtimeexecutor.framework/Headers\"", "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard() } s.header_dir = "cxxreact" s.dependency "boost" s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" s.dependency "RCT-Folly", folly_version s.dependency "glog" add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern') diff --git a/packages/react-native/ReactCommon/hermes/React-hermes.podspec b/packages/react-native/ReactCommon/hermes/React-hermes.podspec index 470fdafd02a5d1..3a072cf9df0127 100644 --- a/packages/react-native/ReactCommon/hermes/React-hermes.podspec +++ b/packages/react-native/ReactCommon/hermes/React-hermes.podspec @@ -21,7 +21,7 @@ folly_config = get_folly_config() folly_compiler_flags = folly_config[:compiler_flags] folly_version = folly_config[:version] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] Pod::Spec.new do |s| s.name = "React-hermes" @@ -47,7 +47,8 @@ Pod::Spec.new do |s| s.dependency "React-perflogger", version s.dependency "RCT-Folly", folly_version s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" s.dependency "glog" s.dependency "hermes-engine" s.dependency "React-jsi" diff --git a/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp b/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp index 8bcbe849d1fe9b..69652a173caaa7 100644 --- a/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp +++ b/packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.cpp @@ -50,6 +50,18 @@ void objectAssign( auto assign = Object.getPropertyAsFunction(runtime, "assign"); assign.callWithThis(runtime, Object, target, value); } + +jsi::Object wrapInErrorIfNecessary( + jsi::Runtime& runtime, + const jsi::Value& value) { + auto Error = runtime.global().getPropertyAsFunction(runtime, "Error"); + auto isError = + value.isObject() && value.asObject(runtime).instanceOf(runtime, Error); + auto error = isError + ? value.getObject(runtime) + : Error.callAsConstructor(runtime, value).getObject(runtime); + return error; +} } // namespace namespace facebook::react { @@ -187,7 +199,7 @@ void JsErrorHandler::emitError( jsi::JSError& error, bool isFatal) { auto message = error.getMessage(); - auto errorObj = error.value().getObject(runtime); + auto errorObj = wrapInErrorIfNecessary(runtime, error.value()); auto componentStackValue = errorObj.getProperty(runtime, "componentStack"); if (!isLooselyNull(componentStackValue)) { message += "\n" + stringifyToCpp(runtime, componentStackValue); diff --git a/packages/react-native/ReactCommon/jsi/React-jsi.podspec b/packages/react-native/ReactCommon/jsi/React-jsi.podspec index 818e0f6db91ef3..9425d6761f4d64 100644 --- a/packages/react-native/ReactCommon/jsi/React-jsi.podspec +++ b/packages/react-native/ReactCommon/jsi/React-jsi.podspec @@ -24,7 +24,7 @@ folly_config = get_folly_config() folly_compiler_flags = folly_config[:compiler_flags] folly_version = folly_config[:version] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] Pod::Spec.new do |s| s.name = "React-jsi" @@ -38,12 +38,13 @@ Pod::Spec.new do |s| s.header_dir = "jsi" s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags - s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\"", + s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\"", "DEFINES_MODULE" => "YES" } s.dependency "boost" s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" s.dependency "RCT-Folly", folly_version s.dependency "glog" diff --git a/packages/react-native/ReactCommon/jsiexecutor/React-jsiexecutor.podspec b/packages/react-native/ReactCommon/jsiexecutor/React-jsiexecutor.podspec index 1343607933ae88..17641842b98da8 100644 --- a/packages/react-native/ReactCommon/jsiexecutor/React-jsiexecutor.podspec +++ b/packages/react-native/ReactCommon/jsiexecutor/React-jsiexecutor.podspec @@ -20,7 +20,7 @@ folly_config = get_folly_config() folly_compiler_flags = folly_config[:compiler_flags] folly_version = folly_config[:version] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] Pod::Spec.new do |s| s.name = "React-jsiexecutor" @@ -33,7 +33,7 @@ Pod::Spec.new do |s| s.source = source s.source_files = "jsireact/*.{cpp,h}" s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags - s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\"", + s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\"", "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard() } s.header_dir = "jsireact" @@ -42,7 +42,8 @@ Pod::Spec.new do |s| s.dependency "React-perflogger", version s.dependency "RCT-Folly", folly_version s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" s.dependency "glog" add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern') diff --git a/packages/react-native/ReactCommon/jsinspector-modern/React-jsinspector.podspec b/packages/react-native/ReactCommon/jsinspector-modern/React-jsinspector.podspec index 2f61ed9934cdd4..cd3dbb49970b10 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/React-jsinspector.podspec +++ b/packages/react-native/ReactCommon/jsinspector-modern/React-jsinspector.podspec @@ -37,7 +37,7 @@ Pod::Spec.new do |s| s.header_dir = 'jsinspector-modern' s.compiler_flags = folly_compiler_flags s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/..\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\"", + "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/..\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\"", "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), "DEFINES_MODULE" => "YES" }.merge!(use_frameworks ? { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 4ab0189b2a8e9b..696d000e77bb8a 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<6a62793678276e28e04ebe3d1b8b0d46>> + * @generated SignedSource<> */ /** @@ -34,14 +34,14 @@ bool ReactNativeFeatureFlags::allowRecursiveCommitsWithSynchronousMountOnAndroid return getAccessor().allowRecursiveCommitsWithSynchronousMountOnAndroid(); } -bool ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop() { - return getAccessor().batchRenderingUpdatesInEventLoop(); -} - bool ReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAndroid() { return getAccessor().completeReactInstanceCreationOnBgThreadOnAndroid(); } +bool ReactNativeFeatureFlags::disableEventLoopOnBridgeless() { + return getAccessor().disableEventLoopOnBridgeless(); +} + bool ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS() { return getAccessor().enableAlignItemsBaselineOnFabricIOS(); } @@ -58,6 +58,10 @@ bool ReactNativeFeatureFlags::enableCleanTextInputYogaNode() { return getAccessor().enableCleanTextInputYogaNode(); } +bool ReactNativeFeatureFlags::enableCppPropsIteratorSetter() { + return getAccessor().enableCppPropsIteratorSetter(); +} + bool ReactNativeFeatureFlags::enableDeletionOfUnmountedViews() { return getAccessor().enableDeletionOfUnmountedViews(); } @@ -102,8 +106,8 @@ bool ReactNativeFeatureFlags::enableLongTaskAPI() { return getAccessor().enableLongTaskAPI(); } -bool ReactNativeFeatureFlags::enableMicrotasks() { - return getAccessor().enableMicrotasks(); +bool ReactNativeFeatureFlags::enableNewBackgroundAndBorderDrawables() { + return getAccessor().enableNewBackgroundAndBorderDrawables(); } bool ReactNativeFeatureFlags::enablePreciseSchedulingForPremountItemsOnAndroid() { @@ -186,10 +190,6 @@ bool ReactNativeFeatureFlags::useImmediateExecutorInAndroidBridgeless() { return getAccessor().useImmediateExecutorInAndroidBridgeless(); } -bool ReactNativeFeatureFlags::useModernRuntimeScheduler() { - return getAccessor().useModernRuntimeScheduler(); -} - bool ReactNativeFeatureFlags::useNativeViewConfigsInBridgelessMode() { return getAccessor().useNativeViewConfigsInBridgelessMode(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 9585a18d4d7d3b..795a323ea19e2c 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5a537adba978cd74ba62e69d4aeb72b0>> + * @generated SignedSource<<29b98e3d5daf7ad09cdee366ef38753e>> */ /** @@ -50,14 +50,14 @@ class ReactNativeFeatureFlags { RN_EXPORT static bool allowRecursiveCommitsWithSynchronousMountOnAndroid(); /** - * When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop. + * Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android */ - RN_EXPORT static bool batchRenderingUpdatesInEventLoop(); + RN_EXPORT static bool completeReactInstanceCreationOnBgThreadOnAndroid(); /** - * Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android + * The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances. */ - RN_EXPORT static bool completeReactInstanceCreationOnBgThreadOnAndroid(); + RN_EXPORT static bool disableEventLoopOnBridgeless(); /** * Kill-switch to turn off support for aling-items:baseline on Fabric iOS. @@ -79,6 +79,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableCleanTextInputYogaNode(); + /** + * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). + */ + RN_EXPORT static bool enableCppPropsIteratorSetter(); + /** * Deletes views that were pre-allocated but never mounted on the screen. */ @@ -135,9 +140,9 @@ class ReactNativeFeatureFlags { RN_EXPORT static bool enableLongTaskAPI(); /** - * Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution). + * Use BackgroundDrawable and BorderDrawable instead of CSSBackgroundDrawable */ - RN_EXPORT static bool enableMicrotasks(); + RN_EXPORT static bool enableNewBackgroundAndBorderDrawables(); /** * Moves execution of pre-mount items to outside the choregrapher in the main thread, so we can estimate idle time more precisely (Android only). @@ -239,11 +244,6 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool useImmediateExecutorInAndroidBridgeless(); - /** - * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. - */ - RN_EXPORT static bool useModernRuntimeScheduler(); - /** * When enabled, the native view configs are used in bridgeless mode. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 54d3491c50c8be..691e72052380f0 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<59763b4423e81fbb2f99f78d12c9cca7>> */ /** @@ -65,8 +65,8 @@ bool ReactNativeFeatureFlagsAccessor::allowRecursiveCommitsWithSynchronousMountO return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::batchRenderingUpdatesInEventLoop() { - auto flagValue = batchRenderingUpdatesInEventLoop_.load(); +bool ReactNativeFeatureFlagsAccessor::completeReactInstanceCreationOnBgThreadOnAndroid() { + auto flagValue = completeReactInstanceCreationOnBgThreadOnAndroid_.load(); if (!flagValue.has_value()) { // This block is not exclusive but it is not necessary. @@ -74,17 +74,17 @@ bool ReactNativeFeatureFlagsAccessor::batchRenderingUpdatesInEventLoop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(2, "batchRenderingUpdatesInEventLoop"); + markFlagAsAccessed(2, "completeReactInstanceCreationOnBgThreadOnAndroid"); - flagValue = currentProvider_->batchRenderingUpdatesInEventLoop(); - batchRenderingUpdatesInEventLoop_ = flagValue; + flagValue = currentProvider_->completeReactInstanceCreationOnBgThreadOnAndroid(); + completeReactInstanceCreationOnBgThreadOnAndroid_ = flagValue; } return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::completeReactInstanceCreationOnBgThreadOnAndroid() { - auto flagValue = completeReactInstanceCreationOnBgThreadOnAndroid_.load(); +bool ReactNativeFeatureFlagsAccessor::disableEventLoopOnBridgeless() { + auto flagValue = disableEventLoopOnBridgeless_.load(); if (!flagValue.has_value()) { // This block is not exclusive but it is not necessary. @@ -92,10 +92,10 @@ bool ReactNativeFeatureFlagsAccessor::completeReactInstanceCreationOnBgThreadOnA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(3, "completeReactInstanceCreationOnBgThreadOnAndroid"); + markFlagAsAccessed(3, "disableEventLoopOnBridgeless"); - flagValue = currentProvider_->completeReactInstanceCreationOnBgThreadOnAndroid(); - completeReactInstanceCreationOnBgThreadOnAndroid_ = flagValue; + flagValue = currentProvider_->disableEventLoopOnBridgeless(); + disableEventLoopOnBridgeless_ = flagValue; } return flagValue.value(); @@ -173,6 +173,24 @@ bool ReactNativeFeatureFlagsAccessor::enableCleanTextInputYogaNode() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() { + auto flagValue = enableCppPropsIteratorSetter_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(8, "enableCppPropsIteratorSetter"); + + flagValue = currentProvider_->enableCppPropsIteratorSetter(); + enableCppPropsIteratorSetter_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableDeletionOfUnmountedViews() { auto flagValue = enableDeletionOfUnmountedViews_.load(); @@ -182,7 +200,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDeletionOfUnmountedViews() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(8, "enableDeletionOfUnmountedViews"); + markFlagAsAccessed(9, "enableDeletionOfUnmountedViews"); flagValue = currentProvider_->enableDeletionOfUnmountedViews(); enableDeletionOfUnmountedViews_ = flagValue; @@ -200,7 +218,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(9, "enableEagerRootViewAttachment"); + markFlagAsAccessed(10, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -218,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEventEmitterRetentionDuringGesturesO // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(10, "enableEventEmitterRetentionDuringGesturesOnAndroid"); + markFlagAsAccessed(11, "enableEventEmitterRetentionDuringGesturesOnAndroid"); flagValue = currentProvider_->enableEventEmitterRetentionDuringGesturesOnAndroid(); enableEventEmitterRetentionDuringGesturesOnAndroid_ = flagValue; @@ -236,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(11, "enableFabricLogs"); + markFlagAsAccessed(12, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -254,7 +272,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(12, "enableFabricRenderer"); + markFlagAsAccessed(13, "enableFabricRenderer"); flagValue = currentProvider_->enableFabricRenderer(); enableFabricRenderer_ = flagValue; @@ -272,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRendererExclusively() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(13, "enableFabricRendererExclusively"); + markFlagAsAccessed(14, "enableFabricRendererExclusively"); flagValue = currentProvider_->enableFabricRendererExclusively(); enableFabricRendererExclusively_ = flagValue; @@ -290,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableGranularShadowTreeStateReconciliatio // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(14, "enableGranularShadowTreeStateReconciliation"); + markFlagAsAccessed(15, "enableGranularShadowTreeStateReconciliation"); flagValue = currentProvider_->enableGranularShadowTreeStateReconciliation(); enableGranularShadowTreeStateReconciliation_ = flagValue; @@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(16, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -326,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(16, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(17, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(17, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(18, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(18, "enableLongTaskAPI"); + markFlagAsAccessed(19, "enableLongTaskAPI"); flagValue = currentProvider_->enableLongTaskAPI(); enableLongTaskAPI_ = flagValue; @@ -371,8 +389,8 @@ bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() { return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::enableMicrotasks() { - auto flagValue = enableMicrotasks_.load(); +bool ReactNativeFeatureFlagsAccessor::enableNewBackgroundAndBorderDrawables() { + auto flagValue = enableNewBackgroundAndBorderDrawables_.load(); if (!flagValue.has_value()) { // This block is not exclusive but it is not necessary. @@ -380,10 +398,10 @@ bool ReactNativeFeatureFlagsAccessor::enableMicrotasks() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "enableMicrotasks"); + markFlagAsAccessed(20, "enableNewBackgroundAndBorderDrawables"); - flagValue = currentProvider_->enableMicrotasks(); - enableMicrotasks_ = flagValue; + flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables(); + enableNewBackgroundAndBorderDrawables_ = flagValue; } return flagValue.value(); @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreciseSchedulingForPremountItemsOnA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enablePreciseSchedulingForPremountItemsOnAndroid"); + markFlagAsAccessed(21, "enablePreciseSchedulingForPremountItemsOnAndroid"); flagValue = currentProvider_->enablePreciseSchedulingForPremountItemsOnAndroid(); enablePreciseSchedulingForPremountItemsOnAndroid_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(22, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableReportEventPaintTime() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "enableReportEventPaintTime"); + markFlagAsAccessed(23, "enableReportEventPaintTime"); flagValue = currentProvider_->enableReportEventPaintTime(); enableReportEventPaintTime_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableSynchronousStateUpdates"); + markFlagAsAccessed(24, "enableSynchronousStateUpdates"); flagValue = currentProvider_->enableSynchronousStateUpdates(); enableSynchronousStateUpdates_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableTextPreallocationOptimisation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableTextPreallocationOptimisation"); + markFlagAsAccessed(25, "enableTextPreallocationOptimisation"); flagValue = currentProvider_->enableTextPreallocationOptimisation(); enableTextPreallocationOptimisation_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableUIConsistency"); + markFlagAsAccessed(26, "enableUIConsistency"); flagValue = currentProvider_->enableUIConsistency(); enableUIConsistency_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "enableViewRecycling"); + markFlagAsAccessed(27, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::excludeYogaFromRawProps() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "excludeYogaFromRawProps"); + markFlagAsAccessed(28, "excludeYogaFromRawProps"); flagValue = currentProvider_->excludeYogaFromRawProps(); excludeYogaFromRawProps_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(29, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMountingCoordinatorReportedPendingTrans // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); + markFlagAsAccessed(30, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); flagValue = currentProvider_->fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); fixMountingCoordinatorReportedPendingTransactionsOnAndroid_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::forceBatchingMountItemsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "forceBatchingMountItemsOnAndroid"); + markFlagAsAccessed(31, "forceBatchingMountItemsOnAndroid"); flagValue = currentProvider_->forceBatchingMountItemsOnAndroid(); forceBatchingMountItemsOnAndroid_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledDebug() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "fuseboxEnabledDebug"); + markFlagAsAccessed(32, "fuseboxEnabledDebug"); flagValue = currentProvider_->fuseboxEnabledDebug(); fuseboxEnabledDebug_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "fuseboxEnabledRelease"); + markFlagAsAccessed(33, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::initEagerTurboModulesOnNativeModulesQueueA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "initEagerTurboModulesOnNativeModulesQueueAndroid"); + markFlagAsAccessed(34, "initEagerTurboModulesOnNativeModulesQueueAndroid"); flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid(); initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "lazyAnimationCallbacks"); + markFlagAsAccessed(35, "lazyAnimationCallbacks"); flagValue = currentProvider_->lazyAnimationCallbacks(); lazyAnimationCallbacks_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::loadVectorDrawablesOnImages() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "loadVectorDrawablesOnImages"); + markFlagAsAccessed(36, "loadVectorDrawablesOnImages"); flagValue = currentProvider_->loadVectorDrawablesOnImages(); loadVectorDrawablesOnImages_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::setAndroidLayoutDirection() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "setAndroidLayoutDirection"); + markFlagAsAccessed(37, "setAndroidLayoutDirection"); flagValue = currentProvider_->setAndroidLayoutDirection(); setAndroidLayoutDirection_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(38, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "useFabricInterop"); + markFlagAsAccessed(39, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "useImmediateExecutorInAndroidBridgeless"); + markFlagAsAccessed(40, "useImmediateExecutorInAndroidBridgeless"); flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless(); useImmediateExecutorInAndroidBridgeless_ = flagValue; @@ -749,24 +767,6 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless() return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { - auto flagValue = useModernRuntimeScheduler_.load(); - - if (!flagValue.has_value()) { - // This block is not exclusive but it is not necessary. - // If multiple threads try to initialize the feature flag, we would only - // be accessing the provider multiple times but the end state of this - // instance and the returned flag value would be the same. - - markFlagAsAccessed(40, "useModernRuntimeScheduler"); - - flagValue = currentProvider_->useModernRuntimeScheduler(); - useModernRuntimeScheduler_ = flagValue; - } - - return flagValue.value(); -} - bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { auto flagValue = useNativeViewConfigsInBridgelessMode_.load(); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 20ba372edb1630..82934f3674d7af 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<3accca8a4ee3ca498f3de148b5c9865f>> + * @generated SignedSource<> */ /** @@ -34,12 +34,13 @@ class ReactNativeFeatureFlagsAccessor { bool commonTestFlag(); bool allowRecursiveCommitsWithSynchronousMountOnAndroid(); - bool batchRenderingUpdatesInEventLoop(); bool completeReactInstanceCreationOnBgThreadOnAndroid(); + bool disableEventLoopOnBridgeless(); bool enableAlignItemsBaselineOnFabricIOS(); bool enableAndroidLineHeightCentering(); bool enableBridgelessArchitecture(); bool enableCleanTextInputYogaNode(); + bool enableCppPropsIteratorSetter(); bool enableDeletionOfUnmountedViews(); bool enableEagerRootViewAttachment(); bool enableEventEmitterRetentionDuringGesturesOnAndroid(); @@ -51,7 +52,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableLayoutAnimationsOnAndroid(); bool enableLayoutAnimationsOnIOS(); bool enableLongTaskAPI(); - bool enableMicrotasks(); + bool enableNewBackgroundAndBorderDrawables(); bool enablePreciseSchedulingForPremountItemsOnAndroid(); bool enablePropsUpdateReconciliationAndroid(); bool enableReportEventPaintTime(); @@ -72,7 +73,6 @@ class ReactNativeFeatureFlagsAccessor { bool traceTurboModulePromiseRejectionsOnAndroid(); bool useFabricInterop(); bool useImmediateExecutorInAndroidBridgeless(); - bool useModernRuntimeScheduler(); bool useNativeViewConfigsInBridgelessMode(); bool useOptimisedViewPreallocationOnAndroid(); bool useOptimizedEventBatchingOnAndroid(); @@ -94,12 +94,13 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> commonTestFlag_; std::atomic> allowRecursiveCommitsWithSynchronousMountOnAndroid_; - std::atomic> batchRenderingUpdatesInEventLoop_; std::atomic> completeReactInstanceCreationOnBgThreadOnAndroid_; + std::atomic> disableEventLoopOnBridgeless_; std::atomic> enableAlignItemsBaselineOnFabricIOS_; std::atomic> enableAndroidLineHeightCentering_; std::atomic> enableBridgelessArchitecture_; std::atomic> enableCleanTextInputYogaNode_; + std::atomic> enableCppPropsIteratorSetter_; std::atomic> enableDeletionOfUnmountedViews_; std::atomic> enableEagerRootViewAttachment_; std::atomic> enableEventEmitterRetentionDuringGesturesOnAndroid_; @@ -111,7 +112,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableLayoutAnimationsOnAndroid_; std::atomic> enableLayoutAnimationsOnIOS_; std::atomic> enableLongTaskAPI_; - std::atomic> enableMicrotasks_; + std::atomic> enableNewBackgroundAndBorderDrawables_; std::atomic> enablePreciseSchedulingForPremountItemsOnAndroid_; std::atomic> enablePropsUpdateReconciliationAndroid_; std::atomic> enableReportEventPaintTime_; @@ -132,7 +133,6 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> traceTurboModulePromiseRejectionsOnAndroid_; std::atomic> useFabricInterop_; std::atomic> useImmediateExecutorInAndroidBridgeless_; - std::atomic> useModernRuntimeScheduler_; std::atomic> useNativeViewConfigsInBridgelessMode_; std::atomic> useOptimisedViewPreallocationOnAndroid_; std::atomic> useOptimizedEventBatchingOnAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 51b6d132ed93df..1201da7752f220 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<868e09dabcb458d56f73d5c6ef9ed05b>> + * @generated SignedSource<<116547f17bc1b3d16a8de7c92c5a9d53>> */ /** @@ -35,11 +35,11 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool batchRenderingUpdatesInEventLoop() override { + bool completeReactInstanceCreationOnBgThreadOnAndroid() override { return false; } - bool completeReactInstanceCreationOnBgThreadOnAndroid() override { + bool disableEventLoopOnBridgeless() override { return false; } @@ -59,6 +59,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableCppPropsIteratorSetter() override { + return false; + } + bool enableDeletionOfUnmountedViews() override { return false; } @@ -103,7 +107,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool enableMicrotasks() override { + bool enableNewBackgroundAndBorderDrawables() override { return false; } @@ -187,10 +191,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool useModernRuntimeScheduler() override { - return false; - } - bool useNativeViewConfigsInBridgelessMode() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 61b65a990c1c04..69f8d38a5c5cf7 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -27,12 +27,13 @@ class ReactNativeFeatureFlagsProvider { virtual bool commonTestFlag() = 0; virtual bool allowRecursiveCommitsWithSynchronousMountOnAndroid() = 0; - virtual bool batchRenderingUpdatesInEventLoop() = 0; virtual bool completeReactInstanceCreationOnBgThreadOnAndroid() = 0; + virtual bool disableEventLoopOnBridgeless() = 0; virtual bool enableAlignItemsBaselineOnFabricIOS() = 0; virtual bool enableAndroidLineHeightCentering() = 0; virtual bool enableBridgelessArchitecture() = 0; virtual bool enableCleanTextInputYogaNode() = 0; + virtual bool enableCppPropsIteratorSetter() = 0; virtual bool enableDeletionOfUnmountedViews() = 0; virtual bool enableEagerRootViewAttachment() = 0; virtual bool enableEventEmitterRetentionDuringGesturesOnAndroid() = 0; @@ -44,7 +45,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableLayoutAnimationsOnAndroid() = 0; virtual bool enableLayoutAnimationsOnIOS() = 0; virtual bool enableLongTaskAPI() = 0; - virtual bool enableMicrotasks() = 0; + virtual bool enableNewBackgroundAndBorderDrawables() = 0; virtual bool enablePreciseSchedulingForPremountItemsOnAndroid() = 0; virtual bool enablePropsUpdateReconciliationAndroid() = 0; virtual bool enableReportEventPaintTime() = 0; @@ -65,7 +66,6 @@ class ReactNativeFeatureFlagsProvider { virtual bool traceTurboModulePromiseRejectionsOnAndroid() = 0; virtual bool useFabricInterop() = 0; virtual bool useImmediateExecutorInAndroidBridgeless() = 0; - virtual bool useModernRuntimeScheduler() = 0; virtual bool useNativeViewConfigsInBridgelessMode() = 0; virtual bool useOptimisedViewPreallocationOnAndroid() = 0; virtual bool useOptimizedEventBatchingOnAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/React-NativeModulesApple.podspec b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/React-NativeModulesApple.podspec index 28dfaa3473cf39..a89192878b13e7 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/React-NativeModulesApple.podspec +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/React-NativeModulesApple.podspec @@ -21,7 +21,7 @@ folly_compiler_flags = folly_config[:compiler_flags] folly_version = folly_config[:version] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] using_hermes = ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == "1" @@ -37,7 +37,7 @@ Pod::Spec.new do |s| s.platforms = min_supported_versions s.source = source s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags - s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\" \"$(PODS_ROOT)/Headers/Private/React-Core\"", + s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\" \"$(PODS_ROOT)/Headers/Private/React-Core\"", "USE_HEADERMAP" => "YES", "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), "GCC_WARN_PEDANTIC" => "YES" } diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm index b7e32bdead22a2..4e87312664262e 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm @@ -475,30 +475,18 @@ - (instancetype)initWithBridgeProxy:(RCTBridgeProxy *)bridgeProxy - (BOOL)_isTurboModule:(const char *)moduleName { - if (RCTTurboModuleInteropForAllTurboModulesEnabled()) { - return NO; - } - Class moduleClass = [self _getModuleClassFromName:moduleName]; return moduleClass != nil && (isTurboModuleClass(moduleClass) && ![moduleClass isSubclassOfClass:RCTCxxModule.class]); } - (BOOL)_isLegacyModule:(const char *)moduleName { - if (RCTTurboModuleInteropForAllTurboModulesEnabled()) { - return YES; - } - Class moduleClass = [self _getModuleClassFromName:moduleName]; return [self _isLegacyModuleClass:moduleClass]; } - (BOOL)_isLegacyModuleClass:(Class)moduleClass { - if (RCTTurboModuleInteropForAllTurboModulesEnabled()) { - return YES; - } - return moduleClass != nil && (!isTurboModuleClass(moduleClass) || [moduleClass isSubclassOfClass:RCTCxxModule.class]); } diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 7f6b37060564a5..ace962fde67a43 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<81047b339ef89dfdfa10b58e22d9407d>> + * @generated SignedSource<<77a440bf8f6221e90d5ab7a1d7ad638e>> */ /** @@ -42,6 +42,13 @@ bool NativeReactNativeFeatureFlags::commonTestFlag( return ReactNativeFeatureFlags::commonTestFlag(); } +bool NativeReactNativeFeatureFlags::commonTestFlagWithoutNativeImplementation( + jsi::Runtime& /*runtime*/) { + // This flag is configured with `skipNativeAPI: true`. + // TODO(T204838867): Implement support for optional methods in C++ TM codegen and remove the method definition altogether. + return false; +} + bool NativeReactNativeFeatureFlags::allowRecursiveCommitsWithSynchronousMountOnAndroid( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::allowRecursiveCommitsWithSynchronousMountOnAndroid(); @@ -49,7 +56,9 @@ bool NativeReactNativeFeatureFlags::allowRecursiveCommitsWithSynchronousMountOnA bool NativeReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop( jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop(); + // This flag is configured with `skipNativeAPI: true`. + // TODO(T204838867): Implement support for optional methods in C++ TM codegen and remove the method definition altogether. + return false; } bool NativeReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAndroid( @@ -57,6 +66,11 @@ bool NativeReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAnd return ReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAndroid(); } +bool NativeReactNativeFeatureFlags::disableEventLoopOnBridgeless( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::disableEventLoopOnBridgeless(); +} + bool NativeReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS(); @@ -77,6 +91,11 @@ bool NativeReactNativeFeatureFlags::enableCleanTextInputYogaNode( return ReactNativeFeatureFlags::enableCleanTextInputYogaNode(); } +bool NativeReactNativeFeatureFlags::enableCppPropsIteratorSetter( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableCppPropsIteratorSetter(); +} + bool NativeReactNativeFeatureFlags::enableDeletionOfUnmountedViews( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableDeletionOfUnmountedViews(); @@ -134,7 +153,14 @@ bool NativeReactNativeFeatureFlags::enableLongTaskAPI( bool NativeReactNativeFeatureFlags::enableMicrotasks( jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::enableMicrotasks(); + // This flag is configured with `skipNativeAPI: true`. + // TODO(T204838867): Implement support for optional methods in C++ TM codegen and remove the method definition altogether. + return false; +} + +bool NativeReactNativeFeatureFlags::enableNewBackgroundAndBorderDrawables( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableNewBackgroundAndBorderDrawables(); } bool NativeReactNativeFeatureFlags::enablePreciseSchedulingForPremountItemsOnAndroid( @@ -239,7 +265,9 @@ bool NativeReactNativeFeatureFlags::useImmediateExecutorInAndroidBridgeless( bool NativeReactNativeFeatureFlags::useModernRuntimeScheduler( jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::useModernRuntimeScheduler(); + // This flag is configured with `skipNativeAPI: true`. + // TODO(T204838867): Implement support for optional methods in C++ TM codegen and remove the method definition altogether. + return false; } bool NativeReactNativeFeatureFlags::useNativeViewConfigsInBridgelessMode( diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index f0db3eed6aa334..ddb938e89eb82e 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<8260155b1822cf4906660d3ad9b298a4>> + * @generated SignedSource<<0885affcf6782a59b0f4a3d1370ffc90>> */ /** @@ -37,12 +37,16 @@ class NativeReactNativeFeatureFlags bool commonTestFlag(jsi::Runtime& runtime); + bool commonTestFlagWithoutNativeImplementation(jsi::Runtime& runtime); + bool allowRecursiveCommitsWithSynchronousMountOnAndroid(jsi::Runtime& runtime); bool batchRenderingUpdatesInEventLoop(jsi::Runtime& runtime); bool completeReactInstanceCreationOnBgThreadOnAndroid(jsi::Runtime& runtime); + bool disableEventLoopOnBridgeless(jsi::Runtime& runtime); + bool enableAlignItemsBaselineOnFabricIOS(jsi::Runtime& runtime); bool enableAndroidLineHeightCentering(jsi::Runtime& runtime); @@ -51,6 +55,8 @@ class NativeReactNativeFeatureFlags bool enableCleanTextInputYogaNode(jsi::Runtime& runtime); + bool enableCppPropsIteratorSetter(jsi::Runtime& runtime); + bool enableDeletionOfUnmountedViews(jsi::Runtime& runtime); bool enableEagerRootViewAttachment(jsi::Runtime& runtime); @@ -75,6 +81,8 @@ class NativeReactNativeFeatureFlags bool enableMicrotasks(jsi::Runtime& runtime); + bool enableNewBackgroundAndBorderDrawables(jsi::Runtime& runtime); + bool enablePreciseSchedulingForPremountItemsOnAndroid(jsi::Runtime& runtime); bool enablePropsUpdateReconciliationAndroid(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.cpp b/packages/react-native/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.cpp index cba57fd72c5539..d6754ffc7f9f95 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.cpp @@ -142,7 +142,8 @@ void NativeMutationObserver::notifyMutationObserversIfNecessary() { if (dispatchNotification) { SystraceSection s("NativeMutationObserver::notifyObservers"); - if (ReactNativeFeatureFlags::enableMicrotasks()) { + if (ReactNativeFeatureFlags::enableBridgelessArchitecture() && + !ReactNativeFeatureFlags::disableEventLoopOnBridgeless()) { runtime_->queueMicrotask(notifyMutationObservers_.value()); } else { jsInvoker_->invokeAsync([&](jsi::Runtime& runtime) { diff --git a/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec b/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec index a19e2dc1c8a5fd..b6155cbb19d533 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec +++ b/packages/react-native/ReactCommon/react/nativemodule/samples/ReactCommon-Samples.podspec @@ -21,13 +21,14 @@ folly_compiler_flags = folly_config[:compiler_flags] folly_version = folly_config[:version] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] using_hermes = ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == "1" header_search_paths = [ "\"$(PODS_ROOT)/boost\"", "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"", "\"$(PODS_ROOT)/Headers/Private/React-Core\"", ] @@ -63,7 +64,8 @@ Pod::Spec.new do |s| s.dependency "RCT-Folly" s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" s.dependency "React-Core" s.dependency "React-cxxreact" s.dependency "React-jsi" diff --git a/packages/react-native/ReactCommon/react/nativemodule/webperformance/NativePerformance.cpp b/packages/react-native/ReactCommon/react/nativemodule/webperformance/NativePerformance.cpp index aac21dd8752873..72ac7ef0e1219a 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/webperformance/NativePerformance.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/webperformance/NativePerformance.cpp @@ -117,6 +117,38 @@ double NativePerformance::now(jsi::Runtime& /*rt*/) { return JSExecutor::performanceNow(); } +double NativePerformance::markWithResult( + jsi::Runtime& rt, + std::string name, + std::optional startTime) { + auto [trackName, eventName] = parseTrackName(name); + auto entry = + PerformanceEntryReporter::getInstance()->reportMark(name, startTime); + + ReactPerfLogger::mark(eventName, entry.startTime, trackName); + + return entry.startTime; +} + +std::tuple NativePerformance::measureWithResult( + jsi::Runtime& rt, + std::string name, + double startTime, + double endTime, + std::optional duration, + std::optional startMark, + std::optional endMark) { + auto [trackName, eventName] = parseTrackName(name); + + auto entry = PerformanceEntryReporter::getInstance()->reportMeasure( + eventName, startTime, endTime, duration, startMark, endMark); + + ReactPerfLogger::measure( + eventName, entry.startTime, entry.startTime + entry.duration, trackName); + + return std::tuple{entry.startTime, entry.duration}; +} + void NativePerformance::mark( jsi::Runtime& rt, std::string name, diff --git a/packages/react-native/ReactCommon/react/nativemodule/webperformance/NativePerformance.h b/packages/react-native/ReactCommon/react/nativemodule/webperformance/NativePerformance.h index 4e173796db3557..11da8fb3fe419b 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/webperformance/NativePerformance.h +++ b/packages/react-native/ReactCommon/react/nativemodule/webperformance/NativePerformance.h @@ -70,9 +70,11 @@ class NativePerformance : public NativePerformanceCxxSpec { #pragma mark - User Timing Level 3 functions (https://w3c.github.io/user-timing/) // https://w3c.github.io/user-timing/#mark-method + // TODO delete when `markWithResult` is fully rolled out void mark(jsi::Runtime& rt, std::string name, double startTime); // https://w3c.github.io/user-timing/#measure-method + // TODO delete when `measureWithResult` is fully rolled out void measure( jsi::Runtime& rt, std::string name, @@ -82,6 +84,22 @@ class NativePerformance : public NativePerformanceCxxSpec { std::optional startMark, std::optional endMark); + // https://w3c.github.io/user-timing/#mark-method + double markWithResult( + jsi::Runtime& rt, + std::string name, + std::optional startTime); + + // https://w3c.github.io/user-timing/#measure-method + std::tuple measureWithResult( + jsi::Runtime& rt, + std::string name, + double startTime, + double endTime, + std::optional duration, + std::optional startMark, + std::optional endMark); + // https://w3c.github.io/user-timing/#clearmarks-method void clearMarks( jsi::Runtime& rt, diff --git a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp index 620b678cd804a2..770ce54d6e2500 100644 --- a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp +++ b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.cpp @@ -125,7 +125,7 @@ void PerformanceEntryReporter::clearEntries( getBufferRef(entryType).clear(entryName); } -void PerformanceEntryReporter::reportMark( +PerformanceEntry PerformanceEntryReporter::reportMark( const std::string& name, const std::optional& startTime) { const auto entry = PerformanceEntry{ @@ -139,9 +139,10 @@ void PerformanceEntryReporter::reportMark( } observerRegistry_->queuePerformanceEntry(entry); + return entry; } -void PerformanceEntryReporter::reportMeasure( +PerformanceEntry PerformanceEntryReporter::reportMeasure( const std::string_view& name, DOMHighResTimeStamp startTime, DOMHighResTimeStamp endTime, @@ -173,6 +174,7 @@ void PerformanceEntryReporter::reportMeasure( } observerRegistry_->queuePerformanceEntry(entry); + return entry; } DOMHighResTimeStamp PerformanceEntryReporter::getMarkTime( diff --git a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h index 71526197456bad..ef13bcf3cfb5a0 100644 --- a/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h +++ b/packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h @@ -74,11 +74,11 @@ class PerformanceEntryReporter { return eventCounts_; } - void reportMark( + PerformanceEntry reportMark( const std::string& name, const std::optional& startTime = std::nullopt); - void reportMeasure( + PerformanceEntry reportMeasure( const std::string_view& name, double startTime, double endTime, diff --git a/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp index 7f660904ae83e8..6fed6d0b96d466 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.cpp @@ -5,10 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +#include #include #include #include -#include namespace facebook::react { @@ -18,15 +18,16 @@ ImageProps::ImageProps( const RawProps& rawProps) : ViewProps(context, sourceProps, rawProps), sources( - CoreFeatures::enablePropIteratorSetter ? sourceProps.sources - : convertRawProp( - context, - rawProps, - "source", - sourceProps.sources, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.sources + : convertRawProp( + context, + rawProps, + "source", + sourceProps.sources, + {})), defaultSources( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.defaultSources : convertRawProp( context, @@ -35,7 +36,7 @@ ImageProps::ImageProps( sourceProps.defaultSources, {})), resizeMode( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.resizeMode : convertRawProp( context, @@ -44,31 +45,34 @@ ImageProps::ImageProps( sourceProps.resizeMode, ImageResizeMode::Stretch)), blurRadius( - CoreFeatures::enablePropIteratorSetter ? sourceProps.blurRadius - : convertRawProp( - context, - rawProps, - "blurRadius", - sourceProps.blurRadius, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.blurRadius + : convertRawProp( + context, + rawProps, + "blurRadius", + sourceProps.blurRadius, + {})), capInsets( - CoreFeatures::enablePropIteratorSetter ? sourceProps.capInsets - : convertRawProp( - context, - rawProps, - "capInsets", - sourceProps.capInsets, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.capInsets + : convertRawProp( + context, + rawProps, + "capInsets", + sourceProps.capInsets, + {})), tintColor( - CoreFeatures::enablePropIteratorSetter ? sourceProps.tintColor - : convertRawProp( - context, - rawProps, - "tintColor", - sourceProps.tintColor, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.tintColor + : convertRawProp( + context, + rawProps, + "tintColor", + sourceProps.tintColor, + {})), internal_analyticTag( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.internal_analyticTag : convertRawProp( context, diff --git a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp index 674c0e2c921621..0dbb4a0f519309 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.cpp @@ -7,10 +7,10 @@ #include "ScrollViewProps.h" +#include #include #include #include -#include #include @@ -22,7 +22,7 @@ ScrollViewProps::ScrollViewProps( const RawProps& rawProps) : ViewProps(context, sourceProps, rawProps), alwaysBounceHorizontal( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.alwaysBounceHorizontal : convertRawProp( context, @@ -31,7 +31,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.alwaysBounceHorizontal, {})), alwaysBounceVertical( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.alwaysBounceVertical : convertRawProp( context, @@ -40,23 +40,25 @@ ScrollViewProps::ScrollViewProps( sourceProps.alwaysBounceVertical, {})), bounces( - CoreFeatures::enablePropIteratorSetter ? sourceProps.bounces - : convertRawProp( - context, - rawProps, - "bounces", - sourceProps.bounces, - true)), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.bounces + : convertRawProp( + context, + rawProps, + "bounces", + sourceProps.bounces, + true)), bouncesZoom( - CoreFeatures::enablePropIteratorSetter ? sourceProps.bouncesZoom - : convertRawProp( - context, - rawProps, - "bouncesZoom", - sourceProps.bouncesZoom, - true)), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.bouncesZoom + : convertRawProp( + context, + rawProps, + "bouncesZoom", + sourceProps.bouncesZoom, + true)), canCancelContentTouches( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.canCancelContentTouches : convertRawProp( context, @@ -65,7 +67,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.canCancelContentTouches, true)), centerContent( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.centerContent : convertRawProp( context, @@ -74,7 +76,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.centerContent, {})), automaticallyAdjustContentInsets( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.automaticallyAdjustContentInsets : convertRawProp( context, @@ -83,7 +85,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.automaticallyAdjustContentInsets, {})), automaticallyAdjustsScrollIndicatorInsets( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.automaticallyAdjustsScrollIndicatorInsets : convertRawProp( context, @@ -92,7 +94,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.automaticallyAdjustsScrollIndicatorInsets, true)), automaticallyAdjustKeyboardInsets( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.automaticallyAdjustKeyboardInsets : convertRawProp( context, @@ -101,7 +103,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.automaticallyAdjustKeyboardInsets, false)), decelerationRate( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.decelerationRate : convertRawProp( context, @@ -110,7 +112,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.decelerationRate, (Float)0.998)), endDraggingSensitivityMultiplier( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.endDraggingSensitivityMultiplier : convertRawProp( context, @@ -119,7 +121,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.endDraggingSensitivityMultiplier, (Float)1)), enableSyncOnScroll( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.enableSyncOnScroll : convertRawProp( context, @@ -128,7 +130,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.enableSyncOnScroll, false)), directionalLockEnabled( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.directionalLockEnabled : convertRawProp( context, @@ -137,7 +139,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.directionalLockEnabled, {})), indicatorStyle( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.indicatorStyle : convertRawProp( context, @@ -146,7 +148,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.indicatorStyle, {})), keyboardDismissMode( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.keyboardDismissMode : convertRawProp( context, @@ -155,7 +157,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.keyboardDismissMode, {})), maintainVisibleContentPosition( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.maintainVisibleContentPosition : convertRawProp( context, @@ -164,7 +166,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.maintainVisibleContentPosition, {})), maximumZoomScale( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.maximumZoomScale : convertRawProp( context, @@ -173,7 +175,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.maximumZoomScale, (Float)1.0)), minimumZoomScale( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.minimumZoomScale : convertRawProp( context, @@ -182,7 +184,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.minimumZoomScale, (Float)1.0)), scrollEnabled( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.scrollEnabled : convertRawProp( context, @@ -191,7 +193,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.scrollEnabled, true)), pagingEnabled( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.pagingEnabled : convertRawProp( context, @@ -200,7 +202,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.pagingEnabled, {})), pinchGestureEnabled( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.pinchGestureEnabled : convertRawProp( context, @@ -209,15 +211,16 @@ ScrollViewProps::ScrollViewProps( sourceProps.pinchGestureEnabled, true)), scrollsToTop( - CoreFeatures::enablePropIteratorSetter ? sourceProps.scrollsToTop - : convertRawProp( - context, - rawProps, - "scrollsToTop", - sourceProps.scrollsToTop, - true)), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.scrollsToTop + : convertRawProp( + context, + rawProps, + "scrollsToTop", + sourceProps.scrollsToTop, + true)), showsHorizontalScrollIndicator( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.showsHorizontalScrollIndicator : convertRawProp( context, @@ -226,7 +229,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.showsHorizontalScrollIndicator, true)), showsVerticalScrollIndicator( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.showsVerticalScrollIndicator : convertRawProp( context, @@ -235,7 +238,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.showsVerticalScrollIndicator, true)), persistentScrollbar( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.persistentScrollbar : convertRawProp( context, @@ -244,15 +247,16 @@ ScrollViewProps::ScrollViewProps( sourceProps.persistentScrollbar, true)), horizontal( - CoreFeatures::enablePropIteratorSetter ? sourceProps.horizontal - : convertRawProp( - context, - rawProps, - "horizontal", - sourceProps.horizontal, - true)), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.horizontal + : convertRawProp( + context, + rawProps, + "horizontal", + sourceProps.horizontal, + true)), scrollEventThrottle( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.scrollEventThrottle : convertRawProp( context, @@ -261,23 +265,25 @@ ScrollViewProps::ScrollViewProps( sourceProps.scrollEventThrottle, {})), zoomScale( - CoreFeatures::enablePropIteratorSetter ? sourceProps.zoomScale - : convertRawProp( - context, - rawProps, - "zoomScale", - sourceProps.zoomScale, - (Float)1.0)), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.zoomScale + : convertRawProp( + context, + rawProps, + "zoomScale", + sourceProps.zoomScale, + (Float)1.0)), contentInset( - CoreFeatures::enablePropIteratorSetter ? sourceProps.contentInset - : convertRawProp( - context, - rawProps, - "contentInset", - sourceProps.contentInset, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.contentInset + : convertRawProp( + context, + rawProps, + "contentInset", + sourceProps.contentInset, + {})), contentOffset( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.contentOffset : convertRawProp( context, @@ -286,7 +292,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.contentOffset, {})), scrollIndicatorInsets( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.scrollIndicatorInsets : convertRawProp( context, @@ -295,7 +301,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.scrollIndicatorInsets, {})), snapToInterval( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.snapToInterval : convertRawProp( context, @@ -304,7 +310,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.snapToInterval, {})), snapToAlignment( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.snapToAlignment : convertRawProp( context, @@ -313,7 +319,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.snapToAlignment, {})), disableIntervalMomentum( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.disableIntervalMomentum : convertRawProp( context, @@ -322,7 +328,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.disableIntervalMomentum, {})), snapToOffsets( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.snapToOffsets : convertRawProp( context, @@ -331,23 +337,25 @@ ScrollViewProps::ScrollViewProps( sourceProps.snapToOffsets, {})), snapToStart( - CoreFeatures::enablePropIteratorSetter ? sourceProps.snapToStart - : convertRawProp( - context, - rawProps, - "snapToStart", - sourceProps.snapToStart, - true)), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.snapToStart + : convertRawProp( + context, + rawProps, + "snapToStart", + sourceProps.snapToStart, + true)), snapToEnd( - CoreFeatures::enablePropIteratorSetter ? sourceProps.snapToEnd - : convertRawProp( - context, - rawProps, - "snapToEnd", - sourceProps.snapToEnd, - true)), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.snapToEnd + : convertRawProp( + context, + rawProps, + "snapToEnd", + sourceProps.snapToEnd, + true)), contentInsetAdjustmentBehavior( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.contentInsetAdjustmentBehavior : convertRawProp( context, @@ -356,7 +364,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.contentInsetAdjustmentBehavior, {ContentInsetAdjustmentBehavior::Never})), scrollToOverflowEnabled( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.scrollToOverflowEnabled : convertRawProp( context, @@ -365,7 +373,7 @@ ScrollViewProps::ScrollViewProps( sourceProps.scrollToOverflowEnabled, {})), isInvertedVirtualizedList( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.isInvertedVirtualizedList : convertRawProp( context, diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp index e5fd9513461417..132281e8ab8333 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.cpp @@ -7,11 +7,11 @@ #include "BaseTextProps.h" +#include #include #include #include #include -#include namespace facebook::react { @@ -230,7 +230,7 @@ BaseTextProps::BaseTextProps( const BaseTextProps& sourceProps, const RawProps& rawProps) : textAttributes( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.textAttributes : convertRawProp( context, diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphProps.cpp index 4011bbf2dc8f7e..12e1b9780b8b9c 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphProps.cpp @@ -7,11 +7,11 @@ #include "ParagraphProps.h" +#include #include #include #include #include -#include #include @@ -24,7 +24,7 @@ ParagraphProps::ParagraphProps( : ViewProps(context, sourceProps, rawProps), BaseTextProps(context, sourceProps, rawProps), paragraphAttributes( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.paragraphAttributes : convertRawProp( context, @@ -32,21 +32,23 @@ ParagraphProps::ParagraphProps( sourceProps.paragraphAttributes, {})), isSelectable( - CoreFeatures::enablePropIteratorSetter ? sourceProps.isSelectable - : convertRawProp( - context, - rawProps, - "selectable", - sourceProps.isSelectable, - false)), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.isSelectable + : convertRawProp( + context, + rawProps, + "selectable", + sourceProps.isSelectable, + false)), onTextLayout( - CoreFeatures::enablePropIteratorSetter ? sourceProps.onTextLayout - : convertRawProp( - context, - rawProps, - "onTextLayout", - sourceProps.onTextLayout, - {})) { + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.onTextLayout + : convertRawProp( + context, + rawProps, + "onTextLayout", + sourceProps.onTextLayout, + {})) { /* * These props are applied to `View`, therefore they must not be a part of * base text attributes. diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp index a8330828df1fda..3285754ea20f97 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp @@ -21,7 +21,6 @@ #include #include #include -#include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp index 2d7e82532e14ec..15f44a150679b1 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp @@ -6,10 +6,10 @@ */ #include "AndroidTextInputProps.h" +#include #include #include #include -#include namespace facebook::react { @@ -37,162 +37,162 @@ AndroidTextInputProps::AndroidTextInputProps( const AndroidTextInputProps &sourceProps, const RawProps &rawProps) : BaseTextInputProps(context, sourceProps, rawProps), - autoComplete(CoreFeatures::enablePropIteratorSetter? sourceProps.autoComplete : convertRawProp( + autoComplete(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.autoComplete : convertRawProp( context, rawProps, "autoComplete", sourceProps.autoComplete, {})), - returnKeyLabel(CoreFeatures::enablePropIteratorSetter? sourceProps.autoComplete : convertRawProp(context, rawProps, + returnKeyLabel(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.autoComplete : convertRawProp(context, rawProps, "returnKeyLabel", sourceProps.returnKeyLabel, {})), - numberOfLines(CoreFeatures::enablePropIteratorSetter? sourceProps.numberOfLines : convertRawProp(context, rawProps, + numberOfLines(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.numberOfLines : convertRawProp(context, rawProps, "numberOfLines", sourceProps.numberOfLines, {0})), - disableFullscreenUI(CoreFeatures::enablePropIteratorSetter? sourceProps.disableFullscreenUI : convertRawProp(context, rawProps, + disableFullscreenUI(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.disableFullscreenUI : convertRawProp(context, rawProps, "disableFullscreenUI", sourceProps.disableFullscreenUI, {false})), - textBreakStrategy(CoreFeatures::enablePropIteratorSetter? sourceProps.textBreakStrategy : convertRawProp(context, rawProps, + textBreakStrategy(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textBreakStrategy : convertRawProp(context, rawProps, "textBreakStrategy", sourceProps.textBreakStrategy, {})), - inlineImageLeft(CoreFeatures::enablePropIteratorSetter? sourceProps.inlineImageLeft : convertRawProp(context, rawProps, + inlineImageLeft(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.inlineImageLeft : convertRawProp(context, rawProps, "inlineImageLeft", sourceProps.inlineImageLeft, {})), - inlineImagePadding(CoreFeatures::enablePropIteratorSetter? sourceProps.inlineImagePadding : convertRawProp(context, rawProps, + inlineImagePadding(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.inlineImagePadding : convertRawProp(context, rawProps, "inlineImagePadding", sourceProps.inlineImagePadding, {0})), - importantForAutofill(CoreFeatures::enablePropIteratorSetter? sourceProps.importantForAutofill : convertRawProp(context, rawProps, + importantForAutofill(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.importantForAutofill : convertRawProp(context, rawProps, "importantForAutofill", sourceProps.importantForAutofill, {})), - showSoftInputOnFocus(CoreFeatures::enablePropIteratorSetter? sourceProps.showSoftInputOnFocus : convertRawProp(context, rawProps, + showSoftInputOnFocus(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.showSoftInputOnFocus : convertRawProp(context, rawProps, "showSoftInputOnFocus", sourceProps.showSoftInputOnFocus, {false})), - autoCorrect(CoreFeatures::enablePropIteratorSetter? sourceProps.autoCorrect : convertRawProp(context, rawProps, + autoCorrect(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.autoCorrect : convertRawProp(context, rawProps, "autoCorrect", sourceProps.autoCorrect, {false})), - allowFontScaling(CoreFeatures::enablePropIteratorSetter? sourceProps.allowFontScaling : convertRawProp(context, rawProps, + allowFontScaling(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.allowFontScaling : convertRawProp(context, rawProps, "allowFontScaling", sourceProps.allowFontScaling, {false})), - maxFontSizeMultiplier(CoreFeatures::enablePropIteratorSetter? sourceProps.maxFontSizeMultiplier : convertRawProp(context, rawProps, + maxFontSizeMultiplier(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.maxFontSizeMultiplier : convertRawProp(context, rawProps, "maxFontSizeMultiplier", sourceProps.maxFontSizeMultiplier, {0.0})), - keyboardType(CoreFeatures::enablePropIteratorSetter? sourceProps.keyboardType : convertRawProp(context, rawProps, + keyboardType(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.keyboardType : convertRawProp(context, rawProps, "keyboardType", sourceProps.keyboardType, {})), - returnKeyType(CoreFeatures::enablePropIteratorSetter? sourceProps.returnKeyType : convertRawProp(context, rawProps, + returnKeyType(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.returnKeyType : convertRawProp(context, rawProps, "returnKeyType", sourceProps.returnKeyType, {})), - multiline(CoreFeatures::enablePropIteratorSetter? sourceProps.multiline : convertRawProp(context, rawProps, + multiline(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.multiline : convertRawProp(context, rawProps, "multiline", sourceProps.multiline, {false})), - secureTextEntry(CoreFeatures::enablePropIteratorSetter? sourceProps.secureTextEntry : convertRawProp(context, rawProps, + secureTextEntry(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.secureTextEntry : convertRawProp(context, rawProps, "secureTextEntry", sourceProps.secureTextEntry, {false})), - value(CoreFeatures::enablePropIteratorSetter? sourceProps.value : convertRawProp(context, rawProps, "value", sourceProps.value, {})), - selectTextOnFocus(CoreFeatures::enablePropIteratorSetter? sourceProps.selectTextOnFocus : convertRawProp(context, rawProps, + value(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.value : convertRawProp(context, rawProps, "value", sourceProps.value, {})), + selectTextOnFocus(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.selectTextOnFocus : convertRawProp(context, rawProps, "selectTextOnFocus", sourceProps.selectTextOnFocus, {false})), - submitBehavior(CoreFeatures::enablePropIteratorSetter? sourceProps.submitBehavior : convertRawProp(context, rawProps, + submitBehavior(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.submitBehavior : convertRawProp(context, rawProps, "submitBehavior", sourceProps.submitBehavior, {})), - caretHidden(CoreFeatures::enablePropIteratorSetter? sourceProps.caretHidden : convertRawProp(context, rawProps, + caretHidden(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.caretHidden : convertRawProp(context, rawProps, "caretHidden", sourceProps.caretHidden, {false})), - contextMenuHidden(CoreFeatures::enablePropIteratorSetter? sourceProps.contextMenuHidden : convertRawProp(context, rawProps, + contextMenuHidden(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.contextMenuHidden : convertRawProp(context, rawProps, "contextMenuHidden", sourceProps.contextMenuHidden, {false})), - textShadowColor(CoreFeatures::enablePropIteratorSetter? sourceProps.textShadowColor : convertRawProp(context, rawProps, + textShadowColor(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textShadowColor : convertRawProp(context, rawProps, "textShadowColor", sourceProps.textShadowColor, {})), - textShadowRadius(CoreFeatures::enablePropIteratorSetter? sourceProps.textShadowRadius : convertRawProp(context, rawProps, + textShadowRadius(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textShadowRadius : convertRawProp(context, rawProps, "textShadowRadius", sourceProps.textShadowRadius, {0.0})), - textDecorationLine(CoreFeatures::enablePropIteratorSetter? sourceProps.textDecorationLine : convertRawProp(context, rawProps, + textDecorationLine(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textDecorationLine : convertRawProp(context, rawProps, "textDecorationLine", sourceProps.textDecorationLine, {})), - fontStyle(CoreFeatures::enablePropIteratorSetter? sourceProps.fontStyle : + fontStyle(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.fontStyle : convertRawProp(context, rawProps, "fontStyle", sourceProps.fontStyle, {})), - textShadowOffset(CoreFeatures::enablePropIteratorSetter? sourceProps.textShadowOffset : convertRawProp(context, rawProps, + textShadowOffset(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textShadowOffset : convertRawProp(context, rawProps, "textShadowOffset", sourceProps.textShadowOffset, {})), - lineHeight(CoreFeatures::enablePropIteratorSetter? sourceProps.lineHeight : convertRawProp(context, rawProps, + lineHeight(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.lineHeight : convertRawProp(context, rawProps, "lineHeight", sourceProps.lineHeight, {0.0})), - textTransform(CoreFeatures::enablePropIteratorSetter? sourceProps.textTransform : convertRawProp(context, rawProps, + textTransform(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textTransform : convertRawProp(context, rawProps, "textTransform", sourceProps.textTransform, {})), color(0 /*convertRawProp(context, rawProps, "color", sourceProps.color, {0})*/), - letterSpacing(CoreFeatures::enablePropIteratorSetter? sourceProps.letterSpacing : convertRawProp(context, rawProps, + letterSpacing(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.letterSpacing : convertRawProp(context, rawProps, "letterSpacing", sourceProps.letterSpacing, {0.0})), - fontSize(CoreFeatures::enablePropIteratorSetter? sourceProps.fontSize : + fontSize(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.fontSize : convertRawProp(context, rawProps, "fontSize", sourceProps.fontSize, {0.0})), - textAlign(CoreFeatures::enablePropIteratorSetter? sourceProps.textAlign : + textAlign(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textAlign : convertRawProp(context, rawProps, "textAlign", sourceProps.textAlign, {})), - includeFontPadding(CoreFeatures::enablePropIteratorSetter? sourceProps.includeFontPadding : convertRawProp(context, rawProps, + includeFontPadding(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.includeFontPadding : convertRawProp(context, rawProps, "includeFontPadding", sourceProps.includeFontPadding, {false})), - fontWeight(CoreFeatures::enablePropIteratorSetter? sourceProps.fontWeight : + fontWeight(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.fontWeight : convertRawProp(context, rawProps, "fontWeight", sourceProps.fontWeight, {})), - fontFamily(CoreFeatures::enablePropIteratorSetter? sourceProps.fontFamily : + fontFamily(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.fontFamily : convertRawProp(context, rawProps, "fontFamily", sourceProps.fontFamily, {})), // See AndroidTextInputComponentDescriptor for usage // TODO T63008435: can these, and this feature, be removed entirely? - hasPadding(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPadding : hasValue(rawProps, sourceProps.hasPadding, "padding")), - hasPaddingHorizontal(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingHorizontal : hasValue( + hasPadding(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPadding : hasValue(rawProps, sourceProps.hasPadding, "padding")), + hasPaddingHorizontal(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingHorizontal : hasValue( rawProps, sourceProps.hasPaddingHorizontal, "paddingHorizontal")), - hasPaddingVertical(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingVertical : hasValue( + hasPaddingVertical(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingVertical : hasValue( rawProps, sourceProps.hasPaddingVertical, "paddingVertical")), - hasPaddingLeft(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingLeft : hasValue( + hasPaddingLeft(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingLeft : hasValue( rawProps, sourceProps.hasPaddingLeft, "paddingLeft")), - hasPaddingTop(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingTop : + hasPaddingTop(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingTop : hasValue(rawProps, sourceProps.hasPaddingTop, "paddingTop")), - hasPaddingRight(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingRight : hasValue( + hasPaddingRight(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingRight : hasValue( rawProps, sourceProps.hasPaddingRight, "paddingRight")), - hasPaddingBottom(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingBottom : hasValue( + hasPaddingBottom(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingBottom : hasValue( rawProps, sourceProps.hasPaddingBottom, "paddingBottom")), - hasPaddingStart(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingStart : hasValue( + hasPaddingStart(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingStart : hasValue( rawProps, sourceProps.hasPaddingStart, "paddingStart")), - hasPaddingEnd(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingEnd : + hasPaddingEnd(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingEnd : hasValue(rawProps, sourceProps.hasPaddingEnd, "paddingEnd")) { } diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityProps.cpp index 56b4c335ad8860..e8062f7d6d4711 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityProps.cpp @@ -7,11 +7,11 @@ #include "AccessibilityProps.h" +#include #include #include #include #include -#include namespace facebook::react { @@ -20,15 +20,16 @@ AccessibilityProps::AccessibilityProps( const AccessibilityProps& sourceProps, const RawProps& rawProps) : accessible( - CoreFeatures::enablePropIteratorSetter ? sourceProps.accessible - : convertRawProp( - context, - rawProps, - "accessible", - sourceProps.accessible, - false)), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.accessible + : convertRawProp( + context, + rawProps, + "accessible", + sourceProps.accessible, + false)), accessibilityState( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityState : convertRawProp( context, @@ -37,7 +38,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityState, {})), accessibilityLabel( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityLabel : convertRawProp( context, @@ -46,7 +47,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityLabel, "")), accessibilityLabelledBy( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityLabelledBy : convertRawProp( context, @@ -55,7 +56,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityLabelledBy, {})), accessibilityLiveRegion( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityLiveRegion : convertRawProp( context, @@ -64,7 +65,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityLiveRegion, AccessibilityLiveRegion::None)), accessibilityHint( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityHint : convertRawProp( context, @@ -73,7 +74,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityHint, "")), accessibilityLanguage( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityLanguage : convertRawProp( context, @@ -82,7 +83,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityLanguage, "")), accessibilityLargeContentTitle( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityLargeContentTitle : convertRawProp( context, @@ -91,7 +92,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityLargeContentTitle, "")), accessibilityValue( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityValue : convertRawProp( context, @@ -100,7 +101,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityValue, {})), accessibilityActions( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityActions : convertRawProp( context, @@ -109,7 +110,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityActions, {})), accessibilityShowsLargeContentViewer( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityShowsLargeContentViewer : convertRawProp( context, @@ -118,7 +119,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityShowsLargeContentViewer, false)), accessibilityViewIsModal( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityViewIsModal : convertRawProp( context, @@ -127,7 +128,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityViewIsModal, false)), accessibilityElementsHidden( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityElementsHidden : convertRawProp( context, @@ -136,7 +137,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityElementsHidden, false)), accessibilityIgnoresInvertColors( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.accessibilityIgnoresInvertColors : convertRawProp( context, @@ -145,7 +146,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.accessibilityIgnoresInvertColors, false)), onAccessibilityTap( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.onAccessibilityTap : convertRawProp( context, @@ -154,7 +155,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.onAccessibilityTap, {})), onAccessibilityMagicTap( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.onAccessibilityMagicTap : convertRawProp( context, @@ -163,7 +164,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.onAccessibilityMagicTap, {})), onAccessibilityEscape( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.onAccessibilityEscape : convertRawProp( context, @@ -172,7 +173,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.onAccessibilityEscape, {})), onAccessibilityAction( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.onAccessibilityAction : convertRawProp( context, @@ -181,7 +182,7 @@ AccessibilityProps::AccessibilityProps( sourceProps.onAccessibilityAction, {})), importantForAccessibility( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.importantForAccessibility : convertRawProp( context, @@ -190,13 +191,14 @@ AccessibilityProps::AccessibilityProps( sourceProps.importantForAccessibility, ImportantForAccessibility::Auto)), testId( - CoreFeatures::enablePropIteratorSetter ? sourceProps.testId - : convertRawProp( - context, - rawProps, - "testID", - sourceProps.testId, - "")) { + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.testId + : convertRawProp( + context, + rawProps, + "testID", + sourceProps.testId, + "")) { // It is a (severe!) perf deoptimization to request props out-of-order. // Thus, since we need to request the same prop twice here // (accessibilityRole) we "must" do them subsequently here to prevent @@ -204,7 +206,7 @@ AccessibilityProps::AccessibilityProps( // it probably can, but this is a fairly rare edge-case that (1) is easy-ish // to work around here, and (2) would require very careful work to address // this case and not regress the more common cases. - if (!CoreFeatures::enablePropIteratorSetter) { + if (!ReactNativeFeatureFlags::enableCppPropsIteratorSetter()) { auto* accessibilityRoleValue = rawProps.at("accessibilityRole", nullptr, nullptr); auto* roleValue = rawProps.at("role", nullptr, nullptr); diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp index de2fffdd4439b9..4ecee2a7a71269 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -16,7 +17,6 @@ #include #include #include -#include namespace facebook::react { @@ -57,15 +57,16 @@ BaseViewProps::BaseViewProps( : YogaStylableProps(context, sourceProps, rawProps), AccessibilityProps(context, sourceProps, rawProps), opacity( - CoreFeatures::enablePropIteratorSetter ? sourceProps.opacity - : convertRawProp( - context, - rawProps, - "opacity", - sourceProps.opacity, - (Float)1.0)), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.opacity + : convertRawProp( + context, + rawProps, + "opacity", + sourceProps.opacity, + (Float)1.0)), backgroundColor( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.backgroundColor : convertRawProp( context, @@ -74,51 +75,56 @@ BaseViewProps::BaseViewProps( sourceProps.backgroundColor, {})), borderRadii( - CoreFeatures::enablePropIteratorSetter ? sourceProps.borderRadii - : convertRawProp( - context, - rawProps, - "border", - "Radius", - sourceProps.borderRadii, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.borderRadii + : convertRawProp( + context, + rawProps, + "border", + "Radius", + sourceProps.borderRadii, + {})), borderColors( - CoreFeatures::enablePropIteratorSetter ? sourceProps.borderColors - : convertRawProp( - context, - rawProps, - "border", - "Color", - sourceProps.borderColors, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.borderColors + : convertRawProp( + context, + rawProps, + "border", + "Color", + sourceProps.borderColors, + {})), borderCurves( - CoreFeatures::enablePropIteratorSetter ? sourceProps.borderCurves - : convertRawProp( - context, - rawProps, - "border", - "Curve", - sourceProps.borderCurves, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.borderCurves + : convertRawProp( + context, + rawProps, + "border", + "Curve", + sourceProps.borderCurves, + {})), borderStyles( - CoreFeatures::enablePropIteratorSetter ? sourceProps.borderStyles - : convertRawProp( - context, - rawProps, - "border", - "Style", - sourceProps.borderStyles, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.borderStyles + : convertRawProp( + context, + rawProps, + "border", + "Style", + sourceProps.borderStyles, + {})), outlineColor( - CoreFeatures::enablePropIteratorSetter ? sourceProps.outlineColor - : convertRawProp( - context, - rawProps, - "outlineColor", - sourceProps.outlineColor, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.outlineColor + : convertRawProp( + context, + rawProps, + "outlineColor", + sourceProps.outlineColor, + {})), outlineOffset( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.outlineOffset : convertRawProp( context, @@ -127,39 +133,43 @@ BaseViewProps::BaseViewProps( sourceProps.outlineOffset, {})), outlineStyle( - CoreFeatures::enablePropIteratorSetter ? sourceProps.outlineStyle - : convertRawProp( - context, - rawProps, - "outlineStyle", - sourceProps.outlineStyle, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.outlineStyle + : convertRawProp( + context, + rawProps, + "outlineStyle", + sourceProps.outlineStyle, + {})), outlineWidth( - CoreFeatures::enablePropIteratorSetter ? sourceProps.outlineWidth - : convertRawProp( - context, - rawProps, - "outlineWidth", - sourceProps.outlineWidth, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.outlineWidth + : convertRawProp( + context, + rawProps, + "outlineWidth", + sourceProps.outlineWidth, + {})), shadowColor( - CoreFeatures::enablePropIteratorSetter ? sourceProps.shadowColor - : convertRawProp( - context, - rawProps, - "shadowColor", - sourceProps.shadowColor, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.shadowColor + : convertRawProp( + context, + rawProps, + "shadowColor", + sourceProps.shadowColor, + {})), shadowOffset( - CoreFeatures::enablePropIteratorSetter ? sourceProps.shadowOffset - : convertRawProp( - context, - rawProps, - "shadowOffset", - sourceProps.shadowOffset, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.shadowOffset + : convertRawProp( + context, + rawProps, + "shadowOffset", + sourceProps.shadowOffset, + {})), shadowOpacity( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.shadowOpacity : convertRawProp( context, @@ -168,39 +178,43 @@ BaseViewProps::BaseViewProps( sourceProps.shadowOpacity, {})), shadowRadius( - CoreFeatures::enablePropIteratorSetter ? sourceProps.shadowRadius - : convertRawProp( - context, - rawProps, - "shadowRadius", - sourceProps.shadowRadius, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.shadowRadius + : convertRawProp( + context, + rawProps, + "shadowRadius", + sourceProps.shadowRadius, + {})), cursor( - CoreFeatures::enablePropIteratorSetter ? sourceProps.cursor - : convertRawProp( - context, - rawProps, - "cursor", - sourceProps.cursor, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.cursor + : convertRawProp( + context, + rawProps, + "cursor", + sourceProps.cursor, + {})), boxShadow( - CoreFeatures::enablePropIteratorSetter ? sourceProps.boxShadow - : convertRawProp( - context, - rawProps, - "boxShadow", - sourceProps.boxShadow, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.boxShadow + : convertRawProp( + context, + rawProps, + "boxShadow", + sourceProps.boxShadow, + {})), filter( - CoreFeatures::enablePropIteratorSetter ? sourceProps.filter - : convertRawProp( - context, - rawProps, - "filter", - sourceProps.filter, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.filter + : convertRawProp( + context, + rawProps, + "filter", + sourceProps.filter, + {})), backgroundImage( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.backgroundImage : convertRawProp( context, @@ -209,31 +223,34 @@ BaseViewProps::BaseViewProps( sourceProps.backgroundImage, {})), mixBlendMode( - CoreFeatures::enablePropIteratorSetter ? sourceProps.mixBlendMode - : convertRawProp( - context, - rawProps, - "mixBlendMode", - sourceProps.mixBlendMode, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.mixBlendMode + : convertRawProp( + context, + rawProps, + "mixBlendMode", + sourceProps.mixBlendMode, + {})), isolation( - CoreFeatures::enablePropIteratorSetter ? sourceProps.isolation - : convertRawProp( - context, - rawProps, - "isolation", - sourceProps.isolation, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.isolation + : convertRawProp( + context, + rawProps, + "isolation", + sourceProps.isolation, + {})), transform( - CoreFeatures::enablePropIteratorSetter ? sourceProps.transform - : convertRawProp( - context, - rawProps, - "transform", - sourceProps.transform, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.transform + : convertRawProp( + context, + rawProps, + "transform", + sourceProps.transform, + {})), transformOrigin( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.transformOrigin : convertRawProp( context, @@ -242,7 +259,7 @@ BaseViewProps::BaseViewProps( sourceProps.transformOrigin, {})), backfaceVisibility( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.backfaceVisibility : convertRawProp( context, @@ -251,7 +268,7 @@ BaseViewProps::BaseViewProps( sourceProps.backfaceVisibility, {})), shouldRasterize( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.shouldRasterize : convertRawProp( context, @@ -260,15 +277,16 @@ BaseViewProps::BaseViewProps( sourceProps.shouldRasterize, {})), zIndex( - CoreFeatures::enablePropIteratorSetter ? sourceProps.zIndex - : convertRawProp( - context, - rawProps, - "zIndex", - sourceProps.zIndex, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.zIndex + : convertRawProp( + context, + rawProps, + "zIndex", + sourceProps.zIndex, + {})), pointerEvents( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.pointerEvents : convertRawProp( context, @@ -277,35 +295,38 @@ BaseViewProps::BaseViewProps( sourceProps.pointerEvents, {})), hitSlop( - CoreFeatures::enablePropIteratorSetter ? sourceProps.hitSlop - : convertRawProp( - context, - rawProps, - "hitSlop", - sourceProps.hitSlop, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.hitSlop + : convertRawProp( + context, + rawProps, + "hitSlop", + sourceProps.hitSlop, + {})), onLayout( - CoreFeatures::enablePropIteratorSetter ? sourceProps.onLayout - : convertRawProp( - context, - rawProps, - "onLayout", - sourceProps.onLayout, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.onLayout + : convertRawProp( + context, + rawProps, + "onLayout", + sourceProps.onLayout, + {})), events( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.events : convertRawProp(context, rawProps, sourceProps.events, {})), collapsable( - CoreFeatures::enablePropIteratorSetter ? sourceProps.collapsable - : convertRawProp( - context, - rawProps, - "collapsable", - sourceProps.collapsable, - true)), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.collapsable + : convertRawProp( + context, + rawProps, + "collapsable", + sourceProps.collapsable, + true)), collapsableChildren( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.collapsableChildren : convertRawProp( context, @@ -314,7 +335,7 @@ BaseViewProps::BaseViewProps( sourceProps.collapsableChildren, true)), removeClippedSubviews( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.removeClippedSubviews : convertRawProp( context, @@ -323,7 +344,7 @@ BaseViewProps::BaseViewProps( sourceProps.removeClippedSubviews, false)), experimental_layoutConformance( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.experimental_layoutConformance : convertRawProp( context, diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/ViewShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/ViewShadowNode.cpp index 7e819c28e997fb..fab1969985d49c 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/ViewShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/ViewShadowNode.cpp @@ -9,7 +9,6 @@ #include #include #include -#include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp index c57292dfbc54a5..a6c9b8538dd53f 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -388,6 +387,12 @@ void YogaLayoutableShadowNode::updateYogaProps() { !viewProps.filter.empty(); YGNodeSetAlwaysFormsContainingBlock(&yogaNode_, alwaysFormsContainingBlock); } + + if (yogaNode_.style().display() == yoga::Display::Contents) { + ShadowNode::traits_.set(ShadowNodeTraits::ForceFlattenView); + } else { + ShadowNode::traits_.unset(ShadowNodeTraits::ForceFlattenView); + } } /*static*/ yoga::Style YogaLayoutableShadowNode::applyAliasedProps( @@ -780,7 +785,7 @@ Rect YogaLayoutableShadowNode::getContentBounds() const { } /*static*/ void YogaLayoutableShadowNode::filterRawProps(RawProps& rawProps) { - if (CoreFeatures::excludeYogaFromRawProps) { + if (ReactNativeFeatureFlags::excludeYogaFromRawProps()) { // TODO: this shouldn't live in RawProps rawProps.filterYogaStylePropsInDynamicConversion(); } diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp index 4f36bf6bb813e1..9277715e8e414e 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h index 35f6047c318c22..58e04bba088aae 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h @@ -119,6 +119,17 @@ static inline PositionType positionTypeFromYogaPositionType( } } +inline DisplayType displayTypeFromYGDisplay(YGDisplay display) { + switch (display) { + case YGDisplayNone: + return DisplayType::None; + case YGDisplayContents: + return DisplayType::Contents; + case YGDisplayFlex: + return DisplayType::Flex; + } +} + inline LayoutMetrics layoutMetricsFromYogaNode(yoga::Node& yogaNode) { auto layoutMetrics = LayoutMetrics{}; @@ -146,9 +157,8 @@ inline LayoutMetrics layoutMetricsFromYogaNode(yoga::Node& yogaNode) { layoutMetrics.borderWidth.bottom + floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeBottom))}; - layoutMetrics.displayType = yogaNode.style().display() == yoga::Display::None - ? DisplayType::None - : DisplayType::Flex; + layoutMetrics.displayType = + displayTypeFromYGDisplay(YGNodeStyleGetDisplay(&yogaNode)); layoutMetrics.positionType = positionTypeFromYogaPositionType(yogaNode.style().positionType()); @@ -429,6 +439,10 @@ inline void fromRawValue( result = yoga::Display::None; return; } + if (stringValue == "contents") { + result = yoga::Display::Contents; + return; + } LOG(ERROR) << "Could not parse yoga::Display: " << stringValue; } diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp index 021268bfdac650..737a09a1eca26f 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp @@ -9,11 +9,11 @@ #include +#include #include #include #include #include -#include namespace facebook::react { @@ -23,15 +23,16 @@ HostPlatformViewProps::HostPlatformViewProps( const RawProps& rawProps) : BaseViewProps(context, sourceProps, rawProps), elevation( - CoreFeatures::enablePropIteratorSetter ? sourceProps.elevation - : convertRawProp( - context, - rawProps, - "elevation", - sourceProps.elevation, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.elevation + : convertRawProp( + context, + rawProps, + "elevation", + sourceProps.elevation, + {})), nativeBackground( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.nativeBackground : convertRawProp( context, @@ -40,7 +41,7 @@ HostPlatformViewProps::HostPlatformViewProps( sourceProps.nativeBackground, {})), nativeForeground( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.nativeForeground : convertRawProp( context, @@ -49,15 +50,16 @@ HostPlatformViewProps::HostPlatformViewProps( sourceProps.nativeForeground, {})), focusable( - CoreFeatures::enablePropIteratorSetter ? sourceProps.focusable - : convertRawProp( - context, - rawProps, - "focusable", - sourceProps.focusable, - {})), + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.focusable + : convertRawProp( + context, + rawProps, + "focusable", + sourceProps.focusable, + {})), hasTVPreferredFocus( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.hasTVPreferredFocus : convertRawProp( context, @@ -66,7 +68,7 @@ HostPlatformViewProps::HostPlatformViewProps( sourceProps.hasTVPreferredFocus, {})), needsOffscreenAlphaCompositing( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.needsOffscreenAlphaCompositing : convertRawProp( context, @@ -75,7 +77,7 @@ HostPlatformViewProps::HostPlatformViewProps( sourceProps.needsOffscreenAlphaCompositing, {})), renderToHardwareTextureAndroid( - CoreFeatures::enablePropIteratorSetter + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.renderToHardwareTextureAndroid : convertRawProp( context, diff --git a/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h b/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h index 54056606cbe756..309584dabe2e23 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h +++ b/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -19,7 +20,6 @@ #include #include #include -#include namespace facebook::react { @@ -115,7 +115,7 @@ class ConcreteComponentDescriptor : public ComponentDescriptor { // Use the new-style iterator // Note that we just check if `Props` has this flag set, no matter // the type of ShadowNode; it acts as the single global flag. - if (CoreFeatures::enablePropIteratorSetter) { + if (ReactNativeFeatureFlags::enableCppPropsIteratorSetter()) { auto shadowNodeProps = ShadowNodeT::Props(context, rawProps, props); #ifdef ANDROID const auto& dynamic = shadowNodeProps->rawProps; diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp index 17262807c0fe59..2afbbfd52145f1 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp @@ -11,19 +11,39 @@ namespace facebook::react { -EventBeat::EventBeat(SharedOwnerBox ownerBox) - : ownerBox_(std::move(ownerBox)) {} +EventBeat::EventBeat( + std::shared_ptr ownerBox, + RuntimeExecutor runtimeExecutor) + : ownerBox_(std::move(ownerBox)), + runtimeExecutor_(std::move(runtimeExecutor)) {} void EventBeat::request() const { isRequested_ = true; } -void EventBeat::induce() const { - // Default implementation does nothing. -} - void EventBeat::setBeatCallback(BeatCallback beatCallback) { beatCallback_ = std::move(beatCallback); } +void EventBeat::induce() const { + if (!isRequested_ || isBeatCallbackScheduled_) { + return; + } + + isRequested_ = false; + isBeatCallbackScheduled_ = true; + + runtimeExecutor_([this, ownerBox = ownerBox_](jsi::Runtime& runtime) { + auto owner = ownerBox->owner.lock(); + if (!owner) { + return; + } + + isBeatCallbackScheduled_ = false; + if (beatCallback_) { + beatCallback_(runtime); + } + }); +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h index 2a13a4af44e167..6a3692737df9a6 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -19,39 +20,50 @@ namespace facebook::react { /* * Event Beat serves two interleaving purposes: synchronization of event queues * and ensuring that event dispatching happens on proper threads. + * + * EventBeat is meant to be subclassed by platform-specific implementations. + * The platform-specific implementation must call EventBeat::induce(). The + * appropriate time to call induce is when the host platform events were queued + * in the EventQueue for a given UI frame. For example, on iOS, + * EventBeat::induce() is called before the main run loop goes to sleep. On + * Android, EventBeat::induce() is called from Android's Choreographer. */ class EventBeat { public: /* * The concept of `Owner` * The purpose of `EventBeat` is handling an asynchronous callback to itself - * which is being delivered on some different thread. That brings a challenge + * which is being delivered on a different thread. That brings a challenge * of ensuring that the `EventBeat` object stays valid during the timeframe of * callback execution. The concept of Owner helps with that. The owner is a * shared pointer that retains (probably indirectly) the `EventBeat` object. * To ensure the correctness of the call, `EventBeat` retains the owner - * (practically creating a retain cycle) during executing the callback. In - * case if the pointer to the owner already null, `EventBeat` skips executing - * the callback. It's impossible to retain itself directly or refer to the - * shared pointer to itself from a constructor. `OwnerBox` is designed to work - * around this issue; it allows to store the pointer later, right after the - * creation of some other object that owns an `EventBeat`. + * weakly during executing the callback. If the pointer to the owner is + * already null, `EventBeat` skips executing the callback. It's impossible to + * retain itself directly or refer to the shared pointer to itself from a + * constructor. `OwnerBox` is designed to work around this issue; it can + * store the pointer after the creation of some other object that + * owns an `EventBeat`. */ - using Owner = std::weak_ptr; struct OwnerBox { - Owner owner; + std::weak_ptr owner; }; - using SharedOwnerBox = std::shared_ptr; - using Factory = - std::function(const SharedOwnerBox& ownerBox)>; + using Factory = std::function( + std::shared_ptr ownerBox)>; using BeatCallback = std::function; - EventBeat(SharedOwnerBox ownerBox); + explicit EventBeat( + std::shared_ptr ownerBox, + RuntimeExecutor runtimeExecutor); virtual ~EventBeat() = default; + // not copyable + EventBeat(const EventBeat& other) = delete; + EventBeat& operator=(const EventBeat& other) = delete; + /* * Communicates to the Beat that a consumer is waiting for the coming beat. * A consumer must request coming beat after the previous beat happened @@ -60,7 +72,6 @@ class EventBeat { virtual void request() const; /* - * Sets the beat callback function. * The callback is must be called on the proper thread. */ void setBeatCallback(BeatCallback beatCallback); @@ -70,11 +81,15 @@ class EventBeat { * Induces the next beat to happen as soon as possible. * Receiver might ignore the call if a beat was not requested. */ - virtual void induce() const; + void induce() const; BeatCallback beatCallback_; - SharedOwnerBox ownerBox_; + std::shared_ptr ownerBox_; mutable std::atomic isRequested_{false}; + + private: + RuntimeExecutor runtimeExecutor_; + mutable std::atomic isBeatCallbackScheduled_{false}; }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp index daf4edc10777e6..10d6d0b46590a8 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp @@ -17,15 +17,12 @@ namespace facebook::react { EventDispatcher::EventDispatcher( const EventQueueProcessor& eventProcessor, - const EventBeat::Factory& asynchronousEventBeatFactory, - const EventBeat::SharedOwnerBox& ownerBox, + std::unique_ptr eventBeat, RuntimeScheduler& runtimeScheduler, StatePipe statePipe, std::weak_ptr eventLogger) - : eventQueue_(EventQueue( - eventProcessor, - asynchronousEventBeatFactory(ownerBox), - runtimeScheduler)), + : eventQueue_( + EventQueue(eventProcessor, std::move(eventBeat), runtimeScheduler)), statePipe_(std::move(statePipe)), eventLogger_(std::move(eventLogger)) {} diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h index 36e4d03c6d9e6a..79eab45e12009c 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h @@ -32,8 +32,7 @@ class EventDispatcher { EventDispatcher( const EventQueueProcessor& eventProcessor, - const EventBeat::Factory& asynchronousEventBeatFactory, - const EventBeat::SharedOwnerBox& ownerBox, + std::unique_ptr eventBeat, RuntimeScheduler& runtimeScheduler, StatePipe statePipe, std::weak_ptr eventLogger); diff --git a/packages/react-native/ReactCommon/react/renderer/core/LayoutPrimitives.h b/packages/react-native/ReactCommon/react/renderer/core/LayoutPrimitives.h index bbe6e5484586e7..d2e50ff7355335 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/LayoutPrimitives.h +++ b/packages/react-native/ReactCommon/react/renderer/core/LayoutPrimitives.h @@ -19,7 +19,7 @@ namespace facebook::react { enum class DisplayType { None = 0, Flex = 1, - Inline = 2, + Contents = 2, }; enum class PositionType { diff --git a/packages/react-native/ReactCommon/react/renderer/core/Props.cpp b/packages/react-native/ReactCommon/react/renderer/core/Props.cpp index df133e8078e501..2e494ba7d2fc43 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/Props.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/Props.cpp @@ -9,7 +9,8 @@ #include #include -#include + +#include namespace facebook::react { @@ -24,7 +25,7 @@ void Props::initialize( const PropsParserContext& context, const Props& sourceProps, const RawProps& rawProps) { - nativeId = CoreFeatures::enablePropIteratorSetter + nativeId = ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.nativeId : convertRawProp(context, rawProps, "nativeID", sourceProps.nativeId, {}); #ifdef ANDROID diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h b/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h index 926a97cae6012c..841a3d7e3a7fe5 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h @@ -75,6 +75,9 @@ class ShadowNodeTraits { // Inherits `YogaLayoutableShadowNode` and has a custom baseline function. BaselineYogaNode = 1 << 10, + + // Forces the node not to form a host view. + ForceFlattenView = 1 << 11, }; /* diff --git a/packages/react-native/ReactCommon/react/renderer/core/conversions.h b/packages/react-native/ReactCommon/react/renderer/core/conversions.h index a11c2120fd4851..f778974811c297 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/core/conversions.h @@ -39,7 +39,7 @@ inline int toInt(const DisplayType& displayType) { return 0; case DisplayType::Flex: return 1; - case DisplayType::Inline: + case DisplayType::Contents: return 2; } } @@ -50,8 +50,8 @@ inline std::string toString(const DisplayType& displayType) { return "none"; case DisplayType::Flex: return "flex"; - case DisplayType::Inline: - return "inline"; + case DisplayType::Contents: + return "contents"; } } diff --git a/packages/react-native/ReactCommon/react/renderer/debug/React-rendererdebug.podspec b/packages/react-native/ReactCommon/react/renderer/debug/React-rendererdebug.podspec index ab0fa4e44c648f..52dc39c8740824 100644 --- a/packages/react-native/ReactCommon/react/renderer/debug/React-rendererdebug.podspec +++ b/packages/react-native/ReactCommon/react/renderer/debug/React-rendererdebug.podspec @@ -24,6 +24,7 @@ header_search_paths = [ "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"" ] @@ -57,6 +58,7 @@ Pod::Spec.new do |s| s.dependency "RCT-Folly", folly_version s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" add_dependency(s, "React-debug") end diff --git a/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp b/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp index 37d784cade03c3..6748efa540d949 100644 --- a/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp +++ b/packages/react-native/ReactCommon/react/renderer/dom/DOM.cpp @@ -380,8 +380,7 @@ DOMSizeRounded getScrollSize( *shadowNodeInCurrentRevision, {.includeTransform = false}); - if (layoutMetrics == EmptyLayoutMetrics || - layoutMetrics.displayType == DisplayType::Inline) { + if (layoutMetrics == EmptyLayoutMetrics) { return DOMSizeRounded{}; } @@ -417,8 +416,7 @@ DOMSizeRounded getInnerSize( *shadowNodeInCurrentRevision, {.includeTransform = false}); - if (layoutMetrics == EmptyLayoutMetrics || - layoutMetrics.displayType == DisplayType::Inline) { + if (layoutMetrics == EmptyLayoutMetrics) { return DOMSizeRounded{}; } @@ -445,8 +443,7 @@ DOMBorderWidthRounded getBorderWidth( *shadowNodeInCurrentRevision, {.includeTransform = false}); - if (layoutMetrics == EmptyLayoutMetrics || - layoutMetrics.displayType == DisplayType::Inline) { + if (layoutMetrics == EmptyLayoutMetrics) { return DOMBorderWidthRounded{}; } diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec b/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec index 4a697a4f4cc6e9..9548d69c19e807 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec +++ b/packages/react-native/ReactCommon/react/renderer/graphics/React-graphics.podspec @@ -21,7 +21,7 @@ folly_compiler_flags = folly_config[:compiler_flags] folly_version = folly_config[:version] boost_config = get_boost_config() -boost_compiler_flags = boost_config[:compiler_flags] +boost_compiler_flags = boost_config[:compiler_flags] Pod::Spec.new do |s| source_files = "**/*.{m,mm,cpp,h}" @@ -30,6 +30,7 @@ Pod::Spec.new do |s| "\"$(PODS_TARGET_SRCROOT)/../../../\"", "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"" ] @@ -67,5 +68,6 @@ Pod::Spec.new do |s| s.dependency "React-jsiexecutor" s.dependency "React-utils" s.dependency "DoubleConversion" - s.dependency "fmt", "9.1.0" + s.dependency "fast_float", "6.1.4" + s.dependency "fmt", "11.0.2" end diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/React-ImageManager.podspec b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/React-ImageManager.podspec index 377aa902a47128..d4d14d52251854 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/React-ImageManager.podspec +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/React-ImageManager.podspec @@ -29,6 +29,7 @@ Pod::Spec.new do |s| "\"$(PODS_TARGET_SRCROOT)\"", "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"", ].join(" ") diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp index caa55984462579..fc14dfdc540ce3 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.cpp @@ -245,13 +245,17 @@ static void sliceChildShadowNodeViewPairsRecursively( // shuffling their children around. bool childrenFormStackingContexts = shadowNode.getTraits().check( ShadowNodeTraits::Trait::ChildrenFormStackingContext); - bool isConcreteView = - childShadowNode.getTraits().check(ShadowNodeTraits::Trait::FormsView) || - childrenFormStackingContexts; - bool areChildrenFlattened = + bool isConcreteView = (childShadowNode.getTraits().check( + ShadowNodeTraits::Trait::FormsView) || + childrenFormStackingContexts) && !childShadowNode.getTraits().check( - ShadowNodeTraits::Trait::FormsStackingContext) && - !childrenFormStackingContexts; + ShadowNodeTraits::Trait::ForceFlattenView); + bool areChildrenFlattened = + (!childShadowNode.getTraits().check( + ShadowNodeTraits::Trait::FormsStackingContext) && + !childrenFormStackingContexts) || + childShadowNode.getTraits().check( + ShadowNodeTraits::Trait::ForceFlattenView); Point storedOrigin = {}; if (areChildrenFlattened) { diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/MountingCoordinator.h b/packages/react-native/ReactCommon/react/renderer/mounting/MountingCoordinator.h index 179f1e0ca654c2..4042a446ad9664 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/MountingCoordinator.h +++ b/packages/react-native/ReactCommon/react/renderer/mounting/MountingCoordinator.h @@ -33,8 +33,6 @@ namespace facebook::react { */ class MountingCoordinator final { public: - using Shared = std::shared_ptr; - /* * The constructor is meant to be used only inside `ShadowTree`, and it's * `public` only to enable using with `std::make_shared<>`. diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp index 3a674a4ef42a00..09c67c66b573e9 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp @@ -231,7 +231,8 @@ CommitMode ShadowTree::getCommitMode() const { return commitMode_; } -MountingCoordinator::Shared ShadowTree::getMountingCoordinator() const { +std::shared_ptr ShadowTree::getMountingCoordinator() + const { return mountingCoordinator_; } @@ -278,8 +279,7 @@ CommitStatus ShadowTree::tryCommit( const auto& oldRootShadowNode = oldRevision.rootShadowNode; auto newRootShadowNode = transaction(*oldRevision.rootShadowNode); - if (!newRootShadowNode || - (commitOptions.shouldYield && commitOptions.shouldYield())) { + if (!newRootShadowNode) { return CommitStatus::Cancelled; } @@ -296,8 +296,7 @@ CommitStatus ShadowTree::tryCommit( newRootShadowNode = delegate_.shadowTreeWillCommit( *this, oldRootShadowNode, newRootShadowNode); - if (!newRootShadowNode || - (commitOptions.shouldYield && commitOptions.shouldYield())) { + if (!newRootShadowNode) { return CommitStatus::Cancelled; } @@ -315,10 +314,6 @@ CommitStatus ShadowTree::tryCommit( // Updating `currentRevision_` in unique manner if it hasn't changed. std::unique_lock lock(commitMutex_); - if (commitOptions.shouldYield && commitOptions.shouldYield()) { - return CommitStatus::Cancelled; - } - if (ReactNativeFeatureFlags:: enableGranularShadowTreeStateReconciliation()) { auto lastRevisionNumberWithNewStateChanged = diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h index a24d55eff830d3..b7b813ffd2d537 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h +++ b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h @@ -66,10 +66,6 @@ class ShadowTree final { // will then let React run layout effects and apply updates before paint. // For all other commits, should be true. bool mountSynchronously{true}; - - // Called during `tryCommit` phase. Returning true indicates current commit - // should yield to the next commit. - std::function shouldYield; }; /* @@ -130,7 +126,7 @@ class ShadowTree final { */ void notifyDelegatesOfUpdates() const; - MountingCoordinator::Shared getMountingCoordinator() const; + std::shared_ptr getMountingCoordinator() const; private: constexpr static ShadowTreeRevision::Number INITIAL_REVISION{0}; @@ -148,7 +144,7 @@ class ShadowTree final { mutable ShadowTreeRevision currentRevision_; // Protected by `commitMutex_`. mutable ShadowTreeRevision::Number lastRevisionNumberWithNewState_; // Protected by `commitMutex_`. - MountingCoordinator::Shared mountingCoordinator_; + std::shared_ptr mountingCoordinator_; }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTreeDelegate.h b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTreeDelegate.h index a260c5f1c292ff..dbb0fecfc92c2e 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTreeDelegate.h +++ b/packages/react-native/ReactCommon/react/renderer/mounting/ShadowTreeDelegate.h @@ -33,7 +33,7 @@ class ShadowTreeDelegate { * Called right after Shadow Tree commit a new state of the tree. */ virtual void shadowTreeDidFinishTransaction( - MountingCoordinator::Shared mountingCoordinator, + std::shared_ptr mountingCoordinator, bool mountSynchronously) const = 0; virtual ~ShadowTreeDelegate() noexcept = default; diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/tests/StateReconciliationTest.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/tests/StateReconciliationTest.cpp index f1c44381f45b6f..0a685ede067cd8 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/tests/StateReconciliationTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/tests/StateReconciliationTest.cpp @@ -34,7 +34,7 @@ class DummyShadowTreeDelegate : public ShadowTreeDelegate { }; void shadowTreeDidFinishTransaction( - MountingCoordinator::Shared mountingCoordinator, + std::shared_ptr mountingCoordinator, bool mountSynchronously) const override {}; }; diff --git a/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.cpp b/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.cpp index 7c0bf6e813c7d7..73184777507880 100644 --- a/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.cpp +++ b/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.cpp @@ -9,7 +9,6 @@ #include #include -#include #include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserverManager.cpp b/packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserverManager.cpp index 6a9e7f87cd72fe..d9cc6a3103df90 100644 --- a/packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserverManager.cpp +++ b/packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserverManager.cpp @@ -43,7 +43,7 @@ void IntersectionObserverManager::observe( // (like on the Web) and we'd send the initial notification there, but as // we don't have it we have to run this check once and manually dispatch. auto& shadowTreeRegistry = uiManager.getShadowTreeRegistry(); - MountingCoordinator::Shared mountingCoordinator = nullptr; + std::shared_ptr mountingCoordinator = nullptr; RootShadowNode::Shared rootShadowNode = nullptr; shadowTreeRegistry.visit(surfaceId, [&](const ShadowTree& shadowTree) { mountingCoordinator = shadowTree.getMountingCoordinator(); diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp index aca04466179e4b..e889cee86df5e5 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp @@ -22,7 +22,8 @@ std::unique_ptr getRuntimeSchedulerImplementation( RuntimeExecutor runtimeExecutor, std::function now, RuntimeSchedulerTaskErrorHandler onTaskError) { - if (ReactNativeFeatureFlags::useModernRuntimeScheduler()) { + if (ReactNativeFeatureFlags::enableBridgelessArchitecture() && + !ReactNativeFeatureFlags::disableEventLoopOnBridgeless()) { return std::make_unique( std::move(runtimeExecutor), std::move(now), std::move(onTaskError)); } else { diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp index 97933129b0ea6c..0a05dd76b33b4a 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp @@ -195,13 +195,7 @@ void RuntimeScheduler_Modern::executeNowOnTheSameThread( } void RuntimeScheduler_Modern::callExpiredTasks(jsi::Runtime& runtime) { - // If we have first-class support for microtasks, this a no-op. - if (ReactNativeFeatureFlags::enableMicrotasks()) { - return; - } - - SystraceSection s("RuntimeScheduler::callExpiredTasks"); - runEventLoop(runtime, true); + // No-op in the event loop implementation. } void RuntimeScheduler_Modern::scheduleRenderingUpdate( @@ -209,14 +203,8 @@ void RuntimeScheduler_Modern::scheduleRenderingUpdate( RuntimeSchedulerRenderingUpdate&& renderingUpdate) { SystraceSection s("RuntimeScheduler::scheduleRenderingUpdate"); - if (ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop()) { - surfaceIdsWithPendingRenderingUpdates_.insert(surfaceId); - pendingRenderingUpdates_.push(renderingUpdate); - } else { - if (renderingUpdate != nullptr) { - renderingUpdate(); - } - } + surfaceIdsWithPendingRenderingUpdates_.insert(surfaceId); + pendingRenderingUpdates_.push(renderingUpdate); } void RuntimeScheduler_Modern::setShadowTreeRevisionConsistencyManager( @@ -337,10 +325,8 @@ void RuntimeScheduler_Modern::runEventLoopTick( auto didUserCallbackTimeout = task.expirationTime <= taskStartTime; executeTask(runtime, task, didUserCallbackTimeout); - if (ReactNativeFeatureFlags::enableMicrotasks()) { - // "Perform a microtask checkpoint" step. - performMicrotaskCheckpoint(runtime); - } + // "Perform a microtask checkpoint" step. + performMicrotaskCheckpoint(runtime); if (ReactNativeFeatureFlags::enableLongTaskAPI()) { auto taskEndTime = now_(); @@ -348,10 +334,8 @@ void RuntimeScheduler_Modern::runEventLoopTick( reportLongTasks(task, taskStartTime, taskEndTime); } - if (ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop()) { - // "Update the rendering" step. - updateRendering(); - } + // "Update the rendering" step. + updateRendering(); currentTask_ = nullptr; } diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/primitives.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/primitives.h index 1531a99aa472fc..85cfd7f16792b1 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/primitives.h @@ -9,7 +9,6 @@ #include #include -#include namespace facebook::react { diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp index 2dc9a8b1276914..bc8be4d44e30ee 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp @@ -28,19 +28,11 @@ static bool forcedBatchRenderingUpdatesInEventLoop = false; class RuntimeSchedulerTestFeatureFlags : public ReactNativeFeatureFlagsDefaults { public: - RuntimeSchedulerTestFeatureFlags(bool useModernRuntimeScheduler) - : useModernRuntimeScheduler_(useModernRuntimeScheduler) {} + explicit RuntimeSchedulerTestFeatureFlags(bool enableEventLoop) + : enableEventLoop_(enableEventLoop) {} - bool useModernRuntimeScheduler() override { - return useModernRuntimeScheduler_; - } - - bool enableMicrotasks() override { - return useModernRuntimeScheduler_; - } - - bool batchRenderingUpdatesInEventLoop() override { - return forcedBatchRenderingUpdatesInEventLoop; + bool enableBridgelessArchitecture() override { + return enableEventLoop_; } bool enableLongTaskAPI() override { @@ -48,7 +40,7 @@ class RuntimeSchedulerTestFeatureFlags } private: - bool useModernRuntimeScheduler_; + bool enableEventLoop_; }; class RuntimeSchedulerTest : public testing::TestWithParam { @@ -162,21 +154,10 @@ TEST_P(RuntimeSchedulerTest, scheduleSingleTask) { EXPECT_EQ(stubQueue_->size(), 0); } -TEST_P(RuntimeSchedulerTest, scheduleNonBatchedRenderingUpdate) { - forcedBatchRenderingUpdatesInEventLoop = false; - - bool didRunRenderingUpdate = false; - - runtimeScheduler_->scheduleRenderingUpdate( - 0, [&]() { didRunRenderingUpdate = true; }); - - EXPECT_TRUE(didRunRenderingUpdate); -} - TEST_P( RuntimeSchedulerTest, scheduleSingleTaskWithMicrotasksAndBatchedRenderingUpdate) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -616,7 +597,7 @@ TEST_P(RuntimeSchedulerTest, immediateTaskDoesntYieldToPlatformEvent) { } TEST_P(RuntimeSchedulerTest, scheduleTaskWithYielding) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -640,7 +621,7 @@ TEST_P(RuntimeSchedulerTest, scheduleTaskWithYielding) { } TEST_P(RuntimeSchedulerTest, normalTaskYieldsToSynchronousAccess) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -709,7 +690,7 @@ TEST_P(RuntimeSchedulerTest, normalTaskYieldsToSynchronousAccess) { } TEST_P(RuntimeSchedulerTest, normalTaskYieldsToSynchronousAccessAndResumes) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -766,7 +747,7 @@ TEST_P(RuntimeSchedulerTest, normalTaskYieldsToSynchronousAccessAndResumes) { } TEST_P(RuntimeSchedulerTest, immediateTaskYieldsToSynchronousAccess) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -1090,7 +1071,7 @@ TEST_P(RuntimeSchedulerTest, legacyTwoThreadsRequestAccessToTheRuntime) { } TEST_P(RuntimeSchedulerTest, modernTwoThreadsRequestAccessToTheRuntime) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -1173,7 +1154,7 @@ TEST_P(RuntimeSchedulerTest, modernTwoThreadsRequestAccessToTheRuntime) { } TEST_P(RuntimeSchedulerTest, errorInTaskShouldNotStopMicrotasks) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -1219,7 +1200,7 @@ TEST_P(RuntimeSchedulerTest, errorInTaskShouldNotStopMicrotasks) { } TEST_P(RuntimeSchedulerTest, reportsLongTasks) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -1271,7 +1252,7 @@ TEST_P(RuntimeSchedulerTest, reportsLongTasks) { } TEST_P(RuntimeSchedulerTest, reportsLongTasksWithYielding) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp deleted file mode 100644 index 30ab47eea4249f..00000000000000 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 "AsynchronousEventBeat.h" - -#include - -namespace facebook::react { - -AsynchronousEventBeat::AsynchronousEventBeat( - RunLoopObserver::Unique uiRunLoopObserver, - RuntimeExecutor runtimeExecutor) - : EventBeat({}), - uiRunLoopObserver_(std::move(uiRunLoopObserver)), - runtimeExecutor_(std::move(runtimeExecutor)) { - uiRunLoopObserver_->setDelegate(this); - uiRunLoopObserver_->enable(); -} - -void AsynchronousEventBeat::activityDidChange( - const RunLoopObserver::Delegate* delegate, - RunLoopObserver::Activity /*activity*/) const noexcept { - react_native_assert(delegate == this); - induce(); -} - -void AsynchronousEventBeat::induce() const { - if (!isRequested_ || isBeatCallbackScheduled_) { - return; - } - - isRequested_ = false; - - // Here we know that `this` object exists because the caller has a strong - // pointer to `owner`. To ensure the object will exist inside - // `runtimeExecutor_` callback, we need to copy the pointer there. - auto weakOwner = uiRunLoopObserver_->getOwner(); - - isBeatCallbackScheduled_ = true; - - runtimeExecutor_([this, weakOwner](jsi::Runtime& runtime) { - auto owner = weakOwner.lock(); - if (!owner) { - return; - } - - isBeatCallbackScheduled_ = false; - if (beatCallback_) { - beatCallback_(runtime); - } - }); -} -} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp index 4b69f2f2b0495f..f5f37c91792def 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp @@ -93,13 +93,14 @@ Scheduler::Scheduler( uiManager->updateState(stateUpdate); }; + auto eventBeat = schedulerToolbox.eventBeatFactory(std::move(eventOwnerBox)); + // Creating an `EventDispatcher` instance inside the already allocated // container (inside the optional). eventDispatcher_->emplace( EventQueueProcessor( eventPipe, eventPipeConclusion, statePipe, eventPerformanceLogger_), - schedulerToolbox.asynchronousEventBeatFactory, - eventOwnerBox, + std::move(eventBeat), *runtimeScheduler, statePipe, eventPerformanceLogger_); @@ -283,7 +284,7 @@ void Scheduler::animationTick() const { #pragma mark - UIManagerDelegate void Scheduler::uiManagerDidFinishTransaction( - MountingCoordinator::Shared mountingCoordinator, + std::shared_ptr mountingCoordinator, bool mountSynchronously) { SystraceSection s("Scheduler::uiManagerDidFinishTransaction"); diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h index 3977cbc2467957..0fb2394f8e4ff2 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h @@ -85,7 +85,7 @@ class Scheduler final : public UIManagerDelegate { #pragma mark - UIManagerDelegate void uiManagerDidFinishTransaction( - MountingCoordinator::Shared mountingCoordinator, + std::shared_ptr mountingCoordinator, bool mountSynchronously) override; void uiManagerDidCreateShadowNode(const ShadowNode& shadowNode) override; void uiManagerDidDispatchCommand( diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h b/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h index e29ed8f465a54b..1f84bd582c2215 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h @@ -26,7 +26,8 @@ class SchedulerDelegate { * to construct a new one. */ virtual void schedulerDidFinishTransaction( - const MountingCoordinator::Shared& mountingCoordinator) = 0; + const std::shared_ptr& + mountingCoordinator) = 0; /* * Called when the runtime scheduler decides that one-or-more previously @@ -37,7 +38,8 @@ class SchedulerDelegate { * correctly apply changes, due to changes in Props representation. */ virtual void schedulerShouldRenderTransactions( - const MountingCoordinator::Shared& mountingCoordinator) = 0; + const std::shared_ptr& + mountingCoordinator) = 0; /* * Called right after a new ShadowNode was created. diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerToolbox.h b/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerToolbox.h index 86a38aba934207..c68ad6eee3a7df 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerToolbox.h +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerToolbox.h @@ -49,11 +49,10 @@ struct SchedulerToolbox final { RuntimeExecutor runtimeExecutor; /* - * Asynchronous & synchronous event beats. * Represent connections with the platform-specific run loops and general * purpose background queue. */ - EventBeat::Factory asynchronousEventBeatFactory; + EventBeat::Factory eventBeatFactory; /* * A list of `UIManagerCommitHook`s that should be registered in `UIManager`. diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/SurfaceManager.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/SurfaceManager.cpp index 9020a8d406c7bd..3d8d484efe7292 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/SurfaceManager.cpp +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/SurfaceManager.cpp @@ -64,9 +64,9 @@ Size SurfaceManager::measureSurface( return size; } -MountingCoordinator::Shared SurfaceManager::findMountingCoordinator( - SurfaceId surfaceId) const noexcept { - auto mountingCoordinator = MountingCoordinator::Shared{}; +std::shared_ptr +SurfaceManager::findMountingCoordinator(SurfaceId surfaceId) const noexcept { + auto mountingCoordinator = std::shared_ptr{}; visit(surfaceId, [&](const SurfaceHandler& surfaceHandler) { mountingCoordinator = surfaceHandler.getMountingCoordinator(); diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/SurfaceManager.h b/packages/react-native/ReactCommon/react/renderer/scheduler/SurfaceManager.h index a5526e176a3040..404185818acb5a 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/SurfaceManager.h +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/SurfaceManager.h @@ -49,7 +49,7 @@ class SurfaceManager final { const LayoutConstraints& layoutConstraints, const LayoutContext& layoutContext) const noexcept; - MountingCoordinator::Shared findMountingCoordinator( + std::shared_ptr findMountingCoordinator( SurfaceId surfaceId) const noexcept; private: diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp index be8da13aad3e97..c381d77e3758cf 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp @@ -607,7 +607,7 @@ RootShadowNode::Unshared UIManager::shadowTreeWillCommit( } void UIManager::shadowTreeDidFinishTransaction( - MountingCoordinator::Shared mountingCoordinator, + std::shared_ptr mountingCoordinator, bool mountSynchronously) const { SystraceSection s("UIManager::shadowTreeDidFinishTransaction"); diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.h b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.h index fd6c87d524f8d2..a84845d9a035a8 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.h +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.h @@ -119,7 +119,7 @@ class UIManager final : public ShadowTreeDelegate { #pragma mark - ShadowTreeDelegate void shadowTreeDidFinishTransaction( - MountingCoordinator::Shared mountingCoordinator, + std::shared_ptr mountingCoordinator, bool mountSynchronously) const override; RootShadowNode::Unshared shadowTreeWillCommit( diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp index de07a2847b647b..a9a97a53dbc2f4 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp @@ -483,9 +483,7 @@ jsi::Value UIManagerBinding::get( uiManager->completeSurface( surfaceId, shadowNodeList, - {.enableStateReconciliation = true, - .mountSynchronously = false, - .shouldYield = nullptr}); + {.enableStateReconciliation = true, .mountSynchronously = false}); return jsi::Value::undefined(); }); diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerDelegate.h b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerDelegate.h index 4b196f4101c4cb..46b78957705670 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerDelegate.h +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerDelegate.h @@ -23,7 +23,7 @@ class UIManagerDelegate { * For this moment the tree is already laid out and sealed. */ virtual void uiManagerDidFinishTransaction( - MountingCoordinator::Shared mountingCoordinator, + std::shared_ptr mountingCoordinator, bool mountSynchronously) = 0; /* diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/consistency/tests/LazyShadowTreeRevisionConsistencyManagerTest.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/consistency/tests/LazyShadowTreeRevisionConsistencyManagerTest.cpp index 0cd1fe194fba38..ae6312baa09cdf 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/consistency/tests/LazyShadowTreeRevisionConsistencyManagerTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/consistency/tests/LazyShadowTreeRevisionConsistencyManagerTest.cpp @@ -24,7 +24,7 @@ class FakeShadowTreeDelegate : public ShadowTreeDelegate { }; void shadowTreeDidFinishTransaction( - MountingCoordinator::Shared mountingCoordinator, + std::shared_ptr mountingCoordinator, bool mountSynchronously) const override {}; }; diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp index 97c420ccf5b060..15ac4c8465c3a3 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp @@ -27,6 +27,24 @@ namespace facebook::react { +namespace { + +std::shared_ptr createRuntimeScheduler( + RuntimeExecutor runtimeExecutor, + RuntimeSchedulerTaskErrorHandler taskErrorHandler) { + std::shared_ptr scheduler = + std::make_shared( + runtimeExecutor, RuntimeSchedulerClock::now, taskErrorHandler); + scheduler->setPerformanceEntryReporter( + // FIXME: Move creation of PerformanceEntryReporter to here and + // guarantee that its lifetime is the same as the runtime. + PerformanceEntryReporter::getInstance().get()); + + return scheduler; +} + +} // namespace + ReactInstance::ReactInstance( std::unique_ptr runtime, std::shared_ptr jsMessageQueueThread, @@ -78,7 +96,7 @@ ReactInstance::ReactInstance( // If we have first-class support for microtasks, // they would've been called as part of the previous callback. - if (!ReactNativeFeatureFlags::enableMicrotasks()) { + if (ReactNativeFeatureFlags::disableEventLoopOnBridgeless()) { if (auto timerManager = weakTimerManager.lock()) { timerManager->callReactNativeMicrotasks(jsiRuntime); } @@ -93,13 +111,34 @@ ReactInstance::ReactInstance( if (parentInspectorTarget_) { auto executor = parentInspectorTarget_->executorFromThis(); - auto runtimeExecutorThatWaitsForInspectorSetup = + auto bufferedRuntimeExecutorThatWaitsForInspectorSetup = std::make_shared(runtimeExecutor); + auto runtimeExecutorThatExecutesAfterInspectorSetup = + [bufferedRuntimeExecutorThatWaitsForInspectorSetup]( + std::function&& callback) { + bufferedRuntimeExecutorThatWaitsForInspectorSetup->execute( + std::move(callback)); + }; + + runtimeScheduler_ = createRuntimeScheduler( + runtimeExecutorThatExecutesAfterInspectorSetup, + [jsErrorHandler = jsErrorHandler_]( + jsi::Runtime& runtime, jsi::JSError& error) { + jsErrorHandler->handleError(runtime, error, true); + }); + + auto runtimeExecutorThatGoesThroughRuntimeScheduler = + [runtimeScheduler = runtimeScheduler_.get()]( + std::function&& callback) { + runtimeScheduler->scheduleWork(std::move(callback)); + }; // This code can execute from any thread, so we need to make sure we set up // the inspector logic in the right one. The callback executes immediately // if we are already in the right thread. - executor([this, runtimeExecutor, runtimeExecutorThatWaitsForInspectorSetup]( + executor([this, + runtimeExecutorThatGoesThroughRuntimeScheduler, + bufferedRuntimeExecutorThatWaitsForInspectorSetup]( jsinspector_modern::HostTarget& hostTarget) { // Callbacks scheduled through the page target executor are generally // not guaranteed to run (e.g.: if the page target is destroyed) @@ -110,32 +149,19 @@ ReactInstance::ReactInstance( // creation task to finish before starting the destruction. inspectorTarget_ = &hostTarget.registerInstance(*this); runtimeInspectorTarget_ = &inspectorTarget_->registerRuntime( - runtime_->getRuntimeTargetDelegate(), runtimeExecutor); - runtimeExecutorThatWaitsForInspectorSetup->flush(); + runtime_->getRuntimeTargetDelegate(), + runtimeExecutorThatGoesThroughRuntimeScheduler); + bufferedRuntimeExecutorThatWaitsForInspectorSetup->flush(); }); - - // We decorate the runtime executor used everywhere else to wait for the - // inspector to finish its setup. - runtimeExecutor = - [runtimeExecutorThatWaitsForInspectorSetup]( - std::function&& callback) { - runtimeExecutorThatWaitsForInspectorSetup->execute( - std::move(callback)); - }; + } else { + runtimeScheduler_ = createRuntimeScheduler( + runtimeExecutor, + [jsErrorHandler = jsErrorHandler_]( + jsi::Runtime& runtime, jsi::JSError& error) { + jsErrorHandler->handleError(runtime, error, true); + }); } - runtimeScheduler_ = std::make_shared( - runtimeExecutor, - RuntimeSchedulerClock::now, - [jsErrorHandler = jsErrorHandler_]( - jsi::Runtime& runtime, jsi::JSError& error) { - jsErrorHandler->handleError(runtime, error, true); - }); - runtimeScheduler_->setPerformanceEntryReporter( - // FIXME: Move creation of PerformanceEntryReporter to here and guarantee - // that its lifetime is the same as the runtime. - PerformanceEntryReporter::getInstance().get()); - bufferedRuntimeExecutor_ = std::make_shared( [runtimeScheduler = runtimeScheduler_.get()]( std::function&& callback) { @@ -365,17 +391,6 @@ bool isTruthy(jsi::Runtime& runtime, const jsi::Value& value) { return Boolean.call(runtime, value).getBool(); } -jsi::Value wrapInErrorIfNecessary( - jsi::Runtime& runtime, - const jsi::Value& value) { - auto Error = runtime.global().getPropertyAsFunction(runtime, "Error"); - auto isError = - value.isObject() && value.asObject(runtime).instanceOf(runtime, Error); - auto error = isError ? value.getObject(runtime) - : Error.callAsConstructor(runtime, value); - return jsi::Value(runtime, error); -} - } // namespace void ReactInstance::initializeRuntime( @@ -422,8 +437,8 @@ void ReactInstance::initializeRuntime( return jsi::Value(false); } - auto jsError = jsi::JSError( - runtime, wrapInErrorIfNecessary(runtime, args[0])); + auto jsError = + jsi::JSError(runtime, jsi::Value(runtime, args[0])); jsErrorHandler->handleError(runtime, jsError, isFatal); return jsi::Value(true); diff --git a/packages/react-native/ReactCommon/react/runtime/TimerManager.cpp b/packages/react-native/ReactCommon/react/runtime/TimerManager.cpp index bc205ce31810dc..e450159a7f69c8 100644 --- a/packages/react-native/ReactCommon/react/runtime/TimerManager.cpp +++ b/packages/react-native/ReactCommon/react/runtime/TimerManager.cpp @@ -226,7 +226,7 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) { // Ensure that we don't define `setImmediate` and `clearImmediate` if // microtasks are enabled (as we polyfill them using `queueMicrotask` then). - if (!ReactNativeFeatureFlags::enableMicrotasks()) { + if (ReactNativeFeatureFlags::disableEventLoopOnBridgeless()) { runtime.global().setProperty( runtime, "setImmediate", diff --git a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp index 8e2e193a53cbfb..9d59d46043875c 100644 --- a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp @@ -147,7 +147,9 @@ std::unique_ptr HermesInstance::createJSRuntime( ::hermes::vm::RuntimeConfig::Builder() .withGCConfig(gcConfig.build()) .withEnableSampleProfiling(true) - .withMicrotaskQueue(ReactNativeFeatureFlags::enableMicrotasks()) + .withMicrotaskQueue( + ReactNativeFeatureFlags::enableBridgelessArchitecture() && + !ReactNativeFeatureFlags::disableEventLoopOnBridgeless()) .withVMExperimentFlags(vmExperimentFlags); if (crashManager) { diff --git a/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp b/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp index cfee71e3c3eeb2..7fb0c662c23d62 100644 --- a/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp +++ b/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp @@ -237,136 +237,6 @@ TEST_F(ReactInstanceTest, testProfilingFlag) { EXPECT_EQ(val.getBool(), true); } -TEST_F(ReactInstanceTest, testPromiseIntegration) { - initializeRuntimeWithScript(""); - - eval(R"xyz123( -let called = 0; -function getResult() { - return called; -} -Promise.resolve().then(() => { - called++; -}).then(() => { - called++; -}) -)xyz123"); - auto result = runtime_->global() - .getPropertyAsFunction(*runtime_, "getResult") - .call(*runtime_); - EXPECT_EQ(result.getNumber(), 2); -} - -TEST_F(ReactInstanceTest, testSetImmediate) { - initializeRuntimeWithScript(""); - - eval(R"xyz123( -let called = false; -function getResult() { - return called; -} -setImmediate(() => { - called = true; -}); -)xyz123"); - auto result = runtime_->global() - .getPropertyAsFunction(*runtime_, "getResult") - .call(*runtime_); - EXPECT_EQ(result.getBool(), true); -} - -TEST_F(ReactInstanceTest, testNestedSetImmediate) { - initializeRuntimeWithScript(""); - - eval(R"xyz123( -let called = false; -function getResult() { - return called; -} -setImmediate(() => { - setImmediate(() => { - called = true; - }) -}); -)xyz123"); - auto result = runtime_->global() - .getPropertyAsFunction(*runtime_, "getResult") - .call(*runtime_); - EXPECT_EQ(result.getBool(), true); -} - -TEST_F(ReactInstanceTest, testSetImmediateWithInvalidArgs) { - initializeRuntimeWithScript(""); - - EXPECT_EQ( - getErrorMessage("setImmediate();"), - "setImmediate must be called with at least one argument (a function to call)"); - - eval("setImmediate('invalid');"); - expectNoError(); - - eval("setImmediate({});"); - expectNoError(); -} - -TEST_F(ReactInstanceTest, testClearImmediate) { - initializeRuntimeWithScript(""); - - eval(R"xyz123( -let called = false; -function getResult() { - return called; -} -const handle = setImmediate(() => { - called = true; -}); -clearImmediate(handle); -)xyz123"); - - auto func = runtime_->global().getPropertyAsFunction(*runtime_, "getResult"); - auto val = func.call(*runtime_); - EXPECT_EQ(val.getBool(), false); -} - -TEST_F(ReactInstanceTest, testClearImmediateWithInvalidHandle) { - initializeRuntimeWithScript(""); - - auto js = R"xyz123( -let called = false; -const handle = setImmediate(() => { - called = true; -}); -function getResult() { - return called; -} -function clearInvalidHandle() { - clearImmediate(handle); -} -)xyz123"; - eval(js); - - auto clear = - runtime_->global().getPropertyAsFunction(*runtime_, "clearInvalidHandle"); - // Clearing an invalid handle should fail silently. - EXPECT_NO_THROW(clear.call((*runtime_))); -} - -TEST_F(ReactInstanceTest, testClearImmediateWithInvalidArgs) { - initializeRuntimeWithScript(""); - - eval("clearImmediate();"); - expectNoError(); - - eval("clearImmediate('invalid');"); - expectNoError(); - - eval("clearImmediate({});"); - expectNoError(); - - eval("clearImmediate(undefined);"); - expectNoError(); -} - TEST_F(ReactInstanceTest, testSetTimeout) { initializeRuntimeWithScript(""); diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp deleted file mode 100644 index 9d4ae217536f0d..00000000000000 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* - * 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 "CoreFeatures.h" - -namespace facebook::react { - -bool CoreFeatures::enablePropIteratorSetter = false; -bool CoreFeatures::excludeYogaFromRawProps = false; - -} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h deleted file mode 100644 index 526e5dc707ec96..00000000000000 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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. - */ - -#pragma once - -namespace facebook::react { - -/* - * Contains the set of feature flags for the renderer core. - * Some of them are temporary and may be eventually phased out - * as soon as the feature is fully implemented. - */ -class CoreFeatures { - public: - // Specifies whether the iterator-style prop parsing is enabled. - static bool enablePropIteratorSetter; - - // When enabled, rawProps in Props will not include Yoga specific props. - static bool excludeYogaFromRawProps; -}; - -} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/utils/RunLoopObserver.cpp b/packages/react-native/ReactCommon/react/utils/RunLoopObserver.cpp index 74707e8d91a63e..b89955025625dd 100644 --- a/packages/react-native/ReactCommon/react/utils/RunLoopObserver.cpp +++ b/packages/react-native/ReactCommon/react/utils/RunLoopObserver.cpp @@ -11,10 +11,8 @@ namespace facebook::react { -RunLoopObserver::RunLoopObserver( - Activity activities, - const WeakOwner& owner) noexcept - : activities_(activities), owner_(owner) {} +RunLoopObserver::RunLoopObserver(Activity activities, WeakOwner owner) noexcept + : activities_(activities), owner_(std::move(owner)) {} void RunLoopObserver::setDelegate(const Delegate* delegate) const noexcept { // We need these constraints to ensure basic thread-safety. diff --git a/packages/react-native/ReactCommon/react/utils/RunLoopObserver.h b/packages/react-native/ReactCommon/react/utils/RunLoopObserver.h index 43a7918aba227e..6e0e5bc9d77dd5 100644 --- a/packages/react-native/ReactCommon/react/utils/RunLoopObserver.h +++ b/packages/react-native/ReactCommon/react/utils/RunLoopObserver.h @@ -18,8 +18,6 @@ namespace facebook::react { */ class RunLoopObserver { public: - using Unique = std::unique_ptr; - /* * The concept of an owner. * A run loop observer normally observes a run loop running on a different @@ -76,7 +74,7 @@ class RunLoopObserver { /* * Constructs a run loop observer. */ - RunLoopObserver(Activity activities, const WeakOwner& owner) noexcept; + RunLoopObserver(Activity activities, WeakOwner owner) noexcept; virtual ~RunLoopObserver() noexcept = default; /* diff --git a/packages/react-native/ReactCommon/reactperflogger/React-perflogger.podspec b/packages/react-native/ReactCommon/reactperflogger/React-perflogger.podspec index 66dfbf4712cd76..686454f975cd4c 100644 --- a/packages/react-native/ReactCommon/reactperflogger/React-perflogger.podspec +++ b/packages/react-native/ReactCommon/reactperflogger/React-perflogger.podspec @@ -24,6 +24,7 @@ header_search_paths = [ "\"$(PODS_TARGET_SRCROOT)/..\"", "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"" ] diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp index c0a72918d8cf9e..cddd5d5849ff83 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp @@ -71,6 +71,8 @@ const char* YGDisplayToString(const YGDisplay value) { return "flex"; case YGDisplayNone: return "none"; + case YGDisplayContents: + return "contents"; } return "unknown"; } @@ -105,8 +107,8 @@ const char* YGErrataToString(const YGErrata value) { return "none"; case YGErrataStretchFlexBasis: return "stretch-flex-basis"; - case YGErrataAbsolutePositioningIncorrect: - return "absolute-positioning-incorrect"; + case YGErrataAbsolutePositionWithoutInsetsExcludesPadding: + return "absolute-position-without-insets-excludes-padding"; case YGErrataAbsolutePercentAgainstInnerSize: return "absolute-percent-against-inner-size"; case YGErrataAll: diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h index 83c368a601bcf5..27f0426f450ec4 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h @@ -43,7 +43,8 @@ YG_ENUM_DECL( YG_ENUM_DECL( YGDisplay, YGDisplayFlex, - YGDisplayNone) + YGDisplayNone, + YGDisplayContents) YG_ENUM_DECL( YGEdge, @@ -61,7 +62,7 @@ YG_ENUM_DECL( YGErrata, YGErrataNone = 0, YGErrataStretchFlexBasis = 1, - YGErrataAbsolutePositioningIncorrect = 2, + YGErrataAbsolutePositionWithoutInsetsExcludesPadding = 2, YGErrataAbsolutePercentAgainstInnerSize = 4, YGErrataAll = 2147483647, YGErrataClassic = 2147483646) diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp index de4eef9df97215..b2d8d8dbefcd1a 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp @@ -19,12 +19,15 @@ static inline void setFlexStartLayoutPosition( const Direction direction, const FlexDirection axis, const float containingBlockWidth) { - child->setLayoutPosition( - child->style().computeFlexStartMargin( - axis, direction, containingBlockWidth) + - parent->getLayout().border(flexStartEdge(axis)) + - parent->getLayout().padding(flexStartEdge(axis)), - flexStartEdge(axis)); + float position = child->style().computeFlexStartMargin( + axis, direction, containingBlockWidth) + + parent->getLayout().border(flexStartEdge(axis)); + + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + position += parent->getLayout().padding(flexStartEdge(axis)); + } + + child->setLayoutPosition(position, flexStartEdge(axis)); } static inline void setFlexEndLayoutPosition( @@ -33,15 +36,16 @@ static inline void setFlexEndLayoutPosition( const Direction direction, const FlexDirection axis, const float containingBlockWidth) { + float flexEndPosition = parent->getLayout().border(flexEndEdge(axis)) + + child->style().computeFlexEndMargin( + axis, direction, containingBlockWidth); + + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + flexEndPosition += parent->getLayout().padding(flexEndEdge(axis)); + } + child->setLayoutPosition( - getPositionOfOppositeEdge( - parent->getLayout().border(flexEndEdge(axis)) + - parent->getLayout().padding(flexEndEdge(axis)) + - child->style().computeFlexEndMargin( - axis, direction, containingBlockWidth), - axis, - parent, - child), + getPositionOfOppositeEdge(flexEndPosition, axis, parent, child), flexStartEdge(axis)); } @@ -51,22 +55,30 @@ static inline void setCenterLayoutPosition( const Direction direction, const FlexDirection axis, const float containingBlockWidth) { - const float parentContentBoxSize = + float parentContentBoxSize = parent->getLayout().measuredDimension(dimension(axis)) - parent->getLayout().border(flexStartEdge(axis)) - - parent->getLayout().border(flexEndEdge(axis)) - - parent->getLayout().padding(flexStartEdge(axis)) - - parent->getLayout().padding(flexEndEdge(axis)); + parent->getLayout().border(flexEndEdge(axis)); + + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + parentContentBoxSize -= parent->getLayout().padding(flexStartEdge(axis)); + parentContentBoxSize -= parent->getLayout().padding(flexEndEdge(axis)); + } + const float childOuterSize = child->getLayout().measuredDimension(dimension(axis)) + child->style().computeMarginForAxis(axis, containingBlockWidth); - child->setLayoutPosition( - (parentContentBoxSize - childOuterSize) / 2.0f + - parent->getLayout().border(flexStartEdge(axis)) + - parent->getLayout().padding(flexStartEdge(axis)) + - child->style().computeFlexStartMargin( - axis, direction, containingBlockWidth), - flexStartEdge(axis)); + + float position = (parentContentBoxSize - childOuterSize) / 2.0f + + parent->getLayout().border(flexStartEdge(axis)) + + child->style().computeFlexStartMargin( + axis, direction, containingBlockWidth); + + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + position += parent->getLayout().padding(flexStartEdge(axis)); + } + + child->setLayoutPosition(position, flexStartEdge(axis)); } static void justifyAbsoluteChild( @@ -133,62 +145,6 @@ static void alignAbsoluteChild( } } -// To ensure no breaking changes, we preserve the legacy way of positioning -// absolute children and determine if we should use it using an errata. -static void positionAbsoluteChildLegacy( - const yoga::Node* const containingNode, - const yoga::Node* const parent, - yoga::Node* child, - const Direction direction, - const FlexDirection axis, - const bool isMainAxis, - const float containingBlockWidth, - const float containingBlockHeight) { - const bool isAxisRow = isRow(axis); - const bool shouldCenter = isMainAxis - ? parent->style().justifyContent() == Justify::Center - : resolveChildAlignment(parent, child) == Align::Center; - const bool shouldFlexEnd = isMainAxis - ? parent->style().justifyContent() == Justify::FlexEnd - : ((resolveChildAlignment(parent, child) == Align::FlexEnd) ^ - (parent->style().flexWrap() == Wrap::WrapReverse)); - - if (child->style().isFlexEndPositionDefined(axis, direction) && - (!child->style().isFlexStartPositionDefined(axis, direction) || - child->style().isFlexStartPositionAuto(axis, direction))) { - child->setLayoutPosition( - containingNode->getLayout().measuredDimension(dimension(axis)) - - child->getLayout().measuredDimension(dimension(axis)) - - containingNode->style().computeFlexEndBorder(axis, direction) - - child->style().computeFlexEndMargin( - axis, - direction, - isAxisRow ? containingBlockWidth : containingBlockHeight) - - child->style().computeFlexEndPosition( - axis, - direction, - isAxisRow ? containingBlockWidth : containingBlockHeight), - flexStartEdge(axis)); - } else if ( - (!child->style().isFlexStartPositionDefined(axis, direction) || - child->style().isFlexStartPositionAuto(axis, direction)) && - shouldCenter) { - child->setLayoutPosition( - (parent->getLayout().measuredDimension(dimension(axis)) - - child->getLayout().measuredDimension(dimension(axis))) / - 2.0f, - flexStartEdge(axis)); - } else if ( - (!child->style().isFlexStartPositionDefined(axis, direction) || - child->style().isFlexStartPositionAuto(axis, direction)) && - shouldFlexEnd) { - child->setLayoutPosition( - (parent->getLayout().measuredDimension(dimension(axis)) - - child->getLayout().measuredDimension(dimension(axis))), - flexStartEdge(axis)); - } -} - /* * Absolutely positioned nodes do not participate in flex layout and thus their * positions can be determined independently from the rest of their siblings. @@ -205,7 +161,7 @@ static void positionAbsoluteChildLegacy( * This function does that positioning for the given axis. The spec has more * information on this topic: https://www.w3.org/TR/css-flexbox-1/#abspos-items */ -static void positionAbsoluteChildImpl( +static void positionAbsoluteChild( const yoga::Node* const containingNode, const yoga::Node* const parent, yoga::Node* child, @@ -267,36 +223,6 @@ static void positionAbsoluteChildImpl( } } -static void positionAbsoluteChild( - const yoga::Node* const containingNode, - const yoga::Node* const parent, - yoga::Node* child, - const Direction direction, - const FlexDirection axis, - const bool isMainAxis, - const float containingBlockWidth, - const float containingBlockHeight) { - child->hasErrata(Errata::AbsolutePositioningIncorrect) - ? positionAbsoluteChildLegacy( - containingNode, - parent, - child, - direction, - axis, - isMainAxis, - containingBlockWidth, - containingBlockHeight) - : positionAbsoluteChildImpl( - containingNode, - parent, - child, - direction, - axis, - isMainAxis, - containingBlockWidth, - containingBlockHeight); -} - void layoutAbsoluteChild( const yoga::Node* const containingNode, const yoga::Node* const node, @@ -508,7 +434,7 @@ bool layoutAbsoluteDescendants( float containingNodeAvailableInnerWidth, float containingNodeAvailableInnerHeight) { bool hasNewLayout = false; - for (auto child : currentNode->getChildren()) { + for (auto child : currentNode->getLayoutChildren()) { if (child->style().display() == Display::None) { continue; } else if (child->style().positionType() == PositionType::Absolute) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/Baseline.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/Baseline.cpp index 61cf7dd1e7eb20..b3002012bc065c 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/Baseline.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/Baseline.cpp @@ -32,9 +32,7 @@ float calculateBaseline(const yoga::Node* node) { } yoga::Node* baselineChild = nullptr; - const size_t childCount = node->getChildCount(); - for (size_t i = 0; i < childCount; i++) { - auto child = node->getChild(i); + for (auto child : node->getLayoutChildren()) { if (child->getLineIndex() > 0) { break; } @@ -67,9 +65,7 @@ bool isBaselineLayout(const yoga::Node* node) { if (node->style().alignItems() == Align::Baseline) { return true; } - const auto childCount = node->getChildCount(); - for (size_t i = 0; i < childCount; i++) { - auto child = node->getChild(i); + for (auto child : node->getLayoutChildren()) { if (child->style().positionType() != PositionType::Absolute && child->style().alignSelf() == Align::Baseline) { return true; diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index 3a98c9232cacaa..1932ff5508bebd 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -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( const yoga::Node* const node, const Direction direction, @@ -525,7 +540,7 @@ static float computeFlexBasisForChildren( const uint32_t generationCount) { float totalOuterFlexBasis = 0.0f; YGNodeRef singleFlexChild = nullptr; - const auto& children = node->getChildren(); + const auto& children = node->getLayoutChildren(); SizingMode sizingModeMainDim = isRow(mainAxis) ? widthSizingMode : heightSizingMode; // If there is only one child with flexGrow + flexShrink it means we can set @@ -981,7 +996,6 @@ static void resolveFlexibleLength( static void justifyMainAxis( yoga::Node* const node, FlexLine& flexLine, - const size_t startOfLineIndex, const FlexDirection mainAxis, const FlexDirection crossAxis, const Direction direction, @@ -1081,102 +1095,69 @@ static void justifyMainAxis( float maxAscentForCurrentLine = 0; float maxDescentForCurrentLine = 0; bool isNodeBaselineLayout = isBaselineLayout(node); - for (size_t i = startOfLineIndex; i < flexLine.endOfLineIndex; i++) { - const auto child = node->getChild(i); - const Style& childStyle = child->style(); + for (auto child : flexLine.itemsInFlow) { const LayoutResults& childLayout = child->getLayout(); - if (childStyle.display() == Display::None) { - continue; + if (child->style().flexStartMarginIsAuto(mainAxis, direction) && + flexLine.layout.remainingFreeSpace > 0.0f) { + flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / + static_cast(flexLine.numberOfAutoMargins); } - if (childStyle.positionType() == PositionType::Absolute && - child->style().isFlexStartPositionDefined(mainAxis, direction) && - !child->style().isFlexStartPositionAuto(mainAxis, direction)) { - if (performLayout) { - // In case the child is position absolute and has left/top being - // defined, we override the position to whatever the user said (and - // margin/border). - child->setLayoutPosition( - child->style().computeFlexStartPosition( - mainAxis, direction, availableInnerMainDim) + - node->style().computeFlexStartBorder(mainAxis, direction) + - child->style().computeFlexStartMargin( - mainAxis, direction, availableInnerWidth), - flexStartEdge(mainAxis)); - } - } else { - // Now that we placed the element, we need to update the variables. - // We need to do that only for relative elements. Absolute elements do not - // take part in that phase. - if (childStyle.positionType() != PositionType::Absolute) { - if (child->style().flexStartMarginIsAuto(mainAxis, direction) && - flexLine.layout.remainingFreeSpace > 0.0f) { - flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / - static_cast(flexLine.numberOfAutoMargins); - } - if (performLayout) { - child->setLayoutPosition( - childLayout.position(flexStartEdge(mainAxis)) + - flexLine.layout.mainDim, - flexStartEdge(mainAxis)); - } - - if (child != flexLine.itemsInFlow.back()) { - flexLine.layout.mainDim += betweenMainDim; - } + if (performLayout) { + child->setLayoutPosition( + childLayout.position(flexStartEdge(mainAxis)) + + flexLine.layout.mainDim, + flexStartEdge(mainAxis)); + } - if (child->style().flexEndMarginIsAuto(mainAxis, direction) && - flexLine.layout.remainingFreeSpace > 0.0f) { - flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / - static_cast(flexLine.numberOfAutoMargins); - } - bool canSkipFlex = - !performLayout && sizingModeCrossDim == SizingMode::StretchFit; - if (canSkipFlex) { - // If we skipped the flex step, then we can't rely on the measuredDims - // because they weren't computed. This means we can't call - // dimensionWithMargin. - flexLine.layout.mainDim += child->style().computeMarginForAxis( - mainAxis, availableInnerWidth) + - childLayout.computedFlexBasis.unwrap(); - flexLine.layout.crossDim = availableInnerCrossDim; - } else { - // The main dimension is the sum of all the elements dimension plus - // the spacing. - flexLine.layout.mainDim += - child->dimensionWithMargin(mainAxis, availableInnerWidth); - - if (isNodeBaselineLayout) { - // If the child is baseline aligned then the cross dimension is - // calculated by adding maxAscent and maxDescent from the baseline. - const float ascent = calculateBaseline(child) + - child->style().computeFlexStartMargin( - FlexDirection::Column, direction, availableInnerWidth); - const float descent = - child->getLayout().measuredDimension(Dimension::Height) + - child->style().computeMarginForAxis( - FlexDirection::Column, availableInnerWidth) - - ascent; + if (child != flexLine.itemsInFlow.back()) { + flexLine.layout.mainDim += betweenMainDim; + } - maxAscentForCurrentLine = - yoga::maxOrDefined(maxAscentForCurrentLine, ascent); - maxDescentForCurrentLine = - yoga::maxOrDefined(maxDescentForCurrentLine, descent); - } else { - // The cross dimension is the max of the elements dimension since - // there can only be one element in that cross dimension in the case - // when the items are not baseline aligned - flexLine.layout.crossDim = yoga::maxOrDefined( - flexLine.layout.crossDim, - child->dimensionWithMargin(crossAxis, availableInnerWidth)); - } - } - } else if (performLayout) { - child->setLayoutPosition( - childLayout.position(flexStartEdge(mainAxis)) + - node->style().computeFlexStartBorder(mainAxis, direction) + - leadingMainDim, - flexStartEdge(mainAxis)); + if (child->style().flexEndMarginIsAuto(mainAxis, direction) && + flexLine.layout.remainingFreeSpace > 0.0f) { + flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / + static_cast(flexLine.numberOfAutoMargins); + } + bool canSkipFlex = + !performLayout && sizingModeCrossDim == SizingMode::StretchFit; + if (canSkipFlex) { + // If we skipped the flex step, then we can't rely on the measuredDims + // because they weren't computed. This means we can't call + // dimensionWithMargin. + flexLine.layout.mainDim += + child->style().computeMarginForAxis(mainAxis, availableInnerWidth) + + childLayout.computedFlexBasis.unwrap(); + flexLine.layout.crossDim = availableInnerCrossDim; + } else { + // The main dimension is the sum of all the elements dimension plus + // the spacing. + flexLine.layout.mainDim += + child->dimensionWithMargin(mainAxis, availableInnerWidth); + + if (isNodeBaselineLayout) { + // If the child is baseline aligned then the cross dimension is + // calculated by adding maxAscent and maxDescent from the baseline. + const float ascent = calculateBaseline(child) + + child->style().computeFlexStartMargin( + FlexDirection::Column, direction, availableInnerWidth); + const float descent = + child->getLayout().measuredDimension(Dimension::Height) + + child->style().computeMarginForAxis( + FlexDirection::Column, availableInnerWidth) - + ascent; + + maxAscentForCurrentLine = + yoga::maxOrDefined(maxAscentForCurrentLine, ascent); + maxDescentForCurrentLine = + yoga::maxOrDefined(maxDescentForCurrentLine, descent); + } else { + // The cross dimension is the max of the elements dimension since + // there can only be one element in that cross dimension in the case + // when the items are not baseline aligned + flexLine.layout.crossDim = yoga::maxOrDefined( + flexLine.layout.crossDim, + child->dimensionWithMargin(crossAxis, availableInnerWidth)); } } } @@ -1335,6 +1316,10 @@ static void calculateLayoutImpl( flexColumnDirection, direction, ownerWidth), PhysicalEdge::Bottom); + // Clean and update all display: contents nodes with a direct path to the + // current node as they will not be traversed + cleanupContentsNodesRecursively(node); + if (node->hasMeasureFunc()) { measureNodeWithMeasureFunc( node, @@ -1350,7 +1335,7 @@ static void calculateLayoutImpl( return; } - const auto childCount = node->getChildCount(); + const auto childCount = node->getLayoutChildCount(); if (childCount == 0) { measureNodeWithoutChildren( node, @@ -1470,9 +1455,9 @@ static void calculateLayoutImpl( } // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES - // Indexes of children that represent the first and last items in the line. - size_t startOfLineIndex = 0; - size_t endOfLineIndex = 0; + // Iterator representing the beginning of the current line + Node::LayoutableChildren::Iterator startOfLineIterator = + node->getLayoutChildren().begin(); // Number of lines. size_t lineCount = 0; @@ -1485,8 +1470,7 @@ static void calculateLayoutImpl( // Max main dimension of all the lines. float maxLineMainDim = 0; - for (; endOfLineIndex < childCount; - lineCount++, startOfLineIndex = endOfLineIndex) { + for (; startOfLineIterator != node->getLayoutChildren().end(); lineCount++) { auto flexLine = calculateFlexLine( node, ownerDirection, @@ -1494,11 +1478,9 @@ static void calculateLayoutImpl( mainAxisOwnerSize, availableInnerWidth, availableInnerMainDim, - startOfLineIndex, + startOfLineIterator, lineCount); - endOfLineIndex = flexLine.endOfLineIndex; - // If we don't need to measure the cross axis, we can skip the entire flex // step. const bool canSkipFlex = @@ -1616,7 +1598,6 @@ static void calculateLayoutImpl( justifyMainAxis( node, flexLine, - startOfLineIndex, mainAxis, crossAxis, direction, @@ -1668,151 +1649,116 @@ static void calculateLayoutImpl( // STEP 7: CROSS-AXIS ALIGNMENT // We can skip child alignment if we're just measuring the container. if (performLayout) { - for (size_t i = startOfLineIndex; i < endOfLineIndex; i++) { - const auto child = node->getChild(i); - if (child->style().display() == Display::None) { - continue; - } - if (child->style().positionType() == PositionType::Absolute) { - // If the child is absolutely positioned and has a - // top/left/bottom/right set, override all the previously computed - // positions to set it correctly. - const bool isChildLeadingPosDefined = - child->style().isFlexStartPositionDefined(crossAxis, direction) && - !child->style().isFlexStartPositionAuto(crossAxis, direction); - if (isChildLeadingPosDefined) { - child->setLayoutPosition( - child->style().computeFlexStartPosition( - crossAxis, direction, availableInnerCrossDim) + - node->style().computeFlexStartBorder(crossAxis, direction) + - child->style().computeFlexStartMargin( - crossAxis, direction, availableInnerWidth), - flexStartEdge(crossAxis)); - } - // If leading position is not defined or calculations result in Nan, - // default to border + margin - if (!isChildLeadingPosDefined || - yoga::isUndefined( - child->getLayout().position(flexStartEdge(crossAxis)))) { - child->setLayoutPosition( - node->style().computeFlexStartBorder(crossAxis, direction) + - child->style().computeFlexStartMargin( - crossAxis, direction, availableInnerWidth), - flexStartEdge(crossAxis)); + for (auto child : flexLine.itemsInFlow) { + float leadingCrossDim = leadingPaddingAndBorderCross; + + // For a relative children, we're either using alignItems (owner) or + // alignSelf (child) in order to determine the position in the cross + // axis + const Align alignItem = resolveChildAlignment(node, child); + + // If the child uses align stretch, we need to lay it out one more + // time, this time forcing the cross-axis size to be the computed + // cross size for the current line. + if (alignItem == Align::Stretch && + !child->style().flexStartMarginIsAuto(crossAxis, direction) && + !child->style().flexEndMarginIsAuto(crossAxis, direction)) { + // If the child defines a definite size for its cross axis, there's + // no need to stretch. + if (!child->hasDefiniteLength( + dimension(crossAxis), availableInnerCrossDim)) { + float childMainSize = + child->getLayout().measuredDimension(dimension(mainAxis)); + const auto& childStyle = child->style(); + float childCrossSize = childStyle.aspectRatio().isDefined() + ? child->style().computeMarginForAxis( + crossAxis, availableInnerWidth) + + (isMainAxisRow + ? childMainSize / childStyle.aspectRatio().unwrap() + : childMainSize * childStyle.aspectRatio().unwrap()) + : flexLine.layout.crossDim; + + childMainSize += child->style().computeMarginForAxis( + mainAxis, availableInnerWidth); + + SizingMode childMainSizingMode = SizingMode::StretchFit; + SizingMode childCrossSizingMode = SizingMode::StretchFit; + constrainMaxSizeForMode( + child, + direction, + mainAxis, + availableInnerMainDim, + availableInnerWidth, + &childMainSizingMode, + &childMainSize); + constrainMaxSizeForMode( + child, + direction, + crossAxis, + availableInnerCrossDim, + availableInnerWidth, + &childCrossSizingMode, + &childCrossSize); + + const float childWidth = + isMainAxisRow ? childMainSize : childCrossSize; + const float childHeight = + !isMainAxisRow ? childMainSize : childCrossSize; + + auto alignContent = node->style().alignContent(); + auto crossAxisDoesNotGrow = + alignContent != Align::Stretch && isNodeFlexWrap; + const SizingMode childWidthSizingMode = + yoga::isUndefined(childWidth) || + (!isMainAxisRow && crossAxisDoesNotGrow) + ? SizingMode::MaxContent + : SizingMode::StretchFit; + const SizingMode childHeightSizingMode = + yoga::isUndefined(childHeight) || + (isMainAxisRow && crossAxisDoesNotGrow) + ? SizingMode::MaxContent + : SizingMode::StretchFit; + + calculateLayoutInternal( + child, + childWidth, + childHeight, + direction, + childWidthSizingMode, + childHeightSizingMode, + availableInnerWidth, + availableInnerHeight, + true, + LayoutPassReason::kStretch, + layoutMarkerData, + depth, + generationCount); } } else { - float leadingCrossDim = leadingPaddingAndBorderCross; - - // For a relative children, we're either using alignItems (owner) or - // alignSelf (child) in order to determine the position in the cross - // axis - const Align alignItem = resolveChildAlignment(node, child); - - // If the child uses align stretch, we need to lay it out one more - // time, this time forcing the cross-axis size to be the computed - // cross size for the current line. - if (alignItem == Align::Stretch && - !child->style().flexStartMarginIsAuto(crossAxis, direction) && - !child->style().flexEndMarginIsAuto(crossAxis, direction)) { - // If the child defines a definite size for its cross axis, there's - // no need to stretch. - if (!child->hasDefiniteLength( - dimension(crossAxis), availableInnerCrossDim)) { - float childMainSize = - child->getLayout().measuredDimension(dimension(mainAxis)); - const auto& childStyle = child->style(); - float childCrossSize = childStyle.aspectRatio().isDefined() - ? child->style().computeMarginForAxis( - crossAxis, availableInnerWidth) + - (isMainAxisRow - ? childMainSize / childStyle.aspectRatio().unwrap() - : childMainSize * childStyle.aspectRatio().unwrap()) - : flexLine.layout.crossDim; - - childMainSize += child->style().computeMarginForAxis( - mainAxis, availableInnerWidth); - - SizingMode childMainSizingMode = SizingMode::StretchFit; - SizingMode childCrossSizingMode = SizingMode::StretchFit; - constrainMaxSizeForMode( - child, - direction, - mainAxis, - availableInnerMainDim, - availableInnerWidth, - &childMainSizingMode, - &childMainSize); - constrainMaxSizeForMode( - child, - direction, - crossAxis, - availableInnerCrossDim, - availableInnerWidth, - &childCrossSizingMode, - &childCrossSize); - - const float childWidth = - isMainAxisRow ? childMainSize : childCrossSize; - const float childHeight = - !isMainAxisRow ? childMainSize : childCrossSize; - - auto alignContent = node->style().alignContent(); - auto crossAxisDoesNotGrow = - alignContent != Align::Stretch && isNodeFlexWrap; - const SizingMode childWidthSizingMode = - yoga::isUndefined(childWidth) || - (!isMainAxisRow && crossAxisDoesNotGrow) - ? SizingMode::MaxContent - : SizingMode::StretchFit; - const SizingMode childHeightSizingMode = - yoga::isUndefined(childHeight) || - (isMainAxisRow && crossAxisDoesNotGrow) - ? SizingMode::MaxContent - : SizingMode::StretchFit; - - calculateLayoutInternal( - child, - childWidth, - childHeight, - direction, - childWidthSizingMode, - childHeightSizingMode, - availableInnerWidth, - availableInnerHeight, - true, - LayoutPassReason::kStretch, - layoutMarkerData, - depth, - generationCount); - } + const float remainingCrossDim = containerCrossAxis - + child->dimensionWithMargin(crossAxis, availableInnerWidth); + + if (child->style().flexStartMarginIsAuto(crossAxis, direction) && + child->style().flexEndMarginIsAuto(crossAxis, direction)) { + leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim / 2); + } else if (child->style().flexEndMarginIsAuto(crossAxis, direction)) { + // No-Op + } else if (child->style().flexStartMarginIsAuto( + crossAxis, direction)) { + leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim); + } else if (alignItem == Align::FlexStart) { + // No-Op + } else if (alignItem == Align::Center) { + leadingCrossDim += remainingCrossDim / 2; } else { - const float remainingCrossDim = containerCrossAxis - - child->dimensionWithMargin(crossAxis, availableInnerWidth); - - if (child->style().flexStartMarginIsAuto(crossAxis, direction) && - child->style().flexEndMarginIsAuto(crossAxis, direction)) { - leadingCrossDim += - yoga::maxOrDefined(0.0f, remainingCrossDim / 2); - } else if (child->style().flexEndMarginIsAuto( - crossAxis, direction)) { - // No-Op - } else if (child->style().flexStartMarginIsAuto( - crossAxis, direction)) { - leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim); - } else if (alignItem == Align::FlexStart) { - // No-Op - } else if (alignItem == Align::Center) { - leadingCrossDim += remainingCrossDim / 2; - } else { - leadingCrossDim += remainingCrossDim; - } + leadingCrossDim += remainingCrossDim; } - // And we apply the position - child->setLayoutPosition( - child->getLayout().position(flexStartEdge(crossAxis)) + - totalLineCrossDim + leadingCrossDim, - flexStartEdge(crossAxis)); } + // And we apply the position + child->setLayoutPosition( + child->getLayout().position(flexStartEdge(crossAxis)) + + totalLineCrossDim + leadingCrossDim, + flexStartEdge(crossAxis)); } } @@ -1886,17 +1832,18 @@ static void calculateLayoutImpl( case Align::Baseline: break; } - size_t endIndex = 0; + Node::LayoutableChildren::Iterator endIterator = + node->getLayoutChildren().begin(); for (size_t i = 0; i < lineCount; i++) { - const size_t startIndex = endIndex; - size_t ii = startIndex; + const Node::LayoutableChildren::Iterator startIterator = endIterator; + auto iterator = startIterator; // compute the line's height and find the endIndex float lineHeight = 0; float maxAscentForCurrentLine = 0; float maxDescentForCurrentLine = 0; - for (; ii < childCount; ii++) { - const auto child = node->getChild(ii); + for (; iterator != node->getLayoutChildren().end(); iterator++) { + const auto child = *iterator; if (child->style().display() == Display::None) { continue; } @@ -1929,11 +1876,11 @@ static void calculateLayoutImpl( } } } - endIndex = ii; + endIterator = iterator; currentLead += i != 0 ? crossAxisGap : 0; - for (ii = startIndex; ii < endIndex; ii++) { - const auto child = node->getChild(ii); + for (iterator = startIterator; iterator != endIterator; iterator++) { + const auto child = *iterator; if (child->style().display() == Display::None) { continue; } @@ -2136,8 +2083,7 @@ static void calculateLayoutImpl( // As we only wrapped in normal direction yet, we need to reverse the // positions on wrap-reverse. if (performLayout && node->style().flexWrap() == Wrap::WrapReverse) { - for (size_t i = 0; i < childCount; i++) { - const auto child = node->getChild(i); + for (auto child : node->getLayoutChildren()) { if (child->style().positionType() != PositionType::Absolute) { child->setLayoutPosition( node->getLayout().measuredDimension(dimension(crossAxis)) - @@ -2154,8 +2100,7 @@ static void calculateLayoutImpl( const bool needsCrossTrailingPos = needsTrailingPosition(crossAxis); if (needsMainTrailingPos || needsCrossTrailingPos) { - for (size_t i = 0; i < childCount; i++) { - const auto child = node->getChild(i); + for (auto child : node->getLayoutChildren()) { // Absolute children will be handled by their containing block since we // cannot guarantee that their positions are set when their parents are // done with layout. diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp index 1ad47fa577b53e..aac495f47b7ed8 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp @@ -20,17 +20,17 @@ FlexLine calculateFlexLine( const float mainAxisownerSize, const float availableInnerWidth, const float availableInnerMainDim, - const size_t startOfLineIndex, + Node::LayoutableChildren::Iterator& iterator, const size_t lineCount) { std::vector itemsInFlow; - itemsInFlow.reserve(node->getChildren().size()); + itemsInFlow.reserve(node->getChildCount()); float sizeConsumed = 0.0f; float totalFlexGrowFactors = 0.0f; float totalFlexShrinkScaledFactors = 0.0f; size_t numberOfAutoMargins = 0; - size_t endOfLineIndex = startOfLineIndex; - size_t firstElementInLineIndex = startOfLineIndex; + size_t endOfLineIndex = iterator.index(); + size_t firstElementInLineIndex = iterator.index(); float sizeConsumedIncludingMinConstraint = 0; const Direction direction = node->resolveDirection(ownerDirection); @@ -41,8 +41,9 @@ FlexLine calculateFlexLine( node->style().computeGapForAxis(mainAxis, availableInnerMainDim); // Add items to the current line until it's full or we run out of items. - for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) { - auto child = node->getChild(endOfLineIndex); + for (; iterator != node->getLayoutChildren().end(); + iterator++, endOfLineIndex = iterator.index()) { + auto child = *iterator; if (child->style().display() == Display::None || child->style().positionType() == PositionType::Absolute) { if (firstElementInLineIndex == endOfLineIndex) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h index 14141794a467a6..4dcf7a509d0e24 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h @@ -72,7 +72,7 @@ FlexLine calculateFlexLine( float mainAxisownerSize, float availableInnerWidth, float availableInnerMainDim, - size_t startOfLineIndex, + Node::LayoutableChildren::Iterator& iterator, size_t lineCount); } // namespace facebook::yoga diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp index 7a694565e9b44e..038994d70e2b08 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp @@ -124,7 +124,7 @@ void roundLayoutResultsToPixelGrid( Dimension::Height); } - for (yoga::Node* child : node->getChildren()) { + for (yoga::Node* child : node->getLayoutChildren()) { roundLayoutResultsToPixelGrid(child, absoluteNodeLeft, absoluteNodeTop); } } diff --git a/packages/react-native/ReactCommon/yoga/yoga/enums/Display.h b/packages/react-native/ReactCommon/yoga/yoga/enums/Display.h index 418ebc1dcd528c..9bf23c0ac7bd1e 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/enums/Display.h +++ b/packages/react-native/ReactCommon/yoga/yoga/enums/Display.h @@ -18,11 +18,12 @@ namespace facebook::yoga { enum class Display : uint8_t { Flex = YGDisplayFlex, None = YGDisplayNone, + Contents = YGDisplayContents, }; template <> constexpr int32_t ordinalCount() { - return 2; + return 3; } constexpr Display scopedEnum(YGDisplay unscoped) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/enums/Errata.h b/packages/react-native/ReactCommon/yoga/yoga/enums/Errata.h index 1b43742e03528b..2f47a941751f6f 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/enums/Errata.h +++ b/packages/react-native/ReactCommon/yoga/yoga/enums/Errata.h @@ -18,7 +18,7 @@ namespace facebook::yoga { enum class Errata : uint32_t { None = YGErrataNone, StretchFlexBasis = YGErrataStretchFlexBasis, - AbsolutePositioningIncorrect = YGErrataAbsolutePositioningIncorrect, + AbsolutePositionWithoutInsetsExcludesPadding = YGErrataAbsolutePositionWithoutInsetsExcludesPadding, AbsolutePercentAgainstInnerSize = YGErrataAbsolutePercentAgainstInnerSize, All = YGErrataAll, Classic = YGErrataClassic, diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h b/packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h new file mode 100644 index 00000000000000..7d5598fb04f8c8 --- /dev/null +++ b/packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h @@ -0,0 +1,151 @@ +/* + * 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. + */ +#pragma once + +#include +#include + +#include + +namespace facebook::yoga { + +class Node; + +template +class LayoutableChildren { + public: + using Backtrack = std::vector>; + 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::Iterator>); + static_assert( + std::is_base_of::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 diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp index 7c6bea55e3cfe7..cf36ab09a49ea3 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp @@ -41,6 +41,7 @@ Node::Node(Node&& node) noexcept style_(std::move(node.style_)), layout_(node.layout_), lineIndex_(node.lineIndex_), + contentsChildrenCount_(node.contentsChildrenCount_), owner_(node.owner_), children_(std::move(node.children_)), config_(node.config_), @@ -116,14 +117,37 @@ void Node::setMeasureFunc(YGMeasureFunc measureFunc) { } 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; } 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); } void Node::insertChild(Node* child, size_t index) { + if (child->style().display() == Display::Contents) { + contentsChildrenCount_++; + } + children_.insert(children_.begin() + static_cast(index), child); } @@ -160,6 +184,10 @@ void Node::setDirty(bool isDirty) { bool Node::removeChild(Node* child) { auto p = std::find(children_.begin(), children_.end(), child); if (p != children_.end()) { + if (child->style().display() == Display::Contents) { + contentsChildrenCount_--; + } + children_.erase(p); return true; } @@ -167,6 +195,10 @@ bool Node::removeChild(Node* child) { } void Node::removeChild(size_t index) { + if (children_[index]->style().display() == Display::Contents) { + contentsChildrenCount_--; + } + children_.erase(children_.begin() + static_cast(index)); } diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.h b/packages/react-native/ReactCommon/yoga/yoga/node/Node.h index 34ef6d955ed8da..d596c564cf26e6 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.h +++ b/packages/react-native/ReactCommon/yoga/yoga/node/Node.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -31,6 +32,7 @@ namespace facebook::yoga { class YG_EXPORT Node : public ::YGNode { public: + using LayoutableChildren = yoga::LayoutableChildren; Node(); explicit Node(const Config* config); @@ -144,6 +146,24 @@ class YG_EXPORT Node : public ::YGNode { 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 { return config_; } @@ -298,6 +318,7 @@ class YG_EXPORT Node : public ::YGNode { Style style_; LayoutResults layout_; size_t lineIndex_ = 0; + size_t contentsChildrenCount_ = 0; Node* owner_ = nullptr; std::vector children_; const Config* config_; diff --git a/packages/react-native/cli.js b/packages/react-native/cli.js index 23a9f1779ac60a..30228c5a84e07a 100755 --- a/packages/react-native/cli.js +++ b/packages/react-native/cli.js @@ -12,10 +12,10 @@ const {name, version: currentVersion} = require('./package.json'); const chalk = require('chalk'); +const {spawn} = require('child_process'); const {get} = require('https'); const semver = require('semver'); const {URL} = require('url'); -const {spawn} = require('child_process'); const deprecated = () => { throw new Error( diff --git a/packages/react-native/gradle/libs.versions.toml b/packages/react-native/gradle/libs.versions.toml index 7896d2a1b208bb..fe9098e2af2dd8 100644 --- a/packages/react-native/gradle/libs.versions.toml +++ b/packages/react-native/gradle/libs.versions.toml @@ -4,7 +4,7 @@ minSdk = "24" targetSdk = "34" compileSdk = "35" buildTools = "35.0.0" -ndkVersion = "26.1.10909125" +ndkVersion = "27.1.12297006" # Dependencies versions agp = "8.7.1" androidx-annotation = "1.6.0" @@ -35,8 +35,9 @@ yoga-proguard-annotations = "1.19.0" # Native Dependencies boost="1_83_0" doubleconversion="1.1.6" -fmt="9.1.0" -folly="2024.01.01.00" +fastFloat="6.1.4" +fmt="11.0.2" +folly="2024.10.14.00" glog="0.3.5" gtest="1.12.1" diff --git a/packages/react-native/index.js b/packages/react-native/index.js index b0291e4a99aa8a..99a5a5ee17bda2 100644 --- a/packages/react-native/index.js +++ b/packages/react-native/index.js @@ -88,7 +88,6 @@ import typeof UTFSequence from './Libraries/UTFSequence'; import typeof * as Appearance from './Libraries/Utilities/Appearance'; import typeof BackHandler from './Libraries/Utilities/BackHandler'; import typeof DeviceInfo from './Libraries/Utilities/DeviceInfo'; -import typeof DevMenu from './src/private/devmenu/DevMenu'; import typeof DevSettings from './Libraries/Utilities/DevSettings'; import typeof Dimensions from './Libraries/Utilities/Dimensions'; import typeof PixelRatio from './Libraries/Utilities/PixelRatio'; @@ -97,6 +96,7 @@ import typeof useColorScheme from './Libraries/Utilities/useColorScheme'; import typeof useWindowDimensions from './Libraries/Utilities/useWindowDimensions'; import typeof Vibration from './Libraries/Vibration/Vibration'; import typeof YellowBox from './Libraries/YellowBox/YellowBoxDeprecated'; +import typeof DevMenu from './src/private/devmenu/DevMenu'; const warnOnce = require('./Libraries/Utilities/warnOnce'); const invariant = require('invariant'); @@ -375,7 +375,7 @@ module.exports = { get processColor(): processColor { return require('./Libraries/StyleSheet/processColor').default; }, - get requireNativeComponent(): ( + get requireNativeComponent(): ( uiViewClassName: string, ) => HostComponent { return require('./Libraries/ReactNative/requireNativeComponent').default; diff --git a/packages/react-native/jest/setup.js b/packages/react-native/jest/setup.js index 667100ed83e1f2..9714d2d73de5ad 100644 --- a/packages/react-native/jest/setup.js +++ b/packages/react-native/jest/setup.js @@ -146,6 +146,7 @@ jest remove: jest.fn(), })), announceForAccessibility: jest.fn(), + announceForAccessibilityWithOptions: jest.fn(), isAccessibilityServiceEnabled: jest.fn(() => Promise.resolve(false)), isBoldTextEnabled: jest.fn(() => Promise.resolve(false)), isGrayscaleEnabled: jest.fn(() => Promise.resolve(false)), diff --git a/packages/react-native/scripts/cocoapods/__tests__/codegen_utils-test.rb b/packages/react-native/scripts/cocoapods/__tests__/codegen_utils-test.rb index 02137db81457ec..48317e230256b7 100644 --- a/packages/react-native/scripts/cocoapods/__tests__/codegen_utils-test.rb +++ b/packages/react-native/scripts/cocoapods/__tests__/codegen_utils-test.rb @@ -523,13 +523,12 @@ def get_podspec_no_fabric_no_script "\"$(PODS_ROOT)/boost\"", "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"", "\"${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\"", "\"$(PODS_ROOT)/Headers/Private/React-Fabric\"", "\"$(PODS_ROOT)/Headers/Private/React-RCTFabric\"", "\"$(PODS_ROOT)/Headers/Private/Yoga\"", - "\"$(PODS_ROOT)/DoubleConversion\"", - "\"$(PODS_ROOT)/fmt/include\"", "\"$(PODS_TARGET_SRCROOT)\"", ].join(' ') }, diff --git a/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb b/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb index 328a705b8dc758..677fe99d185c3b 100644 --- a/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb +++ b/packages/react-native/scripts/cocoapods/__tests__/new_architecture-test.rb @@ -144,21 +144,21 @@ def test_installModulesDependencies_whenNewArchEnabledAndNewArchAndNoSearchPaths spec = SpecMock.new # Act - NewArchitectureHelper.install_modules_dependencies(spec, true, '2024.01.01.00') + NewArchitectureHelper.install_modules_dependencies(spec, true, '2024.10.14.00') # Assert folly_config = Helpers::Constants.folly_config folly_compiler_flags = folly_config[:compiler_flags] assert_equal(spec.compiler_flags, "-DRCT_NEW_ARCH_ENABLED=1 #{NewArchitectureHelper.folly_compiler_flags}") - assert_equal(spec.pod_target_xcconfig["HEADER_SEARCH_PATHS"], "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/Headers/Private/Yoga\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/components/view/platform/cxx\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-FabricImage/React_FabricImage.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-NativeModulesApple/React_NativeModulesApple.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-utils/React_utils.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-featureflags/React_featureflags.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-ImageManager/React_ImageManager.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-rendererdebug/React_rendererdebug.framework/Headers\"") + assert_equal(spec.pod_target_xcconfig["HEADER_SEARCH_PATHS"], "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/Headers/Private/Yoga\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/components/view/platform/cxx\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-FabricImage/React_FabricImage.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-NativeModulesApple/React_NativeModulesApple.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-utils/React_utils.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-featureflags/React_featureflags.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-ImageManager/React_ImageManager.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-rendererdebug/React_rendererdebug.framework/Headers\"") assert_equal(spec.pod_target_xcconfig["CLANG_CXX_LANGUAGE_STANDARD"], "c++20") assert_equal(spec.pod_target_xcconfig["OTHER_CPLUSPLUSFLAGS"], "$(inherited) -DRCT_NEW_ARCH_ENABLED=1 "+ folly_compiler_flags) assert_equal( spec.dependencies, [ { :dependency_name => "React-Core" }, - { :dependency_name => "RCT-Folly", "version"=>"2024.01.01.00" }, + { :dependency_name => "RCT-Folly", "version"=>"2024.10.14.00" }, { :dependency_name => "glog" }, { :dependency_name => "React-RCTFabric" }, { :dependency_name => "ReactCodegen" }, @@ -190,17 +190,17 @@ def test_installModulesDependencies_whenNewArchDisabledAndSearchPathsAndCompiler } # Act - NewArchitectureHelper.install_modules_dependencies(spec, false, '2024.01.01.00') + NewArchitectureHelper.install_modules_dependencies(spec, false, '2024.10.14.00') # Assert assert_equal(Helpers::Constants.folly_config[:compiler_flags], "#{NewArchitectureHelper.folly_compiler_flags}") - assert_equal(spec.pod_target_xcconfig["HEADER_SEARCH_PATHS"], "#{other_flags} \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/Headers/Private/Yoga\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/components/view/platform/cxx\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-FabricImage/React_FabricImage.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-NativeModulesApple/React_NativeModulesApple.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-utils/React_utils.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-featureflags/React_featureflags.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-ImageManager/React_ImageManager.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-rendererdebug/React_rendererdebug.framework/Headers\"") + assert_equal(spec.pod_target_xcconfig["HEADER_SEARCH_PATHS"], "#{other_flags} \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/Headers/Private/Yoga\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/components/view/platform/cxx\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-FabricImage/React_FabricImage.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-NativeModulesApple/React_NativeModulesApple.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-utils/React_utils.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-featureflags/React_featureflags.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-ImageManager/React_ImageManager.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-rendererdebug/React_rendererdebug.framework/Headers\"") assert_equal(spec.pod_target_xcconfig["CLANG_CXX_LANGUAGE_STANDARD"], "c++20") assert_equal( spec.dependencies, [ { :dependency_name => "React-Core" }, - { :dependency_name => "RCT-Folly", "version"=>"2024.01.01.00" }, + { :dependency_name => "RCT-Folly", "version"=>"2024.10.14.00" }, { :dependency_name => "glog" }, { :dependency_name => "React-RCTFabric" }, { :dependency_name => "ReactCodegen" }, diff --git a/packages/react-native/scripts/cocoapods/__tests__/utils-test.rb b/packages/react-native/scripts/cocoapods/__tests__/utils-test.rb index 92c472f79292c1..4ddc0c60b8024c 100644 --- a/packages/react-native/scripts/cocoapods/__tests__/utils-test.rb +++ b/packages/react-native/scripts/cocoapods/__tests__/utils-test.rb @@ -800,7 +800,7 @@ def test_updateSearchPaths_whenUseFrameworks_addsSearchPaths if pod_name == "SecondTarget" target_installation_result.native_target.build_configurations.each do |config| received_search_path = config.build_settings["HEADER_SEARCH_PATHS"] - expected_Search_path = "$(inherited) \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\" \"$(PODS_ROOT)/boost\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCodegen/ReactCodegen.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/components/view/platform/cxx\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-FabricImage/React_FabricImage.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Graphics/React_graphics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/imagemanager/platform/ios\"" + expected_Search_path = "$(inherited) \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\" \"$(PODS_ROOT)/boost\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCodegen/ReactCodegen.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/components/view/platform/cxx\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-FabricImage/React_FabricImage.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Graphics/React_graphics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/imagemanager/platform/ios\"" assert_equal(received_search_path, expected_Search_path) end else diff --git a/packages/react-native/scripts/cocoapods/codegen_utils.rb b/packages/react-native/scripts/cocoapods/codegen_utils.rb index 3cb9bb1e6ef5ee..3c2aca4f0581d1 100644 --- a/packages/react-native/scripts/cocoapods/codegen_utils.rb +++ b/packages/react-native/scripts/cocoapods/codegen_utils.rb @@ -81,13 +81,12 @@ def get_react_codegen_spec(package_json_file, folly_version: get_folly_config()[ "\"$(PODS_ROOT)/boost\"", "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"", "\"${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\"", "\"$(PODS_ROOT)/Headers/Private/React-Fabric\"", "\"$(PODS_ROOT)/Headers/Private/React-RCTFabric\"", "\"$(PODS_ROOT)/Headers/Private/Yoga\"", - "\"$(PODS_ROOT)/DoubleConversion\"", - "\"$(PODS_ROOT)/fmt/include\"", "\"$(PODS_TARGET_SRCROOT)\"", ] framework_search_paths = [] diff --git a/packages/react-native/scripts/cocoapods/helpers.rb b/packages/react-native/scripts/cocoapods/helpers.rb index 762d7226e8341b..35d5635388194f 100644 --- a/packages/react-native/scripts/cocoapods/helpers.rb +++ b/packages/react-native/scripts/cocoapods/helpers.rb @@ -47,12 +47,16 @@ class Constants } @@folly_config = { - :version => '2024.01.01.00', + :version => '2024.10.14.00', :git => 'https://github.com/facebook/folly.git', :compiler_flags => '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_CFG_NO_COROUTINES=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 -Wno-comma -Wno-shorten-64-to-32', :dep_name => 'RCT-Folly/Fabric' } + @@fast_float_config = { + :git => "https://github.com/fastfloat/fast_float.git", + } + @@fmt_config = { :git => "https://github.com/fmtlib/fmt.git", } @@ -97,6 +101,14 @@ def self.set_socket_rocket_config(new_socket_rocket_config) @@socket_rocket_config.update(new_socket_rocket_config) end + def self.fast_float_config + return @@fast_float_config + end + + def self.set_fast_float_config(new_fast_float_config) + @@fast_float_config.update(new_fast_float_config) + end + def self.fmt_config return @@fmt_config end diff --git a/packages/react-native/scripts/cocoapods/new_architecture.rb b/packages/react-native/scripts/cocoapods/new_architecture.rb index f866ef411a38a3..802f6416c768a8 100644 --- a/packages/react-native/scripts/cocoapods/new_architecture.rb +++ b/packages/react-native/scripts/cocoapods/new_architecture.rb @@ -83,6 +83,7 @@ def self.install_modules_dependencies(spec, new_arch_enabled, folly_version = ge header_search_paths = ["\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/Headers/Private/Yoga\""] if ENV['USE_FRAMEWORKS'] header_search_paths << "\"$(PODS_ROOT)/DoubleConversion\"" + header_search_paths << "\"$(PODS_ROOT)/fast_float/include\"" header_search_paths << "\"$(PODS_ROOT)/fmt/include\"" ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-graphics", "React_graphics", ["react/renderer/graphics/platform/ios"]) .concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-Fabric", "React_Fabric", ["react/renderer/components/view/platform/cxx"])) diff --git a/packages/react-native/scripts/cocoapods/utils.rb b/packages/react-native/scripts/cocoapods/utils.rb index 510e084f600ec6..07d866b438cd41 100644 --- a/packages/react-native/scripts/cocoapods/utils.rb +++ b/packages/react-native/scripts/cocoapods/utils.rb @@ -564,6 +564,7 @@ def self.set_rctfolly_search_paths(target_installation_result) ReactNativePodsUtils.update_header_paths_if_depends_on(target_installation_result, "RCT-Folly", [ "\"$(PODS_ROOT)/RCT-Folly\"", "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fast_float/include\"", "\"$(PODS_ROOT)/fmt/include\"", "\"$(PODS_ROOT)/boost\"" ]) @@ -639,6 +640,7 @@ def self.react_native_pods "ReactCommon", "Yoga", "boost", + "fast_float", "fmt", "glog", "hermes-engine", diff --git a/packages/react-native/scripts/codegen/generate-artifacts-executor.js b/packages/react-native/scripts/codegen/generate-artifacts-executor.js index 8e89bf0007ffb7..d9af18b0806b8b 100644 --- a/packages/react-native/scripts/codegen/generate-artifacts-executor.js +++ b/packages/react-native/scripts/codegen/generate-artifacts-executor.js @@ -519,11 +519,22 @@ function rootCodegenTargetNeedsThirdPartyComponentProvider(pkgJson, platform) { return !pkgJsonIncludesGeneratedCode(pkgJson) && platform === 'ios'; } -function dependencyNeedsThirdPartyComponentProvider(schemaInfo, platform) { +function dependencyNeedsThirdPartyComponentProvider( + schemaInfo, + platform, + appCondegenConfigSpec, +) { // Filter the react native core library out. // In the future, core library and third party library should // use the same way to generate/register the fabric components. - return !isReactNativeCoreLibrary(schemaInfo.library.config.name, platform); + // We also have to filter out the the components defined in the app + // because the RCTThirdPartyComponentProvider is generated inside Fabric, + // which lives in a different target from the app and it has no visibility over + // the symbols defined in the app. + return ( + !isReactNativeCoreLibrary(schemaInfo.library.config.name, platform) && + schemaInfo.library.config.name !== appCondegenConfigSpec + ); } function mustGenerateNativeCode(includeLibraryPath, schemaInfo) { @@ -732,8 +743,12 @@ function execute(projectRoot, targetPlatform, baseOutputPath) { if ( rootCodegenTargetNeedsThirdPartyComponentProvider(pkgJson, platform) ) { - const filteredSchemas = schemaInfos.filter( - dependencyNeedsThirdPartyComponentProvider, + const filteredSchemas = schemaInfos.filter(schemaInfo => + dependencyNeedsThirdPartyComponentProvider( + schemaInfo, + platform, + pkgJson.codegenConfig?.appCondegenConfigSpec, + ), ); const schemas = filteredSchemas.map(schemaInfo => schemaInfo.schema); const supportedApplePlatforms = filteredSchemas.map( diff --git a/packages/react-native/scripts/featureflags/README.md b/packages/react-native/scripts/featureflags/README.md index b39adfbda6ab4a..7f774a944c436d 100644 --- a/packages/react-native/scripts/featureflags/README.md +++ b/packages/react-native/scripts/featureflags/README.md @@ -18,14 +18,14 @@ Example contents: ```javascript module.exports = { common: { - enableMicrotasks: { - description: 'Enable the use of microtasks in the JS runtime.', + enableNativeBehavior: { + description: 'Enable some behavior both in native and in JS.', defaultValue: false } }, jsOnly: { - enableAccessToHostTreeInFabric: { - description: 'Enables access to the host tree in Fabric using DOM-compatible APIs.', + enableJSBehavior: { + description: 'Enables some behavior in the JS layer.', defaultValue: false } } @@ -57,7 +57,7 @@ from JavaScript. ```c++ #include -if (ReactNativeFeatureFlags::enableMicrotasks()) { +if (ReactNativeFeatureFlags::enableNativeBehavior()) { // do something } ``` @@ -68,7 +68,7 @@ if (ReactNativeFeatureFlags::enableMicrotasks()) { import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags fun someMethod() { - if (ReactNativeFeatureFlags.enableMicrotasks()) { + if (ReactNativeFeatureFlags.enableNativeBehavior()) { // do something } } @@ -79,11 +79,11 @@ fun someMethod() { ```javascript import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags'; -if (ReactNativeFeatureFlags.enableMicrotasks()) { +if (ReactNativeFeatureFlags.enableNativeBehavior()) { // Native flag } -if (ReactNativeFeatureFlags.enableAccessToHostTreeInFabric()) { +if (ReactNativeFeatureFlags.enableJSBehavior()) { // JS-only flag } ``` @@ -109,7 +109,7 @@ class CustomReactNativeFeatureFlags : public ReactNativeFeatureFlagsDefaults { public: CustomReactNativeFeatureFlags(); - bool enableMicrotasks() override { + bool enableNativeBehavior() override { return true; } } @@ -136,7 +136,7 @@ fun overrideFeatureFlags() { import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags'; ReactNativeFeatureFlags.override({ - enableAccessToHostTreeInFabric: () => true, + enableJSBehavior: () => true, }); ``` diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 80fa246f9c6f4e..fe6354d088be45 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -30,6 +30,15 @@ const testDefinitions: FeatureFlagDefinitions = { purpose: 'operational', }, }, + commonTestFlagWithoutNativeImplementation: { + defaultValue: false, + metadata: { + description: + 'Common flag for testing (without native implementation). Do NOT modify.', + purpose: 'operational', + }, + skipNativeAPI: true, + }, }, jsOnly: { jsOnlyTestFlag: { @@ -61,6 +70,8 @@ const definitions: FeatureFlagDefinitions = { 'When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.', purpose: 'release', }, + // We're preparing to clean up this feature flag. + skipNativeAPI: true, }, completeReactInstanceCreationOnBgThreadOnAndroid: { defaultValue: false, @@ -71,6 +82,14 @@ const definitions: FeatureFlagDefinitions = { purpose: 'experimentation', }, }, + disableEventLoopOnBridgeless: { + defaultValue: false, + metadata: { + description: + 'The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances.', + purpose: 'release', + }, + }, enableAlignItemsBaselineOnFabricIOS: { defaultValue: true, metadata: { @@ -105,6 +124,15 @@ const definitions: FeatureFlagDefinitions = { purpose: 'experimentation', }, }, + enableCppPropsIteratorSetter: { + defaultValue: false, + metadata: { + dateAdded: '2024-09-13', + description: + 'Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java).', + purpose: 'experimentation', + }, + }, enableDeletionOfUnmountedViews: { defaultValue: false, metadata: { @@ -202,6 +230,17 @@ const definitions: FeatureFlagDefinitions = { 'Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).', purpose: 'release', }, + // We're preparing to clean up this feature flag. + skipNativeAPI: true, + }, + enableNewBackgroundAndBorderDrawables: { + defaultValue: false, + metadata: { + dateAdded: '2024-09-24', + description: + 'Use BackgroundDrawable and BorderDrawable instead of CSSBackgroundDrawable', + purpose: 'experimentation', + }, }, enablePreciseSchedulingForPremountItemsOnAndroid: { defaultValue: false, @@ -384,6 +423,8 @@ const definitions: FeatureFlagDefinitions = { 'When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread.', purpose: 'release', }, + // We're preparing to clean up this feature flag. + skipNativeAPI: true, }, useNativeViewConfigsInBridgelessMode: { defaultValue: false, diff --git a/packages/react-native/scripts/featureflags/generateFiles.js b/packages/react-native/scripts/featureflags/generateFiles.js index 8f155b1350aeb5..b466b8cd667dfa 100644 --- a/packages/react-native/scripts/featureflags/generateFiles.js +++ b/packages/react-native/scripts/featureflags/generateFiles.js @@ -28,11 +28,31 @@ export default function generateFiles( const jsModules = generateJavaScriptModules(generatorConfig); - const commonCxxModules = generateCommonCxxModules(generatorConfig); + const generatorConfigWithDefinitionsForNative = { + ...generatorConfig, + featureFlagDefinitions: { + ...generatorConfig.featureFlagDefinitions, + common: Object.fromEntries( + Object.entries(generatorConfig.featureFlagDefinitions.common).filter( + ([_, definition]) => !definition.skipNativeAPI, + ), + ), + }, + }; - const androidModules = generateAndroidModules(generatorConfig); + const commonCxxModules = generateCommonCxxModules( + generatorConfigWithDefinitionsForNative, + ); - const generatedFiles = {...jsModules, ...commonCxxModules, ...androidModules}; + const androidModules = generateAndroidModules( + generatorConfigWithDefinitionsForNative, + ); + + const generatedFiles = { + ...jsModules, + ...commonCxxModules, + ...androidModules, + }; if (generatorOptions.verifyUnchanged) { const existingModules: {[string]: string} = {}; diff --git a/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.cpp-template.js b/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.cpp-template.js index 74be22c0dc43bd..ade547e49d9353 100644 --- a/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.cpp-template.js +++ b/packages/react-native/scripts/featureflags/templates/js/NativeReactNativeFeatureFlags.cpp-template.js @@ -46,11 +46,19 @@ NativeReactNativeFeatureFlags::NativeReactNativeFeatureFlags( : NativeReactNativeFeatureFlagsCxxSpec(std::move(jsInvoker)) {} ${Object.entries(definitions.common) - .map( - ([flagName, flagConfig]) => - `${getCxxTypeFromDefaultValue( - flagConfig.defaultValue, - )} NativeReactNativeFeatureFlags::${flagName}( + .map(([flagName, flagConfig]) => + flagConfig.skipNativeAPI + ? `${getCxxTypeFromDefaultValue( + flagConfig.defaultValue, + )} NativeReactNativeFeatureFlags::${flagName}( + jsi::Runtime& /*runtime*/) { + // This flag is configured with \`skipNativeAPI: true\`. + // TODO(T204838867): Implement support for optional methods in C++ TM codegen and remove the method definition altogether. + return ${JSON.stringify(flagConfig.defaultValue)}; +}` + : `${getCxxTypeFromDefaultValue( + flagConfig.defaultValue, + )} NativeReactNativeFeatureFlags::${flagName}( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::${flagName}(); }`, diff --git a/packages/react-native/scripts/featureflags/types.js b/packages/react-native/scripts/featureflags/types.js index 3c5af96fb1305c..1e328087159714 100644 --- a/packages/react-native/scripts/featureflags/types.js +++ b/packages/react-native/scripts/featureflags/types.js @@ -11,30 +11,42 @@ export type FeatureFlagValue = boolean | number | string; export type FeatureFlagDefinitions = { - common: FeatureFlagList, - jsOnly: FeatureFlagList, + common: CommonFeatureFlagList, + jsOnly: JsOnlyFeatureFlagList, }; -type FeatureFlagList = { +type CommonFeatureFlagList = { [flagName: string]: { defaultValue: FeatureFlagValue, - metadata: - | { - purpose: 'experimentation', - /** - * Aproximate date when the flag was added. - * Used to help prioritize feature flags that need to be cleaned up. - */ - dateAdded: string, - description: string, - } - | { - purpose: 'operational' | 'release', - description: string, - }, + metadata: FeatureFlagMetadata, + // Indicates if this API should only be defined in JavaScript, only to + // preserve backwards compatibility with existing native code temporarily. + skipNativeAPI?: true, }, }; +type JsOnlyFeatureFlagList = { + [flagName: string]: { + defaultValue: FeatureFlagValue, + metadata: FeatureFlagMetadata, + }, +}; + +type FeatureFlagMetadata = + | { + purpose: 'experimentation', + /** + * Aproximate date when the flag was added. + * Used to help prioritize feature flags that need to be cleaned up. + */ + dateAdded: string, + description: string, + } + | { + purpose: 'operational' | 'release', + description: string, + }; + export type GeneratorConfig = { featureFlagDefinitions: FeatureFlagDefinitions, jsPath: string, diff --git a/packages/react-native/scripts/react_native_pods.rb b/packages/react-native/scripts/react_native_pods.rb index 221635d4edd1de..14cb67b102d7dd 100644 --- a/packages/react-native/scripts/react_native_pods.rb +++ b/packages/react-native/scripts/react_native_pods.rb @@ -156,6 +156,7 @@ def use_react_native! ( pod 'DoubleConversion', :podspec => "#{prefix}/third-party-podspecs/DoubleConversion.podspec" pod 'glog', :podspec => "#{prefix}/third-party-podspecs/glog.podspec" pod 'boost', :podspec => "#{prefix}/third-party-podspecs/boost.podspec" + pod 'fast_float', :podspec => "#{prefix}/third-party-podspecs/fast_float.podspec" pod 'fmt', :podspec => "#{prefix}/third-party-podspecs/fmt.podspec" pod 'RCT-Folly', :podspec => "#{prefix}/third-party-podspecs/RCT-Folly.podspec", :modular_headers => true @@ -280,6 +281,13 @@ def get_glog_config() return Helpers::Constants.glog_config end +# This method returns an hash with the fast_float git url +# that can be used to configure libraries. +# @return an hash with the `:git` field. +def get_fast_float_config() + return Helpers::Constants.fast_float_config +end + # This method returns an hash with the fmt git url # that can be used to configure libraries. # @return an hash with the `:git` field. @@ -319,6 +327,12 @@ def set_glog_config(glog_config) Helpers::Constants.set_glog_config(glog_config) end +# This method can be used to set the fast_float config +# that can be used to configure libraries. +def set_fast_float_config(fmt_config) + Helpers::Constants.set_fast_float_config(fast_float_config) +end + # This method can be used to set the fmt config # that can be used to configure libraries. def set_fmt_config(fmt_config) diff --git a/packages/react-native/src/private/animated/NativeAnimatedHelper.js b/packages/react-native/src/private/animated/NativeAnimatedHelper.js index 0c8388ae4b41f2..9ef311408a894c 100644 --- a/packages/react-native/src/private/animated/NativeAnimatedHelper.js +++ b/packages/react-native/src/private/animated/NativeAnimatedHelper.js @@ -8,7 +8,6 @@ * @format */ -import type {EventSubscription} from '../../../Libraries/vendor/emitter/EventEmitter'; import type {EventConfig} from '../../../Libraries/Animated/AnimatedEvent'; import type { AnimationConfig, @@ -18,13 +17,14 @@ import type { AnimatedNodeConfig, EventMapping, } from '../../../Libraries/Animated/NativeAnimatedModule'; +import type {EventSubscription} from '../../../Libraries/vendor/emitter/EventEmitter'; -import * as ReactNativeFeatureFlags from '../featureflags/ReactNativeFeatureFlags'; +import NativeAnimatedNonTurboModule from '../../../Libraries/Animated/NativeAnimatedModule'; +import NativeAnimatedTurboModule from '../../../Libraries/Animated/NativeAnimatedTurboModule'; import NativeEventEmitter from '../../../Libraries/EventEmitter/NativeEventEmitter'; import RCTDeviceEventEmitter from '../../../Libraries/EventEmitter/RCTDeviceEventEmitter'; import Platform from '../../../Libraries/Utilities/Platform'; -import NativeAnimatedNonTurboModule from '../../../Libraries/Animated/NativeAnimatedModule'; -import NativeAnimatedTurboModule from '../../../Libraries/Animated/NativeAnimatedTurboModule'; +import * as ReactNativeFeatureFlags from '../featureflags/ReactNativeFeatureFlags'; import invariant from 'invariant'; import nullthrows from 'nullthrows'; diff --git a/packages/react-native/src/private/animated/__tests__/useAnimatedPropsMemo-test.js b/packages/react-native/src/private/animated/__tests__/useAnimatedPropsMemo-test.js index dbf696efa6d501..40c1c2c2f99f1b 100644 --- a/packages/react-native/src/private/animated/__tests__/useAnimatedPropsMemo-test.js +++ b/packages/react-native/src/private/animated/__tests__/useAnimatedPropsMemo-test.js @@ -12,8 +12,8 @@ import {AnimatedEvent} from '../../../../Libraries/Animated/AnimatedEvent'; import AnimatedValue from '../../../../Libraries/Animated/nodes/AnimatedValue'; import { - createCompositeKeyForProps, areCompositeKeysEqual, + createCompositeKeyForProps, } from '../useAnimatedPropsMemo'; describe('createCompositeKeyForProps', () => { diff --git a/packages/react-native/src/private/animated/useAnimatedPropsMemo.js b/packages/react-native/src/private/animated/useAnimatedPropsMemo.js index d3806ec44273a1..b0a9319cbe850e 100644 --- a/packages/react-native/src/private/animated/useAnimatedPropsMemo.js +++ b/packages/react-native/src/private/animated/useAnimatedPropsMemo.js @@ -17,7 +17,6 @@ import {AnimatedEvent} from '../../../Libraries/Animated/AnimatedEvent'; import AnimatedNode from '../../../Libraries/Animated/nodes/AnimatedNode'; import {isPlainObject} from '../../../Libraries/Animated/nodes/AnimatedObject'; import flattenStyle from '../../../Libraries/StyleSheet/flattenStyle'; - import nullthrows from 'nullthrows'; import {useMemo, useState} from 'react'; diff --git a/packages/react-native/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js b/packages/react-native/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js index a3324550c812ed..e06b2899b64ee7 100644 --- a/packages/react-native/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js +++ b/packages/react-native/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js @@ -10,15 +10,16 @@ */ import type {ViewProps} from '../../../Libraries/Components/View/ViewPropTypes'; -import Platform from '../../../Libraries/Utilities/Platform'; + import View from '../../../Libraries/Components/View/View'; import UIManager from '../../../Libraries/ReactNative/UIManager'; +import Platform from '../../../Libraries/Utilities/Platform'; import * as React from 'react'; -const exported: React.AbstractComponent< - ViewProps, - React.ElementRef, -> = Platform.select({ +const exported: component( + ref?: React.RefSetter>, + ...ViewProps +) = Platform.select({ ios: require('../../../src/private/specs/components/RCTSafeAreaViewNativeComponent') .default, android: UIManager.hasViewManagerConfig('RCTSafeAreaView') diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 05ad73e441c09a..0f17ec52578f00 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5f8a62b797980987ce7f415fa00c0965>> + * @generated SignedSource<> * @flow strict */ @@ -51,13 +51,16 @@ export type ReactNativeFeatureFlagsJsOnlyOverrides = OverridesFor, + commonTestFlagWithoutNativeImplementation: Getter, allowRecursiveCommitsWithSynchronousMountOnAndroid: Getter, batchRenderingUpdatesInEventLoop: Getter, completeReactInstanceCreationOnBgThreadOnAndroid: Getter, + disableEventLoopOnBridgeless: Getter, enableAlignItemsBaselineOnFabricIOS: Getter, enableAndroidLineHeightCentering: Getter, enableBridgelessArchitecture: Getter, enableCleanTextInputYogaNode: Getter, + enableCppPropsIteratorSetter: Getter, enableDeletionOfUnmountedViews: Getter, enableEagerRootViewAttachment: Getter, enableEventEmitterRetentionDuringGesturesOnAndroid: Getter, @@ -70,6 +73,7 @@ export type ReactNativeFeatureFlags = { enableLayoutAnimationsOnIOS: Getter, enableLongTaskAPI: Getter, enableMicrotasks: Getter, + enableNewBackgroundAndBorderDrawables: Getter, enablePreciseSchedulingForPremountItemsOnAndroid: Getter, enablePropsUpdateReconciliationAndroid: Getter, enableReportEventPaintTime: Getter, @@ -188,6 +192,10 @@ export const useRefsForTextInputState: Getter = createJavaScriptFlagGet * Common flag for testing. Do NOT modify. */ export const commonTestFlag: Getter = createNativeFlagGetter('commonTestFlag', false); +/** + * Common flag for testing (without native implementation). Do NOT modify. + */ +export const commonTestFlagWithoutNativeImplementation: Getter = createNativeFlagGetter('commonTestFlagWithoutNativeImplementation', false); /** * Adds support for recursively processing commits that mount synchronously (Android only). */ @@ -200,6 +208,10 @@ export const batchRenderingUpdatesInEventLoop: Getter = createNativeFla * Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android */ export const completeReactInstanceCreationOnBgThreadOnAndroid: Getter = createNativeFlagGetter('completeReactInstanceCreationOnBgThreadOnAndroid', false); +/** + * The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances. + */ +export const disableEventLoopOnBridgeless: Getter = createNativeFlagGetter('disableEventLoopOnBridgeless', false); /** * Kill-switch to turn off support for aling-items:baseline on Fabric iOS. */ @@ -216,6 +228,10 @@ export const enableBridgelessArchitecture: Getter = createNativeFlagGet * Clean yoga node when does not change. */ export const enableCleanTextInputYogaNode: Getter = createNativeFlagGetter('enableCleanTextInputYogaNode', false); +/** + * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). + */ +export const enableCppPropsIteratorSetter: Getter = createNativeFlagGetter('enableCppPropsIteratorSetter', false); /** * Deletes views that were pre-allocated but never mounted on the screen. */ @@ -264,6 +280,10 @@ export const enableLongTaskAPI: Getter = createNativeFlagGetter('enable * Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution). */ export const enableMicrotasks: Getter = createNativeFlagGetter('enableMicrotasks', false); +/** + * Use BackgroundDrawable and BorderDrawable instead of CSSBackgroundDrawable + */ +export const enableNewBackgroundAndBorderDrawables: Getter = createNativeFlagGetter('enableNewBackgroundAndBorderDrawables', false); /** * Moves execution of pre-mount items to outside the choregrapher in the main thread, so we can estimate idle time more precisely (Android only). */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 4f8dac8cbc202f..1632204d2a9d1d 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2dea79097b1952f97d9e5dda86a38e58>> + * @generated SignedSource<<8472e224a5a49da4d706820c89262b6b>> * @flow strict */ @@ -24,13 +24,16 @@ import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboMod export interface Spec extends TurboModule { +commonTestFlag?: () => boolean; + +commonTestFlagWithoutNativeImplementation?: () => boolean; +allowRecursiveCommitsWithSynchronousMountOnAndroid?: () => boolean; +batchRenderingUpdatesInEventLoop?: () => boolean; +completeReactInstanceCreationOnBgThreadOnAndroid?: () => boolean; + +disableEventLoopOnBridgeless?: () => boolean; +enableAlignItemsBaselineOnFabricIOS?: () => boolean; +enableAndroidLineHeightCentering?: () => boolean; +enableBridgelessArchitecture?: () => boolean; +enableCleanTextInputYogaNode?: () => boolean; + +enableCppPropsIteratorSetter?: () => boolean; +enableDeletionOfUnmountedViews?: () => boolean; +enableEagerRootViewAttachment?: () => boolean; +enableEventEmitterRetentionDuringGesturesOnAndroid?: () => boolean; @@ -43,6 +46,7 @@ export interface Spec extends TurboModule { +enableLayoutAnimationsOnIOS?: () => boolean; +enableLongTaskAPI?: () => boolean; +enableMicrotasks?: () => boolean; + +enableNewBackgroundAndBorderDrawables?: () => boolean; +enablePreciseSchedulingForPremountItemsOnAndroid?: () => boolean; +enablePropsUpdateReconciliationAndroid?: () => boolean; +enableReportEventPaintTime?: () => boolean; diff --git a/packages/react-native/src/private/specs/modules/NativeExceptionsManager.js b/packages/react-native/src/private/specs/modules/NativeExceptionsManager.js index 1da0633dc17db1..0b684c681e7071 100644 --- a/packages/react-native/src/private/specs/modules/NativeExceptionsManager.js +++ b/packages/react-native/src/private/specs/modules/NativeExceptionsManager.js @@ -47,11 +47,6 @@ export interface Spec extends TurboModule { exceptionId: number, ) => void; +reportException?: (data: ExceptionData) => void; - +updateExceptionMessage: ( - message: string, - stack: Array, - exceptionId: number, - ) => void; // TODO(T53311281): This is a noop on iOS now. Implement it. +dismissRedbox?: () => void; } @@ -74,13 +69,6 @@ const ExceptionsManager = { ) { NativeModule.reportSoftException(message, stack, exceptionId); }, - updateExceptionMessage( - message: string, - stack: Array, - exceptionId: number, - ) { - NativeModule.updateExceptionMessage(message, stack, exceptionId); - }, dismissRedbox(): void { if (Platform.OS !== 'ios' && NativeModule.dismissRedbox) { // TODO(T53311281): This is a noop on iOS now. Implement it. diff --git a/packages/react-native/src/private/webapis/performance/EventTiming.js b/packages/react-native/src/private/webapis/performance/EventTiming.js index a2f0cf505e0558..f57e50b65d1ce0 100644 --- a/packages/react-native/src/private/webapis/performance/EventTiming.js +++ b/packages/react-native/src/private/webapis/performance/EventTiming.js @@ -16,8 +16,8 @@ import type { } from './PerformanceEntry'; import {PerformanceEntry} from './PerformanceEntry'; -import {warnNoNativePerformance} from './Utilities'; import NativePerformance from './specs/NativePerformance'; +import {warnNoNativePerformance} from './Utilities'; export type PerformanceEventTimingJSON = { ...PerformanceEntryJSON, diff --git a/packages/react-native/src/private/webapis/performance/Performance.js b/packages/react-native/src/private/webapis/performance/Performance.js index f2496ef58d47ab..992f048faabc3c 100644 --- a/packages/react-native/src/private/webapis/performance/Performance.js +++ b/packages/react-native/src/private/webapis/performance/Performance.js @@ -12,8 +12,8 @@ import type { DOMHighResTimeStamp, - PerformanceEntryType, PerformanceEntryList, + PerformanceEntryType, } from './PerformanceEntry'; import type {DetailType, PerformanceMarkOptions} from './UserTiming'; @@ -109,15 +109,24 @@ export default class Performance { markName: string, markOptions?: PerformanceMarkOptions, ): PerformanceMark { - const mark = new PerformanceMark(markName, markOptions); - - if (NativePerformance?.mark) { - NativePerformance.mark(markName, mark.startTime); + let computedStartTime; + if (NativePerformance?.markWithResult) { + computedStartTime = NativePerformance.markWithResult( + markName, + markOptions?.startTime, + ); + } else if (NativePerformance?.mark) { + computedStartTime = markOptions?.startTime ?? performance.now(); + NativePerformance?.mark?.(markName, computedStartTime); } else { warnNoNativePerformance(); + computedStartTime = performance.now(); } - return mark; + return new PerformanceMark(markName, { + startTime: computedStartTime, + detail: markOptions?.detail, + }); } clearMarks(markName?: string): void { @@ -143,6 +152,7 @@ export default class Performance { if (typeof startMarkOrOptions === 'string') { startMarkName = startMarkOrOptions; + options = {}; } else if (startMarkOrOptions !== undefined) { options = startMarkOrOptions; if (endMark !== undefined) { @@ -180,15 +190,20 @@ export default class Performance { duration = options.duration ?? duration; } - const measure = new PerformanceMeasure(measureName, { - // FIXME(T196011255): this is incorrect, as we're only assigning the - // start/end if they're specified as a number, but not if they're - // specified as previous mark names. - startTime, - duration, - }); - - if (NativePerformance?.measure) { + let computedStartTime = startTime; + let computedDuration = duration; + + if (NativePerformance?.measureWithResult) { + [computedStartTime, computedDuration] = + NativePerformance.measureWithResult( + measureName, + startTime, + endTime, + duration, + startMarkName, + endMarkName, + ); + } else if (NativePerformance?.measure) { NativePerformance.measure( measureName, startTime, @@ -201,6 +216,12 @@ export default class Performance { warnNoNativePerformance(); } + const measure = new PerformanceMeasure(measureName, { + startTime: computedStartTime, + duration: computedDuration, + detail: options?.detail, + }); + return measure; } diff --git a/packages/react-native/src/private/webapis/performance/PerformanceObserver.js b/packages/react-native/src/private/webapis/performance/PerformanceObserver.js index 98c76f923517d6..adff3bf671ce0e 100644 --- a/packages/react-native/src/private/webapis/performance/PerformanceObserver.js +++ b/packages/react-native/src/private/webapis/performance/PerformanceObserver.js @@ -10,9 +10,10 @@ import type { DOMHighResTimeStamp, - PerformanceEntryType, PerformanceEntryList, + PerformanceEntryType, } from './PerformanceEntry'; +import type {OpaqueNativeObserverHandle} from './specs/NativePerformance'; import {PerformanceEventTiming} from './EventTiming'; import { @@ -21,7 +22,6 @@ import { rawToPerformanceEntryType, } from './RawPerformanceEntry'; import NativePerformance from './specs/NativePerformance'; -import type {OpaqueNativeObserverHandle} from './specs/NativePerformance'; import {warnNoNativePerformance} from './Utilities'; export {PerformanceEntry} from './PerformanceEntry'; diff --git a/packages/react-native/src/private/webapis/performance/__tests__/Performance-test.js b/packages/react-native/src/private/webapis/performance/__tests__/Performance-test.js index 5074ca99287ea5..61188d4495afe9 100644 --- a/packages/react-native/src/private/webapis/performance/__tests__/Performance-test.js +++ b/packages/react-native/src/private/webapis/performance/__tests__/Performance-test.js @@ -9,6 +9,7 @@ * @oncall react_native */ +// eslint-disable-next-line lint/sort-imports import {performanceEntryTypeToRaw} from '../RawPerformanceEntry'; import {reportEntry} from '../specs/__mocks__/NativePerformanceMock'; diff --git a/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js b/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js index 49ef8985270a72..aa10bbd706c29d 100644 --- a/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js +++ b/packages/react-native/src/private/webapis/performance/specs/NativePerformance.js @@ -33,6 +33,8 @@ export type RawPerformanceEntry = { export type OpaqueNativeObserverHandle = mixed; export type NativeBatchedObserverCallback = () => void; +export type NativePerformanceMarkResult = number; +export type NativePerformanceMeasureResult = $ReadOnlyArray; // [startTime, duration] export type PerformanceObserverInit = { entryTypes?: $ReadOnlyArray, @@ -43,8 +45,10 @@ export type PerformanceObserverInit = { export interface Spec extends TurboModule { +now?: () => number; - +mark: (name: string, startTime: number) => void; - +measure: ( + // TODO: remove when `markWithResult` is fully rolled out. + +mark?: (name: string, startTime: number) => void; + // TODO: remove when `measureWithResult` is fully rolled out. + +measure?: ( name: string, startTime: number, endTime: number, @@ -52,6 +56,18 @@ export interface Spec extends TurboModule { startMark?: string, endMark?: string, ) => void; + +markWithResult?: ( + name: string, + startTime?: number, + ) => NativePerformanceMarkResult; + +measureWithResult?: ( + name: string, + startTime: number, + endTime: number, + duration?: number, + startMark?: string, + endMark?: string, + ) => NativePerformanceMeasureResult; +clearMarks?: (entryName?: string) => void; +clearMeasures?: (entryName?: string) => void; +getEntries?: () => $ReadOnlyArray; diff --git a/packages/react-native/src/private/webapis/performance/specs/__mocks__/NativePerformanceMock.js b/packages/react-native/src/private/webapis/performance/specs/__mocks__/NativePerformanceMock.js index 3195a42bc57fe7..306b4694bae90c 100644 --- a/packages/react-native/src/private/webapis/performance/specs/__mocks__/NativePerformanceMock.js +++ b/packages/react-native/src/private/webapis/performance/specs/__mocks__/NativePerformanceMock.js @@ -11,13 +11,14 @@ import type { NativeBatchedObserverCallback, NativeMemoryInfo, - RawPerformanceEntry, - ReactNativeStartupTiming, - PerformanceObserverInit, + NativePerformanceMarkResult, + NativePerformanceMeasureResult, OpaqueNativeObserverHandle, + PerformanceObserverInit, + RawPerformanceEntry, RawPerformanceEntryType, + ReactNativeStartupTiming, } from '../NativePerformance'; - import typeof NativePerformance from '../NativePerformance'; import {RawPerformanceEntryTypeValues} from '../../RawPerformanceEntry'; @@ -109,32 +110,51 @@ const NativePerformanceMock = { now: (): number => currentTime, - mark: (name: string, startTime: number): void => { - marks.set(name, startTime); + markWithResult: ( + name: string, + startTime?: number, + ): NativePerformanceMarkResult => { + const computedStartTime = startTime ?? performance.now(); + + marks.set(name, computedStartTime); reportEntry({ entryType: RawPerformanceEntryTypeValues.MARK, name, - startTime, + startTime: computedStartTime, duration: 0, }); + + return computedStartTime; }, - measure: ( + measureWithResult: ( name: string, startTime: number, endTime: number, duration?: number, startMark?: string, endMark?: string, - ): void => { - const start = startMark != null ? marks.get(startMark) ?? 0 : startTime; - const end = endMark != null ? marks.get(endMark) ?? 0 : endTime; + ): NativePerformanceMeasureResult => { + const start = startMark != null ? marks.get(startMark) : startTime; + const end = endMark != null ? marks.get(endMark) : endTime; + + if (start === undefined) { + throw new Error('startMark does not exist'); + } + + if (end === undefined) { + throw new Error('endMark does not exist'); + } + + const computedDuration = duration ?? end - start; reportEntry({ entryType: RawPerformanceEntryTypeValues.MEASURE, name, startTime: start, - duration: duration ?? end - start, + duration: computedDuration, }); + + return [start, computedDuration]; }, getSimpleMemoryInfo: (): NativeMemoryInfo => { diff --git a/packages/react-native/third-party-podspecs/RCT-Folly.podspec b/packages/react-native/third-party-podspecs/RCT-Folly.podspec index 40226c863cff88..b3c60a50a9e3fd 100644 --- a/packages/react-native/third-party-podspecs/RCT-Folly.podspec +++ b/packages/react-native/third-party-podspecs/RCT-Folly.podspec @@ -23,7 +23,8 @@ Pod::Spec.new do |spec| spec.dependency 'boost' spec.dependency 'DoubleConversion' spec.dependency 'glog' - spec.dependency "fmt", "9.1.0" + spec.dependency "fast_float", "6.1.4" + spec.dependency "fmt", "11.0.2" spec.compiler_flags = folly_compiler_flags + ' -DFOLLY_HAVE_PTHREAD=1 -Wno-documentation -faligned-new' spec.source_files = 'folly/String.cpp', 'folly/Conv.cpp', @@ -34,18 +35,19 @@ Pod::Spec.new do |spec| 'folly/lang/ToAscii.cpp', 'folly/ScopeGuard.cpp', 'folly/Unicode.cpp', - 'folly/dynamic.cpp', - 'folly/json.cpp', - 'folly/json_pointer.cpp', + 'folly/json/dynamic.cpp', + 'folly/json/json.cpp', + 'folly/json/json_pointer.cpp', 'folly/container/detail/F14Table.cpp', 'folly/detail/Demangle.cpp', 'folly/detail/FileUtilDetail.cpp', 'folly/detail/SplitStringSimd.cpp', + 'folly/detail/StaticSingletonManager.cpp', 'folly/detail/UniqueInstance.cpp', 'folly/hash/SpookyHashV2.cpp', - 'folly/lang/Assume.cpp', 'folly/lang/CString.cpp', 'folly/lang/Exception.cpp', + 'folly/memory/ReentrantAllocator.cpp', 'folly/memory/detail/MallocImpl.cpp', 'folly/net/NetOps.cpp', 'folly/portability/SysUio.cpp', @@ -53,11 +55,15 @@ Pod::Spec.new do |spec| 'folly/system/AtFork.cpp', 'folly/system/ThreadId.cpp', 'folly/*.h', + 'folly/algorithm/simd/*.h', + 'folly/algorithm/simd/detail/*.h', + 'folly/chrono/*.h', 'folly/container/*.h', 'folly/container/detail/*.h', 'folly/detail/*.h', 'folly/functional/*.h', 'folly/hash/*.h', + 'folly/json/*.h', 'folly/lang/*.h', 'folly/memory/*.h', 'folly/memory/detail/*.h', @@ -68,11 +74,15 @@ Pod::Spec.new do |spec| # workaround for https://github.com/facebook/react-native/issues/14326 spec.preserve_paths = 'folly/*.h', + 'folly/algorithm/simd/*.h', + 'folly/algorithm/simd/detail/*.h', + 'folly/chrono/*.h', 'folly/container/*.h', 'folly/container/detail/*.h', 'folly/detail/*.h', 'folly/functional/*.h', 'folly/hash/*.h', + 'folly/json/*.h', 'folly/lang/*.h', 'folly/memory/*.h', 'folly/memory/detail/*.h', @@ -84,7 +94,7 @@ Pod::Spec.new do |spec| spec.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", "DEFINES_MODULE" => "YES", "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), - "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\"", + "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\"", # In dynamic framework (use_frameworks!) mode, ignore the unused and undefined boost symbols when generating the library. "OTHER_LDFLAGS" => "\"-Wl,-U,_jump_fcontext\" \"-Wl,-U,_make_fcontext\"", "GCC_WARN_INHIBIT_ALL_WARNINGS" => "YES" # Disable warnings because we don't control this library @@ -106,7 +116,6 @@ Pod::Spec.new do |spec| 'folly/concurrency/CacheLocality.cpp', 'folly/detail/Futex.cpp', 'folly/synchronization/ParkingLot.cpp', - 'folly/portability/Malloc.cpp', 'folly/concurrency/CacheLocality.h', 'folly/synchronization/*.h', 'folly/system/ThreadId.h' diff --git a/packages/react-native/third-party-podspecs/fast_float.podspec b/packages/react-native/third-party-podspecs/fast_float.podspec new file mode 100644 index 00000000000000..8c89d9da18f54f --- /dev/null +++ b/packages/react-native/third-party-podspecs/fast_float.podspec @@ -0,0 +1,29 @@ +# 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. + +fast_float_config = get_fast_float_config() +fast_float_git_url = fast_float_config[:git] + +Pod::Spec.new do |spec| + spec.name = "fast_float" + spec.version = "6.1.4" + spec.license = { :type => "MIT" } + spec.homepage = "https://github.com/fastfloat/fast_float" + spec.summary = "{fast_float} is an open-source number parsing library for C++. The library provides fast header-only implementations." + spec.authors = "The fast_float contributors" + spec.source = { + :git => fast_float_git_url, + :tag => "v6.1.4" + } + spec.pod_target_xcconfig = { + "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), + "GCC_WARN_INHIBIT_ALL_WARNINGS" => "YES" # Disable warnings because we don't control this library + } + spec.platforms = min_supported_versions + spec.libraries = "c++" + spec.public_header_files = "include/fast_float/*.h" + spec.header_mappings_dir = "include" + spec.source_files = ["include/fast_float/*.h"] +end diff --git a/packages/react-native/third-party-podspecs/fmt.podspec b/packages/react-native/third-party-podspecs/fmt.podspec index c76b312e6b6c69..2f38990e226c13 100644 --- a/packages/react-native/third-party-podspecs/fmt.podspec +++ b/packages/react-native/third-party-podspecs/fmt.podspec @@ -8,14 +8,14 @@ fmt_git_url = fmt_config[:git] Pod::Spec.new do |spec| spec.name = "fmt" - spec.version = "9.1.0" + spec.version = "11.0.2" spec.license = { :type => "MIT" } spec.homepage = "https://github.com/fmtlib/fmt" spec.summary = "{fmt} is an open-source formatting library for C++. It can be used as a safe and fast alternative to (s)printf and iostreams." spec.authors = "The fmt contributors" spec.source = { :git => fmt_git_url, - :tag => "9.1.0" + :tag => "11.0.2" } spec.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(), diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index 6ecec1fbb458af..1927f99fc35dd6 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -1,8 +1,9 @@ PODS: - boost (1.84.0) - DoubleConversion (1.1.6) + - fast_float (6.1.4) - FBLazyVector (1000.0.0) - - fmt (9.1.0) + - fmt (11.0.2) - glog (0.3.5) - hermes-engine (1000.0.0): - hermes-engine/cdp (= 1000.0.0) @@ -15,11 +16,11 @@ PODS: - hermes-engine/inspector (1000.0.0) - hermes-engine/inspector_chrome (1000.0.0) - hermes-engine/Public (1000.0.0) - - MyNativeView (0.76.0-main): + - MyNativeView (0.77.0-main): - DoubleConversion - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -36,11 +37,11 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - NativeCxxModuleExample (0.76.0-main): + - NativeCxxModuleExample (0.77.0-main): - DoubleConversion - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -58,11 +59,11 @@ PODS: - ReactCommon/turbomodule/core - Yoga - OCMock (3.9.4) - - OSSLibraryExample (0.76.0-main): + - OSSLibraryExample (0.77.0-main): - DoubleConversion - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -79,21 +80,24 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - RCT-Folly (2024.01.01.00): + - RCT-Folly (2024.10.14.00): - boost - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - - RCT-Folly/Default (= 2024.01.01.00) - - RCT-Folly/Default (2024.01.01.00): + - RCT-Folly/Default (= 2024.10.14.00) + - RCT-Folly/Default (2024.10.14.00): - boost - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - - RCT-Folly/Fabric (2024.01.01.00): + - RCT-Folly/Fabric (2024.10.14.00): - boost - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - RCTDeprecation (1000.0.0) - RCTRequired (1000.0.0) @@ -118,7 +122,7 @@ PODS: - React-Core (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default (= 1000.0.0) - React-cxxreact @@ -135,7 +139,7 @@ PODS: - React-Core/CoreModulesHeaders (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default - React-cxxreact @@ -152,7 +156,7 @@ PODS: - React-Core/Default (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-cxxreact - React-featureflags @@ -168,7 +172,7 @@ PODS: - React-Core/DevSupport (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default (= 1000.0.0) - React-Core/RCTWebSocket (= 1000.0.0) @@ -186,7 +190,7 @@ PODS: - React-Core/RCTActionSheetHeaders (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default - React-cxxreact @@ -203,7 +207,7 @@ PODS: - React-Core/RCTAnimationHeaders (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default - React-cxxreact @@ -220,7 +224,7 @@ PODS: - React-Core/RCTBlobHeaders (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default - React-cxxreact @@ -237,7 +241,7 @@ PODS: - React-Core/RCTImageHeaders (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default - React-cxxreact @@ -254,7 +258,7 @@ PODS: - React-Core/RCTLinkingHeaders (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default - React-cxxreact @@ -271,7 +275,7 @@ PODS: - React-Core/RCTNetworkHeaders (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default - React-cxxreact @@ -288,7 +292,7 @@ PODS: - React-Core/RCTPushNotificationHeaders (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default - React-cxxreact @@ -305,7 +309,7 @@ PODS: - React-Core/RCTSettingsHeaders (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default - React-cxxreact @@ -322,7 +326,7 @@ PODS: - React-Core/RCTTextHeaders (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default - React-cxxreact @@ -339,7 +343,7 @@ PODS: - React-Core/RCTVibrationHeaders (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default - React-cxxreact @@ -356,7 +360,7 @@ PODS: - React-Core/RCTWebSocket (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTDeprecation - React-Core/Default (= 1000.0.0) - React-cxxreact @@ -372,8 +376,9 @@ PODS: - Yoga - React-CoreModules (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) - - RCT-Folly (= 2024.01.01.00) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) + - RCT-Folly (= 2024.10.14.00) - RCTTypeSafety (= 1000.0.0) - React-Core/CoreModulesHeaders (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -387,10 +392,11 @@ PODS: - React-cxxreact (1000.0.0): - boost - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-callinvoker (= 1000.0.0) - React-debug (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -404,7 +410,7 @@ PODS: - DoubleConversion - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -429,7 +435,7 @@ PODS: - DoubleConversion - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -449,10 +455,11 @@ PODS: - Yoga - React-Fabric (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -484,10 +491,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/animations (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -504,10 +512,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/attributedstring (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -524,10 +533,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/componentregistry (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -544,10 +554,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/componentregistrynative (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -564,10 +575,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/components (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -587,10 +599,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/components/legacyviewmanagerinterop (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -607,10 +620,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/components/root (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -627,10 +641,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/components/view (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -648,10 +663,11 @@ PODS: - Yoga - React-Fabric/core (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -668,10 +684,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/dom (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -688,10 +705,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/imagemanager (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -708,10 +726,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/leakchecker (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -728,10 +747,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/mounting (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -748,10 +768,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/observers (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -769,10 +790,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/observers/events (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -789,10 +811,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/scheduler (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -811,10 +834,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/telemetry (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -831,10 +855,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/templateprocessor (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -851,10 +876,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/uimanager (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -873,10 +899,11 @@ PODS: - ReactCommon/turbomodule/core - React-Fabric/uimanager/consistency (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -894,10 +921,11 @@ PODS: - ReactCommon/turbomodule/core - React-FabricComponents (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -919,10 +947,11 @@ PODS: - Yoga - React-FabricComponents/components (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -951,10 +980,11 @@ PODS: - Yoga - React-FabricComponents/components/inputaccessory (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -974,10 +1004,11 @@ PODS: - Yoga - React-FabricComponents/components/iostextinput (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -997,10 +1028,11 @@ PODS: - Yoga - React-FabricComponents/components/modal (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1020,10 +1052,11 @@ PODS: - Yoga - React-FabricComponents/components/rncore (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1043,10 +1076,11 @@ PODS: - Yoga - React-FabricComponents/components/safeareaview (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1066,10 +1100,11 @@ PODS: - Yoga - React-FabricComponents/components/scrollview (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1089,10 +1124,11 @@ PODS: - Yoga - React-FabricComponents/components/text (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1112,10 +1148,11 @@ PODS: - Yoga - React-FabricComponents/components/textinput (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1135,10 +1172,11 @@ PODS: - Yoga - React-FabricComponents/components/unimplementedview (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1158,10 +1196,11 @@ PODS: - Yoga - React-FabricComponents/textlayoutmanager (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1181,10 +1220,11 @@ PODS: - Yoga - React-FabricImage (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-Fabric @@ -1202,7 +1242,7 @@ PODS: - DoubleConversion - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1221,18 +1261,20 @@ PODS: - Yoga - React-graphics (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - React-jsi - React-jsiexecutor - React-utils - React-hermes (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-cxxreact (= 1000.0.0) - React-jsi - React-jsiexecutor (= 1000.0.0) @@ -1243,7 +1285,7 @@ PODS: - DoubleConversion - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1273,23 +1315,26 @@ PODS: - React-jserrorhandler (1000.0.0): - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - React-cxxreact - React-debug - React-jsi + - ReactCommon/turbomodule/bridging - React-jsi (1000.0.0): - boost - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-jsiexecutor (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) - React-jsinspector @@ -1298,7 +1343,7 @@ PODS: - DoubleConversion - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-featureflags - React-jsi - React-perflogger (= 1000.0.0) @@ -1314,7 +1359,7 @@ PODS: - DoubleConversion - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1345,15 +1390,16 @@ PODS: - ReactCommon/turbomodule/core - React-perflogger (1000.0.0): - DoubleConversion - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-performancetimeline (1000.0.0): - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-cxxreact + - React-featureflags - React-timing - React-RCTActionSheet (1000.0.0): - React-Core/RCTActionSheetHeaders (= 1000.0.0) - React-RCTAnimation (1000.0.0): - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTTypeSafety - React-Core/RCTAnimationHeaders - React-jsi @@ -1361,7 +1407,7 @@ PODS: - ReactCodegen - ReactCommon - React-RCTAppDelegate (1000.0.0): - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1387,9 +1433,10 @@ PODS: - ReactCommon - React-RCTBlob (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-Core/RCTBlobHeaders - React-Core/RCTWebSocket - React-jsi @@ -1401,7 +1448,7 @@ PODS: - React-RCTFabric (1000.0.0): - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - React-Core - React-debug - React-Fabric @@ -1422,7 +1469,7 @@ PODS: - React-utils - Yoga - React-RCTImage (1000.0.0): - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTTypeSafety - React-Core/RCTImageHeaders - React-jsi @@ -1438,7 +1485,7 @@ PODS: - ReactCommon - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTTypeSafety - React-Core/RCTNetworkHeaders - React-jsi @@ -1453,7 +1500,7 @@ PODS: - ReactCodegen - ReactCommon - React-RCTSettings (1000.0.0): - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTTypeSafety - React-Core/RCTSettingsHeaders - React-jsi @@ -1461,7 +1508,7 @@ PODS: - ReactCodegen - ReactCommon - React-RCTTest (1000.0.0): - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-Core (= 1000.0.0) - React-CoreModules (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -1470,7 +1517,7 @@ PODS: - React-Core/RCTTextHeaders (= 1000.0.0) - Yoga - React-RCTVibration (1000.0.0): - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-Core/RCTVibrationHeaders - React-jsi - React-NativeModulesApple @@ -1479,13 +1526,14 @@ PODS: - React-rendererconsistency (1000.0.0) - React-rendererdebug (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) - - RCT-Folly (= 2024.01.01.00) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) + - RCT-Folly (= 2024.10.14.00) - React-debug - React-rncore (1000.0.0) - React-RuntimeApple (1000.0.0): - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - React-callinvoker - React-Core/Default - React-CoreModules @@ -1505,7 +1553,7 @@ PODS: - React-RuntimeCore (1000.0.0): - glog - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - React-cxxreact - React-featureflags - React-jserrorhandler @@ -1520,7 +1568,7 @@ PODS: - React-jsi (= 1000.0.0) - React-RuntimeHermes (1000.0.0): - hermes-engine - - RCT-Folly/Fabric (= 2024.01.01.00) + - RCT-Folly/Fabric (= 2024.10.14.00) - React-featureflags - React-hermes - React-jsi @@ -1532,7 +1580,7 @@ PODS: - React-runtimescheduler (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-callinvoker - React-cxxreact - React-debug @@ -1548,7 +1596,7 @@ PODS: - React-utils (1000.0.0): - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-debug - React-jsi (= 1000.0.0) - ReactCodegen (1000.0.0): @@ -1575,7 +1623,8 @@ PODS: - ReactCommon/turbomodule (= 1000.0.0) - ReactCommon-Samples (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - hermes-engine - RCT-Folly - React-Core @@ -1586,10 +1635,11 @@ PODS: - ReactCommon - ReactCommon/turbomodule (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-callinvoker (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -1599,10 +1649,11 @@ PODS: - ReactCommon/turbomodule/core (= 1000.0.0) - ReactCommon/turbomodule/bridging (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-callinvoker (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -1610,10 +1661,11 @@ PODS: - React-perflogger (= 1000.0.0) - ReactCommon/turbomodule/core (1000.0.0): - DoubleConversion - - fmt (= 9.1.0) + - fast_float (= 6.1.4) + - fmt (= 11.0.2) - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - React-callinvoker (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-debug (= 1000.0.0) @@ -1622,11 +1674,11 @@ PODS: - React-logger (= 1000.0.0) - React-perflogger (= 1000.0.0) - React-utils (= 1000.0.0) - - ScreenshotManager (0.76.0-main): + - ScreenshotManager (0.77.0-main): - DoubleConversion - glog - hermes-engine - - RCT-Folly (= 2024.01.01.00) + - RCT-Folly (= 2024.10.14.00) - RCTRequired - RCTTypeSafety - React-Core @@ -1649,6 +1701,7 @@ PODS: DEPENDENCIES: - boost (from `../react-native/third-party-podspecs/boost.podspec`) - DoubleConversion (from `../react-native/third-party-podspecs/DoubleConversion.podspec`) + - fast_float (from `../react-native/third-party-podspecs/fast_float.podspec`) - FBLazyVector (from `../react-native/Libraries/FBLazyVector`) - fmt (from `../react-native/third-party-podspecs/fmt.podspec`) - glog (from `../react-native/third-party-podspecs/glog.podspec`) @@ -1731,6 +1784,8 @@ EXTERNAL SOURCES: :podspec: "../react-native/third-party-podspecs/boost.podspec" DoubleConversion: :podspec: "../react-native/third-party-podspecs/DoubleConversion.podspec" + fast_float: + :podspec: "../react-native/third-party-podspecs/fast_float.podspec" FBLazyVector: :path: "../react-native/Libraries/FBLazyVector" fmt: @@ -1870,78 +1925,79 @@ EXTERNAL SOURCES: :path: "../react-native/ReactCommon/yoga" SPEC CHECKSUMS: - boost: 1dca942403ed9342f98334bf4c3621f011aa7946 - DoubleConversion: f16ae600a246532c4020132d54af21d0ddb2a385 - FBLazyVector: c8715bd426ed93c57bb679b549e92f79a823212a - fmt: 10c6e61f4be25dc963c36bd73fc7b1705fe975be - glog: 08b301085f15bcbb6ff8632a8ebaf239aae04e6a - hermes-engine: 18648a751649d9b6ac408579511554a4fbaaccc2 - MyNativeView: 32eb899a4fc31dbe7e93f356935a7fe56d42d74e - NativeCxxModuleExample: 9621f63e90acef88ac37beac4fb841132ad18d86 + boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 + DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb + fast_float: 06eeec4fe712a76acc9376682e4808b05ce978b6 + FBLazyVector: d3c2dd739a63c1a124e775df075dc7c517a719cb + fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd + glog: eb93e2f488219332457c3c4eafd2738ddc7e80b8 + hermes-engine: 0f8fb784efaddc3e98ce5b19a6cb1778be784ba1 + MyNativeView: 8af68f7d37413c951b8444e32ec81747099f6959 + NativeCxxModuleExample: 0666f3ce65aaba7fa125324ec9d193d0df44f052 OCMock: 589f2c84dacb1f5aaf6e4cec1f292551fe748e74 - OSSLibraryExample: 44a44517ba2b7e99be1ac345942e5c98e3f8d8da - RCT-Folly: bf5c0376ffe4dd2cf438dcf86db385df9fdce648 + OSSLibraryExample: 6d432836e53c8f04c0c19b98f3f9fd61e12d9f03 + RCT-Folly: 63ea034480807f66007e6e02437b15358c03511e RCTDeprecation: 3808e36294137f9ee5668f4df2e73dc079cd1dcf - RCTRequired: 7a8e6a2c361700f9c645216e9991604757b1025c - RCTTypeSafety: 27891ddab793e9f45bd427e0063985fa9d1a745c - React: 0a852eb3a4778fa382bd4bec1d1102dc95c492ce - React-callinvoker: 4857665c23ce7406d949bb95ce3a579620cd35f5 - React-Core: dab3d3b3713c207cf555cc54f613d72e5dda65dc - React-CoreModules: 5d48f1d3a5f01341d5e34b401cf7b099a6834941 - React-cxxreact: cfad872bd295947124e9d3635b5dc2395037875f - React-debug: 8cf17cbbe4db4489da08583fa1219292ab3add3b - React-defaultsnativemodule: 8f585662fc9ea76ad1a6f2df50f245e126ea2c1f - React-domnativemodule: 6d3248be46d2b94fa9b09e09a5981adb35ec135e - React-Fabric: ea21b602bbfe90f63aadf01c069b7f1759d5e2c7 - React-FabricComponents: c69ec63ffe8b1bf773f85695939d8c21e77b3423 - React-FabricImage: fcbed58676da40e43f50970d4a3abf7014d4c97c - React-featureflags: b8a4c60827c52e3e6b3d331c47964b91226da452 - React-featureflagsnativemodule: 12af419af8e7cc6e2212fa10d450ec6cc78e3c93 - React-graphics: c385ac155868a23b0dd4dace94228a0812dd3587 - React-hermes: bf8bec9c40d4756e74be3bb642dcc636ee0a3376 - React-idlecallbacksnativemodule: 01b2c90be61e39ea57c5ec8fb40223402f0408a3 - React-ImageManager: d09977cf41a8af909d776b92150d00066610253e - React-jserrorhandler: bf2e4e3e6ea6c903c0dac85d6ef069bdf010073c - React-jsi: ca82ba79ab3b28553f3c7cae5d3e6bd61bd0615c - React-jsiexecutor: 0bce63803bd83219aa6f5d64ffdd504a407f8f76 - React-jsinspector: 51698143244af04db8fff1968b6eae92dbc29ef6 - React-jsitracing: 00126dc737136e1359deabbd064ad3e8d17e30a7 - React-logger: 7c9f94c18cab8076ed5ab70f4aeeeb1668c44c7d - React-Mapbuffer: 5dcd028f06ec61a76e3d2e823033a9d33c948f9d - React-microtasksnativemodule: d34bab40ed40aa735326940cfb4d5b1206761431 - React-nativeconfig: ede29a5b5c88ce9f6e6dfd41b5e6cab57059ebb5 - React-NativeModulesApple: 36bd93a8e4aded2cc32355a8f3df92b7e97d8edd - React-perflogger: 932cd803362f3d58552daafd62bc9ff51ba58021 - React-performancetimeline: 0b4298173f00277c86e4cb5ee5a7c05d7bc8d4aa - React-RCTActionSheet: 036a8aefa14fc19675e9e9f5006dc714bcb46684 - React-RCTAnimation: 0053c157cbbea286bc2db8835ef4f44b30508cc4 - React-RCTAppDelegate: 71c4f386c437618dcd5208ce6e8c754293594ad4 - React-RCTBlob: 037dd4857df7cee67f8f888a7bc50d2b4a92bca5 - React-RCTFabric: 02213d7cec2c67a050743a23892810e9c0c3f2fd - React-RCTImage: 66449efc872f237ccb44a6a3bfd356989a587fe4 - React-RCTLinking: 16741487b0dc6801cfaa708e64c038a74e9a847d - React-RCTNetwork: ff9babb55e055cff13673f16f3d4d538c64df90d - React-RCTPushNotification: 03d115747b28a77ae375e0f63e188bf9a1d1d4be - React-RCTSettings: 48fc69ff93298efee6611f6983180aafa438b47a - React-RCTTest: 5f5e3cd632066b2b798917bd076ba539a30fe415 - React-RCTText: 11944100c500f4d315616c05ac547535c4dad9aa - React-RCTVibration: 9fd4ce9cc2b7dd827dcec09eb502d07a1b076b76 - React-rendererconsistency: 546e5e6e2cd2452dceae8a1f649a8729459e1ef7 - React-rendererdebug: ba5a20926f8e0d8de547bad92c88e63910bce590 - React-rncore: 3a67b832671a341bb3418a8b89a8dc4425b62310 - React-RuntimeApple: 71457481a74e06a296448a8ac4a9700167a2d241 - React-RuntimeCore: bf9c9c863e710e4d2938d9bc542501b3cd07fc03 - React-runtimeexecutor: 5a4b1736b547811ebbf2f5db9e58c9184d6514cd - React-RuntimeHermes: 3d83f329b54d2d6accaf7c9d28d6f519857b83b9 - React-runtimescheduler: 8786b1927836380c443d0fb39af3f10cf80ffd18 - React-timing: ff1ffa083a1901bf161f7d50950f08c7e07dca90 - React-utils: 31bd4a7e3141994194048105b704669d2190818c - ReactCodegen: 65ce3f3e2bb238505f943941b1cf30b4f5ea9698 - ReactCommon: 2f7f1a6ac3607b43f524dd6997813075ac06dcfa - ReactCommon-Samples: cb52d135304897c4aab596d514d6a44ab1e25b21 - ScreenshotManager: a3d9db14cd056df5e4a57c3fedee795393246790 + RCTRequired: a00614e2da5344c2cda3d287050b6cee00e21dc6 + RCTTypeSafety: 459a16418c6b413060d35434ba3e83f5b0bd2651 + React: 170a01a19ba2525ab7f11243e2df6b19bf268093 + React-callinvoker: f08f425e4043cd1998a158b6e39a6aed1fd1d718 + React-Core: e14a20ce14bb220db6f15f99308bcb221ad860e1 + React-CoreModules: 03b02c4f8312a22c1b3471e2e4061611f9f64b48 + React-cxxreact: e5dc26540b34869bdafe544a2dc98c729e911004 + React-debug: 195df38487d3f48a7af04deddeb4a5c6d4440416 + React-defaultsnativemodule: 22482f110d58c88bbbd46da565b8102b5ce77819 + React-domnativemodule: 34a9b69d9c6dc8aea1d8f9a71d6fd4bcb1d665f3 + React-Fabric: e1e49a06ae12efbd1adac214862c0f919460b629 + React-FabricComponents: c13525ccd846c2b9efb248a731c37637fd3558b6 + React-FabricImage: 099a46c34a6f55abce3ee6c1d60ff4ee55c85504 + React-featureflags: ac152b9e505abad006bee368edb0a4851fecaf5f + React-featureflagsnativemodule: 509a04bf4640de4ba4e5b95ffdf5554283cbfddd + React-graphics: cd09a3b0ea309e10c3bc93f01c606f95166b6ff5 + React-hermes: f55ba975cf5358df190f8ade0afaeae543ffbeee + React-idlecallbacksnativemodule: 85f2b59c9650f5fc535f6a92e930ce76ce77cdbd + React-ImageManager: 575cefd6f3fe4a9998409eebe9c26eee9ed702f7 + React-jserrorhandler: 99b9dd182461c88d4d02756498d991e9b7ca3248 + React-jsi: 53d26399177921b2e4153b6b90fdea3b466b1f2b + React-jsiexecutor: 41546c370e8ae9ccc1f05b85504f539a04a0acca + React-jsinspector: 3bbe8e8f28c9d17f6313fcf317a085123363fef5 + React-jsitracing: ef82947481b8bf7d49adbaacd8ae0e01028b8ddb + React-logger: b19e99fbaaf73d83adaca8917c133d1da71df8de + React-Mapbuffer: 11fabe7a2a035584622004cd476699897492927b + React-microtasksnativemodule: 2ba56dfb6dcc1b3a189333d7c57037b87c3bbd7e + React-nativeconfig: 8f2cb4bf2028acf616c4bdbef3aecb8312e84291 + React-NativeModulesApple: 0596f545e307887fc7bcee2abf958190599934e1 + React-perflogger: 35eb440e6a623c46f6c3b4b87eb7e3b07112138a + React-performancetimeline: 1d8884eae7282293cbba0293f5075adc227ff1c7 + React-RCTActionSheet: 1bf8cc8086ad1c15da3407dfb7bc9dd94dc7595d + React-RCTAnimation: 8eb55e6604a163e6c50e0543dba49c2991d5559f + React-RCTAppDelegate: 067ff873f2cd24fa0fd35f08aca1c99b00f3fd57 + React-RCTBlob: 38bc99ee05fa5111880b315c0e01079aa7a1c05c + React-RCTFabric: e544aea023b719c985580cccf709bd0295ad175a + React-RCTImage: 8fa6e8edc2f9a6622559bead27d1388f577fc4c0 + React-RCTLinking: a70c4fb248b10bc1c8733ae94452232ab877887f + React-RCTNetwork: 4d52636c4d5e4633d62e42785e063ad8112f2eb6 + React-RCTPushNotification: 08f04e05ff994f93d74c406b51500688ae6e5541 + React-RCTSettings: dd24f3c15d36c217b2facced07ce05e3f7e38f9a + React-RCTTest: 4adb0bfe9f33775a7868d5a55efb2f4b68ff7378 + React-RCTText: e5a08c3829b35f1db001c9cbdf1917936f5dbd25 + React-RCTVibration: 5bcce0239c34658a48da8d33f618f67075ed3a9f + React-rendererconsistency: 777c894edc43dde01499189917ac54ee76ae6a6a + React-rendererdebug: dcdb0febb40c690f680b57100cac68ed7069bd76 + React-rncore: 4a81ce7b8e47448973a6b29c765b07e01715921e + React-RuntimeApple: 40747a7b79ce3c63c9f83d619f31a2ae7da564ef + React-RuntimeCore: dc69373e13f9c7221557c8bf3d2547855184621f + React-runtimeexecutor: fb2d342a477bb13f7128cceb711ee8311edce0c0 + React-RuntimeHermes: 1444afb801cbd255e42a9759bac04f9db69d6bcb + React-runtimescheduler: ea6d18da4a0926b2906f06b575c534a34043c0a8 + React-timing: 9d49179631e5e3c759e6e82d4c613c73da80a144 + React-utils: 3635133e3bd480e3898075afdc00e8d2676f3758 + ReactCodegen: e69ed600668a956ea337bbcf701d26eb7e403792 + ReactCommon: 691e7f9c04e1eceb968f8ee1f3501837d61b59fb + ReactCommon-Samples: 98c203dad7e21c39663450b8dae0c01a356e249f + ScreenshotManager: 0f4041b0b21840453d066283c50bb0186c7b513b SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - Yoga: dcc37de9ded9760f3d5dc18865cc15a62bb4884b + Yoga: 922136ed5790378cd675c3611f6f2b8c67103803 PODFILE CHECKSUM: 8591f96a513620a2a83a0b9a125ad3fa32ea1369 diff --git a/packages/rn-tester/README.md b/packages/rn-tester/README.md index 79182db17dbffd..0d30905bb0fe3f 100644 --- a/packages/rn-tester/README.md +++ b/packages/rn-tester/README.md @@ -26,7 +26,7 @@ cd packages/rn-tester yarn clean-ios ``` -If you are still having a problem after doing the clean up (which can happen if you have built RNTester with older React Native versions where files were generated inside the react-native folder.), the best way might be to clean-install react-native (e.g. remove node_modules and yarn install). +If you are still having a problem after doing the clean up (which can happen if you have built RNTester with older React Native versions where files were generated inside the react-native folder.), the best way might be to clean-install react-native (e.g. remove node_modules and yarn install). If after cleaning up, you are still having issues, you might also want to try `RCT_NEW_ARCH_ENABLED=0 bundle exec pod install` to disable the new architecture as it might be conflicting. Both macOS and Xcode are required. 1. `cd packages/rn-tester` diff --git a/packages/rn-tester/js/RNTesterAppShared.js b/packages/rn-tester/js/RNTesterAppShared.js index a40cbc8c2377d0..d1dfdc900cb36d 100644 --- a/packages/rn-tester/js/RNTesterAppShared.js +++ b/packages/rn-tester/js/RNTesterAppShared.js @@ -10,12 +10,12 @@ import type {RNTesterModuleInfo, ScreenTypes} from './types/RNTesterTypes'; -import {title as PlaygroundTitle} from './examples/Playground/PlaygroundExample'; import RNTesterModuleContainer from './components/RNTesterModuleContainer'; import RNTesterModuleList from './components/RNTesterModuleList'; import RNTesterNavBar, {navBarHeight} from './components/RNTesterNavbar'; import {RNTesterThemeContext, themes} from './components/RNTesterTheme'; import RNTTitleBar from './components/RNTTitleBar'; +import {title as PlaygroundTitle} from './examples/Playground/PlaygroundExample'; import RNTesterList from './utils/RNTesterList'; import { RNTesterNavigationActionsType, diff --git a/packages/rn-tester/js/components/RNTesterModuleList.js b/packages/rn-tester/js/components/RNTesterModuleList.js index 57aa08ba34976e..699d9c8e7ffd78 100644 --- a/packages/rn-tester/js/components/RNTesterModuleList.js +++ b/packages/rn-tester/js/components/RNTesterModuleList.js @@ -61,7 +61,7 @@ const renderSectionHeader = ({section}: {section: any, ...}) => ( ); -const RNTesterModuleList: React.ComponentType = React.memo( +const RNTesterModuleList: React.ComponentType = React.memo( ({sections, handleModuleCardPress}) => { const filter = ({example, filterRegex, category}: any) => filterRegex.test(example.module.title) && diff --git a/packages/rn-tester/js/components/RNTesterSettingSwitchRow.js b/packages/rn-tester/js/components/RNTesterSettingSwitchRow.js index 10b6554c7176ca..9a87aac9f0d747 100644 --- a/packages/rn-tester/js/components/RNTesterSettingSwitchRow.js +++ b/packages/rn-tester/js/components/RNTesterSettingSwitchRow.js @@ -9,7 +9,6 @@ */ import RNTesterText from './RNTesterText'; - import * as React from 'react'; import {StyleSheet, Switch, View} from 'react-native'; diff --git a/packages/rn-tester/js/examples/Accessibility/AccessibilityAndroidExample.js b/packages/rn-tester/js/examples/Accessibility/AccessibilityAndroidExample.js index f3713f727593e9..6b41f435790363 100644 --- a/packages/rn-tester/js/examples/Accessibility/AccessibilityAndroidExample.js +++ b/packages/rn-tester/js/examples/Accessibility/AccessibilityAndroidExample.js @@ -13,8 +13,8 @@ import RNTesterBlock from '../../components/RNTesterBlock'; import RNTesterPage from '../../components/RNTesterPage'; import RNTesterText from '../../components/RNTesterText'; -import {Alert, StyleSheet, TouchableWithoutFeedback, View} from 'react-native'; import React from 'react'; +import {Alert, StyleSheet, TouchableWithoutFeedback, View} from 'react-native'; const importantForAccessibilityValues = [ 'auto', diff --git a/packages/rn-tester/js/examples/Alert/AlertExample.js b/packages/rn-tester/js/examples/Alert/AlertExample.js index d20626984e2e8e..bafad59535ade7 100644 --- a/packages/rn-tester/js/examples/Alert/AlertExample.js +++ b/packages/rn-tester/js/examples/Alert/AlertExample.js @@ -10,8 +10,8 @@ import type {RNTesterModule} from '../../types/RNTesterTypes'; -import {RNTesterThemeContext} from '../../components/RNTesterTheme'; import RNTesterText from '../../components/RNTesterText'; +import {RNTesterThemeContext} from '../../components/RNTesterTheme'; import * as React from 'react'; import {Alert, Pressable, StyleSheet, Text, View} from 'react-native'; diff --git a/packages/rn-tester/js/examples/AppState/AppStateExample.js b/packages/rn-tester/js/examples/AppState/AppStateExample.js index 4b89ebe42b31f6..f1e9d2060075e5 100644 --- a/packages/rn-tester/js/examples/AppState/AppStateExample.js +++ b/packages/rn-tester/js/examples/AppState/AppStateExample.js @@ -13,9 +13,9 @@ import type {AppStateValues} from 'react-native/Libraries/AppState/AppState'; import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter'; +import RNTesterText from '../../components/RNTesterText'; import React from 'react'; import {AppState, Platform, View} from 'react-native'; -import RNTesterText from '../../components/RNTesterText'; class AppStateSubscription extends React.Component< $FlowFixMeProps, diff --git a/packages/rn-tester/js/examples/Appearance/AppearanceExample.js b/packages/rn-tester/js/examples/Appearance/AppearanceExample.js index dc0e99f1022ebf..3b5f269ff435b5 100644 --- a/packages/rn-tester/js/examples/Appearance/AppearanceExample.js +++ b/packages/rn-tester/js/examples/Appearance/AppearanceExample.js @@ -10,8 +10,8 @@ import type {ColorSchemeName} from 'react-native/Libraries/Utilities/NativeAppearance'; -import {RNTesterThemeContext, themes} from '../../components/RNTesterTheme'; import RNTesterText from '../../components/RNTesterText'; +import {RNTesterThemeContext, themes} from '../../components/RNTesterTheme'; import * as React from 'react'; import {useEffect, useState} from 'react'; import {Appearance, Button, Text, View, useColorScheme} from 'react-native'; diff --git a/packages/rn-tester/js/examples/Dimensions/DimensionsExample.js b/packages/rn-tester/js/examples/Dimensions/DimensionsExample.js index a43cbe7080d218..61843b1d210c2a 100644 --- a/packages/rn-tester/js/examples/Dimensions/DimensionsExample.js +++ b/packages/rn-tester/js/examples/Dimensions/DimensionsExample.js @@ -8,9 +8,9 @@ * @flow */ +import RNTesterText from '../../components/RNTesterText'; import React, {useEffect, useState} from 'react'; import {Dimensions, useWindowDimensions} from 'react-native'; -import RNTesterText from '../../components/RNTesterText'; type Props = {dim: string}; diff --git a/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js b/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js index 8d6a51d6358a75..85e21967ad68d1 100644 --- a/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js +++ b/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js @@ -103,7 +103,7 @@ function RelativeChildExample({log}: {log: string => void}) { function PointerEventScaffolding({ Example, }: { - Example: React.AbstractComponent<{log: string => void}>, + Example: component(log: (string) => void), }) { const [eventsLog, setEventsLog] = React.useState(''); const clear = () => setEventsLog(''); diff --git a/packages/rn-tester/js/examples/FlatList/FlatList-basic.js b/packages/rn-tester/js/examples/FlatList/FlatList-basic.js index 56b737acf41282..c0750b93837de1 100644 --- a/packages/rn-tester/js/examples/FlatList/FlatList-basic.js +++ b/packages/rn-tester/js/examples/FlatList/FlatList-basic.js @@ -314,7 +314,11 @@ class FlatListExample extends React.PureComponent { return getItemLayout(data, index, this.state.horizontal); }; _onStartReached = () => { - if (this.state.first <= 0 || this.state.previousLoading) { + if ( + this.state.empty || + this.state.first <= 0 || + this.state.previousLoading + ) { return; } @@ -328,7 +332,11 @@ class FlatListExample extends React.PureComponent { }, LOAD_TIME); }; _onEndReached = () => { - if (this.state.last >= PAGE_SIZE * NUM_PAGES || this.state.nextLoading) { + if ( + this.state.empty || + this.state.last >= PAGE_SIZE * NUM_PAGES || + this.state.nextLoading + ) { return; } diff --git a/packages/rn-tester/js/examples/FlatList/FlatList-maintainVisibleContentPosition.js b/packages/rn-tester/js/examples/FlatList/FlatList-maintainVisibleContentPosition.js new file mode 100644 index 00000000000000..26ac2bfe0d3b06 --- /dev/null +++ b/packages/rn-tester/js/examples/FlatList/FlatList-maintainVisibleContentPosition.js @@ -0,0 +1,99 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +import type {RenderItemProps} from '../../../../virtualized-lists/Lists/VirtualizedListProps'; +import type {RNTesterModuleExample} from '../../types/RNTesterTypes'; + +import * as React from 'react'; +import {useCallback, useState} from 'react'; +import {Button, FlatList, StyleSheet, Text, View} from 'react-native'; + +const DATA = Array.from({length: 20}, (_, i) => ({ + id: i.toString(), +})); + +const MAINTAIN_VISIBLE_CONTENT_POSITION = {minIndexForVisible: 0}; + +export function FlatList_maintainVisibleContentPosition(): React.Node { + const [height, setHeight] = useState(200); + const [isItemResponsive, setIsItemResponsive] = useState(true); + + const changeHeight = useCallback(() => { + setHeight(prevHeight => (prevHeight === 200 ? 400 : 200)); + }, []); + + const toggleResponsiveness = useCallback(() => { + setIsItemResponsive(prevIsItemResponsive => !prevIsItemResponsive); + }, []); + + const renderItem = useCallback( + ({item}: RenderItemProps<{id: string}>) => ( + + + {item.id} + + + ), + [height, isItemResponsive], + ); + + return ( + + + +