| 
									
										
										
										
											2017-09-28 16:18:12 -07: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-12 12:39:27 +13:00
										 |  |  | import {isPlatformBrowser} from '@angular/common'; | 
					
						
							|  |  |  | import {APP_INITIALIZER, ApplicationRef, Inject, InjectionToken, Injector, ModuleWithProviders, NgModule, PLATFORM_ID} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2017-09-28 16:18:12 -07:00
										 |  |  | import {Observable} from 'rxjs/Observable'; | 
					
						
							|  |  |  | import {filter as op_filter} from 'rxjs/operator/filter'; | 
					
						
							|  |  |  | import {take as op_take} from 'rxjs/operator/take'; | 
					
						
							|  |  |  | import {toPromise as op_toPromise} from 'rxjs/operator/toPromise'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {NgswCommChannel} from './low_level'; | 
					
						
							|  |  |  | import {SwPush} from './push'; | 
					
						
							|  |  |  | import {SwUpdate} from './update'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-30 13:16:37 -08:00
										 |  |  | export abstract class RegistrationOptions { | 
					
						
							|  |  |  |   scope?: string; | 
					
						
							|  |  |  |   enabled?: boolean; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-28 16:18:12 -07:00
										 |  |  | export const SCRIPT = new InjectionToken<string>('NGSW_REGISTER_SCRIPT'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export function ngswAppInitializer( | 
					
						
							| 
									
										
										
										
											2017-11-12 12:39:27 +13:00
										 |  |  |     injector: Injector, script: string, options: RegistrationOptions, | 
					
						
							|  |  |  |     platformId: string): Function { | 
					
						
							| 
									
										
										
										
											2017-09-28 16:18:12 -07:00
										 |  |  |   const initializer = () => { | 
					
						
							|  |  |  |     const app = injector.get<ApplicationRef>(ApplicationRef); | 
					
						
							| 
									
										
										
										
											2017-11-12 12:39:27 +13:00
										 |  |  |     if (!(isPlatformBrowser(platformId) && ('serviceWorker' in navigator) && | 
					
						
							|  |  |  |           options.enabled !== false)) { | 
					
						
							| 
									
										
										
										
											2017-09-28 16:18:12 -07:00
										 |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const onStable = | 
					
						
							|  |  |  |         op_filter.call(app.isStable, (stable: boolean) => !!stable) as Observable<boolean>; | 
					
						
							|  |  |  |     const isStable = op_take.call(onStable, 1) as Observable<boolean>; | 
					
						
							|  |  |  |     const whenStable = op_toPromise.call(isStable) as Promise<boolean>; | 
					
						
							| 
									
										
										
										
											2017-10-25 14:38:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 13:24:20 -08: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 14:38:02 -07: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 13:16:37 -08:00
										 |  |  |     whenStable.then(() => navigator.serviceWorker.register(script, {scope: options.scope})); | 
					
						
							| 
									
										
										
										
											2017-09-28 16:18:12 -07:00
										 |  |  |   }; | 
					
						
							|  |  |  |   return initializer; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-12 12:39:27 +13:00
										 |  |  | export function ngswCommChannelFactory( | 
					
						
							|  |  |  |     opts: RegistrationOptions, platformId: string): NgswCommChannel { | 
					
						
							|  |  |  |   return new NgswCommChannel( | 
					
						
							|  |  |  |       opts.enabled !== false ? navigator.serviceWorker : undefined, platformId); | 
					
						
							| 
									
										
										
										
											2017-09-28 16:18:12 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @experimental | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | @NgModule({ | 
					
						
							|  |  |  |   providers: [SwPush, SwUpdate], | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class ServiceWorkerModule { | 
					
						
							| 
									
										
										
										
											2017-11-30 13:16:37 -08: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 16:18:12 -07:00
										 |  |  |     return { | 
					
						
							|  |  |  |       ngModule: ServiceWorkerModule, | 
					
						
							|  |  |  |       providers: [ | 
					
						
							|  |  |  |         {provide: SCRIPT, useValue: script}, | 
					
						
							| 
									
										
										
										
											2017-11-30 13:16:37 -08:00
										 |  |  |         {provide: RegistrationOptions, useValue: opts}, | 
					
						
							| 
									
										
										
										
											2017-11-12 12:39:27 +13:00
										 |  |  |         { | 
					
						
							|  |  |  |           provide: NgswCommChannel, | 
					
						
							|  |  |  |           useFactory: ngswCommChannelFactory, | 
					
						
							|  |  |  |           deps: [RegistrationOptions, PLATFORM_ID] | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2017-09-28 16:18:12 -07:00
										 |  |  |         { | 
					
						
							|  |  |  |           provide: APP_INITIALIZER, | 
					
						
							|  |  |  |           useFactory: ngswAppInitializer, | 
					
						
							| 
									
										
										
										
											2017-11-12 12:39:27 +13:00
										 |  |  |           deps: [Injector, SCRIPT, RegistrationOptions, PLATFORM_ID], | 
					
						
							| 
									
										
										
										
											2017-09-28 16:18:12 -07:00
										 |  |  |           multi: true, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-11-30 13:16:37 -08:00
										 |  |  | } |