UNPKG

zone.js

Version:
1,182 lines (1,168 loc) 91.8 kB
/** * @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 */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); }(this, (function () { 'use strict'; /** * @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 */ var Zone$1 = (function (global) { var FUNCTION = 'function'; var performance = global['performance']; function mark(name) { performance && performance['mark'] && performance['mark'](name); } function performanceMeasure(name, label) { performance && performance['measure'] && performance['measure'](name, label); } mark('Zone'); if (global['Zone']) { throw new Error('Zone already loaded.'); } var Zone = (function () { function Zone(parent, zoneSpec) { this._properties = null; this._parent = parent; this._name = zoneSpec ? zoneSpec.name || 'unnamed' : '<root>'; this._properties = zoneSpec && zoneSpec.properties || {}; this._zoneDelegate = new ZoneDelegate(this, this._parent && this._parent._zoneDelegate, zoneSpec); } Zone.assertZonePatched = function () { if (global['Promise'] !== patches['ZoneAwarePromise']) { throw new Error('Zone.js has detected that ZoneAwarePromise `(window|global).Promise` ' + 'has been overwritten.\n' + 'Most likely cause is that a Promise polyfill has been loaded ' + 'after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. ' + 'If you must load one, do so before loading zone.js.)'); } }; Object.defineProperty(Zone, "root", { get: function () { var zone = Zone.current; while (zone.parent) { zone = zone.parent; } return zone; }, enumerable: true, configurable: true }); Object.defineProperty(Zone, "current", { get: function () { return _currentZoneFrame.zone; }, enumerable: true, configurable: true }); Object.defineProperty(Zone, "currentTask", { get: function () { return _currentTask; }, enumerable: true, configurable: true }); Zone.__load_patch = function (name, fn) { if (patches.hasOwnProperty(name)) { throw Error('Already loaded patch: ' + name); } else if (!global['__Zone_disable_' + name]) { var perfName = 'Zone:' + name; mark(perfName); patches[name] = fn(global, Zone, _api); performanceMeasure(perfName, perfName); } }; Object.defineProperty(Zone.prototype, "parent", { get: function () { return this._parent; }, enumerable: true, configurable: true }); Object.defineProperty(Zone.prototype, "name", { get: function () { return this._name; }, enumerable: true, configurable: true }); Zone.prototype.get = function (key) { var zone = this.getZoneWith(key); if (zone) return zone._properties[key]; }; Zone.prototype.getZoneWith = function (key) { var current = this; while (current) { if (current._properties.hasOwnProperty(key)) { return current; } current = current._parent; } return null; }; Zone.prototype.fork = function (zoneSpec) { if (!zoneSpec) throw new Error('ZoneSpec required!'); return this._zoneDelegate.fork(this, zoneSpec); }; Zone.prototype.wrap = function (callback, source) { if (typeof callback !== FUNCTION) { throw new Error('Expecting function got: ' + callback); } var _callback = this._zoneDelegate.intercept(this, callback, source); var zone = this; return function () { return zone.runGuarded(_callback, this, arguments, source); }; }; Zone.prototype.run = function (callback, applyThis, applyArgs, source) { if (applyThis === void 0) { applyThis = undefined; } if (applyArgs === void 0) { applyArgs = null; } if (source === void 0) { source = null; } _currentZoneFrame = { parent: _currentZoneFrame, zone: this }; try { return this._zoneDelegate.invoke(this, callback, applyThis, applyArgs, source); } finally { _currentZoneFrame = _currentZoneFrame.parent; } }; Zone.prototype.runGuarded = function (callback, applyThis, applyArgs, source) { if (applyThis === void 0) { applyThis = null; } if (applyArgs === void 0) { applyArgs = null; } if (source === void 0) { source = null; } _currentZoneFrame = { parent: _currentZoneFrame, zone: this }; try { try { return this._zoneDelegate.invoke(this, callback, applyThis, applyArgs, source); } catch (error) { if (this._zoneDelegate.handleError(this, error)) { throw error; } } } finally { _currentZoneFrame = _currentZoneFrame.parent; } }; Zone.prototype.runTask = function (task, applyThis, applyArgs) { if (task.zone != this) { throw new Error('A task can only be run in the zone of creation! (Creation: ' + (task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')'); } // https://github.com/angular/zone.js/issues/778, sometimes eventTask // will run in notScheduled(canceled) state, we should not try to // run such kind of task but just return // we have to define an variable here, if not // typescript compiler will complain below var isNotScheduled = task.state === notScheduled; if (isNotScheduled && task.type === eventTask) { return; } var reEntryGuard = task.state != running; reEntryGuard && task._transitionTo(running, scheduled); task.runCount++; var previousTask = _currentTask; _currentTask = task; _currentZoneFrame = { parent: _currentZoneFrame, zone: this }; try { if (task.type == macroTask && task.data && !task.data.isPeriodic) { task.cancelFn = null; } try { return this._zoneDelegate.invokeTask(this, task, applyThis, applyArgs); } catch (error) { if (this._zoneDelegate.handleError(this, error)) { throw error; } } } finally { // if the task's state is notScheduled or unknown, then it has already been cancelled // we should not reset the state to scheduled if (task.state !== notScheduled && task.state !== unknown) { if (task.type == eventTask || (task.data && task.data.isPeriodic)) { reEntryGuard && task._transitionTo(scheduled, running); } else { task.runCount = 0; this._updateTaskCount(task, -1); reEntryGuard && task._transitionTo(notScheduled, running, notScheduled); } } _currentZoneFrame = _currentZoneFrame.parent; _currentTask = previousTask; } }; Zone.prototype.scheduleTask = function (task) { if (task.zone && task.zone !== this) { // check if the task was rescheduled, the newZone // should not be the children of the original zone var newZone = this; while (newZone) { if (newZone === task.zone) { throw Error("can not reschedule task to " + this .name + " which is descendants of the original zone " + task.zone.name); } newZone = newZone.parent; } } task._transitionTo(scheduling, notScheduled); var zoneDelegates = []; task._zoneDelegates = zoneDelegates; task._zone = this; try { task = this._zoneDelegate.scheduleTask(this, task); } catch (err) { // should set task's state to unknown when scheduleTask throw error // because the err may from reschedule, so the fromState maybe notScheduled task._transitionTo(unknown, scheduling, notScheduled); // TODO: @JiaLiPassion, should we check the result from handleError? this._zoneDelegate.handleError(this, err); throw err; } if (task._zoneDelegates === zoneDelegates) { // we have to check because internally the delegate can reschedule the task. this._updateTaskCount(task, 1); } if (task.state == scheduling) { task._transitionTo(scheduled, scheduling); } return task; }; Zone.prototype.scheduleMicroTask = function (source, callback, data, customSchedule) { return this.scheduleTask(new ZoneTask(microTask, source, callback, data, customSchedule, null)); }; Zone.prototype.scheduleMacroTask = function (source, callback, data, customSchedule, customCancel) { return this.scheduleTask(new ZoneTask(macroTask, source, callback, data, customSchedule, customCancel)); }; Zone.prototype.scheduleEventTask = function (source, callback, data, customSchedule, customCancel) { return this.scheduleTask(new ZoneTask(eventTask, source, callback, data, customSchedule, customCancel)); }; Zone.prototype.cancelTask = function (task) { if (task.zone != this) throw new Error('A task can only be cancelled in the zone of creation! (Creation: ' + (task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')'); task._transitionTo(canceling, scheduled, running); try { this._zoneDelegate.cancelTask(this, task); } catch (err) { // if error occurs when cancelTask, transit the state to unknown task._transitionTo(unknown, canceling); this._zoneDelegate.handleError(this, err); throw err; } this._updateTaskCount(task, -1); task._transitionTo(notScheduled, canceling); task.runCount = 0; return task; }; Zone.prototype._updateTaskCount = function (task, count) { var zoneDelegates = task._zoneDelegates; if (count == -1) { task._zoneDelegates = null; } for (var i = 0; i < zoneDelegates.length; i++) { zoneDelegates[i]._updateTaskCount(task.type, count); } }; return Zone; }()); Zone.__symbol__ = __symbol__; var DELEGATE_ZS = { name: '', onHasTask: function (delegate, _, target, hasTaskState) { return delegate.hasTask(target, hasTaskState); }, onScheduleTask: function (delegate, _, target, task) { return delegate.scheduleTask(target, task); }, onInvokeTask: function (delegate, _, target, task, applyThis, applyArgs) { return delegate.invokeTask(target, task, applyThis, applyArgs); }, onCancelTask: function (delegate, _, target, task) { return delegate.cancelTask(target, task); } }; var ZoneDelegate = (function () { function ZoneDelegate(zone, parentDelegate, zoneSpec) { this._taskCounts = { 'microTask': 0, 'macroTask': 0, 'eventTask': 0 }; this.zone = zone; this._parentDelegate = parentDelegate; this._forkZS = zoneSpec && (zoneSpec && zoneSpec.onFork ? zoneSpec : parentDelegate._forkZS); this._forkDlgt = zoneSpec && (zoneSpec.onFork ? parentDelegate : parentDelegate._forkDlgt); this._forkCurrZone = zoneSpec && (zoneSpec.onFork ? this.zone : parentDelegate.zone); this._interceptZS = zoneSpec && (zoneSpec.onIntercept ? zoneSpec : parentDelegate._interceptZS); this._interceptDlgt = zoneSpec && (zoneSpec.onIntercept ? parentDelegate : parentDelegate._interceptDlgt); this._interceptCurrZone = zoneSpec && (zoneSpec.onIntercept ? this.zone : parentDelegate.zone); this._invokeZS = zoneSpec && (zoneSpec.onInvoke ? zoneSpec : parentDelegate._invokeZS); this._invokeDlgt = zoneSpec && (zoneSpec.onInvoke ? parentDelegate : parentDelegate._invokeDlgt); this._invokeCurrZone = zoneSpec && (zoneSpec.onInvoke ? this.zone : parentDelegate.zone); this._handleErrorZS = zoneSpec && (zoneSpec.onHandleError ? zoneSpec : parentDelegate._handleErrorZS); this._handleErrorDlgt = zoneSpec && (zoneSpec.onHandleError ? parentDelegate : parentDelegate._handleErrorDlgt); this._handleErrorCurrZone = zoneSpec && (zoneSpec.onHandleError ? this.zone : parentDelegate.zone); this._scheduleTaskZS = zoneSpec && (zoneSpec.onScheduleTask ? zoneSpec : parentDelegate._scheduleTaskZS); this._scheduleTaskDlgt = zoneSpec && (zoneSpec.onScheduleTask ? parentDelegate : parentDelegate._scheduleTaskDlgt); this._scheduleTaskCurrZone = zoneSpec && (zoneSpec.onScheduleTask ? this.zone : parentDelegate.zone); this._invokeTaskZS = zoneSpec && (zoneSpec.onInvokeTask ? zoneSpec : parentDelegate._invokeTaskZS); this._invokeTaskDlgt = zoneSpec && (zoneSpec.onInvokeTask ? parentDelegate : parentDelegate._invokeTaskDlgt); this._invokeTaskCurrZone = zoneSpec && (zoneSpec.onInvokeTask ? this.zone : parentDelegate.zone); this._cancelTaskZS = zoneSpec && (zoneSpec.onCancelTask ? zoneSpec : parentDelegate._cancelTaskZS); this._cancelTaskDlgt = zoneSpec && (zoneSpec.onCancelTask ? parentDelegate : parentDelegate._cancelTaskDlgt); this._cancelTaskCurrZone = zoneSpec && (zoneSpec.onCancelTask ? this.zone : parentDelegate.zone); this._hasTaskZS = null; this._hasTaskDlgt = null; this._hasTaskDlgtOwner = null; this._hasTaskCurrZone = null; var zoneSpecHasTask = zoneSpec && zoneSpec.onHasTask; var parentHasTask = parentDelegate && parentDelegate._hasTaskZS; if (zoneSpecHasTask || parentHasTask) { // If we need to report hasTask, than this ZS needs to do ref counting on tasks. In such // a case all task related interceptors must go through this ZD. We can't short circuit it. this._hasTaskZS = zoneSpecHasTask ? zoneSpec : DELEGATE_ZS; this._hasTaskDlgt = parentDelegate; this._hasTaskDlgtOwner = this; this._hasTaskCurrZone = zone; if (!zoneSpec.onScheduleTask) { this._scheduleTaskZS = DELEGATE_ZS; this._scheduleTaskDlgt = parentDelegate; this._scheduleTaskCurrZone = this.zone; } if (!zoneSpec.onInvokeTask) { this._invokeTaskZS = DELEGATE_ZS; this._invokeTaskDlgt = parentDelegate; this._invokeTaskCurrZone = this.zone; } if (!zoneSpec.onCancelTask) { this._cancelTaskZS = DELEGATE_ZS; this._cancelTaskDlgt = parentDelegate; this._cancelTaskCurrZone = this.zone; } } } ZoneDelegate.prototype.fork = function (targetZone, zoneSpec) { return this._forkZS ? this._forkZS.onFork(this._forkDlgt, this.zone, targetZone, zoneSpec) : new Zone(targetZone, zoneSpec); }; ZoneDelegate.prototype.intercept = function (targetZone, callback, source) { return this._interceptZS ? this._interceptZS.onIntercept(this._interceptDlgt, this._interceptCurrZone, targetZone, callback, source) : callback; }; ZoneDelegate.prototype.invoke = function (targetZone, callback, applyThis, applyArgs, source) { return this._invokeZS ? this._invokeZS.onInvoke(this._invokeDlgt, this._invokeCurrZone, targetZone, callback, applyThis, applyArgs, source) : callback.apply(applyThis, applyArgs); }; ZoneDelegate.prototype.handleError = function (targetZone, error) { return this._handleErrorZS ? this._handleErrorZS.onHandleError(this._handleErrorDlgt, this._handleErrorCurrZone, targetZone, error) : true; }; ZoneDelegate.prototype.scheduleTask = function (targetZone, task) { var returnTask = task; if (this._scheduleTaskZS) { if (this._hasTaskZS) { returnTask._zoneDelegates.push(this._hasTaskDlgtOwner); } returnTask = this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt, this._scheduleTaskCurrZone, targetZone, task); if (!returnTask) returnTask = task; } else { if (task.scheduleFn) { task.scheduleFn(task); } else if (task.type == microTask) { scheduleMicroTask(task); } else { throw new Error('Task is missing scheduleFn.'); } } return returnTask; }; ZoneDelegate.prototype.invokeTask = function (targetZone, task, applyThis, applyArgs) { return this._invokeTaskZS ? this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt, this._invokeTaskCurrZone, targetZone, task, applyThis, applyArgs) : task.callback.apply(applyThis, applyArgs); }; ZoneDelegate.prototype.cancelTask = function (targetZone, task) { var value; if (this._cancelTaskZS) { value = this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt, this._cancelTaskCurrZone, targetZone, task); } else { if (!task.cancelFn) { throw Error('Task is not cancelable'); } value = task.cancelFn(task); } return value; }; ZoneDelegate.prototype.hasTask = function (targetZone, isEmpty) { // hasTask should not throw error so other ZoneDelegate // can still trigger hasTask callback try { return this._hasTaskZS && this._hasTaskZS.onHasTask(this._hasTaskDlgt, this._hasTaskCurrZone, targetZone, isEmpty); } catch (err) { this.handleError(targetZone, err); } }; ZoneDelegate.prototype._updateTaskCount = function (type, count) { var counts = this._taskCounts; var prev = counts[type]; var next = counts[type] = prev + count; if (next < 0) { throw new Error('More tasks executed then were scheduled.'); } if (prev == 0 || next == 0) { var isEmpty = { microTask: counts['microTask'] > 0, macroTask: counts['macroTask'] > 0, eventTask: counts['eventTask'] > 0, change: type }; this.hasTask(this.zone, isEmpty); } }; return ZoneDelegate; }()); var ZoneTask = (function () { function ZoneTask(type, source, callback, options, scheduleFn, cancelFn) { this._zone = null; this.runCount = 0; this._zoneDelegates = null; this._state = 'notScheduled'; this.type = type; this.source = source; this.data = options; this.scheduleFn = scheduleFn; this.cancelFn = cancelFn; this.callback = callback; var self = this; if (type === eventTask && options && options.isUsingGlobalCallback) { this.invoke = ZoneTask.invokeTask; } else { this.invoke = function () { return ZoneTask.invokeTask.apply(global, [self, this, arguments]); }; } } ZoneTask.invokeTask = function (task, target, args) { if (!task) { task = this; } _numberOfNestedTaskFrames++; try { task.runCount++; return task.zone.runTask(task, target, args); } finally { if (_numberOfNestedTaskFrames == 1) { drainMicroTaskQueue(); } _numberOfNestedTaskFrames--; } }; Object.defineProperty(ZoneTask.prototype, "zone", { get: function () { return this._zone; }, enumerable: true, configurable: true }); Object.defineProperty(ZoneTask.prototype, "state", { get: function () { return this._state; }, enumerable: true, configurable: true }); ZoneTask.prototype.cancelScheduleRequest = function () { this._transitionTo(notScheduled, scheduling); }; ZoneTask.prototype._transitionTo = function (toState, fromState1, fromState2) { if (this._state === fromState1 || this._state === fromState2) { this._state = toState; if (toState == notScheduled) { this._zoneDelegates = null; } } else { throw new Error(this.type + " '" + this.source + "': can not transition to '" + toState + "', expecting state '" + fromState1 + "'" + (fromState2 ? ' or \'' + fromState2 + '\'' : '') + ", was '" + this._state + "'."); } }; ZoneTask.prototype.toString = function () { if (this.data && typeof this.data.handleId !== 'undefined') { return this.data.handleId; } else { return Object.prototype.toString.call(this); } }; // add toJSON method to prevent cyclic error when // call JSON.stringify(zoneTask) ZoneTask.prototype.toJSON = function () { return { type: this.type, state: this.state, source: this.source, zone: this.zone.name, invoke: this.invoke, scheduleFn: this.scheduleFn, cancelFn: this.cancelFn, runCount: this.runCount, callback: this.callback }; }; return ZoneTask; }()); ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// /// MICROTASK QUEUE ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// var symbolSetTimeout = __symbol__('setTimeout'); var symbolPromise = __symbol__('Promise'); var symbolThen = __symbol__('then'); var _microTaskQueue = []; var _isDrainingMicrotaskQueue = false; var nativeMicroTaskQueuePromise; function scheduleMicroTask(task) { // if we are not running in any task, and there has not been anything scheduled // we must bootstrap the initial task creation by manually scheduling the drain if (_numberOfNestedTaskFrames === 0 && _microTaskQueue.length === 0) { // We are not running in Task, so we need to kickstart the microtask queue. if (!nativeMicroTaskQueuePromise) { if (global[symbolPromise]) { nativeMicroTaskQueuePromise = global[symbolPromise].resolve(0); } } if (nativeMicroTaskQueuePromise) { nativeMicroTaskQueuePromise[symbolThen](drainMicroTaskQueue); } else { global[symbolSetTimeout](drainMicroTaskQueue, 0); } } task && _microTaskQueue.push(task); } function drainMicroTaskQueue() { if (!_isDrainingMicrotaskQueue) { _isDrainingMicrotaskQueue = true; while (_microTaskQueue.length) { var queue = _microTaskQueue; _microTaskQueue = []; for (var i = 0; i < queue.length; i++) { var task = queue[i]; try { task.zone.runTask(task, null, null); } catch (error) { _api.onUnhandledError(error); } } } var showError = !Zone[__symbol__('ignoreConsoleErrorUncaughtError')]; _api.microtaskDrainDone(); _isDrainingMicrotaskQueue = false; } } ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// /// BOOTSTRAP ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// var NO_ZONE = { name: 'NO ZONE' }; var notScheduled = 'notScheduled', scheduling = 'scheduling', scheduled = 'scheduled', running = 'running', canceling = 'canceling', unknown = 'unknown'; var microTask = 'microTask', macroTask = 'macroTask', eventTask = 'eventTask'; var patches = {}; var _api = { symbol: __symbol__, currentZoneFrame: function () { return _currentZoneFrame; }, onUnhandledError: noop, microtaskDrainDone: noop, scheduleMicroTask: scheduleMicroTask, showUncaughtError: function () { return !Zone[__symbol__('ignoreConsoleErrorUncaughtError')]; }, patchEventTarget: function () { return []; }, patchOnProperties: noop, patchMethod: function () { return noop; }, setNativePromise: function (NativePromise) { nativeMicroTaskQueuePromise = NativePromise.resolve(0); }, }; var _currentZoneFrame = { parent: null, zone: new Zone(null, null) }; var _currentTask = null; var _numberOfNestedTaskFrames = 0; function noop() { } function __symbol__(name) { return '__zone_symbol__' + name; } performanceMeasure('Zone', 'Zone'); return global['Zone'] = Zone; })(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global); var __read = (undefined && undefined.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __values = (undefined && undefined.__values) || function (o) { var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; if (m) return m.call(o); return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; }; /** * @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 */ Zone.__load_patch('ZoneAwarePromise', function (global, Zone, api) { var __symbol__ = api.symbol; var _uncaughtPromiseErrors = []; var symbolPromise = __symbol__('Promise'); var symbolThen = __symbol__('then'); api.onUnhandledError = function (e) { if (api.showUncaughtError()) { var rejection = e && e.rejection; if (rejection) { console.error('Unhandled Promise rejection:', rejection instanceof Error ? rejection.message : rejection, '; Zone:', e.zone.name, '; Task:', e.task && e.task.source, '; Value:', rejection, rejection instanceof Error ? rejection.stack : undefined); } else { console.error(e); } } }; api.microtaskDrainDone = function () { while (_uncaughtPromiseErrors.length) { var _loop_1 = function () { var uncaughtPromiseError = _uncaughtPromiseErrors.shift(); try { uncaughtPromiseError.zone.runGuarded(function () { throw uncaughtPromiseError; }); } catch (error) { handleUnhandledRejection(error); } }; while (_uncaughtPromiseErrors.length) { _loop_1(); } } }; var UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL = __symbol__('unhandledPromiseRejectionHandler'); function handleUnhandledRejection(e) { api.onUnhandledError(e); try { var handler = Zone[UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL]; if (handler && typeof handler === 'function') { handler.apply(this, [e]); } } catch (err) { } } function isThenable(value) { return value && value.then; } function forwardResolution(value) { return value; } function forwardRejection(rejection) { return ZoneAwarePromise.reject(rejection); } var symbolState = __symbol__('state'); var symbolValue = __symbol__('value'); var source = 'Promise.then'; var UNRESOLVED = null; var RESOLVED = true; var REJECTED = false; var REJECTED_NO_CATCH = 0; function makeResolver(promise, state) { return function (v) { try { resolvePromise(promise, state, v); } catch (err) { resolvePromise(promise, false, err); } // Do not return value or you will break the Promise spec. }; } var once = function () { var wasCalled = false; return function wrapper(wrappedFunction) { return function () { if (wasCalled) { return; } wasCalled = true; wrappedFunction.apply(null, arguments); }; }; }; var TYPE_ERROR = 'Promise resolved with itself'; var OBJECT = 'object'; var FUNCTION = 'function'; var CURRENT_TASK_SYMBOL = __symbol__('currentTask'); // Promise Resolution function resolvePromise(promise, state, value) { var onceWrapper = once(); if (promise === value) { throw new TypeError(TYPE_ERROR); } if (promise[symbolState] === UNRESOLVED) { // should only get value.then once based on promise spec. var then = null; try { if (typeof value === OBJECT || typeof value === FUNCTION) { then = value && value.then; } } catch (err) { onceWrapper(function () { resolvePromise(promise, false, err); })(); return promise; } // if (value instanceof ZoneAwarePromise) { if (state !== REJECTED && value instanceof ZoneAwarePromise && value.hasOwnProperty(symbolState) && value.hasOwnProperty(symbolValue) && value[symbolState] !== UNRESOLVED) { clearRejectedNoCatch(value); resolvePromise(promise, value[symbolState], value[symbolValue]); } else if (state !== REJECTED && typeof then === FUNCTION) { try { then.apply(value, [ onceWrapper(makeResolver(promise, state)), onceWrapper(makeResolver(promise, false)) ]); } catch (err) { onceWrapper(function () { resolvePromise(promise, false, err); })(); } } else { promise[symbolState] = state; var queue = promise[symbolValue]; promise[symbolValue] = value; // record task information in value when error occurs, so we can // do some additional work such as render longStackTrace if (state === REJECTED && value instanceof Error) { value[CURRENT_TASK_SYMBOL] = Zone.currentTask; } for (var i = 0; i < queue.length;) { scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]); } if (queue.length == 0 && state == REJECTED) { promise[symbolState] = REJECTED_NO_CATCH; try { throw new Error('Uncaught (in promise): ' + value + (value && value.stack ? '\n' + value.stack : '')); } catch (err) { var error_1 = err; error_1.rejection = value; error_1.promise = promise; error_1.zone = Zone.current; error_1.task = Zone.currentTask; _uncaughtPromiseErrors.push(error_1); api.scheduleMicroTask(); // to make sure that it is running } } } } // Resolving an already resolved promise is a noop. return promise; } var REJECTION_HANDLED_HANDLER = __symbol__('rejectionHandledHandler'); function clearRejectedNoCatch(promise) { if (promise[symbolState] === REJECTED_NO_CATCH) { // if the promise is rejected no catch status // and queue.length > 0, means there is a error handler // here to handle the rejected promise, we should trigger // windows.rejectionhandled eventHandler or nodejs rejectionHandled // eventHandler try { var handler = Zone[REJECTION_HANDLED_HANDLER]; if (handler && typeof handler === FUNCTION) { handler.apply(this, [{ rejection: promise[symbolValue], promise: promise }]); } } catch (err) { } promise[symbolState] = REJECTED; for (var i = 0; i < _uncaughtPromiseErrors.length; i++) { if (promise === _uncaughtPromiseErrors[i].promise) { _uncaughtPromiseErrors.splice(i, 1); } } } } function scheduleResolveOrReject(promise, zone, chainPromise, onFulfilled, onRejected) { clearRejectedNoCatch(promise); var delegate = promise[symbolState] ? (typeof onFulfilled === FUNCTION) ? onFulfilled : forwardResolution : (typeof onRejected === FUNCTION) ? onRejected : forwardRejection; zone.scheduleMicroTask(source, function () { try { resolvePromise(chainPromise, true, zone.run(delegate, undefined, [promise[symbolValue]])); } catch (error) { resolvePromise(chainPromise, false, error); } }); } var ZONE_AWARE_PROMISE_TO_STRING = 'function ZoneAwarePromise() { [native code] }'; var ZoneAwarePromise = (function () { function ZoneAwarePromise(executor) { var promise = this; if (!(promise instanceof ZoneAwarePromise)) { throw new Error('Must be an instanceof Promise.'); } promise[symbolState] = UNRESOLVED; promise[symbolValue] = []; // queue; try { executor && executor(makeResolver(promise, RESOLVED), makeResolver(promise, REJECTED)); } catch (error) { resolvePromise(promise, false, error); } } ZoneAwarePromise.toString = function () { return ZONE_AWARE_PROMISE_TO_STRING; }; ZoneAwarePromise.resolve = function (value) { return resolvePromise(new this(null), RESOLVED, value); }; ZoneAwarePromise.reject = function (error) { return resolvePromise(new this(null), REJECTED, error); }; ZoneAwarePromise.race = function (values) { var resolve; var reject; var promise = new this(function (res, rej) { _a = __read([res, rej], 2), resolve = _a[0], reject = _a[1]; var _a; }); function onResolve(value) { promise && (promise = null || resolve(value)); } function onReject(error) { promise && (promise = null || reject(error)); } try { for (var values_1 = __values(values), values_1_1 = values_1.next(); !values_1_1.done; values_1_1 = values_1.next()) { var value = values_1_1.value; if (!isThenable(value)) { value = this.resolve(value); } value.then(onResolve, onReject); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (values_1_1 && !values_1_1.done && (_a = values_1.return)) _a.call(values_1); } finally { if (e_1) throw e_1.error; } } return promise; var e_1, _a; }; ZoneAwarePromise.all = function (values) { var resolve; var reject; var promise = new this(function (res, rej) { resolve = res; reject = rej; }); var count = 0; var resolvedValues = []; try { for (var values_2 = __values(values), values_2_1 = values_2.next(); !values_2_1.done; values_2_1 = values_2.next()) { var value = values_2_1.value; if (!isThenable(value)) { value = this.resolve(value); } value.then((function (index) { return function (value) { resolvedValues[index] = value; count--; if (!count) { resolve(resolvedValues); } }; })(count), reject); count++; } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (values_2_1 && !values_2_1.done && (_a = values_2.return)) _a.call(values_2); } finally { if (e_2) throw e_2.error; } } if (!count) resolve(resolvedValues); return promise; var e_2, _a; }; ZoneAwarePromise.prototype.then = function (onFulfilled, onRejected) { var chainPromise = new this.constructor(null); var zone = Zone.current; if (this[symbolState] == UNRESOLVED) { this[symbolValue].push(zone, chainPromise, onFulfilled, onRejected); } else { scheduleResolveOrReject(this, zone, chainPromise, onFulfilled, onRejected); } return chainPromise; }; ZoneAwarePromise.prototype.catch = function (onRejected) { return this.then(null, onRejected); }; return ZoneAwarePromise; }()); // Protect against aggressive optimizers dropping seemingly unused properties. // E.g. Closure Compiler in advanced mode. ZoneAwarePromise['resolve'] = ZoneAwarePromise.resolve; ZoneAwarePromise['reject'] = ZoneAwarePromise.reject; ZoneAwarePromise['race'] = ZoneAwarePromise.race; ZoneAwarePromise['all'] = ZoneAwarePromise.all; var NativePromise = global[symbolPromise] = global['Promise']; var ZONE_AWARE_PROMISE = Zone.__symbol__('ZoneAwarePromise'); var desc = Object.getOwnPropertyDescriptor(global, 'Promise'); if (!desc || desc.configurable) { desc && delete desc.writable; desc && delete desc.value; if (!desc) { desc = { configurable: true, enumerable: true }; } desc.get = function () { // if we already set ZoneAwarePromise, use patched one // otherwise return native one. return global[ZONE_AWARE_PROMISE] ? global[ZONE_AWARE_PROMISE] : global[symbolPromise]; }; desc.set = function (NewNativePromise) { if (NewNativePromise === ZoneAwarePromise) { // if the NewNativePromise is ZoneAwarePromise // save to global global[ZONE_AWARE_PROMISE] = NewNativePromise; } else { // if the NewNativePromise is not ZoneAwarePromise // for example: after load zone.js, some library just // set es6-promise to global, if we set it to global // directly, assertZonePatched will fail and angular // will not loaded, so we just set the NewNativePromise // to global[symbolPromise], so the result is just like // we load ES6 Promise before zone.js global[symbolPromise] = NewNativePromise; if (!NewNativePromise.prototype[symbolThen]) { patchThen(NewNativePromise); } api.setNativePromise(NewNativePromise); } }; Object.defineProperty(global, 'Promise', desc); } global['Promise'] = ZoneAwarePromise; var symbolThenPatched = __symbol__('thenPatched'); function patchThen(Ctor) { var proto = Ctor.prototype; var originalThen = proto.then; // Keep a reference to the original method. proto[symbolThen] = originalThen; // check Ctor.prototype.then propertyDescritor is writable or not // in meteor env, writable is false, we have to make it to be true. var prop = Object.getOwnPropertyDescriptor(Ctor.prototype, 'then'); if (prop && prop.writable === false && prop.configurable) { Object.defineProperty(Ctor.prototype, 'then', { writable: true }); } Ctor.prototype.then = function (onResolve, onReject) { var _this = this; var wrapped = new ZoneAwarePromise(function (resolve, reject) { originalThen.call(_this, resolve, reject); }); return wrapped.then(onResolve, onReject); }; Ctor[symbolThenPatched] = true; } function zoneify(fn) { return function () { var resultPromise = fn.apply(this, arguments); if (resultPromise instanceof ZoneAwarePromise) { return resultPromise; } var ctor = resultPromise.constructor; if (!ctor[symbolThenPatched]) { patchThen(ctor); } return resultPromise; }; } if (NativePromise) { patchThen(NativePromise); var fetch_1 = global['fetch']; if (typeof fetch_1 == FUNCTION) { global['fetch'] = zoneify(fetch_1); } } // This is not part of public API, but it is useful for tests, so we expose it. Promise[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors; return ZoneAwarePromise; }); /** * @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 */ /** * Suppress closure compiler errors about unknown 'Zone' variable * @fileoverview * @suppress {undefinedVars,globalThis,missingRequire} */ var zoneSymbol = Zone.__symbol__; var _global = typeof window === 'object' && window || typeof self === 'object' && self || global; var FUNCTION = 'function'; var UNDEFINED = 'undefined'; function isPropertyWritable(propertyDesc) { if (!propertyDesc) { return true; } if (propertyDesc.writable === false) { return false; } if (typeof propertyDesc.get === FUNCTION && typeof propertyDesc.set === UNDEFINED) { return false; } return true; } var isWebWorker = (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope); // Make sure to access `process` through `_global` so that WebPack does not accidently browserify // this code. var isNode = (!('nw' in _global) && typeof _global.process !== 'undefined' && {}.toString.call(_global.process) === '[object process]'); // we are in electron of nw, so we are both browser and nodejs // Make sure to access `process` through `_global` so that WebPack does not accidently browserify // this code. var isMix = typeof _global.process !== 'undefined' && {}.toString.call(_global.process) === '[object process]' && !isWebWorker && !!(typeof window !== 'undefined' && window['HTMLElement']); var originalInstanceKey = zoneSymbol('originalInstance'); // wrap some native API on `window` function patchMethod(target, name, patchFn) { var proto = target; while (proto && !proto.hasOwnProperty(name)) { proto = Object.getPrototypeOf(proto); } if (!proto && target[name]) { // somehow we did not find it, but we can see it. This happens on IE for Window properties. proto = target; } var delegateName = zoneSymbol(name); var delegate; if (proto && !(delegate = proto[delegateName])) { delegate = proto[delegateName] = proto[name]; // check whether proto[name] is writable // some property is readonly in safari, such as HtmlCanvasElement.prototype.toBlob var desc = proto && Object.getOwnPropertyDescriptor(proto, name); if (isPropertyWritable(desc)) { var patchDelegate_1 = patchFn(delegate, delegateName, name); proto[name] = function () { return patchDelegate_1(this, arguments); }; attachOriginToPatched(proto[name], delegate); } } return delegate; } // TODO: @JiaLiPassion, support cancel task later if necessary function patchMacroTask(obj, funcName, metaCreator) { var setNative = null; function scheduleTask(task) { var data = task.data; data.args[data.callbackIndex] = function () { task.invoke.apply(this, arguments); }; setNative.apply(data.target, data.args); return task; } setNative = patchMethod(obj, funcName, function (delegate) { return function (self, args) { var meta = metaCreator(self, args); if (meta.callbackIndex >= 0 && typeof args[meta.callbackIndex] === 'function') { var task = Zone.current.scheduleMacroTask(meta.name, args[meta.callbackIndex], meta, scheduleTask, null); return task; } else { // cause an error by calling it directly. return delegate.apply(self, args); } }; }); } function patchMicroTask(obj, funcName, metaCreator) { var setNative = null; function scheduleTask(task) { var data = task.data; data.args[data.callbackIndex] = function () { task.invoke.apply(this, arguments);