diff --git a/lib/OpenLayers/Handler/Feature.js b/lib/OpenLayers/Handler/Feature.js index 4baee15692..35f9a921ed 100644 --- a/lib/OpenLayers/Handler/Feature.js +++ b/lib/OpenLayers/Handler/Feature.js @@ -56,6 +56,13 @@ OpenLayers.Handler.Feature = OpenLayers.Class(OpenLayers.Handler, { * {} The location of the last mouseup. */ up: null, + + /** + * Property: touch + * {Boolean} When a touchstart event is fired, touch will be true and all + * mouse related listeners will do nothing. + */ + touch: false, /** * Property: clickTolerance @@ -129,9 +136,33 @@ OpenLayers.Handler.Feature = OpenLayers.Class(OpenLayers.Handler, { * {Boolean} Let the event propagate. */ touchstart: function(evt) { + if(!this.touch) { + this.touch = true; + this.map.events.un({ + mousedown: this.mousedown, + mouseup: this.mouseup, + mousemove: this.mousemove, + click: this.click, + dblclick: this.dblclick, + scope: this + }); + } return this.mousedown(evt); }, + /** + * Method: touchmove + * Handle touchmove events. We just prevent the browser default behavior, + * for Android Safari not to select text when moving the finger after + * selecting a feature. + * + * Parameters: + * evt - {Event} + */ + touchmove: function(evt) { + OpenLayers.Event.stop(evt); + }, + /** * Method: mousedown * Handle mouse down. Stop propagation if a feature is targeted by this @@ -251,6 +282,11 @@ OpenLayers.Handler.Feature = OpenLayers.Class(OpenLayers.Handler, { this.lastFeature = null; } if(this.feature) { + if(evt.type === "touchstart") { + // stop the event to prevent Android Safari from + // "flashing" the map div + OpenLayers.Event.stop(evt); + } var inNew = (this.feature != this.lastFeature); if(this.geometryTypeMatches(this.feature)) { // in to a feature @@ -349,6 +385,7 @@ OpenLayers.Handler.Feature = OpenLayers.Class(OpenLayers.Handler, { this.lastFeature = null; this.down = null; this.up = null; + this.touch = false; this.map.events.un({ "removelayer": this.handleMapEvents, "changelayer": this.handleMapEvents, diff --git a/tests/Handler/Feature.html b/tests/Handler/Feature.html index e1131362c9..4c3641aa33 100644 --- a/tests/Handler/Feature.html +++ b/tests/Handler/Feature.html @@ -53,7 +53,7 @@ } function test_events(t) { - t.plan(30); + t.plan(35); var map = new OpenLayers.Map('map'); var control = new OpenLayers.Control(); @@ -64,8 +64,8 @@ // list below events that should be handled (events) and those // that should not be handled (nonevents) by the handler - var events = ["mousedown", "mouseup", "mousemove", "click", "dblclick", "touchstart"]; - var nonevents = ["mouseout", "resize", "focus", "blur"]; + var events = ["mousedown", "mouseup", "mousemove", "click", "dblclick", "touchstart", "touchmove"]; + var nonevents = ["mouseout", "resize", "focus", "blur", "touchend"]; map.events.registerPriority = function(type, obj, func) { var output = func(); // Don't listen for setEvent handlers (#902) @@ -255,6 +255,82 @@ map.events.triggerEvent('touchstart', evtPx); } + function test_touchstart(t) { + // a test to verify that the touchstart function does + // unregister the mouse listeners when it's called the + // first time + + t.plan(4); + + // set up + + var map = new OpenLayers.Map('map', {controls: []}); + var control = new OpenLayers.Control(); + map.addControl(control); + var layer = new OpenLayers.Layer(); + map.addLayer(layer); + + var handler = new OpenLayers.Handler.Feature(control, layer, {}); + handler.mousedown = function() {}; // mock mousedown + handler.activate(); + + function allRegistered() { + var eventTypes = ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick'], + eventType, + listeners, + listener, + flag; + for(var i=0, ilen=eventTypes.length; i