[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#125976

X-original-commit: 142684dbe7e5c9d5c5fc1baa00b1027367a45213
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Signed-off-by: Guillaume Dieleman (gdi) <gdi@odoo.com>
This commit is contained in:
Guillaume Dieleman
2023-06-22 17:10:45 +02:00
committed by Guillaume (gdi)
parent 3dc7099d37
commit a41e7d7ee5
@@ -1863,6 +1863,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');
@@ -2071,6 +2077,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();
@@ -3815,6 +3825,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.
*