Summary: Having UI modules access the shadowQueue via UIManager.methodQueue is fragile and leads to race conditions in startup, sometimes resulting in an error where the methodQueue is set twice, or not at all.
Reviewed By: javache
Differential Revision: D3304890
fbshipit-source-id: 7198d28314dbec798877fcaaf17ae017d50157e9
Summary:
Currently, `7 << 16` is used as the animation easing function for both the showing and hiding of the keyboard.
Instead, `7 << 16` should be used for showing the keyboard and `6 << 16` for hiding the keyboard.
For details, see: http://stackoverflow.com/questions/18870447/how-to-use-the-default-ios7-uianimation-curve/19439283#19439283
**Test plan (required)**
Testing animating the position of a view to coordinate with the keyboard hiding and showing and it looks good.
Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/7372
Differential Revision: D3300464
Pulled By: nicklockwood
fbshipit-source-id: 3fdc161f709de11deb7de511aad28767f5d80bd6
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:This adds support for delete view animations in LayoutAnimation for iOS. It supports the same properties as the create animation (alpha, scale).
This allows making simple animations when removing a view which is normally hard to do in React since we need to not remove the view node immediately.
**Test plan**
Tested add/removing views in the UIExample explorer with and without setting a LayoutAnimation. Also tested that the completion callback still works properly. Tested that user interation during the animation is properly disabled.
![layout-anim2](https://cloud.githubusercontent.com/assets/2677334/14595471/86fb1654-050d-11e6-8b38-fe45cc2dcd71.gif)
I also plan to work on improving the doc for LayoutAnimation as well as making this PR for android too.
Closes https://github.com/facebook/react-native/pull/6779
Differential Revision: D3215525
Pulled By: sahrens
fb-gh-sync-id: 526120acd371c8d1af433e8f199cfed336183775
fbshipit-source-id: 526120acd371c8d1af433e8f199cfed336183775
Summary:All UIManager operations that affect the view hierarchy are executed via the `addUIBlock:` method, which queues them up to be executed after layout has been completed on the shadow queue.
One of the most expensive view operations is view creation, but since this doesn't actually depend on layout, there's no reason to delay it until the shadow operations have finished.
This diff modifies the `createView` method to dispatch view creation directly to the main thread instead of adding it to the UIBlock queue. This seems to result a measurable improvement in TTI.
(Credit to astreet, for implementing the same idea on Android, and thanks to oli for telling me about it!)
Reviewed By: javache
Differential Revision: D3155709
fb-gh-sync-id: 3ad1da9a8fee687aa7e0e023d668192d94dba340
fbshipit-source-id: 3ad1da9a8fee687aa7e0e023d668192d94dba340
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: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:Because the source of truth for backgroundColor is the shadow view, it's possible for the default RCTView backgroundColor to get overwritten by the current shadowView backgroundColor when the view is first created. This overridden value will then be used as the default whenever the background color is reset, which may not be be appropriate for other components that use RCTView.
This diff fixes the bug by ensuring that the view props (and therefore the default color) are set *before* the background color is propagated from the shadowView.
Reviewed By: furdei
Differential Revision: D3064128
fb-gh-sync-id: ac36007c094c7201a5c4fd93399dee4d3eb9a043
shipit-source-id: ac36007c094c7201a5c4fd93399dee4d3eb9a043
Summary:The UICollectionView example is actually my use-case, which is discussed in a
bit more detail [here](https://github.com/alloy/ReactNativeExperiments/issues/2).
----
This is useful when wrapping native iOS components that determine their
own suggested size and which would be too hard/unnecessary to replicate
in the shadow view. For instance a `UICollectionView` that after layout
will update its `contentSize`, which could be used to suggest a size to
the shadow view.
The reason for adding it to -[RCTShadowView setFrame:] is mainly so it
can be used via the existing -[RCTUIManager setFrame:forView:] API and
because it might not be a feature you want to expose too prominently.
An origin of `{ NAN, NAN }` is used as a sentinel to indicate that the
frame should be used as a size suggestion. The size portion of the rect
may contain a `NAN` to skip that dimension or a suggested value for the
dimension which will be used if no explicit styling has been assigned.
Examples:
* Without any expl
Closes https://github.com/facebook/react-native/pull/6114
Differential Revision: D2994796
Pulled By: nicklockwood
fb-gh-sync-id: 6dd3dd86a352ca7d31a0da38bc38a2859ed0a410
shipit-source-id: 6dd3dd86a352ca7d31a0da38bc38a2859ed0a410
Summary: When embedding in a hybrid app, we sometimes present new modal views or windows that have a different frame from the original root view. This API allows us to get coordinates in the application's window frame, which should be valid in any fullscreen view.
Reviewed By: majak
Differential Revision: D2939827
fb-gh-sync-id: 06b93cc2cb3519a25819c6efa445c779314dd673
shipit-source-id: 06b93cc2cb3519a25819c6efa445c779314dd673
Summary:The `uiBlockToAmendWithShadowViewRegistry:` is called on every single view manager, on every single layout pass. This causes all view managers to be eagerly intiialized, even if not being used.
In practice very few modules actually use this method, so by checking if the method is implemented before calling it, we can eliminate most of this work.
(Hopefully in future we can get ride of this method altogether, but right now it's integral to the way that text layout is implemented).
Reviewed By: majak, javache
Differential Revision: D2982181
fb-gh-sync-id: 818d0aac61197df89263c919c2c80a003e293ac5
shipit-source-id: 818d0aac61197df89263c919c2c80a003e293ac5
Summary:Unfortunately the 'screen' option in the `UIManager.takeSnapshot` API appears to work only on the iOS simulator, not on an actual device.
This diff removes the 'screen' option until a solution can be found that works on the device.
(Taking a snapshot of the window still works fine - it just won't include the status bar, etc.)
Reviewed By: javache
Differential Revision: D2971091
fb-gh-sync-id: 026b9d4eb2f59f686f58c18a16381ff325df612b
shipit-source-id: 026b9d4eb2f59f686f58c18a16381ff325df612b
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:
We were executing all the updateBlocks for every frame that was updated in the UI flush. This would quickly give you an explosive number of block calls when loading complex views.
This update block is only really used by text to propagate padding, even though the actual insets are mostly just 0.
public
Reviewed By: nicklockwood
Differential Revision: D2848968
fb-gh-sync-id: e43c529c2bb9729e2b779bf4abefeed58775cc2e
Summary:
public
Android implement ViewManager methods via a dispatch method on UIManager, whereas iOS implements them by exposing the methods on the view manager modules directly.
This diff polyfills Android's implementation on top of the iOS implementation, allowing the same JS API to be used for both.
Reviewed By: javache
Differential Revision: D2803020
fb-gh-sync-id: 0da0544e593dc936467d16ce957a77f7ca41355b
Summary:
fixes#3106
Having -1 would trigger callback one frame early causing it to be ignored on the next frame.
Closes https://github.com/facebook/react-native/pull/3190
Reviewed By: svcscm
Differential Revision: D2783700
Pulled By: mkonicek
fb-gh-sync-id: 02070f70915055aec3b1543a8d553f2680438611
Summary:
public
Most of the time - especially during app startup - when we call UIManager.manageChildren(), we are actually just adding the first set of children to a newly created view.
This case is already optimized for in the JS code, by memoizing index arrays at various sizes, but this is not especially efficient since it is still sending an array of indices with each call that could be easily inferred on the native side instead.
I've added a hybrid native/JS optimization that improves the performance for this case. It's not a huge win in terms of time saved, but benchmarks show improvements in the ~1% range for several of the app startup metrics.
Reviewed By: tadeuzagallo
Differential Revision: D2757388
fb-gh-sync-id: 74f0cdbba93af2c04d69b192a8c2cc5cf429fa09
Summary:
public
Thanks to the new lazy initialization system for modules, `RCTDidCreateNativeModules` no longer does what the name implies.
Previously, `RCTDidCreateNativeModules` was fired after all native modules had been initialized. Now, it simply fires each time the bridge is reloaded. Modules are created on demand when they are needed, so most of the assumptions about when `RCTDidCreateNativeModules` will fire are now incorrect.
This diff deprecates `RCTDidCreateNativeModules`, and adds a new notification, `RCTDidInitializeModuleNotification`, which fires each time a module a new module is instantiated.
If you need to access a module at any time you can just call `-[bridge moduleForClass:]` and the module will be instantiated on demand. If you want to access a module *only* after it has already been instantiated, you can use the `RCTDidInitializeModuleNotification` notification.
Reviewed By: tadeuzagallo
Differential Revision: D2755036
fb-gh-sync-id: 25bab6d5eb6fcd35d43125ac45908035eea01487
Summary:
A component can be backed by native "node" that can change its internal state, which would result in a new UI after the next layout. Since js has no way of knowing that this has happened it wouldn't trigger a layout if nothing in js world has changed. Therefore we need a way how to trigger layout from native code.
This diff does it by adding methods `layoutIfNeeded` on the uimanager and `isBatchActive` on the bridge.
When `layoutIfNeeded` is called it checks whether a batch is in progress. If it is we do nothing, since at it's end layout happens. If a batch is not in progress we immidiately do layout.
I went with the easiest way how to implement this - `isBatchActive` is a public method on the bridge. It's not ideal, but consistent with other methods for modules.
public
Reviewed By: jspahrsummers, nicklockwood
Differential Revision: D2748896
fb-gh-sync-id: f3664c4af980d40a463b538e069b26c9ebad6300
Summary:
public
This diff replaces the RegEx module method parser with a handwritten recursive descent parser that's faster and easier to maintain.
The new parser is ~8 times faster when tested on the UIManager.managerChildren() method, and uses ~1/10 as much RAM.
The new parser also supports lightweight generics, and is more tolerant of white space.
(This means that you now can – and should – use types like `NSArray<NSString *> *` for your exported properties and method arguments, instead of `NSStringArray`).
Reviewed By: jspahrsummers
Differential Revision: D2736636
fb-gh-sync-id: f6a11431935fa8acc8ac36f3471032ec9a1c8490
Summary:
public
Currently, we wait to invoke `-flushUIBlocks` until the JavaScript batch to native has completed. This means we may be waiting an unnecessarily long time to perform view hierarchy changes and prop changes.
By instead invoking this after each chunk of enqueued UI blocks, we can perform some updates more eagerly, increasing our utilization of the main thread while splitting up the amount of time we spend running upon it.
This shouldn't affect layout, which is still tied to `-batchDidComplete`, so any visual inconsistencies should be limited to prop changes, which seems acceptable for the dramatic improvement in performance.
Reviewed By: javache
Differential Revision: D2658552
fb-gh-sync-id: 6d4560e21d7da1b02d2f30d1860d60735f11c4b5
Summary: There is no point in using `updateLayout` when we have `didSetProps`.
The only a bit risky part is calling `dirtyLayout` in `setFrame:forView:` instead of `updateLayout`,
but since setting frame shouldn't really change border/margin/padding it should be ok.
Depends on D2699512.
public
Reviewed By: nicklockwood
Differential Revision: D2700012
fb-gh-sync-id: a7c33b3b4e3ddc195bebebb8b03934131af016fb
Summary: public
The `bridge.modules` dictionary provides access to all native modules, but this API requires that every module is initialized in advance so that any module can be accessed.
This diff introduces a better API that will allow modules to be initialized lazily as they are needed, and deprecates `bridge.modules` (modules that use it will still work, but should be rewritten to use `bridge.moduleClasses` or `-[bridge moduleForName/Class:` instead.
The rules are now as follows:
* Any module that overrides `init` or `setBridge:` will be initialized on the main thread when the bridge is created
* Any module that implements `constantsToExport:` will be initialized later when the config is exported (the module itself will be initialized on a background queue, but `constantsToExport:` will still be called on the main thread.
* All other modules will be initialized lazily when a method is first called on them.
These rules may seem slightly arcane, but they have the advantage of not violating any assumptions that may have been made by existing code - any module written under the original assumption that it would be initialized synchronously on the main thread when the bridge is created should still function exactly the same, but modules that avoid overriding `init` or `setBridge:` will now be loaded lazily.
I've rewritten most of the standard modules to take advantage of this new lazy loading, with the following results:
Out of the 65 modules included in UIExplorer:
* 16 are initialized on the main thread when the bridge is created
* A further 8 are initialized when the config is exported to JS
* The remaining 41 will be initialized lazily on-demand
Reviewed By: jspahrsummers
Differential Revision: D2677695
fb-gh-sync-id: 507ae7e9fd6b563e89292c7371767c978e928f33
Summary: public
We were calling constantsToExport twice for every ViewManager, and including two copies of the values in __fbBatchedBridgeConfig. This diff removes the copy from UIManager and then puts it back on the JS side.
Reviewed By: tadeuzagallo
Differential Revision: D2665625
fb-gh-sync-id: 147ec4bfb404835e3875964476ba233d619c28aa
Summary: public
In iOS < 9, inserting a nil object into NSMutableDictionary crashes. It is valid for come components to return a nil shadowView (e.g. ART nodes), and this was crashing on iOS 8.
Reviewed By: jspahrsummers
Differential Revision: D2658309
fb-gh-sync-id: 7abf9273708cc03c3b6307b69ba11c016b471fbe
Summary: This queue processes layout and user interface updates, so it should have as high a quality-of-service/priority as possible.
public
Reviewed By: javache
Differential Revision: D2641837
fb-gh-sync-id: 934686f7969b43101af183148d67ff7be4bdf660
Summary: public
Rename it to `RCT_PROFILE_(BEGIN|END)_EVENT` to make it clearer that it's a macro,
since it has special behaviours.
Reviewed By: jspahrsummers
Differential Revision: D2631542
fb-gh-sync-id: 629c139462c4aa3582f719b14482017d13676e33
Summary: public
There were some old markers that are now automatically inject and now are no longer necessary (+ one that was missing an end call :( ))
Reviewed By: javache
Differential Revision: D2625901
fb-gh-sync-id: 4c4c9d6b4e8e2b4bdb9c64fde01000b0ca2e9f47
Summary: public
Add RCTFatal for reporting fatal runtime conditions. This centralizes failure handling to one function and allows you to customize how they should be handled. RCTFatal will be logged to the console and as a redbox and will also be triggered by fatal exceptions coming from RCTExceptionsManager.
Note that there is no RCTLogFatal, since just logging the fatal condition does not allow us to handle it consistently.
Reviewed By: nicklockwood
Differential Revision: D2615490
fb-gh-sync-id: 7d8e134419e10a8fb549297054ad955db3f6bee0
Summary: public
Added lightweight genarics annotations to make the code more readable and help the compiler catch bugs.
Fixed some type bugs and improved bridge validation in a few places.
Reviewed By: javache
Differential Revision: D2600189
fb-gh-sync-id: f81e22f2cdc107bf8d0b15deec6d5b83aacc5b56
Summary: public
The UIManager had a lock around the enqueued ui blocks, but now all the operations
should happen on the shadow thread, so I added assertions to it and removed the
locks.
Reviewed By: nicklockwood
Differential Revision: D2605760
fb-gh-sync-id: e1bc649f759502e7e9fd059932e0cba38dba05bf