UNPKG

@microsoft/office-js

Version:
233 lines (232 loc) • 6.07 kB
/*! Copyright (c) 2014 Roman Dvornov */ var OfficeExtension = OfficeExtension || {}; (function (global) { var NativePromise = global['Promise']; var nativePromiseSupported = NativePromise && 'resolve' in NativePromise && 'reject' in NativePromise && 'all' in NativePromise && 'race' in NativePromise && (function () { var resolve; new NativePromise(function (r) { resolve = r; }); return typeof resolve === 'function'; })(); if (nativePromiseSupported) return; var PENDING = 'pending'; var SEALED = 'sealed'; var FULFILLED = 'fulfilled'; var REJECTED = 'rejected'; var NOOP = function () { }; function isArray(value) { return Object.prototype.toString.call(value) === '[object Array]'; } var asyncSetTimer = typeof setImmediate !== 'undefined' ? setImmediate : setTimeout; var asyncQueue = []; var asyncTimer; function asyncFlush() { for (var i = 0; i < asyncQueue.length; i++) asyncQueue[i][0](asyncQueue[i][1]); asyncQueue = []; asyncTimer = false; } function asyncCall(callback, arg) { asyncQueue.push([callback, arg]); if (!asyncTimer) { asyncTimer = true; asyncSetTimer(asyncFlush, 0); } } function invokeResolver(resolver, promise) { function resolvePromise(value) { resolve(promise, value); } function rejectPromise(reason) { reject(promise, reason); } try { resolver(resolvePromise, rejectPromise); } catch (e) { rejectPromise(e); } } function invokeCallback(subscriber) { var owner = subscriber.owner; var settled = owner.state_; var value = owner.data_; var callback = subscriber[settled]; var promise = subscriber.then; if (typeof callback === 'function') { settled = FULFILLED; try { value = callback(value); } catch (e) { reject(promise, e); } } if (!handleThenable(promise, value)) { if (settled === FULFILLED) resolve(promise, value); if (settled === REJECTED) reject(promise, value); } } function handleThenable(promise, value) { var resolved; try { if (promise === value) throw new TypeError('A promises callback cannot return that same promise.'); if (value && (typeof value === 'function' || typeof value === 'object')) { var then = value.then; if (typeof then === 'function') { then.call(value, function (val) { if (!resolved) { resolved = true; if (value !== val) resolve(promise, val); else fulfill(promise, val); } }, function (reason) { if (!resolved) { resolved = true; reject(promise, reason); } }); return true; } } } catch (e) { if (!resolved) reject(promise, e); return true; } return false; } function resolve(promise, value) { if (promise === value || !handleThenable(promise, value)) fulfill(promise, value); } function fulfill(promise, value) { if (promise.state_ === PENDING) { promise.state_ = SEALED; promise.data_ = value; asyncCall(publishFulfillment, promise); } } function reject(promise, reason) { if (promise.state_ === PENDING) { promise.state_ = SEALED; promise.data_ = reason; asyncCall(publishRejection, promise); } } function publish(promise) { var callbacks = promise.then_; promise.then_ = undefined; for (var i = 0; i < callbacks.length; i++) { invokeCallback(callbacks[i]); } } function publishFulfillment(promise) { promise.state_ = FULFILLED; publish(promise); } function publishRejection(promise) { promise.state_ = REJECTED; publish(promise); } var Promise = function (resolver) { if (typeof resolver !== 'function') throw new TypeError('Promise constructor takes a function argument'); if (this instanceof Promise === false) throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); this.then_ = []; invokeResolver(resolver, this); }; Promise.prototype = { constructor: Promise, state_: PENDING, then_: null, data_: undefined, then: function (onFulfillment, onRejection) { var subscriber = { owner: this, then: new this.constructor(NOOP), fulfilled: onFulfillment, rejected: onRejection }; if (this.state_ === FULFILLED || this.state_ === REJECTED) { asyncCall(invokeCallback, subscriber); } else { this.then_.push(subscriber); } return subscriber.then; }, 'catch': function (onRejection) { return this.then(null, onRejection); } }; Promise.all = function (promises) { var Class = this; if (!isArray(promises)) throw new TypeError('You must pass an array to Promise.all().'); return new Class(function (resolve, reject) { var results = []; var remaining = 0; function resolver(index) { remaining++; return function (value) { results[index] = value; if (!--remaining) resolve(results); }; } for (var i = 0, promise; i < promises.length; i++) { promise = promises[i]; if (promise && typeof promise.then === 'function') promise.then(resolver(i), reject); else results[i] = promise; } if (!remaining) resolve(results); }); }; Promise.race = function (promises) { var Class = this; if (!isArray(promises)) throw new TypeError('You must pass an array to Promise.race().'); return new Class(function (resolve, reject) { for (var i = 0, promise; i < promises.length; i++) { promise = promises[i]; if (promise && typeof promise.then === 'function') promise.then(resolve, reject); else resolve(promise); } }); }; Promise.resolve = function (value) { var Class = this; if (value && typeof value === 'object' && value.constructor === Class) return value; return new Class(function (resolve) { resolve(value); }); }; Promise.reject = function (reason) { var Class = this; return new Class(function (resolve, reject) { reject(reason); }); }; global['Promise'] = Promise; })(OfficeExtension);