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
This commit is contained in:
Christopher Chedeau 2015-03-18 15:57:49 -07:00
parent 55598f913c
commit 06a87bec25
75 changed files with 795 additions and 373 deletions

View File

@ -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]

View File

@ -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() {

View File

@ -6,7 +6,6 @@
var React = require('react-native');
var {
ExpandingText,
Image,
PixelRatio,
ScrollView,
@ -40,10 +39,9 @@ var MovieScreen = React.createClass({
</View>
</View>
<View style={styles.separator} />
<ExpandingText
truncLength={200}
text={this.props.movie.synopsis}
/>
<Text>
{this.props.movie.synopsis}
</Text>
<View style={styles.separator} />
<Cast actors={this.props.movie.abridged_cast} />
</ScrollView>

View File

@ -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} />
<Text>{(this.state.bigImages ? 'Big' : 'Small') + ' Images'}</Text>
<Slider
<SliderIOS
value={this.state.sliderValue}
onValueChange={this._onSliderChange}
/>

View File

@ -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 = '<ExpandingText>';
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 <ExpandingText truncLength={20} text={LOREM} />;
}
}, {
title: 'Expanding text (truncLength=80)',
description: 'The higher the truncLength the more characters that will be shown by default',
render: function() {
return <ExpandingText truncLength={80} text={LOREM + LOREM} />;
}
}, {
title: 'Expanding text with custom style',
description: 'You can style the text within the ExpandingText component',
render: function() {
return (
<ExpandingText
textStyle={{fontFamily: 'Verdana'}}
truncLength={80}
text={LOREM + LOREM}
/>
);
}
}, {
title: 'See More button with custom style' ,
description: 'You can also style just the See More button',
render: function() {
return (
<ExpandingText
seeMoreStyle={{color: 'red'}}
truncLength={80}
text={LOREM}
/>
);
}
}];

View File

@ -99,11 +99,11 @@ var ListViewPagingExample = React.createClass({
};
},
renderRow: function(rowData, sectionID, rowID) {
renderRow: function(rowData: string, sectionID: string, rowID: string): ReactElement {
return (<Thumb text={rowData}/>);
},
renderSectionHeader: function(sectionData, sectionID) {
renderSectionHeader: function(sectionData: string, sectionID: string) {
return (
<View style={styles.section}>
<Text style={styles.text}>

View File

@ -5,7 +5,7 @@
var React = require('react-native');
var {
Slider,
SliderIOS,
Text,
StyleSheet,
View,
@ -24,7 +24,7 @@ var SliderExample = React.createClass({
<Text style={styles.text} >
{this.state.value}
</Text>
<Slider
<SliderIOS
style={styles.slider}
onValueChange={(value) => this.setState({value: value})} />
</View>
@ -45,11 +45,11 @@ var styles = StyleSheet.create({
},
});
exports.title = '<Slider>';
exports.title = '<SliderIOS>';
exports.description = 'Slider input for numeric values';
exports.examples = [
{
title: 'Slider',
title: 'SliderIOS',
render() { return <SliderExample />; }
}
];

View File

@ -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 (
<TouchableHighlight
onPress={this.props.onPress}
style={styles.button}
underlayColor="#eeeeee">
<Text>
{this.props.children}
</Text>
</TouchableHighlight>
);
},
});
var TimerTester = React.createClass({
mixins: [TimerMixin],
render: function() {
var args = 'fn' + (this.props.dt !== undefined ? ', ' + this.props.dt : '');
return (
<Button onPress={this._run}>
Measure: {this.props.type}({args}) - {this._ii || 0}
</Button>
);
},
_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 (
<View>
<TimerTester type="setTimeout" dt={0} />
<TimerTester type="setTimeout" dt={1} />
<TimerTester type="setTimeout" dt={100} />
</View>
);
},
},
{
title: 'this.requestAnimationFrame(fn)',
description: 'Execute function fn on the next frame.',
render: function() {
return (
<View>
<TimerTester type="requestAnimationFrame" />
</View>
);
},
},
{
title: 'this.setImmediate(fn)',
description: 'Execute function fn at the end of the current JS event loop.',
render: function() {
return (
<View>
<TimerTester type="setImmediate" />
</View>
);
},
},
{
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 =
<TimerTester ref="interval" dt={25} type="setInterval" />;
var toggleText = 'Unmount timer';
} else {
var timer = null;
var toggleText = 'Mount new timer';
}
return (
<View>
{timer}
<Button onPress={() => this.refs.interval.clear() }>
Clear interval
</Button>
<Button onPress={this._toggleTimer}>
{toggleText}
</Button>
</View>
);
},
_toggleTimer: function() {
this.setState({showTimer: !this.state.showTimer});
},
});
return <IntervalExample />;
},
},
];

View File

@ -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 = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = "<group>"; };
+ D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = "<group>"; };
/* 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 */

View File

@ -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'),

View File

@ -3,6 +3,8 @@
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#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 '<View>' text in %d seconds", TIMEOUT_SECONDS);
}

View File

@ -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 (
<View style={{backgroundColor: 'white', padding: 40}}>
<Text>
{this.constructor.displayName + ': '}
{this.state.done ? 'Done' : 'Testing...'}
{'\n\n' + this.state.messages}
</Text>
</View>
);
}
});
module.exports = AsyncStorageTest;

View File

@ -3,7 +3,7 @@
*/
'use strict';
var RCTTestModule = require('NativeModules').RCTTestModule;
var RCTTestModule = require('NativeModules').TestModule;
var React = require('react-native');
var {
Text,

View File

@ -18,6 +18,8 @@ var {
var TESTS = [
require('./IntegrationTestHarnessTest'),
require('./TimersTest'),
require('./AsyncStorageTest'),
];
TESTS.forEach(

View File

@ -37,4 +37,14 @@
expectErrorRegex:[NSRegularExpression regularExpressionWithPattern:@"because shouldThrow" options:0 error:nil]];
}
- (void)testTimers
{
[_runner runTest:@"TimersTest"];
}
- (void)testAsyncStorage
{
[_runner runTest:@"AsyncStorageTest"];
}
@end

View File

@ -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 (
<View style={styles.container}>
<Text>
{this.constructor.displayName + ': \n'}
Intervals: {this.state.count + '\n'}
{this.state.done ? 'Done' : 'Testing...'}
</Text>
</View>
);
},
_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;

View File

@ -5,7 +5,7 @@
*/
'use strict';
var { RCTActionSheetManager } = require('NativeModules');
var RCTActionSheetManager = require('NativeModules').ActionSheetManager;
var invariant = require('invariant');

View File

@ -5,7 +5,7 @@
*/
'use strict';
var AdSupport = require('NativeModules').RCTAdSupport;
var AdSupport = require('NativeModules').AdSupport;
module.exports = {
getAdvertisingId: function(onSuccess, onFailure) {

View File

@ -6,7 +6,7 @@
*/
'use strict';
var { RCTAnimationManager } = require('NativeModules');
var RCTAnimationManager = require('NativeModules').AnimationManager;
var AnimationUtils = require('AnimationUtils');
type EasingFunction = (t: number) => number;

View File

@ -7,7 +7,7 @@
'use strict';
var AnimationUtils = require('AnimationUtils');
var { RCTAnimationManager } = require('NativeModules');
var RCTAnimationManager = require('NativeModules').AnimationManager;
var invariant = require('invariant');

View File

@ -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');

View File

@ -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,

View File

@ -6,7 +6,7 @@
'use strict';
var NativeModules = require('NativeModules');
var RCTAppState = NativeModules.RCTAppState;
var RCTAppState = NativeModules.AppState;
var AppState = {

View File

@ -7,7 +7,7 @@
var NativeModules = require('NativeModules');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var RCTAppState = NativeModules.RCTAppState;
var RCTAppState = NativeModules.AppState;
var logError = require('logError');

View File

@ -7,8 +7,8 @@
var NativeModules = require('BatchedBridge').RemoteModules;
var nativeModulePrefixDuplicator = require('nativeModulePrefixDuplicator');
var nativeModulePrefixNormalizer = require('nativeModulePrefixNormalizer');
nativeModulePrefixDuplicator(NativeModules);
nativeModulePrefixNormalizer(NativeModules);
module.exports = NativeModules;

View File

@ -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.

View File

@ -5,6 +5,6 @@
*/
'use strict';
var { RCTAlertManager } = require('NativeModules');
var RCTAlertManager = require('NativeModules').AlertManager;
module.exports = RCTAlertManager;

View File

@ -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 =

View File

@ -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;

View File

@ -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

View File

@ -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');

View File

@ -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;
}
/**

View File

@ -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');

View File

@ -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');

View File

@ -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');

View File

@ -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;

View File

@ -6,7 +6,7 @@
*/
'use strict';
var { RCTStatusBarManager } = require('NativeModules');
var RCTStatusBarManager = require('NativeModules').StatusBarManager;
var StatusBarIOS = {

View File

@ -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');

View File

@ -9,7 +9,7 @@
*/
'use strict';
var RCTUIManager = require('NativeModules').RCTUIManager;
var RCTUIManager = require('NativeModules').UIManager;
var TextInputState = {
/**

View File

@ -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;

View File

@ -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,
});
}
},

View File

@ -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.

View File

@ -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();

View File

@ -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';

View File

@ -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';

View File

@ -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');

View File

@ -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;

View File

@ -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 = {

View File

@ -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');

View File

@ -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;
},

View File

@ -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';

View File

@ -6,7 +6,7 @@
*/
'use strict';
var RCTDataManager = require('NativeModules').RCTDataManager;
var RCTDataManager = require('NativeModules').DataManager;
var crc32 = require('crc32');

View File

@ -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');

View File

@ -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

View File

@ -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;

View File

@ -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');

View File

@ -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');
/**

View File

@ -3,7 +3,7 @@
*/
'use strict';
var RCTUIManager = require('NativeModules').RCTUIManager;
var RCTUIManager = require('NativeModules').UIManager;
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var ReactIOSGlobalResponderHandler = {

View File

@ -5,7 +5,7 @@
*/
'use strict';
var RCTUIManager = require('NativeModules').RCTUIManager;
var RCTUIManager = require('NativeModules').UIManager;
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var ReactPerf = require('ReactPerf');

View File

@ -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');

View File

@ -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');

View File

@ -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;

View File

@ -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 <ExpandingText truncLength={20} text={EXAMPLE_TEXT} />;
* },
* ```
*/
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 (
<Text style={this.props.seeMoreStyle}>
{this.props.seeMoreText}
</Text>
);
},
render: function() {
return (
<TouchableWithoutFeedback onPress={this.onTapSeeMore}>
<View>
<Text style={this.props.textStyle}>
{this.getText()}
{this.renderSeeMore()}
</Text>
</View>
</TouchableWithoutFeedback>
);
}
});
module.exports = ExpandingText;

View File

@ -6,7 +6,7 @@
*/
'use strict';
var { RCTAlertManager } = require('NativeModules');
var RCTAlertManager = require('NativeModules').AlertManager;
var DEFAULT_BUTTON_TEXT = 'OK';
var DEFAULT_BUTTON = {

View File

@ -9,7 +9,7 @@ var NativeModules = require('NativeModules');
var invariant = require('invariant');
var dimensions = NativeModules.RCTUIManager.Dimensions;
var dimensions = NativeModules.UIManager.Dimensions;
class Dimensions {
/**

View File

@ -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;
}

View File

@ -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());
},

View File

@ -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;

View File

@ -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;

View File

@ -5,7 +5,8 @@
*/
'use strict';
var {RCTVibration} = require('NativeModules');
var RCTVibration = require('NativeModules').Vibration;
var invariant = require('invariant');
/**

View File

@ -19,6 +19,8 @@ var addons = {
batchedUpdates: ReactUpdates.batchedUpdates,
cloneWithProps: cloneWithProps,
update: update,
Perf: undefined,
TestUtils: undefined,
};
if (__DEV__) {

View File

@ -4,7 +4,6 @@ declare module "react-native" {
}
declare var AppRegistry: ReactClass<any, any, any>;
declare var ExpandingText: ReactClass<any, any, any>;
declare var Image: ReactClass<any, any, any>;
declare var ListView: ReactClass<any, any, any>;
declare var NavigatorIOS: ReactClass<any, any, any>;

View File

@ -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'),
};

View File

@ -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];

View File

@ -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
};