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

View File

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