summaryrefslogtreecommitdiff
path: root/frontend/delta/js/Clipperz/Async.js
Unidiff
Diffstat (limited to 'frontend/delta/js/Clipperz/Async.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/Clipperz/Async.js707
1 files changed, 707 insertions, 0 deletions
diff --git a/frontend/delta/js/Clipperz/Async.js b/frontend/delta/js/Clipperz/Async.js
new file mode 100644
index 0000000..971fde5
--- a/dev/null
+++ b/frontend/delta/js/Clipperz/Async.js
@@ -0,0 +1,707 @@
1/*
2
3Copyright 2008-2013 Clipperz Srl
4
5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please
7refer to http://www.clipperz.com.
8
9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details.
18
19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21
22*/
23
24//Clipperz.Async = MochiKit.Async;
25
26
27if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
28if (typeof(Clipperz.Async) == 'undefined') { Clipperz.Async = {}; }
29
30Clipperz.Async.VERSION = "0.1";
31Clipperz.Async.NAME = "Clipperz.Async";
32
33Clipperz.Async.Deferred = function(aName, args) {
34 args = args || {};
35
36 Clipperz.Async.Deferred.superclass.constructor.call(this, args.canceller);
37
38 this._args = args;
39 this._name = aName || "Anonymous deferred";
40 this._count = 0;
41 this._shouldTrace = ((CLIPPERZ_DEFERRED_TRACING_ENABLED === true) || (args.trace === true));
42 this._vars = null;
43
44 return this;
45}
46
47//=============================================================================
48
49Clipperz.Base.extend(Clipperz.Async.Deferred, MochiKit.Async.Deferred, {
50
51 'name': function () {
52 return this._name;
53 },
54
55 'args': function () {
56 return this._args;
57 },
58
59 //-----------------------------------------------------------------------------
60
61 'callback': function (aValue) {
62 if (this._shouldTrace) {
63 Clipperz.log("CALLBACK " + this._name, aValue);
64 }
65
66 if (this.chained == false) {
67 var message;
68
69 message = "ERROR [" + this._name + "]";
70 this.addErrback(function(aResult) {
71 if (! (aResult instanceof MochiKit.Async.CancelledError)) {
72 Clipperz.log(message, aResult);
73 }
74 return aResult;
75 });
76
77 if (this._shouldTrace) {
78 var resultMessage;
79
80 resultMessage = "RESULT " + this._name + " <==";
81 // this.addCallback(function(aResult) {
82 Clipperz.Async.Deferred.superclass.addCallback.call(this, function(aResult) {
83 Clipperz.log(resultMessage, aResult);
84 return aResult;
85 });
86 }
87 }
88
89 if (CLIPPERZ_DEFERRED_CALL_LOGGING_ENABLED === true) {
90 Clipperz.log("callback " + this._name, this);
91 }
92
93 return Clipperz.Async.Deferred.superclass.callback.apply(this, arguments);
94 },
95
96 //-----------------------------------------------------------------------------
97
98 'addCallback': function () {
99 var message;
100
101 if (this._shouldTrace) {
102 this._count ++;
103 message = "[" + this._count + "] " + this._name + " ";
104 // this.addBoth(function(aResult) {Clipperz.log(message + "-->", aResult); return aResult;});
105 this.addCallbacks(
106 function(aResult) {Clipperz.log("-OK- " + message + "-->"/*, aResult*/); return aResult;},
107 function(aResult) {Clipperz.log("FAIL " + message + "-->"/*, aResult*/); return aResult;}
108 );
109 }
110
111 Clipperz.Async.Deferred.superclass.addCallback.apply(this, arguments);
112
113 if (this._shouldTrace) {
114 // this.addBoth(function(aResult) {Clipperz.log(message + "<--", aResult); return aResult;});
115 this.addCallbacks(
116 function(aResult) {Clipperz.log("-OK- " + message + "<--", aResult); return aResult;},
117 function(aResult) {Clipperz.log("FAIL " + message + "<--", aResult); return aResult;}
118 );
119 }
120 },
121
122 //=============================================================================
123
124 'addCallbackPass': function() {
125 var passFunction;
126
127 passFunction = MochiKit.Base.partial.apply(null, arguments);
128
129 this.addCallback(function() {
130 var result;
131
132 result = arguments[arguments.length -1];
133 passFunction();
134
135 return result;
136 });
137 },
138
139 //-----------------------------------------------------------------------------
140
141 'addErrbackPass': function() {
142 var passFunction;
143
144 passFunction = MochiKit.Base.partial.apply(null, arguments);
145
146 this.addErrback(function() {
147 var result;
148
149 result = arguments[arguments.length -1];
150 passFunction();
151
152 return result;
153 });
154 },
155
156 //-----------------------------------------------------------------------------
157
158 'addBothPass': function() {
159 var passFunction;
160
161 passFunction = MochiKit.Base.partial.apply(null, arguments);
162
163 this.addBoth(function() {
164 var result;
165
166 result = arguments[arguments.length -1];
167 passFunction();
168
169 return result;
170 });
171 },
172
173 //-----------------------------------------------------------------------------
174
175 'addIf': function (aThenBlock, anElseBlock) {
176 this.addCallback(MochiKit.Base.bind(function (aValue) {
177 var deferredResult;
178
179 if (!MochiKit.Base.isUndefinedOrNull(aValue) && aValue) {
180 deferredResult = Clipperz.Async.callbacks(this._name + " <then>", aThenBlock, null, aValue);
181 } else {
182 deferredResult = Clipperz.Async.callbacks(this._name + " <else>", anElseBlock, null, aValue);
183 }
184
185 return deferredResult;
186 }))
187 },
188
189 //-----------------------------------------------------------------------------
190
191 'addMethod': function () {
192 this.addCallback(MochiKit.Base.method.apply(this, arguments));
193 },
194
195 //-----------------------------------------------------------------------------
196
197 'addMethodcaller': function () {
198 this.addCallback(MochiKit.Base.methodcaller.apply(this, arguments));
199 },
200
201 //=============================================================================
202
203 'addLog': function (aLog) {
204 if (CLIPPERZ_DEFERRED_LOGGING_ENABLED) {
205 this.addBothPass(function(res) {Clipperz.log(aLog + " ", res);});
206 }
207 },
208
209 //=============================================================================
210
211 'acquireLock': function (aLock) {
212 // this.addCallback(function (aResult) {
213 // return Clipperz.Async.callbacks("Clipperz.Async.acquireLock", [
214 // MochiKit.Base.method(aLock, 'acquire'),
215 // MochiKit.Base.partial(MochiKit.Async.succeed, aResult)
216 // ], {trace:false});
217 // });
218
219 this.addCallback(MochiKit.Base.method(aLock, 'acquire'));
220 },
221
222 'releaseLock': function (aLock) {
223 // this.addCallback(function (aResult) {
224 // return Clipperz.Async.callbacks("Clipperz.Async.release <ok>", [
225 // MochiKit.Base.method(aLock, 'release'),
226 // MochiKit.Base.partial(MochiKit.Async.succeed, aResult)
227 // ], {trace:false});
228 // });
229 // this.addErrback(function (aResult) {
230///Clipperz.log("releaseLock.addErrback:", aResult);
231 // return Clipperz.Async.callbacks("Clipperz.Async.release <fail>", [
232 // MochiKit.Base.method(aLock, 'release'),
233 // MochiKit.Base.partial(MochiKit.Async.fail, aResult)
234 // ], {trace:false});
235 // });
236
237 // this.addBothPass(MochiKit.Base.method(aLock, 'release'));
238 this.addCallbackPass(MochiKit.Base.method(aLock, 'release'));
239 this.addErrback(function (anError) {
240 aLock.release();
241
242 return anError;
243 });
244 },
245
246 //=============================================================================
247
248 'collectResults': function (someRequests) {
249 this.addCallback(Clipperz.Async.collectResults(this._name + " <collect results>", someRequests, this._args));
250 },
251
252 'addCallbackList': function (aRequestList) {
253 this.addCallback(Clipperz.Async.callbacks, this._name + " <callback list>", aRequestList, this._args);
254 },
255
256 //=============================================================================
257
258 'vars': function () {
259 if (this._vars == null) {
260 this._vars = {}
261 }
262
263 return this._vars;
264 },
265
266 'setValue': function (aKey) {
267 this.addCallback(MochiKit.Base.bind(function (aValue) {
268 this.vars()[aKey] = aValue;
269 return aValue;
270 }, this));
271 },
272
273 'getValue': function (aKey) {
274 this.addCallback(MochiKit.Base.bind(function () {
275 return this.vars()[aKey];
276 }, this));
277 },
278
279 //=============================================================================
280
281 'wait': function (someSeconds) {
282 this.addCallback(MochiKit.Async.wait, someSeconds);
283 },
284
285 //=============================================================================
286
287 __syntaxFix__: "syntax fix"
288});
289
290//#############################################################################
291
292Clipperz.Async.DeferredSynchronizer = function(aName, someMethods) {
293 this._name = aName || "Anonymous deferred Synchronizer";
294 this._methods = someMethods;
295
296 this._numberOfMethodsDone= 0;
297 this._methodResults = [];
298
299 this._result = new Clipperz.Async.Deferred("Clipperz.Async.DeferredSynchronizer # " + this.name(), {trace:false});
300 this._result.addMethod(this, 'methodResults');
301 this._result.addCallback(function(someResults) {
302 varcancels;
303 var errors;
304 var result;
305
306 cancels = MochiKit.Base.filter(function(aResult) { return (aResult instanceof MochiKit.Async.CancelledError)}, someResults);
307
308 if (cancels.length == 0) {
309 errors = MochiKit.Base.filter(function(aResult) { return (aResult instanceof Error)}, someResults);
310
311 if (errors.length == 0) {
312 // result = MochiKit.Async.succeed(someResults);
313 result = someResults;
314 } else {
315 result = MochiKit.Async.fail(someResults);
316 }
317 } else {
318 result = MochiKit.Async.fail(cancels[0]);
319 }
320
321 return result;
322 }/*, this._methodResults */);
323
324 return this;
325}
326
327MochiKit.Base.update(Clipperz.Async.DeferredSynchronizer.prototype, {
328
329 //-----------------------------------------------------------------------------
330
331 'name': function() {
332 return this._name;
333 },
334
335 //-----------------------------------------------------------------------------
336
337 'methods': function() {
338 return this._methods;
339 },
340
341 'methodResults': function() {
342 return this._methodResults;
343 },
344
345 //-----------------------------------------------------------------------------
346
347 'result': function() {
348 return this._result;
349 },
350
351 //-----------------------------------------------------------------------------
352
353 'numberOfMethodsDone':function() {
354 return this._numberOfMethodsDone;
355 },
356
357 'incrementNumberOfMethodsDone': function() {
358 this._numberOfMethodsDone ++;
359 },
360
361 //-----------------------------------------------------------------------------
362
363 'run': function(args, aValue) {
364 var deferredResults;
365 var i, c;
366
367 deferredResults = [];
368 args = args || {};
369
370 c = this.methods().length;
371 for (i=0; i<c; i++) {
372 var deferredResult;
373 varmethodCalls;
374 var ii, cc;
375
376//Clipperz.log("TYPEOF", typeof(this.methods()[i]));
377 if (typeof(this.methods()[i]) == 'function') {
378 methodCalls = [ this.methods()[i] ];
379 } else {
380 methodCalls = this.methods()[i];
381 }
382
383 cc = methodCalls.length;
384 deferredResult = new Clipperz.Async.Deferred("Clipperz.Async.DeferredSynchronizer.run => " + this.name() + "[" + i + "]", args);
385 for (ii=0; ii<cc; ii++) {
386 deferredResult.addCallback(methodCalls[ii]);
387 }
388 deferredResult.addBoth(MochiKit.Base.method(this, 'handleMethodCallDone', i));
389
390 deferredResults.push(deferredResult);
391 }
392
393 for (i=0; i<c; i++) {
394 deferredResults[i].callback(aValue);
395 }
396
397 return this.result();
398 },
399
400 //-----------------------------------------------------------------------------
401
402 'handleMethodCallDone': function(anIndexValue, aResult) {
403 this.incrementNumberOfMethodsDone();
404 this.methodResults()[anIndexValue] = aResult;
405
406 if (this.numberOfMethodsDone() < this.methods().length) {
407 //nothing to do here other than possibly log something
408 } else if (this.numberOfMethodsDone() == this.methods().length) {
409 this.result().callback();
410 } else if (this.numberOfMethodsDone() > this.methods().length) {
411 alert("Clipperz.Async.Deferred.handleMethodCallDone -> WTF!");
412 //WTF!!! :(
413 }
414
415 },
416
417 //-----------------------------------------------------------------------------
418
419 __syntaxFix__: "syntax fix"
420});
421
422//#############################################################################
423
424MochiKit.Base.update(Clipperz.Async, {
425
426 'callbacks': function (aName, someFunctions, someArguments, aCallbackValue) {
427 var deferredResult;
428 var i, c;
429
430 deferredResult = new Clipperz.Async.Deferred(aName, someArguments);
431 c = someFunctions.length;
432 for (i=0; i<c; i++) {
433 deferredResult.addCallback(someFunctions[i]);
434 }
435 deferredResult.callback(aCallbackValue);
436
437 return deferredResult;
438 },
439
440 //-------------------------------------------------------------------------
441
442 'forkAndJoin': function (aName, someMethods, args) {
443 return MochiKit.Base.partial(function (aName, someMethods, args, aValue) {
444 var synchronizer;
445 varresult;
446
447 args = args || {};
448 synchronizer = new Clipperz.Async.DeferredSynchronizer(aName, someMethods);
449 result = synchronizer.run(args, aValue);
450
451 return result;
452 }, aName, someMethods, args);
453 },
454
455 //-------------------------------------------------------------------------
456
457 'collectResults': function(aName, someRequests, args) {
458 return MochiKit.Base.partial(function(aName, someRequests, args, aValue) {
459 var deferredResult;
460 var requestKeys;
461 var methods;
462
463 requestKeys = MochiKit.Base.keys(someRequests);
464 methods = MochiKit.Base.values(someRequests);
465
466 deferredResult = new Clipperz.Async.Deferred(aName, args);
467 deferredResult.addCallback(Clipperz.Async.forkAndJoin(aName + " [inner forkAndJoin]", methods, args));
468 deferredResult.addBoth(function(someResults) {
469 var returnFunction;
470 var results;
471 var i,c;
472 var result;
473
474 if (someResults instanceof MochiKit.Async.CancelledError) {
475 returnFunction = MochiKit.Async.fail;
476 result = someResults;
477 } else {
478 if (someResults instanceof Error) {
479 returnFunction = MochiKit.Async.fail;
480 results = someResults['message'];
481 } else {
482 returnFunction = MochiKit.Async.succeed;
483 results = someResults;
484 }
485
486 result = {};
487
488 c = requestKeys.length;
489 for (i=0; i<c; i++) {
490 result[requestKeys[i]] = results[i];
491 }
492 }
493
494 return returnFunction.call(null, result);
495 });
496 deferredResult.callback(aValue);
497
498 return deferredResult;
499 }, aName, someRequests, args);
500 },
501
502 //-------------------------------------------------------------------------
503
504 'collectAll': function (someDeferredObjects) {
505 var deferredResult;
506
507 deferredResult = new MochiKit.Async.DeferredList(someDeferredObjects, false, false, false);
508 deferredResult.addCallback(function (aResultList) {
509 return MochiKit.Base.map(function (aResult) {
510 if (aResult[0]) {
511 return aResult[1];
512 } else {
513 throw aResult[1];
514 }
515 }, aResultList);
516 });
517
518 return deferredResult;
519 },
520
521 //-------------------------------------------------------------------------
522
523 'setItem': function (anObject, aKey, aValue) {
524 anObject[aKey] = aValue;
525
526 return anObject;
527 },
528
529 'setItemOnObject': function (aKey, aValue, anObject) {
530 anObject[aKey] = aValue;
531
532 return anObject;
533 },
534
535 'setDeferredItemOnObject': function (aKey, aDeferredFunction, anObject) {
536 return Clipperz.Async.callbacks("Clipperz.Async.setDeferredItemOnObject", [
537 aDeferredFunction,
538 MochiKit.Base.partial(Clipperz.Async.setItem, anObject, aKey)
539 ], {trace:false}, anObject);
540 },
541
542 //-------------------------------------------------------------------------
543
544 'deferredIf': function (aName, aThenBlock, anElseBlock) {
545 return function (aValue) {
546 var deferredResult;
547
548 if (!MochiKit.Base.isUndefinedOrNull(aValue) && aValue) {
549 deferredResult = Clipperz.Async.callbacks(aName + " <then>", aThenBlock, null, aValue);
550 } else {
551 deferredResult = Clipperz.Async.callbacks(aName + " <else>", anElseBlock, null, aValue);
552 }
553
554 return deferredResult;
555 }
556 },
557
558 //-------------------------------------------------------------------------
559
560 'log': function(aMessage, aResult) {
561 if (CLIPPERZ_DEFERRED_LOGGING_ENABLED) {
562 Clipperz.log(aMessage + " ", aResult);
563 }
564
565 return aResult;
566 },
567
568 //=========================================================================
569
570 'deferredCompare': function (aComparator, aDeferred, bDeferred) {
571 var deferredResult;
572
573 deferredResult = new Clipperz.Async.Deferred("Clipperz.Async.deferredCompare", {trace:false});
574 deferredResult.addCallback(Clipperz.Async.collectAll, [aDeferred, bDeferred]);
575 deferredResult.addCallback(function (someResults) {
576 var result;
577
578 if (aComparator(someResults[0], someResults[1]) > 0) {
579 result = MochiKit.Async.succeed();
580 } else {
581 result = MochiKit.Async.fail();
582 };
583
584 return result;
585 });
586 deferredResult.callback();
587
588 return deferredResult;
589 },
590
591 //-------------------------------------------------------------------------
592
593 'insertIntoSortedArray': function (anObject, aDeferredComparator, aSortedResult) {
594 var deferredResult;
595 var i, c;
596
597 if (aSortedResult.length == 0) {
598 deferredResult = MochiKit.Async.succeed([anObject]);
599 } else {
600 deferredResult = new Clipperz.Async.Deferred("Clipperz.Async.insertIntoSortedArray", {trace:false});
601 c = aSortedResult.length + 1;
602 for (i=0; i<c; i++) {
603 deferredResult.addCallback(function (aDeferredComparator, aObject, bObject, aContext) {
604 var innerDeferredResult;
605
606 innerDeferredResult = new Clipperz.Async.Deferred("Clipperz.Async.insertIntoSortedArray <inner compare>", {trace:false});
607 innerDeferredResult.addCallback(aDeferredComparator, aObject, bObject);
608 innerDeferredResult.addErrback(MochiKit.Async.fail, aContext);
609 innerDeferredResult.callback();
610
611 return innerDeferredResult;
612 }, aDeferredComparator, anObject, aSortedResult[i], i);
613 }
614 deferredResult.addMethod(aSortedResult, 'push', anObject);
615 deferredResult.addErrback(function (anError) {
616 aSortedResult.splice(anError.message, 0, anObject);
617 })
618 deferredResult.addBoth(MochiKit.Async.succeed, aSortedResult);
619 deferredResult.callback();
620 }
621
622 return deferredResult;
623 },
624
625 //-------------------------------------------------------------------------
626
627 'deferredSort': function (aDeferredComparator, someObjects) {
628 var deferredResult;
629 var i, c;
630
631 deferredResult = new Clipperz.Async.Deferred("Clipperz.Async.deferredSort", {trace:false});
632 c = someObjects.length;
633 for (i=0; i<c; i++) {
634 deferredResult.addCallback(Clipperz.Async.insertIntoSortedArray, someObjects[i], aDeferredComparator);
635 if ((i % 50) == 0) {
636 //Clipperz.log("######### sort wait ##########");
637 deferredResult.addCallback(MochiKit.Async.wait, 0.5);
638 }
639 }
640 deferredResult.callback([]);
641
642 return deferredResult;
643 },
644
645 //=========================================================================
646
647 'deferredFilter': function (aFunction, someObjects) {
648 vardeferredResult;
649 vari, c;
650
651 deferredResult = new Clipperz.Async.Deferred("Clipperz.Async.deferredFilter", {trace:false});
652 c = someObjects.length;
653 for (i=0; i<c; i++) {
654 deferredResult.addCallback(function (aFunction, anObject, anIndex, aResult) {
655 var innerDeferredResult;
656
657 innerDeferredResult = new Clipperz.Async.Deferred("Clipperz.Async.deferredFilter <inner - " + anIndex + ">", {trace:false});
658 innerDeferredResult.addCallback(aFunction, anObject);
659 innerDeferredResult.addCallback(function (aFilterResult) {
660 if (aFilterResult) {
661 aResult.push(anObject);
662 };
663 });
664 innerDeferredResult.addBoth(MochiKit.Async.succeed, aResult);
665 innerDeferredResult.callback();
666
667 return innerDeferredResult;
668 }, aFunction, someObjects[i], i);
669 }
670 deferredResult.callback([]);
671
672 return deferredResult;
673 },
674
675 'forEach': function (aFunction) {
676 return MochiKit.Base.partial(function (aFunction, anIterable) {
677 MochiKit.Iter.forEach(anIterable, aFunction);
678 }, aFunction);
679 },
680
681 //=========================================================================
682
683 'or': function (someValues) {
684 return Clipperz.Async.callbacks("Clipperz.Async.or", [
685 MochiKit.Base.values,
686 MochiKit.Base.flattenArguments,
687//function (aValue) { Clipperz.log("Record.hasAnyCleanTextData - flatten", aValue); return aValue; },
688 function(someInnerValues) {
689 return MochiKit.Iter.some(someInnerValues, MochiKit.Base.operator.identity);
690 }
691 ], {trace:false}, someValues);
692 },
693
694 //=========================================================================
695
696 'clearResult': function () {},
697
698 //=========================================================================
699 __syntaxFix__: "syntax fix"
700});
701
702
703//#############################################################################
704
705CLIPPERZ_DEFERRED_LOGGING_ENABLED = true;
706CLIPPERZ_DEFERRED_TRACING_ENABLED = false;
707CLIPPERZ_DEFERRED_CALL_LOGGING_ENABLED = false;