| 
									
										
										
										
											2016-06-23 09:47:54 -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-03-01 10:28:52 -08:00
										 |  |  | import {EventEmitter} from '../event_emitter'; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 18:06:24 +02:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2015-09-16 08:31:43 -07:00
										 |  |  |  * An injectable service for executing work inside or outside of the Angular zone. | 
					
						
							| 
									
										
										
										
											2015-04-17 18:06:24 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2015-09-16 08:31:43 -07:00
										 |  |  |  * The most common use of this service is to optimize performance when starting a work consisting of | 
					
						
							|  |  |  |  * one or more asynchronous tasks that don't require UI updates or error handling to be handled by | 
					
						
							| 
									
										
										
										
											2017-04-25 02:15:33 +02:00
										 |  |  |  * Angular. Such tasks can be kicked off via {@link #runOutsideAngular} and if needed, these tasks | 
					
						
							|  |  |  |  * can reenter the Angular zone via {@link #run}. | 
					
						
							| 
									
										
										
										
											2015-04-17 18:06:24 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2015-09-16 08:31:43 -07:00
										 |  |  |  * <!-- TODO: add/fix links to:
 | 
					
						
							|  |  |  |  *   - docs explaining zones and the use of zones in Angular and change-detection | 
					
						
							|  |  |  |  *   - link to runOutsideAngular/run (throughout this file!) | 
					
						
							|  |  |  |  *   --> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-05-18 16:13:00 +01:00
										 |  |  |  * @usageNotes | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |  * ### Example | 
					
						
							| 
									
										
										
										
											2017-02-04 22:24:10 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2015-09-16 08:31:43 -07:00
										 |  |  |  * ```
 | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |  * import {Component, NgZone} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |  * import {NgIf} from '@angular/common'; | 
					
						
							| 
									
										
										
										
											2015-09-16 08:31:43 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  * @Component({ | 
					
						
							| 
									
										
										
										
											2017-09-20 15:17:38 +02:00
										 |  |  |  *   selector: 'ng-zone-demo', | 
					
						
							| 
									
										
										
										
											2015-09-16 08:31:43 -07:00
										 |  |  |  *   template: `
 | 
					
						
							|  |  |  |  *     <h2>Demo: NgZone</h2> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     <p>Progress: {{progress}}%</p> | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |  *     <p *ngIf="progress >= 100">Done processing {{label}} of Angular zone!</p> | 
					
						
							| 
									
										
										
										
											2015-09-16 08:31:43 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  *     <button (click)="processWithinAngularZone()">Process within Angular zone</button> | 
					
						
							|  |  |  |  *     <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button> | 
					
						
							|  |  |  |  *   `,
 | 
					
						
							|  |  |  |  * }) | 
					
						
							|  |  |  |  * export class NgZoneDemo { | 
					
						
							|  |  |  |  *   progress: number = 0; | 
					
						
							|  |  |  |  *   label: string; | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   constructor(private _ngZone: NgZone) {} | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   // Loop inside the Angular zone
 | 
					
						
							|  |  |  |  *   // so the UI DOES refresh after each setTimeout cycle
 | 
					
						
							|  |  |  |  *   processWithinAngularZone() { | 
					
						
							|  |  |  |  *     this.label = 'inside'; | 
					
						
							|  |  |  |  *     this.progress = 0; | 
					
						
							|  |  |  |  *     this._increaseProgress(() => console.log('Inside Done!')); | 
					
						
							|  |  |  |  *   } | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   // Loop outside of the Angular zone
 | 
					
						
							|  |  |  |  *   // so the UI DOES NOT refresh after each setTimeout cycle
 | 
					
						
							|  |  |  |  *   processOutsideOfAngularZone() { | 
					
						
							|  |  |  |  *     this.label = 'outside'; | 
					
						
							|  |  |  |  *     this.progress = 0; | 
					
						
							|  |  |  |  *     this._ngZone.runOutsideAngular(() => { | 
					
						
							|  |  |  |  *       this._increaseProgress(() => { | 
					
						
							| 
									
										
										
										
											2017-09-20 15:17:38 +02:00
										 |  |  |  *         // reenter the Angular zone and display done
 | 
					
						
							|  |  |  |  *         this._ngZone.run(() => { console.log('Outside Done!'); }); | 
					
						
							|  |  |  |  *       }); | 
					
						
							|  |  |  |  *     }); | 
					
						
							| 
									
										
										
										
											2015-09-16 08:31:43 -07:00
										 |  |  |  *   } | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   _increaseProgress(doneCallback: () => void) { | 
					
						
							|  |  |  |  *     this.progress += 1; | 
					
						
							|  |  |  |  *     console.log(`Current progress: ${this.progress}%`); | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     if (this.progress < 100) { | 
					
						
							| 
									
										
										
										
											2017-09-20 15:17:38 +02:00
										 |  |  |  *       window.setTimeout(() => this._increaseProgress(doneCallback), 10); | 
					
						
							| 
									
										
										
										
											2015-09-16 08:31:43 -07:00
										 |  |  |  *     } else { | 
					
						
							|  |  |  |  *       doneCallback(); | 
					
						
							|  |  |  |  *     } | 
					
						
							|  |  |  |  *   } | 
					
						
							|  |  |  |  * } | 
					
						
							|  |  |  |  * ```
 | 
					
						
							| 
									
										
										
										
											2017-02-04 22:24:10 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-05-25 15:00:05 -07:00
										 |  |  |  * @experimental | 
					
						
							| 
									
										
										
										
											2015-04-17 18:06:24 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-10-08 13:33:22 -07:00
										 |  |  | export class NgZone { | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |   readonly hasPendingMicrotasks: boolean = false; | 
					
						
							|  |  |  |   readonly hasPendingMacrotasks: boolean = false; | 
					
						
							| 
									
										
										
										
											2014-12-05 18:30:45 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Whether there are no outstanding microtasks or macrotasks. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   readonly isStable: boolean = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Notifies when code enters Angular Zone. This gets fired first on VM Turn. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   readonly onUnstable: EventEmitter<any> = new EventEmitter(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							| 
									
										
										
										
											2017-06-01 14:45:49 -07:00
										 |  |  |    * Notifies when there is no more microtasks enqueued in the current VM Turn. | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |    * This is a hint for Angular to do change detection, which may enqueue more microtasks. | 
					
						
							|  |  |  |    * For this reason this event can fire multiple times per VM Turn. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   readonly onMicrotaskEmpty: EventEmitter<any> = new EventEmitter(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Notifies when the last `onMicrotaskEmpty` has run and there are no more microtasks, which | 
					
						
							|  |  |  |    * implies we are about to relinquish VM turn. | 
					
						
							|  |  |  |    * This event gets called just once. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   readonly onStable: EventEmitter<any> = new EventEmitter(false); | 
					
						
							| 
									
										
										
										
											2014-12-05 18:30:45 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Notifies that an error has been delivered. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   readonly onError: EventEmitter<any> = new EventEmitter(false); | 
					
						
							| 
									
										
										
										
											2015-07-24 12:46:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-25 14:24:17 -08:00
										 |  |  |   constructor({enableLongStackTrace = false}) { | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |     if (typeof Zone == 'undefined') { | 
					
						
							| 
									
										
										
										
											2017-11-03 11:16:42 +13:00
										 |  |  |       throw new Error(`In this configuration Angular requires Zone.js`); | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Zone.assertZonePatched(); | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |     const self = this as any as NgZonePrivate; | 
					
						
							|  |  |  |     self._nesting = 0; | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |     self._outer = self._inner = Zone.current; | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((Zone as any)['wtfZoneSpec']) { | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |       self._inner = self._inner.fork((Zone as any)['wtfZoneSpec']); | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 11:44:14 -07:00
										 |  |  |     if ((Zone as any)['TaskTrackingZoneSpec']) { | 
					
						
							|  |  |  |       self._inner = self._inner.fork(new ((Zone as any)['TaskTrackingZoneSpec'] as any)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |     if (enableLongStackTrace && (Zone as any)['longStackTraceZoneSpec']) { | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |       self._inner = self._inner.fork((Zone as any)['longStackTraceZoneSpec']); | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |     forkInnerZoneWithAngularBehavior(self); | 
					
						
							| 
									
										
										
										
											2015-07-10 15:12:21 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |   static isInAngularZone(): boolean { return Zone.current.get('isAngularZone') === true; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static assertInAngularZone(): void { | 
					
						
							|  |  |  |     if (!NgZone.isInAngularZone()) { | 
					
						
							|  |  |  |       throw new Error('Expected to be in Angular Zone, but it is not!'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |   static assertNotInAngularZone(): void { | 
					
						
							|  |  |  |     if (NgZone.isInAngularZone()) { | 
					
						
							|  |  |  |       throw new Error('Expected to not be in Angular Zone, but it is!'); | 
					
						
							| 
									
										
										
										
											2016-02-25 14:24:17 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Executes the `fn` function synchronously within the Angular zone and returns value returned by | 
					
						
							|  |  |  |    * the function. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Running functions via `run` allows you to reenter Angular zone from a task that was executed | 
					
						
							| 
									
										
										
										
											2017-04-25 02:15:33 +02:00
										 |  |  |    * outside of the Angular zone (typically started via {@link #runOutsideAngular}). | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |    * | 
					
						
							|  |  |  |    * Any future tasks or microtasks scheduled from within this function will continue executing from | 
					
						
							|  |  |  |    * within the Angular zone. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * If a synchronous error happens it will be rethrown and not reported via `onError`. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2017-07-13 15:36:11 -07:00
										 |  |  |   run<T>(fn: (...args: any[]) => T, applyThis?: any, applyArgs?: any[]): T { | 
					
						
							|  |  |  |     return (this as any as NgZonePrivate)._inner.run(fn, applyThis, applyArgs) as T; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Executes the `fn` function synchronously within the Angular zone as a task and returns value | 
					
						
							|  |  |  |    * returned by the function. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Running functions via `run` allows you to reenter Angular zone from a task that was executed | 
					
						
							|  |  |  |    * outside of the Angular zone (typically started via {@link #runOutsideAngular}). | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Any future tasks or microtasks scheduled from within this function will continue executing from | 
					
						
							|  |  |  |    * within the Angular zone. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * If a synchronous error happens it will be rethrown and not reported via `onError`. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   runTask<T>(fn: (...args: any[]) => T, applyThis?: any, applyArgs?: any[], name?: string): T { | 
					
						
							|  |  |  |     const zone = (this as any as NgZonePrivate)._inner; | 
					
						
							|  |  |  |     const task = zone.scheduleEventTask('NgZoneEvent: ' + name, fn, EMPTY_PAYLOAD, noop, noop); | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       return zone.runTask(task, applyThis, applyArgs) as T; | 
					
						
							|  |  |  |     } finally { | 
					
						
							|  |  |  |       zone.cancelTask(task); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Same as `run`, except that synchronous errors are caught and forwarded via `onError` and not | 
					
						
							|  |  |  |    * rethrown. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2017-07-13 15:36:11 -07:00
										 |  |  |   runGuarded<T>(fn: (...args: any[]) => T, applyThis?: any, applyArgs?: any[]): T { | 
					
						
							|  |  |  |     return (this as any as NgZonePrivate)._inner.runGuarded(fn, applyThis, applyArgs) as T; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by | 
					
						
							|  |  |  |    * the function. | 
					
						
							|  |  |  |    * | 
					
						
							| 
									
										
										
										
											2017-04-25 02:15:33 +02:00
										 |  |  |    * Running functions via {@link #runOutsideAngular} allows you to escape Angular's zone and do | 
					
						
							|  |  |  |    * work that | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |    * doesn't trigger Angular change-detection or is subject to Angular's error handling. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Any future tasks or microtasks scheduled from within this function will continue executing from | 
					
						
							|  |  |  |    * outside of the Angular zone. | 
					
						
							|  |  |  |    * | 
					
						
							| 
									
										
										
										
											2017-04-25 02:15:33 +02:00
										 |  |  |    * Use {@link #run} to reenter the Angular zone and do work that updates the application model. | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2017-07-13 15:36:11 -07:00
										 |  |  |   runOutsideAngular<T>(fn: (...args: any[]) => T): T { | 
					
						
							|  |  |  |     return (this as any as NgZonePrivate)._outer.run(fn) as T; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-10-19 14:41:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-01 14:45:49 -07:00
										 |  |  | function noop() {} | 
					
						
							| 
									
										
										
										
											2017-07-13 15:36:11 -07:00
										 |  |  | const EMPTY_PAYLOAD = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  | interface NgZonePrivate extends NgZone { | 
					
						
							|  |  |  |   _outer: Zone; | 
					
						
							|  |  |  |   _inner: Zone; | 
					
						
							|  |  |  |   _nesting: number; | 
					
						
							| 
									
										
										
										
											2015-10-19 14:41:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |   hasPendingMicrotasks: boolean; | 
					
						
							|  |  |  |   hasPendingMacrotasks: boolean; | 
					
						
							|  |  |  |   isStable: boolean; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-10-19 14:41:15 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  | function checkStable(zone: NgZonePrivate) { | 
					
						
							|  |  |  |   if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       zone._nesting++; | 
					
						
							|  |  |  |       zone.onMicrotaskEmpty.emit(null); | 
					
						
							|  |  |  |     } finally { | 
					
						
							|  |  |  |       zone._nesting--; | 
					
						
							|  |  |  |       if (!zone.hasPendingMicrotasks) { | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |           zone.runOutsideAngular(() => zone.onStable.emit(null)); | 
					
						
							|  |  |  |         } finally { | 
					
						
							|  |  |  |           zone.isStable = true; | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-12-05 18:30:45 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  | function forkInnerZoneWithAngularBehavior(zone: NgZonePrivate) { | 
					
						
							|  |  |  |   zone._inner = zone._inner.fork({ | 
					
						
							|  |  |  |     name: 'angular', | 
					
						
							|  |  |  |     properties: <any>{'isAngularZone': true}, | 
					
						
							|  |  |  |     onInvokeTask: (delegate: ZoneDelegate, current: Zone, target: Zone, task: Task, applyThis: any, | 
					
						
							|  |  |  |                    applyArgs: any): any => { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         onEnter(zone); | 
					
						
							|  |  |  |         return delegate.invokeTask(target, task, applyThis, applyArgs); | 
					
						
							|  |  |  |       } finally { | 
					
						
							|  |  |  |         onLeave(zone); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |     onInvoke: (delegate: ZoneDelegate, current: Zone, target: Zone, callback: Function, | 
					
						
							|  |  |  |                applyThis: any, applyArgs: any[], source: string): any => { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         onEnter(zone); | 
					
						
							|  |  |  |         return delegate.invoke(target, callback, applyThis, applyArgs, source); | 
					
						
							|  |  |  |       } finally { | 
					
						
							|  |  |  |         onLeave(zone); | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     onHasTask: | 
					
						
							|  |  |  |         (delegate: ZoneDelegate, current: Zone, target: Zone, hasTaskState: HasTaskState) => { | 
					
						
							|  |  |  |           delegate.hasTask(target, hasTaskState); | 
					
						
							|  |  |  |           if (current === target) { | 
					
						
							|  |  |  |             // We are only interested in hasTask events which originate from our zone
 | 
					
						
							|  |  |  |             // (A child hasTask event is not interesting to us)
 | 
					
						
							|  |  |  |             if (hasTaskState.change == 'microTask') { | 
					
						
							|  |  |  |               zone.hasPendingMicrotasks = hasTaskState.microTask; | 
					
						
							|  |  |  |               checkStable(zone); | 
					
						
							|  |  |  |             } else if (hasTaskState.change == 'macroTask') { | 
					
						
							|  |  |  |               zone.hasPendingMacrotasks = hasTaskState.macroTask; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |     onHandleError: (delegate: ZoneDelegate, current: Zone, target: Zone, error: any): boolean => { | 
					
						
							|  |  |  |       delegate.handleError(target, error); | 
					
						
							| 
									
										
										
										
											2017-07-20 22:34:19 -07:00
										 |  |  |       zone.runOutsideAngular(() => zone.onError.emit(error)); | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |       return false; | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  | function onEnter(zone: NgZonePrivate) { | 
					
						
							|  |  |  |   zone._nesting++; | 
					
						
							|  |  |  |   if (zone.isStable) { | 
					
						
							|  |  |  |     zone.isStable = false; | 
					
						
							|  |  |  |     zone.onUnstable.emit(null); | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-06 15:23:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-01 10:29:56 -07:00
										 |  |  | function onLeave(zone: NgZonePrivate) { | 
					
						
							|  |  |  |   zone._nesting--; | 
					
						
							|  |  |  |   checkStable(zone); | 
					
						
							| 
									
										
										
										
											2015-04-17 18:06:24 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-06-01 14:45:49 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Provides a noop implementation of `NgZone` which does nothing. This zone requires explicit calls | 
					
						
							|  |  |  |  * to framework to perform rendering. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export class NoopNgZone implements NgZone { | 
					
						
							|  |  |  |   readonly hasPendingMicrotasks: boolean = false; | 
					
						
							|  |  |  |   readonly hasPendingMacrotasks: boolean = false; | 
					
						
							|  |  |  |   readonly isStable: boolean = true; | 
					
						
							|  |  |  |   readonly onUnstable: EventEmitter<any> = new EventEmitter(); | 
					
						
							|  |  |  |   readonly onMicrotaskEmpty: EventEmitter<any> = new EventEmitter(); | 
					
						
							|  |  |  |   readonly onStable: EventEmitter<any> = new EventEmitter(); | 
					
						
							|  |  |  |   readonly onError: EventEmitter<any> = new EventEmitter(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   run(fn: () => any): any { return fn(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   runGuarded(fn: () => any): any { return fn(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   runOutsideAngular(fn: () => any): any { return fn(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   runTask<T>(fn: () => any): any { return fn(); } | 
					
						
							|  |  |  | } |