UNPKG

nativescript-angular

Version:

An Angular renderer that lets you build mobile apps with NativeScript.

1,150 lines (1,142 loc) • 58.3 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 */ /** * @fileoverview * @suppress {globalThis} */ var NEWLINE = '\n'; var IGNORE_FRAMES = {}; var creationTrace = '__creationTrace__'; var ERROR_TAG = 'STACKTRACE TRACKING'; var SEP_TAG = '__SEP_TAG__'; var sepTemplate = SEP_TAG + '@[native]'; var LongStackTrace = /** @class */ (function () { function LongStackTrace() { this.error = getStacktrace(); this.timestamp = new Date(); } return LongStackTrace; }()); function getStacktraceWithUncaughtError() { return new Error(ERROR_TAG); } function getStacktraceWithCaughtError() { try { throw getStacktraceWithUncaughtError(); } catch (err) { return err; } } // Some implementations of exception handling don't create a stack trace if the exception // isn't thrown, however it's faster not to actually throw the exception. var error = getStacktraceWithUncaughtError(); var caughtError = getStacktraceWithCaughtError(); var getStacktrace = error.stack ? getStacktraceWithUncaughtError : (caughtError.stack ? getStacktraceWithCaughtError : getStacktraceWithUncaughtError); function getFrames(error) { return error.stack ? error.stack.split(NEWLINE) : []; } function addErrorStack(lines, error) { var trace = getFrames(error); for (var i = 0; i < trace.length; i++) { var frame = trace[i]; // Filter out the Frames which are part of stack capturing. if (!IGNORE_FRAMES.hasOwnProperty(frame)) { lines.push(trace[i]); } } } function renderLongStackTrace(frames, stack) { var longTrace = [stack ? stack.trim() : '']; if (frames) { var timestamp = new Date().getTime(); for (var i = 0; i < frames.length; i++) { var traceFrames = frames[i]; var lastTime = traceFrames.timestamp; var separator = "____________________Elapsed " + (timestamp - lastTime.getTime()) + " ms; At: " + lastTime; separator = separator.replace(/[^\w\d]/g, '_'); longTrace.push(sepTemplate.replace(SEP_TAG, separator)); addErrorStack(longTrace, traceFrames.error); timestamp = lastTime.getTime(); } } return longTrace.join(NEWLINE); } Zone['longStackTraceZoneSpec'] = { name: 'long-stack-trace', longStackTraceLimit: 10, // add a getLongStackTrace method in spec to // handle handled reject promise error. getLongStackTrace: function (error) { if (!error) { return undefined; } var trace = error[Zone.__symbol__('currentTaskTrace')]; if (!trace) { return error.stack; } return renderLongStackTrace(trace, error.stack); }, onScheduleTask: function (parentZoneDelegate, currentZone, targetZone, task) { if (Error.stackTraceLimit > 0) { // if Error.stackTraceLimit is 0, means stack trace // is disabled, so we don't need to generate long stack trace // this will improve performance in some test(some test will // set stackTraceLimit to 0, https://github.com/angular/zone.js/issues/698 var currentTask = Zone.currentTask; var trace = currentTask && currentTask.data && currentTask.data[creationTrace] || []; trace = [new LongStackTrace()].concat(trace); if (trace.length > this.longStackTraceLimit) { trace.length = this.longStackTraceLimit; } if (!task.data) task.data = {}; task.data[creationTrace] = trace; } return parentZoneDelegate.scheduleTask(targetZone, task); }, onHandleError: function (parentZoneDelegate, currentZone, targetZone, error) { if (Error.stackTraceLimit > 0) { // if Error.stackTraceLimit is 0, means stack trace // is disabled, so we don't need to generate long stack trace // this will improve performance in some test(some test will // set stackTraceLimit to 0, https://github.com/angular/zone.js/issues/698 var parentTask = Zone.currentTask || error.task; if (error instanceof Error && parentTask) { var longStack = renderLongStackTrace(parentTask.data && parentTask.data[creationTrace], error.stack); try { error.stack = error.longStack = longStack; } catch (err) { } } } return parentZoneDelegate.handleError(targetZone, error); } }; function captureStackTraces(stackTraces, count) { if (count > 0) { stackTraces.push(getFrames((new LongStackTrace()).error)); captureStackTraces(stackTraces, count - 1); } } function computeIgnoreFrames() { if (Error.stackTraceLimit <= 0) { return; } var frames = []; captureStackTraces(frames, 2); var frames1 = frames[0]; var frames2 = frames[1]; for (var i = 0; i < frames1.length; i++) { var frame1 = frames1[i]; if (frame1.indexOf(ERROR_TAG) == -1) { var match = frame1.match(/^\s*at\s+/); if (match) { sepTemplate = match[0] + SEP_TAG + ' (http://localhost)'; break; } } } for (var i = 0; i < frames1.length; i++) { var frame1 = frames1[i]; var frame2 = frames2[i]; if (frame1 === frame2) { IGNORE_FRAMES[frame1] = true; } else { break; } } } computeIgnoreFrames(); /** * @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 ProxyZoneSpec = /** @class */ (function () { function ProxyZoneSpec(defaultSpecDelegate) { if (defaultSpecDelegate === void 0) { defaultSpecDelegate = null; } this.defaultSpecDelegate = defaultSpecDelegate; this.name = 'ProxyZone'; this.properties = { 'ProxyZoneSpec': this }; this.propertyKeys = null; this.lastTaskState = null; this.isNeedToTriggerHasTask = false; this.tasks = []; this.setDelegate(defaultSpecDelegate); } ProxyZoneSpec.get = function () { return Zone.current.get('ProxyZoneSpec'); }; ProxyZoneSpec.isLoaded = function () { return ProxyZoneSpec.get() instanceof ProxyZoneSpec; }; ProxyZoneSpec.assertPresent = function () { if (!ProxyZoneSpec.isLoaded()) { throw new Error("Expected to be running in 'ProxyZone', but it was not found."); } return ProxyZoneSpec.get(); }; ProxyZoneSpec.prototype.setDelegate = function (delegateSpec) { var _this = this; var isNewDelegate = this._delegateSpec !== delegateSpec; this._delegateSpec = delegateSpec; this.propertyKeys && this.propertyKeys.forEach(function (key) { return delete _this.properties[key]; }); this.propertyKeys = null; if (delegateSpec && delegateSpec.properties) { this.propertyKeys = Object.keys(delegateSpec.properties); this.propertyKeys.forEach(function (k) { return _this.properties[k] = delegateSpec.properties[k]; }); } // if set a new delegateSpec, shoulde check whether need to // trigger hasTask or not if (isNewDelegate && this.lastTaskState && (this.lastTaskState.macroTask || this.lastTaskState.microTask)) { this.isNeedToTriggerHasTask = true; } }; ProxyZoneSpec.prototype.getDelegate = function () { return this._delegateSpec; }; ProxyZoneSpec.prototype.resetDelegate = function () { var delegateSpec = this.getDelegate(); this.setDelegate(this.defaultSpecDelegate); }; ProxyZoneSpec.prototype.tryTriggerHasTask = function (parentZoneDelegate, currentZone, targetZone) { if (this.isNeedToTriggerHasTask && this.lastTaskState) { // last delegateSpec has microTask or macroTask // should call onHasTask in current delegateSpec this.isNeedToTriggerHasTask = false; this.onHasTask(parentZoneDelegate, currentZone, targetZone, this.lastTaskState); } }; ProxyZoneSpec.prototype.removeFromTasks = function (task) { if (!this.tasks) { return; } for (var i = 0; i < this.tasks.length; i++) { if (this.tasks[i] === task) { this.tasks.splice(i, 1); return; } } }; ProxyZoneSpec.prototype.getAndClearPendingTasksInfo = function () { if (this.tasks.length === 0) { return ''; } var taskInfo = this.tasks.map(function (task) { var dataInfo = task.data && Object.keys(task.data) .map(function (key) { return key + ':' + task.data[key]; }) .join(','); return "type: " + task.type + ", source: " + task.source + ", args: {" + dataInfo + "}"; }); var pendingTasksInfo = '--Pendng async tasks are: [' + taskInfo + ']'; // clear tasks this.tasks = []; return pendingTasksInfo; }; ProxyZoneSpec.prototype.onFork = function (parentZoneDelegate, currentZone, targetZone, zoneSpec) { if (this._delegateSpec && this._delegateSpec.onFork) { return this._delegateSpec.onFork(parentZoneDelegate, currentZone, targetZone, zoneSpec); } else { return parentZoneDelegate.fork(targetZone, zoneSpec); } }; ProxyZoneSpec.prototype.onIntercept = function (parentZoneDelegate, currentZone, targetZone, delegate, source) { if (this._delegateSpec && this._delegateSpec.onIntercept) { return this._delegateSpec.onIntercept(parentZoneDelegate, currentZone, targetZone, delegate, source); } else { return parentZoneDelegate.intercept(targetZone, delegate, source); } }; ProxyZoneSpec.prototype.onInvoke = function (parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) { this.tryTriggerHasTask(parentZoneDelegate, currentZone, targetZone); if (this._delegateSpec && this._delegateSpec.onInvoke) { return this._delegateSpec.onInvoke(parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source); } else { return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source); } }; ProxyZoneSpec.prototype.onHandleError = function (parentZoneDelegate, currentZone, targetZone, error) { if (this._delegateSpec && this._delegateSpec.onHandleError) { return this._delegateSpec.onHandleError(parentZoneDelegate, currentZone, targetZone, error); } else { return parentZoneDelegate.handleError(targetZone, error); } }; ProxyZoneSpec.prototype.onScheduleTask = function (parentZoneDelegate, currentZone, targetZone, task) { if (task.type !== 'eventTask') { this.tasks.push(task); } if (this._delegateSpec && this._delegateSpec.onScheduleTask) { return this._delegateSpec.onScheduleTask(parentZoneDelegate, currentZone, targetZone, task); } else { return parentZoneDelegate.scheduleTask(targetZone, task); } }; ProxyZoneSpec.prototype.onInvokeTask = function (parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs) { if (task.type !== 'eventTask') { this.removeFromTasks(task); } this.tryTriggerHasTask(parentZoneDelegate, currentZone, targetZone); if (this._delegateSpec && this._delegateSpec.onInvokeTask) { return this._delegateSpec.onInvokeTask(parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs); } else { return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs); } }; ProxyZoneSpec.prototype.onCancelTask = function (parentZoneDelegate, currentZone, targetZone, task) { if (task.type !== 'eventTask') { this.removeFromTasks(task); } this.tryTriggerHasTask(parentZoneDelegate, currentZone, targetZone); if (this._delegateSpec && this._delegateSpec.onCancelTask) { return this._delegateSpec.onCancelTask(parentZoneDelegate, currentZone, targetZone, task); } else { return parentZoneDelegate.cancelTask(targetZone, task); } }; ProxyZoneSpec.prototype.onHasTask = function (delegate, current, target, hasTaskState) { this.lastTaskState = hasTaskState; if (this._delegateSpec && this._delegateSpec.onHasTask) { this._delegateSpec.onHasTask(delegate, current, target, hasTaskState); } else { delegate.hasTask(target, hasTaskState); } }; return ProxyZoneSpec; }()); // Export the class so that new instances can be created with proper // constructor params. Zone['ProxyZoneSpec'] = ProxyZoneSpec; /** * @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 SyncTestZoneSpec = /** @class */ (function () { function SyncTestZoneSpec(namePrefix) { this.runZone = Zone.current; this.name = 'syncTestZone for ' + namePrefix; } SyncTestZoneSpec.prototype.onScheduleTask = function (delegate, current, target, task) { switch (task.type) { case 'microTask': case 'macroTask': throw new Error("Cannot call " + task.source + " from within a sync test."); case 'eventTask': task = delegate.scheduleTask(target, task); break; } return task; }; return SyncTestZoneSpec; }()); // Export the class so that new instances can be created with proper // constructor params. Zone['SyncTestZoneSpec'] = SyncTestZoneSpec; /** * @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 _global = typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global; var AsyncTestZoneSpec = /** @class */ (function () { function AsyncTestZoneSpec(finishCallback, failCallback, namePrefix) { this.finishCallback = finishCallback; this.failCallback = failCallback; this._pendingMicroTasks = false; this._pendingMacroTasks = false; this._alreadyErrored = false; this._isSync = false; this.runZone = Zone.current; this.unresolvedChainedPromiseCount = 0; this.supportWaitUnresolvedChainedPromise = false; this.name = 'asyncTestZone for ' + namePrefix; this.properties = { 'AsyncTestZoneSpec': this }; this.supportWaitUnresolvedChainedPromise = _global[Zone.__symbol__('supportWaitUnResolvedChainedPromise')] === true; } AsyncTestZoneSpec.prototype.isUnresolvedChainedPromisePending = function () { return this.unresolvedChainedPromiseCount > 0; }; AsyncTestZoneSpec.prototype._finishCallbackIfDone = function () { var _this = this; if (!(this._pendingMicroTasks || this._pendingMacroTasks || (this.supportWaitUnresolvedChainedPromise && this.isUnresolvedChainedPromisePending()))) { // We do this because we would like to catch unhandled rejected promises. this.runZone.run(function () { setTimeout(function () { if (!_this._alreadyErrored && !(_this._pendingMicroTasks || _this._pendingMacroTasks)) { _this.finishCallback(); } }, 0); }); } }; AsyncTestZoneSpec.prototype.patchPromiseForTest = function () { if (!this.supportWaitUnresolvedChainedPromise) { return; } var patchPromiseForTest = Promise[Zone.__symbol__('patchPromiseForTest')]; if (patchPromiseForTest) { patchPromiseForTest(); } }; AsyncTestZoneSpec.prototype.unPatchPromiseForTest = function () { if (!this.supportWaitUnresolvedChainedPromise) { return; } var unPatchPromiseForTest = Promise[Zone.__symbol__('unPatchPromiseForTest')]; if (unPatchPromiseForTest) { unPatchPromiseForTest(); } }; AsyncTestZoneSpec.prototype.onScheduleTask = function (delegate, current, target, task) { if (task.type !== 'eventTask') { this._isSync = false; } if (task.type === 'microTask' && task.data && task.data instanceof Promise) { // check whether the promise is a chained promise if (task.data[AsyncTestZoneSpec.symbolParentUnresolved] === true) { // chained promise is being scheduled this.unresolvedChainedPromiseCount--; } } return delegate.scheduleTask(target, task); }; AsyncTestZoneSpec.prototype.onInvokeTask = function (delegate, current, target, task, applyThis, applyArgs) { if (task.type !== 'eventTask') { this._isSync = false; } return delegate.invokeTask(target, task, applyThis, applyArgs); }; AsyncTestZoneSpec.prototype.onCancelTask = function (delegate, current, target, task) { if (task.type !== 'eventTask') { this._isSync = false; } return delegate.cancelTask(target, task); }; // Note - we need to use onInvoke at the moment to call finish when a test is // fully synchronous. TODO(juliemr): remove this when the logic for // onHasTask changes and it calls whenever the task queues are dirty. // updated by(JiaLiPassion), only call finish callback when no task // was scheduled/invoked/canceled. AsyncTestZoneSpec.prototype.onInvoke = function (parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) { try { this._isSync = true; return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source); } finally { var afterTaskCounts = parentZoneDelegate._taskCounts; if (this._isSync) { this._finishCallbackIfDone(); } } }; AsyncTestZoneSpec.prototype.onHandleError = function (parentZoneDelegate, currentZone, targetZone, error) { // Let the parent try to handle the error. var result = parentZoneDelegate.handleError(targetZone, error); if (result) { this.failCallback(error); this._alreadyErrored = true; } return false; }; AsyncTestZoneSpec.prototype.onHasTask = function (delegate, current, target, hasTaskState) { delegate.hasTask(target, hasTaskState); if (hasTaskState.change == 'microTask') { this._pendingMicroTasks = hasTaskState.microTask; this._finishCallbackIfDone(); } else if (hasTaskState.change == 'macroTask') { this._pendingMacroTasks = hasTaskState.macroTask; this._finishCallbackIfDone(); } }; AsyncTestZoneSpec.symbolParentUnresolved = Zone.__symbol__('parentUnresolved'); return AsyncTestZoneSpec; }()); // Export the class so that new instances can be created with proper // constructor params. Zone['AsyncTestZoneSpec'] = AsyncTestZoneSpec; /** * @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 __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 __spread = (undefined && undefined.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; (function (global) { var OriginalDate = global.Date; var FakeDate = /** @class */ (function () { function FakeDate() { if (arguments.length === 0) { var d = new OriginalDate(); d.setTime(FakeDate.now()); return d; } else { var args = Array.prototype.slice.call(arguments); return new (OriginalDate.bind.apply(OriginalDate, __spread([void 0], args)))(); } } FakeDate.now = function () { var fakeAsyncTestZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec'); if (fakeAsyncTestZoneSpec) { return fakeAsyncTestZoneSpec.getCurrentRealTime() + fakeAsyncTestZoneSpec.getCurrentTime(); } return OriginalDate.now.apply(this, arguments); }; return FakeDate; }()); FakeDate.UTC = OriginalDate.UTC; FakeDate.parse = OriginalDate.parse; // keep a reference for zone patched timer function var timers = { setTimeout: global.setTimeout, setInterval: global.setInterval, clearTimeout: global.clearTimeout, clearInterval: global.clearInterval }; var Scheduler = /** @class */ (function () { function Scheduler() { // Next scheduler id. this.nextId = 1; // Scheduler queue with the tuple of end time and callback function - sorted by end time. this._schedulerQueue = []; // Current simulated time in millis. this._currentTime = 0; // Current real time in millis. this._currentRealTime = OriginalDate.now(); } Scheduler.prototype.getCurrentTime = function () { return this._currentTime; }; Scheduler.prototype.getCurrentRealTime = function () { return this._currentRealTime; }; Scheduler.prototype.setCurrentRealTime = function (realTime) { this._currentRealTime = realTime; }; Scheduler.prototype.scheduleFunction = function (cb, delay, args, isPeriodic, isRequestAnimationFrame, id) { if (args === void 0) { args = []; } if (isPeriodic === void 0) { isPeriodic = false; } if (isRequestAnimationFrame === void 0) { isRequestAnimationFrame = false; } if (id === void 0) { id = -1; } var currentId = id < 0 ? this.nextId++ : id; var endTime = this._currentTime + delay; // Insert so that scheduler queue remains sorted by end time. var newEntry = { endTime: endTime, id: currentId, func: cb, args: args, delay: delay, isPeriodic: isPeriodic, isRequestAnimationFrame: isRequestAnimationFrame }; var i = 0; for (; i < this._schedulerQueue.length; i++) { var currentEntry = this._schedulerQueue[i]; if (newEntry.endTime < currentEntry.endTime) { break; } } this._schedulerQueue.splice(i, 0, newEntry); return currentId; }; Scheduler.prototype.removeScheduledFunctionWithId = function (id) { for (var i = 0; i < this._schedulerQueue.length; i++) { if (this._schedulerQueue[i].id == id) { this._schedulerQueue.splice(i, 1); break; } } }; Scheduler.prototype.tick = function (millis, doTick) { if (millis === void 0) { millis = 0; } var finalTime = this._currentTime + millis; var lastCurrentTime = 0; if (this._schedulerQueue.length === 0 && doTick) { doTick(millis); return; } while (this._schedulerQueue.length > 0) { var current = this._schedulerQueue[0]; if (finalTime < 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. var current_1 = this._schedulerQueue.shift(); lastCurrentTime = this._currentTime; this._currentTime = current_1.endTime; if (doTick) { doTick(this._currentTime - lastCurrentTime); } var retval = current_1.func.apply(global, current_1.args); if (!retval) { // Uncaught exception in the current scheduled function. Stop processing the queue. break; } } } this._currentTime = finalTime; }; Scheduler.prototype.flush = function (limit, flushPeriodic, doTick) { if (limit === void 0) { limit = 20; } if (flushPeriodic === void 0) { flushPeriodic = false; } if (flushPeriodic) { return this.flushPeriodic(doTick); } else { return this.flushNonPeriodic(limit, doTick); } }; Scheduler.prototype.flushPeriodic = function (doTick) { if (this._schedulerQueue.length === 0) { return 0; } // Find the last task currently queued in the scheduler queue and tick // till that time. var startTime = this._currentTime; var lastTask = this._schedulerQueue[this._schedulerQueue.length - 1]; this.tick(lastTask.endTime - startTime, doTick); return this._currentTime - startTime; }; Scheduler.prototype.flushNonPeriodic = function (limit, doTick) { var startTime = this._currentTime; var lastCurrentTime = 0; var count = 0; while (this._schedulerQueue.length > 0) { count++; if (count > limit) { throw new Error('flush failed after reaching the limit of ' + limit + ' tasks. Does your code use a polling timeout?'); } // flush only non-periodic timers. // If the only remaining tasks are periodic(or requestAnimationFrame), finish flushing. if (this._schedulerQueue.filter(function (task) { return !task.isPeriodic && !task.isRequestAnimationFrame; }) .length === 0) { break; } var current = this._schedulerQueue.shift(); lastCurrentTime = this._currentTime; this._currentTime = current.endTime; if (doTick) { // Update any secondary schedulers like Jasmine mock Date. doTick(this._currentTime - lastCurrentTime); } var retval = current.func.apply(global, current.args); if (!retval) { // Uncaught exception in the current scheduled function. Stop processing the queue. break; } } return this._currentTime - startTime; }; return Scheduler; }()); var FakeAsyncTestZoneSpec = /** @class */ (function () { function FakeAsyncTestZoneSpec(namePrefix, trackPendingRequestAnimationFrame, macroTaskOptions) { if (trackPendingRequestAnimationFrame === void 0) { trackPendingRequestAnimationFrame = false; } this.trackPendingRequestAnimationFrame = trackPendingRequestAnimationFrame; this.macroTaskOptions = macroTaskOptions; this._scheduler = new Scheduler(); this._microtasks = []; this._lastError = null; this._uncaughtPromiseErrors = Promise[Zone.__symbol__('uncaughtPromiseErrors')]; this.pendingPeriodicTimers = []; this.pendingTimers = []; this.patchDateLocked = false; this.properties = { 'FakeAsyncTestZoneSpec': this }; this.name = 'fakeAsyncTestZone for ' + namePrefix; // in case user can't access the construction of FakeAsyncTestSpec // user can also define macroTaskOptions by define a global variable. if (!this.macroTaskOptions) { this.macroTaskOptions = global[Zone.__symbol__('FakeAsyncTestMacroTask')]; } } FakeAsyncTestZoneSpec.assertInZone = function () { if (Zone.current.get('FakeAsyncTestZoneSpec') == null) { throw new Error('The code should be running in the fakeAsync zone to call this function'); } }; FakeAsyncTestZoneSpec.prototype._fnAndFlush = function (fn, completers) { var _this = this; return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } fn.apply(global, args); if (_this._lastError === null) { if (completers.onSuccess != null) { completers.onSuccess.apply(global); } // Flush microtasks only on success. _this.flushMicrotasks(); } else { if (completers.onError != null) { completers.onError.apply(global); } } // Return true if there were no errors, false otherwise. return _this._lastError === null; }; }; FakeAsyncTestZoneSpec._removeTimer = function (timers, id) { var index = timers.indexOf(id); if (index > -1) { timers.splice(index, 1); } }; FakeAsyncTestZoneSpec.prototype._dequeueTimer = function (id) { var _this = this; return function () { FakeAsyncTestZoneSpec._removeTimer(_this.pendingTimers, id); }; }; FakeAsyncTestZoneSpec.prototype._requeuePeriodicTimer = function (fn, interval, args, id) { var _this = this; return function () { // Requeue the timer callback if it's not been canceled. if (_this.pendingPeriodicTimers.indexOf(id) !== -1) { _this._scheduler.scheduleFunction(fn, interval, args, true, false, id); } }; }; FakeAsyncTestZoneSpec.prototype._dequeuePeriodicTimer = function (id) { var _this = this; return function () { FakeAsyncTestZoneSpec._removeTimer(_this.pendingPeriodicTimers, id); }; }; FakeAsyncTestZoneSpec.prototype._setTimeout = function (fn, delay, args, isTimer) { if (isTimer === void 0) { isTimer = true; } var removeTimerFn = this._dequeueTimer(this._scheduler.nextId); // Queue the callback and dequeue the timer on success and error. var cb = this._fnAndFlush(fn, { onSuccess: removeTimerFn, onError: removeTimerFn }); var id = this._scheduler.scheduleFunction(cb, delay, args, false, !isTimer); if (isTimer) { this.pendingTimers.push(id); } return id; }; FakeAsyncTestZoneSpec.prototype._clearTimeout = function (id) { FakeAsyncTestZoneSpec._removeTimer(this.pendingTimers, id); this._scheduler.removeScheduledFunctionWithId(id); }; FakeAsyncTestZoneSpec.prototype._setInterval = function (fn, interval, args) { var id = this._scheduler.nextId; var completers = { onSuccess: null, onError: this._dequeuePeriodicTimer(id) }; var 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, true); this.pendingPeriodicTimers.push(id); return id; }; FakeAsyncTestZoneSpec.prototype._clearInterval = function (id) { FakeAsyncTestZoneSpec._removeTimer(this.pendingPeriodicTimers, id); this._scheduler.removeScheduledFunctionWithId(id); }; FakeAsyncTestZoneSpec.prototype._resetLastErrorAndThrow = function () { var error = this._lastError || this._uncaughtPromiseErrors[0]; this._uncaughtPromiseErrors.length = 0; this._lastError = null; throw error; }; FakeAsyncTestZoneSpec.prototype.getCurrentTime = function () { return this._scheduler.getCurrentTime(); }; FakeAsyncTestZoneSpec.prototype.getCurrentRealTime = function () { return this._scheduler.getCurrentRealTime(); }; FakeAsyncTestZoneSpec.prototype.setCurrentRealTime = function (realTime) { this._scheduler.setCurrentRealTime(realTime); }; FakeAsyncTestZoneSpec.patchDate = function () { if (global['Date'] === FakeDate) { // already patched return; } global['Date'] = FakeDate; FakeDate.prototype = OriginalDate.prototype; // try check and reset timers // because jasmine.clock().install() may // have replaced the global timer FakeAsyncTestZoneSpec.checkTimerPatch(); }; FakeAsyncTestZoneSpec.resetDate = function () { if (global['Date'] === FakeDate) { global['Date'] = OriginalDate; } }; FakeAsyncTestZoneSpec.checkTimerPatch = function () { if (global.setTimeout !== timers.setTimeout) { global.setTimeout = timers.setTimeout; global.clearTimeout = timers.clearTimeout; } if (global.setInterval !== timers.setInterval) { global.setInterval = timers.setInterval; global.clearInterval = timers.clearInterval; } }; FakeAsyncTestZoneSpec.prototype.lockDatePatch = function () { this.patchDateLocked = true; FakeAsyncTestZoneSpec.patchDate(); }; FakeAsyncTestZoneSpec.prototype.unlockDatePatch = function () { this.patchDateLocked = false; FakeAsyncTestZoneSpec.resetDate(); }; FakeAsyncTestZoneSpec.prototype.tick = function (millis, doTick) { if (millis === void 0) { millis = 0; } FakeAsyncTestZoneSpec.assertInZone(); this.flushMicrotasks(); this._scheduler.tick(millis, doTick); if (this._lastError !== null) { this._resetLastErrorAndThrow(); } }; FakeAsyncTestZoneSpec.prototype.flushMicrotasks = function () { var _this = this; FakeAsyncTestZoneSpec.assertInZone(); var flushErrors = function () { 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) { var microtask = this._microtasks.shift(); microtask.func.apply(microtask.target, microtask.args); } flushErrors(); }; FakeAsyncTestZoneSpec.prototype.flush = function (limit, flushPeriodic, doTick) { FakeAsyncTestZoneSpec.assertInZone(); this.flushMicrotasks(); var elapsed = this._scheduler.flush(limit, flushPeriodic, doTick); if (this._lastError !== null) { this._resetLastErrorAndThrow(); } return elapsed; }; FakeAsyncTestZoneSpec.prototype.onScheduleTask = function (delegate, current, target, task) { switch (task.type) { case 'microTask': var args = task.data && task.data.args; // should pass additional arguments to callback if have any // currently we know process.nextTick will have such additional // arguments var additionalArgs = void 0; if (args) { var callbackIndex = task.data.cbIdx; if (typeof args.length === 'number' && args.length > callbackIndex + 1) { additionalArgs = Array.prototype.slice.call(args, callbackIndex + 1); } } this._microtasks.push({ func: task.invoke, args: additionalArgs, target: task.data && task.data.target }); break; case 'macroTask': switch (task.source) { case 'setTimeout': task.data['handleId'] = this._setTimeout(task.invoke, task.data['delay'], Array.prototype.slice.call(task.data['args'], 2)); break; case 'setImmediate': task.data['handleId'] = this._setTimeout(task.invoke, 0, Array.prototype.slice.call(task.data['args'], 1)); break; case 'setInterval': task.data['handleId'] = this._setInterval(task.invoke, task.data['delay'], Array.prototype.slice.call(task.data['args'], 2)); break; case 'XMLHttpRequest.send': throw new Error('Cannot make XHRs from within a fake async test. Request URL: ' + task.data['url']); case 'requestAnimationFrame': case 'webkitRequestAnimationFrame': case 'mozRequestAnimationFrame': // Simulate a requestAnimationFrame by using a setTimeout with 16 ms. // (60 frames per second) task.data['handleId'] = this._setTimeout(task.invoke, 16, task.data['args'], this.trackPendingRequestAnimationFrame); break; default: // user can define which macroTask they want to support by passing // macroTaskOptions var macroTaskOption = this.findMacroTaskOption(task); if (macroTaskOption) { var args_1 = task.data && task.data['args']; var delay = args_1 && args_1.length > 1 ? args_1[1] : 0; var callbackArgs = macroTaskOption.callbackArgs ? macroTaskOption.callbackArgs : args_1; if (!!macroTaskOption.isPeriodic) { // periodic macroTask, use setInterval to simulate task.data['handleId'] = this._setInterval(task.invoke, delay, callbackArgs); task.data.isPeriodic = true; } else { // not periodic, use setTimeout to simulate task.data['handleId'] = this._setTimeout(task.invoke, delay, callbackArgs); } break; } throw new Error('Unknown macroTask scheduled in fake async test: ' + task.source); } break; case 'eventTask': task = delegate.scheduleTask(target, task); break; } return task; }; FakeAsyncTestZoneSpec.prototype.onCancelTask = function (delegate, current, target, task) { switch (task.source) { case 'setTimeout': case 'requestAnimationFrame': case 'webkitRequestAnimationFrame': case 'mozRequestAnimationFrame': return this._clearTimeout(task.data['handleId']); case 'setInterval': return this._clearInterval(task.data['handleId']); default: // user can define which macroTask they want to support by passing // macroTaskOptions var macroTaskOption = this.findMacroTaskOption(task); if (macroTaskOption) { var handleId = task.data['handleId']; return macroTaskOption.isPeriodic ? this._clearInterval(handleId) : this._clearTimeout(handleId); } return delegate.cancelTask(target, task); } }; FakeAsyncTestZoneSpec.prototype.onInvoke = function (delegate, current, target, callback, applyThis, applyArgs, source) { try { FakeAsyncTestZoneSpec.patchDate(); return delegate.invoke(target, callback, applyThis, applyArgs, source); } finally { if (!this.patchDateLocked) { FakeAsyncTestZoneSpec.resetDate(); } } }; FakeAsyncTestZoneSpec.prototype.findMacroTaskOption = function (task) { if (!this.macroTaskOptions) { return null; } for (var i = 0; i < this.macroTaskOptions.length; i++) { var macroTaskOption = this.macroTaskOptions[i]; if (macroTaskOption.source === task.source) { return macroTaskOption; } } return null; }; FakeAsyncTestZoneSpec.prototype.onHandleError = function (parentZoneDelegate, currentZone, targetZone, error) { this._lastError = error; return false; // Don't propagate error to parent zone. }; return 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); /** * @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 */ /** * A `TaskTrackingZoneSpec` allows one to track all outstanding Tasks. * * This is useful in tests. For example to see which tasks are preventing a test from completing * or an automated way of releasing all of the event listeners at the end of the test. */ var TaskTrackingZoneSpec = /** @class */ (function () { function TaskTrackingZoneSpec() { this.name = 'TaskTrackingZone'; this.microTasks = []; this.macroTasks = []; this.eventTasks = []; this.properties = { 'TaskTrackingZone': this }; } TaskTrackingZoneSpec.get = function () { return Zone.current.get('TaskTrackingZone'); }; TaskTrackingZoneSpec.prototype.getTasksFor = function (type) { switch (type) { case 'microTask': return this.microTasks; case 'macroTask': return this.macroTasks; case 'eventTask': return this.eventTasks; } throw new Error('Unknown task format: ' + type); }; TaskTrackingZoneSpec.prototype.onScheduleTask = function (parentZoneDelegate, currentZone, targetZone, task) { task['creationLocation'] = new Error("Task '" + task.type + "' from '" + task.source + "'."); var tasks = this.getTasksFor(task.type); tasks.push(task); return parentZoneDelegate.scheduleTask(targetZone, task); }; TaskTrackingZoneSpec.prototype.onCancelTask = function (parentZoneDelegate, currentZone, targetZone, task) { var tasks = this.getTasksFor(task.type); for (var i = 0; i < tasks.length; i++) { if (tasks[i] == task) { tasks.splice(i, 1); break; } } return parentZoneDelegate.cancelTask(targetZone, task); }; TaskTrackingZoneSpec.prototype.onInvokeTask = function (parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs) { if (task.type === 'eventTask') return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs); var tasks = this.getTasksFor(task.type); for (var i = 0; i < tasks.length; i++) { if (tasks[i] == task) { tasks.splice(i, 1); break; } } return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs); }; TaskTrackingZoneSpec.prototype.clearEvents = function () { while (this.eventTasks.length) { Zone.current.cancelTask(this.eventTasks[0]); } }; return TaskTrackingZoneSpec; }()); // Export the class so that new instances can be created with proper // constructor params. Zone['TaskTrackingZoneSpec'] = TaskTrackingZoneSpec; /** * @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 */ /** * @fileoverview * @suppress {missingRequire} */ (function (global) { // Detect and setup WTF. var wtfTrace = null; var wtfEvents = null; var wtfEnabled = (function () { var wtf = global['wtf']; if (wtf) { wtfTrace = wtf.trace; if (wtfTrace) { wtfEvents = wtfTrace.events; return true; } } return false; })(); var WtfZoneSpec = /** @class */ (function () { function WtfZoneSpec() { this.name = 'WTF'; } WtfZoneSpec.prototype.onFork = function (parentZoneDelegate, currentZone, targetZone, zoneSpec) { var retValue = parentZoneDelegate.fork(targetZone, zoneSpec); WtfZoneSpec.forkInstance(zonePathName(targetZone), retValue.name); return retValue; }; WtfZoneSpec.prototype.onInvoke = function (parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) { var 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)); }; WtfZoneSpec.prototype.onHandleError = function (parentZoneDelegate, currentZone, targetZone, error) { return parentZoneDelegate.handleError(targetZone, error); }; WtfZoneSpec.prototype.onScheduleTask = function (parentZoneDelegate, currentZone, targetZone, task) { var key = task.type + ':' + task.source; var instance = WtfZoneSpec.scheduleInstance[key]; if (!instance) { instance = WtfZoneSpec.scheduleInstance[key] = wtfEvents.createInstance("Zone:schedule:" + key + "(ascii zone, any data)"); } var retValue = parentZoneDelegate.scheduleTask(targetZone, task); instance(zonePathName(targetZone), shallowObj(task.data, 2)); return retValue; }; WtfZoneSpec.prototype.onInvokeTask = function (parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs) {