[FIX] web: usePosition computations on small screens

To compute a positioning, the usePosition hook uses as the default container
the <html/> 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 <html/> 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 <html/> node.
If so, further computations will now take into account the amount of
scrolling the <html/> 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
This commit is contained in:
Bruno Boi
2021-10-13 06:03:57 +00:00
parent 2bd8bb4d7b
commit 97f90b03cf
@@ -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;