Commit Graph
2958 Commits
Author SHA1 Message Date
Scott Wolchok ccb7dbe895 Stop using get_fbobjc_enable_exception_lang_compiler_flags_DEPRECATED in xplat
Summary:
Old deprecated function.

Changelog: [Internal]

Reviewed By: nlutsenko

Differential Revision: D20148856

fbshipit-source-id: 79d6fb97824b059e50f67ff5a0b4c38ec7a19469
2020-04-09 12:44:14 -07:00
Samuel Susla 00c4d950cf Implement event count for TextInput
Summary:
Changelog: [Internal]

Implementation of event count for Fabric's Text input.

Reviewed By: JoshuaGross

Differential Revision: D20800185

fbshipit-source-id: 988692cb2fc786649821cccb06e629b40b9b0479
2020-04-09 03:44:55 -07:00
Samuel Susla 0ef63d0cac Maintain selection and cursor location when setting string on TextInput
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
2020-04-09 03:44:55 -07:00
Samuel Susla 7b4889937c Switch order of onSelectionChange and onChange events send from native
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
2020-04-09 03:44:55 -07:00
Peter Argany 432868b0c0 Add minimumSize to RCTRootView & RCTRootShadowView
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
2020-04-08 12:48:07 -07:00
Ramanpreet Nara fd5de50aca Fix Cocoapods builds
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
2020-04-07 19:07:19 -07:00
Samuel Susla 4cbcee7567 Set _borderLayer.frame when border changes
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
2020-04-06 01:46:35 -07:00
Hein Rutjes e2c417f7cf Fix crash when enabling Performance Monitor on iOS 13.4 (#28512)
Summary:
This PR fixes a crash when opening the Performance Monitor on iOS 13.4.
Detailed info: https://github.com/facebook/react-native/issues/28414

## Changelog

`[iOS] [Fixed] - Fix crash when enabling Performance Monitor on iOS 13.4`

## How

This PR prevents the JavaScriptCore option from being set altogether.
This ensures that the performance monitor keeps working, but on iOS 13.4 and higher, it will no longer crash trying to show the GC usage.
Pull Request resolved: https://github.com/facebook/react-native/pull/28512

Test Plan:
Tested on iOS 13.4 (simulator):

![image](https://user-images.githubusercontent.com/6184593/77903803-c6370c00-7283-11ea-8b71-b6b6546c82f6.png)

Tested on iOS 13.1 (simulator)

![image](https://user-images.githubusercontent.com/6184593/77903499-41e48900-7283-11ea-9d14-83f67a3b7b77.png)

- Verified that the `setOption` was called, but the Performance Monitor didn't show any GC usage regardless.
- Identical PR https://github.com/expo/react-native/pull/21 has been shipped and tested in Expo Client 37

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

Reviewed By: PeteTheHeat

Differential Revision: D20851131

Pulled By: TheSavior

fbshipit-source-id: ff96301036e8487db59f95947bbe6841fe230e1e
2020-04-03 20:44:20 -07:00
Cristiano Santos f9df93385e Fixes iOS reload through metro "r" command key (#28477)
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
2020-04-03 12:11:16 -07:00
Ramanpreet Nara aef0ef4b31 Export Instance::getDecoratedNativeCallInvoker from RCTCxxBridge
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
2020-04-03 09:47:42 -07:00
Ramanpreet Nara 69698b25fc Codemod all getTurboModuleWithJsInvoker methods to accept a native CallInvoker
Summary:
To make iOS TurboModules integrate with the bridge's onBatchComplete event, they need to use a native CallInvoker. This call invoker is created by the `NativeToJsBridge`, and ObjCTurboModule will use this native CallInvoker to dispatch TurboModule method calls. This diff makes sure that ObjCTurboModules are created with that native CallInvoker.

## Script
```
var withSpaces = (...args) => args.join('\s*')

var regexString = withSpaces(
  '-',
  '\(',
  'std::shared_ptr',
  '<',
  '(?<turboModuleClass>(facebook::react::|react::|::|)TurboModule)',
  '>',
  '\)',
  'getTurboModuleWithJsInvoker',
  ':',
  '\(',
  'std::shared_ptr',
  '<',
  '(?<callInvokerClass>(facebook::react::|react::|::|)CallInvoker)',
  '>',
  '\)',
  '(?<jsInvokerInstance>[A-Za-z0-9]+)',
  'perfLogger',
  ':',
  '\(',
  'id',
  '<',
  'RCTTurboModulePerformanceLogger',
  '>',
  '\)',
  '(?<perfLoggerInstance>[A-Za-z0-9]+)',
  '{',
  'return',
  'std::make_shared',
  '<',
  '(?<specName>(facebook::react::|react::|::|)Native[%A-Za-z0-9]+SpecJSI)',
  '>',
  '\(',
  'self',
  ',',
  '\k<jsInvokerInstance>',
  ',',
  '\k<perfLoggerInstance>',
  '\)',
  ';',
  '}',
)

var replaceString = `- (std::shared_ptr<$<turboModuleClass>>)
    getTurboModuleWithJsInvoker:(std::shared_ptr<$<callInvokerClass>>)$<jsInvokerInstance>
                  nativeInvoker:(std::shared_ptr<$<callInvokerClass>>)nativeInvoker
                     perfLogger:(id<RCTTurboModulePerformanceLogger>)$<perfLoggerInstance>
{
  return std::make_shared<$<specName>>(self, $<jsInvokerInstance>, nativeInvoker, $<perfLoggerInstance>);
}`

const exec = require('../lib/exec');
const abspath = require('../lib/abspath');
const relpath = require('../lib/relpath');
const readFile = (filename) => require('fs').readFileSync(filename, 'utf8');
const writeFile = (filename, content) => require('fs').writeFileSync(filename, content);

function main() {
  const tmFiles = exec('cd ~/fbsource && xbgs -n 10000 -l getTurboModuleWithJsInvoker:').split('\n').filter(Boolean);

  tmFiles
    .filter((filename) => !filename.includes('microsoft-fork-of-react-native'))
    .map(abspath)
    .forEach((filename) => {
      const source = readFile(filename);
      const newSource = source.replace(new RegExp(regexString, 'g'), replaceString);

      if (source == newSource) {
        console.log(relpath(filename));
      }

      writeFile(filename, newSource);
    });
}

if (!module.parent) {
  main();
}
```

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D20809202

fbshipit-source-id: 5d39b3cacdaa5681b70ce1803351d0432dd74550
2020-04-03 02:27:10 -07:00
Samuel Susla 2c3a6ab5b2 Fix crash caused by <Modal> trying to present view controller twice
Summary:
Changelog: [Internal]

`_viewController` was being presented twice causing following exception

```
'Application tried to present modally an active controller <FBReactRootViewController: 0x7fe741818b80;
```

Reviewed By: shergin

Differential Revision: D20820395

fbshipit-source-id: 5c9489011e5f99d8bd37befbd544d2d55a650589
2020-04-02 12:50:21 -07:00
Samuel Susla 3d61dc9f36 Back out "Fix controlled TextInput with child nodes"
Summary:
Changelog: [Internal]

Original commit changeset: 1b8a2efabbfa

Original diff D20587681 breaks non-controlled text input.

Reviewed By: motiz88

Differential Revision: D20815935

fbshipit-source-id: 70577ed1e5701850ff0e30a6592945a31c2a8bec
2020-04-02 08:26:04 -07:00
maciej simka 6f627f684b Split loadApplicationScript into initializeRuntime and loadBundle (#27844)
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
2020-04-01 17:52:39 -07:00
Ramanpreet Nara 9b94a541d8 Get CallInvokers from the bridge
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
2020-04-01 11:39:18 -07:00
Samuel Susla 46722dcfc2 Swap left and right yoga position with start and end in RTL context
Summary:
Changelog: [Internal]

Paper swaps right and left in RTL setting, this logic is in [RCTShadowView.m](https://our.intern.facebook.com/intern/diffusion/FBS/browse/master/xplat/js/react-native-github/React/Views/RCTShadowView.m?commit=cdd504cfbee66ae0659495604c4ff7b5764a1d9e&lines=529-549).

For Fabric instead of doing it during yoga props assignment, I swap the left/right with start/end just before we pass yoga nodes to layout calculation.

Reviewed By: shergin

Differential Revision: D20420040

fbshipit-source-id: b777f2658f56c173743b2034b8b5059e3e0c9840
2020-04-01 05:42:20 -07:00
Emilis Baliukonis 232517a574 Implement nativePerformanceNow to improve Profiler API results (#27885)
Summary:
When experimenting with React Profiler API (https://reactjs.org/docs/profiler.html), I noticed that durations are integers without a debugger, but they are doubles with higher precision when debugger is attached. After digging into React Profiler code, I found out that it's using `performance.now()` to accumulate execution times of individual units of work. Since this method does not exist in React Native, it falls back to Javascript `Date`, leading to imprecise results.

This PR introduces `global.nativePerformanceNow` function which returns precise native time, and a very basic `performance` polyfill with `now` function.

This will greatly improve React Profiler API results, which is essential for profiling and benchmark tools.

Solves https://github.com/facebook/react-native/issues/27274

## Changelog

[General] [Added] - Implement `nativePerformanceNow` and `performance.now()`
Pull Request resolved: https://github.com/facebook/react-native/pull/27885

Test Plan:
```
const initialTime = global.performance.now();
setTimeout(() => {
  const newTime = global.performance.now();
  console.warn('duration', newTime - initialTime);
}, 1000);
```

### Android + Hermes

![Screenshot_1580198068](https://user-images.githubusercontent.com/13116854/73245757-af0d6c80-41b5-11ea-8130-dde14ebd41a3.png)

### Android + JSC

![Screenshot_1580199089](https://user-images.githubusercontent.com/13116854/73246157-92256900-41b6-11ea-87a6-ac222383200c.png)

### iOS

![Simulator Screen Shot - iPhone 8 - 2020-01-28 at 10 06 49](https://user-images.githubusercontent.com/13116854/73245871-f136ae00-41b5-11ea-9e31-b1eff5717e62.png)

Reviewed By: ejanzer

Differential Revision: D19888289

Pulled By: rickhanlonii

fbshipit-source-id: ab8152382da9aee9b4b3c76f096e45d40f55da6c
2020-03-31 10:23:51 -07:00
Valentin Shergin 8d3d8afa5b Fabric: Using executeSynchronouslyOnSameThread_CAN_DEADLOCK in MainRunLoopEventBeat
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
2020-03-30 19:35:08 -07:00
Rick Hanlon 011eb4cea5 Remove "Debug with Nuclide" option
Summary: This is no longer needed.

Reviewed By: cpojer

Differential Revision: D20722274

fbshipit-source-id: 5bc3104e90811d724f42aadbf137ab8eff718ca0
2020-03-30 10:09:20 -07:00
Joshua Gross 50a34bcd7f Optimize diff algorithm to produce fewer remove+insert ("move") paired instructions
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
2020-03-27 19:07:53 -07:00
Valentin Shergin 73448012cb Fabric: Fixing a deadlock in RCTSurfacePresenter
Summary:
This is another attempt to fix an issue very similar to T59424871. The previous attempt was in D19249490. I don't know why we don't see production crashes (stalls) but it happened to me (and not to me) in the debugger. The previous attempt didn't work because we still could have a deadlock because we tried to acquired shared mutex already owned exclusively by the `suspend` method.

Here is another approach: Instead of using one shared mutex, now we use two. One is similar to what we had and another that protects `suspend` and `resume`. Besides that, now we pass a Scheduler to functions that use that explicitly. This way we can be more explicit about acquiring mutexes and the overall flow of execution. The idea is: Now an arbitrary code that can be reentrant does not cover with mutexes, so the deadlock is not possible.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D20639228

fbshipit-source-id: 98515742f00f2ae94b50b585c9f1f0611e169ebe
2020-03-26 10:13:43 -07:00
generatedunixname89002005287564 ec2cfe98d2 Daily arc lint --take CLANGFORMAT
Reviewed By: zertosh

Differential Revision: D20666684

fbshipit-source-id: 32255ac7509e0257693969a7b4b044569af30df7
2020-03-26 05:22:59 -07:00
Kevin Gozali 25f7aea86c Replace fbsource// with // in xplat/js/ files [1]
Summary:
`fbsource//xplat` and `//xplat` are equivalent for FB BUCK targets. Removing extra prefix for consistency.

Changelog: [Internal]

Reviewed By: scottrice

Differential Revision: D20495655

fbshipit-source-id: a57b72f694c533e2e16dffe74eccb8fdec1f55f5
2020-03-25 21:55:47 -07:00
Peter Argany 72ac2125bc Fix retaining self in block in LogBox impl
Summary:
Logbox has a retain cycle (see linked task for my deeper investigation).

This diff doesn't fix the retain cycle, but it's just good practice to not retain self strongly in blocks.

Changelog: [iOS][Internal] Fix retaining self in block in LogBox implementation

Reviewed By: shergin

Differential Revision: D20630693

fbshipit-source-id: cf399495e9bcd1917932fcc0e9c9d2d2a32bf6f0
2020-03-25 12:25:49 -07:00
Ramanpreet Nara faff19a7c6 De-jank DevLoadingView
Summary:
## Problems
Repro steps:
1. Disable Fabric (because CMD + R doesn't work with Fabric right now).
2. Open up Marketplace and hit `CMD + OPT + R`
3. **Observe:** The progress bar doesn't show up right away. It also doesn't actually show progress.
https://pxl.cl/140g1

RN Support post: https://fb.workplace.com/groups/rn.support/permalink/3437652016283389/

## Fixes
The first problem is that progress bar doesn't actually show progress.

**Fix:** Bundle load progress is updated in `RCTCxxBridge`, where we first require `RCTDevLoadingView`, and then call its `updateProgress` method. Previously, we wouldn't  lazily load `RCTDevLoadingView`, it already didn't exist. Lazily loading `RCTDevLoadingView` causes the progress view to show up. Here: https://pxl.cl/140gt

If you look at the above video, you'll notice there are two stages to the progress bar: stage 1 displays the actual progress. Stage 2 prompts that we're downloading the JS bundle. As you can see, stage 1 and stage 2 have different background colors, even though both of them are green.

**Fix:** I adjusted the JS to match the Native color. Here: https://pxl.cl/140gT

We're almost there, but the progress bar is dismissed twice?

**Fix:** I dug into the code, and the reason why was because when we hit `CMD + R`, we invalidate the bridge, and immediately re-initialize it. This means that we asynchronously invalidate the old TurboModuleManager, and immediately create a brand new one. Therefore, two `RCTDevLoadingView` modules can (and do) exist at once. So, I moved `RCTDevLoadingView` to be an instance member of `FBReactModule`, to ensure that it doesn't get cleaned up and re-created when TurboModuleManager is deleted and re-created. This finally fixed the progress bar jank:
https://pxl.cl/140hn

Changelog:
[iOS][Fixed] - Remove RCTDevLoadingView jank

Reviewed By: rickhanlonii

Differential Revision: D20607815

fbshipit-source-id: 05825c67adaf3cfda70be0fa2dc92d413dc8921b
2020-03-25 12:09:40 -07:00
Peter Argany 421bc5fc7f Remove RCTExportModule log spam
Summary:
The bridge complains if modules aren't exported, which isn't really helpful with lazily loaded modules and turbo modules.

I considered only turning this off when TurboModules is enabled, but figured we'd be killing this soon anyways... If anyone feels strongly I can go that approach.

Changelog: [iOS][Internal] Remove RCTExportModule log spam

Reviewed By: shergin

Differential Revision: D20629575

fbshipit-source-id: d32d9fe244c4d06acfee982fca7c7f63da294dc5
2020-03-25 11:57:53 -07:00
Max Ovtsin 8721ee0a6b Get ReactiveNative compiled with Clang 10 (#28362)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/28362

Fixed a few compilation errors emitted by Clang 10.

Changelog:
[iOS] [Fixed] - Get ready for Clang 10

Differential Revision: D20549970

fbshipit-source-id: dc36a85d90d3e43a05f045feb57c6ab6ded67da7
2020-03-23 13:46:37 -07:00
Samuel Susla a40cfc05b8 Fix controlled TextInput with child nodes
Summary:
Changelog: [Internal]

# There are three changes in this diff

## _stateRevision is replaced with a BOOL
`_stateRevision` was protecting against setting attributed string that is already visible to the user. Previously this was ok because the change was only coming from native, any changes from JS were ignored.

Imagine following scenario:

1. User taps key.
2. Update state is called on component initiated by native.
3. New state is created with incremented revision by one.
4. `_stateRevision` gets set to new state's revision + 1.
5. Now JS wants to change something because it just learnt that user tapped the key.
6. New state is created again with incremented revision by one.
7. Update state is called on the component, but the change isn't applied to the text view because `_state->getRevision()` will equal `_stateRevision`.

By having a BOOL instead of number, we very explicitly mark the region in which we don't want state changes to be applied to text view.

## Calling [_backedTextInputView setAttributedText] move cursor to the end of text input
This is prevented by storing what the current selection is and applying it after `[_backedTextInputView setAttributedText]` is called.
This was previously invisible because JS wasn't changing contents of `_backedTextInputView`.

## Storing of previously applied JS attributed string in state

This is the mechanism used to detect when value of text input changes come from JavaScript. JavaScript sends text input value changes through props and as children of TextInput.
We compare what previously was set from JavaScript to what is currently being send from JavaScript and if they differ, this change is communicated to the component.
Previously only first attributed string send from JavaScript was send to the component.

# Problem

If children are used to set text input's value, then there is a case in which we can't tell what source of truth should be.

Let's take following example
We have a text field that allows only 4 characters, again this is only a problem if those 4 characters come as children, not as value.
This is a controller text input.

1. User types 1234.
2. User types 5th character.
3. JavaScript updates TextInput, saying that the content should stay 1234.
4. In `TextInputShadowNode` `hasJSUpdatedAttributedString` will be set to false, because previous JS value is the same as current JS value.

Reviewed By: shergin

Differential Revision: D20587681

fbshipit-source-id: 1b8a2efabbfa0fc87cba210570142d162efe61e6
2020-03-23 04:42:09 -07:00
Samuel Susla 56cf99a96e Validate selection range passed to setTextAndSelection
Summary:
Changelog: [Internal]

# Fabric

1. If `start` and `end` parameters in `setTextAndSelection` are -1, we don't move the cursor. Previously the cursor would be moved to beginning of text input.

2. In view commands, do not validate `eventCount`. It is passed in as undefined from JS because Fabric's text input doesn't use `eventCount`.

# Paper

1. If `start` and `end` parameters in `setTextAndSelection` are -1, we don't move the cursor. Previously the cursor would be moved to beginning of text input.

Reviewed By: shergin

Differential Revision: D20538290

fbshipit-source-id: c7aeddc25f58697254474058ce901df958321f7c
2020-03-22 06:11:35 -07:00
Valentin Shergin ad34c63d9e Fabric: Exposing RCTParagraphComponentView::attributedText
Summary:
The new prop on RCTParagraphComponentView is meant to be used only by external introspection tools, not the RN core.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: nscoding

Differential Revision: D20523078

fbshipit-source-id: 4c457d070fd2c172d681c5aa7f731d2d52bba291
2020-03-18 19:09:58 -07:00
Ramanpreet Nara 652fa1b8d4 Add a perfLogger argument to getTurboModuleWithJSInvoker:
Summary:
## Purpose
We must modify the `getTurboModuleWithJsInvoker:` method of all our NativeModules to also accept a `id<RCTTurboModulePerformanceLogger>` object. This performance logger object should then be forwarded to the `Native*SpecJSI` constructor.

## Script
Run the following script via Node:
```
var withSpaces = (...args) => args.join('\s*')

var regexString = withSpaces(
  '-',
  '\(',
  'std::shared_ptr',
  '<',
  '(?<turboModuleClass>(facebook::react::|react::|::|)TurboModule)',
  '>',
  '\)',
  'getTurboModuleWithJsInvoker',
  ':',
  '\(',
  'std::shared_ptr',
  '<',
  '(?<callInvokerClass>(facebook::react::|react::|::|)CallInvoker)',
  '>',
  '\)',
  'jsInvoker',
  '{',
  'return',
  'std::make_shared',
  '<',
  '(?<specName>(facebook::react::|react::|::|)Native[A-Za-z0-9]+SpecJSI)',
  '>',
  '\(',
  '(?<arg1>[A-Za-z0-9]+)',
  ',',
  '(?<arg2>[A-Za-z0-9]+)',
  '\)',
  ';',
  '}',
)

var replaceString = `- (std::shared_ptr<$<turboModuleClass>>)
    getTurboModuleWithJsInvoker:(std::shared_ptr<$<callInvokerClass>>)jsInvoker
                     perfLogger:(id<RCTTurboModulePerformanceLogger>)perfLogger
{
  return std::make_shared<$<specName>>($<arg1>, $<arg2>, perfLogger);
}`

const exec = (cmd) => require('child_process').execSync(cmd, { encoding: 'utf8' });
const abspath = (filename) => `${process.env.HOME}/${filename}`;
const relpath = (filename) => filename.replace(process.env.HOME + '/', '');
const readFile = (filename) => require('fs').readFileSync(filename, 'utf8');
const writeFile = (filename, content) => require('fs').writeFileSync(filename, content);

function main() {
  const tmFiles = exec('cd ~/fbsource && xbgs -n 10000 -l getTurboModuleWithJsInvoker:').split('\n').filter(Boolean);

  tmFiles
    .filter((filename) => !filename.includes('microsoft-fork-of-react-native'))
    .map(abspath)
    .forEach((filename) => {
      const source = readFile(filename);
      const newSource = source.replace(new RegExp(regexString, 'g'), replaceString);

      if (source == newSource) {
        console.log(relpath(filename));
      }

      writeFile(filename, newSource);
    });
}

if (!module.parent) {
  main();
}
```

Also, run: `pushd ~/fbsource && js1 build oss-native-modules-specs -p ios && js1 build oss-native-modules-specs -p android && popd;`

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D20478718

fbshipit-source-id: 89ee27ed8a0338a66a9b2dbb716168a4c4582c44
2020-03-18 11:01:15 -07:00
Samuel Susla 71c7e80bfd Add RTL support
Summary:
Changelog: [internal]

layoutDirectionPass down layoutDirection from `RCTSurfacePresenter` down to `YogaLayutableShadowNode`.

In `ParagraphShadowNode`, we propagate layoutDirection from yoga node to `TextAttributes.layoutDirection`.

Reviewed By: shergin

Differential Revision: D20420041

fbshipit-source-id: 86e01d31ea9415acb8579c44c470cac870ec1b8f
2020-03-17 14:09:28 -07:00
Samuel Susla 1f4535c175 Fix state.padding being out of sync with safe area view
Summary:
Changelog: [Internal]

# Problem

SafeAreaView is getting reused, its previous `safeAreaInsets` is top: 44, bottom: 34 so `safeAreaInsetsDidChange` doesn't get called because it doesn't change. Therefore state gets never updates because `safeAreaInsetsDidChange` is never called.

# Solution

Update state whenever a new state is assigned.

Reviewed By: shergin

Differential Revision: D20444198

fbshipit-source-id: 75d1458450c70d74647df4962ddad88d5f6a38d2
2020-03-16 02:43:29 -07:00
Samuel Susla c774cb8ec5 Remove unwanted animations
Summary:
Changelog: [internal]

# Problem
Assigning `CALayer.contents` implicitly animates the difference. As we keep `UIView` in recycle pool between usages, they keep their previous state. This was causing animation of border when the views were being reused.

# Solution
Wrapping application of mutations in `CATTransaction`.

Reviewed By: shergin

Differential Revision: D20442045

fbshipit-source-id: 214d6c422f23f399dec46b5bf1a38a7b64758160
2020-03-16 02:43:29 -07:00
Valentin Shergin 65d6f5afbb Fabric: Removing taking zIndex into account in hit-testing algorithm
Summary:
Now we have `zIndex` feature implemented in the Core, we don't need to take `view.layer.zIndex` into account when we do hit-testing, so now we don't need to sort *all subviews* on *all levels of hierarchy* every time we process touch down event.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D20425987

fbshipit-source-id: 025bd968ae948b9b0a4188845efc0de950fb5cdf
2020-03-15 20:52:12 -07:00
Valentin Shergin efa74c4c23 Fabric: Removing applying zIndex to layout.zIndex on iOS mounting layer
Summary:
Now we have `zIndex` feature implemented in the Core, we don't need to have it implemented on the mounting layer.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D20432156

fbshipit-source-id: f77b96919bab21b6628472b9fe58c5f4e3233318
2020-03-15 20:52:12 -07:00
generatedunixname89002005287564 1dc82a89d7 Daily arc lint --take CLANGFORMAT
Reviewed By: zertosh

Differential Revision: D20383094

fbshipit-source-id: 1dc497a98fd3b5962542735c5243d7ac9cd40da3
2020-03-11 21:41:04 -07:00
Andy Himberger 0c2db3256f timing fix for RCTCxxBridge.executeApplicationScript (#25991)
Summary:
In one of our test apps (actually on Mac not iOS, but same code) we very consistently crash in RCTCxxBridge.executeApplicationScript when js debugging, due to a timing issue where another thread has reset _reactInstance in between the null check on self->_reactInstance and usage of it on these lines:

```
    } else if (self->_reactInstance) {
      self->_reactInstance->loadScriptFromString(std::make_unique<NSDataBigString>(script),

```
The thread doing the reset is doing so switching the executorClass to WebSocketExecutor.
In the scenario we crash, the packager has a bundle ready and quickly returns it, though its a 34MB string being passed to NSDataBigString which must be taking long enough for the other thread to get a chance to reset.

## Changelog

[iOS] [Fixed] - Fix crash in RCTCxxBridge.executeApplicationScript
Pull Request resolved: https://github.com/facebook/react-native/pull/25991

Test Plan: Ran apple code path in normal from bundle file and js debugging scenarios.

Reviewed By: shergin

Differential Revision: D19186065

Pulled By: hramos

fbshipit-source-id: ae1d4b5b50b7fb33b74aba21addc2978e917479f
2020-03-10 18:15:42 -07:00
Valentin Shergin 0d6d58656a Fabric: EmptyLayoutMetrics does not contain invalid values anymore
Summary:
Before this change, fields of EmptyLayoutMetrics have some "invalid" values to allow us to compare equal them individually and get `false`. Turned out that having invalid values there might break some serialization layers, which is no good.
This change fixes that and adds explicit check for EmptyLayoutMetrics before running a comparison of individual fields.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: mdvacca

Differential Revision: D20324881

fbshipit-source-id: ab8e2a402f6bdfb393fc9b6789decb526fa94dfa
2020-03-10 17:00:41 -07:00
Samuel Susla cd0e4ecd7b Fix scrollView state contentOffset not being in sync with scrollView contentOffset
Summary:
Changelog: [Internal]

# Problem
`scrollView.state.contentOffset` was not in sync with actual `contentOffset` in case `contentOffset` is changed programatically.

# Solution
Add a flag `_isUserTriggeredScrolling` that indicates whether the current scroll is triggered by user or not. In case it isn't, update state.

Reviewed By: shergin

Differential Revision: D20098161

fbshipit-source-id: 021d916e7a45a24095a47bb8f84d1102226b672a
2020-03-10 12:47:20 -07:00
Adam Ernst 0c7bd388f0 Rename get_debug_preprocessor_flags
Summary:
The new name is get_preprocessor_flags_for_build_mode.

Changelog: [Internal]

Reviewed By: d16r

Differential Revision: D20351718

fbshipit-source-id: 67628ce81e7244f0f72af2d00d92842a649ff619
2020-03-09 18:28:27 -07:00
Valentin Shergin d0871d0a9a Clang format for all React Native files
Summary:
Buckle up, this enables clang-format prettifier for all files in React Native opensource repo.

Changelog: [Internal] Clang-format codemod.

Reviewed By: mdvacca

Differential Revision: D20331210

fbshipit-source-id: 8da0f94700be0c35bfd399e0c48f1706de04f5b1
2020-03-08 23:01:17 -07:00
Valentin Shergin a426c8dc77 Fabric: Using (un)wrapManagedObject in TextLayoutManager
Summary:
Investigating a crash, I spend half of an hour staring at `__bridge`, `__bridge_retained`, `CFRelease` and etc trying to understand is there a bug or not. Even if I think there was no bug there, it should not be this way. We have a nice abstraction around that madness we should use to make the code obvious.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D20260917

fbshipit-source-id: 2b511ebf46a78950c4720e749099134aed1dd890
2020-03-08 21:31:54 -07:00
Valentin Shergin 6530c90267 Fabric: Fixing a crash in RCTParagraphComponentView
Summary:
We don't know why exactly it happens but (seemingly) sometime Paragraph component receives an empty State object. This causes a crash because of unchecked access to an instance variable.
This diff introduces an assert in DEBUG mode and the check for prod.

Why is this happens? Hard to say, probably `layout()` method (which updates `State`) is not being called on ShadowNode. Why? One explanation can be that Yoga skips some subtree during layout because it starts from "visibility: hidden" component. We need to investigate it more and figure out what exactly going on and what should we need to improve besides the check. That's why we have an assertion.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D20260512

fbshipit-source-id: 4772855f41c6694be2ed6c0a19da40332d2bb8db
2020-03-06 20:06:32 -08:00
Ramanpreet Nara fe5ac2c3f9 Fix method signature
Summary:
All `NSNumber *` arguments of NativeModules need to be marked with `__nonnull`. Otherwise, when TurboModules are disabled, we run into a RedBox.

Changelog:
[iOS][Fixed] - Fix RCTDevLoadingView RedBox on Reload

Reviewed By: PeteTheHeat

Differential Revision: D20292188

fbshipit-source-id: a8a5d0b2070575d7728b6308b129196242671fe6
2020-03-06 12:44:56 -08:00
Logan Daniels b85cb0cf7a Back out "Moving towards UIWindowScene support"
Summary:
Original commit changeset: ae2a4478e2e7

Changelog: [Internal]

Reviewed By: hramos

Differential Revision: D20289851

fbshipit-source-id: 1167ce8f5135411b80630b523c91c10e2b7eece1
2020-03-05 15:58:44 -08:00
Logan Daniels f4538e5777 Back out "UIViewController-based status bar management"
Summary:
Original commit changeset: 9ae1384ee20a

Changelog: [Internal]

Reviewed By: hramos

Differential Revision: D20289822

fbshipit-source-id: 0db9d99bea458e150d33b3407c256b862dedb9c1
2020-03-05 15:58:43 -08:00
radex 80e6d672f3 UIViewController-based status bar management (#25919)
Summary:
{emoji:26a0} This is a follow up to https://github.com/facebook/react-native/issues/25425 -- which isn't merged yet… See https://github.com/facebook/react-native/pull/25919/files/2a286257a6553a80a34e2b1f1ad94fc7bae36ea3..125aedbedc234c65c8d1b2133b79e926ad6cf145 for actual diff

Currently, StatusBar native module manages the status bar on iOS globally, using `UIApplication.` APIs. This is bad because:

- those APIs have been deprecated for 4 years
- Apple really, really wants you to have an explicitly defined view controller, and control the status bar there
- it [breaks external native components](https://github.com/facebook/react-native/issues/25181#issuecomment-506792819)
- it's [not compatible with iPadOS 13 multi window support](https://github.com/facebook/react-native/issues/25181#issuecomment-506690818)

for those reasons I we should transition towards view controller-based status bar management.

With that, there is a need to introduce a default React Native root view controller, so I added `RCTRootViewController`. Using it is completely opt-in and there is no breaking change here. However I believe this should be a part of the template for new RN iOS apps.

Additionally, I added `RCTRootViewControllerProtocol` with hooks needed for RCTStatusBarManager to control the status bar. This means apps that want to have total control over their view controller can still opt in to react native VC-based status bar by conforming their root view controller to this protocol.

## Changelog

[iOS] [Added] - Added `RCTRootViewController` and `RCTRootViewControllerProtocol`
[iOS] [Fixed] - `UIViewControllerBasedStatusBarAppearance=YES` no longer triggers an error as long as you use `RCTRootViewController`
[iOS] [Fixed] - Status bar style is now correctly changed in multi-window iPadOS 13 apps if you use `RCTRootViewController` and set `UIViewControllerBasedStatusBarAppearance=YES`
Pull Request resolved: https://github.com/facebook/react-native/pull/25919

Test Plan: - Open RNTester → StatusBar → and check that no features broke

Reviewed By: fkgozali

Differential Revision: D16957766

Pulled By: hramos

fbshipit-source-id: 9ae1384ee20a06933053c4404b8237810f1e7c2c
2020-03-04 14:25:12 -08:00
radex b58e176af0 Moving towards UIWindowScene support (#28058)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/28058

I'm taking the first step towards supporting iOS 13 UIScene APIs and modernizing React Native not to assume an app only has a single window. See discussion here: https://github.com/facebook/react-native/issues/25181#issuecomment-505612941

The approach I'm taking is to take advantage of `RootTagContext` and passing it to NativeModules so that they can identify correctly which window they refer to. Here I'm just laying groundwork.

- [x] `Alert` and `ActionSheetIOS` take an optional `rootTag` argument that will cause them to appear on the correct window
- [x] `StatusBar` methods also have `rootTag` argument added, but it's not fully hooked up on the native side — this turns out to require some more work, see: https://github.com/facebook/react-native/issues/25181#issuecomment-506690818
- [x] `setNetworkActivityIndicatorVisible` is deprecated in iOS 13
- [x] `RCTPerfMonitor`, `RCTProfile` no longer assume `UIApplicationDelegate` has a `window` property (no longer the best practice) — they now just render on the key window

Next steps: Add VC-based status bar management (if I get the OK on https://github.com/facebook/react-native/issues/25181#issuecomment-506690818 ), add multiple window demo to RNTester, deprecate Dimensions in favor of a layout context, consider adding hook-based APIs for native modules such as Alert that automatically know which rootTag to pass

## Changelog

[Internal] [Changed] - Modernize Modal to use RootTagContext
[iOS] [Changed] - `Alert`, `ActionSheetIOS`, `StatusBar` methods now take an optional `surface` argument (for future iPadOS 13 support)
[iOS] [Changed] - RCTPresentedViewController now takes a nullable `window` arg
[Internal] [Changed] - Do not assume `UIApplicationDelegate` has a `window` property
Pull Request resolved: https://github.com/facebook/react-native/pull/25425

Test Plan:
- Open RNTester and:
- go to Modal and check if it still works
- Alert → see if works
- ACtionSheetIOS → see if it works
- StatusBar → see if it works
- Share → see if it works

Reviewed By: PeteTheHeat

Differential Revision: D16957751

Pulled By: hramos

fbshipit-source-id: ae2a4478e2e7f8d2be3022c9c4861561ec244a26
2020-03-04 14:25:12 -08:00
Samuel Susla 3ee1e5312a Back out "Rename measure to measureContent and pass it LayoutContext"
Summary:
Original commit changeset: 8928b59d5194

Changelog: [Internal]

Reviewed By: makovkastar

Differential Revision: D20246918

fbshipit-source-id: 0b9142d9bc4774a07304769126411a34cc8c33c5
2020-03-04 05:01:53 -08:00