Summary:
This adds native support for `Animated.event` on iOS.
**Test plan**
Tested in the native animated UIExplorer example that it works properly like on Android.
Closes https://github.com/facebook/react-native/pull/9598
Differential Revision: D4110331
fbshipit-source-id: 15748d23d0f475f2bcd1040ca3dca33e2620f058
Summary:
Explain the **motivation** for making this change. What existing problem does the pull request solve?
See https://github.com/facebook/react-native/issues/10506. A native `NSError` with `NSUnderlyingErrorKey` set causes a JSON stringify error from the websocket dispatcher if remote debugging is enabled.
**Test plan (required)**
I'm not familiar with the react native testing framework. Happy to add a test for this if someone can point me to where this part of the codebase is exercised :)
I did some spot checks with nil user dictionaries and nil underlying errors here. The case that this solves is testable using https://github.com/superseriouscompany/react-native-error-repro, specifically:
```objective-c
NSError *underlyingError = [NSError errorWithDomain:@"underlyingDomain" code:421 userInfo:nil];
NSError *err = [NSError errorWithDomain:@"domain" code:68 userInfo:@{@"NSUnderlyingError": underlyingError}];
reject(@"foo", @"bar", err);
```
Closes https://github.com/facebook/react-native/pull/10507
Differential Revision: D4080802
Pulled By: lacker
fbshipit-source-id: 93a41d9e9a710e406a6ccac214a5617271b4bede
Summary: This is a simple hook to allow native side to fetch any file under the js root folder via packager. Historically, only the `main.jsbundle` is fetched via the packager. This then allows fetching local file like a json file that lives under the same root js folder
Reviewed By: yungsters
Differential Revision: D4037730
fbshipit-source-id: a2d6eb5e30d148fee573d413fc4036d0189f4938
Summary:
Packager can take a long time to load and the progress is usually displayed in another window (Terminal). I'm adding support for showing a UI inside React Native app for packager's progress when loading a bundle.
This is how it will work:
1. React Native sends request to packager with `Accept: multipart/mixed` header.
2. Packager will detect that header to detect that client supports progress events and will reply with `Content-Type: multipart/mixed`.
3. While building the bundle it will emit chunks with small metadata (like `{progress: 0.3}`). In the end it will send the last chunk with the content of the bundle.
4. RN runtime will be receiving the events, for each progress event it will update the UI. The last chunk will be the actual bundle which will end the download process.
This workflow is totally backwards-compatible -- normally RN doesn't set the `Accept` header.
Reviewed By: mmmulani
Differential Revision: D3845684
fbshipit-source-id: 5b3d2c5a4c6f4718d7e5de060d98f17491e82aba
Summary:
First commit for Apple TV support: changes to existing Objective-C code so that it will compile correctly for tvOS.
Closes https://github.com/facebook/react-native/pull/9649
Differential Revision: D3916021
Pulled By: javache
fbshipit-source-id: 34acc9daf3efff835ffe38c43ba5d4098a02c830
Summary:
This fixes measuring of items in the main axis of a container. Previously items were in a lot of cases measured with UNSPECIFIED instead of AT_MOST. This was to support scrolling containers. The correct way to handle scrolling containers is to instead provide them with their own overflow value to activate this behavior. This is also similar to how the web works.
This is a breaking change. Most of your layouts will continue to function as before however some of them might not. Typically this is due to having a `flex: 1` style where it is currently a no-op due to being measured with an undefined size but after this change it may collapse your component to take zero size due to the implicit `flexBasis: 0` now being correctly treated. Removing the bad `flex: 1` style or changing it to `flexGrow: 1` should solve most if not all layout issues your see after this diff.
Reviewed By: majak
Differential Revision: D3876927
fbshipit-source-id: 81ea1c9d6574dd4564a3333f1b3617cf84b4022f
Summary:
If we use RCTLogError, we show a redbox with a native stacktrace before we can actually show the JS stacktrace (which is only done through dispatch_async). Instead use RCTLogWarn so its logged to console but not reported as a redbox.
Also fix call to RCTNSErrorFromJSErrorRef off the main thread RCTJSCExecutor.
Reviewed By: majak, mmmulani
Differential Revision: D3886813
fbshipit-source-id: 119d04858cb0c85c79e12ff8a79806711f8e0b27
Summary: Introduce `overflow:scroll` so that scrolling can be implemented without the current overflow:visible hackiness. Currently we use AT_MOST to measure in the cross axis but not in the main axis. This was done to enable scrolling containers where children are not constraint in the main axis by their parent. This caused problems for non-scrolling containers though as it meant that their children cannot be measured correctly in the main axis. Introducing `overflow:scroll` fixes this.
Reviewed By: astreet
Differential Revision: D3855801
fbshipit-source-id: 3c365f9e6ef612fd9d9caaaa8c650e9702176e77
Summary: Introduce `overflow:scroll` so that scrolling can be implemented without the current overflow:visible hackiness. Currently we use AT_MOST to measure in the cross axis but not in the main axis. This was done to enable scrolling containers where children are not constraint in the main axis by their parent. This caused problems for non-scrolling containers though as it meant that their children cannot be measured correctly in the main axis. Introducing `overflow:scroll` fixes this.
Reviewed By: astreet
Differential Revision: D3855801
fbshipit-source-id: 6077b0bcb68fe5ddd4aa22926acab40ff4d83949
Summary:
At the moment, posting RCTReloadNotification in any circumstance causes all RCTBridge instances to reload. This change scopes the notification to the bridge for which it was intended.
Closes https://github.com/facebook/react-native/pull/8762
Differential Revision: D3831914
fbshipit-source-id: ff29574f574ecd1a403057ddd0458dea38f0136e
Summary:
Include CSSLayout headers in the same way as other project headers, ie `#import <CSSLayout/CSSLayout.h>` becomes `#import "CSSLayout.h"`. CSSLayout is not a framework or system dependency, so shouldn't (AFAIK) be included with angle brackets. Doing so breaks framework builds, such as when RN is used as a pod in a swift project.
In combination with https://github.com/facebook/css-layout/pull/217 this fixes https://github.com/facebook/react-native/issues/9014 (specifically swift cocoapods projects). There is then no need for a separate CSSLayout pod subspec.
Tests run on the RN project in isolation (with changes inside `CSSLayout` itself also applied) and against a dummy swift project with RN included as a pod.
NB: This effectively reverts https://github.com/facebook/react-native/pull/9015 and may break non-swift cocoapods projects unless https://github.com/facebook/css-layout/pull/217 is merged and synced first.
Update: As discussed with alloy and emilsjolander, wrap these imports in a preprocess
Closes https://github.com/facebook/react-native/pull/9544
Differential Revision: D3821791
Pulled By: javache
fbshipit-source-id: d27ac8be9ce560d03479b43d3db740cd196c24da
Summary:
First of all,please forgive my poor english. LOL
When I use Promises as callBack,
I followed the guide to make a (RCTPromiseRejectBlock),in this RCTPromiseRejectBlock,
from the guide I should add a (NSString)code a (NSString)message and an (NSError) to a RCTPromiseRejectBlock.
As what did guide said I just make a NSError with
```
NSError *error=[NSError errorWithDomain:@"native stroage error" code:402 userInfo:@{@"data":key}];
```
As you can see, I want to transfer some data in this callback.But I just found the (userInfo) of NSError didn't composed to a RCTPromiseRejectBlock.
So I check out the source code of RCTUtil ,I found this
```
// TODO: Can we just replace RCTMakeError with this function instead?
NSDictionary<NSString *, id> *RCTJSErrorFromCodeMessageAndNSError(NSString *code,
NSString *message,
NSError *__nullable error)
{
NSString *errorMessage;
Closes https://github.com/facebook/react-native/pull/9519
Differential Revision: D3821334
Pulled By: javache
fbshipit-source-id: 0fa40dd93932af70123b8f8a20a5c7dc5afdd6ac
Summary:
The overflow prop needs to be set on the shadow view so that it can make its way into the layout engine. In some situations, the value of the overflow prop affects the calculations of the layout engine.
**Test plan (required)**
Verified in a test app that the `overflow` prop makes its way into the layout engine. Also, my team's app is currently using this change.
Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/9659
Differential Revision: D3790552
fbshipit-source-id: 61513ece63ae214f48c6cb6f40fb29757a0ac706
Summary:
**Motivation:** We have a project that dynamically changes classes in runtime. This component is initialised within the React Native context. Therefor `RCTBatchedBridge` copies the classes before changes are made to them. While React Native is running, changes are made to the classes dynamically. When the project reloads the `RCTBatchedBridge`, it now has an invalid list of classes containing trash pointers. This causes the project to crash on https://github.com/facebook/react-native/blob/master/React/Base/RCTBatchedBridge.m#L288 with EXC_BAD_ACCESS in the DEBUG-mode.
**Solution:** Copy the class list on each reload to get the current state. Since this is only a DEBUG-feature the overhead of this should not be a major issue.
Closes https://github.com/facebook/react-native/pull/9541
Differential Revision: D3775012
Pulled By: javache
fbshipit-source-id: d55fa0742ca100d8018c73080230cf718aa5a7e9
Summary:
Ground work for allowing `font-variant`s. Currently allows switching between `tabular-nums` and `proportional-nums`. I will need guidance on how to test this, and a few pointers on code style (new to Objective C, and had to make one or two hacks).
Closes https://github.com/facebook/react-native/pull/9045
Reviewed By: majak
Differential Revision: D3664338
Pulled By: javache
fbshipit-source-id: 032f326c37ee6150348da2b33b6a3fc1988e8920
Summary:
When you call `-[RCTConvert UIFont:withFamily:...]` with a non-nil font object, we'll try to use the existing font object for system information. On iOS9+ which uses the San Francisco font, `[UIFont fontNamesForFamilyName:]` doesn't return anything useful, so we need to make sure that we detect this as a system font and use the appropriate methods. This issues is made worse by the fact that RCTTextView and friends recreate the font property for every attribute that is set (pretty horrible perf-wise).
This fixes https://github.com/facebook/react-native/issues/2140
Reviewed By: sahrens
Differential Revision: D3662751
fbshipit-source-id: c528e8945ed361a922c03f861d3c0b584658573b
Summary: Mirrors Android's support for multiple sources for Image, allowing us to fetch new images as the size of the view changes.
Reviewed By: mmmulani
Differential Revision: D3615134
fbshipit-source-id: 3d0bf2b75f63a4379e0e49f2dab9aea351b31d5f
Summary:
This uses `[UIImage imageNamed:]` to load local assets that are bundled using `require('../image/path.png')` and makes sure it is done synchronously on the main queue to prevent images from flickering. This improves user experience a lot when using large local images and prevents icon flickers to match the behaviour of most native apps.
This adds to methods to the ImageLoader protocol, one to tell if the image loader must be executed on the url cache queue and one to tell if the result of the image loader should be cached. I then use these to make the LocalImageLoader bypass the url cache queue and avoid caching images twice.
Note that this doesn't affect debug builds since images are loaded from the packager.
I'm not sure if we want to still support async loading of local images as I'm not sure how much of a perf difference this will make. Maybe someone at fb can benchmark this see how it affects your apps but there wasn't a noticeable one in mine. Also I only enabled this for loading png and jpg im
Closes https://github.com/facebook/react-native/pull/8102
Reviewed By: bnham
Differential Revision: D3433647
Pulled By: javache
fbshipit-source-id: 37bd6aff20c0465c163db3cdbcaeaedff55f7b1f
Summary: Instead of the somewhat odd concept of a "packager running predicate", just expose a class method for generating a JS bundle URL given a host, root, and options. This can be used by consumers that need custom behavior.
Reviewed By: javache
Differential Revision: D3564185
fbshipit-source-id: b1a7e66a2dada6a9eefe783b12b03fca7a330be3
Summary: The docs for this new method explain what it does.
Differential Revision: D3556890
fbshipit-source-id: b075e750cdd1e7354e0a26c03b3fd74cca52aeb7
Summary:
- Avoid using `+initialize`, use dispatch_once instead; it should be equivalent but more performant.
- Don't even let the `isPackagerRunning:` and `guessPackagerHost` methods exist unless `RCT_DEV` is on; they didn't do anything interesting when it is off.
Reviewed By: javache
Differential Revision: D3556645
fbshipit-source-id: 7dcdb4ae27f6625010e15846d757269f6f04155c
Summary: Include the actual scheme instead of "non-file".
Reviewed By: javache
Differential Revision: D3555812
fbshipit-source-id: 3ae0490f2d8fae01a551ba2877789dc15818fc50
Summary:
WebView component detect phone numbers in html as URL links by default. But sometimes we don't want this behavior.
This PR add dataDetectorTypes as a prop of WebView, so one can specify value of this prop as one or more of phoneNumber/link/address/calendarEvent/none/all
This prop maps to UIWebView.dataDetectorTypes
Closes https://github.com/facebook/react-native/pull/8743
Differential Revision: D3556440
fbshipit-source-id: 55f01d2cdd785381f261a9dc931aa9311f0ad1d4
Summary: The loader should be a utility that stands alone. The bridge uses the loader, not the other way around.
Reviewed By: bnham
Differential Revision: D3546157
fbshipit-source-id: 91016afb629df1f8c83c8fca6f42649be0b046b0
Summary:
This diff exposes a new experimental method `[RCTJavaScriptLoader +attemptSynchronousLoadOfBundleAtURL:sourceLength:error:]`. It may be used if you know that a specific call site must load its JavaScript synchronously, or else fail entirely.
This new API will succeed for file URLs that point to a RAM bundle. It will fail for non-RAM-bundle files and for HTTP URLs.
This also cleans up the error domain and codes for this class. This should be the only externally visible change from this diff if you don't use the new API: the codes and domains you receive from the API may change slightly. They were pretty sloppy and undocumented before, so I think this change is for the better.
Reviewed By: bnham
Differential Revision: D3545956
fbshipit-source-id: 30e65f4e8330d2d68f3f50ade077fdc1db4a435e
Summary:
By default we run the the JS display link, even if there are no modules listening. Given that most listeners will be lazily constructed, let's make it paused by default.
Since RCTTiming almost never unpauses due to some long-lived timers, implement a sleep timer that pauses the displaylink but uses an NSTimer to wake up in time.
Reviewed By: mhorowitz
Differential Revision: D3235044
fbshipit-source-id: 4a340fea552ada1bd8bc0d83b596a7df6f992387
Summary:
Currently React Native codebase treats JS stack traces as array of dictionaries.
This diff switches the Red Box to use new `RCTJSStackFrame` for internal data representation, while keeping the exposed API unchanged. The next step would be to replace the rest of manual parsing and usage of dictionaries.
The new class has ability to parse the stack from raw strings or dictionaries.
Depends on D3429031
Reviewed By: javache
Differential Revision: D3473199
fbshipit-source-id: 90d2a4f5e8e054b75c99905f35c2ee54927bb311
Summary: This leaves no optional methods on `RCTJavaScriptExecutor`, which is certainly a good thing.
Reviewed By: majak
Differential Revision: D3518915
fbshipit-source-id: e606b9076c3299f81a225a181ea244148a1832cb
Summary: It's not widely used, and you can do something equivalent anyway by using existing public API.
Reviewed By: javache
Differential Revision: D3518896
fbshipit-source-id: 6995a5d840aecfff4ffd78ac43f3f592a4f47f91
Summary: Reading four bytes is not slow. Don't bother dispatching for that.
Reviewed By: javache
Differential Revision: D3518405
fbshipit-source-id: 910079cec2a1f624dd71760438765bd035055229
Summary: No need to have these way at the top; they're not used until later.
Reviewed By: majak
Differential Revision: D3518364
fbshipit-source-id: 3e7461665e90dea5c6d323d45b1ffb11fb610b09
Summary: No need to keep it open; it just makes it harder to reason about error handling.
Reviewed By: majak
Differential Revision: D3518200
fbshipit-source-id: dc1af6eb0f75de7e9f73513ed1dd522048f76670
Summary:
Thanks for submitting a pull request! Please provide enough information so that others can review your pull request:
(You can skip this if you're fixing a typo or adding an app to the Showcase.)
Explain the **motivation** for making this change. What existing problem does the pull request solve?
Prefer **small pull requests**. These are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.
**Test plan (required)**
Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI.
Make sure tests pass on both Travis and Circle CI.
**Code formatting**
Look around. Match the style of the rest of the codebase. See also the simple [style guide](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#style-guide).
For more info, see the ["Pull Requests" section of our "Contributing" guidelines](https://github.com/facebook/react-native/blob/mas
Closes https://github.com/facebook/react-native/pull/7535
Differential Revision: D3509757
fbshipit-source-id: 70ff6c9c137c766ccb1173921f08571f48cb4f0b
Summary:
Implemented automatic IP detection for iOS, based on #6345 and #6362.
As the previous pull requests did, this works by writing the IP address of the host to a file.
Closes https://github.com/facebook/react-native/pull/8091
Differential Revision: D3427657
Pulled By: javache
fbshipit-source-id: 3f534c9b32c4d6fb9615fc2e2c3c3aef421454c5
Summary:
After cleaning up JS SourceMap code, these native methods are not needed anymore.
On iOS it saves another 30+ Mb during development.
Reviewed By: javache, astreet
Differential Revision: D3348975
fbshipit-source-id: a68ae9b00b4dbaa374b421029ae676fc69ae5a75
Summary:
This diff refactors the view update process into two stages:
1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager.
2. The `didUpdateReactSubviews` method is called, which actually inserts the reactSubviews into the view hierarchy.
This simplifies a lot of the hacks we had for special-case treatment of subviews: In many cases we don't want to actually insert `reactSubviews` into the parentView, and we had a bunch of component-specific solutions for that (typically overriding all of the reactSubviews methods to store views in an array). Now, we can simply override the `didUpdateReactSubviews` method for those views to do nothing, or do something different.
Reviewed By: wwjholmes
Differential Revision: D3396594
fbshipit-source-id: 92fc56fd31db0cfc66aac3d1634a4d4ae3903085
Summary:
This is a followup for "Add Shortcut "Double R" to Reload JS in iOS".
Please see the previous two revisions:[[ D3371536 | D3371536 ]], [[ D3343907 | D3343907 ]]
In previous revisions, we only tested with the iOS UIExplorer app, without testing in the iOS Catalyst app, where the key shortcuts we added are always invoked in TextInput components. It's due to a bug with the `UIApplicationDelegate`. Just fix this bug in this revision and successfully tested in the Catalyst app.
Reviewed By: mkonicek
Differential Revision: D3391045
fbshipit-source-id: 8b76fbfe7592218b02dd22502d25eebbc59f3cbc
Summary:
As per https://twitter.com/olebegemann/status/738656134731599872, our use of "main thread" to mean "main queue" seems to be unsafe.
This diff replaces the `NSThread.isMainQueue` checks with dispatch_get_specific(), which is the recommended approach.
I've also replaced all use of "MainThread" terminology with "MainQueue", and taken the opportunity to deprecate the "sync" param of `RCTExecuteOnMainThread()`, which, while we do still use it in a few places, is incredibly unsafe and shouldn't be encouraged.
Reviewed By: javache
Differential Revision: D3384910
fbshipit-source-id: ea7c216013372267b82eb25a38db5eb4cd46a089
Summary:
Allows developers to specify headers to include in the HTTP request
when fetching a remote image. For example, one might leverage this
when fetching an image from an endpoint that requires authentication:
```
<Image
style={styles.logo}
source={{
uri: 'http://facebook.github.io/react/img/logo_og.png',
headers: {
Authorization: 'someAuthToken'
}
}}
/>
```
Note that the header values must be strings.
Works on iOS and Android.
**Test plan (required)**
- Ran a small example like the one above on iOS and Android and ensured the headers were sent to the server.
- Ran a small example to ensure that \<Image\> components without headers still work.
- Currently using this code in our app.
Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/7338
Reviewed By: javache
Differential Revision: D3371458
Pulled By: nicklockwood
fbshipit-source-id: cdb24fe2572c3ae3ba82c86ad383af6d85157e20
Summary:
Enable double tap R on iOS, consistent with Android.
Keep the existing Cmd+R on iOS because people are already used to it.
Make Cmd+Key and Double Key both invalid when focus is in textview or textfield.
Also try to add Cmd+R in Android, but seems no good.
Reviewed By: nicklockwood
Differential Revision: D3343907
fbshipit-source-id: 68f7e3b0393711c137e1d932db33e1b6a2a19e09
Summary: This will make error messages more helpful.
Reviewed By: javache
Differential Revision: D3292400
fbshipit-source-id: d1e0bb24593058b75422824c0d351ede1320029e
Summary: AppState now subclasses NativeEventEmitter instead of using global RCTDeviceEventEmitter.
Reviewed By: javache
Differential Revision: D3310488
fbshipit-source-id: f0116599223f4411307385c0dab683659d8d63b6
Summary:
On iPad we may get two touch cancel events in direct succession. They would have the same coalescing key, which would result in unsuccesful attempt to coalesce them.
This diff fixes it by making sure two cancel events cannot have the same coalescing key.
(An alternative fix would be implementing coalescing logic for cancel events, but that sounds more complicated. It would be neccessary if there is a legit scenario where big number of cancel events are emitted in succesion.)
Reviewed By: javache
Differential Revision: D3292405
fbshipit-source-id: 1f269771dc81fdd637cf6ac3ee4725e5e2fec679
Summary:
This is a solution for the problem I raised in https://www.facebook.com/groups/react.native.community/permalink/768218933313687/
I've added a new native base class, `RCTEventEmitter` as well as an equivalent JS class/module `NativeEventEmitter` (RCTEventEmitter.js and EventEmitter.js were taken already).
Instead of arbitrary modules sending events via `bridge.eventDispatcher`, the idea is that any module that sends events should now subclass `RCTEventEmitter`, and provide an equivalent JS module that subclasses `NativeEventEmitter`.
JS code that wants to observe the events should now observe it via the specific JS module rather than via `RCTDeviceEventEmitter` directly. e.g. to observer a keyboard event, instead of writing:
const RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
RCTDeviceEventEmitter.addListener('keyboardWillShow', (event) => { ... });
You'd now write:
const Keyboard = require('Keyboard');
Keyboard.addListener('keyboardWillShow', (event) => { ... });
Within a component, you can also use the `Subscribable.Mixin` as you would previously, but instead of:
this.addListenerOn(RCTDeviceEventEmitter, 'keyboardWillShow', ...);
Write:
this.addListenerOn(Keyboard, 'keyboardWillShow', ...);
This approach allows the native `RCTKeyboardObserver` module to be created lazily the first time a listener is added, and to stop sending events when the last listener is removed. It also allows us to validate that the event strings being observed and omitted match the supported events for that module.
As a proof-of-concept, I've converted the `RCTStatusBarManager` and `RCTKeyboardObserver` modules to use the new system. I'll convert the rest in a follow up diff.
For now, the new `NativeEventEmitter` JS module wraps the `RCTDeviceEventEmitter` JS module, and just uses the native `RCTEventEmitter` module for bookkeeping. This allows for full backwards compatibility (code that is observing the event via `RCTDeviceEventEmitter` instead of the specific module will still work as expected, albeit with a warning). Once all legacy calls have been removed, this could be refactored to something more elegant internally, whilst maintaining the same public interface.
Note: currently, all device events still share a single global namespace, since they're really all registered on the same emitter instance internally. We should move away from that as soon as possible because it's not intuitive and will likely lead to strange bugs if people add generic events such as "onChange" or "onError" to their modules (which is common practice for components, where it's not a problem).
Reviewed By: javache
Differential Revision: D3269966
fbshipit-source-id: 1412daba850cd373020e1086673ba38ef9193050
Summary:
Modules which call JS methods directly, or use `sendDeviceEventWithName:`, can trigger effects in JS without ever being referenced from the JS code. This breaks some assumptions in my earlier diff about when modules can be lazily loaded.
Pending a better solution, I've put explicit `init` methods in these modules to ensure they are eagerly initialized (the downside to this is that they'll still be initialized even if they are never used).
Reviewed By: javache
Differential Revision: D3258232
fb-gh-sync-id: f925bc2e5339c1fbfcc244d4613062c5ab848fc2
fbshipit-source-id: f925bc2e5339c1fbfcc244d4613062c5ab848fc2
Summary:
Previously, if a module implemented `setBridge:` we assumed that it needs to be initialised on the main thread. This assumption was not really warranted however, and it was a barrier to deferring module initialization.
This diff tweaks the rules so that only modules that override `init` or `constantsToExport**` are assumed to require main thread initialization, and others can be created lazily when they are first used.
WARNING: this will be a breaking change to any 3rd party modules that are assuming `setBridge:` is called on the main thread. Those modules should be rewritten to move any code that requires the main thread into `init` or `constantsToExport` instead.
`**` We will also be examining whether `constantsToExport` can be done lazily, but for now any module that uses it will still be created eagerly when the bridge starts up.
Reviewed By: javache
Differential Revision: D3240682
fb-gh-sync-id: 48f309e3158bbccb52141032baf70def3e609371
fbshipit-source-id: 48f309e3158bbccb52141032baf70def3e609371
Summary: Using customDirectEventTypes or customBubblingEventTypes causes a viewmanager to be initialized at app start. This diff deprecates those methods and removes their usage from RCTScrollViewManager.
Reviewed By: majak
Differential Revision: D3218973
fb-gh-sync-id: 295bef3be9623b49b0cdcbf8a56e10d9b28126d9
fbshipit-source-id: 295bef3be9623b49b0cdcbf8a56e10d9b28126d9
Summary:
Now that we support initializing the bridge off the main thread, some of the assumptions in the bridge setup process are no longer safe.
In particular we were assuming that the JS executor and injected modules could always be synchronously initialized within bridge init, but that is only safe if those modules don't need to be set up on the main thread.
The setup for those modules was sync-dispatching to the main thread if bridge init happened on a background thread, and this lead to a deadlock under certain circumstances.
Reviewed By: javache
Differential Revision: D3224162
fb-gh-sync-id: 7319b70f541a46ef932cfe4f776e7e192f3ce1e8
fbshipit-source-id: 7319b70f541a46ef932cfe4f776e7e192f3ce1e8
Summary:When JSC throws an error on startup (e.g. a SyntaxError) or when invoking a method that is not caught by RCTExceptionsManager, we previously just reported is a native error, with a (useless) native stack trace in the redbox. This changes that behaviour to report a JS stacktrace.
The same issue was previously reported here: https://github.com/facebook/react-native/pull/5677
Reviewed By: majak
Differential Revision: D3037387
fb-gh-sync-id: 06f8333e0eb50dcef0b26284754262301b8a5f08
fbshipit-source-id: 06f8333e0eb50dcef0b26284754262301b8a5f08
Summary:Turns our using the same coalescing key until a person removes all fingers off screen is not ideal.
It doesn't work in a case where the first finger starts moving on screen and then a second finger joins it later (almost any pinch gesture),
since we would try to coalesce move events from the start when only one finger was touching screen with events where two fingers were moving on screen.
That doesn't work and results in a crash.
I've changed the logic for generating the coalescing key in order to prevent this.
We no longer have a single key for a single gesture, but we change the key each time amount of fingers increases ("touchStart") or decreases ("touchEnd").
Reviewed By: javache
Differential Revision: D3138275
fb-gh-sync-id: c32230ba401819fe3a70d1752b286d849520be89
fbshipit-source-id: c32230ba401819fe3a70d1752b286d849520be89
Summary:D3092867 / 1d3db4c5dc caused deadlock when chrome debugging was turned on, so it was reverted as D3128586 / 144dc30661.
The reason: I was calling `[_bridge dispatchBlock:^{ [self flushEventsQueue]; } queue:RCTJSThread];` from main thread and expecting it will `dispatch_async` to another,
since a held lock was being accessed the dispatched block and was released after the dispatch.
Turns out `RCTWebSocketExecutor` (which is used when chrome debugger is turned on) executes all blocks dispatched this way to `RCTJSThread` synchronously on the main thread.
This resulted in a deadlock. The "dispatched" block was trying to acquired lock which held by the same thread in the dispatching phase.
A fix for this is pretty simple. We will release the lock before dispatching the block.
However it's not super straightforward to see this won't introduce some race condition in a case with two threads where we would end up with events not being processed.
My thinking why that shouldn't happen goes like this: We could get in a bad state if `flushEventsQueue` would run on JS thread while `sendEvent:` is running on MT.
(I don't have a specific example how, maybe it's not possible. However when I show this case is safe we know we are good.)
The way how locking is setup in this diff the only possible scenario where these two threads would execute in these methods concurrently is JS holding the lock and MT going to enqueue another block on JS thread (since that's outside of "locked" zone).
But this scenarion can never happen, since if MT is about to enqueue the block on JS thread it means there cannot be a not yet fully executed block on JS thread.
Therefore nothing bad can happen.
So this diff brings back the reverted diff and adds to it the fix for the deadlock.
Reviewed By: javache
Differential Revision: D3130375
fb-gh-sync-id: 885a166f2f808551d7cd4e4eb98634d26afe6a11
fbshipit-source-id: 885a166f2f808551d7cd4e4eb98634d26afe6a11
Summary:The 200ms timeout was causing resource issues and causing a lot of overhead when you're not running the devtools, since it will basically create a new socket every 200ms.
Also clean up the way we do logging so it's completely compiled out in prod, and standardize all the names we use for threading to lowercase react.
Reviewed By: frantic
Differential Revision: D3115975
fb-gh-sync-id: e6e51c0621d8e9fc4eadb864acd678b8b5d322a1
fbshipit-source-id: e6e51c0621d8e9fc4eadb864acd678b8b5d322a1
Summary:Previously, (mostly touch and scroll) event handling on iOS worked in a hybrid way:
* All incoming coalesce-able events would be pooled and retrieved by js thread in the beginning of its frame (all of this happens on js thread)
* Any non-coalesce-able event would be immediately dispatched on a js thread (triggered from main thread), and if there would be pooled coalesce-able events they would be immediately dispatched at first too.
This behavior has a subtle race condition, where two events are produced (on MT) in one order and received in js in different order.
See https://github.com/facebook/react-native/issues/5246#issuecomment-198326673 for further explanation of this case.
The new event handling is (afaik) what Android already does. When an event comes we add it into a pool of events and dispatch a block on js thread to inform js there are events to be processed. We keep track of whether we did so, so there is at most one of these blocks waiting to be processed. When the block is executed js will process all events that are in pool at that time (NOT at time of enqueuing the block).
This creates a single way of processing events and makes it impossible to process them in different order in js.
The tricky part was making sure we don't coalesce events across gestures/different scrolls. Before this was achieved by knowing that gestures and scrolls start/end with non-coalesce-able event, so the pool never contained events that shouldn't be coalesced together. That "assumption" doesn't hold now.
I've re-added `coalescingKey` and made touch and scroll events use it to prevent coalescing events of the same type that should remain separate in previous diffs (see dependencies).
On top of it it decreases latency in events processing in case where we get only coalesce-able events. Previously these would be processed at begging of the next js frame, even when js would be free and could process them sooner. This delay is done, since they would get processed as soon as the enqueued block would run.
To illustrate this improvement let's look at these two systraces.
Before: https://cloud.githubusercontent.com/assets/713625/14021417/47b35b7a-f1d3-11e5-93dd-4363edfa1923.png
After: https://cloud.githubusercontent.com/assets/713625/14021415/4798582a-f1d3-11e5-8715-425596e0781c.png
Reviewed By: javache
Differential Revision: D3092867
fb-gh-sync-id: 29071780f00fcddb0b1886a46caabdb3da1d5d84
fbshipit-source-id: 29071780f00fcddb0b1886a46caabdb3da1d5d84
Summary: This was previously removed in D2884587, but we will need it going forward. See D3092867 for reasons why it's necessary again.
Reviewed By: javache
Differential Revision: D3092848
fb-gh-sync-id: 0d10dbac4148fcc8e035d32d8eab50f876d99e88
fbshipit-source-id: 0d10dbac4148fcc8e035d32d8eab50f876d99e88
Summary:Interface to `RCTBatchedBridge` was being declared in two different implementation files. This is suboptimal, since it makes it hard to mock that class in a test.
So I've merged and moved these two definitions in `RCTBridge+Private.h`, so it's still obvious it's a private class, but can be included if you really need it.
Reviewed By: javache
Differential Revision: D3126135
fb-gh-sync-id: 173e4c5c2925be387b92deb7f99952ca7bf28588
fbshipit-source-id: 173e4c5c2925be387b92deb7f99952ca7bf28588
Summary:`flowIDMap` lives on the bridge to map from the IDs used for the flow events in
JS and the ones generated by `RCTProfile` in the native side.
It was being accessed from multiple threads (the various modules' queues in the
bridge and the JS thread), so we lock before touching it.
Reviewed By: javache
Differential Revision: D3102745
fb-gh-sync-id: 93d012d124e8b5d1a390c10a98ef5e3a068ccf63
fbshipit-source-id: 93d012d124e8b5d1a390c10a98ef5e3a068ccf63
Summary:It was hard to understand which parts of the shadowview API are designed to be called only on the root view, and which were applicable to any view.
This diff extracts rootview-specific logic out into a new RCTRootShadowView class.
Reviewed By: majak
Differential Revision: D3063905
fb-gh-sync-id: ef890cddfd7625fbd4bf5454314b441acdb03ac8
shipit-source-id: ef890cddfd7625fbd4bf5454314b441acdb03ac8
Summary: For RAM bundling we don't want to hold the entire bundle in memory as that approach doesn't scale. Instead we want to seek and read individual sections as they're required. This rev does that by detecting the type of bundle we're dealing with by reading the first 4 bytes of it. If we're dealing with a RAM Bundle we bail loading.
Reviewed By: javache
Differential Revision: D3026205
fb-gh-sync-id: dc4c745d6f00aa7241203899e5ba136915efa6fe
shipit-source-id: dc4c745d6f00aa7241203899e5ba136915efa6fe
Summary:I've tested this manually, but I'm not sure how to write a test for this. Hopefully someone can help out there. The least I could do is provide a starting point for a PR to be accepted.
Additionally, I've renamed the existing `NSLineBreakMode` enum converter (inside `RCTConvert`) to use dashes in the names instead of camelcase (eg: `word-wrapping` instead of `wordWrapping`).
Fixes#6338
Closes https://github.com/facebook/react-native/pull/6339
Differential Revision: D3052391
Pulled By: nicklockwood
fb-gh-sync-id: 1536dfc139d7995095e9ee9d5f13ca86f90783c5
shipit-source-id: 1536dfc139d7995095e9ee9d5f13ca86f90783c5
Summary: This diff adds support for initializing the bridge on an arbitrary thread. This is helpful if you want to defer bridge creation, or prevent it from delaying your app startup.
Reviewed By: javache
Differential Revision: D2965725
fb-gh-sync-id: 8065fa89e850031c72ee4427351300986985e9de
shipit-source-id: 8065fa89e850031c72ee4427351300986985e9de
Summary:Initializing native modules can block the main thread for tens of milliseconds when it starts up, making it difficult to instantiate the bridge on demand without causing a performance blip.
This diff splits up the initialization of modules so that - although they still happen on the main thread - they don't block the thread continuously.
Reviewed By: javache
Differential Revision: D2965438
fb-gh-sync-id: 38c9c9d281e4672b5874d68b57d4c60d1d268344
shipit-source-id: 38c9c9d281e4672b5874d68b57d4c60d1d268344
Summary: The module initialization process is complex and full of race conditions. This diff adds a set of unit tests that verify that modules setup happens in the correct order, and enforces all the various conditions for main/background init.
Reviewed By: javache
Differential Revision: D2994145
fb-gh-sync-id: 92ea84508cdeeb280ff0fb9e9b2dffa8dbc37e66
shipit-source-id: 92ea84508cdeeb280ff0fb9e9b2dffa8dbc37e66
Summary: This property is now in the bridge.
Reviewed By: tadeuzagallo
Differential Revision: D2985894
fb-gh-sync-id: 38821e0c5998bc96fc8f6164fbbc82c721f5c5ad
shipit-source-id: 38821e0c5998bc96fc8f6164fbbc82c721f5c5ad
Summary: This makes room for local development without touching OSS code.
Reviewed By: tadeuzagallo
Differential Revision: D2986122
fb-gh-sync-id: 2f23088a078b0f0fb4b74946490fd5b67b01c0ac
shipit-source-id: 2f23088a078b0f0fb4b74946490fd5b67b01c0ac
Summary:This adds a `takeSnapshot` method to UIManager that can be used to capture screenshots as an image.
The takeSnapshot method accepts either 'screen', 'window' or a view ref as an argument.
You can also specify the size, format and quality of the captured image.
I've added an example of capturing a screenshot at UIExplorer > Snapshot / Screenshot.
I've also added an example of sharing a screenshot to the UIExplorer > ActionSheetIOS demo.
Reviewed By: javache
Differential Revision: D2958351
fb-gh-sync-id: d2eb93fea3297ec5aaa312854dd6add724a7f4f8
shipit-source-id: d2eb93fea3297ec5aaa312854dd6add724a7f4f8
Summary:
This commit adds the delegate hooks so that local notifications get
passed onto the JS and adds a new event listener type for local
notifications.
Also add functions to clear local notifications
Closes https://github.com/facebook/react-native/pull/2084
Reviewed By: svcscm
Differential Revision: D2908096
Pulled By: nicklockwood
fb-gh-sync-id: 759d299ea35abea177e72934076297d666d3ea20
shipit-source-id: 759d299ea35abea177e72934076297d666d3ea20
Summary:
public
Lazy export of module constants required a sync dispatch to the main thread, which was deadlocking in some of our projects.
This moves the constants export to the initial bridge init, which may slightly increase initial startup time, but avoids the deadlock.
Reviewed By: javache
Differential Revision: D2911295
fb-gh-sync-id: 0d14a629ac4fc7ee21acd293c09595c18232659b
shipit-source-id: 0d14a629ac4fc7ee21acd293c09595c18232659b
Summary:
public
Expose JS hooks to create flow events in systrace (the nice arrows to show async work flow) +
add support to the showing all the work enqueued from the JS thread as added in D2743733
Depends on D2743733
Reviewed By: jspahrsummers
Differential Revision: D2815293
fb-gh-sync-id: 4278f61a67a6e78cf2704bacce34b1389328c6df
Summary:
This is a final diff in the stack, which makes us not send a bazillion events to js after it's been busy while an user dragged his finger on a screen (resulting in ~two events per frame).
I made "touchMove" event to be coalescable, which makes us not send anything while dragging (since this makes both scroll events and touch move events coalesced and not being send until either next js frame or the next different touch event occurs).
This change is far from perfect. The event name is a hard coded string and the coalescing works with some (reasonable) assumptions on internal structure of these touch events. Which may or may not be really true. It would be great if someone could comment on these.
I'm thinking about making the touches more strongly typed. Any thoughts on this?
public
___
//This diff is part of a larger stack. For high level overview what's going on jump to D2884593.//
Reviewed By: nicklockwood
Differential Revision: D2884595
fb-gh-sync-id: f3c2f13430679e2bf52e0c7a3689650b3acae42f
Summary:
This diff finally makes touch events to be emitted to js from the same object as scroll events. Thanks to changes in previous diffs this means the js will now process them in the right order.
This diff on its own would cause us to send events to js on every frame while dragging a finger on the screen. This is something we tried to avoid with event coalescing in the past, and gets fixed in the following diff D2884595.
public
___
**This diff is part of a larger stack. This is a high level overview about what’s going on here.**
This stack of diffs fixes an issue where scroll events and touch events wouldn’t be processed in the correct order on js side.
Current state of world:
* touch events are send to js immediately when they happen (this makes js respond to touches as soon as possible)
* scroll events are buffered, coalesced and send at the beginning of each js frame (coalescing helps in a case where js is busy processing for several native frames and would get all scroll event for that period afterwards)
How did I change this?
1. I’ve made touch events go through the same class every other event (scroll events included) go, RCTEventDispatcher. This gives us a single place to handle all events.
2. I’ve changed RCTEventDispatcher to flush all buffered events every time it gets a touch event before dispatching the touch. This fixes the original ordering issue.
3. I’ve made “touchMove” behave the same way as scroll events do - they are buffered and coalesced. Since “touchMove” events are fired as often as scroll events (while you drag your finger around), doing only 2. would bring back the issue buffering was fixing.
All of this together effectively still keeps the order of events right, avoids overloading js in the important case we care about. The only downside is an increased latency for “touchMove” events, since they are to longer send to js immediately.
(Even better solution would be changing the native->js event passing system to be pull based instead of push based. That way js would always request touches that has happened since the last time it has asked, which would make it get them as soon as it’s possible to process them and native could do coalescing at that point.
However this change has a much bigger scope, so I’m going with this stack of diffs for now.)
Reviewed By: nicklockwood
Differential Revision: D2884593
fb-gh-sync-id: 749a4dc6256f93fde0d8733687394b080ddd4484
Summary:
This diff adds an implementation of `RCTEvent` protocol which represents touch events.
It's basically a copy of this code: c14cc123d5/React/Base/RCTTouchHandler.m (L194-L196)
which is replaced using `RCTTouchEvent` in the next diff (D2884593).
public
___
//This diff is part of a larger stack. For high level overview what's going on jump to D2884593.//
Reviewed By: nicklockwood
Differential Revision: D2884592
fb-gh-sync-id: e35addcf15a7012f89644200a08f5856c7f57299
Summary:
Currently only scroll events are send through `sendEvent`, and all of them are can be coalesced. In future (further in the stack) touch events will go through there as well, but they won't support coalescing.
In order to ensure js processes touch and scroll events in the same order as they were created, we will flush the coalesced events when we encounter one that cannot be coalesced.
public
___
//This diff is part of a larger stack. For high level overview what's going on jump to D2884593.//
Reviewed By: nicklockwood
Differential Revision: D2884591
fb-gh-sync-id: a3d0e916843265ec57f16aad2f016a79764dcce8
Summary:
I want to use the `RCTEvent` protocol for touch events as well. That's why I'm removing not very well defined `body` property and replacing it with `arguments` method, which will return an array that will be passed directly to the js call.
I think this makes sense because there is no unified arguments format for all events and and the called js method (`moduleDotMethod`) is already event specific.
This way touch events and scroll events can result in calling a completely different js function with a completely different arguments (what they indeed currently do).
public
___
//This diff is part of a larger stack. For high level overview what's going on jump to D2884593.//
Reviewed By: nicklockwood
Differential Revision: D2884590
fb-gh-sync-id: 2c1885c3414e255d8572c0fbbbfe62a23d94dd06
Summary:
This property was never used, so I'm removing it.
public
___
//This diff is part of a larger stack. For high level overview what's going on jump to D2884593.//
Reviewed By: javache
Differential Revision: D2884587
fb-gh-sync-id: acd5e576cd13a02e77225f3b308232f8331d3b61
Summary:
`RCTBaseEvent` was never used. This diff removes it.
public
___
//This diff is part of a larger stack. For high level overview what's going on jump to D2884593.//
Reviewed By: javache
Differential Revision: D2884585
fb-gh-sync-id: 66a6afcda3b5baec7f768682da215570f6d33bb1
Summary:
public
https://github.com/facebook/react-native/pull/5494 added a new `source` property to WebView on Android that provides a better API, as well as allowing for request headers to be set.
This diff ports that functionality over to iOS, so we can have a consistent API cross-platform.
I've also extended the API to include `method` (GET or POST) and `body` when setting the WebView content with a URI, and `baseUrl` when setting static HTML.
Reviewed By: javache
Differential Revision: D2884643
fb-gh-sync-id: 83f24494bdbb4e1408aa8f3b7428fee33888ae3a
Summary:
public
This diff improves the implementation of 3D touch by adding a `forceTouchAvailable` constant to View that can be used to check if the feature is supported.
I've also added an example of how you can use the `force` property of the touch event to measure touch pressure in React Native.
Reviewed By: vjeux
Differential Revision: D2864926
fb-gh-sync-id: 754c54989212ce4e4863716ceaba59673f0bb29d
Summary:
This adds the first of the three 3dTouch API types, that found on the touch event.
It adds the `force` prop to touch events when running on iOS 9 devices:
Closes https://github.com/facebook/react-native/pull/3055
Reviewed By: svcscm
Differential Revision: D2860540
Pulled By: nicklockwood
fb-gh-sync-id: 95a3eb433837c844f755b3ed4a3dfcb28452c284
Summary:
public
NSJSONSerialization throws an exception when it encounters bad JSON data, including NaN values, which may not be a programming error.
This diff adds code to catch those exceptions and convert to an error. Also, if no error handling is in place, RCTJSONStringify will now display a redbox, and attempt to recover by sanitizing the JSON data and retrying.
Reviewed By: javache
Differential Revision: D2854778
fb-gh-sync-id: 18e6990af0d91083496d6a0b75c31a94ed9454a5