Skip to content
This repository has been archived by the owner on Apr 12, 2022. It is now read-only.

Commit

Permalink
reapply mapbox#6248 and mapbox#6450
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvoll committed Apr 23, 2018
1 parent 2a1156a commit 5b43a1a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 24 deletions.
28 changes: 17 additions & 11 deletions src/ui/bind_handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,23 @@ module.exports = function bindHandlers(map: Map, options: {}) {
}
}

el.addEventListener('mouseout', onMouseOut, false);
el.addEventListener('mousedown', onMouseDown, false);
el.addEventListener('mouseup', onMouseUp, false);
el.addEventListener('mousemove', onMouseMove, false);
el.addEventListener('touchstart', onTouchStart, false);
el.addEventListener('touchend', onTouchEnd, false);
el.addEventListener('touchmove', onTouchMove, false);
el.addEventListener('touchcancel', onTouchCancel, false);
el.addEventListener('click', onClick, false);
el.addEventListener('dblclick', onDblClick, false);
el.addEventListener('contextmenu', onContextMenu, false);
DOM.addEventListener(el, 'mouseout', onMouseOut);
DOM.addEventListener(el, 'mousedown', onMouseDown);
DOM.addEventListener(el, 'mouseup', onMouseUp);
DOM.addEventListener(el, 'mousemove', onMouseMove);

// Bind touchstart and touchmove with passive: false because, even though
// they only fire a map events and therefore could theoretically be
// passive, binding with passive: true causes iOS not to respect
// e.preventDefault() in _other_ handlers, even if they are non-passive
// (see https://bugs.webkit.org/show_bug.cgi?id=184251)
DOM.addEventListener(el, 'touchstart', onTouchStart, {passive: false});
DOM.addEventListener(el, 'touchmove', onTouchMove, {passive: false});
DOM.addEventListener(el, 'touchend', onTouchEnd);
DOM.addEventListener(el, 'touchcancel', onTouchCancel);
DOM.addEventListener(el, 'click', onClick);
DOM.addEventListener(el, 'dblclick', onDblClick);
DOM.addEventListener(el, 'contextmenu', onContextMenu);

function onMouseOut(e: MouseEvent) {
fireMouseEvent('mouseout', e);
Expand Down
18 changes: 9 additions & 9 deletions src/ui/handler/drag_pan.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ class DragPanHandler {
if (this.isActive()) return;

if (e.touches) {
window.document.addEventListener('touchmove', this._onMove);
window.document.addEventListener('touchend', this._onTouchEnd);
DOM.addEventListener(window.document, 'touchmove', this._onMove, {capture: true});
DOM.addEventListener(window.document, 'touchend', this._onTouchEnd);
} else {
window.document.addEventListener('mousemove', this._onMove);
window.document.addEventListener('mouseup', this._onMouseUp);
DOM.addEventListener(window.document, 'mousemove', this._onMove, {capture: true, passive: false});
DOM.addEventListener(window.document, 'mouseup', this._onMouseUp);
}
/* Deactivate DragPan when the window looses focus. Otherwise if a mouseup occurs when the window isn't in focus, DragPan will still be active even though the mouse is no longer pressed. */
window.addEventListener('blur', this._onMouseUp);
Expand Down Expand Up @@ -183,16 +183,16 @@ class DragPanHandler {
_onMouseUp(e: MouseEvent | FocusEvent) {
if (this._ignoreEvent(e)) return;
this._onUp(e);
window.document.removeEventListener('mousemove', this._onMove);
window.document.removeEventListener('mouseup', this._onMouseUp);
window.removeEventListener('blur', this._onMouseUp);
DOM.removeEventListener(window.document, 'mousemove', this._onMove, {capture: true});
DOM.removeEventListener(window.document, 'mouseup', this._onMouseUp);
DOM.removeEventListener(window, 'blur', this._onMouseUp);
}

_onTouchEnd(e: TouchEvent) {
if (this._ignoreEvent(e)) return;
this._onUp(e);
window.document.removeEventListener('touchmove', this._onMove);
window.document.removeEventListener('touchend', this._onTouchEnd);
DOM.removeEventListener(window.document, 'touchmove', this._onMove, {capture: true, passive: false});
DOM.removeEventListener(window.document, 'touchend', this._onTouchEnd);
}

_fireEvent(type: string, e: Event) {
Expand Down
8 changes: 4 additions & 4 deletions src/ui/handler/touch_zoom_rotate.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ class TouchZoomRotateHandler {
this._gestureIntent = undefined;
this._inertia = [];

window.document.addEventListener('touchmove', this._onMove, false);
window.document.addEventListener('touchend', this._onEnd, false);
DOM.addEventListener(window.document, 'touchmove', this._onMove, {passive: false});
DOM.addEventListener(window.document, 'touchend', this._onEnd);
}

_onMove(e: TouchEvent) {
Expand Down Expand Up @@ -173,8 +173,8 @@ class TouchZoomRotateHandler {
}

_onEnd(e: TouchEvent) {
window.document.removeEventListener('touchmove', this._onMove);
window.document.removeEventListener('touchend', this._onEnd);
DOM.removeEventListener(window.document, 'touchmove', this._onMove, {passive: false});
DOM.removeEventListener(window.document, 'touchend', this._onEnd);
this._drainInertiaBuffer();

const inertia = this._inertia,
Expand Down
31 changes: 31 additions & 0 deletions src/util/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,37 @@ exports.setTransform = function(el: HTMLElement, value: string) {
(el.style: any)[transformProp] = value;
};

// Feature detection for {passive: false} support in add/removeEventListener.
let passiveSupported = false;

try {
const options = (Object.defineProperty: any)({}, "passive", {
get: function() {
passiveSupported = true;
}
});
(window.addEventListener: any)("test", options, options);
(window.removeEventListener: any)("test", options, options);
} catch (err) {
passiveSupported = false;
}

exports.addEventListener = function(target: *, type: *, callback: *, options: {passive?: boolean, capture?: boolean} = {}) {
if ('passive' in options && passiveSupported) {
target.addEventListener(type, callback, (options: any));
} else {
target.addEventListener(type, callback, options.capture);
}
};

exports.removeEventListener = function(target: *, type: *, callback: *, options: {passive?: boolean, capture?: boolean} = {}) {
if ('passive' in options && passiveSupported) {
target.removeEventListener(type, callback, (options: any));
} else {
target.removeEventListener(type, callback, options.capture);
}
};

// Suppress the next click, but only if it's immediate.
const suppressClick: MouseEventListener = function (e) {
e.preventDefault();
Expand Down

0 comments on commit 5b43a1a

Please sign in to comment.