From b92b6e31abb384ad4ac3f38ee0df78ba21104684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=A1ko=20Hevery?= Date: Fri, 19 May 2017 13:25:12 -0700 Subject: [PATCH] chore: release v0.8.11 --- CHANGELOG.md | 14 + dist/webapis-media-query.js | 3 +- dist/webapis-media-query.min.js | 2 +- dist/webapis-notification.js | 3 +- dist/webapis-notification.min.js | 2 +- dist/webapis-shadydom.js | 5 +- dist/webapis-shadydom.min.js | 2 +- dist/zone-mix.js | 2123 +++++++++++++++++------------- dist/zone-node.js | 308 ++--- dist/zone.js | 300 ++++- dist/zone.min.js | 3 +- package.json | 2 +- 12 files changed, 1605 insertions(+), 1162 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a99c3d25..891c67bb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ + +## [0.8.11](https://github.com/angular/zone.js/compare/v0.8.10...0.8.11) (2017-05-19) + + +### Bug Fixes + +* **closure:** patchOnProperty with exact eventNames as possible ([#768](https://github.com/angular/zone.js/issues/768)) ([582ff7b](https://github.com/angular/zone.js/commit/582ff7b)) +* **patch:** fix [#744](https://github.com/angular/zone.js/issues/744), add namespace to load patch name ([#774](https://github.com/angular/zone.js/issues/774)) ([89f990a](https://github.com/angular/zone.js/commit/89f990a)) +* **task:** fix [#778](https://github.com/angular/zone.js/issues/778), sometimes task will run after being canceled ([#780](https://github.com/angular/zone.js/issues/780)) ([b7238c8](https://github.com/angular/zone.js/commit/b7238c8)) +* **webcomponents:** fix [#782](https://github.com/angular/zone.js/issues/782), fix conflicts with shadydom of webcomponents ([#784](https://github.com/angular/zone.js/issues/784)) ([245f8e9](https://github.com/angular/zone.js/commit/245f8e9)) +* **webpack:** access `process` through `_global` so that WebPack does not accidently browserify ([#786](https://github.com/angular/zone.js/issues/786)) ([1919b36](https://github.com/angular/zone.js/commit/1919b36)) + + + ## [0.8.10](https://github.com/angular/zone.js/compare/v0.8.9...0.8.10) (2017-05-03) diff --git a/dist/webapis-media-query.js b/dist/webapis-media-query.js index 392419efc..5b51f9fe9 100644 --- a/dist/webapis-media-query.js +++ b/dist/webapis-media-query.js @@ -22,8 +22,7 @@ Zone.__load_patch('mediaQuery', function (global, Zone, api) { if (!global['MediaQueryList']) { return; } - var patchEventTargetMethods = Zone[Zone.__symbol__('patchEventTargetMethods')]; - patchEventTargetMethods(_global['MediaQueryList'].prototype, 'addListener', 'removeListener', function (self, args) { + api.patchEventTargetMethods(_global['MediaQueryList'].prototype, 'addListener', 'removeListener', function (self, args) { return { useCapturing: false, eventName: 'mediaQuery', diff --git a/dist/webapis-media-query.min.js b/dist/webapis-media-query.min.js index 995c27184..993afd1ba 100644 --- a/dist/webapis-media-query.min.js +++ b/dist/webapis-media-query.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(this,function(){"use strict";Zone.__load_patch("mediaQuery",function(e,t,n){if(e.MediaQueryList){var i=t[t.__symbol__("patchEventTargetMethods")];i(_global.MediaQueryList.prototype,"addListener","removeListener",function(t,n){return{useCapturing:!1,eventName:"mediaQuery",handler:n[0],target:t||e,name:"mediaQuery",invokeAddFunc:function(e,t){return t&&t.invoke?this.target[e](t.invoke):this.target[e](t)},invokeRemoveFunc:function(e,t){return t&&t.invoke?this.target[e](t.invoke):this.target[e](t)}}})}})}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(this,function(){"use strict";Zone.__load_patch("mediaQuery",function(e,t,n){e.MediaQueryList&&n.patchEventTargetMethods(_global.MediaQueryList.prototype,"addListener","removeListener",function(t,n){return{useCapturing:!1,eventName:"mediaQuery",handler:n[0],target:t||e,name:"mediaQuery",invokeAddFunc:function(e,t){return t&&t.invoke?this.target[e](t.invoke):this.target[e](t)},invokeRemoveFunc:function(e,t){return t&&t.invoke?this.target[e](t.invoke):this.target[e](t)}}})})}); \ No newline at end of file diff --git a/dist/webapis-notification.js b/dist/webapis-notification.js index d8db220f4..b466819ba 100644 --- a/dist/webapis-notification.js +++ b/dist/webapis-notification.js @@ -27,8 +27,7 @@ Zone.__load_patch('notification', function (global, Zone, api) { if (!desc || !desc.configurable) { return; } - var patchOnProperties = Zone[Zone.__symbol__('patchOnProperties')]; - patchOnProperties(Notification.prototype, null); + api.patchOnProperties(Notification.prototype, null); }); }))); diff --git a/dist/webapis-notification.min.js b/dist/webapis-notification.min.js index cd2f5976e..48f15a6b6 100644 --- a/dist/webapis-notification.min.js +++ b/dist/webapis-notification.min.js @@ -1 +1 @@ -!function(o,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(this,function(){"use strict";Zone.__load_patch("notification",function(o,t,e){var n=_global.Notification;if(n&&n.prototype){var i=Object.getOwnPropertyDescriptor(n.prototype,"onerror");if(i&&i.configurable){var r=t[t.__symbol__("patchOnProperties")];r(n.prototype,null)}}})}); \ No newline at end of file +!function(o,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(this,function(){"use strict";Zone.__load_patch("notification",function(o,t,e){var n=_global.Notification;if(n&&n.prototype){var i=Object.getOwnPropertyDescriptor(n.prototype,"onerror");i&&i.configurable&&e.patchOnProperties(n.prototype,null)}})}); \ No newline at end of file diff --git a/dist/webapis-shadydom.js b/dist/webapis-shadydom.js index 8be8a1426..d1e2f0fca 100644 --- a/dist/webapis-shadydom.js +++ b/dist/webapis-shadydom.js @@ -19,7 +19,6 @@ * found in the LICENSE file at https://angular.io/license */ Zone.__load_patch('shadydom', function (global, Zone, api) { - var patchEventTargetMethods = Zone[Zone.__symbol__('patchEventTargetMethods')]; // https://github.com/angular/zone.js/issues/782 // in web components, shadydom will patch addEventListener/removeEventListener of // Node.prototype and WindowPrototype, this will have conflict with zone.js @@ -28,12 +27,12 @@ Zone.__load_patch('shadydom', function (global, Zone, api) { if (windowPrototype && windowPrototype.hasOwnProperty('addEventListener')) { windowPrototype[Zone.__symbol__('addEventListener')] = null; windowPrototype[Zone.__symbol__('removeEventListener')] = null; - patchEventTargetMethods(windowPrototype); + api.patchEventTargetMethods(windowPrototype); } if (Node.prototype.hasOwnProperty('addEventListener')) { Node.prototype[Zone.__symbol__('addEventListener')] = null; Node.prototype[Zone.__symbol__('removeEventListener')] = null; - patchEventTargetMethods(Node.prototype); + api.patchEventTargetMethods(Node.prototype); } }); diff --git a/dist/webapis-shadydom.min.js b/dist/webapis-shadydom.min.js index 5ba7405c6..56cdf5f7e 100644 --- a/dist/webapis-shadydom.min.js +++ b/dist/webapis-shadydom.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(this,function(){"use strict";Zone.__load_patch("shadydom",function(e,t,o){var n=t[t.__symbol__("patchEventTargetMethods")],d=Object.getPrototypeOf(window);d&&d.hasOwnProperty("addEventListener")&&(d[t.__symbol__("addEventListener")]=null,d[t.__symbol__("removeEventListener")]=null,n(d)),Node.prototype.hasOwnProperty("addEventListener")&&(Node.prototype[t.__symbol__("addEventListener")]=null,Node.prototype[t.__symbol__("removeEventListener")]=null,n(Node.prototype))})}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(this,function(){"use strict";Zone.__load_patch("shadydom",function(e,t,o){var n=Object.getPrototypeOf(window);n&&n.hasOwnProperty("addEventListener")&&(n[t.__symbol__("addEventListener")]=null,n[t.__symbol__("removeEventListener")]=null,o.patchEventTargetMethods(n)),Node.prototype.hasOwnProperty("addEventListener")&&(Node.prototype[t.__symbol__("addEventListener")]=null,Node.prototype[t.__symbol__("removeEventListener")]=null,o.patchEventTargetMethods(Node.prototype))})}); \ No newline at end of file diff --git a/dist/zone-mix.js b/dist/zone-mix.js index cf062d9bb..37541fbc2 100644 --- a/dist/zone-mix.js +++ b/dist/zone-mix.js @@ -164,9 +164,19 @@ var Zone$1 = (function (global) { } }; Zone.prototype.runTask = function (task, applyThis, applyArgs) { - if (task.zone != this) + if (task.zone != this) { throw new Error('A task can only be run in the zone of creation! (Creation: ' + (task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')'); + } + // https://github.com/angular/zone.js/issues/778, sometimes eventTask + // will run in notScheduled(canceled) state, we should not try to + // run such kind of task but just return + // we have to define an variable here, if not + // typescript compiler will complain below + var isNotScheduled = task.state === notScheduled; + if (isNotScheduled && task.type === eventTask) { + return; + } var reEntryGuard = task.state != running; reEntryGuard && task._transitionTo(running, scheduled); task.runCount++; @@ -598,7 +608,9 @@ var Zone$1 = (function (global) { onUnhandledError: noop, microtaskDrainDone: noop, scheduleMicroTask: scheduleMicroTask, - showUncaughtError: function () { return !Zone[__symbol__('ignoreConsoleErrorUncaughtError')]; } + showUncaughtError: function () { return !Zone[__symbol__('ignoreConsoleErrorUncaughtError')]; }, + patchEventTargetMethods: function () { return false; }, + patchOnProperties: noop }; var _currentZoneFrame = { parent: null, zone: new Zone(null, null) }; var _currentTask = null; @@ -618,385 +630,731 @@ var Zone$1 = (function (global) { * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -/** - * Suppress closure compiler errors about unknown 'Zone' variable - * @fileoverview - * @suppress {undefinedVars,globalThis} - */ -var zoneSymbol = function (n) { return "__zone_symbol__" + n; }; -var _global = typeof window === 'object' && window || typeof self === 'object' && self || global; -function bindArguments(args, source) { - for (var i = args.length - 1; i >= 0; i--) { - if (typeof args[i] === 'function') { - args[i] = Zone.current.wrap(args[i], source + '_' + i); - } - } - return args; -} -function patchPrototype(prototype, fnNames) { - var source = prototype.constructor['name']; - var _loop_1 = function (i) { - var name_1 = fnNames[i]; - var delegate = prototype[name_1]; - if (delegate) { - prototype[name_1] = (function (delegate) { - var patched = function () { - return delegate.apply(this, bindArguments(arguments, source + '.' + name_1)); - }; - attachOriginToPatched(patched, delegate); - return patched; - })(delegate); +Zone.__load_patch('ZoneAwarePromise', function (global, Zone, api) { + var __symbol__ = api.symbol; + var _uncaughtPromiseErrors = []; + var symbolPromise = __symbol__('Promise'); + var symbolThen = __symbol__('then'); + api.onUnhandledError = function (e) { + if (api.showUncaughtError()) { + var rejection = e && e.rejection; + if (rejection) { + console.error('Unhandled Promise rejection:', rejection instanceof Error ? rejection.message : rejection, '; Zone:', e.zone.name, '; Task:', e.task && e.task.source, '; Value:', rejection, rejection instanceof Error ? rejection.stack : undefined); + } + console.error(e); } }; - for (var i = 0; i < fnNames.length; i++) { - _loop_1(i); - } -} -var isWebWorker = (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope); -var isNode = (!('nw' in _global) && typeof process !== 'undefined' && - {}.toString.call(process) === '[object process]'); -var isBrowser = !isNode && !isWebWorker && !!(typeof window !== 'undefined' && window['HTMLElement']); -// we are in electron of nw, so we are both browser and nodejs -var isMix = typeof process !== 'undefined' && - {}.toString.call(process) === '[object process]' && !isWebWorker && - !!(typeof window !== 'undefined' && window['HTMLElement']); -function patchProperty(obj, prop) { - var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true }; - // if the descriptor is not configurable - // just return - if (!desc.configurable) { - return; - } - // A property descriptor cannot have getter/setter and be writable - // deleting the writable and value properties avoids this error: - // - // TypeError: property descriptors must not specify a value or be writable when a - // getter or setter has been specified - delete desc.writable; - delete desc.value; - var originalDescGet = desc.get; - // substr(2) cuz 'onclick' -> 'click', etc - var eventName = prop.substr(2); - var _prop = zoneSymbol('_' + prop); - desc.set = function (newValue) { - // in some of windows's onproperty callback, this is undefined - // so we need to check it - var target = this; - if (!target && obj === _global) { - target = _global; - } - if (!target) { - return; - } - var previousValue = target[_prop]; - if (previousValue) { - target.removeEventListener(eventName, previousValue); - } - if (typeof newValue === 'function') { - var wrapFn = function (event) { - var result = newValue.apply(this, arguments); - if (result != undefined && !result) { - event.preventDefault(); + api.microtaskDrainDone = function () { + while (_uncaughtPromiseErrors.length) { + var _loop_1 = function () { + var uncaughtPromiseError = _uncaughtPromiseErrors.shift(); + try { + uncaughtPromiseError.zone.runGuarded(function () { + throw uncaughtPromiseError; + }); + } + catch (error) { + handleUnhandledRejection(error); } - return result; }; - target[_prop] = wrapFn; - target.addEventListener(eventName, wrapFn, false); - } - else { - target[_prop] = null; + while (_uncaughtPromiseErrors.length) { + _loop_1(); + } } }; - // The getter would return undefined for unassigned properties but the default value of an - // unassigned property is null - desc.get = function () { - // in some of windows's onproperty callback, this is undefined - // so we need to check it - var target = this; - if (!target && obj === _global) { - target = _global; - } - if (!target) { - return null; - } - if (target.hasOwnProperty(_prop)) { - return target[_prop]; - } - else if (originalDescGet) { - // result will be null when use inline event attribute, - // such as - // because the onclick function is internal raw uncompiled handler - // the onclick will be evaluated when first time event was triggered or - // the property is accessed, https://github.com/angular/zone.js/issues/525 - // so we should use original native get to retrieve the handler - var value = originalDescGet && originalDescGet.apply(this); - if (value) { - desc.set.apply(this, [value]); - if (typeof target['removeAttribute'] === 'function') { - target.removeAttribute(prop); - } - return value; + function handleUnhandledRejection(e) { + api.onUnhandledError(e); + try { + var handler = Zone[__symbol__('unhandledPromiseRejectionHandler')]; + if (handler && typeof handler === 'function') { + handler.apply(this, [e]); } } - return null; - }; - Object.defineProperty(obj, prop, desc); -} -function patchOnProperties(obj, properties) { - if (properties) { - for (var i = 0; i < properties.length; i++) { - patchProperty(obj, 'on' + properties[i]); + catch (err) { } } - else { - var onProperties = []; - for (var prop in obj) { - if (prop.substr(0, 2) == 'on') { - onProperties.push(prop); + function isThenable(value) { + return value && value.then; + } + function forwardResolution(value) { + return value; + } + function forwardRejection(rejection) { + return ZoneAwarePromise.reject(rejection); + } + var symbolState = __symbol__('state'); + var symbolValue = __symbol__('value'); + var source = 'Promise.then'; + var UNRESOLVED = null; + var RESOLVED = true; + var REJECTED = false; + var REJECTED_NO_CATCH = 0; + function makeResolver(promise, state) { + return function (v) { + try { + resolvePromise(promise, state, v); } - } - for (var j = 0; j < onProperties.length; j++) { - patchProperty(obj, onProperties[j]); - } + catch (err) { + resolvePromise(promise, false, err); + } + // Do not return value or you will break the Promise spec. + }; } -} -var EVENT_TASKS = zoneSymbol('eventTasks'); -// For EventTarget -var ADD_EVENT_LISTENER = 'addEventListener'; -var REMOVE_EVENT_LISTENER = 'removeEventListener'; -// compare the EventListenerOptionsOrCapture -// 1. if the options is usCapture: boolean, compare the useCpature values directly -// 2. if the options is EventListerOptions, only compare the capture -function compareEventListenerOptions(left, right) { - var leftCapture = (typeof left === 'boolean') ? - left : - ((typeof left === 'object') ? (left && left.capture) : false); - var rightCapture = (typeof right === 'boolean') ? - right : - ((typeof right === 'object') ? (right && right.capture) : false); - return !!leftCapture === !!rightCapture; -} -function findExistingRegisteredTask(target, handler, name, options, remove) { - var eventTasks = target[EVENT_TASKS]; - if (eventTasks) { - for (var i = 0; i < eventTasks.length; i++) { - var eventTask = eventTasks[i]; - var data = eventTask.data; - var listener = data.handler; - if ((data.handler === handler || listener.listener === handler) && - compareEventListenerOptions(data.options, options) && data.eventName === name) { - if (remove) { - eventTasks.splice(i, 1); + var once = function () { + var wasCalled = false; + return function wrapper(wrappedFunction) { + return function () { + if (wasCalled) { + return; } - return eventTask; - } + wasCalled = true; + wrappedFunction.apply(null, arguments); + }; + }; + }; + // Promise Resolution + function resolvePromise(promise, state, value) { + var onceWrapper = once(); + if (promise === value) { + throw new TypeError('Promise resolved with itself'); } - } - return null; -} -function findAllExistingRegisteredTasks(target, name, remove) { - var eventTasks = target[EVENT_TASKS]; - if (eventTasks) { - var result = []; - for (var i = eventTasks.length - 1; i >= 0; i--) { - var eventTask = eventTasks[i]; - var data = eventTask.data; - if (data.eventName === name) { - result.push(eventTask); - if (remove) { - eventTasks.splice(i, 1); + if (promise[symbolState] === UNRESOLVED) { + // should only get value.then once based on promise spec. + var then = null; + try { + if (typeof value === 'object' || typeof value === 'function') { + then = value && value.then; } } - } - return result; - } - return null; -} -function attachRegisteredEvent(target, eventTask, isPrepend) { - var eventTasks = target[EVENT_TASKS]; - if (!eventTasks) { - eventTasks = target[EVENT_TASKS] = []; - } - if (isPrepend) { - eventTasks.unshift(eventTask); - } - else { - eventTasks.push(eventTask); - } -} -var defaultListenerMetaCreator = function (self, args) { - return { - options: args[2], - eventName: args[0], - handler: args[1], - target: self || _global, - name: args[0], - crossContext: false, - invokeAddFunc: function (addFnSymbol, delegate) { - // check if the data is cross site context, if it is, fallback to - // remove the delegate directly and try catch error - if (!this.crossContext) { - if (delegate && delegate.invoke) { - return this.target[addFnSymbol](this.eventName, delegate.invoke, this.options); - } - else { - return this.target[addFnSymbol](this.eventName, delegate, this.options); - } + catch (err) { + onceWrapper(function () { + resolvePromise(promise, false, err); + })(); + return promise; } - else { - // add a if/else branch here for performance concern, for most times - // cross site context is false, so we don't need to try/catch + // if (value instanceof ZoneAwarePromise) { + if (state !== REJECTED && value instanceof ZoneAwarePromise && + value.hasOwnProperty(symbolState) && value.hasOwnProperty(symbolValue) && + value[symbolState] !== UNRESOLVED) { + clearRejectedNoCatch(value); + resolvePromise(promise, value[symbolState], value[symbolValue]); + } + else if (state !== REJECTED && typeof then === 'function') { try { - return this.target[addFnSymbol](this.eventName, delegate, this.options); + then.apply(value, [ + onceWrapper(makeResolver(promise, state)), onceWrapper(makeResolver(promise, false)) + ]); } catch (err) { - // do nothing here is fine, because objects in a cross-site context are unusable + onceWrapper(function () { + resolvePromise(promise, false, err); + })(); } } - }, - invokeRemoveFunc: function (removeFnSymbol, delegate) { - // check if the data is cross site context, if it is, fallback to - // remove the delegate directly and try catch error - if (!this.crossContext) { - if (delegate && delegate.invoke) { - return this.target[removeFnSymbol](this.eventName, delegate.invoke, this.options); + else { + promise[symbolState] = state; + var queue = promise[symbolValue]; + promise[symbolValue] = value; + // record task information in value when error occurs, so we can + // do some additional work such as render longStackTrace + if (state === REJECTED && value instanceof Error) { + value[__symbol__('currentTask')] = Zone.currentTask; } - else { - return this.target[removeFnSymbol](this.eventName, delegate, this.options); + for (var i = 0; i < queue.length;) { + scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]); + } + if (queue.length == 0 && state == REJECTED) { + promise[symbolState] = REJECTED_NO_CATCH; + try { + throw new Error('Uncaught (in promise): ' + value + + (value && value.stack ? '\n' + value.stack : '')); + } + catch (err) { + var error_1 = err; + error_1.rejection = value; + error_1.promise = promise; + error_1.zone = Zone.current; + error_1.task = Zone.currentTask; + _uncaughtPromiseErrors.push(error_1); + api.scheduleMicroTask(); // to make sure that it is running + } } } - else { - // add a if/else branch here for performance concern, for most times - // cross site context is false, so we don't need to try/catch - try { - return this.target[removeFnSymbol](this.eventName, delegate, this.options); + } + // Resolving an already resolved promise is a noop. + return promise; + } + function clearRejectedNoCatch(promise) { + if (promise[symbolState] === REJECTED_NO_CATCH) { + // if the promise is rejected no catch status + // and queue.length > 0, means there is a error handler + // here to handle the rejected promise, we should trigger + // windows.rejectionhandled eventHandler or nodejs rejectionHandled + // eventHandler + try { + var handler = Zone[__symbol__('rejectionHandledHandler')]; + if (handler && typeof handler === 'function') { + handler.apply(this, [{ rejection: promise[symbolValue], promise: promise }]); } - catch (err) { - // do nothing here is fine, because objects in a cross-site context are unusable + } + catch (err) { + } + promise[symbolState] = REJECTED; + for (var i = 0; i < _uncaughtPromiseErrors.length; i++) { + if (promise === _uncaughtPromiseErrors[i].promise) { + _uncaughtPromiseErrors.splice(i, 1); } } } - }; -}; -function makeZoneAwareAddListener(addFnName, removeFnName, useCapturingParam, allowDuplicates, isPrepend, metaCreator) { - if (useCapturingParam === void 0) { useCapturingParam = true; } - if (allowDuplicates === void 0) { allowDuplicates = false; } - if (isPrepend === void 0) { isPrepend = false; } - if (metaCreator === void 0) { metaCreator = defaultListenerMetaCreator; } - var addFnSymbol = zoneSymbol(addFnName); - var removeFnSymbol = zoneSymbol(removeFnName); - var defaultUseCapturing = useCapturingParam ? false : undefined; - function scheduleEventListener(eventTask) { - var meta = eventTask.data; - attachRegisteredEvent(meta.target, eventTask, isPrepend); - return meta.invokeAddFunc(addFnSymbol, eventTask); } - function cancelEventListener(eventTask) { - var meta = eventTask.data; - findExistingRegisteredTask(meta.target, eventTask.invoke, meta.eventName, meta.options, true); - return meta.invokeRemoveFunc(removeFnSymbol, eventTask); + function scheduleResolveOrReject(promise, zone, chainPromise, onFulfilled, onRejected) { + clearRejectedNoCatch(promise); + var delegate = promise[symbolState] ? + (typeof onFulfilled === 'function') ? onFulfilled : forwardResolution : + (typeof onRejected === 'function') ? onRejected : forwardRejection; + zone.scheduleMicroTask(source, function () { + try { + resolvePromise(chainPromise, true, zone.run(delegate, undefined, [promise[symbolValue]])); + } + catch (error) { + resolvePromise(chainPromise, false, error); + } + }); } - return function zoneAwareAddListener(self, args) { - var data = metaCreator(self, args); - data.options = data.options || defaultUseCapturing; - // - Inside a Web Worker, `this` is undefined, the context is `global` - // - When `addEventListener` is called on the global context in strict mode, `this` is undefined - // see https://github.com/angular/zone.js/issues/190 - var delegate = null; - if (typeof data.handler == 'function') { - delegate = data.handler; - } - else if (data.handler && data.handler.handleEvent) { - delegate = function (event) { return data.handler.handleEvent(event); }; - } - var validZoneHandler = false; - try { - // In cross site contexts (such as WebDriver frameworks like Selenium), - // accessing the handler object here will cause an exception to be thrown which - // will fail tests prematurely. - validZoneHandler = data.handler && data.handler.toString() === '[object FunctionWrapper]'; - } - catch (error) { - // we can still try to add the data.handler even we are in cross site context - data.crossContext = true; - return data.invokeAddFunc(addFnSymbol, data.handler); - } - // Ignore special listeners of IE11 & Edge dev tools, see - // https://github.com/angular/zone.js/issues/150 - if (!delegate || validZoneHandler) { - return data.invokeAddFunc(addFnSymbol, data.handler); - } - if (!allowDuplicates) { - var eventTask = findExistingRegisteredTask(data.target, data.handler, data.eventName, data.options, false); - if (eventTask) { - // we already registered, so this will have noop. - return data.invokeAddFunc(addFnSymbol, eventTask); + var ZoneAwarePromise = (function () { + function ZoneAwarePromise(executor) { + var promise = this; + if (!(promise instanceof ZoneAwarePromise)) { + throw new Error('Must be an instanceof Promise.'); + } + promise[symbolState] = UNRESOLVED; + promise[symbolValue] = []; // queue; + try { + executor && executor(makeResolver(promise, RESOLVED), makeResolver(promise, REJECTED)); + } + catch (error) { + resolvePromise(promise, false, error); } } - var zone = Zone.current; - var source = data.target.constructor['name'] + '.' + addFnName + ':' + data.eventName; - zone.scheduleEventTask(source, delegate, data, scheduleEventListener, cancelEventListener); - }; -} -function makeZoneAwareRemoveListener(fnName, useCapturingParam, metaCreator) { - if (useCapturingParam === void 0) { useCapturingParam = true; } - if (metaCreator === void 0) { metaCreator = defaultListenerMetaCreator; } - var symbol = zoneSymbol(fnName); - var defaultUseCapturing = useCapturingParam ? false : undefined; - return function zoneAwareRemoveListener(self, args) { - var data = metaCreator(self, args); - data.options = data.options || defaultUseCapturing; - // - Inside a Web Worker, `this` is undefined, the context is `global` - // - When `addEventListener` is called on the global context in strict mode, `this` is undefined - // see https://github.com/angular/zone.js/issues/190 - var delegate = null; - if (typeof data.handler == 'function') { - delegate = data.handler; - } - else if (data.handler && data.handler.handleEvent) { - delegate = function (event) { return data.handler.handleEvent(event); }; - } - var validZoneHandler = false; - try { - // In cross site contexts (such as WebDriver frameworks like Selenium), - // accessing the handler object here will cause an exception to be thrown which - // will fail tests prematurely. - validZoneHandler = data.handler && data.handler.toString() === '[object FunctionWrapper]'; - } - catch (error) { - data.crossContext = true; - return data.invokeRemoveFunc(symbol, data.handler); - } - // Ignore special listeners of IE11 & Edge dev tools, see - // https://github.com/angular/zone.js/issues/150 - if (!delegate || validZoneHandler) { - return data.invokeRemoveFunc(symbol, data.handler); - } - var eventTask = findExistingRegisteredTask(data.target, data.handler, data.eventName, data.options, true); - if (eventTask) { - eventTask.zone.cancelTask(eventTask); - } - else { - data.invokeRemoveFunc(symbol, data.handler); - } - }; -} -function makeZoneAwareRemoveAllListeners(fnName) { - var symbol = zoneSymbol(fnName); - return function zoneAwareRemoveAllListener(self, args) { - var target = self || _global; - if (args.length === 0) { - // remove all listeners without eventName - target[EVENT_TASKS] = []; - // we don't cancel Task either, because call native eventEmitter.removeAllListeners will - // will do remove listener(cancelTask) for us - target[symbol](); - return; - } - var eventName = args[0]; - // call this function just remove the related eventTask from target[EVENT_TASKS] - // we don't need useCapturing here because useCapturing is just for DOM, and - // removeAllListeners should only be called by node eventEmitter + ZoneAwarePromise.toString = function () { + return 'function ZoneAwarePromise() { [native code] }'; + }; + ZoneAwarePromise.resolve = function (value) { + return resolvePromise(new this(null), RESOLVED, value); + }; + ZoneAwarePromise.reject = function (error) { + return resolvePromise(new this(null), REJECTED, error); + }; + ZoneAwarePromise.race = function (values) { + var resolve; + var reject; + var promise = new this(function (res, rej) { + _a = [res, rej], resolve = _a[0], reject = _a[1]; + var _a; + }); + function onResolve(value) { + promise && (promise = null || resolve(value)); + } + function onReject(error) { + promise && (promise = null || reject(error)); + } + for (var _i = 0, values_1 = values; _i < values_1.length; _i++) { + var value = values_1[_i]; + if (!isThenable(value)) { + value = this.resolve(value); + } + value.then(onResolve, onReject); + } + return promise; + }; + ZoneAwarePromise.all = function (values) { + var resolve; + var reject; + var promise = new this(function (res, rej) { + resolve = res; + reject = rej; + }); + var count = 0; + var resolvedValues = []; + for (var _i = 0, values_2 = values; _i < values_2.length; _i++) { + var value = values_2[_i]; + if (!isThenable(value)) { + value = this.resolve(value); + } + value.then((function (index) { return function (value) { + resolvedValues[index] = value; + count--; + if (!count) { + resolve(resolvedValues); + } + }; })(count), reject); + count++; + } + if (!count) + resolve(resolvedValues); + return promise; + }; + ZoneAwarePromise.prototype.then = function (onFulfilled, onRejected) { + var chainPromise = new this.constructor(null); + var zone = Zone.current; + if (this[symbolState] == UNRESOLVED) { + this[symbolValue].push(zone, chainPromise, onFulfilled, onRejected); + } + else { + scheduleResolveOrReject(this, zone, chainPromise, onFulfilled, onRejected); + } + return chainPromise; + }; + ZoneAwarePromise.prototype.catch = function (onRejected) { + return this.then(null, onRejected); + }; + return ZoneAwarePromise; + }()); + // Protect against aggressive optimizers dropping seemingly unused properties. + // E.g. Closure Compiler in advanced mode. + ZoneAwarePromise['resolve'] = ZoneAwarePromise.resolve; + ZoneAwarePromise['reject'] = ZoneAwarePromise.reject; + ZoneAwarePromise['race'] = ZoneAwarePromise.race; + ZoneAwarePromise['all'] = ZoneAwarePromise.all; + var NativePromise = global[symbolPromise] = global['Promise']; + global['Promise'] = ZoneAwarePromise; + var symbolThenPatched = __symbol__('thenPatched'); + function patchThen(Ctor) { + var proto = Ctor.prototype; + var originalThen = proto.then; + // Keep a reference to the original method. + proto[symbolThen] = originalThen; + Ctor.prototype.then = function (onResolve, onReject) { + var _this = this; + var wrapped = new ZoneAwarePromise(function (resolve, reject) { + originalThen.call(_this, resolve, reject); + }); + return wrapped.then(onResolve, onReject); + }; + Ctor[symbolThenPatched] = true; + } + function zoneify(fn) { + return function () { + var resultPromise = fn.apply(this, arguments); + if (resultPromise instanceof ZoneAwarePromise) { + return resultPromise; + } + var ctor = resultPromise.constructor; + if (!ctor[symbolThenPatched]) { + patchThen(ctor); + } + return resultPromise; + }; + } + if (NativePromise) { + patchThen(NativePromise); + var fetch_1 = global['fetch']; + if (typeof fetch_1 == 'function') { + global['fetch'] = zoneify(fetch_1); + } + } + // This is not part of public API, but it is useful for tests, so we expose it. + Promise[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors; + return ZoneAwarePromise; +}); + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +/** + * Suppress closure compiler errors about unknown 'Zone' variable + * @fileoverview + * @suppress {undefinedVars,globalThis} + */ +var zoneSymbol = function (n) { return "__zone_symbol__" + n; }; +var _global = typeof window === 'object' && window || typeof self === 'object' && self || global; +function bindArguments(args, source) { + for (var i = args.length - 1; i >= 0; i--) { + if (typeof args[i] === 'function') { + args[i] = Zone.current.wrap(args[i], source + '_' + i); + } + } + return args; +} +function patchPrototype(prototype, fnNames) { + var source = prototype.constructor['name']; + var _loop_1 = function (i) { + var name_1 = fnNames[i]; + var delegate = prototype[name_1]; + if (delegate) { + prototype[name_1] = (function (delegate) { + var patched = function () { + return delegate.apply(this, bindArguments(arguments, source + '.' + name_1)); + }; + attachOriginToPatched(patched, delegate); + return patched; + })(delegate); + } + }; + for (var i = 0; i < fnNames.length; i++) { + _loop_1(i); + } +} +var isWebWorker = (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope); +// Make sure to access `process` through `_global` so that WebPack does not accidently browserify +// this code. +var isNode = (!('nw' in _global) && typeof _global.process !== 'undefined' && + {}.toString.call(_global.process) === '[object process]'); +var isBrowser = !isNode && !isWebWorker && !!(typeof window !== 'undefined' && window['HTMLElement']); +// we are in electron of nw, so we are both browser and nodejs +// Make sure to access `process` through `_global` so that WebPack does not accidently browserify +// this code. +var isMix = typeof _global.process !== 'undefined' && + {}.toString.call(_global.process) === '[object process]' && !isWebWorker && + !!(typeof window !== 'undefined' && window['HTMLElement']); +function patchProperty(obj, prop, prototype) { + var desc = Object.getOwnPropertyDescriptor(obj, prop); + if (!desc && prototype) { + // when patch window object, use prototype to check prop exist or not + var prototypeDesc = Object.getOwnPropertyDescriptor(prototype, prop); + if (prototypeDesc) { + desc = { enumerable: true, configurable: true }; + } + } + // if the descriptor not exists or is not configurable + // just return + if (!desc || !desc.configurable) { + return; + } + // A property descriptor cannot have getter/setter and be writable + // deleting the writable and value properties avoids this error: + // + // TypeError: property descriptors must not specify a value or be writable when a + // getter or setter has been specified + delete desc.writable; + delete desc.value; + var originalDescGet = desc.get; + // substr(2) cuz 'onclick' -> 'click', etc + var eventName = prop.substr(2); + var _prop = zoneSymbol('_' + prop); + desc.set = function (newValue) { + // in some of windows's onproperty callback, this is undefined + // so we need to check it + var target = this; + if (!target && obj === _global) { + target = _global; + } + if (!target) { + return; + } + var previousValue = target[_prop]; + if (previousValue) { + target.removeEventListener(eventName, previousValue); + } + if (typeof newValue === 'function') { + var wrapFn = function (event) { + var result = newValue.apply(this, arguments); + if (result != undefined && !result) { + event.preventDefault(); + } + return result; + }; + target[_prop] = wrapFn; + target.addEventListener(eventName, wrapFn, false); + } + else { + target[_prop] = null; + } + }; + // The getter would return undefined for unassigned properties but the default value of an + // unassigned property is null + desc.get = function () { + // in some of windows's onproperty callback, this is undefined + // so we need to check it + var target = this; + if (!target && obj === _global) { + target = _global; + } + if (!target) { + return null; + } + if (target.hasOwnProperty(_prop)) { + return target[_prop]; + } + else if (originalDescGet) { + // result will be null when use inline event attribute, + // such as + // because the onclick function is internal raw uncompiled handler + // the onclick will be evaluated when first time event was triggered or + // the property is accessed, https://github.com/angular/zone.js/issues/525 + // so we should use original native get to retrieve the handler + var value = originalDescGet && originalDescGet.apply(this); + if (value) { + desc.set.apply(this, [value]); + if (typeof target['removeAttribute'] === 'function') { + target.removeAttribute(prop); + } + return value; + } + } + return null; + }; + Object.defineProperty(obj, prop, desc); +} +function patchOnProperties(obj, properties, prototype) { + if (properties) { + for (var i = 0; i < properties.length; i++) { + patchProperty(obj, 'on' + properties[i], prototype); + } + } + else { + var onProperties = []; + for (var prop in obj) { + if (prop.substr(0, 2) == 'on') { + onProperties.push(prop); + } + } + for (var j = 0; j < onProperties.length; j++) { + patchProperty(obj, onProperties[j], prototype); + } + } +} +var EVENT_TASKS = zoneSymbol('eventTasks'); +// For EventTarget +var ADD_EVENT_LISTENER = 'addEventListener'; +var REMOVE_EVENT_LISTENER = 'removeEventListener'; +// compare the EventListenerOptionsOrCapture +// 1. if the options is usCapture: boolean, compare the useCpature values directly +// 2. if the options is EventListerOptions, only compare the capture +function compareEventListenerOptions(left, right) { + var leftCapture = (typeof left === 'boolean') ? + left : + ((typeof left === 'object') ? (left && left.capture) : false); + var rightCapture = (typeof right === 'boolean') ? + right : + ((typeof right === 'object') ? (right && right.capture) : false); + return !!leftCapture === !!rightCapture; +} +function findExistingRegisteredTask(target, handler, name, options, remove) { + var eventTasks = target[EVENT_TASKS]; + if (eventTasks) { + for (var i = 0; i < eventTasks.length; i++) { + var eventTask = eventTasks[i]; + var data = eventTask.data; + var listener = data.handler; + if ((data.handler === handler || listener.listener === handler) && + compareEventListenerOptions(data.options, options) && data.eventName === name) { + if (remove) { + eventTasks.splice(i, 1); + } + return eventTask; + } + } + } + return null; +} +function findAllExistingRegisteredTasks(target, name, remove) { + var eventTasks = target[EVENT_TASKS]; + if (eventTasks) { + var result = []; + for (var i = eventTasks.length - 1; i >= 0; i--) { + var eventTask = eventTasks[i]; + var data = eventTask.data; + if (data.eventName === name) { + result.push(eventTask); + if (remove) { + eventTasks.splice(i, 1); + } + } + } + return result; + } + return null; +} +function attachRegisteredEvent(target, eventTask, isPrepend) { + var eventTasks = target[EVENT_TASKS]; + if (!eventTasks) { + eventTasks = target[EVENT_TASKS] = []; + } + if (isPrepend) { + eventTasks.unshift(eventTask); + } + else { + eventTasks.push(eventTask); + } +} +var defaultListenerMetaCreator = function (self, args) { + return { + options: args[2], + eventName: args[0], + handler: args[1], + target: self || _global, + name: args[0], + crossContext: false, + invokeAddFunc: function (addFnSymbol, delegate) { + // check if the data is cross site context, if it is, fallback to + // remove the delegate directly and try catch error + if (!this.crossContext) { + if (delegate && delegate.invoke) { + return this.target[addFnSymbol](this.eventName, delegate.invoke, this.options); + } + else { + return this.target[addFnSymbol](this.eventName, delegate, this.options); + } + } + else { + // add a if/else branch here for performance concern, for most times + // cross site context is false, so we don't need to try/catch + try { + return this.target[addFnSymbol](this.eventName, delegate, this.options); + } + catch (err) { + // do nothing here is fine, because objects in a cross-site context are unusable + } + } + }, + invokeRemoveFunc: function (removeFnSymbol, delegate) { + // check if the data is cross site context, if it is, fallback to + // remove the delegate directly and try catch error + if (!this.crossContext) { + if (delegate && delegate.invoke) { + return this.target[removeFnSymbol](this.eventName, delegate.invoke, this.options); + } + else { + return this.target[removeFnSymbol](this.eventName, delegate, this.options); + } + } + else { + // add a if/else branch here for performance concern, for most times + // cross site context is false, so we don't need to try/catch + try { + return this.target[removeFnSymbol](this.eventName, delegate, this.options); + } + catch (err) { + // do nothing here is fine, because objects in a cross-site context are unusable + } + } + } + }; +}; +function makeZoneAwareAddListener(addFnName, removeFnName, useCapturingParam, allowDuplicates, isPrepend, metaCreator) { + if (useCapturingParam === void 0) { useCapturingParam = true; } + if (allowDuplicates === void 0) { allowDuplicates = false; } + if (isPrepend === void 0) { isPrepend = false; } + if (metaCreator === void 0) { metaCreator = defaultListenerMetaCreator; } + var addFnSymbol = zoneSymbol(addFnName); + var removeFnSymbol = zoneSymbol(removeFnName); + var defaultUseCapturing = useCapturingParam ? false : undefined; + function scheduleEventListener(eventTask) { + var meta = eventTask.data; + attachRegisteredEvent(meta.target, eventTask, isPrepend); + return meta.invokeAddFunc(addFnSymbol, eventTask); + } + function cancelEventListener(eventTask) { + var meta = eventTask.data; + findExistingRegisteredTask(meta.target, eventTask.invoke, meta.eventName, meta.options, true); + return meta.invokeRemoveFunc(removeFnSymbol, eventTask); + } + return function zoneAwareAddListener(self, args) { + var data = metaCreator(self, args); + data.options = data.options || defaultUseCapturing; + // - Inside a Web Worker, `this` is undefined, the context is `global` + // - When `addEventListener` is called on the global context in strict mode, `this` is undefined + // see https://github.com/angular/zone.js/issues/190 + var delegate = null; + if (typeof data.handler == 'function') { + delegate = data.handler; + } + else if (data.handler && data.handler.handleEvent) { + delegate = function (event) { return data.handler.handleEvent(event); }; + } + var validZoneHandler = false; + try { + // In cross site contexts (such as WebDriver frameworks like Selenium), + // accessing the handler object here will cause an exception to be thrown which + // will fail tests prematurely. + validZoneHandler = data.handler && data.handler.toString() === '[object FunctionWrapper]'; + } + catch (error) { + // we can still try to add the data.handler even we are in cross site context + data.crossContext = true; + return data.invokeAddFunc(addFnSymbol, data.handler); + } + // Ignore special listeners of IE11 & Edge dev tools, see + // https://github.com/angular/zone.js/issues/150 + if (!delegate || validZoneHandler) { + return data.invokeAddFunc(addFnSymbol, data.handler); + } + if (!allowDuplicates) { + var eventTask = findExistingRegisteredTask(data.target, data.handler, data.eventName, data.options, false); + if (eventTask) { + // we already registered, so this will have noop. + return data.invokeAddFunc(addFnSymbol, eventTask); + } + } + var zone = Zone.current; + var source = data.target.constructor['name'] + '.' + addFnName + ':' + data.eventName; + zone.scheduleEventTask(source, delegate, data, scheduleEventListener, cancelEventListener); + }; +} +function makeZoneAwareRemoveListener(fnName, useCapturingParam, metaCreator) { + if (useCapturingParam === void 0) { useCapturingParam = true; } + if (metaCreator === void 0) { metaCreator = defaultListenerMetaCreator; } + var symbol = zoneSymbol(fnName); + var defaultUseCapturing = useCapturingParam ? false : undefined; + return function zoneAwareRemoveListener(self, args) { + var data = metaCreator(self, args); + data.options = data.options || defaultUseCapturing; + // - Inside a Web Worker, `this` is undefined, the context is `global` + // - When `addEventListener` is called on the global context in strict mode, `this` is undefined + // see https://github.com/angular/zone.js/issues/190 + var delegate = null; + if (typeof data.handler == 'function') { + delegate = data.handler; + } + else if (data.handler && data.handler.handleEvent) { + delegate = function (event) { return data.handler.handleEvent(event); }; + } + var validZoneHandler = false; + try { + // In cross site contexts (such as WebDriver frameworks like Selenium), + // accessing the handler object here will cause an exception to be thrown which + // will fail tests prematurely. + validZoneHandler = data.handler && data.handler.toString() === '[object FunctionWrapper]'; + } + catch (error) { + data.crossContext = true; + return data.invokeRemoveFunc(symbol, data.handler); + } + // Ignore special listeners of IE11 & Edge dev tools, see + // https://github.com/angular/zone.js/issues/150 + if (!delegate || validZoneHandler) { + return data.invokeRemoveFunc(symbol, data.handler); + } + var eventTask = findExistingRegisteredTask(data.target, data.handler, data.eventName, data.options, true); + if (eventTask) { + eventTask.zone.cancelTask(eventTask); + } + else { + data.invokeRemoveFunc(symbol, data.handler); + } + }; +} +function makeZoneAwareRemoveAllListeners(fnName) { + var symbol = zoneSymbol(fnName); + return function zoneAwareRemoveAllListener(self, args) { + var target = self || _global; + if (args.length === 0) { + // remove all listeners without eventName + target[EVENT_TASKS] = []; + // we don't cancel Task either, because call native eventEmitter.removeAllListeners will + // will do remove listener(cancelTask) for us + target[symbol](); + return; + } + var eventName = args[0]; + // call this function just remove the related eventTask from target[EVENT_TASKS] + // we don't need useCapturing here because useCapturing is just for DOM, and + // removeAllListeners should only be called by node eventEmitter // and we don't cancel Task either, because call native eventEmitter.removeAllListeners will // will do remove listener(cancelTask) for us findAllExistingRegisteredTasks(target, eventName, true); @@ -1183,8 +1541,6 @@ function findEventTask(target, evtName) { function attachOriginToPatched(patched, original) { patched[zoneSymbol('OriginalDelegate')] = original; } -Zone[zoneSymbol('patchEventTargetMethods')] = patchEventTargetMethods; -Zone[zoneSymbol('patchOnProperties')] = patchOnProperties; /** * @license @@ -1498,8 +1854,215 @@ function apply(_global) { * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -var eventNames = 'copy cut paste abort blur focus canplay canplaythrough change click contextmenu dblclick drag dragend dragenter dragleave dragover dragstart drop durationchange emptied ended input invalid keydown keypress keyup load loadeddata loadedmetadata loadstart message mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup pause play playing progress ratechange reset scroll seeked seeking select show stalled submit suspend timeupdate volumechange waiting mozfullscreenchange mozfullscreenerror mozpointerlockchange mozpointerlockerror error webglcontextrestored webglcontextlost webglcontextcreationerror' - .split(' '); +var globalEventHandlersEventNames = [ + 'abort', + 'animationcancel', + 'animationend', + 'animationiteration', + 'auxclick', + 'beforeinput', + 'blur', + 'cancel', + 'canplay', + 'canplaythrough', + 'change', + 'compositionstart', + 'compositionupdate', + 'compositionend', + 'cuechange', + 'click', + 'close', + 'contextmenu', + 'curechange', + 'dblclick', + 'drag', + 'dragend', + 'dragenter', + 'dragexit', + 'dragleave', + 'dragover', + 'drop', + 'durationchange', + 'emptied', + 'ended', + 'error', + 'focus', + 'focusin', + 'focusout', + 'gotpointercapture', + 'input', + 'invalid', + 'keydown', + 'keypress', + 'keyup', + 'load', + 'loadstart', + 'loadeddata', + 'loadedmetadata', + 'lostpointercapture', + 'mousedown', + 'mouseenter', + 'mouseleave', + 'mousemove', + 'mouseout', + 'mouseover', + 'mouseup', + 'mousewheel', + 'pause', + 'play', + 'playing', + 'pointercancel', + 'pointerdown', + 'pointerenter', + 'pointerleave', + 'pointerlockchange', + 'mozpointerlockchange', + 'webkitpointerlockerchange', + 'pointerlockerror', + 'mozpointerlockerror', + 'webkitpointerlockerror', + 'pointermove', + 'pointout', + 'pointerover', + 'pointerup', + 'progress', + 'ratechange', + 'reset', + 'resize', + 'scroll', + 'seeked', + 'seeking', + 'select', + 'selectionchange', + 'selectstart', + 'show', + 'sort', + 'stalled', + 'submit', + 'suspend', + 'timeupdate', + 'volumechange', + 'touchcancel', + 'touchmove', + 'touchstart', + 'transitioncancel', + 'transitionend', + 'waiting', + 'wheel' +]; +var documentEventNames = [ + 'afterscriptexecute', 'beforescriptexecute', 'DOMContentLoaded', 'fullscreenchange', + 'mozfullscreenchange', 'webkitfullscreenchange', 'msfullscreenchange', 'fullscreenerror', + 'mozfullscreenerror', 'webkitfullscreenerror', 'msfullscreenerror', 'readystatechange' +]; +var windowEventNames = [ + 'absolutedeviceorientation', + 'afterinput', + 'afterprint', + 'appinstalled', + 'beforeinstallprompt', + 'beforeprint', + 'beforeunload', + 'devicelight', + 'devicemotion', + 'deviceorientation', + 'deviceorientationabsolute', + 'deviceproximity', + 'hashchange', + 'languagechange', + 'message', + 'mozbeforepaint', + 'offline', + 'online', + 'paint', + 'pageshow', + 'pagehide', + 'popstate', + 'rejectionhandled', + 'storage', + 'unhandledrejection', + 'unload', + 'userproximity', + 'vrdisplyconnected', + 'vrdisplaydisconnected', + 'vrdisplaypresentchange' +]; +var htmlElementEventNames = [ + 'beforecopy', 'beforecut', 'beforepaste', 'copy', 'cut', 'paste', 'dragstart', 'loadend', + 'animationstart', 'search', 'transitionrun', 'transitionstart', 'webkitanimationend', + 'webkitanimationiteration', 'webkitanimationstart', 'webkittransitionend' +]; +var mediaElementEventNames = ['encrypted', 'waitingforkey', 'msneedkey', 'mozinterruptbegin', 'mozinterruptend']; +var ieElementEventNames = [ + 'activate', + 'afterupdate', + 'ariarequest', + 'beforeactivate', + 'beforedeactivate', + 'beforeeditfocus', + 'beforeupdate', + 'cellchange', + 'controlselect', + 'dataavailable', + 'datasetchanged', + 'datasetcomplete', + 'errorupdate', + 'filterchange', + 'layoutcomplete', + 'losecapture', + 'move', + 'moveend', + 'movestart', + 'propertychange', + 'resizeend', + 'resizestart', + 'rowenter', + 'rowexit', + 'rowsdelete', + 'rowsinserted', + 'command', + 'compassneedscalibration', + 'deactivate', + 'help', + 'mscontentzoom', + 'msmanipulationstatechanged', + 'msgesturechange', + 'msgesturedoubletap', + 'msgestureend', + 'msgesturehold', + 'msgesturestart', + 'msgesturetap', + 'msgotpointercapture', + 'msinertiastart', + 'mslostpointercapture', + 'mspointercancel', + 'mspointerdown', + 'mspointerenter', + 'mspointerhover', + 'mspointerleave', + 'mspointermove', + 'mspointerout', + 'mspointerover', + 'mspointerup', + 'pointerout', + 'mssitemodejumplistitemremoved', + 'msthumbnailclick', + 'stop', + 'storagecommit' +]; +var webglEventNames = ['webglcontextrestored', 'webglcontextlost', 'webglcontextcreationerror']; +var formEventNames = ['autocomplete', 'autocompleteerror']; +var detailEventNames = ['toggle']; +var frameEventNames = ['load']; +var frameSetEventNames = ['blur', 'error', 'focus', 'load', 'resize', 'scroll']; +var marqueeEventNames = ['bounce', 'finish', 'start']; +var XMLHttpRequestEventNames = [ + 'loadstart', 'progress', 'abort', 'error', 'load', 'progress', 'timeout', 'loadend', + 'readystatechange' +]; +var IDBIndexEventNames = ['upgradeneeded', 'complete', 'abort', 'success', 'error', 'blocked', 'versionchange', 'close']; +var websocketEventNames = ['close', 'error', 'open', 'message']; +var eventNames = globalEventHandlersEventNames.concat(webglEventNames, formEventNames, detailEventNames, documentEventNames, windowEventNames, htmlElementEventNames, ieElementEventNames); function propertyDescriptorPatch(_global) { if (isNode && !isMix) { return; @@ -1508,24 +2071,40 @@ function propertyDescriptorPatch(_global) { if (canPatchViaPropertyDescriptor()) { // for browsers that we can patch the descriptor: Chrome & Firefox if (isBrowser) { - patchOnProperties(window, eventNames.concat(['resize'])); + // in IE/Edge, onProp not exist in window object, but in WindowPrototype + // so we need to pass WindowPrototype to check onProp exist or not + patchOnProperties(window, eventNames, Object.getPrototypeOf(window)); patchOnProperties(Document.prototype, eventNames); if (typeof window['SVGElement'] !== 'undefined') { patchOnProperties(window['SVGElement'].prototype, eventNames); } + patchOnProperties(Element.prototype, eventNames); patchOnProperties(HTMLElement.prototype, eventNames); + patchOnProperties(HTMLMediaElement.prototype, mediaElementEventNames); + patchOnProperties(HTMLFrameSetElement.prototype, windowEventNames.concat(frameSetEventNames)); + patchOnProperties(HTMLBodyElement.prototype, windowEventNames.concat(frameSetEventNames)); + patchOnProperties(HTMLFrameElement.prototype, frameEventNames); + patchOnProperties(HTMLIFrameElement.prototype, frameEventNames); + var HTMLMarqueeElement_1 = window['HTMLMarqueeElement']; + if (HTMLMarqueeElement_1) { + patchOnProperties(HTMLMarqueeElement_1.prototype, marqueeEventNames); + } + } + patchOnProperties(XMLHttpRequest.prototype, XMLHttpRequestEventNames); + var XMLHttpRequestEventTarget = _global['XMLHttpRequestEventTarget']; + if (XMLHttpRequestEventTarget) { + patchOnProperties(XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype, XMLHttpRequestEventNames); } - patchOnProperties(XMLHttpRequest.prototype, null); if (typeof IDBIndex !== 'undefined') { - patchOnProperties(IDBIndex.prototype, null); - patchOnProperties(IDBRequest.prototype, null); - patchOnProperties(IDBOpenDBRequest.prototype, null); - patchOnProperties(IDBDatabase.prototype, null); - patchOnProperties(IDBTransaction.prototype, null); - patchOnProperties(IDBCursor.prototype, null); + patchOnProperties(IDBIndex.prototype, IDBIndexEventNames); + patchOnProperties(IDBRequest.prototype, IDBIndexEventNames); + patchOnProperties(IDBOpenDBRequest.prototype, IDBIndexEventNames); + patchOnProperties(IDBDatabase.prototype, IDBIndexEventNames); + patchOnProperties(IDBTransaction.prototype, IDBIndexEventNames); + patchOnProperties(IDBCursor.prototype, IDBIndexEventNames); } if (supportsWebSocket) { - patchOnProperties(WebSocket.prototype, null); + patchOnProperties(WebSocket.prototype, websocketEventNames); } } else { @@ -1612,202 +2191,11 @@ function patchViaCapturingAllTheEvents() { elt = elt.parentElement; } }, true); - }; - for (var i = 0; i < eventNames.length; i++) { - _loop_1(i); - } -} - -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ -function registerElementPatch(_global) { - if ((!isBrowser && !isMix) || !('registerElement' in _global.document)) { - return; - } - var _registerElement = document.registerElement; - var callbacks = ['createdCallback', 'attachedCallback', 'detachedCallback', 'attributeChangedCallback']; - document.registerElement = function (name, opts) { - if (opts && opts.prototype) { - callbacks.forEach(function (callback) { - var source = 'Document.registerElement::' + callback; - if (opts.prototype.hasOwnProperty(callback)) { - var descriptor = Object.getOwnPropertyDescriptor(opts.prototype, callback); - if (descriptor && descriptor.value) { - descriptor.value = Zone.current.wrap(descriptor.value, source); - _redefineProperty(opts.prototype, callback, descriptor); - } - else { - opts.prototype[callback] = Zone.current.wrap(opts.prototype[callback], source); - } - } - else if (opts.prototype[callback]) { - opts.prototype[callback] = Zone.current.wrap(opts.prototype[callback], source); - } - }); - } - return _registerElement.apply(document, [name, opts]); - }; - attachOriginToPatched(document.registerElement, _registerElement); -} - -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ -Zone.__load_patch('timers', function (global, Zone, api) { - var set = 'set'; - var clear = 'clear'; - patchTimer(global, set, clear, 'Timeout'); - patchTimer(global, set, clear, 'Interval'); - patchTimer(global, set, clear, 'Immediate'); - patchTimer(global, 'request', 'cancel', 'AnimationFrame'); - patchTimer(global, 'mozRequest', 'mozCancel', 'AnimationFrame'); - patchTimer(global, 'webkitRequest', 'webkitCancel', 'AnimationFrame'); -}); -Zone.__load_patch('blocking', function (global, Zone, api) { - var blockingMethods = ['alert', 'prompt', 'confirm']; - for (var i = 0; i < blockingMethods.length; i++) { - var name_1 = blockingMethods[i]; - patchMethod(global, name_1, function (delegate, symbol, name) { - return function (s, args) { - return Zone.current.run(delegate, global, args, name); - }; - }); - } -}); -Zone.__load_patch('EventTarget', function (global, Zone, api) { - eventTargetPatch(global); - // patch XMLHttpRequestEventTarget's addEventListener/removeEventListener - var XMLHttpRequestEventTarget = global['XMLHttpRequestEventTarget']; - if (XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype) { - patchEventTargetMethods(XMLHttpRequestEventTarget.prototype); - } - patchClass('MutationObserver'); - patchClass('WebKitMutationObserver'); - patchClass('FileReader'); -}); -Zone.__load_patch('on_property', function (global, Zone, api) { - propertyDescriptorPatch(global); - propertyPatch(); - registerElementPatch(global); -}); -Zone.__load_patch('XHR', function (global, Zone, api) { - // Treat XMLHTTPRequest as a macrotask. - patchXHR(global); - var XHR_TASK = zoneSymbol('xhrTask'); - var XHR_SYNC = zoneSymbol('xhrSync'); - var XHR_LISTENER = zoneSymbol('xhrListener'); - var XHR_SCHEDULED = zoneSymbol('xhrScheduled'); - function patchXHR(window) { - function findPendingTask(target) { - var pendingTask = target[XHR_TASK]; - return pendingTask; - } - function scheduleTask(task) { - XMLHttpRequest[XHR_SCHEDULED] = false; - var data = task.data; - // remove existing event listener - var listener = data.target[XHR_LISTENER]; - if (listener) { - data.target.removeEventListener('readystatechange', listener); - } - var newListener = data.target[XHR_LISTENER] = function () { - if (data.target.readyState === data.target.DONE) { - // sometimes on some browsers XMLHttpRequest will fire onreadystatechange with - // readyState=4 multiple times, so we need to check task state here - if (!data.aborted && XMLHttpRequest[XHR_SCHEDULED] && - task.state === 'scheduled') { - task.invoke(); - } - } - }; - data.target.addEventListener('readystatechange', newListener); - var storedTask = data.target[XHR_TASK]; - if (!storedTask) { - data.target[XHR_TASK] = task; - } - sendNative.apply(data.target, data.args); - XMLHttpRequest[XHR_SCHEDULED] = true; - return task; - } - function placeholderCallback() { } - function clearTask(task) { - var data = task.data; - // Note - ideally, we would call data.target.removeEventListener here, but it's too late - // to prevent it from firing. So instead, we store info for the event listener. - data.aborted = true; - return abortNative.apply(data.target, data.args); - } - var openNative = patchMethod(window.XMLHttpRequest.prototype, 'open', function () { return function (self, args) { - self[XHR_SYNC] = args[2] == false; - return openNative.apply(self, args); - }; }); - var sendNative = patchMethod(window.XMLHttpRequest.prototype, 'send', function () { return function (self, args) { - var zone = Zone.current; - if (self[XHR_SYNC]) { - // if the XHR is sync there is no task to schedule, just execute the code. - return sendNative.apply(self, args); - } - else { - var options = { target: self, isPeriodic: false, delay: null, args: args, aborted: false }; - return zone.scheduleMacroTask('XMLHttpRequest.send', placeholderCallback, options, scheduleTask, clearTask); - } - }; }); - var abortNative = patchMethod(window.XMLHttpRequest.prototype, 'abort', function (delegate) { return function (self, args) { - var task = findPendingTask(self); - if (task && typeof task.type == 'string') { - // If the XHR has already completed, do nothing. - // If the XHR has already been aborted, do nothing. - // Fix #569, call abort multiple times before done will cause - // macroTask task count be negative number - if (task.cancelFn == null || (task.data && task.data.aborted)) { - return; - } - task.zone.cancelTask(task); - } - // Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no - // task - // to cancel. Do nothing. - }; }); - } -}); -Zone.__load_patch('geolocation', function (global, Zone, api) { - /// GEO_LOCATION - if (global['navigator'] && global['navigator'].geolocation) { - patchPrototype(global['navigator'].geolocation, ['getCurrentPosition', 'watchPosition']); - } -}); -Zone.__load_patch('PromiseRejectionEvent', function (global, Zone, api) { - // handle unhandled promise rejection - function findPromiseRejectionHandler(evtName) { - return function (e) { - var eventTasks = findEventTask(global, evtName); - eventTasks.forEach(function (eventTask) { - // windows has added unhandledrejection event listener - // trigger the event listener - var PromiseRejectionEvent = global['PromiseRejectionEvent']; - if (PromiseRejectionEvent) { - var evt = new PromiseRejectionEvent(evtName, { promise: e.promise, reason: e.rejection }); - eventTask.invoke(evt); - } - }); - }; - } - if (global['PromiseRejectionEvent']) { - Zone[zoneSymbol('unhandledPromiseRejectionHandler')] = - findPromiseRejectionHandler('unhandledrejection'); - Zone[zoneSymbol('rejectionHandledHandler')] = - findPromiseRejectionHandler('rejectionhandled'); + }; + for (var i = 0; i < eventNames.length; i++) { + _loop_1(i); } -}); +} /** * @license @@ -1816,332 +2204,192 @@ Zone.__load_patch('PromiseRejectionEvent', function (global, Zone, api) { * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -Zone.__load_patch('ZoneAwarePromise', function (global, Zone, api) { - var __symbol__ = api.symbol; - var _uncaughtPromiseErrors = []; - var symbolPromise = __symbol__('Promise'); - var symbolThen = __symbol__('then'); - api.onUnhandledError = function (e) { - if (api.showUncaughtError()) { - var rejection = e && e.rejection; - if (rejection) { - console.error('Unhandled Promise rejection:', rejection instanceof Error ? rejection.message : rejection, '; Zone:', e.zone.name, '; Task:', e.task && e.task.source, '; Value:', rejection, rejection instanceof Error ? rejection.stack : undefined); - } - console.error(e); - } - }; - api.microtaskDrainDone = function () { - while (_uncaughtPromiseErrors.length) { - var _loop_1 = function () { - var uncaughtPromiseError = _uncaughtPromiseErrors.shift(); - try { - uncaughtPromiseError.zone.runGuarded(function () { - throw uncaughtPromiseError; - }); +function registerElementPatch(_global) { + if ((!isBrowser && !isMix) || !('registerElement' in _global.document)) { + return; + } + var _registerElement = document.registerElement; + var callbacks = ['createdCallback', 'attachedCallback', 'detachedCallback', 'attributeChangedCallback']; + document.registerElement = function (name, opts) { + if (opts && opts.prototype) { + callbacks.forEach(function (callback) { + var source = 'Document.registerElement::' + callback; + if (opts.prototype.hasOwnProperty(callback)) { + var descriptor = Object.getOwnPropertyDescriptor(opts.prototype, callback); + if (descriptor && descriptor.value) { + descriptor.value = Zone.current.wrap(descriptor.value, source); + _redefineProperty(opts.prototype, callback, descriptor); + } + else { + opts.prototype[callback] = Zone.current.wrap(opts.prototype[callback], source); + } } - catch (error) { - handleUnhandledRejection(error); + else if (opts.prototype[callback]) { + opts.prototype[callback] = Zone.current.wrap(opts.prototype[callback], source); } - }; - while (_uncaughtPromiseErrors.length) { - _loop_1(); - } + }); } + return _registerElement.apply(document, [name, opts]); }; - function handleUnhandledRejection(e) { - api.onUnhandledError(e); - try { - var handler = Zone[__symbol__('unhandledPromiseRejectionHandler')]; - if (handler && typeof handler === 'function') { - handler.apply(this, [e]); - } - } - catch (err) { - } - } - function isThenable(value) { - return value && value.then; - } - function forwardResolution(value) { - return value; - } - function forwardRejection(rejection) { - return ZoneAwarePromise.reject(rejection); + attachOriginToPatched(document.registerElement, _registerElement); +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +Zone.__load_patch('timers', function (global, Zone, api) { + var set = 'set'; + var clear = 'clear'; + patchTimer(global, set, clear, 'Timeout'); + patchTimer(global, set, clear, 'Interval'); + patchTimer(global, set, clear, 'Immediate'); + patchTimer(global, 'request', 'cancel', 'AnimationFrame'); + patchTimer(global, 'mozRequest', 'mozCancel', 'AnimationFrame'); + patchTimer(global, 'webkitRequest', 'webkitCancel', 'AnimationFrame'); +}); +Zone.__load_patch('blocking', function (global, Zone, api) { + var blockingMethods = ['alert', 'prompt', 'confirm']; + for (var i = 0; i < blockingMethods.length; i++) { + var name_1 = blockingMethods[i]; + patchMethod(global, name_1, function (delegate, symbol, name) { + return function (s, args) { + return Zone.current.run(delegate, global, args, name); + }; + }); } - var symbolState = __symbol__('state'); - var symbolValue = __symbol__('value'); - var source = 'Promise.then'; - var UNRESOLVED = null; - var RESOLVED = true; - var REJECTED = false; - var REJECTED_NO_CATCH = 0; - function makeResolver(promise, state) { - return function (v) { - try { - resolvePromise(promise, state, v); - } - catch (err) { - resolvePromise(promise, false, err); - } - // Do not return value or you will break the Promise spec. - }; +}); +Zone.__load_patch('EventTarget', function (global, Zone, api) { + eventTargetPatch(global); + // patch XMLHttpRequestEventTarget's addEventListener/removeEventListener + var XMLHttpRequestEventTarget = global['XMLHttpRequestEventTarget']; + if (XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype) { + patchEventTargetMethods(XMLHttpRequestEventTarget.prototype); } - var once = function () { - var wasCalled = false; - return function wrapper(wrappedFunction) { - return function () { - if (wasCalled) { - return; - } - wasCalled = true; - wrappedFunction.apply(null, arguments); - }; - }; - }; - // Promise Resolution - function resolvePromise(promise, state, value) { - var onceWrapper = once(); - if (promise === value) { - throw new TypeError('Promise resolved with itself'); - } - if (promise[symbolState] === UNRESOLVED) { - // should only get value.then once based on promise spec. - var then = null; - try { - if (typeof value === 'object' || typeof value === 'function') { - then = value && value.then; - } - } - catch (err) { - onceWrapper(function () { - resolvePromise(promise, false, err); - })(); - return promise; - } - // if (value instanceof ZoneAwarePromise) { - if (state !== REJECTED && value instanceof ZoneAwarePromise && - value.hasOwnProperty(symbolState) && value.hasOwnProperty(symbolValue) && - value[symbolState] !== UNRESOLVED) { - clearRejectedNoCatch(value); - resolvePromise(promise, value[symbolState], value[symbolValue]); - } - else if (state !== REJECTED && typeof then === 'function') { - try { - then.apply(value, [ - onceWrapper(makeResolver(promise, state)), onceWrapper(makeResolver(promise, false)) - ]); - } - catch (err) { - onceWrapper(function () { - resolvePromise(promise, false, err); - })(); - } - } - else { - promise[symbolState] = state; - var queue = promise[symbolValue]; - promise[symbolValue] = value; - // record task information in value when error occurs, so we can - // do some additional work such as render longStackTrace - if (state === REJECTED && value instanceof Error) { - value[__symbol__('currentTask')] = Zone.currentTask; - } - for (var i = 0; i < queue.length;) { - scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]); - } - if (queue.length == 0 && state == REJECTED) { - promise[symbolState] = REJECTED_NO_CATCH; - try { - throw new Error('Uncaught (in promise): ' + value + - (value && value.stack ? '\n' + value.stack : '')); - } - catch (err) { - var error_1 = err; - error_1.rejection = value; - error_1.promise = promise; - error_1.zone = Zone.current; - error_1.task = Zone.currentTask; - _uncaughtPromiseErrors.push(error_1); - api.scheduleMicroTask(); // to make sure that it is running - } - } - } + patchClass('MutationObserver'); + patchClass('WebKitMutationObserver'); + patchClass('FileReader'); +}); +Zone.__load_patch('on_property', function (global, Zone, api) { + propertyDescriptorPatch(global); + propertyPatch(); + registerElementPatch(global); +}); +Zone.__load_patch('XHR', function (global, Zone, api) { + // Treat XMLHTTPRequest as a macrotask. + patchXHR(global); + var XHR_TASK = zoneSymbol('xhrTask'); + var XHR_SYNC = zoneSymbol('xhrSync'); + var XHR_LISTENER = zoneSymbol('xhrListener'); + var XHR_SCHEDULED = zoneSymbol('xhrScheduled'); + function patchXHR(window) { + function findPendingTask(target) { + var pendingTask = target[XHR_TASK]; + return pendingTask; } - // Resolving an already resolved promise is a noop. - return promise; - } - function clearRejectedNoCatch(promise) { - if (promise[symbolState] === REJECTED_NO_CATCH) { - // if the promise is rejected no catch status - // and queue.length > 0, means there is a error handler - // here to handle the rejected promise, we should trigger - // windows.rejectionhandled eventHandler or nodejs rejectionHandled - // eventHandler - try { - var handler = Zone[__symbol__('rejectionHandledHandler')]; - if (handler && typeof handler === 'function') { - handler.apply(this, [{ rejection: promise[symbolValue], promise: promise }]); - } - } - catch (err) { - } - promise[symbolState] = REJECTED; - for (var i = 0; i < _uncaughtPromiseErrors.length; i++) { - if (promise === _uncaughtPromiseErrors[i].promise) { - _uncaughtPromiseErrors.splice(i, 1); + function scheduleTask(task) { + XMLHttpRequest[XHR_SCHEDULED] = false; + var data = task.data; + // remove existing event listener + var listener = data.target[XHR_LISTENER]; + if (listener) { + data.target.removeEventListener('readystatechange', listener); + } + var newListener = data.target[XHR_LISTENER] = function () { + if (data.target.readyState === data.target.DONE) { + // sometimes on some browsers XMLHttpRequest will fire onreadystatechange with + // readyState=4 multiple times, so we need to check task state here + if (!data.aborted && XMLHttpRequest[XHR_SCHEDULED] && + task.state === 'scheduled') { + task.invoke(); + } } + }; + data.target.addEventListener('readystatechange', newListener); + var storedTask = data.target[XHR_TASK]; + if (!storedTask) { + data.target[XHR_TASK] = task; } + sendNative.apply(data.target, data.args); + XMLHttpRequest[XHR_SCHEDULED] = true; + return task; } - } - function scheduleResolveOrReject(promise, zone, chainPromise, onFulfilled, onRejected) { - clearRejectedNoCatch(promise); - var delegate = promise[symbolState] ? - (typeof onFulfilled === 'function') ? onFulfilled : forwardResolution : - (typeof onRejected === 'function') ? onRejected : forwardRejection; - zone.scheduleMicroTask(source, function () { - try { - resolvePromise(chainPromise, true, zone.run(delegate, undefined, [promise[symbolValue]])); - } - catch (error) { - resolvePromise(chainPromise, false, error); - } - }); - } - var ZoneAwarePromise = (function () { - function ZoneAwarePromise(executor) { - var promise = this; - if (!(promise instanceof ZoneAwarePromise)) { - throw new Error('Must be an instanceof Promise.'); - } - promise[symbolState] = UNRESOLVED; - promise[symbolValue] = []; // queue; - try { - executor && executor(makeResolver(promise, RESOLVED), makeResolver(promise, REJECTED)); - } - catch (error) { - resolvePromise(promise, false, error); - } + function placeholderCallback() { } + function clearTask(task) { + var data = task.data; + // Note - ideally, we would call data.target.removeEventListener here, but it's too late + // to prevent it from firing. So instead, we store info for the event listener. + data.aborted = true; + return abortNative.apply(data.target, data.args); } - ZoneAwarePromise.toString = function () { - return 'function ZoneAwarePromise() { [native code] }'; - }; - ZoneAwarePromise.resolve = function (value) { - return resolvePromise(new this(null), RESOLVED, value); - }; - ZoneAwarePromise.reject = function (error) { - return resolvePromise(new this(null), REJECTED, error); - }; - ZoneAwarePromise.race = function (values) { - var resolve; - var reject; - var promise = new this(function (res, rej) { - _a = [res, rej], resolve = _a[0], reject = _a[1]; - var _a; - }); - function onResolve(value) { - promise && (promise = null || resolve(value)); + var openNative = patchMethod(window.XMLHttpRequest.prototype, 'open', function () { return function (self, args) { + self[XHR_SYNC] = args[2] == false; + return openNative.apply(self, args); + }; }); + var sendNative = patchMethod(window.XMLHttpRequest.prototype, 'send', function () { return function (self, args) { + var zone = Zone.current; + if (self[XHR_SYNC]) { + // if the XHR is sync there is no task to schedule, just execute the code. + return sendNative.apply(self, args); } - function onReject(error) { - promise && (promise = null || reject(error)); + else { + var options = { target: self, isPeriodic: false, delay: null, args: args, aborted: false }; + return zone.scheduleMacroTask('XMLHttpRequest.send', placeholderCallback, options, scheduleTask, clearTask); } - for (var _i = 0, values_1 = values; _i < values_1.length; _i++) { - var value = values_1[_i]; - if (!isThenable(value)) { - value = this.resolve(value); + }; }); + var abortNative = patchMethod(window.XMLHttpRequest.prototype, 'abort', function (delegate) { return function (self, args) { + var task = findPendingTask(self); + if (task && typeof task.type == 'string') { + // If the XHR has already completed, do nothing. + // If the XHR has already been aborted, do nothing. + // Fix #569, call abort multiple times before done will cause + // macroTask task count be negative number + if (task.cancelFn == null || (task.data && task.data.aborted)) { + return; } - value.then(onResolve, onReject); + task.zone.cancelTask(task); } - return promise; - }; - ZoneAwarePromise.all = function (values) { - var resolve; - var reject; - var promise = new this(function (res, rej) { - resolve = res; - reject = rej; - }); - var count = 0; - var resolvedValues = []; - for (var _i = 0, values_2 = values; _i < values_2.length; _i++) { - var value = values_2[_i]; - if (!isThenable(value)) { - value = this.resolve(value); + // Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no + // task + // to cancel. Do nothing. + }; }); + } +}); +Zone.__load_patch('geolocation', function (global, Zone, api) { + /// GEO_LOCATION + if (global['navigator'] && global['navigator'].geolocation) { + patchPrototype(global['navigator'].geolocation, ['getCurrentPosition', 'watchPosition']); + } +}); +Zone.__load_patch('PromiseRejectionEvent', function (global, Zone, api) { + // handle unhandled promise rejection + function findPromiseRejectionHandler(evtName) { + return function (e) { + var eventTasks = findEventTask(global, evtName); + eventTasks.forEach(function (eventTask) { + // windows has added unhandledrejection event listener + // trigger the event listener + var PromiseRejectionEvent = global['PromiseRejectionEvent']; + if (PromiseRejectionEvent) { + var evt = new PromiseRejectionEvent(evtName, { promise: e.promise, reason: e.rejection }); + eventTask.invoke(evt); } - value.then((function (index) { return function (value) { - resolvedValues[index] = value; - count--; - if (!count) { - resolve(resolvedValues); - } - }; })(count), reject); - count++; - } - if (!count) - resolve(resolvedValues); - return promise; - }; - ZoneAwarePromise.prototype.then = function (onFulfilled, onRejected) { - var chainPromise = new this.constructor(null); - var zone = Zone.current; - if (this[symbolState] == UNRESOLVED) { - this[symbolValue].push(zone, chainPromise, onFulfilled, onRejected); - } - else { - scheduleResolveOrReject(this, zone, chainPromise, onFulfilled, onRejected); - } - return chainPromise; - }; - ZoneAwarePromise.prototype.catch = function (onRejected) { - return this.then(null, onRejected); - }; - return ZoneAwarePromise; - }()); - // Protect against aggressive optimizers dropping seemingly unused properties. - // E.g. Closure Compiler in advanced mode. - ZoneAwarePromise['resolve'] = ZoneAwarePromise.resolve; - ZoneAwarePromise['reject'] = ZoneAwarePromise.reject; - ZoneAwarePromise['race'] = ZoneAwarePromise.race; - ZoneAwarePromise['all'] = ZoneAwarePromise.all; - var NativePromise = global[symbolPromise] = global['Promise']; - global['Promise'] = ZoneAwarePromise; - var symbolThenPatched = __symbol__('thenPatched'); - function patchThen(Ctor) { - var proto = Ctor.prototype; - var originalThen = proto.then; - // Keep a reference to the original method. - proto[symbolThen] = originalThen; - Ctor.prototype.then = function (onResolve, onReject) { - var _this = this; - var wrapped = new ZoneAwarePromise(function (resolve, reject) { - originalThen.call(_this, resolve, reject); }); - return wrapped.then(onResolve, onReject); - }; - Ctor[symbolThenPatched] = true; - } - function zoneify(fn) { - return function () { - var resultPromise = fn.apply(this, arguments); - if (resultPromise instanceof ZoneAwarePromise) { - return resultPromise; - } - var ctor = resultPromise.constructor; - if (!ctor[symbolThenPatched]) { - patchThen(ctor); - } - return resultPromise; }; } - if (NativePromise) { - patchThen(NativePromise); - var fetch_1 = global['fetch']; - if (typeof fetch_1 == 'function') { - global['fetch'] = zoneify(fetch_1); - } + if (global['PromiseRejectionEvent']) { + Zone[zoneSymbol('unhandledPromiseRejectionHandler')] = + findPromiseRejectionHandler('unhandledrejection'); + Zone[zoneSymbol('rejectionHandledHandler')] = + findPromiseRejectionHandler('rejectionhandled'); } - // This is not part of public API, but it is useful for tests, so we expose it. - Promise[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors; - return ZoneAwarePromise; +}); +Zone.__load_patch('util', function (global, Zone, api) { + api.patchEventTargetMethods = patchEventTargetMethods; + api.patchOnProperties = patchOnProperties; }); /** @@ -2151,48 +2399,50 @@ Zone.__load_patch('ZoneAwarePromise', function (global, Zone, api) { * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -var callAndReturnFirstParam = function (fn) { - return function (self, args) { - fn(self, args); - return self; +Zone.__load_patch('EventEmitter', function (global, Zone, api) { + var callAndReturnFirstParam = function (fn) { + return function (self, args) { + fn(self, args); + return self; + }; }; -}; -// For EventEmitter -var EE_ADD_LISTENER = 'addListener'; -var EE_PREPEND_LISTENER = 'prependListener'; -var EE_REMOVE_LISTENER = 'removeListener'; -var EE_REMOVE_ALL_LISTENER = 'removeAllListeners'; -var EE_LISTENERS = 'listeners'; -var EE_ON = 'on'; -var zoneAwareAddListener = callAndReturnFirstParam(makeZoneAwareAddListener(EE_ADD_LISTENER, EE_REMOVE_LISTENER, false, true, false)); -var zoneAwarePrependListener = callAndReturnFirstParam(makeZoneAwareAddListener(EE_PREPEND_LISTENER, EE_REMOVE_LISTENER, false, true, true)); -var zoneAwareRemoveListener = callAndReturnFirstParam(makeZoneAwareRemoveListener(EE_REMOVE_LISTENER, false)); -var zoneAwareRemoveAllListeners = callAndReturnFirstParam(makeZoneAwareRemoveAllListeners(EE_REMOVE_ALL_LISTENER)); -var zoneAwareListeners = makeZoneAwareListeners(EE_LISTENERS); -function patchEventEmitterMethods(obj) { - if (obj && obj.addListener) { - patchMethod(obj, EE_ADD_LISTENER, function () { return zoneAwareAddListener; }); - patchMethod(obj, EE_PREPEND_LISTENER, function () { return zoneAwarePrependListener; }); - patchMethod(obj, EE_REMOVE_LISTENER, function () { return zoneAwareRemoveListener; }); - patchMethod(obj, EE_REMOVE_ALL_LISTENER, function () { return zoneAwareRemoveAllListeners; }); - patchMethod(obj, EE_LISTENERS, function () { return zoneAwareListeners; }); - obj[EE_ON] = obj[EE_ADD_LISTENER]; - return true; + // For EventEmitter + var EE_ADD_LISTENER = 'addListener'; + var EE_PREPEND_LISTENER = 'prependListener'; + var EE_REMOVE_LISTENER = 'removeListener'; + var EE_REMOVE_ALL_LISTENER = 'removeAllListeners'; + var EE_LISTENERS = 'listeners'; + var EE_ON = 'on'; + var zoneAwareAddListener = callAndReturnFirstParam(makeZoneAwareAddListener(EE_ADD_LISTENER, EE_REMOVE_LISTENER, false, true, false)); + var zoneAwarePrependListener = callAndReturnFirstParam(makeZoneAwareAddListener(EE_PREPEND_LISTENER, EE_REMOVE_LISTENER, false, true, true)); + var zoneAwareRemoveListener = callAndReturnFirstParam(makeZoneAwareRemoveListener(EE_REMOVE_LISTENER, false)); + var zoneAwareRemoveAllListeners = callAndReturnFirstParam(makeZoneAwareRemoveAllListeners(EE_REMOVE_ALL_LISTENER)); + var zoneAwareListeners = makeZoneAwareListeners(EE_LISTENERS); + function patchEventEmitterMethods(obj) { + if (obj && obj.addListener) { + patchMethod(obj, EE_ADD_LISTENER, function () { return zoneAwareAddListener; }); + patchMethod(obj, EE_PREPEND_LISTENER, function () { return zoneAwarePrependListener; }); + patchMethod(obj, EE_REMOVE_LISTENER, function () { return zoneAwareRemoveListener; }); + patchMethod(obj, EE_REMOVE_ALL_LISTENER, function () { return zoneAwareRemoveAllListeners; }); + patchMethod(obj, EE_LISTENERS, function () { return zoneAwareListeners; }); + obj[EE_ON] = obj[EE_ADD_LISTENER]; + return true; + } + else { + return false; + } } - else { - return false; + // EventEmitter + var events; + try { + events = require('events'); } -} -// EventEmitter -var events; -try { - events = require('events'); -} -catch (err) { -} -if (events && events.EventEmitter) { - patchEventEmitterMethods(events.EventEmitter.prototype); -} + catch (err) { + } + if (events && events.EventEmitter) { + patchEventEmitterMethods(events.EventEmitter.prototype); + } +}); /** * @license @@ -2201,34 +2451,36 @@ if (events && events.EventEmitter) { * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -var fs; -try { - fs = require('fs'); -} -catch (err) { -} -// watch, watchFile, unwatchFile has been patched -// because EventEmitter has been patched -var TO_PATCH_MACROTASK_METHODS = [ - 'access', 'appendFile', 'chmod', 'chown', 'close', 'exists', 'fchmod', - 'fchown', 'fdatasync', 'fstat', 'fsync', 'ftruncate', 'futimes', 'lchmod', - 'lchown', 'link', 'lstat', 'mkdir', 'mkdtemp', 'open', 'read', - 'readdir', 'readFile', 'readlink', 'realpath', 'rename', 'rmdir', 'stat', - 'symlink', 'truncate', 'unlink', 'utimes', 'write', 'writeFile', -]; -if (fs) { - TO_PATCH_MACROTASK_METHODS.filter(function (name) { return !!fs[name] && typeof fs[name] === 'function'; }) - .forEach(function (name) { - patchMacroTask(fs, name, function (self, args) { - return { - name: 'fs.' + name, - args: args, - callbackIndex: args.length > 0 ? args.length - 1 : -1, - target: self - }; +Zone.__load_patch('fs', function (global, Zone, api) { + var fs; + try { + fs = require('fs'); + } + catch (err) { + } + // watch, watchFile, unwatchFile has been patched + // because EventEmitter has been patched + var TO_PATCH_MACROTASK_METHODS = [ + 'access', 'appendFile', 'chmod', 'chown', 'close', 'exists', 'fchmod', + 'fchown', 'fdatasync', 'fstat', 'fsync', 'ftruncate', 'futimes', 'lchmod', + 'lchown', 'link', 'lstat', 'mkdir', 'mkdtemp', 'open', 'read', + 'readdir', 'readFile', 'readlink', 'realpath', 'rename', 'rmdir', 'stat', + 'symlink', 'truncate', 'unlink', 'utimes', 'write', 'writeFile', + ]; + if (fs) { + TO_PATCH_MACROTASK_METHODS.filter(function (name) { return !!fs[name] && typeof fs[name] === 'function'; }) + .forEach(function (name) { + patchMacroTask(fs, name, function (self, args) { + return { + name: 'fs.' + name, + args: args, + callbackIndex: args.length > 0 ? args.length - 1 : -1, + target: self + }; + }); }); - }); -} + } +}); /** * @license @@ -2239,14 +2491,17 @@ if (fs) { */ var set = 'set'; var clear = 'clear'; -Zone.__load_patch('timers', function (global, Zone, api) { +Zone.__load_patch('node_timers', function (global, Zone, api) { // Timers var globalUseTimeoutFromTimer = false; try { var timers = require('timers'); var globalEqualTimersTimeout = global.setTimeout === timers.setTimeout; - if (!globalEqualTimersTimeout) { - // if global.setTimeout not equal timers.setTimeout, check + if (!globalEqualTimersTimeout && !isMix) { + // 1. if isMix, then we are in mix environment such as Electron + // we should only patch timers.setTimeout because global.setTimeout + // have been patched + // 2. if global.setTimeout not equal timers.setTimeout, check // whether global.setTimeout use timers.setTimeout or not var originSetTimeout_1 = timers.setTimeout; timers.setTimeout = function () { @@ -2265,6 +2520,12 @@ Zone.__load_patch('timers', function (global, Zone, api) { // timers module not exists, for example, when we using nativescript // timers is not available } + if (isMix) { + // if we are in mix environment, such as Electron, + // the global.setTimeout has already been patched, + // so we just patch timers.setTimeout + return; + } if (!globalUseTimeoutFromTimer) { // 1. global setTimeout equals timers setTimeout // 2. or global don't use timers setTimeout(maybe some other library patch setTimeout) diff --git a/dist/zone-node.js b/dist/zone-node.js index 97eb43665..594c51ece 100644 --- a/dist/zone-node.js +++ b/dist/zone-node.js @@ -164,9 +164,19 @@ var Zone$1 = (function (global) { } }; Zone.prototype.runTask = function (task, applyThis, applyArgs) { - if (task.zone != this) + if (task.zone != this) { throw new Error('A task can only be run in the zone of creation! (Creation: ' + (task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')'); + } + // https://github.com/angular/zone.js/issues/778, sometimes eventTask + // will run in notScheduled(canceled) state, we should not try to + // run such kind of task but just return + // we have to define an variable here, if not + // typescript compiler will complain below + var isNotScheduled = task.state === notScheduled; + if (isNotScheduled && task.type === eventTask) { + return; + } var reEntryGuard = task.state != running; reEntryGuard && task._transitionTo(running, scheduled); task.runCount++; @@ -598,7 +608,9 @@ var Zone$1 = (function (global) { onUnhandledError: noop, microtaskDrainDone: noop, scheduleMicroTask: scheduleMicroTask, - showUncaughtError: function () { return !Zone[__symbol__('ignoreConsoleErrorUncaughtError')]; } + showUncaughtError: function () { return !Zone[__symbol__('ignoreConsoleErrorUncaughtError')]; }, + patchEventTargetMethods: function () { return false; }, + patchOnProperties: noop }; var _currentZoneFrame = { parent: null, zone: new Zone(null, null) }; var _currentTask = null; @@ -963,117 +975,20 @@ var _global = typeof window === 'object' && window || typeof self === 'object' & var isWebWorker = (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope); -var isNode = (!('nw' in _global) && typeof process !== 'undefined' && - {}.toString.call(process) === '[object process]'); +// Make sure to access `process` through `_global` so that WebPack does not accidently browserify +// this code. +var isNode = (!('nw' in _global) && typeof _global.process !== 'undefined' && + {}.toString.call(_global.process) === '[object process]'); // we are in electron of nw, so we are both browser and nodejs -var isMix = typeof process !== 'undefined' && - {}.toString.call(process) === '[object process]' && !isWebWorker && +// Make sure to access `process` through `_global` so that WebPack does not accidently browserify +// this code. +var isMix = typeof _global.process !== 'undefined' && + {}.toString.call(_global.process) === '[object process]' && !isWebWorker && !!(typeof window !== 'undefined' && window['HTMLElement']); -function patchProperty(obj, prop) { - var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true }; - // if the descriptor is not configurable - // just return - if (!desc.configurable) { - return; - } - // A property descriptor cannot have getter/setter and be writable - // deleting the writable and value properties avoids this error: - // - // TypeError: property descriptors must not specify a value or be writable when a - // getter or setter has been specified - delete desc.writable; - delete desc.value; - var originalDescGet = desc.get; - // substr(2) cuz 'onclick' -> 'click', etc - var eventName = prop.substr(2); - var _prop = zoneSymbol('_' + prop); - desc.set = function (newValue) { - // in some of windows's onproperty callback, this is undefined - // so we need to check it - var target = this; - if (!target && obj === _global) { - target = _global; - } - if (!target) { - return; - } - var previousValue = target[_prop]; - if (previousValue) { - target.removeEventListener(eventName, previousValue); - } - if (typeof newValue === 'function') { - var wrapFn = function (event) { - var result = newValue.apply(this, arguments); - if (result != undefined && !result) { - event.preventDefault(); - } - return result; - }; - target[_prop] = wrapFn; - target.addEventListener(eventName, wrapFn, false); - } - else { - target[_prop] = null; - } - }; - // The getter would return undefined for unassigned properties but the default value of an - // unassigned property is null - desc.get = function () { - // in some of windows's onproperty callback, this is undefined - // so we need to check it - var target = this; - if (!target && obj === _global) { - target = _global; - } - if (!target) { - return null; - } - if (target.hasOwnProperty(_prop)) { - return target[_prop]; - } - else if (originalDescGet) { - // result will be null when use inline event attribute, - // such as - // because the onclick function is internal raw uncompiled handler - // the onclick will be evaluated when first time event was triggered or - // the property is accessed, https://github.com/angular/zone.js/issues/525 - // so we should use original native get to retrieve the handler - var value = originalDescGet && originalDescGet.apply(this); - if (value) { - desc.set.apply(this, [value]); - if (typeof target['removeAttribute'] === 'function') { - target.removeAttribute(prop); - } - return value; - } - } - return null; - }; - Object.defineProperty(obj, prop, desc); -} -function patchOnProperties(obj, properties) { - if (properties) { - for (var i = 0; i < properties.length; i++) { - patchProperty(obj, 'on' + properties[i]); - } - } - else { - var onProperties = []; - for (var prop in obj) { - if (prop.substr(0, 2) == 'on') { - onProperties.push(prop); - } - } - for (var j = 0; j < onProperties.length; j++) { - patchProperty(obj, onProperties[j]); - } - } -} + + var EVENT_TASKS = zoneSymbol('eventTasks'); -// For EventTarget -var ADD_EVENT_LISTENER = 'addEventListener'; -var REMOVE_EVENT_LISTENER = 'removeEventListener'; // compare the EventListenerOptionsOrCapture // 1. if the options is usCapture: boolean, compare the useCpature values directly // 2. if the options is EventListerOptions, only compare the capture @@ -1325,19 +1240,7 @@ function makeZoneAwareListeners(fnName) { .map(function (task) { return task.data['handler']; }); }; } -function patchEventTargetMethods(obj, addFnName, removeFnName, metaCreator) { - if (addFnName === void 0) { addFnName = ADD_EVENT_LISTENER; } - if (removeFnName === void 0) { removeFnName = REMOVE_EVENT_LISTENER; } - if (metaCreator === void 0) { metaCreator = defaultListenerMetaCreator; } - if (obj && obj[addFnName]) { - patchMethod(obj, addFnName, function () { return makeZoneAwareAddListener(addFnName, removeFnName, true, false, false, metaCreator); }); - patchMethod(obj, removeFnName, function () { return makeZoneAwareRemoveListener(removeFnName, true, metaCreator); }); - return true; - } - else { - return false; - } -} + // wrap some native API on `window` function patchMethod(target, name, patchFn) { @@ -1424,8 +1327,6 @@ function findEventTask(target, evtName) { function attachOriginToPatched(patched, original) { patched[zoneSymbol('OriginalDelegate')] = original; } -Zone[zoneSymbol('patchEventTargetMethods')] = patchEventTargetMethods; -Zone[zoneSymbol('patchOnProperties')] = patchOnProperties; /** * @license @@ -1476,48 +1377,50 @@ Zone.__load_patch('toString', function (global, Zone, api) { * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -var callAndReturnFirstParam = function (fn) { - return function (self, args) { - fn(self, args); - return self; +Zone.__load_patch('EventEmitter', function (global, Zone, api) { + var callAndReturnFirstParam = function (fn) { + return function (self, args) { + fn(self, args); + return self; + }; }; -}; -// For EventEmitter -var EE_ADD_LISTENER = 'addListener'; -var EE_PREPEND_LISTENER = 'prependListener'; -var EE_REMOVE_LISTENER = 'removeListener'; -var EE_REMOVE_ALL_LISTENER = 'removeAllListeners'; -var EE_LISTENERS = 'listeners'; -var EE_ON = 'on'; -var zoneAwareAddListener = callAndReturnFirstParam(makeZoneAwareAddListener(EE_ADD_LISTENER, EE_REMOVE_LISTENER, false, true, false)); -var zoneAwarePrependListener = callAndReturnFirstParam(makeZoneAwareAddListener(EE_PREPEND_LISTENER, EE_REMOVE_LISTENER, false, true, true)); -var zoneAwareRemoveListener = callAndReturnFirstParam(makeZoneAwareRemoveListener(EE_REMOVE_LISTENER, false)); -var zoneAwareRemoveAllListeners = callAndReturnFirstParam(makeZoneAwareRemoveAllListeners(EE_REMOVE_ALL_LISTENER)); -var zoneAwareListeners = makeZoneAwareListeners(EE_LISTENERS); -function patchEventEmitterMethods(obj) { - if (obj && obj.addListener) { - patchMethod(obj, EE_ADD_LISTENER, function () { return zoneAwareAddListener; }); - patchMethod(obj, EE_PREPEND_LISTENER, function () { return zoneAwarePrependListener; }); - patchMethod(obj, EE_REMOVE_LISTENER, function () { return zoneAwareRemoveListener; }); - patchMethod(obj, EE_REMOVE_ALL_LISTENER, function () { return zoneAwareRemoveAllListeners; }); - patchMethod(obj, EE_LISTENERS, function () { return zoneAwareListeners; }); - obj[EE_ON] = obj[EE_ADD_LISTENER]; - return true; + // For EventEmitter + var EE_ADD_LISTENER = 'addListener'; + var EE_PREPEND_LISTENER = 'prependListener'; + var EE_REMOVE_LISTENER = 'removeListener'; + var EE_REMOVE_ALL_LISTENER = 'removeAllListeners'; + var EE_LISTENERS = 'listeners'; + var EE_ON = 'on'; + var zoneAwareAddListener = callAndReturnFirstParam(makeZoneAwareAddListener(EE_ADD_LISTENER, EE_REMOVE_LISTENER, false, true, false)); + var zoneAwarePrependListener = callAndReturnFirstParam(makeZoneAwareAddListener(EE_PREPEND_LISTENER, EE_REMOVE_LISTENER, false, true, true)); + var zoneAwareRemoveListener = callAndReturnFirstParam(makeZoneAwareRemoveListener(EE_REMOVE_LISTENER, false)); + var zoneAwareRemoveAllListeners = callAndReturnFirstParam(makeZoneAwareRemoveAllListeners(EE_REMOVE_ALL_LISTENER)); + var zoneAwareListeners = makeZoneAwareListeners(EE_LISTENERS); + function patchEventEmitterMethods(obj) { + if (obj && obj.addListener) { + patchMethod(obj, EE_ADD_LISTENER, function () { return zoneAwareAddListener; }); + patchMethod(obj, EE_PREPEND_LISTENER, function () { return zoneAwarePrependListener; }); + patchMethod(obj, EE_REMOVE_LISTENER, function () { return zoneAwareRemoveListener; }); + patchMethod(obj, EE_REMOVE_ALL_LISTENER, function () { return zoneAwareRemoveAllListeners; }); + patchMethod(obj, EE_LISTENERS, function () { return zoneAwareListeners; }); + obj[EE_ON] = obj[EE_ADD_LISTENER]; + return true; + } + else { + return false; + } } - else { - return false; + // EventEmitter + var events; + try { + events = require('events'); } -} -// EventEmitter -var events; -try { - events = require('events'); -} -catch (err) { -} -if (events && events.EventEmitter) { - patchEventEmitterMethods(events.EventEmitter.prototype); -} + catch (err) { + } + if (events && events.EventEmitter) { + patchEventEmitterMethods(events.EventEmitter.prototype); + } +}); /** * @license @@ -1526,34 +1429,36 @@ if (events && events.EventEmitter) { * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -var fs; -try { - fs = require('fs'); -} -catch (err) { -} -// watch, watchFile, unwatchFile has been patched -// because EventEmitter has been patched -var TO_PATCH_MACROTASK_METHODS = [ - 'access', 'appendFile', 'chmod', 'chown', 'close', 'exists', 'fchmod', - 'fchown', 'fdatasync', 'fstat', 'fsync', 'ftruncate', 'futimes', 'lchmod', - 'lchown', 'link', 'lstat', 'mkdir', 'mkdtemp', 'open', 'read', - 'readdir', 'readFile', 'readlink', 'realpath', 'rename', 'rmdir', 'stat', - 'symlink', 'truncate', 'unlink', 'utimes', 'write', 'writeFile', -]; -if (fs) { - TO_PATCH_MACROTASK_METHODS.filter(function (name) { return !!fs[name] && typeof fs[name] === 'function'; }) - .forEach(function (name) { - patchMacroTask(fs, name, function (self, args) { - return { - name: 'fs.' + name, - args: args, - callbackIndex: args.length > 0 ? args.length - 1 : -1, - target: self - }; +Zone.__load_patch('fs', function (global, Zone, api) { + var fs; + try { + fs = require('fs'); + } + catch (err) { + } + // watch, watchFile, unwatchFile has been patched + // because EventEmitter has been patched + var TO_PATCH_MACROTASK_METHODS = [ + 'access', 'appendFile', 'chmod', 'chown', 'close', 'exists', 'fchmod', + 'fchown', 'fdatasync', 'fstat', 'fsync', 'ftruncate', 'futimes', 'lchmod', + 'lchown', 'link', 'lstat', 'mkdir', 'mkdtemp', 'open', 'read', + 'readdir', 'readFile', 'readlink', 'realpath', 'rename', 'rmdir', 'stat', + 'symlink', 'truncate', 'unlink', 'utimes', 'write', 'writeFile', + ]; + if (fs) { + TO_PATCH_MACROTASK_METHODS.filter(function (name) { return !!fs[name] && typeof fs[name] === 'function'; }) + .forEach(function (name) { + patchMacroTask(fs, name, function (self, args) { + return { + name: 'fs.' + name, + args: args, + callbackIndex: args.length > 0 ? args.length - 1 : -1, + target: self + }; + }); }); - }); -} + } +}); /** * @license @@ -1654,14 +1559,17 @@ function patchTimer(window, setName, cancelName, nameSuffix) { */ var set = 'set'; var clear = 'clear'; -Zone.__load_patch('timers', function (global, Zone, api) { +Zone.__load_patch('node_timers', function (global, Zone, api) { // Timers var globalUseTimeoutFromTimer = false; try { var timers = require('timers'); var globalEqualTimersTimeout = global.setTimeout === timers.setTimeout; - if (!globalEqualTimersTimeout) { - // if global.setTimeout not equal timers.setTimeout, check + if (!globalEqualTimersTimeout && !isMix) { + // 1. if isMix, then we are in mix environment such as Electron + // we should only patch timers.setTimeout because global.setTimeout + // have been patched + // 2. if global.setTimeout not equal timers.setTimeout, check // whether global.setTimeout use timers.setTimeout or not var originSetTimeout_1 = timers.setTimeout; timers.setTimeout = function () { @@ -1680,6 +1588,12 @@ Zone.__load_patch('timers', function (global, Zone, api) { // timers module not exists, for example, when we using nativescript // timers is not available } + if (isMix) { + // if we are in mix environment, such as Electron, + // the global.setTimeout has already been patched, + // so we just patch timers.setTimeout + return; + } if (!globalUseTimeoutFromTimer) { // 1. global setTimeout equals timers setTimeout // 2. or global don't use timers setTimeout(maybe some other library patch setTimeout) @@ -1759,4 +1673,12 @@ Zone.__load_patch('crypto', function (global, Zone, api) { } }); +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + }))); diff --git a/dist/zone.js b/dist/zone.js index b1fee5d56..91cc928f6 100644 --- a/dist/zone.js +++ b/dist/zone.js @@ -164,9 +164,19 @@ var Zone$1 = (function (global) { } }; Zone.prototype.runTask = function (task, applyThis, applyArgs) { - if (task.zone != this) + if (task.zone != this) { throw new Error('A task can only be run in the zone of creation! (Creation: ' + (task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')'); + } + // https://github.com/angular/zone.js/issues/778, sometimes eventTask + // will run in notScheduled(canceled) state, we should not try to + // run such kind of task but just return + // we have to define an variable here, if not + // typescript compiler will complain below + var isNotScheduled = task.state === notScheduled; + if (isNotScheduled && task.type === eventTask) { + return; + } var reEntryGuard = task.state != running; reEntryGuard && task._transitionTo(running, scheduled); task.runCount++; @@ -598,7 +608,9 @@ var Zone$1 = (function (global) { onUnhandledError: noop, microtaskDrainDone: noop, scheduleMicroTask: scheduleMicroTask, - showUncaughtError: function () { return !Zone[__symbol__('ignoreConsoleErrorUncaughtError')]; } + showUncaughtError: function () { return !Zone[__symbol__('ignoreConsoleErrorUncaughtError')]; }, + patchEventTargetMethods: function () { return false; }, + patchOnProperties: noop }; var _currentZoneFrame = { parent: null, zone: new Zone(null, null) }; var _currentTask = null; @@ -988,18 +1000,29 @@ function patchPrototype(prototype, fnNames) { } } var isWebWorker = (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope); -var isNode = (!('nw' in _global) && typeof process !== 'undefined' && - {}.toString.call(process) === '[object process]'); +// Make sure to access `process` through `_global` so that WebPack does not accidently browserify +// this code. +var isNode = (!('nw' in _global) && typeof _global.process !== 'undefined' && + {}.toString.call(_global.process) === '[object process]'); var isBrowser = !isNode && !isWebWorker && !!(typeof window !== 'undefined' && window['HTMLElement']); // we are in electron of nw, so we are both browser and nodejs -var isMix = typeof process !== 'undefined' && - {}.toString.call(process) === '[object process]' && !isWebWorker && +// Make sure to access `process` through `_global` so that WebPack does not accidently browserify +// this code. +var isMix = typeof _global.process !== 'undefined' && + {}.toString.call(_global.process) === '[object process]' && !isWebWorker && !!(typeof window !== 'undefined' && window['HTMLElement']); -function patchProperty(obj, prop) { - var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true }; - // if the descriptor is not configurable +function patchProperty(obj, prop, prototype) { + var desc = Object.getOwnPropertyDescriptor(obj, prop); + if (!desc && prototype) { + // when patch window object, use prototype to check prop exist or not + var prototypeDesc = Object.getOwnPropertyDescriptor(prototype, prop); + if (prototypeDesc) { + desc = { enumerable: true, configurable: true }; + } + } + // if the descriptor not exists or is not configurable // just return - if (!desc.configurable) { + if (!desc || !desc.configurable) { return; } // A property descriptor cannot have getter/setter and be writable @@ -1077,10 +1100,10 @@ function patchProperty(obj, prop) { }; Object.defineProperty(obj, prop, desc); } -function patchOnProperties(obj, properties) { +function patchOnProperties(obj, properties, prototype) { if (properties) { for (var i = 0; i < properties.length; i++) { - patchProperty(obj, 'on' + properties[i]); + patchProperty(obj, 'on' + properties[i], prototype); } } else { @@ -1091,7 +1114,7 @@ function patchOnProperties(obj, properties) { } } for (var j = 0; j < onProperties.length; j++) { - patchProperty(obj, onProperties[j]); + patchProperty(obj, onProperties[j], prototype); } } } @@ -1426,8 +1449,6 @@ function findEventTask(target, evtName) { function attachOriginToPatched(patched, original) { patched[zoneSymbol('OriginalDelegate')] = original; } -Zone[zoneSymbol('patchEventTargetMethods')] = patchEventTargetMethods; -Zone[zoneSymbol('patchOnProperties')] = patchOnProperties; /** * @license @@ -1741,8 +1762,215 @@ function apply(_global) { * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -var eventNames = 'copy cut paste abort blur focus canplay canplaythrough change click contextmenu dblclick drag dragend dragenter dragleave dragover dragstart drop durationchange emptied ended input invalid keydown keypress keyup load loadeddata loadedmetadata loadstart message mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup pause play playing progress ratechange reset scroll seeked seeking select show stalled submit suspend timeupdate volumechange waiting mozfullscreenchange mozfullscreenerror mozpointerlockchange mozpointerlockerror error webglcontextrestored webglcontextlost webglcontextcreationerror' - .split(' '); +var globalEventHandlersEventNames = [ + 'abort', + 'animationcancel', + 'animationend', + 'animationiteration', + 'auxclick', + 'beforeinput', + 'blur', + 'cancel', + 'canplay', + 'canplaythrough', + 'change', + 'compositionstart', + 'compositionupdate', + 'compositionend', + 'cuechange', + 'click', + 'close', + 'contextmenu', + 'curechange', + 'dblclick', + 'drag', + 'dragend', + 'dragenter', + 'dragexit', + 'dragleave', + 'dragover', + 'drop', + 'durationchange', + 'emptied', + 'ended', + 'error', + 'focus', + 'focusin', + 'focusout', + 'gotpointercapture', + 'input', + 'invalid', + 'keydown', + 'keypress', + 'keyup', + 'load', + 'loadstart', + 'loadeddata', + 'loadedmetadata', + 'lostpointercapture', + 'mousedown', + 'mouseenter', + 'mouseleave', + 'mousemove', + 'mouseout', + 'mouseover', + 'mouseup', + 'mousewheel', + 'pause', + 'play', + 'playing', + 'pointercancel', + 'pointerdown', + 'pointerenter', + 'pointerleave', + 'pointerlockchange', + 'mozpointerlockchange', + 'webkitpointerlockerchange', + 'pointerlockerror', + 'mozpointerlockerror', + 'webkitpointerlockerror', + 'pointermove', + 'pointout', + 'pointerover', + 'pointerup', + 'progress', + 'ratechange', + 'reset', + 'resize', + 'scroll', + 'seeked', + 'seeking', + 'select', + 'selectionchange', + 'selectstart', + 'show', + 'sort', + 'stalled', + 'submit', + 'suspend', + 'timeupdate', + 'volumechange', + 'touchcancel', + 'touchmove', + 'touchstart', + 'transitioncancel', + 'transitionend', + 'waiting', + 'wheel' +]; +var documentEventNames = [ + 'afterscriptexecute', 'beforescriptexecute', 'DOMContentLoaded', 'fullscreenchange', + 'mozfullscreenchange', 'webkitfullscreenchange', 'msfullscreenchange', 'fullscreenerror', + 'mozfullscreenerror', 'webkitfullscreenerror', 'msfullscreenerror', 'readystatechange' +]; +var windowEventNames = [ + 'absolutedeviceorientation', + 'afterinput', + 'afterprint', + 'appinstalled', + 'beforeinstallprompt', + 'beforeprint', + 'beforeunload', + 'devicelight', + 'devicemotion', + 'deviceorientation', + 'deviceorientationabsolute', + 'deviceproximity', + 'hashchange', + 'languagechange', + 'message', + 'mozbeforepaint', + 'offline', + 'online', + 'paint', + 'pageshow', + 'pagehide', + 'popstate', + 'rejectionhandled', + 'storage', + 'unhandledrejection', + 'unload', + 'userproximity', + 'vrdisplyconnected', + 'vrdisplaydisconnected', + 'vrdisplaypresentchange' +]; +var htmlElementEventNames = [ + 'beforecopy', 'beforecut', 'beforepaste', 'copy', 'cut', 'paste', 'dragstart', 'loadend', + 'animationstart', 'search', 'transitionrun', 'transitionstart', 'webkitanimationend', + 'webkitanimationiteration', 'webkitanimationstart', 'webkittransitionend' +]; +var mediaElementEventNames = ['encrypted', 'waitingforkey', 'msneedkey', 'mozinterruptbegin', 'mozinterruptend']; +var ieElementEventNames = [ + 'activate', + 'afterupdate', + 'ariarequest', + 'beforeactivate', + 'beforedeactivate', + 'beforeeditfocus', + 'beforeupdate', + 'cellchange', + 'controlselect', + 'dataavailable', + 'datasetchanged', + 'datasetcomplete', + 'errorupdate', + 'filterchange', + 'layoutcomplete', + 'losecapture', + 'move', + 'moveend', + 'movestart', + 'propertychange', + 'resizeend', + 'resizestart', + 'rowenter', + 'rowexit', + 'rowsdelete', + 'rowsinserted', + 'command', + 'compassneedscalibration', + 'deactivate', + 'help', + 'mscontentzoom', + 'msmanipulationstatechanged', + 'msgesturechange', + 'msgesturedoubletap', + 'msgestureend', + 'msgesturehold', + 'msgesturestart', + 'msgesturetap', + 'msgotpointercapture', + 'msinertiastart', + 'mslostpointercapture', + 'mspointercancel', + 'mspointerdown', + 'mspointerenter', + 'mspointerhover', + 'mspointerleave', + 'mspointermove', + 'mspointerout', + 'mspointerover', + 'mspointerup', + 'pointerout', + 'mssitemodejumplistitemremoved', + 'msthumbnailclick', + 'stop', + 'storagecommit' +]; +var webglEventNames = ['webglcontextrestored', 'webglcontextlost', 'webglcontextcreationerror']; +var formEventNames = ['autocomplete', 'autocompleteerror']; +var detailEventNames = ['toggle']; +var frameEventNames = ['load']; +var frameSetEventNames = ['blur', 'error', 'focus', 'load', 'resize', 'scroll']; +var marqueeEventNames = ['bounce', 'finish', 'start']; +var XMLHttpRequestEventNames = [ + 'loadstart', 'progress', 'abort', 'error', 'load', 'progress', 'timeout', 'loadend', + 'readystatechange' +]; +var IDBIndexEventNames = ['upgradeneeded', 'complete', 'abort', 'success', 'error', 'blocked', 'versionchange', 'close']; +var websocketEventNames = ['close', 'error', 'open', 'message']; +var eventNames = globalEventHandlersEventNames.concat(webglEventNames, formEventNames, detailEventNames, documentEventNames, windowEventNames, htmlElementEventNames, ieElementEventNames); function propertyDescriptorPatch(_global) { if (isNode && !isMix) { return; @@ -1751,24 +1979,40 @@ function propertyDescriptorPatch(_global) { if (canPatchViaPropertyDescriptor()) { // for browsers that we can patch the descriptor: Chrome & Firefox if (isBrowser) { - patchOnProperties(window, eventNames.concat(['resize'])); + // in IE/Edge, onProp not exist in window object, but in WindowPrototype + // so we need to pass WindowPrototype to check onProp exist or not + patchOnProperties(window, eventNames, Object.getPrototypeOf(window)); patchOnProperties(Document.prototype, eventNames); if (typeof window['SVGElement'] !== 'undefined') { patchOnProperties(window['SVGElement'].prototype, eventNames); } + patchOnProperties(Element.prototype, eventNames); patchOnProperties(HTMLElement.prototype, eventNames); + patchOnProperties(HTMLMediaElement.prototype, mediaElementEventNames); + patchOnProperties(HTMLFrameSetElement.prototype, windowEventNames.concat(frameSetEventNames)); + patchOnProperties(HTMLBodyElement.prototype, windowEventNames.concat(frameSetEventNames)); + patchOnProperties(HTMLFrameElement.prototype, frameEventNames); + patchOnProperties(HTMLIFrameElement.prototype, frameEventNames); + var HTMLMarqueeElement_1 = window['HTMLMarqueeElement']; + if (HTMLMarqueeElement_1) { + patchOnProperties(HTMLMarqueeElement_1.prototype, marqueeEventNames); + } + } + patchOnProperties(XMLHttpRequest.prototype, XMLHttpRequestEventNames); + var XMLHttpRequestEventTarget = _global['XMLHttpRequestEventTarget']; + if (XMLHttpRequestEventTarget) { + patchOnProperties(XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype, XMLHttpRequestEventNames); } - patchOnProperties(XMLHttpRequest.prototype, null); if (typeof IDBIndex !== 'undefined') { - patchOnProperties(IDBIndex.prototype, null); - patchOnProperties(IDBRequest.prototype, null); - patchOnProperties(IDBOpenDBRequest.prototype, null); - patchOnProperties(IDBDatabase.prototype, null); - patchOnProperties(IDBTransaction.prototype, null); - patchOnProperties(IDBCursor.prototype, null); + patchOnProperties(IDBIndex.prototype, IDBIndexEventNames); + patchOnProperties(IDBRequest.prototype, IDBIndexEventNames); + patchOnProperties(IDBOpenDBRequest.prototype, IDBIndexEventNames); + patchOnProperties(IDBDatabase.prototype, IDBIndexEventNames); + patchOnProperties(IDBTransaction.prototype, IDBIndexEventNames); + patchOnProperties(IDBCursor.prototype, IDBIndexEventNames); } if (supportsWebSocket) { - patchOnProperties(WebSocket.prototype, null); + patchOnProperties(WebSocket.prototype, websocketEventNames); } } else { @@ -2051,6 +2295,10 @@ Zone.__load_patch('PromiseRejectionEvent', function (global, Zone, api) { findPromiseRejectionHandler('rejectionhandled'); } }); +Zone.__load_patch('util', function (global, Zone, api) { + api.patchEventTargetMethods = patchEventTargetMethods; + api.patchOnProperties = patchOnProperties; +}); /** * @license diff --git a/dist/zone.min.js b/dist/zone.min.js index 703fe6405..52f5e47f4 100644 --- a/dist/zone.min.js +++ b/dist/zone.min.js @@ -1 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(this,function(){"use strict";function e(e,t){for(var n=e.length-1;n>=0;n--)"function"==typeof e[n]&&(e[n]=Zone.current.wrap(e[n],t+"_"+n));return e}function t(t,n){for(var r=t.constructor.name,o=function(o){var a=n[o],i=t[a];i&&(t[a]=function(t){var n=function(){return t.apply(this,e(arguments,r+"."+a))};return f(n,t),n}(i))},a=0;a1?new t(e,n):new t(e),i=Object.getOwnPropertyDescriptor(a,"onmessage");return i&&i.configurable===!1?(o=Object.create(a),["addEventListener","removeEventListener","send","close"].forEach(function(e){o[e]=function(){return a[e].apply(a,arguments)}})):o=a,r(o,["close","error","message","open"]),o};for(var n in t)e.WebSocket[n]=t[n]}function b(e){if(!P||j){var t="undefined"!=typeof WebSocket;w()?(O&&(r(window,N.concat(["resize"])),r(Document.prototype,N),"undefined"!=typeof window.SVGElement&&r(window.SVGElement.prototype,N),r(HTMLElement.prototype,N)),r(XMLHttpRequest.prototype,null),"undefined"!=typeof IDBIndex&&(r(IDBIndex.prototype,null),r(IDBRequest.prototype,null),r(IDBOpenDBRequest.prototype,null),r(IDBDatabase.prototype,null),r(IDBTransaction.prototype,null),r(IDBCursor.prototype,null)),t&&r(WebSocket.prototype,null)):(E(),l("XMLHttpRequest"),t&&T(e))}}function w(){if((O||j)&&!Object.getOwnPropertyDescriptor(HTMLElement.prototype,"onclick")&&"undefined"!=typeof Element){var e=Object.getOwnPropertyDescriptor(Element.prototype,"onclick");if(e&&!e.configurable)return!1}var t=Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype,"onreadystatechange");if(t){Object.defineProperty(XMLHttpRequest.prototype,"onreadystatechange",{enumerable:!0,configurable:!0,get:function(){return!0}});var n=new XMLHttpRequest,r=!!n.onreadystatechange;return Object.defineProperty(XMLHttpRequest.prototype,"onreadystatechange",t||{}),r}Object.defineProperty(XMLHttpRequest.prototype,"onreadystatechange",{enumerable:!0,configurable:!0,get:function(){return this[D("fakeonreadystatechange")]},set:function(e){this[D("fakeonreadystatechange")]=e}});var n=new XMLHttpRequest,o=function(){};n.onreadystatechange=o;var r=n[D("fakeonreadystatechange")]===o;return n.onreadystatechange=null,r}function E(){for(var e=function(e){var t=N[e],n="on"+t;self.addEventListener(t,function(e){var t,r,o=e.target;for(r=o?o.constructor.name+"."+n:"unknown."+n;o;)o[n]&&!o[n][W]&&(t=Zone.current.wrap(o[n],r),t[W]=o[n],o[n]=t),o=o.parentElement},!0)},t=0;t",this._properties=t&&t.properties||{},this._zoneDelegate=new l(this,this._parent&&this._parent._zoneDelegate,t)}return r.assertZonePatched=function(){if(e.Promise!==S.ZoneAwarePromise)throw new Error("Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.\nMost likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)")},Object.defineProperty(r,"root",{get:function(){for(var e=r.current;e.parent;)e=e.parent;return e},enumerable:!0,configurable:!0}),Object.defineProperty(r,"current",{get:function(){return P.zone},enumerable:!0,configurable:!0}),Object.defineProperty(r,"currentTask",{get:function(){return O},enumerable:!0,configurable:!0}),r.__load_patch=function(o,a){if(S.hasOwnProperty(o))throw Error("Already loaded patch: "+o);if(!e["__Zone_disable_"+o]){var i="Zone:"+o;t(i),S[o]=a(e,r,z),n(i,i)}},Object.defineProperty(r.prototype,"parent",{get:function(){return this._parent},enumerable:!0,configurable:!0}),Object.defineProperty(r.prototype,"name",{get:function(){return this._name},enumerable:!0,configurable:!0}),r.prototype.get=function(e){var t=this.getZoneWith(e);if(t)return t._properties[e]},r.prototype.getZoneWith=function(e){for(var t=this;t;){if(t._properties.hasOwnProperty(e))return t;t=t._parent}return null},r.prototype.fork=function(e){if(!e)throw new Error("ZoneSpec required!");return this._zoneDelegate.fork(this,e)},r.prototype.wrap=function(e,t){if("function"!=typeof e)throw new Error("Expecting function got: "+e);var n=this._zoneDelegate.intercept(this,e,t),r=this;return function(){return r.runGuarded(n,this,arguments,t)}},r.prototype.run=function(e,t,n,r){void 0===t&&(t=void 0),void 0===n&&(n=null),void 0===r&&(r=null),P={parent:P,zone:this};try{return this._zoneDelegate.invoke(this,e,t,n,r)}finally{P=P.parent}},r.prototype.runGuarded=function(e,t,n,r){void 0===t&&(t=null),void 0===n&&(n=null),void 0===r&&(r=null),P={parent:P,zone:this};try{try{return this._zoneDelegate.invoke(this,e,t,n,r)}catch(o){if(this._zoneDelegate.handleError(this,o))throw o}}finally{P=P.parent}},r.prototype.runTask=function(e,t,n){if(e.zone!=this)throw new Error("A task can only be run in the zone of creation! (Creation: "+(e.zone||k).name+"; Execution: "+this.name+")");var r=e.state!=T;r&&e._transitionTo(T,m),e.runCount++;var o=O;O=e,P={parent:P,zone:this};try{e.type==Z&&e.data&&!e.data.isPeriodic&&(e.cancelFn=null);try{return this._zoneDelegate.invokeTask(this,e,t,n)}catch(a){if(this._zoneDelegate.handleError(this,a))throw a}}finally{e.state!==g&&e.state!==w&&(e.type==D||e.data&&e.data.isPeriodic?r&&e._transitionTo(m,T):(e.runCount=0,this._updateTaskCount(e,-1),r&&e._transitionTo(g,T,g))),P=P.parent,O=o}},r.prototype.scheduleTask=function(e){if(e.zone&&e.zone!==this)for(var t=this;t;){if(t===e.zone)throw Error("can not reschedule task to "+this.name+" which is descendants of the original zone "+e.zone.name);t=t.parent}e._transitionTo(_,g);var n=[];e._zoneDelegates=n,e._zone=this;try{e=this._zoneDelegate.scheduleTask(this,e)}catch(r){throw e._transitionTo(w,_,g),this._zoneDelegate.handleError(this,r),r}return e._zoneDelegates===n&&this._updateTaskCount(e,1),e.state==_&&e._transitionTo(m,_),e},r.prototype.scheduleMicroTask=function(e,t,n,r){return this.scheduleTask(new h(E,e,t,n,r,null))},r.prototype.scheduleMacroTask=function(e,t,n,r,o){return this.scheduleTask(new h(Z,e,t,n,r,o))},r.prototype.scheduleEventTask=function(e,t,n,r,o){return this.scheduleTask(new h(D,e,t,n,r,o))},r.prototype.cancelTask=function(e){if(e.zone!=this)throw new Error("A task can only be cancelled in the zone of creation! (Creation: "+(e.zone||k).name+"; Execution: "+this.name+")");e._transitionTo(b,m,T);try{this._zoneDelegate.cancelTask(this,e)}catch(t){throw e._transitionTo(w,b),this._zoneDelegate.handleError(this,t),t}return this._updateTaskCount(e,-1),e._transitionTo(g,b),e.runCount=0,e},r.prototype._updateTaskCount=function(e,t){var n=e._zoneDelegates;t==-1&&(e._zoneDelegates=null);for(var r=0;r0,macroTask:n.macroTask>0,eventTask:n.eventTask>0,change:e};this.hasTask(this.zone,a)}},e}(),h=function(){function e(e,t,n,r,a,i){this._zone=null,this.runCount=0,this._zoneDelegates=null,this._state="notScheduled",this.type=e,this.source=t,this.data=r,this.scheduleFn=a,this.cancelFn=i,this.callback=n;var s=this;this.invoke=function(){j++;try{return s.runCount++,s.zone.runTask(s,this,arguments)}finally{1==j&&o(),j--}}}return Object.defineProperty(e.prototype,"zone",{get:function(){return this._zone},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"state",{get:function(){return this._state},enumerable:!0,configurable:!0}),e.prototype.cancelScheduleRequest=function(){this._transitionTo(g,_)},e.prototype._transitionTo=function(e,t,n){if(this._state!==t&&this._state!==n)throw new Error(this.type+" '"+this.source+"': can not transition to '"+e+"', expecting state '"+t+"'"+(n?" or '"+n+"'":"")+", was '"+this._state+"'.");this._state=e,e==g&&(this._zoneDelegates=null)},e.prototype.toString=function(){return this.data&&"undefined"!=typeof this.data.handleId?this.data.handleId:Object.prototype.toString.call(this)},e.prototype.toJSON=function(){return{type:this.type,state:this.state,source:this.source,zone:this.zone.name,invoke:this.invoke,scheduleFn:this.scheduleFn,cancelFn:this.cancelFn,runCount:this.runCount,callback:this.callback}},e}(),p=i("setTimeout"),f=i("Promise"),d=i("then"),v=[],y=!1,k={name:"NO ZONE"},g="notScheduled",_="scheduling",m="scheduled",T="running",b="canceling",w="unknown",E="microTask",Z="macroTask",D="eventTask",S={},z={symbol:i,currentZoneFrame:function(){return P},onUnhandledError:a,microtaskDrainDone:a,scheduleMicroTask:r,showUncaughtError:function(){return!c[i("ignoreConsoleErrorUncaughtError")]}},P={parent:null,zone:new c(null,null)},O=null,j=0;return n("Zone","Zone"),e.Zone=c})("undefined"!=typeof window&&window||"undefined"!=typeof self&&self||global);Zone.__load_patch("ZoneAwarePromise",function(e,t,n){function r(e){n.onUnhandledError(e);try{var r=t[f("unhandledPromiseRejectionHandler")];r&&"function"==typeof r&&r.apply(this,[e])}catch(o){}}function o(e){return e&&e.then}function a(e){return e}function i(e){return Z.reject(e)}function s(e,t){return function(n){try{c(e,t,n)}catch(r){c(e,!1,r)}}}function c(e,r,o){var a=E();if(e===o)throw new TypeError("Promise resolved with itself");if(e[k]===m){var i=null;try{"object"!=typeof o&&"function"!=typeof o||(i=o&&o.then)}catch(h){return a(function(){c(e,!1,h)})(),e}if(r!==b&&o instanceof Z&&o.hasOwnProperty(k)&&o.hasOwnProperty(g)&&o[k]!==m)u(o),c(e,o[k],o[g]);else if(r!==b&&"function"==typeof i)try{i.apply(o,[a(s(e,r)),a(s(e,!1))])}catch(h){a(function(){c(e,!1,h)})()}else{e[k]=r;var p=e[g];e[g]=o,r===b&&o instanceof Error&&(o[f("currentTask")]=t.currentTask);for(var v=0;v=0;n--)"function"==typeof e[n]&&(e[n]=Zone.current.wrap(e[n],t+"_"+n));return e}function t(t,n){for(var r=t.constructor.name,o=function(o){var a=n[o],i=t[a];i&&(t[a]=function(t){var n=function(){return t.apply(this,e(arguments,r+"."+a))};return f(n,t),n}(i))},a=0;a1?new t(e,n):new t(e),i=Object.getOwnPropertyDescriptor(a,"onmessage");return i&&i.configurable===!1?(o=Object.create(a),["addEventListener","removeEventListener","send","close"].forEach(function(e){o[e]=function(){return a[e].apply(a,arguments)}})):o=a,r(o,["close","error","message","open"]),o};for(var n in t)e.WebSocket[n]=t[n]}function T(e){if(!O||j){var t="undefined"!=typeof WebSocket;if(w()){if(P){r(window,ae,Object.getPrototypeOf(window)),r(Document.prototype,ae),"undefined"!=typeof window.SVGElement&&r(window.SVGElement.prototype,ae),r(Element.prototype,ae),r(HTMLElement.prototype,ae),r(HTMLMediaElement.prototype,V),r(HTMLFrameSetElement.prototype,U.concat(ee)),r(HTMLBodyElement.prototype,U.concat(ee)),r(HTMLFrameElement.prototype,$),r(HTMLIFrameElement.prototype,$);var n=window.HTMLMarqueeElement;n&&r(n.prototype,te)}r(XMLHttpRequest.prototype,ne);var o=e.XMLHttpRequestEventTarget;o&&r(o&&o.prototype,ne),"undefined"!=typeof IDBIndex&&(r(IDBIndex.prototype,re),r(IDBRequest.prototype,re),r(IDBOpenDBRequest.prototype,re),r(IDBDatabase.prototype,re),r(IDBTransaction.prototype,re),r(IDBCursor.prototype,re)),t&&r(WebSocket.prototype,oe)}else E(),l("XMLHttpRequest"),t&&b(e)}}function w(){if((P||j)&&!Object.getOwnPropertyDescriptor(HTMLElement.prototype,"onclick")&&"undefined"!=typeof Element){var e=Object.getOwnPropertyDescriptor(Element.prototype,"onclick");if(e&&!e.configurable)return!1}var t=Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype,"onreadystatechange");if(t){Object.defineProperty(XMLHttpRequest.prototype,"onreadystatechange",{enumerable:!0,configurable:!0,get:function(){return!0}});var n=new XMLHttpRequest,r=!!n.onreadystatechange;return Object.defineProperty(XMLHttpRequest.prototype,"onreadystatechange",t||{}),r}Object.defineProperty(XMLHttpRequest.prototype,"onreadystatechange",{enumerable:!0,configurable:!0,get:function(){return this[Z("fakeonreadystatechange")]},set:function(e){this[Z("fakeonreadystatechange")]=e}});var n=new XMLHttpRequest,o=function(){};n.onreadystatechange=o;var r=n[Z("fakeonreadystatechange")]===o;return n.onreadystatechange=null,r}function E(){for(var e=function(e){var t=ae[e],n="on"+t;self.addEventListener(t,function(e){var t,r,o=e.target;for(r=o?o.constructor.name+"."+n:"unknown."+n;o;)o[n]&&!o[n][ie]&&(t=Zone.current.wrap(o[n],r),t[ie]=o[n],o[n]=t),o=o.parentElement},!0)},t=0;t",this._properties=t&&t.properties||{},this._zoneDelegate=new l(this,this._parent&&this._parent._zoneDelegate,t)}return r.assertZonePatched=function(){if(e.Promise!==z.ZoneAwarePromise)throw new Error("Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.\nMost likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)")},Object.defineProperty(r,"root",{get:function(){for(var e=r.current;e.parent;)e=e.parent;return e},enumerable:!0,configurable:!0}),Object.defineProperty(r,"current",{get:function(){return O.zone},enumerable:!0,configurable:!0}),Object.defineProperty(r,"currentTask",{get:function(){return P},enumerable:!0,configurable:!0}),r.__load_patch=function(o,a){if(z.hasOwnProperty(o))throw Error("Already loaded patch: "+o);if(!e["__Zone_disable_"+o]){var i="Zone:"+o;t(i),z[o]=a(e,r,S),n(i,i)}},Object.defineProperty(r.prototype,"parent",{get:function(){return this._parent},enumerable:!0,configurable:!0}),Object.defineProperty(r.prototype,"name",{get:function(){return this._name},enumerable:!0,configurable:!0}),r.prototype.get=function(e){var t=this.getZoneWith(e);if(t)return t._properties[e]},r.prototype.getZoneWith=function(e){for(var t=this;t;){if(t._properties.hasOwnProperty(e))return t;t=t._parent}return null},r.prototype.fork=function(e){if(!e)throw new Error("ZoneSpec required!");return this._zoneDelegate.fork(this,e)},r.prototype.wrap=function(e,t){if("function"!=typeof e)throw new Error("Expecting function got: "+e);var n=this._zoneDelegate.intercept(this,e,t),r=this;return function(){return r.runGuarded(n,this,arguments,t)}},r.prototype.run=function(e,t,n,r){void 0===t&&(t=void 0),void 0===n&&(n=null),void 0===r&&(r=null),O={parent:O,zone:this};try{return this._zoneDelegate.invoke(this,e,t,n,r)}finally{O=O.parent}},r.prototype.runGuarded=function(e,t,n,r){void 0===t&&(t=null),void 0===n&&(n=null),void 0===r&&(r=null),O={parent:O,zone:this};try{try{return this._zoneDelegate.invoke(this,e,t,n,r)}catch(o){if(this._zoneDelegate.handleError(this,o))throw o}}finally{O=O.parent}},r.prototype.runTask=function(e,t,n){if(e.zone!=this)throw new Error("A task can only be run in the zone of creation! (Creation: "+(e.zone||y).name+"; Execution: "+this.name+")");var r=e.state===k;if(!r||e.type!==Z){var o=e.state!=b;o&&e._transitionTo(b,_),e.runCount++;var a=P;P=e,O={parent:O,zone:this};try{e.type==D&&e.data&&!e.data.isPeriodic&&(e.cancelFn=null);try{return this._zoneDelegate.invokeTask(this,e,t,n)}catch(i){if(this._zoneDelegate.handleError(this,i))throw i}}finally{e.state!==k&&e.state!==w&&(e.type==Z||e.data&&e.data.isPeriodic?o&&e._transitionTo(_,b):(e.runCount=0,this._updateTaskCount(e,-1),o&&e._transitionTo(k,b,k))),O=O.parent,P=a}}},r.prototype.scheduleTask=function(e){if(e.zone&&e.zone!==this)for(var t=this;t;){if(t===e.zone)throw Error("can not reschedule task to "+this.name+" which is descendants of the original zone "+e.zone.name);t=t.parent}e._transitionTo(m,k);var n=[];e._zoneDelegates=n,e._zone=this;try{e=this._zoneDelegate.scheduleTask(this,e)}catch(r){throw e._transitionTo(w,m,k),this._zoneDelegate.handleError(this,r),r}return e._zoneDelegates===n&&this._updateTaskCount(e,1),e.state==m&&e._transitionTo(_,m),e},r.prototype.scheduleMicroTask=function(e,t,n,r){return this.scheduleTask(new p(E,e,t,n,r,null))},r.prototype.scheduleMacroTask=function(e,t,n,r,o){return this.scheduleTask(new p(D,e,t,n,r,o))},r.prototype.scheduleEventTask=function(e,t,n,r,o){return this.scheduleTask(new p(Z,e,t,n,r,o))},r.prototype.cancelTask=function(e){if(e.zone!=this)throw new Error("A task can only be cancelled in the zone of creation! (Creation: "+(e.zone||y).name+"; Execution: "+this.name+")");e._transitionTo(T,_,b);try{this._zoneDelegate.cancelTask(this,e)}catch(t){throw e._transitionTo(w,T),this._zoneDelegate.handleError(this,t),t}return this._updateTaskCount(e,-1),e._transitionTo(k,T),e.runCount=0,e},r.prototype._updateTaskCount=function(e,t){var n=e._zoneDelegates;t==-1&&(e._zoneDelegates=null);for(var r=0;r0,macroTask:n.macroTask>0,eventTask:n.eventTask>0,change:e};this.hasTask(this.zone,a)}},e}(),p=function(){function e(e,t,n,r,a,i){this._zone=null,this.runCount=0,this._zoneDelegates=null,this._state="notScheduled",this.type=e,this.source=t,this.data=r,this.scheduleFn=a,this.cancelFn=i,this.callback=n;var s=this;this.invoke=function(){j++;try{return s.runCount++,s.zone.runTask(s,this,arguments)}finally{1==j&&o(),j--}}}return Object.defineProperty(e.prototype,"zone",{get:function(){return this._zone},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"state",{get:function(){return this._state},enumerable:!0,configurable:!0}),e.prototype.cancelScheduleRequest=function(){this._transitionTo(k,m)},e.prototype._transitionTo=function(e,t,n){if(this._state!==t&&this._state!==n)throw new Error(this.type+" '"+this.source+"': can not transition to '"+e+"', expecting state '"+t+"'"+(n?" or '"+n+"'":"")+", was '"+this._state+"'.");this._state=e,e==k&&(this._zoneDelegates=null)},e.prototype.toString=function(){return this.data&&"undefined"!=typeof this.data.handleId?this.data.handleId:Object.prototype.toString.call(this)},e.prototype.toJSON=function(){return{type:this.type,state:this.state,source:this.source,zone:this.zone.name,invoke:this.invoke,scheduleFn:this.scheduleFn,cancelFn:this.cancelFn,runCount:this.runCount,callback:this.callback}},e}(),h=i("setTimeout"),f=i("Promise"),d=i("then"),v=[],g=!1,y={name:"NO ZONE"},k="notScheduled",m="scheduling",_="scheduled",b="running",T="canceling",w="unknown",E="microTask",D="macroTask",Z="eventTask",z={},S={symbol:i,currentZoneFrame:function(){return O},onUnhandledError:a,microtaskDrainDone:a,scheduleMicroTask:r,showUncaughtError:function(){return!c[i("ignoreConsoleErrorUncaughtError")]},patchEventTargetMethods:function(){return!1},patchOnProperties:a},O={parent:null,zone:new c(null,null)},P=null,j=0;return n("Zone","Zone"),e.Zone=c})("undefined"!=typeof window&&window||"undefined"!=typeof self&&self||global);Zone.__load_patch("ZoneAwarePromise",function(e,t,n){function r(e){n.onUnhandledError(e);try{var r=t[f("unhandledPromiseRejectionHandler")];r&&"function"==typeof r&&r.apply(this,[e])}catch(o){}}function o(e){return e&&e.then}function a(e){return e}function i(e){return D.reject(e)}function s(e,t){return function(n){try{c(e,t,n)}catch(r){c(e,!1,r)}}}function c(e,r,o){var a=E();if(e===o)throw new TypeError("Promise resolved with itself");if(e[y]===_){var i=null;try{"object"!=typeof o&&"function"!=typeof o||(i=o&&o.then)}catch(p){return a(function(){c(e,!1,p)})(),e}if(r!==T&&o instanceof D&&o.hasOwnProperty(y)&&o.hasOwnProperty(k)&&o[y]!==_)u(o),c(e,o[y],o[k]);else if(r!==T&&"function"==typeof i)try{i.apply(o,[a(s(e,r)),a(s(e,!1))])}catch(p){a(function(){c(e,!1,p)})()}else{e[y]=r;var h=e[k];e[k]=o,r===T&&o instanceof Error&&(o[f("currentTask")]=t.currentTask);for(var v=0;v