From 2ae4e6434112a676c1cfa100e88fd756fe17f000 Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Sat, 8 Oct 2022 22:30:55 +0000 Subject: [PATCH] [FIX] web_editor: restore overlay position computation While working in the current state of the website configuration, the overlay computation was not working anymore in case the scrollbar is moved out of the wrapwrap. Indeed, in that case, the position was wrong by the amount of the page scrolling. While we could include that scrolling value in the equation, this commit chooses to restore the way it worked before the "website-in-backend" merge at [1]: making the overlay be naturally positioned according to the page scrolling wherever the scrollbar is. To do that, the overlay had to be moved inside the content (the website iframe) which has the disadvantage of risking the overlay design being broken by a theme. This solution was chosen as it simplifies the code, and potentially allows for performance improvements in the future: not forcing a position recompute after each scroll (the animation should already be smoother / more performant this way). This will actually be needed for another fix / improvement: the background image overlay has to be in the iframe too. Note: a further commit will move back the scrollbar behavior out of the `#wrapwrap`, this is thus especially needed. [1]: https://github.com/odoo/odoo/commit/31cc10b91dc7762e23b4bde9b945be0c4ce3fe3b closes odoo/odoo#102785 X-original-commit: 872bb20b3ac08cf82613e15e6634a2e7593ccf7a Signed-off-by: Quentin Smetz (qsm) --- .../static/src/js/editor/snippets.editor.js | 28 ++++++++----------- .../static/src/js/editor/snippets.options.js | 2 +- .../static/src/scss/wysiwyg_snippets.scss | 20 +++++++------ .../website/static/src/js/tours/tour_utils.js | 4 +-- .../tests/tours/carousel_content_removal.js | 2 +- .../static/tests/tours/focus_blur_snippets.js | 4 +-- 6 files changed, 29 insertions(+), 31 deletions(-) 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 ea153d41792..3f104113aee 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -380,16 +380,9 @@ var SnippetEditor = Widget.extend({ // Now cover the element const offset = $target.offset(); - // If the target is in an iframe, we need the iframe offset. - const targetWindow = $target[0].ownerDocument.defaultView; - const editorWindow = this.$el[0].ownerDocument.defaultView; - if (targetWindow.frameElement && targetWindow !== editorWindow) { - const { x, y } = targetWindow.frameElement.getBoundingClientRect(); - offset.left += x; - offset.top += y; - } - - var manipulatorOffset = this.$el.parent().offset(); + // The manipulator is supposed to follow the scroll of the content + // naturally without any JS recomputation. + const manipulatorOffset = this.$el.parent().offset(); offset.top -= manipulatorOffset.top; offset.left -= manipulatorOffset.left; this.$el.css({ @@ -929,7 +922,7 @@ var SnippetEditor = Widget.extend({ const rowEl = previousDropzoneEl.parentNode; if (rowEl.classList.contains('o_grid_mode')) { - document.body.removeEventListener('mousemove', self.onDragMove, false); + self.$body[0].removeEventListener('mousemove', self.onDragMove, false); const fromGridToGrid = currentDropzoneEl.classList.contains('oe_grid_zone'); if (fromGridToGrid) { // If we went from a grid dropzone to an other grid one. @@ -1204,7 +1197,7 @@ var SnippetEditor = Widget.extend({ self.dragState.dragHelperEl = dragHelperEl; self.dragState.backgroundGridEl = backgroundGridEl; self.onDragMove = self._onDragMove.bind(self); - document.body.addEventListener('mousemove', self.onDragMove, false); + self.$body[0].addEventListener('mousemove', self.onDragMove, false); } }, out: function () { @@ -1220,7 +1213,7 @@ var SnippetEditor = Widget.extend({ if (sameDropzoneAsCurrent) { if (rowEl.classList.contains('o_grid_mode')) { // Removing the listener + cleaning. - document.body.removeEventListener('mousemove', self.onDragMove, false); + self.$body[0].removeEventListener('mousemove', self.onDragMove, false); gridUtils._gridCleanUp(rowEl, self.$target[0]); self.$target[0].style.removeProperty('z-index'); @@ -1269,7 +1262,7 @@ var SnippetEditor = Widget.extend({ // Case when dropping the column in a grid. // Removing the event listener. - document.body.removeEventListener('mousemove', this.onDragMove, false); + this.$body[0].removeEventListener('mousemove', this.onDragMove, false); // Defining the column grid area with its position. const gridProp = gridUtils._getGridProperties(rowEl); @@ -1303,7 +1296,7 @@ var SnippetEditor = Widget.extend({ // TODO lot of this is duplicated code of the d&d feature of snippets if (!this.dropped) { const { nearest } = this.$body[0].ownerDocument.defaultView.$; - let $el = nearest({x: ui.position.left, y: ui.position.top}, '.oe_drop_zone', {container: document.body}).first(); + let $el = nearest({x: ui.position.left, y: ui.position.top}, '.oe_drop_zone', {container: this.$body[0]}).first(); // Some drop zones might have been disabled. $el = $el.filter(this.$dropZones); if ($el.length) { @@ -1569,7 +1562,7 @@ var SnippetEditor = Widget.extend({ const rowEl = columnEl.parentNode; // Computing the rowEl position. - const rowElTop = rowEl.getBoundingClientRect().top + document.documentElement.scrollTop; + const rowElTop = rowEl.getBoundingClientRect().top; const rowElLeft = rowEl.getBoundingClientRect().left; // Getting the column dimensions. @@ -1809,7 +1802,8 @@ var SnippetsMenu = Widget.extend({ // Prepare snippets editor environment this.$snippetEditorArea = $('
', { id: 'oe_manipulators', - }).insertAfter(this.$el); + }); + this.$body.prepend(this.$snippetEditorArea); // Active snippet editor on click in the page this.$document.on('click.snippets_menu', '*', this._onClick); diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index 3e2a7d63dea..a0658a71ee1 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -7232,7 +7232,7 @@ registry.BackgroundPosition = SnippetOptionWidget.extend({ _onDragBackgroundStart: function (ev) { ev.preventDefault(); this.$bgDragger.addClass('o_we_grabbing'); - const $document = $(document); + const $document = $(this.$target[0].ownerDocument); $document.on('mousemove.bgposition', this._onDragBackgroundMove.bind(this)); $document.one('mouseup', () => { this.$bgDragger.removeClass('o_we_grabbing'); diff --git a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss index 8612f9f3201..8b180b9cfee 100644 --- a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss +++ b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss @@ -18,13 +18,6 @@ body.editor_enable.editor_has_snippets { background-color: rgba(66, 66, 66, 0.4); } } -.editor_has_snippets { - > .oe_overlay.ui-draggable { - .o_handles { - display: none; - } - } -} // Mobile fix for mass mailing @include media-breakpoint-down(lg) { @@ -2291,7 +2284,6 @@ body.editor_enable.editor_has_snippets { &.o_we_background_position_overlay { background-color: rgba(0,0,0,.7); pointer-events: auto; - bottom: 0; .o_we_overlay_content { @include o-grab-cursor; @@ -2301,6 +2293,15 @@ body.editor_enable.editor_has_snippets { } } + .o_we_overlay_buttons { + .btn-primary { + @include button-variant($o-brand-primary, $o-brand-primary); + } + .btn-secondary { + @include button-variant($o-we-color-danger, $o-we-color-danger); + } + } + .o_overlay_background > * { display: block !important; top: 0 !important; @@ -2314,6 +2315,9 @@ body.editor_enable.editor_has_snippets { } } } +.oe_overlay.ui-draggable-dragging .o_handles { + display: none; +} .s-resize-important * { cursor: s-resize !important; diff --git a/addons/website/static/src/js/tours/tour_utils.js b/addons/website/static/src/js/tours/tour_utils.js index 8978208d01f..0864ba9350a 100644 --- a/addons/website/static/src/js/tours/tour_utils.js +++ b/addons/website/static/src/js/tours/tour_utils.js @@ -68,7 +68,7 @@ function selectColorPalette(position = "left") { function changeColumnSize(position = "right") { return { - trigger: `.oe_overlay.ui-draggable.o_we_overlay_sticky.oe_active .o_handle.e`, + trigger: `iframe .oe_overlay.ui-draggable.o_we_overlay_sticky.oe_active .o_handle.e`, content: Markup(_t("Slide this button to change the column size.")), position: position, }; @@ -131,7 +131,7 @@ function changePaddingSize(direction) { position = "bottom"; } return { - trigger: `.oe_overlay.ui-draggable.o_we_overlay_sticky.oe_active .o_handle.${paddingDirection}`, + trigger: `iframe .oe_overlay.ui-draggable.o_we_overlay_sticky.oe_active .o_handle.${paddingDirection}`, content: Markup(_.str.sprintf(_t("Slide this button to change the %s padding"), direction)), consumeEvent: 'mousedown', position: position, diff --git a/addons/website/static/tests/tours/carousel_content_removal.js b/addons/website/static/tests/tours/carousel_content_removal.js index 8e110399b4f..48ecb66e177 100644 --- a/addons/website/static/tests/tours/carousel_content_removal.js +++ b/addons/website/static/tests/tours/carousel_content_removal.js @@ -15,7 +15,7 @@ wTourUtils.registerWebsitePreviewTour("carousel_content_removal", { trigger: "iframe .carousel .carousel-item.active .carousel-content", content: "Select the active carousel item.", }, { - trigger: ".oe_overlay.oe_active .oe_snippet_remove", + trigger: "iframe .oe_overlay.oe_active .oe_snippet_remove", content: "Remove the active carousel item.", }, { diff --git a/addons/website/static/tests/tours/focus_blur_snippets.js b/addons/website/static/tests/tours/focus_blur_snippets.js index 5902c8eff09..9a79cbcc274 100644 --- a/addons/website/static/tests/tours/focus_blur_snippets.js +++ b/addons/website/static/tests/tours/focus_blur_snippets.js @@ -31,8 +31,8 @@ function clickAndCheck(blockID, expected) { }, { content: 'Once the related overlays are enabled/disabled, check that the focus/blur calls have been correct.', trigger: blockID - ? `.oe_overlay.ui-draggable:eq(${blockData.overlayIndex}).oe_active` - : `#oe_manipulators:not(:has(.oe_active))`, + ? `iframe .oe_overlay.ui-draggable:eq(${blockData.overlayIndex}).oe_active` + : `iframe #oe_manipulators:not(:has(.oe_active))`, run: function (actions) { const result = window.focusBlurSnippetsResult; window.focusBlurSnippetsResult = [];