From 06a87bec25d7184269ef95d5190ef63ce77f0942 Mon Sep 17 00:00:00 2001 From: Christopher Chedeau Date: Wed, 18 Mar 2015 15:57:49 -0700 Subject: [PATCH] Updates from Wed 18 Mar - [ReactNative] Add AsyncStorageTest | Spencer Ahrens - [ReactNative] Add timers integration test | Spencer Ahrens - [ReactNative] Remove ExpandingText | Tadeu Zagallo - [TouchableHighlight] Preserve underlay style when restoring inactive props | Christopher Chedeau - clean flow errors in react-native-github | Basil Hosmer - [ReactNative] Sort React Native exports into two groups, Components and APIs | Christopher Chedeau - [ReactNative] Rename Slider to SliderIOS | Tadeu Zagallo - [react_native] JS files from D1919491: Improve JS logging | Martin Kosiba - [ReactNative] Add TimerExample | Spencer Ahrens - [RFC][ReactNative] increase timer resolution | Spencer Ahrens - [ReactNative] Strip prefixes from NativeModules keys | Spencer Ahrens - [ReactNative] Small docs cleanup in ActivityIndicatorIOS and DatePickerIOS | Christopher Chedeau - [ReactNative] Improvements on perf measurement output | Jing Chen - [ReactNative] Clean up Touchable PropTypes | Christopher Chedeau - [ReactKit] Fail tests when redbox shows up | Alex Kotliarskyi --- .flowconfig | 5 +- Examples/2048/Game2048.js | 5 + Examples/Movies/MovieScreen.js | 8 +- Examples/UIExplorer/CameraRollExample.ios.js | 4 +- Examples/UIExplorer/ExpandingTextExample.js | 52 ----- Examples/UIExplorer/ListViewPagingExample.js | 4 +- .../{SliderExample.js => SliderIOSExample.js} | 8 +- Examples/UIExplorer/TimerExample.js | 193 ++++++++++++++++++ .../UIExplorer.xcodeproj/project.pbxproj.rej | 72 +++++++ Examples/UIExplorer/UIExplorerList.js | 4 +- .../UIExplorerTests/UIExplorerTests.m | 8 +- IntegrationTests/AsyncStorageTest.js | 148 ++++++++++++++ .../IntegrationTestHarnessTest.js | 2 +- IntegrationTests/IntegrationTestsApp.js | 2 + .../IntegrationTestsTests.m | 10 + IntegrationTests/TimersTest.js | 150 ++++++++++++++ Libraries/ActionSheetIOS/ActionSheetIOS.js | 2 +- Libraries/AdSupport/AdSupportIOS.js | 2 +- Libraries/Animation/Animation.js | 2 +- Libraries/Animation/AnimationMixin.js | 2 +- Libraries/Animation/LayoutAnimation.js | 2 +- Libraries/Animation/POPAnimationMixin.js | 7 +- Libraries/AppState/AppState.js | 2 +- Libraries/AppStateIOS/AppStateIOS.ios.js | 2 +- .../BatchedBridgedModules/NativeModules.js | 4 +- .../BatchedBridgedModules/POPAnimation.js | 2 +- .../RCTAlertManager.ios.js | 2 +- Libraries/CameraRoll/CameraRoll.js | 2 +- .../ActivityIndicatorIOS.ios.js | 7 +- .../DatePicker/DatePickerIOS.ios.js | 8 +- Libraries/Components/ListView/ListView.js | 2 +- .../Components/ListView/ListViewDataSource.js | 12 +- .../Components/Navigation/NavigatorIOS.ios.js | 2 +- Libraries/Components/ScrollResponder.js | 4 +- Libraries/Components/ScrollView/ScrollView.js | 4 +- .../Slider.js => SliderIOS/SliderIOS.js} | 6 +- .../Components/StatusBar/StatusBarIOS.ios.js | 2 +- .../Components/TextInput/TextInput.ios.js | 2 +- .../Components/TextInput/TextInputState.js | 2 +- .../Touchable/TouchableFeedbackPropType.js | 22 -- .../Touchable/TouchableHighlight.js | 14 +- .../Components/Touchable/TouchableOpacity.js | 4 +- .../Touchable/TouchableWithoutFeedback.js | 12 +- .../Components/WebView/WebView.android.js | 2 +- Libraries/Components/WebView/WebView.ios.js | 2 +- Libraries/Geolocation/Geolocation.ios.js | 2 +- Libraries/Image/Image.ios.js | 2 +- .../InitializeJavaScriptAppEngine.js | 4 +- .../Initialization/loadSourceMap.js | 2 +- .../System/JSTimers/JSTimers.js | 4 +- Libraries/Network/NetInfo.js | 2 +- Libraries/Network/XMLHttpRequest.ios.js | 2 +- Libraries/Picker/PickerIOS.ios.js | 2 +- Libraries/RKBackendNode/queryLayoutByID.js | 2 +- .../ReactIOS/IOSNativeBridgeEventPlugin.js | 2 +- Libraries/ReactIOS/NativeMethodsMixin.js | 4 +- Libraries/ReactIOS/ReactIOSDOMIDOperations.js | 2 +- .../ReactIOSGlobalResponderHandler.js | 2 +- Libraries/ReactIOS/ReactIOSMount.js | 2 +- Libraries/ReactIOS/ReactIOSNativeComponent.js | 2 +- Libraries/ReactIOS/ReactIOSTextComponent.js | 2 +- Libraries/Storage/AsyncStorage.ios.js | 4 +- Libraries/Text/ExpandingText.js | 130 ------------ Libraries/Utilities/AlertIOS.js | 2 +- Libraries/Utilities/Dimensions.js | 2 +- Libraries/Utilities/PushNotificationIOS.js | 2 +- Libraries/Utilities/RCTRenderingPerf.js | 13 ++ .../Utilities/nativeModulePrefixDuplicator.js | 25 --- .../Utilities/nativeModulePrefixNormalizer.js | 24 +++ Libraries/Vibration/VibrationIOS.ios.js | 3 +- Libraries/react-native/addons.js | 2 + .../react-native/react-native-interface.js | 1 - Libraries/react-native/react-native.js | 39 ++-- ReactKit/Modules/RCTTiming.m | 6 + .../haste/polyfills/console.js | 62 +++--- 75 files changed, 794 insertions(+), 372 deletions(-) delete mode 100644 Examples/UIExplorer/ExpandingTextExample.js rename Examples/UIExplorer/{SliderExample.js => SliderIOSExample.js} (90%) create mode 100644 Examples/UIExplorer/TimerExample.js create mode 100644 Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj.rej create mode 100644 IntegrationTests/AsyncStorageTest.js create mode 100644 IntegrationTests/TimersTest.js rename Libraries/Components/{Slider/Slider.js => SliderIOS/SliderIOS.js} (95%) delete mode 100644 Libraries/Components/Touchable/TouchableFeedbackPropType.js delete mode 100644 Libraries/Text/ExpandingText.js delete mode 100644 Libraries/Utilities/nativeModulePrefixDuplicator.js create mode 100644 Libraries/Utilities/nativeModulePrefixNormalizer.js diff --git a/.flowconfig b/.flowconfig index 20bb687568b14d..82d818dcc09b5b 100644 --- a/.flowconfig +++ b/.flowconfig @@ -9,7 +9,7 @@ # Ignore react-tools where there are overlaps, but don't ignore anything that # react-native relies on -.*/node_modules/react-tools/src/vendor/.* +.*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js .*/node_modules/react-tools/src/browser/.* .*/node_modules/react-tools/src/core/ReactInstanceHandles.js .*/node_modules/react-tools/src/event/.* @@ -17,9 +17,6 @@ # Ignore jest .*/react-native/node_modules/jest-cli/.* -# Ignore Libraries -.*/Libraries/.* - [include] [libs] diff --git a/Examples/2048/Game2048.js b/Examples/2048/Game2048.js index e6b7fa6d4c194a..f4ad51b41ed204 100644 --- a/Examples/2048/Game2048.js +++ b/Examples/2048/Game2048.js @@ -129,11 +129,16 @@ class GameEndOverlay extends React.Component { } class Game2048 extends React.Component { + startX: number; + startY: number; + constructor(props) { super(props); this.state = { board: new GameBoard(), }; + this.startX = 0; + this.startY = 0; } restartGame() { diff --git a/Examples/Movies/MovieScreen.js b/Examples/Movies/MovieScreen.js index 53c8879dc02886..8584d8753cc8c3 100644 --- a/Examples/Movies/MovieScreen.js +++ b/Examples/Movies/MovieScreen.js @@ -6,7 +6,6 @@ var React = require('react-native'); var { - ExpandingText, Image, PixelRatio, ScrollView, @@ -40,10 +39,9 @@ var MovieScreen = React.createClass({ - + + {this.props.movie.synopsis} + diff --git a/Examples/UIExplorer/CameraRollExample.ios.js b/Examples/UIExplorer/CameraRollExample.ios.js index 31634d583ac7a8..7be014a33b2c5c 100644 --- a/Examples/UIExplorer/CameraRollExample.ios.js +++ b/Examples/UIExplorer/CameraRollExample.ios.js @@ -7,7 +7,7 @@ var React = require('react-native'); var { CameraRoll, Image, - Slider, + SliderIOS, StyleSheet, SwitchIOS, Text, @@ -35,7 +35,7 @@ var CameraRollExample = React.createClass({ onValueChange={this._onSwitchChange} value={this.state.bigImages} /> {(this.state.bigImages ? 'Big' : 'Small') + ' Images'} - diff --git a/Examples/UIExplorer/ExpandingTextExample.js b/Examples/UIExplorer/ExpandingTextExample.js deleted file mode 100644 index 2a2f61fc823c09..00000000000000 --- a/Examples/UIExplorer/ExpandingTextExample.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright 2004-present Facebook. All Rights Reserved. - */ -'use strict'; - -var React = require('react-native'); -var { - ExpandingText -} = React; - -var LOREM = 'Lorem ipsum dolor sit amet, mea adipisci inimicus ex, paulo essent bonorum et ius, rebum deserunt mediocritatem ius ei.'; - -exports.title = ''; -exports.description = 'Base component for rendering text that is truncated and can be expanded upon tap.'; -exports.examples = [ -{ - title: 'Expanding text (truncLength=20)', - description: 'Setting the truncLength prop will cause the text to truncate to that character length', - render: function() { - return ; - } -}, { - title: 'Expanding text (truncLength=80)', - description: 'The higher the truncLength the more characters that will be shown by default', - render: function() { - return ; - } -}, { - title: 'Expanding text with custom style', - description: 'You can style the text within the ExpandingText component', - render: function() { - return ( - - ); - } -}, { - title: 'See More button with custom style' , - description: 'You can also style just the See More button', - render: function() { - return ( - - ); - } -}]; diff --git a/Examples/UIExplorer/ListViewPagingExample.js b/Examples/UIExplorer/ListViewPagingExample.js index c74795eb5a104e..0eec2700c3c2e3 100644 --- a/Examples/UIExplorer/ListViewPagingExample.js +++ b/Examples/UIExplorer/ListViewPagingExample.js @@ -99,11 +99,11 @@ var ListViewPagingExample = React.createClass({ }; }, - renderRow: function(rowData, sectionID, rowID) { + renderRow: function(rowData: string, sectionID: string, rowID: string): ReactElement { return (); }, - renderSectionHeader: function(sectionData, sectionID) { + renderSectionHeader: function(sectionData: string, sectionID: string) { return ( diff --git a/Examples/UIExplorer/SliderExample.js b/Examples/UIExplorer/SliderIOSExample.js similarity index 90% rename from Examples/UIExplorer/SliderExample.js rename to Examples/UIExplorer/SliderIOSExample.js index d1ff73779c3e00..bc58ccec71cbc0 100644 --- a/Examples/UIExplorer/SliderExample.js +++ b/Examples/UIExplorer/SliderIOSExample.js @@ -5,7 +5,7 @@ var React = require('react-native'); var { - Slider, + SliderIOS, Text, StyleSheet, View, @@ -24,7 +24,7 @@ var SliderExample = React.createClass({ {this.state.value} - this.setState({value: value})} /> @@ -45,11 +45,11 @@ var styles = StyleSheet.create({ }, }); -exports.title = ''; +exports.title = ''; exports.description = 'Slider input for numeric values'; exports.examples = [ { - title: 'Slider', + title: 'SliderIOS', render() { return ; } } ]; diff --git a/Examples/UIExplorer/TimerExample.js b/Examples/UIExplorer/TimerExample.js new file mode 100644 index 00000000000000..6d48738d4d7ef9 --- /dev/null +++ b/Examples/UIExplorer/TimerExample.js @@ -0,0 +1,193 @@ +/** + * Copyright 2004-present Facebook. All Rights Reserved. + */ +'use strict'; + +var React = require('react-native'); +var { + AlertIOS, + StyleSheet, + Text, + TimerMixin, + TouchableHighlight, + View, +} = React; + +var Button = React.createClass({ + render: function() { + return ( + + + {this.props.children} + + + ); + }, +}); + +var TimerTester = React.createClass({ + mixins: [TimerMixin], + + render: function() { + var args = 'fn' + (this.props.dt !== undefined ? ', ' + this.props.dt : ''); + return ( + + ); + }, + + _run: function() { + if (!this._start) { + var d = new Date(); + this._start = d.getTime(); + this._iters = 100; + this._ii = 0; + if (this.props.type === 'setTimeout') { + if (this.props.dt < 1) { + this._iters = 5000; + } else if (this.props.dt > 20) { + this._iters = 10; + } + this._timerFn = () => this.setTimeout(this._run, this.props.dt); + } else if (this.props.type === 'requestAnimationFrame') { + this._timerFn = () => this.requestAnimationFrame(this._run); + } else if (this.props.type === 'setImmediate') { + this._iters = 5000; + this._timerFn = () => this.setImmediate(this._run); + } else if (this.props.type === 'setInterval') { + this._iters = 30; // Only used for forceUpdate periodicidy + this._timerFn = null; + this._handle = this.setInterval(this._run, this.props.dt); + } + } + if (this._ii >= this._iters && !this._handle) { + var d = new Date(); + var e = (d.getTime() - this._start); + var msg = 'Finished ' + this._ii + ' ' + this.props.type + ' calls.\n' + + 'Elapsed time: ' + e + ' ms\n' + (e / this._ii) + ' ms / iter'; + console.log(msg); + AlertIOS.alert(msg); + this._start = null; + this.forceUpdate(() => { this._ii = 0; }); + return; + } + this._ii++; + // Only re-render occasionally so we don't slow down timers. + if (this._ii % (this._iters / 5) === 0) { + this.forceUpdate(); + } + this._timerFn && this._timerFn(); + }, + + clear: function() { + this.clearInterval(this._handle); // invalid handles are ignored + if (this._handle) { + // Configure things so we can do a final run to update UI and reset state. + this._handle = null; + this._iters = this._ii; + this._run(); + } + }, +}); + +var styles = StyleSheet.create({ + button: { + borderColor: 'gray', + borderRadius: 8, + borderWidth: 1, + padding: 10, + margin: 5, + alignItems: 'center', + justifyContent: 'center', + }, +}); + +exports.framework = 'React'; +exports.title = 'Timers, TimerMixin'; +exports.description = 'The TimerMixin provides timer functions for executing ' + + 'code in the future that are safely cleaned up when the component unmounts.'; + +exports.examples = [ + { + title: 'this.setTimeout(fn, t)', + description: 'Execute function fn t milliseconds in the future. If ' + + 't === 0, it will be enqueued immediately in the next event loop. ' + + 'Larger values will fire on the closest frame.', + render: function() { + return ( + + + + + + ); + }, + }, + { + title: 'this.requestAnimationFrame(fn)', + description: 'Execute function fn on the next frame.', + render: function() { + return ( + + + + ); + }, + }, + { + title: 'this.setImmediate(fn)', + description: 'Execute function fn at the end of the current JS event loop.', + render: function() { + return ( + + + + ); + }, + }, + { + title: 'this.setInterval(fn, t)', + description: 'Execute function fn every t milliseconds until cancelled ' + + 'or component is unmounted.', + render: function() { + var IntervalExample = React.createClass({ + getInitialState: function() { + return { + showTimer: true, + }; + }, + + render: function() { + if (this.state.showTimer) { + var timer = + ; + var toggleText = 'Unmount timer'; + } else { + var timer = null; + var toggleText = 'Mount new timer'; + } + return ( + + {timer} + + + + ); + }, + + _toggleTimer: function() { + this.setState({showTimer: !this.state.showTimer}); + }, + }); + return ; + }, + }, +]; diff --git a/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj.rej b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj.rej new file mode 100644 index 00000000000000..fa002c8b07a6b3 --- /dev/null +++ b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj.rej @@ -0,0 +1,72 @@ +diff a/Libraries/FBReactKit/js/react-native-github/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj b/Libraries/FBReactKit/js/react-native-github/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj (rejected hunks) +@@ -19,6 +19,7 @@ + 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; + 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; + 147CED4C1AB3532B00DA3E4C /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 147CED4B1AB34F8C00DA3E4C /* libRCTActionSheet.a */; }; ++ D85B829E1AB6D5D7003F4FE2 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85B829C1AB6D5CE003F4FE2 /* libRCTVibration.a */; }; + /* End PBXBuildFile section */ + + /* Begin PBXContainerItemProxy section */ +@@ -78,6 +79,13 @@ + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = RCTActionSheet; + }; ++ D85B829B1AB6D5CE003F4FE2 /* PBXContainerItemProxy */ = { ++ isa = PBXContainerItemProxy; ++ containerPortal = D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */; ++ proxyType = 2; ++ remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; ++ remoteInfo = RCTVibration; ++ }; + /* End PBXContainerItemProxy section */ + + /* Begin PBXFileReference section */ +@@ -98,6 +106,7 @@ + 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = ""; }; ++ D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = ""; }; + /* End PBXFileReference section */ + + /* Begin PBXFrameworksBuildPhase section */ +@@ -112,6 +121,7 @@ + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( ++ D85B829E1AB6D5D7003F4FE2 /* libRCTVibration.a in Frameworks */, + 147CED4C1AB3532B00DA3E4C /* libRCTActionSheet.a in Frameworks */, + 134454601AAFCABD003F0779 /* libRCTAdSupport.a in Frameworks */, + 134A8A2A1AACED7A00945AAE /* libRCTGeolocation.a in Frameworks */, +@@ -145,6 +155,7 @@ + 1316A21D1AA397F400C0188E /* Libraries */ = { + isa = PBXGroup; + children = ( ++ D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */, + 14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */, + 13417FFA1AA91531003F314A /* ReactKit.xcodeproj */, + 134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */, +@@ -334,6 +353,10 @@ + ProjectRef = 13417FEA1AA914B8003F314A /* RCTText.xcodeproj */; + }, + { ++ ProductGroup = D85B82921AB6D5CE003F4FE2 /* Products */; ++ ProjectRef = D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */; ++ }, ++ { + ProductGroup = 13417FFB1AA91531003F314A /* Products */; + ProjectRef = 13417FFA1AA91531003F314A /* ReactKit.xcodeproj */; + }, +@@ -396,6 +419,13 @@ + remoteRef = 147CED4A1AB34F8C00DA3E4C /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; ++ D85B829C1AB6D5CE003F4FE2 /* libRCTVibration.a */ = { ++ isa = PBXReferenceProxy; ++ fileType = archive.ar; ++ path = libRCTVibration.a; ++ remoteRef = D85B829B1AB6D5CE003F4FE2 /* PBXContainerItemProxy */; ++ sourceTree = BUILT_PRODUCTS_DIR; ++ }; + /* End PBXReferenceProxy section */ + + /* Begin PBXResourcesBuildPhase section */ diff --git a/Examples/UIExplorer/UIExplorerList.js b/Examples/UIExplorer/UIExplorerList.js index bc46292fd4add9..08558971f25b62 100644 --- a/Examples/UIExplorer/UIExplorerList.js +++ b/Examples/UIExplorer/UIExplorerList.js @@ -20,8 +20,8 @@ var EXAMPLES = [ require('./ViewExample'), require('./LayoutExample'), require('./TextExample.ios'), + require('./TimerExample'), require('./TextInputExample'), - require('./ExpandingTextExample'), require('./ImageExample'), require('./ListViewSimpleExample'), require('./ListViewPagingExample'), @@ -36,7 +36,7 @@ var EXAMPLES = [ require('./GeolocationExample'), require('./TabBarExample'), require('./SwitchExample'), - require('./SliderExample'), + require('./SliderIOSExample'), require('./AsyncStorageExample'), require('./CameraRollExample.ios'), require('./MapViewExample'), diff --git a/Examples/UIExplorer/UIExplorerTests/UIExplorerTests.m b/Examples/UIExplorer/UIExplorerTests/UIExplorerTests.m index 237270f67067cd..854ee445a25aa9 100644 --- a/Examples/UIExplorer/UIExplorerTests/UIExplorerTests.m +++ b/Examples/UIExplorer/UIExplorerTests/UIExplorerTests.m @@ -3,6 +3,8 @@ #import #import +#import "RCTRedBox.h" + #define TIMEOUT_SECONDS 240 @interface UIExplorerTests : XCTestCase @@ -29,11 +31,14 @@ - (void)testRootViewLoadsAndRenders { NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; BOOL foundElement = NO; + NSString *redboxError = nil; - while ([date timeIntervalSinceNow] > 0 && !foundElement) { + while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:date]; [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:date]; + redboxError = [[RCTRedBox sharedInstance] currentErrorMessage]; + foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { if ([view respondsToSelector:@selector(attributedText)]) { NSString *text = [(id)view attributedText].string; @@ -45,6 +50,7 @@ - (void)testRootViewLoadsAndRenders { }]; } + XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); XCTAssertTrue(foundElement, @"Cound't find element with '' text in %d seconds", TIMEOUT_SECONDS); } diff --git a/IntegrationTests/AsyncStorageTest.js b/IntegrationTests/AsyncStorageTest.js new file mode 100644 index 00000000000000..82fb348b224371 --- /dev/null +++ b/IntegrationTests/AsyncStorageTest.js @@ -0,0 +1,148 @@ +/** + * Copyright 2004-present Facebook. All Rights Reserved. + */ +'use strict'; + +var RCTTestModule = require('NativeModules').TestModule; +var React = require('react-native'); +var { + AsyncStorage, + Text, + View, +} = React; + +var DEBUG = false; + +var KEY_1 = 'key_1'; +var VAL_1 = 'val_1'; +var KEY_2 = 'key_2'; +var VAL_2 = 'val_2'; + +// setup in componentDidMount +var done; +var updateMessage; + +function runTestCase(description, fn) { + updateMessage(description); + fn(); +} + +function expectTrue(condition, message) { + if (!condition) { + throw new Error(message); + } +} + +function expectEqual(lhs, rhs, testname) { + expectTrue( + lhs === rhs, + 'Error in test ' + testname + ': expected ' + rhs + ', got ' + lhs + ); +} + +function expectAsyncNoError(err) { + expectTrue(err === null, 'Unexpected Async error: ' + JSON.stringify(err)); +} + +function testSetAndGet() { + AsyncStorage.setItem(KEY_1, VAL_1, (err1) => { + expectAsyncNoError(err1); + AsyncStorage.getItem(KEY_1, (err2, result) => { + expectAsyncNoError(err2); + expectEqual(result, VAL_1, 'testSetAndGet setItem'); + updateMessage('get(key_1) correctly returned ' + result); + runTestCase('should get null for missing key', testMissingGet); + }); + }); +} + +function testMissingGet() { + AsyncStorage.getItem(KEY_2, (err, result) => { + expectAsyncNoError(err); + expectEqual(result, null, 'testMissingGet'); + updateMessage('missing get(key_2) correctly returned ' + result); + runTestCase('check set twice results in a single key', testSetTwice); + }); +} + +function testSetTwice() { + AsyncStorage.setItem(KEY_1, VAL_1, ()=>{ + AsyncStorage.setItem(KEY_1, VAL_1, ()=>{ + AsyncStorage.getItem(KEY_1, (err, result) => { + expectAsyncNoError(err); + expectEqual(result, VAL_1, 'testSetTwice'); + updateMessage('setTwice worked as expected'); + runTestCase('test removeItem', testRemoveItem); + }); + }); + }); +} + +function testRemoveItem() { + AsyncStorage.setItem(KEY_1, VAL_1, ()=>{ + AsyncStorage.setItem(KEY_2, VAL_2, ()=>{ + AsyncStorage.getAllKeys((err, result) => { + expectAsyncNoError(err); + expectTrue( + result.indexOf(KEY_1) >= 0 && result.indexOf(KEY_2) >= 0, + 'Missing KEY_1 or KEY_2 in ' + '(' + result + ')' + ); + updateMessage('testRemoveItem - add two items'); + AsyncStorage.removeItem(KEY_1, (err) => { + expectAsyncNoError(err); + updateMessage('delete successful '); + AsyncStorage.getItem(KEY_1, (err, result) => { + expectAsyncNoError(err); + expectEqual( + result, + null, + 'testRemoveItem: key_1 present after delete' + ); + updateMessage('key properly removed '); + AsyncStorage.getAllKeys((err, result2) => { + expectAsyncNoError(err); + expectTrue( + result2.indexOf(KEY_1) === -1, + 'Unexpected: KEY_1 present in ' + result2 + ); + updateMessage('proper length returned.\nDone!'); + done(); + }); + }); + }); + }); + }); + }); +} + +var AsyncStorageTest = React.createClass({ + getInitialState() { + return { + messages: 'Initializing...', + done: false, + }; + }, + + componentDidMount() { + done = () => this.setState({done: true}, RCTTestModule.markTestCompleted); + updateMessage = (msg) => { + this.setState({messages: this.state.messages.concat('\n' + msg)}); + DEBUG && console.log(msg); + }; + AsyncStorage.clear(testSetAndGet); + }, + + render() { + return ( + + + {this.constructor.displayName + ': '} + {this.state.done ? 'Done' : 'Testing...'} + {'\n\n' + this.state.messages} + + + ); + } +}); + +module.exports = AsyncStorageTest; diff --git a/IntegrationTests/IntegrationTestHarnessTest.js b/IntegrationTests/IntegrationTestHarnessTest.js index 5b6e78838fc28f..5ae78cf9cacca0 100644 --- a/IntegrationTests/IntegrationTestHarnessTest.js +++ b/IntegrationTests/IntegrationTestHarnessTest.js @@ -3,7 +3,7 @@ */ 'use strict'; -var RCTTestModule = require('NativeModules').RCTTestModule; +var RCTTestModule = require('NativeModules').TestModule; var React = require('react-native'); var { Text, diff --git a/IntegrationTests/IntegrationTestsApp.js b/IntegrationTests/IntegrationTestsApp.js index ee60aa38872ce2..30464bbccf4f81 100644 --- a/IntegrationTests/IntegrationTestsApp.js +++ b/IntegrationTests/IntegrationTestsApp.js @@ -18,6 +18,8 @@ var { var TESTS = [ require('./IntegrationTestHarnessTest'), + require('./TimersTest'), + require('./AsyncStorageTest'), ]; TESTS.forEach( diff --git a/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m b/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m index 9d9020f7d1188c..4cb8944801c4f8 100644 --- a/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m +++ b/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m @@ -37,4 +37,14 @@ - (void)testTheTester_ExpectError expectErrorRegex:[NSRegularExpression regularExpressionWithPattern:@"because shouldThrow" options:0 error:nil]]; } +- (void)testTimers +{ + [_runner runTest:@"TimersTest"]; +} + +- (void)testAsyncStorage +{ + [_runner runTest:@"AsyncStorageTest"]; +} + @end diff --git a/IntegrationTests/TimersTest.js b/IntegrationTests/TimersTest.js new file mode 100644 index 00000000000000..db376304b839f4 --- /dev/null +++ b/IntegrationTests/TimersTest.js @@ -0,0 +1,150 @@ +/** + * Copyright 2004-present Facebook. All Rights Reserved. + */ +'use strict'; + +var RCTTestModule = require('NativeModules').TestModule; +var React = require('react-native'); +var { + StyleSheet, + Text, + TimerMixin, + View, +} = React; + +var TimersTest = React.createClass({ + mixins: [TimerMixin], + + getInitialState() { + return { + count: 0, + done: false, + }; + }, + + componentDidMount() { + this.testSetTimeout0(); + }, + + testSetTimeout0() { + this.setTimeout(this.testSetTimeout1, 0); + }, + + testSetTimeout1() { + this.setTimeout(this.testSetTimeout50, 1); + }, + + testSetTimeout50() { + this.setTimeout(this.testRequestAnimationFrame, 50); + }, + + testRequestAnimationFrame() { + this.requestAnimationFrame(this.testSetInterval0); + }, + + testSetInterval0() { + this._nextTest = this.testSetInterval20; + this._interval = this.setInterval(this._incrementInterval, 0); + }, + + testSetInterval20() { + this._nextTest = this.testSetImmediate; + this._interval = this.setInterval(this._incrementInterval, 20); + }, + + testSetImmediate() { + this.setImmediate(this.testClearTimeout0); + }, + + testClearTimeout0() { + var timeout = this.setTimeout(() => this._fail('testClearTimeout0'), 0); + this.clearTimeout(timeout); + this.testClearTimeout30(); + }, + + testClearTimeout30() { + var timeout = this.setTimeout(() => this._fail('testClearTimeout30'), 30); + this.clearTimeout(timeout); + this.setTimeout(this.testClearMulti, 50); + }, + + testClearMulti() { + var fails = [this.setTimeout(() => this._fail('testClearMulti-1'), 20)]; + fails.push(this.setTimeout(() => this._fail('testClearMulti-2'), 50)); + var delayClear = this.setTimeout(() => this._fail('testClearMulti-3'), 50); + fails.push(this.setTimeout(() => this._fail('testClearMulti-4'), 0)); + + this.setTimeout(this.testOrdering, 100); // Next test interleaved + + fails.push(this.setTimeout(() => this._fail('testClearMulti-5'), 10)); + + fails.forEach((timeout) => this.clearTimeout(timeout)); + this.setTimeout(() => this.clearTimeout(delayClear), 20); + }, + + testOrdering() { + // Clear timers are set first because it's more likely to uncover bugs. + var fail0; + this.setImmediate(() => this.clearTimeout(fail0)); + fail0 = this.setTimeout( + () => this._fail('testOrdering-t0, setImmediate should happen before ' + + 'setTimeout 0'), + 0 + ); + var failAnim; // This should fail without the t=0 fastpath feature. + this.setTimeout(() => this.cancelAnimationFrame(failAnim), 0); + failAnim = this.requestAnimationFrame( + () => this._fail('testOrdering-Anim, setTimeout 0 should happen before ' + + 'requestAnimationFrame') + ); + var fail50; + this.setTimeout(() => this.clearTimeout(fail50), 20); + fail50 = this.setTimeout( + () => this._fail('testOrdering-t50, setTimeout 20 should happen before ' + + 'setTimeout 50'), + 50 + ); + this.setTimeout(this.done, 75); + }, + + done() { + this.setState({done: true}, RCTTestModule.markTestCompleted); + }, + + render() { + return ( + + + {this.constructor.displayName + ': \n'} + Intervals: {this.state.count + '\n'} + {this.state.done ? 'Done' : 'Testing...'} + + + ); + }, + + _incrementInterval() { + if (this.state.count > 3) { + throw new Error('interval incremented past end.'); + } + if (this.state.count === 3) { + this.clearInterval(this._interval); + this.setState({count: 0}, this._nextTest); + return; + } + this.setState({count: this.state.count + 1}); + }, + + _fail(caller) { + throw new Error('_fail called by ' + caller); + }, +}); + +var styles = StyleSheet.create({ + container: { + backgroundColor: 'white', + padding: 40, + }, +}); + +module.exports = TimersTest; diff --git a/Libraries/ActionSheetIOS/ActionSheetIOS.js b/Libraries/ActionSheetIOS/ActionSheetIOS.js index 5a24f06b045a44..adbb8e3abcab18 100644 --- a/Libraries/ActionSheetIOS/ActionSheetIOS.js +++ b/Libraries/ActionSheetIOS/ActionSheetIOS.js @@ -5,7 +5,7 @@ */ 'use strict'; -var { RCTActionSheetManager } = require('NativeModules'); +var RCTActionSheetManager = require('NativeModules').ActionSheetManager; var invariant = require('invariant'); diff --git a/Libraries/AdSupport/AdSupportIOS.js b/Libraries/AdSupport/AdSupportIOS.js index c0a081aa4d8c54..a470f05cd53d42 100644 --- a/Libraries/AdSupport/AdSupportIOS.js +++ b/Libraries/AdSupport/AdSupportIOS.js @@ -5,7 +5,7 @@ */ 'use strict'; -var AdSupport = require('NativeModules').RCTAdSupport; +var AdSupport = require('NativeModules').AdSupport; module.exports = { getAdvertisingId: function(onSuccess, onFailure) { diff --git a/Libraries/Animation/Animation.js b/Libraries/Animation/Animation.js index 30624266d8f3e9..3fbfb757f175b3 100644 --- a/Libraries/Animation/Animation.js +++ b/Libraries/Animation/Animation.js @@ -6,7 +6,7 @@ */ 'use strict'; -var { RCTAnimationManager } = require('NativeModules'); +var RCTAnimationManager = require('NativeModules').AnimationManager; var AnimationUtils = require('AnimationUtils'); type EasingFunction = (t: number) => number; diff --git a/Libraries/Animation/AnimationMixin.js b/Libraries/Animation/AnimationMixin.js index 56f63fb8ef4d9d..c33d630a9a8712 100644 --- a/Libraries/Animation/AnimationMixin.js +++ b/Libraries/Animation/AnimationMixin.js @@ -7,7 +7,7 @@ 'use strict'; var AnimationUtils = require('AnimationUtils'); -var { RCTAnimationManager } = require('NativeModules'); +var RCTAnimationManager = require('NativeModules').AnimationManager; var invariant = require('invariant'); diff --git a/Libraries/Animation/LayoutAnimation.js b/Libraries/Animation/LayoutAnimation.js index a5adc567b4049d..16f737ba3dbee5 100644 --- a/Libraries/Animation/LayoutAnimation.js +++ b/Libraries/Animation/LayoutAnimation.js @@ -6,7 +6,7 @@ 'use strict'; var PropTypes = require('ReactPropTypes'); -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker'); var keyMirror = require('keyMirror'); diff --git a/Libraries/Animation/POPAnimationMixin.js b/Libraries/Animation/POPAnimationMixin.js index a3f4b7defeb6ac..49145ebd4f859c 100644 --- a/Libraries/Animation/POPAnimationMixin.js +++ b/Libraries/Animation/POPAnimationMixin.js @@ -7,10 +7,11 @@ 'use strict'; var POPAnimation = require('POPAnimation'); + if (!POPAnimation) { // POP animation isn't available in the OSS fork - this is a temporary // workaround to enable its availability to be determined at runtime. - module.exports = null; + module.exports = (null : ?{}); } else { var invariant = require('invariant'); @@ -224,12 +225,10 @@ var POPAnimationMixin = { w: frame.width, h: frame.height }; - frame = undefined; - var velocity = velocity || [0, 0]; var posAnim = POPAnimation.createAnimation(type, { property: POPAnimation.Properties.position, toValue: [animFrame.x, animFrame.y], - velocity: velocity, + velocity: velocity || [0, 0], }); var sizeAnim = POPAnimation.createAnimation(type, { property: POPAnimation.Properties.size, diff --git a/Libraries/AppState/AppState.js b/Libraries/AppState/AppState.js index 47834936ad8c71..043cdba55bad7a 100644 --- a/Libraries/AppState/AppState.js +++ b/Libraries/AppState/AppState.js @@ -6,7 +6,7 @@ 'use strict'; var NativeModules = require('NativeModules'); -var RCTAppState = NativeModules.RCTAppState; +var RCTAppState = NativeModules.AppState; var AppState = { diff --git a/Libraries/AppStateIOS/AppStateIOS.ios.js b/Libraries/AppStateIOS/AppStateIOS.ios.js index 1f6bca95b81bbd..9b3e444728aaac 100644 --- a/Libraries/AppStateIOS/AppStateIOS.ios.js +++ b/Libraries/AppStateIOS/AppStateIOS.ios.js @@ -7,7 +7,7 @@ var NativeModules = require('NativeModules'); var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); -var RCTAppState = NativeModules.RCTAppState; +var RCTAppState = NativeModules.AppState; var logError = require('logError'); diff --git a/Libraries/BatchedBridge/BatchedBridgedModules/NativeModules.js b/Libraries/BatchedBridge/BatchedBridgedModules/NativeModules.js index f8029f8b8e2989..be36f8663c219d 100644 --- a/Libraries/BatchedBridge/BatchedBridgedModules/NativeModules.js +++ b/Libraries/BatchedBridge/BatchedBridgedModules/NativeModules.js @@ -7,8 +7,8 @@ var NativeModules = require('BatchedBridge').RemoteModules; -var nativeModulePrefixDuplicator = require('nativeModulePrefixDuplicator'); +var nativeModulePrefixNormalizer = require('nativeModulePrefixNormalizer'); -nativeModulePrefixDuplicator(NativeModules); +nativeModulePrefixNormalizer(NativeModules); module.exports = NativeModules; diff --git a/Libraries/BatchedBridge/BatchedBridgedModules/POPAnimation.js b/Libraries/BatchedBridge/BatchedBridgedModules/POPAnimation.js index 3195e3ee15150e..97158ecfa3bb03 100644 --- a/Libraries/BatchedBridge/BatchedBridgedModules/POPAnimation.js +++ b/Libraries/BatchedBridge/BatchedBridgedModules/POPAnimation.js @@ -5,7 +5,7 @@ */ 'use strict'; -var RCTPOPAnimationManager = require('NativeModules').RCTPOPAnimationManager; +var RCTPOPAnimationManager = require('NativeModules').POPAnimationManager; if (!RCTPOPAnimationManager) { // POP animation isn't available in the OSS fork - this is a temporary // workaround to enable its availability to be determined at runtime. diff --git a/Libraries/BatchedBridge/BatchedBridgedModules/RCTAlertManager.ios.js b/Libraries/BatchedBridge/BatchedBridgedModules/RCTAlertManager.ios.js index 3621795daa871c..e8b3bcd272f5cc 100644 --- a/Libraries/BatchedBridge/BatchedBridgedModules/RCTAlertManager.ios.js +++ b/Libraries/BatchedBridge/BatchedBridgedModules/RCTAlertManager.ios.js @@ -5,6 +5,6 @@ */ 'use strict'; -var { RCTAlertManager } = require('NativeModules'); +var RCTAlertManager = require('NativeModules').AlertManager; module.exports = RCTAlertManager; diff --git a/Libraries/CameraRoll/CameraRoll.js b/Libraries/CameraRoll/CameraRoll.js index d97fa8ce25fbd7..c8499fc97e66d5 100644 --- a/Libraries/CameraRoll/CameraRoll.js +++ b/Libraries/CameraRoll/CameraRoll.js @@ -6,7 +6,7 @@ 'use strict'; var ReactPropTypes = require('ReactPropTypes'); -var RCTCameraRollManager = require('NativeModules').RCTCameraRollManager; +var RCTCameraRollManager = require('NativeModules').CameraRollManager; var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker'); var deepFreezeAndThrowOnMutationInDev = diff --git a/Libraries/Components/ActivityIndicatorIOS/ActivityIndicatorIOS.ios.js b/Libraries/Components/ActivityIndicatorIOS/ActivityIndicatorIOS.ios.js index c494e031c564b8..8c09ac55177385 100644 --- a/Libraries/Components/ActivityIndicatorIOS/ActivityIndicatorIOS.ios.js +++ b/Libraries/Components/ActivityIndicatorIOS/ActivityIndicatorIOS.ios.js @@ -37,8 +37,11 @@ var ActivityIndicatorIOS = React.createClass({ */ color: PropTypes.string, + /** + * Size of the indicator. Small has a height of 20, large has a height of 36. + */ size: PropTypes.oneOf([ - 'small', // default + 'small', 'large', ]), }, @@ -53,7 +56,7 @@ var ActivityIndicatorIOS = React.createClass({ render: function() { var style = styles.sizeSmall; - var NativeConstants = NativeModules.RCTUIManager.UIActivityIndicatorView.Constants; + var NativeConstants = NativeModules.UIManager.UIActivityIndicatorView.Constants; var activityIndicatorViewStyle = NativeConstants.StyleWhite; if (this.props.size === 'large') { style = styles.sizeLarge; diff --git a/Libraries/Components/DatePicker/DatePickerIOS.ios.js b/Libraries/Components/DatePicker/DatePickerIOS.ios.js index c45672d65dedb8..a010870b1b55cc 100644 --- a/Libraries/Components/DatePicker/DatePickerIOS.ios.js +++ b/Libraries/Components/DatePicker/DatePickerIOS.ios.js @@ -11,7 +11,7 @@ var NativeMethodsMixin = require('NativeMethodsMixin'); var PropTypes = require('ReactPropTypes'); var React = require('React'); var ReactIOSViewAttributes = require('ReactIOSViewAttributes'); -var RCTDatePickerIOSConsts = require('NativeModules').RCTUIManager.RCTDatePicker.Constants; +var RCTDatePickerIOSConsts = require('NativeModules').UIManager.RCTDatePicker.Constants; var StyleSheet = require('StyleSheet'); var View = require('View'); @@ -62,10 +62,8 @@ var DatePickerIOS = React.createClass({ /** * The date picker mode. - * - * Valid modes on iOS are: 'date', 'time', 'datetime'. */ - mode: PropTypes.oneOf(Object.keys(RCTDatePickerIOSConsts.DatePickerModes)), + mode: PropTypes.oneOf(['date', 'time', 'datetime']), /** * The interval at which minutes can be selected. @@ -73,7 +71,7 @@ var DatePickerIOS = React.createClass({ minuteInterval: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30]), /** - * Timezone offset in seconds. + * Timezone offset in minutes. * * By default, the date picker will use the device's timezone. With this * parameter, it is possible to force a certain timezone offset. For diff --git a/Libraries/Components/ListView/ListView.js b/Libraries/Components/ListView/ListView.js index c6e0f5113ccec2..e0c067a18ba401 100644 --- a/Libraries/Components/ListView/ListView.js +++ b/Libraries/Components/ListView/ListView.js @@ -7,7 +7,7 @@ var ListViewDataSource = require('ListViewDataSource'); var React = require('React'); -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; var ScrollView = require('ScrollView'); var ScrollResponder = require('ScrollResponder'); var StaticRenderer = require('StaticRenderer'); diff --git a/Libraries/Components/ListView/ListViewDataSource.js b/Libraries/Components/ListView/ListViewDataSource.js index 3be10944321940..b1916bc64498df 100644 --- a/Libraries/Components/ListView/ListViewDataSource.js +++ b/Libraries/Components/ListView/ListViewDataSource.js @@ -215,9 +215,10 @@ class ListViewDataSource { /** * @param {number} index * - * Gets the rowID at index provided if the dataSource arrays were flattened + * Gets the rowID at index provided if the dataSource arrays were flattened, + * or null of out of range indexes. */ - getRowIDForFlatIndex(index: number): string { + getRowIDForFlatIndex(index: number): ?string { var accessIndex = index; for (var ii = 0; ii < this.sectionIdentities.length; ii++) { if (accessIndex >= this.rowIdentities[ii].length) { @@ -226,14 +227,16 @@ class ListViewDataSource { return this.rowIdentities[ii][accessIndex]; } } + return null; } /** * @param {number} index * - * Gets the sectionID at index provided if the dataSource arrays were flattened + * Gets the sectionID at index provided if the dataSource arrays were flattened, + * or null for out of range indexes. */ - getSectionIDForFlatIndex(index: number): string { + getSectionIDForFlatIndex(index: number): ?string { var accessIndex = index; for (var ii = 0; ii < this.sectionIdentities.length; ii++) { if (accessIndex >= this.rowIdentities[ii].length) { @@ -242,6 +245,7 @@ class ListViewDataSource { return this.sectionIdentities[ii]; } } + return null; } /** diff --git a/Libraries/Components/Navigation/NavigatorIOS.ios.js b/Libraries/Components/Navigation/NavigatorIOS.ios.js index c09ce242ae1866..30082cf21acb92 100644 --- a/Libraries/Components/Navigation/NavigatorIOS.ios.js +++ b/Libraries/Components/Navigation/NavigatorIOS.ios.js @@ -8,7 +8,7 @@ var EventEmitter = require('EventEmitter'); var React = require('React'); var ReactIOSViewAttributes = require('ReactIOSViewAttributes'); -var { RCTNavigatorManager } = require('NativeModules'); +var RCTNavigatorManager = require('NativeModules').NavigatorManager; var StyleSheet = require('StyleSheet'); var StaticContainer = require('StaticContainer.react'); var View = require('View'); diff --git a/Libraries/Components/ScrollResponder.js b/Libraries/Components/ScrollResponder.js index b8f4c96c692ed6..b6e55e0789712b 100644 --- a/Libraries/Components/ScrollResponder.js +++ b/Libraries/Components/ScrollResponder.js @@ -11,8 +11,8 @@ var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); var Subscribable = require('Subscribable'); var TextInputState = require('TextInputState'); -var RCTUIManager = NativeModules.RCTUIManager; -var RCTUIManagerDeprecated = NativeModules.RCTUIManager; +var RCTUIManager = NativeModules.UIManager; +var RCTUIManagerDeprecated = NativeModules.UIManager; var RCTScrollViewConsts = RCTUIManager.RCTScrollView.Constants; var warning = require('warning'); diff --git a/Libraries/Components/ScrollView/ScrollView.js b/Libraries/Components/ScrollView/ScrollView.js index 804b6f57826817..a069988cec99a5 100644 --- a/Libraries/Components/ScrollView/ScrollView.js +++ b/Libraries/Components/ScrollView/ScrollView.js @@ -8,12 +8,12 @@ var EdgeInsetsPropType = require('EdgeInsetsPropType'); var Platform = require('Platform'); var PointPropType = require('PointPropType'); -var RCTScrollView = require('NativeModules').RCTUIManager.RCTScrollView; +var RCTScrollView = require('NativeModules').UIManager.RCTScrollView; var RCTScrollViewConsts = RCTScrollView.Constants; var React = require('React'); var ReactIOSTagHandles = require('ReactIOSTagHandles'); var ReactIOSViewAttributes = require('ReactIOSViewAttributes'); -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; var ScrollResponder = require('ScrollResponder'); var StyleSheet = require('StyleSheet'); var StyleSheetPropType = require('StyleSheetPropType'); diff --git a/Libraries/Components/Slider/Slider.js b/Libraries/Components/SliderIOS/SliderIOS.js similarity index 95% rename from Libraries/Components/Slider/Slider.js rename to Libraries/Components/SliderIOS/SliderIOS.js index a0be43066b1b13..2e5f14bc1ce48d 100644 --- a/Libraries/Components/Slider/Slider.js +++ b/Libraries/Components/SliderIOS/SliderIOS.js @@ -1,7 +1,7 @@ /** * Copyright 2004-present Facebook. All Rights Reserved. * - * @providesModule Slider + * @providesModule SliderIOS */ 'use strict'; @@ -16,7 +16,7 @@ var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass'); var merge = require('merge'); -var Slider = React.createClass({ +var SliderIOS = React.createClass({ mixins: [NativeMethodsMixin], propTypes: { @@ -80,4 +80,4 @@ var RCTSlider = createReactIOSNativeComponentClass({ uiViewClassName: 'RCTSlider', }); -module.exports = Slider; +module.exports = SliderIOS; diff --git a/Libraries/Components/StatusBar/StatusBarIOS.ios.js b/Libraries/Components/StatusBar/StatusBarIOS.ios.js index 50097f3dda79fd..55cb1608c9a0e3 100644 --- a/Libraries/Components/StatusBar/StatusBarIOS.ios.js +++ b/Libraries/Components/StatusBar/StatusBarIOS.ios.js @@ -6,7 +6,7 @@ */ 'use strict'; -var { RCTStatusBarManager } = require('NativeModules'); +var RCTStatusBarManager = require('NativeModules').StatusBarManager; var StatusBarIOS = { diff --git a/Libraries/Components/TextInput/TextInput.ios.js b/Libraries/Components/TextInput/TextInput.ios.js index 21ad49f53b8709..2f2b24dd6b7344 100644 --- a/Libraries/Components/TextInput/TextInput.ios.js +++ b/Libraries/Components/TextInput/TextInput.ios.js @@ -8,7 +8,7 @@ var DocumentSelectionState = require('DocumentSelectionState'); var EventEmitter = require('EventEmitter'); var NativeMethodsMixin = require('NativeMethodsMixin'); -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; var PropTypes = require('ReactPropTypes'); var React = require('React'); var ReactChildren = require('ReactChildren'); diff --git a/Libraries/Components/TextInput/TextInputState.js b/Libraries/Components/TextInput/TextInputState.js index 6d22e3e772c0b6..2bbe8a3d0e80c0 100644 --- a/Libraries/Components/TextInput/TextInputState.js +++ b/Libraries/Components/TextInput/TextInputState.js @@ -9,7 +9,7 @@ */ 'use strict'; -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; var TextInputState = { /** diff --git a/Libraries/Components/Touchable/TouchableFeedbackPropType.js b/Libraries/Components/Touchable/TouchableFeedbackPropType.js deleted file mode 100644 index 336b091c629fdb..00000000000000 --- a/Libraries/Components/Touchable/TouchableFeedbackPropType.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2004-present Facebook. All Rights Reserved. - * - * @providesModule TouchableFeedbackPropType - * @flow - */ -'use strict'; - -var { PropTypes } = require('React'); - -var TouchableFeedbackPropType = { - /** - * Called when the touch is released, but not if cancelled (e.g. by a scroll - * that steals the responder lock). - */ - onPress: PropTypes.func, - onPressIn: PropTypes.func, - onPressOut: PropTypes.func, - onLongPress: PropTypes.func, -}; - -module.exports = TouchableFeedbackPropType; diff --git a/Libraries/Components/Touchable/TouchableHighlight.js b/Libraries/Components/Touchable/TouchableHighlight.js index e00b847e8de6a9..9bb539cebab86e 100644 --- a/Libraries/Components/Touchable/TouchableHighlight.js +++ b/Libraries/Components/Touchable/TouchableHighlight.js @@ -11,7 +11,7 @@ var ReactIOSViewAttributes = require('ReactIOSViewAttributes'); var StyleSheet = require('StyleSheet'); var TimerMixin = require('TimerMixin'); var Touchable = require('Touchable'); -var TouchableFeedbackPropType = require('TouchableFeedbackPropType'); +var TouchableWithoutFeedback = require('TouchableWithoutFeedback'); var View = require('View'); var cloneWithProps = require('cloneWithProps'); @@ -51,12 +51,7 @@ var DEFAULT_PROPS = { var TouchableHighlight = React.createClass({ propTypes: { - ...TouchableFeedbackPropType, - /** - * Called when the touch is released, but not if cancelled (e.g. by - * a scroll that steals the responder lock). - */ - onPress: React.PropTypes.func.isRequired, + ...TouchableWithoutFeedback.propTypes, /** * Determines what the opacity of the wrapped view should be when touch is * active. @@ -164,7 +159,10 @@ var TouchableHighlight = React.createClass({ this._hideTimeout = null; if (this.refs[UNDERLAY_REF]) { this.refs[CHILD_REF].setNativeProps(INACTIVE_CHILD_PROPS); - this.refs[UNDERLAY_REF].setNativeProps(INACTIVE_UNDERLAY_PROPS); + this.refs[UNDERLAY_REF].setNativeProps({ + ...INACTIVE_UNDERLAY_PROPS, + style: this.state.underlayStyle, + }); } }, diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index 1b2f3898fd349f..549df36a86b6c1 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -9,7 +9,7 @@ var NativeMethodsMixin = require('NativeMethodsMixin'); var POPAnimationMixin = require('POPAnimationMixin'); var React = require('React'); var Touchable = require('Touchable'); -var TouchableFeedbackPropType = require('TouchableFeedbackPropType'); +var TouchableWithoutFeedback = require('TouchableWithoutFeedback'); var cloneWithProps = require('cloneWithProps'); var ensureComponentIsNative = require('ensureComponentIsNative'); @@ -42,7 +42,7 @@ var TouchableOpacity = React.createClass({ mixins: [Touchable.Mixin, NativeMethodsMixin, POPAnimationMixin], propTypes: { - ...TouchableFeedbackPropType, + ...TouchableWithoutFeedback.propTypes, /** * Determines what the opacity of the wrapped view should be when touch is * active. diff --git a/Libraries/Components/Touchable/TouchableWithoutFeedback.js b/Libraries/Components/Touchable/TouchableWithoutFeedback.js index ccc784e6ad5b79..78544dbc644080 100644 --- a/Libraries/Components/Touchable/TouchableWithoutFeedback.js +++ b/Libraries/Components/Touchable/TouchableWithoutFeedback.js @@ -7,7 +7,6 @@ var React = require('React'); var Touchable = require('Touchable'); -var TouchableFeedbackPropType = require('TouchableFeedbackPropType'); var onlyChild = require('onlyChild'); @@ -28,7 +27,16 @@ var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; var TouchableWithoutFeedback = React.createClass({ mixins: [Touchable.Mixin], - propTypes: TouchableFeedbackPropType, + propTypes: { + /** + * 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, + onLongPress: React.PropTypes.func, + }, getInitialState: function() { return this.touchableGetInitialState(); diff --git a/Libraries/Components/WebView/WebView.android.js b/Libraries/Components/WebView/WebView.android.js index d153ebe9262fb2..43e6f2c5a0ccee 100644 --- a/Libraries/Components/WebView/WebView.android.js +++ b/Libraries/Components/WebView/WebView.android.js @@ -16,7 +16,7 @@ var keyMirror = require('keyMirror'); var merge = require('merge'); var PropTypes = React.PropTypes; -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; var RCT_WEBVIEW_REF = 'webview'; diff --git a/Libraries/Components/WebView/WebView.ios.js b/Libraries/Components/WebView/WebView.ios.js index e7d483fc43b4f2..213f887ac7600f 100644 --- a/Libraries/Components/WebView/WebView.ios.js +++ b/Libraries/Components/WebView/WebView.ios.js @@ -17,7 +17,7 @@ var insetsDiffer = require('insetsDiffer'); var merge = require('merge'); var PropTypes = React.PropTypes; -var { RCTWebViewManager } = require('NativeModules'); +var RCTWebViewManager = require('NativeModules').WebViewManager; var RCT_WEBVIEW_REF = 'webview'; diff --git a/Libraries/Geolocation/Geolocation.ios.js b/Libraries/Geolocation/Geolocation.ios.js index 0e80153354f40b..37134dd3141be7 100644 --- a/Libraries/Geolocation/Geolocation.ios.js +++ b/Libraries/Geolocation/Geolocation.ios.js @@ -6,7 +6,7 @@ 'use strict'; var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); -var RCTLocationObserver = require('NativeModules').RCTLocationObserver; +var RCTLocationObserver = require('NativeModules').LocationObserver; var invariant = require('invariant'); var logError = require('logError'); diff --git a/Libraries/Image/Image.ios.js b/Libraries/Image/Image.ios.js index 771a27543e0d4a..315667d2518b55 100644 --- a/Libraries/Image/Image.ios.js +++ b/Libraries/Image/Image.ios.js @@ -114,7 +114,7 @@ var Image = React.createClass({ warning(RawImage === RCTStaticImage, 'tintColor style only supported on static images.'); } - var contentModes = NativeModules.RCTUIManager.UIView.ContentMode; + var contentModes = NativeModules.UIManager.UIView.ContentMode; var resizeMode; if (style.resizeMode === ImageResizeMode.stretch) { resizeMode = contentModes.ScaleToFill; diff --git a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js index 6d4d762bd00f3b..92c9d27edb3ec1 100644 --- a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js +++ b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js @@ -60,7 +60,7 @@ function setupDocumentShim() { var sourceMapPromise; function handleErrorWithRedBox(e) { - var RCTExceptionsManager = require('NativeModules').RCTExceptionsManager; + var RCTExceptionsManager = require('NativeModules').ExceptionsManager; var errorToString = require('errorToString'); var loadSourceMap = require('loadSourceMap'); @@ -115,7 +115,7 @@ function setupTimers() { } function setupAlert() { - var { RCTAlertManager } = require('NativeModules'); + var RCTAlertManager = require('NativeModules').AlertManager; if (!GLOBAL.alert) { GLOBAL.alert = function(text) { var alertOpts = { diff --git a/Libraries/JavaScriptAppEngine/Initialization/loadSourceMap.js b/Libraries/JavaScriptAppEngine/Initialization/loadSourceMap.js index 48fd9d1bfabfe8..0af19b27e9a716 100644 --- a/Libraries/JavaScriptAppEngine/Initialization/loadSourceMap.js +++ b/Libraries/JavaScriptAppEngine/Initialization/loadSourceMap.js @@ -8,7 +8,7 @@ 'use strict'; var Promise = require('Promise'); -var RCTSourceCode = require('NativeModules').RCTSourceCode; +var RCTSourceCode = require('NativeModules').SourceCode; var SourceMapConsumer = require('SourceMap').SourceMapConsumer; var SourceMapURL = require('./source-map-url'); diff --git a/Libraries/JavaScriptAppEngine/System/JSTimers/JSTimers.js b/Libraries/JavaScriptAppEngine/System/JSTimers/JSTimers.js index 1b25e00c1d6d2c..4fa4b858730090 100644 --- a/Libraries/JavaScriptAppEngine/System/JSTimers/JSTimers.js +++ b/Libraries/JavaScriptAppEngine/System/JSTimers/JSTimers.js @@ -7,7 +7,7 @@ // Note that the module JSTimers is split into two in order to solve a cycle // in dependencies. NativeModules > BatchedBridge > MessageQueue > JSTimersExecution -var RCTTiming = require('NativeModules').RCTTiming; +var RCTTiming = require('NativeModules').Timing; var JSTimersExecution = require('JSTimersExecution'); /** @@ -90,7 +90,7 @@ var JSTimers = { JSTimersExecution.timerIDs[freeIndex] = newID; JSTimersExecution.callbacks[freeIndex] = func; JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.requestAnimationFrame; - RCTTiming.createTimer(newID, 0, Date.now(), /** recurring */ false); + RCTTiming.createTimer(newID, 1, Date.now(), /** recurring */ false); return newID; }, diff --git a/Libraries/Network/NetInfo.js b/Libraries/Network/NetInfo.js index 671b064a27bf1f..b228547a6cb09b 100644 --- a/Libraries/Network/NetInfo.js +++ b/Libraries/Network/NetInfo.js @@ -8,7 +8,7 @@ var NativeModules = require('NativeModules'); var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); -var RCTReachability = NativeModules.RCTReachability; +var RCTReachability = NativeModules.Reachability; var DEVICE_REACHABILITY_EVENT = 'reachabilityDidChange'; diff --git a/Libraries/Network/XMLHttpRequest.ios.js b/Libraries/Network/XMLHttpRequest.ios.js index b747d0bedde5c1..d1e2e92e816d04 100644 --- a/Libraries/Network/XMLHttpRequest.ios.js +++ b/Libraries/Network/XMLHttpRequest.ios.js @@ -6,7 +6,7 @@ */ 'use strict'; -var RCTDataManager = require('NativeModules').RCTDataManager; +var RCTDataManager = require('NativeModules').DataManager; var crc32 = require('crc32'); diff --git a/Libraries/Picker/PickerIOS.ios.js b/Libraries/Picker/PickerIOS.ios.js index c2d1c2241fde73..69d163cf50076e 100644 --- a/Libraries/Picker/PickerIOS.ios.js +++ b/Libraries/Picker/PickerIOS.ios.js @@ -11,7 +11,7 @@ var NativeMethodsMixin = require('NativeMethodsMixin'); var React = require('React'); var ReactChildren = require('ReactChildren'); var ReactIOSViewAttributes = require('ReactIOSViewAttributes'); -var RCTPickerIOSConsts = require('NativeModules').RCTUIManager.RCTPicker.Constants; +var RCTPickerIOSConsts = require('NativeModules').UIManager.RCTPicker.Constants; var StyleSheet = require('StyleSheet'); var View = require('View'); diff --git a/Libraries/RKBackendNode/queryLayoutByID.js b/Libraries/RKBackendNode/queryLayoutByID.js index a93130e89181ce..0d8893eb677033 100644 --- a/Libraries/RKBackendNode/queryLayoutByID.js +++ b/Libraries/RKBackendNode/queryLayoutByID.js @@ -6,7 +6,7 @@ 'use strict'; var ReactIOSTagHandles = require('ReactIOSTagHandles'); -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; /** * Queries the layout of a view. The layout does not reflect the element as diff --git a/Libraries/ReactIOS/IOSNativeBridgeEventPlugin.js b/Libraries/ReactIOS/IOSNativeBridgeEventPlugin.js index 16446f85d1c84a..fea12db6c5301d 100644 --- a/Libraries/ReactIOS/IOSNativeBridgeEventPlugin.js +++ b/Libraries/ReactIOS/IOSNativeBridgeEventPlugin.js @@ -13,7 +13,7 @@ var SyntheticEvent = require('SyntheticEvent'); var merge = require('merge'); var warning = require('warning'); -var RCTUIManager = NativeModules.RCTUIManager; +var RCTUIManager = NativeModules.UIManager; var customBubblingEventTypes = RCTUIManager.customBubblingEventTypes; var customDirectEventTypes = RCTUIManager.customDirectEventTypes; diff --git a/Libraries/ReactIOS/NativeMethodsMixin.js b/Libraries/ReactIOS/NativeMethodsMixin.js index 767264fae45814..9edc06413f9c59 100644 --- a/Libraries/ReactIOS/NativeMethodsMixin.js +++ b/Libraries/ReactIOS/NativeMethodsMixin.js @@ -7,8 +7,8 @@ var NativeModules = require('NativeModules'); var NativeModules = require('NativeModules'); -var RCTPOPAnimationManager = NativeModules.RCTPOPAnimationManager; -var RCTUIManager = NativeModules.RCTUIManager; +var RCTPOPAnimationManager = NativeModules.POPAnimationManager; +var RCTUIManager = NativeModules.UIManager; var TextInputState = require('TextInputState'); var flattenStyle = require('flattenStyle'); diff --git a/Libraries/ReactIOS/ReactIOSDOMIDOperations.js b/Libraries/ReactIOS/ReactIOSDOMIDOperations.js index 771b581100ee1a..dfb96f8cb808ef 100644 --- a/Libraries/ReactIOS/ReactIOSDOMIDOperations.js +++ b/Libraries/ReactIOS/ReactIOSDOMIDOperations.js @@ -9,7 +9,7 @@ var ReactIOSTagHandles = require('ReactIOSTagHandles'); var ReactMultiChildUpdateTypes = require('ReactMultiChildUpdateTypes'); -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; var ReactPerf = require('ReactPerf'); /** diff --git a/Libraries/ReactIOS/ReactIOSGlobalResponderHandler.js b/Libraries/ReactIOS/ReactIOSGlobalResponderHandler.js index 9c9e64db534164..d22f9848922d37 100644 --- a/Libraries/ReactIOS/ReactIOSGlobalResponderHandler.js +++ b/Libraries/ReactIOS/ReactIOSGlobalResponderHandler.js @@ -3,7 +3,7 @@ */ 'use strict'; -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; var ReactIOSTagHandles = require('ReactIOSTagHandles'); var ReactIOSGlobalResponderHandler = { diff --git a/Libraries/ReactIOS/ReactIOSMount.js b/Libraries/ReactIOS/ReactIOSMount.js index 7226159cc2660a..e26e9934e38114 100644 --- a/Libraries/ReactIOS/ReactIOSMount.js +++ b/Libraries/ReactIOS/ReactIOSMount.js @@ -5,7 +5,7 @@ */ 'use strict'; -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; var ReactIOSTagHandles = require('ReactIOSTagHandles'); var ReactPerf = require('ReactPerf'); diff --git a/Libraries/ReactIOS/ReactIOSNativeComponent.js b/Libraries/ReactIOS/ReactIOSNativeComponent.js index 39c2f294a8dd5f..3bbec560c237d9 100644 --- a/Libraries/ReactIOS/ReactIOSNativeComponent.js +++ b/Libraries/ReactIOS/ReactIOSNativeComponent.js @@ -11,7 +11,7 @@ var ReactIOSEventEmitter = require('ReactIOSEventEmitter'); var ReactIOSStyleAttributes = require('ReactIOSStyleAttributes'); var ReactIOSTagHandles = require('ReactIOSTagHandles'); var ReactMultiChild = require('ReactMultiChild'); -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; var styleDiffer = require('styleDiffer'); var deepFreezeAndThrowOnMutationInDev = require('deepFreezeAndThrowOnMutationInDev'); diff --git a/Libraries/ReactIOS/ReactIOSTextComponent.js b/Libraries/ReactIOS/ReactIOSTextComponent.js index ca8417ddf3d017..ef53b29687f888 100644 --- a/Libraries/ReactIOS/ReactIOSTextComponent.js +++ b/Libraries/ReactIOS/ReactIOSTextComponent.js @@ -7,7 +7,7 @@ 'use strict'; var ReactIOSTagHandles = require('ReactIOSTagHandles'); -var RCTUIManager = require('NativeModules').RCTUIManager; +var RCTUIManager = require('NativeModules').UIManager; var assign = require('Object.assign'); diff --git a/Libraries/Storage/AsyncStorage.ios.js b/Libraries/Storage/AsyncStorage.ios.js index 754e59cb116985..b1a68c40b5fe26 100644 --- a/Libraries/Storage/AsyncStorage.ios.js +++ b/Libraries/Storage/AsyncStorage.ios.js @@ -7,8 +7,8 @@ 'use strict'; var NativeModules = require('NativeModules'); -var RCTAsyncLocalStorage = NativeModules.RCTAsyncLocalStorage; -var RCTAsyncRocksDBStorage = NativeModules.RCTAsyncRocksDBStorage; +var RCTAsyncLocalStorage = NativeModules.AsyncLocalStorage; +var RCTAsyncRocksDBStorage = NativeModules.AsyncRocksDBStorage; // We use RocksDB if available. var RCTAsyncStorage = RCTAsyncRocksDBStorage || RCTAsyncLocalStorage; diff --git a/Libraries/Text/ExpandingText.js b/Libraries/Text/ExpandingText.js deleted file mode 100644 index 181e0a2b8f9456..00000000000000 --- a/Libraries/Text/ExpandingText.js +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Copyright 2004-present Facebook. All Rights Reserved. - * - * @providesModule ExpandingText - */ -'use strict'; - -var React = require('React'); -var StyleSheet = require('StyleSheet'); -var Text = require('Text'); -var TouchableWithoutFeedback = require('TouchableWithoutFeedback'); -var View = require('View'); - -var truncate = require('truncate'); - -var styles = StyleSheet.create({ - boldText: { - fontWeight: 'bold', - }, -}); - -/** - * A react component for displaying text which supports truncating - * based on a set truncLength. - * - * In the following example, the text will truncate - * to show only the first 17 characters plus '...' with a See More button to - * expand the text to its full length. - * - * ``` - * render: function() { - * return ; - * }, - * ``` - */ -var ExpandingText = React.createClass({ - propTypes: { - /** - * Text to be displayed. It will be truncated if the character length - * is greater than the `truncLength` property. - */ - text: React.PropTypes.string, - /** - * The styles that will be applied to the text (both truncated and - * expanded). - */ - textStyle: Text.propTypes.style, - /** - * The styles that will be applied to the See More button. Default - * is bold. - */ - seeMoreStyle: Text.propTypes.style, - /** - * The caption that will be appended at the end, by default it is - * `'See More'`. - */ - seeMoreText: React.PropTypes.string, - /** - * The maximum character length for the text that will - * be displayed by default. Note that ... will be - * appended to the truncated text which is counted towards - * the total truncLength of the default displayed string. - * The default is 130. - */ - truncLength: React.PropTypes.number, - }, - - getDefaultProps: function() { - return { - truncLength: 130, - seeMoreText: 'See More', - seeMoreStyle: styles.boldText, - }; - }, - - getInitialState: function() { - return { - truncated: true, - }; - }, - - onTapSeeMore: function() { - this.setState({ - truncated: !this.state.truncated, - }); - }, - - isTruncated: function() { - return ( - this.props.text.length > this.props.truncLength && - this.state.truncated - ); - }, - - getText: function() { - var text = this.props.text; - if (!this.isTruncated()) { - return text; - } - - return truncate(text, this.props.truncLength) + ' '; - }, - - renderSeeMore: function() { - if (!this.isTruncated()) { - return null; - } - - return ( - - {this.props.seeMoreText} - - ); - }, - - render: function() { - return ( - - - - {this.getText()} - {this.renderSeeMore()} - - - - ); - } -}); - -module.exports = ExpandingText; diff --git a/Libraries/Utilities/AlertIOS.js b/Libraries/Utilities/AlertIOS.js index bbbdc89818b278..8a342004cad0b5 100644 --- a/Libraries/Utilities/AlertIOS.js +++ b/Libraries/Utilities/AlertIOS.js @@ -6,7 +6,7 @@ */ 'use strict'; -var { RCTAlertManager } = require('NativeModules'); +var RCTAlertManager = require('NativeModules').AlertManager; var DEFAULT_BUTTON_TEXT = 'OK'; var DEFAULT_BUTTON = { diff --git a/Libraries/Utilities/Dimensions.js b/Libraries/Utilities/Dimensions.js index d33515799fe4b3..5cbf8cb87bd39b 100644 --- a/Libraries/Utilities/Dimensions.js +++ b/Libraries/Utilities/Dimensions.js @@ -9,7 +9,7 @@ var NativeModules = require('NativeModules'); var invariant = require('invariant'); -var dimensions = NativeModules.RCTUIManager.Dimensions; +var dimensions = NativeModules.UIManager.Dimensions; class Dimensions { /** diff --git a/Libraries/Utilities/PushNotificationIOS.js b/Libraries/Utilities/PushNotificationIOS.js index 86733bde3b489a..cb40e6decc538c 100644 --- a/Libraries/Utilities/PushNotificationIOS.js +++ b/Libraries/Utilities/PushNotificationIOS.js @@ -8,7 +8,7 @@ var NativeModules = require('NativeModules'); var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); -var RCTPushNotificationManager = NativeModules.RCTPushNotificationManager; +var RCTPushNotificationManager = NativeModules.PushNotificationManager; if (RCTPushNotificationManager) { var _initialNotification = RCTPushNotificationManager.initialNotification; } diff --git a/Libraries/Utilities/RCTRenderingPerf.js b/Libraries/Utilities/RCTRenderingPerf.js index cdc44aaa6a46f1..9df484bffcfba0 100644 --- a/Libraries/Utilities/RCTRenderingPerf.js +++ b/Libraries/Utilities/RCTRenderingPerf.js @@ -37,6 +37,19 @@ var RCTRenderingPerf = { ReactDefaultPerf.stop(); ReactDefaultPerf.printInclusive(); ReactDefaultPerf.printWasted(); + + var totalRender = 0; + var totalTime = 0; + var measurements = ReactDefaultPerf.getLastMeasurements(); + for (var ii = 0; ii < measurements.length; ii++) { + var render = measurements[ii].render; + for (var nodeName in render) { + totalRender += render[nodeName]; + } + totalTime += measurements[ii].totalTime; + } + console.log('Total time spent in render(): ' + totalRender + 'ms'); + perfModules.forEach((module) => module.stop()); }, diff --git a/Libraries/Utilities/nativeModulePrefixDuplicator.js b/Libraries/Utilities/nativeModulePrefixDuplicator.js deleted file mode 100644 index fb29516124d44d..00000000000000 --- a/Libraries/Utilities/nativeModulePrefixDuplicator.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2004-present Facebook. All Rights Reserved. - * - * @providesModule nativeModulePrefixDuplicator - */ -'use strict'; - -// Dirty hack to support old (RK) and new (RCT) native module name conventions -function nativeModulePrefixDuplicator(modules) { - Object.keys(modules).forEach((moduleName) => { - var rkModuleName = moduleName.replace(/^RCT/, 'RK'); - var rctModuleName = moduleName.replace(/^RK/, 'RCT'); - if (rkModuleName !== rctModuleName) { - if (modules[rkModuleName] && modules[rctModuleName]) { - throw new Error( - 'Module cannot be registered as both RCT and RK: ' + moduleName - ); - } - modules[rkModuleName] = modules[moduleName]; - modules[rctModuleName] = modules[moduleName]; - } - }); -} - -module.exports = nativeModulePrefixDuplicator; diff --git a/Libraries/Utilities/nativeModulePrefixNormalizer.js b/Libraries/Utilities/nativeModulePrefixNormalizer.js new file mode 100644 index 00000000000000..1c480755361901 --- /dev/null +++ b/Libraries/Utilities/nativeModulePrefixNormalizer.js @@ -0,0 +1,24 @@ +/** + * Copyright 2004-present Facebook. All Rights Reserved. + * + * @providesModule nativeModulePrefixNormalizer + */ +'use strict'; + +// Dirty hack to support old (RK) and new (RCT) native module name conventions +function nativeModulePrefixNormalizer(modules) { + Object.keys(modules).forEach((moduleName) => { + var strippedName = moduleName.replace(/^(RCT|RK)/, ''); + if (modules['RCT' + strippedName] && modules['RK' + strippedName]) { + throw new Error( + 'Module cannot be registered as both RCT and RK: ' + moduleName + ); + } + if (strippedName !== moduleName) { + modules[strippedName] = modules[moduleName]; + delete modules[moduleName]; + } + }); +} + +module.exports = nativeModulePrefixNormalizer; diff --git a/Libraries/Vibration/VibrationIOS.ios.js b/Libraries/Vibration/VibrationIOS.ios.js index 054d6c81eac954..11b09f9890b915 100644 --- a/Libraries/Vibration/VibrationIOS.ios.js +++ b/Libraries/Vibration/VibrationIOS.ios.js @@ -5,7 +5,8 @@ */ 'use strict'; -var {RCTVibration} = require('NativeModules'); +var RCTVibration = require('NativeModules').Vibration; + var invariant = require('invariant'); /** diff --git a/Libraries/react-native/addons.js b/Libraries/react-native/addons.js index fcef285e223909..864d8906d11159 100644 --- a/Libraries/react-native/addons.js +++ b/Libraries/react-native/addons.js @@ -19,6 +19,8 @@ var addons = { batchedUpdates: ReactUpdates.batchedUpdates, cloneWithProps: cloneWithProps, update: update, + Perf: undefined, + TestUtils: undefined, }; if (__DEV__) { diff --git a/Libraries/react-native/react-native-interface.js b/Libraries/react-native/react-native-interface.js index c37bbe68572898..82ceeb77e1c9cb 100644 --- a/Libraries/react-native/react-native-interface.js +++ b/Libraries/react-native/react-native-interface.js @@ -4,7 +4,6 @@ declare module "react-native" { } declare var AppRegistry: ReactClass; - declare var ExpandingText: ReactClass; declare var Image: ReactClass; declare var ListView: ReactClass; declare var NavigatorIOS: ReactClass; diff --git a/Libraries/react-native/react-native.js b/Libraries/react-native/react-native.js index cda4a301422d0b..63690c4fa1b6c1 100644 --- a/Libraries/react-native/react-native.js +++ b/Libraries/react-native/react-native.js @@ -7,40 +7,45 @@ var ReactNative = { ...require('React'), + + // Components ActivityIndicatorIOS: require('ActivityIndicatorIOS'), - AlertIOS: require('AlertIOS'), - Animation: require('Animation'), - AppRegistry: require('AppRegistry'), - AppState: require('AppState'), - AppStateIOS: require('AppStateIOS'), - AsyncStorage: require('AsyncStorage'), - CameraRoll: require('CameraRoll'), DatePickerIOS: require('DatePickerIOS'), - ExpandingText: require('ExpandingText'), Image: require('Image'), - InteractionManager: require('InteractionManager'), - LayoutAnimation: require('LayoutAnimation'), ListView: require('ListView'), ListViewDataSource: require('ListViewDataSource'), MapView: require('MapView'), NavigatorIOS: require('NavigatorIOS'), - NetInfo: require('NetInfo'), PickerIOS: require('PickerIOS'), - PixelRatio: require('PixelRatio'), ScrollView: require('ScrollView'), - Slider: require('Slider'), - StatusBarIOS: require('StatusBarIOS'), - StyleSheet: require('StyleSheet'), + SliderIOS: require('SliderIOS'), SwitchIOS: require('SwitchIOS'), + TabBarIOS: require('TabBarIOS'), Text: require('Text'), TextInput: require('TextInput'), - TimerMixin: require('TimerMixin'), TouchableHighlight: require('TouchableHighlight'), TouchableOpacity: require('TouchableOpacity'), TouchableWithoutFeedback: require('TouchableWithoutFeedback'), - VibrationIOS: require('VibrationIOS'), View: require('View'), WebView: require('WebView'), + + // APIs + AlertIOS: require('AlertIOS'), + Animation: require('Animation'), + AppRegistry: require('AppRegistry'), + AppState: require('AppState'), + AppStateIOS: require('AppStateIOS'), + AsyncStorage: require('AsyncStorage'), + CameraRoll: require('CameraRoll'), + InteractionManager: require('InteractionManager'), + LayoutAnimation: require('LayoutAnimation'), + NetInfo: require('NetInfo'), + PixelRatio: require('PixelRatio'), + StatusBarIOS: require('StatusBarIOS'), + StyleSheet: require('StyleSheet'), + TimerMixin: require('TimerMixin'), + VibrationIOS: require('VibrationIOS'), + invariant: require('invariant'), ix: require('ix'), }; diff --git a/ReactKit/Modules/RCTTiming.m b/ReactKit/Modules/RCTTiming.m index d008178b234152..c1d2ceeb540fa5 100644 --- a/ReactKit/Modules/RCTTiming.m +++ b/ReactKit/Modules/RCTTiming.m @@ -166,6 +166,12 @@ - (void)createTimer:(NSNumber *)callbackID { RCT_EXPORT(); + if (jsDuration == 0 && repeats == NO) { + // For super fast, one-off timers, just enqueue them immediately rather than waiting a frame. + [_bridge enqueueJSCall:@"RCTJSTimers.callTimers" args:@[@[callbackID]]]; + return; + } + NSTimeInterval interval = jsDuration / 1000; NSTimeInterval jsCreationTimeSinceUnixEpoch = jsSchedulingTime / 1000; NSTimeInterval currentTimeSinceUnixEpoch = [[NSDate date] timeIntervalSince1970]; diff --git a/packager/react-packager/src/DependencyResolver/haste/polyfills/console.js b/packager/react-packager/src/DependencyResolver/haste/polyfills/console.js index bb83822d57887f..1b2604e3aba707 100644 --- a/packager/react-packager/src/DependencyResolver/haste/polyfills/console.js +++ b/packager/react-packager/src/DependencyResolver/haste/polyfills/console.js @@ -25,6 +25,13 @@ 'use strict'; var OBJECT_COLUMN_NAME = '(index)'; + var LOG_LEVELS = { + trace: 0, + log: 1, + info: 2, + warn: 3, + error: 4 + }; function setupConsole(global) { @@ -32,29 +39,31 @@ return; } - function doNativeLog() { - var str = Array.prototype.map.call(arguments, function(arg) { - if (arg == null) { - return arg === null ? 'null' : 'undefined'; - } else if (typeof arg === 'string') { - return '"' + arg + '"'; - } else { - // Perform a try catch, just in case the object has a circular - // reference or stringify throws for some other reason. - try { - return JSON.stringify(arg); - } catch (e) { - if (typeof arg.toString === 'function') { - try { - return arg.toString(); - } catch (E) { - return 'unknown'; + function getNativeLogFunction(level) { + return function() { + var str = Array.prototype.map.call(arguments, function(arg) { + if (arg == null) { + return arg === null ? 'null' : 'undefined'; + } else if (typeof arg === 'string') { + return '"' + arg + '"'; + } else { + // Perform a try catch, just in case the object has a circular + // reference or stringify throws for some other reason. + try { + return JSON.stringify(arg); + } catch (e) { + if (typeof arg.toString === 'function') { + try { + return arg.toString(); + } catch (E) { + return 'unknown'; + } } } } - } - }).join(', '); - global.nativeLoggingHook(str); + }).join(', '); + global.nativeLoggingHook(str, level); + }; } var repeat = function(element, n) { @@ -75,7 +84,7 @@ } } if (rows.length === 0) { - global.nativeLoggingHook(''); + global.nativeLoggingHook('', LOG_LEVELS.log); return; } @@ -121,14 +130,15 @@ // Native logging hook adds "RCTLog >" at the front of every // logged string, which would shift the header and screw up // the table - global.nativeLoggingHook('\n' + table.join('\n')); + global.nativeLoggingHook('\n' + table.join('\n'), LOG_LEVELS.log); } global.console = { - error: doNativeLog, - info: doNativeLog, - log: doNativeLog, - warn: doNativeLog, + error: getNativeLogFunction(LOG_LEVELS.error), + info: getNativeLogFunction(LOG_LEVELS.info), + log: getNativeLogFunction(LOG_LEVELS.log), + warn: getNativeLogFunction(LOG_LEVELS.warn), + trace: getNativeLogFunction(LOG_LEVELS.trace), table: consoleTablePolyfill };