fix(service-worker): allow disabling SW while still using services

Currently, the way to not use the SW is to not install its module.
However, this means that you can't inject any of its services.

This change adds a ServiceWorkerModule.disabled() MWP, that still
registers all of the right providers but acts as if the browser does
not support Service Workers.
This commit is contained in:
Alex Rickabaugh 2017-11-30 13:16:37 -08:00
parent 60a30818ef
commit 65f4fad801
2 changed files with 25 additions and 11 deletions

View File

@ -16,14 +16,18 @@ import {NgswCommChannel} from './low_level';
import {SwPush} from './push';
import {SwUpdate} from './update';
export abstract class RegistrationOptions {
scope?: string;
enabled?: boolean;
}
export const SCRIPT = new InjectionToken<string>('NGSW_REGISTER_SCRIPT');
export const OPTS = new InjectionToken<Object>('NGSW_REGISTER_OPTIONS');
export function ngswAppInitializer(
injector: Injector, script: string, options: RegistrationOptions): Function {
const initializer = () => {
const app = injector.get<ApplicationRef>(ApplicationRef);
if (!('serviceWorker' in navigator)) {
if (!('serviceWorker' in navigator) || options.enabled === false) {
return;
}
const onStable =
@ -33,13 +37,13 @@ export function ngswAppInitializer(
// 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.
whenStable.then(() => navigator.serviceWorker.register(script, options));
whenStable.then(() => navigator.serviceWorker.register(script, {scope: options.scope}));
};
return initializer;
}
export function ngswCommChannelFactory(): NgswCommChannel {
return new NgswCommChannel(navigator.serviceWorker);
export function ngswCommChannelFactory(opts: RegistrationOptions): NgswCommChannel {
return new NgswCommChannel(opts.enabled !== false ? navigator.serviceWorker : undefined);
}
/**
@ -49,20 +53,27 @@ export function ngswCommChannelFactory(): NgswCommChannel {
providers: [SwPush, SwUpdate],
})
export class ServiceWorkerModule {
static register(script: string, opts: RegistrationOptions = {}): ModuleWithProviders {
/**
* 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 {
return {
ngModule: ServiceWorkerModule,
providers: [
{provide: SCRIPT, useValue: script},
{provide: OPTS, useValue: opts},
{provide: NgswCommChannel, useFactory: ngswCommChannelFactory},
{provide: RegistrationOptions, useValue: opts},
{provide: NgswCommChannel, useFactory: ngswCommChannelFactory, deps: [RegistrationOptions]},
{
provide: APP_INITIALIZER,
useFactory: ngswAppInitializer,
deps: [Injector, SCRIPT, OPTS],
deps: [Injector, SCRIPT, RegistrationOptions],
multi: true,
},
],
};
}
}
}

View File

@ -1,6 +1,9 @@
/** @experimental */
export declare class ServiceWorkerModule {
static register(script: string, opts?: RegistrationOptions): ModuleWithProviders;
static register(script: string, opts?: {
scope?: string;
enabled?: boolean;
}): ModuleWithProviders;
}
/** @experimental */