aboutsummaryrefslogtreecommitdiff
path: root/node_modules/react-dom/lib/ResponderEventPlugin.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/react-dom/lib/ResponderEventPlugin.js')
-rw-r--r--node_modules/react-dom/lib/ResponderEventPlugin.js505
1 files changed, 0 insertions, 505 deletions
diff --git a/node_modules/react-dom/lib/ResponderEventPlugin.js b/node_modules/react-dom/lib/ResponderEventPlugin.js
deleted file mode 100644
index dc35ded47..000000000
--- a/node_modules/react-dom/lib/ResponderEventPlugin.js
+++ /dev/null
@@ -1,505 +0,0 @@
-/**
- * Copyright 2013-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 EventPluginUtils = require('./EventPluginUtils');
-var EventPropagators = require('./EventPropagators');
-var ResponderSyntheticEvent = require('./ResponderSyntheticEvent');
-var ResponderTouchHistoryStore = require('./ResponderTouchHistoryStore');
-
-var accumulate = require('./accumulate');
-
-var isStartish = EventPluginUtils.isStartish;
-var isMoveish = EventPluginUtils.isMoveish;
-var isEndish = EventPluginUtils.isEndish;
-var executeDirectDispatch = EventPluginUtils.executeDirectDispatch;
-var hasDispatches = EventPluginUtils.hasDispatches;
-var executeDispatchesInOrderStopAtTrue = EventPluginUtils.executeDispatchesInOrderStopAtTrue;
-
-/**
- * Instance of element that should respond to touch/move types of interactions,
- * as indicated explicitly by relevant callbacks.
- */
-var responderInst = null;
-
-/**
- * Count of current touches. A textInput should become responder iff the
- * selection changes while there is a touch on the screen.
- */
-var trackedTouchCount = 0;
-
-/**
- * Last reported number of active touches.
- */
-var previousActiveTouches = 0;
-
-var changeResponder = function (nextResponderInst, blockHostResponder) {
- var oldResponderInst = responderInst;
- responderInst = nextResponderInst;
- if (ResponderEventPlugin.GlobalResponderHandler !== null) {
- ResponderEventPlugin.GlobalResponderHandler.onChange(oldResponderInst, nextResponderInst, blockHostResponder);
- }
-};
-
-var eventTypes = {
- /**
- * On a `touchStart`/`mouseDown`, is it desired that this element become the
- * responder?
- */
- startShouldSetResponder: {
- phasedRegistrationNames: {
- bubbled: 'onStartShouldSetResponder',
- captured: 'onStartShouldSetResponderCapture'
- }
- },
-
- /**
- * On a `scroll`, is it desired that this element become the responder? This
- * is usually not needed, but should be used to retroactively infer that a
- * `touchStart` had occurred during momentum scroll. During a momentum scroll,
- * a touch start will be immediately followed by a scroll event if the view is
- * currently scrolling.
- *
- * TODO: This shouldn't bubble.
- */
- scrollShouldSetResponder: {
- phasedRegistrationNames: {
- bubbled: 'onScrollShouldSetResponder',
- captured: 'onScrollShouldSetResponderCapture'
- }
- },
-
- /**
- * On text selection change, should this element become the responder? This
- * is needed for text inputs or other views with native selection, so the
- * JS view can claim the responder.
- *
- * TODO: This shouldn't bubble.
- */
- selectionChangeShouldSetResponder: {
- phasedRegistrationNames: {
- bubbled: 'onSelectionChangeShouldSetResponder',
- captured: 'onSelectionChangeShouldSetResponderCapture'
- }
- },
-
- /**
- * On a `touchMove`/`mouseMove`, is it desired that this element become the
- * responder?
- */
- moveShouldSetResponder: {
- phasedRegistrationNames: {
- bubbled: 'onMoveShouldSetResponder',
- captured: 'onMoveShouldSetResponderCapture'
- }
- },
-
- /**
- * Direct responder events dispatched directly to responder. Do not bubble.
- */
- responderStart: { registrationName: 'onResponderStart' },
- responderMove: { registrationName: 'onResponderMove' },
- responderEnd: { registrationName: 'onResponderEnd' },
- responderRelease: { registrationName: 'onResponderRelease' },
- responderTerminationRequest: {
- registrationName: 'onResponderTerminationRequest'
- },
- responderGrant: { registrationName: 'onResponderGrant' },
- responderReject: { registrationName: 'onResponderReject' },
- responderTerminate: { registrationName: 'onResponderTerminate' }
-};
-
-/**
- *
- * Responder System:
- * ----------------
- *
- * - A global, solitary "interaction lock" on a view.
- * - 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.
- * - While touches are still occurring, the responder lock can be transferred to
- * a new view, but only to increasingly "higher" views (meaning ancestors of
- * the current responder).
- *
- * Responder being granted:
- * ------------------------
- *
- * - Touch starts, moves, and scrolls can cause an ID to become the responder.
- * - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to
- * the "appropriate place".
- * - If nothing is currently the responder, the "appropriate place" is the
- * initiating event's `targetID`.
- * - If something *is* already the responder, the "appropriate place" is the
- * first common ancestor of the event target and the current `responderInst`.
- * - Some negotiation happens: See the timing diagram below.
- * - Scrolled views automatically become responder. The reasoning is that a
- * platform scroll view that isn't built on top of the responder system has
- * began scrolling, and the active responder must now be notified that the
- * interaction is no longer locked to it - the system has taken over.
- *
- * - Responder being released:
- * As soon as no more touches that *started* inside of descendants of the
- * *current* responderInst, an `onResponderRelease` event is dispatched to the
- * current responder, and the responder lock is released.
- *
- * TODO:
- * - on "end", a callback hook for `onResponderEndShouldRemainResponder` that
- * determines if the responder lock should remain.
- * - If a view shouldn't "remain" the responder, any active touches should by
- * default be considered "dead" and do not influence future negotiations or
- * bubble paths. It should be as if those touches do not exist.
- * -- For multitouch: Usually a translate-z will choose to "remain" responder
- * after one out of many touches ended. For translate-y, usually the view
- * doesn't wish to "remain" responder after one of many touches end.
- * - Consider building this on top of a `stopPropagation` model similar to
- * `W3C` events.
- * - Ensure that `onResponderTerminate` is called on touch cancels, whether or
- * not `onResponderTerminationRequest` returns `true` or `false`.
- *
- */
-
-/* Negotiation Performed
- +-----------------------+
- / \
-Process low level events to + Current Responder + wantsResponderID
-determine who to perform negot-| (if any exists at all) |
-iation/transition | Otherwise just pass through|
--------------------------------+----------------------------+------------------+
-Bubble to find first ID | |
-to return true:wantsResponderID| |
- | |
- +-------------+ | |
- | onTouchStart| | |
- +------+------+ none | |
- | return| |
-+-----------v-------------+true| +------------------------+ |
-|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+
-+-----------+-------------+ | +------------------------+ | |
- | | | +--------+-------+
- | returned true for| false:REJECT +-------->|onResponderReject
- | wantsResponderID | | | +----------------+
- | (now attempt | +------------------+-----+ |
- | handoff) | | onResponder | |
- +------------------->| TerminationRequest| |
- | +------------------+-----+ |
- | | | +----------------+
- | true:GRANT +-------->|onResponderGrant|
- | | +--------+-------+
- | +------------------------+ | |
- | | onResponderTerminate |<-----------+
- | +------------------+-----+ |
- | | | +----------------+
- | +-------->|onResponderStart|
- | | +----------------+
-Bubble to find first ID | |
-to return true:wantsResponderID| |
- | |
- +-------------+ | |
- | onTouchMove | | |
- +------+------+ none | |
- | return| |
-+-----------v-------------+true| +------------------------+ |
-|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+
-+-----------+-------------+ | +------------------------+ | |
- | | | +--------+-------+
- | returned true for| false:REJECT +-------->|onResponderRejec|
- | wantsResponderID | | | +----------------+
- | (now attempt | +------------------+-----+ |
- | handoff) | | onResponder | |
- +------------------->| TerminationRequest| |
- | +------------------+-----+ |
- | | | +----------------+
- | true:GRANT +-------->|onResponderGrant|
- | | +--------+-------+
- | +------------------------+ | |
- | | onResponderTerminate |<-----------+
- | +------------------+-----+ |
- | | | +----------------+
- | +-------->|onResponderMove |
- | | +----------------+
- | |
- | |
- Some active touch started| |
- inside current responder | +------------------------+ |
- +------------------------->| onResponderEnd | |
- | | +------------------------+ |
- +---+---------+ | |
- | onTouchEnd | | |
- +---+---------+ | |
- | | +------------------------+ |
- +------------------------->| onResponderEnd | |
- No active touches started| +-----------+------------+ |
- inside current responder | | |
- | v |
- | +------------------------+ |
- | | onResponderRelease | |
- | +------------------------+ |
- | |
- + + */
-
-/**
- * A note about event ordering in the `EventPluginHub`.
- *
- * Suppose plugins are injected in the following order:
- *
- * `[R, S, C]`
- *
- * To help illustrate the example, assume `S` is `SimpleEventPlugin` (for
- * `onClick` etc) and `R` is `ResponderEventPlugin`.
- *
- * "Deferred-Dispatched Events":
- *
- * - The current event plugin system will traverse the list of injected plugins,
- * in order, and extract events by collecting the plugin's return value of
- * `extractEvents()`.
- * - These events that are returned from `extractEvents` are "deferred
- * dispatched events".
- * - When returned from `extractEvents`, deferred-dispatched events contain an
- * "accumulation" of deferred dispatches.
- * - These deferred dispatches are accumulated/collected before they are
- * returned, but processed at a later time by the `EventPluginHub` (hence the
- * name deferred).
- *
- * In the process of returning their deferred-dispatched events, event plugins
- * themselves can dispatch events on-demand without returning them from
- * `extractEvents`. Plugins might want to do this, so that they can use event
- * dispatching as a tool that helps them decide which events should be extracted
- * in the first place.
- *
- * "On-Demand-Dispatched Events":
- *
- * - On-demand-dispatched events are not returned from `extractEvents`.
- * - On-demand-dispatched events are dispatched during the process of returning
- * the deferred-dispatched events.
- * - They should not have side effects.
- * - They should be avoided, and/or eventually be replaced with another
- * abstraction that allows event plugins to perform multiple "rounds" of event
- * extraction.
- *
- * Therefore, the sequence of event dispatches becomes:
- *
- * - `R`s on-demand events (if any) (dispatched by `R` on-demand)
- * - `S`s on-demand events (if any) (dispatched by `S` on-demand)
- * - `C`s on-demand events (if any) (dispatched by `C` on-demand)
- * - `R`s extracted events (if any) (dispatched by `EventPluginHub`)
- * - `S`s extracted events (if any) (dispatched by `EventPluginHub`)
- * - `C`s extracted events (if any) (dispatched by `EventPluginHub`)
- *
- * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder`
- * on-demand dispatch returns `true` (and some other details are satisfied) the
- * `onResponderGrant` deferred dispatched event is returned from
- * `extractEvents`. The sequence of dispatch executions in this case
- * will appear as follows:
- *
- * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand)
- * - `touchStartCapture` (`EventPluginHub` dispatches as usual)
- * - `touchStart` (`EventPluginHub` dispatches as usual)
- * - `responderGrant/Reject` (`EventPluginHub` dispatches as usual)
- */
-
-function setResponderAndExtractTransfer(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
- var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) ? eventTypes.moveShouldSetResponder : topLevelType === 'topSelectionChange' ? eventTypes.selectionChangeShouldSetResponder : eventTypes.scrollShouldSetResponder;
-
- // TODO: stop one short of the current responder.
- var bubbleShouldSetFrom = !responderInst ? targetInst : EventPluginUtils.getLowestCommonAncestor(responderInst, targetInst);
-
- // When capturing/bubbling the "shouldSet" event, we want to skip the target
- // (deepest ID) if it happens to be the current responder. The reasoning:
- // It's strange to get an `onMoveShouldSetResponder` when you're *already*
- // the responder.
- var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst;
- var shouldSetEvent = ResponderSyntheticEvent.getPooled(shouldSetEventType, bubbleShouldSetFrom, nativeEvent, nativeEventTarget);
- shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
- if (skipOverBubbleShouldSetFrom) {
- EventPropagators.accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent);
- } else {
- EventPropagators.accumulateTwoPhaseDispatches(shouldSetEvent);
- }
- var wantsResponderInst = executeDispatchesInOrderStopAtTrue(shouldSetEvent);
- if (!shouldSetEvent.isPersistent()) {
- shouldSetEvent.constructor.release(shouldSetEvent);
- }
-
- if (!wantsResponderInst || wantsResponderInst === responderInst) {
- return null;
- }
- var extracted;
- var grantEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderGrant, wantsResponderInst, nativeEvent, nativeEventTarget);
- grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
-
- EventPropagators.accumulateDirectDispatches(grantEvent);
- var blockHostResponder = executeDirectDispatch(grantEvent) === true;
- if (responderInst) {
- var terminationRequestEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderTerminationRequest, responderInst, nativeEvent, nativeEventTarget);
- terminationRequestEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
- EventPropagators.accumulateDirectDispatches(terminationRequestEvent);
- var shouldSwitch = !hasDispatches(terminationRequestEvent) || executeDirectDispatch(terminationRequestEvent);
- if (!terminationRequestEvent.isPersistent()) {
- terminationRequestEvent.constructor.release(terminationRequestEvent);
- }
-
- if (shouldSwitch) {
- var terminateEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderTerminate, responderInst, nativeEvent, nativeEventTarget);
- terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
- EventPropagators.accumulateDirectDispatches(terminateEvent);
- extracted = accumulate(extracted, [grantEvent, terminateEvent]);
- changeResponder(wantsResponderInst, blockHostResponder);
- } else {
- var rejectEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderReject, wantsResponderInst, nativeEvent, nativeEventTarget);
- rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
- EventPropagators.accumulateDirectDispatches(rejectEvent);
- extracted = accumulate(extracted, rejectEvent);
- }
- } else {
- extracted = accumulate(extracted, grantEvent);
- changeResponder(wantsResponderInst, blockHostResponder);
- }
- return extracted;
-}
-
-/**
- * A transfer is a negotiation between a currently set responder and the next
- * element to claim responder status. Any start event could trigger a transfer
- * of responderInst. Any move event could trigger a transfer.
- *
- * @param {string} topLevelType Record from `EventConstants`.
- * @return {boolean} True if a transfer of responder could possibly occur.
- */
-function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) {
- return topLevelInst && (
- // responderIgnoreScroll: We are trying to migrate away from specifically
- // tracking native scroll events here and responderIgnoreScroll indicates we
- // will send topTouchCancel to handle canceling touch events instead
- topLevelType === 'topScroll' && !nativeEvent.responderIgnoreScroll || trackedTouchCount > 0 && topLevelType === 'topSelectionChange' || isStartish(topLevelType) || isMoveish(topLevelType));
-}
-
-/**
- * Returns whether or not this touch end event makes it such that there are no
- * longer any touches that started inside of the current `responderInst`.
- *
- * @param {NativeEvent} nativeEvent Native touch end event.
- * @return {boolean} Whether or not this touch end event ends the responder.
- */
-function noResponderTouches(nativeEvent) {
- var touches = nativeEvent.touches;
- if (!touches || touches.length === 0) {
- return true;
- }
- for (var i = 0; i < touches.length; i++) {
- var activeTouch = touches[i];
- var target = activeTouch.target;
- if (target !== null && target !== undefined && target !== 0) {
- // Is the original touch location inside of the current responder?
- var targetInst = EventPluginUtils.getInstanceFromNode(target);
- if (EventPluginUtils.isAncestor(responderInst, targetInst)) {
- return false;
- }
- }
- }
- return true;
-}
-
-var ResponderEventPlugin = {
- /* For unit testing only */
- _getResponderID: function () {
- return responderInst ? responderInst._rootNodeID : null;
- },
-
- eventTypes: eventTypes,
-
- /**
- * We must be resilient to `targetInst` being `null` on `touchMove` or
- * `touchEnd`. On certain platforms, this means that a native scroll has
- * assumed control and the original touch targets are destroyed.
- */
- extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
- if (isStartish(topLevelType)) {
- trackedTouchCount += 1;
- } else if (isEndish(topLevelType)) {
- if (trackedTouchCount >= 0) {
- trackedTouchCount -= 1;
- } else {
- console.error('Ended a touch event which was not counted in `trackedTouchCount`.');
- return null;
- }
- }
-
- ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent);
-
- var extracted = canTriggerTransfer(topLevelType, targetInst, nativeEvent) ? setResponderAndExtractTransfer(topLevelType, targetInst, nativeEvent, nativeEventTarget) : null;
- // Responder may or may not have transferred on a new touch start/move.
- // Regardless, whoever is the responder after any potential transfer, we
- // direct all touch start/move/ends to them in the form of
- // `onResponderMove/Start/End`. These will be called for *every* additional
- // finger that move/start/end, dispatched directly to whoever is the
- // current responder at that moment, until the responder is "released".
- //
- // These multiple individual change touch events are are always bookended
- // by `onResponderGrant`, and one of
- // (`onResponderRelease/onResponderTerminate`).
- var isResponderTouchStart = responderInst && isStartish(topLevelType);
- var isResponderTouchMove = responderInst && isMoveish(topLevelType);
- var isResponderTouchEnd = responderInst && isEndish(topLevelType);
- var incrementalTouch = isResponderTouchStart ? eventTypes.responderStart : isResponderTouchMove ? eventTypes.responderMove : isResponderTouchEnd ? eventTypes.responderEnd : null;
-
- if (incrementalTouch) {
- var gesture = ResponderSyntheticEvent.getPooled(incrementalTouch, responderInst, nativeEvent, nativeEventTarget);
- gesture.touchHistory = ResponderTouchHistoryStore.touchHistory;
- EventPropagators.accumulateDirectDispatches(gesture);
- extracted = accumulate(extracted, gesture);
- }
-
- var isResponderTerminate = responderInst && topLevelType === 'topTouchCancel';
- var isResponderRelease = responderInst && !isResponderTerminate && isEndish(topLevelType) && noResponderTouches(nativeEvent);
- var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease ? eventTypes.responderRelease : null;
- if (finalTouch) {
- var finalEvent = ResponderSyntheticEvent.getPooled(finalTouch, responderInst, nativeEvent, nativeEventTarget);
- finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
- EventPropagators.accumulateDirectDispatches(finalEvent);
- extracted = accumulate(extracted, finalEvent);
- changeResponder(null);
- }
-
- var numberActiveTouches = ResponderTouchHistoryStore.touchHistory.numberActiveTouches;
- if (ResponderEventPlugin.GlobalInteractionHandler && numberActiveTouches !== previousActiveTouches) {
- ResponderEventPlugin.GlobalInteractionHandler.onChange(numberActiveTouches);
- }
- previousActiveTouches = numberActiveTouches;
-
- return extracted;
- },
-
- GlobalResponderHandler: null,
- GlobalInteractionHandler: null,
-
- injection: {
- /**
- * @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler
- * Object that handles any change in responder. Use this to inject
- * integration with an existing touch handling system etc.
- */
- injectGlobalResponderHandler: function (GlobalResponderHandler) {
- ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler;
- },
-
- /**
- * @param {{onChange: (numberActiveTouches) => void} GlobalInteractionHandler
- * Object that handles any change in the number of active touches.
- */
- injectGlobalInteractionHandler: function (GlobalInteractionHandler) {
- ResponderEventPlugin.GlobalInteractionHandler = GlobalInteractionHandler;
- }
- }
-};
-
-module.exports = ResponderEventPlugin; \ No newline at end of file