Compare commits

...
Author SHA1 Message Date
Mike Grabowski 0c1c66e719 [0.58.0-rc.0] Bump version numbers 2018-11-22 18:30:52 +01:00
Mike Grabowski e71fb64ecd Apply same config for Android 2018-11-22 18:29:16 +01:00
Mike Grabowski 26bdd5ba4e Make Metro untyped instead of ignored to let Metro-config resolve type annotations 2018-11-22 18:25:47 +01:00
Mike Grabowski e0ea58ecbd Add missing Metro Config 2018-11-22 18:18:37 +01:00
Kudo ChienandMike Grabowski 64dd60fb7d Fix ReactAndroid build break. (#22377)
Summary:
During C++ build, we need the libjsc.so.
  But arm64-v8a and x86_64 libjsc.so are in different path and this error raised:

    Android NDK: ERROR:/home/circleci/react-native/ReactAndroid/build/third-party-ndk/jsc/Android.mk:jsc: LOCAL_SRC_FILES points to a missing file
    /opt/ndk/android-ndk-r17c/build/core/prebuilt-library.mk:45: *** Android NDK: Aborting    .  Stop.
    Android NDK: Check that /home/circleci/react-native/ReactAndroid/build/third-party-ndk/jsc/jni/arm64-v8a/libjsc.so exists  or that its path is correct

  The commit moves prebuilt libjsc.so into
  ReactAndroid/src/main/jni/third-party/jsc/jni and let ndkbuild script find the prebuilt libjsc.so.
  For AAR packaging, modify the jniLibs so that gradle android library plugin could find the prebuilt libjsc.so as well.
Pull Request resolved: https://github.com/facebook/react-native/pull/22377

Differential Revision: D13166556

Pulled By: hramos

fbshipit-source-id: 61daaede7defbc66491a3e2f20058e7d248ba13e
2018-11-22 17:55:40 +01:00
gengjiawenandMike Grabowski d4d457b4eb Fix jsc regression.Fixes #22274 (#22293)
Summary:
My silly mistake when tinkering with the jsc lib. Also you have this patch first https://github.com/facebook/react-native/pull/22295.
Kudo plz review.

![image](https://user-images.githubusercontent.com/3759816/48561684-758f6f00-e92b-11e8-905b-e394f72349f7.png)
Pull Request resolved: https://github.com/facebook/react-native/pull/22293

Differential Revision: D13153931

Pulled By: hramos

fbshipit-source-id: 8a6efa0cd8abbff359f082d5ea7713933b6e7ac6
2018-11-22 17:55:31 +01:00
Mike Grabowski b864e7e63e Revert "Merge branch 'master' into 0.58-stable"
This reverts commit 696bd89013, reversing
changes made to a525941ab6.
2018-11-22 17:53:44 +01:00
Mike Grabowski 696bd89013 Merge branch 'master' into 0.58-stable 2018-11-22 17:33:25 +01:00
Rafael OlezaandMike Grabowski a525941ab6 Bump metro@0.49.1
Summary: galavant-fistbump

Reviewed By: jeanlauliac

Differential Revision: D13027247

fbshipit-source-id: 3635527b6c745111b26d9f61666c30e696b04526
2018-11-13 23:52:11 +01:00
131 changed files with 1208 additions and 2525 deletions
+4 -4
View File
@@ -22,9 +22,6 @@
; Ignore polyfills
.*/Libraries/polyfills/.*
; Ignore metro
.*/node_modules/metro/.*
; These should not be required directly
; require from fbjs/lib instead: require('fbjs/lib/invariant')
.*/node_modules/invariant/.*
@@ -101,4 +98,7 @@ untyped-import
untyped-type-import
[version]
^0.86.0
^0.85.0
[untyped]
.*/node_modules/metro/.*
+4 -4
View File
@@ -22,9 +22,6 @@
; Ignore polyfills
.*/Libraries/polyfills/.*
; Ignore metro
.*/node_modules/metro/.*
; These should not be required directly
; require from fbjs/lib instead: require('fbjs/lib/invariant')
.*/node_modules/invariant/.*
@@ -101,4 +98,7 @@ untyped-import
untyped-type-import
[version]
^0.86.0
^0.85.0
[untyped]
.*/node_modules/metro/.*
@@ -349,6 +349,9 @@ class AnimatedInterpolation extends AnimatedWithChildren {
__transformDataType(range: Array<any>) {
// Change the string array type to number array
// So we can reuse the same logic in iOS and Android platform
/* $FlowFixMe(>=0.70.0 site=react_native_fb) This comment suppresses an
* error found when Flow v0.70 was deployed. To see the error delete this
* comment and run Flow. */
return range.map(function(value) {
if (typeof value !== 'string') {
return value;
+1 -41
View File
@@ -16,16 +16,6 @@
#import <React/RCTRootView.h>
#import <React/RCTUtils.h>
@interface RCTImagePickerController : UIImagePickerController
@property (nonatomic, assign) BOOL unmirrorFrontFacingCamera;
@end
@implementation RCTImagePickerController
@end
@interface RCTImagePickerManager () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@end
@@ -41,22 +31,6 @@ RCT_EXPORT_MODULE(ImagePickerIOS);
@synthesize bridge = _bridge;
- (id)init
{
if (self = [super init]) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(cameraChanged:)
name:@"AVCaptureDeviceDidStartRunningNotification"
object:nil];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"AVCaptureDeviceDidStartRunningNotification" object:nil];
}
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
@@ -82,10 +56,9 @@ RCT_EXPORT_METHOD(openCameraDialog:(NSDictionary *)config
return;
}
RCTImagePickerController *imagePicker = [RCTImagePickerController new];
UIImagePickerController *imagePicker = [UIImagePickerController new];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.unmirrorFrontFacingCamera = [RCTConvert BOOL:config[@"unmirrorFrontFacingCamera"]];
if ([RCTConvert BOOL:config[@"videoMode"]]) {
imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
@@ -202,17 +175,4 @@ didFinishPickingMediaWithInfo:(NSDictionary<NSString *, id> *)info
}
}
- (void)cameraChanged:(NSNotification *)notification
{
for (UIImagePickerController *picker in _pickers) {
if ([picker isKindOfClass:[RCTImagePickerController class]]
&& ((RCTImagePickerController *)picker).unmirrorFrontFacingCamera
&& picker.cameraDevice == UIImagePickerControllerCameraDeviceFront) {
picker.cameraViewTransform = CGAffineTransformScale(CGAffineTransformIdentity, -1, 1);
} else {
picker.cameraViewTransform = CGAffineTransformIdentity;
}
}
}
@end
@@ -14,42 +14,27 @@ export type TVParallaxPropertiesType = $ReadOnly<{|
/**
* If true, parallax effects are enabled. Defaults to true.
*/
enabled?: boolean,
enabled: boolean,
/**
* Defaults to 2.0.
*/
shiftDistanceX?: number,
shiftDistanceX: number,
/**
* Defaults to 2.0.
*/
shiftDistanceY?: number,
shiftDistanceY: number,
/**
* Defaults to 0.05.
*/
tiltAngle?: number,
tiltAngle: number,
/**
* Defaults to 1.0
*/
magnification?: number,
/**
* Defaults to 1.0
*/
pressMagnification?: number,
/**
* Defaults to 0.3
*/
pressDuration?: number,
/**
* Defaults to 0.3
*/
pressDelay?: number,
magnification: number,
|}>;
/**
@@ -4,150 +4,35 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
'use strict';
const DeprecatedColorPropType = require('DeprecatedColorPropType');
const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes');
const NativeMethodsMixin = require('NativeMethodsMixin');
const Platform = require('Platform');
const PropTypes = require('prop-types');
const React = require('React');
const ReactNative = require('ReactNative');
const StatusBar = require('StatusBar');
const StyleSheet = require('StyleSheet');
const UIManager = require('UIManager');
const View = require('View');
const nullthrows = require('nullthrows');
const DrawerConsts = UIManager.getViewManagerConfig('AndroidDrawerLayout')
.Constants;
const createReactClass = require('create-react-class');
const dismissKeyboard = require('dismissKeyboard');
const requireNativeComponent = require('requireNativeComponent');
const RK_DRAWER_REF = 'drawerlayout';
const INNERVIEW_REF = 'innerView';
const DRAWER_STATES = ['Idle', 'Dragging', 'Settling'];
import type {ViewStyleProp} from 'StyleSheet';
import type {ColorValue} from 'StyleSheetTypes';
import type {SyntheticEvent} from 'CoreEventTypes';
import type {
MeasureOnSuccessCallback,
MeasureInWindowOnSuccessCallback,
MeasureLayoutOnSuccessCallback,
} from 'ReactNativeTypes';
type DrawerStates = 'Idle' | 'Dragging' | 'Settling';
type DrawerStateEvent = SyntheticEvent<
$ReadOnly<{|
drawerState: number,
|}>,
>;
type DrawerSlideEvent = SyntheticEvent<
$ReadOnly<{|
offset: number,
|}>,
>;
type Props = $ReadOnly<{|
/**
* Determines whether the keyboard gets dismissed in response to a drag.
* - 'none' (the default), drags do not dismiss the keyboard.
* - 'on-drag', the keyboard is dismissed when a drag begins.
*/
keyboardDismissMode?: ?('none' | 'on-drag'),
/**
* Specifies the background color of the drawer. The default value is white.
* If you want to set the opacity of the drawer, use rgba. Example:
*
* ```
* return (
* <DrawerLayoutAndroid drawerBackgroundColor="rgba(0,0,0,0.5)">
* </DrawerLayoutAndroid>
* );
* ```
*/
drawerBackgroundColor: ColorValue,
/**
* Specifies the side of the screen from which the drawer will slide in.
*/
drawerPosition: ?number,
/**
* Specifies the width of the drawer, more precisely the width of the view that be pulled in
* from the edge of the window.
*/
drawerWidth?: ?number,
/**
* Specifies the lock mode of the drawer. The drawer can be locked in 3 states:
* - unlocked (default), meaning that the drawer will respond (open/close) to touch gestures.
* - locked-closed, meaning that the drawer will stay closed and not respond to gestures.
* - locked-open, meaning that the drawer will stay opened and not respond to gestures.
* The drawer may still be opened and closed programmatically (`openDrawer`/`closeDrawer`).
*/
drawerLockMode?: ?('unlocked' | 'locked-closed' | 'locked-open'),
/**
* Function called whenever there is an interaction with the navigation view.
*/
onDrawerSlide?: ?(event: DrawerSlideEvent) => mixed,
/**
* Function called when the drawer state has changed. The drawer can be in 3 states:
* - Idle, meaning there is no interaction with the navigation view happening at the time
* - Dragging, meaning there is currently an interaction with the navigation view
* - Settling, meaning that there was an interaction with the navigation view, and the
* navigation view is now finishing its closing or opening animation
*/
onDrawerStateChanged?: ?(state: DrawerStates) => mixed,
/**
* Function called whenever the navigation view has been opened.
*/
onDrawerOpen?: ?() => mixed,
/**
* Function called whenever the navigation view has been closed.
*/
onDrawerClose?: ?() => mixed,
/**
* The navigation view that will be rendered to the side of the screen and can be pulled in.
*/
renderNavigationView: () => React.Element<any>,
/**
* Make the drawer take the entire screen and draw the background of the
* status bar to allow it to open over the status bar. It will only have an
* effect on API 21+.
*/
statusBarBackgroundColor?: ?ColorValue,
children?: React.Node,
style?: ?ViewStyleProp,
|}>;
type NativeProps = $ReadOnly<{|
...$Diff<
Props,
$ReadOnly<{onDrawerStateChanged?: ?(state: DrawerStates) => mixed}>,
>,
onDrawerStateChanged?: ?(state: DrawerStateEvent) => mixed,
|}>;
type State = {|
statusBarBackgroundColor: ColorValue,
|};
// The View that contains both the actual drawer and the main view
const AndroidDrawerLayout = ((requireNativeComponent(
'AndroidDrawerLayout',
): any): Class<ReactNative.NativeComponent<NativeProps>>);
/**
* React component that wraps the platform `DrawerLayout` (Android only). The
* Drawer (typically used for navigation) is rendered with `renderNavigationView`
@@ -179,20 +64,109 @@ const AndroidDrawerLayout = ((requireNativeComponent(
* },
* ```
*/
class DrawerLayoutAndroid extends React.Component<Props, State> {
static positions = DrawerConsts.DrawerPosition;
static defaultProps = {
drawerBackgroundColor: 'white',
};
const DrawerLayoutAndroid = createReactClass({
displayName: 'DrawerLayoutAndroid',
statics: {
positions: DrawerConsts.DrawerPosition,
},
_nativeRef = React.createRef<
Class<ReactNative.NativeComponent<NativeProps>>,
>();
propTypes: {
...DeprecatedViewPropTypes,
/**
* Determines whether the keyboard gets dismissed in response to a drag.
* - 'none' (the default), drags do not dismiss the keyboard.
* - 'on-drag', the keyboard is dismissed when a drag begins.
*/
keyboardDismissMode: PropTypes.oneOf([
'none', // default
'on-drag',
]),
/**
* Specifies the background color of the drawer. The default value is white.
* If you want to set the opacity of the drawer, use rgba. Example:
*
* ```
* return (
* <DrawerLayoutAndroid drawerBackgroundColor="rgba(0,0,0,0.5)">
* </DrawerLayoutAndroid>
* );
* ```
*/
drawerBackgroundColor: DeprecatedColorPropType,
/**
* Specifies the side of the screen from which the drawer will slide in.
*/
drawerPosition: PropTypes.oneOf([
DrawerConsts.DrawerPosition.Left,
DrawerConsts.DrawerPosition.Right,
]),
/**
* Specifies the width of the drawer, more precisely the width of the view that be pulled in
* from the edge of the window.
*/
drawerWidth: PropTypes.number,
/**
* Specifies the lock mode of the drawer. The drawer can be locked in 3 states:
* - unlocked (default), meaning that the drawer will respond (open/close) to touch gestures.
* - locked-closed, meaning that the drawer will stay closed and not respond to gestures.
* - locked-open, meaning that the drawer will stay opened and not respond to gestures.
* The drawer may still be opened and closed programmatically (`openDrawer`/`closeDrawer`).
*/
drawerLockMode: PropTypes.oneOf([
'unlocked',
'locked-closed',
'locked-open',
]),
/**
* Function called whenever there is an interaction with the navigation view.
*/
onDrawerSlide: PropTypes.func,
/**
* Function called when the drawer state has changed. The drawer can be in 3 states:
* - idle, meaning there is no interaction with the navigation view happening at the time
* - dragging, meaning there is currently an interaction with the navigation view
* - settling, meaning that there was an interaction with the navigation view, and the
* navigation view is now finishing its closing or opening animation
*/
onDrawerStateChanged: PropTypes.func,
/**
* Function called whenever the navigation view has been opened.
*/
onDrawerOpen: PropTypes.func,
/**
* Function called whenever the navigation view has been closed.
*/
onDrawerClose: PropTypes.func,
/**
* The navigation view that will be rendered to the side of the screen and can be pulled in.
*/
renderNavigationView: PropTypes.func.isRequired,
state = {statusBarBackgroundColor: null};
/**
* Make the drawer take the entire screen and draw the background of the
* status bar to allow it to open over the status bar. It will only have an
* effect on API 21+.
*/
statusBarBackgroundColor: DeprecatedColorPropType,
},
render() {
const {onDrawerStateChanged, ...props} = this.props;
mixins: [NativeMethodsMixin],
getDefaultProps: function(): {drawerBackgroundColor: string} {
return {
drawerBackgroundColor: 'white',
};
},
getInitialState: function() {
return {statusBarBackgroundColor: undefined};
},
getInnerViewNode: function() {
return this.refs[INNERVIEW_REF].getInnerViewNode();
},
render: function() {
const drawStatusBar =
Platform.Version >= 21 && this.props.statusBarBackgroundColor;
const drawerViewWrapper = (
@@ -210,7 +184,7 @@ class DrawerLayoutAndroid extends React.Component<Props, State> {
</View>
);
const childrenWrapper = (
<View style={styles.mainSubview} collapsable={false}>
<View ref={INNERVIEW_REF} style={styles.mainSubview} collapsable={false}>
{drawStatusBar && (
<StatusBar
translucent
@@ -230,8 +204,8 @@ class DrawerLayoutAndroid extends React.Component<Props, State> {
);
return (
<AndroidDrawerLayout
{...props}
ref={this._nativeRef}
{...this.props}
ref={RK_DRAWER_REF}
drawerWidth={this.props.drawerWidth}
drawerPosition={this.props.drawerPosition}
drawerLockMode={this.props.drawerLockMode}
@@ -244,60 +218,59 @@ class DrawerLayoutAndroid extends React.Component<Props, State> {
{drawerViewWrapper}
</AndroidDrawerLayout>
);
}
},
_onDrawerSlide = (event: DrawerSlideEvent) => {
_onDrawerSlide: function(event) {
if (this.props.onDrawerSlide) {
this.props.onDrawerSlide(event);
}
if (this.props.keyboardDismissMode === 'on-drag') {
dismissKeyboard();
}
};
},
_onDrawerOpen = () => {
_onDrawerOpen: function() {
if (this.props.onDrawerOpen) {
this.props.onDrawerOpen();
}
};
},
_onDrawerClose = () => {
_onDrawerClose: function() {
if (this.props.onDrawerClose) {
this.props.onDrawerClose();
}
};
},
_onDrawerStateChanged = (event: DrawerStateEvent) => {
_onDrawerStateChanged: function(event) {
if (this.props.onDrawerStateChanged) {
this.props.onDrawerStateChanged(
DRAWER_STATES[event.nativeEvent.drawerState],
);
}
};
},
/**
* Opens the drawer.
*/
openDrawer() {
openDrawer: function() {
UIManager.dispatchViewManagerCommand(
this._getDrawerLayoutHandle(),
UIManager.getViewManagerConfig('AndroidDrawerLayout').Commands.openDrawer,
null,
);
}
},
/**
* Closes the drawer.
*/
closeDrawer() {
closeDrawer: function() {
UIManager.dispatchViewManagerCommand(
this._getDrawerLayoutHandle(),
UIManager.getViewManagerConfig('AndroidDrawerLayout').Commands
.closeDrawer,
null,
);
}
},
/**
* Closing and opening example
* Note: To access the drawer you have to give it a ref. Refs do not work on stateless components
@@ -314,45 +287,10 @@ class DrawerLayoutAndroid extends React.Component<Props, State> {
* )
* }
*/
_getDrawerLayoutHandle() {
return ReactNative.findNodeHandle(this._nativeRef.current);
}
/**
* Native methods
*/
blur() {
nullthrows(this._nativeRef.current).blur();
}
focus() {
nullthrows(this._nativeRef.current).focus();
}
measure(callback: MeasureOnSuccessCallback) {
nullthrows(this._nativeRef.current).measure(callback);
}
measureInWindow(callback: MeasureInWindowOnSuccessCallback) {
nullthrows(this._nativeRef.current).measureInWindow(callback);
}
measureLayout(
relativeToNativeNode: number,
onSuccess: MeasureLayoutOnSuccessCallback,
onFail?: () => void,
) {
nullthrows(this._nativeRef.current).measureLayout(
relativeToNativeNode,
onSuccess,
onFail,
);
}
setNativeProps(nativeProps: Object) {
nullthrows(this._nativeRef.current).setNativeProps(nativeProps);
}
}
_getDrawerLayoutHandle: function() {
return ReactNative.findNodeHandle(this.refs[RK_DRAWER_REF]);
},
});
const styles = StyleSheet.create({
base: {
@@ -384,4 +322,7 @@ const styles = StyleSheet.create({
},
});
// The View that contains both the actual drawer and the main view
const AndroidDrawerLayout = requireNativeComponent('AndroidDrawerLayout');
module.exports = DrawerLayoutAndroid;
+27 -31
View File
@@ -24,8 +24,6 @@ const warning = require('fbjs/lib/warning');
const {ScrollViewManager} = require('NativeModules');
import type {PressEvent, ScrollEvent} from 'CoreEventTypes';
import type {KeyboardEvent} from 'Keyboard';
import type EmitterSubscription from 'EmitterSubscription';
/**
@@ -115,6 +113,7 @@ type State = {
observedScrollSinceBecomingResponder: boolean,
becameResponderWhileAnimating: boolean,
};
type Event = Object;
const ScrollResponderMixin = {
_subscriptionKeyboardWillShow: (null: ?EmitterSubscription),
@@ -169,9 +168,7 @@ const ScrollResponderMixin = {
* true.
*
*/
scrollResponderHandleStartShouldSetResponder: function(
e: PressEvent,
): boolean {
scrollResponderHandleStartShouldSetResponder: function(e: Event): boolean {
const currentlyFocusedTextInput = TextInputState.currentlyFocusedField();
if (
@@ -196,7 +193,7 @@ const ScrollResponderMixin = {
* Invoke this from an `onStartShouldSetResponderCapture` event.
*/
scrollResponderHandleStartShouldSetResponderCapture: function(
e: PressEvent,
e: Event,
): boolean {
// The scroll view should receive taps instead of its descendants if:
// * it is already animating/decelerating
@@ -215,7 +212,6 @@ const ScrollResponderMixin = {
if (
keyboardNeverPersistTaps &&
currentlyFocusedTextInput != null &&
e.target &&
!TextInputState.isTextInput(e.target)
) {
return true;
@@ -258,9 +254,9 @@ const ScrollResponderMixin = {
/**
* Invoke this from an `onTouchEnd` event.
*
* @param {PressEvent} e Event.
* @param {SyntheticEvent} e Event.
*/
scrollResponderHandleTouchEnd: function(e: PressEvent) {
scrollResponderHandleTouchEnd: function(e: Event) {
const nativeEvent = e.nativeEvent;
this.state.isTouching = nativeEvent.touches.length !== 0;
this.props.onTouchEnd && this.props.onTouchEnd(e);
@@ -269,9 +265,9 @@ const ScrollResponderMixin = {
/**
* Invoke this from an `onTouchCancel` event.
*
* @param {PressEvent} e Event.
* @param {SyntheticEvent} e Event.
*/
scrollResponderHandleTouchCancel: function(e: PressEvent) {
scrollResponderHandleTouchCancel: function(e: Event) {
this.state.isTouching = false;
this.props.onTouchCancel && this.props.onTouchCancel(e);
},
@@ -279,7 +275,7 @@ const ScrollResponderMixin = {
/**
* Invoke this from an `onResponderRelease` event.
*/
scrollResponderHandleResponderRelease: function(e: PressEvent) {
scrollResponderHandleResponderRelease: function(e: Event) {
this.props.onResponderRelease && this.props.onResponderRelease(e);
// By default scroll views will unfocus a textField
@@ -299,7 +295,7 @@ const ScrollResponderMixin = {
}
},
scrollResponderHandleScroll: function(e: ScrollEvent) {
scrollResponderHandleScroll: function(e: Event) {
this.state.observedScrollSinceBecomingResponder = true;
this.props.onScroll && this.props.onScroll(e);
},
@@ -307,7 +303,7 @@ const ScrollResponderMixin = {
/**
* Invoke this from an `onResponderGrant` event.
*/
scrollResponderHandleResponderGrant: function(e: ScrollEvent) {
scrollResponderHandleResponderGrant: function(e: Event) {
this.state.observedScrollSinceBecomingResponder = false;
this.props.onResponderGrant && this.props.onResponderGrant(e);
this.state.becameResponderWhileAnimating = this.scrollResponderIsAnimating();
@@ -320,7 +316,7 @@ const ScrollResponderMixin = {
*
* Invoke this from an `onScrollBeginDrag` event.
*/
scrollResponderHandleScrollBeginDrag: function(e: ScrollEvent) {
scrollResponderHandleScrollBeginDrag: function(e: Event) {
FrameRateLogger.beginScroll(); // TODO: track all scrolls after implementing onScrollEndAnimation
this.props.onScrollBeginDrag && this.props.onScrollBeginDrag(e);
},
@@ -328,7 +324,7 @@ const ScrollResponderMixin = {
/**
* Invoke this from an `onScrollEndDrag` event.
*/
scrollResponderHandleScrollEndDrag: function(e: ScrollEvent) {
scrollResponderHandleScrollEndDrag: function(e: Event) {
const {velocity} = e.nativeEvent;
// - If we are animating, then this is a "drag" that is stopping the scrollview and momentum end
// will fire.
@@ -347,7 +343,7 @@ const ScrollResponderMixin = {
/**
* Invoke this from an `onMomentumScrollBegin` event.
*/
scrollResponderHandleMomentumScrollBegin: function(e: ScrollEvent) {
scrollResponderHandleMomentumScrollBegin: function(e: Event) {
this.state.lastMomentumScrollBeginTime = performanceNow();
this.props.onMomentumScrollBegin && this.props.onMomentumScrollBegin(e);
},
@@ -355,7 +351,7 @@ const ScrollResponderMixin = {
/**
* Invoke this from an `onMomentumScrollEnd` event.
*/
scrollResponderHandleMomentumScrollEnd: function(e: ScrollEvent) {
scrollResponderHandleMomentumScrollEnd: function(e: Event) {
FrameRateLogger.endScroll();
this.state.lastMomentumScrollEndTime = performanceNow();
this.props.onMomentumScrollEnd && this.props.onMomentumScrollEnd(e);
@@ -370,9 +366,9 @@ const ScrollResponderMixin = {
* responder). The `onResponderReject` won't fire in that case - it only
* fires when a *current* responder rejects our request.
*
* @param {PressEvent} e Touch Start event.
* @param {SyntheticEvent} e Touch Start event.
*/
scrollResponderHandleTouchStart: function(e: PressEvent) {
scrollResponderHandleTouchStart: function(e: Event) {
this.state.isTouching = true;
this.props.onTouchStart && this.props.onTouchStart(e);
},
@@ -386,9 +382,9 @@ const ScrollResponderMixin = {
* responder). The `onResponderReject` won't fire in that case - it only
* fires when a *current* responder rejects our request.
*
* @param {PressEvent} e Touch Start event.
* @param {SyntheticEvent} e Touch Start event.
*/
scrollResponderHandleTouchMove: function(e: PressEvent) {
scrollResponderHandleTouchMove: function(e: Event) {
this.props.onTouchMove && this.props.onTouchMove(e);
},
@@ -413,7 +409,7 @@ const ScrollResponderMixin = {
* Components can pass what node to use by defining a `getScrollableNode`
* function otherwise `this` is used.
*/
scrollResponderGetScrollableNode: function(): ?number {
scrollResponderGetScrollableNode: function(): any {
return this.getScrollableNode
? this.getScrollableNode()
: ReactNative.findNodeHandle(this);
@@ -531,14 +527,14 @@ const ScrollResponderMixin = {
* This method should be used as the callback to onFocus in a TextInputs'
* parent view. Note that any module using this mixin needs to return
* the parent view's ref in getScrollViewRef() in order to use this method.
* @param {number} nodeHandle The TextInput node handle
* @param {any} nodeHandle The TextInput node handle
* @param {number} additionalOffset The scroll view's bottom "contentInset".
* Default is 0.
* @param {bool} preventNegativeScrolling Whether to allow pulling the content
* down to make it meet the keyboard's top. Default is false.
*/
scrollResponderScrollNativeHandleToKeyboard: function(
nodeHandle: number,
nodeHandle: any,
additionalOffset?: number,
preventNegativeScrollOffset?: boolean,
) {
@@ -588,8 +584,8 @@ const ScrollResponderMixin = {
this.preventNegativeScrollOffset = false;
},
scrollResponderTextInputFocusError: function(msg: string) {
console.error('Error measuring text field: ', msg);
scrollResponderTextInputFocusError: function(e: Event) {
console.error('Error measuring text field: ', e);
},
/**
@@ -671,17 +667,17 @@ const ScrollResponderMixin = {
* relevant to you. (For example, only if you receive these callbacks after
* you had explicitly focused a node etc).
*/
scrollResponderKeyboardWillShow: function(e: KeyboardEvent) {
scrollResponderKeyboardWillShow: function(e: Event) {
this.keyboardWillOpenTo = e;
this.props.onKeyboardWillShow && this.props.onKeyboardWillShow(e);
},
scrollResponderKeyboardWillHide: function(e: KeyboardEvent) {
scrollResponderKeyboardWillHide: function(e: Event) {
this.keyboardWillOpenTo = null;
this.props.onKeyboardWillHide && this.props.onKeyboardWillHide(e);
},
scrollResponderKeyboardDidShow: function(e: KeyboardEvent) {
scrollResponderKeyboardDidShow: function(e: Event) {
// TODO(7693961): The event for DidShow is not available on iOS yet.
// Use the one from WillShow and do not assign.
if (e) {
@@ -690,7 +686,7 @@ const ScrollResponderMixin = {
this.props.onKeyboardDidShow && this.props.onKeyboardDidShow(e);
},
scrollResponderKeyboardDidHide: function(e: KeyboardEvent) {
scrollResponderKeyboardDidHide: function(e: Event) {
this.keyboardWillOpenTo = null;
this.props.onKeyboardDidHide && this.props.onKeyboardDidHide(e);
},
@@ -396,8 +396,8 @@ export type Props = $ReadOnly<{|
* - `false`, deprecated, use 'never' instead
* - `true`, deprecated, use 'always' instead
*/
/* $FlowFixMe(>=0.86.0 site=react_native_fb) This comment suppresses an error
* found when Flow v0.86 was deployed. To see the error, delete this comment
/* $FlowFixMe(>=0.85.0 site=react_native_fb) This comment suppresses an error
* found when Flow v0.85 was deployed. To see the error, delete this comment
* and run Flow. */
keyboardShouldPersistTaps?: ?('always' | 'never' | 'handled' | false | true),
/**
+38 -70
View File
@@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
* @flow
*/
'use strict';
@@ -103,56 +103,13 @@ type Props = $ReadOnly<{|
barStyle?: ?('default' | 'light-content' | 'dark-content'),
|}>;
type StackEntryProps = {|
/**
* The background color of the status bar.
*
* @platform android
*/
backgroundColor: {|
value: ?string,
animated: ?boolean,
|},
/**
* Sets the color of the status bar text.
*/
barStyle: {|
value: ?string,
animated: ?boolean,
|},
/**
* If the status bar is translucent.
* When translucent is set to true, the app will draw under the status bar.
* This is useful when using a semi transparent status bar color.
*/
translucent: ?boolean,
/**
*
*/
hidden: {|
value: ?boolean,
animated: boolean,
transition: ?('slide' | 'fade'),
|},
/**
* If the network activity indicator should be visible.
*
* @platform ios
*/
networkActivityIndicatorVisible: ?boolean,
|};
/**
* Merges the prop stack with the default values.
*/
function mergePropsStack(
propsStack: $ReadOnlyArray<StackEntryProps>,
defaultValues: StackEntryProps,
): StackEntryProps {
const init: StackEntryProps = {
...defaultValues,
};
propsStack: Array<Object>,
defaultValues: Object,
): Object {
return propsStack.reduce((prev, cur) => {
for (const prop in cur) {
if (cur[prop] != null) {
@@ -160,31 +117,39 @@ function mergePropsStack(
}
}
return prev;
}, init);
}, Object.assign({}, defaultValues));
}
/**
* Returns an object to insert in the props stack from the props
* and the transition/animation info.
*/
function createStackEntry(props: Props): StackEntryProps {
function createStackEntry(props: any): any {
return {
backgroundColor: {
value: props.backgroundColor,
animated: props.animated,
},
barStyle: {
value: props.barStyle,
animated: props.animated,
},
translucent: props.translucent || false,
hidden: {
value: props.hidden,
animated: props.animated || false,
transition: props.showHideTransition,
},
networkActivityIndicatorVisible:
props.networkActivityIndicatorVisible || false,
backgroundColor:
props.backgroundColor != null
? {
value: props.backgroundColor,
animated: props.animated,
}
: null,
barStyle:
props.barStyle != null
? {
value: props.barStyle,
animated: props.animated,
}
: null,
translucent: props.translucent,
hidden:
props.hidden != null
? {
value: props.hidden,
animated: props.animated,
transition: props.showHideTransition,
}
: null,
networkActivityIndicatorVisible: props.networkActivityIndicatorVisible,
};
}
@@ -228,9 +193,9 @@ function createStackEntry(props: Props): StackEntryProps {
* `currentHeight` (Android only) The height of the status bar.
*/
class StatusBar extends React.Component<Props> {
static _propsStack: Array<StackEntryProps> = [];
static _propsStack = [];
static _defaultProps: StackEntryProps = createStackEntry({
static _defaultProps = createStackEntry({
animated: false,
showHideTransition: 'fade',
backgroundColor: 'black',
@@ -265,9 +230,10 @@ class StatusBar extends React.Component<Props> {
* changing the status bar hidden property.
*/
static setHidden(hidden: boolean, animation?: StatusBarAnimation) {
animation = animation || 'none';
StatusBar._defaultProps.hidden.value = hidden;
if (Platform.OS === 'ios') {
StatusBarManager.setHidden(hidden, animation || 'none');
StatusBarManager.setHidden(hidden, animation);
} else if (Platform.OS === 'android') {
StatusBarManager.setHidden(hidden);
}
@@ -279,9 +245,10 @@ class StatusBar extends React.Component<Props> {
* @param animated Animate the style change.
*/
static setBarStyle(style: StatusBarStyle, animated?: boolean) {
animated = animated || false;
StatusBar._defaultProps.barStyle.value = style;
if (Platform.OS === 'ios') {
StatusBarManager.setStyle(style, animated || false);
StatusBarManager.setStyle(style, animated);
} else if (Platform.OS === 'android') {
StatusBarManager.setStyle(style);
}
@@ -312,8 +279,9 @@ class StatusBar extends React.Component<Props> {
console.warn('`setBackgroundColor` is only available on Android');
return;
}
animated = animated || false;
StatusBar._defaultProps.backgroundColor.value = color;
StatusBarManager.setColor(processColor(color), animated || false);
StatusBarManager.setColor(processColor(color), animated);
}
/**
+26 -93
View File
@@ -34,8 +34,6 @@ const warning = require('fbjs/lib/warning');
import type {TextStyleProp, ViewStyleProp} from 'StyleSheet';
import type {ColorValue} from 'StyleSheetTypes';
import type {ViewProps} from 'ViewPropTypes';
import type {SyntheticEvent, ScrollEvent} from 'CoreEventTypes';
import type {PressEvent} from 'CoreEventTypes';
let AndroidTextInput;
let RCTMultilineTextInputView;
@@ -57,73 +55,11 @@ const onlyMultiline = {
children: true,
};
export type ChangeEvent = SyntheticEvent<
$ReadOnly<{|
eventCount: number,
target: number,
text: string,
|}>,
>;
export type TextInputEvent = SyntheticEvent<
$ReadOnly<{|
eventCount: number,
previousText: string,
range: $ReadOnly<{|
start: number,
end: number,
|}>,
target: number,
text: string,
|}>,
>;
export type ContentSizeChangeEvent = SyntheticEvent<
$ReadOnly<{|
target: number,
contentSize: $ReadOnly<{|
width: number,
height: number,
|}>,
|}>,
>;
type TargetEvent = SyntheticEvent<
$ReadOnly<{|
target: number,
|}>,
>;
export type BlurEvent = TargetEvent;
export type FocusEvent = TargetEvent;
type Selection = $ReadOnly<{|
type Event = Object;
type Selection = {
start: number,
end: number,
|}>;
export type SelectionChangeEvent = SyntheticEvent<
$ReadOnly<{|
selection: Selection,
target: number,
|}>,
>;
export type KeyPressEvent = SyntheticEvent<
$ReadOnly<{|
key: string,
target?: ?number,
eventCount?: ?number,
|}>,
>;
export type EditingEvent = SyntheticEvent<
$ReadOnly<{|
eventCount: number,
text: string,
target: number,
|}>,
>;
end?: number,
};
const DataDetectorTypes = [
'phoneNumber',
@@ -248,17 +184,17 @@ type Props = $ReadOnly<{|
returnKeyType?: ?ReturnKeyType,
maxLength?: ?number,
multiline?: ?boolean,
onBlur?: ?(e: BlurEvent) => void,
onFocus?: ?(e: FocusEvent) => void,
onChange?: ?(e: ChangeEvent) => void,
onChangeText?: ?(text: string) => void,
onContentSizeChange?: ?(e: ContentSizeChangeEvent) => void,
onTextInput?: ?(e: TextInputEvent) => void,
onEndEditing?: ?(e: EditingEvent) => void,
onSelectionChange?: ?(e: SelectionChangeEvent) => void,
onSubmitEditing?: ?(e: EditingEvent) => void,
onKeyPress?: ?(e: KeyPressEvent) => void,
onScroll?: ?(e: ScrollEvent) => void,
onBlur?: ?Function,
onFocus?: ?Function,
onChange?: ?Function,
onChangeText?: ?Function,
onContentSizeChange?: ?Function,
onTextInput?: ?Function,
onEndEditing?: ?Function,
onSelectionChange?: ?Function,
onSubmitEditing?: ?Function,
onKeyPress?: ?Function,
onScroll?: ?Function,
placeholder?: ?Stringish,
placeholderTextColor?: ?ColorValue,
secureTextEntry?: ?boolean,
@@ -856,7 +792,7 @@ const TextInput = createReactClass({
'oneTimeCode',
]),
},
getDefaultProps() {
getDefaultProps(): Object {
return {
allowFontScaling: true,
underlineColorAndroid: 'transparent',
@@ -1172,7 +1108,7 @@ const TextInput = createReactClass({
);
},
_onFocus: function(event: FocusEvent) {
_onFocus: function(event: Event) {
if (this.props.onFocus) {
this.props.onFocus(event);
}
@@ -1182,16 +1118,16 @@ const TextInput = createReactClass({
}
},
_onPress: function(event: PressEvent) {
_onPress: function(event: Event) {
if (this.props.editable || this.props.editable === undefined) {
this.focus();
}
},
_onChange: function(event: ChangeEvent) {
_onChange: function(event: Event) {
// Make sure to fire the mostRecentEventCount first so it is already set on
// native when the text value is set.
if (this._inputRef && this._inputRef.setNativeProps) {
if (this._inputRef) {
this._inputRef.setNativeProps({
mostRecentEventCount: event.nativeEvent.eventCount,
});
@@ -1211,7 +1147,7 @@ const TextInput = createReactClass({
this.forceUpdate();
},
_onSelectionChange: function(event: SelectionChangeEvent) {
_onSelectionChange: function(event: Event) {
this.props.onSelectionChange && this.props.onSelectionChange(event);
if (!this._inputRef) {
@@ -1252,11 +1188,7 @@ const TextInput = createReactClass({
nativeProps.selection = this.props.selection;
}
if (
Object.keys(nativeProps).length > 0 &&
this._inputRef &&
this._inputRef.setNativeProps
) {
if (Object.keys(nativeProps).length > 0 && this._inputRef) {
this._inputRef.setNativeProps(nativeProps);
}
@@ -1265,7 +1197,8 @@ const TextInput = createReactClass({
}
},
_onBlur: function(event: BlurEvent) {
_onBlur: function(event: Event) {
this.blur();
if (this.props.onBlur) {
this.props.onBlur(event);
}
@@ -1275,11 +1208,11 @@ const TextInput = createReactClass({
}
},
_onTextInput: function(event: TextInputEvent) {
_onTextInput: function(event: Event) {
this.props.onTextInput && this.props.onTextInput(event);
},
_onScroll: function(event: ScrollEvent) {
_onScroll: function(event: Event) {
this.props.onScroll && this.props.onScroll(event);
},
});
@@ -1,70 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+react_native
* @format
* @flow-strict
*/
'use strict';
const React = require('React');
const ReactTestRenderer = require('react-test-renderer');
const TextInput = require('TextInput');
import Component from '@reactions/component';
const {enter} = require('ReactNativeTestTools');
jest.unmock('TextInput');
describe('TextInput tests', () => {
let input;
let onChangeListener;
let onChangeTextListener;
const initialValue = 'initialValue';
beforeEach(() => {
onChangeListener = jest.fn();
onChangeTextListener = jest.fn();
const renderTree = ReactTestRenderer.create(
<Component initialState={{text: initialValue}}>
{({setState, state}) => (
<TextInput
value={state.text}
onChangeText={text => {
onChangeTextListener(text);
setState({text});
}}
onChange={event => {
onChangeListener(event);
}}
/>
)}
</Component>,
);
input = renderTree.root.findByType(TextInput);
});
it('has expected instance functions', () => {
expect(input.instance.isFocused).toBeInstanceOf(Function); // Would have prevented S168585
expect(input.instance.clear).toBeInstanceOf(Function);
expect(input.instance.focus).toBeInstanceOf(Function);
expect(input.instance.blur).toBeInstanceOf(Function);
expect(input.instance.setNativeProps).toBeInstanceOf(Function);
expect(input.instance.measure).toBeInstanceOf(Function);
expect(input.instance.measureInWindow).toBeInstanceOf(Function);
expect(input.instance.measureLayout).toBeInstanceOf(Function);
});
it('calls onChange callbacks', () => {
expect(input.props.value).toBe(initialValue);
const message = 'This is a test message';
enter(input, message);
expect(input.props.value).toBe(message);
expect(onChangeTextListener).toHaveBeenCalledWith(message);
expect(onChangeListener).toHaveBeenCalledWith({
nativeEvent: {text: message},
});
});
});
@@ -5,18 +5,13 @@
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
* @flow
*/
'use strict';
const TimePickerModule = require('NativeModules').TimePickerAndroid;
import type {
TimePickerOptions,
TimePickerResult,
} from './TimePickerAndroidTypes';
/**
* Opens the standard Android time picker dialog.
*
@@ -57,18 +52,22 @@ class TimePickerAndroid {
* still be resolved with action being `TimePickerAndroid.dismissedAction` and all the other keys
* being undefined. **Always** check whether the `action` before reading the values.
*/
static async open(options: TimePickerOptions): Promise<TimePickerResult> {
static async open(options: Object): Promise<Object> {
return TimePickerModule.open(options);
}
/**
* A time has been selected.
*/
static +timeSetAction: 'timeSetAction' = 'timeSetAction';
static get timeSetAction() {
return 'timeSetAction';
}
/**
* The dialog has been dismissed.
*/
static +dismissedAction: 'dismissedAction' = 'dismissedAction';
static get dismissedAction() {
return 'dismissedAction';
}
}
module.exports = TimePickerAndroid;
@@ -1,24 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
'use strict';
export type TimePickerOptions = {|
hour?: number,
minute?: number,
is24Hour?: boolean,
mode?: 'clock' | 'spinner' | 'default',
|};
export type TimePickerResult = $ReadOnly<{|
action: string,
hour: number,
minute: number,
|}>;
+17 -83
View File
@@ -4,7 +4,6 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
@@ -24,9 +23,6 @@ const View = require('View');
const keyMirror = require('fbjs/lib/keyMirror');
const normalizeColor = require('normalizeColor');
import type {PressEvent} from 'CoreEventTypes';
import type {EdgeInsetsProp} from 'EdgeInsetsPropType';
/**
* `Touchable`: Taps done right.
*
@@ -115,7 +111,6 @@ import type {EdgeInsetsProp} from 'EdgeInsetsPropType';
/**
* Touchable states.
*/
const States = keyMirror({
NOT_RESPONDER: null, // Not the responder
RESPONDER_INACTIVE_PRESS_IN: null, // Responder, inactive, in the `PressRect`
@@ -127,33 +122,10 @@ const States = keyMirror({
ERROR: null,
});
type State =
| typeof States.NOT_RESPONDER
| typeof States.RESPONDER_INACTIVE_PRESS_IN
| typeof States.RESPONDER_INACTIVE_PRESS_OUT
| typeof States.RESPONDER_ACTIVE_PRESS_IN
| typeof States.RESPONDER_ACTIVE_PRESS_OUT
| typeof States.RESPONDER_ACTIVE_LONG_PRESS_IN
| typeof States.RESPONDER_ACTIVE_LONG_PRESS_OUT
| typeof States.ERROR;
/*
/**
* Quick lookup map for states that are considered to be "active"
*/
const baseStatesConditions = {
NOT_RESPONDER: false,
RESPONDER_INACTIVE_PRESS_IN: false,
RESPONDER_INACTIVE_PRESS_OUT: false,
RESPONDER_ACTIVE_PRESS_IN: false,
RESPONDER_ACTIVE_PRESS_OUT: false,
RESPONDER_ACTIVE_LONG_PRESS_IN: false,
RESPONDER_ACTIVE_LONG_PRESS_OUT: false,
ERROR: false,
};
const IsActive = {
...baseStatesConditions,
RESPONDER_ACTIVE_PRESS_OUT: true,
RESPONDER_ACTIVE_PRESS_IN: true,
};
@@ -163,14 +135,12 @@ const IsActive = {
* therefore eligible to result in a "selection" if the press stops.
*/
const IsPressingIn = {
...baseStatesConditions,
RESPONDER_INACTIVE_PRESS_IN: true,
RESPONDER_ACTIVE_PRESS_IN: true,
RESPONDER_ACTIVE_LONG_PRESS_IN: true,
};
const IsLongPressingIn = {
...baseStatesConditions,
RESPONDER_ACTIVE_LONG_PRESS_IN: true,
};
@@ -187,15 +157,6 @@ const Signals = keyMirror({
LONG_PRESS_DETECTED: null,
});
type Signal =
| typeof Signals.DELAY
| typeof Signals.RESPONDER_GRANT
| typeof Signals.RESPONDER_RELEASE
| typeof Signals.RESPONDER_TERMINATED
| typeof Signals.ENTER_PRESS_RECT
| typeof Signals.LEAVE_PRESS_RECT
| typeof Signals.LONG_PRESS_DETECTED;
/**
* Mapping from States x Signals => States
*/
@@ -430,7 +391,7 @@ const TouchableMixin = {
* @param {SyntheticEvent} e Synthetic event from event system.
*
*/
touchableHandleResponderGrant: function(e: PressEvent) {
touchableHandleResponderGrant: function(e) {
const dispatchID = e.currentTarget;
// Since e is used in a callback invoked on another event loop
// (as in setTimeout etc), we need to call e.persist() on the
@@ -471,21 +432,21 @@ const TouchableMixin = {
/**
* Place as callback for a DOM element's `onResponderRelease` event.
*/
touchableHandleResponderRelease: function(e: PressEvent) {
touchableHandleResponderRelease: function(e) {
this._receiveSignal(Signals.RESPONDER_RELEASE, e);
},
/**
* Place as callback for a DOM element's `onResponderTerminate` event.
*/
touchableHandleResponderTerminate: function(e: PressEvent) {
touchableHandleResponderTerminate: function(e) {
this._receiveSignal(Signals.RESPONDER_TERMINATED, e);
},
/**
* Place as callback for a DOM element's `onResponderMove` event.
*/
touchableHandleResponderMove: function(e: PressEvent) {
touchableHandleResponderMove: function(e) {
// Not enough time elapsed yet, wait for highlight -
// this is just a perf optimization.
if (
@@ -672,14 +633,7 @@ const TouchableMixin = {
UIManager.measure(tag, this._handleQueryLayout);
},
_handleQueryLayout: function(
l: number,
t: number,
w: number,
h: number,
globalX: number,
globalY: number,
) {
_handleQueryLayout: function(l, t, w, h, globalX, globalY) {
//don't do anything UIManager failed to measure node
if (!l && !t && !w && !h && !globalX && !globalY) {
return;
@@ -698,12 +652,12 @@ const TouchableMixin = {
);
},
_handleDelay: function(e: PressEvent) {
_handleDelay: function(e) {
this.touchableDelayTimeout = null;
this._receiveSignal(Signals.DELAY, e);
},
_handleLongDelay: function(e: PressEvent) {
_handleLongDelay: function(e) {
this.longPressDelayTimeout = null;
const curState = this.state.touchable.touchState;
if (
@@ -731,7 +685,7 @@ const TouchableMixin = {
* @throws Error if invalid state transition or unrecognized signal.
* @sideeffects
*/
_receiveSignal: function(signal: Signal, e: PressEvent) {
_receiveSignal: function(signal, e) {
const responderID = this.state.touchable.responderID;
const curState = this.state.touchable.touchState;
const nextState = Transitions[curState] && Transitions[curState][signal];
@@ -771,14 +725,14 @@ const TouchableMixin = {
this.longPressDelayTimeout = null;
},
_isHighlight: function(state: State) {
_isHighlight: function(state) {
return (
state === States.RESPONDER_ACTIVE_PRESS_IN ||
state === States.RESPONDER_ACTIVE_LONG_PRESS_IN
);
},
_savePressInLocation: function(e: PressEvent) {
_savePressInLocation: function(e) {
const touch = TouchEventUtils.extractSingleTouch(e.nativeEvent);
const pageX = touch && touch.pageX;
const pageY = touch && touch.pageY;
@@ -787,12 +741,7 @@ const TouchableMixin = {
this.pressInLocation = {pageX, pageY, locationX, locationY};
},
_getDistanceBetweenPoints: function(
aX: number,
aY: number,
bX: number,
bY: number,
) {
_getDistanceBetweenPoints: function(aX, aY, bX, bY) {
const deltaX = aX - bX;
const deltaY = aY - bY;
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
@@ -809,12 +758,7 @@ const TouchableMixin = {
* @param {Event} e Native event.
* @sideeffects
*/
_performSideEffectsForTransition: function(
curState: State,
nextState: State,
signal: Signal,
e: PressEvent,
) {
_performSideEffectsForTransition: function(curState, nextState, signal, e) {
const curIsHighlight = this._isHighlight(curState);
const newIsHighlight = this._isHighlight(nextState);
@@ -869,12 +813,12 @@ const TouchableMixin = {
UIManager.playTouchSound();
},
_startHighlight: function(e: PressEvent) {
_startHighlight: function(e) {
this._savePressInLocation(e);
this.touchableHandleActivePressIn && this.touchableHandleActivePressIn(e);
},
_endHighlight: function(e: PressEvent) {
_endHighlight: function(e) {
if (this.touchableHandleActivePressOut) {
if (
this.touchableGetPressOutDelayMS &&
@@ -896,13 +840,7 @@ const Touchable = {
/**
* Renders a debugging overlay to visualize touch target with hitSlop (might not work on Android).
*/
renderDebugView: ({
color,
hitSlop,
}: {
color: string | number,
hitSlop: EdgeInsetsProp,
}) => {
renderDebugView: ({color, hitSlop}) => {
if (!Touchable.TOUCH_TARGET_DEBUG) {
return null;
}
@@ -916,12 +854,8 @@ const Touchable = {
for (const key in hitSlop) {
debugHitSlopStyle[key] = -hitSlop[key];
}
const normalizedColor = normalizeColor(color);
if (typeof normalizedColor !== 'number') {
return null;
}
const hexColor =
'#' + ('00000000' + normalizedColor.toString(16)).substr(-8);
'#' + ('00000000' + normalizeColor(color).toString(16)).substr(-8);
return (
<View
pointerEvents="none"
@@ -23,7 +23,8 @@ const createReactClass = require('create-react-class');
import type {EdgeInsetsProp} from 'EdgeInsetsPropType';
import type {ViewStyleProp} from 'StyleSheet';
import type {Props as TouchableWithoutFeedbackProps} from 'TouchableWithoutFeedback';
import type {PressEvent} from 'CoreEventTypes';
type Event = Object;
type State = {
animationID: ?number,
@@ -35,8 +36,8 @@ const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
type Props = $ReadOnly<{|
...TouchableWithoutFeedbackProps,
onPressWithCompletion?: ?(fn: () => void) => void,
onPressAnimationComplete?: ?() => void,
onPressWithCompletion?: ?Function,
onPressAnimationComplete?: ?Function,
pressRetentionOffset?: ?EdgeInsetsProp,
releaseVelocity?: ?number,
releaseBounciness?: ?number,
@@ -94,7 +95,7 @@ const TouchableBounce = ((createReactClass({
value: number,
velocity: number,
bounciness: number,
callback?: ?() => void,
callback?: ?Function,
) {
Animated.spring(this.state.scale, {
toValue: value,
@@ -104,28 +105,21 @@ const TouchableBounce = ((createReactClass({
}).start(callback);
},
/**
* Triggers a bounce animation without invoking any callbacks.
*/
bounce: function() {
this.bounceTo(0.93, 0.1, 0, () => this.bounceTo(1, 0.4, 0));
},
/**
* `Touchable.Mixin` self callbacks. The mixin will invoke these if they are
* defined on your component.
*/
touchableHandleActivePressIn: function(e: PressEvent) {
touchableHandleActivePressIn: function(e: Event) {
this.bounceTo(0.93, 0.1, 0);
this.props.onPressIn && this.props.onPressIn(e);
},
touchableHandleActivePressOut: function(e: PressEvent) {
touchableHandleActivePressOut: function(e: Event) {
this.bounceTo(1, 0.4, 0);
this.props.onPressOut && this.props.onPressOut(e);
},
touchableHandlePress: function(e: PressEvent) {
touchableHandlePress: function(e: Event) {
const onPressWithCompletion = this.props.onPressWithCompletion;
if (onPressWithCompletion) {
onPressWithCompletion(() => {
@@ -153,7 +147,7 @@ const TouchableBounce = ((createReactClass({
return this.props.pressRetentionOffset || PRESS_RETENTION_OFFSET;
},
touchableGetHitSlop: function(): ?EdgeInsetsProp {
touchableGetHitSlop: function(): ?Object {
return this.props.hitSlop;
},
@@ -28,7 +28,6 @@ import type {PressEvent} from 'CoreEventTypes';
import type {ViewStyleProp} from 'StyleSheet';
import type {ColorValue} from 'StyleSheetTypes';
import type {Props as TouchableWithoutFeedbackProps} from 'TouchableWithoutFeedback';
import type {TVParallaxPropertiesType} from 'TVViewPropTypes';
const DEFAULT_PROPS = {
activeOpacity: 0.85,
@@ -40,7 +39,7 @@ const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
type IOSProps = $ReadOnly<{|
hasTVPreferredFocus?: ?boolean,
tvParallaxProperties?: ?TVParallaxPropertiesType,
tvParallaxProperties?: ?Object,
|}>;
type Props = $ReadOnly<{|
@@ -50,8 +49,8 @@ type Props = $ReadOnly<{|
activeOpacity?: ?number,
underlayColor?: ?ColorValue,
style?: ?ViewStyleProp,
onShowUnderlay?: ?() => void,
onHideUnderlay?: ?() => void,
onShowUnderlay?: ?Function,
onHideUnderlay?: ?Function,
testOnly_pressed?: ?boolean,
|}>;
@@ -186,7 +185,18 @@ const TouchableHighlight = ((createReactClass({
*/
hasTVPreferredFocus: PropTypes.bool,
/**
* Apple TV parallax effects
* *(Apple TV only)* Object with properties to control Apple TV parallax effects.
*
* enabled: If true, parallax effects are enabled. Defaults to true.
* shiftDistanceX: Defaults to 2.0.
* shiftDistanceY: Defaults to 2.0.
* tiltAngle: Defaults to 0.05.
* magnification: Defaults to 1.0.
* pressMagnification: Defaults to 1.0.
* pressDuration: Defaults to 0.3.
* pressDelay: Defaults to 0.0.
*
* @platform ios
*/
tvParallaxProperties: PropTypes.object,
/**
@@ -4,7 +4,6 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
@@ -23,8 +22,6 @@ const createReactClass = require('create-react-class');
const ensurePositiveDelayProps = require('ensurePositiveDelayProps');
const processColor = require('processColor');
import type {PressEvent} from 'CoreEventTypes';
const rippleBackgroundPropType = PropTypes.shape({
type: PropTypes.oneOf(['RippleAndroid']),
color: PropTypes.number,
@@ -41,6 +38,8 @@ const backgroundPropType = PropTypes.oneOfType([
themeAttributeBackgroundPropType,
]);
type Event = Object;
const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
/**
@@ -168,7 +167,7 @@ const TouchableNativeFeedback = createReactClass({
* `Touchable.Mixin` self callbacks. The mixin will invoke these if they are
* defined on your component.
*/
touchableHandleActivePressIn: function(e: PressEvent) {
touchableHandleActivePressIn: function(e: Event) {
this.props.onPressIn && this.props.onPressIn(e);
this._dispatchPressedStateChange(true);
if (this.pressInLocation) {
@@ -179,16 +178,16 @@ const TouchableNativeFeedback = createReactClass({
}
},
touchableHandleActivePressOut: function(e: PressEvent) {
touchableHandleActivePressOut: function(e: Event) {
this.props.onPressOut && this.props.onPressOut(e);
this._dispatchPressedStateChange(false);
},
touchableHandlePress: function(e: PressEvent) {
touchableHandlePress: function(e: Event) {
this.props.onPress && this.props.onPress(e);
},
touchableHandleLongPress: function(e: PressEvent) {
touchableHandleLongPress: function(e: Event) {
this.props.onLongPress && this.props.onLongPress(e);
},
+4 -4
View File
@@ -1,17 +1,17 @@
/**
* @generated by scripts/bump-oss-version.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @generated by scripts/bump-oss-version.js
* @flow
*/
exports.version = {
major: 0,
minor: 0,
minor: 58,
patch: 0,
prerelease: null,
prerelease: 'rc.0',
};
@@ -33,18 +33,12 @@ const UIManagerStatTracker = {
const createViewOrig = UIManager.createView;
UIManager.createView = function(tag, className, rootTag, props) {
incStat('createView', 1);
/* $FlowFixMe(>=0.86.0 site=react_native_fb) This comment suppresses an
* error found when Flow v0.86 was deployed. To see the error, delete
* this comment and run Flow. */
incStat('setProp', Object.keys(props || []).length);
createViewOrig(tag, className, rootTag, props);
};
const updateViewOrig = UIManager.updateView;
UIManager.updateView = function(tag, className, props) {
incStat('updateView', 1);
/* $FlowFixMe(>=0.86.0 site=react_native_fb) This comment suppresses an
* error found when Flow v0.86 was deployed. To see the error, delete
* this comment and run Flow. */
incStat('setProp', Object.keys(props || []).length);
updateViewOrig(tag, className, props);
};
@@ -58,13 +52,7 @@ const UIManagerStatTracker = {
remove,
) {
incStat('manageChildren', 1);
/* $FlowFixMe(>=0.86.0 site=react_native_fb) This comment suppresses an
* error found when Flow v0.86 was deployed. To see the error, delete
* this comment and run Flow. */
incStat('move', Object.keys(moveFrom || []).length);
/* $FlowFixMe(>=0.86.0 site=react_native_fb) This comment suppresses an
* error found when Flow v0.86 was deployed. To see the error, delete
* this comment and run Flow. */
incStat('remove', Object.keys(remove || []).length);
manageChildrenOrig(tag, moveFrom, moveTo, addTags, addIndices, remove);
};
+2 -2
View File
@@ -49,8 +49,8 @@ function renderApplication<Props: Object>(
RootComponent.prototype.unstable_isAsyncReactComponent === true
) {
// $FlowFixMe This is not yet part of the official public API
const ConcurrentMode = React.unstable_ConcurrentMode;
renderable = <ConcurrentMode>{renderable}</ConcurrentMode>;
const AsyncMode = React.unstable_AsyncMode;
renderable = <AsyncMode>{renderable}</AsyncMode>;
}
if (fabric) {
+1 -1
View File
@@ -339,7 +339,7 @@ module.exports = {
) {
let value;
if (ReactNativeStyleAttributes[property] === true) {
if (typeof ReactNativeStyleAttributes[property] === 'string') {
value = {};
} else if (typeof ReactNativeStyleAttributes[property] === 'object') {
value = ReactNativeStyleAttributes[property];
+12 -12
View File
@@ -27,10 +27,10 @@ import type {PressRetentionOffset, TextProps} from 'TextProps';
type ResponseHandlers = $ReadOnly<{|
onStartShouldSetResponder: () => boolean,
onResponderGrant: (event: PressEvent, dispatchID: string) => void,
onResponderMove: (event: PressEvent) => void,
onResponderRelease: (event: PressEvent) => void,
onResponderTerminate: (event: PressEvent) => void,
onResponderGrant: (event: SyntheticEvent<>, dispatchID: string) => void,
onResponderMove: (event: SyntheticEvent<>) => void,
onResponderRelease: (event: SyntheticEvent<>) => void,
onResponderTerminate: (event: SyntheticEvent<>) => void,
onResponderTerminationRequest: () => boolean,
|}>;
@@ -93,12 +93,12 @@ class TouchableText extends React.Component<Props, State> {
touchableHandleLongPress: ?(event: PressEvent) => void;
touchableHandlePress: ?(event: PressEvent) => void;
touchableHandleResponderGrant: ?(
event: PressEvent,
event: SyntheticEvent<>,
dispatchID: string,
) => void;
touchableHandleResponderMove: ?(event: PressEvent) => void;
touchableHandleResponderRelease: ?(event: PressEvent) => void;
touchableHandleResponderTerminate: ?(event: PressEvent) => void;
touchableHandleResponderMove: ?(event: SyntheticEvent<>) => void;
touchableHandleResponderRelease: ?(event: SyntheticEvent<>) => void;
touchableHandleResponderTerminate: ?(event: SyntheticEvent<>) => void;
touchableHandleResponderTerminationRequest: ?() => boolean;
state = {
@@ -173,25 +173,25 @@ class TouchableText extends React.Component<Props, State> {
}
return shouldSetResponder;
},
onResponderGrant: (event: PressEvent, dispatchID: string): void => {
onResponderGrant: (event: SyntheticEvent<>, dispatchID: string): void => {
nullthrows(this.touchableHandleResponderGrant)(event, dispatchID);
if (this.props.onResponderGrant != null) {
this.props.onResponderGrant.call(this, event, dispatchID);
}
},
onResponderMove: (event: PressEvent): void => {
onResponderMove: (event: SyntheticEvent<>): void => {
nullthrows(this.touchableHandleResponderMove)(event);
if (this.props.onResponderMove != null) {
this.props.onResponderMove.call(this, event);
}
},
onResponderRelease: (event: PressEvent): void => {
onResponderRelease: (event: SyntheticEvent<>): void => {
nullthrows(this.touchableHandleResponderRelease)(event);
if (this.props.onResponderRelease != null) {
this.props.onResponderRelease.call(this, event);
}
},
onResponderTerminate: (event: PressEvent): void => {
onResponderTerminate: (event: SyntheticEvent<>): void => {
nullthrows(this.touchableHandleResponderTerminate)(event);
if (this.props.onResponderTerminate != null) {
this.props.onResponderTerminate.call(this, event);
+2 -7
View File
@@ -290,9 +290,6 @@
RCTRoundPixelValue(attachmentSize.width),
RCTRoundPixelValue(attachmentSize.height)
}};
NSRange truncatedGlyphRange = [layoutManager truncatedGlyphRangeInLineFragmentForGlyphAtIndex:range.location];
BOOL viewIsTruncated = NSIntersectionRange(range, truncatedGlyphRange).length != 0;
RCTLayoutContext localLayoutContext = layoutContext;
localLayoutContext.absolutePosition.x += frame.origin.x;
@@ -303,11 +300,9 @@
layoutDirection:self.layoutMetrics.layoutDirection
layoutContext:localLayoutContext];
// Reinforcing a proper frame origin for the Shadow View.
RCTLayoutMetrics localLayoutMetrics = shadowView.layoutMetrics;
localLayoutMetrics.frame.origin = frame.origin; // Reinforcing a proper frame origin for the Shadow View.
if (viewIsTruncated) {
localLayoutMetrics.displayType = RCTDisplayTypeNone;
}
localLayoutMetrics.frame.origin = frame.origin;
[shadowView layoutWithMetrics:localLayoutMetrics layoutContext:localLayoutContext];
}
];
+7 -7
View File
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @flow
* @format
*/
@@ -106,12 +106,12 @@ export type TextProps = $ReadOnly<{
* See https://facebook.github.io/react-native/docs/text.html#onpress
*/
onPress?: ?(event: PressEvent) => mixed,
onResponderGrant?: ?(event: PressEvent, dispatchID: string) => void,
onResponderMove?: ?(event: PressEvent) => void,
onResponderRelease?: ?(event: PressEvent) => void,
onResponderTerminate?: ?(event: PressEvent) => void,
onResponderTerminationRequest?: ?() => boolean,
onStartShouldSetResponder?: ?() => boolean,
onResponderGrant?: ?Function,
onResponderMove?: ?Function,
onResponderRelease?: ?Function,
onResponderTerminate?: ?Function,
onResponderTerminationRequest?: ?Function,
onStartShouldSetResponder?: ?Function,
onTextLayout?: ?(event: TextLayoutEvent) => mixed,
/**
+2 -5
View File
@@ -19,11 +19,8 @@ const Platform = {
return constants && constants.Version;
},
get isTesting(): boolean {
if (__DEV__) {
const constants = NativeModules.PlatformConstants;
return constants && constants.isTesting;
}
return false;
const constants = NativeModules.PlatformConstants;
return constants && constants.isTesting;
},
get isTV(): boolean {
const constants = NativeModules.PlatformConstants;
+2 -5
View File
@@ -33,11 +33,8 @@ const Platform = {
return constants ? constants.interfaceIdiom === 'tv' : false;
},
get isTesting(): boolean {
if (__DEV__) {
const constants = NativeModules.PlatformConstants;
return constants && constants.isTesting;
}
return false;
const constants = NativeModules.PlatformConstants;
return constants && constants.isTesting;
},
select: (obj: Object) => ('ios' in obj ? obj.ios : obj.default),
};
-165
View File
@@ -1,165 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
'use strict';
const React = require('React');
const ReactTestRenderer = require('react-test-renderer');
const {Switch, Text, TextInput, VirtualizedList} = require('react-native');
import type {
ReactTestInstance,
ReactTestRendererNode,
Predicate,
} from 'react-test-renderer';
function byClickable(): Predicate {
return withMessage(
node =>
// note: <Text /> lazy-mounts press handlers after the first press,
// so this is a workaround for targeting text nodes.
(node.type === Text &&
node.props &&
typeof node.props.onPress === 'function') ||
// note: Special casing <Switch /> since it doesn't use touchable
(node.type === Switch && node.props && node.props.disabled !== true) ||
(node.instance &&
typeof node.instance.touchableHandlePress === 'function'),
'is clickable',
);
}
function byTestID(testID: string): Predicate {
return withMessage(
node => node.props && node.props.testID === testID,
`testID prop equals ${testID}`,
);
}
function byTextMatching(regex: RegExp): Predicate {
return withMessage(
node => node.props && regex.exec(node.props.children),
`text content matches ${regex.toString()}`,
);
}
function enter(instance: ReactTestInstance, text: string) {
const input = instance.findByType(TextInput);
input.instance._onChange({nativeEvent: {text}});
}
// Returns null if there is no error, otherwise returns an error message string.
function maximumDepthError(
tree: {toJSON: () => ReactTestRendererNode},
maxDepthLimit: number,
): ?string {
const maxDepth = maximumDepthOfJSON(tree.toJSON());
if (maxDepth > maxDepthLimit) {
return (
`maximumDepth of ${maxDepth} exceeded limit of ${maxDepthLimit} - this is a proxy ` +
'metric to protect against stack overflow errors:\n\n' +
'https://fburl.com/rn-view-stack-overflow.\n\n' +
'To fix, you need to remove native layers from your hierarchy, such as unnecessary View ' +
'wrappers.'
);
} else {
return null;
}
}
function expectNoConsoleWarn() {
(jest: $FlowFixMe).spyOn(console, 'warn').mockImplementation((...args) => {
expect(args).toBeFalsy();
});
}
function expectNoConsoleError() {
let hasNotFailed = true;
(jest: $FlowFixMe).spyOn(console, 'error').mockImplementation((...args) => {
if (hasNotFailed) {
hasNotFailed = false; // set false to prevent infinite recursion
expect(args).toBeFalsy();
}
});
}
// Takes a node from toJSON()
function maximumDepthOfJSON(node: ReactTestRendererNode): number {
if (node == null) {
return 0;
} else if (typeof node === 'string' || node.children == null) {
return 1;
} else {
let maxDepth = 0;
node.children.forEach(child => {
maxDepth = Math.max(maximumDepthOfJSON(child) + 1, maxDepth);
});
return maxDepth;
}
}
function renderAndEnforceStrictMode(element: React.Node) {
expectNoConsoleError();
return renderWithStrictMode(element);
}
function renderWithStrictMode(element: React.Node) {
const WorkAroundBugWithStrictModeInTestRenderer = prps => prps.children;
const StrictMode = (React: $FlowFixMe).StrictMode;
return ReactTestRenderer.create(
<WorkAroundBugWithStrictModeInTestRenderer>
<StrictMode>{element}</StrictMode>
</WorkAroundBugWithStrictModeInTestRenderer>,
);
}
function tap(instance: ReactTestInstance) {
const touchable = instance.find(byClickable());
if (touchable.type === Text && touchable.props && touchable.props.onPress) {
touchable.props.onPress();
} else if (touchable.type === Switch && touchable.props) {
const value = !touchable.props.value;
const {onChange, onValueChange} = touchable.props;
onChange && onChange({nativeEvent: {value}});
onValueChange && onValueChange(value);
} else {
// Only tap when props.disabled isn't set (or there aren't any props)
if (!touchable.props || !touchable.props.disabled) {
touchable.instance.touchableHandlePress({nativeEvent: {}});
}
}
}
function scrollToBottom(instance: ReactTestInstance) {
const list = instance.findByType(VirtualizedList);
list.props && list.props.onEndReached();
}
// To make error messages a little bit better, we attach a custom toString
// implementation to a predicate
function withMessage(fn: Predicate, message: string): Predicate {
(fn: any).toString = () => message;
return fn;
}
export {byClickable};
export {byTestID};
export {byTextMatching};
export {enter};
export {expectNoConsoleWarn};
export {expectNoConsoleError};
export {maximumDepthError};
export {maximumDepthOfJSON};
export {renderAndEnforceStrictMode};
export {renderWithStrictMode};
export {scrollToBottom};
export {tap};
export {withMessage};
+3 -7
View File
@@ -12,22 +12,18 @@
const React = require('react');
const ReactNative = require('react-native');
const {AccessibilityInfo, Text, View, TouchableOpacity, Alert} = ReactNative;
const {AccessibilityInfo, Text, View, TouchableOpacity} = ReactNative;
class AccessibilityIOSExample extends React.Component<{}> {
render() {
return (
<View>
<View
onAccessibilityTap={() =>
Alert.alert('Alert', 'onAccessibilityTap success')
}
onAccessibilityTap={() => alert('onAccessibilityTap success')}
accessible={true}>
<Text>Accessibility normal tap example</Text>
</View>
<View
onMagicTap={() => Alert.alert('Alert', 'onMagicTap success')}
accessible={true}>
<View onMagicTap={() => alert('onMagicTap success')} accessible={true}>
<Text>Accessibility magic tap example</Text>
</View>
<View accessibilityLabel="Some announcement" accessible={true}>
+4 -11
View File
@@ -12,14 +12,7 @@
const React = require('react');
const ReactNative = require('react-native');
const {
ActionSheetIOS,
StyleSheet,
takeSnapshot,
Text,
View,
Alert,
} = ReactNative;
const {ActionSheetIOS, StyleSheet, takeSnapshot, Text, View} = ReactNative;
const BUTTONS = ['Option 0', 'Option 1', 'Option 2', 'Delete', 'Cancel'];
const DESTRUCTIVE_INDEX = 3;
@@ -113,7 +106,7 @@ class ShareActionSheetExample extends React.Component<
subject: 'a subject to go in the email heading',
excludedActivityTypes: ['com.apple.UIKit.activity.PostToTwitter'],
},
error => Alert.alert('Error', error),
error => alert(error),
(completed, method) => {
let text;
if (completed) {
@@ -153,7 +146,7 @@ class ShareScreenshotExample extends React.Component<{}, $FlowFixMeState> {
url: uri,
excludedActivityTypes: ['com.apple.UIKit.activity.PostToTwitter'],
},
error => Alert.alert('Error', error),
error => alert(error),
(completed, method) => {
let text;
if (completed) {
@@ -165,7 +158,7 @@ class ShareScreenshotExample extends React.Component<{}, $FlowFixMeState> {
},
);
})
.catch(error => Alert.alert('Error', error));
.catch(error => alert(error));
};
}
+2 -2
View File
@@ -12,7 +12,7 @@
const React = require('react');
const ReactNative = require('react-native');
const {StyleSheet, Text, View, Alert} = ReactNative;
const {StyleSheet, Text, View} = ReactNative;
exports.framework = 'React';
exports.title = 'Geolocation';
@@ -41,7 +41,7 @@ class GeolocationExample extends React.Component<{}, $FlowFixMeState> {
const initialPosition = JSON.stringify(position);
this.setState({initialPosition});
},
error => Alert.alert('Error', JSON.stringify(error)),
error => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000},
);
this.watchID = navigator.geolocation.watchPosition(position => {
+2 -4
View File
@@ -12,7 +12,7 @@
const React = require('react');
const ReactNative = require('react-native');
const {FlatList, StyleSheet, Text, View, Alert} = ReactNative;
const {FlatList, StyleSheet, Text, View} = ReactNative;
const RNTesterPage = require('./RNTesterPage');
@@ -91,9 +91,7 @@ class MultiColumnExample extends React.PureComponent<
data={filteredData}
key={this.state.numColumns + (this.state.fixedHeight ? 'f' : 'v')}
numColumns={this.state.numColumns || 1}
onRefresh={() =>
Alert.alert('Alert', 'onRefresh: nothing to refresh :P')
}
onRefresh={() => alert('onRefresh: nothing to refresh :P')}
refreshing={false}
renderItem={this._renderItemComponent}
disableVirtualization={!this.state.virtualized}
+4 -5
View File
@@ -48,8 +48,7 @@ class TextEventsExample extends React.Component<{}, $FlowFixMeState> {
}
onContentSizeChange={event =>
this.updateText(
'onContentSizeChange size: ' +
JSON.stringify(event.nativeEvent.contentSize),
'onContentSizeChange size: ' + event.nativeEvent.contentSize,
)
}
onEndEditing={event =>
@@ -254,10 +253,10 @@ class ToggleDefaultPaddingExample extends React.Component<
}
type SelectionExampleState = {
selection: $ReadOnly<{|
selection: {
start: number,
end?: number,
|}>,
end: number,
},
value: string,
};
+5 -7
View File
@@ -14,7 +14,7 @@ const Button = require('Button');
const InputAccessoryView = require('InputAccessoryView');
const React = require('react');
const ReactNative = require('react-native');
const {Text, TextInput, View, StyleSheet, Slider, Switch, Alert} = ReactNative;
const {Text, TextInput, View, StyleSheet, Slider, Switch} = ReactNative;
class WithLabel extends React.Component<$FlowFixMeProps> {
render() {
@@ -71,7 +71,7 @@ class TextEventsExample extends React.Component<{}, $FlowFixMeState> {
'onSelectionChange range: ' +
event.nativeEvent.selection.start +
',' +
(event.nativeEvent.selection.end || ''),
event.nativeEvent.selection.end,
)
}
onKeyPress={event => {
@@ -348,10 +348,10 @@ class BlurOnSubmitExample extends React.Component<{}> {
}
type SelectionExampleState = {
selection: $ReadOnly<{|
selection: {|
start: number,
end?: number,
|}>,
|},
value: string,
};
@@ -862,9 +862,7 @@ exports.examples = [
returnKeyType="next"
blurOnSubmit={true}
multiline={true}
onSubmitEditing={event =>
Alert.alert('Alert', event.nativeEvent.text)
}
onSubmitEditing={event => alert(event.nativeEvent.text)}
/>
</View>
);
+2 -2
View File
@@ -12,13 +12,13 @@
const React = require('react');
const ReactNative = require('react-native');
const {Text, View, TouchableOpacity, Alert} = ReactNative;
const {Text, View, TouchableOpacity} = ReactNative;
class TransparentHitTestExample extends React.Component<{}> {
render() {
return (
<View style={{flex: 1}}>
<TouchableOpacity onPress={() => Alert.alert('Alert', 'Hi!')}>
<TouchableOpacity onPress={() => alert('Hi!')}>
<Text>HELLO!</Text>
</TouchableOpacity>
+1 -1
View File
@@ -27,7 +27,7 @@ class XHRExampleFetch extends React.Component<any, any> {
this.responseHeaders = null;
}
submit(uri: string) {
submit(uri: String) {
fetch(uri)
.then(response => {
this.responseURL = response.url;
+1 -1
View File
@@ -35,7 +35,7 @@ server.on('connection', ws => {
console.log('Received message:', message);
console.log('Cookie:', ws.upgradeReq.headers.cookie);
if (respondWithBinary) {
message = Buffer.from(message);
message = new Buffer(message);
}
if (message === 'getImage') {
message = fs.readFileSync(path.resolve(__dirname, 'flux@3x.png'));
-87
View File
@@ -1,87 +0,0 @@
---
AccessModifierOffset: -1
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignOperands: false
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: WebKit
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ForEachMacros: [ FOR_EACH_RANGE, FOR_EACH, ]
IncludeCategories:
- Regex: '^<.*\.h(pp)?>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...
+2 -6
View File
@@ -97,8 +97,8 @@ RCT_EXTERN NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
* Experimental.
* Check/set if JSI-bound NativeModule is enabled. By default it's off.
*/
RCT_EXTERN BOOL RCTTurboModuleEnabled(void);
RCT_EXTERN void RCTEnableTurboModule(BOOL enabled);
RCT_EXTERN BOOL RCTJSINativeModuleEnabled(void);
RCT_EXTERN void RCTEnableJSINativeModule(BOOL enabled);
/**
* Async batched bridge used to communicate with the JavaScript application.
@@ -151,12 +151,8 @@ RCT_EXTERN void RCTEnableTurboModule(BOOL enabled);
* lazily instantiated, so calling these methods for the first time with a given
* module name/class may cause the class to be sychronously instantiated,
* potentially blocking both the calling thread and main thread for a short time.
*
* Note: This method does NOT lazily load the particular module if it's not yet loaded.
*/
- (id)moduleForName:(NSString *)moduleName;
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
// Note: This method lazily load the module as necessary.
- (id)moduleForClass:(Class)moduleClass;
/**
+5 -10
View File
@@ -85,14 +85,14 @@ NSString *RCTBridgeModuleNameForClass(Class cls)
return RCTDropReactPrefixes(name);
}
static BOOL turboModuleEnabled = NO;
BOOL RCTTurboModuleEnabled(void)
static BOOL jsiNativeModuleEnabled = NO;
BOOL RCTJSINativeModuleEnabled(void)
{
return turboModuleEnabled;
return jsiNativeModuleEnabled;
}
void RCTEnableTurboModule(BOOL enabled) {
turboModuleEnabled = enabled;
void RCTEnableJSINativeModule(BOOL enabled) {
jsiNativeModuleEnabled = enabled;
}
#if RCT_DEBUG
@@ -241,11 +241,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
return [self.batchedBridge moduleForName:moduleName];
}
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad
{
return [self.batchedBridge moduleForName:moduleName lazilyLoadIfNecessary:lazilyLoad];
}
- (id)moduleForClass:(Class)moduleClass
{
id module = [self.batchedBridge moduleForClass:moduleClass];
+3 -3
View File
@@ -301,7 +301,7 @@ RCT_EXTERN void RCTRegisterModule(Class); \
* for the lifetime of the bridge, so it is not suitable for returning dynamic values, but may be used for long-lived
* values such as session keys, that are regenerated only as part of a reload of the entire React application.
*
* If you implement this method and do not implement `requiresMainQueueSetup`, you will trigger deprecated logic
* If you implement this method and do not implement `requiresMainThreadSetup`, you will trigger deprecated logic
* that eagerly initializes your module on bridge startup. In the future, this behaviour will be changed to default
* to initializing lazily, and even modules with constants will be initialized lazily.
*/
@@ -324,9 +324,9 @@ RCT_EXTERN void RCTRegisterModule(Class); \
/**
* Experimental.
* A protocol to declare that a class supports TurboModule.
* A protocol to declare that a class supports JSI-bound NativeModule.
* This may be removed in the future.
*/
@protocol RCTTurboModule <NSObject>
@protocol RCTJSINativeModule <NSObject>
@end
+2 -2
View File
@@ -21,9 +21,9 @@ static void __makeVersion()
{
__rnVersion = @{
RCTVersionMajor: @(0),
RCTVersionMinor: @(0),
RCTVersionMinor: @(58),
RCTVersionPatch: @(0),
RCTVersionPrerelease: [NSNull null],
RCTVersionPrerelease: @"rc.0",
};
}
+13 -27
View File
@@ -439,30 +439,6 @@ struct RCTInstanceCallback : public InstanceCallback {
return _moduleDataByName[moduleName].instance;
}
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad
{
if (!lazilyLoad) {
return [self moduleForName:moduleName];
}
RCTModuleData *moduleData = _moduleDataByName[moduleName];
if (moduleData) {
return moduleData.instance;
}
// Module may not be loaded yet, so attempt to force load it here.
const BOOL result = [self.delegate respondsToSelector:@selector(bridge:didNotFindModule:)] &&
[self.delegate bridge:self didNotFindModule:moduleName];
if (result) {
// Try again.
moduleData = _moduleDataByName[moduleName];
} else {
RCTLogError(@"Unable to find module for %@", moduleName);
}
return moduleData.instance;
}
- (BOOL)moduleIsInitialized:(Class)moduleClass
{
return _moduleDataByName[RCTBridgeModuleNameForClass(moduleClass)].hasInstance;
@@ -470,7 +446,17 @@ struct RCTInstanceCallback : public InstanceCallback {
- (id)moduleForClass:(Class)moduleClass
{
return [self moduleForName:RCTBridgeModuleNameForClass(moduleClass) lazilyLoadIfNecessary:YES];
NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass);
RCTModuleData *moduleData = _moduleDataByName[moduleName];
if (moduleData) {
return moduleData.instance;
}
// Module may not be loaded yet, so attempt to force load it here.
RCTAssert([moduleClass conformsToProtocol:@protocol(RCTBridgeModule)], @"Asking for a NativeModule that doesn't conform to RCTBridgeModule: %@", NSStringFromClass(moduleClass));
[self registerAdditionalModuleClasses:@[moduleClass]];
return _moduleDataByName[moduleName].instance;
}
- (std::shared_ptr<ModuleRegistry>)_buildModuleRegistryUnlocked
@@ -561,7 +547,7 @@ struct RCTInstanceCallback : public InstanceCallback {
NSArray *moduleClassesCopy = [moduleClasses copy];
NSMutableArray<RCTModuleData *> *moduleDataByID = [NSMutableArray arrayWithCapacity:moduleClassesCopy.count];
for (Class moduleClass in moduleClassesCopy) {
if (RCTTurboModuleEnabled() && [moduleClass conformsToProtocol:@protocol(RCTTurboModule)]) {
if (RCTJSINativeModuleEnabled() && [moduleClass conformsToProtocol:@protocol(RCTJSINativeModule)]) {
continue;
}
NSString *moduleName = RCTBridgeModuleNameForClass(moduleClass);
@@ -666,7 +652,7 @@ struct RCTInstanceCallback : public InstanceCallback {
// we must use the names provided by the delegate method here.
for (NSString *moduleName in moduleClasses) {
Class moduleClass = moduleClasses[moduleName];
if (RCTTurboModuleEnabled() && [moduleClass conformsToProtocol:@protocol(RCTTurboModule)]) {
if (RCTJSINativeModuleEnabled() && [moduleClass conformsToProtocol:@protocol(RCTJSINativeModule)]) {
continue;
}
@@ -73,7 +73,7 @@ using namespace facebook::react;
_imageLocalData = std::static_pointer_cast<const ImageLocalData>(localData);
assert(_imageLocalData);
auto future = _imageLocalData->getImageRequest().getResponseFuture();
future.via(&MainQueueExecutor::instance()).thenValue([self](ImageResponse &&imageResponse) {
future.via(&MainQueueExecutor::instance()).then([self](ImageResponse &&imageResponse) {
self.image = (__bridge UIImage *)imageResponse.getImage().get();
});
}
+15 -42
View File
@@ -130,7 +130,7 @@ static BOOL AnyTouchesChanged(NSSet<UITouch *> *touches) {
template<typename PointerT>
struct PointerHasher {
constexpr std::size_t operator()(const PointerT &value) const {
return reinterpret_cast<size_t>(value);
return reinterpret_cast<size_t>(&value);
}
};
@@ -196,39 +196,29 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
- (void)_updateTouches:(NSSet<UITouch *> *)touches
{
for (UITouch *touch in touches) {
UpdateActiveTouchWithUITouch(_activeTouches.at(touch), touch, _rootComponentView);
UpdateActiveTouchWithUITouch(_activeTouches[touch], touch, _rootComponentView);
}
}
- (void)_unregisterTouches:(NSSet<UITouch *> *)touches
{
for (UITouch *touch in touches) {
const auto &activeTouch = _activeTouches.at(touch);
const auto &activeTouch = _activeTouches[touch];
_identifierPool.enqueue(activeTouch.touch.identifier);
_activeTouches.erase(touch);
}
}
- (std::vector<ActiveTouch>)_activeTouchesFromTouches:(NSSet<UITouch *> *)touches
{
std::vector<ActiveTouch> activeTouches;
activeTouches.reserve(touches.count);
for (UITouch *touch in touches) {
activeTouches.push_back(_activeTouches.at(touch));
}
return activeTouches;
}
- (void)_dispatchActiveTouches:(std::vector<ActiveTouch>)activeTouches eventType:(RCTTouchEventType)eventType
- (void)_dispatchTouches:(NSSet<UITouch *> *)touches eventType:(RCTTouchEventType)eventType
{
TouchEvent event = {};
std::unordered_set<ActiveTouch, ActiveTouch::Hasher, ActiveTouch::Comparator> changedActiveTouches = {};
std::unordered_set<SharedTouchEventEmitter> uniqueEventEmitter = {};
BOOL isEndishEventType = eventType == RCTTouchEventTypeTouchEnd || eventType == RCTTouchEventTypeTouchCancel;
for (const auto &activeTouch : activeTouches) {
for (UITouch *touch in touches) {
const auto &activeTouch = _activeTouches[touch];
if (!activeTouch.eventEmitter) {
continue;
}
@@ -286,8 +276,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
[super touchesBegan:touches withEvent:event];
[self _registerTouches:touches];
[self _dispatchActiveTouches:[self _activeTouchesFromTouches:touches]
eventType:RCTTouchEventTypeTouchStart];
[self _dispatchTouches:touches eventType:RCTTouchEventTypeTouchStart];
if (self.state == UIGestureRecognizerStatePossible) {
self.state = UIGestureRecognizerStateBegan;
@@ -301,8 +290,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
[super touchesMoved:touches withEvent:event];
[self _updateTouches:touches];
[self _dispatchActiveTouches:[self _activeTouchesFromTouches:touches]
eventType:RCTTouchEventTypeTouchMove];
[self _dispatchTouches:touches eventType:RCTTouchEventTypeTouchMove];
self.state = UIGestureRecognizerStateChanged;
}
@@ -312,8 +300,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
[super touchesEnded:touches withEvent:event];
[self _updateTouches:touches];
[self _dispatchActiveTouches:[self _activeTouchesFromTouches:touches]
eventType:RCTTouchEventTypeTouchEnd];
[self _dispatchTouches:touches eventType:RCTTouchEventTypeTouchEnd];
[self _unregisterTouches:touches];
if (AllTouchesAreCancelledOrEnded(event.allTouches)) {
@@ -328,8 +315,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
[super touchesCancelled:touches withEvent:event];
[self _updateTouches:touches];
[self _dispatchActiveTouches:[self _activeTouchesFromTouches:touches]
eventType:RCTTouchEventTypeTouchCancel];
[self _dispatchTouches:touches eventType:RCTTouchEventTypeTouchCancel];
[self _unregisterTouches:touches];
if (AllTouchesAreCancelledOrEnded(event.allTouches)) {
@@ -341,23 +327,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action
- (void)reset
{
[super reset];
if (_activeTouches.size() != 0) {
std::vector<ActiveTouch> activeTouches;
activeTouches.reserve(_activeTouches.size());
for (auto const &pair : _activeTouches) {
activeTouches.push_back(pair.second);
}
[self _dispatchActiveTouches:activeTouches
eventType:RCTTouchEventTypeTouchCancel];
// Force-unregistering all the touches.
_activeTouches.clear();
_identifierPool.reset();
}
// Technically, `_activeTouches` must be already empty at this point,
// but just to be sure, we clear it explicitly.
_activeTouches.clear();
_identifierPool.reset();
}
- (BOOL)canPreventGestureRecognizer:(__unused UIGestureRecognizer *)preventedGestureRecognizer
+1 -2
View File
@@ -49,8 +49,7 @@
_rootTag = [RCTAllocateRootViewTag() integerValue];
_minimumSize = CGSizeZero;
// FIXME: Replace with `_maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);`.
_maximumSize = RCTScreenSize();
_maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);
_touchHandler = [RCTSurfaceTouchHandler new];
-7
View File
@@ -488,7 +488,6 @@ static NSDictionary *deviceOrientationEventBody(UIDeviceOrientation orientation)
UIUserInterfaceLayoutDirection layoutDirection;
BOOL isNew;
BOOL parentIsNew;
RCTDisplayType displayType;
} RCTFrameData;
// Construct arrays then hand off to main thread
@@ -506,7 +505,6 @@ static NSDictionary *deviceOrientationEventBody(UIDeviceOrientation orientation)
layoutMetrics.layoutDirection,
shadowView.isNewView,
shadowView.superview.isNewView,
layoutMetrics.displayType
};
}
}
@@ -568,7 +566,6 @@ static NSDictionary *deviceOrientationEventBody(UIDeviceOrientation orientation)
RCTLayoutAnimation *updatingLayoutAnimation = isNew ? nil : layoutAnimationGroup.updatingLayoutAnimation;
BOOL shouldAnimateCreation = isNew && !frameData.parentIsNew;
RCTLayoutAnimation *creatingLayoutAnimation = shouldAnimateCreation ? layoutAnimationGroup.creatingLayoutAnimation : nil;
BOOL isHidden = frameData.displayType == RCTDisplayTypeNone;
void (^completion)(BOOL) = ^(BOOL finished) {
completionsCalled++;
@@ -584,10 +581,6 @@ static NSDictionary *deviceOrientationEventBody(UIDeviceOrientation orientation)
if (view.reactLayoutDirection != layoutDirection) {
view.reactLayoutDirection = layoutDirection;
}
if (view.isHidden != isHidden) {
view.hidden = isHidden;
}
if (creatingLayoutAnimation) {
-1
View File
@@ -36,7 +36,6 @@ shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *)request
@property (nonatomic, assign) UIEdgeInsets contentInset;
@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets;
+ (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential;
- (void)postMessage:(NSString *)message;
- (void)injectJavaScript:(NSString *)script;
- (void)goForward;
-21
View File
@@ -10,8 +10,6 @@
#import "RCTAutoInsetsProtocol.h"
static NSString *const MessageHanderName = @"ReactNative";
static NSURLCredential* clientAuthenticationCredential;
@interface RCTWKWebView () <WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler, UIScrollViewDelegate, RCTAutoInsetsProtocol>
@property (nonatomic, copy) RCTDirectEventBlock onLoadingStart;
@@ -312,25 +310,6 @@ static NSURLCredential* clientAuthenticationCredential;
[self setBackgroundColor: _savedBackgroundColor];
}
+ (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential {
clientAuthenticationCredential = credential;
}
- (void) webView:(WKWebView *)webView
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable))completionHandler
{
if (!clientAuthenticationCredential) {
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
return;
}
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
completionHandler(NSURLSessionAuthChallengeUseCredential, clientAuthenticationCredential);
} else {
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}
}
- (void)evaluateJS:(NSString *)js
thenCall: (void (^)(NSString*)) callback
{
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION_NAME=1000.0.0-master
VERSION_NAME=0.58.0-rc.0
GROUP=com.facebook.react
POM_NAME=ReactNative
@@ -1,104 +0,0 @@
package com.facebook.react.tests.core;
import static org.fest.assertions.api.Assertions.assertThat;
import android.support.test.runner.AndroidJUnit4;
import com.facebook.react.bridge.UnexpectedNativeTypeException;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.bridge.WritableNativeMap;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class WritableNativeMapTest {
private WritableNativeMap mMap;
@Before
public void setup() {
mMap = new WritableNativeMap();
mMap.putBoolean("boolean", true);
mMap.putDouble("double", 1.2);
mMap.putInt("int", 1);
mMap.putString("string", "abc");
mMap.putMap("map", new WritableNativeMap());
mMap.putArray("array", new WritableNativeArray());
mMap.putBoolean("dvacca", true);
mMap.setUseNativeAccessor(true);
}
@Test
public void testBoolean() {
assertThat(mMap.getBoolean("boolean")).isEqualTo(true);
}
@Test(expected = UnexpectedNativeTypeException.class)
public void testBooleanInvalidType() {
mMap.getBoolean("string");
}
@Test
public void testDouble() {
assertThat(mMap.getDouble("double")).isEqualTo(1.2);
}
@Test(expected = UnexpectedNativeTypeException.class)
public void testDoubleInvalidType() {
mMap.getDouble("string");
}
@Test
public void testInt() {
assertThat(mMap.getInt("int")).isEqualTo(1);
}
@Test(expected = UnexpectedNativeTypeException.class)
public void testIntInvalidType() {
mMap.getInt("string");
}
@Test
public void testString() {
assertThat(mMap.getString("string")).isEqualTo("abc");
}
@Test(expected = UnexpectedNativeTypeException.class)
public void testStringInvalidType() {
mMap.getString("int");
}
@Test
public void testMap() {
assertThat(mMap.getMap("map")).isNotNull();
}
@Test(expected = UnexpectedNativeTypeException.class)
public void testMapInvalidType() {
mMap.getMap("string");
}
@Test
public void testArray() {
assertThat(mMap.getArray("array")).isNotNull();
}
@Test(expected = UnexpectedNativeTypeException.class)
public void testArrayInvalidType() {
mMap.getArray("string");
}
@Ignore("Needs to be implemented")
@Test
public void testErrorMessageContainsKey() {
String key = "fkg";
try {
mMap.getString(key);
Assert.fail("Expected an UnexpectedNativeTypeException to be thrown");
} catch (UnexpectedNativeTypeException e) {
assertThat(e.getMessage()).contains(key);
}
}
}
@@ -325,7 +325,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
// shared under the hood.
// See https://github.com/square/okhttp/wiki/Recipes#per-call-configuration for more information
if (timeout != mClient.connectTimeoutMillis()) {
clientBuilder.connectTimeout(timeout, TimeUnit.MILLISECONDS);
clientBuilder.readTimeout(timeout, TimeUnit.MILLISECONDS);
}
OkHttpClient client = clientBuilder.build();
@@ -7,7 +7,6 @@ package com.facebook.react.modules.systeminfo;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
@@ -85,7 +84,7 @@ public class AndroidInfoHelpers {
Runtime.getRuntime().exec(new String[] {"/system/bin/getprop", METRO_HOST_PROP_NAME});
reader =
new BufferedReader(
new InputStreamReader(process.getInputStream(), Charset.forName("UTF-8")));
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
String lastLine = "";
String line;
@@ -16,7 +16,7 @@ import java.util.Map;
public class ReactNativeVersion {
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
"major", 0,
"minor", 0,
"minor", 58,
"patch", 0,
"prerelease", null);
"prerelease", "rc.0");
}
@@ -147,11 +147,6 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
sendEvent("websocketOpen", params);
}
@Override
public void onClosing(WebSocket websocket, int code, String reason) {
websocket.close(code, reason);
}
@Override
public void onClosed(WebSocket webSocket, int code, String reason) {
WritableMap params = Arguments.createMap();
@@ -562,11 +562,6 @@ public class NativeViewHierarchyManager {
*/
protected synchronized void dropView(View view) {
UiThreadUtil.assertOnUiThread();
if (mTagsToViewManagers.get(view.getId()) == null) {
// This view has already been dropped (likely due to a threading issue caused by async js
// execution). Ignore this drop operation.
return;
}
if (!mRootTags.get(view.getId())) {
// For non-root views we notify viewmanager with {@link ViewManager#onDropInstance}
resolveViewManager(view.getId()).onDropViewInstance(view);
@@ -94,6 +94,8 @@ public interface ReactShadowNode<T extends ReactShadowNode> {
void removeAndDisposeAllChildren();
@Nullable ReactStylesDiffMap getNewProps();
/**
* This method will be called by {@link UIManagerModule} once per batch, before calculating
* layout. Will be only called for nodes that are marked as updated with {@link #markUpdated()} or
@@ -346,4 +348,12 @@ public interface ReactShadowNode<T extends ReactShadowNode> {
boolean isMeasureDefined();
void dispose();
/**
* @return an immutable {@link List<ReactShadowNode>} containing the children of this
* {@link ReactShadowNode}.
*/
List<ReactShadowNode> getChildrenList();
void updateScreenLayout(ReactShadowNode prevNode);
}
@@ -6,7 +6,12 @@
*/
package com.facebook.react.uimanager;
import static java.lang.System.arraycopy;
import com.facebook.debug.holder.PrinterHolder;
import com.facebook.debug.tags.ReactDebugOverlayTags;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.uimanager.annotations.ReactPropertyHolder;
import com.facebook.yoga.YogaAlign;
import com.facebook.yoga.YogaBaselineFunction;
@@ -25,6 +30,8 @@ import com.facebook.yoga.YogaValue;
import com.facebook.yoga.YogaWrap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
/**
@@ -53,6 +60,8 @@ import javax.annotation.Nullable;
@ReactPropertyHolder
public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl> {
private static final boolean DEBUG = ReactBuildConfig.DEBUG || PrinterHolder.getPrinter().shouldDisplayLogMessage(ReactDebugOverlayTags.FABRIC_UI_MANAGER);
private static final String TAG = ReactShadowNodeImpl.class.getSimpleName();
private static final YogaConfig sYogaConfig;
static {
@@ -81,6 +90,12 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
private final float[] mPadding = new float[Spacing.ALL + 1];
private final boolean[] mPaddingIsPercent = new boolean[Spacing.ALL + 1];
private YogaNode mYogaNode;
private int mGenerationDebugInformation = 1;
private ReactShadowNode mOriginalReactShadowNode = null;
private @Nullable ReactStylesDiffMap mNewProps;
private long mInstanceHandle;
private boolean mIsSealed = false;
public ReactShadowNodeImpl() {
mDefaultPadding = new Spacing(0);
@@ -94,6 +109,32 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
}
}
protected ReactShadowNodeImpl(ReactShadowNodeImpl original) {
mReactTag = original.mReactTag;
mRootTag = original.mRootTag;
mViewClassName = original.mViewClassName;
mThemedContext = original.mThemedContext;
mShouldNotifyOnLayout = original.mShouldNotifyOnLayout;
mIsLayoutOnly = original.mIsLayoutOnly;
mNativeParent = original.mNativeParent;
mDefaultPadding = new Spacing(original.mDefaultPadding);
// Cloned nodes should be always updated.
mNodeUpdated = true;
// "cached" screen coordinates are not cloned because FabricJS not always clone the last
// ReactShadowNode that was rendered in the screen.
mScreenX = 0;
mScreenY = 0;
mScreenWidth = 0;
mScreenHeight = 0;
mGenerationDebugInformation = original.mGenerationDebugInformation + 1;
arraycopy(original.mPadding, 0, mPadding, 0, original.mPadding.length);
arraycopy(original.mPaddingIsPercent, 0, mPaddingIsPercent, 0, original.mPaddingIsPercent.length);
mNewProps = null;
mParent = null;
mOriginalReactShadowNode = original;
mIsSealed = false;
}
/**
* Nodes that return {@code true} will be treated as "virtual" nodes. That is, nodes that are not
* mapped into native views (e.g. nested text node). By default this method returns {@code false}.
@@ -298,6 +339,12 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
// no-op
}
@Override
@Nullable
public ReactStylesDiffMap getNewProps() {
return mNewProps;
}
/**
* Called after layout step at the end of the UI batch from {@link UIManagerModule}. May be used
* to enqueue additional ui operations for the native view. Will only be called on nodes marked as
@@ -929,7 +976,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
}
result.append("<").append(getClass().getSimpleName()).append(" view='").append(getViewClass())
.append("' tag=").append(getReactTag());
.append("' tag=").append(getReactTag()).append(" gen=").append(mGenerationDebugInformation);
if (mYogaNode != null) {
result.append(" layout='x:").append(getScreenX())
.append(" y:").append(getScreenY()).append(" w:").append(getLayoutWidth()).append(" h:")
@@ -956,4 +1003,17 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
}
}
@Nullable
@Override
public List<ReactShadowNode> getChildrenList() {
return mChildren == null ? null : Collections.<ReactShadowNode>unmodifiableList(mChildren);
}
@Override
public void updateScreenLayout(ReactShadowNode prevNode) {
mScreenHeight = prevNode.getScreenHeight();
mScreenWidth = prevNode.getScreenWidth();
mScreenX = prevNode.getScreenX();
mScreenY = prevNode.getScreenY();
}
}
@@ -9,7 +9,6 @@ package com.facebook.react.uimanager;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.View;
import com.facebook.react.common.SingleThreadAsserter;
/**
@@ -37,11 +36,6 @@ public class ShadowNodeRegistry {
public void removeRootNode(int tag) {
mThreadAsserter.assertNow();
if (tag == View.NO_ID) {
// This root node has already been removed (likely due to a threading issue caused by async js
// execution). Ignore this root removal.
return;
}
if (!mRootTags.get(tag)) {
throw new IllegalViewOperationException(
"View with tag " + tag + " is not registered as a root view");
@@ -18,7 +18,6 @@ import com.facebook.react.touch.ReactInterceptingViewGroup;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.annotations.ReactPropGroup;
import com.facebook.react.uimanager.annotations.ReactPropertyHolder;
import com.facebook.yoga.YogaMeasureMode;
import java.util.Map;
import javax.annotation.Nullable;
@@ -219,9 +218,9 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
ReadableNativeMap localData,
ReadableNativeMap props,
float width,
YogaMeasureMode widthMode,
int widthMode,
float height,
YogaMeasureMode heightMode) {
int heightMode) {
return null;
}
}
@@ -8,6 +8,7 @@
package com.facebook.react.uimanager.events;
import android.view.MotionEvent;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
@@ -439,7 +439,7 @@ public class ReactImageView extends GenericDraweeView {
hierarchy.setActualImageScaleType(mScaleType);
if (mDefaultImageDrawable != null) {
hierarchy.setPlaceholderImage(mDefaultImageDrawable, mScaleType);
hierarchy.setPlaceholderImage(mDefaultImageDrawable, ScalingUtils.ScaleType.CENTER);
}
if (mLoadingImageDrawable != null) {
@@ -309,18 +309,8 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
@Override
public void fling(int velocityY) {
// Workaround.
// On Android P if a ScrollView is inverted, we will get a wrong sign for
// velocityY (see https://issuetracker.google.com/issues/112385925).
// At the same time, mOnScrollDispatchHelper tracks the correct velocity direction.
//
// Hence, we can use the absolute value from whatever the OS gives
// us and use the sign of what mOnScrollDispatchHelper has tracked.
final int correctedVelocityY = (int)(Math.abs(velocityY) * Math.signum(mOnScrollDispatchHelper.getYFlingVelocity()));
if (mPagingEnabled) {
flingAndSnap(correctedVelocityY);
flingAndSnap(velocityY);
} else if (mScroller != null) {
// FB SCROLLVIEW CHANGE
@@ -336,7 +326,7 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
getScrollX(), // startX
getScrollY(), // startY
0, // velocityX
correctedVelocityY, // velocityY
velocityY, // velocityY
0, // minX
0, // maxX
0, // minY
@@ -349,9 +339,9 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
// END FB SCROLLVIEW CHANGE
} else {
super.fling(correctedVelocityY);
super.fling(velocityY);
}
handlePostTouchScrolling(0, correctedVelocityY);
handlePostTouchScrolling(0, velocityY);
}
private void enableFpsListener() {
@@ -1,11 +1,13 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.views.text;
import android.graphics.Rect;
import android.os.Build;
import android.text.BoringLayout;
import android.text.Layout;
@@ -13,12 +15,15 @@ import android.text.Spannable;
import android.text.Spanned;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.widget.TextView;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.ReactShadowNodeImpl;
import com.facebook.react.uimanager.Spacing;
import com.facebook.react.uimanager.UIViewOperationQueue;
import com.facebook.react.uimanager.annotations.ReactProp;
@@ -57,17 +62,16 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode {
YogaMeasureMode widthMode,
float height,
YogaMeasureMode heightMode) {
// TODO(5578671): Handle text direction (see View#getTextDirectionHeuristic)
TextPaint textPaint = sTextPaintInstance;
textPaint.setTextSize(mFontSize != UNSET ? mFontSize : getDefaultFontSize());
Layout layout;
Spanned text =
Assertions.assertNotNull(
mPreparedSpannableText,
"Spannable element has not been prepared in onBeforeLayout");
Spanned text = Assertions.assertNotNull(
mPreparedSpannableText,
"Spannable element has not been prepared in onBeforeLayout");
BoringLayout.Metrics boring = BoringLayout.isBoring(text, textPaint);
float desiredWidth = boring == null ? Layout.getDesiredWidth(text, textPaint) : Float.NaN;
float desiredWidth = boring == null ?
Layout.getDesiredWidth(text, textPaint) : Float.NaN;
// technically, width should never be negative, but there is currently a bug in
boolean unconstrainedWidth = widthMode == YogaMeasureMode.UNDEFINED || width < 0;
@@ -85,64 +89,70 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode {
break;
}
if (boring == null
&& (unconstrainedWidth
|| (!YogaConstants.isUndefined(desiredWidth) && desiredWidth <= width))) {
if (boring == null &&
(unconstrainedWidth ||
(!YogaConstants.isUndefined(desiredWidth) && desiredWidth <= width))) {
// Is used when the width is not known and the text is not boring, ie. if it contains
// unicode characters.
int hintWidth = (int) Math.ceil(desiredWidth);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
layout =
new StaticLayout(
text, textPaint, hintWidth, alignment, 1.f, 0.f, mIncludeFontPadding);
layout = new StaticLayout(
text,
textPaint,
hintWidth,
alignment,
1.f,
0.f,
mIncludeFontPadding);
} else {
layout =
StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, hintWidth)
.setAlignment(alignment)
.setLineSpacing(0.f, 1.f)
.setIncludePad(mIncludeFontPadding)
.setBreakStrategy(mTextBreakStrategy)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
.build();
layout = StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, hintWidth)
.setAlignment(alignment)
.setLineSpacing(0.f, 1.f)
.setIncludePad(mIncludeFontPadding)
.setBreakStrategy(mTextBreakStrategy)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
.build();
}
} else if (boring != null && (unconstrainedWidth || boring.width <= width)) {
// Is used for single-line, boring text when the width is either unknown or bigger
// than the width of the text.
layout =
BoringLayout.make(
text,
textPaint,
boring.width,
alignment,
1.f,
0.f,
boring,
mIncludeFontPadding);
layout = BoringLayout.make(
text,
textPaint,
boring.width,
alignment,
1.f,
0.f,
boring,
mIncludeFontPadding);
} else {
// Is used for multiline, boring text and the width is known.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
layout =
new StaticLayout(
text, textPaint, (int) width, alignment, 1.f, 0.f, mIncludeFontPadding);
layout = new StaticLayout(
text,
textPaint,
(int) width,
alignment,
1.f,
0.f,
mIncludeFontPadding);
} else {
layout =
StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, (int) width)
.setAlignment(alignment)
.setLineSpacing(0.f, 1.f)
.setIncludePad(mIncludeFontPadding)
.setBreakStrategy(mTextBreakStrategy)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
.build();
layout = StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, (int) width)
.setAlignment(alignment)
.setLineSpacing(0.f, 1.f)
.setIncludePad(mIncludeFontPadding)
.setBreakStrategy(mTextBreakStrategy)
.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
.build();
}
}
if (mShouldNotifyOnTextLayout) {
WritableArray lines =
FontMetricsUtil.getFontMetrics(
text, layout, sTextPaintInstance, getThemedContext());
FontMetricsUtil.getFontMetrics(text, layout, sTextPaintInstance, getThemedContext());
WritableMap event = Arguments.createMap();
event.putArray("lines", lines);
getThemedContext()
@@ -151,8 +161,7 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode {
}
if (mNumberOfLines != UNSET && mNumberOfLines < layout.getLineCount()) {
return YogaMeasureOutput.make(
layout.getWidth(), layout.getLineBottom(mNumberOfLines - 1));
return YogaMeasureOutput.make(layout.getWidth(), layout.getLineBottom(mNumberOfLines - 1));
} else {
return YogaMeasureOutput.make(layout.getWidth(), layout.getHeight());
}
@@ -206,16 +215,17 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode {
if (mPreparedSpannableText != null) {
ReactTextUpdate reactTextUpdate =
new ReactTextUpdate(
mPreparedSpannableText,
UNSET,
mContainsImages,
getPadding(Spacing.START),
getPadding(Spacing.TOP),
getPadding(Spacing.END),
getPadding(Spacing.BOTTOM),
getTextAlign(),
mTextBreakStrategy);
new ReactTextUpdate(
mPreparedSpannableText,
UNSET,
mContainsImages,
getPadding(Spacing.START),
getPadding(Spacing.TOP),
getPadding(Spacing.END),
getPadding(Spacing.BOTTOM),
getTextAlign(),
mTextBreakStrategy
);
uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), reactTextUpdate);
}
}
@@ -9,18 +9,18 @@ package com.facebook.react.views.text;
import android.text.Layout;
import android.text.Spannable;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.yoga.YogaMeasureMode;
import java.util.Map;
import javax.annotation.Nullable;
import com.facebook.yoga.YogaMeasureMode;
/**
* Concrete class for {@link ReactTextAnchorViewManager} which represents view managers of anchor
@@ -109,17 +109,18 @@ public class ReactTextViewManager
ReadableNativeMap localData,
ReadableNativeMap props,
float width,
YogaMeasureMode widthMode,
int widthMode,
float height,
YogaMeasureMode heightMode) {
int heightMode) {
// TODO: should widthMode and heightMode be a YogaMeasureMode?
return TextLayoutManager.measureText(context,
view,
localData,
props,
width,
widthMode,
YogaMeasureMode.fromInt(widthMode),
height,
heightMode);
YogaMeasureMode.fromInt(heightMode));
}
}
@@ -384,40 +384,33 @@ public class TextAttributeProps {
: -1;
}
//TODO T31905686 remove this from here and add support to RTL
//TODO remove this from here
private YogaDirection getLayoutDirection() {
return YogaDirection.LTR;
}
public float getBottomPadding() {
return getPaddingProp(ViewProps.PADDING_BOTTOM);
// TODO convert into constants
return getFloatProp("bottomPadding", 0f);
}
public float getLeftPadding() {
return getPaddingProp(ViewProps.PADDING_LEFT);
return getFloatProp("leftPadding", 0f);
}
public float getStartPadding() {
return getPaddingProp(ViewProps.PADDING_START);
return getFloatProp("startPadding", 0f);
}
public float getEndPadding() {
return getPaddingProp(ViewProps.PADDING_END);
return getFloatProp("endPadding", 0f);
}
public float getTopPadding() {
return getPaddingProp(ViewProps.PADDING_TOP);
return getFloatProp("topPadding", 0f);
}
public float getRightPadding() {
return getPaddingProp(ViewProps.PADDING_RIGHT);
}
private float getPaddingProp(String paddingType) {
if (mProps.hasKey(ViewProps.PADDING)) {
return PixelUtil.toPixelFromDIP(getFloatProp(ViewProps.PADDING, 0f));
}
return PixelUtil.toPixelFromDIP(getFloatProp(paddingType, 0f));
return getFloatProp("rightPadding", 0f);
}
}
@@ -29,10 +29,8 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeMap;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.ViewDefaults;
import com.facebook.yoga.YogaConstants;
import com.facebook.yoga.YogaMeasureMode;
import java.awt.font.TextAttribute;
import java.util.ArrayList;
import java.util.List;
@@ -97,9 +95,11 @@ public class TextLayoutManager {
new CustomLetterSpacingSpan(textAttributes.mLetterSpacing)));
}
}
ops.add(
new SetSpanOperation(
start, end, new AbsoluteSizeSpan(textAttributes.mFontSize)));
if (textAttributes.mFontSize != UNSET) {
ops.add(
new SetSpanOperation(
start, end, new AbsoluteSizeSpan((int) (textAttributes.mFontSize))));
}
if (textAttributes.mFontStyle != UNSET
|| textAttributes.mFontWeight != UNSET
|| textAttributes.mFontFamily != null) {
@@ -163,14 +163,23 @@ public class TextLayoutManager {
buildSpannedFromShadowNode(context, fragments, sb, ops);
// TODO T31905686: add support for inline Images
// TODO: add support for AllowScaling in C++
// if (textShadowNode.mFontSize == UNSET) {
// int defaultFontSize =
// textShadowNode.mAllowFontScaling
// ? (int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP))
// : (int) Math.ceil(PixelUtil.toPixelFromDIP(ViewDefaults.FONT_SIZE_SP));
//
// ops.add(new SetSpanOperation(0, sb.length(), new AbsoluteSizeSpan(defaultFontSize)));
// }
//
// textShadowNode.mContainsImages = false;
// textShadowNode.mHeightOfTallestInlineImage = Float.NaN;
// While setting the Spans on the final text, we also check whether any of them are images.
int priority = 0;
for (SetSpanOperation op : ops) {
// TODO T31905686: add support for TextInlineImage in C++
// TODO: add support for TextInlineImage in C++
// if (op.what instanceof TextInlineImageSpan) {
// int height = ((TextInlineImageSpan) op.what).getHeight();
// textShadowNode.mContainsImages = true;
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -8,7 +8,6 @@
package com.facebook.yoga;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.soloader.SoLoader;
@DoNotStrip
public class YogaConfig {
@@ -16,7 +15,7 @@ public class YogaConfig {
public static int SPACING_TYPE = 1;
static {
SoLoader.loadLibrary("yoga");
YogaJNI.init();
}
long mNativePointer;
@@ -35,8 +35,4 @@ public class YogaConstants {
public static boolean isUndefined(YogaValue value) {
return value.unit == YogaUnit.UNDEFINED;
}
public static float getUndefined() {
return UNDEFINED;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -0,0 +1,32 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.yoga;
import com.facebook.soloader.SoLoader;
public class YogaJNI {
private static boolean isInitialized = false;
// Known constants. 1-3 used in previous experiments. Do not reuse.
public static int JNI_FAST_CALLS = 4;
// set before loading any other Yoga code
public static boolean useFastCall = false;
private static native void jni_bindNativeMethods(boolean useFastCall);
static synchronized boolean init() {
if (!isInitialized) {
isInitialized = true;
SoLoader.loadLibrary("yoga");
jni_bindNativeMethods(useFastCall);
return true;
}
return false;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -8,7 +8,6 @@
package com.facebook.yoga;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.soloader.SoLoader;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
@@ -17,7 +16,7 @@ import javax.annotation.Nullable;
public class YogaNode implements Cloneable {
static {
SoLoader.loadLibrary("yoga");
YogaJNI.init();
}
/**
@@ -160,7 +159,6 @@ public class YogaNode implements Cloneable {
}
private static native void jni_YGNodeInsertChild(long nativePointer, long childPointer, int index);
public void addChildAt(YogaNode child, int i) {
if (child.mOwner != null) {
throw new IllegalStateException("Child already has a parent, it must be removed first.");
@@ -185,18 +183,6 @@ public class YogaNode implements Cloneable {
jni_YGNodeInsertSharedChild(mNativePointer, child.mNativePointer, i);
}
private static native void jni_YGNodeSetIsReferenceBaseline(long nativePointer, boolean isReferenceBaseline);
public void setIsReferenceBaseline(boolean isReferenceBaseline) {
jni_YGNodeSetIsReferenceBaseline(mNativePointer, isReferenceBaseline);
}
private static native boolean jni_YGNodeIsReferenceBaseline(long nativePointer);
public boolean isReferenceBaseline() {
return jni_YGNodeIsReferenceBaseline(mNativePointer);
}
private static native void jni_YGNodeSetOwner(long nativePointer, long newOwnerNativePointer);
private native long jni_YGNodeClone(long nativePointer, Object newNode);
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc.
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
@@ -371,17 +371,6 @@ void jni_YGNodeRemoveChild(jlong nativePointer, jlong childPointer) {
_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer));
}
void jni_YGNodeSetIsReferenceBaseline(
jlong nativePointer,
jboolean isReferenceBaseline) {
YGNodeSetIsReferenceBaseline(
_jlong2YGNodeRef(nativePointer), isReferenceBaseline);
}
jboolean jni_YGNodeIsReferenceBaseline(jlong nativePointer) {
return YGNodeIsReferenceBaseline(_jlong2YGNodeRef(nativePointer));
}
void jni_YGNodeCalculateLayout(
alias_ref<jclass>,
jlong nativePointer,
@@ -658,112 +647,130 @@ jint jni_YGNodeGetInstanceCount() {
}
#define YGMakeNativeMethod(name) makeNativeMethod(#name, name)
#define YGMakeCriticalNativeMethod(name) makeCriticalNativeMethod(#name, name)
#define YGRealMakeCriticalNativeMethod(name) \
makeCriticalNativeMethod(#name, name)
#define YGWrapCriticalNativeMethodForRegularCall(name) \
makeNativeMethod( \
#name, \
::facebook::jni::detail::CriticalMethod<decltype(&name)>::call<&name>)
#define YGRegisterNatives(YGMakeCriticalNativeMethod) \
registerNatives( \
"com/facebook/yoga/YogaNode", \
{ \
YGMakeNativeMethod(jni_YGNodeNew), \
YGMakeNativeMethod(jni_YGNodeNewWithConfig), \
YGMakeCriticalNativeMethod(jni_YGNodeFree), \
YGMakeCriticalNativeMethod(jni_YGNodeReset), \
YGMakeCriticalNativeMethod(jni_YGNodeClearChildren), \
YGMakeCriticalNativeMethod(jni_YGNodeInsertChild), \
YGMakeCriticalNativeMethod(jni_YGNodeInsertSharedChild), \
YGMakeCriticalNativeMethod(jni_YGNodeRemoveChild), \
YGMakeNativeMethod(jni_YGNodeCalculateLayout), \
YGMakeCriticalNativeMethod(jni_YGNodeMarkDirty), \
YGMakeCriticalNativeMethod( \
jni_YGNodeMarkDirtyAndPropogateToDescendants), \
YGMakeCriticalNativeMethod(jni_YGNodeIsDirty), \
YGMakeCriticalNativeMethod(jni_YGNodeSetHasMeasureFunc), \
YGMakeCriticalNativeMethod(jni_YGNodeSetHasBaselineFunc), \
YGMakeCriticalNativeMethod(jni_YGNodeCopyStyle), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetDirection), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetDirection), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetFlexDirection), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexDirection), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetJustifyContent), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetJustifyContent), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetAlignItems), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetAlignItems), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetAlignSelf), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetAlignSelf), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetAlignContent), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetAlignContent), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetPositionType), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetPositionType), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexWrap), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetOverflow), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetOverflow), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetDisplay), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetDisplay), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlex), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetFlexGrow), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexGrow), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetFlexShrink), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexShrink), \
YGMakeNativeMethod(jni_YGNodeStyleGetFlexBasis), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexBasis), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexBasisPercent), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexBasisAuto), \
YGMakeNativeMethod(jni_YGNodeStyleGetMargin), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMargin), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMarginPercent), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMarginAuto), \
YGMakeNativeMethod(jni_YGNodeStyleGetPadding), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetPadding), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetPaddingPercent), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetBorder), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetBorder), \
YGMakeNativeMethod(jni_YGNodeStyleGetPosition), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetPosition), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetPositionPercent), \
YGMakeNativeMethod(jni_YGNodeStyleGetWidth), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetWidth), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetWidthPercent), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetWidthAuto), \
YGMakeNativeMethod(jni_YGNodeStyleGetHeight), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetHeight), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetHeightPercent), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetHeightAuto), \
YGMakeNativeMethod(jni_YGNodeStyleGetMinWidth), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMinWidth), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMinWidthPercent), \
YGMakeNativeMethod(jni_YGNodeStyleGetMinHeight), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMinHeight), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMinHeightPercent), \
YGMakeNativeMethod(jni_YGNodeStyleGetMaxWidth), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMaxWidth), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMaxWidthPercent), \
YGMakeNativeMethod(jni_YGNodeStyleGetMaxHeight), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMaxHeight), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMaxHeightPercent), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetAspectRatio), \
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetAspectRatio), \
YGMakeCriticalNativeMethod(jni_YGNodeGetInstanceCount), \
YGMakeCriticalNativeMethod(jni_YGNodePrint), \
YGMakeNativeMethod(jni_YGNodeClone), \
YGMakeCriticalNativeMethod(jni_YGNodeSetOwner), \
}); \
registerNatives( \
"com/facebook/yoga/YogaConfig", \
{ \
YGMakeNativeMethod(jni_YGConfigNew), \
YGMakeNativeMethod(jni_YGConfigFree), \
YGMakeNativeMethod(jni_YGConfigSetExperimentalFeatureEnabled), \
YGMakeNativeMethod(jni_YGConfigSetUseWebDefaults), \
YGMakeNativeMethod(jni_YGConfigSetPrintTreeFlag), \
YGMakeNativeMethod(jni_YGConfigSetPointScaleFactor), \
YGMakeNativeMethod(jni_YGConfigSetUseLegacyStretchBehaviour), \
YGMakeNativeMethod(jni_YGConfigSetLogger), \
YGMakeNativeMethod(jni_YGConfigSetHasCloneNodeFunc), \
YGMakeNativeMethod( \
jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour), \
});
void jni_bindNativeMethods(alias_ref<jclass>, jboolean useFastCall) {
if (useFastCall) {
YGRegisterNatives(YGRealMakeCriticalNativeMethod);
} else {
YGRegisterNatives(YGWrapCriticalNativeMethodForRegularCall);
}
}
jint JNI_OnLoad(JavaVM* vm, void*) {
return initialize(vm, [] {
registerNatives(
"com/facebook/yoga/YogaNode",
"com/facebook/yoga/YogaJNI",
{
YGMakeNativeMethod(jni_YGNodeNew),
YGMakeNativeMethod(jni_YGNodeNewWithConfig),
YGMakeCriticalNativeMethod(jni_YGNodeFree),
YGMakeCriticalNativeMethod(jni_YGNodeReset),
YGMakeCriticalNativeMethod(jni_YGNodeClearChildren),
YGMakeCriticalNativeMethod(jni_YGNodeInsertChild),
YGMakeCriticalNativeMethod(jni_YGNodeInsertSharedChild),
YGMakeCriticalNativeMethod(jni_YGNodeRemoveChild),
YGMakeCriticalNativeMethod(jni_YGNodeSetIsReferenceBaseline),
YGMakeCriticalNativeMethod(jni_YGNodeIsReferenceBaseline),
YGMakeNativeMethod(jni_YGNodeCalculateLayout),
YGMakeCriticalNativeMethod(jni_YGNodeMarkDirty),
YGMakeCriticalNativeMethod(
jni_YGNodeMarkDirtyAndPropogateToDescendants),
YGMakeCriticalNativeMethod(jni_YGNodeIsDirty),
YGMakeCriticalNativeMethod(jni_YGNodeSetHasMeasureFunc),
YGMakeCriticalNativeMethod(jni_YGNodeSetHasBaselineFunc),
YGMakeCriticalNativeMethod(jni_YGNodeCopyStyle),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetDirection),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetDirection),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetFlexDirection),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexDirection),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetJustifyContent),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetJustifyContent),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetAlignItems),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetAlignItems),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetAlignSelf),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetAlignSelf),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetAlignContent),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetAlignContent),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetPositionType),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetPositionType),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexWrap),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetOverflow),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetOverflow),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetDisplay),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetDisplay),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlex),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetFlexGrow),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexGrow),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetFlexShrink),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexShrink),
YGMakeNativeMethod(jni_YGNodeStyleGetFlexBasis),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexBasis),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexBasisPercent),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetFlexBasisAuto),
YGMakeNativeMethod(jni_YGNodeStyleGetMargin),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMargin),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMarginPercent),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMarginAuto),
YGMakeNativeMethod(jni_YGNodeStyleGetPadding),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetPadding),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetPaddingPercent),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetBorder),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetBorder),
YGMakeNativeMethod(jni_YGNodeStyleGetPosition),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetPosition),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetPositionPercent),
YGMakeNativeMethod(jni_YGNodeStyleGetWidth),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetWidth),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetWidthPercent),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetWidthAuto),
YGMakeNativeMethod(jni_YGNodeStyleGetHeight),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetHeight),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetHeightPercent),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetHeightAuto),
YGMakeNativeMethod(jni_YGNodeStyleGetMinWidth),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMinWidth),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMinWidthPercent),
YGMakeNativeMethod(jni_YGNodeStyleGetMinHeight),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMinHeight),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMinHeightPercent),
YGMakeNativeMethod(jni_YGNodeStyleGetMaxWidth),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMaxWidth),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMaxWidthPercent),
YGMakeNativeMethod(jni_YGNodeStyleGetMaxHeight),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMaxHeight),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetMaxHeightPercent),
YGMakeCriticalNativeMethod(jni_YGNodeStyleGetAspectRatio),
YGMakeCriticalNativeMethod(jni_YGNodeStyleSetAspectRatio),
YGMakeCriticalNativeMethod(jni_YGNodeGetInstanceCount),
YGMakeCriticalNativeMethod(jni_YGNodePrint),
YGMakeNativeMethod(jni_YGNodeClone),
YGMakeCriticalNativeMethod(jni_YGNodeSetOwner),
});
registerNatives(
"com/facebook/yoga/YogaConfig",
{
YGMakeNativeMethod(jni_YGConfigNew),
YGMakeNativeMethod(jni_YGConfigFree),
YGMakeNativeMethod(jni_YGConfigSetExperimentalFeatureEnabled),
YGMakeNativeMethod(jni_YGConfigSetUseWebDefaults),
YGMakeNativeMethod(jni_YGConfigSetPrintTreeFlag),
YGMakeNativeMethod(jni_YGConfigSetPointScaleFactor),
YGMakeNativeMethod(jni_YGConfigSetUseLegacyStretchBehaviour),
YGMakeNativeMethod(jni_YGConfigSetLogger),
YGMakeNativeMethod(jni_YGConfigSetHasCloneNodeFunc),
YGMakeNativeMethod(
jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour),
YGMakeNativeMethod(jni_bindNativeMethods),
});
});
}
+1 -1
View File
@@ -1,5 +1,5 @@
load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native")
load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_library")
load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_library", "rn_android_resource", "rn_prebuilt_jar")
rn_android_library(
name = "support-v4",
@@ -1,4 +1,4 @@
load("//tools/build_defs/oss:rn_defs.bzl", "YOGA_TARGET", "react_native_dep", "react_native_target", "rn_robolectric_test")
load("//tools/build_defs/oss:rn_defs.bzl", "YOGA_TARGET", "react_native_dep", "react_native_target", "react_native_tests_target", "rn_robolectric_test")
rn_robolectric_test(
name = "layoutanimation",
+6 -35
View File
@@ -67,14 +67,13 @@ public:
std::string name;
size_t callbacks;
bool isPromise;
std::function<void(folly::dynamic, Callback, Callback)> func;
std::function<folly::dynamic(folly::dynamic)> syncFunc;
const char *getType() {
assert(func || syncFunc);
return func ? (isPromise ? "promise" : "async") : "sync";
return func ? (callbacks == 2 ? "promise" : "async") : "sync";
}
// std::function/lambda ctors
@@ -83,36 +82,24 @@ public:
std::function<void()>&& afunc)
: name(std::move(aname))
, callbacks(0)
, isPromise(false)
, func(std::bind(std::move(afunc))) {}
Method(std::string aname,
std::function<void(folly::dynamic)>&& afunc)
: name(std::move(aname))
, callbacks(0)
, isPromise(false)
, func(std::bind(std::move(afunc), std::placeholders::_1)) {}
, func(std::bind(std::move(afunc), _1)) {}
Method(std::string aname,
std::function<void(folly::dynamic, Callback)>&& afunc)
: name(std::move(aname))
, callbacks(1)
, isPromise(false)
, func(std::bind(std::move(afunc), std::placeholders::_1, std::placeholders::_2)) {}
, func(std::bind(std::move(afunc), _1, _2)) {}
Method(std::string aname,
std::function<void(folly::dynamic, Callback, Callback)>&& afunc)
: name(std::move(aname))
, callbacks(2)
, isPromise(true)
, func(std::move(afunc)) {}
Method(std::string aname,
std::function<void(folly::dynamic, Callback, Callback)>&& afunc,
AsyncTagType)
: name(std::move(aname))
, callbacks(2)
, isPromise(false)
, func(std::move(afunc)) {}
// method pointer ctors
@@ -121,39 +108,25 @@ public:
Method(std::string aname, T* t, void (T::*method)())
: name(std::move(aname))
, callbacks(0)
, isPromise(false)
, func(std::bind(method, t)) {}
template <typename T>
Method(std::string aname, T* t, void (T::*method)(folly::dynamic))
: name(std::move(aname))
, callbacks(0)
, isPromise(false)
, func(std::bind(method, t, std::placeholders::_1)) {}
, func(std::bind(method, t, _1)) {}
template <typename T>
Method(std::string aname, T* t, void (T::*method)(folly::dynamic, Callback))
: name(std::move(aname))
, callbacks(1)
, isPromise(false)
, func(std::bind(method, t, std::placeholders::_1, std::placeholders::_2)) {}
, func(std::bind(method, t, _1, _2)) {}
template <typename T>
Method(std::string aname, T* t, void (T::*method)(folly::dynamic, Callback, Callback))
: name(std::move(aname))
, callbacks(2)
, isPromise(true)
, func(std::bind(method, t, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) {}
template <typename T>
Method(std::string aname,
T* t,
void (T::*method)(folly::dynamic, Callback, Callback),
AsyncTagType)
: name(std::move(aname))
, callbacks(2)
, isPromise(false)
, func(std::bind(method, t, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) {}
, func(std::bind(method, t, _1, _2, _3)) {}
// sync std::function/lambda ctors
@@ -166,7 +139,6 @@ public:
SyncTagType)
: name(std::move(aname))
, callbacks(0)
, isPromise(false)
, syncFunc([afunc=std::move(afunc)] (const folly::dynamic&)
{ return afunc(); })
{}
@@ -176,7 +148,6 @@ public:
SyncTagType)
: name(std::move(aname))
, callbacks(0)
, isPromise(false)
, syncFunc(std::move(afunc))
{}
};
-2
View File
@@ -136,8 +136,6 @@ void CxxNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params
if (callId != -1) {
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
}
#else
(void)(callId);
#endif
SystraceSection s(method.name.c_str());
try {
+2 -1
View File
@@ -18,7 +18,7 @@ namespace react {
static const char *errorPrefix = "Malformed calls from JS: ";
std::vector<MethodCall> parseMethodCalls(folly::dynamic&& jsonData) {
std::vector<MethodCall> parseMethodCalls(folly::dynamic&& jsonData) throw(std::invalid_argument) {
if (jsonData.isNull()) {
return {};
}
@@ -77,3 +77,4 @@ std::vector<MethodCall> parseMethodCalls(folly::dynamic&& jsonData) {
}
}}
+1 -2
View File
@@ -27,7 +27,6 @@ struct MethodCall {
, callId(cid) {}
};
/// \throws std::invalid_argument
std::vector<MethodCall> parseMethodCalls(folly::dynamic&& calls);
std::vector<MethodCall> parseMethodCalls(folly::dynamic&& calls) throw(std::invalid_argument);
} }
+3 -3
View File
@@ -90,13 +90,13 @@ folly::Optional<ModuleConfig> ModuleRegistry::getConfig(const std::string& name)
if (it == modulesByName_.end()) {
if (unknownModules_.find(name) != unknownModules_.end()) {
return folly::none;
return nullptr;
}
if (!moduleNotFoundCallback_ ||
!moduleNotFoundCallback_(name) ||
(it = modulesByName_.find(name)) == modulesByName_.end()) {
unknownModules_.insert(name);
return folly::none;
return nullptr;
}
}
size_t index = it->second;
@@ -143,7 +143,7 @@ folly::Optional<ModuleConfig> ModuleRegistry::getConfig(const std::string& name)
if (config.size() == 2 && config[1].empty()) {
// no constants or methods
return folly::none;
return nullptr;
} else {
return ModuleConfig{index, config};
}
@@ -161,8 +161,6 @@ void NativeToJsBridge::callFunction(
"JSCall",
systraceCookie);
SystraceSection s("NativeToJsBridge::callFunction", "module", module, "method", method);
#else
(void)(systraceCookie);
#endif
// This is safe because we are running on the executor's thread: it won't
// destruct until after it's been unregistered (which we check above) and
@@ -193,8 +191,6 @@ void NativeToJsBridge::invokeCallback(double callbackId, folly::dynamic&& argume
"<callback>",
systraceCookie);
SystraceSection s("NativeToJsBridge::invokeCallback");
#else
(void)(systraceCookie);
#endif
executor->invokeCallback(callbackId, arguments);
});
+1 -1
View File
@@ -23,7 +23,7 @@ struct RecoverableError : public std::exception {
: m_what { "facebook::react::Recoverable: " + what_ }
{}
virtual const char* what() const noexcept override { return m_what.c_str(); }
virtual const char* what() const throw() override { return m_what.c_str(); }
/**
* runRethrowingAsRecoverable
-19
View File
@@ -114,25 +114,6 @@ auto SampleCxxModule::getMethods() -> std::vector<Method> {
sample_->hello();
return nullptr;
}, SyncTag),
Method("addIfPositiveAsPromise", [](dynamic args, Callback cb, Callback cbError) {
auto a = jsArgAsDouble(args, 0);
auto b = jsArgAsDouble(args, 1);
if (a < 0 || b < 0) {
cbError({"Negative number!"});
} else {
cb({a + b});
}
}),
Method("addIfPositiveAsAsync", [](dynamic args, Callback cb, Callback cbError) {
auto a = jsArgAsDouble(args, 0);
auto b = jsArgAsDouble(args, 1);
if (a < 0 || b < 0) {
cbError({"Negative number!"});
} else {
cb({a + b});
}
}, AsyncTag),
};
}
@@ -73,7 +73,7 @@ std::string AttributedString::getString() const {
}
bool AttributedString::operator==(const AttributedString &rhs) const {
return fragments_ == rhs.fragments_;
return fragments_ != rhs.fragments_;
}
bool AttributedString::operator!=(const AttributedString &rhs) const {
@@ -158,7 +158,7 @@ TextAttributes TextAttributes::defaultTextAttributes() {
// Non-obvious (can be different among platforms) default text attributes.
textAttributes.foregroundColor = blackColor();
textAttributes.backgroundColor = clearColor();
textAttributes.fontSize = 14.0;
textAttributes.fontSize = 12.0;
return textAttributes;
}();
return textAttributes;

Some files were not shown because too many files have changed in this diff Show More