(core) Fix double-tap on Android failing to select tapped cell; ensure gestures don't get interpreted as double-tap

Summary:
This solves the issue of double-tapping cells when NOT in mobile mode, which is
caused by delayed simulation of click events. (In mobile mode, modern browsers
don't add a delay either way.)

Also avoid unintended opening of the editor by checking that the double-tap is
on the same cell.

Test Plan: Tested manually on iPhone and Chrome emulator.

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D2727
This commit is contained in:
Dmitry S 2021-02-09 10:05:47 -05:00
parent 6c10a43c5d
commit 8a2a14ce74

View File

@ -20,16 +20,25 @@ const DOUBLE_TAP_INTERVAL_MS = 500;
* - https://github.com/w3c/pointerevents/issues/171
*/
export function onDblClickMatchElem(elem: EventTarget, selector: string, callback: EventCB): void {
// According to https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action, this "removes the
// need for browsers to delay the generation of click events when the user taps the screen".
// Without it, the delay (e.g. on mobile Chrome) prevents cursor from moving on double-tap.
dom.styleElem(elem as HTMLElement, 'touch-action', 'manipulation');
dom.onMatchElem(elem, selector, 'dblclick', (ev, _elem) => {
callback(ev, _elem);
});
let lastTapTime = 0;
let lastTapElem: EventTarget|null = null;
dom.onMatchElem(elem, selector, 'touchend', (ev, _elem) => {
const currentTime = Date.now();
const tapLength = currentTime - lastTapTime;
const sameElem = (_elem === lastTapElem);
lastTapTime = currentTime;
if (tapLength < DOUBLE_TAP_INTERVAL_MS && tapLength > 0) {
lastTapElem = _elem;
// Only consider a gesture a double-tap if it's on the same cell. Otherwise, two-finger
// gestures, such as zooming, may trigger this too.
if (sameElem && tapLength < DOUBLE_TAP_INTERVAL_MS && tapLength > 0) {
ev.preventDefault();
callback(ev, _elem);
}