Skip to content
Snippets Groups Projects
Commit f083e664 authored by Benjamin Vray's avatar Benjamin Vray
Browse files

[FIX] web: fix smooth scroll on drag in iframes


This commit addresses a bug in jQuery Draggable where the 'stop' event
did not trigger a 'mouseup' event outside of the dragged element window
if it was inside an iframe. This issue only occurred in Chrome (Firefox
was not affected).

In mass_mailing, this issue occurred in the email editor when the mouse
was released in the area above the editor. This error also affected the
Sign module, where elements can be dropped into a PDF, and where the
'stop' event of the dragging did not trigger outside of the iframe.

Steps to reproduce the bug in mass_mailing:

- Open the Email Marketing app.
- Create a new mailing.
- Choose the second available email template.
- Click and hold the "drag and drop" button of the first snippet (Your
logo) to start dragging it.
- While dragging the snippet, move the mouse outside of the email editor
iframe.
- Release the mouse button.
- Bug: the drop zones are still present in the DOM, and it is possible
to save the template with them.

opw-3164969

closes odoo/odoo#112979

Signed-off-by: default avatarQuentin Smetz (qsm) <qsm@odoo.com>
parent 5d161fc5
Branches
Tags
No related merge requests found
......@@ -99,6 +99,8 @@ const SmoothScrollOnDrag = Class.extend(mixins.ParentedMixin, {
this.$element = $element;
this.$scrollTarget = $scrollTarget;
this.options = options;
this.targetWindow = this.$element[0].ownerDocument.defaultView;
const insideIframe = this.targetWindow !== window.top;
// Setting optional options to their default value if not provided
this.options.jQueryDraggableOptions = this.options.jQueryDraggableOptions || {};
......@@ -129,9 +131,20 @@ const SmoothScrollOnDrag = Class.extend(mixins.ParentedMixin, {
this.options.jQueryDraggableOptions.scroll = false;
this.options.disableHorizontalScroll = this.options.disableHorizontalScroll || false;
const draggableOptions = Object.assign({}, this.options.jQueryDraggableOptions, {
start: (ev, ui) => this._onSmoothDragStart(ev, ui, this.options.jQueryDraggableOptions.start),
start: (ev, ui) => {
this._onSmoothDragStart(ev, ui, this.options.jQueryDraggableOptions.start);
if (insideIframe) {
this.onParentWindowMouseup = this._onParentWindowMouseup.bind(this);
window.top.addEventListener('mouseup', this.onParentWindowMouseup, {once: true});
}
},
drag: (ev, ui) => this._onSmoothDrag(ev, ui, this.options.jQueryDraggableOptions.drag),
stop: (ev, ui) => this._onSmoothDragStop(ev, ui, this.options.jQueryDraggableOptions.stop),
stop: (ev, ui) => {
if (insideIframe) {
window.top.removeEventListener('mouseup', this.onParentWindowMouseup, {once: true});
}
this._onSmoothDragStop(ev, ui, this.options.jQueryDraggableOptions.stop);
}
});
this.$element.draggable(draggableOptions);
},
......@@ -383,6 +396,17 @@ const SmoothScrollOnDrag = Class.extend(mixins.ParentedMixin, {
onDragEndCallBack.call(ui.helper, ev, ui);
}
},
/**
* Called when the mouse is released outside the page iframe (e.g. the
* editor panel in Website). This is only useful in Chrome, where the 'stop'
* event of jQuery Draggable does not trigger a 'mouseup' event outside of
* the "preview" page iframe.
*
* @private
*/
_onParentWindowMouseup() {
this.targetWindow.document.dispatchEvent(new Event('mouseup'));
},
});
return SmoothScrollOnDrag;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment