Merge pull request #9888 from ahocevar/pep
Use PointerEvent polyfill instead of our own abstraction
This commit is contained in:
@@ -1,11 +1,24 @@
|
||||
import Map from '../../../../src/ol/Map.js';
|
||||
import View from '../../../../src/ol/View.js';
|
||||
import ZoomSlider from '../../../../src/ol/control/ZoomSlider.js';
|
||||
import PointerEvent from '../../../../src/ol/pointer/PointerEvent.js';
|
||||
import Event from '../../../../src/ol/events/Event.js';
|
||||
import EventTarget from '../../../../src/ol/events/Target.js';
|
||||
|
||||
describe('ol.control.ZoomSlider', function() {
|
||||
let map, target, zoomslider;
|
||||
|
||||
const createElement = document.createElement;
|
||||
function createEventElement(type) {
|
||||
const element = createElement.call(document, type);
|
||||
const eventTarget = new EventTarget();
|
||||
element.listeners_ = {};
|
||||
element.dispatching_ = {};
|
||||
element.pendingRemovals_ = {};
|
||||
element.dispatchEvent = eventTarget.dispatchEvent.bind(element);
|
||||
element.addEventListener = eventTarget.addEventListener.bind(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
target = document.createElement('div');
|
||||
document.body.appendChild(target);
|
||||
@@ -102,138 +115,142 @@ describe('ol.control.ZoomSlider', function() {
|
||||
});
|
||||
|
||||
it('[horizontal] handles a drag sequence', function() {
|
||||
document.createElement = createEventElement;
|
||||
const control = new ZoomSlider();
|
||||
map.addControl(control);
|
||||
document.createElement = createElement;
|
||||
map.getView().setZoom(0);
|
||||
control.element.style.width = '500px';
|
||||
control.element.style.height = '10px';
|
||||
control.element.firstChild.style.width = '100px';
|
||||
control.element.firstChild.style.height = '10px';
|
||||
map.renderSync();
|
||||
const dragger = control.dragger_;
|
||||
const event = new PointerEvent('pointerdown', {
|
||||
target: control.element.firstElementChild
|
||||
});
|
||||
const event = new Event();
|
||||
event.type = 'pointerdown',
|
||||
event.target = control.element.firstElementChild;
|
||||
event.clientX = control.widthLimit_;
|
||||
event.clientY = 0;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.currentResolution_).to.be(16);
|
||||
expect(control.dragging_).to.be(true);
|
||||
expect(control.dragListenerKeys_.length).to.be(4);
|
||||
expect(control.dragListenerKeys_.length).to.be(2);
|
||||
event.type = 'pointermove';
|
||||
event.clientX = 6 * control.widthLimit_ / 8;
|
||||
event.clientY = 0;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.currentResolution_).to.be(4);
|
||||
event.type = 'pointermove';
|
||||
event.clientX = 4 * control.widthLimit_ / 8;
|
||||
event.clientY = 0;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
event.type = 'pointerup';
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.currentResolution_).to.be(1);
|
||||
expect(control.dragListenerKeys_.length).to.be(0);
|
||||
expect(control.dragging_).to.be(false);
|
||||
});
|
||||
it('[horizontal] handles a drag sequence ending outside its bounds', function() {
|
||||
document.createElement = createEventElement;
|
||||
const control = new ZoomSlider();
|
||||
map.addControl(control);
|
||||
document.createElement = createElement;
|
||||
map.getView().setZoom(0);
|
||||
control.element.style.width = '500px';
|
||||
control.element.style.height = '10px';
|
||||
control.element.firstChild.style.width = '100px';
|
||||
control.element.firstChild.style.height = '10px';
|
||||
map.renderSync();
|
||||
const dragger = control.dragger_;
|
||||
const event = new PointerEvent('pointerdown', {
|
||||
target: control.element.firstElementChild
|
||||
});
|
||||
const event = new Event();
|
||||
event.type = 'pointerdown';
|
||||
event.target = control.element.firstElementChild;
|
||||
event.clientX = control.widthLimit_;
|
||||
event.clientY = 0;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.currentResolution_).to.be(16);
|
||||
expect(control.dragging_).to.be(true);
|
||||
expect(control.dragListenerKeys_.length).to.be(4);
|
||||
expect(control.dragListenerKeys_.length).to.be(2);
|
||||
event.type = 'pointermove';
|
||||
event.clientX = 6 * control.widthLimit_ / 8;
|
||||
event.clientY = 0;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.currentResolution_).to.be(4);
|
||||
event.type = 'pointermove';
|
||||
event.clientX = 12 * control.widthLimit_ / 8;
|
||||
event.clientY = 0;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
event.type = 'pointerup';
|
||||
event.target = 'document';
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.dragListenerKeys_.length).to.be(0);
|
||||
expect(control.dragging_).to.be(false);
|
||||
expect(control.currentResolution_).to.be(16);
|
||||
});
|
||||
it('[vertical] handles a drag sequence', function() {
|
||||
document.createElement = createEventElement;
|
||||
const control = new ZoomSlider();
|
||||
control.element.style.width = '10px';
|
||||
control.element.style.height = '100px';
|
||||
control.element.firstChild.style.width = '10px';
|
||||
control.element.firstChild.style.height = '20px';
|
||||
map.addControl(control);
|
||||
document.createElement = createElement;
|
||||
map.getView().setZoom(8);
|
||||
map.renderSync();
|
||||
const dragger = control.dragger_;
|
||||
const event = new PointerEvent('pointerdown', {
|
||||
target: control.element.firstElementChild
|
||||
});
|
||||
const event = new Event();
|
||||
event.type = 'pointerdown';
|
||||
event.target = control.element.firstElementChild;
|
||||
event.clientX = 0;
|
||||
event.clientY = 0;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.currentResolution_).to.be(0.0625);
|
||||
expect(control.dragging_).to.be(true);
|
||||
expect(control.dragListenerKeys_.length).to.be(4);
|
||||
expect(control.dragListenerKeys_.length).to.be(2);
|
||||
event.type = 'pointermove';
|
||||
event.clientX = 0;
|
||||
event.clientY = 2 * control.heightLimit_ / 8;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.currentResolution_).to.be(0.25);
|
||||
event.type = 'pointermove';
|
||||
event.clientX = 0;
|
||||
event.clientY = 4 * control.heightLimit_ / 8;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
event.type = 'pointerup';
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.currentResolution_).to.be(1);
|
||||
expect(control.dragListenerKeys_.length).to.be(0);
|
||||
expect(control.dragging_).to.be(false);
|
||||
});
|
||||
it('[vertical] handles a drag sequence ending outside its bounds', function() {
|
||||
document.createElement = createEventElement;
|
||||
const control = new ZoomSlider();
|
||||
control.element.style.width = '10px';
|
||||
control.element.style.height = '100px';
|
||||
control.element.firstChild.style.width = '10px';
|
||||
control.element.firstChild.style.height = '20px';
|
||||
map.addControl(control);
|
||||
document.createElement = createElement;
|
||||
map.getView().setZoom(8);
|
||||
map.renderSync();
|
||||
const dragger = control.dragger_;
|
||||
const event = new PointerEvent('pointerdown', {
|
||||
target: control.element.firstElementChild
|
||||
});
|
||||
const event = new Event();
|
||||
event.type = 'pointerdown';
|
||||
event.target = control.element.firstElementChild;
|
||||
event.clientX = 0;
|
||||
event.clientY = 0;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.currentResolution_).to.be(0.0625);
|
||||
expect(control.dragging_).to.be(true);
|
||||
expect(control.dragListenerKeys_.length).to.be(4);
|
||||
expect(control.dragListenerKeys_.length).to.be(2);
|
||||
event.type = 'pointermove';
|
||||
event.clientX = 0;
|
||||
event.clientY = 2 * control.heightLimit_ / 8;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.currentResolution_).to.be(0.25);
|
||||
event.type = 'pointermove';
|
||||
event.clientX = 0;
|
||||
event.clientY = 12 * control.heightLimit_ / 8;
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
event.type = 'pointerup';
|
||||
dragger.dispatchEvent(event);
|
||||
control.element.dispatchEvent(event);
|
||||
expect(control.currentResolution_).to.be(16);
|
||||
expect(control.dragListenerKeys_.length).to.be(0);
|
||||
expect(control.dragging_).to.be(false);
|
||||
|
||||
@@ -3,7 +3,7 @@ import MapBrowserPointerEvent from '../../../../src/ol/MapBrowserPointerEvent.js
|
||||
import View from '../../../../src/ol/View.js';
|
||||
import DragRotateAndZoom from '../../../../src/ol/interaction/DragRotateAndZoom.js';
|
||||
import VectorLayer from '../../../../src/ol/layer/Vector.js';
|
||||
import PointerEvent from '../../../../src/ol/pointer/PointerEvent.js';
|
||||
import Event from '../../../../src/ol/events/Event.js';
|
||||
import VectorSource from '../../../../src/ol/source/Vector.js';
|
||||
|
||||
describe('ol.interaction.DragRotateAndZoom', function() {
|
||||
@@ -57,9 +57,12 @@ describe('ol.interaction.DragRotateAndZoom', function() {
|
||||
});
|
||||
|
||||
it('does not rotate when rotation is disabled on the view', function() {
|
||||
let event = new MapBrowserPointerEvent('pointermove', map,
|
||||
new PointerEvent('pointermove', {clientX: 20, clientY: 10}, {pointerType: 'mouse'}),
|
||||
true);
|
||||
const pointerEvent = new Event();
|
||||
pointerEvent.type = 'pointermove';
|
||||
pointerEvent.clientX = 20;
|
||||
pointerEvent.clientY = 10;
|
||||
pointerEvent.pointerType = 'mouse';
|
||||
let event = new MapBrowserPointerEvent('pointermove', map, pointerEvent, true);
|
||||
interaction.lastAngle_ = Math.PI;
|
||||
|
||||
let callCount = 0;
|
||||
@@ -85,9 +88,11 @@ describe('ol.interaction.DragRotateAndZoom', function() {
|
||||
callCount++;
|
||||
});
|
||||
|
||||
event = new MapBrowserPointerEvent('pointermove', map,
|
||||
new PointerEvent('pointermove', {clientX: 24, clientY: 16}, {pointerType: 'mouse'}),
|
||||
true);
|
||||
pointerEvent.type = 'pointermove';
|
||||
pointerEvent.clientX = 24;
|
||||
pointerEvent.clientY = 16;
|
||||
pointerEvent.pointerType = 'mouse';
|
||||
event = new MapBrowserPointerEvent('pointermove', map, pointerEvent, true);
|
||||
|
||||
interaction.handleDragEvent(event);
|
||||
expect(callCount).to.be(0);
|
||||
|
||||
@@ -15,7 +15,7 @@ import Polygon from '../../../../src/ol/geom/Polygon.js';
|
||||
import Draw, {createRegularPolygon, createBox} from '../../../../src/ol/interaction/Draw.js';
|
||||
import Interaction from '../../../../src/ol/interaction/Interaction.js';
|
||||
import VectorLayer from '../../../../src/ol/layer/Vector.js';
|
||||
import PointerEvent from '../../../../src/ol/pointer/PointerEvent.js';
|
||||
import Event from '../../../../src/ol/events/Event.js';
|
||||
import VectorSource from '../../../../src/ol/source/Vector.js';
|
||||
|
||||
|
||||
@@ -69,14 +69,14 @@ describe('ol.interaction.Draw', function() {
|
||||
// calculated in case body has top < 0 (test runner with small window)
|
||||
const position = viewport.getBoundingClientRect();
|
||||
const shiftKey = opt_shiftKey !== undefined ? opt_shiftKey : false;
|
||||
const event = new PointerEvent(type, {
|
||||
clientX: position.left + x + width / 2,
|
||||
clientY: position.top + y + height / 2,
|
||||
shiftKey: shiftKey,
|
||||
preventDefault: function() {}
|
||||
}, {
|
||||
pointerType: 'mouse'
|
||||
});
|
||||
const event = new Event();
|
||||
event.type = type;
|
||||
event.clientX = position.left + x + width / 2;
|
||||
event.clientY = position.top + y + height / 2;
|
||||
event.shiftKey = shiftKey;
|
||||
event.preventDefault = function() {};
|
||||
event.pointerType = 'mouse';
|
||||
event.pointerId = 0;
|
||||
const simulatedEvent = new MapBrowserPointerEvent(type, map, event);
|
||||
map.handleMapBrowserEvent(simulatedEvent);
|
||||
return simulatedEvent;
|
||||
|
||||
@@ -2,7 +2,7 @@ import Map from '../../../../src/ol/Map.js';
|
||||
import MapBrowserPointerEvent from '../../../../src/ol/MapBrowserPointerEvent.js';
|
||||
import View from '../../../../src/ol/View.js';
|
||||
import ExtentInteraction from '../../../../src/ol/interaction/Extent.js';
|
||||
import PointerEvent from '../../../../src/ol/pointer/PointerEvent.js';
|
||||
import Event from '../../../../src/ol/events/Event.js';
|
||||
|
||||
describe('ol.interaction.Extent', function() {
|
||||
let map, interaction;
|
||||
@@ -50,14 +50,14 @@ describe('ol.interaction.Extent', function() {
|
||||
// calculated in case body has top < 0 (test runner with small window)
|
||||
const position = viewport.getBoundingClientRect();
|
||||
const shiftKey = opt_shiftKey !== undefined ? opt_shiftKey : false;
|
||||
const pointerEvent = new PointerEvent(type, {
|
||||
type: type,
|
||||
button: button,
|
||||
clientX: position.left + x + width / 2,
|
||||
clientY: position.top - y + height / 2,
|
||||
shiftKey: shiftKey,
|
||||
preventDefault: function() {}
|
||||
});
|
||||
const pointerEvent = new Event();
|
||||
pointerEvent.type = type;
|
||||
pointerEvent.button = button;
|
||||
pointerEvent.clientX = position.left + x + width / 2;
|
||||
pointerEvent.clientY = position.top - y + height / 2;
|
||||
pointerEvent.shiftKey = shiftKey;
|
||||
pointerEvent.pointerId = 0;
|
||||
pointerEvent.preventDefault = function() {};
|
||||
const event = new MapBrowserPointerEvent(type, map, pointerEvent);
|
||||
event.pointerEvent.pointerId = 1;
|
||||
map.handleMapBrowserEvent(event);
|
||||
|
||||
@@ -11,8 +11,8 @@ import Point from '../../../../src/ol/geom/Point.js';
|
||||
import Polygon from '../../../../src/ol/geom/Polygon.js';
|
||||
import Modify, {ModifyEvent} from '../../../../src/ol/interaction/Modify.js';
|
||||
import VectorLayer from '../../../../src/ol/layer/Vector.js';
|
||||
import PointerEvent from '../../../../src/ol/pointer/PointerEvent.js';
|
||||
import VectorSource from '../../../../src/ol/source/Vector.js';
|
||||
import Event from '../../../../src/ol/events/Event.js';
|
||||
|
||||
|
||||
describe('ol.interaction.Modify', function() {
|
||||
@@ -81,19 +81,17 @@ describe('ol.interaction.Modify', function() {
|
||||
const viewport = map.getViewport();
|
||||
// calculated in case body has top < 0 (test runner with small window)
|
||||
const position = viewport.getBoundingClientRect();
|
||||
const pointerEvent = new PointerEvent(type, {
|
||||
type: type,
|
||||
clientX: position.left + x + width / 2,
|
||||
clientY: position.top + y + height / 2,
|
||||
shiftKey: modifiers.shift || false,
|
||||
altKey: modifiers.alt || false,
|
||||
preventDefault: function() {}
|
||||
}, {
|
||||
button: button,
|
||||
isPrimary: true
|
||||
});
|
||||
const pointerEvent = new Event();
|
||||
pointerEvent.type = type;
|
||||
pointerEvent.clientX = position.left + x + width / 2;
|
||||
pointerEvent.clientY = position.top + y + height / 2;
|
||||
pointerEvent.shiftKey = modifiers.shift || false;
|
||||
pointerEvent.altKey = modifiers.alt || false;
|
||||
pointerEvent.pointerId = 1;
|
||||
pointerEvent.preventDefault = function() {};
|
||||
pointerEvent.button = button;
|
||||
pointerEvent.isPrimary = true;
|
||||
const event = new MapBrowserPointerEvent(type, map, pointerEvent);
|
||||
event.pointerEvent.pointerId = 1;
|
||||
map.handleMapBrowserEvent(event);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Map from '../../../../src/ol/Map.js';
|
||||
import MapBrowserPointerEvent from '../../../../src/ol/MapBrowserPointerEvent.js';
|
||||
import PointerEvent from '../../../../src/ol/pointer/PointerEvent.js';
|
||||
import Event from '../../../../src/ol/events/Event.js';
|
||||
import PointerInteraction from '../../../../src/ol/interaction/Pointer.js';
|
||||
|
||||
describe('ol.interaction.Pointer', function() {
|
||||
@@ -12,12 +12,12 @@ describe('ol.interaction.Pointer', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
const type = 'pointerdown';
|
||||
const pointerEvent = new PointerEvent(type, {
|
||||
type: type,
|
||||
preventDefault: function() {
|
||||
defaultPrevented = true;
|
||||
}
|
||||
});
|
||||
const pointerEvent = new Event();
|
||||
pointerEvent.type = type;
|
||||
pointerEvent.pointerId = 0;
|
||||
pointerEvent.preventDefault = function() {
|
||||
defaultPrevented = true;
|
||||
};
|
||||
event = new MapBrowserPointerEvent(type, new Map(), pointerEvent);
|
||||
defaultPrevented = false;
|
||||
});
|
||||
|
||||
@@ -8,7 +8,6 @@ import Polygon from '../../../../src/ol/geom/Polygon.js';
|
||||
import Interaction from '../../../../src/ol/interaction/Interaction.js';
|
||||
import Select from '../../../../src/ol/interaction/Select.js';
|
||||
import VectorLayer from '../../../../src/ol/layer/Vector.js';
|
||||
import PointerEvent from '../../../../src/ol/pointer/PointerEvent.js';
|
||||
import VectorSource from '../../../../src/ol/source/Vector.js';
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import Point from '../../../../src/ol/geom/Point.js';
|
||||
import Translate, {TranslateEvent} from '../../../../src/ol/interaction/Translate.js';
|
||||
import Interaction from '../../../../src/ol/interaction/Interaction.js';
|
||||
import VectorLayer from '../../../../src/ol/layer/Vector.js';
|
||||
import PointerEvent from '../../../../src/ol/pointer/PointerEvent.js';
|
||||
import VectorSource from '../../../../src/ol/source/Vector.js';
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import Map from '../../../src/ol/Map.js';
|
||||
import MapBrowserEventHandler from '../../../src/ol/MapBrowserEventHandler.js';
|
||||
import {listen} from '../../../src/ol/events.js';
|
||||
import {DEVICE_PIXEL_RATIO} from '../../../src/ol/has.js';
|
||||
import PointerEvent from '../../../src/ol/pointer/PointerEvent.js';
|
||||
import Event from '../../../src/ol/events/Event.js';
|
||||
|
||||
describe('ol.MapBrowserEventHandler', function() {
|
||||
describe('#emulateClick_', function() {
|
||||
@@ -36,22 +36,22 @@ describe('ol.MapBrowserEventHandler', function() {
|
||||
});
|
||||
|
||||
it('emulates click', function() {
|
||||
handler.emulateClick_(new PointerEvent('pointerdown', {
|
||||
type: 'mousedown',
|
||||
target: target,
|
||||
clientX: 0,
|
||||
clientY: 0
|
||||
}));
|
||||
const event = new Event();
|
||||
event.type = 'pointerdown';
|
||||
event.target = target,
|
||||
event.clientX = 0;
|
||||
event.clientY = 0;
|
||||
handler.emulateClick_(event);
|
||||
expect(clickSpy.called).to.be.ok();
|
||||
});
|
||||
|
||||
it('emulates singleclick', function() {
|
||||
handler.emulateClick_(new PointerEvent('pointerdown', {
|
||||
type: 'mousedown',
|
||||
target: target,
|
||||
clientX: 0,
|
||||
clientY: 0
|
||||
}));
|
||||
const event = new Event();
|
||||
event.type = 'pointerdown';
|
||||
event.target = target;
|
||||
event.clientX = 0;
|
||||
event.clientY = 0;
|
||||
handler.emulateClick_(event);
|
||||
expect(singleclickSpy.called).to.not.be.ok();
|
||||
expect(dblclickSpy.called).to.not.be.ok();
|
||||
|
||||
@@ -59,32 +59,22 @@ describe('ol.MapBrowserEventHandler', function() {
|
||||
expect(singleclickSpy.calledOnce).to.be.ok();
|
||||
expect(dblclickSpy.called).to.not.be.ok();
|
||||
|
||||
handler.emulateClick_(new PointerEvent('pointerdown', {
|
||||
type: 'mousedown',
|
||||
target: target,
|
||||
clientX: 0,
|
||||
clientY: 0
|
||||
}));
|
||||
handler.emulateClick_(event);
|
||||
expect(singleclickSpy.calledOnce).to.be.ok();
|
||||
expect(dblclickSpy.called).to.not.be.ok();
|
||||
});
|
||||
|
||||
it('emulates dblclick', function() {
|
||||
handler.emulateClick_(new PointerEvent('pointerdown', {
|
||||
type: 'mousedown',
|
||||
target: target,
|
||||
clientX: 0,
|
||||
clientY: 0
|
||||
}));
|
||||
const event = new Event();
|
||||
event.type = 'pointerdown';
|
||||
event.target = target;
|
||||
event.clientX = 0;
|
||||
event.clientY = 0;
|
||||
handler.emulateClick_(event);
|
||||
expect(singleclickSpy.called).to.not.be.ok();
|
||||
expect(dblclickSpy.called).to.not.be.ok();
|
||||
|
||||
handler.emulateClick_(new PointerEvent('pointerdown', {
|
||||
type: 'mousedown',
|
||||
target: target,
|
||||
clientX: 0,
|
||||
clientY: 0
|
||||
}));
|
||||
handler.emulateClick_(event);
|
||||
expect(singleclickSpy.called).to.not.be.ok();
|
||||
expect(dblclickSpy.calledOnce).to.be.ok();
|
||||
|
||||
@@ -107,7 +97,7 @@ describe('ol.MapBrowserEventHandler', function() {
|
||||
});
|
||||
|
||||
it('is an event after handlePointerDown_ has been called', function() {
|
||||
const event = new PointerEvent('pointerdown', {});
|
||||
const event = new Event('pointerdown');
|
||||
handler.handlePointerDown_(event);
|
||||
expect(handler.down_).to.be(event);
|
||||
});
|
||||
@@ -121,65 +111,65 @@ describe('ol.MapBrowserEventHandler', function() {
|
||||
beforeEach(function() {
|
||||
defaultHandler = new MapBrowserEventHandler(new Map({}));
|
||||
moveToleranceHandler = new MapBrowserEventHandler(new Map({}), 8);
|
||||
pointerdownAt0 = new PointerEvent('pointerdown', {}, {
|
||||
clientX: 0,
|
||||
clientY: 0
|
||||
});
|
||||
pointerdownAt0 = new Event();
|
||||
pointerdownAt0.type = 'pointerdown';
|
||||
pointerdownAt0.clientX = 0;
|
||||
pointerdownAt0.clientY = 0;
|
||||
defaultHandler.handlePointerDown_(pointerdownAt0);
|
||||
moveToleranceHandler.handlePointerDown_(pointerdownAt0);
|
||||
});
|
||||
|
||||
it('is not moving if distance is 0', function() {
|
||||
const pointerdownAt0 = new PointerEvent('pointerdown', {}, {
|
||||
clientX: 0,
|
||||
clientY: 0
|
||||
});
|
||||
pointerdownAt0 = new Event();
|
||||
pointerdownAt0.type = 'pointerdown';
|
||||
pointerdownAt0.clientX = 0;
|
||||
pointerdownAt0.clientY = 0;
|
||||
expect(defaultHandler.isMoving_(pointerdownAt0)).to.be(false);
|
||||
});
|
||||
|
||||
it('is moving if distance is 2', function() {
|
||||
const pointerdownAt2 = new PointerEvent('pointerdown', {}, {
|
||||
clientX: DEVICE_PIXEL_RATIO + 1,
|
||||
clientY: DEVICE_PIXEL_RATIO + 1
|
||||
});
|
||||
const pointerdownAt2 = new Event();
|
||||
pointerdownAt2.type = 'pointerdown';
|
||||
pointerdownAt2.clientX = DEVICE_PIXEL_RATIO + 1;
|
||||
pointerdownAt2.clientY = DEVICE_PIXEL_RATIO + 1;
|
||||
expect(defaultHandler.isMoving_(pointerdownAt2)).to.be(true);
|
||||
});
|
||||
|
||||
it('is moving with negative distance', function() {
|
||||
const pointerdownAt2 = new PointerEvent('pointerdown', {}, {
|
||||
clientX: -(DEVICE_PIXEL_RATIO + 1),
|
||||
clientY: -(DEVICE_PIXEL_RATIO + 1)
|
||||
});
|
||||
const pointerdownAt2 = new Event();
|
||||
pointerdownAt2.type = 'pointerdown';
|
||||
pointerdownAt2.clientX = -(DEVICE_PIXEL_RATIO + 1);
|
||||
pointerdownAt2.clientY = -(DEVICE_PIXEL_RATIO + 1);
|
||||
expect(defaultHandler.isMoving_(pointerdownAt2)).to.be(true);
|
||||
});
|
||||
|
||||
it('is not moving if distance is less than move tolerance', function() {
|
||||
const pointerdownAt2 = new PointerEvent('pointerdown', {}, {
|
||||
clientX: DEVICE_PIXEL_RATIO + 1,
|
||||
clientY: DEVICE_PIXEL_RATIO + 1
|
||||
});
|
||||
const pointerdownAt2 = new Event();
|
||||
pointerdownAt2.type = 'pointerdown';
|
||||
pointerdownAt2.clientX = DEVICE_PIXEL_RATIO + 1;
|
||||
pointerdownAt2.clientY = DEVICE_PIXEL_RATIO + 1;
|
||||
expect(moveToleranceHandler.isMoving_(pointerdownAt2)).to.be(false);
|
||||
});
|
||||
|
||||
it('is moving if distance is greater than move tolerance', function() {
|
||||
const pointerdownAt9 = new PointerEvent('pointerdown', {}, {
|
||||
clientX: (DEVICE_PIXEL_RATIO * 8) + 1,
|
||||
clientY: (DEVICE_PIXEL_RATIO * 8) + 1
|
||||
});
|
||||
const pointerdownAt9 = new Event();
|
||||
pointerdownAt9.type = 'pointerdown';
|
||||
pointerdownAt9.clientX = (DEVICE_PIXEL_RATIO * 8) + 1;
|
||||
pointerdownAt9.clientY = (DEVICE_PIXEL_RATIO * 8) + 1;
|
||||
expect(moveToleranceHandler.isMoving_(pointerdownAt9)).to.be(true);
|
||||
});
|
||||
|
||||
it('is moving when moving back close to the down pixel', function() {
|
||||
const pointermoveAt9 = new PointerEvent('pointermove', {}, {
|
||||
clientX: (DEVICE_PIXEL_RATIO * 8) + 1,
|
||||
clientY: (DEVICE_PIXEL_RATIO * 8) + 1
|
||||
});
|
||||
const pointermoveAt9 = new Event();
|
||||
pointermoveAt9.type = 'pointermove';
|
||||
pointermoveAt9.clientX = (DEVICE_PIXEL_RATIO * 8) + 1;
|
||||
pointermoveAt9.clientY = (DEVICE_PIXEL_RATIO * 8) + 1;
|
||||
moveToleranceHandler.handlePointerMove_(pointermoveAt9);
|
||||
expect(moveToleranceHandler.isMoving_(pointermoveAt9)).to.be(true);
|
||||
const pointermoveAt2 = new PointerEvent('pointermove', {}, {
|
||||
clientX: DEVICE_PIXEL_RATIO + 1,
|
||||
clientY: DEVICE_PIXEL_RATIO + 1
|
||||
});
|
||||
const pointermoveAt2 = new Event();
|
||||
pointermoveAt2.type = 'pointermove';
|
||||
pointermoveAt2.clientX = DEVICE_PIXEL_RATIO + 1;
|
||||
pointermoveAt2.clientY = DEVICE_PIXEL_RATIO + 1;
|
||||
moveToleranceHandler.handlePointerMove_(pointermoveAt2);
|
||||
expect(moveToleranceHandler.isMoving_(pointermoveAt2)).to.be(true);
|
||||
});
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
import {listen} from '../../../../src/ol/events.js';
|
||||
import EventTarget from '../../../../src/ol/events/Target.js';
|
||||
import PointerEventHandler from '../../../../src/ol/pointer/PointerEventHandler.js';
|
||||
import TouchSource from '../../../../src/ol/pointer/TouchSource.js';
|
||||
import MouseSource from '../../../../src/ol/pointer/MouseSource.js';
|
||||
import MsSource from '../../../../src/ol/pointer/MsSource.js';
|
||||
import NativeSource from '../../../../src/ol/pointer/NativeSource.js';
|
||||
|
||||
|
||||
describe('ol.pointer.MouseSource', function() {
|
||||
let handler;
|
||||
let target;
|
||||
let eventSpy;
|
||||
let clock;
|
||||
|
||||
beforeEach(function() {
|
||||
clock = sinon.useFakeTimers();
|
||||
target = new EventTarget();
|
||||
|
||||
// make sure that a mouse and touch event source is used
|
||||
const POINTER = false;
|
||||
const MSPOINTER = false;
|
||||
const TOUCH = true;
|
||||
const originalRegisterSources = PointerEventHandler.prototype.registerSources;
|
||||
PointerEventHandler.prototype.registerSources = function() {
|
||||
if (POINTER) {
|
||||
this.registerSource('native', new NativeSource(this));
|
||||
} else if (MSPOINTER) {
|
||||
this.registerSource('ms', new MsSource(this));
|
||||
} else {
|
||||
const mouseSource = new MouseSource(this);
|
||||
this.registerSource('mouse', mouseSource);
|
||||
|
||||
if (TOUCH) {
|
||||
const touchSource = new TouchSource(this, mouseSource);
|
||||
// set the timeout to a lower value, to speed up the tests
|
||||
touchSource.dedupTimeout_ = 100;
|
||||
|
||||
this.registerSource('touch', touchSource);
|
||||
}
|
||||
}
|
||||
|
||||
// register events on the viewport element
|
||||
this.register_();
|
||||
};
|
||||
|
||||
handler = new PointerEventHandler(target);
|
||||
PointerEventHandler.prototype.registerSources = originalRegisterSources;
|
||||
|
||||
eventSpy = sinon.spy();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
clock.restore();
|
||||
handler.dispose();
|
||||
});
|
||||
|
||||
describe('simulated mouse events', function() {
|
||||
it('prevents simulated mouse events', function() {
|
||||
listen(handler, 'pointerdown', eventSpy);
|
||||
|
||||
// simulates that a mouse event is triggered from a touch
|
||||
simulateTouchEvent('touchstart', 10, 20);
|
||||
simulateEvent('mousedown', 10, 20);
|
||||
|
||||
expect(eventSpy.calledOnce).to.be.ok();
|
||||
|
||||
});
|
||||
|
||||
it('dispatches real mouse events', function() {
|
||||
listen(handler, 'pointerdown', eventSpy);
|
||||
|
||||
// the two events are at different positions
|
||||
simulateTouchEvent('touchstart', 10, 20);
|
||||
simulateEvent('mousedown', 10, 50);
|
||||
|
||||
expect(eventSpy.calledTwice).to.be.ok();
|
||||
});
|
||||
|
||||
it('dispatches real mouse events after timeout', function() {
|
||||
listen(handler, 'pointerdown', eventSpy);
|
||||
|
||||
// first simulate a touch event, then a mouse event
|
||||
// at the same position after a timeout
|
||||
simulateTouchEvent('touchstart', 10, 20);
|
||||
clock.tick(150);
|
||||
simulateEvent('mousedown', 10, 20);
|
||||
|
||||
expect(eventSpy.calledTwice).to.be.ok();
|
||||
});
|
||||
});
|
||||
|
||||
function simulateTouchEvent(type, x, y) {
|
||||
const touches = [{
|
||||
identifier: 4,
|
||||
clientX: x,
|
||||
clientY: y,
|
||||
target: target
|
||||
}];
|
||||
|
||||
const event = {
|
||||
type: type,
|
||||
touches: touches,
|
||||
changedTouches: touches
|
||||
};
|
||||
target.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function simulateEvent(type, x, y) {
|
||||
const event = {
|
||||
type: type,
|
||||
clientX: x,
|
||||
clientY: y,
|
||||
target: target
|
||||
};
|
||||
target.dispatchEvent(event);
|
||||
}
|
||||
});
|
||||
@@ -1,190 +0,0 @@
|
||||
import {listen} from '../../../../src/ol/events.js';
|
||||
import EventTarget from '../../../../src/ol/events/Target.js';
|
||||
import MouseSource from '../../../../src/ol/pointer/MouseSource.js';
|
||||
import PointerEvent from '../../../../src/ol/pointer/PointerEvent.js';
|
||||
import PointerEventHandler from '../../../../src/ol/pointer/PointerEventHandler.js';
|
||||
import TouchSource from '../../../../src/ol/pointer/TouchSource.js';
|
||||
import MsSource from '../../../../src/ol/pointer/MsSource.js';
|
||||
import NativeSource from '../../../../src/ol/pointer/NativeSource.js';
|
||||
|
||||
|
||||
describe('ol.pointer.PointerEventHandler', function() {
|
||||
let handler;
|
||||
let target;
|
||||
let eventSpy;
|
||||
|
||||
beforeEach(function() {
|
||||
target = new EventTarget();
|
||||
|
||||
// make sure that a mouse event source is used
|
||||
const POINTER = false;
|
||||
const MSPOINTER = false;
|
||||
const TOUCH = false;
|
||||
const originalRegisterSources = PointerEventHandler.prototype.registerSources;
|
||||
PointerEventHandler.prototype.registerSources = function() {
|
||||
if (POINTER) {
|
||||
this.registerSource('native', new NativeSource(this));
|
||||
} else if (MSPOINTER) {
|
||||
this.registerSource('ms', new MsSource(this));
|
||||
} else {
|
||||
const mouseSource = new MouseSource(this);
|
||||
this.registerSource('mouse', mouseSource);
|
||||
|
||||
if (TOUCH) {
|
||||
this.registerSource('touch', new TouchSource(this, mouseSource));
|
||||
}
|
||||
}
|
||||
|
||||
// register events on the viewport element
|
||||
this.register_();
|
||||
};
|
||||
|
||||
handler = new PointerEventHandler(target);
|
||||
PointerEventHandler.prototype.registerSources = originalRegisterSources;
|
||||
|
||||
eventSpy = sinon.spy();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
handler.dispose();
|
||||
});
|
||||
|
||||
|
||||
describe('constructor', function() {
|
||||
it('registers a least one event source', function() {
|
||||
expect(handler.eventSourceList_.length).to.be.greaterThan(0);
|
||||
expect(handler.eventSourceList_[0]).to.be.a(MouseSource);
|
||||
});
|
||||
});
|
||||
|
||||
function simulateEvent(type, x, y) {
|
||||
const event = {
|
||||
type: type,
|
||||
clientX: x,
|
||||
clientY: y,
|
||||
target: target
|
||||
};
|
||||
target.dispatchEvent(event);
|
||||
}
|
||||
|
||||
describe('pointer down', function() {
|
||||
it('fires pointerdown events', function() {
|
||||
listen(handler, 'pointerdown', eventSpy);
|
||||
simulateEvent('mousedown', 0, 0);
|
||||
expect(eventSpy.calledOnce).to.be.ok();
|
||||
|
||||
const pointerEvent = eventSpy.firstCall.args[0];
|
||||
expect(pointerEvent).to.be.a(PointerEvent);
|
||||
expect(pointerEvent.type).to.be('pointerdown');
|
||||
expect(pointerEvent.pointerId).to.be(1);
|
||||
expect(pointerEvent.pointerType).to.be('mouse');
|
||||
});
|
||||
});
|
||||
|
||||
describe('pointer up', function() {
|
||||
it('fires pointerup events', function() {
|
||||
listen(handler, 'pointerup', eventSpy);
|
||||
simulateEvent('mousedown', 0, 0);
|
||||
simulateEvent('mouseup', 0, 0);
|
||||
expect(eventSpy.calledOnce).to.be.ok();
|
||||
});
|
||||
});
|
||||
|
||||
describe('pointer move', function() {
|
||||
it('fires pointermove events', function() {
|
||||
listen(handler, 'pointermove', eventSpy);
|
||||
simulateEvent('mousemove', 0, 0);
|
||||
expect(eventSpy.calledOnce).to.be.ok();
|
||||
});
|
||||
});
|
||||
|
||||
describe('pointer enter and over', function() {
|
||||
it('fires pointerenter and pointerover events', function() {
|
||||
const enterEventSpy = sinon.spy();
|
||||
const overEventSpy = sinon.spy();
|
||||
|
||||
listen(handler, 'pointerenter', enterEventSpy);
|
||||
listen(handler, 'pointerover', overEventSpy);
|
||||
|
||||
simulateEvent('mouseover', 0, 0);
|
||||
|
||||
expect(enterEventSpy.calledOnce).to.be.ok();
|
||||
expect(overEventSpy.calledOnce).to.be.ok();
|
||||
});
|
||||
});
|
||||
|
||||
describe('pointer leave and out', function() {
|
||||
it('fires pointerleave and pointerout events', function() {
|
||||
const leaveEventSpy = sinon.spy();
|
||||
const outEventSpy = sinon.spy();
|
||||
|
||||
listen(handler, 'pointerleave', leaveEventSpy);
|
||||
listen(handler, 'pointerout', outEventSpy);
|
||||
|
||||
simulateEvent('mouseout', 0, 0);
|
||||
|
||||
expect(leaveEventSpy.calledOnce).to.be.ok();
|
||||
expect(outEventSpy.calledOnce).to.be.ok();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#cloneEvent', function() {
|
||||
it('copies the properties of an event', function() {
|
||||
const event = {
|
||||
type: 'mousedown',
|
||||
target: target,
|
||||
clientX: 1,
|
||||
clientY: 2
|
||||
};
|
||||
const browserEvent = event;
|
||||
|
||||
const eventClone = handler.cloneEvent(browserEvent, event);
|
||||
|
||||
// properties are copied from `event`
|
||||
expect(eventClone.type).to.be('mousedown');
|
||||
expect(eventClone.target).to.be(target);
|
||||
expect(eventClone.clientX).to.be(1);
|
||||
expect(eventClone.clientY).to.be(2);
|
||||
|
||||
// properties are copied from `browserEvent`
|
||||
expect(eventClone.screenX).to.be(0);
|
||||
expect(eventClone.screenY).to.be(0);
|
||||
|
||||
// properties are copied from the defaults
|
||||
expect(eventClone.pointerId).to.be(0);
|
||||
expect(eventClone.pressure).to.be(0);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('#makeEvent', function() {
|
||||
it('makes a new pointer event', function() {
|
||||
const event = {
|
||||
type: 'mousedown',
|
||||
target: target,
|
||||
clientX: 1,
|
||||
clientY: 2
|
||||
};
|
||||
const browserEvent = event;
|
||||
|
||||
const eventClone = handler.cloneEvent(browserEvent, event);
|
||||
const pointerEvent = handler.makeEvent('pointerdown',
|
||||
eventClone, browserEvent);
|
||||
|
||||
expect(pointerEvent.type).to.be('pointerdown');
|
||||
expect(pointerEvent.clientX).to.be(1);
|
||||
expect(pointerEvent.clientY).to.be(2);
|
||||
|
||||
expect(pointerEvent.screenX).to.be(0);
|
||||
expect(pointerEvent.screenY).to.be(0);
|
||||
|
||||
expect(pointerEvent.pointerId).to.be(0);
|
||||
expect(pointerEvent.pressure).to.be(0);
|
||||
|
||||
expect(pointerEvent.preventDefault).to.be.ok();
|
||||
|
||||
expect(pointerEvent).to.be.a(PointerEvent);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,156 +0,0 @@
|
||||
import {listen} from '../../../../src/ol/events.js';
|
||||
import Event from '../../../../src/ol/events/Event.js';
|
||||
import EventTarget from '../../../../src/ol/events/Target.js';
|
||||
import {assign} from '../../../../src/ol/obj.js';
|
||||
import PointerEventHandler from '../../../../src/ol/pointer/PointerEventHandler.js';
|
||||
import TouchSource from '../../../../src/ol/pointer/TouchSource.js';
|
||||
import MouseSource from '../../../../src/ol/pointer/MouseSource.js';
|
||||
import MsSource from '../../../../src/ol/pointer/MsSource.js';
|
||||
import NativeSource from '../../../../src/ol/pointer/NativeSource.js';
|
||||
|
||||
describe('ol.pointer.TouchSource', function() {
|
||||
let handler;
|
||||
let target;
|
||||
let eventSpy;
|
||||
|
||||
beforeEach(function() {
|
||||
target = new EventTarget();
|
||||
|
||||
// make sure that a mouse and touch event source is used
|
||||
const POINTER = false;
|
||||
const MSPOINTER = false;
|
||||
const TOUCH = true;
|
||||
const originalRegisterSources = PointerEventHandler.prototype.registerSources;
|
||||
PointerEventHandler.prototype.registerSources = function() {
|
||||
if (POINTER) {
|
||||
this.registerSource('native', new NativeSource(this));
|
||||
} else if (MSPOINTER) {
|
||||
this.registerSource('ms', new MsSource(this));
|
||||
} else {
|
||||
const mouseSource = new MouseSource(this);
|
||||
this.registerSource('mouse', mouseSource);
|
||||
|
||||
if (TOUCH) {
|
||||
this.registerSource('touch', new TouchSource(this, mouseSource));
|
||||
}
|
||||
}
|
||||
|
||||
// register events on the viewport element
|
||||
this.register_();
|
||||
};
|
||||
|
||||
handler = new PointerEventHandler(target);
|
||||
PointerEventHandler.prototype.registerSources = originalRegisterSources;
|
||||
|
||||
eventSpy = sinon.spy();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
handler.dispose();
|
||||
});
|
||||
|
||||
describe('pointer event creation', function() {
|
||||
it('generates pointer events for each touch contact', function() {
|
||||
listen(handler, 'pointerdown', eventSpy);
|
||||
|
||||
simulateTouchEvent('touchstart', [
|
||||
{identifier: 3, clientX: 10, clientY: 11},
|
||||
{identifier: 4, clientX: 30, clientY: 45}
|
||||
]);
|
||||
|
||||
expect(eventSpy.calledTwice).to.be.ok();
|
||||
|
||||
// pointer event for the first touch contact
|
||||
const pointerEvent1 = eventSpy.firstCall.args[0];
|
||||
expect(pointerEvent1.pointerId).to.be(5);
|
||||
expect(pointerEvent1.pointerType).to.be('touch');
|
||||
expect(pointerEvent1.clientX).to.be(10);
|
||||
expect(pointerEvent1.clientY).to.be(11);
|
||||
|
||||
// pointer event for the second touch contact
|
||||
const pointerEvent2 = eventSpy.secondCall.args[0];
|
||||
expect(pointerEvent2.pointerId).to.be(6);
|
||||
expect(pointerEvent2.pointerType).to.be('touch');
|
||||
expect(pointerEvent2.clientX).to.be(30);
|
||||
expect(pointerEvent2.clientY).to.be(45);
|
||||
|
||||
expect(Object.keys(handler.pointerMap).length).to.be(2);
|
||||
});
|
||||
|
||||
it('creates the right pointer events', function() {
|
||||
listen(handler, 'pointerdown', eventSpy);
|
||||
|
||||
// first touch
|
||||
simulateTouchEvent('touchstart', [
|
||||
{identifier: 3, clientX: 10, clientY: 11}
|
||||
]);
|
||||
expect(eventSpy.calledOnce).to.be.ok();
|
||||
expect(Object.keys(handler.pointerMap).length).to.be(1);
|
||||
|
||||
// second touch (first touch still down)
|
||||
simulateTouchEvent('touchstart', [
|
||||
{identifier: 4, clientX: 30, clientY: 45}
|
||||
], [{identifier: 3}, {identifier: 4}]
|
||||
);
|
||||
expect(eventSpy.calledTwice).to.be.ok();
|
||||
expect(Object.keys(handler.pointerMap).length).to.be(2);
|
||||
|
||||
// first touch moves
|
||||
const moveEventSpy = sinon.spy();
|
||||
listen(handler, 'pointermove', moveEventSpy);
|
||||
|
||||
simulateTouchEvent('touchmove', [
|
||||
{identifier: 3, clientX: 15, clientY: 16}
|
||||
], [{identifier: 3}, {identifier: 4}]
|
||||
);
|
||||
expect(moveEventSpy.calledOnce).to.be.ok();
|
||||
|
||||
// and then both touches go up
|
||||
const upEventSpy = sinon.spy();
|
||||
listen(handler, 'pointerup', upEventSpy);
|
||||
|
||||
simulateTouchEvent('touchend', [
|
||||
{identifier: 3, clientX: 15, clientY: 16},
|
||||
{identifier: 4, clientX: 30, clientY: 45}
|
||||
], [{identifier: 3}, {identifier: 4}]
|
||||
);
|
||||
expect(upEventSpy.calledTwice).to.be.ok();
|
||||
expect(Object.keys(handler.pointerMap).length).to.be(0);
|
||||
});
|
||||
|
||||
it('handles flawed touches', function() {
|
||||
listen(handler, 'pointerdown', eventSpy);
|
||||
|
||||
// first touch
|
||||
simulateTouchEvent('touchstart', [
|
||||
{identifier: 3, clientX: 10, clientY: 11}
|
||||
]);
|
||||
expect(eventSpy.calledOnce).to.be.ok();
|
||||
expect(Object.keys(handler.pointerMap).length).to.be(1);
|
||||
|
||||
// second touch, but the first touch has disappeared
|
||||
const cancelEventSpy = sinon.spy();
|
||||
listen(handler, 'pointercancel', cancelEventSpy);
|
||||
simulateTouchEvent('touchstart', [
|
||||
{identifier: 4, clientX: 30, clientY: 45}
|
||||
], [{identifier: 4}]
|
||||
);
|
||||
expect(eventSpy.calledTwice).to.be.ok();
|
||||
|
||||
// the first (broken) touch is canceled
|
||||
expect(cancelEventSpy.calledOnce).to.be.ok();
|
||||
expect(Object.keys(handler.pointerMap).length).to.be(1);
|
||||
});
|
||||
});
|
||||
|
||||
function simulateTouchEvent(type, changedTouches, touches) {
|
||||
touches = touches !== undefined ? touches : changedTouches;
|
||||
|
||||
const event = new Event(type);
|
||||
assign(event, {
|
||||
touches: touches,
|
||||
changedTouches: changedTouches
|
||||
});
|
||||
target.dispatchEvent(event);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user