Summary:
Calls abort() in cases where malloc returns NULL.
Checking the return value from malloc is good practice and is
required to pass a [Veracode security scan](https://www.veracode.com/). This will let
developers who are required to submit their software to Veracode
use React Native.
Pull Request resolved: https://github.com/facebook/react-native/pull/20173
Differential Revision: D9235096
Pulled By: hramos
fbshipit-source-id: 9fdc97f9e84f8d4d91ae59242093907f7a81d286
Summary:
This adds the accessibilityHint for View, Text and Touchable* on iOS.
The accessibilityHint provides some more information about an element
when the accessibilityLabel is not enough.
The accessibilityHint is a core accessibility property on iOS.
From https://developer.apple.com/documentation/objectivec/nsobject/1615093-accessibilityhint:
> An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not obvious from the accessibility label.
Related issue: https://github.com/facebook/react-native/issues/14706
The npm scripts `test`, `flow`, `lint` and `prettier` are satisfied.
I added a couple of examples to the RNTester app. The Accessibility Inspector on Mac helps debugging accessibility stuff on a simulator, but it does not show the accessibilityHint. Therefore I tested the RNTester app on an iPhone 8 device using VoiceOver to verify the hint functionality. It works fine, and I've tested disabling and enabling "read hints" in the VoiceOver settings on the phone.
https://github.com/facebook/react-native-website/pull/222
[IOS][FEATURE][Accessibility] - Add accessibilityHint for View, Text, Touchable* on iOS
Closes https://github.com/facebook/react-native/pull/18093
Reviewed By: hramos
Differential Revision: D7230780
Pulled By: ziqichen6
fbshipit-source-id: 172ad28dc9ae2b67ea256100f6acb939f2466d0b
Summary:
When I bridged FBPullToRefresh to RN, the integration with ScrollView caused a bug on OSS
TLDR; assuming that a scrollview subview that implemented UIScrollViewDelegate protocol was a custom PTR was a bad idea. This caused some scrollviews to break in OSS. The solution is to define a more explicit protocol.
Further details here:
https://github.com/facebook/react-native/issues/20324
Reviewed By: mmmulani
Differential Revision: D8953893
fbshipit-source-id: 98cdc7fcced41d9e98e77293a03934f10c798665
Summary:
Context:
After discussing with yungsters, `currentViewStates` is a very ambiguous name for a prop, especially because there are only two possible values. From a developer's perspective, it makes more sense to just call them `accessibilityStates` because the main use for them is to add states to Talkback and Voiceover.
Also, the actual implementation of what we're changing under the hood in Native Code is abstracted away from developers using React Native, so as long as behavior is as they would expect, it makes more sense to change the name into a clear one.
Changes in this Diff:
Renamed the view property exposed to native iOS code from `currentViewStates` to `accessibilityStates`
Also deleted setting the userInteractionEnabled view property, because we want to keep it as just an accessibility property.
Reviewed By: PeteTheHeat
Differential Revision: D8896821
fbshipit-source-id: 95674c9b7295f5b9e60994c297acdee83f6226d7
Summary:
Added Native iOS functionality for prop currentViewStates.
On iOS, this property modifies both the view property userInteractionEnabled and also adds corresponding UIAccessibilityTraits to the view.
If disabled is passed in, userInteractionEnabled of the view will be set to false.
The value that is passed into currentviewStates is converted to a UIAccessibilityTrait Enum and masked in with existing UIAccessibilityTraits on that native view.
The native implementation for accessibilityRole is also changed to also mask new UIAccessibilityTraits with existing ones.
Reviewed By: PeteTheHeat
Differential Revision: D8842691
fbshipit-source-id: 919267300c70efed93a7a92377a0178bd8885eb5
Summary:
Because we're now separating accessibilityTraits into accessibilityRole and accessibilityState, we're going to only allow one role to be set, and allow on preset combinations of roles that make sense.
This change adds iOS functionality to the role image button because a popular accessibilityTrait combination is image and button.
Reviewed By: ikenwoo
Differential Revision: D8847012
fbshipit-source-id: da386dbf82cb3854d14c228a1116da9f4067fe93
Summary: Removed Accessibility Trait TabBar for iOS compatibility Issues, since tabbar is only available on iOS 10+
Reviewed By: PeteTheHeat
Differential Revision: D8822469
fbshipit-source-id: 34bf00eb930f631a5a4effa0a4159da07c1573f6
Summary:
Added a new property to View for Accessibility called `accessibilityRole`. This property merges functionality of existing properties: `accessibilityTraits` (iOS) and `accessibilityComponentType` (android).
Currently, nine values are supported with equivalent behavior as `accessibilityTraits` (iOS) when `accessibilityRole` is set on iOS Voiceover and Android TalkBack
```
| 'none'
| 'button'
| 'link'
| 'search'
| 'image'
| 'keyboardkey'
| 'text'
| 'adjustable'
| 'tabbar'
```
They currently support similar behavior on talkback on Android and voice over on iOS
Does not break functionality of existing properties, but have not tested for behavior of setting both this one and the old one.
* iOS - I added a property accessibilityRoles, and basically remapped it to the same thing as accessibilityTraits. I also added in enum mappings for keyboardkey and tabbar.
* Android - Also added a property accessibilityRoles, from the Android side. For the underlying native functionality, I built a helper class that is based off of AccessibilityRolesUtil.java from the accessibility team. Biggest changes made are that I defined my own enums if needed, and also set some properties to match the functionality of iOS Accessibility Traits. I also handled the logic for switch/case statements of setting roles for the android side on this file. Also, I currently haven't localized strings for setRoleDescription, but plan to.
* Javascript - I added a view property accessibilityRoles in ViewPropTypes.
Reviewed By: blavalla
Differential Revision: D8756225
fbshipit-source-id: e03eec40cce86042551764f433e1defe7ee41b35
Summary:
Added Check for iOS 11 before setting property for `accessibilityIgnoreInvertColor`
Builds on top of
https://our.intern.facebook.com/intern/diff/D8549084/
Reviewed By: shergin
Differential Revision: D8599698
fbshipit-source-id: c5cc26b4c1c20fb9cca5bfe7143fa9dcb217a2d7
Summary:
@public
Added a property `accessibilityIgnoresInvertColors (boolean)` to Views which allows the Apple API `accessibilityIgnoresInvertColors` to be used in React Native.
Now, when a user has Display: Smart Invert enabled, you can set the property to be true, and things like photos and views with the property set to true will no longer be inverted when Smart Invert is enabled.
This property can also be applied to the Image Component.
Example Use Case:
```
<Image accessibilityIgnoresInvertColors={true} />
```
```
<View accessibilityIgnoresInvertColors={true} />
```
| Before | After |
| ------ | ----- |
| ![original](https://user-images.githubusercontent.com/165856/41738737-b62c6ebc-7547-11e8-8ea3-f82239998071.jpg) | ![feeditem](https://user-images.githubusercontent.com/165856/41738749-beef6de2-7547-11e8-9771-b44e513de0fd.jpg)
Reviewed By: PeteTheHeat
Differential Revision: D8549084
fbshipit-source-id: 82a3bc73c9e6d75d6b50ba013b88127f07692641
Summary: Moving target deployment to iOS 9.0+ from now on, removing customization for iOS 8.
Reviewed By: shergin
Differential Revision: D8053439
fbshipit-source-id: 292c58f15c6e6caf8b28d15c1521812d6ed675c5
Summary:
`RCTFontTests` test in RNTester is broken if the target deployment is <= OS 8.2. This is because RCTFont.mm overrides the OS-defined values, but the override is only visible to RCTFont.mm internals. As the result, when the Unit test tries to create UIFont of the "same" weight, it got a different font - most likely due to internal floating rounding errors.
To mitigate, code that wants to test out internals of RCTFont should import RCTFontConstantsOverride.h
Reviewed By: mmmulani
Differential Revision: D7900954
fbshipit-source-id: e5814ef059a8afdfb5205ca1af46c41b3cfd4318
Summary:
… is not a protoype #19086
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.
<!--
Required: Write your motivation here.
If this PR fixes an issue, type "Fixes #issueNumber" to automatically close the issue when the PR is merged.
-->
Fixes#19086
Related to react-native-navigation issue #3019
<!--
Required: Write your test plan here. If you changed any code, please provide us with
clear instructions on how you verified your changes work. Bonus points for screenshots and videos!
-->
Created a fresh react native >= 0.55.2 project and only install React Native Navigation. The error "This function declaration is not a prototype" message occurs.
Downgrading to React Native 0.54.4 builds fine.
![screen shot 2018-05-01 at 3 17 51 pm](https://user-images.githubusercontent.com/5680239/39491718-ddfdd6a0-4d52-11e8-937f-7ed9702a2e30.png)
<!--
Does this PR require a documentation change?
Create a PR at https://github.com/facebook/react-native-website and add a link to it here.
-->
No documentation change
<!--
Required.
Help reviewers and the release process by writing your own release notes. See below for an example.
-->
[iOS] [BUGFIX] [react-native-navigation] - For compatibility with react-native-navigation >= 2.0.2237 https://github.com/facebook/react-native/issues/19086
<!--
**INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.**
CATEGORY
[----------] TYPE
[ CLI ] [-------------] LOCATION
[ DOCS ] [ BREAKING ] [-------------]
[ GENERAL ] [ BUGFIX ] [ {Component} ]
[ INTERNAL ] [ ENHANCEMENT ] [ {Filename} ]
[ IOS ] [ FEATURE ] [ {Directory} ] |-----------|
[ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} |
[----------] [-------------] [-------------] |-----------|
EXAMPLES:
[IOS] [BREAKING] [FlatList] - Change a thing that breaks other things
[ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput
[CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with
[DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word
[GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position
[INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see
-->
Closes https://github.com/facebook/react-native/pull/19089
Differential Revision: D7841198
Pulled By: shergin
fbshipit-source-id: 31638274055c3f143342d2d6dde6d4af7a2ac304
Summary:
This fixes perf regression which was introduced by recent refactoring of the layout process.
That is how it used to be:
114c258045/React/Views/RCTShadowView.m (L160-L166)
Note: We have to resert this flag in indication that we already applied those changes and we don't need to traverse this subtree until it is changed again.
Reviewed By: fkgozali
Differential Revision: D7343564
fbshipit-source-id: ba7e00bc5fe4992d777eed20ba0d959fd8f6c037
Summary:
This change is a revert of [#17927](https://github.com/facebook/react-native/pull/17927) pull-request.
The pull-request caused an issue with the keyboard covering the text field at the bottom of the scroll view.
Reviewed By: shergin
Differential Revision: D7246609
fbshipit-source-id: 149f825274c4fa79ab593f1bae3602667d16ddee
Summary:
Related to: #15454
Motivation: Improve tvOS feeling for TouchableHighlight
![changewithaniamtion](https://user-images.githubusercontent.com/7658664/29193477-b99b4a10-7e25-11e7-8b31-e0e4ca9d7720.gif)
- When you select the button he is focus and the underlay is show
- When you press the button, there is an animation, but after the animation, the focus is on the button and the underlay is show
Play with tvParallaxProperties on tvOS, test with and without patch just to see the actual behaviour
```
<TouchableHighlight
tvParallaxProperties={{
enabled: true,
shiftDistanceX: 0,
shiftDistanceY: 0,
tiltAngle: 0,
magnification: 1.1,
pressMagnification: 1.0,
pressDuration: 0.3,
}}
underlayColor="black"
onShowUnderlay={() => (console.log("onShowUnderlay")}
onHideUnderlay={() => (console.log("onHideUnderlay")}
onPress={() => (console.log("onPress")}
>
<Image
style={styles.image}
source={ uri: 'https://www.facebook.com/images/fb_icon_325x325.png' }
/>
</TouchableHighlight>
```
Closes https://github.com/facebook/react-native/pull/15455
Differential Revision: D6887437
Pulled By: hramos
fbshipit-source-id: e18b695068bc99643ba4006fb3f39215b38a74c1
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!
-->
The scrollToOffset method of RCTScrollView for iOS does not include bound check for the scroll offset provided to the method. This can cause the whole view to scroll out of screen if the offset provided is greater than the bounds of the View.
The same does not happen on Android, where the scroll halts once the last item of the scrollView is in the viewport.
I have added bounds check so the offset resets to the MaxOffset which makes sure the view does not scroll out of the viewport.
The issue can be observed in the following snack:
https://snack.expo.io/H1363Uo8f
![ezgif com-optimize 1](https://user-images.githubusercontent.com/16662518/36068270-2437ae88-0ef7-11e8-96dd-819b4ae0fd67.gif)
To test my changes I ran the code provided in the snack above with the react-native dependency pointing to my branch. As can be see in the video attached below, the scroll halts once it hits the end of the ScrollView even if the scroll offset provided is higher than the bounds of the ScrollView. It also does not scroll up for negative scroll offset.
![ezgif com-optimize](https://user-images.githubusercontent.com/16662518/36068130-9ae4f918-0ef3-11e8-8728-af7b2888bdb8.gif)
[IOS] [BUGFIX] [ScrollView] - Added bounds check to prevent ScrollView from scrolling to an offset which is out of bounds of the ScrollView for iOS.
Closes https://github.com/facebook/react-native/pull/17927
Differential Revision: D7014466
Pulled By: shergin
fbshipit-source-id: a817738d08e1057a4c70f43373132f88fa1461c4
Summary:
Includes React Native and its dependencies Fresco, Metro, and Yoga. Excludes samples/examples/docs.
find: ^(?:( *)|( *(?:[\*~#]|::))( )? *)?Copyright (?:\(c\) )?(\d{4})\b.+Facebook[\s\S]+?BSD[\s\S]+?(?:this source tree|the same directory)\.$
replace: $1$2$3Copyright (c) $4-present, Facebook, Inc.\n$2\n$1$2$3This source code is licensed under the MIT license found in the\n$1$2$3LICENSE file in the root directory of this source tree.
Reviewed By: TheSavior, yungsters
Differential Revision: D7007050
fbshipit-source-id: 37dd6bf0ffec0923bfc99c260bb330683f35553e
Summary:
This is reimagining of interoperability layer between Yoga and ShadowViews (at least in Yoga -> RN part).
Goals:
* Make it clear and easy.
* Make clear separation between "what layout what", now parent always layout children, noone layout itself.
* Make possible to interleave Yoga layout with custom imperative layout (may be used in SafeAreaView, Text, Modal, InputAccessoryView and so on).
Reviewed By: mmmulani
Differential Revision: D6863654
fbshipit-source-id: 5a6a933874f121d46f744aab99a31ae42ddd4a1b
Summary:
This change enables built-in Yoga mechanism which rounds producing layout metrics to closest "pixel" values.
See previous diff for more context.
Reviewed By: fkgozali
Differential Revision: D6889762
fbshipit-source-id: bc2eea44704db4b377e2e14fab9f67be8c935719
Summary:
> Okay, I don't remember where we first met
> But hey, admitting is the first step
This issue has a looong history.
The original algorithm was introduced by Nick Lockwood (nicklockwood Hey Nick! We miss you!) a while ago and from the very beginning this has one small error that basically makes it useless (try to find it yourself, it's fun!)
The problem was discovered and fixed twice (D4133643, D4983054), but every time we found that our <Text> infra was not ready for this, so we reverted and abandoned the change. As part of the last attempt to finally solve the issue, I ported the algorithm to Yoga where it lives today and works very well for Lytho and CK.
For now, the vision is clear:
* The basic algorithm should live in Yoga for unification and performance reasons.
* We still have to have `absolutePostion` as part of this API because it might be useful for some components which implement its own custom/non-Yoga-based layout.
* We have to enable it in RN eventually.
So, this is the first step: Removing old, broken code which we don't plan to fix and use.
Make React Native crisp again!
Reviewed By: fkgozali
Differential Revision: D6888662
fbshipit-source-id: 2e5098d9935dcbe05d66c777dad3a9ec8ac87ec3
Summary:
It's unused.
Use `display` prop instead to control visiblity of the view.
Reviewed By: fkgozali
Differential Revision: D6888104
fbshipit-source-id: dd37a365033ec36bdfcfa305ec6a965a10dec2cd
Summary: Another juicy leftover from old Text implementation.
Reviewed By: fkgozali
Differential Revision: D6887942
fbshipit-source-id: d0363d06d566554c03d0ae3293597daf9c387028
Summary: This is leftovers from last <Text> reimplementation; nobody uses it and it does not hooked up with UIManager.
Reviewed By: fkgozali
Differential Revision: D6887795
fbshipit-source-id: 9e2e29af4ba959270096eeb494666d1cacaeba32
Summary: It's been more than two years; I think everyone already migrated and learned the new behavior.
Reviewed By: emilsjolander
Differential Revision: D6829885
fbshipit-source-id: a86d56fb7235a137e9ce6e360d7ae2224b047313
Summary:
[this commit](2e1707d0e6) which was just a small refactor broke refreshControl behavior - if we render FlatList with refreshing=true, the refreshControl won't be visible on initial render.
The problem is, the [previous beginRefreshing method](2e1707d0e6 (diff-cfafa8d7e42ab87ab863f917e187a4aeL51)) was renamed to `beginRefreshingProgramatically` and the old call was left in one place [here](2e1707d0e6 (diff-cfafa8d7e42ab87ab863f917e187a4aeR47)).
Now, I am not sure what kind of jumping the mentioned commit was fixing, but since this fix only concerns the initial render, I believe it will not influence the jumping fix.
I have tested this locally in my app, can provide a video if needed.
none
[IOS] [BUGFIX] [RefreshControl] - Make sure refreshControl shows up on initial render if specified
Closes https://github.com/facebook/react-native/pull/17727
Differential Revision: D6827402
Pulled By: shergin
fbshipit-source-id: 25849244e87af54f25d636b6ade7adcf88958980
Summary:
This is a complete rewrite of RCTText, the part of React Native which manages Text and TextInput components.
Key points:
* It's understandable now. It follows a simple architectural pattern, and it's easy to debug and iterate. Text flow layout is a first-class citizen in React Native layout system now, not just a wired special case. It also brings entirely new possibilities such as nested interleaving <Text> and <View> components.
* All <Text>-specific APIs were removed from UIManager and co (it's about ~16 public methods which were used exclusively only by <Text>).
* It relies on new Yoga measurement/cloning API and on-dirty handler. So, it removes built-in dirty propagation subsystem from RN completely.
* It caches string fragments properly and granularly on a per-node basis which makes updating text-containing components more performant.
* It does not instantiate UIView for virtual components which reduces memory utilization.
* It drastically improves <TextInput> capabilities (e.g. rich text inside single line <TextInput> is now supported).
Screenshots:
https://cl.ly/2j3r1V0L0324https://cl.ly/3N2V3C3d3q3R
Reviewed By: mmmulani
Differential Revision: D6617326
fbshipit-source-id: 35d4d81b35c9870e9557d0211c0e934e6072a41e
Summary:
Builds off of cae7179c94
- Make the prop a dictionary for more configuration options
- Rename `maintainPositionAtOrBeyondIndex` -> `maintainVisibleContentPosition` + `minIndexForVisible`
- Add autoscroll threshold feature
Given the async native of RN JS and background layout, there is no way to trigger the scrollTo from JS without risking a delay, so we add the feature in native code.
== Test Plan ==
ScrollViewExample:
https://youtu.be/pmY8pxC9PRs
Reviewed By: shergin
Differential Revision: D6729160
fbshipit-source-id: 70f9bae460ce84567857a4f696da78ce9b3b834c
Summary:
Another trivial sugar/helper to access computed by Yoga layout metrics.
We will use it soon in the new Text render/layout engine.
Reviewed By: mmmulani
Differential Revision: D6671979
fbshipit-source-id: d36933415c2fa50bae5cc171434d8f0b281955b7
Summary:
== Problem / Background ==
Most lists paginate in a single direction (standard infinite list), but some paginate in both directions. Most common example is a chat thread where new messages show up on the bottom, and old content can be loaded by scrolling up. Comment threads are another example.
Right now, adding content to the bottom of a scroll view is smooth - the content doesn't jump. But when adding to the top of the scrollview, the content gets pushed down, which is jarring (note this may appear reversed because of inverting the list which is common for chat applications).
== Approach ==
The basic idea is simple - we set a flag in JS, then for every uimanager transaction, we record which is the first eligible and visible view in the ScrollView, and compare it's new origin to the old one. If it has changed, we update the contentOffset of the ScrollView to compensate.
This is done by observing `willPerformMounting` directly (only from scrollviews that have this new property set), and then observing the prev state with prependUIBlock and making the update synchronously in addUIBlock to avoid any flicker.
There is also a way to skip views that we don't care about, like a spinner at the top of the view that we don't want to stay in place - we actually want it to get pushed up by the new content, replaced visually in the viewport.
== Notes ==
Most chat applications will probably want to do a scrollToTop when new content comes in and the user is already scrolled at or near the bottom.
This is glitchy if visible children are re-ordered, which could be fixed with additional logic, but it doesn't come up in the type of applications we're targetting here so punting on that.
== Test Plan ==
https://youtu.be/4GcqDGz9eOE
Reviewed By: shergin
Differential Revision: D6696921
fbshipit-source-id: 822e7dfcb207006cd1ba098356324ea81f619428
Summary:
Fix issue #17027 (`RCTModalHostView` has a tvOS dependency that was not wrapped in `TARGET_OS_TV`)
Existing test automation should pass.
[GENERAL] [BUGFIX] [tvOS] Fix cocoapods compile issue in RCTModalHostView
Closes https://github.com/facebook/react-native/pull/17502
Differential Revision: D6688166
Pulled By: hramos
fbshipit-source-id: 38297f439f75a8303f59f83b92e004c6c73d9bf6
Summary:
That's now possible thanks to new Yoga's clonning API.
That will speed up RCTSurface measuring (see the next diff in stack) and should illuminate a class of problems in CK interop layer.
We also will use it in the new text layout engine (in React Native).
Reviewed By: gkassabli
Differential Revision: D6665632
fbshipit-source-id: e94909f0af89e9c7fc5e46b95090ecb3c52546a2
Summary:
Yoga and CoreGraphics have different opinions about how "infinity" value
should be represented.
Yoga uses `NAN` which requires additional effort to compare all those values,
whereas GoreGraphics uses `GFLOAT_MAX` which can be easyly compared with
standard `==` operator.
Messing with this can cause super weired bugs like 100% CPU load for couple of seconds somewhere in CoreGraphics.
Reviewed By: mmmulani
Differential Revision: D6665633
fbshipit-source-id: b6236c6fa50d1f8fb0c9576203922f7b24b7301e
Summary:
Those are supposed to replace all `dirtyText`, `dirtyPropagation`, `isPropagationDirty`, `setTextComputed`, `isTextDirty` and so on.
We will use it widely soon (and remove all old ones).
Reviewed By: mmmulani
Differential Revision: D6665634
fbshipit-source-id: 3c1db7154e90b71446756f2495627b163c779996
Summary:
It's always bothered that we have this protocol and I figured it could just be merged with RCTWrapperViewController.
Closes https://github.com/facebook/react-native/pull/17290
Reviewed By: mmmulani
Differential Revision: D6611544
Pulled By: javache
fbshipit-source-id: a50b9d5adbeb2c48dbadbbfc1c77ccf6d1aae144
Summary:
Nobody uses it.
If the reference to the bridge is available (which is should be case for testing purposes at least), it is easy to get same information.
Reviewed By: mmmulani
Differential Revision: D6596376
fbshipit-source-id: 066eeb1e9465b4e0cc9d9b5b6bf41722450870e4
Summary:
Motivation:
* Current implementation of `didUpdateReactSubviews` relies on `processUpdatedProperties:parentProperties:` method of RCTShadowView, which we plan to remove.
* The existing implementation does not call handlers on unmounted nodes (because they are not part of traversing tree), which is not correct.
* The current implementation is tight with RCTComponentData, which is conceptually wrong, it should be a UIManager thing.
* The new implementation must be much more performant because of simplicity. (We can measure it only after removing `processUpdatedProperties`.)
Reviewed By: mmmulani
Differential Revision: D6595780
fbshipit-source-id: a517207c17b5d5db839c9ce99a37136292acf78c