Diffstat (limited to 'frontend/gamma/js/MochiKit/Async.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/gamma/js/MochiKit/Async.js | 120 |
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 | ||
3 | MochiKit.Async 1.5 | 3 | MochiKit.Async 1.5 |
4 | 4 | ||
5 | See <http://mochikit.com/> for documentation, downloads, license, etc. | 5 | See <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 | ||
11 | MochiKit.Base._module('Async', '1.5', ['Base']); | 11 | MochiKit.Base.module(MochiKit, 'Async', '1.5', ['Base']); |
12 | 12 | ||
13 | /** @id MochiKit.Async.Deferred */ | 13 | /** @id MochiKit.Async.Deferred */ |
14 | MochiKit.Async.Deferred = function (/* optional */ canceller) { | 14 | MochiKit.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 | ||
25 | MochiKit.Async.Deferred.prototype = { | 26 | MochiKit.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 | ||
190 | MochiKit.Base.update(MochiKit.Async, { | 223 | MochiKit.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 */ |
439 | MochiKit.Async.DeferredLock = function () { | 504 | MochiKit.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 | ||
512 | MochiKit.Async.DeferredList.prototype = new MochiKit.Async.Deferred(); | 577 | MochiKit.Async.DeferredList.prototype = new MochiKit.Async.Deferred(); |
578 | MochiKit.Async.DeferredList.prototype.constructor = MochiKit.Async.DeferredList; | ||
513 | 579 | ||
514 | MochiKit.Async.DeferredList.prototype._cbDeferred = function (index, succeeded, result) { | 580 | MochiKit.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 */ |
533 | MochiKit.Async.gatherResults = function (deferredList) { | 599 | MochiKit.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 = []; |