/
githubmirror
/
Leaflet
Обзор
Документация
Войти
/
githubmirror
/
Leaflet
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
spec/suites/map/handler/DragHandlerSpec.js
400 строк
12 KB
Iván Sánchez Ortega
Use setPointerCapture/releasePointerCapture globally (#10150)
03 апр 2026, 17:55
Не верифицирован
03 апр 2026, 17:55
c784d58
Код
Авторство
О чём код?
import {expect} from 'chai'; import {DomUtil, LatLng, LeafletMap, Marker, Point} from 'leaflet'; import Hand from 'prosthetic-hand'; import sinon from 'sinon'; import UIEventSimulator from 'ui-event-simulator'; import {createContainer, removeMapContainer, pointerEventType} from '../../SpecHelper.js'; describe('DragHandler', () => { let container, map; beforeEach(() => { container = createContainer(); map = undefined; }); afterEach(() => { removeMapContainer(map, container); }); describe('#addHook', () => { it('calls the map with dragging enabled', () => { map = new LeafletMap(container, { dragging: true }); expect(map.dragging.enabled()).to.be.true; map.setView([0, 0], 0); expect(map.dragging.enabled()).to.be.true; }); it('calls the map with dragging and worldCopyJump enabled', () => { map = new LeafletMap(container, { dragging: true, worldCopyJump: true }); expect(map.dragging.enabled()).to.be.true; map.setView([0, 0], 0); expect(map.dragging.enabled()).to.be.true; }); it('calls the map with dragging disabled and worldCopyJump enabled; ' + 'enables dragging after setting center and zoom', () => { map = new LeafletMap(container, { dragging: false, worldCopyJump: true }); expect(map.dragging.enabled()).to.be.false; map.setView([0, 0], 0); map.dragging.enable(); expect(map.dragging.enabled()).to.be.true; }); }); class MyMap extends LeafletMap { _getPosition() { return DomUtil.getPosition(this.dragging._draggable._element); } getOffset() { return this._getPosition().subtract(this._initialPos); } } MyMap.addInitHook('on', 'load', function () { this._initialPos = this._getPosition(); }); describe('pointer events', () => { it('change the center of the map', (done) => { map = new MyMap(container, { dragging: true, inertia: false }); map.setView([0, 0], 1); const start = new Point(200, 200); const offset = new Point(256, 32); const finish = start.add(offset); const hand = new Hand({timing: 'fastframe'}); hand.addEventListener('stop', () => { expect(map.getOffset()).to.eql(offset); expect(map.getZoom()).to.equal(1); expect(map.getCenter()).to.be.nearLatLng([21.943045533, -180]); done(); }); const pointer = hand.growFinger('pointer'); pointer.moveTo(start.x, start.y, 0) .down().moveBy(5, 0, 20).moveTo(finish.x, finish.y, 1000).up(); }); describe('in CSS scaled container', () => { const scale = new Point(2, 1.5); beforeEach(() => { container.style.webkitTransformOrigin = 'top left'; container.style.webkitTransform = `scale(${scale.x}, ${scale.y})`; }); it('change the center of the map, compensating for CSS scale', (done) => { map = new MyMap(container, { dragging: true, inertia: false }); map.setView([0, 0], 1); const start = new Point(200, 200); const offset = new Point(56, 32); const finish = start.add(offset); const hand = new Hand({timing: 'fastframe'}); hand.addEventListener('stop', () => { expect(map.getOffset()).to.eql(offset); expect(map.getZoom()).to.equal(1); expect(map.getCenter()).to.be.nearLatLng([21.943045533, -39.375]); done(); }); const pointer = hand.growFinger('pointer'); const startScaled = start.scaleBy(scale); const finishScaled = finish.scaleBy(scale); pointer.moveTo(startScaled.x, startScaled.y, 0) .down().moveBy(5, 0, 20).moveTo(finishScaled.x, finishScaled.y, 1000).up(); }); }); it('does not change the center of the map when pointer is moved less than the drag threshold', (done) => { map = new LeafletMap(container, { dragging: true, inertia: false }); const originalCenter = new LatLng(0, 0); map.setView(originalCenter.clone(), 1); const spy = sinon.spy(); map.on('drag', spy); const hand = new Hand({timing: 'fastframe'}); hand.addEventListener('stop', () => { expect(map.getZoom()).to.equal(1); // Expect center point to be the same as before the click expect(map.getCenter()).to.eql(originalCenter); expect(spy.callCount).to.eql(0); // No drag event should have been fired. done(); }); const pointer = hand.growFinger('pointer'); // We move 2 pixels to stay below the default 3-pixel threshold of // Draggable. This should result in a click and not a drag. pointer.moveTo(200, 200, 0) .down().moveBy(1, 0, 20).moveBy(1, 0, 200).up(); }); it('does not trigger preclick nor click', (done) => { map = new LeafletMap(container, { dragging: true, inertia: false }); map.setView([0, 0], 1); const clickSpy = sinon.spy(); const preclickSpy = sinon.spy(); const dragSpy = sinon.spy(); map.on('click', clickSpy); map.on('preclick', preclickSpy); map.on('drag', dragSpy); const hand = new Hand({timing: 'fastframe'}); hand.addEventListener('stop', () => { // A real user scenario would trigger a click on pointerup. // We want to be sure we are cancelling it after a drag. UIEventSimulator.fire('click', container); expect(dragSpy.called).to.be.true; expect(clickSpy.called).to.be.false; expect(preclickSpy.called).to.be.false; done(); }); const pointer = hand.growFinger('pointer'); pointer.moveTo(200, 200, 0) .down().moveBy(5, 0, 20).moveTo(456, 232, 200).up(); }); it('does not trigger preclick nor click when dragging on top of a static marker', (done) => { container.style.width = container.style.height = '600px'; map = new LeafletMap(container, { dragging: true, inertia: false }); map.setView([0, 0], 1); const marker = new Marker(map.getCenter()).addTo(map); const clickSpy = sinon.spy(); const preclickSpy = sinon.spy(); const markerDragSpy = sinon.spy(); const mapDragSpy = sinon.spy(); map.on('click', clickSpy); map.on('preclick', preclickSpy); map.on('drag', mapDragSpy); marker.on('click', clickSpy); marker.on('preclick', preclickSpy); marker.on('drag', markerDragSpy); const hand = new Hand({timing: 'fastframe'}); hand.addEventListener('stop', () => { // A real user scenario would trigger a click on pointerup. // We want to be sure we are cancelling it after a drag. UIEventSimulator.fire('click', container); expect(mapDragSpy.called).to.be.true; expect(markerDragSpy.called).to.be.false; expect(clickSpy.called).to.be.false; expect(preclickSpy.called).to.be.false; done(); }); const pointer = hand.growFinger('pointer'); // We move 5 pixels first to overcome the 3-pixel threshold of // Draggable. pointer.moveTo(300, 280, 0) .down().moveBy(5, 0, 20).moveBy(20, 20, 100).up(); }); it('does not trigger preclick nor click when dragging a marker', (done) => { container.style.width = container.style.height = '600px'; map = new LeafletMap(container, { dragging: true, inertia: false }); map.setView([0, 0], 1); const marker = new Marker(map.getCenter(), {draggable: true}).addTo(map); const clickSpy = sinon.spy(); const preclickSpy = sinon.spy(); const markerDragSpy = sinon.spy(); const mapDragSpy = sinon.spy(); map.on('click', clickSpy); map.on('preclick', preclickSpy); map.on('drag', mapDragSpy); marker.on('click', clickSpy); marker.on('preclick', preclickSpy); marker.on('drag', markerDragSpy); const hand = new Hand({timing: 'fastframe'}); hand.addEventListener('stop', () => { // A real user scenario would trigger a click on pointerup. // We want to be sure we are cancelling it after a drag. UIEventSimulator.fire('click', marker._icon); expect(markerDragSpy.called).to.be.true; expect(mapDragSpy.called).to.be.false; expect(clickSpy.called).to.be.false; expect(preclickSpy.called).to.be.false; done(); }); const pointer = hand.growFinger('pointer'); // We move 5 pixels first to overcome the 3-pixel threshold of // Draggable. pointer.moveTo(300, 280, 0) .down().moveBy(5, 0, 20).moveBy(50, 50, 100).up(); }); it('does not change the center of the map when drag is disabled on click', (done) => { map = new LeafletMap(container, { dragging: true, inertia: false }); const originalCenter = new LatLng(0, 0); map.setView(originalCenter.clone(), 1); map.on('pointerdown', () => { map.dragging.disable(); }); const spy = sinon.spy(); map.on('drag', spy); const hand = new Hand({timing: 'fastframe'}); hand.addEventListener('stop', () => { expect(map.getZoom()).to.equal(1); // Expect center point to be the same as before the click expect(map.getCenter()).to.eql(originalCenter); expect(spy.callCount).to.eql(0); // No drag event should have been fired. done(); }); const pointer = hand.growFinger('pointer'); // We move 5 pixels first to overcome the 3-pixel threshold of // Draggable. pointer.moveTo(200, 200, 0) .down().moveBy(5, 0, 20).moveBy(256, 32, 200).up(); }); }); describe('touch events', () => { it.skipIfNotTouch('change the center of the map', (done) => { map = new MyMap(container, { dragging: true, inertia: false }); map.setView([0, 0], 1); const start = new Point(200, 200); const offset = new Point(256, 32); const finish = start.add(offset); const hand = new Hand({timing: 'fastframe'}); hand.addEventListener('stop', () => { expect(map.getOffset()).to.eql(offset); expect(map.getZoom()).to.equal(1); expect(map.getCenter()).to.be.nearLatLng([21.943045533, -180]); done(); }); const toucher = hand.growFinger(...pointerEventType); toucher.moveTo(start.x, start.y, 0) .down().moveBy(5, 0, 20).moveTo(finish.x, finish.y, 1000).up(); }); it.skipIfNotTouch('does not change the center of the map when finger is moved less than the drag threshold', (done) => { map = new LeafletMap(container, { dragging: true, inertia: false }); const originalCenter = new LatLng(0, 0); map.setView(originalCenter, 1); const spy = sinon.spy(); map.on('drag', spy); const hand = new Hand({timing: 'fastframe'}); hand.addEventListener('stop', () => { expect(map.getZoom()).to.equal(1); // Expect center point to be the same as before the click expect(map.getCenter().equals(originalCenter)).to.be.true; // small margin of error allowed expect(spy.callCount).to.eql(0); // No drag event should have been fired. done(); }); const toucher = hand.growFinger(...pointerEventType); // We move 2 pixels to stay below the default 3-pixel threshold of // Draggable. This should result in a click and not a drag. toucher.moveTo(200, 200, 0) .down().moveBy(1, 0, 20).moveBy(1, 0, 200).up(); }); it.skipIfNotTouch('reset itself after pointerup', (done) => { map = new LeafletMap(container, { dragging: true, inertia: false, zoomAnimation: false // If true, the test has to wait extra 250msec }); map.setView([0, 0], 1); // Change default events order to make the tap coming before the pinchZoom. // See #4315 map.dragging.disable(); map.dragging.enable(); let center, zoom; function savePos() { center = map.getCenter(); zoom = map.getZoom(); } const pointerHand = new Hand({timing: 'fastframe'}); pointerHand.addEventListener('start', savePos); pointerHand.addEventListener('stop', () => { expect(map.getCenter()).to.eql(center); expect(map.getZoom()).to.eql(zoom); done(); }); const pointer = pointerHand.growFinger('pointer', {pointerType: 'touch'}); const hand = new Hand({timing: 'fastframe'}); hand.addEventListener('start', savePos); hand.addEventListener('stop', () => { expect(map.getCenter()).not.to.eql(center); expect(map.getZoom()).not.to.eql(zoom); pointer.moveTo(220, 220, 0).moveBy(200, 0, 2000); }); const f1 = hand.growFinger('pointer', {pointerType: 'touch'}); const f2 = hand.growFinger('pointer', {pointerType: 'touch'}); hand.sync(5); f1.moveTo(275, 300, 0) .down().moveBy(-200, 0, 1000).up(); // This finger should touch me map after the other one. f2.wait(10).moveTo(325, 300, 0) .down().moveBy(210, 0, 1000).up(); }); }); });