| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @fileoverview | 
					
						
							|  |  |  |  * @suppress {missingRequire} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (function(global: any) { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  | interface Wtf { | 
					
						
							|  |  |  |   trace: WtfTrace; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | interface WtfScope {} | 
					
						
							|  |  |  | interface WtfRange {} | 
					
						
							|  |  |  | interface WtfTrace { | 
					
						
							|  |  |  |   events: WtfEvents; | 
					
						
							|  |  |  |   leaveScope(scope: WtfScope, returnValue?: any): void; | 
					
						
							|  |  |  |   beginTimeRange(rangeType: string, action: string): WtfRange; | 
					
						
							|  |  |  |   endTimeRange(range: WtfRange): void; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | interface WtfEvents { | 
					
						
							|  |  |  |   createScope(signature: string, flags?: any): WtfScopeFn; | 
					
						
							|  |  |  |   createInstance(signature: string, flags?: any): WtfEventFn; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type WtfScopeFn = (...args: any[]) => WtfScope; | 
					
						
							|  |  |  | type WtfEventFn = (...args: any[]) => any; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Detect and setup WTF.
 | 
					
						
							|  |  |  | let wtfTrace: WtfTrace|null = null; | 
					
						
							|  |  |  | let wtfEvents: WtfEvents|null = null; | 
					
						
							|  |  |  | const wtfEnabled: boolean = (function(): boolean { | 
					
						
							|  |  |  |   const wtf: Wtf = global['wtf']; | 
					
						
							|  |  |  |   if (wtf) { | 
					
						
							|  |  |  |     wtfTrace = wtf.trace; | 
					
						
							|  |  |  |     if (wtfTrace) { | 
					
						
							|  |  |  |       wtfEvents = wtfTrace.events; | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   return false; | 
					
						
							|  |  |  | })(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WtfZoneSpec implements ZoneSpec { | 
					
						
							|  |  |  |   name: string = 'WTF'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static forkInstance = | 
					
						
							|  |  |  |       wtfEnabled ? wtfEvents!.createInstance('Zone:fork(ascii zone, ascii newZone)') : null; | 
					
						
							|  |  |  |   static scheduleInstance: {[key: string]: WtfEventFn} = {}; | 
					
						
							|  |  |  |   static cancelInstance: {[key: string]: WtfEventFn} = {}; | 
					
						
							|  |  |  |   static invokeScope: {[key: string]: WtfEventFn} = {}; | 
					
						
							|  |  |  |   static invokeTaskScope: {[key: string]: WtfEventFn} = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   onFork(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, zoneSpec: ZoneSpec): | 
					
						
							|  |  |  |       Zone { | 
					
						
							|  |  |  |     const retValue = parentZoneDelegate.fork(targetZone, zoneSpec); | 
					
						
							|  |  |  |     WtfZoneSpec.forkInstance!(zonePathName(targetZone), retValue.name); | 
					
						
							|  |  |  |     return retValue; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   onInvoke( | 
					
						
							|  |  |  |       parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, delegate: Function, | 
					
						
							|  |  |  |       applyThis: any, applyArgs?: any[], source?: string): any { | 
					
						
							|  |  |  |     const src = source || 'unknown'; | 
					
						
							|  |  |  |     let scope = WtfZoneSpec.invokeScope[src]; | 
					
						
							|  |  |  |     if (!scope) { | 
					
						
							|  |  |  |       scope = WtfZoneSpec.invokeScope[src] = | 
					
						
							|  |  |  |           wtfEvents!.createScope(`Zone:invoke:${source}(ascii zone)`); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     return wtfTrace!.leaveScope( | 
					
						
							|  |  |  |         scope(zonePathName(targetZone)), | 
					
						
							|  |  |  |         parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   onHandleError(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, error: any): | 
					
						
							|  |  |  |       boolean { | 
					
						
							|  |  |  |     return parentZoneDelegate.handleError(targetZone, error); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   onScheduleTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task): | 
					
						
							|  |  |  |       any { | 
					
						
							|  |  |  |     const key = task.type + ':' + task.source; | 
					
						
							|  |  |  |     let instance = WtfZoneSpec.scheduleInstance[key]; | 
					
						
							|  |  |  |     if (!instance) { | 
					
						
							|  |  |  |       instance = WtfZoneSpec.scheduleInstance[key] = | 
					
						
							|  |  |  |           wtfEvents!.createInstance(`Zone:schedule:${key}(ascii zone, any data)`); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     const retValue = parentZoneDelegate.scheduleTask(targetZone, task); | 
					
						
							|  |  |  |     instance(zonePathName(targetZone), shallowObj(task.data, 2)); | 
					
						
							|  |  |  |     return retValue; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   onInvokeTask( | 
					
						
							|  |  |  |       parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task, | 
					
						
							|  |  |  |       applyThis?: any, applyArgs?: any[]): any { | 
					
						
							|  |  |  |     const source = task.source; | 
					
						
							|  |  |  |     let scope = WtfZoneSpec.invokeTaskScope[source]; | 
					
						
							|  |  |  |     if (!scope) { | 
					
						
							|  |  |  |       scope = WtfZoneSpec.invokeTaskScope[source] = | 
					
						
							|  |  |  |           wtfEvents!.createScope(`Zone:invokeTask:${source}(ascii zone)`); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     return wtfTrace!.leaveScope( | 
					
						
							|  |  |  |         scope(zonePathName(targetZone)), | 
					
						
							|  |  |  |         parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   onCancelTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task): | 
					
						
							|  |  |  |       any { | 
					
						
							|  |  |  |     const key = task.source; | 
					
						
							|  |  |  |     let instance = WtfZoneSpec.cancelInstance[key]; | 
					
						
							|  |  |  |     if (!instance) { | 
					
						
							|  |  |  |       instance = WtfZoneSpec.cancelInstance[key] = | 
					
						
							|  |  |  |           wtfEvents!.createInstance(`Zone:cancel:${key}(ascii zone, any options)`); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     const retValue = parentZoneDelegate.cancelTask(targetZone, task); | 
					
						
							|  |  |  |     instance(zonePathName(targetZone), shallowObj(task.data, 2)); | 
					
						
							|  |  |  |     return retValue; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function shallowObj(obj: {[k: string]: any}|undefined, depth: number): any { | 
					
						
							|  |  |  |   if (!obj || !depth) return null; | 
					
						
							|  |  |  |   const out: {[k: string]: any} = {}; | 
					
						
							|  |  |  |   for (const key in obj) { | 
					
						
							|  |  |  |     if (obj.hasOwnProperty(key)) { | 
					
						
							|  |  |  |       // explicit : any due to https://github.com/microsoft/TypeScript/issues/33191
 | 
					
						
							|  |  |  |       let value: any = obj[key]; | 
					
						
							|  |  |  |       switch (typeof value) { | 
					
						
							|  |  |  |         case 'object': | 
					
						
							|  |  |  |           const name = value && value.constructor && (<any>value.constructor).name; | 
					
						
							|  |  |  |           value = name == (<any>Object).name ? shallowObj(value, depth - 1) : name; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         case 'function': | 
					
						
							|  |  |  |           value = value.name || undefined; | 
					
						
							|  |  |  |           break; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       out[key] = value; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   return out; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function zonePathName(zone: Zone) { | 
					
						
							|  |  |  |   let name: string = zone.name; | 
					
						
							|  |  |  |   let localZone = zone.parent; | 
					
						
							|  |  |  |   while (localZone != null) { | 
					
						
							|  |  |  |     name = localZone.name + '::' + name; | 
					
						
							|  |  |  |     localZone = localZone.parent; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   return name; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  | (Zone as any)['wtfZoneSpec'] = !wtfEnabled ? null : new WtfZoneSpec(); | 
					
						
							| 
									
										
										
										
											2019-07-08 11:30:29 -07:00
										 |  |  | })(typeof window === 'object' && window || typeof self === 'object' && self || global); |