711 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			711 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /***
 | |
| 
 | |
| MochiKit.Async 1.5
 | |
| 
 | |
| See <http://mochikit.com/> for documentation, downloads, license, etc.
 | |
| 
 | |
| (c) 2005 Bob Ippolito.  All rights Reserved.
 | |
| 
 | |
| ***/
 | |
| 
 | |
| MochiKit.Base.module(MochiKit, 'Async', '1.5', ['Base']);
 | |
| 
 | |
| /** @id MochiKit.Async.Deferred */
 | |
| MochiKit.Async.Deferred = function (/* optional */ canceller) {
 | |
|     this.chain = [];
 | |
|     this.id = this._nextId();
 | |
|     this.fired = -1;
 | |
|     this.paused = 0;
 | |
|     this.results = [null, null];
 | |
|     this.canceller = canceller;
 | |
|     this.silentlyCancelled = false;
 | |
|     this.chained = false;
 | |
|     this.finalized = false;
 | |
| };
 | |
| 
 | |
| MochiKit.Async.Deferred.prototype = {
 | |
|     /** @id MochiKit.Async.Deferred.prototype.repr */
 | |
|     repr: function () {
 | |
|         return 'Deferred(' + this.id + ', ' + this.state() + ')';
 | |
|     },
 | |
| 
 | |
|     toString: MochiKit.Base.forwardCall("repr"),
 | |
| 
 | |
|     _nextId: MochiKit.Base.counter(),
 | |
| 
 | |
|     /** @id MochiKit.Async.Deferred.prototype.state */
 | |
|     state: function () {
 | |
|         if (this.fired == -1) {
 | |
|             return 'unfired';
 | |
|         } else if (this.fired === 0) {
 | |
|             return 'success';
 | |
|         } else {
 | |
|             return 'error';
 | |
|         }
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.Deferred.prototype.cancel */
 | |
|     cancel: function (e) {
 | |
|         var self = MochiKit.Async;
 | |
|         if (this.fired == -1) {
 | |
|             if (this.canceller) {
 | |
|                 this.canceller(this);
 | |
|             } else {
 | |
|                 this.silentlyCancelled = true;
 | |
|             }
 | |
|             if (this.fired == -1) {
 | |
|                 if (typeof(e) === 'string') {
 | |
|                     e = new self.GenericError(e);
 | |
|                 } else if (!(e instanceof Error)) {
 | |
|                     e = new self.CancelledError(this);
 | |
|                 }
 | |
|                 this.errback(e);
 | |
|             }
 | |
|         } else if ((this.fired === 0) && (this.results[0] instanceof self.Deferred)) {
 | |
|             this.results[0].cancel(e);
 | |
|         }
 | |
|     },
 | |
| 
 | |
|     _resback: function (res) {
 | |
|         /***
 | |
| 
 | |
|         The primitive that means either callback or errback
 | |
| 
 | |
|         ***/
 | |
|         this.fired = ((res instanceof Error) ? 1 : 0);
 | |
|         this.results[this.fired] = res;
 | |
|         if (this.paused === 0) {
 | |
|             this._fire();
 | |
|         }
 | |
|     },
 | |
| 
 | |
|     _check: function () {
 | |
|         if (this.fired != -1) {
 | |
|             if (!this.silentlyCancelled) {
 | |
|                 throw new MochiKit.Async.AlreadyCalledError(this);
 | |
|             }
 | |
|             this.silentlyCancelled = false;
 | |
|             return;
 | |
|         }
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.Deferred.prototype.callback */
 | |
|     callback: function (res) {
 | |
|         this._check();
 | |
|         if (res instanceof MochiKit.Async.Deferred) {
 | |
|             throw new Error("Deferred instances can only be chained if they are the result of a callback");
 | |
|         }
 | |
|         this._resback(res);
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.Deferred.prototype.errback */
 | |
|     errback: function (res) {
 | |
|         this._check();
 | |
|         var self = MochiKit.Async;
 | |
|         if (res instanceof self.Deferred) {
 | |
|             throw new Error("Deferred instances can only be chained if they are the result of a callback");
 | |
|         }
 | |
|         if (!(res instanceof Error)) {
 | |
|             res = new self.GenericError(res);
 | |
|         }
 | |
|         this._resback(res);
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.Deferred.prototype.addBoth */
 | |
|     addBoth: function (fn) {
 | |
|         if (arguments.length > 1) {
 | |
|             fn = MochiKit.Base.partial.apply(null, arguments);
 | |
|         }
 | |
|         return this.addCallbacks(fn, fn);
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.Deferred.prototype.addCallback */
 | |
|     addCallback: function (fn) {
 | |
|         if (arguments.length > 1) {
 | |
|             fn = MochiKit.Base.partial.apply(null, arguments);
 | |
|         }
 | |
|         return this.addCallbacks(fn, null);
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.Deferred.prototype.addErrback */
 | |
|     addErrback: function (fn) {
 | |
|         if (arguments.length > 1) {
 | |
|             fn = MochiKit.Base.partial.apply(null, arguments);
 | |
|         }
 | |
|         return this.addCallbacks(null, fn);
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.Deferred.prototype.addCallbacks */
 | |
|     addCallbacks: function (cb, eb) {
 | |
|         if (this.chained) {
 | |
|             throw new Error("Chained Deferreds can not be re-used");
 | |
|         }
 | |
|         if (this.finalized) {
 | |
|             throw new Error("Finalized Deferreds can not be re-used");
 | |
|         }
 | |
|         this.chain.push([cb, eb]);
 | |
|         if (this.fired >= 0) {
 | |
|             this._fire();
 | |
|         }
 | |
|         return this;
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.Deferred.prototype.setFinalizer */
 | |
|     setFinalizer: function (fn) {
 | |
|         if (this.chained) {
 | |
|             throw new Error("Chained Deferreds can not be re-used");
 | |
|         }
 | |
|         if (this.finalized) {
 | |
|             throw new Error("Finalized Deferreds can not be re-used");
 | |
|         }
 | |
|         if (arguments.length > 1) {
 | |
|             fn = MochiKit.Base.partial.apply(null, arguments);
 | |
|         }
 | |
|         this._finalizer = fn;
 | |
|         if (this.fired >= 0) {
 | |
|             this._fire();
 | |
|         }
 | |
|         return this;
 | |
|     },
 | |
| 
 | |
|     _fire: function () {
 | |
|         /***
 | |
| 
 | |
|         Used internally to exhaust the callback sequence when a result
 | |
|         is available.
 | |
| 
 | |
|         ***/
 | |
|         var chain = this.chain;
 | |
|         var fired = this.fired;
 | |
|         var res = this.results[fired];
 | |
|         var self = this;
 | |
|         var cb = null;
 | |
|         while (chain.length > 0 && this.paused === 0) {
 | |
|             // Array
 | |
|             var pair = chain.shift();
 | |
|             var f = pair[fired];
 | |
|             if (f === null) {
 | |
|                 continue;
 | |
|             }
 | |
|             try {
 | |
|                 res = f(res);
 | |
|                 fired = ((res instanceof Error) ? 1 : 0);
 | |
|                 if (res instanceof MochiKit.Async.Deferred) {
 | |
|                     cb = function (res) {
 | |
|                         self.paused--;
 | |
|                         self._resback(res);
 | |
|                     };
 | |
|                     this.paused++;
 | |
|                 }
 | |
|             } catch (err) {
 | |
|                 fired = 1;
 | |
|                 if (!(err instanceof Error)) {
 | |
|                     err = new MochiKit.Async.GenericError(err);
 | |
|                 }
 | |
|                 res = err;
 | |
|             }
 | |
|         }
 | |
|         this.fired = fired;
 | |
|         this.results[fired] = res;
 | |
|         if (this.chain.length == 0 && this.paused === 0 && this._finalizer) {
 | |
|             this.finalized = true;
 | |
|             this._finalizer(res);
 | |
|         }
 | |
|         if (cb && this.paused) {
 | |
|             // this is for "tail recursion" in case the dependent deferred
 | |
|             // is already fired
 | |
|             res.addBoth(cb);
 | |
|             res.chained = true;
 | |
|         }
 | |
|     }
 | |
| };
 | |
| 
 | |
| MochiKit.Base.update(MochiKit.Async, {
 | |
|     /** @id MochiKit.Async.evalJSONRequest */
 | |
|     evalJSONRequest: function (req) {
 | |
|         return MochiKit.Base.evalJSON(req.responseText);
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.succeed */
 | |
|     succeed: function (/* optional */result) {
 | |
|         var d = new MochiKit.Async.Deferred();
 | |
|         d.callback.apply(d, arguments);
 | |
|         return d;
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.fail */
 | |
|     fail: function (/* optional */result) {
 | |
|         var d = new MochiKit.Async.Deferred();
 | |
|         d.errback.apply(d, arguments);
 | |
|         return d;
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.getXMLHttpRequest */
 | |
|     getXMLHttpRequest: function () {
 | |
|         var self = arguments.callee;
 | |
|         if (!self.XMLHttpRequest) {
 | |
|             var tryThese = [
 | |
|                 function () { return new XMLHttpRequest(); },
 | |
|                 function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
 | |
|                 function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
 | |
|                 function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); },
 | |
|                 function () {
 | |
|                     throw new MochiKit.Async.BrowserComplianceError("Browser does not support XMLHttpRequest");
 | |
|                 }
 | |
|             ];
 | |
|             for (var i = 0; i < tryThese.length; i++) {
 | |
|                 var func = tryThese[i];
 | |
|                 try {
 | |
|                     self.XMLHttpRequest = func;
 | |
|                     return func();
 | |
|                 } catch (e) {
 | |
|                     // pass
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return self.XMLHttpRequest();
 | |
|     },
 | |
| 
 | |
|     _xhr_onreadystatechange: function (d) {
 | |
|         // MochiKit.Logging.logDebug('this.readyState', this.readyState);
 | |
|         var m = MochiKit.Base;
 | |
|         if (this.readyState == 4) {
 | |
|             // IE SUCKS
 | |
|             try {
 | |
|                 this.onreadystatechange = null;
 | |
|             } catch (e) {
 | |
|                 try {
 | |
|                     this.onreadystatechange = m.noop;
 | |
|                 } catch (e) {
 | |
|                 }
 | |
|             }
 | |
|             var status = null;
 | |
|             try {
 | |
|                 status = this.status;
 | |
|                 if (!status && (this.response || m.isNotEmpty(this.responseText))) {
 | |
|                     // 0 or undefined seems to mean cached or local
 | |
|                     status = 304;
 | |
|                 }
 | |
|             } catch (e) {
 | |
|                 // pass
 | |
|                 // MochiKit.Logging.logDebug('error getting status?', repr(items(e)));
 | |
|             }
 | |
|             // 200 is OK, 201 is CREATED, 204 is NO CONTENT
 | |
|             // 304 is NOT MODIFIED, 1223 is apparently a bug in IE
 | |
|             if (status == 200 || status == 201 || status == 204 ||
 | |
|                     status == 304 || status == 1223) {
 | |
|                 d.callback(this);
 | |
|             } else {
 | |
|                 var err = new MochiKit.Async.XMLHttpRequestError(this, "Request failed");
 | |
|                 if (err.number) {
 | |
|                     // XXX: This seems to happen on page change
 | |
|                     d.errback(err);
 | |
|                 } else {
 | |
|                     // XXX: this seems to happen when the server is unreachable
 | |
|                     d.errback(err);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     },
 | |
| 
 | |
|     _xhr_canceller: function (req) {
 | |
|         // IE SUCKS
 | |
|         try {
 | |
|             req.onreadystatechange = null;
 | |
|         } catch (e) {
 | |
|             try {
 | |
|                 req.onreadystatechange = MochiKit.Base.noop;
 | |
|             } catch (e) {
 | |
|             }
 | |
|         }
 | |
|         req.abort();
 | |
|     },
 | |
| 
 | |
| 
 | |
|     /** @id MochiKit.Async.sendXMLHttpRequest */
 | |
|     sendXMLHttpRequest: function (req, /* optional */ sendContent) {
 | |
|         if (typeof(sendContent) == "undefined" || sendContent === null) {
 | |
|             sendContent = "";
 | |
|         }
 | |
| 
 | |
|         var m = MochiKit.Base;
 | |
|         var self = MochiKit.Async;
 | |
|         var d = new self.Deferred(m.partial(self._xhr_canceller, req));
 | |
| 
 | |
|         try {
 | |
|             req.onreadystatechange = m.bind(self._xhr_onreadystatechange,
 | |
|                 req, d);
 | |
|             req.send(sendContent);
 | |
|         } catch (e) {
 | |
|             try {
 | |
|                 req.onreadystatechange = null;
 | |
|             } catch (ignore) {
 | |
|                 // pass
 | |
|             }
 | |
|             d.errback(e);
 | |
|         }
 | |
| 
 | |
|         return d;
 | |
| 
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.doXHR */
 | |
|     doXHR: function (url, opts) {
 | |
|         /*
 | |
|             Work around a Firefox bug by dealing with XHR during
 | |
|             the next event loop iteration. Maybe it's this one:
 | |
|             https://bugzilla.mozilla.org/show_bug.cgi?id=249843
 | |
|         */
 | |
|         var self = MochiKit.Async;
 | |
|         return self.callLater(0, self._doXHR, url, opts);
 | |
|     },
 | |
| 
 | |
|     _doXHR: function (url, opts) {
 | |
|         var m = MochiKit.Base;
 | |
|         opts = m.update({
 | |
|             method: 'GET',
 | |
|             sendContent: ''
 | |
|             /*
 | |
|             queryString: undefined,
 | |
|             username: undefined,
 | |
|             password: undefined,
 | |
|             headers: undefined,
 | |
|             mimeType: undefined,
 | |
|             responseType: undefined,
 | |
|             withCredentials: undefined
 | |
|             */
 | |
|         }, opts);
 | |
|         var self = MochiKit.Async;
 | |
|         var req = self.getXMLHttpRequest();
 | |
|         if (opts.queryString) {
 | |
|             var qs = m.queryString(opts.queryString);
 | |
|             if (qs) {
 | |
|                 url += "?" + qs;
 | |
|             }
 | |
|         }
 | |
|         // Safari will send undefined:undefined, so we have to check.
 | |
|         // We can't use apply, since the function is native.
 | |
|         if ('username' in opts) {
 | |
|             req.open(opts.method, url, true, opts.username, opts.password);
 | |
|         } else {
 | |
|             req.open(opts.method, url, true);
 | |
|         }
 | |
|         if (req.overrideMimeType && opts.mimeType) {
 | |
|             req.overrideMimeType(opts.mimeType);
 | |
|         }
 | |
|         req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
 | |
|         if (opts.headers) {
 | |
|             var headers = opts.headers;
 | |
|             if (!m.isArrayLike(headers)) {
 | |
|                 headers = m.items(headers);
 | |
|             }
 | |
|             for (var i = 0; i < headers.length; i++) {
 | |
|                 var header = headers[i];
 | |
|                 var name = header[0];
 | |
|                 var value = header[1];
 | |
|                 req.setRequestHeader(name, value);
 | |
|             }
 | |
|         }
 | |
|         if ("responseType" in opts && "responseType" in req) {
 | |
|             req.responseType = opts.responseType;
 | |
|         }
 | |
|         if (opts.withCredentials) {
 | |
|             req.withCredentials = 'true';
 | |
|         }
 | |
|         return self.sendXMLHttpRequest(req, opts.sendContent);
 | |
|     },
 | |
| 
 | |
|     _buildURL: function (url/*, ...*/) {
 | |
|         if (arguments.length > 1) {
 | |
|             var m = MochiKit.Base;
 | |
|             var qs = m.queryString.apply(null, m.extend(null, arguments, 1));
 | |
|             if (qs) {
 | |
|                 return url + "?" + qs;
 | |
|             }
 | |
|         }
 | |
|         return url;
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.doSimpleXMLHttpRequest */
 | |
|     doSimpleXMLHttpRequest: function (url/*, ...*/) {
 | |
|         var self = MochiKit.Async;
 | |
|         url = self._buildURL.apply(self, arguments);
 | |
|         return self.doXHR(url);
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.loadJSONDoc */
 | |
|     loadJSONDoc: function (url/*, ...*/) {
 | |
|         var self = MochiKit.Async;
 | |
|         url = self._buildURL.apply(self, arguments);
 | |
|         var d = self.doXHR(url, {
 | |
|             'mimeType': 'text/plain',
 | |
|             'headers': [['Accept', 'application/json']]
 | |
|         });
 | |
|         d = d.addCallback(self.evalJSONRequest);
 | |
|         return d;
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.loadScript */
 | |
|     loadScript: function (url) {
 | |
|         var d = new MochiKit.Async.Deferred();
 | |
|         var script = document.createElement("script");
 | |
|         script.type = "text/javascript";
 | |
|         script.src = url;
 | |
|         script.onload = function () {
 | |
|             script.onload = null;
 | |
|             script.onerror = null;
 | |
|             script.onreadystatechange = null;
 | |
|             script = null;
 | |
|             d.callback();
 | |
|         };
 | |
|         script.onerror = function (msg) {
 | |
|             script.onload = null;
 | |
|             script.onerror = null;
 | |
|             script.onreadystatechange = null;
 | |
|             script = null;
 | |
|             msg = "Failed to load script at " + url + ": " + msg;
 | |
|             d.errback(new URIError(msg, url));
 | |
|         }
 | |
|         script.onreadystatechange = function () {
 | |
|             if (script.readyState == "loaded" || script.readyState == "complete") {
 | |
|                 script.onload();
 | |
|             } else {
 | |
|                 // IE doesn't bother to report errors...
 | |
|                 MochiKit.Async.callLater(10, script.onerror, "Script loading timed out")
 | |
|             }
 | |
|         };
 | |
|         document.getElementsByTagName("head")[0].appendChild(script);
 | |
|         return d;
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.wait */
 | |
|     wait: function (seconds, /* optional */value) {
 | |
|         var d = new MochiKit.Async.Deferred();
 | |
|         var cb = MochiKit.Base.bind("callback", d, value);
 | |
|         var timeout = setTimeout(cb, Math.floor(seconds * 1000));
 | |
|         d.canceller = function () {
 | |
|             try {
 | |
|                 clearTimeout(timeout);
 | |
|             } catch (e) {
 | |
|                 // pass
 | |
|             }
 | |
|         };
 | |
|         return d;
 | |
|     },
 | |
| 
 | |
|     /** @id MochiKit.Async.callLater */
 | |
|     callLater: function (seconds, func) {
 | |
|         var m = MochiKit.Base;
 | |
|         var pfunc = m.partial.apply(m, m.extend(null, arguments, 1));
 | |
|         return MochiKit.Async.wait(seconds).addCallback(
 | |
|             function (res) { return pfunc(); }
 | |
|         );
 | |
|     }
 | |
| });
 | |
| 
 | |
| 
 | |
| /** @id MochiKit.Async.DeferredLock */
 | |
| MochiKit.Async.DeferredLock = function () {
 | |
|     this.waiting = [];
 | |
|     this.locked = false;
 | |
|     this.id = this._nextId();
 | |
| };
 | |
| 
 | |
| MochiKit.Async.DeferredLock.prototype = {
 | |
|     __class__: MochiKit.Async.DeferredLock,
 | |
|     /** @id MochiKit.Async.DeferredLock.prototype.acquire */
 | |
|     acquire: function () {
 | |
|         var d = new MochiKit.Async.Deferred();
 | |
|         if (this.locked) {
 | |
|             this.waiting.push(d);
 | |
|         } else {
 | |
|             this.locked = true;
 | |
|             d.callback(this);
 | |
|         }
 | |
|         return d;
 | |
|     },
 | |
|     /** @id MochiKit.Async.DeferredLock.prototype.release */
 | |
|     release: function () {
 | |
|         if (!this.locked) {
 | |
|             throw TypeError("Tried to release an unlocked DeferredLock");
 | |
|         }
 | |
|         this.locked = false;
 | |
|         if (this.waiting.length > 0) {
 | |
|             this.locked = true;
 | |
|             this.waiting.shift().callback(this);
 | |
|         }
 | |
|     },
 | |
|     _nextId: MochiKit.Base.counter(),
 | |
|     repr: function () {
 | |
|         var state;
 | |
|         if (this.locked) {
 | |
|             state = 'locked, ' + this.waiting.length + ' waiting';
 | |
|         } else {
 | |
|             state = 'unlocked';
 | |
|         }
 | |
|         return 'DeferredLock(' + this.id + ', ' + state + ')';
 | |
|     },
 | |
|     toString: MochiKit.Base.forwardCall("repr")
 | |
| 
 | |
| };
 | |
| 
 | |
| /** @id MochiKit.Async.DeferredList */
 | |
| MochiKit.Async.DeferredList = function (list, /* optional */fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller) {
 | |
| 
 | |
|     // call parent constructor
 | |
|     MochiKit.Async.Deferred.apply(this, [canceller]);
 | |
| 
 | |
|     this.list = list;
 | |
|     var resultList = [];
 | |
|     this.resultList = resultList;
 | |
| 
 | |
|     this.finishedCount = 0;
 | |
|     this.fireOnOneCallback = fireOnOneCallback;
 | |
|     this.fireOnOneErrback = fireOnOneErrback;
 | |
|     this.consumeErrors = consumeErrors;
 | |
| 
 | |
|     var cb = MochiKit.Base.bind(this._cbDeferred, this);
 | |
|     for (var i = 0; i < list.length; i++) {
 | |
|         var d = list[i];
 | |
|         resultList.push(undefined);
 | |
|         d.addCallback(cb, i, true);
 | |
|         d.addErrback(cb, i, false);
 | |
|     }
 | |
| 
 | |
|     if (list.length === 0 && !fireOnOneCallback) {
 | |
|         this.callback(this.resultList);
 | |
|     }
 | |
| 
 | |
| };
 | |
| 
 | |
| MochiKit.Async.DeferredList.prototype = new MochiKit.Async.Deferred();
 | |
| MochiKit.Async.DeferredList.prototype.constructor = MochiKit.Async.DeferredList;
 | |
| 
 | |
| MochiKit.Async.DeferredList.prototype._cbDeferred = function (index, succeeded, result) {
 | |
|     this.resultList[index] = [succeeded, result];
 | |
|     this.finishedCount += 1;
 | |
|     if (this.fired == -1) {
 | |
|         if (succeeded && this.fireOnOneCallback) {
 | |
|             this.callback([index, result]);
 | |
|         } else if (!succeeded && this.fireOnOneErrback) {
 | |
|             this.errback(result);
 | |
|         } else if (this.finishedCount == this.list.length) {
 | |
|             this.callback(this.resultList);
 | |
|         }
 | |
|     }
 | |
|     if (!succeeded && this.consumeErrors) {
 | |
|         result = null;
 | |
|     }
 | |
|     return result;
 | |
| };
 | |
| 
 | |
| /** @id MochiKit.Async.gatherResults */
 | |
| MochiKit.Async.gatherResults = function (deferredList) {
 | |
|     var d = new MochiKit.Async.DeferredList(deferredList, false, true, false);
 | |
|     d.addCallback(function (results) {
 | |
|         var ret = [];
 | |
|         for (var i = 0; i < results.length; i++) {
 | |
|             ret.push(results[i][1]);
 | |
|         }
 | |
|         return ret;
 | |
|     });
 | |
|     return d;
 | |
| };
 | |
| 
 | |
| /** @id MochiKit.Async.maybeDeferred */
 | |
| MochiKit.Async.maybeDeferred = function (func) {
 | |
|     var self = MochiKit.Async;
 | |
|     var result;
 | |
|     try {
 | |
|         var r = func.apply(null, MochiKit.Base.extend([], arguments, 1));
 | |
|         if (r instanceof self.Deferred) {
 | |
|             result = r;
 | |
|         } else if (r instanceof Error) {
 | |
|             result = self.fail(r);
 | |
|         } else {
 | |
|             result = self.succeed(r);
 | |
|         }
 | |
|     } catch (e) {
 | |
|         result = self.fail(e);
 | |
|     }
 | |
|     return result;
 | |
| };
 | |
| 
 | |
| 
 | |
| MochiKit.Async.__new__ = function () {
 | |
|     var m = MochiKit.Base;
 | |
|     var ne = m.partial(m._newNamedError, this);
 | |
| 
 | |
|     ne("AlreadyCalledError",
 | |
|         /** @id MochiKit.Async.AlreadyCalledError */
 | |
|         function (deferred) {
 | |
|             /***
 | |
| 
 | |
|             Raised by the Deferred if callback or errback happens
 | |
|             after it was already fired.
 | |
| 
 | |
|             ***/
 | |
|             this.deferred = deferred;
 | |
|         }
 | |
|     );
 | |
| 
 | |
|     ne("CancelledError",
 | |
|         /** @id MochiKit.Async.CancelledError */
 | |
|         function (deferred) {
 | |
|             /***
 | |
| 
 | |
|             Raised by the Deferred cancellation mechanism.
 | |
| 
 | |
|             ***/
 | |
|             this.deferred = deferred;
 | |
|         }
 | |
|     );
 | |
| 
 | |
|     ne("BrowserComplianceError",
 | |
|         /** @id MochiKit.Async.BrowserComplianceError */
 | |
|         function (msg) {
 | |
|             /***
 | |
| 
 | |
|             Raised when the JavaScript runtime is not capable of performing
 | |
|             the given function.  Technically, this should really never be
 | |
|             raised because a non-conforming JavaScript runtime probably
 | |
|             isn't going to support exceptions in the first place.
 | |
| 
 | |
|             ***/
 | |
|             this.message = msg;
 | |
|         }
 | |
|     );
 | |
| 
 | |
|     ne("GenericError",
 | |
|         /** @id MochiKit.Async.GenericError */
 | |
|         function (msg) {
 | |
|             this.message = msg;
 | |
|         }
 | |
|     );
 | |
| 
 | |
|     ne("XMLHttpRequestError",
 | |
|         /** @id MochiKit.Async.XMLHttpRequestError */
 | |
|         function (req, msg) {
 | |
|             /***
 | |
| 
 | |
|             Raised when an XMLHttpRequest does not complete for any reason.
 | |
| 
 | |
|             ***/
 | |
|             this.req = req;
 | |
|             this.message = msg;
 | |
|             try {
 | |
|                 // Strange but true that this can raise in some cases.
 | |
|                 this.number = req.status;
 | |
|             } catch (e) {
 | |
|                 // pass
 | |
|             }
 | |
|         }
 | |
|     );
 | |
| 
 | |
|     m.nameFunctions(this);
 | |
| };
 | |
| 
 | |
| MochiKit.Async.__new__();
 | |
| 
 | |
| MochiKit.Base._exportSymbols(this, MochiKit.Async);
 | 
