fix(docs-infra): remove scroll position from sessionStorage when a ServiceWorker update has been activated (#29958)

closes #29893

PR Close #29958
This commit is contained in:
William Koza 2019-04-17 16:38:39 +02:00 committed by Alex Rickabaugh
parent f094bb54a7
commit bf6bedd714
2 changed files with 40 additions and 5 deletions

View File

@ -6,12 +6,14 @@ import { Subject } from 'rxjs';
import { GaService } from 'app/shared/ga.service'; import { GaService } from 'app/shared/ga.service';
import { SwUpdatesService } from 'app/sw-updates/sw-updates.service'; import { SwUpdatesService } from 'app/sw-updates/sw-updates.service';
import { LocationService } from './location.service'; import { LocationService } from './location.service';
import { ScrollService } from './scroll.service';
describe('LocationService', () => { describe('LocationService', () => {
let injector: ReflectiveInjector; let injector: ReflectiveInjector;
let location: MockLocationStrategy; let location: MockLocationStrategy;
let service: LocationService; let service: LocationService;
let swUpdates: MockSwUpdatesService; let swUpdates: MockSwUpdatesService;
let scrollService: MockScrollService;
beforeEach(() => { beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([ injector = ReflectiveInjector.resolveAndCreate([
@ -20,12 +22,14 @@ describe('LocationService', () => {
{ provide: GaService, useClass: TestGaService }, { provide: GaService, useClass: TestGaService },
{ provide: LocationStrategy, useClass: MockLocationStrategy }, { provide: LocationStrategy, useClass: MockLocationStrategy },
{ provide: PlatformLocation, useClass: MockPlatformLocation }, { provide: PlatformLocation, useClass: MockPlatformLocation },
{ provide: SwUpdatesService, useClass: MockSwUpdatesService } { provide: SwUpdatesService, useClass: MockSwUpdatesService },
{ provide: ScrollService, useClass: MockScrollService }
]); ]);
location = injector.get(LocationStrategy); location = injector.get(LocationStrategy);
service = injector.get(LocationService); service = injector.get(LocationService);
swUpdates = injector.get(SwUpdatesService); swUpdates = injector.get(SwUpdatesService);
scrollService = injector.get(ScrollService);
}); });
describe('currentUrl', () => { describe('currentUrl', () => {
@ -289,11 +293,14 @@ describe('LocationService', () => {
expect(goExternalSpy).toHaveBeenCalledWith(externalUrl); expect(goExternalSpy).toHaveBeenCalledWith(externalUrl);
}); });
it('should do a "full page navigation" if a ServiceWorker update has been activated', () => { it('should do a "full page navigation" and remove the stored scroll position when navigating to ' +
'internal URLs only if a ServiceWorker update has been activated', () => {
const goExternalSpy = spyOn(service, 'goExternal'); const goExternalSpy = spyOn(service, 'goExternal');
const removeStoredScrollPositionSpy = spyOn(scrollService, 'removeStoredScrollPosition');
// Internal URL - No ServiceWorker update // Internal URL - No ServiceWorker update
service.go('some-internal-url'); service.go('some-internal-url');
expect(removeStoredScrollPositionSpy).not.toHaveBeenCalled();
expect(goExternalSpy).not.toHaveBeenCalled(); expect(goExternalSpy).not.toHaveBeenCalled();
expect(location.path(true)).toEqual('some-internal-url'); expect(location.path(true)).toEqual('some-internal-url');
@ -301,7 +308,25 @@ describe('LocationService', () => {
swUpdates.updateActivated.next('foo'); swUpdates.updateActivated.next('foo');
service.go('other-internal-url'); service.go('other-internal-url');
expect(goExternalSpy).toHaveBeenCalledWith('other-internal-url'); expect(goExternalSpy).toHaveBeenCalledWith('other-internal-url');
expect(location.path(true)).toEqual('some-internal-url'); expect(removeStoredScrollPositionSpy).toHaveBeenCalled();
});
it('should not remove the stored scroll position when navigating to external URLs', () => {
const removeStoredScrollPositionSpy = spyOn(scrollService, 'removeStoredScrollPosition');
const goExternalSpy = spyOn(service, 'goExternal');
const externalUrl = 'http://some/far/away/land';
const otherExternalUrl = 'http://some/far/far/away/land';
// External URL - No ServiceWorker update
service.go(externalUrl);
expect(removeStoredScrollPositionSpy).not.toHaveBeenCalled();
expect(goExternalSpy).toHaveBeenCalledWith(externalUrl);
// External URL - ServiceWorker update
swUpdates.updateActivated.next('foo');
service.go(otherExternalUrl);
expect(removeStoredScrollPositionSpy).not.toHaveBeenCalled();
expect(goExternalSpy).toHaveBeenCalledWith(otherExternalUrl);
}); });
it('should not update currentUrl for external url that starts with "http"', () => { it('should not update currentUrl for external url that starts with "http"', () => {
@ -607,6 +632,10 @@ class MockSwUpdatesService {
updateActivated = new Subject<string>(); updateActivated = new Subject<string>();
} }
class MockScrollService {
removeStoredScrollPosition() { }
}
class TestGaService { class TestGaService {
locationChanged = jasmine.createSpy('locationChanged'); locationChanged = jasmine.createSpy('locationChanged');
} }

View File

@ -6,6 +6,7 @@ import { map, tap } from 'rxjs/operators';
import { GaService } from 'app/shared/ga.service'; import { GaService } from 'app/shared/ga.service';
import { SwUpdatesService } from 'app/sw-updates/sw-updates.service'; import { SwUpdatesService } from 'app/sw-updates/sw-updates.service';
import { ScrollService } from './scroll.service';
@Injectable() @Injectable()
export class LocationService { export class LocationService {
@ -25,6 +26,7 @@ export class LocationService {
constructor( constructor(
private gaService: GaService, private gaService: GaService,
private location: Location, private location: Location,
private scrollService: ScrollService,
private platformLocation: PlatformLocation, private platformLocation: PlatformLocation,
swUpdates: SwUpdatesService) { swUpdates: SwUpdatesService) {
@ -41,9 +43,13 @@ export class LocationService {
go(url: string|null|undefined) { go(url: string|null|undefined) {
if (!url) { return; } if (!url) { return; }
url = this.stripSlashes(url); url = this.stripSlashes(url);
if (/^http/.test(url) || this.swUpdateActivated) { if (/^http/.test(url)) {
// Has http protocol so leave the site // Has http protocol so leave the site
// (or do a "full page navigation" if a ServiceWorker update has been activated) this.goExternal(url);
} else if (this.swUpdateActivated) {
// (Do a "full page navigation" if a ServiceWorker update has been activated)
// We need to remove stored Position in order to be sure to scroll to the Top position
this.scrollService.removeStoredScrollPosition();
this.goExternal(url); this.goExternal(url);
} else { } else {
this.location.go(url); this.location.go(url);