ngx-scroll-position-restoration
Version:
Scroll position restoration in Angular.
90 lines • 9.09 kB
JavaScript
import { finder } from '@medv/finder';
export const WINDOW_SELECTOR = '__window-selector__';
/**
* DomUtils
*
* I provide a unified interface for dealing with scroll offsets across different types of targets (elements vs. windows).
*/
/**
* I get the scroll-top of the given target in the active DOM.
*/
export function getScrollTop(target) {
if (target instanceof Window) {
return window.scrollY;
}
else {
return target.scrollTop;
}
}
/**
* I return the CSS selector for the given target.
* ___
* NOTE: The generated selector is intended to be consumed by this class only - it may not produce a valid CSS selector.
*/
export function getSelector(target) {
// NOTE: I am breaking this apart because TypeScript was having trouble dealing
// with type-guard. I believe this is part of this bug:
// --
// https://github.com/Microsoft/TypeScript/issues/7271#issuecomment-360123191
if (target instanceof Window) {
return WINDOW_SELECTOR;
}
else {
// If the given element is not part of the active document, there's no way for us
// to calculate a selector for it.
if (!document.body.contains(target)) {
return null;
}
return finder(target);
}
}
/**
* I get the scrollable target for the given 'scroll' event.
* ___
* NOTE: If you want to ignore (ie, not reinstate the scroll) of a particular type of DOM element, return NULL from this method.
*/
export function getTargetFromScrollEvent(event) {
const node = event.target;
if (node instanceof HTMLDocument) {
return window;
}
else if (node instanceof Element) {
return node;
}
return null;
}
/**
* I attempt to scroll the given target to the given scrollTop and return the resultant value presented by the target.
* @param target
* @param scrollTop
* @returns resultant scroll top.
*/
export function scrollTo(target, scrollTop) {
if (target instanceof Window) {
target.scrollTo(0, scrollTop);
return target.scrollY;
}
else if (target instanceof Element) {
target.scrollTop = scrollTop;
return target.scrollTop;
}
return null;
}
/**
* I return the target accessible at the given CSS selector.
*/
export function select(selector) {
if (selector === WINDOW_SELECTOR) {
return window;
}
else {
return document.querySelector(selector);
}
}
/**
* Source:
* - https://www.bennadel.com/blog/3534-restoring-and-resetting-the-scroll-position-using-the-navigationstart-event-in-angular-7-0-4.htm
* - http://bennadel.github.io/JavaScript-Demos/demos/router-retain-scroll-polyfill-angular7/
* - https://github.com/bennadel/JavaScript-Demos/tree/master/demos/router-retain-scroll-polyfill-angular7
*/
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNjcm9sbC1wb3NpdGlvbi1yZXN0b3JhdGlvbi9zcmMvbGliL2RvbS11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRXRDLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxxQkFBcUIsQ0FBQztBQUlyRDs7OztHQUlHO0FBRUg7O0dBRUc7QUFDSCxNQUFNLFVBQVUsWUFBWSxDQUFDLE1BQWM7SUFDekMsSUFBSSxNQUFNLFlBQVksTUFBTSxFQUFFO1FBQzVCLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQztLQUN2QjtTQUFNO1FBQ0wsT0FBTyxNQUFNLENBQUMsU0FBUyxDQUFDO0tBQ3pCO0FBQ0gsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsV0FBVyxDQUFDLE1BQWM7SUFFeEMsK0VBQStFO0lBQy9FLHVEQUF1RDtJQUN2RCxLQUFLO0lBQ0wsNkVBQTZFO0lBQzdFLElBQUksTUFBTSxZQUFZLE1BQU0sRUFBRTtRQUM1QixPQUFPLGVBQWUsQ0FBQztLQUN4QjtTQUFNO1FBQ0wsaUZBQWlGO1FBQ2pGLGtDQUFrQztRQUNsQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDbkMsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUNELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0tBQ3ZCO0FBQ0gsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsd0JBQXdCLENBQUMsS0FBWTtJQUNuRCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO0lBQzFCLElBQUksSUFBSSxZQUFZLFlBQVksRUFBRTtRQUNoQyxPQUFPLE1BQU0sQ0FBQztLQUNmO1NBQU0sSUFBSSxJQUFJLFlBQVksT0FBTyxFQUFFO1FBQ2xDLE9BQU8sSUFBSSxDQUFDO0tBQ2I7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsTUFBYyxFQUFFLFNBQWlCO0lBQ3hELElBQUksTUFBTSxZQUFZLE1BQU0sRUFBRTtRQUM1QixNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUM5QixPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUM7S0FDdkI7U0FBTSxJQUFJLE1BQU0sWUFBWSxPQUFPLEVBQUU7UUFDcEMsTUFBTSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDN0IsT0FBTyxNQUFNLENBQUMsU0FBUyxDQUFDO0tBQ3pCO0lBQ0QsT0FBTyxJQUFJLENBQUE7QUFDYixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLFFBQWdCO0lBQ3JDLElBQUksUUFBUSxLQUFLLGVBQWUsRUFBRTtRQUNoQyxPQUFPLE1BQU0sQ0FBQztLQUNmO1NBQU07UUFDTCxPQUFPLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7S0FDekM7QUFDSCxDQUFDO0FBR0Q7Ozs7O0dBS0ciLCJzb3VyY2VzQ29udGVudCI6WyJcclxuaW1wb3J0IHsgZmluZGVyIH0gZnJvbSAnQG1lZHYvZmluZGVyJztcclxuXHJcbmV4cG9ydCBjb25zdCBXSU5ET1dfU0VMRUNUT1IgPSAnX193aW5kb3ctc2VsZWN0b3JfXyc7XHJcblxyXG5leHBvcnQgdHlwZSBUYXJnZXQgPSBXaW5kb3cgfCBFbGVtZW50O1xyXG5cclxuLyoqXHJcbiAqIERvbVV0aWxzXHJcbiAqIFxyXG4gKiBJIHByb3ZpZGUgYSB1bmlmaWVkIGludGVyZmFjZSBmb3IgZGVhbGluZyB3aXRoIHNjcm9sbCBvZmZzZXRzIGFjcm9zcyBkaWZmZXJlbnQgdHlwZXMgb2YgdGFyZ2V0cyAoZWxlbWVudHMgdnMuIHdpbmRvd3MpLlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBJIGdldCB0aGUgc2Nyb2xsLXRvcCBvZiB0aGUgZ2l2ZW4gdGFyZ2V0IGluIHRoZSBhY3RpdmUgRE9NLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldFNjcm9sbFRvcCh0YXJnZXQ6IFRhcmdldCk6IG51bWJlciB7XHJcbiAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIFdpbmRvdykge1xyXG4gICAgcmV0dXJuIHdpbmRvdy5zY3JvbGxZO1xyXG4gIH0gZWxzZSB7XHJcbiAgICByZXR1cm4gdGFyZ2V0LnNjcm9sbFRvcDtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBJIHJldHVybiB0aGUgQ1NTIHNlbGVjdG9yIGZvciB0aGUgZ2l2ZW4gdGFyZ2V0LlxyXG4gKiBfX19cclxuICogTk9URTogVGhlIGdlbmVyYXRlZCBzZWxlY3RvciBpcyBpbnRlbmRlZCB0byBiZSBjb25zdW1lZCBieSB0aGlzIGNsYXNzIG9ubHkgLSBpdCBtYXkgbm90IHByb2R1Y2UgYSB2YWxpZCBDU1Mgc2VsZWN0b3IuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VsZWN0b3IodGFyZ2V0OiBUYXJnZXQpOiBzdHJpbmcgfCBudWxsIHtcclxuXHJcbiAgLy8gTk9URTogSSBhbSBicmVha2luZyB0aGlzIGFwYXJ0IGJlY2F1c2UgVHlwZVNjcmlwdCB3YXMgaGF2aW5nIHRyb3VibGUgZGVhbGluZ1xyXG4gIC8vIHdpdGggdHlwZS1ndWFyZC4gSSBiZWxpZXZlIHRoaXMgaXMgcGFydCBvZiB0aGlzIGJ1ZzpcclxuICAvLyAtLVxyXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9NaWNyb3NvZnQvVHlwZVNjcmlwdC9pc3N1ZXMvNzI3MSNpc3N1ZWNvbW1lbnQtMzYwMTIzMTkxXHJcbiAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIFdpbmRvdykge1xyXG4gICAgcmV0dXJuIFdJTkRPV19TRUxFQ1RPUjtcclxuICB9IGVsc2Uge1xyXG4gICAgLy8gSWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgbm90IHBhcnQgb2YgdGhlIGFjdGl2ZSBkb2N1bWVudCwgdGhlcmUncyBubyB3YXkgZm9yIHVzXHJcbiAgICAvLyB0byBjYWxjdWxhdGUgYSBzZWxlY3RvciBmb3IgaXQuXHJcbiAgICBpZiAoIWRvY3VtZW50LmJvZHkuY29udGFpbnModGFyZ2V0KSkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIHJldHVybiBmaW5kZXIodGFyZ2V0KTtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAgSSBnZXQgdGhlIHNjcm9sbGFibGUgdGFyZ2V0IGZvciB0aGUgZ2l2ZW4gJ3Njcm9sbCcgZXZlbnQuXHJcbiAqIF9fX1xyXG4gKiBOT1RFOiBJZiB5b3Ugd2FudCB0byBpZ25vcmUgKGllLCBub3QgcmVpbnN0YXRlIHRoZSBzY3JvbGwpIG9mIGEgcGFydGljdWxhciB0eXBlIG9mIERPTSBlbGVtZW50LCByZXR1cm4gTlVMTCBmcm9tIHRoaXMgbWV0aG9kLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldFRhcmdldEZyb21TY3JvbGxFdmVudChldmVudDogRXZlbnQpOiBUYXJnZXQgfCBudWxsIHtcclxuICBjb25zdCBub2RlID0gZXZlbnQudGFyZ2V0O1xyXG4gIGlmIChub2RlIGluc3RhbmNlb2YgSFRNTERvY3VtZW50KSB7XHJcbiAgICByZXR1cm4gd2luZG93O1xyXG4gIH0gZWxzZSBpZiAobm9kZSBpbnN0YW5jZW9mIEVsZW1lbnQpIHtcclxuICAgIHJldHVybiBub2RlO1xyXG4gIH1cclxuICByZXR1cm4gbnVsbDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEkgYXR0ZW1wdCB0byBzY3JvbGwgdGhlIGdpdmVuIHRhcmdldCB0byB0aGUgZ2l2ZW4gc2Nyb2xsVG9wIGFuZCByZXR1cm4gdGhlIHJlc3VsdGFudCB2YWx1ZSBwcmVzZW50ZWQgYnkgdGhlIHRhcmdldC5cclxuICogQHBhcmFtIHRhcmdldCBcclxuICogQHBhcmFtIHNjcm9sbFRvcCBcclxuICogQHJldHVybnMgcmVzdWx0YW50IHNjcm9sbCB0b3AuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG8odGFyZ2V0OiBUYXJnZXQsIHNjcm9sbFRvcDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XHJcbiAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIFdpbmRvdykge1xyXG4gICAgdGFyZ2V0LnNjcm9sbFRvKDAsIHNjcm9sbFRvcCk7XHJcbiAgICByZXR1cm4gdGFyZ2V0LnNjcm9sbFk7XHJcbiAgfSBlbHNlIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBFbGVtZW50KSB7XHJcbiAgICB0YXJnZXQuc2Nyb2xsVG9wID0gc2Nyb2xsVG9wO1xyXG4gICAgcmV0dXJuIHRhcmdldC5zY3JvbGxUb3A7XHJcbiAgfVxyXG4gIHJldHVybiBudWxsXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBJIHJldHVybiB0aGUgdGFyZ2V0IGFjY2Vzc2libGUgYXQgdGhlIGdpdmVuIENTUyBzZWxlY3Rvci5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBzZWxlY3Qoc2VsZWN0b3I6IHN0cmluZyk6IFRhcmdldCB8IG51bGwge1xyXG4gIGlmIChzZWxlY3RvciA9PT0gV0lORE9XX1NFTEVDVE9SKSB7XHJcbiAgICByZXR1cm4gd2luZG93O1xyXG4gIH0gZWxzZSB7XHJcbiAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XHJcbiAgfVxyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIFNvdXJjZTpcclxuICogLSBodHRwczovL3d3dy5iZW5uYWRlbC5jb20vYmxvZy8zNTM0LXJlc3RvcmluZy1hbmQtcmVzZXR0aW5nLXRoZS1zY3JvbGwtcG9zaXRpb24tdXNpbmctdGhlLW5hdmlnYXRpb25zdGFydC1ldmVudC1pbi1hbmd1bGFyLTctMC00Lmh0bVxyXG4gKiAtIGh0dHA6Ly9iZW5uYWRlbC5naXRodWIuaW8vSmF2YVNjcmlwdC1EZW1vcy9kZW1vcy9yb3V0ZXItcmV0YWluLXNjcm9sbC1wb2x5ZmlsbC1hbmd1bGFyNy9cclxuICogLSBodHRwczovL2dpdGh1Yi5jb20vYmVubmFkZWwvSmF2YVNjcmlwdC1EZW1vcy90cmVlL21hc3Rlci9kZW1vcy9yb3V0ZXItcmV0YWluLXNjcm9sbC1wb2x5ZmlsbC1hbmd1bGFyN1xyXG4gKi8iXX0=