From ea00eb2ea27613491eb517be9659059696fb335b Mon Sep 17 00:00:00 2001 From: ctrlaltca <> Date: Sun, 6 Jan 2013 19:16:09 +0000 Subject: backpotder r3238, r3239 to trunk/ --- HISTORY | 2 + framework/Util/TDateTimeStamp.php | 26 +- framework/Util/TSimpleDateFormatter.php | 11 +- .../Javascripts/source/prototype-1.7/prototype.js | 4112 ++++++++++++-------- 4 files changed, 2562 insertions(+), 1589 deletions(-) diff --git a/HISTORY b/HISTORY index 6bd48091..c8290fa6 100644 --- a/HISTORY +++ b/HISTORY @@ -5,6 +5,7 @@ EHN: Issue #292 - Events should have priorities to allow event handler order to Version 3.2.1 to be released +BUG: Issue #44 - [895] SDateFormatter cannot parse date earlier than 1970 (ctrlaltca) BUG: Issue #412 - open_basedir restriction (ctrlaltca) BUG: Issue #413 - TActiveDatePicker does not fire TCallbackClientSide's events (ctrlaltca) BUG: Issue #414 - ActiveDatagrid's pager does not fire TCallbackClientSide's events (ctrlaltca) @@ -27,6 +28,7 @@ EHN: Use php's hash_hmac() when available in TSecurityManager, and permit the us EHN: Use mbstring when available in TSecurityManager to better handle multibyte text (ctrlaltca) EHN: Updated TinyMCE to 3.5.6 (ctrlaltca) CHG: Rewrite TDateTimeStamp as a wrapper to php's native DateTime and deprecate it (ctrlaltca) +CHG: Updated prototype to 1.7.1 (ctrlaltca) Version 3.2.0 Jun 25, 2012 BUG: Fixed an inconsistency in TRegularExpressionValidator diff --git a/framework/Util/TDateTimeStamp.php b/framework/Util/TDateTimeStamp.php index a7a43b3c..f5f76004 100644 --- a/framework/Util/TDateTimeStamp.php +++ b/framework/Util/TDateTimeStamp.php @@ -102,6 +102,30 @@ class TDateTimeStamp return (int) $dt->format('Z'); } + /** + * @return array an array with date info. + */ + function parseDate($txt=false) + { + if ($txt === false) return getdate(); + + $dt = new DateTime($txt); + + return array( + 'seconds' => (int) $dt->format('s'), + 'minutes' => (int) $dt->format('i'), + 'hours' => (int) $dt->format('G'), + 'mday' => (int) $dt->format('j'), + 'wday' => (int) $dt->format('w'), + 'mon' => (int) $dt->format('n'), + 'year' => (int) $dt->format('Y'), + 'yday' => (int) $dt->format('z'), + 'weekday' => $dt->format('l'), + 'month' => $dt->format('F'), + 0 => (int) $dt->format('U'), + ); + } + /** * @return array an array with date info. */ @@ -123,7 +147,7 @@ class TDateTimeStamp 'yday' => (int) $dt->format('z'), 'weekday' => $dt->format('l'), 'month' => $dt->format('F'), - 0 => (int) $d + 0 => (int) $dt->format('U'), ); } diff --git a/framework/Util/TSimpleDateFormatter.php b/framework/Util/TSimpleDateFormatter.php index 8b17048a..a1a1842a 100644 --- a/framework/Util/TSimpleDateFormatter.php +++ b/framework/Util/TSimpleDateFormatter.php @@ -173,15 +173,8 @@ class TSimpleDateFormatter */ private function getDate($value) { - if(!is_string($value)) - { - $s = Prado::createComponent('System.Util.TDateTimeStamp'); - return $s->getDate($value); - } - $date = @strtotime($value); - if($date < 0) - throw new TInvalidDataValueException('invalid_date', $value); - return @getdate($date); + $s = Prado::createComponent('System.Util.TDateTimeStamp'); + return $s->parseDate($value); } /** diff --git a/framework/Web/Javascripts/source/prototype-1.7/prototype.js b/framework/Web/Javascripts/source/prototype-1.7/prototype.js index 474b2231..37dd39ac 100644 --- a/framework/Web/Javascripts/source/prototype-1.7/prototype.js +++ b/framework/Web/Javascripts/source/prototype-1.7/prototype.js @@ -1,4 +1,4 @@ -/* Prototype JavaScript framework, version 1.7 +/* Prototype JavaScript framework, version 1.7.1 * (c) 2005-2010 Sam Stephenson * * Prototype is freely distributable under the terms of an MIT-style license. @@ -8,7 +8,7 @@ var Prototype = { - Version: '1.7', + Version: '1.7.1', Browser: (function(){ var ua = navigator.userAgent; @@ -49,7 +49,7 @@ var Prototype = { })() }, - ScriptFragment: ']*>([\\S\\s]*?)<\/script>', + ScriptFragment: ']*>([\\S\\s]*?)<\/script\\s*>', JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, emptyFunction: function() { }, @@ -59,27 +59,6 @@ var Prototype = { if (Prototype.Browser.MobileSafari) Prototype.BrowserFeatures.SpecificElementExtensions = false; - - -var Abstract = { }; - - -var Try = { - these: function() { - var returnValue; - - for (var i = 0, length = arguments.length; i < length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) { } - } - - return returnValue; - } -}; - /* Based on Alex Arnell's inheritance implementation. */ var Class = (function() { @@ -141,8 +120,13 @@ var Class = (function() { return function() { return ancestor[m].apply(this, arguments); }; })(property).wrap(method); - value.valueOf = method.valueOf.bind(method); - value.toString = method.toString.bind(method); + value.valueOf = (function(method) { + return function() { return method.valueOf.call(method); }; + })(method); + + value.toString = (function(method) { + return function() { return method.toString.call(method); }; + })(method); } this.prototype[property] = value; } @@ -160,6 +144,7 @@ var Class = (function() { (function() { var _toString = Object.prototype.toString, + _hasOwnProperty = Object.prototype.hasOwnProperty, NULL_TYPE = 'Null', UNDEFINED_TYPE = 'Undefined', BOOLEAN_TYPE = 'Boolean', @@ -177,6 +162,18 @@ var Class = (function() { JSON.stringify(0) === '0' && typeof JSON.stringify(Prototype.K) === 'undefined'; + + + var DONT_ENUMS = ['toString', 'toLocaleString', 'valueOf', + 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor']; + + var IS_DONTENUM_BUGGY = (function(){ + for (var p in { toString: 1 }) { + if (p === 'toString') return false; + } + return true; + })(); + function Type(o) { switch(o) { case null: return NULL_TYPE; @@ -213,9 +210,7 @@ var Class = (function() { } function Str(key, holder, stack) { - var value = holder[key], - type = typeof value; - + var value = holder[key]; if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') { value = value.toJSON(key); } @@ -235,7 +230,7 @@ var Class = (function() { case false: return 'false'; } - type = typeof value; + var type = typeof value; switch (type) { case 'string': return value.inspect(true); @@ -244,7 +239,9 @@ var Class = (function() { case 'object': for (var i = 0, length = stack.length; i < length; i++) { - if (stack[i] === value) { throw new TypeError(); } + if (stack[i] === value) { + throw new TypeError("Cyclic reference to '" + value + "' in object"); + } } stack.push(value); @@ -286,10 +283,17 @@ var Class = (function() { if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); } var results = []; for (var property in object) { - if (object.hasOwnProperty(property)) { + if (_hasOwnProperty.call(object, property)) results.push(property); + } + + if (IS_DONTENUM_BUGGY) { + for (var i = 0; property = DONT_ENUMS[i]; i++) { + if (_hasOwnProperty.call(object, property)) + results.push(property); } } + return results; } @@ -383,13 +387,27 @@ Object.extend(Function.prototype, (function() { return names.length == 1 && !names[0] ? [] : names; } + function bind(context) { - if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; + if (arguments.length < 2 && Object.isUndefined(arguments[0])) + return this; + + if (!Object.isFunction(this)) + throw new TypeError("The object is not callable."); + + var nop = function() {}; var __method = this, args = slice.call(arguments, 1); - return function() { - var a = merge(args, arguments); - return __method.apply(context, a); - } + + var bound = function() { + var a = merge(args, arguments), c = context; + var c = this instanceof bound ? this : context; + return __method.apply(c, a); + }; + + nop.prototype = this.prototype; + bound.prototype = new nop(); + + return bound; } function bindAsEventListener(context) { @@ -439,16 +457,20 @@ Object.extend(Function.prototype, (function() { }; } - return { + var extensions = { argumentNames: argumentNames, - bind: bind, bindAsEventListener: bindAsEventListener, curry: curry, delay: delay, defer: defer, wrap: wrap, methodize: methodize - } + }; + + if (!Function.prototype.bind) + extensions.bind = bind; + + return extensions; })()); @@ -609,7 +631,7 @@ Object.extend(String.prototype, (function() { } function evalScripts() { - return this.extractScripts().map(function(script) { return eval(script) }); + return this.extractScripts().map(function(script) { return eval(script); }); } function escapeHTML() { @@ -819,11 +841,8 @@ var $break = { }; var Enumerable = (function() { function each(iterator, context) { - var index = 0; try { - this._each(function(value) { - iterator.call(context, value, index++); - }); + this._each(iterator, context); } catch (e) { if (e != $break) throw e; } @@ -842,9 +861,9 @@ var Enumerable = (function() { iterator = iterator || Prototype.K; var result = true; this.each(function(value, index) { - result = result && !!iterator.call(context, value, index); + result = result && !!iterator.call(context, value, index, this); if (!result) throw $break; - }); + }, this); return result; } @@ -852,9 +871,9 @@ var Enumerable = (function() { iterator = iterator || Prototype.K; var result = false; this.each(function(value, index) { - if (result = !!iterator.call(context, value, index)) + if (result = !!iterator.call(context, value, index, this)) throw $break; - }); + }, this); return result; } @@ -862,28 +881,28 @@ var Enumerable = (function() { iterator = iterator || Prototype.K; var results = []; this.each(function(value, index) { - results.push(iterator.call(context, value, index)); - }); + results.push(iterator.call(context, value, index, this)); + }, this); return results; } function detect(iterator, context) { var result; this.each(function(value, index) { - if (iterator.call(context, value, index)) { + if (iterator.call(context, value, index, this)) { result = value; throw $break; } - }); + }, this); return result; } function findAll(iterator, context) { var results = []; this.each(function(value, index) { - if (iterator.call(context, value, index)) + if (iterator.call(context, value, index, this)) results.push(value); - }); + }, this); return results; } @@ -896,8 +915,8 @@ var Enumerable = (function() { this.each(function(value, index) { if (filter.match(value)) - results.push(iterator.call(context, value, index)); - }); + results.push(iterator.call(context, value, index, this)); + }, this); return results; } @@ -925,8 +944,8 @@ var Enumerable = (function() { function inject(memo, iterator, context) { this.each(function(value, index) { - memo = iterator.call(context, memo, value, index); - }); + memo = iterator.call(context, memo, value, index, this); + }, this); return memo; } @@ -941,10 +960,10 @@ var Enumerable = (function() { iterator = iterator || Prototype.K; var result; this.each(function(value, index) { - value = iterator.call(context, value, index); + value = iterator.call(context, value, index, this); if (result == null || value >= result) result = value; - }); + }, this); return result; } @@ -952,10 +971,10 @@ var Enumerable = (function() { iterator = iterator || Prototype.K; var result; this.each(function(value, index) { - value = iterator.call(context, value, index); + value = iterator.call(context, value, index, this); if (result == null || value < result) result = value; - }); + }, this); return result; } @@ -963,9 +982,9 @@ var Enumerable = (function() { iterator = iterator || Prototype.K; var trues = [], falses = []; this.each(function(value, index) { - (iterator.call(context, value, index) ? + (iterator.call(context, value, index, this) ? trues : falses).push(value); - }); + }, this); return [trues, falses]; } @@ -980,9 +999,9 @@ var Enumerable = (function() { function reject(iterator, context) { var results = []; this.each(function(value, index) { - if (!iterator.call(context, value, index)) + if (!iterator.call(context, value, index, this)) results.push(value); - }); + }, this); return results; } @@ -990,9 +1009,9 @@ var Enumerable = (function() { return this.map(function(value, index) { return { value: value, - criteria: iterator.call(context, value, index) + criteria: iterator.call(context, value, index, this) }; - }).sort(function(left, right) { + }, this).sort(function(left, right) { var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; }).pluck('value'); @@ -1142,7 +1161,7 @@ Array.from = $A; function intersect(array) { return this.uniq().findAll(function(item) { - return array.detect(function(value) { return item === value }); + return array.indexOf(item) !== -1; }); } @@ -1160,34 +1179,179 @@ Array.from = $A; } 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; + if (this == null) throw new TypeError(); + + var array = Object(this), length = array.length >>> 0; + if (length === 0) return -1; + + i = Number(i); + if (isNaN(i)) { + i = 0; + } else if (i !== 0 && isFinite(i)) { + i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i)); + } + + if (i > length) return -1; + + var k = i >= 0 ? i : Math.max(length - Math.abs(i), 0); + for (; k < length; k++) + if (k in array && array[k] === item) return k; 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; + if (this == null) throw new TypeError(); + + var array = Object(this), length = array.length >>> 0; + if (length === 0) return -1; + + if (!Object.isUndefined(i)) { + i = Number(i); + if (isNaN(i)) { + i = 0; + } else if (i !== 0 && isFinite(i)) { + i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i)); + } + } else { + i = length; + } + + var k = i >= 0 ? Math.min(i, length - 1) : + length - Math.abs(i); + + for (; k >= 0; k--) + if (k in array && array[k] === item) return k; + return -1; } - function concat() { - var array = slice.call(this, 0), item; - for (var i = 0, length = arguments.length; i < length; i++) { - item = arguments[i]; + function concat(_) { + var array = [], items = slice.call(arguments, 0), item, n = 0; + items.unshift(this); + for (var i = 0, length = items.length; i < length; i++) { + item = items[i]; if (Object.isArray(item) && !('callee' in item)) { - for (var j = 0, arrayLength = item.length; j < arrayLength; j++) - array.push(item[j]); + for (var j = 0, arrayLength = item.length; j < arrayLength; j++) { + if (j in item) array[n] = item[j]; + n++; + } } else { - array.push(item); + array[n++] = item; } } + array.length = n; return array; } + + function wrapNative(method) { + return function() { + if (arguments.length === 0) { + return method.call(this, Prototype.K); + } else if (arguments[0] === undefined) { + var args = slice.call(arguments, 1); + args.unshift(Prototype.K); + return method.apply(this, args); + } else { + return method.apply(this, arguments); + } + }; + } + + + function map(iterator) { + if (this == null) throw new TypeError(); + iterator = iterator || Prototype.K; + + var object = Object(this); + var results = [], context = arguments[1], n = 0; + + for (var i = 0, length = object.length >>> 0; i < length; i++) { + if (i in object) { + results[n] = iterator.call(context, object[i], i, object); + } + n++; + } + results.length = n; + return results; + } + + if (arrayProto.map) { + map = wrapNative(Array.prototype.map); + } + + function filter(iterator) { + if (this == null || !Object.isFunction(iterator)) + throw new TypeError(); + + var object = Object(this); + var results = [], context = arguments[1], value; + + for (var i = 0, length = object.length >>> 0; i < length; i++) { + if (i in object) { + value = object[i]; + if (iterator.call(context, value, i, object)) { + results.push(value); + } + } + } + return results; + } + + if (arrayProto.filter) { + filter = Array.prototype.filter; + } + + function some(iterator) { + if (this == null) throw new TypeError(); + iterator = iterator || Prototype.K; + var context = arguments[1]; + + var object = Object(this); + for (var i = 0, length = object.length >>> 0; i < length; i++) { + if (i in object && iterator.call(context, object[i], i, object)) { + return true; + } + } + + return false; + } + + if (arrayProto.some) { + var some = wrapNative(Array.prototype.some); + } + + + function every(iterator) { + if (this == null) throw new TypeError(); + iterator = iterator || Prototype.K; + var context = arguments[1]; + + var object = Object(this); + for (var i = 0, length = object.length >>> 0; i < length; i++) { + if (i in object && !iterator.call(context, object[i], i, object)) { + return false; + } + } + + return true; + } + + if (arrayProto.every) { + var every = wrapNative(Array.prototype.every); + } + + var _reduce = arrayProto.reduce; + function inject(memo, iterator) { + iterator = iterator || Prototype.K; + var context = arguments[2]; + return _reduce.call(this, iterator.bind(context), memo); + } + + if (!arrayProto.reduce) { + var inject = Enumerable.inject; + } + Object.extend(arrayProto, Enumerable); if (!arrayProto._reverse) @@ -1195,6 +1359,18 @@ Array.from = $A; Object.extend(arrayProto, { _each: _each, + + map: map, + collect: map, + select: filter, + filter: filter, + findAll: filter, + some: some, + any: some, + every: every, + all: every, + inject: inject, + clear: clear, first: first, last: last, @@ -1212,7 +1388,7 @@ Array.from = $A; var CONCAT_ARGUMENTS_BUGGY = (function() { return [].concat(arguments)[0][0] !== 1; - })(1,2) + })(1,2); if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; @@ -1229,12 +1405,12 @@ var Hash = Class.create(Enumerable, (function() { } - function _each(iterator) { + function _each(iterator, context) { for (var key in this._object) { var value = this._object[key], pair = [key, value]; pair.key = key; pair.value = value; - iterator(pair); + iterator.call(context, pair); } } @@ -1287,7 +1463,13 @@ var Hash = Class.create(Enumerable, (function() { function toQueryPair(key, value) { if (Object.isUndefined(value)) return key; - return key + '=' + encodeURIComponent(String.interpret(value)); + + var value = String.interpret(value); + + value = value.gsub(/(\r)?\n/, '\r\n'); + value = encodeURIComponent(value); + value = value.gsub(/%20/, '+'); + return key + '=' + value; } function toQueryString() { @@ -1397,10 +1579,10 @@ var ObjectRange = Class.create(Enumerable, (function() { this.exclusive = exclusive; } - function _each(iterator) { + function _each(iterator, context) { var value = this.start; while (this.include(value)) { - iterator(value); + iterator.call(context, value); value = value.succ(); } } @@ -1422,6 +1604,25 @@ var ObjectRange = Class.create(Enumerable, (function() { +var Abstract = { }; + + +var Try = { + these: function() { + var returnValue; + + for (var i = 0, length = arguments.length; i < length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) { } + } + + return returnValue; + } +}; + var Ajax = { getTransport: function() { return Try.these( @@ -1437,8 +1638,8 @@ var Ajax = { Ajax.Responders = { responders: [], - _each: function(iterator) { - this.responders._each(iterator); + _each: function(iterator, context) { + this.responders._each(iterator, context); }, register: function(responder) { @@ -1713,7 +1914,12 @@ Ajax.Response = Class.create({ _getHeaderJSON: function() { var json = this.getHeader('X-JSON'); if (!json) return null; - json = decodeURIComponent(escape(json)); + + try { + json = decodeURIComponent(escape(json)); + } catch(e) { + } + try { return json.evalJSON(this.request.options.sanitizeJSON || !this.request.isSameOrigin()); @@ -1814,54 +2020,51 @@ Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { } }); +(function(GLOBAL) { -function $(element) { - if (arguments.length > 1) { - for (var i = 0, elements = [], length = arguments.length; i < length; i++) - elements.push($(arguments[i])); - return elements; + var UNDEFINED; + var SLICE = Array.prototype.slice; + + var DIV = document.createElement('div'); + + + function $(element) { + if (arguments.length > 1) { + for (var i = 0, elements = [], length = arguments.length; i < length; i++) + elements.push($(arguments[i])); + return elements; + } + + if (Object.isString(element)) + element = document.getElementById(element); + return Element.extend(element); } - if (Object.isString(element)) - element = document.getElementById(element); - return Element.extend(element); -} -if (Prototype.BrowserFeatures.XPath) { - document._getElementsByXPath = function(expression, parentElement) { - var results = []; - var query = document.evaluate(expression, $(parentElement) || document, - null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - for (var i = 0, length = query.snapshotLength; i < length; i++) - results.push(Element.extend(query.snapshotItem(i))); - return results; - }; -} + GLOBAL.$ = $; -/*--------------------------------------------------------------------------*/ -if (!Node) var Node = { }; - -if (!Node.ELEMENT_NODE) { - Object.extend(Node, { - ELEMENT_NODE: 1, - ATTRIBUTE_NODE: 2, - TEXT_NODE: 3, - CDATA_SECTION_NODE: 4, - ENTITY_REFERENCE_NODE: 5, - ENTITY_NODE: 6, - PROCESSING_INSTRUCTION_NODE: 7, - COMMENT_NODE: 8, - DOCUMENT_NODE: 9, - DOCUMENT_TYPE_NODE: 10, - DOCUMENT_FRAGMENT_NODE: 11, - NOTATION_NODE: 12 - }); -} + if (!GLOBAL.Node) GLOBAL.Node = {}; + if (!GLOBAL.Node.ELEMENT_NODE) { + Object.extend(GLOBAL.Node, { + ELEMENT_NODE: 1, + ATTRIBUTE_NODE: 2, + TEXT_NODE: 3, + CDATA_SECTION_NODE: 4, + ENTITY_REFERENCE_NODE: 5, + ENTITY_NODE: 6, + PROCESSING_INSTRUCTION_NODE: 7, + COMMENT_NODE: 8, + DOCUMENT_NODE: 9, + DOCUMENT_TYPE_NODE: 10, + DOCUMENT_FRAGMENT_NODE: 11, + NOTATION_NODE: 12 + }); + } + var ELEMENT_CACHE = {}; -(function(global) { - function shouldUseCache(tagName, attributes) { + function shouldUseCreationCache(tagName, attributes) { if (tagName === 'select') return false; if ('type' in attributes) return false; return true; @@ -1877,12 +2080,11 @@ if (!Node.ELEMENT_NODE) { } })(); - var element = global.Element; - global.Element = function(tagName, attributes) { - attributes = attributes || { }; + var oldElement = GLOBAL.Element; + function Element(tagName, attributes) { + attributes = attributes || {}; tagName = tagName.toLowerCase(); - var cache = Element.cache; if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) { tagName = '<' + tagName + ' name="' + attributes.name + '">'; @@ -1890,783 +2092,854 @@ if (!Node.ELEMENT_NODE) { return Element.writeAttribute(document.createElement(tagName), attributes); } - if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); + if (!ELEMENT_CACHE[tagName]) + ELEMENT_CACHE[tagName] = Element.extend(document.createElement(tagName)); - var node = shouldUseCache(tagName, attributes) ? - cache[tagName].cloneNode(false) : document.createElement(tagName); + var node = shouldUseCreationCache(tagName, attributes) ? + ELEMENT_CACHE[tagName].cloneNode(false) : document.createElement(tagName); return Element.writeAttribute(node, attributes); - }; + } - Object.extend(global.Element, element || { }); - if (element) global.Element.prototype = element.prototype; + GLOBAL.Element = Element; -})(this); + Object.extend(GLOBAL.Element, oldElement || {}); + if (oldElement) GLOBAL.Element.prototype = oldElement.prototype; + + Element.Methods = { ByTag: {}, Simulated: {} }; + + var methods = {}; -Element.idCounter = 1; -Element.cache = { }; + var INSPECT_ATTRIBUTES = { id: 'id', className: 'class' }; + function inspect(element) { + element = $(element); + var result = '<' + element.tagName.toLowerCase(); + + var attribute, value; + for (var property in INSPECT_ATTRIBUTES) { + attribute = INSPECT_ATTRIBUTES[property]; + value = (element[property] || '').toString(); + if (value) result += ' ' + attribute + '=' + value.inspect(true); + } -Element._purgeElement = function(element) { - var uid = element._prototypeUID; - if (uid) { - Element.stopObserving(element); - element._prototypeUID = void 0; - delete Element.Storage[uid]; + return result + '>'; } -} -Element.Methods = { - visible: function(element) { - return $(element).style.display != 'none'; - }, + methods.inspect = inspect; - toggle: function(element) { + + function visible(element) { + return $(element).style.display !== 'none'; + } + + function toggle(element, bool) { element = $(element); - Element[Element.visible(element) ? 'hide' : 'show'](element); + if (Object.isUndefined(bool)) + bool = !Element.visible(element); + Element[bool ? 'show' : 'hide'](element); + return element; - }, + } - hide: function(element) { + function hide(element) { element = $(element); element.style.display = 'none'; return element; - }, + } - show: function(element) { + function show(element) { element = $(element); element.style.display = ''; return element; - }, + } + + + Object.extend(methods, { + visible: visible, + toggle: toggle, + hide: hide, + show: show + }); + - remove: function(element) { + function remove(element) { element = $(element); element.parentNode.removeChild(element); 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 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"; + 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 LINK_ELEMENT_INNERHTML_BUGGY = (function() { + try { + var el = document.createElement('div'); + el.innerHTML = ""; + var isBuggy = (el.childNodes.length === 0); el = null; return isBuggy; - })(); + } catch(e) { + return true; + } + })(); - 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 ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY || + TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY; - var LINK_ELEMENT_INNERHTML_BUGGY = (function() { - try { - var el = document.createElement('div'); - el.innerHTML = ""; - var isBuggy = (el.childNodes.length === 0); - 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; + })(); - var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY || - TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY; + function update(element, content) { + element = $(element); - 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; - })(); + var descendants = element.getElementsByTagName('*'), + i = descendants.length; + while (i--) purgeElement(descendants[i]); + if (content && content.toElement) + content = content.toElement(); - function update(element, content) { - element = $(element); - var purgeElement = Element._purgeElement; + if (Object.isElement(content)) + return element.update().insert(content); - var descendants = element.getElementsByTagName('*'), - i = descendants.length; - while (i--) purgeElement(descendants[i]); - if (content && content.toElement) - content = content.toElement(); + content = Object.toHTML(content); + var tagName = element.tagName.toUpperCase(); - if (Object.isElement(content)) - return element.update().insert(content); + if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { + element.text = content; + return element; + } - content = Object.toHTML(content); + if (ANY_INNERHTML_BUGGY) { + if (tagName in INSERTION_TRANSLATIONS.tags) { + while (element.firstChild) + element.removeChild(element.firstChild); - var tagName = element.tagName.toUpperCase(); + var nodes = getContentFromAnonymousElement(tagName, content.stripScripts()); + for (var i = 0, node; node = nodes[i]; i++) + element.appendChild(node); - if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { - element.text = content; - return element; - } + } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf(' -1) { + while (element.firstChild) + element.removeChild(element.firstChild); - if (ANY_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 if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf(' -1) { - while (element.firstChild) { - element.removeChild(element.firstChild); - } - var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), true); - nodes.each(function(node) { element.appendChild(node) }); - } - else { - element.innerHTML = content.stripScripts(); - } - } - else { + var nodes = getContentFromAnonymousElement(tagName, + content.stripScripts(), true); + + for (var i = 0, node; node = nodes[i]; i++) + element.appendChild(node); + } else { element.innerHTML = content.stripScripts(); } - - content.evalScripts.bind(content).defer(); - return element; + } else { + element.innerHTML = content.stripScripts(); } - return update; - })(), + content.evalScripts.bind(content).defer(); + return element; + } - replace: function(element, content) { + function replace(element, content) { element = $(element); - if (content && content.toElement) content = content.toElement(); - else if (!Object.isElement(content)) { + + if (content && content.toElement) { + content = content.toElement(); + } else if (!Object.isElement(content)) { content = Object.toHTML(content); var range = element.ownerDocument.createRange(); range.selectNode(element); content.evalScripts.bind(content).defer(); content = range.createContextualFragment(content.stripScripts()); } + element.parentNode.replaceChild(content, element); return element; - }, + } + + var INSERTION_TRANSLATIONS = { + before: function(element, node) { + element.parentNode.insertBefore(node, element); + }, + top: function(element, node) { + element.insertBefore(node, element.firstChild); + }, + bottom: function(element, node) { + element.appendChild(node); + }, + after: function(element, node) { + element.parentNode.insertBefore(node, element.nextSibling); + }, - insert: function(element, insertions) { + tags: { + TABLE: ['', '
', 1], + TBODY: ['', '
', 2], + TR: ['', '
', 3], + TD: ['
', '
', 4], + SELECT: ['', 1] + } + }; + + var tags = INSERTION_TRANSLATIONS.tags; + + Object.extend(tags, { + THEAD: tags.TBODY, + TFOOT: tags.TBODY, + TH: tags.TD + }); + + function replace_IE(element, content) { element = $(element); + if (content && content.toElement) + content = content.toElement(); + if (Object.isElement(content)) { + element.parentNode.replaceChild(content, element); + return element; + } - if (Object.isString(insertions) || Object.isNumber(insertions) || - Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) - insertions = {bottom:insertions}; + content = Object.toHTML(content); + var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); - var content, insert, tagName, childNodes; + if (tagName in INSERTION_TRANSLATIONS.tags) { + var nextSibling = Element.next(element); + var fragments = getContentFromAnonymousElement( + tagName, content.stripScripts()); - for (var position in insertions) { - content = insertions[position]; - position = position.toLowerCase(); - insert = Element._insertionTranslations[position]; + parent.removeChild(element); - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - insert(element, content); - continue; - } + var iterator; + if (nextSibling) + iterator = function(node) { parent.insertBefore(node, nextSibling) }; + else + iterator = function(node) { parent.appendChild(node); } - content = Object.toHTML(content); + fragments.each(iterator); + } else { + element.outerHTML = content.stripScripts(); + } - tagName = ((position == 'before' || position == 'after') - ? element.parentNode : element).tagName.toUpperCase(); + content.evalScripts.bind(content).defer(); + return element; + } - childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); + if ('outerHTML' in document.documentElement) + replace = replace_IE; - if (position == 'top' || position == 'after') childNodes.reverse(); - childNodes.each(insert.curry(element)); + function isContent(content) { + if (Object.isUndefined(content) || content === null) return false; - content.evalScripts.bind(content).defer(); + if (Object.isString(content) || Object.isNumber(content)) return true; + if (Object.isElement(content)) return true; + if (content.toElement || content.toHTML) return true; + + return false; + } + + function insertContentAt(element, content, position) { + position = position.toLowerCase(); + var method = INSERTION_TRANSLATIONS[position]; + + if (content && content.toElement) content = content.toElement(); + if (Object.isElement(content)) { + method(element, content); + return element; } + content = Object.toHTML(content); + var tagName = ((position === 'before' || position === 'after') ? + element.parentNode : element).tagName.toUpperCase(); + + var childNodes = getContentFromAnonymousElement(tagName, content.stripScripts()); + + if (position === 'top' || position === 'after') childNodes.reverse(); + + for (var i = 0, node; node = childNodes[i]; i++) + method(element, node); + + content.evalScripts.bind(content).defer(); + } + + function insert(element, insertions) { + element = $(element); + + if (isContent(insertions)) + insertions = { bottom: insertions }; + + for (var position in insertions) + insertContentAt(element, insertions[position], position); + return element; - }, + } - wrap: function(element, wrapper, attributes) { + function wrap(element, wrapper, attributes) { element = $(element); - if (Object.isElement(wrapper)) - $(wrapper).writeAttribute(attributes || { }); - else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); - else wrapper = new Element('div', wrapper); + + if (Object.isElement(wrapper)) { + $(wrapper).writeAttribute(attributes || {}); + } else if (Object.isString(wrapper)) { + wrapper = new Element(wrapper, attributes); + } else { + wrapper = new Element('div', wrapper); + } + if (element.parentNode) element.parentNode.replaceChild(wrapper, element); + wrapper.appendChild(element); + return wrapper; - }, + } - inspect: function(element) { + function cleanWhitespace(element) { element = $(element); - var result = '<' + element.tagName.toLowerCase(); - $H({'id': 'id', 'className': 'class'}).each(function(pair) { - var property = pair.first(), - attribute = pair.last(), - value = (element[property] || '').toString(); - if (value) result += ' ' + attribute + '=' + value.inspect(true); - }); - return result + '>'; - }, + var node = element.firstChild; + + while (node) { + var nextNode = node.nextSibling; + if (node.nodeType === Node.TEXT_NODE && !/\S/.test(node.nodeValue)) + element.removeChild(node); + node = nextNode; + } + return element; + } - recursivelyCollect: function(element, property, maximumLength) { + function empty(element) { + return $(element).innerHTML.blank(); + } + + function getContentFromAnonymousElement(tagName, html, force) { + var t = INSERTION_TRANSLATIONS.tags[tagName], div = DIV; + + var workaround = !!t; + if (!workaround && force) { + workaround = true; + t = ['', '', 0]; + } + + if (workaround) { + div.innerHTML = ' ' + t[0] + html + t[1]; + div.removeChild(div.firstChild); + for (var i = t[2]; i--; ) + div = div.firstChild; + } else { + div.innerHTML = html; + } + + return $A(div.childNodes); + } + + function clone(element, deep) { + if (!(element = $(element))) return; + var clone = element.cloneNode(deep); + if (!HAS_UNIQUE_ID_PROPERTY) { + clone._prototypeUID = UNDEFINED; + if (deep) { + var descendants = Element.select(clone, '*'), + i = descendants.length; + while (i--) + descendants[i]._prototypeUID = UNDEFINED; + } + } + return Element.extend(clone); + } + + function purgeElement(element) { + var uid = getUniqueElementID(element); + if (uid) { + Element.stopObserving(element); + if (!HAS_UNIQUE_ID_PROPERTY) + element._prototypeUID = UNDEFINED; + delete Element.Storage[uid]; + } + } + + function purgeCollection(elements) { + var i = elements.length; + while (i--) + purgeElement(elements[i]); + } + + function purgeCollection_IE(elements) { + var i = elements.length, element, uid; + while (i--) { + element = elements[i]; + uid = getUniqueElementID(element); + delete Element.Storage[uid]; + delete Event.cache[uid]; + } + } + + if (HAS_UNIQUE_ID_PROPERTY) { + purgeCollection = purgeCollection_IE; + } + + + function purge(element) { + if (!(element = $(element))) return; + purgeElement(element); + + var descendants = element.getElementsByTagName('*'), + i = descendants.length; + + while (i--) purgeElement(descendants[i]); + + return null; + } + + Object.extend(methods, { + remove: remove, + update: update, + replace: replace, + insert: insert, + wrap: wrap, + cleanWhitespace: cleanWhitespace, + empty: empty, + clone: clone, + purge: purge + }); + + + + function recursivelyCollect(element, property, maximumLength) { element = $(element); maximumLength = maximumLength || -1; var elements = []; while (element = element[property]) { - if (element.nodeType == 1) + if (element.nodeType === Node.ELEMENT_NODE) elements.push(Element.extend(element)); - if (elements.length == maximumLength) - break; + + if (elements.length === maximumLength) break; } return elements; - }, + } - ancestors: function(element) { - return Element.recursivelyCollect(element, 'parentNode'); - }, - descendants: function(element) { - return Element.select(element, "*"); - }, + function ancestors(element) { + return recursivelyCollect(element, 'parentNode'); + } + + function descendants(element) { + return Element.select(element, '*'); + } - firstDescendant: function(element) { + function firstDescendant(element) { element = $(element).firstChild; - while (element && element.nodeType != 1) element = element.nextSibling; + while (element && element.nodeType !== Node.ELEMENT_NODE) + element = element.nextSibling; + return $(element); - }, + } - immediateDescendants: function(element) { + function immediateDescendants(element) { var results = [], child = $(element).firstChild; + while (child) { - if (child.nodeType === 1) { + if (child.nodeType === Node.ELEMENT_NODE) results.push(Element.extend(child)); - } + child = child.nextSibling; } + return results; - }, + } - previousSiblings: function(element, maximumLength) { - return Element.recursivelyCollect(element, 'previousSibling'); - }, + function previousSiblings(element) { + return recursivelyCollect(element, 'previousSibling'); + } - nextSiblings: function(element) { - return Element.recursivelyCollect(element, 'nextSibling'); - }, + function nextSiblings(element) { + return recursivelyCollect(element, 'nextSibling'); + } - siblings: function(element) { + function siblings(element) { element = $(element); - return Element.previousSiblings(element).reverse() - .concat(Element.nextSiblings(element)); - }, + var previous = previousSiblings(element), + next = nextSiblings(element); + return previous.reverse().concat(next); + } - match: function(element, selector) { + function match(element, selector) { element = $(element); + if (Object.isString(selector)) return Prototype.Selector.match(element, selector); + return selector.match(element); - }, + } - up: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(element.parentNode); - var ancestors = Element.ancestors(element); - return Object.isNumber(expression) ? ancestors[expression] : - Prototype.Selector.find(ancestors, expression, index); - }, - down: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return Element.firstDescendant(element); - return Object.isNumber(expression) ? Element.descendants(element)[expression] : - Element.select(element, expression)[index || 0]; - }, + function _recursivelyFind(element, property, expression, index) { + element = $(element), expression = expression || 0, index = index || 0; + if (Object.isNumber(expression)) { + index = expression, expression = null; + } - previous: function(element, expression, index) { - element = $(element); - if (Object.isNumber(expression)) index = expression, expression = false; - if (!Object.isNumber(index)) index = 0; + while (element = element[property]) { + if (element.nodeType !== 1) continue; + if (expression && !Prototype.Selector.match(element, expression)) + continue; + if (--index >= 0) continue; - if (expression) { - return Prototype.Selector.find(element.previousSiblings(), expression, index); - } else { - return element.recursivelyCollect("previousSibling", index + 1)[index]; + return Element.extend(element); } - }, + } + - next: function(element, expression, index) { + function up(element, expression, index) { element = $(element); - if (Object.isNumber(expression)) index = expression, expression = false; - if (!Object.isNumber(index)) index = 0; - if (expression) { - return Prototype.Selector.find(element.nextSiblings(), expression, index); - } else { - var maximumLength = Object.isNumber(index) ? index + 1 : 1; - return element.recursivelyCollect("nextSibling", index + 1)[index]; - } - }, + if (arguments.length === 1) return $(element.parentNode); + return _recursivelyFind(element, 'parentNode', expression, index); + } + function down(element, expression, index) { + element = $(element), expression = expression || 0, index = index || 0; - select: function(element) { - element = $(element); - var expressions = Array.prototype.slice.call(arguments, 1).join(', '); - return Prototype.Selector.select(expressions, element); - }, + if (Object.isNumber(expression)) + index = expression, expression = '*'; - adjacent: function(element) { - element = $(element); - var expressions = Array.prototype.slice.call(arguments, 1).join(', '); - return Prototype.Selector.select(expressions, element.parentNode).without(element); - }, + var node = Prototype.Selector.select(expression, element)[index]; + return Element.extend(node); + } - identify: function(element) { + function previous(element, expression, index) { + return _recursivelyFind(element, 'previousSibling', expression, index); + } + + function next(element, expression, index) { + return _recursivelyFind(element, 'nextSibling', expression, index); + } + + function select(element) { element = $(element); - var id = Element.readAttribute(element, 'id'); - if (id) return id; - do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id)); - Element.writeAttribute(element, 'id', id); - return id; - }, + var expressions = SLICE.call(arguments, 1).join(', '); + return Prototype.Selector.select(expressions, element); + } - readAttribute: function(element, name) { + function adjacent(element) { element = $(element); - if (Prototype.Browser.IE) { - var t = Element._attributeTranslations.read; - if (t.values[name]) return t.values[name](element, name); - if (t.names[name]) name = t.names[name]; - if (name.include(':')) { - return (!element.attributes || !element.attributes[name]) ? null : - element.attributes[name].value; - } + var expressions = SLICE.call(arguments, 1).join(', '); + var siblings = Element.siblings(element), results = []; + for (var i = 0, sibling; sibling = siblings[i]; i++) { + if (Prototype.Selector.match(sibling, expressions)) + results.push(sibling); } - return element.getAttribute(name); - }, - writeAttribute: function(element, name, value) { - element = $(element); - var attributes = { }, t = Element._attributeTranslations.write; + return results; + } - if (typeof name == 'object') attributes = name; - else attributes[name] = Object.isUndefined(value) ? true : value; + function descendantOf_DOM(element, ancestor) { + element = $(element), ancestor = $(ancestor); + while (element = element.parentNode) + if (element === ancestor) return true; + return false; + } - for (var attr in attributes) { - name = t.names[attr] || attr; - value = attributes[attr]; - if (t.values[attr]) name = t.values[attr](element, value); - if (value === false || value === null) - element.removeAttribute(name); - else if (value === true) - element.setAttribute(name, name); - else element.setAttribute(name, value); - } - return element; - }, + function descendantOf_contains(element, ancestor) { + element = $(element), ancestor = $(ancestor); + if (!ancestor.contains) return descendantOf_DOM(element, ancestor); + return ancestor.contains(element) && ancestor !== element; + } - getHeight: function(element) { - return Element.getDimensions(element).height; - }, + function descendantOf_compareDocumentPosition(element, ancestor) { + element = $(element), ancestor = $(ancestor); + return (element.compareDocumentPosition(ancestor) & 8) === 8; + } - getWidth: function(element) { - return Element.getDimensions(element).width; - }, + var descendantOf; + if (DIV.compareDocumentPosition) { + descendantOf = descendantOf_compareDocumentPosition; + } else if (DIV.contains) { + descendantOf = descendantOf_contains; + } else { + descendantOf = descendantOf_DOM; + } + + + Object.extend(methods, { + recursivelyCollect: recursivelyCollect, + ancestors: ancestors, + descendants: descendants, + firstDescendant: firstDescendant, + immediateDescendants: immediateDescendants, + previousSiblings: previousSiblings, + nextSiblings: nextSiblings, + siblings: siblings, + match: match, + up: up, + down: down, + previous: previous, + next: next, + select: select, + adjacent: adjacent, + descendantOf: descendantOf, + + getElementsBySelector: select, + + childElements: immediateDescendants + }); - classNames: function(element) { - return new Element.ClassNames(element); - }, - hasClassName: function(element, className) { - if (!(element = $(element))) return; - var elementClassName = element.className; - return (elementClassName.length > 0 && (elementClassName == className || - new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); - }, + var idCounter = 1; + function identify(element) { + element = $(element); + var id = Element.readAttribute(element, 'id'); + if (id) return id; - addClassName: function(element, className) { - if (!(element = $(element))) return; - if (!Element.hasClassName(element, className)) - element.className += (element.className ? ' ' : '') + className; - return element; - }, + do { id = 'anonymous_element_' + idCounter++ } while ($(id)); - removeClassName: function(element, className) { - if (!(element = $(element))) return; - element.className = element.className.replace( - new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); - return element; - }, + Element.writeAttribute(element, 'id', id); + return id; + } - toggleClassName: function(element, className) { - if (!(element = $(element))) return; - return Element[Element.hasClassName(element, className) ? - 'removeClassName' : 'addClassName'](element, className); - }, - cleanWhitespace: function(element) { + function readAttribute(element, name) { + return $(element).getAttribute(name); + } + + function readAttribute_IE(element, name) { element = $(element); - var node = element.firstChild; - while (node) { - var nextNode = node.nextSibling; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - element.removeChild(node); - node = nextNode; - } - return element; - }, - empty: function(element) { - return $(element).innerHTML.blank(); - }, + var table = ATTRIBUTE_TRANSLATIONS.read; + if (table.values[name]) + return table.values[name](element, name); - descendantOf: function(element, ancestor) { - element = $(element), ancestor = $(ancestor); + if (table.names[name]) name = table.names[name]; - if (element.compareDocumentPosition) - return (element.compareDocumentPosition(ancestor) & 8) === 8; + if (name.include(':')) { + if (!element.attributes || !element.attributes[name]) return null; + return element.attributes[name].value; + } - if (ancestor.contains) - return ancestor.contains(element) && ancestor !== element; + return element.getAttribute(name); + } - while (element = element.parentNode) - if (element == ancestor) return true; + function readAttribute_Opera(element, name) { + if (name === 'title') return element.title; + return element.getAttribute(name); + } - return false; - }, + var PROBLEMATIC_ATTRIBUTE_READING = (function() { + DIV.setAttribute('onclick', Prototype.emptyFunction); + var value = DIV.getAttribute('onclick'); + var isFunction = (typeof value === 'function'); + DIV.removeAttribute('onclick'); + return isFunction; + })(); + + if (PROBLEMATIC_ATTRIBUTE_READING) { + readAttribute = readAttribute_IE; + } else if (Prototype.Browser.Opera) { + readAttribute = readAttribute_Opera; + } - scrollTo: function(element) { - element = $(element); - var pos = Element.cumulativeOffset(element); - window.scrollTo(pos[0], pos[1]); - return element; - }, - getStyle: function(element, style) { + function writeAttribute(element, name, value) { element = $(element); - style = style == 'float' ? 'cssFloat' : style.camelize(); - var value = element.style[style]; - if (!value || value == 'auto') { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css[style] : null; - } - if (style == 'opacity') return value ? parseFloat(value) : 1.0; - return value == 'auto' ? null : value; - }, + var attributes = {}, table = ATTRIBUTE_TRANSLATIONS.write; - getOpacity: function(element) { - return $(element).getStyle('opacity'); - }, + if (typeof name === 'object') { + attributes = name; + } else { + attributes[name] = Object.isUndefined(value) ? true : value; + } - setStyle: function(element, styles) { - element = $(element); - var elementStyle = element.style, match; - if (Object.isString(styles)) { - element.style.cssText += ';' + styles; - return styles.include('opacity') ? - element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; + for (var attr in attributes) { + name = table.names[attr] || attr; + value = attributes[attr]; + if (table.values[attr]) + name = table.values[attr](element, value); + if (value === false || value === null) + element.removeAttribute(name); + else if (value === true) + element.setAttribute(name, name); + else element.setAttribute(name, value); } - for (var property in styles) - if (property == 'opacity') element.setOpacity(styles[property]); - else - elementStyle[(property == 'float' || property == 'cssFloat') ? - (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') : - property] = styles[property]; return element; - }, + } - setOpacity: function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - return element; - }, + function hasAttribute(element, attribute) { + attribute = ATTRIBUTE_TRANSLATIONS.has[attribute] || attribute; + var node = $(element).getAttributeNode(attribute); + return !!(node && node.specified); + } - makePositioned: function(element) { - element = $(element); - var pos = Element.getStyle(element, 'position'); - if (pos == 'static' || !pos) { - element._madePositioned = true; - element.style.position = 'relative'; - if (Prototype.Browser.Opera) { - element.style.top = 0; - element.style.left = 0; - } - } - return element; - }, + GLOBAL.Element.Methods.Simulated.hasAttribute = hasAttribute; - undoPositioned: function(element) { - element = $(element); - if (element._madePositioned) { - element._madePositioned = undefined; - element.style.position = - element.style.top = - element.style.left = - element.style.bottom = - element.style.right = ''; - } - return element; - }, + function classNames(element) { + return new Element.ClassNames(element); + } - makeClipping: function(element) { - element = $(element); - if (element._overflow) return element; - element._overflow = Element.getStyle(element, 'overflow') || 'auto'; - if (element._overflow !== 'hidden') - element.style.overflow = 'hidden'; - return element; - }, + var regExpCache = {}; + function getRegExpForClassName(className) { + if (regExpCache[className]) return regExpCache[className]; - undoClipping: function(element) { - element = $(element); - if (!element._overflow) return element; - element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; - element._overflow = null; - return element; - }, + var re = new RegExp("(^|\\s+)" + className + "(\\s+|$)"); + regExpCache[className] = re; + return re; + } - clonePosition: function(element, source) { - var options = Object.extend({ - setLeft: true, - setTop: true, - setWidth: true, - setHeight: true, - offsetTop: 0, - offsetLeft: 0 - }, arguments[2] || { }); + function hasClassName(element, className) { + if (!(element = $(element))) return; - source = $(source); - var p = Element.viewportOffset(source), delta = [0, 0], parent = null; + var elementClassName = element.className; - element = $(element); + if (elementClassName.length === 0) return false; + if (elementClassName === className) return true; - if (Element.getStyle(element, 'position') == 'absolute') { - parent = Element.getOffsetParent(element); - delta = Element.viewportOffset(parent); - } + return getRegExpForClassName(className).test(elementClassName); + } - if (parent == document.body) { - delta[0] -= document.body.offsetLeft; - delta[1] -= document.body.offsetTop; - } + function addClassName(element, className) { + if (!(element = $(element))) return; + + if (!hasClassName(element, className)) + element.className += (element.className ? ' ' : '') + className; - 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'; - if (options.setHeight) element.style.height = source.offsetHeight + 'px'; return element; } -}; -Object.extend(Element.Methods, { - getElementsBySelector: Element.Methods.select, + function removeClassName(element, className) { + if (!(element = $(element))) return; - childElements: Element.Methods.immediateDescendants -}); + element.className = element.className.replace( + getRegExpForClassName(className), ' ').strip(); -Element._attributeTranslations = { - write: { - names: { - className: 'class', - htmlFor: 'for' - }, - values: { } + return element; } -}; -if (Prototype.Browser.Opera) { - Element.Methods.getStyle = Element.Methods.getStyle.wrap( - function(proceed, element, style) { - switch (style) { - case 'height': case 'width': - if (!Element.visible(element)) return null; - - var dim = parseInt(proceed(element, style), 10); + function toggleClassName(element, className, bool) { + if (!(element = $(element))) return; - if (dim !== element['offset' + style.capitalize()]) - return dim + 'px'; + if (Object.isUndefined(bool)) + bool = !hasClassName(element, className); - var properties; - if (style === 'height') { - properties = ['border-top-width', 'padding-top', - 'padding-bottom', 'border-bottom-width']; - } - else { - properties = ['border-left-width', 'padding-left', - 'padding-right', 'border-right-width']; - } - return properties.inject(dim, function(memo, property) { - var val = proceed(element, property); - return val === null ? memo : memo - parseInt(val, 10); - }) + 'px'; - default: return proceed(element, style); - } - } - ); + var method = Element[bool ? 'addClassName' : 'removeClassName']; + return method(element, className); + } - Element.Methods.readAttribute = Element.Methods.readAttribute.wrap( - function(proceed, element, attribute) { - if (attribute === 'title') return element.title; - return proceed(element, attribute); - } - ); -} + var ATTRIBUTE_TRANSLATIONS = {}; -else if (Prototype.Browser.IE) { - Element.Methods.getStyle = function(element, style) { - element = $(element); - style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); - var value = element.style[style]; - if (!value && element.currentStyle) value = element.currentStyle[style]; + var classProp = 'className', forProp = 'for'; - if (style == 'opacity') { - if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) - if (value[1]) return parseFloat(value[1]) / 100; - return 1.0; - } + DIV.setAttribute(classProp, 'x'); + if (DIV.className !== 'x') { + DIV.setAttribute('class', 'x'); + if (DIV.className === 'x') + classProp = 'class'; + } - if (value == 'auto') { - if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) - return element['offset' + style.capitalize()] + 'px'; - return null; - } - return value; - }; + var LABEL = document.createElement('label'); + LABEL.setAttribute(forProp, 'x'); + if (LABEL.htmlFor !== 'x') { + LABEL.setAttribute('htmlFor', 'x'); + if (LABEL.htmlFor === 'x') + forProp = 'htmlFor'; + } + LABEL = null; - Element.Methods.setOpacity = function(element, value) { - function stripAlpha(filter){ - return filter.replace(/alpha\([^\)]*\)/gi,''); - } - element = $(element); - var currentStyle = element.currentStyle; - if ((currentStyle && !currentStyle.hasLayout) || - (!currentStyle && element.style.zoom == 'normal')) - element.style.zoom = 1; + function _getAttr(element, attribute) { + return element.getAttribute(attribute); + } - var filter = element.getStyle('filter'), style = element.style; - if (value == 1 || value === '') { - (filter = stripAlpha(filter)) ? - style.filter = filter : style.removeAttribute('filter'); - return element; - } else if (value < 0.00001) value = 0; - style.filter = stripAlpha(filter) + - 'alpha(opacity=' + (value * 100) + ')'; - return element; - }; + function _getAttr2(element, attribute) { + return element.getAttribute(attribute, 2); + } - Element._attributeTranslations = (function(){ + function _getAttrNode(element, attribute) { + var node = element.getAttributeNode(attribute); + return node ? node.value : ''; + } - var classProp = 'className', - forProp = 'for', - el = document.createElement('div'); + function _getFlag(element, attribute) { + return $(element).hasAttribute(attribute) ? attribute : null; + } - el.setAttribute(classProp, 'x'); + DIV.onclick = Prototype.emptyFunction; + var onclickValue = DIV.getAttribute('onclick'); - if (el.className !== 'x') { - el.setAttribute('class', 'x'); - if (el.className === 'x') { - classProp = 'class'; - } - } - el = null; + var _getEv; - el = document.createElement('label'); - el.setAttribute(forProp, 'x'); - if (el.htmlFor !== 'x') { - el.setAttribute('htmlFor', 'x'); - if (el.htmlFor === 'x') { - forProp = 'htmlFor'; - } - } - el = null; + if (String(onclickValue).indexOf('{') > -1) { + _getEv = function(element, attribute) { + var value = element.getAttribute(attribute); + if (!value) return null; + value = value.toString(); + value = value.split('{')[1]; + value = value.split('}')[0]; + return value.strip(); + }; + } + else if (onclickValue === '') { + _getEv = function(element, attribute) { + var value = element.getAttribute(attribute); + if (!value) return null; + return value.strip(); + }; + } - return { - read: { - names: { - 'class': classProp, - 'className': classProp, - 'for': forProp, - 'htmlFor': forProp - }, - 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'), f; - el.onclick = Prototype.emptyFunction; - var value = el.getAttribute('onclick'); - - 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; - } - } + ATTRIBUTE_TRANSLATIONS.read = { + names: { + 'class': classProp, + 'className': classProp, + 'for': forProp, + 'htmlFor': forProp + }, + + values: { + style: function(element) { + return element.style.cssText.toLowerCase(); + }, + title: function(element) { + return element.title; } } - })(); + }; - Element._attributeTranslations.write = { - names: Object.extend({ + ATTRIBUTE_TRANSLATIONS.write = { + names: { + className: 'class', + htmlFor: 'for', cellpadding: 'cellPadding', cellspacing: 'cellSpacing' - }, Element._attributeTranslations.read.names), + }, + values: { checked: function(element, value) { element.checked = !!value; @@ -2678,227 +2951,322 @@ else if (Prototype.Browser.IE) { } }; - Element._attributeTranslations.has = {}; + ATTRIBUTE_TRANSLATIONS.has = { names: {} }; + + Object.extend(ATTRIBUTE_TRANSLATIONS.write.names, + ATTRIBUTE_TRANSLATIONS.read.names); + + var CAMEL_CASED_ATTRIBUTE_NAMES = $w('colSpan rowSpan vAlign dateTime ' + + 'accessKey tabIndex encType maxLength readOnly longDesc frameBorder'); + + for (var i = 0, attr; attr = CAMEL_CASED_ATTRIBUTE_NAMES[i]; i++) { + ATTRIBUTE_TRANSLATIONS.write.names[attr.toLowerCase()] = attr; + ATTRIBUTE_TRANSLATIONS.has.names[attr.toLowerCase()] = attr; + } + + Object.extend(ATTRIBUTE_TRANSLATIONS.read.values, { + href: _getAttr2, + src: _getAttr2, + type: _getAttr, + action: _getAttrNode, + disabled: _getFlag, + checked: _getFlag, + readonly: _getFlag, + multiple: _getFlag, + onload: _getEv, + onunload: _getEv, + onclick: _getEv, + ondblclick: _getEv, + onmousedown: _getEv, + onmouseup: _getEv, + onmouseover: _getEv, + onmousemove: _getEv, + onmouseout: _getEv, + onfocus: _getEv, + onblur: _getEv, + onkeypress: _getEv, + onkeydown: _getEv, + onkeyup: _getEv, + onsubmit: _getEv, + onreset: _getEv, + onselect: _getEv, + onchange: _getEv + }); + - $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + - 'encType maxLength readOnly longDesc frameBorder').each(function(attr) { - Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; - Element._attributeTranslations.has[attr.toLowerCase()] = attr; + Object.extend(methods, { + identify: identify, + readAttribute: readAttribute, + writeAttribute: writeAttribute, + classNames: classNames, + hasClassName: hasClassName, + addClassName: addClassName, + removeClassName: removeClassName, + toggleClassName: toggleClassName }); - (function(v) { - Object.extend(v, { - href: v._getAttr2, - src: v._getAttr2, - type: v._getAttr, - action: v._getAttrNode, - disabled: v._flag, - checked: v._flag, - readonly: v._flag, - multiple: v._flag, - onload: v._getEv, - onunload: v._getEv, - onclick: v._getEv, - ondblclick: v._getEv, - onmousedown: v._getEv, - onmouseup: v._getEv, - onmouseover: v._getEv, - onmousemove: v._getEv, - onmouseout: v._getEv, - onfocus: v._getEv, - onblur: v._getEv, - onkeypress: v._getEv, - onkeydown: v._getEv, - onkeyup: v._getEv, - onsubmit: v._getEv, - onreset: v._getEv, - onselect: v._getEv, - 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; + function normalizeStyleName(style) { + if (style === 'float' || style === 'styleFloat') + return 'cssFloat'; + return style.camelize(); + } + + function normalizeStyleName_IE(style) { + if (style === 'float' || style === 'cssFloat') + return 'styleFloat'; + return style.camelize(); + } + + function setStyle(element, styles) { + element = $(element); + var elementStyle = element.style, match; + + if (Object.isString(styles)) { + elementStyle.cssText += ';' + styles; + if (styles.include('opacity')) { + var opacity = styles.match(/opacity:\s*(\d?\.?\d*)/)[1]; + Element.setOpacity(element, opacity); } + return element; + } - 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]; + for (var property in styles) { + if (property === 'opacity') { + Element.setOpacity(element, styles[property]); + } else { + var value = styles[property]; + if (property === 'float' || property === 'cssFloat') { + property = Object.isUndefined(elementStyle.styleFloat) ? + 'cssFloat' : 'styleFloat'; + } + elementStyle[property] = value; } - })(); + } + + return element; } -} -else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { - Element.Methods.setOpacity = function(element, value) { + function getStyle(element, style) { element = $(element); - element.style.opacity = (value == 1) ? 0.999999 : - (value === '') ? '' : (value < 0.00001) ? 0 : value; - return element; - }; -} + style = normalizeStyleName(style); + + var value = element.style[style]; + if (!value || value === 'auto') { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css[style] : null; + } + + if (style === 'opacity') return value ? parseFloat(value) : 1.0; + return value === 'auto' ? null : value; + } + + function getStyle_Opera(element, style) { + switch (style) { + case 'height': case 'width': + if (!Element.visible(element)) return null; + + var dim = parseInt(getStyle(element, style), 10); + + if (dim !== element['offset' + style.capitalize()]) + return dim + 'px'; + + return Element.measure(element, style); -else if (Prototype.Browser.WebKit) { - Element.Methods.setOpacity = function(element, value) { + default: return getStyle(element, style); + } + } + + function getStyle_IE(element, style) { element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - - if (value == 1) - if (element.tagName.toUpperCase() == 'IMG' && element.width) { - element.width++; element.width--; - } else try { - var n = document.createTextNode(' '); - element.appendChild(n); - element.removeChild(n); - } catch (e) { } + style = normalizeStyleName_IE(style); + + var value = element.style[style]; + if (!value && element.currentStyle) { + value = element.currentStyle[style]; + } + + if (style === 'opacity' && !STANDARD_CSS_OPACITY_SUPPORTED) + return getOpacity_IE(element); + + if (value === 'auto') { + if ((style === 'width' || style === 'height') && Element.visible(element)) + return Element.measure(element, style) + 'px'; + return null; + } + + return value; + } + + function stripAlphaFromFilter_IE(filter) { + return (filter || '').replace(/alpha\([^\)]*\)/gi, ''); + } + function hasLayout_IE(element) { + if (!element.currentStyle.hasLayout) + element.style.zoom = 1; return element; - }; -} + } + + var STANDARD_CSS_OPACITY_SUPPORTED = (function() { + DIV.style.cssText = "opacity:.55"; + return /^0.55/.test(DIV.style.opacity); + })(); -if ('outerHTML' in document.documentElement) { - Element.Methods.replace = function(element, content) { + function setOpacity(element, value) { element = $(element); + if (value == 1 || value === '') value = ''; + else if (value < 0.00001) value = 0; + element.style.opacity = value; + return element; + } - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - element.parentNode.replaceChild(content, element); + function setOpacity_IE(element, value) { + if (STANDARD_CSS_OPACITY_SUPPORTED) + return setOpacity(element, value); + + element = hasLayout_IE($(element)); + var filter = Element.getStyle(element, 'filter'), + style = element.style; + + if (value == 1 || value === '') { + filter = stripAlphaFromFilter_IE(filter); + if (filter) style.filter = filter; + else style.removeAttribute('filter'); return element; } - content = Object.toHTML(content); - var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); + if (value < 0.00001) value = 0; - if (Element._insertionTranslations.tags[tagName]) { - var nextSibling = element.next(), - fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - parent.removeChild(element); - if (nextSibling) - fragments.each(function(node) { parent.insertBefore(node, nextSibling) }); - else - fragments.each(function(node) { parent.appendChild(node) }); - } - else element.outerHTML = content.stripScripts(); + style.filter = stripAlphaFromFilter_IE(filter) + + 'alpha(opacity=' + (value * 100) + ')'; - content.evalScripts.bind(content).defer(); return element; - }; -} + } -Element._returnOffset = function(l, t) { - var result = [l, t]; - result.left = l; - result.top = t; - return result; -}; -Element._getContentFromAnonymousElement = function(tagName, html, force) { - var div = new Element('div'), - t = Element._insertionTranslations.tags[tagName]; + function getOpacity(element) { + return Element.getStyle(element, 'opacity'); + } + + function getOpacity_IE(element) { + if (STANDARD_CSS_OPACITY_SUPPORTED) + return getOpacity(element); - var workaround = false; - if (t) workaround = true; - else if (force) { - workaround = true; - t = ['', '', 0]; + var filter = Element.getStyle(element, 'filter'); + if (filter.length === 0) return 1.0; + var match = (filter || '').match(/alpha\(opacity=(.*)\)/); + if (match[1]) return parseFloat(match[1]) / 100; + return 1.0; } - if (workaround) { - div.innerHTML = ' ' + t[0] + html + t[1]; - div.removeChild(div.firstChild); - for (var i = t[2]; i--; ) { - div = div.firstChild; - } + + Object.extend(methods, { + setStyle: setStyle, + getStyle: getStyle, + setOpacity: setOpacity, + getOpacity: getOpacity + }); + + if ('styleFloat' in DIV.style) { + methods.getStyle = getStyle_IE; + methods.setOpacity = setOpacity_IE; + methods.getOpacity = getOpacity_IE; } - else { - div.innerHTML = html; + + var UID = 0; + + GLOBAL.Element.Storage = { UID: 1 }; + + function getUniqueElementID(element) { + if (element === window) return 0; + + if (typeof element._prototypeUID === 'undefined') + element._prototypeUID = Element.Storage.UID++; + return element._prototypeUID; } - return $A(div.childNodes); -}; -Element._insertionTranslations = { - before: function(element, node) { - element.parentNode.insertBefore(node, element); - }, - top: function(element, node) { - element.insertBefore(node, element.firstChild); - }, - bottom: function(element, node) { - element.appendChild(node); - }, - after: function(element, node) { - element.parentNode.insertBefore(node, element.nextSibling); - }, - tags: { - TABLE: ['', '
', 1], - TBODY: ['', '
', 2], - TR: ['', '
', 3], - TD: ['
', '
', 4], - SELECT: ['', 1] + function getUniqueElementID_IE(element) { + if (element === window) return 0; + if (element == document) return 1; + return element.uniqueID; } -}; -(function() { - var tags = Element._insertionTranslations.tags; - Object.extend(tags, { - THEAD: tags.TBODY, - TFOOT: tags.TBODY, - TH: tags.TD - }); -})(); + var HAS_UNIQUE_ID_PROPERTY = ('uniqueID' in DIV); + if (HAS_UNIQUE_ID_PROPERTY) + getUniqueElementID = getUniqueElementID_IE; -Element.Methods.Simulated = { - hasAttribute: function(element, attribute) { - attribute = Element._attributeTranslations.has[attribute] || attribute; - var node = $(element).getAttributeNode(attribute); - return !!(node && node.specified); + function getStorage(element) { + if (!(element = $(element))) return; + + var uid = getUniqueElementID(element); + + if (!Element.Storage[uid]) + Element.Storage[uid] = $H(); + + return Element.Storage[uid]; } -}; -Element.Methods.ByTag = { }; + function store(element, key, value) { + if (!(element = $(element))) return; + var storage = getStorage(element); + if (arguments.length === 2) { + storage.update(key); + } else { + storage.set(key, value); + } + return element; + } -Object.extend(Element, Element.Methods); + function retrieve(element, key, defaultValue) { + if (!(element = $(element))) return; + var storage = getStorage(element), value = storage.get(key); -(function(div) { + if (Object.isUndefined(value)) { + storage.set(key, defaultValue); + value = defaultValue; + } - if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) { - window.HTMLElement = { }; - window.HTMLElement.prototype = div['__proto__']; - Prototype.BrowserFeatures.ElementExtensions = true; + return value; } - div = null; -})(document.createElement('div')); + Object.extend(methods, { + getStorage: getStorage, + store: store, + retrieve: retrieve + }); -Element.extend = (function() { - function checkDeficiency(tagName) { - if (typeof window.Element != 'undefined') { - var proto = window.Element.prototype; - if (proto) { - var id = '_' + (Math.random()+'').slice(2), - el = document.createElement(tagName); - proto[id] = 'x'; - var isBuggy = (el[id] !== 'x'); - delete proto[id]; - el = null; - return isBuggy; - } + var Methods = {}, ByTag = Element.Methods.ByTag, + F = Prototype.BrowserFeatures; + + if (!F.ElementExtensions && ('__proto__' in DIV)) { + GLOBAL.HTMLElement = {}; + GLOBAL.HTMLElement.prototype = DIV['__proto__']; + F.ElementExtensions = true; + } + + function checkElementPrototypeDeficiency(tagName) { + if (typeof window.Element === 'undefined') return false; + var proto = window.Element.prototype; + if (proto) { + var id = '_' + (Math.random() + '').slice(2), + el = document.createElement(tagName); + proto[id] = 'x'; + var isBuggy = (el[id] !== 'x'); + delete proto[id]; + el = null; + return isBuggy; } + return false; } + var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = + checkElementPrototypeDeficiency('object'); + function extendElementWith(element, methods) { for (var property in methods) { var value = methods[property]; @@ -2907,98 +3275,52 @@ Element.extend = (function() { } } - 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 EXTENDED = {}; + function elementIsExtended(element) { + var uid = getUniqueElementID(element); + return (uid in EXTENDED); } - var Methods = { }, ByTag = Element.Methods.ByTag; - - var extend = Object.extend(function(element) { - if (!element || typeof element._extendedByPrototype != 'undefined' || - element.nodeType != 1 || element == window) return element; + function extend(element) { + if (!element || elementIsExtended(element)) return element; + if (element.nodeType !== Node.ELEMENT_NODE || element == window) + return element; var methods = Object.clone(Methods), - tagName = element.tagName.toUpperCase(); + tagName = element.tagName.toUpperCase(); if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); extendElementWith(element, methods); - - element._extendedByPrototype = Prototype.emptyFunction; + EXTENDED[getUniqueElementID(element)] = true; return element; + } - }, { - refresh: function() { - if (!Prototype.BrowserFeatures.ElementExtensions) { - Object.extend(Methods, Element.Methods); - Object.extend(Methods, Element.Methods.Simulated); - } - } - }); - - extend.refresh(); - return extend; -})(); - -if (document.documentElement.hasAttribute) { - Element.hasAttribute = function(element, attribute) { - return element.hasAttribute(attribute); - }; -} -else { - Element.hasAttribute = Element.Methods.Simulated.hasAttribute; -} - -Element.addMethods = function(methods) { - var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; + function extend_IE8(element) { + if (!element || elementIsExtended(element)) return element; - if (!methods) { - Object.extend(Form, Form.Methods); - Object.extend(Form.Element, Form.Element.Methods); - Object.extend(Element.Methods.ByTag, { - "FORM": Object.clone(Form.Methods), - "INPUT": Object.clone(Form.Element.Methods), - "SELECT": Object.clone(Form.Element.Methods), - "TEXTAREA": Object.clone(Form.Element.Methods), - "BUTTON": Object.clone(Form.Element.Methods) - }); - } + 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()]); + } - if (arguments.length == 2) { - var tagName = methods; - methods = arguments[1]; + return element; } - if (!tagName) Object.extend(Element.Methods, methods || { }); - else { - if (Object.isArray(tagName)) tagName.each(extend); - else extend(tagName); + if (F.SpecificElementExtensions) { + extend = HTMLOBJECTELEMENT_PROTOTYPE_BUGGY ? extend_IE8 : Prototype.K; } - function extend(tagName) { + function addMethodsToTagName(tagName, methods) { tagName = tagName.toUpperCase(); - if (!Element.Methods.ByTag[tagName]) - Element.Methods.ByTag[tagName] = { }; - Object.extend(Element.Methods.ByTag[tagName], methods); + if (!ByTag[tagName]) ByTag[tagName] = {}; + Object.extend(ByTag[tagName], methods); } - function copy(methods, destination, onlyIfAbsent) { - onlyIfAbsent = onlyIfAbsent || false; + function mergeMethods(destination, methods, onlyIfAbsent) { + if (Object.isUndefined(onlyIfAbsent)) onlyIfAbsent = false; for (var property in methods) { var value = methods[property]; if (!Object.isFunction(value)) continue; @@ -3028,169 +3350,142 @@ Element.addMethods = function(methods) { if (window[klass]) return window[klass]; var element = document.createElement(tagName), - proto = element['__proto__'] || element.constructor.prototype; + proto = element['__proto__'] || element.constructor.prototype; element = null; return proto; } - var elementPrototype = window.HTMLElement ? HTMLElement.prototype : - Element.prototype; + function addMethods(methods) { + if (arguments.length === 0) addFormMethods(); - if (F.ElementExtensions) { - copy(Element.Methods, elementPrototype); - copy(Element.Methods.Simulated, elementPrototype, true); - } + if (arguments.length === 2) { + var tagName = methods; + methods = arguments[1]; + } - if (F.SpecificElementExtensions) { - for (var tag in Element.Methods.ByTag) { - var klass = findDOMClass(tag); - if (Object.isUndefined(klass)) continue; - copy(T[tag], klass.prototype); + if (!tagName) { + Object.extend(Element.Methods, methods || {}); + } else { + if (Object.isArray(tagName)) { + for (var i = 0, tag; tag = tagName[i]; i++) + addMethodsToTagName(tag, methods); + } else { + addMethodsToTagName(tagName, methods); + } } - } - Object.extend(Element, Element.Methods); - delete Element.ByTag; + var ELEMENT_PROTOTYPE = window.HTMLElement ? HTMLElement.prototype : + Element.prototype; - if (Element.extend.refresh) Element.extend.refresh(); - Element.cache = { }; -}; + if (F.ElementExtensions) { + mergeMethods(ELEMENT_PROTOTYPE, Element.Methods); + mergeMethods(ELEMENT_PROTOTYPE, Element.Methods.Simulated, true); + } + if (F.SpecificElementExtensions) { + for (var tag in Element.Methods.ByTag) { + var klass = findDOMClass(tag); + if (Object.isUndefined(klass)) continue; + mergeMethods(klass.prototype, ByTag[tag]); + } + } -document.viewport = { + Object.extend(Element, Element.Methods); + Object.extend(Element, Element.Methods.Simulated); + delete Element.ByTag; + delete Element.Simulated; - getDimensions: function() { - return { width: this.getWidth(), height: this.getHeight() }; - }, + Element.extend.refresh(); - getScrollOffsets: function() { - return Element._returnOffset( - window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, - window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); + ELEMENT_CACHE = {}; } -}; -(function(viewport) { - var B = Prototype.Browser, doc = document, element, property = {}; - - function getRootElement() { - if (B.WebKit && !doc.evaluate) - return document; + Object.extend(GLOBAL.Element, { + extend: extend, + addMethods: addMethods + }); - if (B.Opera && window.parseFloat(window.opera.version()) < 9.5) - return document.body; + if (extend === Prototype.K) { + GLOBAL.Element.extend.refresh = Prototype.emptyFunction; + } else { + GLOBAL.Element.extend.refresh = function() { + if (Prototype.BrowserFeatures.ElementExtensions) return; + Object.extend(Methods, Element.Methods); + Object.extend(Methods, Element.Methods.Simulated); - return document.documentElement; + EXTENDED = {}; + }; } - function define(D) { - if (!element) element = getRootElement(); - - property[D] = 'client' + D; - - viewport['get' + D] = function() { return element[property[D]] }; - return viewport['get' + D](); + function addFormMethods() { + Object.extend(Form, Form.Methods); + Object.extend(Form.Element, Form.Element.Methods); + Object.extend(Element.Methods.ByTag, { + "FORM": Object.clone(Form.Methods), + "INPUT": Object.clone(Form.Element.Methods), + "SELECT": Object.clone(Form.Element.Methods), + "TEXTAREA": Object.clone(Form.Element.Methods), + "BUTTON": Object.clone(Form.Element.Methods) + }); } - 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; - } - - 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; - }, + Element.addMethods(methods); - retrieve: function(element, key, defaultValue) { - if (!(element = $(element))) return; - var hash = Element.getStorage(element), value = hash.get(key); +})(this); +(function() { - if (Object.isUndefined(value)) { - hash.set(key, defaultValue); - value = defaultValue; - } + function toDecimal(pctString) { + var match = pctString.match(/^(\d+)%?$/i); + if (!match) return null; + return (Number(match[1]) / 100); + } - return value; - }, + function getRawStyle(element, style) { + element = $(element); - 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; - } + var value = element.style[style]; + if (!value || value === 'auto') { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css[style] : null; } - return Element.extend(clone); - }, - purge: function(element) { - if (!(element = $(element))) return; - var purgeElement = Element._purgeElement; + if (style === 'opacity') return value ? parseFloat(value) : 1.0; + return value === 'auto' ? null : value; + } - purgeElement(element); + function getRawStyle_IE(element, style) { + var value = element.style[style]; + if (!value && element.currentStyle) { + value = element.currentStyle[style]; + } + return value; + } - var descendants = element.getElementsByTagName('*'), - i = descendants.length; + function getContentWidth(element, context) { + var boxWidth = element.offsetWidth; - while (i--) purgeElement(descendants[i]); + var bl = getPixelValue(element, 'borderLeftWidth', context) || 0; + var br = getPixelValue(element, 'borderRightWidth', context) || 0; + var pl = getPixelValue(element, 'paddingLeft', context) || 0; + var pr = getPixelValue(element, 'paddingRight', context) || 0; - return null; + return boxWidth - bl - br - pl - pr; } -}); -(function() { - - function toDecimal(pctString) { - var match = pctString.match(/^(\d+)%?$/i); - if (!match) return null; - return (Number(match[1]) / 100); + if ('currentStyle' in document.documentElement) { + getRawStyle = getRawStyle_IE; } + function getPixelValue(value, property, context) { var element = null; if (Object.isElement(value)) { element = value; - value = element.getStyle(property); + value = getRawStyle(element, property); } - if (value === null) { + if (value === null || Object.isUndefined(value)) { return null; } @@ -3213,14 +3508,12 @@ Element.addMethods({ if (element && isPercentage) { context = context || element.parentNode; - var decimal = toDecimal(value); - var whole = null; - var position = element.getStyle('position'); + var decimal = toDecimal(value), whole = null; var isHorizontal = property.include('left') || property.include('right') || property.include('width'); - var isVertical = property.include('top') || property.include('bottom') || + var isVertical = property.include('top') || property.include('bottom') || property.include('height'); if (context === document.viewport) { @@ -3244,14 +3537,12 @@ Element.addMethods({ } function toCSSPixels(number) { - if (Object.isString(number) && number.endsWith('px')) { + if (Object.isString(number) && number.endsWith('px')) return number; - } return number + 'px'; } function isDisplayed(element) { - var originalElement = element; while (element && element.parentNode) { var display = element.getStyle('display'); if (display === 'none') { @@ -3309,14 +3600,15 @@ Element.addMethods({ }, _begin: function() { - if (this._prepared) return; + if (this._isPrepared()) return; var element = this.element; if (isDisplayed(element)) { - this._prepared = true; + this._setPrepared(true); return; } + var originalStyles = { position: element.style.position || '', width: element.style.width || '', @@ -3326,30 +3618,30 @@ Element.addMethods({ element.store('prototype_original_styles', originalStyles); - var position = element.getStyle('position'), - width = element.getStyle('width'); + var position = getRawStyle(element, 'position'), width = element.offsetWidth; - if (width === "0px" || width === null) { + if (width === 0 || width === null) { element.style.display = 'block'; - width = element.getStyle('width'); + width = element.offsetWidth; } var context = (position === 'fixed') ? document.viewport : element.parentNode; - element.setStyle({ - position: 'absolute', + var tempStyles = { visibility: 'hidden', display: 'block' - }); + }; + + if (position !== 'fixed') tempStyles.position = 'absolute'; - var positionedWidth = element.getStyle('width'); + element.setStyle(tempStyles); - var newWidth; + var positionedWidth = element.offsetWidth, newWidth; if (width && (positionedWidth === width)) { - newWidth = getPixelValue(element, 'width', context); + newWidth = getContentWidth(element, context); } else if (position === 'absolute' || position === 'fixed') { - newWidth = getPixelValue(element, 'width', context); + newWidth = getContentWidth(element, context); } else { var parent = element.parentNode, pLayout = $(parent).getLayout(); @@ -3364,7 +3656,7 @@ Element.addMethods({ element.setStyle({ width: newWidth + 'px' }); - this._prepared = true; + this._setPrepared(true); }, _end: function() { @@ -3372,7 +3664,7 @@ Element.addMethods({ var originalStyles = element.retrieve('prototype_original_styles'); element.store('prototype_original_styles', null); element.setStyle(originalStyles); - this._prepared = false; + this._setPrepared(false); }, _compute: function(property) { @@ -3384,6 +3676,14 @@ Element.addMethods({ return this._set(property, COMPUTATIONS[property].call(this, this.element)); }, + _isPrepared: function() { + return this.element.retrieve('prototype_element_layout_prepared', false); + }, + + _setPrepared: function(bool) { + return this.element.store('prototype_element_layout_prepared', bool); + }, + toObject: function() { var args = $A(arguments); var keys = (args.length === 0) ? Element.Layout.PROPERTIES : @@ -3465,7 +3765,6 @@ Element.addMethods({ pRight = this.get('padding-right'); if (!this._preComputing) this._end(); - return bWidth - bLeft - bRight - pLeft - pRight; }, @@ -3656,6 +3955,14 @@ Element.addMethods({ return $(element).getLayout().get(property); } + function getHeight(element) { + return Element.getDimensions(element).height; + } + + function getWidth(element) { + return Element.getDimensions(element).width; + } + function getDimensions(element) { element = $(element); var display = Element.getStyle(element, 'display'); @@ -3757,10 +4064,9 @@ Element.addMethods({ } function viewportOffset(forElement) { - element = $(element); var valueT = 0, valueL = 0, docBody = document.body; - var element = forElement; + var element = $(forElement); do { valueT += element.offsetTop || 0; valueL += element.offsetLeft || 0; @@ -3823,6 +4129,118 @@ Element.addMethods({ return element; } + + function scrollTo(element) { + element = $(element); + var pos = Element.cumulativeOffset(element); + window.scrollTo(pos.left, pos.top); + return element; + } + + + function makePositioned(element) { + element = $(element); + var position = Element.getStyle(element, 'position'), styles = {}; + if (position === 'static' || !position) { + styles.position = 'relative'; + if (Prototype.Browser.Opera) { + styles.top = 0; + styles.left = 0; + } + Element.setStyle(element, styles); + Element.store(element, 'prototype_made_positioned', true); + } + return element; + } + + function undoPositioned(element) { + element = $(element); + var storage = Element.getStorage(element), + madePositioned = storage.get('prototype_made_positioned'); + + if (madePositioned) { + storage.unset('prototype_made_positioned'); + Element.setStyle(element, { + position: '', + top: '', + bottom: '', + left: '', + right: '' + }); + } + return element; + } + + function makeClipping(element) { + element = $(element); + + var storage = Element.getStorage(element), + madeClipping = storage.get('prototype_made_clipping'); + + if (Object.isUndefined(madeClipping)) { + var overflow = Element.getStyle(element, 'overflow'); + storage.set('prototype_made_clipping', overflow); + if (overflow !== 'hidden') + element.style.overflow = 'hidden'; + } + + return element; + } + + function undoClipping(element) { + element = $(element); + var storage = Element.getStorage(element), + overflow = storage.get('prototype_made_clipping'); + + if (!Object.isUndefined(overflow)) { + storage.unset('prototype_made_clipping'); + element.style.overflow = overflow || ''; + } + + return element; + } + + function clonePosition(element, source, options) { + options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, options || {}); + + source = $(source); + element = $(element); + var p, delta, layout, styles = {}; + + if (options.setLeft || options.setTop) { + p = Element.viewportOffset(source); + delta = [0, 0]; + if (Element.getStyle(element, 'position') === 'absolute') { + var parent = Element.getOffsetParent(element); + if (parent !== document.body) delta = Element.viewportOffset(parent); + } + } + + if (options.setWidth || options.setHeight) { + layout = Element.getLayout(source); + } + + if (options.setLeft) + styles.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if (options.setTop) + styles.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + + if (options.setWidth) + styles.width = layout.get('border-box-width') + 'px'; + if (options.setHeight) + styles.height = layout.get('border-box-height') + 'px'; + + return Element.setStyle(element, styles); + } + + if (Prototype.Browser.IE) { getOffsetParent = getOffsetParent.wrap( function(proceed, element) { @@ -3863,8 +4281,9 @@ Element.addMethods({ do { valueT += element.offsetTop || 0; valueL += element.offsetLeft || 0; - if (element.offsetParent == document.body) + if (element.offsetParent == document.body) { if (Element.getStyle(element, 'position') == 'absolute') break; + } element = element.offsetParent; } while (element); @@ -3877,6 +4296,8 @@ Element.addMethods({ Element.addMethods({ getLayout: getLayout, measure: measure, + getWidth: getWidth, + getHeight: getHeight, getDimensions: getDimensions, getOffsetParent: getOffsetParent, cumulativeOffset: cumulativeOffset, @@ -3884,7 +4305,13 @@ Element.addMethods({ cumulativeScrollOffset: cumulativeScrollOffset, viewportOffset: viewportOffset, absolutize: absolutize, - relativize: relativize + relativize: relativize, + scrollTo: scrollTo, + makePositioned: makePositioned, + undoPositioned: undoPositioned, + makeClipping: makeClipping, + undoClipping: undoClipping, + clonePosition: clonePosition }); function isBody(element) { @@ -3917,6 +4344,49 @@ Element.addMethods({ } }); } + + +})(); + +(function() { + + var IS_OLD_OPERA = Prototype.Browser.Opera && + (window.parseFloat(window.opera.version()) < 9.5); + var ROOT = null; + function getRootElement() { + if (ROOT) return ROOT; + ROOT = IS_OLD_OPERA ? document.body : document.documentElement; + return ROOT; + } + + function getDimensions() { + return { width: this.getWidth(), height: this.getHeight() }; + } + + function getWidth() { + return getRootElement().clientWidth; + } + + function getHeight() { + return getRootElement().clientHeight; + } + + function getScrollOffsets() { + var x = window.pageXOffset || document.documentElement.scrollLeft || + document.body.scrollLeft; + var y = window.pageYOffset || document.documentElement.scrollTop || + document.body.scrollTop; + + return new Element.Offset(x, y); + } + + document.viewport = { + getDimensions: getDimensions, + getWidth: getWidth, + getHeight: getHeight, + getScrollOffsets: getScrollOffsets + }; + })(); window.$$ = function() { var expression = $A(arguments).join(', '); @@ -3962,29 +4432,32 @@ Prototype.Selector = (function() { extendElement: Element.extend }; })(); -Prototype._original_property = window.Sizzle; /*! - * Sizzle CSS Selector Engine - v1.0 - * Copyright 2009, The Dojo Foundation + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * More information: http://sizzlejs.com/ */ (function(){ -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, done = 0, toString = Object.prototype.toString, hasDuplicate = false, - baseHasDuplicate = true; + baseHasDuplicate = true, + rBackslash = /\\/g, + rNonWord = /\W/; -[0, 0].sort(function(){ +[0, 0].sort(function() { baseHasDuplicate = false; return 0; }); -var Sizzle = function(selector, context, results, seed) { +var Sizzle = function( selector, context, results, seed ) { results = results || []; - var origContext = context = context || document; + context = context || document; + + var origContext = context; if ( context.nodeType !== 1 && context.nodeType !== 9 ) { return []; @@ -3994,23 +4467,33 @@ var Sizzle = function(selector, context, results, seed) { return results; } - var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context), + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], soFar = selector; - while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) { - soFar = m[3]; + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; - parts.push( m[1] ); + parts.push( m[1] ); - if ( m[2] ) { - extra = m[3]; - break; + if ( m[2] ) { + extra = m[3]; + break; + } } - } + } while ( m ); if ( parts.length > 1 && origPOS.exec( selector ) ) { + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { set = posProcess( parts[0] + parts[1], context ); + } else { set = Expr.relative[ parts[0] ] ? [ context ] : @@ -4019,33 +4502,43 @@ var Sizzle = function(selector, context, results, seed) { while ( parts.length ) { selector = parts.shift(); - if ( Expr.relative[ selector ] ) + if ( Expr.relative[ selector ] ) { selector += parts.shift(); + } set = posProcess( selector, set ); } } + } else { if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - var ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; } if ( context ) { - var ret = seed ? + ret = seed ? { expr: parts.pop(), set: makeArray(seed) } : Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; if ( parts.length > 0 ) { - checkSet = makeArray(set); + checkSet = makeArray( set ); + } else { prune = false; } while ( parts.length ) { - var cur = parts.pop(), pop = cur; + cur = parts.pop(); + pop = cur; if ( !Expr.relative[ cur ] ) { cur = ""; @@ -4059,6 +4552,7 @@ var Sizzle = function(selector, context, results, seed) { Expr.relative[ cur ]( checkSet, pop, contextXML ); } + } else { checkSet = parts = []; } @@ -4069,25 +4563,28 @@ var Sizzle = function(selector, context, results, seed) { } if ( !checkSet ) { - throw "Syntax error, unrecognized expression: " + (cur || selector); + Sizzle.error( cur || selector ); } if ( toString.call(checkSet) === "[object Array]" ) { if ( !prune ) { results.push.apply( results, checkSet ); + } else if ( context && context.nodeType === 1 ) { - for ( var i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { results.push( set[i] ); } } + } else { - for ( var i = 0; checkSet[i] != null; i++ ) { + for ( i = 0; checkSet[i] != null; i++ ) { if ( checkSet[i] && checkSet[i].nodeType === 1 ) { results.push( set[i] ); } } } + } else { makeArray( checkSet, results ); } @@ -4100,15 +4597,15 @@ var Sizzle = function(selector, context, results, seed) { return results; }; -Sizzle.uniqueSort = function(results){ +Sizzle.uniqueSort = function( results ) { if ( sortOrder ) { hasDuplicate = baseHasDuplicate; - results.sort(sortOrder); + results.sort( sortOrder ); if ( hasDuplicate ) { for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[i-1] ) { - results.splice(i--, 1); + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); } } } @@ -4117,27 +4614,33 @@ Sizzle.uniqueSort = function(results){ return results; }; -Sizzle.matches = function(expr, set){ - return Sizzle(expr, null, null, set); +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; }; -Sizzle.find = function(expr, context, isXML){ - var set, match; +Sizzle.find = function( expr, context, isXML ) { + var set; if ( !expr ) { return []; } for ( var i = 0, l = Expr.order.length; i < l; i++ ) { - var type = Expr.order[i], match; + var match, + type = Expr.order[i]; if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { var left = match[1]; - match.splice(1,1); + match.splice( 1, 1 ); if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace(/\\/g, ""); + match[1] = (match[1] || "").replace( rBackslash, "" ); set = Expr.find[ type ]( match, context, isXML ); + if ( set != null ) { expr = expr.replace( Expr.match[ type ], "" ); break; @@ -4147,23 +4650,37 @@ Sizzle.find = function(expr, context, isXML){ } if ( !set ) { - set = context.getElementsByTagName("*"); + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; } - return {set: set, expr: expr}; + return { set: set, expr: expr }; }; -Sizzle.filter = function(expr, set, inplace, not){ - var old = expr, result = [], curLoop = set, match, anyFound, - isXMLFilter = set && set[0] && isXML(set[0]); +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); while ( expr && set.length ) { for ( var type in Expr.filter ) { - if ( (match = Expr.match[ type ].exec( expr )) != null ) { - var filter = Expr.filter[ type ], found, item; + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + var found, item, + filter = Expr.filter[ type ], + left = match[1]; + anyFound = false; - if ( curLoop == result ) { + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { result = []; } @@ -4172,6 +4689,7 @@ Sizzle.filter = function(expr, set, inplace, not){ if ( !match ) { anyFound = found = true; + } else if ( match === true ) { continue; } @@ -4186,9 +4704,11 @@ Sizzle.filter = function(expr, set, inplace, not){ if ( inplace && found != null ) { if ( pass ) { anyFound = true; + } else { curLoop[i] = false; } + } else if ( pass ) { result.push( item ); anyFound = true; @@ -4213,9 +4733,10 @@ Sizzle.filter = function(expr, set, inplace, not){ } } - if ( expr == old ) { + if ( expr === old ) { if ( anyFound == null ) { - throw "Syntax error, unrecognized expression: " + expr; + Sizzle.error( expr ); + } else { break; } @@ -4227,43 +4748,55 @@ Sizzle.filter = function(expr, set, inplace, not){ return curLoop; }; +Sizzle.error = function( msg ) { + throw "Syntax error, unrecognized expression: " + msg; +}; + var Expr = Sizzle.selectors = { order: [ "ID", "NAME", "TAG" ], + match: { - ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/ + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ }, + leftMatch: {}, + attrMap: { "class": "className", "for": "htmlFor" }, + attrHandle: { - href: function(elem){ - return elem.getAttribute("href"); + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); } }, + relative: { - "+": function(checkSet, part, isXML){ + "+": function(checkSet, part){ var isPartStr = typeof part === "string", - isTag = isPartStr && !/\W/.test(part), + isTag = isPartStr && !rNonWord.test( part ), isPartStrNotTag = isPartStr && !isTag; - if ( isTag && !isXML ) { - part = part.toUpperCase(); + if ( isTag ) { + part = part.toLowerCase(); } for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { if ( (elem = checkSet[i]) ) { while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ? + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? elem || false : elem === part; } @@ -4273,22 +4806,29 @@ var Expr = Sizzle.selectors = { Sizzle.filter( part, checkSet, true ); } }, - ">": function(checkSet, part, isXML){ - var isPartStr = typeof part === "string"; - if ( isPartStr && !/\W/.test(part) ) { - part = isXML ? part : part.toUpperCase(); + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; if ( elem ) { var parent = elem.parentNode; - checkSet[i] = parent.nodeName === part ? parent : false; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; } } + } else { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; + for ( ; i < l; i++ ) { + elem = checkSet[i]; + if ( elem ) { checkSet[i] = isPartStr ? elem.parentNode : @@ -4301,37 +4841,48 @@ var Expr = Sizzle.selectors = { } } }, + "": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; + var nodeCheck, + doneName = done++, + checkFn = dirCheck; - if ( !/\W/.test(part) ) { - var nodeCheck = part = isXML ? part : part.toUpperCase(); + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; checkFn = dirNodeCheck; } - checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); }, - "~": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; - if ( typeof part === "string" && !/\W/.test(part) ) { - var nodeCheck = part = isXML ? part : part.toUpperCase(); + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; checkFn = dirNodeCheck; } - checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); } }, + find: { - ID: function(match, context, isXML){ + ID: function( match, context, isXML ) { if ( typeof context.getElementById !== "undefined" && !isXML ) { var m = context.getElementById(match[1]); - return m ? [m] : []; + return m && m.parentNode ? [m] : []; } }, - NAME: function(match, context, isXML){ + + NAME: function( match, context ) { if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], results = context.getElementsByName(match[1]); + var ret = [], + results = context.getElementsByName( match[1] ); for ( var i = 0, l = results.length; i < l; i++ ) { if ( results[i].getAttribute("name") === match[1] ) { @@ -4342,13 +4893,16 @@ var Expr = Sizzle.selectors = { return ret.length === 0 ? null : ret; } }, - TAG: function(match, context){ - return context.getElementsByTagName(match[1]); + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } } }, preFilter: { - CLASS: function(match, curLoop, inplace, result, not, isXML){ - match = " " + match[1].replace(/\\/g, "") + " "; + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; if ( isXML ) { return match; @@ -4356,9 +4910,11 @@ var Expr = Sizzle.selectors = { for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) { - if ( !inplace ) + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { result.push( elem ); + } + } else if ( inplace ) { curLoop[i] = false; } @@ -4367,184 +4923,262 @@ var Expr = Sizzle.selectors = { return false; }, - ID: function(match){ - return match[1].replace(/\\/g, ""); + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); }, - TAG: function(match, curLoop){ - for ( var i = 0; curLoop[i] === false; i++ ){} - return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase(); + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); }, - CHILD: function(match){ - if ( match[1] == "nth" ) { - var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( - match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" || + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); match[2] = (test[1] + (test[2] || 1)) - 0; match[3] = test[3] - 0; } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } match[0] = done++; return match; }, - ATTR: function(match, curLoop, inplace, result, not, isXML){ - var name = match[1].replace(/\\/g, ""); + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); if ( !isXML && Expr.attrMap[name] ) { match[1] = Expr.attrMap[name]; } + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + if ( match[2] === "~=" ) { match[4] = " " + match[4] + " "; } return match; }, - PSEUDO: function(match, curLoop, inplace, result, not){ + + PSEUDO: function( match, curLoop, inplace, result, not ) { if ( match[1] === "not" ) { if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { match[3] = Sizzle(match[3], null, null, curLoop); + } else { var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + if ( !inplace ) { result.push.apply( result, ret ); } + return false; } + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { return true; } return match; }, - POS: function(match){ + + POS: function( match ) { match.unshift( true ); + return match; } }, + filters: { - enabled: function(elem){ + enabled: function( elem ) { return elem.disabled === false && elem.type !== "hidden"; }, - disabled: function(elem){ + + disabled: function( elem ) { return elem.disabled === true; }, - checked: function(elem){ + + checked: function( elem ) { return elem.checked === true; }, - selected: function(elem){ - elem.parentNode.selectedIndex; + + selected: function( elem ) { + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + return elem.selected === true; }, - parent: function(elem){ + + parent: function( elem ) { return !!elem.firstChild; }, - empty: function(elem){ + + empty: function( elem ) { return !elem.firstChild; }, - has: function(elem, i, match){ + + has: function( elem, i, match ) { return !!Sizzle( match[3], elem ).length; }, - header: function(elem){ - return /h\d/i.test( elem.nodeName ); + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); }, - text: function(elem){ - return "text" === elem.type; + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; }, - radio: function(elem){ - return "radio" === elem.type; + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; }, - checkbox: function(elem){ - return "checkbox" === elem.type; + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; }, - file: function(elem){ - return "file" === elem.type; + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; }, - password: function(elem){ - return "password" === elem.type; + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; }, - submit: function(elem){ - return "submit" === elem.type; + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; }, - image: function(elem){ - return "image" === elem.type; + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; }, - reset: function(elem){ - return "reset" === elem.type; + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; }, - button: function(elem){ - return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON"; + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); }, - input: function(elem){ - return /input|select|textarea|button/i.test(elem.nodeName); + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; } }, setFilters: { - first: function(elem, i){ + first: function( elem, i ) { return i === 0; }, - last: function(elem, i, match, array){ + + last: function( elem, i, match, array ) { return i === array.length - 1; }, - even: function(elem, i){ + + even: function( elem, i ) { return i % 2 === 0; }, - odd: function(elem, i){ + + odd: function( elem, i ) { return i % 2 === 1; }, - lt: function(elem, i, match){ + + lt: function( elem, i, match ) { return i < match[3] - 0; }, - gt: function(elem, i, match){ + + gt: function( elem, i, match ) { return i > match[3] - 0; }, - nth: function(elem, i, match){ - return match[3] - 0 == i; + + nth: function( elem, i, match ) { + return match[3] - 0 === i; }, - eq: function(elem, i, match){ - return match[3] - 0 == i; + + eq: function( elem, i, match ) { + return match[3] - 0 === i; } }, filter: { - PSEUDO: function(elem, match, i, array){ - var name = match[1], filter = Expr.filters[ name ]; + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; if ( filter ) { return filter( elem, i, match, array ); + } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0; + return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; + } else if ( name === "not" ) { var not = match[3]; - for ( var i = 0, l = not.length; i < l; i++ ) { - if ( not[i] === elem ) { + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { return false; } } return true; + + } else { + Sizzle.error( name ); } }, - CHILD: function(elem, match){ - var type = match[1], node = elem; - switch (type) { - case 'only': - case 'first': - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) return false; + + CHILD: function( elem, match ) { + var type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; } - if ( type == 'first') return true; + node = elem; - case 'last': - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) return false; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } } + return true; - case 'nth': - var first = match[2], last = match[3]; - if ( first == 1 && last == 0 ) { + case "nth": + var first = match[2], + last = match[3]; + + if ( first === 1 && last === 0 ) { return true; } @@ -4553,33 +5187,41 @@ var Expr = Sizzle.selectors = { if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { var count = 0; + for ( node = parent.firstChild; node; node = node.nextSibling ) { if ( node.nodeType === 1 ) { node.nodeIndex = ++count; } } + parent.sizcache = doneName; } var diff = elem.nodeIndex - last; - if ( first == 0 ) { - return diff == 0; + + if ( first === 0 ) { + return diff === 0; + } else { - return ( diff % first == 0 && diff / first >= 0 ); + return ( diff % first === 0 && diff / first >= 0 ); } } }, - ID: function(elem, match){ + + ID: function( elem, match ) { return elem.nodeType === 1 && elem.getAttribute("id") === match; }, - TAG: function(elem, match){ - return (match === "*" && elem.nodeType === 1) || elem.nodeName === match; + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; }, - CLASS: function(elem, match){ + + CLASS: function( elem, match ) { return (" " + (elem.className || elem.getAttribute("class")) + " ") .indexOf( match ) > -1; }, - ATTR: function(elem, match){ + + ATTR: function( elem, match ) { var name = match[1], result = Expr.attrHandle[ name ] ? Expr.attrHandle[ name ]( elem ) : @@ -4601,7 +5243,7 @@ var Expr = Sizzle.selectors = { !check ? value && result !== false : type === "!=" ? - value != check : + value !== check : type === "^=" ? value.indexOf(check) === 0 : type === "$=" ? @@ -4610,8 +5252,10 @@ var Expr = Sizzle.selectors = { value === check || value.substr(0, check.length + 1) === check + "-" : false; }, - POS: function(elem, match, i, array){ - var name = match[2], filter = Expr.setFilters[ name ]; + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; if ( filter ) { return filter( elem, i, match, array ); @@ -4620,14 +5264,17 @@ var Expr = Sizzle.selectors = { } }; -var origPOS = Expr.match.POS; +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source ); + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); } -var makeArray = function(array, results) { +var makeArray = function( array, results ) { array = Array.prototype.slice.call( array, 0 ); if ( results ) { @@ -4639,21 +5286,24 @@ var makeArray = function(array, results) { }; try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 ); + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; -} catch(e){ - makeArray = function(array, results) { - var ret = results || []; +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; if ( toString.call(array) === "[object Array]" ) { Array.prototype.push.apply( ret, array ); + } else { if ( typeof array.length === "number" ) { - for ( var i = 0, l = array.length; i < l; i++ ) { + for ( var l = array.length; i < l; i++ ) { ret.push( array[i] ); } + } else { - for ( var i = 0; array[i]; i++ ) { + for ( ; array[i]; i++ ) { ret.push( array[i] ); } } @@ -4663,84 +5313,143 @@ try { }; } -var sortOrder; +var sortOrder, siblingCheck; if ( document.documentElement.compareDocumentPosition ) { sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - if ( a == b ) { - hasDuplicate = true; - } + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; return 0; + + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + if ( aup === bup ) { + return siblingCheck( a, b ); + + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } } - var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); }; -} else if ( "sourceIndex" in document.documentElement ) { - sortOrder = function( a, b ) { - if ( !a.sourceIndex || !b.sourceIndex ) { - if ( a == b ) { - hasDuplicate = true; - } - return 0; - } - var ret = a.sourceIndex - b.sourceIndex; - if ( ret === 0 ) { - hasDuplicate = true; + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; } - return ret; - }; -} else if ( document.createRange ) { - sortOrder = function( a, b ) { - if ( !a.ownerDocument || !b.ownerDocument ) { - if ( a == b ) { - hasDuplicate = true; + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; } - return 0; - } - var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); - aRange.setStart(a, 0); - aRange.setEnd(a, 0); - bRange.setStart(b, 0); - bRange.setEnd(b, 0); - var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); - if ( ret === 0 ) { - hasDuplicate = true; + cur = cur.nextSibling; } - return ret; + + return 1; }; } +Sizzle.getText = function( elems ) { + var ret = "", elem; + + for ( var i = 0; elems[i]; i++ ) { + elem = elems[i]; + + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + } else if ( elem.nodeType !== 8 ) { + ret += Sizzle.getText( elem.childNodes ); + } + } + + return ret; +}; + (function(){ var form = document.createElement("div"), - id = "script" + (new Date).getTime(); + id = "script" + (new Date()).getTime(), + root = document.documentElement; + form.innerHTML = ""; - var root = document.documentElement; root.insertBefore( form, root.firstChild ); - if ( !!document.getElementById( id ) ) { - Expr.find.ID = function(match, context, isXML){ + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { if ( typeof context.getElementById !== "undefined" && !isXML ) { var m = context.getElementById(match[1]); - return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; } }; - Expr.filter.ID = function(elem, match){ + Expr.filter.ID = function( elem, match ) { var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return elem.nodeType === 1 && node && node.nodeValue === match; }; } root.removeChild( form ); - root = form = null; // release memory in IE + + root = form = null; })(); (function(){ @@ -4749,8 +5458,8 @@ if ( document.documentElement.compareDocumentPosition ) { div.appendChild( document.createComment("") ); if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function(match, context){ - var results = context.getElementsByTagName(match[1]); + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); if ( match[1] === "*" ) { var tmp = []; @@ -4769,77 +5478,177 @@ if ( document.documentElement.compareDocumentPosition ) { } div.innerHTML = ""; + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && div.firstChild.getAttribute("href") !== "#" ) { - Expr.attrHandle.href = function(elem){ - return elem.getAttribute("href", 2); + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); }; } - div = null; // release memory in IE + div = null; })(); -if ( document.querySelectorAll ) (function(){ - var oldSizzle = Sizzle, div = document.createElement("div"); - div.innerHTML = "

"; +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } + div.innerHTML = "

"; + + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + if ( !seed && !Sizzle.isXML(context) ) { + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + if ( elem && elem.parentNode ) { + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } - Sizzle = function(query, context, extra, seed){ - context = context || document; + return oldSizzle(query, context, extra, seed); + }; - if ( !seed && context.nodeType === 9 && !isXML(context) ) { - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(e){} + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; } - return oldSizzle(query, context, extra, seed); - }; + div = null; + })(); +} - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); - div = null; // release memory in IE + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + if ( ret || !disconnectedMatch || + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } })(); -if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){ +(function(){ var div = document.createElement("div"); + div.innerHTML = "
"; - if ( div.getElementsByClassName("e").length === 0 ) + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { return; + } div.lastChild.className = "e"; - if ( div.getElementsByClassName("e").length === 1 ) + if ( div.getElementsByClassName("e").length === 1 ) { return; + } Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function(match, context, isXML) { + Expr.find.CLASS = function( match, context, isXML ) { if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { return context.getElementsByClassName(match[1]); } }; - div = null; // release memory in IE + div = null; })(); function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - var sibDir = dir == "previousSibling" && !isXML; for ( var i = 0, l = checkSet.length; i < l; i++ ) { var elem = checkSet[i]; + if ( elem ) { - if ( sibDir && elem.nodeType === 1 ){ - elem.sizcache = doneName; - elem.sizset = i; - } - elem = elem[dir]; var match = false; + elem = elem[dir]; + while ( elem ) { if ( elem.sizcache === doneName ) { match = checkSet[elem.sizset]; @@ -4851,7 +5660,7 @@ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { elem.sizset = i; } - if ( elem.nodeName === cur ) { + if ( elem.nodeName.toLowerCase() === cur ) { match = elem; break; } @@ -4865,17 +5674,14 @@ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { } function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - var sibDir = dir == "previousSibling" && !isXML; for ( var i = 0, l = checkSet.length; i < l; i++ ) { var elem = checkSet[i]; + if ( elem ) { - if ( sibDir && elem.nodeType === 1 ) { - elem.sizcache = doneName; - elem.sizset = i; - } - elem = elem[dir]; var match = false; + elem = elem[dir]; + while ( elem ) { if ( elem.sizcache === doneName ) { match = checkSet[elem.sizset]; @@ -4887,6 +5693,7 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { elem.sizcache = doneName; elem.sizset = i; } + if ( typeof cur !== "string" ) { if ( elem === cur ) { match = true; @@ -4907,19 +5714,32 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { } } -var contains = document.compareDocumentPosition ? function(a, b){ - return a.compareDocumentPosition(b) & 16; -} : function(a, b){ - return a !== b && (a.contains ? a.contains(b) : true); -}; +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; -var isXML = function(elem){ - return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || - !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML"; +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; }; -var posProcess = function(selector, context){ - var tmpSet = [], later = "", match, +var posProcess = function( selector, context ) { + var match, + tmpSet = [], + later = "", root = context.nodeType ? [context] : context; while ( (match = Expr.match.PSEUDO.exec( selector )) ) { @@ -4941,6 +5761,8 @@ window.Sizzle = Sizzle; })(); +Prototype._original_property = window.Sizzle; + ;(function(engine) { var extendElements = Prototype.Selector.extendElements; @@ -4984,7 +5806,10 @@ var Form = { } else { initial = ''; accumulator = function(result, key, value) { - return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value); + value = value.gsub(/(\r)?\n/, '\r\n'); + value = encodeURIComponent(value); + value = value.gsub(/%20/, '+'); + return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + value; } } @@ -5006,19 +5831,16 @@ Form.Methods = { return Form.serializeElements(Form.getElements(form), options); }, + getElements: function(form) { - var elements = $(form).getElementsByTagName('*'), - element, - arr = [ ], - serializers = Form.Element.Serializers; + var elements = $(form).getElementsByTagName('*'); + var element, results = [], serializers = Form.Element.Serializers; + for (var i = 0; element = elements[i]; i++) { - arr.push(element); + if (serializers[element.tagName.toLowerCase()]) + results.push(Element.extend(element)); } - return arr.inject([], function(elements, child) { - if (serializers[child.tagName.toLowerCase()]) - elements.push(Element.extend(child)); - return elements; - }) + return results; }, getInputs: function(form, typeName, name) { @@ -5328,7 +6150,11 @@ Form.EventObserver = Class.create(Abstract.EventObserver, { return Form.serialize(this.element); } }); -(function() { +(function(GLOBAL) { + var DIV = document.createElement('div'); + var docEl = document.documentElement; + var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl + && 'onmouseleave' in docEl; var Event = { KEY_BACKSPACE: 8, @@ -5344,16 +6170,9 @@ Form.EventObserver = Class.create(Abstract.EventObserver, { KEY_END: 35, KEY_PAGEUP: 33, KEY_PAGEDOWN: 34, - KEY_INSERT: 45, - - cache: {} + KEY_INSERT: 45 }; - var docEl = document.documentElement; - var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl - && 'onmouseleave' in docEl; - - var isIELegacyEvent = function(event) { return false; }; @@ -5409,6 +6228,10 @@ Form.EventObserver = Class.create(Abstract.EventObserver, { function isRightClick(event) { return _isButton(event, 2) } function element(event) { + return Element.extend(_element(event)); + } + + function _element(event) { event = Event.extend(event); var node = event.target, type = event.type, @@ -5428,13 +6251,11 @@ Form.EventObserver = Class.create(Abstract.EventObserver, { } function findElement(event, expression) { - var element = Event.element(event); - - if (!expression) return element; + var element = _element(event), match = Prototype.Selector.match; + if (!expression) return Element.extend(element); while (element) { - if (Object.isElement(element) && Prototype.Selector.match(element, expression)) { + if (Object.isElement(element) && match(element, expression)) return Element.extend(element); - } element = element.parentNode; } } @@ -5546,198 +6367,253 @@ Form.EventObserver = Class.create(Abstract.EventObserver, { Object.extend(Event.prototype, methods); } - function _createResponder(element, eventName, handler) { - var registry = Element.retrieve(element, 'prototype_event_registry'); + var EVENT_TRANSLATIONS = { + mouseenter: 'mouseover', + mouseleave: 'mouseout' + }; - if (Object.isUndefined(registry)) { - CACHE.push(element); - registry = Element.retrieve(element, 'prototype_event_registry', $H()); - } + function getDOMEventName(eventName) { + return EVENT_TRANSLATIONS[eventName] || eventName; + } - var respondersForEvent = registry.get(eventName); - if (Object.isUndefined(respondersForEvent)) { - respondersForEvent = []; - registry.set(eventName, respondersForEvent); - } + if (MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) + getDOMEventName = Prototype.K; + + function getUniqueElementID(element) { + if (element === window) return 0; + + if (typeof element._prototypeUID === 'undefined') + element._prototypeUID = Element.Storage.UID++; + return element._prototypeUID; + } - if (respondersForEvent.pluck('handler').include(handler)) return false; + function getUniqueElementID_IE(element) { + if (element === window) return 0; + if (element == document) return 1; + return element.uniqueID; + } - var responder; - if (eventName.include(":")) { - responder = function(event) { - if (Object.isUndefined(event.eventName)) - return false; + if ('uniqueID' in DIV) + getUniqueElementID = getUniqueElementID_IE; - if (event.eventName !== eventName) - return false; + function isCustomEvent(eventName) { + return eventName.include(':'); + } - 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); - - var parent = event.relatedTarget; - while (parent && parent !== element) { - try { parent = parent.parentNode; } - catch(e) { parent = element; } - } - - if (parent === element) return; - - handler.call(element, event); - }; - } - } else { - responder = function(event) { - Event.extend(event, element); - handler.call(element, event); - }; - } - } + Event._isCustomEvent = isCustomEvent; - responder.handler = handler; - respondersForEvent.push(responder); - return responder; + function getRegistryForElement(element, uid) { + var CACHE = GLOBAL.Event.cache; + if (Object.isUndefined(uid)) + uid = getUniqueElementID(element); + if (!CACHE[uid]) CACHE[uid] = { element: element }; + return CACHE[uid]; } - function _destroyCache() { - for (var i = 0, length = CACHE.length; i < length; i++) { - Event.stopObserving(CACHE[i]); - CACHE[i] = null; - } + function destroyRegistryForElement(element, uid) { + if (Object.isUndefined(uid)) + uid = getUniqueElementID(element); + delete GLOBAL.Event.cache[uid]; } - var CACHE = []; - if (Prototype.Browser.IE) - window.attachEvent('onunload', _destroyCache); + function register(element, eventName, handler) { + var registry = getRegistryForElement(element); + if (!registry[eventName]) registry[eventName] = []; + var entries = registry[eventName]; - if (Prototype.Browser.WebKit) - window.addEventListener('unload', Prototype.emptyFunction, false); + var i = entries.length; + while (i--) + if (entries[i].handler === handler) return null; + + var uid = getUniqueElementID(element); + var responder = GLOBAL.Event._createResponder(uid, eventName, handler); + var entry = { + responder: responder, + handler: handler + }; + entries.push(entry); + return entry; + } - var _getDOMEventName = Prototype.K, - translations = { mouseenter: "mouseover", mouseleave: "mouseout" }; + function unregister(element, eventName, handler) { + var registry = getRegistryForElement(element); + var entries = registry[eventName]; + if (!entries) return; - if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) { - _getDOMEventName = function(eventName) { - return (translations[eventName] || eventName); - }; + var i = entries.length, entry; + while (i--) { + if (entries[i].handler === handler) { + entry = entries[i]; + break; + } + } + + if (!entry) return; + + var index = entries.indexOf(entry); + entries.splice(index, 1); + + return entry; } + function observe(element, eventName, handler) { element = $(element); + var entry = register(element, eventName, handler); - var responder = _createResponder(element, eventName, handler); + if (entry === null) return element; - if (!responder) return element; + var responder = entry.responder; + if (isCustomEvent(eventName)) + observeCustomEvent(element, eventName, responder); + else + observeStandardEvent(element, eventName, responder); - if (eventName.include(':')) { - if (element.addEventListener) - element.addEventListener("dataavailable", responder, false); - else { - element.attachEvent("ondataavailable", responder); - element.attachEvent("onlosecapture", responder); - } - } else { - var actualEventName = _getDOMEventName(eventName); + return element; + } - if (element.addEventListener) - element.addEventListener(actualEventName, responder, false); - else - element.attachEvent("on" + actualEventName, responder); + function observeStandardEvent(element, eventName, responder) { + var actualEventName = getDOMEventName(eventName); + if (element.addEventListener) { + element.addEventListener(actualEventName, responder, false); + } else { + element.attachEvent('on' + actualEventName, responder); } + } - return element; + function observeCustomEvent(element, eventName, responder) { + if (element.addEventListener) { + element.addEventListener('dataavailable', responder, false); + } else { + element.attachEvent('ondataavailable', responder); + element.attachEvent('onlosecapture', responder); + } } function stopObserving(element, eventName, handler) { element = $(element); + var handlerGiven = !Object.isUndefined(handler), + eventNameGiven = !Object.isUndefined(eventName); - var registry = Element.retrieve(element, 'prototype_event_registry'); - if (!registry) return element; - - if (!eventName) { - registry.each( function(pair) { - var eventName = pair.key; - stopObserving(element, eventName); - }); + if (!eventNameGiven && !handlerGiven) { + stopObservingElement(element); return element; } - var responders = registry.get(eventName); - if (!responders) return element; - - if (!handler) { - responders.each(function(r) { - stopObserving(element, eventName, r.handler); - }); + if (!handlerGiven) { + stopObservingEventName(element, eventName); return element; } - var i = responders.length, responder; - while (i--) { - if (responders[i].handler === handler) { - responder = responders[i]; - break; - } + var entry = unregister(element, eventName, handler); + + if (!entry) return element; + removeEvent(element, eventName, entry.responder); + return element; + } + + function stopObservingStandardEvent(element, eventName, responder) { + var actualEventName = getDOMEventName(eventName); + if (element.removeEventListener) { + element.removeEventListener(actualEventName, responder, false); + } else { + element.detachEvent('on' + actualEventName, responder); } - if (!responder) return element; + } - if (eventName.include(':')) { - if (element.removeEventListener) - element.removeEventListener("dataavailable", responder, false); - else { - element.detachEvent("ondataavailable", responder); - element.detachEvent("onlosecapture", responder); - } + function stopObservingCustomEvent(element, eventName, responder) { + if (element.removeEventListener) { + element.removeEventListener('dataavailable', responder, false); } else { - var actualEventName = _getDOMEventName(eventName); - if (element.removeEventListener) - element.removeEventListener(actualEventName, responder, false); - else - element.detachEvent('on' + actualEventName, responder); + element.detachEvent('ondataavailable', responder); + element.detachEvent('onlosecapture', responder); } + } - registry.set(eventName, responders.without(responder)); - return element; - } - function fire(element, eventName, memo, bubble) { - element = $(element); + function stopObservingElement(element) { + var uid = getUniqueElementID(element), + registry = getRegistryForElement(element, uid); - if (Object.isUndefined(bubble)) - bubble = true; + destroyRegistryForElement(element, uid); - if (element == document && document.createEvent && !element.dispatchEvent) - element = document.documentElement; + var entries, i; + for (var eventName in registry) { + if (eventName === 'element') continue; - var event; - if (document.createEvent) { - event = document.createEvent('HTMLEvents'); - event.initEvent('dataavailable', bubble, true); - } else { - event = document.createEventObject(); - event.eventType = bubble ? 'ondataavailable' : 'onlosecapture'; + entries = registry[eventName]; + i = entries.length; + while (i--) + removeEvent(element, eventName, entries[i].responder); } + } - event.eventName = eventName; - event.memo = memo || { }; + function stopObservingEventName(element, eventName) { + var registry = getRegistryForElement(element); + var entries = registry[eventName]; + if (!entries) return; + delete registry[eventName]; - if (document.createEvent) - element.dispatchEvent(event); + var i = entries.length; + while (i--) + removeEvent(element, eventName, entries[i].responder); + } + + + function removeEvent(element, eventName, handler) { + if (isCustomEvent(eventName)) + stopObservingCustomEvent(element, eventName, handler); else - element.fireEvent(event.eventType, event); + stopObservingStandardEvent(element, eventName, handler); + } + + + + function getFireTarget(element) { + if (element !== document) return element; + if (document.createEvent && !element.dispatchEvent) + return document.documentElement; + return element; + } + + function fire(element, eventName, memo, bubble) { + element = getFireTarget($(element)); + if (Object.isUndefined(bubble)) bubble = true; + memo = memo || {}; + var event = fireEvent(element, eventName, memo, bubble); return Event.extend(event); } + function fireEvent_DOM(element, eventName, memo, bubble) { + var event = document.createEvent('HTMLEvents'); + event.initEvent('dataavailable', bubble, true); + + event.eventName = eventName; + event.memo = memo; + + element.dispatchEvent(event); + return event; + } + + function fireEvent_IE(element, eventName, memo, bubble) { + var event = document.createEventObject(); + event.eventType = bubble ? 'ondataavailable' : 'onlosecapture'; + + event.eventName = eventName; + event.memo = memo; + + element.fireEvent(event.eventType, event); + return event; + } + + var fireEvent = document.createEvent ? fireEvent_DOM : fireEvent_IE; + + + Event.Handler = Class.create({ initialize: function(element, eventName, selector, callback) { this.element = $(element); @@ -5747,6 +6623,7 @@ Form.EventObserver = Class.create(Abstract.EventObserver, { this.handler = this.handleEvent.bind(this); }, + start: function() { Event.observe(this.element, this.eventName, this.handler); return this; @@ -5803,52 +6680,129 @@ Form.EventObserver = Class.create(Abstract.EventObserver, { loaded: false }); - if (window.Event) Object.extend(window.Event, Event); - else window.Event = Event; -})(); + if (GLOBAL.Event) Object.extend(window.Event, Event); + else GLOBAL.Event = Event; -(function() { + GLOBAL.Event.cache = {}; + + function destroyCache_IE() { + GLOBAL.Event.cache = null; + } + + if (window.attachEvent) + window.attachEvent('onunload', destroyCache_IE); + + DIV = null; + docEl = null; +})(this); + +(function(GLOBAL) { + /* Code for creating leak-free event responders is based on work by + John-David Dalton. */ + + var docEl = document.documentElement; + var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl + && 'onmouseleave' in docEl; + + function isSimulatedMouseEnterLeaveEvent(eventName) { + return !MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && + (eventName === 'mouseenter' || eventName === 'mouseleave'); + } + + function createResponder(uid, eventName, handler) { + if (Event._isCustomEvent(eventName)) + return createResponderForCustomEvent(uid, eventName, handler); + if (isSimulatedMouseEnterLeaveEvent(eventName)) + return createMouseEnterLeaveResponder(uid, eventName, handler); + + return function(event) { + var cacheEntry = Event.cache[uid]; + var element = cacheEntry.element; + + Event.extend(event, element); + handler.call(element, event); + }; + } + + function createResponderForCustomEvent(uid, eventName, handler) { + return function(event) { + var cacheEntry = Event.cache[uid], element = cacheEntry.element; + + if (Object.isUndefined(event.eventName)) + return false; + + if (event.eventName !== eventName) + return false; + + Event.extend(event, element); + handler.call(element, event); + }; + } + + function createMouseEnterLeaveResponder(uid, eventName, handler) { + return function(event) { + var cacheEntry = Event.cache[uid], element = cacheEntry.element; + + Event.extend(event, element); + var parent = event.relatedTarget; + + while (parent && parent !== element) { + try { parent = parent.parentNode; } + catch(e) { parent = element; } + } + + if (parent === element) return; + handler.call(element, event); + } + } + + GLOBAL.Event._createResponder = createResponder; + docEl = null; +})(this); + +(function(GLOBAL) { /* Support for the DOMContentLoaded event is based on work by Dan Webb, Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ - var timer; + var TIMER; function fireContentLoadedEvent() { if (document.loaded) return; - if (timer) window.clearTimeout(timer); + if (TIMER) window.clearTimeout(TIMER); document.loaded = true; document.fire('dom:loaded'); } function checkReadyState() { if (document.readyState === 'complete') { - document.stopObserving('readystatechange', checkReadyState); + document.detachEvent('onreadystatechange', checkReadyState); fireContentLoadedEvent(); } } function pollDoScroll() { - try { document.documentElement.doScroll('left'); } - catch(e) { - timer = pollDoScroll.defer(); + try { + document.documentElement.doScroll('left'); + } catch (e) { + TIMER = pollDoScroll.defer(); return; } + fireContentLoadedEvent(); } if (document.addEventListener) { document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false); } else { - document.observe('readystatechange', checkReadyState); - if (window == top) - timer = pollDoScroll.defer(); + document.attachEvent('onreadystatechange', checkReadyState); + if (window == top) TIMER = pollDoScroll.defer(); } Event.observe(window, 'load', fireContentLoadedEvent); -})(); +})(this); -Element.addMethods(); +Element.addMethods(); /*------------------------------- DEPRECATED -------------------------------*/ Hash.toQueryString = Object.toQueryString; @@ -5997,10 +6951,10 @@ Element.ClassNames.prototype = { this.element = $(element); }, - _each: function(iterator) { + _each: function(iterator, context) { this.element.className.split(/\s+/).select(function(name) { return name.length > 0; - })._each(iterator); + })._each(iterator, context); }, set: function(className) { -- cgit v1.2.3