From 142684dbe7e5c9d5c5fc1baa00b1027367a45213 Mon Sep 17 00:00:00 2001 From: Guillaume Dieleman <gdi@odoo.com> Date: Tue, 24 Jan 2023 15:00:23 +0000 Subject: [PATCH] [IMP] web_editor: add touchscreen support for the editor Before this commit, website and email editing was very limited on devices that have a touchscreen. The blocks tab, the we-lists, ... were unusable. Example of issues (on a device that has a touchscreen): - The users cannot drag & drop snippets in the page. - The users cannot reorder the values of a multiple checkboxes field. - ... This commit allows to handle touchscreen events by translating them into mouse events to allow users to fully use the editor. opw-3195487 closes odoo/odoo#114485 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com> --- .../static/src/js/editor/snippets.editor.js | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index 855a85aaaafe..06ecb1f9a6e4 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -1861,6 +1861,12 @@ var SnippetsMenu = Widget.extend({ // own window and not on the top window lest jquery behave unexpectedly. this.$el = this.window.$(this.$el); this.$el.data('snippetMenu', this); + // We need to activate the touch events to be able to drag and drop + // snippets on devices with a touch screen. + this.__onTouchEvent = this._onTouchEvent.bind(this); + document.addEventListener("touchstart", this.__onTouchEvent, true); + document.addEventListener("touchmove", this.__onTouchEvent, true); + document.addEventListener("touchend", this.__onTouchEvent, true); this.customizePanel = document.createElement('div'); this.customizePanel.classList.add('o_we_customize_panel', 'd-none'); @@ -2063,6 +2069,10 @@ var SnippetsMenu = Widget.extend({ */ destroy: function () { this._super.apply(this, arguments); + // Remove listeners for touch events. + document.removeEventListener("touchstart", this.__onTouchEvent, true); + document.removeEventListener("touchmove", this.__onTouchEvent, true); + document.removeEventListener("touchend", this.__onTouchEvent, true); if (this.$window) { if (this.$snippetEditorArea) { this.$snippetEditorArea.remove(); @@ -3816,6 +3826,34 @@ var SnippetsMenu = Widget.extend({ // snippets could have changed on the page. await this._updateInvisibleDOM(); }, + /** + * Transforms an event coming from a touch screen into a mouse event. + * + * @private + * @param {Event} ev - a touch event + */ + _onTouchEvent(ev) { + if (ev.touches.length > 1) { + // Ignore multi-touch events. + return; + } + const touch = ev.changedTouches[0]; + const touchToMouse = { + touchstart: "mousedown", + touchmove: "mousemove", + touchend: "mouseup" + }; + const simulatedEvent = new MouseEvent(touchToMouse[ev.type], { + screenX: touch.screenX, + screenY: touch.screenY, + clientX: touch.clientX, + clientY: touch.clientY, + button: 0, // left mouse button + bubbles: true, + cancelable: true, + }); + touch.target.dispatchEvent(simulatedEvent); + }, /** * Returns the droppable snippet from which a dropped snippet originates. * -- GitLab