diff --git a/src/ol/interaction/dblclickzoom.js b/src/ol/interaction/dblclickzoom.js
index 587f776265..f01587843c 100644
--- a/src/ol/interaction/dblclickzoom.js
+++ b/src/ol/interaction/dblclickzoom.js
@@ -1,7 +1,7 @@
goog.provide('ol.interaction.DblClickZoom');
-goog.require('goog.events.EventType');
goog.require('ol.MapBrowserEvent');
+goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.interaction.Constraints');
goog.require('ol.interaction.Interaction');
@@ -24,8 +24,8 @@ goog.inherits(ol.interaction.DblClickZoom, ol.interaction.Interaction);
ol.interaction.DblClickZoom.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
- if (browserEvent.type == goog.events.EventType.DBLCLICK &&
- browserEvent.isMouseActionButton()) {
+ if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DBLCLICK &&
+ mapBrowserEvent.isMouseActionButton()) {
var map = mapBrowserEvent.map;
var resolution = map.getResolution();
var delta = mapBrowserEvent.browserEvent.shiftKey ? -1 : 1;
diff --git a/src/ol/interaction/drag.js b/src/ol/interaction/drag.js
index 2009e93364..fbe57dfd54 100644
--- a/src/ol/interaction/drag.js
+++ b/src/ol/interaction/drag.js
@@ -93,19 +93,19 @@ ol.interaction.Drag.prototype.handleMapBrowserEvent =
}
var browserEvent = mapBrowserEvent.browserEvent;
if (this.dragging_) {
- if (mapBrowserEvent.type == goog.fx.Dragger.EventType.DRAG) {
+ if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DRAG) {
goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
this.deltaX = browserEvent.clientX - this.startX;
this.deltaY = browserEvent.clientY - this.startY;
this.handleDrag(mapBrowserEvent);
- } else if (mapBrowserEvent.type == goog.fx.Dragger.EventType.END) {
+ } else if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DRAGEND) {
goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
this.deltaX = browserEvent.clientX - this.startX;
this.deltaY = browserEvent.clientY - this.startY;
this.handleDragEnd(mapBrowserEvent);
this.dragging_ = false;
}
- } else if (mapBrowserEvent.type == goog.fx.Dragger.EventType.START) {
+ } else if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DRAGSTART) {
goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
this.startX = browserEvent.clientX;
this.startY = browserEvent.clientY;
diff --git a/src/ol/map.js b/src/ol/map.js
index 35d1650410..4372cbad2b 100644
--- a/src/ol/map.js
+++ b/src/ol/map.js
@@ -22,8 +22,6 @@ goog.require('goog.events.MouseWheelEvent');
goog.require('goog.events.MouseWheelHandler');
goog.require('goog.events.MouseWheelHandler.EventType');
goog.require('goog.functions');
-goog.require('goog.fx.DragEvent');
-goog.require('goog.fx.Dragger');
goog.require('goog.fx.anim');
goog.require('goog.fx.anim.Animated');
goog.require('goog.object');
@@ -98,12 +96,6 @@ ol.Map = function(
this.logger = goog.debug.Logger.getLogger('ol.map.' + goog.getUid(this));
}
- /**
- * @type {boolean} Are we a touch device?
- * @private
- */
- this.isTouch_ = false;
-
/**
* @type {ol.TransformFunction}
* @private
@@ -159,9 +151,15 @@ ol.Map = function(
this.viewport_.style.zIndex = ol.MapPaneZIndex.VIEWPORT;
goog.dom.appendChild(container, this.viewport_);
- goog.events.listen(this.viewport_, [
- goog.events.EventType.DBLCLICK
- ], this.handleBrowserEvent, false, this);
+ var mapBrowserEventHandler = new ol.MapBrowserEventHandler(this);
+ goog.events.listen(mapBrowserEventHandler, [
+ ol.MapBrowserEvent.EventType.CLICK,
+ ol.MapBrowserEvent.EventType.DBLCLICK,
+ ol.MapBrowserEvent.EventType.DRAGSTART,
+ ol.MapBrowserEvent.EventType.DRAG,
+ ol.MapBrowserEvent.EventType.DRAGEND
+ ], this.handleMapBrowserEvent, false, this);
+ this.registerDisposable(mapBrowserEventHandler);
// FIXME we probably shouldn't listen on document...
var keyHandler = new goog.events.KeyHandler(document);
@@ -175,17 +173,6 @@ ol.Map = function(
this.handleBrowserEvent, false, this);
this.registerDisposable(mouseWheelHandler);
- var dragger = new goog.fx.Dragger(this.viewport_);
- dragger.defaultAction = function() {};
- goog.events.listen(dragger, [
- goog.fx.Dragger.EventType.START,
- goog.fx.Dragger.EventType.DRAG,
- goog.fx.Dragger.EventType.END
- ], this.handleDraggerEvent, false, this);
- goog.events.listen(this.viewport_, goog.events.EventType.TOUCHSTART,
- this.handleTouchstart, false, this);
- this.registerDisposable(dragger);
-
/**
* @type {ol.renderer.Map}
* @private
@@ -501,6 +488,14 @@ ol.Map.prototype.getViewport = function() {
ol.Map.prototype.handleBrowserEvent = function(browserEvent, opt_type) {
var type = opt_type || browserEvent.type;
var mapBrowserEvent = new ol.MapBrowserEvent(type, this, browserEvent);
+ this.handleMapBrowserEvent(mapBrowserEvent);
+};
+
+
+/**
+ * @param {ol.MapBrowserEvent} mapBrowserEvent The event to handle.
+ */
+ol.Map.prototype.handleMapBrowserEvent = function(mapBrowserEvent) {
var interactions = this.getInteractions();
var interactionsArray = /** @type {Array.
} */
interactions.getArray();
@@ -511,28 +506,11 @@ ol.Map.prototype.handleBrowserEvent = function(browserEvent, opt_type) {
};
-/**
- * @param {goog.events.Event} browserEvent Browser event.
- */
-ol.Map.prototype.handleTouchstart = function(browserEvent) {
- this.isTouch_ = true;
- // now we know that we are a touch device
- goog.events.unlisten(this.viewport_, goog.events.EventType.TOUCHSTART,
- this.handleTouchstart, false, this);
-};
-
-
/**
* @param {goog.fx.DragEvent} dragEvent Drag event.
*/
ol.Map.prototype.handleDraggerEvent = function(dragEvent) {
- var browserEvent = dragEvent.browserEvent;
- // workaround for goog.fx.Dragger issue that causes both mousemove and
- // touchmove to trigger a drag event on touch devices
- if ((this.isTouch_ && browserEvent.type != goog.events.EventType.MOUSEMOVE) ||
- !this.isTouch_) {
- this.handleBrowserEvent(browserEvent, dragEvent.type);
- }
+ this.handleBrowserEvent(dragEvent.browserEvent, dragEvent.type);
};
diff --git a/src/ol/mapbrowserevent.js b/src/ol/mapbrowserevent.js
index 0fa253d952..53bd1ba68c 100644
--- a/src/ol/mapbrowserevent.js
+++ b/src/ol/mapbrowserevent.js
@@ -1,6 +1,11 @@
goog.provide('ol.MapBrowserEvent');
+goog.provide('ol.MapBrowserEvent.EventType');
+goog.provide('ol.MapBrowserEventHandler');
+goog.require('goog.asserts');
goog.require('goog.events.BrowserEvent');
+goog.require('goog.events.EventTarget');
+goog.require('goog.events.EventType');
goog.require('goog.style');
goog.require('ol.Coordinate');
goog.require('ol.MapEvent');
@@ -51,3 +56,240 @@ ol.MapBrowserEvent.prototype.getCoordinate = function() {
return coordinate;
}
};
+
+
+/**
+ * @return {boolean} Do we have a left click?
+ */
+ol.MapBrowserEvent.prototype.isMouseActionButton = function() {
+ // always assume a left-click on touch devices
+ return ('ontouchstart' in document.documentElement) ||
+ this.browserEvent.isMouseActionButton();
+};
+
+
+
+/**
+ * @param {ol.Map} map The map with the viewport to listen to events on.
+ * @constructor
+ * @extends {goog.events.EventTarget}
+ */
+ol.MapBrowserEventHandler = function(map) {
+
+ /**
+ * This is the element that we will listen to the real events on.
+ * @type {ol.Map}
+ * @private
+ */
+ this.map_ = map;
+
+ /**
+ * @type {Object}
+ * @private
+ */
+ this.previous_ = null;
+
+ /**
+ * @type {boolean}
+ * @private
+ */
+ this.dragged_ = false;
+
+ /**
+ * @type {number|undefined}
+ * @private
+ */
+ this.timestamp_;
+
+ /**
+ * @type {Array.}
+ * @private
+ */
+ this.dragListenerKeys_ = null;
+
+ /**
+ * @type {goog.events.BrowserEvent}
+ * @private
+ */
+ this.down_ = null;
+
+ /**
+ * @type {boolean}
+ * @private
+ */
+ this.isTouch_ = document && ('ontouchstart' in document.documentElement);
+
+ var element = this.map_.getViewport();
+ goog.events.listen(element,
+ this.isTouch_ ?
+ goog.events.EventType.TOUCHSTART :
+ goog.events.EventType.MOUSEDOWN,
+ this.dragstart_, false, this);
+ goog.events.listen(element,
+ this.isTouch_ ?
+ goog.events.EventType.TOUCHEND :
+ goog.events.EventType.MOUSEUP,
+ this.dblclick_, false, this);
+ goog.events.listen(element,
+ goog.events.EventType.CLICK, this.click_, false, this);
+};
+goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget);
+
+
+/**
+ * @param {goog.events.BrowserEvent} browserEvent Browser event.
+ * @private
+ */
+ol.MapBrowserEventHandler.prototype.touchEnableBrowserEvent_ =
+ function(browserEvent) {
+ if (this.isTouch_) {
+ goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
+ var nativeEvent = browserEvent.getBrowserEvent();
+ if (nativeEvent.touches && nativeEvent.touches.length) {
+ var nativeTouch = nativeEvent.touches[0];
+ browserEvent.clientX = nativeTouch.clientX;
+ browserEvent.clientY = nativeTouch.clientY;
+ }
+ }
+};
+
+
+/**
+ * @param {goog.events.BrowserEvent} browserEvent Browser event.
+ * @private
+ */
+ol.MapBrowserEventHandler.prototype.click_ = function(browserEvent) {
+ if (!this.dragged_) {
+ this.touchEnableBrowserEvent_(browserEvent);
+ var newEvent = new ol.MapBrowserEvent(
+ ol.MapBrowserEvent.EventType.CLICK, this.map_, browserEvent);
+ this.down_ = null;
+ this.dispatchEvent(newEvent);
+ }
+};
+
+
+/**
+ * @param {goog.events.BrowserEvent} browserEvent Browser event.
+ * @private
+ */
+ol.MapBrowserEventHandler.prototype.dblclick_ = function(browserEvent) {
+ if (!this.dragged_) {
+ var now = new Date().getTime();
+ if (!this.timestamp_ || now - this.timestamp_ > 250) {
+ this.timestamp_ = now;
+ } else {
+ this.timestamp_ = undefined;
+ this.touchEnableBrowserEvent_(this.down_);
+ var newEvent = new ol.MapBrowserEvent(
+ ol.MapBrowserEvent.EventType.DBLCLICK, this.map_, this.down_);
+ this.down_ = null;
+ this.dispatchEvent(newEvent);
+ }
+ }
+};
+
+
+/**
+ * @param {goog.events.BrowserEvent} browserEvent Browser event.
+ * @private
+ */
+ol.MapBrowserEventHandler.prototype.dragstart_ = function(browserEvent) {
+ if (!this.previous_) {
+ this.touchEnableBrowserEvent_(browserEvent);
+ this.previous_ = {
+ clientX: browserEvent.clientX,
+ clientY: browserEvent.clientY
+ };
+ this.down_ = browserEvent;
+ this.dragged_ = false;
+ if (this.isTouch_) {
+ this.dragListenerKeys_ = [
+ goog.events.listen(document,
+ goog.events.EventType.TOUCHMOVE, this.drag_, false, this),
+ goog.events.listen(document,
+ goog.events.EventType.TOUCHEND, this.dragend_, false, this)
+ ];
+ } else {
+ this.dragListenerKeys_ = [
+ goog.events.listen(document,
+ goog.events.EventType.MOUSEMOVE, this.drag_, false, this),
+ goog.events.listen(document,
+ goog.events.EventType.MOUSEUP, this.dragend_, false, this)
+ ];
+ }
+ var newEvent = new ol.MapBrowserEvent(
+ ol.MapBrowserEvent.EventType.DRAGSTART, this.map_, browserEvent);
+ this.dispatchEvent(newEvent);
+ }
+};
+
+
+/**
+ * @param {goog.events.BrowserEvent} browserEvent Browser event.
+ * @private
+ */
+ol.MapBrowserEventHandler.prototype.drag_ = function(browserEvent) {
+ this.dragged_ = true;
+ this.touchEnableBrowserEvent_(browserEvent);
+ this.previous_ = {
+ clientX: browserEvent.clientX,
+ clientY: browserEvent.clientY
+ };
+ // prevent viewport dragging on touch devices
+ browserEvent.preventDefault();
+ var newEvent = new ol.MapBrowserEvent(
+ ol.MapBrowserEvent.EventType.DRAG, this.map_, browserEvent);
+ this.dispatchEvent(newEvent);
+};
+
+
+/**
+ * @param {goog.events.BrowserEvent} browserEvent Browser event.
+ * @private
+ */
+ol.MapBrowserEventHandler.prototype.dragend_ = function(browserEvent) {
+ if (this.previous_) {
+ goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
+ this.dragListenerKeys_ = null;
+ this.previous_ = null;
+ var newEvent = new ol.MapBrowserEvent(
+ ol.MapBrowserEvent.EventType.DRAGEND, this.map_, browserEvent);
+ this.down_ = null;
+ this.dispatchEvent(newEvent);
+ }
+};
+
+
+/** @override */
+ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
+ var element = this.map_.getViewport();
+ goog.events.unlisten(element,
+ this.isTouch_ ?
+ goog.events.EventType.TOUCHSTART :
+ goog.events.EventType.MOUSEDOWN,
+ this.dragstart_, false, this);
+ goog.events.unlisten(element,
+ this.isTouch_ ?
+ goog.events.EventType.TOUCHEND :
+ goog.events.EventType.MOUSEUP,
+ this.dblclick_, false, this);
+ goog.events.unlisten(element,
+ goog.events.EventType.CLICK, this.click_, false, this);
+ goog.asserts.assert(goog.isDef(this.dragListenerKeys_));
+ goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
+ this.dragListenerKeys_ = null;
+};
+
+
+/**
+ * Constants for event names.
+ * @enum {string}
+ */
+ol.MapBrowserEvent.EventType = {
+ CLICK: goog.events.EventType.CLICK,
+ DBLCLICK: goog.events.EventType.DBLCLICK,
+ DRAGSTART: 'dragstart',
+ DRAG: 'drag',
+ DRAGEND: 'dragend'
+};