function $(element) { if (arguments.length > 1) { for (var i = 0, elements = [], length = arguments.length; i < length; i++) elements.push($(arguments[i])); return elements; } if (typeof element == 'string') 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(query.snapshotItem(i)); return results; }; } document.getElementsByClassName = function(className, parentElement) { if (Prototype.BrowserFeatures.XPath) { var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]"; return document._getElementsByXPath(q, parentElement); } else { var children = ($(parentElement) || document.body).getElementsByTagName('*'); var elements = [], child; for (var i = 0, length = children.length; i < length; i++) { child = children[i]; if (Element.hasClassName(child, className)) elements.push(Element.extend(child)); } return elements; } }; /*--------------------------------------------------------------------------*/ if (!window.Element) var Element = new Object(); Element.extend = function(element) { var F = Prototype.BrowserFeatures; if (!element || !element.tagName || element.nodeType == 3 || element._extended || F.SpecificElementExtensions || element == window) return element; var methods = {}, tagName = element.tagName, cache = Element.extend.cache, T = Element.Methods.ByTag; // extend methods for all tags (Safari doesn't need this) if (!F.ElementExtensions) { Object.extend(methods, Element.Methods), Object.extend(methods, Element.Methods.Simulated); } // extend methods for specific tags if (T[tagName]) Object.extend(methods, T[tagName]); for (var property in methods) { var value = methods[property]; if (typeof value == 'function' && !(property in element)) element[property] = cache.findOrStore(value); } element._extended = true; return element; }; Element.extend.cache = { findOrStore: function(value) { return this[value] = this[value] || function() { return value.apply(null, [this].concat($A(arguments))); } } }; Element.Methods = { visible: function(element) { return $(element).style.display != 'none'; }, toggle: function(element) { element = $(element); Element[Element.visible(element) ? 'hide' : 'show'](element); return element; }, hide: function(element) { $(element).style.display = 'none'; return element; }, show: function(element) { $(element).style.display = ''; return element; }, remove: function(element) { element = $(element); element.parentNode.removeChild(element); return element; }, update: function(element, html) { html = typeof html == 'undefined' ? '' : html.toString(); $(element).innerHTML = html.stripScripts(); setTimeout(function() {html.evalScripts()}, 10); return element; }, replace: function(element, html) { element = $(element); html = typeof html == 'undefined' ? '' : html.toString(); if (element.outerHTML) { element.outerHTML = html.stripScripts(); } else { var range = element.ownerDocument.createRange(); range.selectNodeContents(element); element.parentNode.replaceChild( range.createContextualFragment(html.stripScripts()), element); } setTimeout(function() {html.evalScripts()}, 10); return element; }, inspect: function(element) { element = $(element); var result = '<' + element.tagName.toLowerCase(); $H({'id': 'id', 'className': 'class'}).each(function(pair) { var property = pair.first(), attribute = pair.last(); var value = (element[property] || '').toString(); if (value) result += ' ' + attribute + '=' + value.inspect(true); }); return result + '>'; }, recursivelyCollect: function(element, property) { element = $(element); var elements = []; while (element = element[property]) if (element.nodeType == 1) elements.push(Element.extend(element)); return elements; }, ancestors: function(element) { return $(element).recursivelyCollect('parentNode'); }, descendants: function(element) { return $A($(element).getElementsByTagName('*')); }, immediateDescendants: function(element) { if (!(element = $(element).firstChild)) return []; while (element && element.nodeType != 1) element = element.nextSibling; if (element) return [element].concat($(element).nextSiblings()); return []; }, previousSiblings: function(element) { return $(element).recursivelyCollect('previousSibling'); }, nextSiblings: function(element) { return $(element).recursivelyCollect('nextSibling'); }, siblings: function(element) { element = $(element); return element.previousSiblings().reverse().concat(element.nextSiblings()); }, match: function(element, selector) { if (typeof selector == 'string') selector = new Selector(selector); return selector.match($(element)); }, up: function(element, expression, index) { return Selector.findElement($(element).ancestors(), expression, index); }, down: function(element, expression, index) { return Selector.findElement($(element).descendants(), expression, index); }, previous: function(element, expression, index) { return Selector.findElement($(element).previousSiblings(), expression, index); }, next: function(element, expression, index) { return Selector.findElement($(element).nextSiblings(), expression, index); }, getElementsBySelector: function() { var args = $A(arguments), element = $(args.shift()); return Selector.findChildElements(element, args); }, getElementsByClassName: function(element, className) { return document.getElementsByClassName(className, element); }, readAttribute: function(element, name) { element = $(element); if (document.all && !window.opera) { var t = Element._attributeTranslations; if (t.values[name]) return t.values[name](element, name); if (t.names[name]) name = t.names[name]; var attribute = element.attributes[name]; if(attribute) return attribute.nodeValue; } return element.getAttribute(name); }, getHeight: function(element) { return $(element).getDimensions().height; }, getWidth: function(element) { return $(element).getDimensions().width; }, classNames: function(element) { return new Element.ClassNames(element); }, hasClassName: function(element, className) { if (!(element = $(element))) return; var elementClassName = element.className; if (elementClassName.length == 0) return false; if (elementClassName == className || elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) return true; return false; }, addClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element).add(className); return element; }, removeClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element).remove(className); return element; }, toggleClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className); return element; }, observe: function() { Event.observe.apply(Event, arguments); return $A(arguments).first(); }, stopObserving: function() { Event.stopObserving.apply(Event, arguments); return $A(arguments).first(); }, // removes whitespace-only text node children cleanWhitespace: function(element) { 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(); }, descendantOf: function(element, ancestor) { element = $(element), ancestor = $(ancestor); while (element = element.parentNode) if (element == ancestor) return true; return false; }, scrollTo: function(element) { element = $(element); var pos = Position.cumulativeOffset(element); window.scrollTo(pos[0], pos[1]); return element; }, getStyle: function(element, style) { element = $(element); style = style == 'float' ? 'cssFloat' : style.camelize(); var value = element.style[style]; if (!value) { 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; }, getOpacity: function(element) { return $(element).getStyle('opacity'); }, setStyle: function(element, styles) { element = $(element); var elementStyle = element.style; for (var property in styles) { var value = styles[property]; if (property == 'opacity') { element.setOpacity(value) } else { property = (property == 'float' || property == 'cssFloat') ? ((elementStyle.styleFloat === undefined) ? 'cssFloat' : 'styleFloat') : property.camelize(); elementStyle[property] = value; } } return element; }, setOpacity: function(element, value) { element = $(element); element.style.opacity = (value == 1 || value === '') ? '' : (value < 0.00001) ? 0 : value; return element; }, getDimensions: function(element) { element = $(element); var display = $(element).getStyle('display'); if (display != 'none' && display != null) // Safari bug return {width: element.offsetWidth, height: element.offsetHeight}; // All *Width and *Height properties give 0 on elements with display none, // so enable the element temporarily var els = element.style; var originalVisibility = els.visibility; var originalPosition = els.position; var originalDisplay = els.display; els.visibility = 'hidden'; els.position = 'absolute'; els.display = 'block'; var originalWidth = element.clientWidth; var originalHeight = element.clientHeight; els.display = originalDisplay; els.position = originalPosition; els.visibility = originalVisibility; return {width: originalWidth, height: originalHeight}; }, makePositioned: function(element) { element = $(element); var pos = Element.getStyle(element, 'position'); if (pos == 'static' || !pos) { element._madePositioned = true; element.style.position = 'relative'; // Opera returns the offset relative to the positioning context, when an // element is position relative but top and left have not been defined if (window.opera) { element.style.top = 0; element.style.left = 0; } } return element; }, 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; }, makeClipping: function(element) { element = $(element); if (element._overflow) return element; element._overflow = element.style.overflow || 'auto'; if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') element.style.overflow = 'hidden'; return element; }, undoClipping: function(element) { element = $(element); if (!element._overflow) return element; element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; element._overflow = null; return element; } }; Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf}); if (Prototype.Browser.Opera) { Element.Methods._getStyle = Element.Methods.getStyle; Element.Methods.getStyle = function(element, style) { switch(style) { case 'left': case 'top': case 'right': case 'bottom': if(Element._getStyle(element, 'position') == 'static') return null; default: return Element._getStyle(element, style); } }; } 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]; if (style == 'opacity') { if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) if (value[1]) return parseFloat(value[1]) / 100; return 1.0; } if (value == 'auto') { if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) return element['offset'+style.capitalize()] + 'px'; return null; } return value; }; Element.Methods.setOpacity = function(element, value) { element = $(element); var filter = element.getStyle('filter'), style = element.style; if (value == 1 || value === '') { style.filter = filter.replace(/alpha\([^\)]*\)/gi,''); return element; } else if (value < 0.00001) value = 0; style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') + 'alpha(opacity=' + (value * 100) + ')'; return element; }; } if (Prototype.Browser.Gecko) { Element.Methods.setOpacity = function(element, value) { element = $(element); element.style.opacity = (value == 1) ? 0.999999 : (value === '') ? '' : (value < 0.00001) ? 0 : value; return element; }; } Element._attributeTranslations = {}; Element._attributeTranslations.names = { colspan: "colSpan", rowspan: "rowSpan", valign: "vAlign", datetime: "dateTime", accesskey: "accessKey", tabindex: "tabIndex", enctype: "encType", maxlength: "maxLength", readonly: "readOnly", longdesc: "longDesc" }; Element._attributeTranslations.values = { _getAttr: function(element, attribute) { return element.getAttribute(attribute, 2); }, _flag: function(element, attribute) { return $(element).hasAttribute(attribute) ? attribute : null; }, style: function(element) { return element.style.cssText.toLowerCase(); }, title: function(element) { var node = element.getAttributeNode('title'); return node.specified ? node.nodeValue : null; } }; Object.extend(Element._attributeTranslations.values, { href: Element._attributeTranslations.values._getAttr, src: Element._attributeTranslations.values._getAttr, disabled: Element._attributeTranslations.values._flag, checked: Element._attributeTranslations.values._flag, readonly: Element._attributeTranslations.values._flag, multiple: Element._attributeTranslations.values._flag }); Element.Methods.Simulated = { hasAttribute: function(element, attribute) { var t = Element._attributeTranslations; attribute = t.names[attribute] || attribute; return $(element).getAttributeNode(attribute).specified; } }; Element.Methods.ByTag = {}; // IE is missing .innerHTML support for TABLE-related elements if (Prototype.Browser.IE){ Element.Methods.update = function(element, html) { element = $(element); html = typeof html == 'undefined' ? '' : html.toString(); var tagName = element.tagName.toUpperCase(); if (['THEAD','TBODY','TR','TD'].include(tagName)) { var div = document.createElement('div'); switch (tagName) { case 'THEAD': case 'TBODY': div.innerHTML = '
' + html.stripScripts() + ' |