|
1 /*** |
|
2 |
|
3 MochiKit.Async 1.4.2 |
|
4 |
|
5 See <http://mochikit.com/> for documentation, downloads, license, etc. |
|
6 |
|
7 (c) 2005 Bob Ippolito. All rights Reserved. |
|
8 |
|
9 ***/ |
|
10 |
|
11 MochiKit.Base._deps('Async', ['Base']); |
|
12 |
|
13 MochiKit.Async.NAME = "MochiKit.Async"; |
|
14 MochiKit.Async.VERSION = "1.4.2"; |
|
15 MochiKit.Async.__repr__ = function () { |
|
16 return "[" + this.NAME + " " + this.VERSION + "]"; |
|
17 }; |
|
18 MochiKit.Async.toString = function () { |
|
19 return this.__repr__(); |
|
20 }; |
|
21 |
|
22 /** @id MochiKit.Async.Deferred */ |
|
23 MochiKit.Async.Deferred = function (/* optional */ canceller) { |
|
24 this.chain = []; |
|
25 this.id = this._nextId(); |
|
26 this.fired = -1; |
|
27 this.paused = 0; |
|
28 this.results = [null, null]; |
|
29 this.canceller = canceller; |
|
30 this.silentlyCancelled = false; |
|
31 this.chained = false; |
|
32 }; |
|
33 |
|
34 MochiKit.Async.Deferred.prototype = { |
|
35 /** @id MochiKit.Async.Deferred.prototype.repr */ |
|
36 repr: function () { |
|
37 var state; |
|
38 if (this.fired == -1) { |
|
39 state = 'unfired'; |
|
40 } else if (this.fired === 0) { |
|
41 state = 'success'; |
|
42 } else { |
|
43 state = 'error'; |
|
44 } |
|
45 return 'Deferred(' + this.id + ', ' + state + ')'; |
|
46 }, |
|
47 |
|
48 toString: MochiKit.Base.forwardCall("repr"), |
|
49 |
|
50 _nextId: MochiKit.Base.counter(), |
|
51 |
|
52 /** @id MochiKit.Async.Deferred.prototype.cancel */ |
|
53 cancel: function () { |
|
54 var self = MochiKit.Async; |
|
55 if (this.fired == -1) { |
|
56 if (this.canceller) { |
|
57 this.canceller(this); |
|
58 } else { |
|
59 this.silentlyCancelled = true; |
|
60 } |
|
61 if (this.fired == -1) { |
|
62 this.errback(new self.CancelledError(this)); |
|
63 } |
|
64 } else if ((this.fired === 0) && (this.results[0] instanceof self.Deferred)) { |
|
65 this.results[0].cancel(); |
|
66 } |
|
67 }, |
|
68 |
|
69 _resback: function (res) { |
|
70 /*** |
|
71 |
|
72 The primitive that means either callback or errback |
|
73 |
|
74 ***/ |
|
75 this.fired = ((res instanceof Error) ? 1 : 0); |
|
76 this.results[this.fired] = res; |
|
77 this._fire(); |
|
78 }, |
|
79 |
|
80 _check: function () { |
|
81 if (this.fired != -1) { |
|
82 if (!this.silentlyCancelled) { |
|
83 throw new MochiKit.Async.AlreadyCalledError(this); |
|
84 } |
|
85 this.silentlyCancelled = false; |
|
86 return; |
|
87 } |
|
88 }, |
|
89 |
|
90 /** @id MochiKit.Async.Deferred.prototype.callback */ |
|
91 callback: function (res) { |
|
92 this._check(); |
|
93 if (res instanceof MochiKit.Async.Deferred) { |
|
94 throw new Error("Deferred instances can only be chained if they are the result of a callback"); |
|
95 } |
|
96 this._resback(res); |
|
97 }, |
|
98 |
|
99 /** @id MochiKit.Async.Deferred.prototype.errback */ |
|
100 errback: function (res) { |
|
101 this._check(); |
|
102 var self = MochiKit.Async; |
|
103 if (res instanceof self.Deferred) { |
|
104 throw new Error("Deferred instances can only be chained if they are the result of a callback"); |
|
105 } |
|
106 if (!(res instanceof Error)) { |
|
107 res = new self.GenericError(res); |
|
108 } |
|
109 this._resback(res); |
|
110 }, |
|
111 |
|
112 /** @id MochiKit.Async.Deferred.prototype.addBoth */ |
|
113 addBoth: function (fn) { |
|
114 if (arguments.length > 1) { |
|
115 fn = MochiKit.Base.partial.apply(null, arguments); |
|
116 } |
|
117 return this.addCallbacks(fn, fn); |
|
118 }, |
|
119 |
|
120 /** @id MochiKit.Async.Deferred.prototype.addCallback */ |
|
121 addCallback: function (fn) { |
|
122 if (arguments.length > 1) { |
|
123 fn = MochiKit.Base.partial.apply(null, arguments); |
|
124 } |
|
125 return this.addCallbacks(fn, null); |
|
126 }, |
|
127 |
|
128 /** @id MochiKit.Async.Deferred.prototype.addErrback */ |
|
129 addErrback: function (fn) { |
|
130 if (arguments.length > 1) { |
|
131 fn = MochiKit.Base.partial.apply(null, arguments); |
|
132 } |
|
133 return this.addCallbacks(null, fn); |
|
134 }, |
|
135 |
|
136 /** @id MochiKit.Async.Deferred.prototype.addCallbacks */ |
|
137 addCallbacks: function (cb, eb) { |
|
138 if (this.chained) { |
|
139 throw new Error("Chained Deferreds can not be re-used"); |
|
140 } |
|
141 this.chain.push([cb, eb]); |
|
142 if (this.fired >= 0) { |
|
143 this._fire(); |
|
144 } |
|
145 return this; |
|
146 }, |
|
147 |
|
148 _fire: function () { |
|
149 /*** |
|
150 |
|
151 Used internally to exhaust the callback sequence when a result |
|
152 is available. |
|
153 |
|
154 ***/ |
|
155 var chain = this.chain; |
|
156 var fired = this.fired; |
|
157 var res = this.results[fired]; |
|
158 var self = this; |
|
159 var cb = null; |
|
160 while (chain.length > 0 && this.paused === 0) { |
|
161 // Array |
|
162 var pair = chain.shift(); |
|
163 var f = pair[fired]; |
|
164 if (f === null) { |
|
165 continue; |
|
166 } |
|
167 try { |
|
168 res = f(res); |
|
169 fired = ((res instanceof Error) ? 1 : 0); |
|
170 if (res instanceof MochiKit.Async.Deferred) { |
|
171 cb = function (res) { |
|
172 self._resback(res); |
|
173 self.paused--; |
|
174 if ((self.paused === 0) && (self.fired >= 0)) { |
|
175 self._fire(); |
|
176 } |
|
177 }; |
|
178 this.paused++; |
|
179 } |
|
180 } catch (err) { |
|
181 fired = 1; |
|
182 if (!(err instanceof Error)) { |
|
183 err = new MochiKit.Async.GenericError(err); |
|
184 } |
|
185 res = err; |
|
186 } |
|
187 } |
|
188 this.fired = fired; |
|
189 this.results[fired] = res; |
|
190 if (cb && this.paused) { |
|
191 // this is for "tail recursion" in case the dependent deferred |
|
192 // is already fired |
|
193 res.addBoth(cb); |
|
194 res.chained = true; |
|
195 } |
|
196 } |
|
197 }; |
|
198 |
|
199 MochiKit.Base.update(MochiKit.Async, { |
|
200 /** @id MochiKit.Async.evalJSONRequest */ |
|
201 evalJSONRequest: function (req) { |
|
202 return MochiKit.Base.evalJSON(req.responseText); |
|
203 }, |
|
204 |
|
205 /** @id MochiKit.Async.succeed */ |
|
206 succeed: function (/* optional */result) { |
|
207 var d = new MochiKit.Async.Deferred(); |
|
208 d.callback.apply(d, arguments); |
|
209 return d; |
|
210 }, |
|
211 |
|
212 /** @id MochiKit.Async.fail */ |
|
213 fail: function (/* optional */result) { |
|
214 var d = new MochiKit.Async.Deferred(); |
|
215 d.errback.apply(d, arguments); |
|
216 return d; |
|
217 }, |
|
218 |
|
219 /** @id MochiKit.Async.getXMLHttpRequest */ |
|
220 getXMLHttpRequest: function () { |
|
221 var self = arguments.callee; |
|
222 if (!self.XMLHttpRequest) { |
|
223 var tryThese = [ |
|
224 function () { return new XMLHttpRequest(); }, |
|
225 function () { return new ActiveXObject('Msxml2.XMLHTTP'); }, |
|
226 function () { return new ActiveXObject('Microsoft.XMLHTTP'); }, |
|
227 function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); }, |
|
228 function () { |
|
229 throw new MochiKit.Async.BrowserComplianceError("Browser does not support XMLHttpRequest"); |
|
230 } |
|
231 ]; |
|
232 for (var i = 0; i < tryThese.length; i++) { |
|
233 var func = tryThese[i]; |
|
234 try { |
|
235 self.XMLHttpRequest = func; |
|
236 return func(); |
|
237 } catch (e) { |
|
238 // pass |
|
239 } |
|
240 } |
|
241 } |
|
242 return self.XMLHttpRequest(); |
|
243 }, |
|
244 |
|
245 _xhr_onreadystatechange: function (d) { |
|
246 // MochiKit.Logging.logDebug('this.readyState', this.readyState); |
|
247 var m = MochiKit.Base; |
|
248 if (this.readyState == 4) { |
|
249 // IE SUCKS |
|
250 try { |
|
251 this.onreadystatechange = null; |
|
252 } catch (e) { |
|
253 try { |
|
254 this.onreadystatechange = m.noop; |
|
255 } catch (e) { |
|
256 } |
|
257 } |
|
258 var status = null; |
|
259 try { |
|
260 status = this.status; |
|
261 if (!status && m.isNotEmpty(this.responseText)) { |
|
262 // 0 or undefined seems to mean cached or local |
|
263 status = 304; |
|
264 } |
|
265 } catch (e) { |
|
266 // pass |
|
267 // MochiKit.Logging.logDebug('error getting status?', repr(items(e))); |
|
268 } |
|
269 // 200 is OK, 201 is CREATED, 204 is NO CONTENT |
|
270 // 304 is NOT MODIFIED, 1223 is apparently a bug in IE |
|
271 if (status == 200 || status == 201 || status == 204 || |
|
272 status == 304 || status == 1223) { |
|
273 d.callback(this); |
|
274 } else { |
|
275 var err = new MochiKit.Async.XMLHttpRequestError(this, "Request failed"); |
|
276 if (err.number) { |
|
277 // XXX: This seems to happen on page change |
|
278 d.errback(err); |
|
279 } else { |
|
280 // XXX: this seems to happen when the server is unreachable |
|
281 d.errback(err); |
|
282 } |
|
283 } |
|
284 } |
|
285 }, |
|
286 |
|
287 _xhr_canceller: function (req) { |
|
288 // IE SUCKS |
|
289 try { |
|
290 req.onreadystatechange = null; |
|
291 } catch (e) { |
|
292 try { |
|
293 req.onreadystatechange = MochiKit.Base.noop; |
|
294 } catch (e) { |
|
295 } |
|
296 } |
|
297 req.abort(); |
|
298 }, |
|
299 |
|
300 |
|
301 /** @id MochiKit.Async.sendXMLHttpRequest */ |
|
302 sendXMLHttpRequest: function (req, /* optional */ sendContent) { |
|
303 if (typeof(sendContent) == "undefined" || sendContent === null) { |
|
304 sendContent = ""; |
|
305 } |
|
306 |
|
307 var m = MochiKit.Base; |
|
308 var self = MochiKit.Async; |
|
309 var d = new self.Deferred(m.partial(self._xhr_canceller, req)); |
|
310 |
|
311 try { |
|
312 req.onreadystatechange = m.bind(self._xhr_onreadystatechange, |
|
313 req, d); |
|
314 req.send(sendContent); |
|
315 } catch (e) { |
|
316 try { |
|
317 req.onreadystatechange = null; |
|
318 } catch (ignore) { |
|
319 // pass |
|
320 } |
|
321 d.errback(e); |
|
322 } |
|
323 |
|
324 return d; |
|
325 |
|
326 }, |
|
327 |
|
328 /** @id MochiKit.Async.doXHR */ |
|
329 doXHR: function (url, opts) { |
|
330 /* |
|
331 Work around a Firefox bug by dealing with XHR during |
|
332 the next event loop iteration. Maybe it's this one: |
|
333 https://bugzilla.mozilla.org/show_bug.cgi?id=249843 |
|
334 */ |
|
335 var self = MochiKit.Async; |
|
336 return self.callLater(0, self._doXHR, url, opts); |
|
337 }, |
|
338 |
|
339 _doXHR: function (url, opts) { |
|
340 var m = MochiKit.Base; |
|
341 opts = m.update({ |
|
342 method: 'GET', |
|
343 sendContent: '' |
|
344 /* |
|
345 queryString: undefined, |
|
346 username: undefined, |
|
347 password: undefined, |
|
348 headers: undefined, |
|
349 mimeType: undefined |
|
350 */ |
|
351 }, opts); |
|
352 var self = MochiKit.Async; |
|
353 var req = self.getXMLHttpRequest(); |
|
354 if (opts.queryString) { |
|
355 var qs = m.queryString(opts.queryString); |
|
356 if (qs) { |
|
357 url += "?" + qs; |
|
358 } |
|
359 } |
|
360 // Safari will send undefined:undefined, so we have to check. |
|
361 // We can't use apply, since the function is native. |
|
362 if ('username' in opts) { |
|
363 req.open(opts.method, url, true, opts.username, opts.password); |
|
364 } else { |
|
365 req.open(opts.method, url, true); |
|
366 } |
|
367 if (req.overrideMimeType && opts.mimeType) { |
|
368 req.overrideMimeType(opts.mimeType); |
|
369 } |
|
370 req.setRequestHeader("X-Requested-With", "XMLHttpRequest"); |
|
371 if (opts.headers) { |
|
372 var headers = opts.headers; |
|
373 if (!m.isArrayLike(headers)) { |
|
374 headers = m.items(headers); |
|
375 } |
|
376 for (var i = 0; i < headers.length; i++) { |
|
377 var header = headers[i]; |
|
378 var name = header[0]; |
|
379 var value = header[1]; |
|
380 req.setRequestHeader(name, value); |
|
381 } |
|
382 } |
|
383 return self.sendXMLHttpRequest(req, opts.sendContent); |
|
384 }, |
|
385 |
|
386 _buildURL: function (url/*, ...*/) { |
|
387 if (arguments.length > 1) { |
|
388 var m = MochiKit.Base; |
|
389 var qs = m.queryString.apply(null, m.extend(null, arguments, 1)); |
|
390 if (qs) { |
|
391 return url + "?" + qs; |
|
392 } |
|
393 } |
|
394 return url; |
|
395 }, |
|
396 |
|
397 /** @id MochiKit.Async.doSimpleXMLHttpRequest */ |
|
398 doSimpleXMLHttpRequest: function (url/*, ...*/) { |
|
399 var self = MochiKit.Async; |
|
400 url = self._buildURL.apply(self, arguments); |
|
401 return self.doXHR(url); |
|
402 }, |
|
403 |
|
404 /** @id MochiKit.Async.loadJSONDoc */ |
|
405 loadJSONDoc: function (url/*, ...*/) { |
|
406 var self = MochiKit.Async; |
|
407 url = self._buildURL.apply(self, arguments); |
|
408 var d = self.doXHR(url, { |
|
409 'mimeType': 'text/plain', |
|
410 'headers': [['Accept', 'application/json']] |
|
411 }); |
|
412 d = d.addCallback(self.evalJSONRequest); |
|
413 return d; |
|
414 }, |
|
415 |
|
416 /** @id MochiKit.Async.wait */ |
|
417 wait: function (seconds, /* optional */value) { |
|
418 var d = new MochiKit.Async.Deferred(); |
|
419 var m = MochiKit.Base; |
|
420 if (typeof(value) != 'undefined') { |
|
421 d.addCallback(function () { return value; }); |
|
422 } |
|
423 var timeout = setTimeout( |
|
424 m.bind("callback", d), |
|
425 Math.floor(seconds * 1000)); |
|
426 d.canceller = function () { |
|
427 try { |
|
428 clearTimeout(timeout); |
|
429 } catch (e) { |
|
430 // pass |
|
431 } |
|
432 }; |
|
433 return d; |
|
434 }, |
|
435 |
|
436 /** @id MochiKit.Async.callLater */ |
|
437 callLater: function (seconds, func) { |
|
438 var m = MochiKit.Base; |
|
439 var pfunc = m.partial.apply(m, m.extend(null, arguments, 1)); |
|
440 return MochiKit.Async.wait(seconds).addCallback( |
|
441 function (res) { return pfunc(); } |
|
442 ); |
|
443 } |
|
444 }); |
|
445 |
|
446 |
|
447 /** @id MochiKit.Async.DeferredLock */ |
|
448 MochiKit.Async.DeferredLock = function () { |
|
449 this.waiting = []; |
|
450 this.locked = false; |
|
451 this.id = this._nextId(); |
|
452 }; |
|
453 |
|
454 MochiKit.Async.DeferredLock.prototype = { |
|
455 __class__: MochiKit.Async.DeferredLock, |
|
456 /** @id MochiKit.Async.DeferredLock.prototype.acquire */ |
|
457 acquire: function () { |
|
458 var d = new MochiKit.Async.Deferred(); |
|
459 if (this.locked) { |
|
460 this.waiting.push(d); |
|
461 } else { |
|
462 this.locked = true; |
|
463 d.callback(this); |
|
464 } |
|
465 return d; |
|
466 }, |
|
467 /** @id MochiKit.Async.DeferredLock.prototype.release */ |
|
468 release: function () { |
|
469 if (!this.locked) { |
|
470 throw TypeError("Tried to release an unlocked DeferredLock"); |
|
471 } |
|
472 this.locked = false; |
|
473 if (this.waiting.length > 0) { |
|
474 this.locked = true; |
|
475 this.waiting.shift().callback(this); |
|
476 } |
|
477 }, |
|
478 _nextId: MochiKit.Base.counter(), |
|
479 repr: function () { |
|
480 var state; |
|
481 if (this.locked) { |
|
482 state = 'locked, ' + this.waiting.length + ' waiting'; |
|
483 } else { |
|
484 state = 'unlocked'; |
|
485 } |
|
486 return 'DeferredLock(' + this.id + ', ' + state + ')'; |
|
487 }, |
|
488 toString: MochiKit.Base.forwardCall("repr") |
|
489 |
|
490 }; |
|
491 |
|
492 /** @id MochiKit.Async.DeferredList */ |
|
493 MochiKit.Async.DeferredList = function (list, /* optional */fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller) { |
|
494 |
|
495 // call parent constructor |
|
496 MochiKit.Async.Deferred.apply(this, [canceller]); |
|
497 |
|
498 this.list = list; |
|
499 var resultList = []; |
|
500 this.resultList = resultList; |
|
501 |
|
502 this.finishedCount = 0; |
|
503 this.fireOnOneCallback = fireOnOneCallback; |
|
504 this.fireOnOneErrback = fireOnOneErrback; |
|
505 this.consumeErrors = consumeErrors; |
|
506 |
|
507 var cb = MochiKit.Base.bind(this._cbDeferred, this); |
|
508 for (var i = 0; i < list.length; i++) { |
|
509 var d = list[i]; |
|
510 resultList.push(undefined); |
|
511 d.addCallback(cb, i, true); |
|
512 d.addErrback(cb, i, false); |
|
513 } |
|
514 |
|
515 if (list.length === 0 && !fireOnOneCallback) { |
|
516 this.callback(this.resultList); |
|
517 } |
|
518 |
|
519 }; |
|
520 |
|
521 MochiKit.Async.DeferredList.prototype = new MochiKit.Async.Deferred(); |
|
522 |
|
523 MochiKit.Async.DeferredList.prototype._cbDeferred = function (index, succeeded, result) { |
|
524 this.resultList[index] = [succeeded, result]; |
|
525 this.finishedCount += 1; |
|
526 if (this.fired == -1) { |
|
527 if (succeeded && this.fireOnOneCallback) { |
|
528 this.callback([index, result]); |
|
529 } else if (!succeeded && this.fireOnOneErrback) { |
|
530 this.errback(result); |
|
531 } else if (this.finishedCount == this.list.length) { |
|
532 this.callback(this.resultList); |
|
533 } |
|
534 } |
|
535 if (!succeeded && this.consumeErrors) { |
|
536 result = null; |
|
537 } |
|
538 return result; |
|
539 }; |
|
540 |
|
541 /** @id MochiKit.Async.gatherResults */ |
|
542 MochiKit.Async.gatherResults = function (deferredList) { |
|
543 var d = new MochiKit.Async.DeferredList(deferredList, false, true, false); |
|
544 d.addCallback(function (results) { |
|
545 var ret = []; |
|
546 for (var i = 0; i < results.length; i++) { |
|
547 ret.push(results[i][1]); |
|
548 } |
|
549 return ret; |
|
550 }); |
|
551 return d; |
|
552 }; |
|
553 |
|
554 /** @id MochiKit.Async.maybeDeferred */ |
|
555 MochiKit.Async.maybeDeferred = function (func) { |
|
556 var self = MochiKit.Async; |
|
557 var result; |
|
558 try { |
|
559 var r = func.apply(null, MochiKit.Base.extend([], arguments, 1)); |
|
560 if (r instanceof self.Deferred) { |
|
561 result = r; |
|
562 } else if (r instanceof Error) { |
|
563 result = self.fail(r); |
|
564 } else { |
|
565 result = self.succeed(r); |
|
566 } |
|
567 } catch (e) { |
|
568 result = self.fail(e); |
|
569 } |
|
570 return result; |
|
571 }; |
|
572 |
|
573 |
|
574 MochiKit.Async.EXPORT = [ |
|
575 "AlreadyCalledError", |
|
576 "CancelledError", |
|
577 "BrowserComplianceError", |
|
578 "GenericError", |
|
579 "XMLHttpRequestError", |
|
580 "Deferred", |
|
581 "succeed", |
|
582 "fail", |
|
583 "getXMLHttpRequest", |
|
584 "doSimpleXMLHttpRequest", |
|
585 "loadJSONDoc", |
|
586 "wait", |
|
587 "callLater", |
|
588 "sendXMLHttpRequest", |
|
589 "DeferredLock", |
|
590 "DeferredList", |
|
591 "gatherResults", |
|
592 "maybeDeferred", |
|
593 "doXHR" |
|
594 ]; |
|
595 |
|
596 MochiKit.Async.EXPORT_OK = [ |
|
597 "evalJSONRequest" |
|
598 ]; |
|
599 |
|
600 MochiKit.Async.__new__ = function () { |
|
601 var m = MochiKit.Base; |
|
602 var ne = m.partial(m._newNamedError, this); |
|
603 |
|
604 ne("AlreadyCalledError", |
|
605 /** @id MochiKit.Async.AlreadyCalledError */ |
|
606 function (deferred) { |
|
607 /*** |
|
608 |
|
609 Raised by the Deferred if callback or errback happens |
|
610 after it was already fired. |
|
611 |
|
612 ***/ |
|
613 this.deferred = deferred; |
|
614 } |
|
615 ); |
|
616 |
|
617 ne("CancelledError", |
|
618 /** @id MochiKit.Async.CancelledError */ |
|
619 function (deferred) { |
|
620 /*** |
|
621 |
|
622 Raised by the Deferred cancellation mechanism. |
|
623 |
|
624 ***/ |
|
625 this.deferred = deferred; |
|
626 } |
|
627 ); |
|
628 |
|
629 ne("BrowserComplianceError", |
|
630 /** @id MochiKit.Async.BrowserComplianceError */ |
|
631 function (msg) { |
|
632 /*** |
|
633 |
|
634 Raised when the JavaScript runtime is not capable of performing |
|
635 the given function. Technically, this should really never be |
|
636 raised because a non-conforming JavaScript runtime probably |
|
637 isn't going to support exceptions in the first place. |
|
638 |
|
639 ***/ |
|
640 this.message = msg; |
|
641 } |
|
642 ); |
|
643 |
|
644 ne("GenericError", |
|
645 /** @id MochiKit.Async.GenericError */ |
|
646 function (msg) { |
|
647 this.message = msg; |
|
648 } |
|
649 ); |
|
650 |
|
651 ne("XMLHttpRequestError", |
|
652 /** @id MochiKit.Async.XMLHttpRequestError */ |
|
653 function (req, msg) { |
|
654 /*** |
|
655 |
|
656 Raised when an XMLHttpRequest does not complete for any reason. |
|
657 |
|
658 ***/ |
|
659 this.req = req; |
|
660 this.message = msg; |
|
661 try { |
|
662 // Strange but true that this can raise in some cases. |
|
663 this.number = req.status; |
|
664 } catch (e) { |
|
665 // pass |
|
666 } |
|
667 } |
|
668 ); |
|
669 |
|
670 |
|
671 this.EXPORT_TAGS = { |
|
672 ":common": this.EXPORT, |
|
673 ":all": m.concat(this.EXPORT, this.EXPORT_OK) |
|
674 }; |
|
675 |
|
676 m.nameFunctions(this); |
|
677 |
|
678 }; |
|
679 |
|
680 MochiKit.Async.__new__(); |
|
681 |
|
682 MochiKit.Base._exportSymbols(this, MochiKit.Async); |