Revision 05f13042
Added by Marc Dequènes over 13 years ago
- ID 05f13042d910b390b3eeb3123fcdfe209e155da3
public/javascripts/prototype.js | ||
---|---|---|
/* Prototype JavaScript framework, version 1.6.0.3
|
||
* (c) 2005-2008 Sam Stephenson
|
||
/* Prototype JavaScript framework, version 1.6.1
|
||
* (c) 2005-2009 Sam Stephenson
|
||
*
|
||
* Prototype is freely distributable under the terms of an MIT-style license.
|
||
* For details, see the Prototype web site: http://www.prototypejs.org/
|
||
... | ... | |
*--------------------------------------------------------------------------*/
|
||
|
||
var Prototype = {
|
||
Version: '1.6.0.3',
|
||
|
||
Browser: {
|
||
IE: !!(window.attachEvent &&
|
||
navigator.userAgent.indexOf('Opera') === -1),
|
||
Opera: navigator.userAgent.indexOf('Opera') > -1,
|
||
WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
|
||
Gecko: navigator.userAgent.indexOf('Gecko') > -1 &&
|
||
navigator.userAgent.indexOf('KHTML') === -1,
|
||
MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
|
||
},
|
||
Version: '1.6.1',
|
||
|
||
Browser: (function(){
|
||
var ua = navigator.userAgent;
|
||
var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
|
||
return {
|
||
IE: !!window.attachEvent && !isOpera,
|
||
Opera: isOpera,
|
||
WebKit: ua.indexOf('AppleWebKit/') > -1,
|
||
Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
|
||
MobileSafari: /Apple.*Mobile.*Safari/.test(ua)
|
||
}
|
||
})(),
|
||
|
||
BrowserFeatures: {
|
||
XPath: !!document.evaluate,
|
||
SelectorsAPI: !!document.querySelector,
|
||
ElementExtensions: !!window.HTMLElement,
|
||
SpecificElementExtensions:
|
||
document.createElement('div')['__proto__'] &&
|
||
document.createElement('div')['__proto__'] !==
|
||
document.createElement('form')['__proto__']
|
||
ElementExtensions: (function() {
|
||
var constructor = window.Element || window.HTMLElement;
|
||
return !!(constructor && constructor.prototype);
|
||
})(),
|
||
SpecificElementExtensions: (function() {
|
||
if (typeof window.HTMLDivElement !== 'undefined')
|
||
return true;
|
||
|
||
var div = document.createElement('div');
|
||
var form = document.createElement('form');
|
||
var isSupported = false;
|
||
|
||
if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
|
||
isSupported = true;
|
||
}
|
||
|
||
div = form = null;
|
||
|
||
return isSupported;
|
||
})()
|
||
},
|
||
|
||
ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
|
||
... | ... | |
Prototype.BrowserFeatures.SpecificElementExtensions = false;
|
||
|
||
|
||
var Abstract = { };
|
||
|
||
|
||
var Try = {
|
||
these: function() {
|
||
var returnValue;
|
||
|
||
for (var i = 0, length = arguments.length; i < length; i++) {
|
||
var lambda = arguments[i];
|
||
try {
|
||
returnValue = lambda();
|
||
break;
|
||
} catch (e) { }
|
||
}
|
||
|
||
return returnValue;
|
||
}
|
||
};
|
||
|
||
/* Based on Alex Arnell's inheritance implementation. */
|
||
var Class = {
|
||
create: function() {
|
||
|
||
var Class = (function() {
|
||
function subclass() {};
|
||
function create() {
|
||
var parent = null, properties = $A(arguments);
|
||
if (Object.isFunction(properties[0]))
|
||
parent = properties.shift();
|
||
... | ... | |
klass.subclasses = [];
|
||
|
||
if (parent) {
|
||
var subclass = function() { };
|
||
subclass.prototype = parent.prototype;
|
||
klass.prototype = new subclass;
|
||
parent.subclasses.push(klass);
|
||
... | ... | |
klass.prototype.initialize = Prototype.emptyFunction;
|
||
|
||
klass.prototype.constructor = klass;
|
||
|
||
return klass;
|
||
}
|
||
};
|
||
|
||
Class.Methods = {
|
||
addMethods: function(source) {
|
||
function addMethods(source) {
|
||
var ancestor = this.superclass && this.superclass.prototype;
|
||
var properties = Object.keys(source);
|
||
|
||
if (!Object.keys({ toString: true }).length)
|
||
properties.push("toString", "valueOf");
|
||
if (!Object.keys({ toString: true }).length) {
|
||
if (source.toString != Object.prototype.toString)
|
||
properties.push("toString");
|
||
if (source.valueOf != Object.prototype.valueOf)
|
||
properties.push("valueOf");
|
||
}
|
||
|
||
for (var i = 0, length = properties.length; i < length; i++) {
|
||
var property = properties[i], value = source[property];
|
||
... | ... | |
value.argumentNames().first() == "$super") {
|
||
var method = value;
|
||
value = (function(m) {
|
||
return function() { return ancestor[m].apply(this, arguments) };
|
||
return function() { return ancestor[m].apply(this, arguments); };
|
||
})(property).wrap(method);
|
||
|
||
value.valueOf = method.valueOf.bind(method);
|
||
... | ... | |
|
||
return this;
|
||
}
|
||
};
|
||
|
||
var Abstract = { };
|
||
return {
|
||
create: create,
|
||
Methods: {
|
||
addMethods: addMethods
|
||
}
|
||
};
|
||
})();
|
||
(function() {
|
||
|
||
Object.extend = function(destination, source) {
|
||
for (var property in source)
|
||
destination[property] = source[property];
|
||
return destination;
|
||
};
|
||
var _toString = Object.prototype.toString;
|
||
|
||
function extend(destination, source) {
|
||
for (var property in source)
|
||
destination[property] = source[property];
|
||
return destination;
|
||
}
|
||
|
||
Object.extend(Object, {
|
||
inspect: function(object) {
|
||
function inspect(object) {
|
||
try {
|
||
if (Object.isUndefined(object)) return 'undefined';
|
||
if (isUndefined(object)) return 'undefined';
|
||
if (object === null) return 'null';
|
||
return object.inspect ? object.inspect() : String(object);
|
||
} catch (e) {
|
||
if (e instanceof RangeError) return '...';
|
||
throw e;
|
||
}
|
||
},
|
||
}
|
||
|
||
toJSON: function(object) {
|
||
function toJSON(object) {
|
||
var type = typeof object;
|
||
switch (type) {
|
||
case 'undefined':
|
||
... | ... | |
|
||
if (object === null) return 'null';
|
||
if (object.toJSON) return object.toJSON();
|
||
if (Object.isElement(object)) return;
|
||
if (isElement(object)) return;
|
||
|
||
var results = [];
|
||
for (var property in object) {
|
||
var value = Object.toJSON(object[property]);
|
||
if (!Object.isUndefined(value))
|
||
var value = toJSON(object[property]);
|
||
if (!isUndefined(value))
|
||
results.push(property.toJSON() + ': ' + value);
|
||
}
|
||
|
||
return '{' + results.join(', ') + '}';
|
||
},
|
||
}
|
||
|
||
toQueryString: function(object) {
|
||
function toQueryString(object) {
|
||
return $H(object).toQueryString();
|
||
},
|
||
}
|
||
|
||
toHTML: function(object) {
|
||
function toHTML(object) {
|
||
return object && object.toHTML ? object.toHTML() : String.interpret(object);
|
||
},
|
||
}
|
||
|
||
keys: function(object) {
|
||
var keys = [];
|
||
function keys(object) {
|
||
var results = [];
|
||
for (var property in object)
|
||
keys.push(property);
|
||
return keys;
|
||
},
|
||
results.push(property);
|
||
return results;
|
||
}
|
||
|
||
values: function(object) {
|
||
var values = [];
|
||
function values(object) {
|
||
var results = [];
|
||
for (var property in object)
|
||
values.push(object[property]);
|
||
return values;
|
||
},
|
||
results.push(object[property]);
|
||
return results;
|
||
}
|
||
|
||
clone: function(object) {
|
||
return Object.extend({ }, object);
|
||
},
|
||
function clone(object) {
|
||
return extend({ }, object);
|
||
}
|
||
|
||
isElement: function(object) {
|
||
function isElement(object) {
|
||
return !!(object && object.nodeType == 1);
|
||
},
|
||
}
|
||
|
||
function isArray(object) {
|
||
return _toString.call(object) == "[object Array]";
|
||
}
|
||
|
||
isArray: function(object) {
|
||
return object != null && typeof object == "object" &&
|
||
'splice' in object && 'join' in object;
|
||
},
|
||
|
||
isHash: function(object) {
|
||
function isHash(object) {
|
||
return object instanceof Hash;
|
||
},
|
||
}
|
||
|
||
isFunction: function(object) {
|
||
return typeof object == "function";
|
||
},
|
||
function isFunction(object) {
|
||
return typeof object === "function";
|
||
}
|
||
|
||
isString: function(object) {
|
||
return typeof object == "string";
|
||
},
|
||
function isString(object) {
|
||
return _toString.call(object) == "[object String]";
|
||
}
|
||
|
||
isNumber: function(object) {
|
||
return typeof object == "number";
|
||
},
|
||
function isNumber(object) {
|
||
return _toString.call(object) == "[object Number]";
|
||
}
|
||
|
||
isUndefined: function(object) {
|
||
return typeof object == "undefined";
|
||
function isUndefined(object) {
|
||
return typeof object === "undefined";
|
||
}
|
||
|
||
extend(Object, {
|
||
extend: extend,
|
||
inspect: inspect,
|
||
toJSON: toJSON,
|
||
toQueryString: toQueryString,
|
||
toHTML: toHTML,
|
||
keys: keys,
|
||
values: values,
|
||
clone: clone,
|
||
isElement: isElement,
|
||
isArray: isArray,
|
||
isHash: isHash,
|
||
isFunction: isFunction,
|
||
isString: isString,
|
||
isNumber: isNumber,
|
||
isUndefined: isUndefined
|
||
});
|
||
})();
|
||
Object.extend(Function.prototype, (function() {
|
||
var slice = Array.prototype.slice;
|
||
|
||
function update(array, args) {
|
||
var arrayLength = array.length, length = args.length;
|
||
while (length--) array[arrayLength + length] = args[length];
|
||
return array;
|
||
}
|
||
|
||
function merge(array, args) {
|
||
array = slice.call(array, 0);
|
||
return update(array, args);
|
||
}
|
||
});
|
||
|
||
Object.extend(Function.prototype, {
|
||
argumentNames: function() {
|
||
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
|
||
function argumentNames() {
|
||
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
|
||
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
|
||
.replace(/\s+/g, '').split(',');
|
||
return names.length == 1 && !names[0] ? [] : names;
|
||
},
|
||
}
|
||
|
||
bind: function() {
|
||
function bind(context) {
|
||
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
|
||
var __method = this, args = $A(arguments), object = args.shift();
|
||
var __method = this, args = slice.call(arguments, 1);
|
||
return function() {
|
||
return __method.apply(object, args.concat($A(arguments)));
|
||
var a = merge(args, arguments);
|
||
return __method.apply(context, a);
|
||
}
|
||
},
|
||
}
|
||
|
||
bindAsEventListener: function() {
|
||
var __method = this, args = $A(arguments), object = args.shift();
|
||
function bindAsEventListener(context) {
|
||
var __method = this, args = slice.call(arguments, 1);
|
||
return function(event) {
|
||
return __method.apply(object, [event || window.event].concat(args));
|
||
var a = update([event || window.event], args);
|
||
return __method.apply(context, a);
|
||
}
|
||
},
|
||
}
|
||
|
||
curry: function() {
|
||
function curry() {
|
||
if (!arguments.length) return this;
|
||
var __method = this, args = $A(arguments);
|
||
var __method = this, args = slice.call(arguments, 0);
|
||
return function() {
|
||
return __method.apply(this, args.concat($A(arguments)));
|
||
var a = merge(args, arguments);
|
||
return __method.apply(this, a);
|
||
}
|
||
},
|
||
}
|
||
|
||
delay: function() {
|
||
var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
|
||
function delay(timeout) {
|
||
var __method = this, args = slice.call(arguments, 1);
|
||
timeout = timeout * 1000
|
||
return window.setTimeout(function() {
|
||
return __method.apply(__method, args);
|
||
}, timeout);
|
||
},
|
||
}
|
||
|
||
defer: function() {
|
||
var args = [0.01].concat($A(arguments));
|
||
function defer() {
|
||
var args = update([0.01], arguments);
|
||
return this.delay.apply(this, args);
|
||
},
|
||
}
|
||
|
||
wrap: function(wrapper) {
|
||
function wrap(wrapper) {
|
||
var __method = this;
|
||
return function() {
|
||
return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
|
||
var a = update([__method.bind(this)], arguments);
|
||
return wrapper.apply(this, a);
|
||
}
|
||
},
|
||
}
|
||
|
||
methodize: function() {
|
||
function methodize() {
|
||
if (this._methodized) return this._methodized;
|
||
var __method = this;
|
||
return this._methodized = function() {
|
||
return __method.apply(null, [this].concat($A(arguments)));
|
||
var a = update([this], arguments);
|
||
return __method.apply(null, a);
|
||
};
|
||
}
|
||
});
|
||
|
||
return {
|
||
argumentNames: argumentNames,
|
||
bind: bind,
|
||
bindAsEventListener: bindAsEventListener,
|
||
curry: curry,
|
||
delay: delay,
|
||
defer: defer,
|
||
wrap: wrap,
|
||
methodize: methodize
|
||
}
|
||
})());
|
||
|
||
|
||
Date.prototype.toJSON = function() {
|
||
return '"' + this.getUTCFullYear() + '-' +
|
||
... | ... | |
this.getUTCSeconds().toPaddedString(2) + 'Z"';
|
||
};
|
||
|
||
var Try = {
|
||
these: function() {
|
||
var returnValue;
|
||
|
||
for (var i = 0, length = arguments.length; i < length; i++) {
|
||
var lambda = arguments[i];
|
||
try {
|
||
returnValue = lambda();
|
||
break;
|
||
} catch (e) { }
|
||
}
|
||
|
||
return returnValue;
|
||
}
|
||
};
|
||
|
||
RegExp.prototype.match = RegExp.prototype.test;
|
||
|
||
RegExp.escape = function(str) {
|
||
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
|
||
};
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
var PeriodicalExecuter = Class.create({
|
||
initialize: function(callback, frequency) {
|
||
this.callback = callback;
|
||
... | ... | |
try {
|
||
this.currentlyExecuting = true;
|
||
this.execute();
|
||
} finally {
|
||
this.currentlyExecuting = false;
|
||
} catch(e) {
|
||
this.currentlyExecuting = false;
|
||
throw e;
|
||
}
|
||
}
|
||
}
|
||
... | ... | |
}
|
||
});
|
||
|
||
Object.extend(String.prototype, {
|
||
gsub: function(pattern, replacement) {
|
||
Object.extend(String.prototype, (function() {
|
||
|
||
function prepareReplacement(replacement) {
|
||
if (Object.isFunction(replacement)) return replacement;
|
||
var template = new Template(replacement);
|
||
return function(match) { return template.evaluate(match) };
|
||
}
|
||
|
||
function gsub(pattern, replacement) {
|
||
var result = '', source = this, match;
|
||
replacement = arguments.callee.prepareReplacement(replacement);
|
||
replacement = prepareReplacement(replacement);
|
||
|
||
if (Object.isString(pattern))
|
||
pattern = RegExp.escape(pattern);
|
||
|
||
if (!(pattern.length || pattern.source)) {
|
||
replacement = replacement('');
|
||
return replacement + source.split('').join(replacement) + replacement;
|
||
}
|
||
|
||
while (source.length > 0) {
|
||
if (match = source.match(pattern)) {
|
||
... | ... | |
}
|
||
}
|
||
return result;
|
||
},
|
||
}
|
||
|
||
sub: function(pattern, replacement, count) {
|
||
replacement = this.gsub.prepareReplacement(replacement);
|
||
function sub(pattern, replacement, count) {
|
||
replacement = prepareReplacement(replacement);
|
||
count = Object.isUndefined(count) ? 1 : count;
|
||
|
||
return this.gsub(pattern, function(match) {
|
||
if (--count < 0) return match[0];
|
||
return replacement(match);
|
||
});
|
||
},
|
||
}
|
||
|
||
scan: function(pattern, iterator) {
|
||
function scan(pattern, iterator) {
|
||
this.gsub(pattern, iterator);
|
||
return String(this);
|
||
},
|
||
}
|
||
|
||
truncate: function(length, truncation) {
|
||
function truncate(length, truncation) {
|
||
length = length || 30;
|
||
truncation = Object.isUndefined(truncation) ? '...' : truncation;
|
||
return this.length > length ?
|
||
this.slice(0, length - truncation.length) + truncation : String(this);
|
||
},
|
||
}
|
||
|
||
strip: function() {
|
||
function strip() {
|
||
return this.replace(/^\s+/, '').replace(/\s+$/, '');
|
||
},
|
||
}
|
||
|
||
stripTags: function() {
|
||
return this.replace(/<\/?[^>]+>/gi, '');
|
||
},
|
||
function stripTags() {
|
||
return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
|
||
}
|
||
|
||
stripScripts: function() {
|
||
function stripScripts() {
|
||
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
|
||
},
|
||
}
|
||
|
||
extractScripts: function() {
|
||
function extractScripts() {
|
||
var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
|
||
var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
|
||
return (this.match(matchAll) || []).map(function(scriptTag) {
|
||
return (scriptTag.match(matchOne) || ['', ''])[1];
|
||
});
|
||
},
|
||
}
|
||
|
||
evalScripts: function() {
|
||
function evalScripts() {
|
||
return this.extractScripts().map(function(script) { return eval(script) });
|
||
},
|
||
}
|
||
|
||
escapeHTML: function() {
|
||
var self = arguments.callee;
|
||
self.text.data = this;
|
||
return self.div.innerHTML;
|
||
},
|
||
function escapeHTML() {
|
||
return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
||
}
|
||
|
||
function unescapeHTML() {
|
||
return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&');
|
||
}
|
||
|
||
unescapeHTML: function() {
|
||
var div = new Element('div');
|
||
div.innerHTML = this.stripTags();
|
||
return div.childNodes[0] ? (div.childNodes.length > 1 ?
|
||
$A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
|
||
div.childNodes[0].nodeValue) : '';
|
||
},
|
||
|
||
toQueryParams: function(separator) {
|
||
function toQueryParams(separator) {
|
||
var match = this.strip().match(/([^?#]*)(#.*)?$/);
|
||
if (!match) return { };
|
||
|
||
... | ... | |
}
|
||
return hash;
|
||
});
|
||
},
|
||
}
|
||
|
||
toArray: function() {
|
||
function toArray() {
|
||
return this.split('');
|
||
},
|
||
}
|
||
|
||
succ: function() {
|
||
function succ() {
|
||
return this.slice(0, this.length - 1) +
|
||
String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
|
||
},
|
||
}
|
||
|
||
times: function(count) {
|
||
function times(count) {
|
||
return count < 1 ? '' : new Array(count + 1).join(this);
|
||
},
|
||
}
|
||
|
||
camelize: function() {
|
||
function camelize() {
|
||
var parts = this.split('-'), len = parts.length;
|
||
if (len == 1) return parts[0];
|
||
|
||
... | ... | |
camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
|
||
|
||
return camelized;
|
||
},
|
||
}
|
||
|
||
capitalize: function() {
|
||
function capitalize() {
|
||
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
|
||
},
|
||
}
|
||
|
||
underscore: function() {
|
||
return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
|
||
},
|
||
function underscore() {
|
||
return this.replace(/::/g, '/')
|
||
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
|
||
.replace(/([a-z\d])([A-Z])/g, '$1_$2')
|
||
.replace(/-/g, '_')
|
||
.toLowerCase();
|
||
}
|
||
|
||
dasherize: function() {
|
||
return this.gsub(/_/,'-');
|
||
},
|
||
function dasherize() {
|
||
return this.replace(/_/g, '-');
|
||
}
|
||
|
||
inspect: function(useDoubleQuotes) {
|
||
var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
|
||
var character = String.specialChar[match[0]];
|
||
return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
|
||
function inspect(useDoubleQuotes) {
|
||
var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
|
||
if (character in String.specialChar) {
|
||
return String.specialChar[character];
|
||
}
|
||
return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
|
||
});
|
||
if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
|
||
return "'" + escapedString.replace(/'/g, '\\\'') + "'";
|
||
},
|
||
}
|
||
|
||
toJSON: function() {
|
||
function toJSON() {
|
||
return this.inspect(true);
|
||
},
|
||
}
|
||
|
||
unfilterJSON: function(filter) {
|
||
return this.sub(filter || Prototype.JSONFilter, '#{1}');
|
||
},
|
||
function unfilterJSON(filter) {
|
||
return this.replace(filter || Prototype.JSONFilter, '$1');
|
||
}
|
||
|
||
isJSON: function() {
|
||
function isJSON() {
|
||
var str = this;
|
||
if (str.blank()) return false;
|
||
str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
|
||
return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
|
||
},
|
||
}
|
||
|
||
evalJSON: function(sanitize) {
|
||
function evalJSON(sanitize) {
|
||
var json = this.unfilterJSON();
|
||
try {
|
||
if (!sanitize || json.isJSON()) return eval('(' + json + ')');
|
||
} catch (e) { }
|
||
throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
|
||
},
|
||
}
|
||
|
||
include: function(pattern) {
|
||
function include(pattern) {
|
||
return this.indexOf(pattern) > -1;
|
||
},
|
||
}
|
||
|
||
startsWith: function(pattern) {
|
||
function startsWith(pattern) {
|
||
return this.indexOf(pattern) === 0;
|
||
},
|
||
}
|
||
|
||
endsWith: function(pattern) {
|
||
function endsWith(pattern) {
|
||
var d = this.length - pattern.length;
|
||
return d >= 0 && this.lastIndexOf(pattern) === d;
|
||
},
|
||
}
|
||
|
||
empty: function() {
|
||
function empty() {
|
||
return this == '';
|
||
},
|
||
}
|
||
|
||
blank: function() {
|
||
function blank() {
|
||
return /^\s*$/.test(this);
|
||
},
|
||
|
||
interpolate: function(object, pattern) {
|
||
return new Template(this, pattern).evaluate(object);
|
||
}
|
||
});
|
||
|
||
if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
|
||
escapeHTML: function() {
|
||
return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
||
},
|
||
unescapeHTML: function() {
|
||
return this.stripTags().replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
||
function interpolate(object, pattern) {
|
||
return new Template(this, pattern).evaluate(object);
|
||
}
|
||
});
|
||
|
||
String.prototype.gsub.prepareReplacement = function(replacement) {
|
||
if (Object.isFunction(replacement)) return replacement;
|
||
var template = new Template(replacement);
|
||
return function(match) { return template.evaluate(match) };
|
||
};
|
||
|
||
String.prototype.parseQuery = String.prototype.toQueryParams;
|
||
|
||
Object.extend(String.prototype.escapeHTML, {
|
||
div: document.createElement('div'),
|
||
text: document.createTextNode('')
|
||
});
|
||
|
||
String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);
|
||
return {
|
||
gsub: gsub,
|
||
sub: sub,
|
||
scan: scan,
|
||
truncate: truncate,
|
||
strip: String.prototype.trim ? String.prototype.trim : strip,
|
||
stripTags: stripTags,
|
||
stripScripts: stripScripts,
|
||
extractScripts: extractScripts,
|
||
evalScripts: evalScripts,
|
||
escapeHTML: escapeHTML,
|
||
unescapeHTML: unescapeHTML,
|
||
toQueryParams: toQueryParams,
|
||
parseQuery: toQueryParams,
|
||
toArray: toArray,
|
||
succ: succ,
|
||
times: times,
|
||
camelize: camelize,
|
||
capitalize: capitalize,
|
||
underscore: underscore,
|
||
dasherize: dasherize,
|
||
inspect: inspect,
|
||
toJSON: toJSON,
|
||
unfilterJSON: unfilterJSON,
|
||
isJSON: isJSON,
|
||
evalJSON: evalJSON,
|
||
include: include,
|
||
startsWith: startsWith,
|
||
endsWith: endsWith,
|
||
empty: empty,
|
||
blank: blank,
|
||
interpolate: interpolate
|
||
};
|
||
})());
|
||
|
||
var Template = Class.create({
|
||
initialize: function(template, pattern) {
|
||
... | ... | |
},
|
||
|
||
evaluate: function(object) {
|
||
if (Object.isFunction(object.toTemplateReplacements))
|
||
if (object && Object.isFunction(object.toTemplateReplacements))
|
||
object = object.toTemplateReplacements();
|
||
|
||
return this.template.gsub(this.pattern, function(match) {
|
||
if (object == null) return '';
|
||
if (object == null) return (match[1] + '');
|
||
|
||
var before = match[1] || '';
|
||
if (before == '\\') return match[2];
|
||
... | ... | |
if (match == null) return before;
|
||
|
||
while (match != null) {
|
||
var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
|
||
var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
|
||
ctx = ctx[comp];
|
||
if (null == ctx || '' == match[3]) break;
|
||
expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
|
||
... | ... | |
|
||
var $break = { };
|
||
|
||
var Enumerable = {
|
||
each: function(iterator, context) {
|
||
var Enumerable = (function() {
|
||
function each(iterator, context) {
|
||
var index = 0;
|
||
try {
|
||
this._each(function(value) {
|
||
... | ... | |
if (e != $break) throw e;
|
||
}
|
||
return this;
|
||
},
|
||
}
|
||
|
||
eachSlice: function(number, iterator, context) {
|
||
function eachSlice(number, iterator, context) {
|
||
var index = -number, slices = [], array = this.toArray();
|
||
if (number < 1) return array;
|
||
while ((index += number) < array.length)
|
||
slices.push(array.slice(index, index+number));
|
||
return slices.collect(iterator, context);
|
||
},
|
||
}
|
||
|
||
all: function(iterator, context) {
|
||
function all(iterator, context) {
|
||
iterator = iterator || Prototype.K;
|
||
var result = true;
|
||
this.each(function(value, index) {
|
||
... | ... | |
if (!result) throw $break;
|
||
});
|
||
return result;
|
||
},
|
||
}
|
||
|
||
any: function(iterator, context) {
|
||
function any(iterator, context) {
|
||
iterator = iterator || Prototype.K;
|
||
var result = false;
|
||
this.each(function(value, index) {
|
||
... | ... | |
throw $break;
|
||
});
|
||
return result;
|
||
},
|
||
}
|
||
|
||
collect: function(iterator, context) {
|
||
function collect(iterator, context) {
|
||
iterator = iterator || Prototype.K;
|
||
var results = [];
|
||
this.each(function(value, index) {
|
||
results.push(iterator.call(context, value, index));
|
||
});
|
||
return results;
|
||
},
|
||
}
|
||
|
||
detect: function(iterator, context) {
|
||
function detect(iterator, context) {
|
||
var result;
|
||
this.each(function(value, index) {
|
||
if (iterator.call(context, value, index)) {
|
||
... | ... | |
}
|
||
});
|
||
return result;
|
||
},
|
||
}
|
||
|
||
findAll: function(iterator, context) {
|
||
function findAll(iterator, context) {
|
||
var results = [];
|
||
this.each(function(value, index) {
|
||
if (iterator.call(context, value, index))
|
||
results.push(value);
|
||
});
|
||
return results;
|
||
},
|
||
}
|
||
|
||
grep: function(filter, iterator, context) {
|
||
function grep(filter, iterator, context) {
|
||
iterator = iterator || Prototype.K;
|
||
var results = [];
|
||
|
||
if (Object.isString(filter))
|
||
filter = new RegExp(filter);
|
||
filter = new RegExp(RegExp.escape(filter));
|
||
|
||
this.each(function(value, index) {
|
||
if (filter.match(value))
|
||
results.push(iterator.call(context, value, index));
|
||
});
|
||
return results;
|
||
},
|
||
}
|
||
|
||
include: function(object) {
|
||
function include(object) {
|
||
if (Object.isFunction(this.indexOf))
|
||
if (this.indexOf(object) != -1) return true;
|
||
|
||
... | ... | |
}
|
||
});
|
||
return found;
|
||
},
|
||
}
|
||
|
||
inGroupsOf: function(number, fillWith) {
|
||
function inGroupsOf(number, fillWith) {
|
||
fillWith = Object.isUndefined(fillWith) ? null : fillWith;
|
||
return this.eachSlice(number, function(slice) {
|
||
while(slice.length < number) slice.push(fillWith);
|
||
return slice;
|
||
});
|
||
},
|
||
}
|
||
|
||
inject: function(memo, iterator, context) {
|
||
function inject(memo, iterator, context) {
|
||
this.each(function(value, index) {
|
||
memo = iterator.call(context, memo, value, index);
|
||
});
|
||
return memo;
|
||
},
|
||
}
|
||
|
||
invoke: function(method) {
|
||
function invoke(method) {
|
||
var args = $A(arguments).slice(1);
|
||
return this.map(function(value) {
|
||
return value[method].apply(value, args);
|
||
});
|
||
},
|
||
}
|
||
|
||
max: function(iterator, context) {
|
||
function max(iterator, context) {
|
||
iterator = iterator || Prototype.K;
|
||
var result;
|
||
this.each(function(value, index) {
|
||
... | ... | |
result = value;
|
||
});
|
||
return result;
|
||
},
|
||
}
|
||
|
||
min: function(iterator, context) {
|
||
function min(iterator, context) {
|
||
iterator = iterator || Prototype.K;
|
||
var result;
|
||
this.each(function(value, index) {
|
||
... | ... | |
result = value;
|
||
});
|
||
return result;
|
||
},
|
||
}
|
||
|
||
partition: function(iterator, context) {
|
||
function partition(iterator, context) {
|
||
iterator = iterator || Prototype.K;
|
||
var trues = [], falses = [];
|
||
this.each(function(value, index) {
|
||
... | ... | |
trues : falses).push(value);
|
||
});
|
||
return [trues, falses];
|
||
},
|
||
}
|
||
|
||
pluck: function(property) {
|
||
function pluck(property) {
|
||
var results = [];
|
||
this.each(function(value) {
|
||
results.push(value[property]);
|
||
});
|
||
return results;
|
||
},
|
||
}
|
||
|
||
reject: function(iterator, context) {
|
||
function reject(iterator, context) {
|
||
var results = [];
|
||
this.each(function(value, index) {
|
||
if (!iterator.call(context, value, index))
|
||
results.push(value);
|
||
});
|
||
return results;
|
||
},
|
||
}
|
||
|
||
sortBy: function(iterator, context) {
|
||
function sortBy(iterator, context) {
|
||
return this.map(function(value, index) {
|
||
return {
|
||
value: value,
|
||
... | ... | |
var a = left.criteria, b = right.criteria;
|
||
return a < b ? -1 : a > b ? 1 : 0;
|
||
}).pluck('value');
|
||
},
|
||
}
|
||
|
||
toArray: function() {
|
||
function toArray() {
|
||
return this.map();
|
||
},
|
||
}
|
||
|
||
zip: function() {
|
||
function zip() {
|
||
var iterator = Prototype.K, args = $A(arguments);
|
||
if (Object.isFunction(args.last()))
|
||
iterator = args.pop();
|
||
... | ... | |
return this.map(function(value, index) {
|
||
return iterator(collections.pluck(index));
|
||
});
|
||
},
|
||
}
|
||
|
||
size: function() {
|
||
function size() {
|
||
return this.toArray().length;
|
||
},
|
||
}
|
||
|
||
inspect: function() {
|
||
function inspect() {
|
||
return '#<Enumerable:' + this.toArray().inspect() + '>';
|
||
}
|
||
};
|
||
|
||
Object.extend(Enumerable, {
|
||
map: Enumerable.collect,
|
||
find: Enumerable.detect,
|
||
select: Enumerable.findAll,
|
||
filter: Enumerable.findAll,
|
||
member: Enumerable.include,
|
||
entries: Enumerable.toArray,
|
||
every: Enumerable.all,
|
||
some: Enumerable.any
|
||
});
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
return {
|
||
each: each,
|
||
eachSlice: eachSlice,
|
||
all: all,
|
||
every: all,
|
||
any: any,
|
||
some: any,
|
||
collect: collect,
|
||
map: collect,
|
||
detect: detect,
|
||
findAll: findAll,
|
||
select: findAll,
|
||
filter: findAll,
|
||
grep: grep,
|
||
include: include,
|
||
member: include,
|
||
inGroupsOf: inGroupsOf,
|
||
inject: inject,
|
||
invoke: invoke,
|
||
max: max,
|
||
min: min,
|
||
partition: partition,
|
||
pluck: pluck,
|
||
reject: reject,
|
||
sortBy: sortBy,
|
||
toArray: toArray,
|
||
entries: toArray,
|
||
zip: zip,
|
||
size: size,
|
||
inspect: inspect,
|
||
find: detect
|
||
};
|
||
})();
|
||
function $A(iterable) {
|
||
if (!iterable) return [];
|
||
if (iterable.toArray) return iterable.toArray();
|
||
if ('toArray' in Object(iterable)) return iterable.toArray();
|
||
var length = iterable.length || 0, results = new Array(length);
|
||
while (length--) results[length] = iterable[length];
|
||
return results;
|
||
}
|
||
|
||
if (Prototype.Browser.WebKit) {
|
||
$A = function(iterable) {
|
||
if (!iterable) return [];
|
||
// In Safari, only use the `toArray` method if it's not a NodeList.
|
||
// A NodeList is a function, has an function `item` property, and a numeric
|
||
// `length` property. Adapted from Google Doctype.
|
||
if (!(typeof iterable === 'function' && typeof iterable.length ===
|
||
'number' && typeof iterable.item === 'function') && iterable.toArray)
|
||
return iterable.toArray();
|
||
var length = iterable.length || 0, results = new Array(length);
|
||
while (length--) results[length] = iterable[length];
|
||
return results;
|
||
};
|
||
function $w(string) {
|
||
if (!Object.isString(string)) return [];
|
||
string = string.strip();
|
||
return string ? string.split(/\s+/) : [];
|
||
}
|
||
|
||
Array.from = $A;
|
||
|
||
Object.extend(Array.prototype, Enumerable);
|
||
|
||
if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
|
||
(function() {
|
||
var arrayProto = Array.prototype,
|
||
slice = arrayProto.slice,
|
||
_each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
|
||
|
||
Object.extend(Array.prototype, {
|
||
_each: function(iterator) {
|
||
function each(iterator) {
|
||
for (var i = 0, length = this.length; i < length; i++)
|
||
iterator(this[i]);
|
||
},
|
||
}
|
||
if (!_each) _each = each;
|
||
|
||
clear: function() {
|
||
function clear() {
|
||
this.length = 0;
|
||
return this;
|
||
},
|
||
}
|
||
|
||
first: function() {
|
||
function first() {
|
||
return this[0];
|
||
},
|
||
}
|
||
|
||
last: function() {
|
||
function last() {
|
||
return this[this.length - 1];
|
||
},
|
||
}
|
||
|
||
compact: function() {
|
||
function compact() {
|
||
return this.select(function(value) {
|
||
return value != null;
|
||
});
|
||
},
|
||
}
|
||
|
||
flatten: function() {
|
||
function flatten() {
|
||
return this.inject([], function(array, value) {
|
||
return array.concat(Object.isArray(value) ?
|
||
value.flatten() : [value]);
|
||
if (Object.isArray(value))
|
||
return array.concat(value.flatten());
|
||
array.push(value);
|
||
return array;
|
||
});
|
||
},
|
||
}
|
||
|
||
without: function() {
|
||
var values = $A(arguments);
|
||
function without() {
|
||
var values = slice.call(arguments, 0);
|
||
return this.select(function(value) {
|
||
return !values.include(value);
|
||
});
|
||
},
|
||
}
|
||
|
||
reverse: function(inline) {
|
||
function reverse(inline) {
|
||
return (inline !== false ? this : this.toArray())._reverse();
|
||
},
|
||
|
||
reduce: function() {
|
||
return this.length > 1 ? this : this[0];
|
||
},
|
||
}
|
||
|
||
uniq: function(sorted) {
|
||
function uniq(sorted) {
|
||
return this.inject([], function(array, value, index) {
|
||
if (0 == index || (sorted ? array.last() != value : !array.include(value)))
|
||
array.push(value);
|
||
return array;
|
||
});
|
||
},
|
||
}
|
||
|
||
intersect: function(array) {
|
||
function intersect(array) {
|
||
return this.uniq().findAll(function(item) {
|
||
return array.detect(function(value) { return item === value });
|
||
});
|
||
},
|
||
}
|
||
|
||
clone: function() {
|
||
return [].concat(this);
|
||
},
|
||
|
||
size: function() {
|
||
function clone() {
|
||
return slice.call(this, 0);
|
||
}
|
||
|
||
function size() {
|
||
return this.length;
|
||
},
|
||
}
|
||
|
||
inspect: function() {
|
||
function inspect() {
|
||
return '[' + this.map(Object.inspect).join(', ') + ']';
|
||
},
|
||
}
|
||
|
||
toJSON: function() {
|
||
function toJSON() {
|
||
var results = [];
|
||
this.each(function(object) {
|
||
var value = Object.toJSON(object);
|
||
... | ... | |
});
|
||
return '[' + results.join(', ') + ']';
|
||
}
|
||
});
|
||
|
||
// use native browser JS 1.6 implementation if available
|
||
if (Object.isFunction(Array.prototype.forEach))
|
||
Array.prototype._each = Array.prototype.forEach;
|
||
|
||
if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
|
||
i || (i = 0);
|
||
var length = this.length;
|
||
if (i < 0) i = length + i;
|
||
for (; i < length; i++)
|
||
if (this[i] === item) return i;
|
||
return -1;
|
||
};
|
||
|
||
if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
|
||
i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
|
||
var n = this.slice(0, i).reverse().indexOf(item);
|
||
return (n < 0) ? n : i - n - 1;
|
||
};
|
||
|
||
Array.prototype.toArray = Array.prototype.clone;
|
||
function indexOf(item, i) {
|
||
i || (i = 0);
|
||
var length = this.length;
|
||
if (i < 0) i = length + i;
|
||
for (; i < length; i++)
|
||
if (this[i] === item) return i;
|
||
return -1;
|
||
}
|
||
|
||
function $w(string) {
|
||
if (!Object.isString(string)) return [];
|
||
string = string.strip();
|
||
return string ? string.split(/\s+/) : [];
|
||
}
|
||
function lastIndexOf(item, i) {
|
||
i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
|
||
var n = this.slice(0, i).reverse().indexOf(item);
|
||
return (n < 0) ? n : i - n - 1;
|
||
}
|
||
|
||
if (Prototype.Browser.Opera){
|
||
Array.prototype.concat = function() {
|
||
var array = [];
|
||
for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
|
||
function concat() {
|
||
var array = slice.call(this, 0), item;
|
||
for (var i = 0, length = arguments.length; i < length; i++) {
|
||
if (Object.isArray(arguments[i])) {
|
||
for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
|
||
array.push(arguments[i][j]);
|
||
item = arguments[i];
|
||
if (Object.isArray(item) && !('callee' in item)) {
|
||
for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
|
||
array.push(item[j]);
|
||
} else {
|
||
array.push(arguments[i]);
|
||
array.push(item);
|
||
}
|
||
}
|
||
return array;
|
||
};
|
||
}
|
||
Object.extend(Number.prototype, {
|
||
toColorPart: function() {
|
||
return this.toPaddedString(2, 16);
|
||
},
|
||
|
||
succ: function() {
|
||
return this + 1;
|
||
},
|
||
}
|
||
|
||
times: function(iterator, context) {
|
||
$R(0, this, true).each(iterator, context);
|
||
return this;
|
||
},
|
||
Object.extend(arrayProto, Enumerable);
|
||
|
||
if (!arrayProto._reverse)
|
||
arrayProto._reverse = arrayProto.reverse;
|
||
|
||
Object.extend(arrayProto, {
|
||
_each: _each,
|
||
clear: clear,
|
||
first: first,
|
||
last: last,
|
||
compact: compact,
|
||
flatten: flatten,
|
||
without: without,
|
||
reverse: reverse,
|
||
uniq: uniq,
|
||
intersect: intersect,
|
||
clone: clone,
|
||
toArray: clone,
|
||
size: size,
|
||
inspect: inspect,
|
||
toJSON: toJSON
|
||
});
|
||
|
||
toPaddedString: function(length, radix) {
|
||
var string = this.toString(radix || 10);
|
||
return '0'.times(length - string.length) + string;
|
||
},
|
||
var CONCAT_ARGUMENTS_BUGGY = (function() {
|
||
return [].concat(arguments)[0][0] !== 1;
|
||
})(1,2)
|
||
|
||
toJSON: function() {
|
||
return isFinite(this) ? this.toString() : 'null';
|
||
}
|
||
});
|
||
if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
|
||
|
||
$w('abs round ceil floor').each(function(method){
|
||
Number.prototype[method] = Math[method].methodize();
|
||
});
|
||
if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
|
||
if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
|
||
})();
|
||
function $H(object) {
|
||
return new Hash(object);
|
||
};
|
||
|
||
var Hash = Class.create(Enumerable, (function() {
|
||
function initialize(object) {
|
||
this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
|
||
}
|
||
|
||
function _each(iterator) {
|
||
for (var key in this._object) {
|
||
var value = this._object[key], pair = [key, value];
|
||
pair.key = key;
|
||
pair.value = value;
|
||
iterator(pair);
|
||
}
|
||
}
|
||
|
||
function set(key, value) {
|
||
return this._object[key] = value;
|
||
}
|
||
|
||
function get(key) {
|
||
if (this._object[key] !== Object.prototype[key])
|
||
return this._object[key];
|
||
}
|
||
|
||
function unset(key) {
|
||
var value = this._object[key];
|
||
delete this._object[key];
|
||
return value;
|
||
}
|
||
|
||
function toObject() {
|
||
return Object.clone(this._object);
|
||
}
|
||
|
||
function keys() {
|
||
return this.pluck('key');
|
||
}
|
||
|
||
function values() {
|
||
return this.pluck('value');
|
||
}
|
||
|
||
function index(value) {
|
||
var match = this.detect(function(pair) {
|
||
return pair.value === value;
|
||
});
|
||
return match && match.key;
|
||
}
|
||
|
||
function merge(object) {
|
||
return this.clone().update(object);
|
||
}
|
||
|
||
function update(object) {
|
||
return new Hash(object).inject(this, function(result, pair) {
|
||
result.set(pair.key, pair.value);
|
||
return result;
|
||
});
|
||
}
|
||
|
||
function toQueryPair(key, value) {
|
||
if (Object.isUndefined(value)) return key;
|
||
return key + '=' + encodeURIComponent(String.interpret(value));
|
||
}
|
||
|
||
return {
|
||
initialize: function(object) {
|
||
this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
|
||
},
|
||
|
||
_each: function(iterator) {
|
||
for (var key in this._object) {
|
||
var value = this._object[key], pair = [key, value];
|
||
pair.key = key;
|
||
pair.value = value;
|
||
iterator(pair);
|
||
}
|
||
},
|
Also available in: Unified diff
[evol] migration to libgettext-ruby 2.1.0 and split rails 2.3.5, step #1