mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-10 10:23:40 +01:00
272 lines
7.2 KiB
JavaScript
272 lines
7.2 KiB
JavaScript
L.Map.mergeOptions({
|
|
touchExtend: true
|
|
});
|
|
|
|
/**
|
|
* @class L.Map.TouchExtend
|
|
* @aka TouchExtend
|
|
*/
|
|
L.Map.TouchExtend = L.Handler.extend({
|
|
|
|
// @method initialize(): void
|
|
// Sets TouchExtend private accessor variables
|
|
initialize: function (map) {
|
|
this._map = map;
|
|
this._container = map._container;
|
|
this._pane = map._panes.overlayPane;
|
|
},
|
|
|
|
// @method addHooks(): void
|
|
// Adds dom listener events to the map container
|
|
addHooks: function () {
|
|
L.DomEvent.on(this._container, 'touchstart', this._onTouchStart, this);
|
|
L.DomEvent.on(this._container, 'touchend', this._onTouchEnd, this);
|
|
L.DomEvent.on(this._container, 'touchmove', this._onTouchMove, this);
|
|
if (this._detectIE()) {
|
|
L.DomEvent.on(this._container, 'MSPointerDown', this._onTouchStart, this);
|
|
L.DomEvent.on(this._container, 'MSPointerUp', this._onTouchEnd, this);
|
|
L.DomEvent.on(this._container, 'MSPointerMove', this._onTouchMove, this);
|
|
L.DomEvent.on(this._container, 'MSPointerCancel', this._onTouchCancel, this);
|
|
|
|
} else {
|
|
L.DomEvent.on(this._container, 'touchcancel', this._onTouchCancel, this);
|
|
L.DomEvent.on(this._container, 'touchleave', this._onTouchLeave, this);
|
|
}
|
|
},
|
|
|
|
// @method removeHooks(): void
|
|
// Removes dom listener events from the map container
|
|
removeHooks: function () {
|
|
L.DomEvent.off(this._container, 'touchstart', this._onTouchStart);
|
|
L.DomEvent.off(this._container, 'touchend', this._onTouchEnd);
|
|
L.DomEvent.off(this._container, 'touchmove', this._onTouchMove);
|
|
if (this._detectIE()) {
|
|
L.DomEvent.off(this._container, 'MSPointerDowm', this._onTouchStart);
|
|
L.DomEvent.off(this._container, 'MSPointerUp', this._onTouchEnd);
|
|
L.DomEvent.off(this._container, 'MSPointerMove', this._onTouchMove);
|
|
L.DomEvent.off(this._container, 'MSPointerCancel', this._onTouchCancel);
|
|
} else {
|
|
L.DomEvent.off(this._container, 'touchcancel', this._onTouchCancel);
|
|
L.DomEvent.off(this._container, 'touchleave', this._onTouchLeave);
|
|
}
|
|
},
|
|
|
|
_touchEvent: function (e, type) {
|
|
// #TODO: fix the pageX error that is do a bug in Android where a single touch triggers two click events
|
|
// _filterClick is what leaflet uses as a workaround.
|
|
// This is a problem with more things than just android. Another problem is touchEnd has no touches in
|
|
// its touch list.
|
|
var touchEvent = {};
|
|
if (typeof e.touches !== 'undefined') {
|
|
if (!e.touches.length) {
|
|
return;
|
|
}
|
|
touchEvent = e.touches[0];
|
|
} else if (e.pointerType === 'touch') {
|
|
touchEvent = e;
|
|
if (!this._filterClick(e)) {
|
|
return;
|
|
}
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
var containerPoint = this._map.mouseEventToContainerPoint(touchEvent),
|
|
layerPoint = this._map.mouseEventToLayerPoint(touchEvent),
|
|
latlng = this._map.layerPointToLatLng(layerPoint);
|
|
|
|
this._map.fire(type, {
|
|
latlng: latlng,
|
|
layerPoint: layerPoint,
|
|
containerPoint: containerPoint,
|
|
pageX: touchEvent.pageX,
|
|
pageY: touchEvent.pageY,
|
|
originalEvent: e
|
|
});
|
|
},
|
|
|
|
/** Borrowed from Leaflet and modified for bool ops **/
|
|
_filterClick: function (e) {
|
|
var timeStamp = (e.timeStamp || e.originalEvent.timeStamp),
|
|
elapsed = L.DomEvent._lastClick && (timeStamp - L.DomEvent._lastClick);
|
|
|
|
// are they closer together than 500ms yet more than 100ms?
|
|
// Android typically triggers them ~300ms apart while multiple listeners
|
|
// on the same event should be triggered far faster;
|
|
// or check if click is simulated on the element, and if it is, reject any non-simulated events
|
|
if ((elapsed && elapsed > 100 && elapsed < 500) || (e.target._simulatedClick && !e._simulated)) {
|
|
L.DomEvent.stop(e);
|
|
return false;
|
|
}
|
|
L.DomEvent._lastClick = timeStamp;
|
|
return true;
|
|
},
|
|
|
|
_onTouchStart: function (e) {
|
|
if (!this._map._loaded) {
|
|
return;
|
|
}
|
|
|
|
var type = 'touchstart';
|
|
this._touchEvent(e, type);
|
|
|
|
},
|
|
|
|
_onTouchEnd: function (e) {
|
|
if (!this._map._loaded) {
|
|
return;
|
|
}
|
|
|
|
var type = 'touchend';
|
|
this._touchEvent(e, type);
|
|
},
|
|
|
|
_onTouchCancel: function (e) {
|
|
if (!this._map._loaded) {
|
|
return;
|
|
}
|
|
|
|
var type = 'touchcancel';
|
|
if (this._detectIE()) {
|
|
type = 'pointercancel';
|
|
}
|
|
this._touchEvent(e, type);
|
|
},
|
|
|
|
_onTouchLeave: function (e) {
|
|
if (!this._map._loaded) {
|
|
return;
|
|
}
|
|
|
|
var type = 'touchleave';
|
|
this._touchEvent(e, type);
|
|
},
|
|
|
|
_onTouchMove: function (e) {
|
|
if (!this._map._loaded) {
|
|
return;
|
|
}
|
|
|
|
var type = 'touchmove';
|
|
this._touchEvent(e, type);
|
|
},
|
|
|
|
_detectIE: function () {
|
|
var ua = window.navigator.userAgent;
|
|
|
|
var msie = ua.indexOf('MSIE ');
|
|
if (msie > 0) {
|
|
// IE 10 or older => return version number
|
|
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
|
|
}
|
|
|
|
var trident = ua.indexOf('Trident/');
|
|
if (trident > 0) {
|
|
// IE 11 => return version number
|
|
var rv = ua.indexOf('rv:');
|
|
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
|
|
}
|
|
|
|
var edge = ua.indexOf('Edge/');
|
|
if (edge > 0) {
|
|
// IE 12 => return version number
|
|
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
|
|
}
|
|
|
|
// other browser
|
|
return false;
|
|
}
|
|
});
|
|
|
|
L.Map.addInitHook('addHandler', 'touchExtend', L.Map.TouchExtend);
|
|
|
|
|
|
/**
|
|
* @class L.Marker.Touch
|
|
* @aka Marker.Touch
|
|
*
|
|
* This isn't full Touch support. This is just to get markers to also support dom touch events after creation
|
|
* #TODO: find a better way of getting markers to support touch.
|
|
*/
|
|
L.Marker.Touch = L.Marker.extend({
|
|
|
|
_initInteraction: function () {
|
|
if (!this.addInteractiveTarget) {
|
|
// 0.7.x support
|
|
return this._initInteractionLegacy();
|
|
}
|
|
// TODO this may need be updated to re-add touch events for 1.0+
|
|
return L.Marker.prototype._initInteraction.apply(this);
|
|
},
|
|
|
|
// This is an exact copy of https://github.com/Leaflet/Leaflet/blob/v0.7/src/layer/marker/Marker.js
|
|
// with the addition of the touch events
|
|
_initInteractionLegacy: function () {
|
|
|
|
if (!this.options.clickable) {
|
|
return;
|
|
}
|
|
|
|
// TODO refactor into something shared with Map/Path/etc. to DRY it up
|
|
|
|
var icon = this._icon,
|
|
events = ['dblclick',
|
|
'mousedown',
|
|
'mouseover',
|
|
'mouseout',
|
|
'contextmenu',
|
|
'touchstart',
|
|
'touchend',
|
|
'touchmove'];
|
|
if (this._detectIE) {
|
|
events.concat(['MSPointerDown',
|
|
'MSPointerUp',
|
|
'MSPointerMove',
|
|
'MSPointerCancel']);
|
|
} else {
|
|
events.concat(['touchcancel']);
|
|
}
|
|
|
|
L.DomUtil.addClass(icon, 'leaflet-clickable');
|
|
L.DomEvent.on(icon, 'click', this._onMouseClick, this);
|
|
L.DomEvent.on(icon, 'keypress', this._onKeyPress, this);
|
|
|
|
for (var i = 0; i < events.length; i++) {
|
|
L.DomEvent.on(icon, events[i], this._fireMouseEvent, this);
|
|
}
|
|
|
|
if (L.Handler.MarkerDrag) {
|
|
this.dragging = new L.Handler.MarkerDrag(this);
|
|
|
|
if (this.options.draggable) {
|
|
this.dragging.enable();
|
|
}
|
|
}
|
|
},
|
|
|
|
_detectIE: function () {
|
|
var ua = window.navigator.userAgent;
|
|
|
|
var msie = ua.indexOf('MSIE ');
|
|
if (msie > 0) {
|
|
// IE 10 or older => return version number
|
|
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
|
|
}
|
|
|
|
var trident = ua.indexOf('Trident/');
|
|
if (trident > 0) {
|
|
// IE 11 => return version number
|
|
var rv = ua.indexOf('rv:');
|
|
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
|
|
}
|
|
|
|
var edge = ua.indexOf('Edge/');
|
|
if (edge > 0) {
|
|
// IE 12 => return version number
|
|
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
|
|
}
|
|
|
|
// other browser
|
|
return false;
|
|
}
|
|
});
|