diff -r 322d0feea350 -r 89ef5ed3c48b src/cm/media/js/lib/yui/yui_3.10.3/build/promise/promise-debug.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui_3.10.3/build/promise/promise-debug.js Tue Jul 16 14:29:46 2013 +0200 @@ -0,0 +1,465 @@ +/* +YUI 3.10.3 (build 2fb5187) +Copyright 2013 Yahoo! Inc. All rights reserved. +Licensed under the BSD License. +http://yuilibrary.com/license/ +*/ + +YUI.add('promise', function (Y, NAME) { + +/** +Wraps the execution of asynchronous operations, providing a promise object that +can be used to subscribe to the various ways the operation may terminate. + +When the operation completes successfully, call the Resolver's `fulfill()` +method, passing any relevant response data for subscribers. If the operation +encounters an error or is unsuccessful in some way, call `reject()`, again +passing any relevant data for subscribers. + +The Resolver object should be shared only with the code resposible for +resolving or rejecting it. Public access for the Resolver is through its +_promise_, which is returned from the Resolver's `promise` property. While both +Resolver and promise allow subscriptions to the Resolver's state changes, the +promise may be exposed to non-controlling code. It is the preferable interface +for adding subscriptions. + +Subscribe to state changes in the Resolver with the promise's +`then(callback, errback)` method. `then()` wraps the passed callbacks in a +new Resolver and returns the corresponding promise, allowing chaining of +asynchronous or synchronous operations. E.g. +`promise.then(someAsyncFunc).then(anotherAsyncFunc)` + +@module promise +@since 3.9.0 +**/ + +/** +A promise represents a value that may not yet be available. Promises allow +you to chain asynchronous operations, write synchronous looking code and +handle errors throughout the process. + +This constructor takes a function as a parameter where you can insert the logic +that fulfills or rejects this promise. The fulfillment value and the rejection +reason can be any JavaScript value. It's encouraged that rejection reasons be +error objects + +

+var fulfilled = new Y.Promise(function (fulfill) {
+    fulfill('I am a fulfilled promise');
+});
+
+var rejected = new Y.Promise(function (fulfill, reject) {
+    reject(new Error('I am a rejected promise'));
+});
+
+ +@class Promise +@constructor +@param {Function} fn A function where to insert the logic that resolves this + promise. Receives `fulfill` and `reject` functions as parameters. + This function is called synchronously. +**/ +function Promise(fn) { + if (!(this instanceof Promise)) { + return new Promise(fn); + } + + var resolver = new Promise.Resolver(this); + + /** + A reference to the resolver object that handles this promise + + @property _resolver + @type Object + @private + */ + this._resolver = resolver; + + fn.call(this, function (value) { + resolver.fulfill(value); + }, function (reason) { + resolver.reject(reason); + }); +} + +Y.mix(Promise.prototype, { + /** + Schedule execution of a callback to either or both of "fulfill" and + "reject" resolutions for this promise. The callbacks are wrapped in a new + promise and that promise is returned. This allows operation chaining ala + `functionA().then(functionB).then(functionC)` where `functionA` returns + a promise, and `functionB` and `functionC` _may_ return promises. + + Asynchronicity of the callbacks is guaranteed. + + @method then + @param {Function} [callback] function to execute if the promise + resolves successfully + @param {Function} [errback] function to execute if the promise + resolves unsuccessfully + @return {Promise} A promise wrapping the resolution of either "resolve" or + "reject" callback + **/ + then: function (callback, errback) { + return this._resolver.then(callback, errback); + }, + + /** + Returns the current status of the operation. Possible results are + "pending", "fulfilled", and "rejected". + + @method getStatus + @return {String} + **/ + getStatus: function () { + return this._resolver.getStatus(); + } +}); + +/** +Checks if an object or value is a promise. This is cross-implementation +compatible, so promises returned from other libraries or native components +that are compatible with the Promises A+ spec should be recognized by this +method. + +@method isPromise +@param {Any} obj The object to test +@return {Boolean} Whether the object is a promise or not +@static +**/ +Promise.isPromise = function (obj) { + // We test promises by form to be able to identify other implementations + // as promises. This is important for cross compatibility and in particular + // Y.when which should take any kind of promise + return !!obj && typeof obj.then === 'function'; +}; + +Y.Promise = Promise; +/** +Represents an asynchronous operation. Provides a +standard API for subscribing to the moment that the operation completes either +successfully (`fulfill()`) or unsuccessfully (`reject()`). + +@class Promise.Resolver +@constructor +@param {Promise} promise The promise instance this resolver will be handling +**/ +function Resolver(promise) { + /** + List of success callbacks + + @property _callbacks + @type Array + @private + **/ + this._callbacks = []; + + /** + List of failure callbacks + + @property _errbacks + @type Array + @private + **/ + this._errbacks = []; + + /** + The promise for this Resolver. + + @property promise + @type Promise + **/ + this.promise = promise; + + /** + The status of the operation. This property may take only one of the following + values: 'pending', 'fulfilled' or 'rejected'. + + @property _status + @type String + @default 'pending' + @private + **/ + this._status = 'pending'; +} + +Y.mix(Resolver.prototype, { + /** + Resolves the promise, signaling successful completion of the + represented operation. All "onFulfilled" subscriptions are executed and passed + the value provided to this method. After calling `fulfill()`, `reject()` and + `notify()` are disabled. + + @method fulfill + @param {Any} value Value to pass along to the "onFulfilled" subscribers + **/ + fulfill: function (value) { + if (this._status === 'pending') { + this._result = value; + } + + if (this._status !== 'rejected') { + this._notify(this._callbacks, this._result); + + // Reset the callback list so that future calls to fulfill() + // won't call the same callbacks again. Promises keep a list + // of callbacks, they're not the same as events. In practice, + // calls to fulfill() after the first one should not be made by + // the user but by then() + this._callbacks = []; + + // Once a promise gets fulfilled it can't be rejected, so + // there is no point in keeping the list. Remove it to help + // garbage collection + this._errbacks = null; + + this._status = 'fulfilled'; + } + }, + + /** + Resolves the promise, signaling *un*successful completion of the + represented operation. All "onRejected" subscriptions are executed with + the value provided to this method. After calling `reject()`, `resolve()` + and `notify()` are disabled. + + @method reject + @param {Any} value Value to pass along to the "reject" subscribers + **/ + reject: function (reason) { + if (this._status === 'pending') { + this._result = reason; + } + + if (this._status !== 'fulfilled') { + this._notify(this._errbacks, this._result); + + // See fulfill() + this._callbacks = null; + this._errbacks = []; + + this._status = 'rejected'; + } + }, + + /** + Schedule execution of a callback to either or both of "resolve" and + "reject" resolutions for the Resolver. The callbacks + are wrapped in a new Resolver and that Resolver's corresponding promise + is returned. This allows operation chaining ala + `functionA().then(functionB).then(functionC)` where `functionA` returns + a promise, and `functionB` and `functionC` _may_ return promises. + + @method then + @param {Function} [callback] function to execute if the Resolver + resolves successfully + @param {Function} [errback] function to execute if the Resolver + resolves unsuccessfully + @return {Promise} The promise of a new Resolver wrapping the resolution + of either "resolve" or "reject" callback + **/ + then: function (callback, errback) { + // When the current promise is fulfilled or rejected, either the + // callback or errback will be executed via the function pushed onto + // this._callbacks or this._errbacks. However, to allow then() + // chaining, the execution of either function needs to be represented + // by a Resolver (the same Resolver can represent both flow paths), and + // its promise returned. + var promise = this.promise, + thenFulfill, thenReject, + + // using promise constructor allows for customized promises to be + // returned instead of plain ones + then = new promise.constructor(function (fulfill, reject) { + thenFulfill = fulfill; + thenReject = reject; + }), + + callbackList = this._callbacks || [], + errbackList = this._errbacks || []; + + // Because the callback and errback are represented by a Resolver, it + // must be fulfilled or rejected to propagate through the then() chain. + // The same logic applies to resolve() and reject() for fulfillment. + callbackList.push(typeof callback === 'function' ? + this._wrap(thenFulfill, thenReject, callback) : thenFulfill); + errbackList.push(typeof errback === 'function' ? + this._wrap(thenFulfill, thenReject, errback) : thenReject); + + // If a promise is already fulfilled or rejected, notify the newly added + // callbacks by calling fulfill() or reject() + if (this._status === 'fulfilled') { + this.fulfill(this._result); + } else if (this._status === 'rejected') { + this.reject(this._result); + } + + return then; + }, + + /** + Wraps the callback in Y.soon to guarantee its asynchronous execution. It + also catches exceptions to turn them into rejections and links promises + returned from the `then` callback. + + @method _wrap + @param {Function} thenFulfill Fulfillment function of the resolver that + handles this promise + @param {Function} thenReject Rejection function of the resolver that + handles this promise + @param {Function} fn Callback to wrap + @return {Function} + @private + **/ + _wrap: function (thenFulfill, thenReject, fn) { + var promise = this.promise; + + return function () { + // The args coming in to the callback/errback from the + // resolution of the parent promise. + var args = arguments; + + // Wrapping all callbacks in Y.soon to guarantee + // asynchronicity. Because setTimeout can cause unnecessary + // delays that *can* become noticeable in some situations + // (especially in Node.js) + Y.soon(function () { + // Call the callback/errback with promise as `this` to + // preserve the contract that access to the deferred is + // only for code that may resolve/reject it. + // Another option would be call the function from the + // global context, but it seemed less useful. + var result; + + // Promises model exception handling through callbacks + // making both synchronous and asynchronous errors behave + // the same way + try { + result = fn.apply(promise, args); + } catch (e) { + return thenReject(e); + } + + if (Promise.isPromise(result)) { + // Returning a promise from a callback makes the current + // promise sync up with the returned promise + result.then(thenFulfill, thenReject); + } else { + // Non-promise return values always trigger resolve() + // because callback is affirmative, and errback is + // recovery. To continue on the rejection path, errbacks + // must return rejected promises or throw. + thenFulfill(result); + } + }); + }; + }, + + /** + Returns the current status of the Resolver as a string "pending", + "fulfilled", or "rejected". + + @method getStatus + @return {String} + **/ + getStatus: function () { + return this._status; + }, + + /** + Executes an array of callbacks from a specified context, passing a set of + arguments. + + @method _notify + @param {Function[]} subs The array of subscriber callbacks + @param {Any} result Value to pass the callbacks + @protected + **/ + _notify: function (subs, result) { + var i, len; + + for (i = 0, len = subs.length; i < len; ++i) { + subs[i](result); + } + } + +}, true); + +Y.Promise.Resolver = Resolver; +/** +Abstraction API allowing you to interact with promises or raw values as if they +were promises. If a non-promise object is passed in, a new Resolver is created +and scheduled to resolve asynchronously with the provided value. + +In either case, a promise is returned. If either _callback_ or _errback_ are +provided, the promise returned is the one returned from calling +`promise.then(callback, errback)` on the provided or created promise. If neither +are provided, the original promise is returned. + +@for YUI +@method when +@param {Any} promise Promise object or value to wrap in a resolved promise +@param {Function} [callback] callback to execute if the promise is resolved +@param {Function} [errback] callback to execute if the promise is rejected +@return {Promise} +**/ +Y.when = function (promise, callback, errback) { + var value; + + if (!Y.Promise.isPromise(promise)) { + value = promise; + + promise = new Y.Promise(function (fulfill) { + fulfill(value); + }); + } + + return (callback || errback) ? promise.then(callback, errback) : promise; +}; +var slice = [].slice; + +/** +Returns a new promise that will be resolved when all operations have completed. +Takes both any numer of values as arguments. If an argument is a not a promise, +it will be wrapped in a new promise, same as in `Y.when()`. + +@for YUI +@method batch +@param {Any} operation* Any number of Y.Promise objects or regular JS values +@return {Promise} Promise to be fulfilled when all provided promises are + resolved +**/ +Y.batch = function () { + var funcs = slice.call(arguments), + remaining = funcs.length, + i = 0, + length = funcs.length, + results = []; + + return new Y.Promise(function (fulfill, reject) { + var allDone = this; + + function oneDone(index) { + return function (value) { + results[index] = value; + + remaining--; + + if (!remaining && allDone.getStatus() !== 'rejected') { + fulfill(results); + } + }; + } + + if (length < 1) { + return fulfill(results); + } + + for (; i < length; i++) { + Y.when(funcs[i], oneDone(i), reject); + } + }); +}; + + +}, '3.10.3', {"requires": ["timers"]});