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 855a85aaaafe1e9165eed0f39e808f0c0ba458d4..06ecb1f9a6e4555e39d76e9be19c0e59453b18d7 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. *