angular2
Version:
Angular 2 - a web framework for modern web apps
101 lines (88 loc) • 3.56 kB
text/typescript
import {global} from 'angular2/src/facade/lang';
/**
* Stores error information; delivered via [NgZone.onError] stream.
*/
export class NgZoneError {
constructor(public error: any, public stackTrace: any) {}
}
export class NgZoneImpl {
static isInAngularZone(): boolean { return Zone.current.get('isAngularZone') === true; }
/** @internal */
private outer: Zone;
/** @internal */
private inner: Zone;
private onEnter: () => void;
private onLeave: () => void;
private setMicrotask: (hasMicrotasks: boolean) => void;
private setMacrotask: (hasMacrotasks: boolean) => void;
private onError: (error: NgZoneError) => void;
constructor({trace, onEnter, onLeave, setMicrotask, setMacrotask, onError}: {
trace: boolean,
onEnter: () => void,
onLeave: () => void,
setMicrotask: (hasMicrotasks: boolean) => void,
setMacrotask: (hasMacrotasks: boolean) => void,
onError: (error: NgZoneError) => void
}) {
this.onEnter = onEnter;
this.onLeave = onLeave;
this.setMicrotask = setMicrotask;
this.setMacrotask = setMacrotask;
this.onError = onError;
if (Zone) {
this.outer = this.inner = Zone.current;
if (Zone['wtfZoneSpec']) {
this.inner = this.inner.fork(Zone['wtfZoneSpec']);
}
if (trace && Zone['longStackTraceZoneSpec']) {
this.inner = this.inner.fork(Zone['longStackTraceZoneSpec']);
}
this.inner = this.inner.fork({
name: 'angular',
properties:<any>{'isAngularZone': true},
onInvokeTask: (delegate: ZoneDelegate, current: Zone, target: Zone, task: Task,
applyThis: any, applyArgs: any): any => {
try {
this.onEnter();
return delegate.invokeTask(target, task, applyThis, applyArgs);
} finally {
this.onLeave();
}
},
onInvoke: (delegate: ZoneDelegate, current: Zone, target: Zone, callback: Function,
applyThis: any, applyArgs: any[], source: string): any => {
try {
this.onEnter();
return delegate.invoke(target, callback, applyThis, applyArgs, source);
} finally {
this.onLeave();
}
},
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') {
this.setMicrotask(hasTaskState.microTask);
} else if (hasTaskState.change == 'macroTask') {
this.setMacrotask(hasTaskState.macroTask);
}
}
},
onHandleError: (delegate: ZoneDelegate, current: Zone, target: Zone, error: any):
boolean => {
delegate.handleError(target, error);
this.onError(new NgZoneError(error, error.stack));
return false;
}
});
} else {
throw new Error('Angular2 needs to be run with Zone.js polyfill.');
}
}
runInner(fn: () => any): any { return this.inner.run(fn); };
runInnerGuarded(fn: () => any): any { return this.inner.runGuarded(fn); };
runOuter(fn: () => any): any { return this.outer.run(fn); };
}