summaryrefslogtreecommitdiff
path: root/frontend/delta/js/MochiKit/Base.js
Unidiff
Diffstat (limited to 'frontend/delta/js/MochiKit/Base.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/MochiKit/Base.js1523
1 files changed, 1523 insertions, 0 deletions
diff --git a/frontend/delta/js/MochiKit/Base.js b/frontend/delta/js/MochiKit/Base.js
new file mode 100644
index 0000000..c55f5c3
--- a/dev/null
+++ b/frontend/delta/js/MochiKit/Base.js
@@ -0,0 +1,1523 @@
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.Base 1.5
27
28See <http://mochikit.com/> for documentation, downloads, license, etc.
29
30(c) 2005 Bob Ippolito. All rights Reserved.
31
32***/
33
34
35// MochiKit module (namespace)
36var MochiKit = MochiKit || {};
37if (typeof(MochiKit.__export__) == "undefined") {
38 MochiKit.__export__ = true;
39}
40MochiKit.NAME = "MochiKit";
41MochiKit.VERSION = "1.5";
42MochiKit.__repr__ = function () {
43 return "[" + this.NAME + " " + this.VERSION + "]";
44};
45MochiKit.toString = function () {
46 return this.__repr__();
47};
48
49
50// MochiKit.Base module
51MochiKit.Base = MochiKit.Base || {};
52
53/**
54 * Creates a new module in a parent namespace. This function will
55 * create a new empty module object with "NAME", "VERSION",
56 * "toString" and "__repr__" properties. This object will be inserted into the parent object
57 * using the specified name (i.e. parent[name] = module). It will
58 * also verify that all the dependency modules are defined in the
59 * parent, or an error will be thrown.
60 *
61 * @param {Object} parent the parent module (use "this" or "window" for
62 * a global module)
63 * @param {String} name the module name, e.g. "Base"
64 * @param {String} version the module version, e.g. "1.5"
65 * @param {Array} [deps] the array of module dependencies (as strings)
66 */
67MochiKit.Base.module = function (parent, name, version, deps) {
68 var module = parent[name] = parent[name] || {};
69 var prefix = (parent.NAME ? parent.NAME + "." : "");
70 module.NAME = prefix + name;
71 module.VERSION = version;
72 module.__repr__ = function () {
73 return "[" + this.NAME + " " + this.VERSION + "]";
74 };
75 module.toString = function () {
76 return this.__repr__();
77 };
78 for (var i = 0; deps != null && i < deps.length; i++) {
79 if (!(deps[i] in parent)) {
80 throw module.NAME + ' depends on ' + prefix + deps[i] + '!';
81 }
82 }
83 return module;
84};
85
86MochiKit.Base.module(MochiKit, "Base", "1.5", []);
87
88/** @id MochiKit.Base.update */
89MochiKit.Base.update = function (self, obj/*, ... */) {
90 if (self === null || self === undefined) {
91 self = {};
92 }
93 for (var i = 1; i < arguments.length; i++) {
94 var o = arguments[i];
95 if (typeof(o) != 'undefined' && o !== null) {
96 for (var k in o) {
97 self[k] = o[k];
98 }
99 }
100 }
101 return self;
102};
103
104MochiKit.Base.update(MochiKit.Base, {
105 /** @id MochiKit.Base.camelize */
106 camelize: function (selector) {
107 /* from dojo.style.toCamelCase */
108 var arr = selector.split('-');
109 var cc = arr[0];
110 for (var i = 1; i < arr.length; i++) {
111 cc += arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
112 }
113 return cc;
114 },
115
116 /** @id MochiKit.Base.counter */
117 counter: function (n/* = 1 */) {
118 if (arguments.length === 0) {
119 n = 1;
120 }
121 return function () {
122 return n++;
123 };
124 },
125
126 /** @id MochiKit.Base.clone */
127 clone: function (obj) {
128 var me = arguments.callee;
129 if (arguments.length == 1) {
130 me.prototype = obj;
131 return new me();
132 }
133 },
134
135 _flattenArray: function (res, lst) {
136 for (var i = 0; i < lst.length; i++) {
137 var o = lst[i];
138 if (o instanceof Array) {
139 arguments.callee(res, o);
140 } else {
141 res.push(o);
142 }
143 }
144 return res;
145 },
146
147 /** @id MochiKit.Base.flattenArray */
148 flattenArray: function (lst) {
149 return MochiKit.Base._flattenArray([], lst);
150 },
151
152 /** @id MochiKit.Base.flattenArguments */
153 flattenArguments: function (lst/* ...*/) {
154 var res = [];
155 var m = MochiKit.Base;
156 var args = m.extend(null, arguments);
157 while (args.length) {
158 var o = args.shift();
159 if (o && typeof(o) == "object" && typeof(o.length) == "number") {
160 for (var i = o.length - 1; i >= 0; i--) {
161 args.unshift(o[i]);
162 }
163 } else {
164 res.push(o);
165 }
166 }
167 return res;
168 },
169
170 /** @id MochiKit.Base.extend */
171 extend: function (self, obj, /* optional */skip) {
172 // Extend an array with an array-like object starting
173 // from the skip index
174 if (!skip) {
175 skip = 0;
176 }
177 if (obj) {
178 // allow iterable fall-through, but skip the full isArrayLike
179 // check for speed, this is called often.
180 var l = obj.length;
181 if (typeof(l) != 'number' /* !isArrayLike(obj) */) {
182 if (typeof(MochiKit.Iter) != "undefined") {
183 obj = MochiKit.Iter.list(obj);
184 l = obj.length;
185 } else {
186 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
187 }
188 }
189 if (!self) {
190 self = [];
191 }
192 for (var i = skip; i < l; i++) {
193 self.push(obj[i]);
194 }
195 }
196 // This mutates, but it's convenient to return because
197 // it's often used like a constructor when turning some
198 // ghetto array-like to a real array
199 return self;
200 },
201
202
203 /** @id MochiKit.Base.updatetree */
204 updatetree: function (self, obj/*, ...*/) {
205 if (self === null || self === undefined) {
206 self = {};
207 }
208 for (var i = 1; i < arguments.length; i++) {
209 var o = arguments[i];
210 if (typeof(o) != 'undefined' && o !== null) {
211 for (var k in o) {
212 var v = o[k];
213 if (typeof(self[k]) == 'object' && typeof(v) == 'object') {
214 arguments.callee(self[k], v);
215 } else {
216 self[k] = v;
217 }
218 }
219 }
220 }
221 return self;
222 },
223
224 /** @id MochiKit.Base.setdefault */
225 setdefault: function (self, obj/*, ...*/) {
226 if (self === null || self === undefined) {
227 self = {};
228 }
229 for (var i = 1; i < arguments.length; i++) {
230 var o = arguments[i];
231 for (var k in o) {
232 if (!(k in self)) {
233 self[k] = o[k];
234 }
235 }
236 }
237 return self;
238 },
239
240 /** @id MochiKit.Base.keys */
241 keys: function (obj) {
242 var rval = [];
243 for (var prop in obj) {
244 rval.push(prop);
245 }
246 return rval;
247 },
248
249 /** @id MochiKit.Base.values */
250 values: function (obj) {
251 var rval = [];
252 for (var prop in obj) {
253 rval.push(obj[prop]);
254 }
255 return rval;
256 },
257
258 /** @id MochiKit.Base.items */
259 items: function (obj) {
260 var rval = [];
261 var e;
262 for (var prop in obj) {
263 var v;
264 try {
265 v = obj[prop];
266 } catch (e) {
267 continue;
268 }
269 rval.push([prop, v]);
270 }
271 return rval;
272 },
273
274
275 _newNamedError: function (module, name, func) {
276 func.prototype = new MochiKit.Base.NamedError(module.NAME + "." + name);
277 func.prototype.constructor = func;
278 module[name] = func;
279 },
280
281
282 /** @id MochiKit.Base.operator */
283 operator: {
284 // unary logic operators
285 /** @id MochiKit.Base.truth */
286 truth: function (a) { return !!a; },
287 /** @id MochiKit.Base.lognot */
288 lognot: function (a) { return !a; },
289 /** @id MochiKit.Base.identity */
290 identity: function (a) { return a; },
291
292 // bitwise unary operators
293 /** @id MochiKit.Base.not */
294 not: function (a) { return ~a; },
295 /** @id MochiKit.Base.neg */
296 neg: function (a) { return -a; },
297
298 // binary operators
299 /** @id MochiKit.Base.add */
300 add: function (a, b) { return a + b; },
301 /** @id MochiKit.Base.sub */
302 sub: function (a, b) { return a - b; },
303 /** @id MochiKit.Base.div */
304 div: function (a, b) { return a / b; },
305 /** @id MochiKit.Base.mod */
306 mod: function (a, b) { return a % b; },
307 /** @id MochiKit.Base.mul */
308 mul: function (a, b) { return a * b; },
309
310 // bitwise binary operators
311 /** @id MochiKit.Base.and */
312 and: function (a, b) { return a & b; },
313 /** @id MochiKit.Base.or */
314 or: function (a, b) { return a | b; },
315 /** @id MochiKit.Base.xor */
316 xor: function (a, b) { return a ^ b; },
317 /** @id MochiKit.Base.lshift */
318 lshift: function (a, b) { return a << b; },
319 /** @id MochiKit.Base.rshift */
320 rshift: function (a, b) { return a >> b; },
321 /** @id MochiKit.Base.zrshift */
322 zrshift: function (a, b) { return a >>> b; },
323
324 // near-worthless built-in comparators
325 /** @id MochiKit.Base.eq */
326 eq: function (a, b) { return a == b; },
327 /** @id MochiKit.Base.ne */
328 ne: function (a, b) { return a != b; },
329 /** @id MochiKit.Base.gt */
330 gt: function (a, b) { return a > b; },
331 /** @id MochiKit.Base.ge */
332 ge: function (a, b) { return a >= b; },
333 /** @id MochiKit.Base.lt */
334 lt: function (a, b) { return a < b; },
335 /** @id MochiKit.Base.le */
336 le: function (a, b) { return a <= b; },
337
338 // strict built-in comparators
339 seq: function (a, b) { return a === b; },
340 sne: function (a, b) { return a !== b; },
341
342 // compare comparators
343 /** @id MochiKit.Base.ceq */
344 ceq: function (a, b) { return MochiKit.Base.compare(a, b) === 0; },
345 /** @id MochiKit.Base.cne */
346 cne: function (a, b) { return MochiKit.Base.compare(a, b) !== 0; },
347 /** @id MochiKit.Base.cgt */
348 cgt: function (a, b) { return MochiKit.Base.compare(a, b) == 1; },
349 /** @id MochiKit.Base.cge */
350 cge: function (a, b) { return MochiKit.Base.compare(a, b) != -1; },
351 /** @id MochiKit.Base.clt */
352 clt: function (a, b) { return MochiKit.Base.compare(a, b) == -1; },
353 /** @id MochiKit.Base.cle */
354 cle: function (a, b) { return MochiKit.Base.compare(a, b) != 1; },
355
356 // binary logical operators
357 /** @id MochiKit.Base.logand */
358 logand: function (a, b) { return a && b; },
359 /** @id MochiKit.Base.logor */
360 logor: function (a, b) { return a || b; },
361 /** @id MochiKit.Base.contains */
362 contains: function (a, b) { return b in a; }
363 },
364
365 /** @id MochiKit.Base.forwardCall */
366 forwardCall: function (func) {
367 return function () {
368 return this[func].apply(this, arguments);
369 };
370 },
371
372 /** @id MochiKit.Base.itemgetter */
373 itemgetter: function (func) {
374 return function (arg) {
375 return arg[func];
376 };
377 },
378
379 /** @id MochiKit.Base.bool */
380 bool: function (value) {
381 if (typeof(value) === "boolean" || value instanceof Boolean) {
382 return value.valueOf();
383 } else if (typeof(value) === "string" || value instanceof String) {
384 return value.length > 0 && value != "false" && value != "null" &&
385 value != "undefined" && value != "0";
386 } else if (typeof(value) === "number" || value instanceof Number) {
387 return !isNaN(value) && value != 0;
388 } else if (value != null && typeof(value.length) === "number") {
389 return value.length !== 0;
390 } else {
391 return value != null;
392 }
393 },
394
395 /** @id MochiKit.Base.typeMatcher */
396 typeMatcher: function (/* typ */) {
397 var types = {};
398 for (var i = 0; i < arguments.length; i++) {
399 var typ = arguments[i];
400 types[typ] = typ;
401 }
402 return function () {
403 for (var i = 0; i < arguments.length; i++) {
404 if (!(typeof(arguments[i]) in types)) {
405 return false;
406 }
407 }
408 return true;
409 };
410 },
411
412 /** @id MochiKit.Base.isNull */
413 isNull: function (/* ... */) {
414 for (var i = 0; i < arguments.length; i++) {
415 if (arguments[i] !== null) {
416 return false;
417 }
418 }
419 return true;
420 },
421
422 /** @id MochiKit.Base.isUndefinedOrNull */
423 isUndefinedOrNull: function (/* ... */) {
424 for (var i = 0; i < arguments.length; i++) {
425 var o = arguments[i];
426 if (!(typeof(o) == 'undefined' || o === null)) {
427 return false;
428 }
429 }
430 return true;
431 },
432
433 /** @id MochiKit.Base.isEmpty */
434 isEmpty: function (obj) {
435 return !MochiKit.Base.isNotEmpty.apply(this, arguments);
436 },
437
438 /** @id MochiKit.Base.isNotEmpty */
439 isNotEmpty: function (obj) {
440 for (var i = 0; i < arguments.length; i++) {
441 var o = arguments[i];
442 if (!(o && o.length)) {
443 return false;
444 }
445 }
446 return true;
447 },
448
449 /** @id MochiKit.Base.isArrayLike */
450 isArrayLike: function () {
451 for (var i = 0; i < arguments.length; i++) {
452 var o = arguments[i];
453 var typ = typeof(o);
454 if (
455 (typ != 'object' && !(typ == 'function' && typeof(o.item) == 'function')) ||
456 o === null ||
457 typeof(o.length) != 'number' ||
458 o.nodeType === 3 ||
459 o.nodeType === 4
460 ) {
461 return false;
462 }
463 }
464 return true;
465 },
466
467 /** @id MochiKit.Base.isDateLike */
468 isDateLike: function () {
469 for (var i = 0; i < arguments.length; i++) {
470 var o = arguments[i];
471 if (typeof(o) != "object" || o === null
472 || typeof(o.getTime) != 'function') {
473 return false;
474 }
475 }
476 return true;
477 },
478
479
480 /** @id MochiKit.Base.xmap */
481 xmap: function (fn/*, obj... */) {
482 if (fn === null) {
483 return MochiKit.Base.extend(null, arguments, 1);
484 }
485 var rval = [];
486 for (var i = 1; i < arguments.length; i++) {
487 rval.push(fn(arguments[i]));
488 }
489 return rval;
490 },
491
492 /** @id MochiKit.Base.map */
493 map: function (fn, lst/*, lst... */) {
494 var m = MochiKit.Base;
495 var itr = MochiKit.Iter;
496 var isArrayLike = m.isArrayLike;
497 if (arguments.length <= 2) {
498 // allow an iterable to be passed
499 if (!isArrayLike(lst)) {
500 if (itr) {
501 // fast path for map(null, iterable)
502 lst = itr.list(lst);
503 if (fn === null) {
504 return lst;
505 }
506 } else {
507 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
508 }
509 }
510 // fast path for map(null, lst)
511 if (fn === null) {
512 return m.extend(null, lst);
513 }
514 // disabled fast path for map(fn, lst)
515 /*
516 if (false && typeof(Array.prototype.map) == 'function') {
517 // Mozilla fast-path
518 return Array.prototype.map.call(lst, fn);
519 }
520 */
521 var rval = [];
522 for (var i = 0; i < lst.length; i++) {
523 rval.push(fn(lst[i]));
524 }
525 return rval;
526 } else {
527 // default for map(null, ...) is zip(...)
528 if (fn === null) {
529 fn = Array;
530 }
531 var length = null;
532 for (var i = 1; i < arguments.length; i++) {
533 // allow iterables to be passed
534 if (!isArrayLike(arguments[i])) {
535 if (itr) {
536 return itr.list(itr.imap.apply(null, arguments));
537 } else {
538 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
539 }
540 }
541 // find the minimum length
542 var l = arguments[i].length;
543 if (length === null || length > l) {
544 length = l;
545 }
546 }
547 rval = [];
548 for (var i = 0; i < length; i++) {
549 var args = [];
550 for (var j = 1; j < arguments.length; j++) {
551 args.push(arguments[j][i]);
552 }
553 rval.push(fn.apply(this, args));
554 }
555 return rval;
556 }
557 },
558
559 /** @id MochiKit.Base.xfilter */
560 xfilter: function (fn/*, obj... */) {
561 var rval = [];
562 if (fn === null) {
563 fn = MochiKit.Base.operator.truth;
564 }
565 for (var i = 1; i < arguments.length; i++) {
566 var o = arguments[i];
567 if (fn(o)) {
568 rval.push(o);
569 }
570 }
571 return rval;
572 },
573
574 /** @id MochiKit.Base.filter */
575 filter: function (fn, lst, self) {
576 var rval = [];
577 // allow an iterable to be passed
578 var m = MochiKit.Base;
579 if (!m.isArrayLike(lst)) {
580 if (MochiKit.Iter) {
581 lst = MochiKit.Iter.list(lst);
582 } else {
583 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
584 }
585 }
586 if (fn === null) {
587 fn = m.operator.truth;
588 }
589 if (typeof(Array.prototype.filter) == 'function') {
590 // Mozilla fast-path
591 return Array.prototype.filter.call(lst, fn, self);
592 } else if (typeof(self) == 'undefined' || self === null) {
593 for (var i = 0; i < lst.length; i++) {
594 var o = lst[i];
595 if (fn(o)) {
596 rval.push(o);
597 }
598 }
599 } else {
600 for (var i = 0; i < lst.length; i++) {
601 o = lst[i];
602 if (fn.call(self, o)) {
603 rval.push(o);
604 }
605 }
606 }
607 return rval;
608 },
609
610
611 _wrapDumbFunction: function (func) {
612 return function () {
613 // fast path!
614 switch (arguments.length) {
615 case 0: return func();
616 case 1: return func(arguments[0]);
617 case 2: return func(arguments[0], arguments[1]);
618 case 3: return func(arguments[0], arguments[1], arguments[2]);
619 }
620 var args = [];
621 for (var i = 0; i < arguments.length; i++) {
622 args.push("arguments[" + i + "]");
623 }
624 return eval("(func(" + args.join(",") + "))");
625 };
626 },
627
628 /** @id MochiKit.Base.methodcaller */
629 methodcaller: function (func/*, args... */) {
630 var args = MochiKit.Base.extend(null, arguments, 1);
631 if (typeof(func) == "function") {
632 return function (obj) {
633 return func.apply(obj, args);
634 };
635 } else {
636 return function (obj) {
637 return obj[func].apply(obj, args);
638 };
639 }
640 },
641
642 /** @id MochiKit.Base.method */
643 method: function (self, func) {
644 var m = MochiKit.Base;
645 return m.bind.apply(this, m.extend([func, self], arguments, 2));
646 },
647
648 /** @id MochiKit.Base.compose */
649 compose: function (f1, f2/*, f3, ... fN */) {
650 var fnlist = [];
651 var m = MochiKit.Base;
652 if (arguments.length === 0) {
653 throw new TypeError("compose() requires at least one argument");
654 }
655 for (var i = 0; i < arguments.length; i++) {
656 var fn = arguments[i];
657 if (typeof(fn) != "function") {
658 throw new TypeError(m.repr(fn) + " is not a function");
659 }
660 fnlist.push(fn);
661 }
662 return function () {
663 var args = arguments;
664 for (var i = fnlist.length - 1; i >= 0; i--) {
665 args = [fnlist[i].apply(this, args)];
666 }
667 return args[0];
668 };
669 },
670
671 /** @id MochiKit.Base.bind */
672 bind: function (func, self/* args... */) {
673 if (typeof(func) == "string") {
674 func = self[func];
675 }
676 var im_func = func.im_func;
677 var im_preargs = func.im_preargs;
678 var im_self = func.im_self;
679 var m = MochiKit.Base;
680 if (typeof(func) == "function" && typeof(func.apply) == "undefined") {
681 // this is for cases where JavaScript sucks ass and gives you a
682 // really dumb built-in function like alert() that doesn't have
683 // an apply
684 func = m._wrapDumbFunction(func);
685 }
686 if (typeof(im_func) != 'function') {
687 im_func = func;
688 }
689 if (typeof(self) != 'undefined') {
690 im_self = self;
691 }
692 if (typeof(im_preargs) == 'undefined') {
693 im_preargs = [];
694 } else {
695 im_preargs = im_preargs.slice();
696 }
697 m.extend(im_preargs, arguments, 2);
698 var newfunc = function () {
699 var args = arguments;
700 var me = arguments.callee;
701 if (me.im_preargs.length > 0) {
702 args = m.concat(me.im_preargs, args);
703 }
704 var self = me.im_self;
705 if (!self) {
706 self = this;
707 }
708 return me.im_func.apply(self, args);
709 };
710 newfunc.im_self = im_self;
711 newfunc.im_func = im_func;
712 newfunc.im_preargs = im_preargs;
713 if (typeof(im_func.NAME) == 'string') {
714 newfunc.NAME = "bind(" + im_func.NAME + ",...)";
715 }
716 return newfunc;
717 },
718
719 /** @id MochiKit.Base.bindLate */
720 bindLate: function (func, self/* args... */) {
721 var m = MochiKit.Base;
722 var args = arguments;
723 if (typeof(func) === "string") {
724 args = m.extend([m.forwardCall(func)], arguments, 1);
725 return m.bind.apply(this, args);
726 }
727 return m.bind.apply(this, args);
728 },
729
730 /** @id MochiKit.Base.bindMethods */
731 bindMethods: function (self) {
732 var bind = MochiKit.Base.bind;
733 for (var k in self) {
734 var func = self[k];
735 if (typeof(func) == 'function') {
736 self[k] = bind(func, self);
737 }
738 }
739 },
740
741 /** @id MochiKit.Base.registerComparator */
742 registerComparator: function (name, check, comparator, /* optional */ override) {
743 MochiKit.Base.comparatorRegistry.register(name, check, comparator, override);
744 },
745
746 _primitives: {'boolean': true, 'string': true, 'number': true},
747
748 /** @id MochiKit.Base.compare */
749 compare: function (a, b) {
750 if (a == b) {
751 return 0;
752 }
753 var aIsNull = (typeof(a) == 'undefined' || a === null);
754 var bIsNull = (typeof(b) == 'undefined' || b === null);
755 if (aIsNull && bIsNull) {
756 return 0;
757 } else if (aIsNull) {
758 return -1;
759 } else if (bIsNull) {
760 return 1;
761 }
762 var m = MochiKit.Base;
763 // bool, number, string have meaningful comparisons
764 var prim = m._primitives;
765 if (!(typeof(a) in prim && typeof(b) in prim)) {
766 try {
767 return m.comparatorRegistry.match(a, b);
768 } catch (e) {
769 if (e != m.NotFound) {
770 throw e;
771 }
772 }
773 }
774 if (a < b) {
775 return -1;
776 } else if (a > b) {
777 return 1;
778 }
779 // These types can't be compared
780 var repr = m.repr;
781 throw new TypeError(repr(a) + " and " + repr(b) + " can not be compared");
782 },
783
784 /** @id MochiKit.Base.compareDateLike */
785 compareDateLike: function (a, b) {
786 return MochiKit.Base.compare(a.getTime(), b.getTime());
787 },
788
789 /** @id MochiKit.Base.compareArrayLike */
790 compareArrayLike: function (a, b) {
791 var compare = MochiKit.Base.compare;
792 var count = a.length;
793 var rval = 0;
794 if (count > b.length) {
795 rval = 1;
796 count = b.length;
797 } else if (count < b.length) {
798 rval = -1;
799 }
800 for (var i = 0; i < count; i++) {
801 var cmp = compare(a[i], b[i]);
802 if (cmp) {
803 return cmp;
804 }
805 }
806 return rval;
807 },
808
809 /** @id MochiKit.Base.registerRepr */
810 registerRepr: function (name, check, wrap, /* optional */override) {
811 MochiKit.Base.reprRegistry.register(name, check, wrap, override);
812 },
813
814 /** @id MochiKit.Base.repr */
815 repr: function (o) {
816 if (typeof(o) == "undefined") {
817 return "undefined";
818 } else if (o === null) {
819 return "null";
820 }
821 try {
822 if (typeof(o.__repr__) == 'function') {
823 return o.__repr__();
824 } else if (typeof(o.repr) == 'function' && o.repr != arguments.callee) {
825 return o.repr();
826 }
827 return MochiKit.Base.reprRegistry.match(o);
828 } catch (e) {
829 try {
830 if (typeof(o.NAME) == 'string' && (
831 o.toString == Function.prototype.toString ||
832 o.toString == Object.prototype.toString
833 )) {
834 return o.NAME;
835 }
836 } catch (ignore) {
837 }
838 }
839 try {
840 var ostring = (o + "");
841 } catch (e) {
842 return "[" + typeof(o) + "]";
843 }
844 if (typeof(o) == "function") {
845 ostring = ostring.replace(/^\s+/, "").replace(/\s+/g, " ");
846 ostring = ostring.replace(/,(\S)/, ", $1");
847 var idx = ostring.indexOf("{");
848 if (idx != -1) {
849 ostring = ostring.substr(0, idx) + "{...}";
850 }
851 }
852 return ostring;
853 },
854
855 /** @id MochiKit.Base.reprArrayLike */
856 reprArrayLike: function (o) {
857 var m = MochiKit.Base;
858 return "[" + m.map(m.repr, o).join(", ") + "]";
859 },
860
861 /** @id MochiKit.Base.reprString */
862 reprString: function (o) {
863 return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
864 ).replace(/[\f]/g, "\\f"
865 ).replace(/[\b]/g, "\\b"
866 ).replace(/[\n]/g, "\\n"
867 ).replace(/[\t]/g, "\\t"
868 ).replace(/[\v]/g, "\\v"
869 ).replace(/[\r]/g, "\\r");
870 },
871
872 /** @id MochiKit.Base.reprNumber */
873 reprNumber: function (o) {
874 return o + "";
875 },
876
877 /** @id MochiKit.Base.registerJSON */
878 registerJSON: function (name, check, wrap, /* optional */override) {
879 MochiKit.Base.jsonRegistry.register(name, check, wrap, override);
880 },
881
882
883 /** @id MochiKit.Base.evalJSON */
884 evalJSON: function (jsonText) {
885 return eval("(" + MochiKit.Base._filterJSON(jsonText) + ")");
886 },
887
888 _filterJSON: function (s) {
889 var m = s.match(/^\s*\/\*(.*)\*\/\s*$/);
890 return (m) ? m[1] : s;
891 },
892
893 /** @id MochiKit.Base.serializeJSON */
894 serializeJSON: function (o) {
895 var objtype = typeof(o);
896 if (objtype == "number" || objtype == "boolean") {
897 return o + "";
898 } else if (o === null) {
899 return "null";
900 } else if (objtype == "string") {
901 var res = "";
902 for (var i = 0; i < o.length; i++) {
903 var c = o.charAt(i);
904 if (c == '\"') {
905 res += '\\"';
906 } else if (c == '\\') {
907 res += '\\\\';
908 } else if (c == '\b') {
909 res += '\\b';
910 } else if (c == '\f') {
911 res += '\\f';
912 } else if (c == '\n') {
913 res += '\\n';
914 } else if (c == '\r') {
915 res += '\\r';
916 } else if (c == '\t') {
917 res += '\\t';
918 } else if (o.charCodeAt(i) <= 0x1F) {
919 var hex = o.charCodeAt(i).toString(16);
920 if (hex.length < 2) {
921 hex = '0' + hex;
922 }
923 res += '\\u00' + hex.toUpperCase();
924 } else {
925 res += c;
926 }
927 }
928 return '"' + res + '"';
929 }
930 // recurse
931 var me = arguments.callee;
932 // short-circuit for objects that support "json" serialization
933 // if they return "self" then just pass-through...
934 var newObj;
935 if (typeof(o.toJSON) == "function") {
936 newObj = o.toJSON();
937 if (o !== newObj) {
938 return me(newObj);
939 }
940 }
941 if (typeof(o.__json__) == "function") {
942 newObj = o.__json__();
943 if (o !== newObj) {
944 return me(newObj);
945 }
946 }
947 if (typeof(o.json) == "function") {
948 newObj = o.json();
949 if (o !== newObj) {
950 return me(newObj);
951 }
952 }
953 // array
954 if (objtype != "function" && typeof(o.length) == "number") {
955 var res = [];
956 for (var i = 0; i < o.length; i++) {
957 var val = me(o[i]);
958 if (typeof(val) != "string") {
959 // skip non-serializable values
960 continue;
961 }
962 res.push(val);
963 }
964 return "[" + res.join(", ") + "]";
965 }
966 // look in the registry
967 var m = MochiKit.Base;
968 try {
969 newObj = m.jsonRegistry.match(o);
970 if (o !== newObj) {
971 return me(newObj);
972 }
973 } catch (e) {
974 if (e != m.NotFound) {
975 // something really bad happened
976 throw e;
977 }
978 }
979 // undefined is outside of the spec
980 if (objtype == "undefined") {
981 throw new TypeError("undefined can not be serialized as JSON");
982 }
983 // it's a function with no adapter, bad
984 if (objtype == "function") {
985 return null;
986 }
987 // generic object code path
988 res = [];
989 for (var k in o) {
990 var useKey;
991 if (typeof(k) == "number") {
992 useKey = '"' + k + '"';
993 } else if (typeof(k) == "string") {
994 useKey = me(k);
995 } else {
996 // skip non-string or number keys
997 continue;
998 }
999 val = me(o[k]);
1000 if (typeof(val) != "string") {
1001 // skip non-serializable values
1002 continue;
1003 }
1004 res.push(useKey + ":" + val);
1005 }
1006 return "{" + res.join(", ") + "}";
1007 },
1008
1009
1010 /** @id MochiKit.Base.objEqual */
1011 objEqual: function (a, b) {
1012 return (MochiKit.Base.compare(a, b) === 0);
1013 },
1014
1015 /** @id MochiKit.Base.arrayEqual */
1016 arrayEqual: function (self, arr) {
1017 if (self.length != arr.length) {
1018 return false;
1019 }
1020 return (MochiKit.Base.compare(self, arr) === 0);
1021 },
1022
1023 /** @id MochiKit.Base.concat */
1024 concat: function (/* lst... */) {
1025 var rval = [];
1026 var extend = MochiKit.Base.extend;
1027 for (var i = 0; i < arguments.length; i++) {
1028 extend(rval, arguments[i]);
1029 }
1030 return rval;
1031 },
1032
1033 /** @id MochiKit.Base.keyComparator */
1034 keyComparator: function (key/* ... */) {
1035 // fast-path for single key comparisons
1036 var m = MochiKit.Base;
1037 var compare = m.compare;
1038 if (arguments.length == 1) {
1039 return function (a, b) {
1040 return compare(a[key], b[key]);
1041 };
1042 }
1043 var compareKeys = m.extend(null, arguments);
1044 return function (a, b) {
1045 var rval = 0;
1046 // keep comparing until something is inequal or we run out of
1047 // keys to compare
1048 for (var i = 0; (rval === 0) && (i < compareKeys.length); i++) {
1049 var key = compareKeys[i];
1050 rval = compare(a[key], b[key]);
1051 }
1052 return rval;
1053 };
1054 },
1055
1056 /** @id MochiKit.Base.reverseKeyComparator */
1057 reverseKeyComparator: function (key) {
1058 var comparator = MochiKit.Base.keyComparator.apply(this, arguments);
1059 return function (a, b) {
1060 return comparator(b, a);
1061 };
1062 },
1063
1064 /** @id MochiKit.Base.partial */
1065 partial: function (func) {
1066 var m = MochiKit.Base;
1067 return m.bind.apply(this, m.extend([func, undefined], arguments, 1));
1068 },
1069
1070 /** @id MochiKit.Base.listMinMax */
1071 listMinMax: function (which, lst) {
1072 if (lst.length === 0) {
1073 return null;
1074 }
1075 var cur = lst[0];
1076 var compare = MochiKit.Base.compare;
1077 for (var i = 1; i < lst.length; i++) {
1078 var o = lst[i];
1079 if (compare(o, cur) == which) {
1080 cur = o;
1081 }
1082 }
1083 return cur;
1084 },
1085
1086 /** @id MochiKit.Base.objMax */
1087 objMax: function (/* obj... */) {
1088 return MochiKit.Base.listMinMax(1, arguments);
1089 },
1090
1091 /** @id MochiKit.Base.objMin */
1092 objMin: function (/* obj... */) {
1093 return MochiKit.Base.listMinMax(-1, arguments);
1094 },
1095
1096 /** @id MochiKit.Base.findIdentical */
1097 findIdentical: function (lst, value, start/* = 0 */, /* optional */end) {
1098 if (typeof(end) == "undefined" || end === null) {
1099 end = lst.length;
1100 }
1101 if (typeof(start) == "undefined" || start === null) {
1102 start = 0;
1103 }
1104 for (var i = start; i < end; i++) {
1105 if (lst[i] === value) {
1106 return i;
1107 }
1108 }
1109 return -1;
1110 },
1111
1112 /** @id MochiKit.Base.mean */
1113 mean: function(/* lst... */) {
1114 /* http://www.nist.gov/dads/HTML/mean.html */
1115 var sum = 0;
1116
1117 var m = MochiKit.Base;
1118 var args = m.extend(null, arguments);
1119 var count = args.length;
1120
1121 while (args.length) {
1122 var o = args.shift();
1123 if (o && typeof(o) == "object" && typeof(o.length) == "number") {
1124 count += o.length - 1;
1125 for (var i = o.length - 1; i >= 0; i--) {
1126 sum += o[i];
1127 }
1128 } else {
1129 sum += o;
1130 }
1131 }
1132
1133 if (count <= 0) {
1134 throw new TypeError('mean() requires at least one argument');
1135 }
1136
1137 return sum/count;
1138 },
1139
1140 /** @id MochiKit.Base.median */
1141 median: function(/* lst... */) {
1142 /* http://www.nist.gov/dads/HTML/median.html */
1143 var data = MochiKit.Base.flattenArguments(arguments);
1144 if (data.length === 0) {
1145 throw new TypeError('median() requires at least one argument');
1146 }
1147 data.sort(MochiKit.Base.compare);
1148 if (data.length % 2 == 0) {
1149 var upper = data.length / 2;
1150 return (data[upper] + data[upper - 1]) / 2;
1151 } else {
1152 return data[(data.length - 1) / 2];
1153 }
1154 },
1155
1156 /** @id MochiKit.Base.findValue */
1157 findValue: function (lst, value, start/* = 0 */, /* optional */end) {
1158 if (typeof(end) == "undefined" || end === null) {
1159 end = lst.length;
1160 }
1161 if (typeof(start) == "undefined" || start === null) {
1162 start = 0;
1163 }
1164 var cmp = MochiKit.Base.compare;
1165 for (var i = start; i < end; i++) {
1166 if (cmp(lst[i], value) === 0) {
1167 return i;
1168 }
1169 }
1170 return -1;
1171 },
1172
1173 /** @id MochiKit.Base.nodeWalk */
1174 nodeWalk: function (node, visitor) {
1175 var nodes = [node];
1176 var extend = MochiKit.Base.extend;
1177 while (nodes.length) {
1178 var res = visitor(nodes.shift());
1179 if (res) {
1180 extend(nodes, res);
1181 }
1182 }
1183 },
1184
1185
1186 /** @id MochiKit.Base.nameFunctions */
1187 nameFunctions: function (namespace) {
1188 var base = namespace.NAME;
1189 if (typeof(base) == 'undefined') {
1190 base = '';
1191 } else {
1192 base = base + '.';
1193 }
1194 for (var name in namespace) {
1195 var o = namespace[name];
1196 if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') {
1197 try {
1198 o.NAME = base + name;
1199 } catch (e) {
1200 // pass
1201 }
1202 }
1203 }
1204 },
1205
1206
1207 /** @id MochiKit.Base.queryString */
1208 queryString: function (names, values) {
1209 // check to see if names is a string or a DOM element, and if
1210 // MochiKit.DOM is available. If so, drop it like it's a form
1211 // Ugliest conditional in MochiKit? Probably!
1212 if (typeof(MochiKit.DOM) != "undefined" && arguments.length == 1
1213 && (typeof(names) == "string" || (
1214 typeof(names.nodeType) != "undefined" && names.nodeType > 0
1215 ))
1216 ) {
1217 var kv = MochiKit.DOM.formContents(names);
1218 names = kv[0];
1219 values = kv[1];
1220 } else if (arguments.length == 1) {
1221 // Allow the return value of formContents to be passed directly
1222 if (typeof(names.length) == "number" && names.length == 2) {
1223 return arguments.callee(names[0], names[1]);
1224 }
1225 var o = names;
1226 names = [];
1227 values = [];
1228 for (var k in o) {
1229 var v = o[k];
1230 if (typeof(v) == "function") {
1231 continue;
1232 } else if (MochiKit.Base.isArrayLike(v)){
1233 for (var i = 0; i < v.length; i++) {
1234 names.push(k);
1235 values.push(v[i]);
1236 }
1237 } else {
1238 names.push(k);
1239 values.push(v);
1240 }
1241 }
1242 }
1243 var rval = [];
1244 var len = Math.min(names.length, values.length);
1245 var urlEncode = MochiKit.Base.urlEncode;
1246 for (var i = 0; i < len; i++) {
1247 v = values[i];
1248 if (typeof(v) != 'undefined' && v !== null) {
1249 rval.push(urlEncode(names[i]) + "=" + urlEncode(v));
1250 }
1251 }
1252 return rval.join("&");
1253 },
1254
1255
1256 /** @id MochiKit.Base.parseQueryString */
1257 parseQueryString: function (encodedString, useArrays) {
1258 // strip a leading '?' from the encoded string
1259 var qstr = (encodedString.charAt(0) == "?")
1260 ? encodedString.substring(1)
1261 : encodedString;
1262 var pairs = qstr.replace(/\+/g, "%20").split(/\&amp\;|\&\#38\;|\&#x26;|\&/);
1263 var o = {};
1264 var decode;
1265 if (typeof(decodeURIComponent) != "undefined") {
1266 decode = decodeURIComponent;
1267 } else {
1268 decode = unescape;
1269 }
1270 if (useArrays) {
1271 for (var i = 0; i < pairs.length; i++) {
1272 var pair = pairs[i].split("=");
1273 var name = decode(pair.shift());
1274 if (!name) {
1275 continue;
1276 }
1277 var arr = o[name];
1278 if (!(arr instanceof Array)) {
1279 arr = [];
1280 o[name] = arr;
1281 }
1282 arr.push(decode(pair.join("=")));
1283 }
1284 } else {
1285 for (var i = 0; i < pairs.length; i++) {
1286 pair = pairs[i].split("=");
1287 var name = pair.shift();
1288 if (!name) {
1289 continue;
1290 }
1291 o[decode(name)] = decode(pair.join("="));
1292 }
1293 }
1294 return o;
1295 }
1296});
1297
1298/** @id MochiKit.Base.AdapterRegistry */
1299MochiKit.Base.AdapterRegistry = function () {
1300 this.pairs = [];
1301};
1302
1303MochiKit.Base.AdapterRegistry.prototype = {
1304 /** @id MochiKit.Base.AdapterRegistry.prototype.register */
1305 register: function (name, check, wrap, /* optional */ override) {
1306 if (override) {
1307 this.pairs.unshift([name, check, wrap]);
1308 } else {
1309 this.pairs.push([name, check, wrap]);
1310 }
1311 },
1312
1313 /** @id MochiKit.Base.AdapterRegistry.prototype.match */
1314 match: function (/* ... */) {
1315 for (var i = 0; i < this.pairs.length; i++) {
1316 var pair = this.pairs[i];
1317 if (pair[1].apply(this, arguments)) {
1318 return pair[2].apply(this, arguments);
1319 }
1320 }
1321 throw MochiKit.Base.NotFound;
1322 },
1323
1324 /** @id MochiKit.Base.AdapterRegistry.prototype.unregister */
1325 unregister: function (name) {
1326 for (var i = 0; i < this.pairs.length; i++) {
1327 var pair = this.pairs[i];
1328 if (pair[0] == name) {
1329 this.pairs.splice(i, 1);
1330 return true;
1331 }
1332 }
1333 return false;
1334 }
1335};
1336
1337/**
1338 * Exports all symbols from one or more modules into the specified
1339 * namespace (or scope). This is similar to MochiKit.Base.update(),
1340 * except for special handling of the "__export__" flag, contained
1341 * sub-modules (exported recursively), and names starting with "_".
1342 *
1343 * @param {Object} namespace the object or scope to modify
1344 * @param {Object} module the module to export
1345 */
1346MochiKit.Base.moduleExport = function (namespace, module/*, ...*/) {
1347 var SKIP = { toString: true, NAME: true, VERSION: true };
1348 var mods = MochiKit.Base.extend([], arguments, 1);
1349 while ((module = mods.shift()) != null) {
1350 for (var k in module) {
1351 var v = module[k];
1352 if (v != null) {
1353 var flagSet = (typeof(v.__export__) == 'boolean');
1354 var nameValid = (k[0] !== "_" && !SKIP[k]);
1355 if (flagSet ? v.__export__ : nameValid) {
1356 if (typeof(v) == 'object' && v.NAME && v.VERSION) {
1357 mods.push(v);
1358 } else {
1359 namespace[k] = module[k];
1360 }
1361 }
1362 }
1363 }
1364 }
1365 return namespace;
1366};
1367
1368/**
1369 * Identical to moduleExport, but also considers the global and
1370 * module-specific "__export__" flag.
1371 */
1372MochiKit.Base._exportSymbols = function (namespace, module) {
1373 if (MochiKit.__export__ !== false && module.__export__ !== false) {
1374 MochiKit.Base.moduleExport(namespace, module);
1375 }
1376};
1377
1378/**
1379 * Creates a deprecated function alias in the specified module. The
1380 * deprecated function will forward all calls and arguments to a
1381 * target function, while also logging a debug message on the first
1382 * call (if MochiKit.Logging is loaded). The destination function may
1383 * be located in another module, which must be loaded, or an
1384 * exception will be thrown.
1385 *
1386 * @param {Object/String} module the source module or module name
1387 * (e.g. 'DOM' or 'MochiKit.DOM')
1388 * @param {String} name the deprecated function name (e.g. 'getStyle')
1389 * @param {String} target the fully qualified name of the target
1390 * function (e.g. 'MochiKit.Style.getStyle')
1391 * @param {String} version the first version when the source function
1392 * was deprecated (e.g. '1.4')
1393 * @param {Boolean} [exportable] the exportable function flag,
1394 * defaults to false
1395 */
1396MochiKit.Base._deprecated = function (module, name, target, version, exportable) {
1397 if (typeof(module) === 'string') {
1398 if (module.indexOf('MochiKit.') === 0) {
1399 module = module.substring(9);
1400 }
1401 module = MochiKit[module];
1402 }
1403 var targetModule = target.split('.')[1];
1404 var targetName = target.split('.')[2];
1405 var func = function () {
1406 var self = arguments.callee;
1407 var msg = module.NAME + '.' + name + ' is deprecated since version ' +
1408 version + '. Use ' + target + ' instead.';
1409 if (self.logged !== true) {
1410 self.logged = true;
1411 if (MochiKit.Logging) {
1412 MochiKit.Logging.logDebug(msg);
1413 } else if (console && console.log) {
1414 console.log(msg);
1415 }
1416 }
1417 if (!MochiKit[targetModule]) {
1418 throw new Error(msg);
1419 }
1420 return MochiKit[targetModule][targetName].apply(this, arguments);
1421 };
1422 func.__export__ = (exportable === true);
1423 module[name] = func;
1424};
1425
1426MochiKit.Base.__new__ = function () {
1427 var m = this;
1428
1429 /** @id MochiKit.Base.noop */
1430 m.noop = m.operator.identity;
1431
1432 // Backwards compat
1433 m._deprecated(m, 'forward', 'MochiKit.Base.forwardCall', '1.3');
1434 m._deprecated(m, 'find', 'MochiKit.Base.findValue', '1.3');
1435
1436 if (typeof(encodeURIComponent) != "undefined") {
1437 /** @id MochiKit.Base.urlEncode */
1438 m.urlEncode = function (unencoded) {
1439 return encodeURIComponent(unencoded).replace(/\'/g, '%27');
1440 };
1441 } else {
1442 m.urlEncode = function (unencoded) {
1443 return escape(unencoded
1444 ).replace(/\+/g, '%2B'
1445 ).replace(/\"/g,'%22'
1446 ).replace(/\'/g, '%27');
1447 };
1448 }
1449
1450 /** @id MochiKit.Base.NamedError */
1451 m.NamedError = function (name) {
1452 this.message = name;
1453 this.name = name;
1454 };
1455 m.NamedError.prototype = new Error();
1456 m.NamedError.prototype.constructor = m.NamedError;
1457 m.update(m.NamedError.prototype, {
1458 repr: function () {
1459 if (this.message && this.message != this.name) {
1460 return this.name + "(" + m.repr(this.message) + ")";
1461 } else {
1462 return this.name + "()";
1463 }
1464 },
1465 toString: m.forwardCall("repr")
1466 });
1467
1468 /** @id MochiKit.Base.NotFound */
1469 m.NotFound = new m.NamedError("MochiKit.Base.NotFound");
1470
1471
1472 /** @id MochiKit.Base.listMax */
1473 m.listMax = m.partial(m.listMinMax, 1);
1474 /** @id MochiKit.Base.listMin */
1475 m.listMin = m.partial(m.listMinMax, -1);
1476
1477 /** @id MochiKit.Base.isCallable */
1478 m.isCallable = m.typeMatcher('function');
1479 /** @id MochiKit.Base.isUndefined */
1480 m.isUndefined = m.typeMatcher('undefined');
1481 /** @id MochiKit.Base.isValue */
1482 m.isValue = m.typeMatcher('boolean', 'number', 'string');
1483
1484 /** @id MochiKit.Base.merge */
1485 m.merge = m.partial(m.update, null);
1486 /** @id MochiKit.Base.zip */
1487 m.zip = m.partial(m.map, null);
1488
1489 /** @id MochiKit.Base.average */
1490 m.average = m.mean;
1491
1492 /** @id MochiKit.Base.comparatorRegistry */
1493 m.comparatorRegistry = new m.AdapterRegistry();
1494 m.registerComparator("dateLike", m.isDateLike, m.compareDateLike);
1495 m.registerComparator("arrayLike", m.isArrayLike, m.compareArrayLike);
1496
1497 /** @id MochiKit.Base.reprRegistry */
1498 m.reprRegistry = new m.AdapterRegistry();
1499 m.registerRepr("arrayLike", m.isArrayLike, m.reprArrayLike);
1500 m.registerRepr("string", m.typeMatcher("string"), m.reprString);
1501 m.registerRepr("numbers", m.typeMatcher("number", "boolean"), m.reprNumber);
1502
1503 /** @id MochiKit.Base.jsonRegistry */
1504 m.jsonRegistry = new m.AdapterRegistry();
1505
1506 m.nameFunctions(this);
1507
1508};
1509
1510MochiKit.Base.__new__();
1511
1512//
1513// XXX: Internet Explorer blows
1514//
1515if (MochiKit.__export__) {
1516 compare = MochiKit.Base.compare;
1517 compose = MochiKit.Base.compose;
1518 serializeJSON = MochiKit.Base.serializeJSON;
1519 mean = MochiKit.Base.mean;
1520 median = MochiKit.Base.median;
1521}
1522
1523MochiKit.Base._exportSymbols(this, MochiKit.Base);