Compare commits

...
Author SHA1 Message Date
Yedidya Feldblum 0bacd9ceed let Value be nothrow-move-constructible (#47422)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47422

Reviewed By: Gownta

Differential Revision: D65273055
2024-11-07 22:16:56 -08:00
Joe Vilches cbab004eb9 Remove position type override on scroll view sticky headers (#47498)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47498

I am trying to help someone with creating a sticky header on a scrollview, specifically one that floats on the side of the scrollview instead of the top Currently we can't really do that, since utilizing `position: absolute` to layout this properly will get overriden by the header styles changed in this diff

This was only added since static was the default and we needed to apply zIndex. With proper static implementation that is no longer the case, so I think it makes sense to remove this to support this use case.

Changelog: [General] [Breaking] - `position` of sticky headers on `ScrollView` will now be taken into account

Reviewed By: rozele

Differential Revision: D65626544

fbshipit-source-id: 8d650ca7654918e692435935e7c1094c412fd9f6
2024-11-07 16:34:31 -08:00
Arushi Kesarwani 846c4b1ea2 Reducing visibility of ImageStoreManager (#47443)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47443

As part of sustainability week effort for switching to internal here:

https://fb.workplace.com/groups/251759413609061/permalink/872342228217440/

Reducing visibility of ImageStoreManager from public to internal

Changelog:
[Android] [Breaking] - Stable API - Make ImageStoreManager internal

Reviewed By: javache

Differential Revision: D65520953

fbshipit-source-id: 0207be6a5e0b92dbbaee534735fc829e9202727d
2024-11-07 15:32:43 -08:00
Thomas Nardone d02da992a4 Convert + Internalize SwipeRefreshLayoutManager (#47470)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47470

Convert to Kotlin and formalize it being an internal class (some methods were already `protected` in Java)

Changelog:
[Android] [Breaking] - Stable API - Make SwipeRefreshLayoutManager internal

Reviewed By: cortinico

Differential Revision: D65481861

fbshipit-source-id: afc5c624373fbcd3ca2d28b2834d2682de672997
2024-11-07 11:39:35 -08:00
Ramanpreet Nara 8b053a4fca Implement always available js error handling (#47466)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47466

Now, when the useAlwaysAvailableJSErrorHandling feature flag is true, React Native will use the earlyjs c++ error reporting pipeline for handling all javascript errors!

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D64715159

fbshipit-source-id: 597a5278eb792f87dca10e06fa9816b3a8c47b84
2024-11-07 11:22:57 -08:00
Fabrizio Cucci 791afd3209 Migrate com.facebook.react.views.text.ReactFontManager to Kotlin (#47488)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47488

As per title.

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D65594248

fbshipit-source-id: 5a21baefb768b1c6f8ec0c33158812d1de6113d5
2024-11-07 10:23:27 -08:00
Pieter De Baets bcdf6ad1af Convert com.facebook.react.bridge.JavaOnlyMap to Kotlin (#47479)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47479

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D65595979

fbshipit-source-id: be8217ef1fd9f59af57a1e100a4d9e86b66d8027
2024-11-07 10:16:21 -08:00
Tim Yung bf31c8f077 RN: Feature Flag to Disable InteractionManager (#47475)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47475

Creates a feature flag to evalute the impact of disabling `InteractionManager` and replacing its scheduling behavior with `setImmediate`.

Changelog:
[Internal]

Reviewed By: javache

Differential Revision: D65577455

fbshipit-source-id: c0dc2b4d062eff4929ef37c5e217fd194addd790
2024-11-07 09:29:44 -08:00
Riccardo Cipolleschi 0ee963ea65 Cleanup after Codegen refactoring (#47483)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47483

I relaized too late that there were a couple of comments on [#47458](https://github.com/facebook/react-native/pull/47458) to add some explanation/remove commented code.

This change applies those comments

## Changelog
[Internal] - Cleanup after landing [#47458](https://github.com/facebook/react-native/pull/47458)

Reviewed By: dmytrorykun

Differential Revision: D65597157

fbshipit-source-id: 238bb75e4b45efae9a8736a7b4feb10f5af5e3d9
2024-11-07 07:53:07 -08:00
Peter Abbondanzo 425093863c Log image load errors (#47419)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47419

Minor improvements to `ImageExample` so we log when images fail to load. Also replaces a `Text` component with `RNTesterText` so it's legible.

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D65363864

fbshipit-source-id: 6c7ce8d5af6aabfed21479c784911bdcffe4684e
2024-11-07 07:53:01 -08:00
Nicola Corti 7817ab5de2 Reland: Undo breaking change of UiManager.eventDispatcher by solving circular dependency (#47478)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47478

That's a reland of D65540601

The `UIManager.eventDispatcher` return type is wrong and is causing a breaking change in 0.77

For 0.76 we fixed it in the release branch but we should fix it for good in main as well.
To solve it I had to fix the circular dependency between .bridge and .uimanager.

I wish I could have isolated the .events package better but as everythign is public, any
change we do is going to be a breaking change so I'm being over cautios here.

Changelog:
[Android] [Fixed] - Undo breaking change of UiManager.eventDispatcher return type

Reviewed By: javache

Differential Revision: D65595391

fbshipit-source-id: fc7f6dce78e531c5ec0cc493ed90c0012262b77f
2024-11-07 05:25:17 -08:00
Alex Hunt 4567e2a897 Remove redundant UnimplementedView export from BackHandler (#47461)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47461

As titled, is overwritten later in the file.

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D65546370

fbshipit-source-id: 4ea71d24e429b7bbded3e7bb7c75015a2c9d95d8
2024-11-07 05:13:53 -08:00
Riccardo Cipolleschi 9e399d940a Remove XCBeautify from CI (#47482)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47482

XCBeautify swallow some errors, especially all the linker errors when some symbol is not defined. The full error is not available in the raw log either.

This makes much harder to debug those issues when they happen.

We can remove xcbeautify for the time being, while we find a better solution.

## Changelog
[Internal] - Remove XCBeautify from ci

Reviewed By: dmytrorykun

Differential Revision: D65596745

fbshipit-source-id: 0550d4cbeadc5bec8acc61b5edc1320d3445bcaf
2024-11-07 04:57:49 -08:00
Riccardo Cipolleschi ffa159e147 Set ASSUME_NONULL in codegen files (#47481)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47481

The Codegenerated files has this option turned off.
This is causing Xcode to output hundreds of warnings due to missing nullability options. RThis fixes them.

## CHANGELOG
[Internal] - Set ASSUME_NONNULL regions in codegen'd files

Reviewed By: dmytrorykun

Differential Revision: D65596598

fbshipit-source-id: bbf664944e103c05ef593a7e07bf5b767445950c
2024-11-07 04:50:55 -08:00
Mateo Guzmán 8bb3033d73 fix(flow): excluding packages/rn-tester/Pods/ from flow checks (#47474)
Summary:
When running the commands to check the flow types locally, there is quite some noise from files under `packages/rn-tester/Pods` that should not be checked as they are not from the source code itself.

<img width="839" alt="Screenshot 2024-11-07 at 00 50 55" src="https://github.com/user-attachments/assets/7ad3d96d-0f4a-4772-9e37-34d7e593b4cf">

## Changelog:

[INTERNAL] [FIXED] - Excluding `packages/rn-tester/Pods/` from flow checks

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

Test Plan:
```bash
yarn flow
```

Reviewed By: cortinico

Differential Revision: D65594400

Pulled By: cipolleschi

fbshipit-source-id: d5e8828f41fc87c9a95293c250f24673ebbc6cd4
2024-11-07 04:37:19 -08:00
Riccardo Cipolleschi ace690aba9 Generate RN specific Files in RN (#47458)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47458

We are in a weird situation where React Native depends on some files that are generated by Codegen.

Codegen runs in the user project, so those dependencies are not available to React Native if we try to build it in isolation.

This is a problem and a blocker to prepare the prebuilds for iOS.

This image show the changes we are introducing:
On the right we have the current situation.
On the left the new one.

{F1954418630}

## Changelog:
[Internal] - Generate React Native specific code inside React Native

Reviewed By: cortinico, blakef

Differential Revision: D65541505

fbshipit-source-id: 1412d7f23c4d2230b795af41f1e832c8a70d5859
2024-11-07 04:08:58 -08:00
Oskar Kwaśniewski 5e18f7f788 fix: typo in spm.rb (#47480)
Summary:
This PR fixes a typo in spm.rb

## Changelog:

[IOS] [FIXED] - Typo in spm.rb

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

Test Plan: N/a

Reviewed By: GijsWeterings

Differential Revision: D65596339

Pulled By: cortinico

fbshipit-source-id: c318cec1422dbcb322e70dc5f189d86af42b626d
2024-11-07 04:01:20 -08:00
Alan Lee fb69f406df Make IntentModule Nullsafe (#47430)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47430

Make IntentModule Nullsafe.
Fixed nullability warnings.

Changelog: [Internal]

Reviewed By: tdn120

Differential Revision: D65463226

fbshipit-source-id: 2da597e66ad170ec4a2a2949348e522bb361c209
2024-11-07 01:03:33 -08:00
Tim Yung 2dab7b078d ScrollView: Delete unstable_setEnableSyncOnScroll (#47399)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47399

Deletes `unstable_setEnableSyncOnScroll` which we are no longer experirmenting with in React Native.

Changelog:
[Internal] - Deleted `unstable_setEnableSyncOnScroll` on `ScrollView`, which was never part of the React Native Public API.

Reviewed By: tdn120, sammy-SC

Differential Revision: D65449039

fbshipit-source-id: 6608d5ccca477f1da5e0168c4a342cce17014b08
2024-11-07 00:00:14 -08:00
Yedidya Feldblum f01b47257a let PointerValue::invalidate() be noexcept (#47354)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47354

`PointerValue::invalidate()` is called from `Pointer` destructor, which is implicitly `noexcept`, and from `Pointer` move-assignment operator, which is now `noexcept`.

Reviewed By: neildhar

Differential Revision: D65271399

fbshipit-source-id: 26fd9707e4389da78537d0d607adaef0c68690ca
2024-11-06 23:10:36 -08:00
Mathieu Acthernoene 7a6c7a462a feat(android): Edge-to-edge Modal (navigationBarTranslucent prop) (#47254)
Summary:
The future of Android is [edge-to-edge](https://github.com/react-native-community/discussions-and-proposals/discussions/827) and to make the React Native developer experience seamless in this regard, the ecosystem needs to transition from “opaque system bars by default” to “edge-to-edge by default.”

Currently, there's no easy way to have edge-to-edge modals, as they are implemented using `Dialog` instances (a separate `Window`) and only provide a `statusBarTranslucent` prop.

I tried to implement it in [`react-native-edge-to-edge`](https://github.com/zoontek/react-native-edge-to-edge) by listening to the `topShow` `UIManager` event. But if it works well when there's a defined animation, we can see a quick jump when there's none, because there's too much delay before the event, and edge-to-edge cannot be applied quick enough to the dialog window.

### react-native-edge-to-edge implem with animation (no jump)

https://github.com/user-attachments/assets/4933a102-87a5-40e4-98d9-47f8c0817592

### react-native-edge-to-edge implem without animation (jump)

https://github.com/user-attachments/assets/e4675589-08fe-44fe-b9d8-0a6b3552b461

 ---

For this reason, and because listening to event feels a bit hacky, I think it will be better to go for a new prop directly on RN Modal component: `navigationBarTranslucent`

> [!NOTE]
> `navigationBarTranslucent` cannot be used without `statusBarTranslucent`, as setting both enable edge-to-edge, like [AndroidX would do](https://github.com/androidx/androidx/blob/androidx-main/activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt) and it would requires extra (and unecessary, given the direction Android is taking) work to find a way to keep the status bar opaque but the navigation bar transparent that work on Android 6 to 15+

### Additional infos

- Colors used for the buttons navigation bar in the PR are the default Android ones ([light](https://github.com/androidx/androidx/blob/androidx-main/activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt#L37) and [dark](https://github.com/androidx/androidx/blob/androidx-main/activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt#L42))
- Compared to the Google implementation, the light scrim is applied from `O_MR1` to `Q` (and not `O` to `Q`) as the [`android:windowLightNavigationBar`](https://developer.android.com/reference/android/R.attr#windowLightNavigationBar) style attribute is not available on `O` (it can only be applied programmatically on API 26).

## Changelog:

[ANDROID] [ADDED] - Add navigationBarTranslucent prop to Modal component

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

Test Plan:
Run the tester app, toggle `navigationBarTranslucent`:

https://github.com/user-attachments/assets/286d173b-35a5-4951-9105-f9f7562d6764

-----
did some additional testing with RNTester using different justification

|flex-start|flex-end|
|https://pxl.cl/5Rd20|https://pxl.cl/5Rd21|

Reviewed By: javache

Differential Revision: D65103501

Pulled By: alanleedev

fbshipit-source-id: ef6473ecd785976d3e26c77bbc212222ec96c9f2
2024-11-06 21:09:36 -08:00
Liron Yahdav 61e660b40e Expose some VirtualizedList functions to allow creating VirtualizedListContextProvider outside of VirtualizedList (#47463)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47463

Note this is just a temporary approach which will be cleaned up later.

Changelog: [Internal]

Reviewed By: yungsters

Differential Revision: D65514902

fbshipit-source-id: f722031c5cd34eb1400b3f732fd94c0b03d5434d
2024-11-06 20:15:08 -08:00
Nicola Corti 46526fc2fe Stable API - Make classes inside com.facebook.react.views.progressbar internal (#47376)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47376

This makes several classes inside `com.facebook.react.views.progressbar` internal:
- ReactProgressBarViewManager
- ProgressBarShadowNode
- ProgressBarContainerView

Those classes should have not been exposed in the first place and users should not depend on them directly.
Marked as Breaking but verified that there are no meaningful usages in OSS.

Changelog:
[Android] [Breaking] - Stable API - Make classes inside `com.facebook.react.views.progressbar` internal

Reviewed By: javache

Differential Revision: D65423290

fbshipit-source-id: dc98fdca996eb648593adb2c32787cbf0d878e3e
2024-11-06 18:32:38 -08:00
Sam Zhou 0ca2ba082d Fix final few problematic React.ElementRef in react-native (#47473)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47473

For example,

```
declare function C<T>(ref: React.RefSetter<Set<T>>): React.Node;

type T = React.ElementRef<typeof C>
```

Previously Flow will evaluate `T` to `Set<mixed>`, by automatically replacing generic types with their upper bounds. But in the future it might be replaced with `empty`.

This diff cleans up instances like this in react-native codebase.

Changelog: [Internal]

Reviewed By: alexmckenley

Differential Revision: D65562571

fbshipit-source-id: bca2f4f022a5a23a5aa40886f5661899cb315f2e
2024-11-06 18:14:19 -08:00
Phillip Pan 8e375f0505 introduce internal API to reload bridgeless without surface restart (#47404)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47404

Changelog: [Internal]

introducing an internal API to reload without starting up the surfaces that were stopped at time of reload

Reviewed By: sammy-SC

Differential Revision: D65461606

fbshipit-source-id: 9e58bebdc3e03ead7f91376b7aaba5c7944bddcf
2024-11-06 18:13:34 -08:00
David Vacca bc3ea5c957 Revert migration of ReactHorizontalScrollContainerViewManager to use ViewManagerInterface (#47472)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47472

using ViewManagerDelegates for ReactHorizontalScrollContainerViewManager which extends ReactClippingViewManager will introduce a bug (not updating props that are managed by ReactClippingViewManager)

I'm reverting the migration and we should fix the bug in codegen

This diff is a revert of D65428646

changelog: [internal] internal

Reviewed By: sammy-SC, Abbondanzo

Differential Revision: D65564730

fbshipit-source-id: ff183876321d4d36e51da8f38ff6f381207c7c3a
2024-11-06 18:04:31 -08:00
Ramanpreet Nara 50b3c2272f ExceptionsManager: Fix soft error reporting (#47465)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47465

When you do @(NO), in objc, it creates an NSNumber.

So this if condition actually evaluates to true:

```
if (@(NO))
```

This means that all soft errors will get logged as fatals on ios.

Changelog: [Internal]

Created from CodeHub with https://fburl.com/edit-in-codehub

Reviewed By: realsoelynn

Differential Revision: D65551648

fbshipit-source-id: 99b5bcb5fa1b0b5dc8055a3c86fc983863a25526
2024-11-06 17:58:27 -08:00
Alan Lee e6090df7dc xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/perftest/PerfTestConfig.java (#47440)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47440

Removing file as it does not seem to be used

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D65457514

fbshipit-source-id: 39efa12176fe65a491fa4285099134f2bf753159
2024-11-06 15:43:58 -08:00
Alan Lee c53d3e1901 xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/ReactFindViewUtil.java (#47431)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47431

Convert Java to Kotlin

Changelog: [Internal]

Reviewed By: tdn120

Differential Revision: D65430703

fbshipit-source-id: a1fcab2dd577fe67a1507c330466dabe7483c843
2024-11-06 15:19:38 -08:00
Grace Nichols 147e6c3458 Revert D65540601: Undo breaking change of UiManager.eventDispatcher by solving circular dependency
Differential Revision:
D65540601

Original commit changeset: 4b1f62806baa

Original Phabricator Diff: D65540601

fbshipit-source-id: 9abc3a663882634bb7d42b16bc95d8c2934a2ca5
2024-11-06 12:58:27 -08:00
Adam Woods-Mccormick e603fde886 Revert D65478448: Convert com.facebook.react.bridge.JavaOnlyMap to Kotlin
Differential Revision:
D65478448

Original commit changeset: 24e6732a80f5

Original Phabricator Diff: D65478448

fbshipit-source-id: fffd2259aa2757b816373bfded96948b3e6dfeba
2024-11-06 12:49:38 -08:00
Nicola Corti dbe509a23a Undo breaking change of UiManager.eventDispatcher by solving circular dependency (#47457)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47457

The `UIManager.eventDispatcher` return type is wrong and is causing a breaking change in 0.77

For 0.76 we fixed it in the release branch but we should fix it for good in main as well.
To solve it I had to fix the circular dependency between .bridge and .uimanager.

I wish I could have isolated the .events package better but as everythign is public, any
change we do is going to be a breaking change so I'm being over cautios here.

Changelog:
[Android] [Fixed] - Undo breaking change of UiManager.eventDispatcher return type

Reviewed By: tdn120

Differential Revision: D65540601

fbshipit-source-id: 4b1f62806baac5f6c3ffdd51b8628ef088447604
2024-11-06 11:50:28 -08:00
Arushi Kesarwani abd118a719 Reducing visibility of OkHttpCallUtil (#47439)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47439

As part of sustainability week effort for switching to internal here:
https://fb.workplace.com/groups/251759413609061/permalink/872342228217440/

Reducing visibility of OkHttpCallUtil from `public` to `internal`

Changelog:
[Android] [Breaking] - Stable API - Make OkHttpCallUtil internal

Reviewed By: javache

Differential Revision: D65506859

fbshipit-source-id: 4ad55d9112da3b3f04b734f41c5a263f4eabfefb
2024-11-06 10:31:21 -08:00
Alex Hunt 0c21db360c Remove unused ReactFabricInternals API (#47454)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47454

As far as I can tell, this module is now unused both within the codebase and externally. Delete to reduce our public API surface (deep module is an accessible import path).

Changelog:
[General][Breaking] - Remove ReactFabricInternals module

Reviewed By: cortinico

Differential Revision: D65535378

fbshipit-source-id: 25ee16ccc637815ffe1c69a5fc546bd3e11d1689
2024-11-06 10:27:31 -08:00
Pieter De Baets 1be0387796 Convert com.facebook.react.bridge.JavaOnlyMap to Kotlin (#47416)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47416

Changelog: [Internal]

Reviewed By: tdn120

Differential Revision: D65478448

fbshipit-source-id: 24e6732a80f5ee858fec5dbb38617e7dfad63f58
2024-11-06 10:27:28 -08:00
Arushi Kesarwani 3dec672398 Reducing visibility of SimpleSettableFuture (#47438)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47438

As part of sustainability week effort for switching to `internal` here:
https://fb.workplace.com/groups/251759413609061/permalink/872342228217440/

Reducing visibility of SimpleSettableFuture from `public` to `internal`

Changelog:
[Android] [Breaking] - Stable API - Make SimpleSettableFuture internal

Reviewed By: javache

Differential Revision: D65502193

fbshipit-source-id: 4bdd9b43684c8bc075271d76856ef848c52e6b12
2024-11-06 10:26:16 -08:00
Mateo Guzmán 17c164621d test(image): [android] improving image property test cases (#47433)
Summary:
I've doing some enhancements around the Image component for Android, and in the process of understanding the codebase I saw some opportunity to improve the test cases as there is no much coverage around the underlying functionality.

## Changelog:

[INTERNAL] [ADDED] - Improving Android Image property test cases

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

Test Plan:
```bash
yarn test-android
```

Reviewed By: javache

Differential Revision: D65530813

Pulled By: cortinico

fbshipit-source-id: b314eaf7493c6f3c859b7cb0d06771c109e5e854
2024-11-06 09:19:27 -08:00
Nicola Corti a3ab7895c9 Add missing \n on actOnLabel.js (#47451)
Summary:
I forgot to add some `\n` in the bot messages. This fixes it.

## Changelog:

[INTERNAL] - Add missing `\n` on actOnLabel.js

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

Test Plan: N/A

Reviewed By: cipolleschi

Differential Revision: D65533495

Pulled By: cortinico

fbshipit-source-id: c2214d00800f6b70ec331a9ae72578414f50cd43
2024-11-06 08:54:10 -08:00
qnnp 0244710c4b refactor(PermissionsAndroid): Use the TypeScript key in syntax to restrict permissions and types of results (#47299)
Summary:
Changelog:
[General][Added] Use the TypeScript key in syntax to restrict permissions and types of results

 - Use key in 'GRANTED' | 'DENIED' | 'NEVER_ASK_AGAIN for RESULTS constants to ensure that only these values are allowed

 - Use a detailed list of permission names for PERMISSIONS constants to restrict the type of key

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

Reviewed By: yungsters

Differential Revision: D65480410

Pulled By: tdn120

fbshipit-source-id: ec23750d72ede0ba6ed96e80c35242da08b2508e
2024-11-06 08:45:18 -08:00
Blake Friedman e0be2efe4e fix/cli start (#47450)
Summary:
When decoupling the community-cli-plugin from the react-native-community/cli-server-api (https://github.com/facebook/react-native/issues/45311), a middleware stub was created to allow a runtime stub to be used in this case. This middleware should be used so as not to break when the optional cli-server-api dependency isn't present.

Changelog:
[General][Fixed] - Fix npm react-native start when cli-server-api isn't installed

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

Test Plan:
Forced a runtime exception simulating the package not being dependent and was able to build rn-tester.

![CleanShot 2024-11-06 at 10 49 58@2x](https://github.com/user-attachments/assets/c040ec5b-7000-43bd-ba54-52a672ff3675)

Reviewed By: cipolleschi

Differential Revision: D65532486

Pulled By: blakef

fbshipit-source-id: 2b380607de63ac2da906ef0cb1e48b9ef263cb68
2024-11-06 07:26:30 -08:00
Pieter De Baets b04f5fbfba Add Binding.h header back for backwards compat (#47453)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47453

`react-native-screens` [depends on this header](https://github.com/software-mansion/react-native-screens/blob/main/android/src/main/cpp/NativeProxy.cpp#L2) and this is an unnecessary API breakage.

Changelog: [Android][Fixed] Added back `<react/fabric/Binding.h>` header.

Reviewed By: fabriziocucci

Differential Revision: D65534176

fbshipit-source-id: ce252f29be1c5322f44e20b6e36ab51db9c7a8ef
2024-11-06 06:38:47 -08:00
Pieter De Baets 5b41c7a84b Convert com.facebook.react.views.text.TextTransform to Kotlin (#47412)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47412

Changelog: [Internal]

Reviewed By: cortinico, fabriziocucci

Differential Revision: D65478027

fbshipit-source-id: e65019b7a90b696c3764e1deaf94f5f8bb0a7a95
2024-11-06 06:38:29 -08:00
Nicola Corti 10f6d5adb5 Stable API - Make ClipboardModule internal (#47413)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47413

This class should not be accessed directly, therefore I'm making it internal.
Technically breaking but I verified that there are no meaningful usages in OSS:
https://github.com/search?type=code&q=NOT+is%3Afork+NOT+org%3Afacebook+com.facebook.react.modules.clipboard.ClipboardModule

Changelog:
[Android] [Breaking] - Stable API - Make `ClipboardModule` internal

Reviewed By: mdvacca

Differential Revision: D65479065

fbshipit-source-id: 1c534cafffdb27b808553eec7346e21fe4f38c24
2024-11-06 04:16:43 -08:00
Riccardo Cipolleschi d352a9979d Add checkout step to check nightly (#47448)
Summary:
In order to use a reusable workflow in GHA, we need first to checkout the repository so the action has access to the other workflows.

## Changelog:
[Internal] - Add checkout step to Check Nightlies

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

Test Plan: GHA - https://github.com/facebook/react-native/actions/runs/11702038686?pr=47448

Reviewed By: cortinico

Differential Revision: D65532274

Pulled By: cipolleschi

fbshipit-source-id: 58117ac81973e3c07829d73d5bde4e6fd4d212f9
2024-11-06 04:07:13 -08:00
kunal.chavhan 92f51c009f add e2e test for empty case in flatlist (#47444)
Summary:
Part of https://github.com/facebook/react-native/issues/46757
Solves: ME2E0010

## Changelog:

[INTERNAL][ADDED] - add e2e test for empty case in flatlist

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

Test Plan:
```
yarn e2e-test-ios
yarn e2e-test-android
```

Reviewed By: cortinico

Differential Revision: D65531064

Pulled By: cipolleschi

fbshipit-source-id: 700c2fd6d43c24671021b6c3c5a4218e5699c7d9
2024-11-06 04:07:01 -08:00
116 changed files with 1753 additions and 1426 deletions
+3
View File
@@ -26,6 +26,9 @@
; helloworld
<PROJECT_ROOT>/packages/helloworld/ios/Pods/
; Ignore rn-tester Pods
<PROJECT_ROOT>/packages/rn-tester/Pods/
[untyped]
.*/node_modules/@react-native-community/cli/.*/.*
@@ -3,9 +3,6 @@ description: Prepare iOS Tests
runs:
using: composite
steps:
- name: brew install xcbeautify
run: brew install xcbeautify
shell: bash
- name: Run Ruby Tests
shell: bash
run: |
+4 -4
View File
@@ -121,21 +121,21 @@ runs:
if: ${{ inputs.run-unit-tests != 'true' && inputs.run-e2e-tests == 'false' }}
shell: bash
run: |
set -o pipefail && xcodebuild build \
xcodebuild build \
-workspace packages/rn-tester/RNTesterPods.xcworkspace \
-scheme RNTester \
-sdk iphonesimulator | xcbeautify
-sdk iphonesimulator
- name: Build RNTester (E2E Tests)
shell: bash
if: ${{ inputs.run-e2e-tests == 'true' }}
run: |
set -o pipefail && xcodebuild \
xcodebuild \
-scheme "RNTester" \
-workspace packages/rn-tester/RNTesterPods.xcworkspace \
-configuration "${{ inputs.flavor }}" \
-sdk "iphonesimulator" \
-destination "generic/platform=iOS Simulator" \
-derivedDataPath "/tmp/RNTesterBuild" | xcbeautify
-derivedDataPath "/tmp/RNTesterBuild"
echo "Print path to *.app file"
find "/tmp/RNTesterBuild" -type d -name "*.app"
+12 -12
View File
@@ -48,83 +48,83 @@ module.exports = async (github, context, labelWithContext) => {
switch (labelWithContext.label) {
case 'Type: Invalid':
await addComment(
`> [!CAUTION]` +
`> [!CAUTION]\n` +
`> **Invalid issue**: This issue is not valid, either is not a bug in React Native, it doesn't match any of the issue template, or we can't help further with this.`,
);
await closeIssue();
return;
case 'Type: Question':
await addComment(
`> [!NOTE]` +
`> [!NOTE]\n` +
`> **Not a bug report**: This issue looks like a question. We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/).`,
);
await closeIssue();
return;
case 'Resolution: For Stack Overflow':
await addComment(
`> [!NOTE]` +
`> [!NOTE]\n` +
`> **Not a bug report**: This issue looks like a question. We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/).`,
);
await closeIssue();
return;
case 'Type: Docs':
await addComment(
`> [!NOTE]` +
`> [!NOTE]\n` +
`> **Docs issue**: This issue looks like an issue related to our docs. Please report documentation issues in the [react-native-website](https://github.com/facebook/react-native-website/issues) repository.`,
);
await closeIssue();
return;
case 'Type: Expo':
await addComment(
`> [!NOTE]` +
`> [!NOTE]\n` +
`> **Expo related**: It looks like your issue is related to Expo and not React Native core. Please open your issue in [Expo's repository](https://github.com/expo/expo/issues/new). If you are able to create a repro that showcases that this issue is also happening in React Native vanilla, we will be happy to re-open.`,
);
await closeIssue();
return;
case 'Needs: Issue Template':
await addComment(
`> [!WARNING]` +
`> [!WARNING]\n` +
`> **Missing issue template**: It looks like your issue may be missing some necessary information. GitHub provides an example template whenever a [new issue is created](https://github.com/facebook/react-native/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A&projects=&template=bug_report.yml). Could you go back and make sure to fill out the template? You may edit this issue, or close it and open a new one.`,
);
await requestAuthorFeedback();
return;
case 'Needs: Environment Info':
await addComment(
`> [!WARNING]` +
`> [!WARNING]\n` +
`> **Missing info**: It looks like your issue may be missing information about your development environment. You can obtain the missing information by running <code>react-native info</code> in a console.`,
);
await requestAuthorFeedback();
return;
case 'Newer Patch Available':
await addComment(
`> [!TIP]` +
`> [!TIP]\n` +
`> **Newer version available**: You are on a supported minor version, but it looks like there's a newer patch available - ${labelWithContext.newestPatch}. Please [upgrade](https://reactnative.dev/docs/upgrading) to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases.`,
);
return;
case 'Needs: Version Info':
await addComment(
`> [!WARNING]` +
`> [!WARNING]\n` +
`> **Could not parse version**: We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.76.2.`,
);
await requestAuthorFeedback();
return;
case 'Needs: Repro':
await addComment(
`> [!WARNING]` +
`> [!WARNING]\n` +
`> **Missing reproducer**: We could not detect a reproducible example in your issue report. Please provide either: <br/><ul><li>If your bug is UI related: a [Snack](https://snack.expo.dev)</li><li> If your bug is build/upgrade related: a project using our [Reproducer Template](https://github.com/react-native-community/reproducer-react-native/generate)</li><li>Otherwise send us a Pull Request with the [RNTesterPlayground.js](https://github.com/facebook/react-native/blob/main/packages/rn-tester/js/examples/Playground/RNTesterPlayground.js) edited to reproduce your bug.</li></ul>`,
);
await requestAuthorFeedback();
return;
case 'Type: Unsupported Version':
await addComment(
`> [!WARNING]` +
`> [!WARNING]\n` +
`> **Unsupported version**: It looks like your issue or the example you provided uses an [unsupported version of React Native](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md).<br/><br/>Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support.`,
);
await requestAuthorFeedback();
return;
case 'Type: Too Old Version':
await addComment(
`> [!CAUTION]` +
`> [!CAUTION]\n` +
`> **Too old version**: It looks like your issue or the example you provided uses a [**Too Old Version of React Native**](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md).<br/><br/>Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support.`,
);
await closeIssue();
+6 -2
View File
@@ -13,6 +13,8 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'facebook/react-native'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check nightly
run: |
TODAY=$(date "+%Y%m%d")
@@ -24,5 +26,7 @@ jobs:
else
echo 'Nightly Worked, All Good!'
fi
- name: Test Libraries
uses: ./.github/workflows/test-libraries-on-nightlies.yml
test-libraries:
uses: ./.github/workflows/test-libraries-on-nightlies.yml
needs: check-nightly
+1 -1
View File
@@ -124,7 +124,7 @@ vendor/
!/packages/rn-tester/Pods/__offline_mirrors_jsc__
# @react-native/codegen
/packages/react-native/React/FBReactNativeSpec/FBReactNativeSpec
/packages/react-native/React/FBReactNativeSpec/
/packages/react-native-codegen/lib
/packages/react-native-codegen/tmp/
/packages/react-native/ReactCommon/react/renderer/components/rncore/
@@ -19,10 +19,7 @@ import isDevServerRunning from '../../utils/isDevServerRunning';
import loadMetroConfig from '../../utils/loadMetroConfig';
import * as version from '../../utils/version';
import attachKeyHandlers from './attachKeyHandlers';
import {
createDevServerMiddleware,
indexPageMiddleware,
} from '@react-native-community/cli-server-api';
import {createDevServerMiddleware, indexPageMiddleware} from './middleware';
import {createDevMiddleware} from '@react-native/dev-middleware';
import chalk from 'chalk';
import Metro from 'metro';
+42
View File
@@ -553,6 +553,48 @@ if (global.nativeLoggingHook) {
assert: consoleAssertPolyfill,
};
// TODO(T206796580): This was copy-pasted from ExceptionsManager.js
// Delete the copy there after the c++ pipeline is rolled out everywhere.
if (global.RN$useAlwaysAvailableJSErrorHandling === true) {
let originalConsoleError = console.error;
console.reportErrorsAsExceptions = true;
function stringifySafe(arg) {
return inspect(arg, {depth: 10}).replaceAll(/\n\s*/g, ' ');
}
console.error = function (...args) {
originalConsoleError.apply(this, args);
if (!console.reportErrorsAsExceptions) {
return;
}
if (global.RN$inExceptionHandler?.()) {
return;
}
let error;
const firstArg = args[0];
if (firstArg?.stack) {
// RN$handleException will console.error this with high enough fidelity.
error = firstArg;
} else {
if (typeof firstArg === 'string' && firstArg.startsWith('Warning: ')) {
// React warnings use console.error so that a stack trace is shown, but
// we don't (currently) want these to show a redbox
return;
}
const message = args
.map(arg => (typeof arg === 'string' ? arg : stringifySafe(arg)))
.join(' ');
error = new Error(message);
error.name = 'console.error';
}
const isFatal = false;
const reportToConsole = false;
global.RN$handleException(error, isFatal, reportToConsole);
};
}
Object.defineProperty(console, '_isPolyfilled', {
value: true,
enumerable: false,
+6 -6
View File
@@ -19,12 +19,12 @@ type Fn<Args, Return> = (...Args) => Return;
* when loading a module. This will report any errors encountered before
* ExceptionsManager is configured.
*/
let _globalHandler: ErrorHandler = function onError(
e: mixed,
isFatal: boolean,
) {
throw e;
};
let _globalHandler: ErrorHandler =
global.RN$useAlwaysAvailableJSErrorHandling === true
? global.RN$handleException
: (e: mixed, isFatal: boolean) => {
throw e;
};
/**
* The particular require runtime that we are using looks for a global
@@ -8,6 +8,7 @@
* @format
*/
import type {SectionBase} from '../../Lists/SectionList';
import type {AnimatedComponentType} from '../createAnimatedComponent';
import SectionList from '../../Lists/SectionList';
@@ -16,5 +17,6 @@ import * as React from 'react';
export default (createAnimatedComponent(SectionList): AnimatedComponentType<
React.ElementConfig<typeof SectionList>,
React.ElementRef<typeof SectionList>,
// $FlowExpectedError[unclear-type]
SectionList<SectionBase<any>>,
>);
@@ -74,7 +74,7 @@ Pod::Spec.new do |s|
s.dependency "React-RCTImage"
s.dependency "React-CoreModules"
s.dependency "React-nativeconfig"
s.dependency "ReactCodegen"
s.dependency "React-RCTFBReactNativeSpec"
s.dependency "React-defaultsnativemodule"
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
@@ -57,7 +57,7 @@ Pod::Spec.new do |s|
s.dependency "React-Core/RCTWebSocket"
s.dependency "React-RCTNetwork"
add_dependency(s, "ReactCodegen")
add_dependency(s, "React-RCTFBReactNativeSpec")
add_dependency(s, "React-NativeModulesApple")
add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern')
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
@@ -31,7 +31,6 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = {
pagingEnabled: true,
persistentScrollbar: true,
horizontal: true,
enableSyncOnScroll: true,
scrollEnabled: true,
scrollEventThrottle: true,
scrollPerfTag: true,
@@ -8,10 +8,6 @@
* @flow strict-local
*/
import type {
TScrollViewNativeComponentInstance,
TScrollViewNativeImperativeHandle,
} from '../../../src/private/components/useSyncOnScroll';
import type {HostInstance} from '../../Renderer/shims/ReactNativeTypes';
import type {EdgeInsetsProp} from '../../StyleSheet/EdgeInsetsPropType';
import type {PointProp} from '../../StyleSheet/PointPropType';
@@ -46,7 +42,6 @@ import StyleSheet from '../../StyleSheet/StyleSheet';
import Dimensions from '../../Utilities/Dimensions';
import dismissKeyboard from '../../Utilities/dismissKeyboard';
import Platform from '../../Utilities/Platform';
import EventEmitter from '../../vendor/emitter/EventEmitter';
import Keyboard from '../Keyboard/Keyboard';
import TextInputState from '../TextInput/TextInputState';
import processDecelerationRate from './processDecelerationRate';
@@ -152,7 +147,7 @@ export type DecelerationRateType = 'fast' | 'normal' | number;
export type ScrollResponderType = ScrollViewImperativeMethods;
type PublicScrollViewInstance = $ReadOnly<{|
...$Exact<TScrollViewNativeComponentInstance>,
...HostInstance,
...ScrollViewImperativeMethods,
|}>;
@@ -743,10 +738,6 @@ class ScrollView extends React.Component<Props, State> {
_subscriptionKeyboardDidShow: ?EventSubscription = null;
_subscriptionKeyboardDidHide: ?EventSubscription = null;
#onScrollEmitter: ?EventEmitter<{
scroll: [{x: number, y: number}],
}> = null;
state: State = {
layoutHeight: null,
};
@@ -817,8 +808,6 @@ class ScrollView extends React.Component<Props, State> {
if (this._scrollAnimatedValueAttachment) {
this._scrollAnimatedValueAttachment.detach();
}
this.#onScrollEmitter?.removeAllListeners();
}
/**
@@ -844,9 +833,8 @@ class ScrollView extends React.Component<Props, State> {
return this._innerView.nativeInstance;
};
getNativeScrollRef: () => TScrollViewNativeComponentInstance | null = () => {
const {nativeInstance} = this._scrollView;
return nativeInstance == null ? null : nativeInstance.componentRef.current;
getNativeScrollRef: () => HostInstance | null = () => {
return this._scrollView.nativeInstance;
};
/**
@@ -937,20 +925,6 @@ class ScrollView extends React.Component<Props, State> {
Commands.flashScrollIndicators(component);
};
_subscribeToOnScroll: (
callback: ({x: number, y: number}) => void,
) => EventSubscription = callback => {
let onScrollEmitter = this.#onScrollEmitter;
if (onScrollEmitter == null) {
onScrollEmitter = new EventEmitter();
this.#onScrollEmitter = onScrollEmitter;
// This is the first subscription, so make sure the native component is
// also configured to output synchronous scroll events.
this._scrollView.nativeInstance?.unstable_setEnableSyncOnScroll(true);
}
return onScrollEmitter.addListener('scroll', callback);
};
/**
* This method should be used as the callback to onFocus in a TextInputs'
* parent view. Note that any module using this mixin needs to return
@@ -1154,11 +1128,6 @@ class ScrollView extends React.Component<Props, State> {
_handleScroll = (e: ScrollEvent) => {
this._observedScrollSinceBecomingResponder = true;
this.props.onScroll && this.props.onScroll(e);
this.#onScrollEmitter?.emit('scroll', {
x: e.nativeEvent.contentOffset.x,
y: e.nativeEvent.contentOffset.y,
});
};
_handleLayout = (e: LayoutEvent) => {
@@ -1181,45 +1150,36 @@ class ScrollView extends React.Component<Props, State> {
(instance: InnerViewInstance): InnerViewInstance => instance,
);
_scrollView: RefForwarder<
TScrollViewNativeImperativeHandle,
PublicScrollViewInstance | null,
> = createRefForwarder(nativeImperativeHandle => {
const nativeInstance = nativeImperativeHandle.componentRef.current;
if (nativeInstance == null) {
return null;
}
_scrollView: RefForwarder<HostInstance, PublicScrollViewInstance | null> =
createRefForwarder(nativeInstance => {
// This is a hack. Ideally we would forwardRef to the underlying
// host component. However, since ScrollView has it's own methods that can be
// called as well, if we used the standard forwardRef then these
// methods wouldn't be accessible and thus be a breaking change.
//
// Therefore we edit ref to include ScrollView's public methods so that
// they are callable from the ref.
// This is a hack. Ideally we would forwardRef to the underlying
// host component. However, since ScrollView has it's own methods that can be
// called as well, if we used the standard forwardRef then these
// methods wouldn't be accessible and thus be a breaking change.
//
// Therefore we edit ref to include ScrollView's public methods so that
// they are callable from the ref.
// $FlowFixMe[prop-missing] - Known issue with appending custom methods.
const publicInstance: PublicScrollViewInstance = Object.assign(
nativeInstance,
{
getScrollResponder: this.getScrollResponder,
getScrollableNode: this.getScrollableNode,
getInnerViewNode: this.getInnerViewNode,
getInnerViewRef: this.getInnerViewRef,
getNativeScrollRef: this.getNativeScrollRef,
scrollTo: this.scrollTo,
scrollToEnd: this.scrollToEnd,
flashScrollIndicators: this.flashScrollIndicators,
scrollResponderZoomTo: this.scrollResponderZoomTo,
scrollResponderScrollNativeHandleToKeyboard:
this.scrollResponderScrollNativeHandleToKeyboard,
},
);
// $FlowFixMe[prop-missing] - Known issue with appending custom methods.
const publicInstance: PublicScrollViewInstance = Object.assign(
nativeInstance,
{
getScrollResponder: this.getScrollResponder,
getScrollableNode: this.getScrollableNode,
getInnerViewNode: this.getInnerViewNode,
getInnerViewRef: this.getInnerViewRef,
getNativeScrollRef: this.getNativeScrollRef,
scrollTo: this.scrollTo,
scrollToEnd: this.scrollToEnd,
flashScrollIndicators: this.flashScrollIndicators,
scrollResponderZoomTo: this.scrollResponderZoomTo,
// TODO: Replace unstable_subscribeToOnScroll once scrollView.addEventListener('scroll', (e: ScrollEvent) => {}, {passive: false});
unstable_subscribeToOnScroll: this._subscribeToOnScroll,
scrollResponderScrollNativeHandleToKeyboard:
this.scrollResponderScrollNativeHandleToKeyboard,
},
);
return publicInstance;
});
return publicInstance;
});
/**
* Warning, this may be called several times for a single keyboard opening.
@@ -1829,8 +1789,9 @@ class ScrollView extends React.Component<Props, State> {
}
const refreshControl = this.props.refreshControl;
const scrollViewRef: React.RefSetter<TScrollViewNativeImperativeHandle | null> =
this._scrollView.getForwardingRef(this.props.scrollViewRef);
const scrollViewRef = this._scrollView.getForwardingRef(
this.props.scrollViewRef,
);
if (refreshControl) {
if (Platform.OS === 'ios') {
@@ -45,7 +45,6 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
diff: require('../../Utilities/differ/pointsDiffer'),
},
decelerationRate: true,
enableSyncOnScroll: true, // Fabric only.
disableIntervalMomentum: true,
maintainVisibleContentPosition: true,
pagingEnabled: true,
@@ -135,7 +134,6 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
contentInsetAdjustmentBehavior: true,
decelerationRate: true,
endDraggingSensitivityMultiplier: true,
enableSyncOnScroll: true, // Fabric only.
directionalLockEnabled: true,
disableIntervalMomentum: true,
indicatorStyle: true,
@@ -301,7 +301,6 @@ const ScrollViewStickyHeaderWithForwardedRef: component(
const styles = StyleSheet.create({
header: {
zIndex: 10,
position: 'relative',
},
fill: {
flex: 1,
+1 -4
View File
@@ -177,10 +177,7 @@ function reactConsoleErrorHandler(...args) {
if (!console.reportErrorsAsExceptions) {
return;
}
if (
inExceptionHandler ||
(global.RN$inExceptionHandler && global.RN$inExceptionHandler())
) {
if (inExceptionHandler || global.RN$inExceptionHandler?.()) {
// The fundamental trick here is that are multiple entry point to logging errors:
// (see D19743075 for more background)
//
+20 -18
View File
@@ -10,24 +10,26 @@
'use strict';
/**
* Sets up the console and exception handling (redbox) for React Native.
* You can use this module directly, or just require InitializeCore.
*/
const ExceptionsManager = require('./ExceptionsManager');
ExceptionsManager.installConsoleErrorReporter();
if (global.RN$useAlwaysAvailableJSErrorHandling !== true) {
/**
* Sets up the console and exception handling (redbox) for React Native.
* You can use this module directly, or just require InitializeCore.
*/
const ExceptionsManager = require('./ExceptionsManager');
ExceptionsManager.installConsoleErrorReporter();
// Set up error handler
if (!global.__fbDisableExceptionsManager) {
const handleError = (e: mixed, isFatal: boolean) => {
try {
ExceptionsManager.handleException(e, isFatal);
} catch (ee) {
console.log('Failed to print error: ', ee.message);
throw e;
}
};
// Set up error handler
if (!global.__fbDisableExceptionsManager) {
const handleError = (e: mixed, isFatal: boolean) => {
try {
ExceptionsManager.handleException(e, isFatal);
} catch (ee) {
console.log('Failed to print error: ', ee.message);
throw e;
}
};
const ErrorUtils = require('../vendor/core/ErrorUtils');
ErrorUtils.setGlobalHandler(handleError);
const ErrorUtils = require('../vendor/core/ErrorUtils');
ErrorUtils.setGlobalHandler(handleError);
}
}
@@ -53,7 +53,7 @@ Pod::Spec.new do |s|
s.dependency "React-Core/RCTImageHeaders"
s.dependency "React-RCTNetwork"
add_dependency(s, "ReactCodegen")
add_dependency(s, "React-RCTFBReactNativeSpec")
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
add_dependency(s, "React-NativeModulesApple")
@@ -10,6 +10,7 @@
import type {Task} from './TaskQueue';
import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags';
import EventEmitter from '../vendor/emitter/EventEmitter';
const BatchedBridge = require('../BatchedBridge/BatchedBridge');
@@ -208,4 +209,8 @@ function _processUpdate() {
_deleteInteractionSet.clear();
}
module.exports = InteractionManager;
module.exports = (
ReactNativeFeatureFlags.disableInteractionManager()
? require('./InteractionManagerStub')
: InteractionManager
) as typeof InteractionManager;
@@ -0,0 +1,176 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict
* @format
*/
import type {EventSubscription} from '../vendor/emitter/EventEmitter';
const invariant = require('invariant');
export type Handle = number;
type Task =
| {
name: string,
run: () => void,
}
| {
name: string,
gen: () => Promise<void>,
}
| (() => void);
/**
* InteractionManager allows long-running work to be scheduled after any
* interactions/animations have completed. In particular, this allows JavaScript
* animations to run smoothly.
*
* Applications can schedule tasks to run after interactions with the following:
*
* ```
* InteractionManager.runAfterInteractions(() => {
* // ...long-running synchronous task...
* });
* ```
*
* Compare this to other scheduling alternatives:
*
* - requestAnimationFrame(): for code that animates a view over time.
* - setImmediate/setTimeout(): run code later, note this may delay animations.
* - runAfterInteractions(): run code later, without delaying active animations.
*
* The touch handling system considers one or more active touches to be an
* 'interaction' and will delay `runAfterInteractions()` callbacks until all
* touches have ended or been cancelled.
*
* InteractionManager also allows applications to register animations by
* creating an interaction 'handle' on animation start, and clearing it upon
* completion:
*
* ```
* var handle = InteractionManager.createInteractionHandle();
* // run animation... (`runAfterInteractions` tasks are queued)
* // later, on animation completion:
* InteractionManager.clearInteractionHandle(handle);
* // queued tasks run if all handles were cleared
* ```
*
* `runAfterInteractions` takes either a plain callback function, or a
* `PromiseTask` object with a `gen` method that returns a `Promise`. If a
* `PromiseTask` is supplied, then it is fully resolved (including asynchronous
* dependencies that also schedule more tasks via `runAfterInteractions`) before
* starting on the next task that might have been queued up synchronously
* earlier.
*
* By default, queued tasks are executed together in a loop in one
* `setImmediate` batch. If `setDeadline` is called with a positive number, then
* tasks will only be executed until the deadline (in terms of js event loop run
* time) approaches, at which point execution will yield via setTimeout,
* allowing events such as touches to start interactions and block queued tasks
* from executing, making apps more responsive.
*
* @deprecated
*/
const InteractionManagerStub = {
Events: {
interactionStart: 'interactionStart',
interactionComplete: 'interactionComplete',
},
/**
* Schedule a function to run after all interactions have completed. Returns a cancellable
* "promise".
*
* @deprecated
*/
runAfterInteractions(task: ?Task): {
then: <U>(
onFulfill?: ?(void) => ?(Promise<U> | U),
onReject?: ?(error: mixed) => ?(Promise<U> | U),
) => Promise<U>,
cancel: () => void,
...
} {
let immediateID: ?$FlowIssue;
const promise = new Promise((resolve, reject) => {
immediateID = setImmediate(() => {
if (typeof task === 'object' && task !== null) {
if (typeof task.gen === 'function') {
task.gen().then(resolve, reject);
} else if (typeof task.run === 'function') {
try {
task.run();
resolve();
} catch (error) {
reject(error);
}
} else {
reject(new TypeError(`Task "${task.name}" missing gen or run.`));
}
} else if (typeof task === 'function') {
try {
task();
resolve();
} catch (error) {
reject(error);
}
} else {
reject(new TypeError('Invalid task of type: ' + typeof task));
}
});
});
return {
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
then: promise.then.bind(promise),
cancel() {
clearImmediate(immediateID);
},
};
},
/**
* Notify manager that an interaction has started.
*
* @deprecated
*/
createInteractionHandle(): Handle {
return -1;
},
/**
* Notify manager that an interaction has completed.
*
* @deprecated
*/
clearInteractionHandle(handle: Handle) {
invariant(!!handle, 'InteractionManager: Must provide a handle to clear.');
},
/**
* @deprecated
*/
addListener(): EventSubscription {
return {
remove() {},
};
},
/**
* A positive number will use setTimeout to schedule any tasks after the
* eventLoopRunningTime hits the deadline value, otherwise all tasks will be
* executed in one setImmediate batch (default).
*
* @deprecated
*/
setDeadline(deadline: number) {
// Do nothing.
},
};
module.exports = InteractionManagerStub;
@@ -50,7 +50,7 @@ Pod::Spec.new do |s|
s.dependency "ReactCommon/turbomodule/core", version
s.dependency "React-jsi", version
add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"])
add_dependency(s, "React-RCTFBReactNativeSpec")
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"])
end
+1 -1
View File
@@ -55,7 +55,7 @@ if (__DEV__) {
if (global.RN$registerExceptionListener != null) {
global.RN$registerExceptionListener(
(error: ExtendedExceptionData & {preventDefault: () => mixed}) => {
if (!error.isFatal) {
if (global.RN$isRuntimeReady?.() || !error.isFatal) {
error.preventDefault();
addException(error);
}
+5
View File
@@ -101,6 +101,11 @@ export interface ModalPropsAndroid {
* Determines whether your modal should go under the system statusbar.
*/
statusBarTranslucent?: boolean | undefined;
/**
* Determines whether your modal should go under the system navigationbar.
*/
navigationBarTranslucent?: boolean | undefined;
}
export type ModalProps = ModalBaseProps &
+17
View File
@@ -95,6 +95,14 @@ export type Props = $ReadOnly<{|
*/
statusBarTranslucent?: ?boolean,
/**
* The `navigationBarTranslucent` prop determines whether your modal should go under
* the system navigationbar.
*
* See https://reactnative.dev/docs/modal.html#navigationbartranslucent-android
*/
navigationBarTranslucent?: ?boolean,
/**
* The `hardwareAccelerated` prop controls whether to force hardware
* acceleration for the underlying window.
@@ -176,6 +184,14 @@ function confirmProps(props: Props) {
`Modal with '${props.presentationStyle}' presentation style and 'transparent' value is not supported.`,
);
}
if (
props.navigationBarTranslucent === true &&
props.statusBarTranslucent !== true
) {
console.warn(
'Modal with translucent navigation bar and without translucent status bar is not supported.',
);
}
}
}
@@ -301,6 +317,7 @@ class Modal extends React.Component<Props, State> {
onDismiss={onDismiss}
visible={this.props.visible}
statusBarTranslucent={this.props.statusBarTranslucent}
navigationBarTranslucent={this.props.navigationBarTranslucent}
identifier={this._identifier}
style={styles.modal}
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
@@ -50,7 +50,7 @@ Pod::Spec.new do |s|
s.dependency "React-jsi"
s.dependency "React-Core/RCTAnimationHeaders"
add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"])
add_dependency(s, "React-RCTFBReactNativeSpec")
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
add_dependency(s, "React-NativeModulesApple")
end
@@ -50,7 +50,7 @@ Pod::Spec.new do |s|
s.dependency "React-jsi"
s.dependency "React-Core/RCTNetworkHeaders"
add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"])
add_dependency(s, "React-RCTFBReactNativeSpec")
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"])
end
@@ -66,11 +66,58 @@ export interface PermissionsAndroidStatic {
/**
* A list of permission results that are returned
*/
RESULTS: {[key: string]: PermissionStatus};
RESULTS: {
[key in 'GRANTED' | 'DENIED' | 'NEVER_ASK_AGAIN']: PermissionStatus;
};
/**
* A list of specified "dangerous" permissions that require prompting the user
*/
PERMISSIONS: {[key: string]: Permission};
PERMISSIONS: {
[key in
| 'READ_CALENDAR'
| 'WRITE_CALENDAR'
| 'CAMERA'
| 'READ_CONTACTS'
| 'WRITE_CONTACTS'
| 'GET_ACCOUNTS'
| 'ACCESS_FINE_LOCATION'
| 'ACCESS_COARSE_LOCATION'
| 'ACCESS_BACKGROUND_LOCATION'
| 'RECORD_AUDIO'
| 'READ_PHONE_STATE'
| 'CALL_PHONE'
| 'READ_CALL_LOG'
| 'WRITE_CALL_LOG'
| 'ADD_VOICEMAIL'
| 'READ_VOICEMAIL'
| 'WRITE_VOICEMAIL'
| 'USE_SIP'
| 'PROCESS_OUTGOING_CALLS'
| 'BODY_SENSORS'
| 'BODY_SENSORS_BACKGROUND'
| 'SEND_SMS'
| 'RECEIVE_SMS'
| 'READ_SMS'
| 'RECEIVE_WAP_PUSH'
| 'RECEIVE_MMS'
| 'READ_EXTERNAL_STORAGE'
| 'READ_MEDIA_IMAGES'
| 'READ_MEDIA_VIDEO'
| 'READ_MEDIA_AUDIO'
| 'READ_MEDIA_VISUAL_USER_SELECTED'
| 'WRITE_EXTERNAL_STORAGE'
| 'BLUETOOTH_CONNECT'
| 'BLUETOOTH_SCAN'
| 'BLUETOOTH_ADVERTISE'
| 'ACCESS_MEDIA_LOCATION'
| 'ACCEPT_HANDOVER'
| 'ACTIVITY_RECOGNITION'
| 'ANSWER_PHONE_CALLS'
| 'READ_PHONE_NUMBERS'
| 'UWB_RANGING'
| 'POST_NOTIFICATIONS'
| 'NEARBY_WIFI_DEVICES']: Permission;
};
new (): PermissionsAndroidStatic;
/**
* @deprecated Use check instead
@@ -50,7 +50,7 @@ Pod::Spec.new do |s|
s.dependency "React-Core/RCTPushNotificationHeaders"
s.dependency "React-jsi"
add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"])
add_dependency(s, "React-RCTFBReactNativeSpec")
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
add_dependency(s, "React-NativeModulesApple")
end
@@ -1,17 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
const createReactNativeComponentClass = require('../Renderer/shims/createReactNativeComponentClass');
module.exports = {
createReactNativeComponentClass,
};
@@ -50,7 +50,7 @@ Pod::Spec.new do |s|
s.dependency "React-jsi"
s.dependency "React-Core/RCTSettingsHeaders"
add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"])
add_dependency(s, "React-RCTFBReactNativeSpec")
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"])
end
@@ -10,8 +10,6 @@
'use strict';
module.exports = require('../Components/UnimplementedViews/UnimplementedView');
type BackPressEventName = 'backPress' | 'hardwareBackPress';
function emptyFunction(): void {}
@@ -50,7 +50,7 @@ Pod::Spec.new do |s|
s.dependency "React-jsi"
s.dependency "React-Core/RCTVibrationHeaders"
add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"])
add_dependency(s, "React-RCTFBReactNativeSpec")
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
add_dependency(s, "React-NativeModulesApple")
end
@@ -707,7 +707,7 @@ declare export default typeof AnimatedScrollView;
exports[`public API should not change unintentionally Libraries/Animated/components/AnimatedSectionList.js 1`] = `
"declare export default AnimatedComponentType<
React.ElementConfig<typeof SectionList>,
React.ElementRef<typeof SectionList>,
SectionList<SectionBase<any>>,
>;
"
`;
@@ -2042,7 +2042,7 @@ exports[`public API should not change unintentionally Libraries/Components/Scrol
export type DecelerationRateType = \\"fast\\" | \\"normal\\" | number;
export type ScrollResponderType = ScrollViewImperativeMethods;
type PublicScrollViewInstance = $ReadOnly<{|
...$Exact<TScrollViewNativeComponentInstance>,
...HostInstance,
...ScrollViewImperativeMethods,
|}>;
type InnerViewInstance = React.ElementRef<View>;
@@ -2169,7 +2169,7 @@ declare class ScrollView extends React.Component<Props, State> {
getScrollableNode: () => ?number;
getInnerViewNode: () => ?number;
getInnerViewRef: () => InnerViewInstance | null;
getNativeScrollRef: () => TScrollViewNativeComponentInstance | null;
getNativeScrollRef: () => HostInstance | null;
scrollTo: (
options?:
| {
@@ -2184,9 +2184,6 @@ declare class ScrollView extends React.Component<Props, State> {
) => void;
scrollToEnd: (options?: ?{ animated?: boolean, ... }) => void;
flashScrollIndicators: () => void;
_subscribeToOnScroll: (
callback: ({ x: number, y: number }) => void
) => EventSubscription;
scrollResponderScrollNativeHandleToKeyboard: (
nodeHandle: number | HostInstance,
additionalOffset?: number,
@@ -2224,10 +2221,7 @@ declare class ScrollView extends React.Component<Props, State> {
_handleLayout: $FlowFixMe;
_handleContentOnLayout: $FlowFixMe;
_innerView: RefForwarder<InnerViewInstance, InnerViewInstance>;
_scrollView: RefForwarder<
TScrollViewNativeImperativeHandle,
PublicScrollViewInstance | null,
>;
_scrollView: RefForwarder<HostInstance, PublicScrollViewInstance | null>;
scrollResponderKeyboardWillShow: (e: KeyboardEvent) => void;
scrollResponderKeyboardWillHide: (e: KeyboardEvent) => void;
scrollResponderKeyboardDidShow: (e: KeyboardEvent) => void;
@@ -5341,7 +5335,41 @@ declare const InteractionManager: {
addListener: $FlowFixMe,
setDeadline(deadline: number): void,
};
declare module.exports: InteractionManager;
declare module.exports: typeof InteractionManager;
"
`;
exports[`public API should not change unintentionally Libraries/Interaction/InteractionManagerStub.js 1`] = `
"export type Handle = number;
type Task =
| {
name: string,
run: () => void,
}
| {
name: string,
gen: () => Promise<void>,
}
| (() => void);
declare const InteractionManagerStub: {
Events: {
interactionStart: \\"interactionStart\\",
interactionComplete: \\"interactionComplete\\",
},
runAfterInteractions(task: ?Task): {
then: <U>(
onFulfill?: ?(void) => ?(Promise<U> | U),
onReject?: ?(error: mixed) => ?(Promise<U> | U)
) => Promise<U>,
cancel: () => void,
...
},
createInteractionHandle(): Handle,
clearInteractionHandle(handle: Handle): void,
addListener(): EventSubscription,
setDeadline(deadline: number): void,
};
declare module.exports: InteractionManagerStub;
"
`;
@@ -6411,6 +6439,7 @@ export type Props = $ReadOnly<{|
),
transparent?: ?boolean,
statusBarTranslucent?: ?boolean,
navigationBarTranslucent?: ?boolean,
hardwareAccelerated?: ?boolean,
visible?: ?boolean,
onRequestClose?: ?DirectEventHandler<null>,
@@ -7525,14 +7554,6 @@ declare module.exports: UIManagerJS;
"
`;
exports[`public API should not change unintentionally Libraries/ReactNative/ReactFabricInternals.js 1`] = `
"declare const createReactNativeComponentClass: $FlowFixMe;
declare module.exports: {
createReactNativeComponentClass: createReactNativeComponentClass,
};
"
`;
exports[`public API should not change unintentionally Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricHostComponent.js 1`] = `
"declare export default class ReactFabricHostComponent
implements INativeMethods
@@ -155,7 +155,7 @@ RCT_EXPORT_METHOD(reportException : (JS::NativeExceptionsManager::ExceptionData
NSArray<NSDictionary<NSString *, id> *> *stack = errorData[@"stack"];
double exceptionId = [errorData[@"id"] doubleValue];
if (errorData[@"isFatal"]) {
if ([errorData[@"isFatal"] boolValue]) {
[self reportFatal:message stack:stack exceptionId:exceptionId extraDataAsJSON:extraDataAsJSON];
} else {
[self reportSoft:message stack:stack exceptionId:exceptionId extraDataAsJSON:extraDataAsJSON];
@@ -71,7 +71,7 @@ Pod::Spec.new do |s|
s.dependency "SocketRocket", socket_rocket_version
add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern')
add_dependency(s, "ReactCodegen")
add_dependency(s, "React-RCTFBReactNativeSpec")
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
add_dependency(s, "React-NativeModulesApple")
end
@@ -618,31 +618,18 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
const auto &props = static_cast<const ScrollViewProps &>(*_props);
auto scrollMetrics = [self _scrollViewMetrics];
if (props.enableSyncOnScroll) {
[self _updateStateWithContentOffset];
NSTimeInterval now = CACurrentMediaTime();
if ((_lastScrollEventDispatchTime == 0) || (now - _lastScrollEventDispatchTime > _scrollEventThrottle)) {
_lastScrollEventDispatchTime = now;
if (_eventEmitter) {
const auto &eventEmitter = static_cast<const ScrollViewEventEmitter &>(*_eventEmitter);
// TODO: temporary API to unblock testing of synchronous rendering.
eventEmitter.experimental_flushSync([&eventEmitter, &scrollMetrics, &self]() {
[self _updateStateWithContentOffset];
// TODO: temporary API to unblock testing of synchronous rendering.
eventEmitter.experimental_onDiscreteScroll(scrollMetrics);
});
static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScroll(scrollMetrics);
}
} else {
[self _updateStateWithContentOffset];
NSTimeInterval now = CACurrentMediaTime();
if ((_lastScrollEventDispatchTime == 0) || (now - _lastScrollEventDispatchTime > _scrollEventThrottle)) {
_lastScrollEventDispatchTime = now;
if (_eventEmitter) {
static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onScroll(scrollMetrics);
}
RCTSendScrollEventForNativeAnimations_DEPRECATED(scrollView, self.tag, kOnScrollEvent);
}
RCTSendScrollEventForNativeAnimations_DEPRECATED(scrollView, self.tag, kOnScrollEvent);
}
[self _remountChildrenIfNeeded];
@@ -0,0 +1,87 @@
# 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.
require "json"
# This Podspec wraps the code generated by Codegen that defines all the interfaces for the
# internal Native Modules that React Native depends on.
package = JSON.parse(File.read(File.join(__dir__, "..", "package.json")))
version = package['version']
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
else
source[:tag] = "v#{version}"
end
module_name = "FBReactNativeSpec"
header_dir = "FBReactNativeSpec"
folly_config = get_folly_config()
folly_compiler_flags = folly_config[:compiler_flags]
folly_version = folly_config[:version]
boost_config = get_boost_config()
boost_compiler_flags = boost_config[:compiler_flags]
new_arch_flags = ENV['RCT_NEW_ARCH_ENABLED'] == '1' ? ' -DRCT_NEW_ARCH_ENABLED=1' : ''
header_search_paths = [
"\"$(PODS_ROOT)/RCT-Folly\"",
]
Pod::Spec.new do |s|
s.name = "React-RCTFBReactNativeSpec"
s.version = version
s.summary = "FBReactNativeSpec for React Native."
s.homepage = "https://reactnative.dev/"
s.license = package["license"]
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = min_supported_versions
s.source = source
s.source_files = "FBReactNativeSpec/**/*.{c,h,m,mm,S,cpp}"
s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags + new_arch_flags
s.header_dir = header_dir
s.module_name = module_name
s.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => header_search_paths,
"OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags + new_arch_flags,
"CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard()
}
s.dependency "React-jsi"
s.dependency "React-jsiexecutor"
s.dependency "RCT-Folly"
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "React-Core"
s.dependency "React-NativeModulesApple"
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
add_dependency(s, "ReactCommon", :subspec => "turbomodule/bridging", :additional_framework_paths => ["react/nativemodule/bridging"])
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
else
s.dependency "React-jsc"
end
s.script_phases = [
{
:name => '[RN]Check FBReactNativeSpec',
:execution_position => :before_compile,
:script => <<-EOS
echo "Checking whether Codegen has run..."
fbReactNativeSpecPath="$REACT_NATIVE_PATH/React/FBReactNativeSpec"
if [[ ! -d "$fbReactNativeSpecPath" ]]; then
echo 'error: Codegen did not run properly in your project. Please reinstall cocoapods with `bundle exec pod install`.'
exit 1
fi
EOS
}
]
end
@@ -926,12 +926,14 @@ public class com/facebook/react/bridge/JavaOnlyArray : com/facebook/react/bridge
public fun toString ()Ljava/lang/String;
}
public class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/ReadableMap, com/facebook/react/bridge/WritableMap {
public final class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/ReadableMap, com/facebook/react/bridge/WritableMap {
public static final field Companion Lcom/facebook/react/bridge/JavaOnlyMap$Companion;
public fun <init> ()V
public synthetic fun <init> ([Ljava/lang/Object;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun copy ()Lcom/facebook/react/bridge/WritableMap;
public static fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap;
public static final fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap;
public fun equals (Ljava/lang/Object;)Z
public static fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap;
public static final fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap;
public fun getArray (Ljava/lang/String;)Lcom/facebook/react/bridge/ReadableArray;
public fun getBoolean (Ljava/lang/String;)Z
public fun getDouble (Ljava/lang/String;)D
@@ -947,7 +949,7 @@ public class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/R
public fun isNull (Ljava/lang/String;)Z
public fun keySetIterator ()Lcom/facebook/react/bridge/ReadableMapKeySetIterator;
public fun merge (Lcom/facebook/react/bridge/ReadableMap;)V
public static fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap;
public static final fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap;
public fun putArray (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
public fun putBoolean (Ljava/lang/String;Z)V
public fun putDouble (Ljava/lang/String;D)V
@@ -956,11 +958,17 @@ public class com/facebook/react/bridge/JavaOnlyMap : com/facebook/react/bridge/R
public fun putMap (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableMap;)V
public fun putNull (Ljava/lang/String;)V
public fun putString (Ljava/lang/String;Ljava/lang/String;)V
public fun remove (Ljava/lang/String;)V
public final fun remove (Ljava/lang/String;)V
public fun toHashMap ()Ljava/util/HashMap;
public fun toString ()Ljava/lang/String;
}
public final class com/facebook/react/bridge/JavaOnlyMap$Companion {
public final fun deepClone (Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/JavaOnlyMap;
public final fun from (Ljava/util/Map;)Lcom/facebook/react/bridge/JavaOnlyMap;
public final fun of ([Ljava/lang/Object;)Lcom/facebook/react/bridge/JavaOnlyMap;
}
public class com/facebook/react/bridge/JavaScriptContextHolder {
public fun <init> (J)V
public fun clear ()V
@@ -1555,7 +1563,7 @@ public abstract interface class com/facebook/react/bridge/UIManager : com/facebo
public abstract fun addUIManagerEventListener (Lcom/facebook/react/bridge/UIManagerListener;)V
public abstract fun dispatchCommand (IILcom/facebook/react/bridge/ReadableArray;)V
public abstract fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
public abstract fun getEventDispatcher ()Ljava/lang/Object;
public abstract fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher;
public abstract fun initialize ()V
public abstract fun invalidate ()V
public abstract fun markActiveTouchForTag (II)V
@@ -1907,19 +1915,6 @@ public final class com/facebook/react/common/build/ReactBuildConfig {
public static final field IS_INTERNAL_BUILD Z
}
public final class com/facebook/react/common/futures/SimpleSettableFuture : java/util/concurrent/Future {
public fun <init> ()V
public fun cancel (Z)Z
public fun get ()Ljava/lang/Object;
public fun get (JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object;
public final fun getOrThrow ()Ljava/lang/Object;
public final fun getOrThrow (JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object;
public fun isCancelled ()Z
public fun isDone ()Z
public final fun set (Ljava/lang/Object;)V
public final fun setException (Ljava/lang/Exception;)V
}
public abstract interface class com/facebook/react/common/mapbuffer/MapBuffer : java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker {
public static final field Companion Lcom/facebook/react/common/mapbuffer/MapBuffer$Companion;
public abstract fun contains (I)Z
@@ -2014,11 +2009,6 @@ public final class com/facebook/react/common/mapbuffer/WritableMapBuffer : com/f
public final fun put (IZ)Lcom/facebook/react/common/mapbuffer/WritableMapBuffer;
}
public final class com/facebook/react/common/network/OkHttpCallUtil {
public static final field INSTANCE Lcom/facebook/react/common/network/OkHttpCallUtil;
public static final fun cancelTag (Lokhttp3/OkHttpClient;Ljava/lang/Object;)V
}
public final class com/facebook/react/config/ReactFeatureFlags {
public static final field INSTANCE Lcom/facebook/react/config/ReactFeatureFlags;
public static field dispatchPointerEvents Z
@@ -2633,7 +2623,6 @@ public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/brid
public fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
public fun getColor (I[Ljava/lang/String;)I
public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher;
public synthetic fun getEventDispatcher ()Ljava/lang/Object;
public fun getInspectorDataForInstance (ILandroid/view/View;)Lcom/facebook/react/bridge/ReadableMap;
public fun getPerformanceCounters ()Ljava/util/Map;
public fun getThemeData (I[F)Z
@@ -3056,27 +3045,6 @@ public class com/facebook/react/modules/blob/FileReaderModule : com/facebook/fbr
public fun readAsText (Lcom/facebook/react/bridge/ReadableMap;Ljava/lang/String;Lcom/facebook/react/bridge/Promise;)V
}
public final class com/facebook/react/modules/camera/ImageStoreManager : com/facebook/fbreact/specs/NativeImageStoreAndroidSpec {
public static final field Companion Lcom/facebook/react/modules/camera/ImageStoreManager$Companion;
public static final field NAME Ljava/lang/String;
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;)V
public fun getBase64ForTag (Ljava/lang/String;Lcom/facebook/react/bridge/Callback;Lcom/facebook/react/bridge/Callback;)V
}
public final class com/facebook/react/modules/camera/ImageStoreManager$Companion {
}
public final class com/facebook/react/modules/clipboard/ClipboardModule : com/facebook/fbreact/specs/NativeClipboardSpec {
public static final field Companion Lcom/facebook/react/modules/clipboard/ClipboardModule$Companion;
public static final field NAME Ljava/lang/String;
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;)V
public fun getString (Lcom/facebook/react/bridge/Promise;)V
public fun setString (Ljava/lang/String;)V
}
public final class com/facebook/react/modules/clipboard/ClipboardModule$Companion {
}
public final class com/facebook/react/modules/common/ModuleDataCleaner {
public static final field INSTANCE Lcom/facebook/react/modules/common/ModuleDataCleaner;
public static final fun cleanDataFromModules (Lcom/facebook/react/bridge/ReactContext;)V
@@ -5178,7 +5146,6 @@ public class com/facebook/react/uimanager/UIManagerModule : com/facebook/react/b
public fun getDefaultEventTypes ()Lcom/facebook/react/bridge/WritableMap;
public fun getDirectEventNamesResolver ()Lcom/facebook/react/uimanager/UIManagerModule$CustomEventNamesResolver;
public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher;
public synthetic fun getEventDispatcher ()Ljava/lang/Object;
public fun getName ()Ljava/lang/String;
public fun getPerformanceCounters ()Ljava/util/Map;
public fun getUIImplementation ()Lcom/facebook/react/uimanager/UIImplementation;
@@ -6128,15 +6095,15 @@ public final class com/facebook/react/uimanager/style/Overflow$Companion {
public final fun fromString (Ljava/lang/String;)Lcom/facebook/react/uimanager/style/Overflow;
}
public class com/facebook/react/uimanager/util/ReactFindViewUtil {
public fun <init> ()V
public static fun addViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V
public static fun addViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;Ljava/util/Set;)V
public static fun findView (Landroid/view/View;Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V
public static fun findView (Landroid/view/View;Ljava/lang/String;)Landroid/view/View;
public static fun notifyViewRendered (Landroid/view/View;)V
public static fun removeViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V
public static fun removeViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;)V
public final class com/facebook/react/uimanager/util/ReactFindViewUtil {
public static final field INSTANCE Lcom/facebook/react/uimanager/util/ReactFindViewUtil;
public static final fun addViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V
public static final fun addViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;Ljava/util/Set;)V
public static final fun findView (Landroid/view/View;Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V
public static final fun findView (Landroid/view/View;Ljava/lang/String;)Landroid/view/View;
public static final fun notifyViewRendered (Landroid/view/View;)V
public static final fun removeViewListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnViewFoundListener;)V
public static final fun removeViewsListener (Lcom/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener;)V
}
public abstract interface class com/facebook/react/uimanager/util/ReactFindViewUtil$OnMultipleViewsFoundListener {
@@ -6293,6 +6260,7 @@ public abstract interface class com/facebook/react/viewmanagers/ModalHostViewMan
public abstract fun setAnimationType (Landroid/view/View;Ljava/lang/String;)V
public abstract fun setHardwareAccelerated (Landroid/view/View;Z)V
public abstract fun setIdentifier (Landroid/view/View;I)V
public abstract fun setNavigationBarTranslucent (Landroid/view/View;Z)V
public abstract fun setPresentationStyle (Landroid/view/View;Ljava/lang/String;)V
public abstract fun setStatusBarTranslucent (Landroid/view/View;Z)V
public abstract fun setSupportedOrientations (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V
@@ -6676,6 +6644,8 @@ public final class com/facebook/react/views/modal/ReactModalHostManager : com/fa
public fun setHardwareAccelerated (Lcom/facebook/react/views/modal/ReactModalHostView;Z)V
public synthetic fun setIdentifier (Landroid/view/View;I)V
public fun setIdentifier (Lcom/facebook/react/views/modal/ReactModalHostView;I)V
public synthetic fun setNavigationBarTranslucent (Landroid/view/View;Z)V
public fun setNavigationBarTranslucent (Lcom/facebook/react/views/modal/ReactModalHostView;Z)V
public synthetic fun setPresentationStyle (Landroid/view/View;Ljava/lang/String;)V
public fun setPresentationStyle (Lcom/facebook/react/views/modal/ReactModalHostView;Ljava/lang/String;)V
public synthetic fun setStatusBarTranslucent (Landroid/view/View;Z)V
@@ -6704,6 +6674,7 @@ public final class com/facebook/react/views/modal/ReactModalHostView : android/v
public fun getChildCount ()I
public final fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher;
public final fun getHardwareAccelerated ()Z
public final fun getNavigationBarTranslucent ()Z
public final fun getOnRequestCloseListener ()Lcom/facebook/react/views/modal/ReactModalHostView$OnRequestCloseListener;
public final fun getOnShowListener ()Landroid/content/DialogInterface$OnShowListener;
public final fun getStateWrapper ()Lcom/facebook/react/uimanager/StateWrapper;
@@ -6719,6 +6690,7 @@ public final class com/facebook/react/views/modal/ReactModalHostView : android/v
public final fun setEventDispatcher (Lcom/facebook/react/uimanager/events/EventDispatcher;)V
public final fun setHardwareAccelerated (Z)V
public fun setId (I)V
public final fun setNavigationBarTranslucent (Z)V
public final fun setOnRequestCloseListener (Lcom/facebook/react/views/modal/ReactModalHostView$OnRequestCloseListener;)V
public final fun setOnShowListener (Landroid/content/DialogInterface$OnShowListener;)V
public final fun setStateWrapper (Lcom/facebook/react/uimanager/StateWrapper;)V
@@ -6743,51 +6715,6 @@ public abstract interface class com/facebook/react/views/modal/ReactModalHostVie
public abstract fun onRequestClose (Landroid/content/DialogInterface;)V
}
public final class com/facebook/react/views/progressbar/ProgressBarContainerView : android/widget/FrameLayout {
public static final field MAX_PROGRESS I
public fun <init> (Landroid/content/Context;)V
}
public final class com/facebook/react/views/progressbar/ProgressBarShadowNode : com/facebook/react/uimanager/LayoutShadowNode, com/facebook/yoga/YogaMeasureFunction {
public fun <init> ()V
public final fun getStyle ()Ljava/lang/String;
public fun measure (Lcom/facebook/yoga/YogaNode;FLcom/facebook/yoga/YogaMeasureMode;FLcom/facebook/yoga/YogaMeasureMode;)J
public final fun setStyle (Ljava/lang/String;)V
}
public final class com/facebook/react/views/progressbar/ReactProgressBarViewManager : com/facebook/react/uimanager/BaseViewManager, com/facebook/react/viewmanagers/AndroidProgressBarManagerInterface {
public static final field Companion Lcom/facebook/react/views/progressbar/ReactProgressBarViewManager$Companion;
public static final field REACT_CLASS Ljava/lang/String;
public fun <init> ()V
public synthetic fun createShadowNodeInstance ()Lcom/facebook/react/uimanager/ReactShadowNode;
public fun createShadowNodeInstance ()Lcom/facebook/react/views/progressbar/ProgressBarShadowNode;
public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View;
public fun getName ()Ljava/lang/String;
public fun getShadowNodeClass ()Ljava/lang/Class;
public fun measure (Landroid/content/Context;Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/ReadableMap;FLcom/facebook/yoga/YogaMeasureMode;FLcom/facebook/yoga/YogaMeasureMode;[F)J
public synthetic fun onAfterUpdateTransaction (Landroid/view/View;)V
public synthetic fun setAnimating (Landroid/view/View;Z)V
public fun setAnimating (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Z)V
public synthetic fun setColor (Landroid/view/View;Ljava/lang/Integer;)V
public fun setColor (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/Integer;)V
public synthetic fun setIndeterminate (Landroid/view/View;Z)V
public fun setIndeterminate (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Z)V
public synthetic fun setProgress (Landroid/view/View;D)V
public fun setProgress (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;D)V
public synthetic fun setStyleAttr (Landroid/view/View;Ljava/lang/String;)V
public fun setStyleAttr (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/String;)V
public synthetic fun setTestID (Landroid/view/View;Ljava/lang/String;)V
public fun setTestID (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/String;)V
public synthetic fun setTypeAttr (Landroid/view/View;Ljava/lang/String;)V
public fun setTypeAttr (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/String;)V
public synthetic fun updateExtraData (Landroid/view/View;Ljava/lang/Object;)V
public fun updateExtraData (Lcom/facebook/react/views/progressbar/ProgressBarContainerView;Ljava/lang/Object;)V
}
public final class com/facebook/react/views/progressbar/ReactProgressBarViewManager$Companion {
public final fun createProgressBar (Landroid/content/Context;I)Landroid/widget/ProgressBar;
}
public abstract interface class com/facebook/react/views/scroll/FpsListener {
public abstract fun disable (Ljava/lang/String;)V
public abstract fun enable (Ljava/lang/String;)V
@@ -6801,16 +6728,14 @@ public final class com/facebook/react/views/scroll/OnScrollDispatchHelper {
public final fun onScrollChanged (II)Z
}
public final class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager : com/facebook/react/views/view/ReactViewManager, com/facebook/react/viewmanagers/AndroidHorizontalScrollContentViewManagerInterface {
public final class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager : com/facebook/react/views/view/ReactViewManager {
public static final field Companion Lcom/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager$Companion;
public static final field REACT_CLASS Ljava/lang/String;
public fun <init> ()V
public synthetic fun createViewInstance (ILcom/facebook/react/uimanager/ThemedReactContext;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Landroid/view/View;
public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View;
public fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Lcom/facebook/react/views/view/ReactViewGroup;
public fun getDelegate ()Lcom/facebook/react/uimanager/ViewManagerDelegate;
public fun getName ()Ljava/lang/String;
public synthetic fun setRemoveClippedSubviews (Landroid/view/View;Z)V
}
public final class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager$Companion {
@@ -6869,7 +6794,6 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollView : android
public fun setBorderWidth (IF)V
public fun setDecelerationRate (F)V
public fun setDisableIntervalMomentum (Z)V
public fun setEnableSyncOnScroll (Z)V
public fun setEndFillColor (I)V
public fun setLastScrollDispatchTime (J)V
public fun setMaintainVisibleContentPosition (Lcom/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper$Config;)V
@@ -6917,7 +6841,6 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollViewManager :
public fun setContentOffset (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Lcom/facebook/react/bridge/ReadableMap;)V
public fun setDecelerationRate (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;F)V
public fun setDisableIntervalMomentum (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Z)V
public fun setEnableSyncOnScroll (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Z)V
public fun setFadingEdgeLength (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;I)V
public fun setHorizontal (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Z)V
public fun setMaintainVisibleContentPosition (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Lcom/facebook/react/bridge/ReadableMap;)V
@@ -6992,7 +6915,6 @@ public class com/facebook/react/views/scroll/ReactScrollView : android/widget/Sc
public fun setContentOffset (Lcom/facebook/react/bridge/ReadableMap;)V
public fun setDecelerationRate (F)V
public fun setDisableIntervalMomentum (Z)V
public fun setEnableSyncOnScroll (Z)V
public fun setEndFillColor (I)V
public fun setLastScrollDispatchTime (J)V
public fun setMaintainVisibleContentPosition (Lcom/facebook/react/views/scroll/MaintainVisibleScrollPositionHelper$Config;)V
@@ -7074,7 +6996,6 @@ public final class com/facebook/react/views/scroll/ReactScrollViewHelper {
public static final fun updateFabricScrollState (Landroid/view/ViewGroup;)V
public final fun updateFabricScrollState (Landroid/view/ViewGroup;II)V
public static final fun updateStateOnScrollChanged (Landroid/view/ViewGroup;FF)V
public static final fun updateStateOnScrollChanged (Landroid/view/ViewGroup;FFZ)V
}
public abstract interface class com/facebook/react/views/scroll/ReactScrollViewHelper$HasFlingAnimator {
@@ -7157,7 +7078,6 @@ public class com/facebook/react/views/scroll/ReactScrollViewManager : com/facebo
public fun setContentOffset (Lcom/facebook/react/views/scroll/ReactScrollView;Lcom/facebook/react/bridge/ReadableMap;)V
public fun setDecelerationRate (Lcom/facebook/react/views/scroll/ReactScrollView;F)V
public fun setDisableIntervalMomentum (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V
public fun setEnableSyncOnScroll (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V
public fun setFadingEdgeLength (Lcom/facebook/react/views/scroll/ReactScrollView;I)V
public fun setHorizontal (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V
public fun setIsInvertedVirtualizedList (Lcom/facebook/react/views/scroll/ReactScrollView;Z)V
@@ -7187,13 +7107,13 @@ public final class com/facebook/react/views/scroll/ScrollEvent : com/facebook/re
public static final field Companion Lcom/facebook/react/views/scroll/ScrollEvent$Companion;
public fun canCoalesce ()Z
public fun getEventName ()Ljava/lang/String;
public static final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIIIZ)Lcom/facebook/react/views/scroll/ScrollEvent;
public static final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent;
public static final fun obtain (ILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent;
public fun onDispose ()V
}
public final class com/facebook/react/views/scroll/ScrollEvent$Companion {
public final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIIIZ)Lcom/facebook/react/views/scroll/ScrollEvent;
public final fun obtain (IILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent;
public final fun obtain (ILcom/facebook/react/views/scroll/ScrollEventType;FFFFIIII)Lcom/facebook/react/views/scroll/ScrollEvent;
}
@@ -7225,37 +7145,6 @@ public class com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout : and
public fun setRefreshing (Z)V
}
public class com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager : com/facebook/react/uimanager/ViewGroupManager, com/facebook/react/viewmanagers/AndroidSwipeRefreshLayoutManagerInterface {
public static final field REACT_CLASS Ljava/lang/String;
public fun <init> ()V
protected synthetic fun addEventEmitters (Lcom/facebook/react/uimanager/ThemedReactContext;Landroid/view/View;)V
protected fun addEventEmitters (Lcom/facebook/react/uimanager/ThemedReactContext;Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;)V
protected synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View;
protected fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;
protected fun getDelegate ()Lcom/facebook/react/uimanager/ViewManagerDelegate;
public fun getExportedCustomDirectEventTypeConstants ()Ljava/util/Map;
public fun getExportedViewConstants ()Ljava/util/Map;
public fun getName ()Ljava/lang/String;
public synthetic fun receiveCommand (Landroid/view/View;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
public fun receiveCommand (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V
public synthetic fun setColors (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V
public fun setColors (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Lcom/facebook/react/bridge/ReadableArray;)V
public synthetic fun setEnabled (Landroid/view/View;Z)V
public fun setEnabled (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Z)V
public synthetic fun setNativeRefreshing (Landroid/view/View;Z)V
public fun setNativeRefreshing (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Z)V
public synthetic fun setProgressBackgroundColor (Landroid/view/View;Ljava/lang/Integer;)V
public fun setProgressBackgroundColor (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Ljava/lang/Integer;)V
public synthetic fun setProgressViewOffset (Landroid/view/View;F)V
public fun setProgressViewOffset (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;F)V
public synthetic fun setRefreshing (Landroid/view/View;Z)V
public fun setRefreshing (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Z)V
public synthetic fun setSize (Landroid/view/View;Ljava/lang/String;)V
public fun setSize (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;I)V
public fun setSize (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Lcom/facebook/react/bridge/Dynamic;)V
public fun setSize (Lcom/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout;Ljava/lang/String;)V
}
public class com/facebook/react/views/switchview/ReactSwitchManager : com/facebook/react/uimanager/SimpleViewManager, com/facebook/react/viewmanagers/AndroidSwitchManagerInterface {
public static final field REACT_CLASS Ljava/lang/String;
public fun <init> ()V
@@ -7372,14 +7261,20 @@ public abstract class com/facebook/react/views/text/ReactBaseTextShadowNode : co
protected fun spannedFromShadowNode (Lcom/facebook/react/views/text/ReactBaseTextShadowNode;Ljava/lang/String;ZLcom/facebook/react/uimanager/NativeViewHierarchyOptimizer;)Landroid/text/Spannable;
}
public class com/facebook/react/views/text/ReactFontManager {
public fun addCustomFont (Landroid/content/Context;Ljava/lang/String;I)V
public fun addCustomFont (Ljava/lang/String;Landroid/graphics/Typeface;)V
public static fun getInstance ()Lcom/facebook/react/views/text/ReactFontManager;
public fun getTypeface (Ljava/lang/String;IILandroid/content/res/AssetManager;)Landroid/graphics/Typeface;
public fun getTypeface (Ljava/lang/String;ILandroid/content/res/AssetManager;)Landroid/graphics/Typeface;
public fun getTypeface (Ljava/lang/String;IZLandroid/content/res/AssetManager;)Landroid/graphics/Typeface;
public fun setTypeface (Ljava/lang/String;ILandroid/graphics/Typeface;)V
public final class com/facebook/react/views/text/ReactFontManager {
public static final field Companion Lcom/facebook/react/views/text/ReactFontManager$Companion;
public synthetic fun <init> (Lcom/facebook/react/views/text/ReactFontManager;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun addCustomFont (Landroid/content/Context;Ljava/lang/String;I)V
public final fun addCustomFont (Ljava/lang/String;Landroid/graphics/Typeface;)V
public static final fun getInstance ()Lcom/facebook/react/views/text/ReactFontManager;
public final fun getTypeface (Ljava/lang/String;IILandroid/content/res/AssetManager;)Landroid/graphics/Typeface;
public final fun getTypeface (Ljava/lang/String;ILandroid/content/res/AssetManager;)Landroid/graphics/Typeface;
public final fun getTypeface (Ljava/lang/String;IZLandroid/content/res/AssetManager;)Landroid/graphics/Typeface;
public final fun setTypeface (Ljava/lang/String;ILandroid/graphics/Typeface;)V
}
public final class com/facebook/react/views/text/ReactFontManager$Companion {
public final fun getInstance ()Lcom/facebook/react/views/text/ReactFontManager;
}
public class com/facebook/react/views/text/ReactRawTextManager : com/facebook/react/uimanager/ViewManager {
@@ -7678,15 +7573,21 @@ public class com/facebook/react/views/text/TextLayoutManager {
public final class com/facebook/react/views/text/TextTransform : java/lang/Enum {
public static final field CAPITALIZE Lcom/facebook/react/views/text/TextTransform;
public static final field Companion Lcom/facebook/react/views/text/TextTransform$Companion;
public static final field LOWERCASE Lcom/facebook/react/views/text/TextTransform;
public static final field NONE Lcom/facebook/react/views/text/TextTransform;
public static final field UNSET Lcom/facebook/react/views/text/TextTransform;
public static final field UPPERCASE Lcom/facebook/react/views/text/TextTransform;
public static fun apply (Ljava/lang/String;Lcom/facebook/react/views/text/TextTransform;)Ljava/lang/String;
public static final fun apply (Ljava/lang/String;Lcom/facebook/react/views/text/TextTransform;)Ljava/lang/String;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lcom/facebook/react/views/text/TextTransform;
public static fun values ()[Lcom/facebook/react/views/text/TextTransform;
}
public final class com/facebook/react/views/text/TextTransform$Companion {
public final fun apply (Ljava/lang/String;Lcom/facebook/react/views/text/TextTransform;)Ljava/lang/String;
}
public class com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageViewManager : com/facebook/react/uimanager/BaseViewManager {
public static final field REACT_CLASS Ljava/lang/String;
public fun <init> ()V
@@ -8035,5 +7936,6 @@ public final class com/facebook/react/views/view/ViewGroupClickEvent : com/faceb
public final class com/facebook/react/views/view/WindowUtilKt {
public static final fun setStatusBarTranslucency (Landroid/view/Window;Z)V
public static final fun setStatusBarVisibility (Landroid/view/Window;Z)V
public static final fun setSystemBarsTranslucency (Landroid/view/Window;Z)V
}
@@ -11,7 +11,9 @@ react.internal.disableJavaVersionAlignment=true
# We ignore:
# - BuildConfig classes because they are generated and not part of the public API
binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig
binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig,\
com.facebook.react.views.progressbar.ReactProgressBarViewManager$$PropsSetter,\
com.facebook.react.views.progressbar.ProgressBarShadowNode$$PropsSetter
binaryCompatibilityValidator.ignoredPackages=com.facebook.debug,\
com.facebook.fbreact,\
@@ -1,270 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.bridge;
import static androidx.core.util.Preconditions.checkNotNull;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Java {@link HashMap} backed implementation of {@link ReadableMap} and {@link WritableMap}
* Instances of this class SHOULD NOT be used for communication between java and JS, use instances
* of {@link WritableNativeMap} created via {@link Arguments#createMap} or just {@link ReadableMap}
* interface if you want your "native" module method to take a map from JS as an argument.
*
* <p>Main purpose for this class is to be used in java-only unit tests, but could also be used
* outside of tests in the code that operates only in java and needs to communicate with RN modules
* via their JS-exposed API.
*/
public class JavaOnlyMap implements ReadableMap, WritableMap {
private final Map mBackingMap;
public static JavaOnlyMap of(Object... keysAndValues) {
return new JavaOnlyMap(keysAndValues);
}
public static JavaOnlyMap from(Map<String, Object> map) {
return new JavaOnlyMap(map);
}
public static JavaOnlyMap deepClone(ReadableMap map) {
JavaOnlyMap res = new JavaOnlyMap();
ReadableMapKeySetIterator iter = map.keySetIterator();
while (iter.hasNextKey()) {
String propKey = iter.nextKey();
ReadableType type = map.getType(propKey);
switch (type) {
case Null:
res.putNull(propKey);
break;
case Boolean:
res.putBoolean(propKey, map.getBoolean(propKey));
break;
case Number:
res.putDouble(propKey, map.getDouble(propKey));
break;
case String:
res.putString(propKey, map.getString(propKey));
break;
case Map:
res.putMap(propKey, deepClone(map.getMap(propKey)));
break;
case Array:
res.putArray(propKey, JavaOnlyArray.deepClone(map.getArray(propKey)));
break;
}
}
return res;
}
/**
* @param keysAndValues keys and values, interleaved
*/
private JavaOnlyMap(Object... keysAndValues) {
if (keysAndValues.length % 2 != 0) {
throw new IllegalArgumentException("You must provide the same number of keys and values");
}
mBackingMap = new HashMap();
for (int i = 0; i < keysAndValues.length; i += 2) {
Object val = keysAndValues[i + 1];
if (val instanceof Number) {
// all values from JS are doubles, so emulate that here for tests.
val = ((Number) val).doubleValue();
}
mBackingMap.put(keysAndValues[i], val);
}
}
public JavaOnlyMap() {
mBackingMap = new HashMap();
}
@Override
public boolean hasKey(@NonNull String name) {
return mBackingMap.containsKey(name);
}
@Override
public boolean isNull(@NonNull String name) {
return mBackingMap.get(name) == null;
}
@Override
public boolean getBoolean(@NonNull String name) {
return (Boolean) mBackingMap.get(name);
}
@Override
public double getDouble(@NonNull String name) {
return ((Number) mBackingMap.get(name)).doubleValue();
}
@Override
public int getInt(@NonNull String name) {
return ((Number) mBackingMap.get(name)).intValue();
}
@Override
public long getLong(@NonNull String name) {
return ((Number) checkNotNull(mBackingMap.get(name))).longValue();
}
@Override
public String getString(@NonNull String name) {
return (String) mBackingMap.get(name);
}
@Override
public ReadableMap getMap(@NonNull String name) {
return (ReadableMap) mBackingMap.get(name);
}
@Override
public ReadableArray getArray(@NonNull String name) {
return (ReadableArray) mBackingMap.get(name);
}
@Override
public @NonNull Dynamic getDynamic(@NonNull String name) {
return DynamicFromMap.create(this, name);
}
@Override
public @NonNull ReadableType getType(@NonNull String name) {
Object value = mBackingMap.get(name);
if (value == null) {
return ReadableType.Null;
} else if (value instanceof Number) {
return ReadableType.Number;
} else if (value instanceof String) {
return ReadableType.String;
} else if (value instanceof Boolean) {
return ReadableType.Boolean;
} else if (value instanceof ReadableMap) {
return ReadableType.Map;
} else if (value instanceof ReadableArray) {
return ReadableType.Array;
} else if (value instanceof Dynamic) {
return ((Dynamic) value).getType();
} else {
throw new IllegalArgumentException(
"Invalid value " + value.toString() + " for key " + name + "contained in JavaOnlyMap");
}
}
@Override
public @NonNull Iterator<Map.Entry<String, Object>> getEntryIterator() {
return mBackingMap.entrySet().iterator();
}
@Override
public @NonNull ReadableMapKeySetIterator keySetIterator() {
return new ReadableMapKeySetIterator() {
Iterator<Map.Entry<String, Object>> mIterator = mBackingMap.entrySet().iterator();
@Override
public boolean hasNextKey() {
return mIterator.hasNext();
}
@Override
public String nextKey() {
return mIterator.next().getKey();
}
};
}
@Override
public void putBoolean(@NonNull String key, boolean value) {
mBackingMap.put(key, value);
}
@Override
public void putDouble(@NonNull String key, double value) {
mBackingMap.put(key, value);
}
@Override
public void putInt(@NonNull String key, int value) {
mBackingMap.put(key, new Double(value));
}
@Override
public void putLong(@NonNull String key, long value) {
mBackingMap.put(key, value);
}
@Override
public void putString(@NonNull String key, @Nullable String value) {
mBackingMap.put(key, value);
}
@Override
public void putNull(@NonNull String key) {
mBackingMap.put(key, null);
}
@Override
public void putMap(@NonNull String key, @Nullable ReadableMap value) {
mBackingMap.put(key, value);
}
@Override
public void merge(@NonNull ReadableMap source) {
mBackingMap.putAll(((JavaOnlyMap) source).mBackingMap);
}
@Override
public WritableMap copy() {
final JavaOnlyMap target = new JavaOnlyMap();
target.merge(this);
return target;
}
@Override
public void putArray(@NonNull String key, @Nullable ReadableArray value) {
mBackingMap.put(key, value);
}
@Override
public @NonNull HashMap<String, Object> toHashMap() {
return new HashMap<String, Object>(mBackingMap);
}
@Override
public String toString() {
return mBackingMap.toString();
}
public void remove(@NonNull String key) {
mBackingMap.remove(key);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
JavaOnlyMap that = (JavaOnlyMap) o;
if (mBackingMap != null ? !mBackingMap.equals(that.mBackingMap) : that.mBackingMap != null)
return false;
return true;
}
@Override
public int hashCode() {
return mBackingMap != null ? mBackingMap.hashCode() : 0;
}
}
@@ -0,0 +1,180 @@
/*
* 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
import java.util.HashMap
import kotlin.collections.Iterator
import kotlin.collections.Map
/**
* Java [HashMap] backed implementation of [ReadableMap] and [WritableMap] Instances of this class
* SHOULD NOT be used for communication between java and JS, use instances of [WritableNativeMap]
* created via [Arguments#createMap] or just [ReadableMap] interface if you want your "native"
* module method to take a map from JS as an argument.
*
* Main purpose for this class is to be used in java-only unit tests, but could also be used outside
* of tests in the code that operates only in java and needs to communicate with RN modules via
* their JS-exposed API.
*/
public class JavaOnlyMap() : ReadableMap, WritableMap {
public companion object {
@JvmStatic public fun of(vararg keysAndValues: Any?): JavaOnlyMap = JavaOnlyMap(*keysAndValues)
@JvmStatic public fun from(map: Map<String, Any?>): JavaOnlyMap = JavaOnlyMap(map)
@JvmStatic
public fun deepClone(map: ReadableMap?): JavaOnlyMap {
val res = JavaOnlyMap()
if (map == null) {
return res
}
val iter = map.keySetIterator()
while (iter.hasNextKey()) {
val propKey = iter.nextKey()
val type = map.getType(propKey)
when (type) {
ReadableType.Null -> res.putNull(propKey)
ReadableType.Boolean -> res.putBoolean(propKey, map.getBoolean(propKey))
ReadableType.Number -> res.putDouble(propKey, map.getDouble(propKey))
ReadableType.String -> res.putString(propKey, map.getString(propKey))
ReadableType.Map -> res.putMap(propKey, deepClone(map.getMap(propKey)))
ReadableType.Array ->
res.putArray(propKey, JavaOnlyArray.deepClone(map.getArray(propKey)))
}
}
return res
}
}
private val backingMap: MutableMap<String, Any?> = HashMap()
/** @param keysAndValues keys and values, interleaved */
private constructor(vararg keysAndValues: Any?) : this() {
require(keysAndValues.size % 2 == 0) { "You must provide the same number of keys and values" }
for (i in keysAndValues.indices step 2) {
var value = keysAndValues[i + 1]
if (value is Number) {
// all values from JS are doubles, so emulate that here for tests.
value = value.toDouble()
}
backingMap[keysAndValues[i] as String] = value
}
}
override fun hasKey(name: String): Boolean = backingMap.containsKey(name)
override fun isNull(name: String): Boolean = backingMap[name] == null
override fun getBoolean(name: String): Boolean = backingMap[name] as Boolean
override fun getDouble(name: String): Double = (backingMap[name] as Number).toDouble()
override fun getInt(name: String): Int = (backingMap[name] as Number).toInt()
override fun getLong(name: String): Long = (backingMap[name] as Number).toLong()
override fun getString(name: String): String? = backingMap[name] as String?
override fun getMap(name: String): ReadableMap? = backingMap[name] as ReadableMap?
override fun getArray(name: String): ReadableArray? = backingMap[name] as ReadableArray?
override fun getDynamic(name: String): Dynamic = DynamicFromMap.create(this, name)
override fun getType(name: String): ReadableType {
val value = backingMap[name]
return when {
value == null -> ReadableType.Null
value is Number -> ReadableType.Number
value is String -> ReadableType.String
value is Boolean -> ReadableType.Boolean
value is ReadableMap -> ReadableType.Map
value is ReadableArray -> ReadableType.Array
value is Dynamic -> value.type
else -> {
throw IllegalArgumentException(
"Invalid value $value for key $name contained in JavaOnlyMap")
}
}
}
override val entryIterator: Iterator<Map.Entry<String, Any?>>
get() = backingMap.entries.iterator()
override fun keySetIterator(): ReadableMapKeySetIterator {
return object : ReadableMapKeySetIterator {
private val iterator = backingMap.entries.iterator()
override fun hasNextKey(): Boolean = iterator.hasNext()
override fun nextKey(): String = iterator.next().key
}
}
override fun putBoolean(key: String, value: Boolean) {
backingMap[key] = value
}
override fun putDouble(key: String, value: Double) {
backingMap[key] = value
}
override fun putInt(key: String, value: Int) {
backingMap[key] = value.toDouble()
}
override fun putLong(key: String, value: Long) {
backingMap[key] = value.toDouble()
}
override fun putString(key: String, value: String?) {
backingMap[key] = value
}
override fun putNull(key: String) {
backingMap[key] = null
}
override fun putMap(key: String, value: ReadableMap?) {
backingMap[key] = value
}
override fun merge(source: ReadableMap) {
backingMap.putAll((source as JavaOnlyMap).backingMap)
}
override fun copy(): WritableMap {
val target = JavaOnlyMap()
target.merge(this)
return target
}
override fun putArray(key: String, value: ReadableArray?) {
backingMap[key] = value
}
public fun remove(key: String) {
backingMap.remove(key)
}
override fun toHashMap(): HashMap<String, Any?> = HashMap<String, Any?>(backingMap)
override fun toString(): String = backingMap.toString()
override fun equals(other: Any?): Boolean {
return if (this === other) {
true
} else if (other == null || javaClass != other.javaClass) {
false
} else {
backingMap == (other as JavaOnlyMap).backingMap
}
}
override fun hashCode(): Int = backingMap.hashCode()
}
@@ -16,7 +16,7 @@ import kotlin.collections.Map
* Kotlin.
*/
public interface ReadableMap {
public val entryIterator: Iterator<Map.Entry<String, Any>>
public val entryIterator: Iterator<Map.Entry<String, Any?>>
public fun getArray(name: String): ReadableArray?
@@ -42,5 +42,5 @@ public interface ReadableMap {
public fun keySetIterator(): ReadableMapKeySetIterator
public fun toHashMap(): HashMap<String, Any>
public fun toHashMap(): HashMap<String, Any?>
}
@@ -20,10 +20,10 @@ public open class ReadableNativeMap protected constructor() : NativeMap(), Reada
private val keys: Array<String> by
lazy(LazyThreadSafetyMode.SYNCHRONIZED) { importKeys().also { jniPassCounter++ } }
private val localMap: HashMap<String, Any> by
private val localMap: HashMap<String, Any?> by
lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
val length = keys.size
val res = HashMap<String, Any>(length)
val res = HashMap<String, Any?>(length)
val values = importValues()
jniPassCounter++
for (i in 0 until length) {
@@ -157,7 +157,7 @@ public open class ReadableNativeMap protected constructor() : NativeMap(), Reada
false
} else localMap == other.localMap
override fun toHashMap(): HashMap<String, Any> {
override fun toHashMap(): HashMap<String, Any?> {
// we can almost just return getLocalMap(), but we need to convert nested arrays and maps to the
// correct types first
val hashMap = HashMap(localMap)
@@ -12,6 +12,7 @@ import androidx.annotation.AnyThread
import androidx.annotation.UiThread
import com.facebook.infer.annotation.ThreadConfined
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.uimanager.events.EventDispatcher
@OptIn(UnstableReactNativeAPI::class)
public interface UIManager : PerformanceCounter {
@@ -78,7 +79,7 @@ public interface UIManager : PerformanceCounter {
public fun dispatchCommand(reactTag: Int, commandId: String, commandArgs: ReadableArray?)
/** @return the [EventDispatcher] object that is used by this class. */
public val eventDispatcher: Any?
public val eventDispatcher: EventDispatcher
/**
* Used by native animated module to bypass the process of updating the values through the shadow
@@ -17,7 +17,7 @@ import java.util.concurrent.TimeoutException
* A super simple Future-like class that can safely notify another Thread when a value is ready.
* Does not support canceling.
*/
public class SimpleSettableFuture<T> : Future<T?> {
internal class SimpleSettableFuture<T> : Future<T?> {
private val readyLatch = CountDownLatch(1)
private var result: T? = null
@@ -13,7 +13,7 @@ import okhttp3.OkHttpClient
/**
* Helper class that provides the necessary methods for canceling queued and running OkHttp calls
*/
public object OkHttpCallUtil {
internal object OkHttpCallUtil {
@JvmStatic
public fun cancelTag(client: OkHttpClient, tag: Any) {
// client.dispatcher is private, so we need to use reflection to access
@@ -22,7 +22,7 @@ import java.io.InputStream
import java.util.concurrent.Executors
@ReactModule(name = NativeImageStoreAndroidSpec.NAME)
public class ImageStoreManager(reactContext: ReactApplicationContext) :
internal class ImageStoreManager(reactContext: ReactApplicationContext) :
NativeImageStoreAndroidSpec(reactContext) {
/**
@@ -16,14 +16,14 @@ import com.facebook.react.module.annotations.ReactModule
/** A module that allows JS to get/set clipboard contents. */
@ReactModule(name = NativeClipboardSpec.NAME)
public class ClipboardModule(context: ReactApplicationContext) : NativeClipboardSpec(context) {
internal class ClipboardModule(context: ReactApplicationContext) : NativeClipboardSpec(context) {
private val clipboardService: ClipboardManager
get() =
getReactApplicationContext().getSystemService(ReactApplicationContext.CLIPBOARD_SERVICE)
as ClipboardManager
public override fun getString(promise: Promise) {
override fun getString(promise: Promise) {
try {
val clipboard = clipboardService
val clipData = clipboard.primaryClip
@@ -38,12 +38,12 @@ public class ClipboardModule(context: ReactApplicationContext) : NativeClipboard
}
}
public override fun setString(text: String?) {
override fun setString(text: String?) {
val clipdata: ClipData = ClipData.newPlainText(null, text)
clipboardService.setPrimaryClip(clipdata)
}
public companion object {
public const val NAME: String = NativeClipboardSpec.NAME
companion object {
const val NAME: String = NativeClipboardSpec.NAME
}
}
@@ -15,7 +15,9 @@ import android.net.Uri;
import android.nfc.NfcAdapter;
import android.provider.Settings;
import androidx.annotation.Nullable;
import androidx.core.util.Preconditions;
import com.facebook.fbreact.specs.NativeIntentAndroidSpec;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.Promise;
@@ -28,6 +30,7 @@ import java.util.ArrayList;
import java.util.List;
/** Intent module. Launch other activities or open URLs. */
@Nullsafe(Nullsafe.Mode.LOCAL)
@ReactModule(name = NativeIntentAndroidSpec.NAME)
public class IntentModule extends NativeIntentAndroidSpec {
@@ -124,7 +127,7 @@ public class IntentModule extends NativeIntentAndroidSpec {
* @param url the URL to open
*/
@Override
public void openURL(String url, Promise promise) {
public void openURL(@Nullable String url, Promise promise) {
if (url == null || url.isEmpty()) {
promise.reject(new JSApplicationIllegalArgumentException("Invalid URL: " + url));
return;
@@ -149,7 +152,7 @@ public class IntentModule extends NativeIntentAndroidSpec {
* @param promise a promise that is always resolved with a boolean argument
*/
@Override
public void canOpenURL(String url, Promise promise) {
public void canOpenURL(@Nullable String url, Promise promise) {
if (url == null || url.isEmpty()) {
promise.reject(new JSApplicationIllegalArgumentException("Invalid URL: " + url));
return;
@@ -160,8 +163,8 @@ public class IntentModule extends NativeIntentAndroidSpec {
// We need Intent.FLAG_ACTIVITY_NEW_TASK since getReactApplicationContext() returns
// the ApplicationContext instead of the Activity context.
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
boolean canOpen =
intent.resolveActivity(getReactApplicationContext().getPackageManager()) != null;
PackageManager packageManager = getReactApplicationContext().getPackageManager();
boolean canOpen = packageManager != null && intent.resolveActivity(packageManager) != null;
promise.resolve(canOpen);
} catch (Exception e) {
promise.reject(
@@ -179,7 +182,7 @@ public class IntentModule extends NativeIntentAndroidSpec {
public void openSettings(Promise promise) {
try {
Intent intent = new Intent();
Activity currentActivity = getCurrentActivity();
Activity currentActivity = Preconditions.checkNotNull(getCurrentActivity());
String selfPackageName = getReactApplicationContext().getPackageName();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
@@ -219,7 +222,7 @@ public class IntentModule extends NativeIntentAndroidSpec {
Intent intent = new Intent(action);
PackageManager packageManager = getReactApplicationContext().getPackageManager();
if (intent.resolveActivity(packageManager) == null) {
if (packageManager == null || intent.resolveActivity(packageManager) == null) {
promise.reject(
new JSApplicationIllegalArgumentException(
"Could not launch Intent with action " + action + "."));
@@ -235,6 +238,7 @@ public class IntentModule extends NativeIntentAndroidSpec {
switch (type) {
case String:
{
// NULLSAFE_FIXME[Parameter Not Nullable]
intent.putExtra(name, map.getString(EXTRA_MAP_KEY_FOR_VALUE));
break;
}
@@ -244,11 +248,13 @@ public class IntentModule extends NativeIntentAndroidSpec {
// See: https://github.com/facebook/react-native/issues/4141
// We might need to find a workaround if this is really an issue
Double number = map.getDouble(EXTRA_MAP_KEY_FOR_VALUE);
// NULLSAFE_FIXME[Parameter Not Nullable]
intent.putExtra(name, number);
break;
}
case Boolean:
{
// NULLSAFE_FIXME[Parameter Not Nullable]
intent.putExtra(name, map.getBoolean(EXTRA_MAP_KEY_FOR_VALUE));
break;
}
@@ -270,8 +276,13 @@ public class IntentModule extends NativeIntentAndroidSpec {
Activity currentActivity = getCurrentActivity();
String selfPackageName = getReactApplicationContext().getPackageName();
ComponentName componentName =
intent.resolveActivity(getReactApplicationContext().getPackageManager());
PackageManager packageManager = getReactApplicationContext().getPackageManager();
ComponentName componentName = null;
if (packageManager == null) {
componentName = intent.getComponent();
} else {
componentName = intent.resolveActivity(packageManager);
}
String otherPackageName = (componentName != null ? componentName.getPackageName() : "");
// If there is no currentActivity or we are launching to a different package we need to set
@@ -1,138 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uimanager.util;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** Finds views in React Native view hierarchies */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class ReactFindViewUtil {
private static final List<OnViewFoundListener> mOnViewFoundListeners = new ArrayList<>();
private static final Map<OnMultipleViewsFoundListener, Set<String>>
mOnMultipleViewsFoundListener = new HashMap<>();
/** Callback to be invoked when a react native view has been found */
public interface OnViewFoundListener {
/** Returns the native id of the view of interest */
String getNativeId();
/**
* Called when the view has been found
*
* @param view
*/
void onViewFound(View view);
}
/** Callback to be invoked when all react native views with geiven NativeIds have been found */
public interface OnMultipleViewsFoundListener {
void onViewFound(View view, String nativeId);
}
/**
* Finds a view that is tagged with {@param nativeId} as its nativeID prop under the {@param root}
* view hierarchy. Returns the view if found, null otherwise.
*
* @param root root of the view hierarchy from which to find the view
*/
public static @Nullable View findView(View root, String nativeId) {
String tag = getNativeId(root);
if (tag != null && tag.equals(nativeId)) {
return root;
}
if (root instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) root;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View view = findView(viewGroup.getChildAt(i), nativeId);
if (view != null) {
return view;
}
}
}
return null;
}
/**
* Finds a view tagged with {@param onViewFoundListener}'s nativeID in the given {@param root}
* view hierarchy. If the view does not exist yet due to React Native's async layout, a listener
* will be added. When the view is found, the {@param onViewFoundListener} will be invoked.
*
* @param root root of the view hierarchy from which to find the view
*/
public static void findView(View root, OnViewFoundListener onViewFoundListener) {
View view = findView(root, onViewFoundListener.getNativeId());
if (view != null) {
onViewFoundListener.onViewFound(view);
}
addViewListener(onViewFoundListener);
}
/**
* Registers an OnViewFoundListener to be invoked when a view with a matching nativeID is found.
* Remove this listener using removeViewListener() if it's no longer needed.
*/
public static void addViewListener(OnViewFoundListener onViewFoundListener) {
mOnViewFoundListeners.add(onViewFoundListener);
}
/** Removes an OnViewFoundListener previously registered with addViewListener(). */
public static void removeViewListener(OnViewFoundListener onViewFoundListener) {
mOnViewFoundListeners.remove(onViewFoundListener);
}
public static void addViewsListener(OnMultipleViewsFoundListener listener, Set<String> ids) {
mOnMultipleViewsFoundListener.put(listener, ids);
}
public static void removeViewsListener(OnMultipleViewsFoundListener listener) {
mOnMultipleViewsFoundListener.remove(listener);
}
/** Invokes any listeners that are listening on this {@param view}'s native id */
public static void notifyViewRendered(View view) {
String nativeId = getNativeId(view);
if (nativeId == null) {
return;
}
Iterator<OnViewFoundListener> iterator = mOnViewFoundListeners.iterator();
while (iterator.hasNext()) {
OnViewFoundListener listener = iterator.next();
if (nativeId.equals(listener.getNativeId())) {
listener.onViewFound(view);
iterator.remove();
}
}
for (Map.Entry<OnMultipleViewsFoundListener, Set<String>> entry :
mOnMultipleViewsFoundListener.entrySet()) {
Set<String> nativeIds = entry.getValue();
if (nativeIds != null && nativeIds.contains(nativeId)) {
entry.getKey().onViewFound(view, nativeId);
}
}
}
private static @Nullable String getNativeId(View view) {
Object tag = view.getTag(R.id.view_tag_native_id);
return tag instanceof String ? (String) tag : null;
}
}
@@ -0,0 +1,129 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uimanager.util
import android.view.View
import android.view.ViewGroup
import com.facebook.react.R
import java.util.ArrayList
import java.util.HashMap
/** Finds views in React Native view hierarchies */
public object ReactFindViewUtil {
private val onViewFoundListeners: MutableList<OnViewFoundListener> = ArrayList()
private val onMultipleViewsFoundListener: MutableMap<OnMultipleViewsFoundListener, Set<String>> =
HashMap()
/** Callback to be invoked when a react native view has been found */
public interface OnViewFoundListener {
/** Returns the native id of the view of interest */
public fun getNativeId(): String
/**
* Called when the view has been found
*
* @param view
*/
public fun onViewFound(view: View)
}
/** Callback to be invoked when all react native views with geiven NativeIds have been found */
public fun interface OnMultipleViewsFoundListener {
public fun onViewFound(view: View, nativeId: String)
}
/**
* Finds a view that is tagged with {@param nativeId} as its nativeID prop under the {@param root}
* view hierarchy. Returns the view if found, null otherwise.
*
* @param root root of the view hierarchy from which to find the view
*/
@JvmStatic
public fun findView(root: View, nativeId: String): View? {
if (getNativeId(root) == nativeId) {
return root
}
if (root is ViewGroup) {
for (i in 0..<root.childCount) {
val view = findView(root.getChildAt(i), nativeId)
if (view != null) {
return view
}
}
}
return null
}
/**
* Finds a view tagged with {@param onViewFoundListener}'s nativeID in the given {@param root}
* view hierarchy. If the view does not exist yet due to React Native's async layout, a listener
* will be added. When the view is found, the {@param onViewFoundListener} will be invoked.
*
* @param root root of the view hierarchy from which to find the view
*/
@JvmStatic
public fun findView(root: View, onViewFoundListener: OnViewFoundListener): Unit {
val view = findView(root, onViewFoundListener.getNativeId())
if (view != null) {
onViewFoundListener.onViewFound(view)
}
addViewListener(onViewFoundListener)
}
/**
* Registers an OnViewFoundListener to be invoked when a view with a matching nativeID is found.
* Remove this listener using removeViewListener() if it's no longer needed.
*/
@JvmStatic
public fun addViewListener(onViewFoundListener: OnViewFoundListener): Unit {
onViewFoundListeners.add(onViewFoundListener)
}
/** Removes an OnViewFoundListener previously registered with addViewListener(). */
@JvmStatic
public fun removeViewListener(onViewFoundListener: OnViewFoundListener): Unit {
onViewFoundListeners.remove(onViewFoundListener)
}
@JvmStatic
public fun addViewsListener(listener: OnMultipleViewsFoundListener, ids: Set<String>): Unit {
onMultipleViewsFoundListener[listener] = ids
}
@JvmStatic
public fun removeViewsListener(listener: OnMultipleViewsFoundListener): Unit {
onMultipleViewsFoundListener.remove(listener)
}
/** Invokes any listeners that are listening on this {@param view}'s native id */
@JvmStatic
public fun notifyViewRendered(view: View): Unit {
val nativeId = getNativeId(view) ?: return
val iterator = onViewFoundListeners.iterator()
while (iterator.hasNext()) {
val listener = iterator.next()
if (nativeId == listener.getNativeId()) {
listener.onViewFound(view)
iterator.remove()
}
}
onMultipleViewsFoundListener.forEach { (listener, nativeIds) ->
if (nativeId in nativeIds) {
listener.onViewFound(view, nativeId)
}
}
}
private fun getNativeId(view: View): String? {
val tag = view.getTag(R.id.view_tag_native_id)
return tag as? String
}
}
@@ -57,6 +57,14 @@ public class ReactModalHostManager :
view.statusBarTranslucent = statusBarTranslucent
}
@ReactProp(name = "navigationBarTranslucent")
public override fun setNavigationBarTranslucent(
view: ReactModalHostView,
navigationBarTranslucent: Boolean
) {
view.navigationBarTranslucent = navigationBarTranslucent
}
@ReactProp(name = "hardwareAccelerated")
public override fun setHardwareAccelerated(
view: ReactModalHostView,
@@ -48,6 +48,7 @@ import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.views.common.ContextUtils
import com.facebook.react.views.view.ReactViewGroup
import com.facebook.react.views.view.setStatusBarTranslucency
import com.facebook.react.views.view.setSystemBarsTranslucency
import java.util.Objects
/**
@@ -79,6 +80,12 @@ public class ReactModalHostView(context: ThemedReactContext) :
createNewDialog = true
}
public var navigationBarTranslucent: Boolean = false
set(value) {
field = value
createNewDialog = true
}
public var animationType: String? = null
set(value) {
field = value
@@ -335,7 +342,12 @@ public class ReactModalHostView(context: ThemedReactContext) :
}
}
dialogWindow.setStatusBarTranslucency(statusBarTranslucent)
// Navigation bar cannot be translucent without status bar being translucent too
dialogWindow.setSystemBarsTranslucency(navigationBarTranslucent)
if (!navigationBarTranslucent) {
dialogWindow.setStatusBarTranslucency(statusBarTranslucent)
}
if (transparent) {
dialogWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
@@ -18,7 +18,7 @@ import com.facebook.react.bridge.JSApplicationIllegalArgumentException
* Controls an enclosing [ProgressBar]. Exists so that the [ProgressBar] can be recreated if the
* style would change.
*/
public class ProgressBarContainerView(context: Context) : FrameLayout(context) {
internal class ProgressBarContainerView(context: Context) : FrameLayout(context) {
internal var color: Int? = null
internal var indeterminate = true
@@ -21,7 +21,7 @@ import com.facebook.yoga.YogaNode
* Node responsible for holding the style of the ProgressBar, see under [ ] for possible styles.
* ReactProgressBarViewManager manages how this style is applied to the ProgressBar.
*/
public class ProgressBarShadowNode : LayoutShadowNode(), YogaMeasureFunction {
internal class ProgressBarShadowNode : LayoutShadowNode(), YogaMeasureFunction {
private val height: SparseIntArray = SparseIntArray()
private val width: SparseIntArray = SparseIntArray()
private val measured: MutableSet<Int> = HashSet()
@@ -31,7 +31,7 @@ public class ProgressBarShadowNode : LayoutShadowNode(), YogaMeasureFunction {
}
@set:ReactProp(name = ReactProgressBarViewManager.PROP_STYLE)
public var style: String? = ReactProgressBarViewManager.DEFAULT_STYLE
var style: String? = ReactProgressBarViewManager.DEFAULT_STYLE
set(value) {
field = value ?: ReactProgressBarViewManager.DEFAULT_STYLE
}
@@ -34,7 +34,7 @@ import java.util.WeakHashMap
* a new one with the style given.
*/
@ReactModule(name = ReactProgressBarViewManager.REACT_CLASS)
public class ReactProgressBarViewManager :
internal class ReactProgressBarViewManager :
BaseViewManager<ProgressBarContainerView, ProgressBarShadowNode>(),
AndroidProgressBarManagerInterface<ProgressBarContainerView> {
private val measuredStyles = WeakHashMap<Int, Pair<Int, Int>>()
@@ -42,60 +42,60 @@ public class ReactProgressBarViewManager :
private val delegate: ViewManagerDelegate<ProgressBarContainerView> =
AndroidProgressBarManagerDelegate(this)
public override fun getName(): String = REACT_CLASS
override fun getName(): String = REACT_CLASS
protected override fun createViewInstance(context: ThemedReactContext): ProgressBarContainerView {
override fun createViewInstance(context: ThemedReactContext): ProgressBarContainerView {
return ProgressBarContainerView(context)
}
@ReactProp(name = PROP_STYLE)
public override fun setStyleAttr(view: ProgressBarContainerView, styleName: String?) {
override fun setStyleAttr(view: ProgressBarContainerView, styleName: String?) {
view.setStyle(styleName)
}
@ReactProp(name = ViewProps.COLOR, customType = "Color")
public override fun setColor(view: ProgressBarContainerView, color: Int?) {
override fun setColor(view: ProgressBarContainerView, color: Int?) {
view.color = color
}
@ReactProp(name = PROP_INDETERMINATE)
public override fun setIndeterminate(view: ProgressBarContainerView, indeterminate: Boolean) {
override fun setIndeterminate(view: ProgressBarContainerView, indeterminate: Boolean) {
view.indeterminate = indeterminate
}
@ReactProp(name = PROP_PROGRESS)
public override fun setProgress(view: ProgressBarContainerView, progress: Double) {
override fun setProgress(view: ProgressBarContainerView, progress: Double) {
view.progress = progress
}
@ReactProp(name = PROP_ANIMATING)
public override fun setAnimating(view: ProgressBarContainerView, animating: Boolean) {
override fun setAnimating(view: ProgressBarContainerView, animating: Boolean) {
view.animating = animating
}
public override fun setTestID(view: ProgressBarContainerView, value: String?) {
override fun setTestID(view: ProgressBarContainerView, value: String?) {
super.setTestId(view, value)
}
@ReactProp(name = PROP_ATTR)
public override fun setTypeAttr(view: ProgressBarContainerView, value: String?): Unit = Unit
override fun setTypeAttr(view: ProgressBarContainerView, value: String?): Unit = Unit
public override fun createShadowNodeInstance(): ProgressBarShadowNode = ProgressBarShadowNode()
override fun createShadowNodeInstance(): ProgressBarShadowNode = ProgressBarShadowNode()
public override fun getShadowNodeClass(): Class<ProgressBarShadowNode> =
override fun getShadowNodeClass(): Class<ProgressBarShadowNode> =
ProgressBarShadowNode::class.java
public override fun updateExtraData(root: ProgressBarContainerView, extraData: Any) {
override fun updateExtraData(root: ProgressBarContainerView, extraData: Any) {
// do nothing
}
protected override fun onAfterUpdateTransaction(view: ProgressBarContainerView) {
override fun onAfterUpdateTransaction(view: ProgressBarContainerView) {
view.apply()
}
protected override fun getDelegate(): ViewManagerDelegate<ProgressBarContainerView> = delegate
override fun getDelegate(): ViewManagerDelegate<ProgressBarContainerView> = delegate
public override fun measure(
override fun measure(
context: Context,
localData: ReadableMap,
props: ReadableMap,
@@ -119,15 +119,15 @@ public class ReactProgressBarViewManager :
toDIPFromPixel(value.first.toFloat()), toDIPFromPixel(value.second.toFloat()))
}
public companion object {
public const val REACT_CLASS: String = "AndroidProgressBar"
companion object {
const val REACT_CLASS: String = "AndroidProgressBar"
internal const val PROP_STYLE: String = "styleAttr"
internal const val PROP_ATTR: String = "typeAttr"
internal const val PROP_INDETERMINATE: String = "indeterminate"
internal const val PROP_PROGRESS: String = "progress"
internal const val PROP_ANIMATING: String = "animating"
internal const val DEFAULT_STYLE: String = "Normal"
const val PROP_STYLE: String = "styleAttr"
const val PROP_ATTR: String = "typeAttr"
const val PROP_INDETERMINATE: String = "indeterminate"
const val PROP_PROGRESS: String = "progress"
const val PROP_ANIMATING: String = "animating"
const val DEFAULT_STYLE: String = "Normal"
private val progressBarCtorLock = Any()
@@ -136,7 +136,7 @@ public class ReactProgressBarViewManager :
* ProgressBar constructor that may cause crashes when two ProgressBars are constructed at the
* same time on two different threads. This static ctor wrapper protects against that.
*/
public fun createProgressBar(context: Context?, style: Int): ProgressBar {
fun createProgressBar(context: Context?, style: Int): ProgressBar {
synchronized(progressBarCtorLock) {
return ProgressBar(context, null, style)
}
@@ -11,25 +11,16 @@ import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.ReactStylesDiffMap
import com.facebook.react.uimanager.StateWrapper
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.uimanager.common.UIManagerType
import com.facebook.react.uimanager.common.ViewUtil
import com.facebook.react.viewmanagers.AndroidHorizontalScrollContentViewManagerDelegate
import com.facebook.react.viewmanagers.AndroidHorizontalScrollContentViewManagerInterface
import com.facebook.react.views.view.ReactViewGroup
import com.facebook.react.views.view.ReactViewManager
/** View manager for {@link ReactHorizontalScrollContainerView} components. */
@ReactModule(name = ReactHorizontalScrollContainerViewManager.REACT_CLASS)
public class ReactHorizontalScrollContainerViewManager :
ReactViewManager(), AndroidHorizontalScrollContentViewManagerInterface<ReactViewGroup> {
public class ReactHorizontalScrollContainerViewManager : ReactViewManager() {
override public fun getName(): String = REACT_CLASS
private val delegate: ViewManagerDelegate<ReactViewGroup> =
AndroidHorizontalScrollContentViewManagerDelegate(this)
public override fun getDelegate(): ViewManagerDelegate<ReactViewGroup> = delegate
protected override fun createViewInstance(
reactTag: Int,
context: ThemedReactContext,
@@ -103,8 +103,6 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
private @Nullable Runnable mPostTouchRunnable;
private boolean mRemoveClippedSubviews;
private boolean mScrollEnabled = true;
private boolean mPreventReentry = false;
private boolean mEnableSyncOnScroll = false;
private boolean mSendMomentumEvents;
private @Nullable FpsListener mFpsListener = null;
private @Nullable String mScrollPerfTag;
@@ -231,10 +229,6 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
mScrollEnabled = scrollEnabled;
}
public void setEnableSyncOnScroll(boolean enableSyncOnScroll) {
mEnableSyncOnScroll = enableSyncOnScroll;
}
public void setPagingEnabled(boolean pagingEnabled) {
mPagingEnabled = pagingEnabled;
}
@@ -492,16 +486,10 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
if (mRemoveClippedSubviews) {
updateClippingRect();
}
if (mPreventReentry) {
return;
}
mPreventReentry = true;
ReactScrollViewHelper.updateStateOnScrollChanged(
this,
mOnScrollDispatchHelper.getXFlingVelocity(),
mOnScrollDispatchHelper.getYFlingVelocity(),
mEnableSyncOnScroll);
mPreventReentry = false;
mOnScrollDispatchHelper.getYFlingVelocity());
}
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
@@ -95,11 +95,6 @@ public class ReactHorizontalScrollViewManager extends ViewGroupManager<ReactHori
view.setDecelerationRate(decelerationRate);
}
@ReactProp(name = "enableSyncOnScroll")
public void setEnableSyncOnScroll(ReactHorizontalScrollView view, boolean enableSyncOnScroll) {
view.setEnableSyncOnScroll(enableSyncOnScroll);
}
@ReactProp(name = "disableIntervalMomentum")
public void setDisableIntervalMomentum(
ReactHorizontalScrollView view, boolean disableIntervalMomentum) {
@@ -102,11 +102,9 @@ public class ReactScrollView extends ScrollView
private @Nullable Runnable mPostTouchRunnable;
private boolean mRemoveClippedSubviews;
private boolean mScrollEnabled = true;
private boolean mPreventReentry = false;
private boolean mSendMomentumEvents;
private @Nullable FpsListener mFpsListener = null;
private @Nullable String mScrollPerfTag;
private boolean mEnableSyncOnScroll = false;
private @Nullable Drawable mEndBackground;
private int mEndFillColor = Color.TRANSPARENT;
private boolean mDisableIntervalMomentum = false;
@@ -210,10 +208,6 @@ public class ReactScrollView extends ScrollView
mScrollPerfTag = scrollPerfTag;
}
public void setEnableSyncOnScroll(boolean enableSyncOnScroll) {
mEnableSyncOnScroll = enableSyncOnScroll;
}
public void setScrollEnabled(boolean scrollEnabled) {
mScrollEnabled = scrollEnabled;
}
@@ -418,16 +412,10 @@ public class ReactScrollView extends ScrollView
if (mRemoveClippedSubviews) {
updateClippingRect();
}
if (mPreventReentry) {
return;
}
mPreventReentry = true;
ReactScrollViewHelper.updateStateOnScrollChanged(
this,
mOnScrollDispatchHelper.getXFlingVelocity(),
mOnScrollDispatchHelper.getYFlingVelocity(),
mEnableSyncOnScroll);
mPreventReentry = false;
mOnScrollDispatchHelper.getYFlingVelocity());
}
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
@@ -103,7 +103,6 @@ public object ReactScrollViewHelper {
scrollEventType: ScrollEventType,
xVelocity: Float,
yVelocity: Float,
experimental_isSynchronous: Boolean = false,
) where T : HasScrollEventThrottle?, T : ViewGroup {
val now = System.currentTimeMillis()
// Throttle the scroll event if scrollEventThrottle is set to be equal or more than 17 ms.
@@ -138,8 +137,7 @@ public object ReactScrollViewHelper {
contentView.width,
contentView.height,
scrollView.width,
scrollView.height,
experimental_isSynchronous))
scrollView.height))
scrollView.lastScrollDispatchTime = now
}
}
@@ -374,29 +372,13 @@ public object ReactScrollViewHelper {
T : HasScrollEventThrottle?,
T : HasScrollState?,
T : HasStateWrapper?,
T : ViewGroup {
updateStateOnScrollChanged(scrollView, xVelocity, yVelocity, false)
}
@JvmStatic
public fun <T> updateStateOnScrollChanged(
scrollView: T,
xVelocity: Float,
yVelocity: Float,
experimental_synchronous: Boolean,
) where
T : HasFlingAnimator?,
T : HasScrollEventThrottle?,
T : HasScrollState?,
T : HasStateWrapper?,
T : ViewGroup {
// Race an UpdateState with every onScroll. This makes it more likely that, in Fabric,
// when JS processes the scroll event, the C++ ShadowNode representation will have a
// "more correct" scroll position. It will frequently be /incorrect/ but this decreases
// the error as much as possible.
updateFabricScrollState(scrollView, scrollView.scrollX, scrollView.scrollY)
emitScrollEvent(
scrollView, ScrollEventType.SCROLL, xVelocity, yVelocity, experimental_synchronous)
emitScrollEvent(scrollView, xVelocity, yVelocity)
}
public fun <T> registerFlingAnimator(scrollView: T) where
@@ -167,11 +167,6 @@ public class ReactScrollViewManager extends ViewGroupManager<ReactScrollView>
view.setScrollPerfTag(scrollPerfTag);
}
@ReactProp(name = "enableSyncOnScroll")
public void setEnableSyncOnScroll(ReactScrollView view, boolean value) {
view.setEnableSyncOnScroll(value);
}
@ReactProp(name = "pagingEnabled")
public void setPagingEnabled(ReactScrollView view, boolean pagingEnabled) {
view.setPagingEnabled(pagingEnabled);
@@ -29,7 +29,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
private var scrollViewHeight = 0
private var scrollEventType: ScrollEventType? = null
private var timestamp: Long = 0
private var experimental_isSynchronous = false
override fun onDispose() {
try {
@@ -53,7 +52,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
contentHeight: Int,
scrollViewWidth: Int,
scrollViewHeight: Int,
experimental_isSynchronous: Boolean,
) {
super.init(surfaceId, viewTag)
this.scrollEventType = scrollEventType
@@ -66,7 +64,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
this.scrollViewWidth = scrollViewWidth
this.scrollViewHeight = scrollViewHeight
this.timestamp = SystemClock.uptimeMillis()
this.experimental_isSynchronous = experimental_isSynchronous
}
override fun getEventName(): String =
@@ -74,10 +71,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
override fun canCoalesce(): Boolean = scrollEventType == ScrollEventType.SCROLL
override fun experimental_isSynchronous(): Boolean {
return experimental_isSynchronous
}
override fun getEventData(): WritableMap {
val contentInset = Arguments.createMap()
contentInset.putDouble("top", 0.0)
@@ -125,7 +118,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
contentHeight: Int,
scrollViewWidth: Int,
scrollViewHeight: Int,
experimental_isSynchronous: Boolean,
): ScrollEvent =
(EVENTS_POOL.acquire() ?: ScrollEvent()).apply {
init(
@@ -139,8 +131,7 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
contentWidth,
contentHeight,
scrollViewWidth,
scrollViewHeight,
experimental_isSynchronous)
scrollViewHeight)
}
@Deprecated(
@@ -172,7 +163,6 @@ public class ScrollEvent private constructor() : Event<ScrollEvent>() {
contentHeight,
scrollViewWidth,
scrollViewHeight,
false,
)
}
}
@@ -15,9 +15,9 @@ import com.facebook.react.uimanager.events.Event
internal class RefreshEvent : Event<RefreshEvent> {
@Deprecated("Use constructor with surfaceId", ReplaceWith("RefreshEvent(surfaceId, viewTag)"))
protected constructor(viewTag: Int) : this(ViewUtil.NO_SURFACE_ID, viewTag)
constructor(viewTag: Int) : this(ViewUtil.NO_SURFACE_ID, viewTag)
protected constructor(surfaceId: Int, viewTag: Int) : super(surfaceId, viewTag)
constructor(surfaceId: Int, viewTag: Int) : super(surfaceId, viewTag)
override public fun getEventName(): String {
return "topRefresh"
@@ -1,194 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.swiperefresh;
import static com.facebook.react.views.swiperefresh.SwipeRefreshLayoutManager.REACT_CLASS;
import android.graphics.Color;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener;
import com.facebook.react.bridge.ColorPropConverter;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.ViewManagerDelegate;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.viewmanagers.AndroidSwipeRefreshLayoutManagerDelegate;
import com.facebook.react.viewmanagers.AndroidSwipeRefreshLayoutManagerInterface;
import java.util.HashMap;
import java.util.Map;
/**
* ViewManager for {@link ReactSwipeRefreshLayout} which allows the user to "pull to refresh" a
* child view. Emits an {@code onRefresh} event when this happens.
*/
@ReactModule(name = REACT_CLASS)
public class SwipeRefreshLayoutManager extends ViewGroupManager<ReactSwipeRefreshLayout>
implements AndroidSwipeRefreshLayoutManagerInterface<ReactSwipeRefreshLayout> {
public static final String REACT_CLASS = "AndroidSwipeRefreshLayout";
private final ViewManagerDelegate<ReactSwipeRefreshLayout> mDelegate;
public SwipeRefreshLayoutManager() {
mDelegate = new AndroidSwipeRefreshLayoutManagerDelegate<>(this);
}
@Override
protected ReactSwipeRefreshLayout createViewInstance(ThemedReactContext reactContext) {
return new ReactSwipeRefreshLayout(reactContext);
}
@Override
public String getName() {
return REACT_CLASS;
}
@Override
@ReactProp(name = ViewProps.ENABLED, defaultBoolean = true)
public void setEnabled(ReactSwipeRefreshLayout view, boolean enabled) {
view.setEnabled(enabled);
}
@Override
@ReactProp(name = "colors", customType = "ColorArray")
public void setColors(ReactSwipeRefreshLayout view, @Nullable ReadableArray colors) {
if (colors != null) {
int[] colorValues = new int[colors.size()];
for (int i = 0; i < colors.size(); i++) {
if (colors.getType(i) == ReadableType.Map) {
colorValues[i] = ColorPropConverter.getColor(colors.getMap(i), view.getContext());
} else {
colorValues[i] = colors.getInt(i);
}
}
view.setColorSchemeColors(colorValues);
} else {
view.setColorSchemeColors();
}
}
@Override
@ReactProp(name = "progressBackgroundColor", customType = "Color")
public void setProgressBackgroundColor(ReactSwipeRefreshLayout view, Integer color) {
view.setProgressBackgroundColorSchemeColor(color == null ? Color.TRANSPARENT : color);
}
// TODO(T46143833): Remove this method once the 'size' prop has been migrated to String in JS.
public void setSize(ReactSwipeRefreshLayout view, int value) {
view.setSize(value);
}
@Override
public void setSize(ReactSwipeRefreshLayout view, String size) {
if (size == null || size.equals("default")) {
view.setSize(SwipeRefreshLayout.DEFAULT);
} else if (size.equals("large")) {
view.setSize(SwipeRefreshLayout.LARGE);
} else {
throw new IllegalArgumentException("Size must be 'default' or 'large', received: " + size);
}
}
// This prop temporarily takes both 0 and 1 as well as 'default' and 'large'.
// 0 and 1 are deprecated and will be removed in a future release.
// See T46143833
@ReactProp(name = "size")
public void setSize(ReactSwipeRefreshLayout view, Dynamic size) {
if (size.isNull()) {
view.setSize(SwipeRefreshLayout.DEFAULT);
} else if (size.getType() == ReadableType.Number) {
view.setSize(size.asInt());
} else if (size.getType() == ReadableType.String) {
setSize(view, size.asString());
} else {
throw new IllegalArgumentException("Size must be 'default' or 'large'");
}
}
@Override
@ReactProp(name = "refreshing")
public void setRefreshing(ReactSwipeRefreshLayout view, boolean refreshing) {
view.setRefreshing(refreshing);
}
@Override
@ReactProp(name = "progressViewOffset", defaultFloat = 0)
public void setProgressViewOffset(final ReactSwipeRefreshLayout view, final float offset) {
view.setProgressViewOffset(offset);
}
@Override
public void setNativeRefreshing(ReactSwipeRefreshLayout view, boolean value) {
setRefreshing(view, value);
}
@Override
protected void addEventEmitters(
final ThemedReactContext reactContext, final ReactSwipeRefreshLayout view) {
view.setOnRefreshListener(
new OnRefreshListener() {
@Override
public void onRefresh() {
EventDispatcher eventDispatcher =
UIManagerHelper.getEventDispatcherForReactTag(reactContext, view.getId());
if (eventDispatcher != null) {
eventDispatcher.dispatchEvent(
new RefreshEvent(UIManagerHelper.getSurfaceId(view), view.getId()));
}
}
});
}
@Override
public void receiveCommand(
@NonNull ReactSwipeRefreshLayout root, String commandId, @Nullable ReadableArray args) {
switch (commandId) {
case "setNativeRefreshing":
if (args != null) {
setRefreshing(root, args.getBoolean(0));
}
break;
}
}
@Nullable
@Override
public Map<String, Object> getExportedViewConstants() {
return MapBuilder.<String, Object>of(
"SIZE",
MapBuilder.of("DEFAULT", SwipeRefreshLayout.DEFAULT, "LARGE", SwipeRefreshLayout.LARGE));
}
@Override
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
@Nullable
Map<String, Object> baseEventTypeConstants = super.getExportedCustomDirectEventTypeConstants();
Map<String, Object> eventTypeConstants =
baseEventTypeConstants == null ? new HashMap<String, Object>() : baseEventTypeConstants;
eventTypeConstants.putAll(
MapBuilder.<String, Object>builder()
.put("topRefresh", MapBuilder.of("registrationName", "onRefresh"))
.build());
return eventTypeConstants;
}
@Override
protected ViewManagerDelegate<ReactSwipeRefreshLayout> getDelegate() {
return mDelegate;
}
}
@@ -0,0 +1,153 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.swiperefresh
import android.graphics.Color
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.facebook.react.bridge.ColorPropConverter
import com.facebook.react.bridge.Dynamic
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.bridge.ReadableType
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.ViewGroupManager
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.uimanager.ViewProps
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.viewmanagers.AndroidSwipeRefreshLayoutManagerDelegate
import com.facebook.react.viewmanagers.AndroidSwipeRefreshLayoutManagerInterface
import java.util.HashMap
/**
* ViewManager for [ReactSwipeRefreshLayout] which allows the user to "pull to refresh" a child
* view. Emits an `onRefresh` event when this happens.
*/
@ReactModule(name = SwipeRefreshLayoutManager.REACT_CLASS)
internal open class SwipeRefreshLayoutManager :
ViewGroupManager<ReactSwipeRefreshLayout>(),
AndroidSwipeRefreshLayoutManagerInterface<ReactSwipeRefreshLayout> {
private val delegate: ViewManagerDelegate<ReactSwipeRefreshLayout> =
AndroidSwipeRefreshLayoutManagerDelegate(this)
override fun createViewInstance(reactContext: ThemedReactContext): ReactSwipeRefreshLayout =
ReactSwipeRefreshLayout(reactContext)
override fun getName(): String = REACT_CLASS
@ReactProp(name = ViewProps.ENABLED, defaultBoolean = true)
override fun setEnabled(view: ReactSwipeRefreshLayout, enabled: Boolean) {
view.isEnabled = enabled
}
@ReactProp(name = "colors", customType = "ColorArray")
override fun setColors(view: ReactSwipeRefreshLayout, colors: ReadableArray?) {
if (colors != null) {
val colorValues = IntArray(colors.size())
for (i in 0..<colors.size()) {
if (colors.getType(i) == ReadableType.Map) {
colorValues[i] = ColorPropConverter.getColor(colors.getMap(i), view.context)
} else {
colorValues[i] = colors.getInt(i)
}
}
view.setColorSchemeColors(*colorValues)
} else {
view.setColorSchemeColors()
}
}
@ReactProp(name = "progressBackgroundColor", customType = "Color")
override fun setProgressBackgroundColor(view: ReactSwipeRefreshLayout, color: Int?) {
view.setProgressBackgroundColorSchemeColor(color ?: Color.TRANSPARENT)
}
// TODO(T46143833): Remove this method once the 'size' prop has been migrated to String in JS.
fun setSize(view: ReactSwipeRefreshLayout, value: Int): Unit {
view.setSize(value)
}
override fun setSize(view: ReactSwipeRefreshLayout, size: String?) {
if (size == null || size.equals("default")) {
view.setSize(SwipeRefreshLayout.DEFAULT)
} else if (size.equals("large")) {
view.setSize(SwipeRefreshLayout.LARGE)
} else {
throw IllegalArgumentException("Size must be 'default' or 'large', received: $size")
}
}
// This prop temporarily takes both 0 and 1 as well as 'default' and 'large'.
// 0 and 1 are deprecated and will be removed in a future release.
// See T46143833
@ReactProp(name = "size")
fun setSize(view: ReactSwipeRefreshLayout, size: Dynamic): Unit {
when {
size.isNull -> view.setSize(SwipeRefreshLayout.DEFAULT)
size.type == ReadableType.Number -> view.setSize(size.asInt())
size.type == ReadableType.String -> this.setSize(view, size.asString())
else -> throw IllegalArgumentException("Size must be 'default' or 'large'")
}
}
@ReactProp(name = "refreshing")
override fun setRefreshing(view: ReactSwipeRefreshLayout, refreshing: Boolean) {
view.isRefreshing = refreshing
}
@ReactProp(name = "progressViewOffset", defaultFloat = 0f)
override fun setProgressViewOffset(view: ReactSwipeRefreshLayout, offset: Float) {
view.setProgressViewOffset(offset)
}
override fun setNativeRefreshing(view: ReactSwipeRefreshLayout, value: Boolean) {
setRefreshing(view, value)
}
override fun addEventEmitters(reactContext: ThemedReactContext, view: ReactSwipeRefreshLayout) {
view.setOnRefreshListener {
val eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, view.id)
eventDispatcher?.dispatchEvent(RefreshEvent(UIManagerHelper.getSurfaceId(view), view.id))
}
}
override fun receiveCommand(
root: ReactSwipeRefreshLayout,
commandId: String,
args: ReadableArray?
) {
when (commandId) {
"setNativeRefreshing" ->
if (args != null) {
setRefreshing(root, args.getBoolean(0))
}
else -> {}
}
}
override fun getExportedViewConstants(): MutableMap<String, Any> =
mutableMapOf(
"SIZE" to
mutableMapOf(
"DEFAULT" to SwipeRefreshLayout.DEFAULT, "LARGE" to SwipeRefreshLayout.LARGE))
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
val baseEventTypeConstants = super.getExportedCustomDirectEventTypeConstants()
val eventTypeConstants: MutableMap<String, Any> = baseEventTypeConstants ?: HashMap()
eventTypeConstants.putAll(
mutableMapOf("topRefresh" to mutableMapOf("registrationName" to "onRefresh")))
return eventTypeConstants
}
override fun getDelegate(): ViewManagerDelegate<ReactSwipeRefreshLayout> = delegate
companion object {
const val REACT_CLASS: String = "AndroidSwipeRefreshLayout"
}
}
@@ -1,66 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.text;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Typeface;
import androidx.annotation.Nullable;
import com.facebook.infer.annotation.Nullsafe;
/**
* Responsible for loading and caching Typeface objects.
*
* @deprecated This class is deprecated and it will be deleted in the near future. Please use {@link
* com.facebook.react.common.assets.ReactFontManager} instead.
*/
@Nullsafe(Nullsafe.Mode.LOCAL)
@Deprecated
public class ReactFontManager {
private static ReactFontManager sReactFontManagerInstance;
private final com.facebook.react.common.assets.ReactFontManager mDelegate;
private ReactFontManager(com.facebook.react.common.assets.ReactFontManager delegate) {
mDelegate = delegate;
}
public static ReactFontManager getInstance() {
if (sReactFontManagerInstance == null) {
sReactFontManagerInstance =
new ReactFontManager(com.facebook.react.common.assets.ReactFontManager.getInstance());
}
return sReactFontManagerInstance;
}
public Typeface getTypeface(String fontFamilyName, int style, AssetManager assetManager) {
return mDelegate.getTypeface(fontFamilyName, style, assetManager);
}
public Typeface getTypeface(
String fontFamilyName, int weight, boolean italic, AssetManager assetManager) {
return mDelegate.getTypeface(fontFamilyName, weight, italic, assetManager);
}
public Typeface getTypeface(
String fontFamilyName, int style, int weight, AssetManager assetManager) {
return mDelegate.getTypeface(fontFamilyName, style, weight, assetManager);
}
public void addCustomFont(Context context, String fontFamily, int fontId) {
mDelegate.addCustomFont(context, fontFamily, fontId);
}
public void addCustomFont(String fontFamily, @Nullable Typeface font) {
mDelegate.addCustomFont(fontFamily, font);
}
public void setTypeface(String fontFamilyName, int style, Typeface typeface) {
mDelegate.setTypeface(fontFamilyName, style, typeface);
}
}
@@ -0,0 +1,58 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.text
import android.content.Context
import android.content.res.AssetManager
import android.graphics.Typeface
/** Responsible for loading and caching Typeface objects. */
@Deprecated(
message =
"This class is deprecated and will be deleted in the near future. Please use [com.facebook.react.common.assets.ReactFontManager] instead.")
@Suppress("DEPRECATION")
public class ReactFontManager private constructor(private val delegate: ReactFontManager) {
public fun getTypeface(fontFamilyName: String, style: Int, assetManager: AssetManager): Typeface =
delegate.getTypeface(fontFamilyName, style, assetManager)
public fun getTypeface(
fontFamilyName: String,
weight: Int,
italic: Boolean,
assetManager: AssetManager
): Typeface = delegate.getTypeface(fontFamilyName, weight, italic, assetManager)
public fun getTypeface(
fontFamilyName: String,
style: Int,
weight: Int,
assetManager: AssetManager
): Typeface = delegate.getTypeface(fontFamilyName, style, weight, assetManager)
public fun addCustomFont(context: Context, fontFamily: String, fontId: Int) {
delegate.addCustomFont(context, fontFamily, fontId)
}
public fun addCustomFont(fontFamily: String, font: Typeface?) {
delegate.addCustomFont(fontFamily, font)
}
public fun setTypeface(fontFamilyName: String, style: Int, typeface: Typeface) {
delegate.setTypeface(fontFamilyName, style, typeface)
}
public companion object {
private var instance: ReactFontManager? = null
@JvmStatic
public fun getInstance(): ReactFontManager {
return instance ?: ReactFontManager(ReactFontManager.getInstance()).also { instance = it }
}
}
}
@@ -1,58 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.text;
import androidx.annotation.Nullable;
import java.text.BreakIterator;
/** Types of text transforms for CustomTextTransformSpan */
public enum TextTransform {
NONE,
UPPERCASE,
LOWERCASE,
CAPITALIZE,
UNSET;
public static String apply(@Nullable String text, TextTransform textTransform) {
if (text == null) {
return null;
}
String transformed;
switch (textTransform) {
case UPPERCASE:
transformed = text.toUpperCase();
break;
case LOWERCASE:
transformed = text.toLowerCase();
break;
case CAPITALIZE:
transformed = capitalize(text);
break;
default:
transformed = text;
}
return transformed;
}
private static String capitalize(String text) {
BreakIterator wordIterator = BreakIterator.getWordInstance();
wordIterator.setText(text);
StringBuilder res = new StringBuilder(text.length());
int start = wordIterator.first();
for (int end = wordIterator.next(); end != BreakIterator.DONE; end = wordIterator.next()) {
res.append(Character.toUpperCase(text.charAt(start)));
res.append(text.substring(start + 1, end));
start = end;
}
return res.toString();
}
};
@@ -0,0 +1,55 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.text
import java.text.BreakIterator
import java.util.Locale
/** Types of text transforms for CustomTextTransformSpan */
public enum class TextTransform {
NONE,
UPPERCASE,
LOWERCASE,
CAPITALIZE,
UNSET;
public companion object {
@JvmStatic
public fun apply(text: String?, textTransform: TextTransform?): String? {
if (text == null) {
return null
}
val transformed: String =
when (textTransform) {
UPPERCASE -> text.uppercase(Locale.getDefault())
LOWERCASE -> text.lowercase(Locale.getDefault())
CAPITALIZE -> capitalize(text)
else -> text
}
return transformed
}
private fun capitalize(text: String): String {
val wordIterator = BreakIterator.getWordInstance()
wordIterator.setText(text)
val res = StringBuilder(text.length)
var start = wordIterator.first()
var end = wordIterator.next()
while (end != BreakIterator.DONE) {
res.append(text[start].uppercaseChar())
res.append(text.substring(start + 1, end))
start = end
end = wordIterator.next()
}
return res.toString()
}
}
}
@@ -1302,8 +1302,7 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
0, // can't get content width
0, // can't get content height
mReactEditText.getWidth(),
mReactEditText.getHeight(),
false);
mReactEditText.getHeight());
mEventDispatcher.dispatchEvent(event);
@@ -7,10 +7,14 @@
package com.facebook.react.views.view
import android.content.res.Configuration
import android.graphics.Color
import android.os.Build
import android.view.Window
import android.view.WindowManager
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsControllerCompat
@Suppress("DEPRECATION")
public fun Window.setStatusBarTranslucency(isTranslucent: Boolean) {
@@ -61,3 +65,41 @@ private fun Window.statusBarShow() {
addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN)
clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
}
@Suppress("DEPRECATION")
public fun Window.setSystemBarsTranslucency(isTranslucent: Boolean) {
WindowCompat.setDecorFitsSystemWindows(this, !isTranslucent)
if (isTranslucent) {
val isDarkMode =
context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
Configuration.UI_MODE_NIGHT_YES
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
isStatusBarContrastEnforced = false
isNavigationBarContrastEnforced = true
}
statusBarColor = Color.TRANSPARENT
navigationBarColor =
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> Color.TRANSPARENT
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1 && !isDarkMode ->
Color.argb(0xe6, 0xFF, 0xFF, 0xFF)
else -> Color.argb(0x80, 0x1b, 0x1b, 0x1b)
}
WindowInsetsControllerCompat(this, this.decorView).run {
isAppearanceLightNavigationBars = !isDarkMode
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
attributes.layoutInDisplayCutoutMode =
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R ->
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
else -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
}
}
}
}
@@ -5,12 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.perftest;
#pragma once
/** PerfTestConfig stub. */
public class PerfTestConfig {
public boolean isRunningInPerfTest() {
return false;
}
}
// This header exists for backwards compatibility with libraries importing
// <react/fabric/Binding.h>
#include "FabricUIManagerBinding.h"
@@ -9,6 +9,7 @@ package com.facebook.react.views.image
import android.graphics.Color
import android.util.DisplayMetrics
import com.facebook.common.logging.FLog
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.drawable.ScalingUtils
import com.facebook.react.bridge.Arguments
@@ -19,6 +20,7 @@ import com.facebook.react.bridge.JavaOnlyMap
import com.facebook.react.bridge.ReactTestHelper.createMockCatalystInstance
import com.facebook.react.bridge.WritableArray
import com.facebook.react.bridge.WritableMap
import com.facebook.react.common.ReactConstants
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsForTests
import com.facebook.react.uimanager.DisplayMetricsHolder
import com.facebook.react.uimanager.ReactStylesDiffMap
@@ -34,7 +36,11 @@ import org.junit.runner.RunWith
import org.mockito.MockedStatic
import org.mockito.Mockito.any
import org.mockito.Mockito.anyString
import org.mockito.Mockito.mock
import org.mockito.Mockito.mockStatic
import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
@@ -47,6 +53,7 @@ class ReactImagePropertyTest {
private lateinit var themeContext: ThemedReactContext
private lateinit var arguments: MockedStatic<Arguments>
private lateinit var rnLog: MockedStatic<RNLog>
private lateinit var flogMock: MockedStatic<FLog>
@Before
fun setup() {
@@ -57,6 +64,8 @@ class ReactImagePropertyTest {
rnLog = mockStatic(RNLog::class.java)
rnLog.`when`<Boolean> { RNLog.w(any(), anyString()) }.thenAnswer {}
flogMock = mockStatic(FLog::class.java)
SoLoader.setInTestMode()
context = BridgeReactContext(RuntimeEnvironment.getApplication())
catalystInstanceMock = createMockCatalystInstance()
@@ -73,6 +82,7 @@ class ReactImagePropertyTest {
DisplayMetricsHolder.setWindowDisplayMetrics(null)
arguments.close()
rnLog.close()
flogMock.close()
}
private fun buildStyles(vararg keysAndValues: Any?): ReactStylesDiffMap {
@@ -87,6 +97,20 @@ class ReactImagePropertyTest {
assertThat(view.isFocusable).isTrue()
}
@Test
fun testOverlayColor() {
val viewManager = ReactImageManager()
val mockView = mock(ReactImageView::class.java)
viewManager.setOverlayColor(mockView, null)
verify(mockView).setOverlayColor(Color.TRANSPARENT)
reset(mockView)
viewManager.setOverlayColor(mockView, Color.argb(50, 0, 0, 255))
verify(mockView).setOverlayColor(Color.argb(50, 0, 0, 255))
reset(mockView)
}
@Test
fun testTintColor() {
val viewManager = ReactImageManager()
@@ -115,4 +139,95 @@ class ReactImagePropertyTest {
assertThat(ImageSource.getTransparentBitmapImageSource(view.context))
.isEqualTo(view.imageSource)
}
@Test
fun testResizeMode() {
val viewManager = ReactImageManager()
val mockView = mock(ReactImageView::class.java)
viewManager.setResizeMode(mockView, null)
verify(mockView).setScaleType(ScalingUtils.ScaleType.CENTER_CROP)
reset(mockView)
viewManager.setResizeMode(mockView, "cover")
verify(mockView).setScaleType(ScalingUtils.ScaleType.CENTER_CROP)
reset(mockView)
viewManager.setResizeMode(mockView, "contain")
verify(mockView).setScaleType(ScalingUtils.ScaleType.FIT_CENTER)
reset(mockView)
viewManager.setResizeMode(mockView, "stretch")
verify(mockView).setScaleType(ScalingUtils.ScaleType.FIT_XY)
reset(mockView)
viewManager.setResizeMode(mockView, "repeat")
verify(mockView).setScaleType(ScaleTypeStartInside.INSTANCE)
reset(mockView)
viewManager.setResizeMode(mockView, "center")
verify(mockView).setScaleType(ScalingUtils.ScaleType.CENTER_INSIDE)
reset(mockView)
viewManager.setResizeMode(mockView, "invalid")
verify(mockView).setScaleType(ScalingUtils.ScaleType.CENTER_CROP)
}
@Test
fun testResizeMethod() {
val viewManager = ReactImageManager()
val mockView = mock(ReactImageView::class.java)
viewManager.setResizeMethod(mockView, null)
verify(mockView).setResizeMethod(ImageResizeMethod.AUTO)
reset(mockView)
viewManager.setResizeMethod(mockView, "auto")
verify(mockView).setResizeMethod(ImageResizeMethod.AUTO)
reset(mockView)
viewManager.setResizeMethod(mockView, "resize")
verify(mockView).setResizeMethod(ImageResizeMethod.RESIZE)
reset(mockView)
viewManager.setResizeMethod(mockView, "scale")
verify(mockView).setResizeMethod(ImageResizeMethod.SCALE)
reset(mockView)
viewManager.setResizeMethod(mockView, "none")
verify(mockView).setResizeMethod(ImageResizeMethod.NONE)
reset(mockView)
viewManager.setResizeMethod(mockView, "invalid")
verify(mockView).setResizeMethod(ImageResizeMethod.AUTO)
flogMock.verify { FLog.w(ReactConstants.TAG, "Invalid resize method: 'invalid'") }
}
@Test
fun testResizeMultiplier() {
val viewManager = ReactImageManager()
val mockView = mock(ReactImageView::class.java)
viewManager.setResizeMultiplier(mockView, 0.01f)
verify(mockView).setResizeMultiplier(0.01f)
reset(mockView)
viewManager.setResizeMultiplier(mockView, 0.009f)
verify(mockView).setResizeMultiplier(0.009f)
flogMock.verify { FLog.w(ReactConstants.TAG, "Invalid resize multiplier: '0.009'") }
}
@Test
fun testHeaders() {
val viewManager = ReactImageManager()
val mockView = mock(ReactImageView::class.java)
viewManager.setHeaders(mockView, null)
verify(mockView, never()).setHeaders(any())
val headers = JavaOnlyMap()
headers.putString("key", "value")
viewManager.setHeaders(mockView, headers)
verify(mockView).setHeaders(headers)
}
}
@@ -17,6 +17,7 @@ import com.facebook.react.bridge.UIManagerListener
import com.facebook.react.bridge.WritableMap
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.fabric.interop.UIBlockViewResolver
import com.facebook.react.uimanager.events.EventDispatcher
@OptIn(UnstableReactNativeAPI::class)
class FakeUIManager : UIManager, UIBlockViewResolver {
@@ -65,7 +66,7 @@ class FakeUIManager : UIManager, UIBlockViewResolver {
error("Not yet implemented")
}
override val eventDispatcher: Any?
override val eventDispatcher: EventDispatcher
get() = TODO("Not yet implemented")
override fun synchronouslyUpdateViewOnUIThread(reactTag: Int, props: ReadableMap?) {
@@ -92,7 +92,6 @@ Pod::Spec.new do |s|
"react/renderer/components/view/platform/cxx",
"react/renderer/imagemanager/platform/ios"
])
add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"])
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
@@ -94,7 +94,7 @@ class JSCRuntime : public jsi::Runtime {
const std::atomic<bool>& ctxInvalid,
JSValueRef sym);
#endif
void invalidate() override;
void invalidate() noexcept override;
JSGlobalContextRef ctx_;
const std::atomic<bool>& ctxInvalid_;
@@ -114,7 +114,7 @@ class JSCRuntime : public jsi::Runtime {
#else
JSCStringValue(JSStringRef str);
#endif
void invalidate() override;
void invalidate() noexcept override;
JSStringRef str_;
#ifndef NDEBUG
@@ -135,7 +135,7 @@ class JSCRuntime : public jsi::Runtime {
#endif
);
void invalidate() override;
void invalidate() noexcept override;
JSGlobalContextRef ctx_;
const std::atomic<bool>& ctxInvalid_;
@@ -506,7 +506,7 @@ JSCRuntime::JSCSymbolValue::JSCSymbolValue(
#endif
}
void JSCRuntime::JSCSymbolValue::invalidate() {
void JSCRuntime::JSCSymbolValue::invalidate() noexcept {
#ifndef NDEBUG
counter_ -= 1;
#endif
@@ -531,7 +531,7 @@ JSCRuntime::JSCStringValue::JSCStringValue(JSStringRef str)
: str_(JSStringRetain(str)) {}
#endif
void JSCRuntime::JSCStringValue::invalidate() {
void JSCRuntime::JSCStringValue::invalidate() noexcept {
// These JSC{String,Object}Value objects are implicitly owned by the
// {String,Object} objects, thus when a String/Object is destructed
// the JSC{String,Object}Value should be released.
@@ -566,7 +566,7 @@ JSCRuntime::JSCObjectValue::JSCObjectValue(
#endif
}
void JSCRuntime::JSCObjectValue::invalidate() {
void JSCRuntime::JSCObjectValue::invalidate() noexcept {
#ifndef NDEBUG
counter_ -= 1;
#endif
@@ -19,4 +19,5 @@ target_link_libraries(jserrorhandler
jsi
folly_runtime
mapbufferjni
react_featureflags
)
@@ -9,6 +9,7 @@
#include <cxxreact/ErrorUtils.h>
#include <glog/logging.h>
#include <react/bridging/Bridging.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <string>
#include "StackTraceParser.h"
@@ -228,7 +229,9 @@ void JsErrorHandler::handleError(
bool logToConsole) {
// TODO: Current error parsing works and is stable. Can investigate using
// REGEX_HERMES to get additional Hermes data, though it requires JS setup
if (_isRuntimeReady) {
if (!ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling() &&
_isRuntimeReady) {
if (isFatal) {
_hasHandledFatalError = true;
}
@@ -325,7 +328,7 @@ void JsErrorHandler::handleErrorWithCppPipeline(
auto id = nextExceptionId();
ParsedError parsedError = {
.message = "EarlyJsError: " + message,
.message = _isRuntimeReady ? message : ("EarlyJsError: " + message),
.originalMessage = originalMessage,
.name = name,
.componentStack = componentStack,
@@ -52,6 +52,7 @@ Pod::Spec.new do |s|
s.dependency "React-cxxreact"
s.dependency "glog"
s.dependency "ReactCommon/turbomodule/bridging"
add_dependency(s, "React-featureflags")
add_dependency(s, "React-debug")
if ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == "1"
@@ -38,8 +38,11 @@ Pod::Spec.new do |s|
s.header_dir = "jsi"
s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\"",
"DEFINES_MODULE" => "YES" }
s.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fast_float/include\" \"$(PODS_ROOT)/fmt/include\"",
"CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
"DEFINES_MODULE" => "YES"
}
s.dependency "boost"
s.dependency "DoubleConversion"
@@ -333,7 +333,7 @@ Function Object::asFunction(Runtime& runtime) && {
return std::move(*this).getFunction(runtime);
}
Value::Value(Value&& other) : Value(other.kind_) {
Value::Value(Value&& other) noexcept : Value(other.kind_) {
if (kind_ == BooleanKind) {
data_.boolean = other.data_.boolean;
} else if (kind_ == NumberKind) {
@@ -288,7 +288,7 @@ class JSI_EXPORT Runtime {
// rvalue arguments/methods would also reduce the number of clones.
struct PointerValue {
virtual void invalidate() = 0;
virtual void invalidate() noexcept = 0;
protected:
virtual ~PointerValue() = default;
@@ -1121,7 +1121,7 @@ class JSI_EXPORT Function : public Object {
class JSI_EXPORT Value {
public:
/// Default ctor creates an \c undefined JS value.
Value() : Value(UndefinedKind) {}
Value() noexcept : Value(UndefinedKind) {}
/// Creates a \c null JS value.
/* implicit */ Value(std::nullptr_t) : kind_(NullKind) {}
@@ -1162,7 +1162,7 @@ class JSI_EXPORT Value {
"Value cannot be constructed directly from const char*");
}
Value(Value&& value);
Value(Value&& other) noexcept;
/// Copies a Symbol lvalue into a new JS value.
Value(Runtime& runtime, const Symbol& sym) : Value(SymbolKind) {
@@ -1217,7 +1217,7 @@ class JSI_EXPORT Value {
/// https://262.ecma-international.org/11.0/#sec-strict-equality-comparison
static bool strictEquals(Runtime& runtime, const Value& a, const Value& b);
Value& operator=(Value&& other) {
Value& operator=(Value&& other) noexcept {
this->~Value();
new (this) Value(std::move(other));
return *this;
@@ -16,7 +16,13 @@ else
source[:tag] = "v#{version}"
end
header_search_paths = []
header_search_paths = [
"\"$(PODS_ROOT)/RCT-Folly\"",
]
folly_config = get_folly_config()
folly_compiler_flags = folly_config[:compiler_flags]
folly_version = folly_config[:version]
if ENV['USE_FRAMEWORKS']
header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../../..\"" # this is needed to allow the defaultsnativemodule to access its own files
@@ -31,10 +37,12 @@ Pod::Spec.new do |s|
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = min_supported_versions
s.source = source
s.compiler_flags = folly_compiler_flags
s.source_files = "*.{cpp,h}"
s.header_dir = "react/nativemodule/defaults"
s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
"HEADER_SEARCH_PATHS" => header_search_paths.join(' '),
"OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags,
"DEFINES_MODULE" => "YES" }
if ENV['USE_FRAMEWORKS']
@@ -42,10 +50,18 @@ Pod::Spec.new do |s|
s.header_mappings_dir = "../.."
end
install_modules_dependencies(s)
s.dependency "RCT-Folly"
s.dependency "React-jsi"
s.dependency "React-jsiexecutor"
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
else
s.dependency "React-jsc"
end
s.dependency "React-domnativemodule"
s.dependency "React-featureflagsnativemodule"
s.dependency "React-microtasksnativemodule"
s.dependency "React-idlecallbacksnativemodule"
add_dependency(s, "React-RCTFBReactNativeSpec")
end
@@ -16,7 +16,14 @@ else
source[:tag] = "v#{version}"
end
header_search_paths = []
header_search_paths = [
"\"$(PODS_ROOT)/RCT-Folly\"",
"\"$(PODS_ROOT)/Headers/Private/Yoga\"",
]
folly_config = get_folly_config()
folly_compiler_flags = folly_config[:compiler_flags]
folly_version = folly_config[:version]
if ENV['USE_FRAMEWORKS']
header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../../..\"" # this is needed to allow the domnativemodule to access its own files
@@ -31,10 +38,12 @@ Pod::Spec.new do |s|
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = min_supported_versions
s.source = source
s.compiler_flags = folly_compiler_flags
s.source_files = "*.{cpp,h}"
s.header_dir = "react/nativemodule/dom"
s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
"HEADER_SEARCH_PATHS" => header_search_paths.join(' '),
"OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags,
"DEFINES_MODULE" => "YES" }
if ENV['USE_FRAMEWORKS']
@@ -42,9 +51,18 @@ Pod::Spec.new do |s|
s.header_mappings_dir = "../.."
end
install_modules_dependencies(s)
s.dependency "RCT-Folly"
s.dependency "React-jsi"
s.dependency "React-jsiexecutor"
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
else
s.dependency "React-jsc"
end
s.dependency "Yoga"
s.dependency "ReactCommon/turbomodule/core"
s.dependency "React-Fabric"
s.dependency "React-FabricComponents"
add_dependency(s, "React-graphics", :additional_framework_paths => ["react/renderer/graphics/platform/ios"])
add_dependency(s, "React-RCTFBReactNativeSpec")
end
@@ -16,7 +16,13 @@ else
source[:tag] = "v#{version}"
end
header_search_paths = []
header_search_paths = [
"\"$(PODS_ROOT)/RCT-Folly\"",
]
folly_config = get_folly_config()
folly_compiler_flags = folly_config[:compiler_flags]
folly_version = folly_config[:version]
if ENV['USE_FRAMEWORKS']
header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../../..\"" # this is needed to allow the feature flags access its own files
@@ -31,10 +37,12 @@ Pod::Spec.new do |s|
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = min_supported_versions
s.source = source
s.compiler_flags = folly_compiler_flags
s.source_files = "*.{cpp,h}"
s.header_dir = "react/nativemodule/featureflags"
s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
"HEADER_SEARCH_PATHS" => header_search_paths.join(' '),
"OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags,
"DEFINES_MODULE" => "YES" }
if ENV['USE_FRAMEWORKS']
@@ -42,7 +50,15 @@ Pod::Spec.new do |s|
s.header_mappings_dir = "../.."
end
install_modules_dependencies(s)
s.dependency "RCT-Folly"
s.dependency "React-jsi"
s.dependency "React-jsiexecutor"
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
else
s.dependency "React-jsc"
end
s.dependency "ReactCommon/turbomodule/core"
s.dependency "React-RCTFBReactNativeSpec"
s.dependency "React-featureflags"
end
@@ -16,7 +16,13 @@ else
source[:tag] = "v#{version}"
end
header_search_paths = []
header_search_paths = [
"\"$(PODS_ROOT)/RCT-Folly\"",
]
folly_config = get_folly_config()
folly_compiler_flags = folly_config[:compiler_flags]
folly_version = folly_config[:version]
if ENV['USE_FRAMEWORKS']
header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../../..\"" # this is needed to allow the module access its own files
@@ -31,10 +37,12 @@ Pod::Spec.new do |s|
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = min_supported_versions
s.source = source
s.compiler_flags = folly_compiler_flags
s.source_files = "*.{cpp,h}"
s.header_dir = "react/nativemodule/idlecallbacks"
s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
"HEADER_SEARCH_PATHS" => header_search_paths.join(' '),
"OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags,
"DEFINES_MODULE" => "YES" }
if ENV['USE_FRAMEWORKS']
@@ -42,8 +50,15 @@ Pod::Spec.new do |s|
s.header_mappings_dir = "../.."
end
install_modules_dependencies(s)
s.dependency "RCT-Folly"
s.dependency "React-jsi"
s.dependency "React-jsiexecutor"
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
else
s.dependency "React-jsc"
end
s.dependency "ReactCommon/turbomodule/core"
s.dependency "React-runtimescheduler"
add_dependency(s, "React-RCTFBReactNativeSpec")
end
@@ -16,7 +16,13 @@ else
source[:tag] = "v#{version}"
end
header_search_paths = []
header_search_paths = [
"\"$(PODS_ROOT)/RCT-Folly\"",
]
folly_config = get_folly_config()
folly_compiler_flags = folly_config[:compiler_flags]
folly_version = folly_config[:version]
if ENV['USE_FRAMEWORKS']
header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../../..\"" # this is needed to allow the microtasks module access its own files
@@ -31,9 +37,11 @@ Pod::Spec.new do |s|
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = min_supported_versions
s.source = source
s.compiler_flags = folly_compiler_flags
s.source_files = "*.{cpp,h}"
s.header_dir = "react/nativemodule/microtasks"
s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
"OTHER_CFLAGS" => "$(inherited) " + folly_compiler_flags,
"HEADER_SEARCH_PATHS" => header_search_paths.join(' '),
"DEFINES_MODULE" => "YES" }
@@ -42,7 +50,14 @@ Pod::Spec.new do |s|
s.header_mappings_dir = "../.."
end
install_modules_dependencies(s)
s.dependency "RCT-Folly"
s.dependency "React-jsi"
s.dependency "React-jsiexecutor"
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
else
s.dependency "React-jsc"
end
s.dependency "ReactCommon/turbomodule/core"
add_dependency(s, "React-RCTFBReactNativeSpec")
end
@@ -69,9 +69,9 @@ Pod::Spec.new do |s|
s.dependency "React-Core"
s.dependency "React-cxxreact"
s.dependency "React-jsi"
add_dependency(s, "ReactCodegen", :additional_framework_paths => ["build/generated/ios"])
add_dependency(s, "React-RCTFBReactNativeSpec")
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core", :additional_framework_paths => ["react/nativemodule/core"])
add_dependency(s, "React-NativeModulesApple", :additional_framework_paths => ["build/generated/ios"])
add_dependency(s, "React-NativeModulesApple")
if using_hermes
s.dependency "hermes-engine"
@@ -13,14 +13,6 @@ void ScrollViewEventEmitter::onScroll(const ScrollEvent& scrollEvent) const {
dispatchUniqueEvent("scroll", std::make_shared<ScrollEvent>(scrollEvent));
}
void ScrollViewEventEmitter::experimental_onDiscreteScroll(
const ScrollEvent& scrollEvent) const {
dispatchEvent(
"scroll",
std::make_shared<ScrollEvent>(scrollEvent),
RawEvent::Category::Discrete);
}
void ScrollViewEventEmitter::onScrollToTop(
const ScrollEvent& scrollEvent) const {
dispatchUniqueEvent(
@@ -23,7 +23,6 @@ class ScrollViewEventEmitter : public ViewEventEmitter {
using Metrics = ScrollEvent;
void onScroll(const ScrollEvent& scrollEvent) const;
void experimental_onDiscreteScroll(const ScrollEvent& scrollEvent) const;
void onScrollBeginDrag(const ScrollEvent& scrollEvent) const;
void onScrollEndDrag(const ScrollEvent& scrollEvent) const;
void onMomentumScrollBegin(const ScrollEvent& scrollEvent) const;
@@ -120,15 +120,6 @@ ScrollViewProps::ScrollViewProps(
"endDraggingSensitivityMultiplier",
sourceProps.endDraggingSensitivityMultiplier,
(Float)1)),
enableSyncOnScroll(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.enableSyncOnScroll
: convertRawProp(
context,
rawProps,
"enableSyncOnScroll",
sourceProps.enableSyncOnScroll,
false)),
directionalLockEnabled(
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.directionalLockEnabled
@@ -411,7 +402,6 @@ void ScrollViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(maximumZoomScale);
RAW_SET_PROP_SWITCH_CASE_BASIC(minimumZoomScale);
RAW_SET_PROP_SWITCH_CASE_BASIC(scrollEnabled);
RAW_SET_PROP_SWITCH_CASE_BASIC(enableSyncOnScroll);
RAW_SET_PROP_SWITCH_CASE_BASIC(endDraggingSensitivityMultiplier);
RAW_SET_PROP_SWITCH_CASE_BASIC(pagingEnabled);
RAW_SET_PROP_SWITCH_CASE_BASIC(pinchGestureEnabled);
@@ -43,7 +43,6 @@ class ScrollViewProps final : public ViewProps {
bool automaticallyAdjustKeyboardInsets{false};
Float decelerationRate{0.998f};
Float endDraggingSensitivityMultiplier{1};
bool enableSyncOnScroll{false};
bool directionalLockEnabled{};
ScrollViewIndicatorStyle indicatorStyle{};
ScrollViewKeyboardDismissMode keyboardDismissMode{};
@@ -409,6 +409,27 @@ void ReactInstance::initializeRuntime(
defineReactInstanceFlags(runtime, options);
defineReadOnlyGlobal(
runtime,
"RN$useAlwaysAvailableJSErrorHandling",
jsi::Value(
ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling()));
defineReadOnlyGlobal(
runtime,
"RN$isRuntimeReady",
jsi::Function::createFromHostFunction(
runtime,
jsi::PropNameID::forAscii(runtime, "isRuntimeReady"),
0,
[jsErrorHandler = jsErrorHandler_](
jsi::Runtime& /*runtime*/,
const jsi::Value& /*unused*/,
const jsi::Value* /*args*/,
size_t /*count*/) {
return jsErrorHandler->isRuntimeReady();
}));
defineReadOnlyGlobal(
runtime,
"RN$inExceptionHandler",
@@ -444,12 +465,16 @@ void ReactInstance::initializeRuntime(
}
auto isFatal = isTruthy(runtime, args[1]);
if (jsErrorHandler->isRuntimeReady()) {
if (isFatal) {
jsErrorHandler->notifyOfFatalError();
}
return jsi::Value(false);
if (!ReactNativeFeatureFlags::
useAlwaysAvailableJSErrorHandling()) {
if (jsErrorHandler->isRuntimeReady()) {
if (isFatal) {
jsErrorHandler->notifyOfFatalError();
}
return jsi::Value(false);
}
}
auto jsError =
@@ -71,7 +71,7 @@ Pod::Spec.new do |s|
s.dependency "React-jsinspector"
s.dependency "React-featureflags"
add_dependency(s, "ReactCodegen")
add_dependency(s, "React-RCTFBReactNativeSpec")
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
@@ -14,6 +14,7 @@
- (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path;
- (void)setBundleURLProvider:(RCTHostBundleURLProvider)bundleURLProvider;
- (void)setContextContainerHandler:(id<RCTContextContainerHandling>)contextContainerHandler;
- (void)reload;
@property (nonatomic, readonly) RCTBundleManager *bundleManager;
@@ -287,25 +287,7 @@ class RCTHostHostTargetDelegate : public facebook::react::jsinspector_modern::Ho
- (void)didReceiveReloadCommand
{
[_instance invalidate];
_instance = nil;
if (_bundleURLProvider) {
[self _setBundleURL:_bundleURLProvider()];
}
_instance = [[RCTInstance alloc] initWithDelegate:self
jsRuntimeFactory:[self _provideJSEngine]
bundleManager:_bundleManager
turboModuleManagerDelegate:_turboModuleManagerDelegate
moduleRegistry:_moduleRegistry
parentInspectorTarget:_inspectorTarget.get()
launchOptions:_launchOptions];
[_hostDelegate hostDidStart:self];
for (RCTFabricSurface *surface in [self _getAttachedSurfaces]) {
[surface resetWithSurfacePresenter:self.surfacePresenter];
[_instance callFunctionOnBufferedRuntimeExecutor:[surface](facebook::jsi::Runtime &_) { [surface start]; }];
}
[self _reloadWithShouldRestartSurfaces:YES];
}
- (void)dealloc
@@ -388,6 +370,11 @@ class RCTHostHostTargetDelegate : public facebook::react::jsinspector_modern::Ho
_contextContainerHandler = contextContainerHandler;
}
- (void)reload
{
[self _reloadWithShouldRestartSurfaces:NO];
}
#pragma mark - Private
- (void)_attachSurface:(RCTFabricSurface *)surface
@@ -432,6 +419,33 @@ class RCTHostHostTargetDelegate : public facebook::react::jsinspector_modern::Ho
RCTReloadCommandSetBundleURL(_bundleURL);
}
- (void)_reloadWithShouldRestartSurfaces:(BOOL)shouldRestartSurfaces
{
[_instance invalidate];
_instance = nil;
if (_bundleURLProvider) {
[self _setBundleURL:_bundleURLProvider()];
}
_instance = [[RCTInstance alloc] initWithDelegate:self
jsRuntimeFactory:[self _provideJSEngine]
bundleManager:_bundleManager
turboModuleManagerDelegate:_turboModuleManagerDelegate
moduleRegistry:_moduleRegistry
parentInspectorTarget:_inspectorTarget.get()
launchOptions:_launchOptions];
[_hostDelegate hostDidStart:self];
for (RCTFabricSurface *surface in [self _getAttachedSurfaces]) {
[surface resetWithSurfacePresenter:self.surfacePresenter];
if (shouldRestartSurfaces) {
[_instance callFunctionOnBufferedRuntimeExecutor:[surface](facebook::jsi::Runtime &_) { [surface start]; }];
}
}
}
#pragma mark - jsinspector_modern
- (jsinspector_modern::HostTarget *)inspectorTarget
{
return _inspectorTarget.get();
@@ -45,7 +45,7 @@ class SPMManager
log_warning "If you're using Xcode 15 or earlier you might need to close and reopen the Xcode workspace"
unless ENV["USE_FRAMEWORKS"] == "dynamic"
@dependencies_by_pod.each do |pod_name, dependencies|
log_warning "Pod #{pod_name} is using swift package(s) #{dependencies.map{|i| i[:products]}.flatten.uniq.join(", ")} with static linking, this might cause linker errors. Consider using USE_FRAMEOWRKS=dynamic, see https://github.com/facebook/react-native/pull/44627#issuecomment-2123119711 for more information"
log_warning "Pod #{pod_name} is using swift package(s) #{dependencies.map{|i| i[:products]}.flatten.uniq.join(", ")} with static linking, this might cause linker errors. Consider using USE_FRAMEWORKS=dynamic, see https://github.com/facebook/react-native/pull/44627#issuecomment-2123119711 for more information"
end
end
end
@@ -47,7 +47,11 @@ const RNCORE_CONFIGS = {
const CORE_LIBRARIES_WITH_OUTPUT_FOLDER = {
rncore: RNCORE_CONFIGS,
FBReactNativeSpec: {
ios: null,
ios: path.join(
REACT_NATIVE_PACKAGE_ROOT_FOLDER,
'React',
'FBReactNativeSpec',
),
android: path.join(
REACT_NATIVE_PACKAGE_ROOT_FOLDER,
'ReactAndroid',
@@ -451,13 +455,7 @@ function shouldSkipGenerationForRncore(schemaInfo, platform) {
if (platform !== 'ios' || schemaInfo.library.config.name !== 'rncore') {
return false;
}
const rncoreOutputPath = path.join(
RNCORE_CONFIGS.ios,
'react',
'renderer',
'components',
'rncore',
);
const rncoreOutputPath = CORE_LIBRARIES_WITH_OUTPUT_FOLDER.rncore.ios;
const rncoreAbsolutePath = path.resolve(rncoreOutputPath);
return (
rncoreAbsolutePath.includes('node_modules') &&
@@ -466,6 +464,26 @@ function shouldSkipGenerationForRncore(schemaInfo, platform) {
);
}
function shouldSkipGenerationForFBReactNativeSpec(schemaInfo, platform) {
if (
platform !== 'ios' ||
schemaInfo.library.config.name !== 'FBReactNativeSpec'
) {
return false;
}
const fbReactNativeSpecOutputPath =
CORE_LIBRARIES_WITH_OUTPUT_FOLDER.FBReactNativeSpec.ios;
const fbReactNativeSpecAbsolutePath = path.resolve(
fbReactNativeSpecOutputPath,
);
return (
fbReactNativeSpecAbsolutePath.includes('node_modules') &&
fs.existsSync(fbReactNativeSpecAbsolutePath) &&
fs.readdirSync(fbReactNativeSpecAbsolutePath).length > 0
);
}
function generateCode(outputPath, schemaInfo, includesGeneratedCode, platform) {
if (shouldSkipGenerationForRncore(schemaInfo, platform)) {
codegenLog(
@@ -475,6 +493,14 @@ function generateCode(outputPath, schemaInfo, includesGeneratedCode, platform) {
return;
}
if (shouldSkipGenerationForFBReactNativeSpec(schemaInfo, platform)) {
codegenLog(
'[Codegen - FBReactNativeSpec] Skipping iOS code generation for FBReactNativeSpec as it has been generated already.',
true,
);
return;
}
const libraryName = schemaInfo.library.config.name;
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), libraryName));
const tmpOutputDir = path.join(tmpDir, 'out');
@@ -615,6 +641,8 @@ function generateCustomURLHandlers(libraries, outputDir) {
.replace(/{imageDataDecoderClassNames}/, customImageDataDecoderClasses)
.replace(/{requestHandlersClassNames}/, customURLHandlerClasses);
fs.mkdirSync(outputDir, {recursive: true});
fs.writeFileSync(
path.join(outputDir, 'RCTModulesConformingToProtocolsProvider.mm'),
finalMMFile,
@@ -676,6 +704,23 @@ function generateRNCoreComponentsIOS(projectRoot /*: string */) /*: void*/ {
generateCode('', rncoreSchemaInfo, false, ios);
}
function generateFBReactNativeSpecIOS(projectRoot /*: string */) /*: void*/ {
const ios = 'ios';
buildCodegenIfNeeded();
const pkgJson = readPkgJsonInDirectory(projectRoot);
const fbReactNativeSpecLib = findProjectRootLibraries(
pkgJson,
projectRoot,
).filter(library => library.config.name === 'FBReactNativeSpec')[0];
if (!fbReactNativeSpecLib) {
throw new Error(
"[Codegen] Can't find FBReactNativeSpec library. Failed to generate rncore artifacts",
);
}
const fbReactNativeSchemaInfo = generateSchemaInfo(fbReactNativeSpecLib, ios);
generateCode('', fbReactNativeSchemaInfo, false, ios);
}
// Execute
/**
@@ -773,6 +818,7 @@ function execute(projectRoot, targetPlatform, baseOutputPath) {
module.exports = {
execute,
generateRNCoreComponentsIOS,
generateFBReactNativeSpecIOS,
// exported for testing purposes only:
_extractLibrariesFromJSON: extractLibrariesFromJSON,
_cleanupEmptyFilesAndFolders: cleanupEmptyFilesAndFolders,

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