Compare commits

...
Author SHA1 Message Date
Nicola Corti a429f4169c Fix tests - take 4 2024-11-05 14:15:39 +00:00
Nicola Corti 05f073d346 Fix tests - take 3 2024-11-05 14:11:50 +00:00
Nicola Corti a0ca57538f Fix tests - take 2 2024-11-05 13:49:14 +00:00
Nicola Corti 292f3a4cab Fix jest tests 2024-11-05 11:49:39 +00:00
Riccardo Cipolleschi 68231cb949 [LOCAL] Revert React 19 to React 18.3.1 2024-11-05 11:49:39 +00:00
Nicola Corti 1f62529dc4 Properly handle paths with spaces in autolinking (#47388)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47388

Fixes https://github.com/facebook/react-native/issues/47364
Fixes https://github.com/facebook/react-native/issues/47377
Fixes https://github.com/facebook/react-native/issues/37124

We're having problems is a path contains a space ' ' because when autolinking,
the `add_subdirectory()` function of CMake consider the path with space as 2 parameters.

This fixes it by properly quoting the path.

Changelog:
[Android] [Fixed] - Properly handle paths with spaces in autolinking

Reviewed By: cipolleschi

Differential Revision: D65434413

fbshipit-source-id: b9147482f98f7e222405cc8d9e6f3c17a5f4ed02
2024-11-05 03:32:16 -08:00
Nicola Corti 3956955eaa Use absolute path when compiling appmodules.so sources (#47379)
Summary:
Fixes https://github.com/facebook/react-native/issues/47352

This fixes a bug when the user is providing its own CMakeLists.txt file say because they want to compile more C++ code than we actually provide.

Previously the `*.cpp` will evalute file in the current directory, meaning that the app's default `OnLoad.cpp` file would be ignored.

## Changelog:

[ANDROID] [FIXED] - Use absolute path when compiling appmodules.so sources

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

Test Plan:
Tested against the reproducer provided in:
- Use absolute path when compiling appmodules.so sources

Reviewed By: cipolleschi

Differential Revision: D65428676

Pulled By: cortinico

fbshipit-source-id: 7f3e4d470da0fffc5191c1a2c7e8fec517fee496
2024-11-05 03:27:59 -08:00
Nicola Corti 83d38501b8 setup-gradle v4 + Remove unnecessary Gradle Wrapper Validation (#47389)
Summary:
As per: https://github.com/gradle/actions#the-wrapper-validation-action

> Starting with v4 the setup-gradle action will [perform wrapper validation](https://github.com/gradle/actions/blob/main/docs/setup-gradle.md#gradle-wrapper-validation) on each execution. If you are using setup-gradle in your workflows, it is unlikely that you will need to use the wrapper-validation action.

I'm moving to setup-gradle v4 and remove this unnecessary extra action.

## Changelog:

[INTERNAL] - setup-gradle v4 + Remove unnecessary Gradle Wrapper Validation

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

Test Plan: CI

Reviewed By: blakef

Differential Revision: D65435069

Pulled By: cortinico

fbshipit-source-id: c28b4d520e91fea9c59a341fb94598db5fc69900
2024-11-05 03:19:06 -08:00
Riccardo Cipolleschi d7d5535fe1 Suppres CC_MD5 warning (#47378)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47378

The RCTMD5Hash in RCTUtils is using CC_MD5 function which is deprecated. unfortunately we can't really change it or we will break many apps that use it in the AsyncStorage.

Those app wlll have to do a migration to use a different function. Meanwhile we are suppressing the warning

## Changelog
[Internal] - Suppress CC_MD5 warning

Reviewed By: cortinico

Differential Revision: D65424309

fbshipit-source-id: e0258ae68482f6c4a3a865bb52920f87bc5ada21
2024-11-05 02:48:49 -08:00
Ramanpreet Nara 0e7ba9094e Make redboxes resilient to react native preloading (#47391)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47391

React Native can preload before the activity is available.

Preloading will execute the js bundle. If the js bundle throws an error, it'll try to render a redbox.

If the activity isn't available, and hasn't been set on the react instance yet, the redbox will just render nothing.

## Changes
In this diff, just re-try displaying the redbox after the application sets the activity on the react instance (i.e: calls onHostResume(activity)).

Changelog: [Android][Breaking] - Rename DevSupportManagerBase.getCurrentContext() -> getCurrentReactContext()

Reviewed By: mdvacca

Differential Revision: D65352596

fbshipit-source-id: 7750f6ca493fc50405119958e0f2908fc24f1cb4
2024-11-04 18:46:35 -08:00
Ramanpreet Nara 5a6a42c7d0 DevSupportManagerBase: Rename getCurrentContext() -> getCurrentReactContext() (#47390)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47390

getCurrentContext() is very ambiguous.

Changelog: [Android][Breaking] - Make DevSupportManagerBase.getCurrentReactContext() public

Reviewed By: mdvacca

Differential Revision: D65433217

fbshipit-source-id: a739d206de8085fc5b47b2a31c7e94fe6e71852f
2024-11-04 18:46:35 -08:00
David Vacca fe656be26e Reduce visibility of ReactUnimplementedViewManager to internal (#47396)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47396

Migrate ReactUnimplementedViewManager to internal visibility

verified and there are usages on OSS

changelog: [Android][Breaking] Reduce visibility of ReactUnimplementedViewManager to internal

Reviewed By: cortinico

Differential Revision: D65444514

fbshipit-source-id: 11ff2acc96098bc4e53be7ef3059e4a5c112c43e
2024-11-04 17:46:14 -08:00
Joe Vilches c9a96715ef Update public API for intrinsic sizing setters (#46939)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46939

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

tsia! opted for one function for each keyword just like auto. This is kinda annoying and not the most sustainable, so maybe it makes more sense to make a new enum here and just add one function

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D64002837

fbshipit-source-id: f15fae9fc0103175e1d85850fc9aa68579989fd3
2024-11-04 16:02:37 -08:00
Joe Vilches 027b8032c2 Modify private apis to set, store, and get intrinsic sizing keywords (#46938)
Summary:
X-link: https://github.com/facebook/yoga/pull/1721

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

The private internals of how we store styles needed to change a bit to support 3 new keyword values. Right now the only other keyword that can be stored is `auto`. As a result there isn't much fancy logic to support storing this and its just stored as a specific type inside of `StyleValueHandle`. There are only 3 bits for types (8 values), so it is not sustainable to just stuff every keyword in there. So the change writes the keyword as a value with a new `keyword` `Type`.

I chose not to put `auto` in there even though it is a keyword since it is a hot path, I did not want to regress perf when I did not need to.

I also make a new `StyleSizeValue` class to store size values - so values for `width`, `height`, etc. This way these new keywords are kept specific to sizes and we will not be able to create, for example, a margin: `max-content`.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D63927512

fbshipit-source-id: 7285469d37ac4b05226183b56275c77f0c06996c
2024-11-04 16:02:37 -08:00
Eli White 35f0e1cca2 Fix CodegenSchema Enum type to not export array (#47324)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47324

I need to reference this type somewhere else, but not an array of the type.

Generally we prefer that all exported types are the object itself, and it used as a member type of arrays when used.

Changelog: [Internal]

Reviewed By: makovkastar

Differential Revision: D65259014

fbshipit-source-id: 35fb5fe03a44bed61ad87337d0fc5c198744c0e9
2024-11-04 12:58:49 -08:00
Eli White dd472101b7 Add NumberLiteralTypeAnnotation support (#47323)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47323

This change adds support for number literals as a type.

The codegen already has parsing support for these types
```
  +passNumber: (arg: number) => void;
  +passString: (arg: string) => void;
  +passStringLiteral: (arg: 'A String Literal') => void;
```

This change now also supports
```
  +passNumberLiteral: (arg: 4) => void;
```

On the native side this is treated the same as `number`. It could be strengthened in the future.

This is a pre-requisite for number literal unions and enums.

Changelog: [Added] Codegen: Added support for Number literals in native module specs

Reviewed By: makovkastar

Differential Revision: D65249334

fbshipit-source-id: 98b051d2a6bd1ad5cc6473ac88acfcbe82bd5c7d
2024-11-04 12:58:49 -08:00
Nicola Corti 623d481991 Make ReactDebugOverlayTags, DebugOverlayTags, Printer, PrinterHolder, NoopPrinter internal
Summary:
Those 2 classes are not supposed to be exposed externally, so I'm making them internal.
The were never part of the public API so I'm not marking this commit as [BREAKING]

Changelog:
[Android] [Changed] - Make ReactDebugOverlayTags, DebugOverlayTags, Printer, PrinterHolder, NoopPrinter internal

Reviewed By: fabriziocucci

Differential Revision: D65420257

fbshipit-source-id: b870274e84d9c3202b9f21360c29eeb995a8d52b
2024-11-04 12:20:50 -08:00
Nicola Corti cba1d4bae7 Stable API - Make InteropModuleRegistry internal (#47374)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47374

I've converted this class to Kotlin + made it `internal` as it should not be exposed publicly.
This class is part of the iterop layer for the New Architecture.
Marked as breaking but I expect no meaningful breakages here.

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

Reviewed By: javache

Differential Revision: D65421965

fbshipit-source-id: 207be5379ebe3a31530cfea75b4623787f5ae7cf
2024-11-04 11:01:46 -08:00
zhongwuzw 44f2a08371 Add png extension only if file exist when load local image (#46971)
Summary:
FIxes https://github.com/facebook/react-native/issues/46870.

To avoid many breaking changes, I modified the logic to add the PNG extension only if the file exists.

## Changelog:

[IOS] [FIXED] - Add png extension only if file exist when load local image

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

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

Reviewed By: blakef

Differential Revision: D65276409

Pulled By: cipolleschi

fbshipit-source-id: 9e03a36b229f7c336632b5b76a92d9f749c59835
2024-11-04 10:26:55 -08:00
Nicola Corti d7550293a2 Stable API - Make ReactDevToolsSettingsManagerModule and ReactDevToolsRuntimeSettingsModule internal (#47373)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47373

Users should not depend on `ReactDevToolsSettingsManagerModule` directly hence I'm making it internal.
I expect to breakages in OSS as there no usages at all:
https://github.com/search?type=code&q=NOT+is%3Afork+NOT+org%3Afacebook+com.facebook.react.modules.reactdevtoolssettings.ReactDevToolsSettingsManagerModule
https://github.com/search?type=code&q=NOT+is%3Afork+NOT+org%3Afacebook+com.facebook.react.modules.devtoolsruntimesettings.ReactDevToolsRuntimeSettingsModule

Changelog:
[Android] [Breaking] - Stable API - Make ReactDevToolsSettingsManagerModule and ReactDevToolsRuntimeSettingsModule internal

Reviewed By: javache

Differential Revision: D65421030

fbshipit-source-id: e9d701af6cde25133f7b3ff9b07b678a7710852c
2024-11-04 10:26:47 -08:00
oddlyspaced cc1d2853fb feat(Android): add support for invert colors check on android accessibility (#47341)
Summary:
This PR provides a fix for the long existing issue of missing check for invert color in accessibility options on Android.
Reference Issue : https://github.com/facebook/react-native/issues/30870

## Changelog:
- Added native module code to check for invert color settings value
- Updated js module to return a proper promise instead of default false for isInvertColorsEnabled()

Pick one each for the category and type tags:

[ANDROID] [FIXED] - Missing isInvertColorsEnabled implementation for Android

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

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

Test Plan: Tested on OnePlus 12 with Android 14 and Pixel 6 with Android 15. The try catch exists because in some cases if the switch hasn't been toggled before the android system raises the missing settings exception.

Reviewed By: cortinico, fabriziocucci

Differential Revision: D65419632

Pulled By: javache

fbshipit-source-id: ddb103445a9d0f318e52ba9d23750140ce5a7ed0
2024-11-04 10:06:10 -08:00
Mateo Guzmán dc9db01665 feat(image): [android] adding only-if-cached cache control option (#47348)
Summary:
Following up from https://github.com/facebook/react-native/issues/47182, as basic caching control is already in place in Android, it can be extended to include the `only-if-cached` option.

We check whether the image is in the cache. If it is, we proceed to load it. Otherwise, we do nothing.

## Changelog:

[ANDROID] [ADDED] - Image `only-if-cached` cache control option

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

Test Plan:
In the `rn-tester`, I added a third example for Android where the third image will never be loaded as the cache policy is set to `only-if-cached` and the image has not been loaded before.

<details>
<summary>Video demonstrating how the `only-if-cached` options behaves</summary>

https://github.com/user-attachments/assets/45669e81-5414-4103-8931-138bffa81447

</details>

<details>
<summary>Error from image not found in cache example</summary>

<img width="807" alt="image" src="https://github.com/user-attachments/assets/6b79d811-1809-437c-b2fe-c86d3da7c58d">

</details>

Reviewed By: rshest

Differential Revision: D65384639

Pulled By: Abbondanzo

fbshipit-source-id: f4a72694f45eb3d7097c350f4a4008a0abf0a1ab
2024-11-04 08:37:59 -08:00
Samuel Susla 91df5a4a0f surface setup issues in EventBeat and Scheduler (#47355)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47355

changelog: [internal]

Reviewed By: rshest

Differential Revision: D65333695

fbshipit-source-id: 854dbc3ae52db0093961cbeb81f1f96934eca40d
2024-11-04 08:15:12 -08:00
Parsa Nasirimehr 4da586ead9 chore(Android): Migrate DebugOverlayTag and ReactDebugOverlayTag to Kotlin (#47362)
Summary:
I believe these two were the last items under `com.facebook.debug` that were still Java.

I thought about making DebugOverlayTag a Data class, but i will leave it up to the reviewer to decide if it would be needed or not.

## Changelog:

[INTERNAL] [FIXED] - Migrate DebugOverlayTag and ReactDebugOverlayTag to Kotlin

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

Test Plan:
`./gradlew test`:
<img width="1265" alt="Screenshot 2024-11-02 at 18 45 45" src="https://github.com/user-attachments/assets/405e77bc-1287-4329-b230-9f46eadb3580">

Reviewed By: javache

Differential Revision: D65417984

Pulled By: cortinico

fbshipit-source-id: e39224e40bde281498fdbed1609a03b264967396
2024-11-04 06:57:47 -08:00
Marc Rousavy de3c1ee097 feat: Trigger Java GC on reload (#43813)
Summary:
While we (Margelo) were developing a new C++ 3D library for react-native, we noticed that Java often keeps a lot of dead instances in memory, making it hard to debug memory allocations (or actually _de_-allocations), especially since we use `jsi::HostObject` and `jni::HybridClass` in conjunction. Having two garbage-collected languages retain an object is a bit tricky, and making sure that we aren't doing anything wrong with our allocations and references was not easy - but manually calling `System.gc()` on app reloads helped us see that much better.

Before this, we needed to wait multiple minutes until some Java objects are actually freed from the GC. Our use-case was a `facebook::jni::HybridClass`, which was held strong in a `facebook::jsi::HostObject` (so again, two GC'd languages).

There _should_ be no change in behaviour with this PR, just two things to note:

1. Memory might be free'd more eagerly in full reloads (dev builds) - makes sense for library developers, especially when working with C++ modules.
2. `System.gc()` only _suggests_ garbage collection, it does not _force_ it. But when it runs, it might impact performance, although we haven't noticed any impact of that at all. The garbage collector runs anyways - better during a reload than later when exceuting the app normally.

## Changelog:

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

Pick one each for the category and type tags:

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

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

[ANDROID] [ADDED] - Trigger Java GC on app reload

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

Test Plan:
Open an app, create a Java module that holds a few objects, add `finalize()` methods to those objects and log their deletion.

Reload the app to see the logs, compare before vs after.

Reviewed By: rshest

Differential Revision: D65418163

Pulled By: javache

fbshipit-source-id: 7597548790577dfc542b57f59578ae48df543b14
2024-11-04 06:53:07 -08:00
Nicola Corti e1a1cead43 AGP to 8.7.2 (#47369)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47369

This just bumps the AGP patch version to the latest stable.

Changelog:
[Android] [Changed] - AGP to 8.7.2

Reviewed By: tdn120

Differential Revision: D65336357

fbshipit-source-id: 9a7464304ba29f6b752f41b252bde9cb0eca0e9a
2024-11-04 05:57:22 -08:00
Peter Abbondanzo 7211119d23 Add cache control check to multisource (#47357)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47357

`MultiSourceHelper` should not yield an `ImageSource` that has its cache control policy set to `RELOAD`. This change skips such sources when computing the bestCached item (but not best item)

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D65337414

fbshipit-source-id: bdd0d55f4a65128b141a1c7a132dba085232fa11
2024-11-01 15:26:58 -07:00
Chi Tsai 6ab7b70241 Add utf16 method to JSI (#47356)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47356

Add utf16 method to JSI. This change will add the default implementation
for all VMs by calling UTF8 and manually convert it to UTF16. A later
change will be added for Hermes to use internal VM information to get
the UTF16 string.

Changelog: [Internal]

Reviewed By: neildhar

Differential Revision: D64918244

fbshipit-source-id: 6fc0c44fc397c2f8bb40a4262596b178ee4f1f29
2024-11-01 13:52:46 -07:00
zhongwuzw af384a914a FIxes CornerRadiiAreEqualAndSymmetrical error when check topLeftHorizontal == topLeftVertical (#47338)
Summary:
FIxes CornerRadiiAreEqualAndSymmetrical error when check topLeftHorizontal == topLeftVertical cc. jorge-cab

## Changelog:

[IOS] [FIXED] - FIxes CornerRadiiAreEqualAndSymmetrical error when check topLeftHorizontal == topLeftVertical

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

Test Plan: N/A

Reviewed By: jorge-cab

Differential Revision: D65281958

Pulled By: cipolleschi

fbshipit-source-id: f79fced7282bf75201d9dc99c82eeaddade0d314
2024-11-01 08:12:29 -07:00
Mateo Guzmán 566d30f88a fix(rn-tester): playground description not visible in dark mode (#47346)
Summary:
The informational description in the `RNTesterPlayground` is not visible in dark mode. To address this, the `RNTesterText`, which takes into account the theme, is used.

## Changelog:

[INTERNAL] [FIXED] -  `RNTesterPlayground` description not visible in dark mode

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

Test Plan:
| Before  | After |
  | ---------- | ---------- |
  | ![Screenshot_1730414376](https://github.com/user-attachments/assets/a42e1a99-de61-41b5-b677-ea3e2b4956fc) | ![Screenshot_1730414393](https://github.com/user-attachments/assets/885ed334-8277-4ba8-a033-477b9afef7b6) |

Reviewed By: cortinico

Differential Revision: D65319138

Pulled By: Abbondanzo

fbshipit-source-id: ff541be9705fb799cc4aa3624a9e2966a76a0f8d
2024-11-01 07:36:05 -07:00
Alex Hunt 4afc47a588 Revert to @babel/eslint-parser in eslint-config (#47333)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47333

Motivated by https://github.com/facebook/hermes/issues/1549. This was originally changed in https://github.com/facebook/react-native/pull/46696, as our internal Flow support had diverged from `babel/eslint-parser` (https://github.com/facebook/react-native/issues/46601).

We effectively have three flavours of JavaScript in support:
- Flow@latest for the `react-native` package, shipped as source — uses `hermes-parser`.
- TypeScript for product code (community template, Expo) — uses `babel/plugin-syntax-typescript`.
- Plain JavaScript or Flow in product code, *which may be extended with additional user Babel plugins and needs lenient parsing* — uses `babel/plugin-syntax-flow` via `babel/eslint-parser` (**this change**).

I'd love to simplify this 😅.

Switching to `hermes-eslint` for the RN monorepo codebase (D63541483) is unchanged.

Changelog: [Internal]

Reviewed By: robhogan, cipolleschi

Differential Revision: D65272156

fbshipit-source-id: 3a2bbe3fcf8ed6057f6d994a0be4985e6bf46fa9
2024-11-01 05:31:37 -07:00
Alan Lee 2cd48ef351 fix Modal content being cut off when Android Activity is edge-to-edge (#47339)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47339

Fixing issue raised in https://github.com/facebook/react-native/issues/47307

This is a follow up from D62286026.
It appears there was a line that went missing while trying to refactor the code.

`fitsSystemWindows = true` is needeod for < API 30 to avoid content rendering under the system bars when Modal is shown with Activity that is edge-to-edge.

Changelog:
[Android][Fixed] Fix Regression - Modal content rendering below system bar on < API 30 when activity is edge-to-edge

Reviewed By: cortinico

Differential Revision: D65280014

fbshipit-source-id: 616ff739be55635f1295ef3bf8b997a27ef769ae
2024-11-01 01:27:40 -07:00
Alan Lee 65cdd5b82c Enable 16KB page size binaries for RN libraries + hermes (#47042)
Summary:
X-link: https://github.com/facebook/hermes/pull/1557

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

Add native build flags to support 16KB page size

- https://developer.android.com/guide/practices/page-sizes#compile-r27-higher

Changelog:
[Android][Added] add cmake arguments to support 16KB page size for native libraries

Reviewed By: cortinico

Differential Revision: D64446876

fbshipit-source-id: 5c6b7874a8837c7ebc9b3e9267ce11fb152bf535
2024-10-31 18:45:31 -07:00
Samuel Susla 66a2f1d312 Back out "delete redundant EventEmitter::dispatchEvent overload" (#47347)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47347

changelog: [internal]

Original commit changeset: cffdc3ef0424

Original Phabricator Diff: D65040505

Reviewed By: lunaleaps

Differential Revision: D65305763

fbshipit-source-id: 4c9e4b4acd9c5f9530af428402b106272a4e0054
2024-10-31 18:42:07 -07:00
Nolan O'Brien 79d55542aa Move FBHashKit to LayerZero/METAHash (#47343)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47343

Moving `FBHashKit` to *LayerZero* as `METAHash`

## Changelog

[Internal][Change] Move `FBXXHashUtils`

Reviewed By: adamjernst

Differential Revision: D65256846

fbshipit-source-id: 6e24a78925367e83e94e7c67a235cda924edd28e
2024-10-31 18:01:57 -07:00
Nolan O'Brien f8fc90e754 Modernize in preparation for move to Layer Zero (#47342)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47342

There are things we can do to modernize `FBHashKit` to make it ready for prime time, aka Layer Zero.

  * Consolidate down to a singular `meta_hash(...)` generic macro (supports all primitives for hashing)
  * Eliminate the unnecessary C++
  * Deprecate legacy FB APIs
  * Make logic (and interfaces) explicit for 32 vs 64 bit inputs and 32 vs 64 bit outputs
  * Introduce robust unit tests
  * Have unit tests actually testable for 32-bit hashes

## Changelog

[Internal][Change] Prep to move `FBXXHashUtils`

Reviewed By: cipolleschi

Differential Revision: D65245787

fbshipit-source-id: 311404068fd9df2a77d1ae4850b8a785466e73f0
2024-10-31 18:01:57 -07:00
Parsa Nasirimehr ec4ead59e1 fix(iOS): small test fix for RCTViewTests (#47314)
Summary:
Depracated usage of scrollInsets + an unused param.

## Changelog:

[INTERNAL] [FIXED] - Switch to verticalScrollIndicatorInsets and mark unused value as __unused in test file

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

Test Plan:
Running the specific test itself, it passes:
<img width="1092" alt="Screenshot 2024-10-30 at 18 02 08" src="https://github.com/user-attachments/assets/e3ed27c6-9f00-4777-a72c-92f0da93a79f">

Reviewed By: NickGerleman

Differential Revision: D65231365

Pulled By: philIip

fbshipit-source-id: eed795ad65bd837fb9f38175081d961245ff3932
2024-10-31 16:24:41 -07:00
Jakub Piasecki fd273f83e0 Add RNTester examples for display: contents (#47201)
Summary:
Adds a page dedicated to `display: contents` to RNTester APIs section. Those can be used to verify that it's working correctly visually.

Needs https://github.com/facebook/react-native/pull/47194

## Changelog:

[INTERNAL] [ADDED] - Added `display: contents` examples to RNTester

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

Test Plan:
Row styles are ignored in new arch and TextInputs as leaf are hidden

https://www.internalfb.com/compare-screenshots-from-diff/D65248256

Reviewed By: javache

Differential Revision: D65248256

Pulled By: NickGerleman

fbshipit-source-id: 90410e1380e4cdb22cb4cac5c8c21e08a088ce69
2024-10-31 16:12:46 -07:00
Nicola Corti ecd138e267 Enable warningAsErrors for hermes-engine (#47320)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47320

I've solved all the warnings on ReactAndroid/hermes-engine.
This enables warningsAsErrors for that part of the codebase so we can make sure
no further warnings get introduced.

Changelog:
[Internal] [Changed] - Enable warningAsErrors for hermes-engine

Reviewed By: NickGerleman

Differential Revision: D65243753

fbshipit-source-id: 17c22d1a7a32d2c684d7f236f7554f6e26469e99
2024-10-31 15:05:12 -07:00
Sam Zhou b91a449e7f Cleanup problematic React.ElementRef (#47340)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47340

This diff cleans up some problematic `React.ElementRef<T>` when T is generic type.

Changelog: [Internal]

Reviewed By: alexmckenley

Differential Revision: D65280467

fbshipit-source-id: 71172b16320a10cbc7a8b46dae5d3dd0eb00ba0c
2024-10-31 13:30:17 -07:00
Pieter De Baets 6ba7cb3102 Fix potential race in FabricMountingManager (#47337)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47337

We call `onSurfaceStart` after calling `surfaceHandler.start()`. In theory it's possible for the React surface to start generating commits before we've informed the mounting manager of the surface having started, which could cause us to not accurately track views allocated for that surface so far.

Changelog: [Android][Fixed] Addressed race condition in surface start.

Reviewed By: rshest

Differential Revision: D65269674

fbshipit-source-id: 2927220bc17e61125dabcdd75f5325a0ca77e60b
2024-10-31 12:33:13 -07:00
Mateo Guzmán e5dd7d68bf feat(image): enabling basic cache control for android (#47182)
Summary:
Fixes https://github.com/facebook/react-native/issues/12606

Previously, `Image` cache control options were not functional on Android, even though they were being passed to the native component via the `source` prop. This PR addresses that by implementing logic to manage cache behaviour on Android.

When the `reload` option is explicitly set, the image is now evicted from both memory and disk caches before a new request is made. This ensures the image is always fetched from the source, aligning the caching behaviour between Android and iOS for the `default` and `reload` options.

## Changelog:

[ANDROID][ADDED] - Enabling basic `Image` cache control for Android

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

Test Plan:
Added a new example to the `rn-tester`, where we can notice that the image on the right is reloaded if rendered or re-rendered as the cache policy is set to `reload`. The image on the left has the cache policy set to `default` and won't be re-rendered as the image is already in the cache.  See the video below:

https://github.com/user-attachments/assets/88bc1d2d-0239-4deb-bcde-fe0ce521ff4d

Also tested on both old and new architecture.

Reviewed By: NickGerleman

Differential Revision: D64915440

Pulled By: Abbondanzo

fbshipit-source-id: 32e1c55dd20bf96ab0f69ef900d821c3c2552ef7
2024-10-31 09:07:40 -07:00
Samuel Susla a12036f7be delete redundant EventEmitter::dispatchEvent overload (#47231)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47231

changelog: [internal]

`EventEmitter::dispatchEvent` and `EventEmitter::dispatchUniqueEvent` that were accepting shared_ptr are not needed. Their functionality is covered by other methods. Let's get rid of them to keep the API of EventEmitter slim.

Reviewed By: rubennorte

Differential Revision: D65040505

fbshipit-source-id: cffdc3ef042418178c5e2e5714779dfd0b61455e
2024-10-31 08:15:21 -07:00
Pieter De Baets 3e46cb384c Downgrade fatal error in FabricMountingManager (#47329)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47329

Downgrading from fatal (introduced in D63148523). It's not yet clear why this is firing, and may point at deeper underlying issues, as the re-ordering we do in `disableMountItemReorderingAndroid` only occurs at a later point in `FabricMountingManager`.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D65267936

fbshipit-source-id: cb32b149a77c9e5a3ac6350baaeae9c7215df01b
2024-10-31 06:47:13 -07:00
HyunWoo Lee 667ba76aef Click basic button & scroll down until item 600 is visible (#46804)
Summary:
This pr is part of issue https://github.com/facebook/react-native/issues/46757 solving a task - [ME2E0008] [ME2E0009]

- Set up a test
  - Starts the app
  - Scrolls until flatlist is visilbe and clicks on flatlist
  - Click basic button
  - Scroll down until item 600 is visible

## Changelog:

[Internal] [Added] - Add e2e-test logic that click button & scroll down until specific item is visible

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

Test Plan:
### Test Locally

- iOS

```bash
yarn install
cd packages/rn-tester
yarn e2e-build-ios
```

- Android

```bash
yarn install
cd packages/rn-tester
yarn e2e-build-android
```

### Start Maestro

- iOS

```bash
 cd packages/rn-tester
 yarn e2e-test-ios
```

- Android

```
cd packages/rn-tester
yarn e2e-test-android
```

### Test in CI

To test in CI, just add a comment on your PR with the text:

```
/test-e2e
```

Reviewed By: cortinico

Differential Revision: D63829274

Pulled By: cipolleschi

fbshipit-source-id: f7b4342ed353a48123f87dcfd8d503009f65637c
2024-10-31 04:33:13 -07:00
hexboy 9a3958a619 fix(Android, iOS): Fix AnsiHighlight Style in RTL Layout (#47230)
Summary:
This pull request fixes a style bug in the AnsiHighlight component when the application is in Right-To-Left (RTL) mode. The adjustments ensure that text highlighting is visually consistent and functions properly across all layout modes.

### Before
| Android RTL | iOS RTL | Android LTR | iOS LTR |
|----------|----------|----------|----------|
|  ![Before-RTL-Android](https://github.com/user-attachments/assets/059e30e7-f6da-4a07-9c91-08d952c6a4b6) | ![Before-RTL-iOS](https://github.com/user-attachments/assets/a325c838-1510-4415-bd1f-c419ce75e7e2) | ![Before-LTR-Android](https://github.com/user-attachments/assets/26494fb1-71dd-4fae-a75c-381eead211de)  | ![Before-LTR-iOS](https://github.com/user-attachments/assets/72bba2d8-f70f-4e16-b771-4af995370d26) |

### After
| Android RTL | iOS RTL | Android LTR | iOS LTR |
|----------|----------|----------|----------|
| ![After-RTL-Android](https://github.com/user-attachments/assets/d2f674c2-7aec-454f-903a-33fcd3e93240) | ![After-RTL-iOS](https://github.com/user-attachments/assets/e3735e79-7323-48e8-8213-f0871bec0ca5) | ![After-LTR-Android](https://github.com/user-attachments/assets/18c80754-8743-4282-8f95-1e9772d51a36) | ![After-LTR-iOS](https://github.com/user-attachments/assets/068f4bd8-df4e-420b-8949-c20dff9c2bc8) |

## Changelog:
[GENERAL] [Fixed] - AnsiHighlight style in RTL layout

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

Pick one each for the category and type tags:

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

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

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

Test Plan:
To test the changes, open LogBox while the app is in RTL mode. The modifications ensure that any error messages display correctly. I have verified that the changes function properly in both LTR and RTL modes, and all existing functionality remains unaffected.

This is an example component to throw an error to show LogBox.

```tsx
import React from 'react';
import {Alert, Button, I18nManager, StyleSheet, Text, View} from 'react-native';

function SampleError() {
  return (
    <View>
      <Button
        title="Change to RTL"
        onPress={() => {
          I18nManager.allowRTL(true);
          I18nManager.forceRTL(true);
          Alert.alert('Restart app to apply changes');
        }}
      />
      <Button
        title="Change to LTR"
        onPress={() => {
          I18nManager.allowRTL(false);
          I18nManager.forceRTL(false);
          Alert.alert('Restart app to apply changes');
        }}
      />

      <Text style={styles.text}>
        isRTL: {I18nManager.isRTL ? 'true' : 'false'}
      </Text>

      <Button
        title="Show Error"
        onPress={() => {
          console.error('sample خطا');
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  text: {
    fontSize: 24,
    textAlign: 'center',
    paddingVertical: 20,
  },
});

export default SampleError;
```

Reviewed By: sammy-SC

Differential Revision: D65145991

Pulled By: NickGerleman

fbshipit-source-id: cbca106813e587ed223be48b75ee5279072c2da0
2024-10-31 01:32:39 -07:00
Phillip Pan 4d90f84869 clean up unused callsites to contextContainer->at (#47322)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47322

Changelog: [Internal]

these callsites were causing crashes in new bridgeless integrations, it appears they are not used, so cleaning up. after this, we can remove all callsites that insert ReactNativeConfig to the contextContainer.

Reviewed By: javache

Differential Revision: D65191733

fbshipit-source-id: 94e694ef27249773c2a39bd77f316f8f5cc2b1fb
2024-10-31 00:56:21 -07:00
Phillip Pan 3a68f14ac2 cleanup enabled_automatic_interop_android (#47321)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47321

Changelog: [Internal]

this seems to be the last callsite where we read the ReactNativeConfig from the contextContainer. i don't think this killswitch should block cleanup of the ReactNativeConfig, so maybe we can just remove this?

Reviewed By: cortinico

Differential Revision: D65192744

fbshipit-source-id: d8b595edb6fecce05e67abc257d98805daa16a9a
2024-10-31 00:56:21 -07:00
147 changed files with 63587 additions and 45077 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ runs:
using: "composite"
steps:
- name: Setup gradle
uses: gradle/actions/setup-gradle@v3
uses: gradle/actions/setup-gradle@v4
with:
gradle-version: wrapper
# We want the Gradle cache to be written only on main/-stable branches run, and only for jobs with `cache-read-only` == false (i.e. `build_android`).
@@ -1,13 +0,0 @@
name: "Validate Gradle Wrapper"
on:
push:
pull_request:
jobs:
validation:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: gradle/actions/wrapper-validation@v3
+2 -5
View File
@@ -93,16 +93,13 @@
"nullthrows": "^1.1.1",
"prettier": "2.8.8",
"prettier-plugin-hermes-parser": "0.24.0",
"react": "19.0.0-rc-fb9a90fa48-20240614",
"react-test-renderer": "19.0.0-rc-fb9a90fa48-20240614",
"react": "18.3.1",
"react-test-renderer": "18.3.1",
"rimraf": "^3.0.2",
"shelljs": "^0.8.5",
"signedsource": "^1.0.0",
"supports-color": "^7.1.0",
"typescript": "5.0.4",
"ws": "^6.2.3"
},
"resolutions": {
"react-is": "19.0.0-rc-fb9a90fa48-20240614"
}
}
+2 -2
View File
@@ -39,7 +39,7 @@ module.exports = {
overrides: [
{
files: ['*.js'],
parser: 'hermes-eslint',
parser: '@babel/eslint-parser',
plugins: ['ft-flow'],
rules: {
// Flow Plugin
@@ -51,7 +51,7 @@ module.exports = {
},
{
files: ['*.jsx'],
parser: 'hermes-eslint',
parser: '@babel/eslint-parser',
},
{
files: ['*.ts', '*.tsx'],
@@ -21,6 +21,7 @@
"main": "index.js",
"dependencies": {
"@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.25.1",
"@react-native/eslint-plugin": "0.77.0-main",
"@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1",
@@ -30,8 +31,7 @@
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-native": "^4.0.0",
"hermes-eslint": "0.24.0"
"eslint-plugin-react-native": "^4.0.0"
},
"peerDependencies": {
"eslint": ">=8",
@@ -1,5 +1,5 @@
[versions]
agp = "8.7.1"
agp = "8.7.2"
gson = "2.8.9"
guava = "31.0.1-jre"
javapoet = "1.13.0"
@@ -59,15 +59,15 @@ abstract class GenerateAutolinkingNewArchitecturesFileTask : DefaultTask() {
val cxxModuleCMakeListsPath = dep.cxxModuleCMakeListsPath
if (libraryName != null && cmakeListsPath != null) {
// If user provided a custom cmakeListsPath, let's honor it.
val nativeFolderPath = cmakeListsPath.replace("CMakeLists.txt", "")
val nativeFolderPath = sanitizeCmakeListsPath(cmakeListsPath)
addDirectoryString +=
"add_subdirectory($nativeFolderPath ${libraryName}_autolinked_build)"
"add_subdirectory(\"$nativeFolderPath\" ${libraryName}_autolinked_build)"
}
if (cxxModuleCMakeListsPath != null) {
// If user provided a custom cxxModuleCMakeListsPath, let's honor it.
val nativeFolderPath = cxxModuleCMakeListsPath.replace("CMakeLists.txt", "")
val nativeFolderPath = sanitizeCmakeListsPath(cxxModuleCMakeListsPath)
addDirectoryString +=
"\nadd_subdirectory($nativeFolderPath ${libraryName}_cxxmodule_autolinked_build)"
"\nadd_subdirectory(\"$nativeFolderPath\" ${libraryName}_cxxmodule_autolinked_build)"
}
addDirectoryString
}
@@ -159,6 +159,9 @@ abstract class GenerateAutolinkingNewArchitecturesFileTask : DefaultTask() {
const val COMPONENT_DESCRIPTOR_FILENAME = "ComponentDescriptors.h"
const val COMPONENT_INCLUDE_PATH = "react/renderer/components"
internal fun sanitizeCmakeListsPath(cmakeListsPath: String): String =
cmakeListsPath.replace("CMakeLists.txt", "").replace(" ", "\\ ")
// language=cmake
val CMAKE_TEMPLATE =
"""
@@ -53,11 +53,8 @@ internal object NdkConfiguratorUtils {
if (cmakeArgs.none { it.startsWith("-DANDROID_STL") }) {
cmakeArgs.add("-DANDROID_STL=c++_shared")
}
// Due to the new NDK toolchain file, the C++ flags gets overridden between compilation
// units. This is causing some libraries to don't be compiled with -DANDROID and other
// crucial flags. This can be revisited once we bump to NDK 25/26
if (cmakeArgs.none { it.startsWith("-DANDROID_USE_LEGACY_TOOLCHAIN_FILE") }) {
cmakeArgs.add("-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON")
if (cmakeArgs.none { it.startsWith("-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES") }) {
cmakeArgs.add("-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON")
}
val architectures = project.getReactNativeArchitectures()
@@ -11,6 +11,7 @@ import com.facebook.react.model.ModelAutolinkingConfigJson
import com.facebook.react.model.ModelAutolinkingDependenciesJson
import com.facebook.react.model.ModelAutolinkingDependenciesPlatformAndroidJson
import com.facebook.react.model.ModelAutolinkingDependenciesPlatformJson
import com.facebook.react.tasks.GenerateAutolinkingNewArchitecturesFileTask.Companion.sanitizeCmakeListsPath
import com.facebook.react.tests.createTestTask
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
@@ -145,9 +146,9 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
# or link against a old prefab target (this is needed for React Native 0.76 on).
set(REACTNATIVE_MERGED_SO true)
add_subdirectory(./a/directory/ aPackage_autolinked_build)
add_subdirectory(./another/directory/ anotherPackage_autolinked_build)
add_subdirectory(./another/directory/cxx/ anotherPackage_cxxmodule_autolinked_build)
add_subdirectory("./a/directory/" aPackage_autolinked_build)
add_subdirectory("./another/directory/with\ spaces/" anotherPackage_autolinked_build)
add_subdirectory("./another/directory/cxx/" anotherPackage_cxxmodule_autolinked_build)
set(AUTOLINKED_LIBRARIES
react_codegen_aPackage
@@ -258,6 +259,24 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
.trimIndent())
}
@Test
fun sanitizeCmakeListsPath_withPathEndingWithFileName_removesFilename() {
val input = "./a/directory/CMakeLists.txt"
assertThat(sanitizeCmakeListsPath(input)).isEqualTo("./a/directory/")
}
@Test
fun sanitizeCmakeListsPath_withSpaces_removesSpaces() {
val input = "./a/dir ectory/with spaces/"
assertThat(sanitizeCmakeListsPath(input)).isEqualTo("./a/dir\\ ectory/with\\ spaces/")
}
@Test
fun sanitizeCmakeListsPath_withPathEndingWithFileNameAndSpaces_sanitizesIt() {
val input = "./a/dir ectory/CMakeLists.txt"
assertThat(sanitizeCmakeListsPath(input)).isEqualTo("./a/dir\\ ectory/")
}
private val testDependencies =
listOf(
ModelAutolinkingDependenciesPlatformAndroidJson(
@@ -276,7 +295,7 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
buildTypes = emptyList(),
libraryName = "anotherPackage",
componentDescriptors = listOf("AnotherPackageComponentDescriptor"),
cmakeListsPath = "./another/directory/CMakeLists.txt",
cmakeListsPath = "./another/directory/with spaces/CMakeLists.txt",
cxxModuleCMakeListsPath = "./another/directory/cxx/CMakeLists.txt",
cxxModuleHeaderName = "AnotherCxxModule",
cxxModuleCMakeListsModuleName = "another_cxxModule",
+2 -2
View File
@@ -12,7 +12,7 @@
"test": "jest"
},
"dependencies": {
"react": "19.0.0-rc-fb9a90fa48-20240614",
"react": "18.3.1",
"react-native": "1000.0.0"
},
"devDependencies": {
@@ -28,7 +28,7 @@
"eslint": "^8.19.0",
"jest": "^29.6.3",
"listr2": "^8.2.1",
"react-test-renderer": "19.0.0-rc-fb9a90fa48-20240614",
"react-test-renderer": "18.3.1",
"rxjs": "^7.8.1"
},
"engines": {
+10 -3
View File
@@ -286,6 +286,11 @@ export interface UnsafeAnyTypeAnnotation {
readonly type: 'AnyTypeAnnotation',
}
export interface NativeModuleNumberLiteralTypeAnnotation {
readonly type: 'NumberLiteralTypeAnnotation';
readonly value: number;
}
export interface NativeModuleStringTypeAnnotation {
readonly type: 'StringTypeAnnotation';
}
@@ -320,10 +325,10 @@ export interface NativeModuleBooleanTypeAnnotation {
readonly type: 'BooleanTypeAnnotation';
}
export type NativeModuleEnumMembers = readonly {
export type NativeModuleEnumMember = {
readonly name: string;
readonly value: string | number;
}[];
};
export type NativeModuleEnumMemberType =
| 'NumberTypeAnnotation'
@@ -339,7 +344,7 @@ export interface NativeModuleEnumDeclarationWithMembers {
name: string;
type: 'EnumDeclarationWithMembers';
memberType: NativeModuleEnumMemberType;
members: NativeModuleEnumMembers;
members: readonly NativeModuleEnumMember[];
}
export interface NativeModuleGenericObjectTypeAnnotation {
@@ -380,6 +385,7 @@ export type NativeModuleEventEmitterBaseTypeAnnotation =
| NativeModuleFloatTypeAnnotation
| NativeModuleInt32TypeAnnotation
| NativeModuleNumberTypeAnnotation
| NativeModuleNumberLiteralTypeAnnotation
| NativeModuleStringTypeAnnotation
| NativeModuleStringLiteralTypeAnnotation
| NativeModuleStringLiteralUnionTypeAnnotation
@@ -399,6 +405,7 @@ export type NativeModuleBaseTypeAnnotation =
| NativeModuleStringLiteralTypeAnnotation
| NativeModuleStringLiteralUnionTypeAnnotation
| NativeModuleNumberTypeAnnotation
| NativeModuleNumberLiteralTypeAnnotation
| NativeModuleInt32TypeAnnotation
| NativeModuleDoubleTypeAnnotation
| NativeModuleFloatTypeAnnotation
+12 -7
View File
@@ -37,6 +37,11 @@ export type Int32TypeAnnotation = $ReadOnly<{
type: 'Int32TypeAnnotation',
}>;
export type NumberLiteralTypeAnnotation = $ReadOnly<{
type: 'NumberLiteralTypeAnnotation',
value: number,
}>;
export type StringTypeAnnotation = $ReadOnly<{
type: 'StringTypeAnnotation',
}>;
@@ -304,12 +309,10 @@ export type NativeModuleNumberTypeAnnotation = $ReadOnly<{
type: 'NumberTypeAnnotation',
}>;
export type NativeModuleEnumMembers = $ReadOnlyArray<
$ReadOnly<{
name: string,
value: string | number,
}>,
>;
export type NativeModuleEnumMember = {
name: string,
value: string | number,
};
export type NativeModuleEnumMemberType =
| 'NumberTypeAnnotation'
@@ -325,7 +328,7 @@ export type NativeModuleEnumDeclarationWithMembers = {
name: string,
type: 'EnumDeclarationWithMembers',
memberType: NativeModuleEnumMemberType,
members: NativeModuleEnumMembers,
members: $ReadOnlyArray<NativeModuleEnumMember>,
};
export type NativeModuleGenericObjectTypeAnnotation = $ReadOnly<{
@@ -366,6 +369,7 @@ type NativeModuleEventEmitterBaseTypeAnnotation =
| FloatTypeAnnotation
| Int32TypeAnnotation
| NativeModuleNumberTypeAnnotation
| NumberLiteralTypeAnnotation
| StringTypeAnnotation
| StringLiteralTypeAnnotation
| StringLiteralUnionTypeAnnotation
@@ -385,6 +389,7 @@ export type NativeModuleBaseTypeAnnotation =
| StringLiteralTypeAnnotation
| StringLiteralUnionTypeAnnotation
| NativeModuleNumberTypeAnnotation
| NumberLiteralTypeAnnotation
| Int32TypeAnnotation
| DoubleTypeAnnotation
| FloatTypeAnnotation
@@ -186,6 +186,8 @@ function serializeArg(
return wrap(val => `${val}.asNumber()`);
case 'Int32TypeAnnotation':
return wrap(val => `${val}.asNumber()`);
case 'NumberLiteralTypeAnnotation':
return wrap(val => `${val}.asNumber()`);
case 'ArrayTypeAnnotation':
return wrap(val => `${val}.asObject(rt).asArray(rt)`);
case 'FunctionTypeAnnotation':
@@ -16,7 +16,7 @@ import type {
import type {
NativeModuleAliasMap,
NativeModuleEnumMap,
NativeModuleEnumMembers,
NativeModuleEnumMember,
NativeModuleEnumMemberType,
NativeModuleEventEmitterShape,
NativeModuleFunctionTypeAnnotation,
@@ -179,6 +179,8 @@ function translatePrimitiveJSTypeToCpp(
return wrapOptional('jsi::String', isRequired);
case 'NumberTypeAnnotation':
return wrapOptional('double', isRequired);
case 'NumberLiteralTypeAnnotation':
return wrapOptional('double', isRequired);
case 'DoubleTypeAnnotation':
return wrapOptional('double', isRequired);
case 'FloatTypeAnnotation':
@@ -407,7 +409,7 @@ struct Bridging<${enumName}> {
function generateEnum(
hasteModuleName: string,
origEnumName: string,
members: NativeModuleEnumMembers,
members: $ReadOnlyArray<NativeModuleEnumMember>,
memberType: NativeModuleEnumMemberType,
): string {
const enumName = getEnumName(hasteModuleName, origEnumName);
@@ -136,6 +136,7 @@ function translateEventEmitterTypeToJavaType(
case 'StringLiteralUnionTypeAnnotation':
return 'String';
case 'NumberTypeAnnotation':
case 'NumberLiteralTypeAnnotation':
case 'FloatTypeAnnotation':
case 'DoubleTypeAnnotation':
case 'Int32TypeAnnotation':
@@ -203,6 +204,8 @@ function translateFunctionParamToJavaType(
return wrapOptional('String', isRequired);
case 'NumberTypeAnnotation':
return wrapOptional('double', isRequired);
case 'NumberLiteralTypeAnnotation':
return wrapOptional('double', isRequired);
case 'FloatTypeAnnotation':
return wrapOptional('double', isRequired);
case 'DoubleTypeAnnotation':
@@ -297,6 +300,8 @@ function translateFunctionReturnTypeToJavaType(
return wrapOptional('String', isRequired);
case 'NumberTypeAnnotation':
return wrapOptional('double', isRequired);
case 'NumberLiteralTypeAnnotation':
return wrapOptional('double', isRequired);
case 'FloatTypeAnnotation':
return wrapOptional('double', isRequired);
case 'DoubleTypeAnnotation':
@@ -373,6 +378,8 @@ function getFalsyReturnStatementFromReturnType(
return '';
case 'NumberTypeAnnotation':
return nullable ? 'return null;' : 'return 0;';
case 'NumberLiteralTypeAnnotation':
return nullable ? 'return null;' : 'return 0;';
case 'FloatTypeAnnotation':
return nullable ? 'return null;' : 'return 0.0;';
case 'DoubleTypeAnnotation':
@@ -197,6 +197,8 @@ function translateReturnTypeToKind(
}
case 'NumberTypeAnnotation':
return 'NumberKind';
case 'NumberLiteralTypeAnnotation':
return 'NumberKind';
case 'DoubleTypeAnnotation':
return 'NumberKind';
case 'FloatTypeAnnotation':
@@ -280,6 +282,8 @@ function translateParamTypeToJniType(
}
case 'NumberTypeAnnotation':
return !isRequired ? 'Ljava/lang/Double;' : 'D';
case 'NumberLiteralTypeAnnotation':
return !isRequired ? 'Ljava/lang/Double;' : 'D';
case 'DoubleTypeAnnotation':
return !isRequired ? 'Ljava/lang/Double;' : 'D';
case 'FloatTypeAnnotation':
@@ -360,6 +364,8 @@ function translateReturnTypeToJniType(
}
case 'NumberTypeAnnotation':
return nullable ? 'Ljava/lang/Double;' : 'D';
case 'NumberLiteralTypeAnnotation':
return nullable ? 'Ljava/lang/Double;' : 'D';
case 'DoubleTypeAnnotation':
return nullable ? 'Ljava/lang/Double;' : 'D';
case 'FloatTypeAnnotation':
@@ -23,6 +23,7 @@ import type {
NativeModuleObjectTypeAnnotation,
NativeModuleTypeAliasTypeAnnotation,
Nullable,
NumberLiteralTypeAnnotation,
ReservedTypeAnnotation,
StringLiteralTypeAnnotation,
StringLiteralUnionTypeAnnotation,
@@ -63,6 +64,7 @@ export type StructTypeAnnotation =
| StringLiteralTypeAnnotation
| StringLiteralUnionTypeAnnotation
| NativeModuleNumberTypeAnnotation
| NumberLiteralTypeAnnotation
| Int32TypeAnnotation
| DoubleTypeAnnotation
| FloatTypeAnnotation
@@ -100,6 +100,8 @@ function toObjCType(
return 'NSString *';
case 'NumberTypeAnnotation':
return wrapCxxOptional('double', isRequired);
case 'NumberLiteralTypeAnnotation':
return wrapCxxOptional('double', isRequired);
case 'FloatTypeAnnotation':
return wrapCxxOptional('double', isRequired);
case 'Int32TypeAnnotation':
@@ -183,6 +185,8 @@ function toObjCValue(
return value;
case 'NumberTypeAnnotation':
return wrapPrimitive('double');
case 'NumberLiteralTypeAnnotation':
return wrapPrimitive('double');
case 'FloatTypeAnnotation':
return wrapPrimitive('double');
case 'Int32TypeAnnotation':
@@ -91,6 +91,8 @@ function toObjCType(
return 'NSString *';
case 'NumberTypeAnnotation':
return wrapCxxOptional('double', isRequired);
case 'NumberLiteralTypeAnnotation':
return wrapCxxOptional('double', isRequired);
case 'FloatTypeAnnotation':
return wrapCxxOptional('double', isRequired);
case 'Int32TypeAnnotation':
@@ -173,6 +175,8 @@ function toObjCValue(
return RCTBridgingTo('String');
case 'NumberTypeAnnotation':
return RCTBridgingTo('Double');
case 'NumberLiteralTypeAnnotation':
return RCTBridgingTo('Double');
case 'FloatTypeAnnotation':
return RCTBridgingTo('Double');
case 'Int32TypeAnnotation':
@@ -25,6 +25,7 @@ function getEventEmitterTypeObjCType(
case 'StringLiteralUnionTypeAnnotation':
return 'NSString *_Nonnull';
case 'NumberTypeAnnotation':
case 'NumberLiteralTypeAnnotation':
return 'NSNumber *_Nonnull';
case 'BooleanTypeAnnotation':
return 'BOOL';
@@ -263,6 +263,8 @@ function getParamObjCType(
return notStruct(wrapOptional('NSString *', !nullable));
case 'NumberTypeAnnotation':
return notStruct(isRequired ? 'double' : 'NSNumber *');
case 'NumberLiteralTypeAnnotation':
return notStruct(isRequired ? 'double' : 'NSNumber *');
case 'FloatTypeAnnotation':
return notStruct(isRequired ? 'float' : 'NSNumber *');
case 'DoubleTypeAnnotation':
@@ -344,6 +346,8 @@ function getReturnObjCType(
return wrapOptional('NSString *', isRequired);
case 'NumberTypeAnnotation':
return wrapOptional('NSNumber *', isRequired);
case 'NumberLiteralTypeAnnotation':
return wrapOptional('NSNumber *', isRequired);
case 'FloatTypeAnnotation':
return wrapOptional('NSNumber *', isRequired);
case 'DoubleTypeAnnotation':
@@ -414,6 +418,8 @@ function getReturnJSType(
return 'StringKind';
case 'NumberTypeAnnotation':
return 'NumberKind';
case 'NumberLiteralTypeAnnotation':
return 'NumberKind';
case 'FloatTypeAnnotation':
return 'NumberKind';
case 'DoubleTypeAnnotation':
@@ -126,6 +126,7 @@ import * as TurboModuleRegistry from '../TurboModuleRegistry';
export interface Spec extends TurboModule {
+passBool?: (arg: boolean) => void;
+passNumber: (arg: number) => void;
+passNumberLiteral: (arg: 4) => void;
+passString: (arg: string) => void;
+passStringish: (arg: Stringish) => void;
+passStringLiteral: (arg: 'A String Literal') => void;
@@ -978,6 +978,26 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_BASIC_PA
]
}
},
{
'name': 'passNumberLiteral',
'optional': false,
'typeAnnotation': {
'type': 'FunctionTypeAnnotation',
'returnTypeAnnotation': {
'type': 'VoidTypeAnnotation'
},
'params': [
{
'name': 'arg',
'optional': false,
'typeAnnotation': {
'type': 'NumberLiteralTypeAnnotation',
'value': 4
}
}
]
}
},
{
'name': 'passString',
'optional': false,
@@ -38,6 +38,7 @@ const {
emitCommonTypes,
emitDictionary,
emitFunction,
emitNumberLiteral,
emitPromise,
emitRootTag,
emitUnion,
@@ -243,6 +244,9 @@ function translateTypeAnnotation(
case 'UnionTypeAnnotation': {
return emitUnion(nullable, hasteModuleName, typeAnnotation, parser);
}
case 'NumberLiteralTypeAnnotation': {
return emitNumberLiteral(nullable, typeAnnotation.value);
}
case 'StringLiteralTypeAnnotation': {
return wrapNullable(nullable, {
type: 'StringLiteralTypeAnnotation',
+4 -2
View File
@@ -15,7 +15,7 @@ import type {
NamedShape,
NativeModuleAliasMap,
NativeModuleEnumMap,
NativeModuleEnumMembers,
NativeModuleEnumMember,
NativeModuleEnumMemberType,
NativeModuleParamTypeAnnotation,
Nullable,
@@ -227,7 +227,9 @@ class FlowParser implements Parser {
});
}
parseEnumMembers(typeAnnotation: $FlowFixMe): NativeModuleEnumMembers {
parseEnumMembers(
typeAnnotation: $FlowFixMe,
): $ReadOnlyArray<NativeModuleEnumMember> {
return typeAnnotation.members.map(member => ({
name: member.id.name,
value: member.init?.value ?? member.id.name,
+4 -2
View File
@@ -15,7 +15,7 @@ import type {
NamedShape,
NativeModuleAliasMap,
NativeModuleEnumMap,
NativeModuleEnumMembers,
NativeModuleEnumMember,
NativeModuleEnumMemberType,
NativeModuleParamTypeAnnotation,
Nullable,
@@ -240,7 +240,9 @@ export interface Parser {
/**
* Calculates enum's members
*/
parseEnumMembers(typeAnnotation: $FlowFixMe): NativeModuleEnumMembers;
parseEnumMembers(
typeAnnotation: $FlowFixMe,
): $ReadOnlyArray<NativeModuleEnumMember>;
/**
* Given a node, it returns true if it is a module interface
+4 -2
View File
@@ -15,7 +15,7 @@ import type {
NamedShape,
NativeModuleAliasMap,
NativeModuleEnumMap,
NativeModuleEnumMembers,
NativeModuleEnumMember,
NativeModuleEnumMemberType,
NativeModuleParamTypeAnnotation,
Nullable,
@@ -168,7 +168,9 @@ export class MockedParser implements Parser {
return;
}
parseEnumMembers(typeAnnotation: $FlowFixMe): NativeModuleEnumMembers {
parseEnumMembers(
typeAnnotation: $FlowFixMe,
): $ReadOnlyArray<NativeModuleEnumMember> {
return typeAnnotation.type === 'StringTypeAnnotation'
? [
{
@@ -31,6 +31,7 @@ import type {
NativeModuleTypeAnnotation,
NativeModuleUnionTypeAnnotation,
Nullable,
NumberLiteralTypeAnnotation,
ObjectTypeAnnotation,
ReservedTypeAnnotation,
StringLiteralTypeAnnotation,
@@ -170,6 +171,16 @@ function emitMixed(
});
}
function emitNumberLiteral(
nullable: boolean,
value: number,
): Nullable<NumberLiteralTypeAnnotation> {
return wrapNullable(nullable, {
type: 'NumberLiteralTypeAnnotation',
value,
});
}
function emitString(nullable: boolean): Nullable<StringTypeAnnotation> {
return wrapNullable(nullable, {
type: 'StringTypeAnnotation',
@@ -762,6 +773,7 @@ module.exports = {
emitInt32Prop,
emitMixedProp,
emitNumber,
emitNumberLiteral,
emitGenericObject,
emitDictionary,
emitObject,
@@ -113,6 +113,7 @@ import * as TurboModuleRegistry from '../TurboModuleRegistry';
export interface Spec extends TurboModule {
readonly passBool?: (arg: boolean) => void;
readonly passNumber: (arg: number) => void;
readonly passNumberLiteral: (arg: 4) => void;
readonly passString: (arg: string) => void;
readonly passStringish: (arg: Stringish) => void;
readonly passStringLiteral: (arg: 'A String Literal') => void;
@@ -1123,6 +1123,26 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_BA
]
}
},
{
'name': 'passNumberLiteral',
'optional': false,
'typeAnnotation': {
'type': 'FunctionTypeAnnotation',
'returnTypeAnnotation': {
'type': 'VoidTypeAnnotation'
},
'params': [
{
'name': 'arg',
'optional': false,
'typeAnnotation': {
'type': 'NumberLiteralTypeAnnotation',
'value': 4
}
}
]
}
},
{
'name': 'passString',
'optional': false,
@@ -37,6 +37,7 @@ const {
emitCommonTypes,
emitDictionary,
emitFunction,
emitNumberLiteral,
emitPromise,
emitRootTag,
emitStringLiteral,
@@ -403,6 +404,9 @@ function translateTypeAnnotation(
case 'StringLiteral': {
return emitStringLiteral(nullable, literal.value);
}
case 'NumericLiteral': {
return emitNumberLiteral(nullable, literal.value);
}
default: {
throw new UnsupportedTypeAnnotationParserError(
hasteModuleName,
@@ -15,7 +15,7 @@ import type {
NamedShape,
NativeModuleAliasMap,
NativeModuleEnumMap,
NativeModuleEnumMembers,
NativeModuleEnumMember,
NativeModuleEnumMemberType,
NativeModuleParamTypeAnnotation,
Nullable,
@@ -223,7 +223,9 @@ class TypeScriptParser implements Parser {
});
}
parseEnumMembers(typeAnnotation: $FlowFixMe): NativeModuleEnumMembers {
parseEnumMembers(
typeAnnotation: $FlowFixMe,
): $ReadOnlyArray<NativeModuleEnumMember> {
return typeAnnotation.members.map(member => ({
name: member.id.name,
value: member.initializer?.value ?? member.id.name,
@@ -16,5 +16,5 @@ import * as React from 'react';
export default (createAnimatedComponent(FlatList): AnimatedComponentType<
React.ElementConfig<typeof FlatList>,
React.ElementRef<typeof FlatList>,
FlatList<mixed>,
>);
@@ -55,6 +55,7 @@ const EventNames: Map<
['highTextContrastChanged', 'highTextContrastDidChange'],
['screenReaderChanged', 'touchExplorationDidChange'],
['accessibilityServiceChanged', 'accessibilityServiceDidChange'],
['invertColorsChanged', 'invertColorDidChange'],
])
: new Map([
['announcementFinished', 'announcementFinished'],
@@ -138,7 +139,13 @@ const AccessibilityInfo = {
*/
isInvertColorsEnabled(): Promise<boolean> {
if (Platform.OS === 'android') {
return Promise.resolve(false);
return new Promise((resolve, reject) => {
if (NativeAccessibilityInfoAndroid?.isInvertColorsEnabled != null) {
NativeAccessibilityInfoAndroid.isInvertColorsEnabled(resolve);
} else {
reject(null);
}
});
} else {
return new Promise((resolve, reject) => {
if (NativeAccessibilityManagerIOS != null) {
+1 -1
View File
@@ -51,7 +51,7 @@ export interface ImageURISource {
* to a URL load request, no attempt is made to load the data from the originating source,
* and the load is considered to have failed.
*
* @platform ios
* @platform ios (for `force-cache`)
*/
cache?: 'default' | 'reload' | 'force-cache' | 'only-if-cached' | undefined;
/**
+1 -1
View File
@@ -66,7 +66,7 @@ export interface ImageURISource {
* to a URL load request, no attempt is made to load the data from the originating source,
* and the load is considered to have failed.
*
* @platform ios
* @platform ios (for `force-cache`)
*/
+cache?: ?('default' | 'reload' | 'force-cache' | 'only-if-cached');
@@ -477,7 +477,10 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image, CGSize size, CGFloat scal
// Add missing png extension
if (request.URL.fileURL && request.URL.pathExtension.length == 0) {
mutableRequest.URL = [request.URL URLByAppendingPathExtension:@"png"];
NSURL *pngRequestURL = [request.URL URLByAppendingPathExtension:@"png"];
if ([[NSFileManager defaultManager] fileExistsAtPath:pngRequestURL.path]) {
mutableRequest.URL = pngRequestURL;
}
}
if (_redirectDelegate != nil) {
mutableRequest.URL = [_redirectDelegate redirectAssetsURL:mutableRequest.URL];
+2 -2
View File
@@ -480,10 +480,10 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
this._checkProps(this.props);
}
_listRef: ?React.ElementRef<typeof VirtualizedList>;
_listRef: ?VirtualizedList;
_virtualizedListPairs: Array<ViewabilityConfigCallbackPair> = [];
_captureRef = (ref: ?React.ElementRef<typeof VirtualizedList>) => {
_captureRef = (ref: ?VirtualizedList) => {
this._listRef = ref;
};
+26 -17
View File
@@ -37,6 +37,8 @@ const COLORS = {
'ansi-bright-white': 'rgb(247, 247, 247)',
};
const LRM = '\u200E'; // Left-to-Right Mark
export default function Ansi({
text,
style,
@@ -80,25 +82,28 @@ export default function Ansi({
};
return (
<View>
<View style={styles.container}>
{parsedLines.map((items, i) => (
<View style={styles.line} key={i}>
{items.map((bundle, key) => {
const textStyle =
bundle.fg && COLORS[bundle.fg]
? {
backgroundColor: bundle.bg && COLORS[bundle.bg],
color: bundle.fg && COLORS[bundle.fg],
}
: {
backgroundColor: bundle.bg && COLORS[bundle.bg],
};
return (
<Text style={[style, textStyle]} key={key}>
{getText(bundle.content, key)}
</Text>
);
})}
<Text>
{LRM}
{items.map((bundle, key) => {
const textStyle =
bundle.fg && COLORS[bundle.fg]
? {
backgroundColor: bundle.bg && COLORS[bundle.bg],
color: bundle.fg && COLORS[bundle.fg],
}
: {
backgroundColor: bundle.bg && COLORS[bundle.bg],
};
return (
<Text style={[style, textStyle]} key={key}>
{getText(bundle.content, key)}
</Text>
);
})}
</Text>
</View>
))}
</View>
@@ -106,6 +111,10 @@ export default function Ansi({
}
const styles = StyleSheet.create({
container: {
minWidth: '100%',
direction: 'ltr',
},
line: {
flexDirection: 'row',
},
@@ -59,7 +59,9 @@ function LogBoxInspectorCodeFrame(props: Props): React.Node {
<LogBoxInspectorSection heading="Source" action={<AppInfo />}>
<View style={styles.box}>
<View style={styles.frame}>
<ScrollView horizontal>
<ScrollView
horizontal
contentContainerStyle={styles.contentContainer}>
<AnsiHighlight style={styles.content} text={codeFrame.content} />
</ScrollView>
</View>
@@ -138,6 +140,9 @@ const styles = StyleSheet.create({
paddingTop: 10,
paddingBottom: 10,
},
contentContainer: {
minWidth: '100%',
},
content: {
color: LogBoxStyle.getTextColor(1),
fontSize: 12,
@@ -26,6 +26,11 @@ exports[`LogBoxInspectorCodeFrame should render a code frame 1`] = `
}
>
<ScrollView
contentContainerStyle={
Object {
"minWidth": "100%",
}
}
horizontal={true}
>
<Ansi
@@ -108,6 +113,11 @@ exports[`LogBoxInspectorCodeFrame should render a code frame without a location
}
>
<ScrollView
contentContainerStyle={
Object {
"minWidth": "100%",
}
}
horizontal={true}
>
<Ansi
@@ -80,7 +80,7 @@ describe('LogBox', () => {
expect(mockWarn).not.toBeCalled();
expect(console.error).toBeCalledTimes(1);
expect(console.error.mock.calls[0]).toEqual([
'Each child in a list should have a unique "key" prop.%s%s See https://react.dev/link/warning-keys for more information.%s',
'Warning: Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.%s',
'\n\nCheck the render method of `DoesNotUseKey`.',
'',
expect.stringMatching('at DoesNotUseKey'),
@@ -94,7 +94,7 @@ describe('LogBox', () => {
componentStackType: 'stack',
message: {
content:
'Warning: Each child in a list should have a unique "key" prop.\n\nCheck the render method of `DoesNotUseKey`. See https://react.dev/link/warning-keys for more information.',
'Warning: Each child in a list should have a unique "key" prop.\n\nCheck the render method of `DoesNotUseKey`. See https://reactjs.org/link/warning-keys for more information.',
substitutions: [
{length: 45, offset: 62},
{length: 0, offset: 107},
@@ -106,7 +106,7 @@ describe('LogBox', () => {
// We also interpolate the string before passing to the underlying console method.
expect(mockError.mock.calls[0]).toEqual([
expect.stringMatching(
'Warning: Each child in a list should have a unique "key" prop.\n\nCheck the render method of `DoesNotUseKey`. See https://react.dev/link/warning-keys for more information.\n at ',
'Warning: Each child in a list should have a unique "key" prop.\n\nCheck the render method of `DoesNotUseKey`. See https://reactjs.org/link/warning-keys for more information.\n at ',
),
]);
});
@@ -134,7 +134,7 @@ describe('LogBox', () => {
expect(mockWarn).not.toBeCalled();
expect(console.error).toBeCalledTimes(1);
expect(console.error.mock.calls[0]).toEqual([
'Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.%s',
'Warning: Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.%s',
'invalid',
expect.stringMatching('at FragmentWithProp'),
]);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -683,7 +683,7 @@ exports[`public API should not change unintentionally Libraries/Animated/bezier.
exports[`public API should not change unintentionally Libraries/Animated/components/AnimatedFlatList.js 1`] = `
"declare export default AnimatedComponentType<
React.ElementConfig<typeof FlatList>,
React.ElementRef<typeof FlatList>,
FlatList<mixed>,
>;
"
`;
@@ -5725,7 +5725,7 @@ declare class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
setNativeProps(props: { [string]: mixed, ... }): void;
constructor(props: Props<ItemT>): void;
componentDidUpdate(prevProps: Props<ItemT>): void;
_listRef: ?React.ElementRef<typeof VirtualizedList>;
_listRef: ?VirtualizedList;
_virtualizedListPairs: Array<ViewabilityConfigCallbackPair>;
_captureRef: $FlowFixMe;
_checkProps(props: Props<ItemT>): void;
@@ -239,7 +239,10 @@ NSString *RCTMD5Hash(NSString *string)
{
const char *str = string.UTF8String;
unsigned char result[CC_MD5_DIGEST_LENGTH];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
CC_MD5(str, (CC_LONG)strlen(str), result);
#pragma clang diagnostic pop
return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
result[0],
@@ -114,9 +114,6 @@ class LayoutAnimationDelegateProxy : public LayoutAnimationStatusDelegate, publi
- (instancetype)initWithToolbox:(SchedulerToolbox)toolbox
{
if (self = [super init]) {
auto reactNativeConfig =
toolbox.contextContainer->at<std::shared_ptr<const ReactNativeConfig>>("ReactNativeConfig");
_delegateProxy = std::make_unique<SchedulerDelegateProxy>((__bridge void *)self);
if (ReactNativeFeatureFlags::enableLayoutAnimationsOnIOS()) {
@@ -26,7 +26,6 @@
#import <React/RCTSurfaceView.h>
#import <React/RCTUtils.h>
#import <react/config/ReactNativeConfig.h>
#import <react/featureflags/ReactNativeFeatureFlags.h>
#import <react/renderer/componentregistry/ComponentDescriptorFactory.h>
#import <react/renderer/components/text/BaseTextProps.h>
@@ -226,8 +225,6 @@ using namespace facebook::react;
- (RCTScheduler *)_createScheduler
{
auto reactNativeConfig = _contextContainer->at<std::shared_ptr<const ReactNativeConfig>>("ReactNativeConfig");
auto componentRegistryFactory =
[factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)](
const EventDispatcher::Weak &eventDispatcher, const ContextContainer::Shared &contextContainer) {
@@ -1,3 +1,4 @@
// @lint-ignore-every LICENSELINT
/*
* Copyright (c) 2015 Daniel Kirchner
*
@@ -27,10 +28,6 @@
NS_ASSUME_NONNULL_BEGIN
#ifdef __cplusplus
extern "C" {
#endif
/// magic constants :-)
static const uint64_t PRIME1 = 11400714785074694791ULL;
static const uint64_t PRIME2 = 14029467366897019727ULL;
@@ -106,13 +103,18 @@ NS_INLINE uint64_t h32bytes(const char *p, uint64_t len, const uint64_t seed)
return h32bytes_compute(p, len, seed + PRIME1 + PRIME2, seed + PRIME2, seed, seed - PRIME1);
}
/*
Primary APIs
*/
NS_INLINE uint64_t meta_xxhash64(const char *p, uint64_t len, uint64_t seed)
{
return finalize((len >= 32 ? h32bytes(p, len, seed) : seed + PRIME5) + len, p + (len & ~0x1FULL), len & 0x1FULL);
}
NS_INLINE uint64_t FBxxHash64(const char *p, uint64_t len, uint64_t seed)
{
return finalize((len >= 32 ? h32bytes(p, len, seed) : seed + PRIME5) + len, p + (len & ~0x1F), len & 0x1F);
return meta_xxhash64(p, len, seed);
}
#ifdef __cplusplus
}
#endif
NS_ASSUME_NONNULL_END
@@ -121,8 +121,8 @@ using namespace facebook::react;
auto &props = *sharedProps;
props.layoutConstraints = LayoutConstraints{{0, 0}, {500, 500}};
auto &yogaStyle = props.yogaStyle;
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200));
return sharedProps;
})
.children({
@@ -136,8 +136,8 @@ using namespace facebook::react;
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(0));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200));
return sharedProps;
})
.children({
@@ -216,8 +216,8 @@ using namespace facebook::react;
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(30));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(50));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(50));
return sharedProps;
})
.children({
@@ -260,8 +260,8 @@ using namespace facebook::react;
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(90));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(50));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(50));
return sharedProps;
})
.children({
@@ -418,8 +418,8 @@ static ParagraphShadowNode::ConcreteState::Shared stateWithShadowNode(
auto &props = *sharedProps;
props.layoutConstraints = LayoutConstraints{{0, 0}, {500, 500}};
auto &yogaStyle = props.yogaStyle;
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(200));
return sharedProps;
})
.children({
@@ -434,8 +434,8 @@ static ParagraphShadowNode::ConcreteState::Shared stateWithShadowNode(
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(90));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(20));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(20));
return sharedProps;
})
.children({
@@ -19,7 +19,7 @@ BOOL RCTBorderInsetsAreEqual(UIEdgeInsets borderInsets)
BOOL RCTCornerRadiiAreEqualAndSymmetrical(RCTCornerRadii cornerRadii)
{
return cornerRadii.topLeftHorizontal == cornerRadii.topLeftHorizontal &&
return cornerRadii.topLeftHorizontal == cornerRadii.topLeftVertical &&
cornerRadii.topRightHorizontal == cornerRadii.topRightVertical &&
cornerRadii.bottomLeftHorizontal == cornerRadii.bottomLeftVertical &&
cornerRadii.bottomRightHorizontal == cornerRadii.bottomRightVertical &&
@@ -87,6 +87,9 @@ CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat baseFloatValue)
return RCTCoreGraphicsFloatFromYogaFloat(value.value) * baseFloatValue;
case YGUnitAuto:
case YGUnitUndefined:
case YGUnitMaxContent:
case YGUnitFitContent:
case YGUnitStretch:
return baseFloatValue;
}
}
@@ -63,6 +63,9 @@ typedef NS_ENUM(unsigned int, meta_prop_t) {
#define RCT_SET_YGVALUE(ygvalue, setter, ...) \
switch (ygvalue.unit) { \
case YGUnitAuto: \
case YGUnitMaxContent: \
case YGUnitFitContent: \
case YGUnitStretch: \
case YGUnitUndefined: \
setter(__VA_ARGS__, YGUndefined); \
break; \
@@ -88,6 +91,35 @@ typedef NS_ENUM(unsigned int, meta_prop_t) {
case YGUnitPercent: \
setter##Percent(__VA_ARGS__, ygvalue.value); \
break; \
case YGUnitMaxContent: \
case YGUnitFitContent: \
case YGUnitStretch: \
break; \
}
#define RCT_SET_YGVALUE_AUTO_INTRINSIC(ygvalue, setter, ...) \
switch (ygvalue.unit) { \
case YGUnitAuto: \
setter##Auto(__VA_ARGS__); \
break; \
case YGUnitMaxContent: \
setter##MaxContent(__VA_ARGS__); \
break; \
case YGUnitFitContent: \
setter##FitContent(__VA_ARGS__); \
break; \
case YGUnitStretch: \
setter##Stretch(__VA_ARGS__); \
break; \
case YGUnitUndefined: \
setter(__VA_ARGS__, YGUndefined); \
break; \
case YGUnitPoint: \
setter(__VA_ARGS__, ygvalue.value); \
break; \
case YGUnitPercent: \
setter##Percent(__VA_ARGS__, ygvalue.value); \
break; \
}
static void RCTProcessMetaPropsPadding(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node)
@@ -483,14 +515,14 @@ RCT_BORDER_PROPERTY(Start, START)
RCT_BORDER_PROPERTY(End, END)
// Dimensions
#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
-(void)set##setProp : (YGValue)value \
{ \
RCT_SET_YGVALUE_AUTO(value, YGNodeStyleSet##cssProp, _yogaNode); \
} \
-(YGValue)getProp \
{ \
return YGNodeStyleGet##cssProp(_yogaNode); \
#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
-(void)set##setProp : (YGValue)value \
{ \
RCT_SET_YGVALUE_AUTO_INTRINSIC(value, YGNodeStyleSet##cssProp, _yogaNode); \
} \
-(YGValue)getProp \
{ \
return YGNodeStyleGet##cssProp(_yogaNode); \
}
#define RCT_MIN_MAX_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
@@ -634,7 +666,7 @@ RCTShadowViewMeasure(YGNodeConstRef node, float width, YGMeasureMode widthMode,
- (void)setFlexBasis:(YGValue)value
{
RCT_SET_YGVALUE_AUTO(value, YGNodeStyleSetFlexBasis, _yogaNode);
RCT_SET_YGVALUE_AUTO_INTRINSIC(value, YGNodeStyleSetFlexBasis, _yogaNode);
}
- (YGValue)flexBasis
@@ -1644,13 +1644,6 @@ public final class com/facebook/react/bridge/WritableNativeMap : com/facebook/re
public fun putString (Ljava/lang/String;Ljava/lang/String;)V
}
public class com/facebook/react/bridge/interop/InteropModuleRegistry {
public fun <init> ()V
public fun getInteropModule (Ljava/lang/Class;)Lcom/facebook/react/bridge/JavaScriptModule;
public fun registerInteropModule (Ljava/lang/Class;Ljava/lang/Object;)V
public fun shouldReturnInteropModule (Ljava/lang/Class;)Z
}
public abstract interface class com/facebook/react/bridge/queue/MessageQueueThread {
public abstract fun assertIsOnThread ()V
public abstract fun assertIsOnThread (Ljava/lang/String;)V
@@ -2168,7 +2161,7 @@ public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/
public fun fetchSplitBundleAndCreateBundleLoader (Ljava/lang/String;Lcom/facebook/react/devsupport/DevSupportManagerBase$CallbackWithBundleLoader;)V
protected fun getApplicationContext ()Landroid/content/Context;
public fun getCurrentActivity ()Landroid/app/Activity;
protected fun getCurrentContext ()Lcom/facebook/react/bridge/ReactContext;
public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
public fun getDevLoadingViewManager ()Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager;
public fun getDevServerHelper ()Lcom/facebook/react/devsupport/DevServerHelper;
public fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;
@@ -2341,6 +2334,7 @@ public class com/facebook/react/devsupport/ReleaseDevSupportManager : com/facebo
public fun destroyRootView (Landroid/view/View;)V
public fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File;
public fun getCurrentActivity ()Landroid/app/Activity;
public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
public fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;
public fun getDevSupportEnabled ()Z
public fun getDownloadedJSBundleFile ()Ljava/lang/String;
@@ -2477,6 +2471,7 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevSupp
public abstract fun destroyRootView (Landroid/view/View;)V
public abstract fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File;
public abstract fun getCurrentActivity ()Landroid/app/Activity;
public abstract fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
public abstract fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;
public abstract fun getDevSupportEnabled ()Z
public abstract fun getDownloadedJSBundleFile ()Ljava/lang/String;
@@ -3319,17 +3314,6 @@ public final class com/facebook/react/modules/devloading/DevLoadingModule : com/
public final class com/facebook/react/modules/devloading/DevLoadingModule$Companion {
}
public final class com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule : com/facebook/fbreact/specs/NativeReactDevToolsRuntimeSettingsModuleSpec {
public static final field Companion Lcom/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule$Companion;
public static final field NAME Ljava/lang/String;
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;)V
public fun getReloadAndProfileConfig ()Lcom/facebook/react/bridge/WritableMap;
public fun setReloadAndProfileConfig (Lcom/facebook/react/bridge/ReadableMap;)V
}
public final class com/facebook/react/modules/devtoolsruntimesettings/ReactDevToolsRuntimeSettingsModule$Companion {
}
public class com/facebook/react/modules/dialog/AlertFragment : androidx/fragment/app/DialogFragment, android/content/DialogInterface$OnClickListener {
public fun <init> ()V
public fun <init> (Lcom/facebook/react/modules/dialog/DialogModule$AlertFragmentListener;Landroid/os/Bundle;)V
@@ -3377,14 +3361,26 @@ public final class com/facebook/react/modules/fresco/FrescoModule$Companion {
public final fun hasBeenInitialized ()Z
}
public final class com/facebook/react/modules/fresco/ImageCacheControl : java/lang/Enum {
public static final field DEFAULT Lcom/facebook/react/modules/fresco/ImageCacheControl;
public static final field ONLY_IF_CACHED Lcom/facebook/react/modules/fresco/ImageCacheControl;
public static final field RELOAD Lcom/facebook/react/modules/fresco/ImageCacheControl;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lcom/facebook/react/modules/fresco/ImageCacheControl;
public static fun values ()[Lcom/facebook/react/modules/fresco/ImageCacheControl;
}
public final class com/facebook/react/modules/fresco/ReactNetworkImageRequest : com/facebook/imagepipeline/request/ImageRequest {
public static final field Companion Lcom/facebook/react/modules/fresco/ReactNetworkImageRequest$Companion;
public synthetic fun <init> (Lcom/facebook/imagepipeline/request/ImageRequestBuilder;Lcom/facebook/react/bridge/ReadableMap;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Lcom/facebook/imagepipeline/request/ImageRequestBuilder;Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/modules/fresco/ImageCacheControl;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public static final fun fromBuilderWithHeaders (Lcom/facebook/imagepipeline/request/ImageRequestBuilder;Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/modules/fresco/ReactNetworkImageRequest;
public static final fun fromBuilderWithHeaders (Lcom/facebook/imagepipeline/request/ImageRequestBuilder;Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/modules/fresco/ImageCacheControl;)Lcom/facebook/react/modules/fresco/ReactNetworkImageRequest;
}
public final class com/facebook/react/modules/fresco/ReactNetworkImageRequest$Companion {
public final fun fromBuilderWithHeaders (Lcom/facebook/imagepipeline/request/ImageRequestBuilder;Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/modules/fresco/ReactNetworkImageRequest;
public final fun fromBuilderWithHeaders (Lcom/facebook/imagepipeline/request/ImageRequestBuilder;Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/modules/fresco/ImageCacheControl;)Lcom/facebook/react/modules/fresco/ReactNetworkImageRequest;
public static synthetic fun fromBuilderWithHeaders$default (Lcom/facebook/react/modules/fresco/ReactNetworkImageRequest$Companion;Lcom/facebook/imagepipeline/request/ImageRequestBuilder;Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/modules/fresco/ImageCacheControl;ILjava/lang/Object;)Lcom/facebook/react/modules/fresco/ReactNetworkImageRequest;
}
public final class com/facebook/react/modules/fresco/SystraceRequestListener : com/facebook/imagepipeline/listener/BaseRequestListener {
@@ -3604,17 +3600,6 @@ public final class com/facebook/react/modules/permissions/PermissionsModule : co
public final class com/facebook/react/modules/permissions/PermissionsModule$Companion {
}
public final class com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule : com/facebook/fbreact/specs/NativeReactDevToolsSettingsManagerSpec {
public static final field Companion Lcom/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule$Companion;
public static final field NAME Ljava/lang/String;
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;)V
public fun getGlobalHookSettings ()Ljava/lang/String;
public fun setGlobalHookSettings (Ljava/lang/String;)V
}
public final class com/facebook/react/modules/reactdevtoolssettings/ReactDevToolsSettingsManagerModule$Companion {
}
public final class com/facebook/react/modules/share/ShareModule : com/facebook/fbreact/specs/NativeShareModuleSpec {
public static final field Companion Lcom/facebook/react/modules/share/ShareModule$Companion;
public static final field ERROR_INVALID_CONTENT Ljava/lang/String;
@@ -6707,8 +6692,10 @@ public class com/facebook/react/views/imagehelper/ImageSource {
public fun <init> (Landroid/content/Context;Ljava/lang/String;)V
public fun <init> (Landroid/content/Context;Ljava/lang/String;D)V
public fun <init> (Landroid/content/Context;Ljava/lang/String;DD)V
public synthetic fun <init> (Landroid/content/Context;Ljava/lang/String;DDILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Landroid/content/Context;Ljava/lang/String;DDLcom/facebook/react/modules/fresco/ImageCacheControl;)V
public synthetic fun <init> (Landroid/content/Context;Ljava/lang/String;DDLcom/facebook/react/modules/fresco/ImageCacheControl;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun equals (Ljava/lang/Object;)Z
public final fun getCacheControl ()Lcom/facebook/react/modules/fresco/ImageCacheControl;
public final fun getSize ()D
public final fun getSource ()Ljava/lang/String;
public static final fun getTransparentBitmapImageSource (Landroid/content/Context;)Lcom/facebook/react/views/imagehelper/ImageSource;
@@ -8169,30 +8156,6 @@ public abstract interface class com/facebook/react/views/textinput/ScrollWatcher
public abstract fun onScrollChanged (IIII)V
}
public final class com/facebook/react/views/unimplementedview/ReactUnimplementedView : android/widget/LinearLayout {
public fun <init> (Landroid/content/Context;)V
public final fun setName (Ljava/lang/String;)V
}
public final class com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager : com/facebook/react/uimanager/ViewGroupManager {
public static final field Companion Lcom/facebook/react/views/unimplementedview/ReactUnimplementedViewManager$Companion;
public static final field REACT_CLASS Ljava/lang/String;
public fun <init> ()V
public synthetic fun createViewInstance (Lcom/facebook/react/uimanager/ThemedReactContext;)Landroid/view/View;
public fun getName ()Ljava/lang/String;
public final fun setName (Lcom/facebook/react/views/unimplementedview/ReactUnimplementedView;Ljava/lang/String;)V
}
public class com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager$$PropsSetter : com/facebook/react/uimanager/ViewManagerPropertyUpdater$ViewManagerSetter {
public fun <init> ()V
public fun getProperties (Ljava/util/Map;)V
public synthetic fun setProperty (Lcom/facebook/react/uimanager/ViewManager;Landroid/view/View;Ljava/lang/String;Ljava/lang/Object;)V
public fun setProperty (Lcom/facebook/react/views/unimplementedview/ReactUnimplementedViewManager;Lcom/facebook/react/views/unimplementedview/ReactUnimplementedView;Ljava/lang/String;Ljava/lang/Object;)V
}
public final class com/facebook/react/views/unimplementedview/ReactUnimplementedViewManager$Companion {
}
public final class com/facebook/react/views/view/ColorUtil {
public static final field INSTANCE Lcom/facebook/react/views/view/ColorUtil;
public static final fun normalize (DDDD)I
@@ -533,9 +533,7 @@ android {
"-DREACT_BUILD_DIR=$buildDir",
"-DANDROID_STL=c++_shared",
"-DANDROID_TOOLCHAIN=clang",
// Due to https://github.com/android/ndk/issues/1693 we're losing Android
// specific compilation flags. This can be removed once we moved to NDK 25/26
"-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON")
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON")
targets(
"reactnative",
@@ -41,7 +41,7 @@ if (PROJECT_ROOT_DIR)
endif ()
file(GLOB input_SRC CONFIGURE_DEPENDS
*.cpp
${REACT_ANDROID_DIR}/cmake-utils/default-app-setup/*.cpp
${BUILD_DIR}/generated/autolinking/src/main/jni/*.cpp)
add_library(${CMAKE_PROJECT_NAME} SHARED ${input_SRC})
@@ -8,7 +8,9 @@ android.useAndroidX=true
react.internal.disableJavaVersionAlignment=true
# Binary Compatibility Validator properties
binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig
binaryCompatibilityValidator.ignoredClasses=com.facebook.react.BuildConfig,\
com.facebook.react.views.unimplementedview.ReactUnimplementedViewManager$$PropsSetter
binaryCompatibilityValidator.ignoredPackages=com.facebook.debug,\
com.facebook.fbreact,\
com.facebook.hermes,\
@@ -228,6 +228,7 @@ android {
"-DHERMES_IS_ANDROID=True",
"-DANDROID_STL=c++_shared",
"-DANDROID_PIE=True",
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON",
"-DIMPORT_HERMESC=${File(hermesBuildDir, "ImportHermesc.cmake").toString()}",
"-DJSI_DIR=${jsiDir}",
"-DHERMES_SLOW_DEBUG=False",
@@ -235,10 +236,7 @@ android {
"-DHERMES_RELEASE_VERSION=for RN ${version}",
// We intentionally build Hermes with Intl support only. This is to simplify
// the build setup and to avoid overcomplicating the build-type matrix.
"-DHERMES_ENABLE_INTL=True",
// Due to https://github.com/android/ndk/issues/1693 we're losing Android
// specific compilation flags. This can be removed once we moved to NDK 25/26
"-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON")
"-DHERMES_ENABLE_INTL=True")
targets("libhermes")
}
@@ -262,11 +260,6 @@ android {
// This has the (unlucky) side effect of letting AGP call the build
// tasks `configureCMakeRelease` while is actually building the debug flavor.
arguments("-DCMAKE_BUILD_TYPE=Release")
// Adding -O3 to handle the issue here:
// https://github.com/android/ndk/issues/1740#issuecomment-1198438260
// The old NDK toolchain is not passing -O3 correctly for release CMake builds. This is
// fixed in NDK 25 and can be removed once we're there.
cppFlags("-O3")
}
}
}
@@ -330,6 +323,11 @@ afterEvaluate {
tasks.getByName("preBuild").dependsOn(prepareHeadersForPrefab)
}
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-Xlint:deprecation,unchecked")
options.compilerArgs.add("-Werror")
}
/* Publishing Configuration */
apply(from = "../publish.gradle")
@@ -1,30 +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.debug.debugoverlay.model;
import javax.annotation.concurrent.Immutable;
/** Tag for a debug overlay log message. Name must be unique. */
@Immutable
public class DebugOverlayTag {
/** Name of tag. */
public final String name;
/** Description to display in settings. */
public final String description;
/** Color for tag display. */
public final int color;
public DebugOverlayTag(String name, String description, int color) {
this.name = name;
this.description = description;
this.color = color;
}
}
@@ -0,0 +1,21 @@
/*
* 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.debug.debugoverlay.model
/**
* Tag for a debug overlay log message. Name must be unique.
*
* @param name Name of tag.
* @param description Description to display in settings.
* @param color Color for tag display.
*/
internal class DebugOverlayTag(
public val name: String,
public val description: String,
public val color: Int,
)
@@ -10,12 +10,11 @@ package com.facebook.debug.holder
import com.facebook.debug.debugoverlay.model.DebugOverlayTag
/** No-op implementation of [Printer]. */
public object NoopPrinter : Printer {
internal object NoopPrinter : Printer {
public override fun logMessage(tag: DebugOverlayTag, message: String, vararg args: Any?): Unit =
Unit
override fun logMessage(tag: DebugOverlayTag, message: String, vararg args: Any?): Unit = Unit
public override fun logMessage(tag: DebugOverlayTag, message: String): Unit = Unit
override fun logMessage(tag: DebugOverlayTag, message: String): Unit = Unit
public override fun shouldDisplayLogMessage(tag: DebugOverlayTag): Boolean = false
override fun shouldDisplayLogMessage(tag: DebugOverlayTag): Boolean = false
}
@@ -10,11 +10,11 @@ package com.facebook.debug.holder
import com.facebook.debug.debugoverlay.model.DebugOverlayTag
/** Interface to debugging tool. */
public interface Printer {
internal interface Printer {
public fun logMessage(tag: DebugOverlayTag, message: String, vararg args: Any?)
fun logMessage(tag: DebugOverlayTag, message: String, vararg args: Any?)
public fun logMessage(tag: DebugOverlayTag, message: String)
fun logMessage(tag: DebugOverlayTag, message: String)
public fun shouldDisplayLogMessage(tag: DebugOverlayTag): Boolean
fun shouldDisplayLogMessage(tag: DebugOverlayTag): Boolean
}
@@ -8,6 +8,6 @@
package com.facebook.debug.holder
/** Holder for debugging tool instance. */
public object PrinterHolder {
@JvmStatic public var printer: Printer = NoopPrinter
internal object PrinterHolder {
@JvmStatic var printer: Printer = NoopPrinter
}
@@ -1,38 +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.debug.tags;
import android.graphics.Color;
import com.facebook.debug.debugoverlay.model.DebugOverlayTag;
/** Category for debug overlays. */
public class ReactDebugOverlayTags {
public static final DebugOverlayTag PERFORMANCE =
new DebugOverlayTag("Performance", "Markers for Performance", Color.GREEN);
public static final DebugOverlayTag NAVIGATION =
new DebugOverlayTag("Navigation", "Tag for navigation", Color.rgb(0x9C, 0x27, 0xB0));
public static final DebugOverlayTag RN_CORE =
new DebugOverlayTag("RN Core", "Tag for React Native Core", Color.BLACK);
public static final DebugOverlayTag BRIDGE_CALLS =
new DebugOverlayTag(
"Bridge Calls", "JS to Java calls (warning: this is spammy)", Color.MAGENTA);
public static final DebugOverlayTag NATIVE_MODULE =
new DebugOverlayTag("Native Module", "Native Module init", Color.rgb(0x80, 0x00, 0x80));
public static final DebugOverlayTag UI_MANAGER =
new DebugOverlayTag(
"UI Manager",
"UI Manager View Operations (requires restart\nwarning: this is spammy)",
Color.CYAN);
public static final DebugOverlayTag FABRIC_UI_MANAGER =
new DebugOverlayTag("FabricUIManager", "Fabric UI Manager View Operations", Color.CYAN);
public static final DebugOverlayTag FABRIC_RECONCILER =
new DebugOverlayTag("FabricReconciler", "Reconciler for Fabric", Color.CYAN);
public static final DebugOverlayTag RELAY =
new DebugOverlayTag("Relay", "including prefetching", Color.rgb(0xFF, 0x99, 0x00));
}
@@ -0,0 +1,45 @@
/*
* 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.debug.tags
import android.graphics.Color
import com.facebook.debug.debugoverlay.model.DebugOverlayTag
/** Category for debug overlays. */
internal object ReactDebugOverlayTags {
@JvmField
val PERFORMANCE: DebugOverlayTag =
DebugOverlayTag("Performance", "Markers for Performance", Color.GREEN)
@JvmField
val NAVIGATION: DebugOverlayTag =
DebugOverlayTag("Navigation", "Tag for navigation", Color.rgb(0x9C, 0x27, 0xB0))
@JvmField
val RN_CORE: DebugOverlayTag =
DebugOverlayTag("RN Core", "Tag for React Native Core", Color.BLACK)
@JvmField
val BRIDGE_CALLS: DebugOverlayTag =
DebugOverlayTag("Bridge Calls", "JS to Java calls (warning: this is spammy)", Color.MAGENTA)
@JvmField
val NATIVE_MODULE: DebugOverlayTag =
DebugOverlayTag("Native Module", "Native Module init", Color.rgb(0x80, 0x00, 0x80))
@JvmField
val UI_MANAGER: DebugOverlayTag =
DebugOverlayTag(
"UI Manager",
"UI Manager View Operations (requires restart\nwarning: this is spammy)",
Color.CYAN)
@JvmField
val FABRIC_UI_MANAGER: DebugOverlayTag =
DebugOverlayTag("FabricUIManager", "Fabric UI Manager View Operations", Color.CYAN)
@JvmField
val FABRIC_RECONCILER: DebugOverlayTag =
DebugOverlayTag("FabricReconciler", "Reconciler for Fabric", Color.CYAN)
@JvmField
val RELAY: DebugOverlayTag =
DebugOverlayTag("Relay", "including prefetching", Color.rgb(0xFF, 0x99, 0x00))
}
@@ -63,6 +63,8 @@ public abstract class ReactContext extends ContextWrapper {
private @Nullable JSExceptionHandler mExceptionHandlerWrapper;
private @Nullable WeakReference<Activity> mCurrentActivity;
// NOTE: When converted to Kotlin, this field should be made internal due to
// visibility restriction on InteropModuleRegistry otherwise it will be exposed to the public API.
protected @Nullable InteropModuleRegistry mInteropModuleRegistry;
private boolean mIsInitialized = false;
@@ -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.bridge.interop;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
import java.util.HashMap;
/**
* A utility class that takes care of returning {@link JavaScriptModule} which are used for the
* Fabric Interop Layer. This allows us to override the returned classes once the user is invoking
* `ReactContext.getJsModule()`.
*
* <p>Currently we only support a `RCTEventEmitter` re-implementation, being `InteropEventEmitter`
* but this class can support other re-implementation in the future.
*/
public class InteropModuleRegistry {
@SuppressWarnings("rawtypes")
private final HashMap<Class, Object> supportedModules;
public InteropModuleRegistry() {
supportedModules = new HashMap<>();
}
public <T extends JavaScriptModule> boolean shouldReturnInteropModule(Class<T> requestedModule) {
return checkReactFeatureFlagsConditions() && supportedModules.containsKey(requestedModule);
}
@Nullable
public <T extends JavaScriptModule> T getInteropModule(Class<T> requestedModule) {
if (checkReactFeatureFlagsConditions()) {
//noinspection unchecked
return (T) supportedModules.get(requestedModule);
} else {
return null;
}
}
public <T extends JavaScriptModule> void registerInteropModule(
Class<T> interopModuleInterface, Object interopModule) {
if (checkReactFeatureFlagsConditions()) {
supportedModules.put(interopModuleInterface, interopModule);
}
}
private boolean checkReactFeatureFlagsConditions() {
return ReactNativeFeatureFlags.enableFabricRenderer()
&& ReactNativeFeatureFlags.useFabricInterop();
}
}
@@ -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.
*/
package com.facebook.react.bridge.interop
import com.facebook.react.bridge.JavaScriptModule
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags.enableFabricRenderer
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags.useFabricInterop
/**
* A utility class that takes care of returning [JavaScriptModule] which are used for the Fabric
* Interop Layer. This allows us to override the returned classes once the user is invoking
* `ReactContext.getJsModule()`.
*
* Currently we only support a `RCTEventEmitter` re-implementation, being `InteropEventEmitter` but
* this class can support other re-implementation in the future.
*/
internal class InteropModuleRegistry {
private val supportedModules = mutableMapOf<Class<*>, Any?>()
fun <T : JavaScriptModule?> shouldReturnInteropModule(requestedModule: Class<T>): Boolean {
return checkReactFeatureFlagsConditions() && supportedModules.containsKey(requestedModule)
}
fun <T : JavaScriptModule?> getInteropModule(requestedModule: Class<T>): T? {
return if (checkReactFeatureFlagsConditions()) {
@Suppress("UNCHECKED_CAST")
supportedModules[requestedModule] as? T?
} else {
null
}
}
fun <T : JavaScriptModule?> registerInteropModule(
interopModuleInterface: Class<T>,
interopModule: Any
) {
if (checkReactFeatureFlagsConditions()) {
supportedModules[interopModuleInterface] = interopModule
}
}
private fun checkReactFeatureFlagsConditions(): Boolean =
enableFabricRenderer() && useFabricInterop()
}
@@ -97,8 +97,8 @@ public final class BridgeDevSupportManager extends DevSupportManagerBase {
new CallbackWithBundleLoader() {
@Override
public void onSuccess(JSBundleLoader bundleLoader) {
bundleLoader.loadScript(getCurrentContext().getCatalystInstance());
getCurrentContext()
bundleLoader.loadScript(getCurrentReactContext().getCatalystInstance());
getCurrentReactContext()
.getJSModule(HMRClient.class)
.registerBundle(getDevServerHelper().getDevServerSplitBundleURL(bundlePath));
callback.onSuccess();
@@ -107,7 +107,7 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
private @Nullable DebugOverlayController mDebugOverlayController;
private boolean mDevLoadingViewVisible = false;
private int mPendingJSSplitBundleRequests = 0;
private @Nullable ReactContext mCurrentContext;
private @Nullable ReactContext mCurrentReactContext;
private final DeveloperSettings mDevSettings;
private boolean mIsReceiverRegistered = false;
private boolean mIsShakeDetectorStarted = false;
@@ -429,11 +429,11 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
() -> {
boolean nextEnabled = !mDevSettings.isHotModuleReplacementEnabled();
mDevSettings.setHotModuleReplacementEnabled(nextEnabled);
if (mCurrentContext != null) {
if (mCurrentReactContext != null) {
if (nextEnabled) {
mCurrentContext.getJSModule(HMRClient.class).enable();
mCurrentReactContext.getJSModule(HMRClient.class).enable();
} else {
mCurrentContext.getJSModule(HMRClient.class).disable();
mCurrentReactContext.getJSModule(HMRClient.class).disable();
}
}
if (nextEnabled && !mDevSettings.isJSDevModeEnabled()) {
@@ -542,8 +542,10 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
.setOnCancelListener(dialog -> mDevOptionsDialog = null)
.create();
mDevOptionsDialog.show();
if (mCurrentContext != null) {
mCurrentContext.getJSModule(RCTNativeAppEventEmitter.class).emit("RCTDevMenuShown", null);
if (mCurrentReactContext != null) {
mCurrentReactContext
.getJSModule(RCTNativeAppEventEmitter.class)
.emit("RCTDevMenuShown", null);
}
}
@@ -588,11 +590,19 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
@Override
public void onReactInstanceDestroyed(ReactContext reactContext) {
if (reactContext == mCurrentContext) {
if (reactContext == mCurrentReactContext) {
// only call reset context when the destroyed context matches the one that is currently set
// for this manager
resetCurrentContext(null);
}
// If some JNI types (e.g. jni::HybridClass) are used in JSI (e.g. jsi::HostObject), they might
// not be immediately deleted on an app refresh as both Java and JavaScript are
// garbage-collected languages and the memory might float around for a while. For C++
// developers, this will be hard to debug as destructors might be called at a later point, so in
// this case we trigger a Java GC to maybe eagerly collect such objects when the app
// reloads.
System.gc();
}
@Override
@@ -656,12 +666,12 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
}
private void resetCurrentContext(@Nullable ReactContext reactContext) {
if (mCurrentContext == reactContext) {
if (mCurrentReactContext == reactContext) {
// new context is the same as the old one - do nothing
return;
}
mCurrentContext = reactContext;
mCurrentReactContext = reactContext;
// Recreate debug overlay controller with new CatalystInstance object
if (mDebugOverlayController != null) {
@@ -671,13 +681,13 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
mDebugOverlayController = new DebugOverlayController(reactContext);
}
if (mCurrentContext != null) {
if (mCurrentReactContext != null) {
try {
URL sourceUrl = new URL(getSourceUrl());
String path = sourceUrl.getPath().substring(1); // strip initial slash in path
String host = sourceUrl.getHost();
int port = sourceUrl.getPort() != -1 ? sourceUrl.getPort() : sourceUrl.getDefaultPort();
mCurrentContext
mCurrentReactContext
.getJSModule(HMRClient.class)
.setup("android", path, host, port, mDevSettings.isHotModuleReplacementEnabled());
} catch (MalformedURLException e) {
@@ -697,8 +707,8 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
}
}
protected @Nullable ReactContext getCurrentContext() {
return mCurrentContext;
public @Nullable ReactContext getCurrentReactContext() {
return mCurrentReactContext;
}
public @Nullable String getJSAppBundleName() {
@@ -775,7 +785,7 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
public void onSuccess() {
UiThreadUtil.runOnUiThread(() -> hideSplitBundleDevLoadingView());
@Nullable ReactContext context = mCurrentContext;
@Nullable ReactContext context = mCurrentReactContext;
if (context == null || !context.hasActiveReactInstance()) {
return;
}
@@ -856,10 +866,10 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
}
private void handleCaptureHeap(final Responder responder) {
if (mCurrentContext == null) {
if (mCurrentReactContext == null) {
return;
}
JSCHeapCapture heapCapture = mCurrentContext.getNativeModule(JSCHeapCapture.class);
JSCHeapCapture heapCapture = mCurrentReactContext.getNativeModule(JSCHeapCapture.class);
if (heapCapture != null) {
heapCapture.captureHeap(
@@ -1152,7 +1162,7 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
@Override
public void openDebugger() {
mDevServerHelper.openDebugger(
mCurrentContext, mApplicationContext.getString(R.string.catalyst_open_debugger_error));
mCurrentReactContext, mApplicationContext.getString(R.string.catalyst_open_debugger_error));
}
@Override
@@ -21,6 +21,8 @@ import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.facebook.common.logging.FLog;
import com.facebook.react.R;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.SurfaceDelegate;
import com.facebook.react.devsupport.interfaces.DevSupportManager;
@@ -55,7 +57,7 @@ class RedBoxDialogSurfaceDelegate implements SurfaceDelegate {
FLog.e(
ReactConstants.TAG,
"Unable to launch redbox because react activity "
+ "is not available, here is the error that redbox would've displayed: "
+ "are not available, here is the error that redbox would've displayed: "
+ (message != null ? message : "N/A"));
return;
}
@@ -82,9 +84,19 @@ class RedBoxDialogSurfaceDelegate implements SurfaceDelegate {
@Nullable String message = mDevSupportManager.getLastErrorTitle();
Activity context = mDevSupportManager.getCurrentActivity();
if (context == null || context.isFinishing()) {
final @Nullable ReactContext reactContext = mDevSupportManager.getCurrentReactContext();
if (reactContext != null) {
/**
* If the activity isn't available, try again after the next onHostResume(). onHostResume()
* is when the activity gets attached to the react native.
*/
runAfterHostResume(reactContext, this::show);
return;
}
FLog.e(
ReactConstants.TAG,
"Unable to launch redbox because react activity "
"Unable to launch redbox because react activity and react context "
+ "is not available, here is the error that redbox would've displayed: "
+ (message != null ? message : "N/A"));
return;
@@ -140,6 +152,23 @@ class RedBoxDialogSurfaceDelegate implements SurfaceDelegate {
mDialog.show();
}
private static void runAfterHostResume(ReactContext reactContext, Runnable runnable) {
reactContext.addLifecycleEventListener(
new LifecycleEventListener() {
@Override
public void onHostResume() {
runnable.run();
reactContext.removeLifecycleEventListener(this);
}
@Override
public void onHostPause() {}
@Override
public void onHostDestroy() {}
});
}
@Override
public void hide() {
// dismiss redbox if exists
@@ -147,6 +147,9 @@ public open class ReleaseDevSupportManager : DevSupportManager {
override public val currentActivity: Activity?
get() = null
override public val currentReactContext: ReactContext?
get() = null
override public fun createSurfaceDelegate(moduleName: String?): SurfaceDelegate? = null
override public fun openDebugger(): Unit = Unit
@@ -35,6 +35,7 @@ public interface DevSupportManager : JSExceptionHandler {
public val lastErrorType: ErrorType?
public val lastErrorCookie: Int
public val currentActivity: Activity?
public val currentReactContext: ReactContext?
public var devSupportEnabled: Boolean
@@ -86,6 +86,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
private var touchExplorationEnabled = false
private var accessibilityServiceEnabled = false
private var recommendedTimeout = 0
private var invertColorsEnabled = false
init {
val appContext = context.applicationContext
@@ -111,6 +112,17 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
return parsedValue == 0f
}
@get:TargetApi(Build.VERSION_CODES.LOLLIPOP)
private val isInvertColorsEnabledValue: Boolean
get() {
try {
return Settings.Secure.getInt(
contentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) == 1
} catch (e: Settings.SettingNotFoundException) {
return false
}
}
@get:TargetApi(Build.VERSION_CODES.LOLLIPOP)
private val isHighTextContrastEnabledValue: Boolean
get() {
@@ -125,6 +137,10 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
successCallback.invoke(reduceMotionEnabled)
}
override fun isInvertColorsEnabled(successCallback: Callback) {
successCallback.invoke(invertColorsEnabled)
}
override fun isHighTextContrastEnabled(successCallback: Callback) {
successCallback.invoke(highTextContrastEnabled)
}
@@ -148,6 +164,17 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
}
}
private fun updateAndSendInvertColorsChangeEvent() {
val isInvertColorsEnabled = isInvertColorsEnabledValue
if (invertColorsEnabled != isInvertColorsEnabled) {
invertColorsEnabled = isInvertColorsEnabled
val reactApplicationContext = getReactApplicationContextIfActiveOrWarn()
if (reactApplicationContext != null) {
reactApplicationContext.emitDeviceEvent(INVERT_COLOR_EVENT_NAME, invertColorsEnabled)
}
}
}
private fun updateAndSendHighTextContrastChangeEvent() {
val isHighTextContrastEnabled = isHighTextContrastEnabledValue
if (highTextContrastEnabled != isHighTextContrastEnabled) {
@@ -199,6 +226,7 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
updateAndSendAccessibilityServiceChangeEvent(accessibilityManager?.isEnabled == true)
updateAndSendReduceMotionChangeEvent()
updateAndSendHighTextContrastChangeEvent()
updateAndSendInvertColorsChangeEvent()
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@@ -263,5 +291,6 @@ internal class AccessibilityInfoModule(context: ReactApplicationContext) :
private const val ACCESSIBILITY_SERVICE_EVENT_NAME = "accessibilityServiceDidChange"
private const val ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED_CONSTANT =
"high_text_contrast_enabled" // constant is marked with @hide
private const val INVERT_COLOR_EVENT_NAME = "invertColorDidChange"
}
}
@@ -22,13 +22,13 @@ private class Settings {
@DoNotStripAny
@ReactModule(name = NativeReactDevToolsRuntimeSettingsModuleSpec.NAME)
public class ReactDevToolsRuntimeSettingsModule(reactContext: ReactApplicationContext?) :
internal class ReactDevToolsRuntimeSettingsModule(reactContext: ReactApplicationContext?) :
NativeReactDevToolsRuntimeSettingsModuleSpec(reactContext) {
public companion object {
companion object {
// static to persist across Turbo Module reloads
private val settings = Settings()
public const val NAME: String = NativeReactDevToolsRuntimeSettingsModuleSpec.NAME
const val NAME: String = NativeReactDevToolsRuntimeSettingsModuleSpec.NAME
}
override fun setReloadAndProfileConfig(map: ReadableMap) {
@@ -0,0 +1,25 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.modules.fresco
public enum class ImageCacheControl {
/** Uses OkHttp's default cache control policy with no store. */
DEFAULT,
/**
* The data for the URL will be loaded from the originating source. No existing cache data should
* be used to satisfy a URL load request.
*/
RELOAD,
/**
* The existing cache data will be used to satisfy a request, regardless of its age or expiration
* date. If there is no existing data in the cache corresponding to a URL load request, no attempt
* is made to load the data from the originating source, and the load is considered to have
* failed.
*/
ONLY_IF_CACHED,
}
@@ -16,16 +16,19 @@ public class ReactNetworkImageRequest
private constructor(
builder: ImageRequestBuilder,
/** Headers for the request */
internal val headers: ReadableMap?
internal val headers: ReadableMap?,
internal val cacheControl: ImageCacheControl,
) : ImageRequest(builder) {
public companion object {
@JvmStatic
@JvmOverloads
public fun fromBuilderWithHeaders(
builder: ImageRequestBuilder,
headers: ReadableMap?
headers: ReadableMap?,
cacheControl: ImageCacheControl = ImageCacheControl.DEFAULT,
): ReactNetworkImageRequest {
return ReactNetworkImageRequest(builder, headers)
return ReactNetworkImageRequest(builder, headers, cacheControl)
}
}
}
@@ -35,22 +35,30 @@ internal class ReactOkHttpNetworkFetcher(private val okHttpClient: OkHttpClient)
fetchState.submitTime = SystemClock.elapsedRealtime()
val uri = fetchState.uri
var requestHeaders: Map<String, String>? = null
val cacheControlBuilder = CacheControl.Builder().noStore()
if (fetchState.context.imageRequest is ReactNetworkImageRequest) {
val networkImageRequest = fetchState.context.imageRequest as ReactNetworkImageRequest
requestHeaders = getHeaders(networkImageRequest.headers)
when (networkImageRequest.cacheControl) {
ImageCacheControl.RELOAD -> {
cacheControlBuilder.noCache()
}
ImageCacheControl.ONLY_IF_CACHED -> {
cacheControlBuilder.onlyIfCached()
}
ImageCacheControl.DEFAULT -> {
// No-op
}
}
}
val headers = OkHttpCompat.getHeadersFromMap(requestHeaders)
val request =
Request.Builder()
.cacheControl(CacheControl.Builder().noStore().build())
.cacheControl(cacheControlBuilder.build())
.url(uri.toString())
.headers(headers)
.get()
.build()
fetchWithRequest(fetchState, callback, request)
}
private companion object {
private const val TAG = "ReactOkHttpNetworkFetcher"
}
}
@@ -14,20 +14,20 @@ import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.annotations.ReactModule
@ReactModule(name = NativeReactDevToolsSettingsManagerSpec.NAME)
public class ReactDevToolsSettingsManagerModule(reactContext: ReactApplicationContext) :
internal class ReactDevToolsSettingsManagerModule(reactContext: ReactApplicationContext) :
NativeReactDevToolsSettingsManagerSpec(reactContext) {
private val sharedPreferences: SharedPreferences =
reactContext.getSharedPreferences(SHARED_PREFERENCES_PREFIX, Context.MODE_PRIVATE)
public override fun setGlobalHookSettings(settings: String): Unit =
override fun setGlobalHookSettings(settings: String): Unit =
sharedPreferences.edit().putString(KEY_HOOK_SETTINGS, settings).apply()
public override fun getGlobalHookSettings(): String? =
override fun getGlobalHookSettings(): String? =
sharedPreferences.getString(KEY_HOOK_SETTINGS, null)
public companion object {
public const val NAME: String = NativeReactDevToolsSettingsManagerSpec.NAME
companion object {
const val NAME: String = NativeReactDevToolsSettingsManagerSpec.NAME
private const val SHARED_PREFERENCES_PREFIX = "ReactNative__DevToolsSettings"
private const val KEY_HOOK_SETTINGS = "HookSettings"
}
@@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable
import android.net.Uri
import com.facebook.common.references.CloseableReference
import com.facebook.common.util.UriUtil
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.controller.AbstractDraweeControllerBuilder
import com.facebook.drawee.controller.ControllerListener
import com.facebook.drawee.controller.ForwardingControllerListener
@@ -40,6 +41,7 @@ import com.facebook.imagepipeline.image.ImageInfo
import com.facebook.imagepipeline.postprocessors.IterativeBoxBlurPostProcessor
import com.facebook.imagepipeline.request.BasePostprocessor
import com.facebook.imagepipeline.request.ImageRequest
import com.facebook.imagepipeline.request.ImageRequest.RequestLevel
import com.facebook.imagepipeline.request.ImageRequestBuilder
import com.facebook.imagepipeline.request.Postprocessor
import com.facebook.react.bridge.ReactContext
@@ -49,6 +51,7 @@ import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.common.annotations.VisibleForTesting
import com.facebook.react.common.build.ReactBuildConfig
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.modules.fresco.ImageCacheControl
import com.facebook.react.modules.fresco.ReactNetworkImageRequest
import com.facebook.react.uimanager.BackgroundStyleApplicator
import com.facebook.react.uimanager.LengthPercentage
@@ -268,7 +271,8 @@ public class ReactImageView(
} else if (sources.size() == 1) {
// Optimize for the case where we have just one uri, case in which we don't need the sizes
val source = sources.getMap(0)
var imageSource = ImageSource(context, source.getString("uri"))
val cacheControl = computeCacheControl(source.getString("cache"))
var imageSource = ImageSource(context, source.getString("uri"), cacheControl = cacheControl)
if (Uri.EMPTY == imageSource.uri) {
warnImageSource(source.getString("uri"))
imageSource = getTransparentBitmapImageSource(context)
@@ -277,12 +281,14 @@ public class ReactImageView(
} else {
for (idx in 0 until sources.size()) {
val source = sources.getMap(idx)
val cacheControl = computeCacheControl(source.getString("cache"))
var imageSource =
ImageSource(
context,
source.getString("uri"),
source.getDouble("width"),
source.getDouble("height"))
source.getDouble("height"),
cacheControl)
if (Uri.EMPTY == imageSource.uri) {
warnImageSource(source.getString("uri"))
imageSource = getTransparentBitmapImageSource(context)
@@ -301,6 +307,23 @@ public class ReactImageView(
isDirty = true
}
private fun computeCacheControl(cacheControl: String?): ImageCacheControl {
return when (cacheControl) {
null,
"default" -> ImageCacheControl.DEFAULT
"reload" -> ImageCacheControl.RELOAD
"only-if-cached" -> ImageCacheControl.ONLY_IF_CACHED
else -> ImageCacheControl.DEFAULT
}
}
private fun computeRequestLevel(cacheControl: ImageCacheControl): RequestLevel {
return when (cacheControl) {
ImageCacheControl.ONLY_IF_CACHED -> RequestLevel.DISK_CACHE
else -> RequestLevel.FULL_FETCH
}
}
public fun setDefaultSource(name: String?) {
val newDefaultDrawable = instance.getResourceDrawable(context, name)
if (defaultImageDrawable != newDefaultDrawable) {
@@ -409,7 +432,10 @@ public class ReactImageView(
}
private fun maybeUpdateViewFromRequest(doResize: Boolean) {
val uri = this.imageSource?.uri ?: return
val imageSource = this.imageSource ?: return
val uri = imageSource.uri
val cacheControl = imageSource.cacheControl
val requestLevel = computeRequestLevel(cacheControl)
val postprocessorList = mutableListOf<Postprocessor>()
iterativeBoxBlurPostProcessor?.let { postprocessorList.add(it) }
@@ -418,19 +444,25 @@ public class ReactImageView(
val resizeOptions = if (doResize) resizeOptions else null
if (cacheControl == ImageCacheControl.RELOAD) {
val imagePipeline = Fresco.getImagePipeline()
imagePipeline.evictFromCache(uri)
}
val imageRequestBuilder =
ImageRequestBuilder.newBuilderWithSource(uri)
.setPostprocessor(postprocessor)
.setResizeOptions(resizeOptions)
.setAutoRotateEnabled(true)
.setProgressiveRenderingEnabled(progressiveRenderingEnabled)
.setLowestPermittedRequestLevel(requestLevel)
if (resizeMethod == ImageResizeMethod.NONE) {
imageRequestBuilder.setDownsampleOverride(DownsampleMode.NEVER)
}
val imageRequest: ImageRequest =
ReactNetworkImageRequest.fromBuilderWithHeaders(imageRequestBuilder, headers)
ReactNetworkImageRequest.fromBuilderWithHeaders(imageRequestBuilder, headers, cacheControl)
globalImageLoadListener?.onLoadAttempt(uri)
@@ -9,6 +9,7 @@ package com.facebook.react.views.imagehelper
import android.content.Context
import android.net.Uri
import com.facebook.react.modules.fresco.ImageCacheControl
import java.util.Objects
/** Class describing an image source (network URI or resource) and size. */
@@ -19,7 +20,8 @@ constructor(
/** Get the source of this image, as it was passed to the constructor. */
public val source: String?,
width: Double = 0.0,
height: Double = 0.0
height: Double = 0.0,
public val cacheControl: ImageCacheControl = ImageCacheControl.DEFAULT,
) {
/** Get the URI for this image - can be either a parsed network URI or a resource URI. */
@@ -45,10 +47,11 @@ constructor(
return java.lang.Double.compare(that.size, size) == 0 &&
isResource == that.isResource &&
uri == that.uri &&
source == that.source
source == that.source &&
cacheControl == that.cacheControl
}
override fun hashCode(): Int = Objects.hash(uri, source, size, isResource)
override fun hashCode(): Int = Objects.hash(uri, source, size, isResource, cacheControl)
private fun computeUri(context: Context): Uri =
try {
@@ -70,6 +73,6 @@ constructor(
@JvmStatic
public fun getTransparentBitmapImageSource(context: Context): ImageSource =
ImageSource(context, TRANSPARENT_BITMAP_URI)
ImageSource(context, TRANSPARENT_BITMAP_URI, cacheControl = ImageCacheControl.DEFAULT)
}
}
@@ -8,6 +8,7 @@
package com.facebook.react.views.imagehelper
import com.facebook.imagepipeline.core.ImagePipelineFactory
import com.facebook.react.modules.fresco.ImageCacheControl
/** Helper class for dealing with multisource images. */
public object MultiSourceHelper {
@@ -62,7 +63,10 @@ public object MultiSourceHelper {
best = source
}
if (precision < bestCachePrecision &&
source.cacheControl != ImageCacheControl.RELOAD &&
(imagePipeline.isInBitmapMemoryCache(source.uri) ||
// TODO: T206445115 isInDiskCacheSync is a blocking operation, we should move this to
// a separate thread
imagePipeline.isInDiskCacheSync(source.uri))) {
bestCachePrecision = precision
bestCached = source
@@ -300,7 +300,14 @@ public class ReactModalHostView(context: ThemedReactContext) :
* changed. This has the pleasant side-effect of us not having to preface all Modals with "top:
* statusBarHeight", since that margin will be included in the FrameLayout.
*/
get() = FrameLayout(context).apply { addView(dialogRootViewGroup) }
get() =
FrameLayout(context).apply {
addView(dialogRootViewGroup)
if (!statusBarTranslucent) {
// this is needed to prevent content hiding behind systems bars < API 30
this.fitsSystemWindows = true
}
}
/**
* updateProperties will update the properties that do not require us to recreate the dialog
@@ -14,7 +14,7 @@ import com.facebook.react.uimanager.annotations.ReactProp
/** ViewManager for [ReactUnimplementedView] to represent a component that is not yet supported. */
@ReactModule(name = ReactUnimplementedViewManager.REACT_CLASS)
public class ReactUnimplementedViewManager : ViewGroupManager<ReactUnimplementedView>() {
internal class ReactUnimplementedViewManager : ViewGroupManager<ReactUnimplementedView>() {
protected override fun createViewInstance(
reactContext: ThemedReactContext
@@ -27,7 +27,7 @@ public class ReactUnimplementedViewManager : ViewGroupManager<ReactUnimplemented
view.setName(name)
}
public companion object {
internal companion object {
public const val REACT_CLASS: String = "UnimplementedNativeView"
}
}
@@ -74,6 +74,9 @@ public class YogaNative {
static native void jni_YGNodeStyleSetFlexBasisJNI(long nativePointer, float flexBasis);
static native void jni_YGNodeStyleSetFlexBasisPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetFlexBasisAutoJNI(long nativePointer);
static native void jni_YGNodeStyleSetFlexBasisMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetFlexBasisFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetFlexBasisStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetMarginJNI(long nativePointer, int edge);
static native void jni_YGNodeStyleSetMarginJNI(long nativePointer, int edge, float margin);
static native void jni_YGNodeStyleSetMarginPercentJNI(long nativePointer, int edge, float percent);
@@ -91,22 +94,40 @@ public class YogaNative {
static native void jni_YGNodeStyleSetWidthJNI(long nativePointer, float width);
static native void jni_YGNodeStyleSetWidthPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetWidthAutoJNI(long nativePointer);
static native void jni_YGNodeStyleSetWidthMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetWidthFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetWidthStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetHeightJNI(long nativePointer);
static native void jni_YGNodeStyleSetHeightJNI(long nativePointer, float height);
static native void jni_YGNodeStyleSetHeightPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetHeightAutoJNI(long nativePointer);
static native void jni_YGNodeStyleSetHeightMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetHeightFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetHeightStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetMinWidthJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinWidthJNI(long nativePointer, float minWidth);
static native void jni_YGNodeStyleSetMinWidthPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetMinWidthMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinWidthFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinWidthStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetMinHeightJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinHeightJNI(long nativePointer, float minHeight);
static native void jni_YGNodeStyleSetMinHeightPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetMinHeightMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinHeightFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMinHeightStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetMaxWidthJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxWidthJNI(long nativePointer, float maxWidth);
static native void jni_YGNodeStyleSetMaxWidthPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetMaxWidthMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxWidthFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxWidthStretchJNI(long nativePointer);
static native long jni_YGNodeStyleGetMaxHeightJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxHeightJNI(long nativePointer, float maxheight);
static native void jni_YGNodeStyleSetMaxHeightPercentJNI(long nativePointer, float percent);
static native void jni_YGNodeStyleSetMaxHeightMaxContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxHeightFitContentJNI(long nativePointer);
static native void jni_YGNodeStyleSetMaxHeightStretchJNI(long nativePointer);
static native float jni_YGNodeStyleGetAspectRatioJNI(long nativePointer);
static native void jni_YGNodeStyleSetAspectRatioJNI(long nativePointer, float aspectRatio);
static native float jni_YGNodeStyleGetGapJNI(long nativePointer, int gutter);
@@ -124,6 +124,12 @@ public abstract class YogaNode implements YogaProps {
public abstract void setFlexBasisAuto();
public abstract void setFlexBasisMaxContent();
public abstract void setFlexBasisFitContent();
public abstract void setFlexBasisStretch();
public abstract YogaValue getMargin(YogaEdge edge);
public abstract void setMargin(YogaEdge edge, float margin);
@@ -158,6 +164,12 @@ public abstract class YogaNode implements YogaProps {
public abstract void setWidthAuto();
public abstract void setWidthMaxContent();
public abstract void setWidthFitContent();
public abstract void setWidthStretch();
public abstract YogaValue getHeight();
public abstract void setHeight(float height);
@@ -166,30 +178,60 @@ public abstract class YogaNode implements YogaProps {
public abstract void setHeightAuto();
public abstract void setHeightMaxContent();
public abstract void setHeightFitContent();
public abstract void setHeightStretch();
public abstract YogaValue getMinWidth();
public abstract void setMinWidth(float minWidth);
public abstract void setMinWidthPercent(float percent);
public abstract void setMinWidthMaxContent();
public abstract void setMinWidthFitContent();
public abstract void setMinWidthStretch();
public abstract YogaValue getMinHeight();
public abstract void setMinHeight(float minHeight);
public abstract void setMinHeightPercent(float percent);
public abstract void setMinHeightMaxContent();
public abstract void setMinHeightFitContent();
public abstract void setMinHeightStretch();
public abstract YogaValue getMaxWidth();
public abstract void setMaxWidth(float maxWidth);
public abstract void setMaxWidthPercent(float percent);
public abstract void setMaxWidthMaxContent();
public abstract void setMaxWidthFitContent();
public abstract void setMaxWidthStretch();
public abstract YogaValue getMaxHeight();
public abstract void setMaxHeight(float maxheight);
public abstract void setMaxHeightPercent(float percent);
public abstract void setMaxHeightMaxContent();
public abstract void setMaxHeightFitContent();
public abstract void setMaxHeightStretch();
public abstract float getAspectRatio();
public abstract void setAspectRatio(float aspectRatio);
@@ -373,6 +373,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetFlexBasisAutoJNI(mNativePointer);
}
public void setFlexBasisMaxContent() {
YogaNative.jni_YGNodeStyleSetFlexBasisMaxContentJNI(mNativePointer);
}
public void setFlexBasisFitContent() {
YogaNative.jni_YGNodeStyleSetFlexBasisFitContentJNI(mNativePointer);
}
public void setFlexBasisStretch() {
YogaNative.jni_YGNodeStyleSetFlexBasisStretchJNI(mNativePointer);
}
public YogaValue getMargin(YogaEdge edge) {
return valueFromLong(YogaNative.jni_YGNodeStyleGetMarginJNI(mNativePointer, edge.intValue()));
}
@@ -441,6 +453,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetWidthAutoJNI(mNativePointer);
}
public void setWidthMaxContent() {
YogaNative.jni_YGNodeStyleSetWidthMaxContentJNI(mNativePointer);
}
public void setWidthFitContent() {
YogaNative.jni_YGNodeStyleSetWidthFitContentJNI(mNativePointer);
}
public void setWidthStretch() {
YogaNative.jni_YGNodeStyleSetWidthStretchJNI(mNativePointer);
}
public YogaValue getHeight() {
return valueFromLong(YogaNative.jni_YGNodeStyleGetHeightJNI(mNativePointer));
}
@@ -457,6 +481,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetHeightAutoJNI(mNativePointer);
}
public void setHeightMaxContent() {
YogaNative.jni_YGNodeStyleSetHeightMaxContentJNI(mNativePointer);
}
public void setHeightFitContent() {
YogaNative.jni_YGNodeStyleSetHeightFitContentJNI(mNativePointer);
}
public void setHeightStretch() {
YogaNative.jni_YGNodeStyleSetHeightStretchJNI(mNativePointer);
}
public YogaValue getMinWidth() {
return valueFromLong(YogaNative.jni_YGNodeStyleGetMinWidthJNI(mNativePointer));
}
@@ -469,6 +505,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetMinWidthPercentJNI(mNativePointer, percent);
}
public void setMinWidthMaxContent() {
YogaNative.jni_YGNodeStyleSetMinWidthMaxContentJNI(mNativePointer);
}
public void setMinWidthFitContent() {
YogaNative.jni_YGNodeStyleSetMinWidthFitContentJNI(mNativePointer);
}
public void setMinWidthStretch() {
YogaNative.jni_YGNodeStyleSetMinWidthStretchJNI(mNativePointer);
}
public YogaValue getMinHeight() {
return valueFromLong(YogaNative.jni_YGNodeStyleGetMinHeightJNI(mNativePointer));
}
@@ -481,6 +529,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetMinHeightPercentJNI(mNativePointer, percent);
}
public void setMinHeightMaxContent() {
YogaNative.jni_YGNodeStyleSetMinHeightMaxContentJNI(mNativePointer);
}
public void setMinHeightFitContent() {
YogaNative.jni_YGNodeStyleSetMinHeightFitContentJNI(mNativePointer);
}
public void setMinHeightStretch() {
YogaNative.jni_YGNodeStyleSetMinHeightStretchJNI(mNativePointer);
}
public YogaValue getMaxWidth() {
return valueFromLong(YogaNative.jni_YGNodeStyleGetMaxWidthJNI(mNativePointer));
}
@@ -493,6 +553,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetMaxWidthPercentJNI(mNativePointer, percent);
}
public void setMaxWidthMaxContent() {
YogaNative.jni_YGNodeStyleSetMaxWidthMaxContentJNI(mNativePointer);
}
public void setMaxWidthFitContent() {
YogaNative.jni_YGNodeStyleSetMaxWidthFitContentJNI(mNativePointer);
}
public void setMaxWidthStretch() {
YogaNative.jni_YGNodeStyleSetMaxWidthStretchJNI(mNativePointer);
}
public YogaValue getMaxHeight() {
return valueFromLong(YogaNative.jni_YGNodeStyleGetMaxHeightJNI(mNativePointer));
}
@@ -505,6 +577,18 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable {
YogaNative.jni_YGNodeStyleSetMaxHeightPercentJNI(mNativePointer, percent);
}
public void setMaxHeightMaxContent() {
YogaNative.jni_YGNodeStyleSetMaxHeightMaxContentJNI(mNativePointer);
}
public void setMaxHeightFitContent() {
YogaNative.jni_YGNodeStyleSetMaxHeightFitContentJNI(mNativePointer);
}
public void setMaxHeightStretch() {
YogaNative.jni_YGNodeStyleSetMaxHeightStretchJNI(mNativePointer);
}
public float getAspectRatio() {
return YogaNative.jni_YGNodeStyleGetAspectRatioJNI(mNativePointer);
}
@@ -15,15 +15,33 @@ public interface YogaProps {
void setWidthPercent(float percent);
void setWidthAuto();
void setWidthMaxContent();
void setWidthFitContent();
void setWidthStretch();
void setMinWidth(float minWidth);
void setMinWidthPercent(float percent);
void setMinWidthMaxContent();
void setMinWidthFitContent();
void setMinWidthStretch();
void setMaxWidth(float maxWidth);
void setMaxWidthPercent(float percent);
void setWidthAuto();
void setMaxWidthMaxContent();
void setMaxWidthFitContent();
void setMaxWidthStretch();
/* Height properties */
@@ -31,15 +49,33 @@ public interface YogaProps {
void setHeightPercent(float percent);
void setHeightAuto();
void setHeightMaxContent();
void setHeightFitContent();
void setHeightStretch();
void setMinHeight(float minHeight);
void setMinHeightPercent(float percent);
void setMinHeightMaxContent();
void setMinHeightFitContent();
void setMinHeightStretch();
void setMaxHeight(float maxHeight);
void setMaxHeightPercent(float percent);
void setHeightAuto();
void setMaxHeightMaxContent();
void setMaxHeightFitContent();
void setMaxHeightStretch();
/* Margin properties */
@@ -81,6 +117,12 @@ public interface YogaProps {
void setFlexBasis(float flexBasis);
void setFlexBasisMaxContent();
void setFlexBasisFitContent();
void setFlexBasisStretch();
void setFlexDirection(YogaFlexDirection direction);
void setFlexGrow(float flexGrow);
@@ -13,7 +13,10 @@ public enum YogaUnit {
UNDEFINED(0),
POINT(1),
PERCENT(2),
AUTO(3);
AUTO(3),
MAX_CONTENT(4),
FIT_CONTENT(5),
STRETCH(6);
private final int mIntValue;
@@ -31,6 +34,9 @@ public enum YogaUnit {
case 1: return POINT;
case 2: return PERCENT;
case 3: return AUTO;
case 4: return MAX_CONTENT;
case 5: return FIT_CONTENT;
case 6: return STRETCH;
default: throw new IllegalArgumentException("Unknown enum value: " + value);
}
}
@@ -429,6 +429,28 @@ static void jni_YGNodeCopyStyleJNI(
YGNodeStyleSet##name##Auto(_jlong2YGNodeRef(nativePointer)); \
}
#define YG_NODE_JNI_STYLE_UNIT_PROP_AUTO_INTRINSIC(name) \
YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(name) \
YG_NODE_JNI_STYLE_UNIT_INTRINSIC(name)
#define YG_NODE_JNI_STYLE_UNIT_PROP_INTRINSIC(name) \
YG_NODE_JNI_STYLE_UNIT_PROP(name) \
YG_NODE_JNI_STYLE_UNIT_INTRINSIC(name)
#define YG_NODE_JNI_STYLE_UNIT_INTRINSIC(name) \
static void jni_YGNodeStyleSet##name##MaxContentJNI( \
JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { \
YGNodeStyleSet##name##MaxContent(_jlong2YGNodeRef(nativePointer)); \
} \
static void jni_YGNodeStyleSet##name##FitContentJNI( \
JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { \
YGNodeStyleSet##name##FitContent(_jlong2YGNodeRef(nativePointer)); \
} \
static void jni_YGNodeStyleSet##name##StretchJNI( \
JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer) { \
YGNodeStyleSet##name##Stretch(_jlong2YGNodeRef(nativePointer)); \
}
#define YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(name) \
static jlong jni_YGNodeStyleGet##name##JNI( \
JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer, jint edge) { \
@@ -483,13 +505,13 @@ YG_NODE_JNI_STYLE_PROP(jfloat, float, Flex);
YG_NODE_JNI_STYLE_PROP(jfloat, float, FlexGrow);
YG_NODE_JNI_STYLE_PROP(jfloat, float, FlexShrink);
YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(FlexBasis);
YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(Width);
YG_NODE_JNI_STYLE_UNIT_PROP(MinWidth);
YG_NODE_JNI_STYLE_UNIT_PROP(MaxWidth);
YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(Height);
YG_NODE_JNI_STYLE_UNIT_PROP(MinHeight);
YG_NODE_JNI_STYLE_UNIT_PROP(MaxHeight);
YG_NODE_JNI_STYLE_UNIT_PROP_AUTO_INTRINSIC(FlexBasis);
YG_NODE_JNI_STYLE_UNIT_PROP_AUTO_INTRINSIC(Width);
YG_NODE_JNI_STYLE_UNIT_PROP_INTRINSIC(MinWidth);
YG_NODE_JNI_STYLE_UNIT_PROP_INTRINSIC(MaxWidth);
YG_NODE_JNI_STYLE_UNIT_PROP_AUTO_INTRINSIC(Height);
YG_NODE_JNI_STYLE_UNIT_PROP_INTRINSIC(MinHeight);
YG_NODE_JNI_STYLE_UNIT_PROP_INTRINSIC(MaxHeight);
YG_NODE_JNI_STYLE_EDGE_UNIT_PROP_AUTO(Position);
@@ -870,6 +892,15 @@ static JNINativeMethod methods[] = {
{"jni_YGNodeStyleSetFlexBasisAutoJNI",
"(J)V",
(void*)jni_YGNodeStyleSetFlexBasisAutoJNI},
{"jni_YGNodeStyleSetFlexBasisMaxContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetFlexBasisMaxContentJNI},
{"jni_YGNodeStyleSetFlexBasisFitContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetFlexBasisFitContentJNI},
{"jni_YGNodeStyleSetFlexBasisStretchJNI",
"(J)V",
(void*)jni_YGNodeStyleSetFlexBasisStretchJNI},
{"jni_YGNodeStyleGetMarginJNI",
"(JI)J",
(void*)jni_YGNodeStyleGetMarginJNI},
@@ -917,6 +948,15 @@ static JNINativeMethod methods[] = {
{"jni_YGNodeStyleSetWidthAutoJNI",
"(J)V",
(void*)jni_YGNodeStyleSetWidthAutoJNI},
{"jni_YGNodeStyleSetWidthMaxContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetWidthMaxContentJNI},
{"jni_YGNodeStyleSetWidthFitContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetWidthFitContentJNI},
{"jni_YGNodeStyleSetWidthStretchJNI",
"(J)V",
(void*)jni_YGNodeStyleSetWidthStretchJNI},
{"jni_YGNodeStyleGetHeightJNI", "(J)J", (void*)jni_YGNodeStyleGetHeightJNI},
{"jni_YGNodeStyleSetHeightJNI",
"(JF)V",
@@ -927,6 +967,15 @@ static JNINativeMethod methods[] = {
{"jni_YGNodeStyleSetHeightAutoJNI",
"(J)V",
(void*)jni_YGNodeStyleSetHeightAutoJNI},
{"jni_YGNodeStyleSetHeightMaxContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetHeightMaxContentJNI},
{"jni_YGNodeStyleSetHeightFitContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetHeightFitContentJNI},
{"jni_YGNodeStyleSetHeightStretchJNI",
"(J)V",
(void*)jni_YGNodeStyleSetHeightStretchJNI},
{"jni_YGNodeStyleGetMinWidthJNI",
"(J)J",
(void*)jni_YGNodeStyleGetMinWidthJNI},
@@ -936,6 +985,15 @@ static JNINativeMethod methods[] = {
{"jni_YGNodeStyleSetMinWidthPercentJNI",
"(JF)V",
(void*)jni_YGNodeStyleSetMinWidthPercentJNI},
{"jni_YGNodeStyleSetMinWidthMaxContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMinWidthMaxContentJNI},
{"jni_YGNodeStyleSetMinWidthFitContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMinWidthFitContentJNI},
{"jni_YGNodeStyleSetMinWidthStretchJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMinWidthStretchJNI},
{"jni_YGNodeStyleGetMinHeightJNI",
"(J)J",
(void*)jni_YGNodeStyleGetMinHeightJNI},
@@ -945,6 +1003,15 @@ static JNINativeMethod methods[] = {
{"jni_YGNodeStyleSetMinHeightPercentJNI",
"(JF)V",
(void*)jni_YGNodeStyleSetMinHeightPercentJNI},
{"jni_YGNodeStyleSetMinHeightMaxContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMinHeightMaxContentJNI},
{"jni_YGNodeStyleSetMinHeightFitContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMinHeightFitContentJNI},
{"jni_YGNodeStyleSetMinHeightStretchJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMinHeightStretchJNI},
{"jni_YGNodeStyleGetMaxWidthJNI",
"(J)J",
(void*)jni_YGNodeStyleGetMaxWidthJNI},
@@ -954,6 +1021,15 @@ static JNINativeMethod methods[] = {
{"jni_YGNodeStyleSetMaxWidthPercentJNI",
"(JF)V",
(void*)jni_YGNodeStyleSetMaxWidthPercentJNI},
{"jni_YGNodeStyleSetMaxWidthMaxContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMaxWidthMaxContentJNI},
{"jni_YGNodeStyleSetMaxWidthFitContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMaxWidthFitContentJNI},
{"jni_YGNodeStyleSetMaxWidthStretchJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMaxWidthStretchJNI},
{"jni_YGNodeStyleGetMaxHeightJNI",
"(J)J",
(void*)jni_YGNodeStyleGetMaxHeightJNI},
@@ -963,6 +1039,15 @@ static JNINativeMethod methods[] = {
{"jni_YGNodeStyleSetMaxHeightPercentJNI",
"(JF)V",
(void*)jni_YGNodeStyleSetMaxHeightPercentJNI},
{"jni_YGNodeStyleSetMaxHeightMaxContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMaxHeightMaxContentJNI},
{"jni_YGNodeStyleSetMaxHeightFitContentJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMaxHeightFitContentJNI},
{"jni_YGNodeStyleSetMaxHeightStretchJNI",
"(J)V",
(void*)jni_YGNodeStyleSetMaxHeightStretchJNI},
{"jni_YGNodeStyleGetAspectRatioJNI",
"(J)F",
(void*)jni_YGNodeStyleGetAspectRatioJNI},
@@ -495,7 +495,8 @@ void FabricMountingManager::executeMount(
? allocatedViewsIterator->second
: defaultAllocatedViews;
if (allocatedViewsIterator == allocatedViewRegistry_.end()) {
LOG(ERROR) << "Executing commit after surface was stopped!";
LOG(ERROR) << "Executing commit after surface " << surfaceId
<< " was stopped!";
}
for (const auto& mutation : mutations) {
@@ -529,7 +530,7 @@ void FabricMountingManager::executeMount(
(maintainMutationOrder ? cppCommonMountItems : cppDeleteMountItems)
.push_back(CppMountItem::DeleteMountItem(oldChildShadowView));
if (allocatedViewTags.erase(oldChildShadowView.tag) != 1) {
LOG(ERROR) << "Emitting delete for unallocated view. "
LOG(ERROR) << "Emitting delete for unallocated view "
<< oldChildShadowView.tag;
}
break;
@@ -537,7 +538,7 @@ void FabricMountingManager::executeMount(
case ShadowViewMutation::Update: {
if (!isVirtual) {
if (!allocatedViewTags.contains(newChildShadowView.tag)) {
LOG(FATAL) << "Emitting update for unallocated view. "
LOG(ERROR) << "Emitting update for unallocated view "
<< newChildShadowView.tag;
}
@@ -605,7 +606,7 @@ void FabricMountingManager::executeMount(
bool shouldCreateView =
!allocatedViewTags.contains(newChildShadowView.tag);
if (shouldCreateView) {
LOG(ERROR) << "Emitting insert for unallocated view. "
LOG(ERROR) << "Emitting insert for unallocated view "
<< newChildShadowView.tag;
(maintainMutationOrder ? cppCommonMountItems
: cppUpdatePropsMountItems)
@@ -157,6 +157,11 @@ void FabricUIManagerBinding::startSurfaceWithSurfaceHandler(
}
scheduler->registerSurface(surfaceHandler);
auto mountingManager = getMountingManager("startSurfaceWithSurfaceHandler");
if (mountingManager != nullptr) {
mountingManager->onSurfaceStart(surfaceId);
}
surfaceHandler.start();
if (ReactNativeFeatureFlags::enableLayoutAnimationsOnAndroid()) {
@@ -167,14 +172,8 @@ void FabricUIManagerBinding::startSurfaceWithSurfaceHandler(
{
std::unique_lock lock(surfaceHandlerRegistryMutex_);
surfaceHandlerRegistry_.emplace(
surfaceHandler.getSurfaceId(), jni::make_weak(surfaceHandlerBinding));
surfaceId, jni::make_weak(surfaceHandlerBinding));
}
auto mountingManager = getMountingManager("startSurfaceWithSurfaceHandler");
if (!mountingManager) {
return;
}
mountingManager->onSurfaceStart(surfaceHandler.getSurfaceId());
}
// Used by non-bridgeless+Fabric
@@ -206,6 +205,11 @@ void FabricUIManagerBinding::startSurface(
scheduler->registerSurface(surfaceHandler);
auto mountingManager = getMountingManager("startSurface");
if (mountingManager != nullptr) {
mountingManager->onSurfaceStart(surfaceId);
}
surfaceHandler.start();
if (ReactNativeFeatureFlags::enableLayoutAnimationsOnAndroid()) {
@@ -214,17 +218,9 @@ void FabricUIManagerBinding::startSurface(
}
{
SystraceSection s2("FabricUIManagerBinding::startSurface::surfaceId::lock");
std::unique_lock lock(surfaceHandlerRegistryMutex_);
SystraceSection s3("FabricUIManagerBinding::startSurface::surfaceId");
surfaceHandlerRegistry_.emplace(surfaceId, std::move(surfaceHandler));
}
auto mountingManager = getMountingManager("startSurface");
if (!mountingManager) {
return;
}
mountingManager->onSurfaceStart(surfaceId);
}
// Used by non-bridgeless+Fabric
@@ -278,6 +274,11 @@ void FabricUIManagerBinding::startSurfaceWithConstraints(
scheduler->registerSurface(surfaceHandler);
auto mountingManager = getMountingManager("startSurfaceWithConstraints");
if (mountingManager != nullptr) {
mountingManager->onSurfaceStart(surfaceId);
}
surfaceHandler.start();
if (ReactNativeFeatureFlags::enableLayoutAnimationsOnAndroid()) {
@@ -286,19 +287,9 @@ void FabricUIManagerBinding::startSurfaceWithConstraints(
}
{
SystraceSection s2(
"FabricUIManagerBinding::startSurfaceWithConstraints::surfaceId::lock");
std::unique_lock lock(surfaceHandlerRegistryMutex_);
SystraceSection s3(
"FabricUIManagerBinding::startSurfaceWithConstraints::surfaceId");
surfaceHandlerRegistry_.emplace(surfaceId, std::move(surfaceHandler));
}
auto mountingManager = getMountingManager("startSurfaceWithConstraints");
if (!mountingManager) {
return;
}
mountingManager->onSurfaceStart(surfaceId);
}
// Used by non-bridgeless+Fabric
@@ -24,7 +24,7 @@ import org.junit.Test
@OptIn(UnstableReactNativeAPI::class)
class InteropModuleRegistryTest {
lateinit var underTest: InteropModuleRegistry
private lateinit var underTest: InteropModuleRegistry
@Before
fun setup() {
@@ -225,6 +225,13 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
return plain_.utf8(s);
}
std::u16string utf16(const String& str) override {
return plain_.utf16(str);
}
std::u16string utf16(const PropNameID& sym) override {
return plain_.utf16(sym);
}
Object createObject() override {
return plain_.createObject();
};
@@ -674,6 +681,15 @@ class WithRuntimeDecorator : public RuntimeDecorator<Plain, Base> {
return RD::utf8(s);
}
std::u16string utf16(const String& str) override {
Around around{with_};
return RD::utf16(str);
}
std::u16string utf16(const PropNameID& sym) override {
Around around{with_};
return RD::utf16(sym);
}
Value createValueFromJsonUtf8(const uint8_t* json, size_t length) override {
Around around{with_};
return RD::createValueFromJsonUtf8(json, length);
@@ -62,6 +62,107 @@ Value callGlobalFunction(Runtime& runtime, const char* name, const Value& arg) {
return f.call(runtime, arg);
}
// Given a sequence of UTF8 encoded bytes, advance the input to past where a
// 32-bit unicode codepoint as been decoded and return the codepoint. If the
// UTF8 encoding is invalid, then return the value with the unicode replacement
// character (U+FFFD). This decoder also relies on zero termination at end of
// the input for bound checks.
// \param input char pointer pointing to the current character
// \return Unicode codepoint
uint32_t decodeUTF8(const char*& input) {
uint32_t ch = (unsigned char)input[0];
if (ch <= 0x7f) {
input += 1;
return ch;
}
uint32_t ret;
constexpr uint32_t replacementCharacter = 0xFFFD;
if ((ch & 0xE0) == 0xC0) {
uint32_t ch1 = (unsigned char)input[1];
if ((ch1 & 0xC0) != 0x80) {
input += 1;
return replacementCharacter;
}
ret = ((ch & 0x1F) << 6) | (ch1 & 0x3F);
input += 2;
if (ret <= 0x7F) {
return replacementCharacter;
}
} else if ((ch & 0xF0) == 0xE0) {
uint32_t ch1 = (unsigned char)input[1];
if ((ch1 & 0x40) != 0 || (ch1 & 0x80) == 0) {
input += 1;
return replacementCharacter;
}
uint32_t ch2 = (unsigned char)input[2];
if ((ch2 & 0x40) != 0 || (ch2 & 0x80) == 0) {
input += 2;
return replacementCharacter;
}
ret = ((ch & 0x0F) << 12) | ((ch1 & 0x3F) << 6) | (ch2 & 0x3F);
input += 3;
if (ret <= 0x7FF) {
return replacementCharacter;
}
} else if ((ch & 0xF8) == 0xF0) {
uint32_t ch1 = (unsigned char)input[1];
if ((ch1 & 0x40) != 0 || (ch1 & 0x80) == 0) {
input += 1;
return replacementCharacter;
}
uint32_t ch2 = (unsigned char)input[2];
if ((ch2 & 0x40) != 0 || (ch2 & 0x80) == 0) {
input += 2;
return replacementCharacter;
}
uint32_t ch3 = (unsigned char)input[3];
if ((ch3 & 0x40) != 0 || (ch3 & 0x80) == 0) {
input += 3;
return replacementCharacter;
}
ret = ((ch & 0x07) << 18) | ((ch1 & 0x3F) << 12) | ((ch2 & 0x3F) << 6) |
(ch3 & 0x3F);
input += 4;
if (ret <= 0xFFFF) {
return replacementCharacter;
}
if (ret > 0x10FFFF) {
return replacementCharacter;
}
} else {
input += 1;
return replacementCharacter;
}
return ret;
}
// Given a valid 32-bit unicode codepoint, encode it as UTF-16 into the output.
void encodeUTF16(std::u16string& out, uint32_t cp) {
if (cp < 0x10000) {
out.push_back((uint16_t)cp);
return;
}
cp -= 0x10000;
uint16_t highSurrogate = 0xD800 + ((cp >> 10) & 0x3FF);
out.push_back(highSurrogate);
uint16_t lowSurrogate = 0xDC00 + (cp & 0x3FF);
out.push_back(lowSurrogate);
}
// Convert the UTF8 encoded string into a UTF16 encoded string. If the
// input is not valid UTF8, the replacement character (U+FFFD) is used to
// represent the invalid sequence.
std::u16string convertUTF8ToUTF16(const std::string& utf8) {
std::u16string ret;
const char* curr = utf8.data();
const char* end = curr + utf8.length();
while (curr < end) {
auto cp = decodeUTF8(curr);
encodeUTF16(ret, cp);
}
return ret;
}
} // namespace
Buffer::~Buffer() = default;
@@ -147,6 +248,16 @@ Value Runtime::createValueFromJsonUtf8(const uint8_t* json, size_t length) {
return parseJson.call(*this, String::createFromUtf8(*this, json, length));
}
std::u16string Runtime::utf16(const PropNameID& sym) {
auto utf8Str = utf8(sym);
return convertUTF8ToUTF16(utf8Str);
}
std::u16string Runtime::utf16(const String& str) {
auto utf8Str = utf8(str);
return convertUTF8ToUTF16(utf8Str);
}
Pointer& Pointer::operator=(Pointer&& other) {
if (ptr_) {
ptr_->invalidate();
@@ -399,6 +399,9 @@ class JSI_EXPORT Runtime {
const jsi::Object& obj,
size_t amount) = 0;
virtual std::u16string utf16(const String& str);
virtual std::u16string utf16(const PropNameID& sym);
// These exist so derived classes can access the private parts of
// Value, Symbol, String, and Object, which are all friends of Runtime.
template <typename T>
@@ -501,6 +504,11 @@ class JSI_EXPORT PropNameID : public Pointer {
return runtime.utf8(*this);
}
/// Copies the data in a PropNameID as utf16 into a C++ string.
std::u16string utf16(Runtime& runtime) const {
return runtime.utf16(*this);
}
static bool compare(
Runtime& runtime,
const jsi::PropNameID& a,
@@ -651,6 +659,11 @@ class JSI_EXPORT String : public Pointer {
return runtime.utf8(*this);
}
/// Copies the data in a JS string as utf16 into a C++ string.
std::u16string utf16(Runtime& runtime) const {
return runtime.utf16(*this);
}
friend class Runtime;
friend class Value;
};

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