Skip to content

Commit

Permalink
Sync React Native with React 16.0.0-alpha.3
Browse files Browse the repository at this point in the history
Reviewed By: sebmarkbage

Differential Revision: D4615201

fbshipit-source-id: fc62b44aa866e096faa1cb048db361bb8c6ab11f
  • Loading branch information
acdlite authored and facebook-github-bot committed Feb 27, 2017
1 parent 2d44908 commit 24a7665
Show file tree
Hide file tree
Showing 24 changed files with 6,652 additions and 257 deletions.
4 changes: 2 additions & 2 deletions Libraries/Animated/src/AnimatedImplementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ class Animated {
throw new Error('This node cannot be made a "native" animated node');
}
}
__getNativeTag(): number {
__getNativeTag(): ?number {
NativeAnimatedHelper.assertNativeAnimatedModule();
invariant(this.__isNative, 'Attempt to get native tag from node not marked as "native"');
if (this.__nativeTag == null) {
var nativeTag: number = NativeAnimatedHelper.generateNewNodeTag();
var nativeTag: ?number = NativeAnimatedHelper.generateNewNodeTag();
NativeAnimatedAPI.createAnimatedNode(nativeTag, this.__getNativeConfig());
this.__nativeTag = nativeTag;
}
Expand Down
34 changes: 17 additions & 17 deletions Libraries/Animated/src/NativeAnimatedHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type EndResult = {finished: boolean};
type EndCallback = (result: EndResult) => void;
type EventMapping = {
nativeEventPath: Array<string>,
animatedValueTag: number,
animatedValueTag: ?number,
};

let nativeEventEmitter;
Expand All @@ -33,67 +33,67 @@ let nativeEventEmitter;
* the native module methods
*/
const API = {
createAnimatedNode: function(tag: number, config: Object): void {
createAnimatedNode: function(tag: ?number, config: Object): void {
assertNativeAnimatedModule();
NativeAnimatedModule.createAnimatedNode(tag, config);
},
startListeningToAnimatedNodeValue: function(tag: number) {
startListeningToAnimatedNodeValue: function(tag: ?number) {
assertNativeAnimatedModule();
NativeAnimatedModule.startListeningToAnimatedNodeValue(tag);
},
stopListeningToAnimatedNodeValue: function(tag: number) {
stopListeningToAnimatedNodeValue: function(tag: ?number) {
assertNativeAnimatedModule();
NativeAnimatedModule.stopListeningToAnimatedNodeValue(tag);
},
connectAnimatedNodes: function(parentTag: number, childTag: number): void {
connectAnimatedNodes: function(parentTag: ?number, childTag: ?number): void {
assertNativeAnimatedModule();
NativeAnimatedModule.connectAnimatedNodes(parentTag, childTag);
},
disconnectAnimatedNodes: function(parentTag: number, childTag: number): void {
disconnectAnimatedNodes: function(parentTag: ?number, childTag: ?number): void {
assertNativeAnimatedModule();
NativeAnimatedModule.disconnectAnimatedNodes(parentTag, childTag);
},
startAnimatingNode: function(animationId: number, nodeTag: number, config: Object, endCallback: EndCallback): void {
startAnimatingNode: function(animationId: ?number, nodeTag: ?number, config: Object, endCallback: EndCallback): void {
assertNativeAnimatedModule();
NativeAnimatedModule.startAnimatingNode(animationId, nodeTag, config, endCallback);
},
stopAnimation: function(animationId: number) {
stopAnimation: function(animationId: ?number) {
assertNativeAnimatedModule();
NativeAnimatedModule.stopAnimation(animationId);
},
setAnimatedNodeValue: function(nodeTag: number, value: number): void {
setAnimatedNodeValue: function(nodeTag: ?number, value: ?number): void {
assertNativeAnimatedModule();
NativeAnimatedModule.setAnimatedNodeValue(nodeTag, value);
},
setAnimatedNodeOffset: function(nodeTag: number, offset: number): void {
setAnimatedNodeOffset: function(nodeTag: ?number, offset: ?number): void {
assertNativeAnimatedModule();
NativeAnimatedModule.setAnimatedNodeOffset(nodeTag, offset);
},
flattenAnimatedNodeOffset: function(nodeTag: number): void {
flattenAnimatedNodeOffset: function(nodeTag: ?number): void {
assertNativeAnimatedModule();
NativeAnimatedModule.flattenAnimatedNodeOffset(nodeTag);
},
extractAnimatedNodeOffset: function(nodeTag: number): void {
extractAnimatedNodeOffset: function(nodeTag: ?number): void {
assertNativeAnimatedModule();
NativeAnimatedModule.extractAnimatedNodeOffset(nodeTag);
},
connectAnimatedNodeToView: function(nodeTag: number, viewTag: number): void {
connectAnimatedNodeToView: function(nodeTag: ?number, viewTag: ?number): void {
assertNativeAnimatedModule();
NativeAnimatedModule.connectAnimatedNodeToView(nodeTag, viewTag);
},
disconnectAnimatedNodeFromView: function(nodeTag: number, viewTag: number): void {
disconnectAnimatedNodeFromView: function(nodeTag: ?number, viewTag: ?number): void {
assertNativeAnimatedModule();
NativeAnimatedModule.disconnectAnimatedNodeFromView(nodeTag, viewTag);
},
dropAnimatedNode: function(tag: number): void {
dropAnimatedNode: function(tag: ?number): void {
assertNativeAnimatedModule();
NativeAnimatedModule.dropAnimatedNode(tag);
},
addAnimatedEventToView: function(viewTag: number, eventName: string, eventMapping: EventMapping) {
addAnimatedEventToView: function(viewTag: ?number, eventName: string, eventMapping: EventMapping) {
assertNativeAnimatedModule();
NativeAnimatedModule.addAnimatedEventToView(viewTag, eventName, eventMapping);
},
removeAnimatedEventFromView(viewTag: number, eventName: string) {
removeAnimatedEventFromView(viewTag: ?number, eventName: string) {
assertNativeAnimatedModule();
NativeAnimatedModule.removeAnimatedEventFromView(viewTag, eventName);
}
Expand Down
2 changes: 1 addition & 1 deletion Libraries/Renderer/src/ReactVersion.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@

'use strict';

module.exports = '16.0.0-alpha.2';
module.exports = '16.0.0-alpha.3';
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function uncacheNode(inst) {

function uncacheFiberNode(tag) {
delete instanceCache[tag];
delete instanceProps[tag];
}

function getInstanceFromTag(tag) {
Expand All @@ -61,7 +62,9 @@ function getInstanceFromTag(tag) {

function getTagFromInstance(inst) {
// TODO (bvaughn) Clean up once Stack is deprecated
var tag = inst._rootNodeID || inst.stateNode._nativeTag;
var tag = typeof inst.tag !== 'number'
? inst._rootNodeID
: inst.stateNode._nativeTag;
invariant(tag, 'All native instances should have a tag.');
return tag;
}
Expand Down
6 changes: 1 addition & 5 deletions Libraries/Renderer/src/renderers/native/ReactNativeFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,7 @@ const NativeRenderer = ReactFiberReconciler({
},

appendInitialChild(parentInstance : Instance, child : Instance | TextInstance) : void {
if (typeof child === 'number') {
parentInstance._children.push(child);
} else {
parentInstance._children.push(child);
}
parentInstance._children.push(child);
},

commitTextUpdate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ var ReactNativeGlobalResponderHandler = {
onChange: function(from, to, blockNativeResponder) {
if (to !== null) {
// TODO (bvaughn) Clean up once Stack is deprecated
UIManager.setJSResponder(
to._rootNodeID || to.stateNode._nativeTag,
blockNativeResponder
);
var tag = typeof to.tag !== 'number'
? to._rootNodeID
: to.stateNode._nativeTag;
UIManager.setJSResponder(tag, blockNativeResponder);
} else {
UIManager.clearJSResponder();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var RCTEventEmitter;
var React;
var ReactErrorUtils;
var ReactNative;
var ResponderEventPlugin;
var UIManager;
var createReactNativeComponentClass;

Expand All @@ -25,6 +26,7 @@ beforeEach(() => {
React = require('React');
ReactErrorUtils = require('ReactErrorUtils');
ReactNative = require('ReactNative');
ResponderEventPlugin = require('ResponderEventPlugin');
UIManager = require('UIManager');
createReactNativeComponentClass = require('createReactNativeComponentClass');

Expand Down Expand Up @@ -91,3 +93,97 @@ it('handles events', () => {
'outer touchend',
]);
});

it('handles when a responder is unmounted while a touch sequence is in progress', () => {
var EventEmitter = RCTEventEmitter.register.mock.calls[0][0];
var View = createReactNativeComponentClass({
validAttributes: { id: true },
uiViewClassName: 'View',
});

function getViewById(id) {
return UIManager.createView.mock.calls.find(
args => args[3] && args[3].id === id
)[0];
}

function getResponderId() {
const responder = ResponderEventPlugin._getResponder();
if (responder === null) {
return null;
}
const props = typeof responder.tag === 'number'
? responder.memoizedProps
: responder._currentElement.props;
return props ? props.id : null;
}

var log = [];
ReactNative.render(
<View id="parent">
<View key={1}>
<View
id="one"
onResponderEnd={() => log.push('one responder end')}
onResponderStart={() => log.push('one responder start')}
onStartShouldSetResponder={() => true}
/>
</View>
<View key={2}>
<View
id="two"
onResponderEnd={() => log.push('two responder end')}
onResponderStart={() => log.push('two responder start')}
onStartShouldSetResponder={() => true}
/>
</View>
</View>,
1
);

EventEmitter.receiveTouches(
'topTouchStart',
[{target: getViewById('one'), identifier: 17}],
[0]
);

expect(getResponderId()).toBe('one');
expect(log).toEqual(['one responder start']);
log.splice(0);

ReactNative.render(
<View id="parent">
<View key={2}>
<View
id="two"
onResponderEnd={() => log.push('two responder end')}
onResponderStart={() => log.push('two responder start')}
onStartShouldSetResponder={() => true}
/>
</View>
</View>,
1
);

// TODO Verify the onResponderEnd listener has been called (before the unmount)
// expect(log).toEqual(['one responder end']);
// log.splice(0);

EventEmitter.receiveTouches(
'topTouchEnd',
[{target: getViewById('two'), identifier: 17}],
[0]
);

expect(getResponderId()).toBeNull();
expect(log).toEqual([]);

EventEmitter.receiveTouches(
'topTouchStart',
[{target: getViewById('two'), identifier: 17}],
[0]
);

expect(getResponderId()).toBe('two');
expect(log).toEqual(['two responder start']);
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ type ReactNativeBaseComponentViewConfig = {
* @param {string} config iOS View configuration.
* @private
*/
const createReactNativeFiberComponentClass = function(
viewConfig: ReactNativeBaseComponentViewConfig
): ReactClass<any> {
// TODO(sema): This actually returns a string. Need to fix this before
// we deploy Fiber.
return (ReactNativeViewConfigRegistry.register(viewConfig) : any);
};

const createReactNativeFiberComponentClass = function(
viewConfig: ReactNativeBaseComponentViewConfig
): ReactClass<any> {
// TODO(sema): This actually returns a string. Need to fix this before
// we deploy Fiber.
return (ReactNativeViewConfigRegistry.register(viewConfig) : any);
};
/**
* @param {string} config iOS View configuration.
* @private
Expand All @@ -59,6 +59,6 @@ const createReactNativeComponentClass = function(
return ((Constructor: any): ReactClass<any>);
};

module.exports = (ReactNativeFeatureFlags.useFiber
module.exports = ReactNativeFeatureFlags.useFiber
? createReactNativeFiberComponentClass
: createReactNativeComponentClass);
: createReactNativeComponentClass;
3 changes: 1 addition & 2 deletions Libraries/Renderer/src/renderers/native/findNodeHandle.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ import type { ReactInstance } from 'ReactInstanceType';
let injectedFindNode;
let injectedFindRootNodeID;

// TODO(sema): Type this more specifically.
function findNodeHandle(componentOrHandle: any): any {
function findNodeHandle(componentOrHandle: any): ?number {
if (__DEV__) {
// TODO: fix this unsafe cast to work with Fiber.
var owner = ((ReactCurrentOwner.current: any): ReactInstance | null);
Expand Down
4 changes: 4 additions & 0 deletions Libraries/Renderer/src/renderers/shared/fiber/ReactFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,12 @@ var createFiber = function(tag : TypeOfWork, key : null | string) : Fiber {
fiber._debugID = debugCounter++;
fiber._debugSource = null;
fiber._debugOwner = null;
if (typeof Object.preventExtensions === 'function') {
Object.preventExtensions(fiber);
}
}


return fiber;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ var invariant = require('fbjs/lib/invariant');
if (__DEV__) {
var ReactDebugCurrentFiber = require('ReactDebugCurrentFiber');
var warning = require('fbjs/lib/warning');

var warnedAboutStatelessRefs = {};
}

Expand Down Expand Up @@ -479,6 +478,15 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
// Proceed under the assumption that this is a functional component
workInProgress.tag = FunctionalComponent;
if (__DEV__) {
const Component = workInProgress.type;

if (Component) {
warning(
!Component.childContextTypes,
'%s(...): childContextTypes cannot be defined on a functional component.',
Component.displayName || Component.name || 'Component'
);
}
if (workInProgress.ref !== null) {
let info = '';
const ownerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ module.exports = function(

instance.props = props;
instance.state = state;
instance.refs = emptyObject;
instance.context = getMaskedContext(workInProgress, unmaskedContext);

if (typeof instance.componentWillMount === 'function') {
Expand Down Expand Up @@ -408,6 +409,19 @@ module.exports = function(
if (oldProps !== newProps || oldContext !== newContext) {
if (typeof instance.componentWillReceiveProps === 'function') {
instance.componentWillReceiveProps(newProps, newContext);

if (instance.state !== workInProgress.memoizedState) {
if (__DEV__) {
warning(
false,
'%s.componentWillReceiveProps(): Assigning directly to ' +
'this.state is deprecated (except inside a component\'s ' +
'constructor). Use setState instead.',
getComponentName(workInProgress)
);
}
updater.enqueueReplaceState(instance, instance.state, null);
}
}
}

Expand Down
Loading

0 comments on commit 24a7665

Please sign in to comment.