Scroll element in to view using center and for all the scrollable ancestors

Closes #14527
(grafted from accca4565e9092605e19afdb22d1bed33d1edab2)

--HG--
branch : 6.0
This commit is contained in:
Cédric Krier committed 2026-01-20 18:43:53 +01:00
1 parent 6f33919b02
commit 768438dbce
1 file changed
+50 -7
+50 -7
View File
@@ -77,16 +77,59 @@
};
Sao.common.scrollIntoViewIfNeeded = function(element) {
element = element[0];
if (element) {
var rect = element.getBoundingClientRect();
if (rect.bottom > window.innerHeight) {
element.scrollIntoView(false);
function isScrollable(el) {
let style = getComputedStyle(el);
return /(auto|scroll|overlay)/.test(
style.overflow + style.overflowY + style.overflowX
);
}
function getScrollableAncestors(el) {
let ancestors = [];
let parent = el.parentElement;
while (parent && parent !== document.body) {
if (isScrollable(parent)) {
ancestors.push(parent);
}
parent = parent.parentElement;
}
if (rect.top < 0) {
element.scrollIntoView();
ancestors.push(window);
return ancestors;
}
function scrollIntoViewWithin(el, container) {
let rect = el.getBoundingClientRect();
if (container === window) {
if (rect.top < 0 || rect.bottom > window.innerHeight) {
el.scrollIntoView({
block: 'center',
});
}
} else {
let container_rect = container.getBoundingClientRect();
let top_ = rect.top - container_rect.top;
let bottom = top_ + rect.height;
let target_top = container.scrollTop;
if (top_ < 0) {
target_top += top_ - container.clientHeight / 2;
} else if (bottom > container.clientHeight) {
target_top += bottom - container.clientHeight / 2
}
container.scrollTo({
top: Math.max(0, target_top),
});
}
}
element.each(function() {
let ancestors = getScrollableAncestors(this);
for (let ancestor of ancestors) {
scrollIntoViewWithin(this, ancestor);
}
});
};
// Handle click and Return press event