Updates from Tue 31 Mar

- 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
This commit is contained in:
Christopher Chedeau
2015-03-31 19:01:48 -07:00
parent e90ede3ce2
commit 18cb5d0711
22 changed files with 205 additions and 88 deletions

View File

@@ -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}
/>
);
},

View File

@@ -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},

View File

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

View File

@@ -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) {

View File

@@ -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 = {

View File

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

View File

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