2017-09-28 19:18:12 -04:00
|
|
|
/**
|
|
|
|
* @license
|
|
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
|
|
* found in the LICENSE file at https://angular.io/license
|
|
|
|
*/
|
|
|
|
|
2017-11-11 18:39:27 -05:00
|
|
|
import {isPlatformBrowser} from '@angular/common';
|
2018-02-27 17:06:06 -05:00
|
|
|
import {APP_INITIALIZER, ApplicationRef, InjectionToken, Injector, ModuleWithProviders, NgModule, PLATFORM_ID} from '@angular/core';
|
|
|
|
import {filter, take} from 'rxjs/operators';
|
2017-09-28 19:18:12 -04:00
|
|
|
|
|
|
|
import {NgswCommChannel} from './low_level';
|
|
|
|
import {SwPush} from './push';
|
|
|
|
import {SwUpdate} from './update';
|
|
|
|
|
2017-11-30 16:16:37 -05:00
|
|
|
export abstract class RegistrationOptions {
|
|
|
|
scope?: string;
|
|
|
|
enabled?: boolean;
|
|
|
|
}
|
|
|
|
|
2017-09-28 19:18:12 -04:00
|
|
|
export const SCRIPT = new InjectionToken<string>('NGSW_REGISTER_SCRIPT');
|
|
|
|
|
|
|
|
export function ngswAppInitializer(
|
2017-11-11 18:39:27 -05:00
|
|
|
injector: Injector, script: string, options: RegistrationOptions,
|
|
|
|
platformId: string): Function {
|
2017-09-28 19:18:12 -04:00
|
|
|
const initializer = () => {
|
|
|
|
const app = injector.get<ApplicationRef>(ApplicationRef);
|
2017-11-11 18:39:27 -05:00
|
|
|
if (!(isPlatformBrowser(platformId) && ('serviceWorker' in navigator) &&
|
|
|
|
options.enabled !== false)) {
|
2017-09-28 19:18:12 -04:00
|
|
|
return;
|
|
|
|
}
|
2018-02-27 17:06:06 -05:00
|
|
|
const whenStable =
|
|
|
|
app.isStable.pipe(filter((stable: boolean) => !!stable), take(1)).toPromise();
|
2017-10-25 17:38:02 -04:00
|
|
|
|
2017-11-29 16:24:20 -05:00
|
|
|
// Wait for service worker controller changes, and fire an INITIALIZE action when a new SW
|
|
|
|
// becomes active. This allows the SW to initialize itself even if there is no application
|
|
|
|
// traffic.
|
|
|
|
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
|
|
|
if (navigator.serviceWorker.controller !== null) {
|
|
|
|
navigator.serviceWorker.controller.postMessage({action: 'INITIALIZE'});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-10-25 17:38:02 -04:00
|
|
|
// Don't return the Promise, as that will block the application until the SW is registered, and
|
|
|
|
// cause a crash if the SW registration fails.
|
2017-11-30 16:16:37 -05:00
|
|
|
whenStable.then(() => navigator.serviceWorker.register(script, {scope: options.scope}));
|
2017-09-28 19:18:12 -04:00
|
|
|
};
|
|
|
|
return initializer;
|
|
|
|
}
|
|
|
|
|
2017-11-11 18:39:27 -05:00
|
|
|
export function ngswCommChannelFactory(
|
|
|
|
opts: RegistrationOptions, platformId: string): NgswCommChannel {
|
|
|
|
return new NgswCommChannel(
|
2018-05-09 11:11:43 -04:00
|
|
|
isPlatformBrowser(platformId) && opts.enabled !== false ? navigator.serviceWorker :
|
|
|
|
undefined);
|
2017-09-28 19:18:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @experimental
|
|
|
|
*/
|
|
|
|
@NgModule({
|
|
|
|
providers: [SwPush, SwUpdate],
|
|
|
|
})
|
|
|
|
export class ServiceWorkerModule {
|
2017-11-30 16:16:37 -05:00
|
|
|
/**
|
|
|
|
* Register the given Angular Service Worker script.
|
|
|
|
*
|
|
|
|
* If `enabled` is set to `false` in the given options, the module will behave as if service
|
|
|
|
* workers are not supported by the browser, and the service worker will not be registered.
|
|
|
|
*/
|
|
|
|
static register(script: string, opts: {scope?: string; enabled?: boolean;} = {}):
|
|
|
|
ModuleWithProviders {
|
2017-09-28 19:18:12 -04:00
|
|
|
return {
|
|
|
|
ngModule: ServiceWorkerModule,
|
|
|
|
providers: [
|
|
|
|
{provide: SCRIPT, useValue: script},
|
2017-11-30 16:16:37 -05:00
|
|
|
{provide: RegistrationOptions, useValue: opts},
|
2017-11-11 18:39:27 -05:00
|
|
|
{
|
|
|
|
provide: NgswCommChannel,
|
|
|
|
useFactory: ngswCommChannelFactory,
|
|
|
|
deps: [RegistrationOptions, PLATFORM_ID]
|
|
|
|
},
|
2017-09-28 19:18:12 -04:00
|
|
|
{
|
|
|
|
provide: APP_INITIALIZER,
|
|
|
|
useFactory: ngswAppInitializer,
|
2017-11-11 18:39:27 -05:00
|
|
|
deps: [Injector, SCRIPT, RegistrationOptions, PLATFORM_ID],
|
2017-09-28 19:18:12 -04:00
|
|
|
multi: true,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
}
|
2017-11-30 16:16:37 -05:00
|
|
|
}
|