UNPKG

3.94 kBJavaScriptView Raw
1import * as DomEvent from './DomEvent';
2import * as Util from '../core/Util';
3import * as Browser from '../core/Browser';
4
5/*
6 * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices.
7 */
8
9
10var POINTER_DOWN = Browser.msPointer ? 'MSPointerDown' : 'pointerdown';
11var POINTER_MOVE = Browser.msPointer ? 'MSPointerMove' : 'pointermove';
12var POINTER_UP = Browser.msPointer ? 'MSPointerUp' : 'pointerup';
13var POINTER_CANCEL = Browser.msPointer ? 'MSPointerCancel' : 'pointercancel';
14var TAG_WHITE_LIST = ['INPUT', 'SELECT', 'OPTION'];
15
16var _pointers = {};
17var _pointerDocListener = false;
18
19// DomEvent.DoubleTap needs to know about this
20export var _pointersCount = 0;
21
22// Provides a touch events wrapper for (ms)pointer events.
23// ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890
24
25export function addPointerListener(obj, type, handler, id) {
26 if (type === 'touchstart') {
27 _addPointerStart(obj, handler, id);
28
29 } else if (type === 'touchmove') {
30 _addPointerMove(obj, handler, id);
31
32 } else if (type === 'touchend') {
33 _addPointerEnd(obj, handler, id);
34 }
35
36 return this;
37}
38
39export function removePointerListener(obj, type, id) {
40 var handler = obj['_leaflet_' + type + id];
41
42 if (type === 'touchstart') {
43 obj.removeEventListener(POINTER_DOWN, handler, false);
44
45 } else if (type === 'touchmove') {
46 obj.removeEventListener(POINTER_MOVE, handler, false);
47
48 } else if (type === 'touchend') {
49 obj.removeEventListener(POINTER_UP, handler, false);
50 obj.removeEventListener(POINTER_CANCEL, handler, false);
51 }
52
53 return this;
54}
55
56function _addPointerStart(obj, handler, id) {
57 var onDown = Util.bind(function (e) {
58 if (e.pointerType !== 'mouse' && e.MSPOINTER_TYPE_MOUSE && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
59 // In IE11, some touch events needs to fire for form controls, or
60 // the controls will stop working. We keep a whitelist of tag names that
61 // need these events. For other target tags, we prevent default on the event.
62 if (TAG_WHITE_LIST.indexOf(e.target.tagName) < 0) {
63 DomEvent.preventDefault(e);
64 } else {
65 return;
66 }
67 }
68
69 _handlePointer(e, handler);
70 });
71
72 obj['_leaflet_touchstart' + id] = onDown;
73 obj.addEventListener(POINTER_DOWN, onDown, false);
74
75 // need to keep track of what pointers and how many are active to provide e.touches emulation
76 if (!_pointerDocListener) {
77 // we listen documentElement as any drags that end by moving the touch off the screen get fired there
78 document.documentElement.addEventListener(POINTER_DOWN, _globalPointerDown, true);
79 document.documentElement.addEventListener(POINTER_MOVE, _globalPointerMove, true);
80 document.documentElement.addEventListener(POINTER_UP, _globalPointerUp, true);
81 document.documentElement.addEventListener(POINTER_CANCEL, _globalPointerUp, true);
82
83 _pointerDocListener = true;
84 }
85}
86
87function _globalPointerDown(e) {
88 _pointers[e.pointerId] = e;
89 _pointersCount++;
90}
91
92function _globalPointerMove(e) {
93 if (_pointers[e.pointerId]) {
94 _pointers[e.pointerId] = e;
95 }
96}
97
98function _globalPointerUp(e) {
99 delete _pointers[e.pointerId];
100 _pointersCount--;
101}
102
103function _handlePointer(e, handler) {
104 e.touches = [];
105 for (var i in _pointers) {
106 e.touches.push(_pointers[i]);
107 }
108 e.changedTouches = [e];
109
110 handler(e);
111}
112
113function _addPointerMove(obj, handler, id) {
114 var onMove = function (e) {
115 // don't fire touch moves when mouse isn't down
116 if ((e.pointerType === e.MSPOINTER_TYPE_MOUSE || e.pointerType === 'mouse') && e.buttons === 0) { return; }
117
118 _handlePointer(e, handler);
119 };
120
121 obj['_leaflet_touchmove' + id] = onMove;
122 obj.addEventListener(POINTER_MOVE, onMove, false);
123}
124
125function _addPointerEnd(obj, handler, id) {
126 var onUp = function (e) {
127 _handlePointer(e, handler);
128 };
129
130 obj['_leaflet_touchend' + id] = onUp;
131 obj.addEventListener(POINTER_UP, onUp, false);
132 obj.addEventListener(POINTER_CANCEL, onUp, false);
133}
134