You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/06/08 23:55:43 UTC
svn commit: r664564 [4/5] - in
/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1:
builder.js controls.js dragdrop.js effects.js prototype.js scriptaculous.js
slider.js sound.js unittest.js
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/prototype.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/prototype.js?rev=664564&r1=664563&r2=664564&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/prototype.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/scriptaculous_1_8_1/prototype.js Sun Jun 8 14:55:43 2008
@@ -7,4234 +7,3505 @@
*--------------------------------------------------------------------------*/
var Prototype = {
- Version: '1.6.0.1',
+ Version: '1.6.0.1',
- Browser: {
- IE: !!(window.attachEvent && !window.opera),
- Opera: !!window.opera,
- WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
- Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
- MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
- },
-
- BrowserFeatures: {
- XPath: !!document.evaluate,
- ElementExtensions: !!window.HTMLElement,
- SpecificElementExtensions:
- document.createElement('div').__proto__ &&
- document.createElement('div').__proto__ !==
- document.createElement('form').__proto__
- },
-
- ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
- JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
-
- emptyFunction: function()
- {
- },
- K: function(x)
- {
- return x
- }
+ Browser: {
+ IE: !!(window.attachEvent && !window.opera),
+ Opera: !!window.opera,
+ WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
+ Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
+ MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
+ },
+
+ BrowserFeatures: {
+ XPath: !!document.evaluate,
+ ElementExtensions: !!window.HTMLElement,
+ SpecificElementExtensions:
+ document.createElement('div').__proto__ &&
+ document.createElement('div').__proto__ !==
+ document.createElement('form').__proto__
+ },
+
+ ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
+ JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
+
+ emptyFunction: function() { },
+ K: function(x) { return x }
};
if (Prototype.Browser.MobileSafari)
- Prototype.BrowserFeatures.SpecificElementExtensions = false;
+ Prototype.BrowserFeatures.SpecificElementExtensions = false;
/* Based on Alex Arnell's inheritance implementation. */
var Class = {
- create: function()
- {
- var parent = null, properties = $A(arguments);
- if (Object.isFunction(properties[0]))
- parent = properties.shift();
-
- function klass()
- {
- this.initialize.apply(this, arguments);
- }
+ create: function() {
+ var parent = null, properties = $A(arguments);
+ if (Object.isFunction(properties[0]))
+ parent = properties.shift();
- Object.extend(klass, Class.Methods);
- klass.superclass = parent;
- klass.subclasses = [];
-
- if (parent)
- {
- var subclass = function()
- {
- };
- subclass.prototype = parent.prototype;
- klass.prototype = new subclass;
- parent.subclasses.push(klass);
- }
+ function klass() {
+ this.initialize.apply(this, arguments);
+ }
- for (var i = 0; i < properties.length; i++)
- klass.addMethods(properties[i]);
+ Object.extend(klass, Class.Methods);
+ klass.superclass = parent;
+ klass.subclasses = [];
- if (!klass.prototype.initialize)
- klass.prototype.initialize = Prototype.emptyFunction;
+ if (parent) {
+ var subclass = function() { };
+ subclass.prototype = parent.prototype;
+ klass.prototype = new subclass;
+ parent.subclasses.push(klass);
+ }
- klass.prototype.constructor = klass;
+ for (var i = 0; i < properties.length; i++)
+ klass.addMethods(properties[i]);
- return klass;
- }
+ if (!klass.prototype.initialize)
+ klass.prototype.initialize = Prototype.emptyFunction;
+
+ klass.prototype.constructor = klass;
+
+ return klass;
+ }
};
Class.Methods = {
- addMethods: function(source)
- {
- var ancestor = this.superclass && this.superclass.prototype;
- var properties = Object.keys(source);
-
- if (!Object.keys({ toString: true }).length)
- properties.push("toString", "valueOf");
-
- for (var i = 0, length = properties.length; i < length; i++)
- {
- var property = properties[i], value = source[property];
- if (ancestor && Object.isFunction(value) &&
- value.argumentNames().first() == "$super")
- {
- var method = value, value = Object.extend((function(m)
- {
- return function()
- {
- return ancestor[m].apply(this, arguments)
- };
- })(property).wrap(method), {
- valueOf: function()
- {
- return method
- },
- toString: function()
- {
- return method.toString()
- }
- });
- }
- this.prototype[property] = value;
- }
-
- return this;
+ addMethods: function(source) {
+ var ancestor = this.superclass && this.superclass.prototype;
+ var properties = Object.keys(source);
+
+ if (!Object.keys({ toString: true }).length)
+ properties.push("toString", "valueOf");
+
+ for (var i = 0, length = properties.length; i < length; i++) {
+ var property = properties[i], value = source[property];
+ if (ancestor && Object.isFunction(value) &&
+ value.argumentNames().first() == "$super") {
+ var method = value, value = Object.extend((function(m) {
+ return function() { return ancestor[m].apply(this, arguments) };
+ })(property).wrap(method), {
+ valueOf: function() { return method },
+ toString: function() { return method.toString() }
+ });
+ }
+ this.prototype[property] = value;
}
+
+ return this;
+ }
};
var Abstract = { };
-Object.extend = function(destination, source)
-{
- for (var property in source)
- destination[property] = source[property];
- return destination;
+Object.extend = function(destination, source) {
+ for (var property in source)
+ destination[property] = source[property];
+ return destination;
};
Object.extend(Object, {
- inspect: function(object)
- {
- try
- {
- if (Object.isUndefined(object)) return 'undefined';
- if (object === null) return 'null';
- return object.inspect ? object.inspect() : object.toString();
- }
- catch (e)
- {
- if (e instanceof RangeError) return '...';
- throw e;
- }
- },
-
- toJSON: function(object)
- {
- var type = typeof object;
- switch (type)
- {
- case 'undefined':
- case 'function':
- case 'unknown': return;
- case 'boolean': return object.toString();
- }
-
- if (object === null) return 'null';
- if (object.toJSON) return object.toJSON();
- if (Object.isElement(object)) return;
-
- var results = [];
- for (var property in object)
- {
- var value = Object.toJSON(object[property]);
- if (!Object.isUndefined(value))
- results.push(property.toJSON() + ': ' + value);
- }
-
- return '{' + results.join(', ') + '}';
- },
-
- toQueryString: function(object)
- {
- return $H(object).toQueryString();
- },
-
- toHTML: function(object)
- {
- return object && object.toHTML ? object.toHTML() : String.interpret(object);
- },
-
- keys: function(object)
- {
- var keys = [];
- for (var property in object)
- keys.push(property);
- return keys;
- },
-
- values: function(object)
- {
- var values = [];
- for (var property in object)
- values.push(object[property]);
- return values;
- },
-
- clone: function(object)
- {
- return Object.extend({ }, object);
- },
-
- isElement: function(object)
- {
- return object && object.nodeType == 1;
- },
-
- isArray: function(object)
- {
- return object && object.constructor === Array;
- },
-
- isHash: function(object)
- {
- return object instanceof Hash;
- },
-
- isFunction: function(object)
- {
- return typeof object == "function";
- },
-
- isString: function(object)
- {
- return typeof object == "string";
- },
-
- isNumber: function(object)
- {
- return typeof object == "number";
- },
-
- isUndefined: function(object)
- {
- return typeof object == "undefined";
- }
+ inspect: function(object) {
+ try {
+ if (Object.isUndefined(object)) return 'undefined';
+ if (object === null) return 'null';
+ return object.inspect ? object.inspect() : object.toString();
+ } catch (e) {
+ if (e instanceof RangeError) return '...';
+ throw e;
+ }
+ },
+
+ toJSON: function(object) {
+ var type = typeof object;
+ switch (type) {
+ case 'undefined':
+ case 'function':
+ case 'unknown': return;
+ case 'boolean': return object.toString();
+ }
+
+ if (object === null) return 'null';
+ if (object.toJSON) return object.toJSON();
+ if (Object.isElement(object)) return;
+
+ var results = [];
+ for (var property in object) {
+ var value = Object.toJSON(object[property]);
+ if (!Object.isUndefined(value))
+ results.push(property.toJSON() + ': ' + value);
+ }
+
+ return '{' + results.join(', ') + '}';
+ },
+
+ toQueryString: function(object) {
+ return $H(object).toQueryString();
+ },
+
+ toHTML: function(object) {
+ return object && object.toHTML ? object.toHTML() : String.interpret(object);
+ },
+
+ keys: function(object) {
+ var keys = [];
+ for (var property in object)
+ keys.push(property);
+ return keys;
+ },
+
+ values: function(object) {
+ var values = [];
+ for (var property in object)
+ values.push(object[property]);
+ return values;
+ },
+
+ clone: function(object) {
+ return Object.extend({ }, object);
+ },
+
+ isElement: function(object) {
+ return object && object.nodeType == 1;
+ },
+
+ isArray: function(object) {
+ return object && object.constructor === Array;
+ },
+
+ isHash: function(object) {
+ return object instanceof Hash;
+ },
+
+ isFunction: function(object) {
+ return typeof object == "function";
+ },
+
+ isString: function(object) {
+ return typeof object == "string";
+ },
+
+ isNumber: function(object) {
+ return typeof object == "number";
+ },
+
+ isUndefined: function(object) {
+ return typeof object == "undefined";
+ }
});
Object.extend(Function.prototype, {
- argumentNames: function()
- {
- var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
- return names.length == 1 && !names[0] ? [] : names;
- },
-
- bind: function()
- {
- if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
- var __method = this, args = $A(arguments), object = args.shift();
- return function()
- {
- return __method.apply(object, args.concat($A(arguments)));
- }
- },
-
- bindAsEventListener: function()
- {
- var __method = this, args = $A(arguments), object = args.shift();
- return function(event)
- {
- return __method.apply(object, [event || window.event].concat(args));
- }
- },
-
- curry: function()
- {
- if (!arguments.length) return this;
- var __method = this, args = $A(arguments);
- return function()
- {
- return __method.apply(this, args.concat($A(arguments)));
- }
- },
-
- delay: function()
- {
- var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
- return window.setTimeout(function()
- {
- return __method.apply(__method, args);
- }, timeout);
- },
-
- wrap: function(wrapper)
- {
- var __method = this;
- return function()
- {
- return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
- }
- },
-
- methodize: function()
- {
- if (this._methodized) return this._methodized;
- var __method = this;
- return this._methodized = function()
- {
- return __method.apply(null, [this].concat($A(arguments)));
- };
- }
+ argumentNames: function() {
+ var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
+ return names.length == 1 && !names[0] ? [] : names;
+ },
+
+ bind: function() {
+ if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
+ var __method = this, args = $A(arguments), object = args.shift();
+ return function() {
+ return __method.apply(object, args.concat($A(arguments)));
+ }
+ },
+
+ bindAsEventListener: function() {
+ var __method = this, args = $A(arguments), object = args.shift();
+ return function(event) {
+ return __method.apply(object, [event || window.event].concat(args));
+ }
+ },
+
+ curry: function() {
+ if (!arguments.length) return this;
+ var __method = this, args = $A(arguments);
+ return function() {
+ return __method.apply(this, args.concat($A(arguments)));
+ }
+ },
+
+ delay: function() {
+ var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+ return window.setTimeout(function() {
+ return __method.apply(__method, args);
+ }, timeout);
+ },
+
+ wrap: function(wrapper) {
+ var __method = this;
+ return function() {
+ return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+ }
+ },
+
+ methodize: function() {
+ if (this._methodized) return this._methodized;
+ var __method = this;
+ return this._methodized = function() {
+ return __method.apply(null, [this].concat($A(arguments)));
+ };
+ }
});
Function.prototype.defer = Function.prototype.delay.curry(0.01);
-Date.prototype.toJSON = function()
-{
- return '"' + this.getUTCFullYear() + '-' +
- (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
- this.getUTCDate().toPaddedString(2) + 'T' +
- this.getUTCHours().toPaddedString(2) + ':' +
- this.getUTCMinutes().toPaddedString(2) + ':' +
- this.getUTCSeconds().toPaddedString(2) + 'Z"';
+Date.prototype.toJSON = function() {
+ return '"' + this.getUTCFullYear() + '-' +
+ (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
+ this.getUTCDate().toPaddedString(2) + 'T' +
+ this.getUTCHours().toPaddedString(2) + ':' +
+ this.getUTCMinutes().toPaddedString(2) + ':' +
+ 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)
- {
- }
- }
+ these: function() {
+ var returnValue;
- return 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');
+RegExp.escape = function(str) {
+ return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};
/*--------------------------------------------------------------------------*/
var PeriodicalExecuter = Class.create({
- initialize: function(callback, frequency)
- {
- this.callback = callback;
- this.frequency = frequency;
+ initialize: function(callback, frequency) {
+ this.callback = callback;
+ this.frequency = frequency;
+ this.currentlyExecuting = false;
+
+ this.registerCallback();
+ },
+
+ registerCallback: function() {
+ this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ execute: function() {
+ this.callback(this);
+ },
+
+ stop: function() {
+ if (!this.timer) return;
+ clearInterval(this.timer);
+ this.timer = null;
+ },
+
+ onTimerEvent: function() {
+ if (!this.currentlyExecuting) {
+ try {
+ this.currentlyExecuting = true;
+ this.execute();
+ } finally {
this.currentlyExecuting = false;
+ }
+ }
+ }
+});
+Object.extend(String, {
+ interpret: function(value) {
+ return value == null ? '' : String(value);
+ },
+ specialChar: {
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '\\': '\\\\'
+ }
+});
- this.registerCallback();
- },
+Object.extend(String.prototype, {
+ gsub: function(pattern, replacement) {
+ var result = '', source = this, match;
+ replacement = arguments.callee.prepareReplacement(replacement);
+
+ while (source.length > 0) {
+ if (match = source.match(pattern)) {
+ result += source.slice(0, match.index);
+ result += String.interpret(replacement(match));
+ source = source.slice(match.index + match[0].length);
+ } else {
+ result += source, source = '';
+ }
+ }
+ return result;
+ },
- registerCallback: function()
- {
- this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
- },
+ sub: function(pattern, replacement, count) {
+ replacement = this.gsub.prepareReplacement(replacement);
+ count = Object.isUndefined(count) ? 1 : count;
+
+ return this.gsub(pattern, function(match) {
+ if (--count < 0) return match[0];
+ return replacement(match);
+ });
+ },
- execute: function()
- {
- this.callback(this);
- },
+ scan: function(pattern, iterator) {
+ this.gsub(pattern, iterator);
+ return String(this);
+ },
+
+ truncate: function(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() {
+ return this.replace(/^\s+/, '').replace(/\s+$/, '');
+ },
+
+ stripTags: function() {
+ return this.replace(/<\/?[^>]+>/gi, '');
+ },
+
+ stripScripts: function() {
+ return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+ },
+
+ extractScripts: function() {
+ 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];
+ });
+ },
- stop: function()
- {
- if (!this.timer) return;
- clearInterval(this.timer);
- this.timer = null;
- },
+ evalScripts: function() {
+ return this.extractScripts().map(function(script) { return eval(script) });
+ },
+
+ escapeHTML: function() {
+ var self = arguments.callee;
+ self.text.data = this;
+ return self.div.innerHTML;
+ },
+
+ 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) {
+ var match = this.strip().match(/([^?#]*)(#.*)?$/);
+ if (!match) return { };
+
+ return match[1].split(separator || '&').inject({ }, function(hash, pair) {
+ if ((pair = pair.split('='))[0]) {
+ var key = decodeURIComponent(pair.shift());
+ var value = pair.length > 1 ? pair.join('=') : pair[0];
+ if (value != undefined) value = decodeURIComponent(value);
+
+ if (key in hash) {
+ if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
+ hash[key].push(value);
+ }
+ else hash[key] = value;
+ }
+ return hash;
+ });
+ },
- onTimerEvent: function()
- {
- if (!this.currentlyExecuting)
- {
- try
- {
- this.currentlyExecuting = true;
- this.execute();
- }
- finally
- {
- this.currentlyExecuting = false;
- }
- }
- }
+ toArray: function() {
+ return this.split('');
+ },
+
+ succ: function() {
+ return this.slice(0, this.length - 1) +
+ String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+ },
+
+ times: function(count) {
+ return count < 1 ? '' : new Array(count + 1).join(this);
+ },
+
+ camelize: function() {
+ var parts = this.split('-'), len = parts.length;
+ if (len == 1) return parts[0];
+
+ var camelized = this.charAt(0) == '-'
+ ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
+ : parts[0];
+
+ for (var i = 1; i < len; i++)
+ camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+
+ return camelized;
+ },
+
+ capitalize: function() {
+ 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();
+ },
+
+ dasherize: function() {
+ return this.gsub(/_/,'-');
+ },
+
+ 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);
+ });
+ if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+ return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+ },
+
+ toJSON: function() {
+ return this.inspect(true);
+ },
+
+ unfilterJSON: function(filter) {
+ return this.sub(filter || Prototype.JSONFilter, '#{1}');
+ },
+
+ isJSON: function() {
+ 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) {
+ 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) {
+ return this.indexOf(pattern) > -1;
+ },
+
+ startsWith: function(pattern) {
+ return this.indexOf(pattern) === 0;
+ },
+
+ endsWith: function(pattern) {
+ var d = this.length - pattern.length;
+ return d >= 0 && this.lastIndexOf(pattern) === d;
+ },
+
+ empty: function() {
+ return this == '';
+ },
+
+ blank: function() {
+ return /^\s*$/.test(this);
+ },
+
+ interpolate: function(object, pattern) {
+ return new Template(this, pattern).evaluate(object);
+ }
});
-Object.extend(String, {
- interpret: function(value)
- {
- return value == null ? '' : String(value);
- },
- specialChar: {
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '\\': '\\\\'
- }
+
+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.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
+ }
});
-Object.extend(String.prototype, {
- gsub: function(pattern, replacement)
- {
- var result = '', source = this, match;
- replacement = arguments.callee.prepareReplacement(replacement);
-
- while (source.length > 0)
- {
- if (match = source.match(pattern))
- {
- result += source.slice(0, match.index);
- result += String.interpret(replacement(match));
- source = source.slice(match.index + match[0].length);
- }
- else
- {
- result += source,source = '';
- }
- }
- return result;
- },
+String.prototype.gsub.prepareReplacement = function(replacement) {
+ if (Object.isFunction(replacement)) return replacement;
+ var template = new Template(replacement);
+ return function(match) { return template.evaluate(match) };
+};
- sub: function(pattern, replacement, count)
- {
- replacement = this.gsub.prepareReplacement(replacement);
- count = Object.isUndefined(count) ? 1 : count;
-
- return this.gsub(pattern, function(match)
- {
- if (--count < 0) return match[0];
- return replacement(match);
- });
- },
+String.prototype.parseQuery = String.prototype.toQueryParams;
- scan: function(pattern, iterator)
- {
- this.gsub(pattern, iterator);
- return String(this);
- },
+Object.extend(String.prototype.escapeHTML, {
+ div: document.createElement('div'),
+ text: document.createTextNode('')
+});
- truncate: function(length, truncation)
- {
- length = length || 30;
- truncation = Object.isUndefined(truncation) ? '...' : truncation;
- return this.length > length ?
- this.slice(0, length - truncation.length) + truncation : String(this);
- },
+with (String.prototype.escapeHTML) div.appendChild(text);
- strip: function()
- {
- return this.replace(/^\s+/, '').replace(/\s+$/, '');
- },
+var Template = Class.create({
+ initialize: function(template, pattern) {
+ this.template = template.toString();
+ this.pattern = pattern || Template.Pattern;
+ },
+
+ evaluate: function(object) {
+ if (Object.isFunction(object.toTemplateReplacements))
+ object = object.toTemplateReplacements();
+
+ return this.template.gsub(this.pattern, function(match) {
+ if (object == null) return '';
+
+ var before = match[1] || '';
+ if (before == '\\') return match[2];
+
+ var ctx = object, expr = match[3];
+ var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
+ match = pattern.exec(expr);
+ if (match == null) return before;
+
+ while (match != null) {
+ var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
+ ctx = ctx[comp];
+ if (null == ctx || '' == match[3]) break;
+ expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
+ match = pattern.exec(expr);
+ }
+
+ return before + String.interpret(ctx);
+ }.bind(this));
+ }
+});
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
- stripTags: function()
- {
- return this.replace(/<\/?[^>]+>/gi, '');
- },
+var $break = { };
- stripScripts: function()
- {
- return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
- },
+var Enumerable = {
+ each: function(iterator, context) {
+ var index = 0;
+ iterator = iterator.bind(context);
+ try {
+ this._each(function(value) {
+ iterator(value, index++);
+ });
+ } catch (e) {
+ if (e != $break) throw e;
+ }
+ return this;
+ },
+
+ eachSlice: function(number, iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var index = -number, slices = [], array = this.toArray();
+ while ((index += number) < array.length)
+ slices.push(array.slice(index, index+number));
+ return slices.collect(iterator, context);
+ },
+
+ all: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var result = true;
+ this.each(function(value, index) {
+ result = result && !!iterator(value, index);
+ if (!result) throw $break;
+ });
+ return result;
+ },
- extractScripts: function()
- {
- 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];
- });
- },
+ any: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var result = false;
+ this.each(function(value, index) {
+ if (result = !!iterator(value, index))
+ throw $break;
+ });
+ return result;
+ },
- evalScripts: function()
- {
- return this.extractScripts().map(function(script)
- {
- return eval(script)
- });
- },
+ collect: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var results = [];
+ this.each(function(value, index) {
+ results.push(iterator(value, index));
+ });
+ return results;
+ },
- escapeHTML: function()
- {
- var self = arguments.callee;
- self.text.data = this;
- return self.div.innerHTML;
- },
-
- 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)
- {
- var match = this.strip().match(/([^?#]*)(#.*)?$/);
- if (!match) return { };
-
- return match[1].split(separator || '&').inject({ }, function(hash, pair)
- {
- if ((pair = pair.split('='))[0])
- {
- var key = decodeURIComponent(pair.shift());
- var value = pair.length > 1 ? pair.join('=') : pair[0];
- if (value != undefined) value = decodeURIComponent(value);
-
- if (key in hash)
- {
- if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
- hash[key].push(value);
- }
- else hash[key] = value;
- }
- return hash;
- });
- },
+ detect: function(iterator, context) {
+ iterator = iterator.bind(context);
+ var result;
+ this.each(function(value, index) {
+ if (iterator(value, index)) {
+ result = value;
+ throw $break;
+ }
+ });
+ return result;
+ },
- toArray: function()
- {
- return this.split('');
- },
+ findAll: function(iterator, context) {
+ iterator = iterator.bind(context);
+ var results = [];
+ this.each(function(value, index) {
+ if (iterator(value, index))
+ results.push(value);
+ });
+ return results;
+ },
- succ: function()
- {
- return this.slice(0, this.length - 1) +
- String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
- },
+ grep: function(filter, iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var results = [];
+
+ if (Object.isString(filter))
+ filter = new RegExp(filter);
+
+ this.each(function(value, index) {
+ if (filter.match(value))
+ results.push(iterator(value, index));
+ });
+ return results;
+ },
- times: function(count)
- {
- return count < 1 ? '' : new Array(count + 1).join(this);
- },
+ include: function(object) {
+ if (Object.isFunction(this.indexOf))
+ if (this.indexOf(object) != -1) return true;
+
+ var found = false;
+ this.each(function(value) {
+ if (value == object) {
+ found = true;
+ throw $break;
+ }
+ });
+ return found;
+ },
- camelize: function()
- {
- var parts = this.split('-'), len = parts.length;
- if (len == 1) return parts[0];
+ inGroupsOf: function(number, fillWith) {
+ fillWith = Object.isUndefined(fillWith) ? null : fillWith;
+ return this.eachSlice(number, function(slice) {
+ while(slice.length < number) slice.push(fillWith);
+ return slice;
+ });
+ },
- var camelized = this.charAt(0) == '-'
- ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
- : parts[0];
+ inject: function(memo, iterator, context) {
+ iterator = iterator.bind(context);
+ this.each(function(value, index) {
+ memo = iterator(memo, value, index);
+ });
+ return memo;
+ },
- for (var i = 1; i < len; i++)
- camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
+ invoke: function(method) {
+ var args = $A(arguments).slice(1);
+ return this.map(function(value) {
+ return value[method].apply(value, args);
+ });
+ },
- return camelized;
- },
+ max: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var result;
+ this.each(function(value, index) {
+ value = iterator(value, index);
+ if (result == null || value >= result)
+ result = value;
+ });
+ return result;
+ },
- capitalize: function()
- {
- return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
- },
+ min: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var result;
+ this.each(function(value, index) {
+ value = iterator(value, index);
+ if (result == null || value < result)
+ result = value;
+ });
+ return result;
+ },
- underscore: function()
- {
- return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/, '#{1}_#{2}').gsub(/([a-z\d])([A-Z])/, '#{1}_#{2}').gsub(/-/, '_').toLowerCase();
- },
+ partition: function(iterator, context) {
+ iterator = iterator ? iterator.bind(context) : Prototype.K;
+ var trues = [], falses = [];
+ this.each(function(value, index) {
+ (iterator(value, index) ?
+ trues : falses).push(value);
+ });
+ return [trues, falses];
+ },
- dasherize: function()
- {
- return this.gsub(/_/, '-');
- },
+ pluck: function(property) {
+ var results = [];
+ this.each(function(value) {
+ results.push(value[property]);
+ });
+ return results;
+ },
- 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);
- });
- if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
- return "'" + escapedString.replace(/'/g, '\\\'') + "'";
- },
+ reject: function(iterator, context) {
+ iterator = iterator.bind(context);
+ var results = [];
+ this.each(function(value, index) {
+ if (!iterator(value, index))
+ results.push(value);
+ });
+ return results;
+ },
- toJSON: function()
- {
- return this.inspect(true);
- },
+ sortBy: function(iterator, context) {
+ iterator = iterator.bind(context);
+ return this.map(function(value, index) {
+ return {value: value, criteria: iterator(value, index)};
+ }).sort(function(left, right) {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }).pluck('value');
+ },
+
+ toArray: function() {
+ return this.map();
+ },
+
+ zip: function() {
+ var iterator = Prototype.K, args = $A(arguments);
+ if (Object.isFunction(args.last()))
+ iterator = args.pop();
+
+ var collections = [this].concat(args).map($A);
+ return this.map(function(value, index) {
+ return iterator(collections.pluck(index));
+ });
+ },
- unfilterJSON: function(filter)
- {
- return this.sub(filter || Prototype.JSONFilter, '#{1}');
- },
+ size: function() {
+ return this.toArray().length;
+ },
+
+ inspect: function() {
+ return '#<Enumerable:' + this.toArray().inspect() + '>';
+ }
+};
- isJSON: function()
- {
- 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);
- },
+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
+});
+function $A(iterable) {
+ if (!iterable) return [];
+ if (iterable.toArray) return iterable.toArray();
+ var length = iterable.length || 0, results = new Array(length);
+ while (length--) results[length] = iterable[length];
+ return results;
+}
- evalJSON: function(sanitize)
- {
- var json = this.unfilterJSON();
- try
- {
- if (!sanitize || json.isJSON()) return eval('(' + json + ')');
- }
- catch (e)
- {
- }
- throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
- },
+if (Prototype.Browser.WebKit) {
+ function $A(iterable) {
+ if (!iterable) return [];
+ if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
+ iterable.toArray) return iterable.toArray();
+ var length = iterable.length || 0, results = new Array(length);
+ while (length--) results[length] = iterable[length];
+ return results;
+ }
+}
- include: function(pattern)
- {
- return this.indexOf(pattern) > -1;
- },
+Array.from = $A;
- startsWith: function(pattern)
- {
- return this.indexOf(pattern) === 0;
- },
+Object.extend(Array.prototype, Enumerable);
- endsWith: function(pattern)
- {
- var d = this.length - pattern.length;
- return d >= 0 && this.lastIndexOf(pattern) === d;
- },
+if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
- empty: function()
- {
- return this == '';
- },
+Object.extend(Array.prototype, {
+ _each: function(iterator) {
+ for (var i = 0, length = this.length; i < length; i++)
+ iterator(this[i]);
+ },
+
+ clear: function() {
+ this.length = 0;
+ return this;
+ },
+
+ first: function() {
+ return this[0];
+ },
+
+ last: function() {
+ return this[this.length - 1];
+ },
+
+ compact: function() {
+ return this.select(function(value) {
+ return value != null;
+ });
+ },
- blank: function()
- {
- return /^\s*$/.test(this);
- },
+ flatten: function() {
+ return this.inject([], function(array, value) {
+ return array.concat(Object.isArray(value) ?
+ value.flatten() : [value]);
+ });
+ },
- interpolate: function(object, pattern)
- {
- return new Template(this, pattern).evaluate(object);
- }
-});
+ without: function() {
+ var values = $A(arguments);
+ return this.select(function(value) {
+ return !values.include(value);
+ });
+ },
-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.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
- }
+ reverse: function(inline) {
+ return (inline !== false ? this : this.toArray())._reverse();
+ },
+
+ reduce: function() {
+ return this.length > 1 ? this : this[0];
+ },
+
+ uniq: function(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) {
+ return this.uniq().findAll(function(item) {
+ return array.detect(function(value) { return item === value });
+ });
+ },
+
+ clone: function() {
+ return [].concat(this);
+ },
+
+ size: function() {
+ return this.length;
+ },
+
+ inspect: function() {
+ return '[' + this.map(Object.inspect).join(', ') + ']';
+ },
+
+ toJSON: function() {
+ var results = [];
+ this.each(function(object) {
+ var value = Object.toJSON(object);
+ if (!Object.isUndefined(value)) results.push(value);
+ });
+ return '[' + results.join(', ') + ']';
+ }
});
-String.prototype.gsub.prepareReplacement = function(replacement)
-{
- if (Object.isFunction(replacement)) return replacement;
- var template = new Template(replacement);
- return function(match)
- {
- return template.evaluate(match)
- };
-};
+// use native browser JS 1.6 implementation if available
+if (Object.isFunction(Array.prototype.forEach))
+ Array.prototype._each = Array.prototype.forEach;
-String.prototype.parseQuery = String.prototype.toQueryParams;
+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;
+};
-Object.extend(String.prototype.escapeHTML, {
- div: document.createElement('div'),
- text: document.createTextNode('')
-});
+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;
+};
-with (String.prototype.escapeHTML) div.appendChild(text);
+Array.prototype.toArray = Array.prototype.clone;
-var Template = Class.create({
- initialize: function(template, pattern)
- {
- this.template = template.toString();
- this.pattern = pattern || Template.Pattern;
- },
-
- evaluate: function(object)
- {
- if (Object.isFunction(object.toTemplateReplacements))
- object = object.toTemplateReplacements();
-
- return this.template.gsub(this.pattern, function(match)
- {
- if (object == null) return '';
-
- var before = match[1] || '';
- if (before == '\\') return match[2];
-
- var ctx = object, expr = match[3];
- var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
- match = pattern.exec(expr);
- if (match == null) return before;
-
- while (match != null)
- {
- var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
- ctx = ctx[comp];
- if (null == ctx || '' == match[3]) break;
- expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
- match = pattern.exec(expr);
- }
+function $w(string) {
+ if (!Object.isString(string)) return [];
+ string = string.strip();
+ return string ? string.split(/\s+/) : [];
+}
- return before + String.interpret(ctx);
- }.bind(this));
+if (Prototype.Browser.Opera){
+ Array.prototype.concat = function() {
+ var array = [];
+ for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+ 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]);
+ } else {
+ array.push(arguments[i]);
+ }
}
+ return array;
+ };
+}
+Object.extend(Number.prototype, {
+ toColorPart: function() {
+ return this.toPaddedString(2, 16);
+ },
+
+ succ: function() {
+ return this + 1;
+ },
+
+ times: function(iterator) {
+ $R(0, this, true).each(iterator);
+ return this;
+ },
+
+ toPaddedString: function(length, radix) {
+ var string = this.toString(radix || 10);
+ return '0'.times(length - string.length) + string;
+ },
+
+ toJSON: function() {
+ return isFinite(this) ? this.toString() : 'null';
+ }
});
-Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
-var $break = { };
+$w('abs round ceil floor').each(function(method){
+ Number.prototype[method] = Math[method].methodize();
+});
+function $H(object) {
+ return new Hash(object);
+};
-var Enumerable = {
- each: function(iterator, context)
- {
- var index = 0;
- iterator = iterator.bind(context);
- try
- {
- this._each(function(value)
- {
- iterator(value, index++);
- });
- }
- catch (e)
- {
- if (e != $break) throw e;
- }
- return this;
- },
+var Hash = Class.create(Enumerable, (function() {
- eachSlice: function(number, iterator, context)
- {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
- var index = -number, slices = [], array = this.toArray();
- while ((index += number) < array.length)
- slices.push(array.slice(index, index + number));
- return slices.collect(iterator, context);
- },
-
- all: function(iterator, context)
- {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
- var result = true;
- this.each(function(value, index)
- {
- result = result && !!iterator(value, index);
- if (!result) throw $break;
- });
- return result;
- },
+ function toQueryPair(key, value) {
+ if (Object.isUndefined(value)) return key;
+ return key + '=' + encodeURIComponent(String.interpret(value));
+ }
- any: function(iterator, context)
- {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
- var result = false;
- this.each(function(value, index)
- {
- if (result = !!iterator(value, index))
- throw $break;
- });
- return result;
+ return {
+ initialize: function(object) {
+ this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
},
- collect: function(iterator, context)
- {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
- var results = [];
- this.each(function(value, index)
- {
- results.push(iterator(value, index));
- });
- return results;
+ _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);
+ }
},
- detect: function(iterator, context)
- {
- iterator = iterator.bind(context);
- var result;
- this.each(function(value, index)
- {
- if (iterator(value, index))
- {
- result = value;
- throw $break;
- }
- });
- return result;
+ set: function(key, value) {
+ return this._object[key] = value;
},
- findAll: function(iterator, context)
- {
- iterator = iterator.bind(context);
- var results = [];
- this.each(function(value, index)
- {
- if (iterator(value, index))
- results.push(value);
- });
- return results;
+ get: function(key) {
+ return this._object[key];
},
- grep: function(filter, iterator, context)
- {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
- var results = [];
-
- if (Object.isString(filter))
- filter = new RegExp(filter);
-
- this.each(function(value, index)
- {
- if (filter.match(value))
- results.push(iterator(value, index));
- });
- return results;
+ unset: function(key) {
+ var value = this._object[key];
+ delete this._object[key];
+ return value;
},
- include: function(object)
- {
- if (Object.isFunction(this.indexOf))
- if (this.indexOf(object) != -1) return true;
-
- var found = false;
- this.each(function(value)
- {
- if (value == object)
- {
- found = true;
- throw $break;
- }
- });
- return found;
+ toObject: function() {
+ return Object.clone(this._object);
},
- inGroupsOf: function(number, fillWith)
- {
- fillWith = Object.isUndefined(fillWith) ? null : fillWith;
- return this.eachSlice(number, function(slice)
- {
- while (slice.length < number) slice.push(fillWith);
- return slice;
- });
+ keys: function() {
+ return this.pluck('key');
},
- inject: function(memo, iterator, context)
- {
- iterator = iterator.bind(context);
- this.each(function(value, index)
- {
- memo = iterator(memo, value, index);
- });
- return memo;
+ values: function() {
+ return this.pluck('value');
},
- invoke: function(method)
- {
- var args = $A(arguments).slice(1);
- return this.map(function(value)
- {
- return value[method].apply(value, args);
- });
+ index: function(value) {
+ var match = this.detect(function(pair) {
+ return pair.value === value;
+ });
+ return match && match.key;
},
- max: function(iterator, context)
- {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
- var result;
- this.each(function(value, index)
- {
- value = iterator(value, index);
- if (result == null || value >= result)
- result = value;
- });
- return result;
+ merge: function(object) {
+ return this.clone().update(object);
},
- min: function(iterator, context)
- {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
- var result;
- this.each(function(value, index)
- {
- value = iterator(value, index);
- if (result == null || value < result)
- result = value;
- });
+ update: function(object) {
+ return new Hash(object).inject(this, function(result, pair) {
+ result.set(pair.key, pair.value);
return result;
+ });
},
- partition: function(iterator, context)
- {
- iterator = iterator ? iterator.bind(context) : Prototype.K;
- var trues = [], falses = [];
- this.each(function(value, index)
- {
- (iterator(value, index) ?
- trues : falses).push(value);
- });
- return [trues, falses];
- },
-
- pluck: function(property)
- {
- var results = [];
- this.each(function(value)
- {
- results.push(value[property]);
- });
- return results;
- },
+ toQueryString: function() {
+ return this.map(function(pair) {
+ var key = encodeURIComponent(pair.key), values = pair.value;
- reject: function(iterator, context)
- {
- iterator = iterator.bind(context);
- var results = [];
- this.each(function(value, index)
- {
- if (!iterator(value, index))
- results.push(value);
- });
- return results;
+ if (values && typeof values == 'object') {
+ if (Object.isArray(values))
+ return values.map(toQueryPair.curry(key)).join('&');
+ }
+ return toQueryPair(key, values);
+ }).join('&');
},
- sortBy: function(iterator, context)
- {
- iterator = iterator.bind(context);
- return this.map(function(value, index)
- {
- return {value: value, criteria: iterator(value, index)};
- }).sort(function(left, right)
- {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- }).pluck('value');
- },
-
- toArray: function()
- {
- return this.map();
- },
-
- zip: function()
- {
- var iterator = Prototype.K, args = $A(arguments);
- if (Object.isFunction(args.last()))
- iterator = args.pop();
-
- var collections = [this].concat(args).map($A);
- return this.map(function(value, index)
- {
- return iterator(collections.pluck(index));
- });
+ inspect: function() {
+ return '#<Hash:{' + this.map(function(pair) {
+ return pair.map(Object.inspect).join(': ');
+ }).join(', ') + '}>';
},
- size: function()
- {
- return this.toArray().length;
+ toJSON: function() {
+ return Object.toJSON(this.toObject());
},
- inspect: function()
- {
- return '#<Enumerable:' + this.toArray().inspect() + '>';
+ clone: function() {
+ return new Hash(this);
}
-};
+ }
+})());
-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
-});
-function $A(iterable)
-{
- if (!iterable) return [];
- if (iterable.toArray) return iterable.toArray();
- var length = iterable.length || 0, results = new Array(length);
- while (length--) results[length] = iterable[length];
- return results;
-}
-
-if (Prototype.Browser.WebKit)
-{
- function $A(iterable)
- {
- if (!iterable) return [];
- if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
- iterable.toArray) return iterable.toArray();
- var length = iterable.length || 0, results = new Array(length);
- while (length--) results[length] = iterable[length];
- return results;
- }
-}
+Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
+Hash.from = $H;
+var ObjectRange = Class.create(Enumerable, {
+ initialize: function(start, end, exclusive) {
+ this.start = start;
+ this.end = end;
+ this.exclusive = exclusive;
+ },
+
+ _each: function(iterator) {
+ var value = this.start;
+ while (this.include(value)) {
+ iterator(value);
+ value = value.succ();
+ }
+ },
+
+ include: function(value) {
+ if (value < this.start)
+ return false;
+ if (this.exclusive)
+ return value < this.end;
+ return value <= this.end;
+ }
+});
-Array.from = $A;
+var $R = function(start, end, exclusive) {
+ return new ObjectRange(start, end, exclusive);
+};
-Object.extend(Array.prototype, Enumerable);
+var Ajax = {
+ getTransport: function() {
+ return Try.these(
+ function() {return new XMLHttpRequest()},
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+ ) || false;
+ },
-if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
+ activeRequestCount: 0
+};
-Object.extend(Array.prototype, {
- _each: function(iterator)
- {
- for (var i = 0, length = this.length; i < length; i++)
- iterator(this[i]);
- },
+Ajax.Responders = {
+ responders: [],
- clear: function()
- {
- this.length = 0;
- return this;
- },
+ _each: function(iterator) {
+ this.responders._each(iterator);
+ },
+
+ register: function(responder) {
+ if (!this.include(responder))
+ this.responders.push(responder);
+ },
+
+ unregister: function(responder) {
+ this.responders = this.responders.without(responder);
+ },
+
+ dispatch: function(callback, request, transport, json) {
+ this.each(function(responder) {
+ if (Object.isFunction(responder[callback])) {
+ try {
+ responder[callback].apply(responder, [request, transport, json]);
+ } catch (e) { }
+ }
+ });
+ }
+};
- first: function()
- {
- return this[0];
- },
+Object.extend(Ajax.Responders, Enumerable);
- last: function()
- {
- return this[this.length - 1];
- },
+Ajax.Responders.register({
+ onCreate: function() { Ajax.activeRequestCount++ },
+ onComplete: function() { Ajax.activeRequestCount-- }
+});
- compact: function()
- {
- return this.select(function(value)
- {
- return value != null;
- });
- },
+Ajax.Base = Class.create({
+ initialize: function(options) {
+ this.options = {
+ method: 'post',
+ asynchronous: true,
+ contentType: 'application/x-www-form-urlencoded',
+ encoding: 'UTF-8',
+ parameters: '',
+ evalJSON: true,
+ evalJS: true
+ };
+ Object.extend(this.options, options || { });
- flatten: function()
- {
- return this.inject([], function(array, value)
- {
- return array.concat(Object.isArray(value) ?
- value.flatten() : [value]);
- });
- },
+ this.options.method = this.options.method.toLowerCase();
- without: function()
- {
- var values = $A(arguments);
- return this.select(function(value)
- {
- return !values.include(value);
- });
- },
+ if (Object.isString(this.options.parameters))
+ this.options.parameters = this.options.parameters.toQueryParams();
+ else if (Object.isHash(this.options.parameters))
+ this.options.parameters = this.options.parameters.toObject();
+ }
+});
- reverse: function(inline)
- {
- return (inline !== false ? this : this.toArray())._reverse();
- },
-
- reduce: function()
- {
- return this.length > 1 ? this : this[0];
- },
-
- uniq: function(sorted)
- {
- return this.inject([], function(array, value, index)
- {
- if (0 == index || (sorted ? array.last() != value : !array.include(value)))
- array.push(value);
- return array;
- });
- },
+Ajax.Request = Class.create(Ajax.Base, {
+ _complete: false,
- intersect: function(array)
- {
- return this.uniq().findAll(function(item)
- {
- return array.detect(function(value)
- {
- return item === value
- });
- });
- },
+ initialize: function($super, url, options) {
+ $super(options);
+ this.transport = Ajax.getTransport();
+ this.request(url);
+ },
- clone: function()
- {
- return [].concat(this);
- },
+ request: function(url) {
+ this.url = url;
+ this.method = this.options.method;
+ var params = Object.clone(this.options.parameters);
- size: function()
- {
- return this.length;
- },
+ if (!['get', 'post'].include(this.method)) {
+ // simulate other verbs over post
+ params['_method'] = this.method;
+ this.method = 'post';
+ }
- inspect: function()
- {
- return '[' + this.map(Object.inspect).join(', ') + ']';
- },
+ this.parameters = params;
- toJSON: function()
- {
- var results = [];
- this.each(function(object)
- {
- var value = Object.toJSON(object);
- if (!Object.isUndefined(value)) results.push(value);
- });
- return '[' + results.join(', ') + ']';
+ if (params = Object.toQueryString(params)) {
+ // when GET, append parameters to URL
+ if (this.method == 'get')
+ this.url += (this.url.include('?') ? '&' : '?') + params;
+ else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
+ params += '&_=';
}
-});
-// use native browser JS 1.6 implementation if available
-if (Object.isFunction(Array.prototype.forEach))
- Array.prototype._each = Array.prototype.forEach;
+ try {
+ var response = new Ajax.Response(this);
+ if (this.options.onCreate) this.options.onCreate(response);
+ Ajax.Responders.dispatch('onCreate', this, response);
-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;
-};
+ this.transport.open(this.method.toUpperCase(), this.url,
+ this.options.asynchronous);
-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;
-};
+ if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
-Array.prototype.toArray = Array.prototype.clone;
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
+ this.setRequestHeaders();
-function $w(string)
-{
- if (!Object.isString(string)) return [];
- string = string.strip();
- return string ? string.split(/\s+/) : [];
-}
+ this.body = this.method == 'post' ? (this.options.postBody || params) : null;
+ this.transport.send(this.body);
-if (Prototype.Browser.Opera)
-{
- Array.prototype.concat = function()
- {
- var array = [];
- for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
- 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]);
- }
- else
- {
- array.push(arguments[i]);
- }
- }
- return array;
- };
-}
-Object.extend(Number.prototype, {
- toColorPart: function()
- {
- return this.toPaddedString(2, 16);
- },
+ /* Force Firefox to handle ready state 4 for synchronous requests */
+ if (!this.options.asynchronous && this.transport.overrideMimeType)
+ this.onStateChange();
- succ: function()
- {
- return this + 1;
- },
+ }
+ catch (e) {
+ this.dispatchException(e);
+ }
+ },
- times: function(iterator)
- {
- $R(0, this, true).each(iterator);
- return this;
- },
+ onStateChange: function() {
+ var readyState = this.transport.readyState;
+ if (readyState > 1 && !((readyState == 4) && this._complete))
+ this.respondToReadyState(this.transport.readyState);
+ },
- toPaddedString: function(length, radix)
- {
- var string = this.toString(radix || 10);
- return '0'.times(length - string.length) + string;
- },
+ setRequestHeaders: function() {
+ var headers = {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'X-Prototype-Version': Prototype.Version,
+ 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+ };
- toJSON: function()
- {
- return isFinite(this) ? this.toString() : 'null';
+ if (this.method == 'post') {
+ headers['Content-type'] = this.options.contentType +
+ (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+ /* Force "Connection: close" for older Mozilla browsers to work
+ * around a bug where XMLHttpRequest sends an incorrect
+ * Content-length header. See Mozilla Bugzilla #246651.
+ */
+ if (this.transport.overrideMimeType &&
+ (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+ headers['Connection'] = 'close';
}
-});
-$w('abs round ceil floor').each(function(method)
-{
- Number.prototype[method] = Math[method].methodize();
+ // user-defined headers
+ if (typeof this.options.requestHeaders == 'object') {
+ var extras = this.options.requestHeaders;
+
+ if (Object.isFunction(extras.push))
+ for (var i = 0, length = extras.length; i < length; i += 2)
+ headers[extras[i]] = extras[i+1];
+ else
+ $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+ }
+
+ for (var name in headers)
+ this.transport.setRequestHeader(name, headers[name]);
+ },
+
+ success: function() {
+ var status = this.getStatus();
+ return !status || (status >= 200 && status < 300);
+ },
+
+ getStatus: function() {
+ try {
+ return this.transport.status || 0;
+ } catch (e) { return 0 }
+ },
+
+ respondToReadyState: function(readyState) {
+ var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
+
+ if (state == 'Complete') {
+ try {
+ this._complete = true;
+ (this.options['on' + response.status]
+ || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+ || Prototype.emptyFunction)(response, response.headerJSON);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ var contentType = response.getHeader('Content-type');
+ if (this.options.evalJS == 'force'
+ || (this.options.evalJS && contentType
+ && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
+ this.evalResponse();
+ }
+
+ try {
+ (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
+ Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ if (state == 'Complete') {
+ // avoid memory leak in MSIE: clean up
+ this.transport.onreadystatechange = Prototype.emptyFunction;
+ }
+ },
+
+ getHeader: function(name) {
+ try {
+ return this.transport.getResponseHeader(name) || null;
+ } catch (e) { return null }
+ },
+
+ evalResponse: function() {
+ try {
+ return eval((this.transport.responseText || '').unfilterJSON());
+ } catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
+ dispatchException: function(exception) {
+ (this.options.onException || Prototype.emptyFunction)(this, exception);
+ Ajax.Responders.dispatch('onException', this, exception);
+ }
});
-function $H(object)
-{
- return new Hash(object);
-}
-;
-var Hash = Class.create(Enumerable, (function()
-{
+Ajax.Request.Events =
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
- function toQueryPair(key, value)
- {
- if (Object.isUndefined(value)) return key;
- return key + '=' + encodeURIComponent(String.interpret(value));
+Ajax.Response = Class.create({
+ initialize: function(request){
+ this.request = request;
+ var transport = this.transport = request.transport,
+ readyState = this.readyState = transport.readyState;
+
+ if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
+ this.status = this.getStatus();
+ this.statusText = this.getStatusText();
+ this.responseText = String.interpret(transport.responseText);
+ this.headerJSON = this._getHeaderJSON();
+ }
+
+ if(readyState == 4) {
+ var xml = transport.responseXML;
+ this.responseXML = Object.isUndefined(xml) ? null : xml;
+ this.responseJSON = this._getResponseJSON();
+ }
+ },
+
+ status: 0,
+ statusText: '',
+
+ getStatus: Ajax.Request.prototype.getStatus,
+
+ getStatusText: function() {
+ try {
+ return this.transport.statusText || '';
+ } catch (e) { return '' }
+ },
+
+ getHeader: Ajax.Request.prototype.getHeader,
+
+ getAllHeaders: function() {
+ try {
+ return this.getAllResponseHeaders();
+ } catch (e) { return null }
+ },
+
+ getResponseHeader: function(name) {
+ return this.transport.getResponseHeader(name);
+ },
+
+ getAllResponseHeaders: function() {
+ return this.transport.getAllResponseHeaders();
+ },
+
+ _getHeaderJSON: function() {
+ var json = this.getHeader('X-JSON');
+ if (!json) return null;
+ json = decodeURIComponent(escape(json));
+ try {
+ return json.evalJSON(this.request.options.sanitizeJSON);
+ } catch (e) {
+ this.request.dispatchException(e);
+ }
+ },
+
+ _getResponseJSON: function() {
+ var options = this.request.options;
+ if (!options.evalJSON || (options.evalJSON != 'force' &&
+ !(this.getHeader('Content-type') || '').include('application/json')) ||
+ this.responseText.blank())
+ return null;
+ try {
+ return this.responseText.evalJSON(options.sanitizeJSON);
+ } catch (e) {
+ this.request.dispatchException(e);
}
+ }
+});
- 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);
- }
- },
-
- set: function(key, value)
- {
- return this._object[key] = value;
- },
+Ajax.Updater = Class.create(Ajax.Request, {
+ initialize: function($super, container, url, options) {
+ this.container = {
+ success: (container.success || container),
+ failure: (container.failure || (container.success ? null : container))
+ };
- get: function(key)
- {
- return this._object[key];
- },
+ options = Object.clone(options);
+ var onComplete = options.onComplete;
+ options.onComplete = (function(response, json) {
+ this.updateContent(response.responseText);
+ if (Object.isFunction(onComplete)) onComplete(response, json);
+ }).bind(this);
+
+ $super(url, options);
+ },
+
+ updateContent: function(responseText) {
+ var receiver = this.container[this.success() ? 'success' : 'failure'],
+ options = this.options;
+
+ if (!options.evalScripts) responseText = responseText.stripScripts();
+
+ if (receiver = $(receiver)) {
+ if (options.insertion) {
+ if (Object.isString(options.insertion)) {
+ var insertion = { }; insertion[options.insertion] = responseText;
+ receiver.insert(insertion);
+ }
+ else options.insertion(receiver, responseText);
+ }
+ else receiver.update(responseText);
+ }
+ }
+});
- unset: function(key)
- {
- var value = this._object[key];
- delete this._object[key];
- return value;
- },
+Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
+ initialize: function($super, container, url, options) {
+ $super(options);
+ this.onComplete = this.options.onComplete;
+
+ this.frequency = (this.options.frequency || 2);
+ this.decay = (this.options.decay || 1);
+
+ this.updater = { };
+ this.container = container;
+ this.url = url;
+
+ this.start();
+ },
+
+ start: function() {
+ this.options.onComplete = this.updateComplete.bind(this);
+ this.onTimerEvent();
+ },
+
+ stop: function() {
+ this.updater.options.onComplete = undefined;
+ clearTimeout(this.timer);
+ (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+ },
+
+ updateComplete: function(response) {
+ if (this.options.decay) {
+ this.decay = (response.responseText == this.lastText ?
+ this.decay * this.options.decay : 1);
+
+ this.lastText = response.responseText;
+ }
+ this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
+ },
+
+ onTimerEvent: function() {
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
+ }
+});
+function $(element) {
+ if (arguments.length > 1) {
+ for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+ elements.push($(arguments[i]));
+ return elements;
+ }
+ if (Object.isString(element))
+ element = document.getElementById(element);
+ return Element.extend(element);
+}
- toObject: function()
- {
- return Object.clone(this._object);
- },
+if (Prototype.BrowserFeatures.XPath) {
+ document._getElementsByXPath = function(expression, parentElement) {
+ var results = [];
+ var query = document.evaluate(expression, $(parentElement) || document,
+ null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ for (var i = 0, length = query.snapshotLength; i < length; i++)
+ results.push(Element.extend(query.snapshotItem(i)));
+ return results;
+ };
+}
- keys: function()
- {
- return this.pluck('key');
- },
+/*--------------------------------------------------------------------------*/
- values: function()
- {
- return this.pluck('value');
- },
+if (!window.Node) var Node = { };
- index: function(value)
- {
- var match = this.detect(function(pair)
- {
- return pair.value === value;
- });
- return match && match.key;
- },
+if (!Node.ELEMENT_NODE) {
+ // DOM level 2 ECMAScript Language Binding
+ Object.extend(Node, {
+ ELEMENT_NODE: 1,
+ ATTRIBUTE_NODE: 2,
+ TEXT_NODE: 3,
+ CDATA_SECTION_NODE: 4,
+ ENTITY_REFERENCE_NODE: 5,
+ ENTITY_NODE: 6,
+ PROCESSING_INSTRUCTION_NODE: 7,
+ COMMENT_NODE: 8,
+ DOCUMENT_NODE: 9,
+ DOCUMENT_TYPE_NODE: 10,
+ DOCUMENT_FRAGMENT_NODE: 11,
+ NOTATION_NODE: 12
+ });
+}
- merge: function(object)
- {
- return this.clone().update(object);
- },
+(function() {
+ var element = this.Element;
+ this.Element = function(tagName, attributes) {
+ attributes = attributes || { };
+ tagName = tagName.toLowerCase();
+ var cache = Element.cache;
+ if (Prototype.Browser.IE && attributes.name) {
+ tagName = '<' + tagName + ' name="' + attributes.name + '">';
+ delete attributes.name;
+ return Element.writeAttribute(document.createElement(tagName), attributes);
+ }
+ if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
+ return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
+ };
+ Object.extend(this.Element, element || { });
+}).call(window);
- update: function(object)
- {
- return new Hash(object).inject(this, function(result, pair)
- {
- result.set(pair.key, pair.value);
- return result;
- });
- },
+Element.cache = { };
- toQueryString: function()
- {
- return this.map(function(pair)
- {
- var key = encodeURIComponent(pair.key), values = pair.value;
-
- if (values && typeof values == 'object')
- {
- if (Object.isArray(values))
- return values.map(toQueryPair.curry(key)).join('&');
- }
- return toQueryPair(key, values);
- }).join('&');
- },
+Element.Methods = {
+ visible: function(element) {
+ return $(element).style.display != 'none';
+ },
+
+ toggle: function(element) {
+ element = $(element);
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
+ return element;
+ },
+
+ hide: function(element) {
+ $(element).style.display = 'none';
+ return element;
+ },
+
+ show: function(element) {
+ $(element).style.display = '';
+ return element;
+ },
+
+ remove: function(element) {
+ element = $(element);
+ element.parentNode.removeChild(element);
+ return element;
+ },
+
+ update: function(element, content) {
+ element = $(element);
+ if (content && content.toElement) content = content.toElement();
+ if (Object.isElement(content)) return element.update().insert(content);
+ content = Object.toHTML(content);
+ element.innerHTML = content.stripScripts();
+ content.evalScripts.bind(content).defer();
+ return element;
+ },
+
+ replace: function(element, content) {
+ element = $(element);
+ if (content && content.toElement) content = content.toElement();
+ else if (!Object.isElement(content)) {
+ content = Object.toHTML(content);
+ var range = element.ownerDocument.createRange();
+ range.selectNode(element);
+ content.evalScripts.bind(content).defer();
+ content = range.createContextualFragment(content.stripScripts());
+ }
+ element.parentNode.replaceChild(content, element);
+ return element;
+ },
+
+ insert: function(element, insertions) {
+ element = $(element);
+
+ if (Object.isString(insertions) || Object.isNumber(insertions) ||
+ Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
+ insertions = {bottom:insertions};
+
+ var content, insert, tagName, childNodes;
+
+ for (position in insertions) {
+ content = insertions[position];
+ position = position.toLowerCase();
+ insert = Element._insertionTranslations[position];
+
+ if (content && content.toElement) content = content.toElement();
+ if (Object.isElement(content)) {
+ insert(element, content);
+ continue;
+ }
+
+ content = Object.toHTML(content);
+
+ tagName = ((position == 'before' || position == 'after')
+ ? element.parentNode : element).tagName.toUpperCase();
+
+ childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+
+ if (position == 'top' || position == 'after') childNodes.reverse();
+ childNodes.each(insert.curry(element));
+
+ content.evalScripts.bind(content).defer();
+ }
+
+ return element;
+ },
+
+ wrap: function(element, wrapper, attributes) {
+ element = $(element);
+ if (Object.isElement(wrapper))
+ $(wrapper).writeAttribute(attributes || { });
+ else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
+ else wrapper = new Element('div', wrapper);
+ if (element.parentNode)
+ element.parentNode.replaceChild(wrapper, element);
+ wrapper.appendChild(element);
+ return wrapper;
+ },
+
+ inspect: function(element) {
+ element = $(element);
+ var result = '<' + element.tagName.toLowerCase();
+ $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+ var property = pair.first(), attribute = pair.last();
+ var value = (element[property] || '').toString();
+ if (value) result += ' ' + attribute + '=' + value.inspect(true);
+ });
+ return result + '>';
+ },
- inspect: function()
- {
- return '#<Hash:{' + this.map(function(pair)
- {
- return pair.map(Object.inspect).join(': ');
- }).join(', ') + '}>';
- },
+ recursivelyCollect: function(element, property) {
+ element = $(element);
+ var elements = [];
+ while (element = element[property])
+ if (element.nodeType == 1)
+ elements.push(Element.extend(element));
+ return elements;
+ },
+
+ ancestors: function(element) {
+ return $(element).recursivelyCollect('parentNode');
+ },
+
+ descendants: function(element) {
+ return $(element).getElementsBySelector("*");
+ },
+
+ firstDescendant: function(element) {
+ element = $(element).firstChild;
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ return $(element);
+ },
+
+ immediateDescendants: function(element) {
+ if (!(element = $(element).firstChild)) return [];
+ while (element && element.nodeType != 1) element = element.nextSibling;
+ if (element) return [element].concat($(element).nextSiblings());
+ return [];
+ },
+
+ previousSiblings: function(element) {
+ return $(element).recursivelyCollect('previousSibling');
+ },
+
+ nextSiblings: function(element) {
+ return $(element).recursivelyCollect('nextSibling');
+ },
+
+ siblings: function(element) {
+ element = $(element);
+ return element.previousSiblings().reverse().concat(element.nextSiblings());
+ },
+
+ match: function(element, selector) {
+ if (Object.isString(selector))
+ selector = new Selector(selector);
+ return selector.match($(element));
+ },
+
+ up: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return $(element.parentNode);
+ var ancestors = element.ancestors();
+ return Object.isNumber(expression) ? ancestors[expression] :
+ Selector.findElement(ancestors, expression, index);
+ },
+
+ down: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return element.firstDescendant();
+ return Object.isNumber(expression) ? element.descendants()[expression] :
+ element.select(expression)[index || 0];
+ },
+
+ previous: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
+ var previousSiblings = element.previousSiblings();
+ return Object.isNumber(expression) ? previousSiblings[expression] :
+ Selector.findElement(previousSiblings, expression, index);
+ },
+
+ next: function(element, expression, index) {
+ element = $(element);
+ if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
+ var nextSiblings = element.nextSiblings();
+ return Object.isNumber(expression) ? nextSiblings[expression] :
+ Selector.findElement(nextSiblings, expression, index);
+ },
+
+ select: function() {
+ var args = $A(arguments), element = $(args.shift());
+ return Selector.findChildElements(element, args);
+ },
+
+ adjacent: function() {
+ var args = $A(arguments), element = $(args.shift());
+ return Selector.findChildElements(element.parentNode, args).without(element);
+ },
+
+ identify: function(element) {
+ element = $(element);
+ var id = element.readAttribute('id'), self = arguments.callee;
+ if (id) return id;
+ do { id = 'anonymous_element_' + self.counter++ } while ($(id));
+ element.writeAttribute('id', id);
+ return id;
+ },
+
+ readAttribute: function(element, name) {
+ element = $(element);
+ if (Prototype.Browser.IE) {
+ var t = Element._attributeTranslations.read;
+ if (t.values[name]) return t.values[name](element, name);
+ if (t.names[name]) name = t.names[name];
+ if (name.include(':')) {
+ return (!element.attributes || !element.attributes[name]) ? null :
+ element.attributes[name].value;
+ }
+ }
+ return element.getAttribute(name);
+ },
+
+ writeAttribute: function(element, name, value) {
+ element = $(element);
+ var attributes = { }, t = Element._attributeTranslations.write;
+
+ if (typeof name == 'object') attributes = name;
+ else attributes[name] = Object.isUndefined(value) ? true : value;
+
+ for (var attr in attributes) {
+ name = t.names[attr] || attr;
+ value = attributes[attr];
+ if (t.values[attr]) name = t.values[attr](element, value);
+ if (value === false || value === null)
+ element.removeAttribute(name);
+ else if (value === true)
+ element.setAttribute(name, name);
+ else element.setAttribute(name, value);
+ }
+ return element;
+ },
+
+ getHeight: function(element) {
+ return $(element).getDimensions().height;
+ },
+
+ getWidth: function(element) {
+ return $(element).getDimensions().width;
+ },
+
+ classNames: function(element) {
+ return new Element.ClassNames(element);
+ },
+
+ hasClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ var elementClassName = element.className;
+ return (elementClassName.length > 0 && (elementClassName == className ||
+ new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
+ },
+
+ addClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ if (!element.hasClassName(className))
+ element.className += (element.className ? ' ' : '') + className;
+ return element;
+ },
+
+ removeClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ element.className = element.className.replace(
+ new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
+ return element;
+ },
+
+ toggleClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ return element[element.hasClassName(className) ?
+ 'removeClassName' : 'addClassName'](className);
+ },
+
+ // removes whitespace-only text node children
+ cleanWhitespace: function(element) {
+ element = $(element);
+ var node = element.firstChild;
+ while (node) {
+ var nextNode = node.nextSibling;
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+ element.removeChild(node);
+ node = nextNode;
+ }
+ return element;
+ },
+
+ empty: function(element) {
+ return $(element).innerHTML.blank();
+ },
+
+ descendantOf: function(element, ancestor) {
+ element = $(element), ancestor = $(ancestor);
+ var originalAncestor = ancestor;
+
+ if (element.compareDocumentPosition)
+ return (element.compareDocumentPosition(ancestor) & 8) === 8;
+
+ if (element.sourceIndex && !Prototype.Browser.Opera) {
+ var e = element.sourceIndex, a = ancestor.sourceIndex,
+ nextAncestor = ancestor.nextSibling;
+ if (!nextAncestor) {
+ do { ancestor = ancestor.parentNode; }
+ while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
+ }
+ if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex);
+ }
+
+ while (element = element.parentNode)
+ if (element == originalAncestor) return true;
+ return false;
+ },
+
+ scrollTo: function(element) {
+ element = $(element);
+ var pos = element.cumulativeOffset();
+ window.scrollTo(pos[0], pos[1]);
+ return element;
+ },
+
+ getStyle: function(element, style) {
+ element = $(element);
+ style = style == 'float' ? 'cssFloat' : style.camelize();
+ var value = element.style[style];
+ if (!value) {
+ var css = document.defaultView.getComputedStyle(element, null);
+ value = css ? css[style] : null;
+ }
+ if (style == 'opacity') return value ? parseFloat(value) : 1.0;
+ return value == 'auto' ? null : value;
+ },
+
+ getOpacity: function(element) {
+ return $(element).getStyle('opacity');
+ },
+
+ setStyle: function(element, styles) {
+ element = $(element);
+ var elementStyle = element.style, match;
+ if (Object.isString(styles)) {
+ element.style.cssText += ';' + styles;
+ return styles.include('opacity') ?
+ element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
+ }
+ for (var property in styles)
+ if (property == 'opacity') element.setOpacity(styles[property]);
+ else
+ elementStyle[(property == 'float' || property == 'cssFloat') ?
+ (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
+ property] = styles[property];
+
+ return element;
+ },
+
+ setOpacity: function(element, value) {
+ element = $(element);
+ element.style.opacity = (value == 1 || value === '') ? '' :
+ (value < 0.00001) ? 0 : value;
+ return element;
+ },
+
+ getDimensions: function(element) {
+ element = $(element);
+ var display = $(element).getStyle('display');
+ if (display != 'none' && display != null) // Safari bug
+ return {width: element.offsetWidth, height: element.offsetHeight};
- toJSON: function()
- {
- return Object.toJSON(this.toObject());
- },
+ // All *Width and *Height properties give 0 on elements with display none,
+ // so enable the element temporarily
+ var els = element.style;
+ var originalVisibility = els.visibility;
+ var originalPosition = els.position;
+ var originalDisplay = els.display;
+ els.visibility = 'hidden';
+ els.position = 'absolute';
+ els.display = 'block';
+ var originalWidth = element.clientWidth;
+ var originalHeight = element.clientHeight;
+ els.display = originalDisplay;
+ els.position = originalPosition;
+ els.visibility = originalVisibility;
+ return {width: originalWidth, height: originalHeight};
+ },
+
[... 5715 lines stripped ...]