Compare commits

...
28 Commits
Author SHA1 Message Date
CodemodService Bot 6a015b7832 Fix CQS signal readability-implicit-bool-conversion in xplat/js/react-native-github/packages
Reviewed By: rshest

Differential Revision: D81565980
2025-09-03 06:07:10 -07:00
Phil Pluckthun f170db412b Use autolinking react-native-config output in iOS artifacts generator (#53503)
Summary:
Resolves https://github.com/facebook/react-native/issues/53501

This is a pretty major oversight of (presumably) the old autolinking refactor. The iOS autolinking's second stage, invoked in `use_react_native!` does not accept the `react-native-config` sub-command's `react-native-config` output. This is only invoked and used in the prior step, `use_native_modules`.

The second step instead invokes old code that does something _similar_ to the new autolinking in `scripts/generate-artifacts-executor`, and happens to align in most cases. (But it does "autolinking" from scratch). tl;dr: When the results don't match up, things go wrong.

Instead, we now write the autolinking (react native config) results to a file, then read the output back in the second step.

This doesn't affect Android/Gradle, which are implemented correctly.

## Changelog:

[IOS] [FIXED] - Use autolinking-generated react-native-config output in second step of cocoapods linking that generates artifacts and generated source

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

Test Plan:
- See https://github.com/facebook/react-native/issues/53501 for failing repro
- Clone for working repro: https://github.com/byCedric/react-native-codegen-ios-autolinking/tree/fix-54503
  - Note: Contains this PR's changes as a patch
  - `bun install`
  - `bun expo run:ios`

Reviewed By: cortinico

Differential Revision: D81490755

Pulled By: cipolleschi

fbshipit-source-id: eefe786a116404f4ed24bd7125dfb108a811f71e
2025-09-03 05:34:11 -07:00
Samuel Susla 3895831c2b ship releaseImageDataWhenConsumed (#53576)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53576

## Changelog:

[iOS] [Fixed] - Images are removed from memory more aggressively to prevent OOMs

Reviewed By: rshest

Differential Revision: D81490116

fbshipit-source-id: d6b12af2d80e1c0a9ab3c624a549088b300feb3e
2025-09-03 04:41:32 -07:00
Nicola Corti 9fbce3eff1 Fix build from source for 0.82 due to Gradle 9.0 (#53560)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53560

Since Gradle 9.0, all the projects in the path must have an existing folder.
As we build :packages:react-native:ReactAndroid, we need to declare the folders
for :packages and :packages:react-native as well as otherwise the build from
source will fail with a missing folder exception.

Changelog:
[Android] [Fixed] - Fix build from source due to missing folder error on Gradle 9.0

Reviewed By: fabriziocucci

Differential Revision: D81482789

fbshipit-source-id: 609b503755486e10060a0f321bd0a38bd71864a1
2025-09-03 03:55:49 -07:00
Alex Hunt 7aef79bd78 Remove UNSAFE-ALLOW-SUBPATHS exports condition (#53566)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53566

TLDR; we never advertised this and it's not in use. We have an updated incoming plan for exposing internal private code to Expo / other frameworks.

Changelog: [Internal]

Reviewed By: christophpurrer

Differential Revision: D81490655

fbshipit-source-id: f3d64582f5e6092e4928865d868ea26867ee7e47
2025-09-03 03:05:31 -07:00
Christoph Purrer 9ef0d21344 Pass surfaceId to imageRequest (#53572)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53572

Changelog: [Internal]

Code refactoring to pass actual `surfaceid` to PrefetchResourcesMountItem

Reviewed By: andrewdacenko

Differential Revision: D81506929

fbshipit-source-id: 6c1cb91180cc23930986b258e2a8842560c0851a
2025-09-03 00:07:26 -07:00
Sam Zhou 4365c1c9f7 Cleanup codeless suppressions in xplat/js (#53573)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53573

Changelog: [Internal]

Reviewed By: marcoww6

Differential Revision: D81552699

fbshipit-source-id: 71b104174a8ad7fbf360cdd87109ce034f49ec70
2025-09-02 21:56:09 -07:00
Christoph Purrer f33a1cd260 Android: Schedule image prefetching on tree commit (#53555)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53555

Changelog: [Internal]

## TLDR;
We run the `ReactVitoImageManager.kt` on the Java Message Queue Thread (`mqt`) > Maybe running it on the `UiThread` (as Android view creation) solves the QE reegressions

## Issue
> Your experiment [qe:enable_image_prefetching_android_v4] is significantly moving important metric(s)

T235749297 > e.g negatively impact `sp_core` (Scroll Performance Core)

https://fburl.com/deltoid3/ef2fd92e

{F1981479985}

## Observation

After adding Perfetto traces in D80717558 and building a `automation_fbandroid_art_arm64_for_perftest_profileable` build > I see 'larger amounts' of `experimental_prefetchResource` on the JavaScript Message Queue Thread

 {F1981479808}

We do run this entire logic on the JavaScript Message Queue Thread

https://www.internalfb.com/code/fbsource/[368503303835439955d87d79439a3d19d979cd40]/fbandroid/java/com/facebook/fresco/vito/rn/ReactVitoImageManager.kt?lines=253-260

However when normally `mounting` Shadow Nodes in RN Android we jump from the  JavaScript Message Queue Thread to the Android UI Thread

https://www.internalfb.com/code/fbsource/[68603b276cb9de1ae2ecb83ec4a789ae3db3b051]/xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp?lines=626%2C638

->

https://www.internalfb.com/code/fbsource/[68603b276cb9de1ae2ecb83ec4a789ae3db3b051]/xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp?lines=690%2C701%2C872-883

->

https://www.internalfb.com/code/fbsource/[68603b276cb9de1ae2ecb83ec4a789ae3db3b051]/xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java?lines=897%2C943

->

https://www.internalfb.com/code/fbsource/[68603b276cb9de1ae2ecb83ec4a789ae3db3b051]/xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java?lines=938-946

## Idea

Run `imagePrefetcher?.prefetchResource` also on the UI thread

## Resources

### :: GDoc
- Image Prefetching for Android https://docs.google.com/document/d/1Yc5G5vuollx0I4tdXpE8Hgwn2DuIhJKwOTHak3g4Gu8/edit?fbclid=IwY2xjawLjgcBleHRuA2FlbQIxMQBicmlkETFra3N5WHg3OGV6UndYUmVTAR5KiXIDgrH2FW4HEBdezFBr2NqX4KPT6FzYQXD1sBRjEfq8d_x0JwQfeL_TXg_aem_ZqWb9dAJ59pHFfoHsrzwbw&pli=1&tab=t.0#heading=h.udv4z3lhwhf7
- React Field of View https://docs.google.com/document/d/1gHLF3oAv9JhKKcztM56iZZUPPWp0mBbjqDlosBkL1kE/edit?tab=t.0#heading=h.36p5puf8ufz7

### :: Fb4A (Facebook for Android)
The debug package name for fb4a `com.facebook.katana` is typically `com.facebook.wakizashi`

### :: Links
- How to Perfetto profile fb4a https://www.internalfb.com/wiki/Luna_Wei/Building_a_fb4a_Profile_Build/
- Building Catalyst Profile Build https://www.internalfb.com/wiki/Luna_Wei/Building_Catalyst_Profile_Build/
- Marketplace QE Regression Guide https://www.internalfb.com/intern/staticdocs/marketplace/performance/my-experiment-is-regressing-perf/
- Install for Profileable build https://www.internalfb.com/wiki/Metatrace/Metatrace-install_for_Profileable_build/
- Metatrace https://www.internalfb.com/wiki/Metatrace/

### Android Java Debug
https://www.internalfb.com/wiki/Platfrom_Health_Learnings/Onboarding_Material_or_New-hired_Engineers/How_to_Debug_FB4A_0/

```
arc focus clean --invalidate-caches-only
arc focus --targets <YOUR_TARGET> --open
```
in this case
```
arc focus --targets fb4a --open
```
It creates a `monoproject` now

 {F1981501090}

Reviewed By: javache

Differential Revision: D80950423

fbshipit-source-id: 5f1c4c096adab218a2d765d262901521bab2e6b3
2025-09-02 17:48:39 -07:00
Tim Yung d6ed32f8d6 VirtualView: Configurable Hidden Layout (#53571)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53571

Changes `VirtualView` so that its layout when hidden can be configured by call sites.

Previously, it was hardcoded to only retain the last known height. However, this logic only works for `VirtualView` children oriented in a column layout.

This change enables the use of `VirtualView` in more flexible abstractions that require different hidden styles (e.g. row or grid orientations).

Also, this changes the default behavior to set `minWidth` and `minHeight`, so that the default behavior is more general and more likely to work in a reasonable manner in more use cases.

NOTE: Ideally, we would be able to default to using `flexBasis` instead. However, the `hiddenStyle` function receives a `Rect` and does not know whether the parent's flex direction is row or column to influence whether to use `targetRect.width` or `targetRect.height`. This is an opportunity for future improvement.

Changelog:
[Internal]

Reviewed By: lunaleaps

Differential Revision: D81344126

fbshipit-source-id: 33d9e81601b671059f97b4590816243cbd24734a
2025-09-02 16:28:02 -07:00
Tim Yung 1604232e8d VirtualView: Create Experimental Feature Flag (#53533)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53533

Creates a new `enableVirtualViewExperimental` feature flag that determines whether `VirtualView` uses the old or new implementation.

Changelog:
[Internal]

Reviewed By: lunaleaps

Differential Revision: D81340963

fbshipit-source-id: f550fe4e4573e080eb8668077d0ad3ca53cd4d33
2025-09-02 16:28:02 -07:00
generatedunixname537391475639613 c1320eb2e1 xplat/js/react-native-github/packages/gradle-plugin/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/TaskConfiguration.kt (#53559)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53559

Reviewed By: cortinico

Differential Revision: D81476261

fbshipit-source-id: f3f38664a7dc63a11b027ab2b6a5a65ca374ebaa
2025-09-02 14:58:53 -07:00
Oskar Kwaśniewski 05c4321b19 fix: fallback alert controller to UIScreen size (#53500)
Summary:
This PR falls back to UIScreen when windowScene is not available.

<img width="500" alt="CleanShot 2025-08-28 at 14 30 59@2x" src="https://github.com/user-attachments/assets/9dda3153-dfe7-48a5-9d0e-5416c2e34c64" />

## Changelog:

[IOS] [FIXED] - Simplify RCTAlertController, don't create additional UIWindow

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

Test Plan:
Open the alert multiple times to check if everything works as expected.

Rollback Plan:

Reviewed By: javache

Differential Revision: D81410450

Pulled By: cipolleschi

fbshipit-source-id: c27ea98d9e811c2f259f0ff3c6689482d116c418
2025-09-02 11:19:42 -07:00
Christoph Purrer 61deab7f94 Add feature flag to trigger Android image prefetch request on the UI thread (#53554)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53554

Changelog: [Internal]

Reviewed By: lenaic

Differential Revision: D81468680

fbshipit-source-id: 9da40feaf90756645d2aed5c051dc137d7a90534
2025-09-02 10:44:59 -07:00
Jorge Cabiedes Acosta e1071ce683 Clean up legacy CSSBackgroundDrawable.java and enablNewBackgroundAndBorderDrawables featureflag (#53534)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53534

BackgroundDrawable and BorderDrawable have already substituted CSSBackgroundDrawable en every Android surface.
- Deleting CSSBackgroundDrawable.java and its callsites
- Deleting enableNewBackgroundAndDrawable featureflag

Just cleaning up what at this point is just dead code.

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D81330969

fbshipit-source-id: bcf66ec8d3225802432ae1d93a2b26ea65cfcda0
2025-09-02 10:19:57 -07:00
generatedunixname537391475639613 b2b992c5bb xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/image/ImageLoaderModule.kt (#53545)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53545

Reviewed By: cortinico

Differential Revision: D81428987

fbshipit-source-id: 7bd04528384bd96f659cf969806d367296665d97
2025-09-02 08:11:47 -07:00
Zeya Peng 716cbae68d support ObjectAnimatedNode (#53517)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53517

## Changelog:

[Internal] [Added] - support ObjectAnimatedNode

Reviewed By: christophpurrer, fabriziocucci

Differential Revision: D81260836

fbshipit-source-id: 82bdda59d54140189684003adfb1adf5c8e2904d
2025-09-02 07:06:09 -07:00
Vitali Zaidman 5128d35e69 changelog/v0.82.0-rc.0 (#53562)
Summary:
Changelog: [Internal] changelog for v0.82.0-rc.0

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

Reviewed By: fabriziocucci, cortinico

Differential Revision: D81483668

Pulled By: vzaidman

fbshipit-source-id: 6f044ce9918f147d981f87c9988e27600cac0ab7
2025-09-02 06:11:26 -07:00
Nick Lefever 8f0713fd4b Add test for empty layout culling skip (#53551)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53551

See title.

Follow up on D81044841

Changelog: [Internal]

Reviewed By: rshest

Differential Revision: D81447133

fbshipit-source-id: 7e6ca4523401c30c4861606c795f306193d97a15
2025-09-02 03:25:54 -07:00
Vitali Zaidman 6e47c953d3 fix release script testing artifact for rntester (#53552)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53552

Changelog: [Internal]

Reviewed By: fabriziocucci, cortinico, hoxyq

Differential Revision: D81452967

fbshipit-source-id: 3032b49b6c7fd49901b8f47886084c98479b368f
2025-09-02 03:01:57 -07:00
Phil Pluckthun 9731e8ebc5 Replace execSync with spawnSync for tarball extraction paths that need to be escaped (#53540)
Summary:
Follow-up to https://github.com/facebook/react-native/issues/53194

This wasn't previously visible in testing without prebuilds and without a release build. This doesn't show up in debug builds.

When testing more against paths that contain spaces, I noticed that release builds can still run into trouble due to the use of `execSync` without escaping paths. While, in other scripts that aren't used in user-projects (afaict), we often escape with quotes and rely on `execSync` calling the shell (due to its `shell: true` default), in some scripts we don't have quote escapes.

That said, since paths could in theory contain quotes, adding quotes wouldn't be sufficient. Instead, since the affected `tar` calls are really trivial, we can instead use `spawnSync` with the `shell: false` default, which escapes arguments automatically.

## Changelog:

[IOS] [FIXED] - fix Node scripts related to prebuilt tarball extraction for paths containing whitespaces

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

Test Plan: - Create a project in a folder `with spaces` and build a release build

Reviewed By: cipolleschi, cortinico

Differential Revision: D81406841

Pulled By: robhogan

fbshipit-source-id: 08bb06b2cd2b15dc17c2f95fab9024129deca6f3
2025-09-01 13:32:10 -07:00
Rubén Norte 727caca09c Set up modern performance APIs if the native module is available (#53431)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53431

Changelog: [internal]

This renames `setUpPerformanceObserver` as `setUpPerformanceModern` and removes the need to call it manually. If the native module is defined, we define the whole new API.

Reviewed By: javache

Differential Revision: D80803626

fbshipit-source-id: ef41cb9aa959ee898d32724c102d7597e6bee84e
2025-09-01 09:18:19 -07:00
Rubén Norte 1716b3ca5c Implement private constructors for Performance APIs (#53430)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53430

Changelog: [internal]

This fixes the spec-compliance of several classes in the Performance API by not allowing userland code to instantiate them directly.

This also exposes some missing interfaces from the Performance API in the global scope.

Reviewed By: rshest

Differential Revision: D80800076

fbshipit-source-id: f6439b9c7914817ef552e78fd61646ccab1e1de2
2025-09-01 09:18:19 -07:00
Rubén Norte bb508a4d94 Refactor PerformanceEntry and subclasses to use interfaces for initialization (#53429)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53429

Changelog: [internal]

This is a refactor of the types in `PerformanceEntry` and subclasses to accept interfaces instead of objects. This allows us to pass down the init object from subclasses to the superclass without having to create intermediate objects.

Additionally, this is also more semantically correct, as existing APIs don't need those options to be own properties of the init object.

Existing benchmark for Performance doesn't show any significant impact.

Reviewed By: rshest

Differential Revision: D80800075

fbshipit-source-id: ab439d70f4db9ce60e3089d89ccb105a91e7ef48
2025-09-01 09:18:19 -07:00
Rubén Norte 81f8b0a6bf Implement PerformanceObserver.takeRecords() (#53428)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53428

Changelog: [internal]

This is the last method in `PerformanceObserver` to implement. For some reason we never added it, even though it was trivial.

Reviewed By: rshest

Differential Revision: D80717237

fbshipit-source-id: ae3bd243d0f3f0fe4f0705437d78d14c532515f7
2025-09-01 09:18:19 -07:00
Rubén Norte 8ed0fa8dda Remove unnecessary references to internal types in performance tests (#53427)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53427

Changelog: [internal]

Migrate the imported types to the globally defined ones, so we follow the good practice of only accessing the public API in Fantom tests.

Reviewed By: rshest

Differential Revision: D80807160

fbshipit-source-id: 77d792b56b53c8da8409dd9133cd111afb8084f1
2025-09-01 09:18:19 -07:00
Rubén Norte 05be3742d4 Define Flow types for Performance APIs (#53433)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53433

Changelog: [internal]

This adds the definitions for the Web Performance APIs in the global scope.

Reviewed By: zeyap

Differential Revision: D80811659

fbshipit-source-id: a81117a27a480ba03f8feb2e813a3a66a10307f9
2025-09-01 09:18:19 -07:00
Alex Hunt 0a0b48b5ff Expose ListViewToken type as root export (#53539)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53539

Resolves https://github.com/react-native-community/discussions-and-proposals/discussions/893#discussioncomment-14190663.

Changelog:
[General][Added] - `ListViewToken` is now exposed when using `"react-native-strict-api"`

Reviewed By: rshest

Differential Revision: D81380882

fbshipit-source-id: 1da5c50eaec2f8dc4a8cde60e7441249556053a8
2025-09-01 08:39:22 -07:00
Pieter De Baets 46278e30e3 Dedupe Accessibility enum string conversions (#53550)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53550

Noticed some duplication between `getDiffProps` and `accessibilityPropsConversion`

Changelog: [Internal]

Reviewed By: lenaic, rshest

Differential Revision: D81435037

fbshipit-source-id: b2701f1aec5e647c165a0212f6180edba90fd9f9
2025-09-01 08:38:27 -07:00
103 changed files with 1598 additions and 2431 deletions
+181
View File
@@ -1,5 +1,186 @@
# Changelog
## v0.82.0-rc.0
### Breaking
- **Appearance.setColorScheme:** `Appearance.setColorScheme` no longer accepts a nullable value ([a4581ecd8b](https://github.com/facebook/react-native/commit/a4581ecd8b6df5efa44dfe6d43708320209c900b) by [@huntie](https://github.com/huntie))
- **`CxxSharedModuleWrapper`:** Removed CxxSharedModuleWrapper ([fafbee2402](https://github.com/facebook/react-native/commit/fafbee240235ea0e63eb01abd31ce32d6a576429) by [@javache](https://github.com/javache))
- **DOM API:** Enable DOM APIs in host component refs ([2ad845ccb2](https://github.com/facebook/react-native/commit/2ad845ccb2fea277e05513dcf41407026a8224f0) by [@rubennorte](https://github.com/rubennorte))
- **Error Handling:** Unhandled promises are now handled by ExceptionsManager.handleException, instead of being swallowed as Logbox Warnings. ([c4082c9ce2](https://github.com/facebook/react-native/commit/c4082c9ce208a324c2d011823ca2ba432411aafc) by [@krystofwoldrich](https://github.com/krystofwoldrich))
- **`shouldEmitW3CPointerEvents`:** Migrate `shouldPressibilityUseW3CPointerEventsForHover` to common private feature flags and remove `shouldEmitW3CPointerEvents` flag. ([fb4587780e](https://github.com/facebook/react-native/commit/fb4587780e8d6111139d73598a9a26ff392dee28) by [@coado](https://github.com/coado))
- **TurboModuleUtils:** Remove unused ReactCommon/TurboModuleUtils functions #deepCopyJSIObject and #deepCopyJSIArray ([ead669ade3](https://github.com/facebook/react-native/commit/ead669ade31ee703c407f96c0ce98d8f2991bdc8) by [@christophpurrer](https://github.com/christophpurrer))
#### Android specific
- **Deps:** Gradle to 9.0 ([7f93b664b4](https://github.com/facebook/react-native/commit/7f93b664b41ba11226aae7cca0e7c9b7f38a7d18) by [@cortinico](https://github.com/cortinico))
- **Image Prefetching:** Android: Image Prefetching send ImageResizeMode as enum value ([e30f34eda6](https://github.com/facebook/react-native/commit/e30f34eda689994cab8cd62aa38175238da8638b) by [@christophpurrer](https://github.com/christophpurrer))
- **New Architecture:** Remove possibility to newArchEnabled=false in 0.82 ([d5d21d0614](https://github.com/facebook/react-native/commit/d5d21d061493ee973c789a7c6ab8cceebc1f04f9) by [@cortinico](https://github.com/cortinico))
- **`reactNativeHost`:** Throw Exception if ReactApplication.reactNativeHost is not overriden ([0d3791ca0a](https://github.com/facebook/react-native/commit/0d3791ca0ab30d5a12881c9901f31291b3e998c6) by [@mdvacca](https://github.com/mdvacca))
- **ViewManagerInterfaces:** Migrate ViewManagerInterfaces to kotlin. Some types in code generated ViewManagerInterfaces might differ. e.g. this will start enforcing nullability in parameters of viewManagerInterface methods (e.g. String commands parameters are not nullable, view params are not nullable in any method, etc) ([79ca9036d3](https://github.com/facebook/react-native/commit/79ca9036d39c16cd115dc0427cb7092f358ac47e) by [@mdvacca](https://github.com/mdvacca))
#### iOS Specific
- **New Architecture:** Removed the opt-out from the New Architecture. ([83e6eaf693](https://github.com/facebook/react-native/commit/83e6eaf693f967b7870a5d4896cbb799206a14f0) by [@cipolleschi](https://github.com/cipolleschi))
### Added
- **Animated:** `Animated.CompositeAnomation` is now exposed when using `"react-native-strict-api"` ([024d25794a](https://github.com/facebook/react-native/commit/024d25794a51c94c877c1dfa115a82ebbf559614) by [@huntie](https://github.com/huntie))
- **Animated:** Allow calling createAnimatedNode without batching ([d9d9a49e18](https://github.com/facebook/react-native/commit/d9d9a49e18f3c51caa18cf7da0a1fcd62f1ecf18) by [@zeyap](https://github.com/zeyap))
- **Animated:** Allow filter usage with native animated driver. ([138d0eb01d](https://github.com/facebook/react-native/commit/138d0eb01dbe597261459a37d364d1780c3ef228) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway))
- **API:** Expose NativeComponentRegistry API as JavaScript root export ([f936780cd5](https://github.com/facebook/react-native/commit/f936780cd5c0c17797f9d2bbc8f5cee81c2eefce) by [@zhongwuzw](https://github.com/zhongwuzw))
- **API:** Expose `ReactNativeVersion` API as JavaScript root export ([ec5638abd0](https://github.com/facebook/react-native/commit/ec5638abd0e872be62b6ea5d8df9bed6335c2191) by [@huntie](https://github.com/huntie))
- **Codegen:** Added getDebugProps to codegen ([e547f466ee](https://github.com/facebook/react-native/commit/e547f466ee41415a75ec6b6f910171285ee7bfc3) by [@cipolleschi](https://github.com/cipolleschi))
- **Pressable:** Allow setting `blockNativeResponder` on Pressable ([6e4d23ded2](https://github.com/facebook/react-native/commit/6e4d23ded2da4a717bafcc032e3d7a0a5fbe3731) by [@zeyap](https://github.com/zeyap))
- **Yoga/API:** Make yoga/Yoga.h an umbrell header ([8ed2cee80e](https://github.com/facebook/react-native/commit/8ed2cee80e0aaac2f2a6a897ba450888f274a5a4) by [@rudybear](https://github.com/rudybear))
#### Android specific
- **Build Type:** Create a `debugOptimized` `buildType` for Android ([eb2461c7c9](https://github.com/facebook/react-native/commit/eb2461c7c902ebed272bd2d22d6cff4d3c586da6) by [@cortinico](https://github.com/cortinico))
- **DevMenu:** Add long-press back as an option to open the DevMenu for devices that lack menu & fast-forward. ([32d37f03ad](https://github.com/facebook/react-native/commit/32d37f03ad05290205a4f04d756f6e1880c4ff89) by [@sbuggay](https://github.com/sbuggay))
- **DevTools:** `DevSupportManager::openDebugger` now supports an optional `panel` param determining the starting panel ([7eb3536728](https://github.com/facebook/react-native/commit/7eb3536728c4a20f7e51245f4f7b64aa505bd799) by [@huntie](https://github.com/huntie))
- **DevTools:** Adds a landing view parameter to opening RNDT, enabling arbitrary view focus on launch. ([635c707eec](https://github.com/facebook/react-native/commit/635c707eec18f6d2ceceac2dcee9f458f17f8aab) by [@sbuggay](https://github.com/sbuggay))
- **HWInput:** Channel up/down hardware events. ([c2a3e4420e](https://github.com/facebook/react-native/commit/c2a3e4420e07147f9a040a665da98dbe22b87a2a) by [@sbuggay](https://github.com/sbuggay))
- **Manifest:** Add support to specify a single Manifest rather than 2 (main/debug) by using the `usesCleartextTraffic` manifest placeholder which is autoconfigured by RNGP. ([d89acc1596](https://github.com/facebook/react-native/commit/d89acc1596345534882938d2bbf40275a6cb89bd) by [@cortinico](https://github.com/cortinico))
#### iOS specific
- **API:** Add deprecation message for RCTAppdelegate APIs ([d503ea4efc](https://github.com/facebook/react-native/commit/d503ea4efc84b6511cef2a46421a16e044862e88) by [@cipolleschi](https://github.com/cipolleschi))
- **New Architecture:** Add warning if RCT_NEW_ARCH_ENABLED is set to 0 ([7d0bef2f25](https://github.com/facebook/react-native/commit/7d0bef2f25a206d917e7f5cc2b9a6c088f13a832) by [@cipolleschi](https://github.com/cipolleschi))
### Changed
- **Font:** Enabled `enableFontScaleChangesUpdatingLayout` feature flag by default ([686d14f1d1](https://github.com/facebook/react-native/commit/686d14f1d16c2f02720104ddd395f7d27c908350) by [@j-piasecki](https://github.com/j-piasecki))
- **Hermes:** Changed names of hermes binaries ([776fca1e7c](https://github.com/facebook/react-native/commit/776fca1e7c978a2d8f817d042836073e4dcb4e0e) by [@j-piasecki](https://github.com/j-piasecki))
- **Metro:** Bump Metro to ^0.83.1 ([840fd6c83f](https://github.com/facebook/react-native/commit/840fd6c83f45326a796bf2823f8c2fa942aed06c) by [@robhogan](https://github.com/robhogan))
- **React:** Bumped React to 19.1.1 ([ec5a98b1f5](https://github.com/facebook/react-native/commit/ec5a98b1f5c2137f5f6ff5f5f6706f20384c44df) by [@cipolleschi](https://github.com/cipolleschi))
- **Runtime:** CDP backend now accepts `addBinding` and `removeBinding` methods earlier, before a Runtime exists. ([3271e57c75](https://github.com/facebook/react-native/commit/3271e57c751e7d1193c1e9f7b53e545231511b9d) by [@motiz88](https://github.com/motiz88))
- **Typing:** Update types for Platform.version ([f6ba2dbf3b](https://github.com/facebook/react-native/commit/f6ba2dbf3b4c85da1a7f9079fd366a41b160fa69) by [@riteshshukla04](https://github.com/riteshshukla04))
- **UIManager:** Avoid unnecessary copy of view props map in UIManager::updateShadowTree ([5b38bb4745](https://github.com/facebook/react-native/commit/5b38bb47457f853c2c3d5f275facbb9fbc150683) by [@zeyap](https://github.com/zeyap))
#### Android specific
- **AGP:** AGP to 8.12.0 ([742ef3d661](https://github.com/facebook/react-native/commit/742ef3d6615c8c1202e9f683e6127ac97d7a9e23) by [@cortinico](https://github.com/cortinico))
- **DevSupportManager:** DevSupport `openDebugger()` methods now accept a `panel: String?` param. Frameworks directly implementing `DevSupportManager` will need to adjust call signatures. ([9dba7112cf](https://github.com/facebook/react-native/commit/9dba7112cfd09b02300869a77dba3dca16f49a28) by [@huntie](https://github.com/huntie))
- **Kotlin:**Migrated TextAttributeProps to Kotlin. You might need to update your property access to use camelCase instead of Hungarian notation. ([fa921b3c7b](https://github.com/facebook/react-native/commit/fa921b3c7b289800a79196468f993a0eb0bf693f) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrated ReactBaseTextShadowNode to Kotlin. You might need to update your property access to use camelCase instead of Hungarian notation. ([8ccfff9a46](https://github.com/facebook/react-native/commit/8ccfff9a46f317fd78f478c8b3f180441535d1ca) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrated com.facebook.react.bridge.Arguments to Kotlin. ([2534aeaddb](https://github.com/facebook/react-native/commit/2534aeaddb0490b69dfaba6b8d316616c7e10a9c) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `YogaConfig` to Kotlin ([4d5caef76b](https://github.com/facebook/react-native/commit/4d5caef76b83eb7e983364ecc81abb6027e5f98e) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `YogaValue` to Kotlin ([4340dcbae8](https://github.com/facebook/react-native/commit/4340dcbae8fc41cde844e805a1ebfc23d23d164f) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `YogaNative` to Kotlin ([bc54a06fcb](https://github.com/facebook/react-native/commit/bc54a06fcb5b5d1efd8996d8568733b657fc1b06) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `YogaConfigFactory` to Kotlin ([33ca53d9db](https://github.com/facebook/react-native/commit/33ca53d9dbe53b92d65f82dbd53a2e9f23efd4f3) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `DoNotStrip` to Kotlin ([35d8086881](https://github.com/facebook/react-native/commit/35d8086881fac643b0ebc0d53aaf7e79b7ccd830) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `YogaLayoutType` to Kotlin ([7e461003c6](https://github.com/facebook/react-native/commit/7e461003c6592c8c539960bd5e8169c48dd27f50) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `LayoutPassReason` to Kotlin ([db2a9c089c](https://github.com/facebook/react-native/commit/db2a9c089cd5802d99e0fc86e4dc0dbf7c888307) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `YogaNodeFactory` to Kotlin ([40afa75a7c](https://github.com/facebook/react-native/commit/40afa75a7c816a5581223c7bcd1b65b8713edf47) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `YogaMeasureOutput` to Kotlin ([453508ada8](https://github.com/facebook/react-native/commit/453508ada837554455733e3ca94440a7143f51b1) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `YogaMeasureFunction` to Kotlin ([05eddd354e](https://github.com/facebook/react-native/commit/05eddd354e2e80ad3c95ed5a2199a59a77317891) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `YogaStyleInputs` to Kotlin ([001736000f](https://github.com/facebook/react-native/commit/001736000f69ce98db86c17707408bbf3f0ae9a5) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `YogaBaselineFunction` to Kotlin ([a2eb3b299d](https://github.com/facebook/react-native/commit/a2eb3b299dddea60c510821b662dfed55b334df7) by [@mateoguzmana](https://github.com/mateoguzmana))
- **Kotlin:** Migrate `YogaLogger` to Kotlin ([9c9a39b58e](https://github.com/facebook/react-native/commit/9c9a39b58e12bc734c27a5d9306e792b0dcaf927) by [@mateoguzmana](https://github.com/mateoguzmana))
- **OnBatchCompleteListener:** Make OnBatchCompleteListener interface internal ([046ff8e58b](https://github.com/facebook/react-native/commit/046ff8e58bed5da0f19adc860b327c7248b19f48) by [@cortinico](https://github.com/cortinico))
- **ReactSurface:** Changed return type of ReactSurfaceImpl.view to ReactSurfaceView to align with parameter recived by ReactSurfaceImpl.attachView() ([41029d8e91](https://github.com/facebook/react-native/commit/41029d8e91492c34c377374b442b31755874618c) by [@mdvacca](https://github.com/mdvacca))
- **TextAttributeProps:** Deprecate the field `TextAttributeProps.effectiveLineHeight`. This field was public but never used in OSS. ([ede037ade7](https://github.com/facebook/react-native/commit/ede037ade795bd44725f9bd82cace193a74aa68d) by [@cortinico](https://github.com/cortinico))
- **ViewManagers:** Changed method arguments names for Core ViewManagers to match the names of ViewManagerInterfaces ([e7d9e0d197](https://github.com/facebook/react-native/commit/e7d9e0d1977c136a85b9a78ef36a258631d1e9ba) by [@mdvacca](https://github.com/mdvacca))
### Deprecated
- **StyleSheet:** `StyleSheet.absoluteFillObject` is deprecated in favor of `StyleSheet.absoluteFill` (equivalent). ([83e19813ff](https://github.com/facebook/react-native/commit/83e19813ff5498ab3497d97fe38dba63a5554425) by [@huntie](https://github.com/huntie))
- Deprecate all the c++ classes not used by interop, or the new architecture. ([9539cd2626](https://github.com/facebook/react-native/commit/9539cd26261aef646379104833c7f719e3d83d02) by [@RSNara](https://github.com/RSNara))
#### Android specific
- **DevMenu:** Remove bridge mode string from React Native Dev Menu title ([1c838f32a9](https://github.com/facebook/react-native/commit/1c838f32a9bcee3867ec0502b344889308302f26) by [@sbuggay](https://github.com/sbuggay))
- **New Architecture:** DefaultDevSupportManagerFactory.create() method used for Old Arch ([026e22bb8d](https://github.com/facebook/react-native/commit/026e22bb8d7b38b3bd66ffcc7d4ee446adfee943) by [@cortinico](https://github.com/cortinico))
- **New Architecture:** Deprecate `BridgelessReactContext.getCatalystInstance()` method ([4583fbe052](https://github.com/facebook/react-native/commit/4583fbe052924df1ad030e51ad80e8d754a4c5a4) by [@cortinico](https://github.com/cortinico))
- **New Architecture:** Deprecate legacy architecture classes ReactInstanceManager and ReactInstanceManagerBuilder, these classes will be deleted in a future release ([fb84932e48](https://github.com/facebook/react-native/commit/fb84932e4894a45c0a2725e1d665acdf7bcea435) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Depreacate `CoreModulesPackage` and `NativeModuleRegistryBuilder` legacy architecture classes, these classes unused in the new architecture and will be deleted in the future ([d3bbbd893a](https://github.com/facebook/react-native/commit/d3bbbd893acd500237ab4e1778c6a2e0fe1948a9) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate Legacy Architecture ViewManagers, these classes are not used as part of the new architecture and will be deleted in the future ([da74d5da2c](https://github.com/facebook/react-native/commit/da74d5da2cac5306e37368c65490c434e7ff9f4f) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate LegacyArchitecture ShadowNode classes included in React Native ([07091a9ae8](https://github.com/facebook/react-native/commit/07091a9ae8d70a601d969d9def4952563d3b7bcf) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Depreacte all LegacyArchitecture classes from the bridge package ([c1f7c5e321](https://github.com/facebook/react-native/commit/c1f7c5e3217a7e8a77a859652aadff2a41e3ea58) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate LegacyArchitecture class UIManagerProvider ([b29b86f275](https://github.com/facebook/react-native/commit/b29b86f27553eac50daa18ffb6bca07be3f24f25) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate BridgeDevSupportManager and JSInstance ([25c011eb4d](https://github.com/facebook/react-native/commit/25c011eb4d403040b57e338bec704769de20793c) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate NativeModuleRegistry Legacy Architecture class ([22e4c25211](https://github.com/facebook/react-native/commit/22e4c252116da1a6658b15a84720e0ee314dddd6) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate subset of LegacyArchitecture classes in com/facebook/react/bridge ([78a3ff81eb](https://github.com/facebook/react-native/commit/78a3ff81eb38ae26fb15106580de841477897101) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate LegacyArchitecture class FrescoBasedReactTextInlineImageShadowNode ([25f466cc4d](https://github.com/facebook/react-native/commit/25f466cc4dd28c962b967475c04c284d26efb722) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate Legacy Architecture class CallbackImpl ([718126fcf0](https://github.com/facebook/react-native/commit/718126fcf0296969ee659c31fae51b4317c896d3) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate LegacyArchitecture class JavaMethodWrapper ([19a99dd088](https://github.com/facebook/react-native/commit/19a99dd0882d786daea3db486fd3aed3c10419b5) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate Legacy Architecture ShadowNode classes ([c4715886a9](https://github.com/facebook/react-native/commit/c4715886a917eb3eb63aab366de5225090dff5a1) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate LegacyArchitecture UIManagerModules class ([85610c8b43](https://github.com/facebook/react-native/commit/85610c8b43ea132154cddcfed973ee6ceb3e55b3) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate LegacyArchitecture classes from com/facebook/react/uimanager ([7f5b2b8f84](https://github.com/facebook/react-native/commit/7f5b2b8f84d7941891a447978c6adc17929ef87f) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate LegacyArchitecture classes from package com.facebook.react.uimanager ([39d24bade3](https://github.com/facebook/react-native/commit/39d24bade317920544a3715e3a1f131663d8cded) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** Deprecate LegacyArchitecture classes from LayoutAnimation package ([f67078df07](https://github.com/facebook/react-native/commit/f67078df07b6c9ad995eb43ff47fc4a43bb2eaee) by [@mdvacca](https://github.com/mdvacca))
- **New Architecture:** ReactPackageLogger is not supported in the new architecture and being deprecated ([65671108f6](https://github.com/facebook/react-native/commit/65671108f69d9b23a011841102e4141293581d9c) by [@mdvacca](https://github.com/mdvacca))
#### iOS specific
- **DevMenu:** Remove bridge mode title and description from React Native Dev Menu title ([775daf5972](https://github.com/facebook/react-native/commit/775daf597280db94354ed484f2ce81690f1eb7b0) by [@sbuggay](https://github.com/sbuggay))
- **New Architecture:** Deprecate all the objc classes not used by interop, or the new architecture. ([70f53ac4ea](https://github.com/facebook/react-native/commit/70f53ac4ea144020560906f5931e480ed4dee87c) by [@RSNara](https://github.com/RSNara))
### Removed
- **New Architecture:** Core: Remove legacy components ([9c8a4c2297](https://github.com/facebook/react-native/commit/9c8a4c22973c7ce6fcf6b5d22c6d5fd4c6dc0d92) by [@RSNara](https://github.com/RSNara))
#### Android specific
- **DefaultReactHost:** Delete unused `DefaultReactHost.getDefaultReactHost()` overload ([d35ddb5e59](https://github.com/facebook/react-native/commit/d35ddb5e59a8cb990dd61a154a8e15e9542f8b15) by [@cortinico](https://github.com/cortinico))
- **DefaultReactHost:** Remove deprecated DefaultReactHost.getDefaultReactHost() overload - part 2 ([bda6acf3b0](https://github.com/facebook/react-native/commit/bda6acf3b08779c0dae7bdadbc9913eea79acd0d) by [@cortinico](https://github.com/cortinico))
- **DefaultReactHost:** Remove deprecated DefaultReactHost.getDefaultReactHost() overload - part 1 ([474f455a75](https://github.com/facebook/react-native/commit/474f455a7591049382da0d0308ddd21589f0cc7e) by [@cortinico](https://github.com/cortinico))
- **Inspector:** Removed unused `Inspector` public class from React Android ([cf528526cc](https://github.com/facebook/react-native/commit/cf528526cc375f1003125cf63f66fbd88790ceae) by [@cortinico](https://github.com/cortinico))
- **JSONArguments:** Remove the `com.facebook.react.bridge.JSONArguments` class ([04ae15d99b](https://github.com/facebook/react-native/commit/04ae15d99bb2ee6f7987bbe8c3d7acfdd46a482f) by [@cortinico](https://github.com/cortinico))
- **MessageQueueThreadPerfStats:** Deprecated MessageQueueThreadPerfStats API and replaced with stub. ([3bf5cb3d0e](https://github.com/facebook/react-native/commit/3bf5cb3d0e7d9d1749ef19a8392b9bbd3ec7ab7d) by [@javache](https://github.com/javache))
### Fixed
- **Accessibility:** Fix for setting the default value for accessibility props ([586f5ba89c](https://github.com/facebook/react-native/commit/586f5ba89cc20a81a9e2d5d0f2708e9cd1b440c0) by Vineeth K)
- **Accessibility:** `aria-hidden` support for `Text`, non-editable `TextInput` and `Image` ([0f39fc3000](https://github.com/facebook/react-native/commit/0f39fc3000411a43711814e0ab9cca1f7093b625) by [@mdjastrzebski](https://github.com/mdjastrzebski))
- **Build:** Fixed babel plugin validation error when coverage instrumentation is enabled ([191ddc1ec7](https://github.com/facebook/react-native/commit/191ddc1ec72be6641ebb8b9cb729cf0e142fff55) by Umar Mohammad)
- **Casting:** Casting rawValue to int was incorrectly truncating ([31b9f10364](https://github.com/facebook/react-native/commit/31b9f103645e67586bdfc5c2f590c28c04ca3871) by [@javache](https://github.com/javache))
- **Codegen:** Help Codegen find library's package.json if some libraries using `exports` field in their package.json file and the `./package.json` subpath is not explicitly defined ([739dfd2141](https://github.com/facebook/react-native/commit/739dfd2141015a8126448bda64a559f5bf22672e) by [@RakaDoank](https://github.com/RakaDoank))
- **Hermes:** Change leftover references to `hermes.framework` to `hermesvm.framework` ([7f051c5470](https://github.com/facebook/react-native/commit/7f051c54701b3585f76f63846abbf7e68e2688d2) by [@j-piasecki](https://github.com/j-piasecki))
- **Performance Panel:** Fix typo in Performance.js type checking condition ([6caf2dfa38](https://github.com/facebook/react-native/commit/6caf2dfa382fd4f1184b8d21b030c36687a256e4) by [@YangJonghun](https://github.com/YangJonghun))
- **Performance Panel:** Add default cases to switch statements in headers ([323fe3a5d4](https://github.com/facebook/react-native/commit/323fe3a5d471ae5a2f94d5c2bd13cc97feffe0a5) by [@NSProgrammer](https://github.com/NSProgrammer))
- **ReactCommon:** Bring back ContextContainer::Shared = std::shared_ptr<const ContextContainer> alias ([daeb6e99ab](https://github.com/facebook/react-native/commit/daeb6e99abbca2b6395a9a703d2b0bb9e5091fb7) by [@christophpurrer](https://github.com/christophpurrer))
- **ReactCommon:** Bring back SharedImageManager = std::shared_ptr<ImageManager> alias ([4718b35259](https://github.com/facebook/react-native/commit/4718b35259135b3503033a0061ae84e15d4eb450) by [@christophpurrer](https://github.com/christophpurrer))
- **ReactCommon:** Fixed Type Conversion Error in DynamicEventPayload ([ff38d59cff](https://github.com/facebook/react-native/commit/ff38d59cff92e0a50f0dd70384fbc4dd11d969c4) by Harini Malothu)
- **ReactCommon:** Fixed Type Conversion Error in CSSHexColor ([2ca88a0069](https://github.com/facebook/react-native/commit/2ca88a0069969bf115da6f0ea9f2fbbae9c9226c) by [@anupriya13](https://github.com/anupriya13))
- **TestCallInvoker:** Fix memory leak in TestCallInvoker ([9f2fbc23e4](https://github.com/facebook/react-native/commit/9f2fbc23e48af9be56b3729d514fbb3fff4ba376) by [@christophpurrer](https://github.com/christophpurrer))
#### Android specific
- **Accessability:** Stabilize custom accessibility action IDs to prevent "incompatible action" errors in TalkBack. ([626568f9a3](https://github.com/facebook/react-native/commit/626568f9a3f956a52f6c55df1dc3bc5cd017e353) by [@leg234-png](https://github.com/leg234-png))
- **Determinism:** Turned off build IDs for native libraries, fixing issues with reproducibility ([4b8dbe7642](https://github.com/facebook/react-native/commit/4b8dbe7642be53d0ccfc68ca8c9b3f5e750a68c0) by [@Rexogamer](https://github.com/Rexogamer))
- **DevTools:** Fix stack trace linkifying failing when using Android emulator and other situations where the device and debugger have different bundle urls ([794df48ad6](https://github.com/facebook/react-native/commit/794df48ad6a259022e66de1a38ff54b5ec67c3e4) by [@vzaidman](https://github.com/vzaidman))
- **Edge to Edge:** Fix `Dimensions` `window` values on Android < 15 when edge-to-edge is enabled ([3b185e4bce](https://github.com/facebook/react-native/commit/3b185e4bcef24e0689cccd4cf250d469b114d4da) by [@zoontek](https://github.com/zoontek))
- **Fonts:** Update font scale when recreating `RootView` ([5cda3065ce](https://github.com/facebook/react-native/commit/5cda3065ce635460a7458cbab5c10e24bea3bfe2) by [@j-piasecki](https://github.com/j-piasecki))
- **Fonts:** Fix incorrect positioning of inline view at the end of string when RTL text in LTR container ([7f224941bb](https://github.com/facebook/react-native/commit/7f224941bb807919b487d8e1634dd2124f9258b8) by [@NickGerleman](https://github.com/NickGerleman))
- **Locale:** Use the first available locale instead of the default one to decide `isDevicePreferredLanguageRTL` ([a03780d279](https://github.com/facebook/react-native/commit/a03780d279d0944e0dcbbf5a93680775006598b0) by Kaining Zhong)
- **New Architecture:** Correctly account for insets on first render of Modals on New Arch ([2e76fc8e8e](https://github.com/facebook/react-native/commit/2e76fc8e8ea01fbce5bd131f675364e688f49088) by [@cortinico](https://github.com/cortinico))
- **Performance:** Fix mounting is very slow on Android by shipping native transform optimizations ([c557311ed8](https://github.com/facebook/react-native/commit/c557311ed836cded8548c5bca32f3eded0abc7ff) by [@cortinico](https://github.com/cortinico))
- **Scroll:** Fixed an issue where shadow tree and native tree layouts mismatch at the end of a scroll event ([1828c53f85](https://github.com/facebook/react-native/commit/1828c53f85faf599a485b3859f8b62586696265f) by [@Abbondanzo](https://github.com/Abbondanzo))
- **Start up:** Fix wrong default for `jsBundleAssetPath` on `DefaultReactHost` ([2246e2b82c](https://github.com/facebook/react-native/commit/2246e2b82cf0c433f9a9b385ea98e532c6f322c6) by [@cortinico](https://github.com/cortinico))
#### iOS specific
- **Build:** Fixed using USE_FRAMEWORKS (static/dynamic) with precompiled binaries ([e723ca4d6b](https://github.com/facebook/react-native/commit/e723ca4d6b86d5a98449498395c700513ceba555) by [@chrfalch](https://github.com/chrfalch))
- **Build:** Non-UTF8 crashes Info.plist local frameworks ([91e69b5d4c](https://github.com/facebook/react-native/commit/91e69b5d4c768278680a8d9ae979bc267624ce98) by [@philipheinser](https://github.com/philipheinser))
- **Build:** Fixed variable naming error in `set_fast_float_config` method in `react_native_pods.rb` ([327057fad5](https://github.com/facebook/react-native/commit/327057fad5c78a95e6c039bfe380d78672e83a43) by [@eliotfallon213](https://github.com/eliotfallon213))
- **Build:** Fix pure cocoapods dynamic framework build ([aa4555eaf1](https://github.com/facebook/react-native/commit/aa4555eaf1b6aab83660c600e867fa6c2da4128e) by [@cipolleschi](https://github.com/cipolleschi))
- **Native Modules:** Fix concurrent calls into resolve/reject inside native modules ([dc879950d1](https://github.com/facebook/react-native/commit/dc879950d196dfd429229f1c4c8e743ef1799d11) by [@RSNara](https://github.com/RSNara))
- **New Architecture:** Fix overriding (xc)framework Info.plist files with RCTNewArchEnabled field ([f84514a88b](https://github.com/facebook/react-native/commit/f84514a88be00f8dcae7972f84aa89d829392a58) by [@msynowski](https://github.com/msynowski))
- **RCTPullToRefreshViewComponentView:** Properly initialize the `RCTPullToRefreshViewComponentView` ([27217e8bd6](https://github.com/facebook/react-native/commit/27217e8bd601757b5db6efc022db428b552a2aa4) by [@cipolleschi](https://github.com/cipolleschi))
- **RCTReactNativeFactory:** Ask the delegate for `getModuleForClass` and `getModuleInstanceFromClass` ([85b47afb48](https://github.com/facebook/react-native/commit/85b47afb48e50b036d2c2c79a008f571d3bfcb43) by [@cipolleschi](https://github.com/cipolleschi))
- **ScrollView:** Correctly propagate `ScrollView` props to `RefreshControl` ([09daad27ea](https://github.com/facebook/react-native/commit/09daad27ea22b83fab65176ea3c7f5f1488ba408) by [@cipolleschi](https://github.com/cipolleschi))
- **ScrollView:** Make sure that `ScrollView` recycled refresh control have the right props setup. ([21b93d8d7d](https://github.com/facebook/react-native/commit/21b93d8d7d46a26f728df19764f85a8aebf318bb) by [@cipolleschi](https://github.com/cipolleschi))
- **Switch:** Fixed a crash when rendering the `Switch` component ([28275a0f7b](https://github.com/facebook/react-native/commit/28275a0f7b182a215010d47fb841d9c2c36bb24c) by [@cipolleschi](https://github.com/cipolleschi))
- **Text:** Fix selectable prop not working correctly ([f004cd39bc](https://github.com/facebook/react-native/commit/f004cd39bc4b632006085cbcf61df52bc5d25242) by [@iamAbhi-916](https://github.com/iamAbhi-916))
- **TextInput:** Update TextInput recycling logic to clean up the `inputAccessoryView` dependency. ([eb08f54594](https://github.com/facebook/react-native/commit/eb08f545948de9e2eca91ab3cb7569670c553b15) by [@ArturKalach](https://github.com/ArturKalach))
- **TextInput:** Fixed TextInput behavior when `maxLength={null}` is passed ([56ad53cb14](https://github.com/facebook/react-native/commit/56ad53cb14b5c842714fcf976b6ba81f68c140f2) by [@cipolleschi](https://github.com/cipolleschi))
- **View:** Inline `View` alignment with `lineHeight` in Text ([6da351a5ed](https://github.com/facebook/react-native/commit/6da351a5ed80a10138a5558afcb380410c8a93c9) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway))
### Security
- **Network:** Fixed vulnerability on undici and on-headers ([dd00c9055a](https://github.com/facebook/react-native/commit/dd00c9055a8f0c9ceac1716385a8a9874f7a4c2e) by [@cipolleschi](https://github.com/cipolleschi))
## v0.81.1
### Added
@@ -88,7 +88,6 @@ Diff: ${styleText(['dim', 'underline'], newVersion?.diffUrl ?? 'none')}
}
}
// $FlowFixMe
function isDiffPurgeEntry(data: Partial<DiffPurge>): data is DiffPurge {
return (
// $FlowFixMe[incompatible-type-guard]
@@ -65,25 +65,26 @@ internal fun Project.configureReactTasks(variant: Variant, config: ReactExtensio
if (!isDebuggableVariant) {
val entryFileEnvVariable = System.getenv("ENTRY_FILE")
val bundleTask =
tasks.register("createBundle${targetName}JsAndAssets", BundleHermesCTask::class.java) {
it.root.set(config.root)
it.nodeExecutableAndArgs.set(config.nodeExecutableAndArgs)
it.cliFile.set(cliFile)
it.bundleCommand.set(config.bundleCommand)
it.entryFile.set(detectedEntryFile(config, entryFileEnvVariable))
it.extraPackagerArgs.set(config.extraPackagerArgs)
it.bundleConfig.set(config.bundleConfig)
it.bundleAssetName.set(config.bundleAssetName)
it.jsBundleDir.set(jsBundleDir)
it.resourcesDir.set(resourcesDir)
it.hermesEnabled.set(isHermesEnabledInThisVariant)
it.minifyEnabled.set(!isHermesEnabledInThisVariant)
it.devEnabled.set(false)
it.jsIntermediateSourceMapsDir.set(jsIntermediateSourceMapsDir)
it.jsSourceMapsDir.set(jsSourceMapsDir)
it.hermesCommand.set(config.hermesCommand)
it.hermesFlags.set(config.hermesFlags)
it.reactNativeDir.set(config.reactNativeDir)
tasks.register("createBundle${targetName}JsAndAssets", BundleHermesCTask::class.java) { task
->
task.root.set(config.root)
task.nodeExecutableAndArgs.set(config.nodeExecutableAndArgs)
task.cliFile.set(cliFile)
task.bundleCommand.set(config.bundleCommand)
task.entryFile.set(detectedEntryFile(config, entryFileEnvVariable))
task.extraPackagerArgs.set(config.extraPackagerArgs)
task.bundleConfig.set(config.bundleConfig)
task.bundleAssetName.set(config.bundleAssetName)
task.jsBundleDir.set(jsBundleDir)
task.resourcesDir.set(resourcesDir)
task.hermesEnabled.set(isHermesEnabledInThisVariant)
task.minifyEnabled.set(!isHermesEnabledInThisVariant)
task.devEnabled.set(false)
task.jsIntermediateSourceMapsDir.set(jsIntermediateSourceMapsDir)
task.jsSourceMapsDir.set(jsSourceMapsDir)
task.hermesCommand.set(config.hermesCommand)
task.hermesFlags.set(config.hermesFlags)
task.reactNativeDir.set(config.reactNativeDir)
}
variant.sources.res?.addGeneratedSourceDirectory(bundleTask, BundleHermesCTask::resourcesDir)
variant.sources.assets?.addGeneratedSourceDirectory(bundleTask, BundleHermesCTask::jsBundleDir)
@@ -2607,3 +2607,35 @@ describe('horizontal ScrollView in RTL script', () => {
]);
});
});
describe('Views with no layout', () => {
it('are not culled', () => {
const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100});
Fantom.runTask(() => {
root.render(
<ScrollView style={{height: 100, width: 100}}>
<View nativeID={'viewWithLayout'} style={{height: 100, width: 100}} />
<View style={{height: 1000, width: 100}} />
<View
nativeID={'culledViewWithLayout'}
style={{height: 100, width: 100}}
/>
<View nativeID={'viewWithoutLayout'} style={{height: 0, width: 0}} />
</ScrollView>,
);
});
expect(root.takeMountingManagerLogs()).toEqual([
'Update {type: "RootView", nativeID: (root)}',
'Create {type: "ScrollView", nativeID: (N/A)}',
'Create {type: "View", nativeID: (N/A)}',
'Create {type: "View", nativeID: "viewWithLayout"}',
'Create {type: "View", nativeID: "viewWithoutLayout"}',
'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "viewWithLayout"}',
'Insert {type: "View", parentNativeID: (N/A), index: 1, nativeID: "viewWithoutLayout"}',
'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}',
'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}',
]);
});
});
+3 -5
View File
@@ -4,19 +4,17 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict
* @flow strict-local
* @format
*/
import setUpPerformanceModern from '../../src/private/setup/setUpPerformanceModern';
import NativePerformance from '../../src/private/webapis/performance/specs/NativePerformance';
// In case if the native implementation of the Performance API is available, use it,
// otherwise fall back to the legacy/default one, which only defines 'Performance.now()'
if (NativePerformance) {
const Performance =
require('../../src/private/webapis/performance/Performance').default;
// $FlowExpectedError[cannot-write]
global.performance = new Performance();
setUpPerformanceModern();
} else {
if (!global.performance) {
// $FlowExpectedError[cannot-write]
+8 -8
View File
@@ -13,8 +13,8 @@ import type {ViewStyleProp} from '../StyleSheet/StyleSheet';
import type {
ListRenderItem,
ListRenderItemInfo,
ListViewToken,
ViewabilityConfigCallbackPair,
ViewToken,
VirtualizedListProps,
} from '@react-native/virtualized-lists';
@@ -573,7 +573,7 @@ class FlatList<ItemT = any> extends React.PureComponent<FlatListProps<ItemT>> {
return keyExtractor(items, index);
};
_pushMultiColumnViewable(arr: Array<ViewToken>, v: ViewToken): void {
_pushMultiColumnViewable(arr: Array<ListViewToken>, v: ListViewToken): void {
const numColumns = numColumnsOrDefault(this.props.numColumns);
const keyExtractor = this.props.keyExtractor ?? defaultKeyExtractor;
v.item.forEach((item, ii) => {
@@ -585,22 +585,22 @@ class FlatList<ItemT = any> extends React.PureComponent<FlatListProps<ItemT>> {
_createOnViewableItemsChanged(
onViewableItemsChanged: ?(info: {
viewableItems: Array<ViewToken>,
changed: Array<ViewToken>,
viewableItems: Array<ListViewToken>,
changed: Array<ListViewToken>,
...
}) => void,
// $FlowFixMe[missing-local-annot]
) {
return (info: {
viewableItems: Array<ViewToken>,
changed: Array<ViewToken>,
viewableItems: Array<ListViewToken>,
changed: Array<ListViewToken>,
...
}) => {
const numColumns = numColumnsOrDefault(this.props.numColumns);
if (onViewableItemsChanged) {
if (numColumns > 1) {
const changed: Array<ViewToken> = [];
const viewableItems: Array<ViewToken> = [];
const changed: Array<ListViewToken> = [];
const viewableItems: Array<ListViewToken> = [];
info.viewableItems.forEach(v =>
this._pushMultiColumnViewable(viewableItems, v),
);
+1 -1
View File
@@ -11,7 +11,7 @@
'use strict';
export type {
ViewToken,
ListViewToken as ViewToken,
ViewabilityConfig,
ViewabilityConfigCallbackPair,
} from '@react-native/virtualized-lists';
@@ -19,6 +19,7 @@ const VirtualizedListComponent: VirtualizedListType =
export type {
ListRenderItemInfo,
ListRenderItem,
ListViewToken,
Separators,
VirtualizedListProps,
} from '@react-native/virtualized-lists';
@@ -102,7 +102,6 @@ export function testBadSectionsShape(): React.MixedElement {
],
},
];
// $FlowExpectedError - section missing `data` field
return <SectionList renderItem={renderMyListItem} sections={sections} />;
}
@@ -649,8 +649,6 @@ class XMLHttpRequest extends EventTarget {
this._url,
this._headers,
data,
/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found
* when making Flow check .android.js files. */
nativeResponseType,
incrementalEvents,
this.timeout,
@@ -41,11 +41,7 @@ export function testBadCompose() {
(StyleSheet.compose(textStyle, textStyle): ImageStyleProp);
// $FlowExpectedError[incompatible-type] - Incompatible type.
(StyleSheet.compose(
// $FlowExpectedError - Incompatible type.
[textStyle],
null,
): ImageStyleProp);
(StyleSheet.compose([textStyle], null): ImageStyleProp);
// $FlowExpectedError[incompatible-type] - Incompatible type.
(StyleSheet.compose(
@@ -18,17 +18,17 @@ void RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode(
*minimumSize = CGSizeZero;
*maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);
if (sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthExact) {
if ((sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthExact) != 0) {
minimumSize->width = size.width;
maximumSize->width = size.width;
} else if (sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthAtMost) {
} else if ((sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthAtMost) != 0) {
maximumSize->width = size.width;
}
if (sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightExact) {
if ((sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightExact) != 0) {
minimumSize->height = size.height;
maximumSize->height = size.height;
} else if (sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightAtMost) {
} else if ((sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightAtMost) != 0) {
maximumSize->height = size.height;
}
}
@@ -31,7 +31,7 @@ using namespace facebook::react;
- (instancetype)init
{
self = [super init];
if (self) {
if (self != nullptr) {
_alertControllers = [NSMutableArray new];
}
return self;
@@ -53,7 +53,7 @@ RCT_EXPORT_MODULE()
alertController.modalPresentationStyle = UIModalPresentationPopover;
UIView *sourceView = parentViewController.view;
if (anchorViewTag) {
if (anchorViewTag != nullptr) {
sourceView = [self.viewRegistry_DEPRECATED viewForReactTag:anchorViewTag];
} else {
alertController.popoverPresentationController.permittedArrowDirections = 0;
@@ -166,12 +166,12 @@ RCT_EXPORT_METHOD(showActionSheetWithOptions
index++;
}
if (disabledButtonIndices) {
if (disabledButtonIndices != nullptr) {
for (NSNumber *disabledButtonIndex in disabledButtonIndices) {
if ([disabledButtonIndex integerValue] < buttons.count) {
UIAlertAction *action = alertController.actions[[disabledButtonIndex integerValue]];
[action setEnabled:false];
if (disabledButtonTintColor) {
if (disabledButtonTintColor != nullptr) {
[action setValue:disabledButtonTintColor forKey:@"titleTextColor"];
}
} else {
@@ -235,14 +235,14 @@ RCT_EXPORT_METHOD(showShareActionSheetWithOptions
UIColor *tintColor = [RCTConvert UIColor:options.tintColor() ? @(*options.tintColor()) : nil];
dispatch_async(dispatch_get_main_queue(), ^{
if (message) {
if (message != nullptr) {
[items addObject:message];
}
if (URL) {
if (URL != nullptr) {
if ([URL.scheme.lowercaseString isEqualToString:@"data"]) {
NSError *error;
NSData *data = [NSData dataWithContentsOfURL:URL options:(NSDataReadingOptions)0 error:&error];
if (!data) {
if (data == nullptr) {
failureCallback(@[ RCTJSErrorFromNSError(error) ]);
return;
}
@@ -258,17 +258,17 @@ RCT_EXPORT_METHOD(showShareActionSheetWithOptions
UIActivityViewController *shareController = [[UIActivityViewController alloc] initWithActivityItems:items
applicationActivities:nil];
if (subject) {
if (subject != nullptr) {
[shareController setValue:subject forKey:@"subject"];
}
if (excludedActivityTypes) {
if (excludedActivityTypes != nullptr) {
shareController.excludedActivityTypes = excludedActivityTypes;
}
UIViewController *controller = RCTPresentedViewController();
shareController.completionWithItemsHandler =
^(NSString *activityType, BOOL completed, __unused NSArray *returnedItems, NSError *activityError) {
if (activityError) {
if (activityError != nullptr) {
failureCallback(@[ RCTJSErrorFromNSError(activityError) ]);
} else if (completed || activityType == nil) {
successCallback(@[ @(completed), RCTNullIfNil(activityType) ]);
@@ -20,9 +20,14 @@
- (UIWindow *)alertWindow
{
if (_alertWindow == nil) {
_alertWindow = [[UIWindow alloc] initWithWindowScene:RCTKeyWindow().windowScene];
UIWindowScene *scene = RCTKeyWindow().windowScene;
if (scene != nil) {
_alertWindow = [[UIWindow alloc] initWithWindowScene:scene];
} else {
_alertWindow = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
}
if (_alertWindow) {
if (_alertWindow != nullptr) {
_alertWindow.rootViewController = [UIViewController new];
_alertWindow.windowLevel = UIWindowLevelAlert + 1;
}
@@ -36,7 +41,7 @@
UIUserInterfaceStyle style = self.overrideUserInterfaceStyle;
if (style == UIUserInterfaceStyleUnspecified) {
UIUserInterfaceStyle overriddenStyle = RCTKeyWindow().overrideUserInterfaceStyle;
style = overriddenStyle ? overriddenStyle : UIUserInterfaceStyleUnspecified;
style = (overriddenStyle != 0) ? overriddenStyle : UIUserInterfaceStyleUnspecified;
}
self.overrideUserInterfaceStyle = style;
@@ -86,7 +86,7 @@ RCT_EXPORT_METHOD(alertWithArgs : (JS::NativeAlertManager::Args &)args callback
UIKeyboardType keyboardType = [RCTConvert UIKeyboardType:args.keyboardType()];
UIUserInterfaceStyle userInterfaceStyle = [RCTConvert UIUserInterfaceStyle:args.userInterfaceStyle()];
if (!title && !message) {
if ((title == nullptr) && (message == nullptr)) {
RCTLogError(@"Must specify either an alert title, or message, or both");
return;
}
@@ -193,7 +193,7 @@ RCT_EXPORT_METHOD(alertWithArgs : (JS::NativeAlertManager::Args &)args callback
}
}
if (!self->_alertControllers) {
if (self->_alertControllers == nullptr) {
self->_alertControllers = [NSHashTable weakObjectsHashTable];
}
[self->_alertControllers addObject:alertController];
@@ -47,7 +47,7 @@ NSString *const RCTShowDevMenuNotification = @"RCTShowDevMenuNotification";
- (instancetype)initWithTitleBlock:(RCTDevMenuItemTitleBlock)titleBlock handler:(dispatch_block_t)handler
{
if ((self = [super init])) {
if ((self = [super init]) != nullptr) {
_titleBlock = [titleBlock copy];
_handler = [handler copy];
}
@@ -72,14 +72,14 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
- (void)callHandler
{
if (_handler) {
if (_handler != nullptr) {
_handler();
}
}
- (NSString *)title
{
if (_titleBlock) {
if (_titleBlock != nullptr) {
return _titleBlock();
}
return nil;
@@ -120,7 +120,7 @@ RCT_EXPORT_MODULE()
- (instancetype)init
{
if ((self = [super init])) {
if ((self = [super init]) != nullptr) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(showOnShake)
name:RCTShowDevMenuNotification
@@ -214,7 +214,7 @@ RCT_EXPORT_MODULE()
if (_actionSheet.isBeingPresented || _actionSheet.beingDismissed) {
return;
}
if (_actionSheet) {
if (_actionSheet != nullptr) {
[_actionSheet dismissViewControllerAnimated:YES
completion:^(void) {
self->_actionSheet = nil;
@@ -379,7 +379,7 @@ RCT_EXPORT_MODULE()
RCT_EXPORT_METHOD(show)
{
if (_actionSheet || RCTRunningInAppExtension()) {
if ((_actionSheet != nullptr) || RCTRunningInAppExtension()) {
return;
}
@@ -412,7 +412,7 @@ RCT_EXPORT_METHOD(show)
- (RCTDevMenuAlertActionHandler)alertActionHandlerForDevItem:(RCTDevMenuItem *__nullable)item
{
return ^(__unused UIAlertAction *action) {
if (item) {
if (item != nullptr) {
[item callHandler];
}
@@ -71,12 +71,14 @@ RCT_EXPORT_MODULE()
{
[_callableJSModules invokeModule:@"RCTNativeAppEventEmitter"
method:@"emit"
withArgs:body ? @[ name, body ] : @[ name ]];
withArgs:(body != nullptr) ? @[ name, body ] : @[ name ]];
}
- (void)sendDeviceEventWithName:(NSString *)name body:(id)body
{
[_callableJSModules invokeModule:@"RCTDeviceEventEmitter" method:@"emit" withArgs:body ? @[ name, body ] : @[ name ]];
[_callableJSModules invokeModule:@"RCTDeviceEventEmitter"
method:@"emit"
withArgs:(body != nullptr) ? @[ name, body ] : @[ name ]];
}
- (void)sendTextEventWithType:(RCTTextEventType)type
@@ -91,13 +93,13 @@ RCT_EXPORT_MODULE()
@"eventCount" : @(eventCount),
}];
if (text) {
if (text != nullptr) {
// We copy the string here because if it's a mutable string it may get released before we dispatch the event on a
// different thread, causing a crash.
body[@"text"] = [text copy];
}
if (key) {
if (key != nullptr) {
if (key.length == 0) {
key = @"Backspace"; // backspace
} else {
@@ -142,7 +144,7 @@ RCT_EXPORT_MODULE()
if (event.canCoalesce) {
eventID = RCTGetEventID(event.viewTag, event.eventName, event.coalescingKey);
id<RCTEvent> previousEvent = _events[eventID];
if (previousEvent) {
if (previousEvent != nullptr) {
event = [previousEvent coalesceWithEvent:event];
} else {
[_eventQueue addObject:eventID];
@@ -173,13 +175,13 @@ RCT_EXPORT_MODULE()
[_eventQueueLock unlock];
if (scheduleEventsDispatch) {
if (_bridge) {
if (_bridge != nullptr) {
[_bridge
dispatchBlock:^{
[self flushEventsQueue];
}
queue:RCTJSThread];
} else if (_dispatchToJSThread) {
} else if (_dispatchToJSThread != nullptr) {
_dispatchToJSThread(^{
[self flushEventsQueue];
});
@@ -236,7 +238,7 @@ RCT_EXPORT_MODULE()
{
NSDictionary *userInfo = notification.userInfo;
id<RCTEvent> event = [userInfo objectForKey:@"event"];
if (event) {
if (event != nullptr) {
[self notifyObserversOfEvent:event];
}
}
@@ -30,7 +30,7 @@ RCT_EXPORT_MODULE()
- (instancetype)initWithDelegate:(id<RCTExceptionsManagerDelegate>)delegate
{
if ((self = [self init])) {
if ((self = [self init]) != nullptr) {
_delegate = delegate;
}
return self;
@@ -46,7 +46,7 @@ RCT_EXPORT_MODULE()
[redbox showErrorMessage:message withStack:stack errorCookie:(int)exceptionId];
}
if (_delegate) {
if (_delegate != nullptr) {
[_delegate handleSoftJSExceptionWithMessage:message
stack:stack
exceptionId:[NSNumber numberWithDouble:exceptionId]
@@ -64,7 +64,7 @@ RCT_EXPORT_MODULE()
[redbox showErrorMessage:message withStack:stack errorCookie:(int)exceptionId];
}
if (_delegate) {
if (_delegate != nullptr) {
[_delegate handleFatalJSExceptionWithMessage:message
stack:stack
exceptionId:[NSNumber numberWithDouble:exceptionId]
@@ -107,13 +107,13 @@ RCT_EXPORT_METHOD(reportException : (JS::NativeExceptionsManager::ExceptionData
{
NSMutableDictionary<NSString *, id> *mutableErrorData = [NSMutableDictionary new];
mutableErrorData[@"message"] = data.message();
if (data.originalMessage()) {
if (data.originalMessage() != nullptr) {
mutableErrorData[@"originalMessage"] = data.originalMessage();
}
if (data.name()) {
if (data.name() != nullptr) {
mutableErrorData[@"name"] = data.name();
}
if (data.componentStack()) {
if (data.componentStack() != nullptr) {
mutableErrorData[@"componentStack"] = data.componentStack();
}
@@ -141,7 +141,7 @@ RCT_EXPORT_METHOD(reportException : (JS::NativeExceptionsManager::ExceptionData
mutableErrorData[@"id"] = @(data.id_());
mutableErrorData[@"isFatal"] = @(data.isFatal());
if (data.extraData()) {
if (data.extraData() != nullptr) {
mutableErrorData[@"extraData"] = data.extraData();
}
@@ -37,7 +37,7 @@
- (instancetype)initWithFrame:(CGRect)frame color:(UIColor *)color
{
if ((self = [super initWithFrame:frame])) {
if ((self = [super initWithFrame:frame]) != nullptr) {
_frameCount = -1;
_prevTime = -1;
_maxFPS = 0;
@@ -64,7 +64,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
- (CAShapeLayer *)graph
{
if (!_graph) {
if (_graph == nullptr) {
_graph = [CAShapeLayer new];
_graph.frame = self.bounds;
_graph.backgroundColor = [_color colorWithAlphaComponent:0.2].CGColor;
@@ -76,7 +76,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
- (UILabel *)label
{
if (!_label) {
if (_label == nullptr) {
_label = [[UILabel alloc] initWithFrame:self.bounds];
_label.font = [UIFont boldSystemFontOfSize:13];
_label.textAlignment = NSTextAlignmentCenter;
@@ -45,23 +45,23 @@ RCT_EXPORT_METHOD(show)
__weak RCTLogBox *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong RCTLogBox *strongSelf = weakSelf;
if (!strongSelf) {
if (strongSelf == nullptr) {
return;
}
if (strongSelf->_view) {
if (strongSelf->_view != nullptr) {
[strongSelf->_view show];
return;
}
if (strongSelf->_bridgelessSurfacePresenter) {
if (strongSelf->_bridgelessSurfacePresenter != nullptr) {
strongSelf->_view = [[RCTLogBoxView alloc] initWithWindow:RCTKeyWindow()
surfacePresenter:strongSelf->_bridgelessSurfacePresenter];
[strongSelf->_view show];
}
#ifndef RCT_FIT_RM_OLD_RUNTIME
else if (strongSelf->_bridge && strongSelf->_bridge.valid) {
if (strongSelf->_bridge.surfacePresenter) {
else if ((strongSelf->_bridge != nullptr) && strongSelf->_bridge.valid) {
if (strongSelf->_bridge.surfacePresenter != nullptr) {
strongSelf->_view = [[RCTLogBoxView alloc] initWithWindow:RCTKeyWindow()
surfacePresenter:strongSelf->_bridge.surfacePresenter];
} else {
@@ -80,7 +80,7 @@ RCT_EXPORT_METHOD(hide)
__weak RCTLogBox *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong RCTLogBox *strongSelf = weakSelf;
if (!strongSelf) {
if (strongSelf == nullptr) {
return;
}
[strongSelf->_view setHidden:YES];
@@ -19,7 +19,7 @@
- (instancetype)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
if ((self = [super initWithFrame:frame]) != nullptr) {
self.windowLevel = UIWindowLevelStatusBar - 1;
self.backgroundColor = [UIColor clearColor];
}
@@ -134,7 +134,7 @@ RCT_EXPORT_MODULE()
#if __has_include(<React/RCTDevMenu.h>)
- (RCTDevMenuItem *)devMenuItem
{
if (!_devMenuItem) {
if (_devMenuItem == nullptr) {
__weak __typeof__(self) weakSelf = self;
__weak RCTDevSettings *devSettings = [self->_moduleRegistry moduleForName:"DevSettings"];
if (devSettings.isPerfMonitorShown) {
@@ -161,7 +161,7 @@ RCT_EXPORT_MODULE()
- (UIPanGestureRecognizer *)gestureRecognizer
{
if (!_gestureRecognizer) {
if (_gestureRecognizer == nullptr) {
_gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(gesture:)];
}
@@ -170,7 +170,7 @@ RCT_EXPORT_MODULE()
- (UIView *)container
{
if (!_container) {
if (_container == nullptr) {
UIEdgeInsets safeInsets = RCTKeyWindow().safeAreaInsets;
_container =
@@ -188,7 +188,7 @@ RCT_EXPORT_MODULE()
- (UILabel *)memory
{
if (!_memory) {
if (_memory == nullptr) {
_memory = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 44, RCTPerfMonitorBarHeight)];
_memory.font = [UIFont systemFontOfSize:12];
_memory.numberOfLines = 3;
@@ -200,7 +200,7 @@ RCT_EXPORT_MODULE()
- (UILabel *)heap
{
if (!_heap) {
if (_heap == nullptr) {
_heap = [[UILabel alloc] initWithFrame:CGRectMake(44, 0, 44, RCTPerfMonitorBarHeight)];
_heap.font = [UIFont systemFontOfSize:12];
_heap.numberOfLines = 3;
@@ -212,7 +212,7 @@ RCT_EXPORT_MODULE()
- (UILabel *)views
{
if (!_views) {
if (_views == nullptr) {
_views = [[UILabel alloc] initWithFrame:CGRectMake(88, 0, 44, RCTPerfMonitorBarHeight)];
_views.font = [UIFont systemFontOfSize:12];
_views.numberOfLines = 3;
@@ -224,7 +224,7 @@ RCT_EXPORT_MODULE()
- (RCTFPSGraph *)uiGraph
{
if (!_uiGraph) {
if (_uiGraph == nullptr) {
_uiGraph = [[RCTFPSGraph alloc] initWithFrame:CGRectMake(134, 14, 40, 30) color:[UIColor lightGrayColor]];
}
return _uiGraph;
@@ -232,7 +232,7 @@ RCT_EXPORT_MODULE()
- (RCTFPSGraph *)jsGraph
{
if (!_jsGraph) {
if (_jsGraph == nullptr) {
_jsGraph = [[RCTFPSGraph alloc] initWithFrame:CGRectMake(178, 14, 40, 30) color:[UIColor lightGrayColor]];
}
return _jsGraph;
@@ -240,7 +240,7 @@ RCT_EXPORT_MODULE()
- (UILabel *)uiGraphLabel
{
if (!_uiGraphLabel) {
if (_uiGraphLabel == nullptr) {
_uiGraphLabel = [[UILabel alloc] initWithFrame:CGRectMake(134, 3, 40, 10)];
_uiGraphLabel.font = [UIFont systemFontOfSize:11];
_uiGraphLabel.textAlignment = NSTextAlignmentCenter;
@@ -252,7 +252,7 @@ RCT_EXPORT_MODULE()
- (UILabel *)jsGraphLabel
{
if (!_jsGraphLabel) {
if (_jsGraphLabel == nullptr) {
_jsGraphLabel = [[UILabel alloc] initWithFrame:CGRectMake(178, 3, 38, 10)];
_jsGraphLabel.font = [UIFont systemFontOfSize:11];
_jsGraphLabel.textAlignment = NSTextAlignmentCenter;
@@ -264,7 +264,7 @@ RCT_EXPORT_MODULE()
- (UITableView *)metrics
{
if (!_metrics) {
if (_metrics == nullptr) {
_metrics = [[UITableView alloc] initWithFrame:CGRectMake(
0,
RCTPerfMonitorBarHeight,
@@ -281,7 +281,7 @@ RCT_EXPORT_MODULE()
- (void)show
{
if (_container) {
if (_container != nullptr) {
return;
}
@@ -317,7 +317,7 @@ RCT_EXPORT_MODULE()
- (void)hide
{
if (!_container) {
if (_container == nullptr) {
return;
}
@@ -360,7 +360,7 @@ RCT_EXPORT_MODULE()
dispatch_io_set_low_water(_io, 20);
dispatch_io_read(_io, 0, SIZE_MAX, _queue, ^(__unused bool done, dispatch_data_t data, __unused int error) {
if (!data) {
if (data == nullptr) {
return;
}
@@ -391,7 +391,7 @@ RCT_EXPORT_MODULE()
GCRegex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil];
});
if (_remaining) {
if (_remaining != nullptr) {
log = [_remaining stringByAppendingString:log];
_remaining = nil;
}
@@ -404,7 +404,7 @@ RCT_EXPORT_MODULE()
for (NSString *line in lines) {
NSTextCheckingResult *match = [GCRegex firstMatchInString:line options:0 range:NSMakeRange(0, line.length)];
if (match) {
if (match != nullptr) {
NSString *heapSizeStr = [line substringWithRange:[match rangeAtIndex:2]];
_heapSize = [heapSizeStr integerValue];
}
@@ -417,7 +417,7 @@ RCT_EXPORT_MODULE()
NSUInteger viewCount = views.count;
NSUInteger visibleViewCount = 0;
for (UIView *view in views.allValues) {
if (view.window || view.superview.window) {
if ((view.window != nullptr) || (view.superview.window != nullptr)) {
visibleViewCount++;
}
}
@@ -436,7 +436,7 @@ RCT_EXPORT_MODULE()
__weak __typeof__(self) weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
__strong __typeof__(weakSelf) strongSelf = weakSelf;
if (strongSelf && strongSelf->_container.superview) {
if ((strongSelf != nullptr) && (strongSelf->_container.superview != nullptr)) {
[strongSelf updateStats];
}
});
@@ -512,7 +512,7 @@ RCT_EXPORT_MODULE()
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:RCTPerfMonitorCellIdentifier
forIndexPath:indexPath];
if (!cell) {
if (cell == nullptr) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:RCTPerfMonitorCellIdentifier];
}
@@ -65,6 +65,7 @@ import com.facebook.react.fabric.mounting.mountitems.BatchMountItem;
import com.facebook.react.fabric.mounting.mountitems.DispatchCommandMountItem;
import com.facebook.react.fabric.mounting.mountitems.MountItem;
import com.facebook.react.fabric.mounting.mountitems.MountItemFactory;
import com.facebook.react.fabric.mounting.mountitems.PrefetchResourcesMountItem;
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
import com.facebook.react.internal.featureflags.ReactNativeNewArchitectureFeatureFlags;
import com.facebook.react.internal.interop.InteropEventEmitter;
@@ -984,9 +985,17 @@ public class FabricUIManager
* by an ImageView.
*/
@UnstableReactNativeAPI
public void experimental_prefetchResources(String componentName, ReadableMapBuffer params) {
mMountingManager.experimental_prefetchResources(
mReactApplicationContext, componentName, params);
public void experimental_prefetchResources(
int surfaceId, String componentName, ReadableMapBuffer params) {
if (ReactNativeFeatureFlags.enableImagePrefetchingOnUiThreadAndroid()) {
mMountItemDispatcher.addMountItem(
new PrefetchResourcesMountItem(surfaceId, componentName, params));
} else {
SurfaceMountingManager surfaceMountingManager = mMountingManager.getSurfaceManager(surfaceId);
if (surfaceMountingManager != null) {
surfaceMountingManager.experimental_prefetchResources(surfaceId, componentName, params);
}
}
}
void setBinding(FabricUIManagerBinding binding) {
@@ -19,8 +19,6 @@ import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.RetryableMountingLayerException
import com.facebook.react.bridge.UiThreadUtil.assertOnUiThread
import com.facebook.react.bridge.WritableMap
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.common.mapbuffer.MapBuffer
import com.facebook.react.fabric.events.EventEmitterWrapper
import com.facebook.react.fabric.mounting.mountitems.MountItem
import com.facebook.react.touch.JSResponderHandler
@@ -325,27 +323,6 @@ internal class MountingManager(
attachmentsPositions,
)
/**
* This prefetch method is experimental, do not use it for production code. it will most likely
* change or be removed in the future.
*
* @param reactContext
* @param componentName
* @param params prefetch request params defined in C++
*/
@Suppress("FunctionName")
@AnyThread
@UnstableReactNativeAPI
fun experimental_prefetchResources(
reactContext: ReactContext?,
componentName: String?,
params: MapBuffer?,
) {
viewManagerRegistry
.get(checkNotNull(componentName))
.experimental_prefetchResources(reactContext, params)
}
fun enqueuePendingEvent(
surfaceId: Int,
reactTag: Int,
@@ -10,6 +10,7 @@ package com.facebook.react.fabric.mounting;
import static com.facebook.infer.annotation.ThreadConfined.ANY;
import static com.facebook.infer.annotation.ThreadConfined.UI;
import android.annotation.SuppressLint;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
@@ -30,7 +31,9 @@ import com.facebook.react.bridge.RetryableMountingLayerException;
import com.facebook.react.bridge.SoftAssertions;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.annotations.UnstableReactNativeAPI;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.common.mapbuffer.MapBuffer;
import com.facebook.react.fabric.events.EventEmitterWrapper;
import com.facebook.react.fabric.mounting.MountingManager.MountItemExecutor;
import com.facebook.react.fabric.mounting.mountitems.MountItem;
@@ -696,6 +699,25 @@ public class SurfaceMountingManager {
.updateProperties(view, viewState.mCurrentProps);
}
/**
* This prefetch method is experimental, do not use it for production code. it will most likely
* change or be removed in the future.
*
* @param surfaceId surface ID
* @param componentName
* @param params prefetch request params defined in C++
*/
@SuppressLint("FunctionName")
@AnyThread
@UnstableReactNativeAPI
public void experimental_prefetchResources(
int surfaceId, String componentName, MapBuffer params) {
mViewManagerRegistry
.get(componentName)
.experimental_prefetchResources(
surfaceId, Assertions.assertNotNull(mThemedReactContext), params);
}
@Deprecated
public void receiveCommand(int reactTag, int commandId, ReadableArray commandArgs) {
if (isStopped()) {
@@ -0,0 +1,35 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.fabric.mounting.mountitems
import com.facebook.react.common.annotations.FrameworkAPI
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.common.mapbuffer.ReadableMapBuffer
import com.facebook.react.fabric.mounting.MountingManager
internal class PrefetchResourcesMountItem(
private val surfaceId: Int,
private val componentName: String,
private val params: ReadableMapBuffer,
) : MountItem {
@OptIn(UnstableReactNativeAPI::class, FrameworkAPI::class)
override fun execute(mountingManager: MountingManager) {
mountingManager
.getSurfaceManager(surfaceId)
?.experimental_prefetchResources(
surfaceId,
componentName,
params,
)
}
override fun getSurfaceId(): Int = surfaceId
override fun toString(): String = "PrefetchResourcesMountItem"
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<34c12f5a31aab5bfb874953f1beefef1>>
* @generated SignedSource<<a59b42b84160c18d214f8b2be76bc743>>
*/
/**
@@ -174,6 +174,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableImagePrefetchingAndroid(): Boolean = accessor.enableImagePrefetchingAndroid()
/**
* When enabled, Android will initiate image prefetch requested on ImageShadowNode::layout on the UI thread
*/
@JvmStatic
public fun enableImagePrefetchingOnUiThreadAndroid(): Boolean = accessor.enableImagePrefetchingOnUiThreadAndroid()
/**
* Dispatches state updates for content offset changes synchronously on the main thread.
*/
@@ -222,12 +228,6 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableNetworkEventReporting(): Boolean = accessor.enableNetworkEventReporting()
/**
* Use BackgroundDrawable and BorderDrawable instead of CSSBackgroundDrawable
*/
@JvmStatic
public fun enableNewBackgroundAndBorderDrawables(): Boolean = accessor.enableNewBackgroundAndBorderDrawables()
/**
* Enables caching text layout artifacts for later reuse
*/
@@ -336,12 +336,6 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun preventShadowTreeCommitExhaustion(): Boolean = accessor.preventShadowTreeCommitExhaustion()
/**
* Releases the cached image data when it is consumed by the observers.
*/
@JvmStatic
public fun releaseImageDataWhenConsumed(): Boolean = accessor.releaseImageDataWhenConsumed()
/**
* Function used to enable / disable Pressibility from using W3C Pointer Events for its hover callbacks
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<392da016e0bf4193b72c44a508811e10>>
* @generated SignedSource<<37203dffb9421d1036aaeaeaa7319e28>>
*/
/**
@@ -44,6 +44,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var enableIOSTextBaselineOffsetPerLineCache: Boolean? = null
private var enableIOSViewClipToPaddingBoxCache: Boolean? = null
private var enableImagePrefetchingAndroidCache: Boolean? = null
private var enableImagePrefetchingOnUiThreadAndroidCache: Boolean? = null
private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null
private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null
private var enableLayoutAnimationsOnAndroidCache: Boolean? = null
@@ -52,7 +53,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var enableModuleArgumentNSNullConversionIOSCache: Boolean? = null
private var enableNativeCSSParsingCache: Boolean? = null
private var enableNetworkEventReportingCache: Boolean? = null
private var enableNewBackgroundAndBorderDrawablesCache: Boolean? = null
private var enablePreparedTextLayoutCache: Boolean? = null
private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null
private var enableResourceTimingAPICache: Boolean? = null
@@ -71,7 +71,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var perfMonitorV2EnabledCache: Boolean? = null
private var preparedTextCacheSizeCache: Double? = null
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
private var releaseImageDataWhenConsumedCache: Boolean? = null
private var shouldPressibilityUseW3CPointerEventsForHoverCache: Boolean? = null
private var skipActivityIdentityAssertionOnHostPauseCache: Boolean? = null
private var sweepActiveTouchOnChildNativeGesturesAndroidCache: Boolean? = null
@@ -306,6 +305,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun enableImagePrefetchingOnUiThreadAndroid(): Boolean {
var cached = enableImagePrefetchingOnUiThreadAndroidCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableImagePrefetchingOnUiThreadAndroid()
enableImagePrefetchingOnUiThreadAndroidCache = cached
}
return cached
}
override fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean {
var cached = enableImmediateUpdateModeForContentOffsetChangesCache
if (cached == null) {
@@ -378,15 +386,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun enableNewBackgroundAndBorderDrawables(): Boolean {
var cached = enableNewBackgroundAndBorderDrawablesCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableNewBackgroundAndBorderDrawables()
enableNewBackgroundAndBorderDrawablesCache = cached
}
return cached
}
override fun enablePreparedTextLayout(): Boolean {
var cached = enablePreparedTextLayoutCache
if (cached == null) {
@@ -549,15 +548,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun releaseImageDataWhenConsumed(): Boolean {
var cached = releaseImageDataWhenConsumedCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.releaseImageDataWhenConsumed()
releaseImageDataWhenConsumedCache = cached
}
return cached
}
override fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean {
var cached = shouldPressibilityUseW3CPointerEventsForHoverCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<a0453230524ebca2bfb8fad656a6f54a>>
* @generated SignedSource<<9c0acc876e3205fe2ea181e71eb512c9>>
*/
/**
@@ -76,6 +76,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun enableImagePrefetchingAndroid(): Boolean
@DoNotStrip @JvmStatic public external fun enableImagePrefetchingOnUiThreadAndroid(): Boolean
@DoNotStrip @JvmStatic public external fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean
@DoNotStrip @JvmStatic public external fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean
@@ -92,8 +94,6 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun enableNetworkEventReporting(): Boolean
@DoNotStrip @JvmStatic public external fun enableNewBackgroundAndBorderDrawables(): Boolean
@DoNotStrip @JvmStatic public external fun enablePreparedTextLayout(): Boolean
@DoNotStrip @JvmStatic public external fun enablePropsUpdateReconciliationAndroid(): Boolean
@@ -130,8 +130,6 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun preventShadowTreeCommitExhaustion(): Boolean
@DoNotStrip @JvmStatic public external fun releaseImageDataWhenConsumed(): Boolean
@DoNotStrip @JvmStatic public external fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean
@DoNotStrip @JvmStatic public external fun skipActivityIdentityAssertionOnHostPause(): Boolean
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<719706a983a073b6c286c49d993f7f80>>
* @generated SignedSource<<05bfed9fc7131062c8b16246986fc999>>
*/
/**
@@ -71,6 +71,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun enableImagePrefetchingAndroid(): Boolean = false
override fun enableImagePrefetchingOnUiThreadAndroid(): Boolean = false
override fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean = false
override fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean = false
@@ -87,8 +89,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun enableNetworkEventReporting(): Boolean = false
override fun enableNewBackgroundAndBorderDrawables(): Boolean = true
override fun enablePreparedTextLayout(): Boolean = false
override fun enablePropsUpdateReconciliationAndroid(): Boolean = false
@@ -125,8 +125,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun preventShadowTreeCommitExhaustion(): Boolean = false
override fun releaseImageDataWhenConsumed(): Boolean = false
override fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean = false
override fun skipActivityIdentityAssertionOnHostPause(): Boolean = false
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<594815ba6a984c460ab8bddd91c5cae2>>
* @generated SignedSource<<9a18369464f81c3d03f2702716dfdb29>>
*/
/**
@@ -48,6 +48,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var enableIOSTextBaselineOffsetPerLineCache: Boolean? = null
private var enableIOSViewClipToPaddingBoxCache: Boolean? = null
private var enableImagePrefetchingAndroidCache: Boolean? = null
private var enableImagePrefetchingOnUiThreadAndroidCache: Boolean? = null
private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null
private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null
private var enableLayoutAnimationsOnAndroidCache: Boolean? = null
@@ -56,7 +57,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var enableModuleArgumentNSNullConversionIOSCache: Boolean? = null
private var enableNativeCSSParsingCache: Boolean? = null
private var enableNetworkEventReportingCache: Boolean? = null
private var enableNewBackgroundAndBorderDrawablesCache: Boolean? = null
private var enablePreparedTextLayoutCache: Boolean? = null
private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null
private var enableResourceTimingAPICache: Boolean? = null
@@ -75,7 +75,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var perfMonitorV2EnabledCache: Boolean? = null
private var preparedTextCacheSizeCache: Double? = null
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
private var releaseImageDataWhenConsumedCache: Boolean? = null
private var shouldPressibilityUseW3CPointerEventsForHoverCache: Boolean? = null
private var skipActivityIdentityAssertionOnHostPauseCache: Boolean? = null
private var sweepActiveTouchOnChildNativeGesturesAndroidCache: Boolean? = null
@@ -334,6 +333,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}
override fun enableImagePrefetchingOnUiThreadAndroid(): Boolean {
var cached = enableImagePrefetchingOnUiThreadAndroidCache
if (cached == null) {
cached = currentProvider.enableImagePrefetchingOnUiThreadAndroid()
accessedFeatureFlags.add("enableImagePrefetchingOnUiThreadAndroid")
enableImagePrefetchingOnUiThreadAndroidCache = cached
}
return cached
}
override fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean {
var cached = enableImmediateUpdateModeForContentOffsetChangesCache
if (cached == null) {
@@ -414,16 +423,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}
override fun enableNewBackgroundAndBorderDrawables(): Boolean {
var cached = enableNewBackgroundAndBorderDrawablesCache
if (cached == null) {
cached = currentProvider.enableNewBackgroundAndBorderDrawables()
accessedFeatureFlags.add("enableNewBackgroundAndBorderDrawables")
enableNewBackgroundAndBorderDrawablesCache = cached
}
return cached
}
override fun enablePreparedTextLayout(): Boolean {
var cached = enablePreparedTextLayoutCache
if (cached == null) {
@@ -604,16 +603,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}
override fun releaseImageDataWhenConsumed(): Boolean {
var cached = releaseImageDataWhenConsumedCache
if (cached == null) {
cached = currentProvider.releaseImageDataWhenConsumed()
accessedFeatureFlags.add("releaseImageDataWhenConsumed")
releaseImageDataWhenConsumedCache = cached
}
return cached
}
override fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean {
var cached = shouldPressibilityUseW3CPointerEventsForHoverCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<dfbd5e84392f1fda0e68324582c328b2>>
* @generated SignedSource<<845b2ee5edc9aedbdbd052d9a930f666>>
*/
/**
@@ -71,6 +71,8 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun enableImagePrefetchingAndroid(): Boolean
@DoNotStrip public fun enableImagePrefetchingOnUiThreadAndroid(): Boolean
@DoNotStrip public fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean
@DoNotStrip public fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean
@@ -87,8 +89,6 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun enableNetworkEventReporting(): Boolean
@DoNotStrip public fun enableNewBackgroundAndBorderDrawables(): Boolean
@DoNotStrip public fun enablePreparedTextLayout(): Boolean
@DoNotStrip public fun enablePropsUpdateReconciliationAndroid(): Boolean
@@ -125,8 +125,6 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun preventShadowTreeCommitExhaustion(): Boolean
@DoNotStrip public fun releaseImageDataWhenConsumed(): Boolean
@DoNotStrip public fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean
@DoNotStrip public fun skipActivityIdentityAssertionOnHostPause(): Boolean
@@ -230,8 +230,8 @@ internal class ImageLoaderModule : NativeImageLoaderAndroidSpec, LifecycleEventL
override fun doInBackgroundGuarded(vararg params: Void) {
val result = buildReadableMap {
val imagePipeline: ImagePipeline = this@ImageLoaderModule.imagePipeline
repeat(uris.size()) {
val uriString = uris.getString(it)
repeat(uris.size()) { index ->
val uriString = uris.getString(index)
if (!uriString.isNullOrEmpty()) {
val uri = Uri.parse(uriString)
if (imagePipeline.isInBitmapMemoryCache(uri)) {
@@ -19,14 +19,12 @@ import android.widget.ImageView
import androidx.annotation.ColorInt
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.uimanager.PixelUtil.dpToPx
import com.facebook.react.uimanager.PixelUtil.pxToDp
import com.facebook.react.uimanager.common.UIManagerType
import com.facebook.react.uimanager.common.ViewUtil
import com.facebook.react.uimanager.drawable.BackgroundDrawable
import com.facebook.react.uimanager.drawable.BorderDrawable
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable
import com.facebook.react.uimanager.drawable.CompositeBackgroundDrawable
import com.facebook.react.uimanager.drawable.InsetBoxShadowDrawable
import com.facebook.react.uimanager.drawable.MIN_INSET_BOX_SHADOW_SDK_VERSION
@@ -59,11 +57,7 @@ public object BackgroundStyleApplicator {
return
}
if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
ensureBackgroundDrawable(view).backgroundColor = color ?: Color.TRANSPARENT
} else {
ensureCSSBackground(view).color = color ?: Color.TRANSPARENT
}
ensureBackgroundDrawable(view).backgroundColor = color ?: Color.TRANSPARENT
}
@JvmStatic
@@ -71,21 +65,13 @@ public object BackgroundStyleApplicator {
view: View,
backgroundImageLayers: List<BackgroundImageLayer>?,
): Unit {
if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
ensureBackgroundDrawable(view).backgroundImageLayers = backgroundImageLayers
} else {
ensureCSSBackground(view).setBackgroundImage(backgroundImageLayers)
}
ensureBackgroundDrawable(view).backgroundImageLayers = backgroundImageLayers
}
@JvmStatic
@ColorInt
public fun getBackgroundColor(view: View): Int? {
return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
getBackground(view)?.backgroundColor
} else {
getCSSBackground(view)?.color
}
return getBackground(view)?.backgroundColor
}
@JvmStatic
@@ -94,16 +80,12 @@ public object BackgroundStyleApplicator {
composite.borderInsets = composite.borderInsets ?: BorderInsets()
composite.borderInsets?.setBorderWidth(edge, width)
if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
ensureBorderDrawable(view).setBorderWidth(edge.toSpacingType(), width?.dpToPx() ?: Float.NaN)
composite.background?.borderInsets = composite.borderInsets
composite.border?.borderInsets = composite.borderInsets
ensureBorderDrawable(view).setBorderWidth(edge.toSpacingType(), width?.dpToPx() ?: Float.NaN)
composite.background?.borderInsets = composite.borderInsets
composite.border?.borderInsets = composite.borderInsets
composite.background?.invalidateSelf()
composite.border?.invalidateSelf()
} else {
ensureCSSBackground(view).setBorderWidth(edge.toSpacingType(), width?.dpToPx() ?: Float.NaN)
}
composite.background?.invalidateSelf()
composite.border?.invalidateSelf()
composite.borderInsets = composite.borderInsets ?: BorderInsets()
composite.borderInsets?.setBorderWidth(edge, width)
@@ -117,32 +99,23 @@ public object BackgroundStyleApplicator {
@JvmStatic
public fun getBorderWidth(view: View, edge: LogicalEdge): Float? {
return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
val width = getBorder(view)?.borderWidth?.getRaw(edge.toSpacingType())
if (width == null || width.isNaN()) null else width.pxToDp()
val width = getBorder(view)?.borderWidth?.getRaw(edge.toSpacingType())
if (width == null || width.isNaN()) {
return null
} else {
val width = getCSSBackground(view)?.getBorderWidth(edge.toSpacingType())
if (width == null || width.isNaN()) null else width.pxToDp()
return width.pxToDp()
}
}
@JvmStatic
public fun setBorderColor(view: View, edge: LogicalEdge, @ColorInt color: Int?): Unit {
if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
ensureBorderDrawable(view).setBorderColor(edge, color)
} else {
ensureCSSBackground(view).setBorderColor(edge.toSpacingType(), color)
}
ensureBorderDrawable(view).setBorderColor(edge, color)
}
@JvmStatic
@ColorInt
public fun getBorderColor(view: View, edge: LogicalEdge): Int? {
return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
getBorder(view)?.getBorderColor(edge)
} else {
getCSSBackground(view)?.getBorderColor(edge.toSpacingType())
}
return getBorder(view)?.getBorderColor(edge)
}
@JvmStatic
@@ -156,19 +129,14 @@ public object BackgroundStyleApplicator {
compositeBackgroundDrawable.borderRadius ?: BorderRadiusStyle()
compositeBackgroundDrawable.borderRadius?.set(corner, radius)
if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
if (view is ImageView) {
ensureBackgroundDrawable(view)
}
compositeBackgroundDrawable.background?.borderRadius =
compositeBackgroundDrawable.borderRadius
compositeBackgroundDrawable.border?.borderRadius = compositeBackgroundDrawable.borderRadius
compositeBackgroundDrawable.background?.invalidateSelf()
compositeBackgroundDrawable.border?.invalidateSelf()
} else {
ensureCSSBackground(view).setBorderRadius(corner, radius)
if (view is ImageView) {
ensureBackgroundDrawable(view)
}
compositeBackgroundDrawable.background?.borderRadius = compositeBackgroundDrawable.borderRadius
compositeBackgroundDrawable.border?.borderRadius = compositeBackgroundDrawable.borderRadius
compositeBackgroundDrawable.background?.invalidateSelf()
compositeBackgroundDrawable.border?.invalidateSelf()
if (Build.VERSION.SDK_INT >= MIN_OUTSET_BOX_SHADOW_SDK_VERSION) {
for (shadow in
@@ -191,29 +159,17 @@ public object BackgroundStyleApplicator {
@JvmStatic
public fun getBorderRadius(view: View, corner: BorderRadiusProp): LengthPercentage? {
return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
getCompositeBackgroundDrawable(view)?.borderRadius?.get(corner)
} else {
getCSSBackground(view)?.borderRadius?.get(corner)
}
return getCompositeBackgroundDrawable(view)?.borderRadius?.get(corner)
}
@JvmStatic
public fun setBorderStyle(view: View, borderStyle: BorderStyle?) {
if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
ensureBorderDrawable(view).borderStyle = borderStyle
} else {
ensureCSSBackground(view).borderStyle = borderStyle
}
ensureBorderDrawable(view).borderStyle = borderStyle
}
@JvmStatic
public fun getBorderStyle(view: View): BorderStyle? {
return if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
getBorder(view)?.borderStyle
} else {
getCSSBackground(view)?.borderStyle
}
return getBorder(view)?.borderStyle
}
@JvmStatic
@@ -342,71 +298,44 @@ public object BackgroundStyleApplicator {
@JvmStatic
public fun setFeedbackUnderlay(view: View, drawable: Drawable?) {
if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
ensureCompositeBackgroundDrawable(view).withNewFeedbackUnderlay(drawable)
} else {
view.background = ensureCompositeBackgroundDrawable(view).withNewFeedbackUnderlay(drawable)
}
ensureCompositeBackgroundDrawable(view).withNewFeedbackUnderlay(drawable)
}
@JvmStatic
public fun clipToPaddingBox(view: View, canvas: Canvas) {
if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
val drawingRect = Rect()
view.getDrawingRect(drawingRect)
val drawingRect = Rect()
view.getDrawingRect(drawingRect)
val composite = getCompositeBackgroundDrawable(view)
if (composite == null) {
canvas.clipRect(drawingRect)
return
}
val composite = getCompositeBackgroundDrawable(view)
if (composite == null) {
canvas.clipRect(drawingRect)
return
}
val paddingBoxRect = RectF()
val paddingBoxRect = RectF()
val computedBorderInsets =
composite.borderInsets?.resolve(composite.layoutDirection, view.context)
val computedBorderInsets =
composite.borderInsets?.resolve(composite.layoutDirection, view.context)
paddingBoxRect.left = composite.bounds.left + (computedBorderInsets?.left?.dpToPx() ?: 0f)
paddingBoxRect.top = composite.bounds.top + (computedBorderInsets?.top?.dpToPx() ?: 0f)
paddingBoxRect.right = composite.bounds.right - (computedBorderInsets?.right?.dpToPx() ?: 0f)
paddingBoxRect.bottom =
composite.bounds.bottom - (computedBorderInsets?.bottom?.dpToPx() ?: 0f)
paddingBoxRect.left = composite.bounds.left + (computedBorderInsets?.left?.dpToPx() ?: 0f)
paddingBoxRect.top = composite.bounds.top + (computedBorderInsets?.top?.dpToPx() ?: 0f)
paddingBoxRect.right = composite.bounds.right - (computedBorderInsets?.right?.dpToPx() ?: 0f)
paddingBoxRect.bottom = composite.bounds.bottom - (computedBorderInsets?.bottom?.dpToPx() ?: 0f)
if (composite.borderRadius?.hasRoundedBorders() == true) {
val paddingBoxPath =
createPaddingBoxPath(
view,
composite,
paddingBoxRect,
computedBorderInsets,
)
if (composite.borderRadius?.hasRoundedBorders() == true) {
val paddingBoxPath =
createPaddingBoxPath(
view,
composite,
paddingBoxRect,
computedBorderInsets,
)
paddingBoxPath.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat())
canvas.clipPath(paddingBoxPath)
} else {
paddingBoxRect.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat())
canvas.clipRect(paddingBoxRect)
}
paddingBoxPath.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat())
canvas.clipPath(paddingBoxPath)
} else {
val drawingRect = Rect()
view.getDrawingRect(drawingRect)
val cssBackground = getCSSBackground(view)
if (cssBackground == null) {
canvas.clipRect(drawingRect)
return
}
val paddingBoxPath = cssBackground.paddingBoxPath
if (paddingBoxPath != null) {
paddingBoxPath.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat())
canvas.clipPath(paddingBoxPath)
} else {
val paddingBoxRect = cssBackground.paddingBoxRect
paddingBoxRect.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat())
canvas.clipRect(paddingBoxRect)
}
paddingBoxRect.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat())
canvas.clipRect(paddingBoxRect)
}
}
@@ -431,19 +360,6 @@ public object BackgroundStyleApplicator {
private fun getCompositeBackgroundDrawable(view: View): CompositeBackgroundDrawable? =
view.background as? CompositeBackgroundDrawable
private fun ensureCSSBackground(view: View): CSSBackgroundDrawable {
val compositeBackgroundDrawable = ensureCompositeBackgroundDrawable(view)
var cssBackground = compositeBackgroundDrawable.cssBackground
return if (cssBackground != null) {
return cssBackground
} else {
cssBackground = CSSBackgroundDrawable(view.context)
view.background = compositeBackgroundDrawable.withNewCssBackground(cssBackground)
cssBackground
}
}
private fun ensureBackgroundDrawable(view: View): BackgroundDrawable {
val compositeBackgroundDrawable = ensureCompositeBackgroundDrawable(view)
var background = compositeBackgroundDrawable.background
@@ -462,9 +378,6 @@ public object BackgroundStyleApplicator {
}
}
private fun getCSSBackground(view: View): CSSBackgroundDrawable? =
getCompositeBackgroundDrawable(view)?.cssBackground
private fun getBackground(view: View): BackgroundDrawable? =
getCompositeBackgroundDrawable(view)?.background
@@ -492,12 +405,7 @@ public object BackgroundStyleApplicator {
val compositeBackgroundDrawable = ensureCompositeBackgroundDrawable(view)
var outline = compositeBackgroundDrawable.outline
if (outline == null) {
val borderRadius =
if (ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables()) {
compositeBackgroundDrawable.borderRadius
} else {
ensureCSSBackground(view).borderRadius
}
val borderRadius = compositeBackgroundDrawable.borderRadius
outline =
OutlineDrawable(
@@ -487,11 +487,13 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
* <p>Subclasses can override this method to implement custom resource prefetching for the
* ViewManager.
*
* @param surfaceId surface ID
* @param reactContext {@link com.facebook.react.bridge.ReactContext} used for the view.
* @param params {@link MapBuffer} prefetch request params defined in C++
*/
@UnstableReactNativeAPI
public void experimental_prefetchResources(ReactContext reactContext, MapBuffer params) {
public void experimental_prefetchResources(
int surfaceId, ReactContext reactContext, MapBuffer params) {
return;
}
@@ -35,14 +35,6 @@ internal class CompositeBackgroundDrawable(
/** Non-inset box shadows */
val outerShadows: List<Drawable> = emptyList(),
/**
* CSS background layer and border rendering
*
* TODO: we should extract path logic from here, and fast-path to using simpler drawables like
* ColorDrawable in the common cases
*/
val cssBackground: CSSBackgroundDrawable? = null,
/** Background rendering Layer */
val background: BackgroundDrawable? = null,
@@ -68,7 +60,6 @@ internal class CompositeBackgroundDrawable(
createLayersArray(
originalBackground,
outerShadows,
cssBackground,
background,
border,
feedbackUnderlay,
@@ -84,28 +75,11 @@ internal class CompositeBackgroundDrawable(
setPaddingMode(LayerDrawable.PADDING_MODE_STACK)
}
fun withNewCssBackground(cssBackground: CSSBackgroundDrawable?): CompositeBackgroundDrawable {
return CompositeBackgroundDrawable(
context,
originalBackground,
outerShadows,
cssBackground,
background,
border,
feedbackUnderlay,
innerShadows,
outline,
borderInsets,
borderRadius,
)
}
fun withNewBackground(background: BackgroundDrawable?): CompositeBackgroundDrawable {
return CompositeBackgroundDrawable(
context,
originalBackground,
outerShadows,
cssBackground,
background,
border,
feedbackUnderlay,
@@ -124,7 +98,6 @@ internal class CompositeBackgroundDrawable(
context,
originalBackground,
outerShadows,
cssBackground,
background,
border,
feedbackUnderlay,
@@ -140,7 +113,6 @@ internal class CompositeBackgroundDrawable(
context,
originalBackground,
outerShadows,
cssBackground,
background,
border,
feedbackUnderlay,
@@ -156,7 +128,6 @@ internal class CompositeBackgroundDrawable(
context,
originalBackground,
outerShadows,
cssBackground,
background,
border,
feedbackUnderlay,
@@ -172,7 +143,6 @@ internal class CompositeBackgroundDrawable(
context,
originalBackground,
outerShadows,
cssBackground,
background,
border,
newUnderlay,
@@ -230,7 +200,6 @@ internal class CompositeBackgroundDrawable(
private fun createLayersArray(
originalBackground: Drawable?,
outerShadows: List<Drawable>,
cssBackground: CSSBackgroundDrawable?,
background: BackgroundDrawable?,
border: BorderDrawable?,
feedbackUnderlay: Drawable?,
@@ -240,7 +209,6 @@ internal class CompositeBackgroundDrawable(
val layers = mutableListOf<Drawable?>()
originalBackground?.let { layers.add(it) }
layers.addAll(outerShadows.asReversed())
cssBackground?.let { layers.add(it) }
background?.let { layers.add(it) }
border?.let { layers.add(it) }
feedbackUnderlay?.let { layers.add(it) }
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<16b12024bb363358ef09b9a42cb2fc97>>
* @generated SignedSource<<d1dda9d6cd1c0179472fcc0631e46fcd>>
*/
/**
@@ -183,6 +183,12 @@ class ReactNativeFeatureFlagsJavaProvider
return method(javaProvider_);
}
bool enableImagePrefetchingOnUiThreadAndroid() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableImagePrefetchingOnUiThreadAndroid");
return method(javaProvider_);
}
bool enableImmediateUpdateModeForContentOffsetChanges() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableImmediateUpdateModeForContentOffsetChanges");
@@ -231,12 +237,6 @@ class ReactNativeFeatureFlagsJavaProvider
return method(javaProvider_);
}
bool enableNewBackgroundAndBorderDrawables() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableNewBackgroundAndBorderDrawables");
return method(javaProvider_);
}
bool enablePreparedTextLayout() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enablePreparedTextLayout");
@@ -345,12 +345,6 @@ class ReactNativeFeatureFlagsJavaProvider
return method(javaProvider_);
}
bool releaseImageDataWhenConsumed() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("releaseImageDataWhenConsumed");
return method(javaProvider_);
}
bool shouldPressibilityUseW3CPointerEventsForHover() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("shouldPressibilityUseW3CPointerEventsForHover");
@@ -577,6 +571,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableImagePrefetchingAndroid(
return ReactNativeFeatureFlags::enableImagePrefetchingAndroid();
}
bool JReactNativeFeatureFlagsCxxInterop::enableImagePrefetchingOnUiThreadAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableImagePrefetchingOnUiThreadAndroid();
}
bool JReactNativeFeatureFlagsCxxInterop::enableImmediateUpdateModeForContentOffsetChanges(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges();
@@ -617,11 +616,6 @@ bool JReactNativeFeatureFlagsCxxInterop::enableNetworkEventReporting(
return ReactNativeFeatureFlags::enableNetworkEventReporting();
}
bool JReactNativeFeatureFlagsCxxInterop::enableNewBackgroundAndBorderDrawables(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableNewBackgroundAndBorderDrawables();
}
bool JReactNativeFeatureFlagsCxxInterop::enablePreparedTextLayout(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enablePreparedTextLayout();
@@ -712,11 +706,6 @@ bool JReactNativeFeatureFlagsCxxInterop::preventShadowTreeCommitExhaustion(
return ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion();
}
bool JReactNativeFeatureFlagsCxxInterop::releaseImageDataWhenConsumed(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::releaseImageDataWhenConsumed();
}
bool JReactNativeFeatureFlagsCxxInterop::shouldPressibilityUseW3CPointerEventsForHover(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover();
@@ -905,6 +894,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"enableImagePrefetchingAndroid",
JReactNativeFeatureFlagsCxxInterop::enableImagePrefetchingAndroid),
makeNativeMethod(
"enableImagePrefetchingOnUiThreadAndroid",
JReactNativeFeatureFlagsCxxInterop::enableImagePrefetchingOnUiThreadAndroid),
makeNativeMethod(
"enableImmediateUpdateModeForContentOffsetChanges",
JReactNativeFeatureFlagsCxxInterop::enableImmediateUpdateModeForContentOffsetChanges),
@@ -929,9 +921,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"enableNetworkEventReporting",
JReactNativeFeatureFlagsCxxInterop::enableNetworkEventReporting),
makeNativeMethod(
"enableNewBackgroundAndBorderDrawables",
JReactNativeFeatureFlagsCxxInterop::enableNewBackgroundAndBorderDrawables),
makeNativeMethod(
"enablePreparedTextLayout",
JReactNativeFeatureFlagsCxxInterop::enablePreparedTextLayout),
@@ -986,9 +975,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"preventShadowTreeCommitExhaustion",
JReactNativeFeatureFlagsCxxInterop::preventShadowTreeCommitExhaustion),
makeNativeMethod(
"releaseImageDataWhenConsumed",
JReactNativeFeatureFlagsCxxInterop::releaseImageDataWhenConsumed),
makeNativeMethod(
"shouldPressibilityUseW3CPointerEventsForHover",
JReactNativeFeatureFlagsCxxInterop::shouldPressibilityUseW3CPointerEventsForHover),
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<54118ccd475a8bf1d7db83304b1f17d0>>
* @generated SignedSource<<31298767c1dd669d2a755e67edacc911>>
*/
/**
@@ -102,6 +102,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool enableImagePrefetchingAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableImagePrefetchingOnUiThreadAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableImmediateUpdateModeForContentOffsetChanges(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
@@ -126,9 +129,6 @@ class JReactNativeFeatureFlagsCxxInterop
static bool enableNetworkEventReporting(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableNewBackgroundAndBorderDrawables(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enablePreparedTextLayout(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
@@ -183,9 +183,6 @@ class JReactNativeFeatureFlagsCxxInterop
static bool preventShadowTreeCommitExhaustion(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool releaseImageDataWhenConsumed(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool shouldPressibilityUseW3CPointerEventsForHover(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<12a06ea04fc09c34f1fbdcbdf6046d81>>
* @generated SignedSource<<9a538d3ebb58173e7e4e34453b71454b>>
*/
/**
@@ -122,6 +122,10 @@ bool ReactNativeFeatureFlags::enableImagePrefetchingAndroid() {
return getAccessor().enableImagePrefetchingAndroid();
}
bool ReactNativeFeatureFlags::enableImagePrefetchingOnUiThreadAndroid() {
return getAccessor().enableImagePrefetchingOnUiThreadAndroid();
}
bool ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges() {
return getAccessor().enableImmediateUpdateModeForContentOffsetChanges();
}
@@ -154,10 +158,6 @@ bool ReactNativeFeatureFlags::enableNetworkEventReporting() {
return getAccessor().enableNetworkEventReporting();
}
bool ReactNativeFeatureFlags::enableNewBackgroundAndBorderDrawables() {
return getAccessor().enableNewBackgroundAndBorderDrawables();
}
bool ReactNativeFeatureFlags::enablePreparedTextLayout() {
return getAccessor().enablePreparedTextLayout();
}
@@ -230,10 +230,6 @@ bool ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion() {
return getAccessor().preventShadowTreeCommitExhaustion();
}
bool ReactNativeFeatureFlags::releaseImageDataWhenConsumed() {
return getAccessor().releaseImageDataWhenConsumed();
}
bool ReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover() {
return getAccessor().shouldPressibilityUseW3CPointerEventsForHover();
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<eee81e4e9bb13ef5134d4e2d79876b38>>
* @generated SignedSource<<3321d357fe5c74fa42c2d0b15a744f87>>
*/
/**
@@ -159,6 +159,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool enableImagePrefetchingAndroid();
/**
* When enabled, Android will initiate image prefetch requested on ImageShadowNode::layout on the UI thread
*/
RN_EXPORT static bool enableImagePrefetchingOnUiThreadAndroid();
/**
* Dispatches state updates for content offset changes synchronously on the main thread.
*/
@@ -199,11 +204,6 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool enableNetworkEventReporting();
/**
* Use BackgroundDrawable and BorderDrawable instead of CSSBackgroundDrawable
*/
RN_EXPORT static bool enableNewBackgroundAndBorderDrawables();
/**
* Enables caching text layout artifacts for later reuse
*/
@@ -294,11 +294,6 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool preventShadowTreeCommitExhaustion();
/**
* Releases the cached image data when it is consumed by the observers.
*/
RN_EXPORT static bool releaseImageDataWhenConsumed();
/**
* Function used to enable / disable Pressibility from using W3C Pointer Events for its hover callbacks
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<3c5588a851e6cdefaba22236c5ebb828>>
* @generated SignedSource<<041526548ef83b4afb12229a0345e29e>>
*/
/**
@@ -461,6 +461,24 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() {
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingOnUiThreadAndroid() {
auto flagValue = enableImagePrefetchingOnUiThreadAndroid_.load();
if (!flagValue.has_value()) {
// This block is not exclusive but it is not necessary.
// If multiple threads try to initialize the feature flag, we would only
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(24, "enableImagePrefetchingOnUiThreadAndroid");
flagValue = currentProvider_->enableImagePrefetchingOnUiThreadAndroid();
enableImagePrefetchingOnUiThreadAndroid_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetChanges() {
auto flagValue = enableImmediateUpdateModeForContentOffsetChanges_.load();
@@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetC
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(24, "enableImmediateUpdateModeForContentOffsetChanges");
markFlagAsAccessed(25, "enableImmediateUpdateModeForContentOffsetChanges");
flagValue = currentProvider_->enableImmediateUpdateModeForContentOffsetChanges();
enableImmediateUpdateModeForContentOffsetChanges_ = flagValue;
@@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimiz
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(25, "enableInteropViewManagerClassLookUpOptimizationIOS");
markFlagAsAccessed(26, "enableInteropViewManagerClassLookUpOptimizationIOS");
flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS();
enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue;
@@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(26, "enableLayoutAnimationsOnAndroid");
markFlagAsAccessed(27, "enableLayoutAnimationsOnAndroid");
flagValue = currentProvider_->enableLayoutAnimationsOnAndroid();
enableLayoutAnimationsOnAndroid_ = flagValue;
@@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(27, "enableLayoutAnimationsOnIOS");
markFlagAsAccessed(28, "enableLayoutAnimationsOnIOS");
flagValue = currentProvider_->enableLayoutAnimationsOnIOS();
enableLayoutAnimationsOnIOS_ = flagValue;
@@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMainQueueCoordinatorOnIOS() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(28, "enableMainQueueCoordinatorOnIOS");
markFlagAsAccessed(29, "enableMainQueueCoordinatorOnIOS");
flagValue = currentProvider_->enableMainQueueCoordinatorOnIOS();
enableMainQueueCoordinatorOnIOS_ = flagValue;
@@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::enableModuleArgumentNSNullConversionIOS()
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(29, "enableModuleArgumentNSNullConversionIOS");
markFlagAsAccessed(30, "enableModuleArgumentNSNullConversionIOS");
flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS();
enableModuleArgumentNSNullConversionIOS_ = flagValue;
@@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(30, "enableNativeCSSParsing");
markFlagAsAccessed(31, "enableNativeCSSParsing");
flagValue = currentProvider_->enableNativeCSSParsing();
enableNativeCSSParsing_ = flagValue;
@@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(31, "enableNetworkEventReporting");
markFlagAsAccessed(32, "enableNetworkEventReporting");
flagValue = currentProvider_->enableNetworkEventReporting();
enableNetworkEventReporting_ = flagValue;
@@ -605,24 +623,6 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() {
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableNewBackgroundAndBorderDrawables() {
auto flagValue = enableNewBackgroundAndBorderDrawables_.load();
if (!flagValue.has_value()) {
// This block is not exclusive but it is not necessary.
// If multiple threads try to initialize the feature flag, we would only
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(32, "enableNewBackgroundAndBorderDrawables");
flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables();
enableNewBackgroundAndBorderDrawables_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enablePreparedTextLayout() {
auto flagValue = enablePreparedTextLayout_.load();
@@ -947,24 +947,6 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() {
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::releaseImageDataWhenConsumed() {
auto flagValue = releaseImageDataWhenConsumed_.load();
if (!flagValue.has_value()) {
// This block is not exclusive but it is not necessary.
// If multiple threads try to initialize the feature flag, we would only
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(51, "releaseImageDataWhenConsumed");
flagValue = currentProvider_->releaseImageDataWhenConsumed();
releaseImageDataWhenConsumed_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHover() {
auto flagValue = shouldPressibilityUseW3CPointerEventsForHover_.load();
@@ -974,7 +956,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(52, "shouldPressibilityUseW3CPointerEventsForHover");
markFlagAsAccessed(51, "shouldPressibilityUseW3CPointerEventsForHover");
flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover();
shouldPressibilityUseW3CPointerEventsForHover_ = flagValue;
@@ -992,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause()
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(53, "skipActivityIdentityAssertionOnHostPause");
markFlagAsAccessed(52, "skipActivityIdentityAssertionOnHostPause");
flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause();
skipActivityIdentityAssertionOnHostPause_ = flagValue;
@@ -1010,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::sweepActiveTouchOnChildNativeGesturesAndro
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(54, "sweepActiveTouchOnChildNativeGesturesAndroid");
markFlagAsAccessed(53, "sweepActiveTouchOnChildNativeGesturesAndroid");
flagValue = currentProvider_->sweepActiveTouchOnChildNativeGesturesAndroid();
sweepActiveTouchOnChildNativeGesturesAndroid_ = flagValue;
@@ -1028,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(55, "traceTurboModulePromiseRejectionsOnAndroid");
markFlagAsAccessed(54, "traceTurboModulePromiseRejectionsOnAndroid");
flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid();
traceTurboModulePromiseRejectionsOnAndroid_ = flagValue;
@@ -1046,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit(
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(56, "updateRuntimeShadowNodeReferencesOnCommit");
markFlagAsAccessed(55, "updateRuntimeShadowNodeReferencesOnCommit");
flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit();
updateRuntimeShadowNodeReferencesOnCommit_ = flagValue;
@@ -1064,7 +1046,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(57, "useAlwaysAvailableJSErrorHandling");
markFlagAsAccessed(56, "useAlwaysAvailableJSErrorHandling");
flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling();
useAlwaysAvailableJSErrorHandling_ = flagValue;
@@ -1082,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(58, "useFabricInterop");
markFlagAsAccessed(57, "useFabricInterop");
flagValue = currentProvider_->useFabricInterop();
useFabricInterop_ = flagValue;
@@ -1100,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeEqualsInNativeReadableArrayAndroi
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(59, "useNativeEqualsInNativeReadableArrayAndroid");
markFlagAsAccessed(58, "useNativeEqualsInNativeReadableArrayAndroid");
flagValue = currentProvider_->useNativeEqualsInNativeReadableArrayAndroid();
useNativeEqualsInNativeReadableArrayAndroid_ = flagValue;
@@ -1118,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeTransformHelperAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(60, "useNativeTransformHelperAndroid");
markFlagAsAccessed(59, "useNativeTransformHelperAndroid");
flagValue = currentProvider_->useNativeTransformHelperAndroid();
useNativeTransformHelperAndroid_ = flagValue;
@@ -1136,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(61, "useNativeViewConfigsInBridgelessMode");
markFlagAsAccessed(60, "useNativeViewConfigsInBridgelessMode");
flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode();
useNativeViewConfigsInBridgelessMode_ = flagValue;
@@ -1154,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(62, "useOptimizedEventBatchingOnAndroid");
markFlagAsAccessed(61, "useOptimizedEventBatchingOnAndroid");
flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid();
useOptimizedEventBatchingOnAndroid_ = flagValue;
@@ -1172,7 +1154,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(63, "useRawPropsJsiValue");
markFlagAsAccessed(62, "useRawPropsJsiValue");
flagValue = currentProvider_->useRawPropsJsiValue();
useRawPropsJsiValue_ = flagValue;
@@ -1190,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(64, "useShadowNodeStateOnClone");
markFlagAsAccessed(63, "useShadowNodeStateOnClone");
flagValue = currentProvider_->useShadowNodeStateOnClone();
useShadowNodeStateOnClone_ = flagValue;
@@ -1208,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(65, "useTurboModuleInterop");
markFlagAsAccessed(64, "useTurboModuleInterop");
flagValue = currentProvider_->useTurboModuleInterop();
useTurboModuleInterop_ = flagValue;
@@ -1226,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(66, "useTurboModules");
markFlagAsAccessed(65, "useTurboModules");
flagValue = currentProvider_->useTurboModules();
useTurboModules_ = flagValue;
@@ -1244,7 +1226,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewHysteresisRatio() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(67, "virtualViewHysteresisRatio");
markFlagAsAccessed(66, "virtualViewHysteresisRatio");
flagValue = currentProvider_->virtualViewHysteresisRatio();
virtualViewHysteresisRatio_ = flagValue;
@@ -1262,7 +1244,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(68, "virtualViewPrerenderRatio");
markFlagAsAccessed(67, "virtualViewPrerenderRatio");
flagValue = currentProvider_->virtualViewPrerenderRatio();
virtualViewPrerenderRatio_ = flagValue;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<f1eb31a7412bff743a5c581224d71e2a>>
* @generated SignedSource<<9c51131fae9f19d03050be0c74ca3d4b>>
*/
/**
@@ -56,6 +56,7 @@ class ReactNativeFeatureFlagsAccessor {
bool enableIOSTextBaselineOffsetPerLine();
bool enableIOSViewClipToPaddingBox();
bool enableImagePrefetchingAndroid();
bool enableImagePrefetchingOnUiThreadAndroid();
bool enableImmediateUpdateModeForContentOffsetChanges();
bool enableInteropViewManagerClassLookUpOptimizationIOS();
bool enableLayoutAnimationsOnAndroid();
@@ -64,7 +65,6 @@ class ReactNativeFeatureFlagsAccessor {
bool enableModuleArgumentNSNullConversionIOS();
bool enableNativeCSSParsing();
bool enableNetworkEventReporting();
bool enableNewBackgroundAndBorderDrawables();
bool enablePreparedTextLayout();
bool enablePropsUpdateReconciliationAndroid();
bool enableResourceTimingAPI();
@@ -83,7 +83,6 @@ class ReactNativeFeatureFlagsAccessor {
bool perfMonitorV2Enabled();
double preparedTextCacheSize();
bool preventShadowTreeCommitExhaustion();
bool releaseImageDataWhenConsumed();
bool shouldPressibilityUseW3CPointerEventsForHover();
bool skipActivityIdentityAssertionOnHostPause();
bool sweepActiveTouchOnChildNativeGesturesAndroid();
@@ -112,7 +111,7 @@ class ReactNativeFeatureFlagsAccessor {
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
bool wasOverridden_;
std::array<std::atomic<const char*>, 69> accessedFeatureFlags_;
std::array<std::atomic<const char*>, 68> accessedFeatureFlags_;
std::atomic<std::optional<bool>> commonTestFlag_;
std::atomic<std::optional<bool>> cdpInteractionMetricsEnabled_;
@@ -138,6 +137,7 @@ class ReactNativeFeatureFlagsAccessor {
std::atomic<std::optional<bool>> enableIOSTextBaselineOffsetPerLine_;
std::atomic<std::optional<bool>> enableIOSViewClipToPaddingBox_;
std::atomic<std::optional<bool>> enableImagePrefetchingAndroid_;
std::atomic<std::optional<bool>> enableImagePrefetchingOnUiThreadAndroid_;
std::atomic<std::optional<bool>> enableImmediateUpdateModeForContentOffsetChanges_;
std::atomic<std::optional<bool>> enableInteropViewManagerClassLookUpOptimizationIOS_;
std::atomic<std::optional<bool>> enableLayoutAnimationsOnAndroid_;
@@ -146,7 +146,6 @@ class ReactNativeFeatureFlagsAccessor {
std::atomic<std::optional<bool>> enableModuleArgumentNSNullConversionIOS_;
std::atomic<std::optional<bool>> enableNativeCSSParsing_;
std::atomic<std::optional<bool>> enableNetworkEventReporting_;
std::atomic<std::optional<bool>> enableNewBackgroundAndBorderDrawables_;
std::atomic<std::optional<bool>> enablePreparedTextLayout_;
std::atomic<std::optional<bool>> enablePropsUpdateReconciliationAndroid_;
std::atomic<std::optional<bool>> enableResourceTimingAPI_;
@@ -165,7 +164,6 @@ class ReactNativeFeatureFlagsAccessor {
std::atomic<std::optional<bool>> perfMonitorV2Enabled_;
std::atomic<std::optional<double>> preparedTextCacheSize_;
std::atomic<std::optional<bool>> preventShadowTreeCommitExhaustion_;
std::atomic<std::optional<bool>> releaseImageDataWhenConsumed_;
std::atomic<std::optional<bool>> shouldPressibilityUseW3CPointerEventsForHover_;
std::atomic<std::optional<bool>> skipActivityIdentityAssertionOnHostPause_;
std::atomic<std::optional<bool>> sweepActiveTouchOnChildNativeGesturesAndroid_;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<a76f1a1e8ba0d65b689b4b87d33d7ced>>
* @generated SignedSource<<5f9c3ecf7887653fd5348a05391ab7d0>>
*/
/**
@@ -123,6 +123,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool enableImagePrefetchingOnUiThreadAndroid() override {
return false;
}
bool enableImmediateUpdateModeForContentOffsetChanges() override {
return false;
}
@@ -155,10 +159,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool enableNewBackgroundAndBorderDrawables() override {
return true;
}
bool enablePreparedTextLayout() override {
return false;
}
@@ -231,10 +231,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool releaseImageDataWhenConsumed() override {
return false;
}
bool shouldPressibilityUseW3CPointerEventsForHover() override {
return false;
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<e2a5086e5586caf4c90ef503416a0e83>>
* @generated SignedSource<<027cef9dd44f14a71be7c0d1b90238b3>>
*/
/**
@@ -261,6 +261,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef
return ReactNativeFeatureFlagsDefaults::enableImagePrefetchingAndroid();
}
bool enableImagePrefetchingOnUiThreadAndroid() override {
auto value = values_["enableImagePrefetchingOnUiThreadAndroid"];
if (!value.isNull()) {
return value.getBool();
}
return ReactNativeFeatureFlagsDefaults::enableImagePrefetchingOnUiThreadAndroid();
}
bool enableImmediateUpdateModeForContentOffsetChanges() override {
auto value = values_["enableImmediateUpdateModeForContentOffsetChanges"];
if (!value.isNull()) {
@@ -333,15 +342,6 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef
return ReactNativeFeatureFlagsDefaults::enableNetworkEventReporting();
}
bool enableNewBackgroundAndBorderDrawables() override {
auto value = values_["enableNewBackgroundAndBorderDrawables"];
if (!value.isNull()) {
return value.getBool();
}
return ReactNativeFeatureFlagsDefaults::enableNewBackgroundAndBorderDrawables();
}
bool enablePreparedTextLayout() override {
auto value = values_["enablePreparedTextLayout"];
if (!value.isNull()) {
@@ -504,15 +504,6 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef
return ReactNativeFeatureFlagsDefaults::preventShadowTreeCommitExhaustion();
}
bool releaseImageDataWhenConsumed() override {
auto value = values_["releaseImageDataWhenConsumed"];
if (!value.isNull()) {
return value.getBool();
}
return ReactNativeFeatureFlagsDefaults::releaseImageDataWhenConsumed();
}
bool shouldPressibilityUseW3CPointerEventsForHover() override {
auto value = values_["shouldPressibilityUseW3CPointerEventsForHover"];
if (!value.isNull()) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<feb44bb7ec97d29787eac070103f9e1b>>
* @generated SignedSource<<a78e171b87f70a1b2ab0de2f9e48012b>>
*/
/**
@@ -49,6 +49,7 @@ class ReactNativeFeatureFlagsProvider {
virtual bool enableIOSTextBaselineOffsetPerLine() = 0;
virtual bool enableIOSViewClipToPaddingBox() = 0;
virtual bool enableImagePrefetchingAndroid() = 0;
virtual bool enableImagePrefetchingOnUiThreadAndroid() = 0;
virtual bool enableImmediateUpdateModeForContentOffsetChanges() = 0;
virtual bool enableInteropViewManagerClassLookUpOptimizationIOS() = 0;
virtual bool enableLayoutAnimationsOnAndroid() = 0;
@@ -57,7 +58,6 @@ class ReactNativeFeatureFlagsProvider {
virtual bool enableModuleArgumentNSNullConversionIOS() = 0;
virtual bool enableNativeCSSParsing() = 0;
virtual bool enableNetworkEventReporting() = 0;
virtual bool enableNewBackgroundAndBorderDrawables() = 0;
virtual bool enablePreparedTextLayout() = 0;
virtual bool enablePropsUpdateReconciliationAndroid() = 0;
virtual bool enableResourceTimingAPI() = 0;
@@ -76,7 +76,6 @@ class ReactNativeFeatureFlagsProvider {
virtual bool perfMonitorV2Enabled() = 0;
virtual double preparedTextCacheSize() = 0;
virtual bool preventShadowTreeCommitExhaustion() = 0;
virtual bool releaseImageDataWhenConsumed() = 0;
virtual bool shouldPressibilityUseW3CPointerEventsForHover() = 0;
virtual bool skipActivityIdentityAssertionOnHostPause() = 0;
virtual bool sweepActiveTouchOnChildNativeGesturesAndroid() = 0;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<c9c36c1dbece9e27f7b71da7611cb747>>
* @generated SignedSource<<07df05bf452f78603bbf79594aa0cba0>>
*/
/**
@@ -164,6 +164,11 @@ bool NativeReactNativeFeatureFlags::enableImagePrefetchingAndroid(
return ReactNativeFeatureFlags::enableImagePrefetchingAndroid();
}
bool NativeReactNativeFeatureFlags::enableImagePrefetchingOnUiThreadAndroid(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableImagePrefetchingOnUiThreadAndroid();
}
bool NativeReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges();
@@ -204,11 +209,6 @@ bool NativeReactNativeFeatureFlags::enableNetworkEventReporting(
return ReactNativeFeatureFlags::enableNetworkEventReporting();
}
bool NativeReactNativeFeatureFlags::enableNewBackgroundAndBorderDrawables(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableNewBackgroundAndBorderDrawables();
}
bool NativeReactNativeFeatureFlags::enablePreparedTextLayout(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enablePreparedTextLayout();
@@ -299,11 +299,6 @@ bool NativeReactNativeFeatureFlags::preventShadowTreeCommitExhaustion(
return ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion();
}
bool NativeReactNativeFeatureFlags::releaseImageDataWhenConsumed(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::releaseImageDataWhenConsumed();
}
bool NativeReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover();
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<320e69fa54228a352fad210e3a43b947>>
* @generated SignedSource<<228d7484ef89bb01fee8dcff2657c56a>>
*/
/**
@@ -84,6 +84,8 @@ class NativeReactNativeFeatureFlags
bool enableImagePrefetchingAndroid(jsi::Runtime& runtime);
bool enableImagePrefetchingOnUiThreadAndroid(jsi::Runtime& runtime);
bool enableImmediateUpdateModeForContentOffsetChanges(jsi::Runtime& runtime);
bool enableInteropViewManagerClassLookUpOptimizationIOS(jsi::Runtime& runtime);
@@ -100,8 +102,6 @@ class NativeReactNativeFeatureFlags
bool enableNetworkEventReporting(jsi::Runtime& runtime);
bool enableNewBackgroundAndBorderDrawables(jsi::Runtime& runtime);
bool enablePreparedTextLayout(jsi::Runtime& runtime);
bool enablePropsUpdateReconciliationAndroid(jsi::Runtime& runtime);
@@ -138,8 +138,6 @@ class NativeReactNativeFeatureFlags
bool preventShadowTreeCommitExhaustion(jsi::Runtime& runtime);
bool releaseImageDataWhenConsumed(jsi::Runtime& runtime);
bool shouldPressibilityUseW3CPointerEventsForHover(jsi::Runtime& runtime);
bool skipActivityIdentityAssertionOnHostPause(jsi::Runtime& runtime);
@@ -25,6 +25,7 @@
#include <react/renderer/animated/nodes/InterpolationAnimatedNode.h>
#include <react/renderer/animated/nodes/ModulusAnimatedNode.h>
#include <react/renderer/animated/nodes/MultiplicationAnimatedNode.h>
#include <react/renderer/animated/nodes/ObjectAnimatedNode.h>
#include <react/renderer/animated/nodes/PropsAnimatedNode.h>
#include <react/renderer/animated/nodes/RoundAnimatedNode.h>
#include <react/renderer/animated/nodes/StyleAnimatedNode.h>
@@ -145,6 +146,8 @@ std::unique_ptr<AnimatedNode> NativeAnimatedNodesManager::animatedNode(
return std::make_unique<DiffClampAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Round:
return std::make_unique<RoundAnimatedNode>(tag, config, *this);
case AnimatedNodeType::Object:
return std::make_unique<ObjectAnimatedNode>(tag, config, *this);
default:
LOG(WARNING) << "Cannot create AnimatedNode of type " << typeName
<< ", it's not implemented yet";
@@ -73,6 +73,8 @@ std::optional<AnimatedNodeType> AnimatedNode::getNodeTypeByName(
return AnimatedNodeType::Tracking;
} else if (nodeTypeName == "round") {
return AnimatedNodeType::Round;
} else if (nodeTypeName == "object") {
return AnimatedNodeType::Object;
} else {
return std::nullopt;
}
@@ -32,6 +32,7 @@ enum class AnimatedNodeType {
Tracking,
Color,
Round,
Object
};
class NativeAnimatedNodesManager;
@@ -0,0 +1,121 @@
/*
* 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.
*/
/*
* Adapted from react-native-windows under the MIT license.
*/
#include "ObjectAnimatedNode.h"
#include <glog/logging.h>
#include <react/renderer/animated/NativeAnimatedNodesManager.h>
#include <react/renderer/animated/internal/NativeAnimatedAllowlist.h>
#include <react/renderer/animated/nodes/ColorAnimatedNode.h>
#include <react/renderer/animated/nodes/TransformAnimatedNode.h>
#include <react/renderer/animated/nodes/ValueAnimatedNode.h>
namespace facebook::react {
ObjectAnimatedNode::ObjectAnimatedNode(
Tag tag,
const folly::dynamic& config,
NativeAnimatedNodesManager& manager)
: AnimatedNode(tag, config, manager, AnimatedNodeType::Object) {}
void ObjectAnimatedNode::collectViewUpdates(
std::string propKey,
folly::dynamic& props) {
const auto& value = getConfig()["value"];
switch (value.type()) {
case folly::dynamic::OBJECT: {
props.insert(propKey, collectViewUpdatesObjectHelper(value));
} break;
case folly::dynamic::ARRAY: {
props.insert(propKey, collectViewUpdatesArrayHelper(value));
} break;
default: {
LOG(ERROR) << "Invalid value type for ObjectAnimatedNode";
} break;
}
}
folly::dynamic ObjectAnimatedNode::collectViewUpdatesObjectHelper(
const folly::dynamic& value) const {
folly::dynamic result = folly::dynamic::object();
for (const auto& valueProp : value.items()) {
result.insert(valueProp.first.asString(), getValueProp(valueProp.second));
}
return result;
}
folly::dynamic ObjectAnimatedNode::collectViewUpdatesArrayHelper(
const folly::dynamic& value) const {
folly::dynamic result = folly::dynamic::array();
for (const auto& valueProp : value) {
result.push_back(getValueProp(valueProp));
}
return result;
}
folly::dynamic ObjectAnimatedNode::getValueProp(
const folly::dynamic& prop) const {
switch (prop.type()) {
case folly::dynamic::OBJECT: {
if (auto itNodeTag = prop.find("nodeTag");
itNodeTag != prop.items().end()) {
auto nodeTag = static_cast<Tag>(itNodeTag->second.asInt());
if (auto node = manager_->getAnimatedNode<AnimatedNode>(nodeTag)) {
switch (node->type()) {
case AnimatedNodeType::Value:
case AnimatedNodeType::Interpolation:
case AnimatedNodeType::Modulus:
case AnimatedNodeType::Round:
case AnimatedNodeType::Diffclamp:
// Operators
case AnimatedNodeType::Addition:
case AnimatedNodeType::Subtraction:
case AnimatedNodeType::Multiplication:
case AnimatedNodeType::Division: {
if (const auto valueNode =
manager_->getAnimatedNode<ValueAnimatedNode>(nodeTag)) {
if (valueNode->getIsColorValue()) {
return static_cast<int32_t>(valueNode->getValue());
} else {
return valueNode->getValue();
}
}
} break;
case AnimatedNodeType::Color: {
if (const auto colorAnimNode =
manager_->getAnimatedNode<ColorAnimatedNode>(nodeTag)) {
return static_cast<int32_t>(colorAnimNode->getColor());
}
} break;
default:
break;
}
}
} else {
return collectViewUpdatesObjectHelper(prop);
}
} break;
case folly::dynamic::ARRAY: {
return collectViewUpdatesArrayHelper(prop);
};
case folly::dynamic::NULLT:
case folly::dynamic::BOOL:
case folly::dynamic::DOUBLE:
case folly::dynamic::INT64:
case folly::dynamic::STRING: {
return prop;
};
}
LOG(ERROR) << "Invalid prop type for ObjectAnimatedNode";
return nullptr;
}
} // namespace facebook::react
@@ -0,0 +1,38 @@
/*
* 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.
*/
/*
* Adapted from react-native-windows under the MIT license.
*/
#pragma once
#include "AnimatedNode.h"
#include <folly/dynamic.h>
namespace facebook::react {
class ObjectAnimatedNode final : public AnimatedNode {
public:
ObjectAnimatedNode(
Tag tag,
const folly::dynamic& config,
NativeAnimatedNodesManager& manager);
void collectViewUpdates(std::string propKey, folly::dynamic& props);
private:
folly::dynamic collectViewUpdatesObjectHelper(
const folly::dynamic& value) const;
folly::dynamic collectViewUpdatesArrayHelper(
const folly::dynamic& value) const;
folly::dynamic getValueProp(const folly::dynamic& prop) const;
};
} // namespace facebook::react
@@ -14,6 +14,7 @@
#include <react/debug/react_native_assert.h>
#include <react/renderer/animated/NativeAnimatedNodesManager.h>
#include <react/renderer/animated/nodes/ColorAnimatedNode.h>
#include <react/renderer/animated/nodes/ObjectAnimatedNode.h>
#include <react/renderer/animated/nodes/StyleAnimatedNode.h>
#include <react/renderer/animated/nodes/ValueAnimatedNode.h>
@@ -126,6 +127,12 @@ void PropsAnimatedNode::update(bool forceFabricCommit) {
styleNode->collectViewUpdates(props_);
}
} break;
case AnimatedNodeType::Object: {
if (const auto objectNode =
manager_->getAnimatedNode<ObjectAnimatedNode>(nodeTag)) {
objectNode->collectViewUpdates(propName, props_);
}
} break;
case AnimatedNodeType::Props:
case AnimatedNodeType::Tracking:
case AnimatedNodeType::Transform:
@@ -14,6 +14,7 @@
#include <react/renderer/animated/NativeAnimatedNodesManager.h>
#include <react/renderer/animated/internal/NativeAnimatedAllowlist.h>
#include <react/renderer/animated/nodes/ColorAnimatedNode.h>
#include <react/renderer/animated/nodes/ObjectAnimatedNode.h>
#include <react/renderer/animated/nodes/TransformAnimatedNode.h>
#include <react/renderer/animated/nodes/ValueAnimatedNode.h>
@@ -82,6 +83,12 @@ void StyleAnimatedNode::collectViewUpdates(folly::dynamic& props) {
static_cast<int32_t>(colorAnimNode->getColor()));
}
} break;
case AnimatedNodeType::Object: {
if (const auto objectNode =
manager_->getAnimatedNode<ObjectAnimatedNode>(nodeTag)) {
objectNode->collectViewUpdates(propName, props);
}
} break;
case AnimatedNodeType::Tracking:
case AnimatedNodeType::Style:
case AnimatedNodeType::Props:
@@ -8,6 +8,7 @@
#include "AnimationTestsBase.h"
#include <react/renderer/animated/nodes/ColorAnimatedNode.h>
#include <react/renderer/animated/nodes/ObjectAnimatedNode.h>
#include <react/renderer/core/ReactRootViewTagGenerator.h>
#include <react/renderer/graphics/Color.h>
@@ -214,4 +215,54 @@ TEST_F(AnimatedNodeTests, DiffClampAnimatedNode) {
EXPECT_EQ(nodesManager_->getValue(diffClampTag), 1);
}
TEST_F(AnimatedNodeTests, ObjectAnimatedNode) {
initNodesManager();
auto rootTag = getNextRootViewTag();
auto valueTag = ++rootTag;
auto objectTag = ++rootTag;
nodesManager_->createAnimatedNode(
valueTag,
folly::dynamic::object("type", "value")("value", 4)("offset", 0));
nodesManager_->createAnimatedNode(
objectTag,
folly::dynamic::object("type", "object")(
"value",
folly::dynamic::array(
folly::dynamic::object(
"translate3d",
folly::dynamic::object("x", 1)("y", 0)("z", 0)),
folly::dynamic::object(
"rotate3d",
folly::dynamic::object("x", 1)("y", 0)("z", 0)(
"angle", "180deg")),
folly::dynamic::object(
"scale3d", folly::dynamic::object("nodeTag", valueTag)))));
nodesManager_->connectAnimatedNodes(valueTag, objectTag);
const auto objectNode =
nodesManager_->getAnimatedNode<ObjectAnimatedNode>(objectTag);
folly::dynamic collectedProps = folly::dynamic::object();
objectNode->collectViewUpdates("test", collectedProps);
const auto expected = folly::dynamic::object(
"test",
folly::dynamic::array(
folly::dynamic::object(
"translate3d", folly::dynamic::object("x", 1)("y", 0)("z", 0)),
folly::dynamic::object(
"rotate3d",
folly::dynamic::object("x", 1)("y", 0)("z", 0)(
"angle", "180deg")),
folly::dynamic::object("scale3d", 4)));
EXPECT_EQ(collectedProps["test"].size(), 3);
EXPECT_EQ(collectedProps["test"][0]["translate3d"]["x"], 1);
EXPECT_EQ(collectedProps["test"][1]["rotate3d"]["y"], 0);
EXPECT_EQ(collectedProps["test"][1]["rotate3d"]["angle"], "180deg");
EXPECT_EQ(collectedProps["test"][2]["scale3d"], 4);
}
} // namespace facebook::react
@@ -12,8 +12,6 @@
#include <string>
#include <vector>
#include <react/renderer/debug/DebugStringConvertible.h>
namespace facebook::react {
enum class AccessibilityTraits : uint32_t {
@@ -55,27 +53,6 @@ struct AccessibilityAction {
std::optional<std::string> label{};
};
inline std::string toString(const AccessibilityAction& accessibilityAction) {
std::string result = accessibilityAction.name;
if (accessibilityAction.label.has_value()) {
result += ": '" + accessibilityAction.label.value() + "'";
}
return result;
}
inline std::string toString(
std::vector<AccessibilityAction> accessibilityActions) {
std::string result = "[";
for (size_t i = 0; i < accessibilityActions.size(); i++) {
result += toString(accessibilityActions[i]);
if (i < accessibilityActions.size() - 1) {
result += ", ";
}
}
result += "]";
return result;
}
inline static bool operator==(
const AccessibilityAction& lhs,
const AccessibilityAction& rhs) {
@@ -110,29 +87,6 @@ constexpr bool operator!=(
return !(rhs == lhs);
}
#if RN_DEBUG_STRING_CONVERTIBLE
inline std::string toString(AccessibilityState::CheckedState state) {
switch (state) {
case AccessibilityState::Unchecked:
return "Unchecked";
case AccessibilityState::Checked:
return "Checked";
case AccessibilityState::Mixed:
return "Mixed";
case AccessibilityState::None:
return "None";
}
}
inline std::string toString(const AccessibilityState& accessibilityState) {
return "{disabled:" + toString(accessibilityState.disabled) +
",selected:" + toString(accessibilityState.selected) +
",checked:" + toString(accessibilityState.checked) +
",busy:" + toString(accessibilityState.busy) +
",expanded:" + toString(accessibilityState.expanded) + "}";
}
#endif
struct AccessibilityLabelledBy {
std::vector<std::string> value{};
};
@@ -182,19 +136,7 @@ enum class AccessibilityLiveRegion : uint8_t {
Assertive,
};
inline std::string toString(
const AccessibilityLiveRegion& accessibilityLiveRegion) {
switch (accessibilityLiveRegion) {
case AccessibilityLiveRegion::None:
return "none";
case AccessibilityLiveRegion::Polite:
return "polite";
case AccessibilityLiveRegion::Assertive:
return "assertive";
}
}
enum class AccessibilityRole {
enum class AccessibilityRole : uint8_t {
None,
Button,
Dropdownlist,
@@ -237,7 +179,7 @@ enum class AccessibilityRole {
Iconmenu,
};
enum class Role {
enum class Role : uint8_t {
Alert,
Alertdialog,
Application,
@@ -14,6 +14,7 @@
#include <react/renderer/components/view/AccessibilityPrimitives.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/propsConversions.h>
#include <react/renderer/debug/DebugStringConvertible.h>
#include <unordered_map>
@@ -782,4 +783,59 @@ inline void fromRawValue(
result = Role::None;
}
inline std::string toString(AccessibilityLiveRegion accessibilityLiveRegion) {
switch (accessibilityLiveRegion) {
case AccessibilityLiveRegion::None:
return "none";
case AccessibilityLiveRegion::Polite:
return "polite";
case AccessibilityLiveRegion::Assertive:
return "assertive";
}
}
#if RN_DEBUG_STRING_CONVERTIBLE
inline std::string toString(AccessibilityState::CheckedState state) {
switch (state) {
case AccessibilityState::Unchecked:
return "Unchecked";
case AccessibilityState::Checked:
return "Checked";
case AccessibilityState::Mixed:
return "Mixed";
case AccessibilityState::None:
return "None";
}
}
inline std::string toString(const AccessibilityAction& accessibilityAction) {
std::string result = accessibilityAction.name;
if (accessibilityAction.label.has_value()) {
result += ": '" + accessibilityAction.label.value() + "'";
}
return result;
}
inline std::string toString(
std::vector<AccessibilityAction> accessibilityActions) {
std::string result = "[";
for (size_t i = 0; i < accessibilityActions.size(); i++) {
result += toString(accessibilityActions[i]);
if (i < accessibilityActions.size() - 1) {
result += ", ";
}
}
result += "]";
return result;
}
inline std::string toString(const AccessibilityState& accessibilityState) {
return "{disabled:" + toString(accessibilityState.disabled) +
",selected:" + toString(accessibilityState.selected) +
",checked:" + toString(accessibilityState.checked) +
",busy:" + toString(accessibilityState.busy) +
",expanded:" + toString(accessibilityState.expanded) + "}";
}
#endif
} // namespace facebook::react
@@ -848,7 +848,7 @@ inline void fromRawValue(
react_native_expect(false);
}
inline std::string toString(const PointerEventsMode& value) {
inline std::string toString(PointerEventsMode value) {
switch (value) {
case PointerEventsMode::Auto:
return "auto";
@@ -618,21 +618,7 @@ folly::dynamic HostPlatformViewProps::getDiffProps(
}
if (pointerEvents != oldProps->pointerEvents) {
std::string value;
switch (pointerEvents) {
case PointerEventsMode::BoxOnly:
result["pointerEvents"] = "box-only";
break;
case PointerEventsMode::BoxNone:
result["pointerEvents"] = "box-none";
break;
case PointerEventsMode::None:
result["pointerEvents"] = "none";
break;
default:
result["pointerEvents"] = "auto";
break;
}
result["pointerEvents"] = toString(pointerEvents);
}
if (hitSlop != oldProps->hitSlop) {
@@ -917,17 +903,7 @@ folly::dynamic HostPlatformViewProps::getDiffProps(
}
if (accessibilityLiveRegion != oldProps->accessibilityLiveRegion) {
switch (accessibilityLiveRegion) {
case AccessibilityLiveRegion::Assertive:
result["accessibilityLiveRegion"] = "assertive";
break;
case AccessibilityLiveRegion::Polite:
result["accessibilityLiveRegion"] = "polite";
break;
case AccessibilityLiveRegion::None:
result["accessibilityLiveRegion"] = "none";
break;
}
result["accessibilityLiveRegion"] = toString(accessibilityLiveRegion);
}
if (accessibilityHint != oldProps->accessibilityHint) {
@@ -1003,20 +979,7 @@ folly::dynamic HostPlatformViewProps::getDiffProps(
}
if (importantForAccessibility != oldProps->importantForAccessibility) {
switch (importantForAccessibility) {
case ImportantForAccessibility::Auto:
result["importantForAccessibility"] = "auto";
break;
case ImportantForAccessibility::Yes:
result["importantForAccessibility"] = "yes";
break;
case ImportantForAccessibility::No:
result["importantForAccessibility"] = "no";
break;
case ImportantForAccessibility::NoHideDescendants:
result["importantForAccessibility"] = "noHideDescendants";
break;
}
result["importantForAccessibility"] = toString(importantForAccessibility);
}
return result;
@@ -123,11 +123,9 @@ void ImageResponseObserverCoordinator::nativeImageResponseFailed(
}
void ImageResponseObserverCoordinator::consumeResponse() const {
if (ReactNativeFeatureFlags::releaseImageDataWhenConsumed()) {
status_ = ImageResponse::Status::Consumed;
imageData_.reset();
imageMetadata_.reset();
}
status_ = ImageResponse::Status::Consumed;
imageData_.reset();
imageMetadata_.reset();
}
} // namespace facebook::react
@@ -44,9 +44,8 @@ ImageRequest ImageFetcher::requestImage(
SurfaceId surfaceId,
const ImageRequestParams& imageRequestParams,
Tag tag) {
items_.emplace_back(ImageRequestItem{
items_[surfaceId].emplace_back(ImageRequestItem{
.imageSource = imageSource,
.surfaceId = surfaceId,
.imageRequestParams = imageRequestParams,
.tag = tag});
@@ -68,13 +67,18 @@ RootShadowNode::Unshared ImageFetcher::shadowTreeWillCommit(
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
static auto prefetchResources =
fabricUIManager_->getClass()
->getMethod<void(std::string, JReadableMapBuffer::javaobject)>(
->getMethod<void(
SurfaceId, std::string, JReadableMapBuffer::javaobject)>(
"experimental_prefetchResources");
auto readableMapBuffer =
JReadableMapBuffer::createWithContents(serializeImageRequests(items_));
for (auto& [surfaceId, surfaceImageRequests] : items_) {
auto readableMapBuffer = JReadableMapBuffer::createWithContents(
serializeImageRequests(surfaceImageRequests));
prefetchResources(
fabricUIManager_, surfaceId, "RCTImageView", readableMapBuffer.get());
}
items_.clear();
prefetchResources(fabricUIManager_, "RCTImageView", readableMapBuffer.get());
return newRootShadowNode;
}
@@ -13,6 +13,8 @@
#include <react/renderer/mounting/ShadowTree.h>
#include <react/renderer/uimanager/UIManagerCommitHook.h>
#include <react/utils/ContextContainer.h>
#include <unordered_map>
#include <vector>
namespace facebook::react {
@@ -43,7 +45,7 @@ class ImageFetcher : public UIManagerCommitHook {
const ShadowTree::CommitOptions& commitOptions) noexcept override;
private:
std::vector<ImageRequestItem> items_;
std::unordered_map<SurfaceId, std::vector<ImageRequestItem>> items_;
std::shared_ptr<const ContextContainer> contextContainer_;
};
} // namespace facebook::react
@@ -93,7 +93,6 @@ class ImageRequestParams {
struct ImageRequestItem {
ImageSource imageSource;
SurfaceId surfaceId{};
ImageRequestParams imageRequestParams;
Tag tag{};
};
@@ -34,8 +34,7 @@ constexpr MapBuffer::Key IS_KEY_FADE_DURATION = 11;
constexpr MapBuffer::Key IS_KEY_PROGRESSIVE_RENDERING_ENABLED = 12;
constexpr MapBuffer::Key IS_KEY_LOADING_INDICATOR_SRC = 13;
constexpr MapBuffer::Key IS_KEY_ANALYTIC_TAG = 14;
constexpr MapBuffer::Key IS_KEY_SURFACE_ID = 15;
constexpr MapBuffer::Key IS_KEY_TAG = 16;
constexpr MapBuffer::Key IS_KEY_TAG = 15;
inline void serializeImageSource(
MapBufferBuilder& builder,
@@ -85,7 +84,6 @@ inline MapBuffer serializeImageRequest(const ImageRequestItem& item) {
auto builder = MapBufferBuilder();
serializeImageSource(builder, item.imageSource);
serializeImageRequestParams(builder, item.imageRequestParams);
builder.putInt(IS_KEY_SURFACE_ID, item.surfaceId);
builder.putInt(IS_KEY_TAG, item.tag);
return builder.build();
}
+22 -21
View File
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<db6de028840aefaf5eeb3e2cec029553>>
* @generated SignedSource<<0a0286ba0bc29af2abd2e8fd836077fb>>
*
* This file was generated by scripts/js-api/build-types/index.js.
*/
@@ -3089,6 +3089,13 @@ declare type ListRenderItemInfo<ItemT> = {
item: ItemT
separators: Separators
}
declare type ListViewToken = {
index: number | undefined
isViewable: boolean
item: any
key: string
section?: any
}
declare type LogBox = typeof LogBox
declare type LogData = {
readonly category: Category
@@ -3511,8 +3518,8 @@ declare type OptionalVirtualizedListProps = {
onStartReached?: (info: { distanceFromStart: number }) => void
onStartReachedThreshold?: number
onViewableItemsChanged?: (info: {
changed: Array<ViewToken>
viewableItems: Array<ViewToken>
changed: Array<ListViewToken>
viewableItems: Array<ListViewToken>
}) => void
persistentScrollbar?: boolean
progressViewOffset?: number
@@ -5679,8 +5686,8 @@ declare type ViewabilityConfig = {
declare type ViewabilityConfigCallbackPair = {
viewabilityConfig: ViewabilityConfig
onViewableItemsChanged: (info: {
changed: Array<ViewToken>
viewableItems: Array<ViewToken>
changed: Array<ListViewToken>
viewableItems: Array<ListViewToken>
}) => void
}
declare class ViewabilityHelper_default {
@@ -5705,10 +5712,10 @@ declare class ViewabilityHelper_default {
index: number,
isViewable: boolean,
props: CellMetricProps,
) => ViewToken,
) => ListViewToken,
onViewableItemsChanged: ($$PARAM_0$$: {
changed: Array<ViewToken>
viewableItems: Array<ViewToken>
changed: Array<ListViewToken>
viewableItems: Array<ListViewToken>
}) => void,
renderRange?: {
first: number
@@ -5793,13 +5800,6 @@ declare type ViewPropsIOS = {
}
declare type ViewStyle = ____ViewStyle_Internal
declare type ViewStyleProp = ____ViewStyleProp_Internal
declare type ViewToken = {
index: number | undefined
isViewable: boolean
item: any
key: string
section?: any
}
declare type VirtualizedList = typeof VirtualizedList
declare class VirtualizedList_default extends StateSafePureComponent_default<
VirtualizedListProps,
@@ -6013,8 +6013,8 @@ export {
EventSubscription, // b8d084aa
ExtendedExceptionData, // 5a6ccf5a
FilterFunction, // bf24c0e3
FlatList, // 714df8ad
FlatListProps, // e3e724ea
FlatList, // 4f1b407e
FlatListProps, // b225fb7a
FocusEvent, // 529b43eb
FontVariant, // 7c7558bb
GestureResponderEvent, // b466f6d6
@@ -6068,6 +6068,7 @@ export {
Linking, // 292de0a0
ListRenderItem, // b5353fd8
ListRenderItemInfo, // e8595b03
ListViewToken, // 833d3481
LogBox, // b58880c6
LogData, // 89af6d4c
MeasureInWindowOnSuccessCallback, // a285f598
@@ -6151,9 +6152,9 @@ export {
ScrollViewPropsIOS, // d83c9733
ScrollViewScrollToOptions, // 3313411e
SectionBase, // 0ccaedac
SectionList, // cc6dec0b
SectionList, // a1a4786b
SectionListData, // 1c80bb2e
SectionListProps, // 97fcf95a
SectionListProps, // 7fb5371e
SectionListRenderItem, // cffebb53
SectionListRenderItemInfo, // 946c2128
Separators, // 6a45f7e3
@@ -6218,9 +6219,9 @@ export {
ViewStyle, // c2db0e6e
VirtualViewMode, // 85a69ef6
VirtualizedList, // 4d513939
VirtualizedListProps, // 8efa6d8e
VirtualizedListProps, // be716140
VirtualizedSectionList, // 446ba0df
VirtualizedSectionListProps, // c5e64f83
VirtualizedSectionListProps, // a6899dfb
WrapperComponentProvider, // 9cf3844c
codegenNativeCommands, // e16d62f7
codegenNativeComponent, // ed4c8103
+157
View File
@@ -88,12 +88,169 @@ declare var navigator: Navigator;
// https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp
declare type DOMHighResTimeStamp = number;
type PerformanceEntryFilterOptions = {
entryType: string,
name: string,
...
};
// https://www.w3.org/TR/performance-timeline-2/
declare class PerformanceEntry {
duration: DOMHighResTimeStamp;
entryType: string;
name: string;
startTime: DOMHighResTimeStamp;
toJSON(): string;
}
// https://w3c.github.io/user-timing/#performancemark
declare class PerformanceMark extends PerformanceEntry {
constructor(name: string, markOptions?: PerformanceMarkOptions): void;
+detail: mixed;
}
// https://w3c.github.io/user-timing/#performancemeasure
declare class PerformanceMeasure extends PerformanceEntry {
+detail: mixed;
}
// https://w3c.github.io/server-timing/#the-performanceservertiming-interface
declare class PerformanceServerTiming {
description: string;
duration: DOMHighResTimeStamp;
name: string;
toJSON(): string;
}
// https://www.w3.org/TR/resource-timing-2/#sec-performanceresourcetiming
// https://w3c.github.io/server-timing/#extension-to-the-performanceresourcetiming-interface
declare class PerformanceResourceTiming extends PerformanceEntry {
connectEnd: number;
connectStart: number;
decodedBodySize: number;
domainLookupEnd: number;
domainLookupStart: number;
encodedBodySize: number;
fetchStart: number;
initiatorType: string;
nextHopProtocol: string;
redirectEnd: number;
redirectStart: number;
requestStart: number;
responseEnd: number;
responseStart: number;
secureConnectionStart: number;
serverTiming: Array<PerformanceServerTiming>;
transferSize: number;
workerStart: number;
}
// https://w3c.github.io/event-timing/#sec-performance-event-timing
declare class PerformanceEventTiming extends PerformanceEntry {
cancelable: boolean;
interactionId: number;
processingEnd: number;
processingStart: number;
target: ?Node;
}
// https://w3c.github.io/longtasks/#taskattributiontiming
declare class TaskAttributionTiming extends PerformanceEntry {
containerId: string;
containerName: string;
containerSrc: string;
containerType: string;
}
// https://w3c.github.io/longtasks/#sec-PerformanceLongTaskTiming
declare class PerformanceLongTaskTiming extends PerformanceEntry {
attribution: $ReadOnlyArray<TaskAttributionTiming>;
}
// https://www.w3.org/TR/user-timing/#extensions-performance-interface
declare type PerformanceMarkOptions = {
detail?: mixed,
startTime?: number,
};
declare type PerformanceMeasureOptions = {
detail?: mixed,
duration?: number,
end?: number | string,
start?: number | string,
};
type EventCountsForEachCallbackType =
| (() => void)
| ((value: number) => void)
| ((value: number, key: string) => void)
| ((value: number, key: string, map: Map<string, number>) => void);
// https://www.w3.org/TR/event-timing/#eventcounts
declare interface EventCounts {
entries(): Iterator<[string, number]>;
forEach(callback: EventCountsForEachCallbackType): void;
get(key: string): ?number;
has(key: string): boolean;
keys(): Iterator<string>;
size: number;
values(): Iterator<number>;
}
declare class Performance {
clearMarks(name?: string): void;
clearMeasures(name?: string): void;
eventCounts: EventCounts;
getEntries: (
options?: PerformanceEntryFilterOptions,
) => Array<PerformanceEntry>;
getEntriesByName: (name: string, type?: string) => Array<PerformanceEntry>;
getEntriesByType: (type: string) => Array<PerformanceEntry>;
mark(name: string, options?: PerformanceMarkOptions): PerformanceMark;
measure(
name: string,
startMarkOrOptions?: string | PerformanceMeasureOptions,
endMark?: string,
): PerformanceMeasure;
now: () => DOMHighResTimeStamp;
toJSON(): string;
}
declare var performance: Performance;
type PerformanceEntryList = Array<PerformanceEntry>;
declare interface PerformanceObserverEntryList {
getEntries(): PerformanceEntryList;
getEntriesByName(name: string, type: ?string): PerformanceEntryList;
getEntriesByType(type: string): PerformanceEntryList;
}
type PerformanceObserverInit = {
buffered?: boolean,
entryTypes?: Array<string>,
type?: string,
...
};
declare class PerformanceObserver {
constructor(
callback: (
entries: PerformanceObserverEntryList,
observer: PerformanceObserver,
) => mixed,
): void;
disconnect(): void;
observe(options: ?PerformanceObserverInit): void;
static supportedEntryTypes: Array<string>;
takeRecords(): PerformanceEntryList;
}
type FormDataEntryValue = string | File;
declare class FormData {
+1
View File
@@ -184,6 +184,7 @@ export {default as View} from './Libraries/Components/View/View';
export type {
ListRenderItemInfo,
ListRenderItem,
ListViewToken,
Separators,
VirtualizedListProps,
} from './Libraries/Lists/VirtualizedList';
-3
View File
@@ -31,13 +31,11 @@
"exports": {
".": {
"react-native-strict-api": "./types_generated/index.d.ts",
"react-native-strict-api-UNSAFE-ALLOW-SUBPATHS": "./types_generated/index.d.ts",
"types": "./types/index.d.ts",
"default": "./index.js"
},
"./*": {
"react-native-strict-api": null,
"react-native-strict-api-UNSAFE-ALLOW-SUBPATHS": "./types_generated/*.d.ts",
"types": "./*.d.ts",
"default": "./*.js"
},
@@ -52,7 +50,6 @@
"./scripts/*": "./scripts/*",
"./src/*": {
"react-native-strict-api": null,
"react-native-strict-api-UNSAFE-ALLOW-SUBPATHS": "./types_generated/src/*.d.ts",
"default": "./src/*.js"
},
"./types/*.d.ts": {
@@ -40,6 +40,12 @@ def list_native_modules!(config_command)
packages = config["dependencies"]
ios_project_root = Pathname.new(config["project"]["ios"]["sourceDir"])
react_native_path = Pathname.new(config["reactNativePath"])
codegen_output_path = ios_project_root.join("build/generated/autolinking/autolinking.json")
# Write autolinking react-native-config output to codegen folder
FileUtils.mkdir_p(File.dirname(codegen_output_path))
File.write(codegen_output_path, json)
found_pods = []
packages.each do |package_name, package|
@@ -87,7 +87,7 @@ class CodegenUtils
codegen_path = file_manager.join(ios_folder, codegen_dir)
return if !dir_manager.exist?(codegen_path)
FileUtils.rm_rf(dir_manager.glob("#{codegen_path}/*"))
FileUtils.rm_rf("#{codegen_path}")
base_provider_path = file_manager.join(rn_path, 'React', 'Fabric', 'RCTThirdPartyFabricComponentsProvider')
FileUtils.rm_rf("#{base_provider_path}.h")
FileUtils.rm_rf("#{base_provider_path}.mm")
@@ -86,10 +86,14 @@ function execute(
buildCodegenIfNeeded();
}
const reactNativeConfig = readReactNativeConfig(projectRoot);
const reactNativeConfig = readReactNativeConfig(
projectRoot,
baseOutputPath,
);
const codegenEnabledLibraries = findCodegenEnabledLibraries(
pkgJson,
projectRoot,
baseOutputPath,
reactNativeConfig,
);
@@ -97,15 +97,40 @@ function cleanupEmptyFilesAndFolders(filepath /*: string */) {
}
}
function readReactNativeConfig(projectRoot /*: string */) /*: $FlowFixMe */ {
const rnConfigFilePath = path.resolve(projectRoot, 'react-native.config.js');
function readGeneratedAutolinkingOutput(
baseOutputPath /*: string */,
) /*: $FlowFixMe */ {
// NOTE: Generated by scripts/cocoapods/autolinking.rb in list_native_modules (called by use_native_modules)
const autolinkingGeneratedPath = path.resolve(
baseOutputPath,
'build/generated/autolinking/autolinking.json',
);
if (fs.existsSync(autolinkingGeneratedPath)) {
// $FlowFixMe[unsupported-syntax]
return require(autolinkingGeneratedPath);
} else {
codegenLog(
`Could not find generated autolinking output at: ${autolinkingGeneratedPath}`,
);
return null;
}
}
if (!fs.existsSync(rnConfigFilePath)) {
function readReactNativeConfig(
projectRoot /*: string */,
baseOutputPath /*: string */,
) /*: $FlowFixMe */ {
const autolinkingOutput = readGeneratedAutolinkingOutput(baseOutputPath);
const rnConfigFilePath = path.resolve(projectRoot, 'react-native.config.js');
if (autolinkingOutput) {
return autolinkingOutput;
} else if (fs.existsSync(rnConfigFilePath)) {
// $FlowFixMe[unsupported-syntax]
return require(rnConfigFilePath);
} else {
codegenLog(`Could not find React Native config at: ${rnConfigFilePath}`);
return {};
}
// $FlowFixMe[unsupported-syntax]
return require(rnConfigFilePath);
}
/**
@@ -114,17 +139,23 @@ function readReactNativeConfig(projectRoot /*: string */) /*: $FlowFixMe */ {
function findCodegenEnabledLibraries(
pkgJson /*: $FlowFixMe */,
projectRoot /*: string */,
baseOutputPath /*: string */,
reactNativeConfig /*: $FlowFixMe */,
) /*: Array<$FlowFixMe> */ {
const projectLibraries = findProjectRootLibraries(pkgJson, projectRoot);
if (pkgJsonIncludesGeneratedCode(pkgJson)) {
return projectLibraries;
} else {
return [
...projectLibraries,
...findExternalLibraries(pkgJson, projectRoot),
const libraries = [...projectLibraries];
// If we ran autolinking, we shouldn't try to run our own "autolinking-like"
// library discovery
if (!readGeneratedAutolinkingOutput(baseOutputPath)) {
libraries.push(...findExternalLibraries(pkgJson, projectRoot));
}
libraries.push(
...findLibrariesFromReactNativeConfig(projectRoot, reactNativeConfig),
];
);
return libraries;
}
}
@@ -303,6 +303,17 @@ const definitions: FeatureFlagDefinitions = {
},
ossReleaseStage: 'none',
},
enableImagePrefetchingOnUiThreadAndroid: {
defaultValue: false,
metadata: {
dateAdded: '2025-09-02',
description:
'When enabled, Android will initiate image prefetch requested on ImageShadowNode::layout on the UI thread',
expectedReleaseValue: true,
purpose: 'experimentation',
},
ossReleaseStage: 'none',
},
enableImmediateUpdateModeForContentOffsetChanges: {
defaultValue: false,
metadata: {
@@ -387,17 +398,6 @@ const definitions: FeatureFlagDefinitions = {
},
ossReleaseStage: 'none',
},
enableNewBackgroundAndBorderDrawables: {
defaultValue: true,
metadata: {
dateAdded: '2024-09-24',
description:
'Use BackgroundDrawable and BorderDrawable instead of CSSBackgroundDrawable',
expectedReleaseValue: true,
purpose: 'experimentation',
},
ossReleaseStage: 'none',
},
enablePreparedTextLayout: {
defaultValue: false,
metadata: {
@@ -591,17 +591,6 @@ const definitions: FeatureFlagDefinitions = {
},
ossReleaseStage: 'experimental',
},
releaseImageDataWhenConsumed: {
defaultValue: false,
metadata: {
dateAdded: '2025-07-10',
description:
'Releases the cached image data when it is consumed by the observers.',
expectedReleaseValue: true,
purpose: 'experimentation',
},
ossReleaseStage: 'none',
},
shouldPressibilityUseW3CPointerEventsForHover: {
defaultValue: false,
metadata: {
@@ -839,6 +828,16 @@ const definitions: FeatureFlagDefinitions = {
},
ossReleaseStage: 'stable',
},
enableVirtualViewExperimental: {
defaultValue: false,
metadata: {
dateAdded: '2025-08-29',
description: 'Enables the experimental version of `VirtualView`.',
expectedReleaseValue: true,
purpose: 'experimentation',
},
ossReleaseStage: 'none',
},
fixVirtualizeListCollapseWindowSize: {
defaultValue: false,
metadata: {
+4 -2
View File
@@ -10,7 +10,7 @@
'use strict';
const {execSync} = require('child_process');
const {spawnSync} = require('child_process');
const fs = require('fs');
const yargs = require('yargs');
@@ -67,7 +67,9 @@ function replaceRNCoreConfiguration(
fs.mkdirSync(finalLocation, {recursive: true});
console.log('Extracting the tarball', tarballURLPath);
execSync(`tar -xf ${tarballURLPath} -C ${finalLocation}`);
spawnSync('tar', ['-xf', tarballURLPath, '-C', finalLocation], {
stdio: 'inherit',
});
}
function updateLastBuildConfiguration(configuration /*: string */) {
@@ -10,7 +10,7 @@
'use strict';
const {execSync} = require('child_process');
const {spawnSync} = require('child_process');
const fs = require('fs');
const yargs = require('yargs');
@@ -62,7 +62,9 @@ function replaceHermesConfiguration(configuration, version, podsRoot) {
fs.mkdirSync(finalLocation, {recursive: true});
console.log('Extracting the tarball');
execSync(`tar -xf ${tarballURLPath} -C ${finalLocation}`);
spawnSync('tar', ['-xf', tarballURLPath, '-C', finalLocation], {
stdio: 'inherit',
});
}
function updateLastBuildConfiguration(configuration) {
@@ -29,3 +29,12 @@ include(":packages:react-native:ReactAndroid:hermes-engine")
project(":packages:react-native:ReactAndroid:hermes-engine").projectDir =
file("ReactAndroid/hermes-engine/")
// Since Gradle 9.0, all the projects in the path must have an existing folder.
// As we build :packages:react-native:ReactAndroid, we need to declare the folders
// for :packages and :packages:react-native as well as otherwise the build from
// source will fail with a missing folder exception.
project(":packages").projectDir = file("/tmp")
project(":packages:react-native").projectDir = file("/tmp")
@@ -16,7 +16,7 @@ import type {NativeModeChangeEvent} from './VirtualViewNativeComponent';
import StyleSheet from '../../../../Libraries/StyleSheet/StyleSheet';
import * as ReactNativeFeatureFlags from '../../featureflags/ReactNativeFeatureFlags';
import VirtualViewExperimentalNativeComponent from './VirtualViewExperimentalNativeComponent';
import VirtualViewNativeComponent from './VirtualViewNativeComponent';
import VirtualViewClassicNativeComponent from './VirtualViewNativeComponent';
import nullthrows from 'nullthrows';
import * as React from 'react';
// $FlowFixMe[missing-export]
@@ -49,8 +49,14 @@ export type ModeChangeEvent = $ReadOnly<{
target: HostInstance,
}>;
const VirtualViewNativeComponent: typeof VirtualViewClassicNativeComponent =
ReactNativeFeatureFlags.enableVirtualViewExperimental()
? VirtualViewExperimentalNativeComponent
: VirtualViewClassicNativeComponent;
type VirtualViewComponent = component(
children?: React.Node,
hiddenStyle?: (targetRect: Rect) => ViewStyleProp,
nativeID?: string,
ref?: ?React.RefSetter<React.ElementRef<typeof VirtualViewNativeComponent>>,
style?: ?ViewStyleProp,
@@ -58,23 +64,21 @@ type VirtualViewComponent = component(
removeClippedSubviews?: boolean,
);
type HiddenHeight = number;
const NotHidden = null;
type HiddenStyle = Exclude<ViewStyleProp, typeof NotHidden>;
type State = HiddenHeight | typeof NotHidden;
type State = HiddenStyle | typeof NotHidden;
function createVirtualView(
initialState: State,
experimental: boolean,
): VirtualViewComponent {
function defaultHiddenStyle(targetRect: Rect): ViewStyleProp {
return {minHeight: targetRect.height, minWidth: targetRect.width};
}
function createVirtualView(initialState: State): VirtualViewComponent {
const initialHidden = initialState !== NotHidden;
const NativeComponent = experimental
? VirtualViewExperimentalNativeComponent
: VirtualViewNativeComponent;
component VirtualView(
children?: React.Node,
hiddenStyle: (targetRect: Rect) => ViewStyleProp = defaultHiddenStyle,
nativeID?: string,
ref?: ?React.RefSetter<React.ElementRef<typeof VirtualViewNativeComponent>>,
style?: ?ViewStyleProp,
@@ -114,9 +118,8 @@ function createVirtualView(
});
}
VirtualViewMode.Hidden => {
const {height} = event.nativeEvent.targetRect;
startTransition(() => {
setState(height as HiddenHeight);
setState(hiddenStyle(event.nativeEvent.targetRect) ?? {});
emitModeChange?.();
});
}
@@ -124,7 +127,7 @@ function createVirtualView(
};
return (
<NativeComponent
<VirtualViewNativeComponent
initialHidden={initialHidden}
nativeID={nativeID}
ref={ref}
@@ -136,9 +139,7 @@ function createVirtualView(
}
style={
isHidden
? StyleSheet.compose(style, {
height: Math.abs(nullthrows(state) as HiddenHeight),
})
? StyleSheet.compose(style, nullthrows(state) as HiddenStyle)
: style
}
onModeChange={handleModeChange}>
@@ -153,24 +154,18 @@ function createVirtualView(
'no-activity' | _ => isHidden ? null : children,
}
}
</NativeComponent>
</VirtualViewNativeComponent>
);
}
return VirtualView;
}
export default createVirtualView(NotHidden, false) as VirtualViewComponent;
export const VirtualViewExperimental = createVirtualView(
NotHidden,
true,
) as VirtualViewComponent;
export default createVirtualView(NotHidden) as VirtualViewComponent;
export function createHiddenVirtualView(
height: number,
experimental: boolean,
style: ViewStyleProp,
): VirtualViewComponent {
return createVirtualView(height as HiddenHeight, experimental);
return createVirtualView((style ?? {}) as HiddenStyle);
}
export const _logs: {states?: Array<State>} = {};
@@ -119,19 +119,19 @@ describe('mode changes', () => {
});
describe('styles', () => {
test('does not set height when visible', () => {
test('does not set styles when visible', () => {
const root = Fantom.createRoot();
Fantom.runTask(() => {
root.render(<VirtualView />);
});
expect(root.getRenderedOutput({props: ['height']}).toJSX()).toEqual(
<rn-virtualView />,
);
expect(
root.getRenderedOutput({props: ['minHeight', 'minWidth']}).toJSX(),
).toEqual(<rn-virtualView />);
});
test('does not set height when prerendered', () => {
test('does not set styles when prerendered', () => {
const root = Fantom.createRoot();
const viewRef = createRef<React.RefOf<VirtualView>>();
@@ -141,12 +141,12 @@ describe('styles', () => {
dispatchModeChangeEvent(viewRef.current, VirtualViewMode.Prerender);
expect(root.getRenderedOutput({props: ['height']}).toJSX()).toEqual(
<rn-virtualView />,
);
expect(
root.getRenderedOutput({props: ['minHeight', 'minWidth']}).toJSX(),
).toEqual(<rn-virtualView />);
});
test('sets height when hidden', () => {
test('sets styles when hidden', () => {
const root = Fantom.createRoot();
const viewRef = createRef<React.RefOf<VirtualView>>();
@@ -156,9 +156,9 @@ describe('styles', () => {
dispatchModeChangeEvent(viewRef.current, VirtualViewMode.Hidden);
expect(root.getRenderedOutput({props: ['height']}).toJSX()).toEqual(
<rn-virtualView height="100.000000" />,
);
expect(
root.getRenderedOutput({props: ['minHeight', 'minWidth']}).toJSX(),
).toEqual(<rn-virtualView minHeight="100.000000" minWidth="100.000000" />);
});
});
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<85a053d6a79240a7b4e181d3054ecfd3>>
* @generated SignedSource<<7de65fc90fa1275f89375fd214b94172>>
* @flow strict
* @noformat
*/
@@ -34,6 +34,7 @@ export type ReactNativeFeatureFlagsJsOnly = $ReadOnly<{
deferFlatListFocusChangeRenderUpdate: Getter<boolean>,
disableMaintainVisibleContentPosition: Getter<boolean>,
enableAccessToHostTreeInFabric: Getter<boolean>,
enableVirtualViewExperimental: Getter<boolean>,
fixVirtualizeListCollapseWindowSize: Getter<boolean>,
isLayoutAnimationEnabled: Getter<boolean>,
reduceDefaultPropsInImage: Getter<boolean>,
@@ -73,6 +74,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{
enableIOSTextBaselineOffsetPerLine: Getter<boolean>,
enableIOSViewClipToPaddingBox: Getter<boolean>,
enableImagePrefetchingAndroid: Getter<boolean>,
enableImagePrefetchingOnUiThreadAndroid: Getter<boolean>,
enableImmediateUpdateModeForContentOffsetChanges: Getter<boolean>,
enableInteropViewManagerClassLookUpOptimizationIOS: Getter<boolean>,
enableLayoutAnimationsOnAndroid: Getter<boolean>,
@@ -81,7 +83,6 @@ export type ReactNativeFeatureFlags = $ReadOnly<{
enableModuleArgumentNSNullConversionIOS: Getter<boolean>,
enableNativeCSSParsing: Getter<boolean>,
enableNetworkEventReporting: Getter<boolean>,
enableNewBackgroundAndBorderDrawables: Getter<boolean>,
enablePreparedTextLayout: Getter<boolean>,
enablePropsUpdateReconciliationAndroid: Getter<boolean>,
enableResourceTimingAPI: Getter<boolean>,
@@ -100,7 +101,6 @@ export type ReactNativeFeatureFlags = $ReadOnly<{
perfMonitorV2Enabled: Getter<boolean>,
preparedTextCacheSize: Getter<number>,
preventShadowTreeCommitExhaustion: Getter<boolean>,
releaseImageDataWhenConsumed: Getter<boolean>,
shouldPressibilityUseW3CPointerEventsForHover: Getter<boolean>,
skipActivityIdentityAssertionOnHostPause: Getter<boolean>,
sweepActiveTouchOnChildNativeGesturesAndroid: Getter<boolean>,
@@ -150,6 +150,11 @@ export const disableMaintainVisibleContentPosition: Getter<boolean> = createJava
*/
export const enableAccessToHostTreeInFabric: Getter<boolean> = createJavaScriptFlagGetter('enableAccessToHostTreeInFabric', true);
/**
* Enables the experimental version of `VirtualView`.
*/
export const enableVirtualViewExperimental: Getter<boolean> = createJavaScriptFlagGetter('enableVirtualViewExperimental', false);
/**
* Fixing an edge case where the current window size is not properly calculated with fast scrolling. Window size collapsed to 1 element even if windowSize more than the current amount of elements
*/
@@ -290,6 +295,10 @@ export const enableIOSViewClipToPaddingBox: Getter<boolean> = createNativeFlagGe
* When enabled, Android will build and initiate image prefetch requests on ImageShadowNode::layout
*/
export const enableImagePrefetchingAndroid: Getter<boolean> = createNativeFlagGetter('enableImagePrefetchingAndroid', false);
/**
* When enabled, Android will initiate image prefetch requested on ImageShadowNode::layout on the UI thread
*/
export const enableImagePrefetchingOnUiThreadAndroid: Getter<boolean> = createNativeFlagGetter('enableImagePrefetchingOnUiThreadAndroid', false);
/**
* Dispatches state updates for content offset changes synchronously on the main thread.
*/
@@ -322,10 +331,6 @@ export const enableNativeCSSParsing: Getter<boolean> = createNativeFlagGetter('e
* Enable network event reporting hooks in each native platform through `NetworkReporter`. This flag should be combined with `enableResourceTimingAPI` and `fuseboxNetworkInspectionEnabled` to enable end-to-end reporting behaviour via the Web Performance API and CDP debugging respectively.
*/
export const enableNetworkEventReporting: Getter<boolean> = createNativeFlagGetter('enableNetworkEventReporting', false);
/**
* Use BackgroundDrawable and BorderDrawable instead of CSSBackgroundDrawable
*/
export const enableNewBackgroundAndBorderDrawables: Getter<boolean> = createNativeFlagGetter('enableNewBackgroundAndBorderDrawables', true);
/**
* Enables caching text layout artifacts for later reuse
*/
@@ -398,10 +403,6 @@ export const preparedTextCacheSize: Getter<number> = createNativeFlagGetter('pre
* Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again.
*/
export const preventShadowTreeCommitExhaustion: Getter<boolean> = createNativeFlagGetter('preventShadowTreeCommitExhaustion', false);
/**
* Releases the cached image data when it is consumed by the observers.
*/
export const releaseImageDataWhenConsumed: Getter<boolean> = createNativeFlagGetter('releaseImageDataWhenConsumed', false);
/**
* Function used to enable / disable Pressibility from using W3C Pointer Events for its hover callbacks
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<da22f4c43e3bdcd999e3dd1dd5896c63>>
* @generated SignedSource<<1e6f17de0ebb06a085d4cc563df1e32b>>
* @flow strict
* @noformat
*/
@@ -49,6 +49,7 @@ export interface Spec extends TurboModule {
+enableIOSTextBaselineOffsetPerLine?: () => boolean;
+enableIOSViewClipToPaddingBox?: () => boolean;
+enableImagePrefetchingAndroid?: () => boolean;
+enableImagePrefetchingOnUiThreadAndroid?: () => boolean;
+enableImmediateUpdateModeForContentOffsetChanges?: () => boolean;
+enableInteropViewManagerClassLookUpOptimizationIOS?: () => boolean;
+enableLayoutAnimationsOnAndroid?: () => boolean;
@@ -57,7 +58,6 @@ export interface Spec extends TurboModule {
+enableModuleArgumentNSNullConversionIOS?: () => boolean;
+enableNativeCSSParsing?: () => boolean;
+enableNetworkEventReporting?: () => boolean;
+enableNewBackgroundAndBorderDrawables?: () => boolean;
+enablePreparedTextLayout?: () => boolean;
+enablePropsUpdateReconciliationAndroid?: () => boolean;
+enableResourceTimingAPI?: () => boolean;
@@ -76,7 +76,6 @@ export interface Spec extends TurboModule {
+perfMonitorV2Enabled?: () => boolean;
+preparedTextCacheSize?: () => number;
+preventShadowTreeCommitExhaustion?: () => boolean;
+releaseImageDataWhenConsumed?: () => boolean;
+shouldPressibilityUseW3CPointerEventsForHover?: () => boolean;
+skipActivityIdentityAssertionOnHostPause?: () => boolean;
+sweepActiveTouchOnChildNativeGesturesAndroid?: () => boolean;
@@ -12,13 +12,62 @@ import {polyfillGlobal} from '../../../Libraries/Utilities/PolyfillFunctions';
let initialized = false;
export default function setUpPerformanceObserver() {
export default function setUpPerformanceModern() {
if (initialized) {
return;
}
initialized = true;
const Performance = require('../webapis/performance/Performance').default;
// We don't use `polyfillGlobal` to define this lazily because the
// `performance` object is always accessed.
// $FlowExpectedError[cannot-write]
global.performance = new Performance();
polyfillGlobal(
'EventCounts',
() => require('../webapis/performance/EventTiming').EventCounts_public,
);
polyfillGlobal(
'Performance',
() => require('../webapis/performance/Performance').Performance_public,
);
polyfillGlobal(
'PerformanceEntry',
() =>
require('../webapis/performance/PerformanceEntry')
.PerformanceEntry_public,
);
polyfillGlobal(
'PerformanceEventTiming',
() =>
require('../webapis/performance/EventTiming')
.PerformanceEventTiming_public,
);
polyfillGlobal(
'PerformanceLongTaskTiming',
() =>
require('../webapis/performance/LongTasks')
.PerformanceLongTaskTiming_public,
);
polyfillGlobal(
'PerformanceMark',
() => require('../webapis/performance/UserTiming').PerformanceMark,
);
polyfillGlobal(
'PerformanceMeasure',
() =>
require('../webapis/performance/UserTiming').PerformanceMeasure_public,
);
polyfillGlobal(
'PerformanceObserver',
() =>
@@ -29,43 +78,19 @@ export default function setUpPerformanceObserver() {
'PerformanceObserverEntryList',
() =>
require('../webapis/performance/PerformanceObserver')
.PerformanceObserverEntryList,
);
polyfillGlobal(
'PerformanceEntry',
() => require('../webapis/performance/PerformanceEntry').PerformanceEntry,
);
polyfillGlobal(
'PerformanceMark',
() => require('../webapis/performance/UserTiming').PerformanceMark,
);
polyfillGlobal(
'PerformanceMeasure',
() => require('../webapis/performance/UserTiming').PerformanceMeasure,
);
polyfillGlobal(
'PerformanceEventTiming',
() => require('../webapis/performance/EventTiming').PerformanceEventTiming,
.PerformanceObserverEntryList_public,
);
polyfillGlobal(
'PerformanceResourceTiming',
() =>
require('../webapis/performance/ResourceTiming')
.PerformanceResourceTiming,
.PerformanceResourceTiming_public,
);
polyfillGlobal(
'TaskAttributionTiming',
() => require('../webapis/performance/LongTasks').TaskAttributionTiming,
);
polyfillGlobal(
'PerformanceLongTaskTiming',
() => require('../webapis/performance/LongTasks').PerformanceLongTaskTiming,
() =>
require('../webapis/performance/LongTasks').TaskAttributionTiming_public,
);
}
@@ -9,9 +9,9 @@
*/
// flowlint unsafe-getters-setters:off
import type {
DOMHighResTimeStamp,
PerformanceEntryInit,
PerformanceEntryJSON,
} from './PerformanceEntry';
@@ -29,25 +29,20 @@ export type PerformanceEventTimingJSON = {
...
};
export interface PerformanceEventTimingInit extends PerformanceEntryInit {
+processingStart?: DOMHighResTimeStamp;
+processingEnd?: DOMHighResTimeStamp;
+interactionId?: number;
}
export class PerformanceEventTiming extends PerformanceEntry {
#processingStart: DOMHighResTimeStamp;
#processingEnd: DOMHighResTimeStamp;
#interactionId: number;
constructor(init: {
name: string,
startTime?: DOMHighResTimeStamp,
duration?: DOMHighResTimeStamp,
processingStart?: DOMHighResTimeStamp,
processingEnd?: DOMHighResTimeStamp,
interactionId?: number,
}) {
super({
name: init.name,
entryType: 'event',
startTime: init.startTime ?? 0,
duration: init.duration ?? 0,
});
constructor(init: PerformanceEventTimingInit) {
super('event', init);
this.#processingStart = init.processingStart ?? 0;
this.#processingEnd = init.processingEnd ?? 0;
this.#interactionId = init.interactionId ?? 0;
@@ -75,6 +70,18 @@ export class PerformanceEventTiming extends PerformanceEntry {
}
}
export const PerformanceEventTiming_public: typeof PerformanceEventTiming =
/* eslint-disable no-shadow */
// $FlowExpectedError[incompatible-type]
function PerformanceEventTiming() {
throw new TypeError(
"Failed to construct 'PerformanceEventTiming': Illegal constructor",
);
};
// $FlowExpectedError[prop-missing]
PerformanceEventTiming_public.prototype = PerformanceEventTiming.prototype;
type EventCountsForEachCallbackType =
| (() => void)
| ((value: number) => void)
@@ -139,3 +146,15 @@ export class EventCounts {
return getCachedEventCounts().values();
}
}
export const EventCounts_public: typeof EventCounts =
/* eslint-disable no-shadow */
// $FlowExpectedError[incompatible-type]
function EventCounts() {
throw new TypeError(
"Failed to construct 'EventCounts': Illegal constructor",
);
};
// $FlowExpectedError[prop-missing]
EventCounts_public.prototype = EventCounts.prototype;
@@ -9,8 +9,10 @@
*/
// flowlint unsafe-getters-setters:off
import type {PerformanceEntryJSON} from './PerformanceEntry';
import type {
PerformanceEntryInit,
PerformanceEntryJSON,
} from './PerformanceEntry';
import {PerformanceEntry} from './PerformanceEntry';
@@ -22,10 +24,28 @@ export type PerformanceLongTaskTimingJSON = {
export class TaskAttributionTiming extends PerformanceEntry {}
export const TaskAttributionTiming_public: typeof TaskAttributionTiming =
/* eslint-disable no-shadow */
// $FlowExpectedError[incompatible-type]
function TaskAttributionTiming() {
throw new TypeError(
"Failed to construct 'TaskAttributionTiming': Illegal constructor",
);
};
// $FlowExpectedError[prop-missing]
TaskAttributionTiming_public.prototype = TaskAttributionTiming.prototype;
const EMPTY_ATTRIBUTION: $ReadOnlyArray<TaskAttributionTiming> =
Object.preventExtensions([]);
export interface PerformanceLongTaskTimingInit extends PerformanceEntryInit {}
export class PerformanceLongTaskTiming extends PerformanceEntry {
constructor(init: PerformanceEntryInit) {
super('longtask', init);
}
get attribution(): $ReadOnlyArray<TaskAttributionTiming> {
return EMPTY_ATTRIBUTION;
}
@@ -37,3 +57,16 @@ export class PerformanceLongTaskTiming extends PerformanceEntry {
};
}
}
export const PerformanceLongTaskTiming_public: typeof PerformanceLongTaskTiming =
/* eslint-disable no-shadow */
// $FlowExpectedError[incompatible-type]
function PerformanceLongTaskTiming() {
throw new TypeError(
"Failed to construct 'PerformanceLongTaskTiming': Illegal constructor",
);
};
// $FlowExpectedError[prop-missing]
PerformanceLongTaskTiming_public.prototype =
PerformanceLongTaskTiming.prototype;
@@ -64,12 +64,13 @@ const cachedGetMarkTime = NativePerformance.getMarkTime;
const cachedNativeClearMarks = NativePerformance.clearMarks;
const cachedNativeClearMeasures = NativePerformance.clearMeasures;
const MARK_OPTIONS_REUSABLE_OBJECT: {...PerformanceMarkOptions} = {
const MARK_OPTIONS_REUSABLE_OBJECT: PerformanceMarkOptions = {
startTime: 0,
detail: undefined,
};
const MEASURE_OPTIONS_REUSABLE_OBJECT: {...PerformanceMeasureInit} = {
const MEASURE_OPTIONS_REUSABLE_OBJECT: PerformanceMeasureInit = {
name: '',
startTime: 0,
duration: 0,
detail: undefined,
@@ -189,7 +190,9 @@ export default class Performance {
resolvedDetail = structuredClone(detail);
}
// $FlowExpectedError[cannot-write]
MARK_OPTIONS_REUSABLE_OBJECT.startTime = resolvedStartTime;
// $FlowExpectedError[cannot-write]
MARK_OPTIONS_REUSABLE_OBJECT.detail = resolvedDetail;
const entry = new PerformanceMark(
@@ -367,14 +370,16 @@ export default class Performance {
}
}
// $FlowExpectedError[cannot-write]
MEASURE_OPTIONS_REUSABLE_OBJECT.name = resolvedMeasureName;
// $FlowExpectedError[cannot-write]
MEASURE_OPTIONS_REUSABLE_OBJECT.startTime = resolvedStartTime;
// $FlowExpectedError[cannot-write]
MEASURE_OPTIONS_REUSABLE_OBJECT.duration = resolvedDuration;
// $FlowExpectedError[cannot-write]
MEASURE_OPTIONS_REUSABLE_OBJECT.detail = resolvedDetail;
const entry = new PerformanceMeasure(
resolvedMeasureName,
MEASURE_OPTIONS_REUSABLE_OBJECT,
);
const entry = new PerformanceMeasure(MEASURE_OPTIONS_REUSABLE_OBJECT);
cachedReportMeasure(
resolvedMeasureName,
@@ -438,4 +443,16 @@ export default class Performance {
}
}
export const Performance_public: typeof Performance =
/* eslint-disable no-shadow */
// $FlowExpectedError[incompatible-type]
function Performance() {
throw new TypeError(
"Failed to construct 'Performance': Illegal constructor",
);
};
// $FlowExpectedError[prop-missing]
Performance_public.prototype = Performance.prototype;
setPlatformObject(Performance);
@@ -28,24 +28,25 @@ export type PerformanceEntryJSON = {
...
};
export interface PerformanceEntryInit {
+name: string;
+startTime: DOMHighResTimeStamp;
+duration: DOMHighResTimeStamp;
}
export class PerformanceEntry {
// We don't use private fields because they're significantly slower to
// initialize on construction and to access.
// We also need these to be protected so they can be initialized in subclasses
// where we avoid calling `super()` for performance reasons.
__name: string;
__entryType: PerformanceEntryType;
__name: string;
__startTime: DOMHighResTimeStamp;
__duration: DOMHighResTimeStamp;
constructor(init: {
name: string,
entryType: PerformanceEntryType,
startTime: DOMHighResTimeStamp,
duration: DOMHighResTimeStamp,
}) {
constructor(entryType: PerformanceEntryType, init: PerformanceEntryInit) {
this.__entryType = entryType;
this.__name = init.name;
this.__entryType = init.entryType;
this.__startTime = init.startTime;
this.__duration = init.duration;
}
@@ -76,6 +77,18 @@ export class PerformanceEntry {
}
}
export const PerformanceEntry_public: typeof PerformanceEntry =
/* eslint-disable no-shadow */
// $FlowExpectedError[incompatible-type]
function PerformanceEntry() {
throw new TypeError(
"Failed to construct 'PerformanceEntry': Illegal constructor",
);
};
// $FlowExpectedError[prop-missing]
PerformanceEntry_public.prototype = PerformanceEntry.prototype;
setPlatformObject(PerformanceEntry);
export type PerformanceEntryList = $ReadOnlyArray<PerformanceEntry>;
@@ -57,6 +57,19 @@ export class PerformanceObserverEntryList {
}
}
export const PerformanceObserverEntryList_public: typeof PerformanceObserverEntryList =
/* eslint-disable no-shadow */
// $FlowExpectedError[incompatible-type]
function PerformanceObserverEntryList() {
throw new TypeError(
"Failed to construct 'PerformanceObserverEntryList': Illegal constructor",
);
};
// $FlowExpectedError[prop-missing]
PerformanceObserverEntryList_public.prototype =
PerformanceObserverEntryList.prototype;
export type PerformanceObserverCallbackOptions = {
droppedEntriesCount: number,
};
@@ -145,6 +158,22 @@ export class PerformanceObserver {
NativePerformance.disconnect(this.#nativeObserverHandle);
}
takeRecords(): PerformanceEntryList {
let entries: PerformanceEntryList = [];
if (this.#nativeObserverHandle != null) {
const rawEntries = NativePerformance.takeRecords(
this.#nativeObserverHandle,
true,
);
if (rawEntries && rawEntries.length > 0) {
entries = rawEntries.map(rawToPerformanceEntry);
}
}
return entries;
}
#createNativeObserver(): OpaqueNativeObserverHandle | null {
this.#calledAtLeastOnce = false;
@@ -154,7 +183,7 @@ export class PerformanceObserver {
observerHandle,
true, // sort records
);
if (!rawEntries) {
if (!rawEntries || rawEntries.length === 0) {
return;
}
@@ -29,6 +29,19 @@ export type PerformanceResourceTimingJSON = {
...
};
export interface PerformanceResourceTimingInit {
+name: string;
+startTime: DOMHighResTimeStamp;
+duration: DOMHighResTimeStamp;
+fetchStart: DOMHighResTimeStamp;
+requestStart: DOMHighResTimeStamp;
+connectStart: DOMHighResTimeStamp;
+connectEnd: DOMHighResTimeStamp;
+responseStart: DOMHighResTimeStamp;
+responseEnd: DOMHighResTimeStamp;
+responseStatus?: number;
}
export class PerformanceResourceTiming extends PerformanceEntry {
#fetchStart: DOMHighResTimeStamp;
#requestStart: DOMHighResTimeStamp;
@@ -38,24 +51,9 @@ export class PerformanceResourceTiming extends PerformanceEntry {
#responseEnd: DOMHighResTimeStamp;
#responseStatus: ?number;
constructor(init: {
name: string,
startTime: DOMHighResTimeStamp,
duration: DOMHighResTimeStamp,
fetchStart: DOMHighResTimeStamp,
requestStart: DOMHighResTimeStamp,
connectStart: DOMHighResTimeStamp,
connectEnd: DOMHighResTimeStamp,
responseStart: DOMHighResTimeStamp,
responseEnd: DOMHighResTimeStamp,
responseStatus?: number,
}) {
super({
name: init.name,
entryType: 'resource',
startTime: init.startTime,
duration: init.duration,
});
constructor(init: PerformanceResourceTimingInit) {
super('resource', init);
this.#fetchStart = init.fetchStart;
this.#requestStart = init.requestStart;
this.#connectStart = init.connectStart;
@@ -106,3 +104,16 @@ export class PerformanceResourceTiming extends PerformanceEntry {
};
}
}
export const PerformanceResourceTiming_public: typeof PerformanceResourceTiming =
/* eslint-disable no-shadow */
// $FlowExpectedError[incompatible-type]
function PerformanceResourceTiming() {
throw new TypeError(
"Failed to construct 'PerformanceResourceTiming': Illegal constructor",
);
};
// $FlowExpectedError[prop-missing]
PerformanceResourceTiming_public.prototype =
PerformanceResourceTiming.prototype;
@@ -9,8 +9,10 @@
*/
// flowlint unsafe-getters-setters:off
import type {DOMHighResTimeStamp} from './PerformanceEntry';
import type {
DOMHighResTimeStamp,
PerformanceEntryInit,
} from './PerformanceEntry';
import type {
ExtensionMarkerPayload,
ExtensionTrackEntryPayload,
@@ -25,18 +27,16 @@ export type DetailType =
// but we'll use it as documentation for how to use the extensibility API.
| {devtools?: ExtensionMarkerPayload | ExtensionTrackEntryPayload, ...};
export type PerformanceMarkOptions = $ReadOnly<{
detail?: DetailType,
startTime?: DOMHighResTimeStamp,
}>;
export interface PerformanceMarkOptions {
+detail?: DetailType;
+startTime?: DOMHighResTimeStamp;
}
export type TimeStampOrName = DOMHighResTimeStamp | string;
export type PerformanceMeasureInit = $ReadOnly<{
detail?: DetailType,
startTime: DOMHighResTimeStamp,
duration: DOMHighResTimeStamp,
}>;
export interface PerformanceMeasureInit extends PerformanceEntryInit {
+detail?: DetailType;
}
class PerformanceMarkTemplate extends PerformanceEntry {
// We don't use private fields because they're significantly slower to
@@ -45,9 +45,8 @@ class PerformanceMarkTemplate extends PerformanceEntry {
// This constructor isn't really used. See `PerformanceMark` below.
constructor(markName: string, markOptions?: PerformanceMarkOptions) {
super({
super('mark', {
name: markName,
entryType: 'mark',
startTime: markOptions?.startTime ?? getCurrentTimeStamp(),
duration: 0,
});
@@ -72,8 +71,8 @@ export const PerformanceMark: typeof PerformanceMarkTemplate =
markName: string,
markOptions?: PerformanceMarkOptions,
) {
this.__name = markName;
this.__entryType = 'mark';
this.__name = markName;
this.__startTime = markOptions?.startTime ?? getCurrentTimeStamp();
this.__duration = 0;
@@ -89,15 +88,10 @@ class PerformanceMeasureTemplate extends PerformanceEntry {
__detail: DetailType;
// This constructor isn't really used. See `PerformanceMeasure` below.
constructor(measureName: string, measureOptions: PerformanceMeasureInit) {
super({
name: measureName,
entryType: 'measure',
startTime: measureOptions.startTime,
duration: measureOptions.duration,
});
constructor(init: PerformanceMeasureInit) {
super('measure', init);
this.__detail = measureOptions?.detail ?? null;
this.__detail = init?.detail ?? null;
}
get detail(): DetailType {
@@ -110,16 +104,27 @@ export const PerformanceMeasure: typeof PerformanceMeasureTemplate =
// $FlowExpectedError[incompatible-type]
function PerformanceMeasure(
this: PerformanceMeasureTemplate,
measureName: string,
measureOptions: PerformanceMeasureInit,
init: PerformanceMeasureInit,
) {
this.__name = measureName;
this.__entryType = 'measure';
this.__startTime = measureOptions.startTime;
this.__duration = measureOptions.duration;
this.__name = init.name;
this.__startTime = init.startTime;
this.__duration = init.duration;
this.__detail = measureOptions.detail ?? null;
this.__detail = init.detail ?? null;
};
// $FlowExpectedError[prop-missing]
PerformanceMeasure.prototype = PerformanceMeasureTemplate.prototype;
export const PerformanceMeasure_public: typeof PerformanceMeasure =
/* eslint-disable no-shadow */
// $FlowExpectedError[incompatible-type]
function PerformanceMeasure() {
throw new TypeError(
"Failed to construct 'PerformanceMeasure': Illegal constructor",
);
};
// $FlowExpectedError[prop-missing]
PerformanceMeasure_public.prototype = PerformanceMeasure.prototype;
@@ -10,24 +10,14 @@
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';
import type Performance from 'react-native/src/private/webapis/performance/Performance';
import type {PerformanceObserverEntryList} from 'react-native/src/private/webapis/performance/PerformanceObserver';
import MaybeNativePerformance from '../specs/NativePerformance';
import * as Fantom from '@react-native/fantom';
import nullthrows from 'nullthrows';
import {useState} from 'react';
import {Text, View} from 'react-native';
import setUpPerformanceObserver from 'react-native/src/private/setup/setUpPerformanceObserver';
import {PerformanceEventTiming} from 'react-native/src/private/webapis/performance/EventTiming';
import {PerformanceObserver} from 'react-native/src/private/webapis/performance/PerformanceObserver';
const NativePerformance = nullthrows(MaybeNativePerformance);
setUpPerformanceObserver();
declare var performance: Performance;
function sleep(ms: number) {
const end = performance.now() + ms;
while (performance.now() < end) {}
@@ -251,6 +241,21 @@ describe('Event Timing API', () => {
expect([...performance.eventCounts.values()]).toEqual([1, 1, 3]);
});
it('does NOT allow creating instances of PerformanceEventTiming directly', () => {
expect(() => {
return new PerformanceEventTiming();
}).toThrow(
"Failed to construct 'PerformanceEventTiming': Illegal constructor",
);
});
it('does NOT allow creating instances of EventCounts directly', () => {
expect(() => {
// $FlowExpectedError[cannot-resolve-name]
return new EventCounts();
}).toThrow("Failed to construct 'EventCounts': Illegal constructor");
});
describe('durationThreshold option', () => {
it('works when used with `type`', () => {
const callback = jest.fn();
@@ -10,17 +10,9 @@
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';
import type {
PerformanceObserverCallbackOptions,
PerformanceObserverEntryList,
} from 'react-native/src/private/webapis/performance/PerformanceObserver';
import type {PerformanceObserverCallbackOptions} from '../PerformanceObserver';
import * as Fantom from '@react-native/fantom';
import setUpPerformanceObserver from 'react-native/src/private/setup/setUpPerformanceObserver';
import {PerformanceLongTaskTiming} from 'react-native/src/private/webapis/performance/LongTasks';
import {PerformanceObserver} from 'react-native/src/private/webapis/performance/PerformanceObserver';
setUpPerformanceObserver();
function ensurePerformanceLongTaskTiming(
value: mixed,
@@ -196,4 +188,20 @@ describe('LongTasks API', () => {
expect(entry.attribution).toEqual([]);
});
});
it('does NOT allow creating instances of PerformanceLongTaskTiming directly', () => {
expect(() => {
return new PerformanceLongTaskTiming();
}).toThrow(
"Failed to construct 'PerformanceLongTaskTiming': Illegal constructor",
);
});
it('does NOT allow creating instances of TaskAttributionTiming directly', () => {
expect(() => {
return new TaskAttributionTiming();
}).toThrow(
"Failed to construct 'TaskAttributionTiming': Illegal constructor",
);
});
});
@@ -10,12 +10,8 @@
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';
import type Performance from 'react-native/src/private/webapis/performance/Performance';
import * as Fantom from '@react-native/fantom';
declare var performance: Performance;
const clearMarksAndMeasures = () => {
performance.clearMarks();
performance.clearMeasures();
@@ -0,0 +1,25 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';
describe('Performance', () => {
it('does NOT allow creating instances of Performance directly', () => {
expect(() => {
return new Performance();
}).toThrow("Failed to construct 'Performance': Illegal constructor");
});
it('does NOT allow creating instances of PerformanceEntry directly', () => {
expect(() => {
return new PerformanceEntry();
}).toThrow("Failed to construct 'PerformanceEntry': Illegal constructor");
});
});
@@ -10,20 +10,9 @@
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';
import type Performance from '../Performance';
import type {
PerformanceObserver as PerformanceObserverT,
PerformanceObserverEntryList,
} from '../PerformanceObserver';
import setUpPerformanceObserver from '../../../setup/setUpPerformanceObserver';
import {PerformanceObserverEntryList_public} from '../PerformanceObserver';
import * as Fantom from '@react-native/fantom';
setUpPerformanceObserver();
declare var performance: Performance;
declare var PerformanceObserver: Class<PerformanceObserverT>;
describe('PerformanceObserver', () => {
it('receives notifications for marks and measures', () => {
const callback = jest.fn();
@@ -106,4 +95,33 @@ describe('PerformanceObserver', () => {
expect(entries1.getEntries()[1]).toBe(measure);
expect(entries2.getEntries()[1]).toBe(measure);
});
describe('takeRecords()', () => {
it('provides all buffered events and clears the buffer', () => {
const callback = jest.fn();
const observer = new PerformanceObserver(callback);
observer.observe({entryTypes: ['mark']});
Fantom.runTask(() => {
const entry = performance.mark('mark1');
const entries = observer.takeRecords();
expect(entries.length).toBe(1);
// This is not supported yet
// expect(entries[0]).toBe(entry);
expect(entries[0]).toEqual(entry);
});
expect(callback).not.toHaveBeenCalled();
});
});
it('does NOT allow creating instances of PerformanceObserverEntryList directly', () => {
expect(() => {
// $FlowExpectedError[incompatible-type]
return new PerformanceObserverEntryList_public();
}).toThrow(
"Failed to construct 'PerformanceObserverEntryList': Illegal constructor",
);
});
});
@@ -10,19 +10,10 @@
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';
import type Performance from '../Performance';
import type {
PerformanceEntryJSON,
PerformanceEntryList,
} from '../PerformanceEntry';
import ensureInstance from '../../../__tests__/utilities/ensureInstance';
import DOMException from '../../errors/DOMException';
import {PerformanceMark, PerformanceMeasure} from '../UserTiming';
import * as Fantom from '@react-native/fantom';
declare var performance: Performance;
function getThrownError(fn: () => mixed): mixed {
try {
fn();
@@ -32,7 +23,7 @@ function getThrownError(fn: () => mixed): mixed {
throw new Error('Expected function to throw');
}
function toJSON(entries: PerformanceEntryList): Array<PerformanceEntryJSON> {
function toJSON(entries: PerformanceEntryList): Array<mixed> {
return entries.map(entry => entry.toJSON());
}
@@ -50,6 +41,24 @@ describe('User Timing', () => {
mockClock.uninstall();
});
it('allows creating instances of PerformanceMark directly', () => {
const before = performance.now();
const entry = new PerformanceMark('mark-now');
const after = performance.now();
expect(entry).toBeInstanceOf(PerformanceMark);
expect(entry.startTime).toBeGreaterThanOrEqual(before);
expect(entry.startTime).toBeLessThanOrEqual(after);
expect(entry.duration).toBe(0);
expect(entry.detail).toBe(null);
});
it('does NOT allow creating instances of PerformanceMeasure directly', () => {
expect(() => {
return new PerformanceMeasure();
}).toThrow("Failed to construct 'PerformanceMeasure': Illegal constructor");
});
describe('mark', () => {
it('works with default timestamp', () => {
mockClock.setTime(25);
@@ -44,7 +44,6 @@ export function rawToPerformanceEntry(
case RawPerformanceEntryTypeValues.LONGTASK:
return new PerformanceLongTaskTiming({
name: entry.name,
entryType: rawToPerformanceEntryType(entry.entryType),
startTime: entry.startTime,
duration: entry.duration,
});
@@ -53,7 +52,8 @@ export function rawToPerformanceEntry(
startTime: entry.startTime,
});
case RawPerformanceEntryTypeValues.MEASURE:
return new PerformanceMeasure(entry.name, {
return new PerformanceMeasure({
name: entry.name,
startTime: entry.startTime,
duration: entry.duration,
});
@@ -71,9 +71,8 @@ export function rawToPerformanceEntry(
responseStatus: entry.responseStatus,
});
default:
return new PerformanceEntry({
return new PerformanceEntry(rawToPerformanceEntryType(entry.entryType), {
name: entry.name,
entryType: rawToPerformanceEntryType(entry.entryType),
startTime: entry.startTime,
duration: entry.duration,
});
@@ -10,7 +10,7 @@
'use strict';
const {execSync} = require('child_process');
const {spawnSync} = require('child_process');
const fs = require('fs');
const yargs = require('yargs');
@@ -66,7 +66,9 @@ function replaceRNDepsConfiguration(
fs.mkdirSync(finalLocation, {recursive: true});
console.log('Extracting the tarball', tarballURLPath);
execSync(`tar -xf ${tarballURLPath} -C ${finalLocation}`);
spawnSync('tar', ['-xf', tarballURLPath, '-C', finalLocation], {
stdio: 'inherit',
});
// Now we need to remove the extra third-party folder as we do in the podspec's prepare-script
// We need to take the ReactNativeDependencies.xcframework folder and move it up one level
@@ -48,7 +48,6 @@ const Drawer = () => {
return (
<DrawerLayoutAndroid
/* $FlowFixMe */
ref={drawer}
accessibilityRole="drawerlayout"
drawerWidth={300}
@@ -21,7 +21,6 @@ function getNativeTagFromHostElement(elem: ?HostInstance | number): ?number {
return elem;
}
if (elem != null) {
// $FlowExpectedError - accessing non-public property
return elem.__nativeTag;
}
return undefined;
-1
View File
@@ -70,7 +70,6 @@ export function observe(result: ExecaPromiseMetaized): TaskResult<{}, string> {
};
});
// $FlowFixMe
return obs;
}

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