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

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

initial commit

  • Property mode set to 100644
File size: 213.1 KB
Line 
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/** Object.create */
658const ObjectCreate = Object.create;
659/** Array.prototype.slice */
660const ArraySlice = Array.prototype.slice;
661/** addEventListener string const */
662const ADD_EVENT_LISTENER_STR = 'addEventListener';
663/** removeEventListener string const */
664const REMOVE_EVENT_LISTENER_STR = 'removeEventListener';
665/** zoneSymbol addEventListener */
666const ZONE_SYMBOL_ADD_EVENT_LISTENER = Zone.__symbol__(ADD_EVENT_LISTENER_STR);
667/** zoneSymbol removeEventListener */
668const ZONE_SYMBOL_REMOVE_EVENT_LISTENER = Zone.__symbol__(REMOVE_EVENT_LISTENER_STR);
669/** true string const */
670const TRUE_STR = 'true';
671/** false string const */
672const FALSE_STR = 'false';
673/** Zone symbol prefix string const. */
674const ZONE_SYMBOL_PREFIX = Zone.__symbol__('');
675function wrapWithCurrentZone(callback, source) {
676 return Zone.current.wrap(callback, source);
677}
678function scheduleMacroTaskWithCurrentZone(source, callback, data, customSchedule, customCancel) {
679 return Zone.current.scheduleMacroTask(source, callback, data, customSchedule, customCancel);
680}
681const zoneSymbol = Zone.__symbol__;
682const isWindowExists = typeof window !== 'undefined';
683const internalWindow = isWindowExists ? window : undefined;
684const _global = isWindowExists && internalWindow || typeof self === 'object' && self || global;
685const REMOVE_ATTRIBUTE = 'removeAttribute';
686const NULL_ON_PROP_VALUE = [null];
687function bindArguments(args, source) {
688 for (let i = args.length - 1; i >= 0; i--) {
689 if (typeof args[i] === 'function') {
690 args[i] = wrapWithCurrentZone(args[i], source + '_' + i);
691 }
692 }
693 return args;
694}
695function patchPrototype(prototype, fnNames) {
696 const source = prototype.constructor['name'];
697 for (let i = 0; i < fnNames.length; i++) {
698 const name = fnNames[i];
699 const delegate = prototype[name];
700 if (delegate) {
701 const prototypeDesc = ObjectGetOwnPropertyDescriptor(prototype, name);
702 if (!isPropertyWritable(prototypeDesc)) {
703 continue;
704 }
705 prototype[name] = ((delegate) => {
706 const patched = function () {
707 return delegate.apply(this, bindArguments(arguments, source + '.' + name));
708 };
709 attachOriginToPatched(patched, delegate);
710 return patched;
711 })(delegate);
712 }
713 }
714}
715function isPropertyWritable(propertyDesc) {
716 if (!propertyDesc) {
717 return true;
718 }
719 if (propertyDesc.writable === false) {
720 return false;
721 }
722 return !(typeof propertyDesc.get === 'function' && typeof propertyDesc.set === 'undefined');
723}
724const isWebWorker = (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope);
725// Make sure to access `process` through `_global` so that WebPack does not accidentally browserify
726// this code.
727const isNode = (!('nw' in _global) && typeof _global.process !== 'undefined' &&
728 {}.toString.call(_global.process) === '[object process]');
729const isBrowser = !isNode && !isWebWorker && !!(isWindowExists && internalWindow['HTMLElement']);
730// we are in electron of nw, so we are both browser and nodejs
731// Make sure to access `process` through `_global` so that WebPack does not accidentally browserify
732// this code.
733const isMix = typeof _global.process !== 'undefined' &&
734 {}.toString.call(_global.process) === '[object process]' && !isWebWorker &&
735 !!(isWindowExists && internalWindow['HTMLElement']);
736const zoneSymbolEventNames = {};
737const wrapFn = function (event) {
738 // https://github.com/angular/zone.js/issues/911, in IE, sometimes
739 // event will be undefined, so we need to use window.event
740 event = event || _global.event;
741 if (!event) {
742 return;
743 }
744 let eventNameSymbol = zoneSymbolEventNames[event.type];
745 if (!eventNameSymbol) {
746 eventNameSymbol = zoneSymbolEventNames[event.type] = zoneSymbol('ON_PROPERTY' + event.type);
747 }
748 const target = this || event.target || _global;
749 const listener = target[eventNameSymbol];
750 let result;
751 if (isBrowser && target === internalWindow && event.type === 'error') {
752 // window.onerror have different signiture
753 // https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror#window.onerror
754 // and onerror callback will prevent default when callback return true
755 const errorEvent = event;
756 result = listener &&
757 listener.call(this, errorEvent.message, errorEvent.filename, errorEvent.lineno, errorEvent.colno, errorEvent.error);
758 if (result === true) {
759 event.preventDefault();
760 }
761 }
762 else {
763 result = listener && listener.apply(this, arguments);
764 if (result != undefined && !result) {
765 event.preventDefault();
766 }
767 }
768 return result;
769};
770function patchProperty(obj, prop, prototype) {
771 let desc = ObjectGetOwnPropertyDescriptor(obj, prop);
772 if (!desc && prototype) {
773 // when patch window object, use prototype to check prop exist or not
774 const prototypeDesc = ObjectGetOwnPropertyDescriptor(prototype, prop);
775 if (prototypeDesc) {
776 desc = { enumerable: true, configurable: true };
777 }
778 }
779 // if the descriptor not exists or is not configurable
780 // just return
781 if (!desc || !desc.configurable) {
782 return;
783 }
784 const onPropPatchedSymbol = zoneSymbol('on' + prop + 'patched');
785 if (obj.hasOwnProperty(onPropPatchedSymbol) && obj[onPropPatchedSymbol]) {
786 return;
787 }
788 // A property descriptor cannot have getter/setter and be writable
789 // deleting the writable and value properties avoids this error:
790 //
791 // TypeError: property descriptors must not specify a value or be writable when a
792 // getter or setter has been specified
793 delete desc.writable;
794 delete desc.value;
795 const originalDescGet = desc.get;
796 const originalDescSet = desc.set;
797 // substr(2) cuz 'onclick' -> 'click', etc
798 const eventName = prop.substr(2);
799 let eventNameSymbol = zoneSymbolEventNames[eventName];
800 if (!eventNameSymbol) {
801 eventNameSymbol = zoneSymbolEventNames[eventName] = zoneSymbol('ON_PROPERTY' + eventName);
802 }
803 desc.set = function (newValue) {
804 // in some of windows's onproperty callback, this is undefined
805 // so we need to check it
806 let target = this;
807 if (!target && obj === _global) {
808 target = _global;
809 }
810 if (!target) {
811 return;
812 }
813 let previousValue = target[eventNameSymbol];
814 if (previousValue) {
815 target.removeEventListener(eventName, wrapFn);
816 }
817 // issue #978, when onload handler was added before loading zone.js
818 // we should remove it with originalDescSet
819 if (originalDescSet) {
820 originalDescSet.apply(target, NULL_ON_PROP_VALUE);
821 }
822 if (typeof newValue === 'function') {
823 target[eventNameSymbol] = newValue;
824 target.addEventListener(eventName, wrapFn, false);
825 }
826 else {
827 target[eventNameSymbol] = null;
828 }
829 };
830 // The getter would return undefined for unassigned properties but the default value of an
831 // unassigned property is null
832 desc.get = function () {
833 // in some of windows's onproperty callback, this is undefined
834 // so we need to check it
835 let target = this;
836 if (!target && obj === _global) {
837 target = _global;
838 }
839 if (!target) {
840 return null;
841 }
842 const listener = target[eventNameSymbol];
843 if (listener) {
844 return listener;
845 }
846 else if (originalDescGet) {
847 // result will be null when use inline event attribute,
848 // such as <button onclick="func();">OK</button>
849 // because the onclick function is internal raw uncompiled handler
850 // the onclick will be evaluated when first time event was triggered or
851 // the property is accessed, https://github.com/angular/zone.js/issues/525
852 // so we should use original native get to retrieve the handler
853 let value = originalDescGet && originalDescGet.call(this);
854 if (value) {
855 desc.set.call(this, value);
856 if (typeof target[REMOVE_ATTRIBUTE] === 'function') {
857 target.removeAttribute(prop);
858 }
859 return value;
860 }
861 }
862 return null;
863 };
864 ObjectDefineProperty(obj, prop, desc);
865 obj[onPropPatchedSymbol] = true;
866}
867function patchOnProperties(obj, properties, prototype) {
868 if (properties) {
869 for (let i = 0; i < properties.length; i++) {
870 patchProperty(obj, 'on' + properties[i], prototype);
871 }
872 }
873 else {
874 const onProperties = [];
875 for (const prop in obj) {
876 if (prop.substr(0, 2) == 'on') {
877 onProperties.push(prop);
878 }
879 }
880 for (let j = 0; j < onProperties.length; j++) {
881 patchProperty(obj, onProperties[j], prototype);
882 }
883 }
884}
885const originalInstanceKey = zoneSymbol('originalInstance');
886// wrap some native API on `window`
887function patchClass(className) {
888 const OriginalClass = _global[className];
889 if (!OriginalClass)
890 return;
891 // keep original class in global
892 _global[zoneSymbol(className)] = OriginalClass;
893 _global[className] = function () {
894 const a = bindArguments(arguments, className);
895 switch (a.length) {
896 case 0:
897 this[originalInstanceKey] = new OriginalClass();
898 break;
899 case 1:
900 this[originalInstanceKey] = new OriginalClass(a[0]);
901 break;
902 case 2:
903 this[originalInstanceKey] = new OriginalClass(a[0], a[1]);
904 break;
905 case 3:
906 this[originalInstanceKey] = new OriginalClass(a[0], a[1], a[2]);
907 break;
908 case 4:
909 this[originalInstanceKey] = new OriginalClass(a[0], a[1], a[2], a[3]);
910 break;
911 default:
912 throw new Error('Arg list too long.');
913 }
914 };
915 // attach original delegate to patched function
916 attachOriginToPatched(_global[className], OriginalClass);
917 const instance = new OriginalClass(function () { });
918 let prop;
919 for (prop in instance) {
920 // https://bugs.webkit.org/show_bug.cgi?id=44721
921 if (className === 'XMLHttpRequest' && prop === 'responseBlob')
922 continue;
923 (function (prop) {
924 if (typeof instance[prop] === 'function') {
925 _global[className].prototype[prop] = function () {
926 return this[originalInstanceKey][prop].apply(this[originalInstanceKey], arguments);
927 };
928 }
929 else {
930 ObjectDefineProperty(_global[className].prototype, prop, {
931 set: function (fn) {
932 if (typeof fn === 'function') {
933 this[originalInstanceKey][prop] = wrapWithCurrentZone(fn, className + '.' + prop);
934 // keep callback in wrapped function so we can
935 // use it in Function.prototype.toString to return
936 // the native one.
937 attachOriginToPatched(this[originalInstanceKey][prop], fn);
938 }
939 else {
940 this[originalInstanceKey][prop] = fn;
941 }
942 },
943 get: function () {
944 return this[originalInstanceKey][prop];
945 }
946 });
947 }
948 }(prop));
949 }
950 for (prop in OriginalClass) {
951 if (prop !== 'prototype' && OriginalClass.hasOwnProperty(prop)) {
952 _global[className][prop] = OriginalClass[prop];
953 }
954 }
955}
956function patchMethod(target, name, patchFn) {
957 let proto = target;
958 while (proto && !proto.hasOwnProperty(name)) {
959 proto = ObjectGetPrototypeOf(proto);
960 }
961 if (!proto && target[name]) {
962 // somehow we did not find it, but we can see it. This happens on IE for Window properties.
963 proto = target;
964 }
965 const delegateName = zoneSymbol(name);
966 let delegate = null;
967 if (proto && (!(delegate = proto[delegateName]) || !proto.hasOwnProperty(delegateName))) {
968 delegate = proto[delegateName] = proto[name];
969 // check whether proto[name] is writable
970 // some property is readonly in safari, such as HtmlCanvasElement.prototype.toBlob
971 const desc = proto && ObjectGetOwnPropertyDescriptor(proto, name);
972 if (isPropertyWritable(desc)) {
973 const patchDelegate = patchFn(delegate, delegateName, name);
974 proto[name] = function () {
975 return patchDelegate(this, arguments);
976 };
977 attachOriginToPatched(proto[name], delegate);
978 }
979 }
980 return delegate;
981}
982// TODO: @JiaLiPassion, support cancel task later if necessary
983function patchMacroTask(obj, funcName, metaCreator) {
984 let setNative = null;
985 function scheduleTask(task) {
986 const data = task.data;
987 data.args[data.cbIdx] = function () {
988 task.invoke.apply(this, arguments);
989 };
990 setNative.apply(data.target, data.args);
991 return task;
992 }
993 setNative = patchMethod(obj, funcName, (delegate) => function (self, args) {
994 const meta = metaCreator(self, args);
995 if (meta.cbIdx >= 0 && typeof args[meta.cbIdx] === 'function') {
996 return scheduleMacroTaskWithCurrentZone(meta.name, args[meta.cbIdx], meta, scheduleTask);
997 }
998 else {
999 // cause an error by calling it directly.
1000 return delegate.apply(self, args);
1001 }
1002 });
1003}
1004function attachOriginToPatched(patched, original) {
1005 patched[zoneSymbol('OriginalDelegate')] = original;
1006}
1007let isDetectedIEOrEdge = false;
1008let ieOrEdge = false;
1009function isIE() {
1010 try {
1011 const ua = internalWindow.navigator.userAgent;
1012 if (ua.indexOf('MSIE ') !== -1 || ua.indexOf('Trident/') !== -1) {
1013 return true;
1014 }
1015 }
1016 catch (error) {
1017 }
1018 return false;
1019}
1020function isIEOrEdge() {
1021 if (isDetectedIEOrEdge) {
1022 return ieOrEdge;
1023 }
1024 isDetectedIEOrEdge = true;
1025 try {
1026 const ua = internalWindow.navigator.userAgent;
1027 if (ua.indexOf('MSIE ') !== -1 || ua.indexOf('Trident/') !== -1 || ua.indexOf('Edge/') !== -1) {
1028 ieOrEdge = true;
1029 }
1030 }
1031 catch (error) {
1032 }
1033 return ieOrEdge;
1034}
1035
1036/**
1037 * @license
1038 * Copyright Google LLC All Rights Reserved.
1039 *
1040 * Use of this source code is governed by an MIT-style license that can be
1041 * found in the LICENSE file at https://angular.io/license
1042 */
1043Zone.__load_patch('ZoneAwarePromise', (global, Zone, api) => {
1044 const ObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
1045 const ObjectDefineProperty = Object.defineProperty;
1046 function readableObjectToString(obj) {
1047 if (obj && obj.toString === Object.prototype.toString) {
1048 const className = obj.constructor && obj.constructor.name;
1049 return (className ? className : '') + ': ' + JSON.stringify(obj);
1050 }
1051 return obj ? obj.toString() : Object.prototype.toString.call(obj);
1052 }
1053 const __symbol__ = api.symbol;
1054 const _uncaughtPromiseErrors = [];
1055 const isDisableWrappingUncaughtPromiseRejection = global[__symbol__('DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION')] === true;
1056 const symbolPromise = __symbol__('Promise');
1057 const symbolThen = __symbol__('then');
1058 const creationTrace = '__creationTrace__';
1059 api.onUnhandledError = (e) => {
1060 if (api.showUncaughtError()) {
1061 const rejection = e && e.rejection;
1062 if (rejection) {
1063 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);
1064 }
1065 else {
1066 console.error(e);
1067 }
1068 }
1069 };
1070 api.microtaskDrainDone = () => {
1071 while (_uncaughtPromiseErrors.length) {
1072 const uncaughtPromiseError = _uncaughtPromiseErrors.shift();
1073 try {
1074 uncaughtPromiseError.zone.runGuarded(() => {
1075 if (uncaughtPromiseError.throwOriginal) {
1076 throw uncaughtPromiseError.rejection;
1077 }
1078 throw uncaughtPromiseError;
1079 });
1080 }
1081 catch (error) {
1082 handleUnhandledRejection(error);
1083 }
1084 }
1085 };
1086 const UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL = __symbol__('unhandledPromiseRejectionHandler');
1087 function handleUnhandledRejection(e) {
1088 api.onUnhandledError(e);
1089 try {
1090 const handler = Zone[UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL];
1091 if (typeof handler === 'function') {
1092 handler.call(this, e);
1093 }
1094 }
1095 catch (err) {
1096 }
1097 }
1098 function isThenable(value) {
1099 return value && value.then;
1100 }
1101 function forwardResolution(value) {
1102 return value;
1103 }
1104 function forwardRejection(rejection) {
1105 return ZoneAwarePromise.reject(rejection);
1106 }
1107 const symbolState = __symbol__('state');
1108 const symbolValue = __symbol__('value');
1109 const symbolFinally = __symbol__('finally');
1110 const symbolParentPromiseValue = __symbol__('parentPromiseValue');
1111 const symbolParentPromiseState = __symbol__('parentPromiseState');
1112 const source = 'Promise.then';
1113 const UNRESOLVED = null;
1114 const RESOLVED = true;
1115 const REJECTED = false;
1116 const REJECTED_NO_CATCH = 0;
1117 function makeResolver(promise, state) {
1118 return (v) => {
1119 try {
1120 resolvePromise(promise, state, v);
1121 }
1122 catch (err) {
1123 resolvePromise(promise, false, err);
1124 }
1125 // Do not return value or you will break the Promise spec.
1126 };
1127 }
1128 const once = function () {
1129 let wasCalled = false;
1130 return function wrapper(wrappedFunction) {
1131 return function () {
1132 if (wasCalled) {
1133 return;
1134 }
1135 wasCalled = true;
1136 wrappedFunction.apply(null, arguments);
1137 };
1138 };
1139 };
1140 const TYPE_ERROR = 'Promise resolved with itself';
1141 const CURRENT_TASK_TRACE_SYMBOL = __symbol__('currentTaskTrace');
1142 // Promise Resolution
1143 function resolvePromise(promise, state, value) {
1144 const onceWrapper = once();
1145 if (promise === value) {
1146 throw new TypeError(TYPE_ERROR);
1147 }
1148 if (promise[symbolState] === UNRESOLVED) {
1149 // should only get value.then once based on promise spec.
1150 let then = null;
1151 try {
1152 if (typeof value === 'object' || typeof value === 'function') {
1153 then = value && value.then;
1154 }
1155 }
1156 catch (err) {
1157 onceWrapper(() => {
1158 resolvePromise(promise, false, err);
1159 })();
1160 return promise;
1161 }
1162 // if (value instanceof ZoneAwarePromise) {
1163 if (state !== REJECTED && value instanceof ZoneAwarePromise &&
1164 value.hasOwnProperty(symbolState) && value.hasOwnProperty(symbolValue) &&
1165 value[symbolState] !== UNRESOLVED) {
1166 clearRejectedNoCatch(value);
1167 resolvePromise(promise, value[symbolState], value[symbolValue]);
1168 }
1169 else if (state !== REJECTED && typeof then === 'function') {
1170 try {
1171 then.call(value, onceWrapper(makeResolver(promise, state)), onceWrapper(makeResolver(promise, false)));
1172 }
1173 catch (err) {
1174 onceWrapper(() => {
1175 resolvePromise(promise, false, err);
1176 })();
1177 }
1178 }
1179 else {
1180 promise[symbolState] = state;
1181 const queue = promise[symbolValue];
1182 promise[symbolValue] = value;
1183 if (promise[symbolFinally] === symbolFinally) {
1184 // the promise is generated by Promise.prototype.finally
1185 if (state === RESOLVED) {
1186 // the state is resolved, should ignore the value
1187 // and use parent promise value
1188 promise[symbolState] = promise[symbolParentPromiseState];
1189 promise[symbolValue] = promise[symbolParentPromiseValue];
1190 }
1191 }
1192 // record task information in value when error occurs, so we can
1193 // do some additional work such as render longStackTrace
1194 if (state === REJECTED && value instanceof Error) {
1195 // check if longStackTraceZone is here
1196 const trace = Zone.currentTask && Zone.currentTask.data &&
1197 Zone.currentTask.data[creationTrace];
1198 if (trace) {
1199 // only keep the long stack trace into error when in longStackTraceZone
1200 ObjectDefineProperty(value, CURRENT_TASK_TRACE_SYMBOL, { configurable: true, enumerable: false, writable: true, value: trace });
1201 }
1202 }
1203 for (let i = 0; i < queue.length;) {
1204 scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]);
1205 }
1206 if (queue.length == 0 && state == REJECTED) {
1207 promise[symbolState] = REJECTED_NO_CATCH;
1208 let uncaughtPromiseError = value;
1209 try {
1210 // Here we throws a new Error to print more readable error log
1211 // and if the value is not an error, zone.js builds an `Error`
1212 // Object here to attach the stack information.
1213 throw new Error('Uncaught (in promise): ' + readableObjectToString(value) +
1214 (value && value.stack ? '\n' + value.stack : ''));
1215 }
1216 catch (err) {
1217 uncaughtPromiseError = err;
1218 }
1219 if (isDisableWrappingUncaughtPromiseRejection) {
1220 // If disable wrapping uncaught promise reject
1221 // use the value instead of wrapping it.
1222 uncaughtPromiseError.throwOriginal = true;
1223 }
1224 uncaughtPromiseError.rejection = value;
1225 uncaughtPromiseError.promise = promise;
1226 uncaughtPromiseError.zone = Zone.current;
1227 uncaughtPromiseError.task = Zone.currentTask;
1228 _uncaughtPromiseErrors.push(uncaughtPromiseError);
1229 api.scheduleMicroTask(); // to make sure that it is running
1230 }
1231 }
1232 }
1233 // Resolving an already resolved promise is a noop.
1234 return promise;
1235 }
1236 const REJECTION_HANDLED_HANDLER = __symbol__('rejectionHandledHandler');
1237 function clearRejectedNoCatch(promise) {
1238 if (promise[symbolState] === REJECTED_NO_CATCH) {
1239 // if the promise is rejected no catch status
1240 // and queue.length > 0, means there is a error handler
1241 // here to handle the rejected promise, we should trigger
1242 // windows.rejectionhandled eventHandler or nodejs rejectionHandled
1243 // eventHandler
1244 try {
1245 const handler = Zone[REJECTION_HANDLED_HANDLER];
1246 if (handler && typeof handler === 'function') {
1247 handler.call(this, { rejection: promise[symbolValue], promise: promise });
1248 }
1249 }
1250 catch (err) {
1251 }
1252 promise[symbolState] = REJECTED;
1253 for (let i = 0; i < _uncaughtPromiseErrors.length; i++) {
1254 if (promise === _uncaughtPromiseErrors[i].promise) {
1255 _uncaughtPromiseErrors.splice(i, 1);
1256 }
1257 }
1258 }
1259 }
1260 function scheduleResolveOrReject(promise, zone, chainPromise, onFulfilled, onRejected) {
1261 clearRejectedNoCatch(promise);
1262 const promiseState = promise[symbolState];
1263 const delegate = promiseState ?
1264 (typeof onFulfilled === 'function') ? onFulfilled : forwardResolution :
1265 (typeof onRejected === 'function') ? onRejected : forwardRejection;
1266 zone.scheduleMicroTask(source, () => {
1267 try {
1268 const parentPromiseValue = promise[symbolValue];
1269 const isFinallyPromise = !!chainPromise && symbolFinally === chainPromise[symbolFinally];
1270 if (isFinallyPromise) {
1271 // if the promise is generated from finally call, keep parent promise's state and value
1272 chainPromise[symbolParentPromiseValue] = parentPromiseValue;
1273 chainPromise[symbolParentPromiseState] = promiseState;
1274 }
1275 // should not pass value to finally callback
1276 const value = zone.run(delegate, undefined, isFinallyPromise && delegate !== forwardRejection && delegate !== forwardResolution ?
1277 [] :
1278 [parentPromiseValue]);
1279 resolvePromise(chainPromise, true, value);
1280 }
1281 catch (error) {
1282 // if error occurs, should always return this error
1283 resolvePromise(chainPromise, false, error);
1284 }
1285 }, chainPromise);
1286 }
1287 const ZONE_AWARE_PROMISE_TO_STRING = 'function ZoneAwarePromise() { [native code] }';
1288 const noop = function () { };
1289 class ZoneAwarePromise {
1290 static toString() {
1291 return ZONE_AWARE_PROMISE_TO_STRING;
1292 }
1293 static resolve(value) {
1294 return resolvePromise(new this(null), RESOLVED, value);
1295 }
1296 static reject(error) {
1297 return resolvePromise(new this(null), REJECTED, error);
1298 }
1299 static race(values) {
1300 let resolve;
1301 let reject;
1302 let promise = new this((res, rej) => {
1303 resolve = res;
1304 reject = rej;
1305 });
1306 function onResolve(value) {
1307 resolve(value);
1308 }
1309 function onReject(error) {
1310 reject(error);
1311 }
1312 for (let value of values) {
1313 if (!isThenable(value)) {
1314 value = this.resolve(value);
1315 }
1316 value.then(onResolve, onReject);
1317 }
1318 return promise;
1319 }
1320 static all(values) {
1321 return ZoneAwarePromise.allWithCallback(values);
1322 }
1323 static allSettled(values) {
1324 const P = this && this.prototype instanceof ZoneAwarePromise ? this : ZoneAwarePromise;
1325 return P.allWithCallback(values, {
1326 thenCallback: (value) => ({ status: 'fulfilled', value }),
1327 errorCallback: (err) => ({ status: 'rejected', reason: err })
1328 });
1329 }
1330 static allWithCallback(values, callback) {
1331 let resolve;
1332 let reject;
1333 let promise = new this((res, rej) => {
1334 resolve = res;
1335 reject = rej;
1336 });
1337 // Start at 2 to prevent prematurely resolving if .then is called immediately.
1338 let unresolvedCount = 2;
1339 let valueIndex = 0;
1340 const resolvedValues = [];
1341 for (let value of values) {
1342 if (!isThenable(value)) {
1343 value = this.resolve(value);
1344 }
1345 const curValueIndex = valueIndex;
1346 try {
1347 value.then((value) => {
1348 resolvedValues[curValueIndex] = callback ? callback.thenCallback(value) : value;
1349 unresolvedCount--;
1350 if (unresolvedCount === 0) {
1351 resolve(resolvedValues);
1352 }
1353 }, (err) => {
1354 if (!callback) {
1355 reject(err);
1356 }
1357 else {
1358 resolvedValues[curValueIndex] = callback.errorCallback(err);
1359 unresolvedCount--;
1360 if (unresolvedCount === 0) {
1361 resolve(resolvedValues);
1362 }
1363 }
1364 });
1365 }
1366 catch (thenErr) {
1367 reject(thenErr);
1368 }
1369 unresolvedCount++;
1370 valueIndex++;
1371 }
1372 // Make the unresolvedCount zero-based again.
1373 unresolvedCount -= 2;
1374 if (unresolvedCount === 0) {
1375 resolve(resolvedValues);
1376 }
1377 return promise;
1378 }
1379 constructor(executor) {
1380 const promise = this;
1381 if (!(promise instanceof ZoneAwarePromise)) {
1382 throw new Error('Must be an instanceof Promise.');
1383 }
1384 promise[symbolState] = UNRESOLVED;
1385 promise[symbolValue] = []; // queue;
1386 try {
1387 executor && executor(makeResolver(promise, RESOLVED), makeResolver(promise, REJECTED));
1388 }
1389 catch (error) {
1390 resolvePromise(promise, false, error);
1391 }
1392 }
1393 get [Symbol.toStringTag]() {
1394 return 'Promise';
1395 }
1396 get [Symbol.species]() {
1397 return ZoneAwarePromise;
1398 }
1399 then(onFulfilled, onRejected) {
1400 let C = this.constructor[Symbol.species];
1401 if (!C || typeof C !== 'function') {
1402 C = this.constructor || ZoneAwarePromise;
1403 }
1404 const chainPromise = new C(noop);
1405 const zone = Zone.current;
1406 if (this[symbolState] == UNRESOLVED) {
1407 this[symbolValue].push(zone, chainPromise, onFulfilled, onRejected);
1408 }
1409 else {
1410 scheduleResolveOrReject(this, zone, chainPromise, onFulfilled, onRejected);
1411 }
1412 return chainPromise;
1413 }
1414 catch(onRejected) {
1415 return this.then(null, onRejected);
1416 }
1417 finally(onFinally) {
1418 let C = this.constructor[Symbol.species];
1419 if (!C || typeof C !== 'function') {
1420 C = ZoneAwarePromise;
1421 }
1422 const chainPromise = new C(noop);
1423 chainPromise[symbolFinally] = symbolFinally;
1424 const zone = Zone.current;
1425 if (this[symbolState] == UNRESOLVED) {
1426 this[symbolValue].push(zone, chainPromise, onFinally, onFinally);
1427 }
1428 else {
1429 scheduleResolveOrReject(this, zone, chainPromise, onFinally, onFinally);
1430 }
1431 return chainPromise;
1432 }
1433 }
1434 // Protect against aggressive optimizers dropping seemingly unused properties.
1435 // E.g. Closure Compiler in advanced mode.
1436 ZoneAwarePromise['resolve'] = ZoneAwarePromise.resolve;
1437 ZoneAwarePromise['reject'] = ZoneAwarePromise.reject;
1438 ZoneAwarePromise['race'] = ZoneAwarePromise.race;
1439 ZoneAwarePromise['all'] = ZoneAwarePromise.all;
1440 const NativePromise = global[symbolPromise] = global['Promise'];
1441 global['Promise'] = ZoneAwarePromise;
1442 const symbolThenPatched = __symbol__('thenPatched');
1443 function patchThen(Ctor) {
1444 const proto = Ctor.prototype;
1445 const prop = ObjectGetOwnPropertyDescriptor(proto, 'then');
1446 if (prop && (prop.writable === false || !prop.configurable)) {
1447 // check Ctor.prototype.then propertyDescriptor is writable or not
1448 // in meteor env, writable is false, we should ignore such case
1449 return;
1450 }
1451 const originalThen = proto.then;
1452 // Keep a reference to the original method.
1453 proto[symbolThen] = originalThen;
1454 Ctor.prototype.then = function (onResolve, onReject) {
1455 const wrapped = new ZoneAwarePromise((resolve, reject) => {
1456 originalThen.call(this, resolve, reject);
1457 });
1458 return wrapped.then(onResolve, onReject);
1459 };
1460 Ctor[symbolThenPatched] = true;
1461 }
1462 api.patchThen = patchThen;
1463 function zoneify(fn) {
1464 return function (self, args) {
1465 let resultPromise = fn.apply(self, args);
1466 if (resultPromise instanceof ZoneAwarePromise) {
1467 return resultPromise;
1468 }
1469 let ctor = resultPromise.constructor;
1470 if (!ctor[symbolThenPatched]) {
1471 patchThen(ctor);
1472 }
1473 return resultPromise;
1474 };
1475 }
1476 if (NativePromise) {
1477 patchThen(NativePromise);
1478 patchMethod(global, 'fetch', delegate => zoneify(delegate));
1479 }
1480 // This is not part of public API, but it is useful for tests, so we expose it.
1481 Promise[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors;
1482 return ZoneAwarePromise;
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 */
1492// override Function.prototype.toString to make zone.js patched function
1493// look like native function
1494Zone.__load_patch('toString', (global) => {
1495 // patch Func.prototype.toString to let them look like native
1496 const originalFunctionToString = Function.prototype.toString;
1497 const ORIGINAL_DELEGATE_SYMBOL = zoneSymbol('OriginalDelegate');
1498 const PROMISE_SYMBOL = zoneSymbol('Promise');
1499 const ERROR_SYMBOL = zoneSymbol('Error');
1500 const newFunctionToString = function toString() {
1501 if (typeof this === 'function') {
1502 const originalDelegate = this[ORIGINAL_DELEGATE_SYMBOL];
1503 if (originalDelegate) {
1504 if (typeof originalDelegate === 'function') {
1505 return originalFunctionToString.call(originalDelegate);
1506 }
1507 else {
1508 return Object.prototype.toString.call(originalDelegate);
1509 }
1510 }
1511 if (this === Promise) {
1512 const nativePromise = global[PROMISE_SYMBOL];
1513 if (nativePromise) {
1514 return originalFunctionToString.call(nativePromise);
1515 }
1516 }
1517 if (this === Error) {
1518 const nativeError = global[ERROR_SYMBOL];
1519 if (nativeError) {
1520 return originalFunctionToString.call(nativeError);
1521 }
1522 }
1523 }
1524 return originalFunctionToString.call(this);
1525 };
1526 newFunctionToString[ORIGINAL_DELEGATE_SYMBOL] = originalFunctionToString;
1527 Function.prototype.toString = newFunctionToString;
1528 // patch Object.prototype.toString to let them look like native
1529 const originalObjectToString = Object.prototype.toString;
1530 const PROMISE_OBJECT_TO_STRING = '[object Promise]';
1531 Object.prototype.toString = function () {
1532 if (typeof Promise === 'function' && this instanceof Promise) {
1533 return PROMISE_OBJECT_TO_STRING;
1534 }
1535 return originalObjectToString.call(this);
1536 };
1537});
1538
1539/**
1540 * @license
1541 * Copyright Google LLC All Rights Reserved.
1542 *
1543 * Use of this source code is governed by an MIT-style license that can be
1544 * found in the LICENSE file at https://angular.io/license
1545 */
1546let passiveSupported = false;
1547if (typeof window !== 'undefined') {
1548 try {
1549 const options = Object.defineProperty({}, 'passive', {
1550 get: function () {
1551 passiveSupported = true;
1552 }
1553 });
1554 window.addEventListener('test', options, options);
1555 window.removeEventListener('test', options, options);
1556 }
1557 catch (err) {
1558 passiveSupported = false;
1559 }
1560}
1561// an identifier to tell ZoneTask do not create a new invoke closure
1562const OPTIMIZED_ZONE_EVENT_TASK_DATA = {
1563 useG: true
1564};
1565const zoneSymbolEventNames$1 = {};
1566const globalSources = {};
1567const EVENT_NAME_SYMBOL_REGX = new RegExp('^' + ZONE_SYMBOL_PREFIX + '(\\w+)(true|false)$');
1568const IMMEDIATE_PROPAGATION_SYMBOL = zoneSymbol('propagationStopped');
1569function prepareEventNames(eventName, eventNameToString) {
1570 const falseEventName = (eventNameToString ? eventNameToString(eventName) : eventName) + FALSE_STR;
1571 const trueEventName = (eventNameToString ? eventNameToString(eventName) : eventName) + TRUE_STR;
1572 const symbol = ZONE_SYMBOL_PREFIX + falseEventName;
1573 const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName;
1574 zoneSymbolEventNames$1[eventName] = {};
1575 zoneSymbolEventNames$1[eventName][FALSE_STR] = symbol;
1576 zoneSymbolEventNames$1[eventName][TRUE_STR] = symbolCapture;
1577}
1578function patchEventTarget(_global, apis, patchOptions) {
1579 const ADD_EVENT_LISTENER = (patchOptions && patchOptions.add) || ADD_EVENT_LISTENER_STR;
1580 const REMOVE_EVENT_LISTENER = (patchOptions && patchOptions.rm) || REMOVE_EVENT_LISTENER_STR;
1581 const LISTENERS_EVENT_LISTENER = (patchOptions && patchOptions.listeners) || 'eventListeners';
1582 const REMOVE_ALL_LISTENERS_EVENT_LISTENER = (patchOptions && patchOptions.rmAll) || 'removeAllListeners';
1583 const zoneSymbolAddEventListener = zoneSymbol(ADD_EVENT_LISTENER);
1584 const ADD_EVENT_LISTENER_SOURCE = '.' + ADD_EVENT_LISTENER + ':';
1585 const PREPEND_EVENT_LISTENER = 'prependListener';
1586 const PREPEND_EVENT_LISTENER_SOURCE = '.' + PREPEND_EVENT_LISTENER + ':';
1587 const invokeTask = function (task, target, event) {
1588 // for better performance, check isRemoved which is set
1589 // by removeEventListener
1590 if (task.isRemoved) {
1591 return;
1592 }
1593 const delegate = task.callback;
1594 if (typeof delegate === 'object' && delegate.handleEvent) {
1595 // create the bind version of handleEvent when invoke
1596 task.callback = (event) => delegate.handleEvent(event);
1597 task.originalDelegate = delegate;
1598 }
1599 // invoke static task.invoke
1600 task.invoke(task, target, [event]);
1601 const options = task.options;
1602 if (options && typeof options === 'object' && options.once) {
1603 // if options.once is true, after invoke once remove listener here
1604 // only browser need to do this, nodejs eventEmitter will cal removeListener
1605 // inside EventEmitter.once
1606 const delegate = task.originalDelegate ? task.originalDelegate : task.callback;
1607 target[REMOVE_EVENT_LISTENER].call(target, event.type, delegate, options);
1608 }
1609 };
1610 // global shared zoneAwareCallback to handle all event callback with capture = false
1611 const globalZoneAwareCallback = function (event) {
1612 // https://github.com/angular/zone.js/issues/911, in IE, sometimes
1613 // event will be undefined, so we need to use window.event
1614 event = event || _global.event;
1615 if (!event) {
1616 return;
1617 }
1618 // event.target is needed for Samsung TV and SourceBuffer
1619 // || global is needed https://github.com/angular/zone.js/issues/190
1620 const target = this || event.target || _global;
1621 const tasks = target[zoneSymbolEventNames$1[event.type][FALSE_STR]];
1622 if (tasks) {
1623 // invoke all tasks which attached to current target with given event.type and capture = false
1624 // for performance concern, if task.length === 1, just invoke
1625 if (tasks.length === 1) {
1626 invokeTask(tasks[0], target, event);
1627 }
1628 else {
1629 // https://github.com/angular/zone.js/issues/836
1630 // copy the tasks array before invoke, to avoid
1631 // the callback will remove itself or other listener
1632 const copyTasks = tasks.slice();
1633 for (let i = 0; i < copyTasks.length; i++) {
1634 if (event && event[IMMEDIATE_PROPAGATION_SYMBOL] === true) {
1635 break;
1636 }
1637 invokeTask(copyTasks[i], target, event);
1638 }
1639 }
1640 }
1641 };
1642 // global shared zoneAwareCallback to handle all event callback with capture = true
1643 const globalZoneAwareCaptureCallback = function (event) {
1644 // https://github.com/angular/zone.js/issues/911, in IE, sometimes
1645 // event will be undefined, so we need to use window.event
1646 event = event || _global.event;
1647 if (!event) {
1648 return;
1649 }
1650 // event.target is needed for Samsung TV and SourceBuffer
1651 // || global is needed https://github.com/angular/zone.js/issues/190
1652 const target = this || event.target || _global;
1653 const tasks = target[zoneSymbolEventNames$1[event.type][TRUE_STR]];
1654 if (tasks) {
1655 // invoke all tasks which attached to current target with given event.type and capture = false
1656 // for performance concern, if task.length === 1, just invoke
1657 if (tasks.length === 1) {
1658 invokeTask(tasks[0], target, event);
1659 }
1660 else {
1661 // https://github.com/angular/zone.js/issues/836
1662 // copy the tasks array before invoke, to avoid
1663 // the callback will remove itself or other listener
1664 const copyTasks = tasks.slice();
1665 for (let i = 0; i < copyTasks.length; i++) {
1666 if (event && event[IMMEDIATE_PROPAGATION_SYMBOL] === true) {
1667 break;
1668 }
1669 invokeTask(copyTasks[i], target, event);
1670 }
1671 }
1672 }
1673 };
1674 function patchEventTargetMethods(obj, patchOptions) {
1675 if (!obj) {
1676 return false;
1677 }
1678 let useGlobalCallback = true;
1679 if (patchOptions && patchOptions.useG !== undefined) {
1680 useGlobalCallback = patchOptions.useG;
1681 }
1682 const validateHandler = patchOptions && patchOptions.vh;
1683 let checkDuplicate = true;
1684 if (patchOptions && patchOptions.chkDup !== undefined) {
1685 checkDuplicate = patchOptions.chkDup;
1686 }
1687 let returnTarget = false;
1688 if (patchOptions && patchOptions.rt !== undefined) {
1689 returnTarget = patchOptions.rt;
1690 }
1691 let proto = obj;
1692 while (proto && !proto.hasOwnProperty(ADD_EVENT_LISTENER)) {
1693 proto = ObjectGetPrototypeOf(proto);
1694 }
1695 if (!proto && obj[ADD_EVENT_LISTENER]) {
1696 // somehow we did not find it, but we can see it. This happens on IE for Window properties.
1697 proto = obj;
1698 }
1699 if (!proto) {
1700 return false;
1701 }
1702 if (proto[zoneSymbolAddEventListener]) {
1703 return false;
1704 }
1705 const eventNameToString = patchOptions && patchOptions.eventNameToString;
1706 // a shared global taskData to pass data for scheduleEventTask
1707 // so we do not need to create a new object just for pass some data
1708 const taskData = {};
1709 const nativeAddEventListener = proto[zoneSymbolAddEventListener] = proto[ADD_EVENT_LISTENER];
1710 const nativeRemoveEventListener = proto[zoneSymbol(REMOVE_EVENT_LISTENER)] =
1711 proto[REMOVE_EVENT_LISTENER];
1712 const nativeListeners = proto[zoneSymbol(LISTENERS_EVENT_LISTENER)] =
1713 proto[LISTENERS_EVENT_LISTENER];
1714 const nativeRemoveAllListeners = proto[zoneSymbol(REMOVE_ALL_LISTENERS_EVENT_LISTENER)] =
1715 proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER];
1716 let nativePrependEventListener;
1717 if (patchOptions && patchOptions.prepend) {
1718 nativePrependEventListener = proto[zoneSymbol(patchOptions.prepend)] =
1719 proto[patchOptions.prepend];
1720 }
1721 /**
1722 * This util function will build an option object with passive option
1723 * to handle all possible input from the user.
1724 */
1725 function buildEventListenerOptions(options, passive) {
1726 if (!passiveSupported && typeof options === 'object' && options) {
1727 // doesn't support passive but user want to pass an object as options.
1728 // this will not work on some old browser, so we just pass a boolean
1729 // as useCapture parameter
1730 return !!options.capture;
1731 }
1732 if (!passiveSupported || !passive) {
1733 return options;
1734 }
1735 if (typeof options === 'boolean') {
1736 return { capture: options, passive: true };
1737 }
1738 if (!options) {
1739 return { passive: true };
1740 }
1741 if (typeof options === 'object' && options.passive !== false) {
1742 return Object.assign(Object.assign({}, options), { passive: true });
1743 }
1744 return options;
1745 }
1746 const customScheduleGlobal = function (task) {
1747 // if there is already a task for the eventName + capture,
1748 // just return, because we use the shared globalZoneAwareCallback here.
1749 if (taskData.isExisting) {
1750 return;
1751 }
1752 return nativeAddEventListener.call(taskData.target, taskData.eventName, taskData.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback, taskData.options);
1753 };
1754 const customCancelGlobal = function (task) {
1755 // if task is not marked as isRemoved, this call is directly
1756 // from Zone.prototype.cancelTask, we should remove the task
1757 // from tasksList of target first
1758 if (!task.isRemoved) {
1759 const symbolEventNames = zoneSymbolEventNames$1[task.eventName];
1760 let symbolEventName;
1761 if (symbolEventNames) {
1762 symbolEventName = symbolEventNames[task.capture ? TRUE_STR : FALSE_STR];
1763 }
1764 const existingTasks = symbolEventName && task.target[symbolEventName];
1765 if (existingTasks) {
1766 for (let i = 0; i < existingTasks.length; i++) {
1767 const existingTask = existingTasks[i];
1768 if (existingTask === task) {
1769 existingTasks.splice(i, 1);
1770 // set isRemoved to data for faster invokeTask check
1771 task.isRemoved = true;
1772 if (existingTasks.length === 0) {
1773 // all tasks for the eventName + capture have gone,
1774 // remove globalZoneAwareCallback and remove the task cache from target
1775 task.allRemoved = true;
1776 task.target[symbolEventName] = null;
1777 }
1778 break;
1779 }
1780 }
1781 }
1782 }
1783 // if all tasks for the eventName + capture have gone,
1784 // we will really remove the global event callback,
1785 // if not, return
1786 if (!task.allRemoved) {
1787 return;
1788 }
1789 return nativeRemoveEventListener.call(task.target, task.eventName, task.capture ? globalZoneAwareCaptureCallback : globalZoneAwareCallback, task.options);
1790 };
1791 const customScheduleNonGlobal = function (task) {
1792 return nativeAddEventListener.call(taskData.target, taskData.eventName, task.invoke, taskData.options);
1793 };
1794 const customSchedulePrepend = function (task) {
1795 return nativePrependEventListener.call(taskData.target, taskData.eventName, task.invoke, taskData.options);
1796 };
1797 const customCancelNonGlobal = function (task) {
1798 return nativeRemoveEventListener.call(task.target, task.eventName, task.invoke, task.options);
1799 };
1800 const customSchedule = useGlobalCallback ? customScheduleGlobal : customScheduleNonGlobal;
1801 const customCancel = useGlobalCallback ? customCancelGlobal : customCancelNonGlobal;
1802 const compareTaskCallbackVsDelegate = function (task, delegate) {
1803 const typeOfDelegate = typeof delegate;
1804 return (typeOfDelegate === 'function' && task.callback === delegate) ||
1805 (typeOfDelegate === 'object' && task.originalDelegate === delegate);
1806 };
1807 const compare = (patchOptions && patchOptions.diff) ? patchOptions.diff : compareTaskCallbackVsDelegate;
1808 const unpatchedEvents = Zone[zoneSymbol('UNPATCHED_EVENTS')];
1809 const passiveEvents = _global[zoneSymbol('PASSIVE_EVENTS')];
1810 const makeAddListener = function (nativeListener, addSource, customScheduleFn, customCancelFn, returnTarget = false, prepend = false) {
1811 return function () {
1812 const target = this || _global;
1813 let eventName = arguments[0];
1814 if (patchOptions && patchOptions.transferEventName) {
1815 eventName = patchOptions.transferEventName(eventName);
1816 }
1817 let delegate = arguments[1];
1818 if (!delegate) {
1819 return nativeListener.apply(this, arguments);
1820 }
1821 if (isNode && eventName === 'uncaughtException') {
1822 // don't patch uncaughtException of nodejs to prevent endless loop
1823 return nativeListener.apply(this, arguments);
1824 }
1825 // don't create the bind delegate function for handleEvent
1826 // case here to improve addEventListener performance
1827 // we will create the bind delegate when invoke
1828 let isHandleEvent = false;
1829 if (typeof delegate !== 'function') {
1830 if (!delegate.handleEvent) {
1831 return nativeListener.apply(this, arguments);
1832 }
1833 isHandleEvent = true;
1834 }
1835 if (validateHandler && !validateHandler(nativeListener, delegate, target, arguments)) {
1836 return;
1837 }
1838 const passive = passiveSupported && !!passiveEvents && passiveEvents.indexOf(eventName) !== -1;
1839 const options = buildEventListenerOptions(arguments[2], passive);
1840 if (unpatchedEvents) {
1841 // check upatched list
1842 for (let i = 0; i < unpatchedEvents.length; i++) {
1843 if (eventName === unpatchedEvents[i]) {
1844 if (passive) {
1845 return nativeListener.call(target, eventName, delegate, options);
1846 }
1847 else {
1848 return nativeListener.apply(this, arguments);
1849 }
1850 }
1851 }
1852 }
1853 const capture = !options ? false : typeof options === 'boolean' ? true : options.capture;
1854 const once = options && typeof options === 'object' ? options.once : false;
1855 const zone = Zone.current;
1856 let symbolEventNames = zoneSymbolEventNames$1[eventName];
1857 if (!symbolEventNames) {
1858 prepareEventNames(eventName, eventNameToString);
1859 symbolEventNames = zoneSymbolEventNames$1[eventName];
1860 }
1861 const symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR];
1862 let existingTasks = target[symbolEventName];
1863 let isExisting = false;
1864 if (existingTasks) {
1865 // already have task registered
1866 isExisting = true;
1867 if (checkDuplicate) {
1868 for (let i = 0; i < existingTasks.length; i++) {
1869 if (compare(existingTasks[i], delegate)) {
1870 // same callback, same capture, same event name, just return
1871 return;
1872 }
1873 }
1874 }
1875 }
1876 else {
1877 existingTasks = target[symbolEventName] = [];
1878 }
1879 let source;
1880 const constructorName = target.constructor['name'];
1881 const targetSource = globalSources[constructorName];
1882 if (targetSource) {
1883 source = targetSource[eventName];
1884 }
1885 if (!source) {
1886 source = constructorName + addSource +
1887 (eventNameToString ? eventNameToString(eventName) : eventName);
1888 }
1889 // do not create a new object as task.data to pass those things
1890 // just use the global shared one
1891 taskData.options = options;
1892 if (once) {
1893 // if addEventListener with once options, we don't pass it to
1894 // native addEventListener, instead we keep the once setting
1895 // and handle ourselves.
1896 taskData.options.once = false;
1897 }
1898 taskData.target = target;
1899 taskData.capture = capture;
1900 taskData.eventName = eventName;
1901 taskData.isExisting = isExisting;
1902 const data = useGlobalCallback ? OPTIMIZED_ZONE_EVENT_TASK_DATA : undefined;
1903 // keep taskData into data to allow onScheduleEventTask to access the task information
1904 if (data) {
1905 data.taskData = taskData;
1906 }
1907 const task = zone.scheduleEventTask(source, delegate, data, customScheduleFn, customCancelFn);
1908 // should clear taskData.target to avoid memory leak
1909 // issue, https://github.com/angular/angular/issues/20442
1910 taskData.target = null;
1911 // need to clear up taskData because it is a global object
1912 if (data) {
1913 data.taskData = null;
1914 }
1915 // have to save those information to task in case
1916 // application may call task.zone.cancelTask() directly
1917 if (once) {
1918 options.once = true;
1919 }
1920 if (!(!passiveSupported && typeof task.options === 'boolean')) {
1921 // if not support passive, and we pass an option object
1922 // to addEventListener, we should save the options to task
1923 task.options = options;
1924 }
1925 task.target = target;
1926 task.capture = capture;
1927 task.eventName = eventName;
1928 if (isHandleEvent) {
1929 // save original delegate for compare to check duplicate
1930 task.originalDelegate = delegate;
1931 }
1932 if (!prepend) {
1933 existingTasks.push(task);
1934 }
1935 else {
1936 existingTasks.unshift(task);
1937 }
1938 if (returnTarget) {
1939 return target;
1940 }
1941 };
1942 };
1943 proto[ADD_EVENT_LISTENER] = makeAddListener(nativeAddEventListener, ADD_EVENT_LISTENER_SOURCE, customSchedule, customCancel, returnTarget);
1944 if (nativePrependEventListener) {
1945 proto[PREPEND_EVENT_LISTENER] = makeAddListener(nativePrependEventListener, PREPEND_EVENT_LISTENER_SOURCE, customSchedulePrepend, customCancel, returnTarget, true);
1946 }
1947 proto[REMOVE_EVENT_LISTENER] = function () {
1948 const target = this || _global;
1949 let eventName = arguments[0];
1950 if (patchOptions && patchOptions.transferEventName) {
1951 eventName = patchOptions.transferEventName(eventName);
1952 }
1953 const options = arguments[2];
1954 const capture = !options ? false : typeof options === 'boolean' ? true : options.capture;
1955 const delegate = arguments[1];
1956 if (!delegate) {
1957 return nativeRemoveEventListener.apply(this, arguments);
1958 }
1959 if (validateHandler &&
1960 !validateHandler(nativeRemoveEventListener, delegate, target, arguments)) {
1961 return;
1962 }
1963 const symbolEventNames = zoneSymbolEventNames$1[eventName];
1964 let symbolEventName;
1965 if (symbolEventNames) {
1966 symbolEventName = symbolEventNames[capture ? TRUE_STR : FALSE_STR];
1967 }
1968 const existingTasks = symbolEventName && target[symbolEventName];
1969 if (existingTasks) {
1970 for (let i = 0; i < existingTasks.length; i++) {
1971 const existingTask = existingTasks[i];
1972 if (compare(existingTask, delegate)) {
1973 existingTasks.splice(i, 1);
1974 // set isRemoved to data for faster invokeTask check
1975 existingTask.isRemoved = true;
1976 if (existingTasks.length === 0) {
1977 // all tasks for the eventName + capture have gone,
1978 // remove globalZoneAwareCallback and remove the task cache from target
1979 existingTask.allRemoved = true;
1980 target[symbolEventName] = null;
1981 // in the target, we have an event listener which is added by on_property
1982 // such as target.onclick = function() {}, so we need to clear this internal
1983 // property too if all delegates all removed
1984 if (typeof eventName === 'string') {
1985 const onPropertySymbol = ZONE_SYMBOL_PREFIX + 'ON_PROPERTY' + eventName;
1986 target[onPropertySymbol] = null;
1987 }
1988 }
1989 existingTask.zone.cancelTask(existingTask);
1990 if (returnTarget) {
1991 return target;
1992 }
1993 return;
1994 }
1995 }
1996 }
1997 // issue 930, didn't find the event name or callback
1998 // from zone kept existingTasks, the callback maybe
1999 // added outside of zone, we need to call native removeEventListener
2000 // to try to remove it.
2001 return nativeRemoveEventListener.apply(this, arguments);
2002 };
2003 proto[LISTENERS_EVENT_LISTENER] = function () {
2004 const target = this || _global;
2005 let eventName = arguments[0];
2006 if (patchOptions && patchOptions.transferEventName) {
2007 eventName = patchOptions.transferEventName(eventName);
2008 }
2009 const listeners = [];
2010 const tasks = findEventTasks(target, eventNameToString ? eventNameToString(eventName) : eventName);
2011 for (let i = 0; i < tasks.length; i++) {
2012 const task = tasks[i];
2013 let delegate = task.originalDelegate ? task.originalDelegate : task.callback;
2014 listeners.push(delegate);
2015 }
2016 return listeners;
2017 };
2018 proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER] = function () {
2019 const target = this || _global;
2020 let eventName = arguments[0];
2021 if (!eventName) {
2022 const keys = Object.keys(target);
2023 for (let i = 0; i < keys.length; i++) {
2024 const prop = keys[i];
2025 const match = EVENT_NAME_SYMBOL_REGX.exec(prop);
2026 let evtName = match && match[1];
2027 // in nodejs EventEmitter, removeListener event is
2028 // used for monitoring the removeListener call,
2029 // so just keep removeListener eventListener until
2030 // all other eventListeners are removed
2031 if (evtName && evtName !== 'removeListener') {
2032 this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, evtName);
2033 }
2034 }
2035 // remove removeListener listener finally
2036 this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, 'removeListener');
2037 }
2038 else {
2039 if (patchOptions && patchOptions.transferEventName) {
2040 eventName = patchOptions.transferEventName(eventName);
2041 }
2042 const symbolEventNames = zoneSymbolEventNames$1[eventName];
2043 if (symbolEventNames) {
2044 const symbolEventName = symbolEventNames[FALSE_STR];
2045 const symbolCaptureEventName = symbolEventNames[TRUE_STR];
2046 const tasks = target[symbolEventName];
2047 const captureTasks = target[symbolCaptureEventName];
2048 if (tasks) {
2049 const removeTasks = tasks.slice();
2050 for (let i = 0; i < removeTasks.length; i++) {
2051 const task = removeTasks[i];
2052 let delegate = task.originalDelegate ? task.originalDelegate : task.callback;
2053 this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options);
2054 }
2055 }
2056 if (captureTasks) {
2057 const removeTasks = captureTasks.slice();
2058 for (let i = 0; i < removeTasks.length; i++) {
2059 const task = removeTasks[i];
2060 let delegate = task.originalDelegate ? task.originalDelegate : task.callback;
2061 this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options);
2062 }
2063 }
2064 }
2065 }
2066 if (returnTarget) {
2067 return this;
2068 }
2069 };
2070 // for native toString patch
2071 attachOriginToPatched(proto[ADD_EVENT_LISTENER], nativeAddEventListener);
2072 attachOriginToPatched(proto[REMOVE_EVENT_LISTENER], nativeRemoveEventListener);
2073 if (nativeRemoveAllListeners) {
2074 attachOriginToPatched(proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER], nativeRemoveAllListeners);
2075 }
2076 if (nativeListeners) {
2077 attachOriginToPatched(proto[LISTENERS_EVENT_LISTENER], nativeListeners);
2078 }
2079 return true;
2080 }
2081 let results = [];
2082 for (let i = 0; i < apis.length; i++) {
2083 results[i] = patchEventTargetMethods(apis[i], patchOptions);
2084 }
2085 return results;
2086}
2087function findEventTasks(target, eventName) {
2088 if (!eventName) {
2089 const foundTasks = [];
2090 for (let prop in target) {
2091 const match = EVENT_NAME_SYMBOL_REGX.exec(prop);
2092 let evtName = match && match[1];
2093 if (evtName && (!eventName || evtName === eventName)) {
2094 const tasks = target[prop];
2095 if (tasks) {
2096 for (let i = 0; i < tasks.length; i++) {
2097 foundTasks.push(tasks[i]);
2098 }
2099 }
2100 }
2101 }
2102 return foundTasks;
2103 }
2104 let symbolEventName = zoneSymbolEventNames$1[eventName];
2105 if (!symbolEventName) {
2106 prepareEventNames(eventName);
2107 symbolEventName = zoneSymbolEventNames$1[eventName];
2108 }
2109 const captureFalseTasks = target[symbolEventName[FALSE_STR]];
2110 const captureTrueTasks = target[symbolEventName[TRUE_STR]];
2111 if (!captureFalseTasks) {
2112 return captureTrueTasks ? captureTrueTasks.slice() : [];
2113 }
2114 else {
2115 return captureTrueTasks ? captureFalseTasks.concat(captureTrueTasks) :
2116 captureFalseTasks.slice();
2117 }
2118}
2119function patchEventPrototype(global, api) {
2120 const Event = global['Event'];
2121 if (Event && Event.prototype) {
2122 api.patchMethod(Event.prototype, 'stopImmediatePropagation', (delegate) => function (self, args) {
2123 self[IMMEDIATE_PROPAGATION_SYMBOL] = true;
2124 // we need to call the native stopImmediatePropagation
2125 // in case in some hybrid application, some part of
2126 // application will be controlled by zone, some are not
2127 delegate && delegate.apply(self, args);
2128 });
2129 }
2130}
2131
2132/**
2133 * @license
2134 * Copyright Google LLC All Rights Reserved.
2135 *
2136 * Use of this source code is governed by an MIT-style license that can be
2137 * found in the LICENSE file at https://angular.io/license
2138 */
2139function patchCallbacks(api, target, targetName, method, callbacks) {
2140 const symbol = Zone.__symbol__(method);
2141 if (target[symbol]) {
2142 return;
2143 }
2144 const nativeDelegate = target[symbol] = target[method];
2145 target[method] = function (name, opts, options) {
2146 if (opts && opts.prototype) {
2147 callbacks.forEach(function (callback) {
2148 const source = `${targetName}.${method}::` + callback;
2149 const prototype = opts.prototype;
2150 if (prototype.hasOwnProperty(callback)) {
2151 const descriptor = api.ObjectGetOwnPropertyDescriptor(prototype, callback);
2152 if (descriptor && descriptor.value) {
2153 descriptor.value = api.wrapWithCurrentZone(descriptor.value, source);
2154 api._redefineProperty(opts.prototype, callback, descriptor);
2155 }
2156 else if (prototype[callback]) {
2157 prototype[callback] = api.wrapWithCurrentZone(prototype[callback], source);
2158 }
2159 }
2160 else if (prototype[callback]) {
2161 prototype[callback] = api.wrapWithCurrentZone(prototype[callback], source);
2162 }
2163 });
2164 }
2165 return nativeDelegate.call(target, name, opts, options);
2166 };
2167 api.attachOriginToPatched(target[method], nativeDelegate);
2168}
2169
2170/**
2171 * @license
2172 * Copyright Google LLC All Rights Reserved.
2173 *
2174 * Use of this source code is governed by an MIT-style license that can be
2175 * found in the LICENSE file at https://angular.io/license
2176 */
2177const globalEventHandlersEventNames = [
2178 'abort',
2179 'animationcancel',
2180 'animationend',
2181 'animationiteration',
2182 'auxclick',
2183 'beforeinput',
2184 'blur',
2185 'cancel',
2186 'canplay',
2187 'canplaythrough',
2188 'change',
2189 'compositionstart',
2190 'compositionupdate',
2191 'compositionend',
2192 'cuechange',
2193 'click',
2194 'close',
2195 'contextmenu',
2196 'curechange',
2197 'dblclick',
2198 'drag',
2199 'dragend',
2200 'dragenter',
2201 'dragexit',
2202 'dragleave',
2203 'dragover',
2204 'drop',
2205 'durationchange',
2206 'emptied',
2207 'ended',
2208 'error',
2209 'focus',
2210 'focusin',
2211 'focusout',
2212 'gotpointercapture',
2213 'input',
2214 'invalid',
2215 'keydown',
2216 'keypress',
2217 'keyup',
2218 'load',
2219 'loadstart',
2220 'loadeddata',
2221 'loadedmetadata',
2222 'lostpointercapture',
2223 'mousedown',
2224 'mouseenter',
2225 'mouseleave',
2226 'mousemove',
2227 'mouseout',
2228 'mouseover',
2229 'mouseup',
2230 'mousewheel',
2231 'orientationchange',
2232 'pause',
2233 'play',
2234 'playing',
2235 'pointercancel',
2236 'pointerdown',
2237 'pointerenter',
2238 'pointerleave',
2239 'pointerlockchange',
2240 'mozpointerlockchange',
2241 'webkitpointerlockerchange',
2242 'pointerlockerror',
2243 'mozpointerlockerror',
2244 'webkitpointerlockerror',
2245 'pointermove',
2246 'pointout',
2247 'pointerover',
2248 'pointerup',
2249 'progress',
2250 'ratechange',
2251 'reset',
2252 'resize',
2253 'scroll',
2254 'seeked',
2255 'seeking',
2256 'select',
2257 'selectionchange',
2258 'selectstart',
2259 'show',
2260 'sort',
2261 'stalled',
2262 'submit',
2263 'suspend',
2264 'timeupdate',
2265 'volumechange',
2266 'touchcancel',
2267 'touchmove',
2268 'touchstart',
2269 'touchend',
2270 'transitioncancel',
2271 'transitionend',
2272 'waiting',
2273 'wheel'
2274];
2275const documentEventNames = [
2276 'afterscriptexecute', 'beforescriptexecute', 'DOMContentLoaded', 'freeze', 'fullscreenchange',
2277 'mozfullscreenchange', 'webkitfullscreenchange', 'msfullscreenchange', 'fullscreenerror',
2278 'mozfullscreenerror', 'webkitfullscreenerror', 'msfullscreenerror', 'readystatechange',
2279 'visibilitychange', 'resume'
2280];
2281const windowEventNames = [
2282 'absolutedeviceorientation',
2283 'afterinput',
2284 'afterprint',
2285 'appinstalled',
2286 'beforeinstallprompt',
2287 'beforeprint',
2288 'beforeunload',
2289 'devicelight',
2290 'devicemotion',
2291 'deviceorientation',
2292 'deviceorientationabsolute',
2293 'deviceproximity',
2294 'hashchange',
2295 'languagechange',
2296 'message',
2297 'mozbeforepaint',
2298 'offline',
2299 'online',
2300 'paint',
2301 'pageshow',
2302 'pagehide',
2303 'popstate',
2304 'rejectionhandled',
2305 'storage',
2306 'unhandledrejection',
2307 'unload',
2308 'userproximity',
2309 'vrdisplayconnected',
2310 'vrdisplaydisconnected',
2311 'vrdisplaypresentchange'
2312];
2313const htmlElementEventNames = [
2314 'beforecopy', 'beforecut', 'beforepaste', 'copy', 'cut', 'paste', 'dragstart', 'loadend',
2315 'animationstart', 'search', 'transitionrun', 'transitionstart', 'webkitanimationend',
2316 'webkitanimationiteration', 'webkitanimationstart', 'webkittransitionend'
2317];
2318const mediaElementEventNames = ['encrypted', 'waitingforkey', 'msneedkey', 'mozinterruptbegin', 'mozinterruptend'];
2319const ieElementEventNames = [
2320 'activate',
2321 'afterupdate',
2322 'ariarequest',
2323 'beforeactivate',
2324 'beforedeactivate',
2325 'beforeeditfocus',
2326 'beforeupdate',
2327 'cellchange',
2328 'controlselect',
2329 'dataavailable',
2330 'datasetchanged',
2331 'datasetcomplete',
2332 'errorupdate',
2333 'filterchange',
2334 'layoutcomplete',
2335 'losecapture',
2336 'move',
2337 'moveend',
2338 'movestart',
2339 'propertychange',
2340 'resizeend',
2341 'resizestart',
2342 'rowenter',
2343 'rowexit',
2344 'rowsdelete',
2345 'rowsinserted',
2346 'command',
2347 'compassneedscalibration',
2348 'deactivate',
2349 'help',
2350 'mscontentzoom',
2351 'msmanipulationstatechanged',
2352 'msgesturechange',
2353 'msgesturedoubletap',
2354 'msgestureend',
2355 'msgesturehold',
2356 'msgesturestart',
2357 'msgesturetap',
2358 'msgotpointercapture',
2359 'msinertiastart',
2360 'mslostpointercapture',
2361 'mspointercancel',
2362 'mspointerdown',
2363 'mspointerenter',
2364 'mspointerhover',
2365 'mspointerleave',
2366 'mspointermove',
2367 'mspointerout',
2368 'mspointerover',
2369 'mspointerup',
2370 'pointerout',
2371 'mssitemodejumplistitemremoved',
2372 'msthumbnailclick',
2373 'stop',
2374 'storagecommit'
2375];
2376const webglEventNames = ['webglcontextrestored', 'webglcontextlost', 'webglcontextcreationerror'];
2377const formEventNames = ['autocomplete', 'autocompleteerror'];
2378const detailEventNames = ['toggle'];
2379const frameEventNames = ['load'];
2380const frameSetEventNames = ['blur', 'error', 'focus', 'load', 'resize', 'scroll', 'messageerror'];
2381const marqueeEventNames = ['bounce', 'finish', 'start'];
2382const XMLHttpRequestEventNames = [
2383 'loadstart', 'progress', 'abort', 'error', 'load', 'progress', 'timeout', 'loadend',
2384 'readystatechange'
2385];
2386const IDBIndexEventNames = ['upgradeneeded', 'complete', 'abort', 'success', 'error', 'blocked', 'versionchange', 'close'];
2387const websocketEventNames = ['close', 'error', 'open', 'message'];
2388const workerEventNames = ['error', 'message'];
2389const eventNames = globalEventHandlersEventNames.concat(webglEventNames, formEventNames, detailEventNames, documentEventNames, windowEventNames, htmlElementEventNames, ieElementEventNames);
2390function filterProperties(target, onProperties, ignoreProperties) {
2391 if (!ignoreProperties || ignoreProperties.length === 0) {
2392 return onProperties;
2393 }
2394 const tip = ignoreProperties.filter(ip => ip.target === target);
2395 if (!tip || tip.length === 0) {
2396 return onProperties;
2397 }
2398 const targetIgnoreProperties = tip[0].ignoreProperties;
2399 return onProperties.filter(op => targetIgnoreProperties.indexOf(op) === -1);
2400}
2401function patchFilteredProperties(target, onProperties, ignoreProperties, prototype) {
2402 // check whether target is available, sometimes target will be undefined
2403 // because different browser or some 3rd party plugin.
2404 if (!target) {
2405 return;
2406 }
2407 const filteredProperties = filterProperties(target, onProperties, ignoreProperties);
2408 patchOnProperties(target, filteredProperties, prototype);
2409}
2410function propertyDescriptorPatch(api, _global) {
2411 if (isNode && !isMix) {
2412 return;
2413 }
2414 if (Zone[api.symbol('patchEvents')]) {
2415 // events are already been patched by legacy patch.
2416 return;
2417 }
2418 const supportsWebSocket = typeof WebSocket !== 'undefined';
2419 const ignoreProperties = _global['__Zone_ignore_on_properties'];
2420 // for browsers that we can patch the descriptor: Chrome & Firefox
2421 if (isBrowser) {
2422 const internalWindow = window;
2423 const ignoreErrorProperties = isIE() ? [{ target: internalWindow, ignoreProperties: ['error'] }] : [];
2424 // in IE/Edge, onProp not exist in window object, but in WindowPrototype
2425 // so we need to pass WindowPrototype to check onProp exist or not
2426 patchFilteredProperties(internalWindow, eventNames.concat(['messageerror']), ignoreProperties ? ignoreProperties.concat(ignoreErrorProperties) : ignoreProperties, ObjectGetPrototypeOf(internalWindow));
2427 patchFilteredProperties(Document.prototype, eventNames, ignoreProperties);
2428 if (typeof internalWindow['SVGElement'] !== 'undefined') {
2429 patchFilteredProperties(internalWindow['SVGElement'].prototype, eventNames, ignoreProperties);
2430 }
2431 patchFilteredProperties(Element.prototype, eventNames, ignoreProperties);
2432 patchFilteredProperties(HTMLElement.prototype, eventNames, ignoreProperties);
2433 patchFilteredProperties(HTMLMediaElement.prototype, mediaElementEventNames, ignoreProperties);
2434 patchFilteredProperties(HTMLFrameSetElement.prototype, windowEventNames.concat(frameSetEventNames), ignoreProperties);
2435 patchFilteredProperties(HTMLBodyElement.prototype, windowEventNames.concat(frameSetEventNames), ignoreProperties);
2436 patchFilteredProperties(HTMLFrameElement.prototype, frameEventNames, ignoreProperties);
2437 patchFilteredProperties(HTMLIFrameElement.prototype, frameEventNames, ignoreProperties);
2438 const HTMLMarqueeElement = internalWindow['HTMLMarqueeElement'];
2439 if (HTMLMarqueeElement) {
2440 patchFilteredProperties(HTMLMarqueeElement.prototype, marqueeEventNames, ignoreProperties);
2441 }
2442 const Worker = internalWindow['Worker'];
2443 if (Worker) {
2444 patchFilteredProperties(Worker.prototype, workerEventNames, ignoreProperties);
2445 }
2446 }
2447 const XMLHttpRequest = _global['XMLHttpRequest'];
2448 if (XMLHttpRequest) {
2449 // XMLHttpRequest is not available in ServiceWorker, so we need to check here
2450 patchFilteredProperties(XMLHttpRequest.prototype, XMLHttpRequestEventNames, ignoreProperties);
2451 }
2452 const XMLHttpRequestEventTarget = _global['XMLHttpRequestEventTarget'];
2453 if (XMLHttpRequestEventTarget) {
2454 patchFilteredProperties(XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype, XMLHttpRequestEventNames, ignoreProperties);
2455 }
2456 if (typeof IDBIndex !== 'undefined') {
2457 patchFilteredProperties(IDBIndex.prototype, IDBIndexEventNames, ignoreProperties);
2458 patchFilteredProperties(IDBRequest.prototype, IDBIndexEventNames, ignoreProperties);
2459 patchFilteredProperties(IDBOpenDBRequest.prototype, IDBIndexEventNames, ignoreProperties);
2460 patchFilteredProperties(IDBDatabase.prototype, IDBIndexEventNames, ignoreProperties);
2461 patchFilteredProperties(IDBTransaction.prototype, IDBIndexEventNames, ignoreProperties);
2462 patchFilteredProperties(IDBCursor.prototype, IDBIndexEventNames, ignoreProperties);
2463 }
2464 if (supportsWebSocket) {
2465 patchFilteredProperties(WebSocket.prototype, websocketEventNames, ignoreProperties);
2466 }
2467}
2468
2469/**
2470 * @license
2471 * Copyright Google LLC All Rights Reserved.
2472 *
2473 * Use of this source code is governed by an MIT-style license that can be
2474 * found in the LICENSE file at https://angular.io/license
2475 */
2476Zone.__load_patch('util', (global, Zone, api) => {
2477 api.patchOnProperties = patchOnProperties;
2478 api.patchMethod = patchMethod;
2479 api.bindArguments = bindArguments;
2480 api.patchMacroTask = patchMacroTask;
2481 // In earlier version of zone.js (<0.9.0), we use env name `__zone_symbol__BLACK_LISTED_EVENTS` to
2482 // define which events will not be patched by `Zone.js`.
2483 // In newer version (>=0.9.0), we change the env name to `__zone_symbol__UNPATCHED_EVENTS` to keep
2484 // the name consistent with angular repo.
2485 // The `__zone_symbol__BLACK_LISTED_EVENTS` is deprecated, but it is still be supported for
2486 // backwards compatibility.
2487 const SYMBOL_BLACK_LISTED_EVENTS = Zone.__symbol__('BLACK_LISTED_EVENTS');
2488 const SYMBOL_UNPATCHED_EVENTS = Zone.__symbol__('UNPATCHED_EVENTS');
2489 if (global[SYMBOL_UNPATCHED_EVENTS]) {
2490 global[SYMBOL_BLACK_LISTED_EVENTS] = global[SYMBOL_UNPATCHED_EVENTS];
2491 }
2492 if (global[SYMBOL_BLACK_LISTED_EVENTS]) {
2493 Zone[SYMBOL_BLACK_LISTED_EVENTS] = Zone[SYMBOL_UNPATCHED_EVENTS] =
2494 global[SYMBOL_BLACK_LISTED_EVENTS];
2495 }
2496 api.patchEventPrototype = patchEventPrototype;
2497 api.patchEventTarget = patchEventTarget;
2498 api.isIEOrEdge = isIEOrEdge;
2499 api.ObjectDefineProperty = ObjectDefineProperty;
2500 api.ObjectGetOwnPropertyDescriptor = ObjectGetOwnPropertyDescriptor;
2501 api.ObjectCreate = ObjectCreate;
2502 api.ArraySlice = ArraySlice;
2503 api.patchClass = patchClass;
2504 api.wrapWithCurrentZone = wrapWithCurrentZone;
2505 api.filterProperties = filterProperties;
2506 api.attachOriginToPatched = attachOriginToPatched;
2507 api._redefineProperty = Object.defineProperty;
2508 api.patchCallbacks = patchCallbacks;
2509 api.getGlobalObjects = () => ({
2510 globalSources,
2511 zoneSymbolEventNames: zoneSymbolEventNames$1,
2512 eventNames,
2513 isBrowser,
2514 isMix,
2515 isNode,
2516 TRUE_STR,
2517 FALSE_STR,
2518 ZONE_SYMBOL_PREFIX,
2519 ADD_EVENT_LISTENER_STR,
2520 REMOVE_EVENT_LISTENER_STR
2521 });
2522});
2523
2524/**
2525 * @license
2526 * Copyright Google LLC All Rights Reserved.
2527 *
2528 * Use of this source code is governed by an MIT-style license that can be
2529 * found in the LICENSE file at https://angular.io/license
2530 */
2531const taskSymbol = zoneSymbol('zoneTask');
2532function patchTimer(window, setName, cancelName, nameSuffix) {
2533 let setNative = null;
2534 let clearNative = null;
2535 setName += nameSuffix;
2536 cancelName += nameSuffix;
2537 const tasksByHandleId = {};
2538 function scheduleTask(task) {
2539 const data = task.data;
2540 data.args[0] = function () {
2541 return task.invoke.apply(this, arguments);
2542 };
2543 data.handleId = setNative.apply(window, data.args);
2544 return task;
2545 }
2546 function clearTask(task) {
2547 return clearNative.call(window, task.data.handleId);
2548 }
2549 setNative =
2550 patchMethod(window, setName, (delegate) => function (self, args) {
2551 if (typeof args[0] === 'function') {
2552 const options = {
2553 isPeriodic: nameSuffix === 'Interval',
2554 delay: (nameSuffix === 'Timeout' || nameSuffix === 'Interval') ? args[1] || 0 :
2555 undefined,
2556 args: args
2557 };
2558 const callback = args[0];
2559 args[0] = function timer() {
2560 try {
2561 return callback.apply(this, arguments);
2562 }
2563 finally {
2564 // issue-934, task will be cancelled
2565 // even it is a periodic task such as
2566 // setInterval
2567 // https://github.com/angular/angular/issues/40387
2568 // Cleanup tasksByHandleId should be handled before scheduleTask
2569 // Since some zoneSpec may intercept and doesn't trigger
2570 // scheduleFn(scheduleTask) provided here.
2571 if (!(options.isPeriodic)) {
2572 if (typeof options.handleId === 'number') {
2573 // in non-nodejs env, we remove timerId
2574 // from local cache
2575 delete tasksByHandleId[options.handleId];
2576 }
2577 else if (options.handleId) {
2578 // Node returns complex objects as handleIds
2579 // we remove task reference from timer object
2580 options.handleId[taskSymbol] = null;
2581 }
2582 }
2583 }
2584 };
2585 const task = scheduleMacroTaskWithCurrentZone(setName, args[0], options, scheduleTask, clearTask);
2586 if (!task) {
2587 return task;
2588 }
2589 // Node.js must additionally support the ref and unref functions.
2590 const handle = task.data.handleId;
2591 if (typeof handle === 'number') {
2592 // for non nodejs env, we save handleId: task
2593 // mapping in local cache for clearTimeout
2594 tasksByHandleId[handle] = task;
2595 }
2596 else if (handle) {
2597 // for nodejs env, we save task
2598 // reference in timerId Object for clearTimeout
2599 handle[taskSymbol] = task;
2600 }
2601 // check whether handle is null, because some polyfill or browser
2602 // may return undefined from setTimeout/setInterval/setImmediate/requestAnimationFrame
2603 if (handle && handle.ref && handle.unref && typeof handle.ref === 'function' &&
2604 typeof handle.unref === 'function') {
2605 task.ref = handle.ref.bind(handle);
2606 task.unref = handle.unref.bind(handle);
2607 }
2608 if (typeof handle === 'number' || handle) {
2609 return handle;
2610 }
2611 return task;
2612 }
2613 else {
2614 // cause an error by calling it directly.
2615 return delegate.apply(window, args);
2616 }
2617 });
2618 clearNative =
2619 patchMethod(window, cancelName, (delegate) => function (self, args) {
2620 const id = args[0];
2621 let task;
2622 if (typeof id === 'number') {
2623 // non nodejs env.
2624 task = tasksByHandleId[id];
2625 }
2626 else {
2627 // nodejs env.
2628 task = id && id[taskSymbol];
2629 // other environments.
2630 if (!task) {
2631 task = id;
2632 }
2633 }
2634 if (task && typeof task.type === 'string') {
2635 if (task.state !== 'notScheduled' &&
2636 (task.cancelFn && task.data.isPeriodic || task.runCount === 0)) {
2637 if (typeof id === 'number') {
2638 delete tasksByHandleId[id];
2639 }
2640 else if (id) {
2641 id[taskSymbol] = null;
2642 }
2643 // Do not cancel already canceled functions
2644 task.zone.cancelTask(task);
2645 }
2646 }
2647 else {
2648 // cause an error by calling it directly.
2649 delegate.apply(window, args);
2650 }
2651 });
2652}
2653
2654/**
2655 * @license
2656 * Copyright Google LLC All Rights Reserved.
2657 *
2658 * Use of this source code is governed by an MIT-style license that can be
2659 * found in the LICENSE file at https://angular.io/license
2660 */
2661function patchCustomElements(_global, api) {
2662 const { isBrowser, isMix } = api.getGlobalObjects();
2663 if ((!isBrowser && !isMix) || !_global['customElements'] || !('customElements' in _global)) {
2664 return;
2665 }
2666 const callbacks = ['connectedCallback', 'disconnectedCallback', 'adoptedCallback', 'attributeChangedCallback'];
2667 api.patchCallbacks(api, _global.customElements, 'customElements', 'define', callbacks);
2668}
2669
2670/**
2671 * @license
2672 * Copyright Google LLC All Rights Reserved.
2673 *
2674 * Use of this source code is governed by an MIT-style license that can be
2675 * found in the LICENSE file at https://angular.io/license
2676 */
2677function eventTargetPatch(_global, api) {
2678 if (Zone[api.symbol('patchEventTarget')]) {
2679 // EventTarget is already patched.
2680 return;
2681 }
2682 const { eventNames, zoneSymbolEventNames, TRUE_STR, FALSE_STR, ZONE_SYMBOL_PREFIX } = api.getGlobalObjects();
2683 // predefine all __zone_symbol__ + eventName + true/false string
2684 for (let i = 0; i < eventNames.length; i++) {
2685 const eventName = eventNames[i];
2686 const falseEventName = eventName + FALSE_STR;
2687 const trueEventName = eventName + TRUE_STR;
2688 const symbol = ZONE_SYMBOL_PREFIX + falseEventName;
2689 const symbolCapture = ZONE_SYMBOL_PREFIX + trueEventName;
2690 zoneSymbolEventNames[eventName] = {};
2691 zoneSymbolEventNames[eventName][FALSE_STR] = symbol;
2692 zoneSymbolEventNames[eventName][TRUE_STR] = symbolCapture;
2693 }
2694 const EVENT_TARGET = _global['EventTarget'];
2695 if (!EVENT_TARGET || !EVENT_TARGET.prototype) {
2696 return;
2697 }
2698 api.patchEventTarget(_global, [EVENT_TARGET && EVENT_TARGET.prototype]);
2699 return true;
2700}
2701function patchEvent(global, api) {
2702 api.patchEventPrototype(global, api);
2703}
2704
2705/**
2706 * @license
2707 * Copyright Google LLC All Rights Reserved.
2708 *
2709 * Use of this source code is governed by an MIT-style license that can be
2710 * found in the LICENSE file at https://angular.io/license
2711 */
2712Zone.__load_patch('legacy', (global) => {
2713 const legacyPatch = global[Zone.__symbol__('legacyPatch')];
2714 if (legacyPatch) {
2715 legacyPatch();
2716 }
2717});
2718Zone.__load_patch('queueMicrotask', (global, Zone, api) => {
2719 api.patchMethod(global, 'queueMicrotask', delegate => {
2720 return function (self, args) {
2721 Zone.current.scheduleMicroTask('queueMicrotask', args[0]);
2722 };
2723 });
2724});
2725Zone.__load_patch('timers', (global) => {
2726 const set = 'set';
2727 const clear = 'clear';
2728 patchTimer(global, set, clear, 'Timeout');
2729 patchTimer(global, set, clear, 'Interval');
2730 patchTimer(global, set, clear, 'Immediate');
2731});
2732Zone.__load_patch('requestAnimationFrame', (global) => {
2733 patchTimer(global, 'request', 'cancel', 'AnimationFrame');
2734 patchTimer(global, 'mozRequest', 'mozCancel', 'AnimationFrame');
2735 patchTimer(global, 'webkitRequest', 'webkitCancel', 'AnimationFrame');
2736});
2737Zone.__load_patch('blocking', (global, Zone) => {
2738 const blockingMethods = ['alert', 'prompt', 'confirm'];
2739 for (let i = 0; i < blockingMethods.length; i++) {
2740 const name = blockingMethods[i];
2741 patchMethod(global, name, (delegate, symbol, name) => {
2742 return function (s, args) {
2743 return Zone.current.run(delegate, global, args, name);
2744 };
2745 });
2746 }
2747});
2748Zone.__load_patch('EventTarget', (global, Zone, api) => {
2749 patchEvent(global, api);
2750 eventTargetPatch(global, api);
2751 // patch XMLHttpRequestEventTarget's addEventListener/removeEventListener
2752 const XMLHttpRequestEventTarget = global['XMLHttpRequestEventTarget'];
2753 if (XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype) {
2754 api.patchEventTarget(global, [XMLHttpRequestEventTarget.prototype]);
2755 }
2756});
2757Zone.__load_patch('MutationObserver', (global, Zone, api) => {
2758 patchClass('MutationObserver');
2759 patchClass('WebKitMutationObserver');
2760});
2761Zone.__load_patch('IntersectionObserver', (global, Zone, api) => {
2762 patchClass('IntersectionObserver');
2763});
2764Zone.__load_patch('FileReader', (global, Zone, api) => {
2765 patchClass('FileReader');
2766});
2767Zone.__load_patch('on_property', (global, Zone, api) => {
2768 propertyDescriptorPatch(api, global);
2769});
2770Zone.__load_patch('customElements', (global, Zone, api) => {
2771 patchCustomElements(global, api);
2772});
2773Zone.__load_patch('XHR', (global, Zone) => {
2774 // Treat XMLHttpRequest as a macrotask.
2775 patchXHR(global);
2776 const XHR_TASK = zoneSymbol('xhrTask');
2777 const XHR_SYNC = zoneSymbol('xhrSync');
2778 const XHR_LISTENER = zoneSymbol('xhrListener');
2779 const XHR_SCHEDULED = zoneSymbol('xhrScheduled');
2780 const XHR_URL = zoneSymbol('xhrURL');
2781 const XHR_ERROR_BEFORE_SCHEDULED = zoneSymbol('xhrErrorBeforeScheduled');
2782 function patchXHR(window) {
2783 const XMLHttpRequest = window['XMLHttpRequest'];
2784 if (!XMLHttpRequest) {
2785 // XMLHttpRequest is not available in service worker
2786 return;
2787 }
2788 const XMLHttpRequestPrototype = XMLHttpRequest.prototype;
2789 function findPendingTask(target) {
2790 return target[XHR_TASK];
2791 }
2792 let oriAddListener = XMLHttpRequestPrototype[ZONE_SYMBOL_ADD_EVENT_LISTENER];
2793 let oriRemoveListener = XMLHttpRequestPrototype[ZONE_SYMBOL_REMOVE_EVENT_LISTENER];
2794 if (!oriAddListener) {
2795 const XMLHttpRequestEventTarget = window['XMLHttpRequestEventTarget'];
2796 if (XMLHttpRequestEventTarget) {
2797 const XMLHttpRequestEventTargetPrototype = XMLHttpRequestEventTarget.prototype;
2798 oriAddListener = XMLHttpRequestEventTargetPrototype[ZONE_SYMBOL_ADD_EVENT_LISTENER];
2799 oriRemoveListener = XMLHttpRequestEventTargetPrototype[ZONE_SYMBOL_REMOVE_EVENT_LISTENER];
2800 }
2801 }
2802 const READY_STATE_CHANGE = 'readystatechange';
2803 const SCHEDULED = 'scheduled';
2804 function scheduleTask(task) {
2805 const data = task.data;
2806 const target = data.target;
2807 target[XHR_SCHEDULED] = false;
2808 target[XHR_ERROR_BEFORE_SCHEDULED] = false;
2809 // remove existing event listener
2810 const listener = target[XHR_LISTENER];
2811 if (!oriAddListener) {
2812 oriAddListener = target[ZONE_SYMBOL_ADD_EVENT_LISTENER];
2813 oriRemoveListener = target[ZONE_SYMBOL_REMOVE_EVENT_LISTENER];
2814 }
2815 if (listener) {
2816 oriRemoveListener.call(target, READY_STATE_CHANGE, listener);
2817 }
2818 const newListener = target[XHR_LISTENER] = () => {
2819 if (target.readyState === target.DONE) {
2820 // sometimes on some browsers XMLHttpRequest will fire onreadystatechange with
2821 // readyState=4 multiple times, so we need to check task state here
2822 if (!data.aborted && target[XHR_SCHEDULED] && task.state === SCHEDULED) {
2823 // check whether the xhr has registered onload listener
2824 // if that is the case, the task should invoke after all
2825 // onload listeners finish.
2826 // Also if the request failed without response (status = 0), the load event handler
2827 // will not be triggered, in that case, we should also invoke the placeholder callback
2828 // to close the XMLHttpRequest::send macroTask.
2829 // https://github.com/angular/angular/issues/38795
2830 const loadTasks = target[Zone.__symbol__('loadfalse')];
2831 if (target.status !== 0 && loadTasks && loadTasks.length > 0) {
2832 const oriInvoke = task.invoke;
2833 task.invoke = function () {
2834 // need to load the tasks again, because in other
2835 // load listener, they may remove themselves
2836 const loadTasks = target[Zone.__symbol__('loadfalse')];
2837 for (let i = 0; i < loadTasks.length; i++) {
2838 if (loadTasks[i] === task) {
2839 loadTasks.splice(i, 1);
2840 }
2841 }
2842 if (!data.aborted && task.state === SCHEDULED) {
2843 oriInvoke.call(task);
2844 }
2845 };
2846 loadTasks.push(task);
2847 }
2848 else {
2849 task.invoke();
2850 }
2851 }
2852 else if (!data.aborted && target[XHR_SCHEDULED] === false) {
2853 // error occurs when xhr.send()
2854 target[XHR_ERROR_BEFORE_SCHEDULED] = true;
2855 }
2856 }
2857 };
2858 oriAddListener.call(target, READY_STATE_CHANGE, newListener);
2859 const storedTask = target[XHR_TASK];
2860 if (!storedTask) {
2861 target[XHR_TASK] = task;
2862 }
2863 sendNative.apply(target, data.args);
2864 target[XHR_SCHEDULED] = true;
2865 return task;
2866 }
2867 function placeholderCallback() { }
2868 function clearTask(task) {
2869 const data = task.data;
2870 // Note - ideally, we would call data.target.removeEventListener here, but it's too late
2871 // to prevent it from firing. So instead, we store info for the event listener.
2872 data.aborted = true;
2873 return abortNative.apply(data.target, data.args);
2874 }
2875 const openNative = patchMethod(XMLHttpRequestPrototype, 'open', () => function (self, args) {
2876 self[XHR_SYNC] = args[2] == false;
2877 self[XHR_URL] = args[1];
2878 return openNative.apply(self, args);
2879 });
2880 const XMLHTTPREQUEST_SOURCE = 'XMLHttpRequest.send';
2881 const fetchTaskAborting = zoneSymbol('fetchTaskAborting');
2882 const fetchTaskScheduling = zoneSymbol('fetchTaskScheduling');
2883 const sendNative = patchMethod(XMLHttpRequestPrototype, 'send', () => function (self, args) {
2884 if (Zone.current[fetchTaskScheduling] === true) {
2885 // a fetch is scheduling, so we are using xhr to polyfill fetch
2886 // and because we already schedule macroTask for fetch, we should
2887 // not schedule a macroTask for xhr again
2888 return sendNative.apply(self, args);
2889 }
2890 if (self[XHR_SYNC]) {
2891 // if the XHR is sync there is no task to schedule, just execute the code.
2892 return sendNative.apply(self, args);
2893 }
2894 else {
2895 const options = { target: self, url: self[XHR_URL], isPeriodic: false, args: args, aborted: false };
2896 const task = scheduleMacroTaskWithCurrentZone(XMLHTTPREQUEST_SOURCE, placeholderCallback, options, scheduleTask, clearTask);
2897 if (self && self[XHR_ERROR_BEFORE_SCHEDULED] === true && !options.aborted &&
2898 task.state === SCHEDULED) {
2899 // xhr request throw error when send
2900 // we should invoke task instead of leaving a scheduled
2901 // pending macroTask
2902 task.invoke();
2903 }
2904 }
2905 });
2906 const abortNative = patchMethod(XMLHttpRequestPrototype, 'abort', () => function (self, args) {
2907 const task = findPendingTask(self);
2908 if (task && typeof task.type == 'string') {
2909 // If the XHR has already completed, do nothing.
2910 // If the XHR has already been aborted, do nothing.
2911 // Fix #569, call abort multiple times before done will cause
2912 // macroTask task count be negative number
2913 if (task.cancelFn == null || (task.data && task.data.aborted)) {
2914 return;
2915 }
2916 task.zone.cancelTask(task);
2917 }
2918 else if (Zone.current[fetchTaskAborting] === true) {
2919 // the abort is called from fetch polyfill, we need to call native abort of XHR.
2920 return abortNative.apply(self, args);
2921 }
2922 // Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no
2923 // task
2924 // to cancel. Do nothing.
2925 });
2926 }
2927});
2928Zone.__load_patch('geolocation', (global) => {
2929 /// GEO_LOCATION
2930 if (global['navigator'] && global['navigator'].geolocation) {
2931 patchPrototype(global['navigator'].geolocation, ['getCurrentPosition', 'watchPosition']);
2932 }
2933});
2934Zone.__load_patch('PromiseRejectionEvent', (global, Zone) => {
2935 // handle unhandled promise rejection
2936 function findPromiseRejectionHandler(evtName) {
2937 return function (e) {
2938 const eventTasks = findEventTasks(global, evtName);
2939 eventTasks.forEach(eventTask => {
2940 // windows has added unhandledrejection event listener
2941 // trigger the event listener
2942 const PromiseRejectionEvent = global['PromiseRejectionEvent'];
2943 if (PromiseRejectionEvent) {
2944 const evt = new PromiseRejectionEvent(evtName, { promise: e.promise, reason: e.rejection });
2945 eventTask.invoke(evt);
2946 }
2947 });
2948 };
2949 }
2950 if (global['PromiseRejectionEvent']) {
2951 Zone[zoneSymbol('unhandledPromiseRejectionHandler')] =
2952 findPromiseRejectionHandler('unhandledrejection');
2953 Zone[zoneSymbol('rejectionHandledHandler')] =
2954 findPromiseRejectionHandler('rejectionhandled');
2955 }
2956});
2957
2958/**
2959 * @license
2960 * Copyright Google LLC All Rights Reserved.
2961 *
2962 * Use of this source code is governed by an MIT-style license that can be
2963 * found in the LICENSE file at https://angular.io/license
2964 */
2965/**
2966 * @fileoverview
2967 * @suppress {globalThis}
2968 */
2969const NEWLINE = '\n';
2970const IGNORE_FRAMES = {};
2971const creationTrace = '__creationTrace__';
2972const ERROR_TAG = 'STACKTRACE TRACKING';
2973const SEP_TAG = '__SEP_TAG__';
2974let sepTemplate = SEP_TAG + '@[native]';
2975class LongStackTrace {
2976 constructor() {
2977 this.error = getStacktrace();
2978 this.timestamp = new Date();
2979 }
2980}
2981function getStacktraceWithUncaughtError() {
2982 return new Error(ERROR_TAG);
2983}
2984function getStacktraceWithCaughtError() {
2985 try {
2986 throw getStacktraceWithUncaughtError();
2987 }
2988 catch (err) {
2989 return err;
2990 }
2991}
2992// Some implementations of exception handling don't create a stack trace if the exception
2993// isn't thrown, however it's faster not to actually throw the exception.
2994const error = getStacktraceWithUncaughtError();
2995const caughtError = getStacktraceWithCaughtError();
2996const getStacktrace = error.stack ?
2997 getStacktraceWithUncaughtError :
2998 (caughtError.stack ? getStacktraceWithCaughtError : getStacktraceWithUncaughtError);
2999function getFrames(error) {
3000 return error.stack ? error.stack.split(NEWLINE) : [];
3001}
3002function addErrorStack(lines, error) {
3003 let trace = getFrames(error);
3004 for (let i = 0; i < trace.length; i++) {
3005 const frame = trace[i];
3006 // Filter out the Frames which are part of stack capturing.
3007 if (!IGNORE_FRAMES.hasOwnProperty(frame)) {
3008 lines.push(trace[i]);
3009 }
3010 }
3011}
3012function renderLongStackTrace(frames, stack) {
3013 const longTrace = [stack ? stack.trim() : ''];
3014 if (frames) {
3015 let timestamp = new Date().getTime();
3016 for (let i = 0; i < frames.length; i++) {
3017 const traceFrames = frames[i];
3018 const lastTime = traceFrames.timestamp;
3019 let separator = `____________________Elapsed ${timestamp - lastTime.getTime()} ms; At: ${lastTime}`;
3020 separator = separator.replace(/[^\w\d]/g, '_');
3021 longTrace.push(sepTemplate.replace(SEP_TAG, separator));
3022 addErrorStack(longTrace, traceFrames.error);
3023 timestamp = lastTime.getTime();
3024 }
3025 }
3026 return longTrace.join(NEWLINE);
3027}
3028// if Error.stackTraceLimit is 0, means stack trace
3029// is disabled, so we don't need to generate long stack trace
3030// this will improve performance in some test(some test will
3031// set stackTraceLimit to 0, https://github.com/angular/zone.js/issues/698
3032function stackTracesEnabled() {
3033 // Cast through any since this property only exists on Error in the nodejs
3034 // typings.
3035 return Error.stackTraceLimit > 0;
3036}
3037Zone['longStackTraceZoneSpec'] = {
3038 name: 'long-stack-trace',
3039 longStackTraceLimit: 10,
3040 // add a getLongStackTrace method in spec to
3041 // handle handled reject promise error.
3042 getLongStackTrace: function (error) {
3043 if (!error) {
3044 return undefined;
3045 }
3046 const trace = error[Zone.__symbol__('currentTaskTrace')];
3047 if (!trace) {
3048 return error.stack;
3049 }
3050 return renderLongStackTrace(trace, error.stack);
3051 },
3052 onScheduleTask: function (parentZoneDelegate, currentZone, targetZone, task) {
3053 if (stackTracesEnabled()) {
3054 const currentTask = Zone.currentTask;
3055 let trace = currentTask && currentTask.data && currentTask.data[creationTrace] || [];
3056 trace = [new LongStackTrace()].concat(trace);
3057 if (trace.length > this.longStackTraceLimit) {
3058 trace.length = this.longStackTraceLimit;
3059 }
3060 if (!task.data)
3061 task.data = {};
3062 if (task.type === 'eventTask') {
3063 // Fix issue https://github.com/angular/zone.js/issues/1195,
3064 // For event task of browser, by default, all task will share a
3065 // singleton instance of data object, we should create a new one here
3066 // The cast to `any` is required to workaround a closure bug which wrongly applies
3067 // URL sanitization rules to .data access.
3068 task.data = Object.assign({}, task.data);
3069 }
3070 task.data[creationTrace] = trace;
3071 }
3072 return parentZoneDelegate.scheduleTask(targetZone, task);
3073 },
3074 onHandleError: function (parentZoneDelegate, currentZone, targetZone, error) {
3075 if (stackTracesEnabled()) {
3076 const parentTask = Zone.currentTask || error.task;
3077 if (error instanceof Error && parentTask) {
3078 const longStack = renderLongStackTrace(parentTask.data && parentTask.data[creationTrace], error.stack);
3079 try {
3080 error.stack = error.longStack = longStack;
3081 }
3082 catch (err) {
3083 }
3084 }
3085 }
3086 return parentZoneDelegate.handleError(targetZone, error);
3087 }
3088};
3089function captureStackTraces(stackTraces, count) {
3090 if (count > 0) {
3091 stackTraces.push(getFrames((new LongStackTrace()).error));
3092 captureStackTraces(stackTraces, count - 1);
3093 }
3094}
3095function computeIgnoreFrames() {
3096 if (!stackTracesEnabled()) {
3097 return;
3098 }
3099 const frames = [];
3100 captureStackTraces(frames, 2);
3101 const frames1 = frames[0];
3102 const frames2 = frames[1];
3103 for (let i = 0; i < frames1.length; i++) {
3104 const frame1 = frames1[i];
3105 if (frame1.indexOf(ERROR_TAG) == -1) {
3106 let match = frame1.match(/^\s*at\s+/);
3107 if (match) {
3108 sepTemplate = match[0] + SEP_TAG + ' (http://localhost)';
3109 break;
3110 }
3111 }
3112 }
3113 for (let i = 0; i < frames1.length; i++) {
3114 const frame1 = frames1[i];
3115 const frame2 = frames2[i];
3116 if (frame1 === frame2) {
3117 IGNORE_FRAMES[frame1] = true;
3118 }
3119 else {
3120 break;
3121 }
3122 }
3123}
3124computeIgnoreFrames();
3125
3126/**
3127 * @license
3128 * Copyright Google LLC All Rights Reserved.
3129 *
3130 * Use of this source code is governed by an MIT-style license that can be
3131 * found in the LICENSE file at https://angular.io/license
3132 */
3133class ProxyZoneSpec {
3134 constructor(defaultSpecDelegate = null) {
3135 this.defaultSpecDelegate = defaultSpecDelegate;
3136 this.name = 'ProxyZone';
3137 this._delegateSpec = null;
3138 this.properties = { 'ProxyZoneSpec': this };
3139 this.propertyKeys = null;
3140 this.lastTaskState = null;
3141 this.isNeedToTriggerHasTask = false;
3142 this.tasks = [];
3143 this.setDelegate(defaultSpecDelegate);
3144 }
3145 static get() {
3146 return Zone.current.get('ProxyZoneSpec');
3147 }
3148 static isLoaded() {
3149 return ProxyZoneSpec.get() instanceof ProxyZoneSpec;
3150 }
3151 static assertPresent() {
3152 if (!ProxyZoneSpec.isLoaded()) {
3153 throw new Error(`Expected to be running in 'ProxyZone', but it was not found.`);
3154 }
3155 return ProxyZoneSpec.get();
3156 }
3157 setDelegate(delegateSpec) {
3158 const isNewDelegate = this._delegateSpec !== delegateSpec;
3159 this._delegateSpec = delegateSpec;
3160 this.propertyKeys && this.propertyKeys.forEach((key) => delete this.properties[key]);
3161 this.propertyKeys = null;
3162 if (delegateSpec && delegateSpec.properties) {
3163 this.propertyKeys = Object.keys(delegateSpec.properties);
3164 this.propertyKeys.forEach((k) => this.properties[k] = delegateSpec.properties[k]);
3165 }
3166 // if a new delegateSpec was set, check if we need to trigger hasTask
3167 if (isNewDelegate && this.lastTaskState &&
3168 (this.lastTaskState.macroTask || this.lastTaskState.microTask)) {
3169 this.isNeedToTriggerHasTask = true;
3170 }
3171 }
3172 getDelegate() {
3173 return this._delegateSpec;
3174 }
3175 resetDelegate() {
3176 const delegateSpec = this.getDelegate();
3177 this.setDelegate(this.defaultSpecDelegate);
3178 }
3179 tryTriggerHasTask(parentZoneDelegate, currentZone, targetZone) {
3180 if (this.isNeedToTriggerHasTask && this.lastTaskState) {
3181 // last delegateSpec has microTask or macroTask
3182 // should call onHasTask in current delegateSpec
3183 this.isNeedToTriggerHasTask = false;
3184 this.onHasTask(parentZoneDelegate, currentZone, targetZone, this.lastTaskState);
3185 }
3186 }
3187 removeFromTasks(task) {
3188 if (!this.tasks) {
3189 return;
3190 }
3191 for (let i = 0; i < this.tasks.length; i++) {
3192 if (this.tasks[i] === task) {
3193 this.tasks.splice(i, 1);
3194 return;
3195 }
3196 }
3197 }
3198 getAndClearPendingTasksInfo() {
3199 if (this.tasks.length === 0) {
3200 return '';
3201 }
3202 const taskInfo = this.tasks.map((task) => {
3203 const dataInfo = task.data &&
3204 Object.keys(task.data)
3205 .map((key) => {
3206 return key + ':' + task.data[key];
3207 })
3208 .join(',');
3209 return `type: ${task.type}, source: ${task.source}, args: {${dataInfo}}`;
3210 });
3211 const pendingTasksInfo = '--Pending async tasks are: [' + taskInfo + ']';
3212 // clear tasks
3213 this.tasks = [];
3214 return pendingTasksInfo;
3215 }
3216 onFork(parentZoneDelegate, currentZone, targetZone, zoneSpec) {
3217 if (this._delegateSpec && this._delegateSpec.onFork) {
3218 return this._delegateSpec.onFork(parentZoneDelegate, currentZone, targetZone, zoneSpec);
3219 }
3220 else {
3221 return parentZoneDelegate.fork(targetZone, zoneSpec);
3222 }
3223 }
3224 onIntercept(parentZoneDelegate, currentZone, targetZone, delegate, source) {
3225 if (this._delegateSpec && this._delegateSpec.onIntercept) {
3226 return this._delegateSpec.onIntercept(parentZoneDelegate, currentZone, targetZone, delegate, source);
3227 }
3228 else {
3229 return parentZoneDelegate.intercept(targetZone, delegate, source);
3230 }
3231 }
3232 onInvoke(parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) {
3233 this.tryTriggerHasTask(parentZoneDelegate, currentZone, targetZone);
3234 if (this._delegateSpec && this._delegateSpec.onInvoke) {
3235 return this._delegateSpec.onInvoke(parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source);
3236 }
3237 else {
3238 return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source);
3239 }
3240 }
3241 onHandleError(parentZoneDelegate, currentZone, targetZone, error) {
3242 if (this._delegateSpec && this._delegateSpec.onHandleError) {
3243 return this._delegateSpec.onHandleError(parentZoneDelegate, currentZone, targetZone, error);
3244 }
3245 else {
3246 return parentZoneDelegate.handleError(targetZone, error);
3247 }
3248 }
3249 onScheduleTask(parentZoneDelegate, currentZone, targetZone, task) {
3250 if (task.type !== 'eventTask') {
3251 this.tasks.push(task);
3252 }
3253 if (this._delegateSpec && this._delegateSpec.onScheduleTask) {
3254 return this._delegateSpec.onScheduleTask(parentZoneDelegate, currentZone, targetZone, task);
3255 }
3256 else {
3257 return parentZoneDelegate.scheduleTask(targetZone, task);
3258 }
3259 }
3260 onInvokeTask(parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs) {
3261 if (task.type !== 'eventTask') {
3262 this.removeFromTasks(task);
3263 }
3264 this.tryTriggerHasTask(parentZoneDelegate, currentZone, targetZone);
3265 if (this._delegateSpec && this._delegateSpec.onInvokeTask) {
3266 return this._delegateSpec.onInvokeTask(parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs);
3267 }
3268 else {
3269 return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs);
3270 }
3271 }
3272 onCancelTask(parentZoneDelegate, currentZone, targetZone, task) {
3273 if (task.type !== 'eventTask') {
3274 this.removeFromTasks(task);
3275 }
3276 this.tryTriggerHasTask(parentZoneDelegate, currentZone, targetZone);
3277 if (this._delegateSpec && this._delegateSpec.onCancelTask) {
3278 return this._delegateSpec.onCancelTask(parentZoneDelegate, currentZone, targetZone, task);
3279 }
3280 else {
3281 return parentZoneDelegate.cancelTask(targetZone, task);
3282 }
3283 }
3284 onHasTask(delegate, current, target, hasTaskState) {
3285 this.lastTaskState = hasTaskState;
3286 if (this._delegateSpec && this._delegateSpec.onHasTask) {
3287 this._delegateSpec.onHasTask(delegate, current, target, hasTaskState);
3288 }
3289 else {
3290 delegate.hasTask(target, hasTaskState);
3291 }
3292 }
3293}
3294// Export the class so that new instances can be created with proper
3295// constructor params.
3296Zone['ProxyZoneSpec'] = ProxyZoneSpec;
3297
3298/**
3299 * @license
3300 * Copyright Google LLC All Rights Reserved.
3301 *
3302 * Use of this source code is governed by an MIT-style license that can be
3303 * found in the LICENSE file at https://angular.io/license
3304 */
3305class SyncTestZoneSpec {
3306 constructor(namePrefix) {
3307 this.runZone = Zone.current;
3308 this.name = 'syncTestZone for ' + namePrefix;
3309 }
3310 onScheduleTask(delegate, current, target, task) {
3311 switch (task.type) {
3312 case 'microTask':
3313 case 'macroTask':
3314 throw new Error(`Cannot call ${task.source} from within a sync test.`);
3315 case 'eventTask':
3316 task = delegate.scheduleTask(target, task);
3317 break;
3318 }
3319 return task;
3320 }
3321}
3322// Export the class so that new instances can be created with proper
3323// constructor params.
3324Zone['SyncTestZoneSpec'] = SyncTestZoneSpec;
3325
3326/**
3327 * @license
3328 * Copyright Google LLC All Rights Reserved.
3329 *
3330 * Use of this source code is governed by an MIT-style license that can be
3331 * found in the LICENSE file at https://angular.io/license
3332 */
3333Zone.__load_patch('jasmine', (global, Zone, api) => {
3334 const __extends = function (d, b) {
3335 for (const p in b)
3336 if (b.hasOwnProperty(p))
3337 d[p] = b[p];
3338 function __() {
3339 this.constructor = d;
3340 }
3341 d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new __());
3342 };
3343 // Patch jasmine's describe/it/beforeEach/afterEach functions so test code always runs
3344 // in a testZone (ProxyZone). (See: angular/zone.js#91 & angular/angular#10503)
3345 if (!Zone)
3346 throw new Error('Missing: zone.js');
3347 if (typeof jest !== 'undefined') {
3348 // return if jasmine is a light implementation inside jest
3349 // in this case, we are running inside jest not jasmine
3350 return;
3351 }
3352 if (typeof jasmine == 'undefined' || jasmine['__zone_patch__']) {
3353 return;
3354 }
3355 jasmine['__zone_patch__'] = true;
3356 const SyncTestZoneSpec = Zone['SyncTestZoneSpec'];
3357 const ProxyZoneSpec = Zone['ProxyZoneSpec'];
3358 if (!SyncTestZoneSpec)
3359 throw new Error('Missing: SyncTestZoneSpec');
3360 if (!ProxyZoneSpec)
3361 throw new Error('Missing: ProxyZoneSpec');
3362 const ambientZone = Zone.current;
3363 // Create a synchronous-only zone in which to run `describe` blocks in order to raise an
3364 // error if any asynchronous operations are attempted inside of a `describe` but outside of
3365 // a `beforeEach` or `it`.
3366 const syncZone = ambientZone.fork(new SyncTestZoneSpec('jasmine.describe'));
3367 const symbol = Zone.__symbol__;
3368 // whether patch jasmine clock when in fakeAsync
3369 const disablePatchingJasmineClock = global[symbol('fakeAsyncDisablePatchingClock')] === true;
3370 // the original variable name fakeAsyncPatchLock is not accurate, so the name will be
3371 // fakeAsyncAutoFakeAsyncWhenClockPatched and if this enablePatchingJasmineClock is false, we also
3372 // automatically disable the auto jump into fakeAsync feature
3373 const enableAutoFakeAsyncWhenClockPatched = !disablePatchingJasmineClock &&
3374 ((global[symbol('fakeAsyncPatchLock')] === true) ||
3375 (global[symbol('fakeAsyncAutoFakeAsyncWhenClockPatched')] === true));
3376 const ignoreUnhandledRejection = global[symbol('ignoreUnhandledRejection')] === true;
3377 if (!ignoreUnhandledRejection) {
3378 const globalErrors = jasmine.GlobalErrors;
3379 if (globalErrors && !jasmine[symbol('GlobalErrors')]) {
3380 jasmine[symbol('GlobalErrors')] = globalErrors;
3381 jasmine.GlobalErrors = function () {
3382 const instance = new globalErrors();
3383 const originalInstall = instance.install;
3384 if (originalInstall && !instance[symbol('install')]) {
3385 instance[symbol('install')] = originalInstall;
3386 instance.install = function () {
3387 const originalHandlers = process.listeners('unhandledRejection');
3388 const r = originalInstall.apply(this, arguments);
3389 process.removeAllListeners('unhandledRejection');
3390 if (originalHandlers) {
3391 originalHandlers.forEach(h => process.on('unhandledRejection', h));
3392 }
3393 return r;
3394 };
3395 }
3396 return instance;
3397 };
3398 }
3399 }
3400 // Monkey patch all of the jasmine DSL so that each function runs in appropriate zone.
3401 const jasmineEnv = jasmine.getEnv();
3402 ['describe', 'xdescribe', 'fdescribe'].forEach(methodName => {
3403 let originalJasmineFn = jasmineEnv[methodName];
3404 jasmineEnv[methodName] = function (description, specDefinitions) {
3405 return originalJasmineFn.call(this, description, wrapDescribeInZone(specDefinitions));
3406 };
3407 });
3408 ['it', 'xit', 'fit'].forEach(methodName => {
3409 let originalJasmineFn = jasmineEnv[methodName];
3410 jasmineEnv[symbol(methodName)] = originalJasmineFn;
3411 jasmineEnv[methodName] = function (description, specDefinitions, timeout) {
3412 arguments[1] = wrapTestInZone(specDefinitions);
3413 return originalJasmineFn.apply(this, arguments);
3414 };
3415 });
3416 ['beforeEach', 'afterEach', 'beforeAll', 'afterAll'].forEach(methodName => {
3417 let originalJasmineFn = jasmineEnv[methodName];
3418 jasmineEnv[symbol(methodName)] = originalJasmineFn;
3419 jasmineEnv[methodName] = function (specDefinitions, timeout) {
3420 arguments[0] = wrapTestInZone(specDefinitions);
3421 return originalJasmineFn.apply(this, arguments);
3422 };
3423 });
3424 if (!disablePatchingJasmineClock) {
3425 // need to patch jasmine.clock().mockDate and jasmine.clock().tick() so
3426 // they can work properly in FakeAsyncTest
3427 const originalClockFn = (jasmine[symbol('clock')] = jasmine['clock']);
3428 jasmine['clock'] = function () {
3429 const clock = originalClockFn.apply(this, arguments);
3430 if (!clock[symbol('patched')]) {
3431 clock[symbol('patched')] = symbol('patched');
3432 const originalTick = (clock[symbol('tick')] = clock.tick);
3433 clock.tick = function () {
3434 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3435 if (fakeAsyncZoneSpec) {
3436 return fakeAsyncZoneSpec.tick.apply(fakeAsyncZoneSpec, arguments);
3437 }
3438 return originalTick.apply(this, arguments);
3439 };
3440 const originalMockDate = (clock[symbol('mockDate')] = clock.mockDate);
3441 clock.mockDate = function () {
3442 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3443 if (fakeAsyncZoneSpec) {
3444 const dateTime = arguments.length > 0 ? arguments[0] : new Date();
3445 return fakeAsyncZoneSpec.setFakeBaseSystemTime.apply(fakeAsyncZoneSpec, dateTime && typeof dateTime.getTime === 'function' ? [dateTime.getTime()] :
3446 arguments);
3447 }
3448 return originalMockDate.apply(this, arguments);
3449 };
3450 // for auto go into fakeAsync feature, we need the flag to enable it
3451 if (enableAutoFakeAsyncWhenClockPatched) {
3452 ['install', 'uninstall'].forEach(methodName => {
3453 const originalClockFn = (clock[symbol(methodName)] = clock[methodName]);
3454 clock[methodName] = function () {
3455 const FakeAsyncTestZoneSpec = Zone['FakeAsyncTestZoneSpec'];
3456 if (FakeAsyncTestZoneSpec) {
3457 jasmine[symbol('clockInstalled')] = 'install' === methodName;
3458 return;
3459 }
3460 return originalClockFn.apply(this, arguments);
3461 };
3462 });
3463 }
3464 }
3465 return clock;
3466 };
3467 }
3468 // monkey patch createSpyObj to make properties enumerable to true
3469 if (!jasmine[Zone.__symbol__('createSpyObj')]) {
3470 const originalCreateSpyObj = jasmine.createSpyObj;
3471 jasmine[Zone.__symbol__('createSpyObj')] = originalCreateSpyObj;
3472 jasmine.createSpyObj = function () {
3473 const args = Array.prototype.slice.call(arguments);
3474 const propertyNames = args.length >= 3 ? args[2] : null;
3475 let spyObj;
3476 if (propertyNames) {
3477 const defineProperty = Object.defineProperty;
3478 Object.defineProperty = function (obj, p, attributes) {
3479 return defineProperty.call(this, obj, p, Object.assign(Object.assign({}, attributes), { configurable: true, enumerable: true }));
3480 };
3481 try {
3482 spyObj = originalCreateSpyObj.apply(this, args);
3483 }
3484 finally {
3485 Object.defineProperty = defineProperty;
3486 }
3487 }
3488 else {
3489 spyObj = originalCreateSpyObj.apply(this, args);
3490 }
3491 return spyObj;
3492 };
3493 }
3494 /**
3495 * Gets a function wrapping the body of a Jasmine `describe` block to execute in a
3496 * synchronous-only zone.
3497 */
3498 function wrapDescribeInZone(describeBody) {
3499 return function () {
3500 return syncZone.run(describeBody, this, arguments);
3501 };
3502 }
3503 function runInTestZone(testBody, applyThis, queueRunner, done) {
3504 const isClockInstalled = !!jasmine[symbol('clockInstalled')];
3505 const testProxyZoneSpec = queueRunner.testProxyZoneSpec;
3506 const testProxyZone = queueRunner.testProxyZone;
3507 if (isClockInstalled && enableAutoFakeAsyncWhenClockPatched) {
3508 // auto run a fakeAsync
3509 const fakeAsyncModule = Zone[Zone.__symbol__('fakeAsyncTest')];
3510 if (fakeAsyncModule && typeof fakeAsyncModule.fakeAsync === 'function') {
3511 testBody = fakeAsyncModule.fakeAsync(testBody);
3512 }
3513 }
3514 if (done) {
3515 return testProxyZone.run(testBody, applyThis, [done]);
3516 }
3517 else {
3518 return testProxyZone.run(testBody, applyThis);
3519 }
3520 }
3521 /**
3522 * Gets a function wrapping the body of a Jasmine `it/beforeEach/afterEach` block to
3523 * execute in a ProxyZone zone.
3524 * This will run in `testProxyZone`. The `testProxyZone` will be reset by the `ZoneQueueRunner`
3525 */
3526 function wrapTestInZone(testBody) {
3527 // The `done` callback is only passed through if the function expects at least one argument.
3528 // Note we have to make a function with correct number of arguments, otherwise jasmine will
3529 // think that all functions are sync or async.
3530 return (testBody && (testBody.length ? function (done) {
3531 return runInTestZone(testBody, this, this.queueRunner, done);
3532 } : function () {
3533 return runInTestZone(testBody, this, this.queueRunner);
3534 }));
3535 }
3536 const QueueRunner = jasmine.QueueRunner;
3537 jasmine.QueueRunner = (function (_super) {
3538 __extends(ZoneQueueRunner, _super);
3539 function ZoneQueueRunner(attrs) {
3540 if (attrs.onComplete) {
3541 attrs.onComplete = (fn => () => {
3542 // All functions are done, clear the test zone.
3543 this.testProxyZone = null;
3544 this.testProxyZoneSpec = null;
3545 ambientZone.scheduleMicroTask('jasmine.onComplete', fn);
3546 })(attrs.onComplete);
3547 }
3548 const nativeSetTimeout = global[Zone.__symbol__('setTimeout')];
3549 const nativeClearTimeout = global[Zone.__symbol__('clearTimeout')];
3550 if (nativeSetTimeout) {
3551 // should run setTimeout inside jasmine outside of zone
3552 attrs.timeout = {
3553 setTimeout: nativeSetTimeout ? nativeSetTimeout : global.setTimeout,
3554 clearTimeout: nativeClearTimeout ? nativeClearTimeout : global.clearTimeout
3555 };
3556 }
3557 // create a userContext to hold the queueRunner itself
3558 // so we can access the testProxy in it/xit/beforeEach ...
3559 if (jasmine.UserContext) {
3560 if (!attrs.userContext) {
3561 attrs.userContext = new jasmine.UserContext();
3562 }
3563 attrs.userContext.queueRunner = this;
3564 }
3565 else {
3566 if (!attrs.userContext) {
3567 attrs.userContext = {};
3568 }
3569 attrs.userContext.queueRunner = this;
3570 }
3571 // patch attrs.onException
3572 const onException = attrs.onException;
3573 attrs.onException = function (error) {
3574 if (error &&
3575 error.message ===
3576 'Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.') {
3577 // jasmine timeout, we can make the error message more
3578 // reasonable to tell what tasks are pending
3579 const proxyZoneSpec = this && this.testProxyZoneSpec;
3580 if (proxyZoneSpec) {
3581 const pendingTasksInfo = proxyZoneSpec.getAndClearPendingTasksInfo();
3582 try {
3583 // try catch here in case error.message is not writable
3584 error.message += pendingTasksInfo;
3585 }
3586 catch (err) {
3587 }
3588 }
3589 }
3590 if (onException) {
3591 onException.call(this, error);
3592 }
3593 };
3594 _super.call(this, attrs);
3595 }
3596 ZoneQueueRunner.prototype.execute = function () {
3597 let zone = Zone.current;
3598 let isChildOfAmbientZone = false;
3599 while (zone) {
3600 if (zone === ambientZone) {
3601 isChildOfAmbientZone = true;
3602 break;
3603 }
3604 zone = zone.parent;
3605 }
3606 if (!isChildOfAmbientZone)
3607 throw new Error('Unexpected Zone: ' + Zone.current.name);
3608 // This is the zone which will be used for running individual tests.
3609 // It will be a proxy zone, so that the tests function can retroactively install
3610 // different zones.
3611 // Example:
3612 // - In beforeEach() do childZone = Zone.current.fork(...);
3613 // - In it() try to do fakeAsync(). The issue is that because the beforeEach forked the
3614 // zone outside of fakeAsync it will be able to escape the fakeAsync rules.
3615 // - Because ProxyZone is parent fo `childZone` fakeAsync can retroactively add
3616 // fakeAsync behavior to the childZone.
3617 this.testProxyZoneSpec = new ProxyZoneSpec();
3618 this.testProxyZone = ambientZone.fork(this.testProxyZoneSpec);
3619 if (!Zone.currentTask) {
3620 // if we are not running in a task then if someone would register a
3621 // element.addEventListener and then calling element.click() the
3622 // addEventListener callback would think that it is the top most task and would
3623 // drain the microtask queue on element.click() which would be incorrect.
3624 // For this reason we always force a task when running jasmine tests.
3625 Zone.current.scheduleMicroTask('jasmine.execute().forceTask', () => QueueRunner.prototype.execute.call(this));
3626 }
3627 else {
3628 _super.prototype.execute.call(this);
3629 }
3630 };
3631 return ZoneQueueRunner;
3632 })(QueueRunner);
3633});
3634
3635/**
3636 * @license
3637 * Copyright Google LLC All Rights Reserved.
3638 *
3639 * Use of this source code is governed by an MIT-style license that can be
3640 * found in the LICENSE file at https://angular.io/license
3641 */
3642Zone.__load_patch('jest', (context, Zone, api) => {
3643 if (typeof jest === 'undefined' || jest['__zone_patch__']) {
3644 return;
3645 }
3646 jest['__zone_patch__'] = true;
3647 const ProxyZoneSpec = Zone['ProxyZoneSpec'];
3648 const SyncTestZoneSpec = Zone['SyncTestZoneSpec'];
3649 if (!ProxyZoneSpec) {
3650 throw new Error('Missing ProxyZoneSpec');
3651 }
3652 const rootZone = Zone.current;
3653 const syncZone = rootZone.fork(new SyncTestZoneSpec('jest.describe'));
3654 const proxyZoneSpec = new ProxyZoneSpec();
3655 const proxyZone = rootZone.fork(proxyZoneSpec);
3656 function wrapDescribeFactoryInZone(originalJestFn) {
3657 return function (...tableArgs) {
3658 const originalDescribeFn = originalJestFn.apply(this, tableArgs);
3659 return function (...args) {
3660 args[1] = wrapDescribeInZone(args[1]);
3661 return originalDescribeFn.apply(this, args);
3662 };
3663 };
3664 }
3665 function wrapTestFactoryInZone(originalJestFn) {
3666 return function (...tableArgs) {
3667 return function (...args) {
3668 args[1] = wrapTestInZone(args[1]);
3669 return originalJestFn.apply(this, tableArgs).apply(this, args);
3670 };
3671 };
3672 }
3673 /**
3674 * Gets a function wrapping the body of a jest `describe` block to execute in a
3675 * synchronous-only zone.
3676 */
3677 function wrapDescribeInZone(describeBody) {
3678 return function (...args) {
3679 return syncZone.run(describeBody, this, args);
3680 };
3681 }
3682 /**
3683 * Gets a function wrapping the body of a jest `it/beforeEach/afterEach` block to
3684 * execute in a ProxyZone zone.
3685 * This will run in the `proxyZone`.
3686 */
3687 function wrapTestInZone(testBody, isTestFunc = false) {
3688 if (typeof testBody !== 'function') {
3689 return testBody;
3690 }
3691 const wrappedFunc = function () {
3692 if (Zone[api.symbol('useFakeTimersCalled')] === true && testBody &&
3693 !testBody.isFakeAsync) {
3694 // jest.useFakeTimers is called, run into fakeAsyncTest automatically.
3695 const fakeAsyncModule = Zone[Zone.__symbol__('fakeAsyncTest')];
3696 if (fakeAsyncModule && typeof fakeAsyncModule.fakeAsync === 'function') {
3697 testBody = fakeAsyncModule.fakeAsync(testBody);
3698 }
3699 }
3700 proxyZoneSpec.isTestFunc = isTestFunc;
3701 return proxyZone.run(testBody, null, arguments);
3702 };
3703 // Update the length of wrappedFunc to be the same as the length of the testBody
3704 // So jest core can handle whether the test function has `done()` or not correctly
3705 Object.defineProperty(wrappedFunc, 'length', { configurable: true, writable: true, enumerable: false });
3706 wrappedFunc.length = testBody.length;
3707 return wrappedFunc;
3708 }
3709 ['describe', 'xdescribe', 'fdescribe'].forEach(methodName => {
3710 let originalJestFn = context[methodName];
3711 if (context[Zone.__symbol__(methodName)]) {
3712 return;
3713 }
3714 context[Zone.__symbol__(methodName)] = originalJestFn;
3715 context[methodName] = function (...args) {
3716 args[1] = wrapDescribeInZone(args[1]);
3717 return originalJestFn.apply(this, args);
3718 };
3719 context[methodName].each = wrapDescribeFactoryInZone(originalJestFn.each);
3720 });
3721 context.describe.only = context.fdescribe;
3722 context.describe.skip = context.xdescribe;
3723 ['it', 'xit', 'fit', 'test', 'xtest'].forEach(methodName => {
3724 let originalJestFn = context[methodName];
3725 if (context[Zone.__symbol__(methodName)]) {
3726 return;
3727 }
3728 context[Zone.__symbol__(methodName)] = originalJestFn;
3729 context[methodName] = function (...args) {
3730 args[1] = wrapTestInZone(args[1], true);
3731 return originalJestFn.apply(this, args);
3732 };
3733 context[methodName].each = wrapTestFactoryInZone(originalJestFn.each);
3734 context[methodName].todo = originalJestFn.todo;
3735 });
3736 context.it.only = context.fit;
3737 context.it.skip = context.xit;
3738 context.test.only = context.fit;
3739 context.test.skip = context.xit;
3740 ['beforeEach', 'afterEach', 'beforeAll', 'afterAll'].forEach(methodName => {
3741 let originalJestFn = context[methodName];
3742 if (context[Zone.__symbol__(methodName)]) {
3743 return;
3744 }
3745 context[Zone.__symbol__(methodName)] = originalJestFn;
3746 context[methodName] = function (...args) {
3747 args[0] = wrapTestInZone(args[0]);
3748 return originalJestFn.apply(this, args);
3749 };
3750 });
3751 Zone.patchJestObject = function patchJestObject(Timer, isModern = false) {
3752 // check whether currently the test is inside fakeAsync()
3753 function isPatchingFakeTimer() {
3754 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3755 return !!fakeAsyncZoneSpec;
3756 }
3757 // check whether the current function is inside `test/it` or other methods
3758 // such as `describe/beforeEach`
3759 function isInTestFunc() {
3760 const proxyZoneSpec = Zone.current.get('ProxyZoneSpec');
3761 return proxyZoneSpec && proxyZoneSpec.isTestFunc;
3762 }
3763 if (Timer[api.symbol('fakeTimers')]) {
3764 return;
3765 }
3766 Timer[api.symbol('fakeTimers')] = true;
3767 // patch jest fakeTimer internal method to make sure no console.warn print out
3768 api.patchMethod(Timer, '_checkFakeTimers', delegate => {
3769 return function (self, args) {
3770 if (isPatchingFakeTimer()) {
3771 return true;
3772 }
3773 else {
3774 return delegate.apply(self, args);
3775 }
3776 };
3777 });
3778 // patch useFakeTimers(), set useFakeTimersCalled flag, and make test auto run into fakeAsync
3779 api.patchMethod(Timer, 'useFakeTimers', delegate => {
3780 return function (self, args) {
3781 Zone[api.symbol('useFakeTimersCalled')] = true;
3782 if (isModern || isInTestFunc()) {
3783 return delegate.apply(self, args);
3784 }
3785 return self;
3786 };
3787 });
3788 // patch useRealTimers(), unset useFakeTimers flag
3789 api.patchMethod(Timer, 'useRealTimers', delegate => {
3790 return function (self, args) {
3791 Zone[api.symbol('useFakeTimersCalled')] = false;
3792 if (isModern || isInTestFunc()) {
3793 return delegate.apply(self, args);
3794 }
3795 return self;
3796 };
3797 });
3798 // patch setSystemTime(), call setCurrentRealTime() in the fakeAsyncTest
3799 api.patchMethod(Timer, 'setSystemTime', delegate => {
3800 return function (self, args) {
3801 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3802 if (fakeAsyncZoneSpec && isPatchingFakeTimer()) {
3803 fakeAsyncZoneSpec.setFakeBaseSystemTime(args[0]);
3804 }
3805 else {
3806 return delegate.apply(self, args);
3807 }
3808 };
3809 });
3810 // patch getSystemTime(), call getCurrentRealTime() in the fakeAsyncTest
3811 api.patchMethod(Timer, 'getRealSystemTime', delegate => {
3812 return function (self, args) {
3813 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3814 if (fakeAsyncZoneSpec && isPatchingFakeTimer()) {
3815 return fakeAsyncZoneSpec.getRealSystemTime();
3816 }
3817 else {
3818 return delegate.apply(self, args);
3819 }
3820 };
3821 });
3822 // patch runAllTicks(), run all microTasks inside fakeAsync
3823 api.patchMethod(Timer, 'runAllTicks', delegate => {
3824 return function (self, args) {
3825 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3826 if (fakeAsyncZoneSpec) {
3827 fakeAsyncZoneSpec.flushMicrotasks();
3828 }
3829 else {
3830 return delegate.apply(self, args);
3831 }
3832 };
3833 });
3834 // patch runAllTimers(), run all macroTasks inside fakeAsync
3835 api.patchMethod(Timer, 'runAllTimers', delegate => {
3836 return function (self, args) {
3837 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3838 if (fakeAsyncZoneSpec) {
3839 fakeAsyncZoneSpec.flush(100, true);
3840 }
3841 else {
3842 return delegate.apply(self, args);
3843 }
3844 };
3845 });
3846 // patch advanceTimersByTime(), call tick() in the fakeAsyncTest
3847 api.patchMethod(Timer, 'advanceTimersByTime', delegate => {
3848 return function (self, args) {
3849 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3850 if (fakeAsyncZoneSpec) {
3851 fakeAsyncZoneSpec.tick(args[0]);
3852 }
3853 else {
3854 return delegate.apply(self, args);
3855 }
3856 };
3857 });
3858 // patch runOnlyPendingTimers(), call flushOnlyPendingTimers() in the fakeAsyncTest
3859 api.patchMethod(Timer, 'runOnlyPendingTimers', delegate => {
3860 return function (self, args) {
3861 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3862 if (fakeAsyncZoneSpec) {
3863 fakeAsyncZoneSpec.flushOnlyPendingTimers();
3864 }
3865 else {
3866 return delegate.apply(self, args);
3867 }
3868 };
3869 });
3870 // patch advanceTimersToNextTimer(), call tickToNext() in the fakeAsyncTest
3871 api.patchMethod(Timer, 'advanceTimersToNextTimer', delegate => {
3872 return function (self, args) {
3873 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3874 if (fakeAsyncZoneSpec) {
3875 fakeAsyncZoneSpec.tickToNext(args[0]);
3876 }
3877 else {
3878 return delegate.apply(self, args);
3879 }
3880 };
3881 });
3882 // patch clearAllTimers(), call removeAllTimers() in the fakeAsyncTest
3883 api.patchMethod(Timer, 'clearAllTimers', delegate => {
3884 return function (self, args) {
3885 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3886 if (fakeAsyncZoneSpec) {
3887 fakeAsyncZoneSpec.removeAllTimers();
3888 }
3889 else {
3890 return delegate.apply(self, args);
3891 }
3892 };
3893 });
3894 // patch getTimerCount(), call getTimerCount() in the fakeAsyncTest
3895 api.patchMethod(Timer, 'getTimerCount', delegate => {
3896 return function (self, args) {
3897 const fakeAsyncZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
3898 if (fakeAsyncZoneSpec) {
3899 return fakeAsyncZoneSpec.getTimerCount();
3900 }
3901 else {
3902 return delegate.apply(self, args);
3903 }
3904 };
3905 });
3906 };
3907});
3908
3909/**
3910 * @license
3911 * Copyright Google LLC All Rights Reserved.
3912 *
3913 * Use of this source code is governed by an MIT-style license that can be
3914 * found in the LICENSE file at https://angular.io/license
3915 */
3916Zone.__load_patch('mocha', (global, Zone) => {
3917 const Mocha = global.Mocha;
3918 if (typeof Mocha === 'undefined') {
3919 // return if Mocha is not available, because now zone-testing
3920 // will load mocha patch with jasmine/jest patch
3921 return;
3922 }
3923 if (typeof Zone === 'undefined') {
3924 throw new Error('Missing Zone.js');
3925 }
3926 const ProxyZoneSpec = Zone['ProxyZoneSpec'];
3927 const SyncTestZoneSpec = Zone['SyncTestZoneSpec'];
3928 if (!ProxyZoneSpec) {
3929 throw new Error('Missing ProxyZoneSpec');
3930 }
3931 if (Mocha['__zone_patch__']) {
3932 throw new Error('"Mocha" has already been patched with "Zone".');
3933 }
3934 Mocha['__zone_patch__'] = true;
3935 const rootZone = Zone.current;
3936 const syncZone = rootZone.fork(new SyncTestZoneSpec('Mocha.describe'));
3937 let testZone = null;
3938 const suiteZone = rootZone.fork(new ProxyZoneSpec());
3939 const mochaOriginal = {
3940 after: Mocha.after,
3941 afterEach: Mocha.afterEach,
3942 before: Mocha.before,
3943 beforeEach: Mocha.beforeEach,
3944 describe: Mocha.describe,
3945 it: Mocha.it
3946 };
3947 function modifyArguments(args, syncTest, asyncTest) {
3948 for (let i = 0; i < args.length; i++) {
3949 let arg = args[i];
3950 if (typeof arg === 'function') {
3951 // The `done` callback is only passed through if the function expects at
3952 // least one argument.
3953 // Note we have to make a function with correct number of arguments,
3954 // otherwise mocha will
3955 // think that all functions are sync or async.
3956 args[i] = (arg.length === 0) ? syncTest(arg) : asyncTest(arg);
3957 // Mocha uses toString to view the test body in the result list, make sure we return the
3958 // correct function body
3959 args[i].toString = function () {
3960 return arg.toString();
3961 };
3962 }
3963 }
3964 return args;
3965 }
3966 function wrapDescribeInZone(args) {
3967 const syncTest = function (fn) {
3968 return function () {
3969 return syncZone.run(fn, this, arguments);
3970 };
3971 };
3972 return modifyArguments(args, syncTest);
3973 }
3974 function wrapTestInZone(args) {
3975 const asyncTest = function (fn) {
3976 return function (done) {
3977 return testZone.run(fn, this, [done]);
3978 };
3979 };
3980 const syncTest = function (fn) {
3981 return function () {
3982 return testZone.run(fn, this);
3983 };
3984 };
3985 return modifyArguments(args, syncTest, asyncTest);
3986 }
3987 function wrapSuiteInZone(args) {
3988 const asyncTest = function (fn) {
3989 return function (done) {
3990 return suiteZone.run(fn, this, [done]);
3991 };
3992 };
3993 const syncTest = function (fn) {
3994 return function () {
3995 return suiteZone.run(fn, this);
3996 };
3997 };
3998 return modifyArguments(args, syncTest, asyncTest);
3999 }
4000 global.describe = global.suite = Mocha.describe = function () {
4001 return mochaOriginal.describe.apply(this, wrapDescribeInZone(arguments));
4002 };
4003 global.xdescribe = global.suite.skip = Mocha.describe.skip = function () {
4004 return mochaOriginal.describe.skip.apply(this, wrapDescribeInZone(arguments));
4005 };
4006 global.describe.only = global.suite.only = Mocha.describe.only = function () {
4007 return mochaOriginal.describe.only.apply(this, wrapDescribeInZone(arguments));
4008 };
4009 global.it = global.specify = global.test = Mocha.it = function () {
4010 return mochaOriginal.it.apply(this, wrapTestInZone(arguments));
4011 };
4012 global.xit = global.xspecify = Mocha.it.skip = function () {
4013 return mochaOriginal.it.skip.apply(this, wrapTestInZone(arguments));
4014 };
4015 global.it.only = global.test.only = Mocha.it.only = function () {
4016 return mochaOriginal.it.only.apply(this, wrapTestInZone(arguments));
4017 };
4018 global.after = global.suiteTeardown = Mocha.after = function () {
4019 return mochaOriginal.after.apply(this, wrapSuiteInZone(arguments));
4020 };
4021 global.afterEach = global.teardown = Mocha.afterEach = function () {
4022 return mochaOriginal.afterEach.apply(this, wrapTestInZone(arguments));
4023 };
4024 global.before = global.suiteSetup = Mocha.before = function () {
4025 return mochaOriginal.before.apply(this, wrapSuiteInZone(arguments));
4026 };
4027 global.beforeEach = global.setup = Mocha.beforeEach = function () {
4028 return mochaOriginal.beforeEach.apply(this, wrapTestInZone(arguments));
4029 };
4030 ((originalRunTest, originalRun) => {
4031 Mocha.Runner.prototype.runTest = function (fn) {
4032 Zone.current.scheduleMicroTask('mocha.forceTask', () => {
4033 originalRunTest.call(this, fn);
4034 });
4035 };
4036 Mocha.Runner.prototype.run = function (fn) {
4037 this.on('test', (e) => {
4038 testZone = rootZone.fork(new ProxyZoneSpec());
4039 });
4040 this.on('fail', (test, err) => {
4041 const proxyZoneSpec = testZone && testZone.get('ProxyZoneSpec');
4042 if (proxyZoneSpec && err) {
4043 try {
4044 // try catch here in case err.message is not writable
4045 err.message += proxyZoneSpec.getAndClearPendingTasksInfo();
4046 }
4047 catch (error) {
4048 }
4049 }
4050 });
4051 return originalRun.call(this, fn);
4052 };
4053 })(Mocha.Runner.prototype.runTest, Mocha.Runner.prototype.run);
4054});
4055
4056/**
4057 * @license
4058 * Copyright Google LLC All Rights Reserved.
4059 *
4060 * Use of this source code is governed by an MIT-style license that can be
4061 * found in the LICENSE file at https://angular.io/license
4062 */
4063(function (_global) {
4064 class AsyncTestZoneSpec {
4065 constructor(finishCallback, failCallback, namePrefix) {
4066 this.finishCallback = finishCallback;
4067 this.failCallback = failCallback;
4068 this._pendingMicroTasks = false;
4069 this._pendingMacroTasks = false;
4070 this._alreadyErrored = false;
4071 this._isSync = false;
4072 this.runZone = Zone.current;
4073 this.unresolvedChainedPromiseCount = 0;
4074 this.supportWaitUnresolvedChainedPromise = false;
4075 this.name = 'asyncTestZone for ' + namePrefix;
4076 this.properties = { 'AsyncTestZoneSpec': this };
4077 this.supportWaitUnresolvedChainedPromise =
4078 _global[Zone.__symbol__('supportWaitUnResolvedChainedPromise')] === true;
4079 }
4080 isUnresolvedChainedPromisePending() {
4081 return this.unresolvedChainedPromiseCount > 0;
4082 }
4083 _finishCallbackIfDone() {
4084 if (!(this._pendingMicroTasks || this._pendingMacroTasks ||
4085 (this.supportWaitUnresolvedChainedPromise && this.isUnresolvedChainedPromisePending()))) {
4086 // We do this because we would like to catch unhandled rejected promises.
4087 this.runZone.run(() => {
4088 setTimeout(() => {
4089 if (!this._alreadyErrored && !(this._pendingMicroTasks || this._pendingMacroTasks)) {
4090 this.finishCallback();
4091 }
4092 }, 0);
4093 });
4094 }
4095 }
4096 patchPromiseForTest() {
4097 if (!this.supportWaitUnresolvedChainedPromise) {
4098 return;
4099 }
4100 const patchPromiseForTest = Promise[Zone.__symbol__('patchPromiseForTest')];
4101 if (patchPromiseForTest) {
4102 patchPromiseForTest();
4103 }
4104 }
4105 unPatchPromiseForTest() {
4106 if (!this.supportWaitUnresolvedChainedPromise) {
4107 return;
4108 }
4109 const unPatchPromiseForTest = Promise[Zone.__symbol__('unPatchPromiseForTest')];
4110 if (unPatchPromiseForTest) {
4111 unPatchPromiseForTest();
4112 }
4113 }
4114 onScheduleTask(delegate, current, target, task) {
4115 if (task.type !== 'eventTask') {
4116 this._isSync = false;
4117 }
4118 if (task.type === 'microTask' && task.data && task.data instanceof Promise) {
4119 // check whether the promise is a chained promise
4120 if (task.data[AsyncTestZoneSpec.symbolParentUnresolved] === true) {
4121 // chained promise is being scheduled
4122 this.unresolvedChainedPromiseCount--;
4123 }
4124 }
4125 return delegate.scheduleTask(target, task);
4126 }
4127 onInvokeTask(delegate, current, target, task, applyThis, applyArgs) {
4128 if (task.type !== 'eventTask') {
4129 this._isSync = false;
4130 }
4131 return delegate.invokeTask(target, task, applyThis, applyArgs);
4132 }
4133 onCancelTask(delegate, current, target, task) {
4134 if (task.type !== 'eventTask') {
4135 this._isSync = false;
4136 }
4137 return delegate.cancelTask(target, task);
4138 }
4139 // Note - we need to use onInvoke at the moment to call finish when a test is
4140 // fully synchronous. TODO(juliemr): remove this when the logic for
4141 // onHasTask changes and it calls whenever the task queues are dirty.
4142 // updated by(JiaLiPassion), only call finish callback when no task
4143 // was scheduled/invoked/canceled.
4144 onInvoke(parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) {
4145 try {
4146 this._isSync = true;
4147 return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source);
4148 }
4149 finally {
4150 const afterTaskCounts = parentZoneDelegate._taskCounts;
4151 if (this._isSync) {
4152 this._finishCallbackIfDone();
4153 }
4154 }
4155 }
4156 onHandleError(parentZoneDelegate, currentZone, targetZone, error) {
4157 // Let the parent try to handle the error.
4158 const result = parentZoneDelegate.handleError(targetZone, error);
4159 if (result) {
4160 this.failCallback(error);
4161 this._alreadyErrored = true;
4162 }
4163 return false;
4164 }
4165 onHasTask(delegate, current, target, hasTaskState) {
4166 delegate.hasTask(target, hasTaskState);
4167 if (hasTaskState.change == 'microTask') {
4168 this._pendingMicroTasks = hasTaskState.microTask;
4169 this._finishCallbackIfDone();
4170 }
4171 else if (hasTaskState.change == 'macroTask') {
4172 this._pendingMacroTasks = hasTaskState.macroTask;
4173 this._finishCallbackIfDone();
4174 }
4175 }
4176 }
4177 AsyncTestZoneSpec.symbolParentUnresolved = Zone.__symbol__('parentUnresolved');
4178 // Export the class so that new instances can be created with proper
4179 // constructor params.
4180 Zone['AsyncTestZoneSpec'] = AsyncTestZoneSpec;
4181})(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global);
4182Zone.__load_patch('asynctest', (global, Zone, api) => {
4183 /**
4184 * Wraps a test function in an asynchronous test zone. The test will automatically
4185 * complete when all asynchronous calls within this zone are done.
4186 */
4187 Zone[api.symbol('asyncTest')] = function asyncTest(fn) {
4188 // If we're running using the Jasmine test framework, adapt to call the 'done'
4189 // function when asynchronous activity is finished.
4190 if (global.jasmine) {
4191 // Not using an arrow function to preserve context passed from call site
4192 return function (done) {
4193 if (!done) {
4194 // if we run beforeEach in @angular/core/testing/testing_internal then we get no done
4195 // fake it here and assume sync.
4196 done = function () { };
4197 done.fail = function (e) {
4198 throw e;
4199 };
4200 }
4201 runInTestZone(fn, this, done, (err) => {
4202 if (typeof err === 'string') {
4203 return done.fail(new Error(err));
4204 }
4205 else {
4206 done.fail(err);
4207 }
4208 });
4209 };
4210 }
4211 // Otherwise, return a promise which will resolve when asynchronous activity
4212 // is finished. This will be correctly consumed by the Mocha framework with
4213 // it('...', async(myFn)); or can be used in a custom framework.
4214 // Not using an arrow function to preserve context passed from call site
4215 return function () {
4216 return new Promise((finishCallback, failCallback) => {
4217 runInTestZone(fn, this, finishCallback, failCallback);
4218 });
4219 };
4220 };
4221 function runInTestZone(fn, context, finishCallback, failCallback) {
4222 const currentZone = Zone.current;
4223 const AsyncTestZoneSpec = Zone['AsyncTestZoneSpec'];
4224 if (AsyncTestZoneSpec === undefined) {
4225 throw new Error('AsyncTestZoneSpec is needed for the async() test helper but could not be found. ' +
4226 'Please make sure that your environment includes zone.js/dist/async-test.js');
4227 }
4228 const ProxyZoneSpec = Zone['ProxyZoneSpec'];
4229 if (!ProxyZoneSpec) {
4230 throw new Error('ProxyZoneSpec is needed for the async() test helper but could not be found. ' +
4231 'Please make sure that your environment includes zone.js/dist/proxy.js');
4232 }
4233 const proxyZoneSpec = ProxyZoneSpec.get();
4234 ProxyZoneSpec.assertPresent();
4235 // We need to create the AsyncTestZoneSpec outside the ProxyZone.
4236 // If we do it in ProxyZone then we will get to infinite recursion.
4237 const proxyZone = Zone.current.getZoneWith('ProxyZoneSpec');
4238 const previousDelegate = proxyZoneSpec.getDelegate();
4239 proxyZone.parent.run(() => {
4240 const testZoneSpec = new AsyncTestZoneSpec(() => {
4241 // Need to restore the original zone.
4242 if (proxyZoneSpec.getDelegate() == testZoneSpec) {
4243 // Only reset the zone spec if it's
4244 // sill this one. Otherwise, assume
4245 // it's OK.
4246 proxyZoneSpec.setDelegate(previousDelegate);
4247 }
4248 testZoneSpec.unPatchPromiseForTest();
4249 currentZone.run(() => {
4250 finishCallback();
4251 });
4252 }, (error) => {
4253 // Need to restore the original zone.
4254 if (proxyZoneSpec.getDelegate() == testZoneSpec) {
4255 // Only reset the zone spec if it's sill this one. Otherwise, assume it's OK.
4256 proxyZoneSpec.setDelegate(previousDelegate);
4257 }
4258 testZoneSpec.unPatchPromiseForTest();
4259 currentZone.run(() => {
4260 failCallback(error);
4261 });
4262 }, 'test');
4263 proxyZoneSpec.setDelegate(testZoneSpec);
4264 testZoneSpec.patchPromiseForTest();
4265 });
4266 return Zone.current.runGuarded(fn, context);
4267 }
4268});
4269
4270/**
4271 * @license
4272 * Copyright Google LLC All Rights Reserved.
4273 *
4274 * Use of this source code is governed by an MIT-style license that can be
4275 * found in the LICENSE file at https://angular.io/license
4276 */
4277(function (global) {
4278 const OriginalDate = global.Date;
4279 // Since when we compile this file to `es2015`, and if we define
4280 // this `FakeDate` as `class FakeDate`, and then set `FakeDate.prototype`
4281 // there will be an error which is `Cannot assign to read only property 'prototype'`
4282 // so we need to use function implementation here.
4283 function FakeDate() {
4284 if (arguments.length === 0) {
4285 const d = new OriginalDate();
4286 d.setTime(FakeDate.now());
4287 return d;
4288 }
4289 else {
4290 const args = Array.prototype.slice.call(arguments);
4291 return new OriginalDate(...args);
4292 }
4293 }
4294 FakeDate.now = function () {
4295 const fakeAsyncTestZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
4296 if (fakeAsyncTestZoneSpec) {
4297 return fakeAsyncTestZoneSpec.getFakeSystemTime();
4298 }
4299 return OriginalDate.now.apply(this, arguments);
4300 };
4301 FakeDate.UTC = OriginalDate.UTC;
4302 FakeDate.parse = OriginalDate.parse;
4303 // keep a reference for zone patched timer function
4304 const timers = {
4305 setTimeout: global.setTimeout,
4306 setInterval: global.setInterval,
4307 clearTimeout: global.clearTimeout,
4308 clearInterval: global.clearInterval
4309 };
4310 class Scheduler {
4311 constructor() {
4312 // Scheduler queue with the tuple of end time and callback function - sorted by end time.
4313 this._schedulerQueue = [];
4314 // Current simulated time in millis.
4315 this._currentTickTime = 0;
4316 // Current fake system base time in millis.
4317 this._currentFakeBaseSystemTime = OriginalDate.now();
4318 // track requeuePeriodicTimer
4319 this._currentTickRequeuePeriodicEntries = [];
4320 }
4321 getCurrentTickTime() {
4322 return this._currentTickTime;
4323 }
4324 getFakeSystemTime() {
4325 return this._currentFakeBaseSystemTime + this._currentTickTime;
4326 }
4327 setFakeBaseSystemTime(fakeBaseSystemTime) {
4328 this._currentFakeBaseSystemTime = fakeBaseSystemTime;
4329 }
4330 getRealSystemTime() {
4331 return OriginalDate.now();
4332 }
4333 scheduleFunction(cb, delay, options) {
4334 options = Object.assign({
4335 args: [],
4336 isPeriodic: false,
4337 isRequestAnimationFrame: false,
4338 id: -1,
4339 isRequeuePeriodic: false
4340 }, options);
4341 let currentId = options.id < 0 ? Scheduler.nextId++ : options.id;
4342 let endTime = this._currentTickTime + delay;
4343 // Insert so that scheduler queue remains sorted by end time.
4344 let newEntry = {
4345 endTime: endTime,
4346 id: currentId,
4347 func: cb,
4348 args: options.args,
4349 delay: delay,
4350 isPeriodic: options.isPeriodic,
4351 isRequestAnimationFrame: options.isRequestAnimationFrame
4352 };
4353 if (options.isRequeuePeriodic) {
4354 this._currentTickRequeuePeriodicEntries.push(newEntry);
4355 }
4356 let i = 0;
4357 for (; i < this._schedulerQueue.length; i++) {
4358 let currentEntry = this._schedulerQueue[i];
4359 if (newEntry.endTime < currentEntry.endTime) {
4360 break;
4361 }
4362 }
4363 this._schedulerQueue.splice(i, 0, newEntry);
4364 return currentId;
4365 }
4366 removeScheduledFunctionWithId(id) {
4367 for (let i = 0; i < this._schedulerQueue.length; i++) {
4368 if (this._schedulerQueue[i].id == id) {
4369 this._schedulerQueue.splice(i, 1);
4370 break;
4371 }
4372 }
4373 }
4374 removeAll() {
4375 this._schedulerQueue = [];
4376 }
4377 getTimerCount() {
4378 return this._schedulerQueue.length;
4379 }
4380 tickToNext(step = 1, doTick, tickOptions) {
4381 if (this._schedulerQueue.length < step) {
4382 return;
4383 }
4384 // Find the last task currently queued in the scheduler queue and tick
4385 // till that time.
4386 const startTime = this._currentTickTime;
4387 const targetTask = this._schedulerQueue[step - 1];
4388 this.tick(targetTask.endTime - startTime, doTick, tickOptions);
4389 }
4390 tick(millis = 0, doTick, tickOptions) {
4391 let finalTime = this._currentTickTime + millis;
4392 let lastCurrentTime = 0;
4393 tickOptions = Object.assign({ processNewMacroTasksSynchronously: true }, tickOptions);
4394 // we need to copy the schedulerQueue so nested timeout
4395 // will not be wrongly called in the current tick
4396 // https://github.com/angular/angular/issues/33799
4397 const schedulerQueue = tickOptions.processNewMacroTasksSynchronously ?
4398 this._schedulerQueue :
4399 this._schedulerQueue.slice();
4400 if (schedulerQueue.length === 0 && doTick) {
4401 doTick(millis);
4402 return;
4403 }
4404 while (schedulerQueue.length > 0) {
4405 // clear requeueEntries before each loop
4406 this._currentTickRequeuePeriodicEntries = [];
4407 let current = schedulerQueue[0];
4408 if (finalTime < current.endTime) {
4409 // Done processing the queue since it's sorted by endTime.
4410 break;
4411 }
4412 else {
4413 // Time to run scheduled function. Remove it from the head of queue.
4414 let current = schedulerQueue.shift();
4415 if (!tickOptions.processNewMacroTasksSynchronously) {
4416 const idx = this._schedulerQueue.indexOf(current);
4417 if (idx >= 0) {
4418 this._schedulerQueue.splice(idx, 1);
4419 }
4420 }
4421 lastCurrentTime = this._currentTickTime;
4422 this._currentTickTime = current.endTime;
4423 if (doTick) {
4424 doTick(this._currentTickTime - lastCurrentTime);
4425 }
4426 let retval = current.func.apply(global, current.isRequestAnimationFrame ? [this._currentTickTime] : current.args);
4427 if (!retval) {
4428 // Uncaught exception in the current scheduled function. Stop processing the queue.
4429 break;
4430 }
4431 // check is there any requeue periodic entry is added in
4432 // current loop, if there is, we need to add to current loop
4433 if (!tickOptions.processNewMacroTasksSynchronously) {
4434 this._currentTickRequeuePeriodicEntries.forEach(newEntry => {
4435 let i = 0;
4436 for (; i < schedulerQueue.length; i++) {
4437 const currentEntry = schedulerQueue[i];
4438 if (newEntry.endTime < currentEntry.endTime) {
4439 break;
4440 }
4441 }
4442 schedulerQueue.splice(i, 0, newEntry);
4443 });
4444 }
4445 }
4446 }
4447 lastCurrentTime = this._currentTickTime;
4448 this._currentTickTime = finalTime;
4449 if (doTick) {
4450 doTick(this._currentTickTime - lastCurrentTime);
4451 }
4452 }
4453 flushOnlyPendingTimers(doTick) {
4454 if (this._schedulerQueue.length === 0) {
4455 return 0;
4456 }
4457 // Find the last task currently queued in the scheduler queue and tick
4458 // till that time.
4459 const startTime = this._currentTickTime;
4460 const lastTask = this._schedulerQueue[this._schedulerQueue.length - 1];
4461 this.tick(lastTask.endTime - startTime, doTick, { processNewMacroTasksSynchronously: false });
4462 return this._currentTickTime - startTime;
4463 }
4464 flush(limit = 20, flushPeriodic = false, doTick) {
4465 if (flushPeriodic) {
4466 return this.flushPeriodic(doTick);
4467 }
4468 else {
4469 return this.flushNonPeriodic(limit, doTick);
4470 }
4471 }
4472 flushPeriodic(doTick) {
4473 if (this._schedulerQueue.length === 0) {
4474 return 0;
4475 }
4476 // Find the last task currently queued in the scheduler queue and tick
4477 // till that time.
4478 const startTime = this._currentTickTime;
4479 const lastTask = this._schedulerQueue[this._schedulerQueue.length - 1];
4480 this.tick(lastTask.endTime - startTime, doTick);
4481 return this._currentTickTime - startTime;
4482 }
4483 flushNonPeriodic(limit, doTick) {
4484 const startTime = this._currentTickTime;
4485 let lastCurrentTime = 0;
4486 let count = 0;
4487 while (this._schedulerQueue.length > 0) {
4488 count++;
4489 if (count > limit) {
4490 throw new Error('flush failed after reaching the limit of ' + limit +
4491 ' tasks. Does your code use a polling timeout?');
4492 }
4493 // flush only non-periodic timers.
4494 // If the only remaining tasks are periodic(or requestAnimationFrame), finish flushing.
4495 if (this._schedulerQueue.filter(task => !task.isPeriodic && !task.isRequestAnimationFrame)
4496 .length === 0) {
4497 break;
4498 }
4499 const current = this._schedulerQueue.shift();
4500 lastCurrentTime = this._currentTickTime;
4501 this._currentTickTime = current.endTime;
4502 if (doTick) {
4503 // Update any secondary schedulers like Jasmine mock Date.
4504 doTick(this._currentTickTime - lastCurrentTime);
4505 }
4506 const retval = current.func.apply(global, current.args);
4507 if (!retval) {
4508 // Uncaught exception in the current scheduled function. Stop processing the queue.
4509 break;
4510 }
4511 }
4512 return this._currentTickTime - startTime;
4513 }
4514 }
4515 // Next scheduler id.
4516 Scheduler.nextId = 1;
4517 class FakeAsyncTestZoneSpec {
4518 constructor(namePrefix, trackPendingRequestAnimationFrame = false, macroTaskOptions) {
4519 this.trackPendingRequestAnimationFrame = trackPendingRequestAnimationFrame;
4520 this.macroTaskOptions = macroTaskOptions;
4521 this._scheduler = new Scheduler();
4522 this._microtasks = [];
4523 this._lastError = null;
4524 this._uncaughtPromiseErrors = Promise[Zone.__symbol__('uncaughtPromiseErrors')];
4525 this.pendingPeriodicTimers = [];
4526 this.pendingTimers = [];
4527 this.patchDateLocked = false;
4528 this.properties = { 'FakeAsyncTestZoneSpec': this };
4529 this.name = 'fakeAsyncTestZone for ' + namePrefix;
4530 // in case user can't access the construction of FakeAsyncTestSpec
4531 // user can also define macroTaskOptions by define a global variable.
4532 if (!this.macroTaskOptions) {
4533 this.macroTaskOptions = global[Zone.__symbol__('FakeAsyncTestMacroTask')];
4534 }
4535 }
4536 static assertInZone() {
4537 if (Zone.current.get('FakeAsyncTestZoneSpec') == null) {
4538 throw new Error('The code should be running in the fakeAsync zone to call this function');
4539 }
4540 }
4541 _fnAndFlush(fn, completers) {
4542 return (...args) => {
4543 fn.apply(global, args);
4544 if (this._lastError === null) { // Success
4545 if (completers.onSuccess != null) {
4546 completers.onSuccess.apply(global);
4547 }
4548 // Flush microtasks only on success.
4549 this.flushMicrotasks();
4550 }
4551 else { // Failure
4552 if (completers.onError != null) {
4553 completers.onError.apply(global);
4554 }
4555 }
4556 // Return true if there were no errors, false otherwise.
4557 return this._lastError === null;
4558 };
4559 }
4560 static _removeTimer(timers, id) {
4561 let index = timers.indexOf(id);
4562 if (index > -1) {
4563 timers.splice(index, 1);
4564 }
4565 }
4566 _dequeueTimer(id) {
4567 return () => {
4568 FakeAsyncTestZoneSpec._removeTimer(this.pendingTimers, id);
4569 };
4570 }
4571 _requeuePeriodicTimer(fn, interval, args, id) {
4572 return () => {
4573 // Requeue the timer callback if it's not been canceled.
4574 if (this.pendingPeriodicTimers.indexOf(id) !== -1) {
4575 this._scheduler.scheduleFunction(fn, interval, { args, isPeriodic: true, id, isRequeuePeriodic: true });
4576 }
4577 };
4578 }
4579 _dequeuePeriodicTimer(id) {
4580 return () => {
4581 FakeAsyncTestZoneSpec._removeTimer(this.pendingPeriodicTimers, id);
4582 };
4583 }
4584 _setTimeout(fn, delay, args, isTimer = true) {
4585 let removeTimerFn = this._dequeueTimer(Scheduler.nextId);
4586 // Queue the callback and dequeue the timer on success and error.
4587 let cb = this._fnAndFlush(fn, { onSuccess: removeTimerFn, onError: removeTimerFn });
4588 let id = this._scheduler.scheduleFunction(cb, delay, { args, isRequestAnimationFrame: !isTimer });
4589 if (isTimer) {
4590 this.pendingTimers.push(id);
4591 }
4592 return id;
4593 }
4594 _clearTimeout(id) {
4595 FakeAsyncTestZoneSpec._removeTimer(this.pendingTimers, id);
4596 this._scheduler.removeScheduledFunctionWithId(id);
4597 }
4598 _setInterval(fn, interval, args) {
4599 let id = Scheduler.nextId;
4600 let completers = { onSuccess: null, onError: this._dequeuePeriodicTimer(id) };
4601 let cb = this._fnAndFlush(fn, completers);
4602 // Use the callback created above to requeue on success.
4603 completers.onSuccess = this._requeuePeriodicTimer(cb, interval, args, id);
4604 // Queue the callback and dequeue the periodic timer only on error.
4605 this._scheduler.scheduleFunction(cb, interval, { args, isPeriodic: true });
4606 this.pendingPeriodicTimers.push(id);
4607 return id;
4608 }
4609 _clearInterval(id) {
4610 FakeAsyncTestZoneSpec._removeTimer(this.pendingPeriodicTimers, id);
4611 this._scheduler.removeScheduledFunctionWithId(id);
4612 }
4613 _resetLastErrorAndThrow() {
4614 let error = this._lastError || this._uncaughtPromiseErrors[0];
4615 this._uncaughtPromiseErrors.length = 0;
4616 this._lastError = null;
4617 throw error;
4618 }
4619 getCurrentTickTime() {
4620 return this._scheduler.getCurrentTickTime();
4621 }
4622 getFakeSystemTime() {
4623 return this._scheduler.getFakeSystemTime();
4624 }
4625 setFakeBaseSystemTime(realTime) {
4626 this._scheduler.setFakeBaseSystemTime(realTime);
4627 }
4628 getRealSystemTime() {
4629 return this._scheduler.getRealSystemTime();
4630 }
4631 static patchDate() {
4632 if (!!global[Zone.__symbol__('disableDatePatching')]) {
4633 // we don't want to patch global Date
4634 // because in some case, global Date
4635 // is already being patched, we need to provide
4636 // an option to let user still use their
4637 // own version of Date.
4638 return;
4639 }
4640 if (global['Date'] === FakeDate) {
4641 // already patched
4642 return;
4643 }
4644 global['Date'] = FakeDate;
4645 FakeDate.prototype = OriginalDate.prototype;
4646 // try check and reset timers
4647 // because jasmine.clock().install() may
4648 // have replaced the global timer
4649 FakeAsyncTestZoneSpec.checkTimerPatch();
4650 }
4651 static resetDate() {
4652 if (global['Date'] === FakeDate) {
4653 global['Date'] = OriginalDate;
4654 }
4655 }
4656 static checkTimerPatch() {
4657 if (global.setTimeout !== timers.setTimeout) {
4658 global.setTimeout = timers.setTimeout;
4659 global.clearTimeout = timers.clearTimeout;
4660 }
4661 if (global.setInterval !== timers.setInterval) {
4662 global.setInterval = timers.setInterval;
4663 global.clearInterval = timers.clearInterval;
4664 }
4665 }
4666 lockDatePatch() {
4667 this.patchDateLocked = true;
4668 FakeAsyncTestZoneSpec.patchDate();
4669 }
4670 unlockDatePatch() {
4671 this.patchDateLocked = false;
4672 FakeAsyncTestZoneSpec.resetDate();
4673 }
4674 tickToNext(steps = 1, doTick, tickOptions = { processNewMacroTasksSynchronously: true }) {
4675 if (steps <= 0) {
4676 return;
4677 }
4678 FakeAsyncTestZoneSpec.assertInZone();
4679 this.flushMicrotasks();
4680 this._scheduler.tickToNext(steps, doTick, tickOptions);
4681 if (this._lastError !== null) {
4682 this._resetLastErrorAndThrow();
4683 }
4684 }
4685 tick(millis = 0, doTick, tickOptions = { processNewMacroTasksSynchronously: true }) {
4686 FakeAsyncTestZoneSpec.assertInZone();
4687 this.flushMicrotasks();
4688 this._scheduler.tick(millis, doTick, tickOptions);
4689 if (this._lastError !== null) {
4690 this._resetLastErrorAndThrow();
4691 }
4692 }
4693 flushMicrotasks() {
4694 FakeAsyncTestZoneSpec.assertInZone();
4695 const flushErrors = () => {
4696 if (this._lastError !== null || this._uncaughtPromiseErrors.length) {
4697 // If there is an error stop processing the microtask queue and rethrow the error.
4698 this._resetLastErrorAndThrow();
4699 }
4700 };
4701 while (this._microtasks.length > 0) {
4702 let microtask = this._microtasks.shift();
4703 microtask.func.apply(microtask.target, microtask.args);
4704 }
4705 flushErrors();
4706 }
4707 flush(limit, flushPeriodic, doTick) {
4708 FakeAsyncTestZoneSpec.assertInZone();
4709 this.flushMicrotasks();
4710 const elapsed = this._scheduler.flush(limit, flushPeriodic, doTick);
4711 if (this._lastError !== null) {
4712 this._resetLastErrorAndThrow();
4713 }
4714 return elapsed;
4715 }
4716 flushOnlyPendingTimers(doTick) {
4717 FakeAsyncTestZoneSpec.assertInZone();
4718 this.flushMicrotasks();
4719 const elapsed = this._scheduler.flushOnlyPendingTimers(doTick);
4720 if (this._lastError !== null) {
4721 this._resetLastErrorAndThrow();
4722 }
4723 return elapsed;
4724 }
4725 removeAllTimers() {
4726 FakeAsyncTestZoneSpec.assertInZone();
4727 this._scheduler.removeAll();
4728 this.pendingPeriodicTimers = [];
4729 this.pendingTimers = [];
4730 }
4731 getTimerCount() {
4732 return this._scheduler.getTimerCount() + this._microtasks.length;
4733 }
4734 onScheduleTask(delegate, current, target, task) {
4735 switch (task.type) {
4736 case 'microTask':
4737 let args = task.data && task.data.args;
4738 // should pass additional arguments to callback if have any
4739 // currently we know process.nextTick will have such additional
4740 // arguments
4741 let additionalArgs;
4742 if (args) {
4743 let callbackIndex = task.data.cbIdx;
4744 if (typeof args.length === 'number' && args.length > callbackIndex + 1) {
4745 additionalArgs = Array.prototype.slice.call(args, callbackIndex + 1);
4746 }
4747 }
4748 this._microtasks.push({
4749 func: task.invoke,
4750 args: additionalArgs,
4751 target: task.data && task.data.target
4752 });
4753 break;
4754 case 'macroTask':
4755 switch (task.source) {
4756 case 'setTimeout':
4757 task.data['handleId'] = this._setTimeout(task.invoke, task.data['delay'], Array.prototype.slice.call(task.data['args'], 2));
4758 break;
4759 case 'setImmediate':
4760 task.data['handleId'] = this._setTimeout(task.invoke, 0, Array.prototype.slice.call(task.data['args'], 1));
4761 break;
4762 case 'setInterval':
4763 task.data['handleId'] = this._setInterval(task.invoke, task.data['delay'], Array.prototype.slice.call(task.data['args'], 2));
4764 break;
4765 case 'XMLHttpRequest.send':
4766 throw new Error('Cannot make XHRs from within a fake async test. Request URL: ' +
4767 task.data['url']);
4768 case 'requestAnimationFrame':
4769 case 'webkitRequestAnimationFrame':
4770 case 'mozRequestAnimationFrame':
4771 // Simulate a requestAnimationFrame by using a setTimeout with 16 ms.
4772 // (60 frames per second)
4773 task.data['handleId'] = this._setTimeout(task.invoke, 16, task.data['args'], this.trackPendingRequestAnimationFrame);
4774 break;
4775 default:
4776 // user can define which macroTask they want to support by passing
4777 // macroTaskOptions
4778 const macroTaskOption = this.findMacroTaskOption(task);
4779 if (macroTaskOption) {
4780 const args = task.data && task.data['args'];
4781 const delay = args && args.length > 1 ? args[1] : 0;
4782 let callbackArgs = macroTaskOption.callbackArgs ? macroTaskOption.callbackArgs : args;
4783 if (!!macroTaskOption.isPeriodic) {
4784 // periodic macroTask, use setInterval to simulate
4785 task.data['handleId'] = this._setInterval(task.invoke, delay, callbackArgs);
4786 task.data.isPeriodic = true;
4787 }
4788 else {
4789 // not periodic, use setTimeout to simulate
4790 task.data['handleId'] = this._setTimeout(task.invoke, delay, callbackArgs);
4791 }
4792 break;
4793 }
4794 throw new Error('Unknown macroTask scheduled in fake async test: ' + task.source);
4795 }
4796 break;
4797 case 'eventTask':
4798 task = delegate.scheduleTask(target, task);
4799 break;
4800 }
4801 return task;
4802 }
4803 onCancelTask(delegate, current, target, task) {
4804 switch (task.source) {
4805 case 'setTimeout':
4806 case 'requestAnimationFrame':
4807 case 'webkitRequestAnimationFrame':
4808 case 'mozRequestAnimationFrame':
4809 return this._clearTimeout(task.data['handleId']);
4810 case 'setInterval':
4811 return this._clearInterval(task.data['handleId']);
4812 default:
4813 // user can define which macroTask they want to support by passing
4814 // macroTaskOptions
4815 const macroTaskOption = this.findMacroTaskOption(task);
4816 if (macroTaskOption) {
4817 const handleId = task.data['handleId'];
4818 return macroTaskOption.isPeriodic ? this._clearInterval(handleId) :
4819 this._clearTimeout(handleId);
4820 }
4821 return delegate.cancelTask(target, task);
4822 }
4823 }
4824 onInvoke(delegate, current, target, callback, applyThis, applyArgs, source) {
4825 try {
4826 FakeAsyncTestZoneSpec.patchDate();
4827 return delegate.invoke(target, callback, applyThis, applyArgs, source);
4828 }
4829 finally {
4830 if (!this.patchDateLocked) {
4831 FakeAsyncTestZoneSpec.resetDate();
4832 }
4833 }
4834 }
4835 findMacroTaskOption(task) {
4836 if (!this.macroTaskOptions) {
4837 return null;
4838 }
4839 for (let i = 0; i < this.macroTaskOptions.length; i++) {
4840 const macroTaskOption = this.macroTaskOptions[i];
4841 if (macroTaskOption.source === task.source) {
4842 return macroTaskOption;
4843 }
4844 }
4845 return null;
4846 }
4847 onHandleError(parentZoneDelegate, currentZone, targetZone, error) {
4848 this._lastError = error;
4849 return false; // Don't propagate error to parent zone.
4850 }
4851 }
4852 // Export the class so that new instances can be created with proper
4853 // constructor params.
4854 Zone['FakeAsyncTestZoneSpec'] = FakeAsyncTestZoneSpec;
4855})(typeof window === 'object' && window || typeof self === 'object' && self || global);
4856Zone.__load_patch('fakeasync', (global, Zone, api) => {
4857 const FakeAsyncTestZoneSpec = Zone && Zone['FakeAsyncTestZoneSpec'];
4858 function getProxyZoneSpec() {
4859 return Zone && Zone['ProxyZoneSpec'];
4860 }
4861 let _fakeAsyncTestZoneSpec = null;
4862 /**
4863 * Clears out the shared fake async zone for a test.
4864 * To be called in a global `beforeEach`.
4865 *
4866 * @experimental
4867 */
4868 function resetFakeAsyncZone() {
4869 if (_fakeAsyncTestZoneSpec) {
4870 _fakeAsyncTestZoneSpec.unlockDatePatch();
4871 }
4872 _fakeAsyncTestZoneSpec = null;
4873 // in node.js testing we may not have ProxyZoneSpec in which case there is nothing to reset.
4874 getProxyZoneSpec() && getProxyZoneSpec().assertPresent().resetDelegate();
4875 }
4876 /**
4877 * Wraps a function to be executed in the fakeAsync zone:
4878 * - microtasks are manually executed by calling `flushMicrotasks()`,
4879 * - timers are synchronous, `tick()` simulates the asynchronous passage of time.
4880 *
4881 * If there are any pending timers at the end of the function, an exception will be thrown.
4882 *
4883 * Can be used to wrap inject() calls.
4884 *
4885 * ## Example
4886 *
4887 * {@example core/testing/ts/fake_async.ts region='basic'}
4888 *
4889 * @param fn
4890 * @returns The function wrapped to be executed in the fakeAsync zone
4891 *
4892 * @experimental
4893 */
4894 function fakeAsync(fn) {
4895 // Not using an arrow function to preserve context passed from call site
4896 const fakeAsyncFn = function (...args) {
4897 const ProxyZoneSpec = getProxyZoneSpec();
4898 if (!ProxyZoneSpec) {
4899 throw new Error('ProxyZoneSpec is needed for the async() test helper but could not be found. ' +
4900 'Please make sure that your environment includes zone.js/dist/proxy.js');
4901 }
4902 const proxyZoneSpec = ProxyZoneSpec.assertPresent();
4903 if (Zone.current.get('FakeAsyncTestZoneSpec')) {
4904 throw new Error('fakeAsync() calls can not be nested');
4905 }
4906 try {
4907 // in case jasmine.clock init a fakeAsyncTestZoneSpec
4908 if (!_fakeAsyncTestZoneSpec) {
4909 if (proxyZoneSpec.getDelegate() instanceof FakeAsyncTestZoneSpec) {
4910 throw new Error('fakeAsync() calls can not be nested');
4911 }
4912 _fakeAsyncTestZoneSpec = new FakeAsyncTestZoneSpec();
4913 }
4914 let res;
4915 const lastProxyZoneSpec = proxyZoneSpec.getDelegate();
4916 proxyZoneSpec.setDelegate(_fakeAsyncTestZoneSpec);
4917 _fakeAsyncTestZoneSpec.lockDatePatch();
4918 try {
4919 res = fn.apply(this, args);
4920 flushMicrotasks();
4921 }
4922 finally {
4923 proxyZoneSpec.setDelegate(lastProxyZoneSpec);
4924 }
4925 if (_fakeAsyncTestZoneSpec.pendingPeriodicTimers.length > 0) {
4926 throw new Error(`${_fakeAsyncTestZoneSpec.pendingPeriodicTimers.length} ` +
4927 `periodic timer(s) still in the queue.`);
4928 }
4929 if (_fakeAsyncTestZoneSpec.pendingTimers.length > 0) {
4930 throw new Error(`${_fakeAsyncTestZoneSpec.pendingTimers.length} timer(s) still in the queue.`);
4931 }
4932 return res;
4933 }
4934 finally {
4935 resetFakeAsyncZone();
4936 }
4937 };
4938 fakeAsyncFn.isFakeAsync = true;
4939 return fakeAsyncFn;
4940 }
4941 function _getFakeAsyncZoneSpec() {
4942 if (_fakeAsyncTestZoneSpec == null) {
4943 _fakeAsyncTestZoneSpec = Zone.current.get('FakeAsyncTestZoneSpec');
4944 if (_fakeAsyncTestZoneSpec == null) {
4945 throw new Error('The code should be running in the fakeAsync zone to call this function');
4946 }
4947 }
4948 return _fakeAsyncTestZoneSpec;
4949 }
4950 /**
4951 * Simulates the asynchronous passage of time for the timers in the fakeAsync zone.
4952 *
4953 * The microtasks queue is drained at the very start of this function and after any timer callback
4954 * has been executed.
4955 *
4956 * ## Example
4957 *
4958 * {@example core/testing/ts/fake_async.ts region='basic'}
4959 *
4960 * @experimental
4961 */
4962 function tick(millis = 0, ignoreNestedTimeout = false) {
4963 _getFakeAsyncZoneSpec().tick(millis, null, ignoreNestedTimeout);
4964 }
4965 /**
4966 * Simulates the asynchronous passage of time for the timers in the fakeAsync zone by
4967 * draining the macrotask queue until it is empty. The returned value is the milliseconds
4968 * of time that would have been elapsed.
4969 *
4970 * @param maxTurns
4971 * @returns The simulated time elapsed, in millis.
4972 *
4973 * @experimental
4974 */
4975 function flush(maxTurns) {
4976 return _getFakeAsyncZoneSpec().flush(maxTurns);
4977 }
4978 /**
4979 * Discard all remaining periodic tasks.
4980 *
4981 * @experimental
4982 */
4983 function discardPeriodicTasks() {
4984 const zoneSpec = _getFakeAsyncZoneSpec();
4985 const pendingTimers = zoneSpec.pendingPeriodicTimers;
4986 zoneSpec.pendingPeriodicTimers.length = 0;
4987 }
4988 /**
4989 * Flush any pending microtasks.
4990 *
4991 * @experimental
4992 */
4993 function flushMicrotasks() {
4994 _getFakeAsyncZoneSpec().flushMicrotasks();
4995 }
4996 Zone[api.symbol('fakeAsyncTest')] =
4997 { resetFakeAsyncZone, flushMicrotasks, discardPeriodicTasks, tick, flush, fakeAsync };
4998}, true);
4999
5000/**
5001 * @license
5002 * Copyright Google LLC All Rights Reserved.
5003 *
5004 * Use of this source code is governed by an MIT-style license that can be
5005 * found in the LICENSE file at https://angular.io/license
5006 */
5007/**
5008 * Promise for async/fakeAsync zoneSpec test
5009 * can support async operation which not supported by zone.js
5010 * such as
5011 * it ('test jsonp in AsyncZone', async() => {
5012 * new Promise(res => {
5013 * jsonp(url, (data) => {
5014 * // success callback
5015 * res(data);
5016 * });
5017 * }).then((jsonpResult) => {
5018 * // get jsonp result.
5019 *
5020 * // user will expect AsyncZoneSpec wait for
5021 * // then, but because jsonp is not zone aware
5022 * // AsyncZone will finish before then is called.
5023 * });
5024 * });
5025 */
5026Zone.__load_patch('promisefortest', (global, Zone, api) => {
5027 const symbolState = api.symbol('state');
5028 const UNRESOLVED = null;
5029 const symbolParentUnresolved = api.symbol('parentUnresolved');
5030 // patch Promise.prototype.then to keep an internal
5031 // number for tracking unresolved chained promise
5032 // we will decrease this number when the parent promise
5033 // being resolved/rejected and chained promise was
5034 // scheduled as a microTask.
5035 // so we can know such kind of chained promise still
5036 // not resolved in AsyncTestZone
5037 Promise[api.symbol('patchPromiseForTest')] = function patchPromiseForTest() {
5038 let oriThen = Promise[Zone.__symbol__('ZonePromiseThen')];
5039 if (oriThen) {
5040 return;
5041 }
5042 oriThen = Promise[Zone.__symbol__('ZonePromiseThen')] = Promise.prototype.then;
5043 Promise.prototype.then = function () {
5044 const chained = oriThen.apply(this, arguments);
5045 if (this[symbolState] === UNRESOLVED) {
5046 // parent promise is unresolved.
5047 const asyncTestZoneSpec = Zone.current.get('AsyncTestZoneSpec');
5048 if (asyncTestZoneSpec) {
5049 asyncTestZoneSpec.unresolvedChainedPromiseCount++;
5050 chained[symbolParentUnresolved] = true;
5051 }
5052 }
5053 return chained;
5054 };
5055 };
5056 Promise[api.symbol('unPatchPromiseForTest')] = function unpatchPromiseForTest() {
5057 // restore origin then
5058 const oriThen = Promise[Zone.__symbol__('ZonePromiseThen')];
5059 if (oriThen) {
5060 Promise.prototype.then = oriThen;
5061 Promise[Zone.__symbol__('ZonePromiseThen')] = undefined;
5062 }
5063 };
5064});
Note: See TracBrowser for help on using the repository browser.