diff --git a/.flowconfig b/.flowconfig
index 20bb68756..82d818dcc 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 e6b7fa6d4..f4ad51b41 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 53c8879dc..8584d8753 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 31634d583..7be014a33 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 2a2f61fc8..000000000
--- 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 c74795eb5..0eec2700c 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 d1ff73779..bc58ccec7 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 000000000..6d48738d4
--- /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 000000000..fa002c8b0
--- /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 bc46292fd..08558971f 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 237270f67..854ee445a 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 @@
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 @@
}];
}
+ 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 000000000..82fb348b2
--- /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 5b6e78838..5ae78cf9c 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 ee60aa388..30464bbcc 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 9d9020f7d..4cb894480 100644
--- a/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m
+++ b/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m
@@ -37,4 +37,14 @@
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 000000000..db376304b
--- /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 5a24f06b0..adbb8e3ab 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 c0a081aa4..a470f05cd 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 30624266d..3fbfb757f 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 56f63fb8e..c33d630a9 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 a5adc567b..16f737ba3 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 a3f4b7def..49145ebd4 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 47834936a..043cdba55 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 1f6bca95b..9b3e44472 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 f8029f8b8..be36f8663 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 3195e3ee1..97158ecfa 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 3621795da..e8b3bcd27 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 d97fa8ce2..c8499fc97 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 c494e031c..8c09ac551 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 c45672d65..a010870b1 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 c6e0f5113..e0c067a18 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 3be109443..b1916bc64 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 c09ce242a..30082cf21 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 b8f4c96c6..b6e55e078 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 804b6f578..a069988ce 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 a0be43066..2e5f14bc1 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 50097f3dd..55cb1608c 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 21ad49f53..2f2b24dd6 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 6d22e3e77..2bbe8a3d0 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 336b091c6..000000000
--- 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 e00b847e8..9bb539ceb 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 1b2f3898f..549df36a8 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 ccc784e6a..78544dbc6 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 d153ebe92..43e6f2c5a 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 e7d483fc4..213f887ac 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 0e8015335..37134dd31 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 771a27543..315667d25 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 6d4d762bd..92c9d27ed 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 48fd9d1bf..0af19b27e 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 1b25e00c1..4fa4b8587 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 671b064a2..b228547a6 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 b747d0bed..d1e2e92e8 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 c2d1c2241..69d163cf5 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 a93130e89..0d8893eb6 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 16446f85d..fea12db6c 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 767264fae..9edc06413 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 771b58110..dfb96f8cb 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 9c9e64db5..d22f98489 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 7226159cc..e26e9934e 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 39c2f294a..3bbec560c 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 ca8417ddf..ef53b2968 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 754e59cb1..b1a68c40b 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 181e0a2b8..000000000
--- 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 bbbdc8981..8a342004c 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 d33515799..5cbf8cb87 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 86733bde3..cb40e6dec 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 cdc44aaa6..9df484bff 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 fb2951612..000000000
--- 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 000000000..1c4807553
--- /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 054d6c81e..11b09f989 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 fcef285e2..864d8906d 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 c37bbe685..82ceeb77e 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 cda4a3014..63690c4fa 100644
--- a/Libraries/react-native/react-native.js
+++ b/Libraries/react-native/react-native.js
@@ -7,7 +7,29 @@
var ReactNative = {
...require('React'),
+
+ // Components
ActivityIndicatorIOS: require('ActivityIndicatorIOS'),
+ DatePickerIOS: require('DatePickerIOS'),
+ Image: require('Image'),
+ ListView: require('ListView'),
+ ListViewDataSource: require('ListViewDataSource'),
+ MapView: require('MapView'),
+ NavigatorIOS: require('NavigatorIOS'),
+ PickerIOS: require('PickerIOS'),
+ ScrollView: require('ScrollView'),
+ SliderIOS: require('SliderIOS'),
+ SwitchIOS: require('SwitchIOS'),
+ TabBarIOS: require('TabBarIOS'),
+ Text: require('Text'),
+ TextInput: require('TextInput'),
+ TouchableHighlight: require('TouchableHighlight'),
+ TouchableOpacity: require('TouchableOpacity'),
+ TouchableWithoutFeedback: require('TouchableWithoutFeedback'),
+ View: require('View'),
+ WebView: require('WebView'),
+
+ // APIs
AlertIOS: require('AlertIOS'),
Animation: require('Animation'),
AppRegistry: require('AppRegistry'),
@@ -15,32 +37,15 @@ var ReactNative = {
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'),
- SwitchIOS: require('SwitchIOS'),
- 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'),
+
invariant: require('invariant'),
ix: require('ix'),
};
diff --git a/ReactKit/Modules/RCTTiming.m b/ReactKit/Modules/RCTTiming.m
index d008178b2..c1d2ceeb5 100644
--- a/ReactKit/Modules/RCTTiming.m
+++ b/ReactKit/Modules/RCTTiming.m
@@ -166,6 +166,12 @@
{
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 bb83822d5..1b2604e3a 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
};