Compare commits

...
Author SHA1 Message Date
Distiller 24b682081b [0.72.3] Bump version numbers 2023-07-12 10:38:28 +00:00
Lorenzo Sciandra 8f41f25c21 Revert "Fix pod install for swift libs using new arch (#38121)"
This reverts commit 7a4ae799b8.
2023-07-12 11:13:30 +01:00
Distiller b95c87daa0 [0.72.2] Bump version numbers 2023-07-11 10:37:43 +00:00
Lorenzo Sciandra 63f78ea8de [LOCAL] remove stub types from dependencies 2023-07-10 14:24:51 +01:00
Lorenzo Sciandra 839091b33f Revert "[LOCAL] fix the metro-config version or it will pick the wrong one on CI"
This reverts commit 73ca044871.
2023-07-10 14:00:04 +01:00
Lorenzo Sciandra 73ca044871 [LOCAL] fix the metro-config version or it will pick the wrong one on CI 2023-07-10 13:55:27 +01:00
Lorenzo Sciandra f37386176c bumped packages versions
#publish-packages-to-npm
2023-07-10 13:31:11 +01:00
Lorenzo Sciandra ba5fa9c394 [LOCAL] bump CLI to 11.3.5 and Metro do 0.76.7 2023-07-10 13:30:38 +01:00
Riccardo CipolleschiandLorenzo Sciandra 978185077d Restore envinfo for test_windows (#38062)
Summary:
We had to disable the envinfo command on test_windows to get the CI back to green.

The reason why it started failing is because they released 7.9.0 which does not seem to have the executable on Windows, so `npx` fails to find what to run.

This fix restore the command in a way that it should display the envinfo using an older version of the package. I also added a task to come back to this periodically.

## Changelog:

[Internal] - Restore envinfo on windows

Pull Request resolved: https://github.com/facebook/react-native/pull/38062

Test Plan: - CircleCI: test_windows stays green

Reviewed By: cortinico

Differential Revision: D47016995

Pulled By: cipolleschi

fbshipit-source-id: 368367caed7ea49d7419475580a39f9406c54757

# Conflicts:
#	.circleci/config.yml
2023-07-10 11:49:23 +01:00
Lorenzo Sciandra 21daa6e790 bumped packages versions
#publish-packages-to-npm
2023-07-10 11:46:37 +01:00
Riccardo CipolleschiandLorenzo Sciandra 470449722f Update when view are added to the ViewRegistry (#38223)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38223

Before this change, the InteropLayer was adding the view to the registry right before invoking a command and right after the command was invoked. This model was too strict as some view commands may have async behaviors that make the lookup in the registry fail.

After this change, we are going to register the view when it's created and we are going to remove it when the view is deallocated.

## Changelog:
[iOS][Changed] - Update logic to add and remove views in the view registry for the interop layer.

Reviewed By: sammy-SC

Differential Revision: D47262664

fbshipit-source-id: 503f4e29e03bfc7ad861c1502129822b383ffcc0
2023-07-10 11:44:18 +01:00
Kudo ChienandLorenzo Sciandra 1683b1250f add InitializeCore in getModulesRunBeforeMainModule (#38207)
Summary:
the `IntializeCore` is critical to react-native for setup polyfills. without this, we would have some erros like undefined `global.performance`. since the effort is now proposing `react-native/metro-config` as universal metro-config, it is better to have the `IntializeCore` in it.

we ran into issues when using expo-cli in bare react-native projects. it happens when using [the default metro config](https://github.com/facebook/react-native/blob/5f84d7338f42fe9b1d5bf2a9b1c8321b59551f15/packages/react-native/template/metro.config.js) and starting metro server without the react-native-community-cli.

### Why the issue does not happen on `yarn react-native start`?

when using `yarn react-native start`, the react-native-community-cli will merge its internal metro-config with the `InitializeCore` ([https://github.com/facebook/react-native/issues/1](https://github.com/react-native-community/cli/blob/5d8a8478cd104adf4a4dd34c09c2e256325ae61d/packages/cli-plugin-metro/src/commands/start/runServer.ts#L56), [https://github.com/facebook/react-native/issues/2](https://github.com/react-native-community/cli/blob/e8e7402512da8c3fbbc58a195284ef0008c7491f/packages/cli-plugin-metro/src/tools/loadMetroConfig.ts#L51-L61)). that's why the issue doesn't happen on react-native-community-cli.

## Changelog:

[GENERAL][FIXED] - `global.performance` in undefined when starting metro from Expo CLI

Pull Request resolved: https://github.com/facebook/react-native/pull/38207

Test Plan:
```sh
$ npx react-native init RN072 --version 0.72
$ cd RN072
$ yarn add expo
$ npx expo run:ios
# then it hits the exception because the global.performance is undefined.
```

Reviewed By: rshest

Differential Revision: D47257439

Pulled By: huntie

fbshipit-source-id: ae294e684047e503d674f0c72563b56d1803ba36
2023-07-10 11:44:10 +01:00
ferguseanandLorenzo Sciandra e163a131f1 fix: repairs $EXTRA_COMPILER_ARGS error with multiple args (#38147)
Summary:
Fixes a regression added [on merge of https://github.com/facebook/react-native/issues/37531](https://github.com/facebook/react-native/commit/260bcf7f1bf78022872eb2f40f33fb552a414809#diff-16a358d6a9dea8469bfdb899d0990df1c32b8c3b1149c86685bec81f50bd24beR179) (though oddly I don't see it in [https://github.com/facebook/react-native/issues/37531's diff](https://github.com/facebook/react-native/pull/37531/files#diff-16a358d6a9dea8469bfdb899d0990df1c32b8c3b1149c86685bec81f50bd24beR179), so perhaps added during conflict resolution?) where multiple arguments in `$EXTRA_COMPILER_ARGS` are now incorrectly wrapped in quotes, including RN's own sourcemap support:

```
runner@SeansMacBookGo sampleapp % /Users/runner/builds/y_x6gsp4/0/sampleapp/ios/Pods/hermes-engine/destroot/bin/hermesc -emit-binary -max-diagnostic-width=80 '-O -output-source-map' -out /Users/runner/builds/y_x6gsp4/0/sampleapp/ios/build/derived-data/Build/Intermediates.noindex/ArchiveIntermediates/sampleapp/BuildProductsPath/Release-iphoneos/sampleapp.app/main.jsbundle /Users/runner/builds/y_x6gsp4/0/sampleapp/ios/build/derived-data/Build/Intermediates.noindex/ArchiveIntermediates/sampleapp/BuildProductsPath/Release-iphoneos/main.jsbundle
hermesc: Unknown command line argument '-O -output-source-map'.  Try: '/Users/runner/builds/y_x6gsp4/0/sampleapp/ios/Pods/hermes-engine/destroot/bin/hermesc -help'
hermesc: Did you mean '-output-source-map'?
```

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[IOS] [FIXED] - Fix build error when there are multiple EXTRA_COMPILER_ARGS

Pull Request resolved: https://github.com/facebook/react-native/pull/38147

Test Plan: Removing the quotes and running the command results a successful run of `hermesc` (exit code 0 and the expected files produced).

Reviewed By: rshest

Differential Revision: D47254412

Pulled By: cipolleschi

fbshipit-source-id: 96b71bb05c7a6939088816e76a9a2d02e89ed768
2023-07-10 11:44:03 +01:00
Nicola CortiandLorenzo Sciandra ee8d5e0259 Compile hermes-engine with -DHERMES_ENABLE_DEBUGGER=False on Release (#38212)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38212

This mirrors the same logic that the Hermes team has on facebook/hermes.
Practically, we want to pass the CMake config flag `HERMES_ENABLE_DEBUGGER=False` only for Release
so that their CMake build is configured correctly.

Their build always enables the Debugger and allows us to selectively turn it off only for release
builds.

More context: https://github.com/facebook/hermes/commit/eabf5fcd25

Changelog:
[Internal] [Changed] - Compile hermes-engine with -DHERMES_ENABLE_DEBUGGER=False on Release

Reviewed By: cipolleschi

Differential Revision: D47252735

fbshipit-source-id: 9b5cd801dea3b540a3f80b0d0975e05984f1d9b9
2023-07-10 11:43:54 +01:00
evelantandLorenzo Sciandra fe2964a84c Fix build failure on iOS with pnpm and use_frameworks! (#38158)
Summary:
Fix build failure on iOS with pnpm and use_frameworks! due to cocoapods copying symlinked headers to wrong paths

When using pnpm all packages are symlinked to node_modules/.pnpm to prevent phantom dependency resolution. This causes react-native iOS build to fail because Cocoapods copies headers to incorrect destinations when they're behind symlinks. The fix resolves absolute paths to the header_mappings_dir at pod install time. With absolute paths cocoapods copies the headers correctly.

This commit also adds a few missing header search paths in use_frameworks! mode.

Fixes https://github.com/facebook/react-native/issues/38140

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[IOS] [FIXED] - Build failure with pnpm and use_frameworks! due to incorrect header paths

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests

Pull Request resolved: https://github.com/facebook/react-native/pull/38158

Test Plan:
1. `pnpm pnpx react-native@latest init AwesomeProject`
2. `cd AwesomeProject`
3. `rm -rf node_modules yarn.lock`
4. `mkdir patches`
5. copy [react-native@0.72.1.patch](https://github.com/facebook/react-native/files/11937570/react-native%400.72.1.patch) to `patches/`
6. Add patch to package.json
```
"pnpm": {
    "patchedDependencies": {
        "react-native@0.72.1": "patches/react-native@0.72.1.patch"
    }
}
```
7. `pnpm install`
8. `cd ios`
9. `NO_FLIPPER=1 USE_FRAMEWORKS=static pod install`
10. `cd ..`
11. `pnpm react-native run-ios`

Hopefully an automated test of building with `pnpm` can be added to CI. I don't know how to make that happen, hopefully someone at facebook can do it.

Reviewed By: dmytrorykun

Differential Revision: D47211946

Pulled By: cipolleschi

fbshipit-source-id: 87640bd3f32f023c43291213b5291a7b990d7e1f
2023-07-10 11:43:46 +01:00
Matt BlagdenandLorenzo Sciandra 965169fe0c Enable debugging in debug build (#38205)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38205

Enable the preprocessor flag to allow debugging when in a debug build. This flag influences the Hermes headers included in the inspector, and causes them to include the debugging functionality.

Changelog:
    [General][Fixed] - Re-enabled debugging for debug builds

Reviewed By: lunaleaps, cortinico

Differential Revision: D47243235

fbshipit-source-id: 7982c69ab554335a9ad985394e4416ed69831137
2023-07-10 11:43:35 +01:00
Koichi NagaokaandLorenzo Sciandra 0759422053 Fix onChangeText not firing when clearing the value of TextInput with multiline=true on iOS (#37958)
Summary:
This fix fixes the TextInput issue in https://github.com/facebook/react-native/issues/37784 with onChangeText not working on iOS only.

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[IOS] [FIXED] - Fix onChangeText not firing when clearing the value of TextInput with multiline=true on iOS

Pull Request resolved: https://github.com/facebook/react-native/pull/37958

Test Plan:
1. Run the repro code given in the issue (https://github.com/facebook/react-native/issues/37784).
2. Verified that onChangeText works after pressing the submit button.
3. Run the repro code from the issue (https://github.com/facebook/react-native/issues/36494) that caused this issue.
4. Verified that issue (https://github.com/facebook/react-native/issues/36494) is not reoccurring.

Reviewed By: rshest

Differential Revision: D47185775

Pulled By: dmytrorykun

fbshipit-source-id: 1a1a6534d6bf8b5bb8cf1090734dd894bab43f82
2023-07-10 11:43:27 +01:00
Samuel SuslaandLorenzo Sciandra 914db09a8e Disable nstextstorage_caching in OSS (#38129)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38129

changelog: [iOS] Disable NSTextStorage caching in OSS

A [bug was reported](https://github.com/facebook/react-native/issues/37944) for NSTextStorage caching. Even thought I fixed the bug in D47019250, I want to disable the feature in OSS until the fix is verified in Facebook app.
My plan is to pick this commit for 0.72.1 and reenable NSTextStorage caching once the fix is validated.

Reviewed By: NickGerleman

Differential Revision: D47127912

fbshipit-source-id: 97694e383eb751e89b776c0599969f2c411bac6f
2023-07-10 11:43:18 +01:00
louiszawadzkiandLorenzo Sciandra 7a4ae799b8 Fix pod install for swift libs using new arch (#38121)
Summary:
This fixes a bug that started with React Native 0.72.0 when using the new architecture and installing a native lib that has Swift code (in my case, `datadog/mobile-react-native`).

Running `pod install` errors with the following output (`DatadogSDKReactNative` is the pod containing the Swift code):

```
[...]
Analyzing dependencies
Downloading dependencies
Installing DatadogSDKReactNative 1.8.0-rc0
[!] The following Swift pods cannot yet be integrated as static libraries:

The Swift pod `DatadogSDKReactNative` depends upon `React-Fabric`, `React-graphics`, `React-utils`, and `React-debug`, which do not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set `use_modular_headers!` globally in your Podfile, or specify `:modular_headers => true` for particular dependencies.
```

Indeed, this pods were added as dependencies in `packages/react-native/scripts/cocoapods/new_architecture.rb` but do not define modules contrary to the other pods in the list.

This PR is solving a problem that already occured in the past and was solved here: https://github.com/facebook/react-native/pull/33743
It's a new implementation for the PR initially opened here: https://github.com/facebook/react-native/pull/38039

## Changelog:
[IOS] [FIXED] - Fix pod install for libraries using Swift code when the new architecture is enabled

Pull Request resolved: https://github.com/facebook/react-native/pull/38121

Test Plan:
1. Clone [this](https://github.com/louiszawadzki/react-native) repo
2. From `main`, add a Swift file to the `MyNativeView` native module in the RN tester app (see inspiration from [this commit](https://github.com/fortmarek/react-native/commit/26958fccf4b4ac90d0bf9bb3699f12760a6b2b58))
3. Try to run `RCT_NEW_ARCH_ENABLED=1 USE_HERMES=0 bundle exec pod install` inside the `packages/rn-tester`
4. Observe errors
5. Apply [the commit](https://github.com/facebook/react-native/commit/7b7c3ff530cae07daccc5b5ea6b72d239f913be0) from this PR
6. Both pod install and the subsequent build should succeed.
7. Revert the changes and repeat steps 2 to 6 with `RCT_NEW_ARCH_ENABLED=1 USE_HERMES=1 bundle exec pod install`

Reviewed By: cortinico

Differential Revision: D47127854

Pulled By: cipolleschi

fbshipit-source-id: bf7f65e0d126195a76a0fafbe2f3172f00d5adc1

# Conflicts:
#	packages/react-native/ReactCommon/react/renderer/debug/React-rendererdebug.podspec
2023-07-10 11:42:52 +01:00
Alex HuntandLorenzo Sciandra e2506760c0 Add global hook to assert that base Metro config is called (#38126)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38126

Towards https://github.com/react-native-community/cli/issues/1987. Will be paired with a CLI PR targeting React Native 0.72.1.

Changelog: None

Reviewed By: motiz88

Differential Revision: D47125080

fbshipit-source-id: b3b9d93ba747240f5168021ccb793ffe5d34251d
2023-07-10 11:40:10 +01:00
Adrian HartantoandLorenzo Sciandra 03b9b52990 Remove okhttp internal util usage (#37843)
Summary:
Remove okhttp internal `Util` usage so it can be compatible with [okhttp 5.0.0 alpha](https://square.github.io/okhttp/changelogs/changelog/#version-500-alpha7).

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[ANDROID] [CHANGED] - Remove okhttp3 internal util usage

Pull Request resolved: https://github.com/facebook/react-native/pull/37843

Test Plan: None, the implementation is based on okhttp internal util

Reviewed By: NickGerleman

Differential Revision: D46764363

Pulled By: cortinico

fbshipit-source-id: e46770625f19057fa7374be15e92903d7966f880
2023-07-10 11:39:57 +01:00
Harry YuandLorenzo Sciandra a46a7cd1f6 Prevent crash in runAnimationStep on OnePlus and Oppo devices (#37487)
Summary:
We've been encountering a crash in `runAnimationStep` with "Calculated frame index should never be lower than 0" https://github.com/facebook/react-native/issues/35766 with OnePlus/Oppo devices as well, but don't have one on hand to test.

This just works around the issue: if the time is before the start time of an animation, we shouldn't do anything anyways, so we just log a message instead of throwing while in production. We still throw in debug mode though for easier debugging.

### Hypothesis of the root cause

Based on stacktrace in https://github.com/facebook/react-native/issues/35766 (which is the same one we see)

Normally, this should happen

1. Choreographer.java constructs a FrameDisplayEventReceiver
2. FrameDisplayEventReceiver.onVSync gets called, which sets the `mTimestampNanos`
3. FrameDisplayEventReceiver.run gets called, which then eventually calls our `doFrame` callback with `mTimestampNanos`. This then causes `FrameBasedAnimationDriver.runAnimationStep` to be called with the same timestamp

I suspect what's happening on OnePlus devices is that the `onVSync` call either doesn't happen or happens rarely enough that the `mTimestampNanos` when `run` is called is sometime in the past

### Fix

1. Add logging so we get the parameters to debug more if we end up getting this error
2. In production, just ignore past times instead of throwing an Error

## Changelog:

Pick one each for the category and type tags:

[ANDROID] [FIXED] - Prevent crash on OnePlus/Oppo devices in runAnimationStep

Pull Request resolved: https://github.com/facebook/react-native/pull/37487

Test Plan: Ran our app using patched version and verified no issues showed up when using it

Reviewed By: cipolleschi

Differential Revision: D46102968

Pulled By: cortinico

fbshipit-source-id: bcb36a0c2aed0afdb8e7e68b141a3db4eb02695a
2023-07-10 11:39:28 +01:00
d73b61c7c7 Do not create RuntimeExecutor on non-JSI executors (#38125) (#38142)
Co-authored-by: Pieter De Baets <pieterdb@meta.com>
resolved: https://github.com/facebook/react-native/pull/38125
2023-07-10 11:27:43 +01:00
Lorenzo Sciandra e22bd7f6a9 [LOCAL] update podlock 2023-07-05 14:26:25 +01:00
Distiller 73293f2c16 [0.72.1] Bump version numbers 2023-06-29 16:57:00 +00:00
Riccardo Cipolleschi 8ce471e2fa [LOCAL] Bump SocketRocket to 6.1.0 2023-06-29 15:52:06 +01:00
Lorenzo Sciandra a8cfeb92a4 [LOCAL] update podlock file for RNTester 2023-06-29 14:00:55 +01:00
Bernhard Owen JosephusandLorenzo Sciandra 92d50d4f4c Resubmit D46501420 (#37790)
Summary:
Multiline text in Android shows some extra space. It's easily noticeable when you set the text `alignSelf` to `flex-start`. This is because we are using `layout.getLineWidth` which will include trailing whitespace.
<img width="300" alt="image" src="https://github.com/facebook/react-native/assets/50919443/8939092b-caef-4ad8-9b34-2ccef5d20968">

Based on Android doc, `getLineMax` exclude trailing whitespace.
<img width="625" alt="image" src="https://github.com/facebook/react-native/assets/50919443/0b32e842-5fab-4fc7-8fd9-299877b9c553">

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID] [FIXED] - Exclude trailing whitespace from newline character on measuring text line width

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[ANDROID] [FIXED] - Exclude trailing whitespace from newline character on measuring text line width

Pull Request resolved: https://github.com/facebook/react-native/pull/37790

Test Plan:
After applying the changes:
<img width="300" alt="image" src="https://github.com/facebook/react-native/assets/50919443/bfbf52b0-7e7d-4c89-8958-6af38d8bc1c7">

Code snippet:
```
<Text style={{backgroundColor: 'red', alignSelf: 'flex-start', color: 'white'}}>
    1{'\n'}
</Text>
```

Reviewed By: cortinico

Differential Revision: D46586516

Pulled By: NickGerleman

fbshipit-source-id: 3ea9c150ad92082f9b4d1da453ba0ef04b09ce51
2023-06-29 13:56:49 +01:00
Riccardo CipolleschiandRiccardo Cipolleschi 4ddfeb6181 Warn users when a component is registered in Rendere and in the interop (#38089)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38089

This change add a warning if a component is registered in both the New Renderer and in the Interop layer.

This can help users migrating their components once the library has been migrated.

[iOS][Added] - Add warning to help users migrate away from the interop layer.

Reviewed By: cortinico

Differential Revision: D47053556

fbshipit-source-id: cc2ba09db16aaa370947a77173b6ea6a0acfa519
2023-06-28 16:16:16 +01:00
Riccardo CipolleschiandRiccardo Cipolleschi f5372578ac Implement multiple manager lookup for the interop layer (#38093)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38093

In [this issue](https://github.com/facebook/react-native/issues/37905), the community detected a strict assumption in the interop layer for which, given a component `XXXView`, its ViewManager must be called `RCTXXXViewManager`.

That's not the case for some components, for example, `BVLinearGradient`, which View manager is `BVLinearGradientManager` and not `RCTBVLinearGradientManager`.

This diff adds a secondary lookup logic:
1. We look for the `RCTXXXViewManager`.
2. If not found, we look for `XXXViewManager`.

We will assess whether to generalize this logic once and for all or to expand other lookup cases on an example/failure basis as it's not a goal to have a 100% accurate interop layer. The Goal is to cover most use cases.

[iOS][Added] - Allow to lookup for ViewManager without the RCT prefix in the Interop Layer

Reviewed By: sammy-SC

Differential Revision: D47055969

fbshipit-source-id: 1d31f3f4bc6f1f543edbd157ce04ad9daf23dbc6
2023-06-28 16:06:34 +01:00
Lorenzo Sciandra 95db9f98f2 bumped packages versions
#publish-packages-to-npm
2023-06-28 15:35:42 +01:00
Lorenzo Sciandra da84901f78 [LOCAL] bump CLI to 11.3.3 2023-06-28 15:33:38 +01:00
Lorenzo Sciandra 10beefbbfa [LOCAL] reapply "Set kotlin.jvm.target.validation.mode=warning on user projects" by Nicola 2023-06-28 15:30:42 +01:00
Alex HuntandLorenzo Sciandra 78c1a7e322 Restore base config merge in metro-config (#38092)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38092

Reverts https://github.com/facebook/react-native/pull/36777.

This is motivated by reducing user friction when the widespread assumption is for `react-native/metro-config` to export a complete Metro config, as with Expo/rnx-kit, and like previously understood uses of `metro-config`. See https://github.com/facebook/metro/issues/1010#issuecomment-1609215165 for further notes.

Fixes:
- https://github.com/facebook/metro/issues/1010
- https://github.com/facebook/react-native/issues/38069
- https://github.com/kristerkari/react-native-svg-transformer/issues/276

Note that we do not intend for `react-native/metro-config` to directly export `assetExts` etc — these can be accessed on the `resolver` property from the full config object.

Changelog: [General][Changed] `react-native/metro-config` now includes all base config values from `metro-config`

Reviewed By: robhogan

Differential Revision: D47055973

fbshipit-source-id: 5ad23cc9700397110de5c0e81c7d76299761ef0a
2023-06-28 15:29:25 +01:00
Samuel SuslaandLorenzo Sciandra 69705a46b1 Add nullptr check to SharedFunction (#38075)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38075

changelog: [internal]

`SharedFunction<>` is created with nullptr for its internal `std::function`. If called after created with default constructor, it crashes app. It also does not have API to check if its internal function is not nullptr.

With image cancelation, there is a race between when native component calls `imageRequest.cancel()` and when cancelation function is set in `RCTImageManager`.
To fix this, this diff adds a nullptr check inside SharedFunction. So it is always safe to call.

Reviewed By: javache

Differential Revision: D47022957

fbshipit-source-id: 0a04a87cd1ffe6bf3ca2fded38f689f06cc92ca9
2023-06-28 15:29:17 +01:00
Tommy NguyenandLorenzo Sciandra ba46e5b2cd fix(virtualized-lists): react-test-renderer is not a runtime dependency (#37955)
Summary:
Installing `react-native` 0.72.x causes a warning about `react-test-renderer` because `react-native/virtualized-lists` has declared a peer dependency on it. As far as I know, it is not used for anything but tests.

```
➤ YN0002: │ react-native@npm:0.72.0-rc.6 [292eb] doesn't provide react-test-renderer (p5a2fb), requested by react-native/virtualized-lists
```

Note that while many package managers default to warnings in this case, there are still a number of users out there for which this is an error.

## Changelog:

[GENERAL] [FIXED] - `react-native/virtualized-lists` does not need `react-test-renderer` at runtime

Pull Request resolved: https://github.com/facebook/react-native/pull/37955

Test Plan: n/a

Reviewed By: rshest

Differential Revision: D46871536

Pulled By: NickGerleman

fbshipit-source-id: 1e5e15608ab394bc43cd4e6ac727a74734874642
2023-06-28 15:29:10 +01:00
Pranav YadavandLorenzo Sciandra 4d8a6a225c Add README to RN Template App, added when npx react-native@latest init <AppName> (#37521)
Summary:
[skip-ci]
I noticed that; when a _new_ RN App is created using RN CLI there is ***NO*** *README* file added to the project.
Having a simple README file explaining what type of project it is, for example how other web projects do it, such as long lived `create-react-app`, now widely used `create-next-app`, etc.

Why not for React Native App then?

This PR; Adds README file to RN Template App , which should be added to the project when a new project is created using RN CLI.

### Website PR: https://github.com/facebook/react-native-website/pull/3732 🚀😇

bypass-github-export-checks

## Changelog:

[INTERNAL] [ADDED] - Add README to RN Template App 

Pull Request resolved: https://github.com/facebook/react-native/pull/37521

Test Plan: - The README file should be included in the newly created RN App using RN CLI

Reviewed By: NickGerleman

Differential Revision: D46075719

Pulled By: cipolleschi

fbshipit-source-id: efcccc09d72c57a065b36de6e787594082000e15
2023-06-28 15:28:03 +01:00
Tommy NguyenandGitHub 0b96bdcf32 fix(ios): fix pod install --project-directory=ios failing (#37994) 2023-06-23 13:44:33 +02:00
Distiller 7a893e4110 [0.72.0] Bump version numbers 2023-06-21 14:15:09 +00:00
Riccardo Cipolleschi 386387762e [LOCAL] update podfile.lock 2023-06-13 18:01:31 -04:00
Distiller ec4771b79a [0.72.0-rc.6] Bump version numbers 2023-06-13 19:39:32 +00:00
Lorenzo Sciandra a2df07ea2a [LOCAL] bump CLI to 11.3.2 2023-06-13 15:51:08 +01:00
Lorenzo Sciandra b2f273750b bumped packages versions
#publish-packages-to-npm
2023-06-13 15:50:05 +01:00
Gabriel DonadelandLorenzo Sciandra 0817eaa301 Revert "fix: border width top/bottom not matching the border radius" (#37840)
Summary:
In an effort to fix https://github.com/facebook/react-native/issues/37753, this PR reverts the changes introduced by https://github.com/facebook/react-native/commit/cd6a91343ee24af83c7437b3f2449b41e97760e9 and https://github.com/facebook/react-native/commit/1d5103227851ab92de889d5e7e910393b5d8743a so border-radius width calculations work as expected

## Changelog:

[ANDROID] [FIXED] - Fix border-radius width calculations

Pull Request resolved: https://github.com/facebook/react-native/pull/37840

Test Plan:
Test border colors along with border-radius through RNTester
<img width="538" alt="image" src="https://github.com/facebook/react-native/assets/11707729/4b148d4b-35dc-4737-be00-c5ff156b0865">

Reviewed By: dmytrorykun

Differential Revision: D46684071

Pulled By: cipolleschi

fbshipit-source-id: cf7a80d0d63009b457f03d690b632e332a9b4a02
2023-06-13 15:49:11 +01:00
Nicola CortiandLorenzo Sciandra 0da7e06f3f Remove CallInvoker parameter from toJs method in Codegen (#37832)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37832

This parameter is currently unused and is causing Android builds to fail
as they compile with `-Wall`

This is a follow-up to https://github.com/facebook/react-native/pull/37454/ as that PR updated only the `fromJs` and not the `toJs` method as well.

Changelog:
[Internal] [Changed] - Remove CallInvoker parameter from toJs method in Codegen

Reviewed By: rshest

Differential Revision: D46647110

fbshipit-source-id: 1f3e22aca7a3df11ac02b5c4b89c9311b8b1798c
2023-06-13 15:49:04 +01:00
Gabriel DonadelandLorenzo Sciandra 2d15f50912 Fix Android border clip check (#37828)
Summary:
Instead of requiring all  types of border color values to be present we should only take into consideration the left, top, right, bottom, and allEdges values and inject block values into  colorBottom and colorTop.

This PR only addresses the first issue described here (https://github.com/facebook/react-native/issues/37753#issuecomment-1587196793) by kelset

## Changelog:

[ANDROID] [FIXED] - Fix border clip check

Pull Request resolved: https://github.com/facebook/react-native/pull/37828

Test Plan:
Test through rn-tester if border color is being applied

<img width="482" alt="image" src="https://github.com/facebook/react-native/assets/11707729/c8c8772c-da8d-4393-bc3f-5868eca5df15">

Reviewed By: lunaleaps

Differential Revision: D46643773

Pulled By: cipolleschi

fbshipit-source-id: efb1ea81bf2462c14767a2554880eb7c44989975
2023-06-13 15:48:58 +01:00
Gabriel DonadelandLorenzo Sciandra 27600427a9 Fix loading NODE_BINARY inside Generate Legacy Components Interop (#37802)
Summary:
When trying to build an app using 0.72.0-RC.5 inside a project that uses `.xcode.env.local` the  `[CP-User] Generate Legacy Components Interop` Phase script fails to run due to a `Permission denied` error. That's because `.xcode.env.local` is not being loaded, resulting in `NODE_BINARY=" "` and then the `React-RCTAppDelegate` script tries to run `generate-legacy-interop-components.js` directly.

E.g

![image](https://github.com/facebook/react-native/assets/11707729/ce72d7d1-69ab-4477-a754-10cd52bb21a2)

In order to fix this we should run the `with-environment.sh` script instead of directly loading `.${PODS_ROOT}/../.xcode.env`

## Changelog:

[IOS] [FIXED] - Fix loading `NODE_BINARY` inside Generate Legacy Components Interop

Pull Request resolved: https://github.com/facebook/react-native/pull/37802

Test Plan: Make sure you don't have a `.xcode.env` file and run locally a project that uses React-RCTAppDelegate

Reviewed By: cortinico

Differential Revision: D46596246

Pulled By: cipolleschi

fbshipit-source-id: 5616395f39b0fae7b2fa9e59bd72c70f39198b4d
2023-06-13 15:48:51 +01:00
Alexander EggersandLorenzo Sciandra 8ed2cfded5 Add support for building with Xcode 15 (#37758)
Summary:
Fixes https://github.com/facebook/react-native/issues/37748

This PR adds a patch which fixes a build issue in Xcode 15.

## Changelog:

[IOS] [ADDED] - Add support for building with Xcode 15

Pull Request resolved: https://github.com/facebook/react-native/pull/37758

Reviewed By: cortinico

Differential Revision: D46524009

Pulled By: cipolleschi

fbshipit-source-id: 9f6c12e12a15c154467282a7b4a00e80e5cc0af2
2023-06-13 15:48:44 +01:00
Jakub TrzebiatowskiandLorenzo Sciandra 73f4a788f1 Fixed random styling for text nodes with many children (#36656)
Summary:
Attempting to fix the issue https://github.com/facebook/react-native/issues/33418

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[ANDROID] Fixed inconsistent styling for text nodes with many children

Pull Request resolved: https://github.com/facebook/react-native/pull/36656

Test Plan:
No test plan yet. I'd like to ask for help with creating one.

##

Putting template aside, I'd like to ask for a review of the approach I'm suggesting.

React Native as-is (at least in some cases) [messes up the styles](https://github.com/facebook/react-native/issues/33418#issuecomment-1485305556) for text nodes with more than 85 children, just like that.

![image](https://user-images.githubusercontent.com/2590174/227981778-7ef6e7e1-00ee-4f67-bcf1-d452183ea33d.png)

All of this text should be blue.

The root cause is that code (on Android) assumes it can assign as many `Spannable` span priority values as we'd like, while in reality, it has to be packed in an 8-bit-long section of the flags mask. So 255 possible values. In the scenario I produced, React generates three spans per text node, and for 85 text nodes, it sums up to 255. For each span, a new priority value is assigned.

As I understand it, we don't need that many priority values. If I'm not mistaken, these priorities are crucial only for ensuring that nested styles have precedence over the outer ones. I'm proposing to calculate the priority value "vertically" (based on the node's depth in the tree) not "horizontally" (based on its position).

It would be awesome if some core engineer familiar with `ReactAndroid` shared their experience with this module, especially if there are any known cases when we _know_ that we'd like to create overlapping spans fighting over the same aspects of the style.

Reviewed By: cortinico

Differential Revision: D46094200

Pulled By: NickGerleman

fbshipit-source-id: aae195c71684fe50469a1ee1bd30625cbfc3622f
2023-06-13 15:48:36 +01:00
Janic DuplessisandLorenzo Sciandra dfc64d5bcc Fix copy / paste menu and simplify controlled text selection on Android (#37424)
Summary:
Currently when using a TextInput with a controlled selection prop the Copy / Paste menu is constantly getting dismissed and is impossible to use. This is because Android dismisses it when certain method that affect the input text are called (https://cs.android.com/android/platform/superproject/+/refs/heads/master:frameworks/base/core/java/android/widget/Editor.java;l=1667;drc=7346c436e5a11ce08f6a80dcfeb8ef941ca30176?q=Editor, https://cs.android.com/android/platform/superproject/+/refs/heads/master:frameworks/base/core/java/android/widget/TextView.java;l=6792;drc=7346c436e5a11ce08f6a80dcfeb8ef941ca30176). The solution to fix this is to avoid calling those methods when only the selection changes.

I also noticed there are a lot of differences on how selection is handled in old vs new arch and a lot of the selection handling can actually be removed as it is partially the cause of this issue.

This implements 2 mitigations to avoid the issue:

- Unify selection handling via commands for old arch, like fabric. Selection is currently a prop in the native component, but it is completely ignored in fabric and selection is set using commands. I removed the selection prop from the native component on Android so now it is exclusively handled with commands like it is currently for fabric. This makes it so that when the selection prop changes the native component no longer re-renders which helps mitigate this issue. More specifically for the old arch we no longer handle the `selection` prop in `ReactTextInputShadowNode`, which used to invalidate the shadow node and cause the text to be replaced and the copy / paste menu to close.

- Only set placeholder if the text value changed. Calling `EditText.setHint` also causes the copy / paste menu to be dismissed. Fabric will call all props handlers when a single prop changed, so if the `selection` prop changed the `placeholder` prop handler would be called too. To fix this we can check that the value changed before calling `setHint`.

## Changelog:

[ANDROID] [FIXED] - Fix copy / paste menu and simplify controlled text selection on Android

Pull Request resolved: https://github.com/facebook/react-native/pull/37424

Test Plan:
Tested on new and old arch in RNTester example.

Before:

https://github.com/facebook/react-native/assets/2677334/a915b62a-dd79-4adb-9d95-2317780431cf

After:

https://github.com/facebook/react-native/assets/2677334/0dd475ed-8981-410c-8908-f00998dcc425

Reviewed By: cortinico

Differential Revision: D45958425

Pulled By: NickGerleman

fbshipit-source-id: 7b90c1270274f6621303efa60b5398b1a49276ca

# Conflicts:
#	packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java
2023-06-13 15:48:22 +01:00
Lorenzo Sciandra bab5babc98 [LOCAL] bump hermes podlock 2023-06-06 10:13:53 +01:00
Distiller a98c7c6f54 [0.72.0-rc.5] Bump version numbers 2023-06-01 09:35:34 +00:00
fortmarek 7dc11bc468 bumped packages versions
#publish-packages-to-npm
2023-06-01 09:22:51 +02:00
Distiller e11396e998 [0.72.0-rc.4] Bump version numbers 2023-05-31 07:15:26 +00:00
Riccardo Cipolleschi 60a452b485 [LOCAL] Fix performance issues in Hermes when Debug 2023-05-30 11:44:26 +01:00
32327cc177 [LOCAL] Fix hermesc for linux (#37591)
Co-authored-by: Riccardo Cipolleschi <cipolleschi@fb.com>
2023-05-26 13:52:21 +01:00
Nicola CortiandGitHub 52d2065910 [LOCAL] Make sure Java Toolchain and source/target level is applied to all projects (#37576) 2023-05-26 12:31:11 +01:00
Riccardo Cipolleschi e0c88fed2d [LOCAL] Fix Ruby tests 2023-05-26 11:02:50 +01:00
Riccardo Cipolleschi a4aaee0c5e [LOCAL] Remove double definition of task wrapper after merge conflict 2023-05-26 10:32:35 +01:00
Riccardo Cipolleschi 74e3803e4c bumped packages versions
#publish-packages-to-npm
2023-05-26 10:28:49 +01:00
Riccardo Cipolleschi 7c5dc1d9bc [LOCAL] bump metro to 0.76.5 and CLI to 11.3.1 2023-05-26 10:27:56 +01:00
Samuel SuslaandRiccardo Cipolleschi c43bd7a73a Do not use setNativeState in RuntimeScheduler::Task
Summary:
changelog: [internal]

`setNativeState` is not implemented in JSC. Let's stick to host objects for now.

Reviewed By: cipolleschi

Differential Revision: D46193786

fbshipit-source-id: 9d36801bb9faa5c144a461bcbe623762bf6947b1
2023-05-26 10:14:45 +01:00
Riccardo Cipolleschi dc6a2c384d [LOCAL] Do not use NativeState as JSC does not implement it 2023-05-25 18:17:41 +01:00
Riccardo Cipolleschi ee177cab75 [LOCAL] Remove conformance to RCTComponentViewFactoryComponentProvider which does not exists in 0.72 2023-05-25 17:34:17 +01:00
Samuel SuslaandRiccardo Cipolleschi dd9a5ab8a9 Enable RuntimeScheduler in old architecture (#37523)
Summary:

[IOS] [FIXED] - unexpected useEffects flushing semantics

Pull Request resolved: https://github.com/facebook/react-native/pull/37523

Test Plan: Run RNTester with old architecture and make sure RuntimeScheduler is used.

Reviewed By: cipolleschi

Differential Revision: D46078324

Pulled By: sammy-SC

fbshipit-source-id: 5f18cbe60e6c9c753c373f175ba413b79288a928
2023-05-25 17:17:35 +01:00
Frank CaliseandLorenzo Sciandra 00027a5ca9 chore(Podfile): fixed URL to New Arch info (#37535)
Summary:
I was following the upgrade helper from [0.71.7 -> 0.72.0-rc.3](https://react-native-community.github.io/upgrade-helper/?from=0.71.7&to=0.72.0-rc.3) and came across a comment with a URL in the Podfile changes. That comment lead to a 404, so this updates that to the correct URL.

Confirmed this was an issue on the [Roadmap to 0.72.0](https://github.com/reactwg/react-native-releases/discussions/54#discussioncomment-5976797)

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[IOS] [CHANGED] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[IOS] [CHANGED] - fixed URL to New Arch info

Pull Request resolved: https://github.com/facebook/react-native/pull/37535

Test Plan: Only updated a comment, no code changes

Reviewed By: cortinico

Differential Revision: D46145428

Pulled By: cipolleschi

fbshipit-source-id: 600274222725567e1cbae041a3dac9561da15aff
2023-05-25 16:36:48 +01:00
Rob HoganandLorenzo Sciandra 072b7f7b86 Use Content-Location header in bundle response as JS source URL (#37501)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37501

This is the iOS side of the fix for https://github.com/facebook/react-native/issues/36794.

That issue aside for the moment, the high-level idea here is to conceptually separate the bundle *request URL*, which represents a request for the *latest* bundle, from the *source URL* passed to JS engines, which should represent the code actually being executed. In future, we'd like to use this to refer to a point-in-time snapshot of the bundle, so that stack traces more often refer to the code that was actually run, even if it's since been updated on disk (actually implementing this isn't planned at the moment, but it helps describe the distinction).

Short term, this separation gives us a way to address the issue with JSC on iOS 16.4 by allowing Metro to provide the client with a [JSC-safe URL](https://github.com/react-native-community/discussions-and-proposals/pull/646) to pass to the JS engine, even where the request URL isn't JSC-safe.

We'll deliver that URL to the client on HTTP bundle requests via the [`Content-Location`](https://www.rfc-editor.org/rfc/rfc9110#name-content-location) header, which is a published standard for communicating a location for the content provided in a successful response (typically used to provide a direct URL to an asset after content negotiation, but I think it fits here too).

For the long-term goal we should follow up with the same functionality on Android and out-of-tree platforms, but it's non-essential for anything other than iOS 16.4 at the moment.

For the issue fix to work end-to-end we'll also need to update Metro, but the two pieces are decoupled and non-breaking so it doesn't matter which lands first.

Changelog:
[iOS][Changed] Prefer `Content-Location` header in bundle response as JS source URL

Reviewed By: huntie

Differential Revision: D45950661

fbshipit-source-id: 170fcd63a098f81bdcba55ebde0cf3569dceb88d
2023-05-25 16:36:41 +01:00
Tommy NguyenandLorenzo Sciandra a168f4bbcb fix: limit diagnostics width output by hermesc (#37531)
Summary:
Limit diagnostics width output by `hermesc` as they may cause slowdowns or even crashes in Gradle/Xcode when a minified bundle is used as input. This occurs because Hermes is unable to determine the terminal width when executed by Gradle/Xcode, and falls back to "unlimited". If the input is a minified bundle, Hermes will output the whole bundle for each warning.

See issues filed:
- https://github.com/microsoft/rnx-kit/issues/2416
- https://github.com/microsoft/rnx-kit/issues/2419
- https://github.com/microsoft/rnx-kit/issues/2424

## Changelog:

[GENERAL] [FIXED] - Limit diagnostics width output by `hermesc`

Pull Request resolved: https://github.com/facebook/react-native/pull/37531

Test Plan: See listed issues for repros.

Reviewed By: cipolleschi

Differential Revision: D46102686

Pulled By: cortinico

fbshipit-source-id: 1b821cad7ef0d561a5e1c13a7aedf9b10164620a
2023-05-25 16:36:31 +01:00
Riccardo CipolleschiandLorenzo Sciandra ad965a1a0d Make CircleCI caches for hermesc be version dependent (#37452)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37452

Fixes #37428

We do have cache poisoning for hermesc on Windows and Linux due to reusing the same cache key among different
React Native version. This fixes it by specifying a cache key which is version dependent + it invalidates the
caches by defining a new key.

Changelog:
[Internal] [Fixed] - Make CircleCI caches for hermesc be version dependent

Reviewed By: cortinico

Differential Revision: D45909178

fbshipit-source-id: 830c87ae45739c7053342a68dac2ee7581945c1d

# Conflicts:
#	.circleci/config.yml
2023-05-25 16:33:36 +01:00
Nicola CortiandLorenzo Sciandra 47b45df65c Make sure the Native RuntimeScheduler is initialized on Old Arch (#37517)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37517

Fixes #35778

We got reports of regressions on `useEffect` starting from 0.69+ when on Hermes.

The issue seems to be caused by a bump of the `scheduler` package from 0.20 to 0.21.
In scheduler@0.21, the method `setImmediate` gets called if available
(see https://github.com/facebook/react/pull/20834). This causes React Native to use Microtasks
which ends up in changing the semantic of useEffect.

The solution is to use the Native RuntimeScheduler properly.
On Paper specifically, we never initialized it as it's effectively initialized by the
TurboModuleManagerDelegate. Here I trigger the initialization of it on Paper as well.

Changelog:
[Android] [Fixed] - Make sure the Native RuntimeScheduler is initialized on Old Arch

Reviewed By: sammy-SC

Differential Revision: D46024807

fbshipit-source-id: d72cd774df58410467644cddeaaf37e3c227b505
2023-05-25 16:31:54 +01:00
Nicola CortiandLorenzo Sciandra cddcf09255 Add -Wno-error=cpp on App's default Cmake file (#37516)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37516

This will fail build failures from apps which are using libraries which imports
```
#include <react/renderer/graphics/conversions.h>
```
That's just a warning but our usage of `-Wall -Werror` is causing this to fail user builds.

More context on this issue here:
https://github.com/reactwg/react-native-releases/discussions/54#discussioncomment-5968545

We can revert this `-Wno-error` once we're on 0.73 as that specific #warning will be entirely
removed from the codebase.

Changelog:
[Internal] [Changed] - Add -Wno-error=cpp on App's default Cmake file

Reviewed By: dmytrorykun

Differential Revision: D46071400

fbshipit-source-id: 4937fb1255df3f2765f645dfd59f5c58526dee42
2023-05-25 16:31:47 +01:00
Nicola CortiandGitHub 5e847c4309 [LOCAL] Remove license header from android/app/build.gradle (#37514) 2023-05-22 15:32:54 +01:00
Lorenzo Sciandra 451a599fa1 bumped packages versions
#publish-packages-to-npm
2023-05-22 12:20:47 +01:00
Lorenzo Sciandra be9941223e [LOCAL] update podlock file 2023-05-22 12:19:44 +01:00
Lorenzo Sciandra f942f2183e [LOCAL] yarn lock wasn't updated during the CLI bump 2023-05-22 12:16:00 +01:00
Douglas LowderandLorenzo Sciandra a86a54e7ed fix: [gradle-plugin] 3rd party lib dependency substitution (#37445)
Summary:
For 3rd party libraries to work with a React Native fork (such as the TV repo) that uses a different Maven group for `react-android` and `hermes-android` artifacts, an additional dependency substitution is required.

## Changelog:

[Android][fixed] RNGP dependency substitutions for fork with different Maven group

Pull Request resolved: https://github.com/facebook/react-native/pull/37445

Test Plan:
- Manual tested with an existing project
- Unit tests pass

Reviewed By: rshest, dmytrorykun

Differential Revision: D45948901

Pulled By: cortinico

fbshipit-source-id: 4151a1d3616172a92c68812c3a0034c98b330d67
2023-05-22 12:14:31 +01:00
Nicola CortiandLorenzo Sciandra 472012dd04 Make sure the -DANDROID compilation flag is always included. (#37451)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37451

It seems like starting from AGP 7.4, Android is not including the `-DANDROID` flag
anymore from the NDK toolchain.

As we do have several `#ifdef` logic that takes care of having this macro set,
I'm going to make sure it's always set for both ReactAndroid, hermes-engine
and the template.

Changelog:
[Android] [Fixed] - Make sure the -DANDROID compilation flag is always included

Reviewed By: javache

Differential Revision: D45908787

fbshipit-source-id: 07284712d7bcce73dc8ea0dffd4a9d00af4de1d2
2023-05-22 12:14:24 +01:00
Christoph PurrerandLorenzo Sciandra a3b4428cad Remove unused jsInvoker from Cxx TM enums (#37454)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37454

Raised here: https://github.com/reactwg/react-native-releases/discussions/54#discussioncomment-5914928

Changelog: [Internal]

Reviewed By: rshest

Differential Revision: D45918922

fbshipit-source-id: 931d2017c37e7327ba472c36e3ac0b29b74d093d
2023-05-22 12:14:17 +01:00
Nicola CortiandLorenzo Sciandra d880c04e7a Remove deprecated POST_NOTIFICATION from PermissionsAndroid (#36936)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36936

I'm removing `POST_NOTIFICATION` as that's a typo as it should be `POST_NOTIFICATIONS`
We had both in version 0.71 so we can remove the wrong one as it's misleading for users.

Changelog:
[Android] [Removed] - Remove deprecated POST_NOTIFICATION from `PermissionsAndroid`

Reviewed By: sshic

Differential Revision: D45054310

fbshipit-source-id: be733811a1ee8e7c9d6e4986c0303eed7c07c35b
2023-05-22 12:14:10 +01:00
Kyle RoachandLorenzo Sciandra 43ff1c42dc fix(types): cross platform autoComplete for TextInput (#36931)
Summary:
Since v0.71 the autoComplete prop on TextInput is available on iOS ([release notes](https://reactnative.dev/blog/2023/01/12/version-071#component-specific-behavior)). However, this change is not reflected in the types.

Original types PR here - https://github.com/DefinitelyTyped/DefinitelyTyped/pull/65144 by chwallen

## Changelog:

[GENERAL] [FIXED] - Fix autoComplete type for TextInput

Pull Request resolved: https://github.com/facebook/react-native/pull/36931

Test Plan: Setting the autoComplete prop on TextInput to `nickname`, `organization`, `organization-title`, or `url` should not result in typescript errors.

Reviewed By: NickGerleman

Differential Revision: D45052350

Pulled By: javache

fbshipit-source-id: 40993833b4ed14f91e3bf3521a264ea93517a0c9
2023-05-22 12:14:02 +01:00
Pranav YadavandGitHub 9476eb6cdc Bump CLI to v11.3.0 in 0.72-stable (#37467) 2023-05-22 11:57:34 +01:00
Ruslan LesiutinandGitHub 97986561f6 backporting babel bumps to 0.72 (#37492) 2023-05-22 11:57:11 +01:00
Lorenzo SciandraandGitHub 42fc885350 Merge pull request #37258 from bang9/cherrypick-0.72-fix-virtualized-list-for-mvcp 2023-05-22 11:56:46 +01:00
Lorenzo SciandraandGitHub 614d9f88e3 Merge pull request #37403 from lunaleaps/add-experimental-types 2023-05-22 11:56:22 +01:00
Luna Wei 8c4694f708 Remove inline props from experimental 2023-05-11 23:02:25 -07:00
Luna WeiandLuna Wei 014ea40012 Make the fabric-only CSS aliases experimental (#37338)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37338

Changelog: [General] [Changed] - Change the way types for New Architecture/experimental APIs are exposed.

Reviewed By: NickGerleman

Differential Revision: D45699522

fbshipit-source-id: 9265ce0c0964bf2e967624cb4d81c2c8a58cfbe7
2023-05-11 22:59:09 -07:00
Distiller d71ba2da34 [0.72.0-rc.3] Bump version numbers 2023-05-11 14:36:11 +00:00
Lorenzo Sciandra 9c18ad85c7 revert type bump in template 2023-05-11 11:21:17 +01:00
Riccardo Cipolleschi e1b175f137 bumped packages versions
#publish-packages-to-npm
2023-05-11 10:02:56 +01:00
Riccardo Cipolleschi 9cf1918d0d [LOCAL] bump metro to 0.76.4 and CLI to 11.2.3 2023-05-11 10:00:38 +01:00
Samuel SuslaandRiccardo Cipolleschi ca17733e2f Update scheduler package (#37295)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37295

changelog: [internal]

Update scheduler package. It will use the native scheduler if available.

Reviewed By: cortinico, cipolleschi

Differential Revision: D45634886

fbshipit-source-id: f169a1e9ab12399a0e0d7bc5e9a19c27944db1d0
2023-05-11 09:53:50 +01:00
Lorenzo Sciandra 0471f9b70f bumped packages versions
#publish-packages-to-npm
2023-05-10 17:38:08 +01:00
Lorenzo Sciandra 935d90023e [LOCAL] bump metro to 0.76.3 and CLI to 11.2.2 2023-05-10 17:37:42 +01:00
Lorenzo Sciandra eca45c28c3 bumped packages versions
#publish-packages-to-npm
2023-05-10 15:59:38 +01:00
Lorenzo Sciandra ab3fe91e9e empty commit to trigger a new patch for metro-config 2023-05-10 15:59:26 +01:00
Douglas LowderandLorenzo Sciandra e217b7f513 Read Maven group from GROUP property (#37204)
Summary:
The [React Native TV repo](https://github.com/react-native-tvos/react-native-tvos) shares most of the same Android code as the core repo. Beginning in 0.71, it needs to also publish Android Maven artifacts for the `react-android` and `hermes-android` libraries.

In order to avoid conflicts, it needs to publish the artifacts to a different group name. However, `react-native-gradle-plugin` uses a hardcoded group name (`com.facebook.react`).

Solution: read the group name from the existing `GROUP` property in `ReactAndroid/gradle.properties`.

## Changelog:

[Android] [Fixed] - read GROUP name in gradle-plugin dependency code

Pull Request resolved: https://github.com/facebook/react-native/pull/37204

Test Plan:
- Android unit tests have been added for the new code and new method in `DependencyUtils.kt`.
- Existing tests should pass
- The new code defaults to the correct group (`com.facebook.react`) so no functional change is expected in the core repo.

Reviewed By: luluwu2032

Differential Revision: D45576700

Pulled By: cortinico

fbshipit-source-id: 6297ab515b4bdbb17024989c7d3035b0a2ded0ae

# Conflicts:
#	packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/ReactPlugin.kt
2023-05-10 15:53:35 +01:00
Max MetralandLorenzo Sciandra 2bba1e325b Fix Flipper by moving FB_SONARKIT_ENABLED to RCTAppDelegate (#37240)
Summary:
An out-of-the-box react-native init project no longer enables Flipper properly as of 0.72.0-rc1.

## Changelog:

[IOS] [FIXED] Fix Flipper by moving podfile modification of preprocessor def `FB_SONARKIT_ENABLED` from React-Core to React-RCTAppDelegate where it is now used.

Pull Request resolved: https://github.com/facebook/react-native/pull/37240

Test Plan: Generated an app and verified Flipper cannot see the app. Made the modification and generated another app and verified Flipper now sees it and can enable plugins. Verified that runtime (non-test) use of FB_SONARKIT_ENABLED is limited to Libraries/AppDelegate in this project.

Reviewed By: dmytrorykun

Differential Revision: D45563282

Pulled By: cipolleschi

fbshipit-source-id: d760c5ae123cc7c967b19c6c626801d6db28d052
2023-05-10 15:52:46 +01:00
Riccardo CipolleschiandLorenzo Sciandra 1ea2c9bad9 Revert ENABLE_HERMES_PROFILER flag in cocoapods (#37228)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37228

As discussed offline, the current approach for the Hermes profiler is not the right one.

I'm partially reverting [the commit](https://github.com/facebook/react-native/commit/dce9d8d5de381fe53760ddda0d6cbbdfb5be00e4) which introduced it.

The commit did also a bit of refactoring to improve the quality of the cocoapods scripts we would like to keep.

## Changelog:
[iOS][Removed] - Remove support of Hermes profiler as that's not the right approach.

Reviewed By: cortinico

Differential Revision: D45527507

fbshipit-source-id: acea5f8b610d8b67ee7a6a91993bb8e4592d093f
2023-05-10 15:52:39 +01:00
Samuel SuslaandLorenzo Sciandra 166cc09d75 Cancel image download when ImageRequest changes (#37223)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37223

changelog: [internal]

Cancel image download when image source changes or <ImageView /> is recycled.

bypass-github-export-checks

Reviewed By: javache

Differential Revision: D45524686

fbshipit-source-id: 515a153ddb214fdce51ff29243b68c5fd5479c64
2023-05-10 15:52:33 +01:00
Samuel SuslaandLorenzo Sciandra 9d5ca3647a Delete ImageRequest::~ImageRequest (#37222)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37222

changelog: [internal]

User defined destructor does not make sense here. ImageRequest is owned by ImageState, which is owned by ImageShadowNode. ImageShadowNode requires garbage collection from the runtime to be destroyed. Calling cancel in dtor is not deterministic and that is undesired.

bypass-github-export-checks

Reviewed By: javache

Differential Revision: D45524705

fbshipit-source-id: 410def2100f479b68682620b2c43071fdfb86715
2023-05-10 15:52:26 +01:00
Samuel SuslaandLorenzo Sciandra 8d6d34644a Move cancelRequest_ in move ctor in ImageRequest (#37221)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37221

changelog: [internal]

Add missing cancelRequest_ std::move.

bypass-github-export-checks

Reviewed By: javache, cortinico

Differential Revision: D45524704

fbshipit-source-id: 1dd0d627549dab353872654d78f7b59d1b2d7174
2023-05-10 15:52:17 +01:00
Janic Duplessisandbang9 96d7c92a06 Fix VirtualizedList with maintainVisibleContentPosition (#35993)
Summary:
`maintainVisibleContentPosition` is broken when using virtualization and the new content pushes visible content outside its "window". This can be reproduced in the example from this diff. When using a large page size it will always push visible content outside of the list "window" which will cause currently visible views to be unmounted so the implementation of `maintainVisibleContentPosition` can't adjust the content inset since the visible views no longer exist.

The first illustration shows the working case, when the new content doesn't push visible content outside the window. The red box represents the window, all views outside the box are not mounted, which means the native implementation of `maintainVisibleContentPosition`  has no way to know it exists. In that case the first visible view is https://github.com/facebook/react-native/issues/2, after new content is added https://github.com/facebook/react-native/issues/2 is still inside the window so there's not problem adjusting content offset to maintain position. As you can see Step 1 and 3 result in the same position for all initial views.

The second illustation shows the broken case, when new content is added and pushes the first visible view outside the window. As you can see in step 2 the view https://github.com/facebook/react-native/issues/2 is no longer rendered so there's no way to maintain its position.

#### Illustration 1

![image](https://user-images.githubusercontent.com/2677334/163263472-eaf7342a-9b94-4c49-9a34-17bf8ef4ffb9.png)

#### Illustration 2

![image](https://user-images.githubusercontent.com/2677334/163263528-a8172341-137e-417e-a0c7-929d1e4e6791.png)

To fix `maintainVisibleContentPosition` when using `VirtualizedList` we need to make sure the visible items stay rendered when new items are added at the start of the list.

In order to do that we need to do the following:

- Detect new items that will cause content to be adjusted
- Add cells to render mask so that previously visible cells stay rendered
- Ignore certain updates while scroll metrics are invalid

### Detect new items that will cause content to be adjusted

The goal here is to know that scroll position will be updated natively by the `maintainVisibleContentPosition` implementation. The problem is that the native code uses layout heuristics which are not easily available to JS to do so. In order to approximate the native heuristic we can assume that if new items are added at the start of the list, it will cause `maintainVisibleContentPosition` to be triggered. This simplifies JS logic a lot as we don't have to track visible items. In the worst case if for some reason our JS heuristic is wrong, it will cause extra cells to be rendered until the next scroll event, or content position will not be maintained (what happens all the time currently). I think this is a good compromise between complexity and accuracy.

We need to find how many items have been added before the first one. To do that we save the key of the first item in state `firstItemKey`. When data changes we can find the index of `firstItemKey` in the new data and that will be the amount we need to adjust the window state by.

Note that this means that keys need to be stable, and using index won't work.

### Add cells to render mask so that previously visible cells stay rendered

Once we have the adjusted number we can save this in a new state value `maintainVisibleContentPositionAdjustment` and add the adjusted cells to the render mask.

This state is then cleared when we receive updated scroll metrics, once the native implementation is done adding the new items and adjusting the content offset.

This value is also only set when `maintainVisibleContentPosition` is set so this makes sure this maintains the currently behavior when that prop is not set.

### Ignore certain updates while scroll metrics are invalid

While the `maintainVisibleContentPositionAdjustment` state is set we know that the current scroll metrics are invalid since they will be updated in the native `ScrollView` implementation. In that case we want to prevent certain code from running.

One example is `onStartReached` that will be called incorrectly while we are waiting for updated scroll metrics.

## Changelog

[General] [Fixed] - Fix VirtualizedList with maintainVisibleContentPosition

Pull Request resolved: https://github.com/facebook/react-native/pull/35993

Test Plan:
Added bidirectional paging to RN tester FlatList example. Note that for this to work RN tester need to be run using old architecture on iOS, to use new architecture it requires https://github.com/facebook/react-native/pull/35319

Using debug mode we can see that virtualization is still working properly, and content position is being maintained.

https://user-images.githubusercontent.com/2677334/163294404-e2eeae5b-e079-4dba-8664-ad280c171ae6.mov

Reviewed By: yungsters

Differential Revision: D45294060

Pulled By: NickGerleman

fbshipit-source-id: 8e5228318886aa75da6ae397f74d1801d40295e8
2023-05-05 03:24:18 +09:00
Oskar Kwaśniewskiandbang9 acc5fdff47 fix: make sure initialScrollIndex is bigger than 0 (#36844)
Summary:
Hey,

`adjustCellsAroundViewport` function was checking if `props.initialScrollIndex` is truthy and -1 was returning true. This caused bugs with rendering for tvOS: https://github.com/react-native-tvos/react-native-tvos/pull/485 There are warnings in the code about `initalScrollIndex` being smaller than 0 but this if statement would still allow that.

## Changelog:

[General] [Fixed] - Make sure initialScrollToIndex is bigger than 0 when adjusting cells

Pull Request resolved: https://github.com/facebook/react-native/pull/36844

Test Plan: Pass -1 as initialScrollToIndex. Check that this code is executed.

Reviewed By: cipolleschi

Differential Revision: D44856266

Pulled By: NickGerleman

fbshipit-source-id: 781a1c0efeae93f00766eede4a42559dcd066d7d
2023-05-05 03:23:36 +09:00
Distiller 9cb7b44d4c [0.72.0-rc.2] Bump version numbers 2023-05-04 12:16:25 +00:00
Nicola CortiandGitHub 5d7c34c3c4 [LOCAL] Do not run Buck OSS on release branches (#37251) 2023-05-04 12:40:52 +01:00
Lorenzo Sciandra 138cb9187e [LOCAL] fix version of metro config 2023-05-04 12:17:40 +01:00
Lorenzo Sciandra d9d7286e8a [LOCAL] bump CLI to 11.2.1 2023-05-04 10:32:41 +01:00
Lorenzo SciandraandGitHub a0cb168aa0 Merge pull request #37230 from facebook/cipolleschi/fix_reading_hermes_tag 2023-05-03 16:05:59 +01:00
Lorenzo SciandraandGitHub 840db2122a Merge pull request #37203 from lunaleaps/revert-insets 2023-05-03 16:05:47 +01:00
Riccardo Cipolleschi 49d2009add Pass the file that needs to be read 2023-05-03 16:01:27 +01:00
Alex HuntandLorenzo Sciandra 738e01430a Set dev menu title to "React Native Dev Menu", add JS executor description (#37195)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37195

Updates the Dev Menu header on Android.

- Small alignment related to D44872456.
- Add subheading label showing current JS executor description (matching iOS) (note: on Android this is unformatted (but informative), e.g. `JSIExecutor+HermesRuntime`).

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D45142924

fbshipit-source-id: 5c95fc85e6d3b6879287440f76165b02957283e5
2023-05-03 15:08:58 +01:00
Dmitry RykunandLorenzo Sciandra 8de71e58b6 Make sure that hermes-engine is updated with cocoapods. (#37148)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37148

This should fix https://github.com/facebook/react-native/issue/36945, which is also causing annoyance when doing the releases

## Changelog:
[iOS][Changed] - Use contents of sdks/.hermesversion to let cocoapods recognize Hermes updates.

Reviewed By: cipolleschi

Differential Revision: D45394241

fbshipit-source-id: 972fbee8f954b90f7087bb232f922761c1639e06
2023-05-03 15:08:48 +01:00
Nicola CortiandLorenzo Sciandra 34d7d016b4 Remove unnecessary files in RN-Tester (#37152)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37152

Those files are unncessary and can be removed from RNTester.
* Proguard file is empty
* Signing config is unnecessary and we can use the debug one also for release.

Changelog:
[Internal] [Changed] - Remove unnecessary files in RN-Tester

Reviewed By: hoxyq

Differential Revision: D45399388

fbshipit-source-id: fd1c6cccaef668e688a699e31045bdc8103ea98e
2023-05-03 15:08:41 +01:00
Nicola CortiandLorenzo Sciandra bbecf516c0 Re-enable newArch on RN-Tester
Summary:
I accidentally turned off New Architecture on RN-Tester while shipping the Fabric Interop. This reverts it.

Changelog:
[Internal] [Changed] - Re-enable newArch on RN-Tester

Reviewed By: cipolleschi

Differential Revision: D45398914

fbshipit-source-id: 2c36f3d0440f147189de644821e1704c00353bac
2023-05-03 15:08:34 +01:00
Nicola CortiandLorenzo Sciandra 1c09228161 Do not explicitely depend on androidx.swiperefreshlayout:swiperefreshlayout (#37139)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37139

This dependency is unnecessary. React Native already exposes a `api` dependency on
`androidx.swiperefreshlayout:swiperefreshlayout` so every consumer will also get it.

This is just another line in the template we can effectively remove.

Changelog:
[Android] [Changed] - Do not explicitely depend on androidx.swiperefreshlayout:swiperefreshlayout

Reviewed By: cipolleschi

Differential Revision: D45390819

fbshipit-source-id: cce34c6a09100d36ee5eb003bb30323f64f0bb9c
2023-05-03 15:08:27 +01:00
Nicola CortiandLorenzo Sciandra fed80ad8c3 Add support for Events on the Fabric Interop Layer (#37059)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37059

This diff introduces InteropEventEmitter, a re-implementation of RCTEventEmitter that works with Fabric and allows to support events on the Fabric Interop for Android.
Thanks to this, users can keep on calling `getJSModule(RCTEventEmitter.class).receiveEvent(...)` in their legacy ViewManagers and they will be using the EventDispatcher
under the hood to dispatch events.

The logic is enabled only if the `unstable_useFabricInterop` flag is turned on. I've turned this on for the template setup and for RN Tester.

On top of this, this diff takes care also of event name "normalization".
On Fabric, all the events needs to be registered with a "top" prefix. With this diff, we'll be adding the "top" prefix at registration time, if the user hasn't added them.
This allows to use legacy ViewManagers on Fabric without having to ask users to change their event name.

Changelog:
[Android] [Added] - Add support for Events on the Fabric Interop Layer

Reviewed By: mdvacca

Differential Revision: D45144246

fbshipit-source-id: 63d4060153907c05977c976379b90574d1f69866
2023-05-03 15:07:02 +01:00
Tim YungandLorenzo Sciandra 2fcda359ba RN: Upgrade to deprecated-react-native-prop-types@4.1.0
Summary:
Upgrades React Native to `deprecated-react-native-prop-types@4.1.0`, which includes many of the new prop types in React Native v0.72.

See: https://github.com/facebook/react-native-deprecated-modules/blob/main/deprecated-react-native-prop-types/CHANGELOG.md

Changelog:
[General][Changed] - Upgrade to deprecated-react-native-prop-types@4.1.0

Reviewed By: rickhanlonii

Differential Revision: D45155955

fbshipit-source-id: 36e715c2338b667755bd1e522b7d5a2611103779
2023-05-03 15:06:55 +01:00
Alex HuntandLorenzo Sciandra d7af544bb9 Rename "Debug Menu" title to "Dev Menu" on iOS (#36981)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36981

We are (following a quick internal RFC) looking to standardise the term "[in-app] [Developer|Debug] menu" to "Dev Menu" in the React Native Debugging docs (and all docs references). (Indeed, the prevalent existing use in docs was already "Developer menu".) This PR aligns naming in the `RCTDevMenu` component on iOS.

See also https://github.com/facebook/react-native-website/pull/3692.

Changelog:
[iOS][Changed] - Rename "Debug Menu" title to "Dev Menu"

Reviewed By: christophpurrer

Differential Revision: D44872456

fbshipit-source-id: c222bb2c551a4f434a1dc0efbb8d4f75c785aa11
2023-05-03 15:06:19 +01:00
Lorenzo Sciandra dd89bfb254 [LOCAL] add missing types requirement 2023-05-03 15:04:51 +01:00
Nick GerlemanandLorenzo Sciandra 414c015da3 Bump @tsconfig/react-native to 3.0.0 (#36957)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36957

Fixes https://github.com/facebook/react-native/issues/36830

This bumps the version of tsconfig/react-native to inform TypeScript of more libraries provided by Hermes/React Native. See https://github.com/tsconfig/bases/commit/eee5f19ce8c6a9a8d8baed5ce42588b95262b1a8.

I did the search off of current Hermes/RN main branch, but I think the new config should be valid as far back as 0.71. It doesn't make sense to change the new app template for an old version though, so instead I think we should include this new version in 0.72.

Changelog:
[General][Changed] - Bump tsconfig/react-native to 3.0.0

Reviewed By: cortinico

Differential Revision: D45085932

fbshipit-source-id: 448f1103ef13f76fa95884f790a3cccd9ff75b2f

# Conflicts:
#	packages/react-native/template/package.json
2023-05-03 15:03:30 +01:00
Dmitry RykunandLorenzo Sciandra c1c8a30cc8 Do not send extra onChangeText even wnen instantianting multiline TextView (#36930)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36930

This diff fixes https://github.com/facebook/react-native/issues/36494

Now this code matches its [Fabric counterpart](https://github.com/facebook/react-native/commit/7b4889937ceb0eccdbb62a610b58525c29928be7).

There is also one extra check that `_lastStringStateWasUpdatedWith != nil`. With that in place we don't send extra `onChangeText` event when `attributedText` is assigned for the first time on TextView construction.

Changelog: [IOS][Fixed] - Do not send extra onChangeText even wnen instantianting multiline TextView

Reviewed By: sammy-SC

Differential Revision: D45049135

fbshipit-source-id: 62fa281308b9d2e0a807d024f08d8a214bd99b5e
2023-05-03 15:02:11 +01:00
Nick GerlemanandLorenzo Sciandra bab46dd321 Export EmitterSubscription TypeScript Type (#36632)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36632

Discovered when bumping the RN documentation to typecheck against 0.72, https://github.com/facebook/react-native/pull/36109 removed the `EmitterSubscription` type which should be kept public.

Changelog:
[General][Fixed] -  Export EmitterSubscription TypeScript Type

Reviewed By: cortinico

Differential Revision: D44375081

fbshipit-source-id: c8dbd5694d3a728a0a2091210894d27c9d84a012
2023-05-03 15:02:02 +01:00
Janic DuplessisandLorenzo Sciandra 37abba0193 Add fabric support for maintainVisibleContentPosition on Android (#35994)
Summary:
Implement a few missing bits for `maintainVisibleContentPosition` to work with fabric. The main thing needed is to add 2 fabric renderer listener methods to allow to hook into specific parts of the rendering process. We need some code to execute before view updates are executed and after view updates are executed. The current methods that are exposed do not work for this case. `willDispatchViewUpdates` is called from JS thread, and there doesn't seem to be a way to add UI blocks that will be executed at the right time like we do in paper. `didDispatchMountItems` is called for every frame which we don't want and will cause lots of overhead.

After that we simply need to call the right methods in the new renderer listener methods.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID] [ADDED] - Add fabric support for maintainVisibleContentPosition on Android

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

Pull Request resolved: https://github.com/facebook/react-native/pull/35994

Test Plan: Tested in RN tester maintainVisibleContentPosition example on Android with fabric enabled.

Reviewed By: cipolleschi

Differential Revision: D44131763

Pulled By: cortinico

fbshipit-source-id: 32c0b5867d460537b18a70d472fd58052da6cf80
2023-05-03 15:01:44 +01:00
Luna Wei 08fc618b77 Revert "feat: Add Fabric implementation of inset logical properties (#35692)"
This reverts commit 9669c10afc.
2023-05-02 14:22:55 -07:00
c068efcdae [0.72] Bump Metro to 0.76.2, cherry pick Metro config updates (#36976)
Co-authored-by: Deepak Jacob <deepakjacob@meta.com>
2023-04-21 10:50:47 +01:00
Lorenzo Sciandra 51de9e1ad6 [LOCAL] update podlock post release to fix CI 2023-04-11 12:14:51 +01:00
Distiller 30b5de04d6 [0.72.0-rc.1] Bump version numbers 2023-04-05 12:16:48 +00:00
Nicola CortiandLorenzo Sciandra f3b71f4843 Fix a crash new app template when createRootView is invoked with null bundle (#36796)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36796

As the title says, this fixes a instacrash on template when `createRootView` is invoked with
a bundle being null. The crash was happening as the parameter, despite being not used, is
specified as `Bundle` and is not nullable. When the Java caller passes `null`, the app crashes.

Changelog:
[Android] [Fixed] - Fix a crash new app template when `createRootView` is invoked with null bundle

Reviewed By: cipolleschi

Differential Revision: D44668305

fbshipit-source-id: 1150ddac26f19765e7340878c8850d8462c6f3fd
2023-04-04 18:36:28 +01:00
Lorenzo Sciandra c92bb3c526 [LOCAL] bump CLI to 11.1.1 2023-04-04 11:50:51 +01:00
Samuel SuslaandLorenzo Sciandra 921bbb6cf1 Correct offset when drawing text to TextStorage coordinate system. (#36771)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36771

Changelog: [internal]

Previously, when `NSTextStorage` was cached, we were not accounting for case where text which was aligned to centre or left, was used to size its container.
The result was that it was painted outside of its container, therefore invisible. To fix this, we adjust the offset to make sure text is painted correctly.

This bug only happens if:
- Text is not aligned to left in right to left writing system.
- The canvas where text is drawn is not stretched to full width of its parent.
- The offset needs to be large enough for this to matter, otherwise the text is just slightly off.
- Because of the caching mechanism, it had to be a piece of text that was rendered before. Otherwise it would work.

This complexity is worth the trouble to avoid invalidation of layout inside NSTextContainer, which is expensive.

Reviewed By: cipolleschi

Differential Revision: D44624085

fbshipit-source-id: 1bb8ef88933a49b478a2606dba6bf16b4e728b2b
2023-04-03 15:19:06 +01:00
Samuel SuslaandLorenzo Sciandra 6d6b6a8345 Only create NSAttributedString if NSTextStorage is nil (#36773)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36773

Changelog: [internal]

Do not construct `NSAttributedString` if `NSTextStorage` exists. Creating `NSAttributedString` is expensive and it isn't needed to measure text if `NSTextStorage` `exists`

Reviewed By: cipolleschi

Differential Revision: D44620292

fbshipit-source-id: 0827c514e40fcbd9626d2b7d7b6d28a3332d9aa1
2023-04-03 15:19:06 +01:00
Samuel SuslaandLorenzo Sciandra 614e4109bf Extract NSTextStorage measure into a helper method (#36772)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36772

changelog: [internal]

Move NSTextStorage into a private method.

Reviewed By: cipolleschi

Differential Revision: D44620262

fbshipit-source-id: 4855879f3c3a09b2f352ab84c906c7bd106aebda
2023-04-03 15:19:06 +01:00
Riccardo CipolleschiandLorenzo Sciandra d3c94b42f4 Fix Cocoapods for Xcode 14.3.0 (#36759)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36759

On Thursday the 30th, Apple Released Xcode 14.3.0.
This Version of Xcode enforce some version checks for which React-Codegen, which supported iOS 11 as minimum supported version, could not be build anymore.

This change ensue that React-Codegen is always aligned to the min version supported by React Native.
Plus, it moves CircleCI's Xcode to 14.3.0, to keep this problem in Check.

While working on this, I figured that, with the monorepo, Ruby tests stopped working because they were in the wrong folder: I moved them in the right one.

## Changelog:
[iOS][Fixed] - Make React Native build with Xcode 14.3.0 and fix tests

Reviewed By: blakef

Differential Revision: D44605617

fbshipit-source-id: 3ec1f5b36858ef07d9f713d74eb411a1edcccd45
2023-04-03 15:19:06 +01:00
Lorenzo SciandraandGitHub e795b534aa fix(metro-config): fix and realign the situation for metro config for 0.72 (#36746) 2023-03-31 17:44:20 +01:00
Ruslan LesiutinandGitHub 68cd44be07 Merge pull request #36573 from hoxyq/hoxyq/cherry-pick-ci-scripts-changes-to-0.72-stable
RN [refactor]: bump and realign package versions by running a single …
2023-03-31 15:53:15 +01:00
Ruslan LesiutinandRuslan Lesiutin a469927c16 RN [refactor]: bump and realign package versions by running a single script
Summary:
Changelog: [Internal]

Okay, so before the monorepo migration we had to use two scripts separately:
1. Bumping every package with `npm run bump-all-updated-packages`
2. Aligning other packages versions with `npm run align-package-versions`

The reason for it is that *before the monorepo* in a release branch cutoff process we had a step, which was removing `workspaces` keyword from `react-native` package. Without this keyword all new versions of packages will be resolved from npm (where they will be not available yet, because we have to publish them prior to it)

This is not the case for our current setup, and we can actually bump packages versions and they will be resolved as a workspaces successfully

Differential Revision: D44261057

fbshipit-source-id: 6095209c8183f6d84e2697fda2e9a21f8a57f73e
2023-03-31 13:44:43 +01:00
Alex HuntandRiccardo Cipolleschi c5f18de6a2 Update template metro.config.js, remove transitive metro dep from main package (#36723)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36723

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D44542544

fbshipit-source-id: 70807edc8a183c28e1f0018a5426f4f2e29580a0
2023-03-31 11:34:47 +01:00
Nicola CortiandRiccardo Cipolleschi 1199e4764d Add examples of Direct Manipulation in Fabric Intrerop (#36724)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36724

Similarly to iOS, this adds some examples of direct manipulation on Android using
all the various methods.

Changelog:
[Internal] [Changed] - Add examples of Direct Manipulation in Fabric Intrerop

Reviewed By: cipolleschi

Differential Revision: D44541437

fbshipit-source-id: b6e10ac0a815f41ff3c980236b7d8c6937e92065
2023-03-31 11:33:01 +01:00
Nicola CortiandRiccardo Cipolleschi cb30323f04 Add example for dispatchViewManagerCommand on Fabric Interop (#36725)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36725

This diff adds an example of using `dispatchViewManagerCommand` for the Fabric Intreop on Android.

Changelog:
[Android] [Added] - Add example for dispatchViewManagerCommand on Fabric Interop

Reviewed By: cipolleschi

Differential Revision: D44540951

fbshipit-source-id: 85bc65ad0eb3a951fbb37d61ca26532ec3cc53b7
2023-03-31 11:32:52 +01:00
Nicola CortiandRiccardo Cipolleschi 5299c60bdc Add Fabric Interop event example (#36692)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36692

Similar to the iOS counterpart,
this changes adds an example to RNTester to verify that the Interop Layer can process bubbling events in Fabric as it used to do in Paper.

Changelog:
[Internal] [Changed] - Add Fabric Interop event example

Reviewed By: cipolleschi

Differential Revision: D44467555

fbshipit-source-id: 1f1af27583c402641c549bc2926a64469dcd7b3f
2023-03-31 11:32:09 +01:00
Nicola CortiandRiccardo Cipolleschi 341cda45ee Add Fabric Interop constants example (#36693)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36693

Similar to #36417, this changes adds an example to RNTester to verify that the Interop Layer can process constants in Fabric as it used to do in Paper for Android.

Changelog:
[Android] [Added] - Add Fabric Interop constants example

Reviewed By: cipolleschi

Differential Revision: D44466391

fbshipit-source-id: 74e654319b93e60b415297dcdddc98eb100913df
2023-03-31 11:31:46 +01:00
Alex HuntandRiccardo Cipolleschi 0026f73360 Remove 'import' from default Package Exports conditions (#955)
Summary:
X-link: https://github.com/facebook/metro/pull/955

Pull Request resolved: https://github.com/facebook/react-native/pull/36584

Changelog:
[General][Changed] - Default condition set for experimental Package Exports is now `['require', 'react-native']`

The [Exports RFC](https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md) had assumed that supporting the `"import"` condition was a syntax-only difference, given we are not in a Node.js environment — and so was worthwhile to support for maximal ecosystem compatibility.

{F915841105}

This assumption is similar to [`--moduleResolution bundler` in TypeScript 5.0](https://github.com/microsoft/TypeScript/pull/51669):

> bundlers and runtimes that include a range of Node-like resolution features and ESM syntax, but do not enforce the strict resolution rules that accompany ES modules in Node or in the browser
> -- https://github.com/microsoft/TypeScript/pull/51669#issue-1467004047

However, robhogan has rightly pointed out that **we should not do this!**

- ESM (once transpiled) is **not** simply a stricter subset of in-scope features supported by CJS. For example, it supports top-level async, which would be breaking at runtime.
- We recently made the same change for our Jest environment:
    - https://github.com/facebook/react-native/commit/681d7f8113d2b5e9d6966255ee6c72b50a7d488a

As such, we are erring on the side of correctness and supporting only `['require', 'react-native']` in our defaults. At runtime, all code run by React Native is anticipated to be CommonJS. `"exports"` will instead allow React Native to correctly select the CommonJS versions of modules from all npm packages.

Metro changelog: [Experimental] Package Exports `unstable_conditionNames` now defaults to `['require']`

Reviewed By: robhogan

Differential Revision: D44303559

fbshipit-source-id: 0077e547e7775e53d1e4e9c3a9d01347f4fb7d4a
2023-03-31 11:28:56 +01:00
Lorenzo Sciandra 392a843494 [LOCAL] fix e2e local testing script post metro-config 2023-03-30 17:50:42 +01:00
Lorenzo Sciandra 8beed6ad08 [LOCAL] need to be in the rn-tester folder the whole time when testing rn-tester 2023-03-30 17:02:02 +01:00
Riccardo CipolleschiandLorenzo Sciandra a9ec217117 Fix RNTester in main (#36686)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36686

After the recent changes of Metro and Metro-Config, we need to update the path used to load the bundle in RNTester

## Changelog:
[General][Fixed] - Use the right path to load RNTester bundle

Reviewed By: cortinico

Differential Revision: D44465418

fbshipit-source-id: 96170194579792f9a5d8a141328d43e45a4db973
2023-03-30 16:56:24 +01:00
Lorenzo Sciandra d0699dc428 [LOCAL] bump CLI to 11.0.1 2023-03-30 16:47:26 +01:00
Lorenzo Sciandra 73837a72f6 [LOCAL] bump js-polyfills and virtualized-lists 2023-03-30 13:54:18 +01:00
Lorenzo Sciandra 8a493af0b9 bumped packages versions
#publish-packages-to-npm
2023-03-30 13:49:52 +01:00
Nicola CortiandLorenzo Sciandra 7b2cff831e Re-enable Fabric in the default app template/RN-Tester (#36717)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36717

After D43711737 landed, it turns out that Fabric is always disabled for both
RN-Tester and new app from template (so for 0.72 also RC0).
The reason is that a new method `createRootView(Bundle)` was introduced inside
`ReactActivityDelegate`. Both RN Tester and the template were using the
old `createRootView()` method which is not called anymore at this stage
(should potentially be deprecated?).

This diff fixes it by overriding both method inside `DefaultReactActivityDelegate`
so that both methods are setting the Fabric renderer.

Changelog:
[Android] [Fixed] - Re-enable Fabric in the default app template/RN-Tester

Reviewed By: cipolleschi

Differential Revision: D44536222

fbshipit-source-id: d22a0c522f011a8fe4d27b5d8f2fcf5dd13c3058
2023-03-30 13:49:30 +01:00
Riccardo CipolleschiandRiccardo Cipolleschi 6070b58a96 Add Examples for Direct Manipulation in the Interop Layer (#36610)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36610

This change add to RNTester examples of a legacy Native Component, loaded in the New Architecture through the Interop Layer, that uses the APIs described in the [Direct Manipulation](https://reactnative.dev/docs/direct-manipulation) sectioon of the website.

[iOS][Added] - Added examples of direct manipulation

Reviewed By: sammy-SC

Differential Revision: D43978674

fbshipit-source-id: 1cbc56f28034f84f309166e3e392ad97a8164e64
2023-03-30 11:11:06 +01:00
Riccardo CipolleschiandRiccardo Cipolleschi 3e079f0802 Make UIManager.dispatchViewManagerCommand work in Fabric through Interop Layer (#36578)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36578

This change brings to the Fabric Interop Layer the possibility to directly call native methods on the View Manager, something that was not possible before and that we can use to simplify the migration to the New Architecture.

[iOS][Added] - Native Components can now call native methods in Fabric when they are loaded through the Interop Layer

Reviewed By: sammy-SC

Differential Revision: D43945278

fbshipit-source-id: fe67ac85a5d0db3747105f56700d1dbba7ada5f1
2023-03-30 11:10:18 +01:00
fortmarekandLorenzo Sciandra 18137348ee Use packaged react-native in test-e2e-local script (#36703)
Summary:
The current `test-e2e-local` script had two bugs:
- On [this](https://github.com/facebook/react-native/blob/c1c22ebacc4097ce56f19385161ebb23ee1624b3/scripts/test-e2e-local.js#L219) line we were initializing a new RN project with the packed `react-native` created [here](https://github.com/facebook/react-native/blob/c1c22ebacc4097ce56f19385161ebb23ee1624b3/scripts/test-e2e-local.js#L211)
- We were updating the local RN version after running `npm pack` [here](https://github.com/facebook/react-native/blob/c1c22ebacc4097ce56f19385161ebb23ee1624b3/scripts/test-e2e-local.js#L214). This meant that the version inside the packaged `react-native-xyz.tgz` was not updated since we ran `pack` before updating it. This was fine since the `init` command was using the local `react-native` repository instead of the packed version.

## Changelog:

[INTERNAL] [FIXED] - Use packaged react-native in test-e2e-local script
<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[INTERNAL] [FIXED] - Use packaged react-native in test-e2e-local script

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

Pull Request resolved: https://github.com/facebook/react-native/pull/36703

Test Plan:
- Run `yarn test-e2e-local -t RNTestProject -p Android`. The command should succeed.

I am not completely sure how to double check that we are using the packed version. Locally, I have a `fsmonitor--daemon.ipc` in my `react-native/.git` that can't be copied. The `.git` folder would be copied only when `cli.js init` was called with the whole repository  – which is how I found out about the issue in the first place.

Reviewed By: hoxyq

Differential Revision: D44504599

Pulled By: cipolleschi

fbshipit-source-id: e57e2858bab46d4f978eed3cbaf3e504138594b8
2023-03-30 10:52:54 +01:00
Nicola CortiandLorenzo Sciandra 14794a9946 Fix the setup to allow the build-from-source on host projects (#36702)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36702

With the monorepo changes we broke the build from source for users.
This fixes it so that folks can just follow the guide:
https://reactnative.dev/contributing/how-to-build-from-source

Changelog:
[Android] [Fixed] - Fix the setup to allow the build-from-source on host projects

Reviewed By: cipolleschi

Differential Revision: D44502428

fbshipit-source-id: 3ad8fb114f5e2f7ffdf6fffa617ceaa45334f5f3
2023-03-29 17:39:30 +01:00
Nick GerlemanandLorenzo Sciandra eae08663fe Mimimize EditText Spans 9/9: Remove addSpansForMeasurement() (#36575)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36575

This is part of a series of changes to minimize the number of spans committed to EditText, as a mitigation for platform issues on Samsung devices. See this [GitHub thread]( https://github.com/facebook/react-native/issues/35936#issuecomment-1411437789) for greater context on the platform behavior.

D23670779 addedd a previous mechanism to add spans for measurement caching, like we needed to do as part of this change. It is called in more specific cases (e.g. when there is a text hint but no text), but it edits the live EditText spannable instead of the cache copy, and does not handle nested text at all.

We are already adding spans back to the input after this, behind everything else, and can replace it with the code we have been adding.

Changelog:
[Android][Fixed] - Mimimize EditText Spans 9/9: Remove `addSpansForMeasurement()`

Reviewed By: javache

Differential Revision: D44298159

fbshipit-source-id: 1af44a39de7550b7e66e45db9ebc3523ae9ff002
2023-03-29 15:48:03 +01:00
Nick GerlemanandLorenzo Sciandra 1ebe10a4e5 Minimize EditText Spans 8/9: CustomStyleSpan (#36577)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36577

This is part of a series of changes to minimize the number of spans committed to EditText, as a mitigation for platform issues on Samsung devices. See this [GitHub thread]( https://github.com/facebook/react-native/issues/35936#issuecomment-1411437789) for greater context on the platform behavior.

This change allows us to strip CustomStyleSpan. We already set all but `fontVariant` on the underlying EditText, so we just need to route that through as well.

Note that because this span is non-parcelable, it is seemingly not subject to the buggy behavior on Samsung devices of infinitely cloning the spans, but non-parcelable spans have different issues on the devices (they disappear), so moving `fontVariant` to the top-level makes sense here.

Changelog:
[Android][Fixed] - Minimize EditText Spans 8/N: CustomStyleSpan

Reviewed By: javache

Differential Revision: D44297384

fbshipit-source-id: ed4c000e961dd456a2a8f4397e27c23a87defb6e
2023-03-29 15:47:56 +01:00
Nick GerlemanandLorenzo Sciandra 1fc7693205 Minimize EditText Spans 7/9: Avoid temp list (#36576)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36576

This is part of a series of changes to minimize the number of spans committed to EditText, as a mitigation for platform issues on Samsung devices. See this [GitHub thread]( https://github.com/facebook/react-native/issues/35936#issuecomment-1411437789) for greater context on the platform behavior.

This change addresses some minor CR feedback and removes the temporary list of spans in favor of applying them directly.

Changelog:
[Internal]

Reviewed By: javache

Differential Revision: D44295190

fbshipit-source-id: bd784e2c514301d45d0bacd8ee6de5c512fc565c
2023-03-29 15:47:50 +01:00
Nick GerlemanandLorenzo Sciandra 4e24223550 Minimize EditText Spans 6/9: letterSpacing (#36548)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36548

This is part of a series of changes to minimize the number of spans committed to EditText, as a mitigation for platform issues on Samsung devices. See this [GitHub thread]( https://github.com/facebook/react-native/issues/35936#issuecomment-1411437789) for greater context on the platform behavior.

This change lets us set `letterSpacing` on the EditText instead of using our custom span.

Changelog:
[Android][Fixed] - Minimize EditText Spans 6/N: letterSpacing

Reviewed By: rshest

Differential Revision: D44240777

fbshipit-source-id: 9bd10c3261257037d8cacf37971011aaa94d1a77
2023-03-29 15:47:44 +01:00
Nick GerlemanandLorenzo Sciandra 536ee8ba4c Minimize EditText Spans 5/9: Strikethrough and Underline (#36544)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36544

This is part of a series of changes to minimize the number of spans committed to EditText, as a mitigation for platform issues on Samsung devices. See this [GitHub thread]( https://github.com/facebook/react-native/issues/35936#issuecomment-1411437789) for greater context on the platform behavior.

This change makes us apply strikethrough and underline as paint flags to the underlying EditText, instead of just the spans. We then opt ReactUnderlineSpan and ReactStrikethroughSpan into being strippable.

This does actually create visual behavior changes, where child text will inherit any underline or strikethrough of the root EditText (including if the child specifies `textDecorationLine: "none"`. The new behavior is consistent with both iOS and web though, so it seems like more of a bugfix than a regression.

Changelog:
[Android][Fixed] - Minimize Spans 5/N: Strikethrough and Underline

Reviewed By: rshest

Differential Revision: D44240778

fbshipit-source-id: d564dfc0121057a5e3b09bb71b8f5662e28be17e
2023-03-29 15:47:37 +01:00
Nick GerlemanandLorenzo Sciandra 3447fea075 Minimize EditText Spans 4/9: ReactForegroundColorSpan (#36545)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36545

This is part of a series of changes to minimize the number of spans committed to EditText, as a mitigation for platform issues on Samsung devices. See this [GitHub thread]( https://github.com/facebook/react-native/issues/35936#issuecomment-1411437789) for greater context on the platform behavior.

This adds ReactForegroundColorSpan to the list of spans eligible to be stripped.

Changelog:
[Android][Fixed] - Minimize Spans 4/N: ReactForegroundColorSpan

Reviewed By: javache

Differential Revision: D44240780

fbshipit-source-id: d86939cc2d7ed9116a4167026c7d48928fc51757
2023-03-29 15:47:15 +01:00
Nick GerlemanandLorenzo Sciandra ea09a4701d Minimize EditText Spans 3/9: ReactBackgroundColorSpan (#36547)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36547

This is part of a series of changes to minimize the number of spans committed to EditText, as a mitigation for platform issues on Samsung devices. See this [GitHub thread]( https://github.com/facebook/react-native/issues/35936#issuecomment-1411437789) for greater context on the platform behavior.

This adds `ReactBackgroundColorSpan` to the list of spans eligible to be stripped.

Changelog:
[Android][Fixed] - Minimize Spans 3/N: ReactBackgroundColorSpan

Reviewed By: javache

Differential Revision: D44240782

fbshipit-source-id: 2ded1a1687a41cf6d5f83e89ffadd2d932089969
2023-03-29 15:47:02 +01:00
Nick GerlemanandLorenzo Sciandra cffdad69c3 Minimize EditText Spans 2/9: Make stripAttributeEquivalentSpans generic (#36546)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36546

This is part of a series of changes to minimize the number of spans committed to EditText, as a mitigation for platform issues on Samsung devices. See this [GitHub thread]( https://github.com/facebook/react-native/issues/35936#issuecomment-1411437789) for greater context on the platform behavior.

This change generalizes `stripAttributeEquivalentSpans()` to allow plugging in different spans.

Changelog:
[Internal]

Reviewed By: rshest

Differential Revision: D44240781

fbshipit-source-id: 89005266020f216368e9ad9ce382699bd8db85a8
2023-03-29 15:46:54 +01:00
Nick GerlemanandLorenzo Sciandra a0a81a400b Minimize EditText Spans 1/9: Fix precedence (#36543)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36543

This is part of a series of changes to minimize the number of spans committed to EditText, as a mitigation for platform issues on Samsung devices. See this [GitHub thread]( https://github.com/facebook/react-native/issues/35936#issuecomment-1411437789) for greater context on the platform behavior.

We cache the backing EditText span on text change to later measure. To measure outside of a TextInput we need to restore any spans we removed. Spans may overlap, so base attributes should be behind everything else.

The logic here for dealing with precedence is incorrect, and we should instead accomplish this by twiddling with the `SPAN_PRIORITY` bits.

Changelog:
[Android][Fixed] - Minimize Spans 1/N: Fix precedence

Reviewed By: javache

Differential Revision: D44240779

fbshipit-source-id: f731b353587888faad946b8cf1e868095cdeced3
2023-03-29 15:46:46 +01:00
Nick GerlemanandLorenzo Sciandra b6291aacf8 Bail on realizing region around last focused cell if we don't know where it is (#36541)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36541

We only know where the last focused cell lives after it is rendered. Apart from dead refs handled in D43835135, this means items added or removed before the focused cell will lead to a stale last index for the next state update.

We don't have a good way to correlate cells after data change. This effects the implementation for [`maintainVisibleContentPosition`](https://github.com/facebook/react-native/pull/35993) as well, but needs some thought on the right way to handle it. For now, we bail when we don't know where the last focused cell lives.

Changelog:
[General][Fixed] - Bail on realizing region around last focused cell if we don't know where it is

Reviewed By: yungsters

Differential Revision: D44221162

fbshipit-source-id: 8fc7e726fe13c62b98870600563857bb89290280
2023-03-29 15:46:33 +01:00
Ruslan LesiutinandLorenzo Sciandra 7700d7fd78 fix: update paths in React-rncore.podspec (#36571)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36571

Changelog: [Internal]

The problem is related to the way we use `js_srcs_dir` & `output_dir` options, one requires just relative path from current ruby script, other requires relative path from iOS root project (where the Podfile located)

output_dir was introduced in D43304641
resulted into the issue, described in https://discord.com/channels/514829729862516747/1087736932953509958

allow-large-files

Reviewed By: cipolleschi

Differential Revision: D44294112

fbshipit-source-id: 47fcf510e203d0880e1f92ab6ead09f4b79cb4dd
2023-03-29 15:45:54 +01:00
Shivam ShashankandLorenzo Sciandra 2443677fe0 Support to enable/disable Fabric in ReactFragment (#36263)
Summary:
New Architecture Support missing in React Native Fragment, added same.

Changelog:
[Android] [Added] - Support to enable/disable Fabric in ReactFragment

Pull Request resolved: https://github.com/facebook/react-native/pull/36263

Test Plan:
<details>
  <summary>Kotlin Code Snippet to test:</summary>
  <p>

```kotlin
supportFragmentManager
  .beginTransaction()
  .add(android.R.id.content,
     ReactFragment.Builder()
       .setComponentName("componentName")
       .setFabricEnabled(true)
       .build())
  .commit()
```

  </p>
</details>

Reviewed By: mdvacca

Differential Revision: D43701078

Pulled By: cortinico

fbshipit-source-id: 659ed2b4cf6619c6d64b803a198a93ff84b574fe
2023-03-29 15:45:44 +01:00
Samuel SuslaandLorenzo Sciandra 7c9f3ab437 Patch setNativeProps in OSS build
Summary:
changelog: [internal]

`setNativeProps` have been implemented in Fabric but require a React change to be accessible from JavaScript components. For React sync to be imported in OSS builds, React needs to have have a new release in NPM.
To work around this limitation, I manually copied over lines of code that glue together setNativeProps to OSS build.

Reviewed By: cortinico, cipolleschi

Differential Revision: D44216496

fbshipit-source-id: b34b598c1a317bdc03cc5a4cadb3f7c610059709
2023-03-29 15:45:36 +01:00
David VaccaandLorenzo Sciandra f5fbda5e46 Improve caching of Text per shadow Node
Summary:
This diff optimizes text measurement by adding a layer of caching per shadow node.
When ReactFeatureFlags.enableTextMeasureCachePerShadowNode is enabled, we will cache and reused measurements per shadow node.
This optimization showed a 2x improvement on text rendearing when a screen contains a big amount of text components.

Changelog: [Internal] Internal

Reviewed By: sammy-SC

Differential Revision: D44221170

fbshipit-source-id: c3e7ba1ad216929826a99585874981717c90e13b
2023-03-29 15:45:27 +01:00
Samuel SuslaandLorenzo Sciandra 05ba16aa3d Enable NSTextStorage caching in OSS
Summary:
changelog: [internal]

Turn on NSTextStorage in OSS.

Reviewed By: cipolleschi

Differential Revision: D44216186

fbshipit-source-id: 7f08291dc0bc1237e72dd96235f76ed90361826b
2023-03-29 15:45:17 +01:00
9ffe82edd3 Port changes from main into Stable to make the CI green (#36665)
Co-authored-by: Riccardo Cipolleschi <cipolleschi@fb.com>
Co-authored-by: Alex Hunt <alexeh@meta.com>
resolved: https://github.com/facebook/react-native/pull/36502
2023-03-28 22:32:42 +01:00
6e04b2a717 Restore object with prerelease as string to unblock 0.72 (#36657)
Co-authored-by: Riccardo Cipolleschi <cipolleschi@fb.com>
2023-03-27 18:22:25 +01:00
Rob HoganandGitHub fecfd04d89 [0.72-stable] Fix localhost references in yarn.lock (#36661) 2023-03-27 17:40:32 +01:00
a4e390a188 Revert Changes to Libraries/Utilities to fix prerelease type (#36655)
Co-authored-by: Riccardo Cipolleschi <cipolleschi@fb.com>
2023-03-27 16:48:42 +01:00
17a96158aa Downgrade CLI to alpha.0 to get Metro working again in CI (#36654)
Co-authored-by: Riccardo Cipolleschi <cipolleschi@fb.com>
2023-03-27 16:48:20 +01:00
Ruslan LesiutinandGitHub 73f37b14d6 fix: format template location following prettier rules (#36651) 2023-03-27 15:11:26 +01:00
aff2e93576 Fix platform Typings (#36650)
Co-authored-by: Riccardo Cipolleschi <cipolleschi@fb.com>
2023-03-27 15:10:49 +01:00
Lorenzo Sciandra 8a5ddb92f1 [LOCAL] bump hermes in RNTester podfile 2023-03-21 15:01:22 +00:00
Lorenzo Sciandra f9b3835f1e fix script 2023-03-21 13:54:54 +00:00
Distiller 2c6edee68e [0.72.0-rc.0] Bump version numbers 2023-03-20 15:38:47 +00:00
Luna Wei f40f8f9ad2 fixed cwd for publish-npm script 2023-03-20 15:24:58 +00:00
Luna Wei c05d19102c Use new package versions 2023-03-20 15:21:00 +00:00
Luna Wei dad96696b7 Fix align-package-version path 2023-03-20 15:20:20 +00:00
Luna Wei 6d2805bf85 bumped packages versions
#publish-packages-to-npm
2023-03-20 15:12:12 +00:00
Luna Wei c2b182f9f5 Set Hermes version 2023-03-20 15:05:51 +00:00
217 changed files with 5857 additions and 3038 deletions
-5
View File
@@ -37,11 +37,6 @@ ADD scripts /app/scripts
WORKDIR /app
RUN scripts/buck/buck_fetch.sh
RUN buck build packages/react-native/ReactAndroid/src/main/java/com/facebook/react
RUN buck build packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell
ADD . /app
RUN yarn
+36 -66
View File
@@ -46,7 +46,7 @@ references:
# Dependency Anchors
# -------------------------
dependency_versions:
xcode_version: &xcode_version "14.2.0"
xcode_version: &xcode_version "14.3.0"
nodelts_image: &nodelts_image "cimg/node:18.12.1"
nodeprevlts_image: &nodeprevlts_image "cimg/node:16.18.1"
@@ -62,7 +62,8 @@ references:
hermes_workspace_cache_key: &hermes_workspace_cache_key v4-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "/tmp/hermes/hermesversion" }}
hermes_workspace_debug_cache_key: &hermes_workspace_debug_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-debug-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_workspace_release_cache_key: &hermes_workspace_release_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-release-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_windows_cache_key: &hermes_windows_cache_key v3-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "tmp/hermes/hermesversion" }}
hermes_linux_cache_key: &hermes_linux_cache_key v1-hermes-{{ .Environment.CIRCLE_JOB }}-linux-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_windows_cache_key: &hermes_windows_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-windows-{{ checksum "/Users/circleci/project/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_tarball_debug_cache_key: &hermes_tarball_debug_cache_key v4-hermes-tarball-debug-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_tarball_release_cache_key: &hermes_tarball_release_cache_key v3-hermes-tarball-release-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
pods_cache_key: &pods_cache_key v8-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }}
@@ -314,11 +315,24 @@ commands:
- run:
name: Get React Native version
command: |
VERSION=$( grep '"version"' packages/react-native/package.json | cut -d '"' -f 4 | head -1)
VERSION=$(cat packages/react-native/package.json | jq -r '.version')
# Save the react native version we are building in a file so we can use that file as part of the cache key.
echo "$VERSION" > /tmp/react-native-version
echo "React Native Version is $(cat /tmp/react-native-version)"
echo "Hermes commit is $(cat /tmp/hermes/hermesversion)"
HERMES_VERSION="$(cat /tmp/hermes/hermesversion)"
echo "Hermes commit is $HERMES_VERSION"
get_react_native_version_windows:
steps:
- run:
name: Get React Native version on Windows
command: |
$VERSION=cat packages/react-native/package.json | jq -r '.version'
# Save the react native version we are building in a file so we can use that file as part of the cache key.
echo "$VERSION" > /tmp/react-native-version
echo "React Native Version is $(cat /tmp/react-native-version)"
$HERMES_VERSION=cat C:\Users\circleci\project\tmp\hermes\hermesversion
echo "Hermes commit is $HERMES_VERSION"
with_hermes_tarball_cache_span:
parameters:
@@ -620,7 +634,7 @@ jobs:
- run:
name: Run Ruby Tests
command: |
cd scripts
cd packages/react-native/scripts
sh run_ruby_tests.sh
- run_yarn
- *attach_hermes_workspace
@@ -719,60 +733,6 @@ jobs:
- store_test_results:
path: ./reports/junit
# -------------------------
# JOBS: Test Buck
# -------------------------
test_buck:
executor: reactnativeandroid
environment:
KOTLIN_HOME=packages/react-native/third-party/kotlin
steps:
- checkout
- setup_artifacts
- run_yarn
- run:
name: Download Dependencies Using Buck
command: ./scripts/buck/buck_fetch.sh
- run:
name: Build & Test React Native using Buck
command: |
buck build packages/react-native/ReactAndroid/src/main/java/com/facebook/react
buck build packages/react-native/ReactAndroid/src/main/java/com/facebook/react/shell
- run:
name: Run Tests - Android Unit Tests with Buck
command: buck test packages/react-native/ReactAndroid/src/test/... --config build.threads=$BUILD_THREADS --xml ./reports/buck/all-results-raw.xml
- run:
name: Build JavaScript Bundle for instrumentation tests
working_directory: ~/react-native/packages/react-native
command: node cli.js bundle --max-workers 2 --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
- run:
name: Build Tests - Android Instrumentation Tests with Buck
# Here, just build the instrumentation tests. There is a known issue with installing the APK to android-21+ emulator.
command: |
if [[ ! -e packages/react-native/ReactAndroid/src/androidTest/assets/AndroidTestBundle.js ]]; then
echo "JavaScript bundle missing, cannot run instrumentation tests. Verify Build JavaScript Bundle step completed successfully."; exit 1;
fi
source scripts/android-setup.sh && NO_BUCKD=1 scripts/retry3 timeout 300 buck build packages/react-native/ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=$BUILD_THREADS
- run:
name: Collect Test Results
command: |
find . -type f -regex ".*/build/test-results/debug/.*xml" -exec cp {} ./reports/build/ \;
find . -type f -regex ".*/outputs/androidTest-results/connected/.*xml" -exec cp {} ./reports/outputs/ \;
find . -type f -regex ".*/buck-out/gen/packages/react-native/ReactAndroid/src/test/.*/.*xml" -exec cp {} ./reports/buck/ \;
if [ -f ~/react-native/reports/buck/all-results-raw.xml ]; then
~/react-native/scripts/circleci/buckToJunit/buckToJunit.sh ~/react-native/reports/buck/all-results-raw.xml ~/react-native/reports/junit/results.xml
fi
when: always
- store_test_results:
path: ./reports/junit
# -------------------------
# JOBS: Test Android
# -------------------------
@@ -1086,9 +1046,15 @@ jobs:
name: Enable Yarn with corepack
command: corepack enable
# it looks like that, last week, envinfo released version 7.9.0 which does not works
# with Windows. I have opened an issue here: https://github.com/tabrindle/envinfo/issues/238
# TODO: T156811874 - Revert this to npx envinfo@latest when the issue is addressed
- run:
name: Display Environment info
command: npx envinfo@latest
command: |
npm install -g envinfo
envinfo -v
envinfo
- restore_cache:
keys:
@@ -1175,7 +1141,7 @@ jobs:
- image: debian:11
environment:
- HERMES_WS_DIR: *hermes_workspace_root
- HERMES_VERSION_FILE: "sdks/.hermesversion"
- HERMES_VERSION_FILE: "packages/react-native/sdks/.hermesversion"
- BUILD_FROM_SOURCE: true
steps:
- run:
@@ -1194,8 +1160,10 @@ jobs:
mkdir -p "/tmp/hermes" "/tmp/hermes/download" "/tmp/hermes/hermes"
if [ -f "$HERMES_VERSION_FILE" ]; then
echo "Hermes version file found. Using the latest commit"
cat $HERMES_VERSION_FILE > /tmp/hermes/hermesversion
else
echo "No hermes version file found. Using the latest commit"
HERMES_TAG_SHA=$(git ls-remote https://github.com/facebook/hermes main | cut -f 1 | tr -d '[:space:]')
echo $HERMES_TAG_SHA > /tmp/hermes/hermesversion
fi
@@ -1226,17 +1194,18 @@ jobs:
docker:
- image: debian:bullseye
resource_class: "xlarge"
working_directory: /root
steps:
- checkout_code_with_cache
- run:
name: Install dependencies
command: |
apt update
apt install -y git openssh-client cmake build-essential \
libreadline-dev libicu-dev zip python3
libreadline-dev libicu-dev jq zip python3
- *attach_hermes_workspace
- get_react_native_version
- restore_cache:
key: *hermes_workspace_cache_key
key: *hermes_linux_cache_key
- run:
name: Set up workspace
command: |
@@ -1255,7 +1224,7 @@ jobs:
cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/.
fi
- save_cache:
key: *hermes_workspace_cache_key
key: *hermes_linux_cache_key
paths:
- /tmp/hermes/linux64-bin/
- /tmp/hermes/hermes/destroot/
@@ -1376,7 +1345,9 @@ jobs:
- MSBUILD_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin'
- CMAKE_DIR: 'C:\Program Files\CMake\bin'
steps:
- checkout_code_with_cache
- *attach_hermes_workspace
- get_react_native_version_windows
- restore_cache:
key: *hermes_windows_cache_key
- run:
@@ -1694,7 +1665,6 @@ workflows:
architecture: ["NewArch", "OldArch"]
jsengine: ["Hermes", "JSC"]
flavor: ["Debug", "Release"]
- test_buck
- test_ios_template:
requires:
- build_npm_package
+9 -9
View File
@@ -3,22 +3,22 @@ GEM
specs:
CFPropertyList (3.0.6)
rexml
activesupport (7.0.4.2)
activesupport (7.0.6)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
addressable (2.8.1)
addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
atomos (0.1.3)
claide (1.1.0)
cocoapods (1.12.0)
cocoapods (1.12.1)
addressable (~> 2.8)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.12.0)
cocoapods-core (= 1.12.1)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.6.0, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
@@ -33,7 +33,7 @@ GEM
nap (~> 1.0)
ruby-macho (>= 2.3.0, < 3.0)
xcodeproj (>= 1.21.0, < 2.0)
cocoapods-core (1.12.0)
cocoapods-core (1.12.1)
activesupport (>= 5.0, < 8)
addressable (~> 2.8)
algoliasearch (~> 1.0)
@@ -62,10 +62,10 @@ GEM
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
httpclient (2.8.3)
i18n (1.12.0)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
json (2.6.3)
minitest (5.18.0)
minitest (5.18.1)
molinillo (0.8.0)
nanaimo (0.3.0)
nap (1.1.0)
@@ -93,7 +93,7 @@ DEPENDENCIES
cocoapods (~> 1.12)
RUBY VERSION
ruby 3.2.0p0
ruby 3.0.6p216
BUNDLED WITH
2.4.7
2.4.13
+8 -8
View File
@@ -40,8 +40,7 @@
"test-ios": "./scripts/objc-test.sh test",
"test-typescript": "dtslint packages/react-native/types",
"test-typescript-offline": "dtslint --localTs node_modules/typescript/lib packages/react-native/types",
"bump-all-updated-packages": "node ./scripts/monorepo/bump-all-updated-packages",
"align-package-versions": "node ./scripts/monorepo/align-package-versions.js"
"bump-all-updated-packages": "node ./scripts/monorepo/bump-all-updated-packages"
},
"workspaces": [
"packages/*"
@@ -51,16 +50,17 @@
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/eslint-parser": "^7.19.0",
"@babel/eslint-parser": "^7.20.0",
"@babel/generator": "^7.20.0",
"@babel/plugin-transform-regenerator": "^7.0.0",
"@babel/plugin-transform-regenerator": "^7.20.0",
"@definitelytyped/dtslint": "^0.0.127",
"@jest/create-cache-key-function": "^29.2.1",
"@reactions/component": "^2.0.2",
"@react-native/metro-config": "^0.72.9",
"@types/react": "^18.0.18",
"@typescript-eslint/parser": "^5.30.5",
"async": "^3.2.2",
"babel-plugin-transform-flow-enums":"^0.0.2",
"babel-plugin-transform-flow-enums": "^0.0.2",
"clang-format": "^1.8.0",
"connect": "^3.6.5",
"coveralls": "^3.1.1",
@@ -84,9 +84,9 @@
"jest": "^29.2.1",
"jest-junit": "^10.0.0",
"jscodeshift": "^0.14.0",
"metro-babel-register": "0.75.1",
"metro-memory-fs": "0.75.1",
"metro-react-native-babel-transformer": "0.75.1",
"metro-babel-register": "0.76.7",
"metro-memory-fs": "0.76.7",
"metro-react-native-babel-transformer": "0.76.7",
"mkdirp": "^0.5.1",
"mock-fs": "^5.1.4",
"prettier": "^2.4.1",
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-config",
"version": "0.72.1",
"version": "0.72.2",
"description": "ESLint config for React Native",
"main": "index.js",
"license": "MIT",
@@ -12,7 +12,7 @@
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/eslint-config-react-native-community#readme",
"dependencies": {
"@babel/core": "^7.20.0",
"@babel/eslint-parser": "^7.19.0",
"@babel/eslint-parser": "^7.20.0",
"@react-native/eslint-plugin": "^0.72.0",
"@typescript-eslint/eslint-plugin": "^5.30.5",
"@typescript-eslint/parser": "^5.30.5",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-plugin-specs",
"version": "0.72.2",
"version": "0.72.4",
"description": "ESLint rules to validate NativeModule and Component Specs",
"main": "index.js",
"repository": {
@@ -14,11 +14,11 @@
},
"dependencies": {
"@babel/core": "^7.20.0",
"@babel/eslint-parser": "^7.19.0",
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
"@babel/preset-flow": "^7.18.0",
"@babel/eslint-parser": "^7.20.0",
"@babel/plugin-transform-flow-strip-types": "^7.20.0",
"@babel/preset-flow": "^7.20.0",
"@react-native/codegen": "*",
"flow-parser": "^0.185.0",
"flow-parser": "^0.206.0",
"make-dir": "^2.1.0",
"pirates": "^4.0.1",
"source-map-support": "0.5.0"
@@ -17,10 +17,10 @@
"yargs": "^17.6.2"
},
"devDependencies": {
"@babel/cli": "^7.19.0",
"@babel/cli": "^7.20.0",
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/preset-flow": "^7.18.0",
"@babel/preset-flow": "^7.20.0",
"jest": "^29.2.1"
},
"jest": {
+94
View File
@@ -0,0 +1,94 @@
/**
* 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
* @noformat
*/
/*:: import type {ConfigT} from 'metro-config'; */
const {getDefaultConfig: getBaseConfig, mergeConfig} = require('metro-config');
const INTERNAL_CALLSITES_REGEX = new RegExp(
[
'/Libraries/Renderer/implementations/.+\\.js$',
'/Libraries/BatchedBridge/MessageQueue\\.js$',
'/Libraries/YellowBox/.+\\.js$',
'/Libraries/LogBox/.+\\.js$',
'/Libraries/Core/Timers/.+\\.js$',
'/Libraries/WebSocket/.+\\.js$',
'/Libraries/vendor/.+\\.js$',
'/node_modules/react-devtools-core/.+\\.js$',
'/node_modules/react-refresh/.+\\.js$',
'/node_modules/scheduler/.+\\.js$',
'/node_modules/event-target-shim/.+\\.js$',
'/node_modules/invariant/.+\\.js$',
'/node_modules/react-native/index.js$',
'/metro-runtime/.+\\.js$',
'^\\[native code\\]$',
].join('|'),
);
/**
* Get the base Metro configuration for a React Native project.
*/
function getDefaultConfig(
projectRoot /*: string */
) /*: ConfigT */ {
const config = {
resolver: {
resolverMainFields: ['react-native', 'browser', 'main'],
platforms: ['android', 'ios'],
unstable_conditionNames: ['require', 'import', 'react-native'],
},
serializer: {
// Note: This option is overridden in cli-plugin-metro (getOverrideConfig)
getModulesRunBeforeMainModule: () => [
require.resolve('react-native/Libraries/Core/InitializeCore'),
],
getPolyfills: () => require('@react-native/js-polyfills')(),
},
server: {
port: Number(process.env.RCT_METRO_PORT) || 8081,
},
symbolicator: {
customizeFrame: (frame /*: $ReadOnly<{file: ?string, ...}>*/) => {
const collapse = Boolean(
frame.file && INTERNAL_CALLSITES_REGEX.test(frame.file),
);
return {collapse};
},
},
transformer: {
allowOptionalDependencies: true,
assetRegistryPath: 'react-native/Libraries/Image/AssetRegistry',
asyncRequireModulePath: require.resolve(
'metro-runtime/src/modules/asyncRequire',
),
babelTransformerPath: require.resolve(
'metro-react-native-babel-transformer',
),
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
watchFolders: [],
};
// Set global hook so that the CLI can detect when this config has been loaded
global.__REACT_NATIVE_METRO_CONFIG_LOADED = true;
return mergeConfig(
getBaseConfig.getDefaultValues(projectRoot),
config,
);
}
module.exports = {getDefaultConfig, mergeConfig};
+18
View File
@@ -0,0 +1,18 @@
{
"name": "@react-native/metro-config",
"version": "0.72.9",
"description": "Metro configuration for React Native.",
"repository": {
"type": "git",
"url": "git@github.com:facebook/react-native.git",
"directory": "packages/metro-config"
},
"license": "MIT",
"exports": "./index.js",
"dependencies": {
"@react-native/js-polyfills": "^0.72.1",
"metro-config": "0.76.7",
"metro-react-native-babel-transformer": "0.76.7",
"metro-runtime": "0.76.7"
}
}
@@ -193,7 +193,7 @@ enum NativeEnumTurboModuleStatusRegularEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusRegularEnum> {
static NativeEnumTurboModuleStatusRegularEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusRegularEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"Active\\") {
return NativeEnumTurboModuleStatusRegularEnum::Active;
@@ -206,7 +206,7 @@ struct Bridging<NativeEnumTurboModuleStatusRegularEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusRegularEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusRegularEnum value) {
if (value == NativeEnumTurboModuleStatusRegularEnum::Active) {
return bridging::toJs(rt, \\"Active\\");
} else if (value == NativeEnumTurboModuleStatusRegularEnum::Paused) {
@@ -225,7 +225,7 @@ enum NativeEnumTurboModuleStatusStrEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusStrEnum> {
static NativeEnumTurboModuleStatusStrEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusStrEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"active\\") {
return NativeEnumTurboModuleStatusStrEnum::Active;
@@ -238,7 +238,7 @@ struct Bridging<NativeEnumTurboModuleStatusStrEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusStrEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusStrEnum value) {
if (value == NativeEnumTurboModuleStatusStrEnum::Active) {
return bridging::toJs(rt, \\"active\\");
} else if (value == NativeEnumTurboModuleStatusStrEnum::Paused) {
@@ -257,7 +257,7 @@ enum NativeEnumTurboModuleStatusNumEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusNumEnum> {
static NativeEnumTurboModuleStatusNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 2) {
return NativeEnumTurboModuleStatusNumEnum::Active;
@@ -270,7 +270,7 @@ struct Bridging<NativeEnumTurboModuleStatusNumEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusNumEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusNumEnum value) {
if (value == NativeEnumTurboModuleStatusNumEnum::Active) {
return bridging::toJs(rt, 2);
} else if (value == NativeEnumTurboModuleStatusNumEnum::Paused) {
@@ -289,7 +289,7 @@ enum NativeEnumTurboModuleStatusFractionEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusFractionEnum> {
static NativeEnumTurboModuleStatusFractionEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusFractionEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 0.2f) {
return NativeEnumTurboModuleStatusFractionEnum::Active;
@@ -302,7 +302,7 @@ struct Bridging<NativeEnumTurboModuleStatusFractionEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusFractionEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusFractionEnum value) {
if (value == NativeEnumTurboModuleStatusFractionEnum::Active) {
return bridging::toJs(rt, 0.2f);
} else if (value == NativeEnumTurboModuleStatusFractionEnum::Paused) {
@@ -2136,7 +2136,7 @@ enum NativeEnumTurboModuleStatusRegularEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusRegularEnum> {
static NativeEnumTurboModuleStatusRegularEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusRegularEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"Active\\") {
return NativeEnumTurboModuleStatusRegularEnum::Active;
@@ -2149,7 +2149,7 @@ struct Bridging<NativeEnumTurboModuleStatusRegularEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusRegularEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusRegularEnum value) {
if (value == NativeEnumTurboModuleStatusRegularEnum::Active) {
return bridging::toJs(rt, \\"Active\\");
} else if (value == NativeEnumTurboModuleStatusRegularEnum::Paused) {
@@ -2168,7 +2168,7 @@ enum NativeEnumTurboModuleStatusStrEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusStrEnum> {
static NativeEnumTurboModuleStatusStrEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusStrEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"active\\") {
return NativeEnumTurboModuleStatusStrEnum::Active;
@@ -2181,7 +2181,7 @@ struct Bridging<NativeEnumTurboModuleStatusStrEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusStrEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusStrEnum value) {
if (value == NativeEnumTurboModuleStatusStrEnum::Active) {
return bridging::toJs(rt, \\"active\\");
} else if (value == NativeEnumTurboModuleStatusStrEnum::Paused) {
@@ -2200,7 +2200,7 @@ enum NativeEnumTurboModuleStatusNumEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusNumEnum> {
static NativeEnumTurboModuleStatusNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 2) {
return NativeEnumTurboModuleStatusNumEnum::Active;
@@ -2213,7 +2213,7 @@ struct Bridging<NativeEnumTurboModuleStatusNumEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusNumEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusNumEnum value) {
if (value == NativeEnumTurboModuleStatusNumEnum::Active) {
return bridging::toJs(rt, 2);
} else if (value == NativeEnumTurboModuleStatusNumEnum::Paused) {
@@ -2232,7 +2232,7 @@ enum NativeEnumTurboModuleStatusFractionEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusFractionEnum> {
static NativeEnumTurboModuleStatusFractionEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusFractionEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 0.2f) {
return NativeEnumTurboModuleStatusFractionEnum::Active;
@@ -2245,7 +2245,7 @@ struct Bridging<NativeEnumTurboModuleStatusFractionEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusFractionEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusFractionEnum value) {
if (value == NativeEnumTurboModuleStatusFractionEnum::Active) {
return bridging::toJs(rt, 0.2f);
} else if (value == NativeEnumTurboModuleStatusFractionEnum::Paused) {
+11 -11
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/codegen",
"version": "0.72.3",
"version": "0.72.6",
"description": "⚛️ Code generation tools for React Native",
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-codegen",
"repository": {
@@ -19,21 +19,21 @@
],
"dependencies": {
"@babel/parser": "^7.20.0",
"flow-parser": "^0.185.0",
"flow-parser": "^0.206.0",
"jscodeshift": "^0.14.0",
"nullthrows": "^1.1.1"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-transform-async-to-generator": "^7.0.0",
"@babel/plugin-transform-destructuring": "^7.0.0",
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
"@babel/preset-env": "^7.14.0",
"@babel/plugin-proposal-class-properties": "^7.18.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.0",
"@babel/plugin-proposal-object-rest-spread": "^7.20.0",
"@babel/plugin-proposal-optional-chaining": "^7.20.0",
"@babel/plugin-syntax-dynamic-import": "^7.8.0",
"@babel/plugin-transform-async-to-generator": "^7.20.0",
"@babel/plugin-transform-destructuring": "^7.20.0",
"@babel/plugin-transform-flow-strip-types": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"chalk": "^4.0.0",
"glob": "^7.1.1",
"invariant": "^2.2.4",
@@ -338,12 +338,12 @@ enum ${enumName} { ${values} };
template <>
struct Bridging<${enumName}> {
static ${enumName} fromJs(jsi::Runtime &rt, ${fromValue}, const std::shared_ptr<CallInvoker> &jsInvoker) {
static ${enumName} fromJs(jsi::Runtime &rt, ${fromValue}) {
${fromValueConversion}
${fromCases}
}
static ${toValue} toJs(jsi::Runtime &rt, ${enumName} value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static ${toValue} toJs(jsi::Runtime &rt, ${enumName} value) {
${toCases}
}
};`;
@@ -211,7 +211,7 @@ enum SampleTurboModuleCxxNumEnum { ONE, TWO };
template <>
struct Bridging<SampleTurboModuleCxxNumEnum> {
static SampleTurboModuleCxxNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleCxxNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 1) {
return SampleTurboModuleCxxNumEnum::ONE;
@@ -222,7 +222,7 @@ struct Bridging<SampleTurboModuleCxxNumEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxNumEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxNumEnum value) {
if (value == SampleTurboModuleCxxNumEnum::ONE) {
return bridging::toJs(rt, 1);
} else if (value == SampleTurboModuleCxxNumEnum::TWO) {
@@ -239,7 +239,7 @@ enum SampleTurboModuleCxxFloatEnum { POINT_ZERO, POINT_ONE, POINT_TWO };
template <>
struct Bridging<SampleTurboModuleCxxFloatEnum> {
static SampleTurboModuleCxxFloatEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleCxxFloatEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 0.0f) {
return SampleTurboModuleCxxFloatEnum::POINT_ZERO;
@@ -252,7 +252,7 @@ struct Bridging<SampleTurboModuleCxxFloatEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxFloatEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxFloatEnum value) {
if (value == SampleTurboModuleCxxFloatEnum::POINT_ZERO) {
return bridging::toJs(rt, 0.0f);
} else if (value == SampleTurboModuleCxxFloatEnum::POINT_ONE) {
@@ -271,7 +271,7 @@ enum SampleTurboModuleCxxStringEnum { HELLO, GoodBye };
template <>
struct Bridging<SampleTurboModuleCxxStringEnum> {
static SampleTurboModuleCxxStringEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleCxxStringEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"hello\\") {
return SampleTurboModuleCxxStringEnum::HELLO;
@@ -282,7 +282,7 @@ struct Bridging<SampleTurboModuleCxxStringEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, SampleTurboModuleCxxStringEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, SampleTurboModuleCxxStringEnum value) {
if (value == SampleTurboModuleCxxStringEnum::HELLO) {
return bridging::toJs(rt, \\"hello\\");
} else if (value == SampleTurboModuleCxxStringEnum::GoodBye) {
@@ -1209,7 +1209,7 @@ enum SampleTurboModuleNumEnum { ONE, TWO };
template <>
struct Bridging<SampleTurboModuleNumEnum> {
static SampleTurboModuleNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 1) {
return SampleTurboModuleNumEnum::ONE;
@@ -1220,7 +1220,7 @@ struct Bridging<SampleTurboModuleNumEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleNumEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleNumEnum value) {
if (value == SampleTurboModuleNumEnum::ONE) {
return bridging::toJs(rt, 1);
} else if (value == SampleTurboModuleNumEnum::TWO) {
@@ -1237,7 +1237,7 @@ enum SampleTurboModuleFloatEnum { POINT_ZERO, POINT_ONE, POINT_TWO };
template <>
struct Bridging<SampleTurboModuleFloatEnum> {
static SampleTurboModuleFloatEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleFloatEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 0.0f) {
return SampleTurboModuleFloatEnum::POINT_ZERO;
@@ -1250,7 +1250,7 @@ struct Bridging<SampleTurboModuleFloatEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleFloatEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleFloatEnum value) {
if (value == SampleTurboModuleFloatEnum::POINT_ZERO) {
return bridging::toJs(rt, 0.0f);
} else if (value == SampleTurboModuleFloatEnum::POINT_ONE) {
@@ -1269,7 +1269,7 @@ enum SampleTurboModuleStringEnum { HELLO, GoodBye };
template <>
struct Bridging<SampleTurboModuleStringEnum> {
static SampleTurboModuleStringEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleStringEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"hello\\") {
return SampleTurboModuleStringEnum::HELLO;
@@ -1280,7 +1280,7 @@ struct Bridging<SampleTurboModuleStringEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, SampleTurboModuleStringEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, SampleTurboModuleStringEnum value) {
if (value == SampleTurboModuleStringEnum::HELLO) {
return bridging::toJs(rt, \\"hello\\");
} else if (value == SampleTurboModuleStringEnum::GoodBye) {
@@ -1,6 +1,6 @@
{
"name": "@react-native/gradle-plugin",
"version": "0.72.5",
"version": "0.72.11",
"description": "⚛️ Gradle Plugin for React Native",
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-gradle-plugin",
"repository": {
@@ -18,7 +18,8 @@ import com.facebook.react.utils.AgpConfiguratorUtils.configureDevPorts
import com.facebook.react.utils.BackwardCompatUtils.configureBackwardCompatibilityReactMap
import com.facebook.react.utils.DependencyUtils.configureDependencies
import com.facebook.react.utils.DependencyUtils.configureRepositories
import com.facebook.react.utils.DependencyUtils.readVersionString
import com.facebook.react.utils.DependencyUtils.readVersionAndGroupStrings
import com.facebook.react.utils.JdkConfiguratorUtils.configureJavaToolChains
import com.facebook.react.utils.JsonUtils
import com.facebook.react.utils.NdkConfiguratorUtils.configureReactNativeNdk
import com.facebook.react.utils.ProjectUtils.needsCodegenFromPackageJson
@@ -54,8 +55,10 @@ class ReactPlugin : Plugin<Project> {
project.afterEvaluate {
val reactNativeDir = extension.reactNativeDir.get().asFile
val propertiesFile = File(reactNativeDir, "ReactAndroid/gradle.properties")
val versionString = readVersionString(propertiesFile)
configureDependencies(project, versionString)
val versionAndGroupStrings = readVersionAndGroupStrings(propertiesFile)
val versionString = versionAndGroupStrings.first
val groupString = versionAndGroupStrings.second
configureDependencies(project, versionString, groupString)
configureRepositories(project, reactNativeDir)
}
@@ -76,6 +79,9 @@ class ReactPlugin : Plugin<Project> {
project.pluginManager.withPlugin("com.android.library") {
configureCodegen(project, extension, rootExtension, isLibrary = true)
}
// App and Library Configurations
configureJavaToolChains(project)
}
private fun checkJvmVersion(project: Project) {
@@ -174,6 +174,7 @@ abstract class BundleHermesCTask : DefaultTask() {
return windowsAwareCommandLine(
hermesCommand,
"-emit-binary",
"-max-diagnostic-width=80",
"-out",
bytecodeFile.cliPath(rootFile),
bundleFile.cliPath(rootFile),
@@ -13,6 +13,8 @@ import java.util.*
import org.gradle.api.Project
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
internal const val DEFAULT_GROUP_STRING = "com.facebook.react"
internal object DependencyUtils {
/**
@@ -46,7 +48,11 @@ internal object DependencyUtils {
* - Forcing the react-android/hermes-android version to the one specified in the package.json
* - Substituting `react-native` with `react-android` and `hermes-engine` with `hermes-android`.
*/
fun configureDependencies(project: Project, versionString: String) {
fun configureDependencies(
project: Project,
versionString: String,
groupString: String = DEFAULT_GROUP_STRING
) {
if (versionString.isBlank()) return
project.rootProject.allprojects { eachProject ->
eachProject.configurations.all { configuration ->
@@ -56,32 +62,46 @@ internal object DependencyUtils {
// implementation("com.facebook.react:react-native:+") and resolve the right dependency.
configuration.resolutionStrategy.dependencySubstitution {
it.substitute(it.module("com.facebook.react:react-native"))
.using(it.module("com.facebook.react:react-android:${versionString}"))
.using(it.module("${groupString}:react-android:${versionString}"))
.because(
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.")
it.substitute(it.module("com.facebook.react:hermes-engine"))
.using(it.module("com.facebook.react:hermes-android:${versionString}"))
.using(it.module("${groupString}:hermes-android:${versionString}"))
.because(
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.")
if (groupString != DEFAULT_GROUP_STRING) {
it.substitute(it.module("com.facebook.react:react-android"))
.using(it.module("${groupString}:react-android:${versionString}"))
.because(
"The react-android dependency was modified to use the correct Maven group.")
it.substitute(it.module("com.facebook.react:hermes-android"))
.using(it.module("${groupString}:hermes-android:${versionString}"))
.because(
"The hermes-android dependency was modified to use the correct Maven group.")
}
}
configuration.resolutionStrategy.force(
"com.facebook.react:react-android:${versionString}",
"com.facebook.react:hermes-android:${versionString}",
"${groupString}:react-android:${versionString}",
"${groupString}:hermes-android:${versionString}",
)
}
}
}
fun readVersionString(propertiesFile: File): String {
fun readVersionAndGroupStrings(propertiesFile: File): Pair<String, String> {
val reactAndroidProperties = Properties()
propertiesFile.inputStream().use { reactAndroidProperties.load(it) }
val versionString = reactAndroidProperties["VERSION_NAME"] as? String ?: ""
val versionStringFromFile = reactAndroidProperties["VERSION_NAME"] as? String ?: ""
// If on a nightly, we need to fetch the -SNAPSHOT artifact from Sonatype.
return if (versionString.startsWith("0.0.0")) {
"$versionString-SNAPSHOT"
} else {
versionString
}
val versionString =
if (versionStringFromFile.startsWith("0.0.0")) {
"$versionStringFromFile-SNAPSHOT"
} else {
versionStringFromFile
}
// Returns Maven group for repos using different group for Maven artifacts
val groupString = reactAndroidProperties["GROUP"] as? String ?: DEFAULT_GROUP_STRING
return Pair(versionString, groupString)
}
fun Project.mavenRepoFromUrl(url: String): MavenArtifactRepository =
@@ -0,0 +1,46 @@
/*
* 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.utils
import com.android.build.api.variant.AndroidComponentsExtension
import com.facebook.react.utils.PropertyUtils.INTERNAL_DISABLE_JAVA_VERSION_ALIGNMENT
import org.gradle.api.Action
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.plugins.AppliedPlugin
internal object JdkConfiguratorUtils {
/**
* Function that takes care of configuring the JDK toolchain for all the projects projects. As we
* do decide the JDK version based on the AGP version that RNGP brings over, here we can safely
* configure the toolchain to 11.
*/
fun configureJavaToolChains(input: Project) {
if (input.hasProperty(INTERNAL_DISABLE_JAVA_VERSION_ALIGNMENT)) {
return
}
input.rootProject.allprojects { project ->
val action =
Action<AppliedPlugin> {
project.extensions.getByType(AndroidComponentsExtension::class.java).finalizeDsl {
ext ->
ext.compileOptions.sourceCompatibility = JavaVersion.VERSION_11
ext.compileOptions.targetCompatibility = JavaVersion.VERSION_11
}
}
project.pluginManager.withPlugin("com.android.application", action)
project.pluginManager.withPlugin("com.android.library", action)
}
// We set kotlin.jvm.target.validation.mode=warning on the root projects, as for projects
// on Gradle 8+ and Kotlin 1.8+ this value is set to `error`. This will cause the build to
// fail if the JDK version between compileKotlin and compileJava and jvmTarget are not
// aligned. This won't be necessary anymore from React Native 0.73. More on this:
// https://kotlinlang.org/docs/whatsnew18.html#obligatory-check-for-jvm-targets-of-related-kotlin-and-java-compile-tasks
input.rootProject.extensions.extraProperties.set("kotlin.jvm.target.validation.mode", "warning")
}
}
@@ -40,16 +40,22 @@ internal object NdkConfiguratorUtils {
// Parameters should be provided in an additive manner (do not override what
// the user provided, but allow for sensible defaults).
val cmakeArgs = ext.defaultConfig.externalNativeBuild.cmake.arguments
if ("-DPROJECT_BUILD_DIR" !in cmakeArgs) {
if (cmakeArgs.none { it.startsWith("-DPROJECT_BUILD_DIR") }) {
cmakeArgs.add("-DPROJECT_BUILD_DIR=${project.buildDir}")
}
if ("-DREACT_ANDROID_DIR" !in cmakeArgs) {
if (cmakeArgs.none { it.startsWith("-DREACT_ANDROID_DIR") }) {
cmakeArgs.add(
"-DREACT_ANDROID_DIR=${extension.reactNativeDir.file("ReactAndroid").get().asFile}")
}
if ("-DANDROID_STL" !in cmakeArgs) {
if (cmakeArgs.none { it.startsWith("-DANDROID_STL") }) {
cmakeArgs.add("-DANDROID_STL=c++_shared")
}
// Due to the new NDK toolchain file, the C++ flags gets overridden between compilation
// units. This is causing some libraries to don't be compiled with -DANDROID and other
// crucial flags. This can be revisited once we bump to NDK 25/26
if (cmakeArgs.none { it.startsWith("-DANDROID_USE_LEGACY_TOOLCHAIN_FILE") }) {
cmakeArgs.add("-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON")
}
val architectures = project.getReactNativeArchitectures()
// abiFilters are split ABI are not compatible each other, so we set the abiFilters
@@ -0,0 +1,18 @@
/*
* 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.utils
/** Collection of all the Gradle Propreties that are accepted by React Native Gradle Plugin. */
object PropertyUtils {
/**
* Internal Property that acts as a killswitch to configure the JDK version and align it for app
* and all the libraries.
*/
const val INTERNAL_DISABLE_JAVA_VERSION_ALIGNMENT = "react.internal.disableJavaVersionAlignment"
}
@@ -341,11 +341,12 @@ class BundleHermesCTaskTest {
assertEquals(customHermesc, hermesCommand[0])
assertEquals("-emit-binary", hermesCommand[1])
assertEquals("-out", hermesCommand[2])
assertEquals(bytecodeFile.absolutePath, hermesCommand[3])
assertEquals(bundleFile.absolutePath, hermesCommand[4])
assertEquals("my-custom-hermes-flag", hermesCommand[5])
assertEquals(6, hermesCommand.size)
assertEquals("-max-diagnostic-width=80", hermesCommand[2])
assertEquals("-out", hermesCommand[3])
assertEquals(bytecodeFile.absolutePath, hermesCommand[4])
assertEquals(bundleFile.absolutePath, hermesCommand[5])
assertEquals("my-custom-hermes-flag", hermesCommand[6])
assertEquals(7, hermesCommand.size)
}
@Test
@@ -366,11 +367,12 @@ class BundleHermesCTaskTest {
assertEquals("/c", hermesCommand[1])
assertEquals(customHermesc, hermesCommand[2])
assertEquals("-emit-binary", hermesCommand[3])
assertEquals("-out", hermesCommand[4])
assertEquals(bytecodeFile.relativeTo(tempFolder.root).path, hermesCommand[5])
assertEquals(bundleFile.relativeTo(tempFolder.root).path, hermesCommand[6])
assertEquals("my-custom-hermes-flag", hermesCommand[7])
assertEquals(8, hermesCommand.size)
assertEquals("-max-diagnostic-width=80", hermesCommand[4])
assertEquals("-out", hermesCommand[5])
assertEquals(bytecodeFile.relativeTo(tempFolder.root).path, hermesCommand[6])
assertEquals(bundleFile.relativeTo(tempFolder.root).path, hermesCommand[7])
assertEquals("my-custom-hermes-flag", hermesCommand[8])
assertEquals(9, hermesCommand.size)
}
@Test
@@ -12,7 +12,7 @@ import com.facebook.react.utils.DependencyUtils.configureDependencies
import com.facebook.react.utils.DependencyUtils.configureRepositories
import com.facebook.react.utils.DependencyUtils.mavenRepoFromURI
import com.facebook.react.utils.DependencyUtils.mavenRepoFromUrl
import com.facebook.react.utils.DependencyUtils.readVersionString
import com.facebook.react.utils.DependencyUtils.readVersionAndGroupStrings
import java.net.URI
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
import org.gradle.testfixtures.ProjectBuilder
@@ -226,6 +226,24 @@ class DependencyUtilsTest {
assertTrue(libForcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
}
@Test
fun configureDependencies_withVersionStringAndGroupString_appliesOnAllProjects() {
val rootProject = ProjectBuilder.builder().build()
val appProject = ProjectBuilder.builder().withName("app").withParent(rootProject).build()
val libProject = ProjectBuilder.builder().withName("lib").withParent(rootProject).build()
appProject.plugins.apply("com.android.application")
libProject.plugins.apply("com.android.library")
configureDependencies(appProject, "1.2.3", "io.github.test")
val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules
val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules
assertTrue(appForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" })
assertTrue(appForcedModules.any { it.toString() == "io.github.test:hermes-android:1.2.3" })
assertTrue(libForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" })
assertTrue(libForcedModules.any { it.toString() == "io.github.test:hermes-android:1.2.3" })
}
@Test
fun readVersionString_withCorrectVersionString_returnsIt() {
val propertiesFile =
@@ -238,7 +256,7 @@ class DependencyUtilsTest {
.trimIndent())
}
val versionString = readVersionString(propertiesFile)
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertEquals("1000.0.0", versionString)
}
@@ -255,7 +273,7 @@ class DependencyUtilsTest {
.trimIndent())
}
val versionString = readVersionString(propertiesFile)
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertEquals("0.0.0-20221101-2019-cfe811ab1-SNAPSHOT", versionString)
}
@@ -271,7 +289,7 @@ class DependencyUtilsTest {
.trimIndent())
}
val versionString = readVersionString(propertiesFile)
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertEquals("", versionString)
}
@@ -287,10 +305,43 @@ class DependencyUtilsTest {
.trimIndent())
}
val versionString = readVersionString(propertiesFile)
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertEquals("", versionString)
}
@Test
fun readGroupString_withCorrectGroupString_returnsIt() {
val propertiesFile =
tempFolder.newFile("gradle.properties").apply {
writeText(
"""
GROUP=io.github.test
ANOTHER_PROPERTY=true
"""
.trimIndent())
}
val groupString = readVersionAndGroupStrings(propertiesFile).second
assertEquals("io.github.test", groupString)
}
@Test
fun readGroupString_withEmptyGroupString_returnsDefault() {
val propertiesFile =
tempFolder.newFile("gradle.properties").apply {
writeText(
"""
ANOTHER_PROPERTY=true
"""
.trimIndent())
}
val groupString = readVersionAndGroupStrings(propertiesFile).second
assertEquals("com.facebook.react", groupString)
}
@Test
fun mavenRepoFromUrl_worksCorrectly() {
val process = createProject()
@@ -94,6 +94,11 @@
*/
- (UIViewController *)createRootViewController;
/// This method controls whether the App will use RuntimeScheduler. Only applicable in the legacy architecture.
///
/// @return: `YES` to use RuntimeScheduler, `NO` to use JavaScript scheduler. The default value is `YES`.
- (BOOL)runtimeSchedulerEnabled;
#if RCT_NEW_ARCH_ENABLED
/// The TurboModule manager
@@ -6,33 +6,41 @@
*/
#import "RCTAppDelegate.h"
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTRootView.h>
#import <React/RCTRuntimeExecutorFromBridge.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import "RCTAppSetupUtils.h"
#if RCT_NEW_ARCH_ENABLED
#import <React/CoreModulesPlugins.h>
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTComponentViewFactory.h>
#import <React/RCTComponentViewProtocol.h>
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
#import <React/RCTLegacyViewManagerInteropComponentView.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <ReactCommon/RCTTurboModuleManager.h>
#import <react/config/ReactNativeConfig.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h>
#import "RCTLegacyInteropComponents.h"
static NSString *const kRNConcurrentRoot = @"concurrentRoot";
@interface RCTAppDelegate () <RCTTurboModuleManagerDelegate, RCTCxxBridgeDelegate> {
@interface RCTAppDelegate () <RCTTurboModuleManagerDelegate> {
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
facebook::react::ContextContainer::Shared _contextContainer;
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
}
@end
#endif
@interface RCTAppDelegate () <RCTCxxBridgeDelegate> {
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
}
@end
@implementation RCTAppDelegate
#if RCT_NEW_ARCH_ENABLED
@@ -126,21 +134,34 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
return [UIViewController new];
}
#if RCT_NEW_ARCH_ENABLED
- (BOOL)runtimeSchedulerEnabled
{
return YES;
}
#pragma mark - RCTCxxBridgeDelegate
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
_runtimeScheduler = _runtimeScheduler =
std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
#if RCT_NEW_ARCH_ENABLED
_runtimeScheduler = std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
std::shared_ptr<facebook::react::CallInvoker> callInvoker =
std::make_shared<facebook::react::RuntimeSchedulerCallInvoker>(_runtimeScheduler);
self.turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self jsInvoker:callInvoker];
_contextContainer->erase("RuntimeScheduler");
_contextContainer->insert("RuntimeScheduler", _runtimeScheduler);
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager, _runtimeScheduler);
return RCTAppSetupDefaultJsExecutorFactory(bridge, self.turboModuleManager, _runtimeScheduler);
#else
if (self.runtimeSchedulerEnabled) {
_runtimeScheduler = std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
}
return RCTAppSetupJsExecutorFactoryForOldArch(bridge, _runtimeScheduler);
#endif
}
#pragma mark RCTTurboModuleManagerDelegate
#if RCT_NEW_ARCH_ENABLED
#pragma mark - RCTTurboModuleManagerDelegate
- (Class)getModuleClassFromName:(const char *)name
{
@@ -11,7 +11,7 @@
#ifdef __cplusplus
#if RCT_NEW_ARCH_ENABLED
#import <memory>
#ifndef RCT_USE_HERMES
#if __has_include(<reacthermes/HermesExecutorFactory.h>)
@@ -27,21 +27,27 @@
#import <React/JSCExecutorFactory.h>
#endif
#if RCT_NEW_ARCH_ENABLED
#import <ReactCommon/RCTTurboModuleManager.h>
#endif
#if RCT_NEW_ARCH_ENABLED
// Forward declaration to decrease compilation coupling
namespace facebook::react {
class RuntimeScheduler;
}
#if RCT_NEW_ARCH_ENABLED
RCT_EXTERN id<RCTTurboModule> RCTAppSetupDefaultModuleFromClass(Class moduleClass);
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupDefaultJsExecutorFactory(
RCTBridge *bridge,
RCTTurboModuleManager *turboModuleManager,
std::shared_ptr<facebook::react::RuntimeScheduler> const &runtimeScheduler);
#else
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupJsExecutorFactoryForOldArch(
RCTBridge *bridge,
std::shared_ptr<facebook::react::RuntimeScheduler> const &runtimeScheduler);
#endif
#endif // __cplusplus
@@ -7,6 +7,10 @@
#import "RCTAppSetupUtils.h"
#import <React/RCTJSIExecutorRuntimeInstaller.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>
#if RCT_NEW_ARCH_ENABLED
// Turbo Module
#import <React/CoreModulesPlugins.h>
@@ -15,7 +19,6 @@
#import <React/RCTGIFImageDecoder.h>
#import <React/RCTHTTPRequestHandler.h>
#import <React/RCTImageLoader.h>
#import <React/RCTJSIExecutorRuntimeInstaller.h>
#import <React/RCTLocalAssetImageLoader.h>
#import <React/RCTNetworking.h>
@@ -135,4 +138,25 @@ std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupDefaultJsExecutor
}));
}
#else
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupJsExecutorFactoryForOldArch(
RCTBridge *bridge,
std::shared_ptr<facebook::react::RuntimeScheduler> const &runtimeScheduler)
{
#if RCT_USE_HERMES
return std::make_unique<facebook::react::HermesExecutorFactory>(
#else
return std::make_unique<facebook::react::JSCExecutorFactory>(
#endif
facebook::react::RCTJSIExecutorRuntimeInstaller([bridge, runtimeScheduler](facebook::jsi::Runtime &runtime) {
if (!bridge) {
return;
}
if (runtimeScheduler) {
facebook::react::RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime, runtimeScheduler);
}
}));
}
#endif
@@ -47,6 +47,9 @@ header_search_paths = [
"$(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-debug/React_debug.framework/Headers/",
"$(PODS_CONFIGURATION_BUILD_DIR)/React-runtimescheduler/React_runtimescheduler.framework/Headers/",
] : []).map{|p| "\"#{p}\""}.join(" ")
Pod::Spec.new do |s|
@@ -75,15 +78,29 @@ Pod::Spec.new do |s|
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "ReactCommon/turbomodule/core"
s.dependency "React-RCTNetwork"
s.dependency "React-RCTImage"
s.dependency "React-NativeModulesApple"
s.dependency "React-CoreModules"
s.dependency "React-runtimescheduler"
if ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == "1"
s.dependency "React-hermes"
else
s.dependency "React-jsc"
end
if is_new_arch_enabled
s.dependency "React-RCTFabric"
s.dependency "React-graphics"
s.dependency "React-utils"
s.dependency "React-debug"
s.script_phases = {
:name => "Generate Legacy Components Interop",
:script => "
. ${PODS_ROOT}/../.xcode.env
WITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"
source $WITH_ENVIRONMENT
${NODE_BINARY} ${REACT_NATIVE_PATH}/scripts/codegen/generate-legacy-interop-components.js -p #{ENV['APP_PATH']} -o ${REACT_NATIVE_PATH}/Libraries/AppDelegate
",
:execution_position => :before_compile,
@@ -692,7 +692,6 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = {
fontStyle: true,
textShadowOffset: true,
selectionColor: {process: require('../../StyleSheet/processColor').default},
selection: true,
placeholderTextColor: {
process: require('../../StyleSheet/processColor').default,
},
@@ -289,92 +289,6 @@ export interface TextInputIOSProps {
* @see https://reactnative.dev/docs/textinput#props
*/
export interface TextInputAndroidProps {
/**
* Specifies autocomplete hints for the system, so it can provide autofill. On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set `autoComplete` to `off`.
*
* *Android Only*
*
* Possible values for `autoComplete` are:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `cc-number`
* - `email`
* - `gender`
* - `name`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `postal-code`
* - `street-address`
* - `sms-otp`
* - `tel`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username`
* - `username-new`
* - `off`
*/
autoComplete?:
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'email'
| 'gender'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'username'
| 'username-new'
| 'off'
| undefined;
/**
* When provided it will set the color of the cursor (or "caret") in the component.
* Unlike the behavior of `selectionColor` the cursor color will be set independently
@@ -558,6 +472,127 @@ export interface TextInputProps
*/
autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters' | undefined;
/**
* Specifies autocomplete hints for the system, so it can provide autofill.
* On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set autoComplete to off.
*
* The following values work across platforms:
*
* - `additional-name`
* - `address-line1`
* - `address-line2`
* - `cc-number`
* - `country`
* - `current-password`
* - `email`
* - `family-name`
* - `given-name`
* - `honorific-prefix`
* - `honorific-suffix`
* - `name`
* - `new-password`
* - `off`
* - `one-time-code`
* - `postal-code`
* - `street-address`
* - `tel`
* - `username`
*
* The following values work on iOS only:
*
* - `nickname`
* - `organization`
* - `organization-title`
* - `url`
*
* The following values work on Android only:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `gender`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `sms-otp`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username-new`
*/
autoComplete?:
| 'additional-name'
| 'address-line1'
| 'address-line2'
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'country'
| 'current-password'
| 'email'
| 'family-name'
| 'gender'
| 'given-name'
| 'honorific-prefix'
| 'honorific-suffix'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'new-password'
| 'nickname'
| 'one-time-code'
| 'organization'
| 'organization-title'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'url'
| 'username'
| 'username-new'
| 'off'
| undefined;
/**
* If false, disables auto-correct.
* The default value is true.
@@ -196,36 +196,6 @@ export type enterKeyHintType =
type PasswordRules = string;
type IOSProps = $ReadOnly<{|
/**
* Give the keyboard and the system information about the
* expected semantic meaning for the content that users enter.
* @platform ios
*/
autoComplete?: ?(
| 'address-line1'
| 'address-line2'
| 'cc-number'
| 'current-password'
| 'country'
| 'email'
| 'name'
| 'additional-name'
| 'family-name'
| 'given-name'
| 'nickname'
| 'honorific-prefix'
| 'honorific-suffix'
| 'new-password'
| 'off'
| 'one-time-code'
| 'organization'
| 'organization-title'
| 'postal-code'
| 'street-address'
| 'tel'
| 'url'
| 'username'
),
/**
* When the clear button should appear on the right side of the text view.
* This property is supported only for single-line TextInput component.
@@ -328,111 +298,6 @@ type IOSProps = $ReadOnly<{|
|}>;
type AndroidProps = $ReadOnly<{|
/**
* Specifies autocomplete hints for the system, so it can provide autofill. On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set `autoComplete` to `off`.
*
* *Android Only*
*
* Possible values for `autoComplete` are:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `cc-number`
* - `email`
* - `gender`
* - `name`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `postal-code`
* - `street-address`
* - `sms-otp`
* - `tel`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username`
* - `username-new`
* - `off`
*
* @platform android
*/
autoComplete?: ?(
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'email'
| 'gender'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'username'
| 'username-new'
| 'off'
// additional HTML autocomplete values
| 'address-line1'
| 'address-line2'
| 'bday'
| 'bday-day'
| 'bday-month'
| 'bday-year'
| 'country'
| 'current-password'
| 'honorific-prefix'
| 'honorific-suffix'
| 'additional-name'
| 'family-name'
| 'given-name'
| 'new-password'
| 'one-time-code'
| 'sex'
),
/**
* When provided it will set the color of the cursor (or "caret") in the component.
* Unlike the behavior of `selectionColor` the cursor color will be set independently
@@ -533,6 +398,127 @@ export type Props = $ReadOnly<{|
*/
autoCapitalize?: ?AutoCapitalize,
/**
* Specifies autocomplete hints for the system, so it can provide autofill.
* On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set autoComplete to off.
*
* The following values work across platforms:
*
* - `additional-name`
* - `address-line1`
* - `address-line2`
* - `cc-number`
* - `country`
* - `current-password`
* - `email`
* - `family-name`
* - `given-name`
* - `honorific-prefix`
* - `honorific-suffix`
* - `name`
* - `new-password`
* - `off`
* - `one-time-code`
* - `postal-code`
* - `street-address`
* - `tel`
* - `username`
*
* The following values work on iOS only:
*
* - `nickname`
* - `organization`
* - `organization-title`
* - `url`
*
* The following values work on Android only:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `gender`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `sms-otp`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username-new`
*/
autoComplete?: ?(
| 'additional-name'
| 'address-line1'
| 'address-line2'
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'country'
| 'current-password'
| 'email'
| 'family-name'
| 'gender'
| 'given-name'
| 'honorific-prefix'
| 'honorific-suffix'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'new-password'
| 'nickname'
| 'one-time-code'
| 'organization'
| 'organization-title'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'url'
| 'username'
| 'username-new'
| 'off'
),
/**
* If `false`, disables auto-correct. The default value is `true`.
*/
@@ -234,36 +234,6 @@ export type enterKeyHintType =
type PasswordRules = string;
type IOSProps = $ReadOnly<{|
/**
* Give the keyboard and the system information about the
* expected semantic meaning for the content that users enter.
* @platform ios
*/
autoComplete?: ?(
| 'address-line1'
| 'address-line2'
| 'cc-number'
| 'current-password'
| 'country'
| 'email'
| 'name'
| 'additional-name'
| 'family-name'
| 'given-name'
| 'nickname'
| 'honorific-prefix'
| 'honorific-suffix'
| 'new-password'
| 'off'
| 'one-time-code'
| 'organization'
| 'organization-title'
| 'postal-code'
| 'street-address'
| 'tel'
| 'url'
| 'username'
),
/**
* When the clear button should appear on the right side of the text view.
* This property is supported only for single-line TextInput component.
@@ -369,111 +339,6 @@ type IOSProps = $ReadOnly<{|
|}>;
type AndroidProps = $ReadOnly<{|
/**
* Specifies autocomplete hints for the system, so it can provide autofill. On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set `autoComplete` to `off`.
*
* *Android Only*
*
* Possible values for `autoComplete` are:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `cc-number`
* - `email`
* - `gender`
* - `name`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `postal-code`
* - `street-address`
* - `sms-otp`
* - `tel`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username`
* - `username-new`
* - `off`
*
* @platform android
*/
autoComplete?: ?(
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'email'
| 'gender'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'username'
| 'username-new'
| 'off'
// additional HTML autocomplete values
| 'address-line1'
| 'address-line2'
| 'bday'
| 'bday-day'
| 'bday-month'
| 'bday-year'
| 'country'
| 'current-password'
| 'honorific-prefix'
| 'honorific-suffix'
| 'additional-name'
| 'family-name'
| 'given-name'
| 'new-password'
| 'one-time-code'
| 'sex'
),
/**
* When provided it will set the color of the cursor (or "caret") in the component.
* Unlike the behavior of `selectionColor` the cursor color will be set independently
@@ -574,6 +439,127 @@ export type Props = $ReadOnly<{|
*/
autoCapitalize?: ?AutoCapitalize,
/**
* Specifies autocomplete hints for the system, so it can provide autofill.
* On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set autoComplete to off.
*
* The following values work across platforms:
*
* - `additional-name`
* - `address-line1`
* - `address-line2`
* - `cc-number`
* - `country`
* - `current-password`
* - `email`
* - `family-name`
* - `given-name`
* - `honorific-prefix`
* - `honorific-suffix`
* - `name`
* - `new-password`
* - `off`
* - `one-time-code`
* - `postal-code`
* - `street-address`
* - `tel`
* - `username`
*
* The following values work on iOS only:
*
* - `nickname`
* - `organization`
* - `organization-title`
* - `url`
*
* The following values work on Android only:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `gender`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `sms-otp`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username-new`
*/
autoComplete?: ?(
| 'additional-name'
| 'address-line1'
| 'address-line2'
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'country'
| 'current-password'
| 'email'
| 'family-name'
| 'gender'
| 'given-name'
| 'honorific-prefix'
| 'honorific-suffix'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'new-password'
| 'nickname'
| 'one-time-code'
| 'organization'
| 'organization-title'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'url'
| 'username'
| 'username-new'
| 'off'
),
/**
* If `false`, disables auto-correct. The default value is `true`.
*/
@@ -1080,27 +1066,19 @@ function InternalTextInput(props: Props): React.Node {
accessibilityState,
id,
tabIndex,
selection: propsSelection,
...otherProps
} = props;
const inputRef = useRef<null | React.ElementRef<HostComponent<mixed>>>(null);
// Android sends a "onTextChanged" event followed by a "onSelectionChanged" event, for
// the same "most recent event count".
// For controlled selection, that means that immediately after text is updated,
// a controlled component will pass in the *previous* selection, even if the controlled
// component didn't mean to modify the selection at all.
// Therefore, we ignore selections and pass them through until the selection event has
// been sent.
// Note that this mitigation is NOT needed for Fabric.
// discovered when upgrading react-hooks
// eslint-disable-next-line react-hooks/exhaustive-deps
let selection: ?Selection =
props.selection == null
const selection: ?Selection =
propsSelection == null
? null
: {
start: props.selection.start,
end: props.selection.end ?? props.selection.start,
start: propsSelection.start,
end: propsSelection.end ?? propsSelection.start,
};
const [mostRecentEventCount, setMostRecentEventCount] = useState<number>(0);
@@ -1112,12 +1090,6 @@ function InternalTextInput(props: Props): React.Node {
|}>({selection, mostRecentEventCount});
const lastNativeSelection = lastNativeSelectionState.selection;
const lastNativeSelectionEventCount =
lastNativeSelectionState.mostRecentEventCount;
if (lastNativeSelectionEventCount < mostRecentEventCount) {
selection = null;
}
let viewCommands;
if (AndroidTextInputCommands) {
@@ -1517,7 +1489,6 @@ function InternalTextInput(props: Props): React.Node {
onScroll={_onScroll}
onSelectionChange={_onSelectionChange}
placeholder={placeholder}
selection={selection}
style={style}
text={text}
textBreakStrategy={props.textBreakStrategy}
@@ -46,13 +46,6 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
flexWrap: true,
gap: true,
height: true,
inset: true,
insetBlock: true,
insetBlockEnd: true,
insetBlockStart: true,
insetInline: true,
insetInlineEnd: true,
insetInlineStart: true,
justifyContent: true,
left: true,
margin: true,
+3 -3
View File
@@ -10,8 +10,8 @@
*/
exports.version = {
major: 1000,
minor: 0,
patch: 0,
major: 0,
minor: 72,
patch: 3,
prerelease: null,
};
@@ -39,8 +39,12 @@ exports.checkVersions = function checkVersions(): void {
}
};
// Note: in OSS, the prerelease version is usually 0.Y.0-rc.W, so it is a string and not a number
// Then we need to keep supporting that object shape.
function _formatVersion(
version: (typeof Platform)['constants']['reactNativeVersion'],
version:
| (typeof Platform)['constants']['reactNativeVersion']
| {major: number, minor: number, patch: number, prerelease: ?string},
): string {
return (
`${version.major}.${version.minor}.${version.patch}` +
@@ -28,7 +28,10 @@ header_search_paths = [
if ENV["USE_FRAMEWORKS"]
header_search_paths = header_search_paths.concat([
"\"$(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-NativeModulesApple/React_NativeModulesApple.framework/Headers\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-NativeModulesApple/React_NativeModulesApple.framework/Headers/build/generated/ios\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-Codegen/React_Codegen.framework/Headers/build/generated/ios\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-Codegen/React_Codegen.framework/Headers\""
])
end
@@ -111,6 +111,7 @@ exports[`FlatList renders all the bells and whistles 1`] = `
<RCTRefreshControl />
<View>
<View
collapsable={false}
onLayout={[Function]}
>
<header />
@@ -243,6 +243,7 @@ exports[`SectionList renders all the bells and whistles 1`] = `
<RCTRefreshControl />
<View>
<View
collapsable={false}
onLayout={[Function]}
>
<header
@@ -258,14 +258,6 @@ const validAttributesForNonEventProps = {
top: true,
bottom: true,
inset: true,
insetBlock: true,
insetBlockEnd: true,
insetBlockStart: true,
insetInline: true,
insetInlineEnd: true,
insetInlineStart: true,
position: true,
style: ReactNativeStyleAttributes,
@@ -236,14 +236,6 @@ const validAttributesForNonEventProps = {
bottom: true,
left: true,
inset: true,
insetBlock: true,
insetBlockEnd: true,
insetBlockStart: true,
insetInline: true,
insetInlineEnd: true,
insetInlineStart: true,
width: true,
height: true,
@@ -28,7 +28,11 @@ header_search_paths = [
if ENV["USE_FRAMEWORKS"]
header_search_paths = header_search_paths.concat([
"\"$(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-NativeModulesApple/React_NativeModulesApple.framework/Headers\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-NativeModulesApple/React_NativeModulesApple.framework/Headers/build/generated/ios\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-Codegen/React_Codegen.framework/Headers/build/generated/ios\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-Codegen/React_Codegen.framework/Headers\"",
])
end
@@ -75,7 +75,6 @@ const PERMISSIONS = Object.freeze({
ANSWER_PHONE_CALLS: 'android.permission.ANSWER_PHONE_CALLS',
READ_PHONE_NUMBERS: 'android.permission.READ_PHONE_NUMBERS',
UWB_RANGING: 'android.permission.UWB_RANGING',
POST_NOTIFICATION: 'android.permission.POST_NOTIFICATIONS', // Remove in 0.72
POST_NOTIFICATIONS: 'android.permission.POST_NOTIFICATIONS',
NEARBY_WIFI_DEVICES: 'android.permission.NEARBY_WIFI_DEVICES',
});
@@ -107,7 +106,6 @@ class PermissionsAndroid {
CAMERA: string,
GET_ACCOUNTS: string,
NEARBY_WIFI_DEVICES: string,
POST_NOTIFICATION: string, // Remove in 0.72
POST_NOTIFICATIONS: string,
PROCESS_OUTGOING_CALLS: string,
READ_CALENDAR: string,
+27 -1
View File
@@ -9,7 +9,6 @@
*/
import type {RootTag} from '../Types/RootTagTypes';
import type {Spec as FabricUIManagerSpec} from './FabricUIManager';
import type {Spec} from './NativeUIManager';
import {getFabricUIManager} from './FabricUIManager';
@@ -175,6 +174,33 @@ const UIManager = {
);
}
},
dispatchViewManagerCommand(
reactTag: number,
commandName: number | string,
commandArgs: any[],
) {
if (isFabricReactTag(reactTag)) {
const FabricUIManager = nullthrows(getFabricUIManager());
const shadowNode =
FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag);
if (shadowNode) {
// Transform the accidental CommandID into a CommandName which is the stringified number.
// The interop layer knows how to convert this number into the right method name.
// Stringify a string is a no-op, so it's safe.
commandName = `${commandName}`;
FabricUIManager.dispatchCommand(shadowNode, commandName, commandArgs);
}
} else {
UIManagerImpl.dispatchViewManagerCommand(
reactTag,
// We have some legacy components that are actually already using strings. ¯\_(ツ)_/¯
// $FlowFixMe[incompatible-call]
commandName,
commandArgs,
);
}
},
};
module.exports = UIManager;
@@ -3419,6 +3419,23 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) {
return callback.apply(context, arguments);
};
}
function warnForStyleProps(props, validAttributes) {
{
for (var key in validAttributes.style) {
if (!(validAttributes[key] || props[key] === undefined)) {
error(
"You are setting the style `{ %s" +
": ... }` as a prop. You " +
"should nest it in a style object. " +
"E.g. `{ style: { %s" +
": ... } }`",
key,
key
);
}
}
}
}
// Modules provided by RN:
var emptyObject = {};
@@ -5100,7 +5117,8 @@ var _nativeFabricUIManage = nativeFabricUIManager,
FabricDefaultPriority = _nativeFabricUIManage.unstable_DefaultEventPriority,
FabricDiscretePriority = _nativeFabricUIManage.unstable_DiscreteEventPriority,
fabricGetCurrentEventPriority =
_nativeFabricUIManage.unstable_getCurrentEventPriority;
_nativeFabricUIManage.unstable_getCurrentEventPriority,
_setNativeProps = _nativeFabricUIManage.setNativeProps;
var getViewConfigForType =
ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views.
// % 10 === 1 means it is a rootTag.
@@ -5199,10 +5217,15 @@ var ReactFabricHostComponent = /*#__PURE__*/ (function() {
_proto.setNativeProps = function setNativeProps(nativeProps) {
{
error("Warning: setNativeProps is not currently supported in Fabric");
warnForStyleProps(nativeProps, this.viewConfig.validAttributes);
}
return;
var updatePayload = create(nativeProps, this.viewConfig.validAttributes);
var stateNode = this._internalInstanceHandle.stateNode;
if (stateNode != null && updatePayload != null) {
_setNativeProps(stateNode.node, updatePayload);
}
}; // This API (addEventListener, removeEventListener) attempts to adhere to the
// w3 Level2 Events spec as much as possible, treating HostComponent as a DOM node.
//
@@ -1922,6 +1922,7 @@ var _nativeFabricUIManage = nativeFabricUIManager,
FabricDiscretePriority = _nativeFabricUIManage.unstable_DiscreteEventPriority,
fabricGetCurrentEventPriority =
_nativeFabricUIManage.unstable_getCurrentEventPriority,
_setNativeProps = _nativeFabricUIManage.setNativeProps,
getViewConfigForType =
ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get,
nextReactTag = 2;
@@ -1979,7 +1980,18 @@ var ReactFabricHostComponent = (function() {
);
}
};
_proto.setNativeProps = function() {};
_proto.setNativeProps = function(nativeProps) {
nativeProps = diffProperties(
null,
emptyObject,
nativeProps,
this.viewConfig.validAttributes
);
var stateNode = this._internalInstanceHandle.stateNode;
null != stateNode &&
null != nativeProps &&
_setNativeProps(stateNode.node, nativeProps);
};
_proto.addEventListener_unstable = function(eventType, listener, options) {
if ("string" !== typeof eventType)
throw Error("addEventListener_unstable eventType must be a string");
@@ -1981,6 +1981,7 @@ var _nativeFabricUIManage = nativeFabricUIManager,
FabricDiscretePriority = _nativeFabricUIManage.unstable_DiscreteEventPriority,
fabricGetCurrentEventPriority =
_nativeFabricUIManage.unstable_getCurrentEventPriority,
_setNativeProps = _nativeFabricUIManage.setNativeProps,
getViewConfigForType =
ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get,
nextReactTag = 2;
@@ -2038,7 +2039,18 @@ var ReactFabricHostComponent = (function() {
);
}
};
_proto.setNativeProps = function() {};
_proto.setNativeProps = function(nativeProps) {
nativeProps = diffProperties(
null,
emptyObject,
nativeProps,
this.viewConfig.validAttributes
);
var stateNode = this._internalInstanceHandle.stateNode;
null != stateNode &&
null != nativeProps &&
_setNativeProps(stateNode.node, nativeProps);
};
_proto.addEventListener_unstable = function(eventType, listener, options) {
if ("string" !== typeof eventType)
throw Error("addEventListener_unstable eventType must be a string");
@@ -28,7 +28,10 @@ header_search_paths = [
if ENV["USE_FRAMEWORKS"]
header_search_paths = header_search_paths.concat([
"\"$(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-NativeModulesApple/React_NativeModulesApple.framework/Headers\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-NativeModulesApple/React_NativeModulesApple.framework/Headers/build/generated/ios\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-Codegen/React_Codegen.framework/Headers/build/generated/ios\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-Codegen/React_Codegen.framework/Headers\"",
])
end
@@ -18,7 +18,7 @@ type FlexAlignType =
| 'stretch'
| 'baseline';
type DimensionValue =
export type DimensionValue =
| number
| 'auto'
| `${number}%`
@@ -69,13 +69,6 @@ export interface FlexStyle {
flexShrink?: number | undefined;
flexWrap?: 'wrap' | 'nowrap' | 'wrap-reverse' | undefined;
height?: DimensionValue | undefined;
inset?: DimensionValue | undefined;
insetBlock?: DimensionValue | undefined;
insetBlockEnd?: DimensionValue | undefined;
insetBlockStart?: DimensionValue | undefined;
insetInline?: DimensionValue | undefined;
insetInlineEnd?: DimensionValue | undefined;
insetInlineStart?: DimensionValue | undefined;
justifyContent?:
| 'flex-start'
| 'flex-end'
@@ -86,15 +79,9 @@ export interface FlexStyle {
| undefined;
left?: DimensionValue | undefined;
margin?: DimensionValue | undefined;
marginBlock?: DimensionValue | undefined;
marginBlockEnd?: DimensionValue | undefined;
marginBlockStart?: DimensionValue | undefined;
marginBottom?: DimensionValue | undefined;
marginEnd?: DimensionValue | undefined;
marginHorizontal?: DimensionValue | undefined;
marginInline?: DimensionValue | undefined;
marginInlineEnd?: DimensionValue | undefined;
marginInlineStart?: DimensionValue | undefined;
marginLeft?: DimensionValue | undefined;
marginRight?: DimensionValue | undefined;
marginStart?: DimensionValue | undefined;
@@ -107,14 +94,8 @@ export interface FlexStyle {
overflow?: 'visible' | 'hidden' | 'scroll' | undefined;
padding?: DimensionValue | undefined;
paddingBottom?: DimensionValue | undefined;
paddingBlock?: DimensionValue | undefined;
paddingBlockEnd?: DimensionValue | undefined;
paddingBlockStart?: DimensionValue | undefined;
paddingEnd?: DimensionValue | undefined;
paddingHorizontal?: DimensionValue | undefined;
paddingInline?: DimensionValue | undefined;
paddingInlineEnd?: DimensionValue | undefined;
paddingInlineStart?: DimensionValue | undefined;
paddingLeft?: DimensionValue | undefined;
paddingRight?: DimensionValue | undefined;
paddingStart?: DimensionValue | undefined;
@@ -134,80 +134,6 @@ type ____LayoutStyle_Internal = $ReadOnly<{
*/
top?: DimensionValue,
/** `inset` is a shorthand that corresponds to the top, right, bottom, and/or left properties.
*
* It works similarly to `inset` in CSS, but in React Native you
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/inset
* for more details of how `inset` affects layout.
*/
inset?: DimensionValue,
/** `insetBlock` is a shorthand that corresponds to the `insetBlockStart` and `insetBlockEnd` properties.
*
* It works similarly to `inset-block` in CSS, but in React Native you
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-block
* for more details of how `inset-block` affects layout.
*/
insetBlock?: DimensionValue,
/** `insetBlockEnd` is a logical property that sets the length that an
* element is offset in the block direction from its ending edge.
*
* It works similarly to `inset-block-end` in CSS, but in React Native you
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-block-end
* for more details of how `inset-block-end` affects layout.
*/
insetBlockEnd?: DimensionValue,
/** `insetBlockStart` is a logical property that sets the length that an
* element is offset in the block direction from its starting edge.
*
* It works similarly to `inset-block-start` in CSS, but in React Native you
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-block-start
* for more details of how `inset-block-start` affects layout.
*/
insetBlockStart?: DimensionValue,
/** `insetInline` is a shorthand that corresponds to the `insetInlineStart` and `insetInlineEnd` properties.
*
* It works similarly to `inset-inline` in CSS, but in React Native you
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-inline
* for more details of how `inset-inline` affects layout.
*/
insetInline?: DimensionValue,
/** `insetInlineEnd` is a logical property that sets the length that an
* element is offset in the starting inline direction.
*
* It works similarly to `inset-inline-end` in CSS, but in React Native you
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-inline-end
* for more details of how `inset-inline-end` affects layout.
*/
insetInlineEnd?: DimensionValue,
/** `insetInlineStart` is a logical property that sets the length that an
* element is offset in the starting inline direction.
*
* It works similarly to `inset-inline-start` in CSS, but in React Native you
* must use points or percentages. Ems and other units are not supported.
*
* See https://developer.mozilla.org/en-US/docs/Web/CSS/inset-inline-start
* for more details of how `inset-inline-start` affects layout.
*/
insetInlineStart?: DimensionValue,
/** `minWidth` is the minimum width for this component, in logical pixels.
*
* It works similarly to `min-width` in CSS, but in React Native you
@@ -260,17 +260,17 @@ static void *TextFieldSelectionObservingContext = &TextFieldSelectionObservingCo
_ignoreNextTextInputCall = NO;
return;
}
_lastStringStateWasUpdatedWith = _backedTextInputView.attributedText;
_textDidChangeIsComing = NO;
[_backedTextInputView.textInputDelegate textInputDidChange];
}
- (void)textViewDidChangeSelection:(__unused UITextView *)textView
{
if (![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
if (_lastStringStateWasUpdatedWith && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
[self textViewDidChange:_backedTextInputView];
_ignoreNextTextInputCall = YES;
}
_lastStringStateWasUpdatedWith = _backedTextInputView.attributedText;
[self textViewProbablyDidChangeSelection];
}
@@ -28,7 +28,9 @@ header_search_paths = [
if ENV["USE_FRAMEWORKS"]
header_search_paths = header_search_paths.concat([
"\"$(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-NativeModulesApple/React_NativeModulesApple.framework/Headers\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-Codegen/React_Codegen.framework/Headers/build/generated/ios\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-Codegen/React_Codegen.framework/Headers\""
])
end
+7 -5
View File
@@ -18,7 +18,7 @@ end
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
folly_version = '2021.07.22.00'
socket_rocket_version = '0.6.0'
socket_rocket_version = '0.6.1'
boost_compiler_flags = '-Wno-documentation'
use_hermes = ENV['USE_HERMES'] == '1'
@@ -126,11 +126,13 @@ Pod::Spec.new do |s|
end
s.dependency "RCT-Folly", folly_version
s.dependency "React-cxxreact", version
s.dependency "React-perflogger", version
s.dependency "React-jsi", version
s.dependency "React-jsiexecutor", version
s.dependency "React-cxxreact"
s.dependency "React-perflogger"
s.dependency "React-jsi"
s.dependency "React-jsiexecutor"
s.dependency "React-utils"
s.dependency "SocketRocket", socket_rocket_version
s.dependency "React-runtimeexecutor"
s.dependency "Yoga"
s.dependency "glog"
@@ -312,7 +312,17 @@ static void attemptAsynchronousLoadOfBundleAtURL(
return;
}
RCTSource *source = RCTSourceCreate(scriptURL, data, data.length);
// Prefer `Content-Location` as the canonical source URL, if given, or fall back to scriptURL.
NSURL *sourceURL = scriptURL;
NSString *contentLocationHeader = headers[@"Content-Location"];
if (contentLocationHeader) {
NSURL *contentLocationURL = [NSURL URLWithString:contentLocationHeader relativeToURL:scriptURL];
if (contentLocationURL) {
sourceURL = contentLocationURL;
}
}
RCTSource *source = RCTSourceCreate(sourceURL, data, data.length);
parseHeaders(headers, source);
onComplete(nil, source);
}
@@ -0,0 +1,19 @@
/*
* 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 <Foundation/Foundation.h>
#ifdef __cplusplus
#import <ReactCommon/RuntimeExecutor.h>
NS_ASSUME_NONNULL_BEGIN
@class RCTBridge;
facebook::react::RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge);
NS_ASSUME_NONNULL_END
#endif
@@ -0,0 +1,56 @@
/*
* 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 "RCTRuntimeExecutorFromBridge.h"
#import <React/RCTAssert.h>
#import <React/RCTBridge+Private.h>
#import <cxxreact/MessageQueueThread.h>
#import <react/utils/ManagedObjectWrapper.h>
using namespace facebook::react;
@interface RCTBridge ()
- (std::shared_ptr<MessageQueueThread>)jsMessageThread;
- (void)invokeAsync:(std::function<void()> &&)func;
@end
RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge)
{
RCTAssert(bridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil.");
auto bridgeWeakWrapper = wrapManagedObjectWeakly([bridge batchedBridge] ?: bridge);
RuntimeExecutor runtimeExecutor = [bridgeWeakWrapper](
std::function<void(facebook::jsi::Runtime & runtime)> &&callback) {
RCTBridge *bridge = unwrapManagedObjectWeakly(bridgeWeakWrapper);
RCTAssert(bridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil at the moment of scheduling a call.");
[bridge invokeAsync:[bridgeWeakWrapper, callback = std::move(callback)]() {
RCTCxxBridge *batchedBridge = (RCTCxxBridge *)unwrapManagedObjectWeakly(bridgeWeakWrapper);
RCTAssert(batchedBridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil at the moment of invocation.");
if (!batchedBridge) {
return;
}
auto runtime = (facebook::jsi::Runtime *)(batchedBridge.runtime);
RCTAssert(
runtime, @"RCTRuntimeExecutorFromBridge: Bridge must have a valid jsi::Runtime at the moment of invocation.");
if (!runtime) {
return;
}
callback(*runtime);
}];
};
return runtimeExecutor;
}
@@ -21,9 +21,9 @@ NSDictionary* RCTGetReactNativeVersion(void)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^(void){
__rnVersion = @{
RCTVersionMajor: @(1000),
RCTVersionMinor: @(0),
RCTVersionPatch: @(0),
RCTVersionMajor: @(0),
RCTVersionMinor: @(72),
RCTVersionPatch: @(3),
RCTVersionPrerelease: [NSNull null],
};
});
@@ -428,10 +428,10 @@ RCT_EXPORT_METHOD(show)
? UIAlertControllerStyleActionSheet
: UIAlertControllerStyleAlert;
NSString *debugMenuType = self.bridge ? @"Bridge" : @"Bridgeless";
NSString *debugMenuTitle = [NSString stringWithFormat:@"React Native Debug Menu (%@)", debugMenuType];
NSString *devMenuType = self.bridge ? @"Bridge" : @"Bridgeless";
NSString *devMenuTitle = [NSString stringWithFormat:@"React Native Dev Menu (%@)", devMenuType];
_actionSheet = [UIAlertController alertControllerWithTitle:debugMenuTitle message:description preferredStyle:style];
_actionSheet = [UIAlertController alertControllerWithTitle:devMenuTitle message:description preferredStyle:style];
NSArray<RCTDevMenuItem *> *items = [self _menuItemsToPresent];
for (RCTDevMenuItem *item in items) {
@@ -18,7 +18,7 @@ end
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
folly_version = '2021.07.22.00'
socket_rocket_version = '0.6.0'
socket_rocket_version = '0.6.1'
header_search_paths = [
"\"$(PODS_TARGET_SRCROOT)/React/CoreModules\"",
@@ -475,6 +475,7 @@ struct RCTInstanceCallback : public InstanceCallback {
// Load the source asynchronously, then store it for later execution.
dispatch_group_enter(prepareBridge);
__block NSData *sourceCode;
__block NSURL *sourceURL = self.bundleURL;
#if (RCT_DEV | RCT_ENABLE_LOADING_VIEW) && __has_include(<React/RCTDevLoadingViewProtocol.h>)
{
@@ -490,6 +491,9 @@ struct RCTInstanceCallback : public InstanceCallback {
}
sourceCode = source.data;
if (source.url) {
sourceURL = source.url;
}
dispatch_group_leave(prepareBridge);
}
onProgress:^(RCTLoadingProgress *progressData) {
@@ -504,7 +508,7 @@ struct RCTInstanceCallback : public InstanceCallback {
dispatch_group_notify(prepareBridge, dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
RCTCxxBridge *strongSelf = weakSelf;
if (sourceCode && strongSelf.loading) {
[strongSelf executeSourceCode:sourceCode sync:NO];
[strongSelf executeSourceCode:sourceCode withSourceURL:sourceURL sync:NO];
}
});
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
@@ -1050,7 +1054,7 @@ struct RCTInstanceCallback : public InstanceCallback {
[_displayLink registerModuleForFrameUpdates:module withModuleData:moduleData];
}
- (void)executeSourceCode:(NSData *)sourceCode sync:(BOOL)sync
- (void)executeSourceCode:(NSData *)sourceCode withSourceURL:(NSURL *)url sync:(BOOL)sync
{
// This will get called from whatever thread was actually executing JS.
dispatch_block_t completion = ^{
@@ -1075,12 +1079,13 @@ struct RCTInstanceCallback : public InstanceCallback {
};
if (sync) {
[self executeApplicationScriptSync:sourceCode url:self.bundleURL];
[self executeApplicationScriptSync:sourceCode url:url];
completion();
} else {
[self enqueueApplicationScript:sourceCode url:self.bundleURL onComplete:completion];
[self enqueueApplicationScript:sourceCode url:url onComplete:completion];
}
// Use the original request URL here - HMRClient uses this to derive the /hot URL and entry point.
[self.devSettings setupHMRClientWithBundleURL:self.bundleURL];
}
@@ -14,6 +14,7 @@
#import <react/renderer/components/image/ImageComponentDescriptor.h>
#import <react/renderer/components/image/ImageEventEmitter.h>
#import <react/renderer/components/image/ImageProps.h>
#import <react/renderer/core/CoreFeatures.h>
#import <react/renderer/imagemanager/ImageRequest.h>
#import <react/renderer/imagemanager/RCTImagePrimitivesConversions.h>
@@ -97,8 +98,21 @@ using namespace facebook::react;
- (void)_setStateAndResubscribeImageResponseObserver:(ImageShadowNode::ConcreteState::Shared const &)state
{
if (_state) {
auto &observerCoordinator = _state->getData().getImageRequest().getObserverCoordinator();
auto const &imageRequest = _state->getData().getImageRequest();
auto &observerCoordinator = imageRequest.getObserverCoordinator();
observerCoordinator.removeObserver(_imageResponseObserverProxy);
if (CoreFeatures::cancelImageDownloadsOnRecycle) {
// Cancelling image request because we are no longer observing it.
// This is not 100% correct place to do this because we may want to
// re-create RCTImageComponentView with the same image and if it
// was cancelled before downloaded, download is not resumed.
// This will only become issue if we decouple life cycle of a
// ShadowNode from ComponentView, which is not something we do now.
imageRequest.cancel();
imageRequest.cancel();
imageRequest.cancel();
imageRequest.cancel();
}
}
_state = state;
@@ -24,6 +24,7 @@
- (void)dealloc
{
[_coordinator removeViewFromRegistryWithTag:_tag];
[_paperView removeFromSuperview];
[_coordinator removeObserveForTag:_tag];
}
@@ -39,6 +40,7 @@
weakSelf.eventInterceptor(eventName, event);
}
}];
[_coordinator addViewToRegistry:_paperView withTag:_tag];
}
return _paperView;
}
@@ -50,7 +52,7 @@
- (void)handleCommand:(NSString *)commandName args:(NSArray *)args
{
[_coordinator handleCommand:commandName args:args reactTag:_tag];
[_coordinator handleCommand:commandName args:args reactTag:_tag paperView:self.paperView];
}
@end
@@ -9,6 +9,7 @@
#import <React/RCTAssert.h>
#import <React/RCTConversions.h>
#import <React/RCTLog.h>
#import <butter/map.h>
#import <butter/set.h>
@@ -105,16 +106,21 @@ static Class<RCTComponentViewProtocol> RCTComponentViewClassWithName(const char
return YES;
}
// Paper name: we prepare this variables to warn the user
// when the component is registered in both Fabric and in the
// interop layer, so they can remove that
NSString *componentNameString = RCTNSStringFromString(name);
BOOL isRegisteredInInteropLayer = [RCTLegacyViewManagerInteropComponentView isSupported:componentNameString];
// Fallback 1: Call provider function for component view class.
Class<RCTComponentViewProtocol> klass = RCTComponentViewClassWithName(name.c_str());
if (klass) {
[self registerComponentViewClass:klass];
[self registerComponentViewClass:klass andWarnIfNeeded:isRegisteredInInteropLayer];
return YES;
}
// Fallback 2: Try to use Paper Interop.
NSString *componentNameString = RCTNSStringFromString(name);
if ([RCTLegacyViewManagerInteropComponentView isSupported:componentNameString]) {
if (isRegisteredInInteropLayer) {
RCTLogNewArchitectureValidation(
RCTNotAllowedInBridgeless,
self,
@@ -203,4 +209,17 @@ static Class<RCTComponentViewProtocol> RCTComponentViewClassWithName(const char
return _providerRegistry.createComponentDescriptorRegistry(parameters);
}
#pragma mark - Private
- (void)registerComponentViewClass:(Class<RCTComponentViewProtocol>)componentViewClass
andWarnIfNeeded:(BOOL)isRegisteredInInteropLayer
{
[self registerComponentViewClass:componentViewClass];
if (isRegisteredInInteropLayer) {
RCTLogWarn(
@"Component with class %@ has been registered in both the New Architecture Renderer and in the Interop Layer.\nPlease remove it from the Interop Layer",
componentViewClass);
}
}
@end
@@ -285,6 +285,10 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
CoreFeatures::cacheNSTextStorage = true;
}
if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:cancel_image_downloads_on_recycle")) {
CoreFeatures::cancelImageDownloadsOnRecycle = true;
}
auto componentRegistryFactory =
[factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)](
EventDispatcher::Weak const &eventDispatcher, ContextContainer::Shared const &contextContainer) {
@@ -6,7 +6,6 @@
*/
#import <Foundation/Foundation.h>
#import <ReactCommon/RuntimeExecutor.h>
#import <UIKit/UIKit.h>
#import <react/utils/ContextContainer.h>
@@ -15,8 +14,6 @@ NS_ASSUME_NONNULL_BEGIN
@class RCTSurfacePresenter;
@class RCTBridge;
facebook::react::RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge);
/*
* Controls a life-cycle of a Surface Presenter based on Bridge's life-cycle.
* We are moving away from using Bridge.
@@ -15,6 +15,7 @@
#import <React/RCTConstants.h>
#import <React/RCTImageLoader.h>
#import <React/RCTImageLoaderWithAttributionProtocol.h>
#import <React/RCTRuntimeExecutorFromBridge.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterStub.h>
@@ -42,43 +43,6 @@ static ContextContainer::Shared RCTContextContainerFromBridge(RCTBridge *bridge)
return contextContainer;
}
RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge)
{
RCTAssert(bridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil.");
auto bridgeWeakWrapper = wrapManagedObjectWeakly([bridge batchedBridge] ?: bridge);
RuntimeExecutor runtimeExecutor = [bridgeWeakWrapper](
std::function<void(facebook::jsi::Runtime & runtime)> &&callback) {
RCTBridge *bridge = unwrapManagedObjectWeakly(bridgeWeakWrapper);
RCTAssert(bridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil at the moment of scheduling a call.");
[bridge invokeAsync:[bridgeWeakWrapper, callback = std::move(callback)]() {
RCTCxxBridge *batchedBridge = (RCTCxxBridge *)unwrapManagedObjectWeakly(bridgeWeakWrapper);
RCTAssert(batchedBridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil at the moment of invocation.");
if (!batchedBridge) {
return;
}
auto runtime = (facebook::jsi::Runtime *)(batchedBridge.runtime);
RCTAssert(
runtime, @"RCTRuntimeExecutorFromBridge: Bridge must have a valid jsi::Runtime at the moment of invocation.");
if (!runtime) {
return;
}
callback(*runtime);
}];
};
return runtimeExecutor;
}
@implementation RCTSurfacePresenterBridgeAdapter {
RCTSurfacePresenter *_Nullable _surfacePresenter;
__weak RCTBridge *_bridge;
@@ -29,7 +29,6 @@ header_search_paths = [
"\"$(PODS_ROOT)/Headers/Private/React-Core\"",
"\"$(PODS_ROOT)/Headers/Public/React-Codegen\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-Codegen/React_Codegen.framework/Headers\"",
]
if ENV['USE_FRAMEWORKS']
@@ -41,6 +40,9 @@ if ENV['USE_FRAMEWORKS']
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-ImageManager/React_ImageManager.framework/Headers\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-utils/React_utils.framework/Headers\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-runtimescheduler/React_runtimescheduler.framework/Headers\""
end
Pod::Spec.new do |s|
@@ -72,6 +74,17 @@ Pod::Spec.new do |s|
s.dependency "React-RCTImage", version
s.dependency "React-ImageManager"
s.dependency "RCT-Folly/Fabric", folly_version
s.dependency "glog"
s.dependency "Yoga"
s.dependency "React-RCTText"
s.dependency "React-utils"
s.dependency "React-runtimescheduler"
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
else
s.dependency "React-jsi"
end
s.test_spec 'Tests' do |test_spec|
test_spec.source_files = "Tests/**/*.{mm}"
@@ -469,7 +469,10 @@ android {
"-DREACT_BUILD_DIR=$buildDir",
"-DANDROID_STL=c++_shared",
"-DANDROID_TOOLCHAIN=clang",
"-DANDROID_PLATFORM=android-21"
"-DANDROID_PLATFORM=android-21",
// Due to https://github.com/android/ndk/issues/1693 we're losing Android
// specific compilation flags. This can be removed once we moved to NDK 25/26
"-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON"
targets "jsijniprofiler",
"reactnativeblob",
@@ -46,7 +46,20 @@ target_include_directories(${CMAKE_PROJECT_NAME}
${CMAKE_CURRENT_SOURCE_DIR}
${PROJECT_BUILD_DIR}/generated/rncli/src/main/jni)
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -Wall -Werror -fexceptions -frtti -std=c++17 -DWITH_INSPECTOR=1 -DLOG_TAG=\"ReactNative\")
target_compile_options(${CMAKE_PROJECT_NAME}
PRIVATE
-Wall
-Werror
# We suppress cpp #error and #warning to don't fail the build
# due to use migrating away from
# #include <react/renderer/graphics/conversions.h>
# This can be removed for React Native 0.73
-Wno-error=cpp
-fexceptions
-frtti
-std=c++17
-DWITH_INSPECTOR=1
-DLOG_TAG=\"ReactNative\")
# Prefab packages from React Native
find_package(ReactAndroid REQUIRED CONFIG)
@@ -1,4 +1,4 @@
VERSION_NAME=1000.0.0
VERSION_NAME=0.72.3
GROUP=com.facebook.react
# JVM Versions
@@ -154,6 +154,9 @@ android {
// We intentionally build Hermes with Intl support only. This is to simplify
// the build setup and to avoid overcomplicating the build-type matrix.
arguments "-DHERMES_ENABLE_INTL=True"
// Due to https://github.com/android/ndk/issues/1693 we're losing Android
// specific compilation flags. This can be removed once we moved to NDK 25/26
arguments "-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON"
targets "libhermes"
}
}
@@ -178,6 +181,8 @@ android {
// This has the (unlucky) side effect of letting AGP call the build
// tasks `configureCMakeRelease` while is actually building the debug flavor.
arguments "-DCMAKE_BUILD_TYPE=Release"
// Adding -O3 to patch the issue here: https://github.com/android/ndk/issues/1740#issuecomment-1198438260
cppFlags "-O3"
}
}
}
@@ -185,6 +190,8 @@ android {
externalNativeBuild {
cmake {
arguments "-DCMAKE_BUILD_TYPE=MinSizeRel"
// For release builds, we don't want to enable the Hermes Debugger.
arguments "-DHERMES_ENABLE_DEBUGGER=False"
}
}
}
@@ -11,6 +11,7 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.devsupport.DoubleTapReloadRecognizer;
@@ -33,6 +34,8 @@ public class ReactDelegate {
private ReactNativeHost mReactNativeHost;
private boolean mFabricEnabled = false;
public ReactDelegate(
Activity activity,
ReactNativeHost reactNativeHost,
@@ -45,6 +48,20 @@ public class ReactDelegate {
mReactNativeHost = reactNativeHost;
}
public ReactDelegate(
Activity activity,
ReactNativeHost reactNativeHost,
@Nullable String appKey,
@Nullable Bundle launchOptions,
boolean fabricEnabled) {
mActivity = activity;
mMainComponentName = appKey;
mLaunchOptions = composeLaunchOptions(launchOptions);
mDoubleTapReloadRecognizer = new DoubleTapReloadRecognizer();
mReactNativeHost = reactNativeHost;
mFabricEnabled = fabricEnabled;
}
public void onHostResume() {
if (getReactNativeHost().hasInstance()) {
if (mActivity instanceof DefaultHardwareBackBtnHandler) {
@@ -109,7 +126,9 @@ public class ReactDelegate {
}
protected ReactRootView createRootView() {
return new ReactRootView(mActivity);
ReactRootView reactRootView = new ReactRootView(mActivity);
reactRootView.setIsFabric(isFabricEnabled());
return reactRootView;
}
/**
@@ -144,4 +163,24 @@ public class ReactDelegate {
public ReactInstanceManager getReactInstanceManager() {
return getReactNativeHost().getReactInstanceManager();
}
/**
* 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.
*
* @return true if Fabric is enabled for this Activity, false otherwise.
*/
protected boolean isFabricEnabled() {
return mFabricEnabled;
}
private @NonNull Bundle composeLaunchOptions(Bundle composedLaunchOptions) {
if (isFabricEnabled()) {
if (composedLaunchOptions == null) {
composedLaunchOptions = new Bundle();
}
composedLaunchOptions.putBoolean("concurrentRoot", true);
}
return composedLaunchOptions;
}
}
@@ -16,6 +16,7 @@ import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.facebook.react.modules.core.PermissionAwareActivity;
@@ -29,6 +30,7 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
protected static final String ARG_COMPONENT_NAME = "arg_component_name";
protected static final String ARG_LAUNCH_OPTIONS = "arg_launch_options";
protected static final String ARG_FABRIC_ENABLED = "arg_fabric_enabled";
private ReactDelegate mReactDelegate;
@@ -40,13 +42,16 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
/**
* @param componentName The name of the react native component
* @param fabricEnabled Flag to enable Fabric for ReactFragment
* @return A new instance of fragment ReactFragment.
*/
private static ReactFragment newInstance(String componentName, Bundle launchOptions) {
private static ReactFragment newInstance(
String componentName, Bundle launchOptions, Boolean fabricEnabled) {
ReactFragment fragment = new ReactFragment();
Bundle args = new Bundle();
args.putString(ARG_COMPONENT_NAME, componentName);
args.putBundle(ARG_LAUNCH_OPTIONS, launchOptions);
args.putBoolean(ARG_FABRIC_ENABLED, fabricEnabled);
fragment.setArguments(args);
return fragment;
}
@@ -57,15 +62,18 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
super.onCreate(savedInstanceState);
String mainComponentName = null;
Bundle launchOptions = null;
Boolean fabricEnabled = null;
if (getArguments() != null) {
mainComponentName = getArguments().getString(ARG_COMPONENT_NAME);
launchOptions = getArguments().getBundle(ARG_LAUNCH_OPTIONS);
fabricEnabled = getArguments().getBoolean(ARG_FABRIC_ENABLED);
}
if (mainComponentName == null) {
throw new IllegalStateException("Cannot loadApp if component name is null");
}
mReactDelegate =
new ReactDelegate(getActivity(), getReactNativeHost(), mainComponentName, launchOptions);
new ReactDelegate(
getActivity(), getReactNativeHost(), mainComponentName, launchOptions, fabricEnabled);
}
/**
@@ -85,7 +93,7 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mReactDelegate.loadApp();
return mReactDelegate.getReactRootView();
}
@@ -140,7 +148,7 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
@Override
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (mPermissionListener != null
&& mPermissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
@@ -170,12 +178,14 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
/** Builder class to help instantiate a ReactFragment */
public static class Builder {
String mComponentName;
Bundle mLaunchOptions;
@Nullable String mComponentName;
@Nullable Bundle mLaunchOptions;
@Nullable Boolean mFabricEnabled;
public Builder() {
mComponentName = null;
mLaunchOptions = null;
mFabricEnabled = null;
}
/**
@@ -201,7 +211,12 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity {
}
public ReactFragment build() {
return ReactFragment.newInstance(mComponentName, mLaunchOptions);
return ReactFragment.newInstance(mComponentName, mLaunchOptions, mFabricEnabled);
}
public Builder setFabricEnabled(boolean fabricEnabled) {
mFabricEnabled = fabricEnabled;
return this;
}
}
}
@@ -1360,6 +1360,15 @@ public class ReactInstanceManager {
reactContext.initializeWithInstance(catalystInstance);
if (ReactFeatureFlags.unstable_useRuntimeSchedulerAlways) {
// On Old Architecture, we need to initialize the Native Runtime Scheduler so that
// the `nativeRuntimeScheduler` object is registered on JS.
// On New Architecture, this is normally triggered by instantiate a TurboModuleManager.
// Here we invoke getRuntimeScheduler() to trigger the creation of it regardless of the
// architecture so it will always be there.
catalystInstance.getRuntimeScheduler();
}
if (ReactFeatureFlags.useTurboModules && mTMMDelegateBuilder != null) {
TurboModuleManagerDelegate tmmDelegate =
mTMMDelegateBuilder
@@ -7,9 +7,12 @@
package com.facebook.react.animated;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.build.ReactBuildConfig;
/**
* Implementation of {@link AnimationDriver} which provides a support for simple time-based
@@ -70,7 +73,17 @@ class FrameBasedAnimationDriver extends AnimationDriver {
long timeFromStartMillis = (frameTimeNanos - mStartFrameTimeNanos) / 1000000;
int frameIndex = (int) Math.round(timeFromStartMillis / FRAME_TIME_MILLIS);
if (frameIndex < 0) {
throw new IllegalStateException("Calculated frame index should never be lower than 0");
String message =
"Calculated frame index should never be lower than 0. Called with frameTimeNanos "
+ frameTimeNanos
+ " and mStartFrameTimeNanos "
+ mStartFrameTimeNanos;
if (ReactBuildConfig.DEBUG) {
throw new IllegalStateException(message);
} else {
FLog.w(ReactConstants.TAG, message);
return;
}
} else if (mHasFinished) {
// nothing to do here
return;
@@ -295,6 +295,16 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
mCurrentFrameNumber++;
}
@Override
public void willMountItems(UIManager uiManager) {
// noop
}
@Override
public void didMountItems(UIManager uiManager) {
// noop
}
// For FabricUIManager only
@Override
@UiThread
@@ -21,6 +21,7 @@ import com.facebook.common.logging.FLog;
import com.facebook.infer.annotation.Assertions;
import com.facebook.infer.annotation.ThreadConfined;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.interop.InteropModuleRegistry;
import com.facebook.react.bridge.queue.MessageQueueThread;
import com.facebook.react.bridge.queue.ReactQueueConfiguration;
import com.facebook.react.common.LifecycleState;
@@ -69,6 +70,8 @@ public class ReactContext extends ContextWrapper {
private @Nullable JSExceptionHandler mJSExceptionHandler;
private @Nullable JSExceptionHandler mExceptionHandlerWrapper;
private @Nullable WeakReference<Activity> mCurrentActivity;
private @Nullable InteropModuleRegistry mInteropModuleRegistry;
private boolean mIsInitialized = false;
public ReactContext(Context base) {
@@ -93,6 +96,7 @@ public class ReactContext extends ContextWrapper {
ReactQueueConfiguration queueConfig = catalystInstance.getReactQueueConfiguration();
initializeMessageQueueThreads(queueConfig);
initializeInteropModules();
}
/** Initialize message queue threads using a ReactQueueConfiguration. */
@@ -120,6 +124,14 @@ public class ReactContext extends ContextWrapper {
mIsInitialized = true;
}
protected void initializeInteropModules() {
mInteropModuleRegistry = new InteropModuleRegistry();
}
protected void initializeInteropModules(ReactContext reactContext) {
mInteropModuleRegistry = reactContext.mInteropModuleRegistry;
}
public void resetPerfStats() {
if (mNativeModulesMessageQueueThread != null) {
mNativeModulesMessageQueueThread.resetPerfStats();
@@ -163,6 +175,10 @@ public class ReactContext extends ContextWrapper {
}
throw new IllegalStateException(EARLY_JS_ACCESS_EXCEPTION_MESSAGE);
}
if (mInteropModuleRegistry != null
&& mInteropModuleRegistry.shouldReturnInteropModule(jsInterface)) {
return mInteropModuleRegistry.getInteropModule(jsInterface);
}
return mCatalystInstance.getJSModule(jsInterface);
}
@@ -546,4 +562,17 @@ public class ReactContext extends ContextWrapper {
Assertions.assertNotNull(mCatalystInstance).registerSegment(segmentId, path);
Assertions.assertNotNull(callback).invoke();
}
/**
* Register a {@link JavaScriptModule} within the Interop Layer so that can be consumed whenever
* getJSModule is invoked.
*
* <p>This method is internal to React Native and should not be used externally.
*/
public <T extends JavaScriptModule> void internal_registerInteropModule(
Class<T> interopModuleInterface, Object interopModule) {
if (mInteropModuleRegistry != null) {
mInteropModuleRegistry.registerInteropModule(interopModuleInterface, interopModule);
}
}
}
@@ -12,10 +12,33 @@ public interface UIManagerListener {
/**
* Called right before view updates are dispatched at the end of a batch. This is useful if a
* module needs to add UIBlocks to the queue before it is flushed.
*
* <p>This is called by Paper only.
*/
void willDispatchViewUpdates(UIManager uiManager);
/* Called right after view updates are dispatched for a frame. */
/**
* Called on UIThread right before view updates are executed.
*
* <p>This is called by Fabric only.
*/
void willMountItems(UIManager uiManager);
/**
* Called on UIThread right after view updates are executed.
*
* <p>This is called by Fabric only.
*/
void didMountItems(UIManager uiManager);
/**
* Called on UIThread right after view updates are dispatched for a frame. Note that this will be
* called for every frame even if there are no updates.
*
* <p>This is called by Fabric only.
*/
void didDispatchMountItems(UIManager uiManager);
/* Called right after scheduleMountItems is called in Fabric, after a new tree is committed. */
/**
* Called right after scheduleMountItems is called in Fabric, after a new tree is committed.
*
* <p>This is called by Fabric only.
*/
void didScheduleMountItems(UIManager uiManager);
}
@@ -0,0 +1,56 @@
/*
* 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.bridge.interop;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.config.ReactFeatureFlags;
import java.util.HashMap;
/**
* A utility class that takes care of returning {@link JavaScriptModule} which are used for the
* Fabric Interop Layer. This allows us to override the returned classes once the user is invoking
* `ReactContext.getJsModule()`.
*
* <p>Currently we only support a `RCTEventEmitter` re-implementation, being `InteropEventEmitter`
* but this class can support other re-implementation in the future.
*/
public class InteropModuleRegistry {
@SuppressWarnings("rawtypes")
private final HashMap<Class, Object> supportedModules;
public InteropModuleRegistry() {
this.supportedModules = new HashMap<>();
}
public <T extends JavaScriptModule> boolean shouldReturnInteropModule(Class<T> requestedModule) {
return checkReactFeatureFlagsConditions() && supportedModules.containsKey(requestedModule);
}
@Nullable
public <T extends JavaScriptModule> T getInteropModule(Class<T> requestedModule) {
if (checkReactFeatureFlagsConditions()) {
//noinspection unchecked
return (T) supportedModules.get(requestedModule);
} else {
return null;
}
}
public <T extends JavaScriptModule> void registerInteropModule(
Class<T> interopModuleInterface, Object interopModule) {
if (checkReactFeatureFlagsConditions()) {
supportedModules.put(interopModuleInterface, interopModule);
}
}
private boolean checkReactFeatureFlagsConditions() {
return ReactFeatureFlags.enableFabricRenderer && ReactFeatureFlags.unstable_useFabricInterop;
}
}
@@ -34,6 +34,21 @@ public class ReactFeatureFlags {
*/
public static volatile boolean enableFabricRenderer = false;
/**
* Should this application enable the Fabric Interop Layer for Android? If yes, the application
* will behave so that it can accept non-Fabric components and render them on Fabric. This toggle
* is controlling extra logic such as custom event dispatching that are needed for the Fabric
* Interop Layer to work correctly.
*/
public static volatile boolean unstable_useFabricInterop = false;
/**
* Should this application always use the Native RuntimeScheduler? If yes, we'll be instantiating
* it over all the architectures (both Old and New). This is intentionally set to true as we want
* to use it more as a kill-switch to turn off this feature to potentially debug issues.
*/
public static volatile boolean unstable_useRuntimeSchedulerAlways = true;
/**
* Feature flag to enable the new bridgeless architecture. Note: Enabling this will force enable
* the following flags: `useTurboModules` & `enableFabricRenderer`.
@@ -75,6 +90,9 @@ public class ReactFeatureFlags {
/** Feature Flag to enable the pending event queue in fabric before mounting views */
public static boolean enableFabricPendingEventQueue = false;
/** Feature Flag to enable caching mechanism of text measurement at shadow node level */
public static boolean enableTextMeasureCachePerShadowNode = false;
/**
* Feature flag that controls how turbo modules are exposed to JS
*
@@ -31,6 +31,7 @@ object DefaultNewArchitectureEntryPoint {
) {
ReactFeatureFlags.useTurboModules = turboModulesEnabled
ReactFeatureFlags.enableFabricRenderer = fabricEnabled
ReactFeatureFlags.unstable_useFabricInterop = fabricEnabled
this.privateFabricEnabled = fabricEnabled
this.privateTurboModulesEnabled = turboModulesEnabled
@@ -7,6 +7,7 @@
package com.facebook.react.defaults
import android.os.Bundle
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.ReactRootView
@@ -43,4 +44,7 @@ open class DefaultReactActivityDelegate(
override fun createRootView(): ReactRootView =
ReactRootView(context).apply { setIsFabric(fabricEnabled) }
override fun createRootView(bundle: Bundle?): ReactRootView =
ReactRootView(context).apply { setIsFabric(fabricEnabled) }
}
@@ -24,6 +24,7 @@ import android.util.Pair;
import android.view.Gravity;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
@@ -553,17 +554,30 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
return;
}
final TextView textView = new TextView(getApplicationContext());
textView.setText("React Native DevMenu (" + getUniqueTag() + ")");
textView.setPadding(0, 50, 0, 0);
textView.setGravity(Gravity.CENTER);
textView.setTextColor(Color.BLACK);
textView.setTextSize(17);
textView.setTypeface(textView.getTypeface(), Typeface.BOLD);
final LinearLayout header = new LinearLayout(getApplicationContext());
header.setOrientation(LinearLayout.VERTICAL);
final TextView title = new TextView(getApplicationContext());
title.setText("React Native Dev Menu (" + getUniqueTag() + ")");
title.setPadding(0, 50, 0, 0);
title.setGravity(Gravity.CENTER);
title.setTextColor(Color.DKGRAY);
title.setTextSize(16);
title.setTypeface(title.getTypeface(), Typeface.BOLD);
final TextView jsExecutorLabel = new TextView(getApplicationContext());
jsExecutorLabel.setText(getJSExecutorDescription());
jsExecutorLabel.setPadding(0, 20, 0, 0);
jsExecutorLabel.setGravity(Gravity.CENTER);
jsExecutorLabel.setTextColor(Color.GRAY);
jsExecutorLabel.setTextSize(14);
header.addView(title);
header.addView(jsExecutorLabel);
mDevOptionsDialog =
new AlertDialog.Builder(context)
.setCustomTitle(textView)
.setCustomTitle(header)
.setItems(
options.keySet().toArray(new String[0]),
new DialogInterface.OnClickListener() {
@@ -587,6 +601,10 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
}
}
private String getJSExecutorDescription() {
return "Running " + getReactInstanceDevHelper().getJavaScriptExecutorFactory().toString();
}
/**
* {@link ReactInstanceDevCommandsHandler} is responsible for enabling/disabling dev support when
* a React view is attached/detached or when application state changes (e.g. the application is
@@ -56,6 +56,7 @@ import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.fabric.events.EventBeatManager;
import com.facebook.react.fabric.events.EventEmitterWrapper;
import com.facebook.react.fabric.events.FabricEventEmitter;
import com.facebook.react.fabric.interop.InteropEventEmitter;
import com.facebook.react.fabric.mounting.MountItemDispatcher;
import com.facebook.react.fabric.mounting.MountingManager;
import com.facebook.react.fabric.mounting.SurfaceMountingManager;
@@ -81,6 +82,7 @@ import com.facebook.react.uimanager.ViewManagerRegistry;
import com.facebook.react.uimanager.events.EventCategoryDef;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.uimanager.events.EventDispatcherImpl;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.facebook.react.views.text.TextLayoutManager;
import com.facebook.react.views.text.TextLayoutManagerMapBuffer;
import java.util.HashMap;
@@ -390,6 +392,11 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
ReactMarker.addFabricListener(mDevToolsReactPerfLogger);
}
if (ReactFeatureFlags.unstable_useFabricInterop) {
InteropEventEmitter interopEventEmitter = new InteropEventEmitter(mReactApplicationContext);
mReactApplicationContext.internal_registerInteropModule(
RCTEventEmitter.class, interopEventEmitter);
}
}
// This is called on the JS thread (see CatalystInstanceImpl).
@@ -1171,6 +1178,20 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
}
private class MountItemDispatchListener implements MountItemDispatcher.ItemDispatchListener {
@Override
public void willMountItems() {
for (UIManagerListener listener : mListeners) {
listener.willMountItems(FabricUIManager.this);
}
}
@Override
public void didMountItems() {
for (UIManagerListener listener : mListeners) {
listener.didMountItems(FabricUIManager.this);
}
}
@Override
public void didDispatchMountItems() {
for (UIManagerListener listener : mListeners) {
@@ -0,0 +1,41 @@
/*
* 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.fabric.interop;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.uimanager.events.Event;
/**
* An {@link Event} class used by the {@link InteropEventEmitter}. This class is just holding the
* event name and the data which is received by the `receiveEvent` method and will be passed over
* the the {@link com.facebook.react.uimanager.events.EventDispatcher}
*/
class InteropEvent extends Event<InteropEvent> {
private final String mName;
private final WritableMap mEventData;
InteropEvent(String name, @Nullable WritableMap eventData, int surfaceId, int viewTag) {
super(surfaceId, viewTag);
mName = name;
mEventData = eventData;
}
@Override
public String getEventName() {
return mName;
}
@Override
@VisibleForTesting
public WritableMap getEventData() {
return mEventData;
}
}
@@ -0,0 +1,65 @@
/*
* 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.fabric.interop;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.uimanager.events.RCTEventEmitter;
/**
* A reimplementation of {@link RCTEventEmitter} which is using a {@link EventDispatcher} under the
* hood.
*
* <p>On Fabric, you're supposed to use {@link EventDispatcher} to dispatch events. However, we
* provide an interop layer for non-Fabric migrated components.
*
* <p>This instance will be returned if the user is invoking `context.getJsModule(RCTEventEmitter)
* and is providing support for the `receiveEvent` method, so that non-Fabric ViewManagers can
* continue to deliver events also when Fabric is turned on.
*/
public class InteropEventEmitter implements RCTEventEmitter {
private final ReactContext mReactContext;
private @Nullable EventDispatcher mEventDispatcherOverride;
public InteropEventEmitter(ReactContext reactContext) {
mReactContext = reactContext;
}
@Override
public void receiveEvent(int targetReactTag, String eventName, @Nullable WritableMap eventData) {
EventDispatcher dispatcher;
if (mEventDispatcherOverride != null) {
dispatcher = mEventDispatcherOverride;
} else {
dispatcher = UIManagerHelper.getEventDispatcherForReactTag(mReactContext, targetReactTag);
}
int surfaceId = UIManagerHelper.getSurfaceId(mReactContext);
if (dispatcher != null) {
dispatcher.dispatchEvent(new InteropEvent(eventName, eventData, surfaceId, targetReactTag));
}
}
@Override
public void receiveTouches(
String eventName, WritableArray touches, WritableArray changedIndices) {
throw new UnsupportedOperationException(
"EventEmitter#receiveTouches is not supported by the Fabric Interop Layer");
}
@VisibleForTesting
void overrideEventDispatcher(EventDispatcher eventDispatcherOverride) {
mEventDispatcherOverride = eventDispatcherOverride;
}
}
@@ -193,6 +193,8 @@ public class MountItemDispatcher {
return false;
}
mItemDispatchListener.willMountItems();
// As an optimization, execute all ViewCommands first
// This should be:
// 1) Performant: ViewCommands are often a replacement for SetNativeProps, which we've always
@@ -299,6 +301,9 @@ public class MountItemDispatcher {
}
mBatchedExecutionTime += SystemClock.uptimeMillis() - batchedExecutionStartTime;
}
mItemDispatchListener.didMountItems();
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
return true;
@@ -415,6 +420,10 @@ public class MountItemDispatcher {
}
public interface ItemDispatchListener {
void willMountItems();
void didMountItems();
void didDispatchMountItems();
}
}
@@ -29,7 +29,6 @@ import java.nio.channels.ReadableByteChannel;
import java.util.zip.GZIPOutputStream;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.internal.Util;
import okio.BufferedSink;
import okio.ByteString;
import okio.Okio;
@@ -122,6 +121,21 @@ import okio.Source;
return RequestBody.create(mediaType, gzipByteArrayOutputStream.toByteArray());
}
/**
* Reference:
* https://github.com/square/okhttp/blob/8c8c3dbcfa91e28de2e13975ec414e07f153fde4/okhttp/src/commonMain/kotlin/okhttp3/internal/-UtilCommon.kt#L281-L288
* Checked exceptions will be ignored
*/
private static void closeQuietly(Source source) {
try {
source.close();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
// noop.
}
}
/** Creates a RequestBody from a mediaType and inputStream given. */
public static RequestBody create(final MediaType mediaType, final InputStream inputStream) {
return new RequestBody() {
@@ -146,7 +160,7 @@ import okio.Source;
source = Okio.source(inputStream);
sink.writeAll(source);
} finally {
Util.closeQuietly(source);
closeQuietly(source);
}
}
};
@@ -15,8 +15,8 @@ import java.util.Map;
public class ReactNativeVersion {
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
"major", 1000,
"minor", 0,
"patch", 0,
"major", 0,
"minor", 72,
"patch", 3,
"prerelease", null);
}
@@ -50,6 +50,7 @@ public class ThemedReactContext extends ReactContext {
if (reactApplicationContext.hasCatalystInstance()) {
initializeWithInstance(reactApplicationContext.getCatalystInstance());
}
initializeInteropModules(reactApplicationContext);
mReactApplicationContext = reactApplicationContext;
mModuleName = moduleName;
mSurfaceId = surfaceId;
@@ -10,11 +10,15 @@ package com.facebook.react.uimanager;
import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.systrace.SystraceMessage;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Helps generate constants map for {@link UIManagerModule} by collecting and merging constants from
@@ -113,6 +117,13 @@ import java.util.Map;
Map viewManagerBubblingEvents = viewManager.getExportedCustomBubblingEventTypeConstants();
if (viewManagerBubblingEvents != null) {
if (ReactFeatureFlags.enableFabricRenderer && ReactFeatureFlags.unstable_useFabricInterop) {
// For Fabric, events needs to be fired with a "top" prefix.
// For the sake of Fabric Interop, here we normalize events adding "top" in their
// name if the user hasn't provided it.
normalizeEventTypes(viewManagerBubblingEvents);
}
recursiveMerge(cumulativeBubblingEventTypes, viewManagerBubblingEvents);
recursiveMerge(viewManagerBubblingEvents, defaultBubblingEvents);
viewManagerConstants.put(BUBBLING_EVENTS_KEY, viewManagerBubblingEvents);
@@ -145,6 +156,27 @@ import java.util.Map;
return viewManagerConstants;
}
@VisibleForTesting
/* package */ static void normalizeEventTypes(Map events) {
if (events == null) {
return;
}
Set<String> keysToNormalize = new HashSet<>();
for (Object key : events.keySet()) {
if (key instanceof String) {
String keyString = (String) key;
if (!keyString.startsWith("top")) {
keysToNormalize.add(keyString);
}
}
}
for (String oldKey : keysToNormalize) {
Object value = events.get(oldKey);
String newKey = "top" + oldKey.substring(0, 1).toUpperCase() + oldKey.substring(1);
events.put(newKey, value);
}
}
/** Merges {@param source} map into {@param dest} map recursively */
private static void recursiveMerge(@Nullable Map dest, @Nullable Map source) {
if (dest == null || source == null || source.isEmpty()) {
@@ -18,6 +18,7 @@ import com.facebook.react.bridge.UIManager;
import com.facebook.react.bridge.UIManagerListener;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.common.UIManagerType;
import com.facebook.react.uimanager.common.ViewUtil;
import com.facebook.react.views.scroll.ReactScrollViewHelper.HasSmoothScroll;
import com.facebook.react.views.view.ReactViewGroup;
@@ -89,6 +90,14 @@ public class MaintainVisibleScrollPositionHelper<ScrollViewT extends ViewGroup &
* been updated.
*/
public void updateScrollPosition() {
// On Fabric this will be called internally in `didMountItems`.
if (ViewUtil.getUIManagerType(mScrollView.getId()) == UIManagerType.FABRIC) {
return;
}
updateScrollPositionInternal();
}
private void updateScrollPositionInternal() {
if (mConfig == null || mFirstVisibleView == null || mPrevFirstVisibleFrame == null) {
return;
}
@@ -169,6 +178,16 @@ public class MaintainVisibleScrollPositionHelper<ScrollViewT extends ViewGroup &
});
}
@Override
public void willMountItems(UIManager uiManager) {
computeTargetView();
}
@Override
public void didMountItems(UIManager uiManager) {
updateScrollPositionInternal();
}
@Override
public void didDispatchMountItems(UIManager uiManager) {
// noop
@@ -37,6 +37,10 @@ public class CustomLetterSpacingSpan extends MetricAffectingSpan implements Reac
apply(paint);
}
public float getSpacing() {
return mLetterSpacing;
}
private void apply(TextPaint paint) {
if (!Float.isNaN(mLetterSpacing)) {
paint.setLetterSpacing(mLetterSpacing);
@@ -71,6 +71,10 @@ public class CustomStyleSpan extends MetricAffectingSpan implements ReactSpan {
return mFontFamily;
}
public @Nullable String getFontFeatureSettings() {
return mFeatureSettings;
}
private static void apply(
Paint paint,
int style,
@@ -42,12 +42,14 @@ public class FontMetricsUtil {
X_HEIGHT_MEASUREMENT_TEXT, 0, X_HEIGHT_MEASUREMENT_TEXT.length(), xHeightBounds);
double xHeight = xHeightBounds.height() / AMPLIFICATION_FACTOR / dm.density;
for (int i = 0; i < layout.getLineCount(); i++) {
boolean endsWithNewLine = text.length() > 0 && text.charAt(layout.getLineEnd(i) - 1) == '\n';
float lineWidth = endsWithNewLine ? layout.getLineMax(i) : layout.getLineWidth(i);
Rect bounds = new Rect();
layout.getLineBounds(i, bounds);
WritableMap line = Arguments.createMap();
line.putDouble("x", layout.getLineLeft(i) / dm.density);
line.putDouble("y", bounds.top / dm.density);
line.putDouble("width", layout.getLineWidth(i) / dm.density);
line.putDouble("width", lineWidth / dm.density);
line.putDouble("height", bounds.height() / dm.density);
line.putDouble("descender", layout.getLineDescent(i) / dm.density);
line.putDouble("ascender", -layout.getLineAscent(i) / dm.density);
@@ -69,31 +69,6 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode {
protected @Nullable ReactTextViewManagerCallback mReactTextViewManagerCallback;
private static class SetSpanOperation {
protected int start, end;
protected ReactSpan what;
SetSpanOperation(int start, int end, ReactSpan what) {
this.start = start;
this.end = end;
this.what = what;
}
public void execute(SpannableStringBuilder sb, int priority) {
// All spans will automatically extend to the right of the text, but not the left - except
// for spans that start at the beginning of the text.
int spanFlags = Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
if (start == 0) {
spanFlags = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
}
spanFlags &= ~Spannable.SPAN_PRIORITY;
spanFlags |= (priority << Spannable.SPAN_PRIORITY_SHIFT) & Spannable.SPAN_PRIORITY;
sb.setSpan(what, start, end, spanFlags);
}
}
private static void buildSpannedFromShadowNode(
ReactBaseTextShadowNode textShadowNode,
SpannableStringBuilder sb,
@@ -276,8 +251,9 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode {
// While setting the Spans on the final text, we also check whether any of them are inline views
// or images.
int priority = 0;
for (SetSpanOperation op : ops) {
for (int priorityIndex = 0; priorityIndex < ops.size(); priorityIndex++) {
final SetSpanOperation op = ops.get(ops.size() - priorityIndex - 1);
boolean isInlineImage = op.what instanceof TextInlineImageSpan;
if (isInlineImage || op.what instanceof TextInlineViewPlaceholderSpan) {
int height;
@@ -304,9 +280,8 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode {
}
// Actual order of calling {@code execute} does NOT matter,
// but the {@code priority} DOES matter.
op.execute(sb, priority);
priority++;
// but the {@code priorityIndex} DOES matter.
op.execute(sb, priorityIndex);
}
textShadowNode.mTextAttributes.setHeightOfTallestInlineViewOrImage(
@@ -135,7 +135,10 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode {
layoutWidth = width;
} else {
for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) {
float lineWidth = layout.getLineWidth(lineIndex);
boolean endsWithNewLine =
text.length() > 0 && text.charAt(layout.getLineEnd(lineIndex) - 1) == '\n';
float lineWidth =
endsWithNewLine ? layout.getLineMax(lineIndex) : layout.getLineWidth(lineIndex);
if (lineWidth > layoutWidth) {
layoutWidth = lineWidth;
}
@@ -27,12 +27,8 @@ public class ReactTextUpdate {
private final float mPaddingBottom;
private final int mTextAlign;
private final int mTextBreakStrategy;
private final int mSelectionStart;
private final int mSelectionEnd;
private final int mJustificationMode;
public boolean mContainsMultipleFragments;
/**
* @deprecated Use a non-deprecated constructor for ReactTextUpdate instead. This one remains
* because it's being used by a unit test that isn't currently open source.
@@ -57,35 +53,7 @@ public class ReactTextUpdate {
paddingBottom,
textAlign,
Layout.BREAK_STRATEGY_HIGH_QUALITY,
Layout.JUSTIFICATION_MODE_NONE,
-1,
-1);
}
public ReactTextUpdate(
Spannable text,
int jsEventCounter,
boolean containsImages,
float paddingStart,
float paddingTop,
float paddingEnd,
float paddingBottom,
int textAlign,
int textBreakStrategy,
int justificationMode) {
this(
text,
jsEventCounter,
containsImages,
paddingStart,
paddingTop,
paddingEnd,
paddingBottom,
textAlign,
textBreakStrategy,
justificationMode,
-1,
-1);
Layout.JUSTIFICATION_MODE_NONE);
}
public ReactTextUpdate(
@@ -105,9 +73,7 @@ public class ReactTextUpdate {
UNSET,
textAlign,
textBreakStrategy,
justificationMode,
-1,
-1);
justificationMode);
}
public ReactTextUpdate(
@@ -120,9 +86,7 @@ public class ReactTextUpdate {
float paddingBottom,
int textAlign,
int textBreakStrategy,
int justificationMode,
int selectionStart,
int selectionEnd) {
int justificationMode) {
mText = text;
mJsEventCounter = jsEventCounter;
mContainsImages = containsImages;
@@ -132,8 +96,6 @@ public class ReactTextUpdate {
mPaddingBottom = paddingBottom;
mTextAlign = textAlign;
mTextBreakStrategy = textBreakStrategy;
mSelectionStart = selectionStart;
mSelectionEnd = selectionEnd;
mJustificationMode = justificationMode;
}
@@ -142,13 +104,11 @@ public class ReactTextUpdate {
int jsEventCounter,
int textAlign,
int textBreakStrategy,
int justificationMode,
boolean containsMultipleFragments) {
int justificationMode) {
ReactTextUpdate reactTextUpdate =
new ReactTextUpdate(
text, jsEventCounter, false, textAlign, textBreakStrategy, justificationMode);
reactTextUpdate.mContainsMultipleFragments = containsMultipleFragments;
return reactTextUpdate;
}
@@ -191,12 +151,4 @@ public class ReactTextUpdate {
public int getJustificationMode() {
return mJustificationMode;
}
public int getSelectionStart() {
return mSelectionStart;
}
public int getSelectionEnd() {
return mSelectionEnd;
}
}
@@ -264,11 +264,14 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
// the last offset in the layout will result in an endless loop. Work around
// this bug by avoiding getPrimaryHorizontal in that case.
if (start == text.length() - 1) {
boolean endsWithNewLine =
text.length() > 0 && text.charAt(layout.getLineEnd(line) - 1) == '\n';
float lineWidth = endsWithNewLine ? layout.getLineMax(line) : layout.getLineWidth(line);
placeholderHorizontalPosition =
isRtlParagraph
// Equivalent to `layout.getLineLeft(line)` but `getLineLeft` returns incorrect
// values when the paragraph is RTL and `setSingleLine(true)`.
? textViewWidth - (int) layout.getLineWidth(line)
? textViewWidth - (int) lineWidth
: (int) layout.getLineRight(line) - width;
} else {
// The direction of the paragraph may not be exactly the direction the string is heading
@@ -0,0 +1,52 @@
package com.facebook.react.views.text;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import com.facebook.common.logging.FLog;
class SetSpanOperation {
private static final String TAG = "SetSpanOperation";
static final int SPAN_MAX_PRIORITY = Spanned.SPAN_PRIORITY >> Spanned.SPAN_PRIORITY_SHIFT;
protected int start, end;
protected ReactSpan what;
SetSpanOperation(int start, int end, ReactSpan what) {
this.start = start;
this.end = end;
this.what = what;
}
/**
* @param sb builder
* @param priorityIndex index of this operation in the topological sorting which puts operations
* with higher priority before operations with lower priority.
*/
public void execute(SpannableStringBuilder sb, int priorityIndex) {
assert priorityIndex >= 0;
// All spans will automatically extend to the right of the text, but not the left - except
// for spans that start at the beginning of the text.
int spanFlags = Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
if (start == 0) {
spanFlags = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
}
// Calculate priority, assigning the highest values to operations with the highest priority
final int priority = SPAN_MAX_PRIORITY - priorityIndex;
if (priority < 0) {
FLog.w(TAG, "Text tree size exceeded the limit, styling may become unpredictable");
}
// If the computed priority doesn't fit in the flags, clamp it. The effect might not be correct
// in 100% of cases, but doing nothing (as we did in the past) leads to totally random results.
final int effectivePriority = Math.max(priority, 0);
spanFlags &= ~Spannable.SPAN_PRIORITY;
spanFlags |= (effectivePriority << Spannable.SPAN_PRIORITY_SHIFT) & Spannable.SPAN_PRIORITY;
sb.setSpan(what, start, end, spanFlags);
}
}
@@ -213,12 +213,12 @@ public class TextLayoutManager {
// TODO T31905686: add support for inline Images
// While setting the Spans on the final text, we also check whether any of them are images.
int priority = 0;
for (SetSpanOperation op : ops) {
for (int priorityIndex = 0; priorityIndex < ops.size(); ++priorityIndex) {
final SetSpanOperation op = ops.get(ops.size() - priorityIndex - 1);
// Actual order of calling {@code execute} does NOT matter,
// but the {@code priority} DOES matter.
op.execute(sb, priority);
priority++;
// but the {@code priorityIndex} DOES matter.
op.execute(sb, priorityIndex);
}
if (reactTextViewManagerCallback != null) {
@@ -397,7 +397,10 @@ public class TextLayoutManager {
calculatedWidth = width;
} else {
for (int lineIndex = 0; lineIndex < calculatedLineCount; lineIndex++) {
float lineWidth = layout.getLineWidth(lineIndex);
boolean endsWithNewLine =
text.length() > 0 && text.charAt(layout.getLineEnd(lineIndex) - 1) == '\n';
float lineWidth =
endsWithNewLine ? layout.getLineMax(lineIndex) : layout.getLineWidth(lineIndex);
if (lineWidth > calculatedWidth) {
calculatedWidth = lineWidth;
}
@@ -452,11 +455,14 @@ public class TextLayoutManager {
// the last offset in the layout will result in an endless loop. Work around
// this bug by avoiding getPrimaryHorizontal in that case.
if (start == text.length() - 1) {
boolean endsWithNewLine =
text.length() > 0 && text.charAt(layout.getLineEnd(line) - 1) == '\n';
float lineWidth = endsWithNewLine ? layout.getLineMax(line) : layout.getLineWidth(line);
placeholderLeftPosition =
isRtlParagraph
// Equivalent to `layout.getLineLeft(line)` but `getLineLeft` returns incorrect
// values when the paragraph is RTL and `setSingleLine(true)`.
? calculatedWidth - layout.getLineWidth(line)
? calculatedWidth - lineWidth
: layout.getLineRight(line) - placeholderWidth;
} else {
// The direction of the paragraph may not be exactly the direction the string is heading
@@ -551,30 +557,4 @@ public class TextLayoutManager {
hyphenationFrequency);
return FontMetricsUtil.getFontMetrics(text, layout, sTextPaintInstance, context);
}
// TODO T31905686: This class should be private
public static class SetSpanOperation {
protected int start, end;
protected ReactSpan what;
public SetSpanOperation(int start, int end, ReactSpan what) {
this.start = start;
this.end = end;
this.what = what;
}
public void execute(Spannable sb, int priority) {
// All spans will automatically extend to the right of the text, but not the left - except
// for spans that start at the beginning of the text.
int spanFlags = Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
if (start == 0) {
spanFlags = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
}
spanFlags &= ~Spannable.SPAN_PRIORITY;
spanFlags |= (priority << Spannable.SPAN_PRIORITY_SHIFT) & Spannable.SPAN_PRIORITY;
sb.setSpan(what, start, end, spanFlags);
}
}
}
@@ -227,12 +227,12 @@ public class TextLayoutManagerMapBuffer {
// TODO T31905686: add support for inline Images
// While setting the Spans on the final text, we also check whether any of them are images.
int priority = 0;
for (SetSpanOperation op : ops) {
for (int priorityIndex = 0; priorityIndex < ops.size(); ++priorityIndex) {
final SetSpanOperation op = ops.get(ops.size() - priorityIndex - 1);
// Actual order of calling {@code execute} does NOT matter,
// but the {@code priority} DOES matter.
op.execute(sb, priority);
priority++;
// but the {@code priorityIndex} DOES matter.
op.execute(sb, priorityIndex);
}
if (reactTextViewManagerCallback != null) {
@@ -411,7 +411,10 @@ public class TextLayoutManagerMapBuffer {
calculatedWidth = width;
} else {
for (int lineIndex = 0; lineIndex < calculatedLineCount; lineIndex++) {
float lineWidth = layout.getLineWidth(lineIndex);
boolean endsWithNewLine =
text.length() > 0 && text.charAt(layout.getLineEnd(lineIndex) - 1) == '\n';
float lineWidth =
endsWithNewLine ? layout.getLineMax(lineIndex) : layout.getLineWidth(lineIndex);
if (lineWidth > calculatedWidth) {
calculatedWidth = lineWidth;
}
@@ -466,12 +469,15 @@ public class TextLayoutManagerMapBuffer {
// the last offset in the layout will result in an endless loop. Work around
// this bug by avoiding getPrimaryHorizontal in that case.
if (start == text.length() - 1) {
boolean endsWithNewLine =
text.length() > 0 && text.charAt(layout.getLineEnd(line) - 1) == '\n';
float lineWidth = endsWithNewLine ? layout.getLineMax(line) : layout.getLineWidth(line);
placeholderLeftPosition =
isRtlParagraph
// Equivalent to `layout.getLineLeft(line)` but `getLineLeft` returns
// incorrect
// values when the paragraph is RTL and `setSingleLine(true)`.
? calculatedWidth - layout.getLineWidth(line)
? calculatedWidth - lineWidth
: layout.getLineRight(line) - placeholderWidth;
} else {
// The direction of the paragraph may not be exactly the direction the string is
@@ -570,30 +576,4 @@ public class TextLayoutManagerMapBuffer {
hyphenationFrequency);
return FontMetricsUtil.getFontMetrics(text, layout, sTextPaintInstance, context);
}
// TODO T31905686: This class should be private
public static class SetSpanOperation {
protected int start, end;
protected ReactSpan what;
public SetSpanOperation(int start, int end, ReactSpan what) {
this.start = start;
this.end = end;
this.what = what;
}
public void execute(Spannable sb, int priority) {
// All spans will automatically extend to the right of the text, but not the left - except
// for spans that start at the beginning of the text.
int spanFlags = Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
if (start == 0) {
spanFlags = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
}
spanFlags &= ~Spannable.SPAN_PRIORITY;
spanFlags |= (priority << Spannable.SPAN_PRIORITY_SHIFT) & Spannable.SPAN_PRIORITY;
sb.setSpan(what, start, end, spanFlags);
}
}
}

Some files were not shown because too many files have changed in this diff Show More