Files
zulip/static/js/scroll_util.js
Steve Howell 3aef11dc0e list_render: Extract get_list_scrolling_container().
We put this in `scroll_util` to make it more likely
we will eventually unify this with other scrolling
logic.  (A big piece to move is ui.get_scroll_element,
but that's for another PR.)

And then the other tactical advantage is that we get
100% line coverage on it.

I changed the warning to an error, since I don't
think we ever expect scrolling at the `body` level,
and I don't bother with the preview node.
2020-04-15 15:13:26 -07:00

80 lines
2.1 KiB
JavaScript

exports.get_list_scrolling_container = function (container) {
/*
This is used for list widgets that don't
have SimpleBar (in contrast to, say,
ui.get_scroll_element().
*/
let nearestScrollingContainer = container;
while (nearestScrollingContainer.length) {
if (nearestScrollingContainer.is("body, html")) {
blueslip.error(
"Please wrap lists in an element with " +
"'max-height' attribute.");
break;
}
if (nearestScrollingContainer.css("max-height") !== "none") {
break;
}
nearestScrollingContainer = nearestScrollingContainer.parent();
}
return nearestScrollingContainer;
};
exports.scroll_delta = function (opts) {
const elem_top = opts.elem_top;
const container_height = opts.container_height;
const elem_bottom = opts.elem_bottom;
let delta = 0;
if (elem_top < 0) {
delta = Math.max(
elem_top,
elem_bottom - container_height
);
delta = Math.min(0, delta);
} else {
if (elem_bottom > container_height) {
delta = Math.min(
elem_top,
elem_bottom - container_height
);
delta = Math.max(0, delta);
}
}
return delta;
};
exports.scroll_element_into_container = function (elem, container) {
// This does the minimum amount of scrolling that is needed to make
// the element visible. It doesn't try to center the element, so
// this will be non-intrusive to users when they already have
// the element visible.
container = ui.get_scroll_element(container);
const elem_top = elem.position().top;
const elem_bottom = elem_top + elem.innerHeight();
const opts = {
elem_top: elem_top,
elem_bottom: elem_bottom,
container_height: container.height(),
};
const delta = exports.scroll_delta(opts);
if (delta === 0) {
return;
}
container.scrollTop(container.scrollTop() + delta);
};
window.scroll_util = exports;