[ReactNative] Fix ResponderEventPlugin after React upgrade
This commit is contained in:
parent
87ce2d635b
commit
e0ea046092
|
@ -10,11 +10,8 @@
|
|||
# Ignore react-tools where there are overlaps, but don't ignore anything that
|
||||
# react-native relies on
|
||||
.*/node_modules/react-tools/src/React.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/reconciler/ReactInstanceHandles.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderSyntheticEvent.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderTouchHistoryStore.js
|
||||
.*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js
|
||||
|
||||
# Ignore commoner tests
|
||||
|
|
|
@ -10,11 +10,8 @@
|
|||
# Ignore react-tools where there are overlaps, but don't ignore anything that
|
||||
# react-native relies on
|
||||
.*/node_modules/react-tools/src/React.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/reconciler/ReactInstanceHandles.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderSyntheticEvent.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderTouchHistoryStore.js
|
||||
.*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js
|
||||
|
||||
|
||||
|
|
|
@ -121,7 +121,8 @@ var ReactNativeEventEmitter = merge(ReactEventEmitterMixin, {
|
|||
topLevelType,
|
||||
rootNodeID,
|
||||
rootNodeID,
|
||||
nativeEvent
|
||||
nativeEvent,
|
||||
nativeEvent.target
|
||||
);
|
||||
},
|
||||
|
||||
|
|
|
@ -253,12 +253,12 @@ var ReactNativeMount = {
|
|||
RCTUIManager.removeSubviewsFromContainerWithID(containerTag);
|
||||
},
|
||||
|
||||
getNode: function<T>(id: T): T {
|
||||
return id;
|
||||
getNode: function(rootNodeID: string): number {
|
||||
return ReactNativeTagHandles.rootNodeIDToTag[rootNodeID];
|
||||
},
|
||||
|
||||
getID: function<T>(id: T): T {
|
||||
return id;
|
||||
getID: function(nativeTag: number): string {
|
||||
return ReactNativeTagHandles.tagToRootNodeID[nativeTag];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
/**
|
||||
* Copyright 2013-2014 Facebook, Inc.
|
||||
* Copyright 2013-2015, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* 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.
|
||||
*
|
||||
* @providesModule ResponderEventPlugin
|
||||
*/
|
||||
|
@ -21,7 +14,6 @@
|
|||
var EventConstants = require('EventConstants');
|
||||
var EventPluginUtils = require('EventPluginUtils');
|
||||
var EventPropagators = require('EventPropagators');
|
||||
var NodeHandle = require('NodeHandle');
|
||||
var ReactInstanceHandles = require('ReactInstanceHandles');
|
||||
var ResponderSyntheticEvent = require('ResponderSyntheticEvent');
|
||||
var ResponderTouchHistoryStore = require('ResponderTouchHistoryStore');
|
||||
|
@ -75,8 +67,8 @@ var eventTypes = {
|
|||
startShouldSetResponder: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: keyOf({onStartShouldSetResponder: null}),
|
||||
captured: keyOf({onStartShouldSetResponderCapture: null})
|
||||
}
|
||||
captured: keyOf({onStartShouldSetResponderCapture: null}),
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -91,8 +83,8 @@ var eventTypes = {
|
|||
scrollShouldSetResponder: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: keyOf({onScrollShouldSetResponder: null}),
|
||||
captured: keyOf({onScrollShouldSetResponderCapture: null})
|
||||
}
|
||||
captured: keyOf({onScrollShouldSetResponderCapture: null}),
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -105,8 +97,8 @@ var eventTypes = {
|
|||
selectionChangeShouldSetResponder: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: keyOf({onSelectionChangeShouldSetResponder: null}),
|
||||
captured: keyOf({onSelectionChangeShouldSetResponderCapture: null})
|
||||
}
|
||||
captured: keyOf({onSelectionChangeShouldSetResponderCapture: null}),
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -116,8 +108,8 @@ var eventTypes = {
|
|||
moveShouldSetResponder: {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: keyOf({onMoveShouldSetResponder: null}),
|
||||
captured: keyOf({onMoveShouldSetResponderCapture: null})
|
||||
}
|
||||
captured: keyOf({onMoveShouldSetResponderCapture: null}),
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -128,11 +120,11 @@ var eventTypes = {
|
|||
responderEnd: {registrationName: keyOf({onResponderEnd: null})},
|
||||
responderRelease: {registrationName: keyOf({onResponderRelease: null})},
|
||||
responderTerminationRequest: {
|
||||
registrationName: keyOf({onResponderTerminationRequest: null})
|
||||
registrationName: keyOf({onResponderTerminationRequest: null}),
|
||||
},
|
||||
responderGrant: {registrationName: keyOf({onResponderGrant: null})},
|
||||
responderReject: {registrationName: keyOf({onResponderReject: null})},
|
||||
responderTerminate: {registrationName: keyOf({onResponderTerminate: null})}
|
||||
responderTerminate: {registrationName: keyOf({onResponderTerminate: null})},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -141,7 +133,7 @@ var eventTypes = {
|
|||
* ----------------
|
||||
*
|
||||
* - A global, solitary "interaction lock" on a view.
|
||||
* - If a `NodeHandle` becomes the responder, it should convey visual feedback
|
||||
* - If a node becomes the responder, it should convey visual feedback
|
||||
* immediately to indicate so, either by highlighting or moving accordingly.
|
||||
* - To be the responder means, that touches are exclusively important to that
|
||||
* responder view, and no other view.
|
||||
|
@ -334,7 +326,8 @@ to return true:wantsResponderID| |
|
|||
function setResponderAndExtractTransfer(
|
||||
topLevelType,
|
||||
topLevelTargetID,
|
||||
nativeEvent) {
|
||||
nativeEvent,
|
||||
nativeEventTarget) {
|
||||
var shouldSetEventType =
|
||||
isStartish(topLevelType) ? eventTypes.startShouldSetResponder :
|
||||
isMoveish(topLevelType) ? eventTypes.moveShouldSetResponder :
|
||||
|
@ -345,7 +338,7 @@ function setResponderAndExtractTransfer(
|
|||
// TODO: stop one short of the the current responder.
|
||||
var bubbleShouldSetFrom = !responderID ?
|
||||
topLevelTargetID :
|
||||
ReactInstanceHandles._getFirstCommonAncestorID(responderID, topLevelTargetID);
|
||||
ReactInstanceHandles.getFirstCommonAncestorID(responderID, topLevelTargetID);
|
||||
|
||||
// When capturing/bubbling the "shouldSet" event, we want to skip the target
|
||||
// (deepest ID) if it happens to be the current responder. The reasoning:
|
||||
|
@ -355,7 +348,8 @@ function setResponderAndExtractTransfer(
|
|||
var shouldSetEvent = ResponderSyntheticEvent.getPooled(
|
||||
shouldSetEventType,
|
||||
bubbleShouldSetFrom,
|
||||
nativeEvent
|
||||
nativeEvent,
|
||||
nativeEventTarget
|
||||
);
|
||||
shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
||||
if (skipOverBubbleShouldSetFrom) {
|
||||
|
@ -375,7 +369,8 @@ function setResponderAndExtractTransfer(
|
|||
var grantEvent = ResponderSyntheticEvent.getPooled(
|
||||
eventTypes.responderGrant,
|
||||
wantsResponderID,
|
||||
nativeEvent
|
||||
nativeEvent,
|
||||
nativeEventTarget
|
||||
);
|
||||
grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
||||
|
||||
|
@ -386,7 +381,8 @@ function setResponderAndExtractTransfer(
|
|||
var terminationRequestEvent = ResponderSyntheticEvent.getPooled(
|
||||
eventTypes.responderTerminationRequest,
|
||||
responderID,
|
||||
nativeEvent
|
||||
nativeEvent,
|
||||
nativeEventTarget
|
||||
);
|
||||
terminationRequestEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
||||
EventPropagators.accumulateDirectDispatches(terminationRequestEvent);
|
||||
|
@ -401,7 +397,8 @@ function setResponderAndExtractTransfer(
|
|||
var terminateEvent = ResponderSyntheticEvent.getPooled(
|
||||
terminateType,
|
||||
responderID,
|
||||
nativeEvent
|
||||
nativeEvent,
|
||||
nativeEventTarget
|
||||
);
|
||||
terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
||||
EventPropagators.accumulateDirectDispatches(terminateEvent);
|
||||
|
@ -411,7 +408,8 @@ function setResponderAndExtractTransfer(
|
|||
var rejectEvent = ResponderSyntheticEvent.getPooled(
|
||||
eventTypes.responderReject,
|
||||
wantsResponderID,
|
||||
nativeEvent
|
||||
nativeEvent,
|
||||
nativeEventTarget
|
||||
);
|
||||
rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
||||
EventPropagators.accumulateDirectDispatches(rejectEvent);
|
||||
|
@ -447,7 +445,7 @@ function canTriggerTransfer(topLevelType, topLevelTargetID) {
|
|||
* longer any touches that started inside of the current `responderID`.
|
||||
*
|
||||
* @param {NativeEvent} nativeEvent Native touch end event.
|
||||
* @return {bool} Whether or not this touch end event ends the responder.
|
||||
* @return {boolean} Whether or not this touch end event ends the responder.
|
||||
*/
|
||||
function noResponderTouches(nativeEvent) {
|
||||
var touches = nativeEvent.touches;
|
||||
|
@ -459,12 +457,12 @@ function noResponderTouches(nativeEvent) {
|
|||
var target = activeTouch.target;
|
||||
if (target !== null && target !== undefined && target !== 0) {
|
||||
// Is the original touch location inside of the current responder?
|
||||
var commonAncestor =
|
||||
ReactInstanceHandles._getFirstCommonAncestorID(
|
||||
var isAncestor =
|
||||
ReactInstanceHandles.isAncestorIDOf(
|
||||
responderID,
|
||||
NodeHandle.getRootNodeID(target)
|
||||
EventPluginUtils.getID(target)
|
||||
);
|
||||
if (commonAncestor === responderID) {
|
||||
if (isAncestor) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -497,8 +495,8 @@ var ResponderEventPlugin = {
|
|||
topLevelType,
|
||||
topLevelTarget,
|
||||
topLevelTargetID,
|
||||
nativeEvent) {
|
||||
|
||||
nativeEvent,
|
||||
nativeEventTarget) {
|
||||
if (isStartish(topLevelType)) {
|
||||
trackedTouchCount += 1;
|
||||
} else if (isEndish(topLevelType)) {
|
||||
|
@ -509,10 +507,14 @@ var ResponderEventPlugin = {
|
|||
);
|
||||
}
|
||||
|
||||
ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent);
|
||||
ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent, nativeEventTarget);
|
||||
|
||||
var extracted = canTriggerTransfer(topLevelType, topLevelTargetID) ?
|
||||
setResponderAndExtractTransfer(topLevelType, topLevelTargetID, nativeEvent) :
|
||||
setResponderAndExtractTransfer(
|
||||
topLevelType,
|
||||
topLevelTargetID,
|
||||
nativeEvent,
|
||||
nativeEventTarget) :
|
||||
null;
|
||||
// Responder may or may not have transfered on a new touch start/move.
|
||||
// Regardless, whoever is the responder after any potential transfer, we
|
||||
|
@ -535,7 +537,12 @@ var ResponderEventPlugin = {
|
|||
|
||||
if (incrementalTouch) {
|
||||
var gesture =
|
||||
ResponderSyntheticEvent.getPooled(incrementalTouch, responderID, nativeEvent);
|
||||
ResponderSyntheticEvent.getPooled(
|
||||
incrementalTouch,
|
||||
responderID,
|
||||
nativeEvent,
|
||||
nativeEventTarget
|
||||
);
|
||||
gesture.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
||||
EventPropagators.accumulateDirectDispatches(gesture);
|
||||
extracted = accumulate(extracted, gesture);
|
||||
|
@ -555,7 +562,7 @@ var ResponderEventPlugin = {
|
|||
null;
|
||||
if (finalTouch) {
|
||||
var finalEvent =
|
||||
ResponderSyntheticEvent.getPooled(finalTouch, responderID, nativeEvent);
|
||||
ResponderSyntheticEvent.getPooled(finalTouch, responderID, nativeEvent, nativeEventTarget);
|
||||
finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
||||
EventPropagators.accumulateDirectDispatches(finalEvent);
|
||||
extracted = accumulate(extracted, finalEvent);
|
||||
|
@ -595,7 +602,7 @@ var ResponderEventPlugin = {
|
|||
injectGlobalInteractionHandler: function(GlobalInteractionHandler) {
|
||||
ResponderEventPlugin.GlobalInteractionHandler = GlobalInteractionHandler;
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = ResponderEventPlugin;
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/**
|
||||
* Copyright 2013-2014 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @providesModule ResponderSyntheticEvent
|
||||
* @typechecks static-only
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var SyntheticEvent = require('SyntheticEvent');
|
||||
|
||||
/**
|
||||
* `touchHistory` isn't actually on the native event, but putting it in the
|
||||
* interface will ensure that it is cleaned up when pooled/destroyed. The
|
||||
* `ResponderEventPlugin` will populate it appropriately.
|
||||
*/
|
||||
var ResponderEventInterface = {
|
||||
touchHistory: function(nativeEvent) {
|
||||
return null; // Actually doesn't even look at the native event.
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {object} dispatchConfig Configuration used to dispatch this event.
|
||||
* @param {string} dispatchMarker Marker identifying the event target.
|
||||
* @param {object} nativeEvent Native event.
|
||||
* @extends {SyntheticEvent}
|
||||
*/
|
||||
function ResponderSyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) {
|
||||
SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
|
||||
}
|
||||
|
||||
SyntheticEvent.augmentClass(ResponderSyntheticEvent, ResponderEventInterface);
|
||||
|
||||
module.exports = ResponderSyntheticEvent;
|
|
@ -1,178 +0,0 @@
|
|||
/**
|
||||
* @providesModule ResponderTouchHistoryStore
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var EventPluginUtils = require('EventPluginUtils');
|
||||
|
||||
var invariant = require('invariant');
|
||||
|
||||
var isMoveish = EventPluginUtils.isMoveish;
|
||||
var isStartish = EventPluginUtils.isStartish;
|
||||
var isEndish = EventPluginUtils.isEndish;
|
||||
|
||||
var MAX_TOUCH_BANK = 20;
|
||||
|
||||
/**
|
||||
* Touch position/time tracking information by touchID. Typically, we'll only
|
||||
* see IDs with a range of 1-20 (they are recycled when touches end and then
|
||||
* start again). This data is commonly needed by many different interaction
|
||||
* logic modules so precomputing it is very helpful to do once.
|
||||
* Each touch object in `touchBank` is of the following form:
|
||||
* { touchActive: boolean,
|
||||
* startTimeStamp: number,
|
||||
* startPageX: number,
|
||||
* startPageY: number,
|
||||
* currentPageX: number,
|
||||
* currentPageY: number,
|
||||
* currentTimeStamp: number
|
||||
* }
|
||||
*/
|
||||
var touchHistory = {
|
||||
touchBank: [ ],
|
||||
numberActiveTouches: 0,
|
||||
// If there is only one active touch, we remember its location. This prevents
|
||||
// us having to loop through all of the touches all the time in the most
|
||||
// common case.
|
||||
indexOfSingleActiveTouch: -1,
|
||||
mostRecentTimeStamp: 0,
|
||||
};
|
||||
|
||||
var timestampForTouch = function(touch) {
|
||||
// The legacy internal implementation provides "timeStamp", which has been
|
||||
// renamed to "timestamp". Let both work for now while we iron it out
|
||||
// TODO (evv): rename timeStamp to timestamp in internal code
|
||||
return touch.timeStamp || touch.timestamp;
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO: Instead of making gestures recompute filtered velocity, we could
|
||||
* include a built in velocity computation that can be reused globally.
|
||||
* @param {Touch} touch Native touch object.
|
||||
*/
|
||||
var initializeTouchData = function(touch) {
|
||||
return {
|
||||
touchActive: true,
|
||||
startTimeStamp: timestampForTouch(touch),
|
||||
startPageX: touch.pageX,
|
||||
startPageY: touch.pageY,
|
||||
currentPageX: touch.pageX,
|
||||
currentPageY: touch.pageY,
|
||||
currentTimeStamp: timestampForTouch(touch),
|
||||
previousPageX: touch.pageX,
|
||||
previousPageY: touch.pageY,
|
||||
previousTimeStamp: timestampForTouch(touch),
|
||||
};
|
||||
};
|
||||
|
||||
var reinitializeTouchTrack = function(touchTrack, touch) {
|
||||
touchTrack.touchActive = true;
|
||||
touchTrack.startTimeStamp = timestampForTouch(touch);
|
||||
touchTrack.startPageX = touch.pageX;
|
||||
touchTrack.startPageY = touch.pageY;
|
||||
touchTrack.currentPageX = touch.pageX;
|
||||
touchTrack.currentPageY = touch.pageY;
|
||||
touchTrack.currentTimeStamp = timestampForTouch(touch);
|
||||
touchTrack.previousPageX = touch.pageX;
|
||||
touchTrack.previousPageY = touch.pageY;
|
||||
touchTrack.previousTimeStamp = timestampForTouch(touch);
|
||||
};
|
||||
|
||||
var validateTouch = function(touch) {
|
||||
var identifier = touch.identifier;
|
||||
invariant(identifier != null, 'Touch object is missing identifier');
|
||||
if (identifier > MAX_TOUCH_BANK) {
|
||||
console.warn(
|
||||
'Touch identifier ' + identifier + ' is greater than maximum ' +
|
||||
'supported ' + MAX_TOUCH_BANK + ' which causes performance issues ' +
|
||||
'backfilling array locations for all of the indices.'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
var recordStartTouchData = function(touch) {
|
||||
var touchBank = touchHistory.touchBank;
|
||||
var identifier = touch.identifier;
|
||||
var touchTrack = touchBank[identifier];
|
||||
if (__DEV__) {
|
||||
validateTouch(touch);
|
||||
}
|
||||
if (!touchTrack) {
|
||||
touchBank[touch.identifier] = initializeTouchData(touch);
|
||||
} else {
|
||||
reinitializeTouchTrack(touchTrack, touch);
|
||||
}
|
||||
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
|
||||
};
|
||||
|
||||
var recordMoveTouchData = function(touch) {
|
||||
var touchBank = touchHistory.touchBank;
|
||||
var touchTrack = touchBank[touch.identifier];
|
||||
if (__DEV__) {
|
||||
validateTouch(touch);
|
||||
invariant(touchTrack, 'Touch data should have been recorded on start');
|
||||
}
|
||||
touchTrack.touchActive = true;
|
||||
touchTrack.previousPageX = touchTrack.currentPageX;
|
||||
touchTrack.previousPageY = touchTrack.currentPageY;
|
||||
touchTrack.previousTimeStamp = touchTrack.currentTimeStamp;
|
||||
touchTrack.currentPageX = touch.pageX;
|
||||
touchTrack.currentPageY = touch.pageY;
|
||||
touchTrack.currentTimeStamp = timestampForTouch(touch);
|
||||
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
|
||||
};
|
||||
|
||||
var recordEndTouchData = function(touch) {
|
||||
var touchBank = touchHistory.touchBank;
|
||||
var touchTrack = touchBank[touch.identifier];
|
||||
if (__DEV__) {
|
||||
validateTouch(touch);
|
||||
invariant(touchTrack, 'Touch data should have been recorded on start');
|
||||
}
|
||||
touchTrack.previousPageX = touchTrack.currentPageX;
|
||||
touchTrack.previousPageY = touchTrack.currentPageY;
|
||||
touchTrack.previousTimeStamp = touchTrack.currentTimeStamp;
|
||||
touchTrack.currentPageX = touch.pageX;
|
||||
touchTrack.currentPageY = touch.pageY;
|
||||
touchTrack.currentTimeStamp = timestampForTouch(touch);
|
||||
touchTrack.touchActive = false;
|
||||
touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
|
||||
};
|
||||
|
||||
var ResponderTouchHistoryStore = {
|
||||
recordTouchTrack: function(topLevelType, nativeEvent) {
|
||||
var touchBank = touchHistory.touchBank;
|
||||
if (isMoveish(topLevelType)) {
|
||||
nativeEvent.changedTouches.forEach(recordMoveTouchData);
|
||||
} else if (isStartish(topLevelType)) {
|
||||
nativeEvent.changedTouches.forEach(recordStartTouchData);
|
||||
touchHistory.numberActiveTouches = nativeEvent.touches.length;
|
||||
if (touchHistory.numberActiveTouches === 1) {
|
||||
touchHistory.indexOfSingleActiveTouch = nativeEvent.touches[0].identifier;
|
||||
}
|
||||
} else if (isEndish(topLevelType)) {
|
||||
nativeEvent.changedTouches.forEach(recordEndTouchData);
|
||||
touchHistory.numberActiveTouches = nativeEvent.touches.length;
|
||||
if (touchHistory.numberActiveTouches === 1) {
|
||||
for (var i = 0; i < touchBank.length; i++) {
|
||||
var touchTrackToCheck = touchBank[i];
|
||||
if (touchTrackToCheck != null && touchTrackToCheck.touchActive) {
|
||||
touchHistory.indexOfSingleActiveTouch = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (__DEV__) {
|
||||
var activeTouchData = touchBank[touchHistory.indexOfSingleActiveTouch];
|
||||
var foundActive = activeTouchData != null && !!activeTouchData.touchActive;
|
||||
invariant(foundActive, 'Cannot find single active touch');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
touchHistory: touchHistory,
|
||||
};
|
||||
|
||||
|
||||
module.exports = ResponderTouchHistoryStore;
|
|
@ -1,348 +0,0 @@
|
|||
/**
|
||||
* Copyright 2013-2014 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @providesModule ReactInstanceHandles
|
||||
* @typechecks static-only
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var ReactRootIndex = require('ReactRootIndex');
|
||||
|
||||
var invariant = require('invariant');
|
||||
|
||||
var SEPARATOR = '.';
|
||||
var SEPARATOR_LENGTH = SEPARATOR.length;
|
||||
|
||||
/**
|
||||
* Maximum depth of traversals before we consider the possibility of a bad ID.
|
||||
*/
|
||||
var MAX_TREE_DEPTH = 100;
|
||||
|
||||
/**
|
||||
* Creates a DOM ID prefix to use when mounting React components.
|
||||
*
|
||||
* @param {number} index A unique integer
|
||||
* @return {string} React root ID.
|
||||
* @internal
|
||||
*/
|
||||
function getReactRootIDString(index) {
|
||||
return SEPARATOR + index.toString(36);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a character in the supplied ID is a separator or the end.
|
||||
*
|
||||
* @param {string} id A React DOM ID.
|
||||
* @param {number} index Index of the character to check.
|
||||
* @return {boolean} True if the character is a separator or end of the ID.
|
||||
* @private
|
||||
*/
|
||||
function isBoundary(id, index) {
|
||||
return id.charAt(index) === SEPARATOR || index === id.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the supplied string is a valid React DOM ID.
|
||||
*
|
||||
* @param {string} id A React DOM ID, maybe.
|
||||
* @return {boolean} True if the string is a valid React DOM ID.
|
||||
* @private
|
||||
*/
|
||||
function isValidID(id) {
|
||||
return id === '' || (
|
||||
id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the first ID is an ancestor of or equal to the second ID.
|
||||
*
|
||||
* @param {string} ancestorID
|
||||
* @param {string} descendantID
|
||||
* @return {boolean} True if `ancestorID` is an ancestor of `descendantID`.
|
||||
* @internal
|
||||
*/
|
||||
function isAncestorIDOf(ancestorID, descendantID) {
|
||||
return (
|
||||
descendantID.indexOf(ancestorID) === 0 &&
|
||||
isBoundary(descendantID, ancestorID.length)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent ID of the supplied React DOM ID, `id`.
|
||||
*
|
||||
* @param {string} id ID of a component.
|
||||
* @return {string} ID of the parent, or an empty string.
|
||||
* @private
|
||||
*/
|
||||
function getParentID(id) {
|
||||
return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next DOM ID on the tree path from the supplied `ancestorID` to the
|
||||
* supplied `destinationID`. If they are equal, the ID is returned.
|
||||
*
|
||||
* @param {string} ancestorID ID of an ancestor node of `destinationID`.
|
||||
* @param {string} destinationID ID of the destination node.
|
||||
* @return {string} Next ID on the path from `ancestorID` to `destinationID`.
|
||||
* @private
|
||||
*/
|
||||
function getNextDescendantID(ancestorID, destinationID) {
|
||||
invariant(
|
||||
isValidID(ancestorID) && isValidID(destinationID),
|
||||
'getNextDescendantID(%s, %s): Received an invalid React DOM ID.',
|
||||
ancestorID,
|
||||
destinationID
|
||||
);
|
||||
invariant(
|
||||
isAncestorIDOf(ancestorID, destinationID),
|
||||
'getNextDescendantID(...): React has made an invalid assumption about ' +
|
||||
'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.',
|
||||
ancestorID,
|
||||
destinationID
|
||||
);
|
||||
if (ancestorID === destinationID) {
|
||||
return ancestorID;
|
||||
}
|
||||
// Skip over the ancestor and the immediate separator. Traverse until we hit
|
||||
// another separator or we reach the end of `destinationID`.
|
||||
var start = ancestorID.length + SEPARATOR_LENGTH;
|
||||
for (var i = start; i < destinationID.length; i++) {
|
||||
if (isBoundary(destinationID, i)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return destinationID.substr(0, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nearest common ancestor ID of two IDs.
|
||||
*
|
||||
* Using this ID scheme, the nearest common ancestor ID is the longest common
|
||||
* prefix of the two IDs that immediately preceded a "marker" in both strings.
|
||||
*
|
||||
* @param {string} oneID
|
||||
* @param {string} twoID
|
||||
* @return {string} Nearest common ancestor ID, or the empty string if none.
|
||||
* @private
|
||||
*/
|
||||
function getFirstCommonAncestorID(oneID, twoID) {
|
||||
var minLength = Math.min(oneID.length, twoID.length);
|
||||
if (minLength === 0) {
|
||||
return '';
|
||||
}
|
||||
var lastCommonMarkerIndex = 0;
|
||||
// Use `<=` to traverse until the "EOL" of the shorter string.
|
||||
for (var i = 0; i <= minLength; i++) {
|
||||
if (isBoundary(oneID, i) && isBoundary(twoID, i)) {
|
||||
lastCommonMarkerIndex = i;
|
||||
} else if (oneID.charAt(i) !== twoID.charAt(i)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
var longestCommonID = oneID.substr(0, lastCommonMarkerIndex);
|
||||
invariant(
|
||||
isValidID(longestCommonID),
|
||||
'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s',
|
||||
oneID,
|
||||
twoID,
|
||||
longestCommonID
|
||||
);
|
||||
return longestCommonID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses the parent path between two IDs (either up or down). The IDs must
|
||||
* not be the same, and there must exist a parent path between them. If the
|
||||
* callback returns `false`, traversal is stopped.
|
||||
*
|
||||
* @param {?string} start ID at which to start traversal.
|
||||
* @param {?string} stop ID at which to end traversal.
|
||||
* @param {function} cb Callback to invoke each ID with.
|
||||
* @param {?boolean} skipFirst Whether or not to skip the first node.
|
||||
* @param {?boolean} skipLast Whether or not to skip the last node.
|
||||
* @private
|
||||
*/
|
||||
function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {
|
||||
start = start || '';
|
||||
stop = stop || '';
|
||||
invariant(
|
||||
start !== stop,
|
||||
'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.',
|
||||
start
|
||||
);
|
||||
var traverseUp = isAncestorIDOf(stop, start);
|
||||
invariant(
|
||||
traverseUp || isAncestorIDOf(start, stop),
|
||||
'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' +
|
||||
'not have a parent path.',
|
||||
start,
|
||||
stop
|
||||
);
|
||||
// Traverse from `start` to `stop` one depth at a time.
|
||||
var depth = 0;
|
||||
var traverse = traverseUp ? getParentID : getNextDescendantID;
|
||||
for (var id = start; /* until break */; id = traverse(id, stop)) {
|
||||
var ret;
|
||||
if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) {
|
||||
ret = cb(id, traverseUp, arg);
|
||||
}
|
||||
if (ret === false || id === stop) {
|
||||
// Only break //after// visiting `stop`.
|
||||
break;
|
||||
}
|
||||
invariant(
|
||||
depth++ < MAX_TREE_DEPTH,
|
||||
'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' +
|
||||
'traversing the React DOM ID tree. This may be due to malformed IDs: %s',
|
||||
start, stop
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the IDs assigned to DOM representations of React components. This
|
||||
* uses a specific scheme in order to traverse the DOM efficiently (e.g. in
|
||||
* order to simulate events).
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
var ReactInstanceHandles = {
|
||||
|
||||
/**
|
||||
* Constructs a React root ID
|
||||
* @return {string} A React root ID.
|
||||
*/
|
||||
createReactRootID: function() {
|
||||
return getReactRootIDString(ReactRootIndex.createReactRootIndex());
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructs a React ID by joining a root ID with a name.
|
||||
*
|
||||
* @param {string} rootID Root ID of a parent component.
|
||||
* @param {string} name A component's name (as flattened children).
|
||||
* @return {string} A React ID.
|
||||
* @internal
|
||||
*/
|
||||
createReactID: function(rootID, name) {
|
||||
return rootID + name;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the DOM ID of the React component that is the root of the tree that
|
||||
* contains the React component with the supplied DOM ID.
|
||||
*
|
||||
* @param {string} id DOM ID of a React component.
|
||||
* @return {?string} DOM ID of the React component that is the root.
|
||||
* @internal
|
||||
*/
|
||||
getReactRootIDFromNodeID: function(id) {
|
||||
if (id && id.charAt(0) === SEPARATOR && id.length > 1) {
|
||||
var index = id.indexOf(SEPARATOR, 1);
|
||||
return index > -1 ? id.substr(0, index) : id;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
|
||||
* should would receive a `mouseEnter` or `mouseLeave` event.
|
||||
*
|
||||
* NOTE: Does not invoke the callback on the nearest common ancestor because
|
||||
* nothing "entered" or "left" that element.
|
||||
*
|
||||
* @param {string} leaveID ID being left.
|
||||
* @param {string} enterID ID being entered.
|
||||
* @param {function} cb Callback to invoke on each entered/left ID.
|
||||
* @param {*} upArg Argument to invoke the callback with on left IDs.
|
||||
* @param {*} downArg Argument to invoke the callback with on entered IDs.
|
||||
* @internal
|
||||
*/
|
||||
traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) {
|
||||
var ancestorID = getFirstCommonAncestorID(leaveID, enterID);
|
||||
if (ancestorID !== leaveID) {
|
||||
traverseParentPath(leaveID, ancestorID, cb, upArg, false, true);
|
||||
}
|
||||
if (ancestorID !== enterID) {
|
||||
traverseParentPath(ancestorID, enterID, cb, downArg, true, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates the traversal of a two-phase, capture/bubble event dispatch.
|
||||
*
|
||||
* NOTE: This traversal happens on IDs without touching the DOM.
|
||||
*
|
||||
* @param {string} targetID ID of the target node.
|
||||
* @param {function} cb Callback to invoke.
|
||||
* @param {*} arg Argument to invoke the callback with.
|
||||
* @internal
|
||||
*/
|
||||
traverseTwoPhase: function(targetID, cb, arg) {
|
||||
if (targetID) {
|
||||
traverseParentPath('', targetID, cb, arg, true, false);
|
||||
traverseParentPath(targetID, '', cb, arg, false, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Same as `traverseTwoPhase` but skips the `targetID`.
|
||||
*/
|
||||
traverseTwoPhaseSkipTarget: function(targetID, cb, arg) {
|
||||
if (targetID) {
|
||||
traverseParentPath('', targetID, cb, arg, true, true);
|
||||
traverseParentPath(targetID, '', cb, arg, true, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Traverse a node ID, calling the supplied `cb` for each ancestor ID. For
|
||||
* example, passing `.0.$row-0.1` would result in `cb` getting called
|
||||
* with `.0`, `.0.$row-0`, and `.0.$row-0.1`.
|
||||
*
|
||||
* NOTE: This traversal happens on IDs without touching the DOM.
|
||||
*
|
||||
* @param {string} targetID ID of the target node.
|
||||
* @param {function} cb Callback to invoke.
|
||||
* @param {*} arg Argument to invoke the callback with.
|
||||
* @internal
|
||||
*/
|
||||
traverseAncestors: function(targetID, cb, arg) {
|
||||
traverseParentPath('', targetID, cb, arg, true, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Exposed for unit testing.
|
||||
* @private
|
||||
*/
|
||||
_getFirstCommonAncestorID: getFirstCommonAncestorID,
|
||||
|
||||
/**
|
||||
* Exposed for unit testing.
|
||||
* @private
|
||||
*/
|
||||
_getNextDescendantID: getNextDescendantID,
|
||||
|
||||
isAncestorIDOf: isAncestorIDOf,
|
||||
|
||||
SEPARATOR: SEPARATOR
|
||||
|
||||
};
|
||||
|
||||
module.exports = ReactInstanceHandles;
|
|
@ -17,9 +17,6 @@ var sharedBlacklist = [
|
|||
'node_modules/react-tools/src/React.js',
|
||||
'node_modules/react-tools/src/renderers/shared/event/EventPropagators.js',
|
||||
'node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js',
|
||||
'node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderSyntheticEvent.js',
|
||||
'node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderTouchHistoryStore.js',
|
||||
'node_modules/react-tools/src/renderers/shared/reconciler/ReactInstanceHandles.js',
|
||||
'node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js',
|
||||
];
|
||||
|
||||
|
|
Loading…
Reference in New Issue