import {listen} from '../../../../src/ol/events.js'; import Event from '../../../../src/ol/events/Event.js'; import EventTarget from '../../../../src/ol/events/EventTarget.js'; import _ol_has_ from '../../../../src/ol/has.js'; import {assign} from '../../../../src/ol/obj.js'; import PointerEventHandler from '../../../../src/ol/pointer/PointerEventHandler.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 _ol_has_.POINTER = false; _ol_has_.MSPOINTER = false; _ol_has_.TOUCH = true; handler = new PointerEventHandler(target); 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); } });