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