Merge pull request #557 from vjeux/update15

Updates from Tue 31 Mar
This commit is contained in:
Christopher Chedeau 2015-03-31 19:07:28 -07:00
commit 2bb10cdaf9
22 changed files with 205 additions and 88 deletions

View File

@ -20,8 +20,11 @@ var SampleApp = React.createClass({
Welcome to React Native! Welcome to React Native!
</Text> </Text>
<Text style={styles.instructions}> <Text style={styles.instructions}>
To get started, edit index.ios.js{'\n'} To get started, edit index.ios.js
Press Cmd+R to reload </Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+Shift+Z for dev menu
</Text> </Text>
</View> </View>
); );
@ -43,6 +46,7 @@ var styles = StyleSheet.create({
instructions: { instructions: {
textAlign: 'center', textAlign: 'center',
color: '#333333', color: '#333333',
marginBottom: 5,
}, },
}); });

View File

@ -40,7 +40,7 @@ var UIExplorerPage = React.createClass({
ContentWrapper = View; ContentWrapper = View;
} else { } else {
ContentWrapper = ScrollView; ContentWrapper = ScrollView;
wrapperProps.keyboardShouldPeristTaps = true; wrapperProps.keyboardShouldPersistTaps = true;
wrapperProps.keyboardDismissMode = 'interactive'; wrapperProps.keyboardDismissMode = 'interactive';
} }
var title = this.props.title ? var title = this.props.title ?

View File

@ -147,6 +147,9 @@ var MapView = React.createClass({
legalLabelInsets={this.props.legalLabelInsets} legalLabelInsets={this.props.legalLabelInsets}
onChange={this._onChange} onChange={this._onChange}
onTouchStart={this.props.onTouchStart} onTouchStart={this.props.onTouchStart}
onTouchMove={this.props.onTouchMove}
onTouchEnd={this.props.onTouchEnd}
onTouchCancel={this.props.onTouchCancel}
/> />
); );
}, },

View File

@ -59,13 +59,20 @@ var ScrollView = React.createClass({
contentOffset: PointPropType, // zeros contentOffset: PointPropType, // zeros
onScroll: PropTypes.func, onScroll: PropTypes.func,
onScrollAnimationEnd: PropTypes.func, onScrollAnimationEnd: PropTypes.func,
scrollEnabled: PropTypes.bool, // tre scrollEnabled: PropTypes.bool, // true
scrollIndicatorInsets: EdgeInsetsPropType, // zeros scrollIndicatorInsets: EdgeInsetsPropType, // zeros
showsHorizontalScrollIndicator: PropTypes.bool, showsHorizontalScrollIndicator: PropTypes.bool,
showsVerticalScrollIndicator: PropTypes.bool, showsVerticalScrollIndicator: PropTypes.bool,
style: StyleSheetPropType(ViewStylePropTypes), style: StyleSheetPropType(ViewStylePropTypes),
scrollEventThrottle: PropTypes.number, // null 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 * 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 * 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() { render: function() {
var contentContainerStyle = [ var contentContainerStyle = [
this.props.horizontal && styles.contentContainerHorizontal, this.props.horizontal && styles.contentContainerHorizontal,
@ -308,6 +323,7 @@ var validAttributes = {
alwaysBounceHorizontal: true, alwaysBounceHorizontal: true,
alwaysBounceVertical: true, alwaysBounceVertical: true,
automaticallyAdjustContentInsets: true, automaticallyAdjustContentInsets: true,
bounces: true,
centerContent: true, centerContent: true,
contentInset: {diff: insetsDiffer}, contentInset: {diff: insetsDiffer},
contentOffset: {diff: pointsDiffer}, contentOffset: {diff: pointsDiffer},

View File

@ -60,7 +60,8 @@ var WebView = React.createClass({
propTypes: { propTypes: {
renderError: PropTypes.func.isRequired, // view to show if there's an error renderError: PropTypes.func.isRequired, // view to show if there's an error
renderLoading: PropTypes.func.isRequired, // loading indicator to show renderLoading: PropTypes.func.isRequired, // loading indicator to show
url: PropTypes.string.isRequired, url: PropTypes.string,
html: PropTypes.string,
automaticallyAdjustContentInsets: PropTypes.bool, automaticallyAdjustContentInsets: PropTypes.bool,
shouldInjectAJAXHandler: PropTypes.bool, shouldInjectAJAXHandler: PropTypes.bool,
contentInset: EdgeInsetsPropType, contentInset: EdgeInsetsPropType,
@ -115,6 +116,7 @@ var WebView = React.createClass({
key="webViewKey" key="webViewKey"
style={webViewStyles} style={webViewStyles}
url={this.props.url} url={this.props.url}
html={this.props.html}
shouldInjectAJAXHandler={this.props.shouldInjectAJAXHandler} shouldInjectAJAXHandler={this.props.shouldInjectAJAXHandler}
contentInset={this.props.contentInset} contentInset={this.props.contentInset}
automaticallyAdjustContentInsets={this.props.automaticallyAdjustContentInsets} automaticallyAdjustContentInsets={this.props.automaticallyAdjustContentInsets}
@ -182,6 +184,7 @@ var WebView = React.createClass({
var RCTWebView = createReactIOSNativeComponentClass({ var RCTWebView = createReactIOSNativeComponentClass({
validAttributes: merge(ReactIOSViewAttributes.UIView, { validAttributes: merge(ReactIOSViewAttributes.UIView, {
url: true, url: true,
html: true,
contentInset: {diff: insetsDiffer}, contentInset: {diff: insetsDiffer},
automaticallyAdjustContentInsets: true, automaticallyAdjustContentInsets: true,
shouldInjectAJAXHandler: true shouldInjectAJAXHandler: true

View File

@ -60,6 +60,10 @@ function setupDocumentShim() {
if (GLOBAL.document) { if (GLOBAL.document) {
GLOBAL.document.createElement = null; 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) { function handleErrorWithRedBox(e) {

View File

@ -67,8 +67,12 @@ var augmentElement = function(element: ReactElement) {
return element; return element;
}; };
var render = function(component: ReactComponent, mountInto: number) { var render = function(
ReactIOSMount.renderComponent(component, mountInto); element: ReactElement,
mountInto: number,
callback?: ?(() => void)
): ?ReactComponent {
return ReactIOSMount.renderComponent(element, mountInto, callback);
}; };
var ReactIOS = { var ReactIOS = {

View File

@ -24,6 +24,7 @@ var NodeHandle = require('NodeHandle');
var ReactClass = require('ReactClass'); var ReactClass = require('ReactClass');
var ReactComponentEnvironment = require('ReactComponentEnvironment'); var ReactComponentEnvironment = require('ReactComponentEnvironment');
var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy'); var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
var ReactEmptyComponent = require('ReactEmptyComponent');
var ReactInstanceHandles = require('ReactInstanceHandles'); var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactIOSComponentEnvironment = require('ReactIOSComponentEnvironment'); var ReactIOSComponentEnvironment = require('ReactIOSComponentEnvironment');
var ReactIOSComponentMixin = require('ReactIOSComponentMixin'); var ReactIOSComponentMixin = require('ReactIOSComponentMixin');
@ -36,6 +37,8 @@ var ReactUpdates = require('ReactUpdates');
var ResponderEventPlugin = require('ResponderEventPlugin'); var ResponderEventPlugin = require('ResponderEventPlugin');
var UniversalWorkerNodeHandle = require('UniversalWorkerNodeHandle'); var UniversalWorkerNodeHandle = require('UniversalWorkerNodeHandle');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
// Just to ensure this gets packaged, since its only caller is from Native. // Just to ensure this gets packaged, since its only caller is from Native.
require('RCTEventEmitter'); require('RCTEventEmitter');
require('RCTLog'); require('RCTLog');
@ -77,6 +80,13 @@ function inject() {
ReactIOSComponentEnvironment 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); EventPluginUtils.injection.injectMount(ReactIOSMount);
ReactClass.injection.injectMixin(ReactIOSComponentMixin); ReactClass.injection.injectMixin(ReactIOSComponentMixin);

View File

@ -16,13 +16,13 @@ var RCTUIManager = require('NativeModules').UIManager;
var ReactIOSTagHandles = require('ReactIOSTagHandles'); var ReactIOSTagHandles = require('ReactIOSTagHandles');
var ReactPerf = require('ReactPerf'); var ReactPerf = require('ReactPerf');
var ReactReconciler = require('ReactReconciler'); var ReactReconciler = require('ReactReconciler');
var ReactUpdateQueue = require('ReactUpdateQueue');
var ReactUpdates = require('ReactUpdates'); var ReactUpdates = require('ReactUpdates');
var emptyObject = require('emptyObject'); var emptyObject = require('emptyObject');
var instantiateReactComponent = require('instantiateReactComponent'); var instantiateReactComponent = require('instantiateReactComponent');
var invariant = require('invariant'); var invariant = require('invariant');
var shouldUpdateReactComponent = require('shouldUpdateReactComponent');
var TOP_ROOT_NODE_IDS = {};
function instanceNumberToChildRootID(rootNodeID, instanceNumber) { function instanceNumberToChildRootID(rootNodeID, instanceNumber) {
return rootNodeID + '[' + instanceNumber + ']'; return rootNodeID + '[' + instanceNumber + ']';
@ -85,10 +85,26 @@ var ReactIOSMount = {
* @param {containerTag} containerView Handle to native view tag * @param {containerTag} containerView Handle to native view tag
*/ */
renderComponent: function( renderComponent: function(
descriptor: ReactComponent, nextElement: ReactElement,
containerTag: number containerTag: number,
) { callback?: ?(() => void)
var instance = instantiateReactComponent(descriptor); ): ?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)) { if (!ReactIOSTagHandles.reactTagIsNativeTopRootID(containerTag)) {
console.error('You cannot render into anything but a top root'); console.error('You cannot render into anything but a top root');
@ -100,13 +116,14 @@ var ReactIOSMount = {
topRootNodeID, topRootNodeID,
containerTag containerTag
); );
TOP_ROOT_NODE_IDS[topRootNodeID] = true;
var instance = instantiateReactComponent(nextElement);
ReactIOSMount._instancesByContainerID[topRootNodeID] = instance;
var childRootNodeID = instanceNumberToChildRootID( var childRootNodeID = instanceNumberToChildRootID(
topRootNodeID, topRootNodeID,
ReactIOSMount.instanceCount++ ReactIOSMount.instanceCount++
); );
ReactIOSMount._instancesByContainerID[topRootNodeID] = instance;
// The initial render is synchronous but any updates that happen during // The initial render is synchronous but any updates that happen during
// rendering, in componentWillMount or componentDidMount, will be batched // rendering, in componentWillMount or componentDidMount, will be batched
@ -118,6 +135,11 @@ var ReactIOSMount = {
childRootNodeID, childRootNodeID,
topRootNodeID topRootNodeID
); );
var component = instance.getPublicInstance();
if (callback) {
callback.call(component);
}
return component;
}, },
/** /**
@ -170,20 +192,18 @@ var ReactIOSMount = {
* component at this time. * component at this time.
*/ */
unmountComponentAtNode: function(containerTag: number): bool { 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( var containerID = ReactIOSTagHandles.tagToRootNodeID[containerTag];
TOP_ROOT_NODE_IDS[containerID],
'We only currently support removing components from the root node'
);
var instance = ReactIOSMount._instancesByContainerID[containerID]; var instance = ReactIOSMount._instancesByContainerID[containerID];
if (!instance) { if (!instance) {
console.error('Tried to unmount a component that does not exist');
return false; return false;
} }
ReactIOSMount.unmountComponentFromNode(instance, containerID); ReactIOSMount.unmountComponentFromNode(instance, containerID);
delete ReactIOSMount._instancesByContainerID[containerID]; delete ReactIOSMount._instancesByContainerID[containerID];
delete TOP_ROOT_NODE_IDS[containerID];
return true; return true;
}, },
@ -200,10 +220,8 @@ var ReactIOSMount = {
instance: ReactComponent, instance: ReactComponent,
containerID: string containerID: string
) { ) {
// call back into native to remove all of the subviews from this container // Call back into native to remove all of the subviews from this container
// TODO: ReactComponent.prototype.unmountComponent is missing from Flow's ReactReconciler.unmountComponent(instance);
// react lib.
(instance: any).unmountComponent();
var containerTag = var containerTag =
ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(containerID); ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(containerID);
RCTUIManager.removeSubviewsFromContainerWithID(containerTag); RCTUIManager.removeSubviewsFromContainerWithID(containerTag);

View File

@ -1,78 +1,94 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = "React" s.name = "React"
s.version = "0.1.0" s.version = "0.3.1"
s.summary = "Build high quality mobile apps using React." s.summary = "Build high quality mobile apps using React."
s.description= <<-DESC s.description = <<-DESC
React Native apps are built using the React JS framework, React Native apps are built using the React JS
and render directly to native UIKit elements using a fully framework, and render directly to native UIKit
asynchronous architecture. There is no browser and no HTML. elements using a fully asynchronous architecture.
We have picked what we think is the best set of features from There is no browser and no HTML. We have picked what
these and other technologies to build what we hope to become we think is the best set of features from these and
the best product development framework available, with an other technologies to build what we hope to become
emphasis on iteration speed, developer delight, continuity the best product development framework available,
of technology, and absolutely beautiful and fast products with an emphasis on iteration speed, developer
with no compromises in quality or capability. delight, continuity of technology, and absolutely
DESC beautiful and fast products with no compromises in
s.homepage = "http://facebook.github.io/react-native/" quality or capability.
s.license = "BSD" DESC
s.author = "Facebook" s.homepage = "http://facebook.github.io/react-native/"
s.platform = :ios, "7.0" s.license = "BSD"
s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "v#{s.version}" } s.author = "Facebook"
s.source_files = "React/**/*.{c,h,m}" s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "v#{s.version}" }
s.resources = "Resources/*.png" s.default_subspec = 'Core'
s.preserve_paths = "cli.js", "Libraries/**/*.js", "lint", "linter.js", "node_modules", "package.json", "packager", "PATENTS", "react-native-cli" s.requires_arc = true
s.exclude_files = "**/__tests__/*", "IntegrationTests/*" s.platform = :ios, "7.0"
s.frameworks = "JavaScriptCore" s.prepare_command = 'npm install'
s.requires_arc = true s.preserve_paths = "cli.js", "Libraries/**/*.js", "lint", "linter.js", "node_modules", "package.json", "packager", "PATENTS", "react-native-cli"
s.prepare_command = 'npm install' s.header_mappings_dir = "."
s.libraries = 'icucore'
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| s.subspec 'RCTActionSheet' do |ss|
ss.source_files = "Libraries/ActionSheetIOS/*.{h,m}" ss.dependency 'React/Core'
ss.preserve_paths = "Libraries/ActionSheetIOS/*.js" ss.source_files = "Libraries/ActionSheetIOS/*.{h,m}"
ss.preserve_paths = "Libraries/ActionSheetIOS/*.js"
end end
s.subspec 'RCTAdSupport' do |ss| s.subspec 'RCTAdSupport' do |ss|
ss.source_files = "Libraries/RCTAdSupport/*.{h,m}" ss.dependency 'React/Core'
ss.preserve_paths = "Libraries/RCTAdSupport/*.js" ss.source_files = "Libraries/AdSupport/*.{h,m}"
ss.preserve_paths = "Libraries/AdSupport/*.js"
end end
s.subspec 'RCTAnimation' do |ss| s.subspec 'RCTAnimation' do |ss|
ss.source_files = "Libraries/Animation/*.{h,m}" ss.dependency 'React/Core'
ss.preserve_paths = "Libraries/Animation/*.js" ss.source_files = "Libraries/Animation/*.{h,m}"
ss.preserve_paths = "Libraries/Animation/*.js"
end end
s.subspec 'RCTGeolocation' do |ss| s.subspec 'RCTGeolocation' do |ss|
ss.source_files = "Libraries/Geolocation/*.{h,m}" ss.dependency 'React/Core'
ss.preserve_paths = "Libraries/Geolocation/*.js" ss.source_files = "Libraries/Geolocation/*.{h,m}"
ss.preserve_paths = "Libraries/Geolocation/*.js"
end end
s.subspec 'RCTImage' do |ss| s.subspec 'RCTImage' do |ss|
ss.source_files = "Libraries/Image/*.{h,m}" ss.dependency 'React/Core'
ss.preserve_paths = "Libraries/Image/*.js" ss.source_files = "Libraries/Image/*.{h,m}"
ss.preserve_paths = "Libraries/Image/*.js"
end end
s.subspec 'RCTNetwork' do |ss| s.subspec 'RCTNetwork' do |ss|
ss.source_files = "Libraries/Network/*.{h,m}" ss.dependency 'React/Core'
ss.preserve_paths = "Libraries/Network/*.js" ss.source_files = "Libraries/Network/*.{h,m}"
ss.preserve_paths = "Libraries/Network/*.js"
end end
s.subspec 'RCTPushNotification' do |ss| s.subspec 'RCTPushNotification' do |ss|
ss.source_files = "Libraries/PushNotificationIOS/*.{h,m}" ss.dependency 'React/Core'
ss.preserve_paths = "Libraries/PushNotificationIOS/*.js" ss.source_files = "Libraries/PushNotificationIOS/*.{h,m}"
ss.preserve_paths = "Libraries/PushNotificationIOS/*.js"
end end
s.subspec 'RCTWebSocketDebugger' do |ss| 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 end
s.subspec 'RCTText' do |ss| s.subspec 'RCTText' do |ss|
ss.source_files = "Libraries/Text/*.{h,m}" ss.dependency 'React/Core'
ss.preserve_paths = "Libraries/Text/*.js" ss.source_files = "Libraries/Text/*.{h,m}"
ss.preserve_paths = "Libraries/Text/*.js"
end end
s.subspec 'RCTVibration' do |ss| s.subspec 'RCTVibration' do |ss|
ss.source_files = "Libraries/Vibration/*.{h,m}" ss.dependency 'React/Core'
ss.preserve_paths = "Libraries/Vibration/*.js" ss.source_files = "Libraries/Vibration/*.{h,m}"
ss.preserve_paths = "Libraries/Vibration/*.js"
end end
end end

View File

@ -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); return RCTMakeAndLogError(@"Entries must be arrays of the form [key: string, value: string], got: ", entry, nil);
} }
if (![entry[1] isKindOfClass:[NSString class]]) { 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]; NSString *key = entry[0];
id errorOut = RCTErrorForKey(key); id errorOut = RCTErrorForKey(key);

View File

@ -507,7 +507,7 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
{ {
RCT_EXPORT(); RCT_EXPORT();
id<RCTViewNodeProtocol> container = _viewRegistry[containerID]; id<RCTViewNodeProtocol> container = _shadowViewRegistry[containerID];
RCTAssert(container != nil, @"container view (for ID %@) not found", containerID); RCTAssert(container != nil, @"container view (for ID %@) not found", containerID);
NSUInteger subviewsCount = [[container reactSubviews] count]; NSUInteger subviewsCount = [[container reactSubviews] count];
@ -1051,13 +1051,27 @@ static void RCTMeasureLayout(RCTShadowView *view,
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){ [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
UIView *view = viewRegistry[reactTag]; UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) { if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
[(id<RCTScrollableProtocol>)view scrollToOffset:CGPointMake([offsetX floatValue], [offsetY floatValue])]; [(id<RCTScrollableProtocol>)view scrollToOffset:CGPointMake([offsetX floatValue], [offsetY floatValue]) animated:YES];
} else { } else {
RCTLogError(@"tried to scrollToOffset: on non-RCTScrollableProtocol view %@ with tag %@", view, reactTag); 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<RCTScrollableProtocol>)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 - (void)zoomToRectWithView:(NSNumber *)reactTag rect:(NSDictionary *)rectDict
{ {
RCT_EXPORT(zoomToRect); RCT_EXPORT(zoomToRect);

View File

@ -79,7 +79,7 @@ RCT_REMAP_VIEW_PROPERTY(testID, accessibilityIdentifier, NSString)
RCT_REMAP_VIEW_PROPERTY(opacity, alpha, CGFloat) RCT_REMAP_VIEW_PROPERTY(opacity, alpha, CGFloat)
RCT_REMAP_VIEW_PROPERTY(shadowColor, layer.shadowColor, CGColor); RCT_REMAP_VIEW_PROPERTY(shadowColor, layer.shadowColor, CGColor);
RCT_REMAP_VIEW_PROPERTY(shadowOffset, layer.shadowOffset, CGSize); 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(shadowRadius, layer.shadowRadius, CGFloat)
RCT_REMAP_VIEW_PROPERTY(transformMatrix, layer.transform, CATransform3D) RCT_REMAP_VIEW_PROPERTY(transformMatrix, layer.transform, CATransform3D)
RCT_CUSTOM_VIEW_PROPERTY(overflow, css_overflow, RCTView) RCT_CUSTOM_VIEW_PROPERTY(overflow, css_overflow, RCTView)

View File

@ -73,6 +73,11 @@
[_webView loadRequest:[NSURLRequest requestWithURL:URL]]; [_webView loadRequest:[NSURLRequest requestWithURL:URL]];
} }
- (void)setHTML:(NSString *)HTML
{
[_webView loadHTMLString:HTML baseURL:nil];
}
- (void)layoutSubviews - (void)layoutSubviews
{ {
[super layoutSubviews]; [super layoutSubviews];

View File

@ -22,8 +22,9 @@
} }
RCT_REMAP_VIEW_PROPERTY(url, URL, NSURL); RCT_REMAP_VIEW_PROPERTY(url, URL, NSURL);
RCT_REMAP_VIEW_PROPERTY(html, HTML, NSString);
RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets); RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets);
RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, UIEdgeInsets); RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, BOOL);
RCT_EXPORT_VIEW_PROPERTY(shouldInjectAJAXHandler, BOOL); RCT_EXPORT_VIEW_PROPERTY(shouldInjectAJAXHandler, BOOL);
- (NSDictionary *)constantsToExport - (NSDictionary *)constantsToExport

View File

@ -1,6 +1,6 @@
{ {
"name": "react-native", "name": "react-native",
"version": "0.3.0", "version": "0.3.1",
"description": "A framework for building native apps using React", "description": "A framework for building native apps using React",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -66,7 +66,7 @@ ws.onopen = function() {
setStatus('Debugger session #' + sessionID + ' active'); setStatus('Debugger session #' + sessionID + ' active');
ws.send(JSON.stringify({replyID: parseInt(sessionID, 10)})); ws.send(JSON.stringify({replyID: parseInt(sessionID, 10)}));
} else { } else {
setStatus('Waiting for simulator'); setStatus('Waiting, press ⌘R in simulator to reload and connect');
} }
} }

View File

@ -14,6 +14,7 @@ jest
.dontMock('path') .dontMock('path')
.dontMock('absolute-path') .dontMock('absolute-path')
.dontMock('../docblock') .dontMock('../docblock')
.dontMock('../../requirePattern')
.setMock('../../../ModuleDescriptor', function(data) {return data;}); .setMock('../../../ModuleDescriptor', function(data) {return data;});
describe('DependencyGraph', function() { describe('DependencyGraph', function() {

View File

@ -12,6 +12,7 @@ var ModuleDescriptor = require('../../ModuleDescriptor');
var q = require('q'); var q = require('q');
var fs = require('fs'); var fs = require('fs');
var docblock = require('./docblock'); var docblock = require('./docblock');
var requirePattern = require('../requirePattern');
var path = require('path'); var path = require('path');
var isAbsolutePath = require('absolute-path'); var isAbsolutePath = require('absolute-path');
var debug = require('debug')('DependecyGraph'); var debug = require('debug')('DependecyGraph');
@ -600,7 +601,6 @@ DependecyGraph.prototype._processAssetChange = function(eventType, file) {
/** /**
* Extract all required modules from a `code` string. * Extract all required modules from a `code` string.
*/ */
var requireRe = /\brequire\s*\(\s*[\'"]([^"\']+)["\']\s*\)/g;
var blockCommentRe = /\/\*(.|\n)*?\*\//g; var blockCommentRe = /\/\*(.|\n)*?\*\//g;
var lineCommentRe = /\/\/.+(\n|$)/g; var lineCommentRe = /\/\/.+(\n|$)/g;
function extractRequires(code) { function extractRequires(code) {
@ -609,7 +609,7 @@ function extractRequires(code) {
code code
.replace(blockCommentRe, '') .replace(blockCommentRe, '')
.replace(lineCommentRe, '') .replace(lineCommentRe, '')
.replace(requireRe, function(match, dep) { .replace(requirePattern, function(match, _, dep) {
deps.push(dep); deps.push(dep);
}); });

View File

@ -10,6 +10,7 @@
jest.dontMock('../') jest.dontMock('../')
.dontMock('q') .dontMock('q')
.dontMock('../requirePattern')
.setMock('../../ModuleDescriptor', function(data) {return data;}); .setMock('../../ModuleDescriptor', function(data) {return data;});
var q = require('q'); var q = require('q');
@ -226,11 +227,13 @@ describe('HasteDependencyResolver', function() {
}); });
var depGraph = depResolver._depGraph; var depGraph = depResolver._depGraph;
var dependencies = ['x', 'y', 'z']; var dependencies = ['x', 'y', 'z', 'a', 'b'];
var code = [ var code = [
'require("x")', 'require("x")',
'require("y")', 'require("y")',
'require("z")', 'require( "z" )',
'require( "a")',
'require("b" )',
].join('\n'); ].join('\n');
depGraph.resolveDependency.mockImpl(function(fromModule, toModuleName) { depGraph.resolveDependency.mockImpl(function(fromModule, toModuleName) {
@ -255,7 +258,9 @@ describe('HasteDependencyResolver', function() {
' require, requireDynamic, requireLazy, module, exports) {' + ' require, requireDynamic, requireLazy, module, exports) {' +
' require(\'changed\')', ' require(\'changed\')',
'require(\'y\')', 'require(\'y\')',
'require("z")});', 'require("z")',
'require("a")',
'require("b")});',
].join('\n')); ].join('\n'));
}); });
}); });

View File

@ -9,8 +9,8 @@
'use strict'; 'use strict';
var path = require('path'); var path = require('path');
var FileWatcher = require('../../FileWatcher');
var DependencyGraph = require('./DependencyGraph'); var DependencyGraph = require('./DependencyGraph');
var requirePattern = require('./requirePattern');
var ModuleDescriptor = require('../ModuleDescriptor'); var ModuleDescriptor = require('../ModuleDescriptor');
var declareOpts = require('../../lib/declareOpts'); var declareOpts = require('../../lib/declareOpts');
@ -25,7 +25,6 @@ var DEFINE_MODULE_CODE = [
].join(''); ].join('');
var DEFINE_MODULE_REPLACE_RE = /_moduleName_|_code_|_deps_/g; var DEFINE_MODULE_REPLACE_RE = /_moduleName_|_code_|_deps_/g;
var REL_REQUIRE_STMT = /require\(['"]([\.\/0-9A-Z_$\-]*)['"]\)/gi;
var validateOpts = declareOpts({ var validateOpts = declareOpts({
projectRoots: { projectRoots: {
@ -146,12 +145,12 @@ HasteDependencyResolver.prototype.wrapModule = function(module, code) {
} }
var relativizedCode = var relativizedCode =
code.replace(REL_REQUIRE_STMT, function(codeMatch, depName) { code.replace(requirePattern, function(codeMatch, _, depName) {
var depId = resolvedDeps[depName]; var depId = resolvedDeps[depName];
if (depId != null) { if (depId != null) {
return 'require(\'' + depId + '\')'; return 'require(\'' + depId + '\')';
} else { } else {
return codeMatch; return codeMatch.replace(/\s+/g, '');
} }
}); });

View File

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