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 93f4aadd5a2..029e833061b 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -2645,7 +2645,8 @@ var SnippetsMenu = Widget.extend({ async _scrollToSnippet($el, $scrollable) { // Don't scroll if $el is added to a visible popup that does not fill // the page (otherwise the page would scroll to a random location). - if ($el.closest('div.modal:not(.s_popup_overflow_page)').length) { + const modalEl = $el[0].closest('.modal'); + if (modalEl && !dom.hasScrollableContent(modalEl)) { return; } return dom.scrollTo($el[0], {extraOffset: 50, $scrollable: $scrollable}); diff --git a/addons/website/static/src/snippets/s_popup/000.js b/addons/website/static/src/snippets/s_popup/000.js index ba6194ed02d..57ac11c3925 100644 --- a/addons/website/static/src/snippets/s_popup/000.js +++ b/addons/website/static/src/snippets/s_popup/000.js @@ -2,6 +2,7 @@ odoo.define('website.s_popup', function (require) { 'use strict'; const config = require('web.config'); +const dom = require('web.dom'); const publicWidget = require('web.public.widget'); const utils = require('web.utils'); @@ -122,16 +123,15 @@ publicWidget.registry.popup = PopupWidget; function _updateScrollbar(ev) { const context = ev.data; - const modalContent = context._element.querySelector('.modal-content'); - const currentOverflow = modalContent.offsetHeight >= window.innerHeight; - if (modalContent && context._isOverflowingWindow !== currentOverflow) { - context._isOverflowingWindow = currentOverflow; + const isOverflowing = dom.hasScrollableContent(context._element); + if (context._isOverflowingWindow !== isOverflowing) { + context._isOverflowingWindow = isOverflowing; context._checkScrollbar(); context._setScrollbar(); - if (context._element.classList.contains('s_popup_overflow_page')) { - $(document.body).addClass('modal-open'); + if (isOverflowing) { + document.body.classList.add('modal-open'); } else { - $(document.body).removeClass('modal-open'); + document.body.classList.remove('modal-open'); context._resetScrollbar(); } } @@ -144,27 +144,41 @@ function _updateScrollbar(ev) { const _baseShowElement = $.fn.modal.Constructor.prototype._showElement; $.fn.modal.Constructor.prototype._showElement = function () { _baseShowElement.apply(this, arguments); - // Update the scrollbar if the content changes or if the window has been - // resized - $(this._element).on('content_changed.update_scrollbar', this, _updateScrollbar); - $(window).on('resize.update_scrollbar', this, _updateScrollbar); - _updateScrollbar({ data: this }); + + if (this._element.classList.contains('s_popup_no_backdrop')) { + // Update the scrollbar if the content changes or if the window has been + // resized. Note this could technically be done for all modals and not + // only the ones with the s_popup_no_backdrop class but that would be + // useless as allowing content scroll while a modal with that class is + // opened is a very specific Odoo behavior. + $(this._element).on('content_changed.update_scrollbar', this, _updateScrollbar); + $(window).on('resize.update_scrollbar', this, _updateScrollbar); + _updateScrollbar({ data: this }); + } }; const _baseHideModal = $.fn.modal.Constructor.prototype._hideModal; $.fn.modal.Constructor.prototype._hideModal = function () { _baseHideModal.apply(this, arguments); + + // Note: do this in all cases, not only for popup with the + // s_popup_no_backdrop class, as the modal may have lost that class during + // edition before being closed. + this._element.classList.remove('s_popup_overflow_page'); + $(this._element).off('content_changed.update_scrollbar'); $(window).off('resize.update_scrollbar'); }; const _baseSetScrollbar = $.fn.modal.Constructor.prototype._setScrollbar; $.fn.modal.Constructor.prototype._setScrollbar = function () { - if (this._element.classList.contains('s_popup_no_backdrop') && !this._isOverflowingWindow) { - this._element.classList.remove('s_popup_overflow_page'); - return; + if (this._element.classList.contains('s_popup_no_backdrop')) { + this._element.classList.toggle('s_popup_overflow_page', !!this._isOverflowingWindow); + + if (!this._isOverflowingWindow) { + return; + } } - this._element.classList.add('s_popup_overflow_page'); return _baseSetScrollbar.apply(this, arguments); };