X-Git-Url: https://projects.mako.cc/source/selectricity-live/blobdiff_plain/469888b30ec666c4f5e11f0be42cab539b2a7ab4..a12d4f62752f546f57421244e370e79965706ffb:/public/javascripts/prototype.js diff --git a/public/javascripts/prototype.js b/public/javascripts/prototype.js index 0ba70a7..0caf9cd 100644 --- a/public/javascripts/prototype.js +++ b/public/javascripts/prototype.js @@ -1,17 +1,14 @@ -/* Prototype JavaScript framework, version 1.4.0_rc2 +/* Prototype JavaScript framework, version 1.5.0_rc0 * (c) 2005 Sam Stephenson * - * 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: '(?:)((\n|\r|.)*?)(?:<\/script>)', emptyFunction: function() {}, K: function(x) {return x} @@ -28,7 +25,7 @@ var Class = { var Abstract = new Object(); Object.extend = function(destination, source) { - for (property in source) { + for (var property in source) { destination[property] = source[property]; } return destination; @@ -45,10 +42,10 @@ Object.inspect = function(object) { } } -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))); } } @@ -119,30 +116,69 @@ PeriodicalExecuter.prototype = { } } } +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); @@ -186,12 +222,35 @@ Object.extend(String.prototype, { }, 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(); @@ -214,8 +273,8 @@ var Enumerable = { 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; }, @@ -223,7 +282,7 @@ var Enumerable = { 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; @@ -296,7 +355,7 @@ var Enumerable = { 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; @@ -306,7 +365,7 @@ var Enumerable = { 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; @@ -358,8 +417,7 @@ var Enumerable = { 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)); }); }, @@ -376,6 +434,7 @@ Object.extend(Enumerable, { entries: Enumerable.toArray }); var $A = Array.from = function(iterable) { + if (!iterable) return []; if (iterable.toArray) { return iterable.toArray(); } else { @@ -388,12 +447,20 @@ var $A = Array.from = function(iterable) { 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]; }, @@ -410,7 +477,7 @@ Object.extend(Array.prototype, { flatten: function() { return this.inject([], function(array, value) { - return array.concat(value.constructor == Array ? + return array.concat(value && value.constructor == Array ? value.flatten() : [value]); }); }, @@ -425,14 +492,11 @@ Object.extend(Array.prototype, { 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() { @@ -441,7 +505,7 @@ Object.extend(Array.prototype, { }); var Hash = { _each: function(iterator) { - for (key in this) { + for (var key in this) { var value = this[key]; if (typeof value == 'function') continue; @@ -486,9 +550,9 @@ function $H(object) { 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; @@ -513,15 +577,15 @@ Object.extend(Range.prototype, { }); 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; }, @@ -549,8 +613,7 @@ Ajax.Responders = { if (responder[callback] && typeof responder[callback] == 'function') { try { responder[callback].apply(responder, [request, transport, json]); - } catch (e) { - } + } catch (e) {} } }); } @@ -574,6 +637,7 @@ Ajax.Base.prototype = { this.options = { method: 'post', asynchronous: true, + contentType: 'application/x-www-form-urlencoded', parameters: '' } Object.extend(this.options, options || {}); @@ -626,19 +690,18 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), { 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 @@ -661,12 +724,23 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), { 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); } }, @@ -674,22 +748,38 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), { 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 = '(?:)((\n|.)*?)(?:<\/script>)'; Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { initialize: function(container, url, options) { @@ -714,16 +804,16 @@ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { 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); } } @@ -731,14 +821,6 @@ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { 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); - } } }); @@ -784,22 +866,57 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { 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'; }, @@ -830,6 +947,24 @@ Object.extend(Element, { 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; @@ -868,6 +1003,13 @@ Object.extend(Element, { 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, @@ -893,6 +1035,12 @@ Object.extend(Element, { 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') @@ -955,7 +1103,32 @@ Object.extend(Element, { 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; @@ -969,13 +1142,14 @@ Abstract.Insertion = function(adjacency) { 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; @@ -986,6 +1160,8 @@ Abstract.Insertion.prototype = { if (this.initializeRange) this.initializeRange(); this.insertContent([this.range.createContextualFragment(this.content)]); } + + setTimeout(function() {content.evalScripts()}, 10); }, contentFromAnonymousTable: function() { @@ -1018,7 +1194,7 @@ Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { }, insertContent: function(fragments) { - fragments.reverse().each((function(fragment) { + fragments.reverse(false).each((function(fragment) { this.element.insertBefore(fragment, this.element.firstChild); }).bind(this)); } @@ -1079,7 +1255,7 @@ Element.ClassNames.prototype = { if (!this.include(classNameToRemove)) return; this.set(this.select(function(className) { return className != classNameToRemove; - })); + }).join(' ')); }, toString: function() { @@ -1088,6 +1264,116 @@ Element.ClassNames.prototype = { } 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++) @@ -1109,8 +1395,10 @@ var Field = { }, activate: function(element) { - $(element).focus(); - $(element).select(); + element = $(element); + element.focus(); + if (element.select) + element.select(); } } @@ -1134,7 +1422,7 @@ var Form = { 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]); @@ -1178,16 +1466,15 @@ var Form = { } }, + 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) { @@ -1201,9 +1488,17 @@ Form.Element = { 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) { @@ -1249,23 +1544,17 @@ Form.Element.Serializers = { 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]; } @@ -1349,24 +1638,14 @@ Abstract.EventObserver.prototype = { 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; } } @@ -1492,7 +1771,8 @@ Object.extend(Event, { }); /* 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