From 1b3404f1f9db61aae8d119b19fddfe715d588c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Mon, 7 Mar 2011 08:21:51 +0000 Subject: [PATCH] the map may jump on mouseup after dragging, p=me, r=crschmidt (closes #2936) git-svn-id: http://svn.openlayers.org/trunk/openlayers@11635 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- lib/OpenLayers/Handler/Drag.js | 17 +++- tests/Handler/Drag.html | 152 +++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 1 deletion(-) diff --git a/lib/OpenLayers/Handler/Drag.js b/lib/OpenLayers/Handler/Drag.js index 261ff343e4..fc9f9b686c 100644 --- a/lib/OpenLayers/Handler/Drag.js +++ b/lib/OpenLayers/Handler/Drag.js @@ -62,6 +62,14 @@ OpenLayers.Handler.Drag = OpenLayers.Class(OpenLayers.Handler, { */ start: null, + /** + * Property: lastMoveEvt + * {Object} The last mousemove event that occurred. Used to + * position the map correctly when our "delay drag" + * timeout expired. + */ + lastMoveEvt: null, + /** * Property: oldOnselectstart * {Function} @@ -209,7 +217,7 @@ OpenLayers.Handler.Drag = OpenLayers.Class(OpenLayers.Handler, { this.oldOnselectstart = document.onselectstart; document.onselectstart = OpenLayers.Function.False; } - this.last = this.evt.xy; + this.last = evt.xy; } return true; }, @@ -341,6 +349,7 @@ OpenLayers.Handler.Drag = OpenLayers.Class(OpenLayers.Handler, { * {Boolean} Let the event propagate. */ mousemove: function(evt) { + this.lastMoveEvt = evt; return this.dragmove(evt); }, @@ -364,6 +373,12 @@ OpenLayers.Handler.Drag = OpenLayers.Class(OpenLayers.Handler, { */ removeTimeout: function() { this.timeoutId = null; + // if timeout expires while we're still dragging (mouseup + // hasn't occurred) then call mousemove to move to the + // correct position + if(this.dragging) { + this.mousemove(this.lastMoveEvt); + } }, /** diff --git a/tests/Handler/Drag.html b/tests/Handler/Drag.html index 838975b19e..a32fa6288f 100644 --- a/tests/Handler/Drag.html +++ b/tests/Handler/Drag.html @@ -440,6 +440,158 @@ "deactivate sets start to null"); } + function test_interval_timer_after_mouseup(t) { + t.plan(5); + + // set up + + var map = new OpenLayers.Map('map'); + + var control = new OpenLayers.Control(); + map.addControl(control); + + var moveCnt; + + var handler = new OpenLayers.Handler.Drag(control, {}, { + interval: 1, + move: function() { + moveCnt++; + } + }); + handler.activate(); + + handler.checkModifiers = function() { return true; }; + + var ilc = OpenLayers.Event.isLeftClick; + OpenLayers.Event.isLeftClick = function() { return true; }; + + // test + + moveCnt = 0; + + var xy1 = new OpenLayers.Pixel(1, 2); + handler.mousedown({xy: xy1}); + t.ok(handler.last == xy1, "[mousedown] last is as expected"); + var xy2 = new OpenLayers.Pixel(2, 3); + handler.mousemove({xy: xy2}); + t.ok(handler.last == xy2, "[mousemove 1] last is as expected"); + t.ok(handler.timeoutId != null, "[mousemove 1] timeoutId is set"); + var xy3 = new OpenLayers.Pixel(3, 4); + handler.mousemove({xy: xy3}); + t.ok(handler.last == xy2, "[mousemove 2] last is as expected"); + var xy4 = new OpenLayers.Pixel(4, 5); + handler.mouseup({xy: xy4}); + + t.delay_call(3, function() { + // the timer should not cause a move + t.eq(moveCnt, 1, "move called once"); + // tear down + OpenLayers.Event.isLeftClick = ilc; + }); + } + + function test_interval_timer_after_mousedown(t) { + t.plan(5); + + // set up + + var map = new OpenLayers.Map('map'); + + var control = new OpenLayers.Control(); + map.addControl(control); + + var moveCnt; + + var handler = new OpenLayers.Handler.Drag(control, {}, { + interval: 1, + move: function() { + moveCnt++; + } + }); + handler.activate(); + + handler.checkModifiers = function() { return true; }; + + var ilc = OpenLayers.Event.isLeftClick; + OpenLayers.Event.isLeftClick = function() { return true; }; + + // test + + moveCnt = 0; + + var xy1 = new OpenLayers.Pixel(1, 2); + handler.mousedown({xy: xy1}); + t.ok(handler.last == xy1, "[mousedown] last is as expected"); + var xy2 = new OpenLayers.Pixel(2, 3); + handler.mousemove({xy: xy2}); + t.ok(handler.last == xy2, "[mousemove 1] last is as expected"); + t.ok(handler.timeoutId != null, "[mousemove 1] timeoutId is set"); + var xy3 = new OpenLayers.Pixel(3, 4); + handler.mousemove({xy: xy3}); + t.ok(handler.last == xy2, "[mousemove 2] last is as expected"); + var xy4 = new OpenLayers.Pixel(4, 5); + handler.mouseup({xy: xy4}); + var xy5 = new OpenLayers.Pixel(5, 6); + handler.mousedown({xy: xy4}); + + t.delay_call(3, function() { + // the timer should not cause a move + t.eq(moveCnt, 1, "move called once"); + // tear down + OpenLayers.Event.isLeftClick = ilc; + }); + } + + function test_interval_timer_before_mouseup(t) { + t.plan(5); + + // set up + + var map = new OpenLayers.Map('map'); + + var control = new OpenLayers.Control(); + map.addControl(control); + + var moveCnt; + + var handler = new OpenLayers.Handler.Drag(control, {}, { + interval: 1, + move: function() { + moveCnt++; + } + }); + handler.activate(); + + handler.checkModifiers = function() { return true; }; + + var ilc = OpenLayers.Event.isLeftClick; + OpenLayers.Event.isLeftClick = function() { return true; }; + + // test + + moveCnt = 0; + + var xy1 = new OpenLayers.Pixel(1, 2); + handler.mousedown({xy: xy1}); + t.ok(handler.last == xy1, "[mousedown] last is as expected"); + var xy2 = new OpenLayers.Pixel(2, 3); + handler.mousemove({xy: xy2}); + t.ok(handler.last == xy2, "[mousemove 1] last is as expected"); + t.ok(handler.timeoutId != null, "[mousemove 1] timeoutId is set"); + var xy3 = new OpenLayers.Pixel(3, 4); + handler.mousemove({xy: xy3}); + t.ok(handler.last == xy2, "[mousemove 2] last is as expected"); + + t.delay_call(3, function() { + // the timer should cause a move + t.eq(moveCnt, 2, "move called twice"); + var xy4 = new OpenLayers.Pixel(4, 5); + handler.mouseup({xy: xy4}); + // tear down + OpenLayers.Event.isLeftClick = ilc; + }); + } +