mirror of
https://github.com/Leaflet/Leaflet.git
synced 2025-07-20 16:37:08 +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.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', () => {
|
||||
@ -60,7 +61,6 @@ describe('DomEvent.DoubleTapSpec.js', () => {
|
||||
UIEventSimulator.fire('dblclick', container); // native dblclick expected
|
||||
expect(spy.called).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', () => {
|
||||
|
@ -7,20 +7,53 @@ import * as DomEvent from './DomEvent.js';
|
||||
* (see https://github.com/Leaflet/Leaflet/issues/7012#issuecomment-595087386)
|
||||
*/
|
||||
|
||||
function makeDblclick(event) {
|
||||
// in modern browsers `type` cannot be just overridden:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only
|
||||
const newEvent = {};
|
||||
let prop, i;
|
||||
for (i in event) {
|
||||
prop = event[i];
|
||||
newEvent[i] = prop && prop.bind ? prop.bind(event) : prop;
|
||||
function makeDblclick(ev) {
|
||||
let init = {
|
||||
// EventInit
|
||||
bubbles: ev.bubbles,
|
||||
cancelable: ev.cancelable,
|
||||
composed: ev.composed,
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -34,14 +67,14 @@ export function addDoubleTapListener(obj, handler) {
|
||||
// So here we rely on that fact to avoid excessive 'dblclick' simulation when not needed.
|
||||
let last = 0,
|
||||
detail;
|
||||
function simDblclick(e) {
|
||||
if (e.detail !== 1) {
|
||||
detail = e.detail; // keep in sync to avoid false dblclick in some cases
|
||||
function simDblclick(ev) {
|
||||
if (ev.detail !== 1) {
|
||||
detail = ev.detail; // keep in sync to avoid false dblclick in some cases
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.pointerType === 'mouse' ||
|
||||
(e.sourceCapabilities && !e.sourceCapabilities.firesTouchEvents)) {
|
||||
if (ev.pointerType === 'mouse' ||
|
||||
(ev.sourceCapabilities && !ev.sourceCapabilities.firesTouchEvents)) {
|
||||
|
||||
return;
|
||||
}
|
||||
@ -51,7 +84,7 @@ export function addDoubleTapListener(obj, handler) {
|
||||
// This ignores clicks on elements which are a label with a 'for'
|
||||
// attribute (or children of such a label), but not children of
|
||||
// a <input>.
|
||||
const path = DomEvent.getPropagationPath(e);
|
||||
const path = DomEvent.getPropagationPath(ev);
|
||||
if (path.some(el => el instanceof HTMLLabelElement && el.attributes.for) &&
|
||||
!path.some(el => (
|
||||
el instanceof HTMLInputElement ||
|
||||
@ -65,7 +98,7 @@ export function addDoubleTapListener(obj, handler) {
|
||||
if (now - last <= delay) {
|
||||
detail++;
|
||||
if (detail === 2) {
|
||||
handler(makeDblclick(e));
|
||||
ev.target.dispatchEvent(makeDblclick(ev));
|
||||
}
|
||||
} else {
|
||||
detail = 1;
|
||||
|
Reference in New Issue
Block a user