-/* Prototype JavaScript framework, version 1.4.0_rc2
+/* Prototype JavaScript framework, version 1.5.0_rc0
* (c) 2005 Sam Stephenson <sam@conio.net>
*
- * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
- * against the source tree, available from the Prototype darcs repository.
- *
* Prototype is freely distributable under the terms of an MIT-style license.
- *
* For details, see the Prototype web site: http://prototype.conio.net/
*
/*--------------------------------------------------------------------------*/
var Prototype = {
- Version: '1.4.0_rc2',
+ Version: '1.5.0_rc0',
+ ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
emptyFunction: function() {},
K: function(x) {return x}
var Abstract = new Object();
Object.extend = function(destination, source) {
- for (property in source) {
+ for (var property in source) {
destination[property] = source[property];
}
return destination;
}
}
-Function.prototype.bind = function(object) {
- var __method = this;
+Function.prototype.bind = function() {
+ var __method = this, args = $A(arguments), object = args.shift();
return function() {
- return __method.apply(object, arguments);
+ return __method.apply(object, args.concat($A(arguments)));
}
}
}
}
}
+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 += (replacement(match) || '').toString();
+ source = source.slice(match.index + match[0].length);
+ } else {
+ result += source, source = '';
+ }
+ }
+ return result;
+ },
-/*--------------------------------------------------------------------------*/
+ sub: function(pattern, replacement, count) {
+ replacement = this.gsub.prepareReplacement(replacement);
+ count = count === undefined ? 1 : count;
-function $() {
- var elements = new Array();
+ return this.gsub(pattern, function(match) {
+ if (--count < 0) return match[0];
+ return replacement(match);
+ });
+ },
- for (var i = 0; i < arguments.length; i++) {
- var element = arguments[i];
- if (typeof element == 'string')
- element = document.getElementById(element);
+ scan: function(pattern, iterator) {
+ this.gsub(pattern, iterator);
+ return this;
+ },
- if (arguments.length == 1)
- return element;
+ truncate: function(length, truncation) {
+ length = length || 30;
+ truncation = truncation === undefined ? '...' : truncation;
+ return this.length > length ?
+ this.slice(0, length - truncation.length) + truncation : this;
+ },
- elements.push(element);
- }
+ strip: function() {
+ return this.replace(/^\s+/, '').replace(/\s+$/, '');
+ },
- return elements;
-}
-Object.extend(String.prototype, {
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];
+ });
+ },
+
+ evalScripts: function() {
+ return this.extractScripts().map(function(script) { return eval(script) });
+ },
+
escapeHTML: function() {
var div = document.createElement('div');
var text = document.createTextNode(this);
},
inspect: function() {
- return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'";
+ return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'";
}
});
+String.prototype.gsub.prepareReplacement = function(replacement) {
+ if (typeof replacement == 'function') return replacement;
+ var template = new Template(replacement);
+ return function(match) { return template.evaluate(match) };
+}
+
String.prototype.parseQuery = String.prototype.toQueryParams;
+var Template = Class.create();
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+Template.prototype = {
+ initialize: function(template, pattern) {
+ this.template = template.toString();
+ this.pattern = pattern || Template.Pattern;
+ },
+
+ evaluate: function(object) {
+ return this.template.gsub(this.pattern, function(match) {
+ var before = match[1];
+ if (before == '\\') return match[2];
+ return before + (object[match[3]] || '').toString();
+ });
+ }
+}
+
var $break = new Object();
var $continue = new Object();
all: function(iterator) {
var result = true;
this.each(function(value, index) {
- if (!(result &= (iterator || Prototype.K)(value, index)))
- throw $break;
+ result = result && !!(iterator || Prototype.K)(value, index);
+ if (!result) throw $break;
});
return result;
},
any: function(iterator) {
var result = true;
this.each(function(value, index) {
- if (result &= (iterator || Prototype.K)(value, index))
+ if (result = !!(iterator || Prototype.K)(value, index))
throw $break;
});
return result;
var result;
this.each(function(value, index) {
value = (iterator || Prototype.K)(value, index);
- if (value >= (result || value))
+ if (result == undefined || value >= result)
result = value;
});
return result;
var result;
this.each(function(value, index) {
value = (iterator || Prototype.K)(value, index);
- if (value <= (result || value))
+ if (result == undefined || value < result)
result = value;
});
return result;
var collections = [this].concat(args).map($A);
return this.map(function(value, index) {
- iterator(value = collections.pluck(index));
- return value;
+ return iterator(collections.pluck(index));
});
},
entries: Enumerable.toArray
});
var $A = Array.from = function(iterable) {
+ if (!iterable) return [];
if (iterable.toArray) {
return iterable.toArray();
} else {
Object.extend(Array.prototype, Enumerable);
+if (!Array.prototype._reverse)
+ Array.prototype._reverse = Array.prototype.reverse;
+
Object.extend(Array.prototype, {
_each: function(iterator) {
for (var i = 0; i < this.length; i++)
iterator(this[i]);
},
+ clear: function() {
+ this.length = 0;
+ return this;
+ },
+
first: function() {
return this[0];
},
flatten: function() {
return this.inject([], function(array, value) {
- return array.concat(value.constructor == Array ?
+ return array.concat(value && value.constructor == Array ?
value.flatten() : [value]);
});
},
indexOf: function(object) {
for (var i = 0; i < this.length; i++)
if (this[i] == object) return i;
- return false;
+ return -1;
},
- reverse: function() {
- var result = [];
- for (var i = this.length; i > 0; i--)
- result.push(this[i-1]);
- return result;
+ reverse: function(inline) {
+ return (inline !== false ? this : this.toArray())._reverse();
},
inspect: function() {
});
var Hash = {
_each: function(iterator) {
- for (key in this) {
+ for (var key in this) {
var value = this[key];
if (typeof value == 'function') continue;
Object.extend(hash, Hash);
return hash;
}
-var Range = Class.create();
-Object.extend(Range.prototype, Enumerable);
-Object.extend(Range.prototype, {
+ObjectRange = Class.create();
+Object.extend(ObjectRange.prototype, Enumerable);
+Object.extend(ObjectRange.prototype, {
initialize: function(start, end, exclusive) {
this.start = start;
this.end = end;
});
var $R = function(start, end, exclusive) {
- return new Range(start, end, exclusive);
+ return new ObjectRange(start, end, exclusive);
}
var Ajax = {
getTransport: function() {
return Try.these(
+ function() {return new XMLHttpRequest()},
function() {return new ActiveXObject('Msxml2.XMLHTTP')},
- function() {return new ActiveXObject('Microsoft.XMLHTTP')},
- function() {return new XMLHttpRequest()}
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')}
) || false;
},
if (responder[callback] && typeof responder[callback] == 'function') {
try {
responder[callback].apply(responder, [request, transport, json]);
- } catch (e) {
- }
+ } catch (e) {}
}
});
}
this.options = {
method: 'post',
asynchronous: true,
+ contentType: 'application/x-www-form-urlencoded',
parameters: ''
}
Object.extend(this.options, options || {});
this.transport.send(this.options.method == 'post' ? body : null);
} catch (e) {
- (this.options.onException || Prototype.emptyFunction)(this, e);
- Ajax.Responders.dispatch('onException', this, e);
+ this.dispatchException(e);
}
},
setRequestHeaders: function() {
var requestHeaders =
['X-Requested-With', 'XMLHttpRequest',
- 'X-Prototype-Version', Prototype.Version];
+ 'X-Prototype-Version', Prototype.Version,
+ 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*'];
if (this.options.method == 'post') {
- requestHeaders.push('Content-type',
- 'application/x-www-form-urlencoded');
+ requestHeaders.push('Content-type', this.options.contentType);
/* Force "Connection: close" for Mozilla browsers to work around
* a bug where XMLHttpReqeuest sends an incorrect Content-length
this.respondToReadyState(this.transport.readyState);
},
+ header: function(name) {
+ try {
+ return this.transport.getResponseHeader(name);
+ } catch (e) {}
+ },
+
evalJSON: function() {
try {
- var json = this.transport.getResponseHeader('X-JSON'), object;
- object = eval(json);
- return object;
+ return eval('(' + this.header('X-JSON') + ')');
+ } catch (e) {}
+ },
+
+ evalResponse: function() {
+ try {
+ return eval(this.transport.responseText);
} catch (e) {
+ this.dispatchException(e);
}
},
var event = Ajax.Request.Events[readyState];
var transport = this.transport, json = this.evalJSON();
- if (event == 'Complete')
- (this.options['on' + this.transport.status]
- || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
- || Prototype.emptyFunction)(transport, json);
+ if (event == 'Complete') {
+ try {
+ (this.options['on' + this.transport.status]
+ || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
+ || Prototype.emptyFunction)(transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
- (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
- Ajax.Responders.dispatch('on' + event, this, transport, json);
+ if ((this.header('Content-type') || '').match(/^text\/javascript/i))
+ this.evalResponse();
+ }
+
+ try {
+ (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + event, this, transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
/* Avoid memory leak in MSIE: clean up the oncomplete event handler */
if (event == 'Complete')
this.transport.onreadystatechange = Prototype.emptyFunction;
+ },
+
+ dispatchException: function(exception) {
+ (this.options.onException || Prototype.emptyFunction)(this, exception);
+ Ajax.Responders.dispatch('onException', this, exception);
}
});
Ajax.Updater = Class.create();
-Ajax.Updater.ScriptFragment = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)';
Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
initialize: function(container, url, options) {
updateContent: function() {
var receiver = this.responseIsSuccess() ?
this.containers.success : this.containers.failure;
+ var response = this.transport.responseText;
- var match = new RegExp(Ajax.Updater.ScriptFragment, 'img');
- var response = this.transport.responseText.replace(match, '');
- var scripts = this.transport.responseText.match(match);
+ if (!this.options.evalScripts)
+ response = response.stripScripts();
if (receiver) {
if (this.options.insertion) {
new this.options.insertion(receiver, response);
} else {
- receiver.innerHTML = response;
+ Element.update(receiver, response);
}
}
if (this.onComplete)
setTimeout(this.onComplete.bind(this), 10);
}
-
- if (this.options.evalScripts && scripts) {
- match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
- setTimeout((function() {
- for (var i = 0; i < scripts.length; i++)
- eval(scripts[i].match(match)[1]);
- }).bind(this), 10);
- }
}
});
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
+function $() {
+ var results = [], element;
+ for (var i = 0; i < arguments.length; i++) {
+ element = arguments[i];
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+ results.push(Element.extend(element));
+ }
+ return results.length < 2 ? results[0] : results;
+}
+
document.getElementsByClassName = function(className, parentElement) {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
return $A(children).inject([], function(elements, child) {
if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
- elements.push(child);
+ elements.push(Element.extend(child));
return elements;
});
}
/*--------------------------------------------------------------------------*/
-if (!window.Element) {
+if (!window.Element)
var Element = new Object();
+
+Element.extend = function(element) {
+ if (!element) return;
+ if (_nativeExtensions) return element;
+
+ if (!element._extended && element.tagName && element != window) {
+ var methods = Element.Methods, cache = Element.extend.cache;
+ for (property in methods) {
+ var value = methods[property];
+ if (typeof value == 'function')
+ element[property] = cache.findOrStore(value);
+ }
+ }
+
+ element._extended = true;
+ return element;
}
-Object.extend(Element, {
+Element.extend.cache = {
+ findOrStore: function(value) {
+ return this[value] = this[value] || function() {
+ return value.apply(null, [this].concat($A(arguments)));
+ }
+ }
+}
+
+Element.Methods = {
visible: function(element) {
return $(element).style.display != 'none';
},
element.parentNode.removeChild(element);
},
+ update: function(element, html) {
+ $(element).innerHTML = html.stripScripts();
+ setTimeout(function() {html.evalScripts()}, 10);
+ },
+
+ replace: function(element, html) {
+ element = $(element);
+ if (element.outerHTML) {
+ element.outerHTML = html.stripScripts();
+ } else {
+ var range = element.ownerDocument.createRange();
+ range.selectNodeContents(element);
+ element.parentNode.replaceChild(
+ range.createContextualFragment(html.stripScripts()), element);
+ }
+ setTimeout(function() {html.evalScripts()}, 10);
+ },
+
getHeight: function(element) {
element = $(element);
return element.offsetHeight;
return $(element).innerHTML.match(/^\s*$/);
},
+ childOf: function(element, ancestor) {
+ element = $(element), ancestor = $(ancestor);
+ while (element = element.parentNode)
+ if (element == ancestor) return true;
+ return false;
+ },
+
scrollTo: function(element) {
element = $(element);
var x = element.x ? element.x : element.offsetLeft,
return value == 'auto' ? null : value;
},
+ setStyle: function(element, style) {
+ element = $(element);
+ for (var name in style)
+ element.style[name.camelize()] = style[name];
+ },
+
getDimensions: function(element) {
element = $(element);
if (Element.getStyle(element, 'display') != 'none')
element.style.overflow = element._overflow;
element._overflow = undefined;
}
-});
+}
+
+Object.extend(Element, Element.Methods);
+
+var _nativeExtensions = false;
+
+if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
+ var HTMLElement = {}
+ HTMLElement.prototype = document.createElement('div').__proto__;
+}
+
+Element.addMethods = function(methods) {
+ Object.extend(Element.Methods, methods || {});
+
+ if(typeof HTMLElement != 'undefined') {
+ var methods = Element.Methods, cache = Element.extend.cache;
+ for (property in methods) {
+ var value = methods[property];
+ if (typeof value == 'function')
+ HTMLElement.prototype[property] = cache.findOrStore(value);
+ }
+ _nativeExtensions = true;
+ }
+}
+
+Element.addMethods();
var Toggle = new Object();
Toggle.display = Element.toggle;
Abstract.Insertion.prototype = {
initialize: function(element, content) {
this.element = $(element);
- this.content = content;
+ this.content = content.stripScripts();
if (this.adjacency && this.element.insertAdjacentHTML) {
try {
this.element.insertAdjacentHTML(this.adjacency, this.content);
} catch (e) {
- if (this.element.tagName.toLowerCase() == 'tbody') {
+ var tagName = this.element.tagName.toLowerCase();
+ if (tagName == 'tbody' || tagName == 'tr') {
this.insertContent(this.contentFromAnonymousTable());
} else {
throw e;
if (this.initializeRange) this.initializeRange();
this.insertContent([this.range.createContextualFragment(this.content)]);
}
+
+ setTimeout(function() {content.evalScripts()}, 10);
},
contentFromAnonymousTable: function() {
},
insertContent: function(fragments) {
- fragments.reverse().each((function(fragment) {
+ fragments.reverse(false).each((function(fragment) {
this.element.insertBefore(fragment, this.element.firstChild);
}).bind(this));
}
if (!this.include(classNameToRemove)) return;
this.set(this.select(function(className) {
return className != classNameToRemove;
- }));
+ }).join(' '));
},
toString: function() {
}
Object.extend(Element.ClassNames.prototype, Enumerable);
+var Selector = Class.create();
+Selector.prototype = {
+ initialize: function(expression) {
+ this.params = {classNames: []};
+ this.expression = expression.toString().strip();
+ this.parseExpression();
+ this.compileMatcher();
+ },
+
+ parseExpression: function() {
+ function abort(message) { throw 'Parse error in selector: ' + message; }
+
+ if (this.expression == '') abort('empty expression');
+
+ var params = this.params, expr = this.expression, match, modifier, clause, rest;
+ while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
+ params.attributes = params.attributes || [];
+ params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
+ expr = match[1];
+ }
+
+ if (expr == '*') return this.params.wildcard = true;
+
+ while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
+ modifier = match[1], clause = match[2], rest = match[3];
+ switch (modifier) {
+ case '#': params.id = clause; break;
+ case '.': params.classNames.push(clause); break;
+ case '':
+ case undefined: params.tagName = clause.toUpperCase(); break;
+ default: abort(expr.inspect());
+ }
+ expr = rest;
+ }
+
+ if (expr.length > 0) abort(expr.inspect());
+ },
+
+ buildMatchExpression: function() {
+ var params = this.params, conditions = [], clause;
+
+ if (params.wildcard)
+ conditions.push('true');
+ if (clause = params.id)
+ conditions.push('element.id == ' + clause.inspect());
+ if (clause = params.tagName)
+ conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
+ if ((clause = params.classNames).length > 0)
+ for (var i = 0; i < clause.length; i++)
+ conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')');
+ if (clause = params.attributes) {
+ clause.each(function(attribute) {
+ var value = 'element.getAttribute(' + attribute.name.inspect() + ')';
+ var splitValueBy = function(delimiter) {
+ return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
+ }
+
+ switch (attribute.operator) {
+ case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break;
+ case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
+ case '|=': conditions.push(
+ splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
+ ); break;
+ case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break;
+ case '':
+ case undefined: conditions.push(value + ' != null'); break;
+ default: throw 'Unknown operator ' + attribute.operator + ' in selector';
+ }
+ });
+ }
+
+ return conditions.join(' && ');
+ },
+
+ compileMatcher: function() {
+ this.match = new Function('element', 'if (!element.tagName) return false; \
+ return ' + this.buildMatchExpression());
+ },
+
+ findElements: function(scope) {
+ var element;
+
+ if (element = $(this.params.id))
+ if (this.match(element))
+ if (!scope || Element.childOf(element, scope))
+ return [element];
+
+ scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
+
+ var results = [];
+ for (var i = 0; i < scope.length; i++)
+ if (this.match(element = scope[i]))
+ results.push(Element.extend(element));
+
+ return results;
+ },
+
+ toString: function() {
+ return this.expression;
+ }
+}
+
+function $$() {
+ return $A(arguments).map(function(expression) {
+ return expression.strip().split(/\s+/).inject([null], function(results, expr) {
+ var selector = new Selector(expr);
+ return results.map(selector.findElements.bind(selector)).flatten();
+ });
+ }).flatten();
+}
var Field = {
clear: function() {
for (var i = 0; i < arguments.length; i++)
},
activate: function(element) {
- $(element).focus();
- $(element).select();
+ element = $(element);
+ element.focus();
+ if (element.select)
+ element.select();
}
}
form = $(form);
var elements = new Array();
- for (tagName in Form.Element.Serializers) {
+ for (var tagName in Form.Element.Serializers) {
var tagElements = form.getElementsByTagName(tagName);
for (var j = 0; j < tagElements.length; j++)
elements.push(tagElements[j]);
}
},
+ findFirstElement: function(form) {
+ return Form.getElements(form).find(function(element) {
+ return element.type != 'hidden' && !element.disabled &&
+ ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ });
+ },
+
focusFirstElement: function(form) {
- form = $(form);
- var elements = Form.getElements(form);
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- if (element.type != 'hidden' && !element.disabled) {
- Field.activate(element);
- break;
- }
- }
+ Field.activate(Form.findFirstElement(form));
},
reset: function(form) {
var method = element.tagName.toLowerCase();
var parameter = Form.Element.Serializers[method](element);
- if (parameter)
- return encodeURIComponent(parameter[0]) + '=' +
- encodeURIComponent(parameter[1]);
+ if (parameter) {
+ var key = encodeURIComponent(parameter[0]);
+ if (key.length == 0) return;
+
+ if (parameter[1].constructor != Array)
+ parameter[1] = [parameter[1]];
+
+ return parameter[1].map(function(value) {
+ return key + '=' + encodeURIComponent(value);
+ }).join('&');
+ }
},
getValue: function(element) {
var value = '', opt, index = element.selectedIndex;
if (index >= 0) {
opt = element.options[index];
- value = opt.value;
- if (!value && !('value' in opt))
- value = opt.text;
+ value = opt.value || opt.text;
}
return [element.name, value];
},
selectMany: function(element) {
- var value = new Array();
+ var value = [];
for (var i = 0; i < element.length; i++) {
var opt = element.options[i];
- if (opt.selected) {
- var optValue = opt.value;
- if (!optValue && !('value' in opt))
- optValue = opt.text;
- value.push(optValue);
- }
+ if (opt.selected)
+ value.push(opt.value || opt.text);
}
return [element.name, value];
}
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
- element.target = this;
- element.prev_onclick = element.onclick || Prototype.emptyFunction;
- element.onclick = function() {
- this.prev_onclick();
- this.target.onElementEvent();
- }
+ Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
case 'password':
case 'text':
case 'textarea':
case 'select-one':
case 'select-multiple':
- element.target = this;
- element.prev_onchange = element.onchange || Prototype.emptyFunction;
- element.onchange = function() {
- this.prev_onchange();
- this.target.onElementEvent();
- }
+ Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}
}
});
/* prevent memory leaks in IE */
-Event.observe(window, 'unload', Event.unloadCache, false);
+if (navigator.appVersion.match(/\bMSIE\b/))
+ Event.observe(window, 'unload', Event.unloadCache, false);
var Position = {
// set to true if needed, warning: firefox performance problems
// NOT neeeded for page scrolling, only if draggable contained in