mirror of
https://github.com/Leaflet/Leaflet.git
synced 2025-07-25 15:38:54 +00:00
Revamp synthetic dblclick event instantiation (#8632)
Signed-off-by: Iván Sánchez Ortega <ivan@sanchezortega.es> Co-authored-by: Florian Bischof <design.falke@gmail.com>
This commit is contained in:

committed by
GitHub

parent
ed39e14fa4
commit
e1ef5761cc
@ -22,7 +22,8 @@ describe('DomEvent.DoubleTapSpec.js', () => {
|
|||||||
|
|
||||||
expect(spy.called).to.be.ok();
|
expect(spy.called).to.be.ok();
|
||||||
expect(spy.calledOnce).to.be.ok();
|
expect(spy.calledOnce).to.be.ok();
|
||||||
expect(spy.lastCall.args[0]._simulated).to.be.ok();
|
expect(spy.lastCall.args[0] instanceof MouseEvent).to.equal(true);
|
||||||
|
expect(spy.lastCall.args[0].isTrusted).to.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not fire dblclick when delay>200', () => {
|
it('does not fire dblclick when delay>200', () => {
|
||||||
@ -60,7 +61,6 @@ describe('DomEvent.DoubleTapSpec.js', () => {
|
|||||||
UIEventSimulator.fire('dblclick', container); // native dblclick expected
|
UIEventSimulator.fire('dblclick', container); // native dblclick expected
|
||||||
expect(spy.called).to.be.ok();
|
expect(spy.called).to.be.ok();
|
||||||
expect(spy.calledOnce).to.be.ok();
|
expect(spy.calledOnce).to.be.ok();
|
||||||
expect(spy.lastCall.args[0]._simulated).not.to.be.ok();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('synthetic dblclick event has expected properties', () => {
|
it('synthetic dblclick event has expected properties', () => {
|
||||||
|
@ -7,20 +7,53 @@ import * as DomEvent from './DomEvent.js';
|
|||||||
* (see https://github.com/Leaflet/Leaflet/issues/7012#issuecomment-595087386)
|
* (see https://github.com/Leaflet/Leaflet/issues/7012#issuecomment-595087386)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function makeDblclick(event) {
|
function makeDblclick(ev) {
|
||||||
// in modern browsers `type` cannot be just overridden:
|
let init = {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only
|
// EventInit
|
||||||
const newEvent = {};
|
bubbles: ev.bubbles,
|
||||||
let prop, i;
|
cancelable: ev.cancelable,
|
||||||
for (i in event) {
|
composed: ev.composed,
|
||||||
prop = event[i];
|
|
||||||
newEvent[i] = prop && prop.bind ? prop.bind(event) : prop;
|
// UIEventInit
|
||||||
|
detail: 2,
|
||||||
|
view: ev.view,
|
||||||
|
|
||||||
|
// mouseEventInit
|
||||||
|
screenX: ev.screenX,
|
||||||
|
screenY: ev.screenY,
|
||||||
|
clientX: ev.clientX,
|
||||||
|
clientY: ev.clientY,
|
||||||
|
ctrlKey: ev.ctrlKey,
|
||||||
|
shiftKey: ev.shiftKey,
|
||||||
|
altKey: ev.altKey,
|
||||||
|
metaKey: ev.metaKey,
|
||||||
|
button: ev.button,
|
||||||
|
buttons: ev.buttons,
|
||||||
|
relatedTarget: ev.relatedTarget,
|
||||||
|
region: ev.region,
|
||||||
|
};
|
||||||
|
|
||||||
|
let newEvent;
|
||||||
|
// The `click` event received should be a PointerEvent - but some
|
||||||
|
// Firefox versions still use MouseEvent.
|
||||||
|
if (ev instanceof PointerEvent) {
|
||||||
|
init = {
|
||||||
|
...init,
|
||||||
|
pointerId: ev.pointerId,
|
||||||
|
width: ev.width,
|
||||||
|
height: ev.height,
|
||||||
|
pressure: ev.pressure,
|
||||||
|
tangentialPressure: ev.tangentialPressure,
|
||||||
|
tiltX: ev.tiltX,
|
||||||
|
tiltY: ev.tiltY,
|
||||||
|
twist: ev.twist,
|
||||||
|
pointerType: ev.pointerType,
|
||||||
|
isPrimary: ev.isPrimary,
|
||||||
|
};
|
||||||
|
newEvent = new PointerEvent('dblclick', init);
|
||||||
|
} else {
|
||||||
|
newEvent = new MouseEvent('dblclick', init);
|
||||||
}
|
}
|
||||||
event = newEvent;
|
|
||||||
newEvent.type = 'dblclick';
|
|
||||||
newEvent.detail = 2;
|
|
||||||
newEvent.isTrusted = false;
|
|
||||||
newEvent._simulated = true; // for debug purposes
|
|
||||||
return newEvent;
|
return newEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,14 +67,14 @@ export function addDoubleTapListener(obj, handler) {
|
|||||||
// So here we rely on that fact to avoid excessive 'dblclick' simulation when not needed.
|
// So here we rely on that fact to avoid excessive 'dblclick' simulation when not needed.
|
||||||
let last = 0,
|
let last = 0,
|
||||||
detail;
|
detail;
|
||||||
function simDblclick(e) {
|
function simDblclick(ev) {
|
||||||
if (e.detail !== 1) {
|
if (ev.detail !== 1) {
|
||||||
detail = e.detail; // keep in sync to avoid false dblclick in some cases
|
detail = ev.detail; // keep in sync to avoid false dblclick in some cases
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.pointerType === 'mouse' ||
|
if (ev.pointerType === 'mouse' ||
|
||||||
(e.sourceCapabilities && !e.sourceCapabilities.firesTouchEvents)) {
|
(ev.sourceCapabilities && !ev.sourceCapabilities.firesTouchEvents)) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -51,7 +84,7 @@ export function addDoubleTapListener(obj, handler) {
|
|||||||
// This ignores clicks on elements which are a label with a 'for'
|
// This ignores clicks on elements which are a label with a 'for'
|
||||||
// attribute (or children of such a label), but not children of
|
// attribute (or children of such a label), but not children of
|
||||||
// a <input>.
|
// a <input>.
|
||||||
const path = DomEvent.getPropagationPath(e);
|
const path = DomEvent.getPropagationPath(ev);
|
||||||
if (path.some(el => el instanceof HTMLLabelElement && el.attributes.for) &&
|
if (path.some(el => el instanceof HTMLLabelElement && el.attributes.for) &&
|
||||||
!path.some(el => (
|
!path.some(el => (
|
||||||
el instanceof HTMLInputElement ||
|
el instanceof HTMLInputElement ||
|
||||||
@ -65,7 +98,7 @@ export function addDoubleTapListener(obj, handler) {
|
|||||||
if (now - last <= delay) {
|
if (now - last <= delay) {
|
||||||
detail++;
|
detail++;
|
||||||
if (detail === 2) {
|
if (detail === 2) {
|
||||||
handler(makeDblclick(e));
|
ev.target.dispatchEvent(makeDblclick(ev));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
detail = 1;
|
detail = 1;
|
||||||
|
Reference in New Issue
Block a user