significantly clean up DomEvent.Pointer code

This commit is contained in:
Vladimir Agafonkin 2013-12-03 17:46:53 +02:00
parent a0ad7b6c0e
commit db8f888c17

View File

@ -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);
}
});