From 5fef42452e959e98e533d5c356c53771e0f30970 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 10 May 2010 20:59:18 +0000 Subject: [PATCH] Fix: optimize speed Qual: update scriptaculous en protoype --- htdocs/includes/pwc/window_mini.jgz | Bin 9723 -> 13543 bytes htdocs/includes/scriptaculous/CHANGELOG | 16 + htdocs/includes/scriptaculous/MIT-LICENSE | 2 +- .../includes/scriptaculous/lib/prototype.js | 3000 ++++++++++------- .../scriptaculous/lib/prototype_mini.jgz | Bin 23239 -> 28228 bytes htdocs/includes/scriptaculous/src/builder.js | 4 +- htdocs/includes/scriptaculous/src/controls.js | 8 +- htdocs/includes/scriptaculous/src/dragdrop.js | 13 +- htdocs/includes/scriptaculous/src/effects.js | 23 +- .../scriptaculous/src/scriptaculous.js | 18 +- htdocs/includes/scriptaculous/src/slider.js | 12 +- htdocs/includes/scriptaculous/src/sound.js | 10 +- htdocs/includes/scriptaculous/src/unittest.js | 8 +- htdocs/main.inc.php | 3 + 14 files changed, 1847 insertions(+), 1270 deletions(-) diff --git a/htdocs/includes/pwc/window_mini.jgz b/htdocs/includes/pwc/window_mini.jgz index b1e900293c724609cfe41d124f70ec198855e08d..853b4eed15b6ce15472734892db0a4749c49ac4a 100644 GIT binary patch literal 13543 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 JV@y`A001W0;e7xA diff --git a/htdocs/includes/scriptaculous/CHANGELOG b/htdocs/includes/scriptaculous/CHANGELOG index 5125cd1ae85..d112a95995f 100644 --- a/htdocs/includes/scriptaculous/CHANGELOG +++ b/htdocs/includes/scriptaculous/CHANGELOG @@ -1,3 +1,19 @@ +*V1.8.3* (October 8, 2009) + +* Update to Prototype 1.6.1 + +* Effect.toggle to return effect (to be able to do Effect.toggle(element, 'appear', {sync: true});) [RStankov] + +* Use element.identify() for fetching element.id in Sortable.create [RStankov] + +* Fix deprecated usage of Position.cumulativeOffset. [#182 state:resolved] [James Wheare] + +* Make loader work for application/xhtml+xml served documents. Closes #95. [Pavel Sedek] + +* Check for Windows Media plugin and RealPlayer plugin in Firefox on Windows to allow sound playback. Closes #36, #86. [Alexander Gavazov et al.] + +* Remove dead code in effects.js. Closes #125. [Confusioner] + *V1.8.2* (November 18, 2008) * Update to Prototype 1.6.0.3 diff --git a/htdocs/includes/scriptaculous/MIT-LICENSE b/htdocs/includes/scriptaculous/MIT-LICENSE index 3889631a368..6d1340dbc16 100644 --- a/htdocs/includes/scriptaculous/MIT-LICENSE +++ b/htdocs/includes/scriptaculous/MIT-LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/htdocs/includes/scriptaculous/lib/prototype.js b/htdocs/includes/scriptaculous/lib/prototype.js index dfe8ab4e136..9fe6e1243bc 100644 --- a/htdocs/includes/scriptaculous/lib/prototype.js +++ b/htdocs/includes/scriptaculous/lib/prototype.js @@ -1,5 +1,5 @@ -/* Prototype JavaScript framework, version 1.6.0.3 - * (c) 2005-2008 Sam Stephenson +/* Prototype JavaScript framework, version 1.6.1 + * (c) 2005-2009 Sam Stephenson * * Prototype is freely distributable under the terms of an MIT-style license. * For details, see the Prototype web site: http://www.prototypejs.org/ @@ -7,26 +7,43 @@ *--------------------------------------------------------------------------*/ var Prototype = { - Version: '1.6.0.3', + Version: '1.6.1', - Browser: { - IE: !!(window.attachEvent && - navigator.userAgent.indexOf('Opera') === -1), - Opera: navigator.userAgent.indexOf('Opera') > -1, - WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, - Gecko: navigator.userAgent.indexOf('Gecko') > -1 && - navigator.userAgent.indexOf('KHTML') === -1, - MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) - }, + Browser: (function(){ + var ua = navigator.userAgent; + var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; + return { + IE: !!window.attachEvent && !isOpera, + Opera: isOpera, + WebKit: ua.indexOf('AppleWebKit/') > -1, + Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, + MobileSafari: /Apple.*Mobile.*Safari/.test(ua) + } + })(), BrowserFeatures: { XPath: !!document.evaluate, SelectorsAPI: !!document.querySelector, - ElementExtensions: !!window.HTMLElement, - SpecificElementExtensions: - document.createElement('div')['__proto__'] && - document.createElement('div')['__proto__'] !== - document.createElement('form')['__proto__'] + ElementExtensions: (function() { + var constructor = window.Element || window.HTMLElement; + return !!(constructor && constructor.prototype); + })(), + SpecificElementExtensions: (function() { + if (typeof window.HTMLDivElement !== 'undefined') + return true; + + var div = document.createElement('div'); + var form = document.createElement('form'); + var isSupported = false; + + if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) { + isSupported = true; + } + + div = form = null; + + return isSupported; + })() }, ScriptFragment: ']*>([\\S\\s]*?)<\/script>', @@ -40,232 +57,8 @@ if (Prototype.Browser.MobileSafari) 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); - } - - 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); - } - - for (var i = 0; i < properties.length; i++) - klass.addMethods(properties[i]); - - 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 = (function(m) { - return function() { return ancestor[m].apply(this, arguments) }; - })(property).wrap(method); - - value.valueOf = method.valueOf.bind(method); - value.toString = method.toString.bind(method); - } - 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(Object, { - inspect: function(object) { - try { - if (Object.isUndefined(object)) return 'undefined'; - if (object === null) return 'null'; - return object.inspect ? object.inspect() : String(object); - } catch (e) { - if (e instanceof RangeError) return '...'; - throw e; - } - }, - - toJSON: function(object) { - 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 != null && typeof object == "object" && - 'splice' in object && 'join' in object; - }, - - 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] - .replace(/\s+/g, '').split(','); - 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); - }, - - defer: function() { - var args = [0.01].concat($A(arguments)); - return this.delay.apply(this, args); - }, - - 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))); - }; - } -}); - -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() { @@ -283,14 +76,297 @@ var Try = { } }; +/* Based on Alex Arnell's inheritance implementation. */ + +var Class = (function() { + function subclass() {}; + function create() { + var parent = null, properties = $A(arguments); + if (Object.isFunction(properties[0])) + parent = properties.shift(); + + function klass() { + this.initialize.apply(this, arguments); + } + + Object.extend(klass, Class.Methods); + klass.superclass = parent; + klass.subclasses = []; + + if (parent) { + subclass.prototype = parent.prototype; + klass.prototype = new subclass; + parent.subclasses.push(klass); + } + + for (var i = 0; i < properties.length; i++) + klass.addMethods(properties[i]); + + if (!klass.prototype.initialize) + klass.prototype.initialize = Prototype.emptyFunction; + + klass.prototype.constructor = klass; + return klass; + } + + function addMethods(source) { + var ancestor = this.superclass && this.superclass.prototype; + var properties = Object.keys(source); + + if (!Object.keys({ toString: true }).length) { + if (source.toString != Object.prototype.toString) + properties.push("toString"); + if (source.valueOf != Object.prototype.valueOf) + properties.push("valueOf"); + } + + for (var i = 0, length = properties.length; i < length; i++) { + var property = properties[i], value = source[property]; + if (ancestor && Object.isFunction(value) && + value.argumentNames().first() == "$super") { + var method = value; + value = (function(m) { + return function() { return ancestor[m].apply(this, arguments); }; + })(property).wrap(method); + + value.valueOf = method.valueOf.bind(method); + value.toString = method.toString.bind(method); + } + this.prototype[property] = value; + } + + return this; + } + + return { + create: create, + Methods: { + addMethods: addMethods + } + }; +})(); +(function() { + + var _toString = Object.prototype.toString; + + function extend(destination, source) { + for (var property in source) + destination[property] = source[property]; + return destination; + } + + function inspect(object) { + try { + if (isUndefined(object)) return 'undefined'; + if (object === null) return 'null'; + return object.inspect ? object.inspect() : String(object); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } + } + + function toJSON(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 (isElement(object)) return; + + var results = []; + for (var property in object) { + var value = toJSON(object[property]); + if (!isUndefined(value)) + results.push(property.toJSON() + ': ' + value); + } + + return '{' + results.join(', ') + '}'; + } + + function toQueryString(object) { + return $H(object).toQueryString(); + } + + function toHTML(object) { + return object && object.toHTML ? object.toHTML() : String.interpret(object); + } + + function keys(object) { + var results = []; + for (var property in object) + results.push(property); + return results; + } + + function values(object) { + var results = []; + for (var property in object) + results.push(object[property]); + return results; + } + + function clone(object) { + return extend({ }, object); + } + + function isElement(object) { + return !!(object && object.nodeType == 1); + } + + function isArray(object) { + return _toString.call(object) == "[object Array]"; + } + + + function isHash(object) { + return object instanceof Hash; + } + + function isFunction(object) { + return typeof object === "function"; + } + + function isString(object) { + return _toString.call(object) == "[object String]"; + } + + function isNumber(object) { + return _toString.call(object) == "[object Number]"; + } + + function isUndefined(object) { + return typeof object === "undefined"; + } + + extend(Object, { + extend: extend, + inspect: inspect, + toJSON: toJSON, + toQueryString: toQueryString, + toHTML: toHTML, + keys: keys, + values: values, + clone: clone, + isElement: isElement, + isArray: isArray, + isHash: isHash, + isFunction: isFunction, + isString: isString, + isNumber: isNumber, + isUndefined: isUndefined + }); +})(); +Object.extend(Function.prototype, (function() { + var slice = Array.prototype.slice; + + function update(array, args) { + var arrayLength = array.length, length = args.length; + while (length--) array[arrayLength + length] = args[length]; + return array; + } + + function merge(array, args) { + array = slice.call(array, 0); + return update(array, args); + } + + function argumentNames() { + var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] + .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') + .replace(/\s+/g, '').split(','); + return names.length == 1 && !names[0] ? [] : names; + } + + function bind(context) { + if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; + var __method = this, args = slice.call(arguments, 1); + return function() { + var a = merge(args, arguments); + return __method.apply(context, a); + } + } + + function bindAsEventListener(context) { + var __method = this, args = slice.call(arguments, 1); + return function(event) { + var a = update([event || window.event], args); + return __method.apply(context, a); + } + } + + function curry() { + if (!arguments.length) return this; + var __method = this, args = slice.call(arguments, 0); + return function() { + var a = merge(args, arguments); + return __method.apply(this, a); + } + } + + function delay(timeout) { + var __method = this, args = slice.call(arguments, 1); + timeout = timeout * 1000 + return window.setTimeout(function() { + return __method.apply(__method, args); + }, timeout); + } + + function defer() { + var args = update([0.01], arguments); + return this.delay.apply(this, args); + } + + function wrap(wrapper) { + var __method = this; + return function() { + var a = update([__method.bind(this)], arguments); + return wrapper.apply(this, a); + } + } + + function methodize() { + if (this._methodized) return this._methodized; + var __method = this; + return this._methodized = function() { + var a = update([this], arguments); + return __method.apply(null, a); + }; + } + + return { + argumentNames: argumentNames, + bind: bind, + bindAsEventListener: bindAsEventListener, + curry: curry, + delay: delay, + defer: defer, + wrap: wrap, + methodize: methodize + } +})()); + + +Date.prototype.toJSON = function() { + return '"' + this.getUTCFullYear() + '-' + + (this.getUTCMonth() + 1).toPaddedString(2) + '-' + + this.getUTCDate().toPaddedString(2) + 'T' + + this.getUTCHours().toPaddedString(2) + ':' + + this.getUTCMinutes().toPaddedString(2) + ':' + + this.getUTCSeconds().toPaddedString(2) + 'Z"'; +}; + + RegExp.prototype.match = RegExp.prototype.test; RegExp.escape = function(str) { return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); }; - -/*--------------------------------------------------------------------------*/ - var PeriodicalExecuter = Class.create({ initialize: function(callback, frequency) { this.callback = callback; @@ -319,8 +395,10 @@ var PeriodicalExecuter = Class.create({ try { this.currentlyExecuting = true; this.execute(); - } finally { this.currentlyExecuting = false; + } catch(e) { + this.currentlyExecuting = false; + throw e; } } } @@ -339,10 +417,25 @@ Object.extend(String, { } }); -Object.extend(String.prototype, { - gsub: function(pattern, replacement) { +Object.extend(String.prototype, (function() { + + function prepareReplacement(replacement) { + if (Object.isFunction(replacement)) return replacement; + var template = new Template(replacement); + return function(match) { return template.evaluate(match) }; + } + + function gsub(pattern, replacement) { var result = '', source = this, match; - replacement = arguments.callee.prepareReplacement(replacement); + replacement = prepareReplacement(replacement); + + if (Object.isString(pattern)) + pattern = RegExp.escape(pattern); + + if (!(pattern.length || pattern.source)) { + replacement = replacement(''); + return replacement + source.split('').join(replacement) + replacement; + } while (source.length > 0) { if (match = source.match(pattern)) { @@ -354,69 +447,64 @@ Object.extend(String.prototype, { } } return result; - }, + } - sub: function(pattern, replacement, count) { - replacement = this.gsub.prepareReplacement(replacement); + function sub(pattern, replacement, count) { + replacement = prepareReplacement(replacement); count = Object.isUndefined(count) ? 1 : count; return this.gsub(pattern, function(match) { if (--count < 0) return match[0]; return replacement(match); }); - }, + } - scan: function(pattern, iterator) { + function scan(pattern, iterator) { this.gsub(pattern, iterator); return String(this); - }, + } - truncate: function(length, truncation) { + function truncate(length, truncation) { length = length || 30; truncation = Object.isUndefined(truncation) ? '...' : truncation; return this.length > length ? this.slice(0, length - truncation.length) + truncation : String(this); - }, + } - strip: function() { + function strip() { return this.replace(/^\s+/, '').replace(/\s+$/, ''); - }, + } - stripTags: function() { - return this.replace(/<\/?[^>]+>/gi, ''); - }, + function stripTags() { + return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); + } - stripScripts: function() { + function stripScripts() { return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); - }, + } - extractScripts: function() { + function extractScripts() { var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); return (this.match(matchAll) || []).map(function(scriptTag) { return (scriptTag.match(matchOne) || ['', ''])[1]; }); - }, + } - evalScripts: function() { + function evalScripts() { return this.extractScripts().map(function(script) { return eval(script) }); - }, + } - escapeHTML: function() { - var self = arguments.callee; - self.text.data = this; - return self.div.innerHTML; - }, + function escapeHTML() { + return this.replace(/&/g,'&').replace(//g,'>'); + } - 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) : ''; - }, + function unescapeHTML() { + return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); + } - toQueryParams: function(separator) { + + function toQueryParams(separator) { var match = this.strip().match(/([^?#]*)(#.*)?$/); if (!match) return { }; @@ -434,22 +522,22 @@ Object.extend(String.prototype, { } return hash; }); - }, + } - toArray: function() { + function toArray() { return this.split(''); - }, + } - succ: function() { + function succ() { return this.slice(0, this.length - 1) + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); - }, + } - times: function(count) { + function times(count) { return count < 1 ? '' : new Array(count + 1).join(this); - }, + } - camelize: function() { + function camelize() { var parts = this.split('-'), len = parts.length; if (len == 1) return parts[0]; @@ -461,101 +549,117 @@ Object.extend(String.prototype, { camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); return camelized; - }, + } - capitalize: function() { + function capitalize() { return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); - }, + } - underscore: function() { - return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); - }, + function underscore() { + return this.replace(/::/g, '/') + .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') + .replace(/([a-z\d])([A-Z])/g, '$1_$2') + .replace(/-/g, '_') + .toLowerCase(); + } - dasherize: function() { - return this.gsub(/_/,'-'); - }, + function dasherize() { + return this.replace(/_/g, '-'); + } - inspect: function(useDoubleQuotes) { - var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { - var character = String.specialChar[match[0]]; - return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); + function inspect(useDoubleQuotes) { + var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) { + if (character in String.specialChar) { + return String.specialChar[character]; + } + return '\\u00' + character.charCodeAt().toPaddedString(2, 16); }); if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; return "'" + escapedString.replace(/'/g, '\\\'') + "'"; - }, + } - toJSON: function() { + function toJSON() { return this.inspect(true); - }, + } - unfilterJSON: function(filter) { - return this.sub(filter || Prototype.JSONFilter, '#{1}'); - }, + function unfilterJSON(filter) { + return this.replace(filter || Prototype.JSONFilter, '$1'); + } - isJSON: function() { + function isJSON() { var str = this; if (str.blank()) return false; str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); - }, + } - evalJSON: function(sanitize) { + function evalJSON(sanitize) { var json = this.unfilterJSON(); try { if (!sanitize || json.isJSON()) return eval('(' + json + ')'); } catch (e) { } throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); - }, + } - include: function(pattern) { + function include(pattern) { return this.indexOf(pattern) > -1; - }, + } - startsWith: function(pattern) { + function startsWith(pattern) { return this.indexOf(pattern) === 0; - }, + } - endsWith: function(pattern) { + function endsWith(pattern) { var d = this.length - pattern.length; return d >= 0 && this.lastIndexOf(pattern) === d; - }, + } - empty: function() { + function empty() { return this == ''; - }, + } - blank: function() { + function blank() { return /^\s*$/.test(this); - }, + } - interpolate: function(object, pattern) { + function interpolate(object, pattern) { return new Template(this, pattern).evaluate(object); } -}); -if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { - escapeHTML: function() { - return this.replace(/&/g,'&').replace(//g,'>'); - }, - unescapeHTML: function() { - return this.stripTags().replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); - } -}); - -String.prototype.gsub.prepareReplacement = function(replacement) { - if (Object.isFunction(replacement)) return replacement; - var template = new Template(replacement); - return function(match) { return template.evaluate(match) }; -}; - -String.prototype.parseQuery = String.prototype.toQueryParams; - -Object.extend(String.prototype.escapeHTML, { - div: document.createElement('div'), - text: document.createTextNode('') -}); - -String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text); + return { + gsub: gsub, + sub: sub, + scan: scan, + truncate: truncate, + strip: String.prototype.trim ? String.prototype.trim : strip, + stripTags: stripTags, + stripScripts: stripScripts, + extractScripts: extractScripts, + evalScripts: evalScripts, + escapeHTML: escapeHTML, + unescapeHTML: unescapeHTML, + toQueryParams: toQueryParams, + parseQuery: toQueryParams, + toArray: toArray, + succ: succ, + times: times, + camelize: camelize, + capitalize: capitalize, + underscore: underscore, + dasherize: dasherize, + inspect: inspect, + toJSON: toJSON, + unfilterJSON: unfilterJSON, + isJSON: isJSON, + evalJSON: evalJSON, + include: include, + startsWith: startsWith, + endsWith: endsWith, + empty: empty, + blank: blank, + interpolate: interpolate + }; +})()); var Template = Class.create({ initialize: function(template, pattern) { @@ -564,11 +668,11 @@ var Template = Class.create({ }, evaluate: function(object) { - if (Object.isFunction(object.toTemplateReplacements)) + if (object && Object.isFunction(object.toTemplateReplacements)) object = object.toTemplateReplacements(); return this.template.gsub(this.pattern, function(match) { - if (object == null) return ''; + if (object == null) return (match[1] + ''); var before = match[1] || ''; if (before == '\\') return match[2]; @@ -579,7 +683,7 @@ var Template = Class.create({ if (match == null) return before; while (match != null) { - var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; + var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1]; ctx = ctx[comp]; if (null == ctx || '' == match[3]) break; expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); @@ -594,8 +698,8 @@ Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; var $break = { }; -var Enumerable = { - each: function(iterator, context) { +var Enumerable = (function() { + function each(iterator, context) { var index = 0; try { this._each(function(value) { @@ -605,17 +709,17 @@ var Enumerable = { if (e != $break) throw e; } return this; - }, + } - eachSlice: function(number, iterator, context) { + function eachSlice(number, iterator, context) { var index = -number, slices = [], array = this.toArray(); if (number < 1) return array; while ((index += number) < array.length) slices.push(array.slice(index, index+number)); return slices.collect(iterator, context); - }, + } - all: function(iterator, context) { + function all(iterator, context) { iterator = iterator || Prototype.K; var result = true; this.each(function(value, index) { @@ -623,9 +727,9 @@ var Enumerable = { if (!result) throw $break; }); return result; - }, + } - any: function(iterator, context) { + function any(iterator, context) { iterator = iterator || Prototype.K; var result = false; this.each(function(value, index) { @@ -633,18 +737,18 @@ var Enumerable = { throw $break; }); return result; - }, + } - collect: function(iterator, context) { + function collect(iterator, context) { iterator = iterator || Prototype.K; var results = []; this.each(function(value, index) { results.push(iterator.call(context, value, index)); }); return results; - }, + } - detect: function(iterator, context) { + function detect(iterator, context) { var result; this.each(function(value, index) { if (iterator.call(context, value, index)) { @@ -653,32 +757,32 @@ var Enumerable = { } }); return result; - }, + } - findAll: function(iterator, context) { + function findAll(iterator, context) { var results = []; this.each(function(value, index) { if (iterator.call(context, value, index)) results.push(value); }); return results; - }, + } - grep: function(filter, iterator, context) { + function grep(filter, iterator, context) { iterator = iterator || Prototype.K; var results = []; if (Object.isString(filter)) - filter = new RegExp(filter); + filter = new RegExp(RegExp.escape(filter)); this.each(function(value, index) { if (filter.match(value)) results.push(iterator.call(context, value, index)); }); return results; - }, + } - include: function(object) { + function include(object) { if (Object.isFunction(this.indexOf)) if (this.indexOf(object) != -1) return true; @@ -690,31 +794,31 @@ var Enumerable = { } }); return found; - }, + } - inGroupsOf: function(number, fillWith) { + function inGroupsOf(number, fillWith) { fillWith = Object.isUndefined(fillWith) ? null : fillWith; return this.eachSlice(number, function(slice) { while(slice.length < number) slice.push(fillWith); return slice; }); - }, + } - inject: function(memo, iterator, context) { + function inject(memo, iterator, context) { this.each(function(value, index) { memo = iterator.call(context, memo, value, index); }); return memo; - }, + } - invoke: function(method) { + function invoke(method) { var args = $A(arguments).slice(1); return this.map(function(value) { return value[method].apply(value, args); }); - }, + } - max: function(iterator, context) { + function max(iterator, context) { iterator = iterator || Prototype.K; var result; this.each(function(value, index) { @@ -723,9 +827,9 @@ var Enumerable = { result = value; }); return result; - }, + } - min: function(iterator, context) { + function min(iterator, context) { iterator = iterator || Prototype.K; var result; this.each(function(value, index) { @@ -734,9 +838,9 @@ var Enumerable = { result = value; }); return result; - }, + } - partition: function(iterator, context) { + function partition(iterator, context) { iterator = iterator || Prototype.K; var trues = [], falses = []; this.each(function(value, index) { @@ -744,26 +848,26 @@ var Enumerable = { trues : falses).push(value); }); return [trues, falses]; - }, + } - pluck: function(property) { + function pluck(property) { var results = []; this.each(function(value) { results.push(value[property]); }); return results; - }, + } - reject: function(iterator, context) { + function reject(iterator, context) { var results = []; this.each(function(value, index) { if (!iterator.call(context, value, index)) results.push(value); }); return results; - }, + } - sortBy: function(iterator, context) { + function sortBy(iterator, context) { return this.map(function(value, index) { return { value: value, @@ -773,13 +877,13 @@ var Enumerable = { var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; }).pluck('value'); - }, + } - toArray: function() { + function toArray() { return this.map(); - }, + } - zip: function() { + function zip() { var iterator = Prototype.K, args = $A(arguments); if (Object.isFunction(args.last())) iterator = args.pop(); @@ -788,336 +892,423 @@ var Enumerable = { return this.map(function(value, index) { return iterator(collections.pluck(index)); }); - }, + } - size: function() { + function size() { return this.toArray().length; - }, + } - inspect: function() { + function inspect() { return '#'; } -}; -Object.extend(Enumerable, { - map: Enumerable.collect, - find: Enumerable.detect, - select: Enumerable.findAll, - filter: Enumerable.findAll, - member: Enumerable.include, - entries: Enumerable.toArray, - every: Enumerable.all, - some: Enumerable.any -}); + + + + + + + + + return { + each: each, + eachSlice: eachSlice, + all: all, + every: all, + any: any, + some: any, + collect: collect, + map: collect, + detect: detect, + findAll: findAll, + select: findAll, + filter: findAll, + grep: grep, + include: include, + member: include, + inGroupsOf: inGroupsOf, + inject: inject, + invoke: invoke, + max: max, + min: min, + partition: partition, + pluck: pluck, + reject: reject, + sortBy: sortBy, + toArray: toArray, + entries: toArray, + zip: zip, + size: size, + inspect: inspect, + find: detect + }; +})(); function $A(iterable) { if (!iterable) return []; - if (iterable.toArray) return iterable.toArray(); + if ('toArray' in Object(iterable)) return iterable.toArray(); var length = iterable.length || 0, results = new Array(length); while (length--) results[length] = iterable[length]; return results; } -if (Prototype.Browser.WebKit) { - $A = function(iterable) { - if (!iterable) return []; - // In Safari, only use the `toArray` method if it's not a NodeList. - // A NodeList is a function, has an function `item` property, and a numeric - // `length` property. Adapted from Google Doctype. - if (!(typeof iterable === 'function' && typeof iterable.length === - 'number' && typeof iterable.item === 'function') && iterable.toArray) - return iterable.toArray(); - var length = iterable.length || 0, results = new Array(length); - while (length--) results[length] = iterable[length]; - return results; - }; -} - -Array.from = $A; - -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, 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; - }); - }, - - flatten: function() { - return this.inject([], function(array, value) { - return array.concat(Object.isArray(value) ? - value.flatten() : [value]); - }); - }, - - without: function() { - var values = $A(arguments); - return this.select(function(value) { - return !values.include(value); - }); - }, - - 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(', ') + ']'; - } -}); - -// use native browser JS 1.6 implementation if available -if (Object.isFunction(Array.prototype.forEach)) - Array.prototype._each = Array.prototype.forEach; - -if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) { - i || (i = 0); - var length = this.length; - if (i < 0) i = length + i; - for (; i < length; i++) - if (this[i] === item) return i; - return -1; -}; - -if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) { - i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; - var n = this.slice(0, i).reverse().indexOf(item); - return (n < 0) ? n : i - n - 1; -}; - -Array.prototype.toArray = Array.prototype.clone; - function $w(string) { if (!Object.isString(string)) return []; string = string.strip(); return string ? string.split(/\s+/) : []; } -if (Prototype.Browser.Opera){ - Array.prototype.concat = function() { - var array = []; - for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); +Array.from = $A; + + +(function() { + var arrayProto = Array.prototype, + slice = arrayProto.slice, + _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available + + function each(iterator) { + for (var i = 0, length = this.length; i < length; i++) + iterator(this[i]); + } + if (!_each) _each = each; + + function clear() { + this.length = 0; + return this; + } + + function first() { + return this[0]; + } + + function last() { + return this[this.length - 1]; + } + + function compact() { + return this.select(function(value) { + return value != null; + }); + } + + function flatten() { + return this.inject([], function(array, value) { + if (Object.isArray(value)) + return array.concat(value.flatten()); + array.push(value); + return array; + }); + } + + function without() { + var values = slice.call(arguments, 0); + return this.select(function(value) { + return !values.include(value); + }); + } + + function reverse(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + } + + function uniq(sorted) { + return this.inject([], function(array, value, index) { + if (0 == index || (sorted ? array.last() != value : !array.include(value))) + array.push(value); + return array; + }); + } + + function intersect(array) { + return this.uniq().findAll(function(item) { + return array.detect(function(value) { return item === value }); + }); + } + + + function clone() { + return slice.call(this, 0); + } + + function size() { + return this.length; + } + + function inspect() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + } + + function toJSON() { + var results = []; + this.each(function(object) { + var value = Object.toJSON(object); + if (!Object.isUndefined(value)) results.push(value); + }); + return '[' + results.join(', ') + ']'; + } + + function indexOf(item, i) { + i || (i = 0); + var length = this.length; + if (i < 0) i = length + i; + for (; i < length; i++) + if (this[i] === item) return i; + return -1; + } + + function lastIndexOf(item, i) { + i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; + var n = this.slice(0, i).reverse().indexOf(item); + return (n < 0) ? n : i - n - 1; + } + + function concat() { + var array = slice.call(this, 0), item; for (var i = 0, length = arguments.length; i < length; i++) { - if (Object.isArray(arguments[i])) { - for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) - array.push(arguments[i][j]); + item = arguments[i]; + if (Object.isArray(item) && !('callee' in item)) { + for (var j = 0, arrayLength = item.length; j < arrayLength; j++) + array.push(item[j]); } else { - array.push(arguments[i]); + array.push(item); } } return array; - }; -} -Object.extend(Number.prototype, { - toColorPart: function() { - return this.toPaddedString(2, 16); - }, - - succ: function() { - return this + 1; - }, - - times: function(iterator, context) { - $R(0, this, true).each(iterator, context); - return this; - }, - - 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'; } -}); -$w('abs round ceil floor').each(function(method){ - Number.prototype[method] = Math[method].methodize(); -}); + Object.extend(arrayProto, Enumerable); + + if (!arrayProto._reverse) + arrayProto._reverse = arrayProto.reverse; + + Object.extend(arrayProto, { + _each: _each, + clear: clear, + first: first, + last: last, + compact: compact, + flatten: flatten, + without: without, + reverse: reverse, + uniq: uniq, + intersect: intersect, + clone: clone, + toArray: clone, + size: size, + inspect: inspect, + toJSON: toJSON + }); + + var CONCAT_ARGUMENTS_BUGGY = (function() { + return [].concat(arguments)[0][0] !== 1; + })(1,2) + + if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; + + if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; + if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; +})(); function $H(object) { return new Hash(object); }; var Hash = Class.create(Enumerable, (function() { + function initialize(object) { + this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); + } + + function _each(iterator) { + for (var key in this._object) { + var value = this._object[key], pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + } + + function set(key, value) { + return this._object[key] = value; + } + + function get(key) { + if (this._object[key] !== Object.prototype[key]) + return this._object[key]; + } + + function unset(key) { + var value = this._object[key]; + delete this._object[key]; + return value; + } + + function toObject() { + return Object.clone(this._object); + } + + function keys() { + return this.pluck('key'); + } + + function values() { + return this.pluck('value'); + } + + function index(value) { + var match = this.detect(function(pair) { + return pair.value === value; + }); + return match && match.key; + } + + function merge(object) { + return this.clone().update(object); + } + + function update(object) { + return new Hash(object).inject(this, function(result, pair) { + result.set(pair.key, pair.value); + return result; + }); + } function toQueryPair(key, value) { if (Object.isUndefined(value)) return key; return key + '=' + encodeURIComponent(String.interpret(value)); } - return { - initialize: function(object) { - this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); - }, + function toQueryString() { + return this.inject([], function(results, pair) { + var key = encodeURIComponent(pair.key), values = pair.value; - _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; - }, - - get: function(key) { - // simulating poorly supported hasOwnProperty - if (this._object[key] !== Object.prototype[key]) - return this._object[key]; - }, - - unset: function(key) { - var value = this._object[key]; - delete this._object[key]; - return value; - }, - - toObject: function() { - return Object.clone(this._object); - }, - - keys: function() { - return this.pluck('key'); - }, - - values: function() { - return this.pluck('value'); - }, - - index: function(value) { - var match = this.detect(function(pair) { - return pair.value === value; - }); - return match && match.key; - }, - - merge: function(object) { - return this.clone().update(object); - }, - - update: function(object) { - return new Hash(object).inject(this, function(result, pair) { - result.set(pair.key, pair.value); - return result; - }); - }, - - toQueryString: function() { - return this.inject([], function(results, pair) { - var key = encodeURIComponent(pair.key), values = pair.value; - - if (values && typeof values == 'object') { - if (Object.isArray(values)) - return results.concat(values.map(toQueryPair.curry(key))); - } else results.push(toQueryPair(key, values)); - return results; - }).join('&'); - }, - - inspect: function() { - return '#'; - }, - - toJSON: function() { - return Object.toJSON(this.toObject()); - }, - - clone: function() { - return new Hash(this); - } + if (values && typeof values == 'object') { + if (Object.isArray(values)) + return results.concat(values.map(toQueryPair.curry(key))); + } else results.push(toQueryPair(key, values)); + return results; + }).join('&'); } + + function inspect() { + return '#'; + } + + function toJSON() { + return Object.toJSON(this.toObject()); + } + + function clone() { + return new Hash(this); + } + + return { + initialize: initialize, + _each: _each, + set: set, + get: get, + unset: unset, + toObject: toObject, + toTemplateReplacements: toObject, + keys: keys, + values: values, + index: index, + merge: merge, + update: update, + toQueryString: toQueryString, + inspect: inspect, + toJSON: toJSON, + clone: clone + }; })()); -Hash.prototype.toTemplateReplacements = Hash.prototype.toObject; Hash.from = $H; -var ObjectRange = Class.create(Enumerable, { - initialize: function(start, end, exclusive) { +Object.extend(Number.prototype, (function() { + function toColorPart() { + return this.toPaddedString(2, 16); + } + + function succ() { + return this + 1; + } + + function times(iterator, context) { + $R(0, this, true).each(iterator, context); + return this; + } + + function toPaddedString(length, radix) { + var string = this.toString(radix || 10); + return '0'.times(length - string.length) + string; + } + + function toJSON() { + return isFinite(this) ? this.toString() : 'null'; + } + + function abs() { + return Math.abs(this); + } + + function round() { + return Math.round(this); + } + + function ceil() { + return Math.ceil(this); + } + + function floor() { + return Math.floor(this); + } + + return { + toColorPart: toColorPart, + succ: succ, + times: times, + toPaddedString: toPaddedString, + toJSON: toJSON, + abs: abs, + round: round, + ceil: ceil, + floor: floor + }; +})()); + +function $R(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var ObjectRange = Class.create(Enumerable, (function() { + function initialize(start, end, exclusive) { this.start = start; this.end = end; this.exclusive = exclusive; - }, + } - _each: function(iterator) { + function _each(iterator) { var value = this.start; while (this.include(value)) { iterator(value); value = value.succ(); } - }, + } - include: function(value) { + function include(value) { if (value < this.start) return false; if (this.exclusive) return value < this.end; return value <= this.end; } -}); -var $R = function(start, end, exclusive) { - return new ObjectRange(start, end, exclusive); -}; + return { + initialize: initialize, + _each: _each, + include: include + }; +})()); + + var Ajax = { getTransport: function() { @@ -1164,7 +1355,6 @@ Ajax.Responders.register({ onCreate: function() { Ajax.activeRequestCount++ }, onComplete: function() { Ajax.activeRequestCount-- } }); - Ajax.Base = Class.create({ initialize: function(options) { this.options = { @@ -1186,7 +1376,6 @@ Ajax.Base = Class.create({ this.options.parameters = this.options.parameters.toObject(); } }); - Ajax.Request = Class.create(Ajax.Base, { _complete: false, @@ -1202,7 +1391,6 @@ Ajax.Request = Class.create(Ajax.Base, { var params = Object.clone(this.options.parameters); if (!['get', 'post'].include(this.method)) { - // simulate other verbs over post params['_method'] = this.method; this.method = 'post'; } @@ -1210,7 +1398,6 @@ Ajax.Request = Class.create(Ajax.Base, { this.parameters = params; 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)) @@ -1269,7 +1456,6 @@ Ajax.Request = Class.create(Ajax.Base, { headers['Connection'] = 'close'; } - // user-defined headers if (typeof this.options.requestHeaders == 'object') { var extras = this.options.requestHeaders; @@ -1323,7 +1509,6 @@ Ajax.Request = Class.create(Ajax.Base, { } if (state == 'Complete') { - // avoid memory leak in MSIE: clean up this.transport.onreadystatechange = Prototype.emptyFunction; } }, @@ -1340,7 +1525,7 @@ Ajax.Request = Class.create(Ajax.Base, { getHeader: function(name) { try { return this.transport.getResponseHeader(name) || null; - } catch (e) { return null } + } catch (e) { return null; } }, evalResponse: function() { @@ -1360,6 +1545,13 @@ Ajax.Request = Class.create(Ajax.Base, { Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + + + + + + + Ajax.Response = Class.create({ initialize: function(request){ this.request = request; @@ -1381,6 +1573,7 @@ Ajax.Response = Class.create({ }, status: 0, + statusText: '', getStatus: Ajax.Request.prototype.getStatus, @@ -1510,6 +1703,9 @@ Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { 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++) @@ -1537,7 +1733,6 @@ if (Prototype.BrowserFeatures.XPath) { if (!window.Node) var Node = { }; if (!Node.ELEMENT_NODE) { - // DOM level 2 ECMAScript Language Binding Object.extend(Node, { ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, @@ -1554,13 +1749,30 @@ if (!Node.ELEMENT_NODE) { }); } -(function() { - var element = this.Element; - this.Element = function(tagName, attributes) { + +(function(global) { + + var SETATTRIBUTE_IGNORES_NAME = (function(){ + var elForm = document.createElement("form"); + var elInput = document.createElement("input"); + var root = document.documentElement; + elInput.setAttribute("name", "test"); + elForm.appendChild(elInput); + root.appendChild(elForm); + var isBuggy = elForm.elements + ? (typeof elForm.elements.test == "undefined") + : null; + root.removeChild(elForm); + elForm = elInput = null; + return isBuggy; + })(); + + var element = global.Element; + global.Element = function(tagName, attributes) { attributes = attributes || { }; tagName = tagName.toLowerCase(); var cache = Element.cache; - if (Prototype.Browser.IE && attributes.name) { + if (SETATTRIBUTE_IGNORES_NAME && attributes.name) { tagName = '<' + tagName + ' name="' + attributes.name + '">'; delete attributes.name; return Element.writeAttribute(document.createElement(tagName), attributes); @@ -1568,11 +1780,12 @@ if (!Node.ELEMENT_NODE) { if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); }; - Object.extend(this.Element, element || { }); - if (element) this.Element.prototype = element.prototype; -}).call(window); + Object.extend(global.Element, element || { }); + if (element) global.Element.prototype = element.prototype; +})(this); Element.cache = { }; +Element.idCounter = 1; Element.Methods = { visible: function(element) { @@ -1585,6 +1798,7 @@ Element.Methods = { return element; }, + hide: function(element) { element = $(element); element.style.display = 'none'; @@ -1603,15 +1817,89 @@ Element.Methods = { 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; - }, + update: (function(){ + + var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ + var el = document.createElement("select"), + isBuggy = true; + el.innerHTML = ""; + if (el.options && el.options[0]) { + isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; + } + el = null; + return isBuggy; + })(); + + var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ + try { + var el = document.createElement("table"); + if (el && el.tBodies) { + el.innerHTML = "test"; + var isBuggy = typeof el.tBodies[0] == "undefined"; + el = null; + return isBuggy; + } + } catch (e) { + return true; + } + })(); + + var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { + var s = document.createElement("script"), + isBuggy = false; + try { + s.appendChild(document.createTextNode("")); + isBuggy = !s.firstChild || + s.firstChild && s.firstChild.nodeType !== 3; + } catch (e) { + isBuggy = true; + } + s = null; + return isBuggy; + })(); + + function update(element, content) { + element = $(element); + + if (content && content.toElement) + content = content.toElement(); + + if (Object.isElement(content)) + return element.update().insert(content); + + content = Object.toHTML(content); + + var tagName = element.tagName.toUpperCase(); + + if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { + element.text = content; + return element; + } + + if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) { + if (tagName in Element._insertionTranslations.tags) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } + Element._getContentFromAnonymousElement(tagName, content.stripScripts()) + .each(function(node) { + element.appendChild(node) + }); + } + else { + element.innerHTML = content.stripScripts(); + } + } + else { + element.innerHTML = content.stripScripts(); + } + + content.evalScripts.bind(content).defer(); + return element; + } + + return update; + })(), replace: function(element, content) { element = $(element); @@ -1696,11 +1984,11 @@ Element.Methods = { }, ancestors: function(element) { - return $(element).recursivelyCollect('parentNode'); + return Element.recursivelyCollect(element, 'parentNode'); }, descendants: function(element) { - return $(element).select("*"); + return Element.select(element, "*"); }, firstDescendant: function(element) { @@ -1717,16 +2005,17 @@ Element.Methods = { }, previousSiblings: function(element) { - return $(element).recursivelyCollect('previousSibling'); + return Element.recursivelyCollect(element, 'previousSibling'); }, nextSiblings: function(element) { - return $(element).recursivelyCollect('nextSibling'); + return Element.recursivelyCollect(element, 'nextSibling'); }, siblings: function(element) { element = $(element); - return element.previousSiblings().reverse().concat(element.nextSiblings()); + return Element.previousSiblings(element).reverse() + .concat(Element.nextSiblings(element)); }, match: function(element, selector) { @@ -1738,22 +2027,22 @@ Element.Methods = { up: function(element, expression, index) { element = $(element); if (arguments.length == 1) return $(element.parentNode); - var ancestors = element.ancestors(); + var ancestors = Element.ancestors(element); 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] : + if (arguments.length == 1) return Element.firstDescendant(element); + return Object.isNumber(expression) ? Element.descendants(element)[expression] : Element.select(element, expression)[index || 0]; }, previous: function(element, expression, index) { element = $(element); if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); - var previousSiblings = element.previousSiblings(); + var previousSiblings = Element.previousSiblings(element); return Object.isNumber(expression) ? previousSiblings[expression] : Selector.findElement(previousSiblings, expression, index); }, @@ -1761,27 +2050,28 @@ Element.Methods = { next: function(element, expression, index) { element = $(element); if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); - var nextSiblings = element.nextSiblings(); + var nextSiblings = Element.nextSiblings(element); return Object.isNumber(expression) ? nextSiblings[expression] : Selector.findElement(nextSiblings, expression, index); }, - select: function() { - var args = $A(arguments), element = $(args.shift()); + + select: function(element) { + var args = Array.prototype.slice.call(arguments, 1); return Selector.findChildElements(element, args); }, - adjacent: function() { - var args = $A(arguments), element = $(args.shift()); + adjacent: function(element) { + var args = Array.prototype.slice.call(arguments, 1); return Selector.findChildElements(element.parentNode, args).without(element); }, identify: function(element) { element = $(element); - var id = element.readAttribute('id'), self = arguments.callee; + var id = Element.readAttribute(element, 'id'); if (id) return id; - do { id = 'anonymous_element_' + self.counter++ } while ($(id)); - element.writeAttribute('id', id); + do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id)); + Element.writeAttribute(element, 'id', id); return id; }, @@ -1820,11 +2110,11 @@ Element.Methods = { }, getHeight: function(element) { - return $(element).getDimensions().height; + return Element.getDimensions(element).height; }, getWidth: function(element) { - return $(element).getDimensions().width; + return Element.getDimensions(element).width; }, classNames: function(element) { @@ -1840,7 +2130,7 @@ Element.Methods = { addClassName: function(element, className) { if (!(element = $(element))) return; - if (!element.hasClassName(className)) + if (!Element.hasClassName(element, className)) element.className += (element.className ? ' ' : '') + className; return element; }, @@ -1854,11 +2144,10 @@ Element.Methods = { toggleClassName: function(element, className) { if (!(element = $(element))) return; - return element[element.hasClassName(className) ? - 'removeClassName' : 'addClassName'](className); + return Element[Element.hasClassName(element, className) ? + 'removeClassName' : 'addClassName'](element, className); }, - // removes whitespace-only text node children cleanWhitespace: function(element) { element = $(element); var node = element.firstChild; @@ -1892,7 +2181,7 @@ Element.Methods = { scrollTo: function(element) { element = $(element); - var pos = element.cumulativeOffset(); + var pos = Element.cumulativeOffset(element); window.scrollTo(pos[0], pos[1]); return element; }, @@ -1940,18 +2229,17 @@ Element.Methods = { getDimensions: function(element) { element = $(element); - var display = element.getStyle('display'); + var display = Element.getStyle(element, 'display'); if (display != 'none' && display != null) // Safari bug return {width: element.offsetWidth, height: element.offsetHeight}; - // 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'; + if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari + els.position = 'absolute'; els.display = 'block'; var originalWidth = element.clientWidth; var originalHeight = element.clientHeight; @@ -1967,8 +2255,6 @@ Element.Methods = { if (pos == 'static' || !pos) { element._madePositioned = true; element.style.position = 'relative'; - // Opera returns the offset relative to the positioning context, when an - // element is position relative but top and left have not been defined if (Prototype.Browser.Opera) { element.style.top = 0; element.style.left = 0; @@ -2034,10 +2320,9 @@ Element.Methods = { absolutize: function(element) { element = $(element); - if (element.getStyle('position') == 'absolute') return element; - // Position.prepare(); // To be done manually by Scripty when it needs it. + if (Element.getStyle(element, 'position') == 'absolute') return element; - var offsets = element.positionedOffset(); + var offsets = Element.positionedOffset(element); var top = offsets[1]; var left = offsets[0]; var width = element.clientWidth; @@ -2058,8 +2343,7 @@ Element.Methods = { relativize: function(element) { element = $(element); - if (element.getStyle('position') == 'relative') return element; - // Position.prepare(); // To be done manually by Scripty when it needs it. + if (Element.getStyle(element, 'position') == 'relative') return element; element.style.position = 'relative'; var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); @@ -2101,7 +2385,6 @@ Element.Methods = { valueT += element.offsetTop || 0; valueL += element.offsetLeft || 0; - // Safari fix if (element.offsetParent == document.body && Element.getStyle(element, 'position') == 'absolute') break; @@ -2128,28 +2411,22 @@ Element.Methods = { offsetLeft: 0 }, arguments[2] || { }); - // find page position of source source = $(source); - var p = source.viewportOffset(); + var p = Element.viewportOffset(source); - // find coordinate system to use element = $(element); var delta = [0, 0]; var parent = null; - // delta [0,0] will do fine with position: fixed elements, - // position:absolute needs offsetParent deltas if (Element.getStyle(element, 'position') == 'absolute') { - parent = element.getOffsetParent(); - delta = parent.viewportOffset(); + parent = Element.getOffsetParent(element); + delta = Element.viewportOffset(parent); } - // correct by body offsets (fixes Safari) if (parent == document.body) { delta[0] -= document.body.offsetLeft; delta[1] -= document.body.offsetTop; } - // set position if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; if (options.setWidth) element.style.width = source.offsetWidth + 'px'; @@ -2158,10 +2435,9 @@ Element.Methods = { } }; -Element.Methods.identify.counter = 1; - Object.extend(Element.Methods, { getElementsBySelector: Element.Methods.select, + childElements: Element.Methods.immediateDescendants }); @@ -2182,11 +2458,8 @@ if (Prototype.Browser.Opera) { case 'left': case 'top': case 'right': case 'bottom': if (proceed(element, 'position') === 'static') return null; case 'height': case 'width': - // returns '0px' for hidden elements; we want it to return null if (!Element.visible(element)) return null; - // returns the border-box dimensions rather than the content-box - // dimensions, so we subtract padding and borders from the value var dim = parseInt(proceed(element, style), 10); if (dim !== element['offset' + style.capitalize()]) @@ -2219,12 +2492,9 @@ if (Prototype.Browser.Opera) { } else if (Prototype.Browser.IE) { - // IE doesn't report offsets correctly for static elements, so we change them - // to "relative" to get the values, then change them back. Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( function(proceed, element) { element = $(element); - // IE throws an error if element is not in document try { element.offsetParent } catch(e) { return $(document.body) } var position = element.getStyle('position'); @@ -2244,8 +2514,6 @@ else if (Prototype.Browser.IE) { catch(e) { return Element._returnOffset(0,0) } var position = element.getStyle('position'); if (position !== 'static') return proceed(element); - // Trigger hasLayout on the offset parent so that IE6 reports - // accurate offsetTop and offsetLeft values for position: fixed. var offsetParent = element.getOffsetParent(); if (offsetParent && offsetParent.getStyle('position') === 'fixed') offsetParent.setStyle({ zoom: 1 }); @@ -2306,36 +2574,92 @@ else if (Prototype.Browser.IE) { return element; }; - Element._attributeTranslations = { - read: { - names: { - 'class': 'className', - 'for': 'htmlFor' - }, - values: { - _getAttr: function(element, attribute) { - return element.getAttribute(attribute, 2); + Element._attributeTranslations = (function(){ + + var classProp = 'className'; + var forProp = 'for'; + + var el = document.createElement('div'); + + el.setAttribute(classProp, 'x'); + + if (el.className !== 'x') { + el.setAttribute('class', 'x'); + if (el.className === 'x') { + classProp = 'class'; + } + } + el = null; + + el = document.createElement('label'); + el.setAttribute(forProp, 'x'); + if (el.htmlFor !== 'x') { + el.setAttribute('htmlFor', 'x'); + if (el.htmlFor === 'x') { + forProp = 'htmlFor'; + } + } + el = null; + + return { + read: { + names: { + 'class': classProp, + 'className': classProp, + 'for': forProp, + 'htmlFor': forProp }, - _getAttrNode: function(element, attribute) { - var node = element.getAttributeNode(attribute); - return node ? node.value : ""; - }, - _getEv: function(element, attribute) { - attribute = element.getAttribute(attribute); - return attribute ? attribute.toString().slice(23, -2) : null; - }, - _flag: function(element, attribute) { - return $(element).hasAttribute(attribute) ? attribute : null; - }, - style: function(element) { - return element.style.cssText.toLowerCase(); - }, - title: function(element) { - return element.title; + values: { + _getAttr: function(element, attribute) { + return element.getAttribute(attribute); + }, + _getAttr2: function(element, attribute) { + return element.getAttribute(attribute, 2); + }, + _getAttrNode: function(element, attribute) { + var node = element.getAttributeNode(attribute); + return node ? node.value : ""; + }, + _getEv: (function(){ + + var el = document.createElement('div'); + el.onclick = Prototype.emptyFunction; + var value = el.getAttribute('onclick'); + var f; + + if (String(value).indexOf('{') > -1) { + f = function(element, attribute) { + attribute = element.getAttribute(attribute); + if (!attribute) return null; + attribute = attribute.toString(); + attribute = attribute.split('{')[1]; + attribute = attribute.split('}')[0]; + return attribute.strip(); + }; + } + else if (value === '') { + f = function(element, attribute) { + attribute = element.getAttribute(attribute); + if (!attribute) return null; + return attribute.strip(); + }; + } + el = null; + return f; + })(), + _flag: function(element, attribute) { + return $(element).hasAttribute(attribute) ? attribute : null; + }, + style: function(element) { + return element.style.cssText.toLowerCase(); + }, + title: function(element) { + return element.title; + } } } } - }; + })(); Element._attributeTranslations.write = { names: Object.extend({ @@ -2363,8 +2687,8 @@ else if (Prototype.Browser.IE) { (function(v) { Object.extend(v, { - href: v._getAttr, - src: v._getAttr, + href: v._getAttr2, + src: v._getAttr2, type: v._getAttr, action: v._getAttrNode, disabled: v._flag, @@ -2391,6 +2715,26 @@ else if (Prototype.Browser.IE) { onchange: v._getEv }); })(Element._attributeTranslations.read.values); + + if (Prototype.BrowserFeatures.ElementExtensions) { + (function() { + function _descendants(element) { + var nodes = element.getElementsByTagName('*'), results = []; + for (var i = 0, node; node = nodes[i]; i++) + if (node.tagName !== "!") // Filter out comment nodes. + results.push(node); + return results; + } + + Element.Methods.down = function(element, expression, index) { + element = $(element); + if (arguments.length == 1) return element.firstDescendant(); + return Object.isNumber(expression) ? _descendants(element)[expression] : + Element.select(element, expression)[index || 0]; + } + })(); + } + } else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { @@ -2420,9 +2764,6 @@ else if (Prototype.Browser.WebKit) { return element; }; - // Safari returns margins on body which is incorrect if the child is absolutely - // positioned. For performance reasons, redefine Element#cumulativeOffset for - // KHTML/WebKit only. Element.Methods.cumulativeOffset = function(element) { var valueT = 0, valueL = 0; do { @@ -2438,30 +2779,7 @@ else if (Prototype.Browser.WebKit) { }; } -if (Prototype.Browser.IE || Prototype.Browser.Opera) { - // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements - Element.Methods.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); - var tagName = element.tagName.toUpperCase(); - - if (tagName in Element._insertionTranslations.tags) { - $A(element.childNodes).each(function(node) { element.removeChild(node) }); - Element._getContentFromAnonymousElement(tagName, content.stripScripts()) - .each(function(node) { element.appendChild(node) }); - } - else element.innerHTML = content.stripScripts(); - - content.evalScripts.bind(content).defer(); - return element; - }; -} - -if ('outerHTML' in document.createElement('div')) { +if ('outerHTML' in document.documentElement) { Element.Methods.replace = function(element, content) { element = $(element); @@ -2529,12 +2847,13 @@ Element._insertionTranslations = { }; (function() { - Object.extend(this.tags, { - THEAD: this.tags.TBODY, - TFOOT: this.tags.TBODY, - TH: this.tags.TD + var tags = Element._insertionTranslations.tags; + Object.extend(tags, { + THEAD: tags.TBODY, + TFOOT: tags.TBODY, + TH: tags.TD }); -}).call(Element._insertionTranslations); +})(); Element.Methods.Simulated = { hasAttribute: function(element, attribute) { @@ -2548,41 +2867,81 @@ Element.Methods.ByTag = { }; Object.extend(Element, Element.Methods); -if (!Prototype.BrowserFeatures.ElementExtensions && - document.createElement('div')['__proto__']) { - window.HTMLElement = { }; - window.HTMLElement.prototype = document.createElement('div')['__proto__']; - Prototype.BrowserFeatures.ElementExtensions = true; -} +(function(div) { + + if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) { + window.HTMLElement = { }; + window.HTMLElement.prototype = div['__proto__']; + Prototype.BrowserFeatures.ElementExtensions = true; + } + + div = null; + +})(document.createElement('div')) Element.extend = (function() { - if (Prototype.BrowserFeatures.SpecificElementExtensions) + + function checkDeficiency(tagName) { + if (typeof window.Element != 'undefined') { + var proto = window.Element.prototype; + if (proto) { + var id = '_' + (Math.random()+'').slice(2); + var el = document.createElement(tagName); + proto[id] = 'x'; + var isBuggy = (el[id] !== 'x'); + delete proto[id]; + el = null; + return isBuggy; + } + } + return false; + } + + function extendElementWith(element, methods) { + for (var property in methods) { + var value = methods[property]; + if (Object.isFunction(value) && !(property in element)) + element[property] = value.methodize(); + } + } + + var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object'); + + if (Prototype.BrowserFeatures.SpecificElementExtensions) { + if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) { + return function(element) { + if (element && typeof element._extendedByPrototype == 'undefined') { + var t = element.tagName; + if (t && (/^(?:object|applet|embed)$/i.test(t))) { + extendElementWith(element, Element.Methods); + extendElementWith(element, Element.Methods.Simulated); + extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]); + } + } + return element; + } + } return Prototype.K; + } var Methods = { }, ByTag = Element.Methods.ByTag; var extend = Object.extend(function(element) { - if (!element || element._extendedByPrototype || + if (!element || typeof element._extendedByPrototype != 'undefined' || element.nodeType != 1 || element == window) return element; var methods = Object.clone(Methods), - tagName = element.tagName.toUpperCase(), property, value; + tagName = element.tagName.toUpperCase(); - // extend methods for specific tags if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); - for (property in methods) { - value = methods[property]; - if (Object.isFunction(value) && !(property in element)) - element[property] = value.methodize(); - } + extendElementWith(element, methods); element._extendedByPrototype = Prototype.emptyFunction; return element; }, { refresh: function() { - // extend methods for all tags (Safari doesn't need this) if (!Prototype.BrowserFeatures.ElementExtensions) { Object.extend(Methods, Element.Methods); Object.extend(Methods, Element.Methods.Simulated); @@ -2661,14 +3020,18 @@ Element.addMethods = function(methods) { klass = 'HTML' + tagName.capitalize() + 'Element'; if (window[klass]) return window[klass]; - window[klass] = { }; - window[klass].prototype = document.createElement(tagName)['__proto__']; - return window[klass]; + var element = document.createElement(tagName); + var proto = element['__proto__'] || element.constructor.prototype; + element = null; + return proto; } + var elementPrototype = window.HTMLElement ? HTMLElement.prototype : + Element.prototype; + if (F.ElementExtensions) { - copy(Element.Methods, HTMLElement.prototype); - copy(Element.Methods.Simulated, HTMLElement.prototype, true); + copy(Element.Methods, elementPrototype); + copy(Element.Methods.Simulated, elementPrototype, true); } if (F.SpecificElementExtensions) { @@ -2686,38 +3049,109 @@ Element.addMethods = function(methods) { Element.cache = { }; }; + document.viewport = { + getDimensions: function() { - var dimensions = { }, B = Prototype.Browser; - $w('width height').each(function(d) { - var D = d.capitalize(); - if (B.WebKit && !document.evaluate) { - // Safari <3.0 needs self.innerWidth/Height - dimensions[d] = self['inner' + D]; - } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) { - // Opera <9.5 needs document.body.clientWidth/Height - dimensions[d] = document.body['client' + D] - } else { - dimensions[d] = document.documentElement['client' + D]; - } - }); - return dimensions; - }, - - getWidth: function() { - return this.getDimensions().width; - }, - - getHeight: function() { - return this.getDimensions().height; + return { width: this.getWidth(), height: this.getHeight() }; }, getScrollOffsets: function() { return Element._returnOffset( window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, - window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); + window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); } }; + +(function(viewport) { + var B = Prototype.Browser, doc = document, element, property = {}; + + function getRootElement() { + if (B.WebKit && !doc.evaluate) + return document; + + if (B.Opera && window.parseFloat(window.opera.version()) < 9.5) + return document.body; + + return document.documentElement; + } + + function define(D) { + if (!element) element = getRootElement(); + + property[D] = 'client' + D; + + viewport['get' + D] = function() { return element[property[D]] }; + return viewport['get' + D](); + } + + viewport.getWidth = define.curry('Width'); + + viewport.getHeight = define.curry('Height'); +})(document.viewport); + + +Element.Storage = { + UID: 1 +}; + +Element.addMethods({ + getStorage: function(element) { + if (!(element = $(element))) return; + + var uid; + if (element === window) { + uid = 0; + } else { + if (typeof element._prototypeUID === "undefined") + element._prototypeUID = [Element.Storage.UID++]; + uid = element._prototypeUID[0]; + } + + if (!Element.Storage[uid]) + Element.Storage[uid] = $H(); + + return Element.Storage[uid]; + }, + + store: function(element, key, value) { + if (!(element = $(element))) return; + + if (arguments.length === 2) { + Element.getStorage(element).update(key); + } else { + Element.getStorage(element).set(key, value); + } + + return element; + }, + + retrieve: function(element, key, defaultValue) { + if (!(element = $(element))) return; + var hash = Element.getStorage(element), value = hash.get(key); + + if (Object.isUndefined(value)) { + hash.set(key, defaultValue); + value = defaultValue; + } + + return value; + }, + + clone: function(element, deep) { + if (!(element = $(element))) return; + var clone = element.cloneNode(deep); + clone._prototypeUID = void 0; + if (deep) { + var descendants = Element.select(clone, '*'), + i = descendants.length; + while (i--) { + descendants[i]._prototypeUID = void 0; + } + } + return Element.extend(clone); + } +}); /* Portions of the Selector class are derived from Jack Slocum's DomQuery, * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style * license. Please see http://www.yui-ext.com/ for more information. */ @@ -2738,31 +3172,52 @@ var Selector = Class.create({ }, - shouldUseXPath: function() { - if (!Prototype.BrowserFeatures.XPath) return false; + shouldUseXPath: (function() { - var e = this.expression; + var IS_DESCENDANT_SELECTOR_BUGGY = (function(){ + var isBuggy = false; + if (document.evaluate && window.XPathResult) { + var el = document.createElement('div'); + el.innerHTML = '
'; - // Safari 3 chokes on :*-of-type and :empty - if (Prototype.Browser.WebKit && - (e.include("-of-type") || e.include(":empty"))) - return false; + var xpath = ".//*[local-name()='ul' or local-name()='UL']" + + "//*[local-name()='li' or local-name()='LI']"; - // XPath can't do namespaced attributes, nor can it read - // the "checked" property from DOM nodes - if ((/(\[[\w-]*?:|:checked)/).test(e)) - return false; + var result = document.evaluate(xpath, el, null, + XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - return true; - }, + isBuggy = (result.snapshotLength !== 2); + el = null; + } + return isBuggy; + })(); + + return function() { + if (!Prototype.BrowserFeatures.XPath) return false; + + var e = this.expression; + + if (Prototype.Browser.WebKit && + (e.include("-of-type") || e.include(":empty"))) + return false; + + if ((/(\[[\w-]*?:|:checked)/).test(e)) + return false; + + if (IS_DESCENDANT_SELECTOR_BUGGY) return false; + + return true; + } + + })(), shouldUseSelectorsAPI: function() { if (!Prototype.BrowserFeatures.SelectorsAPI) return false; + if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false; + if (!Selector._div) Selector._div = new Element('div'); - // Make sure the browser treats the selector as valid. Test on an - // isolated element to minimize cost of this check. try { Selector._div.querySelector(this.expression); } catch(e) { @@ -2774,7 +3229,7 @@ var Selector = Class.create({ compileMatcher: function() { var e = this.expression, ps = Selector.patterns, h = Selector.handlers, - c = Selector.criteria, le, p, m; + c = Selector.criteria, le, p, m, len = ps.length, name; if (Selector._cache[e]) { this.matcher = Selector._cache[e]; @@ -2786,11 +3241,12 @@ var Selector = Class.create({ while (e && le != e && (/\S/).test(e)) { le = e; - for (var i in ps) { - p = ps[i]; + for (var i = 0; i\s*/, - adjacent: /^\s*\+\s*/, - descendant: /^\s/, + patterns: [ + { name: 'laterSibling', re: /^\s*~\s*/ }, + { name: 'child', re: /^\s*>\s*/ }, + { name: 'adjacent', re: /^\s*\+\s*/ }, + { name: 'descendant', re: /^\s/ }, - // selectors follow - tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, - id: /^#([\w\-\*]+)(\b|$)/, - className: /^\.([\w\-\*]+)(\b|$)/, - pseudo: -/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/, - attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/, - attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ - }, + { name: 'tagName', re: /^\s*(\*|[\w\-]+)(\b|$)?/ }, + { name: 'id', re: /^#([\w\-\*]+)(\b|$)/ }, + { name: 'className', re: /^\.([\w\-\*]+)(\b|$)/ }, + { name: 'pseudo', re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ }, + { name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ }, + { name: 'attr', re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ } + ], - // for Selector.match and Element#match assertions: { tagName: function(element, matches) { return matches[1].toUpperCase() == element.tagName.toUpperCase(); @@ -3064,15 +3527,12 @@ Object.extend(Selector, { }, handlers: { - // UTILITY FUNCTIONS - // joins two collections concat: function(a, b) { for (var i = 0, node; node = b[i]; i++) a.push(node); return a; }, - // marks an array of nodes for counting mark: function(nodes) { var _true = Prototype.emptyFunction; for (var i = 0, node; node = nodes[i]; i++) @@ -3080,15 +3540,32 @@ Object.extend(Selector, { return nodes; }, - unmark: function(nodes) { - for (var i = 0, node; node = nodes[i]; i++) - node._countedByPrototype = undefined; - return nodes; - }, + unmark: (function(){ + + var PROPERTIES_ATTRIBUTES_MAP = (function(){ + var el = document.createElement('div'), + isBuggy = false, + propName = '_countedByPrototype', + value = 'x' + el[propName] = value; + isBuggy = (el.getAttribute(propName) === value); + el = null; + return isBuggy; + })(); + + return PROPERTIES_ATTRIBUTES_MAP ? + function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node.removeAttribute('_countedByPrototype'); + return nodes; + } : + function(nodes) { + for (var i = 0, node; node = nodes[i]; i++) + node._countedByPrototype = void 0; + return nodes; + } + })(), - // mark each child node with its position (for nth calls) - // "ofType" flag indicates whether we're indexing for nth-of-type - // rather than nth-child index: function(parentNode, reverse, ofType) { parentNode._countedByPrototype = Prototype.emptyFunction; if (reverse) { @@ -3102,19 +3579,17 @@ Object.extend(Selector, { } }, - // filters out duplicates and extends all nodes unique: function(nodes) { if (nodes.length == 0) return nodes; var results = [], n; for (var i = 0, l = nodes.length; i < l; i++) - if (!(n = nodes[i])._countedByPrototype) { + if (typeof (n = nodes[i])._countedByPrototype == 'undefined') { n._countedByPrototype = Prototype.emptyFunction; results.push(Element.extend(n)); } return Selector.handlers.unmark(results); }, - // COMBINATOR FUNCTIONS descendant: function(nodes) { var h = Selector.handlers; for (var i = 0, results = [], node; node = nodes[i]; i++) @@ -3158,13 +3633,11 @@ Object.extend(Selector, { return null; }, - // TOKEN FUNCTIONS tagName: function(nodes, root, tagName, combinator) { var uTagName = tagName.toUpperCase(); var results = [], h = Selector.handlers; if (nodes) { if (combinator) { - // fastlane for ordinary descendant combinators if (combinator == "descendant") { for (var i = 0, node; node = nodes[i]; i++) h.concat(results, node.getElementsByTagName(tagName)); @@ -3180,8 +3653,19 @@ Object.extend(Selector, { id: function(nodes, root, id, combinator) { var targetNode = $(id), h = Selector.handlers; - if (!targetNode) return []; - if (!nodes && root == document) return [targetNode]; + + if (root == document) { + if (!targetNode) return []; + if (!nodes) return [targetNode]; + } else { + if (!root.sourceIndex || root.sourceIndex < 1) { + var nodes = root.getElementsByTagName('*'); + for (var j = 0, node; node = nodes[j]; j++) { + if (node.id === id) return [node]; + } + } + } + if (nodes) { if (combinator) { if (combinator == 'child') { @@ -3293,7 +3777,6 @@ Object.extend(Selector, { return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); }, - // handles the an+b logic getIndices: function(a, b, total) { if (a == 0) return b > 0 ? [b] : []; return $R(1, total).inject([], function(memo, i) { @@ -3302,7 +3785,6 @@ Object.extend(Selector, { }); }, - // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type nth: function(nodes, formula, root, reverse, ofType) { if (nodes.length == 0) return []; if (formula == 'even') formula = '2n+0'; @@ -3336,7 +3818,6 @@ Object.extend(Selector, { 'empty': function(nodes, value, root) { for (var i = 0, results = [], node; node = nodes[i]; i++) { - // IE treats comments as element nodes if (node.tagName == '!' || node.firstChild) continue; results.push(node); } @@ -3379,8 +3860,6 @@ Object.extend(Selector, { '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); }, '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); }, '*=': function(nv, v) { return nv == v || nv && nv.include(v); }, - '$=': function(nv, v) { return nv.endsWith(v); }, - '*=': function(nv, v) { return nv.include(v); }, '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() + '-').include('-' + (v || "").toUpperCase() + '-'); } @@ -3423,19 +3902,10 @@ Object.extend(Selector, { if (Prototype.Browser.IE) { Object.extend(Selector.handlers, { - // IE returns comment nodes on getElementsByTagName("*"). - // Filter them out. concat: function(a, b) { for (var i = 0, node; node = b[i]; i++) if (node.tagName !== "!") a.push(node); return a; - }, - - // IE improperly serializes _countedByPrototype in (inner|outer)HTML. - unmark: function(nodes) { - for (var i = 0, node; node = nodes[i]; i++) - node.removeAttribute('_countedByPrototype'); - return nodes; } }); } @@ -3443,9 +3913,11 @@ if (Prototype.Browser.IE) { function $$() { return Selector.findChildElements(document, $A(arguments)); } + var Form = { reset: function(form) { - $(form).reset(); + form = $(form); + form.reset(); return form; }, @@ -3460,7 +3932,6 @@ var Form = { if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted && submit !== false && (!submit || key == submit) && (submitted = true)))) { if (key in result) { - // a key is already present; construct an array of values if (!Object.isArray(result[key])) result[key] = [result[key]]; result[key].push(value); } @@ -3480,13 +3951,18 @@ Form.Methods = { }, getElements: function(form) { - return $A($(form).getElementsByTagName('*')).inject([], - function(elements, child) { - if (Form.Element.Serializers[child.tagName.toLowerCase()]) - elements.push(Element.extend(child)); - return elements; - } - ); + var elements = $(form).getElementsByTagName('*'), + element, + arr = [ ], + serializers = Form.Element.Serializers; + for (var i = 0; element = elements[i]; i++) { + arr.push(element); + } + return arr.inject([], function(elements, child) { + if (serializers[child.tagName.toLowerCase()]) + elements.push(Element.extend(child)); + return elements; + }) }, getInputs: function(form, typeName, name) { @@ -3526,7 +4002,7 @@ Form.Methods = { }).sortBy(function(element) { return element.tabIndex }).first(); return firstByIndex ? firstByIndex : elements.find(function(element) { - return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); + return /^(?:input|select|textarea)$/i.test(element.tagName); }); }, @@ -3557,6 +4033,7 @@ Form.Methods = { /*--------------------------------------------------------------------------*/ + Form.Element = { focus: function(element) { $(element).focus(); @@ -3570,6 +4047,7 @@ Form.Element = { }; Form.Element.Methods = { + serialize: function(element) { element = $(element); if (!element.disabled && element.name) { @@ -3610,7 +4088,7 @@ Form.Element.Methods = { try { element.focus(); if (element.select && (element.tagName.toLowerCase() != 'input' || - !['button', 'reset', 'submit'].include(element.type))) + !(/^(?:button|reset|submit)$/i.test(element.type)))) element.select(); } catch (e) { } return element; @@ -3632,6 +4110,7 @@ Form.Element.Methods = { /*--------------------------------------------------------------------------*/ var Field = Form.Element; + var $F = Form.Element.Methods.getValue; /*--------------------------------------------------------------------------*/ @@ -3694,13 +4173,13 @@ Form.Element.Serializers = { }, optionValue: function(opt) { - // extend element because hasAttribute may not be native return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; } }; /*--------------------------------------------------------------------------*/ + Abstract.TimedObserver = Class.create(PeriodicalExecuter, { initialize: function($super, element, frequency, callback) { $super(callback, frequency); @@ -3782,354 +4261,441 @@ Form.EventObserver = Class.create(Abstract.EventObserver, { return Form.serialize(this.element); } }); -if (!window.Event) var Event = { }; +(function() { -Object.extend(Event, { - KEY_BACKSPACE: 8, - KEY_TAB: 9, - KEY_RETURN: 13, - KEY_ESC: 27, - KEY_LEFT: 37, - KEY_UP: 38, - KEY_RIGHT: 39, - KEY_DOWN: 40, - KEY_DELETE: 46, - KEY_HOME: 36, - KEY_END: 35, - KEY_PAGEUP: 33, - KEY_PAGEDOWN: 34, - KEY_INSERT: 45, + var Event = { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + KEY_HOME: 36, + KEY_END: 35, + KEY_PAGEUP: 33, + KEY_PAGEDOWN: 34, + KEY_INSERT: 45, - cache: { }, + cache: {} + }; - relatedTarget: function(event) { - var element; - switch(event.type) { - case 'mouseover': element = event.fromElement; break; - case 'mouseout': element = event.toElement; break; - default: return null; - } - return Element.extend(element); - } -}); - -Event.Methods = (function() { - var isButton; + var docEl = document.documentElement; + var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl + && 'onmouseleave' in docEl; + var _isButton; if (Prototype.Browser.IE) { var buttonMap = { 0: 1, 1: 4, 2: 2 }; - isButton = function(event, code) { - return event.button == buttonMap[code]; + _isButton = function(event, code) { + return event.button === buttonMap[code]; }; - } else if (Prototype.Browser.WebKit) { - isButton = function(event, code) { + _isButton = function(event, code) { switch (code) { case 0: return event.which == 1 && !event.metaKey; case 1: return event.which == 1 && event.metaKey; default: return false; } }; - } else { - isButton = function(event, code) { + _isButton = function(event, code) { return event.which ? (event.which === code + 1) : (event.button === code); }; } - return { - isLeftClick: function(event) { return isButton(event, 0) }, - isMiddleClick: function(event) { return isButton(event, 1) }, - isRightClick: function(event) { return isButton(event, 2) }, + function isLeftClick(event) { return _isButton(event, 0) } - element: function(event) { - event = Event.extend(event); + function isMiddleClick(event) { return _isButton(event, 1) } - var node = event.target, - type = event.type, - currentTarget = event.currentTarget; + function isRightClick(event) { return _isButton(event, 2) } - if (currentTarget && currentTarget.tagName) { - // Firefox screws up the "click" event when moving between radio buttons - // via arrow keys. It also screws up the "load" and "error" events on images, - // reporting the document as the target instead of the original image. - if (type === 'load' || type === 'error' || - (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' - && currentTarget.type === 'radio')) - node = currentTarget; - } - if (node.nodeType == Node.TEXT_NODE) node = node.parentNode; - return Element.extend(node); - }, + function element(event) { + event = Event.extend(event); - findElement: function(event, expression) { - var element = Event.element(event); - if (!expression) return element; - var elements = [element].concat(element.ancestors()); - return Selector.findElement(elements, expression, 0); - }, + var node = event.target, type = event.type, + currentTarget = event.currentTarget; - pointer: function(event) { - var docElement = document.documentElement, - body = document.body || { scrollLeft: 0, scrollTop: 0 }; - return { - x: event.pageX || (event.clientX + - (docElement.scrollLeft || body.scrollLeft) - - (docElement.clientLeft || 0)), - y: event.pageY || (event.clientY + - (docElement.scrollTop || body.scrollTop) - - (docElement.clientTop || 0)) - }; - }, - - pointerX: function(event) { return Event.pointer(event).x }, - pointerY: function(event) { return Event.pointer(event).y }, - - stop: function(event) { - Event.extend(event); - event.preventDefault(); - event.stopPropagation(); - event.stopped = true; + if (currentTarget && currentTarget.tagName) { + if (type === 'load' || type === 'error' || + (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' + && currentTarget.type === 'radio')) + node = currentTarget; } - }; -})(); -Event.extend = (function() { + if (node.nodeType == Node.TEXT_NODE) + node = node.parentNode; + + return Element.extend(node); + } + + function findElement(event, expression) { + var element = Event.element(event); + if (!expression) return element; + var elements = [element].concat(element.ancestors()); + return Selector.findElement(elements, expression, 0); + } + + function pointer(event) { + return { x: pointerX(event), y: pointerY(event) }; + } + + function pointerX(event) { + var docElement = document.documentElement, + body = document.body || { scrollLeft: 0 }; + + return event.pageX || (event.clientX + + (docElement.scrollLeft || body.scrollLeft) - + (docElement.clientLeft || 0)); + } + + function pointerY(event) { + var docElement = document.documentElement, + body = document.body || { scrollTop: 0 }; + + return event.pageY || (event.clientY + + (docElement.scrollTop || body.scrollTop) - + (docElement.clientTop || 0)); + } + + + function stop(event) { + Event.extend(event); + event.preventDefault(); + event.stopPropagation(); + + event.stopped = true; + } + + Event.Methods = { + isLeftClick: isLeftClick, + isMiddleClick: isMiddleClick, + isRightClick: isRightClick, + + element: element, + findElement: findElement, + + pointer: pointer, + pointerX: pointerX, + pointerY: pointerY, + + stop: stop + }; + + var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { m[name] = Event.Methods[name].methodize(); return m; }); if (Prototype.Browser.IE) { + function _relatedTarget(event) { + var element; + switch (event.type) { + case 'mouseover': element = event.fromElement; break; + case 'mouseout': element = event.toElement; break; + default: return null; + } + return Element.extend(element); + } + Object.extend(methods, { stopPropagation: function() { this.cancelBubble = true }, preventDefault: function() { this.returnValue = false }, - inspect: function() { return "[object Event]" } + inspect: function() { return '[object Event]' } }); - return function(event) { + Event.extend = function(event, element) { if (!event) return false; if (event._extendedByPrototype) return event; event._extendedByPrototype = Prototype.emptyFunction; var pointer = Event.pointer(event); + Object.extend(event, { - target: event.srcElement, - relatedTarget: Event.relatedTarget(event), + target: event.srcElement || element, + relatedTarget: _relatedTarget(event), pageX: pointer.x, pageY: pointer.y }); + return Object.extend(event, methods); }; - } else { - Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__']; + Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__; Object.extend(Event.prototype, methods); - return Prototype.K; - } -})(); - -Object.extend(Event, (function() { - var cache = Event.cache; - - function getEventID(element) { - if (element._prototypeEventID) return element._prototypeEventID[0]; - arguments.callee.id = arguments.callee.id || 1; - return element._prototypeEventID = [++arguments.callee.id]; + Event.extend = Prototype.K; } - function getDOMEventName(eventName) { - if (eventName && eventName.include(':')) return "dataavailable"; - return eventName; - } + function _createResponder(element, eventName, handler) { + var registry = Element.retrieve(element, 'prototype_event_registry'); - function getCacheForID(id) { - return cache[id] = cache[id] || { }; - } + if (Object.isUndefined(registry)) { + CACHE.push(element); + registry = Element.retrieve(element, 'prototype_event_registry', $H()); + } - function getWrappersForEventName(id, eventName) { - var c = getCacheForID(id); - return c[eventName] = c[eventName] || []; - } + var respondersForEvent = registry.get(eventName); + if (Object.isUndefined(respondersForEvent)) { + respondersForEvent = []; + registry.set(eventName, respondersForEvent); + } - function createWrapper(element, eventName, handler) { - var id = getEventID(element); - var c = getWrappersForEventName(id, eventName); - if (c.pluck("handler").include(handler)) return false; + if (respondersForEvent.pluck('handler').include(handler)) return false; - var wrapper = function(event) { - if (!Event || !Event.extend || - (event.eventName && event.eventName != eventName)) + var responder; + if (eventName.include(":")) { + responder = function(event) { + if (Object.isUndefined(event.eventName)) return false; - Event.extend(event); - handler.call(element, event); - }; + if (event.eventName !== eventName) + return false; - wrapper.handler = handler; - c.push(wrapper); - return wrapper; - } + Event.extend(event, element); + handler.call(element, event); + }; + } else { + if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && + (eventName === "mouseenter" || eventName === "mouseleave")) { + if (eventName === "mouseenter" || eventName === "mouseleave") { + responder = function(event) { + Event.extend(event, element); - function findWrapper(id, eventName, handler) { - var c = getWrappersForEventName(id, eventName); - return c.find(function(wrapper) { return wrapper.handler == handler }); - } + var parent = event.relatedTarget; + while (parent && parent !== element) { + try { parent = parent.parentNode; } + catch(e) { parent = element; } + } - function destroyWrapper(id, eventName, handler) { - var c = getCacheForID(id); - if (!c[eventName]) return false; - c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); - } + if (parent === element) return; - function destroyCache() { - for (var id in cache) - for (var eventName in cache[id]) - cache[id][eventName] = null; - } - - - // Internet Explorer needs to remove event handlers on page unload - // in order to avoid memory leaks. - if (window.attachEvent) { - window.attachEvent("onunload", destroyCache); - } - - // Safari has a dummy event handler on page unload so that it won't - // use its bfcache. Safari <= 3.1 has an issue with restoring the "document" - // object when page is returned to via the back button using its bfcache. - if (Prototype.Browser.WebKit) { - window.addEventListener('unload', Prototype.emptyFunction, false); - } - - return { - observe: function(element, eventName, handler) { - element = $(element); - var name = getDOMEventName(eventName); - - var wrapper = createWrapper(element, eventName, handler); - if (!wrapper) return element; - - if (element.addEventListener) { - element.addEventListener(name, wrapper, false); + handler.call(element, event); + }; + } } else { - element.attachEvent("on" + name, wrapper); + responder = function(event) { + Event.extend(event, element); + handler.call(element, event); + }; } - - return element; - }, - - stopObserving: function(element, eventName, handler) { - element = $(element); - var id = getEventID(element), name = getDOMEventName(eventName); - - if (!handler && eventName) { - getWrappersForEventName(id, eventName).each(function(wrapper) { - element.stopObserving(eventName, wrapper.handler); - }); - return element; - - } else if (!eventName) { - Object.keys(getCacheForID(id)).each(function(eventName) { - element.stopObserving(eventName); - }); - return element; - } - - var wrapper = findWrapper(id, eventName, handler); - if (!wrapper) return element; - - if (element.removeEventListener) { - element.removeEventListener(name, wrapper, false); - } else { - element.detachEvent("on" + name, wrapper); - } - - destroyWrapper(id, eventName, handler); - - return element; - }, - - fire: function(element, eventName, memo) { - element = $(element); - if (element == document && document.createEvent && !element.dispatchEvent) - element = document.documentElement; - - var event; - if (document.createEvent) { - event = document.createEvent("HTMLEvents"); - event.initEvent("dataavailable", true, true); - } else { - event = document.createEventObject(); - event.eventType = "ondataavailable"; - } - - event.eventName = eventName; - event.memo = memo || { }; - - if (document.createEvent) { - element.dispatchEvent(event); - } else { - element.fireEvent(event.eventType, event); - } - - return Event.extend(event); } - }; -})()); -Object.extend(Event, Event.Methods); + responder.handler = handler; + respondersForEvent.push(responder); + return responder; + } -Element.addMethods({ - fire: Event.fire, - observe: Event.observe, - stopObserving: Event.stopObserving -}); + function _destroyCache() { + for (var i = 0, length = CACHE.length; i < length; i++) { + Event.stopObserving(CACHE[i]); + CACHE[i] = null; + } + } -Object.extend(document, { - fire: Element.Methods.fire.methodize(), - observe: Element.Methods.observe.methodize(), - stopObserving: Element.Methods.stopObserving.methodize(), - loaded: false -}); + var CACHE = []; + + if (Prototype.Browser.IE) + window.attachEvent('onunload', _destroyCache); + + if (Prototype.Browser.WebKit) + window.addEventListener('unload', Prototype.emptyFunction, false); + + + var _getDOMEventName = Prototype.K; + + if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) { + _getDOMEventName = function(eventName) { + var translations = { mouseenter: "mouseover", mouseleave: "mouseout" }; + return eventName in translations ? translations[eventName] : eventName; + }; + } + + function observe(element, eventName, handler) { + element = $(element); + + var responder = _createResponder(element, eventName, handler); + + if (!responder) return element; + + if (eventName.include(':')) { + if (element.addEventListener) + element.addEventListener("dataavailable", responder, false); + else { + element.attachEvent("ondataavailable", responder); + element.attachEvent("onfilterchange", responder); + } + } else { + var actualEventName = _getDOMEventName(eventName); + + if (element.addEventListener) + element.addEventListener(actualEventName, responder, false); + else + element.attachEvent("on" + actualEventName, responder); + } + + return element; + } + + function stopObserving(element, eventName, handler) { + element = $(element); + + var registry = Element.retrieve(element, 'prototype_event_registry'); + + if (Object.isUndefined(registry)) return element; + + if (eventName && !handler) { + var responders = registry.get(eventName); + + if (Object.isUndefined(responders)) return element; + + responders.each( function(r) { + Element.stopObserving(element, eventName, r.handler); + }); + return element; + } else if (!eventName) { + registry.each( function(pair) { + var eventName = pair.key, responders = pair.value; + + responders.each( function(r) { + Element.stopObserving(element, eventName, r.handler); + }); + }); + return element; + } + + var responders = registry.get(eventName); + + if (!responders) return; + + var responder = responders.find( function(r) { return r.handler === handler; }); + if (!responder) return element; + + var actualEventName = _getDOMEventName(eventName); + + if (eventName.include(':')) { + if (element.removeEventListener) + element.removeEventListener("dataavailable", responder, false); + else { + element.detachEvent("ondataavailable", responder); + element.detachEvent("onfilterchange", responder); + } + } else { + if (element.removeEventListener) + element.removeEventListener(actualEventName, responder, false); + else + element.detachEvent('on' + actualEventName, responder); + } + + registry.set(eventName, responders.without(responder)); + + return element; + } + + function fire(element, eventName, memo, bubble) { + element = $(element); + + if (Object.isUndefined(bubble)) + bubble = true; + + if (element == document && document.createEvent && !element.dispatchEvent) + element = document.documentElement; + + var event; + if (document.createEvent) { + event = document.createEvent('HTMLEvents'); + event.initEvent('dataavailable', true, true); + } else { + event = document.createEventObject(); + event.eventType = bubble ? 'ondataavailable' : 'onfilterchange'; + } + + event.eventName = eventName; + event.memo = memo || { }; + + if (document.createEvent) + element.dispatchEvent(event); + else + element.fireEvent(event.eventType, event); + + return Event.extend(event); + } + + + Object.extend(Event, Event.Methods); + + Object.extend(Event, { + fire: fire, + observe: observe, + stopObserving: stopObserving + }); + + Element.addMethods({ + fire: fire, + + observe: observe, + + stopObserving: stopObserving + }); + + Object.extend(document, { + fire: fire.methodize(), + + observe: observe.methodize(), + + stopObserving: stopObserving.methodize(), + + loaded: false + }); + + if (window.Event) Object.extend(window.Event, Event); + else window.Event = Event; +})(); (function() { /* Support for the DOMContentLoaded event is based on work by Dan Webb, - Matthias Miller, Dean Edwards and John Resig. */ + Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ var timer; function fireContentLoadedEvent() { if (document.loaded) return; - if (timer) window.clearInterval(timer); - document.fire("dom:loaded"); + if (timer) window.clearTimeout(timer); document.loaded = true; + document.fire('dom:loaded'); + } + + function checkReadyState() { + if (document.readyState === 'complete') { + document.stopObserving('readystatechange', checkReadyState); + fireContentLoadedEvent(); + } + } + + function pollDoScroll() { + try { document.documentElement.doScroll('left'); } + catch(e) { + timer = pollDoScroll.defer(); + return; + } + fireContentLoadedEvent(); } if (document.addEventListener) { - if (Prototype.Browser.WebKit) { - timer = window.setInterval(function() { - if (/loaded|complete/.test(document.readyState)) - fireContentLoadedEvent(); - }, 0); - - Event.observe(window, "load", fireContentLoadedEvent); - - } else { - document.addEventListener("DOMContentLoaded", - fireContentLoadedEvent, false); - } - + document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false); } else { - document.write("