1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | (function(){
|
24 |
|
25 | this.MooTools = {
|
26 | version: '1.5.2',
|
27 | build: 'ed01297a1a19de0675404640e7377cf97694e131'
|
28 | };
|
29 |
|
30 |
|
31 |
|
32 | var typeOf = this.typeOf = function(item){
|
33 | if (item == null) return 'null';
|
34 | if (item.$family != null) return item.$family();
|
35 |
|
36 | if (item.nodeName){
|
37 | if (item.nodeType == 1) return 'element';
|
38 | if (item.nodeType == 3) return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace';
|
39 | } else if (typeof item.length == 'number'){
|
40 | if ('callee' in item) return 'arguments';
|
41 | if ('item' in item) return 'collection';
|
42 | }
|
43 |
|
44 | return typeof item;
|
45 | };
|
46 |
|
47 | var instanceOf = this.instanceOf = function(item, object){
|
48 | if (item == null) return false;
|
49 | var constructor = item.$constructor || item.constructor;
|
50 | while (constructor){
|
51 | if (constructor === object) return true;
|
52 | constructor = constructor.parent;
|
53 | }
|
54 |
|
55 | return item instanceof object;
|
56 | };
|
57 |
|
58 | var hasOwnProperty = Object.prototype.hasOwnProperty;
|
59 |
|
60 |
|
61 |
|
62 | // Function overloading
|
63 |
|
64 | var Function = this.Function;
|
65 |
|
66 | Function.prototype.overloadSetter = function(usePlural){
|
67 | var self = this;
|
68 | return function(a, b){
|
69 | if (a == null) return this;
|
70 | if (usePlural || typeof a != 'string'){
|
71 | for (var k in a) self.call(this, k, a[k]);
|
72 |
|
73 | } else {
|
74 | self.call(this, a, b);
|
75 | }
|
76 | return this;
|
77 | };
|
78 | };
|
79 |
|
80 | Function.prototype.overloadGetter = function(usePlural){
|
81 | var self = this;
|
82 | return function(a){
|
83 | var args, result;
|
84 | if (typeof a != 'string') args = a;
|
85 | else if (arguments.length > 1) args = arguments;
|
86 | else if (usePlural) args = [a];
|
87 | if (args){
|
88 | result = {};
|
89 | for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]);
|
90 | } else {
|
91 | result = self.call(this, a);
|
92 | }
|
93 | return result;
|
94 | };
|
95 | };
|
96 |
|
97 | Function.prototype.extend = function(key, value){
|
98 | this[key] = value;
|
99 | }.overloadSetter();
|
100 |
|
101 | Function.prototype.implement = function(key, value){
|
102 | this.prototype[key] = value;
|
103 | }.overloadSetter();
|
104 |
|
105 |
|
106 |
|
107 | var slice = Array.prototype.slice;
|
108 |
|
109 | Function.from = function(item){
|
110 | return (typeOf(item) == 'function') ? item : function(){
|
111 | return item;
|
112 | };
|
113 | };
|
114 |
|
115 | Array.from = function(item){
|
116 | if (item == null) return [];
|
117 | return (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(item) == 'array') ? item : slice.call(item) : [item];
|
118 | };
|
119 |
|
120 | Number.from = function(item){
|
121 | var number = parseFloat(item);
|
122 | return isFinite(number) ? number : null;
|
123 | };
|
124 |
|
125 | String.from = function(item){
|
126 | return item + '';
|
127 | };
|
128 |
|
129 |
|
130 |
|
131 | Function.implement({
|
132 |
|
133 | hide: function(){
|
134 | this.$hidden = true;
|
135 | return this;
|
136 | },
|
137 |
|
138 | protect: function(){
|
139 | this.$protected = true;
|
140 | return this;
|
141 | }
|
142 |
|
143 | });
|
144 |
|
145 |
|
146 |
|
147 | var Type = this.Type = function(name, object){
|
148 | if (name){
|
149 | var lower = name.toLowerCase();
|
150 | var typeCheck = function(item){
|
151 | return (typeOf(item) == lower);
|
152 | };
|
153 |
|
154 | Type['is' + name] = typeCheck;
|
155 | if (object != null){
|
156 | object.prototype.$family = (function(){
|
157 | return lower;
|
158 | }).hide();
|
159 |
|
160 | }
|
161 | }
|
162 |
|
163 | if (object == null) return null;
|
164 |
|
165 | object.extend(this);
|
166 | object.$constructor = Type;
|
167 | object.prototype.$constructor = object;
|
168 |
|
169 | return object;
|
170 | };
|
171 |
|
172 | var toString = Object.prototype.toString;
|
173 |
|
174 | Type.isEnumerable = function(item){
|
175 | return (item != null && typeof item.length == 'number' && toString.call(item) != '[object Function]' );
|
176 | };
|
177 |
|
178 | var hooks = {};
|
179 |
|
180 | var hooksOf = function(object){
|
181 | var type = typeOf(object.prototype);
|
182 | return hooks[type] || (hooks[type] = []);
|
183 | };
|
184 |
|
185 | var implement = function(name, method){
|
186 | if (method && method.$hidden) return;
|
187 |
|
188 | var hooks = hooksOf(this);
|
189 |
|
190 | for (var i = 0; i < hooks.length; i++){
|
191 | var hook = hooks[i];
|
192 | if (typeOf(hook) == 'type') implement.call(hook, name, method);
|
193 | else hook.call(this, name, method);
|
194 | }
|
195 |
|
196 | var previous = this.prototype[name];
|
197 | if (previous == null || !previous.$protected) this.prototype[name] = method;
|
198 |
|
199 | if (this[name] == null && typeOf(method) == 'function') extend.call(this, name, function(item){
|
200 | return method.apply(item, slice.call(arguments, 1));
|
201 | });
|
202 | };
|
203 |
|
204 | var extend = function(name, method){
|
205 | if (method && method.$hidden) return;
|
206 | var previous = this[name];
|
207 | if (previous == null || !previous.$protected) this[name] = method;
|
208 | };
|
209 |
|
210 | Type.implement({
|
211 |
|
212 | implement: implement.overloadSetter(),
|
213 |
|
214 | extend: extend.overloadSetter(),
|
215 |
|
216 | alias: function(name, existing){
|
217 | implement.call(this, name, this.prototype[existing]);
|
218 | }.overloadSetter(),
|
219 |
|
220 | mirror: function(hook){
|
221 | hooksOf(this).push(hook);
|
222 | return this;
|
223 | }
|
224 |
|
225 | });
|
226 |
|
227 | new Type('Type', Type);
|
228 |
|
229 |
|
230 |
|
231 | var force = function(name, object, methods){
|
232 | var isType = (object != Object),
|
233 | prototype = object.prototype;
|
234 |
|
235 | if (isType) object = new Type(name, object);
|
236 |
|
237 | for (var i = 0, l = methods.length; i < l; i++){
|
238 | var key = methods[i],
|
239 | generic = object[key],
|
240 | proto = prototype[key];
|
241 |
|
242 | if (generic) generic.protect();
|
243 | if (isType && proto) object.implement(key, proto.protect());
|
244 | }
|
245 |
|
246 | if (isType){
|
247 | var methodsEnumerable = prototype.propertyIsEnumerable(methods[0]);
|
248 | object.forEachMethod = function(fn){
|
249 | if (!methodsEnumerable) for (var i = 0, l = methods.length; i < l; i++){
|
250 | fn.call(prototype, prototype[methods[i]], methods[i]);
|
251 | }
|
252 | for (var key in prototype) fn.call(prototype, prototype[key], key);
|
253 | };
|
254 | }
|
255 |
|
256 | return force;
|
257 | };
|
258 |
|
259 | force('String', String, [
|
260 | 'charAt', 'charCodeAt', 'concat', 'contains', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search',
|
261 | 'slice', 'split', 'substr', 'substring', 'trim', 'toLowerCase', 'toUpperCase'
|
262 | ])('Array', Array, [
|
263 | 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice',
|
264 | 'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce', 'reduceRight', 'contains'
|
265 | ])('Number', Number, [
|
266 | 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision'
|
267 | ])('Function', Function, [
|
268 | 'apply', 'call', 'bind'
|
269 | ])('RegExp', RegExp, [
|
270 | 'exec', 'test'
|
271 | ])('Object', Object, [
|
272 | 'create', 'defineProperty', 'defineProperties', 'keys',
|
273 | 'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames',
|
274 | 'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen'
|
275 | ])('Date', Date, ['now']);
|
276 |
|
277 | Object.extend = extend.overloadSetter();
|
278 |
|
279 | Date.extend('now', function(){
|
280 | return +(new Date);
|
281 | });
|
282 |
|
283 | new Type('Boolean', Boolean);
|
284 |
|
285 |
|
286 |
|
287 | Number.prototype.$family = function(){
|
288 | return isFinite(this) ? 'number' : 'null';
|
289 | }.hide();
|
290 |
|
291 |
|
292 |
|
293 | Number.extend('random', function(min, max){
|
294 | return Math.floor(Math.random() * (max - min + 1) + min);
|
295 | });
|
296 |
|
297 |
|
298 |
|
299 | Array.implement({
|
300 |
|
301 |
|
302 |
|
303 | each: function(fn, bind){
|
304 | Array.forEach(this, fn, bind);
|
305 | return this;
|
306 | }
|
307 |
|
308 | });
|
309 |
|
310 | Object.extend({
|
311 |
|
312 | keys: function(object){
|
313 | var keys = [];
|
314 | for (var k in object){
|
315 | if (hasOwnProperty.call(object, k)) keys.push(k);
|
316 | }
|
317 |
|
318 | return keys;
|
319 | },
|
320 |
|
321 | forEach: function(object, fn, bind){
|
322 | Object.keys(object).forEach(function(key){
|
323 | fn.call(bind, object[key], key, object);
|
324 | });
|
325 | }
|
326 |
|
327 | });
|
328 |
|
329 | Object.each = Object.forEach;
|
330 |
|
331 |
|
332 |
|
333 |
|
334 | var cloneOf = function(item){
|
335 | switch (typeOf(item)){
|
336 | case 'array': return item.clone();
|
337 | case 'object': return Object.clone(item);
|
338 | default: return item;
|
339 | }
|
340 | };
|
341 |
|
342 | Array.implement('clone', function(){
|
343 | var i = this.length, clone = new Array(i);
|
344 | while (i--) clone[i] = cloneOf(this[i]);
|
345 | return clone;
|
346 | });
|
347 |
|
348 | var mergeOne = function(source, key, current){
|
349 | switch (typeOf(current)){
|
350 | case 'object':
|
351 | if (typeOf(source[key]) == 'object') Object.merge(source[key], current);
|
352 | else source[key] = Object.clone(current);
|
353 | break;
|
354 | case 'array': source[key] = current.clone(); break;
|
355 | default: source[key] = current;
|
356 | }
|
357 | return source;
|
358 | };
|
359 |
|
360 | Object.extend({
|
361 |
|
362 | merge: function(source, k, v){
|
363 | if (typeOf(k) == 'string') return mergeOne(source, k, v);
|
364 | for (var i = 1, l = arguments.length; i < l; i++){
|
365 | var object = arguments[i];
|
366 | for (var key in object) mergeOne(source, key, object[key]);
|
367 | }
|
368 | return source;
|
369 | },
|
370 |
|
371 | clone: function(object){
|
372 | var clone = {};
|
373 | for (var key in object) clone[key] = cloneOf(object[key]);
|
374 | return clone;
|
375 | },
|
376 |
|
377 | append: function(original){
|
378 | for (var i = 1, l = arguments.length; i < l; i++){
|
379 | var extended = arguments[i] || {};
|
380 | for (var key in extended) original[key] = extended[key];
|
381 | }
|
382 | return original;
|
383 | }
|
384 |
|
385 | });
|
386 |
|
387 |
|
388 |
|
389 | ['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each(function(name){
|
390 | new Type(name);
|
391 | });
|
392 |
|
393 |
|
394 |
|
395 | var UID = Date.now();
|
396 |
|
397 | String.extend('uniqueID', function(){
|
398 | return (UID++).toString(36);
|
399 | });
|
400 |
|
401 |
|
402 |
|
403 | })();
|
404 |
|
405 |
|
406 |
|
407 |
|
408 |
|
409 |
|
410 |
|
411 |
|
412 |
|
413 |
|
414 |
|
415 |
|
416 |
|
417 |
|
418 |
|
419 |
|
420 |
|
421 | Array.implement({
|
422 |
|
423 |
|
424 |
|
425 | clean: function(){
|
426 | return this.filter(function(item){
|
427 | return item != null;
|
428 | });
|
429 | },
|
430 |
|
431 | invoke: function(methodName){
|
432 | var args = Array.slice(arguments, 1);
|
433 | return this.map(function(item){
|
434 | return item[methodName].apply(item, args);
|
435 | });
|
436 | },
|
437 |
|
438 | associate: function(keys){
|
439 | var obj = {}, length = Math.min(this.length, keys.length);
|
440 | for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
|
441 | return obj;
|
442 | },
|
443 |
|
444 | link: function(object){
|
445 | var result = {};
|
446 | for (var i = 0, l = this.length; i < l; i++){
|
447 | for (var key in object){
|
448 | if (object[key](this[i])){
|
449 | result[key] = this[i];
|
450 | delete object[key];
|
451 | break;
|
452 | }
|
453 | }
|
454 | }
|
455 | return result;
|
456 | },
|
457 |
|
458 | contains: function(item, from){
|
459 | return this.indexOf(item, from) != -1;
|
460 | },
|
461 |
|
462 | append: function(array){
|
463 | this.push.apply(this, array);
|
464 | return this;
|
465 | },
|
466 |
|
467 | getLast: function(){
|
468 | return (this.length) ? this[this.length - 1] : null;
|
469 | },
|
470 |
|
471 | getRandom: function(){
|
472 | return (this.length) ? this[Number.random(0, this.length - 1)] : null;
|
473 | },
|
474 |
|
475 | include: function(item){
|
476 | if (!this.contains(item)) this.push(item);
|
477 | return this;
|
478 | },
|
479 |
|
480 | combine: function(array){
|
481 | for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
|
482 | return this;
|
483 | },
|
484 |
|
485 | erase: function(item){
|
486 | for (var i = this.length; i--;){
|
487 | if (this[i] === item) this.splice(i, 1);
|
488 | }
|
489 | return this;
|
490 | },
|
491 |
|
492 | empty: function(){
|
493 | this.length = 0;
|
494 | return this;
|
495 | },
|
496 |
|
497 | flatten: function(){
|
498 | var array = [];
|
499 | for (var i = 0, l = this.length; i < l; i++){
|
500 | var type = typeOf(this[i]);
|
501 | if (type == 'null') continue;
|
502 | array = array.concat((type == 'array' || type == 'collection' || type == 'arguments' || instanceOf(this[i], Array)) ? Array.flatten(this[i]) : this[i]);
|
503 | }
|
504 | return array;
|
505 | },
|
506 |
|
507 | pick: function(){
|
508 | for (var i = 0, l = this.length; i < l; i++){
|
509 | if (this[i] != null) return this[i];
|
510 | }
|
511 | return null;
|
512 | },
|
513 |
|
514 | hexToRgb: function(array){
|
515 | if (this.length != 3) return null;
|
516 | var rgb = this.map(function(value){
|
517 | if (value.length == 1) value += value;
|
518 | return parseInt(value, 16);
|
519 | });
|
520 | return (array) ? rgb : 'rgb(' + rgb + ')';
|
521 | },
|
522 |
|
523 | rgbToHex: function(array){
|
524 | if (this.length < 3) return null;
|
525 | if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
|
526 | var hex = [];
|
527 | for (var i = 0; i < 3; i++){
|
528 | var bit = (this[i] - 0).toString(16);
|
529 | hex.push((bit.length == 1) ? '0' + bit : bit);
|
530 | }
|
531 | return (array) ? hex : '#' + hex.join('');
|
532 | }
|
533 |
|
534 | });
|
535 |
|
536 |
|
537 |
|
538 |
|
539 |
|
540 |
|
541 |
|
542 |
|
543 |
|
544 |
|
545 |
|
546 |
|
547 |
|
548 |
|
549 |
|
550 |
|
551 |
|
552 |
|
553 |
|
554 | String.implement({
|
555 |
|
556 |
|
557 | contains: function(string, index){
|
558 | return (index ? String(this).slice(index) : String(this)).indexOf(string) > -1;
|
559 | },
|
560 |
|
561 |
|
562 | test: function(regex, params){
|
563 | return ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + regex, params)).test(this);
|
564 | },
|
565 |
|
566 | trim: function(){
|
567 | return String(this).replace(/^\s+|\s+$/g, '');
|
568 | },
|
569 |
|
570 | clean: function(){
|
571 | return String(this).replace(/\s+/g, ' ').trim();
|
572 | },
|
573 |
|
574 | camelCase: function(){
|
575 | return String(this).replace(/-\D/g, function(match){
|
576 | return match.charAt(1).toUpperCase();
|
577 | });
|
578 | },
|
579 |
|
580 | hyphenate: function(){
|
581 | return String(this).replace(/[A-Z]/g, function(match){
|
582 | return ('-' + match.charAt(0).toLowerCase());
|
583 | });
|
584 | },
|
585 |
|
586 | capitalize: function(){
|
587 | return String(this).replace(/\b[a-z]/g, function(match){
|
588 | return match.toUpperCase();
|
589 | });
|
590 | },
|
591 |
|
592 | escapeRegExp: function(){
|
593 | return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
|
594 | },
|
595 |
|
596 | toInt: function(base){
|
597 | return parseInt(this, base || 10);
|
598 | },
|
599 |
|
600 | toFloat: function(){
|
601 | return parseFloat(this);
|
602 | },
|
603 |
|
604 | hexToRgb: function(array){
|
605 | var hex = String(this).match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
|
606 | return (hex) ? hex.slice(1).hexToRgb(array) : null;
|
607 | },
|
608 |
|
609 | rgbToHex: function(array){
|
610 | var rgb = String(this).match(/\d{1,3}/g);
|
611 | return (rgb) ? rgb.rgbToHex(array) : null;
|
612 | },
|
613 |
|
614 | substitute: function(object, regexp){
|
615 | return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){
|
616 | if (match.charAt(0) == '\\') return match.slice(1);
|
617 | return (object[name] != null) ? object[name] : '';
|
618 | });
|
619 | }
|
620 |
|
621 | });
|
622 |
|
623 |
|
624 |
|
625 |
|
626 |
|
627 |
|
628 |
|
629 |
|
630 |
|
631 |
|
632 |
|
633 |
|
634 |
|
635 |
|
636 |
|
637 |
|
638 |
|
639 |
|
640 |
|
641 | Number.implement({
|
642 |
|
643 | limit: function(min, max){
|
644 | return Math.min(max, Math.max(min, this));
|
645 | },
|
646 |
|
647 | round: function(precision){
|
648 | precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0);
|
649 | return Math.round(this * precision) / precision;
|
650 | },
|
651 |
|
652 | times: function(fn, bind){
|
653 | for (var i = 0; i < this; i++) fn.call(bind, i, this);
|
654 | },
|
655 |
|
656 | toFloat: function(){
|
657 | return parseFloat(this);
|
658 | },
|
659 |
|
660 | toInt: function(base){
|
661 | return parseInt(this, base || 10);
|
662 | }
|
663 |
|
664 | });
|
665 |
|
666 | Number.alias('each', 'times');
|
667 |
|
668 | (function(math){
|
669 | var methods = {};
|
670 | math.each(function(name){
|
671 | if (!Number[name]) methods[name] = function(){
|
672 | return Math[name].apply(null, [this].concat(Array.from(arguments)));
|
673 | };
|
674 | });
|
675 | Number.implement(methods);
|
676 | })(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);
|
677 |
|
678 |
|
679 |
|
680 |
|
681 |
|
682 |
|
683 |
|
684 |
|
685 |
|
686 |
|
687 |
|
688 |
|
689 |
|
690 |
|
691 |
|
692 |
|
693 |
|
694 | Function.extend({
|
695 |
|
696 | attempt: function(){
|
697 | for (var i = 0, l = arguments.length; i < l; i++){
|
698 | try {
|
699 | return arguments[i]();
|
700 | } catch (e){}
|
701 | }
|
702 | return null;
|
703 | }
|
704 |
|
705 | });
|
706 |
|
707 | Function.implement({
|
708 |
|
709 | attempt: function(args, bind){
|
710 | try {
|
711 | return this.apply(bind, Array.from(args));
|
712 | } catch (e){}
|
713 |
|
714 | return null;
|
715 | },
|
716 |
|
717 |
|
718 |
|
719 | pass: function(args, bind){
|
720 | var self = this;
|
721 | if (args != null) args = Array.from(args);
|
722 | return function(){
|
723 | return self.apply(bind, args || arguments);
|
724 | };
|
725 | },
|
726 |
|
727 | delay: function(delay, bind, args){
|
728 | return setTimeout(this.pass((args == null ? [] : args), bind), delay);
|
729 | },
|
730 |
|
731 | periodical: function(periodical, bind, args){
|
732 | return setInterval(this.pass((args == null ? [] : args), bind), periodical);
|
733 | }
|
734 |
|
735 | });
|
736 |
|
737 |
|
738 |
|
739 |
|
740 |
|
741 |
|
742 |
|
743 |
|
744 |
|
745 |
|
746 |
|
747 |
|
748 |
|
749 |
|
750 |
|
751 |
|
752 |
|
753 |
|
754 |
|
755 | (function(){
|
756 |
|
757 | var hasOwnProperty = Object.prototype.hasOwnProperty;
|
758 |
|
759 | Object.extend({
|
760 |
|
761 | subset: function(object, keys){
|
762 | var results = {};
|
763 | for (var i = 0, l = keys.length; i < l; i++){
|
764 | var k = keys[i];
|
765 | if (k in object) results[k] = object[k];
|
766 | }
|
767 | return results;
|
768 | },
|
769 |
|
770 | map: function(object, fn, bind){
|
771 | var results = {};
|
772 | var keys = Object.keys(object);
|
773 | for (var i = 0; i < keys.length; i++){
|
774 | var key = keys[i];
|
775 | results[key] = fn.call(bind, object[key], key, object);
|
776 | }
|
777 | return results;
|
778 | },
|
779 |
|
780 | filter: function(object, fn, bind){
|
781 | var results = {};
|
782 | var keys = Object.keys(object);
|
783 | for (var i = 0; i < keys.length; i++){
|
784 | var key = keys[i], value = object[key];
|
785 | if (fn.call(bind, value, key, object)) results[key] = value;
|
786 | }
|
787 | return results;
|
788 | },
|
789 |
|
790 | every: function(object, fn, bind){
|
791 | var keys = Object.keys(object);
|
792 | for (var i = 0; i < keys.length; i++){
|
793 | var key = keys[i];
|
794 | if (!fn.call(bind, object[key], key)) return false;
|
795 | }
|
796 | return true;
|
797 | },
|
798 |
|
799 | some: function(object, fn, bind){
|
800 | var keys = Object.keys(object);
|
801 | for (var i = 0; i < keys.length; i++){
|
802 | var key = keys[i];
|
803 | if (fn.call(bind, object[key], key)) return true;
|
804 | }
|
805 | return false;
|
806 | },
|
807 |
|
808 | values: function(object){
|
809 | var values = [];
|
810 | var keys = Object.keys(object);
|
811 | for (var i = 0; i < keys.length; i++){
|
812 | var k = keys[i];
|
813 | values.push(object[k]);
|
814 | }
|
815 | return values;
|
816 | },
|
817 |
|
818 | getLength: function(object){
|
819 | return Object.keys(object).length;
|
820 | },
|
821 |
|
822 | keyOf: function(object, value){
|
823 | var keys = Object.keys(object);
|
824 | for (var i = 0; i < keys.length; i++){
|
825 | var key = keys[i];
|
826 | if (object[key] === value) return key;
|
827 | }
|
828 | return null;
|
829 | },
|
830 |
|
831 | contains: function(object, value){
|
832 | return Object.keyOf(object, value) != null;
|
833 | },
|
834 |
|
835 | toQueryString: function(object, base){
|
836 | var queryString = [];
|
837 |
|
838 | Object.each(object, function(value, key){
|
839 | if (base) key = base + '[' + key + ']';
|
840 | var result;
|
841 | switch (typeOf(value)){
|
842 | case 'object': result = Object.toQueryString(value, key); break;
|
843 | case 'array':
|
844 | var qs = {};
|
845 | value.each(function(val, i){
|
846 | qs[i] = val;
|
847 | });
|
848 | result = Object.toQueryString(qs, key);
|
849 | break;
|
850 | default: result = key + '=' + encodeURIComponent(value);
|
851 | }
|
852 | if (value != null) queryString.push(result);
|
853 | });
|
854 |
|
855 | return queryString.join('&');
|
856 | }
|
857 |
|
858 | });
|
859 |
|
860 | })();
|
861 |
|
862 |
|
863 |
|
864 |
|
865 |
|
866 |
|
867 |
|
868 |
|
869 |
|
870 |
|
871 |
|
872 |
|
873 |
|
874 |
|
875 |
|
876 |
|
877 |
|
878 |
|
879 |
|
880 | (function(){
|
881 |
|
882 | var Class = this.Class = new Type('Class', function(params){
|
883 | if (instanceOf(params, Function)) params = {initialize: params};
|
884 |
|
885 | var newClass = function(){
|
886 | reset(this);
|
887 | if (newClass.$prototyping) return this;
|
888 | this.$caller = null;
|
889 | this.$family = null;
|
890 | var value = (this.initialize) ? this.initialize.apply(this, arguments) : this;
|
891 | this.$caller = this.caller = null;
|
892 | return value;
|
893 | }.extend(this).implement(params);
|
894 |
|
895 | newClass.$constructor = Class;
|
896 | newClass.prototype.$constructor = newClass;
|
897 | newClass.prototype.parent = parent;
|
898 |
|
899 | return newClass;
|
900 | });
|
901 |
|
902 | var parent = function(){
|
903 | if (!this.$caller) throw new Error('The method "parent" cannot be called.');
|
904 | var name = this.$caller.$name,
|
905 | parent = this.$caller.$owner.parent,
|
906 | previous = (parent) ? parent.prototype[name] : null;
|
907 | if (!previous) throw new Error('The method "' + name + '" has no parent.');
|
908 | return previous.apply(this, arguments);
|
909 | };
|
910 |
|
911 | var reset = function(object){
|
912 | for (var key in object){
|
913 | var value = object[key];
|
914 | switch (typeOf(value)){
|
915 | case 'object':
|
916 | var F = function(){};
|
917 | F.prototype = value;
|
918 | object[key] = reset(new F);
|
919 | break;
|
920 | case 'array': object[key] = value.clone(); break;
|
921 | }
|
922 | }
|
923 | return object;
|
924 | };
|
925 |
|
926 | var wrap = function(self, key, method){
|
927 | if (method.$origin) method = method.$origin;
|
928 | var wrapper = function(){
|
929 | if (method.$protected && this.$caller == null) throw new Error('The method "' + key + '" cannot be called.');
|
930 | var caller = this.caller, current = this.$caller;
|
931 | this.caller = current; this.$caller = wrapper;
|
932 | var result = method.apply(this, arguments);
|
933 | this.$caller = current; this.caller = caller;
|
934 | return result;
|
935 | }.extend({$owner: self, $origin: method, $name: key});
|
936 | return wrapper;
|
937 | };
|
938 |
|
939 | var implement = function(key, value, retain){
|
940 | if (Class.Mutators.hasOwnProperty(key)){
|
941 | value = Class.Mutators[key].call(this, value);
|
942 | if (value == null) return this;
|
943 | }
|
944 |
|
945 | if (typeOf(value) == 'function'){
|
946 | if (value.$hidden) return this;
|
947 | this.prototype[key] = (retain) ? value : wrap(this, key, value);
|
948 | } else {
|
949 | Object.merge(this.prototype, key, value);
|
950 | }
|
951 |
|
952 | return this;
|
953 | };
|
954 |
|
955 | var getInstance = function(klass){
|
956 | klass.$prototyping = true;
|
957 | var proto = new klass;
|
958 | delete klass.$prototyping;
|
959 | return proto;
|
960 | };
|
961 |
|
962 | Class.implement('implement', implement.overloadSetter());
|
963 |
|
964 | Class.Mutators = {
|
965 |
|
966 | Extends: function(parent){
|
967 | this.parent = parent;
|
968 | this.prototype = getInstance(parent);
|
969 | },
|
970 |
|
971 | Implements: function(items){
|
972 | Array.from(items).each(function(item){
|
973 | var instance = new item;
|
974 | for (var key in instance) implement.call(this, key, instance[key], true);
|
975 | }, this);
|
976 | }
|
977 | };
|
978 |
|
979 | })();
|
980 |
|
981 |
|
982 |
|
983 |
|
984 |
|
985 |
|
986 |
|
987 |
|
988 |
|
989 |
|
990 |
|
991 |
|
992 |
|
993 |
|
994 |
|
995 |
|
996 |
|
997 | (function(){
|
998 |
|
999 | this.Chain = new Class({
|
1000 |
|
1001 | $chain: [],
|
1002 |
|
1003 | chain: function(){
|
1004 | this.$chain.append(Array.flatten(arguments));
|
1005 | return this;
|
1006 | },
|
1007 |
|
1008 | callChain: function(){
|
1009 | return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
|
1010 | },
|
1011 |
|
1012 | clearChain: function(){
|
1013 | this.$chain.empty();
|
1014 | return this;
|
1015 | }
|
1016 |
|
1017 | });
|
1018 |
|
1019 | var removeOn = function(string){
|
1020 | return string.replace(/^on([A-Z])/, function(full, first){
|
1021 | return first.toLowerCase();
|
1022 | });
|
1023 | };
|
1024 |
|
1025 | this.Events = new Class({
|
1026 |
|
1027 | $events: {},
|
1028 |
|
1029 | addEvent: function(type, fn, internal){
|
1030 | type = removeOn(type);
|
1031 |
|
1032 |
|
1033 |
|
1034 | this.$events[type] = (this.$events[type] || []).include(fn);
|
1035 | if (internal) fn.internal = true;
|
1036 | return this;
|
1037 | },
|
1038 |
|
1039 | addEvents: function(events){
|
1040 | for (var type in events) this.addEvent(type, events[type]);
|
1041 | return this;
|
1042 | },
|
1043 |
|
1044 | fireEvent: function(type, args, delay){
|
1045 | type = removeOn(type);
|
1046 | var events = this.$events[type];
|
1047 | if (!events) return this;
|
1048 | args = Array.from(args);
|
1049 | events.each(function(fn){
|
1050 | if (delay) fn.delay(delay, this, args);
|
1051 | else fn.apply(this, args);
|
1052 | }, this);
|
1053 | return this;
|
1054 | },
|
1055 |
|
1056 | removeEvent: function(type, fn){
|
1057 | type = removeOn(type);
|
1058 | var events = this.$events[type];
|
1059 | if (events && !fn.internal){
|
1060 | var index = events.indexOf(fn);
|
1061 | if (index != -1) delete events[index];
|
1062 | }
|
1063 | return this;
|
1064 | },
|
1065 |
|
1066 | removeEvents: function(events){
|
1067 | var type;
|
1068 | if (typeOf(events) == 'object'){
|
1069 | for (type in events) this.removeEvent(type, events[type]);
|
1070 | return this;
|
1071 | }
|
1072 | if (events) events = removeOn(events);
|
1073 | for (type in this.$events){
|
1074 | if (events && events != type) continue;
|
1075 | var fns = this.$events[type];
|
1076 | for (var i = fns.length; i--;) if (i in fns){
|
1077 | this.removeEvent(type, fns[i]);
|
1078 | }
|
1079 | }
|
1080 | return this;
|
1081 | }
|
1082 |
|
1083 | });
|
1084 |
|
1085 | this.Options = new Class({
|
1086 |
|
1087 | setOptions: function(){
|
1088 | var options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments));
|
1089 | if (this.addEvent) for (var option in options){
|
1090 | if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
|
1091 | this.addEvent(option, options[option]);
|
1092 | delete options[option];
|
1093 | }
|
1094 | return this;
|
1095 | }
|
1096 |
|
1097 | });
|
1098 |
|
1099 | })();
|
1100 |
|
1101 |
|
1102 |
|
1103 |
|
1104 |
|
1105 |
|
1106 |
|
1107 |
|
1108 |
|
1109 |
|
1110 |
|
1111 |
|
1112 |
|
1113 |
|
1114 |
|
1115 |
|
1116 |
|
1117 |
|
1118 |
|
1119 | if (typeof JSON == 'undefined') this.JSON = {};
|
1120 |
|
1121 |
|
1122 |
|
1123 | (function(){
|
1124 |
|
1125 | var special = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'};
|
1126 |
|
1127 | var escape = function(chr){
|
1128 | return special[chr] || '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4);
|
1129 | };
|
1130 |
|
1131 | JSON.validate = function(string){
|
1132 | string = string.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
|
1133 | replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
|
1134 | replace(/(?:^|:|,)(?:\s*\[)+/g, '');
|
1135 |
|
1136 | return (/^[\],:{}\s]*$/).test(string);
|
1137 | };
|
1138 |
|
1139 | JSON.encode = JSON.stringify ? function(obj){
|
1140 | return JSON.stringify(obj);
|
1141 | } : function(obj){
|
1142 | if (obj && obj.toJSON) obj = obj.toJSON();
|
1143 |
|
1144 | switch (typeOf(obj)){
|
1145 | case 'string':
|
1146 | return '"' + obj.replace(/[\x00-\x1f\\"]/g, escape) + '"';
|
1147 | case 'array':
|
1148 | return '[' + obj.map(JSON.encode).clean() + ']';
|
1149 | case 'object': case 'hash':
|
1150 | var string = [];
|
1151 | Object.each(obj, function(value, key){
|
1152 | var json = JSON.encode(value);
|
1153 | if (json) string.push(JSON.encode(key) + ':' + json);
|
1154 | });
|
1155 | return '{' + string + '}';
|
1156 | case 'number': case 'boolean': return '' + obj;
|
1157 | case 'null': return 'null';
|
1158 | }
|
1159 |
|
1160 | return null;
|
1161 | };
|
1162 |
|
1163 | JSON.secure = true;
|
1164 |
|
1165 |
|
1166 | JSON.decode = function(string, secure){
|
1167 | if (!string || typeOf(string) != 'string') return null;
|
1168 |
|
1169 | if (secure == null) secure = JSON.secure;
|
1170 | if (secure){
|
1171 | if (JSON.parse) return JSON.parse(string);
|
1172 | if (!JSON.validate(string)) throw new Error('JSON could not decode the input; security is enabled and the value is not secure.');
|
1173 | }
|
1174 |
|
1175 | return eval('(' + string + ')');
|
1176 | };
|
1177 |
|
1178 | })();
|