Skip to content

Commit

Permalink
Fix an iOS15 issue where Safari tab bar interrupts panning (#11084) (#…
Browse files Browse the repository at this point in the history
…11089)

* fix an iOS15 issue where map stops when panning

* fix tests and lint

* Test drag pan handler does not end interaction on resize

* Move blur event reset into non-touch handlers (#11087)

* Move blur event reset into non-touch handlers

* Fix linter

* Fix/amend unit tests

* Flush task queue in rotate test

Co-authored-by: Ricky Reusser <ricky.reusser@mapbox.com>
Co-authored-by: Ricky Reusser <rreusser@users.noreply.github.com>

Co-authored-by: Vladimir Agafonkin <agafonkin@gmail.com>
  • Loading branch information
rreusser and mourner committed Oct 6, 2021
1 parent b14396f commit a884ab3
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/ui/handler/box_zoom.js
Expand Up @@ -153,6 +153,10 @@ class BoxZoomHandler {
}
}

blur() {
this.reset();
}

reset() {
this._active = false;

Expand Down
4 changes: 4 additions & 0 deletions src/ui/handler/click_zoom.js
Expand Up @@ -16,6 +16,10 @@ export default class ClickZoomHandler {
this._active = false;
}

blur() {
this.reset();
}

dblclick(e: MouseEvent, point: Point) {
e.preventDefault();
return {
Expand Down
4 changes: 4 additions & 0 deletions src/ui/handler/keyboard.js
Expand Up @@ -45,6 +45,10 @@ class KeyboardHandler {
this._rotationDisabled = false;
}

blur() {
this.reset();
}

reset() {
this._active = false;
}
Expand Down
4 changes: 4 additions & 0 deletions src/ui/handler/mouse.js
Expand Up @@ -31,6 +31,10 @@ class MouseHandler {
this._clickTolerance = options.clickTolerance || 1;
}

blur() {
this.reset();
}

reset() {
this._active = false;
this._moved = false;
Expand Down
4 changes: 4 additions & 0 deletions src/ui/handler/scroll_zoom.js
Expand Up @@ -353,6 +353,10 @@ class ScrollZoomHandler {
return easing;
}

blur() {
this.reset();
}

reset() {
this._active = false;
}
Expand Down
5 changes: 0 additions & 5 deletions src/ui/handler_manager.js
Expand Up @@ -344,11 +344,6 @@ class HandlerManager {

handleEvent(e: InputEvent | RenderFrameEvent, eventName?: string) {

if (e.type === 'blur') {
this.stop(true);
return;
}

this._updatingCamera = true;
assert(e.timeStamp !== undefined);

Expand Down
8 changes: 4 additions & 4 deletions src/ui/map.js
Expand Up @@ -691,9 +691,10 @@ class Map extends Camera {
* if (mapDiv.style.visibility === true) map.resize();
*/
resize(eventData?: Object) {
const dimensions = this._containerDimensions();
const width = dimensions[0];
const height = dimensions[1];
const [width, height] = this._containerDimensions();

// do nothing if container remained the same size
if (width === this.transform.width && height === this.transform.height) return this;

this._resizeCanvas(width, height);

Expand All @@ -702,7 +703,6 @@ class Map extends Camera {

const fireMoving = !this._moving;
if (fireMoving) {
this.stop();
this.fire(new Event('movestart', eventData))
.fire(new Event('move', eventData));
}
Expand Down
4 changes: 4 additions & 0 deletions test/unit/ui/control/attribution.test.js
Expand Up @@ -37,6 +37,7 @@ test('AttributionControl appears in the position specified by the position optio

test('AttributionControl appears in compact mode if compact option is used', (t) => {
const map = createMap(t);
Object.defineProperty(map.getContainer(), 'getBoundingClientRect', {value: () => ({height: 200, width: 700})});
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 700, configurable: true});

let attributionControl = new AttributionControl({
Expand All @@ -49,6 +50,7 @@ test('AttributionControl appears in compact mode if compact option is used', (t)
t.equal(container.querySelectorAll('.mapboxgl-ctrl-attrib.mapboxgl-compact').length, 1);
map.removeControl(attributionControl);

Object.defineProperty(map.getContainer(), 'getBoundingClientRect', {value: () => ({height: 200, width: 600})});
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 600, configurable: true});
attributionControl = new AttributionControl({
compact: false
Expand All @@ -61,13 +63,15 @@ test('AttributionControl appears in compact mode if compact option is used', (t)

test('AttributionControl appears in compact mode if container is less then 640 pixel wide', (t) => {
const map = createMap(t);
Object.defineProperty(map.getContainer(), 'getBoundingClientRect', {value: () => ({height: 200, width: 700})});
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 700, configurable: true});
map.addControl(new AttributionControl());

const container = map.getContainer();

t.equal(container.querySelectorAll('.mapboxgl-ctrl-attrib:not(.mapboxgl-compact)').length, 1);

Object.defineProperty(map.getContainer(), 'getBoundingClientRect', {value: () => ({height: 200, width: 600})});
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 600, configurable: true});
map.resize();

Expand Down
4 changes: 4 additions & 0 deletions test/unit/ui/control/logo.test.js
Expand Up @@ -104,12 +104,16 @@ test('LogoControl appears in compact mode if container is less then 250 pixel wi
const map = createMap(t);
const container = map.getContainer();

Object.defineProperty(map.getContainer(), 'getBoundingClientRect', {value: () => ({height: 200, width: 255})});
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 255, configurable: true});
map.resize();

t.equal(container.querySelectorAll('.mapboxgl-ctrl-logo:not(.mapboxgl-compact)').length, 1);

Object.defineProperty(map.getContainer(), 'getBoundingClientRect', {value: () => ({height: 200, width: 245})});
Object.defineProperty(map.getCanvasContainer(), 'offsetWidth', {value: 245, configurable: true});
map.resize();

t.equal(container.querySelectorAll('.mapboxgl-ctrl-logo.mapboxgl-compact').length, 1);

t.end();
Expand Down
37 changes: 36 additions & 1 deletion test/unit/ui/handler/drag_pan.test.js
Expand Up @@ -151,13 +151,15 @@ test('DragPanHandler ends a mouse-triggered drag if the window blurs', (t) => {
map._renderTaskQueue.run();

simulate.blur(window);
map._renderTaskQueue.run();

t.equal(dragend.callCount, 1);

map.remove();
t.end();
});

test('DragPanHandler ends a touch-triggered drag if the window blurs', (t) => {
test('DragPanHandler does not end a touch-triggered drag if the window blurs', (t) => {
const map = createMap(t);
const target = map.getCanvas();

Expand All @@ -171,7 +173,40 @@ test('DragPanHandler ends a touch-triggered drag if the window blurs', (t) => {
map._renderTaskQueue.run();

simulate.blur(window);
map._renderTaskQueue.run();

t.equal(dragend.callCount, 0);

map.remove();
t.end();
});

test('DragPanHandler does not end a touch-triggered drag if the window resizes', (t) => {
const map = createMap(t);
const target = map.getCanvas();

const dragend = t.spy();
map.on('dragend', dragend);

const drag = t.spy();
map.on('drag', drag);

simulate.touchstart(map.getCanvas(), {touches: [{target, clientX: 0, clientY: 0}]});
map._renderTaskQueue.run();

simulate.touchmove(map.getCanvas(), {touches: [{target, clientX: 10, clientY: 10}]});
map._renderTaskQueue.run();

map.resize();

simulate.touchmove(map.getCanvas(), {touches: [{target, clientX: 20, clientY: 10}]});
map._renderTaskQueue.run();

simulate.touchend(map.getCanvas());
map._renderTaskQueue.run();

t.equal(dragend.callCount, 1);
t.equal(drag.callCount, 2);

map.remove();
t.end();
Expand Down
2 changes: 2 additions & 0 deletions test/unit/ui/handler/drag_rotate.test.js
Expand Up @@ -492,6 +492,8 @@ test('DragRotateHandler ends rotation if the window blurs (#3389)', (t) => {
t.equal(rotate.callCount, 1);

simulate.blur(window);
map._renderTaskQueue.run();

t.equal(rotateend.callCount, 1);

map.remove();
Expand Down
32 changes: 32 additions & 0 deletions test/unit/ui/map.test.js
Expand Up @@ -764,10 +764,42 @@ test('Map', (t) => {
t.end();
});

t.test('does nothing if container size is the same', (t) => {
const map = createMap(t);

t.spy(map.transform, 'resize');
t.spy(map.painter, 'resize');

map.resize();

t.notOk(map.transform.resize.called);
t.notOk(map.painter.resize.called);

t.end();
});

t.test('does not call stop on resize', (t) => {
const map = createMap(t);

Object.defineProperty(map.getContainer(), 'getBoundingClientRect',
{value: () => ({height: 250, width: 250})});

t.spy(map, 'stop');

map.resize();

t.notOk(map.stop.called);

t.end();
});

t.test('fires movestart, move, resize, and moveend events', (t) => {
const map = createMap(t),
events = [];

Object.defineProperty(map.getContainer(), 'getBoundingClientRect',
{value: () => ({height: 250, width: 250})});

['movestart', 'move', 'resize', 'moveend'].forEach((event) => {
map.on(event, (e) => {
events.push(e.type);
Expand Down

0 comments on commit a884ab3

Please sign in to comment.