source: trip-planner-front/node_modules/zone.js/fesm2015/zone-testing-node-bundle.js@ fa375fe

Last change on this file since fa375fe was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 191.9 KB
RevLine 
[6a3a178]1'use strict';
2/**
3 * @license Angular v12.0.0-next.0
4 * (c) 2010-2020 Google LLC. https://angular.io/
5 * License: MIT
6 */
7/**
8 * @license
9 * Copyright Google LLC All Rights Reserved.
10 *
11 * Use of this source code is governed by an MIT-style license that can be
12 * found in the LICENSE file at https://angular.io/license
13 */
14const Zone$1 = (function (global) {
15 const performance = global['performance'];
16 function mark(name) {
17 performance && performance['mark'] && performance['mark'](name);
18 }
19 function performanceMeasure(name, label) {
20 performance && performance['measure'] && performance['measure'](name, label);
21 }
22 mark('Zone');
23 // Initialize before it's accessed below.
24 // __Zone_symbol_prefix global can be used to override the default zone
25 // symbol prefix with a custom one if needed.
26 const symbolPrefix = global['__Zone_symbol_prefix'] || '__zone_symbol__';
27 function __symbol__(name) {
28 return symbolPrefix + name;
29 }
30 const checkDuplicate = global[__symbol__('forceDuplicateZoneCheck')] === true;
31 if (global['Zone']) {
32 // if global['Zone'] already exists (maybe zone.js was already loaded or
33 // some other lib also registered a global object named Zone), we may need
34 // to throw an error, but sometimes user may not want this error.
35 // For example,
36 // we have two web pages, page1 includes zone.js, page2 doesn't.
37 // and the 1st time user load page1 and page2, everything work fine,
38 // but when user load page2 again, error occurs because global['Zone'] already exists.
39 // so we add a flag to let user choose whether to throw this error or not.
40 // By default, if existing Zone is from zone.js, we will not throw the error.
41 if (checkDuplicate || typeof global['Zone'].__symbol__ !== 'function') {
42 throw new Error('Zone already loaded.');
43 }
44 else {
45 return global['Zone'];
46 }
47 }
48 class Zone {
49 constructor(parent, zoneSpec) {
50 this._parent = parent;
51 this._name = zoneSpec ? zoneSpec.name || 'unnamed' : '<root>';
52 this._properties = zoneSpec && zoneSpec.properties || {};
53 this._zoneDelegate =
54 new ZoneDelegate(this, this._parent && this._parent._zoneDelegate, zoneSpec);
55 }
56 static assertZonePatched() {
57 if (global['Promise'] !== patches['ZoneAwarePromise']) {
58 throw new Error('Zone.js has detected that ZoneAwarePromise `(window|global).Promise` ' +
59 'has been overwritten.\n' +
60 'Most likely cause is that a Promise polyfill has been loaded ' +
61 'after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. ' +
62 'If you must load one, do so before loading zone.js.)');
63 }
64 }
65 static get root() {
66 let zone = Zone.current;
67 while (zone.parent) {
68 zone = zone.parent;
69 }
70 return zone;
71 }
72 static get current() {
73 return _currentZoneFrame.zone;
74 }
75 static get currentTask() {
76 return _currentTask;
77 }
78 // tslint:disable-next-line:require-internal-with-underscore
79 static __load_patch(name, fn, ignoreDuplicate = false) {
80 if (patches.hasOwnProperty(name)) {
81 // `checkDuplicate` option is defined from global variable
82 // so it works for all modules.
83 // `ignoreDuplicate` can work for the specified module
84 if (!ignoreDuplicate && checkDuplicate) {
85 throw Error('Already loaded patch: ' + name);
86 }
87 }
88 else if (!global['__Zone_disable_' + name]) {
89 const perfName = 'Zone:' + name;
90 mark(perfName);
91 patches[name] = fn(global, Zone, _api);
92 performanceMeasure(perfName, perfName);
93 }
94 }
95 get parent() {
96 return this._parent;
97 }
98 get name() {
99 return this._name;
100 }
101 get(key) {
102 const zone = this.getZoneWith(key);
103 if (zone)
104 return zone._properties[key];
105 }
106 getZoneWith(key) {
107 let current = this;
108 while (current) {
109 if (current._properties.hasOwnProperty(key)) {
110 return current;
111 }
112 current = current._parent;
113 }
114 return null;
115 }
116 fork(zoneSpec) {
117 if (!zoneSpec)
118 throw new Error('ZoneSpec required!');
119 return this._zoneDelegate.fork(this, zoneSpec);
120 }
121 wrap(callback, source) {
122 if (typeof callback !== 'function') {
123 throw new Error('Expecting function got: ' + callback);
124 }
125 const _callback = this._zoneDelegate.intercept(this, callback, source);
126 const zone = this;
127 return function () {
128 return zone.runGuarded(_callback, this, arguments, source);
129 };
130 }
131 run(callback, applyThis, applyArgs, source) {
132 _currentZoneFrame = { parent: _currentZoneFrame, zone: this };
133 try {
134 return this._zoneDelegate.invoke(this, callback, applyThis, applyArgs, source);
135 }
136 finally {
137 _currentZoneFrame = _currentZoneFrame.parent;
138 }
139 }
140 runGuarded(callback, applyThis = null, applyArgs, source) {
141 _currentZoneFrame = { parent: _currentZoneFrame, zone: this };
142 try {
143 try {
144 return this._zoneDelegate.invoke(this, callback, applyThis, applyArgs, source);
145 }
146 catch (error) {
147 if (this._zoneDelegate.handleError(this, error)) {
148 throw error;
149 }
150 }
151 }
152 finally {
153 _currentZoneFrame = _currentZoneFrame.parent;
154 }
155 }
156 runTask(task, applyThis, applyArgs) {
157 if (task.zone != this) {
158 throw new Error('A task can only be run in the zone of creation! (Creation: ' +
159 (task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')');
160 }
161 // https://github.com/angular/zone.js/issues/778, sometimes eventTask
162 // will run in notScheduled(canceled) state, we should not try to
163 // run such kind of task but just return
164 if (task.state === notScheduled && (task.type === eventTask || task.type === macroTask)) {
165 return;
166 }
167 const reEntryGuard = task.state != running;
168 reEntryGuard && task._transitionTo(running, scheduled);
169 task.runCount++;
170 const previousTask = _currentTask;
171 _currentTask = task;
172 _currentZoneFrame = { parent: _currentZoneFrame, zone: this };
173 try {
174 if (task.type == macroTask && task.data && !task.data.isPeriodic) {
175 task.cancelFn = undefined;
176 }
177 try {
178 return this._zoneDelegate.invokeTask(this, task, applyThis, applyArgs);
179 }
180 catch (error) {
181 if (this._zoneDelegate.handleError(this, error)) {
182 throw error;
183 }
184 }
185 }
186 finally {
187 // if the task's state is notScheduled or unknown, then it has already been cancelled
188 // we should not reset the state to scheduled
189 if (task.state !== notScheduled && task.state !== unknown) {
190 if (task.type == eventTask || (task.data && task.data.isPeriodic)) {
191 reEntryGuard && task._transitionTo(scheduled, running);
192 }
193 else {
194 task.runCount = 0;
195 this._updateTaskCount(task, -1);
196 reEntryGuard &&
197 task._transitionTo(notScheduled, running, notScheduled);
198 }
199 }
200 _currentZoneFrame = _currentZoneFrame.parent;
201 _currentTask = previousTask;
202 }
203 }
204 scheduleTask(task) {
205 if (task.zone && task.zone !== this) {
206 // check if the task was rescheduled, the newZone
207 // should not be the children of the original zone
208 let newZone = this;
209 while (newZone) {
210 if (newZone === task.zone) {
211 throw Error(`can not reschedule task to ${this.name} which is descendants of the original zone ${task.zone.name}`);
212 }
213 newZone = newZone.parent;
214 }
215 }
216 task._transitionTo(scheduling, notScheduled);
217 const zoneDelegates = [];
218 task._zoneDelegates = zoneDelegates;
219 task._zone = this;
220 try {
221 task = this._zoneDelegate.scheduleTask(this, task);
222 }
223 catch (err) {
224 // should set task's state to unknown when scheduleTask throw error
225 // because the err may from reschedule, so the fromState maybe notScheduled
226 task._transitionTo(unknown, scheduling, notScheduled);
227 // TODO: @JiaLiPassion, should we check the result from handleError?
228 this._zoneDelegate.handleError(this, err);
229 throw err;
230 }
231 if (task._zoneDelegates === zoneDelegates) {
232 // we have to check because internally the delegate can reschedule the task.
233 this._updateTaskCount(task, 1);
234 }
235 if (task.state == scheduling) {
236 task._transitionTo(scheduled, scheduling);
237 }
238 return task;
239 }
240 scheduleMicroTask(source, callback, data, customSchedule) {
241 return this.scheduleTask(new ZoneTask(microTask, source, callback, data, customSchedule, undefined));
242 }
243 scheduleMacroTask(source, callback, data, customSchedule, customCancel) {
244 return this.scheduleTask(new ZoneTask(macroTask, source, callback, data, customSchedule, customCancel));
245 }
246 scheduleEventTask(source, callback, data, customSchedule, customCancel) {
247 return this.scheduleTask(new ZoneTask(eventTask, source, callback, data, customSchedule, customCancel));
248 }
249 cancelTask(task) {
250 if (task.zone != this)
251 throw new Error('A task can only be cancelled in the zone of creation! (Creation: ' +
252 (task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')');
253 task._transitionTo(canceling, scheduled, running);
254 try {
255 this._zoneDelegate.cancelTask(this, task);
256 }
257 catch (err) {
258 // if error occurs when cancelTask, transit the state to unknown
259 task._transitionTo(unknown, canceling);
260 this._zoneDelegate.handleError(this, err);
261 throw err;
262 }
263 this._updateTaskCount(task, -1);
264 task._transitionTo(notScheduled, canceling);
265 task.runCount = 0;
266 return task;
267 }
268 _updateTaskCount(task, count) {
269 const zoneDelegates = task._zoneDelegates;
270 if (count == -1) {
271 task._zoneDelegates = null;
272 }
273 for (let i = 0; i < zoneDelegates.length; i++) {
274 zoneDelegates[i]._updateTaskCount(task.type, count);
275 }
276 }
277 }
278 // tslint:disable-next-line:require-internal-with-underscore
279 Zone.__symbol__ = __symbol__;
280 const DELEGATE_ZS = {
281 name: '',
282 onHasTask: (delegate, _, target, hasTaskState) => delegate.hasTask(target, hasTaskState),
283 onScheduleTask: (delegate, _, target, task) => delegate.scheduleTask(target, task),
284 onInvokeTask: (delegate, _, target, task, applyThis, applyArgs) => delegate.invokeTask(target, task, applyThis, applyArgs),
285 onCancelTask: (delegate, _, target, task) => delegate.cancelTask(target, task)
286 };
287 class ZoneDelegate {
288 constructor(zone, parentDelegate, zoneSpec) {
289 this._taskCounts = { 'microTask': 0, 'macroTask': 0, 'eventTask': 0 };
290 this.zone = zone;
291 this._parentDelegate = parentDelegate;
292 this._forkZS = zoneSpec && (zoneSpec && zoneSpec.onFork ? zoneSpec : parentDelegate._forkZS);
293 this._forkDlgt = zoneSpec && (zoneSpec.onFork ? parentDelegate : parentDelegate._forkDlgt);
294 this._forkCurrZone =
295 zoneSpec && (zoneSpec.onFork ? this.zone : parentDelegate._forkCurrZone);
296 this._interceptZS =
297 zoneSpec && (zoneSpec.onIntercept ? zoneSpec : parentDelegate._interceptZS);
298 this._interceptDlgt =
299 zoneSpec && (zoneSpec.onIntercept ? parentDelegate : parentDelegate._interceptDlgt);
300 this._interceptCurrZone =
301 zoneSpec && (zoneSpec.onIntercept ? this.zone : parentDelegate._interceptCurrZone);
302 this._invokeZS = zoneSpec && (zoneSpec.onInvoke ? zoneSpec : parentDelegate._invokeZS);
303 this._invokeDlgt =
304 zoneSpec && (zoneSpec.onInvoke ? parentDelegate : parentDelegate._invokeDlgt);
305 this._invokeCurrZone =
306 zoneSpec && (zoneSpec.onInvoke ? this.zone : parentDelegate._invokeCurrZone);
307 this._handleErrorZS =
308 zoneSpec && (zoneSpec.onHandleError ? zoneSpec : parentDelegate._handleErrorZS);
309 this._handleErrorDlgt =
310 zoneSpec && (zoneSpec.onHandleError ? parentDelegate : parentDelegate._handleErrorDlgt);
311 this._handleErrorCurrZone =
312 zoneSpec && (zoneSpec.onHandleError ? this.zone : parentDelegate._handleErrorCurrZone);
313 this._scheduleTaskZS =
314 zoneSpec && (zoneSpec.onScheduleTask ? zoneSpec : parentDelegate._scheduleTaskZS);
315 this._scheduleTaskDlgt = zoneSpec &&
316 (zoneSpec.onScheduleTask ? parentDelegate : parentDelegate._scheduleTaskDlgt);
317 this._scheduleTaskCurrZone =
318 zoneSpec && (zoneSpec.onScheduleTask ? this.zone : parentDelegate._scheduleTaskCurrZone);
319 this._invokeTaskZS =
320 zoneSpec && (zoneSpec.onInvokeTask ? zoneSpec : parentDelegate._invokeTaskZS);
321 this._invokeTaskDlgt =
322 zoneSpec && (zoneSpec.onInvokeTask ? parentDelegate : parentDelegate._invokeTaskDlgt);
323 this._invokeTaskCurrZone =
324 zoneSpec && (zoneSpec.onInvokeTask ? this.zone : parentDelegate._invokeTaskCurrZone);
325 this._cancelTaskZS =
326 zoneSpec && (zoneSpec.onCancelTask ? zoneSpec : parentDelegate._cancelTaskZS);
327 this._cancelTaskDlgt =
328 zoneSpec && (zoneSpec.onCancelTask ? parentDelegate : parentDelegate._cancelTaskDlgt);
329 this._cancelTaskCurrZone =
330 zoneSpec && (zoneSpec.onCancelTask ? this.zone : parentDelegate._cancelTaskCurrZone);
331 this._hasTaskZS = null;
332 this._hasTaskDlgt = null;
333 this._hasTaskDlgtOwner = null;
334 this._hasTaskCurrZone = null;
335 const zoneSpecHasTask = zoneSpec && zoneSpec.onHasTask;
336 const parentHasTask = parentDelegate && parentDelegate._hasTaskZS;
337 if (zoneSpecHasTask || parentHasTask) {
338 // If we need to report hasTask, than this ZS needs to do ref counting on tasks. In such
339 // a case all task related interceptors must go through this ZD. We can't short circuit it.
340 this._hasTaskZS = zoneSpecHasTask ? zoneSpec : DELEGATE_ZS;
341 this._hasTaskDlgt = parentDelegate;
342 this._hasTaskDlgtOwner = this;
343 this._hasTaskCurrZone = zone;
344 if (!zoneSpec.onScheduleTask) {
345 this._scheduleTaskZS = DELEGATE_ZS;
346 this._scheduleTaskDlgt = parentDelegate;
347 this._scheduleTaskCurrZone = this.zone;
348 }
349 if (!zoneSpec.onInvokeTask) {
350 this._invokeTaskZS = DELEGATE_ZS;
351 this._invokeTaskDlgt = parentDelegate;
352 this._invokeTaskCurrZone = this.zone;
353 }
354 if (!zoneSpec.onCancelTask) {
355 this._cancelTaskZS = DELEGATE_ZS;
356 this._cancelTaskDlgt = parentDelegate;
357 this._cancelTaskCurrZone = this.zone;
358 }
359 }
360 }
361 fork(targetZone, zoneSpec) {
362 return this._forkZS ? this._forkZS.onFork(this._forkDlgt, this.zone, targetZone, zoneSpec) :
363 new Zone(targetZone, zoneSpec);
364 }
365 intercept(targetZone, callback, source) {
366 return this._interceptZS ?
367 this._interceptZS.onIntercept(this._interceptDlgt, this._interceptCurrZone, targetZone, callback, source) :
368 callback;
369 }
370 invoke(targetZone, callback, applyThis, applyArgs, source) {
371 return this._invokeZS ? this._invokeZS.onInvoke(this._invokeDlgt, this._invokeCurrZone, targetZone, callback, applyThis, applyArgs, source) :
372 callback.apply(applyThis, applyArgs);
373 }
374 handleError(targetZone, error) {
375 return this._handleErrorZS ?
376 this._handleErrorZS.onHandleError(this._handleErrorDlgt, this._handleErrorCurrZone, targetZone, error) :
377 true;
378 }
379 scheduleTask(targetZone, task) {
380 let returnTask = task;
381 if (this._scheduleTaskZS) {
382 if (this._hasTaskZS) {
383 returnTask._zoneDelegates.push(this._hasTaskDlgtOwner);
384 }
385 // clang-format off
386 returnTask = this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt, this._scheduleTaskCurrZone, targetZone, task);
387 // clang-format on
388 if (!returnTask)
389 returnTask = task;
390 }
391 else {
392 if (task.scheduleFn) {
393 task.scheduleFn(task);
394 }
395 else if (task.type == microTask) {
396 scheduleMicroTask(task);
397 }
398 else {
399 throw new Error('Task is missing scheduleFn.');
400 }
401 }
402 return returnTask;
403 }
404 invokeTask(targetZone, task, applyThis, applyArgs) {
405 return this._invokeTaskZS ? this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt, this._invokeTaskCurrZone, targetZone, task, applyThis, applyArgs) :
406 task.callback.apply(applyThis, applyArgs);
407 }
408 cancelTask(targetZone, task) {
409 let value;
410 if (this._cancelTaskZS) {
411 value = this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt, this._cancelTaskCurrZone, targetZone, task);
412 }
413 else {
414 if (!task.cancelFn) {
415 throw Error('Task is not cancelable');
416 }
417 value = task.cancelFn(task);
418 }
419 return value;
420 }
421 hasTask(targetZone, isEmpty) {
422 // hasTask should not throw error so other ZoneDelegate
423 // can still trigger hasTask callback
424 try {
425 this._hasTaskZS &&
426 this._hasTaskZS.onHasTask(this._hasTaskDlgt, this._hasTaskCurrZone, targetZone, isEmpty);
427 }
428 catch (err) {
429 this.handleError(targetZone, err);
430 }
431 }
432 // tslint:disable-next-line:require-internal-with-underscore
433 _updateTaskCount(type, count) {
434 const counts = this._taskCounts;
435 const prev = counts[type];
436 const next = counts[type] = prev + count;
437 if (next < 0) {
438 throw new Error('More tasks executed then were scheduled.');
439 }
440 if (prev == 0 || next == 0) {
441 const isEmpty = {
442 microTask: counts['microTask'] > 0,
443 macroTask: counts['macroTask'] > 0,
444 eventTask: counts['eventTask'] > 0,
445 change: type
446 };
447 this.hasTask(this.zone, isEmpty);
448 }
449 }
450 }
451 class ZoneTask {
452 constructor(type, source, callback, options, scheduleFn, cancelFn) {
453 // tslint:disable-next-line:require-internal-with-underscore
454 this._zone = null;
455 this.runCount = 0;
456 // tslint:disable-next-line:require-internal-with-underscore
457 this._zoneDelegates = null;
458 // tslint:disable-next-line:require-internal-with-underscore
459 this._state = 'notScheduled';
460 this.type = type;
461 this.source = source;
462 this.data = options;
463 this.scheduleFn = scheduleFn;
464 this.cancelFn = cancelFn;
465 if (!callback) {
466 throw new Error('callback is not defined');
467 }
468 this.callback = callback;
469 const self = this;
470 // TODO: @JiaLiPassion options should have interface
471 if (type === eventTask && options && options.useG) {
472 this.invoke = ZoneTask.invokeTask;
473 }
474 else {
475 this.invoke = function () {
476 return ZoneTask.invokeTask.call(global, self, this, arguments);
477 };
478 }
479 }
480 static invokeTask(task, target, args) {
481 if (!task) {
482 task = this;
483 }
484 _numberOfNestedTaskFrames++;
485 try {
486 task.runCount++;
487 return task.zone.runTask(task, target, args);
488 }
489 finally {
490 if (_numberOfNestedTaskFrames == 1) {
491 drainMicroTaskQueue();
492 }
493 _numberOfNestedTaskFrames--;
494 }
495 }
496 get zone() {
497 return this._zone;
498 }
499 get state() {
500 return this._state;
501 }
502 cancelScheduleRequest() {
503 this._transitionTo(notScheduled, scheduling);
504 }
505 // tslint:disable-next-line:require-internal-with-underscore
506 _transitionTo(toState, fromState1, fromState2) {
507 if (this._state === fromState1 || this._state === fromState2) {
508 this._state = toState;
509 if (toState == notScheduled) {
510 this._zoneDelegates = null;
511 }
512 }
513 else {
514 throw new Error(`${this.type} '${this.source}': can not transition to '${toState}', expecting state '${fromState1}'${fromState2 ? ' or \'' + fromState2 + '\'' : ''}, was '${this._state}'.`);
515 }
516 }
517 toString() {
518 if (this.data && typeof this.data.handleId !== 'undefined') {
519 return this.data.handleId.toString();
520 }
521 else {
522 return Object.prototype.toString.call(this);
523 }
524 }
525 // add toJSON method to prevent cyclic error when
526 // call JSON.stringify(zoneTask)
527 toJSON() {
528 return {
529 type: this.type,
530 state: this.state,
531 source: this.source,
532 zone: this.zone.name,
533 runCount: this.runCount
534 };
535 }
536 }
537 //////////////////////////////////////////////////////
538 //////////////////////////////////////////////////////
539 /// MICROTASK QUEUE
540 //////////////////////////////////////////////////////
541 //////////////////////////////////////////////////////
542 const symbolSetTimeout = __symbol__('setTimeout');
543 const symbolPromise = __symbol__('Promise');
544 const symbolThen = __symbol__('then');
545 let _microTaskQueue = [];
546 let _isDrainingMicrotaskQueue = false;
547 let nativeMicroTaskQueuePromise;
548 function scheduleMicroTask(task) {
549 // if we are not running in any task, and there has not been anything scheduled
550 // we must bootstrap the initial task creation by manually scheduling the drain
551 if (_numberOfNestedTaskFrames === 0 && _microTaskQueue.length === 0) {
552 // We are not running in Task, so we need to kickstart the microtask queue.
553 if (!nativeMicroTaskQueuePromise) {
554 if (global[symbolPromise]) {
555 nativeMicroTaskQueuePromise = global[symbolPromise].resolve(0);
556 }
557 }
558 if (nativeMicroTaskQueuePromise) {
559 let nativeThen = nativeMicroTaskQueuePromise[symbolThen];
560 if (!nativeThen) {
561 // native Promise is not patchable, we need to use `then` directly
562 // issue 1078
563 nativeThen = nativeMicroTaskQueuePromise['then'];
564 }
565 nativeThen.call(nativeMicroTaskQueuePromise, drainMicroTaskQueue);
566 }
567 else {
568 global[symbolSetTimeout](drainMicroTaskQueue, 0);
569 }
570 }
571 task && _microTaskQueue.push(task);
572 }
573 function drainMicroTaskQueue() {
574 if (!_isDrainingMicrotaskQueue) {
575 _isDrainingMicrotaskQueue = true;
576 while (_microTaskQueue.length) {
577 const queue = _microTaskQueue;
578 _microTaskQueue = [];
579 for (let i = 0; i < queue.length; i++) {
580 const task = queue[i];
581 try {
582 task.zone.runTask(task, null, null);
583 }
584 catch (error) {
585 _api.onUnhandledError(error);
586 }
587 }
588 }
589 _api.microtaskDrainDone();
590 _isDrainingMicrotaskQueue = false;
591 }
592 }
593 //////////////////////////////////////////////////////
594 //////////////////////////////////////////////////////
595 /// BOOTSTRAP
596 //////////////////////////////////////////////////////
597 //////////////////////////////////////////////////////
598 const NO_ZONE = { name: 'NO ZONE' };
599 const notScheduled = 'notScheduled', scheduling = 'scheduling', scheduled = 'scheduled', running = 'running', canceling = 'canceling', unknown = 'unknown';
600 const microTask = 'microTask', macroTask = 'macroTask', eventTask = 'eventTask';
601 const patches = {};
602 const _api = {
603 symbol: __symbol__,
604 currentZoneFrame: () => _currentZoneFrame,
605 onUnhandledError: noop,
606 microtaskDrainDone: noop,
607 scheduleMicroTask: scheduleMicroTask,
608 showUncaughtError: () => !Zone[__symbol__('ignoreConsoleErrorUncaughtError')],
609 patchEventTarget: () => [],
610 patchOnProperties: noop,
611 patchMethod: () => noop,
612 bindArguments: () => [],
613 patchThen: () => noop,
614 patchMacroTask: () => noop,
615 patchEventPrototype: () => noop,
616 isIEOrEdge: () => false,
617 getGlobalObjects: () => undefined,
618 ObjectDefineProperty: () => noop,
619 ObjectGetOwnPropertyDescriptor: () => undefined,
620 ObjectCreate: () => undefined,
621 ArraySlice: () => [],
622 patchClass: () => noop,
623 wrapWithCurrentZone: () => noop,
624 filterProperties: () => [],
625 attachOriginToPatched: () => noop,
626 _redefineProperty: () => noop,
627 patchCallbacks: () => noop
628 };
629 let _currentZoneFrame = { parent: null, zone: new Zone(null, null) };
630 let _currentTask = null;
631 let _numberOfNestedTaskFrames = 0;
632 function noop() { }
633 performanceMeasure('Zone', 'Zone');
634 return global['Zone'] = Zone;
635})(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global);
636
637/**
638 * @license
639 * Copyright Google LLC All Rights Reserved.
640 *
641 * Use of this source code is governed by an MIT-style license that can be
642 * found in the LICENSE file at https://angular.io/license
643 */
644/**
645 * Suppress closure compiler errors about unknown 'Zone' variable
646 * @fileoverview
647 * @suppress {undefinedVars,globalThis,missingRequire}
648 */
649/// <reference types="node"/>
650// issue #989, to reduce bundle size, use short name
651/** Object.getOwnPropertyDescriptor */
652const ObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
653/** Object.defineProperty */
654const ObjectDefineProperty = Object.defineProperty;
655/** Object.getPrototypeOf */
656const ObjectGetPrototypeOf = Object.getPrototypeOf;
657/** Array.prototype.slice */
658const ArraySlice = Array.prototype.slice;
659/** addEventListener string const */
660const ADD_EVENT_LISTENER_STR = 'addEventListener';
661/** removeEventListener string const */
662const REMOVE_EVENT_LISTENER_STR = 'removeEventListener';
663/** zoneSymbol addEventListener */
664const ZONE_SYMBOL_ADD_EVENT_LISTENER = Zone.__symbol__(ADD_EVENT_LISTENER_STR);
665/** zoneSymbol removeEventListener */
666const ZONE_SYMBOL_REMOVE_EVENT_LISTENER = Zone.__symbol__(REMOVE_EVENT_LISTENER_STR);
667/** true string const */
668const TRUE_STR = 'true';
669/** false string const */
670const FALSE_STR = 'false';
671/** Zone symbol prefix string const. */
672const ZONE_SYMBOL_PREFIX = Zone.__symbol__('');
673function wrapWithCurrentZone(callback, source) {
674 return Zone.current.wrap(callback, source);
675}
676function scheduleMacroTaskWithCurrentZone(source, callback, data, customSchedule, customCancel) {
677 return Zone.current.scheduleMacroTask(source, callback, data, customSchedule, customCancel);
678}
679const zoneSymbol = Zone.__symbol__;
680const isWindowExists = typeof window !== 'undefined';
681const internalWindow = isWindowExists ? window : undefined;
682const _global = isWindowExists && internalWindow || typeof self === 'object' && self || global;
683const REMOVE_ATTRIBUTE = 'removeAttribute';
684const NULL_ON_PROP_VALUE = [null];
685function bindArguments(args, source) {
686 for (let i = args.length - 1; i >= 0; i--) {
687 if (typeof args[i] === 'function') {
688 args[i] = wrapWithCurrentZone(args[i], source + '_' + i);
689 }
690 }
691 return args;
692}
693function isPropertyWritable(propertyDesc) {
694 if (!propertyDesc) {
695 return true;
696 }
697 if (propertyDesc.writable === false) {
698 return false;
699 }
700 return !(typeof propertyDesc.get === 'function' && typeof propertyDesc.set === 'undefined');
701}
702const isWebWorker = (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope);
703// Make sure to access `process` through `_global` so that WebPack does not accidentally browserify
704// this code.
705const isNode = (!('nw' in _global) && typeof _global.process !== 'undefined' &&
706 {}.toString.call(_global.process) === '[object process]');
707const isBrowser = !isNode && !isWebWorker && !!(isWindowExists && internalWindow['HTMLElement']);
708// we are in electron of nw, so we are both browser and nodejs
709// Make sure to access `process` through `_global` so that WebPack does not accidentally browserify
710// this code.
711const isMix = typeof _global.process !== 'undefined' &&
712 {}.toString.call(_global.process) === '[object process]' && !isWebWorker &&
713 !!(isWindowExists && internalWindow['HTMLElement']);
714const zoneSymbolEventNames = {};
715const wrapFn = function (event) {
716 // https://github.com/angular/zone.js/issues/911, in IE, sometimes
717 // event will be undefined, so we need to use window.event
718 event = event || _global.event;
719 if (!event) {
720 return;
721 }
722 let eventNameSymbol = zoneSymbolEventNames[event.type];
723 if (!eventNameSymbol) {
724 eventNameSymbol = zoneSymbolEventNames[event.type] = zoneSymbol('ON_PROPERTY' + event.type);
725 }
726 const target = this || event.target || _global;
727 const listener = target[eventNameSymbol];
728 let result;
729 if (isBrowser && target === internalWindow && event.type === 'error') {
730 // window.onerror have different signiture
731 // https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror#window.onerror
732 // and onerror callback will prevent default when callback return true
733 const errorEvent = event;
734 result = listener &&
735 listener.call(this, errorEvent.message, errorEvent.filename, errorEvent.lineno, errorEvent.colno, errorEvent.error);
736 if (result === true) {
737 event.preventDefault();
738 }
739 }
740 else {
741 result = listener && listener.apply(this, arguments);
742 if (result != undefined && !result) {
743 event.preventDefault();
744 }
745 }
746 return result;
747};
748function patchProperty(obj, prop, prototype) {
749 let desc = ObjectGetOwnPropertyDescriptor(obj, prop);
750 if (!desc && prototype) {
751 // when patch window object, use prototype to check prop exist or not
752 const prototypeDesc = ObjectGetOwnPropertyDescriptor(prototype, prop);
753 if (prototypeDesc) {
754 desc = { enumerable: true, configurable: true };
755 }
756 }
757 // if the descriptor not exists or is not configurable
758 // just return
759 if (!desc || !desc.configurable) {
760 return;
761 }
762 const onPropPatchedSymbol = zoneSymbol('on' + prop + 'patched');
763 if (obj.hasOwnProperty(onPropPatchedSymbol) && obj[onPropPatchedSymbol]) {
764 return;
765 }
766 // A property descriptor cannot have getter/setter and be writable
767 // deleting the writable and value properties avoids this error:
768 //
769 // TypeError: property descriptors must not specify a value or be writable when a
770 // getter or setter has been specified
771 delete desc.writable;
772 delete desc.value;
773 const originalDescGet = desc.get;
774 const originalDescSet = desc.set;
775 // substr(2) cuz 'onclick' -> 'click', etc
776 const eventName = prop.substr(2);
777 let eventNameSymbol = zoneSymbolEventNames[eventName];
778 if (!eventNameSymbol) {
779 eventNameSymbol = zoneSymbolEventNames[eventName] = zoneSymbol('ON_PROPERTY' + eventName);
780 }
781 desc.set = function (newValue) {
782 // in some of windows's onproperty callback, this is undefined
783 // so we need to check it
784 let target = this;
785 if (!target && obj === _global) {
786 target = _global;
787 }
788 if (!target) {
789 return;
790 }
791 let previousValue = target[eventNameSymbol];
792 if (previousValue) {
793 target.removeEventListener(eventName, wrapFn);
794 }
795 // issue #978, when onload handler was added before loading zone.js
796 // we should remove it with originalDescSet
797 if (originalDescSet) {
798 originalDescSet.apply(target, NULL_ON_PROP_VALUE);
799 }
800 if (typeof newValue === 'function') {
801 target[eventNameSymbol] = newValue;
802 target.addEventListener(eventName, wrapFn, false);
803 }
804 else {
805 target[eventNameSymbol] = null;
806 }
807 };
808 // The getter would return undefined for unassigned properties but the default value of an
809 // unassigned property is null
810 desc.get = function () {
811 // in some of windows's onproperty callback, this is undefined
812 // so we need to check it
813 let target = this;
814 if (!target && obj === _global) {
815 target = _global;
816 }
817 if (!target) {
818 return null;
819 }
820 const listener = target[eventNameSymbol];
821 if (listener) {
822 return listener;
823 }
824 else if (originalDescGet) {
825 // result will be null when use inline event attribute,
826 // such as <button onclick="func();">OK</button>
827 // because the onclick function is internal raw uncompiled handler
828 // the onclick will be evaluated when first time event was triggered or
829 // the property is accessed, https://github.com/angular/zone.js/issues/525
830 // so we should use original native get to retrieve the handler
831 let value = originalDescGet && originalDescGet.call(this);
832 if (value) {
833 desc.set.call(this, value);
834 if (typeof target[REMOVE_ATTRIBUTE] === 'function') {
835 target.removeAttribute(prop);
836 }
837 return value;
838 }
839 }
840 return null;
841 };
842 ObjectDefineProperty(obj, prop, desc);
843 obj[onPropPatchedSymbol] = true;
844}
845function patchOnProperties(obj, properties, prototype) {
846 if (properties) {
847 for (let i = 0; i < properties.length; i++) {
848 patchProperty(obj, 'on' + properties[i], prototype);
849 }
850 }
851 else {
852 const onProperties = [];
853 for (const prop in obj) {
854 if (prop.substr(0, 2) == 'on') {
855 onProperties.push(prop);
856 }
857 }
858 for (let j = 0; j < onProperties.length; j++) {
859 patchProperty(obj, onProperties[j], prototype);
860 }
861 }
862}
863const originalInstanceKey = zoneSymbol('originalInstance');
864function copySymbolProperties(src, dest) {
865 if (typeof Object.getOwnPropertySymbols !== 'function') {
866 return;
867 }
868 const symbols = Object.getOwnPropertySymbols(src);
869 symbols.forEach((symbol) => {
870 const desc = Object.getOwnPropertyDescriptor(src, symbol);
871 Object.defineProperty(dest, symbol, {
872 get: function () {
873 return src[symbol];
874 },
875 set: function (value) {
876 if (desc && (!desc.writable || typeof desc.set !== 'function')) {
877 // if src[symbol] is not writable or not have a setter, just return
878 return;
879 }
880 src[symbol] = value;
881 },
882 enumerable: desc ? desc.enumerable : true,
883 configurable: desc ? desc.configurable : true
884 });
885 });
886}
887let shouldCopySymbolProperties = false;
888function setShouldCopySymbolProperties(flag) {
889 shouldCopySymbolProperties = flag;
890}
891function patchMethod(target, name, patchFn) {
892 let proto = target;
893 while (proto && !proto.hasOwnProperty(name)) {
894 proto = ObjectGetPrototypeOf(proto);
895 }
896 if (!proto && target[name]) {
897 // somehow we did not find it, but we can see it. This happens on IE for Window properties.
898 proto = target;
899 }
900 const delegateName = zoneSymbol(name);
901 let delegate = null;
902 if (proto && (!(delegate = proto[delegateName]) || !proto.hasOwnProperty(delegateName))) {
903 delegate = proto[delegateName] = proto[name];
904 // check whether proto[name] is writable
905 // some property is readonly in safari, such as HtmlCanvasElement.prototype.toBlob
906 const desc = proto && ObjectGetOwnPropertyDescriptor(proto, name);
907 if (isPropertyWritable(desc)) {
908 const patchDelegate = patchFn(delegate, delegateName, name);
909 proto[name] = function () {
910 return patchDelegate(this, arguments);
911 };
912 attachOriginToPatched(proto[name], delegate);
913 if (shouldCopySymbolProperties) {
914 copySymbolProperties(delegate, proto[name]);
915 }
916 }
917 }
918 return delegate;
919}
920// TODO: @JiaLiPassion, support cancel task later if necessary
921function patchMacroTask(obj, funcName, metaCreator) {
922 let setNative = null;
923 function scheduleTask(task) {
924 const data = task.data;
925 data.args[data.cbIdx] = function () {
926 task.invoke.apply(this, arguments);
927 };
928 setNative.apply(data.target, data.args);
929 return task;
930 }
931 setNative = patchMethod(obj, funcName, (delegate) => function (self, args) {
932 const meta = metaCreator(self, args);
933 if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === 'function') {
934 return scheduleMacroTaskWithCurrentZone(meta.name, args[meta.cbIdx], meta, scheduleTask);
935 }
936 else {
937 // cause an error by calling it directly.
938 return delegate.apply(self, args);
939 }
940 });
941}
942function patchMicroTask(obj, funcName, metaCreator) {
943 let setNative = null;
944 function scheduleTask(task) {
945 const data = task.data;
946 data.args[data.cbIdx] = function () {
947 task.invoke.apply(this, arguments);
948 };
949 setNative.apply(data.target, data.args);
950 return task;
951 }
952 setNative = patchMethod(obj, funcName, (delegate) => function (self, args) {
953 const meta = metaCreator(self, args);
954 if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === 'function') {
955 return Zone.current.scheduleMicroTask(meta.name, args[meta.cbIdx], meta, scheduleTask);
956 }
957 else {
958 // cause an error by calling it directly.
959 return delegate.apply(self, args);
960 }
961 });
962}
963function attachOriginToPatched(patched, original) {
964 patched[zoneSymbol('OriginalDelegate')] = original;
965}
966
967/**
968 * @license
969 * Copyright Google LLC All Rights Reserved.
970 *
971 * Use of this source code is governed by an MIT-style license that can be
972 * found in the LICENSE file at https://angular.io/license
973 */
974Zone.__load_patch('ZoneAwarePromise', (global, Zone, api) => {
975 const ObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
976 const ObjectDefineProperty = Object.defineProperty;
977 function readableObjectToString(obj) {
978 if (obj && obj.toString === Object.prototype.toString) {
979 const className = obj.constructor && obj.constructor.name;
980 return (className ? className : '') + ': ' + JSON.stringify(obj);
981 }
982 return obj ? obj.toString() : Object.prototype.toString.call(obj);
983 }
984 const __symbol__ = api.symbol;
985 const _uncaughtPromiseErrors = [];
986 const isDisableWrappingUncaughtPromiseRejection = global[__symbol__('DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION')] === true;
987 const symbolPromise = __symbol__('Promise');
988 const symbolThen = __symbol__('then');
989 const creationTrace = '__creationTrace__';
990 api.onUnhandledError = (e) => {
991 if (api.showUncaughtError()) {
992 const rejection = e && e.rejection;
993 if (rejection) {
994 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);
995 }
996 else {
997 console.error(e);
998 }
999 }
1000 };
1001 api.microtaskDrainDone = () => {
1002 while (_uncaughtPromiseErrors.length) {
1003 const uncaughtPromiseError = _uncaughtPromiseErrors.shift();
1004 try {
1005 uncaughtPromiseError.zone.runGuarded(() => {
1006 if (uncaughtPromiseError.throwOriginal) {
1007 throw uncaughtPromiseError.rejection;
1008 }
1009 throw uncaughtPromiseError;
1010 });
1011 }
1012 catch (error) {
1013 handleUnhandledRejection(error);
1014 }
1015 }
1016 };
1017 const UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL = __symbol__('unhandledPromiseRejectionHandler');
1018 function handleUnhandledRejection(e) {
1019 api.onUnhandledError(e);
1020 try {
1021 const handler = Zone[UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL];
1022 if (typeof handler === 'function') {
1023 handler.call(this, e);
1024 }
1025 }
1026 catch (err) {
1027 }
1028 }
1029 function isThenable(value) {
1030 return value && value.then;
1031 }
1032 function forwardResolution(value) {
1033 return value;
1034 }
1035 function forwardRejection(rejection) {
1036 return ZoneAwarePromise.reject(rejection);
1037 }
1038 const symbolState = __symbol__('state');
1039 const symbolValue = __symbol__('value');
1040 const symbolFinally = __symbol__('finally');
1041 const symbolParentPromiseValue = __symbol__('parentPromiseValue');
1042 const symbolParentPromiseState = __symbol__('parentPromiseState');
1043 const source = 'Promise.then';
1044 const UNRESOLVED = null;
1045 const RESOLVED = true;
1046 const REJECTED = false;
1047 const REJECTED_NO_CATCH = 0;
1048 function makeResolver(promise, state) {
1049 return (v) => {
1050 try {
1051 resolvePromise(promise, state, v);
1052 }
1053 catch (err) {
1054 resolvePromise(promise, false, err);
1055 }
1056 // Do not return value or you will break the Promise spec.
1057 };
1058 }
1059 const once = function () {
1060 let wasCalled = false;
1061 return function wrapper(wrappedFunction) {
1062 return function () {
1063 if (wasCalled) {
1064 return;
1065 }
1066 wasCalled = true;
1067 wrappedFunction.apply(null, arguments);
1068 };
1069 };
1070 };
1071 const TYPE_ERROR = 'Promise resolved with itself';
1072 const CURRENT_TASK_TRACE_SYMBOL = __symbol__('currentTaskTrace');
1073 // Promise Resolution
1074 function resolvePromise(promise, state, value) {
1075 const onceWrapper = once();
1076 if (promise === value) {
1077 throw new TypeError(TYPE_ERROR);
1078 }
1079 if (promise[symbolState] === UNRESOLVED) {
1080 // should only get value.then once based on promise spec.
1081 let then = null;
1082 try {
1083 if (typeof value === 'object' || typeof value === 'function') {
1084 then = value && value.then;
1085 }
1086 }
1087 catch (err) {
1088 onceWrapper(() => {
1089 resolvePromise(promise, false, err);
1090 })();
1091 return promise;
1092 }
1093 // if (value instanceof ZoneAwarePromise) {
1094 if (state !== REJECTED && value instanceof ZoneAwarePromise &&
1095 value.hasOwnProperty(symbolState) && value.hasOwnProperty(symbolValue) &&
1096 value[symbolState] !== UNRESOLVED) {
1097 clearRejectedNoCatch(value);
1098 resolvePromise(promise, value[symbolState], value[symbolValue]);
1099 }
1100 else if (state !== REJECTED && typeof then === 'function') {
1101 try {
1102 then.call(value, onceWrapper(makeResolver(promise, state)), onceWrapper(makeResolver(promise, false)));
1103 }
1104 catch (err) {
1105 onceWrapper(() => {
1106 resolvePromise(promise, false, err);
1107 })();
1108 }
1109 }
1110 else {
1111 promise[symbolState] = state;
1112 const queue = promise[symbolValue];
1113 promise[symbolValue] = value;
1114 if (promise[symbolFinally] === symbolFinally) {
1115 // the promise is generated by Promise.prototype.finally
1116 if (state === RESOLVED) {
1117 // the state is resolved, should ignore the value
1118 // and use parent promise value
1119 promise[symbolState] = promise[symbolParentPromiseState];
1120 promise[symbolValue] = promise[symbolParentPromiseValue];
1121 }
1122 }
1123 // record task information in value when error occurs, so we can
1124 // do some additional work such as render longStackTrace
1125 if (state === REJECTED && value instanceof Error) {
1126 // check if longStackTraceZone is here
1127 const trace = Zone.currentTask && Zone.currentTask.data &&
1128 Zone.currentTask.data[creationTrace];
1129 if (trace) {
1130 // only keep the long stack trace into error when in longStackTraceZone
1131 ObjectDefineProperty(value, CURRENT_TASK_TRACE_SYMBOL, { configurable: true, enumerable: false, writable: true, value: trace });
1132 }
1133 }
1134 for (let i = 0; i < queue.length;) {
1135 scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]);
1136 }
1137 if (queue.length == 0 && state == REJECTED) {
1138 promise[symbolState] = REJECTED_NO_CATCH;
1139 let uncaughtPromiseError = value;
1140 try {
1141 // Here we throws a new Error to print more readable error log
1142 // and if the value is not an error, zone.js builds an `Error`
1143 // Object here to attach the stack information.
1144 throw new Error('Uncaught (in promise): ' + readableObjectToString(value) +
1145 (value && value.stack ? '\n' + value.stack : ''));
1146 }
1147 catch (err) {
1148 uncaughtPromiseError = err;
1149 }
1150 if (isDisableWrappingUncaughtPromiseRejection) {
1151 // If disable wrapping uncaught promise reject
1152 // use the value instead of wrapping it.
1153 uncaughtPromiseError.throwOriginal = true;
1154 }
1155 uncaughtPromiseError.rejection = value;
1156 uncaughtPromiseError.promise = promise;
1157 uncaughtPromiseError.zone = Zone.current;
1158 uncaughtPromiseError.task = Zone.currentTask;
1159 _uncaughtPromiseErrors.push(uncaughtPromiseError);
1160 api.scheduleMicroTask(); // to make sure that it is running
1161 }
1162 }
1163 }
1164 // Resolving an already resolved promise is a noop.
1165 return promise;
1166 }
1167 const REJECTION_HANDLED_HANDLER = __symbol__('rejectionHandledHandler');
1168 function clearRejectedNoCatch(promise) {
1169 if (promise[symbolState] === REJECTED_NO_CATCH) {
1170 // if the promise is rejected no catch status
1171 // and queue.length > 0, means there is a error handler
1172 // here to handle the rejected promise, we should trigger
1173 // windows.rejectionhandled eventHandler or nodejs rejectionHandled
1174 // eventHandler
1175 try {
1176 const handler = Zone[REJECTION_HANDLED_HANDLER];
1177 if (handler && typeof handler === 'function') {
1178 handler.call(this, { rejection: promise[symbolValue], promise: promise });
1179 }
1180 }
1181 catch (err) {
1182 }
1183 promise[symbolState] = REJECTED;
1184 for (let i = 0; i < _uncaughtPromiseErrors.length; i++) {
1185 if (promise === _uncaughtPromiseErrors[i].promise) {
1186 _uncaughtPromiseErrors.splice(i, 1);
1187 }
1188 }
1189 }
1190 }
1191 function scheduleResolveOrReject(promise, zone, chainPromise, onFulfilled, onRejected) {
1192 clearRejectedNoCatch(promise);
1193 const promiseState = promise[symbolState];
1194 const delegate = promiseState ?
1195 (typeof onFulfilled === 'function') ? onFulfilled : forwardResolution :
1196 (typeof onRejected === 'function') ? onRejected : forwardRejection;
1197 zone.scheduleMicroTask(source, () => {
1198 try {
1199 const parentPromiseValue = promise[symbolValue];
1200 const isFinallyPromise = !!chainPromise && symbolFinally === chainPromise[symbolFinally];
1201 if (isFinallyPromise) {
1202 // if the promise is generated from finally call, keep parent promise's state and value
1203 chainPromise[symbolParentPromiseValue] = parentPromiseValue;
1204 chainPromise[symbolParentPromiseState] = promiseState;
1205 }
1206 // should not pass value to finally callback
1207 const value = zone.run(delegate, undefined, isFinallyPromise && delegate !== forwardRejection && delegate !== forwardResolution ?
1208 [] :
1209 [parentPromiseValue]);
1210 resolvePromise(chainPromise, true, value);
1211 }
1212 catch (error) {
1213 // if error occurs, should always return this error
1214 resolvePromise(chainPromise, false, error);
1215 }
1216 }, chainPromise);
1217 }
1218 const ZONE_AWARE_PROMISE_TO_STRING = 'function ZoneAwarePromise() { [native code] }';
1219 const noop = function () { };
1220 class ZoneAwarePromise {
1221 static toString() {
1222 return ZONE_AWARE_PROMISE_TO_STRING;
1223 }
1224 static resolve(value) {
1225 return resolvePromise(new this(null), RESOLVED, value);
1226 }
1227 static reject(error) {
1228 return resolvePromise(new this(null), REJECTED, error);
1229 }
1230 static race(values) {
1231 let resolve;
1232 let reject;
1233 let promise = new this((res, rej) => {
1234 resolve = res;
1235 reject = rej;
1236 });
1237 function onResolve(value) {
1238 resolve(value);
1239 }
1240 function onReject(error) {
1241 reject(error);
1242 }
1243 for (let value of values) {
1244 if (!isThenable(value)) {
1245 value = this.resolve(value);
1246 }
1247 value.then(onResolve, onReject);
1248 }
1249 return promise;
1250 }
1251 static all(values) {
1252 return ZoneAwarePromise.allWithCallback(values);
1253 }
1254 static allSettled(values) {
1255 const P = this && this.prototype instanceof ZoneAwarePromise ? this : ZoneAwarePromise;
1256 return P.allWithCallback(values, {
1257 thenCallback: (value) => ({ status: 'fulfilled', value }),
1258 errorCallback: (err) => ({ status: 'rejected', reason: err })
1259 });
1260 }
1261 static allWithCallback(values, callback) {
1262 let resolve;
1263 let reject;
1264 let promise = new this((res, rej) => {
1265 resolve = res;
1266 reject = rej;
1267 });
1268 // Start at 2 to prevent prematurely resolving if .then is called immediately.
1269 let unresolvedCount = 2;
1270 let valueIndex = 0;
1271 const resolvedValues = [];
1272 for (let value of values) {
1273 if (!isThenable(value)) {
1274 value = this.resolve(value);
1275 }
1276 const curValueIndex = valueIndex;
1277 try {
1278 value.then((value) => {
1279 resolvedValues[curValueIndex] = callback ? callback.thenCallback(value) : value;
1280 unresolvedCount--;
1281 if (unresolvedCount === 0) {
1282 resolve(resolvedValues);
1283 }
1284 }, (err) => {
1285 if (!callback) {
1286 reject(err);
1287 }
1288 else {
1289 resolvedValues[curValueIndex] = callback.errorCallback(err);
1290 unresolvedCount--;
1291 if (unresolvedCount === 0) {
1292 resolve(resolvedValues);
1293 }
1294 }
1295 });
1296 }
1297 catch (thenErr) {
1298 reject(thenErr);
1299 }
1300 unresolvedCount++;
1301 valueIndex++;
1302 }
1303 // Make the unresolvedCount zero-based again.
1304 unresolvedCount -= 2;
1305 if (unresolvedCount === 0) {
1306 resolve(resolvedValues);
1307 }
1308 return promise;
1309 }
1310 constructor(executor) {
1311 const promise = this;
1312 if (!(promise instanceof ZoneAwarePromise)) {
1313 throw new Error('Must be an instanceof Promise.');
1314 }
1315 promise[symbolState] = UNRESOLVED;
1316 promise[symbolValue] = []; // queue;
1317 try {
1318 executor && executor(makeResolver(promise, RESOLVED), makeResolver(promise, REJECTED));
1319 }
1320 catch (error) {
1321 resolvePromise(promise, false, error);
1322 }
1323 }
1324 get [Symbol.toStringTag]() {
1325 return 'Promise';
1326 }
1327 get [Symbol.species]() {
1328 return ZoneAwarePromise;
1329 }
1330 then(onFulfilled, onRejected) {
1331 let C = this.constructor[Symbol.species];
1332 if (!C || typeof C !== 'function') {
1333 C = this.constructor || ZoneAwarePromise;
1334 }
1335 const chainPromise = new C(noop);
1336 const zone = Zone.current;
1337 if (this[symbolState] == UNRESOLVED) {
1338 this[symbolValue].push(zone, chainPromise, onFulfilled, onRejected);
1339 }
1340 else {
1341 scheduleResolveOrReject(this, zone, chainPromise, onFulfilled, onRejected);
1342 }
1343 return chainPromise;
1344 }
1345 catch(onRejected) {
1346 return this.then(null, onRejected);
1347 }
1348 finally(onFinally) {
1349 let C = this.constructor[Symbol.species];
1350 if (!C || typeof C !== 'function') {
1351 C = ZoneAwarePromise;
1352 }
1353 const chainPromise = new C(noop);
1354 chainPromise[symbolFinally] = symbolFinally;
1355 const zone = Zone.current;
1356 if (this[symbolState] == UNRESOLVED) {
1357 this[symbolValue].push(zone, chainPromise, onFinally, onFinally);
1358 }
1359 else {
1360 scheduleResolveOrReject(this, zone, chainPromise, onFinally, onFinally);
1361 }
1362 return chainPromise;
1363 }
1364 }
1365 // Protect against aggressive optimizers dropping seemingly unused properties.
1366 // E.g. Closure Compiler in advanced mode.
1367 ZoneAwarePromise['resolve'] = ZoneAwarePromise.resolve;
1368 ZoneAwarePromise['reject'] = ZoneAwarePromise.reject;
1369 ZoneAwarePromise['race'] = ZoneAwarePromise.race;
1370 ZoneAwarePromise['all'] = ZoneAwarePromise.all;
1371 const NativePromise = global[symbolPromise] = global['Promise'];
1372 global['Promise'] = ZoneAwarePromise;
1373 const symbolThenPatched = __symbol__('thenPatched');
1374 function patchThen(Ctor) {
1375 const proto = Ctor.prototype;
1376 const prop = ObjectGetOwnPropertyDescriptor(proto, 'then');
1377 if (prop && (prop.writable === false || !prop.configurable)) {
1378 // check Ctor.prototype.then propertyDescriptor is writable or not
1379 // in meteor env, writable is false, we should ignore such case
1380 return;
1381 }
1382 const originalThen = proto.then;
1383 // Keep a reference to the original method.
1384 proto[symbolThen] = originalThen;
1385 Ctor.prototype.then = function (onResolve, onReject) {
1386 const wrapped = new ZoneAwarePromise((resolve, reject) => {
1387 originalThen.call(this, resolve, reject);
1388 });
1389 return wrapped.then(onResolve, onReject);
1390 };
1391 Ctor[symbolThenPatched] = true;
1392 }
1393 api.patchThen = patchThen;
1394 function zoneify(fn) {
1395 return function (self, args) {
1396 let resultPromise = fn.apply(self, args);
1397 if (resultPromise instanceof ZoneAwarePromise) {
1398 return resultPromise;
1399 }
1400 let ctor = resultPromise.constructor;
1401 if (!ctor[symbolThenPatched]) {
1402 patchThen(ctor);
1403 }
1404 return resultPromise;
1405 };
1406 }
1407 if (NativePromise) {
1408 patchThen(NativePromise);
1409 patchMethod(global, 'fetch', delegate => zoneify(delegate));
1410 }
1411 // This is not part of public API, but it is useful for tests, so we expose it.
1412 Promise[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors;
1413 return ZoneAwarePromise;
1414});
1415
1416/**
1417 * @license
1418 * Copyright Google LLC All Rights Reserved.
1419 *
1420 * Use of this source code is governed by an MIT-style license that can be
1421 * found in the LICENSE file at https://angular.io/license
1422 */
1423// override Function.prototype.toString to make zone.js patched function
1424// look like native function
1425Zone.__load_patch('toString', (global) => {
1426 // patch Func.prototype.toString to let them look like native
1427 const originalFunctionToString = Function.prototype.toString;
1428 const ORIGINAL_DELEGATE_SYMBOL = zoneSymbol('OriginalDelegate');
1429 const PROMISE_SYMBOL = zoneSymbol('Promise');
1430 const ERROR_SYMBOL = zoneSymbol('Error');
1431 const newFunctionToString = function toString() {
1432 if (typeof this === 'function') {
1433 const originalDelegate = this[ORIGINAL_DELEGATE_SYMBOL];
1434 if (originalDelegate) {
1435 if (typeof originalDelegate === 'function') {
1436 return originalFunctionToString.call(originalDelegate);
1437 }
1438 else {
1439 return Object.prototype.toString.call(originalDelegate);
1440 }
1441 }
1442 if (this === Promise) {
1443 const nativePromise = global[PROMISE_SYMBOL];
1444 if (nativePromise) {
1445 return originalFunctionToString.call(nativePromise);
1446 }
1447 }
1448 if (this === Error) {
1449 const nativeError = global[ERROR_SYMBOL];
1450 if (nativeError) {
1451 return originalFunctionToString.call(nativeError);
1452 }
1453 }
1454 }
1455 return originalFunctionToString.call(this);
1456 };
1457 newFunctionToString[ORIGINAL_DELEGATE_SYMBOL] = originalFunctionToString;
1458 Function.prototype.toString = newFunctionToString;
1459 // patch Object.prototype.toString to let them look like native
1460 const originalObjectToString = Object.prototype.toString;
1461 const PROMISE_OBJECT_TO_STRING = '[object Promise]';
1462 Object.prototype.toString = function () {
1463 if (typeof Promise === 'function' && this instanceof Promise) {
1464 return PROMISE_OBJECT_TO_STRING;
1465 }
1466 return originalObjectToString.call(this);
1467 };
1468});
1469
1470/**
1471 * @license
1472 * Copyright Google LLC All Rights Reserved.
1473 *
1474 * Use of this source code is governed by an MIT-style license that can be
1475 * found in the LICENSE file at https://angular.io/license
1476 */
1477Zone.__load_patch('node_util', (global, Zone, api) => {
1478 api.patchOnProperties = patchOnProperties;
1479 api.patchMethod = patchMethod;
1480 api.bindArguments = bindArguments;
1481 api.patchMacroTask = patchMacroTask;
1482 setShouldCopySymbolProperties(true);
1483});
1484
1485/**
1486 * @license
1487 * Copyright Google LLC All Rights Reserved.
1488 *
1489 * Use of this source code is governed by an MIT-style license that can be
1490 * found in the LICENSE file at https://angular.io/license
1491 */
1492let passiveSupported = false;
1493if (typeof window !== 'undefined') {
1494 try {
1495 const options = Object.defineProperty({}, 'passive', {
1496 get: function () {
1497 passiveSupported = true;
1498 }
1499 });
1500 window.addEventListener('test', options, options);
1501 window.removeEventListener('test', options, options);
1502 }
1503 catch (err) {
1504 passiveSupported = false;
1505 }
1506}
1507// an identifier to tell ZoneTask do not create a new invoke closure
1508const OPTIMIZED_ZONE_EVENT_TASK_DATA = {
1509 useG: true
1510};
1511const zoneSymbolEventNames$1 = {};
1512const globalSources = {};
1513const EVENT_NAME_SYMBOL_REGX = new RegExp('^' + ZONE_SYMBOL_PREFIX + '(\\w+)(true|false)$');
1514const IMMEDIATE_PROPAGATION_SYMBOL = zoneSymbol('propagationStopped');
1515function prepareEventNames(eventName, eventNameToString) {
1516 const falseEventName = (eventNameToString ? eventNameToString(eventName) : eventName) + FALSE_STR;
1517 const trueEventName = (eventNameToString ? eventNameToString(eventName) : eventName) + TRUE_STR;
1518 const symbol = ZONE_SYMBOL_PREFIX + falseEventName;
1519 const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName;
1520 zoneSymbolEventNames$1[eventName] = {};
1521 zoneSymbolEventNames$1[eventName][FALSE_STR] = symbol;
1522 zoneSymbolEventNames$1[eventName][TRUE_STR] = symbolCapture;
1523}
1524function patchEventTarget(_global, apis, patchOptions) {
1525 const ADD_EVENT_LISTENER = (patchOptions && patchOptions.add) || ADD_EVENT_LISTENER_STR;
1526 const REMOVE_EVENT_LISTENER = (patchOptions && patchOptions.rm) || REMOVE_EVENT_LISTENER_STR;
1527 const LISTENERS_EVENT_LISTENER = (patchOptions && patchOptions.listeners) || 'eventListeners';
1528 const REMOVE_ALL_LISTENERS_EVENT_LISTENER = (patchOptions && patchOptions.rmAll) || 'removeAllListeners';
1529 const zoneSymbolAddEventListener = zoneSymbol(ADD_EVENT_LISTENER);
1530 const ADD_EVENT_LISTENER_SOURCE = '.' + ADD_EVENT_LISTENER + ':';
1531 const PREPEND_EVENT_LISTENER = 'prependListener';
1532 const PREPEND_EVENT_LISTENER_SOURCE = '.' + PREPEND_EVENT_LISTENER + ':';
1533 const invokeTask = function (task, target, event) {
1534 // for better performance, check isRemoved which is set
1535 // by removeEventListener
1536 if (task.isRemoved) {
1537 return;
1538 }
1539 const delegate = task.callback;
1540 if (typeof delegate === 'object' && delegate.handleEvent) {
1541 // create the bind version of handleEvent when invoke
1542 task.callback = (event) => delegate.handleEvent(event);
1543 task.originalDelegate = delegate;
1544 }
1545 // invoke static task.invoke
1546 task.invoke(task, target, [event]);
1547 const options = task.options;
1548 if (options && typeof options === 'object' && options.once) {
1549 // if options.once is true, after invoke once remove listener here
1550 // only browser need to do this, nodejs eventEmitter will cal removeListener
1551 // inside EventEmitter.once
1552 const delegate = task.originalDelegate ? task.originalDelegate : task.callback;
1553 target[REMOVE_EVENT_LISTENER].call(target, event.type, delegate, options);
1554 }
1555 };
1556 // global shared zoneAwareCallback to handle all event callback with capture = false
1557 const globalZoneAwareCallback = function (event) {
1558 // https://github.com/angular/zone.js/issues/911, in IE, sometimes
1559 // event will be undefined, so we need to use window.event
1560 event = event || _global.event;
1561 if (!event) {
1562 return;
1563 }
1564 // event.target is needed for Samsung TV and SourceBuffer
1565 // || global is needed https://github.com/angular/zone.js/issues/190
1566 const target = this || event.target || _global;
1567 const tasks = target[zoneSymbolEventNames$1[event.type][FALSE_STR]];
1568 if (tasks) {
1569 // invoke all tasks which attached to current target with given event.type and capture = false
1570 // for performance concern, if task.length === 1, just invoke
1571 if (tasks.length === 1) {
1572 invokeTask(tasks[0], target, event);
1573 }
1574 else {
1575 // https://github.com/angular/zone.js/issues/836
1576 // copy the tasks array before invoke, to avoid
1577 // the callback will remove itself or other listener
1578 const copyTasks = tasks.slice();
1579 for (let i = 0; i < copyTasks.length; i++) {
1580 if (event && event[IMMEDIATE_PROPAGATION_SYMBOL] === true) {
1581 break;
1582 }
1583 invokeTask(copyTasks[i], target, event);
1584 }
1585 }
1586 }
1587 };
1588 // global shared zoneAwareCallback to handle all event callback with capture = true
1589 const globalZoneAwareCaptureCallback = function (event) {
1590 // https://github.com/angular/zone.js/issues/911, in IE, sometimes
1591 // event will be undefined, so we need to use window.event
1592 event = event || _global.event;
1593 if (!event) {
1594 return;
1595 }
1596 // event.target is needed for Samsung TV and SourceBuffer
1597 // || global is needed https://github.com/angular/zone.js/issues/190
1598 const target = this || event.target || _global;
1599 const tasks = target[zoneSymbolEventNames$1[event.type][TRUE_STR]];
1600 if (tasks) {
1601 // invoke all tasks which attached to current target with given event.type and capture = false
1602 // for performance concern, if task.length === 1, just invoke
1603 if (tasks.length === 1) {
1604 invokeTask(tasks[0], target, event);
1605 }
1606 else {
1607 // https://github.com/angular/zone.js/issues/836
1608 // copy the tasks array before invoke, to avoid
1609 // the callback will remove itself or other listener
1610 const copyTasks = tasks.slice();
1611 for (let i = 0; i < copyTasks.length; i++) {
1612 if (event && event[IMMEDIATE_PROPAGATION_SYMBOL] === true) {
1613 break;
1614 }
1615 invokeTask(copyTasks[i], target, event);
1616 }
1617 }
1618 }
1619 };
1620 function patchEventTargetMethods(obj, patchOptions) {
1621 if (!obj) {
1622 return false;
1623 }
1624 let useGlobalCallback = true;
1625 if (patchOptions && patchOptions.useG !== undefined) {
1626 useGlobalCallback = patchOptions.useG;
1627 }
1628 const validateHandler = patchOptions && patchOptions.vh;
1629 let checkDuplicate = true;
1630 if (patchOptions && patchOptions.chkDup !== undefined) {
1631 checkDuplicate = patchOptions.chkDup;
1632 }
1633 let returnTarget = false;
1634 if (patchOptions && patchOptions.rt !== undefined) {
1635 returnTarget = patchOptions.rt;
1636 }
1637 let proto = obj;
1638 while (proto && !proto.hasOwnProperty(ADD_EVENT_LISTENER)) {
1639 proto = ObjectGetPrototypeOf(proto);
1640 }
1641 if (!proto && obj[ADD_EVENT_LISTENER]) {
1642 // somehow we did not find it, but we can see it. This happens on IE for Window properties.
1643 proto = obj;
1644 }
1645 if (!proto) {
1646 return false;
1647 }
1648 if (proto[zoneSymbolAddEventListener]) {
1649 return false;
1650 }
1651 const eventNameToString = patchOptions && patchOptions.eventNameToString;
1652 // a shared global taskData to pass data for scheduleEventTask
1653 // so we do not need to create a new object just for pass some data
1654 const taskData = {};
1655 const nativeAddEventListener = proto[zoneSymbolAddEventListener] = proto[ADD_EVENT_LISTENER];
1656 const nativeRemoveEventListener = proto[zoneSymbol(REMOVE_EVENT_LISTENER)] =
1657 proto[REMOVE_EVENT_LISTENER];
1658 const nativeListeners = proto[zoneSymbol(LISTENERS_EVENT_LISTENER)] =
1659 proto[LISTENERS_EVENT_LISTENER];
1660 const nativeRemoveAllListeners = proto[zoneSymbol(REMOVE_ALL_LISTENERS_EVENT_LISTENER)] =
1661 proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER];
1662 let nativePrependEventListener;
1663 if (patchOptions && patchOptions.prepend) {
1664 nativePrependEventListener = proto[zoneSymbol(patchOptions.prepend)] =
1665 proto[patchOptions.prepend];
1666 }
1667 /**
1668 * This util function will build an option object with passive option
1669 * to handle all possible input from the user.
1670 */
1671 function buildEventListenerOptions(options, passive) {
1672 if (!passiveSupported && typeof options === 'object' && options) {
1673 // doesn't support passive but user want to pass an object as options.
1674 // this will not work on some old browser, so we just pass a boolean
1675 // as useCapture parameter
1676 return !!options.capture;
1677 }
1678 if (!passiveSupported || !passive) {
1679 return options;
1680 }
1681 if (typeof options === 'boolean') {
1682 return { capture: options, passive: true };
1683 }
1684 if (!options) {
1685 return { passive: true };
1686 }
1687 if (typeof options === 'object' && options.passive !== false) {
1688 return Object.assign(Object.assign({}, options), { passive: true });
1689 }
1690 return options;
1691 }
1692 const customScheduleGlobal = function (task) {
1693 // if there is already a task for the eventName + capture,
1694 // just return, because we use the shared globalZoneAwareCallback here.
1695 if (taskData.isExisting) {
1696 return;
1697 }
1698 return nativeAddEventListener.call(taskData.target, taskData.eventName, taskData.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback, taskData.options);
1699 };
1700 const customCancelGlobal = function (task) {
1701 // if task is not marked as isRemoved, this call is directly
1702 // from Zone.prototype.cancelTask, we should remove the task
1703 // from tasksList of target first
1704 if (!task.isRemoved) {
1705 const symbolEventNames = zoneSymbolEventNames$1[task.eventName];
1706 let symbolEventName;
1707 if (symbolEventNames) {
1708 symbolEventName = symbolEventNames[task.capture ? TRUE_STR : FALSE_STR];
1709 }
1710 const existingTasks = symbolEventName && task.target[symbolEventName];
1711 if (existingTasks) {
1712 for (let i = 0; i < existingTasks.length; i++) {
1713 const existingTask = existingTasks[i];
1714 if (existingTask === task) {
1715 existingTasks.splice(i, 1);
1716 // set isRemoved to data for faster invokeTask check
1717 task.isRemoved = true;
1718 if (existingTasks.length === 0) {
1719 // all tasks for the eventName + capture have gone,
1720 // remove globalZoneAwareCallback and remove the task cache from target
1721 task.allRemoved = true;
1722 task.target[symbolEventName] = null;
1723 }
1724 break;
1725 }
1726 }
1727 }
1728 }
1729 // if all tasks for the eventName + capture have gone,
1730 // we will really remove the global event callback,
1731 // if not, return
1732 if (!task.allRemoved) {
1733 return;
1734 }
1735 return nativeRemoveEventListener.call(task.target, task.eventName, task.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback, task.options);
1736 };
1737 const customScheduleNonGlobal = function (task) {
1738 return nativeAddEventListener.call(taskData.target, taskData.eventName, task.invoke, taskData.options);
1739 };
1740 const customSchedulePrepend = function (task) {
1741 return nativePrependEventListener.call(taskData.target, taskData.eventName, task.invoke, taskData.options);
1742 };
1743 const customCancelNonGlobal = function (task) {
1744 return nativeRemoveEventListener.call(task.target, task.eventName, task.invoke, task.options);
1745 };
1746 const customSchedule = useGlobalCallback ? customScheduleGlobal : customScheduleNonGlobal;
1747 const customCancel = useGlobalCallback ? customCancelGlobal : customCancelNonGlobal;
1748 const compareTaskCallbackVsDelegate = function (task, delegate) {
1749 const typeOfDelegate = typeof delegate;
1750 return (typeOfDelegate === 'function' && task.callback === delegate) ||
1751 (typeOfDelegate === 'object' && task.originalDelegate === delegate);
1752 };
1753 const compare = (patchOptions && patchOptions.diff) ? patchOptions.diff : compareTaskCallbackVsDelegate;
1754 const unpatchedEvents = Zone[zoneSymbol('UNPATCHED_EVENTS')];
1755 const passiveEvents = _global[zoneSymbol('PASSIVE_EVENTS')];
1756 const makeAddListener = function (nativeListener, addSource, customScheduleFn, customCancelFn, returnTarget = false, prepend = false) {
1757 return function () {
1758 const target = this || _global;
1759 let eventName = arguments[0];
1760 if (patchOptions && patchOptions.transferEventName) {
1761 eventName = patchOptions.transferEventName(eventName);
1762 }
1763 let delegate = arguments[1];
1764 if (!delegate) {
1765 return nativeListener.apply(this, arguments);
1766 }
1767 if (isNode && eventName === 'uncaughtException') {
1768 // don't patch uncaughtException of nodejs to prevent endless loop
1769 return nativeListener.apply(this, arguments);
1770 }
1771 // don't create the bind delegate function for handleEvent
1772 // case here to improve addEventListener performance
1773 // we will create the bind delegate when invoke
1774 let isHandleEvent = false;
1775 if (typeof delegate !== 'function') {
1776 if (!delegate.handleEvent) {
1777 return nativeListener.apply(this, arguments);
1778 }
1779 isHandleEvent = true;
1780 }
1781 if (validateHandler && !validateHandler(nativeListener, delegate, target, arguments)) {
1782 return;
1783 }
1784 const passive = passiveSupported && !!passiveEvents && passiveEvents.indexOf(eventName) !== -1;
1785 const options = buildEventListenerOptions(arguments[2], passive);
1786 if (unpatchedEvents) {
1787 // check upatched list
1788 for (let i = 0; i < unpatchedEvents.length; i++) {
1789 if (eventName === unpatchedEvents[i]) {
1790 if (passive) {
1791 return nativeListener.call(target, eventName, delegate, options);
1792 }
1793 else {
1794 return nativeListener.apply(this, arguments);
1795 }
1796 }
1797 }
1798 }
1799 const capture = !options ? false : typeof options === 'boolean' ? true : options.capture;
1800 const once = options && typeof options === 'object' ? options.once : false;
1801 const zone = Zone.current;
1802 let symbolEventNames = zoneSymbolEventNames$1[eventName];
1803 if (!symbolEventNames) {
1804 prepareEventNames(eventName, eventNameToString);
1805 symbolEventNames = zoneSymbolEventNames$1[eventName];
1806 }
1807 const symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR];
1808 let existingTasks = target[symbolEventName];
1809 let isExisting = false;
1810 if (existingTasks) {
1811 // already have task registered
1812 isExisting = true;
1813 if (checkDuplicate) {
1814 for (let i = 0; i < existingTasks.length; i++) {
1815 if (compare(existingTasks[i], delegate)) {
1816 // same callback, same capture, same event name, just return
1817 return;
1818 }
1819 }
1820 }
1821 }
1822 else {
1823 existingTasks = target[symbolEventName] = [];
1824 }
1825 let source;
1826 const constructorName = target.constructor['name'];
1827 const targetSource = globalSources[constructorName];
1828 if (targetSource) {
1829 source = targetSource[eventName];
1830 }
1831 if (!source) {
1832 source = constructorName + addSource +
1833 (eventNameToString ? eventNameToString(eventName) : eventName);
1834 }
1835 // do not create a new object as task.data to pass those things
1836 // just use the global shared one
1837 taskData.options = options;
1838 if (once) {
1839 // if addEventListener with once options, we don't pass it to
1840 // native addEventListener, instead we keep the once setting
1841 // and handle ourselves.
1842 taskData.options.once = false;
1843 }
1844 taskData.target = target;
1845 taskData.capture = capture;
1846 taskData.eventName = eventName;
1847 taskData.isExisting = isExisting;
1848 const data = useGlobalCallback ? OPTIMIZED_ZONE_EVENT_TASK_DATA : undefined;
1849 // keep taskData into data to allow onScheduleEventTask to access the task information
1850 if (data) {
1851 data.taskData = taskData;
1852 }
1853 const task = zone.scheduleEventTask(source, delegate, data, customScheduleFn, customCancelFn);
1854 // should clear taskData.target to avoid memory leak
1855 // issue, https://github.com/angular/angular/issues/20442
1856 taskData.target = null;
1857 // need to clear up taskData because it is a global object
1858 if (data) {
1859 data.taskData = null;
1860 }
1861 // have to save those information to task in case
1862 // application may call task.zone.cancelTask() directly
1863 if (once) {
1864 options.once = true;
1865 }
1866 if (!(!passiveSupported && typeof task.options === 'boolean')) {
1867 // if not support passive, and we pass an option object
1868 // to addEventListener, we should save the options to task
1869 task.options = options;
1870 }
1871 task.target = target;
1872 task.capture = capture;
1873 task.eventName = eventName;
1874 if (isHandleEvent) {
1875 // save original delegate for compare to check duplicate
1876 task.originalDelegate = delegate;
1877 }
1878 if (!prepend) {
1879 existingTasks.push(task);
1880 }
1881 else {
1882 existingTasks.unshift(task);
1883 }
1884 if (returnTarget) {
1885 return target;
1886 }
1887 };
1888 };
1889 proto[ADD_EVENT_LISTENER] = makeAddListener(nativeAddEventListener, ADD_EVENT_LISTENER_SOURCE, customSchedule, customCancel, returnTarget);
1890 if (nativePrependEventListener) {
1891 proto[PREPEND_EVENT_LISTENER] = makeAddListener(nativePrependEventListener, PREPEND_EVENT_LISTENER_SOURCE, customSchedulePrepend, customCancel, returnTarget, true);
1892 }
1893 proto[REMOVE_EVENT_LISTENER] = function () {
1894 const target = this || _global;
1895 let eventName = arguments[0];
1896 if (patchOptions && patchOptions.transferEventName) {
1897 eventName = patchOptions.transferEventName(eventName);
1898 }
1899 const options = arguments[2];
1900 const capture = !options ? false : typeof options === 'boolean' ? true : options.capture;
1901 const delegate = arguments[1];
1902 if (!delegate) {
1903 return nativeRemoveEventListener.apply(this, arguments);
1904 }
1905 if (validateHandler &&
1906 !validateHandler(nativeRemoveEventListener, delegate, target, arguments)) {
1907 return;
1908 }
1909 const symbolEventNames = zoneSymbolEventNames$1[eventName];
1910 let symbolEventName;
1911 if (symbolEventNames) {
1912 symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR];
1913 }
1914 const existingTasks = symbolEventName && target[symbolEventName];
1915 if (existingTasks) {
1916 for (let i = 0; i < existingTasks.length; i++) {
1917 const existingTask = existingTasks[i];
1918 if (compare(existingTask, delegate)) {
1919 existingTasks.splice(i, 1);
1920 // set isRemoved to data for faster invokeTask check
1921 existingTask.isRemoved = true;
1922 if (existingTasks.length === 0) {
1923 // all tasks for the eventName + capture have gone,
1924 // remove globalZoneAwareCallback and remove the task cache from target
1925 existingTask.allRemoved = true;
1926 target[symbolEventName] = null;
1927 // in the target, we have an event listener which is added by on_property
1928 // such as target.onclick = function() {}, so we need to clear this internal
1929 // property too if all delegates all removed
1930 if (typeof eventName === 'string') {
1931 const onPropertySymbol = ZONE_SYMBOL_PREFIX + 'ON_PROPERTY' + eventName;
1932 target[onPropertySymbol] = null;
1933 }
1934 }
1935 existingTask.zone.cancelTask(existingTask);
1936 if (returnTarget) {
1937 return target;
1938 }
1939 return;
1940 }
1941 }
1942 }
1943 // issue 930, didn't find the event name or callback
1944 // from zone kept existingTasks, the callback maybe
1945 // added outside of zone, we need to call native removeEventListener
1946 // to try to remove it.
1947 return nativeRemoveEventListener.apply(this, arguments);
1948 };
1949 proto[LISTENERS_EVENT_LISTENER] = function () {
1950 const target = this || _global;
1951 let eventName = arguments[0];
1952 if (patchOptions && patchOptions.transferEventName) {
1953 eventName = patchOptions.transferEventName(eventName);
1954 }
1955 const listeners = [];
1956 const tasks = findEventTasks(target, eventNameToString ? eventNameToString(eventName) : eventName);
1957 for (let i = 0; i < tasks.length; i++) {
1958 const task = tasks[i];
1959 let delegate = task.originalDelegate ? task.originalDelegate : task.callback;
1960 listeners.push(delegate);
1961 }
1962 return listeners;
1963 };
1964 proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER] = function () {
1965 const target = this || _global;
1966 let eventName = arguments[0];
1967 if (!eventName) {
1968 const keys = Object.keys(target);
1969 for (let i = 0; i < keys.length; i++) {
1970 const prop = keys[i];
1971 const match = EVENT_NAME_SYMBOL_REGX.exec(prop);
1972 let evtName = match && match[1];
1973 // in nodejs EventEmitter, removeListener event is
1974 // used for monitoring the removeListener call,
1975 // so just keep removeListener eventListener until
1976 // all other eventListeners are removed
1977 if (evtName && evtName !== 'removeListener') {
1978 this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, evtName);
1979 }
1980 }
1981 // remove removeListener listener finally
1982 this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, 'removeListener');
1983 }
1984 else {
1985 if (patchOptions && patchOptions.transferEventName) {
1986 eventName = patchOptions.transferEventName(eventName);
1987 }
1988 const symbolEventNames = zoneSymbolEventNames$1[eventName];
1989 if (symbolEventNames) {
1990 const symbolEventName = symbolEventNames[FALSE_STR];
1991 const symbolCaptureEventName = symbolEventNames[TRUE_STR];
1992 const tasks = target[symbolEventName];
1993 const captureTasks = target[symbolCaptureEventName];
1994 if (tasks) {
1995 const removeTasks = tasks.slice();
1996 for (let i = 0; i < removeTasks.length; i++) {
1997 const task = removeTasks[i];
1998 let delegate = task.originalDelegate ? task.originalDelegate : task.callback;
1999 this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options);
2000 }
2001 }
2002 if (captureTasks) {
2003 const removeTasks = captureTasks.slice();
2004 for (let i = 0; i < removeTasks.length; i++) {
2005 const task = removeTasks[i];
2006 let delegate = task.originalDelegate ? task.originalDelegate : task.callback;
2007 this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options);
2008 }
2009 }
2010 }
2011 }
2012 if (returnTarget) {
2013 return this;
2014 }
2015 };
2016 // for native toString patch
2017 attachOriginToPatched(proto[ADD_EVENT_LISTENER], nativeAddEventListener);
2018 attachOriginToPatched(proto[REMOVE_EVENT_LISTENER], nativeRemoveEventListener);
2019 if (nativeRemoveAllListeners) {
2020 attachOriginToPatched(proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER], nativeRemoveAllListeners);
2021 }
2022 if (nativeListeners) {
2023 attachOriginToPatched(proto[LISTENERS_EVENT_LISTENER], nativeListeners);
2024 }
2025 return true;
2026 }
2027 let results = [];
2028 for (let i = 0; i < apis.length; i++) {
2029 results[i] = patchEventTargetMethods(apis[i], patchOptions);
2030 }
2031 return results;
2032}
2033function findEventTasks(target, eventName) {
2034 if (!eventName) {
2035 const foundTasks = [];
2036 for (let prop in target) {
2037 const match = EVENT_NAME_SYMBOL_REGX.exec(prop);
2038 let evtName = match && match[1];
2039 if (evtName && (!eventName || evtName === eventName)) {
2040 const tasks = target[prop];
2041 if (tasks) {
2042 for (let i = 0; i < tasks.length; i++) {
2043 foundTasks.push(tasks[i]);
2044 }
2045 }
2046 }
2047 }
2048 return foundTasks;
2049 }
2050 let symbolEventName = zoneSymbolEventNames$1[eventName];
2051 if (!symbolEventName) {
2052 prepareEventNames(eventName);
2053 symbolEventName = zoneSymbolEventNames$1[eventName];
2054 }
2055 const captureFalseTasks = target[symbolEventName[FALSE_STR]];
2056 const captureTrueTasks = target[symbolEventName[TRUE_STR]];
2057 if (!captureFalseTasks) {
2058 return captureTrueTasks ? captureTrueTasks.slice() : [];
2059 }
2060 else {
2061 return captureTrueTasks ? captureFalseTasks.concat(captureTrueTasks) :
2062 captureFalseTasks.slice();
2063 }
2064}
2065
2066/**
2067 * @license
2068 * Copyright Google LLC All Rights Reserved.
2069 *
2070 * Use of this source code is governed by an MIT-style license that can be
2071 * found in the LICENSE file at https://angular.io/license
2072 */
2073Zone.__load_patch('EventEmitter', (global) => {
2074 // For EventEmitter
2075 const EE_ADD_LISTENER = 'addListener';
2076 const EE_PREPEND_LISTENER = 'prependListener';
2077 const EE_REMOVE_LISTENER = 'removeListener';
2078 const EE_REMOVE_ALL_LISTENER = 'removeAllListeners';
2079 const EE_LISTENERS = 'listeners';
2080 const EE_ON = 'on';
2081 const EE_OFF = 'off';
2082 const compareTaskCallbackVsDelegate = function (task, delegate) {
2083 // same callback, same capture, same event name, just return
2084 return task.callback === delegate || task.callback.listener === delegate;
2085 };
2086 const eventNameToString = function (eventName) {
2087 if (typeof eventName === 'string') {
2088 return eventName;
2089 }
2090 if (!eventName) {
2091 return '';
2092 }
2093 return eventName.toString().replace('(', '_').replace(')', '_');
2094 };
2095 function patchEventEmitterMethods(obj) {
2096 const result = patchEventTarget(global, [obj], {
2097 useG: false,
2098 add: EE_ADD_LISTENER,
2099 rm: EE_REMOVE_LISTENER,
2100 prepend: EE_PREPEND_LISTENER,
2101 rmAll: EE_REMOVE_ALL_LISTENER,
2102 listeners: EE_LISTENERS,
2103 chkDup: false,
2104 rt: true,
2105 diff: compareTaskCallbackVsDelegate,
2106 eventNameToString: eventNameToString
2107 });
2108 if (result && result[0]) {
2109 obj[EE_ON] = obj[EE_ADD_LISTENER];
2110 obj[EE_OFF] = obj[EE_REMOVE_LISTENER];
2111 }
2112 }
2113 // EventEmitter
2114 let events;
2115 try {
2116 events = require('events');
2117 }
2118 catch (err) {
2119 }
2120 if (events && events.EventEmitter) {
2121 patchEventEmitterMethods(events.EventEmitter.prototype);
2122 }
2123});
2124
2125/**
2126 * @license
2127 * Copyright Google LLC All Rights Reserved.
2128 *
2129 * Use of this source code is governed by an MIT-style license that can be
2130 * found in the LICENSE file at https://angular.io/license
2131 */
2132Zone.__load_patch('fs', () => {
2133 let fs;
2134 try {
2135 fs = require('fs');
2136 }
2137 catch (err) {
2138 }
2139 // watch, watchFile, unwatchFile has been patched
2140 // because EventEmitter has been patched
2141 const TO_PATCH_MACROTASK_METHODS = [
2142 'access', 'appendFile', 'chmod', 'chown', 'close', 'exists', 'fchmod',
2143 'fchown', 'fdatasync', 'fstat', 'fsync', 'ftruncate', 'futimes', 'lchmod',
2144 'lchown', 'link', 'lstat', 'mkdir', 'mkdtemp', 'open', 'read',
2145 'readdir', 'readFile', 'readlink', 'realpath', 'rename', 'rmdir', 'stat',
2146 'symlink', 'truncate', 'unlink', 'utimes', 'write', 'writeFile',
2147 ];
2148 if (fs) {
2149 TO_PATCH_MACROTASK_METHODS.filter(name => !!fs[name] && typeof fs[name] === 'function')
2150 .forEach(name => {
2151 patchMacroTask(fs, name, (self, args) => {
2152 return {
2153 name: 'fs.' + name,
2154 args: args,
2155 cbIdx: args.length > 0 ? args.length - 1 : -1,
2156 target: self
2157 };
2158 });
2159 });
2160 }
2161});
2162
2163/**
2164 * @license
2165 * Copyright Google LLC All Rights Reserved.
2166 *
2167 * Use of this source code is governed by an MIT-style license that can be
2168 * found in the LICENSE file at https://angular.io/license
2169 */
2170const taskSymbol = zoneSymbol('zoneTask');
2171function patchTimer(window, setName, cancelName, nameSuffix) {
2172 let setNative = null;
2173 let clearNative = null;
2174 setName += nameSuffix;
2175 cancelName += nameSuffix;
2176 const tasksByHandleId = {};
2177 function scheduleTask(task) {
2178 const data = task.data;
2179 data.args[0] = function () {
2180 return task.invoke.apply(this, arguments);
2181 };
2182 data.handleId = setNative.apply(window, data.args);
2183 return task;
2184 }
2185 function clearTask(task) {
2186 return clearNative.call(window, task.data.handleId);
2187 }
2188 setNative =
2189 patchMethod(window, setName, (delegate) => function (self, args) {
2190 if (typeof args[0] === 'function') {
2191 const options = {
2192 isPeriodic: nameSuffix === 'Interval',
2193 delay: (nameSuffix === 'Timeout' || nameSuffix === 'Interval') ? args[1] || 0 :
2194 undefined,
2195 args: args
2196 };
2197 const callback = args[0];
2198 args[0] = function timer() {
2199 try {
2200 return callback.apply(this, arguments);
2201 }
2202 finally {
2203 // issue-934, task will be cancelled
2204 // even it is a periodic task such as
2205 // setInterval
2206 // https://github.com/angular/angular/issues/40387
2207 // Cleanup tasksByHandleId should be handled before scheduleTask
2208 // Since some zoneSpec may intercept and doesn't trigger
2209 // scheduleFn(scheduleTask) provided here.
2210 if (!(options.isPeriodic)) {
2211 if (typeof options.handleId === 'number') {
2212 // in non-nodejs env, we remove timerId
2213 // from local cache
2214 delete tasksByHandleId[options.handleId];
2215 }
2216 else if (options.handleId) {
2217 // Node returns complex objects as handleIds
2218 // we remove task reference from timer object
2219 options.handleId[taskSymbol] = null;
2220 }
2221 }
2222 }
2223 };
2224 const task = scheduleMacroTaskWithCurrentZone(setName, args[0], options, scheduleTask, clearTask);
2225 if (!task) {
2226 return task;
2227 }
2228 // Node.js must additionally support the ref and unref functions.
2229 const handle = task.data.handleId;
2230 if (typeof handle === 'number') {
2231 // for non nodejs env, we save handleId: task
2232 // mapping in local cache for clearTimeout
2233 tasksByHandleId[handle] = task;
2234 }
2235 else if (handle) {
2236 // for nodejs env, we save task
2237 // reference in timerId Object for clearTimeout
2238 handle[taskSymbol] = task;
2239 }
2240 // check whether handle is null, because some polyfill or browser
2241 // may return undefined from setTimeout/setInterval/setImmediate/requestAnimationFrame
2242 if (handle && handle.ref && handle.unref && typeof handle.ref === 'function' &&
2243 typeof handle.unref === 'function') {
2244 task.ref = handle.ref.bind(handle);
2245 task.unref = handle.unref.bind(handle);
2246 }
2247 if (typeof handle === 'number' || handle) {
2248 return handle;
2249 }
2250 return task;
2251 }
2252 else {
2253 // cause an error by calling it directly.
2254 return delegate.apply(window, args);
2255 }
2256 });
2257 clearNative =
2258 patchMethod(window, cancelName, (delegate) => function (self, args) {
2259 const id = args[0];
2260 let task;
2261 if (typeof id === 'number') {
2262 // non nodejs env.
2263 task = tasksByHandleId[id];
2264 }
2265 else {
2266 // nodejs env.
2267 task = id && id[taskSymbol];
2268 // other environments.
2269 if (!task) {
2270 task = id;
2271 }
2272 }
2273 if (task && typeof task.type === 'string') {
2274 if (task.state !== 'notScheduled' &&
2275 (task.cancelFn && task.data.isPeriodic || task.runCount === 0)) {
2276 if (typeof id === 'number') {
2277 delete tasksByHandleId[id];
2278 }
2279 else if (id) {
2280 id[taskSymbol] = null;
2281 }
2282 // Do not cancel already canceled functions
2283 task.zone.cancelTask(task);
2284 }
2285 }
2286 else {
2287 // cause an error by calling it directly.
2288 delegate.apply(window, args);
2289 }
2290 });
2291}
2292
2293/**
2294 * @license
2295 * Copyright Google LLC All Rights Reserved.
2296 *
2297 * Use of this source code is governed by an MIT-style license that can be
2298 * found in the LICENSE file at https://angular.io/license
2299 */
2300const set = 'set';
2301const clear = 'clear';
2302Zone.__load_patch('node_timers', (global, Zone) => {
2303 // Timers
2304 let globalUseTimeoutFromTimer = false;
2305 try {
2306 const timers = require('timers');
2307 let globalEqualTimersTimeout = global.setTimeout === timers.setTimeout;
2308 if (!globalEqualTimersTimeout && !isMix) {
2309 // 1. if isMix, then we are in mix environment such as Electron
2310 // we should only patch timers.setTimeout because global.setTimeout
2311 // have been patched
2312 // 2. if global.setTimeout not equal timers.setTimeout, check
2313 // whether global.setTimeout use timers.setTimeout or not
2314 const originSetTimeout = timers.setTimeout;
2315 timers.setTimeout = function () {
2316 globalUseTimeoutFromTimer = true;
2317 return originSetTimeout.apply(this, arguments);
2318 };
2319 const detectTimeout = global.setTimeout(() => { }, 100);
2320 clearTimeout(detectTimeout);
2321 timers.setTimeout = originSetTimeout;
2322 }
2323 patchTimer(timers, set, clear, 'Timeout');
2324 patchTimer(timers, set, clear, 'Interval');
2325 patchTimer(timers, set, clear, 'Immediate');
2326 }
2327 catch (error) {
2328 // timers module not exists, for example, when we using nativeScript
2329 // timers is not available
2330 }
2331 if (isMix) {
2332 // if we are in mix environment, such as Electron,
2333 // the global.setTimeout has already been patched,
2334 // so we just patch timers.setTimeout
2335 return;
2336 }
2337 if (!globalUseTimeoutFromTimer) {
2338 // 1. global setTimeout equals timers setTimeout
2339 // 2. or global don't use timers setTimeout(maybe some other library patch setTimeout)
2340 // 3. or load timers module error happens, we should patch global setTimeout
2341 patchTimer(global, set, clear, 'Timeout');
2342 patchTimer(global, set, clear, 'Interval');
2343 patchTimer(global, set, clear, 'Immediate');
2344 }
2345 else {
2346 // global use timers setTimeout, but not equals
2347 // this happens when use nodejs v0.10.x, global setTimeout will
2348 // use a lazy load version of timers setTimeout
2349 // we should not double patch timer's setTimeout
2350 // so we only store the __symbol__ for consistency
2351 global[Zone.__symbol__('setTimeout')] = global.setTimeout;
2352 global[Zone.__symbol__('setInterval')] = global.setInterval;
2353 global[Zone.__symbol__('setImmediate')] = global.setImmediate;
2354 }
2355});
2356// patch process related methods
2357Zone.__load_patch('nextTick', () => {
2358 // patch nextTick as microTask
2359 patchMicroTask(process, 'nextTick', (self, args) => {
2360 return {
2361 name: 'process.nextTick',
2362 args: args,
2363 cbIdx: (args.length > 0 && typeof args[0] === 'function') ? 0 : -1,
2364 target: process
2365 };
2366 });
2367});
2368Zone.__load_patch('handleUnhandledPromiseRejection', (global, Zone, api) => {
2369 Zone[api.symbol('unhandledPromiseRejectionHandler')] =
2370 findProcessPromiseRejectionHandler('unhandledRejection');
2371 Zone[api.symbol('rejectionHandledHandler')] =
2372 findProcessPromiseRejectionHandler('rejectionHandled');
2373 // handle unhandled promise rejection
2374 function findProcessPromiseRejectionHandler(evtName) {
2375 return function (e) {
2376 const eventTasks = findEventTasks(process, evtName);
2377 eventTasks.forEach(eventTask => {
2378 // process has added unhandledrejection event listener
2379 // trigger the event listener
2380 if (evtName === 'unhandledRejection') {
2381 eventTask.invoke(e.rejection, e.promise);
2382 }
2383 else if (evtName === 'rejectionHandled') {
2384 eventTask.invoke(e.promise);
2385 }
2386 });
2387 };
2388 }
2389});
2390// Crypto
2391Zone.__load_patch('crypto', () => {
2392 let crypto;
2393 try {
2394 crypto = require('crypto');
2395 }
2396 catch (err) {
2397 }
2398 // use the generic patchMacroTask to patch crypto
2399 if (crypto) {
2400 const methodNames = ['randomBytes', 'pbkdf2'];
2401 methodNames.forEach(name => {
2402 patchMacroTask(crypto, name, (self, args) => {
2403 return {
2404 name: 'crypto.' + name,
2405 args: args,
2406 cbIdx: (args.length > 0 && typeof args[args.length - 1] === 'function') ?
2407 args.length - 1 :
2408 -1,
2409 target: crypto
2410 };
2411 });
2412 });
2413 }
2414});
2415Zone.__load_patch('console', (global, Zone) => {
2416 const consoleMethods = ['dir', 'log', 'info', 'error', 'warn', 'assert', 'debug', 'timeEnd', 'trace'];
2417 consoleMethods.forEach((m) => {
2418 const originalMethod = console[Zone.__symbol__(m)] = console[m];
2419 if (originalMethod) {
2420 console[m] = function () {
2421 const args = ArraySlice.call(arguments);
2422 if (Zone.current === Zone.root) {
2423 return originalMethod.apply(this, args);
2424 }
2425 else {
2426 return Zone.root.run(originalMethod, this, args);
2427 }
2428 };
2429 }
2430 });
2431});
2432
2433/**
2434 * @license
2435 * Copyright Google LLC All Rights Reserved.
2436 *
2437 * Use of this source code is governed by an MIT-style license that can be
2438 * found in the LICENSE file at https://angular.io/license
2439 */
2440/**
2441 * @fileoverview
2442 * @suppress {globalThis}
2443 */
2444const NEWLINE = '\n';
2445const IGNORE_FRAMES = {};
2446const creationTrace = '__creationTrace__';
2447const ERROR_TAG = 'STACKTRACE TRACKING';
2448const SEP_TAG = '__SEP_TAG__';
2449let sepTemplate = SEP_TAG + '@[native]';
2450class LongStackTrace {
2451 constructor() {
2452 this.error = getStacktrace();
2453 this.timestamp = new Date();
2454 }
2455}
2456function getStacktraceWithUncaughtError() {
2457 return new Error(ERROR_TAG);
2458}
2459function getStacktraceWithCaughtError() {
2460 try {
2461 throw getStacktraceWithUncaughtError();
2462 }
2463 catch (err) {
2464 return err;
2465 }
2466}
2467// Some implementations of exception handling don't create a stack trace if the exception
2468// isn't thrown, however it's faster not to actually throw the exception.
2469const error = getStacktraceWithUncaughtError();
2470const caughtError = getStacktraceWithCaughtError();
2471const getStacktrace = error.stack ?
2472 getStacktraceWithUncaughtError :
2473 (caughtError.stack ? getStacktraceWithCaughtError : getStacktraceWithUncaughtError);
2474function getFrames(error) {
2475 return error.stack ? error.stack.split(NEWLINE) : [];
2476}
2477function addErrorStack(lines, error) {
2478 let trace = getFrames(error);
2479 for (let i = 0; i < trace.length; i++) {
2480 const frame = trace[i];
2481 // Filter out the Frames which are part of stack capturing.
2482 if (!IGNORE_FRAMES.hasOwnProperty(frame)) {
2483 lines.push(trace[i]);
2484 }
2485 }
2486}
2487function renderLongStackTrace(frames, stack) {
2488 const longTrace = [stack ? stack.trim() : ''];
2489 if (frames) {
2490 let timestamp = new Date().getTime();
2491 for (let i = 0; i < frames.length; i++) {
2492 const traceFrames = frames[i];
2493 const lastTime = traceFrames.timestamp;
2494 let separator = `____________________Elapsed ${timestamp - lastTime.getTime()} ms; At: ${lastTime}`;
2495 separator = separator.replace(/[^\w\d]/g, '_');
2496 longTrace.push(sepTemplate.replace(SEP_TAG, separator));
2497 addErrorStack(longTrace, traceFrames.error);
2498 timestamp = lastTime.getTime();
2499 }
2500 }
2501 return longTrace.join(NEWLINE);
2502}
2503// if Error.stackTraceLimit is 0, means stack trace
2504// is disabled, so we don't need to generate long stack trace
2505// this will improve performance in some test(some test will
2506// set stackTraceLimit to 0, https://github.com/angular/zone.js/issues/698
2507function stackTracesEnabled() {
2508 // Cast through any since this property only exists on Error in the nodejs
2509 // typings.
2510 return Error.stackTraceLimit > 0;
2511}
2512Zone['longStackTraceZoneSpec'] = {
2513 name: 'long-stack-trace',
2514 longStackTraceLimit: 10,
2515 // add a getLongStackTrace method in spec to
2516 // handle handled reject promise error.
2517 getLongStackTrace: function (error) {
2518 if (!error) {
2519 return undefined;
2520 }
2521 const trace = error[Zone.__symbol__('currentTaskTrace')];
2522 if (!trace) {
2523 return error.stack;
2524 }
2525 return renderLongStackTrace(trace, error.stack);
2526 },
2527 onScheduleTask: function (parentZoneDelegate, currentZone, targetZone, task) {
2528 if (stackTracesEnabled()) {
2529 const currentTask = Zone.currentTask;
2530 let trace = currentTask && currentTask.data && currentTask.data[creationTrace] || [];
2531 trace = [new LongStackTrace()].concat(trace);
2532 if (trace.length > this.longStackTraceLimit) {
2533 trace.length = this.longStackTraceLimit;
2534 }
2535 if (!task.data)
2536 task.data = {};
2537 if (task.type === 'eventTask') {
2538 // Fix issue https://github.com/angular/zone.js/issues/1195,
2539 // For event task of browser, by default, all task will share a
2540 // singleton instance of data object, we should create a new one here
2541 // The cast to `any` is required to workaround a closure bug which wrongly applies
2542 // URL sanitization rules to .data access.
2543 task.data = Object.assign({}, task.data);
2544 }
2545 task.data[creationTrace] = trace;
2546 }
2547 return parentZoneDelegate.scheduleTask(targetZone, task);
2548 },
2549 onHandleError: function (parentZoneDelegate, currentZone, targetZone, error) {
2550 if (stackTracesEnabled()) {
2551 const parentTask = Zone.currentTask || error.task;
2552 if (error instanceof Error && parentTask) {
2553 const longStack = renderLongStackTrace(parentTask.data && parentTask.data[creationTrace], error.stack);
2554 try {
2555 error.stack = error.longStack = longStack;
2556 }
2557 catch (err) {
2558 }
2559 }
2560 }
2561 return parentZoneDelegate.handleError(targetZone, error);
2562 }
2563};
2564function captureStackTraces(stackTraces, count) {
2565 if (count > 0) {
2566 stackTraces.push(getFrames((new LongStackTrace()).error));
2567 captureStackTraces(stackTraces, count - 1);
2568 }
2569}
2570function computeIgnoreFrames() {
2571 if (!stackTracesEnabled()) {
2572 return;
2573 }
2574 const frames = [];
2575 captureStackTraces(frames, 2);
2576 const frames1 = frames[0];
2577 const frames2 = frames[1];
2578 for (let i = 0; i < frames1.length; i++) {
2579 const frame1 = frames1[i];
2580 if (frame1.indexOf(ERROR_TAG) == -1) {
2581 let match = frame1.match(/^\s*at\s+/);
2582 if (match) {
2583 sepTemplate = match[0] + SEP_TAG + ' (http://localhost)';
2584 break;
2585 }
2586 }
2587 }
2588 for (let i = 0; i < frames1.length; i++) {
2589 const frame1 = frames1[i];
2590 const frame2 = frames2[i];
2591 if (frame1 === frame2) {
2592 IGNORE_FRAMES[frame1] = true;
2593 }
2594 else {
2595 break;
2596 }
2597 }
2598}
2599computeIgnoreFrames();
2600
2601/**
2602 * @license
2603 * Copyright Google LLC All Rights Reserved.
2604 *
2605 * Use of this source code is governed by an MIT-style license that can be
2606 * found in the LICENSE file at https://angular.io/license
2607 */
2608class ProxyZoneSpec {
2609 constructor(defaultSpecDelegate = null) {
2610 this.defaultSpecDelegate = defaultSpecDelegate;
2611 this.name = 'ProxyZone';
2612 this._delegateSpec = null;
2613 this.properties = { 'ProxyZoneSpec': this };
2614 this.propertyKeys = null;
2615 this.lastTaskState = null;
2616 this.isNeedToTriggerHasTask = false;
2617 this.tasks = [];
2618 this.setDelegate(defaultSpecDelegate);
2619 }
2620 static get() {
2621 return Zone.current.get('ProxyZoneSpec');
2622 }
2623 static isLoaded() {
2624 return ProxyZoneSpec.get() instanceof ProxyZoneSpec;
2625 }
2626 static assertPresent() {
2627 if (!ProxyZoneSpec.isLoaded()) {
2628 throw new Error(`Expected to be running in 'ProxyZone', but it was not found.`);
2629 }
2630 return ProxyZoneSpec.get();
2631 }
2632 setDelegate(delegateSpec) {
2633 const isNewDelegate = this._delegateSpec !== delegateSpec;
2634 this._delegateSpec = delegateSpec;
2635 this.propertyKeys && this.propertyKeys.forEach((key) => delete this.properties[key]);
2636 this.propertyKeys = null;
2637 if (delegateSpec && delegateSpec.properties) {
2638 this.propertyKeys = Object.keys(delegateSpec.properties);
2639 this.propertyKeys.forEach((k) => this.properties[k] = delegateSpec.properties[k]);
2640 }
2641 // if a new delegateSpec was set, check if we need to trigger hasTask
2642 if (isNewDelegate && this.lastTaskState &&
2643 (this.lastTaskState.macroTask || this.lastTaskState.microTask)) {
2644 this.isNeedToTriggerHasTask = true;
2645 }
2646 }
2647 getDelegate() {
2648 return this._delegateSpec;
2649 }
2650 resetDelegate() {
2651 const delegateSpec = this.getDelegate();
2652 this.setDelegate(this.defaultSpecDelegate);
2653 }
2654 tryTriggerHasTask(parentZoneDelegate, currentZone, targetZone) {
2655 if (this.isNeedToTriggerHasTask && this.lastTaskState) {
2656 // last delegateSpec has microTask or macroTask
2657 // should call onHasTask in current delegateSpec
2658 this.isNeedToTriggerHasTask = false;
2659 this.onHasTask(parentZoneDelegate, currentZone, targetZone, this.lastTaskState);
2660 }
2661 }
2662 removeFromTasks(task) {
2663 if (!this.tasks) {
2664 return;
2665 }
2666 for (let i = 0; i < this.tasks.length; i++) {
2667 if (this.tasks[i] === task) {
2668 this.tasks.splice(i, 1);
2669 return;
2670 }
2671 }
2672 }
2673 getAndClearPendingTasksInfo() {
2674 if (this.tasks.length === 0) {
2675 return '';
2676 }
2677 const taskInfo = this.tasks.map((task) => {
2678 const dataInfo = task.data &&
2679 Object.keys(task.data)
2680 .map((key) => {
2681 return key + ':' + task.data[key];
2682 })
2683 .join(',');
2684 return `type: ${task.type}, source: ${task.source}, args: {${dataInfo}}`;
2685 });
2686 const pendingTasksInfo = '--Pending async tasks are: [' + taskInfo + ']';
2687 // clear tasks
2688 this.tasks = [];
2689 return pendingTasksInfo;
2690 }
2691 onFork(parentZoneDelegate, currentZone, targetZone, zoneSpec) {
2692 if (this._delegateSpec && this._delegateSpec.onFork) {
2693 return this._delegateSpec.onFork(parentZoneDelegate, currentZone, targetZone, zoneSpec);
2694 }
2695 else {
2696 return parentZoneDelegate.fork(targetZone, zoneSpec);
2697 }
2698 }
2699 onIntercept(parentZoneDelegate, currentZone, targetZone, delegate, source) {
2700 if (this._delegateSpec && this._delegateSpec.onIntercept) {
2701 return this._delegateSpec.onIntercept(parentZoneDelegate, currentZone, targetZone, delegate, source);
2702 }
2703 else {
2704 return parentZoneDelegate.intercept(targetZone, delegate, source);
2705 }
2706 }
2707 onInvoke(parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) {
2708 this.tryTriggerHasTask(parentZoneDelegate, currentZone, targetZone);
2709 if (this._delegateSpec && this._delegateSpec.onInvoke) {
2710 return this._delegateSpec.onInvoke(parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source);
2711 }
2712 else {
2713 return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source);
2714 }
2715 }
2716 onHandleError(parentZoneDelegate, currentZone, targetZone, error) {
2717 if (this._delegateSpec && this._delegateSpec.onHandleError) {
2718 return this._delegateSpec.onHandleError(parentZoneDelegate, currentZone, targetZone, error);
2719 }
2720 else {
2721 return parentZoneDelegate.handleError(targetZone, error);
2722 }
2723 }
2724 onScheduleTask(parentZoneDelegate, currentZone, targetZone, task) {
2725 if (task.type !== 'eventTask') {
2726 this.tasks.push(task);
2727 }
2728 if (this._delegateSpec && this._delegateSpec.onScheduleTask) {
2729 return this._delegateSpec.onScheduleTask(parentZoneDelegate, currentZone, targetZone, task);
2730 }
2731 else {
2732 return parentZoneDelegate.scheduleTask(targetZone, task);
2733 }
2734 }
2735 onInvokeTask(parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs) {
2736 if (task.type !== 'eventTask') {
2737 this.removeFromTasks(task);
2738 }
2739 this.tryTriggerHasTask(parentZoneDelegate, currentZone, targetZone);
2740 if (this._delegateSpec && this._delegateSpec.onInvokeTask) {
2741 return this._delegateSpec.onInvokeTask(parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs);
2742 }
2743 else {
2744 return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs);
2745 }
2746 }
2747 onCancelTask(parentZoneDelegate, currentZone, targetZone, task) {
2748 if (task.type !== 'eventTask') {
2749 this.removeFromTasks(task);
2750 }
2751 this.tryTriggerHasTask(parentZoneDelegate, currentZone, targetZone);
2752 if (this._delegateSpec && this._delegateSpec.onCancelTask) {
2753 return this._delegateSpec.onCancelTask(parentZoneDelegate, currentZone, targetZone, task);
2754 }
2755 else {
2756 return parentZoneDelegate.cancelTask(targetZone, task);
2757 }
2758 }
2759 onHasTask(delegate, current, target, hasTaskState) {
2760 this.lastTaskState = hasTaskState;
2761 if (this._delegateSpec && this._delegateSpec.onHasTask) {
2762 this._delegateSpec.onHasTask(delegate, current, target, hasTaskState);
2763 }
2764 else {
2765 delegate.hasTask(target, hasTaskState);
2766 }
2767 }
2768}
2769// Export the class so that new instances can be created with proper
2770// constructor params.
2771Zone['ProxyZoneSpec'] = ProxyZoneSpec;
2772
2773/**
2774 * @license
2775 * Copyright Google LLC All Rights Reserved.
2776 *
2777 * Use of this source code is governed by an MIT-style license that can be
2778 * found in the LICENSE file at https://angular.io/license
2779 */
2780class SyncTestZoneSpec {
2781 constructor(namePrefix) {
2782 this.runZone = Zone.current;
2783 this.name = 'syncTestZone for ' + namePrefix;
2784 }
2785 onScheduleTask(delegate, current, target, task) {
2786 switch (task.type) {
2787 case 'microTask':
2788 case 'macroTask':
2789 throw new Error(`Cannot call ${task.source} from within a sync test.`);
2790 case 'eventTask':
2791 task = delegate.scheduleTask(target, task);
2792 break;
2793 }
2794 return task;
2795 }
2796}
2797// Export the class so that new instances can be created with proper
2798// constructor params.
2799Zone['SyncTestZoneSpec'] = SyncTestZoneSpec;
2800
2801/**
2802 * @license
2803 * Copyright Google LLC All Rights Reserved.
2804 *
2805 * Use of this source code is governed by an MIT-style license that can be
2806 * found in the LICENSE file at https://angular.io/license
2807 */
2808Zone.__load_patch('jasmine', (global, Zone, api) => {
2809 const __extends = function (d, b) {
2810 for (const p in b)
2811 if (b.hasOwnProperty(p))
2812 d[p] = b[p];
2813 function __() {
2814 this.constructor = d;
2815 }
2816 d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new __());
2817 };
2818 // Patch jasmine's describe/it/beforeEach/afterEach functions so test code always runs
2819 // in a testZone (ProxyZone). (See: angular/zone.js#91 & angular/angular#10503)
2820 if (!Zone)
2821 throw new Error('Missing: zone.js');
2822 if (typeof jest !== 'undefined') {
2823 // return if jasmine is a light implementation inside jest
2824 // in this case, we are running inside jest not jasmine
2825 return;
2826 }
2827 if (typeof jasmine == 'undefined' || jasmine['__zone_patch__']) {
2828 return;
2829 }
2830 jasmine['__zone_patch__'] = true;
2831 const SyncTestZoneSpec = Zone['SyncTestZoneSpec'];
2832 const ProxyZoneSpec = Zone['ProxyZoneSpec'];
2833 if (!SyncTestZoneSpec)
2834 throw new Error('Missing: SyncTestZoneSpec');
2835 if (!ProxyZoneSpec)
2836 throw new Error('Missing: ProxyZoneSpec');
2837 const ambientZone = Zone.current;
2838 // Create a synchronous-only zone in which to run `describe` blocks in order to raise an
2839 // error if any asynchronous operations are attempted inside of a `describe` but outside of
2840 // a `beforeEach` or `it`.
2841 const syncZone = ambientZone.fork(new SyncTestZoneSpec('jasmine.describe'));
2842 const symbol = Zone.__symbol__;
2843 // whether patch jasmine clock when in fakeAsync
2844 const disablePatchingJasmineClock = global[symbol('fakeAsyncDisablePatchingClock')] === true;
2845 // the original variable name fakeAsyncPatchLock is not accurate, so the name will be
2846 // fakeAsyncAutoFakeAsyncWhenClockPatched and if this enablePatchingJasmineClock is false, we also
2847 // automatically disable the auto jump into fakeAsync feature
2848 const enableAutoFakeAsyncWhenClockPatched = !disablePatchingJasmineClock &&
2849 ((global[symbol('fakeAsyncPatchLock')] === true) ||
2850 (global[symbol('fakeAsyncAutoFakeAsyncWhenClockPatched')] === true));
2851 const ignoreUnhandledRejection = global[symbol('ignoreUnhandledRejection')] === true;
2852 if (!ignoreUnhandledRejection) {
2853 const globalErrors = jasmine.GlobalErrors;
2854 if (globalErrors && !jasmine[symbol('GlobalErrors')]) {
2855 jasmine[symbol('GlobalErrors')] = globalErrors;
2856 jasmine.GlobalErrors = function () {
2857 const instance = new globalErrors();
2858 const originalInstall = instance.install;
2859 if (originalInstall && !instance[symbol('install')]) {
2860 instance[symbol('install')] = originalInstall;
2861 instance.install = function () {
2862 const originalHandlers = process.listeners('unhandledRejection');
2863 const r = originalInstall.apply(this, arguments);
2864 process.removeAllListeners('unhandledRejection');
2865 if (originalHandlers) {
2866 originalHandlers.forEach(h => process.on('unhandledRejection', h));
2867 }
2868 return r;
2869 };
2870 }
2871 return instance;
2872 };
2873 }
2874 }
2875 // Monkey patch all of the jasmine DSL so that each function runs in appropriate zone.
2876 const jasmineEnv = jasmine.getEnv();
2877 ['describe', 'xdescribe', 'fdescribe'].forEach(methodName => {
2878 let originalJasmineFn = jasmineEnv[methodName];
2879 jasmineEnv[methodName] = function (description, specDefinitions) {
2880 return originalJasmineFn.call(this, description, wrapDescribeInZone(specDefinitions));
2881 };
2882 });
2883 ['it', 'xit', 'fit'].forEach(methodName => {
2884 let originalJasmineFn = jasmineEnv[methodName];
2885 jasmineEnv[symbol(methodName)] = originalJasmineFn;
2886 jasmineEnv[methodName] = function (description, specDefinitions, timeout) {
2887 arguments[1] = wrapTestInZone(specDefinitions);
2888 return originalJasmineFn.apply(this, arguments);
2889 };
2890 });
2891 ['beforeEach', 'afterEach', 'beforeAll', 'afterAll'].forEach(methodName => {
2892 let originalJasmineFn = jasmineEnv[methodName];
2893 jasmineEnv[symbol(methodName)] = originalJasmineFn;
2894 jasmineEnv[methodName] = function (specDefinitions, timeout) {
2895 arguments[0] = wrapTestInZone(specDefinitions);
2896 return originalJasmineFn.apply(this, arguments);
2897 };
2898 });
2899 if (!disablePatchingJasmineClock) {
2900 // need to patch jasmine.clock().mockDate and jasmine.clock().tick() so
2901 // they can work properly in FakeAsyncTest
2902 const originalClockFn = (jasmine[symbol('clock')] = jasmine['clock']);
2903 jasmine['clock'] = function () {
2904 const clock = originalClockFn.apply(this, arguments);
2905 if (!clock[symbol('patched')]) {
2906 clock[symbol('patched')] = symbol('patched');
2907 const originalTick = (clock[symbol('tick')] = clock.tick);
2908 clock.tick = function () {
2909 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
2910 if (fakeAsyncZoneSpec) {
2911 return fakeAsyncZoneSpec.tick.apply(fakeAsyncZoneSpec, arguments);
2912 }
2913 return originalTick.apply(this, arguments);
2914 };
2915 const originalMockDate = (clock[symbol('mockDate')] = clock.mockDate);
2916 clock.mockDate = function () {
2917 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
2918 if (fakeAsyncZoneSpec) {
2919 const dateTime = arguments.length > 0 ? arguments[0] : new Date();
2920 return fakeAsyncZoneSpec.setFakeBaseSystemTime.apply(fakeAsyncZoneSpec, dateTime && typeof dateTime.getTime === 'function' ? [dateTime.getTime()] :
2921 arguments);
2922 }
2923 return originalMockDate.apply(this, arguments);
2924 };
2925 // for auto go into fakeAsync feature, we need the flag to enable it
2926 if (enableAutoFakeAsyncWhenClockPatched) {
2927 ['install', 'uninstall'].forEach(methodName => {
2928 const originalClockFn = (clock[symbol(methodName)] = clock[methodName]);
2929 clock[methodName] = function () {
2930 const FakeAsyncTestZoneSpec = Zone['FakeAsyncTestZoneSpec'];
2931 if (FakeAsyncTestZoneSpec) {
2932 jasmine[symbol('clockInstalled')] = 'install' === methodName;
2933 return;
2934 }
2935 return originalClockFn.apply(this, arguments);
2936 };
2937 });
2938 }
2939 }
2940 return clock;
2941 };
2942 }
2943 // monkey patch createSpyObj to make properties enumerable to true
2944 if (!jasmine[Zone.__symbol__('createSpyObj')]) {
2945 const originalCreateSpyObj = jasmine.createSpyObj;
2946 jasmine[Zone.__symbol__('createSpyObj')] = originalCreateSpyObj;
2947 jasmine.createSpyObj = function () {
2948 const args = Array.prototype.slice.call(arguments);
2949 const propertyNames = args.length >= 3 ? args[2] : null;
2950 let spyObj;
2951 if (propertyNames) {
2952 const defineProperty = Object.defineProperty;
2953 Object.defineProperty = function (obj, p, attributes) {
2954 return defineProperty.call(this, obj, p, Object.assign(Object.assign({}, attributes), { configurable: true, enumerable: true }));
2955 };
2956 try {
2957 spyObj = originalCreateSpyObj.apply(this, args);
2958 }
2959 finally {
2960 Object.defineProperty = defineProperty;
2961 }
2962 }
2963 else {
2964 spyObj = originalCreateSpyObj.apply(this, args);
2965 }
2966 return spyObj;
2967 };
2968 }
2969 /**
2970 * Gets a function wrapping the body of a Jasmine `describe` block to execute in a
2971 * synchronous-only zone.
2972 */
2973 function wrapDescribeInZone(describeBody) {
2974 return function () {
2975 return syncZone.run(describeBody, this, arguments);
2976 };
2977 }
2978 function runInTestZone(testBody, applyThis, queueRunner, done) {
2979 const isClockInstalled = !!jasmine[symbol('clockInstalled')];
2980 const testProxyZoneSpec = queueRunner.testProxyZoneSpec;
2981 const testProxyZone = queueRunner.testProxyZone;
2982 if (isClockInstalled && enableAutoFakeAsyncWhenClockPatched) {
2983 // auto run a fakeAsync
2984 const fakeAsyncModule = Zone[Zone.__symbol__('fakeAsyncTest')];
2985 if (fakeAsyncModule && typeof fakeAsyncModule.fakeAsync === 'function') {
2986 testBody = fakeAsyncModule.fakeAsync(testBody);
2987 }
2988 }
2989 if (done) {
2990 return testProxyZone.run(testBody, applyThis, [done]);
2991 }
2992 else {
2993 return testProxyZone.run(testBody, applyThis);
2994 }
2995 }
2996 /**
2997 * Gets a function wrapping the body of a Jasmine `it/beforeEach/afterEach` block to
2998 * execute in a ProxyZone zone.
2999 * This will run in `testProxyZone`. The `testProxyZone` will be reset by the `ZoneQueueRunner`
3000 */
3001 function wrapTestInZone(testBody) {
3002 // The `done` callback is only passed through if the function expects at least one argument.
3003 // Note we have to make a function with correct number of arguments, otherwise jasmine will
3004 // think that all functions are sync or async.
3005 return (testBody && (testBody.length ? function (done) {
3006 return runInTestZone(testBody, this, this.queueRunner, done);
3007 } : function () {
3008 return runInTestZone(testBody, this, this.queueRunner);
3009 }));
3010 }
3011 const QueueRunner = jasmine.QueueRunner;
3012 jasmine.QueueRunner = (function (_super) {
3013 __extends(ZoneQueueRunner, _super);
3014 function ZoneQueueRunner(attrs) {
3015 if (attrs.onComplete) {
3016 attrs.onComplete = (fn => () => {
3017 // All functions are done, clear the test zone.
3018 this.testProxyZone = null;
3019 this.testProxyZoneSpec = null;
3020 ambientZone.scheduleMicroTask('jasmine.onComplete', fn);
3021 })(attrs.onComplete);
3022 }
3023 const nativeSetTimeout = global[Zone.__symbol__('setTimeout')];
3024 const nativeClearTimeout = global[Zone.__symbol__('clearTimeout')];
3025 if (nativeSetTimeout) {
3026 // should run setTimeout inside jasmine outside of zone
3027 attrs.timeout = {
3028 setTimeout: nativeSetTimeout ? nativeSetTimeout : global.setTimeout,
3029 clearTimeout: nativeClearTimeout ? nativeClearTimeout : global.clearTimeout
3030 };
3031 }
3032 // create a userContext to hold the queueRunner itself
3033 // so we can access the testProxy in it/xit/beforeEach ...
3034 if (jasmine.UserContext) {
3035 if (!attrs.userContext) {
3036 attrs.userContext = new jasmine.UserContext();
3037 }
3038 attrs.userContext.queueRunner = this;
3039 }
3040 else {
3041 if (!attrs.userContext) {
3042 attrs.userContext = {};
3043 }
3044 attrs.userContext.queueRunner = this;
3045 }
3046 // patch attrs.onException
3047 const onException = attrs.onException;
3048 attrs.onException = function (error) {
3049 if (error &&
3050 error.message ===
3051 'Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.') {
3052 // jasmine timeout, we can make the error message more
3053 // reasonable to tell what tasks are pending
3054 const proxyZoneSpec = this && this.testProxyZoneSpec;
3055 if (proxyZoneSpec) {
3056 const pendingTasksInfo = proxyZoneSpec.getAndClearPendingTasksInfo();
3057 try {
3058 // try catch here in case error.message is not writable
3059 error.message += pendingTasksInfo;
3060 }
3061 catch (err) {
3062 }
3063 }
3064 }
3065 if (onException) {
3066 onException.call(this, error);
3067 }
3068 };
3069 _super.call(this, attrs);
3070 }
3071 ZoneQueueRunner.prototype.execute = function () {
3072 let zone = Zone.current;
3073 let isChildOfAmbientZone = false;
3074 while (zone) {
3075 if (zone === ambientZone) {
3076 isChildOfAmbientZone = true;
3077 break;
3078 }
3079 zone = zone.parent;
3080 }
3081 if (!isChildOfAmbientZone)
3082 throw new Error('Unexpected Zone: ' + Zone.current.name);
3083 // This is the zone which will be used for running individual tests.
3084 // It will be a proxy zone, so that the tests function can retroactively install
3085 // different zones.
3086 // Example:
3087 // - In beforeEach() do childZone = Zone.current.fork(...);
3088 // - In it() try to do fakeAsync(). The issue is that because the beforeEach forked the
3089 // zone outside of fakeAsync it will be able to escape the fakeAsync rules.
3090 // - Because ProxyZone is parent fo `childZone` fakeAsync can retroactively add
3091 // fakeAsync behavior to the childZone.
3092 this.testProxyZoneSpec = new ProxyZoneSpec();
3093 this.testProxyZone = ambientZone.fork(this.testProxyZoneSpec);
3094 if (!Zone.currentTask) {
3095 // if we are not running in a task then if someone would register a
3096 // element.addEventListener and then calling element.click() the
3097 // addEventListener callback would think that it is the top most task and would
3098 // drain the microtask queue on element.click() which would be incorrect.
3099 // For this reason we always force a task when running jasmine tests.
3100 Zone.current.scheduleMicroTask('jasmine.execute().forceTask', () => QueueRunner.prototype.execute.call(this));
3101 }
3102 else {
3103 _super.prototype.execute.call(this);
3104 }
3105 };
3106 return ZoneQueueRunner;
3107 })(QueueRunner);
3108});
3109
3110/**
3111 * @license
3112 * Copyright Google LLC All Rights Reserved.
3113 *
3114 * Use of this source code is governed by an MIT-style license that can be
3115 * found in the LICENSE file at https://angular.io/license
3116 */
3117Zone.__load_patch('jest', (context, Zone, api) => {
3118 if (typeof jest === 'undefined' || jest['__zone_patch__']) {
3119 return;
3120 }
3121 jest['__zone_patch__'] = true;
3122 const ProxyZoneSpec = Zone['ProxyZoneSpec'];
3123 const SyncTestZoneSpec = Zone['SyncTestZoneSpec'];
3124 if (!ProxyZoneSpec) {
3125 throw new Error('Missing ProxyZoneSpec');
3126 }
3127 const rootZone = Zone.current;
3128 const syncZone = rootZone.fork(new SyncTestZoneSpec('jest.describe'));
3129 const proxyZoneSpec = new ProxyZoneSpec();
3130 const proxyZone = rootZone.fork(proxyZoneSpec);
3131 function wrapDescribeFactoryInZone(originalJestFn) {
3132 return function (...tableArgs) {
3133 const originalDescribeFn = originalJestFn.apply(this, tableArgs);
3134 return function (...args) {
3135 args[1] = wrapDescribeInZone(args[1]);
3136 return originalDescribeFn.apply(this, args);
3137 };
3138 };
3139 }
3140 function wrapTestFactoryInZone(originalJestFn) {
3141 return function (...tableArgs) {
3142 return function (...args) {
3143 args[1] = wrapTestInZone(args[1]);
3144 return originalJestFn.apply(this, tableArgs).apply(this, args);
3145 };
3146 };
3147 }
3148 /**
3149 * Gets a function wrapping the body of a jest `describe` block to execute in a
3150 * synchronous-only zone.
3151 */
3152 function wrapDescribeInZone(describeBody) {
3153 return function (...args) {
3154 return syncZone.run(describeBody, this, args);
3155 };
3156 }
3157 /**
3158 * Gets a function wrapping the body of a jest `it/beforeEach/afterEach` block to
3159 * execute in a ProxyZone zone.
3160 * This will run in the `proxyZone`.
3161 */
3162 function wrapTestInZone(testBody, isTestFunc = false) {
3163 if (typeof testBody !== 'function') {
3164 return testBody;
3165 }
3166 const wrappedFunc = function () {
3167 if (Zone[api.symbol('useFakeTimersCalled')] === true && testBody &&
3168 !testBody.isFakeAsync) {
3169 // jest.useFakeTimers is called, run into fakeAsyncTest automatically.
3170 const fakeAsyncModule = Zone[Zone.__symbol__('fakeAsyncTest')];
3171 if (fakeAsyncModule && typeof fakeAsyncModule.fakeAsync === 'function') {
3172 testBody = fakeAsyncModule.fakeAsync(testBody);
3173 }
3174 }
3175 proxyZoneSpec.isTestFunc = isTestFunc;
3176 return proxyZone.run(testBody, null, arguments);
3177 };
3178 // Update the length of wrappedFunc to be the same as the length of the testBody
3179 // So jest core can handle whether the test function has `done()` or not correctly
3180 Object.defineProperty(wrappedFunc, 'length', { configurable: true, writable: true, enumerable: false });
3181 wrappedFunc.length = testBody.length;
3182 return wrappedFunc;
3183 }
3184 ['describe', 'xdescribe', 'fdescribe'].forEach(methodName => {
3185 let originalJestFn = context[methodName];
3186 if (context[Zone.__symbol__(methodName)]) {
3187 return;
3188 }
3189 context[Zone.__symbol__(methodName)] = originalJestFn;
3190 context[methodName] = function (...args) {
3191 args[1] = wrapDescribeInZone(args[1]);
3192 return originalJestFn.apply(this, args);
3193 };
3194 context[methodName].each = wrapDescribeFactoryInZone(originalJestFn.each);
3195 });
3196 context.describe.only = context.fdescribe;
3197 context.describe.skip = context.xdescribe;
3198 ['it', 'xit', 'fit', 'test', 'xtest'].forEach(methodName => {
3199 let originalJestFn = context[methodName];
3200 if (context[Zone.__symbol__(methodName)]) {
3201 return;
3202 }
3203 context[Zone.__symbol__(methodName)] = originalJestFn;
3204 context[methodName] = function (...args) {
3205 args[1] = wrapTestInZone(args[1], true);
3206 return originalJestFn.apply(this, args);
3207 };
3208 context[methodName].each = wrapTestFactoryInZone(originalJestFn.each);
3209 context[methodName].todo = originalJestFn.todo;
3210 });
3211 context.it.only = context.fit;
3212 context.it.skip = context.xit;
3213 context.test.only = context.fit;
3214 context.test.skip = context.xit;
3215 ['beforeEach', 'afterEach', 'beforeAll', 'afterAll'].forEach(methodName => {
3216 let originalJestFn = context[methodName];
3217 if (context[Zone.__symbol__(methodName)]) {
3218 return;
3219 }
3220 context[Zone.__symbol__(methodName)] = originalJestFn;
3221 context[methodName] = function (...args) {
3222 args[0] = wrapTestInZone(args[0]);
3223 return originalJestFn.apply(this, args);
3224 };
3225 });
3226 Zone.patchJestObject = function patchJestObject(Timer, isModern = false) {
3227 // check whether currently the test is inside fakeAsync()
3228 function isPatchingFakeTimer() {
3229 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3230 return !!fakeAsyncZoneSpec;
3231 }
3232 // check whether the current function is inside `test/it` or other methods
3233 // such as `describe/beforeEach`
3234 function isInTestFunc() {
3235 const proxyZoneSpec = Zone.current.get('ProxyZoneSpec');
3236 return proxyZoneSpec && proxyZoneSpec.isTestFunc;
3237 }
3238 if (Timer[api.symbol('fakeTimers')]) {
3239 return;
3240 }
3241 Timer[api.symbol('fakeTimers')] = true;
3242 // patch jest fakeTimer internal method to make sure no console.warn print out
3243 api.patchMethod(Timer, '_checkFakeTimers', delegate => {
3244 return function (self, args) {
3245 if (isPatchingFakeTimer()) {
3246 return true;
3247 }
3248 else {
3249 return delegate.apply(self, args);
3250 }
3251 };
3252 });
3253 // patch useFakeTimers(), set useFakeTimersCalled flag, and make test auto run into fakeAsync
3254 api.patchMethod(Timer, 'useFakeTimers', delegate => {
3255 return function (self, args) {
3256 Zone[api.symbol('useFakeTimersCalled')] = true;
3257 if (isModern || isInTestFunc()) {
3258 return delegate.apply(self, args);
3259 }
3260 return self;
3261 };
3262 });
3263 // patch useRealTimers(), unset useFakeTimers flag
3264 api.patchMethod(Timer, 'useRealTimers', delegate => {
3265 return function (self, args) {
3266 Zone[api.symbol('useFakeTimersCalled')] = false;
3267 if (isModern || isInTestFunc()) {
3268 return delegate.apply(self, args);
3269 }
3270 return self;
3271 };
3272 });
3273 // patch setSystemTime(), call setCurrentRealTime() in the fakeAsyncTest
3274 api.patchMethod(Timer, 'setSystemTime', delegate => {
3275 return function (self, args) {
3276 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3277 if (fakeAsyncZoneSpec && isPatchingFakeTimer()) {
3278 fakeAsyncZoneSpec.setFakeBaseSystemTime(args[0]);
3279 }
3280 else {
3281 return delegate.apply(self, args);
3282 }
3283 };
3284 });
3285 // patch getSystemTime(), call getCurrentRealTime() in the fakeAsyncTest
3286 api.patchMethod(Timer, 'getRealSystemTime', delegate => {
3287 return function (self, args) {
3288 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3289 if (fakeAsyncZoneSpec && isPatchingFakeTimer()) {
3290 return fakeAsyncZoneSpec.getRealSystemTime();
3291 }
3292 else {
3293 return delegate.apply(self, args);
3294 }
3295 };
3296 });
3297 // patch runAllTicks(), run all microTasks inside fakeAsync
3298 api.patchMethod(Timer, 'runAllTicks', delegate => {
3299 return function (self, args) {
3300 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3301 if (fakeAsyncZoneSpec) {
3302 fakeAsyncZoneSpec.flushMicrotasks();
3303 }
3304 else {
3305 return delegate.apply(self, args);
3306 }
3307 };
3308 });
3309 // patch runAllTimers(), run all macroTasks inside fakeAsync
3310 api.patchMethod(Timer, 'runAllTimers', delegate => {
3311 return function (self, args) {
3312 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3313 if (fakeAsyncZoneSpec) {
3314 fakeAsyncZoneSpec.flush(100, true);
3315 }
3316 else {
3317 return delegate.apply(self, args);
3318 }
3319 };
3320 });
3321 // patch advanceTimersByTime(), call tick() in the fakeAsyncTest
3322 api.patchMethod(Timer, 'advanceTimersByTime', delegate => {
3323 return function (self, args) {
3324 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3325 if (fakeAsyncZoneSpec) {
3326 fakeAsyncZoneSpec.tick(args[0]);
3327 }
3328 else {
3329 return delegate.apply(self, args);
3330 }
3331 };
3332 });
3333 // patch runOnlyPendingTimers(), call flushOnlyPendingTimers() in the fakeAsyncTest
3334 api.patchMethod(Timer, 'runOnlyPendingTimers', delegate => {
3335 return function (self, args) {
3336 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3337 if (fakeAsyncZoneSpec) {
3338 fakeAsyncZoneSpec.flushOnlyPendingTimers();
3339 }
3340 else {
3341 return delegate.apply(self, args);
3342 }
3343 };
3344 });
3345 // patch advanceTimersToNextTimer(), call tickToNext() in the fakeAsyncTest
3346 api.patchMethod(Timer, 'advanceTimersToNextTimer', delegate => {
3347 return function (self, args) {
3348 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3349 if (fakeAsyncZoneSpec) {
3350 fakeAsyncZoneSpec.tickToNext(args[0]);
3351 }
3352 else {
3353 return delegate.apply(self, args);
3354 }
3355 };
3356 });
3357 // patch clearAllTimers(), call removeAllTimers() in the fakeAsyncTest
3358 api.patchMethod(Timer, 'clearAllTimers', delegate => {
3359 return function (self, args) {
3360 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3361 if (fakeAsyncZoneSpec) {
3362 fakeAsyncZoneSpec.removeAllTimers();
3363 }
3364 else {
3365 return delegate.apply(self, args);
3366 }
3367 };
3368 });
3369 // patch getTimerCount(), call getTimerCount() in the fakeAsyncTest
3370 api.patchMethod(Timer, 'getTimerCount', delegate => {
3371 return function (self, args) {
3372 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3373 if (fakeAsyncZoneSpec) {
3374 return fakeAsyncZoneSpec.getTimerCount();
3375 }
3376 else {
3377 return delegate.apply(self, args);
3378 }
3379 };
3380 });
3381 };
3382});
3383
3384/**
3385 * @license
3386 * Copyright Google LLC All Rights Reserved.
3387 *
3388 * Use of this source code is governed by an MIT-style license that can be
3389 * found in the LICENSE file at https://angular.io/license
3390 */
3391Zone.__load_patch('mocha', (global, Zone) => {
3392 const Mocha = global.Mocha;
3393 if (typeof Mocha === 'undefined') {
3394 // return if Mocha is not available, because now zone-testing
3395 // will load mocha patch with jasmine/jest patch
3396 return;
3397 }
3398 if (typeof Zone === 'undefined') {
3399 throw new Error('Missing Zone.js');
3400 }
3401 const ProxyZoneSpec = Zone['ProxyZoneSpec'];
3402 const SyncTestZoneSpec = Zone['SyncTestZoneSpec'];
3403 if (!ProxyZoneSpec) {
3404 throw new Error('Missing ProxyZoneSpec');
3405 }
3406 if (Mocha['__zone_patch__']) {
3407 throw new Error('"Mocha" has already been patched with "Zone".');
3408 }
3409 Mocha['__zone_patch__'] = true;
3410 const rootZone = Zone.current;
3411 const syncZone = rootZone.fork(new SyncTestZoneSpec('Mocha.describe'));
3412 let testZone = null;
3413 const suiteZone = rootZone.fork(new ProxyZoneSpec());
3414 const mochaOriginal = {
3415 after: Mocha.after,
3416 afterEach: Mocha.afterEach,
3417 before: Mocha.before,
3418 beforeEach: Mocha.beforeEach,
3419 describe: Mocha.describe,
3420 it: Mocha.it
3421 };
3422 function modifyArguments(args, syncTest, asyncTest) {
3423 for (let i = 0; i < args.length; i++) {
3424 let arg = args[i];
3425 if (typeof arg === 'function') {
3426 // The `done` callback is only passed through if the function expects at
3427 // least one argument.
3428 // Note we have to make a function with correct number of arguments,
3429 // otherwise mocha will
3430 // think that all functions are sync or async.
3431 args[i] = (arg.length === 0) ? syncTest(arg) : asyncTest(arg);
3432 // Mocha uses toString to view the test body in the result list, make sure we return the
3433 // correct function body
3434 args[i].toString = function () {
3435 return arg.toString();
3436 };
3437 }
3438 }
3439 return args;
3440 }
3441 function wrapDescribeInZone(args) {
3442 const syncTest = function (fn) {
3443 return function () {
3444 return syncZone.run(fn, this, arguments);
3445 };
3446 };
3447 return modifyArguments(args, syncTest);
3448 }
3449 function wrapTestInZone(args) {
3450 const asyncTest = function (fn) {
3451 return function (done) {
3452 return testZone.run(fn, this, [done]);
3453 };
3454 };
3455 const syncTest = function (fn) {
3456 return function () {
3457 return testZone.run(fn, this);
3458 };
3459 };
3460 return modifyArguments(args, syncTest, asyncTest);
3461 }
3462 function wrapSuiteInZone(args) {
3463 const asyncTest = function (fn) {
3464 return function (done) {
3465 return suiteZone.run(fn, this, [done]);
3466 };
3467 };
3468 const syncTest = function (fn) {
3469 return function () {
3470 return suiteZone.run(fn, this);
3471 };
3472 };
3473 return modifyArguments(args, syncTest, asyncTest);
3474 }
3475 global.describe = global.suite = Mocha.describe = function () {
3476 return mochaOriginal.describe.apply(this, wrapDescribeInZone(arguments));
3477 };
3478 global.xdescribe = global.suite.skip = Mocha.describe.skip = function () {
3479 return mochaOriginal.describe.skip.apply(this, wrapDescribeInZone(arguments));
3480 };
3481 global.describe.only = global.suite.only = Mocha.describe.only = function () {
3482 return mochaOriginal.describe.only.apply(this, wrapDescribeInZone(arguments));
3483 };
3484 global.it = global.specify = global.test = Mocha.it = function () {
3485 return mochaOriginal.it.apply(this, wrapTestInZone(arguments));
3486 };
3487 global.xit = global.xspecify = Mocha.it.skip = function () {
3488 return mochaOriginal.it.skip.apply(this, wrapTestInZone(arguments));
3489 };
3490 global.it.only = global.test.only = Mocha.it.only = function () {
3491 return mochaOriginal.it.only.apply(this, wrapTestInZone(arguments));
3492 };
3493 global.after = global.suiteTeardown = Mocha.after = function () {
3494 return mochaOriginal.after.apply(this, wrapSuiteInZone(arguments));
3495 };
3496 global.afterEach = global.teardown = Mocha.afterEach = function () {
3497 return mochaOriginal.afterEach.apply(this, wrapTestInZone(arguments));
3498 };
3499 global.before = global.suiteSetup = Mocha.before = function () {
3500 return mochaOriginal.before.apply(this, wrapSuiteInZone(arguments));
3501 };
3502 global.beforeEach = global.setup = Mocha.beforeEach = function () {
3503 return mochaOriginal.beforeEach.apply(this, wrapTestInZone(arguments));
3504 };
3505 ((originalRunTest, originalRun) => {
3506 Mocha.Runner.prototype.runTest = function (fn) {
3507 Zone.current.scheduleMicroTask('mocha.forceTask', () => {
3508 originalRunTest.call(this, fn);
3509 });
3510 };
3511 Mocha.Runner.prototype.run = function (fn) {
3512 this.on('test', (e) => {
3513 testZone = rootZone.fork(new ProxyZoneSpec());
3514 });
3515 this.on('fail', (test, err) => {
3516 const proxyZoneSpec = testZone && testZone.get('ProxyZoneSpec');
3517 if (proxyZoneSpec && err) {
3518 try {
3519 // try catch here in case err.message is not writable
3520 err.message += proxyZoneSpec.getAndClearPendingTasksInfo();
3521 }
3522 catch (error) {
3523 }
3524 }
3525 });
3526 return originalRun.call(this, fn);
3527 };
3528 })(Mocha.Runner.prototype.runTest, Mocha.Runner.prototype.run);
3529});
3530
3531/**
3532 * @license
3533 * Copyright Google LLC All Rights Reserved.
3534 *
3535 * Use of this source code is governed by an MIT-style license that can be
3536 * found in the LICENSE file at https://angular.io/license
3537 */
3538(function (_global) {
3539 class AsyncTestZoneSpec {
3540 constructor(finishCallback, failCallback, namePrefix) {
3541 this.finishCallback = finishCallback;
3542 this.failCallback = failCallback;
3543 this._pendingMicroTasks = false;
3544 this._pendingMacroTasks = false;
3545 this._alreadyErrored = false;
3546 this._isSync = false;
3547 this.runZone = Zone.current;
3548 this.unresolvedChainedPromiseCount = 0;
3549 this.supportWaitUnresolvedChainedPromise = false;
3550 this.name = 'asyncTestZone for ' + namePrefix;
3551 this.properties = { 'AsyncTestZoneSpec': this };
3552 this.supportWaitUnresolvedChainedPromise =
3553 _global[Zone.__symbol__('supportWaitUnResolvedChainedPromise')] === true;
3554 }
3555 isUnresolvedChainedPromisePending() {
3556 return this.unresolvedChainedPromiseCount > 0;
3557 }
3558 _finishCallbackIfDone() {
3559 if (!(this._pendingMicroTasks || this._pendingMacroTasks ||
3560 (this.supportWaitUnresolvedChainedPromise && this.isUnresolvedChainedPromisePending()))) {
3561 // We do this because we would like to catch unhandled rejected promises.
3562 this.runZone.run(() => {
3563 setTimeout(() => {
3564 if (!this._alreadyErrored && !(this._pendingMicroTasks || this._pendingMacroTasks)) {
3565 this.finishCallback();
3566 }
3567 }, 0);
3568 });
3569 }
3570 }
3571 patchPromiseForTest() {
3572 if (!this.supportWaitUnresolvedChainedPromise) {
3573 return;
3574 }
3575 const patchPromiseForTest = Promise[Zone.__symbol__('patchPromiseForTest')];
3576 if (patchPromiseForTest) {
3577 patchPromiseForTest();
3578 }
3579 }
3580 unPatchPromiseForTest() {
3581 if (!this.supportWaitUnresolvedChainedPromise) {
3582 return;
3583 }
3584 const unPatchPromiseForTest = Promise[Zone.__symbol__('unPatchPromiseForTest')];
3585 if (unPatchPromiseForTest) {
3586 unPatchPromiseForTest();
3587 }
3588 }
3589 onScheduleTask(delegate, current, target, task) {
3590 if (task.type !== 'eventTask') {
3591 this._isSync = false;
3592 }
3593 if (task.type === 'microTask' && task.data && task.data instanceof Promise) {
3594 // check whether the promise is a chained promise
3595 if (task.data[AsyncTestZoneSpec.symbolParentUnresolved] === true) {
3596 // chained promise is being scheduled
3597 this.unresolvedChainedPromiseCount--;
3598 }
3599 }
3600 return delegate.scheduleTask(target, task);
3601 }
3602 onInvokeTask(delegate, current, target, task, applyThis, applyArgs) {
3603 if (task.type !== 'eventTask') {
3604 this._isSync = false;
3605 }
3606 return delegate.invokeTask(target, task, applyThis, applyArgs);
3607 }
3608 onCancelTask(delegate, current, target, task) {
3609 if (task.type !== 'eventTask') {
3610 this._isSync = false;
3611 }
3612 return delegate.cancelTask(target, task);
3613 }
3614 // Note - we need to use onInvoke at the moment to call finish when a test is
3615 // fully synchronous. TODO(juliemr): remove this when the logic for
3616 // onHasTask changes and it calls whenever the task queues are dirty.
3617 // updated by(JiaLiPassion), only call finish callback when no task
3618 // was scheduled/invoked/canceled.
3619 onInvoke(parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) {
3620 try {
3621 this._isSync = true;
3622 return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source);
3623 }
3624 finally {
3625 const afterTaskCounts = parentZoneDelegate._taskCounts;
3626 if (this._isSync) {
3627 this._finishCallbackIfDone();
3628 }
3629 }
3630 }
3631 onHandleError(parentZoneDelegate, currentZone, targetZone, error) {
3632 // Let the parent try to handle the error.
3633 const result = parentZoneDelegate.handleError(targetZone, error);
3634 if (result) {
3635 this.failCallback(error);
3636 this._alreadyErrored = true;
3637 }
3638 return false;
3639 }
3640 onHasTask(delegate, current, target, hasTaskState) {
3641 delegate.hasTask(target, hasTaskState);
3642 if (hasTaskState.change == 'microTask') {
3643 this._pendingMicroTasks = hasTaskState.microTask;
3644 this._finishCallbackIfDone();
3645 }
3646 else if (hasTaskState.change == 'macroTask') {
3647 this._pendingMacroTasks = hasTaskState.macroTask;
3648 this._finishCallbackIfDone();
3649 }
3650 }
3651 }
3652 AsyncTestZoneSpec.symbolParentUnresolved = Zone.__symbol__('parentUnresolved');
3653 // Export the class so that new instances can be created with proper
3654 // constructor params.
3655 Zone['AsyncTestZoneSpec'] = AsyncTestZoneSpec;
3656})(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global);
3657Zone.__load_patch('asynctest', (global, Zone, api) => {
3658 /**
3659 * Wraps a test function in an asynchronous test zone. The test will automatically
3660 * complete when all asynchronous calls within this zone are done.
3661 */
3662 Zone[api.symbol('asyncTest')] = function asyncTest(fn) {
3663 // If we're running using the Jasmine test framework, adapt to call the 'done'
3664 // function when asynchronous activity is finished.
3665 if (global.jasmine) {
3666 // Not using an arrow function to preserve context passed from call site
3667 return function (done) {
3668 if (!done) {
3669 // if we run beforeEach in @angular/core/testing/testing_internal then we get no done
3670 // fake it here and assume sync.
3671 done = function () { };
3672 done.fail = function (e) {
3673 throw e;
3674 };
3675 }
3676 runInTestZone(fn, this, done, (err) => {
3677 if (typeof err === 'string') {
3678 return done.fail(new Error(err));
3679 }
3680 else {
3681 done.fail(err);
3682 }
3683 });
3684 };
3685 }
3686 // Otherwise, return a promise which will resolve when asynchronous activity
3687 // is finished. This will be correctly consumed by the Mocha framework with
3688 // it('...', async(myFn)); or can be used in a custom framework.
3689 // Not using an arrow function to preserve context passed from call site
3690 return function () {
3691 return new Promise((finishCallback, failCallback) => {
3692 runInTestZone(fn, this, finishCallback, failCallback);
3693 });
3694 };
3695 };
3696 function runInTestZone(fn, context, finishCallback, failCallback) {
3697 const currentZone = Zone.current;
3698 const AsyncTestZoneSpec = Zone['AsyncTestZoneSpec'];
3699 if (AsyncTestZoneSpec === undefined) {
3700 throw new Error('AsyncTestZoneSpec is needed for the async() test helper but could not be found. ' +
3701 'Please make sure that your environment includes zone.js/dist/async-test.js');
3702 }
3703 const ProxyZoneSpec = Zone['ProxyZoneSpec'];
3704 if (!ProxyZoneSpec) {
3705 throw new Error('ProxyZoneSpec is needed for the async() test helper but could not be found. ' +
3706 'Please make sure that your environment includes zone.js/dist/proxy.js');
3707 }
3708 const proxyZoneSpec = ProxyZoneSpec.get();
3709 ProxyZoneSpec.assertPresent();
3710 // We need to create the AsyncTestZoneSpec outside the ProxyZone.
3711 // If we do it in ProxyZone then we will get to infinite recursion.
3712 const proxyZone = Zone.current.getZoneWith('ProxyZoneSpec');
3713 const previousDelegate = proxyZoneSpec.getDelegate();
3714 proxyZone.parent.run(() => {
3715 const testZoneSpec = new AsyncTestZoneSpec(() => {
3716 // Need to restore the original zone.
3717 if (proxyZoneSpec.getDelegate() == testZoneSpec) {
3718 // Only reset the zone spec if it's
3719 // sill this one. Otherwise, assume
3720 // it's OK.
3721 proxyZoneSpec.setDelegate(previousDelegate);
3722 }
3723 testZoneSpec.unPatchPromiseForTest();
3724 currentZone.run(() => {
3725 finishCallback();
3726 });
3727 }, (error) => {
3728 // Need to restore the original zone.
3729 if (proxyZoneSpec.getDelegate() == testZoneSpec) {
3730 // Only reset the zone spec if it's sill this one. Otherwise, assume it's OK.
3731 proxyZoneSpec.setDelegate(previousDelegate);
3732 }
3733 testZoneSpec.unPatchPromiseForTest();
3734 currentZone.run(() => {
3735 failCallback(error);
3736 });
3737 }, 'test');
3738 proxyZoneSpec.setDelegate(testZoneSpec);
3739 testZoneSpec.patchPromiseForTest();
3740 });
3741 return Zone.current.runGuarded(fn, context);
3742 }
3743});
3744
3745/**
3746 * @license
3747 * Copyright Google LLC All Rights Reserved.
3748 *
3749 * Use of this source code is governed by an MIT-style license that can be
3750 * found in the LICENSE file at https://angular.io/license
3751 */
3752(function (global) {
3753 const OriginalDate = global.Date;
3754 // Since when we compile this file to `es2015`, and if we define
3755 // this `FakeDate` as `class FakeDate`, and then set `FakeDate.prototype`
3756 // there will be an error which is `Cannot assign to read only property 'prototype'`
3757 // so we need to use function implementation here.
3758 function FakeDate() {
3759 if (arguments.length === 0) {
3760 const d = new OriginalDate();
3761 d.setTime(FakeDate.now());
3762 return d;
3763 }
3764 else {
3765 const args = Array.prototype.slice.call(arguments);
3766 return new OriginalDate(...args);
3767 }
3768 }
3769 FakeDate.now = function () {
3770 const fakeAsyncTestZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3771 if (fakeAsyncTestZoneSpec) {
3772 return fakeAsyncTestZoneSpec.getFakeSystemTime();
3773 }
3774 return OriginalDate.now.apply(this, arguments);
3775 };
3776 FakeDate.UTC = OriginalDate.UTC;
3777 FakeDate.parse = OriginalDate.parse;
3778 // keep a reference for zone patched timer function
3779 const timers = {
3780 setTimeout: global.setTimeout,
3781 setInterval: global.setInterval,
3782 clearTimeout: global.clearTimeout,
3783 clearInterval: global.clearInterval
3784 };
3785 class Scheduler {
3786 constructor() {
3787 // Scheduler queue with the tuple of end time and callback function - sorted by end time.
3788 this._schedulerQueue = [];
3789 // Current simulated time in millis.
3790 this._currentTickTime = 0;
3791 // Current fake system base time in millis.
3792 this._currentFakeBaseSystemTime = OriginalDate.now();
3793 // track requeuePeriodicTimer
3794 this._currentTickRequeuePeriodicEntries = [];
3795 }
3796 getCurrentTickTime() {
3797 return this._currentTickTime;
3798 }
3799 getFakeSystemTime() {
3800 return this._currentFakeBaseSystemTime + this._currentTickTime;
3801 }
3802 setFakeBaseSystemTime(fakeBaseSystemTime) {
3803 this._currentFakeBaseSystemTime = fakeBaseSystemTime;
3804 }
3805 getRealSystemTime() {
3806 return OriginalDate.now();
3807 }
3808 scheduleFunction(cb, delay, options) {
3809 options = Object.assign({
3810 args: [],
3811 isPeriodic: false,
3812 isRequestAnimationFrame: false,
3813 id: -1,
3814 isRequeuePeriodic: false
3815 }, options);
3816 let currentId = options.id < 0 ? Scheduler.nextId++ : options.id;
3817 let endTime = this._currentTickTime + delay;
3818 // Insert so that scheduler queue remains sorted by end time.
3819 let newEntry = {
3820 endTime: endTime,
3821 id: currentId,
3822 func: cb,
3823 args: options.args,
3824 delay: delay,
3825 isPeriodic: options.isPeriodic,
3826 isRequestAnimationFrame: options.isRequestAnimationFrame
3827 };
3828 if (options.isRequeuePeriodic) {
3829 this._currentTickRequeuePeriodicEntries.push(newEntry);
3830 }
3831 let i = 0;
3832 for (; i < this._schedulerQueue.length; i++) {
3833 let currentEntry = this._schedulerQueue[i];
3834 if (newEntry.endTime < currentEntry.endTime) {
3835 break;
3836 }
3837 }
3838 this._schedulerQueue.splice(i, 0, newEntry);
3839 return currentId;
3840 }
3841 removeScheduledFunctionWithId(id) {
3842 for (let i = 0; i < this._schedulerQueue.length; i++) {
3843 if (this._schedulerQueue[i].id == id) {
3844 this._schedulerQueue.splice(i, 1);
3845 break;
3846 }
3847 }
3848 }
3849 removeAll() {
3850 this._schedulerQueue = [];
3851 }
3852 getTimerCount() {
3853 return this._schedulerQueue.length;
3854 }
3855 tickToNext(step = 1, doTick, tickOptions) {
3856 if (this._schedulerQueue.length < step) {
3857 return;
3858 }
3859 // Find the last task currently queued in the scheduler queue and tick
3860 // till that time.
3861 const startTime = this._currentTickTime;
3862 const targetTask = this._schedulerQueue[step - 1];
3863 this.tick(targetTask.endTime - startTime, doTick, tickOptions);
3864 }
3865 tick(millis = 0, doTick, tickOptions) {
3866 let finalTime = this._currentTickTime + millis;
3867 let lastCurrentTime = 0;
3868 tickOptions = Object.assign({ processNewMacroTasksSynchronously: true }, tickOptions);
3869 // we need to copy the schedulerQueue so nested timeout
3870 // will not be wrongly called in the current tick
3871 // https://github.com/angular/angular/issues/33799
3872 const schedulerQueue = tickOptions.processNewMacroTasksSynchronously ?
3873 this._schedulerQueue :
3874 this._schedulerQueue.slice();
3875 if (schedulerQueue.length === 0 && doTick) {
3876 doTick(millis);
3877 return;
3878 }
3879 while (schedulerQueue.length > 0) {
3880 // clear requeueEntries before each loop
3881 this._currentTickRequeuePeriodicEntries = [];
3882 let current = schedulerQueue[0];
3883 if (finalTime < current.endTime) {
3884 // Done processing the queue since it's sorted by endTime.
3885 break;
3886 }
3887 else {
3888 // Time to run scheduled function. Remove it from the head of queue.
3889 let current = schedulerQueue.shift();
3890 if (!tickOptions.processNewMacroTasksSynchronously) {
3891 const idx = this._schedulerQueue.indexOf(current);
3892 if (idx >= 0) {
3893 this._schedulerQueue.splice(idx, 1);
3894 }
3895 }
3896 lastCurrentTime = this._currentTickTime;
3897 this._currentTickTime = current.endTime;
3898 if (doTick) {
3899 doTick(this._currentTickTime - lastCurrentTime);
3900 }
3901 let retval = current.func.apply(global, current.isRequestAnimationFrame ? [this._currentTickTime] : current.args);
3902 if (!retval) {
3903 // Uncaught exception in the current scheduled function. Stop processing the queue.
3904 break;
3905 }
3906 // check is there any requeue periodic entry is added in
3907 // current loop, if there is, we need to add to current loop
3908 if (!tickOptions.processNewMacroTasksSynchronously) {
3909 this._currentTickRequeuePeriodicEntries.forEach(newEntry => {
3910 let i = 0;
3911 for (; i < schedulerQueue.length; i++) {
3912 const currentEntry = schedulerQueue[i];
3913 if (newEntry.endTime < currentEntry.endTime) {
3914 break;
3915 }
3916 }
3917 schedulerQueue.splice(i, 0, newEntry);
3918 });
3919 }
3920 }
3921 }
3922 lastCurrentTime = this._currentTickTime;
3923 this._currentTickTime = finalTime;
3924 if (doTick) {
3925 doTick(this._currentTickTime - lastCurrentTime);
3926 }
3927 }
3928 flushOnlyPendingTimers(doTick) {
3929 if (this._schedulerQueue.length === 0) {
3930 return 0;
3931 }
3932 // Find the last task currently queued in the scheduler queue and tick
3933 // till that time.
3934 const startTime = this._currentTickTime;
3935 const lastTask = this._schedulerQueue[this._schedulerQueue.length - 1];
3936 this.tick(lastTask.endTime - startTime, doTick, { processNewMacroTasksSynchronously: false });
3937 return this._currentTickTime - startTime;
3938 }
3939 flush(limit = 20, flushPeriodic = false, doTick) {
3940 if (flushPeriodic) {
3941 return this.flushPeriodic(doTick);
3942 }
3943 else {
3944 return this.flushNonPeriodic(limit, doTick);
3945 }
3946 }
3947 flushPeriodic(doTick) {
3948 if (this._schedulerQueue.length === 0) {
3949 return 0;
3950 }
3951 // Find the last task currently queued in the scheduler queue and tick
3952 // till that time.
3953 const startTime = this._currentTickTime;
3954 const lastTask = this._schedulerQueue[this._schedulerQueue.length - 1];
3955 this.tick(lastTask.endTime - startTime, doTick);
3956 return this._currentTickTime - startTime;
3957 }
3958 flushNonPeriodic(limit, doTick) {
3959 const startTime = this._currentTickTime;
3960 let lastCurrentTime = 0;
3961 let count = 0;
3962 while (this._schedulerQueue.length > 0) {
3963 count++;
3964 if (count > limit) {
3965 throw new Error('flush failed after reaching the limit of ' + limit +
3966 ' tasks. Does your code use a polling timeout?');
3967 }
3968 // flush only non-periodic timers.
3969 // If the only remaining tasks are periodic(or requestAnimationFrame), finish flushing.
3970 if (this._schedulerQueue.filter(task => !task.isPeriodic && !task.isRequestAnimationFrame)
3971 .length === 0) {
3972 break;
3973 }
3974 const current = this._schedulerQueue.shift();
3975 lastCurrentTime = this._currentTickTime;
3976 this._currentTickTime = current.endTime;
3977 if (doTick) {
3978 // Update any secondary schedulers like Jasmine mock Date.
3979 doTick(this._currentTickTime - lastCurrentTime);
3980 }
3981 const retval = current.func.apply(global, current.args);
3982 if (!retval) {
3983 // Uncaught exception in the current scheduled function. Stop processing the queue.
3984 break;
3985 }
3986 }
3987 return this._currentTickTime - startTime;
3988 }
3989 }
3990 // Next scheduler id.
3991 Scheduler.nextId = 1;
3992 class FakeAsyncTestZoneSpec {
3993 constructor(namePrefix, trackPendingRequestAnimationFrame = false, macroTaskOptions) {
3994 this.trackPendingRequestAnimationFrame = trackPendingRequestAnimationFrame;
3995 this.macroTaskOptions = macroTaskOptions;
3996 this._scheduler = new Scheduler();
3997 this._microtasks = [];
3998 this._lastError = null;
3999 this._uncaughtPromiseErrors = Promise[Zone.__symbol__('uncaughtPromiseErrors')];
4000 this.pendingPeriodicTimers = [];
4001 this.pendingTimers = [];
4002 this.patchDateLocked = false;
4003 this.properties = { 'FakeAsyncTestZoneSpec': this };
4004 this.name = 'fakeAsyncTestZone for ' + namePrefix;
4005 // in case user can't access the construction of FakeAsyncTestSpec
4006 // user can also define macroTaskOptions by define a global variable.
4007 if (!this.macroTaskOptions) {
4008 this.macroTaskOptions = global[Zone.__symbol__('FakeAsyncTestMacroTask')];
4009 }
4010 }
4011 static assertInZone() {
4012 if (Zone.current.get('FakeAsyncTestZoneSpec') == null) {
4013 throw new Error('The code should be running in the fakeAsync zone to call this function');
4014 }
4015 }
4016 _fnAndFlush(fn, completers) {
4017 return (...args) => {
4018 fn.apply(global, args);
4019 if (this._lastError === null) { // Success
4020 if (completers.onSuccess != null) {
4021 completers.onSuccess.apply(global);
4022 }
4023 // Flush microtasks only on success.
4024 this.flushMicrotasks();
4025 }
4026 else { // Failure
4027 if (completers.onError != null) {
4028 completers.onError.apply(global);
4029 }
4030 }
4031 // Return true if there were no errors, false otherwise.
4032 return this._lastError === null;
4033 };
4034 }
4035 static _removeTimer(timers, id) {
4036 let index = timers.indexOf(id);
4037 if (index > -1) {
4038 timers.splice(index, 1);
4039 }
4040 }
4041 _dequeueTimer(id) {
4042 return () => {
4043 FakeAsyncTestZoneSpec._removeTimer(this.pendingTimers, id);
4044 };
4045 }
4046 _requeuePeriodicTimer(fn, interval, args, id) {
4047 return () => {
4048 // Requeue the timer callback if it's not been canceled.
4049 if (this.pendingPeriodicTimers.indexOf(id) !== -1) {
4050 this._scheduler.scheduleFunction(fn, interval, { args, isPeriodic: true, id, isRequeuePeriodic: true });
4051 }
4052 };
4053 }
4054 _dequeuePeriodicTimer(id) {
4055 return () => {
4056 FakeAsyncTestZoneSpec._removeTimer(this.pendingPeriodicTimers, id);
4057 };
4058 }
4059 _setTimeout(fn, delay, args, isTimer = true) {
4060 let removeTimerFn = this._dequeueTimer(Scheduler.nextId);
4061 // Queue the callback and dequeue the timer on success and error.
4062 let cb = this._fnAndFlush(fn, { onSuccess: removeTimerFn, onError: removeTimerFn });
4063 let id = this._scheduler.scheduleFunction(cb, delay, { args, isRequestAnimationFrame: !isTimer });
4064 if (isTimer) {
4065 this.pendingTimers.push(id);
4066 }
4067 return id;
4068 }
4069 _clearTimeout(id) {
4070 FakeAsyncTestZoneSpec._removeTimer(this.pendingTimers, id);
4071 this._scheduler.removeScheduledFunctionWithId(id);
4072 }
4073 _setInterval(fn, interval, args) {
4074 let id = Scheduler.nextId;
4075 let completers = { onSuccess: null, onError: this._dequeuePeriodicTimer(id) };
4076 let cb = this._fnAndFlush(fn, completers);
4077 // Use the callback created above to requeue on success.
4078 completers.onSuccess = this._requeuePeriodicTimer(cb, interval, args, id);
4079 // Queue the callback and dequeue the periodic timer only on error.
4080 this._scheduler.scheduleFunction(cb, interval, { args, isPeriodic: true });
4081 this.pendingPeriodicTimers.push(id);
4082 return id;
4083 }
4084 _clearInterval(id) {
4085 FakeAsyncTestZoneSpec._removeTimer(this.pendingPeriodicTimers, id);
4086 this._scheduler.removeScheduledFunctionWithId(id);
4087 }
4088 _resetLastErrorAndThrow() {
4089 let error = this._lastError || this._uncaughtPromiseErrors[0];
4090 this._uncaughtPromiseErrors.length = 0;
4091 this._lastError = null;
4092 throw error;
4093 }
4094 getCurrentTickTime() {
4095 return this._scheduler.getCurrentTickTime();
4096 }
4097 getFakeSystemTime() {
4098 return this._scheduler.getFakeSystemTime();
4099 }
4100 setFakeBaseSystemTime(realTime) {
4101 this._scheduler.setFakeBaseSystemTime(realTime);
4102 }
4103 getRealSystemTime() {
4104 return this._scheduler.getRealSystemTime();
4105 }
4106 static patchDate() {
4107 if (!!global[Zone.__symbol__('disableDatePatching')]) {
4108 // we don't want to patch global Date
4109 // because in some case, global Date
4110 // is already being patched, we need to provide
4111 // an option to let user still use their
4112 // own version of Date.
4113 return;
4114 }
4115 if (global['Date'] === FakeDate) {
4116 // already patched
4117 return;
4118 }
4119 global['Date'] = FakeDate;
4120 FakeDate.prototype = OriginalDate.prototype;
4121 // try check and reset timers
4122 // because jasmine.clock().install() may
4123 // have replaced the global timer
4124 FakeAsyncTestZoneSpec.checkTimerPatch();
4125 }
4126 static resetDate() {
4127 if (global['Date'] === FakeDate) {
4128 global['Date'] = OriginalDate;
4129 }
4130 }
4131 static checkTimerPatch() {
4132 if (global.setTimeout !== timers.setTimeout) {
4133 global.setTimeout = timers.setTimeout;
4134 global.clearTimeout = timers.clearTimeout;
4135 }
4136 if (global.setInterval !== timers.setInterval) {
4137 global.setInterval = timers.setInterval;
4138 global.clearInterval = timers.clearInterval;
4139 }
4140 }
4141 lockDatePatch() {
4142 this.patchDateLocked = true;
4143 FakeAsyncTestZoneSpec.patchDate();
4144 }
4145 unlockDatePatch() {
4146 this.patchDateLocked = false;
4147 FakeAsyncTestZoneSpec.resetDate();
4148 }
4149 tickToNext(steps = 1, doTick, tickOptions = { processNewMacroTasksSynchronously: true }) {
4150 if (steps <= 0) {
4151 return;
4152 }
4153 FakeAsyncTestZoneSpec.assertInZone();
4154 this.flushMicrotasks();
4155 this._scheduler.tickToNext(steps, doTick, tickOptions);
4156 if (this._lastError !== null) {
4157 this._resetLastErrorAndThrow();
4158 }
4159 }
4160 tick(millis = 0, doTick, tickOptions = { processNewMacroTasksSynchronously: true }) {
4161 FakeAsyncTestZoneSpec.assertInZone();
4162 this.flushMicrotasks();
4163 this._scheduler.tick(millis, doTick, tickOptions);
4164 if (this._lastError !== null) {
4165 this._resetLastErrorAndThrow();
4166 }
4167 }
4168 flushMicrotasks() {
4169 FakeAsyncTestZoneSpec.assertInZone();
4170 const flushErrors = () => {
4171 if (this._lastError !== null || this._uncaughtPromiseErrors.length) {
4172 // If there is an error stop processing the microtask queue and rethrow the error.
4173 this._resetLastErrorAndThrow();
4174 }
4175 };
4176 while (this._microtasks.length > 0) {
4177 let microtask = this._microtasks.shift();
4178 microtask.func.apply(microtask.target, microtask.args);
4179 }
4180 flushErrors();
4181 }
4182 flush(limit, flushPeriodic, doTick) {
4183 FakeAsyncTestZoneSpec.assertInZone();
4184 this.flushMicrotasks();
4185 const elapsed = this._scheduler.flush(limit, flushPeriodic, doTick);
4186 if (this._lastError !== null) {
4187 this._resetLastErrorAndThrow();
4188 }
4189 return elapsed;
4190 }
4191 flushOnlyPendingTimers(doTick) {
4192 FakeAsyncTestZoneSpec.assertInZone();
4193 this.flushMicrotasks();
4194 const elapsed = this._scheduler.flushOnlyPendingTimers(doTick);
4195 if (this._lastError !== null) {
4196 this._resetLastErrorAndThrow();
4197 }
4198 return elapsed;
4199 }
4200 removeAllTimers() {
4201 FakeAsyncTestZoneSpec.assertInZone();
4202 this._scheduler.removeAll();
4203 this.pendingPeriodicTimers = [];
4204 this.pendingTimers = [];
4205 }
4206 getTimerCount() {
4207 return this._scheduler.getTimerCount() + this._microtasks.length;
4208 }
4209 onScheduleTask(delegate, current, target, task) {
4210 switch (task.type) {
4211 case 'microTask':
4212 let args = task.data && task.data.args;
4213 // should pass additional arguments to callback if have any
4214 // currently we know process.nextTick will have such additional
4215 // arguments
4216 let additionalArgs;
4217 if (args) {
4218 let callbackIndex = task.data.cbIdx;
4219 if (typeof args.length === 'number' && args.length > callbackIndex + 1) {
4220 additionalArgs = Array.prototype.slice.call(args, callbackIndex + 1);
4221 }
4222 }
4223 this._microtasks.push({
4224 func: task.invoke,
4225 args: additionalArgs,
4226 target: task.data && task.data.target
4227 });
4228 break;
4229 case 'macroTask':
4230 switch (task.source) {
4231 case 'setTimeout':
4232 task.data['handleId'] = this._setTimeout(task.invoke, task.data['delay'], Array.prototype.slice.call(task.data['args'], 2));
4233 break;
4234 case 'setImmediate':
4235 task.data['handleId'] = this._setTimeout(task.invoke, 0, Array.prototype.slice.call(task.data['args'], 1));
4236 break;
4237 case 'setInterval':
4238 task.data['handleId'] = this._setInterval(task.invoke, task.data['delay'], Array.prototype.slice.call(task.data['args'], 2));
4239 break;
4240 case 'XMLHttpRequest.send':
4241 throw new Error('Cannot make XHRs from within a fake async test. Request URL: ' +
4242 task.data['url']);
4243 case 'requestAnimationFrame':
4244 case 'webkitRequestAnimationFrame':
4245 case 'mozRequestAnimationFrame':
4246 // Simulate a requestAnimationFrame by using a setTimeout with 16 ms.
4247 // (60 frames per second)
4248 task.data['handleId'] = this._setTimeout(task.invoke, 16, task.data['args'], this.trackPendingRequestAnimationFrame);
4249 break;
4250 default:
4251 // user can define which macroTask they want to support by passing
4252 // macroTaskOptions
4253 const macroTaskOption = this.findMacroTaskOption(task);
4254 if (macroTaskOption) {
4255 const args = task.data && task.data['args'];
4256 const delay = args && args.length > 1 ? args[1] : 0;
4257 let callbackArgs = macroTaskOption.callbackArgs ? macroTaskOption.callbackArgs : args;
4258 if (!!macroTaskOption.isPeriodic) {
4259 // periodic macroTask, use setInterval to simulate
4260 task.data['handleId'] = this._setInterval(task.invoke, delay, callbackArgs);
4261 task.data.isPeriodic = true;
4262 }
4263 else {
4264 // not periodic, use setTimeout to simulate
4265 task.data['handleId'] = this._setTimeout(task.invoke, delay, callbackArgs);
4266 }
4267 break;
4268 }
4269 throw new Error('Unknown macroTask scheduled in fake async test: ' + task.source);
4270 }
4271 break;
4272 case 'eventTask':
4273 task = delegate.scheduleTask(target, task);
4274 break;
4275 }
4276 return task;
4277 }
4278 onCancelTask(delegate, current, target, task) {
4279 switch (task.source) {
4280 case 'setTimeout':
4281 case 'requestAnimationFrame':
4282 case 'webkitRequestAnimationFrame':
4283 case 'mozRequestAnimationFrame':
4284 return this._clearTimeout(task.data['handleId']);
4285 case 'setInterval':
4286 return this._clearInterval(task.data['handleId']);
4287 default:
4288 // user can define which macroTask they want to support by passing
4289 // macroTaskOptions
4290 const macroTaskOption = this.findMacroTaskOption(task);
4291 if (macroTaskOption) {
4292 const handleId = task.data['handleId'];
4293 return macroTaskOption.isPeriodic ? this._clearInterval(handleId) :
4294 this._clearTimeout(handleId);
4295 }
4296 return delegate.cancelTask(target, task);
4297 }
4298 }
4299 onInvoke(delegate, current, target, callback, applyThis, applyArgs, source) {
4300 try {
4301 FakeAsyncTestZoneSpec.patchDate();
4302 return delegate.invoke(target, callback, applyThis, applyArgs, source);
4303 }
4304 finally {
4305 if (!this.patchDateLocked) {
4306 FakeAsyncTestZoneSpec.resetDate();
4307 }
4308 }
4309 }
4310 findMacroTaskOption(task) {
4311 if (!this.macroTaskOptions) {
4312 return null;
4313 }
4314 for (let i = 0; i < this.macroTaskOptions.length; i++) {
4315 const macroTaskOption = this.macroTaskOptions[i];
4316 if (macroTaskOption.source === task.source) {
4317 return macroTaskOption;
4318 }
4319 }
4320 return null;
4321 }
4322 onHandleError(parentZoneDelegate, currentZone, targetZone, error) {
4323 this._lastError = error;
4324 return false; // Don't propagate error to parent zone.
4325 }
4326 }
4327 // Export the class so that new instances can be created with proper
4328 // constructor params.
4329 Zone['FakeAsyncTestZoneSpec'] = FakeAsyncTestZoneSpec;
4330})(typeof window === 'object' && window || typeof self === 'object' && self || global);
4331Zone.__load_patch('fakeasync', (global, Zone, api) => {
4332 const FakeAsyncTestZoneSpec = Zone && Zone['FakeAsyncTestZoneSpec'];
4333 function getProxyZoneSpec() {
4334 return Zone && Zone['ProxyZoneSpec'];
4335 }
4336 let _fakeAsyncTestZoneSpec = null;
4337 /**
4338 * Clears out the shared fake async zone for a test.
4339 * To be called in a global `beforeEach`.
4340 *
4341 * @experimental
4342 */
4343 function resetFakeAsyncZone() {
4344 if (_fakeAsyncTestZoneSpec) {
4345 _fakeAsyncTestZoneSpec.unlockDatePatch();
4346 }
4347 _fakeAsyncTestZoneSpec = null;
4348 // in node.js testing we may not have ProxyZoneSpec in which case there is nothing to reset.
4349 getProxyZoneSpec() && getProxyZoneSpec().assertPresent().resetDelegate();
4350 }
4351 /**
4352 * Wraps a function to be executed in the fakeAsync zone:
4353 * - microtasks are manually executed by calling `flushMicrotasks()`,
4354 * - timers are synchronous, `tick()` simulates the asynchronous passage of time.
4355 *
4356 * If there are any pending timers at the end of the function, an exception will be thrown.
4357 *
4358 * Can be used to wrap inject() calls.
4359 *
4360 * ## Example
4361 *
4362 * {@example core/testing/ts/fake_async.ts region='basic'}
4363 *
4364 * @param fn
4365 * @returns The function wrapped to be executed in the fakeAsync zone
4366 *
4367 * @experimental
4368 */
4369 function fakeAsync(fn) {
4370 // Not using an arrow function to preserve context passed from call site
4371 const fakeAsyncFn = function (...args) {
4372 const ProxyZoneSpec = getProxyZoneSpec();
4373 if (!ProxyZoneSpec) {
4374 throw new Error('ProxyZoneSpec is needed for the async() test helper but could not be found. ' +
4375 'Please make sure that your environment includes zone.js/dist/proxy.js');
4376 }
4377 const proxyZoneSpec = ProxyZoneSpec.assertPresent();
4378 if (Zone.current.get('FakeAsyncTestZoneSpec')) {
4379 throw new Error('fakeAsync() calls can not be nested');
4380 }
4381 try {
4382 // in case jasmine.clock init a fakeAsyncTestZoneSpec
4383 if (!_fakeAsyncTestZoneSpec) {
4384 if (proxyZoneSpec.getDelegate() instanceof FakeAsyncTestZoneSpec) {
4385 throw new Error('fakeAsync() calls can not be nested');
4386 }
4387 _fakeAsyncTestZoneSpec = new FakeAsyncTestZoneSpec();
4388 }
4389 let res;
4390 const lastProxyZoneSpec = proxyZoneSpec.getDelegate();
4391 proxyZoneSpec.setDelegate(_fakeAsyncTestZoneSpec);
4392 _fakeAsyncTestZoneSpec.lockDatePatch();
4393 try {
4394 res = fn.apply(this, args);
4395 flushMicrotasks();
4396 }
4397 finally {
4398 proxyZoneSpec.setDelegate(lastProxyZoneSpec);
4399 }
4400 if (_fakeAsyncTestZoneSpec.pendingPeriodicTimers.length > 0) {
4401 throw new Error(`${_fakeAsyncTestZoneSpec.pendingPeriodicTimers.length} ` +
4402 `periodic timer(s) still in the queue.`);
4403 }
4404 if (_fakeAsyncTestZoneSpec.pendingTimers.length > 0) {
4405 throw new Error(`${_fakeAsyncTestZoneSpec.pendingTimers.length} timer(s) still in the queue.`);
4406 }
4407 return res;
4408 }
4409 finally {
4410 resetFakeAsyncZone();
4411 }
4412 };
4413 fakeAsyncFn.isFakeAsync = true;
4414 return fakeAsyncFn;
4415 }
4416 function _getFakeAsyncZoneSpec() {
4417 if (_fakeAsyncTestZoneSpec == null) {
4418 _fakeAsyncTestZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
4419 if (_fakeAsyncTestZoneSpec == null) {
4420 throw new Error('The code should be running in the fakeAsync zone to call this function');
4421 }
4422 }
4423 return _fakeAsyncTestZoneSpec;
4424 }
4425 /**
4426 * Simulates the asynchronous passage of time for the timers in the fakeAsync zone.
4427 *
4428 * The microtasks queue is drained at the very start of this function and after any timer callback
4429 * has been executed.
4430 *
4431 * ## Example
4432 *
4433 * {@example core/testing/ts/fake_async.ts region='basic'}
4434 *
4435 * @experimental
4436 */
4437 function tick(millis = 0, ignoreNestedTimeout = false) {
4438 _getFakeAsyncZoneSpec().tick(millis, null, ignoreNestedTimeout);
4439 }
4440 /**
4441 * Simulates the asynchronous passage of time for the timers in the fakeAsync zone by
4442 * draining the macrotask queue until it is empty. The returned value is the milliseconds
4443 * of time that would have been elapsed.
4444 *
4445 * @param maxTurns
4446 * @returns The simulated time elapsed, in millis.
4447 *
4448 * @experimental
4449 */
4450 function flush(maxTurns) {
4451 return _getFakeAsyncZoneSpec().flush(maxTurns);
4452 }
4453 /**
4454 * Discard all remaining periodic tasks.
4455 *
4456 * @experimental
4457 */
4458 function discardPeriodicTasks() {
4459 const zoneSpec = _getFakeAsyncZoneSpec();
4460 const pendingTimers = zoneSpec.pendingPeriodicTimers;
4461 zoneSpec.pendingPeriodicTimers.length = 0;
4462 }
4463 /**
4464 * Flush any pending microtasks.
4465 *
4466 * @experimental
4467 */
4468 function flushMicrotasks() {
4469 _getFakeAsyncZoneSpec().flushMicrotasks();
4470 }
4471 Zone[api.symbol('fakeAsyncTest')] =
4472 { resetFakeAsyncZone, flushMicrotasks, discardPeriodicTasks, tick, flush, fakeAsync };
4473}, true);
4474
4475/**
4476 * @license
4477 * Copyright Google LLC All Rights Reserved.
4478 *
4479 * Use of this source code is governed by an MIT-style license that can be
4480 * found in the LICENSE file at https://angular.io/license
4481 */
4482/**
4483 * Promise for async/fakeAsync zoneSpec test
4484 * can support async operation which not supported by zone.js
4485 * such as
4486 * it ('test jsonp in AsyncZone', async() => {
4487 * new Promise(res => {
4488 * jsonp(url, (data) => {
4489 * // success callback
4490 * res(data);
4491 * });
4492 * }).then((jsonpResult) => {
4493 * // get jsonp result.
4494 *
4495 * // user will expect AsyncZoneSpec wait for
4496 * // then, but because jsonp is not zone aware
4497 * // AsyncZone will finish before then is called.
4498 * });
4499 * });
4500 */
4501Zone.__load_patch('promisefortest', (global, Zone, api) => {
4502 const symbolState = api.symbol('state');
4503 const UNRESOLVED = null;
4504 const symbolParentUnresolved = api.symbol('parentUnresolved');
4505 // patch Promise.prototype.then to keep an internal
4506 // number for tracking unresolved chained promise
4507 // we will decrease this number when the parent promise
4508 // being resolved/rejected and chained promise was
4509 // scheduled as a microTask.
4510 // so we can know such kind of chained promise still
4511 // not resolved in AsyncTestZone
4512 Promise[api.symbol('patchPromiseForTest')] = function patchPromiseForTest() {
4513 let oriThen = Promise[Zone.__symbol__('ZonePromiseThen')];
4514 if (oriThen) {
4515 return;
4516 }
4517 oriThen = Promise[Zone.__symbol__('ZonePromiseThen')] = Promise.prototype.then;
4518 Promise.prototype.then = function () {
4519 const chained = oriThen.apply(this, arguments);
4520 if (this[symbolState] === UNRESOLVED) {
4521 // parent promise is unresolved.
4522 const asyncTestZoneSpec = Zone.current.get('AsyncTestZoneSpec');
4523 if (asyncTestZoneSpec) {
4524 asyncTestZoneSpec.unresolvedChainedPromiseCount++;
4525 chained[symbolParentUnresolved] = true;
4526 }
4527 }
4528 return chained;
4529 };
4530 };
4531 Promise[api.symbol('unPatchPromiseForTest')] = function unpatchPromiseForTest() {
4532 // restore origin then
4533 const oriThen = Promise[Zone.__symbol__('ZonePromiseThen')];
4534 if (oriThen) {
4535 Promise.prototype.then = oriThen;
4536 Promise[Zone.__symbol__('ZonePromiseThen')] = undefined;
4537 }
4538 };
4539});
Note: See TracBrowser for help on using the repository browser.