angular/zone/zone-microtask.js

1925 lines
58 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(function (global){
'use strict';
var core = require('../core');
var microtask = require('../microtask');
var browserPatch = require('../patch/browser');
var es6Promise = require('../ext/es6-promise.js');
if (global.Zone) {
console.warn('Zone already exported on window the object!');
}
global.Zone = microtask.addMicrotaskSupport(core.Zone);
global.zone = new global.Zone();
// Monkey path ẗhe Promise implementation to add support for microtasks
global.Promise = es6Promise.Promise;
browserPatch.apply();
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"../core":2,"../ext/es6-promise.js":3,"../microtask":4,"../patch/browser":5}],2:[function(require,module,exports){
(function (global){
'use strict';
function Zone(parentZone, data) {
var zone = (arguments.length) ? Object.create(parentZone) : this;
zone.parent = parentZone;
Object.keys(data || {}).forEach(function(property) {
var _property = property.substr(1);
// augment the new zone with a hook decorates the parent's hook
if (property[0] === '$') {
zone[_property] = data[property](parentZone[_property] || function () {});
// augment the new zone with a hook that runs after the parent's hook
} else if (property[0] === '+') {
if (parentZone[_property]) {
zone[_property] = function () {
var result = parentZone[_property].apply(this, arguments);
data[property].apply(this, arguments);
return result;
};
} else {
zone[_property] = data[property];
}
// augment the new zone with a hook that runs before the parent's hook
} else if (property[0] === '-') {
if (parentZone[_property]) {
zone[_property] = function () {
data[property].apply(this, arguments);
return parentZone[_property].apply(this, arguments);
};
} else {
zone[_property] = data[property];
}
// set the new zone's hook (replacing the parent zone's)
} else {
zone[property] = (typeof data[property] === 'object') ?
JSON.parse(JSON.stringify(data[property])) :
data[property];
}
});
zone.$id = ++Zone.nextId;
return zone;
}
Zone.prototype = {
constructor: Zone,
fork: function (locals) {
this.onZoneCreated();
return new Zone(this, locals);
},
bind: function (fn, skipEnqueue) {
skipEnqueue || this.enqueueTask(fn);
var zone = this.fork();
return function zoneBoundFn() {
return zone.run(fn, this, arguments);
};
},
bindOnce: function (fn) {
var boundZone = this;
return this.bind(function () {
var result = fn.apply(this, arguments);
boundZone.dequeueTask(fn);
return result;
});
},
run: function run (fn, applyTo, applyWith) {
applyWith = applyWith || [];
var oldZone = global.zone;
global.zone = this;
try {
this.beforeTask();
return fn.apply(applyTo, applyWith);
} catch (e) {
if (this.onError) {
this.onError(e);
} else {
throw e;
}
} finally {
this.afterTask();
global.zone = oldZone;
}
},
// onError is used to override error handling.
// When a custom error handler is provided, it should most probably rethrow the exception
// not to break the expected control flow:
//
// `promise.then(fnThatThrows).catch(fn);`
//
// When this code is executed in a zone with a custom onError handler that doesn't rethrow, the
// `.catch()` branch will not be taken as the `fnThatThrows` exception will be swallowed by the
// handler.
onError: null,
beforeTask: function () {},
onZoneCreated: function () {},
afterTask: function () {},
enqueueTask: function () {},
dequeueTask: function () {}
};
Zone.nextId = 1;
Zone.bindPromiseFn = require('./patch/promise').bindPromiseFn;
module.exports = {
Zone: Zone
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./patch/promise":10}],3:[function(require,module,exports){
(function (process,global){
/*!
* @overview es6-promise - a tiny implementation of Promises/A+.
* @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
* @license Licensed under MIT license
* See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE
* @version 2.1.1
*/
(function() {
"use strict";
function lib$es6$promise$utils$$objectOrFunction(x) {
return typeof x === 'function' || (typeof x === 'object' && x !== null);
}
function lib$es6$promise$utils$$isFunction(x) {
return typeof x === 'function';
}
function lib$es6$promise$utils$$isMaybeThenable(x) {
return typeof x === 'object' && x !== null;
}
var lib$es6$promise$utils$$_isArray;
if (!Array.isArray) {
lib$es6$promise$utils$$_isArray = function (x) {
return Object.prototype.toString.call(x) === '[object Array]';
};
} else {
lib$es6$promise$utils$$_isArray = Array.isArray;
}
var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray;
var lib$es6$promise$asap$$len = 0;
var lib$es6$promise$asap$$toString = {}.toString;
var lib$es6$promise$asap$$vertxNext;
function lib$es6$promise$asap$$asap(callback, arg) {
window.zone.scheduleMicrotask(function() {
callback(arg);
});
//queue[len] = callback;
//queue[len + 1] = arg;
//len += 2;
//if (len === 2) {
// // If len is 2, that means that we need to schedule an async flush.
// // If additional callbacks are queued before the queue is flushed, they
// // will be processed by this flush that we are scheduling.
// scheduleFlush();
//}
}
var lib$es6$promise$asap$$default = lib$es6$promise$asap$$asap;
var lib$es6$promise$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined;
var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {};
var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver;
var lib$es6$promise$asap$$isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
// test for web worker but not in IE10
var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' &&
typeof importScripts !== 'undefined' &&
typeof MessageChannel !== 'undefined';
// node
function lib$es6$promise$asap$$useNextTick() {
var nextTick = process.nextTick;
// node version 0.10.x displays a deprecation warning when nextTick is used recursively
// setImmediate should be used instead instead
var version = process.versions.node.match(/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/);
if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {
nextTick = setImmediate;
}
return function() {
nextTick(lib$es6$promise$asap$$flush);
};
}
// vertx
function lib$es6$promise$asap$$useVertxTimer() {
return function() {
lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush);
};
}
function lib$es6$promise$asap$$useMutationObserver() {
var iterations = 0;
var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush);
var node = document.createTextNode('');
observer.observe(node, { characterData: true });
return function() {
node.data = (iterations = ++iterations % 2);
};
}
// web worker
function lib$es6$promise$asap$$useMessageChannel() {
var channel = new MessageChannel();
channel.port1.onmessage = lib$es6$promise$asap$$flush;
return function () {
channel.port2.postMessage(0);
};
}
function lib$es6$promise$asap$$useSetTimeout() {
return function() {
setTimeout(lib$es6$promise$asap$$flush, 1);
};
}
var lib$es6$promise$asap$$queue = new Array(1000);
function lib$es6$promise$asap$$flush() {
for (var i = 0; i < lib$es6$promise$asap$$len; i+=2) {
var callback = lib$es6$promise$asap$$queue[i];
var arg = lib$es6$promise$asap$$queue[i+1];
callback(arg);
lib$es6$promise$asap$$queue[i] = undefined;
lib$es6$promise$asap$$queue[i+1] = undefined;
}
lib$es6$promise$asap$$len = 0;
}
function lib$es6$promise$asap$$attemptVertex() {
try {
var r = require;
var vertx = r('vertx');
lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext;
return lib$es6$promise$asap$$useVertxTimer();
} catch(e) {
return lib$es6$promise$asap$$useSetTimeout();
}
}
var lib$es6$promise$asap$$scheduleFlush;
// Decide what async method to use to triggering processing of queued callbacks:
if (lib$es6$promise$asap$$isNode) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick();
} else if (lib$es6$promise$asap$$BrowserMutationObserver) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver();
} else if (lib$es6$promise$asap$$isWorker) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel();
} else if (lib$es6$promise$asap$$browserWindow === undefined && typeof require === 'function') {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertex();
} else {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout();
}
function lib$es6$promise$$internal$$noop() {}
var lib$es6$promise$$internal$$PENDING = void 0;
var lib$es6$promise$$internal$$FULFILLED = 1;
var lib$es6$promise$$internal$$REJECTED = 2;
var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject();
function lib$es6$promise$$internal$$selfFullfillment() {
return new TypeError("You cannot resolve a promise with itself");
}
function lib$es6$promise$$internal$$cannotReturnOwn() {
return new TypeError('A promises callback cannot return that same promise.');
}
function lib$es6$promise$$internal$$getThen(promise) {
try {
return promise.then;
} catch(error) {
lib$es6$promise$$internal$$GET_THEN_ERROR.error = error;
return lib$es6$promise$$internal$$GET_THEN_ERROR;
}
}
function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {
try {
then.call(value, fulfillmentHandler, rejectionHandler);
} catch(e) {
return e;
}
}
function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) {
lib$es6$promise$asap$$default(function(promise) {
var sealed = false;
var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) {
if (sealed) { return; }
sealed = true;
if (thenable !== value) {
lib$es6$promise$$internal$$resolve(promise, value);
} else {
lib$es6$promise$$internal$$fulfill(promise, value);
}
}, function(reason) {
if (sealed) { return; }
sealed = true;
lib$es6$promise$$internal$$reject(promise, reason);
}, 'Settle: ' + (promise._label || ' unknown promise'));
if (!sealed && error) {
sealed = true;
lib$es6$promise$$internal$$reject(promise, error);
}
}, promise);
}
function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) {
if (thenable._state === lib$es6$promise$$internal$$FULFILLED) {
lib$es6$promise$$internal$$fulfill(promise, thenable._result);
} else if (thenable._state === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, thenable._result);
} else {
lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) {
lib$es6$promise$$internal$$resolve(promise, value);
}, function(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
});
}
}
function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable) {
if (maybeThenable.constructor === promise.constructor) {
lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable);
} else {
var then = lib$es6$promise$$internal$$getThen(maybeThenable);
if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error);
} else if (then === undefined) {
lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
} else if (lib$es6$promise$utils$$isFunction(then)) {
lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then);
} else {
lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
}
}
}
function lib$es6$promise$$internal$$resolve(promise, value) {
if (promise === value) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFullfillment());
} else if (lib$es6$promise$utils$$objectOrFunction(value)) {
lib$es6$promise$$internal$$handleMaybeThenable(promise, value);
} else {
lib$es6$promise$$internal$$fulfill(promise, value);
}
}
function lib$es6$promise$$internal$$publishRejection(promise) {
if (promise._onerror) {
promise._onerror(promise._result);
}
lib$es6$promise$$internal$$publish(promise);
}
function lib$es6$promise$$internal$$fulfill(promise, value) {
if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
promise._result = value;
promise._state = lib$es6$promise$$internal$$FULFILLED;
if (promise._subscribers.length !== 0) {
lib$es6$promise$asap$$default(lib$es6$promise$$internal$$publish, promise);
}
}
function lib$es6$promise$$internal$$reject(promise, reason) {
if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
promise._state = lib$es6$promise$$internal$$REJECTED;
promise._result = reason;
lib$es6$promise$asap$$default(lib$es6$promise$$internal$$publishRejection, promise);
}
function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) {
var subscribers = parent._subscribers;
var length = subscribers.length;
parent._onerror = null;
subscribers[length] = child;
subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment;
subscribers[length + lib$es6$promise$$internal$$REJECTED] = onRejection;
if (length === 0 && parent._state) {
lib$es6$promise$asap$$default(lib$es6$promise$$internal$$publish, parent);
}
}
function lib$es6$promise$$internal$$publish(promise) {
var subscribers = promise._subscribers;
var settled = promise._state;
if (subscribers.length === 0) { return; }
var child, callback, detail = promise._result;
for (var i = 0; i < subscribers.length; i += 3) {
child = subscribers[i];
callback = subscribers[i + settled];
if (child) {
lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail);
} else {
callback(detail);
}
}
promise._subscribers.length = 0;
}
function lib$es6$promise$$internal$$ErrorObject() {
this.error = null;
}
var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject();
function lib$es6$promise$$internal$$tryCatch(callback, detail) {
try {
return callback(detail);
} catch(e) {
lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e;
return lib$es6$promise$$internal$$TRY_CATCH_ERROR;
}
}
function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) {
var hasCallback = lib$es6$promise$utils$$isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
value = lib$es6$promise$$internal$$tryCatch(callback, detail);
if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) {
failed = true;
error = value.error;
value = null;
} else {
succeeded = true;
}
if (promise === value) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn());
return;
}
} else {
value = detail;
succeeded = true;
}
if (promise._state !== lib$es6$promise$$internal$$PENDING) {
// noop
} else if (hasCallback && succeeded) {
lib$es6$promise$$internal$$resolve(promise, value);
} else if (failed) {
lib$es6$promise$$internal$$reject(promise, error);
} else if (settled === lib$es6$promise$$internal$$FULFILLED) {
lib$es6$promise$$internal$$fulfill(promise, value);
} else if (settled === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, value);
}
}
function lib$es6$promise$$internal$$initializePromise(promise, resolver) {
try {
resolver(function resolvePromise(value){
lib$es6$promise$$internal$$resolve(promise, value);
}, function rejectPromise(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
});
} catch(e) {
lib$es6$promise$$internal$$reject(promise, e);
}
}
function lib$es6$promise$enumerator$$Enumerator(Constructor, input) {
var enumerator = this;
enumerator._instanceConstructor = Constructor;
enumerator.promise = new Constructor(lib$es6$promise$$internal$$noop);
if (enumerator._validateInput(input)) {
enumerator._input = input;
enumerator.length = input.length;
enumerator._remaining = input.length;
enumerator._init();
if (enumerator.length === 0) {
lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);
} else {
enumerator.length = enumerator.length || 0;
enumerator._enumerate();
if (enumerator._remaining === 0) {
lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);
}
}
} else {
lib$es6$promise$$internal$$reject(enumerator.promise, enumerator._validationError());
}
}
lib$es6$promise$enumerator$$Enumerator.prototype._validateInput = function(input) {
return lib$es6$promise$utils$$isArray(input);
};
lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function() {
return new Error('Array Methods must be provided an Array');
};
lib$es6$promise$enumerator$$Enumerator.prototype._init = function() {
this._result = new Array(this.length);
};
var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator;
lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() {
var enumerator = this;
var length = enumerator.length;
var promise = enumerator.promise;
var input = enumerator._input;
for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
enumerator._eachEntry(input[i], i);
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) {
var enumerator = this;
var c = enumerator._instanceConstructor;
if (lib$es6$promise$utils$$isMaybeThenable(entry)) {
if (entry.constructor === c && entry._state !== lib$es6$promise$$internal$$PENDING) {
entry._onerror = null;
enumerator._settledAt(entry._state, i, entry._result);
} else {
enumerator._willSettleAt(c.resolve(entry), i);
}
} else {
enumerator._remaining--;
enumerator._result[i] = entry;
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) {
var enumerator = this;
var promise = enumerator.promise;
if (promise._state === lib$es6$promise$$internal$$PENDING) {
enumerator._remaining--;
if (state === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, value);
} else {
enumerator._result[i] = value;
}
}
if (enumerator._remaining === 0) {
lib$es6$promise$$internal$$fulfill(promise, enumerator._result);
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) {
var enumerator = this;
lib$es6$promise$$internal$$subscribe(promise, undefined, function(value) {
enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value);
}, function(reason) {
enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason);
});
};
function lib$es6$promise$promise$all$$all(entries) {
return new lib$es6$promise$enumerator$$default(this, entries).promise;
}
var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all;
function lib$es6$promise$promise$race$$race(entries) {
/*jshint validthis:true */
var Constructor = this;
var promise = new Constructor(lib$es6$promise$$internal$$noop);
if (!lib$es6$promise$utils$$isArray(entries)) {
lib$es6$promise$$internal$$reject(promise, new TypeError('You must pass an array to race.'));
return promise;
}
var length = entries.length;
function onFulfillment(value) {
lib$es6$promise$$internal$$resolve(promise, value);
}
function onRejection(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
}
for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
}
return promise;
}
var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race;
function lib$es6$promise$promise$resolve$$resolve(object) {
/*jshint validthis:true */
var Constructor = this;
if (object && typeof object === 'object' && object.constructor === Constructor) {
return object;
}
var promise = new Constructor(lib$es6$promise$$internal$$noop);
lib$es6$promise$$internal$$resolve(promise, object);
return promise;
}
var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve;
function lib$es6$promise$promise$reject$$reject(reason) {
/*jshint validthis:true */
var Constructor = this;
var promise = new Constructor(lib$es6$promise$$internal$$noop);
lib$es6$promise$$internal$$reject(promise, reason);
return promise;
}
var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject;
var lib$es6$promise$promise$$counter = 0;
function lib$es6$promise$promise$$needsResolver() {
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
}
function lib$es6$promise$promise$$needsNew() {
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
}
var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise;
/**
Promise objects represent the eventual result of an asynchronous operation. The
primary way of interacting with a promise is through its `then` method, which
registers callbacks to receive either a promises eventual value or the reason
why the promise cannot be fulfilled.
Terminology
-----------
- `promise` is an object or function with a `then` method whose behavior conforms to this specification.
- `thenable` is an object or function that defines a `then` method.
- `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
- `exception` is a value that is thrown using the throw statement.
- `reason` is a value that indicates why a promise was rejected.
- `settled` the final resting state of a promise, fulfilled or rejected.
A promise can be in one of three states: pending, fulfilled, or rejected.
Promises that are fulfilled have a fulfillment value and are in the fulfilled
state. Promises that are rejected have a rejection reason and are in the
rejected state. A fulfillment value is never a thenable.
Promises can also be said to *resolve* a value. If this value is also a
promise, then the original promise's settled state will match the value's
settled state. So a promise that *resolves* a promise that rejects will
itself reject, and a promise that *resolves* a promise that fulfills will
itself fulfill.
Basic Usage:
------------
```js
var promise = new Promise(function(resolve, reject) {
// on success
resolve(value);
// on failure
reject(reason);
});
promise.then(function(value) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Advanced Usage:
---------------
Promises shine when abstracting away asynchronous interactions such as
`XMLHttpRequest`s.
```js
function getJSON(url) {
return new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.responseType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
xhr.send();
function handler() {
if (this.readyState === this.DONE) {
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
}
}
};
});
}
getJSON('/posts.json').then(function(json) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Unlike callbacks, promises are great composable primitives.
```js
Promise.all([
getJSON('/posts'),
getJSON('/comments')
]).then(function(values){
values[0] // => postsJSON
values[1] // => commentsJSON
return values;
});
```
@class Promise
@param {function} resolver
Useful for tooling.
@constructor
*/
function lib$es6$promise$promise$$Promise(resolver) {
this._id = lib$es6$promise$promise$$counter++;
this._state = undefined;
this._result = undefined;
this._subscribers = [];
if (lib$es6$promise$$internal$$noop !== resolver) {
if (!lib$es6$promise$utils$$isFunction(resolver)) {
lib$es6$promise$promise$$needsResolver();
}
if (!(this instanceof lib$es6$promise$promise$$Promise)) {
lib$es6$promise$promise$$needsNew();
}
lib$es6$promise$$internal$$initializePromise(this, resolver);
}
}
lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default;
lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default;
lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default;
lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default;
lib$es6$promise$promise$$Promise.prototype = {
constructor: lib$es6$promise$promise$$Promise,
/**
The primary way of interacting with a promise is through its `then` method,
which registers callbacks to receive either a promise's eventual value or the
reason why the promise cannot be fulfilled.
```js
findUser().then(function(user){
// user is available
}, function(reason){
// user is unavailable, and you are given the reason why
});
```
Chaining
--------
The return value of `then` is itself a promise. This second, 'downstream'
promise is resolved with the return value of the first promise's fulfillment
or rejection handler, or rejected if the handler throws an exception.
```js
findUser().then(function (user) {
return user.name;
}, function (reason) {
return 'default name';
}).then(function (userName) {
// If `findUser` fulfilled, `userName` will be the user's name, otherwise it
// will be `'default name'`
});
findUser().then(function (user) {
throw new Error('Found user, but still unhappy');
}, function (reason) {
throw new Error('`findUser` rejected and we're unhappy');
}).then(function (value) {
// never reached
}, function (reason) {
// if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
// If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
});
```
If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
```js
findUser().then(function (user) {
throw new PedagogicalException('Upstream error');
}).then(function (value) {
// never reached
}).then(function (value) {
// never reached
}, function (reason) {
// The `PedgagocialException` is propagated all the way down to here
});
```
Assimilation
------------
Sometimes the value you want to propagate to a downstream promise can only be
retrieved asynchronously. This can be achieved by returning a promise in the
fulfillment or rejection handler. The downstream promise will then be pending
until the returned promise is settled. This is called *assimilation*.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// The user's comments are now available
});
```
If the assimliated promise rejects, then the downstream promise will also reject.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// If `findCommentsByAuthor` fulfills, we'll have the value here
}, function (reason) {
// If `findCommentsByAuthor` rejects, we'll have the reason here
});
```
Simple Example
--------------
Synchronous Example
```javascript
var result;
try {
result = findResult();
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
findResult(function(result, err){
if (err) {
// failure
} else {
// success
}
});
```
Promise Example;
```javascript
findResult().then(function(result){
// success
}, function(reason){
// failure
});
```
Advanced Example
--------------
Synchronous Example
```javascript
var author, books;
try {
author = findAuthor();
books = findBooksByAuthor(author);
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
function foundBooks(books) {
}
function failure(reason) {
}
findAuthor(function(author, err){
if (err) {
failure(err);
// failure
} else {
try {
findBoooksByAuthor(author, function(books, err) {
if (err) {
failure(err);
} else {
try {
foundBooks(books);
} catch(reason) {
failure(reason);
}
}
});
} catch(error) {
failure(err);
}
// success
}
});
```
Promise Example;
```javascript
findAuthor().
then(findBooksByAuthor).
then(function(books){
// found books
}).catch(function(reason){
// something went wrong
});
```
@method then
@param {Function} onFulfilled
@param {Function} onRejected
Useful for tooling.
@return {Promise}
*/
then: function(onFulfillment, onRejection) {
var parent = this;
var state = parent._state;
if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) {
return this;
}
var child = new this.constructor(lib$es6$promise$$internal$$noop);
var result = parent._result;
if (state) {
var callback = arguments[state - 1];
lib$es6$promise$asap$$default(function(){
lib$es6$promise$$internal$$invokeCallback(state, child, callback, result);
});
} else {
lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection);
}
return child;
},
/**
`catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
as the catch block of a try/catch statement.
```js
function findAuthor(){
throw new Error('couldn't find that author');
}
// synchronous
try {
findAuthor();
} catch(reason) {
// something went wrong
}
// async with promises
findAuthor().catch(function(reason){
// something went wrong
});
```
@method catch
@param {Function} onRejection
Useful for tooling.
@return {Promise}
*/
'catch': function(onRejection) {
return this.then(null, onRejection);
}
};
function lib$es6$promise$polyfill$$polyfill() {
var local;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof self !== 'undefined') {
local = self;
} else {
try {
local = Function('return this')();
} catch (e) {
throw new Error('polyfill failed because global object is unavailable in this environment');
}
}
var P = local.Promise;
if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) {
return;
}
local.Promise = lib$es6$promise$promise$$default;
}
var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill;
var lib$es6$promise$umd$$ES6Promise = {
'Promise': lib$es6$promise$promise$$default,
'polyfill': lib$es6$promise$polyfill$$default
};
/* global define:true module:true window: true */
if (typeof define === 'function' && define['amd']) {
define(function() { return lib$es6$promise$umd$$ES6Promise; });
} else if (typeof module !== 'undefined' && module['exports']) {
module['exports'] = lib$es6$promise$umd$$ES6Promise;
} else if (typeof this !== 'undefined') {
this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise;
}
lib$es6$promise$polyfill$$default();
}).call(this);
}).call(this,{},typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],4:[function(require,module,exports){
(function (global){
'use strict';
function scheduleMicrotask(fn) {
asap(this.bind(fn));
}
function addMicrotaskSupport(zoneClass) {
zoneClass.prototype.scheduleMicrotask = scheduleMicrotask;
return zoneClass;
}
module.exports = {
addMicrotaskSupport: addMicrotaskSupport
};
// TODO(vicb): There are plan to be able to use asap() from es6-promise
// see https://github.com/jakearchibald/es6-promise/pull/113
// for now adapt code from asap.js in es6-promise
// Note: the node support has been dropped here
// TODO(vicb): Create a benchmark for the different methods & the usage of the queue
// see https://github.com/angular/zone.js/issues/97
var len = 0;
var hasNativePromise = typeof Promise ==! "undefined" &&
Promise.toString().indexOf("[native code]") !== -1;
var isFirefox = global.navigator &&
global.navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
function asap(callback) {
queue[len] = callback;
len += 1;
if (len === 1) {
scheduleFlush();
}
}
var browserWindow = (typeof global.window !== 'undefined') ? global.window : undefined;
var browserGlobal = browserWindow || {};
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
// test for web worker but not in IE10
var isWorker = typeof Uint8ClampedArray !== 'undefined' &&
typeof importScripts !== 'undefined' &&
typeof MessageChannel !== 'undefined';
function useMutationObserver() {
var iterations = 0;
var observer = new BrowserMutationObserver(flush);
var node = document.createTextNode('');
observer.observe(node, { characterData: true });
return function() {
node.data = (iterations = ++iterations % 2);
};
}
// web worker
function useMessageChannel() {
var channel = new MessageChannel();
channel.port1.onmessage = flush;
return function () {
channel.port2.postMessage(0);
};
}
function useSetTimeout() {
return function() {
setTimeout(flush, 1);
};
}
function usePromise() {
var resolvedPromise = Promise.resolve(void 0);
return function() {
resolvedPromise.then(flush);
}
}
var queue = new Array(1000);
function flush() {
for (var i = 0; i < len; i++) {
var callback = queue[i];
callback();
queue[i] = undefined;
}
len = 0;
}
var scheduleFlush;
// Decide what async method to use to triggering processing of queued callbacks:
if (hasNativePromise && !isFirefox) {
// TODO(vicb): remove '!isFirefox' when the bug is fixed:
// https://bugzilla.mozilla.org/show_bug.cgi?id=1162013
scheduleFlush = usePromise();
} else if (BrowserMutationObserver) {
scheduleFlush = useMutationObserver();
} else if (isWorker) {
scheduleFlush = useMessageChannel();
} else {
scheduleFlush = useSetTimeout();
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],5:[function(require,module,exports){
(function (global){
'use strict';
var fnPatch = require('./functions');
var promisePatch = require('./promise');
var mutationObserverPatch = require('./mutation-observer');
var definePropertyPatch = require('./define-property');
var registerElementPatch = require('./register-element');
var webSocketPatch = require('./websocket');
var eventTargetPatch = require('./event-target');
var propertyDescriptorPatch = require('./property-descriptor');
function apply() {
fnPatch.patchSetClearFunction(global, [
'timeout',
'interval',
'immediate'
]);
fnPatch.patchSetFunction(global, [
'requestAnimationFrame',
'mozRequestAnimationFrame',
'webkitRequestAnimationFrame'
]);
fnPatch.patchFunction(global, [
'alert',
'prompt'
]);
eventTargetPatch.apply();
propertyDescriptorPatch.apply();
promisePatch.apply();
mutationObserverPatch.patchClass('MutationObserver');
mutationObserverPatch.patchClass('WebKitMutationObserver');
definePropertyPatch.apply();
registerElementPatch.apply();
}
module.exports = {
apply: apply
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./define-property":6,"./event-target":7,"./functions":8,"./mutation-observer":9,"./promise":10,"./property-descriptor":11,"./register-element":12,"./websocket":13}],6:[function(require,module,exports){
'use strict';
// might need similar for object.freeze
// i regret nothing
var _defineProperty = Object.defineProperty;
var _getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
var _create = Object.create;
function apply() {
Object.defineProperty = function (obj, prop, desc) {
if (isUnconfigurable(obj, prop)) {
throw new TypeError('Cannot assign to read only property \'' + prop + '\' of ' + obj);
}
if (prop !== 'prototype') {
desc = rewriteDescriptor(obj, prop, desc);
}
return _defineProperty(obj, prop, desc);
};
Object.defineProperties = function (obj, props) {
Object.keys(props).forEach(function (prop) {
Object.defineProperty(obj, prop, props[prop]);
});
return obj;
};
Object.create = function (obj, proto) {
if (typeof proto === 'object') {
Object.keys(proto).forEach(function (prop) {
proto[prop] = rewriteDescriptor(obj, prop, proto[prop]);
});
}
return _create(obj, proto);
};
Object.getOwnPropertyDescriptor = function (obj, prop) {
var desc = _getOwnPropertyDescriptor(obj, prop);
if (isUnconfigurable(obj, prop)) {
desc.configurable = false;
}
return desc;
};
};
function _redefineProperty(obj, prop, desc) {
desc = rewriteDescriptor(obj, prop, desc);
return _defineProperty(obj, prop, desc);
};
function isUnconfigurable (obj, prop) {
return obj && obj.__unconfigurables && obj.__unconfigurables[prop];
}
function rewriteDescriptor (obj, prop, desc) {
desc.configurable = true;
if (!desc.configurable) {
if (!obj.__unconfigurables) {
_defineProperty(obj, '__unconfigurables', { writable: true, value: {} });
}
obj.__unconfigurables[prop] = true;
}
return desc;
}
module.exports = {
apply: apply,
_redefineProperty: _redefineProperty
};
},{}],7:[function(require,module,exports){
(function (global){
'use strict';
var utils = require('../utils');
function apply() {
// patched properties depend on addEventListener, so this needs to come first
if (global.EventTarget) {
utils.patchEventTargetMethods(global.EventTarget.prototype);
// Note: EventTarget is not available in all browsers,
// if it's not available, we instead patch the APIs in the IDL that inherit from EventTarget
} else {
var apis = [ 'ApplicationCache',
'EventSource',
'FileReader',
'InputMethodContext',
'MediaController',
'MessagePort',
'Node',
'Performance',
'SVGElementInstance',
'SharedWorker',
'TextTrack',
'TextTrackCue',
'TextTrackList',
'WebKitNamedFlow',
'Window',
'Worker',
'WorkerGlobalScope',
'XMLHttpRequestEventTarget',
'XMLHttpRequestUpload'
];
apis.forEach(function(thing) {
global[thing] && utils.patchEventTargetMethods(global[thing].prototype);
});
}
}
module.exports = {
apply: apply
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"../utils":14}],8:[function(require,module,exports){
(function (global){
'use strict';
var utils = require('../utils');
function patchSetClearFunction(obj, fnNames) {
fnNames.map(function (name) {
return name[0].toUpperCase() + name.substr(1);
}).forEach(function (name) {
var setName = 'set' + name;
var delegate = obj[setName];
if (delegate) {
var clearName = 'clear' + name;
var ids = {};
var bindArgs = setName === 'setInterval' ? utils.bindArguments : utils.bindArgumentsOnce;
global.zone[setName] = function (fn) {
var id, fnRef = fn;
arguments[0] = function () {
delete ids[id];
return fnRef.apply(this, arguments);
};
var args = bindArgs(arguments);
id = delegate.apply(obj, args);
ids[id] = true;
return id;
};
obj[setName] = function () {
return global.zone[setName].apply(this, arguments);
};
var clearDelegate = obj[clearName];
global.zone[clearName] = function (id) {
if (ids[id]) {
delete ids[id];
global.zone.dequeueTask();
}
return clearDelegate.apply(this, arguments);
};
obj[clearName] = function () {
return global.zone[clearName].apply(this, arguments);
};
}
});
};
function patchSetFunction(obj, fnNames) {
fnNames.forEach(function (name) {
var delegate = obj[name];
if (delegate) {
global.zone[name] = function (fn) {
var fnRef = fn;
arguments[0] = function () {
return fnRef.apply(this, arguments);
};
var args = utils.bindArgumentsOnce(arguments);
return delegate.apply(obj, args);
};
obj[name] = function () {
return zone[name].apply(this, arguments);
};
}
});
};
function patchFunction(obj, fnNames) {
fnNames.forEach(function (name) {
var delegate = obj[name];
global.zone[name] = function () {
return delegate.apply(obj, arguments);
};
obj[name] = function () {
return global.zone[name].apply(this, arguments);
};
});
};
module.exports = {
patchSetClearFunction: patchSetClearFunction,
patchSetFunction: patchSetFunction,
patchFunction: patchFunction
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"../utils":14}],9:[function(require,module,exports){
(function (global){
'use strict';
// wrap some native API on `window`
function patchClass(className) {
var OriginalClass = global[className];
if (!OriginalClass) return;
global[className] = function (fn) {
this._o = new OriginalClass(zone.bind(fn, true));
};
var instance = new OriginalClass(function () {});
global[className].prototype.disconnect = function () {
var result = this._o.disconnect.apply(this._o, arguments);
this._active && global.zone.dequeueTask();
this._active = false;
return result;
};
global[className].prototype.observe = function () {
if (!this._active) {
global.zone.enqueueTask();
}
this._active = true;
return this._o.observe.apply(this._o, arguments);
};
var prop;
for (prop in instance) {
(function (prop) {
if (typeof global[className].prototype !== undefined) {
return;
}
if (typeof instance[prop] === 'function') {
global[className].prototype[prop] = function () {
return this._o[prop].apply(this._o, arguments);
};
} else {
Object.defineProperty(global[className].prototype, prop, {
set: function (fn) {
if (typeof fn === 'function') {
this._o[prop] = zone.bind(fn);
} else {
this._o[prop] = fn;
}
},
get: function () {
return this._o[prop];
}
});
}
}(prop));
}
};
module.exports = {
patchClass: patchClass
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],10:[function(require,module,exports){
(function (global){
'use strict';
var utils = require('../utils');
/*
* patch a fn that returns a promise
*/
var bindPromiseFn = (function() {
// if the browser natively supports Promises, we can just return a native promise
if (global.Promise) {
return function (delegate) {
return function() {
var delegatePromise = delegate.apply(this, arguments);
if (delegatePromise instanceof Promise) {
return delegatePromise;
} else {
return new Promise(function(resolve, reject) {
delegatePromise.then(resolve, reject);
});
}
};
};
} else {
// if the browser does not have native promises, we have to patch each promise instance
return function (delegate) {
return function () {
return patchThenable(delegate.apply(this, arguments));
};
};
}
function patchThenable(thenable) {
var then = thenable.then;
thenable.then = function () {
var args = utils.bindArguments(arguments);
var nextThenable = then.apply(thenable, args);
return patchThenable(nextThenable);
};
var ocatch = thenable.catch;
thenable.catch = function () {
var args = utils.bindArguments(arguments);
var nextThenable = ocatch.apply(thenable, args);
return patchThenable(nextThenable);
};
return thenable;
}
}());
function apply() {
if (global.Promise) {
utils.patchPrototype(Promise.prototype, [
'then',
'catch'
]);
}
}
module.exports = {
apply: apply,
bindPromiseFn: bindPromiseFn
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"../utils":14}],11:[function(require,module,exports){
(function (global){
'use strict';
var webSocketPatch = require('./websocket');
var utils = require('../utils');
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(' ');
function apply() {
if (canPatchViaPropertyDescriptor()) {
// for browsers that we can patch the descriptor: Chrome & Firefox
var onEventNames = eventNames.map(function (property) {
return 'on' + property;
});
utils.patchProperties(HTMLElement.prototype, onEventNames);
utils.patchProperties(XMLHttpRequest.prototype);
utils.patchProperties(WebSocket.prototype);
} else {
// Safari
patchViaCapturingAllTheEvents();
utils.patchClass('XMLHttpRequest');
webSocketPatch.apply();
}
}
function canPatchViaPropertyDescriptor() {
if (!Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'onclick') && typeof Element !== 'undefined') {
// WebKit https://bugs.webkit.org/show_bug.cgi?id=134364
// IDL interface attributes are not configurable
var desc = Object.getOwnPropertyDescriptor(Element.prototype, 'onclick');
if (desc && !desc.configurable) return false;
}
Object.defineProperty(HTMLElement.prototype, 'onclick', {
get: function () {
return true;
}
});
var elt = document.createElement('div');
var result = !!elt.onclick;
Object.defineProperty(HTMLElement.prototype, 'onclick', {});
return result;
};
// Whenever any event fires, we check the event target and all parents
// for `onwhatever` properties and replace them with zone-bound functions
// - Chrome (for now)
function patchViaCapturingAllTheEvents() {
eventNames.forEach(function (property) {
var onproperty = 'on' + property;
document.addEventListener(property, function (event) {
var elt = event.target, bound;
while (elt) {
if (elt[onproperty] && !elt[onproperty]._unbound) {
bound = global.zone.bind(elt[onproperty]);
bound._unbound = elt[onproperty];
elt[onproperty] = bound;
}
elt = elt.parentElement;
}
}, true);
});
};
module.exports = {
apply: apply
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"../utils":14,"./websocket":13}],12:[function(require,module,exports){
(function (global){
'use strict';
var _redefineProperty = require('./define-property')._redefineProperty;
function apply() {
if (!('registerElement' in global.document)) {
return;
}
var _registerElement = document.registerElement;
var callbacks = [
'createdCallback',
'attachedCallback',
'detachedCallback',
'attributeChangedCallback'
];
document.registerElement = function (name, opts) {
callbacks.forEach(function (callback) {
if (opts.prototype[callback]) {
var descriptor = Object.getOwnPropertyDescriptor(opts.prototype, callback);
if (descriptor.value) {
descriptor.value = zone.bind(descriptor.value || opts.prototype[callback]);
_redefineProperty(opts.prototype, callback, descriptor);
}
}
});
return _registerElement.apply(document, [name, opts]);
};
}
module.exports = {
apply: apply
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./define-property":6}],13:[function(require,module,exports){
(function (global){
'use strict';
var utils = require('../utils.js');
// we have to patch the instance since the proto is non-configurable
function apply() {
var WS = global.WebSocket;
utils.patchEventTargetMethods(WS.prototype);
global.WebSocket = function(a, b) {
var socket = arguments.length > 1 ? new WS(a, b) : new WS(a);
var proxySocket;
// Safari 7.0 has non-configurable own 'onmessage' and friends properties on the socket instance
var onmessageDesc = Object.getOwnPropertyDescriptor(socket, 'onmessage');
if (onmessageDesc && onmessageDesc.configurable === false) {
proxySocket = Object.create(socket);
['addEventListener', 'removeEventListener', 'send', 'close'].forEach(function(propName) {
proxySocket[propName] = function() {
return socket[propName].apply(socket, arguments);
};
});
} else {
// we can patch the real socket
proxySocket = socket;
}
utils.patchProperties(proxySocket, ['onclose', 'onerror', 'onmessage', 'onopen']);
return proxySocket;
};
}
module.exports = {
apply: apply
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"../utils.js":14}],14:[function(require,module,exports){
(function (global){
'use strict';
function bindArguments(args) {
for (var i = args.length - 1; i >= 0; i--) {
if (typeof args[i] === 'function') {
args[i] = global.zone.bind(args[i]);
}
}
return args;
};
function bindArgumentsOnce(args) {
for (var i = args.length - 1; i >= 0; i--) {
if (typeof args[i] === 'function') {
args[i] = global.zone.bindOnce(args[i]);
}
}
return args;
};
function patchPrototype(obj, fnNames) {
fnNames.forEach(function (name) {
var delegate = obj[name];
if (delegate) {
obj[name] = function () {
return delegate.apply(this, bindArguments(arguments));
};
}
});
};
function patchProperty(obj, prop) {
var desc = Object.getOwnPropertyDescriptor(obj, prop) || {
enumerable: true,
configurable: true
};
// 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;
// substr(2) cuz 'onclick' -> 'click', etc
var eventName = prop.substr(2);
var _prop = '_' + prop;
desc.set = function (fn) {
if (this[_prop]) {
this.removeEventListener(eventName, this[_prop]);
}
if (typeof fn === 'function') {
this[_prop] = fn;
this.addEventListener(eventName, fn, false);
} else {
this[_prop] = null;
}
};
desc.get = function () {
return this[_prop];
};
Object.defineProperty(obj, prop, desc);
};
function patchProperties(obj, properties) {
(properties || (function () {
var props = [];
for (var prop in obj) {
props.push(prop);
}
return props;
}()).
filter(function (propertyName) {
return propertyName.substr(0,2) === 'on';
})).
forEach(function (eventName) {
patchProperty(obj, eventName);
});
};
function patchEventTargetMethods(obj) {
var addDelegate = obj.addEventListener;
obj.addEventListener = function (eventName, fn) {
fn._bound = fn._bound || {};
arguments[1] = fn._bound[eventName] = zone.bind(fn);
return addDelegate.apply(this, arguments);
};
var removeDelegate = obj.removeEventListener;
obj.removeEventListener = function (eventName, fn) {
if(arguments[1]._bound && arguments[1]._bound[eventName]) {
var _bound = arguments[1]._bound;
arguments[1] = _bound[eventName];
delete _bound[eventName];
}
var result = removeDelegate.apply(this, arguments);
global.zone.dequeueTask(fn);
return result;
};
};
// wrap some native API on `window`
function patchClass(className) {
var OriginalClass = global[className];
if (!OriginalClass) return;
global[className] = function () {
var a = bindArguments(arguments);
switch (a.length) {
case 0: this._o = new OriginalClass(); break;
case 1: this._o = new OriginalClass(a[0]); break;
case 2: this._o = new OriginalClass(a[0], a[1]); break;
case 3: this._o = new OriginalClass(a[0], a[1], a[2]); break;
case 4: this._o = new OriginalClass(a[0], a[1], a[2], a[3]); break;
default: throw new Error('what are you even doing?');
}
};
var instance = new OriginalClass(className.substr(-16) === 'MutationObserver' ? function () {} : undefined);
var prop;
for (prop in instance) {
(function (prop) {
if (typeof instance[prop] === 'function') {
global[className].prototype[prop] = function () {
return this._o[prop].apply(this._o, arguments);
};
} else {
Object.defineProperty(global[className].prototype, prop, {
set: function (fn) {
if (typeof fn === 'function') {
this._o[prop] = global.zone.bind(fn);
} else {
this._o[prop] = fn;
}
},
get: function () {
return this._o[prop];
}
});
}
}(prop));
};
};
module.exports = {
bindArguments: bindArguments,
bindArgumentsOnce: bindArgumentsOnce,
patchPrototype: patchPrototype,
patchProperty: patchProperty,
patchProperties: patchProperties,
patchEventTargetMethods: patchEventTargetMethods,
patchClass: patchClass
};
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}]},{},[1]);