From 41ae2314ceade2113a91906aa5b84b5bd9036fa5 Mon Sep 17 00:00:00 2001 From: Christopher Chedeau Date: Sat, 14 Mar 2015 10:52:40 -0700 Subject: [PATCH] Updates from Sat 14 Mar - Unforked RKWebView | Nick Lockwood - [ReactNative] Add integration test stuff | Spencer Ahrens - [ReactNative] AlertIOS.alert and examples | Eric Vicenti - [react-packager] Implement image loading i.e. ix('img') -> require('image!img'); | Amjad Masad - Fixed scrollOffset bug | Nick Lockwood - [React Native] Update 2048 | Alex Akers - deepDiffer should support explicitly undefined values | Thomas Aylott --- Examples/2048/Game2048.js | 66 +- Examples/2048/main.m | 2 +- Examples/UIExplorer/AlertIOSExample.js | 98 +++ Examples/UIExplorer/UIExplorerList.js | 2 + Examples/UIExplorer/WebViewExample.js | 264 +++++++ IntegrationTests/AppDelegate.h | 10 + IntegrationTests/AppDelegate.m | 44 ++ IntegrationTests/Base.lproj/LaunchScreen.xib | 42 ++ .../AppIcon.appiconset/Contents.json | 44 ++ .../AppIcon.appiconset/uie_icon@2x-1.png | Bin 0 -> 31759 bytes .../AppIcon.appiconset/uie_icon@2x-2.png | Bin 0 -> 31759 bytes .../AppIcon.appiconset/uie_icon@2x-3.png | Bin 0 -> 31759 bytes .../AppIcon.appiconset/uie_icon@2x-4.png | Bin 0 -> 31759 bytes .../AppIcon.appiconset/uie_icon@2x-5.png | Bin 0 -> 31759 bytes .../AppIcon.appiconset/uie_icon@2x.png | Bin 0 -> 31759 bytes IntegrationTests/Info.plist | 42 ++ .../IntegrationTestHarnessTest.js | 57 ++ .../project.pbxproj | 651 ++++++++++++++++++ IntegrationTests/IntegrationTestsApp.js | 84 +++ .../IntegrationTestsTests/Info.plist | 24 + .../IntegrationTestsTests.m | 40 ++ IntegrationTests/main.m | 10 + Libraries/Animation/Animation.js | 5 +- Libraries/Animation/AnimationMixin.js | 3 +- .../Components/WebView/WebView.android.js | 169 +++++ Libraries/Components/WebView/WebView.ios.js | 182 +++++ .../RCTTest/RCTTest.xcodeproj/project.pbxproj | 264 +++++++ Libraries/RCTTest/RCTTestModule.h | 9 + Libraries/RCTTest/RCTTestModule.m | 14 + Libraries/RCTTest/RCTTestRunner.h | 14 + Libraries/RCTTest/RCTTestRunner.m | 64 ++ Libraries/Utilities/AlertIOS.js | 77 +++ Libraries/Utilities/differ/deepDiffer.js | 2 +- Libraries/react-native/react-native.js | 2 + ReactKit/Base/RCTRedBox.h | 2 + ReactKit/Base/RCTRedBox.m | 12 +- ReactKit/Base/RCTRootView.h | 11 +- ReactKit/Base/RCTRootView.m | 2 +- ReactKit/ReactKit.xcodeproj/project.pbxproj | 12 + ReactKit/Views/RCTScrollView.m | 39 +- ReactKit/Views/RCTScrollViewManager.m | 4 +- ReactKit/Views/RCTWebView.h | 20 + ReactKit/Views/RCTWebView.m | 180 +++++ ReactKit/Views/RCTWebViewManager.h | 7 + ReactKit/Views/RCTWebViewManager.m | 76 ++ .../DependencyResolver/ModuleDescriptor.js | 2 + .../__tests__/DependencyGraph-test.js | 34 + .../haste/DependencyGraph/index.js | 136 +++- .../src/DependencyResolver/haste/index.js | 8 +- .../src/Packager/__tests__/Packager-test.js | 14 + packager/react-packager/src/Packager/index.js | 33 +- packager/react-packager/src/Server/index.js | 4 + 52 files changed, 2807 insertions(+), 74 deletions(-) create mode 100644 Examples/UIExplorer/AlertIOSExample.js create mode 100644 Examples/UIExplorer/WebViewExample.js create mode 100644 IntegrationTests/AppDelegate.h create mode 100644 IntegrationTests/AppDelegate.m create mode 100644 IntegrationTests/Base.lproj/LaunchScreen.xib create mode 100644 IntegrationTests/Images.xcassets/AppIcon.appiconset/Contents.json create mode 100644 IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-1.png create mode 100644 IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-2.png create mode 100644 IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-3.png create mode 100644 IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-4.png create mode 100644 IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-5.png create mode 100644 IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x.png create mode 100644 IntegrationTests/Info.plist create mode 100644 IntegrationTests/IntegrationTestHarnessTest.js create mode 100644 IntegrationTests/IntegrationTests.xcodeproj/project.pbxproj create mode 100644 IntegrationTests/IntegrationTestsApp.js create mode 100644 IntegrationTests/IntegrationTestsTests/Info.plist create mode 100644 IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m create mode 100644 IntegrationTests/main.m create mode 100644 Libraries/Components/WebView/WebView.android.js create mode 100644 Libraries/Components/WebView/WebView.ios.js create mode 100644 Libraries/RCTTest/RCTTest.xcodeproj/project.pbxproj create mode 100644 Libraries/RCTTest/RCTTestModule.h create mode 100644 Libraries/RCTTest/RCTTestModule.m create mode 100644 Libraries/RCTTest/RCTTestRunner.h create mode 100644 Libraries/RCTTest/RCTTestRunner.m create mode 100644 Libraries/Utilities/AlertIOS.js create mode 100644 ReactKit/Views/RCTWebView.h create mode 100644 ReactKit/Views/RCTWebView.m create mode 100644 ReactKit/Views/RCTWebViewManager.h create mode 100644 ReactKit/Views/RCTWebViewManager.m diff --git a/Examples/2048/Game2048.js b/Examples/2048/Game2048.js index 4337aee91..e6b7fa6d4 100644 --- a/Examples/2048/Game2048.js +++ b/Examples/2048/Game2048.js @@ -15,20 +15,20 @@ var { View, } = React; -var GameBoard = require('./GameBoard'); +var GameBoard = require('GameBoard'); var TouchableBounce = require('TouchableBounce'); var BOARD_PADDING = 3; var CELL_MARGIN = 4; var CELL_SIZE = 60; -var Cell = React.createClass({ - render: function() { +class Cell extends React.Component { + render() { return ; } -}); +} -var Board = React.createClass({ +class Board extends React.Component { render() { return ( @@ -40,12 +40,10 @@ var Board = React.createClass({ ); } -}); +} -var Tile = React.createClass({ - mixins: [Animation.Mixin], - - calculateOffset() { +class Tile extends React.Component { + calculateOffset(): {top: number; left: number; opacity: number} { var tile = this.props.tile; var pos = (i) => { @@ -59,6 +57,7 @@ var Tile = React.createClass({ var offset = { top: pos(tile.toRow()), left: pos(tile.toColumn()), + opacity: 1, }; if (tile.isNew()) { @@ -68,18 +67,18 @@ var Tile = React.createClass({ animationPosition(tile.toColumn()), animationPosition(tile.toRow()), ]; - this.startAnimation('this', 100, 0, 'easeInOutQuad', {position: point}); + Animation.startAnimation(this.refs['this'], 100, 0, 'easeInOutQuad', {position: point}); } return offset; - }, + } componentDidMount() { setTimeout(() => { - this.startAnimation('this', 300, 0, 'easeInOutQuad', {scaleXY: [1, 1]}); - this.startAnimation('this', 100, 0, 'easeInOutQuad', {opacity: 1}); + Animation.startAnimation(this.refs['this'], 300, 0, 'easeInOutQuad', {scaleXY: [1, 1]}); + Animation.startAnimation(this.refs['this'], 100, 0, 'easeInOutQuad', {opacity: 1}); }, 0); - }, + } render() { var tile = this.props.tile; @@ -103,9 +102,9 @@ var Tile = React.createClass({ ); } -}); +} -var GameEndOverlay = React.createClass({ +class GameEndOverlay extends React.Component { render() { var board = this.props.board; @@ -127,27 +126,30 @@ var GameEndOverlay = React.createClass({ ); } -}); +} -var Game2048 = React.createClass({ - getInitialState() { - return { board: new GameBoard() }; - }, +class Game2048 extends React.Component { + constructor(props) { + super(props); + this.state = { + board: new GameBoard(), + }; + } restartGame() { - this.setState(this.getInitialState()); - }, + this.setState({board: new GameBoard()}); + } - handleTouchStart(event) { + handleTouchStart(event: Object) { if (this.state.board.hasWon()) { return; } this.startX = event.nativeEvent.pageX; this.startY = event.nativeEvent.pageY; - }, + } - handleTouchEnd(event) { + handleTouchEnd(event: Object) { if (this.state.board.hasWon()) { return; } @@ -165,7 +167,7 @@ var Game2048 = React.createClass({ if (direction !== -1) { this.setState({board: this.state.board.move(direction)}); } - }, + } render() { var tiles = this.state.board.tiles @@ -175,16 +177,16 @@ var Game2048 = React.createClass({ return ( + onTouchStart={(event) => this.handleTouchStart(event)} + onTouchEnd={(event) => this.handleTouchEnd(event)}> {tiles} - + this.restartGame()} /> ); } -}); +} var styles = StyleSheet.create({ container: { diff --git a/Examples/2048/main.m b/Examples/2048/main.m index a43b55738..3c8987ce3 100644 --- a/Examples/2048/main.m +++ b/Examples/2048/main.m @@ -6,6 +6,6 @@ int main(int argc, char * argv[]) { @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } diff --git a/Examples/UIExplorer/AlertIOSExample.js b/Examples/UIExplorer/AlertIOSExample.js new file mode 100644 index 000000000..a2b92d975 --- /dev/null +++ b/Examples/UIExplorer/AlertIOSExample.js @@ -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 ( + + AlertIOS.alert( + 'Foo Title', + 'My Alert Msg' + )}> + + Alert with message and default button + + + AlertIOS.alert( + null, + null, + [ + {text: 'Button', onPress: () => console.log('Button Pressed!')}, + ] + )}> + + Alert with only one button + + + AlertIOS.alert( + 'Foo Title', + 'My Alert Msg', + [ + {text: 'Foo', onPress: () => console.log('Foo Pressed!')}, + {text: 'Bar', onPress: () => console.log('Bar Pressed!')}, + ] + )}> + + Alert with two buttons + + + 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!')}, + ] + )}> + + Alert with 3 buttons + + + AlertIOS.alert( + 'Foo Title', + 'My Alert Msg', + '..............'.split('').map((dot, index) => ({ + text: 'Button ' + index, + onPress: () => console.log('Pressed ' + index) + })) + )}> + + Alert with too many buttons + + + + ); + }, +}]; + +var styles = StyleSheet.create({ + wrapper: { + borderRadius: 5, + marginBottom: 5, + }, + button: { + backgroundColor: '#eeeeee', + padding: 10, + }, +}); diff --git a/Examples/UIExplorer/UIExplorerList.js b/Examples/UIExplorer/UIExplorerList.js index 59653055e..b7108681e 100644 --- a/Examples/UIExplorer/UIExplorerList.js +++ b/Examples/UIExplorer/UIExplorerList.js @@ -40,7 +40,9 @@ var EXAMPLES = [ require('./AsyncStorageExample'), require('./CameraRollExample.ios'), require('./MapViewExample'), + require('./WebViewExample'), require('./AppStateIOSExample'), + require('./AlertIOSExample'), require('./AdSupportIOSExample'), require('./AppStateExample'), require('./ActionSheetIOSExample'), diff --git a/Examples/UIExplorer/WebViewExample.js b/Examples/UIExplorer/WebViewExample.js new file mode 100644 index 000000000..4b7a1513d --- /dev/null +++ b/Examples/UIExplorer/WebViewExample.js @@ -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 ( + + + + + + {'<'} + + + + + + + {'>'} + + + + + + + + Go! + + + + + + + {this.state.status} + + + ); + }, + + 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 ( + + + Error loading page + + + {'Domain: ' + errorDomain} + + + {'Error Code: ' + errorCode} + + + {'Description: ' + errorDesc} + + + ); + }, + + renderLoadingView: function() { + return ( + + + + ); + }, + + 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 = ''; +exports.description = 'Base component to display web content'; +exports.examples = [ + { + title: 'WebView', + render() { return ; } + } +]; diff --git a/IntegrationTests/AppDelegate.h b/IntegrationTests/AppDelegate.h new file mode 100644 index 000000000..f0ec66bdb --- /dev/null +++ b/IntegrationTests/AppDelegate.h @@ -0,0 +1,10 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import + +@interface AppDelegate : UIResponder + +@property (nonatomic, strong) UIWindow *window; + +@end + diff --git a/IntegrationTests/AppDelegate.m b/IntegrationTests/AppDelegate.m new file mode 100644 index 000000000..db988faf8 --- /dev/null +++ b/IntegrationTests/AppDelegate.m @@ -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 diff --git a/IntegrationTests/Base.lproj/LaunchScreen.xib b/IntegrationTests/Base.lproj/LaunchScreen.xib new file mode 100644 index 000000000..52cc0828d --- /dev/null +++ b/IntegrationTests/Base.lproj/LaunchScreen.xib @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IntegrationTests/Images.xcassets/AppIcon.appiconset/Contents.json b/IntegrationTests/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..413d60e76 --- /dev/null +++ b/IntegrationTests/Images.xcassets/AppIcon.appiconset/Contents.json @@ -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" + } +} \ No newline at end of file diff --git a/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-1.png b/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-1.png new file mode 100644 index 0000000000000000000000000000000000000000..08a42699daa9ca2149e641e7236b63bf74bdb5f6 GIT binary patch literal 31759 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 literal 0 HcmV?d00001 diff --git a/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-2.png b/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-2.png new file mode 100644 index 0000000000000000000000000000000000000000..08a42699daa9ca2149e641e7236b63bf74bdb5f6 GIT binary patch literal 31759 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 literal 0 HcmV?d00001 diff --git a/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-3.png b/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-3.png new file mode 100644 index 0000000000000000000000000000000000000000..08a42699daa9ca2149e641e7236b63bf74bdb5f6 GIT binary patch literal 31759 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 literal 0 HcmV?d00001 diff --git a/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-4.png b/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-4.png new file mode 100644 index 0000000000000000000000000000000000000000..08a42699daa9ca2149e641e7236b63bf74bdb5f6 GIT binary patch literal 31759 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 literal 0 HcmV?d00001 diff --git a/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-5.png b/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x-5.png new file mode 100644 index 0000000000000000000000000000000000000000..08a42699daa9ca2149e641e7236b63bf74bdb5f6 GIT binary patch literal 31759 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 literal 0 HcmV?d00001 diff --git a/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x.png b/IntegrationTests/Images.xcassets/AppIcon.appiconset/uie_icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..08a42699daa9ca2149e641e7236b63bf74bdb5f6 GIT binary patch literal 31759 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 literal 0 HcmV?d00001 diff --git a/IntegrationTests/Info.plist b/IntegrationTests/Info.plist new file mode 100644 index 000000000..245054621 --- /dev/null +++ b/IntegrationTests/Info.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.facebook.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + NSLocationWhenInUseUsageDescription + You need to add NSLocationWhenInUseUsageDescription key in Info.plist to enable geolocation, otherwise it is going to *fail silently*! + UIViewControllerBasedStatusBarAppearance + + + diff --git a/IntegrationTests/IntegrationTestHarnessTest.js b/IntegrationTests/IntegrationTestHarnessTest.js new file mode 100644 index 000000000..5b6e78838 --- /dev/null +++ b/IntegrationTests/IntegrationTestHarnessTest.js @@ -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 ( + + + {this.constructor.displayName + ': '} + {this.state.done ? 'Done' : 'Testing...'} + + + ); + } +}); + +module.exports = IntegrationTestHarnessTest; diff --git a/IntegrationTests/IntegrationTests.xcodeproj/project.pbxproj b/IntegrationTests/IntegrationTests.xcodeproj/project.pbxproj new file mode 100644 index 000000000..c850360b1 --- /dev/null +++ b/IntegrationTests/IntegrationTests.xcodeproj/project.pbxproj @@ -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 = ""; }; + 004D28A21AAF61C70097A701 /* IntegrationTestsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IntegrationTestsTests.m; sourceTree = ""; }; + 13417FE31AA91428003F314A /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../Libraries/Image/RCTImage.xcodeproj; sourceTree = ""; }; + 13417FEA1AA914B8003F314A /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../Libraries/Text/RCTText.xcodeproj; sourceTree = ""; }; + 13417FFA1AA91531003F314A /* ReactKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactKit.xcodeproj; path = ../ReactKit/ReactKit.xcodeproj; sourceTree = ""; }; + 134180261AA91779003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = ""; }; + 134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAdSupport.xcodeproj; path = ../Libraries/AdSupport/RCTAdSupport.xcodeproj; sourceTree = ""; }; + 134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../Libraries/GeoLocation/RCTGeolocation.xcodeproj; sourceTree = ""; }; + 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 = ""; }; + 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 580C37891AB104AF0015E709 /* RCTTest.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTTest.xcodeproj; path = ../Libraries/RCTTest/RCTTest.xcodeproj; sourceTree = ""; }; +/* 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 = ""; + }; + 004D28A01AAF61C70097A701 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 004D28A11AAF61C70097A701 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 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 = ""; + }; + 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 = ""; + }; + 580C37421AB0F5320015E709 /* Products */ = { + isa = PBXGroup; + children = ( + 580C37461AB0F5320015E709 /* libReactKit.a */, + ); + name = Products; + sourceTree = ""; + }; + 580C37471AB0F54A0015E709 /* Products */ = { + isa = PBXGroup; + children = ( + 580C374B1AB0F54A0015E709 /* libRCTAdSupport.a */, + ); + name = Products; + sourceTree = ""; + }; + 580C374C1AB0F55C0015E709 /* Products */ = { + isa = PBXGroup; + children = ( + 580C37501AB0F55C0015E709 /* libRCTGeolocation.a */, + ); + name = Products; + sourceTree = ""; + }; + 580C37511AB0F56E0015E709 /* Products */ = { + isa = PBXGroup; + children = ( + 580C37551AB0F56E0015E709 /* libRCTImage.a */, + ); + name = Products; + sourceTree = ""; + }; + 580C37561AB0F5970015E709 /* Products */ = { + isa = PBXGroup; + children = ( + 580C375A1AB0F5970015E709 /* libRCTNetwork.a */, + ); + name = Products; + sourceTree = ""; + }; + 580C375B1AB0F5D10015E709 /* Products */ = { + isa = PBXGroup; + children = ( + 580C375F1AB0F5D10015E709 /* libRCTText.a */, + ); + name = Products; + sourceTree = ""; + }; + 580C378A1AB104AF0015E709 /* Products */ = { + isa = PBXGroup; + children = ( + 580C378F1AB104B00015E709 /* libRCTTest.a */, + ); + name = Products; + sourceTree = ""; + }; + 83CBB9F61A601CBA00E9B192 = { + isa = PBXGroup; + children = ( + 13B07FAE1A68108700A75B9A /* IntegrationTests */, + 1316A21D1AA397F400C0188E /* Libraries */, + 004D289F1AAF61C70097A701 /* IntegrationTestsTests */, + 83CBBA001A601CBA00E9B192 /* Products */, + ); + sourceTree = ""; + }; + 83CBBA001A601CBA00E9B192 /* Products */ = { + isa = PBXGroup; + children = ( + 13B07F961A680F5B00A75B9A /* IntegrationTests.app */, + 004D289E1AAF61C70097A701 /* IntegrationTestsTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; +/* 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 = ""; + }; +/* 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 */; +} diff --git a/IntegrationTests/IntegrationTestsApp.js b/IntegrationTests/IntegrationTestsApp.js new file mode 100644 index 000000000..ee60aa388 --- /dev/null +++ b/IntegrationTests/IntegrationTestsApp.js @@ -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 ( + + + + ); + } + return ( + + + 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. + + + + {TESTS.map((test) => [ + this.setState({test})}> + + + {test.displayName} + + + , + + ])} + + + ); + } +}); + +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); diff --git a/IntegrationTests/IntegrationTestsTests/Info.plist b/IntegrationTests/IntegrationTestsTests/Info.plist new file mode 100644 index 000000000..87e3a6175 --- /dev/null +++ b/IntegrationTests/IntegrationTestsTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.facebook.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m b/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m new file mode 100644 index 000000000..9d9020f7d --- /dev/null +++ b/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m @@ -0,0 +1,40 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import +#import + +#import + +#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 diff --git a/IntegrationTests/main.m b/IntegrationTests/main.m new file mode 100644 index 000000000..357a233b1 --- /dev/null +++ b/IntegrationTests/main.m @@ -0,0 +1,10 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/Libraries/Animation/Animation.js b/Libraries/Animation/Animation.js index 80029f148..30624266d 100644 --- a/Libraries/Animation/Animation.js +++ b/Libraries/Animation/Animation.js @@ -23,10 +23,11 @@ var Animation = { ): number { var nodeHandle = +node.getNodeHandle(); 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); }, }; diff --git a/Libraries/Animation/AnimationMixin.js b/Libraries/Animation/AnimationMixin.js index ff29e2735..56f63fb8e 100644 --- a/Libraries/Animation/AnimationMixin.js +++ b/Libraries/Animation/AnimationMixin.js @@ -34,7 +34,8 @@ var AnimationMixin = { var nodeHandle = +ref.getNodeHandle(); 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) { diff --git a/Libraries/Components/WebView/WebView.android.js b/Libraries/Components/WebView/WebView.android.js new file mode 100644 index 000000000..8190258ae --- /dev/null +++ b/Libraries/Components/WebView/WebView.android.js @@ -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 = + ; + + return ( + + {webView} + {otherView} + + ); + }, + + 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; diff --git a/Libraries/Components/WebView/WebView.ios.js b/Libraries/Components/WebView/WebView.ios.js new file mode 100644 index 000000000..ff916f8e7 --- /dev/null +++ b/Libraries/Components/WebView/WebView.ios.js @@ -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 = + ; + + return ( + + {webView} + {otherView} + + ); + }, + + 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; diff --git a/Libraries/RCTTest/RCTTest.xcodeproj/project.pbxproj b/Libraries/RCTTest/RCTTest.xcodeproj/project.pbxproj new file mode 100644 index 000000000..f377b4c98 --- /dev/null +++ b/Libraries/RCTTest/RCTTest.xcodeproj/project.pbxproj @@ -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 = ""; }; + 585135341AB3C56F00882537 /* RCTTestModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTestModule.m; sourceTree = ""; }; + 585135351AB3C56F00882537 /* RCTTestRunner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTestRunner.h; sourceTree = ""; }; + 585135361AB3C56F00882537 /* RCTTestRunner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTestRunner.m; sourceTree = ""; }; +/* 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 = ""; + }; + 580C37701AB104AF0015E709 /* Products */ = { + isa = PBXGroup; + children = ( + 580C376F1AB104AF0015E709 /* libRCTTest.a */, + ); + name = Products; + sourceTree = ""; + }; +/* 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 */; +} diff --git a/Libraries/RCTTest/RCTTestModule.h b/Libraries/RCTTest/RCTTestModule.h new file mode 100644 index 000000000..f439df7b2 --- /dev/null +++ b/Libraries/RCTTest/RCTTestModule.h @@ -0,0 +1,9 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import "RCTBridgeModule.h" + +@interface RCTTestModule : NSObject + +@property (nonatomic, readonly, getter=isDone) BOOL done; + +@end diff --git a/Libraries/RCTTest/RCTTestModule.m b/Libraries/RCTTest/RCTTestModule.m new file mode 100644 index 000000000..eeb73734c --- /dev/null +++ b/Libraries/RCTTest/RCTTestModule.m @@ -0,0 +1,14 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import "RCTTestModule.h" + +@implementation RCTTestModule + +- (void)markTestCompleted +{ + RCT_EXPORT(); + + _done = YES; +} + +@end diff --git a/Libraries/RCTTest/RCTTestRunner.h b/Libraries/RCTTest/RCTTestRunner.h new file mode 100644 index 000000000..a774088dc --- /dev/null +++ b/Libraries/RCTTest/RCTTestRunner.h @@ -0,0 +1,14 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import + +@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 diff --git a/Libraries/RCTTest/RCTTestRunner.m b/Libraries/RCTTest/RCTTestRunner.m new file mode 100644 index 000000000..3fec65b9e --- /dev/null +++ b/Libraries/RCTTest/RCTTestRunner.m @@ -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 diff --git a/Libraries/Utilities/AlertIOS.js b/Libraries/Utilities/AlertIOS.js new file mode 100644 index 000000000..ee0bb2d0b --- /dev/null +++ b/Libraries/Utilities/AlertIOS.js @@ -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; diff --git a/Libraries/Utilities/differ/deepDiffer.js b/Libraries/Utilities/differ/deepDiffer.js index 97c3f516f..e118097ab 100644 --- a/Libraries/Utilities/differ/deepDiffer.js +++ b/Libraries/Utilities/differ/deepDiffer.js @@ -38,7 +38,7 @@ var deepDiffer = function(one: any, two: any): bool { for (var twoKey in two) { // The only case we haven't checked yet is keys that are in two but aren't // in one, which means they are different. - if (one[twoKey] === undefined) { + if (one[twoKey] === undefined && two[twoKey] !== undefined) { return true; } } diff --git a/Libraries/react-native/react-native.js b/Libraries/react-native/react-native.js index 48217795f..6f0b22df5 100644 --- a/Libraries/react-native/react-native.js +++ b/Libraries/react-native/react-native.js @@ -9,6 +9,7 @@ var ReactNative = { ...require('React'), Animation: require('Animation'), ActivityIndicatorIOS: require('ActivityIndicatorIOS'), + AlertIOS: require('AlertIOS'), AppRegistry: require('AppRegistry'), AppState: require('AppState'), AppStateIOS: require('AppStateIOS'), @@ -36,6 +37,7 @@ var ReactNative = { TouchableOpacity: require('TouchableOpacity'), TouchableWithoutFeedback: require('TouchableWithoutFeedback'), View: require('View'), + WebView: require('WebView'), invariant: require('invariant'), ix: require('ix'), }; diff --git a/ReactKit/Base/RCTRedBox.h b/ReactKit/Base/RCTRedBox.h index 82137eb06..c13ac729b 100644 --- a/ReactKit/Base/RCTRedBox.h +++ b/ReactKit/Base/RCTRedBox.h @@ -11,6 +11,8 @@ - (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack; - (void)updateErrorMessage:(NSString *)message withStack:(NSArray *)stack; +- (NSString *)currentErrorMessage; + - (void)dismiss; @end diff --git a/ReactKit/Base/RCTRedBox.m b/ReactKit/Base/RCTRedBox.m index 93a73087e..1d037cd4f 100644 --- a/ReactKit/Base/RCTRedBox.m +++ b/ReactKit/Base/RCTRedBox.m @@ -6,6 +6,8 @@ @interface RCTRedBoxWindow : UIWindow +@property (nonatomic, copy) NSString *lastErrorMessage; + @end @implementation RCTRedBoxWindow @@ -13,7 +15,6 @@ UIView *_rootView; UITableView *_stackTraceTableView; - NSString *_lastErrorMessage; NSArray *_lastStackTrace; UITableViewCell *_cachedMessageCell; @@ -289,6 +290,15 @@ } +- (NSString *)currentErrorMessage +{ + if (_window && !_window.hidden) { + return _window.lastErrorMessage; + } else { + return nil; + } +} + - (void)dismiss { [_window dismiss]; diff --git a/ReactKit/Base/RCTRootView.h b/ReactKit/Base/RCTRootView.h index 240c000c3..3fc0be165 100644 --- a/ReactKit/Base/RCTRootView.h +++ b/ReactKit/Base/RCTRootView.h @@ -2,6 +2,8 @@ #import +#import "RCTBridge.h" + @interface RCTRootView : UIView /** @@ -19,13 +21,20 @@ */ @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 * is first loaded. Defaults to nil/empty. */ @property (nonatomic, copy) NSDictionary *initialProperties; -/** +/** * The class of the RCTJavaScriptExecutor to use with this view. * If not specified, it will default to using RCTContextExecutor. * Changes will take effect next time the bundle is reloaded. diff --git a/ReactKit/Base/RCTRootView.m b/ReactKit/Base/RCTRootView.m index 5f0698e32..c62793d50 100644 --- a/ReactKit/Base/RCTRootView.m +++ b/ReactKit/Base/RCTRootView.m @@ -142,7 +142,7 @@ static Class _globalExecutorClass; // Choose local executor if specified, followed by global, followed by default _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]; [self addGestureRecognizer:_touchHandler]; diff --git a/ReactKit/ReactKit.xcodeproj/project.pbxproj b/ReactKit/ReactKit.xcodeproj/project.pbxproj index eed3a13e7..d00c6b2c8 100644 --- a/ReactKit/ReactKit.xcodeproj/project.pbxproj +++ b/ReactKit/ReactKit.xcodeproj/project.pbxproj @@ -31,6 +31,8 @@ 13B0801F1A69489C00A75B9A /* RCTTextFieldManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080171A69489C00A75B9A /* RCTTextFieldManager.m */; }; 13B080201A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080191A69489C00A75B9A /* RCTUIActivityIndicatorViewManager.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 */; }; 13E067551A70F44B002CDEE1 /* RCTShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E0674C1A70F44B002CDEE1 /* RCTShadowView.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 = ""; }; 13B080231A694A8400A75B9A /* RCTWrapperViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWrapperViewController.h; sourceTree = ""; }; 13B080241A694A8400A75B9A /* RCTWrapperViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWrapperViewController.m; sourceTree = ""; }; + 13C156011AB1A2840079392D /* RCTWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebView.h; sourceTree = ""; }; + 13C156021AB1A2840079392D /* RCTWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebView.m; sourceTree = ""; }; + 13C156031AB1A2840079392D /* RCTWebViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebViewManager.h; sourceTree = ""; }; + 13C156041AB1A2840079392D /* RCTWebViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebViewManager.m; sourceTree = ""; }; 13C325261AA63B6A0048765F /* RCTAutoInsetsProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAutoInsetsProtocol.h; sourceTree = ""; }; 13C325271AA63B6A0048765F /* RCTScrollableProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTScrollableProtocol.h; sourceTree = ""; }; 13C325281AA63B6A0048765F /* RCTViewNodeProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTViewNodeProtocol.h; sourceTree = ""; }; @@ -299,6 +305,10 @@ 13E0674D1A70F44B002CDEE1 /* RCTViewManager.h */, 13E0674E1A70F44B002CDEE1 /* RCTViewManager.m */, 13C325281AA63B6A0048765F /* RCTViewNodeProtocol.h */, + 13C156011AB1A2840079392D /* RCTWebView.h */, + 13C156021AB1A2840079392D /* RCTWebView.m */, + 13C156031AB1A2840079392D /* RCTWebViewManager.h */, + 13C156041AB1A2840079392D /* RCTWebViewManager.m */, 13B080231A694A8400A75B9A /* RCTWrapperViewController.h */, 13B080241A694A8400A75B9A /* RCTWrapperViewController.m */, 13E067531A70F44B002CDEE1 /* UIView+ReactKit.h */, @@ -480,7 +490,9 @@ 83CBBA531A601E3B00E9B192 /* RCTUtils.m in Sources */, 14435CE61AAC4AE100FC20F4 /* RCTMapManager.m in Sources */, 83C911101AAE6521001323A3 /* RCTAnimationManager.m in Sources */, + 13C156051AB1A2840079392D /* RCTWebView.m in Sources */, 83CBBA601A601EAA00E9B192 /* RCTBridge.m in Sources */, + 13C156061AB1A2840079392D /* RCTWebViewManager.m in Sources */, 58114A161AAE854800E7D092 /* RCTPicker.m in Sources */, 137327E81AA5CF210034F82E /* RCTTabBarItem.m in Sources */, 13E067551A70F44B002CDEE1 /* RCTShadowView.m in Sources */, diff --git a/ReactKit/Views/RCTScrollView.m b/ReactKit/Views/RCTScrollView.m index 55b6690c9..fa6dc0f81 100644 --- a/ReactKit/Views/RCTScrollView.m +++ b/ReactKit/Views/RCTScrollView.m @@ -343,10 +343,14 @@ CGFloat const ZINDEX_STICKY_HEADER = 50; - (void)setContentInset:(UIEdgeInsets)contentInset { + CGPoint contentOffset = _scrollView.contentOffset; + _contentInset = contentInset; [RCTView autoAdjustInsetsForView:self withScrollView:_scrollView updateOffset:NO]; + + _scrollView.contentOffset = contentOffset; } - (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 { return [super respondsToSelector:aSelector] || [_scrollView respondsToSelector:aSelector]; @@ -577,13 +614,11 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, RCTScrollEventTypeMove) - (void)setValue:(id)value forUndefinedKey:(NSString *)key { - // Pipe unrecognized properties to scrollview [_scrollView setValue:value forKey:key]; } - (id)valueForUndefinedKey:(NSString *)key { - // Pipe unrecognized properties from scrollview return [_scrollView valueForKey:key]; } diff --git a/ReactKit/Views/RCTScrollViewManager.m b/ReactKit/Views/RCTScrollViewManager.m index 470c2c3f2..799d4b83c 100644 --- a/ReactKit/Views/RCTScrollViewManager.m +++ b/ReactKit/Views/RCTScrollViewManager.m @@ -34,10 +34,10 @@ RCT_EXPORT_VIEW_PROPERTY(showsHorizontalScrollIndicator) RCT_EXPORT_VIEW_PROPERTY(showsVerticalScrollIndicator) RCT_EXPORT_VIEW_PROPERTY(stickyHeaderIndices); 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(scrollIndicatorInsets); -RCT_EXPORT_VIEW_PROPERTY(contentOffset); +RCT_REMAP_VIEW_PROPERTY(contentOffset, scrollView.contentOffset); - (NSDictionary *)constantsToExport { diff --git a/ReactKit/Views/RCTWebView.h b/ReactKit/Views/RCTWebView.h new file mode 100644 index 000000000..ec3c9d6eb --- /dev/null +++ b/ReactKit/Views/RCTWebView.h @@ -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 diff --git a/ReactKit/Views/RCTWebView.m b/ReactKit/Views/RCTWebView.m new file mode 100644 index 000000000..cc5a07578 --- /dev/null +++ b/ReactKit/Views/RCTWebView.m @@ -0,0 +1,180 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import "RCTWebView.h" + +#import + +#import "RCTAutoInsetsProtocol.h" +#import "RCTEventDispatcher.h" +#import "RCTLog.h" +#import "RCTUtils.h" +#import "RCTView.h" +#import "UIView+ReactKit.h" + +@interface RCTWebView () + +@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 diff --git a/ReactKit/Views/RCTWebViewManager.h b/ReactKit/Views/RCTWebViewManager.h new file mode 100644 index 000000000..d375cbdab --- /dev/null +++ b/ReactKit/Views/RCTWebViewManager.h @@ -0,0 +1,7 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import "RCTViewManager.h" + +@interface RCTWebViewManager : RCTViewManager + +@end diff --git a/ReactKit/Views/RCTWebViewManager.m b/ReactKit/Views/RCTWebViewManager.m new file mode 100644 index 000000000..8e68d9eb8 --- /dev/null +++ b/ReactKit/Views/RCTWebViewManager.m @@ -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 diff --git a/packager/react-packager/src/DependencyResolver/ModuleDescriptor.js b/packager/react-packager/src/DependencyResolver/ModuleDescriptor.js index f1a30545c..df29e57c5 100644 --- a/packager/react-packager/src/DependencyResolver/ModuleDescriptor.js +++ b/packager/react-packager/src/DependencyResolver/ModuleDescriptor.js @@ -22,6 +22,8 @@ function ModuleDescriptor(fields) { this.isPolyfill = fields.isPolyfill || false; + this.isAsset = fields.isAsset || false; + this._fields = fields; } diff --git a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js index eb839296c..6dee93ec6 100644 --- a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js +++ b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js @@ -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() { var root = '/root'; fs.__setMockFilesystem({ diff --git a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js index ce6318562..122701d56 100644 --- a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js +++ b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js @@ -28,12 +28,22 @@ var validateOpts = declareOpts({ type: 'object', required: true, }, + assetRoots: { + type: 'array', + default: [], + }, + assetExts: { + type: 'array', + default: ['png'], + } }); function DependecyGraph(options) { var opts = validateOpts(options); this._roots = opts.roots; + this._assetRoots = opts.assetRoots; + this._assetExts = opts.assetExts; this._ignoreFilePath = opts.ignoreFilePath; this._fileWatcher = options.fileWatcher; @@ -50,7 +60,16 @@ function DependecyGraph(options) { } 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, 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; // Package relative modules starts with '.' or '..'. @@ -214,32 +242,13 @@ DependecyGraph.prototype._search = function() { // 2. Filter the files and queue up the directories. // 3. Process any package.json in the files // 4. recur. - return readDir(dir) - .then(function(files){ - return q.all(files.map(function(filePath) { - return realpath(path.join(dir, filePath)).catch(handleBrokenLink); - })); - }) - .then(function(filePaths) { - filePaths = filePaths.filter(function(filePath) { - if (filePath == null) { + return readAndStatDir(dir) + .spread(function(files, stats) { + var modulePaths = files.filter(function(filePath, i) { + if (self._ignoreFilePath(filePath)) { 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()) { self._queue.push(filePath); return false; @@ -465,6 +474,19 @@ DependecyGraph.prototype._getAbsolutePath = function(filePath) { 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. */ @@ -511,4 +533,70 @@ function handleBrokenLink(e) { 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; diff --git a/packager/react-packager/src/DependencyResolver/haste/index.js b/packager/react-packager/src/DependencyResolver/haste/index.js index 6aada00b9..fdc779edc 100644 --- a/packager/react-packager/src/DependencyResolver/haste/index.js +++ b/packager/react-packager/src/DependencyResolver/haste/index.js @@ -17,7 +17,6 @@ var DEFINE_MODULE_CODE = [ ].join(''); var DEFINE_MODULE_REPLACE_RE = /_moduleName_|_code_|_deps_/g; - var REL_REQUIRE_STMT = /require\(['"]([\.\/0-9A-Z_$\-]*)['"]\)/gi; var validateOpts = declareOpts({ @@ -40,6 +39,10 @@ var validateOpts = declareOpts({ type: 'string', default: 'haste', }, + assetRoots: { + type: 'array', + default: [], + }, }); function HasteDependencyResolver(options) { @@ -51,11 +54,12 @@ function HasteDependencyResolver(options) { this._depGraph = new DependencyGraph({ roots: opts.projectRoots, + assetRoots: opts.assetRoots, ignoreFilePath: function(filepath) { return filepath.indexOf('__tests__') !== -1 || (opts.blacklistRE && opts.blacklistRE.test(filepath)); }, - fileWatcher: this._fileWatcher + fileWatcher: this._fileWatcher, }); diff --git a/packager/react-packager/src/Packager/__tests__/Packager-test.js b/packager/react-packager/src/Packager/__tests__/Packager-test.js index d8348be8f..498faea3a 100644 --- a/packager/react-packager/src/Packager/__tests__/Packager-test.js +++ b/packager/react-packager/src/Packager/__tests__/Packager-test.js @@ -40,6 +40,11 @@ describe('Packager', function() { var modules = [ {id: 'foo', path: '/root/foo.js', dependencies: []}, {id: 'bar', path: '/root/bar.js', dependencies: []}, + { id: 'image!img', + path: '/root/img/img.png', + isAsset: true, + dependencies: [], + } ]; getDependencies.mockImpl(function() { @@ -74,6 +79,15 @@ describe('Packager', function() { 'source /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([ {runMainModule: true} diff --git a/packager/react-packager/src/Packager/index.js b/packager/react-packager/src/Packager/index.js index 75cccdb26..c21889b48 100644 --- a/packager/react-packager/src/Packager/index.js +++ b/packager/react-packager/src/Packager/index.js @@ -44,6 +44,10 @@ var validateOpts = declareOpts({ type: 'boolean', default: false, }, + assetRoots: { + type: 'array', + required: false, + }, }); function Packager(options) { @@ -56,7 +60,8 @@ function Packager(options) { blacklistRE: opts.blacklistRE, polyfillModuleNames: opts.polyfillModuleNames, nonPersistent: opts.nonPersistent, - moduleFormat: opts.moduleFormat + moduleFormat: opts.moduleFormat, + assetRoots: opts.assetRoots, }); this._transformer = new Transformer({ @@ -118,10 +123,18 @@ Packager.prototype.getDependencies = function(main, isDev) { }; 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; - return this._transformer.loadFileAndTransform( - path.resolve(module.path) - ).then(function(transformed) { + return transform.then(function(transformed) { return _.extend( {}, transformed, @@ -140,5 +153,17 @@ Packager.prototype.getGraphDebugInfo = function() { 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; diff --git a/packager/react-packager/src/Server/index.js b/packager/react-packager/src/Server/index.js index 8982bc916..7df686ad2 100644 --- a/packager/react-packager/src/Server/index.js +++ b/packager/react-packager/src/Server/index.js @@ -43,6 +43,10 @@ var validateOpts = declareOpts({ type: 'boolean', default: false, }, + assetRoots: { + type: 'array', + required: false, + }, }); function Server(options) {