Summary:
Changelog: [internal]
As part of recycle, we should delete state. This is a common pattern used in other components as well.
Reviewed By: shergin
Differential Revision: D21348782
fbshipit-source-id: a5dee2f4ccee9b19498db31dab1983d8879dca71
Summary:
There's a corner case where:
* The bridge gets invalidated, and native modules are cleaning up themselves (but not done yet)
* Something asks for a NativeModule instance - ideally it should just get nil at this point
* If TM Manager is invalidating, we get nil correctly, but we continue thru the old NativeModule lookup logic
* The latter will fail anyway, and would throw a redbox (RCTLogError).
So, if the bridge is invalidated, if TM Manager returns nil, we should just return nil for old NativeModule lookup.
The module of interest is RCTImageLoader, which was requested by RCTImageView on deallocation. The problem is RCTImageView got dealloc'ed **after** the bridge has been invalidated, so the lookup would always fail...
Bonus: RCTImageView should just keep a weak ref to the RCTImageLoader, so that:
* if the imageLoader is still alive on image dealloc, it can still access them (last minute "meaningless" cleanup)
* if the imageLoader is gone, then the image deallocation doesn't do anything
Changelog: [iOS] [Fixed] - Fix module lookup race condition on bridge invalidation.
Reviewed By: p-sun, sammy-SC
Differential Revision: D21371845
fbshipit-source-id: 862dc07de18ddbfb90e87e24b8dbd001147ddce4
Summary:
This diff removes the hostname from the loading bar and shrinks it down so it's inside the margins of the safe area view, never blocking app content inside the safe area.
Changelog: [General] [iOS] Shrink loading bar down to not cover safe area.
Reviewed By: shergin
Differential Revision: D21339480
fbshipit-source-id: e8416af63b7e06bcc21c7b6277d5d01d61eb3f73
Summary:
In D20836890 we no longer set `_contentView.frame` inside `layoutSubviews`.
This doesn't work well with component views that set their `contentView` after `updateLayoutMetrics` is called. For Example legacy interop which sets its contentView in the `finalizeUpdates` method. Other component views that set their contentView during initialisation are fine.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D21302108
fbshipit-source-id: 5adcf489e4e650ac04b84c836a8f8d6f55a77267
Summary:
This diff updates the loading banner to protect against showing percentages over 100%
Changelog: [Fixed] [iOS] Cap loading bar percentage at 100%
Reviewed By: shergin
Differential Revision: D21295809
fbshipit-source-id: 343f53acafa126800367444562730eff4ae67af4
Summary:
This diff reduces the minimum loading banner time and animation time to make the locating banner faster.
Changelog: [General] [iOS] Speed up loading banner animations
Reviewed By: PeteTheHeat
Differential Revision: D21290517
fbshipit-source-id: 111dff41df53b0246548e1da1db80c2188498a9c
Summary:
This diff fixes an issue where the initial "Loading from Metro..." message is flashed for a few milliseconds before the download progress kicks in. It's just jarring enough to be noticed and is ~600ms too fast to be read.
This diff adds a delay so that if the loading progress starts within 200ms we go straight to the progress.
Changelog: [Fixed] [iOS] Delay loading banner message to prevent flashing messages
Reviewed By: PeteTheHeat
Differential Revision: D21281870
fbshipit-source-id: d28c1eae01c2ac9d79f356f1870f17dbb22a9d84
Summary:
This diff fixes an issue where the loading banner message could update while the banner hide animation is going, catching your eye for no reason.
Changelog: [Fixed] [iOS] Do not update loading banner message while hiding
Reviewed By: PeteTheHeat
Differential Revision: D21280786
fbshipit-source-id: a10b33cd72f263d08eea6d8e94963514affbe24d
Summary:
This diff adds a hostname to the loading banner on iOS so it's clear which server you're loading from.
Changelog: [Added] [iOS] Added hostname to loading banner.
Reviewed By: PeteTheHeat
Differential Revision: D21280252
fbshipit-source-id: d7733c056f5fb63e32b247a4fa1476ab42c7da17
Summary:
Changelog: [Internal]
When there is a change coming from javascript, avoid triggering `onChange ` and `onSelectionChange` events since JavaScript already has these changes. This is only necessary for multiline text.
For changes coming through view commands, do not increment `_mostRecentEventCount`.
Reviewed By: shergin
Differential Revision: D21255228
fbshipit-source-id: e972dab0eb3dd21f611ee5c71d755bab593ae9cc
Summary:
Changelog: [Internal]
In `onKeyPress` event, we were not returning `key` property. This diff adds `key` property to `onKeyPress` event and removes other, redundant properties from `onKeyPress` event.
The implementation has been translated from Paper.
Reviewed By: shergin
Differential Revision: D21250411
fbshipit-source-id: f1e31381667acb9dec02d0b33883df8f8f5b2a4b
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/28730
Moving RuntimeExecutor out of react/utils and into its own subdir of ReactCommon. I'm doing this because I'm going to be pulling this into CatalystInstance on Android, and I don't want to pull in all the files we don't need there; also, this should hopefully make the OSS NDK stuff easier (this uses the react/utils prefix to export, and I'm not sure if you can include a '/' in a gradle module name?)
Changelog: [Internal]
Reviewed By: shergin, mdvacca
Differential Revision: D21098528
fbshipit-source-id: 9fbd72901ece522b1caec3ec34fafb8f9b327275
Summary:
Per discussion in https://github.com/react-native-community/releases/issues/186 the iOS `PlatformColor()` function is documented to use the semantic color names provided by the system. The referenced HIG documentation itself links to the `UIColor` documentation for semantic colors names. However, these names differ depending on if you are viewing the new Swift API docs or the Objective C docs. The current Objective C implementation in react-native assumes Objective C UIColor selector names that are suffixed 'Color'. But in Swift, Apple provides a Swift Extension on UIColor that makes aliases without the the 'Color' suffix and then makes the original selectors invalid presumably via `NS_UNAVAILABLE_SWIFT`.
Since both selector names are valid depending on if you are using Objective C or Swift, let's make both forms be legal for `PlatformColor()`. In `RCTConvert.m` there is a dictionary of legal selector names. The code already supports the ability to have names be aliases of other selectors via a RCTSelector metadata key. The change adds code to the initialization of the map: it iterates over the keys in the map, which are all ObjC style UIColor selectors, and creates aliases by duplicating the entries, creating key names by stripping off the ObjC "Color" suffix, adds the RCTSelector key referring to the original and then appends these new Swift aliases to the map.
## Changelog
[iOS] [Changed] - Allow iOS PlatformColor strings to be ObjC or Swift UIColor selectors
Pull Request resolved: https://github.com/facebook/react-native/pull/28703
Test Plan:
The PlatformColorExample.js is updated to use the new, shorter Swift selector names. There are still other examples in the same file and in unit tests that exercise the ObjC selector names.
<img width="492" alt="PlatformColor" src="https://user-images.githubusercontent.com/30053638/79809089-89ab7d00-8324-11ea-8a9d-120b92edeedf.png">
Reviewed By: shergin
Differential Revision: D21147404
Pulled By: TheSavior
fbshipit-source-id: 0273ec855e426b3a7ba97a87645859e05bcd4126
Summary:
This diff exports `isPackagerRunning` as a class method to be used without and instance.
Changelog: [Internal]
Reviewed By: cpojer
Differential Revision: D21094414
fbshipit-source-id: 44becb59e3c08d66e4992c4c1b32d6efcd4fe257
Summary:
Before the change, an incorrect (NaN or Inf) values in LayoutMetrics might force an early return in the `updateLayoutMetrics:oldMetrics:` method implementation. This was not correct because the rest of the method also didn't run in this case, so it might force some value to stale.
E.g., imagine we have an instruction that contains NaN size and `display: none`. Previously, the function might just return right before applying sizes and progress the stored "already applied" value of LayoutMetrics which will cause the view being visible even if it should not.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D21110644
fbshipit-source-id: 501319d7b1dcd5c18f27e0ceca3c8d207485c49b
Summary:
We need to break up the `uimanager` module in order to solve circular dependencies problem (which future diff would have otherwise).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D20885645
fbshipit-source-id: 8148bd934879802b076261ed86fa78acf0a07ed3
Summary:
We need to break up the `uimanager` module in order to solve circular dependencies problem (which future diff would have otherwise).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D20885163
fbshipit-source-id: 08eb1ba1d408fc0948e8d0da62380786a40973af
Summary:
This diff introduces a new "Open Debugger" menu item for VMs that support on device debugging and for opening the React DevTools in Flipper. Provided so that we don't drift too far from the Android code.
Changelog: [Internal]
Reviewed By: RSNara
Differential Revision: D20784270
fbshipit-source-id: 6bb16431d25a6c093a583e2e041b8cffa6765ddd
Summary:
Changelog: [Internal]
We don't use view command `setMostRecentEventCount`, let's get rid of it.
Reviewed By: JoshuaGross
Differential Revision: D21016600
fbshipit-source-id: 6491c063e9d6a89252300cb47c010b248e473f4b
Summary:
Now we can control the differentiator mode via MC.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: fkgozali
Differential Revision: D20978857
fbshipit-source-id: 13264948762f02f874d8d051c873d378062d6db4
Summary:
Calling `-[RCTRedBox showErrorMessage]` twice causes a crash
We used `-[UIViewController isBeingPresented]` to tell whether view controller is already presented.
But from the documentation:
> A Boolean value indicating whether the view controller is being presented.
Source: https://developer.apple.com/documentation/uikit/uiviewcontroller/2097564-beingpresented?language=objc#
---
So this means that if you present it, wait until presentation animation is finished and then call `-[RCTRedBox showErrorMessage]` again, following exception will be thrown.
```
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <UIViewController: 0x7fc33e422f50>.'
```
Changelog: Fix crash caused by presenting view controller twice from RCTRedBox
Reviewed By: PeteTheHeat
Differential Revision: D20946645
fbshipit-source-id: 763066e37db4e56efb0118b2e7867ad0724bae81
Summary:
Changelog: [Internal]
Calling `_backedTextInputView.attributedText = attributedString` causes cursor to be moved to the end of text input.
This applies to both, `UITextField` and `UITextView`.
This is not desired as when JS sets a new text, we don't want the cursor to be moved to the end of text input.
JS has the option to use view commands if it wishes to move cursor somewhere.
Reviewed By: JoshuaGross
Differential Revision: D20836201
fbshipit-source-id: 9234e54cfbc5fc206f723626988e505275788aae
Summary:
Changelog: [Internal]
UIKit uses either `UITextField` or `UITextView` as its UIKit element for `<TextInput>`. `UITextField` is for single line entry, `UITextView` is for multiline entry.
There is a problem with order of events when user types a character.
In `UITextField` (single line text entry), typing a character first triggers `onChange` event and then `onSelectionChange`. JavaScript depends on this order of events because it uses `mostRecentEventCount` from this even to communicate to native that it is in sync with changes in native.
In `UITextView` (multi line text entry), typing a character first triggers `onSelectionChange` and then `onChange`. As JS depends on the correct order of events, this can cause issues. An example would be a TextInput which changes contents based as a result of `onSelectionChange`. Those changes would be ignored as native will throw them away because JavaScript doesn't have the newest version.
Reviewed By: JoshuaGross
Differential Revision: D20836195
fbshipit-source-id: fbae3b6c0d388fc059ca2541ae980073b8e5f6c7
Summary:
This adds a `minimumSize` property to RCTRootView, and forwards any changes to it's shadow view. This **does not** change any default behaviour, as the default minimum size is `CGSizeZero` before & after this diff.
Changelog: [iOS][Internal] Add minimumSize to RCTRootView & RCTRootShadowView
Reviewed By: RSNara
Differential Revision: D20905456
fbshipit-source-id: a03f880e782891f60ef86b9c898965e05a5e796e
Summary:
## Problem
For some reason, D20831545 broke the `use_frameworks!` build of RNTester.
## Building RNTester
```
pushd ~/fbsource/xplat/js/react-native-github/RNTester && USE_FRAMEWORKS=1 pod install && open RNTesterPods.xcworkspace && popd;
```
## Error
I built RNTester locally, and the error was this:
```
Undefined symbols for architecture x86_64:
"facebook::jsi::HostObject::set(facebook::jsi::Runtime&, facebook::jsi::PropNameID const&, facebook::jsi::Value const&)", referenced from:
vtable for facebook::react::ObjCTurboModule in RCTImageEditingManager.o
vtable for facebook::react::ObjCTurboModule in RCTImageLoader.o
vtable for facebook::react::ObjCTurboModule in RCTImageStoreManager.o
"facebook::jsi::HostObject::getPropertyNames(facebook::jsi::Runtime&)", referenced from:
vtable for facebook::react::ObjCTurboModule in RCTImageEditingManager.o
vtable for facebook::react::ObjCTurboModule in RCTImageLoader.o
vtable for facebook::react::ObjCTurboModule in RCTImageStoreManager.o
ld: symbol(s) not found for architecture x86_64
```
## Fix
It looked like libraries that depend on "ReactCommon/turbomodule/core" weren't linking to JSI correctly. So, I modified all such Podspecs to also depend on "React-jsi":
```
arc rfr ' s.dependency "ReactCommon/turbomodule/core", version' ' s.dependency "ReactCommon/turbomodule/core", version\n s.dependency "React-jsi", version'
```
This seemed to do the trick. In buck, we'd fix this problem using exported_dependencies. I skimmed through cocoapods, and couldn't find such a configuration option there. So, I guess this will have to do?
Changelog:
[iOS][Fixed] - Fix Cocoapods builds of RNTester
Reviewed By: fkgozali, hramos
Differential Revision: D20905465
fbshipit-source-id: 60218c8274ec165752a428f2a7a9a546607c8fec
Summary:
Changelog: [Internal]
Setting `_borderLayer.frame` inside `-[RCTViewComponentView layoutSubviews]` causes unwanted animation because it is not wrapped in `CATransaction`.
Moving it to `-[RCTViewComponentView updateLayoutMetrics]` which is called inside `CATransaction`.
Reviewed By: shergin
Differential Revision: D20836890
fbshipit-source-id: 2048a25fd2edb8109f6275c1186c0adae4b9f504
Summary:
This allows the iOS device to be reloaded through the metro command line, besides the fact that whenever packagerServerHost is called, it will only get the IP address once when debugging.
## Changelog
[iOS] [Fixed] - Fixed connection of metro reload command to iOS device
Pull Request resolved: https://github.com/facebook/react-native/pull/28477
Test Plan:
- Build any react-native project in debug mode to an iOS device connected through USB
- Press the “r” key on the terminal that is running metro
- The device should now reload the project
Reviewed By: cpojer
Differential Revision: D20818462
Pulled By: TheSavior
fbshipit-source-id: 6d9792447d205223dad8fbd955518885427cbba8
Summary:
`RCTTurboModuleManager` will create a native `CallInvoker` for each ObjC NativeModule. This `CallInvoker` will be used to dispatch calls from JS to native. Before passing the native `CallInvoker` to the `ObjCTurboModule`, it'll first use `RCTCxxBridge decorateNativeCallInvoker` to get a bridge-aware decorated native `CallInvoker`. That way, the bridge remains informed about async TurboModule method calls that took place since the last time it was flushed. This ensures that we don't end up dispatching `onBatchComplete` any less with TurboModules on than we do with TurboModules off.
Changelog: [Internal]
Reviewed By: fkgozali
Differential Revision: D20831546
fbshipit-source-id: b2eb4e0097e0dabf8c4bd8fdc4c850a0858af699
Summary:
This is the first of three PRs related to enabling multi-bundle support in React Native. More details, motivation and reasoning behind it can be found in RFC [here](https://github.com/react-native-community/discussions-and-proposals/issues/152).
Logic responsible for installing globals was pulled out from `loadApplicationScript` to `initializeRuntime` since it should be ran only once, what was left was renamed to `loadBundle`.
It's based on dratwas work from [here](https://github.com/callstack/react-native/tree/feat/multibundle/split-load-application), but applied to current `master` to avoid rebasing 3-months old branch and issues that come with that.
## Changelog
[Internal] [Changed] - split `loadApplicationScript` into `initializeRuntime` and `loadBundle` to enable multi-bundle support in the future
Pull Request resolved: https://github.com/facebook/react-native/pull/27844
Test Plan: Initialized new RN app with CLI, set RN to build from source and verified the still app builds and runs OK using code from this branch.
Reviewed By: rickhanlonii
Differential Revision: D19888605
Pulled By: ejanzer
fbshipit-source-id: 24ace48ffe8978796591fe7c6cf53a61b127cce6
Summary:
## Context
For now, assume TurboModules doesn't exist.
**What happens when we call an async NativeModule method?**
Everytime JS calls an async NativeModule method, we don't immediately execute it. The legacy infra pushes the call into some queue managed by `MessageQueue.js`. This queue is "flushed" or "emptied" by the following events:
- **Flushed:** A C++ -> JS call. NativeModule async methods can called with an `onSuccess` and/or `onFail` callback(s). Calling `NativeToJsBridge::invokeCallback` to invoke one of these callbacks is one way for ObjC++/C++/Java to call into JS. Another way is via JSModule method calls, which are initiated by `NativeToJsBridge::callFunction`.
- **Flushed:** When `JSIExecutor::flush` is called. Since TurboModules don't exist, this only happens when we call `JSIExecutor::loadApplicationScript`.
- **Emptied:** When more than 5 ms have passed, and the queue hasn't been flushed/emptied, on the next async NativeModule method call, we add to the queue. Afterwards, we empty it, and invoke all the NativeModule method calls.
**So, what's the difference between flushed and emptied?**
> Note: These are two terms I just made up, but the distinction is important.
If the queue was "flushed", and it contained at least one NativeModule method call, `JsToNativeBridge` dispatches the `onBatchComplete` event. On Android, the UIManager module is the only module that listens to this event. This `onBatchComplete` event doesn't fire if the queue was "emptied".
**Why does any of this matter?**
1. TurboModules exist.
2. We need the TurboModules infra to have `JsToNativeBridge` dispatch `onBatchComplete`, which depends on:
- **Problem 1:** The queue being flushed on calls into JS from Java/C++/ObjC++.
- **Problem 2:** There being queued up NativeModule async method calls when the queue is flushed.
In D14656466, fkgozali fixed Problem 1 by making every C++/Java/Obj -> JS call from TurboModules also execute `JSIExecutor::flush()`. This means that, with TurboModules, we flush the NativeModule async method call queue as often as we do without TurboModules. So far, so good. However, we still have one big problem: As we convert more NativeModules to TurboModules, the average size of the queue of NativeModule method calls will become smaller and smaller, because more NativeModule method calls will be TurboModule method calls. This queue will more often be empty than not. Therefore, we'll end up dispatching the `onBatchComplete` event less often with TurboModules enabled. So, somehow, when we're about to flush the NativeModule method call queue, we need `JsToNativeBridge` to understand that we've executed TurboModule method calls in the batch. These calls would have normally been queued, which would have led the queue size to be non-zero. So if, during a batch, some TurboModule async method calls were executed, `JsToNativeBridge` should dispatch `onBatchComplete`.
**So, what does this diff do?**
1. Make `Instance` responsible for creating the JS `CallInvoker`.
2. Make `NativeToJsBridge` responsible for creating the native `CallInvoker`. `Instance` calls into `NativeToJsBridge` to get the native `CallInvoker`.
3. Hook up `CatalystInstanceImpl`, the Android bridge, with the new JS `CallInvoker`, and the new native `CallInvoker`. This fixes `onBatchComplete` on Android. iOS work is pending.
Changelog:
[Android][Fixed] - Ensure `onBatchComplete` is dispatched correctly with TurboModules
Reviewed By: mdvacca
Differential Revision: D20717931
fbshipit-source-id: bc3ccbd6c135b7f084edbc6ddb4d1e3c0c7e0875
Summary:
We are replacing inline-ed implementation with practically the same one implemented as the helper method.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20551409
fbshipit-source-id: fcc6f497cd240af65fba534051c217fe5746ce82
Summary:
An evolution of D20633188 but more performant.
There are three optimized paths before the slow path.
The first optimized path tries to pair identical nodes from old/new tree, and generate Update mutations, until we hit nodes that are different (indicating either a remove or an insert). This already existed.
The next two optimizations, introduced by Tim in his JS pseudocode, were inspired by ReactJS's diffing algorithm. They work in cases where the rest of the nodes are (1) all removals/deletes or (2) all creates+inserts.
Finally, if those final two optimized paths can't run, it's because there is a mix of delete+remove, create+insert, and "move" operations, mixed at the beginning, middle, and/or end of the list.
This has slightly better average/best-case complexity as the previous implementation.
In particularly pathological cases where all nodes are arbitrarily reordered, or reversed, for instance (ABCDE->EDCBA) the algorithm has the same complexity as the previous algorithm (quadratic).
For now iOS is pinned to the older differ
Changelog: [Internal] Experiment to optimize diffing algorithm in Fabric
Reviewed By: shergin
Differential Revision: D20684094
fbshipit-source-id: d29fba95a0328156c023e1c87804f23770ee1d91