import * as DomEvent from './DomEvent'; import * as Util from '../core/Util'; import * as Browser from '../core/Browser'; /* * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices. */ var POINTER_DOWN = Browser.msPointer ? 'MSPointerDown' : 'pointerdown'; var POINTER_MOVE = Browser.msPointer ? 'MSPointerMove' : 'pointermove'; var POINTER_UP = Browser.msPointer ? 'MSPointerUp' : 'pointerup'; var POINTER_CANCEL = Browser.msPointer ? 'MSPointerCancel' : 'pointercancel'; var TAG_WHITE_LIST = ['INPUT', 'SELECT', 'OPTION']; var _pointers = {}; var _pointerDocListener = false; // DomEvent.DoubleTap needs to know about this export var _pointersCount = 0; // Provides a touch events wrapper for (ms)pointer events. // ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890 export function addPointerListener(obj, type, handler, id) { if (type === 'touchstart') { _addPointerStart(obj, handler, id); } else if (type === 'touchmove') { _addPointerMove(obj, handler, id); } else if (type === 'touchend') { _addPointerEnd(obj, handler, id); } return this; } export function removePointerListener(obj, type, id) { var handler = obj['_leaflet_' + type + id]; if (type === 'touchstart') { obj.removeEventListener(POINTER_DOWN, handler, false); } else if (type === 'touchmove') { obj.removeEventListener(POINTER_MOVE, handler, false); } else if (type === 'touchend') { obj.removeEventListener(POINTER_UP, handler, false); obj.removeEventListener(POINTER_CANCEL, handler, false); } return this; } function _addPointerStart(obj, handler, id) { var onDown = Util.bind(function (e) { if (e.pointerType !== 'mouse' && e.MSPOINTER_TYPE_MOUSE && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) { // In IE11, some touch events needs to fire for form controls, or // the controls will stop working. We keep a whitelist of tag names that // need these events. For other target tags, we prevent default on the event. if (TAG_WHITE_LIST.indexOf(e.target.tagName) < 0) { DomEvent.preventDefault(e); } else { return; } } _handlePointer(e, handler); }); obj['_leaflet_touchstart' + id] = onDown; obj.addEventListener(POINTER_DOWN, onDown, false); // need to keep track of what pointers and how many are active to provide e.touches emulation if (!_pointerDocListener) { // we listen documentElement as any drags that end by moving the touch off the screen get fired there document.documentElement.addEventListener(POINTER_DOWN, _globalPointerDown, true); document.documentElement.addEventListener(POINTER_MOVE, _globalPointerMove, true); document.documentElement.addEventListener(POINTER_UP, _globalPointerUp, true); document.documentElement.addEventListener(POINTER_CANCEL, _globalPointerUp, true); _pointerDocListener = true; } } function _globalPointerDown(e) { _pointers[e.pointerId] = e; _pointersCount++; } function _globalPointerMove(e) { if (_pointers[e.pointerId]) { _pointers[e.pointerId] = e; } } function _globalPointerUp(e) { delete _pointers[e.pointerId]; _pointersCount--; } function _handlePointer(e, handler) { e.touches = []; for (var i in _pointers) { e.touches.push(_pointers[i]); } e.changedTouches = [e]; handler(e); } function _addPointerMove(obj, handler, id) { var onMove = function (e) { // don't fire touch moves when mouse isn't down if ((e.pointerType === e.MSPOINTER_TYPE_MOUSE || e.pointerType === 'mouse') && e.buttons === 0) { return; } _handlePointer(e, handler); }; obj['_leaflet_touchmove' + id] = onMove; obj.addEventListener(POINTER_MOVE, onMove, false); } function _addPointerEnd(obj, handler, id) { var onUp = function (e) { _handlePointer(e, handler); }; obj['_leaflet_touchend' + id] = onUp; obj.addEventListener(POINTER_UP, onUp, false); obj.addEventListener(POINTER_CANCEL, onUp, false); }