0
-/* Prototype JavaScript framework, version 1.6.0
_rc00
+/* Prototype JavaScript framework, version 1.6.0
.20
* (c) 2005-2007 Sam Stephenson
0
* Prototype is freely distributable under the terms of an MIT-style license.
0
*--------------------------------------------------------------------------*/
0
IE: !!(window.attachEvent && !window.opera),
0
@@ -19,10 +19,12 @@ var Prototype = {
0
XPath: !!document.evaluate,
0
+ SelectorsAPI: !!document.querySelector,
0
ElementExtensions: !!window.HTMLElement,
0
SpecificElementExtensions:
0
+ document.createElement('div').__proto__ &&
0
document.createElement('div').__proto__ !==
0
-
document.createElement('form').__proto__
0
+
document.createElement('form').__proto__
0
ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
0
@@ -35,6 +37,7 @@ var Prototype = {
0
if (Prototype.Browser.MobileSafari)
0
Prototype.BrowserFeatures.SpecificElementExtensions = false;
0
/* Based on Alex Arnell's inheritance implementation. */
0
@@ -71,10 +74,14 @@ var Class = {
0
addMethods: function(source) {
0
- var ancestor = this.superclass && this.superclass.prototype;
0
+ var ancestor = this.superclass && this.superclass.prototype;
0
+ var properties = Object.keys(source);
0
+ if (!Object.keys({ toString: true }).length)
0
+ properties.push("toString", "valueOf");
0
- for (var property in source) {
0
- var value = source[property];
0
+ for (var i = 0, length = properties.length; i < length; i++) {
0
+ var property = properties[i], value = source[property];
0
if (ancestor && Object.isFunction(value) &&
0
value.argumentNames().first() == "$super") {
0
var method = value, value = Object.extend((function(m) {
0
@@ -102,9 +109,9 @@ Object.extend = function(destination, source) {
0
Object.extend(Object, {
0
inspect: function(object) {
0
- if (
object === undefined) return 'undefined';
0
+ if (
Object.isUndefined(object)) return 'undefined';
0
if (object === null) return 'null';
0
- return object.inspect ? object.inspect() :
object.toString();
0
+ return object.inspect ? object.inspect() :
String(object);
0
if (e instanceof RangeError) return '...';
0
@@ -127,7 +134,7 @@ Object.extend(Object, {
0
for (var property in object) {
0
var value = Object.toJSON(object[property]);
0
- if (
value !== undefined)
0
+ if (
!Object.isUndefined(value))
0
results.push(property.toJSON() + ': ' + value);
0
@@ -165,7 +172,12 @@ Object.extend(Object, {
0
isArray: function(object) {
0
- return object && object.constructor === Array;
0
+ return object != null && typeof object == "object" &&
0
+ 'splice' in object && 'join' in object;
0
+ isHash: function(object) {
0
+ return object instanceof Hash;
0
isFunction: function(object) {
0
@@ -187,12 +199,12 @@ Object.extend(Object, {
0
Object.extend(Function.prototype, {
0
argumentNames: function() {
0
- var names = this.toString().match(/^[\s\(]*function
\s*\((.*?)\)/)[1].split(",").invoke("strip");
0
+ var names = this.toString().match(/^[\s\(]*function
[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
0
return names.length == 1 && !names[0] ? [] : names;
0
- if (arguments.length < 2 &&
arguments[0] === undefined) return this;
0
+ if (arguments.length < 2 &&
Object.isUndefined(arguments[0])) return this;
0
var __method = this, args = $A(arguments), object = args.shift();
0
return __method.apply(object, args.concat($A(arguments)));
0
@@ -339,7 +351,7 @@ Object.extend(String.prototype, {
0
sub: function(pattern, replacement, count) {
0
replacement = this.gsub.prepareReplacement(replacement);
0
- count =
count === undefined ? 1 : count;
0
+ count =
Object.isUndefined(count) ? 1 : count;
0
return this.gsub(pattern, function(match) {
0
if (--count < 0) return match[0];
0
@@ -354,7 +366,7 @@ Object.extend(String.prototype, {
0
truncate: function(length, truncation) {
0
- truncation =
truncation === undefined ? '...' : truncation;
0
+ truncation =
Object.isUndefined(truncation) ? '...' : truncation;
0
return this.length > length ?
0
this.slice(0, length - truncation.length) + truncation : String(this);
0
@@ -427,9 +439,7 @@ Object.extend(String.prototype, {
0
times: function(count) {
0
- for (var i = 0; i < count; i++) result += this;
0
+ return count < 1 ? '' : new Array(count + 1).join(this);
0
@@ -476,7 +486,9 @@ Object.extend(String.prototype, {
0
- var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
0
+ if (str.blank()) return false;
0
+ str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
0
return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
0
@@ -519,7 +531,7 @@ if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.proto
0
return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
0
unescapeHTML: function() {
0
- return this.
replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
0
+ return this.
stripTags().replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
0
@@ -536,7 +548,7 @@ Object.extend(String.prototype.escapeHTML, {
0
text: document.createTextNode('')
0
-
with (String.prototype.escapeHTML) div.appendChild(text);
0
+
String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);
0
var Template = Class.create({
0
initialize: function(template, pattern) {
0
@@ -555,8 +567,9 @@ var Template = Class.create({
0
if (before == '\\') return match[2];
0
var ctx = object, expr = match[3];
0
- var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr);
0
- if (match == null) return '';
0
+ var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
0
+ match = pattern.exec(expr);
0
+ if (match == null) return before;
0
while (match != null) {
0
var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
0
@@ -567,7 +580,7 @@ var Template = Class.create({
0
return before + String.interpret(ctx);
0
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
0
@@ -577,10 +590,9 @@ var $break = { };
0
each: function(iterator, context) {
0
- iterator = iterator.bind(context);
0
this._each(function(value) {
0
- iterator
(value, index++);
0
+ iterator
.call(context, value, index++);
0
if (e != $break) throw e;
0
@@ -589,47 +601,46 @@ var Enumerable = {
0
eachSlice: function(number, iterator, context) {
0
- iterator = iterator ? iterator.bind(context) : Prototype.K;
0
var index = -number, slices = [], array = this.toArray();
0
+ if (number < 1) return array;
0
while ((index += number) < array.length)
0
slices.push(array.slice(index, index+number));
0
return slices.collect(iterator, context);
0
all: function(iterator, context) {
0
- iterator = iterator
? iterator.bind(context) : Prototype.K;
0
+ iterator = iterator
|| Prototype.K;
0
this.each(function(value, index) {
0
- result = result && !!iterator
(value, index);
0
+ result = result && !!iterator
.call(context, value, index);
0
if (!result) throw $break;
0
any: function(iterator, context) {
0
- iterator = iterator
? iterator.bind(context) : Prototype.K;
0
+ iterator = iterator
|| Prototype.K;
0
this.each(function(value, index) {
0
- if (result = !!iterator
(value, index))
0
+ if (result = !!iterator
.call(context, value, index))
0
collect: function(iterator, context) {
0
- iterator = iterator
? iterator.bind(context) : Prototype.K;
0
+ iterator = iterator
|| Prototype.K;
0
this.each(function(value, index) {
0
- results.push(iterator
(value, index));
0
+ results.push(iterator
.call(context, value, index));
0
detect: function(iterator, context) {
0
- iterator = iterator.bind(context);
0
this.each(function(value, index) {
0
- if (iterator
(value, index)) {
0
+ if (iterator
.call(context, value, index)) {
0
@@ -638,17 +649,16 @@ var Enumerable = {
0
findAll: function(iterator, context) {
0
- iterator = iterator.bind(context);
0
this.each(function(value, index) {
0
- if (iterator
(value, index))
0
+ if (iterator
.call(context, value, index))
0
grep: function(filter, iterator, context) {
0
- iterator = iterator
? iterator.bind(context) : Prototype.K;
0
+ iterator = iterator
|| Prototype.K;
0
if (Object.isString(filter))
0
@@ -656,7 +666,7 @@ var Enumerable = {
0
this.each(function(value, index) {
0
if (filter.match(value))
0
- results.push(iterator
(value, index));
0
+ results.push(iterator
.call(context, value, index));
0
@@ -676,7 +686,7 @@ var Enumerable = {
0
inGroupsOf: function(number, fillWith) {
0
- fillWith =
fillWith === undefined ? null : fillWith;
0
+ fillWith =
Object.isUndefined(fillWith) ? null : fillWith;
0
return this.eachSlice(number, function(slice) {
0
while(slice.length < number) slice.push(fillWith);
0
@@ -684,9 +694,8 @@ var Enumerable = {
0
inject: function(memo, iterator, context) {
0
- iterator = iterator.bind(context);
0
this.each(function(value, index) {
0
- memo = iterator
(memo, value, index);
0
+ memo = iterator
.call(context, memo, value, index);
0
@@ -699,32 +708,32 @@ var Enumerable = {
0
max: function(iterator, context) {
0
- iterator = iterator
? iterator.bind(context) : Prototype.K;
0
+ iterator = iterator
|| Prototype.K;
0
this.each(function(value, index) {
0
- value = iterator(value, index);
0
- if (result == undefined || value >= result)
0
+ value = iterator.call(context, value, index);
0
+ if (result == null || value >= result)
0
min: function(iterator, context) {
0
- iterator = iterator
? iterator.bind(context) : Prototype.K;
0
+ iterator = iterator
|| Prototype.K;
0
this.each(function(value, index) {
0
- value = iterator(value, index);
0
- if (result == undefined || value < result)
0
+ value = iterator.call(context, value, index);
0
+ if (result == null || value < result)
0
partition: function(iterator, context) {
0
- iterator = iterator
? iterator.bind(context) : Prototype.K;
0
+ iterator = iterator
|| Prototype.K;
0
var trues = [], falses = [];
0
this.each(function(value, index) {
0
- (iterator
(value, index) ?
0
+ (iterator
.call(context, value, index) ?
0
trues : falses).push(value);
0
return [trues, falses];
0
@@ -739,19 +748,20 @@ var Enumerable = {
0
reject: function(iterator, context) {
0
- iterator = iterator.bind(context);
0
this.each(function(value, index) {
0
- if (!iterator
(value, index))
0
+ if (!iterator
.call(context, value, index))
0
sortBy: function(iterator, context) {
0
- iterator = iterator.bind(context);
0
return this.map(function(value, index) {
0
- return {value: value, criteria: iterator(value, index)};
0
+ criteria: iterator.call(context, value, index)
0
}).sort(function(left, right) {
0
var a = left.criteria, b = right.criteria;
0
return a < b ? -1 : a > b ? 1 : 0;
0
@@ -795,27 +805,20 @@ Object.extend(Enumerable, {
0
function $A(iterable) {
0
if (!iterable) return [];
0
if (iterable.toArray) return iterable.toArray();
0
- for (var i = 0, length = iterable.length; i < length; i++)
0
- results.push(iterable[i]);
0
+ var length = iterable.length || 0, results = new Array(length);
0
+ while (length--) results[length] = iterable[length];
0
if (Prototype.Browser.WebKit) {
0
-
function $A(iterable) {
0
+
$A = function(iterable) {
0
if (!iterable) return [];
0
if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
0
- return iterable.toArray();
0
- for (var i = 0, length = iterable.length; i < length; i++)
0
- results.push(iterable[i]);
0
+ iterable.toArray) return iterable.toArray();
0
+ var length = iterable.length || 0, results = new Array(length);
0
+ while (length--) results[length] = iterable[length];
0
@@ -901,7 +904,7 @@ Object.extend(Array.prototype, {
0
this.each(function(object) {
0
var value = Object.toJSON(object);
0
- if (
value !== undefined) results.push(value);
0
+ if (
!Object.isUndefined(value)) results.push(value);
0
return '[' + results.join(', ') + ']';
0
@@ -929,6 +932,7 @@ if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i
0
Array.prototype.toArray = Array.prototype.clone;
0
+ if (!Object.isString(string)) return [];
0
string = string.strip();
0
return string ? string.split(/\s+/) : [];
0
@@ -980,34 +984,6 @@ function $H(object) {
0
var Hash = Class.create(Enumerable, (function() {
0
- var i = 0, Test = function(value) { this.key = value };
0
- Test.prototype.key = 'foo';
0
- for (var property in new Test('bar')) i++;
0
- function each(iterator) {
0
- for (var key in this._object) {
0
- var value = this._object[key];
0
- if (cache.include(key)) continue;
0
- var pair = [key, value];
0
- function each(iterator) {
0
- for (var key in this._object) {
0
- var value = this._object[key], pair = [key, value];
0
function toQueryPair(key, value) {
0
if (Object.isUndefined(value)) return key;
0
@@ -1016,10 +992,17 @@ var Hash = Class.create(Enumerable, (function() {
0
initialize: function(object) {
0
- this._object =
object instanceof Hash ? object.toObject() : Object.clone(object);
0
+ this._object =
Object.isHash(object) ? object.toObject() : Object.clone(object);
0
+ _each: function(iterator) {
0
+ for (var key in this._object) {
0
+ var value = this._object[key], pair = [key, value];
0
set: function(key, value) {
0
return this._object[key] = value;
0
@@ -1066,14 +1049,14 @@ var Hash = Class.create(Enumerable, (function() {
0
toQueryString: function() {
0
- return this.
map(function(pair) {
0
+ return this.
inject([], function(results, pair) {
0
var key = encodeURIComponent(pair.key), values = pair.value;
0
if (values && typeof values == 'object') {
0
if (Object.isArray(values))
0
- return values.map(toQueryPair.curry(key)).join('&');
0
- return toQueryPair(key, values);
0
+ return results.concat(values.map(toQueryPair.curry(key)));
0
+ } else results.push(toQueryPair(key, values));
0
@@ -1093,6 +1076,7 @@ var Hash = Class.create(Enumerable, (function() {
0
+Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
0
var ObjectRange = Class.create(Enumerable, {
0
initialize: function(start, end, exclusive) {
0
@@ -1182,8 +1166,11 @@ Ajax.Base = Class.create({
0
Object.extend(this.options, options || { });
0
this.options.method = this.options.method.toLowerCase();
0
if (Object.isString(this.options.parameters))
0
this.options.parameters = this.options.parameters.toQueryParams();
0
+ else if (Object.isHash(this.options.parameters))
0
+ this.options.parameters = this.options.parameters.toObject();
0
@@ -1310,7 +1297,7 @@ Ajax.Request = Class.create(Ajax.Base, {
0
var contentType = response.getHeader('Content-type');
0
if (this.options.evalJS == 'force'
0
- || (this.options.evalJS &&
contentType
0
+ || (this.options.evalJS &&
this.isSameOrigin() && contentType
0
&& contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
0
@@ -1328,9 +1315,18 @@ Ajax.Request = Class.create(Ajax.Base, {
0
+ isSameOrigin: function() {
0
+ var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
0
+ return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
0
+ protocol: location.protocol,
0
+ domain: document.domain,
0
+ port: location.port ? ':' + location.port : ''
0
getHeader: function(name) {
0
- return this.transport.getResponseHeader(name)
;
0
+ return this.transport.getResponseHeader(name)
|| null;
0
} catch (e) { return null }
0
@@ -1366,7 +1362,7 @@ Ajax.Response = Class.create({
0
var xml = transport.responseXML;
0
- this.responseXML =
xml === undefined ? null : xml;
0
+ this.responseXML =
Object.isUndefined(xml) ? null : xml;
0
this.responseJSON = this._getResponseJSON();
0
@@ -1400,8 +1396,11 @@ Ajax.Response = Class.create({
0
_getHeaderJSON: function() {
0
var json = this.getHeader('X-JSON');
0
+ if (!json) return null;
0
+ json = decodeURIComponent(escape(json));
0
- return json ? json.evalJSON(this.request.options.sanitizeJSON) : null;
0
+ return json.evalJSON(this.request.options.sanitizeJSON ||
0
+ !this.request.isSameOrigin());
0
this.request.dispatchException(e);
0
@@ -1409,11 +1408,13 @@ Ajax.Response = Class.create({
0
_getResponseJSON: function() {
0
var options = this.request.options;
0
+ if (!options.evalJSON || (options.evalJSON != 'force' &&
0
+ !(this.getHeader('Content-type') || '').include('application/json')) ||
0
+ this.responseText.blank())
0
- if (options.evalJSON == 'force' || (options.evalJSON &&
0
- (this.getHeader('Content-type') || '').include('application/json')))
0
- return this.transport.responseText.evalJSON(options.sanitizeJSON);
0
+ return this.responseText.evalJSON(options.sanitizeJSON ||
0
+ !this.request.isSameOrigin());
0
this.request.dispatchException(e);
0
@@ -1427,11 +1428,11 @@ Ajax.Updater = Class.create(Ajax.Request, {
0
failure: (container.failure || (container.success ? null : container))
0
- options =
options || { };
0
+ options =
Object.clone(options);
0
var onComplete = options.onComplete;
0
- options.onComplete = (function(response,
param) {
0
+ options.onComplete = (function(response,
json) {
0
this.updateContent(response.responseText);
0
- if (Object.isFunction(onComplete)) onComplete(response,
param);
0
+ if (Object.isFunction(onComplete)) onComplete(response,
json);
0
@@ -1453,10 +1454,6 @@ Ajax.Updater = Class.create(Ajax.Request, {
0
else receiver.update(responseText);
0
- if (this.onComplete) this.onComplete.bind(this).defer();
0
@@ -1559,6 +1556,7 @@ if (!Node.ELEMENT_NODE) {
0
return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
0
Object.extend(this.Element, element || { });
0
+ if (element) this.Element.prototype = element.prototype;
0
@@ -1621,24 +1619,28 @@ Element.Methods = {
0
Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
0
insertions = {bottom:insertions};
0
- var content,
t, range;
0
+ var content,
insert, tagName, childNodes;
0
- for (
position in insertions) {
0
+ for (
var position in insertions) {
0
content = insertions[position];
0
position = position.toLowerCase();
0
-
t = Element._insertionTranslations[position];
0
+
insert = Element._insertionTranslations[position];
0
if (content && content.toElement) content = content.toElement();
0
if (Object.isElement(content)) {
0
-
t.insert(element, content);
0
+
insert(element, content);
0
content = Object.toHTML(content);
0
- range = element.ownerDocument.createRange();
0
- t.initializeRange(element, range);
0
- t.insert(element, range.createContextualFragment(content.stripScripts()));
0
+ tagName = ((position == 'before' || position == 'after')
0
+ ? element.parentNode : element).tagName.toUpperCase();
0
+ childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
0
+ if (position == 'top' || position == 'after') childNodes.reverse();
0
+ childNodes.each(insert.curry(element));
0
content.evalScripts.bind(content).defer();
0
@@ -1683,7 +1685,7 @@ Element.Methods = {
0
descendants: function(element) {
0
- return $
A($(element).getElementsByTagName('*')).each(Element.extend);
0
+ return $
(element).select("*");
0
firstDescendant: function(element) {
0
@@ -1722,32 +1724,31 @@ Element.Methods = {
0
if (arguments.length == 1) return $(element.parentNode);
0
var ancestors = element.ancestors();
0
- return expression ? Selector.findElement(ancestors, expression, index) :
0
- ancestors[index || 0];
0
+ return Object.isNumber(expression) ? ancestors[expression] :
0
+ Selector.findElement(ancestors, expression, index);
0
down: function(element, expression, index) {
0
if (arguments.length == 1) return element.firstDescendant();
0
- var descendants = element.descendants();
0
- return expression ? Selector.findElement(descendants, expression, index) :
0
- descendants[index || 0];
0
+ return Object.isNumber(expression) ? element.descendants()[expression] :
0
+ element.select(expression)[index || 0];
0
previous: function(element, expression, index) {
0
if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
0
var previousSiblings = element.previousSiblings();
0
- return expression ? Selector.findElement(previousSiblings, expression, index) :
0
- previousSiblings[index || 0];
0
+ return Object.isNumber(expression) ? previousSiblings[expression] :
0
+ Selector.findElement(previousSiblings, expression, index);
0
next: function(element, expression, index) {
0
if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
0
var nextSiblings = element.nextSiblings();
0
- return expression ? Selector.findElement(nextSiblings, expression, index) :
0
- nextSiblings[index || 0];
0
+ return Object.isNumber(expression) ? nextSiblings[expression] :
0
+ Selector.findElement(nextSiblings, expression, index);
0
@@ -1788,10 +1789,11 @@ Element.Methods = {
0
var attributes = { }, t = Element._attributeTranslations.write;
0
if (typeof name == 'object') attributes = name;
0
- else attributes[name] =
value === undefined ? true : value;
0
+ else attributes[name] =
Object.isUndefined(value) ? true : value;
0
for (var attr in attributes) {
0
- var name = t.names[attr] || attr, value = attributes[attr];
0
+ name = t.names[attr] || attr;
0
+ value = attributes[attr];
0
if (t.values[attr]) name = t.values[attr](element, value);
0
if (value === false || value === null)
0
element.removeAttribute(name);
0
@@ -1818,7 +1820,7 @@ Element.Methods = {
0
if (!(element = $(element))) return;
0
var elementClassName = element.className;
0
return (elementClassName.length > 0 && (elementClassName == className ||
0
-
elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))));
0
+
new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
0
addClassName: function(element, className) {
0
@@ -1860,8 +1862,16 @@ Element.Methods = {
0
descendantOf: function(element, ancestor) {
0
element = $(element), ancestor = $(ancestor);
0
+ if (element.compareDocumentPosition)
0
+ return (element.compareDocumentPosition(ancestor) & 8) === 8;
0
+ if (ancestor.contains)
0
+ return ancestor.contains(element) && ancestor !== element;
0
while (element = element.parentNode)
0
if (element == ancestor) return true;
0
@@ -1900,7 +1910,7 @@ Element.Methods = {
0
if (property == 'opacity') element.setOpacity(styles[property]);
0
elementStyle[(property == 'float' || property == 'cssFloat') ?
0
- (
elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
0
+ (
Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
0
property] = styles[property];
0
@@ -1915,7 +1925,7 @@ Element.Methods = {
0
getDimensions: function(element) {
0
- var display =
$(element).getStyle('display');
0
+ var display =
element.getStyle('display');
0
if (display != 'none' && display != null) // Safari bug
0
return {width: element.offsetWidth, height: element.offsetHeight};
0
@@ -1968,8 +1978,8 @@ Element.Methods = {
0
makeClipping: function(element) {
0
if (element._overflow) return element;
0
- element._overflow = element.style.overflow || 'auto';
0
- if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
0
+ element._overflow = Element.getStyle(element, 'overflow') || 'auto';
0
+ if (element._overflow !== 'hidden')
0
element.style.overflow = 'hidden';
0
@@ -1999,9 +2009,9 @@ Element.Methods = {
0
valueL += element.offsetLeft || 0;
0
element = element.offsetParent;
0
- if (element.tagName
== 'BODY') break;
0
+ if (element.tagName
.toUpperCase() == 'BODY') break;
0
var p = Element.getStyle(element, 'position');
0
- if (p
== 'relative' || p == 'absolute') break;
0
+ if (p
!== 'static') break;
0
return Element._returnOffset(valueL, valueT);
0
@@ -2009,7 +2019,7 @@ Element.Methods = {
0
absolutize: function(element) {
0
- if (element.getStyle('position') == 'absolute') return
;
0
+ if (element.getStyle('position') == 'absolute') return
element;
0
// Position.prepare(); // To be done manually by Scripty when it needs it.
0
var offsets = element.positionedOffset();
0
@@ -2033,7 +2043,7 @@ Element.Methods = {
0
relativize: function(element) {
0
- if (element.getStyle('position') == 'relative') return
;
0
+ if (element.getStyle('position') == 'relative') return
element;
0
// Position.prepare(); // To be done manually by Scripty when it needs it.
0
element.style.position = 'relative';
0
@@ -2084,7 +2094,7 @@ Element.Methods = {
0
- if (!Prototype.Browser.Opera || element.tagName
== 'BODY') {
0
+ if (!Prototype.Browser.Opera || element.tagName
.toUpperCase() == 'BODY') {
0
valueT -= element.scrollTop || 0;
0
valueL -= element.scrollLeft || 0;
0
@@ -2150,72 +2160,80 @@ Element._attributeTranslations = {
0
-if (!document.createRange || Prototype.Browser.Opera) {
0
- Element.Methods.insert = function(element, insertions) {
0
- if (Object.isString(insertions) || Object.isNumber(insertions) ||
0
- Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
0
- insertions = { bottom: insertions };
0
- var t = Element._insertionTranslations, content, position, pos, tagName;
0
- for (position in insertions) {
0
- content = insertions[position];
0
- position = position.toLowerCase();
0
- if (content && content.toElement) content = content.toElement();
0
- if (Object.isElement(content)) {
0
- pos.insert(element, content);
0
- content = Object.toHTML(content);
0
- tagName = ((position == 'before' || position == 'after')
0
- ? element.parentNode : element).tagName.toUpperCase();
0
- if (t.tags[tagName]) {
0
- var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
0
- if (position == 'top' || position == 'after') fragments.reverse();
0
- fragments.each(pos.insert.curry(element));
0
+if (Prototype.Browser.Opera) {
0
+ Element.Methods.getStyle = Element.Methods.getStyle.wrap(
0
+ function(proceed, element, style) {
0
+ case 'left': case 'top': case 'right': case 'bottom':
0
+ if (proceed(element, 'position') === 'static') return null;
0
+ case 'height': case 'width':
0
+ // returns '0px' for hidden elements; we want it to return null
0
+ if (!Element.visible(element)) return null;
0
+ // returns the border-box dimensions rather than the content-box
0
+ // dimensions, so we subtract padding and borders from the value
0
+ var dim = parseInt(proceed(element, style), 10);
0
+ if (dim !== element['offset' + style.capitalize()])
0
+ if (style === 'height') {
0
+ properties = ['border-top-width', 'padding-top',
0
+ 'padding-bottom', 'border-bottom-width'];
0
+ properties = ['border-left-width', 'padding-left',
0
+ 'padding-right', 'border-right-width'];
0
+ return properties.inject(dim, function(memo, property) {
0
+ var val = proceed(element, property);
0
+ return val === null ? memo : memo - parseInt(val, 10);
0
+ default: return proceed(element, style);
0
- else element.insertAdjacentHTML(pos.adjacency, content.stripScripts());
0
- content.evalScripts.bind(content).defer();
0
-if (Prototype.Browser.Opera) {
0
- Element.Methods._getStyle = Element.Methods.getStyle;
0
- Element.Methods.getStyle = function(element, style) {
0
- if (Element._getStyle(element, 'position') == 'static') return null;
0
- default: return Element._getStyle(element, style);
0
+ Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
0
+ function(proceed, element, attribute) {
0
+ if (attribute === 'title') return element.title;
0
+ return proceed(element, attribute);
0
- Element.Methods._readAttribute = Element.Methods.readAttribute;
0
- Element.Methods.readAttribute = function(element, attribute) {
0
- if (attribute == 'title') return element.title;
0
- return Element._readAttribute(element, attribute);
0
else if (Prototype.Browser.IE) {
0
- $w('positionedOffset getOffsetParent viewportOffset').each(function(method) {
0
+ // IE doesn't report offsets correctly for static elements, so we change them
0
+ // to "relative" to get the values, then change them back.
0
+ Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
0
+ function(proceed, element) {
0
+ // IE throws an error if element is not in document
0
+ try { element.offsetParent }
0
+ catch(e) { return $(document.body) }
0
+ var position = element.getStyle('position');
0
+ if (position !== 'static') return proceed(element);
0
+ element.setStyle({ position: 'relative' });
0
+ var value = proceed(element);
0
+ element.setStyle({ position: position });
0
+ $w('positionedOffset viewportOffset').each(function(method) {
0
Element.Methods[method] = Element.Methods[method].wrap(
0
function(proceed, element) {
0
+ try { element.offsetParent }
0
+ catch(e) { return Element._returnOffset(0,0) }
0
var position = element.getStyle('position');
0
- if (position != 'static') return proceed(element);
0
+ if (position !== 'static') return proceed(element);
0
+ // Trigger hasLayout on the offset parent so that IE6 reports
0
+ // accurate offsetTop and offsetLeft values for position: fixed.
0
+ var offsetParent = element.getOffsetParent();
0
+ if (offsetParent && offsetParent.getStyle('position') === 'fixed')
0
+ offsetParent.setStyle({ zoom: 1 });
0
element.setStyle({ position: 'relative' });
0
var value = proceed(element);
0
element.setStyle({ position: position });
0
@@ -2224,6 +2242,14 @@ else if (Prototype.Browser.IE) {
0
+ Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
0
+ function(proceed, element) {
0
+ try { element.offsetParent }
0
+ catch(e) { return Element._returnOffset(0,0) }
0
+ return proceed(element);
0
Element.Methods.getStyle = function(element, style) {
0
style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
0
@@ -2249,7 +2275,11 @@ else if (Prototype.Browser.IE) {
0
return filter.replace(/alpha\([^\)]*\)/gi,'');
0
- if (!element.currentStyle.hasLayout) element.style.zoom = 1;
0
+ var currentStyle = element.currentStyle;
0
+ if ((currentStyle && !currentStyle.hasLayout) ||
0
+ (!currentStyle && element.style.zoom == 'normal'))
0
+ element.style.zoom = 1;
0
var filter = element.getStyle('filter'), style = element.style;
0
if (value == 1 || value === '') {
0
(filter = stripAlpha(filter)) ?
0
@@ -2276,7 +2306,7 @@ else if (Prototype.Browser.IE) {
0
return node ? node.value : "";
0
_getEv: function(element, attribute) {
0
-
var attribute = element.getAttribute(attribute);
0
+
attribute = element.getAttribute(attribute);
0
return attribute ? attribute.toString().slice(23, -2) : null;
0
_flag: function(element, attribute) {
0
@@ -2293,7 +2323,10 @@ else if (Prototype.Browser.IE) {
0
Element._attributeTranslations.write = {
0
- names: Object.clone(Element._attributeTranslations.read.names),
0
+ names: Object.extend({
0
+ cellpadding: 'cellPadding',
0
+ cellspacing: 'cellSpacing'
0
+ }, Element._attributeTranslations.read.names),
0
checked: function(element, value) {
0
element.checked = !!value;
0
@@ -2308,7 +2341,7 @@ else if (Prototype.Browser.IE) {
0
Element._attributeTranslations.has = {};
0
$w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
0
- 'encType maxLength readOnly longDesc
').each(function(attr) {
0
+ 'encType maxLength readOnly longDesc
frameBorder').each(function(attr) {
0
Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
0
Element._attributeTranslations.has[attr.toLowerCase()] = attr;
0
@@ -2343,9 +2376,18 @@ else if (Prototype.Browser.IE) {
0
})(Element._attributeTranslations.read.values);
0
+ // Wrap Element#update to clean up event handlers on
0
+ // newly-removed elements. Prevents memory leaks in IE.
0
+ Element.Methods.update = Element.Methods.update.wrap(
0
+ function(proceed, element, contents) {
0
+ Element.select(element, '*').each(Event.stopObserving);
0
+ return proceed(element, contents);
0
-else if (Prototype.Browser.Gecko
) {
0
+else if (Prototype.Browser.Gecko
&& /rv:1\.8\.0/.test(navigator.userAgent)) {
0
Element.Methods.setOpacity = function(element, value) {
0
element.style.opacity = (value == 1) ? 0.999999 :
0
@@ -2361,7 +2403,7 @@ else if (Prototype.Browser.WebKit) {
0
(value < 0.00001) ? 0 : value;
0
- if(element.tagName
== 'IMG' && element.width) {
0
+ if(element.tagName
.toUpperCase() == 'IMG' && element.width) {
0
element.width++; element.width--;
0
var n = document.createTextNode(' ');
0
@@ -2373,7 +2415,7 @@ else if (Prototype.Browser.WebKit) {
0
// Safari returns margins on body which is incorrect if the child is absolutely
0
- // positioned. For performance reasons, redefine
Position.cumulativeOffset for
0
+ // positioned. For performance reasons, redefine
Element#cumulativeOffset for
0
Element.Methods.cumulativeOffset = function(element) {
0
var valueT = 0, valueL = 0;
0
@@ -2413,7 +2455,7 @@ if (Prototype.Browser.IE || Prototype.Browser.Opera) {
0
-if (
document.createElement('div').outerHTML) {
0
+if (
'outerHTML' in document.createElement('div')) {
0
Element.Methods.replace = function(element, content) {
0
@@ -2451,45 +2493,25 @@ Element._returnOffset = function(l, t) {
0
Element._getContentFromAnonymousElement = function(tagName, html) {
0
var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
0
- div.innerHTML = t[0] + html + t[1];
0
- t[2].times(function() { div = div.firstChild });
0
+ div.innerHTML = t[0] + html + t[1];
0
+ t[2].times(function() { div = div.firstChild });
0
+ } else div.innerHTML = html;
0
return $A(div.childNodes);
0
Element._insertionTranslations = {
0
- adjacency: 'beforeBegin',
0
- insert: function(element, node) {
0
- element.parentNode.insertBefore(node, element);
0
- initializeRange: function(element, range) {
0
- range.setStartBefore(element);
0
+ before: function(element, node) {
0
+ element.parentNode.insertBefore(node, element);
0
- adjacency: 'afterBegin',
0
- insert: function(element, node) {
0
- element.insertBefore(node, element.firstChild);
0
- initializeRange: function(element, range) {
0
- range.selectNodeContents(element);
0
+ top: function(element, node) {
0
+ element.insertBefore(node, element.firstChild);
0
- adjacency: 'beforeEnd',
0
- insert: function(element, node) {
0
- element.appendChild(node);
0
+ bottom: function(element, node) {
0
+ element.appendChild(node);
0
- adjacency: 'afterEnd',
0
- insert: function(element, node) {
0
- element.parentNode.insertBefore(node, element.nextSibling);
0
- initializeRange: function(element, range) {
0
- range.setStartAfter(element);
0
+ after: function(element, node) {
0
+ element.parentNode.insertBefore(node, element.nextSibling);
0
TABLE: ['<table>', '</table>', 1],
0
@@ -2501,7 +2523,6 @@ Element._insertionTranslations = {
0
- this.bottom.initializeRange = this.top.initializeRange;
0
Object.extend(this.tags, {
0
THEAD: this.tags.TBODY,
0
TFOOT: this.tags.TBODY,
0
@@ -2539,7 +2560,7 @@ Element.extend = (function() {
0
element.nodeType != 1 || element == window) return element;
0
var methods = Object.clone(Methods),
0
- tagName = element.tagName
, property, value;
0
+ tagName = element.tagName
.toUpperCase(), property, value;
0
// extend methods for specific tags
0
if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
0
@@ -2662,10 +2683,11 @@ Element.addMethods = function(methods) {
0
getDimensions: function() {
0
+ var B = Prototype.Browser;
0
$w('width height').each(function(d) {
0
var D = d.capitalize();
0
- dimensions[d] = self['inner' + D] ||
0
- (document.documentElement['client' + D] || document.body['client' + D]);
0
+ dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
0
+ (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
0
@@ -2684,21 +2706,61 @@ document.viewport = {
0
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
0
-/* Portions of the Selector class are derived from Jack Slocum
’s DomQuery,
0
+/* Portions of the Selector class are derived from Jack Slocum
's DomQuery,
0
* part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
0
* license. Please see http://www.yui-ext.com/ for more information. */
0
var Selector = Class.create({
0
initialize: function(expression) {
0
this.expression = expression.strip();
0
- this.compileMatcher();
0
+ if (this.shouldUseSelectorsAPI()) {
0
+ this.mode = 'selectorsAPI';
0
+ } else if (this.shouldUseXPath()) {
0
+ this.compileXPathMatcher();
0
+ this.compileMatcher();
0
- compileMatcher: function() {
0
- // Selectors with namespaced attributes can't use the XPath version
0
- if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
0
- return this.compileXPathMatcher();
0
+ shouldUseXPath: function() {
0
+ if (!Prototype.BrowserFeatures.XPath) return false;
0
+ var e = this.expression;
0
+ // Safari 3 chokes on :*-of-type and :empty
0
+ if (Prototype.Browser.WebKit &&
0
+ (e.include("-of-type") || e.include(":empty")))
0
+ // XPath can't do namespaced attributes, nor can it read
0
+ // the "checked" property from DOM nodes
0
+ if ((/(\[[\w-]*?:|:checked)/).test(e))
0
+ shouldUseSelectorsAPI: function() {
0
+ if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
0
+ if (!Selector._div) Selector._div = new Element('div');
0
+ // Make sure the browser treats the selector as valid. Test on an
0
+ // isolated element to minimize cost of this check.
0
+ Selector._div.querySelector(this.expression);
0
+ compileMatcher: function() {
0
var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
0
c = Selector.criteria, le, p, m;
0
@@ -2716,7 +2778,7 @@ var Selector = Class.create({
0
this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
0
-
new Template(c[i]).evaluate(m));
0
+
new Template(c[i]).evaluate(m));
0
e = e.replace(m[0], '');
0
@@ -2755,8 +2817,27 @@ var Selector = Class.create({
0
findElements: function(root) {
0
root = root || document;
0
- if (this.xpath) return document._getElementsByXPath(this.xpath, root);
0
- return this.matcher(root);
0
+ var e = this.expression, results;
0
+ // querySelectorAll queries document-wide, then filters to descendants
0
+ // of the context element. That's not what we want.
0
+ // Add an explicit context to the selector if necessary.
0
+ if (root !== document) {
0
+ var oldId = root.id, id = $(root).identify();
0
+ e = "#" + id + " " + e;
0
+ results = $A(root.querySelectorAll(e)).map(Element.extend);
0
+ return document._getElementsByXPath(this.xpath, root);
0
+ return this.matcher(root);
0
match: function(element) {
0
@@ -2819,8 +2900,12 @@ Object.extend(Selector, {
0
className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
0
- attrPresence: "[@#{1}]",
0
+ attrPresence: function(m) {
0
+ m[1] = m[1].toLowerCase();
0
+ return new Template("[@#{1}]").evaluate(m);
0
+ m[1] = m[1].toLowerCase();
0
return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
0
@@ -2843,13 +2928,13 @@ Object.extend(Selector, {
0
'first-child': '[not(preceding-sibling::*)]',
0
'last-child': '[not(following-sibling::*)]',
0
'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
0
- 'empty': "[count(*) = 0 and (count(text()) = 0
or translate(text(), ' \t\r\n', '') = '')]",
0
+ 'empty': "[count(*) = 0 and (count(text()) = 0
)]",
0
'checked': "[@checked]",
0
- 'disabled': "[@disabled]",
0
- 'enabled': "[not(@disabled)]",
0
+ 'disabled': "[(@disabled) and (@type!='hidden')]",
0
+ 'enabled': "[not(@disabled) and (@type!='hidden')]",
0
var e = m[6], p = Selector.patterns,
0
- x = Selector.xpath, le,
m, v;
0
+ x = Selector.xpath, le,
v;
0
while (e && le != e && (/\S/).test(e)) {
0
@@ -2906,13 +2991,13 @@ Object.extend(Selector, {
0
- tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
0
- className: 'n = h.className(n, r, "#{1}", c); c = false;',
0
- id: 'n = h.id(n, r, "#{1}", c); c = false;',
0
- attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
0
+ tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
0
+ className: 'n = h.className(n, r, "#{1}", c); c = false;',
0
+ id: 'n = h.id(n, r, "#{1}", c); c = false;',
0
+ attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
0
- return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"
); c = false;').evaluate(m);
0
+ return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"
, c); c = false;').evaluate(m);
0
if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
0
@@ -2936,8 +3021,9 @@ Object.extend(Selector, {
0
tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
0
id: /^#([\w\-\*]+)(\b|$)/,
0
className: /^\.([\w\-\*]+)(\b|$)/,
0
- pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/,
0
- attrPresence: /^\[([\w]+)\]/,
0
+/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
0
+ attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
0
attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
0
@@ -2961,7 +3047,7 @@ Object.extend(Selector, {
0
attr: function(element, matches) {
0
var nodeValue = Element.readAttribute(element, matches[1]);
0
- return
Selector.operators[matches[2]](nodeValue, matches[3]);
0
+ return
nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
0
@@ -2976,14 +3062,15 @@ Object.extend(Selector, {
0
// marks an array of nodes for counting
0
mark: function(nodes) {
0
+ var _true = Prototype.emptyFunction;
0
for (var i = 0, node; node = nodes[i]; i++)
0
+ node._counted
ByPrototype = _true;
0
unmark: function(nodes) {
0
for (var i = 0, node; node = nodes[i]; i++)
0
- node._counted
= undefined;
0
+ node._counted
ByPrototype = undefined;
0
@@ -2991,15 +3078,15 @@ Object.extend(Selector, {
0
// "ofType" flag indicates whether we're indexing for nth-of-type
0
// rather than nth-child
0
index: function(parentNode, reverse, ofType) {
0
- parentNode._counted
= true;
0
+ parentNode._counted
ByPrototype = Prototype.emptyFunction;
0
for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
0
- if (node.nodeType == 1 && (!ofType || node._counted
)) node.nodeIndex = j++;
0
+ if (node.nodeType == 1 && (!ofType || node._counted
ByPrototype)) node.nodeIndex = j++;
0
for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
0
- if (node.nodeType == 1 && (!ofType || node._counted
)) node.nodeIndex = j++;
0
+ if (node.nodeType == 1 && (!ofType || node._counted
ByPrototype)) node.nodeIndex = j++;
0
@@ -3008,8 +3095,8 @@ Object.extend(Selector, {
0
if (nodes.length == 0) return nodes;
0
for (var i = 0, l = nodes.length; i < l; i++)
0
- if (!(n = nodes[i])._counted) {
0
+ if (!(n = nodes[i])._countedByPrototype) {
0
+ n._countedByPrototype = Prototype.emptyFunction;
0
results.push(Element.extend(n));
0
return Selector.handlers.unmark(results);
0
@@ -3026,7 +3113,7 @@ Object.extend(Selector, {
0
child: function(nodes) {
0
var h = Selector.handlers;
0
for (var i = 0, results = [], node; node = nodes[i]; i++) {
0
- for (var j = 0, child
ren = [], child; child = node.childNodes[j]; j++)
0
+ for (var j = 0, child
; child = node.childNodes[j]; j++)
0
if (child.nodeType == 1 && child.tagName != '!') results.push(child);
0
@@ -3049,7 +3136,7 @@ Object.extend(Selector, {
0
nextElementSibling: function(node) {
0
while (node = node.nextSibling)
0
-
if (node.nodeType == 1) return node;
0
+
if (node.nodeType == 1) return node;
0
@@ -3061,7 +3148,7 @@ Object.extend(Selector, {
0
tagName: function(nodes, root, tagName, combinator) {
0
-
tagName = tagName.toUpperCase();
0
+
var uTagName = tagName.toUpperCase();
0
var results = [], h = Selector.handlers;
0
@@ -3074,7 +3161,7 @@ Object.extend(Selector, {
0
if (tagName == "*") return nodes;
0
for (var i = 0, node; node = nodes[i]; i++)
0
- if (node.tagName.toUpperCase() ==
tagName) results.push(node);
0
+ if (node.tagName.toUpperCase() ==
= uTagName) results.push(node);
0
} else return root.getElementsByTagName(tagName);
0
@@ -3121,15 +3208,18 @@ Object.extend(Selector, {
0
- attrPresence: function(nodes, root, attr) {
0
+ attrPresence: function(nodes, root, attr, combinator) {
0
+ if (!nodes) nodes = root.getElementsByTagName("*");
0
+ if (nodes && combinator) nodes = this[combinator](nodes);
0
for (var i = 0, node; node = nodes[i]; i++)
0
if (Element.hasAttribute(node, attr)) results.push(node);
0
- attr: function(nodes, root, attr, value, operator
) {
0
+ attr: function(nodes, root, attr, value, operator
, combinator) {
0
if (!nodes) nodes = root.getElementsByTagName("*");
0
+ if (nodes && combinator) nodes = this[combinator](nodes);
0
var handler = Selector.operators[operator], results = [];
0
for (var i = 0, node; node = nodes[i]; i++) {
0
var nodeValue = Element.readAttribute(node, attr);
0
@@ -3208,7 +3298,7 @@ Object.extend(Selector, {
0
var h = Selector.handlers, results = [], indexed = [], m;
0
for (var i = 0, node; node = nodes[i]; i++) {
0
- if (!node.parentNode._counted
) {
0
+ if (!node.parentNode._counted
ByPrototype) {
0
h.index(node.parentNode, reverse, ofType);
0
indexed.push(node.parentNode);
0
@@ -3235,7 +3325,7 @@ Object.extend(Selector, {
0
'empty': function(nodes, value, root) {
0
for (var i = 0, results = [], node; node = nodes[i]; i++) {
0
// IE treats comments as element nodes
0
- if (node.tagName == '!' ||
(node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
0
+ if (node.tagName == '!' ||
node.firstChild) continue;
0
@@ -3246,14 +3336,15 @@ Object.extend(Selector, {
0
var exclusions = new Selector(selector).findElements(root);
0
for (var i = 0, results = [], node; node = nodes[i]; i++)
0
- if (!node._counted
) results.push(node);
0
+ if (!node._counted
ByPrototype) results.push(node);
0
'enabled': function(nodes, value, root) {
0
for (var i = 0, results = [], node; node = nodes[i]; i++)
0
- if (!node.disabled) results.push(node);
0
+ if (!node.disabled && (!node.type || node.type !== 'hidden'))
0
@@ -3272,19 +3363,29 @@ Object.extend(Selector, {
0
'=': function(nv, v) { return nv == v; },
0
- '!=': function(nv, v) { return nv != v; },
0
- '^=': function(nv, v) { return nv.startsWith(v); },
0
+ '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
0
+ '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
0
+ '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
0
'$=': function(nv, v) { return nv.endsWith(v); },
0
'*=': function(nv, v) { return nv.include(v); },
0
'~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
0
- '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
0
+ '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
0
+ '-').include('-' + (v || "").toUpperCase() + '-'); }
0
+ split: function(expression) {
0
+ expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
0
+ expressions.push(m[1].strip());
0
matchElements: function(elements, expression) {
0
- var matches =
new Selector(expression).findElements(), h = Selector.handlers;
0
+ var matches =
$$(expression), h = Selector.handlers;
0
for (var i = 0, results = [], element; element = elements[i]; i++)
0
- if (element._counted
) results.push(element);
0
+ if (element._counted
ByPrototype) results.push(element);
0
@@ -3297,10 +3398,7 @@ Object.extend(Selector, {
0
findChildElements: function(element, expressions) {
0
- var exprs = expressions.join(','), expressions = [];
0
- exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
0
- expressions.push(m[1].strip());
0
+ expressions = Selector.split(expressions.join(','));
0
var results = [], h = Selector.handlers;
0
for (var i = 0, l = expressions.length, selector; i < l; i++) {
0
selector = new Selector(expressions[i].strip());
0
@@ -3310,6 +3408,25 @@ Object.extend(Selector, {
0
+if (Prototype.Browser.IE) {
0
+ Object.extend(Selector.handlers, {
0
+ // IE returns comment nodes on getElementsByTagName("*").
0
+ concat: function(a, b) {
0
+ for (var i = 0, node; node = b[i]; i++)
0
+ if (node.tagName !== "!") a.push(node);
0
+ // IE improperly serializes _countedByPrototype in (inner|outer)HTML.
0
+ unmark: function(nodes) {
0
+ for (var i = 0, node; node = nodes[i]; i++)
0
+ node.removeAttribute('_countedByPrototype');
0
return Selector.findChildElements(document, $A(arguments));
0
@@ -3321,7 +3438,7 @@ var Form = {
0
serializeElements: function(elements, options) {
0
if (typeof options != 'object') options = { hash: !!options };
0
- else if (
options.hash === undefined) options.hash = true;
0
+ else if (
Object.isUndefined(options.hash)) options.hash = true;
0
var key, value, submitted = false, submit = options.submit;
0
var data = elements.inject({ }, function(result, element) {
0
@@ -3519,17 +3636,17 @@ Form.Element.Serializers = {
0
inputSelector: function(element, value) {
0
- if (
value === undefined) return element.checked ? element.value : null;
0
+ if (
Object.isUndefined(value)) return element.checked ? element.value : null;
0
else element.checked = !!value;
0
textarea: function(element, value) {
0
- if (
value === undefined) return element.value;
0
+ if (
Object.isUndefined(value)) return element.value;
0
else element.value = value;
0
select: function(element, index) {
0
- if (
index === undefined)
0
+ if (
Object.isUndefined(index))
0
return this[element.type == 'select-one' ?
0
'selectOne' : 'selectMany'](element);
0
@@ -3684,39 +3801,86 @@ Object.extend(Event, {
0
- element: function(event) {
0
- var node = event.target;
0
- return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
0
+Event.Methods = (function() {
0
- findElement: function(event, expression) {
0
- var element = Event.element(event);
0
- return element.match(expression) ? element : element.up(expression);
0
+ if (Prototype.Browser.IE) {
0
+ var buttonMap = { 0: 1, 1: 4, 2: 2 };
0
+ isButton = function(event, code) {
0
+ return event.button == buttonMap[code];
0
- isLeftClick: function(event) {
0
- return (((event.which) && (event.which == 1)) ||
0
- ((event.button) && (event.button == 1)));
0
+ } else if (Prototype.Browser.WebKit) {
0
+ isButton = function(event, code) {
0
+ case 0: return event.which == 1 && !event.metaKey;
0
+ case 1: return event.which == 1 && event.metaKey;
0
+ default: return false;
0
- pointer: function(event) {
0
- x: event.pageX || (event.clientX +
0
- (document.documentElement.scrollLeft || document.body.scrollLeft)),
0
- y: event.pageY || (event.clientY +
0
- (document.documentElement.scrollTop || document.body.scrollTop))
0
+ isButton = function(event, code) {
0
+ return event.which ? (event.which === code + 1) : (event.button === code);
0
- pointerX: function(event) { return Event.pointer(event).x },
0
- pointerY: function(event) { return Event.pointer(event).y },
0
+ isLeftClick: function(event) { return isButton(event, 0) },
0
+ isMiddleClick: function(event) { return isButton(event, 1) },
0
+ isRightClick: function(event) { return isButton(event, 2) },
0
+ element: function(event) {
0
+ event = Event.extend(event);
0
+ var node = event.target, type = event.type;
0
+ if (event.currentTarget && event.currentTarget.tagName) {
0
+ // Firefox screws up the "click" event when moving between radio buttons
0
+ // via arrow keys. It also screws up the "load" and "error" events on images,
0
+ // reporting the document as the target instead of the original image.
0
+ var currentTarget = event.currentTarget;
0
+ var tagName = currentTarget.tagName.toUpperCase();
0
+ if (['load', 'error'].include(type) ||
0
+ (tagName === 'INPUT' && currentTarget.type === 'radio' && type === 'click'))
0
- stop: function(event) {
0
- event.preventDefault();
0
- event.stopPropagation();
0
+ return Element.extend(node && node.nodeType == Node.TEXT_NODE ?
0
+ node.parentNode : node);
0
+ findElement: function(event, expression) {
0
+ var element = Event.element(event);
0
+ if (!expression) return element;
0
+ var elements = [element].concat(element.ancestors());
0
+ return Selector.findElement(elements, expression, 0);
0
+ pointer: function(event) {
0
+ var docElement = document.documentElement,
0
+ body = document.body || { scrollLeft: 0, scrollTop: 0 };
0
+ x: event.pageX || (event.clientX +
0
+ (docElement.scrollLeft || body.scrollLeft) -
0
+ (docElement.clientLeft || 0)),
0
+ y: event.pageY || (event.clientY +
0
+ (docElement.scrollTop || body.scrollTop) -
0
+ (docElement.clientTop || 0))
0
+ pointerX: function(event) { return Event.pointer(event).x },
0
+ pointerY: function(event) { return Event.pointer(event).y },
0
+ stop: function(event) {
0
+ event.preventDefault();
0
+ event.stopPropagation();
0
Event.extend = (function() {
0
var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
0
@@ -3757,14 +3921,17 @@ Object.extend(Event, (function() {
0
var cache = Event.cache;
0
function getEventID(element) {
0
- if (element._eventID) return element._eventID;
0
+ // Event ID is stored as the 0th index in a one-item array so that it
0
+ // won't get copied to a new node when cloneNode is called.
0
+ if (element._prototypeEventID) return element._prototypeEventID[0];
0
arguments.callee.id = arguments.callee.id || 1;
0
- return element._eventID = ++arguments.callee.id;
0
+ return element._prototypeEventID = [++arguments.callee.id];
0
function getDOMEventName(eventName) {
0
- if (eventName && eventName.match(/:/)) return "dataavailable";
0
- return { keypress: "keydown" }[eventName] || eventName;
0
+ if (eventName && eventName.include(':')) return "dataavailable";
0
function getCacheForID(id) {
0
@@ -3777,16 +3944,22 @@ Object.extend(Event, (function() {
0
function createWrapper(element, eventName, handler) {
0
- var id = getEventID(element);
0
+ var id = getEventID(element), _c = getCacheForID(id);
0
+ // Attach the element itself onto its cache entry so we can retrieve it for
0
+ // cleanup on page unload.
0
+ if (!_c.element) _c.element = element;
0
var c = getWrappersForEventName(id, eventName);
0
if (c.pluck("handler").include(handler)) return false;
0
var wrapper = function(event) {
0
- if (event.eventName && event.eventName != eventName)
0
+ if (!Event || !Event.extend ||
0
+ (event.eventName && event.eventName != eventName))
0
- handler.call(element, event)
0
+ handler.call(element, event)
;0
wrapper.handler = handler;
0
@@ -3805,14 +3978,45 @@ Object.extend(Event, (function() {
0
c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
0
- function destroyCache() {
0
- for (var eventName in cache[id])
0
- cache[id][eventName] = null;
0
+ // Loop through all elements and remove all handlers on page unload. IE
0
+ // needs this in order to prevent memory leaks.
0
+ function purgeListeners() {
0
+ for (var i in Event.cache) {
0
+ entry = Event.cache[i];
0
+ Event.stopObserving(entry.element);
0
+ document.detachEvent('onstop', onStop);
0
+ function onBeforeUnload() {
0
+ if (document.readyState === "interactive") {
0
+ document.attachEvent('onstop', onStop);
0
+ (function() { document.detachEvent('onstop', onStop); }).defer();
0
if (window.attachEvent) {
0
- window.attachEvent("onunload", destroyCache);
0
+ // Internet Explorer needs to remove event handlers on page unload
0
+ // in order to avoid memory leaks.
0
+ window.attachEvent("onunload", purgeListeners);
0
+ // IE also doesn't fire the unload event if the page is navigated away
0
+ // from before it's done loading. Workaround adapted from
0
+ // http://blog.moxiecode.com/2008/04/08/unload-event-never-fires-in-ie/.
0
+ window.attachEvent("onbeforeunload", onBeforeUnload);
0
+ // Safari has a dummy event handler on page unload so that it won't
0
+ // use its bfcache. Safari <= 3.1 has an issue with restoring the "document"
0
+ // object when page is returned to via the back button using its bfcache.
0
+ if (Prototype.Browser.WebKit) {
0
+ window.addEventListener('unload', Prototype.emptyFunction, false);
0
@@ -3838,13 +4042,13 @@ Object.extend(Event, (function() {
0
if (!handler && eventName) {
0
getWrappersForEventName(id, eventName).each(function(wrapper) {
0
-
element.stopObserving(eventName, wrapper.handler);
0
+
Event.stopObserving(element, eventName, wrapper.handler);
0
} else if (!eventName) {
0
- Object.keys(getCacheForID(id)).each(function(eventName) {
0
- element.stopObserving(eventName);
0
+ Object.keys(getCacheForID(id)).without("element").each(function(eventName) {
0
+ Event.stopObserving(element, eventName);
0
@@ -3868,11 +4072,12 @@ Object.extend(Event, (function() {
0
if (element == document && document.createEvent && !element.dispatchEvent)
0
element = document.documentElement;
0
if (document.createEvent) {
0
-
var event = document.createEvent("HTMLEvents");
0
+
event = document.createEvent("HTMLEvents");
0
event.initEvent("dataavailable", true, true);
0
-
var event = document.createEventObject();
0
+
event = document.createEventObject();
0
event.eventType = "ondataavailable";
0
@@ -3885,7 +4090,7 @@ Object.extend(Event, (function() {
0
element.fireEvent(event.eventType, event);
0
+ return
Event.extend(event);
0
@@ -3901,20 +4106,21 @@ Element.addMethods({
0
Object.extend(document, {
0
fire: Element.Methods.fire.methodize(),
0
observe: Element.Methods.observe.methodize(),
0
- stopObserving: Element.Methods.stopObserving.methodize()
0
+ stopObserving: Element.Methods.stopObserving.methodize(),
0
/* Support for the DOMContentLoaded event is based on work by Dan Webb,
0
Matthias Miller, Dean Edwards and John Resig. */
0
- var timer
, fired = false;
0
function fireContentLoadedEvent() {
0
+ if (
document.loaded) return;
0
if (timer) window.clearInterval(timer);
0
document.fire("dom:loaded");
0
+
document.loaded = true;
0
if (document.addEventListener) {