@tamagui/react-native-use-responder-events 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -319,8 +319,9 @@ const documentEventsBubblePhase = [
|
|
|
319
319
|
"select",
|
|
320
320
|
"selectionchange"
|
|
321
321
|
];
|
|
322
|
+
const isTamaguiResponderActive = Symbol();
|
|
322
323
|
function attachListeners() {
|
|
323
|
-
if (import_utils.canUseDOM && !window[
|
|
324
|
+
if (import_utils.canUseDOM && !window[isTamaguiResponderActive]) {
|
|
324
325
|
window.addEventListener("blur", eventListener);
|
|
325
326
|
documentEventsBubblePhase.forEach((eventType) => {
|
|
326
327
|
document.addEventListener(eventType, eventListener);
|
|
@@ -328,7 +329,7 @@ function attachListeners() {
|
|
|
328
329
|
documentEventsCapturePhase.forEach((eventType) => {
|
|
329
330
|
document.addEventListener(eventType, eventListener, true);
|
|
330
331
|
});
|
|
331
|
-
window[
|
|
332
|
+
window[isTamaguiResponderActive] = true;
|
|
332
333
|
}
|
|
333
334
|
}
|
|
334
335
|
function addNode(id, node, config) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/ResponderSystem.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Copyright (c) Nicolas Gallagher\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { ResponderEvent } from './createResponderEvent'\nimport createResponderEvent from './createResponderEvent'\nimport { ResponderTouchHistoryStore } from './ResponderTouchHistoryStore'\nimport {\n isCancelish,\n isEndish,\n isMoveish,\n isScroll,\n isSelectionChange,\n isStartish,\n} from './types'\nimport { canUseDOM } from './utils'\nimport {\n getLowestCommonAncestor,\n getResponderPaths,\n hasTargetTouches,\n hasValidSelection,\n isPrimaryPointerDown,\n setResponderId,\n} from './utils'\n\n/* ------------ TYPES ------------ */\n\ntype ResponderId = string\n\ntype ActiveResponderInstance = {\n id: ResponderId\n idPath: Array<number>\n node: any\n}\n\ntype EmptyResponderInstance = {\n id: null\n idPath: null\n node: null\n}\n\ntype ResponderInstance = ActiveResponderInstance | EmptyResponderInstance\n\nexport type ResponderConfig = {\n // Direct responder events dispatched directly to responder. Do not bubble.\n onResponderEnd?: ((e: ResponderEvent) => void) | null\n onResponderGrant?: ((e: ResponderEvent) => void | boolean) | null\n onResponderMove?: ((e: ResponderEvent) => void) | null\n onResponderRelease?: ((e: ResponderEvent) => void) | null\n onResponderReject?: ((e: ResponderEvent) => void) | null\n onResponderStart?: ((e: ResponderEvent) => void) | null\n onResponderTerminate?: ((e: ResponderEvent) => void) | null\n onResponderTerminationRequest?: ((e: ResponderEvent) => boolean) | null\n // On pointer down, should this element become the responder?\n onStartShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onStartShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On pointer move, should this element become the responder?\n onMoveShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onMoveShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On scroll, should this element become the responder? Do no bubble\n onScrollShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onScrollShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On text selection change, should this element become the responder?\n onSelectionChangeShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onSelectionChangeShouldSetResponderCapture?:\n | ((e: ResponderEvent) => boolean)\n | null\n}\n\nconst emptyObject = {}\n\n/* ------------ IMPLEMENTATION ------------ */\n\nconst startRegistration = [\n 'onStartShouldSetResponderCapture',\n 'onStartShouldSetResponder',\n { bubbles: true },\n]\nconst moveRegistration = [\n 'onMoveShouldSetResponderCapture',\n 'onMoveShouldSetResponder',\n { bubbles: true },\n]\nconst scrollRegistration = [\n 'onScrollShouldSetResponderCapture',\n 'onScrollShouldSetResponder',\n { bubbles: false },\n]\nconst shouldSetResponderEvents = {\n touchstart: startRegistration,\n mousedown: startRegistration,\n touchmove: moveRegistration,\n mousemove: moveRegistration,\n scroll: scrollRegistration,\n}\n\nconst emptyResponder = { id: null, idPath: null, node: null }\nconst responderListenersMap = new Map()\n\nlet isEmulatingMouseEvents = false\nlet trackedTouchCount = 0\nlet currentResponder: ResponderInstance = {\n id: null,\n node: null,\n idPath: null,\n}\nconst responderTouchHistoryStore = new ResponderTouchHistoryStore()\n\nfunction changeCurrentResponder(responder: ResponderInstance) {\n currentResponder = responder\n}\n\nfunction getResponderConfig(id: ResponderId): ResponderConfig | any {\n const config = responderListenersMap.get(id)\n return config != null ? config : emptyObject\n}\n\n/**\n * Process native events\n *\n * A single event listener is used to manage the responder system.\n * All pointers are tracked in the ResponderTouchHistoryStore. Native events\n * are interpreted in terms of the Responder System and checked to see if\n * the responder should be transferred. Each host node that is attached to\n * the Responder System has an ID, which is used to look up its associated\n * callbacks.\n */\nfunction eventListener(domEvent: any) {\n const eventType = domEvent.type\n const eventTarget = domEvent.target\n\n /**\n * Manage emulated events and early bailout.\n * Since PointerEvent is not used yet (lack of support in older Safari), it's\n * necessary to manually manage the mess of browser touch/mouse events.\n * And bailout early for termination events when there is no active responder.\n */\n\n // Flag when browser may produce emulated events\n if (eventType === 'touchstart') {\n isEmulatingMouseEvents = true\n }\n // Remove flag when browser will not produce emulated events\n if (eventType === 'touchmove' || trackedTouchCount > 1) {\n isEmulatingMouseEvents = false\n }\n // Ignore various events in particular circumstances\n if (\n // Ignore browser emulated mouse events\n (eventType === 'mousedown' && isEmulatingMouseEvents) ||\n (eventType === 'mousemove' && isEmulatingMouseEvents) ||\n // Ignore mousemove if a mousedown didn't occur first\n (eventType === 'mousemove' && trackedTouchCount < 1)\n ) {\n return\n }\n // Remove flag after emulated events are finished\n if (isEmulatingMouseEvents && eventType === 'mouseup') {\n if (trackedTouchCount === 0) {\n isEmulatingMouseEvents = false\n }\n return\n }\n\n const isStartEvent = isStartish(eventType) && isPrimaryPointerDown(domEvent)\n const isMoveEvent = isMoveish(eventType)\n const isEndEvent = isEndish(eventType)\n const isScrollEvent = isScroll(eventType)\n const isSelectionChangeEvent = isSelectionChange(eventType)\n const responderEvent = createResponderEvent(domEvent, responderTouchHistoryStore)\n\n /**\n * Record the state of active pointers\n */\n\n if (isStartEvent || isMoveEvent || isEndEvent) {\n if (domEvent.touches) {\n trackedTouchCount = domEvent.touches.length\n } else {\n if (isStartEvent) {\n trackedTouchCount = 1\n } else if (isEndEvent) {\n trackedTouchCount = 0\n }\n }\n responderTouchHistoryStore.recordTouchTrack(\n eventType,\n responderEvent.nativeEvent as any,\n )\n }\n\n /**\n * Responder System logic\n */\n\n let eventPaths: any = getResponderPaths(domEvent)\n let wasNegotiated = false\n let wantsResponder\n\n // If an event occured that might change the current responder...\n if (isStartEvent || isMoveEvent || (isScrollEvent && trackedTouchCount > 0)) {\n // If there is already a responder, prune the event paths to the lowest common ancestor\n // of the existing responder and deepest target of the event.\n const currentResponderIdPath = currentResponder.idPath\n const eventIdPath = eventPaths.idPath\n\n if (currentResponderIdPath != null && eventIdPath != null) {\n const lowestCommonAncestor = getLowestCommonAncestor(\n currentResponderIdPath,\n eventIdPath,\n )\n if (lowestCommonAncestor != null) {\n const indexOfLowestCommonAncestor = eventIdPath.indexOf(lowestCommonAncestor)\n // Skip the current responder so it doesn't receive unexpected \"shouldSet\" events.\n const index =\n indexOfLowestCommonAncestor +\n (lowestCommonAncestor === currentResponder.id ? 1 : 0)\n eventPaths = {\n idPath: eventIdPath.slice(index),\n nodePath: eventPaths.nodePath.slice(index),\n }\n } else {\n eventPaths = null\n }\n }\n\n if (eventPaths != null) {\n // If a node wants to become the responder, attempt to transfer.\n wantsResponder = findWantsResponder(eventPaths, domEvent, responderEvent)\n if (wantsResponder != null) {\n // Sets responder if none exists, or negotates with existing responder.\n attemptTransfer(responderEvent, wantsResponder)\n wasNegotiated = true\n }\n }\n }\n\n // If there is now a responder, invoke its callbacks for the lifecycle of the gesture.\n if (currentResponder.id != null && currentResponder.node != null) {\n const { id, node } = currentResponder\n const {\n onResponderStart,\n onResponderMove,\n onResponderEnd,\n onResponderRelease,\n onResponderTerminate,\n onResponderTerminationRequest,\n } = getResponderConfig(id)\n\n responderEvent.bubbles = false\n responderEvent.cancelable = false\n responderEvent.currentTarget = node\n\n // Start\n if (isStartEvent) {\n if (onResponderStart != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderStart'\n onResponderStart(responderEvent)\n }\n }\n // Move\n else if (isMoveEvent) {\n if (onResponderMove != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderMove'\n onResponderMove(responderEvent)\n }\n } else {\n const isTerminateEvent =\n isCancelish(eventType) ||\n // native context menu\n eventType === 'contextmenu' ||\n // window blur\n (eventType === 'blur' && eventTarget === window) ||\n // responder (or ancestors) blur\n (eventType === 'blur' &&\n eventTarget.contains(node) &&\n domEvent.relatedTarget !== node) ||\n // native scroll without using a pointer\n (isScrollEvent && trackedTouchCount === 0) ||\n // native scroll on node that is parent of the responder (allow siblings to scroll)\n (isScrollEvent && eventTarget.contains(node) && eventTarget !== node) ||\n // native select/selectionchange on node\n (isSelectionChangeEvent && hasValidSelection(domEvent))\n\n const isReleaseEvent =\n isEndEvent && !isTerminateEvent && !hasTargetTouches(node, domEvent.touches)\n\n // End\n if (isEndEvent) {\n if (onResponderEnd != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderEnd'\n onResponderEnd(responderEvent)\n }\n }\n // Release\n if (isReleaseEvent) {\n if (onResponderRelease != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderRelease'\n onResponderRelease(responderEvent)\n }\n changeCurrentResponder(emptyResponder)\n }\n // Terminate\n if (isTerminateEvent) {\n let shouldTerminate = true\n\n // Responders can still avoid termination but only for these events.\n if (\n eventType === 'contextmenu' ||\n eventType === 'scroll' ||\n eventType === 'selectionchange'\n ) {\n // Only call this function is it wasn't already called during negotiation.\n if (wasNegotiated) {\n shouldTerminate = false\n } else if (onResponderTerminationRequest != null) {\n responderEvent.dispatchConfig.registrationName =\n 'onResponderTerminationRequest'\n if (onResponderTerminationRequest(responderEvent) === false) {\n shouldTerminate = false\n }\n }\n }\n\n if (shouldTerminate) {\n if (onResponderTerminate != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminate'\n onResponderTerminate(responderEvent)\n }\n changeCurrentResponder(emptyResponder)\n isEmulatingMouseEvents = false\n trackedTouchCount = 0\n }\n }\n }\n }\n}\n\n/**\n * Walk the event path to/from the target node. At each node, stop and call the\n * relevant \"shouldSet\" functions for the given event type. If any of those functions\n * call \"stopPropagation\" on the event, stop searching for a responder.\n */\nfunction findWantsResponder(eventPaths, domEvent, responderEvent) {\n const shouldSetCallbacks = shouldSetResponderEvents[domEvent.type as any] // for Flow\n\n if (shouldSetCallbacks != null) {\n const { idPath, nodePath } = eventPaths\n\n const shouldSetCallbackCaptureName = shouldSetCallbacks[0]\n const shouldSetCallbackBubbleName = shouldSetCallbacks[1]\n const { bubbles } = shouldSetCallbacks[2]\n\n const check = function (id, node, callbackName) {\n const config = getResponderConfig(id)\n const shouldSetCallback = config[callbackName]\n if (shouldSetCallback != null) {\n responderEvent.currentTarget = node\n if (shouldSetCallback(responderEvent) === true) {\n // Start the path from the potential responder\n const prunedIdPath = idPath.slice(idPath.indexOf(id))\n return { id, node, idPath: prunedIdPath }\n }\n }\n }\n\n // capture\n for (let i = idPath.length - 1; i >= 0; i--) {\n const id = idPath[i]\n const node = nodePath[i]\n const result = check(id, node, shouldSetCallbackCaptureName)\n if (result != null) {\n return result\n }\n if (responderEvent.isPropagationStopped() === true) {\n return\n }\n }\n\n // bubble\n if (bubbles) {\n for (let i = 0; i < idPath.length; i++) {\n const id = idPath[i]\n const node = nodePath[i]\n const result = check(id, node, shouldSetCallbackBubbleName)\n if (result != null) {\n return result\n }\n if (responderEvent.isPropagationStopped() === true) {\n return\n }\n }\n } else {\n const id = idPath[0]\n const node = nodePath[0]\n const target = domEvent.target\n if (target === node) {\n return check(id, node, shouldSetCallbackBubbleName)\n }\n }\n }\n}\n\n/**\n * Attempt to transfer the responder.\n */\nfunction attemptTransfer(\n responderEvent: ResponderEvent,\n wantsResponder: ActiveResponderInstance,\n) {\n const { id: currentId, node: currentNode } = currentResponder\n const { id, node } = wantsResponder\n\n const { onResponderGrant, onResponderReject } = getResponderConfig(id)\n\n responderEvent.bubbles = false\n responderEvent.cancelable = false\n responderEvent.currentTarget = node\n\n // Set responder\n if (currentId == null) {\n if (onResponderGrant != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderGrant'\n onResponderGrant(responderEvent)\n }\n changeCurrentResponder(wantsResponder)\n }\n // Negotiate with current responder\n else {\n const { onResponderTerminate, onResponderTerminationRequest } =\n getResponderConfig(currentId)\n\n let allowTransfer = true\n if (onResponderTerminationRequest != null) {\n responderEvent.currentTarget = currentNode\n responderEvent.dispatchConfig.registrationName =\n 'onResponderTerminationRequest'\n if (onResponderTerminationRequest(responderEvent) === false) {\n allowTransfer = false\n }\n }\n\n if (allowTransfer) {\n // Terminate existing responder\n if (onResponderTerminate != null) {\n responderEvent.currentTarget = currentNode\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminate'\n onResponderTerminate(responderEvent)\n }\n // Grant next responder\n if (onResponderGrant != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderGrant'\n onResponderGrant(responderEvent)\n }\n changeCurrentResponder(wantsResponder)\n } else {\n // Reject responder request\n if (onResponderReject != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderReject'\n onResponderReject(responderEvent)\n }\n }\n }\n}\n\n/* ------------ PUBLIC API ------------ */\n\n/**\n * Attach Listeners\n *\n * Use native events as ReactDOM doesn't have a non-plugin API to implement\n * this system.\n */\nconst documentEventsCapturePhase = ['blur', 'scroll']\nconst documentEventsBubblePhase = [\n // mouse\n 'mousedown',\n 'mousemove',\n 'mouseup',\n 'dragstart',\n // touch\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'touchcancel',\n // other\n 'contextmenu',\n 'select',\n 'selectionchange',\n]\nexport function attachListeners() {\n if (canUseDOM && !window['__tamaguiReactResponderSystemActive']) {\n window.addEventListener('blur', eventListener)\n documentEventsBubblePhase.forEach((eventType) => {\n document.addEventListener(eventType, eventListener)\n })\n documentEventsCapturePhase.forEach((eventType) => {\n document.addEventListener(eventType, eventListener, true)\n })\n window['__tamaguiReactResponderSystemActive'] = true\n }\n}\n\n/**\n * Register a node with the ResponderSystem.\n */\nexport function addNode(id: ResponderId, node: any, config: ResponderConfig) {\n setResponderId(node, id)\n responderListenersMap.set(id, config)\n}\n\n/**\n * Unregister a node with the ResponderSystem.\n */\nexport function removeNode(id: ResponderId) {\n if (currentResponder.id === id) {\n terminateResponder()\n }\n if (responderListenersMap.has(id)) {\n responderListenersMap.delete(id)\n }\n}\n\n/**\n * Allow the current responder to be terminated from within components to support\n * more complex requirements, such as use with other React libraries for working\n * with scroll views, input views, etc.\n */\nexport function terminateResponder() {\n const { id, node } = currentResponder\n if (id != null && node != null) {\n const { onResponderTerminate } = getResponderConfig(id)\n if (onResponderTerminate != null) {\n const event = createResponderEvent({}, responderTouchHistoryStore)\n event.currentTarget = node\n onResponderTerminate(event)\n }\n changeCurrentResponder(emptyResponder)\n }\n isEmulatingMouseEvents = false\n trackedTouchCount = 0\n}\n\n/**\n * Allow unit tests to inspect the current responder in the system.\n * FOR TESTING ONLY.\n */\nexport function getResponderNode(): any {\n return currentResponder.node\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,kCAAiC;AACjC,wCAA2C;AAC3C,mBAOO;AACP,mBAA0B;AAC1B,IAAAA,gBAOO;
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) Nicolas Gallagher\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { ResponderEvent } from './createResponderEvent'\nimport createResponderEvent from './createResponderEvent'\nimport { ResponderTouchHistoryStore } from './ResponderTouchHistoryStore'\nimport {\n isCancelish,\n isEndish,\n isMoveish,\n isScroll,\n isSelectionChange,\n isStartish,\n} from './types'\nimport { canUseDOM } from './utils'\nimport {\n getLowestCommonAncestor,\n getResponderPaths,\n hasTargetTouches,\n hasValidSelection,\n isPrimaryPointerDown,\n setResponderId,\n} from './utils'\n\n/* ------------ TYPES ------------ */\n\ntype ResponderId = string\n\ntype ActiveResponderInstance = {\n id: ResponderId\n idPath: Array<number>\n node: any\n}\n\ntype EmptyResponderInstance = {\n id: null\n idPath: null\n node: null\n}\n\ntype ResponderInstance = ActiveResponderInstance | EmptyResponderInstance\n\nexport type ResponderConfig = {\n // Direct responder events dispatched directly to responder. Do not bubble.\n onResponderEnd?: ((e: ResponderEvent) => void) | null\n onResponderGrant?: ((e: ResponderEvent) => void | boolean) | null\n onResponderMove?: ((e: ResponderEvent) => void) | null\n onResponderRelease?: ((e: ResponderEvent) => void) | null\n onResponderReject?: ((e: ResponderEvent) => void) | null\n onResponderStart?: ((e: ResponderEvent) => void) | null\n onResponderTerminate?: ((e: ResponderEvent) => void) | null\n onResponderTerminationRequest?: ((e: ResponderEvent) => boolean) | null\n // On pointer down, should this element become the responder?\n onStartShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onStartShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On pointer move, should this element become the responder?\n onMoveShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onMoveShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On scroll, should this element become the responder? Do no bubble\n onScrollShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onScrollShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On text selection change, should this element become the responder?\n onSelectionChangeShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onSelectionChangeShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n}\n\nconst emptyObject = {}\n\n/* ------------ IMPLEMENTATION ------------ */\n\nconst startRegistration = [\n 'onStartShouldSetResponderCapture',\n 'onStartShouldSetResponder',\n { bubbles: true },\n]\nconst moveRegistration = [\n 'onMoveShouldSetResponderCapture',\n 'onMoveShouldSetResponder',\n { bubbles: true },\n]\nconst scrollRegistration = [\n 'onScrollShouldSetResponderCapture',\n 'onScrollShouldSetResponder',\n { bubbles: false },\n]\nconst shouldSetResponderEvents = {\n touchstart: startRegistration,\n mousedown: startRegistration,\n touchmove: moveRegistration,\n mousemove: moveRegistration,\n scroll: scrollRegistration,\n}\n\nconst emptyResponder = { id: null, idPath: null, node: null }\nconst responderListenersMap = new Map()\n\nlet isEmulatingMouseEvents = false\nlet trackedTouchCount = 0\nlet currentResponder: ResponderInstance = {\n id: null,\n node: null,\n idPath: null,\n}\nconst responderTouchHistoryStore = new ResponderTouchHistoryStore()\n\nfunction changeCurrentResponder(responder: ResponderInstance) {\n currentResponder = responder\n}\n\nfunction getResponderConfig(id: ResponderId): ResponderConfig | any {\n const config = responderListenersMap.get(id)\n return config != null ? config : emptyObject\n}\n\n/**\n * Process native events\n *\n * A single event listener is used to manage the responder system.\n * All pointers are tracked in the ResponderTouchHistoryStore. Native events\n * are interpreted in terms of the Responder System and checked to see if\n * the responder should be transferred. Each host node that is attached to\n * the Responder System has an ID, which is used to look up its associated\n * callbacks.\n */\nfunction eventListener(domEvent: any) {\n const eventType = domEvent.type\n const eventTarget = domEvent.target\n\n /**\n * Manage emulated events and early bailout.\n * Since PointerEvent is not used yet (lack of support in older Safari), it's\n * necessary to manually manage the mess of browser touch/mouse events.\n * And bailout early for termination events when there is no active responder.\n */\n\n // Flag when browser may produce emulated events\n if (eventType === 'touchstart') {\n isEmulatingMouseEvents = true\n }\n // Remove flag when browser will not produce emulated events\n if (eventType === 'touchmove' || trackedTouchCount > 1) {\n isEmulatingMouseEvents = false\n }\n // Ignore various events in particular circumstances\n if (\n // Ignore browser emulated mouse events\n (eventType === 'mousedown' && isEmulatingMouseEvents) ||\n (eventType === 'mousemove' && isEmulatingMouseEvents) ||\n // Ignore mousemove if a mousedown didn't occur first\n (eventType === 'mousemove' && trackedTouchCount < 1)\n ) {\n return\n }\n // Remove flag after emulated events are finished\n if (isEmulatingMouseEvents && eventType === 'mouseup') {\n if (trackedTouchCount === 0) {\n isEmulatingMouseEvents = false\n }\n return\n }\n\n const isStartEvent = isStartish(eventType) && isPrimaryPointerDown(domEvent)\n const isMoveEvent = isMoveish(eventType)\n const isEndEvent = isEndish(eventType)\n const isScrollEvent = isScroll(eventType)\n const isSelectionChangeEvent = isSelectionChange(eventType)\n const responderEvent = createResponderEvent(domEvent, responderTouchHistoryStore)\n\n /**\n * Record the state of active pointers\n */\n\n if (isStartEvent || isMoveEvent || isEndEvent) {\n if (domEvent.touches) {\n trackedTouchCount = domEvent.touches.length\n } else {\n if (isStartEvent) {\n trackedTouchCount = 1\n } else if (isEndEvent) {\n trackedTouchCount = 0\n }\n }\n responderTouchHistoryStore.recordTouchTrack(\n eventType,\n responderEvent.nativeEvent as any\n )\n }\n\n /**\n * Responder System logic\n */\n\n let eventPaths: any = getResponderPaths(domEvent)\n let wasNegotiated = false\n let wantsResponder\n\n // If an event occured that might change the current responder...\n if (isStartEvent || isMoveEvent || (isScrollEvent && trackedTouchCount > 0)) {\n // If there is already a responder, prune the event paths to the lowest common ancestor\n // of the existing responder and deepest target of the event.\n const currentResponderIdPath = currentResponder.idPath\n const eventIdPath = eventPaths.idPath\n\n if (currentResponderIdPath != null && eventIdPath != null) {\n const lowestCommonAncestor = getLowestCommonAncestor(\n currentResponderIdPath,\n eventIdPath\n )\n if (lowestCommonAncestor != null) {\n const indexOfLowestCommonAncestor = eventIdPath.indexOf(lowestCommonAncestor)\n // Skip the current responder so it doesn't receive unexpected \"shouldSet\" events.\n const index =\n indexOfLowestCommonAncestor +\n (lowestCommonAncestor === currentResponder.id ? 1 : 0)\n eventPaths = {\n idPath: eventIdPath.slice(index),\n nodePath: eventPaths.nodePath.slice(index),\n }\n } else {\n eventPaths = null\n }\n }\n\n if (eventPaths != null) {\n // If a node wants to become the responder, attempt to transfer.\n wantsResponder = findWantsResponder(eventPaths, domEvent, responderEvent)\n if (wantsResponder != null) {\n // Sets responder if none exists, or negotates with existing responder.\n attemptTransfer(responderEvent, wantsResponder)\n wasNegotiated = true\n }\n }\n }\n\n // If there is now a responder, invoke its callbacks for the lifecycle of the gesture.\n if (currentResponder.id != null && currentResponder.node != null) {\n const { id, node } = currentResponder\n const {\n onResponderStart,\n onResponderMove,\n onResponderEnd,\n onResponderRelease,\n onResponderTerminate,\n onResponderTerminationRequest,\n } = getResponderConfig(id)\n\n responderEvent.bubbles = false\n responderEvent.cancelable = false\n responderEvent.currentTarget = node\n\n // Start\n if (isStartEvent) {\n if (onResponderStart != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderStart'\n onResponderStart(responderEvent)\n }\n }\n // Move\n else if (isMoveEvent) {\n if (onResponderMove != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderMove'\n onResponderMove(responderEvent)\n }\n } else {\n const isTerminateEvent =\n isCancelish(eventType) ||\n // native context menu\n eventType === 'contextmenu' ||\n // window blur\n (eventType === 'blur' && eventTarget === window) ||\n // responder (or ancestors) blur\n (eventType === 'blur' &&\n eventTarget.contains(node) &&\n domEvent.relatedTarget !== node) ||\n // native scroll without using a pointer\n (isScrollEvent && trackedTouchCount === 0) ||\n // native scroll on node that is parent of the responder (allow siblings to scroll)\n (isScrollEvent && eventTarget.contains(node) && eventTarget !== node) ||\n // native select/selectionchange on node\n (isSelectionChangeEvent && hasValidSelection(domEvent))\n\n const isReleaseEvent =\n isEndEvent && !isTerminateEvent && !hasTargetTouches(node, domEvent.touches)\n\n // End\n if (isEndEvent) {\n if (onResponderEnd != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderEnd'\n onResponderEnd(responderEvent)\n }\n }\n // Release\n if (isReleaseEvent) {\n if (onResponderRelease != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderRelease'\n onResponderRelease(responderEvent)\n }\n changeCurrentResponder(emptyResponder)\n }\n // Terminate\n if (isTerminateEvent) {\n let shouldTerminate = true\n\n // Responders can still avoid termination but only for these events.\n if (\n eventType === 'contextmenu' ||\n eventType === 'scroll' ||\n eventType === 'selectionchange'\n ) {\n // Only call this function is it wasn't already called during negotiation.\n if (wasNegotiated) {\n shouldTerminate = false\n } else if (onResponderTerminationRequest != null) {\n responderEvent.dispatchConfig.registrationName =\n 'onResponderTerminationRequest'\n if (onResponderTerminationRequest(responderEvent) === false) {\n shouldTerminate = false\n }\n }\n }\n\n if (shouldTerminate) {\n if (onResponderTerminate != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminate'\n onResponderTerminate(responderEvent)\n }\n changeCurrentResponder(emptyResponder)\n isEmulatingMouseEvents = false\n trackedTouchCount = 0\n }\n }\n }\n }\n}\n\n/**\n * Walk the event path to/from the target node. At each node, stop and call the\n * relevant \"shouldSet\" functions for the given event type. If any of those functions\n * call \"stopPropagation\" on the event, stop searching for a responder.\n */\nfunction findWantsResponder(eventPaths, domEvent, responderEvent) {\n const shouldSetCallbacks = shouldSetResponderEvents[domEvent.type as any] // for Flow\n\n if (shouldSetCallbacks != null) {\n const { idPath, nodePath } = eventPaths\n\n const shouldSetCallbackCaptureName = shouldSetCallbacks[0]\n const shouldSetCallbackBubbleName = shouldSetCallbacks[1]\n const { bubbles } = shouldSetCallbacks[2]\n\n const check = function (id, node, callbackName) {\n const config = getResponderConfig(id)\n const shouldSetCallback = config[callbackName]\n if (shouldSetCallback != null) {\n responderEvent.currentTarget = node\n if (shouldSetCallback(responderEvent) === true) {\n // Start the path from the potential responder\n const prunedIdPath = idPath.slice(idPath.indexOf(id))\n return { id, node, idPath: prunedIdPath }\n }\n }\n }\n\n // capture\n for (let i = idPath.length - 1; i >= 0; i--) {\n const id = idPath[i]\n const node = nodePath[i]\n const result = check(id, node, shouldSetCallbackCaptureName)\n if (result != null) {\n return result\n }\n if (responderEvent.isPropagationStopped() === true) {\n return\n }\n }\n\n // bubble\n if (bubbles) {\n for (let i = 0; i < idPath.length; i++) {\n const id = idPath[i]\n const node = nodePath[i]\n const result = check(id, node, shouldSetCallbackBubbleName)\n if (result != null) {\n return result\n }\n if (responderEvent.isPropagationStopped() === true) {\n return\n }\n }\n } else {\n const id = idPath[0]\n const node = nodePath[0]\n const target = domEvent.target\n if (target === node) {\n return check(id, node, shouldSetCallbackBubbleName)\n }\n }\n }\n}\n\n/**\n * Attempt to transfer the responder.\n */\nfunction attemptTransfer(\n responderEvent: ResponderEvent,\n wantsResponder: ActiveResponderInstance\n) {\n const { id: currentId, node: currentNode } = currentResponder\n const { id, node } = wantsResponder\n\n const { onResponderGrant, onResponderReject } = getResponderConfig(id)\n\n responderEvent.bubbles = false\n responderEvent.cancelable = false\n responderEvent.currentTarget = node\n\n // Set responder\n if (currentId == null) {\n if (onResponderGrant != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderGrant'\n onResponderGrant(responderEvent)\n }\n changeCurrentResponder(wantsResponder)\n }\n // Negotiate with current responder\n else {\n const { onResponderTerminate, onResponderTerminationRequest } =\n getResponderConfig(currentId)\n\n let allowTransfer = true\n if (onResponderTerminationRequest != null) {\n responderEvent.currentTarget = currentNode\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminationRequest'\n if (onResponderTerminationRequest(responderEvent) === false) {\n allowTransfer = false\n }\n }\n\n if (allowTransfer) {\n // Terminate existing responder\n if (onResponderTerminate != null) {\n responderEvent.currentTarget = currentNode\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminate'\n onResponderTerminate(responderEvent)\n }\n // Grant next responder\n if (onResponderGrant != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderGrant'\n onResponderGrant(responderEvent)\n }\n changeCurrentResponder(wantsResponder)\n } else {\n // Reject responder request\n if (onResponderReject != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderReject'\n onResponderReject(responderEvent)\n }\n }\n }\n}\n\n/* ------------ PUBLIC API ------------ */\n\n/**\n * Attach Listeners\n *\n * Use native events as ReactDOM doesn't have a non-plugin API to implement\n * this system.\n */\nconst documentEventsCapturePhase = ['blur', 'scroll']\nconst documentEventsBubblePhase = [\n // mouse\n 'mousedown',\n 'mousemove',\n 'mouseup',\n 'dragstart',\n // touch\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'touchcancel',\n // other\n 'contextmenu',\n 'select',\n 'selectionchange',\n]\n\nconst isTamaguiResponderActive = Symbol()\n\nexport function attachListeners() {\n if (canUseDOM && !window[isTamaguiResponderActive]) {\n window.addEventListener('blur', eventListener)\n documentEventsBubblePhase.forEach((eventType) => {\n document.addEventListener(eventType, eventListener)\n })\n documentEventsCapturePhase.forEach((eventType) => {\n document.addEventListener(eventType, eventListener, true)\n })\n window[isTamaguiResponderActive] = true\n }\n}\n\n/**\n * Register a node with the ResponderSystem.\n */\nexport function addNode(id: ResponderId, node: any, config: ResponderConfig) {\n setResponderId(node, id)\n responderListenersMap.set(id, config)\n}\n\n/**\n * Unregister a node with the ResponderSystem.\n */\nexport function removeNode(id: ResponderId) {\n if (currentResponder.id === id) {\n terminateResponder()\n }\n if (responderListenersMap.has(id)) {\n responderListenersMap.delete(id)\n }\n}\n\n/**\n * Allow the current responder to be terminated from within components to support\n * more complex requirements, such as use with other React libraries for working\n * with scroll views, input views, etc.\n */\nexport function terminateResponder() {\n const { id, node } = currentResponder\n if (id != null && node != null) {\n const { onResponderTerminate } = getResponderConfig(id)\n if (onResponderTerminate != null) {\n const event = createResponderEvent({}, responderTouchHistoryStore)\n event.currentTarget = node\n onResponderTerminate(event)\n }\n changeCurrentResponder(emptyResponder)\n }\n isEmulatingMouseEvents = false\n trackedTouchCount = 0\n}\n\n/**\n * Allow unit tests to inspect the current responder in the system.\n * FOR TESTING ONLY.\n */\nexport function getResponderNode(): any {\n return currentResponder.node\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_utils", "createResponderEvent"]
|
|
7
7
|
}
|
|
@@ -300,8 +300,9 @@ const documentEventsBubblePhase = [
|
|
|
300
300
|
"select",
|
|
301
301
|
"selectionchange"
|
|
302
302
|
];
|
|
303
|
+
const isTamaguiResponderActive = Symbol();
|
|
303
304
|
function attachListeners() {
|
|
304
|
-
if (canUseDOM && !window[
|
|
305
|
+
if (canUseDOM && !window[isTamaguiResponderActive]) {
|
|
305
306
|
window.addEventListener("blur", eventListener);
|
|
306
307
|
documentEventsBubblePhase.forEach((eventType) => {
|
|
307
308
|
document.addEventListener(eventType, eventListener);
|
|
@@ -309,7 +310,7 @@ function attachListeners() {
|
|
|
309
310
|
documentEventsCapturePhase.forEach((eventType) => {
|
|
310
311
|
document.addEventListener(eventType, eventListener, true);
|
|
311
312
|
});
|
|
312
|
-
window[
|
|
313
|
+
window[isTamaguiResponderActive] = true;
|
|
313
314
|
}
|
|
314
315
|
}
|
|
315
316
|
function addNode(id, node, config) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/ResponderSystem.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Copyright (c) Nicolas Gallagher\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { ResponderEvent } from './createResponderEvent'\nimport createResponderEvent from './createResponderEvent'\nimport { ResponderTouchHistoryStore } from './ResponderTouchHistoryStore'\nimport {\n isCancelish,\n isEndish,\n isMoveish,\n isScroll,\n isSelectionChange,\n isStartish,\n} from './types'\nimport { canUseDOM } from './utils'\nimport {\n getLowestCommonAncestor,\n getResponderPaths,\n hasTargetTouches,\n hasValidSelection,\n isPrimaryPointerDown,\n setResponderId,\n} from './utils'\n\n/* ------------ TYPES ------------ */\n\ntype ResponderId = string\n\ntype ActiveResponderInstance = {\n id: ResponderId\n idPath: Array<number>\n node: any\n}\n\ntype EmptyResponderInstance = {\n id: null\n idPath: null\n node: null\n}\n\ntype ResponderInstance = ActiveResponderInstance | EmptyResponderInstance\n\nexport type ResponderConfig = {\n // Direct responder events dispatched directly to responder. Do not bubble.\n onResponderEnd?: ((e: ResponderEvent) => void) | null\n onResponderGrant?: ((e: ResponderEvent) => void | boolean) | null\n onResponderMove?: ((e: ResponderEvent) => void) | null\n onResponderRelease?: ((e: ResponderEvent) => void) | null\n onResponderReject?: ((e: ResponderEvent) => void) | null\n onResponderStart?: ((e: ResponderEvent) => void) | null\n onResponderTerminate?: ((e: ResponderEvent) => void) | null\n onResponderTerminationRequest?: ((e: ResponderEvent) => boolean) | null\n // On pointer down, should this element become the responder?\n onStartShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onStartShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On pointer move, should this element become the responder?\n onMoveShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onMoveShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On scroll, should this element become the responder? Do no bubble\n onScrollShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onScrollShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On text selection change, should this element become the responder?\n onSelectionChangeShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onSelectionChangeShouldSetResponderCapture?:\n | ((e: ResponderEvent) => boolean)\n | null\n}\n\nconst emptyObject = {}\n\n/* ------------ IMPLEMENTATION ------------ */\n\nconst startRegistration = [\n 'onStartShouldSetResponderCapture',\n 'onStartShouldSetResponder',\n { bubbles: true },\n]\nconst moveRegistration = [\n 'onMoveShouldSetResponderCapture',\n 'onMoveShouldSetResponder',\n { bubbles: true },\n]\nconst scrollRegistration = [\n 'onScrollShouldSetResponderCapture',\n 'onScrollShouldSetResponder',\n { bubbles: false },\n]\nconst shouldSetResponderEvents = {\n touchstart: startRegistration,\n mousedown: startRegistration,\n touchmove: moveRegistration,\n mousemove: moveRegistration,\n scroll: scrollRegistration,\n}\n\nconst emptyResponder = { id: null, idPath: null, node: null }\nconst responderListenersMap = new Map()\n\nlet isEmulatingMouseEvents = false\nlet trackedTouchCount = 0\nlet currentResponder: ResponderInstance = {\n id: null,\n node: null,\n idPath: null,\n}\nconst responderTouchHistoryStore = new ResponderTouchHistoryStore()\n\nfunction changeCurrentResponder(responder: ResponderInstance) {\n currentResponder = responder\n}\n\nfunction getResponderConfig(id: ResponderId): ResponderConfig | any {\n const config = responderListenersMap.get(id)\n return config != null ? config : emptyObject\n}\n\n/**\n * Process native events\n *\n * A single event listener is used to manage the responder system.\n * All pointers are tracked in the ResponderTouchHistoryStore. Native events\n * are interpreted in terms of the Responder System and checked to see if\n * the responder should be transferred. Each host node that is attached to\n * the Responder System has an ID, which is used to look up its associated\n * callbacks.\n */\nfunction eventListener(domEvent: any) {\n const eventType = domEvent.type\n const eventTarget = domEvent.target\n\n /**\n * Manage emulated events and early bailout.\n * Since PointerEvent is not used yet (lack of support in older Safari), it's\n * necessary to manually manage the mess of browser touch/mouse events.\n * And bailout early for termination events when there is no active responder.\n */\n\n // Flag when browser may produce emulated events\n if (eventType === 'touchstart') {\n isEmulatingMouseEvents = true\n }\n // Remove flag when browser will not produce emulated events\n if (eventType === 'touchmove' || trackedTouchCount > 1) {\n isEmulatingMouseEvents = false\n }\n // Ignore various events in particular circumstances\n if (\n // Ignore browser emulated mouse events\n (eventType === 'mousedown' && isEmulatingMouseEvents) ||\n (eventType === 'mousemove' && isEmulatingMouseEvents) ||\n // Ignore mousemove if a mousedown didn't occur first\n (eventType === 'mousemove' && trackedTouchCount < 1)\n ) {\n return\n }\n // Remove flag after emulated events are finished\n if (isEmulatingMouseEvents && eventType === 'mouseup') {\n if (trackedTouchCount === 0) {\n isEmulatingMouseEvents = false\n }\n return\n }\n\n const isStartEvent = isStartish(eventType) && isPrimaryPointerDown(domEvent)\n const isMoveEvent = isMoveish(eventType)\n const isEndEvent = isEndish(eventType)\n const isScrollEvent = isScroll(eventType)\n const isSelectionChangeEvent = isSelectionChange(eventType)\n const responderEvent = createResponderEvent(domEvent, responderTouchHistoryStore)\n\n /**\n * Record the state of active pointers\n */\n\n if (isStartEvent || isMoveEvent || isEndEvent) {\n if (domEvent.touches) {\n trackedTouchCount = domEvent.touches.length\n } else {\n if (isStartEvent) {\n trackedTouchCount = 1\n } else if (isEndEvent) {\n trackedTouchCount = 0\n }\n }\n responderTouchHistoryStore.recordTouchTrack(\n eventType,\n responderEvent.nativeEvent as any,\n )\n }\n\n /**\n * Responder System logic\n */\n\n let eventPaths: any = getResponderPaths(domEvent)\n let wasNegotiated = false\n let wantsResponder\n\n // If an event occured that might change the current responder...\n if (isStartEvent || isMoveEvent || (isScrollEvent && trackedTouchCount > 0)) {\n // If there is already a responder, prune the event paths to the lowest common ancestor\n // of the existing responder and deepest target of the event.\n const currentResponderIdPath = currentResponder.idPath\n const eventIdPath = eventPaths.idPath\n\n if (currentResponderIdPath != null && eventIdPath != null) {\n const lowestCommonAncestor = getLowestCommonAncestor(\n currentResponderIdPath,\n eventIdPath,\n )\n if (lowestCommonAncestor != null) {\n const indexOfLowestCommonAncestor = eventIdPath.indexOf(lowestCommonAncestor)\n // Skip the current responder so it doesn't receive unexpected \"shouldSet\" events.\n const index =\n indexOfLowestCommonAncestor +\n (lowestCommonAncestor === currentResponder.id ? 1 : 0)\n eventPaths = {\n idPath: eventIdPath.slice(index),\n nodePath: eventPaths.nodePath.slice(index),\n }\n } else {\n eventPaths = null\n }\n }\n\n if (eventPaths != null) {\n // If a node wants to become the responder, attempt to transfer.\n wantsResponder = findWantsResponder(eventPaths, domEvent, responderEvent)\n if (wantsResponder != null) {\n // Sets responder if none exists, or negotates with existing responder.\n attemptTransfer(responderEvent, wantsResponder)\n wasNegotiated = true\n }\n }\n }\n\n // If there is now a responder, invoke its callbacks for the lifecycle of the gesture.\n if (currentResponder.id != null && currentResponder.node != null) {\n const { id, node } = currentResponder\n const {\n onResponderStart,\n onResponderMove,\n onResponderEnd,\n onResponderRelease,\n onResponderTerminate,\n onResponderTerminationRequest,\n } = getResponderConfig(id)\n\n responderEvent.bubbles = false\n responderEvent.cancelable = false\n responderEvent.currentTarget = node\n\n // Start\n if (isStartEvent) {\n if (onResponderStart != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderStart'\n onResponderStart(responderEvent)\n }\n }\n // Move\n else if (isMoveEvent) {\n if (onResponderMove != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderMove'\n onResponderMove(responderEvent)\n }\n } else {\n const isTerminateEvent =\n isCancelish(eventType) ||\n // native context menu\n eventType === 'contextmenu' ||\n // window blur\n (eventType === 'blur' && eventTarget === window) ||\n // responder (or ancestors) blur\n (eventType === 'blur' &&\n eventTarget.contains(node) &&\n domEvent.relatedTarget !== node) ||\n // native scroll without using a pointer\n (isScrollEvent && trackedTouchCount === 0) ||\n // native scroll on node that is parent of the responder (allow siblings to scroll)\n (isScrollEvent && eventTarget.contains(node) && eventTarget !== node) ||\n // native select/selectionchange on node\n (isSelectionChangeEvent && hasValidSelection(domEvent))\n\n const isReleaseEvent =\n isEndEvent && !isTerminateEvent && !hasTargetTouches(node, domEvent.touches)\n\n // End\n if (isEndEvent) {\n if (onResponderEnd != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderEnd'\n onResponderEnd(responderEvent)\n }\n }\n // Release\n if (isReleaseEvent) {\n if (onResponderRelease != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderRelease'\n onResponderRelease(responderEvent)\n }\n changeCurrentResponder(emptyResponder)\n }\n // Terminate\n if (isTerminateEvent) {\n let shouldTerminate = true\n\n // Responders can still avoid termination but only for these events.\n if (\n eventType === 'contextmenu' ||\n eventType === 'scroll' ||\n eventType === 'selectionchange'\n ) {\n // Only call this function is it wasn't already called during negotiation.\n if (wasNegotiated) {\n shouldTerminate = false\n } else if (onResponderTerminationRequest != null) {\n responderEvent.dispatchConfig.registrationName =\n 'onResponderTerminationRequest'\n if (onResponderTerminationRequest(responderEvent) === false) {\n shouldTerminate = false\n }\n }\n }\n\n if (shouldTerminate) {\n if (onResponderTerminate != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminate'\n onResponderTerminate(responderEvent)\n }\n changeCurrentResponder(emptyResponder)\n isEmulatingMouseEvents = false\n trackedTouchCount = 0\n }\n }\n }\n }\n}\n\n/**\n * Walk the event path to/from the target node. At each node, stop and call the\n * relevant \"shouldSet\" functions for the given event type. If any of those functions\n * call \"stopPropagation\" on the event, stop searching for a responder.\n */\nfunction findWantsResponder(eventPaths, domEvent, responderEvent) {\n const shouldSetCallbacks = shouldSetResponderEvents[domEvent.type as any] // for Flow\n\n if (shouldSetCallbacks != null) {\n const { idPath, nodePath } = eventPaths\n\n const shouldSetCallbackCaptureName = shouldSetCallbacks[0]\n const shouldSetCallbackBubbleName = shouldSetCallbacks[1]\n const { bubbles } = shouldSetCallbacks[2]\n\n const check = function (id, node, callbackName) {\n const config = getResponderConfig(id)\n const shouldSetCallback = config[callbackName]\n if (shouldSetCallback != null) {\n responderEvent.currentTarget = node\n if (shouldSetCallback(responderEvent) === true) {\n // Start the path from the potential responder\n const prunedIdPath = idPath.slice(idPath.indexOf(id))\n return { id, node, idPath: prunedIdPath }\n }\n }\n }\n\n // capture\n for (let i = idPath.length - 1; i >= 0; i--) {\n const id = idPath[i]\n const node = nodePath[i]\n const result = check(id, node, shouldSetCallbackCaptureName)\n if (result != null) {\n return result\n }\n if (responderEvent.isPropagationStopped() === true) {\n return\n }\n }\n\n // bubble\n if (bubbles) {\n for (let i = 0; i < idPath.length; i++) {\n const id = idPath[i]\n const node = nodePath[i]\n const result = check(id, node, shouldSetCallbackBubbleName)\n if (result != null) {\n return result\n }\n if (responderEvent.isPropagationStopped() === true) {\n return\n }\n }\n } else {\n const id = idPath[0]\n const node = nodePath[0]\n const target = domEvent.target\n if (target === node) {\n return check(id, node, shouldSetCallbackBubbleName)\n }\n }\n }\n}\n\n/**\n * Attempt to transfer the responder.\n */\nfunction attemptTransfer(\n responderEvent: ResponderEvent,\n wantsResponder: ActiveResponderInstance,\n) {\n const { id: currentId, node: currentNode } = currentResponder\n const { id, node } = wantsResponder\n\n const { onResponderGrant, onResponderReject } = getResponderConfig(id)\n\n responderEvent.bubbles = false\n responderEvent.cancelable = false\n responderEvent.currentTarget = node\n\n // Set responder\n if (currentId == null) {\n if (onResponderGrant != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderGrant'\n onResponderGrant(responderEvent)\n }\n changeCurrentResponder(wantsResponder)\n }\n // Negotiate with current responder\n else {\n const { onResponderTerminate, onResponderTerminationRequest } =\n getResponderConfig(currentId)\n\n let allowTransfer = true\n if (onResponderTerminationRequest != null) {\n responderEvent.currentTarget = currentNode\n responderEvent.dispatchConfig.registrationName =\n 'onResponderTerminationRequest'\n if (onResponderTerminationRequest(responderEvent) === false) {\n allowTransfer = false\n }\n }\n\n if (allowTransfer) {\n // Terminate existing responder\n if (onResponderTerminate != null) {\n responderEvent.currentTarget = currentNode\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminate'\n onResponderTerminate(responderEvent)\n }\n // Grant next responder\n if (onResponderGrant != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderGrant'\n onResponderGrant(responderEvent)\n }\n changeCurrentResponder(wantsResponder)\n } else {\n // Reject responder request\n if (onResponderReject != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderReject'\n onResponderReject(responderEvent)\n }\n }\n }\n}\n\n/* ------------ PUBLIC API ------------ */\n\n/**\n * Attach Listeners\n *\n * Use native events as ReactDOM doesn't have a non-plugin API to implement\n * this system.\n */\nconst documentEventsCapturePhase = ['blur', 'scroll']\nconst documentEventsBubblePhase = [\n // mouse\n 'mousedown',\n 'mousemove',\n 'mouseup',\n 'dragstart',\n // touch\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'touchcancel',\n // other\n 'contextmenu',\n 'select',\n 'selectionchange',\n]\nexport function attachListeners() {\n if (canUseDOM && !window['__tamaguiReactResponderSystemActive']) {\n window.addEventListener('blur', eventListener)\n documentEventsBubblePhase.forEach((eventType) => {\n document.addEventListener(eventType, eventListener)\n })\n documentEventsCapturePhase.forEach((eventType) => {\n document.addEventListener(eventType, eventListener, true)\n })\n window['__tamaguiReactResponderSystemActive'] = true\n }\n}\n\n/**\n * Register a node with the ResponderSystem.\n */\nexport function addNode(id: ResponderId, node: any, config: ResponderConfig) {\n setResponderId(node, id)\n responderListenersMap.set(id, config)\n}\n\n/**\n * Unregister a node with the ResponderSystem.\n */\nexport function removeNode(id: ResponderId) {\n if (currentResponder.id === id) {\n terminateResponder()\n }\n if (responderListenersMap.has(id)) {\n responderListenersMap.delete(id)\n }\n}\n\n/**\n * Allow the current responder to be terminated from within components to support\n * more complex requirements, such as use with other React libraries for working\n * with scroll views, input views, etc.\n */\nexport function terminateResponder() {\n const { id, node } = currentResponder\n if (id != null && node != null) {\n const { onResponderTerminate } = getResponderConfig(id)\n if (onResponderTerminate != null) {\n const event = createResponderEvent({}, responderTouchHistoryStore)\n event.currentTarget = node\n onResponderTerminate(event)\n }\n changeCurrentResponder(emptyResponder)\n }\n isEmulatingMouseEvents = false\n trackedTouchCount = 0\n}\n\n/**\n * Allow unit tests to inspect the current responder in the system.\n * FOR TESTING ONLY.\n */\nexport function getResponderNode(): any {\n return currentResponder.node\n}\n"],
|
|
5
|
-
"mappings": "AAOA,OAAO,0BAA0B;AACjC,SAAS,kCAAkC;AAC3C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) Nicolas Gallagher\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { ResponderEvent } from './createResponderEvent'\nimport createResponderEvent from './createResponderEvent'\nimport { ResponderTouchHistoryStore } from './ResponderTouchHistoryStore'\nimport {\n isCancelish,\n isEndish,\n isMoveish,\n isScroll,\n isSelectionChange,\n isStartish,\n} from './types'\nimport { canUseDOM } from './utils'\nimport {\n getLowestCommonAncestor,\n getResponderPaths,\n hasTargetTouches,\n hasValidSelection,\n isPrimaryPointerDown,\n setResponderId,\n} from './utils'\n\n/* ------------ TYPES ------------ */\n\ntype ResponderId = string\n\ntype ActiveResponderInstance = {\n id: ResponderId\n idPath: Array<number>\n node: any\n}\n\ntype EmptyResponderInstance = {\n id: null\n idPath: null\n node: null\n}\n\ntype ResponderInstance = ActiveResponderInstance | EmptyResponderInstance\n\nexport type ResponderConfig = {\n // Direct responder events dispatched directly to responder. Do not bubble.\n onResponderEnd?: ((e: ResponderEvent) => void) | null\n onResponderGrant?: ((e: ResponderEvent) => void | boolean) | null\n onResponderMove?: ((e: ResponderEvent) => void) | null\n onResponderRelease?: ((e: ResponderEvent) => void) | null\n onResponderReject?: ((e: ResponderEvent) => void) | null\n onResponderStart?: ((e: ResponderEvent) => void) | null\n onResponderTerminate?: ((e: ResponderEvent) => void) | null\n onResponderTerminationRequest?: ((e: ResponderEvent) => boolean) | null\n // On pointer down, should this element become the responder?\n onStartShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onStartShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On pointer move, should this element become the responder?\n onMoveShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onMoveShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On scroll, should this element become the responder? Do no bubble\n onScrollShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onScrollShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n // On text selection change, should this element become the responder?\n onSelectionChangeShouldSetResponder?: ((e: ResponderEvent) => boolean) | null\n onSelectionChangeShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null\n}\n\nconst emptyObject = {}\n\n/* ------------ IMPLEMENTATION ------------ */\n\nconst startRegistration = [\n 'onStartShouldSetResponderCapture',\n 'onStartShouldSetResponder',\n { bubbles: true },\n]\nconst moveRegistration = [\n 'onMoveShouldSetResponderCapture',\n 'onMoveShouldSetResponder',\n { bubbles: true },\n]\nconst scrollRegistration = [\n 'onScrollShouldSetResponderCapture',\n 'onScrollShouldSetResponder',\n { bubbles: false },\n]\nconst shouldSetResponderEvents = {\n touchstart: startRegistration,\n mousedown: startRegistration,\n touchmove: moveRegistration,\n mousemove: moveRegistration,\n scroll: scrollRegistration,\n}\n\nconst emptyResponder = { id: null, idPath: null, node: null }\nconst responderListenersMap = new Map()\n\nlet isEmulatingMouseEvents = false\nlet trackedTouchCount = 0\nlet currentResponder: ResponderInstance = {\n id: null,\n node: null,\n idPath: null,\n}\nconst responderTouchHistoryStore = new ResponderTouchHistoryStore()\n\nfunction changeCurrentResponder(responder: ResponderInstance) {\n currentResponder = responder\n}\n\nfunction getResponderConfig(id: ResponderId): ResponderConfig | any {\n const config = responderListenersMap.get(id)\n return config != null ? config : emptyObject\n}\n\n/**\n * Process native events\n *\n * A single event listener is used to manage the responder system.\n * All pointers are tracked in the ResponderTouchHistoryStore. Native events\n * are interpreted in terms of the Responder System and checked to see if\n * the responder should be transferred. Each host node that is attached to\n * the Responder System has an ID, which is used to look up its associated\n * callbacks.\n */\nfunction eventListener(domEvent: any) {\n const eventType = domEvent.type\n const eventTarget = domEvent.target\n\n /**\n * Manage emulated events and early bailout.\n * Since PointerEvent is not used yet (lack of support in older Safari), it's\n * necessary to manually manage the mess of browser touch/mouse events.\n * And bailout early for termination events when there is no active responder.\n */\n\n // Flag when browser may produce emulated events\n if (eventType === 'touchstart') {\n isEmulatingMouseEvents = true\n }\n // Remove flag when browser will not produce emulated events\n if (eventType === 'touchmove' || trackedTouchCount > 1) {\n isEmulatingMouseEvents = false\n }\n // Ignore various events in particular circumstances\n if (\n // Ignore browser emulated mouse events\n (eventType === 'mousedown' && isEmulatingMouseEvents) ||\n (eventType === 'mousemove' && isEmulatingMouseEvents) ||\n // Ignore mousemove if a mousedown didn't occur first\n (eventType === 'mousemove' && trackedTouchCount < 1)\n ) {\n return\n }\n // Remove flag after emulated events are finished\n if (isEmulatingMouseEvents && eventType === 'mouseup') {\n if (trackedTouchCount === 0) {\n isEmulatingMouseEvents = false\n }\n return\n }\n\n const isStartEvent = isStartish(eventType) && isPrimaryPointerDown(domEvent)\n const isMoveEvent = isMoveish(eventType)\n const isEndEvent = isEndish(eventType)\n const isScrollEvent = isScroll(eventType)\n const isSelectionChangeEvent = isSelectionChange(eventType)\n const responderEvent = createResponderEvent(domEvent, responderTouchHistoryStore)\n\n /**\n * Record the state of active pointers\n */\n\n if (isStartEvent || isMoveEvent || isEndEvent) {\n if (domEvent.touches) {\n trackedTouchCount = domEvent.touches.length\n } else {\n if (isStartEvent) {\n trackedTouchCount = 1\n } else if (isEndEvent) {\n trackedTouchCount = 0\n }\n }\n responderTouchHistoryStore.recordTouchTrack(\n eventType,\n responderEvent.nativeEvent as any\n )\n }\n\n /**\n * Responder System logic\n */\n\n let eventPaths: any = getResponderPaths(domEvent)\n let wasNegotiated = false\n let wantsResponder\n\n // If an event occured that might change the current responder...\n if (isStartEvent || isMoveEvent || (isScrollEvent && trackedTouchCount > 0)) {\n // If there is already a responder, prune the event paths to the lowest common ancestor\n // of the existing responder and deepest target of the event.\n const currentResponderIdPath = currentResponder.idPath\n const eventIdPath = eventPaths.idPath\n\n if (currentResponderIdPath != null && eventIdPath != null) {\n const lowestCommonAncestor = getLowestCommonAncestor(\n currentResponderIdPath,\n eventIdPath\n )\n if (lowestCommonAncestor != null) {\n const indexOfLowestCommonAncestor = eventIdPath.indexOf(lowestCommonAncestor)\n // Skip the current responder so it doesn't receive unexpected \"shouldSet\" events.\n const index =\n indexOfLowestCommonAncestor +\n (lowestCommonAncestor === currentResponder.id ? 1 : 0)\n eventPaths = {\n idPath: eventIdPath.slice(index),\n nodePath: eventPaths.nodePath.slice(index),\n }\n } else {\n eventPaths = null\n }\n }\n\n if (eventPaths != null) {\n // If a node wants to become the responder, attempt to transfer.\n wantsResponder = findWantsResponder(eventPaths, domEvent, responderEvent)\n if (wantsResponder != null) {\n // Sets responder if none exists, or negotates with existing responder.\n attemptTransfer(responderEvent, wantsResponder)\n wasNegotiated = true\n }\n }\n }\n\n // If there is now a responder, invoke its callbacks for the lifecycle of the gesture.\n if (currentResponder.id != null && currentResponder.node != null) {\n const { id, node } = currentResponder\n const {\n onResponderStart,\n onResponderMove,\n onResponderEnd,\n onResponderRelease,\n onResponderTerminate,\n onResponderTerminationRequest,\n } = getResponderConfig(id)\n\n responderEvent.bubbles = false\n responderEvent.cancelable = false\n responderEvent.currentTarget = node\n\n // Start\n if (isStartEvent) {\n if (onResponderStart != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderStart'\n onResponderStart(responderEvent)\n }\n }\n // Move\n else if (isMoveEvent) {\n if (onResponderMove != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderMove'\n onResponderMove(responderEvent)\n }\n } else {\n const isTerminateEvent =\n isCancelish(eventType) ||\n // native context menu\n eventType === 'contextmenu' ||\n // window blur\n (eventType === 'blur' && eventTarget === window) ||\n // responder (or ancestors) blur\n (eventType === 'blur' &&\n eventTarget.contains(node) &&\n domEvent.relatedTarget !== node) ||\n // native scroll without using a pointer\n (isScrollEvent && trackedTouchCount === 0) ||\n // native scroll on node that is parent of the responder (allow siblings to scroll)\n (isScrollEvent && eventTarget.contains(node) && eventTarget !== node) ||\n // native select/selectionchange on node\n (isSelectionChangeEvent && hasValidSelection(domEvent))\n\n const isReleaseEvent =\n isEndEvent && !isTerminateEvent && !hasTargetTouches(node, domEvent.touches)\n\n // End\n if (isEndEvent) {\n if (onResponderEnd != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderEnd'\n onResponderEnd(responderEvent)\n }\n }\n // Release\n if (isReleaseEvent) {\n if (onResponderRelease != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderRelease'\n onResponderRelease(responderEvent)\n }\n changeCurrentResponder(emptyResponder)\n }\n // Terminate\n if (isTerminateEvent) {\n let shouldTerminate = true\n\n // Responders can still avoid termination but only for these events.\n if (\n eventType === 'contextmenu' ||\n eventType === 'scroll' ||\n eventType === 'selectionchange'\n ) {\n // Only call this function is it wasn't already called during negotiation.\n if (wasNegotiated) {\n shouldTerminate = false\n } else if (onResponderTerminationRequest != null) {\n responderEvent.dispatchConfig.registrationName =\n 'onResponderTerminationRequest'\n if (onResponderTerminationRequest(responderEvent) === false) {\n shouldTerminate = false\n }\n }\n }\n\n if (shouldTerminate) {\n if (onResponderTerminate != null) {\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminate'\n onResponderTerminate(responderEvent)\n }\n changeCurrentResponder(emptyResponder)\n isEmulatingMouseEvents = false\n trackedTouchCount = 0\n }\n }\n }\n }\n}\n\n/**\n * Walk the event path to/from the target node. At each node, stop and call the\n * relevant \"shouldSet\" functions for the given event type. If any of those functions\n * call \"stopPropagation\" on the event, stop searching for a responder.\n */\nfunction findWantsResponder(eventPaths, domEvent, responderEvent) {\n const shouldSetCallbacks = shouldSetResponderEvents[domEvent.type as any] // for Flow\n\n if (shouldSetCallbacks != null) {\n const { idPath, nodePath } = eventPaths\n\n const shouldSetCallbackCaptureName = shouldSetCallbacks[0]\n const shouldSetCallbackBubbleName = shouldSetCallbacks[1]\n const { bubbles } = shouldSetCallbacks[2]\n\n const check = function (id, node, callbackName) {\n const config = getResponderConfig(id)\n const shouldSetCallback = config[callbackName]\n if (shouldSetCallback != null) {\n responderEvent.currentTarget = node\n if (shouldSetCallback(responderEvent) === true) {\n // Start the path from the potential responder\n const prunedIdPath = idPath.slice(idPath.indexOf(id))\n return { id, node, idPath: prunedIdPath }\n }\n }\n }\n\n // capture\n for (let i = idPath.length - 1; i >= 0; i--) {\n const id = idPath[i]\n const node = nodePath[i]\n const result = check(id, node, shouldSetCallbackCaptureName)\n if (result != null) {\n return result\n }\n if (responderEvent.isPropagationStopped() === true) {\n return\n }\n }\n\n // bubble\n if (bubbles) {\n for (let i = 0; i < idPath.length; i++) {\n const id = idPath[i]\n const node = nodePath[i]\n const result = check(id, node, shouldSetCallbackBubbleName)\n if (result != null) {\n return result\n }\n if (responderEvent.isPropagationStopped() === true) {\n return\n }\n }\n } else {\n const id = idPath[0]\n const node = nodePath[0]\n const target = domEvent.target\n if (target === node) {\n return check(id, node, shouldSetCallbackBubbleName)\n }\n }\n }\n}\n\n/**\n * Attempt to transfer the responder.\n */\nfunction attemptTransfer(\n responderEvent: ResponderEvent,\n wantsResponder: ActiveResponderInstance\n) {\n const { id: currentId, node: currentNode } = currentResponder\n const { id, node } = wantsResponder\n\n const { onResponderGrant, onResponderReject } = getResponderConfig(id)\n\n responderEvent.bubbles = false\n responderEvent.cancelable = false\n responderEvent.currentTarget = node\n\n // Set responder\n if (currentId == null) {\n if (onResponderGrant != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderGrant'\n onResponderGrant(responderEvent)\n }\n changeCurrentResponder(wantsResponder)\n }\n // Negotiate with current responder\n else {\n const { onResponderTerminate, onResponderTerminationRequest } =\n getResponderConfig(currentId)\n\n let allowTransfer = true\n if (onResponderTerminationRequest != null) {\n responderEvent.currentTarget = currentNode\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminationRequest'\n if (onResponderTerminationRequest(responderEvent) === false) {\n allowTransfer = false\n }\n }\n\n if (allowTransfer) {\n // Terminate existing responder\n if (onResponderTerminate != null) {\n responderEvent.currentTarget = currentNode\n responderEvent.dispatchConfig.registrationName = 'onResponderTerminate'\n onResponderTerminate(responderEvent)\n }\n // Grant next responder\n if (onResponderGrant != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderGrant'\n onResponderGrant(responderEvent)\n }\n changeCurrentResponder(wantsResponder)\n } else {\n // Reject responder request\n if (onResponderReject != null) {\n responderEvent.currentTarget = node\n responderEvent.dispatchConfig.registrationName = 'onResponderReject'\n onResponderReject(responderEvent)\n }\n }\n }\n}\n\n/* ------------ PUBLIC API ------------ */\n\n/**\n * Attach Listeners\n *\n * Use native events as ReactDOM doesn't have a non-plugin API to implement\n * this system.\n */\nconst documentEventsCapturePhase = ['blur', 'scroll']\nconst documentEventsBubblePhase = [\n // mouse\n 'mousedown',\n 'mousemove',\n 'mouseup',\n 'dragstart',\n // touch\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'touchcancel',\n // other\n 'contextmenu',\n 'select',\n 'selectionchange',\n]\n\nconst isTamaguiResponderActive = Symbol()\n\nexport function attachListeners() {\n if (canUseDOM && !window[isTamaguiResponderActive]) {\n window.addEventListener('blur', eventListener)\n documentEventsBubblePhase.forEach((eventType) => {\n document.addEventListener(eventType, eventListener)\n })\n documentEventsCapturePhase.forEach((eventType) => {\n document.addEventListener(eventType, eventListener, true)\n })\n window[isTamaguiResponderActive] = true\n }\n}\n\n/**\n * Register a node with the ResponderSystem.\n */\nexport function addNode(id: ResponderId, node: any, config: ResponderConfig) {\n setResponderId(node, id)\n responderListenersMap.set(id, config)\n}\n\n/**\n * Unregister a node with the ResponderSystem.\n */\nexport function removeNode(id: ResponderId) {\n if (currentResponder.id === id) {\n terminateResponder()\n }\n if (responderListenersMap.has(id)) {\n responderListenersMap.delete(id)\n }\n}\n\n/**\n * Allow the current responder to be terminated from within components to support\n * more complex requirements, such as use with other React libraries for working\n * with scroll views, input views, etc.\n */\nexport function terminateResponder() {\n const { id, node } = currentResponder\n if (id != null && node != null) {\n const { onResponderTerminate } = getResponderConfig(id)\n if (onResponderTerminate != null) {\n const event = createResponderEvent({}, responderTouchHistoryStore)\n event.currentTarget = node\n onResponderTerminate(event)\n }\n changeCurrentResponder(emptyResponder)\n }\n isEmulatingMouseEvents = false\n trackedTouchCount = 0\n}\n\n/**\n * Allow unit tests to inspect the current responder in the system.\n * FOR TESTING ONLY.\n */\nexport function getResponderNode(): any {\n return currentResponder.node\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/react-native-use-responder-events",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"types": "./types/index.d.ts",
|
|
5
5
|
"main": "dist/cjs",
|
|
6
6
|
"module": "dist/esm",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"react": "^18.2.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@tamagui/build": "^1.0.
|
|
24
|
+
"@tamagui/build": "^1.0.2",
|
|
25
25
|
"@types/react": "^18.0.15"
|
|
26
26
|
},
|
|
27
27
|
"publishConfig": {
|
package/src/ResponderSystem.ts
CHANGED
|
@@ -64,9 +64,7 @@ export type ResponderConfig = {
|
|
|
64
64
|
onScrollShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null
|
|
65
65
|
// On text selection change, should this element become the responder?
|
|
66
66
|
onSelectionChangeShouldSetResponder?: ((e: ResponderEvent) => boolean) | null
|
|
67
|
-
onSelectionChangeShouldSetResponderCapture?:
|
|
68
|
-
| ((e: ResponderEvent) => boolean)
|
|
69
|
-
| null
|
|
67
|
+
onSelectionChangeShouldSetResponderCapture?: ((e: ResponderEvent) => boolean) | null
|
|
70
68
|
}
|
|
71
69
|
|
|
72
70
|
const emptyObject = {}
|
|
@@ -187,7 +185,7 @@ function eventListener(domEvent: any) {
|
|
|
187
185
|
}
|
|
188
186
|
responderTouchHistoryStore.recordTouchTrack(
|
|
189
187
|
eventType,
|
|
190
|
-
responderEvent.nativeEvent as any
|
|
188
|
+
responderEvent.nativeEvent as any
|
|
191
189
|
)
|
|
192
190
|
}
|
|
193
191
|
|
|
@@ -209,7 +207,7 @@ function eventListener(domEvent: any) {
|
|
|
209
207
|
if (currentResponderIdPath != null && eventIdPath != null) {
|
|
210
208
|
const lowestCommonAncestor = getLowestCommonAncestor(
|
|
211
209
|
currentResponderIdPath,
|
|
212
|
-
eventIdPath
|
|
210
|
+
eventIdPath
|
|
213
211
|
)
|
|
214
212
|
if (lowestCommonAncestor != null) {
|
|
215
213
|
const indexOfLowestCommonAncestor = eventIdPath.indexOf(lowestCommonAncestor)
|
|
@@ -408,7 +406,7 @@ function findWantsResponder(eventPaths, domEvent, responderEvent) {
|
|
|
408
406
|
*/
|
|
409
407
|
function attemptTransfer(
|
|
410
408
|
responderEvent: ResponderEvent,
|
|
411
|
-
wantsResponder: ActiveResponderInstance
|
|
409
|
+
wantsResponder: ActiveResponderInstance
|
|
412
410
|
) {
|
|
413
411
|
const { id: currentId, node: currentNode } = currentResponder
|
|
414
412
|
const { id, node } = wantsResponder
|
|
@@ -436,8 +434,7 @@ function attemptTransfer(
|
|
|
436
434
|
let allowTransfer = true
|
|
437
435
|
if (onResponderTerminationRequest != null) {
|
|
438
436
|
responderEvent.currentTarget = currentNode
|
|
439
|
-
responderEvent.dispatchConfig.registrationName =
|
|
440
|
-
'onResponderTerminationRequest'
|
|
437
|
+
responderEvent.dispatchConfig.registrationName = 'onResponderTerminationRequest'
|
|
441
438
|
if (onResponderTerminationRequest(responderEvent) === false) {
|
|
442
439
|
allowTransfer = false
|
|
443
440
|
}
|
|
@@ -493,8 +490,11 @@ const documentEventsBubblePhase = [
|
|
|
493
490
|
'select',
|
|
494
491
|
'selectionchange',
|
|
495
492
|
]
|
|
493
|
+
|
|
494
|
+
const isTamaguiResponderActive = Symbol()
|
|
495
|
+
|
|
496
496
|
export function attachListeners() {
|
|
497
|
-
if (canUseDOM && !window[
|
|
497
|
+
if (canUseDOM && !window[isTamaguiResponderActive]) {
|
|
498
498
|
window.addEventListener('blur', eventListener)
|
|
499
499
|
documentEventsBubblePhase.forEach((eventType) => {
|
|
500
500
|
document.addEventListener(eventType, eventListener)
|
|
@@ -502,7 +502,7 @@ export function attachListeners() {
|
|
|
502
502
|
documentEventsCapturePhase.forEach((eventType) => {
|
|
503
503
|
document.addEventListener(eventType, eventListener, true)
|
|
504
504
|
})
|
|
505
|
-
window[
|
|
505
|
+
window[isTamaguiResponderActive] = true
|
|
506
506
|
}
|
|
507
507
|
}
|
|
508
508
|
|