summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/MochiKit/Async.js
Unidiff
Diffstat (limited to 'frontend/gamma/js/MochiKit/Async.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/js/MochiKit/Async.js120
1 files changed, 93 insertions, 27 deletions
diff --git a/frontend/gamma/js/MochiKit/Async.js b/frontend/gamma/js/MochiKit/Async.js
index c7408e7..cc43835 100644
--- a/frontend/gamma/js/MochiKit/Async.js
+++ b/frontend/gamma/js/MochiKit/Async.js
@@ -1,92 +1,103 @@
1/*** 1/***
2 2
3MochiKit.Async 1.5 3MochiKit.Async 1.5
4 4
5See <http://mochikit.com/> for documentation, downloads, license, etc. 5See <http://mochikit.com/> for documentation, downloads, license, etc.
6 6
7(c) 2005 Bob Ippolito. All rights Reserved. 7(c) 2005 Bob Ippolito. All rights Reserved.
8 8
9***/ 9***/
10 10
11MochiKit.Base._module('Async', '1.5', ['Base']); 11MochiKit.Base.module(MochiKit, 'Async', '1.5', ['Base']);
12 12
13/** @id MochiKit.Async.Deferred */ 13/** @id MochiKit.Async.Deferred */
14MochiKit.Async.Deferred = function (/* optional */ canceller) { 14MochiKit.Async.Deferred = function (/* optional */ canceller) {
15 this.chain = []; 15 this.chain = [];
16 this.id = this._nextId(); 16 this.id = this._nextId();
17 this.fired = -1; 17 this.fired = -1;
18 this.paused = 0; 18 this.paused = 0;
19 this.results = [null, null]; 19 this.results = [null, null];
20 this.canceller = canceller; 20 this.canceller = canceller;
21 this.silentlyCancelled = false; 21 this.silentlyCancelled = false;
22 this.chained = false; 22 this.chained = false;
23 this.finalized = false;
23}; 24};
24 25
25MochiKit.Async.Deferred.prototype = { 26MochiKit.Async.Deferred.prototype = {
26 /** @id MochiKit.Async.Deferred.prototype.repr */ 27 /** @id MochiKit.Async.Deferred.prototype.repr */
27 repr: function () { 28 repr: function () {
28 var state; 29 return 'Deferred(' + this.id + ', ' + this.state() + ')';
29 if (this.fired == -1) {
30 state = 'unfired';
31 } else if (this.fired === 0) {
32 state = 'success';
33 } else {
34 state = 'error';
35 }
36 return 'Deferred(' + this.id + ', ' + state + ')';
37 }, 30 },
38 31
39 toString: MochiKit.Base.forwardCall("repr"), 32 toString: MochiKit.Base.forwardCall("repr"),
40 33
41 _nextId: MochiKit.Base.counter(), 34 _nextId: MochiKit.Base.counter(),
42 35
36 /** @id MochiKit.Async.Deferred.prototype.state */
37 state: function () {
38 if (this.fired == -1) {
39 return 'unfired';
40 } else if (this.fired === 0) {
41 return 'success';
42 } else {
43 return 'error';
44 }
45 },
46
43 /** @id MochiKit.Async.Deferred.prototype.cancel */ 47 /** @id MochiKit.Async.Deferred.prototype.cancel */
44 cancel: function () { 48 cancel: function (e) {
45 var self = MochiKit.Async; 49 var self = MochiKit.Async;
46 if (this.fired == -1) { 50 if (this.fired == -1) {
47 if (this.canceller) { 51 if (this.canceller) {
48 this.canceller(this); 52 this.canceller(this);
49 } else { 53 } else {
50 this.silentlyCancelled = true; 54 this.silentlyCancelled = true;
51 } 55 }
52 if (this.fired == -1) { 56 if (this.fired == -1) {
53 this.errback(new self.CancelledError(this)); 57 if (typeof(e) === 'string') {
58 e = new self.GenericError(e);
59 } else if (!(e instanceof Error)) {
60 e = new self.CancelledError(this);
61 }
62 this.errback(e);
54 } 63 }
55 } else if ((this.fired === 0) && (this.results[0] instanceof self.Deferred)) { 64 } else if ((this.fired === 0) && (this.results[0] instanceof self.Deferred)) {
56 this.results[0].cancel(); 65 this.results[0].cancel(e);
57 } 66 }
58 }, 67 },
59 68
60 _resback: function (res) { 69 _resback: function (res) {
61 /*** 70 /***
62 71
63 The primitive that means either callback or errback 72 The primitive that means either callback or errback
64 73
65 ***/ 74 ***/
66 this.fired = ((res instanceof Error) ? 1 : 0); 75 this.fired = ((res instanceof Error) ? 1 : 0);
67 this.results[this.fired] = res; 76 this.results[this.fired] = res;
68 this._fire(); 77 if (this.paused === 0) {
78 this._fire();
79 }
69 }, 80 },
70 81
71 _check: function () { 82 _check: function () {
72 if (this.fired != -1) { 83 if (this.fired != -1) {
73 if (!this.silentlyCancelled) { 84 if (!this.silentlyCancelled) {
74 throw new MochiKit.Async.AlreadyCalledError(this); 85 throw new MochiKit.Async.AlreadyCalledError(this);
75 } 86 }
76 this.silentlyCancelled = false; 87 this.silentlyCancelled = false;
77 return; 88 return;
78 } 89 }
79 }, 90 },
80 91
81 /** @id MochiKit.Async.Deferred.prototype.callback */ 92 /** @id MochiKit.Async.Deferred.prototype.callback */
82 callback: function (res) { 93 callback: function (res) {
83 this._check(); 94 this._check();
84 if (res instanceof MochiKit.Async.Deferred) { 95 if (res instanceof MochiKit.Async.Deferred) {
85 throw new Error("Deferred instances can only be chained if they are the result of a callback"); 96 throw new Error("Deferred instances can only be chained if they are the result of a callback");
86 } 97 }
87 this._resback(res); 98 this._resback(res);
88 }, 99 },
89 100
90 /** @id MochiKit.Async.Deferred.prototype.errback */ 101 /** @id MochiKit.Async.Deferred.prototype.errback */
91 errback: function (res) { 102 errback: function (res) {
92 this._check(); 103 this._check();
@@ -108,97 +119,119 @@ MochiKit.Async.Deferred.prototype = {
108 return this.addCallbacks(fn, fn); 119 return this.addCallbacks(fn, fn);
109 }, 120 },
110 121
111 /** @id MochiKit.Async.Deferred.prototype.addCallback */ 122 /** @id MochiKit.Async.Deferred.prototype.addCallback */
112 addCallback: function (fn) { 123 addCallback: function (fn) {
113 if (arguments.length > 1) { 124 if (arguments.length > 1) {
114 fn = MochiKit.Base.partial.apply(null, arguments); 125 fn = MochiKit.Base.partial.apply(null, arguments);
115 } 126 }
116 return this.addCallbacks(fn, null); 127 return this.addCallbacks(fn, null);
117 }, 128 },
118 129
119 /** @id MochiKit.Async.Deferred.prototype.addErrback */ 130 /** @id MochiKit.Async.Deferred.prototype.addErrback */
120 addErrback: function (fn) { 131 addErrback: function (fn) {
121 if (arguments.length > 1) { 132 if (arguments.length > 1) {
122 fn = MochiKit.Base.partial.apply(null, arguments); 133 fn = MochiKit.Base.partial.apply(null, arguments);
123 } 134 }
124 return this.addCallbacks(null, fn); 135 return this.addCallbacks(null, fn);
125 }, 136 },
126 137
127 /** @id MochiKit.Async.Deferred.prototype.addCallbacks */ 138 /** @id MochiKit.Async.Deferred.prototype.addCallbacks */
128 addCallbacks: function (cb, eb) { 139 addCallbacks: function (cb, eb) {
129 if (this.chained) { 140 if (this.chained) {
130 throw new Error("Chained Deferreds can not be re-used"); 141 throw new Error("Chained Deferreds can not be re-used");
131 } 142 }
143 if (this.finalized) {
144 throw new Error("Finalized Deferreds can not be re-used");
145 }
132 this.chain.push([cb, eb]); 146 this.chain.push([cb, eb]);
133 if (this.fired >= 0) { 147 if (this.fired >= 0) {
134 this._fire(); 148 this._fire();
135 } 149 }
136 return this; 150 return this;
137 }, 151 },
138 152
153 /** @id MochiKit.Async.Deferred.prototype.setFinalizer */
154 setFinalizer: function (fn) {
155 if (this.chained) {
156 throw new Error("Chained Deferreds can not be re-used");
157 }
158 if (this.finalized) {
159 throw new Error("Finalized Deferreds can not be re-used");
160 }
161 if (arguments.length > 1) {
162 fn = MochiKit.Base.partial.apply(null, arguments);
163 }
164 this._finalizer = fn;
165 if (this.fired >= 0) {
166 this._fire();
167 }
168 return this;
169 },
170
139 _fire: function () { 171 _fire: function () {
140 /*** 172 /***
141 173
142 Used internally to exhaust the callback sequence when a result 174 Used internally to exhaust the callback sequence when a result
143 is available. 175 is available.
144 176
145 ***/ 177 ***/
146 var chain = this.chain; 178 var chain = this.chain;
147 var fired = this.fired; 179 var fired = this.fired;
148 var res = this.results[fired]; 180 var res = this.results[fired];
149 var self = this; 181 var self = this;
150 var cb = null; 182 var cb = null;
151 while (chain.length > 0 && this.paused === 0) { 183 while (chain.length > 0 && this.paused === 0) {
152 // Array 184 // Array
153 var pair = chain.shift(); 185 var pair = chain.shift();
154 var f = pair[fired]; 186 var f = pair[fired];
155 if (f === null) { 187 if (f === null) {
156 continue; 188 continue;
157 } 189 }
158 try { 190 try {
159 res = f(res); 191 res = f(res);
160 fired = ((res instanceof Error) ? 1 : 0); 192 fired = ((res instanceof Error) ? 1 : 0);
161 if (res instanceof MochiKit.Async.Deferred) { 193 if (res instanceof MochiKit.Async.Deferred) {
162 cb = function (res) { 194 cb = function (res) {
163 self._resback(res);
164 self.paused--; 195 self.paused--;
165 if ((self.paused === 0) && (self.fired >= 0)) { 196 self._resback(res);
166 self._fire();
167 }
168 }; 197 };
169 this.paused++; 198 this.paused++;
170 } 199 }
171 } catch (err) { 200 } catch (err) {
172 fired = 1; 201 fired = 1;
173 if (!(err instanceof Error)) { 202 if (!(err instanceof Error)) {
174 err = new MochiKit.Async.GenericError(err); 203 err = new MochiKit.Async.GenericError(err);
175 } 204 }
176 res = err; 205 res = err;
177 } 206 }
178 } 207 }
179 this.fired = fired; 208 this.fired = fired;
180 this.results[fired] = res; 209 this.results[fired] = res;
210 if (this.chain.length == 0 && this.paused === 0 && this._finalizer) {
211 this.finalized = true;
212 this._finalizer(res);
213 }
181 if (cb && this.paused) { 214 if (cb && this.paused) {
182 // this is for "tail recursion" in case the dependent deferred 215 // this is for "tail recursion" in case the dependent deferred
183 // is already fired 216 // is already fired
184 res.addBoth(cb); 217 res.addBoth(cb);
185 res.chained = true; 218 res.chained = true;
186 } 219 }
187 } 220 }
188}; 221};
189 222
190MochiKit.Base.update(MochiKit.Async, { 223MochiKit.Base.update(MochiKit.Async, {
191 /** @id MochiKit.Async.evalJSONRequest */ 224 /** @id MochiKit.Async.evalJSONRequest */
192 evalJSONRequest: function (req) { 225 evalJSONRequest: function (req) {
193 return MochiKit.Base.evalJSON(req.responseText); 226 return MochiKit.Base.evalJSON(req.responseText);
194 }, 227 },
195 228
196 /** @id MochiKit.Async.succeed */ 229 /** @id MochiKit.Async.succeed */
197 succeed: function (/* optional */result) { 230 succeed: function (/* optional */result) {
198 var d = new MochiKit.Async.Deferred(); 231 var d = new MochiKit.Async.Deferred();
199 d.callback.apply(d, arguments); 232 d.callback.apply(d, arguments);
200 return d; 233 return d;
201 }, 234 },
202 235
203 /** @id MochiKit.Async.fail */ 236 /** @id MochiKit.Async.fail */
204 fail: function (/* optional */result) { 237 fail: function (/* optional */result) {
@@ -228,49 +261,49 @@ MochiKit.Base.update(MochiKit.Async, {
228 } catch (e) { 261 } catch (e) {
229 // pass 262 // pass
230 } 263 }
231 } 264 }
232 } 265 }
233 return self.XMLHttpRequest(); 266 return self.XMLHttpRequest();
234 }, 267 },
235 268
236 _xhr_onreadystatechange: function (d) { 269 _xhr_onreadystatechange: function (d) {
237 // MochiKit.Logging.logDebug('this.readyState', this.readyState); 270 // MochiKit.Logging.logDebug('this.readyState', this.readyState);
238 var m = MochiKit.Base; 271 var m = MochiKit.Base;
239 if (this.readyState == 4) { 272 if (this.readyState == 4) {
240 // IE SUCKS 273 // IE SUCKS
241 try { 274 try {
242 this.onreadystatechange = null; 275 this.onreadystatechange = null;
243 } catch (e) { 276 } catch (e) {
244 try { 277 try {
245 this.onreadystatechange = m.noop; 278 this.onreadystatechange = m.noop;
246 } catch (e) { 279 } catch (e) {
247 } 280 }
248 } 281 }
249 var status = null; 282 var status = null;
250 try { 283 try {
251 status = this.status; 284 status = this.status;
252 if (!status && m.isNotEmpty(this.responseText)) { 285 if (!status && (this.response || m.isNotEmpty(this.responseText))) {
253 // 0 or undefined seems to mean cached or local 286 // 0 or undefined seems to mean cached or local
254 status = 304; 287 status = 304;
255 } 288 }
256 } catch (e) { 289 } catch (e) {
257 // pass 290 // pass
258 // MochiKit.Logging.logDebug('error getting status?', repr(items(e))); 291 // MochiKit.Logging.logDebug('error getting status?', repr(items(e)));
259 } 292 }
260 // 200 is OK, 201 is CREATED, 204 is NO CONTENT 293 // 200 is OK, 201 is CREATED, 204 is NO CONTENT
261 // 304 is NOT MODIFIED, 1223 is apparently a bug in IE 294 // 304 is NOT MODIFIED, 1223 is apparently a bug in IE
262 if (status == 200 || status == 201 || status == 204 || 295 if (status == 200 || status == 201 || status == 204 ||
263 status == 304 || status == 1223) { 296 status == 304 || status == 1223) {
264 d.callback(this); 297 d.callback(this);
265 } else { 298 } else {
266 var err = new MochiKit.Async.XMLHttpRequestError(this, "Request failed"); 299 var err = new MochiKit.Async.XMLHttpRequestError(this, "Request failed");
267 if (err.number) { 300 if (err.number) {
268 // XXX: This seems to happen on page change 301 // XXX: This seems to happen on page change
269 d.errback(err); 302 d.errback(err);
270 } else { 303 } else {
271 // XXX: this seems to happen when the server is unreachable 304 // XXX: this seems to happen when the server is unreachable
272 d.errback(err); 305 d.errback(err);
273 } 306 }
274 } 307 }
275 } 308 }
276 }, 309 },
@@ -316,125 +349,157 @@ MochiKit.Base.update(MochiKit.Async, {
316 349
317 }, 350 },
318 351
319 /** @id MochiKit.Async.doXHR */ 352 /** @id MochiKit.Async.doXHR */
320 doXHR: function (url, opts) { 353 doXHR: function (url, opts) {
321 /* 354 /*
322 Work around a Firefox bug by dealing with XHR during 355 Work around a Firefox bug by dealing with XHR during
323 the next event loop iteration. Maybe it's this one: 356 the next event loop iteration. Maybe it's this one:
324 https://bugzilla.mozilla.org/show_bug.cgi?id=249843 357 https://bugzilla.mozilla.org/show_bug.cgi?id=249843
325 */ 358 */
326 var self = MochiKit.Async; 359 var self = MochiKit.Async;
327 return self.callLater(0, self._doXHR, url, opts); 360 return self.callLater(0, self._doXHR, url, opts);
328 }, 361 },
329 362
330 _doXHR: function (url, opts) { 363 _doXHR: function (url, opts) {
331 var m = MochiKit.Base; 364 var m = MochiKit.Base;
332 opts = m.update({ 365 opts = m.update({
333 method: 'GET', 366 method: 'GET',
334 sendContent: '' 367 sendContent: ''
335 /* 368 /*
336 queryString: undefined, 369 queryString: undefined,
337 username: undefined, 370 username: undefined,
338 password: undefined, 371 password: undefined,
339 headers: undefined, 372 headers: undefined,
340 mimeType: undefined 373 mimeType: undefined,
374 responseType: undefined
341 */ 375 */
342 }, opts); 376 }, opts);
343 var self = MochiKit.Async; 377 var self = MochiKit.Async;
344 var req = self.getXMLHttpRequest(); 378 var req = self.getXMLHttpRequest();
345 if (opts.queryString) { 379 if (opts.queryString) {
346 var qs = m.queryString(opts.queryString); 380 var qs = m.queryString(opts.queryString);
347 if (qs) { 381 if (qs) {
348 url += "?" + qs; 382 url += "?" + qs;
349 } 383 }
350 } 384 }
351 // Safari will send undefined:undefined, so we have to check. 385 // Safari will send undefined:undefined, so we have to check.
352 // We can't use apply, since the function is native. 386 // We can't use apply, since the function is native.
353 if ('username' in opts) { 387 if ('username' in opts) {
354 req.open(opts.method, url, true, opts.username, opts.password); 388 req.open(opts.method, url, true, opts.username, opts.password);
355 } else { 389 } else {
356 req.open(opts.method, url, true); 390 req.open(opts.method, url, true);
357 } 391 }
358 if (req.overrideMimeType && opts.mimeType) { 392 if (req.overrideMimeType && opts.mimeType) {
359 req.overrideMimeType(opts.mimeType); 393 req.overrideMimeType(opts.mimeType);
360 } 394 }
361 req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 395 req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
362 if (opts.headers) { 396 if (opts.headers) {
363 var headers = opts.headers; 397 var headers = opts.headers;
364 if (!m.isArrayLike(headers)) { 398 if (!m.isArrayLike(headers)) {
365 headers = m.items(headers); 399 headers = m.items(headers);
366 } 400 }
367 for (var i = 0; i < headers.length; i++) { 401 for (var i = 0; i < headers.length; i++) {
368 var header = headers[i]; 402 var header = headers[i];
369 var name = header[0]; 403 var name = header[0];
370 var value = header[1]; 404 var value = header[1];
371 req.setRequestHeader(name, value); 405 req.setRequestHeader(name, value);
372 } 406 }
373 } 407 }
408 if ("responseType" in opts && "responseType" in req) {
409 req.responseType = opts.responseType;
410 }
374 return self.sendXMLHttpRequest(req, opts.sendContent); 411 return self.sendXMLHttpRequest(req, opts.sendContent);
375 }, 412 },
376 413
377 _buildURL: function (url/*, ...*/) { 414 _buildURL: function (url/*, ...*/) {
378 if (arguments.length > 1) { 415 if (arguments.length > 1) {
379 var m = MochiKit.Base; 416 var m = MochiKit.Base;
380 var qs = m.queryString.apply(null, m.extend(null, arguments, 1)); 417 var qs = m.queryString.apply(null, m.extend(null, arguments, 1));
381 if (qs) { 418 if (qs) {
382 return url + "?" + qs; 419 return url + "?" + qs;
383 } 420 }
384 } 421 }
385 return url; 422 return url;
386 }, 423 },
387 424
388 /** @id MochiKit.Async.doSimpleXMLHttpRequest */ 425 /** @id MochiKit.Async.doSimpleXMLHttpRequest */
389 doSimpleXMLHttpRequest: function (url/*, ...*/) { 426 doSimpleXMLHttpRequest: function (url/*, ...*/) {
390 var self = MochiKit.Async; 427 var self = MochiKit.Async;
391 url = self._buildURL.apply(self, arguments); 428 url = self._buildURL.apply(self, arguments);
392 return self.doXHR(url); 429 return self.doXHR(url);
393 }, 430 },
394 431
395 /** @id MochiKit.Async.loadJSONDoc */ 432 /** @id MochiKit.Async.loadJSONDoc */
396 loadJSONDoc: function (url/*, ...*/) { 433 loadJSONDoc: function (url/*, ...*/) {
397 var self = MochiKit.Async; 434 var self = MochiKit.Async;
398 url = self._buildURL.apply(self, arguments); 435 url = self._buildURL.apply(self, arguments);
399 var d = self.doXHR(url, { 436 var d = self.doXHR(url, {
400 'mimeType': 'text/plain', 437 'mimeType': 'text/plain',
401 'headers': [['Accept', 'application/json']] 438 'headers': [['Accept', 'application/json']]
402 }); 439 });
403 d = d.addCallback(self.evalJSONRequest); 440 d = d.addCallback(self.evalJSONRequest);
404 return d; 441 return d;
405 }, 442 },
406 443
444 /** @id MochiKit.Async.loadScript */
445 loadScript: function (url) {
446 var d = new MochiKit.Async.Deferred();
447 var script = document.createElement("script");
448 script.type = "text/javascript";
449 script.src = url;
450 script.onload = function () {
451 script.onload = null;
452 script.onerror = null;
453 script.onreadystatechange = null;
454 script = null;
455 d.callback();
456 };
457 script.onerror = function (msg) {
458 script.onload = null;
459 script.onerror = null;
460 script.onreadystatechange = null;
461 script = null;
462 msg = "Failed to load script at " + url + ": " + msg;
463 d.errback(new URIError(msg, url));
464 }
465 script.onreadystatechange = function () {
466 if (script.readyState == "loaded" || script.readyState == "complete") {
467 script.onload();
468 } else {
469 // IE doesn't bother to report errors...
470 MochiKit.Async.callLater(10, script.onerror, "Script loading timed out")
471 }
472 };
473 document.getElementsByTagName("head")[0].appendChild(script);
474 return d;
475 },
476
407 /** @id MochiKit.Async.wait */ 477 /** @id MochiKit.Async.wait */
408 wait: function (seconds, /* optional */value) { 478 wait: function (seconds, /* optional */value) {
409 var d = new MochiKit.Async.Deferred(); 479 var d = new MochiKit.Async.Deferred();
410 var m = MochiKit.Base; 480 var cb = MochiKit.Base.bind("callback", d, value);
411 if (typeof(value) != 'undefined') { 481 var timeout = setTimeout(cb, Math.floor(seconds * 1000));
412 d.addCallback(function () { return value; });
413 }
414 var timeout = setTimeout(
415 m.bind("callback", d),
416 Math.floor(seconds * 1000));
417 d.canceller = function () { 482 d.canceller = function () {
418 try { 483 try {
419 clearTimeout(timeout); 484 clearTimeout(timeout);
420 } catch (e) { 485 } catch (e) {
421 // pass 486 // pass
422 } 487 }
423 }; 488 };
424 return d; 489 return d;
425 }, 490 },
426 491
427 /** @id MochiKit.Async.callLater */ 492 /** @id MochiKit.Async.callLater */
428 callLater: function (seconds, func) { 493 callLater: function (seconds, func) {
429 var m = MochiKit.Base; 494 var m = MochiKit.Base;
430 var pfunc = m.partial.apply(m, m.extend(null, arguments, 1)); 495 var pfunc = m.partial.apply(m, m.extend(null, arguments, 1));
431 return MochiKit.Async.wait(seconds).addCallback( 496 return MochiKit.Async.wait(seconds).addCallback(
432 function (res) { return pfunc(); } 497 function (res) { return pfunc(); }
433 ); 498 );
434 } 499 }
435}); 500});
436 501
437 502
438/** @id MochiKit.Async.DeferredLock */ 503/** @id MochiKit.Async.DeferredLock */
439MochiKit.Async.DeferredLock = function () { 504MochiKit.Async.DeferredLock = function () {
440 this.waiting = []; 505 this.waiting = [];
@@ -489,48 +554,49 @@ MochiKit.Async.DeferredList = function (list, /* optional */fireOnOneCallback, f
489 this.list = list; 554 this.list = list;
490 var resultList = []; 555 var resultList = [];
491 this.resultList = resultList; 556 this.resultList = resultList;
492 557
493 this.finishedCount = 0; 558 this.finishedCount = 0;
494 this.fireOnOneCallback = fireOnOneCallback; 559 this.fireOnOneCallback = fireOnOneCallback;
495 this.fireOnOneErrback = fireOnOneErrback; 560 this.fireOnOneErrback = fireOnOneErrback;
496 this.consumeErrors = consumeErrors; 561 this.consumeErrors = consumeErrors;
497 562
498 var cb = MochiKit.Base.bind(this._cbDeferred, this); 563 var cb = MochiKit.Base.bind(this._cbDeferred, this);
499 for (var i = 0; i < list.length; i++) { 564 for (var i = 0; i < list.length; i++) {
500 var d = list[i]; 565 var d = list[i];
501 resultList.push(undefined); 566 resultList.push(undefined);
502 d.addCallback(cb, i, true); 567 d.addCallback(cb, i, true);
503 d.addErrback(cb, i, false); 568 d.addErrback(cb, i, false);
504 } 569 }
505 570
506 if (list.length === 0 && !fireOnOneCallback) { 571 if (list.length === 0 && !fireOnOneCallback) {
507 this.callback(this.resultList); 572 this.callback(this.resultList);
508 } 573 }
509 574
510}; 575};
511 576
512MochiKit.Async.DeferredList.prototype = new MochiKit.Async.Deferred(); 577MochiKit.Async.DeferredList.prototype = new MochiKit.Async.Deferred();
578MochiKit.Async.DeferredList.prototype.constructor = MochiKit.Async.DeferredList;
513 579
514MochiKit.Async.DeferredList.prototype._cbDeferred = function (index, succeeded, result) { 580MochiKit.Async.DeferredList.prototype._cbDeferred = function (index, succeeded, result) {
515 this.resultList[index] = [succeeded, result]; 581 this.resultList[index] = [succeeded, result];
516 this.finishedCount += 1; 582 this.finishedCount += 1;
517 if (this.fired == -1) { 583 if (this.fired == -1) {
518 if (succeeded && this.fireOnOneCallback) { 584 if (succeeded && this.fireOnOneCallback) {
519 this.callback([index, result]); 585 this.callback([index, result]);
520 } else if (!succeeded && this.fireOnOneErrback) { 586 } else if (!succeeded && this.fireOnOneErrback) {
521 this.errback(result); 587 this.errback(result);
522 } else if (this.finishedCount == this.list.length) { 588 } else if (this.finishedCount == this.list.length) {
523 this.callback(this.resultList); 589 this.callback(this.resultList);
524 } 590 }
525 } 591 }
526 if (!succeeded && this.consumeErrors) { 592 if (!succeeded && this.consumeErrors) {
527 result = null; 593 result = null;
528 } 594 }
529 return result; 595 return result;
530}; 596};
531 597
532/** @id MochiKit.Async.gatherResults */ 598/** @id MochiKit.Async.gatherResults */
533MochiKit.Async.gatherResults = function (deferredList) { 599MochiKit.Async.gatherResults = function (deferredList) {
534 var d = new MochiKit.Async.DeferredList(deferredList, false, true, false); 600 var d = new MochiKit.Async.DeferredList(deferredList, false, true, false);
535 d.addCallback(function (results) { 601 d.addCallback(function (results) {
536 var ret = []; 602 var ret = [];