diff options
Diffstat (limited to 'devtools/client/shared/scroll.js')
-rw-r--r-- | devtools/client/shared/scroll.js | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/devtools/client/shared/scroll.js b/devtools/client/shared/scroll.js new file mode 100644 index 000000000..ee591e014 --- /dev/null +++ b/devtools/client/shared/scroll.js @@ -0,0 +1,52 @@ +/* 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; |