From cccb9f9f5c09bca4a093d62bfe9f775f32dd6133 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Fri, 22 Mar 2019 15:38:21 -0700 Subject: [PATCH 1/9] Fix/add tests for existing dblclick-zoom functionality --- test/unit/ui/handler/dblclick_zoom.test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/unit/ui/handler/dblclick_zoom.test.js b/test/unit/ui/handler/dblclick_zoom.test.js index 1d00c55fe78..20d52fe4a6b 100644 --- a/test/unit/ui/handler/dblclick_zoom.test.js +++ b/test/unit/ui/handler/dblclick_zoom.test.js @@ -9,6 +9,21 @@ function createMap(t) { return new Map({ container: DOM.create('div', '', window.document.body) }); } +test('DoubleClickZoomHandler zooms on dblclick event', (t) => { + const map = createMap(t); + + const zoom = t.spy(); + map.on('zoom', zoom); + + simulate.dblclick(map.getCanvas()); + map._renderTaskQueue.run(); + + t.ok(zoom.called); + + map.remove(); + t.end(); +}); + test('DoubleClickZoomHandler does not zoom if preventDefault is called on the dblclick event', (t) => { const map = createMap(t); @@ -18,6 +33,7 @@ test('DoubleClickZoomHandler does not zoom if preventDefault is called on the db map.on('zoom', zoom); simulate.dblclick(map.getCanvas()); + map._renderTaskQueue.run(); t.equal(zoom.callCount, 0); From edb7d2b7b60ef6509b310436f9d389d265ea5288 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Fri, 22 Mar 2019 15:42:43 -0700 Subject: [PATCH 2/9] Add tests for existing dbltap-zoom functionality --- test/unit/ui/handler/dblclick_zoom.test.js | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/test/unit/ui/handler/dblclick_zoom.test.js b/test/unit/ui/handler/dblclick_zoom.test.js index 20d52fe4a6b..6ec28c8f3e3 100644 --- a/test/unit/ui/handler/dblclick_zoom.test.js +++ b/test/unit/ui/handler/dblclick_zoom.test.js @@ -40,3 +40,59 @@ test('DoubleClickZoomHandler does not zoom if preventDefault is called on the db map.remove(); t.end(); }); + +test('DoubleClickZoomHandler zooms on double tap if touchstart events are < 300ms apart', (t) => { + const map = createMap(t); + + const zoom = t.spy(); + map.on('zoom', zoom); + + const simulateDoubleTap = () => { + return new Promise(resolve => { + simulate.touchstart(map.getCanvas()); + simulate.touchend(map.getCanvas()); + setTimeout(() => { + simulate.touchstart(map.getCanvas()); + simulate.touchend(map.getCanvas()); + map._renderTaskQueue.run(); + resolve(); + }, 100); + }); + }; + + simulateDoubleTap(map, 100).then(() => { + t.ok(zoom.called); + + map.remove(); + t.end(); + }); + +}); + +test('DoubleClickZoomHandler does not zoom on double tap if touchstart events are > 300ms apart', (t) => { + const map = createMap(t); + + const zoom = t.spy(); + map.on('zoom', zoom); + + const simulateDelayedDoubleTap = () => { + return new Promise(resolve => { + simulate.touchstart(map.getCanvas()); + simulate.touchend(map.getCanvas()); + setTimeout(() => { + simulate.touchstart(map.getCanvas()); + simulate.touchend(map.getCanvas()); + map._renderTaskQueue.run(); + resolve(); + }, 300); + }); + }; + + simulateDelayedDoubleTap().then(() => { + t.equal(zoom.callCount, 0); + + map.remove(); + t.end(); + }); + +}); From daff8330db09c9cab57f748af80637e89aeaf677 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Fri, 22 Mar 2019 17:23:49 -0700 Subject: [PATCH 3/9] Prevent dbltap-zoom if touch points differ, add test --- src/ui/handler/dblclick_zoom.js | 15 ++++++++++-- test/unit/ui/handler/dblclick_zoom.test.js | 28 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/ui/handler/dblclick_zoom.js b/src/ui/handler/dblclick_zoom.js index 1be4de8b931..357cd556e95 100644 --- a/src/ui/handler/dblclick_zoom.js +++ b/src/ui/handler/dblclick_zoom.js @@ -14,6 +14,7 @@ class DoubleClickZoomHandler { _enabled: boolean; _active: boolean; _tapped: ?TimeoutID; + _tappedPoint: ?{x: number, y: number}; /** * @private @@ -71,12 +72,22 @@ class DoubleClickZoomHandler { if (!this.isEnabled()) return; if (e.points.length > 1) return; + const maxDelta = 0; + if (!this._tapped) { - this._tapped = setTimeout(() => { this._tapped = null; }, 300); + this._tappedPoint = e.points[0]; + this._tapped = setTimeout(() => { this._tapped = null; this._tappedPoint = null; }, 300); } else { + const newTap = e.points[0]; + const firstTap = this._tappedPoint; + clearTimeout(this._tapped); this._tapped = null; - this._zoom(e); + this._tappedPoint = null; + + if (firstTap && Math.abs(firstTap.x - newTap.x) <= maxDelta && Math.abs(firstTap.y - newTap.y) <= maxDelta) { + this._zoom(e); + } } } diff --git a/test/unit/ui/handler/dblclick_zoom.test.js b/test/unit/ui/handler/dblclick_zoom.test.js index 6ec28c8f3e3..506f3e4abc7 100644 --- a/test/unit/ui/handler/dblclick_zoom.test.js +++ b/test/unit/ui/handler/dblclick_zoom.test.js @@ -96,3 +96,31 @@ test('DoubleClickZoomHandler does not zoom on double tap if touchstart events ar }); }); + +test('DoubleClickZoomHandler does not zoom on double tap if touchstart events are in different locations', (t) => { + const map = createMap(t); + + const zoom = t.spy(); + map.on('zoom', zoom); + + const simulateTwoDifferentTaps = () => { + return new Promise(resolve => { + simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0, clientY: 0}]}); + simulate.touchend(map.getCanvas()); + setTimeout(() => { + simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0.5, clientY: 0.5}]}); + simulate.touchend(map.getCanvas()); + map._renderTaskQueue.run(); + resolve(); + }, 100); + }); + }; + + simulateTwoDifferentTaps().then(() => { + t.equal(zoom.callCount, 0); + + map.remove(); + t.end(); + }); + +}); From c2a1ca8e2b8a4e45f1f76ed632956ea1f01c536b Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Fri, 22 Mar 2019 19:36:39 -0700 Subject: [PATCH 4/9] Trigger dbltap-zoom on second touchend, add tests --- src/ui/handler/dblclick_zoom.js | 30 +++++++++-- test/unit/ui/handler/dblclick_zoom.test.js | 58 ++++++++++++++++++++++ 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/src/ui/handler/dblclick_zoom.js b/src/ui/handler/dblclick_zoom.js index 357cd556e95..c67ac5eeca2 100644 --- a/src/ui/handler/dblclick_zoom.js +++ b/src/ui/handler/dblclick_zoom.js @@ -81,16 +81,36 @@ class DoubleClickZoomHandler { const newTap = e.points[0]; const firstTap = this._tappedPoint; - clearTimeout(this._tapped); - this._tapped = null; - this._tappedPoint = null; - if (firstTap && Math.abs(firstTap.x - newTap.x) <= maxDelta && Math.abs(firstTap.y - newTap.y) <= maxDelta) { - this._zoom(e); + const onTouchEnd = () => { + if (this._tapped) { // make sure we are still within the timeout window + this._zoom(e); // pass this touchstart event, as touchend events have no points + } + this._map.off('touchend', onTouchEnd); + this._resetTapped(); + }; + + const onTouchCancel = () => { + this._map.off('touchend', onTouchEnd); + this._map.off('touchcancel', onTouchCancel); + this._resetTapped(); + }; + + this._map.on('touchend', onTouchEnd); + this._map.on('touchcancel', onTouchCancel); + + } else { // touches are too far apart, don't zoom + this._resetTapped(); } } } + _resetTapped() { + clearTimeout(this._tapped); + this._tapped = null; + this._tappedPoint = null; + } + onDblClick(e: MapMouseEvent) { if (!this.isEnabled()) return; e.originalEvent.preventDefault(); diff --git a/test/unit/ui/handler/dblclick_zoom.test.js b/test/unit/ui/handler/dblclick_zoom.test.js index 506f3e4abc7..ea72e1127e2 100644 --- a/test/unit/ui/handler/dblclick_zoom.test.js +++ b/test/unit/ui/handler/dblclick_zoom.test.js @@ -124,3 +124,61 @@ test('DoubleClickZoomHandler does not zoom on double tap if touchstart events ar }); }); + +test('DoubleClickZoomHandler zooms on the second touchend event of a double tap', (t) => { + const map = createMap(t); + + const zoom = t.spy(); + map.on('zoom', zoom); + + simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0.5, clientY: 0.5}]}); + simulate.touchend(map.getCanvas()); + simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0.5, clientY: 0.5}]}); + map._renderTaskQueue.run(); + t.notOk(zoom.called, 'should not trigger zoom before second touchend'); + + simulate.touchcancel(map.getCanvas()); + simulate.touchend(map.getCanvas()); + map._renderTaskQueue.run(); + t.notOk(zoom.called, 'should not trigger zoom if second touch is canceled'); + + simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0.5, clientY: 0.5}]}); + simulate.touchend(map.getCanvas()); + simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0.5, clientY: 0.5}]}); + map._renderTaskQueue.run(); + t.notOk(zoom.called); + + simulate.touchend(map.getCanvas()); + map._renderTaskQueue.run(); + + t.ok(zoom.called, 'should trigger zoom after second touchend'); + t.deepEquals(zoom.getCall(0).args[0].point, { x: 0.5, y: 0.5 }, 'should zoom to correct point'); + + t.end(); +}); + +test('DoubleClickZoomHandler does not zoom on double tap if second touchend is >300ms after first touchstart', (t) => { + const map = createMap(t); + + const zoom = t.spy(); + map.on('zoom', zoom); + + const simulateSlowSecondTap = () => { + return new Promise(resolve => { + simulate.touchstart(map.getCanvas()); + simulate.touchend(map.getCanvas()); + simulate.touchstart(map.getCanvas()); + setTimeout(() => { + simulate.touchend(map.getCanvas()); + map._renderTaskQueue.run(); + resolve(); + }, 300); + }); + }; + + simulateSlowSecondTap().then(() => { + t.notOk(zoom.called); + + t.end(); + }); +}); From 81f7c0c4d27d089049d888a42f890fdf6c270730 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 26 Mar 2019 17:06:42 -0700 Subject: [PATCH 5/9] Increase double-tap maxDelta to 30 --- src/ui/handler/dblclick_zoom.js | 2 +- test/unit/ui/handler/dblclick_zoom.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/handler/dblclick_zoom.js b/src/ui/handler/dblclick_zoom.js index c67ac5eeca2..720bc31f2fd 100644 --- a/src/ui/handler/dblclick_zoom.js +++ b/src/ui/handler/dblclick_zoom.js @@ -72,7 +72,7 @@ class DoubleClickZoomHandler { if (!this.isEnabled()) return; if (e.points.length > 1) return; - const maxDelta = 0; + const maxDelta = 30; if (!this._tapped) { this._tappedPoint = e.points[0]; diff --git a/test/unit/ui/handler/dblclick_zoom.test.js b/test/unit/ui/handler/dblclick_zoom.test.js index ea72e1127e2..0e7823566ef 100644 --- a/test/unit/ui/handler/dblclick_zoom.test.js +++ b/test/unit/ui/handler/dblclick_zoom.test.js @@ -108,7 +108,7 @@ test('DoubleClickZoomHandler does not zoom on double tap if touchstart events ar simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0, clientY: 0}]}); simulate.touchend(map.getCanvas()); setTimeout(() => { - simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0.5, clientY: 0.5}]}); + simulate.touchstart(map.getCanvas(), {touches: [{clientX: 30.5, clientY: 30.5}]}); simulate.touchend(map.getCanvas()); map._renderTaskQueue.run(); resolve(); From b5824b36bb48923a478f833d3a4998e6c0f6b62c Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 26 Mar 2019 17:34:09 -0700 Subject: [PATCH 6/9] Prevent duplicate zoom on dblclick if double-tap zoom is triggered --- src/ui/handler/dblclick_zoom.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ui/handler/dblclick_zoom.js b/src/ui/handler/dblclick_zoom.js index 720bc31f2fd..9c6c273fb1a 100644 --- a/src/ui/handler/dblclick_zoom.js +++ b/src/ui/handler/dblclick_zoom.js @@ -82,6 +82,8 @@ class DoubleClickZoomHandler { const firstTap = this._tappedPoint; if (firstTap && Math.abs(firstTap.x - newTap.x) <= maxDelta && Math.abs(firstTap.y - newTap.y) <= maxDelta) { + e.originalEvent.preventDefault(); // prevent duplicate zoom on dblclick + const onTouchEnd = () => { if (this._tapped) { // make sure we are still within the timeout window this._zoom(e); // pass this touchstart event, as touchend events have no points From 1dabf9bdc2ff492da57161729ba6eca62927e695 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Mon, 1 Apr 2019 12:03:12 -0700 Subject: [PATCH 7/9] Address review comments from @mourner & @asheemmamoowala - Use proper Point obj w/ .dist() method - Remove touchcancel handler on touchend - Attach touchend/cancel handlers with .once() - Move distance threshold to top-level constant, add doc comment - Refactor tests to avoid repetition --- src/ui/handler/dblclick_zoom.js | 17 ++--- test/unit/ui/handler/dblclick_zoom.test.js | 83 ++++++++++------------ 2 files changed, 48 insertions(+), 52 deletions(-) diff --git a/src/ui/handler/dblclick_zoom.js b/src/ui/handler/dblclick_zoom.js index 9c6c273fb1a..81d44776c9d 100644 --- a/src/ui/handler/dblclick_zoom.js +++ b/src/ui/handler/dblclick_zoom.js @@ -4,6 +4,10 @@ import { bindAll } from '../../util/util'; import type Map from '../map'; import type {MapMouseEvent, MapTouchEvent} from '../events'; +import Point from '@mapbox/point-geometry'; + +// maximum distance between two tap Points for them to qualify as a double-tap +const maxDist = 30; /** * The `DoubleClickZoomHandler` allows the user to zoom the map at a point by @@ -14,7 +18,7 @@ class DoubleClickZoomHandler { _enabled: boolean; _active: boolean; _tapped: ?TimeoutID; - _tappedPoint: ?{x: number, y: number}; + _tappedPoint: ?Point; /** * @private @@ -72,8 +76,6 @@ class DoubleClickZoomHandler { if (!this.isEnabled()) return; if (e.points.length > 1) return; - const maxDelta = 30; - if (!this._tapped) { this._tappedPoint = e.points[0]; this._tapped = setTimeout(() => { this._tapped = null; this._tappedPoint = null; }, 300); @@ -81,25 +83,24 @@ class DoubleClickZoomHandler { const newTap = e.points[0]; const firstTap = this._tappedPoint; - if (firstTap && Math.abs(firstTap.x - newTap.x) <= maxDelta && Math.abs(firstTap.y - newTap.y) <= maxDelta) { + if (firstTap && firstTap.dist(newTap) <= maxDist) { e.originalEvent.preventDefault(); // prevent duplicate zoom on dblclick const onTouchEnd = () => { if (this._tapped) { // make sure we are still within the timeout window this._zoom(e); // pass this touchstart event, as touchend events have no points } - this._map.off('touchend', onTouchEnd); + this._map.off('touchcancel', onTouchCancel); this._resetTapped(); }; const onTouchCancel = () => { this._map.off('touchend', onTouchEnd); - this._map.off('touchcancel', onTouchCancel); this._resetTapped(); }; - this._map.on('touchend', onTouchEnd); - this._map.on('touchcancel', onTouchCancel); + this._map.once('touchend', onTouchEnd); + this._map.once('touchcancel', onTouchCancel); } else { // touches are too far apart, don't zoom this._resetTapped(); diff --git a/test/unit/ui/handler/dblclick_zoom.test.js b/test/unit/ui/handler/dblclick_zoom.test.js index 0e7823566ef..d0a3671abe2 100644 --- a/test/unit/ui/handler/dblclick_zoom.test.js +++ b/test/unit/ui/handler/dblclick_zoom.test.js @@ -9,6 +9,20 @@ function createMap(t) { return new Map({ container: DOM.create('div', '', window.document.body) }); } +function simulateDoubleTap(map, delay = 100) { + const canvas = map.getCanvas(); + return new Promise(resolve => { + simulate.touchstart(canvas); + simulate.touchend(canvas); + setTimeout(() => { + simulate.touchstart(canvas); + simulate.touchend(canvas); + map._renderTaskQueue.run(); + resolve(); + }, delay); + }); +} + test('DoubleClickZoomHandler zooms on dblclick event', (t) => { const map = createMap(t); @@ -47,19 +61,6 @@ test('DoubleClickZoomHandler zooms on double tap if touchstart events are < 300m const zoom = t.spy(); map.on('zoom', zoom); - const simulateDoubleTap = () => { - return new Promise(resolve => { - simulate.touchstart(map.getCanvas()); - simulate.touchend(map.getCanvas()); - setTimeout(() => { - simulate.touchstart(map.getCanvas()); - simulate.touchend(map.getCanvas()); - map._renderTaskQueue.run(); - resolve(); - }, 100); - }); - }; - simulateDoubleTap(map, 100).then(() => { t.ok(zoom.called); @@ -75,20 +76,7 @@ test('DoubleClickZoomHandler does not zoom on double tap if touchstart events ar const zoom = t.spy(); map.on('zoom', zoom); - const simulateDelayedDoubleTap = () => { - return new Promise(resolve => { - simulate.touchstart(map.getCanvas()); - simulate.touchend(map.getCanvas()); - setTimeout(() => { - simulate.touchstart(map.getCanvas()); - simulate.touchend(map.getCanvas()); - map._renderTaskQueue.run(); - resolve(); - }, 300); - }); - }; - - simulateDelayedDoubleTap().then(() => { + simulateDoubleTap(map, 300).then(() => { t.equal(zoom.callCount, 0); map.remove(); @@ -103,13 +91,15 @@ test('DoubleClickZoomHandler does not zoom on double tap if touchstart events ar const zoom = t.spy(); map.on('zoom', zoom); + const canvas = map.getCanvas(); + const simulateTwoDifferentTaps = () => { return new Promise(resolve => { - simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0, clientY: 0}]}); - simulate.touchend(map.getCanvas()); + simulate.touchstart(canvas, {touches: [{clientX: 0, clientY: 0}]}); + simulate.touchend(canvas); setTimeout(() => { - simulate.touchstart(map.getCanvas(), {touches: [{clientX: 30.5, clientY: 30.5}]}); - simulate.touchend(map.getCanvas()); + simulate.touchstart(canvas, {touches: [{clientX: 30.5, clientY: 30.5}]}); + simulate.touchend(canvas); map._renderTaskQueue.run(); resolve(); }, 100); @@ -131,24 +121,27 @@ test('DoubleClickZoomHandler zooms on the second touchend event of a double tap' const zoom = t.spy(); map.on('zoom', zoom); - simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0.5, clientY: 0.5}]}); - simulate.touchend(map.getCanvas()); - simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0.5, clientY: 0.5}]}); + const canvas = map.getCanvas(); + const touchOptions = {touches: [{clientX: 0.5, clientY: 0.5}]}; + + simulate.touchstart(canvas, touchOptions); + simulate.touchend(canvas); + simulate.touchstart(canvas, touchOptions); map._renderTaskQueue.run(); t.notOk(zoom.called, 'should not trigger zoom before second touchend'); - simulate.touchcancel(map.getCanvas()); - simulate.touchend(map.getCanvas()); + simulate.touchcancel(canvas); + simulate.touchend(canvas); map._renderTaskQueue.run(); t.notOk(zoom.called, 'should not trigger zoom if second touch is canceled'); - simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0.5, clientY: 0.5}]}); - simulate.touchend(map.getCanvas()); - simulate.touchstart(map.getCanvas(), {touches: [{clientX: 0.5, clientY: 0.5}]}); + simulate.touchstart(canvas, touchOptions); + simulate.touchend(canvas); + simulate.touchstart(canvas, touchOptions); map._renderTaskQueue.run(); t.notOk(zoom.called); - simulate.touchend(map.getCanvas()); + simulate.touchend(canvas); map._renderTaskQueue.run(); t.ok(zoom.called, 'should trigger zoom after second touchend'); @@ -163,13 +156,15 @@ test('DoubleClickZoomHandler does not zoom on double tap if second touchend is > const zoom = t.spy(); map.on('zoom', zoom); + const canvas = map.getCanvas(); + const simulateSlowSecondTap = () => { return new Promise(resolve => { - simulate.touchstart(map.getCanvas()); - simulate.touchend(map.getCanvas()); - simulate.touchstart(map.getCanvas()); + simulate.touchstart(canvas); + simulate.touchend(canvas); + simulate.touchstart(canvas); setTimeout(() => { - simulate.touchend(map.getCanvas()); + simulate.touchend(canvas); map._renderTaskQueue.run(); resolve(); }, 300); From 61362b03c557a37164e457c518fd92bb276f56fa Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Mon, 1 Apr 2019 16:29:05 -0700 Subject: [PATCH 8/9] Clarify comments re passing touchstart vs. -end event --- src/ui/handler/dblclick_zoom.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/handler/dblclick_zoom.js b/src/ui/handler/dblclick_zoom.js index 81d44776c9d..edbd3be70ca 100644 --- a/src/ui/handler/dblclick_zoom.js +++ b/src/ui/handler/dblclick_zoom.js @@ -86,9 +86,9 @@ class DoubleClickZoomHandler { if (firstTap && firstTap.dist(newTap) <= maxDist) { e.originalEvent.preventDefault(); // prevent duplicate zoom on dblclick - const onTouchEnd = () => { + const onTouchEnd = () => { // ignore the touchend event, as it has no point we can zoom to if (this._tapped) { // make sure we are still within the timeout window - this._zoom(e); // pass this touchstart event, as touchend events have no points + this._zoom(e); // pass the original touchstart event, with the tapped point } this._map.off('touchcancel', onTouchCancel); this._resetTapped(); From ae80d83b06da759e149e560c667f58da6e1b9bf2 Mon Sep 17 00:00:00 2001 From: Anjana Vakil Date: Tue, 2 Apr 2019 11:43:47 -0700 Subject: [PATCH 9/9] Fix type-only import --- src/ui/handler/dblclick_zoom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/handler/dblclick_zoom.js b/src/ui/handler/dblclick_zoom.js index edbd3be70ca..e4b5f23d21f 100644 --- a/src/ui/handler/dblclick_zoom.js +++ b/src/ui/handler/dblclick_zoom.js @@ -4,7 +4,7 @@ import { bindAll } from '../../util/util'; import type Map from '../map'; import type {MapMouseEvent, MapTouchEvent} from '../events'; -import Point from '@mapbox/point-geometry'; +import type Point from '@mapbox/point-geometry'; // maximum distance between two tap Points for them to qualify as a double-tap const maxDist = 30;