commit
c54c048fc9
|
@ -15,20 +15,20 @@ var {
|
||||||
View,
|
View,
|
||||||
} = React;
|
} = React;
|
||||||
|
|
||||||
var GameBoard = require('./GameBoard');
|
var GameBoard = require('GameBoard');
|
||||||
var TouchableBounce = require('TouchableBounce');
|
var TouchableBounce = require('TouchableBounce');
|
||||||
|
|
||||||
var BOARD_PADDING = 3;
|
var BOARD_PADDING = 3;
|
||||||
var CELL_MARGIN = 4;
|
var CELL_MARGIN = 4;
|
||||||
var CELL_SIZE = 60;
|
var CELL_SIZE = 60;
|
||||||
|
|
||||||
var Cell = React.createClass({
|
class Cell extends React.Component {
|
||||||
render: function() {
|
render() {
|
||||||
return <View style={styles.cell} />;
|
return <View style={styles.cell} />;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
var Board = React.createClass({
|
class Board extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.board}>
|
<View style={styles.board}>
|
||||||
|
@ -40,12 +40,10 @@ var Board = React.createClass({
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
var Tile = React.createClass({
|
class Tile extends React.Component {
|
||||||
mixins: [Animation.Mixin],
|
calculateOffset(): {top: number; left: number; opacity: number} {
|
||||||
|
|
||||||
calculateOffset() {
|
|
||||||
var tile = this.props.tile;
|
var tile = this.props.tile;
|
||||||
|
|
||||||
var pos = (i) => {
|
var pos = (i) => {
|
||||||
|
@ -59,6 +57,7 @@ var Tile = React.createClass({
|
||||||
var offset = {
|
var offset = {
|
||||||
top: pos(tile.toRow()),
|
top: pos(tile.toRow()),
|
||||||
left: pos(tile.toColumn()),
|
left: pos(tile.toColumn()),
|
||||||
|
opacity: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (tile.isNew()) {
|
if (tile.isNew()) {
|
||||||
|
@ -68,18 +67,18 @@ var Tile = React.createClass({
|
||||||
animationPosition(tile.toColumn()),
|
animationPosition(tile.toColumn()),
|
||||||
animationPosition(tile.toRow()),
|
animationPosition(tile.toRow()),
|
||||||
];
|
];
|
||||||
this.startAnimation('this', 100, 0, 'easeInOutQuad', {position: point});
|
Animation.startAnimation(this.refs['this'], 100, 0, 'easeInOutQuad', {position: point});
|
||||||
}
|
}
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
},
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.startAnimation('this', 300, 0, 'easeInOutQuad', {scaleXY: [1, 1]});
|
Animation.startAnimation(this.refs['this'], 300, 0, 'easeInOutQuad', {scaleXY: [1, 1]});
|
||||||
this.startAnimation('this', 100, 0, 'easeInOutQuad', {opacity: 1});
|
Animation.startAnimation(this.refs['this'], 100, 0, 'easeInOutQuad', {opacity: 1});
|
||||||
}, 0);
|
}, 0);
|
||||||
},
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
var tile = this.props.tile;
|
var tile = this.props.tile;
|
||||||
|
@ -103,9 +102,9 @@ var Tile = React.createClass({
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
var GameEndOverlay = React.createClass({
|
class GameEndOverlay extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
var board = this.props.board;
|
var board = this.props.board;
|
||||||
|
|
||||||
|
@ -127,27 +126,30 @@ var GameEndOverlay = React.createClass({
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
var Game2048 = React.createClass({
|
class Game2048 extends React.Component {
|
||||||
getInitialState() {
|
constructor(props) {
|
||||||
return { board: new GameBoard() };
|
super(props);
|
||||||
},
|
this.state = {
|
||||||
|
board: new GameBoard(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
restartGame() {
|
restartGame() {
|
||||||
this.setState(this.getInitialState());
|
this.setState({board: new GameBoard()});
|
||||||
},
|
}
|
||||||
|
|
||||||
handleTouchStart(event) {
|
handleTouchStart(event: Object) {
|
||||||
if (this.state.board.hasWon()) {
|
if (this.state.board.hasWon()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.startX = event.nativeEvent.pageX;
|
this.startX = event.nativeEvent.pageX;
|
||||||
this.startY = event.nativeEvent.pageY;
|
this.startY = event.nativeEvent.pageY;
|
||||||
},
|
}
|
||||||
|
|
||||||
handleTouchEnd(event) {
|
handleTouchEnd(event: Object) {
|
||||||
if (this.state.board.hasWon()) {
|
if (this.state.board.hasWon()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -165,7 +167,7 @@ var Game2048 = React.createClass({
|
||||||
if (direction !== -1) {
|
if (direction !== -1) {
|
||||||
this.setState({board: this.state.board.move(direction)});
|
this.setState({board: this.state.board.move(direction)});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
var tiles = this.state.board.tiles
|
var tiles = this.state.board.tiles
|
||||||
|
@ -175,16 +177,16 @@ var Game2048 = React.createClass({
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={styles.container}
|
style={styles.container}
|
||||||
onTouchStart={this.handleTouchStart}
|
onTouchStart={(event) => this.handleTouchStart(event)}
|
||||||
onTouchEnd={this.handleTouchEnd}>
|
onTouchEnd={(event) => this.handleTouchEnd(event)}>
|
||||||
<Board>
|
<Board>
|
||||||
{tiles}
|
{tiles}
|
||||||
</Board>
|
</Board>
|
||||||
<GameEndOverlay board={this.state.board} onRestart={this.restartGame} />
|
<GameEndOverlay board={this.state.board} onRestart={() => this.restartGame()} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
var styles = StyleSheet.create({
|
var styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
|
|
|
@ -6,6 +6,6 @@
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var React = require('react-native');
|
||||||
|
var {
|
||||||
|
StyleSheet,
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
TouchableHighlight,
|
||||||
|
AlertIOS,
|
||||||
|
} = React;
|
||||||
|
|
||||||
|
exports.framework = 'React';
|
||||||
|
exports.title = 'AlertIOS';
|
||||||
|
exports.description = 'iOS alerts and action sheets';
|
||||||
|
exports.examples = [{
|
||||||
|
title: 'Alerts',
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<TouchableHighlight style={styles.wrapper}
|
||||||
|
onPress={() => AlertIOS.alert(
|
||||||
|
'Foo Title',
|
||||||
|
'My Alert Msg'
|
||||||
|
)}>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Text>Alert with message and default button</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableHighlight>
|
||||||
|
<TouchableHighlight style={styles.wrapper}
|
||||||
|
onPress={() => AlertIOS.alert(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
{text: 'Button', onPress: () => console.log('Button Pressed!')},
|
||||||
|
]
|
||||||
|
)}>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Text>Alert with only one button</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableHighlight>
|
||||||
|
<TouchableHighlight style={styles.wrapper}
|
||||||
|
onPress={() => AlertIOS.alert(
|
||||||
|
'Foo Title',
|
||||||
|
'My Alert Msg',
|
||||||
|
[
|
||||||
|
{text: 'Foo', onPress: () => console.log('Foo Pressed!')},
|
||||||
|
{text: 'Bar', onPress: () => console.log('Bar Pressed!')},
|
||||||
|
]
|
||||||
|
)}>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Text>Alert with two buttons</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableHighlight>
|
||||||
|
<TouchableHighlight style={styles.wrapper}
|
||||||
|
onPress={() => AlertIOS.alert(
|
||||||
|
'Foo Title',
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
{text: 'Foo', onPress: () => console.log('Foo Pressed!')},
|
||||||
|
{text: 'Bar', onPress: () => console.log('Bar Pressed!')},
|
||||||
|
{text: 'Baz', onPress: () => console.log('Baz Pressed!')},
|
||||||
|
]
|
||||||
|
)}>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Text>Alert with 3 buttons</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableHighlight>
|
||||||
|
<TouchableHighlight style={styles.wrapper}
|
||||||
|
onPress={() => AlertIOS.alert(
|
||||||
|
'Foo Title',
|
||||||
|
'My Alert Msg',
|
||||||
|
'..............'.split('').map((dot, index) => ({
|
||||||
|
text: 'Button ' + index,
|
||||||
|
onPress: () => console.log('Pressed ' + index)
|
||||||
|
}))
|
||||||
|
)}>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Text>Alert with too many buttons</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableHighlight>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
|
||||||
|
var styles = StyleSheet.create({
|
||||||
|
wrapper: {
|
||||||
|
borderRadius: 5,
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
backgroundColor: '#eeeeee',
|
||||||
|
padding: 10,
|
||||||
|
},
|
||||||
|
});
|
|
@ -40,7 +40,9 @@ var EXAMPLES = [
|
||||||
require('./AsyncStorageExample'),
|
require('./AsyncStorageExample'),
|
||||||
require('./CameraRollExample.ios'),
|
require('./CameraRollExample.ios'),
|
||||||
require('./MapViewExample'),
|
require('./MapViewExample'),
|
||||||
|
require('./WebViewExample'),
|
||||||
require('./AppStateIOSExample'),
|
require('./AppStateIOSExample'),
|
||||||
|
require('./AlertIOSExample'),
|
||||||
require('./AdSupportIOSExample'),
|
require('./AdSupportIOSExample'),
|
||||||
require('./AppStateExample'),
|
require('./AppStateExample'),
|
||||||
require('./ActionSheetIOSExample'),
|
require('./ActionSheetIOSExample'),
|
||||||
|
|
|
@ -0,0 +1,264 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var React = require('react-native');
|
||||||
|
var StyleSheet = require('StyleSheet');
|
||||||
|
var {
|
||||||
|
ActivityIndicatorIOS,
|
||||||
|
StyleSheet,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
View,
|
||||||
|
WebView
|
||||||
|
} = React;
|
||||||
|
|
||||||
|
var HEADER = '#3b5998';
|
||||||
|
var BGWASH = 'rgba(255,255,255,0.8)';
|
||||||
|
var DISABLED_WASH = 'rgba(255,255,255,0.25)';
|
||||||
|
|
||||||
|
var TEXT_INPUT_REF = 'urlInput';
|
||||||
|
var WEBVIEW_REF = 'webview';
|
||||||
|
var DEFAULT_URL = 'https://m.facebook.com';
|
||||||
|
|
||||||
|
var WebViewExample = React.createClass({
|
||||||
|
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
url: DEFAULT_URL,
|
||||||
|
status: 'No Page Loaded',
|
||||||
|
backButtonEnabled: false,
|
||||||
|
forwardButtonEnabled: false,
|
||||||
|
loading: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTextInputChange: function(event) {
|
||||||
|
this.inputText = event.nativeEvent.text;
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
this.inputText = this.state.url;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[styles.container]}>
|
||||||
|
<View style={[styles.addressBarRow]}>
|
||||||
|
<TouchableOpacity onPress={this.goBack}>
|
||||||
|
<View style={this.state.backButtonEnabled ? styles.navButton : styles.disabledButton}>
|
||||||
|
<Text>
|
||||||
|
{'<'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity onPress={this.goForward}>
|
||||||
|
<View style={this.state.forwardButtonEnabled ? styles.navButton : styles.disabledButton}>
|
||||||
|
<Text>
|
||||||
|
{'>'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TextInput
|
||||||
|
ref={TEXT_INPUT_REF}
|
||||||
|
autoCapitalize="none"
|
||||||
|
value={this.state.url}
|
||||||
|
onSubmitEditing={this.onSubmitEditing}
|
||||||
|
onChange={this.handleTextInputChange}
|
||||||
|
clearButtonMode="while-editing"
|
||||||
|
style={styles.addressBarTextInput}
|
||||||
|
/>
|
||||||
|
<TouchableOpacity onPress={this.pressGoButton}>
|
||||||
|
<View style={styles.goButton}>
|
||||||
|
<Text>
|
||||||
|
Go!
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<WebView
|
||||||
|
ref={WEBVIEW_REF}
|
||||||
|
automaticallyAdjustContentInsets={false}
|
||||||
|
style={styles.webView}
|
||||||
|
url={this.state.url}
|
||||||
|
renderErrorView={this.renderErrorView}
|
||||||
|
renderLoadingView={this.renderLoadingView}
|
||||||
|
onNavigationStateChange={this.onNavigationStateChange}
|
||||||
|
startInLoadingState={true}
|
||||||
|
/>
|
||||||
|
<View style={styles.statusBar}>
|
||||||
|
<Text style={styles.statusBarText}>{this.state.status}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
goBack: function() {
|
||||||
|
this.refs[WEBVIEW_REF].goBack();
|
||||||
|
},
|
||||||
|
|
||||||
|
goForward: function() {
|
||||||
|
this.refs[WEBVIEW_REF].goForward();
|
||||||
|
},
|
||||||
|
|
||||||
|
reload: function() {
|
||||||
|
this.refs[WEBVIEW_REF].reload();
|
||||||
|
},
|
||||||
|
|
||||||
|
onNavigationStateChange: function(navState) {
|
||||||
|
this.setState({
|
||||||
|
backButtonEnabled: navState.canGoBack,
|
||||||
|
forwardButtonEnabled: navState.canGoForward,
|
||||||
|
url: navState.url,
|
||||||
|
status: navState.title,
|
||||||
|
loading: navState.loading,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
renderErrorView: function(errorDomain, errorCode, errorDesc) {
|
||||||
|
return (
|
||||||
|
<View style={styles.errorContainer}>
|
||||||
|
<Text style={styles.errorTextTitle}>
|
||||||
|
Error loading page
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.errorText}>
|
||||||
|
{'Domain: ' + errorDomain}
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.errorText}>
|
||||||
|
{'Error Code: ' + errorCode}
|
||||||
|
</Text>
|
||||||
|
<Text style={styles.errorText}>
|
||||||
|
{'Description: ' + errorDesc}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderLoadingView: function() {
|
||||||
|
return (
|
||||||
|
<View style={styles.loadingView}>
|
||||||
|
<ActivityIndicatorIOS />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
onSubmitEditing: function(event) {
|
||||||
|
this.pressGoButton();
|
||||||
|
},
|
||||||
|
|
||||||
|
pressGoButton: function() {
|
||||||
|
var url = this.inputText.toLowerCase();
|
||||||
|
if (url === this.state.url) {
|
||||||
|
this.reload();
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
url: url,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// dismiss keyoard
|
||||||
|
this.refs[TEXT_INPUT_REF].blur();
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: HEADER,
|
||||||
|
},
|
||||||
|
addressBarRow: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
padding: 8,
|
||||||
|
},
|
||||||
|
webView: {
|
||||||
|
backgroundColor: BGWASH,
|
||||||
|
height: 350,
|
||||||
|
},
|
||||||
|
addressBarTextInput: {
|
||||||
|
backgroundColor: BGWASH,
|
||||||
|
borderColor: 'transparent',
|
||||||
|
borderRadius: 3,
|
||||||
|
borderWidth: 1,
|
||||||
|
height: 24,
|
||||||
|
paddingLeft: 10,
|
||||||
|
paddingTop: 3,
|
||||||
|
paddingBottom: 3,
|
||||||
|
flex: 1,
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
navButton: {
|
||||||
|
width: 20,
|
||||||
|
padding: 3,
|
||||||
|
marginRight: 3,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
backgroundColor: BGWASH,
|
||||||
|
borderColor: 'transparent',
|
||||||
|
borderRadius: 3,
|
||||||
|
},
|
||||||
|
disabledButton: {
|
||||||
|
width: 20,
|
||||||
|
padding: 3,
|
||||||
|
marginRight: 3,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
backgroundColor: DISABLED_WASH,
|
||||||
|
borderColor: 'transparent',
|
||||||
|
borderRadius: 3,
|
||||||
|
},
|
||||||
|
goButton: {
|
||||||
|
height: 24,
|
||||||
|
padding: 3,
|
||||||
|
marginLeft: 8,
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: BGWASH,
|
||||||
|
borderColor: 'transparent',
|
||||||
|
borderRadius: 3,
|
||||||
|
alignSelf: 'stretch',
|
||||||
|
},
|
||||||
|
loadingView: {
|
||||||
|
backgroundColor: BGWASH,
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
errorContainer: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: BGWASH,
|
||||||
|
},
|
||||||
|
errorTextTitle: {
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
errorText: {
|
||||||
|
fontSize: 14,
|
||||||
|
textAlign: 'center',
|
||||||
|
marginBottom: 2,
|
||||||
|
},
|
||||||
|
statusBar: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingLeft: 5,
|
||||||
|
height: 22,
|
||||||
|
},
|
||||||
|
statusBarText: {
|
||||||
|
color: 'white',
|
||||||
|
fontSize: 13,
|
||||||
|
},
|
||||||
|
spinner: {
|
||||||
|
width: 20,
|
||||||
|
marginRight: 6,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.title = '<WebView>';
|
||||||
|
exports.description = 'Base component to display web content';
|
||||||
|
exports.examples = [
|
||||||
|
{
|
||||||
|
title: 'WebView',
|
||||||
|
render() { return <WebViewExample />; }
|
||||||
|
}
|
||||||
|
];
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIWindow *window;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
|
#import "RCTRootView.h"
|
||||||
|
|
||||||
|
@implementation AppDelegate
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||||
|
{
|
||||||
|
NSURL *jsCodeLocation;
|
||||||
|
RCTRootView *rootView = [[RCTRootView alloc] init];
|
||||||
|
|
||||||
|
// Loading JavaScript code - uncomment the one you want.
|
||||||
|
|
||||||
|
// OPTION 1
|
||||||
|
// Load from development server. Start the server from the repository root:
|
||||||
|
//
|
||||||
|
// $ npm start
|
||||||
|
//
|
||||||
|
// To run on device, change `localhost` to the IP address of your computer, and make sure your computer and
|
||||||
|
// iOS device are on the same Wi-Fi network.
|
||||||
|
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/IntegrationTests/IntegrationTestsApp.includeRequire.runModule.bundle?dev=true"];
|
||||||
|
|
||||||
|
// OPTION 2
|
||||||
|
// Load from pre-bundled file on disk. To re-generate the static bundle, run
|
||||||
|
//
|
||||||
|
// $ curl http://localhost:8081/IntegrationTests/IntegrationTestsApp.includeRequire.runModule.bundle -o main.jsbundle
|
||||||
|
//
|
||||||
|
// and uncomment the next following line
|
||||||
|
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||||
|
|
||||||
|
rootView.scriptURL = jsCodeLocation;
|
||||||
|
rootView.moduleName = @"IntegrationTestsApp";
|
||||||
|
|
||||||
|
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||||
|
UIViewController *rootViewController = [[UIViewController alloc] init];
|
||||||
|
rootViewController.view = rootView;
|
||||||
|
self.window.rootViewController = rootViewController;
|
||||||
|
[self.window makeKeyAndVisible];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="13F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
||||||
|
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||||
|
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Facebook. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||||
|
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="IntegrationTests" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||||
|
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||||
|
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||||
|
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||||
|
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||||
|
</constraints>
|
||||||
|
<nil key="simulatedStatusBarMetrics"/>
|
||||||
|
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||||
|
<point key="canvasLocation" x="548" y="455"/>
|
||||||
|
</view>
|
||||||
|
</objects>
|
||||||
|
</document>
|
|
@ -0,0 +1,44 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "uie_icon@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "29x29",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "uie_icon@2x-1.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "uie_icon@2x-2.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "40x40",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "uie_icon@2x-3.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "60x60",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "uie_icon@2x-5.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "60x60",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"filename" : "uie_icon@2x-4.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.facebook.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
|
<array>
|
||||||
|
<string>armv7</string>
|
||||||
|
</array>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string>You need to add NSLocationWhenInUseUsageDescription key in Info.plist to enable geolocation, otherwise it is going to *fail silently*!</string>
|
||||||
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var RCTTestModule = require('NativeModules').RCTTestModule;
|
||||||
|
var React = require('react-native');
|
||||||
|
var {
|
||||||
|
Text,
|
||||||
|
View,
|
||||||
|
} = React;
|
||||||
|
|
||||||
|
var IntegrationTestHarnessTest = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
shouldThrow: React.PropTypes.bool,
|
||||||
|
waitOneFrame: React.PropTypes.bool,
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState() {
|
||||||
|
return {
|
||||||
|
done: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
if (this.props.waitOneFrame) {
|
||||||
|
requestAnimationFrame(this.runTest);
|
||||||
|
} else {
|
||||||
|
this.runTest();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
runTest() {
|
||||||
|
if (this.props.shouldThrow) {
|
||||||
|
throw new Error('Throwing error because shouldThrow');
|
||||||
|
}
|
||||||
|
if (!RCTTestModule) {
|
||||||
|
throw new Error('RCTTestModule is not registered.');
|
||||||
|
} else if (!RCTTestModule.markTestCompleted) {
|
||||||
|
throw new Error('RCTTestModule.markTestCompleted not defined.');
|
||||||
|
}
|
||||||
|
this.setState({done: true}, RCTTestModule.markTestCompleted);
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<View style={{backgroundColor: 'white', padding: 40}}>
|
||||||
|
<Text>
|
||||||
|
{this.constructor.displayName + ': '}
|
||||||
|
{this.state.done ? 'Done' : 'Testing...'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = IntegrationTestHarnessTest;
|
|
@ -0,0 +1,651 @@
|
||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 46;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
004D28A31AAF61C70097A701 /* IntegrationTestsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 004D28A21AAF61C70097A701 /* IntegrationTestsTests.m */; };
|
||||||
|
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||||
|
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||||
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||||
|
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||||
|
580C37601AB0F6180015E709 /* libReactKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 580C37461AB0F5320015E709 /* libReactKit.a */; };
|
||||||
|
580C37611AB0F61E0015E709 /* libRCTAdSupport.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 580C374B1AB0F54A0015E709 /* libRCTAdSupport.a */; };
|
||||||
|
580C37621AB0F6260015E709 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 580C37501AB0F55C0015E709 /* libRCTGeolocation.a */; };
|
||||||
|
580C37631AB0F62C0015E709 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 580C37551AB0F56E0015E709 /* libRCTImage.a */; };
|
||||||
|
580C37641AB0F6350015E709 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 580C375A1AB0F5970015E709 /* libRCTNetwork.a */; };
|
||||||
|
580C37651AB0F63E0015E709 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 580C375F1AB0F5D10015E709 /* libRCTText.a */; };
|
||||||
|
580C37921AB1090B0015E709 /* libRCTTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 580C378F1AB104B00015E709 /* libRCTTest.a */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
004D28A41AAF61C70097A701 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
|
||||||
|
remoteInfo = IntegrationTests;
|
||||||
|
};
|
||||||
|
580C37451AB0F5320015E709 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 13417FFA1AA91531003F314A /* ReactKit.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
||||||
|
remoteInfo = ReactKit;
|
||||||
|
};
|
||||||
|
580C374A1AB0F54A0015E709 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 832C81801AAF6DEF007FA2F7;
|
||||||
|
remoteInfo = RCTAdSupport;
|
||||||
|
};
|
||||||
|
580C374F1AB0F55C0015E709 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||||
|
remoteInfo = RCTGeolocation;
|
||||||
|
};
|
||||||
|
580C37541AB0F56E0015E709 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 13417FE31AA91428003F314A /* RCTImage.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
|
||||||
|
remoteInfo = RCTImage;
|
||||||
|
};
|
||||||
|
580C37591AB0F5970015E709 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 134180261AA91779003F314A /* RCTNetwork.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 58B511DB1A9E6C8500147676;
|
||||||
|
remoteInfo = RCTNetwork;
|
||||||
|
};
|
||||||
|
580C375E1AB0F5D10015E709 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 13417FEA1AA914B8003F314A /* RCTText.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||||
|
remoteInfo = RCTText;
|
||||||
|
};
|
||||||
|
580C378E1AB104B00015E709 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 580C37891AB104AF0015E709 /* RCTTest.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 580C376F1AB104AF0015E709;
|
||||||
|
remoteInfo = RCTTest;
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
004D289E1AAF61C70097A701 /* IntegrationTestsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IntegrationTestsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
004D28A11AAF61C70097A701 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
004D28A21AAF61C70097A701 /* IntegrationTestsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IntegrationTestsTests.m; sourceTree = "<group>"; };
|
||||||
|
13417FE31AA91428003F314A /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
13417FFA1AA91531003F314A /* ReactKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactKit.xcodeproj; path = ../ReactKit/ReactKit.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
134180261AA91779003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAdSupport.xcodeproj; path = ../Libraries/AdSupport/RCTAdSupport.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../Libraries/GeoLocation/RCTGeolocation.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
13B07F961A680F5B00A75B9A /* IntegrationTests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IntegrationTests.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||||
|
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||||
|
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||||
|
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||||
|
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>"; };
|
||||||
|
580C37891AB104AF0015E709 /* RCTTest.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTTest.xcodeproj; path = ../Libraries/RCTTest/RCTTest.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
004D289B1AAF61C70097A701 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
580C37601AB0F6180015E709 /* libReactKit.a in Frameworks */,
|
||||||
|
580C37611AB0F61E0015E709 /* libRCTAdSupport.a in Frameworks */,
|
||||||
|
580C37621AB0F6260015E709 /* libRCTGeolocation.a in Frameworks */,
|
||||||
|
580C37631AB0F62C0015E709 /* libRCTImage.a in Frameworks */,
|
||||||
|
580C37641AB0F6350015E709 /* libRCTNetwork.a in Frameworks */,
|
||||||
|
580C37651AB0F63E0015E709 /* libRCTText.a in Frameworks */,
|
||||||
|
580C37921AB1090B0015E709 /* libRCTTest.a in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
004D289F1AAF61C70097A701 /* IntegrationTestsTests */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
004D28A21AAF61C70097A701 /* IntegrationTestsTests.m */,
|
||||||
|
004D28A01AAF61C70097A701 /* Supporting Files */,
|
||||||
|
);
|
||||||
|
path = IntegrationTestsTests;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
004D28A01AAF61C70097A701 /* Supporting Files */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
004D28A11AAF61C70097A701 /* Info.plist */,
|
||||||
|
);
|
||||||
|
name = "Supporting Files";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
1316A21D1AA397F400C0188E /* Libraries */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
13417FFA1AA91531003F314A /* ReactKit.xcodeproj */,
|
||||||
|
134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */,
|
||||||
|
134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */,
|
||||||
|
13417FE31AA91428003F314A /* RCTImage.xcodeproj */,
|
||||||
|
134180261AA91779003F314A /* RCTNetwork.xcodeproj */,
|
||||||
|
13417FEA1AA914B8003F314A /* RCTText.xcodeproj */,
|
||||||
|
580C37891AB104AF0015E709 /* RCTTest.xcodeproj */,
|
||||||
|
);
|
||||||
|
name = Libraries;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
13B07FAE1A68108700A75B9A /* IntegrationTests */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||||
|
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||||
|
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||||
|
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||||
|
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||||
|
13B07FB71A68108700A75B9A /* main.m */,
|
||||||
|
);
|
||||||
|
name = IntegrationTests;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
580C37421AB0F5320015E709 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
580C37461AB0F5320015E709 /* libReactKit.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
580C37471AB0F54A0015E709 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
580C374B1AB0F54A0015E709 /* libRCTAdSupport.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
580C374C1AB0F55C0015E709 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
580C37501AB0F55C0015E709 /* libRCTGeolocation.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
580C37511AB0F56E0015E709 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
580C37551AB0F56E0015E709 /* libRCTImage.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
580C37561AB0F5970015E709 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
580C375A1AB0F5970015E709 /* libRCTNetwork.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
580C375B1AB0F5D10015E709 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
580C375F1AB0F5D10015E709 /* libRCTText.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
580C378A1AB104AF0015E709 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
580C378F1AB104B00015E709 /* libRCTTest.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
83CBB9F61A601CBA00E9B192 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
13B07FAE1A68108700A75B9A /* IntegrationTests */,
|
||||||
|
1316A21D1AA397F400C0188E /* Libraries */,
|
||||||
|
004D289F1AAF61C70097A701 /* IntegrationTestsTests */,
|
||||||
|
83CBBA001A601CBA00E9B192 /* Products */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
83CBBA001A601CBA00E9B192 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
13B07F961A680F5B00A75B9A /* IntegrationTests.app */,
|
||||||
|
004D289E1AAF61C70097A701 /* IntegrationTestsTests.xctest */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
004D289D1AAF61C70097A701 /* IntegrationTestsTests */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 004D28AD1AAF61C70097A701 /* Build configuration list for PBXNativeTarget "IntegrationTestsTests" */;
|
||||||
|
buildPhases = (
|
||||||
|
004D289A1AAF61C70097A701 /* Sources */,
|
||||||
|
004D289B1AAF61C70097A701 /* Frameworks */,
|
||||||
|
004D289C1AAF61C70097A701 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
004D28A51AAF61C70097A701 /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
name = IntegrationTestsTests;
|
||||||
|
productName = IntegrationTestsTests;
|
||||||
|
productReference = 004D289E1AAF61C70097A701 /* IntegrationTestsTests.xctest */;
|
||||||
|
productType = "com.apple.product-type.bundle.unit-test";
|
||||||
|
};
|
||||||
|
13B07F861A680F5B00A75B9A /* IntegrationTests */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "IntegrationTests" */;
|
||||||
|
buildPhases = (
|
||||||
|
13B07F871A680F5B00A75B9A /* Sources */,
|
||||||
|
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||||
|
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = IntegrationTests;
|
||||||
|
productName = "Hello World";
|
||||||
|
productReference = 13B07F961A680F5B00A75B9A /* IntegrationTests.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastUpgradeCheck = 0610;
|
||||||
|
ORGANIZATIONNAME = Facebook;
|
||||||
|
TargetAttributes = {
|
||||||
|
004D289D1AAF61C70097A701 = {
|
||||||
|
CreatedOnToolsVersion = 6.1.1;
|
||||||
|
TestTargetID = 13B07F861A680F5B00A75B9A;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "IntegrationTests" */;
|
||||||
|
compatibilityVersion = "Xcode 3.2";
|
||||||
|
developmentRegion = English;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||||
|
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectReferences = (
|
||||||
|
{
|
||||||
|
ProductGroup = 580C37471AB0F54A0015E709 /* Products */;
|
||||||
|
ProjectRef = 134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 580C374C1AB0F55C0015E709 /* Products */;
|
||||||
|
ProjectRef = 134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 580C37511AB0F56E0015E709 /* Products */;
|
||||||
|
ProjectRef = 13417FE31AA91428003F314A /* RCTImage.xcodeproj */;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 580C37561AB0F5970015E709 /* Products */;
|
||||||
|
ProjectRef = 134180261AA91779003F314A /* RCTNetwork.xcodeproj */;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 580C378A1AB104AF0015E709 /* Products */;
|
||||||
|
ProjectRef = 580C37891AB104AF0015E709 /* RCTTest.xcodeproj */;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 580C375B1AB0F5D10015E709 /* Products */;
|
||||||
|
ProjectRef = 13417FEA1AA914B8003F314A /* RCTText.xcodeproj */;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 580C37421AB0F5320015E709 /* Products */;
|
||||||
|
ProjectRef = 13417FFA1AA91531003F314A /* ReactKit.xcodeproj */;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
13B07F861A680F5B00A75B9A /* IntegrationTests */,
|
||||||
|
004D289D1AAF61C70097A701 /* IntegrationTestsTests */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXReferenceProxy section */
|
||||||
|
580C37461AB0F5320015E709 /* libReactKit.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libReactKit.a;
|
||||||
|
remoteRef = 580C37451AB0F5320015E709 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
580C374B1AB0F54A0015E709 /* libRCTAdSupport.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libRCTAdSupport.a;
|
||||||
|
remoteRef = 580C374A1AB0F54A0015E709 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
580C37501AB0F55C0015E709 /* libRCTGeolocation.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libRCTGeolocation.a;
|
||||||
|
remoteRef = 580C374F1AB0F55C0015E709 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
580C37551AB0F56E0015E709 /* libRCTImage.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libRCTImage.a;
|
||||||
|
remoteRef = 580C37541AB0F56E0015E709 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
580C375A1AB0F5970015E709 /* libRCTNetwork.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libRCTNetwork.a;
|
||||||
|
remoteRef = 580C37591AB0F5970015E709 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
580C375F1AB0F5D10015E709 /* libRCTText.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libRCTText.a;
|
||||||
|
remoteRef = 580C375E1AB0F5D10015E709 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
580C378F1AB104B00015E709 /* libRCTTest.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libRCTTest.a;
|
||||||
|
remoteRef = 580C378E1AB104B00015E709 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
|
/* End PBXReferenceProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
004D289C1AAF61C70097A701 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||||
|
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
004D289A1AAF61C70097A701 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
004D28A31AAF61C70097A701 /* IntegrationTestsTests.m in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||||
|
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXTargetDependency section */
|
||||||
|
004D28A51AAF61C70097A701 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 13B07F861A680F5B00A75B9A /* IntegrationTests */;
|
||||||
|
targetProxy = 004D28A41AAF61C70097A701 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
|
/* Begin PBXVariantGroup section */
|
||||||
|
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
13B07FB21A68108700A75B9A /* Base */,
|
||||||
|
);
|
||||||
|
name = LaunchScreen.xib;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
004D28A61AAF61C70097A701 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||||
|
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||||
|
);
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
INFOPLIST_FILE = IntegrationTestsTests/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/IntegrationTests.app/IntegrationTests";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
004D28A71AAF61C70097A701 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||||
|
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||||
|
);
|
||||||
|
INFOPLIST_FILE = IntegrationTestsTests/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/IntegrationTests.app/IntegrationTests";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
|
"$(SRCROOT)/../../ReactKit/**",
|
||||||
|
);
|
||||||
|
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||||
|
OTHER_LDFLAGS = "-ObjC";
|
||||||
|
PRODUCT_NAME = IntegrationTests;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
|
"$(SRCROOT)/../../ReactKit/**",
|
||||||
|
);
|
||||||
|
INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
|
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||||
|
OTHER_LDFLAGS = "-ObjC";
|
||||||
|
PRODUCT_NAME = IntegrationTests;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
|
"$(SRCROOT)/../ReactKit/**",
|
||||||
|
);
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
83CBBA211A601CBA00E9B192 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
|
COPY_PHASE_STRIP = YES;
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
|
"$(SRCROOT)/../ReactKit/**",
|
||||||
|
);
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
004D28AD1AAF61C70097A701 /* Build configuration list for PBXNativeTarget "IntegrationTestsTests" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
004D28A61AAF61C70097A701 /* Debug */,
|
||||||
|
004D28A71AAF61C70097A701 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "IntegrationTests" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
13B07F941A680F5B00A75B9A /* Debug */,
|
||||||
|
13B07F951A680F5B00A75B9A /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "IntegrationTests" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
83CBBA201A601CBA00E9B192 /* Debug */,
|
||||||
|
83CBBA211A601CBA00E9B192 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule IntegrationTestsApp
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var React = require('react-native');
|
||||||
|
|
||||||
|
var {
|
||||||
|
AppRegistry,
|
||||||
|
ScrollView,
|
||||||
|
StyleSheet,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
View,
|
||||||
|
} = React;
|
||||||
|
|
||||||
|
var TESTS = [
|
||||||
|
require('./IntegrationTestHarnessTest'),
|
||||||
|
];
|
||||||
|
|
||||||
|
TESTS.forEach(
|
||||||
|
(test) => AppRegistry.registerComponent(test.displayName, () => test)
|
||||||
|
);
|
||||||
|
|
||||||
|
var IntegrationTestsApp = React.createClass({
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
test: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
if (this.state.test) {
|
||||||
|
return (
|
||||||
|
<ScrollView>
|
||||||
|
<this.state.test />
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text style={styles.row}>
|
||||||
|
Click on a test to run it in this shell for easier debugging and
|
||||||
|
development. Run all tests in the testing envirnment with cmd+U in
|
||||||
|
Xcode.
|
||||||
|
</Text>
|
||||||
|
<View style={styles.separator} />
|
||||||
|
<ScrollView>
|
||||||
|
{TESTS.map((test) => [
|
||||||
|
<TouchableOpacity onPress={() => this.setState({test})}>
|
||||||
|
<View style={styles.row}>
|
||||||
|
<Text style={styles.testName}>
|
||||||
|
{test.displayName}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>,
|
||||||
|
<View style={styles.separator} />
|
||||||
|
])}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
backgroundColor: 'white',
|
||||||
|
marginTop: 40,
|
||||||
|
margin: 15,
|
||||||
|
},
|
||||||
|
row: {
|
||||||
|
padding: 10,
|
||||||
|
},
|
||||||
|
testName: {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
separator: {
|
||||||
|
height: 1,
|
||||||
|
backgroundColor: '#bbbbbb',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
AppRegistry.registerComponent('IntegrationTestsApp', () => IntegrationTestsApp);
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.facebook.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>BNDL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <XCTest/XCTest.h>
|
||||||
|
|
||||||
|
#import <RCTTest/RCTTestRunner.h>
|
||||||
|
|
||||||
|
#import "RCTAssert.h"
|
||||||
|
|
||||||
|
@interface IntegrationTestsTests : XCTestCase
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation IntegrationTestsTests {
|
||||||
|
RCTTestRunner *_runner;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setUp
|
||||||
|
{
|
||||||
|
_runner = [[RCTTestRunner alloc] initWithApp:@"IntegrationTests/IntegrationTestsApp"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testTheTester
|
||||||
|
{
|
||||||
|
[_runner runTest:@"IntegrationTestHarnessTest"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testTheTester_waitOneFrame
|
||||||
|
{
|
||||||
|
[_runner runTest:@"IntegrationTestHarnessTest" initialProps:@{@"waitOneFrame": @YES} expectErrorBlock:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testTheTester_ExpectError
|
||||||
|
{
|
||||||
|
[_runner runTest:@"IntegrationTestHarnessTest"
|
||||||
|
initialProps:@{@"shouldThrow": @YES}
|
||||||
|
expectErrorRegex:[NSRegularExpression regularExpressionWithPattern:@"because shouldThrow" options:0 error:nil]];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
|
int main(int argc, char * argv[]) {
|
||||||
|
@autoreleasepool {
|
||||||
|
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,10 +23,11 @@ var Animation = {
|
||||||
): number {
|
): number {
|
||||||
var nodeHandle = +node.getNodeHandle();
|
var nodeHandle = +node.getNodeHandle();
|
||||||
var easingSample = AnimationUtils.evaluateEasingFunction(duration, easing);
|
var easingSample = AnimationUtils.evaluateEasingFunction(duration, easing);
|
||||||
RCTAnimationManager.startAnimation(nodeHandle, AnimationUtils.allocateTag(), duration, delay, easingSample, properties);
|
var tag: number = RCTAnimationManager.startAnimation(nodeHandle, AnimationUtils.allocateTag(), duration, delay, easingSample, properties);
|
||||||
|
return tag;
|
||||||
},
|
},
|
||||||
|
|
||||||
stopAnimation: function(tag) {
|
stopAnimation: function(tag: number) {
|
||||||
RCTAnimationManager.stopAnimation(tag);
|
RCTAnimationManager.stopAnimation(tag);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,7 +34,8 @@ var AnimationMixin = {
|
||||||
|
|
||||||
var nodeHandle = +ref.getNodeHandle();
|
var nodeHandle = +ref.getNodeHandle();
|
||||||
var easingSample = AnimationUtils.evaluateEasingFunction(duration, easing);
|
var easingSample = AnimationUtils.evaluateEasingFunction(duration, easing);
|
||||||
RCTAnimationManager.startAnimation(nodeHandle, AnimationUtils.allocateTag(), duration, delay, easingSample, properties);
|
var tag: number = RCTAnimationManager.startAnimation(nodeHandle, AnimationUtils.allocateTag(), duration, delay, easingSample, properties);
|
||||||
|
return tag;
|
||||||
},
|
},
|
||||||
|
|
||||||
stopAnimation: function(tag: number) {
|
stopAnimation: function(tag: number) {
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule WebView
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var EdgeInsetsPropType = require('EdgeInsetsPropType');
|
||||||
|
var React = require('React');
|
||||||
|
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
|
||||||
|
var StyleSheet = require('StyleSheet');
|
||||||
|
var View = require('View');
|
||||||
|
|
||||||
|
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
|
||||||
|
var keyMirror = require('keyMirror');
|
||||||
|
var merge = require('merge');
|
||||||
|
|
||||||
|
var PropTypes = React.PropTypes;
|
||||||
|
var RKUIManager = require('NativeModules').RKUIManager;
|
||||||
|
|
||||||
|
var RK_WEBVIEW_REF = 'webview';
|
||||||
|
|
||||||
|
var WebViewState = keyMirror({
|
||||||
|
IDLE: null,
|
||||||
|
LOADING: null,
|
||||||
|
ERROR: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
var WebView = React.createClass({
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
renderErrorView: PropTypes.func.isRequired, // view to show if there's an error
|
||||||
|
renderLoadingView: PropTypes.func.isRequired, // loading indicator to show
|
||||||
|
url: PropTypes.string.isRequired,
|
||||||
|
automaticallyAdjustContentInsets: PropTypes.bool,
|
||||||
|
contentInset: EdgeInsetsPropType,
|
||||||
|
onNavigationStateChange: PropTypes.func,
|
||||||
|
startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load
|
||||||
|
style: View.propTypes.style,
|
||||||
|
/**
|
||||||
|
* Used to locate this view in end-to-end tests.
|
||||||
|
*/
|
||||||
|
testID: PropTypes.string,
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
viewState: WebViewState.IDLE,
|
||||||
|
lastErrorEvent: null,
|
||||||
|
startInLoadingState: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillMount: function() {
|
||||||
|
if (this.props.startInLoadingState) {
|
||||||
|
this.setState({viewState: WebViewState.LOADING});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
var otherView = null;
|
||||||
|
|
||||||
|
if (this.state.viewState === WebViewState.LOADING) {
|
||||||
|
otherView = this.props.renderLoadingView();
|
||||||
|
} else if (this.state.viewState === WebViewState.ERROR) {
|
||||||
|
var errorEvent = this.state.lastErrorEvent;
|
||||||
|
otherView = this.props.renderErrorView(
|
||||||
|
errorEvent.domain,
|
||||||
|
errorEvent.code,
|
||||||
|
errorEvent.description);
|
||||||
|
} else if (this.state.viewState !== WebViewState.IDLE) {
|
||||||
|
console.error("RCTWebView invalid state encountered: " + this.state.loading);
|
||||||
|
}
|
||||||
|
|
||||||
|
var webViewStyles = [styles.container, this.props.style];
|
||||||
|
if (this.state.viewState === WebViewState.LOADING ||
|
||||||
|
this.state.viewState === WebViewState.ERROR) {
|
||||||
|
// if we're in either LOADING or ERROR states, don't show the webView
|
||||||
|
webViewStyles.push(styles.hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
var webView =
|
||||||
|
<RCTWebView
|
||||||
|
ref={RK_WEBVIEW_REF}
|
||||||
|
key="webViewKey"
|
||||||
|
style={webViewStyles}
|
||||||
|
url={this.props.url}
|
||||||
|
contentInset={this.props.contentInset}
|
||||||
|
automaticallyAdjustContentInsets={this.props.automaticallyAdjustContentInsets}
|
||||||
|
onLoadingStart={this.onLoadingStart}
|
||||||
|
onLoadingFinish={this.onLoadingFinish}
|
||||||
|
onLoadingError={this.onLoadingError}
|
||||||
|
testID={this.props.testID}
|
||||||
|
/>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{webView}
|
||||||
|
{otherView}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
goForward: function() {
|
||||||
|
RKUIManager.webViewGoForward(this.getWebWiewHandle());
|
||||||
|
},
|
||||||
|
|
||||||
|
goBack: function() {
|
||||||
|
RKUIManager.webViewGoBack(this.getWebWiewHandle());
|
||||||
|
},
|
||||||
|
|
||||||
|
reload: function() {
|
||||||
|
RKUIManager.webViewReload(this.getWebWiewHandle());
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We return an event with a bunch of fields including:
|
||||||
|
* url, title, loading, canGoBack, canGoForward
|
||||||
|
*/
|
||||||
|
updateNavigationState: function(event) {
|
||||||
|
if (this.props.onNavigationStateChange) {
|
||||||
|
this.props.onNavigationStateChange(event.nativeEvent);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getWebWiewHandle: function() {
|
||||||
|
return this.refs[RK_WEBVIEW_REF].getNodeHandle();
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoadingStart: function(event) {
|
||||||
|
this.updateNavigationState(event);
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoadingError: function(event) {
|
||||||
|
event.persist(); // persist this event because we need to store it
|
||||||
|
console.error("encountered an error loading page", event.nativeEvent);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
lastErrorEvent: event.nativeEvent,
|
||||||
|
viewState: WebViewState.ERROR
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoadingFinish: function(event) {
|
||||||
|
this.setState({
|
||||||
|
viewState: WebViewState.IDLE,
|
||||||
|
});
|
||||||
|
this.updateNavigationState(event);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var RCTWebView = createReactIOSNativeComponentClass({
|
||||||
|
validAttributes: merge(ReactIOSViewAttributes.UIView, {
|
||||||
|
url: true,
|
||||||
|
}),
|
||||||
|
uiViewClassName: 'RCTWebView',
|
||||||
|
});
|
||||||
|
|
||||||
|
var styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
hidden: {
|
||||||
|
height: 0,
|
||||||
|
flex: 0, // disable 'flex:1' when hiding a View
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = WebView;
|
|
@ -0,0 +1,182 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule WebView
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var EdgeInsetsPropType = require('EdgeInsetsPropType');
|
||||||
|
var React = require('React');
|
||||||
|
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
|
||||||
|
var StyleSheet = require('StyleSheet');
|
||||||
|
var View = require('View');
|
||||||
|
|
||||||
|
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
|
||||||
|
var keyMirror = require('keyMirror');
|
||||||
|
var insetsDiffer = require('insetsDiffer');
|
||||||
|
var merge = require('merge');
|
||||||
|
|
||||||
|
var PropTypes = React.PropTypes;
|
||||||
|
var { RKWebViewManager } = require('NativeModules');
|
||||||
|
|
||||||
|
var RK_WEBVIEW_REF = 'webview';
|
||||||
|
|
||||||
|
var WebViewState = keyMirror({
|
||||||
|
IDLE: null,
|
||||||
|
LOADING: null,
|
||||||
|
ERROR: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
var NavigationType = {
|
||||||
|
click: RKWebViewManager.NavigationType.LinkClicked,
|
||||||
|
formsubmit: RKWebViewManager.NavigationType.FormSubmitted,
|
||||||
|
backforward: RKWebViewManager.NavigationType.BackForward,
|
||||||
|
reload: RKWebViewManager.NavigationType.Reload,
|
||||||
|
formresubmit: RKWebViewManager.NavigationType.FormResubmitted,
|
||||||
|
other: RKWebViewManager.NavigationType.Other,
|
||||||
|
};
|
||||||
|
|
||||||
|
var WebView = React.createClass({
|
||||||
|
statics: {
|
||||||
|
NavigationType: NavigationType,
|
||||||
|
},
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
renderErrorView: PropTypes.func.isRequired, // view to show if there's an error
|
||||||
|
renderLoadingView: PropTypes.func.isRequired, // loading indicator to show
|
||||||
|
url: PropTypes.string.isRequired,
|
||||||
|
automaticallyAdjustContentInsets: PropTypes.bool,
|
||||||
|
shouldInjectAJAXHandler: PropTypes.bool,
|
||||||
|
contentInset: EdgeInsetsPropType,
|
||||||
|
onNavigationStateChange: PropTypes.func,
|
||||||
|
startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load
|
||||||
|
style: View.propTypes.style,
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
viewState: WebViewState.IDLE,
|
||||||
|
lastErrorEvent: null,
|
||||||
|
startInLoadingState: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillMount: function() {
|
||||||
|
if (this.props.startInLoadingState) {
|
||||||
|
this.setState({viewState: WebViewState.LOADING});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
var otherView = null;
|
||||||
|
|
||||||
|
if (this.state.viewState === WebViewState.LOADING) {
|
||||||
|
otherView = this.props.renderLoadingView();
|
||||||
|
} else if (this.state.viewState === WebViewState.ERROR) {
|
||||||
|
var errorEvent = this.state.lastErrorEvent;
|
||||||
|
otherView = this.props.renderErrorView(
|
||||||
|
errorEvent.domain,
|
||||||
|
errorEvent.code,
|
||||||
|
errorEvent.description);
|
||||||
|
} else if (this.state.viewState !== WebViewState.IDLE) {
|
||||||
|
console.error("RKWebView invalid state encountered: " + this.state.loading);
|
||||||
|
}
|
||||||
|
|
||||||
|
var webViewStyles = [styles.container, this.props.style];
|
||||||
|
if (this.state.viewState === WebViewState.LOADING ||
|
||||||
|
this.state.viewState === WebViewState.ERROR) {
|
||||||
|
// if we're in either LOADING or ERROR states, don't show the webView
|
||||||
|
webViewStyles.push(styles.hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
var webView =
|
||||||
|
<RCTWebView
|
||||||
|
ref={RK_WEBVIEW_REF}
|
||||||
|
key="webViewKey"
|
||||||
|
style={webViewStyles}
|
||||||
|
url={this.props.url}
|
||||||
|
shouldInjectAJAXHandler={this.props.shouldInjectAJAXHandler}
|
||||||
|
contentInset={this.props.contentInset}
|
||||||
|
automaticallyAdjustContentInsets={this.props.automaticallyAdjustContentInsets}
|
||||||
|
onLoadingStart={this.onLoadingStart}
|
||||||
|
onLoadingFinish={this.onLoadingFinish}
|
||||||
|
onLoadingError={this.onLoadingError}
|
||||||
|
/>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{webView}
|
||||||
|
{otherView}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
goForward: function() {
|
||||||
|
RKWebViewManager.goForward(this.getWebWiewHandle());
|
||||||
|
},
|
||||||
|
|
||||||
|
goBack: function() {
|
||||||
|
RKWebViewManager.goBack(this.getWebWiewHandle());
|
||||||
|
},
|
||||||
|
|
||||||
|
reload: function() {
|
||||||
|
RKWebViewManager.reload(this.getWebWiewHandle());
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We return an event with a bunch of fields including:
|
||||||
|
* url, title, loading, canGoBack, canGoForward
|
||||||
|
*/
|
||||||
|
updateNavigationState: function(event) {
|
||||||
|
if (this.props.onNavigationStateChange) {
|
||||||
|
this.props.onNavigationStateChange(event.nativeEvent);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getWebWiewHandle: function() {
|
||||||
|
return this.refs[RK_WEBVIEW_REF].getNodeHandle();
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoadingStart: function(event) {
|
||||||
|
this.updateNavigationState(event);
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoadingError: function(event) {
|
||||||
|
event.persist(); // persist this event because we need to store it
|
||||||
|
console.error("encountered an error loading page", event.nativeEvent);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
lastErrorEvent: event.nativeEvent,
|
||||||
|
viewState: WebViewState.ERROR
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoadingFinish: function(event) {
|
||||||
|
this.setState({
|
||||||
|
viewState: WebViewState.IDLE,
|
||||||
|
});
|
||||||
|
this.updateNavigationState(event);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var RCTWebView = createReactIOSNativeComponentClass({
|
||||||
|
validAttributes: merge(ReactIOSViewAttributes.UIView, {
|
||||||
|
url: true,
|
||||||
|
contentInset: {diff: insetsDiffer},
|
||||||
|
automaticallyAdjustContentInsets: true,
|
||||||
|
shouldInjectAJAXHandler: true
|
||||||
|
}),
|
||||||
|
uiViewClassName: 'RCTWebView',
|
||||||
|
});
|
||||||
|
|
||||||
|
var styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
hidden: {
|
||||||
|
height: 0,
|
||||||
|
flex: 0, // disable 'flex:1' when hiding a View
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = WebView;
|
|
@ -0,0 +1,264 @@
|
||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 46;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
585135371AB3C56F00882537 /* RCTTestModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 585135341AB3C56F00882537 /* RCTTestModule.m */; };
|
||||||
|
585135381AB3C57000882537 /* RCTTestRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 585135361AB3C56F00882537 /* RCTTestRunner.m */; };
|
||||||
|
585135391AB3C59A00882537 /* RCTTestRunner.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 585135351AB3C56F00882537 /* RCTTestRunner.h */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
580C376D1AB104AF0015E709 /* CopyFiles */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "include/$(PRODUCT_NAME)";
|
||||||
|
dstSubfolderSpec = 16;
|
||||||
|
files = (
|
||||||
|
585135391AB3C59A00882537 /* RCTTestRunner.h in CopyFiles */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
580C376F1AB104AF0015E709 /* libRCTTest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTTest.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
585135331AB3C56F00882537 /* RCTTestModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTestModule.h; sourceTree = "<group>"; };
|
||||||
|
585135341AB3C56F00882537 /* RCTTestModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTestModule.m; sourceTree = "<group>"; };
|
||||||
|
585135351AB3C56F00882537 /* RCTTestRunner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTestRunner.h; sourceTree = "<group>"; };
|
||||||
|
585135361AB3C56F00882537 /* RCTTestRunner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTestRunner.m; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
580C376C1AB104AF0015E709 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
580C37661AB104AF0015E709 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
585135331AB3C56F00882537 /* RCTTestModule.h */,
|
||||||
|
585135341AB3C56F00882537 /* RCTTestModule.m */,
|
||||||
|
585135351AB3C56F00882537 /* RCTTestRunner.h */,
|
||||||
|
585135361AB3C56F00882537 /* RCTTestRunner.m */,
|
||||||
|
580C37701AB104AF0015E709 /* Products */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
580C37701AB104AF0015E709 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
580C376F1AB104AF0015E709 /* libRCTTest.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
580C376E1AB104AF0015E709 /* RCTTest */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 580C37831AB104AF0015E709 /* Build configuration list for PBXNativeTarget "RCTTest" */;
|
||||||
|
buildPhases = (
|
||||||
|
580C376B1AB104AF0015E709 /* Sources */,
|
||||||
|
580C376C1AB104AF0015E709 /* Frameworks */,
|
||||||
|
580C376D1AB104AF0015E709 /* CopyFiles */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = RCTTest;
|
||||||
|
productName = RCTTest;
|
||||||
|
productReference = 580C376F1AB104AF0015E709 /* libRCTTest.a */;
|
||||||
|
productType = "com.apple.product-type.library.static";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
580C37671AB104AF0015E709 /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastUpgradeCheck = 0610;
|
||||||
|
ORGANIZATIONNAME = Facebook;
|
||||||
|
TargetAttributes = {
|
||||||
|
580C376E1AB104AF0015E709 = {
|
||||||
|
CreatedOnToolsVersion = 6.1.1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 580C376A1AB104AF0015E709 /* Build configuration list for PBXProject "RCTTest" */;
|
||||||
|
compatibilityVersion = "Xcode 3.2";
|
||||||
|
developmentRegion = English;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
);
|
||||||
|
mainGroup = 580C37661AB104AF0015E709;
|
||||||
|
productRefGroup = 580C37701AB104AF0015E709 /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
580C376E1AB104AF0015E709 /* RCTTest */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
580C376B1AB104AF0015E709 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
585135371AB3C56F00882537 /* RCTTestModule.m in Sources */,
|
||||||
|
585135381AB3C57000882537 /* RCTTestRunner.m in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
580C37811AB104AF0015E709 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
|
"$(SRCROOT)/../../ReactKit/**",
|
||||||
|
);
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
580C37821AB104AF0015E709 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = YES;
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
|
"$(SRCROOT)/../../ReactKit/**",
|
||||||
|
);
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
580C37841AB104AF0015E709 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
OTHER_LDFLAGS = (
|
||||||
|
"-ObjC",
|
||||||
|
"-framework",
|
||||||
|
XCTest,
|
||||||
|
);
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
580C37851AB104AF0015E709 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
OTHER_LDFLAGS = (
|
||||||
|
"-ObjC",
|
||||||
|
"-framework",
|
||||||
|
XCTest,
|
||||||
|
);
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
580C376A1AB104AF0015E709 /* Build configuration list for PBXProject "RCTTest" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
580C37811AB104AF0015E709 /* Debug */,
|
||||||
|
580C37821AB104AF0015E709 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
580C37831AB104AF0015E709 /* Build configuration list for PBXNativeTarget "RCTTest" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
580C37841AB104AF0015E709 /* Debug */,
|
||||||
|
580C37851AB104AF0015E709 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 580C37671AB104AF0015E709 /* Project object */;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import "RCTBridgeModule.h"
|
||||||
|
|
||||||
|
@interface RCTTestModule : NSObject <RCTBridgeModule>
|
||||||
|
|
||||||
|
@property (nonatomic, readonly, getter=isDone) BOOL done;
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import "RCTTestModule.h"
|
||||||
|
|
||||||
|
@implementation RCTTestModule
|
||||||
|
|
||||||
|
- (void)markTestCompleted
|
||||||
|
{
|
||||||
|
RCT_EXPORT();
|
||||||
|
|
||||||
|
_done = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@interface RCTTestRunner : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, copy) NSString *script;
|
||||||
|
|
||||||
|
- (instancetype)initWithApp:(NSString *)app;
|
||||||
|
- (void)runTest:(NSString *)moduleName;
|
||||||
|
- (void)runTest:(NSString *)moduleName initialProps:(NSDictionary *)initialProps expectErrorRegex:(NSRegularExpression *)expectErrorRegex;
|
||||||
|
- (void)runTest:(NSString *)moduleName initialProps:(NSDictionary *)initialProps expectErrorBlock:(BOOL(^)(NSString *error))expectErrorBlock;
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import "RCTTestRunner.h"
|
||||||
|
|
||||||
|
#import "RCTRedBox.h"
|
||||||
|
#import "RCTRootView.h"
|
||||||
|
#import "RCTTestModule.h"
|
||||||
|
#import "RCTUtils.h"
|
||||||
|
|
||||||
|
#define TIMEOUT_SECONDS 30
|
||||||
|
|
||||||
|
@implementation RCTTestRunner
|
||||||
|
|
||||||
|
- (instancetype)initWithApp:(NSString *)app
|
||||||
|
{
|
||||||
|
if (self = [super init]) {
|
||||||
|
_script = [NSString stringWithFormat:@"http://localhost:8081/%@.includeRequire.runModule.bundle?dev=true", app];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)runTest:(NSString *)moduleName
|
||||||
|
{
|
||||||
|
[self runTest:moduleName initialProps:nil expectErrorBlock:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)runTest:(NSString *)moduleName initialProps:(NSDictionary *)initialProps expectErrorRegex:(NSRegularExpression *)errorRegex
|
||||||
|
{
|
||||||
|
[self runTest:moduleName initialProps:initialProps expectErrorBlock:^BOOL(NSString *error){
|
||||||
|
return [errorRegex numberOfMatchesInString:error options:0 range:NSMakeRange(0, [error length])] > 0;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)runTest:(NSString *)moduleName initialProps:(NSDictionary *)initialProps expectErrorBlock:(BOOL(^)(NSString *error))expectErrorBlock
|
||||||
|
{
|
||||||
|
RCTTestModule *testModule = [[RCTTestModule alloc] init];
|
||||||
|
RCTRootView *rootView = [[RCTRootView alloc] init];
|
||||||
|
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
||||||
|
vc.view = rootView;
|
||||||
|
rootView.moduleProvider = ^(void){
|
||||||
|
return @[testModule];
|
||||||
|
};
|
||||||
|
rootView.moduleName = moduleName;
|
||||||
|
rootView.initialProperties = initialProps;
|
||||||
|
rootView.scriptURL = [NSURL URLWithString:_script];
|
||||||
|
|
||||||
|
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
|
||||||
|
NSString *error = [[RCTRedBox sharedInstance] currentErrorMessage];
|
||||||
|
while ([date timeIntervalSinceNow] > 0 && ![testModule isDone] && error == nil) {
|
||||||
|
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:date];
|
||||||
|
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:date];
|
||||||
|
error = [[RCTRedBox sharedInstance] currentErrorMessage];
|
||||||
|
}
|
||||||
|
[[RCTRedBox sharedInstance] dismiss];
|
||||||
|
if (expectErrorBlock) {
|
||||||
|
RCTAssert(expectErrorBlock(error), @"Expected an error but got none.");
|
||||||
|
} else if (error) {
|
||||||
|
RCTAssert(error == nil, @"RedBox error: %@", error);
|
||||||
|
} else {
|
||||||
|
RCTAssert([testModule isDone], @"Test didn't finish within %d seconds", TIMEOUT_SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule AlertIOS
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var NativeModules = require('NativeModulesDeprecated');
|
||||||
|
|
||||||
|
var RCTAlertManager = NativeModules.RCTAlertManager;
|
||||||
|
|
||||||
|
var DEFAULT_BUTTON_TEXT = 'OK';
|
||||||
|
var DEFAULT_BUTTON = {
|
||||||
|
text: DEFAULT_BUTTON_TEXT,
|
||||||
|
onPress: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AlertIOS manages native iOS alerts, option sheets, and share dialogs
|
||||||
|
*/
|
||||||
|
|
||||||
|
class AlertIOS {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launches an alert dialog with the specified title and message.
|
||||||
|
*
|
||||||
|
* Optionally provide a list of buttons. Tapping any button will fire the
|
||||||
|
* respective onPress callback and dismiss the alert. By default, the only
|
||||||
|
* button will be an 'OK' button
|
||||||
|
*
|
||||||
|
* The last button in the list will be considered the 'Primary' button and
|
||||||
|
* it will appear bold.
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* AlertIOS.alert(
|
||||||
|
* 'Foo Title',
|
||||||
|
* 'My Alert Msg',
|
||||||
|
* [
|
||||||
|
* {text: 'Foo', onPress: () => console.log('Foo Pressed!')},
|
||||||
|
* {text: 'Bar', onPress: () => console.log('Bar Pressed!')},
|
||||||
|
* ]
|
||||||
|
* )}
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
static alert(
|
||||||
|
title: ?string,
|
||||||
|
message: ?string,
|
||||||
|
buttons: ?Array<{
|
||||||
|
text: ?string;
|
||||||
|
onPress: ?Function;
|
||||||
|
}>
|
||||||
|
): void {
|
||||||
|
var callbacks = [];
|
||||||
|
var buttonsSpec = [];
|
||||||
|
title = title || '';
|
||||||
|
message = message || '';
|
||||||
|
buttons = buttons || [DEFAULT_BUTTON];
|
||||||
|
buttons.forEach((btn, index) => {
|
||||||
|
callbacks[index] = btn.onPress;
|
||||||
|
var btnDef = {};
|
||||||
|
btnDef[index] = btn.text || DEFAULT_BUTTON_TEXT;
|
||||||
|
buttonsSpec.push(btnDef);
|
||||||
|
});
|
||||||
|
RCTAlertManager.alertWithArgs({
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
buttons: buttonsSpec,
|
||||||
|
}, (id) => {
|
||||||
|
var cb = callbacks[id];
|
||||||
|
cb && cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = AlertIOS;
|
|
@ -38,7 +38,7 @@ var deepDiffer = function(one: any, two: any): bool {
|
||||||
for (var twoKey in two) {
|
for (var twoKey in two) {
|
||||||
// The only case we haven't checked yet is keys that are in two but aren't
|
// The only case we haven't checked yet is keys that are in two but aren't
|
||||||
// in one, which means they are different.
|
// in one, which means they are different.
|
||||||
if (one[twoKey] === undefined) {
|
if (one[twoKey] === undefined && two[twoKey] !== undefined) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ var ReactNative = {
|
||||||
...require('React'),
|
...require('React'),
|
||||||
Animation: require('Animation'),
|
Animation: require('Animation'),
|
||||||
ActivityIndicatorIOS: require('ActivityIndicatorIOS'),
|
ActivityIndicatorIOS: require('ActivityIndicatorIOS'),
|
||||||
|
AlertIOS: require('AlertIOS'),
|
||||||
AppRegistry: require('AppRegistry'),
|
AppRegistry: require('AppRegistry'),
|
||||||
AppState: require('AppState'),
|
AppState: require('AppState'),
|
||||||
AppStateIOS: require('AppStateIOS'),
|
AppStateIOS: require('AppStateIOS'),
|
||||||
|
@ -36,6 +37,7 @@ var ReactNative = {
|
||||||
TouchableOpacity: require('TouchableOpacity'),
|
TouchableOpacity: require('TouchableOpacity'),
|
||||||
TouchableWithoutFeedback: require('TouchableWithoutFeedback'),
|
TouchableWithoutFeedback: require('TouchableWithoutFeedback'),
|
||||||
View: require('View'),
|
View: require('View'),
|
||||||
|
WebView: require('WebView'),
|
||||||
invariant: require('invariant'),
|
invariant: require('invariant'),
|
||||||
ix: require('ix'),
|
ix: require('ix'),
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack;
|
- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack;
|
||||||
- (void)updateErrorMessage:(NSString *)message withStack:(NSArray *)stack;
|
- (void)updateErrorMessage:(NSString *)message withStack:(NSArray *)stack;
|
||||||
|
|
||||||
|
- (NSString *)currentErrorMessage;
|
||||||
|
|
||||||
- (void)dismiss;
|
- (void)dismiss;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
@interface RCTRedBoxWindow : UIWindow <UITableViewDelegate, UITableViewDataSource>
|
@interface RCTRedBoxWindow : UIWindow <UITableViewDelegate, UITableViewDataSource>
|
||||||
|
|
||||||
|
@property (nonatomic, copy) NSString *lastErrorMessage;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation RCTRedBoxWindow
|
@implementation RCTRedBoxWindow
|
||||||
|
@ -13,7 +15,6 @@
|
||||||
UIView *_rootView;
|
UIView *_rootView;
|
||||||
UITableView *_stackTraceTableView;
|
UITableView *_stackTraceTableView;
|
||||||
|
|
||||||
NSString *_lastErrorMessage;
|
|
||||||
NSArray *_lastStackTrace;
|
NSArray *_lastStackTrace;
|
||||||
|
|
||||||
UITableViewCell *_cachedMessageCell;
|
UITableViewCell *_cachedMessageCell;
|
||||||
|
@ -289,6 +290,15 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString *)currentErrorMessage
|
||||||
|
{
|
||||||
|
if (_window && !_window.hidden) {
|
||||||
|
return _window.lastErrorMessage;
|
||||||
|
} else {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)dismiss
|
- (void)dismiss
|
||||||
{
|
{
|
||||||
[_window dismiss];
|
[_window dismiss];
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
#import "RCTBridge.h"
|
||||||
|
|
||||||
@interface RCTRootView : UIView
|
@interface RCTRootView : UIView
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,13 +21,20 @@
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, copy) NSString *moduleName;
|
@property (nonatomic, copy) NSString *moduleName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A block that returns an array of pre-allocated modules. These
|
||||||
|
* modules will take precedence over any automatically registered
|
||||||
|
* modules of the same name.
|
||||||
|
*/
|
||||||
|
@property (nonatomic, copy) RCTBridgeModuleProviderBlock moduleProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default properties to apply to the view when the script bundle
|
* The default properties to apply to the view when the script bundle
|
||||||
* is first loaded. Defaults to nil/empty.
|
* is first loaded. Defaults to nil/empty.
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, copy) NSDictionary *initialProperties;
|
@property (nonatomic, copy) NSDictionary *initialProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The class of the RCTJavaScriptExecutor to use with this view.
|
* The class of the RCTJavaScriptExecutor to use with this view.
|
||||||
* If not specified, it will default to using RCTContextExecutor.
|
* If not specified, it will default to using RCTContextExecutor.
|
||||||
* Changes will take effect next time the bundle is reloaded.
|
* Changes will take effect next time the bundle is reloaded.
|
||||||
|
|
|
@ -142,7 +142,7 @@ static Class _globalExecutorClass;
|
||||||
|
|
||||||
// Choose local executor if specified, followed by global, followed by default
|
// Choose local executor if specified, followed by global, followed by default
|
||||||
_executor = [[_executorClass ?: _globalExecutorClass ?: [RCTContextExecutor class] alloc] init];
|
_executor = [[_executorClass ?: _globalExecutorClass ?: [RCTContextExecutor class] alloc] init];
|
||||||
_bridge = [[RCTBridge alloc] initWithExecutor:_executor moduleProvider:nil];
|
_bridge = [[RCTBridge alloc] initWithExecutor:_executor moduleProvider:_moduleProvider];
|
||||||
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge];
|
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge];
|
||||||
[self addGestureRecognizer:_touchHandler];
|
[self addGestureRecognizer:_touchHandler];
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
13B0801F1A69489C00A75B9A /* RCTTextFieldManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080171A69489C00A75B9A /* RCTTextFieldManager.m */; };
|
13B0801F1A69489C00A75B9A /* RCTTextFieldManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080171A69489C00A75B9A /* RCTTextFieldManager.m */; };
|
||||||
13B080201A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080191A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m */; };
|
13B080201A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080191A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m */; };
|
||||||
13B080261A694A8400A75B9A /* RCTWrapperViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080241A694A8400A75B9A /* RCTWrapperViewController.m */; };
|
13B080261A694A8400A75B9A /* RCTWrapperViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080241A694A8400A75B9A /* RCTWrapperViewController.m */; };
|
||||||
|
13C156051AB1A2840079392D /* RCTWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13C156021AB1A2840079392D /* RCTWebView.m */; };
|
||||||
|
13C156061AB1A2840079392D /* RCTWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13C156041AB1A2840079392D /* RCTWebViewManager.m */; };
|
||||||
13E0674A1A70F434002CDEE1 /* RCTUIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E067491A70F434002CDEE1 /* RCTUIManager.m */; };
|
13E0674A1A70F434002CDEE1 /* RCTUIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E067491A70F434002CDEE1 /* RCTUIManager.m */; };
|
||||||
13E067551A70F44B002CDEE1 /* RCTShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E0674C1A70F44B002CDEE1 /* RCTShadowView.m */; };
|
13E067551A70F44B002CDEE1 /* RCTShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E0674C1A70F44B002CDEE1 /* RCTShadowView.m */; };
|
||||||
13E067561A70F44B002CDEE1 /* RCTViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E0674E1A70F44B002CDEE1 /* RCTViewManager.m */; };
|
13E067561A70F44B002CDEE1 /* RCTViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E0674E1A70F44B002CDEE1 /* RCTViewManager.m */; };
|
||||||
|
@ -124,6 +126,10 @@
|
||||||
13B080191A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIActivityIndicatorViewManager.m; sourceTree = "<group>"; };
|
13B080191A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIActivityIndicatorViewManager.m; sourceTree = "<group>"; };
|
||||||
13B080231A694A8400A75B9A /* RCTWrapperViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWrapperViewController.h; sourceTree = "<group>"; };
|
13B080231A694A8400A75B9A /* RCTWrapperViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWrapperViewController.h; sourceTree = "<group>"; };
|
||||||
13B080241A694A8400A75B9A /* RCTWrapperViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWrapperViewController.m; sourceTree = "<group>"; };
|
13B080241A694A8400A75B9A /* RCTWrapperViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWrapperViewController.m; sourceTree = "<group>"; };
|
||||||
|
13C156011AB1A2840079392D /* RCTWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebView.h; sourceTree = "<group>"; };
|
||||||
|
13C156021AB1A2840079392D /* RCTWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebView.m; sourceTree = "<group>"; };
|
||||||
|
13C156031AB1A2840079392D /* RCTWebViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebViewManager.h; sourceTree = "<group>"; };
|
||||||
|
13C156041AB1A2840079392D /* RCTWebViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebViewManager.m; sourceTree = "<group>"; };
|
||||||
13C325261AA63B6A0048765F /* RCTAutoInsetsProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAutoInsetsProtocol.h; sourceTree = "<group>"; };
|
13C325261AA63B6A0048765F /* RCTAutoInsetsProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAutoInsetsProtocol.h; sourceTree = "<group>"; };
|
||||||
13C325271AA63B6A0048765F /* RCTScrollableProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTScrollableProtocol.h; sourceTree = "<group>"; };
|
13C325271AA63B6A0048765F /* RCTScrollableProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTScrollableProtocol.h; sourceTree = "<group>"; };
|
||||||
13C325281AA63B6A0048765F /* RCTViewNodeProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTViewNodeProtocol.h; sourceTree = "<group>"; };
|
13C325281AA63B6A0048765F /* RCTViewNodeProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTViewNodeProtocol.h; sourceTree = "<group>"; };
|
||||||
|
@ -299,6 +305,10 @@
|
||||||
13E0674D1A70F44B002CDEE1 /* RCTViewManager.h */,
|
13E0674D1A70F44B002CDEE1 /* RCTViewManager.h */,
|
||||||
13E0674E1A70F44B002CDEE1 /* RCTViewManager.m */,
|
13E0674E1A70F44B002CDEE1 /* RCTViewManager.m */,
|
||||||
13C325281AA63B6A0048765F /* RCTViewNodeProtocol.h */,
|
13C325281AA63B6A0048765F /* RCTViewNodeProtocol.h */,
|
||||||
|
13C156011AB1A2840079392D /* RCTWebView.h */,
|
||||||
|
13C156021AB1A2840079392D /* RCTWebView.m */,
|
||||||
|
13C156031AB1A2840079392D /* RCTWebViewManager.h */,
|
||||||
|
13C156041AB1A2840079392D /* RCTWebViewManager.m */,
|
||||||
13B080231A694A8400A75B9A /* RCTWrapperViewController.h */,
|
13B080231A694A8400A75B9A /* RCTWrapperViewController.h */,
|
||||||
13B080241A694A8400A75B9A /* RCTWrapperViewController.m */,
|
13B080241A694A8400A75B9A /* RCTWrapperViewController.m */,
|
||||||
13E067531A70F44B002CDEE1 /* UIView+ReactKit.h */,
|
13E067531A70F44B002CDEE1 /* UIView+ReactKit.h */,
|
||||||
|
@ -480,7 +490,9 @@
|
||||||
83CBBA531A601E3B00E9B192 /* RCTUtils.m in Sources */,
|
83CBBA531A601E3B00E9B192 /* RCTUtils.m in Sources */,
|
||||||
14435CE61AAC4AE100FC20F4 /* RCTMapManager.m in Sources */,
|
14435CE61AAC4AE100FC20F4 /* RCTMapManager.m in Sources */,
|
||||||
83C911101AAE6521001323A3 /* RCTAnimationManager.m in Sources */,
|
83C911101AAE6521001323A3 /* RCTAnimationManager.m in Sources */,
|
||||||
|
13C156051AB1A2840079392D /* RCTWebView.m in Sources */,
|
||||||
83CBBA601A601EAA00E9B192 /* RCTBridge.m in Sources */,
|
83CBBA601A601EAA00E9B192 /* RCTBridge.m in Sources */,
|
||||||
|
13C156061AB1A2840079392D /* RCTWebViewManager.m in Sources */,
|
||||||
58114A161AAE854800E7D092 /* RCTPicker.m in Sources */,
|
58114A161AAE854800E7D092 /* RCTPicker.m in Sources */,
|
||||||
137327E81AA5CF210034F82E /* RCTTabBarItem.m in Sources */,
|
137327E81AA5CF210034F82E /* RCTTabBarItem.m in Sources */,
|
||||||
13E067551A70F44B002CDEE1 /* RCTShadowView.m in Sources */,
|
13E067551A70F44B002CDEE1 /* RCTShadowView.m in Sources */,
|
||||||
|
|
|
@ -343,10 +343,14 @@ CGFloat const ZINDEX_STICKY_HEADER = 50;
|
||||||
|
|
||||||
- (void)setContentInset:(UIEdgeInsets)contentInset
|
- (void)setContentInset:(UIEdgeInsets)contentInset
|
||||||
{
|
{
|
||||||
|
CGPoint contentOffset = _scrollView.contentOffset;
|
||||||
|
|
||||||
_contentInset = contentInset;
|
_contentInset = contentInset;
|
||||||
[RCTView autoAdjustInsetsForView:self
|
[RCTView autoAdjustInsetsForView:self
|
||||||
withScrollView:_scrollView
|
withScrollView:_scrollView
|
||||||
updateOffset:NO];
|
updateOffset:NO];
|
||||||
|
|
||||||
|
_scrollView.contentOffset = contentOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)scrollToOffset:(CGPoint)offset
|
- (void)scrollToOffset:(CGPoint)offset
|
||||||
|
@ -570,6 +574,39 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, RCTScrollEventTypeMove)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: setting several properties of UIScrollView has the effect of
|
||||||
|
// resetting its contentOffset to {0, 0}. To prevent this, we generate
|
||||||
|
// setters here that will record the contentOffset beforehand, and
|
||||||
|
// restore it after the property has been set.
|
||||||
|
|
||||||
|
#define RCT_SET_AND_PRESERVE_OFFSET(setter, type) \
|
||||||
|
- (void)setter:(type)value \
|
||||||
|
{ \
|
||||||
|
CGPoint contentOffset = _scrollView.contentOffset; \
|
||||||
|
[_scrollView setter:value]; \
|
||||||
|
_scrollView.contentOffset = contentOffset; \
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setAlwaysBounceHorizontal, BOOL)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setAlwaysBounceVertical, BOOL)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setBounces, BOOL)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setBouncesZoom, BOOL)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setCanCancelContentTouches, BOOL)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setDecelerationRate, CGFloat)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setDirectionalLockEnabled, BOOL)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setKeyboardDismissMode, UIScrollViewKeyboardDismissMode)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setMaximumZoomScale, CGFloat)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setMinimumZoomScale, CGFloat)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setPagingEnabled, BOOL)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setScrollEnabled, BOOL)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setScrollsToTop, BOOL)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setShowsHorizontalScrollIndicator, BOOL)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setShowsVerticalScrollIndicator, BOOL)
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setZoomScale, CGFloat);
|
||||||
|
RCT_SET_AND_PRESERVE_OFFSET(setScrollIndicatorInsets, UIEdgeInsets);
|
||||||
|
|
||||||
|
#pragma mark - Forward methods and properties to underlying UIScrollView
|
||||||
|
|
||||||
- (BOOL)respondsToSelector:(SEL)aSelector
|
- (BOOL)respondsToSelector:(SEL)aSelector
|
||||||
{
|
{
|
||||||
return [super respondsToSelector:aSelector] || [_scrollView respondsToSelector:aSelector];
|
return [super respondsToSelector:aSelector] || [_scrollView respondsToSelector:aSelector];
|
||||||
|
@ -577,13 +614,11 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, RCTScrollEventTypeMove)
|
||||||
|
|
||||||
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
|
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
|
||||||
{
|
{
|
||||||
// Pipe unrecognized properties to scrollview
|
|
||||||
[_scrollView setValue:value forKey:key];
|
[_scrollView setValue:value forKey:key];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)valueForUndefinedKey:(NSString *)key
|
- (id)valueForUndefinedKey:(NSString *)key
|
||||||
{
|
{
|
||||||
// Pipe unrecognized properties from scrollview
|
|
||||||
return [_scrollView valueForKey:key];
|
return [_scrollView valueForKey:key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,10 @@ RCT_EXPORT_VIEW_PROPERTY(showsHorizontalScrollIndicator)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(showsVerticalScrollIndicator)
|
RCT_EXPORT_VIEW_PROPERTY(showsVerticalScrollIndicator)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(stickyHeaderIndices);
|
RCT_EXPORT_VIEW_PROPERTY(stickyHeaderIndices);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(throttleScrollCallbackMS);
|
RCT_EXPORT_VIEW_PROPERTY(throttleScrollCallbackMS);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(zoomScale); // TODO: this needs to be set first because it resets other props like contentOffset
|
RCT_EXPORT_VIEW_PROPERTY(zoomScale);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(contentInset);
|
RCT_EXPORT_VIEW_PROPERTY(contentInset);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(scrollIndicatorInsets);
|
RCT_EXPORT_VIEW_PROPERTY(scrollIndicatorInsets);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(contentOffset);
|
RCT_REMAP_VIEW_PROPERTY(contentOffset, scrollView.contentOffset);
|
||||||
|
|
||||||
- (NSDictionary *)constantsToExport
|
- (NSDictionary *)constantsToExport
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import "RCTView.h"
|
||||||
|
|
||||||
|
@class RCTEventDispatcher;
|
||||||
|
|
||||||
|
@interface RCTWebView : RCTView
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSURL *URL;
|
||||||
|
@property (nonatomic, assign) UIEdgeInsets contentInset;
|
||||||
|
@property (nonatomic, assign) BOOL shouldInjectAJAXHandler;
|
||||||
|
@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets;
|
||||||
|
|
||||||
|
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
|
- (void)goForward;
|
||||||
|
- (void)goBack;
|
||||||
|
- (void)reload;
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,180 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import "RCTWebView.h"
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
#import "RCTAutoInsetsProtocol.h"
|
||||||
|
#import "RCTEventDispatcher.h"
|
||||||
|
#import "RCTLog.h"
|
||||||
|
#import "RCTUtils.h"
|
||||||
|
#import "RCTView.h"
|
||||||
|
#import "UIView+ReactKit.h"
|
||||||
|
|
||||||
|
@interface RCTWebView () <UIWebViewDelegate, RCTAutoInsetsProtocol>
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation RCTWebView
|
||||||
|
{
|
||||||
|
RCTEventDispatcher *_eventDispatcher;
|
||||||
|
UIWebView *_webView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
|
||||||
|
{
|
||||||
|
if ((self = [super initWithFrame:CGRectZero])) {
|
||||||
|
_automaticallyAdjustContentInsets = YES;
|
||||||
|
_contentInset = UIEdgeInsetsZero;
|
||||||
|
_eventDispatcher = eventDispatcher;
|
||||||
|
_webView = [[UIWebView alloc] initWithFrame:self.bounds];
|
||||||
|
_webView.delegate = self;
|
||||||
|
[self addSubview:_webView];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)goForward
|
||||||
|
{
|
||||||
|
[_webView goForward];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)goBack
|
||||||
|
{
|
||||||
|
[_webView goBack];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reload
|
||||||
|
{
|
||||||
|
[_webView reload];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setURL:(NSURL *)URL
|
||||||
|
{
|
||||||
|
// Because of the way React works, as pages redirect, we actually end up
|
||||||
|
// passing the redirect urls back here, so we ignore them if trying to load
|
||||||
|
// the same url. We'll expose a call to 'reload' to allow a user to load
|
||||||
|
// the existing page.
|
||||||
|
if ([URL isEqual:_webView.request.URL]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!URL) {
|
||||||
|
// Clear the webview
|
||||||
|
[_webView loadHTMLString:nil baseURL:nil];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[_webView loadRequest:[NSURLRequest requestWithURL:URL]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layoutSubviews
|
||||||
|
{
|
||||||
|
[super layoutSubviews];
|
||||||
|
_webView.frame = self.bounds;
|
||||||
|
[RCTView autoAdjustInsetsForView:self
|
||||||
|
withScrollView:_webView.scrollView
|
||||||
|
updateOffset:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setContentInset:(UIEdgeInsets)contentInset
|
||||||
|
{
|
||||||
|
_contentInset = contentInset;
|
||||||
|
[RCTView autoAdjustInsetsForView:self
|
||||||
|
withScrollView:_webView.scrollView
|
||||||
|
updateOffset:NO];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableDictionary *)baseEvent
|
||||||
|
{
|
||||||
|
NSURL *url = _webView.request.URL;
|
||||||
|
NSString *title = [_webView stringByEvaluatingJavaScriptFromString:@"document.title"];
|
||||||
|
NSMutableDictionary *event = [[NSMutableDictionary alloc] initWithDictionary: @{
|
||||||
|
@"target": self.reactTag,
|
||||||
|
@"url": url ? [url absoluteString] : @"",
|
||||||
|
@"loading" : @(_webView.loading),
|
||||||
|
@"title": title,
|
||||||
|
@"canGoBack": @([_webView canGoBack]),
|
||||||
|
@"canGoForward" : @([_webView canGoForward]),
|
||||||
|
}];
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - UIWebViewDelegate methods
|
||||||
|
|
||||||
|
static NSString *const RCTJSAJAXScheme = @"react-ajax";
|
||||||
|
|
||||||
|
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
|
||||||
|
navigationType:(UIWebViewNavigationType)navigationType
|
||||||
|
{
|
||||||
|
// We have this check to filter out iframe requests and whatnot
|
||||||
|
BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL];
|
||||||
|
if (isTopFrame) {
|
||||||
|
NSMutableDictionary *event = [self baseEvent];
|
||||||
|
[event addEntriesFromDictionary: @{
|
||||||
|
@"url": [request.URL absoluteString],
|
||||||
|
@"navigationType": @(navigationType)
|
||||||
|
}];
|
||||||
|
[_eventDispatcher sendInputEventWithName:@"topLoadingStart" body:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
// AJAX handler
|
||||||
|
return ![request.URL.scheme isEqualToString:RCTJSAJAXScheme];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
|
||||||
|
{
|
||||||
|
if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled) {
|
||||||
|
// NSURLErrorCancelled is reported when a page has a redirect OR if you load
|
||||||
|
// a new URL in the WebView before the previous one came back. We can just
|
||||||
|
// ignore these since they aren't real errors.
|
||||||
|
// http://stackoverflow.com/questions/1024748/how-do-i-fix-nsurlerrordomain-error-999-in-iphone-3-0-os
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSMutableDictionary *event = [self baseEvent];
|
||||||
|
[event addEntriesFromDictionary: @{
|
||||||
|
@"domain": error.domain,
|
||||||
|
@"code": @(error.code),
|
||||||
|
@"description": [error localizedDescription],
|
||||||
|
}];
|
||||||
|
[_eventDispatcher sendInputEventWithName:@"topLoadingError" body:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)webViewDidFinishLoad:(UIWebView *)webView
|
||||||
|
{
|
||||||
|
if (_shouldInjectAJAXHandler) {
|
||||||
|
|
||||||
|
// From http://stackoverflow.com/questions/5353278/uiwebviewdelegate-not-monitoring-xmlhttprequest
|
||||||
|
|
||||||
|
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"\
|
||||||
|
var s_ajaxListener = new Object(); \n\
|
||||||
|
s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open; \n\
|
||||||
|
s_ajaxListener.tempSend = XMLHttpRequest.prototype.send; \n\
|
||||||
|
s_ajaxListener.callback = function() { \n\
|
||||||
|
window.location.href = '%@://' + this.url; \n\
|
||||||
|
} \n\
|
||||||
|
XMLHttpRequest.prototype.open = function(a,b) { \n\
|
||||||
|
s_ajaxListener.tempOpen.apply(this, arguments); \n\
|
||||||
|
s_ajaxListener.method = a; \n\
|
||||||
|
s_ajaxListener.url = b; \n\
|
||||||
|
if (a.toLowerCase() === 'get') { \n\
|
||||||
|
s_ajaxListener.data = (b.split('?'))[1]; \n\
|
||||||
|
} \n\
|
||||||
|
} \n\
|
||||||
|
XMLHttpRequest.prototype.send = function(a,b) { \n\
|
||||||
|
s_ajaxListener.tempSend.apply(this, arguments); \n\
|
||||||
|
if (s_ajaxListener.method.toLowerCase() === 'post') { \n\
|
||||||
|
s_ajaxListener.data = a; \n\
|
||||||
|
} \n\
|
||||||
|
s_ajaxListener.callback(); \n\
|
||||||
|
} \n\
|
||||||
|
", RCTJSAJAXScheme]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// we only need the final 'finishLoad' call so only fire the event when we're actually done loading.
|
||||||
|
if (!webView.loading && ![webView.request.URL.absoluteString isEqualToString:@"about:blank"]) {
|
||||||
|
[_eventDispatcher sendInputEventWithName:@"topLoadingFinish" body:[self baseEvent]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,7 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import "RCTViewManager.h"
|
||||||
|
|
||||||
|
@interface RCTWebViewManager : RCTViewManager
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#import "RCTWebViewManager.h"
|
||||||
|
|
||||||
|
#import "RCTBridge.h"
|
||||||
|
#import "RCTSparseArray.h"
|
||||||
|
#import "RCTUIManager.h"
|
||||||
|
#import "RCTWebView.h"
|
||||||
|
|
||||||
|
@implementation RCTWebViewManager
|
||||||
|
|
||||||
|
- (UIView *)view
|
||||||
|
{
|
||||||
|
return [[RCTWebView alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_REMAP_VIEW_PROPERTY(url, URL);
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(contentInset);
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets);
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(shouldInjectAJAXHandler);
|
||||||
|
|
||||||
|
- (NSDictionary *)constantsToExport
|
||||||
|
{
|
||||||
|
return @{
|
||||||
|
@"NavigationType": @{
|
||||||
|
@"LinkClicked": @(UIWebViewNavigationTypeLinkClicked),
|
||||||
|
@"FormSubmitted": @(UIWebViewNavigationTypeFormSubmitted),
|
||||||
|
@"BackForward": @(UIWebViewNavigationTypeBackForward),
|
||||||
|
@"Reload": @(UIWebViewNavigationTypeReload),
|
||||||
|
@"FormResubmitted": @(UIWebViewNavigationTypeFormResubmitted),
|
||||||
|
@"Other": @(UIWebViewNavigationTypeOther)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)goBack:(NSNumber *)reactTag
|
||||||
|
{
|
||||||
|
RCT_EXPORT();
|
||||||
|
|
||||||
|
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
|
RCTWebView *view = viewRegistry[reactTag];
|
||||||
|
if (![view isKindOfClass:[RCTWebView class]]) {
|
||||||
|
RCTLogError(@"Invalid view returned from registry, expecting RKWebView, got: %@", view);
|
||||||
|
}
|
||||||
|
[view goBack];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)goForward:(NSNumber *)reactTag
|
||||||
|
{
|
||||||
|
RCT_EXPORT();
|
||||||
|
|
||||||
|
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
|
id view = viewRegistry[reactTag];
|
||||||
|
if (![view isKindOfClass:[RCTWebView class]]) {
|
||||||
|
RCTLogError(@"Invalid view returned from registry, expecting RKWebView, got: %@", view);
|
||||||
|
}
|
||||||
|
[view goForward];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)reload:(NSNumber *)reactTag
|
||||||
|
{
|
||||||
|
RCT_EXPORT();
|
||||||
|
|
||||||
|
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
|
||||||
|
RCTWebView *view = viewRegistry[reactTag];
|
||||||
|
if (![view isKindOfClass:[RCTWebView class]]) {
|
||||||
|
RCTLogMustFix(@"Invalid view returned from registry, expecting RKWebView, got: %@", view);
|
||||||
|
}
|
||||||
|
[view reload];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -22,6 +22,8 @@ function ModuleDescriptor(fields) {
|
||||||
|
|
||||||
this.isPolyfill = fields.isPolyfill || false;
|
this.isPolyfill = fields.isPolyfill || false;
|
||||||
|
|
||||||
|
this.isAsset = fields.isAsset || false;
|
||||||
|
|
||||||
this._fields = fields;
|
this._fields = fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,40 @@ describe('DependencyGraph', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pit('should get dependencies', function() {
|
||||||
|
var root = '/root';
|
||||||
|
fs.__setMockFilesystem({
|
||||||
|
'root': {
|
||||||
|
'index.js': [
|
||||||
|
'/**',
|
||||||
|
' * @providesModule index',
|
||||||
|
' */',
|
||||||
|
'require("image!a")'
|
||||||
|
].join('\n'),
|
||||||
|
'imgs': {
|
||||||
|
'a.png': ''
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var dgraph = new DependencyGraph({
|
||||||
|
roots: [root],
|
||||||
|
fileWatcher: fileWatcher,
|
||||||
|
assetRoots: ['/root/imgs']
|
||||||
|
});
|
||||||
|
return dgraph.load().then(function() {
|
||||||
|
expect(dgraph.getOrderedDependencies('/root/index.js'))
|
||||||
|
.toEqual([
|
||||||
|
{id: 'index', path: '/root/index.js', dependencies: ['image!a']},
|
||||||
|
{ id: 'image!a',
|
||||||
|
path: '/root/imgs/a.png',
|
||||||
|
dependencies: [],
|
||||||
|
isAsset: true
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
pit('should get recursive dependencies', function() {
|
pit('should get recursive dependencies', function() {
|
||||||
var root = '/root';
|
var root = '/root';
|
||||||
fs.__setMockFilesystem({
|
fs.__setMockFilesystem({
|
||||||
|
|
|
@ -28,12 +28,22 @@ var validateOpts = declareOpts({
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
assetRoots: {
|
||||||
|
type: 'array',
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
assetExts: {
|
||||||
|
type: 'array',
|
||||||
|
default: ['png'],
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function DependecyGraph(options) {
|
function DependecyGraph(options) {
|
||||||
var opts = validateOpts(options);
|
var opts = validateOpts(options);
|
||||||
|
|
||||||
this._roots = opts.roots;
|
this._roots = opts.roots;
|
||||||
|
this._assetRoots = opts.assetRoots;
|
||||||
|
this._assetExts = opts.assetExts;
|
||||||
this._ignoreFilePath = opts.ignoreFilePath;
|
this._ignoreFilePath = opts.ignoreFilePath;
|
||||||
this._fileWatcher = options.fileWatcher;
|
this._fileWatcher = options.fileWatcher;
|
||||||
|
|
||||||
|
@ -50,7 +60,16 @@ function DependecyGraph(options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DependecyGraph.prototype.load = function() {
|
DependecyGraph.prototype.load = function() {
|
||||||
return this._loading || (this._loading = this._search());
|
if (this._loading != null) {
|
||||||
|
return this._loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._loading = q.all([
|
||||||
|
this._search(),
|
||||||
|
this._buildAssetMap(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return this._loading;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,6 +134,15 @@ DependecyGraph.prototype.resolveDependency = function(
|
||||||
fromModule,
|
fromModule,
|
||||||
depModuleId
|
depModuleId
|
||||||
) {
|
) {
|
||||||
|
// Process asset requires.
|
||||||
|
var assetMatch = depModuleId.match(/^image!(.+)/);
|
||||||
|
if (assetMatch && assetMatch[1]) {
|
||||||
|
if (!this._assetMap[assetMatch[1]]) {
|
||||||
|
throw new Error('Cannot find asset: ' + assetMatch[1]);
|
||||||
|
}
|
||||||
|
return this._assetMap[assetMatch[1]];
|
||||||
|
}
|
||||||
|
|
||||||
var packageJson, modulePath, dep;
|
var packageJson, modulePath, dep;
|
||||||
|
|
||||||
// Package relative modules starts with '.' or '..'.
|
// Package relative modules starts with '.' or '..'.
|
||||||
|
@ -214,32 +242,13 @@ DependecyGraph.prototype._search = function() {
|
||||||
// 2. Filter the files and queue up the directories.
|
// 2. Filter the files and queue up the directories.
|
||||||
// 3. Process any package.json in the files
|
// 3. Process any package.json in the files
|
||||||
// 4. recur.
|
// 4. recur.
|
||||||
return readDir(dir)
|
return readAndStatDir(dir)
|
||||||
.then(function(files){
|
.spread(function(files, stats) {
|
||||||
return q.all(files.map(function(filePath) {
|
var modulePaths = files.filter(function(filePath, i) {
|
||||||
return realpath(path.join(dir, filePath)).catch(handleBrokenLink);
|
if (self._ignoreFilePath(filePath)) {
|
||||||
}));
|
|
||||||
})
|
|
||||||
.then(function(filePaths) {
|
|
||||||
filePaths = filePaths.filter(function(filePath) {
|
|
||||||
if (filePath == null) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !self._ignoreFilePath(filePath);
|
|
||||||
});
|
|
||||||
|
|
||||||
var statsP = filePaths.map(function(filePath) {
|
|
||||||
return lstat(filePath).catch(handleBrokenLink);
|
|
||||||
});
|
|
||||||
|
|
||||||
return [
|
|
||||||
filePaths,
|
|
||||||
q.all(statsP)
|
|
||||||
];
|
|
||||||
})
|
|
||||||
.spread(function(files, stats) {
|
|
||||||
var modulePaths = files.filter(function(filePath, i) {
|
|
||||||
if (stats[i].isDirectory()) {
|
if (stats[i].isDirectory()) {
|
||||||
self._queue.push(filePath);
|
self._queue.push(filePath);
|
||||||
return false;
|
return false;
|
||||||
|
@ -465,6 +474,19 @@ DependecyGraph.prototype._getAbsolutePath = function(filePath) {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DependecyGraph.prototype._buildAssetMap = function() {
|
||||||
|
if (this._assetRoots == null || this._assetRoots.length === 0) {
|
||||||
|
return q();
|
||||||
|
}
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
return buildAssetMap(this._assetRoots, this._assetExts)
|
||||||
|
.then(function(map) {
|
||||||
|
self._assetMap = map;
|
||||||
|
return map;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract all required modules from a `code` string.
|
* Extract all required modules from a `code` string.
|
||||||
*/
|
*/
|
||||||
|
@ -511,4 +533,70 @@ function handleBrokenLink(e) {
|
||||||
return q();
|
return q();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readAndStatDir(dir) {
|
||||||
|
return readDir(dir)
|
||||||
|
.then(function(files){
|
||||||
|
return q.all(files.map(function(filePath) {
|
||||||
|
return realpath(path.join(dir, filePath)).catch(handleBrokenLink);
|
||||||
|
}));
|
||||||
|
}).then(function(files) {
|
||||||
|
files = files.filter(function(f) {
|
||||||
|
return !!f;
|
||||||
|
});
|
||||||
|
|
||||||
|
var stats = files.map(function(filePath) {
|
||||||
|
return lstat(filePath).catch(handleBrokenLink);
|
||||||
|
});
|
||||||
|
|
||||||
|
return [
|
||||||
|
files,
|
||||||
|
q.all(stats),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a list of roots and list of extensions find all the files in
|
||||||
|
* the directory with that extension and build a map of those assets.
|
||||||
|
*/
|
||||||
|
function buildAssetMap(roots, exts) {
|
||||||
|
var queue = roots.slice(0);
|
||||||
|
var map = Object.create(null);
|
||||||
|
|
||||||
|
function search() {
|
||||||
|
var root = queue.shift();
|
||||||
|
|
||||||
|
if (root == null) {
|
||||||
|
return q(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
return readAndStatDir(root).spread(function(files, stats) {
|
||||||
|
files.forEach(function(file, i) {
|
||||||
|
if (stats[i].isDirectory()) {
|
||||||
|
queue.push(file);
|
||||||
|
} else {
|
||||||
|
var ext = path.extname(file).replace(/^\./, '');
|
||||||
|
if (exts.indexOf(ext) !== -1) {
|
||||||
|
var assetName = path.basename(file, '.' + ext);
|
||||||
|
if (map[assetName] != null) {
|
||||||
|
debug('Conflcting assets', assetName);
|
||||||
|
}
|
||||||
|
|
||||||
|
map[assetName] = new ModuleDescriptor({
|
||||||
|
id: 'image!' + assetName,
|
||||||
|
path: path.resolve(file),
|
||||||
|
isAsset: true,
|
||||||
|
dependencies: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return search();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return search();
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = DependecyGraph;
|
module.exports = DependecyGraph;
|
||||||
|
|
|
@ -17,7 +17,6 @@ var DEFINE_MODULE_CODE = [
|
||||||
].join('');
|
].join('');
|
||||||
|
|
||||||
var DEFINE_MODULE_REPLACE_RE = /_moduleName_|_code_|_deps_/g;
|
var DEFINE_MODULE_REPLACE_RE = /_moduleName_|_code_|_deps_/g;
|
||||||
|
|
||||||
var REL_REQUIRE_STMT = /require\(['"]([\.\/0-9A-Z_$\-]*)['"]\)/gi;
|
var REL_REQUIRE_STMT = /require\(['"]([\.\/0-9A-Z_$\-]*)['"]\)/gi;
|
||||||
|
|
||||||
var validateOpts = declareOpts({
|
var validateOpts = declareOpts({
|
||||||
|
@ -40,6 +39,10 @@ var validateOpts = declareOpts({
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: 'haste',
|
default: 'haste',
|
||||||
},
|
},
|
||||||
|
assetRoots: {
|
||||||
|
type: 'array',
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function HasteDependencyResolver(options) {
|
function HasteDependencyResolver(options) {
|
||||||
|
@ -51,11 +54,12 @@ function HasteDependencyResolver(options) {
|
||||||
|
|
||||||
this._depGraph = new DependencyGraph({
|
this._depGraph = new DependencyGraph({
|
||||||
roots: opts.projectRoots,
|
roots: opts.projectRoots,
|
||||||
|
assetRoots: opts.assetRoots,
|
||||||
ignoreFilePath: function(filepath) {
|
ignoreFilePath: function(filepath) {
|
||||||
return filepath.indexOf('__tests__') !== -1 ||
|
return filepath.indexOf('__tests__') !== -1 ||
|
||||||
(opts.blacklistRE && opts.blacklistRE.test(filepath));
|
(opts.blacklistRE && opts.blacklistRE.test(filepath));
|
||||||
},
|
},
|
||||||
fileWatcher: this._fileWatcher
|
fileWatcher: this._fileWatcher,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,11 @@ describe('Packager', function() {
|
||||||
var modules = [
|
var modules = [
|
||||||
{id: 'foo', path: '/root/foo.js', dependencies: []},
|
{id: 'foo', path: '/root/foo.js', dependencies: []},
|
||||||
{id: 'bar', path: '/root/bar.js', dependencies: []},
|
{id: 'bar', path: '/root/bar.js', dependencies: []},
|
||||||
|
{ id: 'image!img',
|
||||||
|
path: '/root/img/img.png',
|
||||||
|
isAsset: true,
|
||||||
|
dependencies: [],
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
getDependencies.mockImpl(function() {
|
getDependencies.mockImpl(function() {
|
||||||
|
@ -74,6 +79,15 @@ describe('Packager', function() {
|
||||||
'source /root/bar.js',
|
'source /root/bar.js',
|
||||||
'/root/bar.js'
|
'/root/bar.js'
|
||||||
]);
|
]);
|
||||||
|
expect(p.addModule.mock.calls[2]).toEqual([
|
||||||
|
'lol module.exports = ' +
|
||||||
|
JSON.stringify({ uri: 'img', isStatic: true}) +
|
||||||
|
'; lol',
|
||||||
|
'module.exports = ' +
|
||||||
|
JSON.stringify({ uri: 'img', isStatic: true}) +
|
||||||
|
';',
|
||||||
|
'/root/img/img.png'
|
||||||
|
]);
|
||||||
|
|
||||||
expect(p.finalize.mock.calls[0]).toEqual([
|
expect(p.finalize.mock.calls[0]).toEqual([
|
||||||
{runMainModule: true}
|
{runMainModule: true}
|
||||||
|
|
|
@ -44,6 +44,10 @@ var validateOpts = declareOpts({
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
assetRoots: {
|
||||||
|
type: 'array',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function Packager(options) {
|
function Packager(options) {
|
||||||
|
@ -56,7 +60,8 @@ function Packager(options) {
|
||||||
blacklistRE: opts.blacklistRE,
|
blacklistRE: opts.blacklistRE,
|
||||||
polyfillModuleNames: opts.polyfillModuleNames,
|
polyfillModuleNames: opts.polyfillModuleNames,
|
||||||
nonPersistent: opts.nonPersistent,
|
nonPersistent: opts.nonPersistent,
|
||||||
moduleFormat: opts.moduleFormat
|
moduleFormat: opts.moduleFormat,
|
||||||
|
assetRoots: opts.assetRoots,
|
||||||
});
|
});
|
||||||
|
|
||||||
this._transformer = new Transformer({
|
this._transformer = new Transformer({
|
||||||
|
@ -118,10 +123,18 @@ Packager.prototype.getDependencies = function(main, isDev) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Packager.prototype._transformModule = function(module) {
|
Packager.prototype._transformModule = function(module) {
|
||||||
|
var transform;
|
||||||
|
|
||||||
|
if (module.isAsset) {
|
||||||
|
transform = q(generateAssetModule(module));
|
||||||
|
} else {
|
||||||
|
transform = this._transformer.loadFileAndTransform(
|
||||||
|
path.resolve(module.path)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
var resolver = this._resolver;
|
var resolver = this._resolver;
|
||||||
return this._transformer.loadFileAndTransform(
|
return transform.then(function(transformed) {
|
||||||
path.resolve(module.path)
|
|
||||||
).then(function(transformed) {
|
|
||||||
return _.extend(
|
return _.extend(
|
||||||
{},
|
{},
|
||||||
transformed,
|
transformed,
|
||||||
|
@ -140,5 +153,17 @@ Packager.prototype.getGraphDebugInfo = function() {
|
||||||
return this._resolver.getDebugInfo();
|
return this._resolver.getDebugInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function generateAssetModule(module) {
|
||||||
|
var code = 'module.exports = ' + JSON.stringify({
|
||||||
|
uri: module.id.replace(/^[^!]+!/, ''),
|
||||||
|
isStatic: true,
|
||||||
|
}) + ';';
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: code,
|
||||||
|
sourceCode: code,
|
||||||
|
sourcePath: module.path,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = Packager;
|
module.exports = Packager;
|
||||||
|
|
|
@ -43,6 +43,10 @@ var validateOpts = declareOpts({
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
assetRoots: {
|
||||||
|
type: 'array',
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function Server(options) {
|
function Server(options) {
|
||||||
|
|
Loading…
Reference in New Issue