summaryrefslogtreecommitdiff
path: root/frontend/delta/js/MochiKit/Iter.js
Unidiff
Diffstat (limited to 'frontend/delta/js/MochiKit/Iter.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/MochiKit/Iter.js811
1 files changed, 811 insertions, 0 deletions
diff --git a/frontend/delta/js/MochiKit/Iter.js b/frontend/delta/js/MochiKit/Iter.js
new file mode 100644
index 0000000..8f7ea3d
--- a/dev/null
+++ b/frontend/delta/js/MochiKit/Iter.js
@@ -0,0 +1,811 @@
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/***
25
26MochiKit.Iter 1.5
27
28See <http://mochikit.com/> for documentation, downloads, license, etc.
29
30(c) 2005 Bob Ippolito. All rights Reserved.
31
32***/
33
34MochiKit.Base.module(MochiKit, 'Iter', '1.5', ['Base']);
35
36MochiKit.Base.update(MochiKit.Iter, {
37 /** @id MochiKit.Iter.registerIteratorFactory */
38 registerIteratorFactory: function (name, check, iterfactory, /* optional */ override) {
39 MochiKit.Iter.iteratorRegistry.register(name, check, iterfactory, override);
40 },
41
42 /** @id MochiKit.Iter.isIterable */
43 isIterable: function(o) {
44 return o != null &&
45 (typeof(o.next) == "function" || typeof(o.iter) == "function");
46 },
47
48 /** @id MochiKit.Iter.iter */
49 iter: function (iterable, /* optional */ sentinel) {
50 var self = MochiKit.Iter;
51 if (arguments.length == 2) {
52 return self.takewhile(
53 function (a) { return a != sentinel; },
54 iterable
55 );
56 }
57 if (typeof(iterable.next) == 'function') {
58 return iterable;
59 } else if (typeof(iterable.iter) == 'function') {
60 return iterable.iter();
61 /*
62 } else if (typeof(iterable.__iterator__) == 'function') {
63 //
64 // XXX: We can't support JavaScript 1.7 __iterator__ directly
65 // because of Object.prototype.__iterator__
66 //
67 return iterable.__iterator__();
68 */
69 }
70
71 try {
72 return self.iteratorRegistry.match(iterable);
73 } catch (e) {
74 var m = MochiKit.Base;
75 if (e == m.NotFound) {
76 e = new TypeError(typeof(iterable) + ": " + m.repr(iterable) + " is not iterable");
77 }
78 throw e;
79 }
80 },
81
82 /** @id MochiKit.Iter.count */
83 count: function (n) {
84 if (!n) {
85 n = 0;
86 }
87 var m = MochiKit.Base;
88 return {
89 repr: function () { return "count(" + n + ")"; },
90 toString: m.forwardCall("repr"),
91 next: m.counter(n)
92 };
93 },
94
95 /** @id MochiKit.Iter.cycle */
96 cycle: function (p) {
97 var self = MochiKit.Iter;
98 var m = MochiKit.Base;
99 var lst = [];
100 var iterator = self.iter(p);
101 return {
102 repr: function () { return "cycle(...)"; },
103 toString: m.forwardCall("repr"),
104 next: function () {
105 try {
106 var rval = iterator.next();
107 lst.push(rval);
108 return rval;
109 } catch (e) {
110 if (e != self.StopIteration) {
111 throw e;
112 }
113 if (lst.length === 0) {
114 this.next = function () {
115 throw self.StopIteration;
116 };
117 } else {
118 var i = -1;
119 this.next = function () {
120 i = (i + 1) % lst.length;
121 return lst[i];
122 };
123 }
124 return this.next();
125 }
126 }
127 };
128 },
129
130 /** @id MochiKit.Iter.repeat */
131 repeat: function (elem, /* optional */n) {
132 var m = MochiKit.Base;
133 if (typeof(n) == 'undefined') {
134 return {
135 repr: function () {
136 return "repeat(" + m.repr(elem) + ")";
137 },
138 toString: m.forwardCall("repr"),
139 next: function () {
140 return elem;
141 }
142 };
143 }
144 return {
145 repr: function () {
146 return "repeat(" + m.repr(elem) + ", " + n + ")";
147 },
148 toString: m.forwardCall("repr"),
149 next: function () {
150 if (n <= 0) {
151 throw MochiKit.Iter.StopIteration;
152 }
153 n -= 1;
154 return elem;
155 }
156 };
157 },
158
159 /** @id MochiKit.Iter.next */
160 next: function (iterator) {
161 return iterator.next();
162 },
163
164 /** @id MochiKit.Iter.izip */
165 izip: function (p, q/*, ...*/) {
166 var m = MochiKit.Base;
167 var self = MochiKit.Iter;
168 var next = self.next;
169 var iterables = m.map(self.iter, arguments);
170 return {
171 repr: function () { return "izip(...)"; },
172 toString: m.forwardCall("repr"),
173 next: function () { return m.map(next, iterables); }
174 };
175 },
176
177 /** @id MochiKit.Iter.ifilter */
178 ifilter: function (pred, seq) {
179 var m = MochiKit.Base;
180 seq = MochiKit.Iter.iter(seq);
181 if (pred === null) {
182 pred = m.operator.truth;
183 }
184 return {
185 repr: function () { return "ifilter(...)"; },
186 toString: m.forwardCall("repr"),
187 next: function () {
188 while (true) {
189 var rval = seq.next();
190 if (pred(rval)) {
191 return rval;
192 }
193 }
194 // mozilla warnings aren't too bright
195 return undefined;
196 }
197 };
198 },
199
200 /** @id MochiKit.Iter.ifilterfalse */
201 ifilterfalse: function (pred, seq) {
202 var m = MochiKit.Base;
203 seq = MochiKit.Iter.iter(seq);
204 if (pred === null) {
205 pred = m.operator.truth;
206 }
207 return {
208 repr: function () { return "ifilterfalse(...)"; },
209 toString: m.forwardCall("repr"),
210 next: function () {
211 while (true) {
212 var rval = seq.next();
213 if (!pred(rval)) {
214 return rval;
215 }
216 }
217 // mozilla warnings aren't too bright
218 return undefined;
219 }
220 };
221 },
222
223 /** @id MochiKit.Iter.islice */
224 islice: function (seq/*, [start,] stop[, step] */) {
225 var self = MochiKit.Iter;
226 var m = MochiKit.Base;
227 seq = self.iter(seq);
228 var start = 0;
229 var stop = 0;
230 var step = 1;
231 var i = -1;
232 if (arguments.length == 2) {
233 stop = arguments[1];
234 } else if (arguments.length == 3) {
235 start = arguments[1];
236 stop = arguments[2];
237 } else {
238 start = arguments[1];
239 stop = arguments[2];
240 step = arguments[3];
241 }
242 return {
243 repr: function () {
244 return "islice(" + ["...", start, stop, step].join(", ") + ")";
245 },
246 toString: m.forwardCall("repr"),
247 next: function () {
248 if (start >= stop) {
249 throw self.StopIteration;
250 }
251
252 var rval;
253 while (i < start) {
254 rval = seq.next();
255 i++;
256 }
257 start += step;
258 return rval;
259 }
260 };
261 },
262
263 /** @id MochiKit.Iter.imap */
264 imap: function (fun, p, q/*, ...*/) {
265 var m = MochiKit.Base;
266 var self = MochiKit.Iter;
267 var iterables = m.map(self.iter, m.extend(null, arguments, 1));
268 var map = m.map;
269 var next = self.next;
270 return {
271 repr: function () { return "imap(...)"; },
272 toString: m.forwardCall("repr"),
273 next: function () {
274 return fun.apply(this, map(next, iterables));
275 }
276 };
277 },
278
279 /** @id MochiKit.Iter.applymap */
280 applymap: function (fun, seq, self) {
281 seq = MochiKit.Iter.iter(seq);
282 var m = MochiKit.Base;
283 return {
284 repr: function () { return "applymap(...)"; },
285 toString: m.forwardCall("repr"),
286 next: function () {
287 return fun.apply(self, seq.next());
288 }
289 };
290 },
291
292 /** @id MochiKit.Iter.chain */
293 chain: function (p, q/*, ...*/) {
294 // dumb fast path
295 var self = MochiKit.Iter;
296 var m = MochiKit.Base;
297 if (arguments.length == 1) {
298 return self.iter(arguments[0]);
299 }
300 var argiter = m.map(self.iter, arguments);
301 return {
302 repr: function () { return "chain(...)"; },
303 toString: m.forwardCall("repr"),
304 next: function () {
305 while (argiter.length > 1) {
306 try {
307 return argiter[0].next();
308 } catch (e) {
309 if (e != self.StopIteration) {
310 throw e;
311 }
312 argiter.shift();
313 }
314 }
315 if (argiter.length == 1) {
316 // optimize last element
317 var arg = argiter.shift();
318 this.next = m.bind("next", arg);
319 return this.next();
320 }
321 throw self.StopIteration;
322 }
323 };
324 },
325
326 /** @id MochiKit.Iter.takewhile */
327 takewhile: function (pred, seq) {
328 var self = MochiKit.Iter;
329 seq = self.iter(seq);
330 return {
331 repr: function () { return "takewhile(...)"; },
332 toString: MochiKit.Base.forwardCall("repr"),
333 next: function () {
334 var rval = seq.next();
335 if (!pred(rval)) {
336 this.next = function () {
337 throw self.StopIteration;
338 };
339 this.next();
340 }
341 return rval;
342 }
343 };
344 },
345
346 /** @id MochiKit.Iter.dropwhile */
347 dropwhile: function (pred, seq) {
348 seq = MochiKit.Iter.iter(seq);
349 var m = MochiKit.Base;
350 var bind = m.bind;
351 return {
352 "repr": function () { return "dropwhile(...)"; },
353 "toString": m.forwardCall("repr"),
354 "next": function () {
355 while (true) {
356 var rval = seq.next();
357 if (!pred(rval)) {
358 break;
359 }
360 }
361 this.next = bind("next", seq);
362 return rval;
363 }
364 };
365 },
366
367 _tee: function (ident, sync, iterable) {
368 sync.pos[ident] = -1;
369 var m = MochiKit.Base;
370 var listMin = m.listMin;
371 return {
372 repr: function () { return "tee(" + ident + ", ...)"; },
373 toString: m.forwardCall("repr"),
374 next: function () {
375 var rval;
376 var i = sync.pos[ident];
377
378 if (i == sync.max) {
379 rval = iterable.next();
380 sync.deque.push(rval);
381 sync.max += 1;
382 sync.pos[ident] += 1;
383 } else {
384 rval = sync.deque[i - sync.min];
385 sync.pos[ident] += 1;
386 if (i == sync.min && listMin(sync.pos) != sync.min) {
387 sync.min += 1;
388 sync.deque.shift();
389 }
390 }
391 return rval;
392 }
393 };
394 },
395
396 /** @id MochiKit.Iter.tee */
397 tee: function (iterable, n/* = 2 */) {
398 var rval = [];
399 var sync = {
400 "pos": [],
401 "deque": [],
402 "max": -1,
403 "min": -1
404 };
405 if (arguments.length == 1 || typeof(n) == "undefined" || n === null) {
406 n = 2;
407 }
408 var self = MochiKit.Iter;
409 iterable = self.iter(iterable);
410 var _tee = self._tee;
411 for (var i = 0; i < n; i++) {
412 rval.push(_tee(i, sync, iterable));
413 }
414 return rval;
415 },
416
417 /** @id MochiKit.Iter.list */
418 list: function (iterable) {
419 // Fast-path for Array and Array-like
420 var rval;
421 if (iterable instanceof Array) {
422 return iterable.slice();
423 }
424 // this is necessary to avoid a Safari crash
425 if (typeof(iterable) == "function" &&
426 !(iterable instanceof Function) &&
427 typeof(iterable.length) == 'number') {
428 rval = [];
429 for (var i = 0; i < iterable.length; i++) {
430 rval.push(iterable[i]);
431 }
432 return rval;
433 }
434
435 var self = MochiKit.Iter;
436 iterable = self.iter(iterable);
437 rval = [];
438 var a_val;
439 try {
440 while (true) {
441 a_val = iterable.next();
442 rval.push(a_val);
443 }
444 } catch (e) {
445 if (e != self.StopIteration) {
446 throw e;
447 }
448 return rval;
449 }
450 // mozilla warnings aren't too bright
451 return undefined;
452 },
453
454
455 /** @id MochiKit.Iter.reduce */
456 reduce: function (fn, iterable, /* optional */initial) {
457 var i = 0;
458 var x = initial;
459 var self = MochiKit.Iter;
460 iterable = self.iter(iterable);
461 if (arguments.length < 3) {
462 try {
463 x = iterable.next();
464 } catch (e) {
465 if (e == self.StopIteration) {
466 e = new TypeError("reduce() of empty sequence with no initial value");
467 }
468 throw e;
469 }
470 i++;
471 }
472 try {
473 while (true) {
474 x = fn(x, iterable.next());
475 }
476 } catch (e) {
477 if (e != self.StopIteration) {
478 throw e;
479 }
480 }
481 return x;
482 },
483
484 /** @id MochiKit.Iter.range */
485 range: function (/* [start,] stop[, step] */) {
486 var start = 0;
487 var stop = 0;
488 var step = 1;
489 if (arguments.length == 1) {
490 stop = arguments[0];
491 } else if (arguments.length == 2) {
492 start = arguments[0];
493 stop = arguments[1];
494 } else if (arguments.length == 3) {
495 start = arguments[0];
496 stop = arguments[1];
497 step = arguments[2];
498 } else {
499 throw new TypeError("range() takes 1, 2, or 3 arguments!");
500 }
501 if (step === 0) {
502 throw new TypeError("range() step must not be 0");
503 }
504 return {
505 next: function () {
506 if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
507 throw MochiKit.Iter.StopIteration;
508 }
509 var rval = start;
510 start += step;
511 return rval;
512 },
513 repr: function () {
514 return "range(" + [start, stop, step].join(", ") + ")";
515 },
516 toString: MochiKit.Base.forwardCall("repr")
517 };
518 },
519
520 /** @id MochiKit.Iter.sum */
521 sum: function (iterable, start/* = 0 */) {
522 if (typeof(start) == "undefined" || start === null) {
523 start = 0;
524 }
525 var x = start;
526 var self = MochiKit.Iter;
527 iterable = self.iter(iterable);
528 try {
529 while (true) {
530 x += iterable.next();
531 }
532 } catch (e) {
533 if (e != self.StopIteration) {
534 throw e;
535 }
536 }
537 return x;
538 },
539
540 /** @id MochiKit.Iter.exhaust */
541 exhaust: function (iterable) {
542 var self = MochiKit.Iter;
543 iterable = self.iter(iterable);
544 try {
545 while (true) {
546 iterable.next();
547 }
548 } catch (e) {
549 if (e != self.StopIteration) {
550 throw e;
551 }
552 }
553 },
554
555 /** @id MochiKit.Iter.forEach */
556 forEach: function (iterable, func, /* optional */obj) {
557 var m = MochiKit.Base;
558 var self = MochiKit.Iter;
559 if (arguments.length > 2) {
560 func = m.bind(func, obj);
561 }
562 // fast path for array
563 if (m.isArrayLike(iterable) && !self.isIterable(iterable)) {
564 try {
565 for (var i = 0; i < iterable.length; i++) {
566 func(iterable[i]);
567 }
568 } catch (e) {
569 if (e != self.StopIteration) {
570 throw e;
571 }
572 }
573 } else {
574 self.exhaust(self.imap(func, iterable));
575 }
576 },
577
578 /** @id MochiKit.Iter.every */
579 every: function (iterable, func) {
580 var self = MochiKit.Iter;
581 try {
582 self.ifilterfalse(func, iterable).next();
583 return false;
584 } catch (e) {
585 if (e != self.StopIteration) {
586 throw e;
587 }
588 return true;
589 }
590 },
591
592 /** @id MochiKit.Iter.sorted */
593 sorted: function (iterable, /* optional */cmp) {
594 var rval = MochiKit.Iter.list(iterable);
595 if (arguments.length == 1) {
596 cmp = MochiKit.Base.compare;
597 }
598 rval.sort(cmp);
599 return rval;
600 },
601
602 /** @id MochiKit.Iter.reversed */
603 reversed: function (iterable) {
604 var rval = MochiKit.Iter.list(iterable);
605 rval.reverse();
606 return rval;
607 },
608
609 /** @id MochiKit.Iter.some */
610 some: function (iterable, func) {
611 var self = MochiKit.Iter;
612 try {
613 self.ifilter(func, iterable).next();
614 return true;
615 } catch (e) {
616 if (e != self.StopIteration) {
617 throw e;
618 }
619 return false;
620 }
621 },
622
623 /** @id MochiKit.Iter.iextend */
624 iextend: function (lst, iterable) {
625 var m = MochiKit.Base;
626 var self = MochiKit.Iter;
627 if (m.isArrayLike(iterable) && !self.isIterable(iterable)) {
628 // fast-path for array-like
629 for (var i = 0; i < iterable.length; i++) {
630 lst.push(iterable[i]);
631 }
632 } else {
633 iterable = self.iter(iterable);
634 try {
635 while (true) {
636 lst.push(iterable.next());
637 }
638 } catch (e) {
639 if (e != self.StopIteration) {
640 throw e;
641 }
642 }
643 }
644 return lst;
645 },
646
647 /** @id MochiKit.Iter.groupby */
648 groupby: function(iterable, /* optional */ keyfunc) {
649 var m = MochiKit.Base;
650 var self = MochiKit.Iter;
651 if (arguments.length < 2) {
652 keyfunc = m.operator.identity;
653 }
654 iterable = self.iter(iterable);
655
656 // shared
657 var pk = undefined;
658 var k = undefined;
659 var v;
660
661 function fetch() {
662 v = iterable.next();
663 k = keyfunc(v);
664 };
665
666 function eat() {
667 var ret = v;
668 v = undefined;
669 return ret;
670 };
671
672 var first = true;
673 var compare = m.compare;
674 return {
675 repr: function () { return "groupby(...)"; },
676 next: function() {
677 // iterator-next
678
679 // iterate until meet next group
680 while (compare(k, pk) === 0) {
681 fetch();
682 if (first) {
683 first = false;
684 break;
685 }
686 }
687 pk = k;
688 return [k, {
689 next: function() {
690 // subiterator-next
691 if (v == undefined) { // Is there something to eat?
692 fetch();
693 }
694 if (compare(k, pk) !== 0) {
695 throw self.StopIteration;
696 }
697 return eat();
698 }
699 }];
700 }
701 };
702 },
703
704 /** @id MochiKit.Iter.groupby_as_array */
705 groupby_as_array: function (iterable, /* optional */ keyfunc) {
706 var m = MochiKit.Base;
707 var self = MochiKit.Iter;
708 if (arguments.length < 2) {
709 keyfunc = m.operator.identity;
710 }
711
712 iterable = self.iter(iterable);
713 var result = [];
714 var first = true;
715 var prev_key;
716 var compare = m.compare;
717 while (true) {
718 try {
719 var value = iterable.next();
720 var key = keyfunc(value);
721 } catch (e) {
722 if (e == self.StopIteration) {
723 break;
724 }
725 throw e;
726 }
727 if (first || compare(key, prev_key) !== 0) {
728 var values = [];
729 result.push([key, values]);
730 }
731 values.push(value);
732 first = false;
733 prev_key = key;
734 }
735 return result;
736 },
737
738 /** @id MochiKit.Iter.arrayLikeIter */
739 arrayLikeIter: function (iterable) {
740 var i = 0;
741 return {
742 repr: function () { return "arrayLikeIter(...)"; },
743 toString: MochiKit.Base.forwardCall("repr"),
744 next: function () {
745 if (i >= iterable.length) {
746 throw MochiKit.Iter.StopIteration;
747 }
748 return iterable[i++];
749 }
750 };
751 },
752
753 /** @id MochiKit.Iter.hasIterateNext */
754 hasIterateNext: function (iterable) {
755 return (iterable && typeof(iterable.iterateNext) == "function");
756 },
757
758 /** @id MochiKit.Iter.iterateNextIter */
759 iterateNextIter: function (iterable) {
760 return {
761 repr: function () { return "iterateNextIter(...)"; },
762 toString: MochiKit.Base.forwardCall("repr"),
763 next: function () {
764 var rval = iterable.iterateNext();
765 if (rval === null || rval === undefined) {
766 throw MochiKit.Iter.StopIteration;
767 }
768 return rval;
769 }
770 };
771 }
772});
773
774
775MochiKit.Iter.__new__ = function () {
776 var m = MochiKit.Base;
777 // Re-use StopIteration if exists (e.g. SpiderMonkey)
778 if (typeof(StopIteration) != "undefined") {
779 this.StopIteration = StopIteration;
780 } else {
781 /** @id MochiKit.Iter.StopIteration */
782 this.StopIteration = new m.NamedError("StopIteration");
783 }
784 this.iteratorRegistry = new m.AdapterRegistry();
785 // Register the iterator factory for arrays
786 this.registerIteratorFactory(
787 "arrayLike",
788 m.isArrayLike,
789 this.arrayLikeIter
790 );
791
792 this.registerIteratorFactory(
793 "iterateNext",
794 this.hasIterateNext,
795 this.iterateNextIter
796 );
797
798 m.nameFunctions(this);
799
800};
801
802MochiKit.Iter.__new__();
803
804//
805// XXX: Internet Explorer blows
806//
807if (MochiKit.__export__) {
808 reduce = MochiKit.Iter.reduce;
809}
810
811MochiKit.Base._exportSymbols(this, MochiKit.Iter);