From 97f90b03cf59652cdbe7a1cfbd52b32e94a4c917 Mon Sep 17 00:00:00 2001 From: Bruno Boi Date: Mon, 11 Oct 2021 12:23:48 +0000 Subject: [PATCH] [FIX] web: usePosition computations on small screens To compute a positioning, the usePosition hook uses as the default container the element... but in the positioning computations it is assumed that the container is scrollable which is not the case for small screens when web_enterprise module is installed, as its webclient_layout.scss applies rules to make sure only the main content is scrollable. When the element is not scrollable, it can be scrolled out of the viewport, which is problematic as the positioning computations are based on a fixed positionment strategy. The way we chose to fix this is to account the scrollTop position of the container only if the container is the node. If so, further computations will now take into account the amount of scrolling the node has, and thus will be correct. See https://developer.mozilla.org/docs/Web/API/Element/scrollTop fur further understanding. X-original-commit: a050094cdaa5dd6b76c3f10fb49d3a9c0813425a Part-of: odoo/odoo#78261 --- .../static/src/core/position/position_hook.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/core/position/position_hook.js b/addons/web/static/src/core/position/position_hook.js index e2b82a42f30..69b2be0522e 100644 --- a/addons/web/static/src/core/position/position_hook.js +++ b/addons/web/static/src/core/position/position_hook.js @@ -94,6 +94,8 @@ export function computePositioning(reference, popper, options) { const refBox = reference.getBoundingClientRect(); const contBox = container.getBoundingClientRect(); + const containerIsHTMLNode = container === document.firstElementChild; + // Compute positioning data /** @type {DirectionsData} */ const directionsData = { @@ -122,13 +124,23 @@ export function computePositioning(reference, popper, options) { const [directionSize, variantSize] = vertical ? [popBox.height + margin, popBox.width] : [popBox.width, popBox.height + margin]; - const [directionMin, directionMax] = vertical + let [directionMin, directionMax] = vertical ? [contBox.top, contBox.bottom] : [contBox.left, contBox.right]; - const [variantMin, variantMax] = vertical + let [variantMin, variantMax] = vertical ? [contBox.left, contBox.right] : [contBox.top, contBox.bottom]; + if (containerIsHTMLNode) { + if (vertical) { + directionMin += container.scrollTop; + directionMax += container.scrollTop; + } else { + variantMin += container.scrollTop; + variantMax += container.scrollTop; + } + } + // Abort if outside container boundaries const directionOverflow = directionValue < directionMin || directionValue + directionSize > directionMax;