Summary:
<!--
Thank you for sending the PR! We appreciate you spending the time to work on these changes.
Help us understand your motivation by explaining why you decided to make this change.
You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html
Happy contributing!
-->
Headless tasks are required to run in the main thread, however due to the nature of the React context creation flow, the handler may be returned outside of the main thread, causing the HeadlessJsTaskContext to throw an exception.
Swipe out the app. send push notification from a server that starts a HeadlessJsTaskService
Closes https://github.com/facebook/react-native/pull/15940
Differential Revision: D5852448
Pulled By: foghina
fbshipit-source-id: 54c58a1eb7434dd5de5c39c28f6e068ed15ead9d
Summary:
When we convert nested <Text> components to Spannable object we must enforce the order of spans somehow,
otherwise we will have Spannable object with unpredictable order of spans, which will produce unpredictalbe text layout.
We can do it only using `Spannable.SPAN_PRIORITY` feature because Spannable objects do not maintain the order of spans internally.
We also have to fix this to implement autoexpandable <TextInput>.
Reviewed By: achen1
Differential Revision: D5811172
fbshipit-source-id: 5bc68b869e58aba27d6986581af9fe3343d116a7
Summary:
**Problem:**
It was observed that in [this code path](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java#L292) (i.e. horizontal, paging-enabled scroll view) if you tried to programmatically call the scrollTo method within ~1s of the onMomentumScrollEnd event (which should only be called after all scrolling has ended), the scrollView would scroll to the new location, and then scroll BACK to the original location.
For example, assume you had released the scrollView at location B, and the nearest page boundary is A. Then, 1000ms later, you call scrollTo position C. The order of operations would be:
1. Begin scrolling to A from position B (as it is the nearest page boundary)
2. Reach position A
3. Fire onMomentumScrollEnd
4. 1000ms later call scrollTo C
5. scrollView scrolls to C
6. scrollView scrolls BACK to position A (for no apparent reason).
**Reason:**
I suspect this is because the [smoothlyScrollTo](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java#L292) will continue to animate towards A, but the [scrollEvents will not fire](f954f3d9b6/ReactAndroid/src/main/java/com/facebook/react/views/scroll/OnScrollDispatchHelper.java (L45)) as they are too close to each other. So the true order of events is:
1. Begin scrolling to A from position B (as it is the nearest page boundary)
[begin smoothlyScrollTo]
[scroll towards position A]
[mActivelyScrolling is true]
2. Reach position A
[mActivelyScrolling is true]
[scroll towards position A]
[mActivelyScrolling is false, as there is another scrollEvent, but because it is close enough to the same location it is ignored]
3. Fire onMomentumScrollEnd
4. 1000ms later call scrollTo C
[scroll towards position C]
5. scrollView scrolls to C
[scroll towards position A as the original smoothlyScrollTo animation was never completed]
6. scrollView scrolls BACK to position A.
This is an untested hypothesis, but seems to explain the behavior, and the solution is more semantically correct anyway. If there is an easy way to rebuild the android binaries happy to test it myself! Just let me know!
**Solution:**
Move the mActivelyAnimating outside the mOnScrollDispatchHelper.onScrollChanged helper, because the HorizontalScrollView event should be considered to be animating so long as onScrollChanged events are being fired.
Closes https://github.com/facebook/react-native/pull/15146
Reviewed By: AaaChiuuu
Differential Revision: D5792026
Pulled By: tomasreimers
fbshipit-source-id: 9654fda038d4a687cc32f4c32dc312baa34627ed
Summary:
Abstract class `ReactBaseTextShadowNode` was decoupled from `ReactTextShadowNode` to separate two goals/roles:
* `ReactBaseTextShadowNode` represents spanned `<Text>` nodes, which can bear text attributes (both `RCTText` and `RCTVirtualText`);
* `ReactTextShadowNode` represents anchor `<Text>` view in Yoga terms, which can bear layout attributes (`RCTText` and `RCTTextInput`).
`ReactVirtualTextShadowNode` now inherits `ReactBaseTextShadowNode`.
The same architectural changes was applited to view managers.
Why?
* This is just a better architecture which represents the nature of this objects.
* Bunch of "negative" logic which turn off excessive features for some suclasses was removed.
* Memory efficiency.
* Now we can improve `<TextInput>` component using right inheritance. Yay!
Reviewed By: achen1
Differential Revision: D5715830
fbshipit-source-id: ecc0764a03b5b7586fe77ad31f149cd840f4da41
Summary:
ReactRawTextShadowNode represents "raw" text node (aka textContent), so it cannot have layout or styling, it is just a line of text, a pure string.
So, we must not interit it from HUGE ReactTextShadowNode (which represents <Text> node with ReactRawTextShadowNode instance inside).
We need this change to make future fancy (and valuable from product perspective) refactoring possible. Stay tuned!
Reviewed By: achen1
Differential Revision: D5712961
fbshipit-source-id: 009e48046bdf34ddfd40b93175934969af64b98b
Summary:
We have to have a way to explicitly enforce the fact that some nodes cannot have Yoga child nodes.
Previously we relied on `isMeasureDefined()`, which is actually special case (so it does not cover all possible cases).
Reviewed By: AaaChiuuu
Differential Revision: D5647855
fbshipit-source-id: 59591be61ef62c61eb98748d44bb28b878f713fc
Summary:
This code related to velocity would cause some scroll events to be skipped and caused some jitter for sticky headers. Not sure if there is a better fix but removing this does fix missing events and the velocity calculation still seems to be working.
**Test plan**
Tested that sticky headers now work properly on Android, tested that velocity calculation still seem to work.
Closes https://github.com/facebook/react-native/pull/15761
Differential Revision: D5760820
Pulled By: sahrens
fbshipit-source-id: 562b5f606bdc5452ca3d85efb5e0e3e7db224891
Summary:
…ndroid
Android overrides the original set ime option when the EditText is a multiline one.
This change makes sure to set it back to the original one when blurOnSubmit is true,
which causes the button icon to be conforming to the set returnKeyType as well as
changing the behaviour of the button, such that it will blurOnSubmit correctly.
The reason not do it with blurOnSubmit being false is
because it then would not create new lines when pressing the submit button,
which would be inconsistent with IOS behaviour.
**Note** this change relies on this one #11006 because the app would crash if we don't expllicitly remove the focus (`editText.clearFocus();`)
Fixes#8778
**Test plan (required)**
1. Create view with TextInput with multiline and blurOnSubmit set to true
```javascript
<View>
<TextInput
returnKeyType='search'
blurOnSubmit={true}
multiline={true}
onSubmitEditing={event => console.log('submit search')}></TextInput>
</View>
```
2. Input some text and click submit button in soft keyboard
3. See submit event fired and focus cleared / keyboard removed
Closes https://github.com/facebook/react-native/pull/11125
Differential Revision: D5718755
Pulled By: hramos
fbshipit-source-id: c403d61a8a879c04c3defb40ad0b6689a2329ce1
Summary:
Fixes#12591
The Android JSTouchDispatcher was using `mTargetCoordinates` when creating the TouchEvent for a move. However, these are final values which are set when the touch down is received. When the user's finger moves, it's important to be able to track the coordinates of the touch as it moves. Thus, we need to update the x,y coordinates by calling `TouchTargetHelper` on each move event.
Closes https://github.com/facebook/react-native/pull/15123
Reviewed By: achen1
Differential Revision: D5476663
Pulled By: shergin
fbshipit-source-id: ce79e96490f3657a13f9114fcc93e80d5fdbebaf
Summary:
<!--
Thank you for sending the PR! We appreciate you spending the time to work on these changes.
Help us understand your motivation by explaining why you decided to make this change.
You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html
Happy contributing!
-->
I was trying to typeset mathematical equations in react native. When typesetting fractions, baseline of the fraction must be aligned with the baseline of others. The baseline of fraction will vary based on size of numerator and denominator.
![image](https://user-images.githubusercontent.com/31202232/29577330-a22b45ee-8788-11e7-9cc5-04a72bcc1180.png)
In yoga, we can set custom baseline function using `YogaNode.setBaselineFunction` method. If this method is exposed in `ReactShadowNode` class, it will be easy to create custom native UI modules which requires setting custom baseline.
Closes https://github.com/facebook/react-native/pull/15605
Differential Revision: D5686876
Pulled By: shergin
fbshipit-source-id: 34d797a7ea27d5c1b9f6b9c36e469cdca3883aec
Summary:
Currently, `onLoadStart` fires for a couple of cases:
1. toplevel page loads (e.g. initial page load, clicking links)
2. loading of pages within an iframe
The fact that `onLoadStart` fires for case (2) causes some problems. For example, it makes it difficult for the code that uses the WebView to know what URL the WebView is currently rendering. This is because the listener can't distinguish between the toplevel URL and the URL of an iframe. Additionally, this behavior is inconsistent with the behavior on iOS. On iOS, `onLoadStart` only fires for toplevel page loads.
To fix these issues, this change deletes the `doUpdateVisitedHistory` handler so that `onLoadStart` only fires for case (1).
**Test Plan**
Created a test page that has an iframe and loaded it in the WebView. Verified that `onLoadStart` only fires for toplevel page loads.
Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/15554
Differential Revision: D5665979
Pulled By: hramos
fbshipit-source-id: a52e473bc5691a6e180f45f0728e4ad89a7d354f
Summary:
Overview -
This PR resolves the issue described in #14606. This PR makes Text components take into account the includeFontPadding property when calculating their size.
Background -
Currently, on Android, when includeFontPadding is set to false, the React Text component does not adjust its height. This makes it difficult to lay out other components at a precise spacing relative to a Text component.
iOS calculates the height of a UILabel based on the font's descent + ascent.
Android lets you choose whether to calculate the height of a TextView based on the font's top + bottom (includeFontPadding=true) or ascent + descent (includeFontPadding=false).
In order for a text component to be the same size on iOS and Android (relative to the rest of the layout in points and dips), one should set includeFontPadding=false on Android - but the React Text component needs to take this property into account when sizing itself for this to work.
Please see this stack overflow post for a visual explanation of the difference between a font's ascent/descent and top/bottom - https://stackoverflow.com/questions/27631736/meaning-of-top-ascent-baseline-descent-bottom-and-leading-in-androids-font
Testing -
Please see the attached screenshots to see the height difference of a Text component with this PR when includeFontPadding is true vs false.
The font I am using has an ascent + descent = em-size so that the height of the Text component will be equal to the font-size for a single line of text. This is to clearly show the additional height that includeFontPadding=true adds to the Text component.
For Text components that are styled in the same way,
When includeFontPadding=true, height = ~29.714 dips
When includeFontPadding=false, height= 24 dips
<img width="342" alt="includefontpaddingtrue" src="https://user-images.githubusercontent.com/1437344/27299391-3eec9de0-54fa-11e7-81d5-d0aeb40e8e27.png">
<img width="346" alt="includefontpaddingfalse" src="https://user-images.githubusercontent.com/1437344/27299401-45c95248-54fa-11e7-98d7-17dd152d3cb8.png">
Closes https://github.com/facebook/react-native/pull/14609
Reviewed By: AaaChiuuu
Differential Revision: D5587602
Pulled By: achen1
fbshipit-source-id: 6d2f12ba72ec7462676645519cd27820279278eb
Summary:
This is a workaround for missing PDF url support in Android WebView, which is a general known issue: when tapping a PDF url within WebView, instead of doing nothing, we just let android default intent handle it (e.g. it will open Chrome to load it).
This is basically to trick `shouldOverrideUrlLoading()` to return true for the specific url. The drawback is that product code needs to provide the whitelist.
The proper fix would be to use PdfRenderer in that method, but it seems like it's only for API >= 21...
Differential Revision: D5619383
fbshipit-source-id: f86b930f970dab9a5f57999df69ce94b9508edc9
Summary:
Since the `hot` parameter is not used anymore in metro-bundler (we are always applying the HMR transforms for bundlers requested through the HTTP server), we can remove it from the client request URL.
This allows us to reduce the metro-bundler memory by half when switching between HMR and not-HMR, since metro caches the bundles based on the requested URL path.
Reviewed By: davidaurelio
Differential Revision: D5630051
fbshipit-source-id: fb5dce4c31bbb38b1c0c93c97a525a992b2f6d8d
Summary:
We ran into a couple of problems with the implementation of `getCurrentPosition` on Android:
- It sometimes returns an inaccurate location
- It times out when `enableHighAccuracy` is `true` (#7495)
This change improves `getCurrentPosition` for both of the above problems. Instead of calling `requestSingleUpdate` it now calls `requestLocationUpdates` so it can receive multiple locations giving it an opportunity to pick a better one. Unlike `requestSingleUpdate`, this approach doesn't seem to timeout when `enableHighAccuracy` is `true`.
**Test plan (required)**
Verified in a test app that `getCurrentPosition` returns a good location and doesn't timeout when `enableHighAccuracy` is `true`. Also, my team has been using this change in our app in production.
Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/15094
Differential Revision: D5632100
Pulled By: hramos
fbshipit-source-id: 86e40b01d941a13820cb775bccad7e19dba3d692
Summary:
This is a simple groundwork PR to allow options to be passed to the `WebSocket` constructor. It represents a minor change to an undocumented part of the API, moving `headers` to within `options`.
This will be a BC for anyone manually specifying headers other than `origin` but a) that's not a common use case with WebSockets and b) it's not documented even in code and wouldn't currently pass a flow check.
NB: The third argument to the WebSocket constructor isn't part of the W3C spec, so I think this is a good place for RN-specific named parameters, better than adding a fourth argument. `protocols` needs to stay where it is, in line with the spec.
If this goes through I'd like to build on it by adding an additional connection option for SSL certificate pinning, as already supported by the underlying `okhttp` and `RCTSRWebSocket`. It could later be expanded for various other uses.
Currently, there's no way for a `WebSocket` user to specify any connection options other than url, protocol and headers. The fact that `WebSocket` connects in its constructor means any options have to go in there.
Connect to a websocket server using iOS and Android, observe the connection headers:
1. Without specifying `origin`, the default header should be set
2. Specifying it in the old way `new WebSocket(url, protocols, { origin: 'customorigin.com' })`
3. Specifying it in the new way `new WebSocket(url, protocols, { headers: { origin: 'customorigin.com' }})`.
I've tested myself using the test app with iOS and Android.
Closes https://github.com/facebook/react-native/pull/15334
Differential Revision: D5601675
Pulled By: javache
fbshipit-source-id: 5959d03a3e1d269b2c6775f3e0cf071ff08617bf
Summary:
LocalString doesn't have a check for null ptr which causes a crash if the null string passed.
Closes https://github.com/facebook/react-native/pull/15372
Differential Revision: D5601469
Pulled By: javache
fbshipit-source-id: a1b20efbae90009f0d465c077e6401a701d7515f
Summary:
If the z-index was updated after the initial mount, changes would not be reflected because we did not recalculate the z-index mapped child views and redraw the view. This adds code to do that and call it whenever we update z-index.
**Test plan**
Tested by reproducing the bug with 2 overlapping views that change z-index every second. Made sure it now works properly and z-index changes are reflected.
Closes https://github.com/facebook/react-native/pull/15203
Differential Revision: D5564832
Pulled By: achen1
fbshipit-source-id: 5b6c20147211ce0b7e8954d60f8614eafe128fb4
Summary:
My PR was pulled into RN 0.37 (d294e15c43). Since then an issue was discovered: ARTSurface skipped drawing the first render cycle if native TextureView takes too long. In case a static graphic is rendered in a single render cycle, it may be skipped resulting in an empty canvas being displayed.
A solution proposed in this PR: instead of skipping updates, make them pending and flush once the TextureView is ready.
This solution is released within our production app. It fixed ArtSurface initialisation issues cased by original PR to RN 0.37.
Closes https://github.com/facebook/react-native/pull/11539
Differential Revision: D4449255
Pulled By: shergin
fbshipit-source-id: a517909ca5c78c09a3ac8d9052664b92841b4e08
Summary:
This is the better fix for the same issue as mentioned in PR https://github.com/facebook/react-native/pull/14560
Certain rotateX, rotateY, scaleX and scaleY animations do not work correctly on some phones in Android 7.0.0, causing issues such as https://github.com/facebook/react-native/issues/14462 and https://github.com/facebook/react-native/issues/13522.
The issue can be fixed on JS side by setting an additional transform for perspective, eg. `{perspective: 1}` which triggers a `setCameraDistance` call in native code.
The fix in this PR always sets the camera distance on transforms, even when no perspective transform was specified. The default camera distance is set before the scale multiplication, to make sure that the value is appropriate for the phones density. The value calculates to an Android 'default' camera distance of 1280 * scale multiplier; https://developer.android.com/reference/android/view/View.html#setCameraDistance(float)
If a perspective transform is specified, this value will be used correctly still.
This fix was tested on the RNTester. Before the fix, on some devices, the FlatList example, with inverted turned on, will not display the list.
Devices that have been confirmed to have this issue:
FRD-AL10(honor 8) EMUI:5.0 android: 7.0
MHA-AL00(Mate9) EMUI:5.0 android:7.0
Huawei P10 VTR-L09, running Android 7.0
After the fix, the inverted FlatList displays correctly.
Closes https://github.com/facebook/react-native/pull/14646
Differential Revision: D5492009
Pulled By: shergin
fbshipit-source-id: d4da3b090a7e65df3b84e48ea32c964f4f8f7c88
Summary:
**Summary:**
There was a bug with RN.Dimensions returning incorrect window dimensions. In certain cases when device was in portrait, window dimensions reported landscape dimensions and vice versa.
This happened because in certain scenarios, after device orientation changed, dimensions update event from ReactRootView had incorrect dimensions.
Was able to reproduce this when device was rotated during app launch. After rotation global layout listener callback gets invoked. Inside the callback current and previous orientations are compared. When a change is detected, orientation and dimension change events are sent to JS. It is assumed, when orientation changes, new dimensions are available immediately. This is not the case for window dimensions as they are retrieved from resources object which gets updated asynchronously after orientation change. In cases when app is doing a lot of work on the main thread, like app startup, it takes more time to update the resources object. And when orientation change is detected in global layout, resources object is not updated with new dimensions yet. This causes dimensions update to be sent to JS with old window dimensions.
Global layout listener callback does get invoked a second time when resources object is finally updated with new dimensions, but since orientation no longer changes, no event is sent to JS.
Fixed this by separating dimensions update from orientation update. Now RN keeps track of previous window and screen dimension values. When a change is detected, an event is sent to JS with updated dimensions. This ensures that whenever dimensions change, JS gets the updated values.
This has a side effect of sending dimension update twice in some cases.
One example is the case above where window dimensions take time to update, but screen dimensions are updated immediately. This will cause two events to be sent to JS. One for window dimensions and one for screen dimensions update.
Other change is that initial value for both window and screen fields is empty. Which results in first change to trigger an event. Previously initial orientation value was 0 which meant when app started in normal portrait orientation, first layout did not trigger a dimension update event. Now even first layout sends the event. This should not be an issue as it is to make sure dimensions in JS side are correct.
**Testing:**
Verified with a sample app that correct dimensions are available when app launches.
Verified that after orientation dimensions are updated.
Verified that in the scenario described above where window dimensions are updated later, we get correct dimension values in JS.
We have incorporated this fix into our app and have been testing it internally.
Ats Jenk
Microsoft Corp.
<!--
Thank you for sending the PR!
If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!
Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.
Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/15181
Differential Revision: D5552195
Pulled By: shergin
fbshipit-source-id: d1f190cb960090468886ff56cda58cac296745db
Summary:
Fixes the following crash:
```
Fatal Exception: java.lang.RuntimeException: Unable to destroy activity {com.example/com.example.MainActivity}: java.lang.NullPointerException: ImagePipelineFactory was not initialized!
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3831)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3849)
at android.app.ActivityThread.access$1500(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:764)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
Caused by java.lang.NullPointerException: ImagePipelineFactory was not initialized!
at com.facebook.common.internal.Preconditions.checkNotNull(Preconditions.java:226)
at com.facebook.imagepipeline.core.ImagePipelineFactory.getInstance(ImagePipelineFactory.java:74)
at com.facebook.drawee.backends.pipeline.Fresco.getImagePipelineFactory(Fresco.java:92)
at com.facebook.drawee.backends.pipeline.Fresco.getImagePipeline(Fresco.java:97)
at com.facebook.react.modules.fresco.FrescoModule.onHostDestroy(FrescoModule.java:186)
at com.facebook.react.bridge.ReactContext.onHostDestroy(ReactContext.java:240)
at com.facebook.react.ReactInstanceManager.moveToBeforeCreateLifecycleState(ReactInstanceManager.java:667)
at com.facebook.react.ReactInstanceManager.onHostDestroy(ReactInstanceManager.java:586)
at com.facebook.react.ReactInstanceManager.onHostDestroy(ReactInstanceManager.java:599)
at com.facebook.react.ReactActivityDelegate.onDestroy(ReactActivityDelegate.java:142)
at com.facebook.react.ReactActivity.onDestroy(ReactActivity.java:72)
at android.app.Activity.performDestroy(Activity.java:6456)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1143)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3818)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3849)
at android.app.ActivityThread.access$1500(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:764)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
```
This was introduced by d9ae27ba89
1. Create app with an image to be loaded
2. Background app before fresco has been initialised. (Very tight window to do this)
3. Should not crash
cc foghina
Closes https://github.com/facebook/react-native/pull/14359
Differential Revision: D5508505
Pulled By: hramos
fbshipit-source-id: 5a66d594625783f1c30180fe78c5baddb4f835aa