Compare commits

...
Author SHA1 Message Date
Blake Friedman 14cce6c313 [RN][CI] Fix typo in template action watcher script
Trivial typo

Changelog: [Internal]
2024-10-29 14:45:28 +00:00
Samuel Susla 741ae296d9 ship optimisation enableTextPreallocationOptimisation (#47257)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47257

changelog: [internal]

Reviewed By: NickGerleman, rshest

Differential Revision: D65068406

fbshipit-source-id: 2e54e0e42e9d30f14c139ac039378d3cb4897067
2024-10-29 07:20:16 -07:00
Samuel Susla 21b99d9981 delete stale flag enableCleanTextInputYogaNode (#47256)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47256

changelog: [internal]

no plans to ship this. Let's delete the feature flag for now.

Reviewed By: rshest

Differential Revision: D65068295

fbshipit-source-id: 0b68e331c54c4989e6227d3e40a3bade30aa49d1
2024-10-29 07:20:16 -07:00
Rubén Norte 5f45f8a71c Remove unused flags for Hermes VM (#47244)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47244

Changelog: [internal]

Reviewed By: rshest

Differential Revision: D65062303

fbshipit-source-id: 7372536643636b8a1923d9e1194ebca45f856e57
2024-10-29 06:20:13 -07:00
Pieter De Baets f503fe3f10 Reduce public API for DevToolsReactPerfLogger (#47275)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47275

Changelog: [Android][Removed] DevToolsReactPerfLogger stats gathering now uses an internal API

Reviewed By: cortinico, fabriziocucci

Differential Revision: D65133420

fbshipit-source-id: 360e86b69b1e4ba757090ae3fb87fc82d49163e7
2024-10-29 05:19:02 -07:00
Parsa Nasirimehr c1e964aa1f fix(iOS): migrate from RCTSharedApplication() for RCTDeviceInfo's RCTIsIPhoneNotched method (#47220)
Summary:
Far as i can see it, this is the last direct reference to how we used to get windows before the introduction of scenes. Everything now uses the new Scenes system (potentially we could start adding a `RCTSceneDelegate` if we ever want to move in that direction)

I also threw in a nullability check. Theoretically, that shouldn't happen, but honestly, who knows what platform will come in the future, better safe than sorry. Let me know if you think i should remove it

## Changelog:

[INTERNAL] [FIXED] - Potentially Migrate the last `KeyWindow` usage to `RCTKeyWindow` instead of tapping to the `UIWindow` directly via RCTSharedApplication

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

Test Plan:
yarn test:
<img width="1784" alt="Screenshot 2024-10-26 at 23 48 22" src="https://github.com/user-attachments/assets/3c0c6b2b-6aa1-4e7a-b663-327a363e4de6">
iOS test: Sadly it seems like it is still broken on Xcode 16 on my machine. Will leave it up to the CI to test it. I can see that there are more that are potentially broken. Might try to take a look and see if i can fix it in another PR.
<img width="1840" alt="Screenshot 2024-10-26 at 23 53 47" src="https://github.com/user-attachments/assets/2e302aee-bc57-41fe-baf3-0292dc65485e">

Reviewed By: philIip

Differential Revision: D65057289

Pulled By: cipolleschi

fbshipit-source-id: a5b2e875e681120a54e57ede90d67e66e9376a56
2024-10-29 04:37:24 -07:00
Nick Gerleman 52cdedb40e Fix missing emitter attributes on iOS TextInput when controlled component value specified using value instead of children (#47269)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47269

There were [reports](https://github.com/reactwg/react-native-releases/issues/595) that patching in the fixes for iOS controlled input did not work as expected.

I think tracked this down to a difference in how I tested, where the controlled component I used passed value as a child of the `TextInput`, instead of via `value`. Passing via `value` triggers a secondary bug, where we don't correctly pass a reference to correct ShadowView when creating attributedstring, specifically in the iOS TextInputShadowNode impl.

We previously passed nothing for the ShadowView (only the first two struct fields). This was exposed in D52589303 which enabled `-Wextra`, but there, I went with same behavior of passing empty ShadowView, instead of the correct behavior (like Android impl) of passing a ShadowView of the current ShadowNode.

After fixing this, we now correctly create event emitters in the passed attributedstring, which matches expectations for pargraph-level eventemitter now in typing attributes. We don't seem actually use this on iOS for TextInput right now (just Text), but this is likely the right foundation for events regardless.

Changelog:
[iOS][Fixed] - Fix missing emitter attributes on iOS TextInput when controlled component value specified using `value` instead of `children`

Reviewed By: cipolleschi

Differential Revision: D65108163

fbshipit-source-id: 499fe28439fabd2579eca6ded7fd13fd8ea2e43e
2024-10-29 03:43:10 -07:00
David Vacca 4076dbfc86 Convert ReactFeatureFlags to Kotlin (#47260)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47260

Convert ReactFeatureFlags to Kotlin

changeLog: [Android][Changed] Migrate ReactFeatureFlags to Kotlin

Reviewed By: shwanton, javache

Differential Revision: D65070217

fbshipit-source-id: 8939326c1e1e7cd634347a58123ad8c0795c309e
2024-10-28 18:49:19 -07:00
David Vacca 03797dda03 Convert LongStreamingStats to Kotlin (#47261)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47261

Convert LongStreamingStats to Kotlin

changeLog: [internal] internal

Reviewed By: javache

Differential Revision: D65070215

fbshipit-source-id: b4e3ca9152ea382e516d1b598401df6bf38135eb
2024-10-28 18:49:19 -07:00
David Vacca b5696e6172 Migrate PreAllocateViewMountItem to Kotlin (#47258)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47258

Migrate PreAllocateViewMountItem to Kotlin

changeLog: [internal] internal

Reviewed By: shwanton

Differential Revision: D65070220

fbshipit-source-id: 3785f36747ea54304e45234daf377d20381f3c6c
2024-10-28 18:49:19 -07:00
David Vacca 0705eb8b91 Assert FeatureFlags in Bridgeless initialization only on Debug mode (#47263)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47263

Assert FeatureFlags in Bridgeless initialization only on Debug mode

changelog: [internal] internal

Reviewed By: shwanton

Differential Revision: D65078365

fbshipit-source-id: 79a40ba84e140b9784660ac9d1c14fd0f7426653
2024-10-28 14:23:51 -07:00
Samuel Susla 92d743a9ab surface setup issues in EventBeat and Scheduler (#47253)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47253

changelog: [internal]

Add assert statements to make sure EventBeat and Scheduler classes are correctly setup.

Scheduler must receive RuntimeScheduler through ContextContainer.
Callers of EventBeat must set beatCallback before calling request.

Reviewed By: javache

Differential Revision: D65001802

fbshipit-source-id: 5e044e1e6b0249bc89c11cccd51801add2e85b88
2024-10-28 13:17:43 -07:00
Eli White 3111473d57 Add test for native module returning enum (#47229)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47229

Adding a test case for an enum value in a fromNative position

Changelog: [Internal]

Reviewed By: makovkastar

Differential Revision: D65038107

fbshipit-source-id: ed323d9a8b226be3ff571c86fda617cabc17cdb9
2024-10-28 12:03:33 -07:00
Zeya Peng b5b65275c6 move multiline and submitBehavior down to BaseTextInputProps (#47205)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47205

move `multiline` and `submitBehavior` from ios and android respectively to BaseTextInputProps

Changelog: [Internal]

Reviewed By: christophpurrer

Differential Revision: D64494449

fbshipit-source-id: ac737af27ba21ee886c92667f6c51945738bfc02
2024-10-28 10:17:02 -07:00
Zeya Peng db835e28d8 Make textInputProps.submitBehavior on android an enum type (#47206)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47206

Share definition of `SubmitBehavior` enum on ios, and use it on android

Changelog: [Internal]

Reviewed By: rshest

Differential Revision: D64718150

fbshipit-source-id: a078c9be44c625cc5e9001e4ae25d32eaaf5d8e4
2024-10-28 10:17:02 -07:00
Samuel Susla 8b9535f101 add missing breaks in PointerEvent (#47233)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47233

changelog: [internal]

This looks like a missing break statement when it was refactored in https://github.com/facebook/react-native/pull/41519

Reviewed By: rubennorte

Differential Revision: D65040504

fbshipit-source-id: c4d52792099a5764d00c16708e400fa8a0046c93
2024-10-28 10:14:34 -07:00
Riccardo Cipolleschi e4e68db2bc Backport to main fixes in publishing the template (#47250)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47250

This commit backports to main [#47116](https://github.com/facebook/react-native/pull/47116)

## Changelog
[Internal] - Backport fix to publishTemplate from 0.76 to main

Reviewed By: blakef

Differential Revision: D65066047

fbshipit-source-id: 2c8fcca8ea7b75495aa5ad1bd4e3f53379cb3246
2024-10-28 09:58:38 -07:00
Samuel Susla 9a5d3efb12 remove EventEmitter::toggleEventTargetOwnership_ (#47224)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47224

changelog: [internal]

not used, let's remove it.

Reviewed By: rshest

Differential Revision: D65004362

fbshipit-source-id: 7cedf18bf1d685510da3512cf40628897b357bcf
2024-10-28 09:20:04 -07:00
Blake Friedman cf8250a79f verify template is published method (#47243)
Summary:
This step called an old reference, this function identifier was updated.

Changelog: [Internal]

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

Reviewed By: cipolleschi

Differential Revision: D65063054

Pulled By: blakef

fbshipit-source-id: 640a4c501818c9b83cebb27c89ba6efd82800be8
2024-10-28 08:15:35 -07:00
Pieter De Baets bd133b5dd5 Add featureflag to not re-order mount items in FabricMountingManager (#46702)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46702

In https://github.com/facebook/react-native/pull/44188, we've started combining multiple transactions in a single transaction, to meet React's atomicity requirements, while also dealing with the constraints of Android's Fabric implementation.

This revealed a bug where in some scenarios (especially when using transitions), a node may be deleted and created during the same transaction. The current implementation of FabricMountingManager assumes it can safely reorder some operations, which it does to optimize the size of IntBufferBatch mount items. This is however incorrect and unsafe when multiple transactions are merged.

**Example:**

Differentiator output:

```
# Transaction 1
Remove #100 from #11
Delete #100

# Transaction 2
Create #100
Insert #100 into #11
```
FabricMountingManager output
```
Remove #100 from #11
Insert #100 into #11
Delete #100
```

Note that the create action is also skipped, because we only update `allocatedViewTags` after processing all mutations, leading FabricMountingManager to assume creation is not required.

This leads to an invalid state in SurfaceMountingManager, which will be surfaced as a crash in `getViewState` on the next mutation that interacts with these views.

Changelog: [Android][Fixed] Fix crash in getViewState when using suspense fallbacks.

Reviewed By: sammy-SC

Differential Revision: D63148523

fbshipit-source-id: 07ae26b2f7b7eba1b9784041dd3059b0956c035e
2024-10-28 06:18:43 -07:00
Samuel Susla dd432790b8 Use RuntimeScheduler in EventBeat 2nd try (#47196)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47196

changelog: [internal]

EventBeat can use RuntimeScheduler directly, no need to go through RuntimeExecutor.

Reviewed By: christophpurrer

Differential Revision: D64927936

fbshipit-source-id: 9fb317d7c98da588d3438424ab9923dc0c0259c1
2024-10-28 05:50:15 -07:00
zhongwuzw e271b23fad Fixes regression of RCTWindowFrameDidChangeNotification not fired (#47236)
Summary:
Fixes https://github.com/facebook/react-native/issues/47234. regression from https://github.com/facebook/react-native/commit/391680fe844aad887e497912378c699aed13464b#diff-b7fda5d350ac535115fa683faa7317b43aa11f3448f95266ef9ff051c3753a6fL63

bypass-github-export-checks

## Changelog:

[IOS] [FIXED] - Fixes regression of RCTWindowFrameDidChangeNotification not fired

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

Test Plan: Demo in https://github.com/facebook/react-native/issues/47234.

Reviewed By: blakef

Differential Revision: D65058105

Pulled By: cipolleschi

fbshipit-source-id: 0e286182ed93f289cb853710e2e00801ef2d4f73
2024-10-28 05:23:52 -07:00
Riccardo Cipolleschi 4192678bd7 Pin Xcodeproj to < 1.26.0 (#47237)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47237

The Xcodeproj gem has been released yesterday to version 1.26.0 and it broke the CI pipeline of react native.

This should fix the issue

## Changelog
[Internal] - Pin Xcodeproj gem to 1.26.0

Reviewed By: blakef

Differential Revision: D65057797

fbshipit-source-id: f4035a1d3c75dd4140eb1646ab2aa0ccb08fb16b
2024-10-28 04:20:31 -07:00
Pieter De Baets dc2000c875 Improve correctness of textTransform: capitalize (#47219)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47219

We received reports that textTransform does not correctly match the web behaviour for capitalize, eg. capitalized characters should not be lowercased when using `capitalize`.

Example input: 'hello WORLD', should become 'Hello WORLD'.

Changelog: [General][Fixed] TextTransform: capitalize better reflects the web behaviour

Reviewed By: NickGerleman

Differential Revision: D65023821

fbshipit-source-id: 8ba5fdbd7afb1460193bf82a2f4021c3aff2110a
2024-10-26 17:57:26 -07:00
Jakub Piasecki 33e1ae13f8 Add tests for LayoutableChildren iterator
Summary:
Adds unit tests that directly cover the order in which `LayoutableChildren` iterator goes over the descendant nodes. The covered cases are as follows (nodes with `display: contents` are marked green):

### Single `display: contents` node

```mermaid
flowchart TD
R((R)) --> A((A))
R --> B((B))
R --> C((C))

B --> D((D))
B --> E((E))

style B fill:https://github.com/facebook/yoga/issues/090
```

Correct order: `A, D, E, C`

### Multiple `display: contents` nodes

```mermaid
flowchart TD
R((R)) --> A((A))
R --> B((B))
R --> C((C))

A --> D((D))
A --> E((E))

B --> F((F))
B --> G((G))

C --> H((H))
C --> I((I))

style A fill:https://github.com/facebook/yoga/issues/090
style B fill:https://github.com/facebook/yoga/issues/090
style C fill:https://github.com/facebook/yoga/issues/090
```

Correct order: `D, E, F, G, H, I`

### Nested `display: contents` nodes

```mermaid
flowchart TD
R((R)) --> A((A))
R --> B((B))
R --> C((C))

B --> D((D))
B --> E((E))

E --> F((F))
E --> G((G))

style B fill:https://github.com/facebook/yoga/issues/090
style E fill:https://github.com/facebook/yoga/issues/090
```

Correct order: `A, D, F, G, C`

### Leaf `display: contents` node

```mermaid
flowchart TD
R((R)) --> A((A))
R --> B((B))
R --> C((C))

style B fill:https://github.com/facebook/yoga/issues/090
```

Correct order: `A, C`

### Root `display: contents` node

```mermaid
flowchart TD
R((R)) --> A((A))
R --> B((B))
R --> C((C))

style R fill:https://github.com/facebook/yoga/issues/090
```

Correct order: `A, B, C` - `LayoutableChildren` goes over the children with `display: contents` property, setting it on the root node should have no effect.

Changelog: [Internal]

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

Reviewed By: joevilches

Differential Revision: D64981779

Pulled By: NickGerleman

fbshipit-source-id: ee39759c663a40f96ad313f1b775d53ab68fb442
2024-10-25 18:01:20 -07:00
Samuel Susla db09e7c2e5 delete shouldYield from commit options (#47191)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47191

changelog: [internal]

not used, let's delete it.

Reviewed By: javache, rubennorte

Differential Revision: D64916432

fbshipit-source-id: 182848c85ca58d4e8fae3c6ab67c781807803dff
2024-10-25 17:41:06 -07:00
Jakub Piasecki a88ddcecc9 Fix for nodes with display: contents not being cleaned in some cases (#47194)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47194

Fixes a case where a node with `display: contents` would not be cleaned up in some cases. This was caused by it being called after some early returns handling different quick paths. This PR moves the call to `cleanupContentsNodesRecursively` earlier so that it's always called.

The problem here wasn't mutating before cloning, but leaving a node marked as dirty after the layout has finished.

The exact case in which I found this was a node with a single `display: contents` child which needs to be a leaf. Then in the parent node [this](https://github.com/facebook/yoga/blob/b0b842d5e75d041e3af7e0ac55abfb8929fbbf21/yoga/algorithm/CalculateLayout.cpp#L1339) condition is true, so `cleanupContentsNodesRecursively` doesn't get called and the child node is never visited and cleaned. I assume the same will happen in the other paths with an early return here.

Changelog:
[General][Fixed] - Fix for nodes with `display: contents` not being cleaned in some cases

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

Reviewed By: rozele

Differential Revision: D64910099

Pulled By: NickGerleman

fbshipit-source-id: 6d56f8fbf687b7ee5af889c0b868406213c9cee8
2024-10-25 17:34:36 -07:00
Ramanpreet Nara 4f47439a02 cleanup: ExceptionsManager: Delete updateExceptionMessage (#47167)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47167

I couldn't find any usages of this method in javascript.

Removing, so that the native code is easier to read.

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D64606928

fbshipit-source-id: 1d52d58437370ae3d99e9c44500080687f137191
2024-10-25 15:12:40 -07:00
Ramanpreet Nara f8788963b9 cleanup: ExceptionsManager: Delete reportUnhandledException (#47166)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47166

This method wasn't used from javascript.

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D64607415

fbshipit-source-id: 2fb7eeee9479de85284d05629ed8e1bfb9fa5917
2024-10-25 15:12:40 -07:00
Ramanpreet Nara 0941b51e9d earlyjs: Make ExceptionsManager the js interface for c++ pipeline (#47165)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47165

The c++ pipeline needs a javascript interface.

We could just re-use exceptions manager (for now).

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D64779068

fbshipit-source-id: 4e300668a01fa22e194ea9f149ef1d936d5e0834
2024-10-25 15:12:40 -07:00
Ramanpreet Nara 2247e0b983 earlyjs: Make JsErrorHandler work for all js throwables
Summary:
Now, handleError can be called with a JSError that wraps a non-error object!

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D64706198

fbshipit-source-id: 562ed7d4e2a13eaef48acfdf3499296462e54166
2024-10-25 15:12:40 -07:00
Samuel Susla 3fff4cf966 delete MountingCoordinator::Shared typealias (#47207)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47207

changelog: [internal]

delete typealias `MountingCoordinator::Shared` and use `std::shared_ptr<const MountingCoordinator>` directly.

Reviewed By: christophpurrer

Differential Revision: D64917023

fbshipit-source-id: 586ffcd5d22ea48b22d8a6cf86aa5fdf87fdefd0
2024-10-25 12:51:57 -07:00
David Vacca eddc0a1d49 Delete CoreFeatures class (#45626)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45626

I'm deleting CoreFeatures class and all its imports because it was fully replaced by ReactNativeFeatureFlags

Changelog: [Internal][Removed] Delete CoreFeatures class in favor of ReactNativeFeatureFlags

Reviewed By: rubennorte

Differential Revision: D60137380

fbshipit-source-id: 8bf918cdd1ce66e315aa95e1c5a28879445ff9f9
2024-10-25 08:32:20 -07:00
David Vacca a01e2e4165 Delete CoreFeatures::excludeYogaFromRawProps (#45627)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45627

I'm deleting CoreFeatures::excludeYogaFromRawProps in favor of ReactNativeFeatureFlags::excludeYogaFromRawProps();

changelog: [internal] internal

Reviewed By: rubennorte

Differential Revision: D60124448

fbshipit-source-id: 1dfec40d638c4051ebfebe712abe0bee6764e584
2024-10-25 08:32:20 -07:00
David Vacca 26278b10b1 Migrate enableCppPropsIteratorSetter to ReactNativeFeatureFlags (#45602)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45602

Migrate enableCppPropsIteratorSetter to ReactNativeFeatureFlags

Changelog: [Internal] internal

Reviewed By: rubennorte

Differential Revision: D60022936

fbshipit-source-id: 88fe6f41af3dea0ac5de4a097901a7e8df39efb2
2024-10-25 08:32:20 -07:00
David Vacca 143b9d172c Expose JSBundleLoader as parameter of DefaultReactHost (#47179)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47179

In this diff I'm exposing the new parameter (JSBundleLoader) as parameter of DefaultReactHost.

changelog: [Android][Breaking] Added JSBundleLoader as parameter of DefaultReactHost

Reviewed By: cortinico

Differential Revision: D64381501

fbshipit-source-id: dd0d56441802f7db53c67c659bbcae63c4b1b613
2024-10-25 02:08:32 -07:00
David Vacca 80f846948a Remove unused dependencies from facebook/react/interfaces (#47115)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47115

Remove unused dependencies from facebook/react/interfaces

changelog: [internal] internal

Reviewed By: cortinico

Differential Revision: D64585748

fbshipit-source-id: fd42b63dd25cb4b6d4d7bb4f05912cff3f167db8
2024-10-25 02:08:32 -07:00
David Vacca 2cb5198f1b Delete CompositeReactPackage from RN (#47128)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47128

Delete CompositeReactPackage from RN, these classes were deprecated for a long time and they can be deleted now, there are no internal usages

changelog: [Android][Breaking] Deleting deprecated CompositeReactPackage

Reviewed By: cortinico

Differential Revision: D64382211

fbshipit-source-id: d4fdfd51177612a64dde918cd68d6e852ef1b0e2
2024-10-25 02:08:32 -07:00
Parsa Nasirimehr 795a21a471 fix(iOS): migrate from depracated websocket method in RCTCxxInspectorWebSocketAdapter (#47197)
Summary:
Saw this while going through the remaining warnings of the project. I double checked, and i can't find any other usages left behind, so this is probably the last one

## Changelog:

[INTERNAL] [FIXED] - Switch to using the new sendString method for Websocket

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

Test Plan:
yarn test:
<img width="933" alt="Screenshot 2024-10-25 at 00 55 58" src="https://github.com/user-attachments/assets/dbfebb90-4957-4fc9-8a90-153c03055ac9">
Running the tests in Xcode with `CMD+U` or the objc-test: I could not get it to pass in either the old code or the modified code. I know the test documentation said it needs a WebSocket, but it was a bit too vague , and even turning metro on did not help, so i have no idea how to test it. If anyone can guide me on that one, please let me know

Reviewed By: blakef

Differential Revision: D64934981

Pulled By: cipolleschi

fbshipit-source-id: c6f13d3da5aafe3eed8b99b98f04904fcdcc4115
2024-10-24 23:49:13 -07:00
Blake Friedman 94fdc38822 fix: mitigate DangerJS transpilation bug (#47192)
Summary:
Danger seems to have a bug where it's not transpiling the import of
rnx-kit/rn-changelog-generator. This mitigates the issue to get our
project back on track.

This can be replicated locally by:

```bash
DEBUG="*" DANGER_GITHUB_API_TOKEN=$GITHUB_TOKEN yarn danger pr https://github.com/facebook/react-native/pull/47182
```
You can see it running correctly here when switching to the branch with the fix.  **I'm a little concerned that this is still failing on the PR**.  Thoughts?

 {F1946190275}

Changelog: [internal]

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

Reviewed By: cortinico

Differential Revision: D64924466

Pulled By: blakef

fbshipit-source-id: 68df0521620809effe3a78ce842e043382ad64a6
2024-10-24 20:07:20 -07:00
Riccardo Cipolleschi e851e73c18 Add yoga to app search paths (#47195)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47195

When a user wants to create a Fabric Component i their app (not in a separate library) the app fails to build because:
- The custom component has to inherit from `RCTViewComponentView`
- `RCTViewComponentView` imports `ViewProps.h`
- `ViewProps.h` imports `HostPlatformViewProps.h`
- `HostPlatformViewProps.h` imports `BaseViewProps.h`
- `BaseViewProps.h` imports `YogaStylableProps.h`

which is a Yoga private header and the App has not visibility over it.

It is also not possible to fix this issue with forward declaring the `YogaStylableProps`, because `BaseViewProps` inherit from the yoga's props, so the compiler needs the full declaration of `YogaStylableProps` to work

This needs to be picked in 0.76

## Changelog
[iOS][Fixed] - Give apps access to Yoga headers

Reviewed By: blakef

Differential Revision: D64925222

fbshipit-source-id: e724076bbfb0a678948340dfab2ce609e6509533
2024-10-24 17:16:50 -07:00
Sunny Luo d293fdd27a Add jsBundleFile to DefaultReactNativeHost.kt (#47188)
Summary:
The JsBundleFilePath has been ignored when converting DefaultReactNativeHost to ReactHost

Changelog:
[Internal] [Changed] - Add jsBundleFile to DefaultReactNativeHost.kt

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

Reviewed By: javache

Differential Revision: D64914149

Pulled By: cortinico

fbshipit-source-id: d437ca81df5a170e0c5f01a22ccda83f43a09dd2
2024-10-24 14:59:21 -07:00
140 changed files with 1284 additions and 1794 deletions
@@ -46,7 +46,7 @@ describe('#publishTemplate', () => {
expect(github.rest.actions.createWorkflowDispatch).toHaveBeenCalledWith({
owner: 'react-native-community',
repo: 'template',
workflow_id: 'release.yml',
workflow_id: 'release.yaml',
ref: '0.76-stable',
inputs: {
dry_run: true,
@@ -66,7 +66,7 @@ describe('#publishTemplate', () => {
expect(github.rest.actions.createWorkflowDispatch).toHaveBeenCalledWith({
owner: 'react-native-community',
repo: 'template',
workflow_id: 'release.yml',
workflow_id: 'release.yaml',
ref: '0.76-stable',
inputs: {
dry_run: false,
+1 -1
View File
@@ -42,7 +42,7 @@ module.exports.publishTemplate = async (github, version, dryRun = true) => {
await github.rest.actions.createWorkflowDispatch({
owner: 'react-native-community',
repo: 'template',
workflow_id: 'release.yml',
workflow_id: 'release.yaml',
ref,
inputs: {
dry_run: dryRun,
+2 -2
View File
@@ -9,7 +9,7 @@
const {execSync} = require('child_process');
function run(...cmd) {
function run(cmd) {
return execSync(cmd, 'utf8').toString().trim();
}
module.exports.run = run;
@@ -21,7 +21,7 @@ module.exports.sleep = sleep;
async function getNpmPackageInfo(pkg, versionOrTag) {
return fetch(`https://registry.npmjs.org/${pkg}/${versionOrTag}`).then(resp =>
res.json(),
resp.json(),
);
}
module.exports.getNpmPackageInfo = getNpmPackageInfo;
+2 -2
View File
@@ -205,9 +205,9 @@ jobs:
with:
github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }}
script: |
const {verifyPublished, isLatest} = require('./.github/workflow-scripts/publishTemplate.js')
const {verifyPublishedTemplate, isLatest} = require('./.github/workflow-scripts/publishTemplate.js')
const version = "${{ github.ref_name }}"
await verifyPublished(version, isLatest());
await verifyPublishedTemplate(version, isLatest());
- name: Update rn-diff-purge to generate upgrade-support diff
run: |
curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \
+1
View File
@@ -5,3 +5,4 @@ ruby ">= 2.6.10"
gem 'cocoapods', '~> 1.13', '!= 1.15.0', '!= 1.15.1'
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
gem 'xcodeproj', '< 1.26.0'
+1
View File
@@ -4,3 +4,4 @@ ruby ">= 2.6.10"
gem 'cocoapods', '~> 1.13', '!= 1.15.0', '!= 1.15.1'
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
gem 'xcodeproj', '< 1.26.0'
+3 -4
View File
@@ -8,9 +8,6 @@
*/
'use strict';
const {validate: validateChangelog} =
require('@rnx-kit/rn-changelog-generator').default;
const {danger, fail, /*message,*/ warn} = require('danger');
const includes = require('lodash.includes');
@@ -60,7 +57,9 @@ if (!includesTestPlan && !isFromPhabricator) {
// Check if there is a changelog and validate it
if (!isFromPhabricator) {
const status = validateChangelog(danger.github.pr.body);
const status = require('@rnx-kit/rn-changelog-generator').default.validate(
danger.github.pr.body,
);
const changelogInstructions =
'See <a target="_blank" href="https://reactnative.dev/contributing/changelogs-in-pull-requests">Changelog format</a>';
if (status === 'missing') {
@@ -496,7 +496,9 @@ const SIMPLE_NATIVE_MODULES: SchemaType = {
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
type: 'StringTypeAnnotation',
name: 'StringEnum',
type: 'EnumDeclaration',
memberType: 'StringTypeAnnotation',
},
params: [
{
@@ -811,7 +811,7 @@ export type CustomDeviceEvent = {
export interface Spec extends TurboModule {
+getCallback: () => () => void;
+getMixed: (arg: mixed) => mixed;
+getEnums: (quality: Quality, resolution?: Resolution, stringOptions: StringOptions) => string;
+getEnums: (quality: Quality, resolution?: Resolution, stringOptions: StringOptions) => Quality;
+getBinaryTreeNode: (arg: BinaryTreeNode) => BinaryTreeNode;
+getGraphNode: (arg: GraphNode) => GraphNode;
+getMap: (arg: {[a: string]: ?number}) => {[b: string]: ?number};
@@ -227,7 +227,9 @@ exports[`RN Codegen Flow Parser can generate fixture CXX_ONLY_NATIVE_MODULE 1`]
'typeAnnotation': {
'type': 'FunctionTypeAnnotation',
'returnTypeAnnotation': {
'type': 'StringTypeAnnotation'
'name': 'Quality',
'type': 'EnumDeclaration',
'memberType': 'StringTypeAnnotation'
},
'params': [
{
@@ -900,7 +900,7 @@ export type CustomDeviceEvent = {
export interface Spec extends TurboModule {
readonly getCallback: () => () => void;
readonly getMixed: (arg: unknown) => unknown;
readonly getEnums: (quality: Quality, resolution?: Resolution, stringOptions: StringOptions) => string;
readonly getEnums: (quality: Quality, resolution?: Resolution, stringOptions: StringOptions) => Quality;
readonly getBinaryTreeNode: (arg: BinaryTreeNode) => BinaryTreeNode;
readonly getGraphNode: (arg: GraphNode) => GraphNode;
readonly getMap: (arg: {[a: string]: number | null;}) => {[b: string]: number | null;};
@@ -218,7 +218,9 @@ exports[`RN Codegen TypeScript Parser can generate fixture CXX_ONLY_NATIVE_MODUL
'typeAnnotation': {
'type': 'FunctionTypeAnnotation',
'returnTypeAnnotation': {
'type': 'StringTypeAnnotation'
'name': 'Quality',
'type': 'EnumDeclaration',
'memberType': 'StringTypeAnnotation'
},
'params': [
{
@@ -76,6 +76,7 @@
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [self createRootViewController];
[self setRootView:rootView toRootViewController:rootViewController];
_window.windowScene.delegate = self;
_window.rootViewController = rootViewController;
[_window makeKeyAndVisible];
}
@@ -64,7 +64,7 @@ Pod::Spec.new do |s|
"CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
"DEFINES_MODULE" => "YES"
}
s.user_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\""}
s.user_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\" \"$(PODS_ROOT)/Headers/Private/Yoga\""}
s.dependency "React-Core"
s.dependency "RCT-Folly", folly_version
+21 -18
View File
@@ -141,24 +141,27 @@ let inExceptionHandler = false;
* Logs exceptions to the (native) console and displays them
*/
function handleException(e: mixed, isFatal: boolean) {
let error: Error;
if (e instanceof Error) {
error = e;
} else {
// Workaround for reporting errors caused by `throw 'some string'`
// Unfortunately there is no way to figure out the stacktrace in this
// case, so if you ended up here trying to trace an error, look for
// `throw '<error message>'` somewhere in your codebase.
error = new SyntheticError(e);
}
try {
inExceptionHandler = true;
/* $FlowFixMe[class-object-subtyping] added when improving typing for this
* parameters */
// $FlowFixMe[incompatible-call]
reportException(error, isFatal, /*reportToConsole*/ true);
} finally {
inExceptionHandler = false;
// TODO(T196834299): We should really use a c++ turbomodule for this
if (!global.RN$handleException || !global.RN$handleException(e, isFatal)) {
let error: Error;
if (e instanceof Error) {
error = e;
} else {
// Workaround for reporting errors caused by `throw 'some string'`
// Unfortunately there is no way to figure out the stacktrace in this
// case, so if you ended up here trying to trace an error, look for
// `throw '<error message>'` somewhere in your codebase.
error = new SyntheticError(e);
}
try {
inExceptionHandler = true;
/* $FlowFixMe[class-object-subtyping] added when improving typing for this
* parameters */
// $FlowFixMe[incompatible-call]
reportException(error, isFatal, /*reportToConsole*/ true);
} finally {
inExceptionHandler = false;
}
}
}
@@ -14,7 +14,6 @@ import typeof NativeExceptionsManager from '../NativeExceptionsManager';
export default ({
reportFatalException: jest.fn(),
reportSoftException: jest.fn(),
updateExceptionMessage: jest.fn(),
dismissRedbox: jest.fn(),
reportException: jest.fn(),
}: NativeExceptionsManager);
@@ -67,8 +67,6 @@ function runExceptionsManagerTests() {
return {
default: {
reportException: jest.fn(),
// Used to show symbolicated messages, not part of this test.
updateExceptionMessage: () => {},
},
};
});
+1 -7
View File
@@ -21,13 +21,7 @@ ExceptionsManager.installConsoleErrorReporter();
if (!global.__fbDisableExceptionsManager) {
const handleError = (e: mixed, isFatal: boolean) => {
try {
// TODO(T196834299): We should really use a c++ turbomodule for this
if (
!global.RN$handleException ||
!global.RN$handleException(e, isFatal)
) {
ExceptionsManager.handleException(e, isFatal);
}
ExceptionsManager.handleException(e, isFatal);
} catch (ee) {
console.log('Failed to print error: ', ee.message);
throw e;
@@ -9,8 +9,7 @@
#import <React/RCTDynamicTypeRamp.h>
#import <React/RCTTextDecorationLineType.h>
#import "RCTTextTransform.h"
#import <React/RCTTextTransform.h>
NS_ASSUME_NONNULL_BEGIN
@@ -278,19 +278,15 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib
static NSString *capitalizeText(NSString *text)
{
NSArray *words = [text componentsSeparatedByString:@" "];
NSMutableArray *newWords = [NSMutableArray new];
NSNumberFormatter *num = [NSNumberFormatter new];
for (NSString *item in words) {
NSString *word;
if ([item length] > 0 && [num numberFromString:[item substringWithRange:NSMakeRange(0, 1)]] == nil) {
word = [item capitalizedString];
} else {
word = [item lowercaseString];
}
[newWords addObject:word];
}
return [newWords componentsJoinedByString:@" "];
NSMutableString *result = [[NSMutableString alloc] initWithString:text];
[result
enumerateSubstringsInRange:NSMakeRange(0, text.length)
options:NSStringEnumerationByWords
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[result replaceCharactersInRange:NSMakeRange(substringRange.location, 1)
withString:[[substring substringToIndex:1] uppercaseString]];
}];
return result;
}
- (NSString *)applyTextAttributesToText:(NSString *)text
@@ -128,7 +128,10 @@ static BOOL RCTIsIPhoneNotched()
RCTAssertMainQueue();
// 20pt is the top safeArea value in non-notched devices
isIPhoneNotched = RCTSharedApplication().keyWindow.safeAreaInsets.top > 20;
UIWindow *keyWindow = RCTKeyWindow();
if (keyWindow) {
isIPhoneNotched = keyWindow.safeAreaInsets.top > 20;
}
});
#endif
@@ -11,7 +11,6 @@
NS_ASSUME_NONNULL_BEGIN
@protocol RCTExceptionsManagerDelegate <NSObject>
- (void)handleSoftJSExceptionWithMessage:(nullable NSString *)message
stack:(nullable NSArray *)stack
exceptionId:(NSNumber *)exceptionId
@@ -20,12 +19,6 @@ NS_ASSUME_NONNULL_BEGIN
stack:(nullable NSArray *)stack
exceptionId:(NSNumber *)exceptionId
extraDataAsJSON:(nullable NSString *)extraDataAsJSON;
@optional
- (void)updateJSExceptionWithMessage:(nullable NSString *)message
stack:(nullable NSArray *)stack
exceptionId:(NSNumber *)exceptionId;
@end
@interface RCTExceptionsManager : NSObject <RCTBridgeModule>
@@ -99,27 +99,6 @@ RCT_EXPORT_METHOD(reportFatalException
[self reportFatal:message stack:stack exceptionId:exceptionId extraDataAsJSON:nil];
}
RCT_EXPORT_METHOD(updateExceptionMessage
: (NSString *)message stack
: (NSArray<NSDictionary *> *)stack exceptionId
: (double)exceptionId)
{
if (RCTRedBoxGetEnabled()) {
RCTRedBox *redbox = [_moduleRegistry moduleForName:"RedBox"];
[redbox updateErrorMessage:message withStack:stack errorCookie:(int)exceptionId];
}
if (_delegate && [_delegate respondsToSelector:@selector(updateJSExceptionWithMessage:stack:exceptionId:)]) {
[_delegate updateJSExceptionWithMessage:message stack:stack exceptionId:[NSNumber numberWithDouble:exceptionId]];
}
}
// Deprecated. Use reportFatalException directly instead.
RCT_EXPORT_METHOD(reportUnhandledException : (NSString *)message stack : (NSArray<NSDictionary *> *)stack)
{
[self reportFatalException:message stack:stack exceptionId:-1];
}
RCT_EXPORT_METHOD(dismissRedbox) {}
RCT_EXPORT_METHOD(reportException : (JS::NativeExceptionsManager::ExceptionData &)data)
@@ -14,8 +14,8 @@ namespace facebook::react {
AppleEventBeat::AppleEventBeat(
std::shared_ptr<OwnerBox> ownerBox,
std::unique_ptr<const RunLoopObserver> uiRunLoopObserver,
RuntimeExecutor runtimeExecutor)
: EventBeat(std::move(ownerBox), std::move(runtimeExecutor)),
RuntimeScheduler& runtimeScheduler)
: EventBeat(std::move(ownerBox), runtimeScheduler),
uiRunLoopObserver_(std::move(uiRunLoopObserver)) {
uiRunLoopObserver_->setDelegate(this);
uiRunLoopObserver_->enable();
@@ -13,6 +13,8 @@
namespace facebook::react {
class RuntimeScheduler;
/*
* Event beat associated with JavaScript runtime.
* The beat is called on `RuntimeExecutor`'s thread induced by the UI thread
@@ -23,7 +25,7 @@ class AppleEventBeat : public EventBeat, public RunLoopObserver::Delegate {
AppleEventBeat(
std::shared_ptr<OwnerBox> ownerBox,
std::unique_ptr<const RunLoopObserver> uiRunLoopObserver,
RuntimeExecutor runtimeExecutor);
RuntimeScheduler& RuntimeScheduler);
#pragma mark - RunLoopObserver::Delegate
@@ -16,7 +16,6 @@
#import <react/renderer/components/image/ImageProps.h>
#import <react/renderer/imagemanager/ImageRequest.h>
#import <react/renderer/imagemanager/RCTImagePrimitivesConversions.h>
#import <react/utils/CoreFeatures.h>
using namespace facebook::react;
@@ -78,7 +78,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
const auto &defaultProps = TextInputShadowNode::defaultSharedProps();
_props = defaultProps;
_backedTextInputView = defaultProps->traits.multiline ? [RCTUITextView new] : [RCTUITextField new];
_backedTextInputView = defaultProps->multiline ? [RCTUITextView new] : [RCTUITextField new];
_backedTextInputView.textInputDelegate = self;
_ignoreNextTextInputCall = NO;
_comingFromJS = NO;
@@ -166,8 +166,8 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
const auto &newTextInputProps = static_cast<const TextInputProps &>(*props);
// Traits:
if (newTextInputProps.traits.multiline != oldTextInputProps.traits.multiline) {
[self _setMultiline:newTextInputProps.traits.multiline];
if (newTextInputProps.multiline != oldTextInputProps.multiline) {
[self _setMultiline:newTextInputProps.multiline];
}
if (newTextInputProps.traits.autocapitalizationType != oldTextInputProps.traits.autocapitalizationType) {
@@ -448,7 +448,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
return;
}
const auto &props = static_cast<const TextInputProps &>(*_props);
if (props.traits.multiline && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
if (props.multiline && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) {
[self textInputDidChange];
_ignoreNextTextInputCall = YES;
}
@@ -785,14 +785,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
- (SubmitBehavior)getSubmitBehavior
{
const auto &props = static_cast<const TextInputProps &>(*_props);
const SubmitBehavior submitBehaviorDefaultable = props.traits.submitBehavior;
// We should always have a non-default `submitBehavior`, but in case we don't, set it based on multiline.
if (submitBehaviorDefaultable == SubmitBehavior::Default) {
return props.traits.multiline ? SubmitBehavior::Newline : SubmitBehavior::BlurAndSubmit;
}
return submitBehaviorDefaultable;
return props.getNonDefaultSubmitBehavior();
}
@end
@@ -48,7 +48,7 @@ NS_ASSUME_NONNULL_BEGIN
* Schedule a mounting transaction to be performed on the main thread.
* Can be called from any thread.
*/
- (void)scheduleTransaction:(facebook::react::MountingCoordinator::Shared)mountingCoordinator;
- (void)scheduleTransaction:(std::shared_ptr<const facebook::react::MountingCoordinator>)mountingCoordinator;
/**
* Dispatch a command to be performed on the main thread.
@@ -20,7 +20,6 @@
#import <react/renderer/core/LayoutableShadowNode.h>
#import <react/renderer/core/RawProps.h>
#import <react/renderer/mounting/TelemetryController.h>
#import <react/utils/CoreFeatures.h>
#import <React/RCTComponentViewProtocol.h>
#import <React/RCTComponentViewRegistry.h>
@@ -187,7 +186,7 @@ static void RCTPerformMountInstructions(
componentViewDescriptor:rootViewDescriptor];
}
- (void)scheduleTransaction:(MountingCoordinator::Shared)mountingCoordinator
- (void)scheduleTransaction:(std::shared_ptr<const MountingCoordinator>)mountingCoordinator
{
if (RCTIsMainQueue()) {
// Already on the proper thread, so:
@@ -26,9 +26,10 @@ NS_ASSUME_NONNULL_BEGIN
*/
@protocol RCTSchedulerDelegate
- (void)schedulerDidFinishTransaction:(facebook::react::MountingCoordinator::Shared)mountingCoordinator;
- (void)schedulerDidFinishTransaction:(std::shared_ptr<const facebook::react::MountingCoordinator>)mountingCoordinator;
- (void)schedulerShouldRenderTransactions:(facebook::react::MountingCoordinator::Shared)mountingCoordinator;
- (void)schedulerShouldRenderTransactions:
(std::shared_ptr<const facebook::react::MountingCoordinator>)mountingCoordinator;
- (void)schedulerDidDispatchCommand:(const facebook::react::ShadowView &)shadowView
commandName:(const std::string &)commandName
@@ -26,13 +26,13 @@ class SchedulerDelegateProxy : public SchedulerDelegate {
public:
SchedulerDelegateProxy(void *scheduler) : scheduler_(scheduler) {}
void schedulerDidFinishTransaction(const MountingCoordinator::Shared &mountingCoordinator) override
void schedulerDidFinishTransaction(const std::shared_ptr<const MountingCoordinator> &mountingCoordinator) override
{
RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_;
[scheduler.delegate schedulerDidFinishTransaction:mountingCoordinator];
}
void schedulerShouldRenderTransactions(const MountingCoordinator::Shared &mountingCoordinator) override
void schedulerShouldRenderTransactions(const std::shared_ptr<const MountingCoordinator> &mountingCoordinator) override
{
RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_;
[scheduler.delegate schedulerShouldRenderTransactions:mountingCoordinator];
@@ -762,8 +762,10 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithTarget : (id)target action : (SEL)act
switch (recognizer.state) {
case UIGestureRecognizerStateEnded:
eventEmitter->onPointerLeave(event);
break;
default:
eventEmitter->onPointerMove(event);
break;
}
}
}
@@ -33,7 +33,6 @@
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/scheduler/SchedulerToolbox.h>
#import <react/utils/ContextContainer.h>
#import <react/utils/CoreFeatures.h>
#import <react/utils/ManagedObjectWrapper.h>
#import "AppleEventBeat.h"
@@ -229,10 +228,6 @@ using namespace facebook::react;
{
auto reactNativeConfig = _contextContainer->at<std::shared_ptr<const ReactNativeConfig>>("ReactNativeConfig");
if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_cpp_props_iterator_setter_ios")) {
CoreFeatures::enablePropIteratorSetter = true;
}
auto componentRegistryFactory =
[factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)](
const EventDispatcher::Weak &eventDispatcher, const ContextContainer::Shared &contextContainer) {
@@ -258,10 +253,10 @@ using namespace facebook::react;
toolbox.bridgelessBindingsExecutor = _bridgelessBindingsExecutor;
toolbox.eventBeatFactory =
[runtimeExecutor](std::shared_ptr<EventBeat::OwnerBox> ownerBox) -> std::unique_ptr<EventBeat> {
[runtimeScheduler](std::shared_ptr<EventBeat::OwnerBox> ownerBox) -> std::unique_ptr<EventBeat> {
auto runLoopObserver =
std::make_unique<const MainRunLoopObserver>(RunLoopObserver::Activity::BeforeWaiting, ownerBox->owner);
return std::make_unique<AppleEventBeat>(std::move(ownerBox), std::move(runLoopObserver), runtimeExecutor);
return std::make_unique<AppleEventBeat>(std::move(ownerBox), std::move(runLoopObserver), *runtimeScheduler);
};
RCTScheduler *scheduler = [[RCTScheduler alloc] initWithToolbox:toolbox];
@@ -297,12 +292,12 @@ using namespace facebook::react;
#pragma mark - RCTSchedulerDelegate
- (void)schedulerDidFinishTransaction:(MountingCoordinator::Shared)mountingCoordinator
- (void)schedulerDidFinishTransaction:(std::shared_ptr<const MountingCoordinator>)mountingCoordinator
{
// no-op, we will flush the transaction from schedulerShouldRenderTransactions
}
- (void)schedulerShouldRenderTransactions:(MountingCoordinator::Shared)mountingCoordinator
- (void)schedulerShouldRenderTransactions:(std::shared_ptr<const MountingCoordinator>)mountingCoordinator
{
[_mountingManager scheduleTransaction:mountingCoordinator];
}
@@ -50,7 +50,7 @@ NSString *NSStringFromUTF8StringView(std::string_view view)
dispatch_async(dispatch_get_main_queue(), ^{
RCTCxxInspectorWebSocketAdapter *strongSelf = weakSelf;
if (strongSelf) {
[strongSelf->_webSocket send:messageStr];
[strongSelf->_webSocket sendString:messageStr error:NULL];
}
});
}
@@ -0,0 +1,49 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <XCTest/XCTest.h>
#import <React/RCTTextAttributes.h>
@interface RCTTextAttributesTest : XCTestCase
@end
@implementation RCTTextAttributesTest
- (void)testCapitalize
{
RCTTextAttributes *attrs = [RCTTextAttributes new];
attrs.textTransform = RCTTextTransformCapitalize;
NSString *input = @"hello WORLD from ReAcT nAtIvE 2a !b c";
NSString *output = @"Hello WORLD From ReAcT NAtIvE 2a !B C";
XCTAssertEqualObjects([attrs applyTextAttributesToText:input], output);
}
- (void)testUppercase
{
RCTTextAttributes *attrs = [RCTTextAttributes new];
attrs.textTransform = RCTTextTransformUppercase;
NSString *input = @"hello WORLD from ReAcT nAtIvE 2a !b c";
NSString *output = @"HELLO WORLD FROM REACT NATIVE 2A !B C";
XCTAssertEqualObjects([attrs applyTextAttributesToText:input], output);
}
- (void)testLowercase
{
RCTTextAttributes *attrs = [RCTTextAttributes new];
attrs.textTransform = RCTTextTransformLowercase;
NSString *input = @"hello WORLD from ReAcT nAtIvE 2a !b c";
NSString *output = @"hello world from react native 2a !b c";
XCTAssertEqualObjects([attrs applyTextAttributesToText:input], output);
}
@end
@@ -7,23 +7,6 @@ public abstract class com/facebook/react/BaseReactPackage : com/facebook/react/R
protected fun getViewManagers (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/List;
}
public class com/facebook/react/CompositeReactPackage : com/facebook/react/ReactPackage, com/facebook/react/ViewManagerOnDemandReactPackage {
public fun <init> (Lcom/facebook/react/ReactPackage;Lcom/facebook/react/ReactPackage;[Lcom/facebook/react/ReactPackage;)V
public fun createNativeModules (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/List;
public fun createViewManager (Lcom/facebook/react/bridge/ReactApplicationContext;Ljava/lang/String;)Lcom/facebook/react/uimanager/ViewManager;
public fun createViewManagers (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/List;
public fun getViewManagerNames (Lcom/facebook/react/bridge/ReactApplicationContext;)Ljava/util/Collection;
}
public class com/facebook/react/CompositeReactPackageTurboModuleManagerDelegate : com/facebook/react/ReactPackageTurboModuleManagerDelegate {
protected fun initHybrid ()Lcom/facebook/jni/HybridData;
}
public class com/facebook/react/CompositeReactPackageTurboModuleManagerDelegate$Builder : com/facebook/react/ReactPackageTurboModuleManagerDelegate$Builder {
public fun <init> (Ljava/util/List;)V
protected fun build (Lcom/facebook/react/bridge/ReactApplicationContext;Ljava/util/List;)Lcom/facebook/react/ReactPackageTurboModuleManagerDelegate;
}
public class com/facebook/react/CoreModulesPackage$$ReactModuleInfoProvider : com/facebook/react/module/model/ReactModuleInfoProvider {
public fun <init> ()V
public fun getReactModuleInfos ()Ljava/util/Map;
@@ -2042,10 +2025,9 @@ public final class com/facebook/react/common/network/OkHttpCallUtil {
public static final fun cancelTag (Lokhttp3/OkHttpClient;Ljava/lang/Object;)V
}
public class com/facebook/react/config/ReactFeatureFlags {
public final class com/facebook/react/config/ReactFeatureFlags {
public static final field INSTANCE Lcom/facebook/react/config/ReactFeatureFlags;
public static field dispatchPointerEvents Z
public static field enableCppPropsIteratorSetter Z
public fun <init> ()V
}
public final class com/facebook/react/defaults/DefaultComponentsRegistry {
@@ -2076,8 +2058,8 @@ public class com/facebook/react/defaults/DefaultReactActivityDelegate : com/face
public final class com/facebook/react/defaults/DefaultReactHost {
public static final field INSTANCE Lcom/facebook/react/defaults/DefaultReactHost;
public static final fun getDefaultReactHost (Landroid/content/Context;Lcom/facebook/react/ReactNativeHost;)Lcom/facebook/react/ReactHost;
public static final fun getDefaultReactHost (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;)Lcom/facebook/react/ReactHost;
public static synthetic fun getDefaultReactHost$default (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;ILjava/lang/Object;)Lcom/facebook/react/ReactHost;
public static final fun getDefaultReactHost (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lcom/facebook/react/bridge/JSBundleLoader;)Lcom/facebook/react/ReactHost;
public static synthetic fun getDefaultReactHost$default (Landroid/content/Context;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLjava/util/List;Lcom/facebook/react/bridge/JSBundleLoader;ILjava/lang/Object;)Lcom/facebook/react/ReactHost;
}
public abstract class com/facebook/react/defaults/DefaultReactNativeHost : com/facebook/react/ReactNativeHost {
@@ -2230,7 +2212,6 @@ public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/
public fun startInspector ()V
public fun stopInspector ()V
public fun toggleElementInspector ()V
public fun updateJSError (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;I)V
}
public abstract interface class com/facebook/react/devsupport/DevSupportManagerBase$CallbackWithBundleLoader {
@@ -2398,7 +2379,6 @@ public class com/facebook/react/devsupport/ReleaseDevSupportManager : com/facebo
public fun startInspector ()V
public fun stopInspector ()V
public fun toggleElementInspector ()V
public fun updateJSError (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;I)V
}
public class com/facebook/react/devsupport/StackTraceHelper {
@@ -2534,7 +2514,6 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevSupp
public abstract fun startInspector ()V
public abstract fun stopInspector ()V
public abstract fun toggleElementInspector ()V
public abstract fun updateJSError (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;I)V
}
public abstract interface class com/facebook/react/devsupport/interfaces/DevSupportManager$PackagerLocationCustomizer {
@@ -2594,11 +2573,6 @@ public final class com/facebook/react/fabric/ComponentFactory {
}
public class com/facebook/react/fabric/DevToolsReactPerfLogger : com/facebook/react/bridge/ReactMarker$FabricMarkerListener {
public static final field mStreamingBatchExecutionStats Lcom/facebook/react/fabric/LongStreamingStats;
public static final field mStreamingCommitStats Lcom/facebook/react/fabric/LongStreamingStats;
public static final field mStreamingDiffStats Lcom/facebook/react/fabric/LongStreamingStats;
public static final field mStreamingLayoutStats Lcom/facebook/react/fabric/LongStreamingStats;
public static final field mStreamingTransactionEndStats Lcom/facebook/react/fabric/LongStreamingStats;
public fun <init> ()V
public fun addDevToolsReactPerfLoggerListener (Lcom/facebook/react/fabric/DevToolsReactPerfLogger$DevToolsReactPerfLoggerListener;)V
public fun logFabricMarker (Lcom/facebook/react/bridge/ReactMarkerConstants;Ljava/lang/String;IJ)V
@@ -2634,12 +2608,6 @@ public class com/facebook/react/fabric/DevToolsReactPerfLogger$FabricCommitPoint
public fun toString ()Ljava/lang/String;
}
public class com/facebook/react/fabric/DevToolsReactPerfLogger$FabricCommitPointData {
public fun <init> (JI)V
public fun getCounter ()I
public fun getTimeStamp ()J
}
public final class com/facebook/react/fabric/EmptyReactNativeConfig : com/facebook/react/fabric/ReactNativeConfig {
public fun <init> ()V
public fun getBool (Ljava/lang/String;)Z
@@ -3156,7 +3124,6 @@ public class com/facebook/react/modules/core/ExceptionsManagerModule : com/faceb
public fun reportException (Lcom/facebook/react/bridge/ReadableMap;)V
public fun reportFatalException (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;D)V
public fun reportSoftException (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;D)V
public fun updateExceptionMessage (Ljava/lang/String;Lcom/facebook/react/bridge/ReadableArray;D)V
}
public class com/facebook/react/modules/core/HeadlessJsTaskSupportModule : com/facebook/fbreact/specs/NativeHeadlessJsTaskSupportSpec {
@@ -1,131 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
/**
* {@code CompositeReactPackage} allows to create a single package composed of views and modules
* from several other packages.
*
* @deprecated
*/
@Deprecated(
since = "CompositeReactPackage is deprecated and will be deleted, use ReactPackage instead",
forRemoval = true)
public class CompositeReactPackage implements ViewManagerOnDemandReactPackage, ReactPackage {
private final List<ReactPackage> mChildReactPackages = new ArrayList<>();
/**
* The order in which packages are passed matters. It may happen that a NativeModule or a
* ViewManager exists in two or more ReactPackages. In that case the latter will win i.e. the
* latter will overwrite the former. This re-occurrence is detected by comparing a name of a
* module.
*/
public CompositeReactPackage(ReactPackage arg1, ReactPackage arg2, ReactPackage... args) {
mChildReactPackages.add(arg1);
mChildReactPackages.add(arg2);
Collections.addAll(mChildReactPackages, args);
}
/** {@inheritDoc} */
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
// This is for backward compatibility.
final Map<String, NativeModule> moduleMap = new HashMap<>();
for (ReactPackage reactPackage : mChildReactPackages) {
/**
* For now, we eagerly initialize the NativeModules inside BaseReactPackages. Ultimately, we
* should turn CompositeReactPackage into a BaseReactPackage and remove this eager
* initialization.
*
* <p>TODO: T45627020
*/
if (reactPackage instanceof BaseReactPackage) {
BaseReactPackage baseReactPackage = (BaseReactPackage) reactPackage;
ReactModuleInfoProvider moduleInfoProvider = baseReactPackage.getReactModuleInfoProvider();
Map<String, ReactModuleInfo> moduleInfos = moduleInfoProvider.getReactModuleInfos();
for (final String moduleName : moduleInfos.keySet()) {
moduleMap.put(moduleName, baseReactPackage.getModule(moduleName, reactContext));
}
continue;
}
for (NativeModule nativeModule : reactPackage.createNativeModules(reactContext)) {
moduleMap.put(nativeModule.getName(), nativeModule);
}
}
return new ArrayList<>(moduleMap.values());
}
/** {@inheritDoc} */
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
final Map<String, ViewManager> viewManagerMap = new HashMap<>();
for (ReactPackage reactPackage : mChildReactPackages) {
for (ViewManager viewManager : reactPackage.createViewManagers(reactContext)) {
viewManagerMap.put(viewManager.getName(), viewManager);
}
}
return new ArrayList<>(viewManagerMap.values());
}
/** {@inheritDoc} */
@Override
public Collection<String> getViewManagerNames(ReactApplicationContext reactContext) {
Set<String> uniqueNames = new HashSet<>();
for (ReactPackage reactPackage : mChildReactPackages) {
if (reactPackage instanceof ViewManagerOnDemandReactPackage) {
Collection<String> names =
((ViewManagerOnDemandReactPackage) reactPackage).getViewManagerNames(reactContext);
if (names != null) {
uniqueNames.addAll(names);
}
}
}
return uniqueNames;
}
/** {@inheritDoc} */
@Override
public @Nullable ViewManager createViewManager(
ReactApplicationContext reactContext, String viewManagerName) {
ListIterator<ReactPackage> iterator =
mChildReactPackages.listIterator(mChildReactPackages.size());
while (iterator.hasPrevious()) {
ReactPackage reactPackage = iterator.previous();
if (reactPackage instanceof ViewManagerOnDemandReactPackage) {
ViewManager viewManager =
((ViewManagerOnDemandReactPackage) reactPackage)
.createViewManager(reactContext, viewManagerName);
if (viewManager != null) {
return viewManager;
}
}
}
return null;
}
}
@@ -1,57 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react;
import androidx.annotation.NonNull;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.internal.turbomodule.core.TurboModuleManagerDelegate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Deprecated(
since =
"CompositeReactPackageTurboModuleManagerDelegate is deprecated and will be deleted in the"
+ " future. Please use ReactPackage interface or BaseReactPackage instead.")
@DoNotStrip
public class CompositeReactPackageTurboModuleManagerDelegate
extends ReactPackageTurboModuleManagerDelegate {
protected native HybridData initHybrid();
private CompositeReactPackageTurboModuleManagerDelegate(
ReactApplicationContext context,
List<ReactPackage> packages,
List<TurboModuleManagerDelegate> delegates) {
super(context, packages);
for (TurboModuleManagerDelegate delegate : delegates) {
addTurboModuleManagerDelegate(delegate);
}
}
private native void addTurboModuleManagerDelegate(TurboModuleManagerDelegate delegates);
public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
private final List<ReactPackageTurboModuleManagerDelegate.Builder> mDelegatesBuilder;
public Builder(@NonNull List<ReactPackageTurboModuleManagerDelegate.Builder> delegatesBuilder) {
mDelegatesBuilder = delegatesBuilder;
}
protected ReactPackageTurboModuleManagerDelegate build(
ReactApplicationContext context, List<ReactPackage> packages) {
List<TurboModuleManagerDelegate> delegates = new ArrayList<>();
for (ReactPackageTurboModuleManagerDelegate.Builder delegatesBuilder : mDelegatesBuilder) {
delegates.add(delegatesBuilder.build(context, Collections.<ReactPackage>emptyList()));
}
return new CompositeReactPackageTurboModuleManagerDelegate(context, packages, delegates);
}
}
}
@@ -1,31 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.config;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.proguard.annotations.DoNotStripAny;
/**
* Hi there, traveller! This configuration class is not meant to be used by end-users of RN. It
* contains mainly flags for features that are either under active development and not ready for
* public consumption, or for use in experiments.
*
* <p>These values are safe defaults and should not require manual changes.
*/
@Nullsafe(Nullsafe.Mode.LOCAL)
@Deprecated(since = "Use com.facebook.react.internal.featureflags.ReactNativeFeatureFlags instead.")
@DoNotStripAny
public class ReactFeatureFlags {
public static boolean dispatchPointerEvents = false;
/**
* Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java).
*/
public static boolean enableCppPropsIteratorSetter = false;
}
@@ -0,0 +1,24 @@
/*
* 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.config
import com.facebook.proguard.annotations.DoNotStripAny
import kotlin.jvm.JvmField
/**
* Hi there, traveller! This configuration class is not meant to be used by end-users of RN. It
* contains mainly flags for features that are either under active development and not ready for
* public consumption, or for use in experiments.
*
* These values are safe defaults and should not require manual changes.
*/
@Deprecated("Use com.facebook.react.internal.featureflags.ReactNativeFeatureFlags instead.")
@DoNotStripAny
public object ReactFeatureFlags {
@JvmField public var dispatchPointerEvents: Boolean = false
}
@@ -45,6 +45,7 @@ public object DefaultReactHost {
* @param useDevSupport whether to enable dev support, default to ReactBuildConfig.DEBUG.
* @param cxxReactPackageProviders a list of cxxreactpackage providers (to register c++ turbo
* modules)
* @param jsBundleLoader a [JSBundleLoader] to use for creating the [ReactHost]
*
* TODO(T186951312): Should this be @UnstableReactNativeAPI?
*/
@@ -59,25 +60,28 @@ public object DefaultReactHost {
isHermesEnabled: Boolean = true,
useDevSupport: Boolean = ReactBuildConfig.DEBUG,
cxxReactPackageProviders: List<(ReactContext) -> CxxReactPackage> = emptyList(),
jsBundleLoader: JSBundleLoader? = null,
): ReactHost {
if (reactHost == null) {
val jsBundleLoader =
if (jsBundleFilePath != null) {
if (jsBundleFilePath.startsWith("assets://")) {
JSBundleLoader.createAssetLoader(context, jsBundleFilePath, true)
} else {
JSBundleLoader.createFileLoader(jsBundleFilePath)
}
} else {
JSBundleLoader.createAssetLoader(context, "assets://$jsBundleAssetPath", true)
}
val bundleLoader =
jsBundleLoader
?: if (jsBundleFilePath != null) {
if (jsBundleFilePath.startsWith("assets://")) {
JSBundleLoader.createAssetLoader(context, jsBundleFilePath, true)
} else {
JSBundleLoader.createFileLoader(jsBundleFilePath)
}
} else {
JSBundleLoader.createAssetLoader(context, "assets://$jsBundleAssetPath", true)
}
val jsRuntimeFactory = if (isHermesEnabled) HermesInstance() else JSCInstance()
val defaultTmmDelegateBuilder = DefaultTurboModuleManagerDelegate.Builder()
cxxReactPackageProviders.forEach { defaultTmmDelegateBuilder.addCxxReactPackage(it) }
val defaultReactHostDelegate =
DefaultReactHostDelegate(
jsMainModulePath = jsMainModulePath,
jsBundleLoader = jsBundleLoader,
jsBundleLoader = bundleLoader,
reactPackages = packageList,
jsRuntimeFactory = jsRuntimeFactory,
turboModuleManagerDelegateBuilder = defaultTmmDelegateBuilder)
@@ -111,7 +111,7 @@ protected constructor(
packages,
jsMainModuleName,
bundleAssetName ?: "index",
null,
jsBundleFile,
isHermesEnabled ?: true,
useDeveloperSupport,
)
@@ -279,26 +279,6 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
return errorInfo;
}
@Override
public void updateJSError(
final String message, final ReadableArray details, final int errorCookie) {
UiThreadUtil.runOnUiThread(
() -> {
// Since we only show the first JS error in a succession of JS errors, make sure we only
// update the error message for that error message. This assumes that updateJSError
// belongs to the most recent showNewJSError
if ((mRedBoxSurfaceDelegate != null && !mRedBoxSurfaceDelegate.isShowing())
|| errorCookie != mLastErrorCookie) {
return;
}
// The RedBox surface delegate will always show the latest error
updateLastErrorInfo(
message, StackTraceHelper.convertJsStackTrace(details), errorCookie, ErrorType.JS);
mRedBoxSurfaceDelegate.show();
});
}
@Override
public void hideRedboxDialog() {
if (mRedBoxSurfaceDelegate == null) {
@@ -53,12 +53,6 @@ public open class ReleaseDevSupportManager : DevSupportManager {
override public fun destroyRootView(rootView: View?): Unit = Unit
override public fun updateJSError(
message: String?,
details: ReadableArray?,
errorCookie: Int
): Unit = Unit
override public fun hideRedboxDialog(): Unit = Unit
override public fun showDevOptionsDialog(): Unit = Unit
@@ -48,8 +48,6 @@ public interface DevSupportManager : JSExceptionHandler {
public fun showNewJSError(message: String?, details: ReadableArray?, errorCookie: Int)
public fun updateJSError(message: String?, details: ReadableArray?, errorCookie: Int)
public fun hideRedboxDialog()
public fun showDevOptionsDialog()
@@ -37,18 +37,17 @@ public class DevToolsReactPerfLogger implements ReactMarker.FabricMarkerListener
private final List<DevToolsReactPerfLoggerListener> mDevToolsReactPerfLoggerListeners =
new ArrayList<>();
public static final LongStreamingStats mStreamingCommitStats = new LongStreamingStats();
public static final LongStreamingStats mStreamingLayoutStats = new LongStreamingStats();
public static final LongStreamingStats mStreamingDiffStats = new LongStreamingStats();
public static final LongStreamingStats mStreamingTransactionEndStats = new LongStreamingStats();
public static final LongStreamingStats mStreamingBatchExecutionStats = new LongStreamingStats();
static final LongStreamingStats mStreamingCommitStats = new LongStreamingStats();
static final LongStreamingStats mStreamingLayoutStats = new LongStreamingStats();
static final LongStreamingStats mStreamingDiffStats = new LongStreamingStats();
static final LongStreamingStats mStreamingTransactionEndStats = new LongStreamingStats();
static final LongStreamingStats mStreamingBatchExecutionStats = new LongStreamingStats();
public interface DevToolsReactPerfLoggerListener {
void onFabricCommitEnd(FabricCommitPoint commitPoint);
}
public static class FabricCommitPointData {
private static class FabricCommitPointData {
private final long mTimeStamp;
private final int mCounter;
@@ -1,76 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.fabric;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
/* package */
class LongStreamingStats {
// TODO(T138627466): Calculate median value with better algorithm after Android API 24.
private final Queue<Long> minHeap =
new PriorityQueue<>(11, Comparator.comparingLong(aLong -> aLong));
private final Queue<Long> maxHeap =
new PriorityQueue<>(
11,
(first, second) -> {
// Reversed order
return Long.compare(second, first);
});
private double streamingAverage = 0.0;
private int len = 0;
private long max = 0;
LongStreamingStats() {}
public void add(long n) {
// To make medians more useful, we discard all zero values
// This isn't perfect and certainly makes this a totally invalid median, but, alas...
if (n != 0) {
if (minHeap.size() == maxHeap.size()) {
maxHeap.offer(n);
minHeap.offer(maxHeap.poll());
} else {
minHeap.offer(n);
maxHeap.offer(minHeap.poll());
}
}
len++;
if (len == 1) {
streamingAverage = n;
} else {
streamingAverage = (streamingAverage / (len / (len - 1))) + (n / len);
}
max = (n > max ? n : max);
}
public double getMedian() {
if (minHeap.size() == 0 && maxHeap.size() == 0) {
return 0;
}
long median;
if (minHeap.size() > maxHeap.size()) {
median = minHeap.peek();
} else {
median = (minHeap.peek() + maxHeap.peek()) / 2;
}
return median;
}
public double getAverage() {
return streamingAverage;
}
public long getMax() {
return max;
}
}
@@ -0,0 +1,62 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.fabric
import java.util.PriorityQueue
import java.util.Queue
import kotlin.comparisons.reverseOrder
internal class LongStreamingStats {
// TODO(T138627466): Calculate median value with better algorithm after Android API 24.
private val minHeap: Queue<Long> = PriorityQueue(11)
private val maxHeap: Queue<Long> = PriorityQueue(11, reverseOrder())
var average: Double = 0.0
private set
private var len = 0
var max: Long = 0L
private set
fun add(n: Long) {
// To make medians more useful, we discard all zero values
// This isn't perfect and certainly makes this a totally invalid median, but, alas...
if (n != 0L) {
if (minHeap.size == maxHeap.size) {
maxHeap.offer(n)
minHeap.offer(maxHeap.poll())
} else {
minHeap.offer(n)
maxHeap.offer(minHeap.poll())
}
}
len++
if (len == 1) {
average = n.toDouble()
} else {
average = (average / (len / (len - 1))) + (n / len)
}
max = (if (n > max) n else max)
}
val median: Double
get() {
if (minHeap.size == 0 && maxHeap.size == 0) {
return 0.0
}
val median =
if (minHeap.size > maxHeap.size) {
minHeap.peek()
} else {
(minHeap.peek() ?: 0 + maxHeap.peek()!!) / 2
}
return median.toDouble()
}
}
@@ -1,90 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.fabric.mounting.mountitems;
import static com.facebook.react.fabric.FabricUIManager.IS_DEVELOPMENT_ENVIRONMENT;
import static com.facebook.react.fabric.FabricUIManager.TAG;
import static com.facebook.react.fabric.mounting.mountitems.FabricNameComponentMapping.getFabricComponentName;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.facebook.common.logging.FLog;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.fabric.mounting.MountingManager;
import com.facebook.react.fabric.mounting.SurfaceMountingManager;
import com.facebook.react.uimanager.StateWrapper;
/** {@link MountItem} that is used to pre-allocate views for JS components. */
@Nullsafe(Nullsafe.Mode.LOCAL)
final class PreAllocateViewMountItem implements MountItem {
private final @NonNull String mComponent;
private final int mSurfaceId;
private final int mReactTag;
private final @Nullable ReadableMap mProps;
private final @Nullable StateWrapper mStateWrapper;
private final boolean mIsLayoutable;
PreAllocateViewMountItem(
int surfaceId,
int reactTag,
@NonNull String component,
@Nullable ReadableMap props,
@Nullable StateWrapper stateWrapper,
boolean isLayoutable) {
mComponent = getFabricComponentName(component);
mSurfaceId = surfaceId;
mProps = props;
mStateWrapper = stateWrapper;
mReactTag = reactTag;
mIsLayoutable = isLayoutable;
}
@Override
public int getSurfaceId() {
return mSurfaceId;
}
@Override
public void execute(@NonNull MountingManager mountingManager) {
SurfaceMountingManager surfaceMountingManager = mountingManager.getSurfaceManager(mSurfaceId);
if (surfaceMountingManager == null) {
FLog.e(
TAG,
"Skipping View PreAllocation; no SurfaceMountingManager found for [" + mSurfaceId + "]");
return;
}
surfaceMountingManager.preallocateView(
mComponent, mReactTag, mProps, mStateWrapper, mIsLayoutable);
}
@Override
@NonNull
public String toString() {
StringBuilder result =
new StringBuilder("PreAllocateViewMountItem [")
.append(mReactTag)
.append("] - component: ")
.append(mComponent)
.append(" surfaceId: ")
.append(mSurfaceId)
.append(" isLayoutable: ")
.append(mIsLayoutable);
if (IS_DEVELOPMENT_ENVIRONMENT) {
result
.append(" props: ")
.append(mProps != null ? mProps.toString() : "<null>")
.append(" state: ")
.append(mStateWrapper != null ? mStateWrapper.toString() : "<null>");
}
return result.toString();
}
}
@@ -0,0 +1,63 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.fabric.mounting.mountitems
import com.facebook.common.logging.FLog
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.fabric.FabricUIManager
import com.facebook.react.fabric.mounting.MountingManager
import com.facebook.react.fabric.mounting.mountitems.FabricNameComponentMapping.getFabricComponentName
import com.facebook.react.uimanager.StateWrapper
/** [MountItem] that is used to pre-allocate views for JS components. */
internal class PreAllocateViewMountItem(
private val surfaceId: Int,
private val reactTag: Int,
component: String,
private val props: ReadableMap?,
private val stateWrapper: StateWrapper?,
private val isLayoutable: Boolean
) : MountItem {
private val fabricComponentName = getFabricComponentName(component)
override fun getSurfaceId(): Int = surfaceId
override fun execute(mountingManager: MountingManager) {
val surfaceMountingManager = mountingManager.getSurfaceManager(surfaceId)
if (surfaceMountingManager == null) {
FLog.e(
FabricUIManager.TAG,
"Skipping View PreAllocation; no SurfaceMountingManager found for [$surfaceId]")
return
}
surfaceMountingManager.preallocateView(
fabricComponentName, reactTag, props, stateWrapper, isLayoutable)
}
override fun toString(): String {
val result =
StringBuilder("PreAllocateViewMountItem [")
.append(reactTag)
.append("] - component: ")
.append(fabricComponentName)
.append(" surfaceId: ")
.append(surfaceId)
.append(" isLayoutable: ")
.append(isLayoutable)
if (FabricUIManager.IS_DEVELOPMENT_ENVIRONMENT) {
result
.append(" props: ")
.append(props?.toString() ?: "<null>")
.append(" state: ")
.append(stateWrapper?.toString() ?: "<null>")
}
return result.toString()
}
}
@@ -17,33 +17,33 @@ public interface ReactSurface {
// the API of this interface will be completed as we analyze and refactor API of ReactSurface,
// ReactRootView, etc.
// Returns surface ID of this surface
/** Returns surface ID of this surface */
public val surfaceID: Int
// Returns module name of this surface
/** Returns module name of this surface */
public val moduleName: String
// Returns whether the surface is running or not
/** Returns whether the surface is running or not */
public val isRunning: Boolean
// Returns React root view of this surface
/** Returns React root view of this surface */
public val view: ViewGroup?
// Returns context associated with the surface
/** Returns context associated with the surface */
public val context: Context
// Prerender this surface
/** Prerender this surface */
public fun prerender(): TaskInterface<Void>
// Start running this surface
/** Start running this surface */
public fun start(): TaskInterface<Void>
// Stop running this surface
/** Stop running this surface */
public fun stop(): TaskInterface<Void>
// Clear surface
/** Clear surface */
public fun clear()
// Detach surface from Host
/** Detach surface from Host */
public fun detach()
}
@@ -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<<6eb9ba14445c1ce6b54a690941171485>>
* @generated SignedSource<<64521c5f18fcaf7092590a2629bb8418>>
*/
/**
@@ -52,6 +52,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun disableEventLoopOnBridgeless(): Boolean = accessor.disableEventLoopOnBridgeless()
/**
* Prevent FabricMountingManager from reordering mountitems, which may lead to invalid state on the UI thread
*/
@JvmStatic
public fun disableMountItemReorderingAndroid(): Boolean = accessor.disableMountItemReorderingAndroid()
/**
* Kill-switch to turn off support for aling-items:baseline on Fabric iOS.
*/
@@ -71,10 +77,10 @@ public object ReactNativeFeatureFlags {
public fun enableBridgelessArchitecture(): Boolean = accessor.enableBridgelessArchitecture()
/**
* Clean yoga node when <TextInput /> does not change.
* Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java).
*/
@JvmStatic
public fun enableCleanTextInputYogaNode(): Boolean = accessor.enableCleanTextInputYogaNode()
public fun enableCppPropsIteratorSetter(): Boolean = accessor.enableCppPropsIteratorSetter()
/**
* Deletes views that were pre-allocated but never mounted on the screen.
@@ -172,12 +178,6 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableSynchronousStateUpdates(): Boolean = accessor.enableSynchronousStateUpdates()
/**
* Text preallocation optimisation where unnecessary work is removed.
*/
@JvmStatic
public fun enableTextPreallocationOptimisation(): Boolean = accessor.enableTextPreallocationOptimisation()
/**
* Ensures that JavaScript always has a consistent view of the state of the UI (e.g.: commits done in other threads are not immediately propagated to JS during its execution).
*/
@@ -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<<f88e475c51f2595d8ead29ff66e84da1>>
* @generated SignedSource<<8ed11f58c6671703e4021a91256d315d>>
*/
/**
@@ -24,10 +24,11 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null
private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null
private var disableEventLoopOnBridgelessCache: Boolean? = null
private var disableMountItemReorderingAndroidCache: Boolean? = null
private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null
private var enableAndroidLineHeightCenteringCache: Boolean? = null
private var enableBridgelessArchitectureCache: Boolean? = null
private var enableCleanTextInputYogaNodeCache: Boolean? = null
private var enableCppPropsIteratorSetterCache: Boolean? = null
private var enableDeletionOfUnmountedViewsCache: Boolean? = null
private var enableEagerRootViewAttachmentCache: Boolean? = null
private var enableEventEmitterRetentionDuringGesturesOnAndroidCache: Boolean? = null
@@ -44,7 +45,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null
private var enableReportEventPaintTimeCache: Boolean? = null
private var enableSynchronousStateUpdatesCache: Boolean? = null
private var enableTextPreallocationOptimisationCache: Boolean? = null
private var enableUIConsistencyCache: Boolean? = null
private var enableViewRecyclingCache: Boolean? = null
private var excludeYogaFromRawPropsCache: Boolean? = null
@@ -103,6 +103,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}
override fun disableMountItemReorderingAndroid(): Boolean {
var cached = disableMountItemReorderingAndroidCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.disableMountItemReorderingAndroid()
disableMountItemReorderingAndroidCache = cached
}
return cached
}
override fun enableAlignItemsBaselineOnFabricIOS(): Boolean {
var cached = enableAlignItemsBaselineOnFabricIOSCache
if (cached == null) {
@@ -130,11 +139,11 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}
override fun enableCleanTextInputYogaNode(): Boolean {
var cached = enableCleanTextInputYogaNodeCache
override fun enableCppPropsIteratorSetter(): Boolean {
var cached = enableCppPropsIteratorSetterCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableCleanTextInputYogaNode()
enableCleanTextInputYogaNodeCache = cached
cached = ReactNativeFeatureFlagsCxxInterop.enableCppPropsIteratorSetter()
enableCppPropsIteratorSetterCache = cached
}
return cached
}
@@ -283,15 +292,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}
override fun enableTextPreallocationOptimisation(): Boolean {
var cached = enableTextPreallocationOptimisationCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableTextPreallocationOptimisation()
enableTextPreallocationOptimisationCache = cached
}
return cached
}
override fun enableUIConsistency(): Boolean {
var cached = enableUIConsistencyCache
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<<a16a01bbf3c2404ed7c6fa569d68b505>>
* @generated SignedSource<<6f5d74e7ec13afa88fbd088182f0ba2b>>
*/
/**
@@ -36,13 +36,15 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun disableEventLoopOnBridgeless(): Boolean
@DoNotStrip @JvmStatic public external fun disableMountItemReorderingAndroid(): Boolean
@DoNotStrip @JvmStatic public external fun enableAlignItemsBaselineOnFabricIOS(): Boolean
@DoNotStrip @JvmStatic public external fun enableAndroidLineHeightCentering(): Boolean
@DoNotStrip @JvmStatic public external fun enableBridgelessArchitecture(): Boolean
@DoNotStrip @JvmStatic public external fun enableCleanTextInputYogaNode(): Boolean
@DoNotStrip @JvmStatic public external fun enableCppPropsIteratorSetter(): Boolean
@DoNotStrip @JvmStatic public external fun enableDeletionOfUnmountedViews(): Boolean
@@ -76,8 +78,6 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun enableSynchronousStateUpdates(): Boolean
@DoNotStrip @JvmStatic public external fun enableTextPreallocationOptimisation(): Boolean
@DoNotStrip @JvmStatic public external fun enableUIConsistency(): Boolean
@DoNotStrip @JvmStatic public external fun enableViewRecycling(): 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<<1ce9496b005924d8a421899ce55f6d81>>
* @generated SignedSource<<e1868b062c62107e77fe2897a0681e6e>>
*/
/**
@@ -31,13 +31,15 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun disableEventLoopOnBridgeless(): Boolean = false
override fun disableMountItemReorderingAndroid(): Boolean = false
override fun enableAlignItemsBaselineOnFabricIOS(): Boolean = true
override fun enableAndroidLineHeightCentering(): Boolean = false
override fun enableBridgelessArchitecture(): Boolean = false
override fun enableCleanTextInputYogaNode(): Boolean = false
override fun enableCppPropsIteratorSetter(): Boolean = false
override fun enableDeletionOfUnmountedViews(): Boolean = false
@@ -71,8 +73,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun enableSynchronousStateUpdates(): Boolean = false
override fun enableTextPreallocationOptimisation(): Boolean = false
override fun enableUIConsistency(): Boolean = false
override fun enableViewRecycling(): Boolean = false
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<b6dd6a5d02c9070c3f35f70d5d1b7e35>>
* @generated SignedSource<<c6e809489f71a930ad05d83a4ef37cde>>
*/
/**
@@ -28,10 +28,11 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null
private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null
private var disableEventLoopOnBridgelessCache: Boolean? = null
private var disableMountItemReorderingAndroidCache: Boolean? = null
private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null
private var enableAndroidLineHeightCenteringCache: Boolean? = null
private var enableBridgelessArchitectureCache: Boolean? = null
private var enableCleanTextInputYogaNodeCache: Boolean? = null
private var enableCppPropsIteratorSetterCache: Boolean? = null
private var enableDeletionOfUnmountedViewsCache: Boolean? = null
private var enableEagerRootViewAttachmentCache: Boolean? = null
private var enableEventEmitterRetentionDuringGesturesOnAndroidCache: Boolean? = null
@@ -48,7 +49,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null
private var enableReportEventPaintTimeCache: Boolean? = null
private var enableSynchronousStateUpdatesCache: Boolean? = null
private var enableTextPreallocationOptimisationCache: Boolean? = null
private var enableUIConsistencyCache: Boolean? = null
private var enableViewRecyclingCache: Boolean? = null
private var excludeYogaFromRawPropsCache: Boolean? = null
@@ -111,6 +111,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun disableMountItemReorderingAndroid(): Boolean {
var cached = disableMountItemReorderingAndroidCache
if (cached == null) {
cached = currentProvider.disableMountItemReorderingAndroid()
accessedFeatureFlags.add("disableMountItemReorderingAndroid")
disableMountItemReorderingAndroidCache = cached
}
return cached
}
override fun enableAlignItemsBaselineOnFabricIOS(): Boolean {
var cached = enableAlignItemsBaselineOnFabricIOSCache
if (cached == null) {
@@ -141,12 +151,12 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun enableCleanTextInputYogaNode(): Boolean {
var cached = enableCleanTextInputYogaNodeCache
override fun enableCppPropsIteratorSetter(): Boolean {
var cached = enableCppPropsIteratorSetterCache
if (cached == null) {
cached = currentProvider.enableCleanTextInputYogaNode()
accessedFeatureFlags.add("enableCleanTextInputYogaNode")
enableCleanTextInputYogaNodeCache = cached
cached = currentProvider.enableCppPropsIteratorSetter()
accessedFeatureFlags.add("enableCppPropsIteratorSetter")
enableCppPropsIteratorSetterCache = cached
}
return cached
}
@@ -311,16 +321,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun enableTextPreallocationOptimisation(): Boolean {
var cached = enableTextPreallocationOptimisationCache
if (cached == null) {
cached = currentProvider.enableTextPreallocationOptimisation()
accessedFeatureFlags.add("enableTextPreallocationOptimisation")
enableTextPreallocationOptimisationCache = cached
}
return cached
}
override fun enableUIConsistency(): Boolean {
var cached = enableUIConsistencyCache
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<<12dbd7afae2f6360d17df521ebc53d2f>>
* @generated SignedSource<<4c0f737c0dfaa5095d46defe1f67bddf>>
*/
/**
@@ -31,13 +31,15 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun disableEventLoopOnBridgeless(): Boolean
@DoNotStrip public fun disableMountItemReorderingAndroid(): Boolean
@DoNotStrip public fun enableAlignItemsBaselineOnFabricIOS(): Boolean
@DoNotStrip public fun enableAndroidLineHeightCentering(): Boolean
@DoNotStrip public fun enableBridgelessArchitecture(): Boolean
@DoNotStrip public fun enableCleanTextInputYogaNode(): Boolean
@DoNotStrip public fun enableCppPropsIteratorSetter(): Boolean
@DoNotStrip public fun enableDeletionOfUnmountedViews(): Boolean
@@ -71,8 +73,6 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun enableSynchronousStateUpdates(): Boolean
@DoNotStrip public fun enableTextPreallocationOptimisation(): Boolean
@DoNotStrip public fun enableUIConsistency(): Boolean
@DoNotStrip public fun enableViewRecycling(): Boolean
@@ -60,17 +60,6 @@ public open class ExceptionsManagerModule(private val devSupportManager: DevSupp
}
}
override fun updateExceptionMessage(
title: String?,
details: ReadableArray?,
exceptionIdDouble: Double
) {
val exceptionId = exceptionIdDouble.toInt()
if (devSupportManager.devSupportEnabled) {
devSupportManager.updateJSError(title, details, exceptionId)
}
}
override fun dismissRedbox() {
if (devSupportManager.devSupportEnabled) {
devSupportManager.hideRedboxDialog()
@@ -923,17 +923,19 @@ public class ReactHostImpl implements ReactHost {
final String method = "getOrCreateStartTask()";
if (mStartTask == null) {
log(method, "Schedule");
Assertions.assertCondition(
ReactNativeFeatureFlags.enableBridgelessArchitecture(),
"enableBridgelessArchitecture FeatureFlag must be set to start ReactNative.");
if (ReactBuildConfig.DEBUG) {
Assertions.assertCondition(
ReactNativeFeatureFlags.enableBridgelessArchitecture(),
"enableBridgelessArchitecture FeatureFlag must be set to start ReactNative.");
Assertions.assertCondition(
ReactNativeFeatureFlags.enableFabricRenderer(),
"enableFabricRenderer FeatureFlag must be set to start ReactNative.");
Assertions.assertCondition(
ReactNativeFeatureFlags.enableFabricRenderer(),
"enableFabricRenderer FeatureFlag must be set to start ReactNative.");
Assertions.assertCondition(
ReactNativeFeatureFlags.useTurboModules(),
"useTurboModules FeatureFlag must be set to start ReactNative.");
Assertions.assertCondition(
ReactNativeFeatureFlags.useTurboModules(),
"useTurboModules FeatureFlag must be set to start ReactNative.");
}
mStartTask =
waitThenCallGetOrCreateReactInstanceTask()
.continueWithTask(
@@ -48,13 +48,8 @@ public enum TextTransform {
StringBuilder res = new StringBuilder(text.length());
int start = wordIterator.first();
for (int end = wordIterator.next(); end != BreakIterator.DONE; end = wordIterator.next()) {
String word = text.substring(start, end);
if (Character.isLetterOrDigit(word.charAt(0))) {
res.append(Character.toUpperCase(word.charAt(0)));
res.append(word.substring(1).toLowerCase());
} else {
res.append(word);
}
res.append(Character.toUpperCase(text.charAt(start)));
res.append(text.substring(start + 1, end));
start = end;
}
@@ -16,9 +16,9 @@ namespace facebook::react {
AndroidEventBeat::AndroidEventBeat(
std::shared_ptr<OwnerBox> ownerBox,
EventBeatManager* eventBeatManager,
RuntimeExecutor runtimeExecutor,
RuntimeScheduler& runtimeScheduler,
jni::global_ref<jobject> javaUIManager)
: EventBeat(std::move(ownerBox), std::move(runtimeExecutor)),
: EventBeat(std::move(ownerBox), runtimeScheduler),
eventBeatManager_(eventBeatManager),
javaUIManager_(std::move(javaUIManager)) {
eventBeatManager->addObserver(*this);
@@ -19,7 +19,7 @@ class AndroidEventBeat final : public EventBeat,
AndroidEventBeat(
std::shared_ptr<OwnerBox> ownerBox,
EventBeatManager* eventBeatManager,
RuntimeExecutor runtimeExecutor,
RuntimeScheduler& runtimeScheduler,
jni::global_ref<jobject> javaUIManager);
~AndroidEventBeat() override;
@@ -19,7 +19,6 @@
#include <react/renderer/mounting/MountingTransaction.h>
#include <react/renderer/mounting/ShadowView.h>
#include <react/renderer/mounting/ShadowViewMutation.h>
#include <react/utils/CoreFeatures.h>
#include <fbjni/fbjni.h>
#include <glog/logging.h>
@@ -38,7 +37,8 @@ FabricMountingManager::FabricMountingManager(
void FabricMountingManager::onSurfaceStart(SurfaceId surfaceId) {
std::lock_guard lock(allocatedViewsMutex_);
allocatedViewRegistry_.emplace(surfaceId, std::unordered_set<Tag>{});
allocatedViewRegistry_.emplace(
surfaceId, std::unordered_set<Tag>({surfaceId}));
}
void FabricMountingManager::onSurfaceStop(SurfaceId surfaceId) {
@@ -466,6 +466,9 @@ void FabricMountingManager::executeMount(
auto surfaceId = transaction.getSurfaceId();
auto& mutations = transaction.getMutations();
bool maintainMutationOrder =
ReactNativeFeatureFlags::disableMountItemReorderingAndroid();
auto revisionNumber = telemetry.getRevisionNumber();
std::vector<CppMountItem> cppCommonMountItems;
@@ -487,7 +490,7 @@ void FabricMountingManager::executeMount(
// operand is a value type, the compiler will decide the expression to be a
// value type, an unnecessary (sometimes expensive) copy will happen as a
// result.
const auto& allocatedViewTags =
auto& allocatedViewTags =
allocatedViewsIterator != allocatedViewRegistry_.end()
? allocatedViewsIterator->second
: defaultAllocatedViews;
@@ -511,6 +514,7 @@ void FabricMountingManager::executeMount(
if (shouldCreateView) {
cppCommonMountItems.push_back(
CppMountItem::CreateMountItem(newChildShadowView));
allocatedViewTags.insert(newChildShadowView.tag);
}
break;
}
@@ -522,20 +526,32 @@ void FabricMountingManager::executeMount(
break;
}
case ShadowViewMutation::Delete: {
cppDeleteMountItems.push_back(
CppMountItem::DeleteMountItem(oldChildShadowView));
(maintainMutationOrder ? cppCommonMountItems : cppDeleteMountItems)
.push_back(CppMountItem::DeleteMountItem(oldChildShadowView));
if (allocatedViewTags.erase(oldChildShadowView.tag) != 1) {
LOG(ERROR) << "Emitting delete for unallocated view. "
<< oldChildShadowView.tag;
}
break;
}
case ShadowViewMutation::Update: {
if (!isVirtual) {
if (!allocatedViewTags.contains(newChildShadowView.tag)) {
LOG(FATAL) << "Emitting update for unallocated view. "
<< newChildShadowView.tag;
}
if (oldChildShadowView.props != newChildShadowView.props) {
cppUpdatePropsMountItems.push_back(
CppMountItem::UpdatePropsMountItem(
(maintainMutationOrder ? cppCommonMountItems
: cppUpdatePropsMountItems)
.push_back(CppMountItem::UpdatePropsMountItem(
oldChildShadowView, newChildShadowView));
}
if (oldChildShadowView.state != newChildShadowView.state) {
cppUpdateStateMountItems.push_back(
CppMountItem::UpdateStateMountItem(newChildShadowView));
(maintainMutationOrder ? cppCommonMountItems
: cppUpdateStateMountItems)
.push_back(
CppMountItem::UpdateStateMountItem(newChildShadowView));
}
// Padding: padding mountItems must be executed before layout props
@@ -544,14 +560,17 @@ void FabricMountingManager::executeMount(
// padding information.
if (oldChildShadowView.layoutMetrics.contentInsets !=
newChildShadowView.layoutMetrics.contentInsets) {
cppUpdatePaddingMountItems.push_back(
CppMountItem::UpdatePaddingMountItem(newChildShadowView));
(maintainMutationOrder ? cppCommonMountItems
: cppUpdatePaddingMountItems)
.push_back(
CppMountItem::UpdatePaddingMountItem(newChildShadowView));
}
if (oldChildShadowView.layoutMetrics !=
newChildShadowView.layoutMetrics) {
cppUpdateLayoutMountItems.push_back(
CppMountItem::UpdateLayoutMountItem(
(maintainMutationOrder ? cppCommonMountItems
: cppUpdateLayoutMountItems)
.push_back(CppMountItem::UpdateLayoutMountItem(
mutation.newChildShadowView, parentShadowView));
}
@@ -561,16 +580,18 @@ void FabricMountingManager::executeMount(
// pack too much data there.
if ((oldChildShadowView.layoutMetrics.overflowInset !=
newChildShadowView.layoutMetrics.overflowInset)) {
cppUpdateOverflowInsetMountItems.push_back(
CppMountItem::UpdateOverflowInsetMountItem(
(maintainMutationOrder ? cppCommonMountItems
: cppUpdateOverflowInsetMountItems)
.push_back(CppMountItem::UpdateOverflowInsetMountItem(
newChildShadowView));
}
}
if (oldChildShadowView.eventEmitter !=
newChildShadowView.eventEmitter) {
cppUpdateEventEmitterMountItems.push_back(
CppMountItem::UpdateEventEmitterMountItem(
(maintainMutationOrder ? cppCommonMountItems
: cppUpdatePropsMountItems)
.push_back(CppMountItem::UpdateEventEmitterMountItem(
mutation.newChildShadowView));
}
break;
@@ -581,19 +602,23 @@ void FabricMountingManager::executeMount(
cppCommonMountItems.push_back(CppMountItem::InsertMountItem(
parentShadowView, newChildShadowView, index));
bool allocationCheck =
allocatedViewTags.find(newChildShadowView.tag) ==
allocatedViewTags.end();
bool shouldCreateView = allocationCheck;
bool shouldCreateView =
!allocatedViewTags.contains(newChildShadowView.tag);
if (shouldCreateView) {
cppUpdatePropsMountItems.push_back(
CppMountItem::UpdatePropsMountItem({}, newChildShadowView));
LOG(ERROR) << "Emitting insert for unallocated view. "
<< newChildShadowView.tag;
(maintainMutationOrder ? cppCommonMountItems
: cppUpdatePropsMountItems)
.push_back(CppMountItem::UpdatePropsMountItem(
{}, newChildShadowView));
}
// State
if (newChildShadowView.state) {
cppUpdateStateMountItems.push_back(
CppMountItem::UpdateStateMountItem(newChildShadowView));
(maintainMutationOrder ? cppCommonMountItems
: cppUpdateStateMountItems)
.push_back(
CppMountItem::UpdateStateMountItem(newChildShadowView));
}
// Padding: padding mountItems must be executed before layout props
@@ -602,13 +627,16 @@ void FabricMountingManager::executeMount(
// padding information.
if (newChildShadowView.layoutMetrics.contentInsets !=
EdgeInsets::ZERO) {
cppUpdatePaddingMountItems.push_back(
CppMountItem::UpdatePaddingMountItem(newChildShadowView));
(maintainMutationOrder ? cppCommonMountItems
: cppUpdatePaddingMountItems)
.push_back(
CppMountItem::UpdatePaddingMountItem(newChildShadowView));
}
// Layout
cppUpdateLayoutMountItems.push_back(
CppMountItem::UpdateLayoutMountItem(
(maintainMutationOrder ? cppCommonMountItems
: cppUpdateLayoutMountItems)
.push_back(CppMountItem::UpdateLayoutMountItem(
newChildShadowView, parentShadowView));
// OverflowInset: This is the values indicating boundaries including
@@ -617,15 +645,19 @@ void FabricMountingManager::executeMount(
// pack too much data there.
if (newChildShadowView.layoutMetrics.overflowInset !=
EdgeInsets::ZERO) {
cppUpdateOverflowInsetMountItems.push_back(
CppMountItem::UpdateOverflowInsetMountItem(
(maintainMutationOrder ? cppCommonMountItems
: cppUpdateOverflowInsetMountItems)
.push_back(CppMountItem::UpdateOverflowInsetMountItem(
newChildShadowView));
}
}
// EventEmitter
cppUpdateEventEmitterMountItems.push_back(
CppMountItem::UpdateEventEmitterMountItem(
// On insert we always update the event emitter, as we do not pass
// it in when preallocating views
(maintainMutationOrder ? cppCommonMountItems
: cppUpdateEventEmitterMountItems)
.push_back(CppMountItem::UpdateEventEmitterMountItem(
mutation.newChildShadowView));
break;
@@ -635,22 +667,6 @@ void FabricMountingManager::executeMount(
}
}
}
if (allocatedViewsIterator != allocatedViewRegistry_.end()) {
auto& views = allocatedViewsIterator->second;
for (const auto& mutation : mutations) {
switch (mutation.type) {
case ShadowViewMutation::Create:
views.insert(mutation.newChildShadowView.tag);
break;
case ShadowViewMutation::Delete:
views.erase(mutation.oldChildShadowView.tag);
break;
default:
break;
}
}
}
}
// We now have all the information we need, including ordering of mount items,
@@ -729,12 +745,33 @@ void FabricMountingManager::executeMount(
case CppMountItem::Type::Create:
writeCreateMountItem(buffer, mountItem);
break;
case CppMountItem::Type::Delete:
writeDeleteMountItem(buffer, mountItem);
break;
case CppMountItem::Type::Insert:
writeInsertMountItem(buffer, mountItem);
break;
case CppMountItem::Type::Remove:
writeRemoveMountItem(buffer, mountItem);
break;
case CppMountItem::Type::UpdateProps:
writeUpdatePropsMountItem(buffer, mountItem);
break;
case CppMountItem::Type::UpdateState:
writeUpdateStateMountItem(buffer, mountItem);
break;
case CppMountItem::Type::UpdateLayout:
writeUpdateLayoutMountItem(buffer, mountItem);
break;
case CppMountItem::Type::UpdateEventEmitter:
writeUpdateEventEmitterMountItem(buffer, mountItem);
break;
case CppMountItem::Type::UpdatePadding:
writeUpdatePaddingMountItem(buffer, mountItem);
break;
case CppMountItem::Type::UpdateOverflowInset:
writeUpdateOverflowInsetMountItem(buffer, mountItem);
break;
default:
LOG(FATAL) << "Unexpected CppMountItem type: " << mountItemType;
}
@@ -907,11 +944,11 @@ void FabricMountingManager::preallocateShadowView(
if (allocatedViewsIterator == allocatedViewRegistry_.end()) {
return;
}
auto& allocatedViews = allocatedViewsIterator->second;
if (allocatedViews.find(shadowView.tag) != allocatedViews.end()) {
const auto [_, inserted] =
allocatedViewsIterator->second.insert(shadowView.tag);
if (!inserted) {
return;
}
allocatedViews.insert(shadowView.tag);
}
bool isLayoutableShadowNode = shadowView.layoutMetrics != EmptyLayoutMetrics;
@@ -930,7 +967,6 @@ void FabricMountingManager::preallocateShadowView(
// Updating state on Android side has a cost and doing it unnecessarily for
// dummy state is wasteful.
bool preventPassingStateWrapperForText =
ReactNativeFeatureFlags::enableTextPreallocationOptimisation() &&
strcmp(shadowView.componentName, "Paragraph") == 0;
if (shadowView.state != nullptr && !preventPassingStateWrapperForText) {
javaStateWrapper = StateWrapperImpl::newObjectJavaArgs();
@@ -30,7 +30,6 @@
#include <react/renderer/scheduler/SchedulerToolbox.h>
#include <react/renderer/uimanager/primitives.h>
#include <react/utils/ContextContainer.h>
#include <react/utils/CoreFeatures.h>
namespace facebook::react {
@@ -73,16 +72,6 @@ FabricUIManagerBinding::getInspectorDataForInstance(
return ReadableNativeMap::newObjectCxxArgs(result);
}
constexpr static auto kReactFeatureFlagsJavaDescriptor =
"com/facebook/react/config/ReactFeatureFlags";
static bool getFeatureFlagValue(const char* name) {
static const auto reactFeatureFlagsClass =
jni::findClassStatic(kReactFeatureFlagsJavaDescriptor);
const auto field = reactFeatureFlagsClass->getStaticField<jboolean>(name);
return reactFeatureFlagsClass->getStaticFieldValue(field) != 0;
}
void FabricUIManagerBinding::setPixelDensity(float pointScaleFactor) {
pointScaleFactor_ = pointScaleFactor;
}
@@ -471,28 +460,25 @@ void FabricUIManagerBinding::installFabricUIManager(
auto runtimeExecutor = runtimeExecutorHolder->cthis()->get();
if (runtimeSchedulerHolder) {
auto runtimeScheduler = runtimeSchedulerHolder->cthis()->get().lock();
if (runtimeScheduler) {
runtimeExecutor =
[runtimeScheduler](
std::function<void(jsi::Runtime & runtime)>&& callback) {
runtimeScheduler->scheduleWork(std::move(callback));
};
contextContainer->insert(
"RuntimeScheduler",
std::weak_ptr<RuntimeScheduler>(runtimeScheduler));
}
auto runtimeScheduler = runtimeSchedulerHolder->cthis()->get().lock();
if (runtimeScheduler) {
runtimeExecutor =
[runtimeScheduler](
std::function<void(jsi::Runtime & runtime)>&& callback) {
runtimeScheduler->scheduleWork(std::move(callback));
};
contextContainer->insert(
"RuntimeScheduler", std::weak_ptr<RuntimeScheduler>(runtimeScheduler));
}
EventBeat::Factory eventBeatFactory =
[eventBeatManager, runtimeExecutor, globalJavaUiManager](
[eventBeatManager, &runtimeScheduler, globalJavaUiManager](
std::shared_ptr<EventBeat::OwnerBox> ownerBox)
-> std::unique_ptr<EventBeat> {
return std::make_unique<AndroidEventBeat>(
std::move(ownerBox),
eventBeatManager,
runtimeExecutor,
*runtimeScheduler,
globalJavaUiManager);
};
@@ -502,11 +488,6 @@ void FabricUIManagerBinding::installFabricUIManager(
// Keep reference to config object and cache some feature flags here
reactNativeConfig_ = config;
CoreFeatures::enablePropIteratorSetter =
getFeatureFlagValue("enableCppPropsIteratorSetter");
CoreFeatures::excludeYogaFromRawProps =
ReactNativeFeatureFlags::excludeYogaFromRawProps();
auto toolbox = SchedulerToolbox{};
toolbox.contextContainer = contextContainer;
toolbox.componentRegistryFactory = componentsRegistry->buildRegistryFunction;
@@ -551,7 +532,7 @@ FabricUIManagerBinding::getMountingManager(const char* locationHint) {
}
void FabricUIManagerBinding::schedulerDidFinishTransaction(
const MountingCoordinator::Shared& mountingCoordinator) {
const std::shared_ptr<const MountingCoordinator>& mountingCoordinator) {
// We shouldn't be pulling the transaction here (which triggers diffing of
// the trees to determine the mutations to run on the host platform),
// but we have to due to current limitations in the Android implementation.
@@ -580,7 +561,8 @@ void FabricUIManagerBinding::schedulerDidFinishTransaction(
}
void FabricUIManagerBinding::schedulerShouldRenderTransactions(
const MountingCoordinator::Shared& /* mountingCoordinator */) {
const std::shared_ptr<
const MountingCoordinator>& /* mountingCoordinator */) {
auto mountingManager =
getMountingManager("schedulerShouldRenderTransactions");
if (!mountingManager) {
@@ -101,10 +101,12 @@ class FabricUIManagerBinding : public jni::HybridClass<FabricUIManagerBinding>,
jni::alias_ref<SurfaceHandlerBinding::jhybridobject> surfaceHandler);
void schedulerDidFinishTransaction(
const MountingCoordinator::Shared& mountingCoordinator) override;
const std::shared_ptr<const MountingCoordinator>& mountingCoordinator)
override;
void schedulerShouldRenderTransactions(
const MountingCoordinator::Shared& mountingCoordinator) override;
const std::shared_ptr<const MountingCoordinator>& mountingCoordinator)
override;
void schedulerDidRequestPreliminaryViewAllocation(
const ShadowNode& shadowNode) override;
@@ -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<<b83cbcc992ef83cbc0a5db25a8ac0987>>
* @generated SignedSource<<e51d7efeeff83508fa5f1a7a46ee859d>>
*/
/**
@@ -63,6 +63,12 @@ class ReactNativeFeatureFlagsProviderHolder
return method(javaProvider_);
}
bool disableMountItemReorderingAndroid() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("disableMountItemReorderingAndroid");
return method(javaProvider_);
}
bool enableAlignItemsBaselineOnFabricIOS() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableAlignItemsBaselineOnFabricIOS");
@@ -81,9 +87,9 @@ class ReactNativeFeatureFlagsProviderHolder
return method(javaProvider_);
}
bool enableCleanTextInputYogaNode() override {
bool enableCppPropsIteratorSetter() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableCleanTextInputYogaNode");
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableCppPropsIteratorSetter");
return method(javaProvider_);
}
@@ -183,12 +189,6 @@ class ReactNativeFeatureFlagsProviderHolder
return method(javaProvider_);
}
bool enableTextPreallocationOptimisation() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableTextPreallocationOptimisation");
return method(javaProvider_);
}
bool enableUIConsistency() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableUIConsistency");
@@ -339,6 +339,11 @@ bool JReactNativeFeatureFlagsCxxInterop::disableEventLoopOnBridgeless(
return ReactNativeFeatureFlags::disableEventLoopOnBridgeless();
}
bool JReactNativeFeatureFlagsCxxInterop::disableMountItemReorderingAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::disableMountItemReorderingAndroid();
}
bool JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS();
@@ -354,9 +359,9 @@ bool JReactNativeFeatureFlagsCxxInterop::enableBridgelessArchitecture(
return ReactNativeFeatureFlags::enableBridgelessArchitecture();
}
bool JReactNativeFeatureFlagsCxxInterop::enableCleanTextInputYogaNode(
bool JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableCleanTextInputYogaNode();
return ReactNativeFeatureFlags::enableCppPropsIteratorSetter();
}
bool JReactNativeFeatureFlagsCxxInterop::enableDeletionOfUnmountedViews(
@@ -439,11 +444,6 @@ bool JReactNativeFeatureFlagsCxxInterop::enableSynchronousStateUpdates(
return ReactNativeFeatureFlags::enableSynchronousStateUpdates();
}
bool JReactNativeFeatureFlagsCxxInterop::enableTextPreallocationOptimisation(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableTextPreallocationOptimisation();
}
bool JReactNativeFeatureFlagsCxxInterop::enableUIConsistency(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableUIConsistency();
@@ -592,6 +592,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"disableEventLoopOnBridgeless",
JReactNativeFeatureFlagsCxxInterop::disableEventLoopOnBridgeless),
makeNativeMethod(
"disableMountItemReorderingAndroid",
JReactNativeFeatureFlagsCxxInterop::disableMountItemReorderingAndroid),
makeNativeMethod(
"enableAlignItemsBaselineOnFabricIOS",
JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS),
@@ -602,8 +605,8 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
"enableBridgelessArchitecture",
JReactNativeFeatureFlagsCxxInterop::enableBridgelessArchitecture),
makeNativeMethod(
"enableCleanTextInputYogaNode",
JReactNativeFeatureFlagsCxxInterop::enableCleanTextInputYogaNode),
"enableCppPropsIteratorSetter",
JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter),
makeNativeMethod(
"enableDeletionOfUnmountedViews",
JReactNativeFeatureFlagsCxxInterop::enableDeletionOfUnmountedViews),
@@ -652,9 +655,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"enableSynchronousStateUpdates",
JReactNativeFeatureFlagsCxxInterop::enableSynchronousStateUpdates),
makeNativeMethod(
"enableTextPreallocationOptimisation",
JReactNativeFeatureFlagsCxxInterop::enableTextPreallocationOptimisation),
makeNativeMethod(
"enableUIConsistency",
JReactNativeFeatureFlagsCxxInterop::enableUIConsistency),
@@ -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<<f7d93dbd2b21fc29bfd3c4c231d0fa79>>
* @generated SignedSource<<161df10ef8d0b49dce49c9d0e9354279>>
*/
/**
@@ -42,6 +42,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool disableEventLoopOnBridgeless(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool disableMountItemReorderingAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableAlignItemsBaselineOnFabricIOS(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
@@ -51,7 +54,7 @@ class JReactNativeFeatureFlagsCxxInterop
static bool enableBridgelessArchitecture(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableCleanTextInputYogaNode(
static bool enableCppPropsIteratorSetter(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableDeletionOfUnmountedViews(
@@ -102,9 +105,6 @@ class JReactNativeFeatureFlagsCxxInterop
static bool enableSynchronousStateUpdates(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableTextPreallocationOptimisation(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool enableUIConsistency(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
@@ -47,7 +47,6 @@ add_library(
turbomodulejsijni
OBJECT
ReactCommon/BindingsInstallerHolder.cpp
ReactCommon/CompositeTurboModuleManagerDelegate.cpp
ReactCommon/OnLoad.cpp
ReactCommon/TurboModuleManager.cpp
$<TARGET_OBJECTS:logger>
@@ -1,58 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "CompositeTurboModuleManagerDelegate.h"
namespace facebook::react {
jni::local_ref<CompositeTurboModuleManagerDelegate::jhybriddata>
CompositeTurboModuleManagerDelegate::initHybrid(jni::alias_ref<jhybridobject>) {
return makeCxxInstance();
}
void CompositeTurboModuleManagerDelegate::registerNatives() {
registerHybrid({
makeNativeMethod(
"initHybrid", CompositeTurboModuleManagerDelegate::initHybrid),
makeNativeMethod(
"addTurboModuleManagerDelegate",
CompositeTurboModuleManagerDelegate::addTurboModuleManagerDelegate),
});
}
std::shared_ptr<TurboModule>
CompositeTurboModuleManagerDelegate::getTurboModule(
const std::string& moduleName,
const std::shared_ptr<CallInvoker>& jsInvoker) {
for (auto delegate : mDelegates_) {
if (auto turboModule =
delegate->cthis()->getTurboModule(moduleName, jsInvoker)) {
return turboModule;
}
}
return nullptr;
}
std::shared_ptr<TurboModule>
CompositeTurboModuleManagerDelegate::getTurboModule(
const std::string& moduleName,
const JavaTurboModule::InitParams& params) {
for (auto delegate : mDelegates_) {
if (auto turboModule =
delegate->cthis()->getTurboModule(moduleName, params)) {
return turboModule;
}
}
return nullptr;
}
void CompositeTurboModuleManagerDelegate::addTurboModuleManagerDelegate(
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate) {
mDelegates_.push_back(jni::make_global(delegate));
}
} // namespace facebook::react
@@ -1,48 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <ReactCommon/TurboModuleManagerDelegate.h>
#include <fbjni/fbjni.h>
#include <memory>
#include <string>
#include <vector>
namespace facebook::react {
class CompositeTurboModuleManagerDelegate
: public jni::HybridClass<
CompositeTurboModuleManagerDelegate,
TurboModuleManagerDelegate> {
public:
static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/CompositeReactPackageTurboModuleManagerDelegate;";
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>);
static void registerNatives();
std::shared_ptr<TurboModule> getTurboModule(
const std::string& moduleName,
const std::shared_ptr<CallInvoker>& jsInvoker) override;
std::shared_ptr<TurboModule> getTurboModule(
const std::string& moduleName,
const JavaTurboModule::InitParams& params) override;
private:
friend HybridBase;
using HybridBase::HybridBase;
std::vector<jni::global_ref<TurboModuleManagerDelegate::javaobject>>
mDelegates_;
void addTurboModuleManagerDelegate(
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate);
};
} // namespace facebook::react
@@ -9,7 +9,6 @@
#include <fbjni/fbjni.h>
#include <reactperflogger/JNativeModulePerfLogger.h>
#include "CompositeTurboModuleManagerDelegate.h"
#include "TurboModuleManager.h"
void jniEnableCppLogging(
@@ -26,8 +25,6 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
// "ComponentDescriptorFactory" is defined in Fabric
facebook::react::TurboModuleManager::registerNatives();
facebook::react::CompositeTurboModuleManagerDelegate::registerNatives();
facebook::jni::registerNatives(
"com/facebook/react/internal/turbomodule/core/TurboModulePerfLogger",
{makeNativeMethod("jniEnableCppLogging", jniEnableCppLogging)});
@@ -1,131 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react
import com.facebook.react.bridge.BridgeReactContext
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
@RunWith(RobolectricTestRunner::class)
class CompositeReactPackageTest {
private lateinit var packageNo1: ReactPackage
private lateinit var packageNo2: ReactPackage
private lateinit var packageNo3: ReactPackage
private lateinit var reactContext: ReactApplicationContext
@Before
fun setUp() {
packageNo1 = mock(ReactPackage::class.java)
packageNo2 = mock(ReactPackage::class.java)
packageNo3 = mock(ReactPackage::class.java)
reactContext = BridgeReactContext(RuntimeEnvironment.getApplication())
}
@Test
@Suppress("DEPRECATION")
fun testThatCreateNativeModulesIsCalledOnAllPackages() {
// Given
val composite = CompositeReactPackage(packageNo1, packageNo2, packageNo3)
// When
composite.createNativeModules(reactContext)
// Then
verify(packageNo1).createNativeModules(reactContext)
verify(packageNo2).createNativeModules(reactContext)
verify(packageNo3).createNativeModules(reactContext)
}
@Test
@Suppress("DEPRECATION")
fun testThatCreateViewManagersIsCalledOnAllPackages() {
// Given
val composite = CompositeReactPackage(packageNo1, packageNo2, packageNo3)
// When
composite.createViewManagers(reactContext)
// Then
verify(packageNo1).createViewManagers(reactContext)
verify(packageNo2).createViewManagers(reactContext)
verify(packageNo3).createViewManagers(reactContext)
}
@Test
@Suppress("DEPRECATION")
fun testThatCompositeReturnsASumOfNativeModules() {
// Given
val composite = CompositeReactPackage(packageNo1, packageNo2)
val moduleNo1 = mock(NativeModule::class.java)
whenever(moduleNo1.name).thenReturn("ModuleNo1")
// module2 and module3 will share same name, composite should return only the latter one
val sameModuleName = "SameModuleName"
val moduleNo2 = mock(NativeModule::class.java)
whenever(moduleNo2.name).thenReturn(sameModuleName)
val moduleNo3 = mock(NativeModule::class.java)
whenever(moduleNo3.name).thenReturn(sameModuleName)
val moduleNo4 = mock(NativeModule::class.java)
whenever(moduleNo4.name).thenReturn("ModuleNo4")
whenever(packageNo1.createNativeModules(reactContext)).thenReturn(listOf(moduleNo1, moduleNo2))
whenever(packageNo2.createNativeModules(reactContext)).thenReturn(listOf(moduleNo3, moduleNo4))
// When
val compositeModules = composite.createNativeModules(reactContext)
// Then
// Wrapping lists into sets to be order-independent.
// Note that there should be no module2 returned.
val expected: Set<NativeModule> = setOf(moduleNo1, moduleNo3, moduleNo4)
val actual: Set<NativeModule> = compositeModules.toSet()
assertThat(actual).isEqualTo(expected)
}
@Test
@Suppress("DEPRECATION")
fun testThatCompositeReturnsASumOfViewManagers() {
// Given
val composite = CompositeReactPackage(packageNo1, packageNo2)
val managerNo1 = mock(ViewManager::class.java)
whenever(managerNo1.name).thenReturn("ManagerNo1")
// managerNo2 and managerNo3 will share same name, composite should return only the latter
// one
val sameModuleName = "SameModuleName"
val managerNo2 = mock(ViewManager::class.java)
whenever(managerNo2.name).thenReturn(sameModuleName)
val managerNo3 = mock(ViewManager::class.java)
whenever(managerNo3.name).thenReturn(sameModuleName)
val managerNo4 = mock(ViewManager::class.java)
whenever(managerNo4.name).thenReturn("ManagerNo4")
whenever(packageNo1.createViewManagers(reactContext)).thenReturn(listOf(managerNo1, managerNo2))
whenever(packageNo2.createViewManagers(reactContext)).thenReturn(listOf(managerNo3, managerNo4))
// When
val compositeModules = composite.createViewManagers(reactContext)
// Then
// Wrapping lists into sets to be order-independent.
// Note that there should be no managerNo2 returned.
val expected: Set<ViewManager<*, *>> = setOf(managerNo1, managerNo3, managerNo4)
val actual: Set<ViewManager<*, *>> = compositeModules.toSet()
assertThat(actual).isEqualTo(expected)
}
}
@@ -0,0 +1,37 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.text
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
@RunWith(RobolectricTestRunner::class)
class TextTransformTest {
@Test
fun textTransformCapitalize() {
val input = "hello WORLD from ReAcT nAtIvE 2a !b c"
val output = "Hello WORLD From ReAcT NAtIvE 2a !B C"
assertThat(TextTransform.apply(input, TextTransform.CAPITALIZE)).isEqualTo(output)
}
@Test
fun textTransformUppercase() {
val input = "hello WORLD from ReAcT nAtIvE 2a !b c"
val output = "HELLO WORLD FROM REACT NATIVE 2A !B C"
assertThat(TextTransform.apply(input, TextTransform.UPPERCASE)).isEqualTo(output)
}
@Test
fun textTransformLowercase() {
val input = "hello WORLD from ReAcT nAtIvE 2a !b c"
val output = "hello world from react native 2a !b c"
assertThat(TextTransform.apply(input, TextTransform.LOWERCASE)).isEqualTo(output)
}
}
@@ -78,6 +78,7 @@ Pod::Spec.new do |s|
s.dependency "DoubleConversion"
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"
@@ -50,6 +50,18 @@ void objectAssign(
auto assign = Object.getPropertyAsFunction(runtime, "assign");
assign.callWithThis(runtime, Object, target, value);
}
jsi::Object wrapInErrorIfNecessary(
jsi::Runtime& runtime,
const jsi::Value& value) {
auto Error = runtime.global().getPropertyAsFunction(runtime, "Error");
auto isError =
value.isObject() && value.asObject(runtime).instanceOf(runtime, Error);
auto error = isError
? value.getObject(runtime)
: Error.callAsConstructor(runtime, value).getObject(runtime);
return error;
}
} // namespace
namespace facebook::react {
@@ -187,7 +199,7 @@ void JsErrorHandler::emitError(
jsi::JSError& error,
bool isFatal) {
auto message = error.getMessage();
auto errorObj = error.value().getObject(runtime);
auto errorObj = wrapInErrorIfNecessary(runtime, error.value());
auto componentStackValue = errorObj.getProperty(runtime, "componentStack");
if (!isLooselyNull(componentStackValue)) {
message += "\n" + stringifyToCpp(runtime, componentStackValue);
@@ -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<<2797dcc4840b0f60670760231f51d459>>
* @generated SignedSource<<0b4373e19b66481d17c0a8e81785df23>>
*/
/**
@@ -42,6 +42,10 @@ bool ReactNativeFeatureFlags::disableEventLoopOnBridgeless() {
return getAccessor().disableEventLoopOnBridgeless();
}
bool ReactNativeFeatureFlags::disableMountItemReorderingAndroid() {
return getAccessor().disableMountItemReorderingAndroid();
}
bool ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS() {
return getAccessor().enableAlignItemsBaselineOnFabricIOS();
}
@@ -54,8 +58,8 @@ bool ReactNativeFeatureFlags::enableBridgelessArchitecture() {
return getAccessor().enableBridgelessArchitecture();
}
bool ReactNativeFeatureFlags::enableCleanTextInputYogaNode() {
return getAccessor().enableCleanTextInputYogaNode();
bool ReactNativeFeatureFlags::enableCppPropsIteratorSetter() {
return getAccessor().enableCppPropsIteratorSetter();
}
bool ReactNativeFeatureFlags::enableDeletionOfUnmountedViews() {
@@ -122,10 +126,6 @@ bool ReactNativeFeatureFlags::enableSynchronousStateUpdates() {
return getAccessor().enableSynchronousStateUpdates();
}
bool ReactNativeFeatureFlags::enableTextPreallocationOptimisation() {
return getAccessor().enableTextPreallocationOptimisation();
}
bool ReactNativeFeatureFlags::enableUIConsistency() {
return getAccessor().enableUIConsistency();
}
@@ -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<<64ea086a7c847e822595983867cdf776>>
* @generated SignedSource<<fdd3b31a0a8fbd406a14c8a088350034>>
*/
/**
@@ -59,6 +59,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool disableEventLoopOnBridgeless();
/**
* Prevent FabricMountingManager from reordering mountitems, which may lead to invalid state on the UI thread
*/
RN_EXPORT static bool disableMountItemReorderingAndroid();
/**
* Kill-switch to turn off support for aling-items:baseline on Fabric iOS.
*/
@@ -75,9 +80,9 @@ class ReactNativeFeatureFlags {
RN_EXPORT static bool enableBridgelessArchitecture();
/**
* Clean yoga node when <TextInput /> does not change.
* Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java).
*/
RN_EXPORT static bool enableCleanTextInputYogaNode();
RN_EXPORT static bool enableCppPropsIteratorSetter();
/**
* Deletes views that were pre-allocated but never mounted on the screen.
@@ -159,11 +164,6 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool enableSynchronousStateUpdates();
/**
* Text preallocation optimisation where unnecessary work is removed.
*/
RN_EXPORT static bool enableTextPreallocationOptimisation();
/**
* Ensures that JavaScript always has a consistent view of the state of the UI (e.g.: commits done in other threads are not immediately propagated to JS during its execution).
*/
@@ -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<<309c5668b6fea35c89764f496d58e803>>
* @generated SignedSource<<3ee70c854f08a871c4951e231f5c27c2>>
*/
/**
@@ -101,6 +101,24 @@ bool ReactNativeFeatureFlagsAccessor::disableEventLoopOnBridgeless() {
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::disableMountItemReorderingAndroid() {
auto flagValue = disableMountItemReorderingAndroid_.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(4, "disableMountItemReorderingAndroid");
flagValue = currentProvider_->disableMountItemReorderingAndroid();
disableMountItemReorderingAndroid_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableAlignItemsBaselineOnFabricIOS() {
auto flagValue = enableAlignItemsBaselineOnFabricIOS_.load();
@@ -110,7 +128,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAlignItemsBaselineOnFabricIOS() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(4, "enableAlignItemsBaselineOnFabricIOS");
markFlagAsAccessed(5, "enableAlignItemsBaselineOnFabricIOS");
flagValue = currentProvider_->enableAlignItemsBaselineOnFabricIOS();
enableAlignItemsBaselineOnFabricIOS_ = flagValue;
@@ -128,7 +146,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAndroidLineHeightCentering() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(5, "enableAndroidLineHeightCentering");
markFlagAsAccessed(6, "enableAndroidLineHeightCentering");
flagValue = currentProvider_->enableAndroidLineHeightCentering();
enableAndroidLineHeightCentering_ = flagValue;
@@ -146,7 +164,7 @@ bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(6, "enableBridgelessArchitecture");
markFlagAsAccessed(7, "enableBridgelessArchitecture");
flagValue = currentProvider_->enableBridgelessArchitecture();
enableBridgelessArchitecture_ = flagValue;
@@ -155,8 +173,8 @@ bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() {
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableCleanTextInputYogaNode() {
auto flagValue = enableCleanTextInputYogaNode_.load();
bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() {
auto flagValue = enableCppPropsIteratorSetter_.load();
if (!flagValue.has_value()) {
// This block is not exclusive but it is not necessary.
@@ -164,10 +182,10 @@ bool ReactNativeFeatureFlagsAccessor::enableCleanTextInputYogaNode() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(7, "enableCleanTextInputYogaNode");
markFlagAsAccessed(8, "enableCppPropsIteratorSetter");
flagValue = currentProvider_->enableCleanTextInputYogaNode();
enableCleanTextInputYogaNode_ = flagValue;
flagValue = currentProvider_->enableCppPropsIteratorSetter();
enableCppPropsIteratorSetter_ = flagValue;
}
return flagValue.value();
@@ -182,7 +200,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDeletionOfUnmountedViews() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(8, "enableDeletionOfUnmountedViews");
markFlagAsAccessed(9, "enableDeletionOfUnmountedViews");
flagValue = currentProvider_->enableDeletionOfUnmountedViews();
enableDeletionOfUnmountedViews_ = flagValue;
@@ -200,7 +218,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(9, "enableEagerRootViewAttachment");
markFlagAsAccessed(10, "enableEagerRootViewAttachment");
flagValue = currentProvider_->enableEagerRootViewAttachment();
enableEagerRootViewAttachment_ = flagValue;
@@ -218,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEventEmitterRetentionDuringGesturesO
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(10, "enableEventEmitterRetentionDuringGesturesOnAndroid");
markFlagAsAccessed(11, "enableEventEmitterRetentionDuringGesturesOnAndroid");
flagValue = currentProvider_->enableEventEmitterRetentionDuringGesturesOnAndroid();
enableEventEmitterRetentionDuringGesturesOnAndroid_ = flagValue;
@@ -236,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(11, "enableFabricLogs");
markFlagAsAccessed(12, "enableFabricLogs");
flagValue = currentProvider_->enableFabricLogs();
enableFabricLogs_ = flagValue;
@@ -254,7 +272,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(12, "enableFabricRenderer");
markFlagAsAccessed(13, "enableFabricRenderer");
flagValue = currentProvider_->enableFabricRenderer();
enableFabricRenderer_ = flagValue;
@@ -272,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRendererExclusively() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(13, "enableFabricRendererExclusively");
markFlagAsAccessed(14, "enableFabricRendererExclusively");
flagValue = currentProvider_->enableFabricRendererExclusively();
enableFabricRendererExclusively_ = flagValue;
@@ -290,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableGranularShadowTreeStateReconciliatio
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(14, "enableGranularShadowTreeStateReconciliation");
markFlagAsAccessed(15, "enableGranularShadowTreeStateReconciliation");
flagValue = currentProvider_->enableGranularShadowTreeStateReconciliation();
enableGranularShadowTreeStateReconciliation_ = flagValue;
@@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(15, "enableIOSViewClipToPaddingBox");
markFlagAsAccessed(16, "enableIOSViewClipToPaddingBox");
flagValue = currentProvider_->enableIOSViewClipToPaddingBox();
enableIOSViewClipToPaddingBox_ = flagValue;
@@ -326,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(16, "enableLayoutAnimationsOnAndroid");
markFlagAsAccessed(17, "enableLayoutAnimationsOnAndroid");
flagValue = currentProvider_->enableLayoutAnimationsOnAndroid();
enableLayoutAnimationsOnAndroid_ = flagValue;
@@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(17, "enableLayoutAnimationsOnIOS");
markFlagAsAccessed(18, "enableLayoutAnimationsOnIOS");
flagValue = currentProvider_->enableLayoutAnimationsOnIOS();
enableLayoutAnimationsOnIOS_ = flagValue;
@@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(18, "enableLongTaskAPI");
markFlagAsAccessed(19, "enableLongTaskAPI");
flagValue = currentProvider_->enableLongTaskAPI();
enableLongTaskAPI_ = flagValue;
@@ -380,7 +398,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(19, "enableNewBackgroundAndBorderDrawables");
markFlagAsAccessed(20, "enableNewBackgroundAndBorderDrawables");
flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables();
enableNewBackgroundAndBorderDrawables_ = flagValue;
@@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreciseSchedulingForPremountItemsOnA
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(20, "enablePreciseSchedulingForPremountItemsOnAndroid");
markFlagAsAccessed(21, "enablePreciseSchedulingForPremountItemsOnAndroid");
flagValue = currentProvider_->enablePreciseSchedulingForPremountItemsOnAndroid();
enablePreciseSchedulingForPremountItemsOnAndroid_ = flagValue;
@@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(21, "enablePropsUpdateReconciliationAndroid");
markFlagAsAccessed(22, "enablePropsUpdateReconciliationAndroid");
flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid();
enablePropsUpdateReconciliationAndroid_ = flagValue;
@@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableReportEventPaintTime() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(22, "enableReportEventPaintTime");
markFlagAsAccessed(23, "enableReportEventPaintTime");
flagValue = currentProvider_->enableReportEventPaintTime();
enableReportEventPaintTime_ = flagValue;
@@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(23, "enableSynchronousStateUpdates");
markFlagAsAccessed(24, "enableSynchronousStateUpdates");
flagValue = currentProvider_->enableSynchronousStateUpdates();
enableSynchronousStateUpdates_ = flagValue;
@@ -461,24 +479,6 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() {
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableTextPreallocationOptimisation() {
auto flagValue = enableTextPreallocationOptimisation_.load();
if (!flagValue.has_value()) {
// This block is not exclusive but it is not necessary.
// If multiple threads try to initialize the feature flag, we would only
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(24, "enableTextPreallocationOptimisation");
flagValue = currentProvider_->enableTextPreallocationOptimisation();
enableTextPreallocationOptimisation_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() {
auto flagValue = enableUIConsistency_.load();
@@ -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<<e6092a90044213cc3b88f995a301aeb6>>
* @generated SignedSource<<337a399929dd2a198b1b7d99ff395236>>
*/
/**
@@ -36,10 +36,11 @@ class ReactNativeFeatureFlagsAccessor {
bool allowRecursiveCommitsWithSynchronousMountOnAndroid();
bool completeReactInstanceCreationOnBgThreadOnAndroid();
bool disableEventLoopOnBridgeless();
bool disableMountItemReorderingAndroid();
bool enableAlignItemsBaselineOnFabricIOS();
bool enableAndroidLineHeightCentering();
bool enableBridgelessArchitecture();
bool enableCleanTextInputYogaNode();
bool enableCppPropsIteratorSetter();
bool enableDeletionOfUnmountedViews();
bool enableEagerRootViewAttachment();
bool enableEventEmitterRetentionDuringGesturesOnAndroid();
@@ -56,7 +57,6 @@ class ReactNativeFeatureFlagsAccessor {
bool enablePropsUpdateReconciliationAndroid();
bool enableReportEventPaintTime();
bool enableSynchronousStateUpdates();
bool enableTextPreallocationOptimisation();
bool enableUIConsistency();
bool enableViewRecycling();
bool excludeYogaFromRawProps();
@@ -95,10 +95,11 @@ class ReactNativeFeatureFlagsAccessor {
std::atomic<std::optional<bool>> allowRecursiveCommitsWithSynchronousMountOnAndroid_;
std::atomic<std::optional<bool>> completeReactInstanceCreationOnBgThreadOnAndroid_;
std::atomic<std::optional<bool>> disableEventLoopOnBridgeless_;
std::atomic<std::optional<bool>> disableMountItemReorderingAndroid_;
std::atomic<std::optional<bool>> enableAlignItemsBaselineOnFabricIOS_;
std::atomic<std::optional<bool>> enableAndroidLineHeightCentering_;
std::atomic<std::optional<bool>> enableBridgelessArchitecture_;
std::atomic<std::optional<bool>> enableCleanTextInputYogaNode_;
std::atomic<std::optional<bool>> enableCppPropsIteratorSetter_;
std::atomic<std::optional<bool>> enableDeletionOfUnmountedViews_;
std::atomic<std::optional<bool>> enableEagerRootViewAttachment_;
std::atomic<std::optional<bool>> enableEventEmitterRetentionDuringGesturesOnAndroid_;
@@ -115,7 +116,6 @@ class ReactNativeFeatureFlagsAccessor {
std::atomic<std::optional<bool>> enablePropsUpdateReconciliationAndroid_;
std::atomic<std::optional<bool>> enableReportEventPaintTime_;
std::atomic<std::optional<bool>> enableSynchronousStateUpdates_;
std::atomic<std::optional<bool>> enableTextPreallocationOptimisation_;
std::atomic<std::optional<bool>> enableUIConsistency_;
std::atomic<std::optional<bool>> enableViewRecycling_;
std::atomic<std::optional<bool>> excludeYogaFromRawProps_;
@@ -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<<c624d0aed510abd12f9b808324dc2da8>>
* @generated SignedSource<<65bca35ca4b820d9b311b4d9a194fdab>>
*/
/**
@@ -43,6 +43,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool disableMountItemReorderingAndroid() override {
return false;
}
bool enableAlignItemsBaselineOnFabricIOS() override {
return true;
}
@@ -55,7 +59,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool enableCleanTextInputYogaNode() override {
bool enableCppPropsIteratorSetter() override {
return false;
}
@@ -123,10 +127,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool enableTextPreallocationOptimisation() override {
return false;
}
bool enableUIConsistency() 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<<35bffd8482840e9a7d0255098e78450a>>
* @generated SignedSource<<6f33275c4058c3c67653247c1983f526>>
*/
/**
@@ -29,10 +29,11 @@ class ReactNativeFeatureFlagsProvider {
virtual bool allowRecursiveCommitsWithSynchronousMountOnAndroid() = 0;
virtual bool completeReactInstanceCreationOnBgThreadOnAndroid() = 0;
virtual bool disableEventLoopOnBridgeless() = 0;
virtual bool disableMountItemReorderingAndroid() = 0;
virtual bool enableAlignItemsBaselineOnFabricIOS() = 0;
virtual bool enableAndroidLineHeightCentering() = 0;
virtual bool enableBridgelessArchitecture() = 0;
virtual bool enableCleanTextInputYogaNode() = 0;
virtual bool enableCppPropsIteratorSetter() = 0;
virtual bool enableDeletionOfUnmountedViews() = 0;
virtual bool enableEagerRootViewAttachment() = 0;
virtual bool enableEventEmitterRetentionDuringGesturesOnAndroid() = 0;
@@ -49,7 +50,6 @@ class ReactNativeFeatureFlagsProvider {
virtual bool enablePropsUpdateReconciliationAndroid() = 0;
virtual bool enableReportEventPaintTime() = 0;
virtual bool enableSynchronousStateUpdates() = 0;
virtual bool enableTextPreallocationOptimisation() = 0;
virtual bool enableUIConsistency() = 0;
virtual bool enableViewRecycling() = 0;
virtual bool excludeYogaFromRawProps() = 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<<12ecbb280bde10b2d74376a2a890cf97>>
* @generated SignedSource<<9c9ab8e276227aa107d905c5eb6578ae>>
*/
/**
@@ -71,6 +71,11 @@ bool NativeReactNativeFeatureFlags::disableEventLoopOnBridgeless(
return ReactNativeFeatureFlags::disableEventLoopOnBridgeless();
}
bool NativeReactNativeFeatureFlags::disableMountItemReorderingAndroid(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::disableMountItemReorderingAndroid();
}
bool NativeReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS();
@@ -86,9 +91,9 @@ bool NativeReactNativeFeatureFlags::enableBridgelessArchitecture(
return ReactNativeFeatureFlags::enableBridgelessArchitecture();
}
bool NativeReactNativeFeatureFlags::enableCleanTextInputYogaNode(
bool NativeReactNativeFeatureFlags::enableCppPropsIteratorSetter(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableCleanTextInputYogaNode();
return ReactNativeFeatureFlags::enableCppPropsIteratorSetter();
}
bool NativeReactNativeFeatureFlags::enableDeletionOfUnmountedViews(
@@ -178,11 +183,6 @@ bool NativeReactNativeFeatureFlags::enableSynchronousStateUpdates(
return ReactNativeFeatureFlags::enableSynchronousStateUpdates();
}
bool NativeReactNativeFeatureFlags::enableTextPreallocationOptimisation(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableTextPreallocationOptimisation();
}
bool NativeReactNativeFeatureFlags::enableUIConsistency(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::enableUIConsistency();
@@ -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<<00421354f8b4b982f5eac771592d418f>>
* @generated SignedSource<<81af74188979662ffc39840c1521ca72>>
*/
/**
@@ -47,13 +47,15 @@ class NativeReactNativeFeatureFlags
bool disableEventLoopOnBridgeless(jsi::Runtime& runtime);
bool disableMountItemReorderingAndroid(jsi::Runtime& runtime);
bool enableAlignItemsBaselineOnFabricIOS(jsi::Runtime& runtime);
bool enableAndroidLineHeightCentering(jsi::Runtime& runtime);
bool enableBridgelessArchitecture(jsi::Runtime& runtime);
bool enableCleanTextInputYogaNode(jsi::Runtime& runtime);
bool enableCppPropsIteratorSetter(jsi::Runtime& runtime);
bool enableDeletionOfUnmountedViews(jsi::Runtime& runtime);
@@ -89,8 +91,6 @@ class NativeReactNativeFeatureFlags
bool enableSynchronousStateUpdates(jsi::Runtime& runtime);
bool enableTextPreallocationOptimisation(jsi::Runtime& runtime);
bool enableUIConsistency(jsi::Runtime& runtime);
bool enableViewRecycling(jsi::Runtime& runtime);
@@ -5,10 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/components/image/ImageProps.h>
#include <react/renderer/components/image/conversions.h>
#include <react/renderer/core/propsConversions.h>
#include <react/utils/CoreFeatures.h>
namespace facebook::react {
@@ -18,15 +18,16 @@ ImageProps::ImageProps(
const RawProps& rawProps)
: ViewProps(context, sourceProps, rawProps),
sources(
CoreFeatures::enablePropIteratorSetter ? sourceProps.sources
: convertRawProp(
context,
rawProps,
"source",
sourceProps.sources,
{})),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.sources
: convertRawProp(
context,
rawProps,
"source",
sourceProps.sources,
{})),
defaultSources(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.defaultSources
: convertRawProp(
context,
@@ -35,7 +36,7 @@ ImageProps::ImageProps(
sourceProps.defaultSources,
{})),
resizeMode(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.resizeMode
: convertRawProp(
context,
@@ -44,31 +45,34 @@ ImageProps::ImageProps(
sourceProps.resizeMode,
ImageResizeMode::Stretch)),
blurRadius(
CoreFeatures::enablePropIteratorSetter ? sourceProps.blurRadius
: convertRawProp(
context,
rawProps,
"blurRadius",
sourceProps.blurRadius,
{})),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.blurRadius
: convertRawProp(
context,
rawProps,
"blurRadius",
sourceProps.blurRadius,
{})),
capInsets(
CoreFeatures::enablePropIteratorSetter ? sourceProps.capInsets
: convertRawProp(
context,
rawProps,
"capInsets",
sourceProps.capInsets,
{})),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.capInsets
: convertRawProp(
context,
rawProps,
"capInsets",
sourceProps.capInsets,
{})),
tintColor(
CoreFeatures::enablePropIteratorSetter ? sourceProps.tintColor
: convertRawProp(
context,
rawProps,
"tintColor",
sourceProps.tintColor,
{})),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.tintColor
: convertRawProp(
context,
rawProps,
"tintColor",
sourceProps.tintColor,
{})),
internal_analyticTag(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.internal_analyticTag
: convertRawProp(
context,
@@ -7,10 +7,10 @@
#include "ScrollViewProps.h"
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/components/scrollview/conversions.h>
#include <react/renderer/core/graphicsConversions.h>
#include <react/renderer/debug/debugStringConvertibleUtils.h>
#include <react/utils/CoreFeatures.h>
#include <react/renderer/core/propsConversions.h>
@@ -22,7 +22,7 @@ ScrollViewProps::ScrollViewProps(
const RawProps& rawProps)
: ViewProps(context, sourceProps, rawProps),
alwaysBounceHorizontal(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.alwaysBounceHorizontal
: convertRawProp(
context,
@@ -31,7 +31,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.alwaysBounceHorizontal,
{})),
alwaysBounceVertical(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.alwaysBounceVertical
: convertRawProp(
context,
@@ -40,23 +40,25 @@ ScrollViewProps::ScrollViewProps(
sourceProps.alwaysBounceVertical,
{})),
bounces(
CoreFeatures::enablePropIteratorSetter ? sourceProps.bounces
: convertRawProp(
context,
rawProps,
"bounces",
sourceProps.bounces,
true)),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.bounces
: convertRawProp(
context,
rawProps,
"bounces",
sourceProps.bounces,
true)),
bouncesZoom(
CoreFeatures::enablePropIteratorSetter ? sourceProps.bouncesZoom
: convertRawProp(
context,
rawProps,
"bouncesZoom",
sourceProps.bouncesZoom,
true)),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.bouncesZoom
: convertRawProp(
context,
rawProps,
"bouncesZoom",
sourceProps.bouncesZoom,
true)),
canCancelContentTouches(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.canCancelContentTouches
: convertRawProp(
context,
@@ -65,7 +67,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.canCancelContentTouches,
true)),
centerContent(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.centerContent
: convertRawProp(
context,
@@ -74,7 +76,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.centerContent,
{})),
automaticallyAdjustContentInsets(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.automaticallyAdjustContentInsets
: convertRawProp(
context,
@@ -83,7 +85,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.automaticallyAdjustContentInsets,
{})),
automaticallyAdjustsScrollIndicatorInsets(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.automaticallyAdjustsScrollIndicatorInsets
: convertRawProp(
context,
@@ -92,7 +94,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.automaticallyAdjustsScrollIndicatorInsets,
true)),
automaticallyAdjustKeyboardInsets(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.automaticallyAdjustKeyboardInsets
: convertRawProp(
context,
@@ -101,7 +103,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.automaticallyAdjustKeyboardInsets,
false)),
decelerationRate(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.decelerationRate
: convertRawProp(
context,
@@ -110,7 +112,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.decelerationRate,
(Float)0.998)),
endDraggingSensitivityMultiplier(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.endDraggingSensitivityMultiplier
: convertRawProp(
context,
@@ -119,7 +121,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.endDraggingSensitivityMultiplier,
(Float)1)),
enableSyncOnScroll(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.enableSyncOnScroll
: convertRawProp(
context,
@@ -128,7 +130,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.enableSyncOnScroll,
false)),
directionalLockEnabled(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.directionalLockEnabled
: convertRawProp(
context,
@@ -137,7 +139,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.directionalLockEnabled,
{})),
indicatorStyle(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.indicatorStyle
: convertRawProp(
context,
@@ -146,7 +148,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.indicatorStyle,
{})),
keyboardDismissMode(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.keyboardDismissMode
: convertRawProp(
context,
@@ -155,7 +157,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.keyboardDismissMode,
{})),
maintainVisibleContentPosition(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.maintainVisibleContentPosition
: convertRawProp(
context,
@@ -164,7 +166,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.maintainVisibleContentPosition,
{})),
maximumZoomScale(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.maximumZoomScale
: convertRawProp(
context,
@@ -173,7 +175,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.maximumZoomScale,
(Float)1.0)),
minimumZoomScale(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.minimumZoomScale
: convertRawProp(
context,
@@ -182,7 +184,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.minimumZoomScale,
(Float)1.0)),
scrollEnabled(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.scrollEnabled
: convertRawProp(
context,
@@ -191,7 +193,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.scrollEnabled,
true)),
pagingEnabled(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.pagingEnabled
: convertRawProp(
context,
@@ -200,7 +202,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.pagingEnabled,
{})),
pinchGestureEnabled(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.pinchGestureEnabled
: convertRawProp(
context,
@@ -209,15 +211,16 @@ ScrollViewProps::ScrollViewProps(
sourceProps.pinchGestureEnabled,
true)),
scrollsToTop(
CoreFeatures::enablePropIteratorSetter ? sourceProps.scrollsToTop
: convertRawProp(
context,
rawProps,
"scrollsToTop",
sourceProps.scrollsToTop,
true)),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.scrollsToTop
: convertRawProp(
context,
rawProps,
"scrollsToTop",
sourceProps.scrollsToTop,
true)),
showsHorizontalScrollIndicator(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.showsHorizontalScrollIndicator
: convertRawProp(
context,
@@ -226,7 +229,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.showsHorizontalScrollIndicator,
true)),
showsVerticalScrollIndicator(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.showsVerticalScrollIndicator
: convertRawProp(
context,
@@ -235,7 +238,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.showsVerticalScrollIndicator,
true)),
persistentScrollbar(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.persistentScrollbar
: convertRawProp(
context,
@@ -244,15 +247,16 @@ ScrollViewProps::ScrollViewProps(
sourceProps.persistentScrollbar,
true)),
horizontal(
CoreFeatures::enablePropIteratorSetter ? sourceProps.horizontal
: convertRawProp(
context,
rawProps,
"horizontal",
sourceProps.horizontal,
true)),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.horizontal
: convertRawProp(
context,
rawProps,
"horizontal",
sourceProps.horizontal,
true)),
scrollEventThrottle(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.scrollEventThrottle
: convertRawProp(
context,
@@ -261,23 +265,25 @@ ScrollViewProps::ScrollViewProps(
sourceProps.scrollEventThrottle,
{})),
zoomScale(
CoreFeatures::enablePropIteratorSetter ? sourceProps.zoomScale
: convertRawProp(
context,
rawProps,
"zoomScale",
sourceProps.zoomScale,
(Float)1.0)),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.zoomScale
: convertRawProp(
context,
rawProps,
"zoomScale",
sourceProps.zoomScale,
(Float)1.0)),
contentInset(
CoreFeatures::enablePropIteratorSetter ? sourceProps.contentInset
: convertRawProp(
context,
rawProps,
"contentInset",
sourceProps.contentInset,
{})),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.contentInset
: convertRawProp(
context,
rawProps,
"contentInset",
sourceProps.contentInset,
{})),
contentOffset(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.contentOffset
: convertRawProp(
context,
@@ -286,7 +292,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.contentOffset,
{})),
scrollIndicatorInsets(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.scrollIndicatorInsets
: convertRawProp(
context,
@@ -295,7 +301,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.scrollIndicatorInsets,
{})),
snapToInterval(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.snapToInterval
: convertRawProp(
context,
@@ -304,7 +310,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.snapToInterval,
{})),
snapToAlignment(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.snapToAlignment
: convertRawProp(
context,
@@ -313,7 +319,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.snapToAlignment,
{})),
disableIntervalMomentum(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.disableIntervalMomentum
: convertRawProp(
context,
@@ -322,7 +328,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.disableIntervalMomentum,
{})),
snapToOffsets(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.snapToOffsets
: convertRawProp(
context,
@@ -331,23 +337,25 @@ ScrollViewProps::ScrollViewProps(
sourceProps.snapToOffsets,
{})),
snapToStart(
CoreFeatures::enablePropIteratorSetter ? sourceProps.snapToStart
: convertRawProp(
context,
rawProps,
"snapToStart",
sourceProps.snapToStart,
true)),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.snapToStart
: convertRawProp(
context,
rawProps,
"snapToStart",
sourceProps.snapToStart,
true)),
snapToEnd(
CoreFeatures::enablePropIteratorSetter ? sourceProps.snapToEnd
: convertRawProp(
context,
rawProps,
"snapToEnd",
sourceProps.snapToEnd,
true)),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.snapToEnd
: convertRawProp(
context,
rawProps,
"snapToEnd",
sourceProps.snapToEnd,
true)),
contentInsetAdjustmentBehavior(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.contentInsetAdjustmentBehavior
: convertRawProp(
context,
@@ -356,7 +364,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.contentInsetAdjustmentBehavior,
{ContentInsetAdjustmentBehavior::Never})),
scrollToOverflowEnabled(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.scrollToOverflowEnabled
: convertRawProp(
context,
@@ -365,7 +373,7 @@ ScrollViewProps::ScrollViewProps(
sourceProps.scrollToOverflowEnabled,
{})),
isInvertedVirtualizedList(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.isInvertedVirtualizedList
: convertRawProp(
context,
@@ -7,11 +7,11 @@
#include "BaseTextProps.h"
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/attributedstring/conversions.h>
#include <react/renderer/core/graphicsConversions.h>
#include <react/renderer/core/propsConversions.h>
#include <react/renderer/debug/DebugStringConvertibleItem.h>
#include <react/utils/CoreFeatures.h>
namespace facebook::react {
@@ -230,7 +230,7 @@ BaseTextProps::BaseTextProps(
const BaseTextProps& sourceProps,
const RawProps& rawProps)
: textAttributes(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.textAttributes
: convertRawProp(
context,
@@ -7,11 +7,11 @@
#include "ParagraphProps.h"
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/attributedstring/conversions.h>
#include <react/renderer/attributedstring/primitives.h>
#include <react/renderer/core/propsConversions.h>
#include <react/renderer/debug/debugStringConvertibleUtils.h>
#include <react/utils/CoreFeatures.h>
#include <glog/logging.h>
@@ -24,7 +24,7 @@ ParagraphProps::ParagraphProps(
: ViewProps(context, sourceProps, rawProps),
BaseTextProps(context, sourceProps, rawProps),
paragraphAttributes(
CoreFeatures::enablePropIteratorSetter
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.paragraphAttributes
: convertRawProp(
context,
@@ -32,21 +32,23 @@ ParagraphProps::ParagraphProps(
sourceProps.paragraphAttributes,
{})),
isSelectable(
CoreFeatures::enablePropIteratorSetter ? sourceProps.isSelectable
: convertRawProp(
context,
rawProps,
"selectable",
sourceProps.isSelectable,
false)),
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.isSelectable
: convertRawProp(
context,
rawProps,
"selectable",
sourceProps.isSelectable,
false)),
onTextLayout(
CoreFeatures::enablePropIteratorSetter ? sourceProps.onTextLayout
: convertRawProp(
context,
rawProps,
"onTextLayout",
sourceProps.onTextLayout,
{})) {
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
? sourceProps.onTextLayout
: convertRawProp(
context,
rawProps,
"onTextLayout",
sourceProps.onTextLayout,
{})) {
/*
* These props are applied to `View`, therefore they must not be a part of
* base text attributes.
@@ -17,11 +17,11 @@
#include <react/renderer/attributedstring/TextAttributes.h>
#include <react/renderer/attributedstring/conversions.h>
#include <react/renderer/components/image/conversions.h>
#include <react/renderer/components/textinput/baseConversions.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/graphicsConversions.h>
#include <react/renderer/graphics/Color.h>
#include <react/renderer/imagemanager/primitives.h>
#include <react/utils/CoreFeatures.h>
namespace facebook::react {
@@ -114,7 +114,19 @@ BaseTextInputProps::BaseTextInputProps(
rawProps,
"readOnly",
sourceProps.readOnly,
{})) {}
{})),
submitBehavior(convertRawProp(
context,
rawProps,
"submitBehavior",
sourceProps.submitBehavior,
{})),
multiline(convertRawProp(
context,
rawProps,
"multiline",
sourceProps.multiline,
{false})) {}
void BaseTextInputProps::setProp(
const PropsParserContext& context,
@@ -194,7 +206,17 @@ void BaseTextInputProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(autoCapitalize);
RAW_SET_PROP_SWITCH_CASE_BASIC(editable);
RAW_SET_PROP_SWITCH_CASE_BASIC(readOnly);
RAW_SET_PROP_SWITCH_CASE_BASIC(submitBehavior);
RAW_SET_PROP_SWITCH_CASE_BASIC(multiline);
}
}
SubmitBehavior BaseTextInputProps::getNonDefaultSubmitBehavior() const {
if (submitBehavior == SubmitBehavior::Default) {
return multiline ? SubmitBehavior::Newline : SubmitBehavior::BlurAndSubmit;
}
return submitBehavior;
}
} // namespace facebook::react
@@ -9,6 +9,7 @@
#include <react/renderer/attributedstring/ParagraphAttributes.h>
#include <react/renderer/components/text/BaseTextProps.h>
#include <react/renderer/components/textinput/basePrimitives.h>
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/graphics/Color.h>
@@ -66,6 +67,12 @@ class BaseTextInputProps : public ViewProps, public BaseTextProps {
bool editable{true};
bool readOnly{false};
SubmitBehavior submitBehavior{SubmitBehavior::Default};
bool multiline{false};
SubmitBehavior getNonDefaultSubmitBehavior() const;
};
} // namespace facebook::react
@@ -0,0 +1,46 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/renderer/components/textinput/basePrimitives.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/RawValue.h>
#include <string>
namespace facebook::react {
inline void fromRawValue(
const PropsParserContext& /*context*/,
const RawValue& value,
SubmitBehavior& result) {
auto string = static_cast<std::string>(value);
if (string == "newline") {
result = SubmitBehavior::Newline;
} else if (string == "submit") {
result = SubmitBehavior::Submit;
} else if (string == "blurAndSubmit") {
result = SubmitBehavior::BlurAndSubmit;
} else {
abort();
}
}
inline folly::dynamic toDynamic(const SubmitBehavior& value) {
switch (value) {
case SubmitBehavior::Newline:
return "newline";
case SubmitBehavior::Submit:
return "submit";
case SubmitBehavior::BlurAndSubmit:
return "blurAndSubmit";
case SubmitBehavior::Default:
return {nullptr};
}
}
} // namespace facebook::react
@@ -5,11 +5,15 @@
* LICENSE file in the root directory of this source tree.
*/
#include "CoreFeatures.h"
#pragma once
namespace facebook::react {
bool CoreFeatures::enablePropIteratorSetter = false;
bool CoreFeatures::excludeYogaFromRawProps = false;
enum class SubmitBehavior {
Default,
Submit,
BlurAndSubmit,
Newline,
};
} // namespace facebook::react
@@ -6,10 +6,11 @@
*/
#include "AndroidTextInputProps.h"
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/renderer/components/image/conversions.h>
#include <react/renderer/components/textinput/baseConversions.h>
#include <react/renderer/core/graphicsConversions.h>
#include <react/renderer/core/propsConversions.h>
#include <react/utils/CoreFeatures.h>
namespace facebook::react {
@@ -37,162 +38,154 @@ AndroidTextInputProps::AndroidTextInputProps(
const AndroidTextInputProps &sourceProps,
const RawProps &rawProps)
: BaseTextInputProps(context, sourceProps, rawProps),
autoComplete(CoreFeatures::enablePropIteratorSetter? sourceProps.autoComplete : convertRawProp(
autoComplete(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.autoComplete : convertRawProp(
context,
rawProps,
"autoComplete",
sourceProps.autoComplete,
{})),
returnKeyLabel(CoreFeatures::enablePropIteratorSetter? sourceProps.autoComplete : convertRawProp(context, rawProps,
returnKeyLabel(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.autoComplete : convertRawProp(context, rawProps,
"returnKeyLabel",
sourceProps.returnKeyLabel,
{})),
numberOfLines(CoreFeatures::enablePropIteratorSetter? sourceProps.numberOfLines : convertRawProp(context, rawProps,
numberOfLines(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.numberOfLines : convertRawProp(context, rawProps,
"numberOfLines",
sourceProps.numberOfLines,
{0})),
disableFullscreenUI(CoreFeatures::enablePropIteratorSetter? sourceProps.disableFullscreenUI : convertRawProp(context, rawProps,
disableFullscreenUI(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.disableFullscreenUI : convertRawProp(context, rawProps,
"disableFullscreenUI",
sourceProps.disableFullscreenUI,
{false})),
textBreakStrategy(CoreFeatures::enablePropIteratorSetter? sourceProps.textBreakStrategy : convertRawProp(context, rawProps,
textBreakStrategy(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textBreakStrategy : convertRawProp(context, rawProps,
"textBreakStrategy",
sourceProps.textBreakStrategy,
{})),
inlineImageLeft(CoreFeatures::enablePropIteratorSetter? sourceProps.inlineImageLeft : convertRawProp(context, rawProps,
inlineImageLeft(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.inlineImageLeft : convertRawProp(context, rawProps,
"inlineImageLeft",
sourceProps.inlineImageLeft,
{})),
inlineImagePadding(CoreFeatures::enablePropIteratorSetter? sourceProps.inlineImagePadding : convertRawProp(context, rawProps,
inlineImagePadding(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.inlineImagePadding : convertRawProp(context, rawProps,
"inlineImagePadding",
sourceProps.inlineImagePadding,
{0})),
importantForAutofill(CoreFeatures::enablePropIteratorSetter? sourceProps.importantForAutofill : convertRawProp(context, rawProps,
importantForAutofill(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.importantForAutofill : convertRawProp(context, rawProps,
"importantForAutofill",
sourceProps.importantForAutofill,
{})),
showSoftInputOnFocus(CoreFeatures::enablePropIteratorSetter? sourceProps.showSoftInputOnFocus : convertRawProp(context, rawProps,
showSoftInputOnFocus(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.showSoftInputOnFocus : convertRawProp(context, rawProps,
"showSoftInputOnFocus",
sourceProps.showSoftInputOnFocus,
{false})),
autoCorrect(CoreFeatures::enablePropIteratorSetter? sourceProps.autoCorrect : convertRawProp(context, rawProps,
autoCorrect(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.autoCorrect : convertRawProp(context, rawProps,
"autoCorrect",
sourceProps.autoCorrect,
{false})),
allowFontScaling(CoreFeatures::enablePropIteratorSetter? sourceProps.allowFontScaling : convertRawProp(context, rawProps,
allowFontScaling(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.allowFontScaling : convertRawProp(context, rawProps,
"allowFontScaling",
sourceProps.allowFontScaling,
{false})),
maxFontSizeMultiplier(CoreFeatures::enablePropIteratorSetter? sourceProps.maxFontSizeMultiplier : convertRawProp(context, rawProps,
maxFontSizeMultiplier(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.maxFontSizeMultiplier : convertRawProp(context, rawProps,
"maxFontSizeMultiplier",
sourceProps.maxFontSizeMultiplier,
{0.0})),
keyboardType(CoreFeatures::enablePropIteratorSetter? sourceProps.keyboardType : convertRawProp(context, rawProps,
keyboardType(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.keyboardType : convertRawProp(context, rawProps,
"keyboardType",
sourceProps.keyboardType,
{})),
returnKeyType(CoreFeatures::enablePropIteratorSetter? sourceProps.returnKeyType : convertRawProp(context, rawProps,
returnKeyType(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.returnKeyType : convertRawProp(context, rawProps,
"returnKeyType",
sourceProps.returnKeyType,
{})),
multiline(CoreFeatures::enablePropIteratorSetter? sourceProps.multiline : convertRawProp(context, rawProps,
"multiline",
sourceProps.multiline,
{false})),
secureTextEntry(CoreFeatures::enablePropIteratorSetter? sourceProps.secureTextEntry : convertRawProp(context, rawProps,
secureTextEntry(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.secureTextEntry : convertRawProp(context, rawProps,
"secureTextEntry",
sourceProps.secureTextEntry,
{false})),
value(CoreFeatures::enablePropIteratorSetter? sourceProps.value : convertRawProp(context, rawProps, "value", sourceProps.value, {})),
selectTextOnFocus(CoreFeatures::enablePropIteratorSetter? sourceProps.selectTextOnFocus : convertRawProp(context, rawProps,
value(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.value : convertRawProp(context, rawProps, "value", sourceProps.value, {})),
selectTextOnFocus(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.selectTextOnFocus : convertRawProp(context, rawProps,
"selectTextOnFocus",
sourceProps.selectTextOnFocus,
{false})),
submitBehavior(CoreFeatures::enablePropIteratorSetter? sourceProps.submitBehavior : convertRawProp(context, rawProps,
"submitBehavior",
sourceProps.submitBehavior,
{})),
caretHidden(CoreFeatures::enablePropIteratorSetter? sourceProps.caretHidden : convertRawProp(context, rawProps,
caretHidden(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.caretHidden : convertRawProp(context, rawProps,
"caretHidden",
sourceProps.caretHidden,
{false})),
contextMenuHidden(CoreFeatures::enablePropIteratorSetter? sourceProps.contextMenuHidden : convertRawProp(context, rawProps,
contextMenuHidden(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.contextMenuHidden : convertRawProp(context, rawProps,
"contextMenuHidden",
sourceProps.contextMenuHidden,
{false})),
textShadowColor(CoreFeatures::enablePropIteratorSetter? sourceProps.textShadowColor : convertRawProp(context, rawProps,
textShadowColor(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textShadowColor : convertRawProp(context, rawProps,
"textShadowColor",
sourceProps.textShadowColor,
{})),
textShadowRadius(CoreFeatures::enablePropIteratorSetter? sourceProps.textShadowRadius : convertRawProp(context, rawProps,
textShadowRadius(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textShadowRadius : convertRawProp(context, rawProps,
"textShadowRadius",
sourceProps.textShadowRadius,
{0.0})),
textDecorationLine(CoreFeatures::enablePropIteratorSetter? sourceProps.textDecorationLine : convertRawProp(context, rawProps,
textDecorationLine(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textDecorationLine : convertRawProp(context, rawProps,
"textDecorationLine",
sourceProps.textDecorationLine,
{})),
fontStyle(CoreFeatures::enablePropIteratorSetter? sourceProps.fontStyle :
fontStyle(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.fontStyle :
convertRawProp(context, rawProps, "fontStyle", sourceProps.fontStyle, {})),
textShadowOffset(CoreFeatures::enablePropIteratorSetter? sourceProps.textShadowOffset : convertRawProp(context, rawProps,
textShadowOffset(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textShadowOffset : convertRawProp(context, rawProps,
"textShadowOffset",
sourceProps.textShadowOffset,
{})),
lineHeight(CoreFeatures::enablePropIteratorSetter? sourceProps.lineHeight : convertRawProp(context, rawProps,
lineHeight(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.lineHeight : convertRawProp(context, rawProps,
"lineHeight",
sourceProps.lineHeight,
{0.0})),
textTransform(CoreFeatures::enablePropIteratorSetter? sourceProps.textTransform : convertRawProp(context, rawProps,
textTransform(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textTransform : convertRawProp(context, rawProps,
"textTransform",
sourceProps.textTransform,
{})),
color(0 /*convertRawProp(context, rawProps, "color", sourceProps.color, {0})*/),
letterSpacing(CoreFeatures::enablePropIteratorSetter? sourceProps.letterSpacing : convertRawProp(context, rawProps,
letterSpacing(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.letterSpacing : convertRawProp(context, rawProps,
"letterSpacing",
sourceProps.letterSpacing,
{0.0})),
fontSize(CoreFeatures::enablePropIteratorSetter? sourceProps.fontSize :
fontSize(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.fontSize :
convertRawProp(context, rawProps, "fontSize", sourceProps.fontSize, {0.0})),
textAlign(CoreFeatures::enablePropIteratorSetter? sourceProps.textAlign :
textAlign(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.textAlign :
convertRawProp(context, rawProps, "textAlign", sourceProps.textAlign, {})),
includeFontPadding(CoreFeatures::enablePropIteratorSetter? sourceProps.includeFontPadding : convertRawProp(context, rawProps,
includeFontPadding(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.includeFontPadding : convertRawProp(context, rawProps,
"includeFontPadding",
sourceProps.includeFontPadding,
{false})),
fontWeight(CoreFeatures::enablePropIteratorSetter? sourceProps.fontWeight :
fontWeight(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.fontWeight :
convertRawProp(context, rawProps, "fontWeight", sourceProps.fontWeight, {})),
fontFamily(CoreFeatures::enablePropIteratorSetter? sourceProps.fontFamily :
fontFamily(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.fontFamily :
convertRawProp(context, rawProps, "fontFamily", sourceProps.fontFamily, {})),
// See AndroidTextInputComponentDescriptor for usage
// TODO T63008435: can these, and this feature, be removed entirely?
hasPadding(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPadding : hasValue(rawProps, sourceProps.hasPadding, "padding")),
hasPaddingHorizontal(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingHorizontal : hasValue(
hasPadding(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPadding : hasValue(rawProps, sourceProps.hasPadding, "padding")),
hasPaddingHorizontal(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingHorizontal : hasValue(
rawProps,
sourceProps.hasPaddingHorizontal,
"paddingHorizontal")),
hasPaddingVertical(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingVertical : hasValue(
hasPaddingVertical(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingVertical : hasValue(
rawProps,
sourceProps.hasPaddingVertical,
"paddingVertical")),
hasPaddingLeft(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingLeft : hasValue(
hasPaddingLeft(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingLeft : hasValue(
rawProps,
sourceProps.hasPaddingLeft,
"paddingLeft")),
hasPaddingTop(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingTop :
hasPaddingTop(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingTop :
hasValue(rawProps, sourceProps.hasPaddingTop, "paddingTop")),
hasPaddingRight(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingRight : hasValue(
hasPaddingRight(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingRight : hasValue(
rawProps,
sourceProps.hasPaddingRight,
"paddingRight")),
hasPaddingBottom(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingBottom : hasValue(
hasPaddingBottom(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingBottom : hasValue(
rawProps,
sourceProps.hasPaddingBottom,
"paddingBottom")),
hasPaddingStart(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingStart : hasValue(
hasPaddingStart(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingStart : hasValue(
rawProps,
sourceProps.hasPaddingStart,
"paddingStart")),
hasPaddingEnd(CoreFeatures::enablePropIteratorSetter? sourceProps.hasPaddingEnd :
hasPaddingEnd(ReactNativeFeatureFlags::enableCppPropsIteratorSetter()? sourceProps.hasPaddingEnd :
hasValue(rawProps, sourceProps.hasPaddingEnd, "paddingEnd")) {
}
@@ -223,10 +216,8 @@ void AndroidTextInputProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(maxFontSizeMultiplier);
RAW_SET_PROP_SWITCH_CASE_BASIC(keyboardType);
RAW_SET_PROP_SWITCH_CASE_BASIC(returnKeyType);
RAW_SET_PROP_SWITCH_CASE_BASIC(multiline);
RAW_SET_PROP_SWITCH_CASE_BASIC(secureTextEntry);
RAW_SET_PROP_SWITCH_CASE_BASIC(selectTextOnFocus);
RAW_SET_PROP_SWITCH_CASE_BASIC(submitBehavior);
RAW_SET_PROP_SWITCH_CASE_BASIC(caretHidden);
RAW_SET_PROP_SWITCH_CASE_BASIC(contextMenuHidden);
RAW_SET_PROP_SWITCH_CASE_BASIC(textShadowColor);
@@ -322,7 +313,7 @@ folly::dynamic AndroidTextInputProps::getDynamic() const {
props["value"] = value;
props["defaultValue"] = defaultValue;
props["selectTextOnFocus"] = selectTextOnFocus;
props["submitBehavior"] = submitBehavior;
props["submitBehavior"] = toDynamic(submitBehavior);
props["caretHidden"] = caretHidden;
props["contextMenuHidden"] = contextMenuHidden;
props["textShadowColor"] = toAndroidRepr(textShadowColor);
@@ -13,6 +13,7 @@
#include <react/renderer/attributedstring/TextAttributes.h>
#include <react/renderer/attributedstring/conversions.h>
#include <react/renderer/components/textinput/BaseTextInputProps.h>
#include <react/renderer/components/textinput/basePrimitives.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/propsConversions.h>
#include <react/renderer/graphics/Color.h>
@@ -89,11 +90,9 @@ class AndroidTextInputProps final : public BaseTextInputProps {
Float maxFontSizeMultiplier{0.0};
std::string keyboardType{};
std::string returnKeyType{};
bool multiline{false};
bool secureTextEntry{false};
std::string value{};
bool selectTextOnFocus{false};
std::string submitBehavior{};
bool caretHidden{false};
bool contextMenuHidden{false};
SharedColor textShadowColor{};
@@ -27,24 +27,6 @@ namespace facebook::react {
extern const char AndroidTextInputComponentName[] = "AndroidTextInput";
AndroidTextInputShadowNode::AndroidTextInputShadowNode(
const ShadowNode& sourceShadowNode,
const ShadowNodeFragment& fragment)
: ConcreteViewShadowNode(sourceShadowNode, fragment) {
auto& sourceTextInputShadowNode =
static_cast<const AndroidTextInputShadowNode&>(sourceShadowNode);
if (ReactNativeFeatureFlags::enableCleanTextInputYogaNode()) {
if (!fragment.children && !fragment.props &&
sourceTextInputShadowNode.getIsLayoutClean()) {
// This ParagraphShadowNode was cloned but did not change
// in a way that affects its layout. Let's mark it clean
// to stop Yoga from traversing it.
cleanLayout();
}
}
}
void AndroidTextInputShadowNode::setContextContainer(
ContextContainer* contextContainer) {
ensureUnsealed();
@@ -40,10 +40,6 @@ class AndroidTextInputShadowNode final
using ConcreteViewShadowNode::ConcreteViewShadowNode;
AndroidTextInputShadowNode(
const ShadowNode& sourceShadowNode,
const ShadowNodeFragment& fragment);
void setContextContainer(ContextContainer* contextContainer);
/*
@@ -9,6 +9,7 @@
#include <react/renderer/attributedstring/conversions.h>
#include <react/renderer/components/iostextinput/propsConversions.h>
#include <react/renderer/components/textinput/baseConversions.h>
#include <react/renderer/core/graphicsConversions.h>
#include <react/renderer/core/propsConversions.h>
@@ -64,7 +65,7 @@ TextAttributes TextInputProps::getEffectiveTextAttributes(
ParagraphAttributes TextInputProps::getEffectiveParagraphAttributes() const {
auto result = paragraphAttributes;
if (!traits.multiline) {
if (!multiline) {
result.maximumNumberOfLines = 1;
}
@@ -20,24 +20,6 @@ namespace facebook::react {
extern const char TextInputComponentName[] = "TextInput";
TextInputShadowNode::TextInputShadowNode(
const ShadowNode& sourceShadowNode,
const ShadowNodeFragment& fragment)
: ConcreteViewShadowNode(sourceShadowNode, fragment) {
auto& sourceTextInputShadowNode =
static_cast<const TextInputShadowNode&>(sourceShadowNode);
if (ReactNativeFeatureFlags::enableCleanTextInputYogaNode()) {
if (!fragment.children && !fragment.props &&
sourceTextInputShadowNode.getIsLayoutClean()) {
// This ParagraphShadowNode was cloned but did not change
// in a way that affects its layout. Let's mark it clean
// to stop Yoga from traversing it.
cleanLayout();
}
}
}
AttributedStringBox TextInputShadowNode::attributedStringBoxToMeasure(
const LayoutContext& layoutContext) const {
bool hasMeaningfulState =
@@ -83,7 +65,7 @@ AttributedString TextInputShadowNode::getAttributedString(
.string = getConcreteProps().text,
.textAttributes = textAttributes,
// TODO: Is this really meant to be by value?
.parentShadowView = ShadowView{}});
.parentShadowView = ShadowView(*this)});
auto attachments = Attachments{};
BaseTextShadowNode::buildAttributedString(
@@ -111,7 +93,8 @@ void TextInputShadowNode::updateStateIfNeeded(
(!state.layoutManager || state.layoutManager == textLayoutManager_) &&
"`StateData` refers to a different `TextLayoutManager`");
if (state.reactTreeAttributedString == reactTreeAttributedString &&
if (state.reactTreeAttributedString.isContentEqual(
reactTreeAttributedString) &&
state.layoutManager == textLayoutManager_) {
return;
}
@@ -32,10 +32,6 @@ class TextInputShadowNode final : public ConcreteViewShadowNode<
public:
using ConcreteViewShadowNode::ConcreteViewShadowNode;
TextInputShadowNode(
const ShadowNode& sourceShadowNode,
const ShadowNodeFragment& fragment);
static ShadowNodeTraits BaseTraits() {
auto traits = ConcreteViewShadowNode::BaseTraits();
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
@@ -125,26 +125,6 @@ inline void fromRawValue(
abort();
}
inline void fromRawValue(
const PropsParserContext& context,
const RawValue& value,
SubmitBehavior& result) {
auto string = (std::string)value;
if (string == "newline") {
result = SubmitBehavior::Newline;
return;
}
if (string == "submit") {
result = SubmitBehavior::Submit;
return;
}
if (string == "blurAndSubmit") {
result = SubmitBehavior::BlurAndSubmit;
return;
}
abort();
}
inline void fromRawValue(
const PropsParserContext& context,
const RawValue& value,
@@ -7,6 +7,7 @@
#pragma once
#include <react/renderer/components/textinput/basePrimitives.h>
#include <optional>
#include <string>
@@ -47,14 +48,6 @@ enum class ReturnKeyType {
Continue,
};
// iOS & Android.
enum class SubmitBehavior {
Default,
Submit,
BlurAndSubmit,
Newline,
};
// iOS-only
enum class TextInputAccessoryVisibilityMode {
Never,
@@ -94,12 +87,6 @@ class Selection final {
*/
class TextInputTraits final {
public:
/*
* iOS & Android
* Default value: `false`.
*/
bool multiline{false};
/*
* iOS & Android
* Default value: `Sentences`.
@@ -175,12 +162,6 @@ class TextInputTraits final {
*/
bool secureTextEntry{false};
/*
* iOS & Android
* Default value: `Default`.
*/
SubmitBehavior submitBehavior{SubmitBehavior::Default};
/*
* iOS-only (implemented only on iOS for now)
* Default value: `false`.

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