Fix box zoom race condition (#5452)
* Fix box zoom race condition The deferred call to `_resetState` can interrupt the next box zoom if the user initiates it before the timeout fires. This causes the mouse move handler to create a second box zoom element, orphaning the first one and leaving it in the DOM. * Extract duplicate code into private method
This commit is contained in:
parent
1318b999ef
commit
8e96ac476d
@ -25,6 +25,7 @@ export var BoxZoom = Handler.extend({
|
||||
this._map = map;
|
||||
this._container = map._container;
|
||||
this._pane = map._panes.overlayPane;
|
||||
this._resetStateTimeout = 0;
|
||||
map.on('unload', this._destroy, this);
|
||||
},
|
||||
|
||||
@ -46,12 +47,23 @@ export var BoxZoom = Handler.extend({
|
||||
},
|
||||
|
||||
_resetState: function () {
|
||||
this._resetStateTimeout = 0;
|
||||
this._moved = false;
|
||||
},
|
||||
|
||||
_clearDeferredResetState: function () {
|
||||
if (this._resetStateTimeout !== 0) {
|
||||
clearTimeout(this._resetStateTimeout);
|
||||
this._resetStateTimeout = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseDown: function (e) {
|
||||
if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; }
|
||||
|
||||
// Clear the deferred resetState if it hasn't executed yet, otherwise it
|
||||
// will interrupt the interaction and orphan a box element in the container.
|
||||
this._clearDeferredResetState();
|
||||
this._resetState();
|
||||
|
||||
DomUtil.disableTextSelection();
|
||||
@ -113,7 +125,8 @@ export var BoxZoom = Handler.extend({
|
||||
if (!this._moved) { return; }
|
||||
// Postpone to next JS tick so internal click event handling
|
||||
// still see it as "moved".
|
||||
setTimeout(Util.bind(this._resetState, this), 0);
|
||||
this._clearDeferredResetState();
|
||||
this._resetStateTimeout = setTimeout(Util.bind(this._resetState, this), 0);
|
||||
|
||||
var bounds = new LatLngBounds(
|
||||
this._map.containerPointToLatLng(this._startPoint),
|
||||
|
Loading…
Reference in New Issue
Block a user