refactor(docs-infra): make SwUpdatesService
depend on LocationService
(#39651)
Previously, the `LocationService` depended on the `SwUpdatesService`. This felt backwards, since `LocationService` is a more low-level and basic service and should not be depending on a service for a higher-level, specific feature (ServiceWorkers). This commit inverses the relation, making `SwUpdatesService` depend on `LocationService` instead. PR Close #39651
This commit is contained in:
parent
824f051843
commit
305d05545a
@ -1,10 +1,8 @@
|
|||||||
import { Injector } from '@angular/core';
|
import { Injector } from '@angular/core';
|
||||||
import { Location, LocationStrategy, PlatformLocation } from '@angular/common';
|
import { Location, LocationStrategy, PlatformLocation } from '@angular/common';
|
||||||
import { MockLocationStrategy } from '@angular/common/testing';
|
import { MockLocationStrategy } from '@angular/common/testing';
|
||||||
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 { LocationService } from './location.service';
|
import { LocationService } from './location.service';
|
||||||
import { ScrollService } from './scroll.service';
|
import { ScrollService } from './scroll.service';
|
||||||
|
|
||||||
@ -12,25 +10,22 @@ describe('LocationService', () => {
|
|||||||
let injector: Injector;
|
let injector: Injector;
|
||||||
let location: MockLocationStrategy;
|
let location: MockLocationStrategy;
|
||||||
let service: LocationService;
|
let service: LocationService;
|
||||||
let swUpdates: MockSwUpdatesService;
|
|
||||||
let scrollService: MockScrollService;
|
let scrollService: MockScrollService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
injector = Injector.create({
|
injector = Injector.create({
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: LocationService, deps: [GaService, Location, ScrollService, PlatformLocation, SwUpdatesService] },
|
{ provide: LocationService, deps: [GaService, Location, ScrollService, PlatformLocation] },
|
||||||
{ provide: Location, deps: [LocationStrategy, PlatformLocation] },
|
{ provide: Location, deps: [LocationStrategy, PlatformLocation] },
|
||||||
{ provide: GaService, useClass: TestGaService, deps: [] },
|
{ provide: GaService, useClass: TestGaService, deps: [] },
|
||||||
{ provide: LocationStrategy, useClass: MockLocationStrategy, deps: [] },
|
{ provide: LocationStrategy, useClass: MockLocationStrategy, deps: [] },
|
||||||
{ provide: PlatformLocation, useClass: MockPlatformLocation, deps: [] },
|
{ provide: PlatformLocation, useClass: MockPlatformLocation, deps: [] },
|
||||||
{ provide: SwUpdatesService, useClass: MockSwUpdatesService, deps: [] },
|
|
||||||
{ provide: ScrollService, useClass: MockScrollService, deps: [] }
|
{ provide: ScrollService, useClass: MockScrollService, deps: [] }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
location = injector.get(LocationStrategy) as unknown as MockLocationStrategy;
|
location = injector.get(LocationStrategy) as unknown as MockLocationStrategy;
|
||||||
service = injector.get(LocationService);
|
service = injector.get(LocationService);
|
||||||
swUpdates = injector.get(SwUpdatesService) as unknown as MockSwUpdatesService;
|
|
||||||
scrollService = injector.get(ScrollService);
|
scrollService = injector.get(ScrollService);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -244,7 +239,7 @@ describe('LocationService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('go', () => {
|
describe('go()', () => {
|
||||||
|
|
||||||
it('should update the location', () => {
|
it('should update the location', () => {
|
||||||
service.go('some-new-url');
|
service.go('some-new-url');
|
||||||
@ -295,19 +290,19 @@ describe('LocationService', () => {
|
|||||||
expect(goExternalSpy).toHaveBeenCalledWith(externalUrl);
|
expect(goExternalSpy).toHaveBeenCalledWith(externalUrl);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should do a "full page navigation" and remove the stored scroll position when navigating to ' +
|
it('should do a "full page navigation" if requested and remove the stored scroll position ' +
|
||||||
'internal URLs only if a ServiceWorker update has been activated', () => {
|
'when navigating to internal URLs only', () => {
|
||||||
const goExternalSpy = spyOn(service, 'goExternal');
|
const goExternalSpy = spyOn(service, 'goExternal');
|
||||||
const removeStoredScrollInfoSpy = spyOn(scrollService, 'removeStoredScrollInfo');
|
const removeStoredScrollInfoSpy = spyOn(scrollService, 'removeStoredScrollInfo');
|
||||||
|
|
||||||
// Internal URL - No ServiceWorker update
|
// Internal URL - No full page navigation requested
|
||||||
service.go('some-internal-url');
|
service.go('some-internal-url');
|
||||||
expect(removeStoredScrollInfoSpy).not.toHaveBeenCalled();
|
expect(removeStoredScrollInfoSpy).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');
|
||||||
|
|
||||||
// Internal URL - ServiceWorker update
|
// Internal URL - Full page navigation requested
|
||||||
swUpdates.updateActivated.next('foo');
|
service.fullPageNavigationNeeded();
|
||||||
service.go('other-internal-url');
|
service.go('other-internal-url');
|
||||||
expect(goExternalSpy).toHaveBeenCalledWith('other-internal-url');
|
expect(goExternalSpy).toHaveBeenCalledWith('other-internal-url');
|
||||||
expect(removeStoredScrollInfoSpy).toHaveBeenCalled();
|
expect(removeStoredScrollInfoSpy).toHaveBeenCalled();
|
||||||
@ -319,13 +314,13 @@ describe('LocationService', () => {
|
|||||||
const externalUrl = 'http://some/far/away/land';
|
const externalUrl = 'http://some/far/away/land';
|
||||||
const otherExternalUrl = 'http://some/far/far/away/land';
|
const otherExternalUrl = 'http://some/far/far/away/land';
|
||||||
|
|
||||||
// External URL - No ServiceWorker update
|
// External URL - No full page navigation requested
|
||||||
service.go(externalUrl);
|
service.go(externalUrl);
|
||||||
expect(removeStoredScrollInfoSpy).not.toHaveBeenCalled();
|
expect(removeStoredScrollInfoSpy).not.toHaveBeenCalled();
|
||||||
expect(goExternalSpy).toHaveBeenCalledWith(externalUrl);
|
expect(goExternalSpy).toHaveBeenCalledWith(externalUrl);
|
||||||
|
|
||||||
// External URL - ServiceWorker update
|
// External URL - Full page navigation requested
|
||||||
swUpdates.updateActivated.next('foo');
|
service.fullPageNavigationNeeded();
|
||||||
service.go(otherExternalUrl);
|
service.go(otherExternalUrl);
|
||||||
expect(removeStoredScrollInfoSpy).not.toHaveBeenCalled();
|
expect(removeStoredScrollInfoSpy).not.toHaveBeenCalled();
|
||||||
expect(goExternalSpy).toHaveBeenCalledWith(otherExternalUrl);
|
expect(goExternalSpy).toHaveBeenCalledWith(otherExternalUrl);
|
||||||
@ -341,7 +336,7 @@ describe('LocationService', () => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('search', () => {
|
describe('search()', () => {
|
||||||
it('should read the query from the current location.path', () => {
|
it('should read the query from the current location.path', () => {
|
||||||
location.simulatePopState('a/b/c?foo=bar&moo=car');
|
location.simulatePopState('a/b/c?foo=bar&moo=car');
|
||||||
expect(service.search()).toEqual({ foo: 'bar', moo: 'car' });
|
expect(service.search()).toEqual({ foo: 'bar', moo: 'car' });
|
||||||
@ -378,7 +373,7 @@ describe('LocationService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setSearch', () => {
|
describe('setSearch()', () => {
|
||||||
let platformLocation: MockPlatformLocation;
|
let platformLocation: MockPlatformLocation;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -416,7 +411,7 @@ describe('LocationService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('handleAnchorClick', () => {
|
describe('handleAnchorClick()', () => {
|
||||||
let anchor: HTMLAnchorElement;
|
let anchor: HTMLAnchorElement;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -630,10 +625,6 @@ class MockPlatformLocation {
|
|||||||
replaceState = jasmine.createSpy('PlatformLocation.replaceState');
|
replaceState = jasmine.createSpy('PlatformLocation.replaceState');
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockSwUpdatesService {
|
|
||||||
updateActivated = new Subject<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
class MockScrollService {
|
class MockScrollService {
|
||||||
removeStoredScrollInfo() { }
|
removeStoredScrollInfo() { }
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import { ReplaySubject } from 'rxjs';
|
|||||||
import { map, tap } from 'rxjs/operators';
|
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 { ScrollService } from './scroll.service';
|
import { ScrollService } from './scroll.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -13,7 +12,7 @@ export class LocationService {
|
|||||||
|
|
||||||
private readonly urlParser = document.createElement('a');
|
private readonly urlParser = document.createElement('a');
|
||||||
private urlSubject = new ReplaySubject<string>(1);
|
private urlSubject = new ReplaySubject<string>(1);
|
||||||
private swUpdateActivated = false;
|
private fullPageNavigation = false;
|
||||||
|
|
||||||
currentUrl = this.urlSubject
|
currentUrl = this.urlSubject
|
||||||
.pipe(map(url => this.stripSlashes(url)));
|
.pipe(map(url => this.stripSlashes(url)));
|
||||||
@ -27,16 +26,22 @@ export class LocationService {
|
|||||||
private gaService: GaService,
|
private gaService: GaService,
|
||||||
private location: Location,
|
private location: Location,
|
||||||
private scrollService: ScrollService,
|
private scrollService: ScrollService,
|
||||||
private platformLocation: PlatformLocation,
|
private platformLocation: PlatformLocation) {
|
||||||
swUpdates: SwUpdatesService) {
|
|
||||||
|
|
||||||
this.urlSubject.next(location.path(true));
|
this.urlSubject.next(location.path(true));
|
||||||
|
|
||||||
this.location.subscribe(state => {
|
this.location.subscribe(state => {
|
||||||
return this.urlSubject.next(state.url || '');
|
return this.urlSubject.next(state.url || '');
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
swUpdates.updateActivated.subscribe(() => this.swUpdateActivated = true);
|
/**
|
||||||
|
* Signify that a full page navigation is needed (instead of a regular in-app navigation).
|
||||||
|
*
|
||||||
|
* This will happen on the next user-initiated navigation.
|
||||||
|
*/
|
||||||
|
fullPageNavigationNeeded(): void {
|
||||||
|
this.fullPageNavigation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: ignore if url-without-hash-or-search matches current location?
|
// TODO: ignore if url-without-hash-or-search matches current location?
|
||||||
@ -46,9 +51,9 @@ export class LocationService {
|
|||||||
if (/^http/.test(url)) {
|
if (/^http/.test(url)) {
|
||||||
// Has http protocol so leave the site
|
// Has http protocol so leave the site
|
||||||
this.goExternal(url);
|
this.goExternal(url);
|
||||||
} else if (this.swUpdateActivated) {
|
} else if (this.fullPageNavigation) {
|
||||||
// (Do a "full page navigation" if a ServiceWorker update has been activated)
|
// Do a "full page navigation".
|
||||||
// We need to remove stored Position in order to be sure to scroll to the Top position
|
// We need to remove the stored scroll position to ensure we scroll to the top.
|
||||||
this.scrollService.removeStoredScrollInfo();
|
this.scrollService.removeStoredScrollInfo();
|
||||||
this.goExternal(url);
|
this.goExternal(url);
|
||||||
} else {
|
} else {
|
||||||
@ -118,7 +123,6 @@ export class LocationService {
|
|||||||
* `AppComponent`, whose element contains all the of the application and so captures all
|
* `AppComponent`, whose element contains all the of the application and so captures all
|
||||||
* link clicks both inside and outside the `DocViewerComponent`.
|
* link clicks both inside and outside the `DocViewerComponent`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
handleAnchorClick(anchor: HTMLAnchorElement, button = 0, ctrlKey = false, metaKey = false) {
|
handleAnchorClick(anchor: HTMLAnchorElement, button = 0, ctrlKey = false, metaKey = false) {
|
||||||
|
|
||||||
// Check for modifier keys and non-left-button, which indicate the user wants to control navigation
|
// Check for modifier keys and non-left-button, which indicate the user wants to control navigation
|
||||||
|
@ -3,7 +3,9 @@ import { discardPeriodicTasks, fakeAsync, tick } from '@angular/core/testing';
|
|||||||
import { SwUpdate } from '@angular/service-worker';
|
import { SwUpdate } from '@angular/service-worker';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
|
||||||
|
import { LocationService } from 'app/shared/location.service';
|
||||||
import { Logger } from 'app/shared/logger.service';
|
import { Logger } from 'app/shared/logger.service';
|
||||||
|
import { MockLocationService } from 'testing/location.service';
|
||||||
import { MockLogger } from 'testing/logger.service';
|
import { MockLogger } from 'testing/logger.service';
|
||||||
import { SwUpdatesService } from './sw-updates.service';
|
import { SwUpdatesService } from './sw-updates.service';
|
||||||
|
|
||||||
@ -11,6 +13,7 @@ import { SwUpdatesService } from './sw-updates.service';
|
|||||||
describe('SwUpdatesService', () => {
|
describe('SwUpdatesService', () => {
|
||||||
let injector: Injector;
|
let injector: Injector;
|
||||||
let appRef: MockApplicationRef;
|
let appRef: MockApplicationRef;
|
||||||
|
let location: MockLocationService;
|
||||||
let service: SwUpdatesService;
|
let service: SwUpdatesService;
|
||||||
let swu: MockSwUpdate;
|
let swu: MockSwUpdate;
|
||||||
let checkInterval: number;
|
let checkInterval: number;
|
||||||
@ -24,12 +27,14 @@ describe('SwUpdatesService', () => {
|
|||||||
const setup = (isSwUpdateEnabled: boolean) => {
|
const setup = (isSwUpdateEnabled: boolean) => {
|
||||||
injector = Injector.create({providers: [
|
injector = Injector.create({providers: [
|
||||||
{ provide: ApplicationRef, useClass: MockApplicationRef, deps: [] },
|
{ provide: ApplicationRef, useClass: MockApplicationRef, deps: [] },
|
||||||
|
{ provide: LocationService, useFactory: () => new MockLocationService(''), deps: [] },
|
||||||
{ provide: Logger, useClass: MockLogger, deps: [] },
|
{ provide: Logger, useClass: MockLogger, deps: [] },
|
||||||
{ provide: SwUpdate, useFactory: () => new MockSwUpdate(isSwUpdateEnabled), deps: [] },
|
{ provide: SwUpdate, useFactory: () => new MockSwUpdate(isSwUpdateEnabled), deps: [] },
|
||||||
{ provide: SwUpdatesService, deps: [ApplicationRef, Logger, SwUpdate] }
|
{ provide: SwUpdatesService, deps: [ApplicationRef, LocationService, Logger, SwUpdate] }
|
||||||
]});
|
]});
|
||||||
|
|
||||||
appRef = injector.get(ApplicationRef) as unknown as MockApplicationRef;
|
appRef = injector.get(ApplicationRef) as unknown as MockApplicationRef;
|
||||||
|
location = injector.get(LocationService) as unknown as MockLocationService;
|
||||||
service = injector.get(SwUpdatesService);
|
service = injector.get(SwUpdatesService);
|
||||||
swu = injector.get(SwUpdate) as unknown as MockSwUpdate;
|
swu = injector.get(SwUpdate) as unknown as MockSwUpdate;
|
||||||
checkInterval = (service as any).checkInterval;
|
checkInterval = (service as any).checkInterval;
|
||||||
@ -100,16 +105,18 @@ describe('SwUpdatesService', () => {
|
|||||||
discardPeriodicTasks();
|
discardPeriodicTasks();
|
||||||
})));
|
})));
|
||||||
|
|
||||||
it('should emit on `updateActivated` when an update has been activated', run(() => {
|
it('should request a full page navigation when an update has been activated', run(() => {
|
||||||
const activatedVersions: (string|undefined)[] = [];
|
|
||||||
service.updateActivated.subscribe(v => activatedVersions.push(v));
|
|
||||||
|
|
||||||
swu.$$availableSubj.next({available: {hash: 'foo'}});
|
swu.$$availableSubj.next({available: {hash: 'foo'}});
|
||||||
swu.$$activatedSubj.next({current: {hash: 'bar'}});
|
expect(location.fullPageNavigationNeeded).toHaveBeenCalledTimes(0);
|
||||||
swu.$$availableSubj.next({available: {hash: 'baz'}});
|
|
||||||
swu.$$activatedSubj.next({current: {hash: 'qux'}});
|
|
||||||
|
|
||||||
expect(activatedVersions).toEqual(['bar', 'qux']);
|
swu.$$activatedSubj.next({current: {hash: 'bar'}});
|
||||||
|
expect(location.fullPageNavigationNeeded).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
swu.$$availableSubj.next({available: {hash: 'baz'}});
|
||||||
|
expect(location.fullPageNavigationNeeded).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
swu.$$activatedSubj.next({current: {hash: 'qux'}});
|
||||||
|
expect(location.fullPageNavigationNeeded).toHaveBeenCalledTimes(2);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('when `SwUpdate` is not enabled', () => {
|
describe('when `SwUpdate` is not enabled', () => {
|
||||||
@ -135,16 +142,13 @@ describe('SwUpdatesService', () => {
|
|||||||
expect(swu.activateUpdate).not.toHaveBeenCalled();
|
expect(swu.activateUpdate).not.toHaveBeenCalled();
|
||||||
})));
|
})));
|
||||||
|
|
||||||
it('should never emit on `updateActivated`', runDeactivated(() => {
|
it('should never request a full page navigation', runDeactivated(() => {
|
||||||
const activatedVersions: (string|undefined)[] = [];
|
|
||||||
service.updateActivated.subscribe(v => activatedVersions.push(v));
|
|
||||||
|
|
||||||
swu.$$availableSubj.next({available: {hash: 'foo'}});
|
swu.$$availableSubj.next({available: {hash: 'foo'}});
|
||||||
swu.$$activatedSubj.next({current: {hash: 'bar'}});
|
swu.$$activatedSubj.next({current: {hash: 'bar'}});
|
||||||
swu.$$availableSubj.next({available: {hash: 'baz'}});
|
swu.$$availableSubj.next({available: {hash: 'baz'}});
|
||||||
swu.$$activatedSubj.next({current: {hash: 'qux'}});
|
swu.$$activatedSubj.next({current: {hash: 'qux'}});
|
||||||
|
|
||||||
expect(activatedVersions).toEqual([]);
|
expect(location.fullPageNavigationNeeded).not.toHaveBeenCalled();
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -185,17 +189,17 @@ describe('SwUpdatesService', () => {
|
|||||||
expect(swu.activateUpdate).not.toHaveBeenCalled();
|
expect(swu.activateUpdate).not.toHaveBeenCalled();
|
||||||
})));
|
})));
|
||||||
|
|
||||||
it('should stop emitting on `updateActivated`', run(() => {
|
it('should stop requesting full page navigations when updates are activated', run(() => {
|
||||||
const activatedVersions: (string|undefined)[] = [];
|
|
||||||
service.updateActivated.subscribe(v => activatedVersions.push(v));
|
|
||||||
|
|
||||||
swu.$$availableSubj.next({available: {hash: 'foo'}});
|
swu.$$availableSubj.next({available: {hash: 'foo'}});
|
||||||
swu.$$activatedSubj.next({current: {hash: 'bar'}});
|
swu.$$activatedSubj.next({current: {hash: 'bar'}});
|
||||||
|
expect(location.fullPageNavigationNeeded).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
service.ngOnDestroy();
|
service.ngOnDestroy();
|
||||||
|
location.fullPageNavigationNeeded.calls.reset();
|
||||||
|
|
||||||
swu.$$availableSubj.next({available: {hash: 'baz'}});
|
swu.$$availableSubj.next({available: {hash: 'baz'}});
|
||||||
swu.$$activatedSubj.next({current: {hash: 'qux'}});
|
swu.$$activatedSubj.next({current: {hash: 'qux'}});
|
||||||
|
expect(location.fullPageNavigationNeeded).not.toHaveBeenCalled();
|
||||||
expect(activatedVersions).toEqual(['bar']);
|
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { ApplicationRef, Injectable, OnDestroy } from '@angular/core';
|
import { ApplicationRef, Injectable, OnDestroy } from '@angular/core';
|
||||||
import { SwUpdate } from '@angular/service-worker';
|
import { SwUpdate } from '@angular/service-worker';
|
||||||
import { concat, interval, NEVER, Observable, Subject } from 'rxjs';
|
import { concat, interval, Subject } from 'rxjs';
|
||||||
import { first, map, takeUntil, tap } from 'rxjs/operators';
|
import { first, takeUntil, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { LocationService } from 'app/shared/location.service';
|
||||||
import { Logger } from 'app/shared/logger.service';
|
import { Logger } from 'app/shared/logger.service';
|
||||||
|
|
||||||
|
|
||||||
@ -19,12 +20,10 @@ export class SwUpdatesService implements OnDestroy {
|
|||||||
private checkInterval = 1000 * 60 * 60 * 6; // 6 hours
|
private checkInterval = 1000 * 60 * 60 * 6; // 6 hours
|
||||||
private onDestroy = new Subject<void>();
|
private onDestroy = new Subject<void>();
|
||||||
|
|
||||||
/** Emit the version hash whenever an update is activated. */
|
constructor(
|
||||||
updateActivated: Observable<string>;
|
appRef: ApplicationRef, location: LocationService, private logger: Logger,
|
||||||
|
private swu: SwUpdate) {
|
||||||
constructor(appRef: ApplicationRef, private logger: Logger, private swu: SwUpdate) {
|
|
||||||
if (!swu.isEnabled) {
|
if (!swu.isEnabled) {
|
||||||
this.updateActivated = NEVER.pipe(takeUntil(this.onDestroy));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,12 +44,13 @@ export class SwUpdatesService implements OnDestroy {
|
|||||||
)
|
)
|
||||||
.subscribe(() => this.swu.activateUpdate());
|
.subscribe(() => this.swu.activateUpdate());
|
||||||
|
|
||||||
// Notify about activated updates.
|
// Request a full page navigation once an update has been activated.
|
||||||
this.updateActivated = this.swu.activated.pipe(
|
this.swu.activated
|
||||||
tap(evt => this.log(`Update activated: ${JSON.stringify(evt)}`)),
|
.pipe(
|
||||||
map(evt => evt.current.hash),
|
tap(evt => this.log(`Update activated: ${JSON.stringify(evt)}`)),
|
||||||
takeUntil(this.onDestroy),
|
takeUntil(this.onDestroy),
|
||||||
);
|
)
|
||||||
|
.subscribe(() => location.fullPageNavigationNeeded());
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
@ -8,6 +8,7 @@ export class MockLocationService {
|
|||||||
currentPath = this.currentUrl.pipe(map(url => url.match(/[^?#]*/)![0]));
|
currentPath = this.currentUrl.pipe(map(url => url.match(/[^?#]*/)![0]));
|
||||||
search = jasmine.createSpy('search').and.returnValue({});
|
search = jasmine.createSpy('search').and.returnValue({});
|
||||||
setSearch = jasmine.createSpy('setSearch');
|
setSearch = jasmine.createSpy('setSearch');
|
||||||
|
fullPageNavigationNeeded = jasmine.createSpy('Location.fullPageNavigationNeeded');
|
||||||
go = jasmine.createSpy('Location.go').and
|
go = jasmine.createSpy('Location.go').and
|
||||||
.callFake((url: string) => this.urlSubject.next(url));
|
.callFake((url: string) => this.urlSubject.next(url));
|
||||||
goExternal = jasmine.createSpy('Location.goExternal');
|
goExternal = jasmine.createSpy('Location.goExternal');
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"master": {
|
"master": {
|
||||||
"uncompressed": {
|
"uncompressed": {
|
||||||
"runtime-es2015": 3033,
|
"runtime-es2015": 3033,
|
||||||
"main-es2015": 448327,
|
"main-es2015": 447565,
|
||||||
"polyfills-es2015": 52343
|
"polyfills-es2015": 52343
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12,7 +12,7 @@
|
|||||||
"master": {
|
"master": {
|
||||||
"uncompressed": {
|
"uncompressed": {
|
||||||
"runtime-es2015": 3033,
|
"runtime-es2015": 3033,
|
||||||
"main-es2015": 448538,
|
"main-es2015": 447774,
|
||||||
"polyfills-es2015": 52493
|
"polyfills-es2015": 52493
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user