From b1d300dc265604418afeb7f813b1b30de94b2b34 Mon Sep 17 00:00:00 2001 From: WilliamKoza Date: Sun, 20 Jan 2019 14:12:52 +0100 Subject: [PATCH] fix(common): Prefer to use pageXOffset / pageYOffset instance of scrollX / scrollY (#28262) This fix ensures a better cross-browser compatibility. This fix has been used for angular.io. PR Close #28262 --- aio/src/app/shared/scroll.service.ts | 2 +- packages/common/src/viewport_scroller.ts | 6 +++--- packages/common/test/viewport_scroller_spec.ts | 3 ++- packages/router/test/bootstrap.spec.ts | 17 +++++++---------- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/aio/src/app/shared/scroll.service.ts b/aio/src/app/shared/scroll.service.ts index ab5f299b66..20b133055b 100644 --- a/aio/src/app/shared/scroll.service.ts +++ b/aio/src/app/shared/scroll.service.ts @@ -24,7 +24,7 @@ export class ScrollService implements OnDestroy { poppedStateScrollPosition: ScrollPosition|null = null; // Whether the browser supports the necessary features for manual scroll restoration. supportManualScrollRestoration: boolean = !!window && ('scrollTo' in window) && - ('scrollX' in window) && ('scrollY' in window) && isScrollRestorationWritable(); + ('pageXOffset' in window) && isScrollRestorationWritable(); // Offset from the top of the document to bottom of any static elements // at the top (e.g. toolbar) + some margin diff --git a/packages/common/src/viewport_scroller.ts b/packages/common/src/viewport_scroller.ts index bbcf53ebbc..d3ff85d6fd 100644 --- a/packages/common/src/viewport_scroller.ts +++ b/packages/common/src/viewport_scroller.ts @@ -89,7 +89,7 @@ export class BrowserViewportScroller implements ViewportScroller { */ getScrollPosition(): [number, number] { if (this.supportsScrolling()) { - return [this.window.scrollX, this.window.scrollY]; + return [this.window.pageXOffset, this.window.pageYOffset]; } else { return [0, 0]; } @@ -149,7 +149,7 @@ export class BrowserViewportScroller implements ViewportScroller { */ private supportScrollRestoration(): boolean { try { - if (!this.window || !this.window.scrollTo) { + if (!this.supportsScrolling()) { return false; } // The `scrollRestoration` property could be on the `history` instance or its prototype. @@ -166,7 +166,7 @@ export class BrowserViewportScroller implements ViewportScroller { private supportsScrolling(): boolean { try { - return !!this.window.scrollTo; + return !!this.window && !!this.window.scrollTo && 'pageXOffset' in this.window; } catch { return false; } diff --git a/packages/common/test/viewport_scroller_spec.ts b/packages/common/test/viewport_scroller_spec.ts index 006702e985..90713e62fd 100644 --- a/packages/common/test/viewport_scroller_spec.ts +++ b/packages/common/test/viewport_scroller_spec.ts @@ -15,7 +15,8 @@ describe('BrowserViewportScroller', () => { let windowSpy: any; beforeEach(() => { - windowSpy = jasmine.createSpyObj('window', ['history', 'scrollTo']); + windowSpy = + jasmine.createSpyObj('window', ['history', 'scrollTo', 'pageXOffset', 'pageYOffset']); windowSpy.history.scrollRestoration = 'auto'; documentSpy = jasmine.createSpyObj('document', ['getElementById', 'getElementsByName']); scroller = new BrowserViewportScroller(documentSpy, windowSpy, null!); diff --git a/packages/router/test/bootstrap.spec.ts b/packages/router/test/bootstrap.spec.ts index f3ee2c51df..5c76c6b8e2 100644 --- a/packages/router/test/bootstrap.spec.ts +++ b/packages/router/test/bootstrap.spec.ts @@ -348,27 +348,24 @@ describe('bootstrap', () => { await router.navigateByUrl('/aa'); window.scrollTo(0, 5000); - // IE 11 uses non-standard pageYOffset instead of scrollY - const getScrollY = () => window.scrollY !== undefined ? window.scrollY : window.pageYOffset; - await router.navigateByUrl('/fail'); - expect(getScrollY()).toEqual(5000); + expect(window.pageYOffset).toEqual(5000); await router.navigateByUrl('/bb'); window.scrollTo(0, 3000); - expect(getScrollY()).toEqual(3000); + expect(window.pageYOffset).toEqual(3000); await router.navigateByUrl('/cc'); - expect(getScrollY()).toEqual(0); + expect(window.pageYOffset).toEqual(0); await router.navigateByUrl('/aa#marker2'); - expect(getScrollY()).toBeGreaterThanOrEqual(5900); - expect(getScrollY()).toBeLessThan(6000); // offset + expect(window.pageYOffset).toBeGreaterThanOrEqual(5900); + expect(window.pageYOffset).toBeLessThan(6000); // offset await router.navigateByUrl('/aa#marker3'); - expect(getScrollY()).toBeGreaterThanOrEqual(8900); - expect(getScrollY()).toBeLessThan(9000); + expect(window.pageYOffset).toBeGreaterThanOrEqual(8900); + expect(window.pageYOffset).toBeLessThan(9000); done(); });