UNPKG

@ionic/core

Version:
124 lines (123 loc) 3.74 kB
/*! * (C) Ionic http://ionicframework.com - MIT License */ import { addEventListener } from "./listener"; const MOUSE_WAIT = 2000; // TODO(FW-2832): types export const createPointerEvents = (el, pointerDown, pointerMove, pointerUp, options) => { let rmTouchStart; let rmTouchMove; let rmTouchEnd; let rmTouchCancel; let rmMouseStart; let rmMouseMove; let rmMouseUp; let lastTouchEvent = 0; const handleTouchStart = (ev) => { lastTouchEvent = Date.now() + MOUSE_WAIT; if (!pointerDown(ev)) { return; } if (!rmTouchMove && pointerMove) { rmTouchMove = addEventListener(el, 'touchmove', pointerMove, options); } /** * Events are dispatched on the element that is tapped and bubble up to * the reference element in the gesture. In the event that the element this * event was first dispatched on is removed from the DOM, the event will no * longer bubble up to our reference element. This leaves the gesture in an * unusable state. To account for this, the touchend and touchcancel listeners * should be added to the event target so that they still fire even if the target * is removed from the DOM. */ if (!rmTouchEnd) { rmTouchEnd = addEventListener(ev.target, 'touchend', handleTouchEnd, options); } if (!rmTouchCancel) { rmTouchCancel = addEventListener(ev.target, 'touchcancel', handleTouchEnd, options); } }; const handleMouseDown = (ev) => { if (lastTouchEvent > Date.now()) { return; } if (!pointerDown(ev)) { return; } if (!rmMouseMove && pointerMove) { rmMouseMove = addEventListener(getDocument(el), 'mousemove', pointerMove, options); } if (!rmMouseUp) { rmMouseUp = addEventListener(getDocument(el), 'mouseup', handleMouseUp, options); } }; const handleTouchEnd = (ev) => { stopTouch(); if (pointerUp) { pointerUp(ev); } }; const handleMouseUp = (ev) => { stopMouse(); if (pointerUp) { pointerUp(ev); } }; const stopTouch = () => { if (rmTouchMove) { rmTouchMove(); } if (rmTouchEnd) { rmTouchEnd(); } if (rmTouchCancel) { rmTouchCancel(); } rmTouchMove = rmTouchEnd = rmTouchCancel = undefined; }; const stopMouse = () => { if (rmMouseMove) { rmMouseMove(); } if (rmMouseUp) { rmMouseUp(); } rmMouseMove = rmMouseUp = undefined; }; const stop = () => { stopTouch(); stopMouse(); }; const enable = (isEnabled = true) => { if (!isEnabled) { if (rmTouchStart) { rmTouchStart(); } if (rmMouseStart) { rmMouseStart(); } rmTouchStart = rmMouseStart = undefined; stop(); } else { if (!rmTouchStart) { rmTouchStart = addEventListener(el, 'touchstart', handleTouchStart, options); } if (!rmMouseStart) { rmMouseStart = addEventListener(el, 'mousedown', handleMouseDown, options); } } }; const destroy = () => { enable(false); pointerUp = pointerMove = pointerDown = undefined; }; return { enable, stop, destroy, }; }; const getDocument = (node) => { return node instanceof Document ? node : node.ownerDocument; };