Skip to content

Commit

Permalink
fix(gestures): fixes browser quirk with TouchMove events
Browse files Browse the repository at this point in the history
TouchMove events aren't dispatched when target element is removed from
the document. To solve this issue we should detect when target is
detached from the document and reattach it until we don't need touch
move events anymore.
  • Loading branch information
localvoid committed Jun 11, 2018
1 parent d3c4f72 commit 9fedf9e
Showing 1 changed file with 37 additions and 13 deletions.
50 changes: 37 additions & 13 deletions packages/ivi-gestures/src/touch_event_listener.ts
Expand Up @@ -10,13 +10,7 @@ import { NativeEventListener, NativeEventListenerFlags } from "./native_event_li
import { createMouseEventListener } from "./mouse_event_listener";
import { debugPubTouchState } from "./debug";
import { IOS_GESTURE_EVENT } from "./features";

/**
* TODO: make sure that target is always attached to the document, because touch events are always working in capture
* mode and when target is removed, all events just disappear. The trick is to add a special task that is executed
* after frame is updated and checks that target is attached to the document, if it were removed than we just need
* set display:none and reattach it somewhere.
*/
import { beforeUpdate } from "ivi-scheduler";

/**
* id 1 is reserved for mouse, and touch identifiers can start from 0.
Expand Down Expand Up @@ -54,7 +48,9 @@ export function createTouchEventListener(
const mouseListener = createMouseEventListener(dispatch, primaryPointers);

let primaryTouch: Touch | null = null;
let target: EventTarget | null = null;
let currentFlags: NativeEventListenerFlags = 0;
let removeTarget = false;
let preventFirstMove = false;
let moveTrackingEnabled = false;
let eventTimeOffset = 0;
Expand Down Expand Up @@ -133,6 +129,7 @@ export function createTouchEventListener(

if ((pointers.size === 0) || (pointers.size === 1 && pointers.get(1) !== void 0)) {
primaryTouch = touches[0];
target = ev.target;
if (!moveTrackingEnabled && (currentFlags & NativeEventListenerFlags.TrackMove)) {
moveTrackingEnabled = true;
beforeNativeEvent(EVENT_DISPATCHER_ACTIVE_TOUCH_MOVE, onMove);
Expand Down Expand Up @@ -209,9 +206,16 @@ export function createTouchEventListener(
primaryTouch = null;
}
}
if (moveTrackingEnabled && pointers.size === 0) {
moveTrackingEnabled = false;
removeBeforeNativeEvent(EVENT_DISPATCHER_ACTIVE_TOUCH_MOVE, onMove);
if (pointers.size === 0) {
if (removeTarget) {
removeTarget = false;
document.removeChild(target as Element);
}
target = null;
if (moveTrackingEnabled) {
moveTrackingEnabled = false;
removeBeforeNativeEvent(EVENT_DISPATCHER_ACTIVE_TOUCH_MOVE, onMove);
}
}
if (DEBUG) {
debugPubTouchState({ currentFlags, primaryPointers, primaryTouch, eventTimeOffset, moveTrackingEnabled });
Expand All @@ -236,22 +240,42 @@ export function createTouchEventListener(
primaryTouch = null;
}
}
if (moveTrackingEnabled && pointers.size === 0) {
moveTrackingEnabled = false;
removeBeforeNativeEvent(EVENT_DISPATCHER_ACTIVE_TOUCH_MOVE, onMove);
if (pointers.size === 0) {
if (removeTarget) {
removeTarget = false;
document.removeChild(target as Element);
}
target = null;
if (moveTrackingEnabled) {
moveTrackingEnabled = false;
removeBeforeNativeEvent(EVENT_DISPATCHER_ACTIVE_TOUCH_MOVE, onMove);
}
}
if (DEBUG) {
debugPubTouchState({ currentFlags, primaryPointers, primaryTouch, eventTimeOffset, moveTrackingEnabled });
}
}

function onBeforeUpdate() {
if (target !== null) {
if (!document.contains(target as Element)) {
removeTarget = true;
(target as HTMLElement).style.display = "none";
document.appendChild(target as Element);
}
return true;
}
return false;
}

return {
activate: () => {
mouseListener.activate();
// touchstart should be active, otherwise touchmove can't be canceled.
beforeNativeEvent(EVENT_DISPATCHER_ACTIVE_TOUCH_START, onStart);
beforeNativeEvent(EVENT_DISPATCHER_TOUCH_END, onEnd);
beforeNativeEvent(EVENT_DISPATCHER_TOUCH_CANCEL, onCancel);
beforeUpdate(onBeforeUpdate);
/**
* Safari just being safari: https://bugs.webkit.org/show_bug.cgi?id=182521
*/
Expand Down

0 comments on commit 9fedf9e

Please sign in to comment.