From 7758af933c13003c89493a0e0da1f1e0dd93c4db Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Thu, 28 Mar 2024 16:52:18 +0000 Subject: [PATCH] [FIX] website, *: make code work wherever the main page scroll is *: web, web_editor Follow-up of [1] (see its own explanation for details). This is about fixing the remaining code. In the future, we will probably go even further: - No more wrapwrap element at all - No support of a main scroll which is not left up to the browser (see some more details about that in [2] which explains the many problems which occurred when the scroll was on the wrapwrap element). Those final points have yet to be confirmed though. All in all, this PR should not change any behavior in the standard stable versions. But it will fix bugs in some custo trying to change the page scrolling behavior, while unifying the versions codebases. [1]: https://github.com/odoo/odoo/commit/ffc19547c8da2ef7fee8e2ac743ab99a607dcf90 [2]: https://github.com/odoo/odoo/pull/98429 closes odoo/odoo#163393 X-original-commit: 10df96564fcadd6acde52adf8bf1da32990f3dcf Signed-off-by: Quentin Smetz (qsm) --- addons/web/static/src/legacy/js/libs/jquery.js | 14 ++++++++++++++ .../static/src/js/editor/snippets.editor.js | 4 +--- .../static/src/js/content/snippets.animation.js | 13 ++++++++----- addons/website/static/src/scss/website.scss | 2 +- addons/website/static/src/snippets/s_popup/000.js | 2 +- .../static/src/snippets/s_table_of_content/000.js | 4 +++- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/addons/web/static/src/legacy/js/libs/jquery.js b/addons/web/static/src/legacy/js/libs/jquery.js index 61236bfa485..48336f906a9 100644 --- a/addons/web/static/src/legacy/js/libs/jquery.js +++ b/addons/web/static/src/legacy/js/libs/jquery.js @@ -201,6 +201,20 @@ $.fn.extend({ } return $baseScrollingElement; }, + /** + * @returns {jQuery} + */ + getScrollingTarget(contextItem = window.document) { + const $scrollingElement = contextItem instanceof Element + ? $(contextItem) + : contextItem instanceof jQuery + ? contextItem + : $().getScrollingElement(contextItem); + const document = $scrollingElement[0].ownerDocument; + return $scrollingElement.is(document.scrollingElement) + ? $(document.defaultView) + : $scrollingElement; + }, /** * @return {boolean} */ 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 0473e41ea4a..fc36ed00409 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -2033,9 +2033,7 @@ var SnippetsMenu = Widget.extend({ if (!this.$scrollingElement[0]) { this.$scrollingElement = $(this.ownerDocument).find('.o_editable'); } - this.$scrollingTarget = this.$scrollingElement.is(this.$body[0].ownerDocument.scrollingElement) - ? $(this.$body[0].ownerDocument.defaultView) - : this.$scrollingElement; + this.$scrollingTarget = $().getScrollingTarget(this.$scrollingElement); this._onScrollingElementScroll = throttleForAnimation(() => { for (const editor of this.snippetEditors) { editor.toggleOverlayVisibility(false); diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js index 0cb23a38265..b1f08366ce8 100644 --- a/addons/website/static/src/js/content/snippets.animation.js +++ b/addons/website/static/src/js/content/snippets.animation.js @@ -138,7 +138,7 @@ var AnimationEffect = Class.extend(mixins.ParentedMixin, { this.startEvents = startEvents || 'scroll'; const modalEl = options.enableInModal ? parent.target.closest('.modal') : null; const mainScrollingElement = modalEl ? modalEl : $().getScrollingElement()[0]; - const mainScrollingTarget = mainScrollingElement === document.documentElement ? window : mainScrollingElement; + const mainScrollingTarget = $().getScrollingTarget(mainScrollingElement)[0]; this.$startTarget = $($startTarget ? $startTarget : this.startEvents === 'scroll' ? mainScrollingTarget : window); if (options.getStateCallback) { this._getStateCallback = options.getStateCallback; @@ -1289,8 +1289,9 @@ registry.BottomFixedElement = publicWidget.Widget.extend({ */ async start() { this.$scrollingElement = $().getScrollingElement(); + this.$scrollingTarget = $().getScrollingTarget(this.$scrollingElement); this.__hideBottomFixedElements = debounce(() => this._hideBottomFixedElements(), 100); - this.$scrollingElement.on('scroll.bottom_fixed_element', this.__hideBottomFixedElements); + this.$scrollingTarget.on('scroll.bottom_fixed_element', this.__hideBottomFixedElements); $(window).on('resize.bottom_fixed_element', this.__hideBottomFixedElements); return this._super(...arguments); }, @@ -1299,7 +1300,8 @@ registry.BottomFixedElement = publicWidget.Widget.extend({ */ destroy() { this._super(...arguments); - this.$scrollingElement.off('.bottom_fixed_element'); + this.$scrollingElement.off('.bottom_fixed_element'); // TODO remove in master + this.$scrollingTarget.off('.bottom_fixed_element'); $(window).off('.bottom_fixed_element'); this._restoreBottomFixedElements($('.o_bottom_fixed_element')); }, @@ -1385,6 +1387,7 @@ registry.WebsiteAnimate = publicWidget.Widget.extend({ start() { this.lastScroll = 0; this.$scrollingElement = $().getScrollingElement(); + this.$scrollingTarget = $().getScrollingTarget(this.$scrollingElement); this.$animatedElements = this.$('.o_animate'); // Fix for "transform: none" not overriding keyframe transforms on @@ -1422,7 +1425,7 @@ registry.WebsiteAnimate = publicWidget.Widget.extend({ // for events that otherwise don’t support it. (e.g. useful when // scrolling a modal) this.__onScrollWebsiteAnimate = throttleForAnimation(this._onScrollWebsiteAnimate.bind(this)); - this.$scrollingElement[0].addEventListener('scroll', this.__onScrollWebsiteAnimate, {capture: true}); + this.$scrollingTarget[0].addEventListener('scroll', this.__onScrollWebsiteAnimate, {capture: true}); $(window).on('resize.o_animate, shown.bs.modal.o_animate, slid.bs.carousel.o_animate, shown.bs.tab.o_animate, shown.bs.collapse.o_animate', () => { this.windowsHeight = $(window).height(); @@ -1445,7 +1448,7 @@ registry.WebsiteAnimate = publicWidget.Widget.extend({ }); $(window).off('.o_animate'); this.__onScrollWebsiteAnimate.cancel(); - this.$scrollingElement[0].removeEventListener('scroll', this.__onScrollWebsiteAnimate, {capture: true}); + this.$scrollingTarget[0].removeEventListener('scroll', this.__onScrollWebsiteAnimate, {capture: true}); this.$scrollingElement[0].classList.remove('o_wanim_overflow_xy_hidden'); }, diff --git a/addons/website/static/src/scss/website.scss b/addons/website/static/src/scss/website.scss index 08219276865..8d0323fc3d6 100644 --- a/addons/website/static/src/scss/website.scss +++ b/addons/website/static/src/scss/website.scss @@ -1746,7 +1746,7 @@ input[value*="data-oe-translation-initial-sha"] { .o_wanim_overflow_xy_hidden { overflow-x: hidden !important; - &.o_rtl { + &.o_rtl, .o_rtl { // Fix for Chrome and Edge bug: resolves slow/stuck scrolling during // left-overflowing animations on RTL web pages. Note: using overflow on // the main element hides animated elements outside of it (e.g. "Framed" diff --git a/addons/website/static/src/snippets/s_popup/000.js b/addons/website/static/src/snippets/s_popup/000.js index 6b3b761a882..ebdf36f8bfa 100644 --- a/addons/website/static/src/snippets/s_popup/000.js +++ b/addons/website/static/src/snippets/s_popup/000.js @@ -59,7 +59,7 @@ const SharedPopupWidget = publicWidget.Widget.extend({ // '_hideBottomFixedElements' method and re-display any bottom fixed // elements that may have been hidden (e.g. the live chat button // hidden when the cookies bar is open). - $().getScrollingElement()[0].dispatchEvent(new Event('scroll')); + $().getScrollingTarget()[0].dispatchEvent(new Event('scroll')); } this.el.classList.add('d-none'); diff --git a/addons/website/static/src/snippets/s_table_of_content/000.js b/addons/website/static/src/snippets/s_table_of_content/000.js index a0745c8705d..9592987f118 100644 --- a/addons/website/static/src/snippets/s_table_of_content/000.js +++ b/addons/website/static/src/snippets/s_table_of_content/000.js @@ -14,6 +14,7 @@ const TableOfContent = publicWidget.Widget.extend({ this._stripNavbarStyles(); await this._super(...arguments); this.$scrollingElement = this.$target.closest(".s_table_of_content").closestScrollable(); + this.$scrollingTarget = $().getScrollingTarget(this.$scrollingElement); this.previousPosition = -1; this._updateTableOfContentNavbarPosition(); this._updateTableOfContentNavbarPositionBound = this._updateTableOfContentNavbarPosition.bind(this); @@ -68,7 +69,8 @@ const TableOfContent = publicWidget.Widget.extend({ position += isHorizontalNavbar ? this.$el.outerHeight() : 0; this.$el.find('.s_table_of_content_navbar').css('maxHeight', isHorizontalNavbar ? '' : `calc(100vh - ${position + 40}px)`); if (this.previousPosition !== position) { - new ScrollSpy(this.$scrollingElement, { + const target = this.$scrollingTarget[0]; + new ScrollSpy(target instanceof Window ? target.document.body : target, { target: this.$el.find('.s_table_of_content_navbar'), method: 'offset', offset: position + 100,