diff --git a/Examples/SampleApp/index.ios.js b/Examples/SampleApp/index.ios.js
index 97ff012e7..c6139d947 100644
--- a/Examples/SampleApp/index.ios.js
+++ b/Examples/SampleApp/index.ios.js
@@ -20,8 +20,11 @@ var SampleApp = React.createClass({
Welcome to React Native!
- To get started, edit index.ios.js{'\n'}
- Press Cmd+R to reload
+ To get started, edit index.ios.js
+
+
+ Press Cmd+R to reload,{'\n'}
+ Cmd+Shift+Z for dev menu
);
@@ -43,6 +46,7 @@ var styles = StyleSheet.create({
instructions: {
textAlign: 'center',
color: '#333333',
+ marginBottom: 5,
},
});
diff --git a/Examples/UIExplorer/UIExplorerPage.js b/Examples/UIExplorer/UIExplorerPage.js
index 6890349ea..ea1761a28 100644
--- a/Examples/UIExplorer/UIExplorerPage.js
+++ b/Examples/UIExplorer/UIExplorerPage.js
@@ -40,7 +40,7 @@ var UIExplorerPage = React.createClass({
ContentWrapper = View;
} else {
ContentWrapper = ScrollView;
- wrapperProps.keyboardShouldPeristTaps = true;
+ wrapperProps.keyboardShouldPersistTaps = true;
wrapperProps.keyboardDismissMode = 'interactive';
}
var title = this.props.title ?
diff --git a/Libraries/Components/MapView/MapView.js b/Libraries/Components/MapView/MapView.js
index b778fc695..388e22ddc 100644
--- a/Libraries/Components/MapView/MapView.js
+++ b/Libraries/Components/MapView/MapView.js
@@ -147,6 +147,9 @@ var MapView = React.createClass({
legalLabelInsets={this.props.legalLabelInsets}
onChange={this._onChange}
onTouchStart={this.props.onTouchStart}
+ onTouchMove={this.props.onTouchMove}
+ onTouchEnd={this.props.onTouchEnd}
+ onTouchCancel={this.props.onTouchCancel}
/>
);
},
diff --git a/Libraries/Components/ScrollView/ScrollView.js b/Libraries/Components/ScrollView/ScrollView.js
index ba6a2c8b1..fc7fc7223 100644
--- a/Libraries/Components/ScrollView/ScrollView.js
+++ b/Libraries/Components/ScrollView/ScrollView.js
@@ -59,13 +59,20 @@ var ScrollView = React.createClass({
contentOffset: PointPropType, // zeros
onScroll: PropTypes.func,
onScrollAnimationEnd: PropTypes.func,
- scrollEnabled: PropTypes.bool, // tre
+ scrollEnabled: PropTypes.bool, // true
scrollIndicatorInsets: EdgeInsetsPropType, // zeros
showsHorizontalScrollIndicator: PropTypes.bool,
showsVerticalScrollIndicator: PropTypes.bool,
style: StyleSheetPropType(ViewStylePropTypes),
scrollEventThrottle: PropTypes.number, // null
+ /**
+ * When true, the scroll view bounces when it reaches the end of the
+ * content if the content is larger then the scroll view along the axis of
+ * the scroll direction. When false, it disables all bouncing even if
+ * the `alwaysBounce*` props are true. The default value is true.
+ */
+ bounces: PropTypes.bool,
/**
* When true, the scroll view bounces horizontally when it reaches the end
* even if the content is smaller than the scroll view itself. The default
@@ -195,6 +202,14 @@ var ScrollView = React.createClass({
);
},
+ scrollWithoutAnimationTo: function(destY?: number, destX?: number) {
+ RCTUIManager.scrollWithoutAnimationTo(
+ this.getNodeHandle(),
+ destX || 0,
+ destY || 0
+ );
+ },
+
render: function() {
var contentContainerStyle = [
this.props.horizontal && styles.contentContainerHorizontal,
@@ -308,6 +323,7 @@ var validAttributes = {
alwaysBounceHorizontal: true,
alwaysBounceVertical: true,
automaticallyAdjustContentInsets: true,
+ bounces: true,
centerContent: true,
contentInset: {diff: insetsDiffer},
contentOffset: {diff: pointsDiffer},
diff --git a/Libraries/Components/WebView/WebView.ios.js b/Libraries/Components/WebView/WebView.ios.js
index 867143b8c..f05e2f61b 100644
--- a/Libraries/Components/WebView/WebView.ios.js
+++ b/Libraries/Components/WebView/WebView.ios.js
@@ -60,7 +60,8 @@ var WebView = React.createClass({
propTypes: {
renderError: PropTypes.func.isRequired, // view to show if there's an error
renderLoading: PropTypes.func.isRequired, // loading indicator to show
- url: PropTypes.string.isRequired,
+ url: PropTypes.string,
+ html: PropTypes.string,
automaticallyAdjustContentInsets: PropTypes.bool,
shouldInjectAJAXHandler: PropTypes.bool,
contentInset: EdgeInsetsPropType,
@@ -115,6 +116,7 @@ var WebView = React.createClass({
key="webViewKey"
style={webViewStyles}
url={this.props.url}
+ html={this.props.html}
shouldInjectAJAXHandler={this.props.shouldInjectAJAXHandler}
contentInset={this.props.contentInset}
automaticallyAdjustContentInsets={this.props.automaticallyAdjustContentInsets}
@@ -182,6 +184,7 @@ var WebView = React.createClass({
var RCTWebView = createReactIOSNativeComponentClass({
validAttributes: merge(ReactIOSViewAttributes.UIView, {
url: true,
+ html: true,
contentInset: {diff: insetsDiffer},
automaticallyAdjustContentInsets: true,
shouldInjectAJAXHandler: true
diff --git a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js
index a9e06a6cf..51f6809cc 100644
--- a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js
+++ b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js
@@ -60,6 +60,10 @@ function setupDocumentShim() {
if (GLOBAL.document) {
GLOBAL.document.createElement = null;
}
+
+ // There is no DOM so MutationObserver doesn't make sense. It is used
+ // as feature detection in Bluebird Promise implementation
+ GLOBAL.MutationObserver = undefined;
}
function handleErrorWithRedBox(e) {
diff --git a/Libraries/ReactIOS/ReactIOS.js b/Libraries/ReactIOS/ReactIOS.js
index 028577429..56faaa30b 100644
--- a/Libraries/ReactIOS/ReactIOS.js
+++ b/Libraries/ReactIOS/ReactIOS.js
@@ -67,8 +67,12 @@ var augmentElement = function(element: ReactElement) {
return element;
};
-var render = function(component: ReactComponent, mountInto: number) {
- ReactIOSMount.renderComponent(component, mountInto);
+var render = function(
+ element: ReactElement,
+ mountInto: number,
+ callback?: ?(() => void)
+): ?ReactComponent {
+ return ReactIOSMount.renderComponent(element, mountInto, callback);
};
var ReactIOS = {
diff --git a/Libraries/ReactIOS/ReactIOSDefaultInjection.js b/Libraries/ReactIOS/ReactIOSDefaultInjection.js
index d6b81da2c..a64236973 100644
--- a/Libraries/ReactIOS/ReactIOSDefaultInjection.js
+++ b/Libraries/ReactIOS/ReactIOSDefaultInjection.js
@@ -24,6 +24,7 @@ var NodeHandle = require('NodeHandle');
var ReactClass = require('ReactClass');
var ReactComponentEnvironment = require('ReactComponentEnvironment');
var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
+var ReactEmptyComponent = require('ReactEmptyComponent');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactIOSComponentEnvironment = require('ReactIOSComponentEnvironment');
var ReactIOSComponentMixin = require('ReactIOSComponentMixin');
@@ -36,6 +37,8 @@ var ReactUpdates = require('ReactUpdates');
var ResponderEventPlugin = require('ResponderEventPlugin');
var UniversalWorkerNodeHandle = require('UniversalWorkerNodeHandle');
+var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
+
// Just to ensure this gets packaged, since its only caller is from Native.
require('RCTEventEmitter');
require('RCTLog');
@@ -77,6 +80,13 @@ function inject() {
ReactIOSComponentEnvironment
);
+ // Can't import View here because it depends on React to make its composite
+ var RCTView = createReactIOSNativeComponentClass({
+ validAttributes: {},
+ uiViewClassName: 'RCTView',
+ });
+ ReactEmptyComponent.injection.injectEmptyComponent(RCTView);
+
EventPluginUtils.injection.injectMount(ReactIOSMount);
ReactClass.injection.injectMixin(ReactIOSComponentMixin);
diff --git a/Libraries/ReactIOS/ReactIOSMount.js b/Libraries/ReactIOS/ReactIOSMount.js
index 7e4094408..730031672 100644
--- a/Libraries/ReactIOS/ReactIOSMount.js
+++ b/Libraries/ReactIOS/ReactIOSMount.js
@@ -16,13 +16,13 @@ var RCTUIManager = require('NativeModules').UIManager;
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var ReactPerf = require('ReactPerf');
var ReactReconciler = require('ReactReconciler');
+var ReactUpdateQueue = require('ReactUpdateQueue');
var ReactUpdates = require('ReactUpdates');
var emptyObject = require('emptyObject');
var instantiateReactComponent = require('instantiateReactComponent');
var invariant = require('invariant');
-
-var TOP_ROOT_NODE_IDS = {};
+var shouldUpdateReactComponent = require('shouldUpdateReactComponent');
function instanceNumberToChildRootID(rootNodeID, instanceNumber) {
return rootNodeID + '[' + instanceNumber + ']';
@@ -85,10 +85,26 @@ var ReactIOSMount = {
* @param {containerTag} containerView Handle to native view tag
*/
renderComponent: function(
- descriptor: ReactComponent,
- containerTag: number
- ) {
- var instance = instantiateReactComponent(descriptor);
+ nextElement: ReactElement,
+ containerTag: number,
+ callback?: ?(() => void)
+ ): ?ReactComponent {
+ var topRootNodeID = ReactIOSTagHandles.tagToRootNodeID[containerTag];
+ if (topRootNodeID) {
+ var prevComponent = ReactIOSMount._instancesByContainerID[topRootNodeID];
+ if (prevComponent) {
+ var prevElement = prevComponent._currentElement;
+ if (shouldUpdateReactComponent(prevElement, nextElement)) {
+ ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement);
+ if (callback) {
+ ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback);
+ }
+ return prevComponent;
+ } else {
+ ReactIOSMount.unmountComponentAtNode(containerTag);
+ }
+ }
+ }
if (!ReactIOSTagHandles.reactTagIsNativeTopRootID(containerTag)) {
console.error('You cannot render into anything but a top root');
@@ -100,13 +116,14 @@ var ReactIOSMount = {
topRootNodeID,
containerTag
);
- TOP_ROOT_NODE_IDS[topRootNodeID] = true;
+
+ var instance = instantiateReactComponent(nextElement);
+ ReactIOSMount._instancesByContainerID[topRootNodeID] = instance;
var childRootNodeID = instanceNumberToChildRootID(
topRootNodeID,
ReactIOSMount.instanceCount++
);
- ReactIOSMount._instancesByContainerID[topRootNodeID] = instance;
// The initial render is synchronous but any updates that happen during
// rendering, in componentWillMount or componentDidMount, will be batched
@@ -118,6 +135,11 @@ var ReactIOSMount = {
childRootNodeID,
topRootNodeID
);
+ var component = instance.getPublicInstance();
+ if (callback) {
+ callback.call(component);
+ }
+ return component;
},
/**
@@ -170,20 +192,18 @@ var ReactIOSMount = {
* component at this time.
*/
unmountComponentAtNode: function(containerTag: number): bool {
- var containerID = ReactIOSTagHandles.tagToRootNodeID[containerTag];
+ if (!ReactIOSTagHandles.reactTagIsNativeTopRootID(containerTag)) {
+ console.error('You cannot render into anything but a top root');
+ return;
+ }
- invariant(
- TOP_ROOT_NODE_IDS[containerID],
- 'We only currently support removing components from the root node'
- );
+ var containerID = ReactIOSTagHandles.tagToRootNodeID[containerTag];
var instance = ReactIOSMount._instancesByContainerID[containerID];
if (!instance) {
- console.error('Tried to unmount a component that does not exist');
return false;
}
ReactIOSMount.unmountComponentFromNode(instance, containerID);
delete ReactIOSMount._instancesByContainerID[containerID];
- delete TOP_ROOT_NODE_IDS[containerID];
return true;
},
@@ -200,10 +220,8 @@ var ReactIOSMount = {
instance: ReactComponent,
containerID: string
) {
- // call back into native to remove all of the subviews from this container
- // TODO: ReactComponent.prototype.unmountComponent is missing from Flow's
- // react lib.
- (instance: any).unmountComponent();
+ // Call back into native to remove all of the subviews from this container
+ ReactReconciler.unmountComponent(instance);
var containerTag =
ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(containerID);
RCTUIManager.removeSubviewsFromContainerWithID(containerTag);
diff --git a/React.podspec b/React.podspec
index 4ad740e4a..8abc2a5ba 100644
--- a/React.podspec
+++ b/React.podspec
@@ -1,78 +1,94 @@
Pod::Spec.new do |s|
- s.name = "React"
- s.version = "0.1.0"
- s.summary = "Build high quality mobile apps using React."
- s.description= <<-DESC
- React Native apps are built using the React JS framework,
- and render directly to native UIKit elements using a fully
- asynchronous architecture. There is no browser and no HTML.
- We have picked what we think is the best set of features from
- these and other technologies to build what we hope to become
- the best product development framework available, with an
- emphasis on iteration speed, developer delight, continuity
- of technology, and absolutely beautiful and fast products
- with no compromises in quality or capability.
- DESC
- s.homepage = "http://facebook.github.io/react-native/"
- s.license = "BSD"
- s.author = "Facebook"
- s.platform = :ios, "7.0"
- s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "v#{s.version}" }
- s.source_files = "React/**/*.{c,h,m}"
- s.resources = "Resources/*.png"
- s.preserve_paths = "cli.js", "Libraries/**/*.js", "lint", "linter.js", "node_modules", "package.json", "packager", "PATENTS", "react-native-cli"
- s.exclude_files = "**/__tests__/*", "IntegrationTests/*"
- s.frameworks = "JavaScriptCore"
- s.requires_arc = true
- s.prepare_command = 'npm install'
- s.libraries = 'icucore'
+ s.name = "React"
+ s.version = "0.3.1"
+ s.summary = "Build high quality mobile apps using React."
+ s.description = <<-DESC
+ React Native apps are built using the React JS
+ framework, and render directly to native UIKit
+ elements using a fully asynchronous architecture.
+ There is no browser and no HTML. We have picked what
+ we think is the best set of features from these and
+ other technologies to build what we hope to become
+ the best product development framework available,
+ with an emphasis on iteration speed, developer
+ delight, continuity of technology, and absolutely
+ beautiful and fast products with no compromises in
+ quality or capability.
+ DESC
+ s.homepage = "http://facebook.github.io/react-native/"
+ s.license = "BSD"
+ s.author = "Facebook"
+ s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "v#{s.version}" }
+ s.default_subspec = 'Core'
+ s.requires_arc = true
+ s.platform = :ios, "7.0"
+ s.prepare_command = 'npm install'
+ s.preserve_paths = "cli.js", "Libraries/**/*.js", "lint", "linter.js", "node_modules", "package.json", "packager", "PATENTS", "react-native-cli"
+ s.header_mappings_dir = "."
+
+ s.subspec 'Core' do |ss|
+ ss.source_files = "React/**/*.{c,h,m}"
+ ss.exclude_files = "**/__tests__/*", "IntegrationTests/*"
+ ss.frameworks = "JavaScriptCore"
+ end
s.subspec 'RCTActionSheet' do |ss|
- ss.source_files = "Libraries/ActionSheetIOS/*.{h,m}"
- ss.preserve_paths = "Libraries/ActionSheetIOS/*.js"
+ ss.dependency 'React/Core'
+ ss.source_files = "Libraries/ActionSheetIOS/*.{h,m}"
+ ss.preserve_paths = "Libraries/ActionSheetIOS/*.js"
end
s.subspec 'RCTAdSupport' do |ss|
- ss.source_files = "Libraries/RCTAdSupport/*.{h,m}"
- ss.preserve_paths = "Libraries/RCTAdSupport/*.js"
+ ss.dependency 'React/Core'
+ ss.source_files = "Libraries/AdSupport/*.{h,m}"
+ ss.preserve_paths = "Libraries/AdSupport/*.js"
end
s.subspec 'RCTAnimation' do |ss|
- ss.source_files = "Libraries/Animation/*.{h,m}"
- ss.preserve_paths = "Libraries/Animation/*.js"
+ ss.dependency 'React/Core'
+ ss.source_files = "Libraries/Animation/*.{h,m}"
+ ss.preserve_paths = "Libraries/Animation/*.js"
end
s.subspec 'RCTGeolocation' do |ss|
- ss.source_files = "Libraries/Geolocation/*.{h,m}"
- ss.preserve_paths = "Libraries/Geolocation/*.js"
+ ss.dependency 'React/Core'
+ ss.source_files = "Libraries/Geolocation/*.{h,m}"
+ ss.preserve_paths = "Libraries/Geolocation/*.js"
end
s.subspec 'RCTImage' do |ss|
- ss.source_files = "Libraries/Image/*.{h,m}"
- ss.preserve_paths = "Libraries/Image/*.js"
+ ss.dependency 'React/Core'
+ ss.source_files = "Libraries/Image/*.{h,m}"
+ ss.preserve_paths = "Libraries/Image/*.js"
end
s.subspec 'RCTNetwork' do |ss|
- ss.source_files = "Libraries/Network/*.{h,m}"
- ss.preserve_paths = "Libraries/Network/*.js"
+ ss.dependency 'React/Core'
+ ss.source_files = "Libraries/Network/*.{h,m}"
+ ss.preserve_paths = "Libraries/Network/*.js"
end
s.subspec 'RCTPushNotification' do |ss|
- ss.source_files = "Libraries/PushNotificationIOS/*.{h,m}"
- ss.preserve_paths = "Libraries/PushNotificationIOS/*.js"
+ ss.dependency 'React/Core'
+ ss.source_files = "Libraries/PushNotificationIOS/*.{h,m}"
+ ss.preserve_paths = "Libraries/PushNotificationIOS/*.js"
end
s.subspec 'RCTWebSocketDebugger' do |ss|
- ss.source_files = "Libraries/RCTWebSocketDebugger/*.{h,m}"
+ ss.dependency 'React/Core'
+ ss.libraries = 'icucore'
+ ss.source_files = "Libraries/RCTWebSocketDebugger/*.{h,m}"
end
s.subspec 'RCTText' do |ss|
- ss.source_files = "Libraries/Text/*.{h,m}"
- ss.preserve_paths = "Libraries/Text/*.js"
+ ss.dependency 'React/Core'
+ ss.source_files = "Libraries/Text/*.{h,m}"
+ ss.preserve_paths = "Libraries/Text/*.js"
end
s.subspec 'RCTVibration' do |ss|
- ss.source_files = "Libraries/Vibration/*.{h,m}"
- ss.preserve_paths = "Libraries/Vibration/*.js"
+ ss.dependency 'React/Core'
+ ss.source_files = "Libraries/Vibration/*.{h,m}"
+ ss.preserve_paths = "Libraries/Vibration/*.js"
end
end
diff --git a/React/Modules/RCTAsyncLocalStorage.m b/React/Modules/RCTAsyncLocalStorage.m
index e1daeb2fb..95fb383e4 100644
--- a/React/Modules/RCTAsyncLocalStorage.m
+++ b/React/Modules/RCTAsyncLocalStorage.m
@@ -157,7 +157,7 @@ static dispatch_queue_t RCTFileQueue(void)
return RCTMakeAndLogError(@"Entries must be arrays of the form [key: string, value: string], got: ", entry, nil);
}
if (![entry[1] isKindOfClass:[NSString class]]) {
- return RCTMakeAndLogError(@"Values must be strings, got: ", entry[1], entry[0]);
+ return RCTMakeAndLogError(@"Values must be strings, got: ", entry[1], @{@"key": entry[0]});
}
NSString *key = entry[0];
id errorOut = RCTErrorForKey(key);
diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m
index d460ea68d..82324f281 100644
--- a/React/Modules/RCTUIManager.m
+++ b/React/Modules/RCTUIManager.m
@@ -507,7 +507,7 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
{
RCT_EXPORT();
- id container = _viewRegistry[containerID];
+ id container = _shadowViewRegistry[containerID];
RCTAssert(container != nil, @"container view (for ID %@) not found", containerID);
NSUInteger subviewsCount = [[container reactSubviews] count];
@@ -1051,13 +1051,27 @@ static void RCTMeasureLayout(RCTShadowView *view,
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
- [(id)view scrollToOffset:CGPointMake([offsetX floatValue], [offsetY floatValue])];
+ [(id)view scrollToOffset:CGPointMake([offsetX floatValue], [offsetY floatValue]) animated:YES];
} else {
RCTLogError(@"tried to scrollToOffset: on non-RCTScrollableProtocol view %@ with tag %@", view, reactTag);
}
}];
}
+- (void)scrollWithoutAnimationToOffsetWithView:(NSNumber *)reactTag scrollToOffsetX:(NSNumber *)offsetX offsetY:(NSNumber *)offsetY
+{
+ RCT_EXPORT(scrollWithoutAnimationTo);
+
+ [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
+ UIView *view = viewRegistry[reactTag];
+ if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
+ [(id)view scrollToOffset:CGPointMake([offsetX floatValue], [offsetY floatValue]) animated:NO];
+ } else {
+ RCTLogError(@"tried to scrollToOffset: on non-RCTScrollableProtocol view %@ with tag %@", view, reactTag);
+ }
+ }];
+}
+
- (void)zoomToRectWithView:(NSNumber *)reactTag rect:(NSDictionary *)rectDict
{
RCT_EXPORT(zoomToRect);
diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m
index fa9975ac8..50d55a8a7 100644
--- a/React/Views/RCTViewManager.m
+++ b/React/Views/RCTViewManager.m
@@ -79,7 +79,7 @@ RCT_REMAP_VIEW_PROPERTY(testID, accessibilityIdentifier, NSString)
RCT_REMAP_VIEW_PROPERTY(opacity, alpha, CGFloat)
RCT_REMAP_VIEW_PROPERTY(shadowColor, layer.shadowColor, CGColor);
RCT_REMAP_VIEW_PROPERTY(shadowOffset, layer.shadowOffset, CGSize);
-RCT_REMAP_VIEW_PROPERTY(shadowOpacity, layer.shadowOpacity, CGFloat)
+RCT_REMAP_VIEW_PROPERTY(shadowOpacity, layer.shadowOpacity, float)
RCT_REMAP_VIEW_PROPERTY(shadowRadius, layer.shadowRadius, CGFloat)
RCT_REMAP_VIEW_PROPERTY(transformMatrix, layer.transform, CATransform3D)
RCT_CUSTOM_VIEW_PROPERTY(overflow, css_overflow, RCTView)
diff --git a/React/Views/RCTWebView.m b/React/Views/RCTWebView.m
index 86dae0172..bb9bb2acf 100644
--- a/React/Views/RCTWebView.m
+++ b/React/Views/RCTWebView.m
@@ -73,6 +73,11 @@
[_webView loadRequest:[NSURLRequest requestWithURL:URL]];
}
+- (void)setHTML:(NSString *)HTML
+{
+ [_webView loadHTMLString:HTML baseURL:nil];
+}
+
- (void)layoutSubviews
{
[super layoutSubviews];
diff --git a/React/Views/RCTWebViewManager.m b/React/Views/RCTWebViewManager.m
index 4b02f6c0a..7525ee236 100644
--- a/React/Views/RCTWebViewManager.m
+++ b/React/Views/RCTWebViewManager.m
@@ -22,8 +22,9 @@
}
RCT_REMAP_VIEW_PROPERTY(url, URL, NSURL);
+RCT_REMAP_VIEW_PROPERTY(html, HTML, NSString);
RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets);
-RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, UIEdgeInsets);
+RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, BOOL);
RCT_EXPORT_VIEW_PROPERTY(shouldInjectAJAXHandler, BOOL);
- (NSDictionary *)constantsToExport
diff --git a/package.json b/package.json
index 1db1dc05f..ca60030f7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-native",
- "version": "0.3.0",
+ "version": "0.3.1",
"description": "A framework for building native apps using React",
"repository": {
"type": "git",
diff --git a/packager/debugger.html b/packager/debugger.html
index 38e9e6cdd..d0d4aba54 100644
--- a/packager/debugger.html
+++ b/packager/debugger.html
@@ -66,7 +66,7 @@ ws.onopen = function() {
setStatus('Debugger session #' + sessionID + ' active');
ws.send(JSON.stringify({replyID: parseInt(sessionID, 10)}));
} else {
- setStatus('Waiting for simulator');
+ setStatus('Waiting, press ⌘R in simulator to reload and connect');
}
}
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 69ed11e65..3202274c4 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
@@ -14,6 +14,7 @@ jest
.dontMock('path')
.dontMock('absolute-path')
.dontMock('../docblock')
+ .dontMock('../../requirePattern')
.setMock('../../../ModuleDescriptor', function(data) {return data;});
describe('DependencyGraph', function() {
diff --git a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js
index 00c4a5c5c..a23f6d500 100644
--- a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js
+++ b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js
@@ -12,6 +12,7 @@ var ModuleDescriptor = require('../../ModuleDescriptor');
var q = require('q');
var fs = require('fs');
var docblock = require('./docblock');
+var requirePattern = require('../requirePattern');
var path = require('path');
var isAbsolutePath = require('absolute-path');
var debug = require('debug')('DependecyGraph');
@@ -600,7 +601,6 @@ DependecyGraph.prototype._processAssetChange = function(eventType, file) {
/**
* Extract all required modules from a `code` string.
*/
-var requireRe = /\brequire\s*\(\s*[\'"]([^"\']+)["\']\s*\)/g;
var blockCommentRe = /\/\*(.|\n)*?\*\//g;
var lineCommentRe = /\/\/.+(\n|$)/g;
function extractRequires(code) {
@@ -609,7 +609,7 @@ function extractRequires(code) {
code
.replace(blockCommentRe, '')
.replace(lineCommentRe, '')
- .replace(requireRe, function(match, dep) {
+ .replace(requirePattern, function(match, _, dep) {
deps.push(dep);
});
diff --git a/packager/react-packager/src/DependencyResolver/haste/__tests__/HasteDependencyResolver-test.js b/packager/react-packager/src/DependencyResolver/haste/__tests__/HasteDependencyResolver-test.js
index 69354590d..c81944d8e 100644
--- a/packager/react-packager/src/DependencyResolver/haste/__tests__/HasteDependencyResolver-test.js
+++ b/packager/react-packager/src/DependencyResolver/haste/__tests__/HasteDependencyResolver-test.js
@@ -10,6 +10,7 @@
jest.dontMock('../')
.dontMock('q')
+ .dontMock('../requirePattern')
.setMock('../../ModuleDescriptor', function(data) {return data;});
var q = require('q');
@@ -226,11 +227,13 @@ describe('HasteDependencyResolver', function() {
});
var depGraph = depResolver._depGraph;
- var dependencies = ['x', 'y', 'z'];
+ var dependencies = ['x', 'y', 'z', 'a', 'b'];
var code = [
'require("x")',
'require("y")',
- 'require("z")',
+ 'require( "z" )',
+ 'require( "a")',
+ 'require("b" )',
].join('\n');
depGraph.resolveDependency.mockImpl(function(fromModule, toModuleName) {
@@ -255,7 +258,9 @@ describe('HasteDependencyResolver', function() {
' require, requireDynamic, requireLazy, module, exports) {' +
' require(\'changed\')',
'require(\'y\')',
- 'require("z")});',
+ 'require("z")',
+ 'require("a")',
+ 'require("b")});',
].join('\n'));
});
});
diff --git a/packager/react-packager/src/DependencyResolver/haste/index.js b/packager/react-packager/src/DependencyResolver/haste/index.js
index 0e46d5e8a..941a687ec 100644
--- a/packager/react-packager/src/DependencyResolver/haste/index.js
+++ b/packager/react-packager/src/DependencyResolver/haste/index.js
@@ -9,8 +9,8 @@
'use strict';
var path = require('path');
-var FileWatcher = require('../../FileWatcher');
var DependencyGraph = require('./DependencyGraph');
+var requirePattern = require('./requirePattern');
var ModuleDescriptor = require('../ModuleDescriptor');
var declareOpts = require('../../lib/declareOpts');
@@ -25,7 +25,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({
projectRoots: {
@@ -146,12 +145,12 @@ HasteDependencyResolver.prototype.wrapModule = function(module, code) {
}
var relativizedCode =
- code.replace(REL_REQUIRE_STMT, function(codeMatch, depName) {
+ code.replace(requirePattern, function(codeMatch, _, depName) {
var depId = resolvedDeps[depName];
if (depId != null) {
return 'require(\'' + depId + '\')';
} else {
- return codeMatch;
+ return codeMatch.replace(/\s+/g, '');
}
});
diff --git a/packager/react-packager/src/DependencyResolver/haste/requirePattern.js b/packager/react-packager/src/DependencyResolver/haste/requirePattern.js
new file mode 100644
index 000000000..26d807ffd
--- /dev/null
+++ b/packager/react-packager/src/DependencyResolver/haste/requirePattern.js
@@ -0,0 +1,14 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+'use strict';
+
+var REQUIRE_RE = /\brequire\s*?\(\s*?([\'"])([^"\']+)\1\s*?\)/g;
+
+module.exports = REQUIRE_RE;