diff --git a/lib/zone-spec/fake-async-test.ts b/lib/zone-spec/fake-async-test.ts index 953d246f8..9d2ce990e 100644 --- a/lib/zone-spec/fake-async-test.ts +++ b/lib/zone-spec/fake-async-test.ts @@ -1,259 +1,261 @@ -interface ScheduledFunction { - endTime: number; - id: number, - func: Function; - args: any[]; - delay: number; -} - -class Scheduler { - // Next scheduler id. - public nextId: number = 0; - - // Scheduler queue with the tuple of end time and callback function - sorted by end time. - private _schedulerQueue: ScheduledFunction[] = []; - // Current simulated time in millis. - private _currentTime: number = 0; - - constructor() {} - - scheduleFunction(cb: Function, delay: number, args: any[] = [], id: number = -1) : number { - let currentId: number = id < 0 ? this.nextId++ : id; - let endTime = this._currentTime + delay; - - // Insert so that scheduler queue remains sorted by end time. - let newEntry: ScheduledFunction = { - endTime: endTime, - id: currentId, - func: cb, - args: args, - delay: delay - } - let i = 0; - for (; i < this._schedulerQueue.length; i++) { - let currentEntry = this._schedulerQueue[i]; - if (newEntry.endTime < currentEntry.endTime) { - break; - } - } - this._schedulerQueue.splice(i, 0, newEntry); - return currentId; +(function(global: any) { + interface ScheduledFunction { + endTime: number; + id: number, + func: Function; + args: any[]; + delay: number; } - removeScheduledFunctionWithId(id: number): void { - for (let i = 0; i < this._schedulerQueue.length; i++) { - if (this._schedulerQueue[i].id == id) { - this._schedulerQueue.splice(i, 1); - break; + class Scheduler { + // Next scheduler id. + public nextId: number = 0; + + // Scheduler queue with the tuple of end time and callback function - sorted by end time. + private _schedulerQueue: ScheduledFunction[] = []; + // Current simulated time in millis. + private _currentTime: number = 0; + + constructor() {} + + scheduleFunction(cb: Function, delay: number, args: any[] = [], id: number = -1) : number { + let currentId: number = id < 0 ? this.nextId++ : id; + let endTime = this._currentTime + delay; + + // Insert so that scheduler queue remains sorted by end time. + let newEntry: ScheduledFunction = { + endTime: endTime, + id: currentId, + func: cb, + args: args, + delay: delay } + let i = 0; + for (; i < this._schedulerQueue.length; i++) { + let currentEntry = this._schedulerQueue[i]; + if (newEntry.endTime < currentEntry.endTime) { + break; + } + } + this._schedulerQueue.splice(i, 0, newEntry); + return currentId; } - } - - tick(millis: number = 0): void { - this._currentTime += millis; - while (this._schedulerQueue.length > 0) { - let current = this._schedulerQueue[0]; - if (this._currentTime < current.endTime) { - // Done processing the queue since it's sorted by endTime. - break; - } else { - // Time to run scheduled function. Remove it from the head of queue. - let current = this._schedulerQueue.shift(); - let retval = current.func.apply(global, current.args); - if (!retval) { - // Uncaught exception in the current scheduled function. Stop processing the queue. + + removeScheduledFunctionWithId(id: number): void { + for (let i = 0; i < this._schedulerQueue.length; i++) { + if (this._schedulerQueue[i].id == id) { + this._schedulerQueue.splice(i, 1); break; } } } - } -} - -class FakeAsyncTestZoneSpec implements ZoneSpec { - static assertInZone(): void { - if (Zone.current.get('FakeAsyncTestZoneSpec') == null) { - throw new Error('The code should be running in the fakeAsync zone to call this function'); + + tick(millis: number = 0): void { + this._currentTime += millis; + while (this._schedulerQueue.length > 0) { + let current = this._schedulerQueue[0]; + if (this._currentTime < current.endTime) { + // Done processing the queue since it's sorted by endTime. + break; + } else { + // Time to run scheduled function. Remove it from the head of queue. + let current = this._schedulerQueue.shift(); + let retval = current.func.apply(global, current.args); + if (!retval) { + // Uncaught exception in the current scheduled function. Stop processing the queue. + break; + } + } + } } } - private _scheduler: Scheduler = new Scheduler(); - private _microtasks: Function[] = []; - private _lastError: Error = null; - private _uncaughtPromiseErrors: {rejection: any}[] = Promise[Zone['__symbol__']('uncaughtPromiseErrors')]; - - pendingPeriodicTimers: number[] = []; - pendingTimers: number[] = []; + class FakeAsyncTestZoneSpec implements ZoneSpec { + static assertInZone(): void { + if (Zone.current.get('FakeAsyncTestZoneSpec') == null) { + throw new Error('The code should be running in the fakeAsync zone to call this function'); + } + } + + private _scheduler: Scheduler = new Scheduler(); + private _microtasks: Function[] = []; + private _lastError: Error = null; + private _uncaughtPromiseErrors: {rejection: any}[] = Promise[Zone['__symbol__']('uncaughtPromiseErrors')]; + + pendingPeriodicTimers: number[] = []; + pendingTimers: number[] = []; - constructor(namePrefix: string) { - this.name = 'fakeAsyncTestZone for ' + namePrefix; - } + constructor(namePrefix: string) { + this.name = 'fakeAsyncTestZone for ' + namePrefix; + } - private _fnAndFlush(fn: Function, - completers: {onSuccess?: Function, onError?: Function}): Function { - return (...args): boolean => { - fn.apply(global, args); - - if (this._lastError === null) { // Success - if (completers.onSuccess != null) { - completers.onSuccess.apply(global); - } - // Flush microtasks only on success. - this.flushMicrotasks(); - } else { // Failure - if (completers.onError != null) { - completers.onError.apply(global); + private _fnAndFlush(fn: Function, + completers: {onSuccess?: Function, onError?: Function}): Function { + return (...args): boolean => { + fn.apply(global, args); + + if (this._lastError === null) { // Success + if (completers.onSuccess != null) { + completers.onSuccess.apply(global); + } + // Flush microtasks only on success. + this.flushMicrotasks(); + } else { // Failure + if (completers.onError != null) { + completers.onError.apply(global); + } } + // Return true if there were no errors, false otherwise. + return this._lastError === null; } - // Return true if there were no errors, false otherwise. - return this._lastError === null; } - } - - private static _removeTimer(timers: number[], id:number): void { - let index = timers.indexOf(id); - if (index > -1) { - timers.splice(index, 1); - } - } - - private _dequeueTimer(id: number): Function { - return () => { - FakeAsyncTestZoneSpec._removeTimer(this.pendingTimers, id); - }; - } - - private _requeuePeriodicTimer( - fn: Function, interval: number, args: any[], id: number): Function { - return () => { - // Requeue the timer callback if it's not been canceled. - if (this.pendingPeriodicTimers.indexOf(id) !== -1) { - this._scheduler.scheduleFunction(fn, interval, args, id); + + private static _removeTimer(timers: number[], id:number): void { + let index = timers.indexOf(id); + if (index > -1) { + timers.splice(index, 1); + } + } + + private _dequeueTimer(id: number): Function { + return () => { + FakeAsyncTestZoneSpec._removeTimer(this.pendingTimers, id); + }; + } + + private _requeuePeriodicTimer( + fn: Function, interval: number, args: any[], id: number): Function { + return () => { + // Requeue the timer callback if it's not been canceled. + if (this.pendingPeriodicTimers.indexOf(id) !== -1) { + this._scheduler.scheduleFunction(fn, interval, args, id); + } } } - } - - private _dequeuePeriodicTimer(id: number): Function { - return () => { - FakeAsyncTestZoneSpec._removeTimer(this.pendingPeriodicTimers, id); - }; - } - - private _setTimeout(fn: Function, delay: number, args: any[]): number { - let removeTimerFn = this._dequeueTimer(this._scheduler.nextId); - // Queue the callback and dequeue the timer on success and error. - let cb = this._fnAndFlush(fn, {onSuccess: removeTimerFn, onError: removeTimerFn}); - let id = this._scheduler.scheduleFunction(cb, delay, args); - this.pendingTimers.push(id); - return id; - } - - private _clearTimeout(id: number): void { - FakeAsyncTestZoneSpec._removeTimer(this.pendingTimers, id); - this._scheduler.removeScheduledFunctionWithId(id); - } - - private _setInterval(fn: Function, interval: number, ...args): number { - let id = this._scheduler.nextId; - let completers = {onSuccess: null, onError: this._dequeuePeriodicTimer(id)}; - let cb = this._fnAndFlush(fn, completers); - // Use the callback created above to requeue on success. - completers.onSuccess = this._requeuePeriodicTimer(cb, interval, args, id); + private _dequeuePeriodicTimer(id: number): Function { + return () => { + FakeAsyncTestZoneSpec._removeTimer(this.pendingPeriodicTimers, id); + }; + } - // Queue the callback and dequeue the periodic timer only on error. - this._scheduler.scheduleFunction(cb, interval, args); - this.pendingPeriodicTimers.push(id); - return id; - } - - private _clearInterval(id: number): void { - FakeAsyncTestZoneSpec._removeTimer(this.pendingPeriodicTimers, id); - this._scheduler.removeScheduledFunctionWithId(id); - } + private _setTimeout(fn: Function, delay: number, args: any[]): number { + let removeTimerFn = this._dequeueTimer(this._scheduler.nextId); + // Queue the callback and dequeue the timer on success and error. + let cb = this._fnAndFlush(fn, {onSuccess: removeTimerFn, onError: removeTimerFn}); + let id = this._scheduler.scheduleFunction(cb, delay, args); + this.pendingTimers.push(id); + return id; + } + + private _clearTimeout(id: number): void { + FakeAsyncTestZoneSpec._removeTimer(this.pendingTimers, id); + this._scheduler.removeScheduledFunctionWithId(id); + } + + private _setInterval(fn: Function, interval: number, ...args): number { + let id = this._scheduler.nextId; + let completers = {onSuccess: null, onError: this._dequeuePeriodicTimer(id)}; + let cb = this._fnAndFlush(fn, completers); + + // Use the callback created above to requeue on success. + completers.onSuccess = this._requeuePeriodicTimer(cb, interval, args, id); + + // Queue the callback and dequeue the periodic timer only on error. + this._scheduler.scheduleFunction(cb, interval, args); + this.pendingPeriodicTimers.push(id); + return id; + } - private _resetLastErrorAndThrow(): void { - let error = this._lastError || this._uncaughtPromiseErrors[0]; - this._uncaughtPromiseErrors.length = 0; - this._lastError = null; - throw error; - } - - tick(millis: number = 0): void { - FakeAsyncTestZoneSpec.assertInZone(); - this.flushMicrotasks(); - this._scheduler.tick(millis); - if (this._lastError !== null) { - this._resetLastErrorAndThrow(); + private _clearInterval(id: number): void { + FakeAsyncTestZoneSpec._removeTimer(this.pendingPeriodicTimers, id); + this._scheduler.removeScheduledFunctionWithId(id); } - } - flushMicrotasks(): void { - FakeAsyncTestZoneSpec.assertInZone(); - const flushErrors = () => { - if (this._lastError !== null || this._uncaughtPromiseErrors.length) { - // If there is an error stop processing the microtask queue and rethrow the error. + private _resetLastErrorAndThrow(): void { + let error = this._lastError || this._uncaughtPromiseErrors[0]; + this._uncaughtPromiseErrors.length = 0; + this._lastError = null; + throw error; + } + + tick(millis: number = 0): void { + FakeAsyncTestZoneSpec.assertInZone(); + this.flushMicrotasks(); + this._scheduler.tick(millis); + if (this._lastError !== null) { this._resetLastErrorAndThrow(); } } - while (this._microtasks.length > 0) { - let microtask = this._microtasks.shift(); - microtask(); + + flushMicrotasks(): void { + FakeAsyncTestZoneSpec.assertInZone(); + const flushErrors = () => { + if (this._lastError !== null || this._uncaughtPromiseErrors.length) { + // If there is an error stop processing the microtask queue and rethrow the error. + this._resetLastErrorAndThrow(); + } + } + while (this._microtasks.length > 0) { + let microtask = this._microtasks.shift(); + microtask(); + } + flushErrors(); } - flushErrors(); - } - // ZoneSpec implementation below. + // ZoneSpec implementation below. - name: string; + name: string; - properties: { [key: string]: any } = { 'FakeAsyncTestZoneSpec': this }; + properties: { [key: string]: any } = { 'FakeAsyncTestZoneSpec': this }; - onScheduleTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task): Task { - switch (task.type) { - case 'microTask': - this._microtasks.push(task.invoke); - break; - case 'macroTask': - switch (task.source) { - case 'setTimeout': - task.data['handleId'] = - this._setTimeout(task.invoke, task.data['delay'], task.data['args']); - break; - case 'setInterval': - task.data['handleId'] = - this._setInterval(task.invoke, task.data['delay'], task.data['args']); - break; - case 'XMLHttpRequest.send': - throw new Error('Cannot make XHRs from within a fake async test.'); - default: - task = delegate.scheduleTask(target, task); - } - break; - case 'eventTask': - task = delegate.scheduleTask(target, task); - break; + onScheduleTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task): Task { + switch (task.type) { + case 'microTask': + this._microtasks.push(task.invoke); + break; + case 'macroTask': + switch (task.source) { + case 'setTimeout': + task.data['handleId'] = + this._setTimeout(task.invoke, task.data['delay'], task.data['args']); + break; + case 'setInterval': + task.data['handleId'] = + this._setInterval(task.invoke, task.data['delay'], task.data['args']); + break; + case 'XMLHttpRequest.send': + throw new Error('Cannot make XHRs from within a fake async test.'); + default: + task = delegate.scheduleTask(target, task); + } + break; + case 'eventTask': + task = delegate.scheduleTask(target, task); + break; + } + return task; } - return task; - } - onCancelTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task): any { - switch (task.source) { - case 'setTimeout': - return this._clearTimeout(task.data['handleId']); - case 'setInterval': - return this._clearInterval(task.data['handleId']); - default: - return delegate.cancelTask(target, task); + onCancelTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task): any { + switch (task.source) { + case 'setTimeout': + return this._clearTimeout(task.data['handleId']); + case 'setInterval': + return this._clearInterval(task.data['handleId']); + default: + return delegate.cancelTask(target, task); + } + } + + onHandleError(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, + error: any): boolean { + this._lastError = error; + return false; // Don't propagate error to parent zone. } } - - onHandleError(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, - error: any): boolean { - this._lastError = error; - return false; // Don't propagate error to parent zone. - } -} -// Export the class so that new instances can be created with proper -// constructor params. -Zone['FakeAsyncTestZoneSpec'] = FakeAsyncTestZoneSpec; + // Export the class so that new instances can be created with proper + // constructor params. + Zone['FakeAsyncTestZoneSpec'] = FakeAsyncTestZoneSpec; +})(typeof window === 'object' && window || typeof self === 'object' && self || global); diff --git a/lib/zone-spec/wtf.ts b/lib/zone-spec/wtf.ts index 27b0f2d96..7ae79140d 100644 --- a/lib/zone-spec/wtf.ts +++ b/lib/zone-spec/wtf.ts @@ -1,138 +1,140 @@ -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; -} +(function(global) { + 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; + type WtfScopeFn = (...args: any[]) => WtfScope; + type WtfEventFn = (...args: any[]) => any; -// Detect and setup WTF. -let wtfTrace: WtfTrace = null; -let wtfEvents: WtfEvents = null; -const wtfEnabled: boolean = (function (): boolean { - const wtf: Wtf = global['wtf']; - if (wtf) { - wtfTrace = wtf.trace; - if (wtfTrace) { - wtfEvents = wtfTrace.events; - return true; + // Detect and setup WTF. + let wtfTrace: WtfTrace = null; + let wtfEvents: WtfEvents = null; + const wtfEnabled: boolean = (function (): boolean { + const wtf: Wtf = global['wtf']; + if (wtf) { + wtfTrace = wtf.trace; + if (wtfTrace) { + wtfEvents = wtfTrace.events; + return true; + } } - } - return false; -})(); + return false; + })(); -class WtfZoneSpec implements ZoneSpec { - name: string = 'WTF'; + class WtfZoneSpec implements ZoneSpec { + name: string = 'WTF'; - static forkInstance = wtfEnabled && wtfEvents.createInstance('Zone:fork(ascii zone, ascii newZone)'); - static scheduleInstance: {[key: string]: WtfEventFn} = {}; - static cancelInstance: {[key: string]: WtfEventFn} = {}; - static invokeScope: {[key: string]: WtfEventFn} = {}; - static invokeTaskScope: {[key: string]: WtfEventFn} = {}; + static forkInstance = wtfEnabled && wtfEvents.createInstance('Zone:fork(ascii zone, ascii newZone)'); + 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; - } + onFork(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, + zoneSpec: ZoneSpec): Zone { + const retValue = parentZoneDelegate.fork(targetZone, zoneSpec); + WtfZoneSpec.forkInstance(zonePathName(targetZone), retValue.name); + return retValue; + } - onInvoke(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, - delegate: Function, applyThis: any, applyArgs: any[], source: string): any { - let scope = WtfZoneSpec.invokeScope[source]; - if (!scope) { - scope = WtfZoneSpec.invokeScope[source] - = wtfEvents.createScope(`Zone:invoke:${source}(ascii zone)`); + onInvoke(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, + delegate: Function, applyThis: any, applyArgs: any[], source: string): any { + let scope = WtfZoneSpec.invokeScope[source]; + if (!scope) { + scope = WtfZoneSpec.invokeScope[source] + = wtfEvents.createScope(`Zone:invoke:${source}(ascii zone)`); + } + return wtfTrace.leaveScope(scope(zonePathName(targetZone)), + parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source)); } - return wtfTrace.leaveScope(scope(zonePathName(targetZone)), - parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source)); - } - onHandleError(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, - error: any): boolean { - return parentZoneDelegate.handleError(targetZone, error); - } + onHandleError(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, + error: any): boolean { + return parentZoneDelegate.handleError(targetZone, error); + } - 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)`); + 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)`); + } + const retValue = parentZoneDelegate.scheduleTask(targetZone, task); + instance(zonePathName(targetZone), shallowObj(task.data, 2)); + return retValue; } - const retValue = parentZoneDelegate.scheduleTask(targetZone, task); - instance(zonePathName(targetZone), shallowObj(task.data, 2)); - return retValue; - } - 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)`); + 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)`); + } + return wtfTrace.leaveScope(scope(zonePathName(targetZone)), + parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs)); } - return wtfTrace.leaveScope(scope(zonePathName(targetZone)), - parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs)); - } - 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)`); - } - const retValue = parentZoneDelegate.cancelTask(targetZone, task); - instance(zonePathName(targetZone), shallowObj(task.data, 2)); - return retValue; - }; -} + 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)`); + } + const retValue = parentZoneDelegate.cancelTask(targetZone, task); + instance(zonePathName(targetZone), shallowObj(task.data, 2)); + return retValue; + }; + } -function shallowObj(obj: any, depth: number): any { - if (!depth) return null; - const out = {}; - for(const key in obj) { - if (obj.hasOwnProperty(key)) { - let value = obj[key]; - switch (typeof value) { - case 'object': - const name = value && value.constructor && (value.constructor).name; - value = name == (Object).name ? shallowObj(value, depth - 1) : name; - break; - case 'function': - value = value.name || undefined; - break; + function shallowObj(obj: any, depth: number): any { + if (!depth) return null; + const out = {}; + for(const key in obj) { + if (obj.hasOwnProperty(key)) { + let value = obj[key]; + switch (typeof value) { + case 'object': + const name = value && value.constructor && (value.constructor).name; + value = name == (Object).name ? shallowObj(value, depth - 1) : name; + break; + case 'function': + value = value.name || undefined; + break; + } + out[key] = value; } - out[key] = value; } + return out; } - return out; -} -function zonePathName(zone: Zone) { - let name: string = zone.name; - zone = zone.parent; - while(zone != null) { - name = zone.name + '::' + name; + function zonePathName(zone: Zone) { + let name: string = zone.name; zone = zone.parent; + while(zone != null) { + name = zone.name + '::' + name; + zone = zone.parent; + } + return name; } - return name; -} -Zone['wtfZoneSpec'] = !wtfEnabled ? null : new WtfZoneSpec(); + Zone['wtfZoneSpec'] = !wtfEnabled ? null : new WtfZoneSpec(); +})(typeof window === 'object' && window || typeof self === 'object' && self || global);