Skip to content

Commit

Permalink
Updates from Tue 31 Mar
Browse files Browse the repository at this point in the history
- Bugfix/require module regexp | Amjad Masad
- [ReactNative] RCTView's shadowOffset is of float type, not CGFloat | Kevin Gozali
- Fix WebView automaticallyAdjustContentInsets error | Spencer Ahrens
- [react-native] map view - add onTouch** props | Jiajie Zhu
- [react-native] Fix documentation extraction for View | Ben Alpert
- [ReactNative] Add few hints in the UI | Alex Kotliarskyi
- Adding `scrollWithoutAnimationTo` method for ScrollViews | Felix Oghina
- [ScrollView] Add "bounces" property to ScrollView propTypes | Spencer Ahrens
- Fix a crash in RCTAsyncLocalStorage when the value is not a string. | Spencer Ahrens
- [ReactNative] Remove global MutationObserver to fix Bluebird feature detection | Christopher Chedeau
- [catalyst] fix typo | Jiajie Zhu
- [react-packager] check-in bluebird | Amjad Masad
- [react-native] v0.3.1 | Amjad Masad
- [Pod] Preserve header directory structure | Alex Akers
- [react-native] Bring React.render behavior in line with web | Ben Alpert
- Expose html prop on WebView | Spencer Ahrens
- missing '.' in ListView.DataSource example | Christopher Chedeau
- [react-native] Support returning null from a component | Ben Alpert
- [react-native] Fix race condition in removeSubviewsFromContainerWithID: | Ben Alpert
  • Loading branch information
vjeux committed Apr 1, 2015
1 parent e90ede3 commit 18cb5d0
Show file tree
Hide file tree
Showing 22 changed files with 205 additions and 88 deletions.
8 changes: 6 additions & 2 deletions Examples/SampleApp/index.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ var SampleApp = React.createClass({
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js{'\n'}
Press Cmd+R to reload
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+Shift+Z for dev menu
</Text>
</View>
);
Expand All @@ -43,6 +46,7 @@ var styles = StyleSheet.create({
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});

Expand Down
2 changes: 1 addition & 1 deletion Examples/UIExplorer/UIExplorerPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ?
Expand Down
3 changes: 3 additions & 0 deletions Libraries/Components/MapView/MapView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}
/>
);
},
Expand Down
18 changes: 17 additions & 1 deletion Libraries/Components/ScrollView/ScrollView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -308,6 +323,7 @@ var validAttributes = {
alwaysBounceHorizontal: true,
alwaysBounceVertical: true,
automaticallyAdjustContentInsets: true,
bounces: true,
centerContent: true,
contentInset: {diff: insetsDiffer},
contentOffset: {diff: pointsDiffer},
Expand Down
5 changes: 4 additions & 1 deletion Libraries/Components/WebView/WebView.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
8 changes: 6 additions & 2 deletions Libraries/ReactIOS/ReactIOS.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
10 changes: 10 additions & 0 deletions Libraries/ReactIOS/ReactIOSDefaultInjection.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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');
Expand Down Expand Up @@ -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);
Expand Down
56 changes: 37 additions & 19 deletions Libraries/ReactIOS/ReactIOSMount.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 + ']';
Expand Down Expand Up @@ -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');
Expand All @@ -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
Expand All @@ -118,6 +135,11 @@ var ReactIOSMount = {
childRootNodeID,
topRootNodeID
);
var component = instance.getPublicInstance();
if (callback) {
callback.call(component);
}
return component;
},

/**
Expand Down Expand Up @@ -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;
},

Expand All @@ -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);
Expand Down
Loading

0 comments on commit 18cb5d0

Please sign in to comment.