[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) <qsm@odoo.com>
This commit is contained in:
qsm-odoo
2024-04-25 18:45:51 +00:00
parent 8b4e56d84e
commit 7758af933c
6 changed files with 28 additions and 11 deletions
+14
View File
@@ -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}
*/
@@ -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);
@@ -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');
},
+1 -1
View File
@@ -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"
@@ -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');
@@ -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,