From 432865c7edefb81a07bc280dce758e4af74cd86a Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 18:05:49 +0000 Subject: [PATCH 001/149] Remove old source --- .../EventEmitter/EmitterSubscription.js | 45 - src/Libraries/EventEmitter/EventEmitter.js | 202 --- .../EventEmitter/EventSubscription.js | 31 - .../EventEmitter/EventSubscriptionVendor.js | 91 -- .../EventEmitter/NativeEventEmitter.js | 29 - .../NavigationExperimental/NavigationCard.js | 21 - .../NavigationPropTypes.js | 98 -- .../NavigationStateUtils.js | 123 -- src/Libraries/NavigationExperimental/index.js | 20 - src/Libraries/Network/FormData.js | 88 -- src/Libraries/Network/Headers.js | 54 - src/Libraries/Network/Response.js | 25 - src/Libraries/Network/XMLHttpRequest.js | 60 - src/NativeModules/ActionSheetManager.js | 11 - src/NativeModules/AlertManager.js | 10 - src/NativeModules/AppState.js | 19 - src/NativeModules/CameraRollManager.js | 13 - src/NativeModules/Clipboard.js | 16 - src/NativeModules/DatePickerAndroid.js | 8 - src/NativeModules/DeviceEventManager.js | 7 - src/NativeModules/ImagePickerIOS.js | 19 - src/NativeModules/LinkingManager.js | 15 - src/NativeModules/ScrollViewManager.js | 29 - src/NativeModules/SourceCode.js | 19 - src/NativeModules/TestModule.js | 24 - src/NativeModules/TimePickerAndroid.js | 14 - src/NativeModules/Timing.js | 13 - src/NativeModules/UIManager.js | 71 - src/NativeModules/Vibration.js | 7 - src/NativeModules/WebViewManager.js | 26 - src/NativeModules/index.js | 23 - src/api/ActionSheetIOS.js | 46 - src/api/Alert.js | 10 - src/api/AlertIOS.js | 143 -- src/api/Animated/AnimatedImplementation.js | 1182 ----------------- src/api/Animated/Easing.js | 122 -- src/api/Animated/Interpolation.js | 10 - src/api/Animated/SpringConfig.js | 80 -- src/api/Animated/createAnimatedComponent.js | 20 - src/api/Animated/index.js | 13 - src/api/AppRegistry.js | 33 - src/api/AppState.js | 55 - src/api/AppStateIOS.js | 126 -- src/api/AsyncStorage.js | 81 -- src/api/BackAndroid.js | 55 - src/api/CameraRoll.js | 107 -- src/api/DatePickerAndroid.js | 71 - src/api/Dimensions.js | 24 - src/api/ImagePickerIOS.js | 28 - src/api/IntentAndroid.js | 66 - src/api/InteractionManager.js | 69 - src/api/Keyboard.js | 12 - src/api/LayoutAnimation.js | 124 -- src/api/Linking.js | 121 -- src/api/LinkingIOS.js | 78 -- src/api/ListViewDataSource.js | 27 - src/api/NetInfo.js | 71 - src/api/PanResponder.js | 386 ------ src/api/PixelRatio.js | 23 - src/api/PushNotificationIOS.js | 231 ---- src/api/Settings.js | 68 - src/api/StatusBarIOS.js | 32 - src/api/StyleSheet.js | 17 - src/api/TextInputState.js | 39 - src/api/TimePickerAndroid.js | 54 - src/api/TouchHistoryMath.js | 118 -- src/api/VibrationIOS.js | 25 - src/components/ART/Path.js | 28 - src/components/ART/Transform.js | 28 - src/components/ART/index.js | 40 - src/components/ActivityIndicator.js | 46 - src/components/ActivityIndicatorIOS.js | 47 - src/components/DrawerLayoutAndroid.js | 115 -- src/components/Image.js | 127 -- src/components/ListView.js | 167 --- src/components/Navigator.js | 103 -- src/components/ScrollView.js | 318 ----- src/components/StatusBar.js | 72 - src/components/Text.js | 53 - src/components/TextInput.js | 249 ---- src/components/TouchableNativeFeedback.js | 22 - src/components/TouchableOpacity.js | 24 - src/components/TouchableWithoutFeedback.js | 71 - src/components/View.js | 288 ---- src/components/WebView.js | 145 -- src/components/createMockComponent.js | 12 - src/defineGlobalProperty.js | 8 - src/mixins/NativeMethodsMixin.js | 20 - src/mixins/ScrollResponder.js | 509 ------- src/mixins/Subscribable.js | 39 - src/plugins/DeviceEventEmitter.js | 5 - src/plugins/NativeAppEventEmitter.js | 5 - src/plugins/Platform.js | 27 - src/plugins/processColor.js | 6 - src/plugins/requireNativeComponent.js | 15 - src/propTypes/ColorPropType.js | 20 - src/propTypes/EdgeInsetsPropType.js | 15 - src/propTypes/ImageResizeMode.js | 13 - src/propTypes/ImageStylePropTypes.js | 52 - src/propTypes/LayoutPropTypes.js | 97 -- src/propTypes/PointPropType.js | 13 - src/propTypes/ShadowPropTypesIOS.js | 32 - src/propTypes/StyleSheetPropType.js | 22 - src/propTypes/TextStylePropTypes.js | 74 -- src/propTypes/TransformPropTypes.js | 40 - src/propTypes/ViewStylePropTypes.js | 49 - src/propTypes/flattenStyle.js | 11 - src/react-native.js | 131 -- src/requireLibrary.js | 20 - 109 files changed, 8176 deletions(-) delete mode 100644 src/Libraries/EventEmitter/EmitterSubscription.js delete mode 100644 src/Libraries/EventEmitter/EventEmitter.js delete mode 100644 src/Libraries/EventEmitter/EventSubscription.js delete mode 100644 src/Libraries/EventEmitter/EventSubscriptionVendor.js delete mode 100644 src/Libraries/EventEmitter/NativeEventEmitter.js delete mode 100644 src/Libraries/NavigationExperimental/NavigationCard.js delete mode 100644 src/Libraries/NavigationExperimental/NavigationPropTypes.js delete mode 100644 src/Libraries/NavigationExperimental/NavigationStateUtils.js delete mode 100644 src/Libraries/NavigationExperimental/index.js delete mode 100644 src/Libraries/Network/FormData.js delete mode 100644 src/Libraries/Network/Headers.js delete mode 100644 src/Libraries/Network/Response.js delete mode 100644 src/Libraries/Network/XMLHttpRequest.js delete mode 100644 src/NativeModules/ActionSheetManager.js delete mode 100644 src/NativeModules/AlertManager.js delete mode 100644 src/NativeModules/AppState.js delete mode 100644 src/NativeModules/CameraRollManager.js delete mode 100644 src/NativeModules/Clipboard.js delete mode 100644 src/NativeModules/DatePickerAndroid.js delete mode 100644 src/NativeModules/DeviceEventManager.js delete mode 100644 src/NativeModules/ImagePickerIOS.js delete mode 100644 src/NativeModules/LinkingManager.js delete mode 100644 src/NativeModules/ScrollViewManager.js delete mode 100644 src/NativeModules/SourceCode.js delete mode 100644 src/NativeModules/TestModule.js delete mode 100644 src/NativeModules/TimePickerAndroid.js delete mode 100644 src/NativeModules/Timing.js delete mode 100644 src/NativeModules/UIManager.js delete mode 100644 src/NativeModules/Vibration.js delete mode 100644 src/NativeModules/WebViewManager.js delete mode 100644 src/NativeModules/index.js delete mode 100644 src/api/ActionSheetIOS.js delete mode 100644 src/api/Alert.js delete mode 100644 src/api/AlertIOS.js delete mode 100644 src/api/Animated/AnimatedImplementation.js delete mode 100644 src/api/Animated/Easing.js delete mode 100644 src/api/Animated/Interpolation.js delete mode 100644 src/api/Animated/SpringConfig.js delete mode 100644 src/api/Animated/createAnimatedComponent.js delete mode 100644 src/api/Animated/index.js delete mode 100644 src/api/AppRegistry.js delete mode 100644 src/api/AppState.js delete mode 100644 src/api/AppStateIOS.js delete mode 100644 src/api/AsyncStorage.js delete mode 100644 src/api/BackAndroid.js delete mode 100644 src/api/CameraRoll.js delete mode 100644 src/api/DatePickerAndroid.js delete mode 100644 src/api/Dimensions.js delete mode 100644 src/api/ImagePickerIOS.js delete mode 100644 src/api/IntentAndroid.js delete mode 100644 src/api/InteractionManager.js delete mode 100644 src/api/Keyboard.js delete mode 100644 src/api/LayoutAnimation.js delete mode 100644 src/api/Linking.js delete mode 100644 src/api/LinkingIOS.js delete mode 100644 src/api/ListViewDataSource.js delete mode 100644 src/api/NetInfo.js delete mode 100644 src/api/PanResponder.js delete mode 100644 src/api/PixelRatio.js delete mode 100644 src/api/PushNotificationIOS.js delete mode 100644 src/api/Settings.js delete mode 100644 src/api/StatusBarIOS.js delete mode 100644 src/api/StyleSheet.js delete mode 100644 src/api/TextInputState.js delete mode 100644 src/api/TimePickerAndroid.js delete mode 100644 src/api/TouchHistoryMath.js delete mode 100644 src/api/VibrationIOS.js delete mode 100644 src/components/ART/Path.js delete mode 100644 src/components/ART/Transform.js delete mode 100644 src/components/ART/index.js delete mode 100644 src/components/ActivityIndicator.js delete mode 100644 src/components/ActivityIndicatorIOS.js delete mode 100644 src/components/DrawerLayoutAndroid.js delete mode 100644 src/components/Image.js delete mode 100644 src/components/ListView.js delete mode 100644 src/components/Navigator.js delete mode 100644 src/components/ScrollView.js delete mode 100644 src/components/StatusBar.js delete mode 100644 src/components/Text.js delete mode 100644 src/components/TextInput.js delete mode 100644 src/components/TouchableNativeFeedback.js delete mode 100644 src/components/TouchableOpacity.js delete mode 100644 src/components/TouchableWithoutFeedback.js delete mode 100644 src/components/View.js delete mode 100644 src/components/WebView.js delete mode 100644 src/components/createMockComponent.js delete mode 100644 src/defineGlobalProperty.js delete mode 100644 src/mixins/NativeMethodsMixin.js delete mode 100644 src/mixins/ScrollResponder.js delete mode 100644 src/mixins/Subscribable.js delete mode 100644 src/plugins/DeviceEventEmitter.js delete mode 100644 src/plugins/NativeAppEventEmitter.js delete mode 100644 src/plugins/Platform.js delete mode 100644 src/plugins/processColor.js delete mode 100644 src/plugins/requireNativeComponent.js delete mode 100644 src/propTypes/ColorPropType.js delete mode 100644 src/propTypes/EdgeInsetsPropType.js delete mode 100644 src/propTypes/ImageResizeMode.js delete mode 100644 src/propTypes/ImageStylePropTypes.js delete mode 100644 src/propTypes/LayoutPropTypes.js delete mode 100644 src/propTypes/PointPropType.js delete mode 100644 src/propTypes/ShadowPropTypesIOS.js delete mode 100644 src/propTypes/StyleSheetPropType.js delete mode 100644 src/propTypes/TextStylePropTypes.js delete mode 100644 src/propTypes/TransformPropTypes.js delete mode 100644 src/propTypes/ViewStylePropTypes.js delete mode 100644 src/propTypes/flattenStyle.js delete mode 100644 src/react-native.js delete mode 100644 src/requireLibrary.js diff --git a/src/Libraries/EventEmitter/EmitterSubscription.js b/src/Libraries/EventEmitter/EmitterSubscription.js deleted file mode 100644 index f7140e9..0000000 --- a/src/Libraries/EventEmitter/EmitterSubscription.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -const EventSubscription = require('./EventSubscription'); - -/** - * EmitterSubscription represents a subscription with listener and context data. - */ -class EmitterSubscription extends EventSubscription { - - /** - * @param {EventEmitter} emitter - The event emitter that registered this - * subscription - * @param {EventSubscriptionVendor} subscriber - The subscriber that controls - * this subscription - * @param {function} listener - Function to invoke when the specified event is - * emitted - * @param {*} context - Optional context object to use when invoking the - * listener - */ - constructor(emitter, subscriber, listener, context) { - super(subscriber); - this.emitter = emitter; - this.listener = listener; - this.context = context; - } - - /** - * Removes this subscription from the emitter that registered it. - * Note: we're overriding the `remove()` method of EventSubscription here - * but deliberately not calling `super.remove()` as the responsibility - * for removing the subscription lies with the EventEmitter. - */ - remove() { - this.emitter.removeSubscription(this); - } -} - -module.exports = EmitterSubscription; diff --git a/src/Libraries/EventEmitter/EventEmitter.js b/src/Libraries/EventEmitter/EventEmitter.js deleted file mode 100644 index 315f575..0000000 --- a/src/Libraries/EventEmitter/EventEmitter.js +++ /dev/null @@ -1,202 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -const EmitterSubscription = require('./EmitterSubscription'); -const EventSubscriptionVendor = require('./EventSubscriptionVendor'); -const invariant = require('invariant'); - -/** - * @class EventEmitter - * @description - * An EventEmitter is responsible for managing a set of listeners and publishing - * events to them when it is told that such events happened. In addition to the - * data for the given event it also sends a event control object which allows - * the listeners/handlers to prevent the default behavior of the given event. - * - * The emitter is designed to be generic enough to support all the different - * contexts in which one might want to emit events. It is a simple multicast - * mechanism on top of which extra functionality can be composed. For example, a - * more advanced emitter may use an EventHolder and EventFactory. - */ -class EventEmitter { - /** - * @constructor - * - * @param {EventSubscriptionVendor} subscriber - Optional subscriber instance - * to use. If omitted, a new subscriber will be created for the emitter. - */ - constructor(subscriber) { - this._subscriber = subscriber || new EventSubscriptionVendor(); - } - - /** - * Adds a listener to be invoked when events of the specified type are - * emitted. An optional calling context may be provided. The data arguments - * emitted will be passed to the listener function. - * - * TODO: Annotate the listener arg's type. This is tricky because listeners - * can be invoked with varargs. - * - * @param {string} eventType - Name of the event to listen to - * @param {function} listener - Function to invoke when the specified event is - * emitted - * @param {*} context - Optional context object to use when invoking the - * listener - */ - addListener(eventType, listener, context) { - return (this._subscriber.addSubscription( - eventType, - new EmitterSubscription(this, this._subscriber, listener, context) - )); - } - - /** - * Similar to addListener, except that the listener is removed after it is - * invoked once. - * - * @param {string} eventType - Name of the event to listen to - * @param {function} listener - Function to invoke only once when the - * specified event is emitted - * @param {*} context - Optional context object to use when invoking the - * listener - */ - once(eventType, listener, context) { - return this.addListener(eventType, (...args) => { - this.removeCurrentListener(); - listener.apply(context, args); - }); - } - - /** - * Removes all of the registered listeners, including those registered as - * listener maps. - * - * @param {?string} eventType - Optional name of the event whose registered - * listeners to remove - */ - removeAllListeners(eventType) { - this._subscriber.removeAllSubscriptions(eventType); - } - - /** - * Provides an API that can be called during an eventing cycle to remove the - * last listener that was invoked. This allows a developer to provide an event - * object that can remove the listener (or listener map) during the - * invocation. - * - * If it is called when not inside of an emitting cycle it will throw. - * - * @throws {Error} When called not during an eventing cycle - * - * @example - * var subscription = emitter.addListenerMap({ - * someEvent: function(data, event) { - * console.log(data); - * emitter.removeCurrentListener(); - * } - * }); - * - * emitter.emit('someEvent', 'abc'); // logs 'abc' - * emitter.emit('someEvent', 'def'); // does not log anything - */ - removeCurrentListener() { - invariant( - !!this._currentSubscription, - 'Not in an emitting cycle; there is no current subscription' - ); - this.removeSubscription(this._currentSubscription); - } - - /** - * Removes a specific subscription. Called by the `remove()` method of the - * subscription itself to ensure any necessary cleanup is performed. - */ - removeSubscription(subscription) { - invariant( - subscription.emitter === this, - 'Subscription does not belong to this emitter.' - ); - this._subscriber.removeSubscription(subscription); - } - - /** - * Returns an array of listeners that are currently registered for the given - * event. - * - * @param {string} eventType - Name of the event to query - * @returns {array} - */ - listeners(eventType) { - const subscriptions = (this._subscriber.getSubscriptionsForType(eventType)); - return subscriptions ? subscriptions.map(subscription => subscription.listener) : []; - } - - /** - * Emits an event of the given type with the given data. All handlers of that - * particular type will be notified. - * - * @param {string} eventType - Name of the event to emit - * @param {...*} Arbitrary arguments to be passed to each registered listener - * - * @example - * emitter.addListener('someEvent', function(message) { - * console.log(message); - * }); - * - * emitter.emit('someEvent', 'abc'); // logs 'abc' - */ - emit(eventType) { - const subscriptions = (this._subscriber.getSubscriptionsForType(eventType)); - if (subscriptions) { - for (let i = 0, l = subscriptions.length; i < l; i++) { - const subscription = subscriptions[i]; - - // The subscription may have been removed during this event loop. - if (subscription) { - this._currentSubscription = subscription; - subscription.listener.apply( - subscription.context, - Array.prototype.slice.call(arguments, 1) - ); - } - } - this._currentSubscription = null; - } - } - - /** - * Removes the given listener for event of specific type. - * - * @param {string} eventType - Name of the event to emit - * @param {function} listener - Function to invoke when the specified event is - * emitted - * - * @example - * emitter.removeListener('someEvent', function(message) { - * console.log(message); - * }); // removes the listener if already registered - * - */ - removeListener(eventType, listener) { - const subscriptions = (this._subscriber.getSubscriptionsForType(eventType)); - if (subscriptions) { - for (let i = 0, l = subscriptions.length; i < l; i++) { - const subscription = subscriptions[i]; - - // The subscription may have been removed during this event loop. - // its listener matches the listener in method parameters - if (subscription && subscription.listener === listener) { - subscription.remove(); - } - } - } - } -} - -module.exports = EventEmitter; diff --git a/src/Libraries/EventEmitter/EventSubscription.js b/src/Libraries/EventEmitter/EventSubscription.js deleted file mode 100644 index ea45450..0000000 --- a/src/Libraries/EventEmitter/EventSubscription.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -/** - * EventSubscription represents a subscription to a particular event. It can - * remove its own subscription. - */ -class EventSubscription { - /** - * @param {EventSubscriptionVendor} subscriber the subscriber that controls - * this subscription. - */ - constructor(subscriber) { - this.subscriber = subscriber; - } - - /** - * Removes this subscription from the subscriber that controls it. - */ - remove() { - this.subscriber.removeSubscription(this); - } -} - -module.exports = EventSubscription; diff --git a/src/Libraries/EventEmitter/EventSubscriptionVendor.js b/src/Libraries/EventEmitter/EventSubscriptionVendor.js deleted file mode 100644 index 4c18c3c..0000000 --- a/src/Libraries/EventEmitter/EventSubscriptionVendor.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -const invariant = require('invariant'); - -/** - * EventSubscriptionVendor stores a set of EventSubscriptions that are - * subscribed to a particular event type. - */ -class EventSubscriptionVendor { - - constructor() { - this._subscriptionsForType = {}; - this._currentSubscription = null; - } - - /** - * Adds a subscription keyed by an event type. - * - * @param {string} eventType - * @param {EventSubscription} subscription - */ - addSubscription(eventType, subscription) { - /* eslint-disable no-param-reassign */ - invariant( - subscription.subscriber === this, - 'The subscriber of the subscription is incorrectly set.'); - if (!this._subscriptionsForType[eventType]) { - this._subscriptionsForType[eventType] = []; - } - const key = this._subscriptionsForType[eventType].length; - this._subscriptionsForType[eventType].push(subscription); - subscription.eventType = eventType; - subscription.key = key; - return subscription; - } - - /** - * Removes a bulk set of the subscriptions. - * - * @param {?string} eventType - Optional name of the event type whose - * registered supscriptions to remove, if null remove all subscriptions. - */ - removeAllSubscriptions(eventType) { - if (eventType === undefined) { - this._subscriptionsForType = {}; - } else { - delete this._subscriptionsForType[eventType]; - } - } - - /** - * Removes a specific subscription. Instead of calling this function, call - * `subscription.remove()` directly. - * - * @param {object} subscription - */ - removeSubscription(subscription) { - const eventType = subscription.eventType; - const key = subscription.key; - - const subscriptionsForType = this._subscriptionsForType[eventType]; - if (subscriptionsForType) { - delete subscriptionsForType[key]; - } - } - - /** - * Returns the array of subscriptions that are currently registered for the - * given event type. - * - * Note: This array can be potentially sparse as subscriptions are deleted - * from it when they are removed. - * - * TODO: This returns a nullable array. wat? - * - * @param {string} eventType - * @returns {?array} - */ - getSubscriptionsForType(eventType) { - return this._subscriptionsForType[eventType]; - } -} - -module.exports = EventSubscriptionVendor; diff --git a/src/Libraries/EventEmitter/NativeEventEmitter.js b/src/Libraries/EventEmitter/NativeEventEmitter.js deleted file mode 100644 index 5fd9339..0000000 --- a/src/Libraries/EventEmitter/NativeEventEmitter.js +++ /dev/null @@ -1,29 +0,0 @@ -const invariant = require('invariant'); -const EventEmitter = require('./EventEmitter'); -const EmitterSubscription = require('./EmitterSubscription'); -const EventSubscriptionVender = require('./EventSubscriptionVendor'); - -const sharedSubscriber = new EventSubscriptionVender(); - -class NativeEventEmitter extends EventEmitter { - constructor(nativeModule) { - super(sharedSubscriber); - invariant(nativeModule, 'Native module cannot be null.'); - this._nativeModule = nativeModule; - } - - addListener(eventType, listener, context) { - return super.addListener(eventType, listener, context); - } - - removeAllListeners(eventType: string) { - invariant(eventType, 'eventType argument is required.'); - super.removeAllListeners(eventType); - } - - removeSubscription(subscription: EmitterSubscription) { - super.removeSubscription(subscription); - } -} - -module.exports = NativeEventEmitter; diff --git a/src/Libraries/NavigationExperimental/NavigationCard.js b/src/Libraries/NavigationExperimental/NavigationCard.js deleted file mode 100644 index 01563d6..0000000 --- a/src/Libraries/NavigationExperimental/NavigationCard.js +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; - -class CardStackPanResponder { -} - -class PagerPanResponder { -} - -class NavigationCard extends React.Component { - static CardStackPanResponder = CardStackPanResponder; - static CardStackStyleInterpolator = { - forHorizontal: () => ({}), - forVertical: () => ({}), - }; - static PagerPanResponder = PagerPanResponder; - static PagerStyleInterpolator = { - forHorizontal: () => ({}), - }; -} - -module.exports = NavigationCard; diff --git a/src/Libraries/NavigationExperimental/NavigationPropTypes.js b/src/Libraries/NavigationExperimental/NavigationPropTypes.js deleted file mode 100644 index 8caa73e..0000000 --- a/src/Libraries/NavigationExperimental/NavigationPropTypes.js +++ /dev/null @@ -1,98 +0,0 @@ -class Animated {} - -import React from 'react'; - -const { PropTypes } = React; - -/* NavigationAction */ -const action = PropTypes.shape({ - type: PropTypes.string.isRequired, -}); - -/* NavigationAnimatedValue */ -const animatedValue = PropTypes.instanceOf(Animated.Value); - -/* NavigationRoute */ -const navigationRoute = PropTypes.shape({ - key: PropTypes.string.isRequired, -}); - -/* navigationRoute */ -const navigationState = PropTypes.shape({ - index: PropTypes.number.isRequired, - routes: PropTypes.arrayOf(navigationRoute), -}); - -/* NavigationLayout */ -const layout = PropTypes.shape({ - height: animatedValue, - initHeight: PropTypes.number.isRequired, - initWidth: PropTypes.number.isRequired, - isMeasured: PropTypes.bool.isRequired, - width: animatedValue, -}); - -/* NavigationScene */ -const scene = PropTypes.shape({ - index: PropTypes.number.isRequired, - isStale: PropTypes.bool.isRequired, - key: PropTypes.string.isRequired, - route: navigationRoute.isRequired, -}); - -/* NavigationSceneRendererProps */ -const SceneRendererProps = { - layout: layout.isRequired, - navigationState: navigationState.isRequired, - position: animatedValue.isRequired, - progress: animatedValue.isRequired, - scene: scene.isRequired, - scenes: PropTypes.arrayOf(scene).isRequired, -}; - -const SceneRenderer = PropTypes.shape(SceneRendererProps); - -/* NavigationPanPanHandlers */ -const panHandlers = PropTypes.shape({ - onMoveShouldSetResponder: PropTypes.func.isRequired, - onMoveShouldSetResponderCapture: PropTypes.func.isRequired, - onResponderEnd: PropTypes.func.isRequired, - onResponderGrant: PropTypes.func.isRequired, - onResponderMove: PropTypes.func.isRequired, - onResponderReject: PropTypes.func.isRequired, - onResponderRelease: PropTypes.func.isRequired, - onResponderStart: PropTypes.func.isRequired, - onResponderTerminate: PropTypes.func.isRequired, - onResponderTerminationRequest: PropTypes.func.isRequired, - onStartShouldSetResponder: PropTypes.func.isRequired, - onStartShouldSetResponderCapture: PropTypes.func.isRequired, -}); - -/** - * Helper function that extracts the props needed for scene renderer. - */ -function extractSceneRendererProps(props) { - return { - layout: props.layout, - navigationState: props.navigationState, - position: props.position, - progress: props.progress, - scene: props.scene, - scenes: props.scenes, - }; -} - -module.exports = { - // helpers - extractSceneRendererProps, - - // Bundled propTypes. - SceneRendererProps, - - // propTypes - SceneRenderer, - action, - navigationState, - navigationRoute, - panHandlers, -}; diff --git a/src/Libraries/NavigationExperimental/NavigationStateUtils.js b/src/Libraries/NavigationExperimental/NavigationStateUtils.js deleted file mode 100644 index d0c2f50..0000000 --- a/src/Libraries/NavigationExperimental/NavigationStateUtils.js +++ /dev/null @@ -1,123 +0,0 @@ -function get(state, key) { - return state.routes.find(route => route.key === key) || null; -} - -function indexOf(state, key) { - return state.routes.map(route => route.key).indexOf(key); -} - -function has(state, key) { - return !!state.routes.some(route => route.key === key); -} - -function push(state, route) { - if (indexOf(state, route.key) !== -1) { - throw new Error('should not push route with duplicated key ' + route.key); - } - - const routes = [ - ...state.routes, - route, - ]; - - return { - ...state, - index: routes.length - 1, - routes, - }; -} - -function pop(state) { - if (state.index <= 0) { - return state; - } - const routes = state.routes.slice(0, -1); - return { - ...state, - index: routes.length - 1, - routes, - }; -} - -function jumpToIndex(state, index: number) { - if (index === state.index) { - return state; - } - - if (!state.routes[index]) { - throw new Error('invalid index ' + index + ' to jump to'); - } - - return { - ...state, - index, - }; -} - - -function jumpTo(state, key) { - const index = indexOf(state, key); - return jumpToIndex(state, index); -} - -function replaceAtIndex(state, index, route) { - if (!state.routes[index]) { - throw new Error('invalid index ' + index + ' for replacing route ' + route.key); - } - - if (state.routes[index] === route) { - return state; - } - - const routes = state.routes.slice(); - routes[index] = route; - - return { - ...state, - index, - routes, - }; -} - -function replaceAt(state, key, route) { - const index = indexOf(state, key); - return replaceAtIndex(state, index, route); -} - -function reset(state, routes, index = null) { - if (!routes.length && Array.isArray(routes)) { - throw new Error('invalid routes to replace'); - } - - const nextIndex = index === undefined ? routes.length - 1 : index; - - if (state.routes.length === routes.length && state.index === nextIndex) { - const compare = (route, ii) => routes[ii] === route; - if (state.routes.every(compare)) { - return state; - } - } - - if (!routes[nextIndex]) { - throw new Error('invalid index ' + nextIndex + ' to reset'); - } - - return { - ...state, - index: nextIndex, - routes, - }; -} - -module.exports = { - get, - has, - indexOf, - jumpTo, - jumpToIndex, - pop, - push, - replaceAt, - replaceAtIndex, - reset, -}; diff --git a/src/Libraries/NavigationExperimental/index.js b/src/Libraries/NavigationExperimental/index.js deleted file mode 100644 index 303cb39..0000000 --- a/src/Libraries/NavigationExperimental/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @see https://github.com/facebook/react-native/blob/master/Libraries/NavigationExperimental/NavigationExperimental.js - */ -import createMockComponent from '../../components/createMockComponent'; -import StateUtils from './NavigationStateUtils'; -import Card from './NavigationCard'; -import PropTypes from './NavigationPropTypes'; - -module.exports = { - StateUtils, - - AnimatedView: createMockComponent('NavigationAnimatedView'), - Transitioner: createMockComponent('NavigationTransitioner'), - - Card, - CardStack: createMockComponent('NavigationCardStack'), - Header: createMockComponent('NavigationHeader'), - - PropTypes, -}; diff --git a/src/Libraries/Network/FormData.js b/src/Libraries/Network/FormData.js deleted file mode 100644 index 6705ccd..0000000 --- a/src/Libraries/Network/FormData.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule FormData - * @flow - */ - -type FormDataValue = any; -type FormDataNameValuePair = [string, FormDataValue]; - -type Headers = {[name: string]: string}; -type FormDataPart = { - string: string, - headers: Headers, -} | { - uri: string, - headers: Headers, - name?: string, - type?: string, -}; - -/** - * Polyfill for XMLHttpRequest2 FormData API, allowing multipart POST requests - * with mixed data (string, native files) to be submitted via XMLHttpRequest. - * - * Example: - * - * var photo = { - * uri: uriFromCameraRoll, - * type: 'image/jpeg', - * name: 'photo.jpg', - * }; - * - * var body = new FormData(); - * body.append('authToken', 'secret'); - * body.append('photo', photo); - * body.append('title', 'A beautiful photo!'); - * - * xhr.open('POST', serverURL); - * xhr.send(body); - */ -class FormData { - _parts: Array; - - constructor() { - this._parts = []; - } - - append(key: string, value: FormDataValue) { - // The XMLHttpRequest spec doesn't specify if duplicate keys are allowed. - // MDN says that any new values should be appended to existing values. - // In any case, major browsers allow duplicate keys, so that's what we'll do - // too. They'll simply get appended as additional form data parts in the - // request body, leaving the server to deal with them. - this._parts.push([key, value]); - } - - getParts(): Array { - return this._parts.map(([name, value]) => { - const contentDisposition = 'form-data; name="' + name + '"'; - - const headers: Headers = { 'content-disposition': contentDisposition }; - - // The body part is a "blob", which in React Native just means - // an object with a `uri` attribute. Optionally, it can also - // have a `name` and `type` attribute to specify filename and - // content type (cf. web Blob interface.) - if (typeof value === 'object') { - if (typeof value.name === 'string') { - headers['content-disposition'] += '; filename="' + value.name + '"'; - } - if (typeof value.type === 'string') { - headers['content-type'] = value.type; - } - return { ...value, headers, fieldName: name }; - } - // Convert non-object values to strings as per FormData.append() spec - return { string: String(value), headers, fieldName: name }; - }); - } -} - -module.exports = FormData; diff --git a/src/Libraries/Network/Headers.js b/src/Libraries/Network/Headers.js deleted file mode 100644 index daef279..0000000 --- a/src/Libraries/Network/Headers.js +++ /dev/null @@ -1,54 +0,0 @@ -class Headers { - _headers: Object; - - constructor() { - this._headers = []; - } - - append(name: string, value: string) { - const normalName: string = name.toLowerCase(); - this._headers.push({ name: normalName, value }); - } - - delete(name: string) { - const normalName: string = name.toLowerCase(); - this._headers = this._headers.filter((pair) => pair.name !== normalName); - } - - entries() { - return this._headers.entries(); - } - - get(name: string) { - const normalName: string = name.toLowerCase(); - const header = this._headers.find((pair) => pair.name === normalName); - return header ? header.value : undefined; - } - - getAll(name: string) { - const normalName: string = name.toLowerCase(); - const headers = this._headers.filter((pair) => pair.name === normalName); - return headers.map((pair) => pair.value); - } - - has(name: string) { - const normalName: string = name.toLowerCase(); - return this.get(normalName); - } - - keys() { - return this._headers.map((pair) => pair.name); - } - - set(name: string, value: string) { - const normalName: string = name.toLowerCase(); - this.delete(normalName); - this.append(normalName, value); - } - - values() { - return this._headers.map((pair) => pair.value); - } -} - -module.exports = Headers; diff --git a/src/Libraries/Network/Response.js b/src/Libraries/Network/Response.js deleted file mode 100644 index d8390b3..0000000 --- a/src/Libraries/Network/Response.js +++ /dev/null @@ -1,25 +0,0 @@ -class Response { - _status: number; - _headers: Headers; - _body: string; - - constructor() { - this._status = 200; - this._headers = new Headers(); - this._body = ''; - } - - get status(): number { - return this._status; - } - - get headers(): Headers { - return this._headers; - } - - get body(): string { - return this._body; - } -} - -module.exports = Response; diff --git a/src/Libraries/Network/XMLHttpRequest.js b/src/Libraries/Network/XMLHttpRequest.js deleted file mode 100644 index 581edc7..0000000 --- a/src/Libraries/Network/XMLHttpRequest.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule XMLHttpRequest - * @flow - */ - -const UNSENT = 0; -const OPENED = 1; -const HEADERS_RECEIVED = 2; -const LOADING = 3; -const DONE = 4; - -class XMLHttpRequest { - static UNSENT: number = UNSENT; - static OPENED: number = OPENED; - static HEADERS_RECEIVED: number = HEADERS_RECEIVED; - static LOADING: number = LOADING; - static DONE: number = DONE; - - UNSENT: number = UNSENT; - OPENED: number = OPENED; - HEADERS_RECEIVED: number = HEADERS_RECEIVED; - LOADING: number = LOADING; - DONE: number = DONE; - - onload: ?Function; - onloadstart: ?Function; - onprogress: ?Function; - ontimeout: ?Function; - onerror: ?Function; - onloadend: ?Function; - onreadystatechange: ?Function; - - readyState: number = UNSENT; - responseHeaders: ?Object; - status: number = 0; - timeout: number = 0; - responseURL: ?string; - - upload: { - addEventListener: ?Function; - }; - - open(method: string, url: string, async: ?boolean): void { - } - - send(data: any): void { - } - - abort(): void { - } -} - -module.exports = XMLHttpRequest; diff --git a/src/NativeModules/ActionSheetManager.js b/src/NativeModules/ActionSheetManager.js deleted file mode 100644 index 24c3a2f..0000000 --- a/src/NativeModules/ActionSheetManager.js +++ /dev/null @@ -1,11 +0,0 @@ - -const ActionSheetManager = { - showActionSheetWithOptions(options, callback) { - - }, - showShareActionSheetWithOptions(options, failure, success) { - - }, -}; - -module.exports = ActionSheetManager; diff --git a/src/NativeModules/AlertManager.js b/src/NativeModules/AlertManager.js deleted file mode 100644 index 3a1ea6b..0000000 --- a/src/NativeModules/AlertManager.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/React/Modules/RCTAlertManager.m - */ -const AlertManager = { - alertWithArgs(args, callback) { - - }, -}; - -module.exports = AlertManager; diff --git a/src/NativeModules/AppState.js b/src/NativeModules/AppState.js deleted file mode 100644 index dfd705b..0000000 --- a/src/NativeModules/AppState.js +++ /dev/null @@ -1,19 +0,0 @@ -import DeviceEventEmitter from '../plugins/DeviceEventEmitter'; - -let _appState = 'active'; - -DeviceEventEmitter.on('appStateDidChange', data => { - _appState = data._appState; -}); - -const AppState = { - getCurrentAppState(callback, error) { - Promise.resolve({ _appState }).then(callback); - }, - - __setAppState(appState) { - DeviceEventEmitter.emit('appStateDidChange', { _appState: appState }); - }, -}; - -module.exports = AppState; diff --git a/src/NativeModules/CameraRollManager.js b/src/NativeModules/CameraRollManager.js deleted file mode 100644 index 9780c26..0000000 --- a/src/NativeModules/CameraRollManager.js +++ /dev/null @@ -1,13 +0,0 @@ - -const CameraRollManager = { - saveImageWithTag(imageTag) { - return Promise.resolve(['/asset/url']); - }, - getPhotos(params) { - return Promise.resolve([ - // TODO(lmr): - ]); - }, -}; - -module.exports = CameraRollManager; diff --git a/src/NativeModules/Clipboard.js b/src/NativeModules/Clipboard.js deleted file mode 100644 index ee1d8fe..0000000 --- a/src/NativeModules/Clipboard.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Components/Clipboard/Clipboard.js - */ -let _content = null; - -const Clipboard = { - getString() { - return Promise.resolve(_content); - }, - - setString(content) { - _content = content; - }, -}; - -module.exports = Clipboard; diff --git a/src/NativeModules/DatePickerAndroid.js b/src/NativeModules/DatePickerAndroid.js deleted file mode 100644 index 3b9bb67..0000000 --- a/src/NativeModules/DatePickerAndroid.js +++ /dev/null @@ -1,8 +0,0 @@ -// TODO(lmr): figure out a good way to have separate responses like "dismissed" vs "set". -const DatePickerAndroid = { - open(options) { - return Promise.resolve().then({ action: 'dismissedAction' }); - }, -}; - -module.exports = DatePickerAndroid; diff --git a/src/NativeModules/DeviceEventManager.js b/src/NativeModules/DeviceEventManager.js deleted file mode 100644 index 1b7fc91..0000000 --- a/src/NativeModules/DeviceEventManager.js +++ /dev/null @@ -1,7 +0,0 @@ -const DeviceEventManager = { - invokeDefaultBackPressHandler() { - - }, -}; - -module.exports = DeviceEventManager; diff --git a/src/NativeModules/ImagePickerIOS.js b/src/NativeModules/ImagePickerIOS.js deleted file mode 100644 index e3c5c7d..0000000 --- a/src/NativeModules/ImagePickerIOS.js +++ /dev/null @@ -1,19 +0,0 @@ -const _canRecordVideos = true; -const _canUseCamera = true; - -const ImagePickerIOS = { - canRecordVideos(callback) { - Promise.resolve(_canRecordVideos).then(callback); - }, - canUseCamera(callback) { - Promise.resolve(_canUseCamera).then(callback); - }, - openCameraDialog(config, success, cancel) { - // TODO(lmr): - }, - openSelectDialog(config, success, cancel) { - // TODO(lmr): - }, -}; - -module.exports = ImagePickerIOS; diff --git a/src/NativeModules/LinkingManager.js b/src/NativeModules/LinkingManager.js deleted file mode 100644 index 805685f..0000000 --- a/src/NativeModules/LinkingManager.js +++ /dev/null @@ -1,15 +0,0 @@ -let _test = url => true; -const LinkingManger = { - openURL(url) { - return Promise.resolve(true); - }, - canOpenURL(url) { - return Promise.resolve(_test(url)); - }, - - __setCanOpenURLTest(test) { - _test = test; - } -}; - -module.exports = LinkingManger; diff --git a/src/NativeModules/ScrollViewManager.js b/src/NativeModules/ScrollViewManager.js deleted file mode 100644 index 761fee1..0000000 --- a/src/NativeModules/ScrollViewManager.js +++ /dev/null @@ -1,29 +0,0 @@ - -const ScrollViewManager = { - getContentSize(reactTag, callback) { - Promise.resolve().then(() => callback({ - width: 20, - height: 20, - })); - }, - calculateChildFrames(reactTag, callback) { - Promise.resolve().then(() => callback({ - // TODO(lmr): - })); - }, - endRefreshing(reactTag) { - - }, - scrollTo(reactTag, offset, animated) { - - }, - zoomToRect(reactTag, rect, animated) { - - }, - DecelerationRate: { - normal: 0, - fast: 1, - }, -}; - -module.exports = ScrollViewManager; diff --git a/src/NativeModules/SourceCode.js b/src/NativeModules/SourceCode.js deleted file mode 100644 index a420ce9..0000000 --- a/src/NativeModules/SourceCode.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/React/Modules/RCTSourceCode.m - */ -let _sourceCode = null; - -const SourceCode = { - getScriptText() { - return _sourceCode - ? Promise.resolve(_sourceCode) - : Promise.reject(new Error('Source code is not available')); - }, - __setScriptText(url, text) { - _sourceCode = !!url && !!text - ? { url, text } - : null; - }, -}; - -module.exports = SourceCode; diff --git a/src/NativeModules/TestModule.js b/src/NativeModules/TestModule.js deleted file mode 100644 index fb1bbe2..0000000 --- a/src/NativeModules/TestModule.js +++ /dev/null @@ -1,24 +0,0 @@ -import NativeAppEventEmitter from '../plugins/NativeAppEventEmitter'; - -const TestModule = { - verifySnapshot(callback) { - Promise.resolve().then(() => callback(true)); - }, - sendAppEvent(name, body) { - NativeAppEventEmitter.emit(name, body); - }, - shouldResolve() { - return Promise.resolve(1); - }, - shouldReject() { - return Promise.reject(null); - }, - markTestCompleted() { - - }, - markTestPassed(success) { - - }, -}; - -module.exports = TestModule; diff --git a/src/NativeModules/TimePickerAndroid.js b/src/NativeModules/TimePickerAndroid.js deleted file mode 100644 index 1b61601..0000000 --- a/src/NativeModules/TimePickerAndroid.js +++ /dev/null @@ -1,14 +0,0 @@ -// TODO(lmr): figure out a good way to toggle between timeSetAction and dismissedAction -let _resolver = () => ({ action: 'timeSetAction', hour: 2, minute: 30 }); -const TimePickerAndroid = { - open(options) { - const result = _resolver(options) || { action: 'dismissedAction' }; - return Promise.resolve(result); - }, - - __setResolverFunction(resolver) { - _resolver = resolver; - } -}; - -module.exports = TimePickerAndroid; diff --git a/src/NativeModules/Timing.js b/src/NativeModules/Timing.js deleted file mode 100644 index 1b2fa46..0000000 --- a/src/NativeModules/Timing.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/React/Modules/RCTTiming.m - */ -const Timing = { - createTimer(callbackId, duration, jsSchedulingTime, repeats) { - - }, - deleteTimer(timerId) { - - }, -}; - -module.exports = Timing; diff --git a/src/NativeModules/UIManager.js b/src/NativeModules/UIManager.js deleted file mode 100644 index a7be40a..0000000 --- a/src/NativeModules/UIManager.js +++ /dev/null @@ -1,71 +0,0 @@ - -const UIManager = { - removeSubviewsFromContainerWithID(containerId) { - - }, - removeRootView(rootReactTag) { - - }, - replaceExistingNonRootView(reactTag, newReactTag) { - - }, - setChildren(containerTag, reactTags) { - - }, - manageChildren( - containerReactTag, - moveFromIndices, - moveToIndices, - addChildReactTags, - addAtIndices, - removeAtIndices - ) { - - }, - createView(reactTag, viewName, rootTag, props) { - - }, - updateView(reactTag, viewName, props) { - - }, - focus(reactTag) { - - }, - blur(reactTag) { - - }, - findSubviewIn(reactTag, atPoint, callback) { - - }, - dispatchViewManagerCommand(reactTag, commandID, commandArgs) { - - }, - measure(reactTag, callback) { - - }, - measureLayout(reactTag, relativeTo, errorCallback, callback) { - - }, - measureLayoutRelativeToParent(reactTag, errorCallback, callback) { - - }, - measureViewsInRect(rect, parentView, errorCallback, callback) { - - }, - setJSResponder(reactTag, blockNativeResponder) { - - }, - clearJSResponder() { - - }, - configureNextLayoutAnimation(callback, errorCallback) { - - }, - AndroidDrawerLayout: { - Constants: { - DrawerPosition: { Left: 8388611, Right: 8388613 }, - }, - }, -}; - -module.exports = UIManager; diff --git a/src/NativeModules/Vibration.js b/src/NativeModules/Vibration.js deleted file mode 100644 index 8345c50..0000000 --- a/src/NativeModules/Vibration.js +++ /dev/null @@ -1,7 +0,0 @@ -const Vibration = { - vibrate() { - - }, -}; - -module.exports = Vibration; diff --git a/src/NativeModules/WebViewManager.js b/src/NativeModules/WebViewManager.js deleted file mode 100644 index 6c1ce39..0000000 --- a/src/NativeModules/WebViewManager.js +++ /dev/null @@ -1,26 +0,0 @@ - -const WebViewManager = { - goBack(reactTag) { - - }, - goForward(reactTag) { - - }, - reload(reactTag) { - - }, - startLoadWithResult(result, lockIdentifier) { - - }, - JSNavigationScheme: 'react-js-navigation', - NavigationType: { - LinkClicked: 0, - FormSubmitted: 1, - BackForward: 2, - Reload: 3, - FormResubmitted: 4, - Other: 5, - } -}; - -module.exports = WebViewManager; diff --git a/src/NativeModules/index.js b/src/NativeModules/index.js deleted file mode 100644 index 31b1c1f..0000000 --- a/src/NativeModules/index.js +++ /dev/null @@ -1,23 +0,0 @@ - -const NativeModules = { - Timing: require('./Timing'), - UIManager: require('./UIManager'), - AsyncLocalStorage: require('../api/AsyncStorage'), - SourceCode: require('./SourceCode'), - AlertManager: require('./AlertManager'), - Clipboard: require('./Clipboard'), - CameraRollManager: require('./CameraRollManager'), - TestModule: require('./TestModule'), - WebViewManager: require('./WebViewManager'), - ScrollViewManager: require('./ScrollViewManager'), - ActionSheetManager: require('./ActionSheetManager'), - AppState: require('./AppState'), - ImagePickerIOS: require('./ImagePickerIOS'), - DeviceEventManager: require('./DeviceEventManager'), - DatePickerAndroid: require('./DatePickerAndroid'), - LinkingManager: require('./LinkingManager'), - TimePickerAndroid: require('./TimePickerAndroid'), - Vibration: require('./Vibration'), -}; - -module.exports = NativeModules; diff --git a/src/api/ActionSheetIOS.js b/src/api/ActionSheetIOS.js deleted file mode 100644 index 88477dc..0000000 --- a/src/api/ActionSheetIOS.js +++ /dev/null @@ -1,46 +0,0 @@ -import ActionSheetManager from '../NativeModules/ActionSheetManager'; -import invariant from 'invariant'; -import processColor from '../plugins/processColor'; - -const ActionSheetIOS = { - showActionSheetWithOptions(options, callback) { - invariant( - typeof options === 'object' && options !== null, - 'Options must a valid object' - ); - invariant( - typeof callback === 'function', - 'Must provide a valid callback' - ); - ActionSheetManager.showActionSheetWithOptions( - { ...options, tintColor: processColor(options.tintColor) }, - callback - ); - }, - - showShareActionSheetWithOptions( - options, - failureCallback, - successCallback - ) { - invariant( - typeof options === 'object' && options !== null, - 'Options must a valid object' - ); - invariant( - typeof failureCallback === 'function', - 'Must provide a valid failureCallback' - ); - invariant( - typeof successCallback === 'function', - 'Must provide a valid successCallback' - ); - ActionSheetManager.showShareActionSheetWithOptions( - { ...options, tintColor: processColor(options.tintColor) }, - failureCallback, - successCallback - ); - } -}; - -module.exports = ActionSheetIOS; diff --git a/src/api/Alert.js b/src/api/Alert.js deleted file mode 100644 index ac2c918..0000000 --- a/src/api/Alert.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Utilities/Alert.js - */ -const Alert = { - alert(title, message, buttons, type) { - - }, -}; - -module.exports = Alert; diff --git a/src/api/AlertIOS.js b/src/api/AlertIOS.js deleted file mode 100644 index 9d86ad5..0000000 --- a/src/api/AlertIOS.js +++ /dev/null @@ -1,143 +0,0 @@ -import AlertManager from '../NativeModules/AlertManager'; -/** - * The AlertsIOS utility provides two functions: `alert` and `prompt`. All - * functionality available through `AlertIOS.alert` is also available in the - * cross-platform `Alert.alert`, which we recommend you use if you don't need - * iOS-specific functionality. - * - * `AlertIOS.prompt` allows you to prompt the user for input inside of an - * alert popup. - * - */ -class AlertIOS { - /** - * Creates a popup to alert the user. See - * [Alert](/react-native/docs/alert.html). - * - * - title: string -- The dialog's title. - * - message: string -- An optional message that appears above the text input. - * - callbackOrButtons -- This optional argument should be either a - * single-argument function or an array of buttons. If passed a function, - * it will be called when the user taps 'OK'. - * - * If passed an array of button configurations, each button should include - * a `text` key, as well as optional `onPress` and `style` keys. - * `style` should be one of 'default', 'cancel' or 'destructive'. - * - type -- *deprecated, do not use* - * - * Example: - * - * ``` - * AlertIOS.alert( - * 'Sync Complete', - * 'All your data are belong to us.' - * ); - * ``` - */ - static alert(title, message, callbackOrButtons, type) { - if (typeof type !== 'undefined') { - console.warn( - 'AlertIOS.alert() with a 4th "type" parameter is deprecated and will be removed. Use AlertIOS.prompt() instead.' - ); - this.prompt(title, message, callbackOrButtons, type); - return; - } - this.prompt(title, message, callbackOrButtons, 'default'); - } - - /** - * Prompt the user to enter some text. - * - * - title: string -- The dialog's title. - * - message: string -- An optional message that appears above the text input. - * - callbackOrButtons -- This optional argument should be either a - * single-argument function or an array of buttons. If passed a function, - * it will be called with the prompt's value when the user taps 'OK'. - * - * If passed an array of button configurations, each button should include - * a `text` key, as well as optional `onPress` and `style` keys (see example). - * `style` should be one of 'default', 'cancel' or 'destructive'. - * - type: string -- This configures the text input. One of 'plain-text', - * 'secure-text' or 'login-password'. - * - defaultValue: string -- the default value for the text field. - * - * Example with custom buttons: - * ``` - * AlertIOS.prompt( - * 'Enter password', - * 'Enter your password to claim your $1.5B in lottery winnings', - * [ - * {text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'}, - * {text: 'OK', onPress: password => console.log('OK Pressed, password: ' + password)}, - * ], - * 'secure-text' - * ); - * ``` - * - * Example with the default button and a custom callback: - * ``` - * AlertIOS.prompt( - * 'Update username', - * null, - * text => console.log("Your username is "+text), - * null, - * 'default' - * ) - * ``` - */ - static prompt(title, message, callbackOrButtons, type, defaultValue) { - if (typeof type === 'function') { - const callback = type; - AlertManager.alertWithArgs({ - title: title || undefined, - type: 'plain-text', - message, - }, (id, value) => { - callback(value); - }); - return; - } - - let callbacks = []; - const buttons = []; - let cancelButtonKey; - let destructiveButtonKey; - if (typeof callbackOrButtons === 'function') { - callbacks = [callbackOrButtons]; - } else if (callbackOrButtons instanceof Array) { - callbackOrButtons.forEach((btn, index) => { - callbacks[index] = btn.onPress; - if (btn.style === 'cancel') { - cancelButtonKey = String(index); - } else if (btn.style === 'destructive') { - destructiveButtonKey = String(index); - } - if (btn.text || index < (callbackOrButtons || []).length - 1) { - const btnDef = {}; - btnDef[index] = btn.text || ''; - buttons.push(btnDef); - } - }); - } - - AlertManager.alertWithArgs( - { - title: title || undefined, - message: message || undefined, - buttons, - type: type || undefined, - defaultValue, - cancelButtonKey, - destructiveButtonKey, - }, - (id, value) => { - const cb = callbacks[id]; - if (cb) { - cb(value); - } - } - ); - } -} - -module.exports = AlertIOS; diff --git a/src/api/Animated/AnimatedImplementation.js b/src/api/Animated/AnimatedImplementation.js deleted file mode 100644 index 682d9ae..0000000 --- a/src/api/Animated/AnimatedImplementation.js +++ /dev/null @@ -1,1182 +0,0 @@ -import invariant from 'invariant'; -import Interpolation from './Interpolation'; -import Easing from './Easing'; -import InteractionManager from '../InteractionManager'; -import SpringConfig from './SpringConfig'; -import requestAnimationFrame from 'raf'; -import flattenStyle from '../../propTypes/flattenStyle'; - -class Animated { - __attach() {} - __detach() {} - __getValue() {} - __getAnimatedValue() { return this.__getValue(); } - __addChild(child) {} - __removeChild(child) {} - __getChildren() { return []; } -} - -class Animation { - start(fromValue, onUpdate, onEnd, previousAnimation) {} - stop() {} - __debouncedOnEnd(result) { - const onEnd = this.__onEnd; - this.__onEnd = null; - if (onEnd) { - onEnd(result); - } - } -} - -class AnimatedWithChildren extends Animated { - constructor() { - super(); - this._children = []; - } - - __addChild(child) { - if (this._children.length === 0) { - this.__attach(); - } - this._children.push(child); - } - - __removeChild(child) { - const index = this._children.indexOf(child); - if (index === -1) { - console.warn( - 'Trying to remove a child that doesn\'t exist' - ); - return; - } - this._children.splice(index, 1); - if (this._children.length === 0) { - this.__detach(); - } - } - - __getChildren() { - return this._children; - } -} - -/** - * Animated works by building a directed acyclic graph of dependencies - * transparently when you render your Animated components. - * - * new Animated.Value(0) - * .interpolate() .interpolate() new Animated.Value(1) - * opacity translateY scale - * style transform - * View#234 style - * View#123 - * - * A) Top Down phase - * When an Animated.Value is updated, we recursively go down through this - * graph in order to find leaf nodes: the views that we flag as needing - * an update. - * - * B) Bottom Up phase - * When a view is flagged as needing an update, we recursively go back up - * in order to build the new value that it needs. The reason why we need - * this two-phases process is to deal with composite props such as - * transform which can receive values from multiple parents. - */ -function _flush(rootNode) { - const animatedStyles = new Set(); - function findAnimatedStyles(node) { - if (typeof node.update === 'function') { - animatedStyles.add(node); - } else { - node.__getChildren().forEach(findAnimatedStyles); - } - } - findAnimatedStyles(rootNode); - animatedStyles.forEach(animatedStyle => animatedStyle.update()); -} - -const easeInOut = Easing.inOut(Easing.ease); - -class TimingAnimation extends Animation { - constructor(config) { - super(); - this._toValue = config.toValue; - this._easing = config.easing || easeInOut; - this._duration = config.duration !== undefined ? config.duration : 500; - this._delay = config.delay || 0; - this.__isInteraction = config.isInteraction !== undefined ? config.isInteraction : true; - } - - start(fromValue, onUpdate, onEnd) { - this.__active = true; - this._fromValue = fromValue; - this._onUpdate = onUpdate; - this.__onEnd = onEnd; - - const start = () => { - if (this._duration === 0) { - this._onUpdate(this._toValue); - this.__debouncedOnEnd({ finished: true }); - } else { - this._startTime = Date.now(); - this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this)); - } - }; - if (this._delay) { - this._timeout = setTimeout(start, this._delay); - } else { - start(); - } - } - - onUpdate() { - const now = Date.now(); - if (now >= this._startTime + this._duration) { - if (this._duration === 0) { - this._onUpdate(this._toValue); - } else { - this._onUpdate( - this._fromValue + this._easing(1) * (this._toValue - this._fromValue) - ); - } - this.__debouncedOnEnd({ finished: true }); - return; - } - - this._onUpdate( - this._fromValue + - this._easing((now - this._startTime) / this._duration) * - (this._toValue - this._fromValue) - ); - if (this.__active) { - this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this)); - } - } - - stop() { - this.__active = false; - clearTimeout(this._timeout); - if (global && global.cancelAnimationFrame) { - global.cancelAnimationFrame(this._animationFrame); - } - this.__debouncedOnEnd({ finished: false }); - } -} - -class DecayAnimation extends Animation { - constructor(config) { - super(); - this._deceleration = config.deceleration || 0.998; - this._velocity = config.velocity; - this.__isInteraction = config.isInteraction !== undefined ? config.isInteraction : true; - } - - start(fromValue, onUpdate, onEnd) { - this.__active = true; - this._lastValue = fromValue; - this._fromValue = fromValue; - this._onUpdate = onUpdate; - this.__onEnd = onEnd; - this._startTime = Date.now(); - this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this)); - } - - onUpdate() { - const now = Date.now(); - - const value = this._fromValue + - (this._velocity / (1 - this._deceleration)) * - (1 - Math.exp(-(1 - this._deceleration) * (now - this._startTime))); - - this._onUpdate(value); - - if (Math.abs(this._lastValue - value) < 0.1) { - this.__debouncedOnEnd({ finished: true }); - return; - } - - this._lastValue = value; - if (this.__active) { - this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this)); - } - } - - stop() { - this.__active = false; - if (global && global.cancelAnimationFrame) { - global.cancelAnimationFrame(this._animationFrame); - } - this.__debouncedOnEnd({ finished: false }); - } -} - -function withDefault(value, defaultValue) { - if (value === undefined || value === null) { - return defaultValue; - } - return value; -} - -class SpringAnimation extends Animation { - constructor(config) { - super(); - - this._overshootClamping = withDefault(config.overshootClamping, false); - this._restDisplacementThreshold = withDefault(config.restDisplacementThreshold, 0.001); - this._restSpeedThreshold = withDefault(config.restSpeedThreshold, 0.001); - this._initialVelocity = config.velocity; - this._lastVelocity = withDefault(config.velocity, 0); - this._toValue = config.toValue; - this.__isInteraction = config.isInteraction !== undefined ? config.isInteraction : true; - - let springConfig; - if (config.bounciness !== undefined || config.speed !== undefined) { - invariant( - config.tension === undefined && config.friction === undefined, - 'You can only define bounciness/speed or tension/friction but not both' - ); - springConfig = SpringConfig.fromBouncinessAndSpeed( - withDefault(config.bounciness, 8), - withDefault(config.speed, 12), - ); - } else { - springConfig = SpringConfig.fromOrigamiTensionAndFriction( - withDefault(config.tension, 40), - withDefault(config.friction, 7), - ); - } - this._tension = springConfig.tension; - this._friction = springConfig.friction; - } - - start(fromValue, onUpdate, onEnd, previousAnimation) { - this.__active = true; - this._startPosition = fromValue; - this._lastPosition = this._startPosition; - - this._onUpdate = onUpdate; - this.__onEnd = onEnd; - this._lastTime = Date.now(); - - if (previousAnimation instanceof SpringAnimation) { - const internalState = previousAnimation.getInternalState(); - this._lastPosition = internalState.lastPosition; - this._lastVelocity = internalState.lastVelocity; - this._lastTime = internalState.lastTime; - } - if (this._initialVelocity !== undefined && this._initialVelocity !== null) { - this._lastVelocity = this._initialVelocity; - } - this.onUpdate(); - } - - getInternalState() { - return { - lastPosition: this._lastPosition, - lastVelocity: this._lastVelocity, - lastTime: this._lastTime, - }; - } - - onUpdate() { - let position = this._lastPosition; - let velocity = this._lastVelocity; - - let tempPosition = this._lastPosition; - let tempVelocity = this._lastVelocity; - - // If for some reason we lost a lot of frames (e.g. process large payload or - // stopped in the debugger), we only advance by 4 frames worth of - // computation and will continue on the next frame. It's better to have it - // running at faster speed than jumping to the end. - const MAX_STEPS = 64; - let now = Date.now(); - if (now > this._lastTime + MAX_STEPS) { - now = this._lastTime + MAX_STEPS; - } - - // We are using a fixed time step and a maximum number of iterations. - // The following post provides a lot of thoughts into how to build this - // loop: http://gafferongames.com/game-physics/fix-your-timestep/ - const TIMESTEP_MSEC = 1; - const numSteps = Math.floor((now - this._lastTime) / TIMESTEP_MSEC); - - for (let i = 0; i < numSteps; ++i) { - // Velocity is based on seconds instead of milliseconds - const step = TIMESTEP_MSEC / 1000; - - // This is using RK4. A good blog post to understand how it works: - // http://gafferongames.com/game-physics/integration-basics/ - const aVelocity = velocity; - const aAcceleration = - this._tension * (this._toValue - tempPosition) - this._friction * tempVelocity; - tempPosition = position + aVelocity * step / 2; - tempVelocity = velocity + aAcceleration * step / 2; - - const bVelocity = tempVelocity; - const bAcceleration = - this._tension * (this._toValue - tempPosition) - this._friction * tempVelocity; - tempPosition = position + bVelocity * step / 2; - tempVelocity = velocity + bAcceleration * step / 2; - - const cVelocity = tempVelocity; - const cAcceleration = - this._tension * (this._toValue - tempPosition) - this._friction * tempVelocity; - tempPosition = position + cVelocity * step / 2; - tempVelocity = velocity + cAcceleration * step / 2; - - const dVelocity = tempVelocity; - const dAcceleration = - this._tension * (this._toValue - tempPosition) - this._friction * tempVelocity; - tempPosition = position + cVelocity * step / 2; - tempVelocity = velocity + cAcceleration * step / 2; - - const dxdt = (aVelocity + 2 * (bVelocity + cVelocity) + dVelocity) / 6; - const dvdt = (aAcceleration + 2 * (bAcceleration + cAcceleration) + dAcceleration) / 6; - - position += dxdt * step; - velocity += dvdt * step; - } - - this._lastTime = now; - this._lastPosition = position; - this._lastVelocity = velocity; - - this._onUpdate(position); - if (!this.__active) { // a listener might have stopped us in _onUpdate - return; - } - - // Conditions for stopping the spring animation - let isOvershooting = false; - if (this._overshootClamping && this._tension !== 0) { - if (this._startPosition < this._toValue) { - isOvershooting = position > this._toValue; - } else { - isOvershooting = position < this._toValue; - } - } - - const isVelocity = Math.abs(velocity) <= this._restSpeedThreshold; - let isDisplacement = true; - if (this._tension !== 0) { - isDisplacement = Math.abs(this._toValue - position) <= this._restDisplacementThreshold; - } - - if (isOvershooting || (isVelocity && isDisplacement)) { - if (this._tension !== 0) { - // Ensure that we end up with a round value - this._onUpdate(this._toValue); - } - - this.__debouncedOnEnd({ finished: true }); - return; - } - this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this)); - } - - stop() { - this.__active = false; - window.cancelAnimationFrame(this._animationFrame); - this.__debouncedOnEnd({ finished: false }); - } -} - -let _uniqueId = 1; - -class AnimatedInterpolation extends AnimatedWithChildren { - constructor(parent, interpolation) { - super(); - this._parent = parent; - this._interpolation = interpolation; - } - - __getValue() { - const parentValue = this._parent.__getValue(); - invariant( - typeof parentValue === 'number', - 'Cannot interpolate an input which is not a number.' - ); - return this._interpolation(parentValue); - } - - interpolate(config) { - return new AnimatedInterpolation(this, Interpolation.create(config)); - } - - __attach() { - this._parent.__addChild(this); - } - - __detach() { - this._parent.__removeChild(this); - } -} - - -class AnimatedValue extends AnimatedWithChildren { - constructor(value) { - super(); - this._value = value; - this._offset = 0; - this._animation = null; - this._listeners = {}; - } - - __detach() { - this.stopAnimation(); - } - - __getValue() { - return this._value + this._offset; - } - - /** - * Directly set the value. This will stop any animations running on the value - * and update all the bound properties. - */ - setValue(value) { - if (this._animation) { - this._animation.stop(); - this._animation = null; - } - this._updateValue(value); - } - - /** - * Sets an offset that is applied on top of whatever value is set, whether via - * `setValue`, an animation, or `Animated.event`. Useful for compensating - * things like the start of a pan gesture. - */ - setOffset(offset) { - this._offset = offset; - } - - /** - * Merges the offset value into the base value and resets the offset to zero. - * The final output of the value is unchanged. - */ - flattenOffset() { - this._value += this._offset; - this._offset = 0; - } - - /** - * Adds an asynchronous listener to the value so you can observe updates from - * animations. This is useful because there is no way to - * synchronously read the value because it might be driven natively. - */ - addListener(callback) { - const id = String(_uniqueId++); - this._listeners[id] = callback; - return id; - } - - removeListener(id) { - delete this._listeners[id]; - } - - removeAllListeners() { - this._listeners = {}; - } - - /** - * Stops any running animation or tracking. `callback` is invoked with the - * final value after stopping the animation, which is useful for updating - * state to match the animation position with layout. - */ - stopAnimation(callback) { - this.stopTracking(); - if (this._animation) { - this._animation.stop(); - } - this._animation = null; - if (callback) { - callback(this.__getValue()); - } - } - - /** - * Interpolates the value before updating the property, e.g. mapping 0-1 to - * 0-10. - */ - interpolate(config) { - return new AnimatedInterpolation(this, Interpolation.create(config)); - } - - /** - * Typically only used internally, but could be used by a custom Animation - * class. - */ - animate(animation, callback) { - let handle = null; - if (animation.__isInteraction) { - handle = InteractionManager.createInteractionHandle(); - } - const previousAnimation = this._animation; - if (this._animation) { - this._animation.stop(); - } - this._animation = animation; - animation.start( - this._value, - (value) => { - this._updateValue(value); - }, - (result) => { - this._animation = null; - if (handle !== null) { - InteractionManager.clearInteractionHandle(handle); - } - if (callback) { - callback(result); - } - }, - previousAnimation - ); - } - - /** - * Typically only used internally. - */ - stopTracking() { - if (this._tracking) { - this._tracking.__detach(); - } - this._tracking = null; - } - - /** - * Typically only used internally. - */ - track(tracking) { - this.stopTracking(); - this._tracking = tracking; - } - - _updateValue(value) { - this._value = value; - _flush(this); - for (const key in this._listeners) { - this._listeners[key]({ value: this.__getValue() }); - } - } -} - - -class AnimatedValueXY extends AnimatedWithChildren { - constructor(valueIn) { - super(); - const value = valueIn || { x: 0, y: 0 }; // @flowfixme: shouldn't need `: any` - if (typeof value.x === 'number' && typeof value.y === 'number') { - this.x = new AnimatedValue(value.x); - this.y = new AnimatedValue(value.y); - } else { - invariant( - value.x instanceof AnimatedValue && - value.y instanceof AnimatedValue, - 'AnimatedValueXY must be initalized with an object of numbers or ' + - 'AnimatedValues.' - ); - this.x = value.x; - this.y = value.y; - } - this._listeners = {}; - } - - setValue(value) { - this.x.setValue(value.x); - this.y.setValue(value.y); - } - - setOffset(offset) { - this.x.setOffset(offset.x); - this.y.setOffset(offset.y); - } - - flattenOffset() { - this.x.flattenOffset(); - this.y.flattenOffset(); - } - - __getValue() { - return { - x: this.x.__getValue(), - y: this.y.__getValue(), - }; - } - - stopAnimation(callback) { - this.x.stopAnimation(); - this.y.stopAnimation(); - if (callback) { - callback(this.__getValue()); - } - } - - addListener(callback) { - const id = String(_uniqueId++); - const jointCallback = ({ value }) => { - callback(this.__getValue()); - }; - this._listeners[id] = { - x: this.x.addListener(jointCallback), - y: this.y.addListener(jointCallback), - }; - return id; - } - - removeListener(id) { - this.x.removeListener(this._listeners[id].x); - this.y.removeListener(this._listeners[id].y); - delete this._listeners[id]; - } - - /** - * Converts `{x, y}` into `{left, top}` for use in style, e.g. - * - *```javascript - * style={this.state.anim.getLayout()} - *``` - */ - getLayout() { - return { - left: this.x, - top: this.y, - }; - } - - /** - * Converts `{x, y}` into a useable translation transform, e.g. - * - *```javascript - * style={{ - * transform: this.state.anim.getTranslateTransform() - * }} - *``` - */ - getTranslateTransform() { - return [ - { translateX: this.x }, - { translateY: this.y } - ]; - } -} - - -class AnimatedAddition extends AnimatedWithChildren { - constructor(a, b) { - super(); - this._a = a; - this._b = b; - } - - __getValue() { - return this._a.__getValue() + this._b.__getValue(); - } - - interpolate(config) { - return new AnimatedInterpolation(this, Interpolation.create(config)); - } - - __attach() { - this._a.__addChild(this); - this._b.__addChild(this); - } - - __detach() { - this._a.__removeChild(this); - this._b.__removeChild(this); - } -} - -class AnimatedMultiplication extends AnimatedWithChildren { - constructor(a, b) { - super(); - this._a = a; - this._b = b; - } - - __getValue() { - return this._a.__getValue() * this._b.__getValue(); - } - - interpolate(config) { - return new AnimatedInterpolation(this, Interpolation.create(config)); - } - - __attach() { - this._a.__addChild(this); - this._b.__addChild(this); - } - - __detach() { - this._a.__removeChild(this); - this._b.__removeChild(this); - } -} - -class AnimatedTransform extends AnimatedWithChildren { - constructor(transforms) { - super(); - this._transforms = transforms; - } - - __getValue() { - return this._transforms.map(transform => { - const result = {}; - for (const key in transform) { - const value = transform[key]; - if (value instanceof Animated) { - result[key] = value.__getValue(); - } else { - result[key] = value; - } - } - return result; - }); - } - - __getAnimatedValue() { - return this._transforms.map(transform => { - const result = {}; - for (const key in transform) { - const value = transform[key]; - if (value instanceof Animated) { - result[key] = value.__getAnimatedValue(); - } else { - // All transform components needed to recompose matrix - result[key] = value; - } - } - return result; - }); - } - - __attach() { - this._transforms.forEach(transform => { - for (const key in transform) { - const value = transform[key]; - if (value instanceof Animated) { - value.__addChild(this); - } - } - }); - } - - __detach() { - this._transforms.forEach(transform => { - for (const key in transform) { - const value = transform[key]; - if (value instanceof Animated) { - value.__removeChild(this); - } - } - }); - } -} - -class AnimatedStyle extends AnimatedWithChildren { - constructor(style) { - super(); - let newStyle; - newStyle = flattenStyle(style) || {}; - if (newStyle.transform) { - newStyle = { - ...newStyle, - transform: new AnimatedTransform(newStyle.transform), - }; - } - this._style = newStyle; - } - - __getValue() { - const style = {}; - for (const key in this._style) { - const value = this._style[key]; - if (value instanceof Animated) { - style[key] = value.__getValue(); - } else { - style[key] = value; - } - } - return style; - } - - __getAnimatedValue() { - const style = {}; - for (const key in this._style) { - const value = this._style[key]; - if (value instanceof Animated) { - style[key] = value.__getAnimatedValue(); - } - } - return style; - } - - __attach() { - for (const key in this._style) { - const value = this._style[key]; - if (value instanceof Animated) { - value.__addChild(this); - } - } - } - - __detach() { - for (const key in this._style) { - const value = this._style[key]; - if (value instanceof Animated) { - value.__removeChild(this); - } - } - } -} - -class AnimatedProps extends Animated { - constructor(props, callback) { - super(); - this._props = props; - if (this._props.style) { - this._props = { - ...this._props, - style: new AnimatedStyle(this._props.style), - }; - } - this._callback = callback; - this.__attach(); - } - - __getValue() { - const props = {}; - for (const key in this._props) { - const value = this._props[key]; - if (value instanceof Animated) { - props[key] = value.__getValue(); - } else { - props[key] = value; - } - } - return props; - } - - __getAnimatedValue() { - const props = {}; - for (const key in this._props) { - const value = this._props[key]; - if (value instanceof Animated) { - props[key] = value.__getAnimatedValue(); - } - } - return props; - } - - __attach() { - for (const key in this._props) { - const value = this._props[key]; - if (value instanceof Animated) { - value.__addChild(this); - } - } - } - - __detach() { - for (const key in this._props) { - const value = this._props[key]; - if (value instanceof Animated) { - value.__removeChild(this); - } - } - } - - update() { - this._callback(); - } -} - -class AnimatedTracking extends Animated { - constructor(value, parent, animationClass, animationConfig, callback) { - super(); - this._value = value; - this._parent = parent; - this._animationClass = animationClass; - this._animationConfig = animationConfig; - this._callback = callback; - this.__attach(); - } - - __getValue() { - return this._parent.__getValue(); - } - - __attach() { - this._parent.__addChild(this); - } - - __detach() { - this._parent.__removeChild(this); - } - - update() { - this._value.animate(new this._animationClass({ - ...this._animationConfig, - toValue: this._animationConfig.toValue.__getValue(), - }), this._callback); - } -} - -function add(a, b) { - return new AnimatedAddition(a, b); -} - -function multiply(a, b) { - return new AnimatedMultiplication(a, b); -} - -function parallel(animations, config) { - let doneCount = 0; - // Make sure we only call stop() at most once for each animation - const hasEnded = {}; - const stopTogether = !(config && config.stopTogether === false); - - const result = { - start(callback) { - if (doneCount === animations.length) { - if (callback) { - callback({ finished: true }); - } - return; - } - - animations.forEach((animation, idx) => { - const cb = function (endResult) { - hasEnded[idx] = true; - doneCount++; - if (doneCount === animations.length) { - doneCount = 0; - if (callback) { - callback(endResult); - } - return; - } - - if (!endResult.finished && stopTogether) { - result.stop(); - } - }; - - if (!animation) { - cb({ finished: true }); - } else { - animation.start(cb); - } - }); - }, - - stop() { - animations.forEach((animation, idx) => { - if (!hasEnded[idx]) { - animation.stop(); - } - hasEnded[idx] = true; - }); - } - }; - - return result; -} - -function maybeVectorAnim(value, config, anim) { - if (value instanceof AnimatedValueXY) { - const configX = { ...config }; - const configY = { ...config }; - for (const key in config) { - const { x, y } = config[key]; - if (x !== undefined && y !== undefined) { - configX[key] = x; - configY[key] = y; - } - } - const aX = anim(value.x, configX); - const aY = anim(value.y, configY); - // We use `stopTogether: false` here because otherwise tracking will break - // because the second animation will get stopped before it can update. - return parallel([aX, aY], { stopTogether: false }); - } - return null; -} - -function spring(value, config) { - return maybeVectorAnim(value, config, spring) || { - start(callback) { - const singleValue = value; - const singleConfig = config; - singleValue.stopTracking(); - if (config.toValue instanceof Animated) { - singleValue.track(new AnimatedTracking( - singleValue, - config.toValue, - SpringAnimation, - singleConfig, - callback - )); - } else { - singleValue.animate(new SpringAnimation(singleConfig), callback); - } - }, - - stop() { - value.stopAnimation(); - }, - }; -} - -function timing(value, config) { - return maybeVectorAnim(value, config, timing) || { - start(callback) { - const singleValue = value; - const singleConfig = config; - singleValue.stopTracking(); - if (config.toValue instanceof Animated) { - singleValue.track(new AnimatedTracking( - singleValue, - config.toValue, - TimingAnimation, - singleConfig, - callback - )); - } else { - singleValue.animate(new TimingAnimation(singleConfig), callback); - } - }, - - stop() { - value.stopAnimation(); - }, - }; -} - -function decay(value, config) { - return maybeVectorAnim(value, config, decay) || { - start(callback) { - const singleValue = value; - const singleConfig = config; - singleValue.stopTracking(); - singleValue.animate(new DecayAnimation(singleConfig), callback); - }, - - stop() { - value.stopAnimation(); - }, - }; -} - -function sequence(animations) { - let current = 0; - return { - start(callback) { - const onComplete = function (result) { - if (!result.finished) { - if (callback) { - callback(result); - } - return; - } - - current++; - - if (current === animations.length) { - if (callback) { - callback(result); - } - return; - } - - animations[current].start(onComplete); - }; - - if (animations.length === 0) { - if (callback) { - callback({ finished: true }); - } - } else { - animations[current].start(onComplete); - } - }, - - stop() { - if (current < animations.length) { - animations[current].stop(); - } - } - }; -} - -function delay(time) { - // Would be nice to make a specialized implementation - return timing(new AnimatedValue(0), { toValue: 0, delay: time, duration: 0 }); -} - -function stagger(time, animations) { - return parallel(animations.map(function (animation, i) { - return sequence([ - delay(time * i), - animation, - ]); - })); -} - -function event(argMapping, config) { - return function (...args) { - const traverse = function (recMapping, recEvt, key) { - if (typeof recEvt === 'number') { - invariant( - recMapping instanceof AnimatedValue, - 'Bad mapping of type ' + typeof recMapping + ' for key ' + key + - ', event value must map to AnimatedValue' - ); - recMapping.setValue(recEvt); - return; - } - invariant( - typeof recMapping === 'object', - 'Bad mapping of type ' + typeof recMapping + ' for key ' + key - ); - invariant( - typeof recEvt === 'object', - 'Bad event of type ' + typeof recEvt + ' for key ' + key - ); - for (const i in recMapping) { - traverse(recMapping[i], recEvt[i], i); - } - }; - argMapping.forEach((mapping, idx) => { - traverse(mapping, args[idx], 'arg' + idx); - }); - if (config && config.listener) { - config.listener.apply(null, args); - } - }; -} - -const AnimatedImplementation = { - Value: AnimatedValue, - ValueXY: AnimatedValueXY, - decay, - timing, - spring, - add, - multiply, - sequence, - parallel, - stagger, - event, - - __PropsOnlyForTests: AnimatedProps, - __Animated: Animated, - __Animation: Animation, - __AnimatedWithChildren: AnimatedWithChildren, - __AnimatedStyle: AnimatedStyle, -}; - -module.exports = AnimatedImplementation; diff --git a/src/api/Animated/Easing.js b/src/api/Animated/Easing.js deleted file mode 100644 index 6183793..0000000 --- a/src/api/Animated/Easing.js +++ /dev/null @@ -1,122 +0,0 @@ -import _bezier from 'cubic-bezier'; - -let _ease = () => {}; - -const EPSILON = (1000 / 60 / 500) / 4; - -/** - * This class implements common easing functions. The math is pretty obscure, - * but this cool website has nice visual illustrations of what they represent: - * http://xaedes.de/dev/transitions/ - */ -class Easing { - static step0(n) { - return n > 0 ? 1 : 0; - } - - static step1(n) { - return n >= 1 ? 1 : 0; - } - - static linear(t) { - return t; - } - - static ease(t) { - return _ease(t); - } - - static quad(t) { - return t * t; - } - - static cubic(t) { - return t * t * t; - } - - static poly(n) { - return (t) => Math.pow(t, n); - } - - static sin(t) { - return 1 - Math.cos(t * Math.PI / 2); - } - - static circle(t) { - return 1 - Math.sqrt(1 - t * t); - } - - static exp(t) { - return Math.pow(2, 10 * (t - 1)); - } - - /** - * A simple elastic interaction, similar to a spring. Default bounciness - * is 1, which overshoots a little bit once. 0 bounciness doesn't overshoot - * at all, and bounciness of N > 1 will overshoot about N times. - * - * Wolfram Plots: - * - * http://tiny.cc/elastic_b_1 (default bounciness = 1) - * http://tiny.cc/elastic_b_3 (bounciness = 3) - */ - static elastic(bounciness = 1) { - const p = bounciness * Math.PI; - return (t) => 1 - Math.pow(Math.cos(t * Math.PI / 2), 3) * Math.cos(t * p); - } - - static back(s = 1.70158) { - return (t) => t * t * ((s + 1) * t - s); - } - - static bounce(argT) { - let t = argT; - if (t < 1 / 2.75) { - return 7.5625 * t * t; - } - - if (t < 2 / 2.75) { - t -= 1.5 / 2.75; - return 7.5625 * t * t + 0.75; - } - - if (t < 2.5 / 2.75) { - t -= 2.25 / 2.75; - return 7.5625 * t * t + 0.9375; - } - - t -= 2.625 / 2.75; - return 7.5625 * t * t + 0.984375; - } - - static bezier(x1, y1, x2, y2, epsilon = EPSILON) { - return _bezier(x1, y1, x2, y2, epsilon); - } - - static in(easing) { - return easing; - } - - /** - * Runs an easing function backwards. - */ - static out(easing) { - return (t) => 1 - easing(1 - t); - } - - /** - * Makes any easing function symmetrical. - */ - static inOut(easing) { - return (t) => { - if (t < 0.5) { - return easing(t * 2) / 2; - } - return 1 - easing((1 - t) * 2) / 2; - }; - } -} - -_ease = Easing.bezier(0.42, 0, 1, 1); - -module.exports = Easing; diff --git a/src/api/Animated/Interpolation.js b/src/api/Animated/Interpolation.js deleted file mode 100644 index aa38a49..0000000 --- a/src/api/Animated/Interpolation.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Animated/src/Interpolation.js - */ -class Interpolation { - static create(config) { - // TODO(lmr): - } -} - -module.exports = Interpolation; diff --git a/src/api/Animated/SpringConfig.js b/src/api/Animated/SpringConfig.js deleted file mode 100644 index 0488523..0000000 --- a/src/api/Animated/SpringConfig.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Animated/src/SpringConfig.js - */ - -function tensionFromOrigamiValue(oValue) { - return (oValue - 30) * 3.62 + 194; -} - -function frictionFromOrigamiValue(oValue) { - return (oValue - 8) * 3 + 25; -} - -function fromOrigamiTensionAndFriction(tension, friction) { - return { - tension: tensionFromOrigamiValue(tension), - friction: frictionFromOrigamiValue(friction) - }; -} - -function fromBouncinessAndSpeed(bounciness, speed) { - function normalize(value, startValue, endValue) { - return (value - startValue) / (endValue - startValue); - } - - function projectNormal(n, start, end) { - return start + (n * (end - start)); - } - - function linearInterpolation(t, start, end) { - return t * end + (1 - t) * start; - } - - function quadraticOutInterpolation(t, start, end) { - return linearInterpolation(2 * t - t * t, start, end); - } - - function b3Friction1(x) { - return (0.0007 * Math.pow(x, 3)) - - (0.031 * Math.pow(x, 2)) + 0.64 * x + 1.28; - } - - function b3Friction2(x) { - return (0.000044 * Math.pow(x, 3)) - - (0.006 * Math.pow(x, 2)) + 0.36 * x + 2; - } - - function b3Friction3(x) { - return (0.00000045 * Math.pow(x, 3)) - - (0.000332 * Math.pow(x, 2)) + 0.1078 * x + 5.84; - } - - function b3Nobounce(tension) { - if (tension <= 18) { - return b3Friction1(tension); - } else if (tension > 18 && tension <= 44) { - return b3Friction2(tension); - } - return b3Friction3(tension); - } - - let b = normalize(bounciness / 1.7, 0, 20); - b = projectNormal(b, 0, 0.8); - const s = normalize(speed / 1.7, 0, 20); - const bouncyTension = projectNormal(s, 0.5, 200); - const bouncyFriction = quadraticOutInterpolation( - b, - b3Nobounce(bouncyTension), - 0.01 - ); - - return { - tension: tensionFromOrigamiValue(bouncyTension), - friction: frictionFromOrigamiValue(bouncyFriction) - }; -} - -module.exports = { - fromOrigamiTensionAndFriction, - fromBouncinessAndSpeed, -}; diff --git a/src/api/Animated/createAnimatedComponent.js b/src/api/Animated/createAnimatedComponent.js deleted file mode 100644 index 6e9cba5..0000000 --- a/src/api/Animated/createAnimatedComponent.js +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; - -function createAnimatedComponent(Component) { - const refName = 'node'; - - class AnimatedComponent extends React.Component { - render() { - return ( - - ); - } - } - - return AnimatedComponent; -} - -module.exports = createAnimatedComponent; diff --git a/src/api/Animated/index.js b/src/api/Animated/index.js deleted file mode 100644 index 914f6ca..0000000 --- a/src/api/Animated/index.js +++ /dev/null @@ -1,13 +0,0 @@ -import View from '../../components/View'; -import Text from '../../components/Text'; -import Image from '../../components/Image'; -import createAnimatedComponent from './createAnimatedComponent'; -import AnimatedImplementation from './AnimatedImplementation'; - -module.exports = { - ...AnimatedImplementation, - createAnimatedComponent, - View: createAnimatedComponent(View), - Text: createAnimatedComponent(Text), - Image: createAnimatedComponent(Image), -}; diff --git a/src/api/AppRegistry.js b/src/api/AppRegistry.js deleted file mode 100644 index df50345..0000000 --- a/src/api/AppRegistry.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/AppRegistry/AppRegistry.js - */ -const runnables = {}; - -const AppRegistry = { - registerConfig(configs) { - - }, - - registerComponent(appKey, getComponentFunc) { - return appKey; - }, - - registerRunnable(appKey, func) { - runnables[appKey] = { run: func }; - return appKey; - }, - - getAppKeys() { - return Object.keys(runnables); - }, - - runApplication(appKey, appParameters) { - - }, - - unmountApplicationComponentAtRootTag(rootTag) { - - }, -}; - -module.exports = AppRegistry; diff --git a/src/api/AppState.js b/src/api/AppState.js deleted file mode 100644 index 8e3b75a..0000000 --- a/src/api/AppState.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/AppState/AppState.js - */ -import invariant from 'invariant'; -import DeviceEventEmitter from '../plugins/DeviceEventEmitter'; - -const _eventHandlers = { - change: new Map(), - memoryWarning: new Map(), -}; - -const AppState = { - addEventListener(type, handler) { - invariant( - ['change', 'memoryWarning'].indexOf(type) !== -1, - 'Trying to subscribe to unknown event: "%s"', type - ); - if (type === 'change') { - _eventHandlers[type].set(handler, DeviceEventEmitter.addListener( - 'appStateDidChange', - (appStateData) => handler(appStateData.appState) - )); - } else if (type === 'memoryWarning') { - _eventHandlers[type].set(handler, DeviceEventEmitter.addListener( - 'memoryWarning', - handler - )); - } - }, - - removeEventListener(type, handler) { - invariant( - ['change', 'memoryWarning'].indexOf(type) !== -1, - 'Trying to remove listener for unknown event: "%s"', type - ); - if (!_eventHandlers[type].has(handler)) { - return; - } - _eventHandlers[type].get(handler).remove(); - _eventHandlers[type].delete(handler); - }, - - currentState: 'active', - - __setAppState(appState) { - DeviceEventEmitter.emit('appStateDidChange', { appState }); - }, -}; - -DeviceEventEmitter.addListener( - 'appStateDidChange', - (appStateData) => { AppState.currentState = appStateData.appState; } -); - -module.exports = AppState; diff --git a/src/api/AppStateIOS.js b/src/api/AppStateIOS.js deleted file mode 100644 index 5066681..0000000 --- a/src/api/AppStateIOS.js +++ /dev/null @@ -1,126 +0,0 @@ -import DeviceEventEmitter from '../plugins/DeviceEventEmitter'; -import AppState from '../NativeModules/AppState'; -import invariant from 'invariant'; - -const logError = (error) => console.error(error); - -const _eventHandlers = { - change: new Map(), - memoryWarning: new Map(), -}; - -/** - * `AppStateIOS` can tell you if the app is in the foreground or background, - * and notify you when the state changes. - * - * AppStateIOS is frequently used to determine the intent and proper behavior when - * handling push notifications. - * - * ### iOS App States - * - * - `active` - The app is running in the foreground - * - `background` - The app is running in the background. The user is either - * in another app or on the home screen - * - `inactive` - This is a transition state that currently never happens for - * typical React Native apps. - * - * For more information, see - * [Apple's documentation](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html) - * - * ### Basic Usage - * - * To see the current state, you can check `AppStateIOS.currentState`, which - * will be kept up-to-date. However, `currentState` will be null at launch - * while `AppStateIOS` retrieves it over the bridge. - * - * ``` - * getInitialState: function() { - * return { - * currentAppState: AppStateIOS.currentState, - * }; - * }, - * componentDidMount: function() { - * AppStateIOS.addEventListener('change', this._handleAppStateChange); - * }, - * componentWillUnmount: function() { - * AppStateIOS.removeEventListener('change', this._handleAppStateChange); - * }, - * _handleAppStateChange: function(currentAppState) { - * this.setState({ currentAppState, }); - * }, - * render: function() { - * return ( - * Current state is: {this.state.currentAppState} - * ); - * }, - * ``` - * - * This example will only ever appear to say "Current state is: active" because - * the app is only visible to the user when in the `active` state, and the null - * state will happen only momentarily. - */ - -const AppStateIOS = { - - /** - * Add a handler to AppState changes by listening to the `change` event type - * and providing the handler - */ - addEventListener(type, handler) { - invariant( - ['change', 'memoryWarning'].indexOf(type) !== -1, - 'Trying to subscribe to unknown event: "%s"', type - ); - if (type === 'change') { - _eventHandlers[type].set(handler, DeviceEventEmitter.addListener( - 'appStateDidChange', - (appStateData) => { - handler(appStateData.app_state); - } - )); - } else if (type === 'memoryWarning') { - _eventHandlers[type].set(handler, DeviceEventEmitter.addListener( - 'memoryWarning', - handler - )); - } - }, - - /** - * Remove a handler by passing the `change` event type and the handler - */ - removeEventListener(type, handler) { - invariant( - ['change', 'memoryWarning'].indexOf(type) !== -1, - 'Trying to remove listener for unknown event: "%s"', type - ); - if (!_eventHandlers[type].has(handler)) { - return; - } - _eventHandlers[type].get(handler).remove(); - _eventHandlers[type].delete(handler); - }, - - // TODO: getCurrentAppState callback seems to be called at a really late stage - // after app launch. Trying to get currentState when mounting App component - // will likely to have the initial value here. - // Initialize to 'active' instead of null. - currentState: 'active', - -}; - -DeviceEventEmitter.addListener( - 'appStateDidChange', - (appStateData) => { - AppStateIOS.currentState = appStateData.app_state; - } -); - -AppState.getCurrentAppState( - (appStateData) => { - AppStateIOS.currentState = appStateData.app_state; - }, - logError -); - -module.exports = AppStateIOS; diff --git a/src/api/AsyncStorage.js b/src/api/AsyncStorage.js deleted file mode 100644 index 94655e4..0000000 --- a/src/api/AsyncStorage.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Storage/AsyncStorage.js - */ - -function wrap(value, callback) { - return Promise.resolve(value).then( - obj => { - if (callback) { - callback(null, obj); - } - return obj; - }, - err => { - if (callback) { - callback(err); - } - throw err; - } - ); -} - -let db = {}; - -const AsyncStorage = { - getItem(key, callback) { - return wrap(db[key] || null, callback); - }, - - setItem(key, value, callback) { - db[key] = value; - return wrap(null, callback); - }, - - removeItem(key, callback) { - delete db[key]; - return wrap(null, callback); - }, - - mergeItem(key, value, callback) { - db[key] = Object.assign({}, db[key] || {}, value); - return wrap(null, callback); - }, - - clear(callback) { - db = {}; - return wrap(null, callback); - }, - - getAllKeys(callback) { - return wrap(Object.keys(db), callback); - }, - - flushGetRequests() { - - }, - - multiGet(keys, callback) { - return wrap(keys.map(k => [k, db[k] || null]), callback); - }, - - multiSet(keyValuePairs, callback) { - keyValuePairs.forEach(([key, value]) => { - db[key] = value; - }); - return wrap(null, callback); - }, - - multiRemove(keys, callback) { - keys.forEach(key => delete db[key]); - return wrap(null, callback); - }, - - multiMerge(keyValuePairs, callback) { - keyValuePairs.forEach(([key, value]) => { - db[key] = Object.asign({}, db[key] || {}, value); - }); - return wrap(null, callback); - }, -}; - -module.exports = AsyncStorage; diff --git a/src/api/BackAndroid.js b/src/api/BackAndroid.js deleted file mode 100644 index 2214fdf..0000000 --- a/src/api/BackAndroid.js +++ /dev/null @@ -1,55 +0,0 @@ -import DeviceEventEmitter from '../plugins/DeviceEventEmitter'; -import DeviceEventManager from '../NativeModules/DeviceEventManager'; - -const DEVICE_BACK_EVENT = 'hardwareBackPress'; - -const _backPressSubscriptions = new Set(); - -/** - * Detect hardware back button presses, and programmatically invoke the default back button - * functionality to exit the app if there are no listeners or if none of the listeners return true. - * - * Example: - * - * ```js - * BackAndroid.addEventListener('hardwareBackPress', function() { - * if (!this.onMainScreen()) { - * this.goBack(); - * return true; - * } - * return false; - * }); - * ``` - */ -const BackAndroid = { - - exitApp() { - DeviceEventManager.invokeDefaultBackPressHandler(); - }, - - addEventListener(eventName, handler) { - _backPressSubscriptions.add(handler); - return { - remove: () => BackAndroid.removeEventListener(eventName, handler), - }; - }, - - removeEventListener(eventName, handler) { - _backPressSubscriptions.delete(handler); - }, - -}; - -DeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function () { - let invokeDefault = true; - _backPressSubscriptions.forEach((subscription) => { - if (subscription()) { - invokeDefault = false; - } - }); - if (invokeDefault) { - BackAndroid.exitApp(); - } -}); - -module.exports = BackAndroid; diff --git a/src/api/CameraRoll.js b/src/api/CameraRoll.js deleted file mode 100644 index 02ab154..0000000 --- a/src/api/CameraRoll.js +++ /dev/null @@ -1,107 +0,0 @@ -import invariant from 'invariant'; -import React from 'react'; -import CameraRollManager from '../NativeModules/CameraRollManager'; - -const { PropTypes } = React; - -const GROUP_TYPES_OPTIONS = [ - 'Album', - 'All', - 'Event', - 'Faces', - 'Library', - 'PhotoStream', - 'SavedPhotos', // default -]; - -const ASSET_TYPE_OPTIONS = [ - 'All', - 'Videos', - 'Photos', // default -]; - -/** - * Shape of the param arg for the `getPhotos` function. - */ -const getPhotosParamChecker = PropTypes.shape({ - /** - * The number of photos wanted in reverse order of the photo application - * (i.e. most recent first for SavedPhotos). - */ - first: PropTypes.number.isRequired, - - /** - * A cursor that matches `page_info { end_cursor }` returned from a previous - * call to `getPhotos` - */ - after: PropTypes.string, - - /** - * Specifies which group types to filter the results to. - */ - groupTypes: PropTypes.oneOf(GROUP_TYPES_OPTIONS), - - /** - * Specifies filter on group names, like 'Recent Photos' or custom album - * titles. - */ - groupName: PropTypes.string, - - /** - * Specifies filter on asset type - */ - assetType: PropTypes.oneOf(ASSET_TYPE_OPTIONS), - - /** - * Filter by mimetype (e.g. image/jpeg). - */ - mimeTypes: PropTypes.arrayOf(PropTypes.string), -}); - -class CameraRoll { - - /** - * Saves the image to the camera roll / gallery. - * - * On Android, the tag is a local URI, such as `"file:///sdcard/img.png"`. - * - * On iOS, the tag can be one of the following: - * - * - local URI - * - assets-library tag - * - a tag not matching any of the above, which means the image data will - * be stored in memory (and consume memory as long as the process is alive) - * - * Returns a Promise which when resolved will be passed the new URI. - */ - static saveImageWithTag(tag) { - invariant( - typeof tag === 'string', - 'CameraRoll.saveImageWithTag tag must be a valid string.' - ); - // TODO(lmr): - return CameraRollManager.saveImageWithTag(tag); - } - - /** - * Returns a Promise with photo identifier objects from the local camera - * roll of the device matching shape defined by `getPhotosReturnChecker`. - * - * @param {object} params See `getPhotosParamChecker`. - * - * Returns a Promise which when resolved will be of shape `getPhotosReturnChecker`. - */ - static getPhotos(params) { - if (process.env.NODE_ENV === 'development') { - getPhotosParamChecker({ params }, 'params', 'CameraRoll.getPhotos'); - } - // TODO(lmr): - // TODO: Add the __DEV__ check back in to verify the Promise result - return CameraRollManager.getPhotos(params); - } -} - -CameraRoll.GroupTypesOptions = GROUP_TYPES_OPTIONS; -CameraRoll.AssetTypeOptions = ASSET_TYPE_OPTIONS; - -module.exports = CameraRoll; diff --git a/src/api/DatePickerAndroid.js b/src/api/DatePickerAndroid.js deleted file mode 100644 index f7d403a..0000000 --- a/src/api/DatePickerAndroid.js +++ /dev/null @@ -1,71 +0,0 @@ -import DatePickerModule from '../NativeModules/DatePickerAndroid'; - -/** - * Convert a Date to a timestamp. - */ -function _toMillis(dateVal) { - // Is it a Date object? - if (typeof dateVal === 'object' && typeof dateVal.getMonth === 'function') { - return dateVal.getTime(); - } - return null; -} - -/** - * Opens the standard Android date picker dialog. - * - * ### Example - * - * ``` - * try { - * const {action, year, month, day} = await DatePickerAndroid.open({ - * // Use `new Date()` for current date. - * // May 25 2020. Month 0 is January. - * date: new Date(2020, 4, 25) - * }); - * if (action !== DatePickerAndroid.dismissedAction) { - * // Selected year, month (0-11), day - * } - * } catch ({code, message}) { - * console.warn('Cannot open date picker', message); - * } - * ``` - */ -class DatePickerAndroid { - /** - * Opens the standard Android date picker dialog. - * - * The available keys for the `options` object are: - * * `date` (`Date` object or timestamp in milliseconds) - date to show by default - * * `minDate` (`Date` or timestamp in milliseconds) - minimum date that can be selected - * * `maxDate` (`Date` object or timestamp in milliseconds) - minimum date that can be selected - * - * Returns a Promise which will be invoked an object containing `action`, `year`, `month` (0-11), - * `day` if the user picked a date. If the user dismissed the dialog, the Promise will - * still be resolved with action being `DatePickerAndroid.dismissedAction` and all the other keys - * being undefined. **Always** check whether the `action` before reading the values. - * - * Note the native date picker dialog has some UI glitches on Android 4 and lower - * when using the `minDate` and `maxDate` options. - */ - static open(options) { - const optionsMs = options; - if (optionsMs) { - optionsMs.date = _toMillis(options.date); - optionsMs.minDate = _toMillis(options.minDate); - optionsMs.maxDate = _toMillis(options.maxDate); - } - return DatePickerModule.open(optionsMs); - } - - /** - * A date has been selected. - */ - static get dateSetAction() { return 'dateSetAction'; } - /** - * The dialog has been dismissed. - */ - static get dismissedAction() { return 'dismissedAction'; } -} - -module.exports = DatePickerAndroid; diff --git a/src/api/Dimensions.js b/src/api/Dimensions.js deleted file mode 100644 index 8459193..0000000 --- a/src/api/Dimensions.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Utilities/Dimensions.js - */ -const dimensions = { - // TODO(lmr): find the other dimensions to put in here... - window: { - width: 320, - height: 768, - scale: 2, - fontScale: 2, - }, -}; - -const Dimensions = { - set(dims) { - Object.assign(dimensions, dims); - return true; - }, - get(dim) { - return dimensions[dim]; - }, -}; - -module.exports = Dimensions; diff --git a/src/api/ImagePickerIOS.js b/src/api/ImagePickerIOS.js deleted file mode 100644 index 4cb5001..0000000 --- a/src/api/ImagePickerIOS.js +++ /dev/null @@ -1,28 +0,0 @@ - -import ImagePicker from '../NativeModules/ImagePickerIOS'; - -const ImagePickerIOS = { - canRecordVideos(callback) { - return ImagePicker.canRecordVideos(callback); - }, - canUseCamera(callback) { - return ImagePicker.canUseCamera(callback); - }, - openCameraDialog(config, successCallback, cancelCallback) { - const newConfig = { - videoMode: false, - ...config, - }; - return ImagePicker.openCameraDialog(newConfig, successCallback, cancelCallback); - }, - openSelectDialog(config, successCallback, cancelCallback) { - const newConfig = { - showImages: true, - showVideos: false, - ...config, - }; - return ImagePicker.openSelectDialog(newConfig, successCallback, cancelCallback); - }, -}; - -module.exports = ImagePickerIOS; diff --git a/src/api/IntentAndroid.js b/src/api/IntentAndroid.js deleted file mode 100644 index 23fa450..0000000 --- a/src/api/IntentAndroid.js +++ /dev/null @@ -1,66 +0,0 @@ -import invariant from 'invariant'; -import Linking from './Linking'; - -class IntentAndroid { - - /** - * Starts a corresponding external activity for the given URL. - * - * For example, if the URL is "https://www.facebook.com", the system browser will be opened, - * or the "choose application" dialog will be shown. - * - * You can use other URLs, like a location (e.g. "geo:37.484847,-122.148386"), a contact, - * or any other URL that can be opened with {@code Intent.ACTION_VIEW}. - * - * NOTE: This method will fail if the system doesn't know how to open the specified URL. - * If you're passing in a non-http(s) URL, it's best to check {@code canOpenURL} first. - * - * NOTE: For web URLs, the protocol ("http://", "https://") must be set accordingly! - * - * @deprecated - */ - static openURL(url) { - console.warn( - '"IntentAndroid" is deprecated. Use the promise based "Linking" instead.' - ); - Linking.openURL(url); - } - - /** - * Determine whether or not an installed app can handle a given URL. - * - * You can use other URLs, like a location (e.g. "geo:37.484847,-122.148386"), a contact, - * or any other URL that can be opened with {@code Intent.ACTION_VIEW}. - * - * NOTE: For web URLs, the protocol ("http://", "https://") must be set accordingly! - * - * @param URL the URL to open - * - * @deprecated - */ - static canOpenURL(url, callback) { - invariant( - typeof callback === 'function', - 'A valid callback function is required' - ); - Linking.canOpenURL(url).then(callback); - } - - /** - * If the app launch was triggered by an app link with {@code Intent.ACTION_VIEW}, - * it will give the link url, otherwise it will give `null` - * - * Refer http://developer.android.com/training/app-indexing/deep-linking.html#handling-intents - * - * @deprecated - */ - static getInitialURL(callback) { - invariant( - typeof callback === 'function', - 'A valid callback function is required' - ); - Linking.getInitialURL().then(callback); - } -} - -module.exports = IntentAndroid; diff --git a/src/api/InteractionManager.js b/src/api/InteractionManager.js deleted file mode 100644 index 21c2371..0000000 --- a/src/api/InteractionManager.js +++ /dev/null @@ -1,69 +0,0 @@ -import keyMirror from 'keymirror'; -import invariant from 'invariant'; - -const { EventEmitter } = require('events'); - -const _emitter = new EventEmitter(); - -let _inc = 0; -let _deadline = -1; // eslint-disable-line no-unused-vars - -const InteractionManager = { - Events: keyMirror({ - interactionStart: true, - interactionComplete: true, - }), - - /** - * Schedule a function to run after all interactions have completed. - */ - runAfterInteractions(task) { - return new Promise(resolve => { - // TODO(lmr): - // _scheduleUpdate(); - // if (task) { - // _taskQueue.enqueue(task); - // } - // const name = task && task.name || '?'; - // _taskQueue.enqueue({ run: resolve, name: 'resolve ' + name }); - }); - }, - - /** - * Notify manager that an interaction has started. - */ - createInteractionHandle() { - // TODO(lmr): - // _scheduleUpdate(); - const handle = ++_inc; - // _addInteractionSet.add(handle); - return handle; - }, - - /** - * Notify manager that an interaction has completed. - */ - clearInteractionHandle(handle) { - invariant( - !!handle, - 'Must provide a handle to clear.' - ); - // TODO(lmr): - // _scheduleUpdate(); - // _addInteractionSet.delete(handle); - // _deleteInteractionSet.add(handle); - }, - - addListener: _emitter.addListener.bind(_emitter), - - /** - * A positive number will use setTimeout to schedule any tasks after the - * eventLoopRunningTime hits the deadline value, otherwise all tasks will be - * executed in one setImmediate batch (default). - */ - setDeadline(deadline) { - _deadline = deadline; - }, -}; - -module.exports = InteractionManager; diff --git a/src/api/Keyboard.js b/src/api/Keyboard.js deleted file mode 100644 index af21cf5..0000000 --- a/src/api/Keyboard.js +++ /dev/null @@ -1,12 +0,0 @@ -const Keyboard = { - addListener(eventname, handler) { - return { - remove: () => {} - }; - }, - removeListener: () => {}, - removeAllListeners: () => {}, - dismiss: () => {} -}; - -module.exports = Keyboard; diff --git a/src/api/LayoutAnimation.js b/src/api/LayoutAnimation.js deleted file mode 100644 index d5715ed..0000000 --- a/src/api/LayoutAnimation.js +++ /dev/null @@ -1,124 +0,0 @@ -import React from 'react'; -import UIManager from '../NativeModules/UIManager'; -import keyMirror from 'keymirror'; - -const { PropTypes } = React; - -const TypesEnum = { - spring: true, - linear: true, - easeInEaseOut: true, - easeIn: true, - easeOut: true, - keyboard: true, -}; - -const Types = keyMirror(TypesEnum); - -const PropertiesEnum = { - opacity: true, - scaleXY: true, -}; - -const Properties = keyMirror(PropertiesEnum); - -const animChecker = PropTypes.shape({ - duration: PropTypes.number, - delay: PropTypes.number, - springDamping: PropTypes.number, - initialVelocity: PropTypes.number, - type: PropTypes.oneOf( - Object.keys(Types) - ), - property: PropTypes.oneOf( // Only applies to create/delete - Object.keys(Properties) - ), -}); - -const configChecker = PropTypes.shape({ - duration: PropTypes.number.isRequired, - create: animChecker, - update: animChecker, - delete: animChecker, -}); - -const nop = () => {}; - -function configureNext(config, onAnimationDidEnd) { - configChecker({ config }, 'config', 'LayoutAnimation.configureNext'); - UIManager.configureNextLayoutAnimation( - config, - onAnimationDidEnd || nop, - nop - ); -} - -function create(duration, type, creationProp) { - return { - duration, - create: { - type, - property: creationProp, - }, - update: { - type, - }, - }; -} - -const Presets = { - easeInEaseOut: create( - 300, Types.easeInEaseOut, Properties.opacity - ), - linear: create( - 500, Types.linear, Properties.opacity - ), - spring: { - duration: 700, - create: { - type: Types.linear, - property: Properties.opacity, - }, - update: { - type: Types.spring, - springDamping: 0.4, - }, - }, -}; - -const LayoutAnimation = { - /** - * Schedules an animation to happen on the next layout. - * - * @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) - * - * @param onAnimationDidEnd Called when the animation finished. - * Only supported on iOS. - * @param onError Called on error. Only supported on iOS. - */ - configureNext, - /** - * Helper for creating a config for `configureNext`. - */ - create, - Types, - Properties, - configChecker, - Presets, - easeInEaseOut: configureNext.bind( - null, Presets.easeInEaseOut - ), - linear: configureNext.bind( - null, Presets.linear - ), - spring: configureNext.bind( - null, Presets.spring - ), -}; - -module.exports = LayoutAnimation; diff --git a/src/api/Linking.js b/src/api/Linking.js deleted file mode 100644 index d01f726..0000000 --- a/src/api/Linking.js +++ /dev/null @@ -1,121 +0,0 @@ -import invariant from 'invariant'; -import Platform from '../plugins/Platform'; -import DeviceEventEmitter from '../plugins/DeviceEventEmitter'; -import LinkingManager from '../NativeModules/LinkingManager'; -import IntentAndroid from './IntentAndroid'; -import LinkingManagerIOS from './LinkingIOS'; - -const _notifHandlers = new Map(); - -const DEVICE_NOTIF_EVENT = 'openURL'; - -// TODO(lmr): -class Linking { - /** - * Add a handler to Linking changes by listening to the `url` event type - * and providing the handler - * - * @platform ios - */ - static addEventListener(type, handler) { - if (Platform.OS === 'android') { - console.warn( - 'Linking.addEventListener is not supported on Android' - ); - } else { - invariant( - type === 'url', - 'Linking only supports `url` events' - ); - const listener = DeviceEventEmitter.addListener( - DEVICE_NOTIF_EVENT, - handler - ); - _notifHandlers.set(handler, listener); - } - } - - /** - * Remove a handler by passing the `url` event type and the handler - * - * @platform ios - */ - static removeEventListener(type, handler) { - if (Platform.OS === 'android') { - console.warn( - 'Linking.removeEventListener is not supported on Android' - ); - } else { - invariant( - type === 'url', - 'Linking only supports `url` events' - ); - const listener = _notifHandlers.get(handler); - if (!listener) { - return; - } - listener.removeListener( - DEVICE_NOTIF_EVENT, - handler - ); - _notifHandlers.delete(handler); - } - } - - /** - * Try to open the given `url` with any of the installed apps. - * - * You can use other URLs, like a location (e.g. "geo:37.484847,-122.148386"), a contact, - * or any other URL that can be opened with the installed apps. - * - * NOTE: This method will fail if the system doesn't know how to open the specified URL. - * If you're passing in a non-http(s) URL, it's best to check {@code canOpenURL} first. - * - * NOTE: For web URLs, the protocol ("http://", "https://") must be set accordingly! - */ - static openURL(url) { - this._validateURL(url); - return LinkingManager.openURL(url); - } - - /** - * Determine whether or not an installed app can handle a given URL. - * - * NOTE: For web URLs, the protocol ("http://", "https://") must be set accordingly! - * - * NOTE: As of iOS 9, your app needs to provide the `LSApplicationQueriesSchemes` key - * inside `Info.plist`. - * - * @param URL the URL to open - */ - static canOpenURL(url) { - this._validateURL(url); - return LinkingManager.canOpenURL(url); - } - - /** - * If the app launch was triggered by an app link with, - * it will give the link url, otherwise it will give `null` - * - * NOTE: To support deep linking on Android, refer http://developer.android.com/training/app-indexing/deep-linking.html#handling-intents - */ - static getInitialURL() { - if (Platform.OS === 'android') { - return IntentAndroid.getInitialURL(); - } - return Promise.resolve(LinkingManagerIOS.initialURL); - } - - static _validateURL(url) { - invariant( - typeof url === 'string', - `Invalid URL: should be a string. Was: ${url}` - ); - invariant( - url, - 'Invalid URL: cannot be empty' - ); - } -} - -module.exports = Linking; diff --git a/src/api/LinkingIOS.js b/src/api/LinkingIOS.js deleted file mode 100644 index 49fae0b..0000000 --- a/src/api/LinkingIOS.js +++ /dev/null @@ -1,78 +0,0 @@ -import LinkingManager from '../NativeModules/LinkingManager'; -import Linking from './Linking'; -import invariant from 'invariant'; - -let _initialURL = LinkingManager && LinkingManager.initialURL; - -class LinkingIOS { - /** - * Add a handler to LinkingIOS changes by listening to the `url` event type - * and providing the handler - * - * @deprecated - */ - static addEventListener(type, handler) { - console.warn( - '"LinkingIOS.addEventListener" is deprecated. Use "Linking.addEventListener" instead.' - ); - Linking.addEventListener(type, handler); - } - - /** - * Remove a handler by passing the `url` event type and the handler - * - * @deprecated - */ - static removeEventListener(type, handler) { - console.warn( - '"LinkingIOS.removeEventListener" is deprecated. Use "Linking.removeEventListener" instead.' - ); - Linking.removeEventListener(type, handler); - } - - /** - * Try to open the given `url` with any of the installed apps. - * - * @deprecated - */ - static openURL(url) { - console.warn( - '"LinkingIOS.openURL" is deprecated. Use the promise based "Linking.openURL" instead.' - ); - Linking.openURL(url); - } - - /** - * Determine whether or not an installed app can handle a given URL. - * The callback function will be called with `bool supported` as the only argument - * - * NOTE: As of iOS 9, your app needs to provide the `LSApplicationQueriesSchemes` key - * inside `Info.plist`. - * - * @deprecated - */ - static canOpenURL(url, callback) { - console.warn( - '"LinkingIOS.canOpenURL" is deprecated. Use the promise based "Linking.canOpenURL" instead.' - ); - invariant( - typeof callback === 'function', - 'A valid callback function is required' - ); - Linking.canOpenURL(url).then(callback); - } - - /** - * If the app launch was triggered by an app link, it will pop the link url, - * otherwise it will return `null` - * - * @deprecated - */ - static popInitialURL() { - const initialURL = _initialURL; - _initialURL = null; - return initialURL; - } -} - -module.exports = LinkingIOS; diff --git a/src/api/ListViewDataSource.js b/src/api/ListViewDataSource.js deleted file mode 100644 index 46d28e0..0000000 --- a/src/api/ListViewDataSource.js +++ /dev/null @@ -1,27 +0,0 @@ - - -class ListViewDataSource { - constructor() { - this._dataBlob = null; - } - - getRowCount() { - - } - - cloneWithRows(data) { - const newSource = new ListViewDataSource(); - newSource._dataBlob = data; - - return newSource; - } - - cloneWithRowsAndSections(data) { - const newSource = new ListViewDataSource(); - newSource._dataBlob = data; - - return newSource; - } -} - -module.exports = ListViewDataSource; diff --git a/src/api/NetInfo.js b/src/api/NetInfo.js deleted file mode 100644 index 393847f..0000000 --- a/src/api/NetInfo.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Network/NetInfo.js - */ -import Platform from '../plugins/Platform'; -import DeviceEventEmitter from '../plugins/DeviceEventEmitter'; - -const DEVICE_CONNECTIVITY_EVENT = 'networkStatusDidChange'; -const _subscriptions = new Map(); - -let isExpensive = false; -let networkInfo = { - connected: true -}; - - -const NetInfo = { - addEventListener(eventname, handler) { - const listener = DeviceEventEmitter.addListener( - DEVICE_CONNECTIVITY_EVENT, - ({ network_info }) => handler(network_info) - ); - _subscriptions.set(handler, listener); - }, - - removeEventListener(eventName, handler) { - const listener = _subscriptions.get(handler); - if (!listener) { - return; - } - listener.remove(); - _subscriptions.delete(handler); - }, - - fetch() { - return Promise.resolve(networkInfo); - }, - - isConnected: { - addEventListener(eventname, handler) { - - }, - - removeEventListener(eventName, handler) { - - }, - fetch() { - return NetInfo.fetch().then(info => info.connected); - }, - }, - - isConnectionExpensive(callback) { - if (Platform.OS === 'android') { - callback(isExpensive); - } else { - callback(null, 'Unsupported'); - } - }, - - // TODO(lmr): figure out a good way to expose setters here. - __setNetworkInfo(info) { - networkInfo = info; - }, - __setIsConnectionExpensive(expensive) { - isExpensive = expensive; - }, - __setIsConnected(connected) { - networkInfo = Object.assign({}, networkInfo, { connected }); - }, -}; - -module.exports = NetInfo; diff --git a/src/api/PanResponder.js b/src/api/PanResponder.js deleted file mode 100644 index d344162..0000000 --- a/src/api/PanResponder.js +++ /dev/null @@ -1,386 +0,0 @@ -import TouchHistoryMath from './TouchHistoryMath'; - -const currentCentroidXOfTouchesChangedAfter = - TouchHistoryMath.currentCentroidXOfTouchesChangedAfter; -const currentCentroidYOfTouchesChangedAfter = - TouchHistoryMath.currentCentroidYOfTouchesChangedAfter; -const previousCentroidXOfTouchesChangedAfter = - TouchHistoryMath.previousCentroidXOfTouchesChangedAfter; -const previousCentroidYOfTouchesChangedAfter = - TouchHistoryMath.previousCentroidYOfTouchesChangedAfter; -const currentCentroidX = TouchHistoryMath.currentCentroidX; -const currentCentroidY = TouchHistoryMath.currentCentroidY; - -/** - * `PanResponder` reconciles several touches into a single gesture. It makes - * single-touch gestures resilient to extra touches, and can be used to - * recognize simple multi-touch gestures. - * - * It provides a predictable wrapper of the responder handlers provided by the - * [gesture responder system](/react-native/docs/gesture-responder-system.html). - * For each handler, it provides a new `gestureState` object alongside the - * native event object: - * - * ``` - * onPanResponderMove: (event, gestureState) => {} - * ``` - * - * A native event is a synthetic touch event with the following form: - * - * - `nativeEvent` - * + `changedTouches` - Array of all touch events that have changed since the last event - * + `identifier` - The ID of the touch - * + `locationX` - The X position of the touch, relative to the element - * + `locationY` - The Y position of the touch, relative to the element - * + `pageX` - The X position of the touch, relative to the root element - * + `pageY` - The Y position of the touch, relative to the root element - * + `target` - The node id of the element receiving the touch event - * + `timestamp` - A time identifier for the touch, useful for velocity calculation - * + `touches` - Array of all current touches on the screen - * - * A `gestureState` object has the following: - * - * - `stateID` - ID of the gestureState- persisted as long as there at least - * one touch on screen - * - `moveX` - the latest screen coordinates of the recently-moved touch - * - `moveY` - the latest screen coordinates of the recently-moved touch - * - `x0` - the screen coordinates of the responder grant - * - `y0` - the screen coordinates of the responder grant - * - `dx` - accumulated distance of the gesture since the touch started - * - `dy` - accumulated distance of the gesture since the touch started - * - `vx` - current velocity of the gesture - * - `vy` - current velocity of the gesture - * - `numberActiveTouches` - Number of touches currently on screen - * - * ### Basic Usage - * - * ``` - * componentWillMount: function() { - * this._panResponder = PanResponder.create({ - * // Ask to be the responder: - * onStartShouldSetPanResponder: (evt, gestureState) => true, - * onStartShouldSetPanResponderCapture: (evt, gestureState) => true, - * onMoveShouldSetPanResponder: (evt, gestureState) => true, - * onMoveShouldSetPanResponderCapture: (evt, gestureState) => true, - * - * onPanResponderGrant: (evt, gestureState) => { - * // The guesture has started. Show visual feedback so the user knows - * // what is happening! - * - * // gestureState.{x,y}0 will be set to zero now - * }, - * onPanResponderMove: (evt, gestureState) => { - * // The most recent move distance is gestureState.move{X,Y} - * - * // The accumulated gesture distance since becoming responder is - * // gestureState.d{x,y} - * }, - * onPanResponderTerminationRequest: (evt, gestureState) => true, - * onPanResponderRelease: (evt, gestureState) => { - * // The user has released all touches while this view is the - * // responder. This typically means a gesture has succeeded - * }, - * onPanResponderTerminate: (evt, gestureState) => { - * // Another component has become the responder, so this gesture - * // should be cancelled - * }, - * onShouldBlockNativeResponder: (evt, gestureState) => { - * // Returns whether this component should block native components from becoming the JS - * // responder. Returns true by default. Is currently only supported on android. - * return true; - * }, - * }); - * }, - * - * render: function() { - * return ( - * - * ); - * }, - * - * ``` - * - * ### Working Example - * - * To see it in action, try the - * [PanResponder example in UIExplorer](https://github.com/facebook/react-native/blob/master/Examples/UIExplorer/PanResponderExample.js) - */ - -const PanResponder = { - - /** - * - * A graphical explanation of the touch data flow: - * - * +----------------------------+ +--------------------------------+ - * | ResponderTouchHistoryStore | |TouchHistoryMath | - * +----------------------------+ +----------+---------------------+ - * |Global store of touchHistory| |Allocation-less math util | - * |including activeness, start | |on touch history (centroids | - * |position, prev/cur position.| |and multitouch movement etc) | - * | | | | - * +----^-----------------------+ +----^---------------------------+ - * | | - * | (records relevant history | - * | of touches relevant for | - * | implementing higher level | - * | gestures) | - * | | - * +----+-----------------------+ +----|---------------------------+ - * | ResponderEventPlugin | | | Your App/Component | - * +----------------------------+ +----|---------------------------+ - * |Negotiates which view gets | Low level | | High level | - * |onResponderMove events. | events w/ | +-+-------+ events w/ | - * |Also records history into | touchHistory| | Pan | multitouch + | - * |ResponderTouchHistoryStore. +---------------->Responder+-----> accumulative| - * +----------------------------+ attached to | | | distance and | - * each event | +---------+ velocity. | - * | | - * | | - * +--------------------------------+ - * - * - * - * Gesture that calculates cumulative movement over time in a way that just - * "does the right thing" for multiple touches. The "right thing" is very - * nuanced. When moving two touches in opposite directions, the cumulative - * distance is zero in each dimension. When two touches move in parallel five - * pixels in the same direction, the cumulative distance is five, not ten. If - * two touches start, one moves five in a direction, then stops and the other - * touch moves fives in the same direction, the cumulative distance is ten. - * - * This logic requires a kind of processing of time "clusters" of touch events - * so that two touch moves that essentially occur in parallel but move every - * other frame respectively, are considered part of the same movement. - * - * Explanation of some of the non-obvious fields: - * - * - moveX/moveY: If no move event has been observed, then `(moveX, moveY)` is - * invalid. If a move event has been observed, `(moveX, moveY)` is the - * centroid of the most recently moved "cluster" of active touches. - * (Currently all move have the same timeStamp, but later we should add some - * threshold for what is considered to be "moving"). If a palm is - * accidentally counted as a touch, but a finger is moving greatly, the palm - * will move slightly, but we only want to count the single moving touch. - * - x0/y0: Centroid location (non-cumulative) at the time of becoming - * responder. - * - dx/dy: Cumulative touch distance - not the same thing as sum of each touch - * distance. Accounts for touch moves that are clustered together in time, - * moving the same direction. Only valid when currently responder (otherwise, - * it only represents the drag distance below the threshold). - * - vx/vy: Velocity. - */ - - _initializeGestureState(gestureState) { - const newGestureState = gestureState; - newGestureState.moveX = 0; - newGestureState.moveY = 0; - newGestureState.x0 = 0; - newGestureState.y0 = 0; - newGestureState.dx = 0; - newGestureState.dy = 0; - newGestureState.vx = 0; - newGestureState.vy = 0; - newGestureState.numberActiveTouches = 0; - newGestureState._accountsForMovesUpTo = 0; - }, - - /** - * This is nuanced and is necessary. It is incorrect to continuously take all - * active *and* recently moved touches, find the centroid, and track how that - * result changes over time. Instead, we must take all recently moved - * touches, and calculate how the centroid has changed just for those - * recently moved touches, and append that change to an accumulator. This is - * to (at least) handle the case where the user is moving three fingers, and - * then one of the fingers stops but the other two continue. - * - * This is very different than taking all of the recently moved touches and - * storing their centroid as `dx/dy`. For correctness, we must *accumulate - * changes* in the centroid of recently moved touches. - * - * There is also some nuance with how we handle multiple moved touches in a - * single event. With the way `ReactNativeEventEmitter` dispatches touches as - * individual events, multiple touches generate two 'move' events, each of - * them triggering `onResponderMove`. But with the way `PanResponder` works, - * all of the gesture inference is performed on the first dispatch, since it - * looks at all of the touches (even the ones for which there hasn't been a - * native dispatch yet). Therefore, `PanResponder` does not call - * `onResponderMove` passed the first dispatch. This diverges from the - * typical responder callback pattern (without using `PanResponder`), but - * avoids more dispatches than necessary. - */ - _updateGestureStateOnMove(gestureState, touchHistory) { - const newGestureState = gestureState; - newGestureState.numberActiveTouches = touchHistory.numberActiveTouches; - newGestureState.moveX = currentCentroidXOfTouchesChangedAfter( - touchHistory, - newGestureState._accountsForMovesUpTo - ); - newGestureState.moveY = currentCentroidYOfTouchesChangedAfter( - touchHistory, - newGestureState._accountsForMovesUpTo - ); - const movedAfter = newGestureState._accountsForMovesUpTo; - const prevX = previousCentroidXOfTouchesChangedAfter(touchHistory, movedAfter); - const x = currentCentroidXOfTouchesChangedAfter(touchHistory, movedAfter); - const prevY = previousCentroidYOfTouchesChangedAfter(touchHistory, movedAfter); - const y = currentCentroidYOfTouchesChangedAfter(touchHistory, movedAfter); - const nextDX = newGestureState.dx + (x - prevX); - const nextDY = newGestureState.dy + (y - prevY); - - // TODO: This must be filtered intelligently. - const dt = - (touchHistory.mostRecentTimeStamp - newGestureState._accountsForMovesUpTo); - newGestureState.vx = (nextDX - newGestureState.dx) / dt; - newGestureState.vy = (nextDY - newGestureState.dy) / dt; - - newGestureState.dx = nextDX; - newGestureState.dy = nextDY; - newGestureState._accountsForMovesUpTo = touchHistory.mostRecentTimeStamp; - }, - - /** - * @param {object} config Enhanced versions of all of the responder callbacks - * that provide not only the typical `ResponderSyntheticEvent`, but also the - * `PanResponder` gesture state. Simply replace the word `Responder` with - * `PanResponder` in each of the typical `onResponder*` callbacks. For - * example, the `config` object would look like: - * - * - `onMoveShouldSetPanResponder: (e, gestureState) => {...}` - * - `onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}` - * - `onStartShouldSetPanResponder: (e, gestureState) => {...}` - * - `onStartShouldSetPanResponderCapture: (e, gestureState) => {...}` - * - `onPanResponderReject: (e, gestureState) => {...}` - * - `onPanResponderGrant: (e, gestureState) => {...}` - * - `onPanResponderStart: (e, gestureState) => {...}` - * - `onPanResponderEnd: (e, gestureState) => {...}` - * - `onPanResponderRelease: (e, gestureState) => {...}` - * - `onPanResponderMove: (e, gestureState) => {...}` - * - `onPanResponderTerminate: (e, gestureState) => {...}` - * - `onPanResponderTerminationRequest: (e, gestureState) => {...}` - * - `onShouldBlockNativeResponder: (e, gestureState) => {...}` - * - * In general, for events that have capture equivalents, we update the - * gestureState once in the capture phase and can use it in the bubble phase - * as well. - * - * Be careful with onStartShould* callbacks. They only reflect updated - * `gestureState` for start/end events that bubble/capture to the Node. - * Once the node is the responder, you can rely on every start/end event - * being processed by the gesture and `gestureState` being updated - * accordingly. (numberActiveTouches) may not be totally accurate unless you - * are the responder. - */ - create(config) { - const gestureState = { - // Useful for debugging - stateID: Math.random(), - }; - PanResponder._initializeGestureState(gestureState); - const panHandlers = { - onStartShouldSetResponder(e) { - return config.onStartShouldSetPanResponder === undefined ? false : - config.onStartShouldSetPanResponder(e, gestureState); - }, - onMoveShouldSetResponder(e) { - return config.onMoveShouldSetPanResponder === undefined ? false : - config.onMoveShouldSetPanResponder(e, gestureState); - }, - onStartShouldSetResponderCapture(e) { - // TODO: Actually, we should reinitialize the state any time - // touches.length increases from 0 active to > 0 active. - if (e.nativeEvent.touches.length === 1) { - PanResponder._initializeGestureState(gestureState); - } - gestureState.numberActiveTouches = e.touchHistory.numberActiveTouches; - return config.onStartShouldSetPanResponderCapture !== undefined ? - config.onStartShouldSetPanResponderCapture(e, gestureState) : false; - }, - - onMoveShouldSetResponderCapture(e) { - const touchHistory = e.touchHistory; - // Responder system incorrectly dispatches should* to current responder - // Filter out any touch moves past the first one - we would have - // already processed multi-touch geometry during the first event. - if (gestureState._accountsForMovesUpTo === touchHistory.mostRecentTimeStamp) { - return false; - } - PanResponder._updateGestureStateOnMove(gestureState, touchHistory); - return config.onMoveShouldSetPanResponderCapture ? - config.onMoveShouldSetPanResponderCapture(e, gestureState) : false; - }, - - onResponderGrant(e) { - gestureState.x0 = currentCentroidX(e.touchHistory); - gestureState.y0 = currentCentroidY(e.touchHistory); - gestureState.dx = 0; - gestureState.dy = 0; - if (config.onPanResponderGrant) { - config.onPanResponderGrant(e, gestureState); - } - // TODO: t7467124 investigate if this can be removed - return config.onShouldBlockNativeResponder === undefined ? true : - config.onShouldBlockNativeResponder(); - }, - - onResponderReject(e) { - if (config.onPanResponderReject) { - config.onPanResponderReject(e, gestureState); - } - }, - - onResponderRelease(e) { - if (config.onPanResponderRelease) { - config.onPanResponderRelease(e, gestureState); - } - PanResponder._initializeGestureState(gestureState); - }, - - onResponderStart(e) { - const touchHistory = e.touchHistory; - gestureState.numberActiveTouches = touchHistory.numberActiveTouches; - if (config.onPanResponderStart) { - config.onPanResponderStart(e, gestureState); - } - }, - - onResponderMove(e) { - const touchHistory = e.touchHistory; - // Guard against the dispatch of two touch moves when there are two - // simultaneously changed touches. - if (gestureState._accountsForMovesUpTo === touchHistory.mostRecentTimeStamp) { - return; - } - // Filter out any touch moves past the first one - we would have - // already processed multi-touch geometry during the first event. - PanResponder._updateGestureStateOnMove(gestureState, touchHistory); - if (config.onPanResponderMove) { - config.onPanResponderMove(e, gestureState); - } - }, - - onResponderEnd(e) { - const touchHistory = e.touchHistory; - gestureState.numberActiveTouches = touchHistory.numberActiveTouches; - if (config.onPanResponderEnd) { - config.onPanResponderEnd(e, gestureState); - } - }, - - onResponderTerminate(e) { - if (config.onPanResponderTerminate) { - config.onPanResponderTerminate(e, gestureState); - } - PanResponder._initializeGestureState(gestureState); - }, - - onResponderTerminationRequest(e) { - return config.onPanResponderTerminationRequest === undefined ? true : - config.onPanResponderTerminationRequest(e, gestureState); - }, - }; - return { panHandlers }; - }, -}; - -module.exports = PanResponder; diff --git a/src/api/PixelRatio.js b/src/api/PixelRatio.js deleted file mode 100644 index 3978a31..0000000 --- a/src/api/PixelRatio.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Utilities/PixelRatio.js - */ -const PixelRatio = { - get() { - return 2; - }, - getFontScale() { - return 2; - }, - getPixelSizeForLayoutSize(layoutSize) { - return Math.round(layoutSize * PixelRatio.get()); - }, - roundToNearestPixel(layoutSize) { - const ratio = PixelRatio.get(); - return Math.round(layoutSize * ratio) / ratio; - }, - startDetecting() { - - }, -}; - -module.exports = PixelRatio; diff --git a/src/api/PushNotificationIOS.js b/src/api/PushNotificationIOS.js deleted file mode 100644 index 9884e12..0000000 --- a/src/api/PushNotificationIOS.js +++ /dev/null @@ -1,231 +0,0 @@ -import invariant from 'invariant'; -import DeviceEventEmitter from '../plugins/DeviceEventEmitter'; - -const _notifHandlers = new Map(); -let _initialNotification = null; - -const DEVICE_NOTIF_EVENT = 'remoteNotificationReceived'; -const NOTIF_REGISTER_EVENT = 'remoteNotificationsRegistered'; - -class PushNotificationIOS { - /** - * Schedules the localNotification for immediate presentation. - * - * details is an object containing: - * - * - `alertBody` : The message displayed in the notification alert. - * - `soundName` : The sound played when the notification is fired (optional). - * - */ - static presentLocalNotification(details) { - - } - - /** - * Schedules the localNotification for future presentation. - * - * details is an object containing: - * - * - `fireDate` : The date and time when the system should deliver the notification. - * - `alertBody` : The message displayed in the notification alert. - * - `soundName` : The sound played when the notification is fired (optional). - * - */ - static scheduleLocalNotification(details) { - - } - - /** - * Cancels all scheduled localNotifications - */ - static cancelAllLocalNotifications() { - - } - - /** - * Sets the badge number for the app icon on the home screen - */ - static setApplicationIconBadgeNumber(number) { - - } - - /** - * Gets the current badge number for the app icon on the home screen - */ - static getApplicationIconBadgeNumber(callback) { - - } - - /** - * Attaches a listener to remote notification events while the app is running - * in the foreground or the background. - * - * Valid events are: - * - * - `notification` : Fired when a remote notification is received. The - * handler will be invoked with an instance of `PushNotificationIOS`. - * - `register`: Fired when the user registers for remote notifications. The - * handler will be invoked with a hex string representing the deviceToken. - */ - static addEventListener(type, handler) { - invariant( - type === 'notification' || type === 'register', - 'PushNotificationIOS only supports `notification` and `register` events' - ); - let listener; - if (type === 'notification') { - listener = DeviceEventEmitter.addListener( - DEVICE_NOTIF_EVENT, - (notifData) => { - handler(new PushNotificationIOS(notifData)); - } - ); - } else if (type === 'register') { - listener = DeviceEventEmitter.addListener( - NOTIF_REGISTER_EVENT, - (registrationInfo) => { - handler(registrationInfo.deviceToken); - } - ); - } - _notifHandlers.set(handler, listener); - } - - /** - * Requests notification permissions from iOS, prompting the user's - * dialog box. By default, it will request all notification permissions, but - * a subset of these can be requested by passing a map of requested - * permissions. - * The following permissions are supported: - * - * - `alert` - * - `badge` - * - `sound` - * - * If a map is provided to the method, only the permissions with truthy values - * will be requested. - */ - static requestPermissions(permissions) { - - } - - /** - * Unregister for all remote notifications received via Apple Push Notification service. - * - * You should call this method in rare circumstances only, such as when a new version of - * the app removes support for all types of remote notifications. Users can temporarily - * prevent apps from receiving remote notifications through the Notifications section of - * the Settings app. Apps unregistered through this method can always re-register. - */ - static abandonPermissions() { - - } - - /** - * See what push permissions are currently enabled. `callback` will be - * invoked with a `permissions` object: - * - * - `alert` :boolean - * - `badge` :boolean - * - `sound` :boolean - */ - static checkPermissions(callback) { - invariant( - typeof callback === 'function', - 'Must provide a valid callback' - ); - } - - /** - * Removes the event listener. Do this in `componentWillUnmount` to prevent - * memory leaks - */ - static removeEventListener(type, handler) { - invariant( - type === 'notification' || type === 'register', - 'PushNotificationIOS only supports `notification` and `register` events' - ); - const listener = _notifHandlers.get(handler); - if (!listener) { - return; - } - listener.remove(); - _notifHandlers.delete(handler); - } - - /** - * An initial notification will be available if the app was cold-launched - * from a notification. - * - * The first caller of `popInitialNotification` will get the initial - * notification object, or `null`. Subsequent invocations will return null. - */ - static popInitialNotification() { - const initialNotification = _initialNotification && - new PushNotificationIOS(_initialNotification); - _initialNotification = null; - return initialNotification; - } - - /** - * You will never need to instantiate `PushNotificationIOS` yourself. - * Listening to the `notification` event and invoking - * `popInitialNotification` is sufficient - */ - constructor(nativeNotif) { - this._data = {}; - - // Extract data from Apple's `aps` dict as defined: - - // https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html - - Object.keys(nativeNotif).forEach((notifKey) => { - const notifVal = nativeNotif[notifKey]; - if (notifKey === 'aps') { - this._alert = notifVal.alert; - this._sound = notifVal.sound; - this._badgeCount = notifVal.badge; - } else { - this._data[notifKey] = notifVal; - } - }); - } - - /** - * An alias for `getAlert` to get the notification's main message string - */ - getMessage() { - // alias because "alert" is an ambiguous name - return this._alert; - } - - /** - * Gets the sound string from the `aps` object - */ - getSound() { - return this._sound; - } - - /** - * Gets the notification's main message from the `aps` object - */ - getAlert() { - return this._alert; - } - - /** - * Gets the badge count number from the `aps` object - */ - getBadgeCount() { - return this._badgeCount; - } - - /** - * Gets the data object on the notif - */ - getData() { - return this._data; - } -} - -module.exports = PushNotificationIOS; diff --git a/src/api/Settings.js b/src/api/Settings.js deleted file mode 100644 index 02e924a..0000000 --- a/src/api/Settings.js +++ /dev/null @@ -1,68 +0,0 @@ -import invariant from 'invariant'; -import DeviceEventEmitter from '../plugins/DeviceEventEmitter'; - -const subscriptions = []; - -const Settings = { - _settings: {}, - - get(key) { - return this._settings[key]; - }, - - set(settings) { - this._settings = Object.assign(this._settings, settings); - }, - - watchKeys(keys, callback) { - let newKeys = keys; - if (typeof keys === 'string') { - newKeys = [keys]; - } - - invariant( - Array.isArray(newKeys), - 'keys should be a string or array of strings' - ); - - const sid = subscriptions.length; - subscriptions.push({ keys: newKeys, callback }); - return sid; - }, - - clearWatch(watchId) { - if (watchId < subscriptions.length) { - subscriptions[watchId] = { - keys: [], - callback: null, - }; - } - }, - - _sendObservations(body) { - Object.keys(body).forEach((key) => { - const newValue = body[key]; - const didChange = this._settings[key] !== newValue; - this._settings[key] = newValue; - - if (didChange) { - subscriptions.forEach((sub) => { - if (sub.keys.indexOf(key) !== -1 && sub.callback) { - sub.callback(); - } - }); - } - }); - }, - - __emulateDeviceSettingsChange(settings) { - DeviceEventEmitter.emit('settingsUpdated', settings); - }, -}; - -DeviceEventEmitter.addListener( - 'settingsUpdated', - Settings._sendObservations.bind(Settings) -); - -module.exports = Settings; diff --git a/src/api/StatusBarIOS.js b/src/api/StatusBarIOS.js deleted file mode 100644 index 7410329..0000000 --- a/src/api/StatusBarIOS.js +++ /dev/null @@ -1,32 +0,0 @@ -let _style = {}; -let _hidden = false; -let _networkActivityIndicatorVisible = true; - -const StatusBarIOS = { - - setStyle(style, animated) { - _style = style; - }, - - setHidden(hidden, animation) { - _hidden = hidden; - }, - - setNetworkActivityIndicatorVisible(visible) { - _networkActivityIndicatorVisible = visible; - }, - - __getStyle() { - return _style; - }, - - __getHidden() { - return _hidden; - }, - - __getNetworkActivityIndicatorVisible() { - return _networkActivityIndicatorVisible; - }, -}; - -module.exports = StatusBarIOS; diff --git a/src/api/StyleSheet.js b/src/api/StyleSheet.js deleted file mode 100644 index aef5363..0000000 --- a/src/api/StyleSheet.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/StyleSheet.js - */ -const StyleSheet = { - create(styles) { - return styles; - }, - flatten(styles) { - if (Array.isArray(styles)) { - return Object.assign({}, ...styles.map(StyleSheet.flatten)); - } - - return styles; - } -}; - -module.exports = StyleSheet; diff --git a/src/api/TextInputState.js b/src/api/TextInputState.js deleted file mode 100644 index fd9a4de..0000000 --- a/src/api/TextInputState.js +++ /dev/null @@ -1,39 +0,0 @@ - -const TextInputState = { - /** - * Internal state - */ - _currentlyFocusedID: null, - - /** - * Returns the ID of the currently focused text field, if one exists - * If no text field is focused it returns null - */ - currentlyFocusedField() { - return this._currentlyFocusedID; - }, - - /** - * @param {number} TextInputID id of the text field to focus - * Focuses the specified text field - * noop if the text field was already focused - */ - focusTextInput(textFieldID) { - if (this._currentlyFocusedID !== textFieldID && textFieldID !== null) { - this._currentlyFocusedID = textFieldID; - } - }, - - /** - * @param {number} textFieldID id of the text field to focus - * Unfocuses the specified text field - * noop if it wasn't focused - */ - blurTextInput(textFieldID) { - if (this._currentlyFocusedID === textFieldID && textFieldID !== null) { - this._currentlyFocusedID = null; - } - } -}; - -module.exports = TextInputState; diff --git a/src/api/TimePickerAndroid.js b/src/api/TimePickerAndroid.js deleted file mode 100644 index cfe9644..0000000 --- a/src/api/TimePickerAndroid.js +++ /dev/null @@ -1,54 +0,0 @@ -import TimePickerModule from '../NativeModules/TimePickerAndroid'; - -/** - * Opens the standard Android time picker dialog. - * - * ### Example - * - * ``` - * try { - * const {action, hour, minute} = await TimePickerAndroid.open({ - * hour: 14, - * minute: 0, - * is24Hour: false, // Will display '2 PM' - * }); - * if (action !== DatePickerAndroid.dismissedAction) { - * // Selected hour (0-23), minute (0-59) - * } - * } catch ({code, message}) { - * console.warn('Cannot open time picker', message); - * } - * ``` - */ -class TimePickerAndroid { - - /** - * Opens the standard Android time picker dialog. - * - * The available keys for the `options` object are: - * * `hour` (0-23) - the hour to show, defaults to the current time - * * `minute` (0-59) - the minute to show, defaults to the current time - * * `is24Hour` (boolean) - If `true`, the picker uses the 24-hour format. If `false`, - * the picker shows an AM/PM chooser. If undefined, the default for the current locale - * is used. - * - * Returns a Promise which will be invoked an object containing `action`, `hour` (0-23), - * `minute` (0-59) if the user picked a time. If the user dismissed the dialog, the Promise will - * still be resolved with action being `TimePickerAndroid.dismissedAction` and all the other keys - * being undefined. **Always** check whether the `action` before reading the values. - */ - static open(options) { - return TimePickerModule.open(options); - } - - /** - * A time has been selected. - */ - static get timeSetAction() { return 'timeSetAction'; } - /** - * The dialog has been dismissed. - */ - static get dismissedAction() { return 'dismissedAction'; } -} - -module.exports = TimePickerAndroid; diff --git a/src/api/TouchHistoryMath.js b/src/api/TouchHistoryMath.js deleted file mode 100644 index a8f8b19..0000000 --- a/src/api/TouchHistoryMath.js +++ /dev/null @@ -1,118 +0,0 @@ -const TouchHistoryMath = { - /** - * This code is optimized and not intended to look beautiful. This allows - * computing of touch centroids that have moved after `touchesChangedAfter` - * timeStamp. You can compute the current centroid involving all touches - * moves after `touchesChangedAfter`, or you can compute the previous - * centroid of all touches that were moved after `touchesChangedAfter`. - * - * @param {TouchHistoryMath} touchHistory Standard Responder touch track - * data. - * @param {number} touchesChangedAfter timeStamp after which moved touches - * are considered "actively moving" - not just "active". - * @param {boolean} isXAxis Consider `x` dimension vs. `y` dimension. - * @param {boolean} ofCurrent Compute current centroid for actively moving - * touches vs. previous centroid of now actively moving touches. - * @return {number} value of centroid in specified dimension. - */ - centroidDimension(touchHistory, touchesChangedAfter, isXAxis, ofCurrent) { - const touchBank = touchHistory.touchBank; - let total = 0; - let count = 0; - - const oneTouchData = touchHistory.numberActiveTouches === 1 ? - touchHistory.touchBank[touchHistory.indexOfSingleActiveTouch] : null; - - if (oneTouchData !== null) { - if (oneTouchData.touchActive && oneTouchData.currentTimeStamp > touchesChangedAfter) { - // FIXME: DONT USE TERNARIES!!!! - total += - ofCurrent && isXAxis ? oneTouchData.currentPageX : // eslint-disable-line - ofCurrent && !isXAxis ? oneTouchData.currentPageY : // eslint-disable-line - !ofCurrent && isXAxis ? oneTouchData.previousPageX : - oneTouchData.previousPageY; - count = 1; - } - } else { - for (let i = 0; i < touchBank.length; i++) { - const touchTrack = touchBank[i]; - if (touchTrack !== null && - touchTrack !== undefined && - touchTrack.touchActive && - touchTrack.currentTimeStamp >= touchesChangedAfter) { - let toAdd; // Yuck, program temporarily in invalid state. - if (ofCurrent && isXAxis) { - toAdd = touchTrack.currentPageX; - } else if (ofCurrent && !isXAxis) { - toAdd = touchTrack.currentPageY; - } else if (!ofCurrent && isXAxis) { - toAdd = touchTrack.previousPageX; - } else { - toAdd = touchTrack.previousPageY; - } - total += toAdd; - count++; - } - } - } - return count > 0 ? total / count : TouchHistoryMath.noCentroid; - }, - - currentCentroidXOfTouchesChangedAfter(touchHistory, touchesChangedAfter) { - return TouchHistoryMath.centroidDimension( - touchHistory, - touchesChangedAfter, - true, // isXAxis - true // ofCurrent - ); - }, - - currentCentroidYOfTouchesChangedAfter(touchHistory, touchesChangedAfter) { - return TouchHistoryMath.centroidDimension( - touchHistory, - touchesChangedAfter, - false, // isXAxis - true // ofCurrent - ); - }, - - previousCentroidXOfTouchesChangedAfter(touchHistory, touchesChangedAfter) { - return TouchHistoryMath.centroidDimension( - touchHistory, - touchesChangedAfter, - true, // isXAxis - false // ofCurrent - ); - }, - - previousCentroidYOfTouchesChangedAfter(touchHistory, touchesChangedAfter) { - return TouchHistoryMath.centroidDimension( - touchHistory, - touchesChangedAfter, - false, // isXAxis - false // ofCurrent - ); - }, - - currentCentroidX(touchHistory) { - return TouchHistoryMath.centroidDimension( - touchHistory, - 0, // touchesChangedAfter - true, // isXAxis - true // ofCurrent - ); - }, - - currentCentroidY(touchHistory) { - return TouchHistoryMath.centroidDimension( - touchHistory, - 0, // touchesChangedAfter - false, // isXAxis - true // ofCurrent - ); - }, - - noCentroid: -1, -}; - -module.exports = TouchHistoryMath; diff --git a/src/api/VibrationIOS.js b/src/api/VibrationIOS.js deleted file mode 100644 index 12165fe..0000000 --- a/src/api/VibrationIOS.js +++ /dev/null @@ -1,25 +0,0 @@ -import NativeVibration from '../NativeModules/Vibration'; -import invariant from 'invariant'; - -/** - * The Vibration API is exposed at `VibrationIOS.vibrate()`. On iOS, calling this - * function will trigger a one second vibration. The vibration is asynchronous - * so this method will return immediately. - * - * There will be no effect on devices that do not support Vibration, eg. the iOS - * simulator. - * - * Vibration patterns are currently unsupported. - */ - -const Vibration = { - vibrate() { - invariant( - arguments[0] === undefined, - 'Vibration patterns not supported.' - ); - NativeVibration.vibrate(); - } -}; - -module.exports = Vibration; diff --git a/src/components/ART/Path.js b/src/components/ART/Path.js deleted file mode 100644 index 85d7d9b..0000000 --- a/src/components/ART/Path.js +++ /dev/null @@ -1,28 +0,0 @@ - -class Path { - constructor(path) { - [ - 'push', - 'reset', - 'move', - 'moveTo', - 'line', - 'lineTo', - 'curve', - 'curveTo', - 'arc', - 'arcTo', - 'counterArc', - 'counterArcTo', - 'close' - ].forEach((methodName) => { this[methodName] = () => this; }); - - this.path = path || []; - } - - toJSON() { - return JSON.stringify(this.path); - } -} - -module.exports = Path; diff --git a/src/components/ART/Transform.js b/src/components/ART/Transform.js deleted file mode 100644 index e41a615..0000000 --- a/src/components/ART/Transform.js +++ /dev/null @@ -1,28 +0,0 @@ - -class Transform { - constructor() { - this.xx = 0; - this.yx = 0; - this.xy = 0; - this.yy = 0; - this.x = 0; - this.y = 0; - } - transformTo() { - return this; - } - move() { - return this; - } - rotate() { - return this; - } - scale() { - return this; - } - transform() { - return this; - } -} - -module.exports = Transform; diff --git a/src/components/ART/index.js b/src/components/ART/index.js deleted file mode 100644 index d9f4e73..0000000 --- a/src/components/ART/index.js +++ /dev/null @@ -1,40 +0,0 @@ -import createMockComponent from '../createMockComponent'; -import Transform from './Transform'; -import Path from './Path'; - -const LINEAR_GRADIENT = 1; -const RADIAL_GRADIENT = 2; -const PATTERN = 3; - -function CSSBackgroundPattern() { - // TODO(lmr): - return {}; -} - -function Pattern(url, width, height, left, top) { - this._brush = [PATTERN, url, +left || 0, +top || 0, +width, +height]; -} - -function LinearGradient(stops, x1, y1, x2, y2) { - this._brush = [LINEAR_GRADIENT, +x1, +y1, +x2, +y2]; -} - -function RadialGradient(stops, fx, fy, rx, ry, cx, cy) { - this._brush = [RADIAL_GRADIENT, +fx, +fy, +rx * 2, +ry * 2, +cx, +cy]; -} - -const ReactART = { - LinearGradient, - RadialGradient, - Pattern, - Transform, - Path, - Surface: createMockComponent('Surface'), - Group: createMockComponent('Group'), - ClippingRectangle: createMockComponent('ClippingRectangle'), - Shape: createMockComponent('Shape'), - Text: createMockComponent('Text'), - CSSBackgroundPattern, -}; - -module.exports = ReactART; diff --git a/src/components/ActivityIndicator.js b/src/components/ActivityIndicator.js deleted file mode 100644 index 7d0f447..0000000 --- a/src/components/ActivityIndicator.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Components/ActivityIndicator/ActivityIndicator.js - */ -import React from 'react'; -import NativeMethodsMixin from '../mixins/NativeMethodsMixin'; -import View from './View'; -import ColorPropType from '../propTypes/ColorPropType'; - -const { PropTypes } = React; - -const ActivityIndicator = React.createClass({ - propTypes: { - ...View.propTypes, - /** - * Whether to show the indicator (true, the default) or hide it (false). - */ - animating: PropTypes.bool, - /** - * The foreground color of the spinner (default is gray). - */ - color: ColorPropType, - /** - * Whether the indicator should hide when not animating (true by default). - */ - hidesWhenStopped: PropTypes.bool, - /** - * Size of the indicator. Small has a height of 20, large has a height of 36. - */ - size: PropTypes.oneOf([ - 'small', - 'large', - ]), - /** - * Invoked on mount and layout changes with - * - * {nativeEvent: { layout: {x, y, width, height}}}. - */ - onLayout: PropTypes.func, - }, - mixins: [NativeMethodsMixin], - render() { - return null; - }, -}); - -module.exports = ActivityIndicator; diff --git a/src/components/ActivityIndicatorIOS.js b/src/components/ActivityIndicatorIOS.js deleted file mode 100644 index 63a95ca..0000000 --- a/src/components/ActivityIndicatorIOS.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Components/ActivityIndicator/ActivityIndicatorIOS.ios.js - */ -import React from 'react'; -import NativeMethodsMixin from '../mixins/NativeMethodsMixin'; -import View from './View'; - -const { PropTypes } = React; - -const ActivityIndicatorIOS = React.createClass({ - propTypes: { - ...View.propTypes, - /** - * Whether to show the indicator (true, the default) or hide it (false). - */ - animating: PropTypes.bool, - /** - * The foreground color of the spinner (default is gray). - */ - color: PropTypes.string, - /** - * Whether the indicator should hide when not animating (true by default). - */ - hidesWhenStopped: PropTypes.bool, - /** - * Size of the indicator. Small has a height of 20, large has a height of 36. - */ - size: PropTypes.oneOf([ - 'small', - 'large', - ]), - /** - * Invoked on mount and layout changes with - * - * {nativeEvent: { layout: {x, y, width, height}}}. - */ - onLayout: PropTypes.func, - }, - - mixins: [NativeMethodsMixin], - - render() { - return null; - }, -}); - -module.exports = ActivityIndicatorIOS; diff --git a/src/components/DrawerLayoutAndroid.js b/src/components/DrawerLayoutAndroid.js deleted file mode 100644 index 86e1e37..0000000 --- a/src/components/DrawerLayoutAndroid.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - *https://github.com/facebook/react-native/blob/master/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js - */ -import React from 'react'; -import NativeMethodsMixin from '../mixins/NativeMethodsMixin'; -import View from './View'; -import UIManager from '../NativeModules/UIManager'; -import ColorPropType from '../propTypes/ColorPropType'; - -const ReactPropTypes = React.PropTypes; -const DrawerConsts = UIManager.AndroidDrawerLayout.Constants; - -const DrawerLayoutAndroid = React.createClass({ - - propTypes: { - ...View.propTypes, - /** - * Determines whether the keyboard gets dismissed in response to a drag. - * - 'none' (the default), drags do not dismiss the keyboard. - * - 'on-drag', the keyboard is dismissed when a drag begins. - */ - keyboardDismissMode: ReactPropTypes.oneOf([ - 'none', // default - 'on-drag', - ]), - /** - * Specifies the background color of the drawer. The default value is white. - * If you want to set the opacity of the drawer, use rgba. Example: - * - * ``` - * return ( - * - * - * ); - * ``` - */ - drawerBackgroundColor: ColorPropType, - /** - * Specifies the side of the screen from which the drawer will slide in. - */ - drawerPosition: ReactPropTypes.oneOf([ - DrawerConsts.DrawerPosition.Left, - DrawerConsts.DrawerPosition.Right - ]), - /** - * Specifies the width of the drawer, more precisely the width of the view that be pulled in - * from the edge of the window. - */ - drawerWidth: ReactPropTypes.number, - /** - * Specifies the lock mode of the drawer. The drawer can be locked in 3 states: - * - unlocked (default), meaning that the drawer will respond (open/close) to touch gestures. - * - locked-closed, meaning that the drawer will stay closed and not respond to gestures. - * - locked-open, meaning that the drawer will stay opened and not respond to gestures. - * The drawer may still be opened and closed programmatically (`openDrawer`/`closeDrawer`). - */ - drawerLockMode: ReactPropTypes.oneOf([ - 'unlocked', - 'locked-closed', - 'locked-open' - ]), - /** - * Function called whenever there is an interaction with the navigation view. - */ - onDrawerSlide: ReactPropTypes.func, - /** - * Function called when the drawer state has changed. The drawer can be in 3 states: - * - idle, meaning there is no interaction with the navigation view happening at the time - * - dragging, meaning there is currently an interaction with the navigation view - * - settling, meaning that there was an interaction with the navigation view, and the - * navigation view is now finishing its closing or opening animation - */ - onDrawerStateChanged: ReactPropTypes.func, - /** - * Function called whenever the navigation view has been opened. - */ - onDrawerOpen: ReactPropTypes.func, - /** - * Function called whenever the navigation view has been closed. - */ - onDrawerClose: ReactPropTypes.func, - /** - * The navigation view that will be rendered to the side of the screen and can be pulled in. - */ - renderNavigationView: ReactPropTypes.func.isRequired, - - /** - * Make the drawer take the entire screen and draw the background of the - * status bar to allow it to open over the status bar. It will only have an - * effect on API 21+. - */ - statusBarBackgroundColor: ColorPropType, - }, - - mixins: [NativeMethodsMixin], - - statics: { - positions: DrawerConsts.DrawerPosition - }, - - openDrawer() { - // do nothing - }, - - closeDrawer() { - // do nothing - }, - - render() { - return null; - } - -}); - -module.exports = DrawerLayoutAndroid; diff --git a/src/components/Image.js b/src/components/Image.js deleted file mode 100644 index 3bc21fa..0000000 --- a/src/components/Image.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Image/Image.ios.js - */ -import React from 'react'; -import styleSheetPropType from '../propTypes/StyleSheetPropType'; -import NativeMethodsMixin from '../mixins/NativeMethodsMixin'; -import EdgeInsetsPropType from '../propTypes/EdgeInsetsPropType'; -import ImageStylePropTypes from '../propTypes/ImageStylePropTypes'; -import ImageResizeMode from '../propTypes/ImageResizeMode'; - -const { PropTypes } = React; - -const Image = React.createClass({ - propTypes: { - style: styleSheetPropType(ImageStylePropTypes), - /** - * `uri` is a string representing the resource identifier for the image, which - * could be an http address, a local file path, or the name of a static image - * resource (which should be wrapped in the `require('./path/to/image.png')` function). - */ - source: PropTypes.oneOfType([ - PropTypes.shape({ - uri: PropTypes.string, - }), - // Opaque type returned by require('./image.jpg') - PropTypes.number, - ]), - /** - * A static image to display while loading the image source. - * @platform ios - */ - defaultSource: PropTypes.oneOfType([ - PropTypes.shape({ - uri: PropTypes.string, - }), - // Opaque type returned by require('./image.jpg') - PropTypes.number, - ]), - /** - * When true, indicates the image is an accessibility element. - * @platform ios - */ - accessible: PropTypes.bool, - /** - * The text that's read by the screen reader when the user interacts with - * the image. - * @platform ios - */ - accessibilityLabel: PropTypes.string, - /** - * When the image is resized, the corners of the size specified - * by capInsets will stay a fixed size, but the center content and borders - * of the image will be stretched. This is useful for creating resizable - * rounded buttons, shadows, and other resizable assets. More info on - * [Apple documentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/index.html#//apple_ref/occ/instm/UIImage/resizableImageWithCapInsets) - * @platform ios - */ - capInsets: EdgeInsetsPropType, - /** - * Determines how to resize the image when the frame doesn't match the raw - * image dimensions. - * - * 'cover': Scale the image uniformly (maintain the image's aspect ratio) - * so that both dimensions (width and height) of the image will be equal - * to or larger than the corresponding dimension of the view (minus padding). - * - * 'contain': Scale the image uniformly (maintain the image's aspect ratio) - * so that both dimensions (width and height) of the image will be equal to - * or less than the corresponding dimension of the view (minus padding). - * - * 'stretch': Scale width and height independently, This may change the - * aspect ratio of the src. - * - * `repeat`: Repeat the image to cover the frame of the view. The - * image will keep it's size and aspect ratio. (iOS only) - * - */ - resizeMode: PropTypes.oneOf(ImageResizeMode), - /** - * A unique identifier for this element to be used in UI Automation - * testing scripts. - */ - testID: PropTypes.string, - /** - * Invoked on mount and layout changes with - * `{nativeEvent: {layout: {x, y, width, height}}}`. - */ - onLayout: PropTypes.func, - /** - * Invoked on load start - */ - onLoadStart: PropTypes.func, - /** - * Invoked on download progress with `{nativeEvent: {loaded, total}}` - * @platform ios - */ - onProgress: PropTypes.func, - /** - * Invoked on load error with `{nativeEvent: {error}}` - * @platform ios - */ - onError: PropTypes.func, - /** - * Invoked when load completes successfully - */ - onLoad: PropTypes.func, - /** - * Invoked when load either succeeds or fails - */ - onLoadEnd: PropTypes.func, - }, - mixins: [NativeMethodsMixin], - statics: { - resizeMode: ImageResizeMode, - getSize(uri, success, failure) { - - }, - prefetch(uri) { - - } - }, - render() { - return null; - }, -}); - -module.exports = Image; diff --git a/src/components/ListView.js b/src/components/ListView.js deleted file mode 100644 index f546f45..0000000 --- a/src/components/ListView.js +++ /dev/null @@ -1,167 +0,0 @@ -import React from 'react'; -import ScrollResponder from '../mixins/ScrollResponder'; -import TimerMixin from 'react-timer-mixin'; -import ScrollView from './ScrollView'; -import ListViewDataSource from '../api/ListViewDataSource'; - -const { PropTypes } = React; -const SCROLLVIEW_REF = 'listviewscroll'; - - -const ListView = React.createClass({ - propTypes: { - ...ScrollView.propTypes, - - dataSource: PropTypes.instanceOf(ListViewDataSource).isRequired, - /** - * (sectionID, rowID, adjacentRowHighlighted) => renderable - * - * If provided, a renderable component to be rendered as the separator - * below each row but not the last row if there is a section header below. - * Take a sectionID and rowID of the row above and whether its adjacent row - * is highlighted. - */ - renderSeparator: PropTypes.func, - /** - * (rowData, sectionID, rowID, highlightRow) => renderable - * - * Takes a data entry from the data source and its ids and should return - * a renderable component to be rendered as the row. By default the data - * is exactly what was put into the data source, but it's also possible to - * provide custom extractors. ListView can be notified when a row is - * being highlighted by calling highlightRow function. The separators above and - * below will be hidden when a row is highlighted. The highlighted state of - * a row can be reset by calling highlightRow(null). - */ - renderRow: PropTypes.func.isRequired, - /** - * How many rows to render on initial component mount. Use this to make - * it so that the first screen worth of data appears at one time instead of - * over the course of multiple frames. - */ - initialListSize: PropTypes.number, - /** - * Called when all rows have been rendered and the list has been scrolled - * to within onEndReachedThreshold of the bottom. The native scroll - * event is provided. - */ - onEndReached: PropTypes.func, - /** - * Threshold in pixels for onEndReached. - */ - onEndReachedThreshold: PropTypes.number, - /** - * Number of rows to render per event loop. - */ - pageSize: PropTypes.number, - /** - * () => renderable - * - * The header and footer are always rendered (if these props are provided) - * on every render pass. If they are expensive to re-render, wrap them - * in StaticContainer or other mechanism as appropriate. Footer is always - * at the bottom of the list, and header at the top, on every render pass. - */ - renderFooter: PropTypes.func, - renderHeader: PropTypes.func, - /** - * (sectionData, sectionID) => renderable - * - * If provided, a sticky header is rendered for this section. The sticky - * behavior means that it will scroll with the content at the top of the - * section until it reaches the top of the screen, at which point it will - * stick to the top until it is pushed off the screen by the next section - * header. - */ - renderSectionHeader: PropTypes.func, - /** - * (props) => renderable - * - * A function that returns the scrollable component in which the list rows - * are rendered. Defaults to returning a ScrollView with the given props. - */ - renderScrollComponent: React.PropTypes.func.isRequired, - /** - * How early to start rendering rows before they come on screen, in - * pixels. - */ - scrollRenderAheadDistance: React.PropTypes.number, - /** - * (visibleRows, changedRows) => void - * - * Called when the set of visible rows changes. `visibleRows` maps - * { sectionID: { rowID: true }} for all the visible rows, and - * `changedRows` maps { sectionID: { rowID: true | false }} for the rows - * that have changed their visibility, with true indicating visible, and - * false indicating the view has moved out of view. - */ - onChangeVisibleRows: React.PropTypes.func, - /** - * A performance optimization for improving scroll perf of - * large lists, used in conjunction with overflow: 'hidden' on the row - * containers. This is enabled by default. - */ - removeClippedSubviews: React.PropTypes.bool, - /** - * An array of child indices determining which children get docked to the - * top of the screen when scrolling. For example, passing - * `stickyHeaderIndices={[0]}` will cause the first child to be fixed to the - * top of the scroll view. This property is not supported in conjunction - * with `horizontal={true}`. - * @platform ios - */ - stickyHeaderIndices: PropTypes.arrayOf(PropTypes.number), - }, - mixins: [ScrollResponder.Mixin, TimerMixin], - - statics: { - DataSource: ListViewDataSource, - }, - - /** - * Exports some data, e.g. for perf investigations or analytics. - */ - getMetrics() { // eslint-disable-line react/sort-comp - // It's fixed, but the linter doesnt want to recognise it... - return { - contentLength: this.scrollProperties.contentLength, - totalRows: this.props.dataSource.getRowCount(), - renderedRows: this.state.curRenderedRowsCount, - visibleRows: Object.keys(this._visibleRows).length, - }; - }, - - scrollTo(destY, destX) { - this.getScrollResponder().scrollResponderScrollTo(destX || 0, destY || 0); - }, - - /** - * Provides a handle to the underlying scroll responder to support operations - * such as scrollTo. - */ - getScrollResponder() { - return this.refs[SCROLLVIEW_REF] && - this.refs[SCROLLVIEW_REF].getScrollResponder && - this.refs[SCROLLVIEW_REF].getScrollResponder(); - }, - - setNativeProps(props) { - this.refs[SCROLLVIEW_REF].setNativeProps(props); - }, - - getDefaultProps() { - return { - renderScrollComponent: (props) => - }; - }, - - getInnerViewNode() { - return this.refs[SCROLLVIEW_REF].getInnerViewNode(); - }, - - render() { - return null; - }, -}); - -module.exports = ListView; diff --git a/src/components/Navigator.js b/src/components/Navigator.js deleted file mode 100644 index 14a1d57..0000000 --- a/src/components/Navigator.js +++ /dev/null @@ -1,103 +0,0 @@ -import React, { PropTypes } from 'react'; -import createMockComponent from './createMockComponent'; -import View from './View'; - -const NavigatorSceneConfigType = PropTypes.shape({ - gestures: PropTypes.object, - springFriction: PropTypes.number, - springTension: PropTypes.number, - defaultTransitionVelocity: PropTypes.number, - animationInterpolators: React.PropTypes.object, -}); - -const NavigatorSceneConfigs = { - PushFromRight: NavigatorSceneConfigType, - FloatFromRight: NavigatorSceneConfigType, - FloatFromLeft: NavigatorSceneConfigType, - FloatFromBottom: NavigatorSceneConfigType, - FloatFromBottomAndroid: NavigatorSceneConfigType, - FadeAndroid: NavigatorSceneConfigType, - HorizontalSwipeJump: NavigatorSceneConfigType, - HorizontalSwipeJumpFromRight: NavigatorSceneConfigType, - VerticalUpSwipeJump: NavigatorSceneConfigType, - VerticalDownSwipeJump: NavigatorSceneConfigType -}; - -const Navigator = React.createClass({ - propTypes: { - /** - * Optional function that allows configuration about scene animations and - * gestures. Will be invoked with the route and the routeStack and should - * return a scene configuration object - * - * ``` - * (route, routeStack) => Navigator.SceneConfigs.FloatFromRight - * ``` - */ - configureScene: PropTypes.func, - - /** - * Required function which renders the scene for a given route. Will be - * invoked with the route and the navigator object - * - * ``` - * (route, navigator) => - * - * ``` - */ - renderScene: PropTypes.func.isRequired, - - /** - * Specify a route to start on. A route is an object that the navigator - * will use to identify each scene to render. `initialRoute` must be - * a route in the `initialRouteStack` if both props are provided. The - * `initialRoute` will default to the last item in the `initialRouteStack`. - */ - initialRoute: PropTypes.object, - - /** - * Provide a set of routes to initially mount. Required if no initialRoute - * is provided. Otherwise, it will default to an array containing only the - * `initialRoute` - */ - initialRouteStack: PropTypes.arrayOf(PropTypes.object), - - /** - * Will emit the target route upon mounting and before each nav transition - */ - onWillFocus: PropTypes.func, - - /** - * Will be called with the new route of each scene after the transition is - * complete or after the initial mounting - */ - onDidFocus: PropTypes.func, - - /** - * Optionally provide a navigation bar that persists across scene - * transitions - */ - navigationBar: PropTypes.node, - - /** - * Optionally provide the navigator object from a parent Navigator - */ - navigator: PropTypes.object, - - /** - * Styles to apply to the container of each scene - */ - sceneStyle: View.propTypes.style, - }, - - statics: { - BreadcrumbNavigationBar: createMockComponent('NavigatorBreadcrumbNavigationBar'), - NavigationBar: createMockComponent('NavigatorNavigationBar'), - SceneConfigs: NavigatorSceneConfigs, - }, - render() { - return null; - } -}); - -module.exports = Navigator; diff --git a/src/components/ScrollView.js b/src/components/ScrollView.js deleted file mode 100644 index e132137..0000000 --- a/src/components/ScrollView.js +++ /dev/null @@ -1,318 +0,0 @@ -import React from 'react'; -import EdgeInsetsPropType from '../propTypes/EdgeInsetsPropType'; -import PointPropType from '../propTypes/PointPropType'; -import ScrollResponder from '../mixins/ScrollResponder'; -import View from './View'; -import ViewStylePropTypes from '../propTypes/ViewStylePropTypes'; -import ScrollViewManager from '../NativeModules/ScrollViewManager'; -import styleSheetPropType from '../propTypes/StyleSheetPropType'; - -const { PropTypes } = React; - -const SCROLLVIEW = 'ScrollView'; -const INNERVIEW = 'InnerScrollView'; - -const ScrollView = React.createClass({ - propTypes: { - ...View.propTypes, - /** - * Controls whether iOS should automatically adjust the content inset - * for scroll views that are placed behind a navigation bar or - * tab bar/ toolbar. The default value is true. - * @platform ios - */ - automaticallyAdjustContentInsets: PropTypes.bool, - /** - * The amount by which the scroll view content is inset from the edges - * of the scroll view. Defaults to `{0, 0, 0, 0}`. - * @platform ios - */ - contentInset: EdgeInsetsPropType, - /** - * Used to manually set the starting scroll offset. - * The default value is `{x: 0, y: 0}`. - * @platform ios - */ - contentOffset: PointPropType, - /** - * When true, the scroll view bounces when it reaches the end of the - * content if the content is larger then the scroll view along the axis of - * the scroll direction. When false, it disables all bouncing even if - * the `alwaysBounce*` props are true. The default value is true. - * @platform ios - */ - bounces: PropTypes.bool, - /** - * When true, gestures can drive zoom past min/max and the zoom will animate - * to the min/max value at gesture end, otherwise the zoom will not exceed - * the limits. - * @platform ios - */ - bouncesZoom: PropTypes.bool, - /** - * When true, the scroll view bounces horizontally when it reaches the end - * even if the content is smaller than the scroll view itself. The default - * value is true when `horizontal={true}` and false otherwise. - * @platform ios - */ - alwaysBounceHorizontal: PropTypes.bool, - /** - * When true, the scroll view bounces vertically when it reaches the end - * even if the content is smaller than the scroll view itself. The default - * value is false when `horizontal={true}` and true otherwise. - * @platform ios - */ - alwaysBounceVertical: PropTypes.bool, - /** - * When true, the scroll view automatically centers the content when the - * content is smaller than the scroll view bounds; when the content is - * larger than the scroll view, this property has no effect. The default - * value is false. - * @platform ios - */ - centerContent: PropTypes.bool, - /** - * These styles will be applied to the scroll view content container which - * wraps all of the child views. Example: - * - * return ( - * - * - * ); - * ... - * var styles = StyleSheet.create({ - * contentContainer: { - * paddingVertical: 20 - * } - * }); - */ - contentContainerStyle: styleSheetPropType(ViewStylePropTypes), - /** - * A floating-point number that determines how quickly the scroll view - * decelerates after the user lifts their finger. You may also use string - * shortcuts `"normal"` and `"fast"` which match the underlying iOS settings - * for `UIScrollViewDecelerationRateNormal` and - * `UIScrollViewDecelerationRateFast` respectively. - * - Normal: 0.998 (the default) - * - Fast: 0.9 - * @platform ios - */ - decelerationRate: PropTypes.oneOfType([ - PropTypes.oneOf(['fast', 'normal']), - PropTypes.number, - ]), - /** - * When true, the scroll view's children are arranged horizontally in a row - * instead of vertically in a column. The default value is false. - */ - horizontal: PropTypes.bool, - /** - * The style of the scroll indicators. - * - `default` (the default), same as `black`. - * - `black`, scroll indicator is black. - * - `white`, scroll indicator is white. - * @platform ios - */ - indicatorStyle: PropTypes.oneOf([ - 'default', // default - 'black', - 'white', - ]), - /** - * When true, the ScrollView will try to lock to only vertical or horizontal - * scrolling while dragging. The default value is false. - * @platform ios - */ - directionalLockEnabled: PropTypes.bool, - /** - * When false, once tracking starts, won't try to drag if the touch moves. - * The default value is true. - * @platform ios - */ - canCancelContentTouches: PropTypes.bool, - /** - * Determines whether the keyboard gets dismissed in response to a drag. - * - 'none' (the default), drags do not dismiss the keyboard. - * - 'on-drag', the keyboard is dismissed when a drag begins. - * - 'interactive', the keyboard is dismissed interactively with the drag and moves in - * synchrony with the touch; dragging upwards cancels the dismissal. - * On android this is not supported and it will have the same behavior as 'none'. - */ - keyboardDismissMode: PropTypes.oneOf([ - 'none', // default - 'interactive', - 'on-drag', - ]), - /** - * When false, tapping outside of the focused text input when the keyboard - * is up dismisses the keyboard. When true, the scroll view will not catch - * taps, and the keyboard will not dismiss automatically. The default value - * is false. - */ - keyboardShouldPersistTaps: PropTypes.bool, - /** - * The maximum allowed zoom scale. The default value is 1.0. - * @platform ios - */ - maximumZoomScale: PropTypes.number, - /** - * The minimum allowed zoom scale. The default value is 1.0. - * @platform ios - */ - minimumZoomScale: PropTypes.number, - /** - * Fires at most once per frame during scrolling. The frequency of the - * events can be controlled using the `scrollEventThrottle` prop. - */ - onScroll: PropTypes.func, - /** - * Called when a scrolling animation ends. - * @platform ios - */ - onScrollAnimationEnd: PropTypes.func, - /** - * Called when scrollable content view of the ScrollView changes. It's - * implemented using onLayout handler attached to the content container - * which this ScrollView renders. - */ - onContentSizeChange: PropTypes.func, - /** - * When true, the scroll view stops on multiples of the scroll view's size - * when scrolling. This can be used for horizontal pagination. The default - * value is false. - * @platform ios - */ - pagingEnabled: PropTypes.bool, - /** - * When false, the content does not scroll. - * The default value is true. - * @platform ios - */ - scrollEnabled: PropTypes.bool, - /** - * This controls how often the scroll event will be fired while scrolling - * (in events per seconds). A higher number yields better accuracy for code - * that is tracking the scroll position, but can lead to scroll performance - * problems due to the volume of information being send over the bridge. - * The default value is zero, which means the scroll event will be sent - * only once each time the view is scrolled. - * @platform ios - */ - scrollEventThrottle: PropTypes.number, - /** - * The amount by which the scroll view indicators are inset from the edges - * of the scroll view. This should normally be set to the same value as - * the `contentInset`. Defaults to `{0, 0, 0, 0}`. - * @platform ios - */ - scrollIndicatorInsets: EdgeInsetsPropType, - /** - * When true, the scroll view scrolls to top when the status bar is tapped. - * The default value is true. - * @platform ios - */ - scrollsToTop: PropTypes.bool, - /** - * When true, momentum events will be sent from Android - * This is internal and set automatically by the framework if you have - * onMomentumScrollBegin or onMomentumScrollEnd set on your ScrollView - * @platform android - */ - sendMomentumEvents: PropTypes.bool, - /** - * When true, shows a horizontal scroll indicator. - */ - showsHorizontalScrollIndicator: PropTypes.bool, - /** - * When true, shows a vertical scroll indicator. - */ - showsVerticalScrollIndicator: PropTypes.bool, - /** - * An array of child indices determining which children get docked to the - * top of the screen when scrolling. For example, passing - * `stickyHeaderIndices={[0]}` will cause the first child to be fixed to the - * top of the scroll view. This property is not supported in conjunction - * with `horizontal={true}`. - * @platform ios - */ - stickyHeaderIndices: PropTypes.arrayOf(PropTypes.number), - style: styleSheetPropType(ViewStylePropTypes), - /** - * When set, causes the scroll view to stop at multiples of the value of - * `snapToInterval`. This can be used for paginating through children - * that have lengths smaller than the scroll view. Used in combination - * with `snapToAlignment`. - * @platform ios - */ - snapToInterval: PropTypes.number, - /** - * When `snapToInterval` is set, `snapToAlignment` will define the relationship - * of the the snapping to the scroll view. - * - `start` (the default) will align the snap at the left (horizontal) or top (vertical) - * - `center` will align the snap in the center - * - `end` will align the snap at the right (horizontal) or bottom (vertical) - * @platform ios - */ - snapToAlignment: PropTypes.oneOf([ - 'start', // default - 'center', - 'end', - ]), - /** - * Experimental: When true, offscreen child views (whose `overflow` value is - * `hidden`) are removed from their native backing superview when offscreen. - * This can improve scrolling performance on long lists. The default value is - * true. - */ - removeClippedSubviews: PropTypes.bool, - /** - * The current scale of the scroll view content. The default value is 1.0. - * @platform ios - */ - zoomScale: PropTypes.number, - - /** - * A RefreshControl component, used to provide pull-to-refresh - * functionality for the ScrollView. - * - * See [RefreshControl](http://facebook.github.io/react-native/docs/refreshcontrol.html). - */ - refreshControl: PropTypes.element, - }, - - mixins: [ScrollResponder.Mixin], - - setNativeProps(props) { - this.refs[SCROLLVIEW].setNativeProps(props); - }, - - /** - * Returns a reference to the underlying scroll responder, which supports - * operations like `scrollTo`. All ScrollView-like components should - * implement this method so that they can be composed while providing access - * to the underlying scroll responder's methods. - */ - getScrollResponder() { - return this; - }, - - getInnerViewNode() { - return React.findNodeHandle(this.refs[INNERVIEW]); - }, - - endRefreshin() { - ScrollViewManager.endRefreshing( - React.findNodeHandle(this) - ); - }, - - scrollTo(destY = 0, destX = 0, animated = true) { - - }, - - render() { - return null; - }, -}); - -module.exports = ScrollView; diff --git a/src/components/StatusBar.js b/src/components/StatusBar.js deleted file mode 100644 index f9f51f3..0000000 --- a/src/components/StatusBar.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Components/StatusBar/StatusBar.js - */ -import React from 'react'; -import ColorPropType from '../propTypes/ColorPropType'; - - -let _backgroundColor = ''; -let _barStyle = {}; -let _hidden = false; -let _networkActivityIndicatorVisible = false; -let _translucent = false; - -const StatusBar = React.createClass({ - propTypes: { - animated: React.PropTypes.bool, - barStyle: React.PropTypes.oneOf(['default', 'light-content']), - backgroundColor: ColorPropType, - hidden: React.PropTypes.bool, - networkActivityIndicatorVisible: React.PropTypes.bool, - showHideTransition: React.PropTypes.oneOf(['fade', 'slide']), - translucent: React.PropTypes.bool - }, - - statics: { - setBackgroundColor(backgroundColor, animated) { - _backgroundColor = backgroundColor; - }, - - setBarStyle(barStyle, animated) { - _barStyle = barStyle; - }, - - setHidden(hidden, animated) { - _hidden = hidden; - }, - - setNetworkActivityIndicatorVisible(visible) { - _networkActivityIndicatorVisible = visible; - }, - - setTranslucent(translucent) { - _translucent = translucent; - }, - - __getBackgroundColor() { - return _backgroundColor; - }, - - __getBarStyle() { - return _barStyle; - }, - - __getHidden() { - return _hidden; - }, - - __getNetworkActivityIndicatorVisible() { - return _networkActivityIndicatorVisible; - }, - - __getTranslucent() { - return _translucent; - } - }, - - render() { - return null; - } -}); - -module.exports = StatusBar; diff --git a/src/components/Text.js b/src/components/Text.js deleted file mode 100644 index a8a267b..0000000 --- a/src/components/Text.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Text/Text.js - */ -import React from 'react'; -import styleSheetPropType from '../propTypes/StyleSheetPropType'; -import TextStylePropTypes from '../propTypes/TextStylePropTypes'; -import NativeMethodsMixin from '../mixins/NativeMethodsMixin'; - -const stylePropType = styleSheetPropType(TextStylePropTypes); - -const Text = React.createClass({ - propTypes: { - /** - * Used to truncate the text with an ellipsis after computing the text - * layout, including line wrapping, such that the total number of lines - * does not exceed this number. - */ - numberOfLines: React.PropTypes.number, - /** - * Invoked on mount and layout changes with - * - * `{nativeEvent: {layout: {x, y, width, height}}}` - */ - onLayout: React.PropTypes.func, - /** - * This function is called on press. - */ - onPress: React.PropTypes.func, - /** - * When true, no visual change is made when text is pressed down. By - * default, a gray oval highlights the text on press down. - * @platform ios - */ - suppressHighlighting: React.PropTypes.bool, - style: stylePropType, - /** - * Used to locate this view in end-to-end tests. - */ - testID: React.PropTypes.string, - /** - * Specifies should fonts scale to respect Text Size accessibility setting on iOS. - * @platform ios - */ - allowFontScaling: React.PropTypes.bool, - }, - mixins: [NativeMethodsMixin], - - render() { - return null; - }, -}); - -module.exports = Text; diff --git a/src/components/TextInput.js b/src/components/TextInput.js deleted file mode 100644 index 5cec014..0000000 --- a/src/components/TextInput.js +++ /dev/null @@ -1,249 +0,0 @@ -import React from 'react'; -import TextInputState from '../api/TextInputState'; -import TimerMixin from 'react-timer-mixin'; -import NativeMethodsMixin from '../mixins/NativeMethodsMixin'; -import View from './View'; -import Text from './Text'; - -const { PropTypes } = React; - -const TextInput = React.createClass({ - propTypes: { - ...View.propTypes, - /** - * Can tell TextInput to automatically capitalize certain characters. - * - * - characters: all characters, - * - words: first letter of each word - * - sentences: first letter of each sentence (default) - * - none: don't auto capitalize anything - */ - autoCapitalize: PropTypes.oneOf([ - 'none', - 'sentences', - 'words', - 'characters', - ]), - /** - * If false, disables auto-correct. The default value is true. - */ - autoCorrect: PropTypes.bool, - /** - * If true, focuses the input on componentDidMount. - * The default value is false. - */ - autoFocus: PropTypes.bool, - /** - * If false, text is not editable. The default value is true. - */ - editable: PropTypes.bool, - /** - * Determines which keyboard to open, e.g.`numeric`. - * - * The following values work across platforms: - * - default - * - numeric - * - email-address - */ - keyboardType: PropTypes.oneOf([ - // Cross-platform - 'default', - 'email-address', - 'numeric', - 'phone-pad', - // iOS-only - 'ascii-capable', - 'numbers-and-punctuation', - 'url', - 'number-pad', - 'name-phone-pad', - 'decimal-pad', - 'twitter', - 'web-search', - ]), - /** - * Determines the color of the keyboard. - * @platform ios - */ - keyboardAppearance: PropTypes.oneOf([ - 'default', - 'light', - 'dark', - ]), - /** - * Determines how the return key should look. - * @platform ios - */ - returnKeyType: PropTypes.oneOf([ - 'default', - 'go', - 'google', - 'join', - 'next', - 'route', - 'search', - 'send', - 'yahoo', - 'done', - 'emergency-call', - ]), - /** - * Limits the maximum number of characters that can be entered. Use this - * instead of implementing the logic in JS to avoid flicker. - */ - maxLength: PropTypes.number, - /** - * Sets the number of lines for a TextInput. Use it with multiline set to - * true to be able to fill the lines. - * @platform android - */ - numberOfLines: PropTypes.number, - /** - * If true, the keyboard disables the return key when there is no text and - * automatically enables it when there is text. The default value is false. - * @platform ios - */ - enablesReturnKeyAutomatically: PropTypes.bool, - /** - * If true, the text input can be multiple lines. - * The default value is false. - */ - multiline: PropTypes.bool, - /** - * Callback that is called when the text input is blurred - */ - onBlur: PropTypes.func, - /** - * Callback that is called when the text input is focused - */ - onFocus: PropTypes.func, - /** - * Callback that is called when the text input's text changes. - */ - onChange: PropTypes.func, - /** - * Callback that is called when the text input's text changes. - * Changed text is passed as an argument to the callback handler. - */ - onChangeText: PropTypes.func, - /** - * Callback that is called when text input ends. - */ - onEndEditing: PropTypes.func, - /** - * Callback that is called when the text input selection is changed - */ - onSelectionChange: PropTypes.func, - /** - * Callback that is called when the text input's submit button is pressed. - * Invalid if multiline={true} is specified. - */ - onSubmitEditing: PropTypes.func, - /** - * Callback that is called when a key is pressed. - * Pressed key value is passed as an argument to the callback handler. - * Fires before onChange callbacks. - * @platform ios - */ - onKeyPress: PropTypes.func, - /** - * Invoked on mount and layout changes with `{x, y, width, height}`. - */ - onLayout: PropTypes.func, - /** - * The string that will be rendered before text input has been entered - */ - placeholder: PropTypes.string, - /** - * The text color of the placeholder string - */ - placeholderTextColor: PropTypes.string, - /** - * If true, the text input obscures the text entered so that sensitive text - * like passwords stay secure. The default value is false. - */ - secureTextEntry: PropTypes.bool, - /** - * See DocumentSelectionState.js, some state that is responsible for - * maintaining selection information for a document - * @platform ios - */ - // TODO(lmr): requireLibrary - // selectionState: PropTypes.instanceOf(DocumentSelectionState), - /** - * The value to show for the text input. TextInput is a controlled - * component, which means the native value will be forced to match this - * value prop if provided. For most uses this works great, but in some - * cases this may cause flickering - one common cause is preventing edits - * by keeping value the same. In addition to simply setting the same value, - * either set `editable={false}`, or set/update `maxLength` to prevent - * unwanted edits without flicker. - */ - value: PropTypes.string, - /** - * Provides an initial value that will change when the user starts typing. - * Useful for simple use-cases where you don't want to deal with listening - * to events and updating the value prop to keep the controlled state in sync. - */ - defaultValue: PropTypes.string, - /** - * When the clear button should appear on the right side of the text view - * @platform ios - */ - clearButtonMode: PropTypes.oneOf([ - 'never', - 'while-editing', - 'unless-editing', - 'always', - ]), - /** - * If true, clears the text field automatically when editing begins - * @platform ios - */ - clearTextOnFocus: PropTypes.bool, - /** - * If true, all text will automatically be selected on focus - * @platform ios - */ - selectTextOnFocus: PropTypes.bool, - /** - * If true, the text field will blur when submitted. - * The default value is true for single-line fields and false for - * multiline fields. Note that for multiline fields, setting blurOnSubmit - * to true means that pressing return will blur the field and trigger the - * onSubmitEditing event instead of inserting a newline into the field. - * @platform ios - */ - blurOnSubmit: PropTypes.bool, - /** - * Styles - */ - style: Text.propTypes.style, - /** - * Used to locate this view in end-to-end tests - */ - testID: PropTypes.string, - /** - * The color of the textInput underline. - * @platform android - */ - underlineColorAndroid: PropTypes.string, - }, - mixins: [NativeMethodsMixin, TimerMixin], - statics: { - State: TextInputState, - }, - isFocused() { - // TODO(lmr): React.findNodeHandle - return TextInputState.currentlyFocusedField() === - React.findNodeHandle(this.refs.input); - }, - clear() { - - }, - render() { - return null; - }, -}); - -module.exports = TextInput; diff --git a/src/components/TouchableNativeFeedback.js b/src/components/TouchableNativeFeedback.js deleted file mode 100644 index bd606a5..0000000 --- a/src/components/TouchableNativeFeedback.js +++ /dev/null @@ -1,22 +0,0 @@ - -import React from 'react'; - -import TouchableWithoutFeedback from './TouchableWithoutFeedback'; - -const TouchableNativeFeedback = React.createClass({ - propTypes: { - ...TouchableWithoutFeedback.propTypes, - - background: React.PropTypes.object - }, - statics: { - SelectableBackground() {}, - SelectableBackgroundBorderless() {}, - Ripple(color, borderless) {} - }, - render() { - return null; - } -}); - -module.exports = TouchableNativeFeedback; diff --git a/src/components/TouchableOpacity.js b/src/components/TouchableOpacity.js deleted file mode 100644 index aab17a8..0000000 --- a/src/components/TouchableOpacity.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Components/Touchable/TouchableOpacity.js - */ -import React from 'react'; - -import TouchableWithoutFeedback from './TouchableWithoutFeedback'; - -const TouchableOpacity = React.createClass({ - propTypes: { - ...TouchableWithoutFeedback.propTypes, - - /** - * Determines what the opacity of the wrapped view should be when touch is - * active. Defaults to 0.2. - */ - activeOpacity: React.PropTypes.number, - }, - - render() { - return null; - }, -}); - -module.exports = TouchableOpacity; diff --git a/src/components/TouchableWithoutFeedback.js b/src/components/TouchableWithoutFeedback.js deleted file mode 100644 index cf1d3e2..0000000 --- a/src/components/TouchableWithoutFeedback.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Components/Touchable/TouchableWithoutFeedback.js - */ -import React from 'react'; -import EdgeInsetsPropType from '../propTypes/EdgeInsetsPropType'; -import View from './View'; - -const TouchableWithoutFeedback = React.createClass({ - propTypes: { - accessible: React.PropTypes.bool, - accessibilityComponentType: React.PropTypes.oneOf(View.AccessibilityComponentType), - accessibilityTraits: React.PropTypes.oneOfType([ - React.PropTypes.oneOf(View.AccessibilityTraits), - React.PropTypes.arrayOf(React.PropTypes.oneOf(View.AccessibilityTraits)), - ]), - /** - * If true, disable all interactions for this component. - */ - disabled: React.PropTypes.bool, - /** - * Called when the touch is released, but not if cancelled (e.g. by a scroll - * that steals the responder lock). - */ - onPress: React.PropTypes.func, - onPressIn: React.PropTypes.func, - onPressOut: React.PropTypes.func, - /** - * Invoked on mount and layout changes with - * - * `{nativeEvent: {layout: {x, y, width, height}}}` - */ - onLayout: React.PropTypes.func, - - onLongPress: React.PropTypes.func, - - /** - * Delay in ms, from the start of the touch, before onPressIn is called. - */ - delayPressIn: React.PropTypes.number, - /** - * Delay in ms, from the release of the touch, before onPressOut is called. - */ - delayPressOut: React.PropTypes.number, - /** - * Delay in ms, from onPressIn, before onLongPress is called. - */ - delayLongPress: React.PropTypes.number, - /** - * When the scroll view is disabled, this defines how far your touch may - * move off of the button, before deactivating the button. Once deactivated, - * try moving it back and you'll see that the button is once again - * reactivated! Move it back and forth several times while the scroll view - * is disabled. Ensure you pass in a constant to reduce memory allocations. - */ - pressRetentionOffset: EdgeInsetsPropType, - /** - * This defines how far your touch can start away from the button. This is - * added to `pressRetentionOffset` when moving off of the button. - * ** NOTE ** - * The touch area never extends past the parent view bounds and the Z-index - * of sibling views always takes precedence if a touch hits two overlapping - * views. - */ - hitSlop: EdgeInsetsPropType, - }, - render() { - return null; - }, -}); - -module.exports = TouchableWithoutFeedback; diff --git a/src/components/View.js b/src/components/View.js deleted file mode 100644 index efd7954..0000000 --- a/src/components/View.js +++ /dev/null @@ -1,288 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Components/View/View.js - */ -import React from 'react'; -import styleSheetPropType from '../propTypes/StyleSheetPropType'; -import ViewStylePropTypes from '../propTypes/ViewStylePropTypes'; -import NativeMethodsMixin from '../mixins/NativeMethodsMixin'; - -const stylePropType = styleSheetPropType(ViewStylePropTypes); - -const { PropTypes } = React; - -const AccessibilityTraits = [ - 'none', - 'button', - 'link', - 'header', - 'search', - 'image', - 'selected', - 'plays', - 'key', - 'text', - 'summary', - 'disabled', - 'frequentUpdates', - 'startsMedia', - 'adjustable', - 'allowsDirectInteraction', - 'pageTurn', -]; - -const AccessibilityComponentType = [ - 'none', - 'button', - 'radiobutton_checked', - 'radiobutton_unchecked', -]; - -// TODO(lmr): -const forceTouchAvailable = false; - -const statics = { - AccessibilityTraits, - AccessibilityComponentType, - /** - * Is 3D Touch / Force Touch available (i.e. will touch events include `force`) - * @platform ios - */ - forceTouchAvailable, -}; - -const View = React.createClass({ - propTypes: { - /** - * When true, indicates that the view is an accessibility element. By default, - * all the touchable elements are accessible. - */ - accessible: PropTypes.bool, - - /** - * Overrides the text that's read by the screen reader when the user interacts - * with the element. By default, the label is constructed by traversing all the - * children and accumulating all the Text nodes separated by space. - */ - accessibilityLabel: PropTypes.string, - - /** - * Indicates to accessibility services to treat UI component like a - * native one. Works for Android only. - * @platform android - */ - accessibilityComponentType: PropTypes.oneOf(AccessibilityComponentType), - - /** - * Indicates to accessibility services whether the user should be notified - * when this view changes. Works for Android API >= 19 only. - * See http://developer.android.com/reference/android/view/View.html#attr_android:accessibilityLiveRegion - * for references. - * @platform android - */ - accessibilityLiveRegion: PropTypes.oneOf([ - 'none', - 'polite', - 'assertive', - ]), - - /** - * Controls how view is important for accessibility which is if it - * fires accessibility events and if it is reported to accessibility services - * that query the screen. Works for Android only. - * See http://developer.android.com/reference/android/R.attr.html#importantForAccessibility - * for references. - * Possible values: - * 'auto' - The system determines whether the view is important for accessibility - - * default (recommended). - * 'yes' - The view is important for accessibility. - * 'no' - The view is not important for accessibility. - * 'no-hide-descendants' - The view is not important for accessibility, - * nor are any of its descendant views. - * - * @platform android - */ - importantForAccessibility: PropTypes.oneOf([ - 'auto', - 'yes', - 'no', - 'no-hide-descendants', - ]), - - /** - * Provides additional traits to screen reader. By default no traits are - * provided unless specified otherwise in element - * @platform ios - */ - accessibilityTraits: PropTypes.oneOfType([ - PropTypes.oneOf(AccessibilityTraits), - PropTypes.arrayOf(PropTypes.oneOf(AccessibilityTraits)), - ]), - - /** - * When `accessible` is true, the system will try to invoke this function - * when the user performs accessibility tap gesture. - */ - onAccessibilityTap: PropTypes.func, - - /** - * When `accessible` is true, the system will invoke this function when the - * user performs the magic tap gesture. - */ - onMagicTap: PropTypes.func, - - /** - * Used to locate this view in end-to-end tests. NB: disables the 'layout-only - * view removal' optimization for this view! - */ - testID: PropTypes.string, - - /** - * For most touch interactions, you'll simply want to wrap your component in - * `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`, - * `ScrollResponder.js` and `ResponderEventPlugin.js` for more discussion. - */ - onResponderGrant: PropTypes.func, - onResponderMove: PropTypes.func, - onResponderReject: PropTypes.func, - onResponderRelease: PropTypes.func, - onResponderTerminate: PropTypes.func, - onResponderTerminationRequest: PropTypes.func, - onStartShouldSetResponder: PropTypes.func, - onStartShouldSetResponderCapture: PropTypes.func, - onMoveShouldSetResponder: PropTypes.func, - onMoveShouldSetResponderCapture: PropTypes.func, - - /** - * Invoked on mount and layout changes with - * - * {nativeEvent: { layout: {x, y, width, height}}}. - * - * This event is fired immediately once the layout has been calculated, but - * the new layout may not yet be reflected on the screen at the time the - * event is received, especially if a layout animation is in progress. - */ - onLayout: PropTypes.func, - - /** - * In the absence of `auto` property, `none` is much like `CSS`'s `none` - * value. `box-none` is as if you had applied the `CSS` class: - * - * ``` - * .box-none { - * pointer-events: none; - * } - * .box-none * { - * pointer-events: all; - * } - * ``` - * - * `box-only` is the equivalent of - * - * ``` - * .box-only { - * pointer-events: all; - * } - * .box-only * { - * pointer-events: none; - * } - * ``` - * - * But since `pointerEvents` does not affect layout/appearance, and we are - * already deviating from the spec by adding additional modes, we opt to not - * include `pointerEvents` on `style`. On some platforms, we would need to - * implement it as a `className` anyways. Using `style` or not is an - * implementation detail of the platform. - */ - pointerEvents: PropTypes.oneOf([ - 'box-none', - 'none', - 'box-only', - 'auto', - ]), - style: stylePropType, - - /** - * This is a special performance property exposed by RCTView and is useful - * for scrolling content when there are many subviews, most of which are - * offscreen. For this property to be effective, it must be applied to a - * view that contains many subviews that extend outside its bound. The - * subviews must also have overflow: hidden, as should the containing view - * (or one of its superviews). - */ - removeClippedSubviews: PropTypes.bool, - - /** - * Whether this view should render itself (and all of its children) into a - * single hardware texture on the GPU. - * - * On Android, this is useful for animations and interactions that only - * modify opacity, rotation, translation, and/or scale: in those cases, the - * view doesn't have to be redrawn and display lists don't need to be - * re-executed. The texture can just be re-used and re-composited with - * different parameters. The downside is that this can use up limited video - * memory, so this prop should be set back to false at the end of the - * interaction/animation. - * @platform android - */ - renderToHardwareTextureAndroid: PropTypes.bool, - - /** - * Whether this view should be rendered as a bitmap before compositing. - * - * On iOS, this is useful for animations and interactions that do not - * modify this component's dimensions nor its children; for example, when - * translating the position of a static view, rasterization allows the - * renderer to reuse a cached bitmap of a static view and quickly composite - * it during each frame. - * - * Rasterization incurs an off-screen drawing pass and the bitmap consumes - * memory. Test and measure when using this property. - * @platform ios - */ - shouldRasterizeIOS: PropTypes.bool, - - /** - * Views that are only used to layout their children or otherwise don't draw - * anything may be automatically removed from the native hierarchy as an - * optimization. Set this property to `false` to disable this optimization and - * ensure that this View exists in the native view hierarchy. - * @platform android - */ - collapsable: PropTypes.bool, - - /** - * Whether this view needs to rendered offscreen and composited with an alpha - * in order to preserve 100% correct colors and blending behavior. The default - * (false) falls back to drawing the component and its children with an alpha - * applied to the paint used to draw each element instead of rendering the full - * component offscreen and compositing it back with an alpha value. This default - * may be noticeable and undesired in the case where the View you are setting - * an opacity on has multiple overlapping elements (e.g. multiple overlapping - * Views, or text and a background). - * - * Rendering offscreen to preserve correct alpha behavior is extremely - * expensive and hard to debug for non-native developers, which is why it is - * not turned on by default. If you do need to enable this property for an - * animation, consider combining it with renderToHardwareTextureAndroid if the - * view **contents** are static (i.e. it doesn't need to be redrawn each frame). - * If that property is enabled, this View will be rendered off-screen once, - * saved in a hardware texture, and then composited onto the screen with an alpha - * each frame without having to switch rendering targets on the GPU. - * - * @platform android - */ - needsOffscreenAlphaCompositing: PropTypes.bool, - }, - - mixins: [NativeMethodsMixin], - - statics: { - ...statics, - }, - - render() { - return null; - }, -}); - -module.exports = View; diff --git a/src/components/WebView.js b/src/components/WebView.js deleted file mode 100644 index b4aac8b..0000000 --- a/src/components/WebView.js +++ /dev/null @@ -1,145 +0,0 @@ -import EdgeInsetsPropType from '../propTypes/EdgeInsetsPropType'; -import React from 'react'; -import View from './View'; -import ScrollView from './ScrollView'; -import WebViewManager from '../NativeModules/WebViewManager'; - -const { PropTypes } = React; - -const RCT_WEBVIEW_REF = 'webview'; - -const NavigationType = { - click: WebViewManager.NavigationType.LinkClicked, - formsubmit: WebViewManager.NavigationType.FormSubmitted, - backforward: WebViewManager.NavigationType.BackForward, - reload: WebViewManager.NavigationType.Reload, - formresubmit: WebViewManager.NavigationType.FormResubmitted, - other: WebViewManager.NavigationType.Other, -}; - -const JSNavigationScheme = WebViewManager.JSNavigationScheme; - -const WebView = React.createClass({ - propTypes: { - ...View.propTypes, - url: PropTypes.string, - html: PropTypes.string, - /** - * Function that returns a view to show if there's an error. - */ - renderError: PropTypes.func, // view to show if there's an error - /** - * Function that returns a loading indicator. - */ - renderLoading: PropTypes.func, - /** - * Invoked when load finish - */ - onLoad: PropTypes.func, - /** - * Invoked when load either succeeds or fails - */ - onLoadEnd: PropTypes.func, - /** - * Invoked on load start - */ - onLoadStart: PropTypes.func, - /** - * Invoked when load fails - */ - onError: PropTypes.func, - /** - * @platform ios - */ - bounces: PropTypes.bool, - /** - * A floating-point number that determines how quickly the scroll view - * decelerates after the user lifts their finger. You may also use string - * shortcuts `"normal"` and `"fast"` which match the underlying iOS settings - * for `UIScrollViewDecelerationRateNormal` and - * `UIScrollViewDecelerationRateFast` respectively. - * - Normal: 0.998 - * - Fast: 0.9 (the default for iOS WebView) - * @platform ios - */ - decelerationRate: ScrollView.propTypes.decelerationRate, - /** - * @platform ios - */ - scrollEnabled: PropTypes.bool, - automaticallyAdjustContentInsets: PropTypes.bool, - contentInset: EdgeInsetsPropType, - onNavigationStateChange: PropTypes.func, - startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load - style: View.propTypes.style, - - /** - * Used on Android only, JS is enabled by default for WebView on iOS - * @platform android - */ - javaScriptEnabled: PropTypes.bool, - - /** - * Used on Android only, controls whether DOM Storage is enabled or not - * @platform android - */ - domStorageEnabled: PropTypes.bool, - - /** - * Sets the JS to be injected when the webpage loads. - */ - injectedJavaScript: PropTypes.string, - - /** - * Sets whether the webpage scales to fit the view and the user can change the scale. - * @platform ios - */ - scalesPageToFit: PropTypes.bool, - - /** - * Allows custom handling of any webview requests by a JS handler. Return true - * or false from this method to continue loading the request. - * @platform ios - */ - onShouldStartLoadWithRequest: PropTypes.func, - - /** - * Determines whether HTML5 videos play inline or use the native full-screen - * controller. - * default value `false` - * **NOTE** : "In order for video to play inline, not only does this - * property need to be set to true, but the video element in the HTML - * document must also include the webkit-playsinline attribute." - * @platform ios - */ - allowsInlineMediaPlayback: PropTypes.bool, - }, - - statics: { - JSNavigationScheme, - NavigationType, - }, - - getWebViewHandle() { - // TODO(lmr): React.findNodeHandle - return React.findNodeHandle(this.refs[RCT_WEBVIEW_REF]); - }, - - reload() { - // do nothing - }, - - goForward() { - // do nothing - }, - - goBack() { - // do nothing - }, - - render() { - return null; - }, -}); - -module.exports = WebView; diff --git a/src/components/createMockComponent.js b/src/components/createMockComponent.js deleted file mode 100644 index f7b1a32..0000000 --- a/src/components/createMockComponent.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react'; - -function createMockComponent(displayName) { - return React.createClass({ - displayName, - render() { - return null; - }, - }); -} - -module.exports = createMockComponent; diff --git a/src/defineGlobalProperty.js b/src/defineGlobalProperty.js deleted file mode 100644 index b849756..0000000 --- a/src/defineGlobalProperty.js +++ /dev/null @@ -1,8 +0,0 @@ -function defineGlobalProperty(name, value) { - Object.defineProperty(global, name, { - configurable: true, - value: value(), - }); -} - -export default defineGlobalProperty; diff --git a/src/mixins/NativeMethodsMixin.js b/src/mixins/NativeMethodsMixin.js deleted file mode 100644 index 47e6cf6..0000000 --- a/src/mixins/NativeMethodsMixin.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/ReactIOS/NativeMethodsMixin.js - */ -module.exports = { - measure(callback) { - - }, - measureLayout(relativeToNativeNode, onSuccess, onFail) { - - }, - setNativeProps(nativeProps) { - - }, - focus() { - - }, - blur() { - - }, -}; diff --git a/src/mixins/ScrollResponder.js b/src/mixins/ScrollResponder.js deleted file mode 100644 index afea6ef..0000000 --- a/src/mixins/ScrollResponder.js +++ /dev/null @@ -1,509 +0,0 @@ -import ScrollViewManager from '../NativeModules/ScrollViewManager'; -import Platform from '../plugins/Platform'; -import Dimensions from '../api/Dimensions'; -import DeviceEventEmitter from '../plugins/DeviceEventEmitter'; -import React from 'react'; -import invariant from 'invariant'; -import warning from 'warning'; -import TextInputState from '../api/TextInputState'; -import Subscribable from './Subscribable'; -import UIManager from '../NativeModules/UIManager'; - -/** - * Mixin that can be integrated in order to handle scrolling that plays well - * with `ResponderEventPlugin`. Integrate with your platform specific scroll - * views, or even your custom built (every-frame animating) scroll views so that - * all of these systems play well with the `ResponderEventPlugin`. - * - * iOS scroll event timing nuances: - * =============================== - * - * - * Scrolling without bouncing, if you touch down: - * ------------------------------- - * - * 1. `onMomentumScrollBegin` (when animation begins after letting up) - * ... physical touch starts ... - * 2. `onTouchStartCapture` (when you press down to stop the scroll) - * 3. `onTouchStart` (same, but bubble phase) - * 4. `onResponderRelease` (when lifting up - you could pause forever before * lifting) - * 5. `onMomentumScrollEnd` - * - * - * Scrolling with bouncing, if you touch down: - * ------------------------------- - * - * 1. `onMomentumScrollBegin` (when animation begins after letting up) - * ... bounce begins ... - * ... some time elapses ... - * ... physical touch during bounce ... - * 2. `onMomentumScrollEnd` (Makes no sense why this occurs first during bounce) - * 3. `onTouchStartCapture` (immediately after `onMomentumScrollEnd`) - * 4. `onTouchStart` (same, but bubble phase) - * 5. `onTouchEnd` (You could hold the touch start for a long time) - * 6. `onMomentumScrollBegin` (When releasing the view starts bouncing back) - * - * So when we receive an `onTouchStart`, how can we tell if we are touching - * *during* an animation (which then causes the animation to stop)? The only way - * to tell is if the `touchStart` occurred immediately after the - * `onMomentumScrollEnd`. - * - * This is abstracted out for you, so you can just call this.scrollResponderIsAnimating() if - * necessary - * - * `ScrollResponder` also includes logic for blurring a currently focused input - * if one is focused while scrolling. The `ScrollResponder` is a natural place - * to put this logic since it can support not dismissing the keyboard while - * scrolling, unless a recognized "tap"-like gesture has occurred. - * - * The public lifecycle API includes events for keyboard interaction, responder - * interaction, and scrolling (among others). The keyboard callbacks - * `onKeyboardWill/Did/*` are *global* events, but are invoked on scroll - * responder's props so that you can guarantee that the scroll responder's - * internal state has been updated accordingly (and deterministically) by - * the time the props callbacks are invoke. Otherwise, you would always wonder - * if the scroll responder is currently in a state where it recognizes new - * keyboard positions etc. If coordinating scrolling with keyboard movement, - * *always* use these hooks instead of listening to your own global keyboard - * events. - * - * Public keyboard lifecycle API: (props callbacks) - * - * Standard Keyboard Appearance Sequence: - * - * this.props.onKeyboardWillShow - * this.props.onKeyboardDidShow - * - * `onScrollResponderKeyboardDismissed` will be invoked if an appropriate - * tap inside the scroll responder's scrollable region was responsible - * for the dismissal of the keyboard. There are other reasons why the - * keyboard could be dismissed. - * - * this.props.onScrollResponderKeyboardDismissed - * - * Standard Keyboard Hide Sequence: - * - * this.props.onKeyboardWillHide - * this.props.onKeyboardDidHide - */ - -const IS_ANIMATING_TOUCH_START_THRESHOLD_MS = 16; - -const ScrollResponderMixin = { - mixins: [Subscribable.Mixin], - scrollResponderMixinGetInitialState() { - return { - isTouching: false, - lastMomentumScrollBeginTime: 0, - lastMomentumScrollEndTime: 0, - - // Reset to false every time becomes responder. This is used to: - // - Determine if the scroll view has been scrolled and therefore should - // refuse to give up its responder lock. - // - Determine if releasing should dismiss the keyboard when we are in - // tap-to-dismiss mode (!this.props.keyboardShouldPersistTaps). - observedScrollSinceBecomingResponder: false, - becameResponderWhileAnimating: false, - }; - }, - - /** - * Invoke this from an `onScroll` event. - */ - scrollResponderHandleScrollShouldSetResponder() { - return this.state.isTouching; - }, - - /** - * Merely touch starting is not sufficient for a scroll view to become the - * responder. Being the "responder" means that the very next touch move/end - * event will result in an action/movement. - * - * Invoke this from an `onStartShouldSetResponder` event. - * - * `onStartShouldSetResponder` is used when the next move/end will trigger - * some UI movement/action, but when you want to yield priority to views - * nested inside of the view. - * - * There may be some cases where scroll views actually should return `true` - * from `onStartShouldSetResponder`: Any time we are detecting a standard tap - * that gives priority to nested views. - * - * - If a single tap on the scroll view triggers an action such as - * recentering a map style view yet wants to give priority to interaction - * views inside (such as dropped pins or labels), then we would return true - * from this method when there is a single touch. - * - * - Similar to the previous case, if a two finger "tap" should trigger a - * zoom, we would check the `touches` count, and if `>= 2`, we would return - * true. - * - */ - scrollResponderHandleStartShouldSetResponder() { - return false; - }, - - /** - * There are times when the scroll view wants to become the responder - * (meaning respond to the next immediate `touchStart/touchEnd`), in a way - * that *doesn't* give priority to nested views (hence the capture phase): - * - * - Currently animating. - * - Tapping anywhere that is not the focused input, while the keyboard is - * up (which should dismiss the keyboard). - * - * Invoke this from an `onStartShouldSetResponderCapture` event. - */ - scrollResponderHandleStartShouldSetResponderCapture(e) { - // First see if we want to eat taps while the keyboard is up - const currentlyFocusedTextInput = TextInputState.currentlyFocusedField(); - if (!this.props.keyboardShouldPersistTaps && - currentlyFocusedTextInput != null && - e.target !== currentlyFocusedTextInput) { - return true; - } - return this.scrollResponderIsAnimating(); - }, - - /** - * Invoke this from an `onResponderReject` event. - * - * Some other element is not yielding its role as responder. Normally, we'd - * just disable the `UIScrollView`, but a touch has already began on it, the - * `UIScrollView` will not accept being disabled after that. The easiest - * solution for now is to accept the limitation of disallowing this - * altogether. To improve this, find a way to disable the `UIScrollView` after - * a touch has already started. - */ - scrollResponderHandleResponderReject() { - warning(false, "ScrollView doesn't take rejection well - scrolls anyway"); - }, - - /** - * We will allow the scroll view to give up its lock iff it acquired the lock - * during an animation. This is a very useful default that happens to satisfy - * many common user experiences. - * - * - Stop a scroll on the left edge, then turn that into an outer view's - * backswipe. - * - Stop a scroll mid-bounce at the top, continue pulling to have the outer - * view dismiss. - * - However, without catching the scroll view mid-bounce (while it is - * motionless), if you drag far enough for the scroll view to become - * responder (and therefore drag the scroll view a bit), any backswipe - * navigation of a swipe gesture higher in the view hierarchy, should be - * rejected. - */ - scrollResponderHandleTerminationRequest() { - return !this.state.observedScrollSinceBecomingResponder; - }, - - /** - * Invoke this from an `onTouchEnd` event. - * - * @param {SyntheticEvent} e Event. - */ - scrollResponderHandleTouchEnd(e) { - const nativeEvent = e.nativeEvent; - this.state.isTouching = nativeEvent.touches.length !== 0; - if (this.props.onTouchEnd) { - this.props.onTouchEnd(e); - } - }, - - /** - * Invoke this from an `onResponderRelease` event. - */ - scrollResponderHandleResponderRelease(e) { - if (this.props.onResponderRelease) { - this.props.onResponderRelease(e); - } - - // By default scroll views will unfocus a textField - // if another touch occurs outside of it - const currentlyFocusedTextInput = TextInputState.currentlyFocusedField(); - if (!this.props.keyboardShouldPersistTaps && - currentlyFocusedTextInput != null && - e.target !== currentlyFocusedTextInput && - !this.state.observedScrollSinceBecomingResponder && - !this.state.becameResponderWhileAnimating) { - if (this.props.onScrollResponderKeyboardDismissed) { - this.props.onScrollResponderKeyboardDismissed(e); - } - TextInputState.blurTextInput(currentlyFocusedTextInput); - } - }, - - scrollResponderHandleScroll(e) { - this.state.observedScrollSinceBecomingResponder = true; - if (this.props.onScroll) { - this.props.onScroll(e); - } - }, - - /** - * Invoke this from an `onResponderGrant` event. - */ - scrollResponderHandleResponderGrant(e) { - this.state.observedScrollSinceBecomingResponder = false; - if (this.props.onResponderGrant) { - this.props.onResponderGrant(e); - } - this.state.becameResponderWhileAnimating = this.scrollResponderIsAnimating(); - }, - - /** - * Unfortunately, `onScrollBeginDrag` also fires when *stopping* the scroll - * animation, and there's not an easy way to distinguish a drag vs. stopping - * momentum. - * - * Invoke this from an `onScrollBeginDrag` event. - */ - scrollResponderHandleScrollBeginDrag(e) { - if (this.props.onScrollBeginDrag) { - this.props.onScrollBeginDrag(e); - } - }, - - /** - * Invoke this from an `onScrollEndDrag` event. - */ - scrollResponderHandleScrollEndDrag(e) { - if (this.props.onScrollEndDrag) { - this.props.onScrollEndDrag(e); - } - }, - - /** - * Invoke this from an `onMomentumScrollBegin` event. - */ - scrollResponderHandleMomentumScrollBegin(e) { - this.state.lastMomentumScrollBeginTime = Date.now(); - if (this.props.onMomentumScrollBegin) { - this.props.onMomentumScrollBegin(e); - } - }, - - /** - * Invoke this from an `onMomentumScrollEnd` event. - */ - scrollResponderHandleMomentumScrollEnd(e) { - this.state.lastMomentumScrollEndTime = Date.now(); - if (this.props.onMomentumScrollEnd) { - this.props.onMomentumScrollEnd(e); - } - }, - - /** - * Invoke this from an `onTouchStart` event. - * - * Since we know that the `SimpleEventPlugin` occurs later in the plugin - * order, after `ResponderEventPlugin`, we can detect that we were *not* - * permitted to be the responder (presumably because a contained view became - * responder). The `onResponderReject` won't fire in that case - it only - * fires when a *current* responder rejects our request. - * - * @param {SyntheticEvent} e Touch Start event. - */ - scrollResponderHandleTouchStart(e) { - this.state.isTouching = true; - if (this.props.onTouchStart) { - this.props.onTouchStart(e); - } - }, - - /** - * Invoke this from an `onTouchMove` event. - * - * Since we know that the `SimpleEventPlugin` occurs later in the plugin - * order, after `ResponderEventPlugin`, we can detect that we were *not* - * permitted to be the responder (presumably because a contained view became - * responder). The `onResponderReject` won't fire in that case - it only - * fires when a *current* responder rejects our request. - * - * @param {SyntheticEvent} e Touch Start event. - */ - scrollResponderHandleTouchMove(e) { - if (this.props.onTouchMove) { - this.props.onTouchMove(e); - } - }, - - /** - * A helper function for this class that lets us quickly determine if the - * view is currently animating. This is particularly useful to know when - * a touch has just started or ended. - */ - scrollResponderIsAnimating() { - const now = Date.now(); - const timeSinceLastMomentumScrollEnd = now - this.state.lastMomentumScrollEndTime; - const isAnimating = timeSinceLastMomentumScrollEnd < IS_ANIMATING_TOUCH_START_THRESHOLD_MS || - this.state.lastMomentumScrollEndTime < this.state.lastMomentumScrollBeginTime; - return isAnimating; - }, - - /** - * A helper function to scroll to a specific point in the scrollview. - * This is currently used to help focus on child textviews, but this - * can also be used to quickly scroll to any element we want to focus - */ - scrollResponderScrollTo(offsetX, offsetY, animated = true) { - - }, - - /** - * A helper function to zoom to a specific rect in the scrollview. - * @param {object} rect Should have shape {x, y, width, height} - * @param {bool} animated Specify whether zoom is instant or animated - */ - scrollResponderZoomTo(rect, animated = true) { - if (Platform.OS === 'android') { - invariant('zoomToRect is not implemented'); - } else { - ScrollViewManager.zoomToRect(React.findNodeHandle(this), rect, animated); - } - }, - - /** - * This method should be used as the callback to onFocus in a TextInputs' - * parent view. Note that any module using this mixin needs to return - * the parent view's ref in getScrollViewRef() in order to use this method. - * @param {any} nodeHandle The TextInput node handle - * @param {number} additionalOffset The scroll view's top "contentInset". - * Default is 0. - * @param {bool} preventNegativeScrolling Whether to allow pulling the content - * down to make it meet the keyboard's top. Default is false. - */ - scrollResponderScrollNativeHandleToKeyboard( - nodeHandle, - additionalOffset, - preventNegativeScrollOffset) { - this.additionalScrollOffset = additionalOffset || 0; - this.preventNegativeScrollOffset = !!preventNegativeScrollOffset; - UIManager.measureLayout( - nodeHandle, - React.findNodeHandle(this.getInnerViewNode()), - this.scrollResponderTextInputFocusError, - this.scrollResponderInputMeasureAndScrollToKeyboard - ); - }, - - /** - * The calculations performed here assume the scroll view takes up the entire - * screen - even if has some content inset. We then measure the offsets of the - * keyboard, and compensate both for the scroll view's "contentInset". - * - * @param {number} left Position of input w.r.t. table view. - * @param {number} top Position of input w.r.t. table view. - * @param {number} width Width of the text input. - * @param {number} height Height of the text input. - */ - scrollResponderInputMeasureAndScrollToKeyboard(left, top, width, height) { - let keyboardScreenY = Dimensions.get('window').height; - if (this.keyboardWillOpenTo) { - keyboardScreenY = this.keyboardWillOpenTo.endCoordinates.screenY; - } - let scrollOffsetY = top - keyboardScreenY + height + this.additionalScrollOffset; - - // By default, this can scroll with negative offset, pulling the content - // down so that the target component's bottom meets the keyboard's top. - // If requested otherwise, cap the offset at 0 minimum to avoid content - // shifting down. - if (this.preventNegativeScrollOffset) { - scrollOffsetY = Math.max(0, scrollOffsetY); - } - this.scrollResponderScrollTo(0, scrollOffsetY); - - this.additionalOffset = 0; - this.preventNegativeScrollOffset = false; - }, - - scrollResponderTextInputFocusError(e) { - console.error('Error measuring text field: ', e); - }, - - /** - * `componentWillMount` is the closest thing to a standard "constructor" for - * React components. - * - * The `keyboardWillShow` is called before input focus. - */ - componentWillMount() { - this.keyboardWillOpenTo = null; - this.additionalScrollOffset = 0; - this.addListenerOn( - DeviceEventEmitter, 'keyboardWillShow', this.scrollResponderKeyboardWillShow - ); - this.addListenerOn( - DeviceEventEmitter, 'keyboardWillHide', this.scrollResponderKeyboardWillHide - ); - this.addListenerOn(DeviceEventEmitter, 'keyboardDidShow', this.scrollResponderKeyboardDidShow); - this.addListenerOn(DeviceEventEmitter, 'keyboardDidHide', this.scrollResponderKeyboardDidHide); - }, - - /** - * Warning, this may be called several times for a single keyboard opening. - * It's best to store the information in this method and then take any action - * at a later point (either in `keyboardDidShow` or other). - * - * Here's the order that events occur in: - * - focus - * - willShow {startCoordinates, endCoordinates} several times - * - didShow several times - * - blur - * - willHide {startCoordinates, endCoordinates} several times - * - didHide several times - * - * The `ScrollResponder` providesModule callbacks for each of these events. - * Even though any user could have easily listened to keyboard events - * themselves, using these `props` callbacks ensures that ordering of events - * is consistent - and not dependent on the order that the keyboard events are - * subscribed to. This matters when telling the scroll view to scroll to where - * the keyboard is headed - the scroll responder better have been notified of - * the keyboard destination before being instructed to scroll to where the - * keyboard will be. Stick to the `ScrollResponder` callbacks, and everything - * will work. - * - * WARNING: These callbacks will fire even if a keyboard is displayed in a - * different navigation pane. Filter out the events to determine if they are - * relevant to you. (For example, only if you receive these callbacks after - * you had explicitly focused a node etc). - */ - scrollResponderKeyboardWillShow(e) { - this.keyboardWillOpenTo = e; - if (this.props.onKeyboardWillShow) { - this.props.onKeyboardWillShow(e); - } - }, - - scrollResponderKeyboardWillHide(e) { - this.keyboardWillOpenTo = null; - if (this.props.onKeyboardWillHide) { - this.props.onKeyboardWillHide(e); - } - }, - - scrollResponderKeyboardDidShow(e) { - // TODO(7693961): The event for DidShow is not available on iOS yet. - // Use the one from WillShow and do not assign. - if (e) { - this.keyboardWillOpenTo = e; - } - if (this.props.onKeyboardDidShow) { - this.props.onKeyoardDidShow(e); - } - }, - - scrollResponderKeyboardDidHide(e) { - this.keyboardWillOpenTo = null; - if (this.props.onKeyboardDidHide) { - this.props.onKeyboardDidHide(e); - } - } -}; - -const ScrollResponder = { - Mixin: ScrollResponderMixin, -}; - -module.exports = ScrollResponder; diff --git a/src/mixins/Subscribable.js b/src/mixins/Subscribable.js deleted file mode 100644 index 7bdc5aa..0000000 --- a/src/mixins/Subscribable.js +++ /dev/null @@ -1,39 +0,0 @@ - -const SubscribableMixin = { - - componentWillMount() { - this._subscribableSubscriptions = []; - }, - - componentWillUnmount() { - this._subscribableSubscriptions.forEach( - (subscription) => subscription.remove() - ); - this._subscribableSubscriptions = null; - }, - - /** - * Special form of calling `addListener` that *guarantees* that a - * subscription *must* be tied to a component instance, and therefore will - * be cleaned up when the component is unmounted. It is impossible to create - * the subscription and pass it in - this method must be the one to create - * the subscription and therefore can guarantee it is retained in a way that - * will be cleaned up. - * - * @param {EventEmitter} eventEmitter emitter to subscribe to. - * @param {string} eventType Type of event to listen to. - * @param {function} listener Function to invoke when event occurs. - * @param {object} context Object to use as listener context. - */ - addListenerOn(eventEmitter, eventType, listener, context) { - this._subscribableSubscriptions.push( - eventEmitter.addListener(eventType, listener, context) - ); - } -}; - -const Subscribable = { - Mixin: SubscribableMixin, -}; - -module.exports = Subscribable; diff --git a/src/plugins/DeviceEventEmitter.js b/src/plugins/DeviceEventEmitter.js deleted file mode 100644 index b04f78d..0000000 --- a/src/plugins/DeviceEventEmitter.js +++ /dev/null @@ -1,5 +0,0 @@ -const EventEmitter = require('events').EventEmitter; - -const DeviceEventEmitter = new EventEmitter(); - -module.exports = DeviceEventEmitter; diff --git a/src/plugins/NativeAppEventEmitter.js b/src/plugins/NativeAppEventEmitter.js deleted file mode 100644 index e58c8b2..0000000 --- a/src/plugins/NativeAppEventEmitter.js +++ /dev/null @@ -1,5 +0,0 @@ -const EventEmitter = require('events').EventEmitter; - -const NativeAppEventEmitter = new EventEmitter(); - -module.exports = NativeAppEventEmitter; diff --git a/src/plugins/Platform.js b/src/plugins/Platform.js deleted file mode 100644 index e24ad72..0000000 --- a/src/plugins/Platform.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Utilities/Platform.android.js - */ -const Platform = { - OS: 'ios', - Version: undefined, - - /** - * Exposed in react-native-mock for testing purposes. Not part of real API. - */ - __setOS(os) { - Platform.OS = os; - }, - - select(objs) { - return objs[Platform.OS]; - }, - - /** - * Exposed in react-native-mock for testing purposes. Not part of real API. - */ - __setVersion(version) { - Platform.Version = version; - }, -}; - -module.exports = Platform; diff --git a/src/plugins/processColor.js b/src/plugins/processColor.js deleted file mode 100644 index f43fee9..0000000 --- a/src/plugins/processColor.js +++ /dev/null @@ -1,6 +0,0 @@ -function processColor() { - // TODO(lmr): seems like a good example of something we should pull directly from RN. - return 0; -} - -module.exports = processColor; diff --git a/src/plugins/requireNativeComponent.js b/src/plugins/requireNativeComponent.js deleted file mode 100644 index 6a35800..0000000 --- a/src/plugins/requireNativeComponent.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/ReactIOS/requireNativeComponent.js - */ -import React from 'react'; - -function requireNativeComponent(viewName, componentInterface, extraConfig) { - return React.createClass({ - displayName: viewName, - render() { - return null; - }, - }); -} - -module.exports = requireNativeComponent; diff --git a/src/propTypes/ColorPropType.js b/src/propTypes/ColorPropType.js deleted file mode 100644 index 6a0e1fb..0000000 --- a/src/propTypes/ColorPropType.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/ColorPropType.js - */ -const ColorPropType = function (props, propName) { - const color = props[propName]; - if (color === undefined || color === null) { - // return; - } - - if (typeof color === 'number') { - // Developers should not use a number, but we are using the prop type - // both for user provided colors and for transformed ones. This isn't ideal - // and should be fixed but will do for now... - // return; - } - - // TODO(lmr): test color -}; - -module.exports = ColorPropType; diff --git a/src/propTypes/EdgeInsetsPropType.js b/src/propTypes/EdgeInsetsPropType.js deleted file mode 100644 index 14cd25a..0000000 --- a/src/propTypes/EdgeInsetsPropType.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/EdgeInsetsPropType.js - */ -import React from 'react'; - -const { PropTypes } = React; - -const EdgeInsetsPropType = PropTypes.shape({ - top: PropTypes.number, - left: PropTypes.number, - bottom: PropTypes.number, - right: PropTypes.number, -}); - -module.exports = EdgeInsetsPropType; diff --git a/src/propTypes/ImageResizeMode.js b/src/propTypes/ImageResizeMode.js deleted file mode 100644 index 055321c..0000000 --- a/src/propTypes/ImageResizeMode.js +++ /dev/null @@ -1,13 +0,0 @@ -import Platfrom from '../plugins/Platform'; - -const resizePropTypes = [ - 'contain', - 'cover', - 'stretch', -]; - -if (Platfrom.OS === 'ios') { - resizePropTypes.push('repeat', 'center'); -} - -module.exports = resizePropTypes; diff --git a/src/propTypes/ImageStylePropTypes.js b/src/propTypes/ImageStylePropTypes.js deleted file mode 100644 index 2522dea..0000000 --- a/src/propTypes/ImageStylePropTypes.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Image/ImageStylePropTypes.js - */ -import React from 'react'; -import ColorPropType from './ColorPropType'; -import TransformPropTypes from './TransformPropTypes'; -import ShadowPropTypesIOS from './ShadowPropTypesIOS'; -import LayoutPropTypes from './LayoutPropTypes'; -import ImageResizeMode from './ImageResizeMode'; - -const { PropTypes } = React; - -const ImageStylePropTypes = { - ...LayoutPropTypes, - ...ShadowPropTypesIOS, - ...TransformPropTypes, - resizeMode: PropTypes.oneOf(ImageResizeMode), - backfaceVisibility: PropTypes.oneOf(['visible', 'hidden']), - backgroundColor: ColorPropType, - borderColor: ColorPropType, - borderWidth: PropTypes.number, - borderRadius: PropTypes.number, - overflow: PropTypes.oneOf(['visible', 'hidden']), - - /** - * iOS-Specific style to "tint" an image. - * Changes the color of all the non-transparent pixels to the tintColor. - * @platform ios - */ - tintColor: ColorPropType, - opacity: PropTypes.number, - /** - * When the image has rounded corners, specifying an overlayColor will - * cause the remaining space in the corners to be filled with a solid color. - * This is useful in cases which are not supported by the Android - * implementation of rounded corners: - * - Certain resize modes, such as 'contain' - * - Animated GIFs - * - * A typical way to use this prop is with images displayed on a solid - * background and setting the `overlayColor` to the same color - * as the background. - * - * For details of how this works under the hood, see - * http://frescolib.org/docs/rounded-corners-and-circles.html - * - * @platform android - */ - overlayColor: PropTypes.string, -}; - -module.exports = ImageStylePropTypes; diff --git a/src/propTypes/LayoutPropTypes.js b/src/propTypes/LayoutPropTypes.js deleted file mode 100644 index 2aff673..0000000 --- a/src/propTypes/LayoutPropTypes.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/LayoutPropTypes.js - */ -import React from 'react'; - -const { PropTypes } = React; - -/** - * React Native's layout system is based on Flexbox and is powered both - * on iOS and Android by an open source project called css-layout: - * https://github.com/facebook/css-layout - * - * The implementation in css-layout is slightly different from what the - * Flexbox spec defines - for example, we chose more sensible default - * values. Please refer to the css-layout README for details. - * - * These properties are a subset of our styles that are consumed by the layout - * algorithm and affect the positioning and sizing of views. - */ -const LayoutPropTypes = { - width: PropTypes.number, - height: PropTypes.number, - top: PropTypes.number, - left: PropTypes.number, - right: PropTypes.number, - bottom: PropTypes.number, - margin: PropTypes.number, - marginVertical: PropTypes.number, - marginHorizontal: PropTypes.number, - marginTop: PropTypes.number, - marginBottom: PropTypes.number, - marginLeft: PropTypes.number, - marginRight: PropTypes.number, - padding: PropTypes.number, - paddingVertical: PropTypes.number, - paddingHorizontal: PropTypes.number, - paddingTop: PropTypes.number, - paddingBottom: PropTypes.number, - paddingLeft: PropTypes.number, - paddingRight: PropTypes.number, - borderWidth: PropTypes.number, - borderTopWidth: PropTypes.number, - borderRightWidth: PropTypes.number, - borderBottomWidth: PropTypes.number, - borderLeftWidth: PropTypes.number, - - position: PropTypes.oneOf([ - 'absolute', - 'relative' - ]), - - // https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction - flexDirection: PropTypes.oneOf([ - 'row', - 'column' - ]), - - // https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap - flexWrap: PropTypes.oneOf([ - 'wrap', - 'nowrap' - ]), - - // How to align children in the main direction - // https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content - justifyContent: PropTypes.oneOf([ - 'flex-start', - 'flex-end', - 'center', - 'space-between', - 'space-around' - ]), - - // How to align children in the cross direction - // https://developer.mozilla.org/en-US/docs/Web/CSS/align-items - alignItems: PropTypes.oneOf([ - 'flex-start', - 'flex-end', - 'center', - 'stretch' - ]), - - // How to align the element in the cross direction - // https://developer.mozilla.org/en-US/docs/Web/CSS/align-items - alignSelf: PropTypes.oneOf([ - 'auto', - 'flex-start', - 'flex-end', - 'center', - 'stretch' - ]), - - // https://developer.mozilla.org/en-US/docs/Web/CSS/flex - flex: PropTypes.number, -}; - -module.exports = LayoutPropTypes; diff --git a/src/propTypes/PointPropType.js b/src/propTypes/PointPropType.js deleted file mode 100644 index e62e116..0000000 --- a/src/propTypes/PointPropType.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/PointPropType.js - */ -import React from 'react'; - -const { PropTypes } = React; - -const PointPropType = PropTypes.shape({ - x: PropTypes.number, - y: PropTypes.number, -}); - -module.exports = PointPropType; diff --git a/src/propTypes/ShadowPropTypesIOS.js b/src/propTypes/ShadowPropTypesIOS.js deleted file mode 100644 index 8899315..0000000 --- a/src/propTypes/ShadowPropTypesIOS.js +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; -import ColorPropType from './ColorPropType'; - -const { PropTypes } = React; - -const ShadowPropTypesIOS = { - /** - * Sets the drop shadow color - * @platform ios - */ - shadowColor: ColorPropType, - /** - * Sets the drop shadow offset - * @platform ios - */ - shadowOffset: PropTypes.shape({ - width: PropTypes.number, - height: PropTypes.number, - }), - /** - * Sets the drop shadow opacity (multiplied by the color's alpha component) - * @platform ios - */ - shadowOpacity: PropTypes.number, - /** - * Sets the drop shadow blur radius - * @platform ios - */ - shadowRadius: PropTypes.number, -}; - -module.exports = ShadowPropTypesIOS; diff --git a/src/propTypes/StyleSheetPropType.js b/src/propTypes/StyleSheetPropType.js deleted file mode 100644 index c244660..0000000 --- a/src/propTypes/StyleSheetPropType.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/StyleSheetPropType.js - */ -import React from 'react'; -import flattenStyle from './flattenStyle'; - -const { PropTypes } = React; - -function StyleSheetPropType(shape) { - const shapePropType = PropTypes.shape(shape); - return function (props, propName, componentName, ...rest) { - let newProps = props; - if (props[propName]) { - // Just make a dummy prop object with only the flattened style - newProps = {}; - newProps[propName] = flattenStyle(props[propName]); - } - return shapePropType(newProps, propName, componentName, ...rest); - }; -} - -module.exports = StyleSheetPropType; diff --git a/src/propTypes/TextStylePropTypes.js b/src/propTypes/TextStylePropTypes.js deleted file mode 100644 index 143f0cc..0000000 --- a/src/propTypes/TextStylePropTypes.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Text/TextStylePropTypes.js - */ -import React from 'react'; -import ColorPropType from './ColorPropType'; -import ViewStylePropTypes from './ViewStylePropTypes'; - -const { PropTypes } = React; - -// TODO: use spread instead of Object.assign/create after #6560135 is fixed -const TextStylePropTypes = Object.assign(Object.create(ViewStylePropTypes), { - color: ColorPropType, - fontFamily: PropTypes.string, - fontSize: PropTypes.number, - fontStyle: PropTypes.oneOf(['normal', 'italic']), - /** - * Specifies font weight. The values 'normal' and 'bold' are supported for - * most fonts. Not all fonts have a variant for each of the numeric values, - * in that case the closest one is chosen. - */ - fontWeight: PropTypes.oneOf( - ['normal', 'bold', - '100', '200', '300', '400', '500', '600', '700', '800', '900'] - ), - textShadowOffset: PropTypes.shape( - { - width: PropTypes.number, - height: PropTypes.number - } - ), - textShadowRadius: PropTypes.number, - textShadowColor: ColorPropType, - /** - * @platform ios - */ - letterSpacing: PropTypes.number, - lineHeight: PropTypes.number, - /** - * Specifies text alignment. The value 'justify' is only supported on iOS. - */ - textAlign: PropTypes.oneOf( - ['auto', 'left', 'right', 'center', 'justify'] - ), - /** - * @platform android - */ - textAlignVertical: PropTypes.oneOf( - ['auto', 'top', 'bottom', 'center'] - ), - /** - * @platform ios - */ - textDecorationLine: PropTypes.oneOf( - ['none', 'underline', 'line-through', 'underline line-through'] - ), - /** - * @platform ios - */ - textDecorationStyle: PropTypes.oneOf( - ['solid', 'double', 'dotted', 'dashed'] - ), - /** - * @platform ios - */ - textDecorationColor: ColorPropType, - /** - * @platform ios - */ - writingDirection: PropTypes.oneOf( - ['auto', 'ltr', 'rtl'] - ), -}); - -module.exports = TextStylePropTypes; diff --git a/src/propTypes/TransformPropTypes.js b/src/propTypes/TransformPropTypes.js deleted file mode 100644 index b49bfe8..0000000 --- a/src/propTypes/TransformPropTypes.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/TransformPropTypes.js - */ -import React from 'react'; - -const { PropTypes } = React; - -const arrayOfNumberPropType = PropTypes.arrayOf(PropTypes.number); - -const transformMatrixPropType = function (props, propName, componentName, ...rest) { - if (props.transform && props.transformMatrix) { - return new Error( - 'transformMatrix and transform styles cannot be used on the same ' + - 'component' - ); - } - return arrayOfNumberPropType(props, propName, componentName, ...rest); -}; - -const transformPropTypes = { - transform: PropTypes.arrayOf( - PropTypes.oneOfType([ - PropTypes.shape({ perspective: PropTypes.number }), - PropTypes.shape({ rotate: PropTypes.string }), - PropTypes.shape({ rotateX: PropTypes.string }), - PropTypes.shape({ rotateY: PropTypes.string }), - PropTypes.shape({ rotateZ: PropTypes.string }), - PropTypes.shape({ scale: PropTypes.number }), - PropTypes.shape({ scaleX: PropTypes.number }), - PropTypes.shape({ scaleY: PropTypes.number }), - PropTypes.shape({ translateX: PropTypes.number }), - PropTypes.shape({ translateY: PropTypes.number }), - PropTypes.shape({ skewX: PropTypes.string }), - PropTypes.shape({ skewY: PropTypes.string }), - ]) - ), - transformMatrix: transformMatrixPropType, -}; - -module.exports = transformPropTypes; diff --git a/src/propTypes/ViewStylePropTypes.js b/src/propTypes/ViewStylePropTypes.js deleted file mode 100644 index b8e168a..0000000 --- a/src/propTypes/ViewStylePropTypes.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/Components/View/ViewStylePropTypes.js - */ -import React from 'react'; -import ColorPropType from './ColorPropType'; -import LayoutPropTypes from './LayoutPropTypes'; -import ShadowPropTypesIOS from './ShadowPropTypesIOS'; -import TransformPropTypes from './TransformPropTypes'; - -const { PropTypes } = React; - -/** - * Warning: Some of these properties may not be supported in all releases. - */ -const ViewStylePropTypes = { - ...LayoutPropTypes, - ...ShadowPropTypesIOS, - ...TransformPropTypes, - backfaceVisibility: PropTypes.oneOf(['visible', 'hidden']), - backgroundColor: ColorPropType, - borderColor: ColorPropType, - borderTopColor: ColorPropType, - borderRightColor: ColorPropType, - borderBottomColor: ColorPropType, - borderLeftColor: ColorPropType, - borderRadius: PropTypes.number, - borderTopLeftRadius: PropTypes.number, - borderTopRightRadius: PropTypes.number, - borderBottomLeftRadius: PropTypes.number, - borderBottomRightRadius: PropTypes.number, - borderStyle: PropTypes.oneOf(['solid', 'dotted', 'dashed']), - borderWidth: PropTypes.number, - borderTopWidth: PropTypes.number, - borderRightWidth: PropTypes.number, - borderBottomWidth: PropTypes.number, - borderLeftWidth: PropTypes.number, - opacity: PropTypes.number, - overflow: PropTypes.oneOf(['visible', 'hidden']), - /** - * (Android-only) Sets the elevation of a view, using Android's underlying - * [elevation API](https://developer.android.com/training/material/shadows-clipping.html#Elevation). - * This adds a drop shadow to the item and affects z-order for overlapping views. - * Only supported on Android 5.0+, has no effect on earlier versions. - * @platform android - */ - elevation: PropTypes.number, -}; - -module.exports = ViewStylePropTypes; diff --git a/src/propTypes/flattenStyle.js b/src/propTypes/flattenStyle.js deleted file mode 100644 index 9e7d1f7..0000000 --- a/src/propTypes/flattenStyle.js +++ /dev/null @@ -1,11 +0,0 @@ -function flattenStyle(style) { - if (!style) { - return undefined; - } - if (!Array.isArray(style)) { - return style; - } - return Object.assign({}, ...style); -} - -module.exports = flattenStyle; diff --git a/src/react-native.js b/src/react-native.js deleted file mode 100644 index 14acfec..0000000 --- a/src/react-native.js +++ /dev/null @@ -1,131 +0,0 @@ -/** - * https://github.com/facebook/react-native/blob/master/Libraries/react-native/react-native.js - */ -import React from 'react'; - -import createMockComponent from './components/createMockComponent'; -import defineGlobalProperty from './defineGlobalProperty'; - -// Export React, plus some native additions. -const ReactNative = { - // Components - ActivityIndicator: require('./components/ActivityIndicator'), - ActivityIndicatorIOS: require('./components/ActivityIndicatorIOS'), - ART: require('./components/ART'), - Button: createMockComponent('Button'), - DatePickerIOS: createMockComponent('DatePickerIOS'), - DrawerLayoutAndroid: require('./components/DrawerLayoutAndroid'), - Image: require('./components/Image'), - ImageEditor: createMockComponent('ImageEditor'), - ImageStore: createMockComponent('ImageStore'), - KeyboardAvoidingView: createMockComponent('KeyboardAvoidingView'), - ListView: require('./components/ListView'), - MapView: createMockComponent('MapView'), - Modal: createMockComponent('Modal'), - Navigator: require('./components/Navigator'), - NavigatorIOS: createMockComponent('NavigatorIOS'), - Picker: createMockComponent('Picker'), - PickerIOS: createMockComponent('PickerIOS'), - ProgressBarAndroid: createMockComponent('ProgressBarAndroid'), - ProgressViewIOS: createMockComponent('ProgressViewIOS'), - ScrollView: require('./components/ScrollView'), - SegmentedControlIOS: createMockComponent('SegmentedControlIOS'), - SliderIOS: createMockComponent('SliderIOS'), - SnapshotViewIOS: createMockComponent('SnapshotViewIOS'), - Switch: createMockComponent('Switch'), - PullToRefreshViewAndroid: createMockComponent('PullToRefreshViewAndroid'), - RecyclerViewBackedScrollView: createMockComponent('RecyclerViewBackedScrollView'), - RefreshControl: createMockComponent('RefreshControl'), - StatusBar: require('./components/StatusBar'), - SwitchAndroid: createMockComponent('SwitchAndroid'), - SwitchIOS: createMockComponent('SwitchIOS'), - TabBarIOS: { - ...createMockComponent('TabBarIOS'), - Item: createMockComponent('TabBarIOS.Item') - }, - Text: require('./components/Text'), - TextInput: require('./components/TextInput'), - ToastAndroid: createMockComponent('ToastAndroid'), - ToolbarAndroid: createMockComponent('ToolbarAndroid'), - Touchable: createMockComponent('Touchable'), - TouchableHighlight: createMockComponent('TouchableHighlight'), - TouchableNativeFeedback: require('./components/TouchableNativeFeedback'), - TouchableOpacity: require('./components/TouchableOpacity'), - TouchableWithoutFeedback: require('./components/TouchableWithoutFeedback'), - View: require('./components/View'), - ViewPagerAndroid: createMockComponent('ViewPagerAndroid'), - WebView: require('./components/WebView'), - - // APIs - ActionSheetIOS: require('./api/ActionSheetIOS'), - Alert: require('./api/Alert'), - AlertIOS: require('./api/AlertIOS'), - Animated: require('./api/Animated'), - AppRegistry: require('./api/AppRegistry'), - AppState: require('./api/AppState'), - AppStateIOS: require('./api/AppStateIOS'), - AsyncStorage: require('./api/AsyncStorage'), - BackAndroid: require('./api/BackAndroid'), - CameraRoll: require('./api/CameraRoll'), - Clipboard: require('./NativeModules/Clipboard'), - DatePickerAndroid: require('./api/DatePickerAndroid'), - Dimensions: require('./api/Dimensions'), - Easing: require('./api/Animated/Easing'), - ImagePickerIOS: require('./api/ImagePickerIOS'), - IntentAndroid: require('./api/IntentAndroid'), - InteractionManager: require('./api/InteractionManager'), - Keyboard: require('./api/Keyboard'), - LayoutAnimation: require('./api/LayoutAnimation'), - Linking: require('./api/Linking'), - LinkingIOS: require('./api/LinkingIOS'), - NetInfo: require('./api/NetInfo'), - PanResponder: require('./api/PanResponder'), - PixelRatio: require('./api/PixelRatio'), - PushNotificationIOS: require('./api/PushNotificationIOS'), - Settings: require('./api/Settings'), - StatusBarIOS: require('./api/StatusBarIOS'), - StyleSheet: require('./api/StyleSheet'), - TimePickerAndroid: require('./api/TimePickerAndroid'), - UIManager: require('./NativeModules/UIManager'), - VibrationIOS: require('./api/VibrationIOS'), - - // Plugins - DeviceEventEmitter: require('./plugins/DeviceEventEmitter'), - NativeAppEventEmitter: require('./plugins/NativeAppEventEmitter'), - NativeEventEmitter: require('./Libraries/EventEmitter/NativeEventEmitter'), - NativeModules: require('./NativeModules'), - Platform: require('./plugins/Platform'), - processColor: require('./plugins/processColor'), - requireNativeComponent: require('./plugins/requireNativeComponent'), - - // Prop Types - ColorPropType: require('./propTypes/ColorPropType'), - EdgeInsetsPropType: require('./propTypes/EdgeInsetsPropType'), - PointPropType: require('./propTypes/PointPropType'), - NavigationExperimental: require('./Libraries/NavigationExperimental'), -}; - - -// See http://facebook.github.io/react/docs/addons.html -const ReactNativeAddons = { - // LinkedStateMixin: require('react-addons-linked-state-mixin') deprecated, - Perf: require('react-addons-perf'), - PureRenderMixin: require('react-addons-pure-render-mixin'), - TestModule: require('./NativeModules/TestModule'), - TestUtils: require('react-addons-test-utils'), - // TODO(lmr): not sure where to find this - // batchedUpdates: require('ReactUpdates').batchedUpdates, deprecated - // cloneWithProps: require('react-addons-clone-with-props'), deprecated - createFragment: require('react-addons-create-fragment'), - update: require('react-addons-update'), -}; - -Object.assign(ReactNative, React, { addons: ReactNativeAddons }); - -// Global properties defined in https://github.com/facebook/react-native/blob/master/Libraries/Core/InitializeCore.js -defineGlobalProperty('XMLHttpRequest', () => require('./Libraries/Network/XMLHttpRequest')); -defineGlobalProperty('FormData', () => require('./Libraries/Network/FormData')); -defineGlobalProperty('Headers', () => require('./Libraries/Network/Headers')); -defineGlobalProperty('Response', () => require('./Libraries/Network/Response')); - -module.exports = ReactNative; diff --git a/src/requireLibrary.js b/src/requireLibrary.js deleted file mode 100644 index e94a286..0000000 --- a/src/requireLibrary.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Playing around with the idea of requiring libraries from RN directly. - * - * Next steps: utilize RN's packager transform in order to parse the code. - */ -const path = require('path'); -const absolutePathToRN = require.resolve('react-native'); -const relativePathToRN = path.relative(__filename, absolutePathToRN); -const pathToLibraries = path.join(relativePathToRN, '../../'); - - -function requireLibrary(lib) { - const relPath = path.join(pathToLibraries, lib); - const absPath = path.resolve(__filename, relPath); - return require(absPath); -} - -// Example Usage: -// var normalizeColor = requireLibrary('StyleSheet/normalizeColor.js'); -module.exports = requireLibrary; From 6d681c85fbde46bf79a63a022f9b10adbe2a3662 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 18:29:14 +0000 Subject: [PATCH 002/149] Update dependancies --- .babelrc | 2 +- .eslintrc | 1 - package.json | 48 +++++++++++++++++++----------------------------- 3 files changed, 20 insertions(+), 31 deletions(-) diff --git a/.babelrc b/.babelrc index 3b8efe7..dac7dc9 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,3 @@ { - "presets": ["airbnb", "react-native"], + "presets": ["react-native"], } diff --git a/.eslintrc b/.eslintrc index 63d3749..59628fd 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,7 +7,6 @@ "env": { "mocha": true }, - "parser": "babel-eslint", "rules": { "no-unused-vars": [2, {"vars": "all", "args": "none"}], "comma-dangle": 0, diff --git a/package.json b/package.json index 363eb24..0192376 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,10 @@ { "name": "react-native-mock", - "version": "0.2.9", + "version": "1.0.0", "description": "A fully mocked and test-friendly version of react native", "main": "build/react-native.js", "scripts": { - "prepublish": "npm run build", - "test": "npm run lint && npm run mocha", - "mocha": "mocha --require babel-core/register 'test/**/*.js'", - "mocha:watch": "npm run test -- --watch", - "build": "babel src --out-dir build", + "test": "npm run lint", "lint": "eslint 'src/' 'test/' 'mock.js'" }, "repository": { @@ -27,36 +23,30 @@ "url": "https://github.com/RealOrangeOne/react-native-mock/issues" }, "homepage": "https://github.com/RealOrangeOne/react-native-mock#readme", + "dependencies": { + "babel-cli": "^6.9.0", + "babel-preset-react-native": "^1.6.0", + "mockery": "=2.0.0", + "node-glob": "=1.2.0", + "react-addons-test-utils": "^15.4.1", + "react-dom": "^15.4.1", + "underscore": "=1.8.3" + }, "devDependencies": { - "babel-cli": "6.9.0", - "babel-core": "6.9.0", - "babel-eslint": "6.0.4", - "babel-preset-airbnb": "2.0.0", - "babel-preset-react-native": "1.8.0", - "chai": "3.5.0", + "chai": "=3.5.0", + "enzyme": "=2.6.0", "eslint": "2.10.2", "eslint-config-airbnb": "9.0.1", "eslint-plugin-import": "1.8.0", "eslint-plugin-jsx-a11y": "1.2.2", "eslint-plugin-react": "5.1.1", "eslint-plugin-react-native": "1.0.2", - "mocha": "2.5.3", - "react": "^15.4.0", - "react-native": "^0.38.0" - }, - "dependencies": { - "cubic-bezier": "^0.1.2", - "invariant": "^2.2.1", - "keymirror": "^0.1.1", - "raf": "^3.2.0", - "react-addons-create-fragment": "^15.4.0", - "react-addons-perf": "^15.4.0", - "react-addons-pure-render-mixin": "^15.4.0", - "react-addons-test-utils": "^15.4.0", - "react-addons-update": "^15.4.0", - "react-dom": "^15.4.0", - "react-timer-mixin": "^0.13.3", - "warning": "^2.1.0" + "mocha": "3.2.0", + "mocka": "0.0.1", + "react": "^15.4.1", + "react-addons-test-utils": "^15.4.1", + "react-dom": "^15.4.1", + "react-native": "^0.39.1" }, "peerDependencies": { "react": "*", From d9a57537db40e5af43e93edc744acfddc9f8b15d Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 18:42:51 +0000 Subject: [PATCH 003/149] Add babel build --- package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 0192376..7228e57 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "main": "build/react-native.js", "scripts": { "test": "npm run lint", - "lint": "eslint 'src/' 'test/' 'mock.js'" + "lint": "eslint 'src/' 'test/' 'mock.js'", + "build": "babel src --out-dir build" }, "repository": { "type": "git", @@ -24,7 +25,7 @@ }, "homepage": "https://github.com/RealOrangeOne/react-native-mock#readme", "dependencies": { - "babel-cli": "^6.9.0", + "babel-core": "^6.9.0", "babel-preset-react-native": "^1.6.0", "mockery": "=2.0.0", "node-glob": "=1.2.0", @@ -33,6 +34,7 @@ "underscore": "=1.8.3" }, "devDependencies": { + "babel-cli": "=6.9.0", "chai": "=3.5.0", "enzyme": "=2.6.0", "eslint": "2.10.2", From 96b1114861abbc98023470dd34df4d52bf27c752 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 21:06:59 +0000 Subject: [PATCH 004/149] Add haste map generator --- haste-map.json | 404 ++++++++++++++++++++++++++++++++++++ src/haste.js | 23 ++ src/react-native-version.js | 3 + 3 files changed, 430 insertions(+) create mode 100644 haste-map.json create mode 100644 src/haste.js create mode 100644 src/react-native-version.js diff --git a/haste-map.json b/haste-map.json new file mode 100644 index 0000000..42ea6ef --- /dev/null +++ b/haste-map.json @@ -0,0 +1,404 @@ +{ + "hasteMap": { + "ActionSheetIOS": "node_modules/react-native/Libraries/ActionSheetIOS/ActionSheetIOS.js", + "AdSupportIOS": "node_modules/react-native/Libraries/AdSupport/AdSupportIOS.js", + "Alert": "node_modules/react-native/Libraries/Alert/Alert.js", + "AlertIOS": "node_modules/react-native/Libraries/Alert/AlertIOS.js", + "RCTAlertManager": "node_modules/react-native/Libraries/Alert/RCTAlertManager.ios.js", + "Animated": "node_modules/react-native/Libraries/Animated/src/Animated.js", + "AnimatedImplementation": "node_modules/react-native/Libraries/Animated/src/AnimatedImplementation.js", + "bezier": "node_modules/react-native/Libraries/Animated/src/bezier.js", + "Easing": "node_modules/react-native/Libraries/Animated/src/Easing.js", + "Interpolation": "node_modules/react-native/Libraries/Animated/src/Interpolation.js", + "NativeAnimatedHelper": "node_modules/react-native/Libraries/Animated/src/NativeAnimatedHelper.js", + "SpringConfig": "node_modules/react-native/Libraries/Animated/src/SpringConfig.js", + "AppState": "node_modules/react-native/Libraries/AppState/AppState.js", + "ARTSerializablePath": "node_modules/react-native/Libraries/ART/ARTSerializablePath.js", + "ReactNativeART": "node_modules/react-native/Libraries/ART/ReactNativeART.js", + "MessageQueueTestModule": "node_modules/react-native/Libraries/BatchedBridge/__mocks__/MessageQueueTestModule.js", + "BatchedBridge": "node_modules/react-native/Libraries/BatchedBridge/BatchedBridge.js", + "MessageQueue": "node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js", + "NativeModules": "node_modules/react-native/Libraries/BatchedBridge/NativeModules.js", + "BugReporting": "node_modules/react-native/Libraries/BugReporting/BugReporting.js", + "dumpReactTree": "node_modules/react-native/Libraries/BugReporting/dumpReactTree.js", + "getReactData": "node_modules/react-native/Libraries/BugReporting/getReactData.js", + "CameraRoll": "node_modules/react-native/Libraries/CameraRoll/CameraRoll.js", + "ImagePickerIOS": "node_modules/react-native/Libraries/CameraRoll/ImagePickerIOS.js", + "ActivityIndicator": "node_modules/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.js", + "Button": "node_modules/react-native/Libraries/Components/Button.js", + "Clipboard": "node_modules/react-native/Libraries/Components/Clipboard/Clipboard.js", + "DatePickerIOS": "node_modules/react-native/Libraries/Components/DatePicker/DatePickerIOS.ios.js", + "DatePickerAndroid": "node_modules/react-native/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js", + "DrawerLayoutAndroid": "node_modules/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.ios.js", + "Keyboard": "node_modules/react-native/Libraries/Components/Keyboard/Keyboard.js", + "KeyboardAvoidingView": "node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js", + "LazyRenderer": "node_modules/react-native/Libraries/Components/LazyRenderer.js", + "MapView": "node_modules/react-native/Libraries/Components/MapView/MapView.js", + "NavigatorIOS": "node_modules/react-native/Libraries/Components/Navigation/NavigatorIOS.ios.js", + "Picker": "node_modules/react-native/Libraries/Components/Picker/Picker.js", + "PickerAndroid": "node_modules/react-native/Libraries/Components/Picker/PickerAndroid.ios.js", + "PickerIOS": "node_modules/react-native/Libraries/Components/Picker/PickerIOS.ios.js", + "ProgressBarAndroid": "node_modules/react-native/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.ios.js", + "ProgressViewIOS": "node_modules/react-native/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js", + "RefreshControl": "node_modules/react-native/Libraries/Components/RefreshControl/RefreshControl.js", + "ScrollResponder": "node_modules/react-native/Libraries/Components/ScrollResponder.js", + "processDecelerationRate": "node_modules/react-native/Libraries/Components/ScrollView/processDecelerationRate.js", + "RecyclerViewBackedScrollView": "node_modules/react-native/Libraries/Components/ScrollView/RecyclerViewBackedScrollView.ios.js", + "ScrollView": "node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js", + "SegmentedControlIOS": "node_modules/react-native/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js", + "Slider": "node_modules/react-native/Libraries/Components/Slider/Slider.js", + "StaticContainer.react": "node_modules/react-native/Libraries/Components/StaticContainer.js", + "StaticRenderer": "node_modules/react-native/Libraries/Components/StaticRenderer.js", + "StatusBar": "node_modules/react-native/Libraries/Components/StatusBar/StatusBar.js", + "StatusBarIOS": "node_modules/react-native/Libraries/Components/StatusBar/StatusBarIOS.ios.js", + "Subscribable": "node_modules/react-native/Libraries/Components/Subscribable.js", + "Switch": "node_modules/react-native/Libraries/Components/Switch/Switch.js", + "TabBarIOS": "node_modules/react-native/Libraries/Components/TabBarIOS/TabBarIOS.ios.js", + "TabBarItemIOS": "node_modules/react-native/Libraries/Components/TabBarIOS/TabBarItemIOS.ios.js", + "TextInput": "node_modules/react-native/Libraries/Components/TextInput/TextInput.js", + "TextInputState": "node_modules/react-native/Libraries/Components/TextInput/TextInputState.js", + "TimePickerAndroid": "node_modules/react-native/Libraries/Components/TimePickerAndroid/TimePickerAndroid.ios.js", + "ToastAndroid": "node_modules/react-native/Libraries/Components/ToastAndroid/ToastAndroid.ios.js", + "ToolbarAndroid": "node_modules/react-native/Libraries/Components/ToolbarAndroid/ToolbarAndroid.ios.js", + "BoundingDimensions": "node_modules/react-native/Libraries/Components/Touchable/BoundingDimensions.js", + "ensureComponentIsNative": "node_modules/react-native/Libraries/Components/Touchable/ensureComponentIsNative.js", + "ensurePositiveDelayProps": "node_modules/react-native/Libraries/Components/Touchable/ensurePositiveDelayProps.js", + "Position": "node_modules/react-native/Libraries/Components/Touchable/Position.js", + "Touchable": "node_modules/react-native/Libraries/Components/Touchable/Touchable.js", + "TouchableBounce": "node_modules/react-native/Libraries/Components/Touchable/TouchableBounce.js", + "TouchableHighlight": "node_modules/react-native/Libraries/Components/Touchable/TouchableHighlight.js", + "TouchableNativeFeedback": "node_modules/react-native/Libraries/Components/Touchable/TouchableNativeFeedback.ios.js", + "TouchableOpacity": "node_modules/react-native/Libraries/Components/Touchable/TouchableOpacity.js", + "TouchableWithoutFeedback": "node_modules/react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js", + "UnimplementedView": "node_modules/react-native/Libraries/Components/UnimplementedViews/UnimplementedView.js", + "ReactNativeStyleAttributes": "node_modules/react-native/Libraries/Components/View/ReactNativeStyleAttributes.js", + "ReactNativeViewAttributes": "node_modules/react-native/Libraries/Components/View/ReactNativeViewAttributes.js", + "ShadowPropTypesIOS": "node_modules/react-native/Libraries/Components/View/ShadowPropTypesIOS.js", + "View": "node_modules/react-native/Libraries/Components/View/View.js", + "ViewStylePropTypes": "node_modules/react-native/Libraries/Components/View/ViewStylePropTypes.js", + "ViewPagerAndroid": "node_modules/react-native/Libraries/Components/ViewPager/ViewPagerAndroid.ios.js", + "WebView": "node_modules/react-native/Libraries/Components/WebView/WebView.ios.js", + "getDevServer": "node_modules/react-native/Libraries/Core/Devtools/getDevServer.js", + "openFileInEditor": "node_modules/react-native/Libraries/Core/Devtools/openFileInEditor.js", + "parseErrorStack": "node_modules/react-native/Libraries/Core/Devtools/parseErrorStack.js", + "setupDevtools": "node_modules/react-native/Libraries/Core/Devtools/setupDevtools.js", + "symbolicateStackTrace": "node_modules/react-native/Libraries/Core/Devtools/symbolicateStackTrace.js", + "ErrorUtils": "node_modules/react-native/Libraries/Core/ErrorUtils.js", + "ExceptionsManager": "node_modules/react-native/Libraries/Core/ExceptionsManager.js", + "InitializeCore": "node_modules/react-native/Libraries/Core/InitializeCore.js", + "JSTimers": "node_modules/react-native/Libraries/Core/Timers/JSTimers.js", + "JSTimersExecution": "node_modules/react-native/Libraries/Core/Timers/JSTimersExecution.js", + "ListView": "node_modules/react-native/Libraries/CustomComponents/ListView/ListView.js", + "ListViewDataSource": "node_modules/react-native/Libraries/CustomComponents/ListView/ListViewDataSource.js", + "NavigationAnimatedValueSubscription": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationAnimatedValueSubscription.js", + "NavigationCard": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationCard.js", + "NavigationCardStack": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js", + "NavigationCardStackPanResponder": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationCardStackPanResponder.js", + "NavigationCardStackStyleInterpolator": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationCardStackStyleInterpolator.js", + "NavigationHeader": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationHeader.js", + "NavigationHeaderBackButton": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderBackButton.js", + "NavigationHeaderStyleInterpolator": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderStyleInterpolator.js", + "NavigationHeaderTitle": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderTitle.js", + "NavigationPagerPanResponder": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationPagerPanResponder.js", + "NavigationPagerStyleInterpolator": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationPagerStyleInterpolator.js", + "NavigationPointerEventsContainer": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationPointerEventsContainer.js", + "NavigationContext": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationContext.js", + "NavigationEvent": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationEvent.js", + "NavigationEventEmitter": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationEventEmitter.js", + "NavigationRouteStack": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationRouteStack.js", + "NavigationTreeNode": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationTreeNode.js", + "Navigator": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigator.js", + "NavigatorBreadcrumbNavigationBar": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorBreadcrumbNavigationBar.js", + "NavigatorBreadcrumbNavigationBarStyles": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorBreadcrumbNavigationBarStyles.ios.js", + "NavigatorNavigationBar": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorNavigationBar.js", + "NavigatorNavigationBarStylesAndroid": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorNavigationBarStylesAndroid.js", + "NavigatorNavigationBarStylesIOS": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorNavigationBarStylesIOS.js", + "NavigatorSceneConfigs": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js", + "RCTDebugComponentOwnership": "node_modules/react-native/Libraries/DebugComponentHierarchy/RCTDebugComponentOwnership.js", + "EmitterSubscription": "node_modules/react-native/Libraries/EventEmitter/EmitterSubscription.js", + "EventEmitter": "node_modules/react-native/Libraries/EventEmitter/EventEmitter.js", + "EventEmitterWithHolding": "node_modules/react-native/Libraries/EventEmitter/EventEmitterWithHolding.js", + "EventHolder": "node_modules/react-native/Libraries/EventEmitter/EventHolder.js", + "EventSubscription": "node_modules/react-native/Libraries/EventEmitter/EventSubscription.js", + "EventSubscriptionVendor": "node_modules/react-native/Libraries/EventEmitter/EventSubscriptionVendor.js", + "EventValidator": "node_modules/react-native/Libraries/EventEmitter/EventValidator.js", + "mixInEventEmitter": "node_modules/react-native/Libraries/EventEmitter/mixInEventEmitter.js", + "NativeEventEmitter": "node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js", + "RCTDeviceEventEmitter": "node_modules/react-native/Libraries/EventEmitter/RCTDeviceEventEmitter.js", + "RCTEventEmitter": "node_modules/react-native/Libraries/EventEmitter/RCTEventEmitter.js", + "RCTNativeAppEventEmitter": "node_modules/react-native/Libraries/EventEmitter/RCTNativeAppEventEmitter.js", + "Incremental": "node_modules/react-native/Libraries/Experimental/Incremental.js", + "IncrementalExample": "node_modules/react-native/Libraries/Experimental/IncrementalExample.js", + "IncrementalGroup": "node_modules/react-native/Libraries/Experimental/IncrementalGroup.js", + "IncrementalPresenter": "node_modules/react-native/Libraries/Experimental/IncrementalPresenter.js", + "SwipeableListView": "node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableListView.js", + "SwipeableListViewDataSource": "node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableListViewDataSource.js", + "SwipeableQuickActionButton": "node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableQuickActionButton.js", + "SwipeableQuickActions": "node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js", + "SwipeableRow": "node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableRow.js", + "ViewabilityHelper": "node_modules/react-native/Libraries/Experimental/ViewabilityHelper.js", + "WindowedListView": "node_modules/react-native/Libraries/Experimental/WindowedListView.js", + "Geolocation": "node_modules/react-native/Libraries/Geolocation/Geolocation.js", + "AssetRegistry": "node_modules/react-native/Libraries/Image/AssetRegistry.js", + "AssetSourceResolver": "node_modules/react-native/Libraries/Image/AssetSourceResolver.js", + "GlobalImageStub": "node_modules/react-native/Libraries/Image/GlobalImageStub.js", + "Image": "node_modules/react-native/Libraries/Image/Image.ios.js", + "ImageEditor": "node_modules/react-native/Libraries/Image/ImageEditor.js", + "ImageResizeMode": "node_modules/react-native/Libraries/Image/ImageResizeMode.js", + "ImageSource": "node_modules/react-native/Libraries/Image/ImageSource.js", + "ImageSourcePropType": "node_modules/react-native/Libraries/Image/ImageSourcePropType.js", + "ImageStore": "node_modules/react-native/Libraries/Image/ImageStore.js", + "ImageStylePropTypes": "node_modules/react-native/Libraries/Image/ImageStylePropTypes.js", + "nativeImageSource": "node_modules/react-native/Libraries/Image/nativeImageSource.js", + "RelativeImageStub": "node_modules/react-native/Libraries/Image/RelativeImageStub.js", + "resolveAssetSource": "node_modules/react-native/Libraries/Image/resolveAssetSource.js", + "BorderBox": "node_modules/react-native/Libraries/Inspector/BorderBox.js", + "BoxInspector": "node_modules/react-native/Libraries/Inspector/BoxInspector.js", + "ElementBox": "node_modules/react-native/Libraries/Inspector/ElementBox.js", + "ElementProperties": "node_modules/react-native/Libraries/Inspector/ElementProperties.js", + "Inspector": "node_modules/react-native/Libraries/Inspector/Inspector.js", + "InspectorOverlay": "node_modules/react-native/Libraries/Inspector/InspectorOverlay.js", + "InspectorPanel": "node_modules/react-native/Libraries/Inspector/InspectorPanel.js", + "InspectorUtils": "node_modules/react-native/Libraries/Inspector/InspectorUtils.js", + "NetworkOverlay": "node_modules/react-native/Libraries/Inspector/NetworkOverlay.js", + "PerformanceOverlay": "node_modules/react-native/Libraries/Inspector/PerformanceOverlay.js", + "resolveBoxStyle": "node_modules/react-native/Libraries/Inspector/resolveBoxStyle.js", + "StyleInspector": "node_modules/react-native/Libraries/Inspector/StyleInspector.js", + "Batchinator": "node_modules/react-native/Libraries/Interaction/Batchinator.js", + "InteractionManager": "node_modules/react-native/Libraries/Interaction/InteractionManager.js", + "InteractionMixin": "node_modules/react-native/Libraries/Interaction/InteractionMixin.js", + "JSEventLoopWatchdog": "node_modules/react-native/Libraries/Interaction/JSEventLoopWatchdog.js", + "PanResponder": "node_modules/react-native/Libraries/Interaction/PanResponder.js", + "TaskQueue": "node_modules/react-native/Libraries/Interaction/TaskQueue.js", + "InspectorAgent": "node_modules/react-native/Libraries/JSInspector/InspectorAgent.js", + "JSInspector": "node_modules/react-native/Libraries/JSInspector/JSInspector.js", + "NetworkAgent": "node_modules/react-native/Libraries/JSInspector/NetworkAgent.js", + "LayoutAnimation": "node_modules/react-native/Libraries/LayoutAnimation/LayoutAnimation.js", + "Linking": "node_modules/react-native/Libraries/Linking/Linking.js", + "Modal": "node_modules/react-native/Libraries/Modal/Modal.js", + "NavigationAbstractPanResponder": "node_modules/react-native/Libraries/NavigationExperimental/NavigationAbstractPanResponder.js", + "NavigationExperimental": "node_modules/react-native/Libraries/NavigationExperimental/NavigationExperimental.js", + "NavigationPropTypes": "node_modules/react-native/Libraries/NavigationExperimental/NavigationPropTypes.js", + "NavigationStateUtils": "node_modules/react-native/Libraries/NavigationExperimental/NavigationStateUtils.js", + "NavigationTransitioner": "node_modules/react-native/Libraries/NavigationExperimental/NavigationTransitioner.js", + "NavigationTypeDefinition": "node_modules/react-native/Libraries/NavigationExperimental/NavigationTypeDefinition.js", + "NavigationScenesReducer": "node_modules/react-native/Libraries/NavigationExperimental/Reducer/NavigationScenesReducer.js", + "fetch": "node_modules/react-native/Libraries/Network/fetch.js", + "FormData": "node_modules/react-native/Libraries/Network/FormData.js", + "NetInfo": "node_modules/react-native/Libraries/Network/NetInfo.js", + "RCTNetworking": "node_modules/react-native/Libraries/Network/RCTNetworking.ios.js", + "XHRInterceptor": "node_modules/react-native/Libraries/Network/XHRInterceptor.js", + "XMLHttpRequest": "node_modules/react-native/Libraries/Network/XMLHttpRequest.js", + "CPUProfiler": "node_modules/react-native/Libraries/Performance/CPUProfiler.js", + "QuickPerformanceLogger": "node_modules/react-native/Libraries/Performance/QuickPerformanceLogger.js", + "RCTRenderingPerf": "node_modules/react-native/Libraries/Performance/RCTRenderingPerf.js", + "SamplingProfiler": "node_modules/react-native/Libraries/Performance/SamplingProfiler.js", + "Systrace": "node_modules/react-native/Libraries/Performance/Systrace.js", + "PermissionsAndroid": "node_modules/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js", + "Promise": "node_modules/react-native/Libraries/Promise.js", + "promiseRejectionIsError": "node_modules/react-native/Libraries/promiseRejectionIsError.js", + "PushNotificationIOS": "node_modules/react-native/Libraries/PushNotificationIOS/PushNotificationIOS.js", + "SnapshotViewIOS": "node_modules/react-native/Libraries/RCTTest/SnapshotViewIOS.ios.js", + "React": "node_modules/react-native/Libraries/react-native/React.js", + "AppContainer": "node_modules/react-native/Libraries/ReactNative/AppContainer.js", + "AppRegistry": "node_modules/react-native/Libraries/ReactNative/AppRegistry.js", + "I18nManager": "node_modules/react-native/Libraries/ReactNative/I18nManager.js", + "queryLayoutByID": "node_modules/react-native/Libraries/ReactNative/queryLayoutByID.js", + "renderApplication": "node_modules/react-native/Libraries/ReactNative/renderApplication.js", + "requireNativeComponent": "node_modules/react-native/Libraries/ReactNative/requireNativeComponent.js", + "UIManager": "node_modules/react-native/Libraries/ReactNative/UIManager.js", + "UIManagerStatTracker": "node_modules/react-native/Libraries/ReactNative/UIManagerStatTracker.js", + "verifyPropTypes": "node_modules/react-native/Libraries/ReactNative/verifyPropTypes.js", + "YellowBox": "node_modules/react-native/Libraries/ReactNative/YellowBox.js", + "ReactVersion": "node_modules/react-native/Libraries/Renderer/src/ReactVersion.js", + "createReactNativeComponentClass": "node_modules/react-native/Libraries/Renderer/src/renderers/native/createReactNativeComponentClass.js", + "findNodeHandle": "node_modules/react-native/Libraries/Renderer/src/renderers/native/findNodeHandle.js", + "NativeMethodsMixin": "node_modules/react-native/Libraries/Renderer/src/renderers/native/NativeMethodsMixin.js", + "ReactNative": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNative.js", + "ReactNativeAttributePayload": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeAttributePayload.js", + "ReactNativeBaseComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeBaseComponent.js", + "ReactNativeBridgeEventPlugin": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeBridgeEventPlugin.js", + "ReactNativeComponentEnvironment": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeComponentEnvironment.js", + "ReactNativeComponentTree": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeComponentTree.js", + "ReactNativeContainerInfo": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeContainerInfo.js", + "ReactNativeDefaultInjection": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeDefaultInjection.js", + "ReactNativeDOMIDOperations": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeDOMIDOperations.js", + "ReactNativeEventEmitter": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeEventEmitter.js", + "ReactNativeEventPluginOrder": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeEventPluginOrder.js", + "ReactNativeGlobalResponderHandler": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeGlobalResponderHandler.js", + "ReactNativeMount": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeMount.js", + "ReactNativePropRegistry": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativePropRegistry.js", + "ReactNativeReconcileTransaction": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeReconcileTransaction.js", + "ReactNativeTagHandles": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeTagHandles.js", + "ReactNativeTextComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeTextComponent.js", + "ReactNativeTreeTraversal": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeTreeTraversal.js", + "ReactCoroutine": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/isomorphic/ReactCoroutine.js", + "ReactTypes": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/isomorphic/ReactTypes.js", + "ReactChildFiber": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactChildFiber.js", + "ReactFiber": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiber.js", + "ReactFiberBeginWork": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberBeginWork.js", + "ReactFiberCommitWork": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberCommitWork.js", + "ReactFiberCompleteWork": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberCompleteWork.js", + "ReactFiberReconciler": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberReconciler.js", + "ReactFiberRoot": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberRoot.js", + "ReactFiberScheduler": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberScheduler.js", + "ReactFiberUpdateQueue": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberUpdateQueue.js", + "ReactPriorityLevel": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactPriorityLevel.js", + "ReactReifiedYield": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactReifiedYield.js", + "ReactTypeOfWork": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactTypeOfWork.js", + "ReactHostOperationHistoryHook": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/hooks/ReactHostOperationHistoryHook.js", + "ReactInvalidSetStateWarningHook": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/hooks/ReactInvalidSetStateWarningHook.js", + "ReactDebugTool": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/ReactDebugTool.js", + "ReactInstrumentation": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/ReactInstrumentation.js", + "ReactPerf": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/ReactPerf.js", + "ReactInstanceMap": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/shared/ReactInstanceMap.js", + "shouldUpdateReactComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/shared/shouldUpdateReactComponent.js", + "EventConstants": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/EventConstants.js", + "EventPluginHub": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/EventPluginHub.js", + "EventPluginRegistry": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/EventPluginRegistry.js", + "ResponderEventPlugin": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/eventPlugins/ResponderEventPlugin.js", + "ResponderSyntheticEvent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/eventPlugins/ResponderSyntheticEvent.js", + "ResponderTouchHistoryStore": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/eventPlugins/ResponderTouchHistoryStore.js", + "TouchHistoryMath": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/eventPlugins/TouchHistoryMath.js", + "EventPluginUtils": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/EventPluginUtils.js", + "EventPropagators": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/EventPropagators.js", + "PluginModuleType": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/PluginModuleType.js", + "ReactSyntheticEventType": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/ReactSyntheticEventType.js", + "SyntheticEvent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/SyntheticEvent.js", + "getHostComponentFromComposite": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/getHostComponentFromComposite.js", + "instantiateReactComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/instantiateReactComponent.js", + "ReactChildReconciler": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactChildReconciler.js", + "ReactComponentEnvironment": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactComponentEnvironment.js", + "ReactCompositeComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js", + "ReactDefaultBatchingStrategy": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactDefaultBatchingStrategy.js", + "ReactEmptyComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactEmptyComponent.js", + "ReactEventEmitterMixin": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactEventEmitterMixin.js", + "ReactHostComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactHostComponent.js", + "ReactInstanceType": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactInstanceType.js", + "ReactMultiChild": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactMultiChild.js", + "ReactMultiChildUpdateTypes": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactMultiChildUpdateTypes.js", + "ReactNodeTypes": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactNodeTypes.js", + "ReactOwner": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactOwner.js", + "ReactReconciler": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactReconciler.js", + "ReactRef": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactRef.js", + "ReactSimpleEmptyComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactSimpleEmptyComponent.js", + "ReactUpdateQueue": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactUpdateQueue.js", + "ReactUpdates": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactUpdates.js", + "accumulate": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/accumulate.js", + "accumulateInto": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/accumulateInto.js", + "adler32": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/adler32.js", + "CallbackQueue": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/CallbackQueue.js", + "forEachAccumulated": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/forEachAccumulated.js", + "isTextInputElement": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/isTextInputElement.js", + "ReactErrorUtils": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/ReactErrorUtils.js", + "ReactFeatureFlags": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/ReactFeatureFlags.js", + "Transaction": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/Transaction.js", + "checkReactTypeSpec": "node_modules/react-native/Libraries/Renderer/src/shared/types/checkReactTypeSpec.js", + "ReactPropTypeLocationNames": "node_modules/react-native/Libraries/Renderer/src/shared/types/ReactPropTypeLocationNames.js", + "ReactPropTypeLocations": "node_modules/react-native/Libraries/Renderer/src/shared/types/ReactPropTypeLocations.js", + "ReactPropTypesSecret": "node_modules/react-native/Libraries/Renderer/src/shared/types/ReactPropTypesSecret.js", + "canDefineProperty": "node_modules/react-native/Libraries/Renderer/src/shared/utils/canDefineProperty.js", + "deprecated": "node_modules/react-native/Libraries/Renderer/src/shared/utils/deprecated.js", + "flattenChildren": "node_modules/react-native/Libraries/Renderer/src/shared/utils/flattenChildren.js", + "getIteratorFn": "node_modules/react-native/Libraries/Renderer/src/shared/utils/getIteratorFn.js", + "KeyEscapeUtils": "node_modules/react-native/Libraries/Renderer/src/shared/utils/KeyEscapeUtils.js", + "PooledClass": "node_modules/react-native/Libraries/Renderer/src/shared/utils/PooledClass.js", + "ReactElementSymbol": "node_modules/react-native/Libraries/Renderer/src/shared/utils/ReactElementSymbol.js", + "reactProdInvariant": "node_modules/react-native/Libraries/Renderer/src/shared/utils/reactProdInvariant.js", + "traverseAllChildren": "node_modules/react-native/Libraries/Renderer/src/shared/utils/traverseAllChildren.js", + "Sample": "node_modules/react-native/Libraries/Sample/Sample.ios.js", + "Settings": "node_modules/react-native/Libraries/Settings/Settings.ios.js", + "Share": "node_modules/react-native/Libraries/Share/Share.js", + "AsyncStorage": "node_modules/react-native/Libraries/Storage/AsyncStorage.js", + "ColorPropType": "node_modules/react-native/Libraries/StyleSheet/ColorPropType.js", + "EdgeInsetsPropType": "node_modules/react-native/Libraries/StyleSheet/EdgeInsetsPropType.js", + "flattenStyle": "node_modules/react-native/Libraries/StyleSheet/flattenStyle.js", + "LayoutPropTypes": "node_modules/react-native/Libraries/StyleSheet/LayoutPropTypes.js", + "normalizeColor": "node_modules/react-native/Libraries/StyleSheet/normalizeColor.js", + "PointPropType": "node_modules/react-native/Libraries/StyleSheet/PointPropType.js", + "processColor": "node_modules/react-native/Libraries/StyleSheet/processColor.js", + "processTransform": "node_modules/react-native/Libraries/StyleSheet/processTransform.js", + "setNormalizedColorAlpha": "node_modules/react-native/Libraries/StyleSheet/setNormalizedColorAlpha.js", + "StyleSheet": "node_modules/react-native/Libraries/StyleSheet/StyleSheet.js", + "StyleSheetPropType": "node_modules/react-native/Libraries/StyleSheet/StyleSheetPropType.js", + "StyleSheetTypes": "node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.js", + "StyleSheetValidation": "node_modules/react-native/Libraries/StyleSheet/StyleSheetValidation.js", + "TransformPropTypes": "node_modules/react-native/Libraries/StyleSheet/TransformPropTypes.js", + "Text": "node_modules/react-native/Libraries/Text/Text.js", + "TextStylePropTypes": "node_modules/react-native/Libraries/Text/TextStylePropTypes.js", + "TextUpdateTest": "node_modules/react-native/Libraries/Text/TextUpdateTest.js", + "BackAndroid": "node_modules/react-native/Libraries/Utilities/BackAndroid.ios.js", + "buildStyleInterpolator": "node_modules/react-native/Libraries/Utilities/buildStyleInterpolator.js", + "clamp": "node_modules/react-native/Libraries/Utilities/clamp.js", + "createStrictShapeTypeChecker": "node_modules/react-native/Libraries/Utilities/createStrictShapeTypeChecker.js", + "deepFreezeAndThrowOnMutationInDev": "node_modules/react-native/Libraries/Utilities/deepFreezeAndThrowOnMutationInDev.js", + "defineLazyObjectProperty": "node_modules/react-native/Libraries/Utilities/defineLazyObjectProperty.js", + "deprecatedPropType": "node_modules/react-native/Libraries/Utilities/deprecatedPropType.js", + "deepDiffer": "node_modules/react-native/Libraries/Utilities/differ/deepDiffer.js", + "insetsDiffer": "node_modules/react-native/Libraries/Utilities/differ/insetsDiffer.js", + "matricesDiffer": "node_modules/react-native/Libraries/Utilities/differ/matricesDiffer.js", + "pointsDiffer": "node_modules/react-native/Libraries/Utilities/differ/pointsDiffer.js", + "sizesDiffer": "node_modules/react-native/Libraries/Utilities/differ/sizesDiffer.js", + "Dimensions": "node_modules/react-native/Libraries/Utilities/Dimensions.js", + "dismissKeyboard": "node_modules/react-native/Libraries/Utilities/dismissKeyboard.js", + "groupByEveryN": "node_modules/react-native/Libraries/Utilities/groupByEveryN.js", + "HeapCapture": "node_modules/react-native/Libraries/Utilities/HeapCapture.js", + "HMRClient": "node_modules/react-native/Libraries/Utilities/HMRClient.js", + "HMRLoadingView": "node_modules/react-native/Libraries/Utilities/HMRLoadingView.ios.js", + "infoLog": "node_modules/react-native/Libraries/Utilities/infoLog.js", + "logError": "node_modules/react-native/Libraries/Utilities/logError.js", + "mapWithSeparator": "node_modules/react-native/Libraries/Utilities/mapWithSeparator.js", + "MatrixMath": "node_modules/react-native/Libraries/Utilities/MatrixMath.js", + "mergeFast": "node_modules/react-native/Libraries/Utilities/mergeFast.js", + "mergeIntoFast": "node_modules/react-native/Libraries/Utilities/mergeIntoFast.js", + "PerformanceLogger": "node_modules/react-native/Libraries/Utilities/PerformanceLogger.js", + "PixelRatio": "node_modules/react-native/Libraries/Utilities/PixelRatio.js", + "Platform": "node_modules/react-native/Libraries/Utilities/Platform.ios.js", + "RCTLog": "node_modules/react-native/Libraries/Utilities/RCTLog.js", + "stringifySafe": "node_modules/react-native/Libraries/Utilities/stringifySafe.js", + "throwOnWrongReactAPI": "node_modules/react-native/Libraries/Utilities/throwOnWrongReactAPI.js", + "truncate": "node_modules/react-native/Libraries/Utilities/truncate.js", + "utf8": "node_modules/react-native/Libraries/Utilities/utf8.js", + "_shouldPolyfillES6Collection": "node_modules/react-native/Libraries/vendor/core/_shouldPolyfillES6Collection.js", + "copyProperties": "node_modules/react-native/Libraries/vendor/core/copyProperties.js", + "getObjectValues": "node_modules/react-native/Libraries/vendor/core/getObjectValues.js", + "guid": "node_modules/react-native/Libraries/vendor/core/guid.js", + "isEmpty": "node_modules/react-native/Libraries/vendor/core/isEmpty.js", + "Map": "node_modules/react-native/Libraries/vendor/core/Map.js", + "merge": "node_modules/react-native/Libraries/vendor/core/merge.js", + "mergeHelpers": "node_modules/react-native/Libraries/vendor/core/mergeHelpers.js", + "mergeInto": "node_modules/react-native/Libraries/vendor/core/mergeInto.js", + "Set": "node_modules/react-native/Libraries/vendor/core/Set.js", + "toIterator": "node_modules/react-native/Libraries/vendor/core/toIterator.js", + "DocumentSelectionState": "node_modules/react-native/Libraries/vendor/document/selection/DocumentSelectionState.js", + "Vibration": "node_modules/react-native/Libraries/Vibration/Vibration.js", + "VibrationIOS": "node_modules/react-native/Libraries/Vibration/VibrationIOS.ios.js", + "WebSocket": "node_modules/react-native/Libraries/WebSocket/WebSocket.js", + "WebSocketEvent": "node_modules/react-native/Libraries/WebSocket/WebSocketEvent.js", + "WebSocketInterceptor": "node_modules/react-native/Libraries/WebSocket/WebSocketInterceptor.js", + "Asserts": "node_modules/react-native/ReactAndroid/src/androidTest/js/Asserts.js", + "CatalystRootViewTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/CatalystRootViewTestModule.js", + "DatePickerDialogTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/DatePickerDialogTestModule.js", + "InitialPropsTestApp": "node_modules/react-native/ReactAndroid/src/androidTest/js/InitialPropsTestApp.js", + "JSResponderTestApp": "node_modules/react-native/ReactAndroid/src/androidTest/js/JSResponderTestApp.js", + "LayoutEventsTestApp": "node_modules/react-native/ReactAndroid/src/androidTest/js/LayoutEventsTestApp.js", + "MeasureLayoutTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/MeasureLayoutTestModule.js", + "MultitouchHandlingTestAppModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/MultitouchHandlingTestAppModule.js", + "PickerAndroidTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/PickerAndroidTestModule.js", + "ProgressBarTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/ProgressBarTestModule.js", + "ScrollViewTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/ScrollViewTestModule.js", + "ShareTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/ShareTestModule.js", + "SubviewsClippingTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/SubviewsClippingTestModule.js", + "SwipeRefreshLayoutTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/SwipeRefreshLayoutTestModule.js", + "TestIdTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TestIdTestModule.js", + "TestJavaToJSArgumentsModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TestJavaToJSArgumentsModule.js", + "TestJSLocaleModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TestJSLocaleModule.js", + "TestJSToJavaParametersModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TestJSToJavaParametersModule.js", + "TextInputTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TextInputTestModule.js", + "TimePickerDialogTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TimePickerDialogTestModule.js", + "TouchBubblingTestAppModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TouchBubblingTestAppModule.js", + "UIManagerTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/UIManagerTestModule.js", + "ViewRenderingTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/ViewRenderingTestModule.js" + }, + "version": "0.39.1" +} \ No newline at end of file diff --git a/src/haste.js b/src/haste.js new file mode 100644 index 0000000..fc0691b --- /dev/null +++ b/src/haste.js @@ -0,0 +1,23 @@ +const glob = require('glob'); +const path = require('path'); +const fs = require('fs'); + +const providesRegex = /\r?\n \* @providesModule (\S+)(?=\r?\n)/; +const validName = /^[a-z0-9-_].+$/i; +const CWD = process.cwd(); + +const data = { + hasteMap: {}, + version: require('./react-native-version') +}; + +const files = glob.sync('node_modules/**/*.js'); + +files.forEach(function (file) { + const matches = providesRegex.exec(fs.readFileSync(file).toString()); + if (matches && validName.test(matches[1])) { + data.hasteMap[matches[1]] = file.replace(CWD, ''); + } +}); + +fs.writeFileSync(path.join(CWD, 'haste-map.json'), JSON.stringify(data, null, 2)); diff --git a/src/react-native-version.js b/src/react-native-version.js new file mode 100644 index 0000000..0bce277 --- /dev/null +++ b/src/react-native-version.js @@ -0,0 +1,3 @@ +const fs = require('fs'); + +module.exports = JSON.parse(fs.readFileSync('node_modules/react-native/package.json')).version; From aa72a6fae24d9a38e603609c45d361bb93132879 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 21:19:52 +0000 Subject: [PATCH 005/149] Build file on post install --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 7228e57..b2e5555 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "A fully mocked and test-friendly version of react native", "main": "build/react-native.js", "scripts": { + "postinstall": "node src/haste.js", "test": "npm run lint", "lint": "eslint 'src/' 'test/' 'mock.js'", "build": "babel src --out-dir build" From 89f467c035e7d53361590fc7616eff824e0e344a Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 21:20:34 +0000 Subject: [PATCH 006/149] Use require, dummy! --- src/react-native-version.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/react-native-version.js b/src/react-native-version.js index 0bce277..b2917bd 100644 --- a/src/react-native-version.js +++ b/src/react-native-version.js @@ -1,3 +1,3 @@ const fs = require('fs'); -module.exports = JSON.parse(fs.readFileSync('node_modules/react-native/package.json')).version; +module.exports = require('react-native/package.json').version; From 19c9cc99fb1671c685afc6ea0ea2a429cdcad89d Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 21:23:01 +0000 Subject: [PATCH 007/149] Remove old test files --- mock.js | 12 ------ src/react-native-version.js | 2 - test/StyleSheet.js | 56 -------------------------- test/basic-test.js | 9 ----- test/components/DrawerLayoutAndroid.js | 19 --------- 5 files changed, 98 deletions(-) delete mode 100644 mock.js delete mode 100644 test/StyleSheet.js delete mode 100644 test/basic-test.js delete mode 100644 test/components/DrawerLayoutAndroid.js diff --git a/mock.js b/mock.js deleted file mode 100644 index 124d710..0000000 --- a/mock.js +++ /dev/null @@ -1,12 +0,0 @@ -const ReactNativeMock = require('./build/react-native'); - -// the cache key that real react native would get -const key = require.resolve('react-native'); - -// make sure the cache is filled with our lib -require.cache[key] = { - id: key, - filename: key, - loaded: true, - exports: ReactNativeMock, -}; diff --git a/src/react-native-version.js b/src/react-native-version.js index b2917bd..f8a3c97 100644 --- a/src/react-native-version.js +++ b/src/react-native-version.js @@ -1,3 +1 @@ -const fs = require('fs'); - module.exports = require('react-native/package.json').version; diff --git a/test/StyleSheet.js b/test/StyleSheet.js deleted file mode 100644 index fef8bc7..0000000 --- a/test/StyleSheet.js +++ /dev/null @@ -1,56 +0,0 @@ -import { StyleSheet } from '../src/react-native'; -import { expect } from 'chai'; - - -describe('StyleSheet', () => { - let styles; - - beforeEach(function () { - styles = StyleSheet.create({ - listItem: { - flex: 1, - fontSize: 16, - color: 'white' - }, - selectedListItem: { - color: 'green' - }, - headerItem: { - fontWeight: 'bold' - } - }); - }); - - it('flatten', () => { - const result = StyleSheet.flatten(styles.listItem); - const expectedResult = { - flex: 1, - fontSize: 16, - color: 'white' - }; - expect(result).to.deep.equal(expectedResult); - }); - - it('flatten with array', () => { - const result = StyleSheet.flatten([styles.listItem, styles.selectedListItem]); - const expectedResult = { - flex: 1, - fontSize: 16, - color: 'green' - }; - expect(result).to.deep.equal(expectedResult); - }); - - it('flatten with nested array', () => { - const result = StyleSheet.flatten( - [styles.listItem, [styles.headerItem, styles.selectedListItem]] - ); - const expectedResult = { - flex: 1, - fontSize: 16, - color: 'green', - fontWeight: 'bold' - }; - expect(result).to.deep.equal(expectedResult); - }); -}); diff --git a/test/basic-test.js b/test/basic-test.js deleted file mode 100644 index e5368e6..0000000 --- a/test/basic-test.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from '../src/react-native'; -import { expect } from 'chai'; - -describe('Requires', () => { - it('requires', () => { - console.log(Object.keys(React)); // eslint-disable-line no-console - expect(true).to.equal(true); - }); -}); diff --git a/test/components/DrawerLayoutAndroid.js b/test/components/DrawerLayoutAndroid.js deleted file mode 100644 index 5e1af92..0000000 --- a/test/components/DrawerLayoutAndroid.js +++ /dev/null @@ -1,19 +0,0 @@ -/* eslint no-unused-expressions: 0 */ -import React from 'react'; -import { DrawerLayoutAndroid } from '../../src/react-native'; -import { expect } from 'chai'; -import ReactTestUtils from 'react-addons-test-utils'; - -describe('DrawerLayoutAndroid', () => { - it('should render an empty DrawerLayoutAndroid', () => { - const renderer = ReactTestUtils.createRenderer(); - const wrapper = renderer.getRenderOutput( {}} />); - expect(wrapper).to.be.null; - }); - - it('should have static properties for the positions', () => { - expect(DrawerLayoutAndroid.positions).to.be.an.object; - expect(DrawerLayoutAndroid.positions).to.have.property('Left'); - expect(DrawerLayoutAndroid.positions).to.have.property('Right'); - }); -}); From a8430c992134e566b56a95b985690a76a3452156 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 21:25:40 +0000 Subject: [PATCH 008/149] Add prepublish --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index b2e5555..dc7a728 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "A fully mocked and test-friendly version of react native", "main": "build/react-native.js", "scripts": { + "prepublish": "npm run build", "postinstall": "node src/haste.js", "test": "npm run lint", "lint": "eslint 'src/' 'test/' 'mock.js'", From c6a65d46b221c7e8f9079d284a19e8dd110f53da Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 21:31:34 +0000 Subject: [PATCH 009/149] dont commit the map fool! --- .gitignore | 1 + haste-map.json | 404 ------------------------------------------------- 2 files changed, 1 insertion(+), 404 deletions(-) delete mode 100644 haste-map.json diff --git a/.gitignore b/.gitignore index 51d9ef1..8631559 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ node_modules .node_repl_history /build +haste-map.json diff --git a/haste-map.json b/haste-map.json deleted file mode 100644 index 42ea6ef..0000000 --- a/haste-map.json +++ /dev/null @@ -1,404 +0,0 @@ -{ - "hasteMap": { - "ActionSheetIOS": "node_modules/react-native/Libraries/ActionSheetIOS/ActionSheetIOS.js", - "AdSupportIOS": "node_modules/react-native/Libraries/AdSupport/AdSupportIOS.js", - "Alert": "node_modules/react-native/Libraries/Alert/Alert.js", - "AlertIOS": "node_modules/react-native/Libraries/Alert/AlertIOS.js", - "RCTAlertManager": "node_modules/react-native/Libraries/Alert/RCTAlertManager.ios.js", - "Animated": "node_modules/react-native/Libraries/Animated/src/Animated.js", - "AnimatedImplementation": "node_modules/react-native/Libraries/Animated/src/AnimatedImplementation.js", - "bezier": "node_modules/react-native/Libraries/Animated/src/bezier.js", - "Easing": "node_modules/react-native/Libraries/Animated/src/Easing.js", - "Interpolation": "node_modules/react-native/Libraries/Animated/src/Interpolation.js", - "NativeAnimatedHelper": "node_modules/react-native/Libraries/Animated/src/NativeAnimatedHelper.js", - "SpringConfig": "node_modules/react-native/Libraries/Animated/src/SpringConfig.js", - "AppState": "node_modules/react-native/Libraries/AppState/AppState.js", - "ARTSerializablePath": "node_modules/react-native/Libraries/ART/ARTSerializablePath.js", - "ReactNativeART": "node_modules/react-native/Libraries/ART/ReactNativeART.js", - "MessageQueueTestModule": "node_modules/react-native/Libraries/BatchedBridge/__mocks__/MessageQueueTestModule.js", - "BatchedBridge": "node_modules/react-native/Libraries/BatchedBridge/BatchedBridge.js", - "MessageQueue": "node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js", - "NativeModules": "node_modules/react-native/Libraries/BatchedBridge/NativeModules.js", - "BugReporting": "node_modules/react-native/Libraries/BugReporting/BugReporting.js", - "dumpReactTree": "node_modules/react-native/Libraries/BugReporting/dumpReactTree.js", - "getReactData": "node_modules/react-native/Libraries/BugReporting/getReactData.js", - "CameraRoll": "node_modules/react-native/Libraries/CameraRoll/CameraRoll.js", - "ImagePickerIOS": "node_modules/react-native/Libraries/CameraRoll/ImagePickerIOS.js", - "ActivityIndicator": "node_modules/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.js", - "Button": "node_modules/react-native/Libraries/Components/Button.js", - "Clipboard": "node_modules/react-native/Libraries/Components/Clipboard/Clipboard.js", - "DatePickerIOS": "node_modules/react-native/Libraries/Components/DatePicker/DatePickerIOS.ios.js", - "DatePickerAndroid": "node_modules/react-native/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js", - "DrawerLayoutAndroid": "node_modules/react-native/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.ios.js", - "Keyboard": "node_modules/react-native/Libraries/Components/Keyboard/Keyboard.js", - "KeyboardAvoidingView": "node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js", - "LazyRenderer": "node_modules/react-native/Libraries/Components/LazyRenderer.js", - "MapView": "node_modules/react-native/Libraries/Components/MapView/MapView.js", - "NavigatorIOS": "node_modules/react-native/Libraries/Components/Navigation/NavigatorIOS.ios.js", - "Picker": "node_modules/react-native/Libraries/Components/Picker/Picker.js", - "PickerAndroid": "node_modules/react-native/Libraries/Components/Picker/PickerAndroid.ios.js", - "PickerIOS": "node_modules/react-native/Libraries/Components/Picker/PickerIOS.ios.js", - "ProgressBarAndroid": "node_modules/react-native/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.ios.js", - "ProgressViewIOS": "node_modules/react-native/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js", - "RefreshControl": "node_modules/react-native/Libraries/Components/RefreshControl/RefreshControl.js", - "ScrollResponder": "node_modules/react-native/Libraries/Components/ScrollResponder.js", - "processDecelerationRate": "node_modules/react-native/Libraries/Components/ScrollView/processDecelerationRate.js", - "RecyclerViewBackedScrollView": "node_modules/react-native/Libraries/Components/ScrollView/RecyclerViewBackedScrollView.ios.js", - "ScrollView": "node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js", - "SegmentedControlIOS": "node_modules/react-native/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js", - "Slider": "node_modules/react-native/Libraries/Components/Slider/Slider.js", - "StaticContainer.react": "node_modules/react-native/Libraries/Components/StaticContainer.js", - "StaticRenderer": "node_modules/react-native/Libraries/Components/StaticRenderer.js", - "StatusBar": "node_modules/react-native/Libraries/Components/StatusBar/StatusBar.js", - "StatusBarIOS": "node_modules/react-native/Libraries/Components/StatusBar/StatusBarIOS.ios.js", - "Subscribable": "node_modules/react-native/Libraries/Components/Subscribable.js", - "Switch": "node_modules/react-native/Libraries/Components/Switch/Switch.js", - "TabBarIOS": "node_modules/react-native/Libraries/Components/TabBarIOS/TabBarIOS.ios.js", - "TabBarItemIOS": "node_modules/react-native/Libraries/Components/TabBarIOS/TabBarItemIOS.ios.js", - "TextInput": "node_modules/react-native/Libraries/Components/TextInput/TextInput.js", - "TextInputState": "node_modules/react-native/Libraries/Components/TextInput/TextInputState.js", - "TimePickerAndroid": "node_modules/react-native/Libraries/Components/TimePickerAndroid/TimePickerAndroid.ios.js", - "ToastAndroid": "node_modules/react-native/Libraries/Components/ToastAndroid/ToastAndroid.ios.js", - "ToolbarAndroid": "node_modules/react-native/Libraries/Components/ToolbarAndroid/ToolbarAndroid.ios.js", - "BoundingDimensions": "node_modules/react-native/Libraries/Components/Touchable/BoundingDimensions.js", - "ensureComponentIsNative": "node_modules/react-native/Libraries/Components/Touchable/ensureComponentIsNative.js", - "ensurePositiveDelayProps": "node_modules/react-native/Libraries/Components/Touchable/ensurePositiveDelayProps.js", - "Position": "node_modules/react-native/Libraries/Components/Touchable/Position.js", - "Touchable": "node_modules/react-native/Libraries/Components/Touchable/Touchable.js", - "TouchableBounce": "node_modules/react-native/Libraries/Components/Touchable/TouchableBounce.js", - "TouchableHighlight": "node_modules/react-native/Libraries/Components/Touchable/TouchableHighlight.js", - "TouchableNativeFeedback": "node_modules/react-native/Libraries/Components/Touchable/TouchableNativeFeedback.ios.js", - "TouchableOpacity": "node_modules/react-native/Libraries/Components/Touchable/TouchableOpacity.js", - "TouchableWithoutFeedback": "node_modules/react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js", - "UnimplementedView": "node_modules/react-native/Libraries/Components/UnimplementedViews/UnimplementedView.js", - "ReactNativeStyleAttributes": "node_modules/react-native/Libraries/Components/View/ReactNativeStyleAttributes.js", - "ReactNativeViewAttributes": "node_modules/react-native/Libraries/Components/View/ReactNativeViewAttributes.js", - "ShadowPropTypesIOS": "node_modules/react-native/Libraries/Components/View/ShadowPropTypesIOS.js", - "View": "node_modules/react-native/Libraries/Components/View/View.js", - "ViewStylePropTypes": "node_modules/react-native/Libraries/Components/View/ViewStylePropTypes.js", - "ViewPagerAndroid": "node_modules/react-native/Libraries/Components/ViewPager/ViewPagerAndroid.ios.js", - "WebView": "node_modules/react-native/Libraries/Components/WebView/WebView.ios.js", - "getDevServer": "node_modules/react-native/Libraries/Core/Devtools/getDevServer.js", - "openFileInEditor": "node_modules/react-native/Libraries/Core/Devtools/openFileInEditor.js", - "parseErrorStack": "node_modules/react-native/Libraries/Core/Devtools/parseErrorStack.js", - "setupDevtools": "node_modules/react-native/Libraries/Core/Devtools/setupDevtools.js", - "symbolicateStackTrace": "node_modules/react-native/Libraries/Core/Devtools/symbolicateStackTrace.js", - "ErrorUtils": "node_modules/react-native/Libraries/Core/ErrorUtils.js", - "ExceptionsManager": "node_modules/react-native/Libraries/Core/ExceptionsManager.js", - "InitializeCore": "node_modules/react-native/Libraries/Core/InitializeCore.js", - "JSTimers": "node_modules/react-native/Libraries/Core/Timers/JSTimers.js", - "JSTimersExecution": "node_modules/react-native/Libraries/Core/Timers/JSTimersExecution.js", - "ListView": "node_modules/react-native/Libraries/CustomComponents/ListView/ListView.js", - "ListViewDataSource": "node_modules/react-native/Libraries/CustomComponents/ListView/ListViewDataSource.js", - "NavigationAnimatedValueSubscription": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationAnimatedValueSubscription.js", - "NavigationCard": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationCard.js", - "NavigationCardStack": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationCardStack.js", - "NavigationCardStackPanResponder": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationCardStackPanResponder.js", - "NavigationCardStackStyleInterpolator": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationCardStackStyleInterpolator.js", - "NavigationHeader": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationHeader.js", - "NavigationHeaderBackButton": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderBackButton.js", - "NavigationHeaderStyleInterpolator": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderStyleInterpolator.js", - "NavigationHeaderTitle": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationHeaderTitle.js", - "NavigationPagerPanResponder": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationPagerPanResponder.js", - "NavigationPagerStyleInterpolator": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationPagerStyleInterpolator.js", - "NavigationPointerEventsContainer": "node_modules/react-native/Libraries/CustomComponents/NavigationExperimental/NavigationPointerEventsContainer.js", - "NavigationContext": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationContext.js", - "NavigationEvent": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationEvent.js", - "NavigationEventEmitter": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationEventEmitter.js", - "NavigationRouteStack": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationRouteStack.js", - "NavigationTreeNode": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigation/NavigationTreeNode.js", - "Navigator": "node_modules/react-native/Libraries/CustomComponents/Navigator/Navigator.js", - "NavigatorBreadcrumbNavigationBar": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorBreadcrumbNavigationBar.js", - "NavigatorBreadcrumbNavigationBarStyles": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorBreadcrumbNavigationBarStyles.ios.js", - "NavigatorNavigationBar": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorNavigationBar.js", - "NavigatorNavigationBarStylesAndroid": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorNavigationBarStylesAndroid.js", - "NavigatorNavigationBarStylesIOS": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorNavigationBarStylesIOS.js", - "NavigatorSceneConfigs": "node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js", - "RCTDebugComponentOwnership": "node_modules/react-native/Libraries/DebugComponentHierarchy/RCTDebugComponentOwnership.js", - "EmitterSubscription": "node_modules/react-native/Libraries/EventEmitter/EmitterSubscription.js", - "EventEmitter": "node_modules/react-native/Libraries/EventEmitter/EventEmitter.js", - "EventEmitterWithHolding": "node_modules/react-native/Libraries/EventEmitter/EventEmitterWithHolding.js", - "EventHolder": "node_modules/react-native/Libraries/EventEmitter/EventHolder.js", - "EventSubscription": "node_modules/react-native/Libraries/EventEmitter/EventSubscription.js", - "EventSubscriptionVendor": "node_modules/react-native/Libraries/EventEmitter/EventSubscriptionVendor.js", - "EventValidator": "node_modules/react-native/Libraries/EventEmitter/EventValidator.js", - "mixInEventEmitter": "node_modules/react-native/Libraries/EventEmitter/mixInEventEmitter.js", - "NativeEventEmitter": "node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js", - "RCTDeviceEventEmitter": "node_modules/react-native/Libraries/EventEmitter/RCTDeviceEventEmitter.js", - "RCTEventEmitter": "node_modules/react-native/Libraries/EventEmitter/RCTEventEmitter.js", - "RCTNativeAppEventEmitter": "node_modules/react-native/Libraries/EventEmitter/RCTNativeAppEventEmitter.js", - "Incremental": "node_modules/react-native/Libraries/Experimental/Incremental.js", - "IncrementalExample": "node_modules/react-native/Libraries/Experimental/IncrementalExample.js", - "IncrementalGroup": "node_modules/react-native/Libraries/Experimental/IncrementalGroup.js", - "IncrementalPresenter": "node_modules/react-native/Libraries/Experimental/IncrementalPresenter.js", - "SwipeableListView": "node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableListView.js", - "SwipeableListViewDataSource": "node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableListViewDataSource.js", - "SwipeableQuickActionButton": "node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableQuickActionButton.js", - "SwipeableQuickActions": "node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js", - "SwipeableRow": "node_modules/react-native/Libraries/Experimental/SwipeableRow/SwipeableRow.js", - "ViewabilityHelper": "node_modules/react-native/Libraries/Experimental/ViewabilityHelper.js", - "WindowedListView": "node_modules/react-native/Libraries/Experimental/WindowedListView.js", - "Geolocation": "node_modules/react-native/Libraries/Geolocation/Geolocation.js", - "AssetRegistry": "node_modules/react-native/Libraries/Image/AssetRegistry.js", - "AssetSourceResolver": "node_modules/react-native/Libraries/Image/AssetSourceResolver.js", - "GlobalImageStub": "node_modules/react-native/Libraries/Image/GlobalImageStub.js", - "Image": "node_modules/react-native/Libraries/Image/Image.ios.js", - "ImageEditor": "node_modules/react-native/Libraries/Image/ImageEditor.js", - "ImageResizeMode": "node_modules/react-native/Libraries/Image/ImageResizeMode.js", - "ImageSource": "node_modules/react-native/Libraries/Image/ImageSource.js", - "ImageSourcePropType": "node_modules/react-native/Libraries/Image/ImageSourcePropType.js", - "ImageStore": "node_modules/react-native/Libraries/Image/ImageStore.js", - "ImageStylePropTypes": "node_modules/react-native/Libraries/Image/ImageStylePropTypes.js", - "nativeImageSource": "node_modules/react-native/Libraries/Image/nativeImageSource.js", - "RelativeImageStub": "node_modules/react-native/Libraries/Image/RelativeImageStub.js", - "resolveAssetSource": "node_modules/react-native/Libraries/Image/resolveAssetSource.js", - "BorderBox": "node_modules/react-native/Libraries/Inspector/BorderBox.js", - "BoxInspector": "node_modules/react-native/Libraries/Inspector/BoxInspector.js", - "ElementBox": "node_modules/react-native/Libraries/Inspector/ElementBox.js", - "ElementProperties": "node_modules/react-native/Libraries/Inspector/ElementProperties.js", - "Inspector": "node_modules/react-native/Libraries/Inspector/Inspector.js", - "InspectorOverlay": "node_modules/react-native/Libraries/Inspector/InspectorOverlay.js", - "InspectorPanel": "node_modules/react-native/Libraries/Inspector/InspectorPanel.js", - "InspectorUtils": "node_modules/react-native/Libraries/Inspector/InspectorUtils.js", - "NetworkOverlay": "node_modules/react-native/Libraries/Inspector/NetworkOverlay.js", - "PerformanceOverlay": "node_modules/react-native/Libraries/Inspector/PerformanceOverlay.js", - "resolveBoxStyle": "node_modules/react-native/Libraries/Inspector/resolveBoxStyle.js", - "StyleInspector": "node_modules/react-native/Libraries/Inspector/StyleInspector.js", - "Batchinator": "node_modules/react-native/Libraries/Interaction/Batchinator.js", - "InteractionManager": "node_modules/react-native/Libraries/Interaction/InteractionManager.js", - "InteractionMixin": "node_modules/react-native/Libraries/Interaction/InteractionMixin.js", - "JSEventLoopWatchdog": "node_modules/react-native/Libraries/Interaction/JSEventLoopWatchdog.js", - "PanResponder": "node_modules/react-native/Libraries/Interaction/PanResponder.js", - "TaskQueue": "node_modules/react-native/Libraries/Interaction/TaskQueue.js", - "InspectorAgent": "node_modules/react-native/Libraries/JSInspector/InspectorAgent.js", - "JSInspector": "node_modules/react-native/Libraries/JSInspector/JSInspector.js", - "NetworkAgent": "node_modules/react-native/Libraries/JSInspector/NetworkAgent.js", - "LayoutAnimation": "node_modules/react-native/Libraries/LayoutAnimation/LayoutAnimation.js", - "Linking": "node_modules/react-native/Libraries/Linking/Linking.js", - "Modal": "node_modules/react-native/Libraries/Modal/Modal.js", - "NavigationAbstractPanResponder": "node_modules/react-native/Libraries/NavigationExperimental/NavigationAbstractPanResponder.js", - "NavigationExperimental": "node_modules/react-native/Libraries/NavigationExperimental/NavigationExperimental.js", - "NavigationPropTypes": "node_modules/react-native/Libraries/NavigationExperimental/NavigationPropTypes.js", - "NavigationStateUtils": "node_modules/react-native/Libraries/NavigationExperimental/NavigationStateUtils.js", - "NavigationTransitioner": "node_modules/react-native/Libraries/NavigationExperimental/NavigationTransitioner.js", - "NavigationTypeDefinition": "node_modules/react-native/Libraries/NavigationExperimental/NavigationTypeDefinition.js", - "NavigationScenesReducer": "node_modules/react-native/Libraries/NavigationExperimental/Reducer/NavigationScenesReducer.js", - "fetch": "node_modules/react-native/Libraries/Network/fetch.js", - "FormData": "node_modules/react-native/Libraries/Network/FormData.js", - "NetInfo": "node_modules/react-native/Libraries/Network/NetInfo.js", - "RCTNetworking": "node_modules/react-native/Libraries/Network/RCTNetworking.ios.js", - "XHRInterceptor": "node_modules/react-native/Libraries/Network/XHRInterceptor.js", - "XMLHttpRequest": "node_modules/react-native/Libraries/Network/XMLHttpRequest.js", - "CPUProfiler": "node_modules/react-native/Libraries/Performance/CPUProfiler.js", - "QuickPerformanceLogger": "node_modules/react-native/Libraries/Performance/QuickPerformanceLogger.js", - "RCTRenderingPerf": "node_modules/react-native/Libraries/Performance/RCTRenderingPerf.js", - "SamplingProfiler": "node_modules/react-native/Libraries/Performance/SamplingProfiler.js", - "Systrace": "node_modules/react-native/Libraries/Performance/Systrace.js", - "PermissionsAndroid": "node_modules/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js", - "Promise": "node_modules/react-native/Libraries/Promise.js", - "promiseRejectionIsError": "node_modules/react-native/Libraries/promiseRejectionIsError.js", - "PushNotificationIOS": "node_modules/react-native/Libraries/PushNotificationIOS/PushNotificationIOS.js", - "SnapshotViewIOS": "node_modules/react-native/Libraries/RCTTest/SnapshotViewIOS.ios.js", - "React": "node_modules/react-native/Libraries/react-native/React.js", - "AppContainer": "node_modules/react-native/Libraries/ReactNative/AppContainer.js", - "AppRegistry": "node_modules/react-native/Libraries/ReactNative/AppRegistry.js", - "I18nManager": "node_modules/react-native/Libraries/ReactNative/I18nManager.js", - "queryLayoutByID": "node_modules/react-native/Libraries/ReactNative/queryLayoutByID.js", - "renderApplication": "node_modules/react-native/Libraries/ReactNative/renderApplication.js", - "requireNativeComponent": "node_modules/react-native/Libraries/ReactNative/requireNativeComponent.js", - "UIManager": "node_modules/react-native/Libraries/ReactNative/UIManager.js", - "UIManagerStatTracker": "node_modules/react-native/Libraries/ReactNative/UIManagerStatTracker.js", - "verifyPropTypes": "node_modules/react-native/Libraries/ReactNative/verifyPropTypes.js", - "YellowBox": "node_modules/react-native/Libraries/ReactNative/YellowBox.js", - "ReactVersion": "node_modules/react-native/Libraries/Renderer/src/ReactVersion.js", - "createReactNativeComponentClass": "node_modules/react-native/Libraries/Renderer/src/renderers/native/createReactNativeComponentClass.js", - "findNodeHandle": "node_modules/react-native/Libraries/Renderer/src/renderers/native/findNodeHandle.js", - "NativeMethodsMixin": "node_modules/react-native/Libraries/Renderer/src/renderers/native/NativeMethodsMixin.js", - "ReactNative": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNative.js", - "ReactNativeAttributePayload": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeAttributePayload.js", - "ReactNativeBaseComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeBaseComponent.js", - "ReactNativeBridgeEventPlugin": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeBridgeEventPlugin.js", - "ReactNativeComponentEnvironment": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeComponentEnvironment.js", - "ReactNativeComponentTree": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeComponentTree.js", - "ReactNativeContainerInfo": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeContainerInfo.js", - "ReactNativeDefaultInjection": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeDefaultInjection.js", - "ReactNativeDOMIDOperations": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeDOMIDOperations.js", - "ReactNativeEventEmitter": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeEventEmitter.js", - "ReactNativeEventPluginOrder": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeEventPluginOrder.js", - "ReactNativeGlobalResponderHandler": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeGlobalResponderHandler.js", - "ReactNativeMount": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeMount.js", - "ReactNativePropRegistry": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativePropRegistry.js", - "ReactNativeReconcileTransaction": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeReconcileTransaction.js", - "ReactNativeTagHandles": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeTagHandles.js", - "ReactNativeTextComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeTextComponent.js", - "ReactNativeTreeTraversal": "node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeTreeTraversal.js", - "ReactCoroutine": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/isomorphic/ReactCoroutine.js", - "ReactTypes": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/isomorphic/ReactTypes.js", - "ReactChildFiber": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactChildFiber.js", - "ReactFiber": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiber.js", - "ReactFiberBeginWork": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberBeginWork.js", - "ReactFiberCommitWork": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberCommitWork.js", - "ReactFiberCompleteWork": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberCompleteWork.js", - "ReactFiberReconciler": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberReconciler.js", - "ReactFiberRoot": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberRoot.js", - "ReactFiberScheduler": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberScheduler.js", - "ReactFiberUpdateQueue": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactFiberUpdateQueue.js", - "ReactPriorityLevel": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactPriorityLevel.js", - "ReactReifiedYield": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactReifiedYield.js", - "ReactTypeOfWork": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/fiber/ReactTypeOfWork.js", - "ReactHostOperationHistoryHook": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/hooks/ReactHostOperationHistoryHook.js", - "ReactInvalidSetStateWarningHook": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/hooks/ReactInvalidSetStateWarningHook.js", - "ReactDebugTool": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/ReactDebugTool.js", - "ReactInstrumentation": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/ReactInstrumentation.js", - "ReactPerf": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/ReactPerf.js", - "ReactInstanceMap": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/shared/ReactInstanceMap.js", - "shouldUpdateReactComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/shared/shouldUpdateReactComponent.js", - "EventConstants": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/EventConstants.js", - "EventPluginHub": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/EventPluginHub.js", - "EventPluginRegistry": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/EventPluginRegistry.js", - "ResponderEventPlugin": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/eventPlugins/ResponderEventPlugin.js", - "ResponderSyntheticEvent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/eventPlugins/ResponderSyntheticEvent.js", - "ResponderTouchHistoryStore": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/eventPlugins/ResponderTouchHistoryStore.js", - "TouchHistoryMath": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/eventPlugins/TouchHistoryMath.js", - "EventPluginUtils": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/EventPluginUtils.js", - "EventPropagators": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/EventPropagators.js", - "PluginModuleType": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/PluginModuleType.js", - "ReactSyntheticEventType": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/ReactSyntheticEventType.js", - "SyntheticEvent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/event/SyntheticEvent.js", - "getHostComponentFromComposite": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/getHostComponentFromComposite.js", - "instantiateReactComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/instantiateReactComponent.js", - "ReactChildReconciler": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactChildReconciler.js", - "ReactComponentEnvironment": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactComponentEnvironment.js", - "ReactCompositeComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js", - "ReactDefaultBatchingStrategy": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactDefaultBatchingStrategy.js", - "ReactEmptyComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactEmptyComponent.js", - "ReactEventEmitterMixin": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactEventEmitterMixin.js", - "ReactHostComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactHostComponent.js", - "ReactInstanceType": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactInstanceType.js", - "ReactMultiChild": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactMultiChild.js", - "ReactMultiChildUpdateTypes": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactMultiChildUpdateTypes.js", - "ReactNodeTypes": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactNodeTypes.js", - "ReactOwner": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactOwner.js", - "ReactReconciler": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactReconciler.js", - "ReactRef": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactRef.js", - "ReactSimpleEmptyComponent": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactSimpleEmptyComponent.js", - "ReactUpdateQueue": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactUpdateQueue.js", - "ReactUpdates": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/stack/reconciler/ReactUpdates.js", - "accumulate": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/accumulate.js", - "accumulateInto": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/accumulateInto.js", - "adler32": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/adler32.js", - "CallbackQueue": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/CallbackQueue.js", - "forEachAccumulated": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/forEachAccumulated.js", - "isTextInputElement": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/isTextInputElement.js", - "ReactErrorUtils": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/ReactErrorUtils.js", - "ReactFeatureFlags": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/ReactFeatureFlags.js", - "Transaction": "node_modules/react-native/Libraries/Renderer/src/renderers/shared/utils/Transaction.js", - "checkReactTypeSpec": "node_modules/react-native/Libraries/Renderer/src/shared/types/checkReactTypeSpec.js", - "ReactPropTypeLocationNames": "node_modules/react-native/Libraries/Renderer/src/shared/types/ReactPropTypeLocationNames.js", - "ReactPropTypeLocations": "node_modules/react-native/Libraries/Renderer/src/shared/types/ReactPropTypeLocations.js", - "ReactPropTypesSecret": "node_modules/react-native/Libraries/Renderer/src/shared/types/ReactPropTypesSecret.js", - "canDefineProperty": "node_modules/react-native/Libraries/Renderer/src/shared/utils/canDefineProperty.js", - "deprecated": "node_modules/react-native/Libraries/Renderer/src/shared/utils/deprecated.js", - "flattenChildren": "node_modules/react-native/Libraries/Renderer/src/shared/utils/flattenChildren.js", - "getIteratorFn": "node_modules/react-native/Libraries/Renderer/src/shared/utils/getIteratorFn.js", - "KeyEscapeUtils": "node_modules/react-native/Libraries/Renderer/src/shared/utils/KeyEscapeUtils.js", - "PooledClass": "node_modules/react-native/Libraries/Renderer/src/shared/utils/PooledClass.js", - "ReactElementSymbol": "node_modules/react-native/Libraries/Renderer/src/shared/utils/ReactElementSymbol.js", - "reactProdInvariant": "node_modules/react-native/Libraries/Renderer/src/shared/utils/reactProdInvariant.js", - "traverseAllChildren": "node_modules/react-native/Libraries/Renderer/src/shared/utils/traverseAllChildren.js", - "Sample": "node_modules/react-native/Libraries/Sample/Sample.ios.js", - "Settings": "node_modules/react-native/Libraries/Settings/Settings.ios.js", - "Share": "node_modules/react-native/Libraries/Share/Share.js", - "AsyncStorage": "node_modules/react-native/Libraries/Storage/AsyncStorage.js", - "ColorPropType": "node_modules/react-native/Libraries/StyleSheet/ColorPropType.js", - "EdgeInsetsPropType": "node_modules/react-native/Libraries/StyleSheet/EdgeInsetsPropType.js", - "flattenStyle": "node_modules/react-native/Libraries/StyleSheet/flattenStyle.js", - "LayoutPropTypes": "node_modules/react-native/Libraries/StyleSheet/LayoutPropTypes.js", - "normalizeColor": "node_modules/react-native/Libraries/StyleSheet/normalizeColor.js", - "PointPropType": "node_modules/react-native/Libraries/StyleSheet/PointPropType.js", - "processColor": "node_modules/react-native/Libraries/StyleSheet/processColor.js", - "processTransform": "node_modules/react-native/Libraries/StyleSheet/processTransform.js", - "setNormalizedColorAlpha": "node_modules/react-native/Libraries/StyleSheet/setNormalizedColorAlpha.js", - "StyleSheet": "node_modules/react-native/Libraries/StyleSheet/StyleSheet.js", - "StyleSheetPropType": "node_modules/react-native/Libraries/StyleSheet/StyleSheetPropType.js", - "StyleSheetTypes": "node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.js", - "StyleSheetValidation": "node_modules/react-native/Libraries/StyleSheet/StyleSheetValidation.js", - "TransformPropTypes": "node_modules/react-native/Libraries/StyleSheet/TransformPropTypes.js", - "Text": "node_modules/react-native/Libraries/Text/Text.js", - "TextStylePropTypes": "node_modules/react-native/Libraries/Text/TextStylePropTypes.js", - "TextUpdateTest": "node_modules/react-native/Libraries/Text/TextUpdateTest.js", - "BackAndroid": "node_modules/react-native/Libraries/Utilities/BackAndroid.ios.js", - "buildStyleInterpolator": "node_modules/react-native/Libraries/Utilities/buildStyleInterpolator.js", - "clamp": "node_modules/react-native/Libraries/Utilities/clamp.js", - "createStrictShapeTypeChecker": "node_modules/react-native/Libraries/Utilities/createStrictShapeTypeChecker.js", - "deepFreezeAndThrowOnMutationInDev": "node_modules/react-native/Libraries/Utilities/deepFreezeAndThrowOnMutationInDev.js", - "defineLazyObjectProperty": "node_modules/react-native/Libraries/Utilities/defineLazyObjectProperty.js", - "deprecatedPropType": "node_modules/react-native/Libraries/Utilities/deprecatedPropType.js", - "deepDiffer": "node_modules/react-native/Libraries/Utilities/differ/deepDiffer.js", - "insetsDiffer": "node_modules/react-native/Libraries/Utilities/differ/insetsDiffer.js", - "matricesDiffer": "node_modules/react-native/Libraries/Utilities/differ/matricesDiffer.js", - "pointsDiffer": "node_modules/react-native/Libraries/Utilities/differ/pointsDiffer.js", - "sizesDiffer": "node_modules/react-native/Libraries/Utilities/differ/sizesDiffer.js", - "Dimensions": "node_modules/react-native/Libraries/Utilities/Dimensions.js", - "dismissKeyboard": "node_modules/react-native/Libraries/Utilities/dismissKeyboard.js", - "groupByEveryN": "node_modules/react-native/Libraries/Utilities/groupByEveryN.js", - "HeapCapture": "node_modules/react-native/Libraries/Utilities/HeapCapture.js", - "HMRClient": "node_modules/react-native/Libraries/Utilities/HMRClient.js", - "HMRLoadingView": "node_modules/react-native/Libraries/Utilities/HMRLoadingView.ios.js", - "infoLog": "node_modules/react-native/Libraries/Utilities/infoLog.js", - "logError": "node_modules/react-native/Libraries/Utilities/logError.js", - "mapWithSeparator": "node_modules/react-native/Libraries/Utilities/mapWithSeparator.js", - "MatrixMath": "node_modules/react-native/Libraries/Utilities/MatrixMath.js", - "mergeFast": "node_modules/react-native/Libraries/Utilities/mergeFast.js", - "mergeIntoFast": "node_modules/react-native/Libraries/Utilities/mergeIntoFast.js", - "PerformanceLogger": "node_modules/react-native/Libraries/Utilities/PerformanceLogger.js", - "PixelRatio": "node_modules/react-native/Libraries/Utilities/PixelRatio.js", - "Platform": "node_modules/react-native/Libraries/Utilities/Platform.ios.js", - "RCTLog": "node_modules/react-native/Libraries/Utilities/RCTLog.js", - "stringifySafe": "node_modules/react-native/Libraries/Utilities/stringifySafe.js", - "throwOnWrongReactAPI": "node_modules/react-native/Libraries/Utilities/throwOnWrongReactAPI.js", - "truncate": "node_modules/react-native/Libraries/Utilities/truncate.js", - "utf8": "node_modules/react-native/Libraries/Utilities/utf8.js", - "_shouldPolyfillES6Collection": "node_modules/react-native/Libraries/vendor/core/_shouldPolyfillES6Collection.js", - "copyProperties": "node_modules/react-native/Libraries/vendor/core/copyProperties.js", - "getObjectValues": "node_modules/react-native/Libraries/vendor/core/getObjectValues.js", - "guid": "node_modules/react-native/Libraries/vendor/core/guid.js", - "isEmpty": "node_modules/react-native/Libraries/vendor/core/isEmpty.js", - "Map": "node_modules/react-native/Libraries/vendor/core/Map.js", - "merge": "node_modules/react-native/Libraries/vendor/core/merge.js", - "mergeHelpers": "node_modules/react-native/Libraries/vendor/core/mergeHelpers.js", - "mergeInto": "node_modules/react-native/Libraries/vendor/core/mergeInto.js", - "Set": "node_modules/react-native/Libraries/vendor/core/Set.js", - "toIterator": "node_modules/react-native/Libraries/vendor/core/toIterator.js", - "DocumentSelectionState": "node_modules/react-native/Libraries/vendor/document/selection/DocumentSelectionState.js", - "Vibration": "node_modules/react-native/Libraries/Vibration/Vibration.js", - "VibrationIOS": "node_modules/react-native/Libraries/Vibration/VibrationIOS.ios.js", - "WebSocket": "node_modules/react-native/Libraries/WebSocket/WebSocket.js", - "WebSocketEvent": "node_modules/react-native/Libraries/WebSocket/WebSocketEvent.js", - "WebSocketInterceptor": "node_modules/react-native/Libraries/WebSocket/WebSocketInterceptor.js", - "Asserts": "node_modules/react-native/ReactAndroid/src/androidTest/js/Asserts.js", - "CatalystRootViewTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/CatalystRootViewTestModule.js", - "DatePickerDialogTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/DatePickerDialogTestModule.js", - "InitialPropsTestApp": "node_modules/react-native/ReactAndroid/src/androidTest/js/InitialPropsTestApp.js", - "JSResponderTestApp": "node_modules/react-native/ReactAndroid/src/androidTest/js/JSResponderTestApp.js", - "LayoutEventsTestApp": "node_modules/react-native/ReactAndroid/src/androidTest/js/LayoutEventsTestApp.js", - "MeasureLayoutTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/MeasureLayoutTestModule.js", - "MultitouchHandlingTestAppModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/MultitouchHandlingTestAppModule.js", - "PickerAndroidTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/PickerAndroidTestModule.js", - "ProgressBarTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/ProgressBarTestModule.js", - "ScrollViewTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/ScrollViewTestModule.js", - "ShareTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/ShareTestModule.js", - "SubviewsClippingTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/SubviewsClippingTestModule.js", - "SwipeRefreshLayoutTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/SwipeRefreshLayoutTestModule.js", - "TestIdTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TestIdTestModule.js", - "TestJavaToJSArgumentsModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TestJavaToJSArgumentsModule.js", - "TestJSLocaleModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TestJSLocaleModule.js", - "TestJSToJavaParametersModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TestJSToJavaParametersModule.js", - "TextInputTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TextInputTestModule.js", - "TimePickerDialogTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TimePickerDialogTestModule.js", - "TouchBubblingTestAppModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/TouchBubblingTestAppModule.js", - "UIManagerTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/UIManagerTestModule.js", - "ViewRenderingTestModule": "node_modules/react-native/ReactAndroid/src/androidTest/js/ViewRenderingTestModule.js" - }, - "version": "0.39.1" -} \ No newline at end of file From 4e3296b0fb21ac0761afcf25ded68b781e24f577 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 21:45:30 +0000 Subject: [PATCH 010/149] Add mock file --- mock.js | 5 +++++ src/react-native-mock.js | 0 2 files changed, 5 insertions(+) create mode 100644 mock.js create mode 100644 src/react-native-mock.js diff --git a/mock.js b/mock.js new file mode 100644 index 0000000..43e6f89 --- /dev/null +++ b/mock.js @@ -0,0 +1,5 @@ +/* + Shortcut file to allow use via `react-native-mock/mock` +*/ + +module.exports = require('build/react-native-mock.js'); diff --git a/src/react-native-mock.js b/src/react-native-mock.js new file mode 100644 index 0000000..e69de29 From 3c07424bdad76de54d52031c2a6df0bc3ed96b9c Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 22:19:38 +0000 Subject: [PATCH 011/149] use imports --- src/haste.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/haste.js b/src/haste.js index fc0691b..0dbabbb 100644 --- a/src/haste.js +++ b/src/haste.js @@ -1,6 +1,6 @@ -const glob = require('glob'); -const path = require('path'); -const fs = require('fs'); +import glob from 'glob'; +import path from 'path' +import fs from 'fs' const providesRegex = /\r?\n \* @providesModule (\S+)(?=\r?\n)/; const validName = /^[a-z0-9-_].+$/i; From b4e09165901975dc52453cfd2e763e1110fe8a3e Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 22:21:44 +0000 Subject: [PATCH 012/149] use built script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dc7a728..adefe4d 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "build/react-native.js", "scripts": { "prepublish": "npm run build", - "postinstall": "node src/haste.js", + "postinstall": "node build/haste.js", "test": "npm run lint", "lint": "eslint 'src/' 'test/' 'mock.js'", "build": "babel src --out-dir build" From f1d40a0b58c64516307a5b2514aa0efb201c072d Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 23:00:41 +0000 Subject: [PATCH 013/149] Start on mocking code --- mock.js | 2 +- src/MockComponent.js | 17 +++++++++++++++++ src/defineGlobalProperty.js | 6 ++++++ src/haste.js | 4 ++-- src/react-native-mock.js | 11 +++++++++++ 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 src/MockComponent.js create mode 100644 src/defineGlobalProperty.js diff --git a/mock.js b/mock.js index 43e6f89..fb689dc 100644 --- a/mock.js +++ b/mock.js @@ -2,4 +2,4 @@ Shortcut file to allow use via `react-native-mock/mock` */ -module.exports = require('build/react-native-mock.js'); +module.exports = require('./build/react-native-mock.js'); diff --git a/src/MockComponent.js b/src/MockComponent.js new file mode 100644 index 0000000..91d5ea7 --- /dev/null +++ b/src/MockComponent.js @@ -0,0 +1,17 @@ +import React from 'react'; + +export default name => { + class Component extends React.Component { // eslint-disable-line react/prefer-stateless-function + render() { + return React.createElement( + name.replace(/^(RCT|RK)/, ''), + this.props, + this.props.children + ); + } + } + Component.propTypes = { + children: React.PropTypes.any + }; + return Component; +}; diff --git a/src/defineGlobalProperty.js b/src/defineGlobalProperty.js new file mode 100644 index 0000000..fe0ef70 --- /dev/null +++ b/src/defineGlobalProperty.js @@ -0,0 +1,6 @@ +export default function defineGlobalProperty(name, value) { + Object.defineProperty(global, name, { + configurable: true, + value, + }); +} diff --git a/src/haste.js b/src/haste.js index 0dbabbb..48cd88e 100644 --- a/src/haste.js +++ b/src/haste.js @@ -1,6 +1,6 @@ import glob from 'glob'; -import path from 'path' -import fs from 'fs' +import path from 'path'; +import fs from 'fs'; const providesRegex = /\r?\n \* @providesModule (\S+)(?=\r?\n)/; const validName = /^[a-z0-9-_].+$/i; diff --git a/src/react-native-mock.js b/src/react-native-mock.js index e69de29..1d9239c 100644 --- a/src/react-native-mock.js +++ b/src/react-native-mock.js @@ -0,0 +1,11 @@ +import defineGlobalProperty from './defineGlobalProperty'; +import mockery from 'mockery'; + +mockery.enable({ + warnOnReplace: false, + warnOnUnregistered: false +}); + +defineGlobalProperty('__DEV__', true); +defineGlobalProperty('Promise', require('promise')); +defineGlobalProperty('regeneratorRuntime', require('regenerator-runtime/runtime')); From 68ca353e8154f1ca9adefdbc4949f802e4f64c7d Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 23:18:57 +0000 Subject: [PATCH 014/149] Make haste script node 4 compatable --- package.json | 2 +- src/haste.js | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index adefe4d..dc7a728 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "build/react-native.js", "scripts": { "prepublish": "npm run build", - "postinstall": "node build/haste.js", + "postinstall": "node src/haste.js", "test": "npm run lint", "lint": "eslint 'src/' 'test/' 'mock.js'", "build": "babel src --out-dir build" diff --git a/src/haste.js b/src/haste.js index 48cd88e..dd21958 100644 --- a/src/haste.js +++ b/src/haste.js @@ -1,20 +1,21 @@ -import glob from 'glob'; -import path from 'path'; -import fs from 'fs'; +var fs = require('fs'); +var glob = require('glob'); +var path = require('path'); +var _ = require('underscore'); -const providesRegex = /\r?\n \* @providesModule (\S+)(?=\r?\n)/; -const validName = /^[a-z0-9-_].+$/i; -const CWD = process.cwd(); +var providesRegex = /\r?\n \* @providesModule (\S+)(?=\r?\n)/; +var validName = /^[a-z0-9-_].+$/i; +var CWD = process.cwd(); -const data = { +var data = { hasteMap: {}, version: require('./react-native-version') }; -const files = glob.sync('node_modules/**/*.js'); +var files = glob.sync('node_modules/**/*.js'); -files.forEach(function (file) { - const matches = providesRegex.exec(fs.readFileSync(file).toString()); +_.forEach(files, function (file) { + var matches = providesRegex.exec(fs.readFileSync(file).toString()); if (matches && validName.test(matches[1])) { data.hasteMap[matches[1]] = file.replace(CWD, ''); } From 7b247b20668353fc6fefbf6d0f7f10a50cfde2e1 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 10 Dec 2016 23:23:53 +0000 Subject: [PATCH 015/149] wrong lib... --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dc7a728..f91db8d 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,8 @@ "dependencies": { "babel-core": "^6.9.0", "babel-preset-react-native": "^1.6.0", + "glob": "^7.1.1", "mockery": "=2.0.0", - "node-glob": "=1.2.0", "react-addons-test-utils": "^15.4.1", "react-dom": "^15.4.1", "underscore": "=1.8.3" From e13a36c1f907b256d6d225d3bb6d4132bedebe3f Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 11 Dec 2016 12:12:07 +0000 Subject: [PATCH 016/149] Disable var check on haste builder --- src/haste.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/haste.js b/src/haste.js index dd21958..3a23446 100644 --- a/src/haste.js +++ b/src/haste.js @@ -1,3 +1,5 @@ +/* eslint-disable no-var */ + var fs = require('fs'); var glob = require('glob'); var path = require('path'); From 66808920e7c0455f1fef7204120a76a618f4e72c Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 11 Dec 2016 12:24:56 +0000 Subject: [PATCH 017/149] Add extra dependandies for node 4 --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index f91db8d..6638d26 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,10 @@ "babel-preset-react-native": "^1.6.0", "glob": "^7.1.1", "mockery": "=2.0.0", + "promise": "^7.1.1", "react-addons-test-utils": "^15.4.1", "react-dom": "^15.4.1", + "regenerator-runtime": "^0.10.1", "underscore": "=1.8.3" }, "devDependencies": { From 130a5ee347b2464bd35d824007f98c7e2612063c Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 11 Dec 2016 15:32:59 +0000 Subject: [PATCH 018/149] Add remaining mock library --- src/NativeModules.js | 115 ++++++++++++++++++++++++++++++++ src/babel.js | 4 ++ src/haste.js | 2 +- src/mocks/ErrorUtils.js | 18 +++++ src/mocks/ListViewDataSource.js | 20 ++++++ src/react-native-mock.js | 40 ++++++++++- 6 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 src/NativeModules.js create mode 100644 src/babel.js create mode 100644 src/mocks/ErrorUtils.js create mode 100644 src/mocks/ListViewDataSource.js diff --git a/src/NativeModules.js b/src/NativeModules.js new file mode 100644 index 0000000..96fa106 --- /dev/null +++ b/src/NativeModules.js @@ -0,0 +1,115 @@ +import _ from 'underscore'; +import mockery from 'mockery'; + + +const mockNativeModules = { + AlertManager: { + alertWithArgs: _.noop, + }, + AppState: { + addEventListener: _.noop, + }, + AsyncLocalStorage: { + clear: _.noop, + getItem: _.noop, + removeItem: _.noop, + setItem: _.noop, + }, + BuildInfo: { + appVersion: '0', + buildVersion: '0', + }, + Clipboard: { + setString: _.noop, + }, + DataManager: { + queryData: _.noop, + }, + FacebookSDK: { + login: _.noop, + logout: _.noop, + queryGraphPath: (path, method, params, callback) => callback(), + }, + FbRelayNativeAdapter: { + updateCLC: _.noop, + }, + GraphPhotoUpload: { + upload: _.noop, + }, + I18n: { + translationsDictionary: JSON.stringify({ + 'Good bye, {name}!|Bye message': '\u{00A1}Adi\u{00F3}s {name}!', + }), + }, + ImageLoader: { + getSize: (uri, success) => process.nextTick(() => success(320, 240) + ), + prefetchImage: _.noop, + }, + ImageViewManager: { + getSize: (uri, success) => process.nextTick(() => success(320, 240) + ), + prefetchImage: _.noop, + }, + KeyboardObserver: { + addListener: _.noop, + removeListeners: _.noop, + }, + ModalFullscreenViewManager: {}, + Networking: { + sendRequest: _.noop, + abortRequest: _.noop, + addListener: _.noop, + removeListeners: _.noop, + }, + SourceCode: { + scriptURL: null, + }, + StatusBarManager: { + setStyle: _.noop, + setHidden: _.noop, + setNetworkActivityIndicatorVisible: _.noop, + setBackgroundColor: _.noop, + setTranslucent: _.noop, + }, + Timing: { + createTimer: _.noop, + deleteTimer: _.noop, + }, + UIManager: { + customBubblingEventTypes: {}, + customDirectEventTypes: {}, + Dimensions: { + window: { + fontScale: 2, + height: 1334, + scale: 2, + width: 750, + }, + }, + ModalFullscreenView: { + Constants: {}, + }, + ScrollView: { + Constants: {}, + }, + View: { + Constants: {}, + }, + }, + WebSocketModule: { + connect: _.noop, + send: _.noop, + sendBinary: _.noop, + ping: _.noop, + close: _.noop, + addListener: _.noop, + removeListeners: _.noop, + }, +}; + +_.forEach(Object.keys(mockNativeModules), function (mod) { + mockery.registerMock(mod, mockNativeModules[mod]); +}); + +mockery.registerMock('NativeModules', mockNativeModules); diff --git a/src/babel.js b/src/babel.js new file mode 100644 index 0000000..35f3f28 --- /dev/null +++ b/src/babel.js @@ -0,0 +1,4 @@ +require('babel-core/register')({ + // Ignore everything in node_modules except node_modules/rcomponents. + ignore: /node_modules\/(?!react-native)/ +}); diff --git a/src/haste.js b/src/haste.js index 3a23446..63e0850 100644 --- a/src/haste.js +++ b/src/haste.js @@ -19,7 +19,7 @@ var files = glob.sync('node_modules/**/*.js'); _.forEach(files, function (file) { var matches = providesRegex.exec(fs.readFileSync(file).toString()); if (matches && validName.test(matches[1])) { - data.hasteMap[matches[1]] = file.replace(CWD, ''); + data.hasteMap[matches[1]] = file.replace('node_modules/', ''); } }); diff --git a/src/mocks/ErrorUtils.js b/src/mocks/ErrorUtils.js new file mode 100644 index 0000000..eb4d895 --- /dev/null +++ b/src/mocks/ErrorUtils.js @@ -0,0 +1,18 @@ +import mockery from 'mockery'; + +function execute(fun, context, args) { + return fun.apply(context, args); +} + +function reportError(error) { + throw error; +} + +mockery.registerMock('ErrorUtils', { + apply: execute, + applyWithGuard: execute, + guard: callback => callback, + inGuard: () => true, + reportError, + setGlobalHandler: () => undefined, +}); diff --git a/src/mocks/ListViewDataSource.js b/src/mocks/ListViewDataSource.js new file mode 100644 index 0000000..cbc9950 --- /dev/null +++ b/src/mocks/ListViewDataSource.js @@ -0,0 +1,20 @@ +import mockery from 'mockery'; + +const DataSource = require('ListViewDataSource'); // eslint-disable-line import/no-unresolved + +DataSource.prototype.toJSON = function () { + function ListViewDataSource(dataBlob) { + this.items = 0; + // Ensure this doesn't throw. + try { + Object.keys(dataBlob).forEach(key => { + this.items += dataBlob[key] && dataBlob[key].length; + }); + } catch (e) { + this.items = 'unknown'; + } + } + return new ListViewDataSource(this._dataBlob); +}; + +mockery.registerMock('ListViewDataSource', DataSource); diff --git a/src/react-native-mock.js b/src/react-native-mock.js index 1d9239c..9d43379 100644 --- a/src/react-native-mock.js +++ b/src/react-native-mock.js @@ -1,5 +1,9 @@ -import defineGlobalProperty from './defineGlobalProperty'; import mockery from 'mockery'; +import _ from 'underscore'; +import defineGlobalProperty from './defineGlobalProperty'; +import MockComponent from './MockComponent'; + +require('./babel'); mockery.enable({ warnOnReplace: false, @@ -9,3 +13,37 @@ mockery.enable({ defineGlobalProperty('__DEV__', true); defineGlobalProperty('Promise', require('promise')); defineGlobalProperty('regeneratorRuntime', require('regenerator-runtime/runtime')); + +mockery.registerMock('ensureComponentIsNative', () => true); + +_.mapObject(require('../haste-map.json').hasteMap, function (val, key) { + mockery.registerSubstitute(key, val); +}); + +require('./NativeModules'); + +const mockPropRegistry = {}; +mockery.registerMock('ReactNativePropRegistry', { + register: id => id, + getByID: () => mockPropRegistry +}); + +const MOCK_COMPONENTS = [ + 'Image', + 'Text', + 'TextInput', + 'Modal', + 'View', + 'ScrollView', + 'ActivityIndicator', + 'ListView' +]; + +_.forEach(MOCK_COMPONENTS, function (component) { + mockery.registerMock(component, MockComponent(component)); // eslint-disable-line new-cap +}); + +mockery.registerMock('requireNativeComponent', MockComponent); + +require('./mocks/ListViewDataSource'); +require('./mocks/ErrorUtils'); From 151bc027f3df1e201ead4467eb4a3af7844e5f51 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 11 Dec 2016 17:07:31 +0000 Subject: [PATCH 019/149] add some basic tests --- package.json | 5 +++-- src/NativeModules.js | 2 ++ tests/globals.test.js | 16 ++++++++++++++++ tests/haste-map.test.js | 19 +++++++++++++++++++ tests/native-modules.test.js | 18 ++++++++++++++++++ tests/react-native-version.test.js | 9 +++++++++ 6 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 tests/globals.test.js create mode 100644 tests/haste-map.test.js create mode 100644 tests/native-modules.test.js create mode 100644 tests/react-native-version.test.js diff --git a/package.json b/package.json index 6638d26..8a311c7 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,9 @@ "scripts": { "prepublish": "npm run build", "postinstall": "node src/haste.js", - "test": "npm run lint", - "lint": "eslint 'src/' 'test/' 'mock.js'", + "test": "npm run lint && npm run mocha", + "mocha": "mocha --require mock.js --bail 'tests/**/*.test.js'", + "lint": "eslint 'src/' 'tests/' 'mock.js'", "build": "babel src --out-dir build" }, "repository": { diff --git a/src/NativeModules.js b/src/NativeModules.js index 96fa106..8bbb114 100644 --- a/src/NativeModules.js +++ b/src/NativeModules.js @@ -113,3 +113,5 @@ _.forEach(Object.keys(mockNativeModules), function (mod) { }); mockery.registerMock('NativeModules', mockNativeModules); + +export default mockNativeModules; diff --git a/tests/globals.test.js b/tests/globals.test.js new file mode 100644 index 0000000..80b93e7 --- /dev/null +++ b/tests/globals.test.js @@ -0,0 +1,16 @@ +import { expect } from 'chai'; + + +describe('Globals', function () { + it('should have promise globally', function () { + expect(global.Promise).to.deep.equal(require('promise')); + }); + + it('should have promise globally', function () { + expect(global.regeneratorRuntime).to.deep.equal(require('regenerator-runtime/runtime')); + }); + + it('should be in dev', function () { + expect(global.__DEV__).to.be.true; + }); +}); diff --git a/tests/haste-map.test.js b/tests/haste-map.test.js new file mode 100644 index 0000000..3cda4fb --- /dev/null +++ b/tests/haste-map.test.js @@ -0,0 +1,19 @@ +import { expect } from 'chai'; +import fs from 'fs'; +import path from 'path'; + +const MAP_LOCATION = path.join(__dirname, '../haste-map.json'); + +describe('Haste Map', function () { + it('Should have one initially', function () { + const stat = fs.statSync(MAP_LOCATION); + expect(stat.isFile()).to.be.true; + }); + + it('should contain correct data', function () { + const HasteMap = require('../haste-map'); + expect(HasteMap).to.have.all.keys('hasteMap', 'version'); + expect(HasteMap.hasteMap).to.be.an('object'); + expect(HasteMap.version).to.be.a('string'); + }); +}); diff --git a/tests/native-modules.test.js b/tests/native-modules.test.js new file mode 100644 index 0000000..bc70fa7 --- /dev/null +++ b/tests/native-modules.test.js @@ -0,0 +1,18 @@ +import { expect } from 'chai'; +import NativeModules from '../src/NativeModules'; + +describe('Native Modules', function () { + it('Should be defined', function () { + expect(require('NativeModules')).to.deep.equal(NativeModules); // eslint-disable-line import/no-unresolved + expect(NativeModules).to.be.an('object'); + }); + + describe('Single Modules', function () { + Object.keys(NativeModules).forEach(function (mod) { + it('should require ' + mod, function () { + expect(require(mod)).to.deep.equal(NativeModules[mod]); + expect(require(mod)).to.be.an('object'); + }); + }); + }); +}); diff --git a/tests/react-native-version.test.js b/tests/react-native-version.test.js new file mode 100644 index 0000000..e4f604c --- /dev/null +++ b/tests/react-native-version.test.js @@ -0,0 +1,9 @@ +import { expect } from 'chai'; + + +describe('React-Native version', function () { + it('should return correct version', function () { + const version = require('../src/react-native-version'); + expect(version).to.be.a('string'); + }); +}); From 33567e4c84328cf102f890587e3b9d472cc27d0b Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 11 Dec 2016 21:54:03 +0000 Subject: [PATCH 020/149] Update lint config --- .eslintrc | 4 +-- src/NativeModules.js | 52 ++++++++++++++++++------------------- src/defineGlobalProperty.js | 2 +- src/mocks/ErrorUtils.js | 2 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.eslintrc b/.eslintrc index 59628fd..654d5f8 100644 --- a/.eslintrc +++ b/.eslintrc @@ -9,7 +9,7 @@ }, "rules": { "no-unused-vars": [2, {"vars": "all", "args": "none"}], - "comma-dangle": 0, + "comma-dangle": ["error", "never"], "func-names": 0, "prefer-arrow-callback": 0, "global-require": 0, @@ -19,7 +19,7 @@ "guard-for-in": 0, "no-restricted-syntax": 0, "prefer-template": 0, - "no-console": 0, + "no-unused-expressions": 0, "max-len": [ 2, 120, diff --git a/src/NativeModules.js b/src/NativeModules.js index 8bbb114..7ccfc7e 100644 --- a/src/NativeModules.js +++ b/src/NativeModules.js @@ -4,77 +4,77 @@ import mockery from 'mockery'; const mockNativeModules = { AlertManager: { - alertWithArgs: _.noop, + alertWithArgs: _.noop }, AppState: { - addEventListener: _.noop, + addEventListener: _.noop }, AsyncLocalStorage: { clear: _.noop, getItem: _.noop, removeItem: _.noop, - setItem: _.noop, + setItem: _.noop }, BuildInfo: { appVersion: '0', - buildVersion: '0', + buildVersion: '0' }, Clipboard: { - setString: _.noop, + setString: _.noop }, DataManager: { - queryData: _.noop, + queryData: _.noop }, FacebookSDK: { login: _.noop, logout: _.noop, - queryGraphPath: (path, method, params, callback) => callback(), + queryGraphPath: (path, method, params, callback) => callback() }, FbRelayNativeAdapter: { - updateCLC: _.noop, + updateCLC: _.noop }, GraphPhotoUpload: { - upload: _.noop, + upload: _.noop }, I18n: { translationsDictionary: JSON.stringify({ - 'Good bye, {name}!|Bye message': '\u{00A1}Adi\u{00F3}s {name}!', - }), + 'Good bye, {name}!|Bye message': '\u{00A1}Adi\u{00F3}s {name}!' + }) }, ImageLoader: { getSize: (uri, success) => process.nextTick(() => success(320, 240) ), - prefetchImage: _.noop, + prefetchImage: _.noop }, ImageViewManager: { getSize: (uri, success) => process.nextTick(() => success(320, 240) ), - prefetchImage: _.noop, + prefetchImage: _.noop }, KeyboardObserver: { addListener: _.noop, - removeListeners: _.noop, + removeListeners: _.noop }, ModalFullscreenViewManager: {}, Networking: { sendRequest: _.noop, abortRequest: _.noop, addListener: _.noop, - removeListeners: _.noop, + removeListeners: _.noop }, SourceCode: { - scriptURL: null, + scriptURL: null }, StatusBarManager: { setStyle: _.noop, setHidden: _.noop, setNetworkActivityIndicatorVisible: _.noop, setBackgroundColor: _.noop, - setTranslucent: _.noop, + setTranslucent: _.noop }, Timing: { createTimer: _.noop, - deleteTimer: _.noop, + deleteTimer: _.noop }, UIManager: { customBubblingEventTypes: {}, @@ -84,18 +84,18 @@ const mockNativeModules = { fontScale: 2, height: 1334, scale: 2, - width: 750, - }, + width: 750 + } }, ModalFullscreenView: { - Constants: {}, + Constants: {} }, ScrollView: { - Constants: {}, + Constants: {} }, View: { - Constants: {}, - }, + Constants: {} + } }, WebSocketModule: { connect: _.noop, @@ -104,8 +104,8 @@ const mockNativeModules = { ping: _.noop, close: _.noop, addListener: _.noop, - removeListeners: _.noop, - }, + removeListeners: _.noop + } }; _.forEach(Object.keys(mockNativeModules), function (mod) { diff --git a/src/defineGlobalProperty.js b/src/defineGlobalProperty.js index fe0ef70..c307e13 100644 --- a/src/defineGlobalProperty.js +++ b/src/defineGlobalProperty.js @@ -1,6 +1,6 @@ export default function defineGlobalProperty(name, value) { Object.defineProperty(global, name, { configurable: true, - value, + value }); } diff --git a/src/mocks/ErrorUtils.js b/src/mocks/ErrorUtils.js index eb4d895..d9b5ee0 100644 --- a/src/mocks/ErrorUtils.js +++ b/src/mocks/ErrorUtils.js @@ -14,5 +14,5 @@ mockery.registerMock('ErrorUtils', { guard: callback => callback, inGuard: () => true, reportError, - setGlobalHandler: () => undefined, + setGlobalHandler: () => undefined }); From 9a24aa446cb5b1d5cbc9679fb5ae95ba125896b2 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 11 Dec 2016 22:22:21 +0000 Subject: [PATCH 021/149] add tests for mock component script --- tests/mock-component.test.js | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/mock-component.test.js diff --git a/tests/mock-component.test.js b/tests/mock-component.test.js new file mode 100644 index 0000000..6d91d8a --- /dev/null +++ b/tests/mock-component.test.js @@ -0,0 +1,34 @@ +import React from 'react'; // eslint-disable-line no-unused-vars +import { shallow } from 'enzyme'; +import { expect } from 'chai'; +import MockComponent from '../src/MockComponent'; + +describe('Mock Component', function () { + it('Should render correctly', function () { + const Component = MockComponent('test'); + const instance = shallow(); + expect(instance.html()).to.equal(''); + }); + + it('Should replace RCT in name', function () { + const Component = MockComponent('RCTtest'); + const instance = shallow(); + expect(instance.html()).to.equal(''); + }); + + it('Should replace RK in name', function () { + const Component = MockComponent('RKtest'); + const instance = shallow(); + expect(instance.html()).to.equal(''); + }); + + it('Should pass props and children', function () { + const Component = MockComponent('test'); + const instance = shallow(bar); + expect(instance.html()).to.equal('bar'); + }); + + it('should be accessible globally', function () { + expect(require('requireNativeComponent').name).to.equal(MockComponent.name); + }); +}); From 188871852113b5fd02515bc8f73a2a4b04b4279c Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 12 Dec 2016 09:31:13 +0000 Subject: [PATCH 022/149] Fix linter --- src/{MockComponent.js => createMockComponent.js} | 0 src/react-native-mock.js | 6 +++--- tests/mock-component.test.js | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) rename src/{MockComponent.js => createMockComponent.js} (100%) diff --git a/src/MockComponent.js b/src/createMockComponent.js similarity index 100% rename from src/MockComponent.js rename to src/createMockComponent.js diff --git a/src/react-native-mock.js b/src/react-native-mock.js index 9d43379..b8d5315 100644 --- a/src/react-native-mock.js +++ b/src/react-native-mock.js @@ -1,7 +1,7 @@ import mockery from 'mockery'; import _ from 'underscore'; import defineGlobalProperty from './defineGlobalProperty'; -import MockComponent from './MockComponent'; +import createMockCompunent from './createMockComponent'; require('./babel'); @@ -40,10 +40,10 @@ const MOCK_COMPONENTS = [ ]; _.forEach(MOCK_COMPONENTS, function (component) { - mockery.registerMock(component, MockComponent(component)); // eslint-disable-line new-cap + mockery.registerMock(component, createMockCompunent(component)); }); -mockery.registerMock('requireNativeComponent', MockComponent); +mockery.registerMock('requireNativeComponent', createMockCompunent()); require('./mocks/ListViewDataSource'); require('./mocks/ErrorUtils'); diff --git a/tests/mock-component.test.js b/tests/mock-component.test.js index 6d91d8a..2d5e783 100644 --- a/tests/mock-component.test.js +++ b/tests/mock-component.test.js @@ -1,34 +1,34 @@ import React from 'react'; // eslint-disable-line no-unused-vars import { shallow } from 'enzyme'; import { expect } from 'chai'; -import MockComponent from '../src/MockComponent'; +import createMockComponent from '../src/createMockComponent'; describe('Mock Component', function () { it('Should render correctly', function () { - const Component = MockComponent('test'); + const Component = createMockComponent('test'); const instance = shallow(); expect(instance.html()).to.equal(''); }); it('Should replace RCT in name', function () { - const Component = MockComponent('RCTtest'); + const Component = createMockComponent('RCTtest'); const instance = shallow(); expect(instance.html()).to.equal(''); }); it('Should replace RK in name', function () { - const Component = MockComponent('RKtest'); + const Component = createMockComponent('RKtest'); const instance = shallow(); expect(instance.html()).to.equal(''); }); it('Should pass props and children', function () { - const Component = MockComponent('test'); + const Component = createMockComponent('test'); const instance = shallow(bar); expect(instance.html()).to.equal('bar'); }); it('should be accessible globally', function () { - expect(require('requireNativeComponent').name).to.equal(MockComponent.name); + expect(require('requireNativeComponent').name).to.equal(createMockComponent.name); // eslint-disable-line import/no-unresolved }); }); From 568102d33ae47a1a4d217a9a6c4eb4d4eb2f8bef Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 12 Dec 2016 13:19:12 +0000 Subject: [PATCH 023/149] Better tests --- tests/mock-component.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/mock-component.test.js b/tests/mock-component.test.js index 2d5e783..df87e4f 100644 --- a/tests/mock-component.test.js +++ b/tests/mock-component.test.js @@ -30,5 +30,8 @@ describe('Mock Component', function () { it('should be accessible globally', function () { expect(require('requireNativeComponent').name).to.equal(createMockComponent.name); // eslint-disable-line import/no-unresolved + const RequiredComponent = require('requireNativeComponent')('test'); // eslint-disable-line import/no-unresolved + const Component = createMockComponent('test'); + expect(shallow().html()).to.equal(shallow().html()); }); }); From 1706f486c4172697e1372a6af87cf80950d3faa5 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 12 Dec 2016 13:40:31 +0000 Subject: [PATCH 024/149] fix typo --- src/react-native-mock.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/react-native-mock.js b/src/react-native-mock.js index b8d5315..090db3a 100644 --- a/src/react-native-mock.js +++ b/src/react-native-mock.js @@ -1,7 +1,7 @@ import mockery from 'mockery'; import _ from 'underscore'; import defineGlobalProperty from './defineGlobalProperty'; -import createMockCompunent from './createMockComponent'; +import createMockComponent from './createMockComponent'; require('./babel'); @@ -40,10 +40,10 @@ const MOCK_COMPONENTS = [ ]; _.forEach(MOCK_COMPONENTS, function (component) { - mockery.registerMock(component, createMockCompunent(component)); + mockery.registerMock(component, createMockComponent(component)); }); -mockery.registerMock('requireNativeComponent', createMockCompunent()); +mockery.registerMock('requireNativeComponent', createMockComponent); require('./mocks/ListViewDataSource'); require('./mocks/ErrorUtils'); From 9e8c8b4113fb253390c191db3063b0f2e47a25f3 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 12 Dec 2016 13:42:07 +0000 Subject: [PATCH 025/149] remove pointless test --- tests/mock-component.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/mock-component.test.js b/tests/mock-component.test.js index df87e4f..cbf8c5a 100644 --- a/tests/mock-component.test.js +++ b/tests/mock-component.test.js @@ -29,7 +29,6 @@ describe('Mock Component', function () { }); it('should be accessible globally', function () { - expect(require('requireNativeComponent').name).to.equal(createMockComponent.name); // eslint-disable-line import/no-unresolved const RequiredComponent = require('requireNativeComponent')('test'); // eslint-disable-line import/no-unresolved const Component = createMockComponent('test'); expect(shallow().html()).to.equal(shallow().html()); From 3783b752d36ff7923c4553f838bace25c0af34c1 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 12 Dec 2016 14:00:40 +0000 Subject: [PATCH 026/149] Add coverage --- .gitignore | 1 + package.json | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8631559..9db71bb 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ node_modules /build haste-map.json +.nyc_output/ diff --git a/package.json b/package.json index 8a311c7..5eae73f 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,10 @@ "scripts": { "prepublish": "npm run build", "postinstall": "node src/haste.js", - "test": "npm run lint && npm run mocha", + "test": "npm run lint && npm run coverage", "mocha": "mocha --require mock.js --bail 'tests/**/*.test.js'", "lint": "eslint 'src/' 'tests/' 'mock.js'", + "coverage": "nyc mocha --require mock.js --bail --recursive 'tests/**/*.test.js'", "build": "babel src --out-dir build" }, "repository": { @@ -50,6 +51,7 @@ "eslint-plugin-react-native": "1.0.2", "mocha": "3.2.0", "mocka": "0.0.1", + "nyc": "10.0.0", "react": "^15.4.1", "react-addons-test-utils": "^15.4.1", "react-dom": "^15.4.1", From 8c8d9f145a4e632055d2254c2fec5590a3ddfbf8 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Tue, 13 Dec 2016 14:10:19 +0000 Subject: [PATCH 027/149] Added nycrc file, woops --- .nycrc | 26 ++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 .nycrc diff --git a/.nycrc b/.nycrc new file mode 100644 index 0000000..b2e008f --- /dev/null +++ b/.nycrc @@ -0,0 +1,26 @@ +{ + "lines": 0, + "statements": 0, + "functions": 0, + "branches": 0, + "require": [ + "./mock.js" + ], + "include": [ + "src/**/*.js", + "mock.js" + ], + "extension": [ + ".js" + ], + "reporter": [ + "lcov", + "text", + "text-summary" + ], + "all": true, + "check-coverage": true, + "sourceMap": true, + "instrument": true, + "report-dir": "./coverage" +} diff --git a/package.json b/package.json index 5eae73f..caa1b9c 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "test": "npm run lint && npm run coverage", "mocha": "mocha --require mock.js --bail 'tests/**/*.test.js'", "lint": "eslint 'src/' 'tests/' 'mock.js'", - "coverage": "nyc mocha --require mock.js --bail --recursive 'tests/**/*.test.js'", + "coverage": "nyc npm run mocha", "build": "babel src --out-dir build" }, "repository": { From e0623d226ebc06de2b2ee5b782128dc5935d356e Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Wed, 14 Dec 2016 16:48:44 +0000 Subject: [PATCH 028/149] More tests on global --- tests/globals.test.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/globals.test.js b/tests/globals.test.js index 80b93e7..2a1ecd7 100644 --- a/tests/globals.test.js +++ b/tests/globals.test.js @@ -1,4 +1,5 @@ import { expect } from 'chai'; +import defineGlobalProperty from '../src/defineGlobalProperty'; describe('Globals', function () { @@ -6,11 +7,18 @@ describe('Globals', function () { expect(global.Promise).to.deep.equal(require('promise')); }); - it('should have promise globally', function () { + it('should have regenerator runtime globally', function () { expect(global.regeneratorRuntime).to.deep.equal(require('regenerator-runtime/runtime')); }); it('should be in dev', function () { expect(global.__DEV__).to.be.true; }); + + describe('describeGlobalProperty', function () { + it('Should define property', function () { + defineGlobalProperty('testKey1', 'testValue1'); + expect(global.testKey1).to.equal('testValue1'); + }); + }); }); From 24df013a9446c20d9d59a64304c41ee69688d846 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Wed, 14 Dec 2016 17:11:37 +0000 Subject: [PATCH 029/149] Add better tests to haste map --- tests/haste-map.test.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/haste-map.test.js b/tests/haste-map.test.js index 3cda4fb..b05aafc 100644 --- a/tests/haste-map.test.js +++ b/tests/haste-map.test.js @@ -11,9 +11,19 @@ describe('Haste Map', function () { }); it('should contain correct data', function () { - const HasteMap = require('../haste-map'); + const HasteMap = require(MAP_LOCATION); expect(HasteMap).to.have.all.keys('hasteMap', 'version'); expect(HasteMap.hasteMap).to.be.an('object'); expect(HasteMap.version).to.be.a('string'); }); + + describe('Haste Map Builder', function () { + it('Should build the map', function (done) { + fs.unlinkSync(MAP_LOCATION); + require('../src/haste'); + const stat = fs.statSync(MAP_LOCATION); + expect(stat.isFile()).to.be.true; + done(); + }); + }); }); From 4e22354f36e9971c0b6b763fb8b8f13ee0767a65 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Wed, 14 Dec 2016 17:44:31 +0000 Subject: [PATCH 030/149] Add longer timeout for tests --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index caa1b9c..84206b5 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "prepublish": "npm run build", "postinstall": "node src/haste.js", "test": "npm run lint && npm run coverage", - "mocha": "mocha --require mock.js --bail 'tests/**/*.test.js'", + "mocha": "mocha --require mock.js --bail --timeout 5000 'tests/**/*.test.js'", "lint": "eslint 'src/' 'tests/' 'mock.js'", "coverage": "nyc npm run mocha", "build": "babel src --out-dir build" From 184b5c77da708cfdb9a90c6290c315b630bb0215 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Wed, 14 Dec 2016 17:47:58 +0000 Subject: [PATCH 031/149] Remove unnecessary done --- tests/haste-map.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/haste-map.test.js b/tests/haste-map.test.js index b05aafc..9176470 100644 --- a/tests/haste-map.test.js +++ b/tests/haste-map.test.js @@ -18,12 +18,11 @@ describe('Haste Map', function () { }); describe('Haste Map Builder', function () { - it('Should build the map', function (done) { + it('Should build the map', function () { fs.unlinkSync(MAP_LOCATION); require('../src/haste'); const stat = fs.statSync(MAP_LOCATION); expect(stat.isFile()).to.be.true; - done(); }); }); }); From 1c1edab1c369a35b53aa35559ee161f04cc6c827 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Wed, 14 Dec 2016 18:18:20 +0000 Subject: [PATCH 032/149] Add more general test --- tests/react-native-mock.test.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/react-native-mock.test.js diff --git a/tests/react-native-mock.test.js b/tests/react-native-mock.test.js new file mode 100644 index 0000000..73db438 --- /dev/null +++ b/tests/react-native-mock.test.js @@ -0,0 +1,9 @@ +describe('React Native Mock', function () { + it('shouldnt break when mocking', function () { + require('../src/react-native-mock'); + }); + + it('Should allow requiring of react-native', function () { + require('react-native'); + }); +}); From 049df39757f3fab3d58d7d2dedab8e356c12d9c7 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Wed, 14 Dec 2016 18:39:57 +0000 Subject: [PATCH 033/149] More timeout --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 84206b5..21f25e9 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "prepublish": "npm run build", "postinstall": "node src/haste.js", "test": "npm run lint && npm run coverage", - "mocha": "mocha --require mock.js --bail --timeout 5000 'tests/**/*.test.js'", + "mocha": "mocha --require mock.js --bail --timeout 10000 'tests/**/*.test.js'", "lint": "eslint 'src/' 'tests/' 'mock.js'", "coverage": "nyc npm run mocha", "build": "babel src --out-dir build" From c9610a6f0b58b586f1d3c15cd27d7c1239828986 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 31 Dec 2016 20:38:13 +0000 Subject: [PATCH 034/149] Refactor mocks to not require mockery internally --- src/mocks/ErrorUtils.js | 6 ++---- src/mocks/ListViewDataSource.js | 4 +--- src/react-native-mock.js | 5 +++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/mocks/ErrorUtils.js b/src/mocks/ErrorUtils.js index d9b5ee0..ddd410d 100644 --- a/src/mocks/ErrorUtils.js +++ b/src/mocks/ErrorUtils.js @@ -1,5 +1,3 @@ -import mockery from 'mockery'; - function execute(fun, context, args) { return fun.apply(context, args); } @@ -8,11 +6,11 @@ function reportError(error) { throw error; } -mockery.registerMock('ErrorUtils', { +module.exports = { apply: execute, applyWithGuard: execute, guard: callback => callback, inGuard: () => true, reportError, setGlobalHandler: () => undefined -}); +}; diff --git a/src/mocks/ListViewDataSource.js b/src/mocks/ListViewDataSource.js index cbc9950..77f2cd8 100644 --- a/src/mocks/ListViewDataSource.js +++ b/src/mocks/ListViewDataSource.js @@ -1,5 +1,3 @@ -import mockery from 'mockery'; - const DataSource = require('ListViewDataSource'); // eslint-disable-line import/no-unresolved DataSource.prototype.toJSON = function () { @@ -17,4 +15,4 @@ DataSource.prototype.toJSON = function () { return new ListViewDataSource(this._dataBlob); }; -mockery.registerMock('ListViewDataSource', DataSource); +module.exports = DataSource; diff --git a/src/react-native-mock.js b/src/react-native-mock.js index 090db3a..602a042 100644 --- a/src/react-native-mock.js +++ b/src/react-native-mock.js @@ -45,5 +45,6 @@ _.forEach(MOCK_COMPONENTS, function (component) { mockery.registerMock('requireNativeComponent', createMockComponent); -require('./mocks/ListViewDataSource'); -require('./mocks/ErrorUtils'); + +mockery.registerMock('ListViewDataSource', require('./mocks/ListViewDataSource')); +mockery.registerMock('ErrorUtils', require('./mocks/ErrorUtils')); From 2191970377f717b22006982dbce1042a54e5ca05 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 31 Dec 2016 22:14:38 +0000 Subject: [PATCH 035/149] Fix mock component --- src/createMockComponent.js | 9 ++++----- tests/mock-component.test.js | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/createMockComponent.js b/src/createMockComponent.js index 91d5ea7..9ac70b5 100644 --- a/src/createMockComponent.js +++ b/src/createMockComponent.js @@ -1,17 +1,16 @@ import React from 'react'; export default name => { - class Component extends React.Component { // eslint-disable-line react/prefer-stateless-function + const RealComponent = require(name); + const componentName = (RealComponent.displayName || RealComponent.name || name).replace(/^(RCT|RK)/, ''); + class Component extends RealComponent { // eslint-disable-line react/prefer-stateless-function render() { return React.createElement( - name.replace(/^(RCT|RK)/, ''), + componentName, this.props, this.props.children ); } } - Component.propTypes = { - children: React.PropTypes.any - }; return Component; }; diff --git a/tests/mock-component.test.js b/tests/mock-component.test.js index cbf8c5a..068c155 100644 --- a/tests/mock-component.test.js +++ b/tests/mock-component.test.js @@ -1,9 +1,21 @@ import React from 'react'; // eslint-disable-line no-unused-vars import { shallow } from 'enzyme'; import { expect } from 'chai'; +import mockery from 'mockery'; import createMockComponent from '../src/createMockComponent'; describe('Mock Component', function () { + const testComponent = React.Component; + + beforeEach(function () { + testComponent.name = testComponent.displayName = 'test'; + mockery.registerMock('test', testComponent); + }); + + afterEach(function () { + mockery.deregisterMock('test'); + }); + it('Should render correctly', function () { const Component = createMockComponent('test'); const instance = shallow(); @@ -11,13 +23,17 @@ describe('Mock Component', function () { }); it('Should replace RCT in name', function () { - const Component = createMockComponent('RCTtest'); + testComponent.name = testComponent.displayName = 'RCTtest'; + mockery.registerMock('test', testComponent); + const Component = createMockComponent('test'); const instance = shallow(); expect(instance.html()).to.equal(''); }); it('Should replace RK in name', function () { - const Component = createMockComponent('RKtest'); + testComponent.name = testComponent.displayName = 'RKtest'; + mockery.registerMock('test', testComponent); + const Component = createMockComponent('test'); const instance = shallow(); expect(instance.html()).to.equal(''); }); From 79bbb76f66834b433fcd4abcac23c02d44d6f169 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 31 Dec 2016 22:43:56 +0000 Subject: [PATCH 036/149] Update ListViewDataSource mock --- src/mocks/ListViewDataSource.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mocks/ListViewDataSource.js b/src/mocks/ListViewDataSource.js index 77f2cd8..c12cd6f 100644 --- a/src/mocks/ListViewDataSource.js +++ b/src/mocks/ListViewDataSource.js @@ -6,7 +6,9 @@ DataSource.prototype.toJSON = function () { // Ensure this doesn't throw. try { Object.keys(dataBlob).forEach(key => { - this.items += dataBlob[key] && dataBlob[key].length; + this.items += dataBlob[key] && ( + dataBlob[key].length || dataBlob[key].size || 0 + ); }); } catch (e) { this.items = 'unknown'; From 6e6123bf5fbc399f7ff89341e0e5ee0e08cc6452 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 31 Dec 2016 22:44:16 +0000 Subject: [PATCH 037/149] update requireNativeComponent --- src/react-native-mock.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/react-native-mock.js b/src/react-native-mock.js index 602a042..1e07ec8 100644 --- a/src/react-native-mock.js +++ b/src/react-native-mock.js @@ -2,6 +2,7 @@ import mockery from 'mockery'; import _ from 'underscore'; import defineGlobalProperty from './defineGlobalProperty'; import createMockComponent from './createMockComponent'; +import React from 'react'; require('./babel'); @@ -43,7 +44,11 @@ _.forEach(MOCK_COMPONENTS, function (component) { mockery.registerMock(component, createMockComponent(component)); }); -mockery.registerMock('requireNativeComponent', createMockComponent); +mockery.registerMock('requireNativeComponent', viewName => props => React.createElement( + viewName, + props, + props.children, +)); mockery.registerMock('ListViewDataSource', require('./mocks/ListViewDataSource')); From 32b5f8c3ccc074aa8ec0e174d9a70373b9d42da4 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 31 Dec 2016 22:55:45 +0000 Subject: [PATCH 038/149] add RefreshControl mock --- src/react-native-mock.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/react-native-mock.js b/src/react-native-mock.js index 1e07ec8..b7b5ef5 100644 --- a/src/react-native-mock.js +++ b/src/react-native-mock.js @@ -37,7 +37,8 @@ const MOCK_COMPONENTS = [ 'View', 'ScrollView', 'ActivityIndicator', - 'ListView' + 'ListView', + 'RefreshControl' ]; _.forEach(MOCK_COMPONENTS, function (component) { From bfb785028971fe8b2a26ae0e6f3c9041e274c6dc Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 31 Dec 2016 22:55:57 +0000 Subject: [PATCH 039/149] cleanup dependencies --- package.json | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 21f25e9..926c1fe 100644 --- a/package.json +++ b/package.json @@ -29,20 +29,17 @@ }, "homepage": "https://github.com/RealOrangeOne/react-native-mock#readme", "dependencies": { - "babel-core": "^6.9.0", - "babel-preset-react-native": "^1.6.0", - "glob": "^7.1.1", - "mockery": "=2.0.0", - "promise": "^7.1.1", - "react-addons-test-utils": "^15.4.1", - "react-dom": "^15.4.1", + "glob": "7.1.1", + "mockery": "2.0.0", + "promise": "7.1.1", "regenerator-runtime": "^0.10.1", - "underscore": "=1.8.3" + "react-dom": "^15.4.1", + "underscore": "1.8.3" }, "devDependencies": { - "babel-cli": "=6.9.0", - "chai": "=3.5.0", - "enzyme": "=2.6.0", + "babel-cli": "6.9.0", + "chai": "3.5.0", + "enzyme": "2.6.0", "eslint": "2.10.2", "eslint-config-airbnb": "9.0.1", "eslint-plugin-import": "1.8.0", @@ -55,9 +52,11 @@ "react": "^15.4.1", "react-addons-test-utils": "^15.4.1", "react-dom": "^15.4.1", - "react-native": "^0.39.1" + "react-native": "^0.39.0" }, "peerDependencies": { + "babel-core": "*", + "babel-preset-react-native": "*", "react": "*", "react-native": "*" } From 345764073ab6d76ab7ffc2ea22b2ee81e82f3686 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 31 Dec 2016 23:47:40 +0000 Subject: [PATCH 040/149] fix lint --- src/react-native-mock.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/react-native-mock.js b/src/react-native-mock.js index b7b5ef5..1e74517 100644 --- a/src/react-native-mock.js +++ b/src/react-native-mock.js @@ -48,7 +48,7 @@ _.forEach(MOCK_COMPONENTS, function (component) { mockery.registerMock('requireNativeComponent', viewName => props => React.createElement( viewName, props, - props.children, + props.children // eslint-disable-line react/prop-types )); From 5c69cf3fd109e0c41e5c70f41cc26a285a51e18f Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 1 Jan 2017 00:01:35 +0000 Subject: [PATCH 041/149] QUICKLY --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 63e0bfb..dca202a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 Jake Howard +Copyright (c) 2017 Jake Howard Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 47803e302c9089c38d58e29e193386242af37267 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 1 Jan 2017 01:00:46 +0000 Subject: [PATCH 042/149] Added sinon for spying --- package.json | 3 +- src/NativeModules.js | 77 ++++++++++++++++++++-------------------- src/mocks/ErrorUtils.js | 8 +++-- src/react-native-mock.js | 3 +- 4 files changed, 47 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index 926c1fe..df65a14 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,9 @@ "glob": "7.1.1", "mockery": "2.0.0", "promise": "7.1.1", - "regenerator-runtime": "^0.10.1", "react-dom": "^15.4.1", + "regenerator-runtime": "^0.10.1", + "sinon": "1.17.7", "underscore": "1.8.3" }, "devDependencies": { diff --git a/src/NativeModules.js b/src/NativeModules.js index 7ccfc7e..0a865be 100644 --- a/src/NativeModules.js +++ b/src/NativeModules.js @@ -1,40 +1,41 @@ import _ from 'underscore'; import mockery from 'mockery'; +import sinon from 'sinon'; const mockNativeModules = { AlertManager: { - alertWithArgs: _.noop + alertWithArgs: sinon.spy() }, AppState: { - addEventListener: _.noop + addEventListener: sinon.spy() }, AsyncLocalStorage: { - clear: _.noop, - getItem: _.noop, - removeItem: _.noop, - setItem: _.noop + clear: sinon.spy(), + getItem: sinon.spy(), + removeItem: sinon.spy(), + setItem: sinon.spy() }, BuildInfo: { appVersion: '0', buildVersion: '0' }, Clipboard: { - setString: _.noop + setString: sinon.spy() }, DataManager: { - queryData: _.noop + queryData: sinon.spy() }, FacebookSDK: { - login: _.noop, - logout: _.noop, - queryGraphPath: (path, method, params, callback) => callback() + login: sinon.spy(), + logout: sinon.spy(), + queryGraphPath: sinon.spy((path, method, params, callback) => callback()) }, FbRelayNativeAdapter: { - updateCLC: _.noop + updateCLC: sinon.spy() }, GraphPhotoUpload: { - upload: _.noop + upload: sinon.spy() }, I18n: { translationsDictionary: JSON.stringify({ @@ -42,39 +43,37 @@ const mockNativeModules = { }) }, ImageLoader: { - getSize: (uri, success) => process.nextTick(() => success(320, 240) - ), - prefetchImage: _.noop + getSize: sinon.spy((uri, success) => process.nextTick(() => success(320, 240))), + prefetchImage: sinon.spy() }, ImageViewManager: { - getSize: (uri, success) => process.nextTick(() => success(320, 240) - ), - prefetchImage: _.noop + getSize: sinon.spy((uri, success) => process.nextTick(() => success(320, 240))), + prefetchImage: sinon.spy() }, KeyboardObserver: { - addListener: _.noop, - removeListeners: _.noop + addListener: sinon.spy(), + removeListeners: sinon.spy() }, ModalFullscreenViewManager: {}, Networking: { - sendRequest: _.noop, - abortRequest: _.noop, - addListener: _.noop, - removeListeners: _.noop + sendRequest: sinon.spy(), + abortRequest: sinon.spy(), + addListener: sinon.spy(), + removeListeners: sinon.spy() }, SourceCode: { scriptURL: null }, StatusBarManager: { - setStyle: _.noop, - setHidden: _.noop, - setNetworkActivityIndicatorVisible: _.noop, - setBackgroundColor: _.noop, - setTranslucent: _.noop + setStyle: sinon.spy(), + setHidden: sinon.spy(), + setNetworkActivityIndicatorVisible: sinon.spy(), + setBackgroundColor: sinon.spy(), + setTranslucent: sinon.spy() }, Timing: { - createTimer: _.noop, - deleteTimer: _.noop + createTimer: sinon.spy(), + deleteTimer: sinon.spy() }, UIManager: { customBubblingEventTypes: {}, @@ -98,13 +97,13 @@ const mockNativeModules = { } }, WebSocketModule: { - connect: _.noop, - send: _.noop, - sendBinary: _.noop, - ping: _.noop, - close: _.noop, - addListener: _.noop, - removeListeners: _.noop + connect: sinon.spy(), + send: sinon.spy(), + sendBinary: sinon.spy(), + ping: sinon.spy(), + close: sinon.spy(), + addListener: sinon.spy(), + removeListeners: sinon.spy() } }; diff --git a/src/mocks/ErrorUtils.js b/src/mocks/ErrorUtils.js index ddd410d..0407dec 100644 --- a/src/mocks/ErrorUtils.js +++ b/src/mocks/ErrorUtils.js @@ -1,3 +1,5 @@ +import sinon from 'sinon'; + function execute(fun, context, args) { return fun.apply(context, args); } @@ -9,8 +11,8 @@ function reportError(error) { module.exports = { apply: execute, applyWithGuard: execute, - guard: callback => callback, - inGuard: () => true, + guard: sinon.spy(callback => callback), + inGuard: sinon.spy(() => true), reportError, - setGlobalHandler: () => undefined + setGlobalHandler: sinon.spy(() => undefined) }; diff --git a/src/react-native-mock.js b/src/react-native-mock.js index 1e74517..54ef602 100644 --- a/src/react-native-mock.js +++ b/src/react-native-mock.js @@ -3,6 +3,7 @@ import _ from 'underscore'; import defineGlobalProperty from './defineGlobalProperty'; import createMockComponent from './createMockComponent'; import React from 'react'; +import sinon from 'sinon'; require('./babel'); @@ -26,7 +27,7 @@ require('./NativeModules'); const mockPropRegistry = {}; mockery.registerMock('ReactNativePropRegistry', { register: id => id, - getByID: () => mockPropRegistry + getByID: sinon.spy(() => mockPropRegistry) }); const MOCK_COMPONENTS = [ From 4c080634a428a8284c80d0a7b10495e8214499ab Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 1 Jan 2017 12:59:44 +0000 Subject: [PATCH 043/149] Add test cases for native modules --- package.json | 5 +- scripts/test-helper.js | 5 + tests/native-modules.test.js | 339 ++++++++++++++++++++++++++++++++++- 3 files changed, 343 insertions(+), 6 deletions(-) create mode 100644 scripts/test-helper.js diff --git a/package.json b/package.json index df65a14..996fd0f 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "prepublish": "npm run build", "postinstall": "node src/haste.js", "test": "npm run lint && npm run coverage", - "mocha": "mocha --require mock.js --bail --timeout 10000 'tests/**/*.test.js'", + "mocha": "mocha --require scripts/test-helper.js --require mock.js --bail --timeout 10000 'tests/**/*.test.js'", "lint": "eslint 'src/' 'tests/' 'mock.js'", "coverage": "nyc npm run mocha", "build": "babel src --out-dir build" @@ -53,7 +53,8 @@ "react": "^15.4.1", "react-addons-test-utils": "^15.4.1", "react-dom": "^15.4.1", - "react-native": "^0.39.0" + "react-native": "^0.39.0", + "sinon-chai": "2.8.0" }, "peerDependencies": { "babel-core": "*", diff --git a/scripts/test-helper.js b/scripts/test-helper.js new file mode 100644 index 0000000..1312e71 --- /dev/null +++ b/scripts/test-helper.js @@ -0,0 +1,5 @@ +const sinonChai = require('sinon-chai'); +const chai = require('chai'); + +chai.expect(); +chai.use(sinonChai); diff --git a/tests/native-modules.test.js b/tests/native-modules.test.js index bc70fa7..83cbbff 100644 --- a/tests/native-modules.test.js +++ b/tests/native-modules.test.js @@ -1,5 +1,6 @@ import { expect } from 'chai'; import NativeModules from '../src/NativeModules'; +import sinon from 'sinon'; describe('Native Modules', function () { it('Should be defined', function () { @@ -7,11 +8,341 @@ describe('Native Modules', function () { expect(NativeModules).to.be.an('object'); }); - describe('Single Modules', function () { + it('should be requirable', function () { Object.keys(NativeModules).forEach(function (mod) { - it('should require ' + mod, function () { - expect(require(mod)).to.deep.equal(NativeModules[mod]); - expect(require(mod)).to.be.an('object'); + expect(require(mod)).to.deep.equal(NativeModules[mod]); + }); + }); + + describe('Specific Modules', function () { + describe('AlertManager', function () { + it('should have alertWithArgs as spy', function () { + expect(NativeModules.AlertManager.alertWithArgs).to.be.a('function'); + NativeModules.AlertManager.alertWithArgs(); + expect(NativeModules.AlertManager.alertWithArgs).to.have.been.calledOnce; + }); + }); + + describe('AppState', function () { + it('should have addEventListener as spy', function () { + expect(NativeModules.AppState.addEventListener).to.be.a('function'); + NativeModules.AppState.addEventListener(); + expect(NativeModules.AppState.addEventListener).to.have.been.calledOnce; + }); + }); + + describe('AsyncLocalStorage', function () { + it('should have clear as spy', function () { + expect(NativeModules.AsyncLocalStorage.clear).to.be.a('function'); + NativeModules.AsyncLocalStorage.clear(); + expect(NativeModules.AsyncLocalStorage.clear).to.have.been.calledOnce; + }); + + it('should have getItem as spy', function () { + expect(NativeModules.AsyncLocalStorage.getItem).to.be.a('function'); + NativeModules.AsyncLocalStorage.getItem(); + expect(NativeModules.AsyncLocalStorage.getItem).to.have.been.calledOnce; + }); + + it('should have removeItem as spy', function () { + expect(NativeModules.AsyncLocalStorage.removeItem).to.be.a('function'); + NativeModules.AsyncLocalStorage.removeItem(); + expect(NativeModules.AsyncLocalStorage.removeItem).to.have.been.calledOnce; + }); + + it('should have setItem as spy', function () { + expect(NativeModules.AsyncLocalStorage.setItem).to.be.a('function'); + NativeModules.AsyncLocalStorage.setItem(); + expect(NativeModules.AsyncLocalStorage.setItem).to.have.been.calledOnce; + }); + }); + + describe('BuildInfo', function () { + it('should have version keys', function () { + expect(NativeModules.BuildInfo.appVersion).to.equal('0'); + expect(NativeModules.BuildInfo.buildVersion).to.equal('0'); + }); + }); + + describe('Clipboard', function () { + it('should have setString as spy', function () { + expect(NativeModules.Clipboard.setString).to.be.a('function'); + NativeModules.Clipboard.setString(); + expect(NativeModules.Clipboard.setString).to.have.been.calledOnce; + }); + }); + + describe('DataManager', function () { + it('should have queryData as spy', function () { + expect(NativeModules.DataManager.queryData).to.be.a('function'); + NativeModules.DataManager.queryData(); + expect(NativeModules.DataManager.queryData).to.have.been.calledOnce; + }); + }); + + describe('FacebookSDK', function () { + it('should have login as spy', function () { + expect(NativeModules.FacebookSDK.login).to.be.a('function'); + NativeModules.FacebookSDK.login(); + expect(NativeModules.FacebookSDK.login).to.have.been.calledOnce; + }); + + it('should have logout as spy', function () { + expect(NativeModules.FacebookSDK.logout).to.be.a('function'); + NativeModules.FacebookSDK.logout(); + expect(NativeModules.FacebookSDK.logout).to.have.been.calledOnce; + }); + + it('should have queryGraphPath as spy', function () { + expect(NativeModules.FacebookSDK.queryGraphPath).to.be.a('function'); + const callback = sinon.spy() + NativeModules.FacebookSDK.queryGraphPath('', '', '', callback); + expect(NativeModules.FacebookSDK.queryGraphPath).to.have.been.calledOnce; + expect(callback).to.have.been.calledOnce; + }); + }); + + describe('FbRelayNativeAdapter', function () { + it('should have updateCLC as spy', function () { + expect(NativeModules.FbRelayNativeAdapter.updateCLC).to.be.a('function'); + NativeModules.FbRelayNativeAdapter.updateCLC(); + expect(NativeModules.FbRelayNativeAdapter.updateCLC).to.have.been.calledOnce; + }); + }); + + describe('GraphPhotoUpload', function () { + it('should have upload as spy', function () { + expect(NativeModules.GraphPhotoUpload.upload).to.be.a('function'); + NativeModules.GraphPhotoUpload.upload(); + expect(NativeModules.GraphPhotoUpload.upload).to.have.been.calledOnce; + }); + }); + + describe('I18n', function () { + it('should have translation dict', function () { + expect(NativeModules.I18n.translationsDictionary).to.be.a('string'); + const dict = JSON.parse(NativeModules.I18n.translationsDictionary); + expect(Object.keys(dict)).to.have.lengthOf(1); + }); + }); + + describe('ImageLoader', function () { + it('should have getSize as spy', function (done) { + const callback = sinon.spy(function () { + expect(callback).to.have.been.calledWith(320, 240); + done(); + }); + expect(NativeModules.ImageLoader.getSize).to.be.a('function'); + NativeModules.ImageLoader.getSize('', callback); + expect(NativeModules.ImageLoader.getSize).to.have.been.calledOnce; + }); + + it('should have prefetchImage as spy', function () { + expect(NativeModules.ImageLoader.prefetchImage).to.be.a('function'); + NativeModules.ImageLoader.prefetchImage(); + expect(NativeModules.ImageLoader.prefetchImage).to.have.been.calledOnc + }); + }); + + describe('ImageViewManager', function () { + it('should have getSize as spy', function (done) { + const callback = sinon.spy(function () { + expect(callback).to.have.been.calledWith(320, 240); + done(); + }); + expect(NativeModules.ImageViewManager.getSize).to.be.a('function'); + NativeModules.ImageViewManager.getSize('', callback); + expect(NativeModules.ImageViewManager.getSize).to.have.been.calledOnce; + }); + + it('should have prefetchImage as spy', function () { + expect(NativeModules.ImageViewManager.prefetchImage).to.be.a('function'); + NativeModules.ImageViewManager.prefetchImage(); + expect(NativeModules.ImageViewManager.prefetchImage).to.have.been.calledOnc + }); + }); + + describe('KeyboardObserver', function () { + it('should have addListener as spy', function () { + expect(NativeModules.KeyboardObserver.addListener).to.be.a('function'); + NativeModules.KeyboardObserver.addListener(); + expect(NativeModules.KeyboardObserver.addListener).to.have.been.calledOnce; + }); + + it('should have removeListeners as spy', function () { + expect(NativeModules.KeyboardObserver.removeListeners).to.be.a('function'); + NativeModules.KeyboardObserver.removeListeners(); + expect(NativeModules.KeyboardObserver.removeListeners).to.have.been.calledOnc + }); + }); + + describe('ModalFullscreenViewManager', function () { + it('should be empty', function () { + expect(NativeModules.ModalFullscreenViewManager).to.be.an('object'); + expect(Object.keys(NativeModules.ModalFullscreenViewManager)).to.deep.equal([]); + }); + }); + + describe('Networking', function () { + it('should have sendRequest as spy', function () { + expect(NativeModules.Networking.sendRequest).to.be.a('function'); + NativeModules.Networking.sendRequest(); + expect(NativeModules.Networking.sendRequest).to.have.been.calledOnce; + }); + + it('should have abortRequest as spy', function () { + expect(NativeModules.Networking.abortRequest).to.be.a('function'); + NativeModules.Networking.abortRequest(); + expect(NativeModules.Networking.abortRequest).to.have.been.calledOnce; + }); + + it('should have addListener as spy', function () { + expect(NativeModules.Networking.addListener).to.be.a('function'); + NativeModules.Networking.addListener(); + expect(NativeModules.Networking.addListener).to.have.been.calledOnce; + }); + + it('should have removeListeners as spy', function () { + expect(NativeModules.Networking.removeListeners).to.be.a('function'); + NativeModules.Networking.removeListeners(); + expect(NativeModules.Networking.removeListeners).to.have.been.calledOnce; + }); + }); + + describe('SourceCode', function () { + it('should have null scriptUrl', function () { + expect(NativeModules.SourceCode.scriptURL).to.be.null; + }); + }); + + describe('StatusBarManager', function () { + it('should have setStyle as spy', function () { + expect(NativeModules.StatusBarManager.setStyle).to.be.a('function'); + NativeModules.StatusBarManager.setStyle(); + expect(NativeModules.StatusBarManager.setStyle).to.have.been.calledOnce; + }); + + it('should have setHidden as spy', function () { + expect(NativeModules.StatusBarManager.setHidden).to.be.a('function'); + NativeModules.StatusBarManager.setHidden(); + expect(NativeModules.StatusBarManager.setHidden).to.have.been.calledOnce; + }); + + it('should have setNetworkActivityIndicatorVisible as spy', function () { + expect(NativeModules.StatusBarManager.setNetworkActivityIndicatorVisible).to.be.a('function'); + NativeModules.StatusBarManager.setNetworkActivityIndicatorVisible(); + expect(NativeModules.StatusBarManager.setNetworkActivityIndicatorVisible).to.have.been.calledOnce; + }); + + it('should have setBackgroundColor as spy', function () { + expect(NativeModules.StatusBarManager.setBackgroundColor).to.be.a('function'); + NativeModules.StatusBarManager.setBackgroundColor(); + expect(NativeModules.StatusBarManager.setBackgroundColor).to.have.been.calledOnce; + }); + + it('should have setTranslucent as spy', function () { + expect(NativeModules.StatusBarManager.setTranslucent).to.be.a('function'); + NativeModules.StatusBarManager.setTranslucent(); + expect(NativeModules.StatusBarManager.setTranslucent).to.have.been.calledOnce; + }); + }); + + describe('Timing', function () { + it('should have createTimer as spy', function () { + expect(NativeModules.Timing.createTimer).to.be.a('function'); + NativeModules.Timing.createTimer(); + expect(NativeModules.Timing.createTimer).to.have.been.calledOnce; + }); + + it('should have deleteTimer as spy', function () { + expect(NativeModules.Timing.deleteTimer).to.be.a('function'); + NativeModules.Timing.deleteTimer(); + expect(NativeModules.Timing.deleteTimer).to.have.been.calledOnce; + }); + }); + + describe('UIManager', function () { + it('should have customBubblingEventTypes as object', function () { + expect(NativeModules.UIManager.customBubblingEventTypes).to.be.an('object'); + expect(Object.keys(NativeModules.UIManager.customBubblingEventTypes)).to.deep.equal([]); + }); + + it('should have customDirectEventTypes as object', function () { + expect(NativeModules.UIManager.customDirectEventTypes).to.be.an('object'); + expect(Object.keys(NativeModules.UIManager.customDirectEventTypes)).to.deep.equal([]); + }); + + it('should have window dimensions', function () { + expect(NativeModules.UIManager.Dimensions).to.be.an('object'); + expect(NativeModules.UIManager.Dimensions.window).to.deep.equal({ + fontScale: 2, + height: 1334, + scale: 2, + width: 750 + }); + }); + + it('should have ModalFullscreenView as object', function () { + expect(NativeModules.UIManager.ModalFullscreenView).to.be.an('object'); + expect(NativeModules.UIManager.ModalFullscreenView.Constants).to.be.an('object'); + expect(Object.keys(NativeModules.UIManager.ModalFullscreenView.Constants)).to.deep.equal([]); + }); + + it('should have ScrollView as object', function () { + expect(NativeModules.UIManager.ScrollView).to.be.an('object'); + expect(NativeModules.UIManager.ScrollView.Constants).to.be.an('object'); + expect(Object.keys(NativeModules.UIManager.ScrollView.Constants)).to.deep.equal([]); + }); + + it('should have View as object', function () { + expect(NativeModules.UIManager.View).to.be.an('object'); + expect(NativeModules.UIManager.View.Constants).to.be.an('object'); + expect(Object.keys(NativeModules.UIManager.View.Constants)).to.deep.equal([]); + }); + }); + + + describe('WebSocketModule', function () { + it('should have connect as spy', function () { + expect(NativeModules.WebSocketModule.connect).to.be.a('function'); + NativeModules.WebSocketModule.connect(); + expect(NativeModules.WebSocketModule.connect).to.have.been.calledOnce; + }); + + it('should have send as spy', function () { + expect(NativeModules.WebSocketModule.send).to.be.a('function'); + NativeModules.WebSocketModule.send(); + expect(NativeModules.WebSocketModule.send).to.have.been.calledOnce; + }); + + it('should have sendBinary as spy', function () { + expect(NativeModules.WebSocketModule.sendBinary).to.be.a('function'); + NativeModules.WebSocketModule.sendBinary(); + expect(NativeModules.WebSocketModule.sendBinary).to.have.been.calledOnce; + }); + + it('should have ping as spy', function () { + expect(NativeModules.WebSocketModule.ping).to.be.a('function'); + NativeModules.WebSocketModule.ping(); + expect(NativeModules.WebSocketModule.ping).to.have.been.calledOnce; + }); + + it('should have close as spy', function () { + expect(NativeModules.WebSocketModule.close).to.be.a('function'); + NativeModules.WebSocketModule.close(); + expect(NativeModules.WebSocketModule.close).to.have.been.calledOnce; + }); + + it('should have addListener as spy', function () { + expect(NativeModules.WebSocketModule.addListener).to.be.a('function'); + NativeModules.WebSocketModule.addListener(); + expect(NativeModules.WebSocketModule.addListener).to.have.been.calledOnce; + }); + + it('should have removeListeners as spy', function () { + expect(NativeModules.WebSocketModule.removeListeners).to.be.a('function'); + NativeModules.WebSocketModule.removeListeners(); + expect(NativeModules.WebSocketModule.removeListeners).to.have.been.calledOnce; }); }); }); From 17fde2e6532ab538cebce687b7b932f8633eeff5 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 1 Jan 2017 13:29:46 +0000 Subject: [PATCH 044/149] Test mocked components --- src/react-native-mock.js | 8 ++++---- tests/mock-component.test.js | 13 +++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/react-native-mock.js b/src/react-native-mock.js index 54ef602..0ab9e1e 100644 --- a/src/react-native-mock.js +++ b/src/react-native-mock.js @@ -26,11 +26,11 @@ require('./NativeModules'); const mockPropRegistry = {}; mockery.registerMock('ReactNativePropRegistry', { - register: id => id, + register: sinon.spy(id => id), getByID: sinon.spy(() => mockPropRegistry) }); -const MOCK_COMPONENTS = [ +export const MOCK_COMPONENTS = [ 'Image', 'Text', 'TextInput', @@ -46,11 +46,11 @@ _.forEach(MOCK_COMPONENTS, function (component) { mockery.registerMock(component, createMockComponent(component)); }); -mockery.registerMock('requireNativeComponent', viewName => props => React.createElement( +mockery.registerMock('requireNativeComponent', sinon.spy(viewName => props => React.createElement( viewName, props, props.children // eslint-disable-line react/prop-types -)); +))); mockery.registerMock('ListViewDataSource', require('./mocks/ListViewDataSource')); diff --git a/tests/mock-component.test.js b/tests/mock-component.test.js index 068c155..9fa375c 100644 --- a/tests/mock-component.test.js +++ b/tests/mock-component.test.js @@ -3,6 +3,7 @@ import { shallow } from 'enzyme'; import { expect } from 'chai'; import mockery from 'mockery'; import createMockComponent from '../src/createMockComponent'; +import { MOCK_COMPONENTS } from '../src/react-native-mock'; describe('Mock Component', function () { const testComponent = React.Component; @@ -49,4 +50,16 @@ describe('Mock Component', function () { const Component = createMockComponent('test'); expect(shallow().html()).to.equal(shallow().html()); }); + + describe('Native Components', function () { + const componentRegex = /<(.*?)><\/.*?>/i; + MOCK_COMPONENTS.forEach(function (component) { + it('should require ' + component, function () { + const Component = require(component); + expect(Component).to.be.a('function'); + const instance = shallow(); + expect([component, 'Component']).to.include(componentRegex.exec(instance.html())[1]); + }); + }); + }); }); From 4c8a0a71a66da258bfebda4044b904cda5804429 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 1 Jan 2017 13:42:19 +0000 Subject: [PATCH 045/149] Better check module requires --- tests/react-native-mock.test.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/react-native-mock.test.js b/tests/react-native-mock.test.js index 73db438..ee49c9f 100644 --- a/tests/react-native-mock.test.js +++ b/tests/react-native-mock.test.js @@ -1,9 +1,11 @@ +import { expect } from 'chai'; + describe('React Native Mock', function () { it('shouldnt break when mocking', function () { - require('../src/react-native-mock'); + expect(require('../src/react-native-mock')).to.be.ok; }); it('Should allow requiring of react-native', function () { - require('react-native'); + expect(require('react-native')).to.be.ok; }); }); From c598674b8ae3e47fc725b41efe339bd0740d5696 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 2 Jan 2017 09:57:06 +0000 Subject: [PATCH 046/149] Make images requirable --- src/image-compiler.js | 15 +++++++++++++++ src/react-native-mock.js | 2 ++ tests/image-compiler.test.js | 23 +++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 src/image-compiler.js create mode 100644 tests/image-compiler.test.js diff --git a/src/image-compiler.js b/src/image-compiler.js new file mode 100644 index 0000000..58a2b1f --- /dev/null +++ b/src/image-compiler.js @@ -0,0 +1,15 @@ +/* + Thanks to @zhaotai and @miracle2k for this! + https://github.com/RealOrangeOne/react-native-mock/issues/11#issuecomment-230435835s +*/ + +const m = require('module'); +const originalLoader = m._load; + +m._load = function hookedLoader(request, parent, isMain) { + if (request.match(/.jpeg|.jpg|.png$/)) { + return { uri: request }; + } + + return originalLoader(request, parent, isMain); +}; diff --git a/src/react-native-mock.js b/src/react-native-mock.js index 0ab9e1e..9c15955 100644 --- a/src/react-native-mock.js +++ b/src/react-native-mock.js @@ -55,3 +55,5 @@ mockery.registerMock('requireNativeComponent', sinon.spy(viewName => props => Re mockery.registerMock('ListViewDataSource', require('./mocks/ListViewDataSource')); mockery.registerMock('ErrorUtils', require('./mocks/ErrorUtils')); + +require('./image-compiler'); diff --git a/tests/image-compiler.test.js b/tests/image-compiler.test.js new file mode 100644 index 0000000..3853685 --- /dev/null +++ b/tests/image-compiler.test.js @@ -0,0 +1,23 @@ +import { expect } from 'chai'; + + +describe('Image Compiler', function () { + it('should require a jpg image', function () { + expect(require('foo.jpg')).to.deep.equal({uri: 'foo.jpg'}); + }); + + it('should require a jpeg image', function () { + expect(require('foo.jpeg')).to.deep.equal({uri: 'foo.jpeg'}); + }); + + it('should require a png image', function () { + expect(require('foo.png')).to.deep.equal({uri: 'foo.png'}); + }); + + it('shouldnt require non-image', function () { + function throwRequire() { + return require('foo.foo'); + } + expect(throwRequire).to.throw(Error); + }); +}); From d0e99aecfe13603f793502262f65f0e9ead07dbc Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 2 Jan 2017 12:39:54 +0000 Subject: [PATCH 047/149] FIx mock component display name --- src/createMockComponent.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/createMockComponent.js b/src/createMockComponent.js index 9ac70b5..082d0a5 100644 --- a/src/createMockComponent.js +++ b/src/createMockComponent.js @@ -2,8 +2,13 @@ import React from 'react'; export default name => { const RealComponent = require(name); - const componentName = (RealComponent.displayName || RealComponent.name || name).replace(/^(RCT|RK)/, ''); - class Component extends RealComponent { // eslint-disable-line react/prefer-stateless-function + const realComponentName = RealComponent.name === 'Component' ? name : RealComponent.name + const componentName = (RealComponent.displayName || realComponentName || name).replace(/^(RCT|RK)/, ''); + + return class extends RealComponent { // eslint-disable-line react/prefer-stateless-function + static displayName = componentName; + static name = componentName; + render() { return React.createElement( componentName, @@ -11,6 +16,5 @@ export default name => { this.props.children ); } - } - return Component; + }; }; From f81a298eee9405812cba094ecaca118c728e7f99 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 2 Jan 2017 12:41:01 +0000 Subject: [PATCH 048/149] Fix linting --- tests/image-compiler.test.js | 8 ++++---- tests/native-modules.test.js | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/image-compiler.test.js b/tests/image-compiler.test.js index 3853685..db385e8 100644 --- a/tests/image-compiler.test.js +++ b/tests/image-compiler.test.js @@ -3,20 +3,20 @@ import { expect } from 'chai'; describe('Image Compiler', function () { it('should require a jpg image', function () { - expect(require('foo.jpg')).to.deep.equal({uri: 'foo.jpg'}); + expect(require('foo.jpg')).to.deep.equal({ uri: 'foo.jpg' }); // eslint-disable-line import/no-unresolved }); it('should require a jpeg image', function () { - expect(require('foo.jpeg')).to.deep.equal({uri: 'foo.jpeg'}); + expect(require('foo.jpeg')).to.deep.equal({ uri: 'foo.jpeg' }); // eslint-disable-line import/no-unresolved }); it('should require a png image', function () { - expect(require('foo.png')).to.deep.equal({uri: 'foo.png'}); + expect(require('foo.png')).to.deep.equal({ uri: 'foo.png' }); // eslint-disable-line import/no-unresolved }); it('shouldnt require non-image', function () { function throwRequire() { - return require('foo.foo'); + return require('foo.foo'); // eslint-disable-line import/no-unresolved } expect(throwRequire).to.throw(Error); }); diff --git a/tests/native-modules.test.js b/tests/native-modules.test.js index 83cbbff..fafb9c9 100644 --- a/tests/native-modules.test.js +++ b/tests/native-modules.test.js @@ -95,7 +95,7 @@ describe('Native Modules', function () { it('should have queryGraphPath as spy', function () { expect(NativeModules.FacebookSDK.queryGraphPath).to.be.a('function'); - const callback = sinon.spy() + const callback = sinon.spy(); NativeModules.FacebookSDK.queryGraphPath('', '', '', callback); expect(NativeModules.FacebookSDK.queryGraphPath).to.have.been.calledOnce; expect(callback).to.have.been.calledOnce; @@ -140,7 +140,7 @@ describe('Native Modules', function () { it('should have prefetchImage as spy', function () { expect(NativeModules.ImageLoader.prefetchImage).to.be.a('function'); NativeModules.ImageLoader.prefetchImage(); - expect(NativeModules.ImageLoader.prefetchImage).to.have.been.calledOnc + expect(NativeModules.ImageLoader.prefetchImage).to.have.been.calledOnce; }); }); @@ -158,7 +158,7 @@ describe('Native Modules', function () { it('should have prefetchImage as spy', function () { expect(NativeModules.ImageViewManager.prefetchImage).to.be.a('function'); NativeModules.ImageViewManager.prefetchImage(); - expect(NativeModules.ImageViewManager.prefetchImage).to.have.been.calledOnc + expect(NativeModules.ImageViewManager.prefetchImage).to.have.been.calledOnce; }); }); @@ -172,7 +172,7 @@ describe('Native Modules', function () { it('should have removeListeners as spy', function () { expect(NativeModules.KeyboardObserver.removeListeners).to.be.a('function'); NativeModules.KeyboardObserver.removeListeners(); - expect(NativeModules.KeyboardObserver.removeListeners).to.have.been.calledOnc + expect(NativeModules.KeyboardObserver.removeListeners).to.have.been.calledOnce; }); }); @@ -306,7 +306,7 @@ describe('Native Modules', function () { it('should have connect as spy', function () { expect(NativeModules.WebSocketModule.connect).to.be.a('function'); NativeModules.WebSocketModule.connect(); - expect(NativeModules.WebSocketModule.connect).to.have.been.calledOnce; + expect(NativeModules.WebSocketModule.connect).to.have.been.called; }); it('should have send as spy', function () { @@ -336,7 +336,7 @@ describe('Native Modules', function () { it('should have addListener as spy', function () { expect(NativeModules.WebSocketModule.addListener).to.be.a('function'); NativeModules.WebSocketModule.addListener(); - expect(NativeModules.WebSocketModule.addListener).to.have.been.calledOnce; + expect(NativeModules.WebSocketModule.addListener).to.have.been.called; }); it('should have removeListeners as spy', function () { From 751dc0d8bab612ad8502ab6ab3e0aef0345641f7 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 2 Jan 2017 12:41:55 +0000 Subject: [PATCH 049/149] Start rendering actual components --- .../components/ActivityIndicator.test.js | 18 ++++++++++++++++++ tests/test-utils.js | 1 + 2 files changed, 19 insertions(+) create mode 100644 tests/integration/components/ActivityIndicator.test.js create mode 100644 tests/test-utils.js diff --git a/tests/integration/components/ActivityIndicator.test.js b/tests/integration/components/ActivityIndicator.test.js new file mode 100644 index 0000000..d8b8237 --- /dev/null +++ b/tests/integration/components/ActivityIndicator.test.js @@ -0,0 +1,18 @@ +import React from 'react'; // eslint-disable-line no-unused-vars +import { shallow } from 'enzyme'; +import { expect } from 'chai'; +import { buildComponentHTML } from '../../test-utils'; + + +describe('ActivityIndicator', function () { + let ActivityIndicator; + + beforeEach(function () { + ActivityIndicator = require('react-native').ActivityIndicator; + }); + + it('should render', function () { + const instance = shallow(); + expect(instance.html()).to.equal(buildComponentHTML('ActivityIndicator')); + }); +}); diff --git a/tests/test-utils.js b/tests/test-utils.js new file mode 100644 index 0000000..a43692f --- /dev/null +++ b/tests/test-utils.js @@ -0,0 +1 @@ +export const buildComponentHTML = (componentName) => `<${componentName}>`; From 6b6106ece7e29670f4182614eb902fb65fd49460 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 2 Jan 2017 12:50:33 +0000 Subject: [PATCH 050/149] Add / setup jsdom --- package.json | 1 + scripts/test-helper.js | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/package.json b/package.json index 996fd0f..daef9da 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "eslint-plugin-jsx-a11y": "1.2.2", "eslint-plugin-react": "5.1.1", "eslint-plugin-react-native": "1.0.2", + "jsdom": "9.9.1", "mocha": "3.2.0", "mocka": "0.0.1", "nyc": "10.0.0", diff --git a/scripts/test-helper.js b/scripts/test-helper.js index 1312e71..bfe0400 100644 --- a/scripts/test-helper.js +++ b/scripts/test-helper.js @@ -1,5 +1,22 @@ const sinonChai = require('sinon-chai'); const chai = require('chai'); +const jsdom = require('jsdom'); chai.expect(); chai.use(sinonChai); + +// Jsdom document & window +const doc = jsdom.jsdom(''); +const win = doc.defaultView; + +// Add to global +global.document = doc; +global.window = win; + + +// Add window keys to global window +Object.keys(window).forEach((key) => { + if (!(key in global)) { + global[key] = window[key]; + } +}); From 6578af57aa67c5e6e6c7313a685a7d08f8359611 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 2 Jan 2017 17:47:16 +0000 Subject: [PATCH 051/149] Fix haste map generator --- src/haste.js | 11 ++++++++++- tests/haste-map.test.js | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/haste.js b/src/haste.js index 63e0850..5e1ba29 100644 --- a/src/haste.js +++ b/src/haste.js @@ -7,6 +7,8 @@ var _ = require('underscore'); var providesRegex = /\r?\n \* @providesModule (\S+)(?=\r?\n)/; var validName = /^[a-z0-9-_].+$/i; +var iosTest = /ios/gi; +var androidTest = /android/gi; var CWD = process.cwd(); var data = { @@ -19,7 +21,14 @@ var files = glob.sync('node_modules/**/*.js'); _.forEach(files, function (file) { var matches = providesRegex.exec(fs.readFileSync(file).toString()); if (matches && validName.test(matches[1])) { - data.hasteMap[matches[1]] = file.replace('node_modules/', ''); + var component = matches[1]; + if (component.match(iosTest) && file.endsWith('.android.js')) { // Dont add IOS components if they end in android.js + return; + } + if (component.match(androidTest) && file.endsWith('.ios.js')) { // Dont add Android components if they end in ios.js + return; + } + data.hasteMap[component] = file.replace('node_modules/', ''); } }); diff --git a/tests/haste-map.test.js b/tests/haste-map.test.js index 9176470..83dd32c 100644 --- a/tests/haste-map.test.js +++ b/tests/haste-map.test.js @@ -25,4 +25,24 @@ describe('Haste Map', function () { expect(stat.isFile()).to.be.true; }); }); + + describe('Modules', function () { + const HasteMap = require(MAP_LOCATION).hasteMap; + + it('shouldnt import android version of ios components', function () { + Object.keys(HasteMap).forEach(function (mod) { + if (mod.match(/ios/gi)) { + expect(HasteMap[mod].endsWith('.android.js')).to.be.false; + } + }); + }); + + it('shouldnt import ios version of android components', function () { + Object.keys(HasteMap).forEach(function (mod) { + if (mod.match(/android/gi)) { + expect(HasteMap[mod].endsWith('.ios.js')).to.be.false; + } + }); + }); + }); }); From 09b1c2e6bb7904afbc6387b065d7f708f1c76808 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 2 Jan 2017 21:11:02 +0000 Subject: [PATCH 052/149] Create expect spy wrapper --- tests/native-modules.test.js | 143 ++++++++++------------------------- tests/test-utils.js | 10 +++ 2 files changed, 48 insertions(+), 105 deletions(-) diff --git a/tests/native-modules.test.js b/tests/native-modules.test.js index fafb9c9..94212b9 100644 --- a/tests/native-modules.test.js +++ b/tests/native-modules.test.js @@ -1,6 +1,7 @@ import { expect } from 'chai'; import NativeModules from '../src/NativeModules'; import sinon from 'sinon'; +import { expectSpy } from './test-utils'; describe('Native Modules', function () { it('Should be defined', function () { @@ -17,43 +18,31 @@ describe('Native Modules', function () { describe('Specific Modules', function () { describe('AlertManager', function () { it('should have alertWithArgs as spy', function () { - expect(NativeModules.AlertManager.alertWithArgs).to.be.a('function'); - NativeModules.AlertManager.alertWithArgs(); - expect(NativeModules.AlertManager.alertWithArgs).to.have.been.calledOnce; + expectSpy(NativeModules.AlertManager.alertWithArgs); }); }); describe('AppState', function () { it('should have addEventListener as spy', function () { - expect(NativeModules.AppState.addEventListener).to.be.a('function'); - NativeModules.AppState.addEventListener(); - expect(NativeModules.AppState.addEventListener).to.have.been.calledOnce; + expectSpy(NativeModules.AppState.addEventListener); }); }); describe('AsyncLocalStorage', function () { it('should have clear as spy', function () { - expect(NativeModules.AsyncLocalStorage.clear).to.be.a('function'); - NativeModules.AsyncLocalStorage.clear(); - expect(NativeModules.AsyncLocalStorage.clear).to.have.been.calledOnce; + expectSpy(NativeModules.AsyncLocalStorage.clear); }); it('should have getItem as spy', function () { - expect(NativeModules.AsyncLocalStorage.getItem).to.be.a('function'); - NativeModules.AsyncLocalStorage.getItem(); - expect(NativeModules.AsyncLocalStorage.getItem).to.have.been.calledOnce; + expectSpy(NativeModules.AsyncLocalStorage.getItem); }); it('should have removeItem as spy', function () { - expect(NativeModules.AsyncLocalStorage.removeItem).to.be.a('function'); - NativeModules.AsyncLocalStorage.removeItem(); - expect(NativeModules.AsyncLocalStorage.removeItem).to.have.been.calledOnce; + expectSpy(NativeModules.AsyncLocalStorage.removeItem); }); it('should have setItem as spy', function () { - expect(NativeModules.AsyncLocalStorage.setItem).to.be.a('function'); - NativeModules.AsyncLocalStorage.setItem(); - expect(NativeModules.AsyncLocalStorage.setItem).to.have.been.calledOnce; + expectSpy(NativeModules.AsyncLocalStorage.setItem); }); }); @@ -66,35 +55,27 @@ describe('Native Modules', function () { describe('Clipboard', function () { it('should have setString as spy', function () { - expect(NativeModules.Clipboard.setString).to.be.a('function'); - NativeModules.Clipboard.setString(); - expect(NativeModules.Clipboard.setString).to.have.been.calledOnce; + expectSpy(NativeModules.Clipboard.setString); }); }); describe('DataManager', function () { it('should have queryData as spy', function () { - expect(NativeModules.DataManager.queryData).to.be.a('function'); - NativeModules.DataManager.queryData(); - expect(NativeModules.DataManager.queryData).to.have.been.calledOnce; + expectSpy(NativeModules.DataManager.queryData); }); }); describe('FacebookSDK', function () { it('should have login as spy', function () { - expect(NativeModules.FacebookSDK.login).to.be.a('function'); - NativeModules.FacebookSDK.login(); - expect(NativeModules.FacebookSDK.login).to.have.been.calledOnce; + expectSpy(NativeModules.FacebookSDK.login); }); it('should have logout as spy', function () { - expect(NativeModules.FacebookSDK.logout).to.be.a('function'); - NativeModules.FacebookSDK.logout(); - expect(NativeModules.FacebookSDK.logout).to.have.been.calledOnce; + expectSpy(NativeModules.FacebookSDK.logout); }); it('should have queryGraphPath as spy', function () { - expect(NativeModules.FacebookSDK.queryGraphPath).to.be.a('function'); + expectSpy(NativeModules.FacebookSDK.queryGraphPath); const callback = sinon.spy(); NativeModules.FacebookSDK.queryGraphPath('', '', '', callback); expect(NativeModules.FacebookSDK.queryGraphPath).to.have.been.calledOnce; @@ -104,17 +85,13 @@ describe('Native Modules', function () { describe('FbRelayNativeAdapter', function () { it('should have updateCLC as spy', function () { - expect(NativeModules.FbRelayNativeAdapter.updateCLC).to.be.a('function'); - NativeModules.FbRelayNativeAdapter.updateCLC(); - expect(NativeModules.FbRelayNativeAdapter.updateCLC).to.have.been.calledOnce; + expectSpy(NativeModules.FbRelayNativeAdapter.updateCLC); }); }); describe('GraphPhotoUpload', function () { it('should have upload as spy', function () { - expect(NativeModules.GraphPhotoUpload.upload).to.be.a('function'); - NativeModules.GraphPhotoUpload.upload(); - expect(NativeModules.GraphPhotoUpload.upload).to.have.been.calledOnce; + expectSpy(NativeModules.GraphPhotoUpload.upload); }); }); @@ -128,51 +105,43 @@ describe('Native Modules', function () { describe('ImageLoader', function () { it('should have getSize as spy', function (done) { + expectSpy(NativeModules.ImageLoader.getSize); const callback = sinon.spy(function () { expect(callback).to.have.been.calledWith(320, 240); done(); }); - expect(NativeModules.ImageLoader.getSize).to.be.a('function'); NativeModules.ImageLoader.getSize('', callback); expect(NativeModules.ImageLoader.getSize).to.have.been.calledOnce; }); it('should have prefetchImage as spy', function () { - expect(NativeModules.ImageLoader.prefetchImage).to.be.a('function'); - NativeModules.ImageLoader.prefetchImage(); - expect(NativeModules.ImageLoader.prefetchImage).to.have.been.calledOnce; + expectSpy(NativeModules.ImageLoader.prefetchImage); }); }); describe('ImageViewManager', function () { it('should have getSize as spy', function (done) { + expectSpy(NativeModules.ImageViewManager.getSize); const callback = sinon.spy(function () { expect(callback).to.have.been.calledWith(320, 240); done(); }); - expect(NativeModules.ImageViewManager.getSize).to.be.a('function'); NativeModules.ImageViewManager.getSize('', callback); expect(NativeModules.ImageViewManager.getSize).to.have.been.calledOnce; }); it('should have prefetchImage as spy', function () { - expect(NativeModules.ImageViewManager.prefetchImage).to.be.a('function'); - NativeModules.ImageViewManager.prefetchImage(); - expect(NativeModules.ImageViewManager.prefetchImage).to.have.been.calledOnce; + expectSpy(NativeModules.ImageViewManager.prefetchImage); }); }); describe('KeyboardObserver', function () { it('should have addListener as spy', function () { - expect(NativeModules.KeyboardObserver.addListener).to.be.a('function'); - NativeModules.KeyboardObserver.addListener(); - expect(NativeModules.KeyboardObserver.addListener).to.have.been.calledOnce; + expectSpy(NativeModules.KeyboardObserver.addListener); }); it('should have removeListeners as spy', function () { - expect(NativeModules.KeyboardObserver.removeListeners).to.be.a('function'); - NativeModules.KeyboardObserver.removeListeners(); - expect(NativeModules.KeyboardObserver.removeListeners).to.have.been.calledOnce; + expectSpy(NativeModules.KeyboardObserver.removeListeners); }); }); @@ -185,27 +154,19 @@ describe('Native Modules', function () { describe('Networking', function () { it('should have sendRequest as spy', function () { - expect(NativeModules.Networking.sendRequest).to.be.a('function'); - NativeModules.Networking.sendRequest(); - expect(NativeModules.Networking.sendRequest).to.have.been.calledOnce; + expectSpy(NativeModules.Networking.sendRequest); }); it('should have abortRequest as spy', function () { - expect(NativeModules.Networking.abortRequest).to.be.a('function'); - NativeModules.Networking.abortRequest(); - expect(NativeModules.Networking.abortRequest).to.have.been.calledOnce; + expectSpy(NativeModules.Networking.abortRequest); }); it('should have addListener as spy', function () { - expect(NativeModules.Networking.addListener).to.be.a('function'); - NativeModules.Networking.addListener(); - expect(NativeModules.Networking.addListener).to.have.been.calledOnce; + expectSpy(NativeModules.Networking.addListener); }); it('should have removeListeners as spy', function () { - expect(NativeModules.Networking.removeListeners).to.be.a('function'); - NativeModules.Networking.removeListeners(); - expect(NativeModules.Networking.removeListeners).to.have.been.calledOnce; + expectSpy(NativeModules.Networking.removeListeners); }); }); @@ -217,47 +178,33 @@ describe('Native Modules', function () { describe('StatusBarManager', function () { it('should have setStyle as spy', function () { - expect(NativeModules.StatusBarManager.setStyle).to.be.a('function'); - NativeModules.StatusBarManager.setStyle(); - expect(NativeModules.StatusBarManager.setStyle).to.have.been.calledOnce; + expectSpy(NativeModules.StatusBarManager.setStyle); }); it('should have setHidden as spy', function () { - expect(NativeModules.StatusBarManager.setHidden).to.be.a('function'); - NativeModules.StatusBarManager.setHidden(); - expect(NativeModules.StatusBarManager.setHidden).to.have.been.calledOnce; + expectSpy(NativeModules.StatusBarManager.setHidden); }); it('should have setNetworkActivityIndicatorVisible as spy', function () { - expect(NativeModules.StatusBarManager.setNetworkActivityIndicatorVisible).to.be.a('function'); - NativeModules.StatusBarManager.setNetworkActivityIndicatorVisible(); - expect(NativeModules.StatusBarManager.setNetworkActivityIndicatorVisible).to.have.been.calledOnce; + expectSpy(NativeModules.StatusBarManager.setNetworkActivityIndicatorVisible); }); it('should have setBackgroundColor as spy', function () { - expect(NativeModules.StatusBarManager.setBackgroundColor).to.be.a('function'); - NativeModules.StatusBarManager.setBackgroundColor(); - expect(NativeModules.StatusBarManager.setBackgroundColor).to.have.been.calledOnce; + expectSpy(NativeModules.StatusBarManager.setBackgroundColor); }); it('should have setTranslucent as spy', function () { - expect(NativeModules.StatusBarManager.setTranslucent).to.be.a('function'); - NativeModules.StatusBarManager.setTranslucent(); - expect(NativeModules.StatusBarManager.setTranslucent).to.have.been.calledOnce; + expectSpy(NativeModules.StatusBarManager.setTranslucent); }); }); describe('Timing', function () { it('should have createTimer as spy', function () { - expect(NativeModules.Timing.createTimer).to.be.a('function'); - NativeModules.Timing.createTimer(); - expect(NativeModules.Timing.createTimer).to.have.been.calledOnce; + expectSpy(NativeModules.Timing.createTimer); }); it('should have deleteTimer as spy', function () { - expect(NativeModules.Timing.deleteTimer).to.be.a('function'); - NativeModules.Timing.deleteTimer(); - expect(NativeModules.Timing.deleteTimer).to.have.been.calledOnce; + expectSpy(NativeModules.Timing.deleteTimer); }); }); @@ -304,45 +251,31 @@ describe('Native Modules', function () { describe('WebSocketModule', function () { it('should have connect as spy', function () { - expect(NativeModules.WebSocketModule.connect).to.be.a('function'); - NativeModules.WebSocketModule.connect(); - expect(NativeModules.WebSocketModule.connect).to.have.been.called; + expectSpy(NativeModules.WebSocketModule.connect); }); it('should have send as spy', function () { - expect(NativeModules.WebSocketModule.send).to.be.a('function'); - NativeModules.WebSocketModule.send(); - expect(NativeModules.WebSocketModule.send).to.have.been.calledOnce; + expectSpy(NativeModules.WebSocketModule.send); }); it('should have sendBinary as spy', function () { - expect(NativeModules.WebSocketModule.sendBinary).to.be.a('function'); - NativeModules.WebSocketModule.sendBinary(); - expect(NativeModules.WebSocketModule.sendBinary).to.have.been.calledOnce; + expectSpy(NativeModules.WebSocketModule.sendBinary); }); it('should have ping as spy', function () { - expect(NativeModules.WebSocketModule.ping).to.be.a('function'); - NativeModules.WebSocketModule.ping(); - expect(NativeModules.WebSocketModule.ping).to.have.been.calledOnce; + expectSpy(NativeModules.WebSocketModule.ping); }); it('should have close as spy', function () { - expect(NativeModules.WebSocketModule.close).to.be.a('function'); - NativeModules.WebSocketModule.close(); - expect(NativeModules.WebSocketModule.close).to.have.been.calledOnce; + expectSpy(NativeModules.WebSocketModule.close); }); it('should have addListener as spy', function () { - expect(NativeModules.WebSocketModule.addListener).to.be.a('function'); - NativeModules.WebSocketModule.addListener(); - expect(NativeModules.WebSocketModule.addListener).to.have.been.called; + expectSpy(NativeModules.WebSocketModule.addListener); }); it('should have removeListeners as spy', function () { - expect(NativeModules.WebSocketModule.removeListeners).to.be.a('function'); - NativeModules.WebSocketModule.removeListeners(); - expect(NativeModules.WebSocketModule.removeListeners).to.have.been.calledOnce; + expectSpy(NativeModules.WebSocketModule.removeListeners); }); }); }); diff --git a/tests/test-utils.js b/tests/test-utils.js index a43692f..d204881 100644 --- a/tests/test-utils.js +++ b/tests/test-utils.js @@ -1 +1,11 @@ +import { expect } from 'chai'; +import sinon from 'sinon'; + + export const buildComponentHTML = (componentName) => `<${componentName}>`; + +export const expectSpy = function isSpy(spy) { + expect(spy).to.contain.all.keys( + Object.keys(sinon.spy()) + ); +}; From 9583ea8c24af08ac0047667e340cc34e58e4ccff Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 2 Jan 2017 21:46:48 +0000 Subject: [PATCH 053/149] Add some tests of actual components --- .eslintrc | 1 + src/NativeModules.js | 13 +++++ src/createMockComponent.js | 12 ++-- tests/integration/components.test.js | 55 +++++++++++++++++++ .../components/ActivityIndicator.test.js | 18 ------ tests/test-utils.js | 2 +- 6 files changed, 77 insertions(+), 24 deletions(-) create mode 100644 tests/integration/components.test.js delete mode 100644 tests/integration/components/ActivityIndicator.test.js diff --git a/.eslintrc b/.eslintrc index 654d5f8..86a2186 100644 --- a/.eslintrc +++ b/.eslintrc @@ -20,6 +20,7 @@ "no-restricted-syntax": 0, "prefer-template": 0, "no-unused-expressions": 0, + "vars-on-top": 0, "max-len": [ 2, 120, diff --git a/src/NativeModules.js b/src/NativeModules.js index 0a865be..2346974 100644 --- a/src/NativeModules.js +++ b/src/NativeModules.js @@ -94,6 +94,14 @@ const mockNativeModules = { }, View: { Constants: {} + }, + AndroidDrawerLayout: { + Constants: { + DrawerPosition: { + Right: 'RIGHT', + Left: 'LEFT' + } + } } }, WebSocketModule: { @@ -104,6 +112,11 @@ const mockNativeModules = { close: sinon.spy(), addListener: sinon.spy(), removeListeners: sinon.spy() + }, + Platform: { // https://github.com/facebook/react-native/pull/11651 + OS: 'ios', + Version: () => '', + select: (obj) => obj.ios } }; diff --git a/src/createMockComponent.js b/src/createMockComponent.js index 082d0a5..b05198c 100644 --- a/src/createMockComponent.js +++ b/src/createMockComponent.js @@ -2,13 +2,10 @@ import React from 'react'; export default name => { const RealComponent = require(name); - const realComponentName = RealComponent.name === 'Component' ? name : RealComponent.name + const realComponentName = RealComponent.name === 'Component' ? name : RealComponent.name; const componentName = (RealComponent.displayName || realComponentName || name).replace(/^(RCT|RK)/, ''); - return class extends RealComponent { // eslint-disable-line react/prefer-stateless-function - static displayName = componentName; - static name = componentName; - + const Component = class extends RealComponent { // eslint-disable-line react/prefer-stateless-function render() { return React.createElement( componentName, @@ -17,4 +14,9 @@ export default name => { ); } }; + + Component.displayName = componentName; + Component.name = componentName; + + return Component; }; diff --git a/tests/integration/components.test.js b/tests/integration/components.test.js new file mode 100644 index 0000000..cd2fc15 --- /dev/null +++ b/tests/integration/components.test.js @@ -0,0 +1,55 @@ +import React from 'react'; // eslint-disable-line no-unused-vars +import { shallow } from 'enzyme'; +import { expect } from 'chai'; +import { buildComponentHTML } from '../test-utils'; +import sinon from 'sinon'; + +const COMPONENTS = [ + 'Image', + 'Text', + 'TextInput', + 'Modal', + 'View', + 'ScrollView', + 'ActivityIndicator', + 'ListView', + 'RefreshControl' +]; + +describe('Components', function () { + const ReactNative = require('react-native'); + + COMPONENTS.forEach(function (component) { // Render loads fast! + it(`should render ${component}`, function () { + const Component = ReactNative[component]; + const instance = shallow(); + expect(instance.html()).to.equal(buildComponentHTML(component)); + }); + }); + + it('should render Button', function () { + const { Button } = ReactNative; + const instance = shallow(