1.2.6
[mootools.git] / Source / Core / Core.js
blob34d6b6fa60529880fe454886f48944efe8da33e0
1 /*
2 ---
4 name: Core
6 description: The core of MooTools, contains all the base functions and the Native and Hash implementations. Required by all the other scripts.
8 license: MIT-style license.
10 copyright: Copyright (c) 2006-2008 [Valerio Proietti](http://mad4milk.net/).
12 authors: The MooTools production team (http://mootools.net/developers/)
14 inspiration:
15   - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)
16   - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php)
18 provides: [MooTools, Native, Hash.base, Array.each, $util]
20 ...
23 var MooTools = {
24         'version': '1.2.6',
25         'build': 'a3be7a0ef5205eb655c4ee11e8cbedcb3f2ffa95'
28 var Native = function(options){
29         options = options || {};
30         var name = options.name;
31         var legacy = options.legacy;
32         var protect = options.protect;
33         var methods = options.implement;
34         var generics = options.generics;
35         var initialize = options.initialize;
36         var afterImplement = options.afterImplement || function(){};
37         var object = initialize || legacy;
38         generics = generics !== false;
40         object.constructor = Native;
41         object.$family = {name: 'native'};
42         if (legacy && initialize) object.prototype = legacy.prototype;
43         object.prototype.constructor = object;
45         if (name){
46                 var family = name.toLowerCase();
47                 object.prototype.$family = {name: family};
48                 Native.typize(object, family);
49         }
51         var add = function(obj, name, method, force){
52                 if (!protect || force || !obj.prototype[name]) obj.prototype[name] = method;
53                 if (generics) Native.genericize(obj, name, protect);
54                 afterImplement.call(obj, name, method);
55                 return obj;
56         };
58         object.alias = function(a1, a2, a3){
59                 if (typeof a1 == 'string'){
60                         var pa1 = this.prototype[a1];
61                         if ((a1 = pa1)) return add(this, a2, a1, a3);
62                 }
63                 for (var a in a1) this.alias(a, a1[a], a2);
64                 return this;
65         };
67         object.implement = function(a1, a2, a3){
68                 if (typeof a1 == 'string') return add(this, a1, a2, a3);
69                 for (var p in a1) add(this, p, a1[p], a2);
70                 return this;
71         };
73         if (methods) object.implement(methods);
75         return object;
78 Native.genericize = function(object, property, check){
79         if ((!check || !object[property]) && typeof object.prototype[property] == 'function') object[property] = function(){
80                 var args = Array.prototype.slice.call(arguments);
81                 return object.prototype[property].apply(args.shift(), args);
82         };
85 Native.implement = function(objects, properties){
86         for (var i = 0, l = objects.length; i < l; i++) objects[i].implement(properties);
89 Native.typize = function(object, family){
90         if (!object.type) object.type = function(item){
91                 return ($type(item) === family);
92         };
95 (function(){
96         var natives = {'Array': Array, 'Date': Date, 'Function': Function, 'Number': Number, 'RegExp': RegExp, 'String': String};
97         for (var n in natives) new Native({name: n, initialize: natives[n], protect: true});
99         var types = {'boolean': Boolean, 'native': Native, 'object': Object};
100         for (var t in types) Native.typize(types[t], t);
102         var generics = {
103                 'Array': ["concat", "indexOf", "join", "lastIndexOf", "pop", "push", "reverse", "shift", "slice", "sort", "splice", "toString", "unshift", "valueOf"],
104                 'String': ["charAt", "charCodeAt", "concat", "indexOf", "lastIndexOf", "match", "replace", "search", "slice", "split", "substr", "substring", "toLowerCase", "toUpperCase", "valueOf"]
105         };
106         for (var g in generics){
107                 for (var i = generics[g].length; i--;) Native.genericize(natives[g], generics[g][i], true);
108         }
109 })();
111 var Hash = new Native({
113         name: 'Hash',
115         initialize: function(object){
116                 if ($type(object) == 'hash') object = $unlink(object.getClean());
117                 for (var key in object) this[key] = object[key];
118                 return this;
119         }
123 Hash.implement({
125         forEach: function(fn, bind){
126                 for (var key in this){
127                         if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this);
128                 }
129         },
131         getClean: function(){
132                 var clean = {};
133                 for (var key in this){
134                         if (this.hasOwnProperty(key)) clean[key] = this[key];
135                 }
136                 return clean;
137         },
139         getLength: function(){
140                 var length = 0;
141                 for (var key in this){
142                         if (this.hasOwnProperty(key)) length++;
143                 }
144                 return length;
145         }
149 Hash.alias('forEach', 'each');
151 Array.implement({
153         forEach: function(fn, bind){
154                 for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[i], i, this);
155         }
159 Array.alias('forEach', 'each');
161 function $A(iterable){
162         if (iterable.item){
163                 var l = iterable.length, array = new Array(l);
164                 while (l--) array[l] = iterable[l];
165                 return array;
166         }
167         return Array.prototype.slice.call(iterable);
170 function $arguments(i){
171         return function(){
172                 return arguments[i];
173         };
176 function $chk(obj){
177         return !!(obj || obj === 0);
180 function $clear(timer){
181         clearTimeout(timer);
182         clearInterval(timer);
183         return null;
186 function $defined(obj){
187         return (obj != undefined);
190 function $each(iterable, fn, bind){
191         var type = $type(iterable);
192         ((type == 'arguments' || type == 'collection' || type == 'array') ? Array : Hash).each(iterable, fn, bind);
195 function $empty(){};
197 function $extend(original, extended){
198         for (var key in (extended || {})) original[key] = extended[key];
199         return original;
202 function $H(object){
203         return new Hash(object);
206 function $lambda(value){
207         return ($type(value) == 'function') ? value : function(){
208                 return value;
209         };
212 function $merge(){
213         var args = Array.slice(arguments);
214         args.unshift({});
215         return $mixin.apply(null, args);
218 function $mixin(mix){
219         for (var i = 1, l = arguments.length; i < l; i++){
220                 var object = arguments[i];
221                 if ($type(object) != 'object') continue;
222                 for (var key in object){
223                         var op = object[key], mp = mix[key];
224                         mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $mixin(mp, op) : $unlink(op);
225                 }
226         }
227         return mix;
230 function $pick(){
231         for (var i = 0, l = arguments.length; i < l; i++){
232                 if (arguments[i] != undefined) return arguments[i];
233         }
234         return null;
237 function $random(min, max){
238         return Math.floor(Math.random() * (max - min + 1) + min);
241 function $splat(obj){
242         var type = $type(obj);
243         return (type) ? ((type != 'array' && type != 'arguments') ? [obj] : obj) : [];
246 var $time = Date.now || function(){
247         return +new Date;
250 function $try(){
251         for (var i = 0, l = arguments.length; i < l; i++){
252                 try {
253                         return arguments[i]();
254                 } catch(e){}
255         }
256         return null;
259 function $type(obj){
260         if (obj == undefined) return false;
261         if (obj.$family) return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name;
262         if (obj.nodeName){
263                 switch (obj.nodeType){
264                         case 1: return 'element';
265                         case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
266                 }
267         } else if (typeof obj.length == 'number'){
268                 if (obj.callee) return 'arguments';
269                 else if (obj.item) return 'collection';
270         }
271         return typeof obj;
274 function $unlink(object){
275         var unlinked;
276         switch ($type(object)){
277                 case 'object':
278                         unlinked = {};
279                         for (var p in object) unlinked[p] = $unlink(object[p]);
280                 break;
281                 case 'hash':
282                         unlinked = new Hash(object);
283                 break;
284                 case 'array':
285                         unlinked = [];
286                         for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]);
287                 break;
288                 default: return object;
289         }
290         return unlinked;