feat(service-worker): allow configuring when the SW is registered (#21842)

Fixes #20970

PR Close #21842
This commit is contained in:
JiaLi.Passion 2018-01-29 01:38:16 +09:00 committed by Andrew Kushnir
parent aa53d6cc6d
commit 4cfba58072
4 changed files with 58 additions and 16 deletions

View File

@ -218,3 +218,15 @@ If the field is omitted, it defaults to:
'!/**/*__*/**', // Exclude URLs containing `__` in any other segment.
]
```
## `register options`
<code-example path="service-worker-getting-started/src/app/app.module.ts" linenums="false" header="src/app/app.module.ts" region="sw-module"> </code-example>
You can pass some options to the `register()` method.
- enabled: optional parameter, by default is true, if enabled is false, the module will behave like the browser not support service worker, and service worker will not be registered.
- scope: optional parameter, to specify the subset of your content that you want the service worker to control.
- registrationStrategy: optional parameter, specify a strategy that determines when to register the service worker, the available options are:
- registerWhenStable: this is the default behavior, the service worker will register when the application is stable (no microTasks or macroTasks remain).
- registerImmediately: register immediately without waiting the application to become stable.
- registerDelay:timeout : register after the timeout period, `timeout` is the number of milliseconds to delay registration. For example `registerDelay:5000` would register the service worker after 5 seconds. If the number of `timeout` is not given (`registerDelay`), by default, `timeout` will be `0`, but it is not equal to `registerImmediately`, it will still run a `setTimeout(register, 0)` to wait all `microTasks` to finish then perform registration of the service worker.
- A factory to get Observable : you can also specify a factory which returns an Observable, the service worker will be registered the first time that a value is emitted by the Observable.

View File

@ -8,6 +8,7 @@
import {isPlatformBrowser} from '@angular/common';
import {APP_INITIALIZER, ApplicationRef, InjectionToken, Injector, ModuleWithProviders, NgModule, PLATFORM_ID} from '@angular/core';
import {Observable} from 'rxjs';
import {filter, take} from 'rxjs/operators';
import {NgswCommChannel} from './low_level';
@ -41,6 +42,8 @@ export abstract class SwRegistrationOptions {
* [ServiceWorkerContainer#register()](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register).
*/
scope?: string;
registrationStrategy?: (() => Observable<any>)|string;
}
export const SCRIPT = new InjectionToken<string>('NGSW_REGISTER_SCRIPT');
@ -68,7 +71,33 @@ 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, {scope: options.scope}));
if (typeof options.registrationStrategy === 'function') {
const observable = options.registrationStrategy();
const subscription = observable.subscribe(() => {
navigator.serviceWorker.register(script, {scope: options.scope});
subscription.unsubscribe();
});
} else {
const registrationStrategy = typeof options.registrationStrategy === 'string' ?
options.registrationStrategy :
'registerWhenStable';
if (registrationStrategy === 'registerWhenStable') {
whenStable.then(() => navigator.serviceWorker.register(script, {scope: options.scope}));
} else if (registrationStrategy === 'registerImmediately') {
navigator.serviceWorker.register(script, {scope: options.scope});
} else if (registrationStrategy.indexOf('registerDelay') !== -1) {
const split = registrationStrategy.split(':');
const delayStr = split.length > 1 ? split[1] : undefined;
const delay = Number(delayStr);
setTimeout(
() => navigator.serviceWorker.register(script, {scope: options.scope}),
typeof delay === 'number' ? delay : 0);
} else {
// wrong strategy
throw new Error(
`Unknown service worker registration strategy: ${options.registrationStrategy}`);
}
}
};
return initializer;
}

View File

@ -21,6 +21,7 @@ export declare class SwPush {
export declare abstract class SwRegistrationOptions {
enabled?: boolean;
registrationStrategy?: (() => Observable<any>) | string;
scope?: string;
}