Compare commits

...
Author SHA1 Message Date
Vojtech Novak da65b27f92 fix IOException in BuildCodegenCLITask 2024-11-28 16:55:40 +01:00
Kudo ChienandFacebook GitHub Bot 24fee29f7a Add useColorScheme mock test (#47988)
Summary:
add a jest test to test when `useColorScheme` is not mocked. following up https://github.com/facebook/react-native/pull/47629#issuecomment-2491534678

## Changelog:

[GENERAL] [ADDED] - Add useColorScheme mock test

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

Test Plan: ci passed

Reviewed By: javache

Differential Revision: D66573172

Pulled By: blakef

fbshipit-source-id: 820227f6fc4e18a968b3181fad8f534a716f1e9e
2024-11-28 05:05:31 -08:00
Rubén NorteandFacebook GitHub Bot 6ae49ee9e3 Improve error messages in tests (#47994)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47994

Changelog: [internal]

This adds a few hacks to improve errors messages in Fantom tests. Before, we were only logging the error message. After this, we log the message and the full (unsymbolicated for now) stack, including a pretty print of the exact location of the error.

For errors thrown from `expect` functions, the stack trace is modified to remove the "infra" lines from the stack.

The next step is symbolicating the errors using source maps generated by metro.

Reviewed By: javache

Differential Revision: D66555063

fbshipit-source-id: 17bd23cb30429a17e99f13f934c45e001120bbb3
2024-11-28 04:31:20 -08:00
Jorge Cabiedes AcostaandFacebook GitHub Bot ce9f5345e3 Fix Android ensureNoOverlap function and revise implementation (#47989)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47989

- Fixing Android's ensureNoOverlap algorithm. (For real this time)
- Improve verbiage for `ensureNoOverlap` function.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66514729

fbshipit-source-id: 99908deee2232cc125bb0998ae7acd636a1f7e10
2024-11-27 19:57:55 -08:00
Arushi KesarwaniandFacebook GitHub Bot 5da7089e35 NIT: Updating docstring for DefaultReactHost for missing arguments (#47992)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47992

TSIA

Changelog: [Internal]

Reviewed By: shwanton

Differential Revision: D66552119

fbshipit-source-id: 6dcd461fcea1444a58db4f98316bf8878ae98781
2024-11-27 17:26:19 -08:00
Arushi KesarwaniandFacebook GitHub Bot 762bcc6073 NIT: Updating docstring for DefaultReactHost to match the arguments. (#47991)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47991

TSIA

Changelog: [Internal]

Reviewed By: shwanton

Differential Revision: D66550256

fbshipit-source-id: b3c18032a421fd9f0bd69c142e72d884f96340f8
2024-11-27 17:26:19 -08:00
Alex HuntandFacebook GitHub Bot 7f57018e25 Add profiling_target_registered event, log to terminal (#47968)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47968

Updates the Inspector Proxy to report + log when a profiling build target (experimental) is registered. This notifies the developer that debugging is available for these app(s), which will not otherwise fetch development bundles from Metro.

Changelog: [Internal]

Reviewed By: rubennorte

Differential Revision: D66501771

fbshipit-source-id: e06dee279158094ad5c70bf8e6a90e7c983de48a
2024-11-27 11:42:31 -08:00
Alex HuntandFacebook GitHub Bot b95631ed7f Enable identifying profiling builds on proxy registration (#47967)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47967

(Android only) Updates `jsinspector-modern` to enable identifying profiling builds (experimental) when registering the debug target with the Inspector Proxy.

Changelog: [Internal]

Reviewed By: rubennorte

Differential Revision: D66501768

fbshipit-source-id: bbe2b9a2c7c014c952ef5ee49284a161dbeefb09
2024-11-27 11:42:31 -08:00
Alex HuntandFacebook GitHub Bot b9762d568a Enable identifying profiling builds over CDP (#47966)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47966

Updates `jsinspector-modern` to enable identifying profiling builds (experimental) to the frontend over CDP.

Changelog: [Internal]

Reviewed By: rubennorte

Differential Revision: D66501770

fbshipit-source-id: 9d079da862a59d5e2dc6f970e7418339620e1451
2024-11-27 11:42:31 -08:00
Rubén NorteandFacebook GitHub Bot a36dbae486 Optimize performance of ReactNativeElement constructor (#47983)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47983

Changelog: [internal]

This mitigates some performance regressions caused by the migration from `ReactFabricHostComponent` to `ReactNativeElement` (enabling the DOM APIs).

Those regressions were caused by 2 main things:
1. By the use of a class hierarchy and having to call `super()`, which we transpile to a very complex code to ensure it's spec compliant.
2. By the use of private fields (`#viewConfig`) which are significantly slower than a regular field with the `_` naming convention (`_viewConfig`) processed by our custom transform.

This mitigates those problems by using the `_` convention and refactoring the class hierarchy to avoid the use of `super()` while preserving the Flow typing and most of the existing implementation.

Reviewed By: javache, andrewdacenko

Differential Revision: D66540756

fbshipit-source-id: db6aa18c12194b18e3a69e9979621d0feae6186a
2024-11-27 11:24:31 -08:00
Jakub RomanczykandFacebook GitHub Bot 881d8a720f refactor(community-cli-plugin): use node builtin fetch (#47397)
Summary:
Removed `node-fetch` in favour of node builtin fetch to get rid of the deprecated `punycode` warning when using Node 22.

`react-native/community-cli-plugin` already requires Node >= 18 where it was made available by default (without `--experimental-fetch` flag).

This change is similar to the one made in https://github.com/facebook/react-native/pull/45227

## Changelog:

[GENERAL] [CHANGED] - Drop node-fetch in favor of Node's built-in fetch from undici in `react-native/community-cli-plugin`

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

Test Plan: tests pass

Reviewed By: blakef

Differential Revision: D66512595

Pulled By: NickGerleman

fbshipit-source-id: c4e01baf388f9fae8cea7b4bfe25034bff28b461
2024-11-27 10:39:39 -08:00
Joe VilchesandFacebook GitHub Bot 1d909efa23 Align order of params between calculateLayoutInternal and calculateLayoutImpl (#47975)
Summary:
X-link: https://github.com/facebook/yoga/pull/1755

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

I've been working with callsites here and its annoying if you switch these that you need to move these params around too. Let's just make them the same order

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66519836

fbshipit-source-id: 2e98e671270a053c6e62372e2003f1ca67774ec9
2024-11-26 22:48:24 -08:00
Phillip PanandFacebook GitHub Bot 3c09d6bfce allow bindings installer to be passed down to DefaultReactHost (#47944)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47944

Changelog: [Internal]

adding an option to pass down bindings installer from product layer

Reviewed By: mlord93

Differential Revision: D66477349

fbshipit-source-id: 9462cbe0b1fcee875c18de0426c0c1b02f086ff1
2024-11-26 19:20:56 -08:00
Joe VilchesandFacebook GitHub Bot 40c194cf47 Camel case LengthValue in Node.cpp (#47971)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47971

X-link: https://github.com/facebook/yoga/pull/1754

This was annoying me

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66510734

fbshipit-source-id: d1b952f2e82e7018b16dc0c572d9b98aec18c0e5
2024-11-26 15:23:08 -08:00
Alex HuntandFacebook GitHub Bot 24f010d5b5 Update unstable-react-profiling to use PerftestDevSupportManager (#47715)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47715

Changelog: [Internal]

Reviewed By: rubennorte

Differential Revision: D66167302

fbshipit-source-id: 23e6154eedd36c2011062de3195887cba7af8a72
2024-11-26 12:48:37 -08:00
Andrei MarchenkoandFacebook GitHub Bot df7b6ae092 fix item disappearing with scroll in VirtualizedList (#47965)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47965

Changelog: [General] [Changed] - fix item disappearing with scroll in VirtualizedList

It was caused because the function `computeWindowedRenderLimits` collapsed the current window size to just 1 element. So, users start scroll current window increase from {left:0, right:5 } -> {left:0, right:6 } and after some edge cases the window collapsed to `{left:6, right:6 }` which cause to remove all elements and recreate them later. As a result users have a lot of lags and blank pages.

The diff fixes the collapsing window size to 1 element. Also fix other decreasing `left` position even if windowSize more than current amount of elements.

Reviewed By: NickGerleman

Differential Revision: D66334188

fbshipit-source-id: 2162d00d03d64ab6325c0492d87449051e68a4e9
2024-11-26 10:44:30 -08:00
Rob HoganandFacebook GitHub Bot 016f44518e Changelog for 0.77.0-rc.0 (#47958)
Summary:
Changelog as generated by rnx-kit + manual fixes.

Changelog: [Internal]

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

Reviewed By: rshest, blakef

Differential Revision: D66498590

Pulled By: robhogan

fbshipit-source-id: 81efda2615f8e61be5f5922511362946f3ba3c6b
2024-11-26 08:06:18 -08:00
Dmitry RykunandFacebook GitHub Bot 69356b7f21 Introduce ImageRequestParams (#47723)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47723

Identity of `ImageRequest` is based on `ImageSource` and a subset of `ImageProps`. If any of those change, the request must be recreated and resubmitted.

Currently, the relevant subset of ImageProps is represented by a single `blurRadius` prop. This list will grow in the future. In order to simplify adding new props to the image request, we introduce the `ImageRequestParams` type that will wrap all the relevant props.

The alternative approach to pass `ImageProps` directly to `ImageManager` is worse because it would introduce dependency cycle between `ImageManager` and the `Image` component, and also it would require to store the props in State, which is bad.

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D66172570

fbshipit-source-id: d6853bf8dcecd6e76ac90ccb2079d102a3015988
2024-11-26 07:27:02 -08:00
Dmitry RykunandFacebook GitHub Bot a6b2355b8d Introduce Android ImageManger (#47721)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47721

This diff splits Cxx ImageManger into Cxx and Android variants. They both are currently no-op, but the Android one will be used for image prefetching, just as `RCTImageManager.mm` for iOS.
Changelog: [Internal]

Reviewed By: javache

Differential Revision: D65753319

fbshipit-source-id: 774ff09b6b397facee7f645706dd97ba6d1177d7
2024-11-26 04:22:09 -08:00
Pieter De BaetsandFacebook GitHub Bot 8869fa4c2c Fix stale reference to ReactViewGroup#mAllChildren (#47950)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47950

`addInArray` may reallocate `mAllChildren` so it's not correct to store this reference.

Changelog: [Internal]

Reviewed By: tdn120

Differential Revision: D66474532

fbshipit-source-id: 90ce2fcbf8ff236501ed47b2acc413e54ef8b82a
2024-11-26 04:00:14 -08:00
Pieter De BaetsandFacebook GitHub Bot 84adf268e1 Add more diagnostics for subview clipping crash (#47937)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47937

Changelog: [Internal]

Reviewed By: tdn120

Differential Revision: D66469161

fbshipit-source-id: d32f0592787ecae850854b2ff04d7c703ee8ec2e
2024-11-26 04:00:14 -08:00
Sam ZhouandFacebook GitHub Bot d86412dcc6 prepare for primitive literal changes (#47943)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47943

Changelog: [Internal]

Reviewed By: panagosg7

Differential Revision: D66461724

fbshipit-source-id: b526ed1617667b70337472f4dad4e19f152a266b
2024-11-26 00:07:32 -08:00
Jorge Cabiedes AcostaandFacebook GitHub Bot f70c3cae5b Fix border disappearing when only one edge is transparent (#47940)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47940

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

Border was disappearing when only one edge had an alpha of 0. This was due to clipping conditional

Changelog: [Internal]

Reviewed By: shwanton, NickGerleman

Differential Revision: D66397736

fbshipit-source-id: 8937323ad16e0c6e98a55051f244c08ef54c96eb
2024-11-25 18:15:25 -08:00
Jorge Cabiedes AcostaandFacebook GitHub Bot 96e66e7b48 Add unit tests for CompositeBackgroundDrawable layer ordering optimization (#47913)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47913

CompositeBackgroundDrawable has some logic for inserting the layers that are not set through the constructor. This unit test makes sure they are being properly ordered.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66381515

fbshipit-source-id: 514979a4a97fa159c1d1c3c923afe969eafc21c3
2024-11-25 16:48:39 -08:00
Sam ZhouandFacebook GitHub Bot cb7cd89a10 Deploy 0.255.0 to xplat (#47941)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47941

Changelog: [Internal]

Reviewed By: pieterv

Differential Revision: D66477998

fbshipit-source-id: f4d1dbe506d6c42751fade897637031f0a43aa29
2024-11-25 16:06:09 -08:00
Brett LavallaandFacebook GitHub Bot f363b43856 Make color value of ShadowStyleSpan public (#47934)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47934

This property needs to be made public for later diffs in this stack.

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D66338915

fbshipit-source-id: f4896f8404e3d7eed7255e0f923ab5eec9a1291e
2024-11-25 15:45:57 -08:00
danandFacebook GitHub Bot fe7e97a2fd Fix ScrollView centerContent losing taps and causing jitter on iOS (#47591)
Summary:
The React Native `<ScrollView>` has a peculiar `centerContent` prop. It solves a common need — keeping the image "centered" while it's not fully zoomed in (but then allowing full panning after it's sufficiently zoomed in).

This prop sort of works but it has a few wonky behaviors:

- If you start tapping immediately after pinch (and don't stop), the taps will not be recognized until a second after you stop tapping. I suspect this is because the existing `centerContent` implementation hijacks the `contentOffset` setter, but the calling UIKit code _does not know_ it's being hijacked, and so the calling UIKit code _thinks_ it needs to do a momentum animation. This (invisible) momentum animation causes the scroll view to keep eating the tap touches.
- While you're zooming in, once you cross the threshold where `contentOffset` hijacking stops adjusting values, there will be a sudden visual jump during the pinch. This is because the "real" `contentOffset` tracks the accumulated translation from the pinch gesture, and once it gets taken into account with no "correction", the new offset snaps into place.
- While not sufficiently pinched in, the vertical axis is completely rigid. It does not have the natural rubber banding.

The solution to all of these issues is described [here](https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/). Instead of hijacking `contentOffset`, it is more reliable to track zooming, child view, and frame changes, and adjust `contentInsets` instead. This solves all three issues:

- UIKit isn't confused by the content offset changing from under it so it doesn't mistrigger a faux momentum animation.
- There is no sudden jump because it's the insets that are being adjusted.
- Rubber banding just works.

## Changelog:

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

Pick one each for the category and type tags:

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

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

[IOS] [FIXED] - Fixed centerContent losing taps and causing jitter

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

Test Plan:
I'm extracting this from [a patch we're applying to Bluesky](https://github.com/bluesky-social/social-app/blob/2ef697fe3d7dec198544ed6834553f33b95790b3/patches/react-native%2B0.74.1.patch). I'll be honest — I have not tested this in isolation, and it likely requires some testing to get merged in. I do not, unfortuntately, have the capacity to do it myself so this is more of a "throw over the wall" kind of patch. Maybe it will be helpful to somebody else.

I've tested these in our real open source app (https://github.com/bluesky-social/social-app/pull/6298). You can reproduce it in any of the lightboxes in the feed or the profile.

### Before the fix

Observe the failing tap gestures, sudden jump while pinching, lack of rubber banding.

https://github.com/user-attachments/assets/c9883201-c9f0-4782-9b80-8e0a9f77c47c

### After the fix

Observe the natural iOS behavior.

https://github.com/user-attachments/assets/c025e1df-6963-40ba-9e28-d48bfa5e631d

Unfortunately I do not have the capacity to verify this fix in other scenarios outside of our app.

Reviewed By: sammy-SC

Differential Revision: D66093472

Pulled By: javache

fbshipit-source-id: 064f0415b8093ff55cb51bdebab2a46ee97f8fa9
2024-11-25 14:56:02 -08:00
Jorge Cabiedes AcostaandFacebook GitHub Bot 2a2f58ad9d Add mixBlendMode to iterator style parser (#47292)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47292

If we don't add the prop to the iterator style parser then since fabric is not parsing the prop we are not properly creating the stacking context for when a prop has a mix-blend-mode set

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D65166886

fbshipit-source-id: 7b5bce82e81bf0c566ccd4620852ae877ccbf376
2024-11-25 13:12:12 -08:00
Jorge Cabiedes AcostaandFacebook GitHub Bot b41fb6c88e Add fabric check to drawChild function (#47293)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47293

We missed fabric check for the mix-blend-mode conditional on `drawChildren` adding it now

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D65167244

fbshipit-source-id: 1af5dc1979fb79c453ba0f27c0385a94dc539a55
2024-11-25 13:12:12 -08:00
Dmitry RykunandFacebook GitHub Bot 8d83da6460 Introduce experimental image prefetching API (#47755)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47755

TIA.
Changelog: [Internal]

Reviewed By: tdn120

Differential Revision: D65596686

fbshipit-source-id: 9fbd57caa2fdeab0bdf68e7919b1f65179634a9d
2024-11-25 12:40:09 -08:00
Jorge Cabiedes AcostaandFacebook GitHub Bot 81a94f4f14 Forward fix incorrect elliptical border radius (#47931)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47931

tsia

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66388179

fbshipit-source-id: 5c614cf52e834f664bb9f59767b2e172c51af620
2024-11-25 11:10:02 -08:00
Mateo GuzmánandFacebook GitHub Bot 81cb166d10 fix(image): [android] cache control headers are being overwritten (#47922)
Summary:
While trying to write some test cases for `ReactOkHttpNetworkFetcher`, I found that the cache control headers are not being sent over the network request correctly. These cache control headers are always being overwritten by the rest of the headers hence all the logic to set this custom cache control doesn't seem to be working as expected.

As per the [Request headers](https://github.com/square/okhttp/blob/2832a9e532ecbc6f1f84b3a07e8e64b75372789c/okhttp/src/main/kotlin/okhttp3/Request.kt#L256) docs, this seems to be the explanation:

> /** Removes all headers on this builder and adds [headers]. */
    open fun headers(headers: Headers) = commonHeaders(headers)

With the new approach by setting the headers first, we ensure that the cache control headers don't get overwritten but they would get added on top of the passed headers.

Notice that currently it seems to be overwriting these headers even if there are not headers passed from the Image component (AKA null/empty).

See my reproduction example in the test plan.

## Changelog:

[ANDROID] [FIXED] - ReactOkHttpNetworkFetcher – cache control headers getting overwritten by the rest of the headers

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

Test Plan:
By creating the following component, we log the request headers using `FLog` with the previous and the new approach. See the difference on the outputs below:

Component:
```tsx
<Image
  source={{
    uri: 'https://www.facebook.com/assets/fb_lite_messaging/E2EE-settings@3x.png?cacheBust=reload',
    cache: 'reload',
    headers: {
      'some-header': 'some-header-value',
    },
  }}
/>
```

Setting the `headers` last (current approach):

```kt
val request =
        Request.Builder()
            .cacheControl(cacheControlBuilder.build())
            .url(uri.toString())
            .headers(headers)
            .get()
            .build()
FLog.w("RequestHeaders", request.headers.toString())
```

Output (notice that the Cache-Control header is not present):
```bash
RequestHeaders  com.facebook.react.uiapp  W  some-header: some-header-value
```

<img width="561" alt="image" src="https://github.com/user-attachments/assets/797cd90a-2064-4772-99cc-5f9d39d73361">

 ---

New approach by setting the `headers` first:

```kt
val request =
        Request.Builder()
            .headers(headers)
            .cacheControl(cacheControlBuilder.build())
            .url(uri.toString())
            .get()
            .build()
FLog.w("RequestHeaders", request.headers.toString())
```

Output (Cache-Control is present now along with the passed headers):
```bash
RequestHeaders  com.facebook.react.uiapp   W  some-header: some-header-value
Cache-Control: no-cache, no-store
```

<img width="556" alt="image" src="https://github.com/user-attachments/assets/1b9f7865-926e-496b-ad3a-36e19ae92188">

Reviewed By: rshest

Differential Revision: D66446820

Pulled By: javache

fbshipit-source-id: 2640ea4b0e678a7aa919b919b0b44bedc0da0af4
2024-11-25 07:34:51 -08:00
94 changed files with 1522 additions and 221 deletions
+2 -1
View File
@@ -44,6 +44,7 @@ packages/react-native/flow/
[options]
enums=true
as_const=true
casting_syntax=both
emoji=true
@@ -95,4 +96,4 @@ untyped-import
untyped-type-import
[version]
^0.254.2
^0.255.0
+382
View File
@@ -1,5 +1,387 @@
# Changelog
## v0.77.0-rc.0
### Breaking
- Bridgeless: Make NativeModules.foo load turbomodules (unset turboModuleProxy in bridgeless). ([cc5f17d5a2](https://github.com/facebook/react-native/commit/cc5f17d5a2b185de1e7dec2a56a97b088e4c7a81) by [@RSNara](https://github.com/RSNara))
- dev-middleware: Frameworks should specify `serverBaseUrl` relative to the middleware host. ([acf384a72e](https://github.com/facebook/react-native/commit/acf384a72e599691e4c9d53043f1801da01c58fd) by [@robhogan](https://github.com/robhogan))
- `position` of sticky headers on `ScrollView` will now be taken into account ([cbab004eb9](https://github.com/facebook/react-native/commit/cbab004eb94f8312e9b10dae1502d3ca8632a006) by [@joevilches](https://github.com/joevilches))
- Remove ReactFabricInternals module ([0c21db360c](https://github.com/facebook/react-native/commit/0c21db360cecc6a3265eea50d628106c58b67af8) by [@huntie](https://github.com/huntie))
- Make ReactDebugOverlayTags, DebugOverlayTags, Printer, PrinterHolder, NoopPrinter internal ([623d481991](https://github.com/facebook/react-native/commit/623d4819915e7e6fafb8006c8e3b3b796e394974) by [@cortinico](https://github.com/cortinico))
- More spec compliant absolute positioning ([0a2dec175e](https://github.com/facebook/react-native/commit/0a2dec175e92185943907f3e1f6073bae6cd663d) by [@NickGerleman](https://github.com/NickGerleman))
- Native looping animation will not send React state update every time it finishes. ([4b035d820d](https://github.com/facebook/react-native/commit/4b035d820d3f1c3c9a98ce4f55bcc95a7ab064bf) by [@dmytrorykun](https://github.com/dmytrorykun))
#### Android specific
- Removed ReactViewGroup.getBackgroundColor() ([6a472c5cf2](https://github.com/facebook/react-native/commit/6a472c5cf25d72f72ec7e261282d611a5ab0a662) by Thomas Nardone)
- ReadableArray non-primitive getters are now correctly typed as optional ([145c72f816](https://github.com/facebook/react-native/commit/145c72f8163048f0eee30d5ce850911f5dad865c) by [@javache](https://github.com/javache))
- Remove jsBundleLoader from DefaultReactHost.getDefaultReactHost() ([fbe4c0ed34](https://github.com/facebook/react-native/commit/fbe4c0ed347156a7ea24da29e09083a499c80cf5) by [@mdvacca](https://github.com/mdvacca))
- Reduce visibility of TaskCompletionSource class ([4f55161132](https://github.com/facebook/react-native/commit/4f551611326d63b6fb5cd53e63d536c2c6f04647) by [@mdvacca](https://github.com/mdvacca))
- Stable API - Make ImageStoreManager internal ([846c4b1ea2](https://github.com/facebook/react-native/commit/846c4b1ea2d139e3f3cbafa2f8ddbf159e3322e4) by [@arushikesarwani94](https://github.com/arushikesarwani94))
- Stable API - Make SwipeRefreshLayoutManager internal ([d02da992a4](https://github.com/facebook/react-native/commit/d02da992a4c0893313b9f059a8be228f43fffa7a) by Thomas Nardone)
- Undo breaking change of UiManager.eventDispatcher return type ([7817ab5de2](https://github.com/facebook/react-native/commit/7817ab5de2ce324df734a5dfd705f2454937328f) by [@cortinico](https://github.com/cortinico))
- Stable API - Make classes inside `com.facebook.react.views.progressbar` internal ([46526fc2fe](https://github.com/facebook/react-native/commit/46526fc2fe1dd0ce937fad35469b64b9fb05eaa2) by [@cortinico](https://github.com/cortinico))
- Undo breaking change of UiManager.eventDispatcher return type ([dbe509a23a](https://github.com/facebook/react-native/commit/dbe509a23a974f16804aefea055a24c06910b259) by [@cortinico](https://github.com/cortinico))
- Stable API - Make OkHttpCallUtil internal ([abd118a719](https://github.com/facebook/react-native/commit/abd118a719fe0aeb13f980729ff9ce5fb8358b83) by [@arushikesarwani94](https://github.com/arushikesarwani94))
- Stable API - Make SimpleSettableFuture internal ([3dec672398](https://github.com/facebook/react-native/commit/3dec672398729cd668aff92249f1fdde231fb928) by [@arushikesarwani94](https://github.com/arushikesarwani94))
- Stable API - Make `ClipboardModule` internal ([10f6d5adb5](https://github.com/facebook/react-native/commit/10f6d5adb538a9b20043312fc09b192759100d63) by [@cortinico](https://github.com/cortinico))
- Reduce visibility of ReactVirtualTextShadowNode to internal ([496b0a8729](https://github.com/facebook/react-native/commit/496b0a8729b41266683fdd84de5618b23d06ce3d) by [@mdvacca](https://github.com/mdvacca))
- Reduce visibility of ReactVirtualTextViewManager to internal ([4a119c4c3a](https://github.com/facebook/react-native/commit/4a119c4c3ac9bf4b234e2942a27a6efd68a801cc) by [@mdvacca](https://github.com/mdvacca))
- Stable API - Make classes in `com.facebook.react.views.safeareaview` internal ([39dfbadd5d](https://github.com/facebook/react-native/commit/39dfbadd5d3468d079bf3b039401237c6e7f363c) by [@cortinico](https://github.com/cortinico))
- Stable API - Make ClipboardModule internal ([a72c35f98c](https://github.com/facebook/react-native/commit/a72c35f98ccd1a49d367678b46a29c814ad5de43) by [@cortinico](https://github.com/cortinico))
- Undo a breaking change on ReactViewGroup constructor ([bbe714e487](https://github.com/facebook/react-native/commit/bbe714e487fb51c61820fdc5d89c9782da79b657) by [@cortinico](https://github.com/cortinico))
- Stable API - Make NativeModulePerfLogger internal ([d7d5de9f96](https://github.com/facebook/react-native/commit/d7d5de9f9630e7dcd0194830d7ccb32f167b619c) by [@cortinico](https://github.com/cortinico))
- Make `DevLoadingModule` internal ([8c50bf0beb](https://github.com/facebook/react-native/commit/8c50bf0beb17ced7fdafeae7a734edfc03e6e0b2) by [@cortinico](https://github.com/cortinico))
- Stable API - Convert to Kotlin and make internal `NotThreadSafeViewHierarchyUpdateDebugListener` ([287e200332](https://github.com/facebook/react-native/commit/287e20033207df5e59d199a347b7ae2b4cd7a59e) by [@cortinico](https://github.com/cortinico))
- Rename DevSupportManagerBase.getCurrentContext() -> getCurrentReactContext() ([0e7ba9094e](https://github.com/facebook/react-native/commit/0e7ba9094ea573d1512b2dc71e46f55b24201b7a) by [@RSNara](https://github.com/RSNara))
- Make DevSupportManagerBase.getCurrentReactContext() public ([5a6a42c7d0](https://github.com/facebook/react-native/commit/5a6a42c7d029d44799cb907c0ca3c8aa38fa1770) by [@RSNara](https://github.com/RSNara))
- Reduce visibility of ReactUnimplementedViewManager to internal ([fe656be26e](https://github.com/facebook/react-native/commit/fe656be26e0d71bf2505032578dbea54af36b2c5) by [@mdvacca](https://github.com/mdvacca))
- Stable API - Make InteropModuleRegistry internal ([cba1d4bae7](https://github.com/facebook/react-native/commit/cba1d4bae7285ba160b05f31ca18cfa0b91e9ef5) by [@cortinico](https://github.com/cortinico))
- Stable API - Make ReactDevToolsSettingsManagerModule and ReactDevToolsRuntimeSettingsModule internal ([d7550293a2](https://github.com/facebook/react-native/commit/d7550293a2530f02f75b4249b7e6003edaf28ac9) by [@cortinico](https://github.com/cortinico))
- Added JSBundleLoader as parameter of DefaultReactHost ([143b9d172c](https://github.com/facebook/react-native/commit/143b9d172ca755e2457e8dfc6009eeef2475a4a1) by [@mdvacca](https://github.com/mdvacca))
- Deleting deprecated CompositeReactPackage ([2cb5198f1b](https://github.com/facebook/react-native/commit/2cb5198f1b589a57a4cfd3cc40a9ed6224fc5d75) by [@mdvacca](https://github.com/mdvacca))
- Make ReactHost.createSurface() method non nullable ([70c7616535](https://github.com/facebook/react-native/commit/70c761653564653bdfcb77a8c5ef3608dafcf5d7) by [@mdvacca](https://github.com/mdvacca))
- Stable API - Make AppStateModule internal ([dbf09fbe58](https://github.com/facebook/react-native/commit/dbf09fbe5823d77556b451317c14f833735067d9) by [@cortinico](https://github.com/cortinico))
- Undo breaking change on UIManager eventDispatcher accessor ([dc1a498d39](https://github.com/facebook/react-native/commit/dc1a498d3974680f2257efd8ff9ec3f989204c68) by [@cortinico](https://github.com/cortinico))
- Make `AccessibilityInfoModule` internal ([7168a9d1a2](https://github.com/facebook/react-native/commit/7168a9d1a2ed7459ebb056ebe45d86de791013e3) by [@cortinico](https://github.com/cortinico))
- Undo breaking change on ViewManagerDelegate.kt String params ([2d2bb9c588](https://github.com/facebook/react-native/commit/2d2bb9c58824af34392bda196fbf0be17498cc05) by [@cortinico](https://github.com/cortinico))
- Add 3 methods to ReactInstanceDevHelper ([c867aba2f3](https://github.com/facebook/react-native/commit/c867aba2f3dd7773be9d2ee0827bcd69481a394e) by [@cortinico](https://github.com/cortinico))
- Add test case for set opacity in new arch examples ([848471b69f](https://github.com/facebook/react-native/commit/848471b69f59094780ace25c6963e480d94ec5c3) by [@poonamjain96](https://github.com/poonamjain96))
- Add test for Console.log measure in new-arch-examples ([8cf27e8b6f](https://github.com/facebook/react-native/commit/8cf27e8b6f112d646111ddaba0b5036cafac3299) by [@poonamjain96](https://github.com/poonamjain96))
- Remove Deprecated DefaultDevSupportManagerFactory.create() ([f25abe51ce](https://github.com/facebook/react-native/commit/f25abe51ce93b97ef1fe97af5fc76f13a5a6ff03) by [@cortinico](https://github.com/cortinico))
- Remove BaseViewManagerInterface ([7fb3d830be](https://github.com/facebook/react-native/commit/7fb3d830beae3daf431ac90e9326b744ff8300a1) by [@NickGerleman](https://github.com/NickGerleman))
- Chore: test case added for Image ([d0e5053528](https://github.com/facebook/react-native/commit/d0e50535287088030e60e131691c8d9ed1d57989) by [@sarthak-d11](https://github.com/sarthak-d11))
- Remove ReactNativeFlipper object, deprecated in 0.75 ([d1a256f51a](https://github.com/facebook/react-native/commit/d1a256f51a43f465823bdfb8a70fae5f92473d7c) by [@cortinico](https://github.com/cortinico))
- Add test for background color and border width in text.yml ([fa62b7e1ed](https://github.com/facebook/react-native/commit/fa62b7e1ed00c69819d85819c6209fb42bedb233) by [@muskan27797](https://github.com/muskan27797))
- Added Submit Application test to button.yml ([699f73a6b0](https://github.com/facebook/react-native/commit/699f73a6b0734fe716b01d263e9579bca38c4652) by [@shubhamguptadream11](https://github.com/shubhamguptadream11))
- Use BackgroundStyleApplicator when setting background color in BaseViewManager ([309cdea337](https://github.com/facebook/react-native/commit/309cdea337101cfe2212cfb6abebf1e783e43282) by [@NickGerleman](https://github.com/NickGerleman))
- Delete useTurboModules, enableFabricRenderer and enableBridgelessArchitecture fields from ReactFeatureFlags class ([10a33e0479](https://github.com/facebook/react-native/commit/10a33e04793befbeab6ae82d4068b1ebd7fdffd0) by [@mdvacca](https://github.com/mdvacca))
- Remove ReactViewBackgroundManager and ReactViewBackgroundDrawable ([51673e41ae](https://github.com/facebook/react-native/commit/51673e41ae12f06b2b378e048094ad39ca30c317) by [@NickGerleman](https://github.com/NickGerleman))
#### iOS specific
- Use the RCTDependencyProvider in the RCTAppDelegate, breaking the dependency with Codegen ([b91626af26](https://github.com/facebook/react-native/commit/b91626af2626bf611958b1e7d0dd0b7338ccc29e) by [@cipolleschi](https://github.com/cipolleschi))
- Delete experimental API RCTConstants.RCTGetMemoryPressureUnloadLevel ([d79dc48abd](https://github.com/facebook/react-native/commit/d79dc48abd2e65e4d203e488f99eb554c473a1fc) by [@mdvacca](https://github.com/mdvacca))
- ([6fc500ee99](https://github.com/facebook/react-native/commit/6fc500ee9942e51519545c1ba1026bacad03dc61) by [@philIip](https://github.com/philIip))
- ([538bff710f](https://github.com/facebook/react-native/commit/538bff710f7afb4afa7ce91f20074668ad5c739d) by [@philIip](https://github.com/philIip))
- Replace uses of `CGColorRef` with UIColor to avoid manual memory management ([b70709dbc2](https://github.com/facebook/react-native/commit/b70709dbc27c75c69e9fd2b082ffa27e7e8db7fd) by [@Saadnajmi](https://github.com/Saadnajmi))
- Cocoapods decide the C++ version for iOS pods ([bd50c4a460](https://github.com/facebook/react-native/commit/bd50c4a460a01dad3cd7cade8191273563675d24) by [@cipolleschi](https://github.com/cipolleschi))
- Delete partialBatchDidFlush ([a777a8937e](https://github.com/facebook/react-native/commit/a777a8937ee165993d7d9b35c7c981fe6698f9dc) by [@philIip](https://github.com/philIip))
- We deprecated RCTRuntimeExecutor in 0.76, so let's get rid of the code now. ([cf8d09b279](https://github.com/facebook/react-native/commit/cf8d09b279c4bd667d96f9445c1c0b9acb0a0dfc) by [@philIip](https://github.com/philIip))
- Unbreak `RCTHermesInstance` constructor breaking change ([aec6666bfa](https://github.com/facebook/react-native/commit/aec6666bfabf93cde70fa869b3eea68590998dee) by [@tido64](https://github.com/tido64))
### Added
- Add FuseboxPerfettoDataSource to emit Fusebox traces using Perfetto ([ef0ea4d834](https://github.com/facebook/react-native/commit/ef0ea4d834ec61c5deede487b46a787a363f6a64) by Benoit Girard)
- Add support for `rn_rootThreshold` in Intersection Observer ([a77d8d9d50](https://github.com/facebook/react-native/commit/a77d8d9d50e69a6a4563737c2ce68d26204eda7f) by [@lunaleaps](https://github.com/lunaleaps))
- Codegen: Support negative values in enums ([177bf4d043](https://github.com/facebook/react-native/commit/177bf4d043ce862911e477e0f0039214d8541cfd) by [@okwasniewski](https://github.com/okwasniewski))
- Use the TypeScript key in syntax to restrict permissions and types of results ([0244710c4b](https://github.com/facebook/react-native/commit/0244710c4b1e5016069ec9f7b8e7116ff51f59f1) by [@qnnp-me](https://github.com/qnnp-me))
- Image `resizeMode` and `objectFit` support for `'none'`. ([d8cfd98070](https://github.com/facebook/react-native/commit/d8cfd98070cbccc5e8a49446d76bdc2cb0c6939f) by [@mateoguzmana](https://github.com/mateoguzmana))
- Add NumberLiteralTypeAnnotation support ([dd472101b7](https://github.com/facebook/react-native/commit/dd472101b76a964b7a64f0bb84d967f702500cad) by [@elicwhite](https://github.com/elicwhite))
- Eliminate usage of more than 1-arg `React.AbstractComponent` in React codebase ([6205aad81e](https://github.com/facebook/react-native/commit/6205aad81ef8154a106fa253a1f4b00aee568650) by [@SamChou19815](https://github.com/SamChou19815))
- Added support for `display: contents` ([e7a3f479fe](https://github.com/facebook/react-native/commit/e7a3f479fe37a5d503770bafc03c80b1c2dcb8f7) by [@j-piasecki](https://github.com/j-piasecki))
- Added the missing `announceForAccessibilityWithOptions` function mock in the `packages/react-native/jest/setup.js` file. ([4ae999b90b](https://github.com/facebook/react-native/commit/4ae999b90b2a67233890d30a8bff0dbdd58364f2) by [@ChrisMattew](https://github.com/ChrisMattew))
- Add support for reload-to-profile in Fusebox (Part 2 of 2: JS) ([4df224ca6d](https://github.com/facebook/react-native/commit/4df224ca6df9dc593ab7090520578f27c520f361) by [@EdmondChuiHW](https://github.com/EdmondChuiHW))
- Add JS layer for new text content type cellular EID and cellular IMEI ([118c1f7035](https://github.com/facebook/react-native/commit/118c1f7035cfcadb567b1ccd40d85c751dd65162) by [@cipolleschi](https://github.com/cipolleschi))
- Add support for reload-to-profile in Fusebox. (Part 1 of 2: native) ([91a40a28de](https://github.com/facebook/react-native/commit/91a40a28de3f74a389c6e6ad05fb917d58fc072d) by [@EdmondChuiHW](https://github.com/EdmondChuiHW))
- Add cli --help details to combine-js-toschema-cli.js ([e4814b0d6d](https://github.com/facebook/react-native/commit/e4814b0d6d981cf96eef2803e8f20548263ea0e4) by [@blakef](https://github.com/blakef))
- Codegen for Native Modules now supports string literals ([d2f3f06826](https://github.com/facebook/react-native/commit/d2f3f06826e2287ad5f5dc4e27201fc5dc9fcd5c) by [@elicwhite](https://github.com/elicwhite))
- Codegen now supports Union Types in NativeModules ([3af126b562](https://github.com/facebook/react-native/commit/3af126b562cf7e0828906a4fe0ac79a886b557e6) by [@elicwhite](https://github.com/elicwhite))
- Updated FlatList setNativeProps type ([b0ac99b477](https://github.com/facebook/react-native/commit/b0ac99b47781e3b68bee2ff737b109f58eeeba78) by [@JDMathew](https://github.com/JDMathew))
- Added Jest mocks for `NativeAnimatedModule` ([fd355308fa](https://github.com/facebook/react-native/commit/fd355308faa2da30d4e0d68ae9b4d136d2a5f1c3) by [@yungsters](https://github.com/yungsters))
- Added `HostInstance` type to represent the instance of a `HostComponent<T>`. ([e24f9917c2](https://github.com/facebook/react-native/commit/e24f9917c25ed8c32c6e01d50a5fa49fe66a6ee1) by [@yungsters](https://github.com/yungsters))
- Export `DevMenu` from `react-native` ([e12c0d9551](https://github.com/facebook/react-native/commit/e12c0d95516924b5e6ca4f0d5ebcadb42bb19f30) by [@frankcalise](https://github.com/frankcalise))
- Removed `experimental` prefix and fully released `mixBlendMode` prop ([d2c48f3b1a](https://github.com/facebook/react-native/commit/d2c48f3b1a2a15e9832ea3240c19aea5186ceb24) by [@jorge-cab](https://github.com/jorge-cab))
- Add Playground to RNTester for testing out features & submitting reproducers. ([256adcab7b](https://github.com/facebook/react-native/commit/256adcab7b02e8a80227d44b76d1a74d8c4973de) by [@shwanton](https://github.com/shwanton))
- Add color formatting to codegen output ([1747f57c67](https://github.com/facebook/react-native/commit/1747f57c6708ffa59ea511f9fbbacf37364fde72) by [@okwasniewski](https://github.com/okwasniewski))
- Added overlayColor prop to modal component for customisable background overlay ([4e1d7015c1](https://github.com/facebook/react-native/commit/4e1d7015c1d4e2703133b1347ed97a0cc93b1318) by [@shubhamguptadream11](https://github.com/shubhamguptadream11))
- Created an experimental optimization to improve memoization within `Animated` to improve product performance ([dc84d00db6](https://github.com/facebook/react-native/commit/dc84d00db64b78234e91c2b73f4d4fce8782cd02) by [@yungsters](https://github.com/yungsters))
- Expose missing text content type to JS ([d3d48cb357](https://github.com/facebook/react-native/commit/d3d48cb357e55b1f2ae0042a5960451fbe5ff5c7) by [@cipolleschi](https://github.com/cipolleschi))
- Created an experimental (unstable) method for allowlisting props when using `Animated` ([f3f652daab](https://github.com/facebook/react-native/commit/f3f652daabc4a1d374190165ac38715ad31a5214) by [@yungsters](https://github.com/yungsters))
- Upgrade Flow to 0.245.2 ([1f65bf9545](https://github.com/facebook/react-native/commit/1f65bf9545cd84bbf1be7a7a91cb0b4f8b4b47ba) by [@SamChou19815](https://github.com/SamChou19815))
#### Android specific
- Image `force-cache` caching control option ([a0be88fd72](https://github.com/facebook/react-native/commit/a0be88fd727898d4626ca51876d0bfb4e50dcb77) by [@mateoguzmana](https://github.com/mateoguzmana))
- Add overlapping radii resolution logic preventing incorrect rendering ([451ff70da4](https://github.com/facebook/react-native/commit/451ff70da422beefccfff5b87024145003bb49ff) by [@jorge-cab](https://github.com/jorge-cab))
- Marked ReactPackage#getModule as stable. ([8fba7ebb5e](https://github.com/facebook/react-native/commit/8fba7ebb5e874d001dc5c16eb4229054a2ef4812) by [@javache](https://github.com/javache))
- ReactDelegate and ReactActivityDelegate#getCurrentReactContext can be used to access the current context ([fe8cc62824](https://github.com/facebook/react-native/commit/fe8cc62824372229d90445b2769fed9c08604a7e) by [@javache](https://github.com/javache))
- Add exceptionHandler as a parameter of DefaultReactHost.getDefaultReactHost() method ([7a5a10c95c](https://github.com/facebook/react-native/commit/7a5a10c95ce6af1964ce5bd273c0c6513fb78a1e) by [@mdvacca](https://github.com/mdvacca))
- Logic to check for grayscale mode on android ([e70202e606](https://github.com/facebook/react-native/commit/e70202e606be3101da33d28f5403443c3e84749e) by [@oddlyspaced](https://github.com/oddlyspaced))
- TextTransform ktx ([7794d7af43](https://github.com/facebook/react-native/commit/7794d7af43b90b581574361af102f67ad7961a5e) by Thomas Nardone)
- Add navigationBarTranslucent prop to Modal component ([7a6c7a462a](https://github.com/facebook/react-native/commit/7a6c7a462a7898e13327438a6603d83a39147abb) by [@zoontek](https://github.com/zoontek))
- Trigger Java GC on app reload ([de3c1ee097](https://github.com/facebook/react-native/commit/de3c1ee097f7041d6f9754a55a45cea80fd25813) by [@mrousavy](https://github.com/mrousavy))
- Add cmake arguments to support 16KB page size for native libraries ([65cdd5b82c](https://github.com/facebook/react-native/commit/65cdd5b82ce7652630b1920fa3a48c8f256c7983) by [@alanleedev](https://github.com/alanleedev))
- Enabling basic `Image` cache control for Android ([e5dd7d68bf](https://github.com/facebook/react-native/commit/e5dd7d68bf264669fc5c4ce5e69b24249d28558b) by [@mateoguzmana](https://github.com/mateoguzmana))
- Add OnLayoutChange API for scroll views ([d825a4d712](https://github.com/facebook/react-native/commit/d825a4d712a1ba53c0f4209c9da5d51578209a6d) by Thomas Nardone)
- React Activity exposes ReactHost ([d78cb78b15](https://github.com/facebook/react-native/commit/d78cb78b15a520f3bebcdf00b82b26bf120f4180) by [@shwanton](https://github.com/shwanton))
- Added PixelUtil extensions for Int and Long ([9406a09f87](https://github.com/facebook/react-native/commit/9406a09f871d3efa66e3d10237a6d1fd08ddee0b) by Thomas Nardone)
- Add boxShadow support to BaseViewManager ([b69a92e2c9](https://github.com/facebook/react-native/commit/b69a92e2c95990fcfa95a6ab7b7260ac492f942c) by [@NickGerleman](https://github.com/NickGerleman))
- Test: pressable test cases ([3102a58df3](https://github.com/facebook/react-native/commit/3102a58df38d96f3dacef0530e4dbb399037fcd2) by [@deepanshushuklad11](https://github.com/deepanshushuklad11))
- Added showcase for Android `resizeMethod` options when applied to a large image ([768a1d8664](https://github.com/facebook/react-native/commit/768a1d86649e391964d404a15733c227c57c0d38) by [@Abbondanzo](https://github.com/Abbondanzo))
- Adds a new `resizeMethod`, `none`, which disables downsampling for an image ([6202319ed5](https://github.com/facebook/react-native/commit/6202319ed544e4d23f1f327ff5334c480af3819d) by [@Abbondanzo](https://github.com/Abbondanzo))
- Add Modal Testing to modal.yml ([1a2532b1fc](https://github.com/facebook/react-native/commit/1a2532b1fc32ec989e05576121b5e669697d29af) by [@ahmedbilal008](https://github.com/ahmedbilal008))
- Add a new Fresco decoder for XML resource types ([118b7c18a6](https://github.com/facebook/react-native/commit/118b7c18a6f827dabb00522bbd6a2416e1bf99da) by [@Abbondanzo](https://github.com/Abbondanzo))
- Added `isHighTextContrastEnabled()` to `AccessibilityInfo` to read `ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED` setting value ([d4ea147b41](https://github.com/facebook/react-native/commit/d4ea147b41e4d22253f80be8b74731dcf0439302) by Ariel Lin)
- Outline properties `outline-width`, `outline-color`, `outline-style` & `outline-offset` ([17faac4170](https://github.com/facebook/react-native/commit/17faac417035f2cc5f12ec60a46270991be0989a) by [@jorge-cab](https://github.com/jorge-cab))
- Flag in ReactFragment to allow unmounting a surface without destroying ReactHost. ([bb3ec4d6c3](https://github.com/facebook/react-native/commit/bb3ec4d6c342d3afcb109e8c65f99e7693c962b5) by [@rozele](https://github.com/rozele))
- ReactDelegate `unloadApp` methods for unmounting surfaces without destroying ReactHost ([38593c440e](https://github.com/facebook/react-native/commit/38593c440e949a9b52df0a6821b80ac47b19a693) by [@rozele](https://github.com/rozele))
- New feature flag for line height calculation ([f338e7c0a1](https://github.com/facebook/react-native/commit/f338e7c0a1072974b5ac76567c8d1d06f5b7c1e2) by [@mellyeliu](https://github.com/mellyeliu))
- Adds support for importing XML assets as images ([2e80f5acf1](https://github.com/facebook/react-native/commit/2e80f5acf11cd9726921a00a58700cab9e0bb0a7) by [@Abbondanzo](https://github.com/Abbondanzo))
#### iOS specific
- Image `only-if-cached` cache control option ([dc9db01665](https://github.com/facebook/react-native/commit/dc9db01665308ac931967326abfc86deb9ae7e2a) by [@mateoguzmana](https://github.com/mateoguzmana))
- TextInput `inputAccessoryViewButtonLabel` prop ([32931466ed](https://github.com/facebook/react-native/commit/32931466ed7e3d8d9eeeb65f12ce146e123870ba) by [@mateoguzmana](https://github.com/mateoguzmana))
- Fix: Correct Layout Behavior for Combined align-content and align-items ([73a2be1243](https://github.com/facebook/react-native/commit/73a2be12437c93bbd138e0d63cd45d834529a3c4) by [@phuccvx12](https://github.com/phuccvx12))
- Extract RCTAppDependencyProvider in the ReactAppDependencyProvider pod ([102062fbc7](https://github.com/facebook/react-native/commit/102062fbc7d6a5c81192562c3ccb87bc4222a0cf) by [@cipolleschi](https://github.com/cipolleschi))
- Pass the `RCTAppDependencyProvider` to the `RCTAppDelegate` ([95fc906930](https://github.com/facebook/react-native/commit/95fc906930ece9b30482eb1f0924d7e8614af7c6) by [@cipolleschi](https://github.com/cipolleschi))
- Introduce the RCTAppDependencyProvider to minimize the changes required y the users ([41c2502b36](https://github.com/facebook/react-native/commit/41c2502b3650e238b0a5d86b5044abcb538b76e3) by [@cipolleschi](https://github.com/cipolleschi))
- Add RCTDependencyProvider protocol ([f2b3716426](https://github.com/facebook/react-native/commit/f2b371642684682916522dc82adee93464ba31fe) by [@cipolleschi](https://github.com/cipolleschi))
- Added `disabledButtonTintColor` prop to ActionSheetIOS ([089c87e22e](https://github.com/facebook/react-native/commit/089c87e22e9f431d0e7f35292dce2e36fa86d09a) by [@henninghall](https://github.com/henninghall))
- Scroll the cursor into view when text input is focused ([e021e50d53](https://github.com/facebook/react-native/commit/e021e50d537884a55a9f5bea931adb19e9069dd6) by [@dominictb](https://github.com/dominictb))
- Introduce RCTArchConfiguratorProtocol ([ec0dbb729d](https://github.com/facebook/react-native/commit/ec0dbb729d3774184dee83efbff5f9beebce72ce) by [@okwasniewski](https://github.com/okwasniewski))
- Introduce RCTUIConfiguratorProtocol ([8850736188](https://github.com/facebook/react-native/commit/8850736188321f13c7bdeadedeed15c759ad72c1) by [@okwasniewski](https://github.com/okwasniewski))
- TvOS support for Hermes artifacts ([f673759c83](https://github.com/facebook/react-native/commit/f673759c83fed130964ea7dfe677c04608b8e64d) by [@douglowder](https://github.com/douglowder))
- Add `CallInvoker` to `BindingsInstaller` ([87bae7f734](https://github.com/facebook/react-native/commit/87bae7f7349976cfc269b25584330c4d3d897d79) by [@mrousavy](https://github.com/mrousavy))
- Added `isDarkerSystemColorsEnabled()` to `AccessibilityInfo` to read "Increase Contrast" setting value ([af3bee6511](https://github.com/facebook/react-native/commit/af3bee6511fe72fda7415bf974f937012b3eefec) by Ariel Lin)
- Expose RCT_NEW_ARCH_ENABLED to Swift ([d24507611d](https://github.com/facebook/react-native/commit/d24507611de7fefc71286fd54b2c909d98a4bf27) by [@okwasniewski](https://github.com/okwasniewski))
- Add `systemCyan` and `systemMint` colors on iOS ([4caf548a9f](https://github.com/facebook/react-native/commit/4caf548a9f2e485aef9cbaeeb0a666cf9b9d3e59) by [@EvanBacon](https://github.com/EvanBacon))
- Outline properties `outline-width`, `outline-color`, `outline-style` & `outline-offset` ([1288e38423](https://github.com/facebook/react-native/commit/1288e38423f93ed57737dd9b40ad55696494d6f4) by [@jorge-cab](https://github.com/jorge-cab))
- Declare supportedInterfaceOrientations only on iOS ([40c5e6b64a](https://github.com/facebook/react-native/commit/40c5e6b64a1d82b5b481717b9086340eca2aaef9) by [@okwasniewski](https://github.com/okwasniewski))
- New text content type cellular EID and cellular IMEI ([14e0d0dffb](https://github.com/facebook/react-native/commit/14e0d0dffb9ee8b1d41d60ccbcfd63d53bfe4d48) by [@pasc0al](https://github.com/pasc0al))
- User-configurable BUNDLE_NAME when building bundles ([f8287e25e1](https://github.com/facebook/react-native/commit/f8287e25e11d56beb66ace414ca5f8a6a32405a9) by [@fivecar](https://github.com/fivecar))
- Line break mode for TextInput components. **This includes JS APIs for the new mode.** ([ce2d34f194](https://github.com/facebook/react-native/commit/ce2d34f19451c91a90f0bd820064208912c86092) by [@shubhamguptadream11](https://github.com/shubhamguptadream11))
### Changed
- Fixed a typo in the README file. ([30e75a51f3](https://github.com/facebook/react-native/commit/30e75a51f3af7fbad83e4b002526b69bba021753) by [@Aryan2727-debug](https://github.com/Aryan2727-debug))
- Fix unnececary rerenders of VirtualizedListCells with strictMode={true} ([aafe696453](https://github.com/facebook/react-native/commit/aafe696453186d0e87ae96d0bca4c6650234d222) by [@Tom910](https://github.com/Tom910))
- The `AnimatedNode` graph will not occur during the insertion effect phase, which means animations can now be reliably started during layout effects. ([316170ce8d](https://github.com/facebook/react-native/commit/316170ce8d0aac1df3261c792b9f768665d134c5) by [@yungsters](https://github.com/yungsters))
- AttributedString `appendFragment` and `prependFragment` take an rval instead of a const ref; append/prependAttributedString have been removed ([2c31fe99e1](https://github.com/facebook/react-native/commit/2c31fe99e1cc5bfdb393d4f5c70231a042ea67ef) by [@javache](https://github.com/javache))
- Improved AttributedText generation for raw text nodes. ([2f7957f2fd](https://github.com/facebook/react-native/commit/2f7957f2fd424fdaa980d99a4ff05eb3237d662e) by [@javache](https://github.com/javache))
- Callbacks passed to `animation.start(<callback>)` will be scheduled for execution in a microtask. Previously, there were certain scenarios in which the callback could be synchronously executed by `start`. ([090501d26d](https://github.com/facebook/react-native/commit/090501d26d83be5c5d2df885c60d05ec133d7a54) by [@yungsters](https://github.com/yungsters))
- Optimized the performance of updating `Animated` components. ([f0ffcd4f5d](https://github.com/facebook/react-native/commit/f0ffcd4f5dfeab794fbfa3257bb9a8fd793ff2bc) by [@yungsters](https://github.com/yungsters))
- Bump serve-static to 1.16.2 to fix CVE-2024-43800 ([50e38cc9f1](https://github.com/facebook/react-native/commit/50e38cc9f1e6713228a91ad50f426c4f65e65e1a) by [@cortinico](https://github.com/cortinico))
- Bump Folly to 2024.10.14.00 ([37375d8aba](https://github.com/facebook/react-native/commit/37375d8aba0869531567426466478b0de9a1aea3) by [@alanleedev](https://github.com/alanleedev))
- `useMergeRefs` and components using it (e.g. `Pressable`) now support ref cleanup functions. ([01e210fd28](https://github.com/facebook/react-native/commit/01e210fd28bc961e8c1b5fa454b3c947adda296c) by [@yungsters](https://github.com/yungsters))
- : Update Metro to 0.81.0 ([0902b0af75](https://github.com/facebook/react-native/commit/0902b0af75ba30ec9d4abeda71769d0685637afa) by [@robhogan](https://github.com/robhogan))
- Animations started with incompatible `useNativeDriver` and `AnimatedValue` configurations will now synchronously fail. Previously, spring and timing animations with non-zero delays would throw the error asynchronously. ([fd8cf19625](https://github.com/facebook/react-native/commit/fd8cf1962585aa49e8921475d89c1a5c2423c51c) by [@yungsters](https://github.com/yungsters))
- The `Animation` superclass no longer exposes `__onEnd` as a property. Subclasses must instead invoke `super.start(…)` in their `start()` implementation. ([b3fe06b268](https://github.com/facebook/react-native/commit/b3fe06b2685e526fe2bc420a902a3ccd4e1381df) by [@yungsters](https://github.com/yungsters))
- Simplified Flow types to use `HostInstance` (which changing nominal types). ([177697f539](https://github.com/facebook/react-native/commit/177697f539ec68a47cbb8f57260cebe701589ef1) by [@yungsters](https://github.com/yungsters))
- Upgrade React DevTools to 6.0.0. ([ed4f6d6891](https://github.com/facebook/react-native/commit/ed4f6d68910677ab050e3fef5aaa87e42d582fe0) by [@hoxyq](https://github.com/hoxyq))
- Fix: use public instance in Fiber renderer and expose it from getInspectorDataForViewAtPoint (#31068) ([633ad4933e](https://github.com/facebook/react-native/commit/633ad4933e9514d4168d6dcdb7e56c9a1859482a) by [@hoxyq](https://github.com/hoxyq))
- Get react-native package name from package.json in codegen script ([65575e8399](https://github.com/facebook/react-native/commit/65575e8399a08841a0ccbc5b28cafeee6d41714c) by [@okwasniewski](https://github.com/okwasniewski))
- Bring back shouldSkipStateUpdatesForLoopingAnimations feature flag ([6e0e712c2a](https://github.com/facebook/react-native/commit/6e0e712c2a680cf4b4de1ee5fb25cc5282b242c5) by [@dmytrorykun](https://github.com/dmytrorykun))
- AnimatedNode (and its subclasses) once again implement `toJSON()`. ([7bd4a54968](https://github.com/facebook/react-native/commit/7bd4a5496815943b031b68ca46792560d8d798d8) by [@yungsters](https://github.com/yungsters))
- Do not print Bridgeless Mode is enabled on console anymore ([f3a969f38d](https://github.com/facebook/react-native/commit/f3a969f38d7a2c74bf63ee05c4c819c0873059a9) by [@cortinico](https://github.com/cortinico))
- Bump main to 0.77-main ([120558c0cd](https://github.com/facebook/react-native/commit/120558c0cd6ae50156d2f7b958d3a29fd7ae4623) by [@cipolleschi](https://github.com/cipolleschi))
- Improved the performance of unmounting (and updating, when an enclosing Activity becomes hidden) Animated components ([46abda55b9](https://github.com/facebook/react-native/commit/46abda55b9749dc171e0fec551ba83c027818eb7) by Royi Hagigi)
- AnimatedNode (and its subclasses) no longer implement `toJSON()`. ([fe6228512e](https://github.com/facebook/react-native/commit/fe6228512e076820c9c11869cfe24b19d1abfb58) by [@yungsters](https://github.com/yungsters))
- Animated now resolves `style` to the original prop value if it contains no `AnimatedNode` instances. Previously, it would resolve to a flattened style object. ([ca234ba10e](https://github.com/facebook/react-native/commit/ca234ba10e8d06630da7ea00aac515b222137645) by [@yungsters](https://github.com/yungsters))
- Bump Metro dependencies to 0.81.0-alpha.0 ([40f98b5eee](https://github.com/facebook/react-native/commit/40f98b5eeef18bb9c20a9a2762d0b1d648c4ae91) by [@robhogan](https://github.com/robhogan))
#### Android specific
- Consolidated ReactViewGroup add/remove overrides ([0b22b955f1](https://github.com/facebook/react-native/commit/0b22b955f1494f0e7441a01dd19b3fdf5e20c3dc) by Thomas Nardone)
- Migrated systeminfo module code from Java to Kotlin ([8dc2c90ce5](https://github.com/facebook/react-native/commit/8dc2c90ce5f4b30f4729560aed2412e6d29f39fa) by [@oddlyspaced](https://github.com/oddlyspaced))
- Updating targetSdk to 35 (apps can still choose their own targetSdk regardless of RN version) ([48ea6867a9](https://github.com/facebook/react-native/commit/48ea6867a96bd16dc7aed9af5a8e9ce12a487c22) by [@alanleedev](https://github.com/alanleedev))
- Invocations to JS will now invoke their callbacks immediately if the instance is ready. Surface starts will not wait for the main thread to become available to dispatch the work in JS. ([9fa4845136](https://github.com/facebook/react-native/commit/9fa4845136969ec95ce5615b7ea78feaf0f7f109) by [@javache](https://github.com/javache))
- TurboModules marked as requiring eager init will now be constructed on the mqt_native thread to increase concurrency in React Native init. ([663b5f9d19](https://github.com/facebook/react-native/commit/663b5f9d19a905520bd0aef62cda890f76ef9b6e) by [@javache](https://github.com/javache))
- Reduce visibility of Continuation to internal, although this interface wasn't being exposed in any public API ([7b21b9e69c](https://github.com/facebook/react-native/commit/7b21b9e69c6176c7f66af0e479623ed1c2be0d62) by [@mdvacca](https://github.com/mdvacca))
- Update documentation for ReactHost.destroy() APIs ([443bc32dc4](https://github.com/facebook/react-native/commit/443bc32dc49a86534fce1d6ec0e31c97b8f33053) by [@mdvacca](https://github.com/mdvacca))
- Deprecate CatalystInstance in old architecture ([3e27ef1f6e](https://github.com/facebook/react-native/commit/3e27ef1f6e024bba8725a3bd64e2648ffd6af496) by [@mdvacca](https://github.com/mdvacca))
- Deprecate BridgelessCatalystInstance class ([72bd840dd3](https://github.com/facebook/react-native/commit/72bd840dd3dc7b6e3e88a74ac9ddb000a0cb3a60) by [@mdvacca](https://github.com/mdvacca))
- AGP to 8.7.2 ([e1a1cead43](https://github.com/facebook/react-native/commit/e1a1cead434a6856b2b018274876b9ba8eab706a) by [@cortinico](https://github.com/cortinico))
- Migrate ReactFeatureFlags to Kotlin ([4076dbfc86](https://github.com/facebook/react-native/commit/4076dbfc8651fcd193b886bf63b23728fad466d7) by [@mdvacca](https://github.com/mdvacca))
- Android NDK to 27.1 ([ba061a5d18](https://github.com/facebook/react-native/commit/ba061a5d18176fd455c3aa6350127506dac05211) by [@alanleedev](https://github.com/alanleedev))
- Migrate MainReactPackage to Kotlin (and make it final) ([7bbac8ee27](https://github.com/facebook/react-native/commit/7bbac8ee27daf092b580b57c2c7ee46d2723cd09) by [@cortinico](https://github.com/cortinico))
- Bump fbjni to 0.7.0 ([1c002c7b4e](https://github.com/facebook/react-native/commit/1c002c7b4ea4f22729920e54a9032402247ea350) by [@alanleedev](https://github.com/alanleedev))
- Fresco to 3.4.0 ([091025e18b](https://github.com/facebook/react-native/commit/091025e18b1dc5212031e3ed06bfb6c450e788e2) by [@cortinico](https://github.com/cortinico))
- Bump Kotlin 1.9.x to 2.0.x ([972c2c864c](https://github.com/facebook/react-native/commit/972c2c864c0b563163a36080a13908d1c0a3fb87) by [@cortinico](https://github.com/cortinico))
- Fix: change opacity logic from random to decrement by -0.20 ([af4907025e](https://github.com/facebook/react-native/commit/af4907025ef358c312d469118a52699dcf14507d) by [@sarthak-d11](https://github.com/sarthak-d11))
- Bump Android Gradle Plugin (AGP) to 8.7.0 ([cbc0978bb6](https://github.com/facebook/react-native/commit/cbc0978bb65dcfd2a18a54201c845785a626b1b3) by [@cortinico](https://github.com/cortinico))
- Improve FpsDebugFrameCallback.getTotalTimeMS() accuracy ([d54c25fdae](https://github.com/facebook/react-native/commit/d54c25fdaee4d2642cdbca812b61c6973d3f203d) by [@aamagda](https://github.com/aamagda))
- Update Fresco from 3.2.0 to 3.3.0 ([86d92e41d2](https://github.com/facebook/react-native/commit/86d92e41d2e129d12589848f75dfe2b2db09ed1a) by [@Abbondanzo](https://github.com/Abbondanzo))
- Disabling `outline` props on Android to stay consistent with iOS ([7ab0002799](https://github.com/facebook/react-native/commit/7ab0002799d52a876a8cdd32f25ebef6d431650e) by [@jorge-cab](https://github.com/jorge-cab))
- Gradle to 8.10.1 ([90f89a830a](https://github.com/facebook/react-native/commit/90f89a830acced9e6b8e80ef58aefd7e2c9666a8) by [@cortinico](https://github.com/cortinico))
#### iOS specific
- Make `prefetchImageWithMetadata`'s `queryRootName` nullable in the spec ([4dd60acb7d](https://github.com/facebook/react-native/commit/4dd60acb7ddc2811453e84e3567c1a114fa5e6f9) by [@TheRogue76](https://github.com/TheRogue76))
- Change how components automatically register ([8becc2514d](https://github.com/facebook/react-native/commit/8becc2514d484c99b51ea76f479f06a8fcdd8265) by [@cipolleschi](https://github.com/cipolleschi))
- Stop generating the RCTThirdPartyLibraryComponentProvider ([60b9d3d89e](https://github.com/facebook/react-native/commit/60b9d3d89eba90a945070646c6220b3c03b3aeba) by [@cipolleschi](https://github.com/cipolleschi))
- `RCTSurfaceHostingProxyRootView` no longer has different behavior (whether it calls `start` on the provided *surface*) depending on which initializer is used. Call `start` yourself on the *surface* instead. ([13b93cfdda](https://github.com/facebook/react-native/commit/13b93cfddaa559697968ac1c19e55f7aaa053070) by Nolan O'Brien)
- Use `newArchEnabled` flag in RCTAppDelegate and RCTRootViewFactory ([7e1674fc59](https://github.com/facebook/react-native/commit/7e1674fc59abeeb70d946ee082a829fae4c671b7) by [@okwasniewski](https://github.com/okwasniewski))
- Do not move to the main queue synchronously when starting a new surface ([ab2c47be28](https://github.com/facebook/react-native/commit/ab2c47be285fde99a77d189fd04220ef8ad0933a) by [@cipolleschi](https://github.com/cipolleschi))
- Rename `RCTUIGraphicsImageRenderer` to `RCTMakeUIGraphicsImageRenderer` ([6a09fc09af](https://github.com/facebook/react-native/commit/6a09fc09af8eedbf409ab870d5714e44892b2a16) by [@Saadnajmi](https://github.com/Saadnajmi))
- Refactor RCTDevLoadingView to use constraints ([fbda60e657](https://github.com/facebook/react-native/commit/fbda60e65783d9a3f257cd427cbffc1c9b2cc01b) by [@okwasniewski](https://github.com/okwasniewski))
### Deprecated
#### Android specific
- Deprecated shadows for ReadableNative[Map|Array].[Readable|Writable] ([d424bb9d7c](https://github.com/facebook/react-native/commit/d424bb9d7cf101dc5609e8f787ba8af2a33d0262) by [@javache](https://github.com/javache))
- ReactContext.getFabricUIManager() method ([fb737ca7d3](https://github.com/facebook/react-native/commit/fb737ca7d34b636a3aa337a0935bf9a5a10c641d) by [@mdvacca](https://github.com/mdvacca))
#### iOS specific
- Deprecating RCTBridgeModule batchDidComplete and adding configuration to disable it ([731bd95c43](https://github.com/facebook/react-native/commit/731bd95c430c752126aaaa34e4911ba2b87b382f) by [@philIip](https://github.com/philIip))
### Removed
- Remove `BackHandler.removeEventListener` ([44d619414c](https://github.com/facebook/react-native/commit/44d619414c1de3dbf17a421afa8dbcec7cdab025) by [@retyui](https://github.com/retyui))
- Removed type for useConcurrentRoot from AppRegistry, as it was already ignored ([2ec547ad28](https://github.com/facebook/react-native/commit/2ec547ad28ca914c17e276abb91174dfa0dc87b2) by [@javache](https://github.com/javache))
- Remove "run on iOS" and "run on Android" from the dev server key commands ([19b971ff94](https://github.com/facebook/react-native/commit/19b971ff94a0fe353f82363e788c13f86815663b) by [@huntie](https://github.com/huntie))
- Removed `refs` property from `NativeMethods` TypeScript definition. ([223e98cc4b](https://github.com/facebook/react-native/commit/223e98cc4b656b94b48c88940114bfdc025f8ddf) by [@yungsters](https://github.com/yungsters))
#### Android specific
- Removed hasConstants constructor from ReactModuleInfo ([aec7a66ae8](https://github.com/facebook/react-native/commit/aec7a66ae84bd7689d902686711db8eabc21c1f1) by [@javache](https://github.com/javache))
- Removed TurboReactPackage, which was replaced by BaseReactPackage ([bf5c98cf5e](https://github.com/facebook/react-native/commit/bf5c98cf5e1ce5c041d3d9321a0ba2fd3c755b46) by [@javache](https://github.com/javache))
- DevToolsReactPerfLogger stats gathering now uses an internal API ([f503fe3f10](https://github.com/facebook/react-native/commit/f503fe3f100d96a31fc56451d7846d80ce5c342f) by [@javache](https://github.com/javache))
- BindingImpl is no longer part of the public interface ([18faf68b48](https://github.com/facebook/react-native/commit/18faf68b4825118253cf247572084c4da8f6366e) by [@javache](https://github.com/javache))
- FabricComponents is removed from public API ([300db67b27](https://github.com/facebook/react-native/commit/300db67b270a5d6fc85d27188d0d1089675f89c0) by [@javache](https://github.com/javache))
#### iOS specific
- Remove available for RCTKeyWindow check ([e98c221e5e](https://github.com/facebook/react-native/commit/e98c221e5e54e79c25acd06f14e7d01221823305) by [@okwasniewski](https://github.com/okwasniewski))
### Fixed
- Hermes: revert Intl removal ([4cffff35e0](https://github.com/facebook/react-native/commit/4cffff35e030f256c32bf69c5971dfee4e60723f) by [@robhogan](https://github.com/robhogan))
- Fix the nodes' owners not being updated when `display: contents` is used ([aa53bde21b](https://github.com/facebook/react-native/commit/aa53bde21b8952533cf17ffee234b273766f2133) by [@j-piasecki](https://github.com/j-piasecki))
- dev-middleware: Rewrite URLs in the inspector proxy to cover all configurations, not just Android emulators. ([74995bc90a](https://github.com/facebook/react-native/commit/74995bc90aa039b880e4875ad356d3bce324d902) by [@robhogan](https://github.com/robhogan))
- Fix C++ bridging template compatibility with MSVC ([e6848ba5ba](https://github.com/facebook/react-native/commit/e6848ba5ba997d102cbaf6181c7c8c73e25a0827) by [@acoates-ms](https://github.com/acoates-ms))
- Accessing KeyboardAvoidingEvent event in onLayout handler ([68db74205a](https://github.com/facebook/react-native/commit/68db74205afdd190304eb73ef71710781fa580b9) by [@mhoran](https://github.com/mhoran))
- dev-middleware: Fix URL rewriting where device and debugger reach the server on different ports/protocols. ([5da7ebf99a](https://github.com/facebook/react-native/commit/5da7ebf99ae317c104d8e4bfbf36d3d89f66b5c9) by [@robhogan](https://github.com/robhogan))
- dev-middleware: Regex-escape IP addresses in urlRegex replacements ([aae3e03e57](https://github.com/facebook/react-native/commit/aae3e03e57096c3dc51589a3de240d49a8b9fadf) by [@robhogan](https://github.com/robhogan))
- Fixed jest error from Appearance.js ([ce838a4bcf](https://github.com/facebook/react-native/commit/ce838a4bcfb1c08728b637a9addd24cc6e3477e0) by [@Kudo](https://github.com/Kudo))
- When using Babel with plain JavaScript files, support for additional user syntax plugins should be fixed (now uses Babel's parser instead of hermes-parser). There is no change for JS files annotated with `flow`, where extended JS syntax remains unsupported. ([3de9892353](https://github.com/facebook/react-native/commit/3de989235365504468d2b6c0bb194e944bf1ce8e) by [@huntie](https://github.com/huntie))
- Fix `Appearance.setColorScheme(null)` not resetting color scheme value ([7d63235086](https://github.com/facebook/react-native/commit/7d63235086352d8c424d634c7039551f0a5025dc) by [@sangonz193](https://github.com/sangonz193))
- Fix text not taking full width ([550b0c0ed1](https://github.com/facebook/react-native/commit/550b0c0ed16a64ce58102f15d4657abe92aac71c) by [@s77rt](https://github.com/s77rt))
- Linear gradient start and end point algorithm. ([221d1eceda](https://github.com/facebook/react-native/commit/221d1eceda0e5ab870e96dcdd26e22ab17a3870c) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway))
- Codegen: Support nested objects in arrays ([13780126d3](https://github.com/facebook/react-native/commit/13780126d3cb17ad00c2954f9830a3623812dc3e) by [@tvanlaerhoven](https://github.com/tvanlaerhoven))
- RN DevTools: Don't assume 10.0.2.2 is an alias for localhost unless it's used to establish a connection to the server ([69400be4fc](https://github.com/facebook/react-native/commit/69400be4fc0abd38072f6586f3e7d5b6c33e54be) by [@robhogan](https://github.com/robhogan))
- Do not discard props in the patch when they are not null while using `useNativeProps` ([4c3112c8d8](https://github.com/facebook/react-native/commit/4c3112c8d8685d6c34be9acf07b18871b3cee5b2) by [@cipolleschi](https://github.com/cipolleschi))
- : dev-middleware: Remove URL.canParse, restore compat with Node < 18.17 ([99767d43b0](https://github.com/facebook/react-native/commit/99767d43b04e41c83e3bcbfebe267d6fdc284549) by [@robhogan](https://github.com/robhogan))
- RN DevTools: Fix fetching sources and source maps when the dev-server is remote and not tunnelled via the same port+protocol. ([d1b0e9a30b](https://github.com/facebook/react-native/commit/d1b0e9a30b3afc56b9355453cf7f6e690bdd8aff) by [@robhogan](https://github.com/robhogan))
- Fix npm react-native start when cli-server-api isn't installed ([e0be2efe4e](https://github.com/facebook/react-native/commit/e0be2efe4e80edf99f96a2ae6a25856f6df5e0ca) by [@blakef](https://github.com/blakef))
- AnsiHighlight style in RTL layout ([9a3958a619](https://github.com/facebook/react-native/commit/9a3958a619fddb75ed3c6eddebd94f11c0d00e9f) by [@hexboy](https://github.com/hexboy))
- Fixes typo in ReactHostImpl ([e3f03269c5](https://github.com/facebook/react-native/commit/e3f03269c5cea28977e44ddf5c5125968336b0e6) by [@rozele](https://github.com/rozele))
- TextTransform: capitalize better reflects the web behaviour ([dc2000c875](https://github.com/facebook/react-native/commit/dc2000c8750f42b2f01bdad75455750814d567c6) by [@javache](https://github.com/javache))
- Fix for nodes with `display: contents` not being cleaned in some cases ([a88ddcecc9](https://github.com/facebook/react-native/commit/a88ddcecc93a9fa2d231907439d02b11bac8a944) by [@j-piasecki](https://github.com/j-piasecki))
- Microtasks are now correctly executed after the code evaluation in Console panel of DevTools. ([3dfe22bd27](https://github.com/facebook/react-native/commit/3dfe22bd27429a43b4648c597b71f7965f31ca65) by [@hoxyq](https://github.com/hoxyq))
- Passed height and width as native props to support cases where source is an array. ([45b177f50d](https://github.com/facebook/react-native/commit/45b177f50de624eefcb66bb2d8bc1ffb00855863) by [@shubhamguptadream11](https://github.com/shubhamguptadream11))
- `PerformanceEntryReporter::reportMark` and `PerformanceEntryReporter::reportMeasaure` now return created performance entries. ([32f7b3b4e0](https://github.com/facebook/react-native/commit/32f7b3b4e0b8be1d1138f43c46b3c86d9a64c29a) by [@robik](https://github.com/robik))
- Make Codegen work with local modules ([7b6e8e7765](https://github.com/facebook/react-native/commit/7b6e8e776574e683821133f0c814969d74c4de61) by [@cipolleschi](https://github.com/cipolleschi))
- Fix KeyboardAvoidingView not aware of the keyboard closing it is unmounted ([08bd8ac47d](https://github.com/facebook/react-native/commit/08bd8ac47da60121225e7b281bbf566e2c5a291e) by [@QichenZhu](https://github.com/QichenZhu))
- Fix onEndReached not being called when getItemLayout is present and we scroll past render window ([3485e9ed87](https://github.com/facebook/react-native/commit/3485e9ed871886b3e7408f90d623da5c018da493) by YunPeng Chong)
- Fix cast and control paths errors on windows ([0794fa909b](https://github.com/facebook/react-native/commit/0794fa909b2e06fad5c40dce402c5f14a24bb946) by [@TatianaKapos](https://github.com/TatianaKapos))
- Plumbing to get boxSizing prop to Yoga round 2 ([3ca796edc3](https://github.com/facebook/react-native/commit/3ca796edc327c5287533dcc8f4394033d5398c2d) by [@joevilches](https://github.com/joevilches))
- Fix onEndReached not being called when getItemLayout is present and we scroll past render window ([62b7396bf4](https://github.com/facebook/react-native/commit/62b7396bf45c04bd47e74fe4c1e5b5e59918244d) by [@NickGerleman](https://github.com/NickGerleman))
- TurboModule::get is now a final method, override `create` to customize property lookup ([5b5e150eaf](https://github.com/facebook/react-native/commit/5b5e150eaff015540720225b9e61acb306e1d107) by [@javache](https://github.com/javache))
- Improved types for AnimatedProps ([390925ea39](https://github.com/facebook/react-native/commit/390925ea39eb469768f21cf7069b8f75ccdec09d) by [@javache](https://github.com/javache))
- Upgrade Codegen dependency `jscodeshift@17.0.0` to resolve outdated dependencies ([39c98fb8f8](https://github.com/facebook/react-native/commit/39c98fb8f8af98aa40dc89a1580d6c1901fa86cf) by [@byCedric](https://github.com/byCedric))
- Fixed issues with W3C PointerEvents testsx ([1dcaf823f5](https://github.com/facebook/react-native/commit/1dcaf823f5e7d9b114dd803ce3181aa0b8f827ad) by [@rozele](https://github.com/rozele))
- Fixed issue with W3C PointerEvents tests ([68a6b69b27](https://github.com/facebook/react-native/commit/68a6b69b27275998b4083797942f3e26a92d3adb) by [@rozele](https://github.com/rozele))
- Fix setImmediate/clearTimeout mismatch in NativeAnimatedHelper that could clear an unrelated setTimeout. ([a5dd1be889](https://github.com/facebook/react-native/commit/a5dd1be889be21f8daefbc609702989ec7c156cf) by Benoit Girard)
- Improved error message when no view config is found. ([bca232ad90](https://github.com/facebook/react-native/commit/bca232ad90692da7a87be5e37ee2680380f94bef) by [@javache](https://github.com/javache))
- : Order of operations related to platformConfig propagation in NativeAnimated ([a64183b0c6](https://github.com/facebook/react-native/commit/a64183b0c6a56e9d482c7b8b0f80965493ed87af) by [@rozele](https://github.com/rozele))
- Rename overlayColor prop in Modal to backdropColor ([7aeff18970](https://github.com/facebook/react-native/commit/7aeff18970a2b47cbb3fffc1408e4bb21eec6fed) by [@alanleedev](https://github.com/alanleedev))
- Fix source mapping for codegenNativeCommands ([8fba154b66](https://github.com/facebook/react-native/commit/8fba154b6655b5d87609d7c9f136997141ea5e99) by [@vzaidman](https://github.com/vzaidman))
- Fixed accuracy of FlatList estimations to determine what elements are visible in the rendering window. ([40aaeb7181](https://github.com/facebook/react-native/commit/40aaeb71814a1987482d97fd3170af0add55bc6a) by [@rubennorte](https://github.com/rubennorte))
- Fix type conversion error in react native windows build. ([13db1cb88b](https://github.com/facebook/react-native/commit/13db1cb88bdd454cf19be358d6f0cd62f5a6d0cc) by [@marlenecota](https://github.com/marlenecota))
- Correctly pass down isLooping in parallel animation ([4014aa4528](https://github.com/facebook/react-native/commit/4014aa4528d43e905246850c83007a635938d7cb) by [@zeyap](https://github.com/zeyap))
#### Android specific
- Yoga: Fix YogaConfig getting garbage collected #1678 ([7dcb10b6e7](https://github.com/facebook/react-native/commit/7dcb10b6e7e226034a496eaed5351601ae0a1ae2) by [@michaeltroger](https://github.com/michaeltroger))
- Enable mix-blend-mode on ReactRootView so blending works with app background ([24b0ded3cf](https://github.com/facebook/react-native/commit/24b0ded3cf715bb0e849d9f7ca8cd2d4d42cbf90) by [@jorge-cab](https://github.com/jorge-cab))
- RN DevTools: Fix source loading when using an Android emulator connecting to a dev server on the host. ([ca9c56329f](https://github.com/facebook/react-native/commit/ca9c56329fe548b6631934afee0c9be63e1752a1) by [@robhogan](https://github.com/robhogan))
- Fixes some deadlocks when doing commits and state updates synchronously from the UI thread (e.g.: from reanimated). ([3986eefed1](https://github.com/facebook/react-native/commit/3986eefed1733f305db5410737a96b635f0159e7) by [@rubennorte](https://github.com/rubennorte))
- Ensure setSelection in onAttachedToWindow is within text range ([08759121cd](https://github.com/facebook/react-native/commit/08759121cda3785e4d7ee1f1c82011a3e3a955a9) by [@zeyap](https://github.com/zeyap))
- Fixed crash in legacy ReactFontManager ([3da23f7093](https://github.com/facebook/react-native/commit/3da23f7093730e10aeda6b58f4934a381e226dd2) by [@javache](https://github.com/javache))
- Dispatch onMomentumScrollEnd after programmatic scrolling ([c69e330324](https://github.com/facebook/react-native/commit/c69e330324724a1e363f4786b2b03ee7ff4b35c5) by [@Biki-das](https://github.com/Biki-das))
- RNGP - Do not attempt to substring to 1024 while logging ([e64513bf4e](https://github.com/facebook/react-native/commit/e64513bf4ecce60aff5c04e3bed91b203429d12f) by [@cortinico](https://github.com/cortinico))
- Missing isInvertColorsEnabled implementation for Android ([cc1d2853fb](https://github.com/facebook/react-native/commit/cc1d2853fb2b64adfb884cb30c8d22ce0260be15) by [@oddlyspaced](https://github.com/oddlyspaced))
- Addressed race condition in surface start. ([6ba7cb3102](https://github.com/facebook/react-native/commit/6ba7cb310273a0ecce6a168bf3aae45fb85bf955) by [@javache](https://github.com/javache))
- The definition of ts of resizeMethod attribute is none. ([758892a7d8](https://github.com/facebook/react-native/commit/758892a7d89cc1e316984f8f522738021410f530) by [@nianxiongdi](https://github.com/nianxiongdi))
- Reimplement Android lineHeight positioning/determination ([41265bac6b](https://github.com/facebook/react-native/commit/41265bac6b83ee0bb92d645ace81e314065bf5e0) by [@NickGerleman](https://github.com/NickGerleman))
- Fix legacy arch RTL horizontal ScrollView regression ([bfca7cfe7a](https://github.com/facebook/react-native/commit/bfca7cfe7a8e0da10fdb776100fbc706233c0d8d) by [@NickGerleman](https://github.com/NickGerleman))
- Fix RTL ScrollView position when content smaller than container ([0df59d4f03](https://github.com/facebook/react-native/commit/0df59d4f03f79c0fcb9ede2d21bf4d49c97c21ef) by [@NickGerleman](https://github.com/NickGerleman))
- Avoid null reference exception in bridgeless ReactDelegate ([0d664100bb](https://github.com/facebook/react-native/commit/0d664100bbf608550a5c42a4e9b02c6c5bd0f5b8) by [@rozele](https://github.com/rozele))
- Fix generating empty line at the end of multiline text view when `textAlign` is set to `justify` ([08e8f6adfd](https://github.com/facebook/react-native/commit/08e8f6adfdcdfec59002f34bb7acf35bb842b331) by [@coado](https://github.com/coado))
- Fix Frame Callback not being called after Host Resume ([e8f8ee3c0f](https://github.com/facebook/react-native/commit/e8f8ee3c0f28b8c5751ffaef495adea0b8daf1eb) by [@s77rt](https://github.com/s77rt))
- Fix crash in getViewState when using suspense fallbacks. ([bd133b5dd5](https://github.com/facebook/react-native/commit/bd133b5dd57b18140eae51c6d7aaab02874455c1) by [@javache](https://github.com/javache))
- Text without explicit font styles was potentially cut-off. ([95a5d1c628](https://github.com/facebook/react-native/commit/95a5d1c6287c7301265207d1962ba8b50d178b20) by [@javache](https://github.com/javache))
- Merge Android ViewNativeComponent ViewConfig into BaseViewConfig ([0ba00fc998](https://github.com/facebook/react-native/commit/0ba00fc99891a333d3625db15d9dd832ca7eac88) by [@NickGerleman](https://github.com/NickGerleman))
- Fixed styling on alert dialog titles to wrap two lines and retain bold appearance ([c54b23ff9e](https://github.com/facebook/react-native/commit/c54b23ff9ed7a6bfbb52c081c5afe4b3911d0dd2) by [@Abbondanzo](https://github.com/Abbondanzo))
- Prevent ArrayIndexOutOfBoundsException in permission check ([6aeca53b3e](https://github.com/facebook/react-native/commit/6aeca53b3ed4530e57a31d7a5593ae16b550b985) by [@antFrancon](https://github.com/antFrancon))
- Account for items dynamically scaling with the container when using `maintainVisibleContentPosition` in virtualized lists ([6c19996e10](https://github.com/facebook/react-native/commit/6c19996e10eda97a3501f53a68da246d1f122d01) by [@fabriziocucci](https://github.com/fabriziocucci))
- Apps will no longer fatally crash when trying to draw large images ([483b928224](https://github.com/facebook/react-native/commit/483b92822496fa2e6339f75049a33be1e9567f52) by [@Abbondanzo](https://github.com/Abbondanzo))
- Add missing BaseViewManager props to BaseViewManagerDelegate ([6741fd94ad](https://github.com/facebook/react-native/commit/6741fd94ad26012938caa65a5129f0eca6f2246e) by [@NickGerleman](https://github.com/NickGerleman))
- Fix TextInput caret moving to the beginning when attached to window ([ca0abd1b9e](https://github.com/facebook/react-native/commit/ca0abd1b9ea164a566b39cb9090eaa75647aad5a) by [@QichenZhu](https://github.com/QichenZhu))
- Fix issue where `onDropViewInstance` cleanup was not being handled after `ReactRootView.unmountReactApplication` ([0449630612](https://github.com/facebook/react-native/commit/04496306123c46730b46accb2cd6239531e51fef) by [@rozele](https://github.com/rozele))
- Fix issues with Modals and lifecycle events in multi-surface apps ([1ffef5669c](https://github.com/facebook/react-native/commit/1ffef5669c21f4b2c5fec6bc58a85f95518cf10e) by [@rozele](https://github.com/rozele))
- Fix mising `ANTI_ALIAS_FLAG` when resetting Text Paint ([276e3a7df7](https://github.com/facebook/react-native/commit/276e3a7df7de1b04dec0891fa7ed72917568ee7b) by [@NickGerleman](https://github.com/NickGerleman))
- Fix some cases where we override setBackgroundColor on View-level instead of VM level ([0b0ac81fbe](https://github.com/facebook/react-native/commit/0b0ac81fbeebf819e744b6ecc19d549aaab8406d) by [@NickGerleman](https://github.com/NickGerleman))
- Avoid blocking the main thread when decompressing drawable resources ([420229d669](https://github.com/facebook/react-native/commit/420229d66946320f06485c5a3d3c167eae1a407e) by [@Abbondanzo](https://github.com/Abbondanzo))
- Reenable `setAndroidLayoutDirection` by default ([6cf0cfb5a4](https://github.com/facebook/react-native/commit/6cf0cfb5a47a437b8a17b50b4c70460be15ee1cd) by [@NickGerleman](https://github.com/NickGerleman))
- Properly fix measurement of trailing newlines ([060c594457](https://github.com/facebook/react-native/commit/060c59445740f9b92188d2193623b36c3d859ba7) by [@NickGerleman](https://github.com/NickGerleman))
- Fix crash for Modal not attached to window manager ([eaa780de1c](https://github.com/facebook/react-native/commit/eaa780de1c799bf35fded2914d27b1953b093340) by [@cipolleschi](https://github.com/cipolleschi))
- Fix NPE on ReactTextInputManager.setTextDecorationLine ([41c6ad5597](https://github.com/facebook/react-native/commit/41c6ad55978184cad1a32ec63c2d1f07e8282d5e) by [@cortinico](https://github.com/cortinico))
- BoxShadow now supports platformColor. ([4ede9205a0](https://github.com/facebook/react-native/commit/4ede9205a0559fcaf7ac58a3d70bc902eb23fcb6) by [@javache](https://github.com/javache))
- MixBlendMode now properly does state updates ([fae572d815](https://github.com/facebook/react-native/commit/fae572d815c7fb9684fc6c3b7f001de35ea8fb69) by [@jorge-cab](https://github.com/jorge-cab))
- Fix interactions between removeClippedSubviews and RTL ([513e9669e7](https://github.com/facebook/react-native/commit/513e9669e78a4bfd9b0380335c61f581343c4009) by [@NickGerleman](https://github.com/NickGerleman))
- LayoutAnimations work on full new architecture ([43af902693](https://github.com/facebook/react-native/commit/43af902693f0befde802a7f684e26b19ec7126c8) by [@javache](https://github.com/javache))
- Fix: ReactDelegate/ReactFragment crashing on New Architecture apps ([12dda31bc1](https://github.com/facebook/react-native/commit/12dda31bc12f4a04ec9df70d30328b1001bb2cec) by [@cortinico](https://github.com/cortinico))
- ReactFragment should properly instantiate ReactDelegate on Bridgeless ([7176d11ce4](https://github.com/facebook/react-native/commit/7176d11ce468ca37e9cbe8afcc1f6344c250dd0c) by [@cortinico](https://github.com/cortinico))
- Fixed text being measured incorrectly when ending with an empty line on the new architecture ([bd323929dc](https://github.com/facebook/react-native/commit/bd323929dc5be5666ee36043babec7d981a095dc) by [@j-piasecki](https://github.com/j-piasecki))
- Linear gradient with platform colors ([6866968a79](https://github.com/facebook/react-native/commit/6866968a79d44518884965959760983acdadc17c) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway))
- ARG_DISABLE_HOST_LIFECYCLE_EVENTS in ReactFragment to allow unmounting a surface without destroying ReactHost. ([40c875deca](https://github.com/facebook/react-native/commit/40c875decabaa56d6dd45ce03b22e8b3931781ac) by [@vincenzovitale](https://github.com/vincenzovitale))
- Fixed incorrect scroll event/position for scroll views when doing a smooth scroll animation. ([b4c41ec768](https://github.com/facebook/react-native/commit/b4c41ec7685da6e8ef35c41c30aa402639bc42c1) by [@rubennorte](https://github.com/rubennorte))
- Use appropriate Nullable attribute for ReactRootView field in ReactDelegate ([cbddcfc691](https://github.com/facebook/react-native/commit/cbddcfc6911101608df36f2a8d047768296c63b2) by [@rozele](https://github.com/rozele))
- Hover events were dispatched incorrectly when multiple ReactRoots were layered. ([533ef2ca37](https://github.com/facebook/react-native/commit/533ef2ca37d3b19fc909315f183e3f30dbf4b93d) by [@javache](https://github.com/javache))
- Improve text line height calculation ([65d8f66b50](https://github.com/facebook/react-native/commit/65d8f66b50471d2fb4ddd5e63e17fcc808623110) by [@mellyeliu](https://github.com/mellyeliu))
#### iOS specific
- Fix possible NSRangeException when updating typing attributes in response to new text content ([6e06a810f0](https://github.com/facebook/react-native/commit/6e06a810f0ab1002f1d10351bc878babde36b1f1) by [@NickGerleman](https://github.com/NickGerleman))
- Ensure artifacts directory exists when building Hermes from local source ([c3091ccfed](https://github.com/facebook/react-native/commit/c3091ccfed4440d7f0b906a7eb954718656b71b2) by [@kraenhansen](https://github.com/kraenhansen))
- "Reconnect DevTools" button not working sometimes ([8507204b53](https://github.com/facebook/react-native/commit/8507204b533cf87d1e4345a9c062cd10cf0022c1) by [@EdmondChuiHW](https://github.com/EdmondChuiHW))
- Fixed use of view commands from layout effects ([6f1c2a512e](https://github.com/facebook/react-native/commit/6f1c2a512e44d25edefea53e864f688018745c07) by [@sammy-SC](https://github.com/sammy-SC))
- Fix `r` & `d` not working from Metro sometimes ([9a60038a40](https://github.com/facebook/react-native/commit/9a60038a40e16925ea1adeb3e3c937c22a615485) by [@EdmondChuiHW](https://github.com/EdmondChuiHW))
- Resolve deprecated function prototype warning in RCTAppearance.h ([594c9d9a46](https://github.com/facebook/react-native/commit/594c9d9a46623016abb6bbd0d8f2982bf68bdc34) by [@eli-front](https://github.com/eli-front))
- Fixes rn-tester bundled images examples ([8cbc7c3357](https://github.com/facebook/react-native/commit/8cbc7c3357ac4043e6c423261c090a1bf656f68e) by [@zhongwuzw](https://github.com/zhongwuzw))
- Fixed `onMomentumScrollBegin` event not firing on command-driven scroll events ([5b609cca09](https://github.com/facebook/react-native/commit/5b609cca099b3b0d4fc66d4cf50f69d3c5b7fc8e) by [@Abbondanzo](https://github.com/Abbondanzo))
- Typo in spm.rb ([5e18f7f788](https://github.com/facebook/react-native/commit/5e18f7f788ccbea60e96b8e7deab29d423ccf1a6) by [@okwasniewski](https://github.com/okwasniewski))
- Add png extension only if file exist when load local image ([44f2a08371](https://github.com/facebook/react-native/commit/44f2a083716205b7560bef2f09d25830e29cd0c5) by [@zhongwuzw](https://github.com/zhongwuzw))
- FIxes CornerRadiiAreEqualAndSymmetrical error when check topLeftHorizontal == topLeftVertical ([af384a914a](https://github.com/facebook/react-native/commit/af384a914a4e9ef6a5d25b00bc14b0483e5af879) by [@zhongwuzw](https://github.com/zhongwuzw))
- Fix numerous class interfaces having incorrect designated initializer patterns ([b98846c2e3](https://github.com/facebook/react-native/commit/b98846c2e37c3ec895536ab942978d7701f51a5e) by Nolan O'Brien)
- AutomaticallyAdjustKeyboardInsets not shifting scrollview content ([2d9933e616](https://github.com/facebook/react-native/commit/2d9933e616c3efe57ed0ca141277638182a69d9c) by [@zhongwuzw](https://github.com/zhongwuzw))
- Fix launching App Clips with nullish URLs. ([043e2fe14a](https://github.com/facebook/react-native/commit/043e2fe14a6f13885a552211f17d61292001fa76) by [@EvanBacon](https://github.com/EvanBacon))
- Fixes scrollIndicatorInsets not work in old arch ([c1178ac208](https://github.com/facebook/react-native/commit/c1178ac2085e073afb07453eefc9095a1f5d530f) by [@zhongwuzw](https://github.com/zhongwuzw))
- Silenced 'set but unused variable' warning. ([f7b28e86aa](https://github.com/facebook/react-native/commit/f7b28e86aaded58f76978179d8d83f11e913b026) by [@nlutsenko](https://github.com/nlutsenko))
- Fixed crash on promise rejection handler in iOS 18. ([26d8d490e4](https://github.com/facebook/react-native/commit/26d8d490e47bd3fa46dc4a3b8e66e9ec35c15cf7) by David Rickard)
- Fixed scroll view ([ab8f3ff3e9](https://github.com/facebook/react-native/commit/ab8f3ff3e9e6445fa9961467e965792908d4c2bd) by [@coado](https://github.com/coado))
- Fixes missing char mode of linebreakmode ([77889afa1c](https://github.com/facebook/react-native/commit/77889afa1c9d0bdb966102860a5d1d1d91187ae8) by [@zhongwuzw](https://github.com/zhongwuzw))
- Removed usage of set but unused variable. ([d386dfc804](https://github.com/facebook/react-native/commit/d386dfc804842ed36565966da5aed15d9df7960e) by [@nlutsenko](https://github.com/nlutsenko))
- Cast the UIScene to UIWindowScene only if the scene respond to the selector ([fdee0ebbcb](https://github.com/facebook/react-native/commit/fdee0ebbcb88f40c23b92b07792fbb9d1041c546) by [@cipolleschi](https://github.com/cipolleschi))
- Move RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED to const ([a1ec345e2a](https://github.com/facebook/react-native/commit/a1ec345e2a2cdb4ccf255293616ed5e90f519e40) by [@okwasniewski](https://github.com/okwasniewski))
- Fixes the exported synchronous method not being called on the method queue when it's the main queue ([8bfd7e1039](https://github.com/facebook/react-native/commit/8bfd7e10393e649554c7246df430019c4f78d5e0) by [@zhongwuzw](https://github.com/zhongwuzw))
- Make sure that the Increment and Decrement accessibility actions works on iOS ([303e0ed764](https://github.com/facebook/react-native/commit/303e0ed7641409acf2d852c077f6be426afd7a0c) by [@cipolleschi](https://github.com/cipolleschi))
- Subscribe to orientation changes in RCTUIManager only on iOS ([2f5adc3874](https://github.com/facebook/react-native/commit/2f5adc3874bcdfc8d7d2c3cd5293eefec63a91f8) by [@okwasniewski](https://github.com/okwasniewski))
- Fix ActionSheetIOS crash `attempt to insert nil object from objects` ([bebd6531b5](https://github.com/facebook/react-native/commit/bebd6531b5f4ef0300aa5a4b6f9d23e60b57a25e) by [@RodolfoGS](https://github.com/RodolfoGS))
- Allow pods mixte type settings on post-install ([1e59f2e3f8](https://github.com/facebook/react-native/commit/1e59f2e3f8f0ab3ee4173bddaa089bbecf61d1eb) by [@MasGaNo](https://github.com/MasGaNo))
- Fallback to old resolve mechanism when node require fails to resolve react native path ([3cbaddbc16](https://github.com/facebook/react-native/commit/3cbaddbc164b9dc326b2a7ddc0b35ce885bc7d9d) by [@okwasniewski](https://github.com/okwasniewski))
- Fixed warnings when validating SVC ([de39a204c3](https://github.com/facebook/react-native/commit/de39a204c3588a3c02dc2e72464174c75b3a6749) by [@cipolleschi](https://github.com/cipolleschi))
- Solved SVC warnings for RNTester ([fad4a0783b](https://github.com/facebook/react-native/commit/fad4a0783b0a0478c147d9bde2ef9ab082a08297) by [@cipolleschi](https://github.com/cipolleschi))
- Don't reference PrivacyInfo.xcprivacy twice for new projects ([cadd41b1a2](https://github.com/facebook/react-native/commit/cadd41b1a2e16b1c77a8d3022f4ccbdbd5ea295f) by [@okwasniewski](https://github.com/okwasniewski))
## v0.76.3
### Fixed
+57 -21
View File
@@ -175,6 +175,38 @@ function createMockFunction<TArgs: $ReadOnlyArray<mixed>, TReturn>(
// flowlint unsafe-getters-setters:off
class ErrorWithCustomBlame extends Error {
// Initially 5 to ignore all the frames from Babel helpers to instantiate this
// custom error class.
#ignoredFrameCount: number = 5;
#cachedProcessedStack: ?string;
blameToPreviousFrame(): this {
this.#ignoredFrameCount++;
return this;
}
get stack(): string {
if (this.#cachedProcessedStack == null) {
const originalStack = super.stack;
if (originalStack == null) {
this.#cachedProcessedStack = originalStack;
} else {
const lines = originalStack.split('\n');
lines.splice(1, this.#ignoredFrameCount);
this.#cachedProcessedStack = lines.join('\n');
}
}
return this.#cachedProcessedStack;
}
set stack(value: string) {
// no-op
}
}
class Expect {
#received: mixed;
#isNot: boolean = false;
@@ -191,27 +223,27 @@ class Expect {
toEqual(expected: mixed): void {
const pass = deepEqual(this.#received, expected, {strict: true});
if (!this.#isExpectedResult(pass)) {
throw new Error(
throw new ErrorWithCustomBlame(
`Expected${this.#maybeNotLabel()} to equal ${String(expected)} but received ${String(this.#received)}.`,
);
).blameToPreviousFrame();
}
}
toBe(expected: mixed): void {
const pass = this.#received === expected;
if (!this.#isExpectedResult(pass)) {
throw new Error(
throw new ErrorWithCustomBlame(
`Expected${this.#maybeNotLabel()} ${String(expected)} but received ${String(this.#received)}.`,
);
).blameToPreviousFrame();
}
}
toBeInstanceOf(expected: Class<mixed>): void {
const pass = this.#received instanceof expected;
if (!this.#isExpectedResult(pass)) {
throw new Error(
throw new ErrorWithCustomBlame(
`expected ${String(this.#received)}${this.#maybeNotLabel()} to be an instance of ${String(expected)}`,
);
).blameToPreviousFrame();
}
}
@@ -219,26 +251,26 @@ class Expect {
const pass =
Math.abs(expected - Number(this.#received)) < Math.pow(10, -precision);
if (!this.#isExpectedResult(pass)) {
throw new Error(
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to be close to ${expected}`,
);
).blameToPreviousFrame();
}
}
toBeNull(): void {
const pass = this.#received == null;
if (!this.#isExpectedResult(pass)) {
throw new Error(
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to be null`,
);
).blameToPreviousFrame();
}
}
toThrow(expected?: string): void {
if (expected != null && typeof expected !== 'string') {
throw new Error(
throw new ErrorWithCustomBlame(
'toThrow() implementation only accepts strings as arguments.',
);
).blameToPreviousFrame();
}
let pass = false;
@@ -249,9 +281,9 @@ class Expect {
pass = expected != null ? error.message === expected : true;
}
if (!this.#isExpectedResult(pass)) {
throw new Error(
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to throw`,
);
).blameToPreviousFrame();
}
}
@@ -259,9 +291,9 @@ class Expect {
const mock = this.#requireMock();
const pass = mock.calls.length > 0;
if (!this.#isExpectedResult(pass)) {
throw new Error(
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to have been called, but it was${this.#isNot ? '' : "n't"}`,
);
).blameToPreviousFrame();
}
}
@@ -269,9 +301,9 @@ class Expect {
const mock = this.#requireMock();
const pass = mock.calls.length === times;
if (!this.#isExpectedResult(pass)) {
throw new Error(
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)}${this.#maybeNotLabel()} to have been called ${times} times, but it was called ${mock.calls.length} times`,
);
).blameToPreviousFrame();
}
}
@@ -286,9 +318,11 @@ class Expect {
#requireMock(): JestMockFn<$ReadOnlyArray<mixed>, mixed>['mock'] {
// $FlowExpectedError[incompatible-use]
if (!this.#received?.[MOCK_FN_TAG]) {
throw new Error(
throw new ErrorWithCustomBlame(
`Expected ${String(this.#received)} to be a mock function, but it wasn't`,
);
)
.blameToPreviousFrame()
.blameToPreviousFrame();
}
// $FlowExpectedError[incompatible-use]
@@ -346,7 +380,9 @@ function executeTests() {
result.status = status;
result.duration = Date.now() - start;
result.failureMessages =
status === 'failed' && error ? [error.message] : [];
status === 'failed' && error
? [error.stack ?? error.message ?? String(error)]
: [];
}
}
+1 -1
View File
@@ -77,7 +77,7 @@
"eslint-plugin-redundant-undefined": "^0.4.0",
"eslint-plugin-relay": "^1.8.3",
"flow-api-translator": "0.25.1",
"flow-bin": "^0.254.2",
"flow-bin": "^0.255.0",
"glob": "^7.1.1",
"hermes-eslint": "0.25.1",
"hermes-transform": "0.25.1",
@@ -30,7 +30,6 @@
"metro": "^0.81.0",
"metro-config": "^0.81.0",
"metro-core": "^0.81.0",
"node-fetch": "^2.2.0",
"readline": "^1.3.0",
"semver": "^7.1.3"
},
@@ -12,7 +12,6 @@
import type TerminalReporter from 'metro/src/lib/TerminalReporter';
import chalk from 'chalk';
import fetch from 'node-fetch';
type PageDescription = $ReadOnly<{
id: string,
@@ -10,7 +10,6 @@
*/
import net from 'net';
import fetch from 'node-fetch';
/**
* Determine whether we can run the dev server.
@@ -11,7 +11,7 @@
import type {CreateCustomMessageHandlerFn} from './inspector-proxy/CustomMessageHandler';
import type {BrowserLauncher} from './types/BrowserLauncher';
import type {EventReporter} from './types/EventReporter';
import type {EventReporter, ReportableEvent} from './types/EventReporter';
import type {Experiments, ExperimentsConfig} from './types/Experiments';
import type {Logger} from './types/Logger';
import type {NextHandleFunction} from 'connect';
@@ -81,11 +81,15 @@ export default function createDevMiddleware({
unstable_customInspectorMessageHandler,
}: Options): DevMiddlewareAPI {
const experiments = getExperiments(experimentConfig);
const eventReporter = createWrappedEventReporter(
unstable_eventReporter,
logger,
);
const inspectorProxy = new InspectorProxy(
projectRoot,
serverBaseUrl,
unstable_eventReporter,
eventReporter,
experiments,
unstable_customInspectorMessageHandler,
);
@@ -97,7 +101,7 @@ export default function createDevMiddleware({
serverBaseUrl,
inspectorProxy,
browserLauncher: unstable_browserLauncher,
eventReporter: unstable_eventReporter,
eventReporter,
experiments,
logger,
}),
@@ -129,3 +133,26 @@ function getExperiments(config: ExperimentsConfig): Experiments {
enableNetworkInspector: config.enableNetworkInspector ?? false,
};
}
/**
* Creates a wrapped EventReporter that locally intercepts events to
* log to the terminal.
*/
function createWrappedEventReporter(
reporter: ?EventReporter,
logger: ?Logger,
): EventReporter {
return {
logEvent(event: ReportableEvent) {
switch (event.type) {
case 'profiling_target_registered':
logger?.info(
`Profiling build target "${event.appId}" registered for debugging`,
);
break;
}
reporter?.logEvent(event);
},
};
}
@@ -63,6 +63,7 @@ export type DeviceOptions = $ReadOnly<{
createMessageMiddleware: ?CreateCustomMessageHandlerFn,
deviceRelativeBaseUrl: URL,
serverRelativeBaseUrl: URL,
isProfilingBuild: boolean,
}>;
/**
@@ -140,6 +141,7 @@ export default class Device {
createMessageMiddleware,
serverRelativeBaseUrl,
deviceRelativeBaseUrl,
isProfilingBuild,
}: DeviceOptions) {
this.#id = id;
this.#name = name;
@@ -157,6 +159,10 @@ export default class Device {
: null;
this.#createCustomMessageHandler = createMessageMiddleware;
if (isProfilingBuild) {
this.#deviceEventReporter?.logProfilingTargetRegistered();
}
// $FlowFixMe[incompatible-call]
this.#deviceSocket.on('message', (message: string) => {
this.#messageFromDeviceQueue = this.#messageFromDeviceQueue
@@ -145,6 +145,17 @@ class DeviceEventReporter {
});
}
logProfilingTargetRegistered() {
this.#eventReporter.logEvent({
type: 'profiling_target_registered',
status: 'success',
appId: this.#metadata.appId,
deviceName: this.#metadata.deviceName,
deviceId: this.#metadata.deviceId,
pageId: null,
});
}
logConnection(
connectedEntity: 'debugger',
metadata: $ReadOnly<{
@@ -225,6 +225,7 @@ export default class InspectorProxy implements InspectorProxyQueries {
const deviceId = query.device || fallbackDeviceId;
const deviceName = query.name || 'Unknown';
const appName = query.app || 'Unknown';
const isProfilingBuild = query.profiling === 'true';
const deviceRelativeBaseUrl =
getBaseUrlFromRequest(req) ?? this.#serverBaseUrl;
@@ -242,6 +243,7 @@ export default class InspectorProxy implements InspectorProxyQueries {
createMessageMiddleware: this.#customMessageHandler,
deviceRelativeBaseUrl,
serverRelativeBaseUrl: this.#serverBaseUrl,
isProfilingBuild,
};
if (oldDevice) {
@@ -77,6 +77,11 @@ export type ReportableEvent =
| 'PROTOCOL_ERROR',
>,
}
| {
type: 'profiling_target_registered',
status: 'success',
...DebuggerSessionIDs,
}
| {
type: 'proxy_error',
status: 'error',
@@ -39,7 +39,7 @@ abstract class BuildCodegenCLITask : Exec() {
}
override fun exec() {
val logfile = "${project.layout.buildDirectory}/build-cli.log"
val logfile = "${project.layout.buildDirectory.getAsFile().get()}/build-cli.log"
File(logfile).apply {
parentFile.mkdirs()
if (exists()) {
@@ -2673,7 +2673,7 @@ const UNION_MODULE: SchemaType = {
},
};
const STRING_LITERALS = {
const STRING_LITERALS: SchemaType = {
modules: {
NativeSampleTurboModule: {
type: 'NativeModule',
@@ -121,7 +121,7 @@ const Presets = {
'opacity',
): LayoutAnimationConfig),
linear: (create(500, 'linear', 'opacity'): LayoutAnimationConfig),
spring: {
spring: ({
duration: 700,
create: {
type: 'linear',
@@ -135,7 +135,7 @@ const Presets = {
type: 'linear',
property: 'opacity',
},
},
}: LayoutAnimationConfig),
};
/**
@@ -0,0 +1,39 @@
/**
* 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
* @oncall react_native
*/
import useColorScheme from '../useColorScheme';
describe('useColorScheme', () => {
it('should return a mocked light theme by default', () => {
expect(jest.isMockFunction(useColorScheme)).toBe(true);
expect(useColorScheme()).toBe('light');
});
it('should have console.error when not using mock', () => {
const useColorSchemeActual = jest.requireActual<{
default: typeof useColorScheme,
}>('../useColorScheme').default;
const spy = jest.spyOn(console, 'error').mockImplementationOnce(() => {
// Simulate LogBox console.error() call to throw an error and stop the further execution
throw new Error('console.error() was called');
});
expect(() => {
useColorSchemeActual();
}).toThrow();
expect(spy).toHaveBeenCalledWith(
expect.stringMatching(
/Invalid hook call. Hooks can only be called inside of the body of a function component./,
),
);
});
});
@@ -5609,12 +5609,7 @@ declare function create(
declare const Presets: {
easeInEaseOut: LayoutAnimationConfig,
linear: LayoutAnimationConfig,
spring: {
duration: 700,
create: { type: \\"linear\\", property: \\"opacity\\" },
update: { type: \\"spring\\", springDamping: 0.4 },
delete: { type: \\"linear\\", property: \\"opacity\\" },
},
spring: LayoutAnimationConfig,
};
declare const LayoutAnimation: {
configureNext: configureNext,
@@ -67,28 +67,52 @@
* ScrollView, we force it to be centered, but when you zoom or the content otherwise
* becomes larger than the ScrollView, there is no padding around the content but it
* can still fill the whole view.
* This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/.
*/
- (void)centerContentIfNeeded
{
if (!_centerContent) {
return;
}
CGSize contentSize = self.contentSize;
CGSize boundsSize = self.bounds.size;
if (CGSizeEqualToSize(contentSize, CGSizeZero) || CGSizeEqualToSize(boundsSize, CGSizeZero)) {
return;
}
CGFloat top = 0, left = 0;
if (contentSize.width < boundsSize.width) {
left = (boundsSize.width - contentSize.width) * 0.5f;
}
if (contentSize.height < boundsSize.height) {
top = (boundsSize.height - contentSize.height) * 0.5f;
}
self.contentInset = UIEdgeInsetsMake(top, left, top, left);
}
- (void)setContentOffset:(CGPoint)contentOffset
{
if (_isSetContentOffsetDisabled) {
return;
}
if (_centerContent && !CGSizeEqualToSize(self.contentSize, CGSizeZero)) {
CGSize scrollViewSize = self.bounds.size;
if (self.contentSize.width <= scrollViewSize.width) {
contentOffset.x = -(scrollViewSize.width - self.contentSize.width) / 2.0;
}
if (self.contentSize.height <= scrollViewSize.height) {
contentOffset.y = -(scrollViewSize.height - self.contentSize.height) / 2.0;
}
}
super.contentOffset = CGPointMake(
RCTSanitizeNaNValue(contentOffset.x, @"scrollView.contentOffset.x"),
RCTSanitizeNaNValue(contentOffset.y, @"scrollView.contentOffset.y"));
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
[self centerContentIfNeeded];
}
- (void)didAddSubview:(UIView *)subview
{
[super didAddSubview:subview];
[self centerContentIfNeeded];
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
if ([_overridingDelegate respondsToSelector:@selector(touchesShouldCancelInContentView:)]) {
@@ -258,6 +282,11 @@
}
}
- (void)scrollViewDidZoom:(__unused UIScrollView *)scrollView
{
[self centerContentIfNeeded];
}
#pragma mark -
- (BOOL)isHorizontal:(UIScrollView *)scrollView
@@ -159,26 +159,8 @@
return !shouldDisableScrollInteraction;
}
/*
* Automatically centers the content such that if the content is smaller than the
* ScrollView, we force it to be centered, but when you zoom or the content otherwise
* becomes larger than the ScrollView, there is no padding around the content but it
* can still fill the whole view.
*/
- (void)setContentOffset:(CGPoint)contentOffset
{
UIView *contentView = [self contentView];
if (contentView && _centerContent && !CGSizeEqualToSize(contentView.frame.size, CGSizeZero)) {
CGSize subviewSize = contentView.frame.size;
CGSize scrollViewSize = self.bounds.size;
if (subviewSize.width <= scrollViewSize.width) {
contentOffset.x = -(scrollViewSize.width - subviewSize.width) / 2.0;
}
if (subviewSize.height <= scrollViewSize.height) {
contentOffset.y = -(scrollViewSize.height - subviewSize.height) / 2.0;
}
}
super.contentOffset = CGPointMake(
RCTSanitizeNaNValue(contentOffset.x, @"scrollView.contentOffset.x"),
RCTSanitizeNaNValue(contentOffset.y, @"scrollView.contentOffset.y"));
@@ -433,6 +415,12 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(
// Does nothing
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
[self centerContentIfNeeded];
}
- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
{
[super insertReactSubview:view atIndex:atIndex];
@@ -450,6 +438,8 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(
RCTApplyTransformationAccordingLayoutDirection(_contentView, self.reactLayoutDirection);
[_scrollView addSubview:view];
}
[self centerContentIfNeeded];
}
- (void)removeReactSubview:(UIView *)subview
@@ -658,9 +648,45 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(
}
RCT_SCROLL_EVENT_HANDLER(scrollViewWillBeginDecelerating, onMomentumScrollBegin)
RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, onScroll)
RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
[self centerContentIfNeeded];
RCT_SEND_SCROLL_EVENT(onScroll, nil);
RCT_FORWARD_SCROLL_EVENT(scrollViewDidZoom : scrollView);
}
/*
* Automatically centers the content such that if the content is smaller than the
* ScrollView, we force it to be centered, but when you zoom or the content otherwise
* becomes larger than the ScrollView, there is no padding around the content but it
* can still fill the whole view.
* This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/.
*/
- (void)centerContentIfNeeded
{
if (!_scrollView.centerContent) {
return;
}
CGSize contentSize = self.contentSize;
CGSize boundsSize = self.bounds.size;
if (CGSizeEqualToSize(contentSize, CGSizeZero) || CGSizeEqualToSize(boundsSize, CGSizeZero)) {
return;
}
CGFloat top = 0, left = 0;
if (contentSize.width < boundsSize.width) {
left = (boundsSize.width - contentSize.width) * 0.5f;
}
if (contentSize.height < boundsSize.height) {
top = (boundsSize.height - contentSize.height) * 0.5f;
}
_scrollView.contentInset = UIEdgeInsetsMake(top, left, top, left);
}
- (void)addScrollListener:(NSObject<UIScrollViewDelegate> *)scrollListener
{
[_scrollListeners addObject:scrollListener];
@@ -939,6 +965,7 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
CGSize contentSize = self.contentSize;
if (!CGSizeEqualToSize(_scrollView.contentSize, contentSize)) {
_scrollView.contentSize = contentSize;
[self centerContentIfNeeded];
}
}
@@ -2036,9 +2036,9 @@ public final class com/facebook/react/defaults/DefaultReactHost {
public static final field INSTANCE Lcom/facebook/react/defaults/DefaultReactHost;
public static final fun getDefaultReactHost (Landroid/content/Context;Lcom/facebook/react/ReactNativeHost;)Lcom/facebook/react/ReactHost;
public static final fun getDefaultReactHost (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;)Lcom/facebook/react/ReactHost;
public static final fun getDefaultReactHost (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lkotlin/jvm/functions/Function1;)Lcom/facebook/react/ReactHost;
public static final fun getDefaultReactHost (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lkotlin/jvm/functions/Function1;Lcom/facebook/react/runtime/BindingsInstaller;)Lcom/facebook/react/ReactHost;
public static synthetic fun getDefaultReactHost$default (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;ILjava/lang/Object;)Lcom/facebook/react/ReactHost;
public static synthetic fun getDefaultReactHost$default (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/facebook/react/ReactHost;
public static synthetic fun getDefaultReactHost$default (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lkotlin/jvm/functions/Function1;Lcom/facebook/react/runtime/BindingsInstaller;ILjava/lang/Object;)Lcom/facebook/react/ReactHost;
}
public abstract class com/facebook/react/defaults/DefaultReactNativeHost : com/facebook/react/ReactNativeHost {
@@ -2219,6 +2219,7 @@ public abstract interface class com/facebook/react/devsupport/HMRClient : com/fa
public final class com/facebook/react/devsupport/InspectorFlags {
public static final field INSTANCE Lcom/facebook/react/devsupport/InspectorFlags;
public static final fun getFuseboxEnabled ()Z
public static final fun getIsProfilingBuild ()Z
}
public class com/facebook/react/devsupport/InspectorPackagerConnection : com/facebook/react/devsupport/IInspectorPackagerConnection {
@@ -2760,6 +2761,7 @@ public class com/facebook/react/fabric/mounting/MountingManager {
public fun attachRootView (ILandroid/view/View;Lcom/facebook/react/uimanager/ThemedReactContext;)V
public fun clearJSResponder ()V
public fun enqueuePendingEvent (IILjava/lang/String;ZLcom/facebook/react/bridge/WritableMap;I)V
public fun experimental_prefetchResource (Lcom/facebook/react/bridge/ReactContext;Ljava/lang/String;IILcom/facebook/react/common/mapbuffer/MapBuffer;)V
public fun getEventEmitter (II)Lcom/facebook/react/fabric/events/EventEmitterWrapper;
public fun getSurfaceManager (I)Lcom/facebook/react/fabric/mounting/SurfaceMountingManager;
public fun getSurfaceManagerEnforced (ILjava/lang/String;)Lcom/facebook/react/fabric/mounting/SurfaceMountingManager;
@@ -5281,6 +5283,8 @@ public abstract class com/facebook/react/uimanager/ViewManager : com/facebook/re
public fun createView (ILcom/facebook/react/uimanager/ThemedReactContext;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;Lcom/facebook/react/touch/JSResponderHandler;)Landroid/view/View;
protected fun createViewInstance (ILcom/facebook/react/uimanager/ThemedReactContext;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Landroid/view/View;
protected abstract fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View;
protected fun experimental_isPrefetchingEnabled ()Z
public fun experimental_prefetchResource (Lcom/facebook/react/bridge/ReactContext;IILcom/facebook/react/common/mapbuffer/MapBuffer;)V
public fun getCommandsMap ()Ljava/util/Map;
protected fun getDelegate ()Lcom/facebook/react/uimanager/ViewManagerDelegate;
public fun getExportedCustomBubblingEventTypeConstants ()Ljava/util/Map;
@@ -16,6 +16,7 @@ import com.facebook.react.bridge.ReactContext
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.common.build.ReactBuildConfig
import com.facebook.react.fabric.ComponentFactory
import com.facebook.react.runtime.BindingsInstaller
import com.facebook.react.runtime.JSCInstance
import com.facebook.react.runtime.ReactHostImpl
import com.facebook.react.runtime.cxxreactpackage.CxxReactPackage
@@ -42,11 +43,12 @@ public object DefaultReactHost {
* `index.<platform>`
* @param jsBundleAssetPath the path to the JS bundle relative to the assets directory. Will be
* composed in a `asset://...` URL
* @param jsBundleFilePath the path to the JS bundle on the filesystem. Will be composed in a
* `file://...` URL
* @param isHermesEnabled whether to use Hermes as the JS engine, default to true.
* @param useDevSupport whether to enable dev support, default to ReactBuildConfig.DEBUG.
* @param cxxReactPackageProviders a list of cxxreactpackage providers (to register c++ turbo
* modules)
* @param jsBundleLoader a [JSBundleLoader] to use for creating the [ReactHost]
*
* TODO(T186951312): Should this be @UnstableReactNativeAPI?
*/
@@ -70,9 +72,9 @@ public object DefaultReactHost {
jsBundleFilePath,
isHermesEnabled,
useDevSupport,
cxxReactPackageProviders) {
throw it
}
cxxReactPackageProviders,
{ throw it },
null)
/**
* Util function to create a default [ReactHost] to be used in your application. This method is
@@ -84,13 +86,15 @@ public object DefaultReactHost {
* `index.<platform>`
* @param jsBundleAssetPath the path to the JS bundle relative to the assets directory. Will be
* composed in a `asset://...` URL
* @param jsBundleFilePath the path to the JS bundle on the filesystem. Will be composed in a
* `file://...` URL
* @param isHermesEnabled whether to use Hermes as the JS engine, default to true.
* @param useDevSupport whether to enable dev support, default to ReactBuildConfig.DEBUG.
* @param cxxReactPackageProviders a list of cxxreactpackage providers (to register c++ turbo
* modules)
* @param jsBundleLoader a [JSBundleLoader] to use for creating the [ReactHost]
* @param exceptionHandler Callback that can be used by React Native host applications to react to
* exceptions thrown by the internals of React Native.
* @param bindingsInstaller that can be used for installing bindings.
*
* TODO(T186951312): Should this be @UnstableReactNativeAPI?
*/
@@ -106,6 +110,7 @@ public object DefaultReactHost {
useDevSupport: Boolean = ReactBuildConfig.DEBUG,
cxxReactPackageProviders: List<(ReactContext) -> CxxReactPackage> = emptyList(),
exceptionHandler: (Exception) -> Unit = { throw it },
bindingsInstaller: BindingsInstaller? = null,
): ReactHost {
if (reactHost == null) {
@@ -128,6 +133,7 @@ public object DefaultReactHost {
jsBundleLoader = bundleLoader,
reactPackages = packageList,
jsRuntimeFactory = jsRuntimeFactory,
bindingsInstaller = bindingsInstaller,
turboModuleManagerDelegateBuilder = defaultTmmDelegateBuilder,
exceptionHandler = exceptionHandler)
val componentFactory = ComponentFactory()
@@ -9,6 +9,7 @@ package com.facebook.react.devsupport
import android.content.Context
import com.facebook.react.common.SurfaceDelegateFactory
import com.facebook.react.common.build.ReactBuildConfig
import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener
import com.facebook.react.devsupport.interfaces.DevLoadingViewManager
import com.facebook.react.devsupport.interfaces.DevSupportManager
@@ -101,7 +102,11 @@ public class DefaultDevSupportManagerFactory : DevSupportManagerFactory {
useDevSupport: Boolean
): DevSupportManager =
if (!useDevSupport) {
ReleaseDevSupportManager()
if (ReactBuildConfig.UNSTABLE_ENABLE_FUSEBOX_RELEASE) {
PerftestDevSupportManager(applicationContext)
} else {
ReleaseDevSupportManager()
}
} else {
BridgelessDevSupportManager(
applicationContext,
@@ -325,11 +325,12 @@ public class DevServerHelper {
private String getInspectorDeviceUrl() {
return String.format(
Locale.US,
"http://%s/inspector/device?name=%s&app=%s&device=%s",
"http://%s/inspector/device?name=%s&app=%s&device=%s&profiling=%b",
mPackagerConnectionSettings.getDebugServerHost(),
Uri.encode(AndroidInfoHelpers.getFriendlyDeviceName()),
Uri.encode(mPackageName),
Uri.encode(getInspectorDeviceId()));
Uri.encode(getInspectorDeviceId()),
InspectorFlags.getIsProfilingBuild());
}
public void downloadBundleFromURL(
@@ -17,4 +17,6 @@ public object InspectorFlags {
}
@DoNotStrip @JvmStatic public external fun getFuseboxEnabled(): Boolean
@DoNotStrip @JvmStatic public external fun getIsProfilingBuild(): Boolean
}
@@ -427,6 +427,28 @@ public class MountingManager {
attachmentsPositions);
}
/**
* @deprecated 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 surfaceId {@link int} surface ID
* @param reactTag reactTag that should be set as ID of the view instance
* @param params {@link MapBuffer} prefetch request params defined in C++
*/
@AnyThread
@Deprecated
public void experimental_prefetchResource(
ReactContext reactContext,
String componentName,
int surfaceId,
int reactTag,
MapBuffer params) {
mViewManagerRegistry
.get(componentName)
.experimental_prefetchResource(reactContext, surfaceId, reactTag, params);
}
public void enqueuePendingEvent(
int surfaceId,
int reactTag,
@@ -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<<b1ad8179cf22c2e97f623435bf152aab>>
* @generated SignedSource<<6d8d8f4b81d7be882b315d0960499dcb>>
*/
/**
@@ -130,6 +130,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableIOSViewClipToPaddingBox(): Boolean = accessor.enableIOSViewClipToPaddingBox()
/**
* When enabled, Andoid will build and initiate image prefetch requests on ImageShadowNode::layout
*/
@JvmStatic
public fun enableImagePrefetchingAndroid(): Boolean = accessor.enableImagePrefetchingAndroid()
/**
* When enabled, LayoutAnimations API will animate state changes on Android.
*/
@@ -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<<7dd21b62dfe429aecdbd179cb482fb26>>
* @generated SignedSource<<031fce8e8b4c20a3e3d6dbecf94d138a>>
*/
/**
@@ -37,6 +37,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
private var enableFixForViewCommandRaceCache: Boolean? = null
private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null
private var enableIOSViewClipToPaddingBoxCache: Boolean? = null
private var enableImagePrefetchingAndroidCache: Boolean? = null
private var enableLayoutAnimationsOnAndroidCache: Boolean? = null
private var enableLayoutAnimationsOnIOSCache: Boolean? = null
private var enableLongTaskAPICache: Boolean? = null
@@ -219,6 +220,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}
override fun enableImagePrefetchingAndroid(): Boolean {
var cached = enableImagePrefetchingAndroidCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableImagePrefetchingAndroid()
enableImagePrefetchingAndroidCache = cached
}
return cached
}
override fun enableLayoutAnimationsOnAndroid(): Boolean {
var cached = enableLayoutAnimationsOnAndroidCache
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<<fcfded14a5fe05501892993c1f58f3ed>>
* @generated SignedSource<<35811667ac2543e1f64e27bbdb483ec1>>
*/
/**
@@ -62,6 +62,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun enableIOSViewClipToPaddingBox(): Boolean
@DoNotStrip @JvmStatic public external fun enableImagePrefetchingAndroid(): Boolean
@DoNotStrip @JvmStatic public external fun enableLayoutAnimationsOnAndroid(): Boolean
@DoNotStrip @JvmStatic public external fun enableLayoutAnimationsOnIOS(): 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<<86d8dd894e80a788af7f47172d30d33c>>
* @generated SignedSource<<9d829c58e49164a0b2b6b66bc0ce088a>>
*/
/**
@@ -57,6 +57,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun enableIOSViewClipToPaddingBox(): Boolean = false
override fun enableImagePrefetchingAndroid(): Boolean = false
override fun enableLayoutAnimationsOnAndroid(): Boolean = false
override fun enableLayoutAnimationsOnIOS(): Boolean = true
@@ -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<<4bb5173b9ba1d3e620f3a7d613b27ac7>>
* @generated SignedSource<<0121e113410a5b0e14eaf74a3076df2f>>
*/
/**
@@ -41,6 +41,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
private var enableFixForViewCommandRaceCache: Boolean? = null
private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null
private var enableIOSViewClipToPaddingBoxCache: Boolean? = null
private var enableImagePrefetchingAndroidCache: Boolean? = null
private var enableLayoutAnimationsOnAndroidCache: Boolean? = null
private var enableLayoutAnimationsOnIOSCache: Boolean? = null
private var enableLongTaskAPICache: Boolean? = null
@@ -240,6 +241,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun enableImagePrefetchingAndroid(): Boolean {
var cached = enableImagePrefetchingAndroidCache
if (cached == null) {
cached = currentProvider.enableImagePrefetchingAndroid()
accessedFeatureFlags.add("enableImagePrefetchingAndroid")
enableImagePrefetchingAndroidCache = cached
}
return cached
}
override fun enableLayoutAnimationsOnAndroid(): Boolean {
var cached = enableLayoutAnimationsOnAndroidCache
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<<2217f2b9992c9424c3d1d221bdfa2236>>
* @generated SignedSource<<2787d9027695dd14ec6b917a32a1a6de>>
*/
/**
@@ -57,6 +57,8 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun enableIOSViewClipToPaddingBox(): Boolean
@DoNotStrip public fun enableImagePrefetchingAndroid(): Boolean
@DoNotStrip public fun enableLayoutAnimationsOnAndroid(): Boolean
@DoNotStrip public fun enableLayoutAnimationsOnIOS(): Boolean
@@ -60,9 +60,9 @@ internal class ReactOkHttpNetworkFetcher(private val okHttpClient: OkHttpClient)
val headers = OkHttpCompat.getHeadersFromMap(requestHeaders)
val request =
Request.Builder()
.headers(headers)
.cacheControl(cacheControlBuilder.build())
.url(uri.toString())
.headers(headers)
.get()
.build()
fetchWithRequest(fetchState, callback, request)
@@ -194,7 +194,7 @@ public class ReactHostImpl implements ReactHost {
mUIExecutor = uiExecutor;
mMemoryPressureRouter = new MemoryPressureRouter(context);
mAllowPackagerServerAccess = allowPackagerServerAccess;
mUseDevSupport = useDevSupport || ReactBuildConfig.UNSTABLE_ENABLE_FUSEBOX_RELEASE;
mUseDevSupport = useDevSupport;
if (devSupportManagerFactory == null) {
devSupportManagerFactory = new DefaultDevSupportManagerFactory();
}
@@ -130,9 +130,7 @@ final class ReactInstance {
mQueueConfiguration.getNativeModulesQueueThread();
ReactChoreographer.initialize(AndroidChoreographerProvider.getInstance());
if (useDevSupport) {
devSupportManager.startInspector();
}
devSupportManager.startInspector();
JSTimerExecutor jsTimerExecutor = createJSTimerExecutor();
mJavaTimerManager =
@@ -298,6 +298,10 @@ public object BackgroundStyleApplicator {
val borderInsets = compositeBackgroundDrawable.borderInsets
val borderRadius = compositeBackgroundDrawable.borderRadius
/**
* z-ordering of user-provided shadow-list is opposite direction of LayerDrawable z-ordering
* https://drafts.csswg.org/css-backgrounds/#shadow-layers
*/
for (boxShadow in shadows.asReversed()) {
val offsetX = boxShadow.offsetX
val offsetY = boxShadow.offsetY
@@ -14,6 +14,7 @@ import androidx.annotation.Nullable;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.BaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.mapbuffer.MapBuffer;
@@ -488,4 +489,25 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
mRecyclableViews = new HashMap<>();
}
}
/**
* @deprecated THIS PREFETCH METHOD IS EXPERIMENTAL, DO NOT USE IT FOR PRODUCTION CODE, MOST
* LIKELY IT WILL CHANGE OR BE REMOVED IN THE FUTURE.
* <p>Subclasses can override this method to implement custom resource prefetching for the
* ViewManager.
* @param reactContext {@link com.facebook.react.bridge.ReactContext} used for the view.
* @param surfaceId {@link int} surface ID
* @param reactTag reactTag that should be set as ID of the view instance
* @param params {@link MapBuffer} prefetch request params defined in C++
*/
@Deprecated
public void experimental_prefetchResource(
ReactContext reactContext, int surfaceId, int reactTag, MapBuffer params) {
return;
}
@Deprecated
protected boolean experimental_isPrefetchingEnabled() {
return ReactNativeFeatureFlags.enableImagePrefetchingAndroid();
}
}
@@ -138,7 +138,7 @@ internal class BorderDrawable(
@Deprecated("Deprecated in Java")
override fun getOpacity(): Int {
val maxBorderAlpha =
minOf(
maxOf(
(Color.alpha(multiplyColorAlpha(computedBorderColors.left, borderAlpha))),
(Color.alpha(multiplyColorAlpha(computedBorderColors.top, borderAlpha))),
(Color.alpha(multiplyColorAlpha(computedBorderColors.right, borderAlpha))),
@@ -675,10 +675,10 @@ internal class BorderDrawable(
val borderWidth = computeBorderInsets()
// Clip border ONLY if its color is non transparent
if (Color.alpha(computedBorderColors.left) != 0 &&
Color.alpha(computedBorderColors.top) != 0 &&
Color.alpha(computedBorderColors.right) != 0 &&
// Clip border ONLY if at least one edge is non-transparent
if (Color.alpha(computedBorderColors.left) != 0 ||
Color.alpha(computedBorderColors.top) != 0 ||
Color.alpha(computedBorderColors.right) != 0 ||
Color.alpha(computedBorderColors.bottom) != 0) {
innerClipTempRectForBorderRadius?.top =
innerClipTempRectForBorderRadius?.top?.plus(borderWidth.top) ?: 0f
@@ -646,13 +646,13 @@ public class CSSBackgroundDrawable extends Drawable {
colorTop = colorBlockStart;
}
// Clip border ONLY if its color is non transparent
// Clip border ONLY if at least one edge is non-transparent
float pathAdjustment = 0f;
if (Color.alpha(colorLeft) != 0
&& Color.alpha(colorTop) != 0
&& Color.alpha(colorRight) != 0
&& Color.alpha(colorBottom) != 0
&& Color.alpha(borderColor) != 0) {
|| Color.alpha(colorTop) != 0
|| Color.alpha(colorRight) != 0
|| Color.alpha(colorBottom) != 0
|| Color.alpha(borderColor) != 0) {
mInnerClipTempRectForBorderRadius.top += borderWidth.top;
mInnerClipTempRectForBorderRadius.bottom -= borderWidth.bottom;
@@ -178,33 +178,32 @@ public data class BorderRadiusStyle(
width: Float,
height: Float
): ComputedBorderRadius {
val leftInset = topLeft.horizontal + bottomLeft.horizontal
val topInset = topLeft.vertical + topRight.vertical
val rightInset = topRight.horizontal + bottomRight.horizontal
val bottomInset = bottomLeft.vertical + bottomRight.vertical
val leftEdgeRadii = topLeft.vertical + bottomLeft.vertical
val topEdgeRadii = topLeft.horizontal + topRight.horizontal
val rightEdgeRadii = topRight.vertical + bottomRight.vertical
val bottomEdgeRadii = bottomLeft.horizontal + bottomRight.horizontal
val leftInsetScale = if (leftInset > 0) minOf(1.0f, height / leftInset) else 0f
val topInsetScale = if (topInset > 0) minOf(1.0f, width / topInset) else 0f
val rightInsetScale = if (rightInset > 0) minOf(1.0f, height / rightInset) else 0f
val bottomInsetScale = if (bottomInset > 0) minOf(1.0f, width / bottomInset) else 0f
val leftEdgeRadiiScale = if (leftEdgeRadii > 0) minOf(height / leftEdgeRadii, 1f) else 0f
val topEdgeRadiiScale = if (topEdgeRadii > 0) minOf(width / topEdgeRadii, 1f) else 0f
val rightEdgeRadiiScale = if (rightEdgeRadii > 0) minOf(height / rightEdgeRadii, 1f) else 0f
val bottomEdgeRadiiScale = if (bottomEdgeRadii > 0) minOf(width / bottomEdgeRadii, 1f) else 0f
return ComputedBorderRadius(
topLeft =
CornerRadii(
topLeft.horizontal * minOf(topInsetScale, leftInsetScale),
topLeft.vertical * minOf(topInsetScale, leftInsetScale)),
topLeft.horizontal * minOf(topEdgeRadiiScale, leftEdgeRadiiScale),
topLeft.vertical * minOf(topEdgeRadiiScale, leftEdgeRadiiScale)),
topRight =
CornerRadii(
topRight.horizontal * minOf(topInsetScale, rightInsetScale),
topRight.vertical * minOf(topInsetScale, rightInsetScale)),
topRight.horizontal * minOf(rightEdgeRadiiScale, topEdgeRadiiScale),
topRight.vertical * minOf(rightEdgeRadiiScale, topEdgeRadiiScale)),
bottomLeft =
CornerRadii(
bottomLeft.horizontal * minOf(bottomInsetScale, leftInsetScale),
bottomLeft.vertical * minOf(bottomInsetScale, leftInsetScale)),
bottomLeft.horizontal * minOf(bottomEdgeRadiiScale, leftEdgeRadiiScale),
bottomLeft.vertical * minOf(bottomEdgeRadiiScale, leftEdgeRadiiScale)),
bottomRight =
CornerRadii(
bottomRight.horizontal * minOf(bottomInsetScale, rightInsetScale),
bottomRight.vertical * minOf(bottomInsetScale, rightInsetScale)),
)
bottomRight.horizontal * minOf(bottomEdgeRadiiScale, rightEdgeRadiiScale),
bottomRight.vertical * minOf(bottomEdgeRadiiScale, rightEdgeRadiiScale)))
}
}
@@ -14,7 +14,7 @@ public class ShadowStyleSpan(
private val dx: Float,
private val dy: Float,
private val radius: Float,
private val color: Int
public val color: Int
) : CharacterStyle(), ReactSpan {
public override fun updateDrawState(textPaint: TextPaint) {
textPaint.setShadowLayer(radius, dx, dy, color)
@@ -22,6 +22,7 @@ import android.os.Build;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewStructure;
import android.view.animation.Animation;
import androidx.annotation.Nullable;
@@ -56,6 +57,8 @@ import com.facebook.react.uimanager.style.BorderRadiusProp;
import com.facebook.react.uimanager.style.BorderStyle;
import com.facebook.react.uimanager.style.LogicalEdge;
import com.facebook.react.uimanager.style.Overflow;
import java.util.HashSet;
import java.util.Set;
/**
* Backing for a React View. Has support for borders, but since borders aren't common, lazy
@@ -409,6 +412,13 @@ public class ReactViewGroup extends ViewGroup
try {
updateSubviewClipStatus(clippingRect, i, clippedSoFar);
} catch (IndexOutOfBoundsException e) {
int realClippedSoFar = 0;
Set<View> uniqueViews = new HashSet<>();
for (int j = 0; j < i; j++) {
realClippedSoFar += isViewClipped(mAllChildren[j]) ? 1 : 0;
uniqueViews.add(mAllChildren[j]);
}
throw new IllegalStateException(
"Invalid clipping state. i="
+ i
@@ -419,7 +429,11 @@ public class ReactViewGroup extends ViewGroup
+ " allChildrenCount="
+ mAllChildrenCount
+ " recycleCount="
+ mRecycleCount,
+ mRecycleCount
+ " realClippedSoFar="
+ realClippedSoFar
+ " uniqueViewsCount="
+ uniqueViews.size(),
e);
}
if (isViewClipped(mAllChildren[i])) {
@@ -450,7 +464,9 @@ public class ReactViewGroup extends ViewGroup
removeViewInLayout(child);
needUpdateClippingRecursive = true;
} else if (intersects && isViewClipped(child)) {
addViewInLayout(child, idx - clippedSoFar, sDefaultLayoutParam, true);
int adjustedIdx = idx - clippedSoFar;
Assertions.assertCondition(adjustedIdx >= 0);
addViewInLayout(child, adjustedIdx, sDefaultLayoutParam, true);
invalidate();
needUpdateClippingRecursive = true;
} else if (intersects) {
@@ -622,11 +638,12 @@ public class ReactViewGroup extends ViewGroup
/*package*/ void addViewWithSubviewClippingEnabled(
final View child, int index, ViewGroup.LayoutParams params) {
Assertions.assertCondition(mRemoveClippedSubviews);
Rect clippingRect = Assertions.assertNotNull(mClippingRect);
View[] childArray = Assertions.assertNotNull(mAllChildren);
addInArray(child, index);
// we add view as "clipped" and then run {@link #updateSubviewClipStatus} to conditionally
// attach it
Rect clippingRect = Assertions.assertNotNull(mClippingRect);
View[] childArray = Assertions.assertNotNull(mAllChildren);
int clippedSoFar = 0;
for (int i = 0; i < index; i++) {
if (isViewClipped(childArray[i])) {
@@ -694,7 +711,13 @@ public class ReactViewGroup extends ViewGroup
* @return {@code true} if the view has been removed from the ViewGroup.
*/
private boolean isViewClipped(View view) {
return view.getParent() == null;
ViewParent parent = view.getParent();
if (parent == null) {
return true;
} else {
Assertions.assertCondition(parent == this);
return false;
}
}
private int indexOfChildInAllChildren(View child) {
@@ -851,6 +874,7 @@ public class ReactViewGroup extends ViewGroup
BlendMode mixBlendMode = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
&& ViewUtil.getUIManagerType(this) == UIManagerType.FABRIC
&& BlendModeHelper.needsIsolatedLayer(this)) {
mixBlendMode = (BlendMode) child.getTag(R.id.mix_blend_mode);
if (mixBlendMode != null) {
@@ -16,10 +16,19 @@ bool JInspectorFlags::getFuseboxEnabled(jni::alias_ref<jclass> /*unused*/) {
return inspectorFlags.getFuseboxEnabled();
}
bool JInspectorFlags::getIsProfilingBuild(jni::alias_ref<jclass> /*unused*/) {
auto& inspectorFlags = InspectorFlags::getInstance();
return inspectorFlags.getIsProfilingBuild();
}
void JInspectorFlags::registerNatives() {
javaClassLocal()->registerNatives({
makeNativeMethod("getFuseboxEnabled", JInspectorFlags::getFuseboxEnabled),
});
javaClassLocal()->registerNatives({
makeNativeMethod(
"getIsProfilingBuild", JInspectorFlags::getIsProfilingBuild),
});
}
} // namespace facebook::react::jsinspector_modern
@@ -20,6 +20,7 @@ class JInspectorFlags : public jni::JavaClass<JInspectorFlags> {
"Lcom/facebook/react/devsupport/InspectorFlags;";
static bool getFuseboxEnabled(jni::alias_ref<jclass>);
static bool getIsProfilingBuild(jni::alias_ref<jclass>);
static void registerNatives();
@@ -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<<d5ccaecdf8cc2cf6144409658d9076ae>>
* @generated SignedSource<<902b269e45fcb4970c6f8a86818e1940>>
*/
/**
@@ -141,6 +141,12 @@ class ReactNativeFeatureFlagsProviderHolder
return method(javaProvider_);
}
bool enableImagePrefetchingAndroid() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableImagePrefetchingAndroid");
return method(javaProvider_);
}
bool enableLayoutAnimationsOnAndroid() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableLayoutAnimationsOnAndroid");
@@ -398,6 +404,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableIOSViewClipToPaddingBox(
return ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox();
}
bool JReactNativeFeatureFlagsCxxInterop::enableImagePrefetchingAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableImagePrefetchingAndroid();
}
bool JReactNativeFeatureFlagsCxxInterop::enableLayoutAnimationsOnAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableLayoutAnimationsOnAndroid();
@@ -620,6 +631,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"enableIOSViewClipToPaddingBox",
JReactNativeFeatureFlagsCxxInterop::enableIOSViewClipToPaddingBox),
makeNativeMethod(
"enableImagePrefetchingAndroid",
JReactNativeFeatureFlagsCxxInterop::enableImagePrefetchingAndroid),
makeNativeMethod(
"enableLayoutAnimationsOnAndroid",
JReactNativeFeatureFlagsCxxInterop::enableLayoutAnimationsOnAndroid),
@@ -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<<0b07eaeba8112f65ecb18d53b7b893af>>
* @generated SignedSource<<17da0d7937c5c0c533293b86c8cdc9be>>
*/
/**
@@ -81,6 +81,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool enableIOSViewClipToPaddingBox(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableImagePrefetchingAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableLayoutAnimationsOnAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
@@ -0,0 +1,93 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uimanager
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.LayerDrawable
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.uimanager.drawable.BackgroundDrawable
import com.facebook.react.uimanager.drawable.BorderDrawable
import com.facebook.react.uimanager.drawable.CompositeBackgroundDrawable
import com.facebook.react.uimanager.drawable.InsetBoxShadowDrawable
import com.facebook.react.uimanager.drawable.OutlineDrawable
import com.facebook.react.uimanager.drawable.OutsetBoxShadowDrawable
import com.facebook.react.uimanager.style.OutlineStyle
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.MockedStatic
import org.mockito.Mockito.mockStatic
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
@TargetApi(29)
@OptIn(UnstableReactNativeAPI::class)
@RunWith(RobolectricTestRunner::class)
class CompositeBackgroundDrawableTest {
private val ctx: Context = RuntimeEnvironment.getApplication()
private lateinit var rnFeatureFlags: MockedStatic<ReactNativeFeatureFlags>
@Before
fun setup() {
rnFeatureFlags = mockStatic(ReactNativeFeatureFlags::class.java)
rnFeatureFlags
.`when`<Boolean> { ReactNativeFeatureFlags.enableNewBackgroundAndBorderDrawables() }
.thenReturn(true)
}
@Test
fun testCompositeBackgroundDrawableLayerOrdering() {
val background = BackgroundDrawable(ctx)
val outerShadows =
LayerDrawable(arrayOf(OutsetBoxShadowDrawable(ctx, Color.BLACK, 1f, 1f, 0f, 1f)))
val innerShadows =
LayerDrawable(arrayOf(InsetBoxShadowDrawable(ctx, Color.BLACK, 1f, 1f, 0f, 1f)))
val border = BorderDrawable(ctx, null, null, null, null)
val outline =
OutlineDrawable(
ctx,
outlineColor = Color.BLACK,
outlineOffset = 0f,
outlineStyle = OutlineStyle.SOLID,
outlineWidth = 1f)
/** Create CompositeBackgroundDrawable with constructor */
val control =
CompositeBackgroundDrawable(
context = ctx,
outerShadows = outerShadows,
background = background,
border = border,
innerShadows = innerShadows,
outline = outline)
/**
* Create CompositeBackgroundDrawable with shuffled method functions (triggers layer ordering
* logic)
*/
val test = CompositeBackgroundDrawable(ctx)
test.withNewInnerShadow(innerShadows)
test.withNewOuterShadow(outerShadows)
test.withNewBorder(border)
test.withNewOutline(outline)
test.withNewBackground(background)
/** Verify that the two CompositeBackgroundDrawables are equivalent */
assertThat(test.getDrawable(0)).isEqualTo(control.getDrawable(0))
assertThat(test.getDrawable(1)).isEqualTo(control.getDrawable(1))
assertThat(test.getDrawable(2)).isEqualTo(control.getDrawable(2))
assertThat(test.getDrawable(3)).isEqualTo(control.getDrawable(3))
assertThat(test.getDrawable(4)).isEqualTo(control.getDrawable(4))
}
}
@@ -79,10 +79,13 @@ Pod::Spec.new do |s|
s.dependency "fast_float", "6.1.4"
s.dependency "fmt", "11.0.2"
s.dependency "React-featureflags"
s.dependency "React-ImageManager"
s.dependency "React-utils"
s.dependency "Yoga"
add_dependency(s, "React-ImageManager", :additional_framework_paths => [
"react/renderer/components/view/platform/cxx",
"react/renderer/imagemanager/platform/ios",
])
add_dependency(s, "ReactCommon", :subspec => "turbomodule/core")
add_dependency(s, "React-graphics", :additional_framework_paths => ["react/renderer/graphics/platform/ios"])
add_dependency(s, "React-Fabric", :additional_framework_paths => [
@@ -139,7 +139,7 @@ void HostAgent::handleRequest(const cdp::PreparsedRequest& req) {
frontendChannel_(cdp::jsonNotification(
"ReactNativeApplication.metadataUpdated",
hostMetadataToDynamic(hostMetadata_)));
createHostMetadataPayload(hostMetadata_)));
shouldSendOKResponse = true;
isFinishedHandlingRequest = true;
@@ -13,6 +13,8 @@
#include "InstanceTarget.h"
#include "SessionState.h"
#include <jsinspector-modern/InspectorFlags.h>
#include <folly/dynamic.h>
#include <folly/json.h>
@@ -232,7 +234,22 @@ bool HostTargetController::decrementPauseOverlayCounter() {
return true;
}
folly::dynamic hostMetadataToDynamic(const HostTargetMetadata& metadata) {
namespace {
struct StaticHostTargetMetadata {
std::optional<bool> isProfilingBuild;
};
StaticHostTargetMetadata getStaticHostMetadata() {
auto& inspectorFlags = jsinspector_modern::InspectorFlags::getInstance();
return {.isProfilingBuild = inspectorFlags.getIsProfilingBuild()};
}
} // namespace
folly::dynamic createHostMetadataPayload(const HostTargetMetadata& metadata) {
auto staticMetadata = getStaticHostMetadata();
folly::dynamic result = folly::dynamic::object;
if (metadata.appDisplayName) {
@@ -253,6 +270,10 @@ folly::dynamic hostMetadataToDynamic(const HostTargetMetadata& metadata) {
if (metadata.reactNativeVersion) {
result["reactNativeVersion"] = metadata.reactNativeVersion.value();
}
if (staticMetadata.isProfilingBuild) {
result["unstable_isProfilingBuild"] =
staticMetadata.isProfilingBuild.value();
}
return result;
}
@@ -271,6 +271,6 @@ class JSINSPECTOR_EXPORT HostTarget
friend class HostTargetController;
};
folly::dynamic hostMetadataToDynamic(const HostTargetMetadata& metadata);
folly::dynamic createHostMetadataPayload(const HostTargetMetadata& metadata);
} // namespace facebook::react::jsinspector_modern
@@ -21,6 +21,10 @@ bool InspectorFlags::getFuseboxEnabled() const {
return loadFlagsAndAssertUnchanged().fuseboxEnabled;
}
bool InspectorFlags::getIsProfilingBuild() const {
return loadFlagsAndAssertUnchanged().isProfilingBuild;
}
void InspectorFlags::dangerouslyResetFlags() {
*this = InspectorFlags{};
}
@@ -48,6 +52,12 @@ const InspectorFlags::Values& InspectorFlags::loadFlagsAndAssertUnchanged()
true,
#else
ReactNativeFeatureFlags::fuseboxEnabledRelease(),
#endif
.isProfilingBuild =
#if defined(REACT_NATIVE_ENABLE_FUSEBOX_RELEASE)
true,
#else
false,
#endif
};
@@ -24,6 +24,12 @@ class InspectorFlags {
*/
bool getFuseboxEnabled() const;
/**
* Flag determining if this is a profiling build
* (react_native.enable_fusebox_release).
*/
bool getIsProfilingBuild() const;
/**
* Reset flags to their upstream values. The caller must ensure any resources
* that have read previous flag values have been cleaned up.
@@ -33,6 +39,7 @@ class InspectorFlags {
private:
struct Values {
bool fuseboxEnabled;
bool isProfilingBuild;
bool operator==(const Values&) const = default;
};
@@ -373,7 +373,8 @@ TYPED_TEST(JsiIntegrationPortableTest, ReactNativeApplicationEnable) {
this->expectMessageFromPage(JsonEq(R"({
"method": "ReactNativeApplication.metadataUpdated",
"params": {
"integrationName": "JsiIntegrationTest"
"integrationName": "JsiIntegrationTest",
"unstable_isProfilingBuild": false
}
})"));
@@ -20,6 +20,7 @@ struct InspectorFlagOverrides {
// NOTE: Keep these entries in sync with ReactNativeFeatureFlagsOverrides in
// the implementation file.
std::optional<bool> fuseboxEnabledDebug;
std::optional<bool> isProfilingBuild;
};
/**
@@ -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<<90e3ea3abb6f13c711aec3754ab03126>>
* @generated SignedSource<<ef215623465d45c563030d724287b1c9>>
*/
/**
@@ -94,6 +94,10 @@ bool ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox() {
return getAccessor().enableIOSViewClipToPaddingBox();
}
bool ReactNativeFeatureFlags::enableImagePrefetchingAndroid() {
return getAccessor().enableImagePrefetchingAndroid();
}
bool ReactNativeFeatureFlags::enableLayoutAnimationsOnAndroid() {
return getAccessor().enableLayoutAnimationsOnAndroid();
}
@@ -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<<4544b1e206765808859ef84c2e6333a9>>
* @generated SignedSource<<f741660e4cf2528defe0ab1f61858aab>>
*/
/**
@@ -124,6 +124,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool enableIOSViewClipToPaddingBox();
/**
* When enabled, Andoid will build and initiate image prefetch requests on ImageShadowNode::layout
*/
RN_EXPORT static bool enableImagePrefetchingAndroid();
/**
* When enabled, LayoutAnimations API will animate state changes on Android.
*/
@@ -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<<cd77cfb18c0099b88035ff42fcd2dd46>>
* @generated SignedSource<<4c3956150bbf826c2abf4f8daf569b88>>
*/
/**
@@ -335,6 +335,24 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() {
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() {
auto flagValue = enableImagePrefetchingAndroid_.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(17, "enableImagePrefetchingAndroid");
flagValue = currentProvider_->enableImagePrefetchingAndroid();
enableImagePrefetchingAndroid_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() {
auto flagValue = enableLayoutAnimationsOnAndroid_.load();
@@ -344,7 +362,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(17, "enableLayoutAnimationsOnAndroid");
markFlagAsAccessed(18, "enableLayoutAnimationsOnAndroid");
flagValue = currentProvider_->enableLayoutAnimationsOnAndroid();
enableLayoutAnimationsOnAndroid_ = flagValue;
@@ -362,7 +380,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(18, "enableLayoutAnimationsOnIOS");
markFlagAsAccessed(19, "enableLayoutAnimationsOnIOS");
flagValue = currentProvider_->enableLayoutAnimationsOnIOS();
enableLayoutAnimationsOnIOS_ = flagValue;
@@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(19, "enableLongTaskAPI");
markFlagAsAccessed(20, "enableLongTaskAPI");
flagValue = currentProvider_->enableLongTaskAPI();
enableLongTaskAPI_ = flagValue;
@@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNewBackgroundAndBorderDrawables() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(20, "enableNewBackgroundAndBorderDrawables");
markFlagAsAccessed(21, "enableNewBackgroundAndBorderDrawables");
flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables();
enableNewBackgroundAndBorderDrawables_ = flagValue;
@@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreciseSchedulingForPremountItemsOnA
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(21, "enablePreciseSchedulingForPremountItemsOnAndroid");
markFlagAsAccessed(22, "enablePreciseSchedulingForPremountItemsOnAndroid");
flagValue = currentProvider_->enablePreciseSchedulingForPremountItemsOnAndroid();
enablePreciseSchedulingForPremountItemsOnAndroid_ = flagValue;
@@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(22, "enablePropsUpdateReconciliationAndroid");
markFlagAsAccessed(23, "enablePropsUpdateReconciliationAndroid");
flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid();
enablePropsUpdateReconciliationAndroid_ = flagValue;
@@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableReportEventPaintTime() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(23, "enableReportEventPaintTime");
markFlagAsAccessed(24, "enableReportEventPaintTime");
flagValue = currentProvider_->enableReportEventPaintTime();
enableReportEventPaintTime_ = flagValue;
@@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(24, "enableSynchronousStateUpdates");
markFlagAsAccessed(25, "enableSynchronousStateUpdates");
flagValue = currentProvider_->enableSynchronousStateUpdates();
enableSynchronousStateUpdates_ = flagValue;
@@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(25, "enableUIConsistency");
markFlagAsAccessed(26, "enableUIConsistency");
flagValue = currentProvider_->enableUIConsistency();
enableUIConsistency_ = flagValue;
@@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(26, "enableViewRecycling");
markFlagAsAccessed(27, "enableViewRecycling");
flagValue = currentProvider_->enableViewRecycling();
enableViewRecycling_ = flagValue;
@@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::excludeYogaFromRawProps() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(27, "excludeYogaFromRawProps");
markFlagAsAccessed(28, "excludeYogaFromRawProps");
flagValue = currentProvider_->excludeYogaFromRawProps();
excludeYogaFromRawProps_ = flagValue;
@@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(28, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
markFlagAsAccessed(29, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact();
fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue;
@@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMountingCoordinatorReportedPendingTrans
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(29, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid");
markFlagAsAccessed(30, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid");
flagValue = currentProvider_->fixMountingCoordinatorReportedPendingTransactionsOnAndroid();
fixMountingCoordinatorReportedPendingTransactionsOnAndroid_ = flagValue;
@@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledDebug() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(30, "fuseboxEnabledDebug");
markFlagAsAccessed(31, "fuseboxEnabledDebug");
flagValue = currentProvider_->fuseboxEnabledDebug();
fuseboxEnabledDebug_ = flagValue;
@@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(31, "fuseboxEnabledRelease");
markFlagAsAccessed(32, "fuseboxEnabledRelease");
flagValue = currentProvider_->fuseboxEnabledRelease();
fuseboxEnabledRelease_ = flagValue;
@@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::initEagerTurboModulesOnNativeModulesQueueA
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(32, "initEagerTurboModulesOnNativeModulesQueueAndroid");
markFlagAsAccessed(33, "initEagerTurboModulesOnNativeModulesQueueAndroid");
flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid();
initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue;
@@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(33, "lazyAnimationCallbacks");
markFlagAsAccessed(34, "lazyAnimationCallbacks");
flagValue = currentProvider_->lazyAnimationCallbacks();
lazyAnimationCallbacks_ = flagValue;
@@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::loadVectorDrawablesOnImages() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(34, "loadVectorDrawablesOnImages");
markFlagAsAccessed(35, "loadVectorDrawablesOnImages");
flagValue = currentProvider_->loadVectorDrawablesOnImages();
loadVectorDrawablesOnImages_ = flagValue;
@@ -668,7 +686,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(35, "traceTurboModulePromiseRejectionsOnAndroid");
markFlagAsAccessed(36, "traceTurboModulePromiseRejectionsOnAndroid");
flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid();
traceTurboModulePromiseRejectionsOnAndroid_ = flagValue;
@@ -686,7 +704,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(36, "useAlwaysAvailableJSErrorHandling");
markFlagAsAccessed(37, "useAlwaysAvailableJSErrorHandling");
flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling();
useAlwaysAvailableJSErrorHandling_ = flagValue;
@@ -704,7 +722,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(37, "useFabricInterop");
markFlagAsAccessed(38, "useFabricInterop");
flagValue = currentProvider_->useFabricInterop();
useFabricInterop_ = flagValue;
@@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless()
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(38, "useImmediateExecutorInAndroidBridgeless");
markFlagAsAccessed(39, "useImmediateExecutorInAndroidBridgeless");
flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless();
useImmediateExecutorInAndroidBridgeless_ = flagValue;
@@ -740,7 +758,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(39, "useNativeViewConfigsInBridgelessMode");
markFlagAsAccessed(40, "useNativeViewConfigsInBridgelessMode");
flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode();
useNativeViewConfigsInBridgelessMode_ = flagValue;
@@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimisedViewPreallocationOnAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(40, "useOptimisedViewPreallocationOnAndroid");
markFlagAsAccessed(41, "useOptimisedViewPreallocationOnAndroid");
flagValue = currentProvider_->useOptimisedViewPreallocationOnAndroid();
useOptimisedViewPreallocationOnAndroid_ = flagValue;
@@ -776,7 +794,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(41, "useOptimizedEventBatchingOnAndroid");
markFlagAsAccessed(42, "useOptimizedEventBatchingOnAndroid");
flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid();
useOptimizedEventBatchingOnAndroid_ = flagValue;
@@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(42, "useRuntimeShadowNodeReferenceUpdate");
markFlagAsAccessed(43, "useRuntimeShadowNodeReferenceUpdate");
flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate();
useRuntimeShadowNodeReferenceUpdate_ = flagValue;
@@ -812,7 +830,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(43, "useTurboModuleInterop");
markFlagAsAccessed(44, "useTurboModuleInterop");
flagValue = currentProvider_->useTurboModuleInterop();
useTurboModuleInterop_ = flagValue;
@@ -830,7 +848,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(44, "useTurboModules");
markFlagAsAccessed(45, "useTurboModules");
flagValue = currentProvider_->useTurboModules();
useTurboModules_ = 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<<6f11d494553e3f12b2ca326a880746f3>>
* @generated SignedSource<<3d98085a73dfc51541342dbb42ed89ab>>
*/
/**
@@ -49,6 +49,7 @@ class ReactNativeFeatureFlagsAccessor {
bool enableFixForViewCommandRace();
bool enableGranularShadowTreeStateReconciliation();
bool enableIOSViewClipToPaddingBox();
bool enableImagePrefetchingAndroid();
bool enableLayoutAnimationsOnAndroid();
bool enableLayoutAnimationsOnIOS();
bool enableLongTaskAPI();
@@ -88,7 +89,7 @@ class ReactNativeFeatureFlagsAccessor {
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
bool wasOverridden_;
std::array<std::atomic<const char*>, 45> accessedFeatureFlags_;
std::array<std::atomic<const char*>, 46> accessedFeatureFlags_;
std::atomic<std::optional<bool>> commonTestFlag_;
std::atomic<std::optional<bool>> completeReactInstanceCreationOnBgThreadOnAndroid_;
@@ -107,6 +108,7 @@ class ReactNativeFeatureFlagsAccessor {
std::atomic<std::optional<bool>> enableFixForViewCommandRace_;
std::atomic<std::optional<bool>> enableGranularShadowTreeStateReconciliation_;
std::atomic<std::optional<bool>> enableIOSViewClipToPaddingBox_;
std::atomic<std::optional<bool>> enableImagePrefetchingAndroid_;
std::atomic<std::optional<bool>> enableLayoutAnimationsOnAndroid_;
std::atomic<std::optional<bool>> enableLayoutAnimationsOnIOS_;
std::atomic<std::optional<bool>> enableLongTaskAPI_;
@@ -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<<213e1ad83360a79e27d41c06e20fb8c9>>
* @generated SignedSource<<aff3c46b8d2db3bde519e1392569d53d>>
*/
/**
@@ -95,6 +95,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool enableImagePrefetchingAndroid() override {
return false;
}
bool enableLayoutAnimationsOnAndroid() 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<<5b2b2aba574e77851ad214809ead9228>>
* @generated SignedSource<<8f8c7a372cdf9a3c06bc0d71f1ed85ad>>
*/
/**
@@ -42,6 +42,7 @@ class ReactNativeFeatureFlagsProvider {
virtual bool enableFixForViewCommandRace() = 0;
virtual bool enableGranularShadowTreeStateReconciliation() = 0;
virtual bool enableIOSViewClipToPaddingBox() = 0;
virtual bool enableImagePrefetchingAndroid() = 0;
virtual bool enableLayoutAnimationsOnAndroid() = 0;
virtual bool enableLayoutAnimationsOnIOS() = 0;
virtual bool enableLongTaskAPI() = 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<<aeb742608efce797a86b73e243a62d0c>>
* @generated SignedSource<<4808c1455f8e17c42036055dd6a81d7d>>
*/
/**
@@ -129,6 +129,11 @@ bool NativeReactNativeFeatureFlags::enableIOSViewClipToPaddingBox(
return ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox();
}
bool NativeReactNativeFeatureFlags::enableImagePrefetchingAndroid(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableImagePrefetchingAndroid();
}
bool NativeReactNativeFeatureFlags::enableLayoutAnimationsOnAndroid(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableLayoutAnimationsOnAndroid();
@@ -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<<b42cf9d00bd5b0d01f3d14b633771201>>
* @generated SignedSource<<6b4909879b76908792d89e3f24c1453a>>
*/
/**
@@ -71,6 +71,8 @@ class NativeReactNativeFeatureFlags
bool enableIOSViewClipToPaddingBox(jsi::Runtime& runtime);
bool enableImagePrefetchingAndroid(jsi::Runtime& runtime);
bool enableLayoutAnimationsOnAndroid(jsi::Runtime& runtime);
bool enableLayoutAnimationsOnIOS(jsi::Runtime& runtime);
@@ -10,6 +10,7 @@
#include <react/renderer/components/image/ImageShadowNode.h>
#include <react/renderer/core/LayoutContext.h>
#include <react/renderer/imagemanager/ImageRequestParams.h>
#include "ImageState.h"
namespace facebook::react {
@@ -24,20 +25,30 @@ void ImageShadowNode::setImageManager(const SharedImageManager& imageManager) {
void ImageShadowNode::updateStateIfNeeded() {
ensureUnsealed();
auto imageSource = getImageSource();
const auto& currentState = getStateData();
bool hasSameRadius =
getConcreteProps().blurRadius == currentState.getBlurRadius();
bool hasSameImageSource = currentState.getImageSource() == imageSource;
const auto& savedState = getStateData();
const auto& oldImageSource = savedState.getImageSource();
auto newImageSource = getImageSource();
const auto& oldImageRequestParams = savedState.getImageRequestParams();
const auto& imageProps = getConcreteProps();
const auto& newImageRequestParams = ImageRequestParams(imageProps.blurRadius);
if (hasSameImageSource && hasSameRadius) {
if (oldImageSource == newImageSource &&
oldImageRequestParams == newImageRequestParams) {
return;
}
auto state = ImageState{
imageSource,
imageManager_->requestImage(imageSource, getSurfaceId()),
getConcreteProps().blurRadius};
newImageSource,
imageManager_->requestImage(
newImageSource,
getSurfaceId()
#ifdef ANDROID
,
newImageRequestParams,
getTag()
#endif
),
newImageRequestParams};
setStateData(std::move(state));
}
@@ -46,7 +46,7 @@ class ImageShadowNode final : public ConcreteViewShadowNode<
const ShadowNodeFamily::Shared& /*family*/,
const ComponentDescriptor& componentDescriptor) {
auto imageSource = ImageSource{ImageSource::Type::Invalid};
return {imageSource, {imageSource, nullptr}, 0};
return {imageSource, {imageSource, nullptr}, {}};
}
#pragma mark - LayoutableShadowNode
@@ -16,9 +16,8 @@ ImageSource ImageState::getImageSource() const {
const ImageRequest& ImageState::getImageRequest() const {
return *imageRequest_;
}
Float ImageState::getBlurRadius() const {
return blurRadius_;
const ImageRequestParams& ImageState::getImageRequestParams() const {
return imageRequestParams_;
}
} // namespace facebook::react
@@ -8,6 +8,7 @@
#pragma once
#include <react/renderer/imagemanager/ImageRequest.h>
#include <react/renderer/imagemanager/ImageRequestParams.h>
#include <react/renderer/imagemanager/primitives.h>
#ifdef ANDROID
@@ -26,10 +27,10 @@ class ImageState final {
ImageState(
const ImageSource& imageSource,
ImageRequest imageRequest,
const Float blurRadius)
const ImageRequestParams& imageRequestParams)
: imageSource_(imageSource),
imageRequest_(std::make_shared<ImageRequest>(std::move(imageRequest))),
blurRadius_(blurRadius){};
imageRequestParams_(imageRequestParams) {}
/*
* Returns stored ImageSource object.
@@ -42,11 +43,13 @@ class ImageState final {
*/
const ImageRequest& getImageRequest() const;
Float getBlurRadius() const;
/*
* Returns stored ImageRequestParams object.
*/
const ImageRequestParams& getImageRequestParams() const;
#ifdef ANDROID
ImageState(const ImageState& previousState, folly::dynamic data)
: blurRadius_{0} {};
: imageRequestParams_{} {};
/*
* Empty implementation for Android because it doesn't use this class.
@@ -59,7 +62,7 @@ class ImageState final {
private:
ImageSource imageSource_;
std::shared_ptr<ImageRequest> imageRequest_;
const Float blurRadius_;
ImageRequestParams imageRequestParams_;
};
} // namespace facebook::react
@@ -403,8 +403,9 @@ void BaseViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineOffset);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineStyle);
RAW_SET_PROP_SWITCH_CASE_BASIC(outlineWidth);
RAW_SET_PROP_SWITCH_CASE(filter, "filter");
RAW_SET_PROP_SWITCH_CASE(boxShadow, "boxShadow");
RAW_SET_PROP_SWITCH_CASE_BASIC(filter);
RAW_SET_PROP_SWITCH_CASE_BASIC(boxShadow);
RAW_SET_PROP_SWITCH_CASE_BASIC(mixBlendMode);
// events field
VIEW_EVENT_CASE(PointerEnter);
VIEW_EVENT_CASE(PointerEnterCapture);
@@ -11,6 +11,7 @@
#include <react/renderer/core/ReactPrimitives.h>
#include <react/renderer/imagemanager/ImageRequest.h>
#include <react/renderer/imagemanager/ImageRequestParams.h>
#include <react/renderer/imagemanager/primitives.h>
#include <react/utils/ContextContainer.h>
@@ -33,6 +34,12 @@ class ImageManager {
const ImageSource& imageSource,
SurfaceId surfaceId) const;
virtual ImageRequest requestImage(
const ImageSource& imageSource,
SurfaceId surfaceId,
const ImageRequestParams& imageRequestParams,
Tag tag) const;
private:
void* self_{};
};
@@ -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.
*/
#include "ImageManager.h"
namespace facebook::react {
ImageManager::ImageManager(
const ContextContainer::Shared& /*contextContainer*/) {
// Silence unused-private-field warning.
(void)self_;
// Not implemented.
}
ImageManager::~ImageManager() = default;
ImageRequest ImageManager::requestImage(
const ImageSource& imageSource,
SurfaceId surfaceId) const {
return requestImage(imageSource, surfaceId, ImageRequestParams{}, {});
}
ImageRequest ImageManager::requestImage(
const ImageSource& imageSource,
SurfaceId /*surfaceId*/,
const ImageRequestParams& /*imageRequestParams*/,
Tag /* tag */) const {
return {imageSource, nullptr, {}};
}
} // namespace facebook::react
@@ -0,0 +1,30 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/renderer/graphics/Float.h>
namespace facebook::react {
class ImageRequestParams {
public:
ImageRequestParams() = default;
ImageRequestParams(Float blurRadius) : blurRadius(blurRadius) {}
Float blurRadius{};
bool operator==(const ImageRequestParams& rhs) const {
return this->blurRadius == rhs.blurRadius;
}
bool operator!=(const ImageRequestParams& rhs) const {
return !(*this == rhs);
}
};
} // namespace facebook::react
@@ -22,7 +22,15 @@ ImageManager::~ImageManager() {
ImageRequest ImageManager::requestImage(
const ImageSource& imageSource,
SurfaceId /*surfaceId*/) const {
SurfaceId surfaceId) const {
return requestImage(imageSource, surfaceId, ImageRequestParams{}, {});
}
ImageRequest ImageManager::requestImage(
const ImageSource& imageSource,
SurfaceId /*surfaceId*/,
const ImageRequestParams& /*imageRequestParams*/,
Tag /*tag*/) const {
// Not implemented.
return {imageSource, nullptr, {}};
}
@@ -0,0 +1,30 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/renderer/graphics/Float.h>
namespace facebook::react {
class ImageRequestParams {
public:
ImageRequestParams() = default;
explicit ImageRequestParams(Float blurRadius) : blurRadius(blurRadius) {}
Float blurRadius{};
bool operator==(const ImageRequestParams& rhs) const {
return this->blurRadius == rhs.blurRadius;
}
bool operator!=(const ImageRequestParams& rhs) const {
return !(*this == rhs);
}
};
} // namespace facebook::react
@@ -35,6 +35,15 @@ ImageManager::~ImageManager()
}
ImageRequest ImageManager::requestImage(const ImageSource &imageSource, SurfaceId surfaceId) const
{
return requestImage(imageSource, surfaceId, ImageRequestParams{}, {});
}
ImageRequest ImageManager::requestImage(
const ImageSource &imageSource,
SurfaceId surfaceId,
const ImageRequestParams & /*imageRequestParams*/,
Tag /*tag*/) const
{
RCTImageManager *imageManager = (__bridge RCTImageManager *)self_;
return [imageManager requestImage:imageSource surfaceId:surfaceId];
@@ -0,0 +1,30 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/renderer/graphics/Float.h>
namespace facebook::react {
class ImageRequestParams {
public:
ImageRequestParams() {}
ImageRequestParams(Float blurRadius) : blurRadius(blurRadius) {}
Float blurRadius{};
bool operator==(const ImageRequestParams& rhs) const {
return this->blurRadius == rhs.blurRadius;
}
bool operator!=(const ImageRequestParams& rhs) const {
return !(*this == rhs);
}
};
} // namespace facebook::react
@@ -1213,10 +1213,10 @@ static void calculateLayoutImpl(
const float ownerWidth,
const float ownerHeight,
const bool performLayout,
const LayoutPassReason reason,
LayoutData& layoutMarkerData,
const uint32_t depth,
const uint32_t generationCount,
const LayoutPassReason reason) {
const uint32_t generationCount) {
yoga::assertFatalWithNode(
node,
yoga::isUndefined(availableWidth)
@@ -2268,10 +2268,10 @@ bool calculateLayoutInternal(
ownerWidth,
ownerHeight,
performLayout,
reason,
layoutMarkerData,
depth,
generationCount,
reason);
generationCount);
layout->lastOwnerDirection = ownerDirection;
layout->configVersion = node->getConfig()->getVersion();
@@ -245,8 +245,8 @@ void Node::setLayoutHadOverflow(bool hadOverflow) {
layout_.setHadOverflow(hadOverflow);
}
void Node::setLayoutDimension(float LengthValue, Dimension dimension) {
layout_.setDimension(dimension, LengthValue);
void Node::setLayoutDimension(float lengthValue, Dimension dimension) {
layout_.setDimension(dimension, lengthValue);
}
// If both left and right are defined, then use left. Otherwise return +left or
@@ -259,7 +259,7 @@ class YG_EXPORT Node : public ::YGNode {
uint32_t computedFlexBasisGeneration);
void setLayoutMeasuredDimension(float measuredDimension, Dimension dimension);
void setLayoutHadOverflow(bool hadOverflow);
void setLayoutDimension(float LengthValue, Dimension dimension);
void setLayoutDimension(float lengthValue, Dimension dimension);
void setLayoutDirection(Direction direction);
void setLayoutMargin(float margin, PhysicalEdge edge);
void setLayoutBorder(float border, PhysicalEdge edge);
@@ -188,6 +188,15 @@ const definitions: FeatureFlagDefinitions = {
purpose: 'experimentation',
},
},
enableImagePrefetchingAndroid: {
defaultValue: false,
metadata: {
dateAdded: '2024-11-19',
description:
'When enabled, Andoid will build and initiate image prefetch requests on ImageShadowNode::layout',
purpose: 'experimentation',
},
},
enableLayoutAnimationsOnAndroid: {
defaultValue: false,
metadata: {
@@ -502,6 +511,15 @@ const definitions: FeatureFlagDefinitions = {
purpose: 'release',
},
},
fixVirtualizeListCollapseWindowSize: {
defaultValue: false,
metadata: {
dateAdded: '2024-11-22',
description:
'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',
purpose: 'experimentation',
},
},
isLayoutAnimationEnabled: {
defaultValue: true,
metadata: {
@@ -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<<83b5798ee1c7a28fffbf110e19641d69>>
* @generated SignedSource<<38ad29621eeb29a9f82735dc187c13d4>>
* @flow strict
*/
@@ -36,6 +36,7 @@ export type ReactNativeFeatureFlagsJsOnly = {
enableAnimatedAllowlist: Getter<boolean>,
enableAnimatedClearImmediateFix: Getter<boolean>,
enableAnimatedPropsMemo: Getter<boolean>,
fixVirtualizeListCollapseWindowSize: Getter<boolean>,
isLayoutAnimationEnabled: Getter<boolean>,
shouldSkipStateUpdatesForLoopingAnimations: Getter<boolean>,
shouldUseAnimatedObjectForTransform: Getter<boolean>,
@@ -67,6 +68,7 @@ export type ReactNativeFeatureFlags = {
enableFixForViewCommandRace: Getter<boolean>,
enableGranularShadowTreeStateReconciliation: Getter<boolean>,
enableIOSViewClipToPaddingBox: Getter<boolean>,
enableImagePrefetchingAndroid: Getter<boolean>,
enableLayoutAnimationsOnAndroid: Getter<boolean>,
enableLayoutAnimationsOnIOS: Getter<boolean>,
enableLongTaskAPI: Getter<boolean>,
@@ -142,6 +144,11 @@ export const enableAnimatedClearImmediateFix: Getter<boolean> = createJavaScript
*/
export const enableAnimatedPropsMemo: Getter<boolean> = createJavaScriptFlagGetter('enableAnimatedPropsMemo', true);
/**
* 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
*/
export const fixVirtualizeListCollapseWindowSize: Getter<boolean> = createJavaScriptFlagGetter('fixVirtualizeListCollapseWindowSize', false);
/**
* Function used to enable / disabled Layout Animations in React Native.
*/
@@ -249,6 +256,10 @@ export const enableGranularShadowTreeStateReconciliation: Getter<boolean> = crea
* iOS Views will clip to their padding box vs border box
*/
export const enableIOSViewClipToPaddingBox: Getter<boolean> = createNativeFlagGetter('enableIOSViewClipToPaddingBox', false);
/**
* When enabled, Andoid will build and initiate image prefetch requests on ImageShadowNode::layout
*/
export const enableImagePrefetchingAndroid: Getter<boolean> = createNativeFlagGetter('enableImagePrefetchingAndroid', false);
/**
* When enabled, LayoutAnimations API will animate state changes on Android.
*/
@@ -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<<4caaf5dbaa68614ce53c8aecbd512df8>>
* @generated SignedSource<<17c0e677f7b308795e836c558b15d1d1>>
* @flow strict
*/
@@ -41,6 +41,7 @@ export interface Spec extends TurboModule {
+enableFixForViewCommandRace?: () => boolean;
+enableGranularShadowTreeStateReconciliation?: () => boolean;
+enableIOSViewClipToPaddingBox?: () => boolean;
+enableImagePrefetchingAndroid?: () => boolean;
+enableLayoutAnimationsOnAndroid?: () => boolean;
+enableLayoutAnimationsOnIOS?: () => boolean;
+enableLongTaskAPI?: () => boolean;
@@ -25,7 +25,7 @@ import {getFabricUIManager} from '../../../../../Libraries/ReactNative/FabricUIM
import {create as createAttributePayload} from '../../../../../Libraries/ReactNative/ReactFabricPublicInstance/ReactNativeAttributePayload';
import warnForStyleProps from '../../../../../Libraries/ReactNative/ReactFabricPublicInstance/warnForStyleProps';
import ReadOnlyElement, {getBoundingClientRect} from './ReadOnlyElement';
import ReadOnlyNode from './ReadOnlyNode';
import ReadOnlyNode, {setInstanceHandle} from './ReadOnlyNode';
import {
getPublicInstanceFromInternalInstanceHandle,
getShadowNode,
@@ -35,7 +35,26 @@ import nullthrows from 'nullthrows';
const noop = () => {};
export default class ReactNativeElement
// Ideally, this class would be exported as-is, but this implementation is
// significantly slower than the existing `ReactFabricHostComponent`.
// This is a very hot code path (this class is instantiated once per rendered
// host component in the tree) and we can't regress performance here.
//
// This implementation is slower because this is a subclass and we have to call
// super(), which is a very slow operation the way that Babel transforms it at
// the moment.
//
// The optimization we're doing is using an old-style function constructor,
// where we're not required to use `super()`, and we make that constructor
// extend this class so it inherits all the methods and it sets the class
// hierarchy correctly.
//
// An alternative implementation was to implement the constructor as a function
// returning a manually constructed instance using `Object.create()` but that
// was slower than this method because the engine has to create an object than
// we then discard to create a new one.
class ReactNativeElementMethods
extends ReadOnlyElement
implements INativeMethods
{
@@ -43,8 +62,10 @@ export default class ReactNativeElement
__nativeTag: number;
__internalInstanceHandle: InternalInstanceHandle;
#viewConfig: ViewConfig;
__viewConfig: ViewConfig;
// This constructor isn't really used. See the `ReactNativeElement` function
// below.
constructor(
tag: number,
viewConfig: ViewConfig,
@@ -54,7 +75,7 @@ export default class ReactNativeElement
this.__nativeTag = tag;
this.__internalInstanceHandle = internalInstanceHandle;
this.#viewConfig = viewConfig;
this.__viewConfig = viewConfig;
}
get offsetHeight(): number {
@@ -171,12 +192,12 @@ export default class ReactNativeElement
setNativeProps(nativeProps: {...}): void {
if (__DEV__) {
warnForStyleProps(nativeProps, this.#viewConfig.validAttributes);
warnForStyleProps(nativeProps, this.__viewConfig.validAttributes);
}
const updatePayload = createAttributePayload(
nativeProps,
this.#viewConfig.validAttributes,
this.__viewConfig.validAttributes,
);
const node = getShadowNode(this);
@@ -186,3 +207,24 @@ export default class ReactNativeElement
}
}
}
// Alternative constructor just implemented to provide a better performance than
// calling super() in the original class.
function ReactNativeElement(
this: ReactNativeElementMethods,
tag: number,
viewConfig: ViewConfig,
internalInstanceHandle: InternalInstanceHandle,
) {
this.__nativeTag = tag;
this.__internalInstanceHandle = internalInstanceHandle;
this.__viewConfig = viewConfig;
setInstanceHandle(this, internalInstanceHandle);
}
ReactNativeElement.prototype = Object.create(
ReactNativeElementMethods.prototype,
);
// $FlowExpectedError[prop-missing]
export default ReactNativeElement as typeof ReactNativeElementMethods;
@@ -26,6 +26,8 @@ let ReadOnlyElementClass: Class<ReadOnlyElement>;
export default class ReadOnlyNode {
constructor(internalInstanceHandle: InternalInstanceHandle) {
// This constructor is inlined in `ReactNativeElement` so if you modify
// this make sure that their implementation stays in sync.
setInstanceHandle(this, internalInstanceHandle);
}
@@ -293,7 +295,7 @@ export function getInstanceHandle(node: ReadOnlyNode): InternalInstanceHandle {
return node[INSTANCE_HANDLE_KEY];
}
function setInstanceHandle(
export function setInstanceHandle(
node: ReadOnlyNode,
instanceHandle: InternalInstanceHandle,
): void {
@@ -8,6 +8,7 @@
* @flow strict-local
*/
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
import type {Node} from 'react';
import React, {useCallback, useEffect, useRef, useState} from 'react';
@@ -152,4 +153,4 @@ exports.examples = [
return <ActivityIndicator style={styles.centering} size={75} />;
},
},
];
] as Array<RNTesterModuleExample>;
@@ -10,6 +10,7 @@
'use strict';
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
import type {AppStateValues} from 'react-native/Libraries/AppState/AppState';
import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
@@ -159,4 +160,4 @@ exports.examples = [
return <AppStateSubscription detectEvents={true} />;
},
},
];
] as Array<RNTesterModuleExample>;
@@ -10,6 +10,7 @@
'use strict';
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
import React from 'react';
@@ -228,4 +229,4 @@ exports.examples = [
);
},
},
];
] as Array<RNTesterModuleExample>;
@@ -10,6 +10,7 @@
'use strict';
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
import type {ImageProps} from 'react-native/Libraries/Image/ImageProps';
import type {LayoutEvent} from 'react-native/Libraries/Types/CoreEventTypes';
@@ -1809,4 +1810,4 @@ exports.examples = [
},
platform: 'android',
},
];
] as Array<RNTesterModuleExample>;
@@ -8,6 +8,8 @@
* @format
*/
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
import * as MutationObserverExample from './MutationObserverExample';
import * as VisualCompletionExample from './VisualCompletionExample/VisualCompletionExample';
@@ -18,7 +20,7 @@ export const documentationURL =
'https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver';
export const description = 'API to detect mutations in React Native nodes.';
export const showIndividualExamples = true;
export const examples = [MutationObserverExample];
export const examples: Array<RNTesterModuleExample> = [MutationObserverExample];
if (typeof IntersectionObserver !== 'undefined') {
examples.push(VisualCompletionExample);
@@ -9,6 +9,9 @@
*/
'use strict';
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
import SectionListBaseExample from './SectionListBaseExample';
import * as React from 'react';
import {StyleSheet, Text, View} from 'react-native';
@@ -81,4 +84,4 @@ export default {
render: function (): React.MixedElement {
return <SectionList_contentInset />;
},
};
} as RNTesterModuleExample;
@@ -10,6 +10,8 @@
'use strict';
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
import RNTesterText from '../../components/RNTesterText';
import React from 'react';
import {
@@ -515,7 +517,7 @@ exports.examples = [
},
platform: 'android',
},
];
] as Array<RNTesterModuleExample>;
const styles = StyleSheet.create({
container: {
@@ -8,6 +8,8 @@
* @flow
*/
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
import RNTesterText from '../../components/RNTesterText';
import React from 'react';
import {useEffect, useRef, useState} from 'react';
@@ -799,4 +801,4 @@ exports.examples = [
return <TouchableDisabled />;
},
},
];
] as Array<RNTesterModuleExample>;
@@ -20,7 +20,7 @@ export const RNTesterNavigationActionsType = {
EXAMPLE_CARD_PRESS: 'EXAMPLE_CARD_PRESS',
EXAMPLE_OPEN_URL_REQUEST: 'EXAMPLE_OPEN_URL_REQUEST',
NAVBAR_OPEN_MODULE_PRESS: 'NAVBAR_OPEN_MODULE_PRESS',
};
} as const;
const getUpdatedRecentlyUsed = ({
exampleType,
@@ -14,6 +14,8 @@ import type ListMetricsAggregator, {
CellMetricProps,
} from './ListMetricsAggregator';
import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags';
/**
* Used to find the indices of the frames that overlap the given offsets. Useful for finding the
* items that bound different windows of content, such as the visible area or the buffered overscan
@@ -176,10 +178,20 @@ export function computeWindowedRenderLimits(
break;
}
const maxNewCells = newCellCount >= maxToRenderPerBatch;
const firstWillAddMore = first <= prev.first || first > prev.last;
let firstWillAddMore;
let lastWillAddMore;
if (ReactNativeFeatureFlags.fixVirtualizeListCollapseWindowSize()) {
firstWillAddMore = first <= prev.first;
lastWillAddMore = last >= prev.last;
} else {
firstWillAddMore = first <= prev.first || first > prev.last;
lastWillAddMore = last >= prev.last || last < prev.first;
}
const firstShouldIncrement =
first > overscanFirst && (!maxNewCells || !firstWillAddMore);
const lastWillAddMore = last >= prev.last || last < prev.first;
const lastShouldIncrement =
last < overscanLast && (!maxNewCells || !lastWillAddMore);
if (maxNewCells && !firstShouldIncrement && !lastShouldIncrement) {
@@ -10,7 +10,13 @@
'use strict';
import {elementsThatOverlapOffsets, newRangeCount} from '../VirtualizeUtils';
import ListMetricsAggregator from '../ListMetricsAggregator';
import {
computeWindowedRenderLimits,
elementsThatOverlapOffsets,
newRangeCount,
} from '../VirtualizeUtils';
import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags';
describe('newRangeCount', function () {
it('handles subset', function () {
@@ -116,3 +122,155 @@ function fakeProps(length) {
getItemCount: () => length,
};
}
describe('computeWindowedRenderLimits', function () {
const defaultProps = {
getItemCount: () => 10,
getItem: (_, index) => ({key: `test_${index}`}),
getItemLayout: (_, index) => {
return {index, length: 100, offset: index * 100};
},
};
const defaultScrollMetrics = {
dt: 16,
dOffset: 0,
offset: 0,
timestamp: 0,
velocity: 0,
visibleLength: 500,
zoomScale: 1,
};
it('renders all items when list is small', function () {
const props = {
...defaultProps,
getItemCount: () => 3,
};
const result = computeWindowedRenderLimits(
props,
5,
10,
{first: 0, last: 2},
new ListMetricsAggregator(),
defaultScrollMetrics,
);
expect(result).toEqual({first: 0, last: 2});
});
it('handles overflow cases when window size suddenly collapses', function () {
ReactNativeFeatureFlags.override({
fixVirtualizeListCollapseWindowSize: () => true,
});
const listMetricsAggregator = new ListMetricsAggregator();
listMetricsAggregator._contentLength = 2713.60009765625;
const offsets = [
{index: 0, length: 275, offset: 0},
{index: 1, length: 352, offset: 275},
{index: 2, length: 326, offset: 627},
{index: 3, length: 352, offset: 953},
{index: 4, length: 293, offset: 1305},
{index: 5, length: 293, offset: 1598},
{index: 6, length: 293, offset: 1891},
{index: 7, length: 293, offset: 2184},
];
expect(
computeWindowedRenderLimits(
{
...defaultProps,
getItemCount: () => 8,
getItemLayout: (_, index) => {
return offsets[index];
},
},
1,
31,
{first: 0, last: 5},
listMetricsAggregator,
{
dt: 949,
dOffset: 879.2000732421875,
offset: 2073.60009765625,
timestamp: 1732180589708,
velocity: 0.9264489707504611,
visibleLength: 640,
},
),
).toEqual({first: 0, last: 6});
});
it('handles reaching the end of the list', function () {
const listMetricsAggregator = new ListMetricsAggregator();
listMetricsAggregator._contentLength = 1000;
const offsets = Array.from({length: 10}, (_, index) => ({
index,
length: 100,
offset: index * 100,
}));
expect(
computeWindowedRenderLimits(
{
...defaultProps,
getItemLayout: (_, index) => offsets[index],
},
2,
5,
{first: 5, last: 9},
listMetricsAggregator,
{
dt: 100,
dOffset: 100,
offset: 900,
timestamp: 1000,
velocity: 1,
visibleLength: 300,
},
),
).toEqual({first: 3, last: 9});
});
it('respects maxToRenderPerBatch when adding new cells', function () {
const scrollMetrics = {
...defaultScrollMetrics,
offset: 0,
dOffset: 0,
velocity: 0,
};
const prev = {first: 0, last: 2};
const result = computeWindowedRenderLimits(
defaultProps,
2, // maxToRenderPerBatch
5, // windowSize
prev,
new ListMetricsAggregator(),
scrollMetrics,
);
expect(result).toEqual({first: 0, last: 4});
});
it('handles case where overscanFirst and overscanLast encompass entire list', function () {
const props = {
...defaultProps,
getItemCount: () => 5,
};
const scrollMetrics = {
...defaultScrollMetrics,
offset: 0,
visibleLength: 1000,
};
const result = computeWindowedRenderLimits(
props,
5,
10, // windowSize large enough to cover entire list
{first: 0, last: 4},
new ListMetricsAggregator(),
scrollMetrics,
);
expect(result).toEqual({first: 0, last: 4});
});
});
+4 -4
View File
@@ -4465,10 +4465,10 @@ flow-api-translator@0.25.1:
hermes-transform "0.25.1"
typescript "5.3.2"
flow-bin@^0.254.2:
version "0.254.2"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.254.2.tgz#eedacf079864c57f7f7fb1b4d055c0b47f328db5"
integrity sha512-+dnSUPUSt2KepiGWelhWSgFE2XjTS3V+h5RTFRGx/QIS0kYlfINlI6bcG3/J3+oauIaJsT7//Niqe6EhJX2nQQ==
flow-bin@^0.255.0:
version "0.255.0"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.255.0.tgz#b6770284a89f3b39ea39ad6222de02136e262445"
integrity sha512-UT1kfKTJ5xS6c7sBjiLSuO4SXf4YsatNKm9VCZIeoEY5TRXwg8F17Gu41iqVLAo19/ufqzQVz+/Nj0oWi24kFA==
flow-enums-runtime@^0.0.6:
version "0.0.6"