Project

General

Profile

Feature #19604 » 0009783.patch

Administrator Admin, 2008-11-12 18:02

View differences:

typo3/contrib/prototype/prototype.js (Arbeitskopie)
/* Prototype JavaScript framework, version 1.6.0.2
/* Prototype JavaScript framework, version 1.6.0.3
* (c) 2005-2008 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
......
*--------------------------------------------------------------------------*/
var Prototype = {
Version: '1.6.0.2',
Version: '1.6.0.3',
Browser: {
IE: !!(window.attachEvent && !window.opera),
Opera: !!window.opera,
IE: !!(window.attachEvent &&
navigator.userAgent.indexOf('Opera') === -1),
Opera: navigator.userAgent.indexOf('Opera') > -1,
WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
Gecko: navigator.userAgent.indexOf('Gecko') > -1 &&
navigator.userAgent.indexOf('KHTML') === -1,
MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
},
BrowserFeatures: {
XPath: !!document.evaluate,
SelectorsAPI: !!document.querySelector,
ElementExtensions: !!window.HTMLElement,
SpecificElementExtensions:
document.createElement('div').__proto__ &&
document.createElement('div').__proto__ !==
document.createElement('form').__proto__
document.createElement('div')['__proto__'] &&
document.createElement('div')['__proto__'] !==
document.createElement('form')['__proto__']
},
ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
......
var property = properties[i], value = source[property];
if (ancestor && Object.isFunction(value) &&
value.argumentNames().first() == "$super") {
var method = value, value = Object.extend((function(m) {
var method = value;
value = (function(m) {
return function() { return ancestor[m].apply(this, arguments) };
})(property).wrap(method), {
valueOf: function() { return method },
toString: function() { return method.toString() }
});
})(property).wrap(method);
value.valueOf = method.valueOf.bind(method);
value.toString = method.toString.bind(method);
}
this.prototype[property] = value;
}
......
},
isElement: function(object) {
return object && object.nodeType == 1;
return !!(object && object.nodeType == 1);
},
isArray: function(object) {
......
Object.extend(Function.prototype, {
argumentNames: function() {
var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
.replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names;
},
......
}, timeout);
},
defer: function() {
var args = [0.01].concat($A(arguments));
return this.delay.apply(this, args);
},
wrap: function(wrapper) {
var __method = this;
return function() {
......
}
});
Function.prototype.defer = Function.prototype.delay.curry(0.01);
Date.prototype.toJSON = function() {
return '"' + this.getUTCFullYear() + '-' +
(this.getUTCMonth() + 1).toPaddedString(2) + '-' +
......
return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
},
unescapeHTML: function() {
return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
return this.stripTags().replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
}
});
......
text: document.createTextNode('')
});
with (String.prototype.escapeHTML) div.appendChild(text);
String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);
var Template = Class.create({
initialize: function(template, pattern) {
......
var Enumerable = {
each: function(iterator, context) {
var index = 0;
iterator = iterator.bind(context);
try {
this._each(function(value) {
iterator(value, index++);
iterator.call(context, value, index++);
});
} catch (e) {
if (e != $break) throw e;
......
},
eachSlice: function(number, iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K;
var index = -number, slices = [], array = this.toArray();
if (number < 1) return array;
while ((index += number) < array.length)
slices.push(array.slice(index, index+number));
return slices.collect(iterator, context);
},
all: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K;
iterator = iterator || Prototype.K;
var result = true;
this.each(function(value, index) {
result = result && !!iterator(value, index);
result = result && !!iterator.call(context, value, index);
if (!result) throw $break;
});
return result;
},
any: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K;
iterator = iterator || Prototype.K;
var result = false;
this.each(function(value, index) {
if (result = !!iterator(value, index))
if (result = !!iterator.call(context, value, index))
throw $break;
});
return result;
},
collect: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K;
iterator = iterator || Prototype.K;
var results = [];
this.each(function(value, index) {
results.push(iterator(value, index));
results.push(iterator.call(context, value, index));
});
return results;
},
detect: function(iterator, context) {
iterator = iterator.bind(context);
var result;
this.each(function(value, index) {
if (iterator(value, index)) {
if (iterator.call(context, value, index)) {
result = value;
throw $break;
}
......
},
findAll: function(iterator, context) {
iterator = iterator.bind(context);
var results = [];
this.each(function(value, index) {
if (iterator(value, index))
if (iterator.call(context, value, index))
results.push(value);
});
return results;
},
grep: function(filter, iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K;
iterator = iterator || Prototype.K;
var results = [];
if (Object.isString(filter))
......
this.each(function(value, index) {
if (filter.match(value))
results.push(iterator(value, index));
results.push(iterator.call(context, value, index));
});
return results;
},
......
},
inject: function(memo, iterator, context) {
iterator = iterator.bind(context);
this.each(function(value, index) {
memo = iterator(memo, value, index);
memo = iterator.call(context, memo, value, index);
});
return memo;
},
......
},
max: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K;
iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
value = iterator(value, index);
value = iterator.call(context, value, index);
if (result == null || value >= result)
result = value;
});
......
},
min: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K;
iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
value = iterator(value, index);
value = iterator.call(context, value, index);
if (result == null || value < result)
result = value;
});
......
},
partition: function(iterator, context) {
iterator = iterator ? iterator.bind(context) : Prototype.K;
iterator = iterator || Prototype.K;
var trues = [], falses = [];
this.each(function(value, index) {
(iterator(value, index) ?
(iterator.call(context, value, index) ?
trues : falses).push(value);
});
return [trues, falses];
......
},
reject: function(iterator, context) {
iterator = iterator.bind(context);
var results = [];
this.each(function(value, index) {
if (!iterator(value, index))
if (!iterator.call(context, value, index))
results.push(value);
});
return results;
},
sortBy: function(iterator, context) {
iterator = iterator.bind(context);
return this.map(function(value, index) {
return {value: value, criteria: iterator(value, index)};
return {
value: value,
criteria: iterator.call(context, value, index)
};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
......
if (Prototype.Browser.WebKit) {
$A = function(iterable) {
if (!iterable) return [];
if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
iterable.toArray) return iterable.toArray();
// In Safari, only use the `toArray` method if it's not a NodeList.
// A NodeList is a function, has an function `item` property, and a numeric
// `length` property. Adapted from Google Doctype.
if (!(typeof iterable === 'function' && typeof iterable.length ===
'number' && typeof iterable.item === 'function') && iterable.toArray)
return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
......
return this + 1;
},
times: function(iterator) {
$R(0, this, true).each(iterator);
times: function(iterator, context) {
$R(0, this, true).each(iterator, context);
return this;
},
......
},
get: function(key) {
return this._object[key];
// simulating poorly supported hasOwnProperty
if (this._object[key] !== Object.prototype[key])
return this._object[key];
},
unset: function(key) {
......
},
toQueryString: function() {
return this.map(function(pair) {
return this.inject([], function(results, pair) {
var key = encodeURIComponent(pair.key), values = pair.value;
if (values && typeof values == 'object') {
if (Object.isArray(values))
return values.map(toQueryPair.curry(key)).join('&');
}
return toQueryPair(key, values);
return results.concat(values.map(toQueryPair.curry(key)));
} else results.push(toQueryPair(key, values));
return results;
}).join('&');
},
......
return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
};
Object.extend(this.Element, element || { });
if (element) this.Element.prototype = element.prototype;
}).call(window);
Element.cache = { };
......
},
hide: function(element) {
$(element).style.display = 'none';
element = $(element);
element.style.display = 'none';
return element;
},
show: function(element) {
$(element).style.display = '';
element = $(element);
element.style.display = '';
return element;
},
......
element = $(element);
if (arguments.length == 1) return element.firstDescendant();
return Object.isNumber(expression) ? element.descendants()[expression] :
element.select(expression)[index || 0];
Element.select(element, expression)[index || 0];
},
previous: function(element, expression, index) {
......
descendantOf: function(element, ancestor) {
element = $(element), ancestor = $(ancestor);
var originalAncestor = ancestor;
if (element.compareDocumentPosition)
return (element.compareDocumentPosition(ancestor) & 8) === 8;
if (element.sourceIndex && !Prototype.Browser.Opera) {
var e = element.sourceIndex, a = ancestor.sourceIndex,
nextAncestor = ancestor.nextSibling;
if (!nextAncestor) {
do { ancestor = ancestor.parentNode; }
while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
}
if (nextAncestor && nextAncestor.sourceIndex)
return (e > a && e < nextAncestor.sourceIndex);
}
if (ancestor.contains)
return ancestor.contains(element) && ancestor !== element;
while (element = element.parentNode)
if (element == originalAncestor) return true;
if (element == ancestor) return true;
return false;
},
......
element = $(element);
style = style == 'float' ? 'cssFloat' : style.camelize();
var value = element.style[style];
if (!value) {
if (!value || value == 'auto') {
var css = document.defaultView.getComputedStyle(element, null);
value = css ? css[style] : null;
}
......
getDimensions: function(element) {
element = $(element);
var display = $(element).getStyle('display');
var display = element.getStyle('display');
if (display != 'none' && display != null) // Safari bug
return {width: element.offsetWidth, height: element.offsetHeight};
......
element.style.position = 'relative';
// Opera returns the offset relative to the positioning context, when an
// element is position relative but top and left have not been defined
if (window.opera) {
if (Prototype.Browser.Opera) {
element.style.top = 0;
element.style.left = 0;
}
......
valueL += element.offsetLeft || 0;
element = element.offsetParent;
if (element) {
if (element.tagName == 'BODY') break;
if (element.tagName.toUpperCase() == 'BODY') break;
var p = Element.getStyle(element, 'position');
if (p !== 'static') break;
}
......
absolutize: function(element) {
element = $(element);
if (element.getStyle('position') == 'absolute') return;
if (element.getStyle('position') == 'absolute') return element;
// Position.prepare(); // To be done manually by Scripty when it needs it.
var offsets = element.positionedOffset();
......
relativize: function(element) {
element = $(element);
if (element.getStyle('position') == 'relative') return;
if (element.getStyle('position') == 'relative') return element;
// Position.prepare(); // To be done manually by Scripty when it needs it.
element.style.position = 'relative';
......
element = forElement;
do {
if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
valueT -= element.scrollTop || 0;
valueL -= element.scrollLeft || 0;
}
......
Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
function(proceed, element) {
element = $(element);
// IE throws an error if element is not in document
try { element.offsetParent }
catch(e) { return $(document.body) }
var position = element.getStyle('position');
if (position !== 'static') return proceed(element);
element.setStyle({ position: 'relative' });
......
Element.Methods[method] = Element.Methods[method].wrap(
function(proceed, element) {
element = $(element);
try { element.offsetParent }
catch(e) { return Element._returnOffset(0,0) }
var position = element.getStyle('position');
if (position !== 'static') return proceed(element);
// Trigger hasLayout on the offset parent so that IE6 reports
......
);
});
Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
function(proceed, element) {
try { element.offsetParent }
catch(e) { return Element._returnOffset(0,0) }
return proceed(element);
}
);
Element.Methods.getStyle = function(element, style) {
element = $(element);
style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
......
Element._attributeTranslations.has = {};
$w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
'encType maxLength readOnly longDesc').each(function(attr) {
'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
Element._attributeTranslations.has[attr.toLowerCase()] = attr;
});
......
(value < 0.00001) ? 0 : value;
if (value == 1)
if(element.tagName == 'IMG' && element.width) {
if(element.tagName.toUpperCase() == 'IMG' && element.width) {
element.width++; element.width--;
} else try {
var n = document.createTextNode(' ');
......
hasAttribute: function(element, attribute) {
attribute = Element._attributeTranslations.has[attribute] || attribute;
var node = $(element).getAttributeNode(attribute);
return node && node.specified;
return !!(node && node.specified);
}
};
......
Object.extend(Element, Element.Methods);
if (!Prototype.BrowserFeatures.ElementExtensions &&
document.createElement('div').__proto__) {
document.createElement('div')['__proto__']) {
window.HTMLElement = { };
window.HTMLElement.prototype = document.createElement('div').__proto__;
window.HTMLElement.prototype = document.createElement('div')['__proto__'];
Prototype.BrowserFeatures.ElementExtensions = true;
}
......
element.nodeType != 1 || element == window) return element;
var methods = Object.clone(Methods),
tagName = element.tagName, property, value;
tagName = element.tagName.toUpperCase(), property, value;
// extend methods for specific tags
if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
......
if (window[klass]) return window[klass];
window[klass] = { };
window[klass].prototype = document.createElement(tagName).__proto__;
window[klass].prototype = document.createElement(tagName)['__proto__'];
return window[klass];
}
......
document.viewport = {
getDimensions: function() {
var dimensions = { };
var B = Prototype.Browser;
var dimensions = { }, B = Prototype.Browser;
$w('width height').each(function(d) {
var D = d.capitalize();
dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
(B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
if (B.WebKit && !document.evaluate) {
// Safari <3.0 needs self.innerWidth/Height
dimensions[d] = self['inner' + D];
} else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {
// Opera <9.5 needs document.body.clientWidth/Height
dimensions[d] = document.body['client' + D]
} else {
dimensions[d] = document.documentElement['client' + D];
}
});
return dimensions;
},
......
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
}
};
/* Portions of the Selector class are derived from Jack Slocums DomQuery,
/* Portions of the Selector class are derived from Jack Slocum's DomQuery,
* part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
* license. Please see http://www.yui-ext.com/ for more information. */
var Selector = Class.create({
initialize: function(expression) {
this.expression = expression.strip();
this.compileMatcher();
if (this.shouldUseSelectorsAPI()) {
this.mode = 'selectorsAPI';
} else if (this.shouldUseXPath()) {
this.mode = 'xpath';
this.compileXPathMatcher();
} else {
this.mode = "normal";
this.compileMatcher();
}
},
shouldUseXPath: function() {
......
// XPath can't do namespaced attributes, nor can it read
// the "checked" property from DOM nodes
if ((/(\[[\w-]*?:|:checked)/).test(this.expression))
if ((/(\[[\w-]*?:|:checked)/).test(e))
return false;
return true;
},
shouldUseSelectorsAPI: function() {
if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
if (!Selector._div) Selector._div = new Element('div');
// Make sure the browser treats the selector as valid. Test on an
// isolated element to minimize cost of this check.
try {
Selector._div.querySelector(this.expression);
} catch(e) {
return false;
}
return true;
},
compileMatcher: function() {
if (this.shouldUseXPath())
return this.compileXPathMatcher();
var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
c = Selector.criteria, le, p, m;
......
p = ps[i];
if (m = e.match(p)) {
this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
new Template(c[i]).evaluate(m));
new Template(c[i]).evaluate(m));
e = e.replace(m[0], '');
break;
}
......
findElements: function(root) {
root = root || document;
if (this.xpath) return document._getElementsByXPath(this.xpath, root);
return this.matcher(root);
var e = this.expression, results;
switch (this.mode) {
case 'selectorsAPI':
// querySelectorAll queries document-wide, then filters to descendants
// of the context element. That's not what we want.
// Add an explicit context to the selector if necessary.
if (root !== document) {
var oldId = root.id, id = $(root).identify();
e = "#" + id + " " + e;
}
results = $A(root.querySelectorAll(e)).map(Element.extend);
root.id = oldId;
return results;
case 'xpath':
return document._getElementsByXPath(this.xpath, root);
default:
return this.matcher(root);
}
},
match: function(element) {
......
'first-child': '[not(preceding-sibling::*)]',
'last-child': '[not(following-sibling::*)]',
'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
'empty': "[count(*) = 0 and (count(text()) = 0)]",
'checked': "[@checked]",
'disabled': "[@disabled]",
'enabled': "[not(@disabled)]",
'disabled': "[(@disabled) and (@type!='hidden')]",
'enabled': "[not(@disabled) and (@type!='hidden')]",
'not': function(m) {
var e = m[6], p = Selector.patterns,
x = Selector.xpath, le, v;
......
className: /^\.([\w\-\*]+)(\b|$)/,
pseudo:
/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
attrPresence: /^\[([\w]+)\]/,
attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
},
......
nextElementSibling: function(node) {
while (node = node.nextSibling)
if (node.nodeType == 1) return node;
if (node.nodeType == 1) return node;
return null;
},
......
'empty': function(nodes, value, root) {
for (var i = 0, results = [], node; node = nodes[i]; i++) {
// IE treats comments as element nodes
if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
if (node.tagName == '!' || node.firstChild) continue;
results.push(node);
}
return results;
......
'enabled': function(nodes, value, root) {
for (var i = 0, results = [], node; node = nodes[i]; i++)
if (!node.disabled) results.push(node);
if (!node.disabled && (!node.type || node.type !== 'hidden'))
results.push(node);
return results;
},
......
operators: {
'=': function(nv, v) { return nv == v; },
'!=': function(nv, v) { return nv != v; },
'^=': function(nv, v) { return nv.startsWith(v); },
'^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
'$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
'*=': function(nv, v) { return nv == v || nv && nv.include(v); },
'$=': function(nv, v) { return nv.endsWith(v); },
'*=': function(nv, v) { return nv.include(v); },
'~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
'|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
'|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
'-').include('-' + (v || "").toUpperCase() + '-'); }
},
split: function(expression) {
......
var data = elements.inject({ }, function(result, element) {
if (!element.disabled && element.name) {
key = element.name; value = $(element).getValue();
if (value != null && (element.type != 'submit' || (!submitted &&
if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
submit !== false && (!submit || key == submit) && (submitted = true)))) {
if (key in result) {
// a key is already present; construct an array of values
......
disable: function(element) {
element = $(element);
element.blur();
element.disabled = true;
return element;
},
......
else element.value = value;
},
select: function(element, index) {
if (Object.isUndefined(index))
select: function(element, value) {
if (Object.isUndefined(value))
return this[element.type == 'select-one' ?
'selectOne' : 'selectMany'](element);
else {
var opt, value, single = !Object.isArray(index);
var opt, currentValue, single = !Object.isArray(value);
for (var i = 0, length = element.length; i < length; i++) {
opt = element.options[i];
value = this.optionValue(opt);
currentValue = this.optionValue(opt);
if (single) {
if (value == index) {
if (currentValue == value) {
opt.selected = true;
return;
}
}
else opt.selected = index.include(value);
else opt.selected = value.include(currentValue);
}
}
},
......
isRightClick: function(event) { return isButton(event, 2) },
element: function(event) {
var node = Event.extend(event).target;
return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
event = Event.extend(event);
var node = event.target,
type = event.type,
currentTarget = event.currentTarget;
if (currentTarget && currentTarget.tagName) {
// Firefox screws up the "click" event when moving between radio buttons
// via arrow keys. It also screws up the "load" and "error" events on images,
// reporting the document as the target instead of the original image.
if (type === 'load' || type === 'error' ||
(type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
&& currentTarget.type === 'radio'))
node = currentTarget;
}
if (node.nodeType == Node.TEXT_NODE) node = node.parentNode;
return Element.extend(node);
},
findElement: function(event, expression) {
......
},
pointer: function(event) {
var docElement = document.documentElement,
body = document.body || { scrollLeft: 0, scrollTop: 0 };
return {
x: event.pageX || (event.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft)),
(docElement.scrollLeft || body.scrollLeft) -
(docElement.clientLeft || 0)),
y: event.pageY || (event.clientY +
(document.documentElement.scrollTop || document.body.scrollTop))
(docElement.scrollTop || body.scrollTop) -
(docElement.clientTop || 0))
};
},
......
};
} else {
Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__'];
Object.extend(Event.prototype, methods);
return Prototype.K;
}
......
cache[id][eventName] = null;
}
// Internet Explorer needs to remove event handlers on page unload
// in order to avoid memory leaks.
if (window.attachEvent) {
window.attachEvent("onunload", destroyCache);
}
// Safari has a dummy event handler on page unload so that it won't
// use its bfcache. Safari <= 3.1 has an issue with restoring the "document"
// object when page is returned to via the back button using its bfcache.
if (Prototype.Browser.WebKit) {
window.addEventListener('unload', Prototype.emptyFunction, false);
}
return {
observe: function(element, eventName, handler) {
element = $(element);
    (1-1/1)