Created
March 17, 2010 00:22
-
-
Save ahem/334708 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MooTools core functionality usefull for server side developement with node.js | |
// Exports added to bottom of file so it can be required like a CommonJS module. | |
/* | |
--- | |
script: Core.js | |
description: The core of MooTools, contains all the base functions and the Native and Hash implementations. Required by all the other scripts. | |
license: MIT-style license. | |
copyright: Copyright (c) 2006-2008 [Valerio Proietti](http://mad4milk.net/). | |
authors: The MooTools production team (http://mootools.net/developers/) | |
inspiration: | |
- 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) | |
- Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php) | |
provides: [Mootools, Native, Hash.base, Array.each, $util] | |
... | |
*/ | |
var MooTools = { | |
'version': '1.2.4', | |
'build': '0d9113241a90b9cd5643b926795852a2026710d4' | |
}; | |
var Native = function(options){ | |
options = options || {}; | |
var name = options.name; | |
var legacy = options.legacy; | |
var protect = options.protect; | |
var methods = options.implement; | |
var generics = options.generics; | |
var initialize = options.initialize; | |
var afterImplement = options.afterImplement || function(){}; | |
var object = initialize || legacy; | |
generics = generics !== false; | |
object.constructor = Native; | |
object.$family = {name: 'native'}; | |
if (legacy && initialize) object.prototype = legacy.prototype; | |
object.prototype.constructor = object; | |
if (name){ | |
var family = name.toLowerCase(); | |
object.prototype.$family = {name: family}; | |
Native.typize(object, family); | |
} | |
var add = function(obj, name, method, force){ | |
if (!protect || force || !obj.prototype[name]) obj.prototype[name] = method; | |
if (generics) Native.genericize(obj, name, protect); | |
afterImplement.call(obj, name, method); | |
return obj; | |
}; | |
object.alias = function(a1, a2, a3){ | |
if (typeof a1 == 'string'){ | |
var pa1 = this.prototype[a1]; | |
if ((a1 = pa1)) return add(this, a2, a1, a3); | |
} | |
for (var a in a1) this.alias(a, a1[a], a2); | |
return this; | |
}; | |
object.implement = function(a1, a2, a3){ | |
if (typeof a1 == 'string') return add(this, a1, a2, a3); | |
for (var p in a1) add(this, p, a1[p], a2); | |
return this; | |
}; | |
if (methods) object.implement(methods); | |
return object; | |
}; | |
Native.genericize = function(object, property, check){ | |
if ((!check || !object[property]) && typeof object.prototype[property] == 'function') object[property] = function(){ | |
var args = Array.prototype.slice.call(arguments); | |
return object.prototype[property].apply(args.shift(), args); | |
}; | |
}; | |
Native.implement = function(objects, properties){ | |
for (var i = 0, l = objects.length; i < l; i++) objects[i].implement(properties); | |
}; | |
Native.typize = function(object, family){ | |
if (!object.type) object.type = function(item){ | |
return ($type(item) === family); | |
}; | |
}; | |
(function(){ | |
var natives = {'Array': Array, 'Date': Date, 'Function': Function, 'Number': Number, 'RegExp': RegExp, 'String': String}; | |
for (var n in natives) new Native({name: n, initialize: natives[n], protect: true}); | |
var types = {'boolean': Boolean, 'native': Native, 'object': Object}; | |
for (var t in types) Native.typize(types[t], t); | |
var generics = { | |
'Array': ["concat", "indexOf", "join", "lastIndexOf", "pop", "push", "reverse", "shift", "slice", "sort", "splice", "toString", "unshift", "valueOf"], | |
'String': ["charAt", "charCodeAt", "concat", "indexOf", "lastIndexOf", "match", "replace", "search", "slice", "split", "substr", "substring", "toLowerCase", "toUpperCase", "valueOf"] | |
}; | |
for (var g in generics){ | |
for (var i = generics[g].length; i--;) Native.genericize(natives[g], generics[g][i], true); | |
} | |
})(); | |
var Hash = new Native({ | |
name: 'Hash', | |
initialize: function(object){ | |
if ($type(object) == 'hash') object = $unlink(object.getClean()); | |
for (var key in object) this[key] = object[key]; | |
return this; | |
} | |
}); | |
Hash.implement({ | |
forEach: function(fn, bind){ | |
for (var key in this){ | |
if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this); | |
} | |
}, | |
getClean: function(){ | |
var clean = {}; | |
for (var key in this){ | |
if (this.hasOwnProperty(key)) clean[key] = this[key]; | |
} | |
return clean; | |
}, | |
getLength: function(){ | |
var length = 0; | |
for (var key in this){ | |
if (this.hasOwnProperty(key)) length++; | |
} | |
return length; | |
} | |
}); | |
Hash.alias('forEach', 'each'); | |
Array.implement({ | |
forEach: function(fn, bind){ | |
for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[i], i, this); | |
} | |
}); | |
Array.alias('forEach', 'each'); | |
function $A(iterable){ | |
if (iterable.item){ | |
var l = iterable.length, array = new Array(l); | |
while (l--) array[l] = iterable[l]; | |
return array; | |
} | |
return Array.prototype.slice.call(iterable); | |
}; | |
function $arguments(i){ | |
return function(){ | |
return arguments[i]; | |
}; | |
}; | |
function $chk(obj){ | |
return !!(obj || obj === 0); | |
}; | |
function $clear(timer){ | |
clearTimeout(timer); | |
clearInterval(timer); | |
return null; | |
}; | |
function $defined(obj){ | |
return (obj != undefined); | |
}; | |
function $each(iterable, fn, bind){ | |
var type = $type(iterable); | |
((type == 'arguments' || type == 'collection' || type == 'array') ? Array : Hash).each(iterable, fn, bind); | |
}; | |
function $empty(){}; | |
function $extend(original, extended){ | |
for (var key in (extended || {})) original[key] = extended[key]; | |
return original; | |
}; | |
function $H(object){ | |
return new Hash(object); | |
}; | |
function $lambda(value){ | |
return ($type(value) == 'function') ? value : function(){ | |
return value; | |
}; | |
}; | |
function $merge(){ | |
var args = Array.slice(arguments); | |
args.unshift({}); | |
return $mixin.apply(null, args); | |
}; | |
function $mixin(mix){ | |
for (var i = 1, l = arguments.length; i < l; i++){ | |
var object = arguments[i]; | |
if ($type(object) != 'object') continue; | |
for (var key in object){ | |
var op = object[key], mp = mix[key]; | |
mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $mixin(mp, op) : $unlink(op); | |
} | |
} | |
return mix; | |
}; | |
function $pick(){ | |
for (var i = 0, l = arguments.length; i < l; i++){ | |
if (arguments[i] != undefined) return arguments[i]; | |
} | |
return null; | |
}; | |
function $random(min, max){ | |
return Math.floor(Math.random() * (max - min + 1) + min); | |
}; | |
function $splat(obj){ | |
var type = $type(obj); | |
return (type) ? ((type != 'array' && type != 'arguments') ? [obj] : obj) : []; | |
}; | |
var $time = Date.now || function(){ | |
return +new Date; | |
}; | |
function $try(){ | |
for (var i = 0, l = arguments.length; i < l; i++){ | |
try { | |
return arguments[i](); | |
} catch(e){} | |
} | |
return null; | |
}; | |
function $type(obj){ | |
if (obj == undefined) return false; | |
if (obj.$family) return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name; | |
if (obj.nodeName){ | |
switch (obj.nodeType){ | |
case 1: return 'element'; | |
case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace'; | |
} | |
} else if (typeof obj.length == 'number'){ | |
if (obj.callee) return 'arguments'; | |
else if (obj.item) return 'collection'; | |
} | |
return typeof obj; | |
}; | |
function $unlink(object){ | |
var unlinked; | |
switch ($type(object)){ | |
case 'object': | |
unlinked = {}; | |
for (var p in object) unlinked[p] = $unlink(object[p]); | |
break; | |
case 'hash': | |
unlinked = new Hash(object); | |
break; | |
case 'array': | |
unlinked = []; | |
for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]); | |
break; | |
default: return object; | |
} | |
return unlinked; | |
}; | |
/* | |
--- | |
script: Array.js | |
description: Contains Array Prototypes like each, contains, and erase. | |
license: MIT-style license. | |
requires: | |
- /$util | |
- /Array.each | |
provides: [Array] | |
... | |
*/ | |
Array.implement({ | |
every: function(fn, bind){ | |
for (var i = 0, l = this.length; i < l; i++){ | |
if (!fn.call(bind, this[i], i, this)) return false; | |
} | |
return true; | |
}, | |
filter: function(fn, bind){ | |
var results = []; | |
for (var i = 0, l = this.length; i < l; i++){ | |
if (fn.call(bind, this[i], i, this)) results.push(this[i]); | |
} | |
return results; | |
}, | |
clean: function(){ | |
return this.filter($defined); | |
}, | |
indexOf: function(item, from){ | |
var len = this.length; | |
for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){ | |
if (this[i] === item) return i; | |
} | |
return -1; | |
}, | |
map: function(fn, bind){ | |
var results = []; | |
for (var i = 0, l = this.length; i < l; i++) results[i] = fn.call(bind, this[i], i, this); | |
return results; | |
}, | |
some: function(fn, bind){ | |
for (var i = 0, l = this.length; i < l; i++){ | |
if (fn.call(bind, this[i], i, this)) return true; | |
} | |
return false; | |
}, | |
associate: function(keys){ | |
var obj = {}, length = Math.min(this.length, keys.length); | |
for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; | |
return obj; | |
}, | |
link: function(object){ | |
var result = {}; | |
for (var i = 0, l = this.length; i < l; i++){ | |
for (var key in object){ | |
if (object[key](this[i])){ | |
result[key] = this[i]; | |
delete object[key]; | |
break; | |
} | |
} | |
} | |
return result; | |
}, | |
contains: function(item, from){ | |
return this.indexOf(item, from) != -1; | |
}, | |
extend: function(array){ | |
for (var i = 0, j = array.length; i < j; i++) this.push(array[i]); | |
return this; | |
}, | |
getLast: function(){ | |
return (this.length) ? this[this.length - 1] : null; | |
}, | |
getRandom: function(){ | |
return (this.length) ? this[$random(0, this.length - 1)] : null; | |
}, | |
include: function(item){ | |
if (!this.contains(item)) this.push(item); | |
return this; | |
}, | |
combine: function(array){ | |
for (var i = 0, l = array.length; i < l; i++) this.include(array[i]); | |
return this; | |
}, | |
erase: function(item){ | |
for (var i = this.length; i--; i){ | |
if (this[i] === item) this.splice(i, 1); | |
} | |
return this; | |
}, | |
empty: function(){ | |
this.length = 0; | |
return this; | |
}, | |
flatten: function(){ | |
var array = []; | |
for (var i = 0, l = this.length; i < l; i++){ | |
var type = $type(this[i]); | |
if (!type) continue; | |
array = array.concat((type == 'array' || type == 'collection' || type == 'arguments') ? Array.flatten(this[i]) : this[i]); | |
} | |
return array; | |
}, | |
hexToRgb: function(array){ | |
if (this.length != 3) return null; | |
var rgb = this.map(function(value){ | |
if (value.length == 1) value += value; | |
return value.toInt(16); | |
}); | |
return (array) ? rgb : 'rgb(' + rgb + ')'; | |
}, | |
rgbToHex: function(array){ | |
if (this.length < 3) return null; | |
if (this.length == 4 && this[3] == 0 && !array) return 'transparent'; | |
var hex = []; | |
for (var i = 0; i < 3; i++){ | |
var bit = (this[i] - 0).toString(16); | |
hex.push((bit.length == 1) ? '0' + bit : bit); | |
} | |
return (array) ? hex : '#' + hex.join(''); | |
} | |
}); | |
/* | |
--- | |
script: Function.js | |
description: Contains Function Prototypes like create, bind, pass, and delay. | |
license: MIT-style license. | |
requires: | |
- /Native | |
- /$util | |
provides: [Function] | |
... | |
*/ | |
Function.implement({ | |
extend: function(properties){ | |
for (var property in properties) this[property] = properties[property]; | |
return this; | |
}, | |
create: function(options){ | |
var self = this; | |
options = options || {}; | |
return function(event){ | |
var args = options.arguments; | |
args = (args != undefined) ? $splat(args) : Array.slice(arguments, (options.event) ? 1 : 0); | |
if (options.event) args = [event || window.event].extend(args); | |
var returns = function(){ | |
return self.apply(options.bind || null, args); | |
}; | |
if (options.delay) return setTimeout(returns, options.delay); | |
if (options.periodical) return setInterval(returns, options.periodical); | |
if (options.attempt) return $try(returns); | |
return returns(); | |
}; | |
}, | |
run: function(args, bind){ | |
return this.apply(bind, $splat(args)); | |
}, | |
pass: function(args, bind){ | |
return this.create({bind: bind, arguments: args}); | |
}, | |
bind: function(bind, args){ | |
return this.create({bind: bind, arguments: args}); | |
}, | |
bindWithEvent: function(bind, args){ | |
return this.create({bind: bind, arguments: args, event: true}); | |
}, | |
attempt: function(args, bind){ | |
return this.create({bind: bind, arguments: args, attempt: true})(); | |
}, | |
delay: function(delay, bind, args){ | |
return this.create({bind: bind, arguments: args, delay: delay})(); | |
}, | |
periodical: function(periodical, bind, args){ | |
return this.create({bind: bind, arguments: args, periodical: periodical})(); | |
} | |
}); | |
/* | |
--- | |
script: Number.js | |
description: Contains Number Prototypes like limit, round, times, and ceil. | |
license: MIT-style license. | |
requires: | |
- /Native | |
- /$util | |
provides: [Number] | |
... | |
*/ | |
Number.implement({ | |
limit: function(min, max){ | |
return Math.min(max, Math.max(min, this)); | |
}, | |
round: function(precision){ | |
precision = Math.pow(10, precision || 0); | |
return Math.round(this * precision) / precision; | |
}, | |
times: function(fn, bind){ | |
for (var i = 0; i < this; i++) fn.call(bind, i, this); | |
}, | |
toFloat: function(){ | |
return parseFloat(this); | |
}, | |
toInt: function(base){ | |
return parseInt(this, base || 10); | |
} | |
}); | |
Number.alias('times', 'each'); | |
(function(math){ | |
var methods = {}; | |
math.each(function(name){ | |
if (!Number[name]) methods[name] = function(){ | |
return Math[name].apply(null, [this].concat($A(arguments))); | |
}; | |
}); | |
Number.implement(methods); | |
})(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']); | |
/* | |
--- | |
script: String.js | |
description: Contains String Prototypes like camelCase, capitalize, test, and toInt. | |
license: MIT-style license. | |
requires: | |
- /Native | |
provides: [String] | |
... | |
*/ | |
String.implement({ | |
test: function(regex, params){ | |
return ((typeof regex == 'string') ? new RegExp(regex, params) : regex).test(this); | |
}, | |
contains: function(string, separator){ | |
return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : this.indexOf(string) > -1; | |
}, | |
trim: function(){ | |
return this.replace(/^\s+|\s+$/g, ''); | |
}, | |
clean: function(){ | |
return this.replace(/\s+/g, ' ').trim(); | |
}, | |
camelCase: function(){ | |
return this.replace(/-\D/g, function(match){ | |
return match.charAt(1).toUpperCase(); | |
}); | |
}, | |
hyphenate: function(){ | |
return this.replace(/[A-Z]/g, function(match){ | |
return ('-' + match.charAt(0).toLowerCase()); | |
}); | |
}, | |
capitalize: function(){ | |
return this.replace(/\b[a-z]/g, function(match){ | |
return match.toUpperCase(); | |
}); | |
}, | |
escapeRegExp: function(){ | |
return this.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1'); | |
}, | |
toInt: function(base){ | |
return parseInt(this, base || 10); | |
}, | |
toFloat: function(){ | |
return parseFloat(this); | |
}, | |
hexToRgb: function(array){ | |
var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); | |
return (hex) ? hex.slice(1).hexToRgb(array) : null; | |
}, | |
rgbToHex: function(array){ | |
var rgb = this.match(/\d{1,3}/g); | |
return (rgb) ? rgb.rgbToHex(array) : null; | |
}, | |
stripScripts: function(option){ | |
var scripts = ''; | |
var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(){ | |
scripts += arguments[1] + '\n'; | |
return ''; | |
}); | |
if (option === true) $exec(scripts); | |
else if ($type(option) == 'function') option(scripts, text); | |
return text; | |
}, | |
substitute: function(object, regexp){ | |
return this.replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){ | |
if (match.charAt(0) == '\\') return match.slice(1); | |
return (object[name] != undefined) ? object[name] : ''; | |
}); | |
} | |
}); | |
/* | |
--- | |
script: Hash.js | |
description: Contains Hash Prototypes. Provides a means for overcoming the JavaScript practical impossibility of extending native Objects. | |
license: MIT-style license. | |
requires: | |
- /Hash.base | |
provides: [Hash] | |
... | |
*/ | |
Hash.implement({ | |
has: Object.prototype.hasOwnProperty, | |
keyOf: function(value){ | |
for (var key in this){ | |
if (this.hasOwnProperty(key) && this[key] === value) return key; | |
} | |
return null; | |
}, | |
hasValue: function(value){ | |
return (Hash.keyOf(this, value) !== null); | |
}, | |
extend: function(properties){ | |
Hash.each(properties || {}, function(value, key){ | |
Hash.set(this, key, value); | |
}, this); | |
return this; | |
}, | |
combine: function(properties){ | |
Hash.each(properties || {}, function(value, key){ | |
Hash.include(this, key, value); | |
}, this); | |
return this; | |
}, | |
erase: function(key){ | |
if (this.hasOwnProperty(key)) delete this[key]; | |
return this; | |
}, | |
get: function(key){ | |
return (this.hasOwnProperty(key)) ? this[key] : null; | |
}, | |
set: function(key, value){ | |
if (!this[key] || this.hasOwnProperty(key)) this[key] = value; | |
return this; | |
}, | |
empty: function(){ | |
Hash.each(this, function(value, key){ | |
delete this[key]; | |
}, this); | |
return this; | |
}, | |
include: function(key, value){ | |
if (this[key] == undefined) this[key] = value; | |
return this; | |
}, | |
map: function(fn, bind){ | |
var results = new Hash; | |
Hash.each(this, function(value, key){ | |
results.set(key, fn.call(bind, value, key, this)); | |
}, this); | |
return results; | |
}, | |
filter: function(fn, bind){ | |
var results = new Hash; | |
Hash.each(this, function(value, key){ | |
if (fn.call(bind, value, key, this)) results.set(key, value); | |
}, this); | |
return results; | |
}, | |
every: function(fn, bind){ | |
for (var key in this){ | |
if (this.hasOwnProperty(key) && !fn.call(bind, this[key], key)) return false; | |
} | |
return true; | |
}, | |
some: function(fn, bind){ | |
for (var key in this){ | |
if (this.hasOwnProperty(key) && fn.call(bind, this[key], key)) return true; | |
} | |
return false; | |
}, | |
getKeys: function(){ | |
var keys = []; | |
Hash.each(this, function(value, key){ | |
keys.push(key); | |
}); | |
return keys; | |
}, | |
getValues: function(){ | |
var values = []; | |
Hash.each(this, function(value){ | |
values.push(value); | |
}); | |
return values; | |
}, | |
toQueryString: function(base){ | |
var queryString = []; | |
Hash.each(this, function(value, key){ | |
if (base) key = base + '[' + key + ']'; | |
var result; | |
switch ($type(value)){ | |
case 'object': result = Hash.toQueryString(value, key); break; | |
case 'array': | |
var qs = {}; | |
value.each(function(val, i){ | |
qs[i] = val; | |
}); | |
result = Hash.toQueryString(qs, key); | |
break; | |
default: result = key + '=' + encodeURIComponent(value); | |
} | |
if (value != undefined) queryString.push(result); | |
}); | |
return queryString.join('&'); | |
} | |
}); | |
Hash.alias({keyOf: 'indexOf', hasValue: 'contains'}); | |
$extend(exports, { | |
Hash: Hash, | |
$A :$A, | |
$arguments: $arguments, | |
$chk: $chk, | |
$defined: $defined, | |
$each: $each, | |
$extend: $extend, | |
$H: $H, | |
$lambda: $lambda, | |
$merge: $merge, | |
$mixin: $mixin, | |
$pick: $pick, | |
$random: $random, | |
$splat: $splat, | |
$time: $time, | |
$try: $try, | |
$type: $type, | |
$unlink: $unlink | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment