From 57877fd6db4573cb2bce0d4c7cbe0aaa9bd2dcef Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Thu, 8 Jun 2023 14:38:08 +0200 Subject: [PATCH] FIX: on iOS PWA prevents touch to click (#22000) This behavior has been possible for a long time and has been made more in recent commits. On PWA iOS when release the touch after the mobile actions menu has been shown, if the finger was over one of the buttons of the menu, it would trigger a click. This commit should now correctly trap and cancel events. --- .../discourse/modifiers/chat/on-long-press.js | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/plugins/chat/assets/javascripts/discourse/modifiers/chat/on-long-press.js b/plugins/chat/assets/javascripts/discourse/modifiers/chat/on-long-press.js index 6a0d0733dec..68ab69b28f6 100644 --- a/plugins/chat/assets/javascripts/discourse/modifiers/chat/on-long-press.js +++ b/plugins/chat/assets/javascripts/discourse/modifiers/chat/on-long-press.js @@ -34,40 +34,60 @@ export default class ChatOnLongPress extends Modifier { this.onLongPressCancel = onLongPressCancel || (() => {}); element.addEventListener("touchstart", this.handleTouchStart, { - passive: true, + passive: false, + capture: true, }); } @bind onCancel() { cancel(this.timeout); - this.element.removeEventListener("touchmove", this.onCancel); - this.element.removeEventListener("touchend", this.onCancel); - this.element.removeEventListener("touchcancel", this.onCancel); + + this.element.removeEventListener("touchmove", this.onCancel, { + capture: true, + }); + this.element.removeEventListener("touchend", this.onCancel, { + capture: true, + }); + this.element.removeEventListener("touchcancel", this.onCancel, { + capture: true, + }); + this.onLongPressCancel(this.element); } @bind handleTouchStart(event) { if (event.touches.length > 1) { + this.onCancel(); return; } + cancelEvent(event); + this.onLongPressStart(this.element, event); - this.element.addEventListener("touchmove", this.onCancel); - this.element.addEventListener("touchend", this.onCancel); - this.element.addEventListener("touchcancel", this.onCancel); + this.element.addEventListener("touchmove", this.onCancel, { + capture: true, + }); + this.element.addEventListener("touchend", this.onCancel, { + capture: true, + }); + this.element.addEventListener("touchcancel", this.onCancel, { + capture: true, + }); this.timeout = discourseLater(() => { if (this.isDestroying || this.isDestroyed) { return; } - this.onLongPressEnd(this.element, event); this.element.addEventListener("touchend", cancelEvent, { once: true, + capture: true, }); + + this.onLongPressEnd(this.element, event); }, 400); }