From 16f06bcb80184739277ae16aec2a5550c206be75 Mon Sep 17 00:00:00 2001 From: empyrical Date: Fri, 28 Sep 2018 00:04:05 -0700 Subject: [PATCH 001/112] SwipeableRow: Remove PropTypes, convert to ES6 class (#21386) Summary: Part of: https://github.com/facebook/react-native/issues/21342 This PR removes prop types from `SwipeableRow`, and converts it from a `createReactClass` to an ES6 class. Pull Request resolved: https://github.com/facebook/react-native/pull/21386 Differential Revision: D10100555 Pulled By: TheSavior fbshipit-source-id: ab350546f4fa6f1ed3fdeae07e342890af6d9a22 --- .../Experimental/SwipeableRow/SwipeableRow.js | 205 ++++++++---------- 1 file changed, 94 insertions(+), 111 deletions(-) diff --git a/Libraries/Experimental/SwipeableRow/SwipeableRow.js b/Libraries/Experimental/SwipeableRow/SwipeableRow.js index fb9cc1df409090..be44b3c3abffa9 100644 --- a/Libraries/Experimental/SwipeableRow/SwipeableRow.js +++ b/Libraries/Experimental/SwipeableRow/SwipeableRow.js @@ -16,13 +16,8 @@ const PanResponder = require('PanResponder'); const React = require('React'); const PropTypes = require('prop-types'); const StyleSheet = require('StyleSheet'); -/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error - * found when Flow v0.54 was deployed. To see the error delete this comment and - * run Flow. */ -const TimerMixin = require('react-timer-mixin'); const View = require('View'); -const createReactClass = require('create-react-class'); const emptyFunction = require('fbjs/lib/emptyFunction'); import type {LayoutEvent, PressEvent} from 'CoreEventTypes'; @@ -62,18 +57,38 @@ const RIGHT_SWIPE_THRESHOLD = 30 * SLOW_SPEED_SWIPE_FACTOR; type Props = $ReadOnly<{| children?: ?React.Node, - isOpen?: ?boolean, - maxSwipeDistance?: ?number, - onClose?: ?Function, - onOpen?: ?Function, - onSwipeEnd?: ?Function, - onSwipeStart?: ?Function, - preventSwipeRight?: ?boolean, + isOpen: boolean, + maxSwipeDistance: number, + onClose: () => mixed, + onOpen: () => mixed, + onSwipeEnd: () => mixed, + onSwipeStart: () => mixed, + preventSwipeRight: boolean, + + /** + * Should bounce the row on mount + */ shouldBounceOnMount?: ?boolean, + + /** + * A ReactElement that is unveiled when the user swipes + */ slideoutView?: ?React.Node, - swipeThreshold?: ?number, + + /** + * The minimum swipe distance required before fully animating the swipe. If + * the user swipes less than this distance, the item will return to its + * previous (open/close) position. + */ + swipeThreshold: number, |}>; +type State = {| + currentLeft: Animated.Value, + isSwipeableViewRendered: boolean, + rowHeight: ?number, +|}; + /** * Creates a swipable row that allows taps on the main item and a custom View * on the item hidden behind the row. Typically this should be used in @@ -81,75 +96,44 @@ type Props = $ReadOnly<{| * used in a normal ListView. See the renderRow for SwipeableListView to see how * to use this component separately. */ -const SwipeableRow = createReactClass({ - displayName: 'SwipeableRow', - _panResponder: {}, - _previousLeft: CLOSED_LEFT_POSITION, - - mixins: [TimerMixin], - - propTypes: { - children: PropTypes.any, - isOpen: PropTypes.bool, - preventSwipeRight: PropTypes.bool, - maxSwipeDistance: PropTypes.number.isRequired, - onOpen: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - onSwipeEnd: PropTypes.func.isRequired, - onSwipeStart: PropTypes.func.isRequired, - // Should bounce the row on mount - shouldBounceOnMount: PropTypes.bool, - /** - * A ReactElement that is unveiled when the user swipes - */ - slideoutView: PropTypes.node.isRequired, +class SwipeableRow extends React.Component { + _timerID: ?TimeoutID = null; + + static defaultProps = { + isOpen: false, + preventSwipeRight: false, + maxSwipeDistance: 0, + onOpen: emptyFunction, + onClose: emptyFunction, + onSwipeEnd: emptyFunction, + onSwipeStart: emptyFunction, + swipeThreshold: 30, + }; + + state = { + currentLeft: new Animated.Value(this._previousLeft), /** - * The minimum swipe distance required before fully animating the swipe. If - * the user swipes less than this distance, the item will return to its - * previous (open/close) position. + * In order to render component A beneath component B, A must be rendered + * before B. However, this will cause "flickering", aka we see A briefly + * then B. To counter this, _isSwipeableViewRendered flag is used to set + * component A to be transparent until component B is loaded. */ - swipeThreshold: PropTypes.number.isRequired, - }, - - getInitialState(): Object { - return { - currentLeft: new Animated.Value(this._previousLeft), - /** - * In order to render component A beneath component B, A must be rendered - * before B. However, this will cause "flickering", aka we see A briefly - * then B. To counter this, _isSwipeableViewRendered flag is used to set - * component A to be transparent until component B is loaded. - */ - isSwipeableViewRendered: false, - rowHeight: (null: ?number), - }; - }, - - getDefaultProps(): Object { - return { - isOpen: false, - preventSwipeRight: false, - maxSwipeDistance: 0, - onOpen: emptyFunction, - onClose: emptyFunction, - onSwipeEnd: emptyFunction, - onSwipeStart: emptyFunction, - swipeThreshold: 30, - }; - }, - - UNSAFE_componentWillMount(): void { - this._panResponder = PanResponder.create({ - onMoveShouldSetPanResponderCapture: this - ._handleMoveShouldSetPanResponderCapture, - onPanResponderGrant: this._handlePanResponderGrant, - onPanResponderMove: this._handlePanResponderMove, - onPanResponderRelease: this._handlePanResponderEnd, - onPanResponderTerminationRequest: this._onPanResponderTerminationRequest, - onPanResponderTerminate: this._handlePanResponderEnd, - onShouldBlockNativeResponder: (event, gestureState) => false, - }); - }, + isSwipeableViewRendered: false, + rowHeight: null, + }; + + _panResponder = PanResponder.create({ + onMoveShouldSetPanResponderCapture: this + ._handleMoveShouldSetPanResponderCapture, + onPanResponderGrant: this._handlePanResponderGrant, + onPanResponderMove: this._handlePanResponderMove, + onPanResponderRelease: this._handlePanResponderEnd, + onPanResponderTerminationRequest: this._onPanResponderTerminationRequest, + onPanResponderTerminate: this._handlePanResponderEnd, + onShouldBlockNativeResponder: (event, gestureState) => false, + }); + + _previousLeft = CLOSED_LEFT_POSITION; componentDidMount(): void { if (this.props.shouldBounceOnMount) { @@ -157,13 +141,17 @@ const SwipeableRow = createReactClass({ * Do the on mount bounce after a delay because if we animate when other * components are loading, the animation will be laggy */ - this.setTimeout(() => { + this._timerID = setTimeout(() => { this._animateBounceBack(ON_MOUNT_BOUNCE_DURATION); }, ON_MOUNT_BOUNCE_DELAY); } - }, + } + + componentWillUnmount(): void { + this._timerID && clearTimeout(this._timerID); + } - UNSAFE_componentWillReceiveProps(nextProps: Object): void { + UNSAFE_componentWillReceiveProps(nextProps: Props): void { /** * We do not need an "animateOpen(noCallback)" because this animation is * handled internally by this component. @@ -171,9 +159,9 @@ const SwipeableRow = createReactClass({ if (this.props.isOpen && !nextProps.isOpen) { this._animateToClosedPosition(); } - }, + } - render(): React.Element { + render(): React.Node { // The view hidden behind the main view let slideOutView; if (this.state.isSwipeableViewRendered && this.state.rowHeight) { @@ -200,19 +188,19 @@ const SwipeableRow = createReactClass({ {swipeableView} ); - }, + } close(): void { this.props.onClose(); this._animateToClosedPosition(); - }, + } _onSwipeableViewLayout(event: LayoutEvent): void { this.setState({ isSwipeableViewRendered: true, rowHeight: event.nativeEvent.layout.height, }); - }, + } _handleMoveShouldSetPanResponderCapture( event: PressEvent, @@ -220,12 +208,12 @@ const SwipeableRow = createReactClass({ ): boolean { // Decides whether a swipe is responded to by this component or its child return gestureState.dy < 10 && this._isValidSwipe(gestureState); - }, + } _handlePanResponderGrant( event: PressEvent, gestureState: GestureState, - ): void {}, + ): void {} _handlePanResponderMove(event: PressEvent, gestureState: GestureState): void { if (this._isSwipingExcessivelyRightFromClosedPosition(gestureState)) { @@ -239,22 +227,22 @@ const SwipeableRow = createReactClass({ } else { this._swipeFullSpeed(gestureState); } - }, + } _isSwipingRightFromClosed(gestureState: GestureState): boolean { const gestureStateDx = IS_RTL ? -gestureState.dx : gestureState.dx; return this._previousLeft === CLOSED_LEFT_POSITION && gestureStateDx > 0; - }, + } _swipeFullSpeed(gestureState: GestureState): void { this.state.currentLeft.setValue(this._previousLeft + gestureState.dx); - }, + } _swipeSlowSpeed(gestureState: GestureState): void { this.state.currentLeft.setValue( this._previousLeft + gestureState.dx / SLOW_SPEED_SWIPE_FACTOR, ); - }, + } _isSwipingExcessivelyRightFromClosedPosition( gestureState: GestureState, @@ -269,14 +257,14 @@ const SwipeableRow = createReactClass({ this._isSwipingRightFromClosed(gestureState) && gestureStateDx > RIGHT_SWIPE_THRESHOLD ); - }, + } _onPanResponderTerminationRequest( event: PressEvent, gestureState: GestureState, ): boolean { return false; - }, + } _animateTo( toValue: number, @@ -291,14 +279,14 @@ const SwipeableRow = createReactClass({ this._previousLeft = toValue; callback(); }); - }, + } _animateToOpenPosition(): void { const maxSwipeDistance = IS_RTL ? -this.props.maxSwipeDistance : this.props.maxSwipeDistance; this._animateTo(-maxSwipeDistance); - }, + } _animateToOpenPositionWith(speed: number, distMoved: number): void { /** @@ -320,15 +308,15 @@ const SwipeableRow = createReactClass({ ? -this.props.maxSwipeDistance : this.props.maxSwipeDistance; this._animateTo(-maxSwipeDistance, duration); - }, + } _animateToClosedPosition(duration: number = SWIPE_DURATION): void { this._animateTo(CLOSED_LEFT_POSITION, duration); - }, + } _animateToClosedPositionDuringBounce(): void { this._animateToClosedPosition(RIGHT_SWIPE_BOUNCE_BACK_DURATION); - }, + } _animateBounceBack(duration: number): void { /** @@ -343,7 +331,7 @@ const SwipeableRow = createReactClass({ duration, this._animateToClosedPositionDuringBounce, ); - }, + } // Ignore swipes due to user's finger moving slightly when tapping _isValidSwipe(gestureState: GestureState): boolean { @@ -356,7 +344,7 @@ const SwipeableRow = createReactClass({ } return Math.abs(gestureState.dx) > HORIZONTAL_SWIPE_DISTANCE_THRESHOLD; - }, + } _shouldAnimateRemainder(gestureState: GestureState): boolean { /** @@ -367,7 +355,7 @@ const SwipeableRow = createReactClass({ Math.abs(gestureState.dx) > this.props.swipeThreshold || gestureState.vx > HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD ); - }, + } _handlePanResponderEnd(event: PressEvent, gestureState: GestureState): void { const horizontalDistance = IS_RTL ? -gestureState.dx : gestureState.dx; @@ -393,12 +381,7 @@ const SwipeableRow = createReactClass({ } this.props.onSwipeEnd(); - }, -}); - -// TODO: Delete this when `SwipeableRow` uses class syntax. -class TypedSwipeableRow extends React.Component { - close() {} + } } const styles = StyleSheet.create({ @@ -411,4 +394,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = ((SwipeableRow: any): Class); +module.exports = SwipeableRow; From 9104b0426103748c528768c9dd4237b1448c54fa Mon Sep 17 00:00:00 2001 From: empyrical Date: Fri, 28 Sep 2018 00:16:59 -0700 Subject: [PATCH 002/112] SwipeableFlatList, SwipeableQuickActions: Remove PropTypes (#21384) Summary: Part of: https://github.com/facebook/react-native/issues/21342 This PR removes the prop types for the components `SwipeableFlatList` and `SwipeableQuickActions`. The props for `SwipeableFlatList` have been left as not $ReadOnly, because it needs the types in `Libraries/Lists/*` to also be cleaned up. A todo notice has been added. Pull Request resolved: https://github.com/facebook/react-native/pull/21384 Differential Revision: D10099694 Pulled By: TheSavior fbshipit-source-id: 424b900942c9a7889b664f351f79abee55923430 --- .../SwipeableRow/SwipeableFlatList.js | 36 +++++++------------ .../SwipeableRow/SwipeableQuickActions.js | 18 +++++----- 2 files changed, 21 insertions(+), 33 deletions(-) diff --git a/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js b/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js index c2790f848a5979..cf54d9d502f7f8 100644 --- a/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js +++ b/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js @@ -17,23 +17,31 @@ const React = require('React'); const SwipeableRow = require('SwipeableRow'); const FlatList = require('FlatList'); +// TODO: Make this $ReadOnly and Exact. Will require doing the same to the props in +// Libraries/Lists/* type SwipableListProps = { /** * To alert the user that swiping is possible, the first row can bounce * on component mount. */ bounceFirstRowOnMount: boolean, - // Maximum distance to open to after a swipe + + /** + * Maximum distance to open to after a swipe + */ maxSwipeDistance: number | (Object => number), - // Callback method to render the view that will be unveiled on swipe + + /** + * Callback method to render the view that will be unveiled on swipe + */ renderQuickActions: renderItemType, }; type Props = SwipableListProps & FlatListProps; -type State = { +type State = {| openRowKey: ?string, -}; +|}; /** * A container component that renders multiple SwipeableRow's in a FlatList @@ -53,29 +61,9 @@ type State = { */ class SwipeableFlatList extends React.Component, State> { - props: Props; - state: State; - _flatListRef: ?FlatList = null; _shouldBounceFirstRowOnMount: boolean = false; - static propTypes = { - ...FlatList.propTypes, - - /** - * To alert the user that swiping is possible, the first row can bounce - * on component mount. - */ - bounceFirstRowOnMount: PropTypes.bool.isRequired, - - // Maximum distance to open to after a swipe - maxSwipeDistance: PropTypes.oneOfType([PropTypes.number, PropTypes.func]) - .isRequired, - - // Callback method to render the view that will be unveiled on swipe - renderQuickActions: PropTypes.func.isRequired, - }; - static defaultProps = { ...FlatList.defaultProps, bounceFirstRowOnMount: true, diff --git a/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js b/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js index 4d2a43825f3b36..c97f77648af76f 100644 --- a/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js +++ b/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js @@ -10,11 +10,17 @@ 'use strict'; -const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); const React = require('React'); const StyleSheet = require('StyleSheet'); const View = require('View'); +import type {ViewStyleProp} from 'StyleSheet'; + +type Props = $ReadOnly<{| + style?: ?ViewStyleProp, + children: React.Node, +|}>; + /** * A thin wrapper around standard quick action buttons that can, if the user * chooses, be used with SwipeableListView. Sample usage is as follows, in the @@ -25,13 +31,8 @@ const View = require('View'); * * */ -class SwipeableQuickActions extends React.Component<{style?: $FlowFixMe}> { - static propTypes = { - style: DeprecatedViewPropTypes.style, - }; - +class SwipeableQuickActions extends React.Component { render(): React.Node { - // $FlowFixMe found when converting React.createClass to ES6 const children = this.props.children; let buttons = []; @@ -40,8 +41,7 @@ class SwipeableQuickActions extends React.Component<{style?: $FlowFixMe}> { for (let i = 0; i < children.length; i++) { buttons.push(children[i]); - // $FlowFixMe found when converting React.createClass to ES6 - if (i < this.props.children.length - 1) { + if (i < children.length - 1) { // Not last button buttons.push(); } From d16ec742368085a92e0994509cae786c074000ff Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Fri, 28 Sep 2018 00:48:05 -0700 Subject: [PATCH 003/112] RN: Replace `ImageResizeMode` w/ Flow Type Summary: Replaces `ImageResizeMode` with a Flow type. JavaScript enums provide little value when you have a type system. Reviewed By: bvaughn, TheSavior Differential Revision: D10057237 fbshipit-source-id: f108b60795a6d82a6786421e4ac72aeedc53bee8 --- Libraries/Image/ImageResizeMode.js | 60 ++++++++++---------------- Libraries/Image/ImageStylePropTypes.js | 9 +++- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/Libraries/Image/ImageResizeMode.js b/Libraries/Image/ImageResizeMode.js index b3f3b087887df2..1dad3309b1588d 100644 --- a/Libraries/Image/ImageResizeMode.js +++ b/Libraries/Image/ImageResizeMode.js @@ -4,49 +4,33 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow + * @flow strict * @format */ -'use strict'; -/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error - * found when Flow v0.54 was deployed. To see the error delete this comment and - * run Flow. */ -const keyMirror = require('fbjs/lib/keyMirror'); +'use strict'; /** - * ImageResizeMode - Enum for different image resizing modes, set via - * `resizeMode` style property on `` components. + * ImageResizeMode defines valid values for different image resizing modes set + * via the `resizeMode` style property on ``. */ -const ImageResizeMode = keyMirror({ - /** - * contain - The image will be resized such that it will be completely - * visible, contained within the frame of the View. - */ - contain: null, - /** - * cover - The image will be resized such that the entire area of the view - * is covered by the image, potentially clipping parts of the image. - */ - cover: null, - /** - * stretch - The image will be stretched to fill the entire frame of the - * view without clipping. This may change the aspect ratio of the image, - * distorting it. - */ - stretch: null, - /** - * center - The image will be scaled down such that it is completely visible, - * if bigger than the area of the view. - * The image will not be scaled up. - */ - center: null, +export type ImageResizeMode = + // Resize by scaling down such that it is completely visible, if bigger than + // the area of the view. The image will not be scaled up. + | 'center' + + // Resize such that it will be completely visible, contained within the frame + // of the View. + | 'contain' + + // Resize such that the entire area of the view is covered by the image, + // potentially clipping parts of the image. + | 'cover' - /** - * repeat - The image will be repeated to cover the frame of the View. The - * image will keep it's size and aspect ratio. - */ - repeat: null, -}); + // Resize by repeating to cover the frame of the View. The image will keep its + // size and aspect ratio. + | 'repeat' -module.exports = ImageResizeMode; + // Resize by stretching it to fill the entire frame of the view without + // clipping. This may change the aspect ratio of the image, distorting it. + | 'stretch'; diff --git a/Libraries/Image/ImageStylePropTypes.js b/Libraries/Image/ImageStylePropTypes.js index 20088ace1abfb7..be1d08201ab7d2 100644 --- a/Libraries/Image/ImageStylePropTypes.js +++ b/Libraries/Image/ImageStylePropTypes.js @@ -10,7 +10,6 @@ 'use strict'; const DeprecatedColorPropType = require('DeprecatedColorPropType'); -const ImageResizeMode = require('ImageResizeMode'); const LayoutPropTypes = require('LayoutPropTypes'); const ReactPropTypes = require('prop-types'); const DeprecatedShadowPropTypesIOS = require('DeprecatedShadowPropTypesIOS'); @@ -20,7 +19,13 @@ const ImageStylePropTypes = { ...LayoutPropTypes, ...DeprecatedShadowPropTypesIOS, ...DeprecatedTransformPropTypes, - resizeMode: ReactPropTypes.oneOf(Object.keys(ImageResizeMode)), + resizeMode: ReactPropTypes.oneOf([ + 'center', + 'contain', + 'cover', + 'repeat', + 'stretch', + ]), backfaceVisibility: ReactPropTypes.oneOf(['visible', 'hidden']), backgroundColor: DeprecatedColorPropType, borderColor: DeprecatedColorPropType, From e873809222468e04ceb79a74e52c79ce447d9052 Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Fri, 28 Sep 2018 00:48:07 -0700 Subject: [PATCH 004/112] RN: Remove Prop Types from `LayoutAnimation` Summary: Removes the prop types from `LayoutAnimation` and refines the Flow types. This also disables `LayoutAnimation.checkConfig` with a `console.error`. Reviewed By: bvaughn Differential Revision: D10057234 fbshipit-source-id: a386f3d7dd5deafa1d4681d1f49821821fda9a6a --- Libraries/LayoutAnimation/LayoutAnimation.js | 143 ++++++++----------- 1 file changed, 57 insertions(+), 86 deletions(-) diff --git a/Libraries/LayoutAnimation/LayoutAnimation.js b/Libraries/LayoutAnimation/LayoutAnimation.js index 8e69693cc7bbe1..6f0fed1c0690d2 100644 --- a/Libraries/LayoutAnimation/LayoutAnimation.js +++ b/Libraries/LayoutAnimation/LayoutAnimation.js @@ -7,121 +7,79 @@ * @flow * @format */ + 'use strict'; -const PropTypes = require('prop-types'); const UIManager = require('UIManager'); -/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error - * found when Flow v0.54 was deployed. To see the error delete this comment and - * run Flow. */ -const keyMirror = require('fbjs/lib/keyMirror'); - -const {checkPropTypes} = PropTypes; - -const TypesEnum = { - spring: true, - linear: true, - easeInEaseOut: true, - easeIn: true, - easeOut: true, - keyboard: true, -}; -const Types = keyMirror(TypesEnum); - -const PropertiesEnum = { - opacity: true, - scaleX: true, - scaleY: true, - scaleXY: true, -}; -const Properties = keyMirror(PropertiesEnum); +type Type = + | 'spring' + | 'linear' + | 'easeInEaseOut' + | 'easeIn' + | 'easeOut' + | 'keyboard'; -const animType = PropTypes.shape({ - duration: PropTypes.number, - delay: PropTypes.number, - springDamping: PropTypes.number, - initialVelocity: PropTypes.number, - type: PropTypes.oneOf(Object.keys(Types)).isRequired, - property: PropTypes.oneOf( - // Only applies to create/delete - Object.keys(Properties), - ), -}); +type Property = 'opacity' | 'scaleX' | 'scaleY' | 'scaleXY'; -type Anim = { +type AnimationConfig = $ReadOnly<{| duration?: number, delay?: number, springDamping?: number, initialVelocity?: number, - type?: $Enum, - property?: $Enum, -}; - -const configType = PropTypes.shape({ - duration: PropTypes.number.isRequired, - create: animType, - update: animType, - delete: animType, -}); + type?: Type, + property?: Property, +|}>; -type Config = { +type LayoutAnimationConfig = $ReadOnly<{| duration: number, - create?: Anim, - update?: Anim, - delete?: Anim, -}; + create?: AnimationConfig, + update?: AnimationConfig, + delete?: AnimationConfig, +|}>; -function checkConfig(config: Config, location: string, name: string) { - checkPropTypes({config: configType}, {config}, location, name); -} - -function configureNext(config: Config, onAnimationDidEnd?: Function) { - if (__DEV__) { - checkConfig(config, 'config', 'LayoutAnimation.configureNext'); - } +function configureNext( + config: LayoutAnimationConfig, + onAnimationDidEnd?: Function, +) { UIManager.configureNextLayoutAnimation( config, - onAnimationDidEnd || function() {}, + onAnimationDidEnd ?? function() {}, function() { /* unused */ }, ); } -function create(duration: number, type, creationProp): Config { +function create( + duration: number, + type: Type, + property: Property, +): LayoutAnimationConfig { return { duration, - create: { - type, - property: creationProp, - }, - update: { - type, - }, - delete: { - type, - property: creationProp, - }, + create: {type, property}, + update: {type}, + delete: {type, property}, }; } const Presets = { - easeInEaseOut: create(300, Types.easeInEaseOut, Properties.opacity), - linear: create(500, Types.linear, Properties.opacity), + easeInEaseOut: create(300, 'easeInEaseOut', 'opacity'), + linear: create(500, 'linear', 'opacity'), spring: { duration: 700, create: { - type: Types.linear, - property: Properties.opacity, + type: 'linear', + property: 'opacity', }, update: { - type: Types.spring, + type: 'spring', springDamping: 0.4, }, delete: { - type: Types.linear, - property: Properties.opacity, + type: 'linear', + property: 'opacity', }, }, }; @@ -143,9 +101,8 @@ const LayoutAnimation = { * @param config Specifies animation properties: * * - `duration` in milliseconds - * - `create`, config for animating in new views (see `Anim` type) - * - `update`, config for animating views that have been updated - * (see `Anim` type) + * - `create`, `AnimationConfig` for animating in new views + * - `update`, `AnimationConfig` for animating views that have been updated * * @param onAnimationDidEnd Called when the animation finished. * Only supported on iOS. @@ -156,9 +113,23 @@ const LayoutAnimation = { * Helper for creating a config for `configureNext`. */ create, - Types, - Properties, - checkConfig, + Types: Object.freeze({ + spring: 'spring', + linear: 'linear', + easeInEaseOut: 'easeInEaseOut', + easeIn: 'easeIn', + easeOut: 'easeOut', + keyboard: 'keyboard', + }), + Properties: Object.freeze({ + opacity: 'opacity', + scaleX: 'scaleX', + scaleY: 'scaleY', + scaleXY: 'scaleXY', + }), + checkConfig(...args: Array) { + console.error('LayoutAnimation.checkConfig(...) has been disabled.'); + }, Presets, easeInEaseOut: configureNext.bind(null, Presets.easeInEaseOut), linear: configureNext.bind(null, Presets.linear), From 199c918dbe86fa8ac3b4e2ccb8ef57731252dd71 Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Fri, 28 Sep 2018 00:48:09 -0700 Subject: [PATCH 005/112] RN: Fix `ReactNativeViewAttributes` Type Bugs Summary: Fixes the runtime value of `ReactNativeStyleAttributes` to correctly map to `true` instead of strings (as returned by `keyMirror`). Reviewed By: TheSavior Differential Revision: D10057235 fbshipit-source-id: dc855cff3a114761098ed5176b2e6e25412481dc --- .../View/ReactNativeStyleAttributes.js | 20 +++++++++---------- .../View/ReactNativeViewAttributes.js | 2 +- Libraries/Renderer/shims/ReactNativeTypes.js | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Libraries/Components/View/ReactNativeStyleAttributes.js b/Libraries/Components/View/ReactNativeStyleAttributes.js index 93ea3a35bc83c6..46c821f6675141 100644 --- a/Libraries/Components/View/ReactNativeStyleAttributes.js +++ b/Libraries/Components/View/ReactNativeStyleAttributes.js @@ -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. * - * @format + * @format strict-local * @flow */ @@ -14,19 +14,19 @@ const ImageStylePropTypes = require('ImageStylePropTypes'); const TextStylePropTypes = require('TextStylePropTypes'); const ViewStylePropTypes = require('ViewStylePropTypes'); -/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error - * found when Flow v0.54 was deployed. To see the error delete this comment and - * run Flow. */ -const keyMirror = require('fbjs/lib/keyMirror'); const processColor = require('processColor'); const processTransform = require('processTransform'); const sizesDiffer = require('sizesDiffer'); -const ReactNativeStyleAttributes = { - ...keyMirror(ViewStylePropTypes), - ...keyMirror(TextStylePropTypes), - ...keyMirror(ImageStylePropTypes), -}; +const ReactNativeStyleAttributes = {}; + +for (const attributeName of Object.keys({ + ...ViewStylePropTypes, + ...TextStylePropTypes, + ...ImageStylePropTypes, +})) { + ReactNativeStyleAttributes[attributeName] = true; +} ReactNativeStyleAttributes.transform = {process: processTransform}; ReactNativeStyleAttributes.shadowOffset = {diff: sizesDiffer}; diff --git a/Libraries/Components/View/ReactNativeViewAttributes.js b/Libraries/Components/View/ReactNativeViewAttributes.js index c1639e13631691..5b4ab1c6c2c5fa 100644 --- a/Libraries/Components/View/ReactNativeViewAttributes.js +++ b/Libraries/Components/View/ReactNativeViewAttributes.js @@ -4,8 +4,8 @@ * 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 - * @flow strict */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index 8daf4fe7f86f7a..f9058abc1e939a 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -36,8 +36,8 @@ export type MeasureLayoutOnSuccessCallback = ( type AttributeType = | true | $ReadOnly<{| - diff: ?(arg1: T, arg2: T) => boolean, - process: ?(arg1: any) => any, + diff?: (arg1: T, arg2: T) => boolean, + process?: (arg1: any) => any, |}>; export type AttributeConfiguration< From ae4be91cac1bc5036689bdcc84669b3ec16a25c0 Mon Sep 17 00:00:00 2001 From: Spencer Ahrens Date: Fri, 28 Sep 2018 09:03:50 -0700 Subject: [PATCH 006/112] fix broken animation tests Summary: UIAnimationDragCoefficient is 10.0 in tests for some reason, but we need it to be 1.0 for our tests. Reviewed By: PeteTheHeat Differential Revision: D10096375 fbshipit-source-id: 9acd042a3d87a9c6a253745fe48145f0442f6567 --- Libraries/NativeAnimation/RCTAnimationUtils.m | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Libraries/NativeAnimation/RCTAnimationUtils.m b/Libraries/NativeAnimation/RCTAnimationUtils.m index 7ffb4690d2197b..bd4b2c33e249ce 100644 --- a/Libraries/NativeAnimation/RCTAnimationUtils.m +++ b/Libraries/NativeAnimation/RCTAnimationUtils.m @@ -102,7 +102,13 @@ CGFloat RCTDegreesToRadians(CGFloat degrees) CGFloat RCTAnimationDragCoefficient() { #if TARGET_IPHONE_SIMULATOR - return (CGFloat)UIAnimationDragCoefficient(); + if (NSClassFromString(@"XCTest") != nil) { + // UIAnimationDragCoefficient is 10.0 in tests for some reason, but + // we need it to be 1.0. Fixes T34233294 + return 1.0; + } else { + return (CGFloat)UIAnimationDragCoefficient(); + } #else return 1.0; #endif From 02ad56f5419675572d684c3cc8a28644f29afffa Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Fri, 28 Sep 2018 09:25:39 -0700 Subject: [PATCH 007/112] Expose a getter for overflow setting in ReactViewGroup (#21398) Summary: This change adds getter for overflow attribute in ReactViewGroup class. Overflow setting can affect how view children are drawn but also how hit testing behaves when receiving touch. Exposing this setting makes it possible for gesture-handler library to implement proper hit testing that takes into account overflow property of a view. Pull Request resolved: https://github.com/facebook/react-native/pull/21398 Differential Revision: D10105398 Pulled By: shergin fbshipit-source-id: 15ae2b31be3bf80e7e1d28b87ce4474af0f486f5 --- .../java/com/facebook/react/views/view/ReactViewGroup.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index d6a0c1e80add99..246db3459f9071 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -644,6 +644,10 @@ public void setOverflow(String overflow) { invalidate(); } + public @Nullable String getOverflow() { + return mOverflow; + } + /** * Set the background for the view or remove the background. It calls {@link * #setBackground(Drawable)} or {@link #setBackgroundDrawable(Drawable)} based on the sdk version. From e3b61f53bd0bfa425420e0dca0c4a78010117b6c Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Fri, 28 Sep 2018 10:24:38 -0700 Subject: [PATCH 008/112] Fabric: Debug Pretty-printing is now debug only feature Summary: That should save us some app size kilobytes. Reviewed By: mdvacca Differential Revision: D10081499 fbshipit-source-id: 2b950768c609b412f9be332c22b6b1e96657e5ea --- .../attributedstring/AttributedString.cpp | 2 ++ .../attributedstring/AttributedString.h | 2 ++ .../attributedstring/ParagraphAttributes.cpp | 2 ++ .../attributedstring/ParagraphAttributes.h | 2 ++ .../attributedstring/TextAttributes.cpp | 2 ++ .../fabric/attributedstring/TextAttributes.h | 2 ++ .../components/image/ImageLocalData.cpp | 2 ++ .../fabric/components/image/ImageLocalData.h | 2 ++ .../scrollview/ScrollViewLocalData.cpp | 2 ++ .../scrollview/ScrollViewLocalData.h | 2 ++ .../components/scrollview/ScrollViewProps.cpp | 2 ++ .../components/scrollview/ScrollViewProps.h | 2 ++ .../text/basetext/BaseTextProps.cpp | 2 ++ .../components/text/basetext/BaseTextProps.h | 2 ++ .../text/paragraph/ParagraphLocalData.cpp | 2 ++ .../text/paragraph/ParagraphLocalData.h | 2 ++ .../text/paragraph/ParagraphProps.cpp | 2 ++ .../text/paragraph/ParagraphProps.h | 3 ++- .../components/text/rawtext/RawTextProps.cpp | 2 ++ .../components/text/rawtext/RawTextProps.h | 2 ++ .../fabric/components/text/text/TextProps.cpp | 2 ++ .../fabric/components/text/text/TextProps.h | 2 ++ .../components/view/ConcreteViewShadowNode.h | 3 ++- .../fabric/components/view/ViewProps.cpp | 2 ++ .../fabric/components/view/ViewProps.h | 2 ++ .../view/yoga/YogaStylableProps.cpp | 2 ++ .../components/view/yoga/YogaStylableProps.h | 2 ++ .../core/layout/LayoutableShadowNode.cpp | 2 ++ .../fabric/core/layout/LayoutableShadowNode.h | 2 ++ .../fabric/core/shadownode/LocalData.h | 10 +++++---- ReactCommon/fabric/core/shadownode/Props.h | 6 +++-- .../fabric/core/shadownode/ShadowNode.cpp | 2 ++ .../fabric/core/shadownode/ShadowNode.h | 4 ++++ .../fabric/debug/DebugStringConvertible.cpp | 4 ++++ .../fabric/debug/DebugStringConvertible.h | 13 ++++++++++- .../debug/DebugStringConvertibleItem.cpp | 4 ++++ .../fabric/debug/DebugStringConvertibleItem.h | 4 ++++ .../debug/debugStringConvertibleUtils.h | 4 ++++ .../fabric/uimanager/FabricUIManager.cpp | 22 ------------------- 39 files changed, 102 insertions(+), 31 deletions(-) diff --git a/ReactCommon/fabric/attributedstring/AttributedString.cpp b/ReactCommon/fabric/attributedstring/AttributedString.cpp index 196b52983f6bcd..7ad102a557594a 100644 --- a/ReactCommon/fabric/attributedstring/AttributedString.cpp +++ b/ReactCommon/fabric/attributedstring/AttributedString.cpp @@ -81,6 +81,7 @@ bool AttributedString::operator!=(const AttributedString &rhs) const { #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList AttributedString::getDebugChildren() const { auto list = SharedDebugStringConvertibleList {}; @@ -103,6 +104,7 @@ SharedDebugStringConvertibleList AttributedString::getDebugChildren() const { return list; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/attributedstring/AttributedString.h b/ReactCommon/fabric/attributedstring/AttributedString.h index ecd6289f6bcfb3..447001adbc58d9 100644 --- a/ReactCommon/fabric/attributedstring/AttributedString.h +++ b/ReactCommon/fabric/attributedstring/AttributedString.h @@ -77,7 +77,9 @@ class AttributedString: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugChildren() const override; +#endif private: diff --git a/ReactCommon/fabric/attributedstring/ParagraphAttributes.cpp b/ReactCommon/fabric/attributedstring/ParagraphAttributes.cpp index 13ed8f4aa58646..cdd130b276d915 100644 --- a/ReactCommon/fabric/attributedstring/ParagraphAttributes.cpp +++ b/ReactCommon/fabric/attributedstring/ParagraphAttributes.cpp @@ -16,6 +16,7 @@ namespace react { #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList ParagraphAttributes::getDebugProps() const { return { debugStringConvertibleItem("maximumNumberOfLines", maximumNumberOfLines), @@ -25,6 +26,7 @@ SharedDebugStringConvertibleList ParagraphAttributes::getDebugProps() const { debugStringConvertibleItem("maximumFontSize", maximumFontSize) }; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/attributedstring/ParagraphAttributes.h b/ReactCommon/fabric/attributedstring/ParagraphAttributes.h index 160ce1767c4da0..f5e4ef8d8e8375 100644 --- a/ReactCommon/fabric/attributedstring/ParagraphAttributes.h +++ b/ReactCommon/fabric/attributedstring/ParagraphAttributes.h @@ -58,7 +58,9 @@ class ParagraphAttributes: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const override; +#endif }; } // namespace react diff --git a/ReactCommon/fabric/attributedstring/TextAttributes.cpp b/ReactCommon/fabric/attributedstring/TextAttributes.cpp index 8ce27505c1fb7f..313a79e778224b 100644 --- a/ReactCommon/fabric/attributedstring/TextAttributes.cpp +++ b/ReactCommon/fabric/attributedstring/TextAttributes.cpp @@ -115,6 +115,7 @@ bool TextAttributes::operator!=(const TextAttributes &rhs) const { #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList TextAttributes::getDebugProps() const { return { // Color @@ -153,6 +154,7 @@ SharedDebugStringConvertibleList TextAttributes::getDebugProps() const { debugStringConvertibleItem("layoutDirection", layoutDirection), }; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/attributedstring/TextAttributes.h b/ReactCommon/fabric/attributedstring/TextAttributes.h index d14d1f0bc5141e..8ba767fc30edda 100644 --- a/ReactCommon/fabric/attributedstring/TextAttributes.h +++ b/ReactCommon/fabric/attributedstring/TextAttributes.h @@ -78,7 +78,9 @@ class TextAttributes: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const override; +#endif }; } // namespace react diff --git a/ReactCommon/fabric/components/image/ImageLocalData.cpp b/ReactCommon/fabric/components/image/ImageLocalData.cpp index e5247b5d6e748f..c1f1a5525c32a4 100644 --- a/ReactCommon/fabric/components/image/ImageLocalData.cpp +++ b/ReactCommon/fabric/components/image/ImageLocalData.cpp @@ -23,6 +23,7 @@ const ImageRequest &ImageLocalData::getImageRequest() const { #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE std::string ImageLocalData::getDebugName() const { return "ImageLocalData"; } @@ -32,6 +33,7 @@ SharedDebugStringConvertibleList ImageLocalData::getDebugProps() const { debugStringConvertibleItem("imageSource", imageSource_) }; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/image/ImageLocalData.h b/ReactCommon/fabric/components/image/ImageLocalData.h index b453d1e1b49581..ec50e5f35e6d24 100644 --- a/ReactCommon/fabric/components/image/ImageLocalData.h +++ b/ReactCommon/fabric/components/image/ImageLocalData.h @@ -44,8 +44,10 @@ class ImageLocalData: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE std::string getDebugName() const override; SharedDebugStringConvertibleList getDebugProps() const override; +#endif private: diff --git a/ReactCommon/fabric/components/scrollview/ScrollViewLocalData.cpp b/ReactCommon/fabric/components/scrollview/ScrollViewLocalData.cpp index 66329efed7d6a2..b600d1afc5c8bd 100644 --- a/ReactCommon/fabric/components/scrollview/ScrollViewLocalData.cpp +++ b/ReactCommon/fabric/components/scrollview/ScrollViewLocalData.cpp @@ -22,6 +22,7 @@ Size ScrollViewLocalData::getContentSize() const { #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE std::string ScrollViewLocalData::getDebugName() const { return "ScrollViewLocalData"; } @@ -31,6 +32,7 @@ SharedDebugStringConvertibleList ScrollViewLocalData::getDebugProps() const { debugStringConvertibleItem("contentBoundingRect", contentBoundingRect) }; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/scrollview/ScrollViewLocalData.h b/ReactCommon/fabric/components/scrollview/ScrollViewLocalData.h index 9edb597dd8e41a..e02d7b250d6cb0 100644 --- a/ReactCommon/fabric/components/scrollview/ScrollViewLocalData.h +++ b/ReactCommon/fabric/components/scrollview/ScrollViewLocalData.h @@ -38,8 +38,10 @@ class ScrollViewLocalData: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE std::string getDebugName() const override; SharedDebugStringConvertibleList getDebugProps() const override; +#endif }; } // namespace react diff --git a/ReactCommon/fabric/components/scrollview/ScrollViewProps.cpp b/ReactCommon/fabric/components/scrollview/ScrollViewProps.cpp index b5228d7e365524..b44ae2704c2940 100644 --- a/ReactCommon/fabric/components/scrollview/ScrollViewProps.cpp +++ b/ReactCommon/fabric/components/scrollview/ScrollViewProps.cpp @@ -46,6 +46,7 @@ ScrollViewProps::ScrollViewProps(const ScrollViewProps &sourceProps, const RawPr #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList ScrollViewProps::getDebugProps() const { auto defaultScrollViewProps = ScrollViewProps {}; @@ -79,6 +80,7 @@ SharedDebugStringConvertibleList ScrollViewProps::getDebugProps() const { debugStringConvertibleItem("snapToAlignment", snapToAlignment, defaultScrollViewProps.snapToAlignment), }; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/scrollview/ScrollViewProps.h b/ReactCommon/fabric/components/scrollview/ScrollViewProps.h index 0334fe3483d07c..c046315b71a882 100644 --- a/ReactCommon/fabric/components/scrollview/ScrollViewProps.h +++ b/ReactCommon/fabric/components/scrollview/ScrollViewProps.h @@ -51,7 +51,9 @@ class ScrollViewProps final: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const override; +#endif }; } // namespace react diff --git a/ReactCommon/fabric/components/text/basetext/BaseTextProps.cpp b/ReactCommon/fabric/components/text/basetext/BaseTextProps.cpp index 41c644f92240e9..c54363337cb5c3 100644 --- a/ReactCommon/fabric/components/text/basetext/BaseTextProps.cpp +++ b/ReactCommon/fabric/components/text/basetext/BaseTextProps.cpp @@ -60,9 +60,11 @@ BaseTextProps::BaseTextProps(const BaseTextProps &sourceProps, const RawProps &r #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList BaseTextProps::getDebugProps() const { return textAttributes.getDebugProps(); } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/text/basetext/BaseTextProps.h b/ReactCommon/fabric/components/text/basetext/BaseTextProps.h index a24aaa5dc2a1ba..0751c0cbce9c9b 100644 --- a/ReactCommon/fabric/components/text/basetext/BaseTextProps.h +++ b/ReactCommon/fabric/components/text/basetext/BaseTextProps.h @@ -31,7 +31,9 @@ class BaseTextProps { #pragma mark - DebugStringConvertible (partially) +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const; +#endif }; } // namespace react diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.cpp b/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.cpp index 69f5cdcbcef620..f80630c2529d93 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.cpp +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.cpp @@ -37,6 +37,7 @@ folly::dynamic ParagraphLocalData::getDynamic() const { #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE std::string ParagraphLocalData::getDebugName() const { return "ParagraphLocalData"; } @@ -46,6 +47,7 @@ SharedDebugStringConvertibleList ParagraphLocalData::getDebugProps() const { debugStringConvertibleItem("attributedString", attributedString_, "") }; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.h b/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.h index b24f53d55f2222..3ca3180c86aaf6 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.h +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphLocalData.h @@ -45,8 +45,10 @@ class ParagraphLocalData: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE std::string getDebugName() const override; SharedDebugStringConvertibleList getDebugProps() const override; +#endif private: diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphProps.cpp b/ReactCommon/fabric/components/text/paragraph/ParagraphProps.cpp index b6bc970041c3a2..32fc5b3e8524f4 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphProps.cpp +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphProps.cpp @@ -34,6 +34,7 @@ ParagraphProps::ParagraphProps(const ParagraphProps &sourceProps, const RawProps #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList ParagraphProps::getDebugProps() const { return ViewProps::getDebugProps() + @@ -43,6 +44,7 @@ SharedDebugStringConvertibleList ParagraphProps::getDebugProps() const { debugStringConvertibleItem("isSelectable", isSelectable) }; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphProps.h b/ReactCommon/fabric/components/text/paragraph/ParagraphProps.h index 82636f5376dc11..8258bc084179bc 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphProps.h +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphProps.h @@ -45,8 +45,9 @@ class ParagraphProps: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const override; - +#endif }; } // namespace react diff --git a/ReactCommon/fabric/components/text/rawtext/RawTextProps.cpp b/ReactCommon/fabric/components/text/rawtext/RawTextProps.cpp index ac140878efca2e..b161ee01b02b3c 100644 --- a/ReactCommon/fabric/components/text/rawtext/RawTextProps.cpp +++ b/ReactCommon/fabric/components/text/rawtext/RawTextProps.cpp @@ -19,11 +19,13 @@ RawTextProps::RawTextProps(const RawTextProps &sourceProps, const RawProps &rawP #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList RawTextProps::getDebugProps() const { return { debugStringConvertibleItem("text", text) }; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/text/rawtext/RawTextProps.h b/ReactCommon/fabric/components/text/rawtext/RawTextProps.h index a12b96f4b62ec2..0c098b9260c2ca 100644 --- a/ReactCommon/fabric/components/text/rawtext/RawTextProps.h +++ b/ReactCommon/fabric/components/text/rawtext/RawTextProps.h @@ -32,7 +32,9 @@ class RawTextProps: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const override; +#endif }; } // namespace react diff --git a/ReactCommon/fabric/components/text/text/TextProps.cpp b/ReactCommon/fabric/components/text/text/TextProps.cpp index 6a2de65aaa7136..07d68ed20fa978 100644 --- a/ReactCommon/fabric/components/text/text/TextProps.cpp +++ b/ReactCommon/fabric/components/text/text/TextProps.cpp @@ -15,9 +15,11 @@ TextProps::TextProps(const TextProps &sourceProps, const RawProps &rawProps): #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList TextProps::getDebugProps() const { return BaseTextProps::getDebugProps(); } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/text/text/TextProps.h b/ReactCommon/fabric/components/text/text/TextProps.h index 593bc4e8dd1227..86a78d5153a52a 100644 --- a/ReactCommon/fabric/components/text/text/TextProps.h +++ b/ReactCommon/fabric/components/text/text/TextProps.h @@ -26,7 +26,9 @@ class TextProps: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const override; +#endif }; } // namespace react diff --git a/ReactCommon/fabric/components/view/ConcreteViewShadowNode.h b/ReactCommon/fabric/components/view/ConcreteViewShadowNode.h index cdb373c5d6f01d..a44153b8ebdf77 100644 --- a/ReactCommon/fabric/components/view/ConcreteViewShadowNode.h +++ b/ReactCommon/fabric/components/view/ConcreteViewShadowNode.h @@ -115,6 +115,7 @@ class ConcreteViewShadowNode: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const override { auto list = SharedDebugStringConvertibleList {}; @@ -125,7 +126,7 @@ class ConcreteViewShadowNode: return list; } - +#endif }; } // namespace react diff --git a/ReactCommon/fabric/components/view/ViewProps.cpp b/ReactCommon/fabric/components/view/ViewProps.cpp index 41ee01e5082974..f367edfe55e3ff 100644 --- a/ReactCommon/fabric/components/view/ViewProps.cpp +++ b/ReactCommon/fabric/components/view/ViewProps.cpp @@ -65,6 +65,7 @@ BorderMetrics ViewProps::resolveBorderMetrics(bool isRTL) const { #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList ViewProps::getDebugProps() const { const auto &defaultViewProps = ViewProps(); @@ -78,6 +79,7 @@ SharedDebugStringConvertibleList ViewProps::getDebugProps() const { debugStringConvertibleItem("backgroundColor", backgroundColor, defaultViewProps.backgroundColor), }; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/view/ViewProps.h b/ReactCommon/fabric/components/view/ViewProps.h index 96183feae5e933..1027b961fa1d57 100644 --- a/ReactCommon/fabric/components/view/ViewProps.h +++ b/ReactCommon/fabric/components/view/ViewProps.h @@ -66,7 +66,9 @@ class ViewProps: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const override; +#endif }; } // namespace react diff --git a/ReactCommon/fabric/components/view/yoga/YogaStylableProps.cpp b/ReactCommon/fabric/components/view/yoga/YogaStylableProps.cpp index 8174995e09d792..1367a28e032a4e 100644 --- a/ReactCommon/fabric/components/view/yoga/YogaStylableProps.cpp +++ b/ReactCommon/fabric/components/view/yoga/YogaStylableProps.cpp @@ -27,6 +27,7 @@ YogaStylableProps::YogaStylableProps(const YogaStylableProps &sourceProps, const #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList YogaStylableProps::getDebugProps() const { auto defaultYogaStyle = YGStyle {}; return { @@ -54,6 +55,7 @@ SharedDebugStringConvertibleList YogaStylableProps::getDebugProps() const { debugStringConvertibleItem("aspectRatio", yogaStyle.aspectRatio, defaultYogaStyle.aspectRatio), }; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/view/yoga/YogaStylableProps.h b/ReactCommon/fabric/components/view/yoga/YogaStylableProps.h index fd75fc840d67f9..c581104779b499 100644 --- a/ReactCommon/fabric/components/view/yoga/YogaStylableProps.h +++ b/ReactCommon/fabric/components/view/yoga/YogaStylableProps.h @@ -33,7 +33,9 @@ class YogaStylableProps { #pragma mark - DebugStringConvertible (Partial) +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const; +#endif }; } // namespace react diff --git a/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp b/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp index 55406dc90323c0..a25ecf8741ea0a 100644 --- a/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp +++ b/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp @@ -94,6 +94,7 @@ void LayoutableShadowNode::layoutChildren(LayoutContext layoutContext) { // Default implementation does nothing. } +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList LayoutableShadowNode::getDebugProps() const { auto list = SharedDebugStringConvertibleList {}; @@ -128,6 +129,7 @@ SharedDebugStringConvertibleList LayoutableShadowNode::getDebugProps() const { return list; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/core/layout/LayoutableShadowNode.h b/ReactCommon/fabric/core/layout/LayoutableShadowNode.h index 3d25b791fb2964..516b50e6881230 100644 --- a/ReactCommon/fabric/core/layout/LayoutableShadowNode.h +++ b/ReactCommon/fabric/core/layout/LayoutableShadowNode.h @@ -108,7 +108,9 @@ class LayoutableShadowNode: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const; +#endif private: LayoutMetrics layoutMetrics_ {}; diff --git a/ReactCommon/fabric/core/shadownode/LocalData.h b/ReactCommon/fabric/core/shadownode/LocalData.h index 603ee7ef6ef5f4..71560fb77d9700 100644 --- a/ReactCommon/fabric/core/shadownode/LocalData.h +++ b/ReactCommon/fabric/core/shadownode/LocalData.h @@ -30,10 +30,12 @@ class LocalData: public Sealable, public DebugStringConvertible { - public: - virtual folly::dynamic getDynamic() const { - return folly::dynamic::object(); - }; +public: + virtual ~LocalData() = default; + + virtual folly::dynamic getDynamic() const { + return folly::dynamic::object(); + } }; } // namespace react diff --git a/ReactCommon/fabric/core/shadownode/Props.h b/ReactCommon/fabric/core/shadownode/Props.h index a25e4d0b1d22d2..f072f7a3a3398a 100644 --- a/ReactCommon/fabric/core/shadownode/Props.h +++ b/ReactCommon/fabric/core/shadownode/Props.h @@ -30,11 +30,13 @@ class Props: public: Props() = default; Props(const Props &sourceProps, const RawProps &rawProps); + virtual ~Props() = default; const std::string nativeId; - #ifdef ANDROID + +#ifdef ANDROID const RawProps rawProps; - #endif +#endif }; } // namespace react diff --git a/ReactCommon/fabric/core/shadownode/ShadowNode.cpp b/ReactCommon/fabric/core/shadownode/ShadowNode.cpp index 67ee0b1d8cd689..853cfc20cc056c 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNode.cpp +++ b/ReactCommon/fabric/core/shadownode/ShadowNode.cpp @@ -145,6 +145,7 @@ void ShadowNode::cloneChildrenIfShared() { #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE std::string ShadowNode::getDebugName() const { return getComponentName(); } @@ -173,6 +174,7 @@ SharedDebugStringConvertibleList ShadowNode::getDebugProps() const { debugStringConvertibleItem("tag", folly::to(tag_)) }; } +#endif } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/core/shadownode/ShadowNode.h b/ReactCommon/fabric/core/shadownode/ShadowNode.h index 573553292f5655..a93cd0b4321382 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNode.h +++ b/ReactCommon/fabric/core/shadownode/ShadowNode.h @@ -63,6 +63,8 @@ class ShadowNode: const ShadowNodeFragment &fragment ); + virtual ~ShadowNode() = default; + /* * Clones the shadow node using stored `cloneFunction`. */ @@ -103,10 +105,12 @@ class ShadowNode: #pragma mark - DebugStringConvertible +#if RN_DEBUG_STRING_CONVERTIBLE std::string getDebugName() const override; std::string getDebugValue() const override; SharedDebugStringConvertibleList getDebugChildren() const override; SharedDebugStringConvertibleList getDebugProps() const override; +#endif protected: Tag tag_; diff --git a/ReactCommon/fabric/debug/DebugStringConvertible.cpp b/ReactCommon/fabric/debug/DebugStringConvertible.cpp index acf416bddcd3a6..3deadc2260865c 100644 --- a/ReactCommon/fabric/debug/DebugStringConvertible.cpp +++ b/ReactCommon/fabric/debug/DebugStringConvertible.cpp @@ -10,6 +10,8 @@ namespace facebook { namespace react { +#if RN_DEBUG_STRING_CONVERTIBLE + std::string DebugStringConvertible::getDebugChildrenDescription(DebugStringConvertibleOptions options, int depth) const { if (depth >= options.maximumDepth) { return ""; @@ -86,5 +88,7 @@ SharedDebugStringConvertibleList DebugStringConvertible::getDebugProps() const { return SharedDebugStringConvertibleList(); } +#endif + } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/debug/DebugStringConvertible.h b/ReactCommon/fabric/debug/DebugStringConvertible.h index 7180b74f78e5de..dffd501986e6d5 100644 --- a/ReactCommon/fabric/debug/DebugStringConvertible.h +++ b/ReactCommon/fabric/debug/DebugStringConvertible.h @@ -14,6 +14,12 @@ namespace facebook { namespace react { +#ifndef NDEBUG +#define RN_DEBUG_STRING_CONVERTIBLE 1 +#endif + +#if RN_DEBUG_STRING_CONVERTIBLE + class DebugStringConvertible; using SharedDebugStringConvertible = std::shared_ptr; @@ -28,7 +34,6 @@ struct DebugStringConvertibleOptions { // and implements basic recursive debug string assembly algorithm. // Use this as a base class for providing a debugging textual representation // of your class. -// TODO (#26770211): Clear up the naming. class DebugStringConvertible { public: @@ -63,5 +68,11 @@ class DebugStringConvertible { virtual std::string getDebugChildrenDescription(DebugStringConvertibleOptions options = {}, int depth = 0) const; }; +#else + +class DebugStringConvertible {}; + +#endif + } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/debug/DebugStringConvertibleItem.cpp b/ReactCommon/fabric/debug/DebugStringConvertibleItem.cpp index 1bbc15002fe5c3..9b686eefbe2cbd 100644 --- a/ReactCommon/fabric/debug/DebugStringConvertibleItem.cpp +++ b/ReactCommon/fabric/debug/DebugStringConvertibleItem.cpp @@ -10,6 +10,8 @@ namespace facebook { namespace react { +#if RN_DEBUG_STRING_CONVERTIBLE + DebugStringConvertibleItem::DebugStringConvertibleItem( const std::string &name, const std::string &value, @@ -37,5 +39,7 @@ SharedDebugStringConvertibleList DebugStringConvertibleItem::getDebugChildren() return children_; } +#endif + } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/debug/DebugStringConvertibleItem.h b/ReactCommon/fabric/debug/DebugStringConvertibleItem.h index 64fdaf45edef60..6680683d3645e6 100644 --- a/ReactCommon/fabric/debug/DebugStringConvertibleItem.h +++ b/ReactCommon/fabric/debug/DebugStringConvertibleItem.h @@ -14,6 +14,8 @@ namespace facebook { namespace react { +#if RN_DEBUG_STRING_CONVERTIBLE + // Trivial implementation of `DebugStringConvertible` abstract class // with a stored output; useful for assembling `DebugStringConvertible` values // in custom implementations of `getDebugChildren` and `getDebugProps`. @@ -43,5 +45,7 @@ class DebugStringConvertibleItem: SharedDebugStringConvertibleList children_; }; +#endif + } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/debug/debugStringConvertibleUtils.h b/ReactCommon/fabric/debug/debugStringConvertibleUtils.h index 354f15a0d5697c..d82f079175ce63 100644 --- a/ReactCommon/fabric/debug/debugStringConvertibleUtils.h +++ b/ReactCommon/fabric/debug/debugStringConvertibleUtils.h @@ -20,6 +20,8 @@ namespace facebook { namespace react { +#if RN_DEBUG_STRING_CONVERTIBLE + inline std::string toString(const std::string &value) { return value; } inline std::string toString(const int &value) { return folly::to(value); } inline std::string toString(const bool &value) { return folly::to(value); } @@ -55,5 +57,7 @@ inline SharedDebugStringConvertible debugStringConvertibleItem(std::string name, return debugStringConvertibleItem(name, value.getDebugDescription(), defaultValue); } +#endif + } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/uimanager/FabricUIManager.cpp b/ReactCommon/fabric/uimanager/FabricUIManager.cpp index 6bc96f956a6a48..e24a241ee64a3c 100644 --- a/ReactCommon/fabric/uimanager/FabricUIManager.cpp +++ b/ReactCommon/fabric/uimanager/FabricUIManager.cpp @@ -21,9 +21,6 @@ namespace facebook { namespace react { -// TODO: Kill this flag and remove debug logging. -const bool isLoggingEnabled = false; - static const RawProps rawPropsFromDynamic(const folly::dynamic object) { // TODO: Convert this to something smarter, probably returning `std::iterator`. RawProps result; @@ -174,8 +171,6 @@ void FabricUIManager::stopSurface(SurfaceId surfaceId) const { } SharedShadowNode FabricUIManager::createNode(int tag, std::string viewName, int rootTag, folly::dynamic props, SharedEventTarget eventTarget) const { - isLoggingEnabled && LOG(INFO) << "FabricUIManager::createNode(tag: " << tag << ", name: " << viewName << ", rootTag: " << rootTag << ", props: " << props << ")"; - ComponentName componentName = componentNameByReactViewName(viewName); const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[componentName]; RawProps rawProps = rawPropsFromDynamic(props); @@ -188,8 +183,6 @@ SharedShadowNode FabricUIManager::createNode(int tag, std::string viewName, int .props = componentDescriptor->cloneProps(nullptr, rawProps) }); - isLoggingEnabled && LOG(INFO) << "FabricUIManager::createNode() -> " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}); - if (delegate_) { delegate_->uiManagerDidCreateShadowNode(shadowNode); } @@ -198,18 +191,15 @@ SharedShadowNode FabricUIManager::createNode(int tag, std::string viewName, int } SharedShadowNode FabricUIManager::cloneNode(const SharedShadowNode &shadowNode) const { - isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNode(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")"; const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode]; SharedShadowNode clonedShadowNode = componentDescriptor->cloneShadowNode(*shadowNode, {}); - isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNode() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}); return clonedShadowNode; } SharedShadowNode FabricUIManager::cloneNodeWithNewChildren(const SharedShadowNode &shadowNode) const { - isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildren(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")"; // Assuming semantic: Cloning with same props but empty children. const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode]; @@ -221,12 +211,10 @@ SharedShadowNode FabricUIManager::cloneNodeWithNewChildren(const SharedShadowNod } ); - isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildren() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}); return clonedShadowNode; } SharedShadowNode FabricUIManager::cloneNodeWithNewProps(const SharedShadowNode &shadowNode, folly::dynamic props) const { - isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewProps(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ", props: " << props << ")"; // Assuming semantic: Cloning with same children and specified props. const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode]; RawProps rawProps = rawPropsFromDynamic(props); @@ -239,12 +227,10 @@ SharedShadowNode FabricUIManager::cloneNodeWithNewProps(const SharedShadowNode & } ); - isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewProps() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}); return clonedShadowNode; } SharedShadowNode FabricUIManager::cloneNodeWithNewChildrenAndProps(const SharedShadowNode &shadowNode, folly::dynamic props) const { - isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildrenAndProps(shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ", props: " << props << ")"; // Assuming semantic: Cloning with empty children and specified props. const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[shadowNode]; RawProps rawProps = rawPropsFromDynamic(props); @@ -258,37 +244,29 @@ SharedShadowNode FabricUIManager::cloneNodeWithNewChildrenAndProps(const SharedS } ); - isLoggingEnabled && LOG(INFO) << "FabricUIManager::cloneNodeWithNewChildrenAndProps() -> " << clonedShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}); return clonedShadowNode; } void FabricUIManager::appendChild(const SharedShadowNode &parentShadowNode, const SharedShadowNode &childShadowNode) const { - isLoggingEnabled && LOG(INFO) << "FabricUIManager::appendChild(parentShadowNode: " << parentShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ", childShadowNode: " << childShadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")"; const SharedComponentDescriptor &componentDescriptor = (*componentDescriptorRegistry_)[parentShadowNode]; componentDescriptor->appendChild(parentShadowNode, childShadowNode); } SharedShadowNodeUnsharedList FabricUIManager::createChildSet(int rootTag) const { - isLoggingEnabled && LOG(INFO) << "FabricUIManager::createChildSet(rootTag: " << rootTag << ")"; return std::make_shared(SharedShadowNodeList({})); } void FabricUIManager::appendChildToSet(const SharedShadowNodeUnsharedList &shadowNodeList, const SharedShadowNode &shadowNode) const { - isLoggingEnabled && LOG(INFO) << "FabricUIManager::appendChildToSet(shadowNodeList: " << shadowNodeList << ", shadowNode: " << shadowNode->getDebugDescription(DebugStringConvertibleOptions {.format = false}) << ")"; shadowNodeList->push_back(shadowNode); } void FabricUIManager::completeRoot(int rootTag, const SharedShadowNodeUnsharedList &children) const { - isLoggingEnabled && LOG(INFO) << "FabricUIManager::completeRoot(rootTag: " << rootTag << ", shadowNodeList: " << children << ")"; - if (delegate_) { delegate_->uiManagerDidFinishTransaction(rootTag, children); } } void FabricUIManager::registerEventHandler(UniqueEventHandler eventHandler) const { - isLoggingEnabled && LOG(INFO) << "FabricUIManager::registerEventHandler(eventHandler: " << eventHandler.get() << ")"; - // Technically, it should be protected by a mutex but regularly it should // be safe because it used only during initialization process. eventHandler_ = std::move(eventHandler); From 6715268794095f451de380adde31c09fd09a0d4f Mon Sep 17 00:00:00 2001 From: Fred Liu Date: Fri, 28 Sep 2018 10:39:08 -0700 Subject: [PATCH 009/112] Revert D10100555: [react-native][PR] SwipeableRow: Remove PropTypes, convert to ES6 class Differential Revision: D10100555 Original commit changeset: ab350546f4fa fbshipit-source-id: 7afd51aacceac209564c06462ae60c4a12cf4815 --- .../Experimental/SwipeableRow/SwipeableRow.js | 205 ++++++++++-------- 1 file changed, 111 insertions(+), 94 deletions(-) diff --git a/Libraries/Experimental/SwipeableRow/SwipeableRow.js b/Libraries/Experimental/SwipeableRow/SwipeableRow.js index be44b3c3abffa9..fb9cc1df409090 100644 --- a/Libraries/Experimental/SwipeableRow/SwipeableRow.js +++ b/Libraries/Experimental/SwipeableRow/SwipeableRow.js @@ -16,8 +16,13 @@ const PanResponder = require('PanResponder'); const React = require('React'); const PropTypes = require('prop-types'); const StyleSheet = require('StyleSheet'); +/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error + * found when Flow v0.54 was deployed. To see the error delete this comment and + * run Flow. */ +const TimerMixin = require('react-timer-mixin'); const View = require('View'); +const createReactClass = require('create-react-class'); const emptyFunction = require('fbjs/lib/emptyFunction'); import type {LayoutEvent, PressEvent} from 'CoreEventTypes'; @@ -57,38 +62,18 @@ const RIGHT_SWIPE_THRESHOLD = 30 * SLOW_SPEED_SWIPE_FACTOR; type Props = $ReadOnly<{| children?: ?React.Node, - isOpen: boolean, - maxSwipeDistance: number, - onClose: () => mixed, - onOpen: () => mixed, - onSwipeEnd: () => mixed, - onSwipeStart: () => mixed, - preventSwipeRight: boolean, - - /** - * Should bounce the row on mount - */ + isOpen?: ?boolean, + maxSwipeDistance?: ?number, + onClose?: ?Function, + onOpen?: ?Function, + onSwipeEnd?: ?Function, + onSwipeStart?: ?Function, + preventSwipeRight?: ?boolean, shouldBounceOnMount?: ?boolean, - - /** - * A ReactElement that is unveiled when the user swipes - */ slideoutView?: ?React.Node, - - /** - * The minimum swipe distance required before fully animating the swipe. If - * the user swipes less than this distance, the item will return to its - * previous (open/close) position. - */ - swipeThreshold: number, + swipeThreshold?: ?number, |}>; -type State = {| - currentLeft: Animated.Value, - isSwipeableViewRendered: boolean, - rowHeight: ?number, -|}; - /** * Creates a swipable row that allows taps on the main item and a custom View * on the item hidden behind the row. Typically this should be used in @@ -96,44 +81,75 @@ type State = {| * used in a normal ListView. See the renderRow for SwipeableListView to see how * to use this component separately. */ -class SwipeableRow extends React.Component { - _timerID: ?TimeoutID = null; - - static defaultProps = { - isOpen: false, - preventSwipeRight: false, - maxSwipeDistance: 0, - onOpen: emptyFunction, - onClose: emptyFunction, - onSwipeEnd: emptyFunction, - onSwipeStart: emptyFunction, - swipeThreshold: 30, - }; - - state = { - currentLeft: new Animated.Value(this._previousLeft), +const SwipeableRow = createReactClass({ + displayName: 'SwipeableRow', + _panResponder: {}, + _previousLeft: CLOSED_LEFT_POSITION, + + mixins: [TimerMixin], + + propTypes: { + children: PropTypes.any, + isOpen: PropTypes.bool, + preventSwipeRight: PropTypes.bool, + maxSwipeDistance: PropTypes.number.isRequired, + onOpen: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + onSwipeEnd: PropTypes.func.isRequired, + onSwipeStart: PropTypes.func.isRequired, + // Should bounce the row on mount + shouldBounceOnMount: PropTypes.bool, + /** + * A ReactElement that is unveiled when the user swipes + */ + slideoutView: PropTypes.node.isRequired, /** - * In order to render component A beneath component B, A must be rendered - * before B. However, this will cause "flickering", aka we see A briefly - * then B. To counter this, _isSwipeableViewRendered flag is used to set - * component A to be transparent until component B is loaded. + * The minimum swipe distance required before fully animating the swipe. If + * the user swipes less than this distance, the item will return to its + * previous (open/close) position. */ - isSwipeableViewRendered: false, - rowHeight: null, - }; - - _panResponder = PanResponder.create({ - onMoveShouldSetPanResponderCapture: this - ._handleMoveShouldSetPanResponderCapture, - onPanResponderGrant: this._handlePanResponderGrant, - onPanResponderMove: this._handlePanResponderMove, - onPanResponderRelease: this._handlePanResponderEnd, - onPanResponderTerminationRequest: this._onPanResponderTerminationRequest, - onPanResponderTerminate: this._handlePanResponderEnd, - onShouldBlockNativeResponder: (event, gestureState) => false, - }); - - _previousLeft = CLOSED_LEFT_POSITION; + swipeThreshold: PropTypes.number.isRequired, + }, + + getInitialState(): Object { + return { + currentLeft: new Animated.Value(this._previousLeft), + /** + * In order to render component A beneath component B, A must be rendered + * before B. However, this will cause "flickering", aka we see A briefly + * then B. To counter this, _isSwipeableViewRendered flag is used to set + * component A to be transparent until component B is loaded. + */ + isSwipeableViewRendered: false, + rowHeight: (null: ?number), + }; + }, + + getDefaultProps(): Object { + return { + isOpen: false, + preventSwipeRight: false, + maxSwipeDistance: 0, + onOpen: emptyFunction, + onClose: emptyFunction, + onSwipeEnd: emptyFunction, + onSwipeStart: emptyFunction, + swipeThreshold: 30, + }; + }, + + UNSAFE_componentWillMount(): void { + this._panResponder = PanResponder.create({ + onMoveShouldSetPanResponderCapture: this + ._handleMoveShouldSetPanResponderCapture, + onPanResponderGrant: this._handlePanResponderGrant, + onPanResponderMove: this._handlePanResponderMove, + onPanResponderRelease: this._handlePanResponderEnd, + onPanResponderTerminationRequest: this._onPanResponderTerminationRequest, + onPanResponderTerminate: this._handlePanResponderEnd, + onShouldBlockNativeResponder: (event, gestureState) => false, + }); + }, componentDidMount(): void { if (this.props.shouldBounceOnMount) { @@ -141,17 +157,13 @@ class SwipeableRow extends React.Component { * Do the on mount bounce after a delay because if we animate when other * components are loading, the animation will be laggy */ - this._timerID = setTimeout(() => { + this.setTimeout(() => { this._animateBounceBack(ON_MOUNT_BOUNCE_DURATION); }, ON_MOUNT_BOUNCE_DELAY); } - } - - componentWillUnmount(): void { - this._timerID && clearTimeout(this._timerID); - } + }, - UNSAFE_componentWillReceiveProps(nextProps: Props): void { + UNSAFE_componentWillReceiveProps(nextProps: Object): void { /** * We do not need an "animateOpen(noCallback)" because this animation is * handled internally by this component. @@ -159,9 +171,9 @@ class SwipeableRow extends React.Component { if (this.props.isOpen && !nextProps.isOpen) { this._animateToClosedPosition(); } - } + }, - render(): React.Node { + render(): React.Element { // The view hidden behind the main view let slideOutView; if (this.state.isSwipeableViewRendered && this.state.rowHeight) { @@ -188,19 +200,19 @@ class SwipeableRow extends React.Component { {swipeableView} ); - } + }, close(): void { this.props.onClose(); this._animateToClosedPosition(); - } + }, _onSwipeableViewLayout(event: LayoutEvent): void { this.setState({ isSwipeableViewRendered: true, rowHeight: event.nativeEvent.layout.height, }); - } + }, _handleMoveShouldSetPanResponderCapture( event: PressEvent, @@ -208,12 +220,12 @@ class SwipeableRow extends React.Component { ): boolean { // Decides whether a swipe is responded to by this component or its child return gestureState.dy < 10 && this._isValidSwipe(gestureState); - } + }, _handlePanResponderGrant( event: PressEvent, gestureState: GestureState, - ): void {} + ): void {}, _handlePanResponderMove(event: PressEvent, gestureState: GestureState): void { if (this._isSwipingExcessivelyRightFromClosedPosition(gestureState)) { @@ -227,22 +239,22 @@ class SwipeableRow extends React.Component { } else { this._swipeFullSpeed(gestureState); } - } + }, _isSwipingRightFromClosed(gestureState: GestureState): boolean { const gestureStateDx = IS_RTL ? -gestureState.dx : gestureState.dx; return this._previousLeft === CLOSED_LEFT_POSITION && gestureStateDx > 0; - } + }, _swipeFullSpeed(gestureState: GestureState): void { this.state.currentLeft.setValue(this._previousLeft + gestureState.dx); - } + }, _swipeSlowSpeed(gestureState: GestureState): void { this.state.currentLeft.setValue( this._previousLeft + gestureState.dx / SLOW_SPEED_SWIPE_FACTOR, ); - } + }, _isSwipingExcessivelyRightFromClosedPosition( gestureState: GestureState, @@ -257,14 +269,14 @@ class SwipeableRow extends React.Component { this._isSwipingRightFromClosed(gestureState) && gestureStateDx > RIGHT_SWIPE_THRESHOLD ); - } + }, _onPanResponderTerminationRequest( event: PressEvent, gestureState: GestureState, ): boolean { return false; - } + }, _animateTo( toValue: number, @@ -279,14 +291,14 @@ class SwipeableRow extends React.Component { this._previousLeft = toValue; callback(); }); - } + }, _animateToOpenPosition(): void { const maxSwipeDistance = IS_RTL ? -this.props.maxSwipeDistance : this.props.maxSwipeDistance; this._animateTo(-maxSwipeDistance); - } + }, _animateToOpenPositionWith(speed: number, distMoved: number): void { /** @@ -308,15 +320,15 @@ class SwipeableRow extends React.Component { ? -this.props.maxSwipeDistance : this.props.maxSwipeDistance; this._animateTo(-maxSwipeDistance, duration); - } + }, _animateToClosedPosition(duration: number = SWIPE_DURATION): void { this._animateTo(CLOSED_LEFT_POSITION, duration); - } + }, _animateToClosedPositionDuringBounce(): void { this._animateToClosedPosition(RIGHT_SWIPE_BOUNCE_BACK_DURATION); - } + }, _animateBounceBack(duration: number): void { /** @@ -331,7 +343,7 @@ class SwipeableRow extends React.Component { duration, this._animateToClosedPositionDuringBounce, ); - } + }, // Ignore swipes due to user's finger moving slightly when tapping _isValidSwipe(gestureState: GestureState): boolean { @@ -344,7 +356,7 @@ class SwipeableRow extends React.Component { } return Math.abs(gestureState.dx) > HORIZONTAL_SWIPE_DISTANCE_THRESHOLD; - } + }, _shouldAnimateRemainder(gestureState: GestureState): boolean { /** @@ -355,7 +367,7 @@ class SwipeableRow extends React.Component { Math.abs(gestureState.dx) > this.props.swipeThreshold || gestureState.vx > HORIZONTAL_FULL_SWIPE_SPEED_THRESHOLD ); - } + }, _handlePanResponderEnd(event: PressEvent, gestureState: GestureState): void { const horizontalDistance = IS_RTL ? -gestureState.dx : gestureState.dx; @@ -381,7 +393,12 @@ class SwipeableRow extends React.Component { } this.props.onSwipeEnd(); - } + }, +}); + +// TODO: Delete this when `SwipeableRow` uses class syntax. +class TypedSwipeableRow extends React.Component { + close() {} } const styles = StyleSheet.create({ @@ -394,4 +411,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = SwipeableRow; +module.exports = ((SwipeableRow: any): Class); From 97f0e43710a990c30e14d66bf67c7d612377d3f2 Mon Sep 17 00:00:00 2001 From: Timothy Kukulski Date: Fri, 28 Sep 2018 12:51:29 -0700 Subject: [PATCH 010/112] allow zero offset when shadow radius is nonzero Summary: update creation logic for text shadow: allow shadows with zero offset when the radius is nonzero (?should we also add a check to drop the node as a no-op when color.alpha == 0 ?) Reviewed By: yungsters Differential Revision: D10017778 fbshipit-source-id: 0168ac6db5ad22a5d7eb32dcd184aede361d6651 --- .../facebook/react/views/text/ReactBaseTextShadowNode.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java index b2772a60b6fcb0..6e6d2cfef8441b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java @@ -6,6 +6,7 @@ */ package com.facebook.react.views.text; +import android.graphics.Color; import android.graphics.Typeface; import android.os.Build; import android.text.Layout; @@ -150,7 +151,10 @@ private static void buildSpannedFromShadowNode( if (textShadowNode.mIsLineThroughTextDecorationSet) { ops.add(new SetSpanOperation(start, end, new StrikethroughSpan())); } - if (textShadowNode.mTextShadowOffsetDx != 0 || textShadowNode.mTextShadowOffsetDy != 0) { + if ((textShadowNode.mTextShadowOffsetDx != 0 + || textShadowNode.mTextShadowOffsetDy != 0 + || textShadowNode.mTextShadowRadius != 0) + && Color.alpha(textShadowNode.mTextShadowColor) != 0) { ops.add( new SetSpanOperation( start, From 9edf63534eb78d2de748539cf190f9877498a8aa Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Fri, 28 Sep 2018 14:46:28 -0700 Subject: [PATCH 011/112] Fabric: Using YGNodeLayoutGet* family functions to access Yoga layout Summary: ... instead of using direction access to `ygNode.getLayout()` object. Suddenly, YGLayout object that YGNode exposes contains unresolved/directional-unaware styles. To get resolved directional-aware styles we have to use functions from Yoga.h. I am not happy with this solution, I will try to implement something like `ygNode.getResolvedLayout()` and use that instead. This change fixes strange missing horizontal padding around some views. Reviewed By: mdvacca Differential Revision: D10112049 fbshipit-source-id: 4b6ef39d8dd34e78a4592962e8af4eeaa5028768 --- .../fabric/components/view/conversions.h | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/ReactCommon/fabric/components/view/conversions.h b/ReactCommon/fabric/components/view/conversions.h index dbd60e912136e4..7d8ea01d7e33ff 100644 --- a/ReactCommon/fabric/components/view/conversions.h +++ b/ReactCommon/fabric/components/view/conversions.h @@ -73,38 +73,37 @@ inline folly::Optional optionalFloatFromYogaValue(const YGValue &value, f inline LayoutMetrics layoutMetricsFromYogaNode(YGNode &yogaNode) { auto layoutMetrics = LayoutMetrics {}; - auto layout = yogaNode.getLayout(); layoutMetrics.frame = Rect { Point { - floatFromYogaFloat(layout.position[YGEdgeLeft]), - floatFromYogaFloat(layout.position[YGEdgeTop]) + floatFromYogaFloat(YGNodeLayoutGetLeft(&yogaNode)), + floatFromYogaFloat(YGNodeLayoutGetTop(&yogaNode)) }, Size { - floatFromYogaFloat(layout.dimensions[YGDimensionWidth]), - floatFromYogaFloat(layout.dimensions[YGDimensionHeight]) + floatFromYogaFloat(YGNodeLayoutGetWidth(&yogaNode)), + floatFromYogaFloat(YGNodeLayoutGetHeight(&yogaNode)) } }; layoutMetrics.borderWidth = EdgeInsets { - floatFromYogaFloat(layout.border[YGEdgeLeft]), - floatFromYogaFloat(layout.border[YGEdgeTop]), - floatFromYogaFloat(layout.border[YGEdgeRight]), - floatFromYogaFloat(layout.border[YGEdgeBottom]) + floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeLeft)), + floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeTop)), + floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeRight)), + floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeBottom)) }; layoutMetrics.contentInsets = EdgeInsets { - floatFromYogaFloat(layout.border[YGEdgeLeft] + layout.padding[YGEdgeLeft]), - floatFromYogaFloat(layout.border[YGEdgeTop] + layout.padding[YGEdgeTop]), - floatFromYogaFloat(layout.border[YGEdgeRight] + layout.padding[YGEdgeRight]), - floatFromYogaFloat(layout.border[YGEdgeBottom] + layout.padding[YGEdgeBottom]) + layoutMetrics.borderWidth.left + floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeLeft)), + layoutMetrics.borderWidth.top + floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeTop)), + layoutMetrics.borderWidth.right + floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeRight)), + layoutMetrics.borderWidth.bottom + floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeBottom)) }; layoutMetrics.displayType = yogaNode.getStyle().display == YGDisplayNone ? DisplayType::None : DisplayType::Flex; layoutMetrics.layoutDirection = - layout.direction == YGDirectionRTL ? LayoutDirection::RightToLeft : LayoutDirection::LeftToRight; + YGNodeLayoutGetDirection(&yogaNode) == YGDirectionRTL ? LayoutDirection::RightToLeft : LayoutDirection::LeftToRight; return layoutMetrics; } From 5ce2c0144b70270762cc991593f45bb89a731efa Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Fri, 28 Sep 2018 14:46:29 -0700 Subject: [PATCH 012/112] Fabric: Fixed a bug in LayoutMetrics::operator== Summary: Trivial. We missed `pointScaleFactor`. Reviewed By: mdvacca Differential Revision: D10112051 fbshipit-source-id: 980b8c310fbb3701008765509dce5b6e61852c0e --- ReactCommon/fabric/core/layout/LayoutMetrics.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ReactCommon/fabric/core/layout/LayoutMetrics.h b/ReactCommon/fabric/core/layout/LayoutMetrics.h index 6d4b9891942991..9e519221c2335f 100644 --- a/ReactCommon/fabric/core/layout/LayoutMetrics.h +++ b/ReactCommon/fabric/core/layout/LayoutMetrics.h @@ -31,13 +31,13 @@ struct LayoutMetrics { }; } - bool operator ==(const LayoutMetrics& rhs) const { + bool operator==(const LayoutMetrics &rhs) const { return - std::tie(this->frame, this->contentInsets, this->borderWidth, this->displayType, this->layoutDirection) == - std::tie(rhs.frame, rhs.contentInsets, rhs.borderWidth, rhs.displayType, rhs.layoutDirection); + std::tie(this->frame, this->contentInsets, this->borderWidth, this->displayType, this->layoutDirection, this->pointScaleFactor) == + std::tie(rhs.frame, rhs.contentInsets, rhs.borderWidth, rhs.displayType, rhs.layoutDirection, this->pointScaleFactor); } - bool operator !=(const LayoutMetrics& rhs) const { + bool operator!=(const LayoutMetrics &rhs) const { return !(*this == rhs); } }; From e082a613245b654d1f90e1ac9e4a429331d1b755 Mon Sep 17 00:00:00 2001 From: "Andrew Chen (Eng)" Date: Fri, 28 Sep 2018 14:50:37 -0700 Subject: [PATCH 013/112] Revert D9930713: Avoid view manager class loads Differential Revision: D9930713 Original commit changeset: 4aa013f8398d fbshipit-source-id: 1fed02b41fa9d91f54d1a19f710bdb666701a4a0 --- Libraries/ReactNative/UIManager.js | 34 +--------- Libraries/ReactNative/UIManagerProperties.js | 67 ------------------- .../getNativeComponentAttributes.js | 2 +- .../java/com/facebook/react/uimanager/BUCK | 2 +- .../UIManagerModuleConstantsHelper.java | 7 +- 5 files changed, 5 insertions(+), 107 deletions(-) delete mode 100644 Libraries/ReactNative/UIManagerProperties.js diff --git a/Libraries/ReactNative/UIManager.js b/Libraries/ReactNative/UIManager.js index ddc06f3437cbac..c93563011981d2 100644 --- a/Libraries/ReactNative/UIManager.js +++ b/Libraries/ReactNative/UIManager.js @@ -11,13 +11,11 @@ const NativeModules = require('NativeModules'); const Platform = require('Platform'); -const UIManagerProperties = require('UIManagerProperties'); const defineLazyObjectProperty = require('defineLazyObjectProperty'); const invariant = require('fbjs/lib/invariant'); const {UIManager} = NativeModules; -const viewManagerConfigs = {}; invariant( UIManager, @@ -38,20 +36,7 @@ UIManager.takeSnapshot = function() { ); }; UIManager.getViewManagerConfig = function(viewManagerName: string) { - if ( - viewManagerConfigs[viewManagerName] === undefined && - UIManager.getConstantsForViewManager - ) { - try { - viewManagerConfigs[ - viewManagerName - ] = UIManager.getConstantsForViewManager(viewManagerName); - } catch (e) { - viewManagerConfigs[viewManagerName] = null; - } - } - - return viewManagerConfigs[viewManagerName]; + return UIManager[viewManagerName]; }; /** @@ -63,7 +48,6 @@ if (Platform.OS === 'ios') { Object.keys(UIManager).forEach(viewName => { const viewConfig = UIManager[viewName]; if (viewConfig.Manager) { - viewManagerConfigs[viewName] = viewConfig; defineLazyObjectProperty(viewConfig, 'Constants', { get: () => { const viewManager = NativeModules[viewConfig.Manager]; @@ -123,20 +107,4 @@ if (Platform.OS === 'ios') { if (global.__makePartial) global.__makePartial(UIManager); } -if (__DEV__) { - Object.keys(UIManager).forEach(viewManagerName => { - if (!UIManagerProperties.includes(viewManagerName)) { - defineLazyObjectProperty(UIManager, viewManagerName, { - get: () => { - console.warn( - `Accessing view manager configs directly off UIManager via UIManager['${viewManagerName}'] ` + - `is no longer supported. Use UIManager.getViewManager('${viewManagerName}') instead.`, - ); - return UIManager.getViewManagerConfig(viewManagerName); - }, - }); - } - }); -} - module.exports = UIManager; diff --git a/Libraries/ReactNative/UIManagerProperties.js b/Libraries/ReactNative/UIManagerProperties.js deleted file mode 100644 index a579b604717649..00000000000000 --- a/Libraries/ReactNative/UIManagerProperties.js +++ /dev/null @@ -1,67 +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 strict-local - * @format - */ -'use strict'; - -/** - * The list of non-ViewManager related UIManager properties. - * - * In an effort to improve startup performance by lazily loading view managers, - * the interface to access view managers will change from - * UIManager['viewManagerName'] to UIManager.getViewManager('viewManagerName'). - * By using a function call instead of a property access, the UIManager will - * be able to initialize and load the required view manager from native - * synchronously. All of React Native's core components have been updated to - * use getViewManager(). For the next few releases, any usage of - * UIManager['viewManagerName'] will result in a warning. Because React Native - * does not support Proxy objects, a view manager access is implied if any of - * UIManager's properties that are not one of the properties below is being - * accessed. Once UIManager property accesses for view managers has been fully - * deprecated, this file will also be removed. - */ -module.exports = [ - 'clearJSResponder', - 'configureNextLayoutAnimation', - 'createView', - 'dismissPopupMenu', - 'dispatchViewManagerCommand', - 'findSubviewIn', - 'getConstantsForViewManager', - 'getDefaultEventTypes', - 'manageChildren', - 'measure', - 'measureInWindow', - 'measureLayout', - 'measureLayoutRelativeToParent', - 'playTouchSound', - 'removeRootView', - 'removeSubviewsFromContainerWithID', - 'replaceExistingNonRootView', - 'sendAccessibilityEvent', - 'setChildren', - 'setJSResponder', - 'setLayoutAnimationEnabledExperimental', - 'showPopupMenu', - 'updateView', - 'viewIsDescendantOf', - 'PopupMenu', - 'LazyViewManagersEnabled', - 'ViewManagerNames', - 'StyleConstants', - 'AccessibilityEventTypes', - 'UIView', - '__takeSnapshot', - 'takeSnapshot', - 'getViewManagerConfig', - 'measureViewsInRect', - 'blur', - 'focus', - 'genericBubblingEventTypes', - 'genericDirectEventTypes', -]; diff --git a/Libraries/ReactNative/getNativeComponentAttributes.js b/Libraries/ReactNative/getNativeComponentAttributes.js index 6a8c5491404c40..64771945f93995 100644 --- a/Libraries/ReactNative/getNativeComponentAttributes.js +++ b/Libraries/ReactNative/getNativeComponentAttributes.js @@ -96,7 +96,7 @@ function attachDefaultEventTypes(viewConfig: any) { // This is supported on UIManager platforms (ex: Android), // as lazy view managers are not implemented for all platforms. // See [UIManager] for details on constants and implementations. - if (UIManager.ViewManagerNames || UIManager.LazyViewManagersEnabled) { + if (UIManager.ViewManagerNames) { // Lazy view managers enabled. viewConfig = merge(viewConfig, UIManager.getDefaultEventTypes()); } else { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BUCK b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BUCK index 9bb553e2e9aefe..262d60c93307fa 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BUCK @@ -30,7 +30,7 @@ rn_android_library( react_native_target("java/com/facebook/react/animation:animation"), react_native_target("java/com/facebook/react/bridge:bridge"), react_native_target("java/com/facebook/react/common:common"), - react_native_target("java/com/facebook/react/config:config"), + react_native_target("java/com/facebook/react/common:common"), react_native_target("java/com/facebook/react/module/annotations:annotations"), react_native_target("java/com/facebook/react/modules/core:core"), react_native_target("java/com/facebook/react/modules/i18nmanager:i18nmanager"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java index 8e993c1935cfe5..a6aed93436e973 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstantsHelper.java @@ -10,7 +10,7 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE; import com.facebook.react.common.MapBuilder; -import com.facebook.react.config.ReactFeatureFlags; +import com.facebook.systrace.Systrace; import com.facebook.systrace.SystraceMessage; import java.util.List; import java.util.Map; @@ -35,10 +35,7 @@ /* package */ static Map createConstants( UIManagerModule.ViewManagerResolver resolver) { Map constants = UIManagerModuleConstants.getConstants(); - if (!ReactFeatureFlags.lazilyLoadViewManagers) { - constants.put("ViewManagerNames", resolver.getViewManagerNames()); - } - constants.put("LazyViewManagersEnabled", true); + constants.put("ViewManagerNames", resolver.getViewManagerNames()); return constants; } From af181fb192c83e1dd0575c24e38d8814bbf187d6 Mon Sep 17 00:00:00 2001 From: Artur Chrusciel Date: Fri, 28 Sep 2018 15:33:11 -0700 Subject: [PATCH 014/112] Check if child view != null before dropping (#20465) Summary: Fixes our top crash when framework try drop a view from parent, but it's a null (already removed etc.). Fixes #20288 Pull Request resolved: https://github.com/facebook/react-native/pull/20465 Differential Revision: D10113976 Pulled By: hramos fbshipit-source-id: 34f5654f3bdbc63eb7f7d0b5c94885576fc3cdcd --- .../facebook/react/uimanager/NativeViewHierarchyManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java index 3e6993518ada0a..430f2478a2b2e1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -570,7 +570,9 @@ protected synchronized void dropView(View view) { ViewGroupManager viewGroupManager = (ViewGroupManager) viewManager; for (int i = viewGroupManager.getChildCount(viewGroup) - 1; i >= 0; i--) { View child = viewGroupManager.getChildAt(viewGroup, i); - if (mTagsToViews.get(child.getId()) != null) { + if (child == null) { + FLog.e(TAG, "Unable to drop null child view"); + } else if (mTagsToViews.get(child.getId()) != null) { dropView(child); } } From ea53727e16223d412fcbba49df79cc68b39f5d93 Mon Sep 17 00:00:00 2001 From: chenwenyu Date: Fri, 28 Sep 2018 16:00:35 -0700 Subject: [PATCH 015/112] Android: fix cookies lost on Android 5.0 and above (#19770) Summary: This fixes cookie missing bug on Android 5.0 and above. On Android 5.0 and above, after the app successfully obtains the cookie, you kills the App within 30 seconds and restarts the App. It accesses the interface that needs to carry the cookie and finds that the cookie does not exist. Updated tests for the addCookies function to include test cases specifying Android version, and tested on the command line in my app to make sure it has the expected behavior. Updated tests for the addCookies function to include test cases specifying Android version, and tested on the command line in my app to make sure it has the expected behavior. [ANDROID] [BUGFIX] [Cookie] - Fix cookies lost on Android 5.0 and above Pull Request resolved: https://github.com/facebook/react-native/pull/19770 Differential Revision: D10114102 Pulled By: hramos fbshipit-source-id: 5b4766f02f70541fd46ac5db36f1179fe386ac7a --- .../facebook/react/modules/network/ForwardingCookieHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/network/ForwardingCookieHandler.java b/ReactAndroid/src/main/java/com/facebook/react/modules/network/ForwardingCookieHandler.java index 4c1c413cbd899b..222a7ce463652c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/network/ForwardingCookieHandler.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/network/ForwardingCookieHandler.java @@ -129,6 +129,7 @@ public void run() { for (String cookie : cookies) { addCookieAsync(url, cookie); } + getCookieManager().flush(); mCookieSaver.onCookiesModified(); } } From 53b487d215eac5f31e8b59ba34238159c233efc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Fri, 28 Sep 2018 17:00:18 -0700 Subject: [PATCH 016/112] Use ShellCheck (#19681) Summary: As recommended in https://circleci.com/docs/2.0/using-shell-scripts/#use-shellcheck It will only run on PRs for now. Pull Request resolved: https://github.com/facebook/react-native/pull/19681 Differential Revision: D10111711 Pulled By: hramos fbshipit-source-id: e980a526561dced79e5197a11cfb41a3eba9be8b --- .circleci/config.yml | 17 ++- ...un-android-docker-instrumentation-tests.sh | 5 +- .../scripts/run-android-docker-unit-tests.sh | 2 +- ContainerShip/scripts/run-ci-e2e-tests.sh | 9 +- ...run-instrumentation-tests-via-adb-shell.sh | 10 +- scripts/circleci/analyze_scripts.sh | 19 +++ scripts/circleci/code-analysis-bot.js | 143 ++++++++++-------- scripts/test-manual-e2e.sh | 6 +- scripts/validate-android-device-env.sh | 5 +- 9 files changed, 130 insertions(+), 86 deletions(-) create mode 100755 scripts/circleci/analyze_scripts.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 1b28b421da2391..0cd278c13aa381 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -585,9 +585,23 @@ jobs: - checkout - run: *setup-artifacts - - restore-cache: *restore-yarn-cache + - restore-cache: *restore-cache-analysis - run: *yarn + - run: + name: Analyze Shell Scripts + command: | + if [ -n "$CIRCLE_PR_NUMBER" ]; then + echo -e "\\x1B[36mInstalling additional dependencies\\x1B[0m" + sudo apt-get install -y shellcheck + yarn add @octokit/rest@15.10.0 + echo -e "\\x1B[36mAnalyzing shell scripts\\x1B[0m" + GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" ./scripts/circleci/analyze_scripts.sh + else + echo "Skipping shell script analysis." + fi + when: always + - run: name: Analyze Code command: | @@ -599,7 +613,6 @@ jobs: fi when: always - - restore-cache: *restore-cache-analysis - run: name: Analyze Pull Request command: | diff --git a/ContainerShip/scripts/run-android-docker-instrumentation-tests.sh b/ContainerShip/scripts/run-android-docker-instrumentation-tests.sh index ed7183dec9d5fc..e2c320d7e61afe 100644 --- a/ContainerShip/scripts/run-android-docker-instrumentation-tests.sh +++ b/ContainerShip/scripts/run-android-docker-instrumentation-tests.sh @@ -6,7 +6,7 @@ mount -o remount,exec /dev/shm AVD_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1) # create virtual device -echo no | android create avd -n $AVD_UUID -f -t android-19 --abi default/armeabi-v7a +echo no | android create avd -n "$AVD_UUID" -f -t android-19 --abi default/armeabi-v7a # emulator setup emulator64-arm -avd $AVD_UUID -no-skin -no-audio -no-window -no-boot-anim & @@ -28,8 +28,9 @@ watchman shutdown-server node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js # build test APK +# shellcheck disable=SC1091 source ./scripts/android-setup.sh && NO_BUCKD=1 retry3 buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=1 # run installed apk with tests -node ./ContainerShip/scripts/run-android-ci-instrumentation-tests.js $* +node ./ContainerShip/scripts/run-android-ci-instrumentation-tests.js "$*" exit $? diff --git a/ContainerShip/scripts/run-android-docker-unit-tests.sh b/ContainerShip/scripts/run-android-docker-unit-tests.sh index 5a58bb352e5421..1a422c25bf1b17 100644 --- a/ContainerShip/scripts/run-android-docker-unit-tests.sh +++ b/ContainerShip/scripts/run-android-docker-unit-tests.sh @@ -9,4 +9,4 @@ mount -o remount,exec /dev/shm set -x # run unit tests -buck test ReactAndroid/src/test/... --config build.threads=$UNIT_TESTS_BUILD_THREADS +buck test ReactAndroid/src/test/... --config build.threads="$UNIT_TESTS_BUILD_THREADS" diff --git a/ContainerShip/scripts/run-ci-e2e-tests.sh b/ContainerShip/scripts/run-ci-e2e-tests.sh index 73296e5325c622..be916439735dfd 100755 --- a/ContainerShip/scripts/run-ci-e2e-tests.sh +++ b/ContainerShip/scripts/run-ci-e2e-tests.sh @@ -128,6 +128,7 @@ function e2e_suite() { emulator64-arm -avd "$AVD_UUID" -no-skin -no-audio -no-window -no-boot-anim & bootanim="" + # shellcheck disable=SC2076 until [[ "$bootanim" =~ "stopped" ]]; do sleep 5 bootanim=$(adb -e shell getprop init.svc.bootanim 2>&1) @@ -210,15 +211,15 @@ function e2e_suite() { fi # kill packager process - if kill -0 $SERVER_PID; then + if kill -0 "$SERVER_PID"; then echo "Killing packager $SERVER_PID" - kill -9 $SERVER_PID + kill -9 "$SERVER_PID" fi # kill appium process - if kill -0 $APPIUM_PID; then + if kill -0 "$APPIUM_PID"; then echo "Killing appium $APPIUM_PID" - kill -9 $APPIUM_PID + kill -9 "$APPIUM_PID" fi fi diff --git a/ContainerShip/scripts/run-instrumentation-tests-via-adb-shell.sh b/ContainerShip/scripts/run-instrumentation-tests-via-adb-shell.sh index 5a9a976a97da4e..72b011ca9c3c8b 100755 --- a/ContainerShip/scripts/run-instrumentation-tests-via-adb-shell.sh +++ b/ContainerShip/scripts/run-instrumentation-tests-via-adb-shell.sh @@ -1,5 +1,5 @@ #!/bin/bash - +# shellcheck disable=SC1117 # Python script to run instrumentation tests, copied from https://github.com/circleci/circle-dummy-android # Example: ./scripts/run-android-instrumentation-tests.sh com.facebook.react.tests com.facebook.react.tests.ReactPickerTestCase # @@ -9,7 +9,7 @@ export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$PATH" adb logcat -c # run tests and check output -python - $1 $2 << END +python - "$1" "$2" << END import re import subprocess as sp @@ -24,7 +24,7 @@ test_class = None if len(sys.argv) > 2: test_class = sys.argv[2] - + def update(): # prevent CircleCI from killing the process for inactivity while not done: @@ -38,10 +38,10 @@ t.start() def run(): sp.Popen(['adb', 'wait-for-device']).communicate() if (test_class != None): - p = sp.Popen('adb shell am instrument -w -e class %s %s/android.support.test.runner.AndroidJUnitRunner' + p = sp.Popen('adb shell am instrument -w -e class %s %s/android.support.test.runner.AndroidJUnitRunner' % (test_class, test_app), shell=True, stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE) else : - p = sp.Popen('adb shell am instrument -w %s/android.support.test.runner.AndroidJUnitRunner' + p = sp.Popen('adb shell am instrument -w %s/android.support.test.runner.AndroidJUnitRunner' % (test_app), shell=True, stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE) return p.communicate() diff --git a/scripts/circleci/analyze_scripts.sh b/scripts/circleci/analyze_scripts.sh new file mode 100755 index 00000000000000..556caa6d606df0 --- /dev/null +++ b/scripts/circleci/analyze_scripts.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# 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. + +IFS=$'\n' + +results=( "$(find . -type f -not -path "*node_modules*" -not -path "*third-party*" -name '*.sh' -exec sh -c 'shellcheck "$1" -f json' -- {} \;)" ) + +cat <(echo shellcheck; printf '%s\n' "${results[@]}" | jq .,[] | jq -s . | jq --compact-output --raw-output '[ (.[] | .[] | . ) ]') | node bots/code-analysis-bot.js + +# check status +STATUS=$? +if [ $STATUS == 0 ]; then + echo "Shell scripts analyzed successfully" +else + echo "Shell script analysis failed, error status $STATUS" +fi diff --git a/scripts/circleci/code-analysis-bot.js b/scripts/circleci/code-analysis-bot.js index 837dce2ded78aa..0e5a3d5be70aa2 100644 --- a/scripts/circleci/code-analysis-bot.js +++ b/scripts/circleci/code-analysis-bot.js @@ -17,27 +17,11 @@ if (!process.env.CIRCLE_PROJECT_REPONAME) { console.error('Missing CIRCLE_PROJECT_REPONAME. Example: react-native'); process.exit(1); } -if (!process.env.GITHUB_TOKEN) { - console.error( - 'Missing GITHUB_TOKEN. Example: 5fd88b964fa214c4be2b144dc5af5d486a2f8c1e', - ); - process.exit(1); -} -if (!process.env.CIRCLE_PR_NUMBER) { - console.error('Missing CIRCLE_PR_NUMBER. Example: 4687'); - // for master branch, don't throw an error - process.exit(0); -} // https://octokit.github.io/rest.js/ const octokit = require('@octokit/rest')(); -var path = require('path'); - -octokit.authenticate({ - type: 'oauth', - token: process.env.GITHUB_TOKEN, -}); +const path = require('path'); function push(arr, key, value) { if (!arr[key]) { @@ -58,9 +42,9 @@ function push(arr, key, value) { * This is an object where the keys are the path of the files and values * is an array of objects of the shape message and line. */ -var converters = { +const converters = { raw: function(output, input) { - for (var key in input) { + for (let key in input) { input[key].forEach(function(message) { push(output, key, message); }); @@ -76,6 +60,7 @@ var converters = { push(output, error.message[0].path, { message: error.message.map(message => message.descr).join(' '), line: error.message[0].line, + converter: 'flow', }); }); }, @@ -90,10 +75,36 @@ var converters = { push(output, file.filePath, { message: message.ruleId + ': ' + message.message, line: message.line, + converter: 'eslint', }); }); }); }, + + shellcheck: function(output, input) { + if (!input) { + return; + } + + input.forEach(function(report) { + push(output, report.file, { + message: + '**[SC' + + report.code + + '](https://github.com/koalaman/shellcheck/wiki/SC' + + report.code + + '):** (' + + report.level + + ') ' + + report.message, + line: report.line, + endLine: report.endLine, + column: report.column, + endColumn: report.endColumn, + converter: 'shellcheck', + }); + }); + }, }; function getShaFromPullRequest(owner, repo, number, callback) { @@ -129,9 +140,9 @@ function getFilesFromCommit(owner, repo, sha, callback) { * in the patch file */ function getLineMapFromPatch(patchString) { - var diffLineIndex = 0; - var fileLineIndex = 0; - var lineMap = {}; + let diffLineIndex = 0; + let fileLineIndex = 0; + let lineMap = {}; patchString.split('\n').forEach(line => { if (line.match(/^@@/)) { @@ -151,14 +162,17 @@ function getLineMapFromPatch(patchString) { return lineMap; } -function sendReview(owner, repo, number, commit_id, comments) { +function sendReview(owner, repo, number, commit_id, comments, convertersUsed) { if (comments.length === 0) { // Do not leave an empty review. return; } - const body = - '`eslint` found some issues. You may run `yarn prettier` or `npm run prettier` to fix these.'; + let body = '**Code analysis results:**\n\n'; + convertersUsed.forEach(converter => { + body += '* `' + converter + '` found some issues.\n'; + }); + const event = 'REQUEST_CHANGES'; const opts = { @@ -179,71 +193,59 @@ function sendReview(owner, repo, number, commit_id, comments) { }); } -function sendComment(owner, repo, number, sha, filename, lineMap, message) { - if (!lineMap[message.line]) { - // Do not send messages on lines that did not change - return; - } - - var opts = { - owner, - repo, - number, - sha, - commit_id: sha, - path: filename, - position: lineMap[message.line], - body: message.message, - }; - octokit.pullRequests.createComment(opts, function(error, res) { - if (error) { - console.error(error); - return; - } - }); - console.log('Sending comment', opts); -} - function main(messages, owner, repo, number) { // No message, we don't need to do anything :) if (Object.keys(messages).length === 0) { return; } + if (!process.env.GITHUB_TOKEN) { + console.error( + 'Missing GITHUB_TOKEN. Example: 5fd88b964fa214c4be2b144dc5af5d486a2f8c1e', + ); + process.exit(1); + } + + octokit.authenticate({ + type: 'oauth', + token: process.env.GITHUB_TOKEN, + }); + getShaFromPullRequest(owner, repo, number, sha => { getFilesFromCommit(owner, repo, sha, files => { - var comments = []; + let comments = []; + let convertersUsed = []; files.filter(file => messages[file.filename]).forEach(file => { // github api sometimes does not return a patch on large commits if (!file.patch) { return; } - var lineMap = getLineMapFromPatch(file.patch); + const lineMap = getLineMapFromPatch(file.patch); messages[file.filename].forEach(message => { if (lineMap[message.line]) { - var comment = { + const comment = { path: file.filename, position: lineMap[message.line], body: message.message, }; - + convertersUsed.push(message.converter); comments.push(comment); } }); // forEach }); // filter - sendReview(owner, repo, number, sha, comments); + sendReview(owner, repo, number, sha, comments, convertersUsed); }); // getFilesFromCommit }); // getShaFromPullRequest } -var content = ''; +let content = ''; process.stdin.resume(); process.stdin.on('data', function(buf) { content += buf.toString(); }); process.stdin.on('end', function() { - var messages = {}; + let messages = {}; // Since we send a few http requests to setup the process, we don't want // to run this file one time per code analysis tool. Instead, we write all @@ -259,13 +261,13 @@ process.stdin.on('end', function() { // // cat <(echo eslint; npm run lint --silent -- --format=json; echo flow; flow --json) | node code-analysis-bot.js - var lines = content.trim().split('\n'); - for (var i = 0; i < Math.ceil(lines.length / 2); ++i) { - var converter = converters[lines[i * 2]]; + const lines = content.trim().split('\n'); + for (let i = 0; i < Math.ceil(lines.length / 2); ++i) { + const converter = converters[lines[i * 2]]; if (!converter) { throw new Error('Unknown converter ' + lines[i * 2]); } - var json; + let json; try { json = JSON.parse(lines[i * 2 + 1]); } catch (e) {} @@ -275,9 +277,9 @@ process.stdin.on('end', function() { // The paths are returned in absolute from code analysis tools but github works // on paths relative from the root of the project. Doing the normalization here. - var pwd = path.resolve('.'); - for (var absolutePath in messages) { - var relativePath = path.relative(pwd, absolutePath); + const pwd = path.resolve('.'); + for (let absolutePath in messages) { + const relativePath = path.relative(pwd, absolutePath); if (relativePath === absolutePath) { continue; } @@ -285,9 +287,16 @@ process.stdin.on('end', function() { delete messages[absolutePath]; } - var owner = process.env.CIRCLE_PROJECT_USERNAME; - var repo = process.env.CIRCLE_PROJECT_REPONAME; - var number = process.env.CIRCLE_PR_NUMBER; + const owner = process.env.CIRCLE_PROJECT_USERNAME; + const repo = process.env.CIRCLE_PROJECT_REPONAME; + + if (!process.env.CIRCLE_PR_NUMBER) { + console.error('Missing CIRCLE_PR_NUMBER. Example: 4687'); + // for master branch, don't throw an error + process.exit(0); + } + + const number = process.env.CIRCLE_PR_NUMBER; // intentional lint warning to make sure that the bot is working :) main(messages, owner, repo, number); diff --git a/scripts/test-manual-e2e.sh b/scripts/test-manual-e2e.sh index 09c73c0d9c5e90..ac1157df60514f 100755 --- a/scripts/test-manual-e2e.sh +++ b/scripts/test-manual-e2e.sh @@ -8,16 +8,16 @@ BLUE="\033[0;35m" ENDCOLOR="\033[0m" error() { - echo -e $RED"$@"$ENDCOLOR + echo -e "$RED""$*""$ENDCOLOR" exit 1 } success() { - echo -e $GREEN"$@"$ENDCOLOR + echo -e "$GREEN""$*""$ENDCOLOR" } info() { - echo -e $BLUE"$@"$ENDCOLOR + echo -e "$BLUE""$*""$ENDCOLOR" } PACKAGE_VERSION=$(cat package.json \ diff --git a/scripts/validate-android-device-env.sh b/scripts/validate-android-device-env.sh index 80cf5f642c3375..cfb51c9c58e731 100755 --- a/scripts/validate-android-device-env.sh +++ b/scripts/validate-android-device-env.sh @@ -28,8 +28,9 @@ fi while : do - BOOTANIM=`adb -e shell getprop init.svc.bootanim` - if [ -n `echo $BOOTANIM | grep stopped` ]; then + BOOTANIM=$(adb -e shell getprop init.svc.bootanim) + # shellcheck disable=SC2143 + if [[ -n $(echo "$BOOTANIM" | grep stopped) ]]; then break fi echo "Waiting for the emulator to finish booting..." From e2210ab752bd978f393dd5c6110626fff92bc6b3 Mon Sep 17 00:00:00 2001 From: Emily Janzer Date: Fri, 28 Sep 2018 17:06:57 -0700 Subject: [PATCH 017/112] Fix flow in InitializeCore Reviewed By: yungsters Differential Revision: D10115867 fbshipit-source-id: be619b9d6fc30e318cbc0e0fc6e741d80dd94a4b --- Libraries/Core/InitializeCore.js | 6 ------ Libraries/JSInspector/JSInspector.js | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Libraries/Core/InitializeCore.js b/Libraries/Core/InitializeCore.js index 5fcceab22909fb..c55163981c8e4b 100644 --- a/Libraries/Core/InitializeCore.js +++ b/Libraries/Core/InitializeCore.js @@ -91,9 +91,6 @@ polyfillGlobal('regeneratorRuntime', () => { // The require just sets up the global, so make sure when we first // invoke it the global does not exist delete global.regeneratorRuntime; - /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an - * error found when Flow v0.54 was deployed. To see the error delete this - * comment and run Flow. */ require('regenerator-runtime/runtime'); return global.regeneratorRuntime; }); @@ -214,9 +211,6 @@ if (__DEV__) { // Set up inspector const JSInspector = require('JSInspector'); - /* $FlowFixMe(>=0.56.0 site=react_native_fb,react_native_oss) This comment - * suppresses an error found when Flow v0.56 was deployed. To see the error - * delete this comment and run Flow. */ JSInspector.registerAgent(require('NetworkAgent')); } } diff --git a/Libraries/JSInspector/JSInspector.js b/Libraries/JSInspector/JSInspector.js index d66052ba05fc72..6d7a2f70037e7f 100644 --- a/Libraries/JSInspector/JSInspector.js +++ b/Libraries/JSInspector/JSInspector.js @@ -10,7 +10,7 @@ 'use strict'; -import type EventSender from 'InspectorAgent'; +import type {EventSender} from 'InspectorAgent'; interface Agent { constructor(eventSender: EventSender): void; From e28d8f6eeb9a229558e7abdc36909b07865ea2e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Fri, 28 Sep 2018 17:16:46 -0700 Subject: [PATCH 018/112] Fix copyright headers Summary: Update several files to use the proper copyright header: ``` // 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. ``` In the case of Xcode project files, I used the shortform version, `Copyright (c) Facebook, Inc. and its affiliates.` Reviewed By: axe-fb Differential Revision: D10114529 fbshipit-source-id: a1f2d5a46d04797c1cf281ea9ab80d3a2caa6fb4 --- RNTester/RNTester/Base.lproj/LaunchScreen.xib | 2 +- RNTester/RNTester/RNTesterBundle/Info.plist | 2 +- React/third-party.xcconfig | 6 ++++-- .../facebook/react/testing/rule/ReactNativeTestRule.java | 5 ++++- .../com/facebook/react/tests/core/ReactRootViewTest.java | 5 ++++- ReactAndroid/src/main/jni/react/jni/ReadableNativeArray.h | 5 ++++- .../link/__tests__/android/normalizeProjectName.spec.js | 2 -- 7 files changed, 18 insertions(+), 9 deletions(-) diff --git a/RNTester/RNTester/Base.lproj/LaunchScreen.xib b/RNTester/RNTester/Base.lproj/LaunchScreen.xib index 9a4c50e157cc14..f7722dde9ba78c 100644 --- a/RNTester/RNTester/Base.lproj/LaunchScreen.xib +++ b/RNTester/RNTester/Base.lproj/LaunchScreen.xib @@ -16,7 +16,7 @@ -