1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- "use strict";
- /**
- * Scroll the document so that the element "elem" appears in the viewport.
- *
- * @param {DOMNode} elem
- * The element that needs to appear in the viewport.
- * @param {Boolean} centered
- * true if you want it centered, false if you want it to appear on the
- * top of the viewport. It is true by default, and that is usually what
- * you want.
- */
- function scrollIntoViewIfNeeded(elem, centered = true) {
- let win = elem.ownerDocument.defaultView;
- let clientRect = elem.getBoundingClientRect();
- // The following are always from the {top, bottom}
- // of the viewport, to the {top, …} of the box.
- // Think of them as geometrical vectors, it helps.
- // The origin is at the top left.
- let topToBottom = clientRect.bottom;
- let bottomToTop = clientRect.top - win.innerHeight;
- // We allow one translation on the y axis.
- let yAllowed = true;
- // Whatever `centered` is, the behavior is the same if the box is
- // (even partially) visible.
- if ((topToBottom > 0 || !centered) && topToBottom <= elem.offsetHeight) {
- win.scrollBy(0, topToBottom - elem.offsetHeight);
- yAllowed = false;
- } else if ((bottomToTop < 0 || !centered) &&
- bottomToTop >= -elem.offsetHeight) {
- win.scrollBy(0, bottomToTop + elem.offsetHeight);
- yAllowed = false;
- }
- // If we want it centered, and the box is completely hidden,
- // then we center it explicitly.
- if (centered) {
- if (yAllowed && (topToBottom <= 0 || bottomToTop >= 0)) {
- win.scroll(win.scrollX,
- win.scrollY + clientRect.top
- - (win.innerHeight - elem.offsetHeight) / 2);
- }
- }
- }
- exports.scrollIntoViewIfNeeded = scrollIntoViewIfNeeded;
|