Code coverage report for src/dom/DomEvent.DoubleTap.js

Statements: 2.17% (1 / 46)      Branches: 6.25% (2 / 32)      Functions: 0% (0 / 4)      Lines: 2.17% (1 / 46)     

All files » src/dom/ » DomEvent.DoubleTap.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97        1                                                                                                                                                                                        
/*
 * Extends the event handling code with double tap support for mobile browsers.
 */
 
L.extend(L.DomEvent, {
 
	_touchstart: L.Browser.msTouch ? 'MSPointerDown' : 'touchstart',
	_touchend: L.Browser.msTouch ? 'MSPointerUp' : 'touchend',
 
	// inspired by Zepto touch code by Thomas Fuchs
	addDoubleTapListener: function (obj, handler, id) {
		var last,
		    doubleTap = false,
		    delay = 250,
		    touch,
		    pre = '_leaflet_',
		    touchstart = this._touchstart,
		    touchend = this._touchend,
		    trackedTouches = [];
 
		function onTouchStart(e) {
			var count;
			if (L.Browser.msTouch) {
				trackedTouches.push(e.pointerId);
				count = trackedTouches.length;
			} else {
				count = e.touches.length;
			}
			if (count > 1) {
				return;
			}
 
			var now = Date.now(),
				delta = now - (last || now);
 
			touch = e.touches ? e.touches[0] : e;
			doubleTap = (delta > 0 && delta <= delay);
			last = now;
		}
 
		function onTouchEnd(e) {
			/*jshint forin:false */
			if (L.Browser.msTouch) {
				var idx = trackedTouches.indexOf(e.pointerId);
				if (idx === -1) {
					return;
				}
				trackedTouches.splice(idx, 1);
			}
 
			if (doubleTap) {
				if (L.Browser.msTouch) {
					//Work around .type being readonly with MSPointer* events
					var newTouch = { },
						prop;
 
					for (var i in touch) {
						prop = touch[i];
						if (typeof prop === 'function') {
							newTouch[i] = prop.bind(touch);
						} else {
							newTouch[i] = prop;
						}
					}
					touch = newTouch;
				}
				touch.type = 'dblclick';
				handler(touch);
				last = null;
			}
		}
		obj[pre + touchstart + id] = onTouchStart;
		obj[pre + touchend + id] = onTouchEnd;
 
		//On msTouch we need to listen on the document otherwise a drag starting on the map and moving off screen will not come through to us
		// so we will lose track of how many touches are ongoing
		var endElement = L.Browser.msTouch ? document.documentElement : obj;
 
		obj.addEventListener(touchstart, onTouchStart, false);
		endElement.addEventListener(touchend, onTouchEnd, false);
		if (L.Browser.msTouch) {
			endElement.addEventListener('MSPointerCancel', onTouchEnd, false);
		}
		return this;
	},
 
	removeDoubleTapListener: function (obj, id) {
		var pre = '_leaflet_';
		obj.removeEventListener(this._touchstart, obj[pre + this._touchstart + id], false);
		(L.Browser.msTouch ? document.documentElement : obj).removeEventListener(this._touchend, obj[pre + this._touchend + id], false);
		if (L.Browser.msTouch) {
			document.documentElement.removeEventListener('MSPointerCancel', obj[pre + this._touchend + id], false);
		}
		return this;
	}
});