| Index: lib/polyfill/promise.js | 
| =================================================================== | 
| new file mode 100644 | 
| --- /dev/null | 
| +++ b/lib/polyfill/promise.js | 
| @@ -0,0 +1,152 @@ | 
| +/* | 
| + * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| + * Copyright (C) 2006-2015 Eyeo GmbH | 
| + * | 
| + * Adblock Plus is free software: you can redistribute it and/or modify | 
| + * it under the terms of the GNU General Public License version 3 as | 
| + * published by the Free Software Foundation. | 
| + * | 
| + * Adblock Plus is distributed in the hope that it will be useful, | 
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
| + * GNU General Public License for more details. | 
| + * | 
| + * You should have received a copy of the GNU General Public License | 
| + * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 
| + */ | 
| + | 
| +(function(global) | 
| +{ | 
| + if ("Promise" in global) | 
| + return; | 
| + | 
| + var PENDING = 0; | 
| + var FULFILLED = 1; | 
| + var REJECTED = 2; | 
| + | 
| + global.Promise = function(executor) | 
| + { | 
| + this._state = PENDING; | 
| + this._value = undefined; | 
| + this._subscriptions = []; | 
| + | 
| + try | 
| + { | 
| + executor(this._emit.bind(this, FULFILLED), | 
| + this._emit.bind(this, REJECTED)); | 
| + } | 
| + catch (reason) | 
| + { | 
| + this._emit(REJECTED, reason); | 
| + } | 
| + }; | 
| + | 
| + Promise.prototype = { | 
| + _dispatch: function(onFulfilled, onRejected, resolve, reject) | 
| + { | 
| + var callback = this._state == FULFILLED ? onFulfilled : onRejected; | 
| + | 
| + if (typeof callback == "function") | 
| + { | 
| + var result; | 
| + | 
| + try | 
| + { | 
| + result = callback(this._value); | 
| + } | 
| + catch (reason) | 
| + { | 
| + reject(reason); | 
| + return; | 
| + } | 
| + | 
| + Promise.resolve(result).then(resolve, reject); | 
| + } | 
| + else if (this._state == FULFILLED) | 
| + { | 
| + resolve(this._value); | 
| + } | 
| + else if (this._state == REJECTED) | 
| + { | 
| + reject(this._value); | 
| + } | 
| + }, | 
| + _dispatchSubscriptions: function() | 
| + { | 
| + if (this._state == REJECTED && this._subscriptions.length == 0) | 
| + console.error('Uncaught (in promise)', this._value); | 
| + | 
| + for (var i = 0; i < this._subscriptions.length; i++) | 
| + this._dispatch.apply(this, this._subscriptions[i]); | 
| + | 
| + this._subscriptions = null; | 
| + }, | 
| + _emit: function(state, value) | 
| + { | 
| + if (this._state != PENDING) | 
| + return; | 
| + | 
| + this._state = state; | 
| + this._value = value; | 
| + | 
| + setTimeout(this._dispatchSubscriptions.bind(this), 0); | 
| + }, | 
| + then: function(onFulfilled, onRejected) | 
| + { | 
| + return new Promise(function(resolve, reject) | 
| + { | 
| + if (this._subscriptions) | 
| + this._subscriptions.push([onFulfilled, onRejected, resolve, reject]); | 
| + else | 
| + setTimeout( | 
| + this._dispatch.bind(this), 0, | 
| + onFulfilled, onRejected, resolve, reject | 
| + ); | 
| + }.bind(this)); | 
| + }, | 
| + catch: function(onRejected) | 
| + { | 
| + return this.then(undefined, onRejected); | 
| + } | 
| + }; | 
| + | 
| + Promise.resolve = function(value) | 
| + { | 
| + if (value instanceof Promise) | 
| + return value; | 
| + return new Promise(function(resolve, reject) { resolve(value); }); | 
| + }; | 
| + | 
| + Promise.reject = function(reason) | 
| + { | 
| + return new Promise(function(resolve, reject) { reject(reason); }); | 
| + }; | 
| + | 
| + Promise.all = function(promises) | 
| + { | 
| + return new Promise(function(resolve, reject) | 
| + { | 
| + var count = promises.length; | 
| + var result = new Array(count); | 
| + | 
| + if (count == 0) | 
| + { | 
| + resolve(result); | 
| + return; | 
| + } | 
| + | 
| + promises.forEach(function(promise, i) | 
| + { | 
| + Promise.resolve(promise).then( | 
| + function(value) | 
| + { | 
| + result[i] = value; | 
| + if (--count == 0) | 
| + resolve(result); | 
| + }, | 
| + reject | 
| + ); | 
| + }); | 
| + }); | 
| + }; | 
| +})(this); |