From 7d54ec45cfb0736bcc9f0c14ebd4c0a495f1f0ad Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Thu, 23 Sep 2021 15:24:27 +0000 Subject: [PATCH] [FIX] web: scrolling: take html to scroll in mobile Before this commit the scroll position in mobile mode were not kept. This was because the scroll element was the body node. After this commit, the scroll is saved and reused correctly as the reference node is the html node. This commit makes no sense without its enterprise counterpart. (https://github.com/odoo/enterprise/pull/21150) closes odoo/odoo#77232 X-original-commit: 4957fd2ceec51ba3907a968bd0fce0512a57f3ac Related: odoo/enterprise#21196 Signed-off-by: Aaron Bohy (aab) --- addons/web/static/src/core/utils/scrolling.js | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/addons/web/static/src/core/utils/scrolling.js b/addons/web/static/src/core/utils/scrolling.js index bd6ac0cec65..40cf6c92636 100644 --- a/addons/web/static/src/core/utils/scrolling.js +++ b/addons/web/static/src/core/utils/scrolling.js @@ -34,6 +34,24 @@ export function scrollTo(element, scrollable = null) { } } +/* + * Returns the main scrollable element relevant in a context of an action. + * In desktop, the relevant element is the .o_content of the action. + * In mobile, it is the html node itself, provided no other children is scrollable + * Most of the times in mobile, we don't want to scroll individual elements, so every bit + * of code should enforce that html is the scrollable element. + * + * @param {Component} The action component. + * @return {Element} + */ +function getScrollableElement(component) { + if (component.env.isSmall) { + return document.firstElementChild; // aka html node; + } else { + return component.el.querySelector(".o_action_manager .o_content"); + } +} + /** * Retrieves the current top and left scroll position. By default, the scrolling * area is the '.o_content' main div. In mobile, it is the body. @@ -42,12 +60,7 @@ export function scrollTo(element, scrollable = null) { * area. */ export function getScrollPosition(component) { - let scrollingEl; - if (component.env.isSmall) { - scrollingEl = document.body; - } else { - scrollingEl = component.el.querySelector(".o_action_manager .o_content"); - } + const scrollingEl = getScrollableElement(component); return { left: scrollingEl ? scrollingEl.scrollLeft : 0, top: scrollingEl ? scrollingEl.scrollTop : 0, @@ -65,12 +78,7 @@ export function getScrollPosition(component) { * @param {number} [offset.top=0] */ export function setScrollPosition(component, offset) { - let scrollingEl; - if (component.env.isSmall) { - scrollingEl = document.body; - } else { - scrollingEl = component.el.querySelector(".o_action_manager .o_content"); - } + const scrollingEl = getScrollableElement(component); if (scrollingEl) { scrollingEl.scrollLeft = offset.left || 0; scrollingEl.scrollTop = offset.top || 0;