diff --git a/src/dom/DomEvent.Pointer.js b/src/dom/DomEvent.Pointer.js index 4957fcd1..824ecc3b 100644 --- a/src/dom/DomEvent.Pointer.js +++ b/src/dom/DomEvent.Pointer.js @@ -4,152 +4,104 @@ L.extend(L.DomEvent, { - //static - POINTER_DOWN: L.Browser.msPointer ? 'MSPointerDown' : 'pointerdown', - POINTER_MOVE: L.Browser.msPointer ? 'MSPointerMove' : 'pointermove', - POINTER_UP: L.Browser.msPointer ? 'MSPointerUp' : 'pointerup', + POINTER_DOWN: L.Browser.msPointer ? 'MSPointerDown' : 'pointerdown', + POINTER_MOVE: L.Browser.msPointer ? 'MSPointerMove' : 'pointermove', + POINTER_UP: L.Browser.msPointer ? 'MSPointerUp' : 'pointerup', POINTER_CANCEL: L.Browser.msPointer ? 'MSPointerCancel' : 'pointercancel', - _pointers: [], - _pointerDocumentListener: false, + _pointers: {}, // Provides a touch events wrapper for (ms)pointer events. - // Based on changes by veproza https://github.com/CloudMade/Leaflet/pull/1019 - //ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890 + // ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890 addPointerListener: function (obj, type, handler, id) { - switch (type) { - case 'touchstart': - return this.addPointerListenerStart(obj, type, handler, id); - case 'touchend': - return this.addPointerListenerEnd(obj, type, handler, id); - case 'touchmove': - return this.addPointerListenerMove(obj, type, handler, id); - default: - throw 'Unknown touch event type'; + if (type === 'touchstart') { + this._addPointerStart(obj, handler, id); + + } else if (type === 'touchmove') { + this._addPointerMove(obj, handler, id); + + } else if (type === 'touchend') { + this._addPointerEnd(obj, handler, id); } - }, - - addPointerListenerStart: function (obj, type, handler, id) { - var pre = '_leaflet_', - pointers = this._pointers; - - var cb = function (e) { - - L.DomEvent.preventDefault(e); - - var alreadyInArray = false; - for (var i = 0; i < pointers.length; i++) { - if (pointers[i].pointerId === e.pointerId) { - alreadyInArray = true; - break; - } - } - if (!alreadyInArray) { - pointers.push(e); - } - - e.touches = pointers.slice(); - e.changedTouches = [e]; - - handler(e); - }; - - obj[pre + 'touchstart' + id] = cb; - obj.addEventListener(this.POINTER_DOWN, cb, false); - - // need to also listen for end events to keep the _pointers list accurate - // this needs to be on the body and never go away - if (!this._pointerDocumentListener) { - var internalCb = function (e) { - for (var i = 0; i < pointers.length; i++) { - if (pointers[i].pointerId === e.pointerId) { - pointers.splice(i, 1); - break; - } - } - }; - //We listen on the documentElement as any drags that end by moving the touch off the screen get fired there - document.documentElement.addEventListener(this.POINTER_UP, internalCb, false); - document.documentElement.addEventListener(this.POINTER_CANCEL, internalCb, false); - - this._pointerDocumentListener = true; - } - - return this; - }, - - addPointerListenerMove: function (obj, type, handler, id) { - var pre = '_leaflet_', - touches = this._pointers; - - function cb(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; } - - for (var i = 0; i < touches.length; i++) { - if (touches[i].pointerId === e.pointerId) { - touches[i] = e; - break; - } - } - - e.touches = touches.slice(); - e.changedTouches = [e]; - - handler(e); - } - - obj[pre + 'touchmove' + id] = cb; - obj.addEventListener(this.POINTER_MOVE, cb, false); - - return this; - }, - - addPointerListenerEnd: function (obj, type, handler, id) { - var pre = '_leaflet_', - touches = this._pointers; - - var cb = function (e) { - for (var i = 0; i < touches.length; i++) { - if (touches[i].pointerId === e.pointerId) { - touches.splice(i, 1); - break; - } - } - - e.touches = touches.slice(); - e.changedTouches = [e]; - - handler(e); - }; - - obj[pre + 'touchend' + id] = cb; - obj.addEventListener(this.POINTER_UP, cb, false); - obj.addEventListener(this.POINTER_CANCEL, cb, false); return this; }, removePointerListener: function (obj, type, id) { - var pre = '_leaflet_', - cb = obj[pre + type + id]; + var handler = obj['_leaflet_' + type + id]; - switch (type) { - case 'touchstart': - obj.removeEventListener(this.POINTER_DOWN, cb, false); - break; - case 'touchmove': - obj.removeEventListener(this.POINTER_MOVE, cb, false); - break; - case 'touchend': - obj.removeEventListener(this.POINTER_UP, cb, false); - obj.removeEventListener(this.POINTER_CANCEL, cb, false); - break; + if (type === 'touchstart') { + obj.removeEventListener(this.POINTER_DOWN, handler, false); + + } else if (type === 'touchmove') { + obj.removeEventListener(this.POINTER_MOVE, handler, false); + + } else if (type === 'touchend') { + obj.removeEventListener(this.POINTER_UP, handler, false); + obj.removeEventListener(this.POINTER_CANCEL, handler, false); } return this; + }, + + _addPointerStart: function (obj, handler, id) { + var onDown = L.bind(function (e) { + L.DomEvent.preventDefault(e); + + this._pointers[e.pointerId] = e; + this._handlePointer(e, handler); + }, this); + + obj['_leaflet_touchstart' + id] = onDown; + obj.addEventListener(this.POINTER_DOWN, onDown, false); + + // need to also listen for end events to keep the _pointers object accurate + if (!this._pointerDocListener) { + var removePointer = L.bind(function (e) { + delete this._pointers[e.pointerId]; + }, this); + + // we listen documentElement as any drags that end by moving the touch off the screen get fired there + document.documentElement.addEventListener(this.POINTER_UP, removePointer, false); + document.documentElement.addEventListener(this.POINTER_CANCEL, removePointer, false); + + this._pointerDocListener = true; + } + }, + + _handlePointer: function (e, handler) { + e.touches = []; + for (var i in this._pointers) { + e.touches.push(this._pointers[i]); + } + e.changedTouches = [e]; + + handler(e); + }, + + _addPointerMove: function (obj, handler, id) { + var onMove = L.bind(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; } + + this._pointers[e.pointerId] = e; + this._handlePointer(e, handler); + }, this); + + obj['_leaflet_touchmove' + id] = onMove; + obj.addEventListener(this.POINTER_MOVE, onMove, false); + }, + + _addPointerEnd: function (obj, handler, id) { + var onUp = L.bind(function (e) { + delete this._pointers[e.pointerId]; + this._handlePointer(e, handler); + }, this); + + obj['_leaflet_touchend' + id] = onUp; + obj.addEventListener(this.POINTER_UP, onUp, false); + obj.addEventListener(this.POINTER_CANCEL, onUp, false); } });