AutorÃa | Ultima modificación | Ver Log |
YUI.add('yui2-dom', function(Y) {var YAHOO = Y.YUI2;/*Copyright (c) 2011, Yahoo! Inc. All rights reserved.Code licensed under the BSD License:http://developer.yahoo.com/yui/license.htmlversion: 2.9.0*//*** The dom module provides helper methods for manipulating Dom elements.* @module dom**/(function() {// for use with generateId (global to save state if Dom is overwritten)YAHOO.env._id_counter = YAHOO.env._id_counter || 0;// internal shorthandvar Y = YAHOO.util,lang = YAHOO.lang,UA = YAHOO.env.ua,trim = YAHOO.lang.trim,propertyCache = {}, // for faster hyphen convertsreCache = {}, // cache className regexesRE_TABLE = /^t(?:able|d|h)$/i, // for _calcBordersRE_COLOR = /color$/i,// DOM aliasesdocument = window.document,documentElement = document.documentElement,// string constantsOWNER_DOCUMENT = 'ownerDocument',DEFAULT_VIEW = 'defaultView',DOCUMENT_ELEMENT = 'documentElement',COMPAT_MODE = 'compatMode',OFFSET_LEFT = 'offsetLeft',OFFSET_TOP = 'offsetTop',OFFSET_PARENT = 'offsetParent',PARENT_NODE = 'parentNode',NODE_TYPE = 'nodeType',TAG_NAME = 'tagName',SCROLL_LEFT = 'scrollLeft',SCROLL_TOP = 'scrollTop',GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect',GET_COMPUTED_STYLE = 'getComputedStyle',CURRENT_STYLE = 'currentStyle',CSS1_COMPAT = 'CSS1Compat',_BACK_COMPAT = 'BackCompat',_CLASS = 'class', // underscore due to reserved wordCLASS_NAME = 'className',EMPTY = '',SPACE = ' ',C_START = '(?:^|\\s)',C_END = '(?= |$)',G = 'g',POSITION = 'position',FIXED = 'fixed',RELATIVE = 'relative',LEFT = 'left',TOP = 'top',MEDIUM = 'medium',BORDER_LEFT_WIDTH = 'borderLeftWidth',BORDER_TOP_WIDTH = 'borderTopWidth',// brower detectionisOpera = UA.opera,isSafari = UA.webkit,isGecko = UA.gecko,isIE = UA.ie;/*** Provides helper methods for DOM elements.* @namespace YAHOO.util* @class Dom* @requires yahoo, event*/Y.Dom = {CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8'for': 'htmlFor','class': CLASS_NAME} : { // w3c'htmlFor': 'for','className': _CLASS},DOT_ATTRIBUTES: {checked: true},/*** Returns an HTMLElement reference.* @method get* @param {String | HTMLElement |Array} el Accepts a string to use as an ID for getting a DOM reference, an actual DOM reference, or an Array of IDs and/or HTMLElements.* @return {HTMLElement | Array} A DOM reference to an HTML element or an array of HTMLElements.*/get: function(el) {var id, nodes, c, i, len, attr, ret = null;if (el) {if (typeof el == 'string' || typeof el == 'number') { // idid = el + '';el = document.getElementById(el);attr = (el) ? el.attributes : null;if (el && attr && attr.id && attr.id.value === id) { // IE: avoid false match on "name" attributereturn el;} else if (el && document.all) { // filter by nameel = null;nodes = document.all[id];if (nodes && nodes.length) {for (i = 0, len = nodes.length; i < len; ++i) {if (nodes[i].id === id) {return nodes[i];}}}}} else if (Y.Element && el instanceof Y.Element) {el = el.get('element');} else if (!el.nodeType && 'length' in el) { // array-likec = [];for (i = 0, len = el.length; i < len; ++i) {c[c.length] = Y.Dom.get(el[i]);}el = c;}ret = el;}return ret;},getComputedStyle: function(el, property) {if (window[GET_COMPUTED_STYLE]) {return el[OWNER_DOCUMENT][DEFAULT_VIEW][GET_COMPUTED_STYLE](el, null)[property];} else if (el[CURRENT_STYLE]) {return Y.Dom.IE_ComputedStyle.get(el, property);}},/*** Normalizes currentStyle and ComputedStyle.* @method getStyle* @param {String | HTMLElement |Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.* @param {String} property The style property whose value is returned.* @return {String | Array} The current value of the style property for the element(s).*/getStyle: function(el, property) {return Y.Dom.batch(el, Y.Dom._getStyle, property);},// branching at load instead of runtime_getStyle: function() {if (window[GET_COMPUTED_STYLE]) { // W3C DOM methodreturn function(el, property) {property = (property === 'float') ? property = 'cssFloat' :Y.Dom._toCamel(property);var value = el.style[property],computed;if (!value) {computed = el[OWNER_DOCUMENT][DEFAULT_VIEW][GET_COMPUTED_STYLE](el, null);if (computed) { // test computed before touching for safarivalue = computed[property];}}return value;};} else if (documentElement[CURRENT_STYLE]) {return function(el, property) {var value;switch(property) {case 'opacity' :// IE opacity uses filtervalue = 100;try { // will error if no DXImageTransformvalue = el.filters['DXImageTransform.Microsoft.Alpha'].opacity;} catch(e) {try { // make sure its in the documentvalue = el.filters('alpha').opacity;} catch(err) {YAHOO.log('getStyle: IE filter failed','error', 'Dom');}}return value / 100;case 'float': // fix reserved wordproperty = 'styleFloat'; // fall throughdefault:property = Y.Dom._toCamel(property);value = el[CURRENT_STYLE] ? el[CURRENT_STYLE][property] : null;return ( el.style[property] || value );}};}}(),/*** Wrapper for setting style properties of HTMLElements. Normalizes "opacity" across modern browsers.* @method setStyle* @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.* @param {String} property The style property to be set.* @param {String} val The value to apply to the given property.*/setStyle: function(el, property, val) {Y.Dom.batch(el, Y.Dom._setStyle, { prop: property, val: val });},_setStyle: function() {if (!window.getComputedStyle && document.documentElement.currentStyle) {return function(el, args) {var property = Y.Dom._toCamel(args.prop),val = args.val;if (el) {switch (property) {case 'opacity':// remove filter if unsetting or full opacityif (val === '' || val === null || val === 1) {el.style.removeAttribute('filter');} else if ( lang.isString(el.style.filter) ) { // in case not appendedel.style.filter = 'alpha(opacity=' + val * 100 + ')';if (!el[CURRENT_STYLE] || !el[CURRENT_STYLE].hasLayout) {el.style.zoom = 1; // when no layout or cant tell}}break;case 'float':property = 'styleFloat';default:el.style[property] = val;}} else {YAHOO.log('element ' + el + ' is undefined', 'error', 'Dom');}};} else {return function(el, args) {var property = Y.Dom._toCamel(args.prop),val = args.val;if (el) {if (property == 'float') {property = 'cssFloat';}el.style[property] = val;} else {YAHOO.log('element ' + el + ' is undefined', 'error', 'Dom');}};}}(),/*** Gets the current position of an element based on page coordinates.* Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).* @method getXY* @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM* reference, or an Array of IDs and/or HTMLElements* @return {Array} The XY position of the element(s)*/getXY: function(el) {return Y.Dom.batch(el, Y.Dom._getXY);},_canPosition: function(el) {return ( Y.Dom._getStyle(el, 'display') !== 'none' && Y.Dom._inDoc(el) );},_getXY: function(node) {var scrollLeft, scrollTop, box, doc,clientTop, clientLeft,round = Math.round, // TODO: round?xy = false;if (Y.Dom._canPosition(node)) {box = node[GET_BOUNDING_CLIENT_RECT]();doc = node[OWNER_DOCUMENT];scrollLeft = Y.Dom.getDocumentScrollLeft(doc);scrollTop = Y.Dom.getDocumentScrollTop(doc);xy = [box[LEFT], box[TOP]];// remove IE default documentElement offset (border)if (clientTop || clientLeft) {xy[0] -= clientLeft;xy[1] -= clientTop;}if ((scrollTop || scrollLeft)) {xy[0] += scrollLeft;xy[1] += scrollTop;}// gecko may return sub-pixel (non-int) valuesxy[0] = round(xy[0]);xy[1] = round(xy[1]);} else {YAHOO.log('getXY failed: element not positionable (either not in a document or not displayed)', 'error', 'Dom');}return xy;},/*** Gets the current X position of an element based on page coordinates. The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).* @method getX* @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements* @return {Number | Array} The X position of the element(s)*/getX: function(el) {var f = function(el) {return Y.Dom.getXY(el)[0];};return Y.Dom.batch(el, f, Y.Dom, true);},/*** Gets the current Y position of an element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).* @method getY* @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements* @return {Number | Array} The Y position of the element(s)*/getY: function(el) {var f = function(el) {return Y.Dom.getXY(el)[1];};return Y.Dom.batch(el, f, Y.Dom, true);},/*** Set the position of an html element in page coordinates, regardless of how the element is positioned.* The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).* @method setXY* @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements* @param {Array} pos Contains X & Y values for new position (coordinates are page-based)* @param {Boolean} noRetry By default we try and set the position a second time if the first fails*/setXY: function(el, pos, noRetry) {Y.Dom.batch(el, Y.Dom._setXY, { pos: pos, noRetry: noRetry });},_setXY: function(node, args) {var pos = Y.Dom._getStyle(node, POSITION),setStyle = Y.Dom.setStyle,xy = args.pos,noRetry = args.noRetry,delta = [ // assuming pixels; if not we will have to retryparseInt( Y.Dom.getComputedStyle(node, LEFT), 10 ),parseInt( Y.Dom.getComputedStyle(node, TOP), 10 )],currentXY,newXY;currentXY = Y.Dom._getXY(node);if (!xy || currentXY === false) { // has to be part of doc to have xyYAHOO.log('xy failed: node not available', 'error', 'Node');return false;}if (pos == 'static') { // default to relativepos = RELATIVE;setStyle(node, POSITION, pos);}if ( isNaN(delta[0]) ) {// in case of 'auto'delta[0] = (pos == RELATIVE) ? 0 : node[OFFSET_LEFT];}if ( isNaN(delta[1]) ) { // in case of 'auto'delta[1] = (pos == RELATIVE) ? 0 : node[OFFSET_TOP];}if (xy[0] !== null) { // from setXsetStyle(node, LEFT, xy[0] - currentXY[0] + delta[0] + 'px');}if (xy[1] !== null) { // from setYsetStyle(node, TOP, xy[1] - currentXY[1] + delta[1] + 'px');}if (!noRetry) {newXY = Y.Dom._getXY(node);// if retry is true, try one more time if we missif ( (xy[0] !== null && newXY[0] != xy[0]) ||(xy[1] !== null && newXY[1] != xy[1]) ) {Y.Dom._setXY(node, { pos: xy, noRetry: true });}}YAHOO.log('setXY setting position to ' + xy, 'info', 'Node');},/*** Set the X position of an html element in page coordinates, regardless of how the element is positioned.* The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).* @method setX* @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.* @param {Int} x The value to use as the X coordinate for the element(s).*/setX: function(el, x) {Y.Dom.setXY(el, [x, null]);},/*** Set the Y position of an html element in page coordinates, regardless of how the element is positioned.* The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).* @method setY* @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.* @param {Int} x To use as the Y coordinate for the element(s).*/setY: function(el, y) {Y.Dom.setXY(el, [null, y]);},/*** Returns the region position of the given element.* The element must be part of the DOM tree to have a region (display:none or elements not appended return false).* @method getRegion* @param {String | HTMLElement | Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.* @return {Region | Array} A Region or array of Region instances containing "top, left, bottom, right" member data.*/getRegion: function(el) {var f = function(el) {var region = false;if ( Y.Dom._canPosition(el) ) {region = Y.Region.getRegion(el);YAHOO.log('getRegion returning ' + region, 'info', 'Dom');} else {YAHOO.log('getRegion failed: element not positionable (either not in a document or not displayed)', 'error', 'Dom');}return region;};return Y.Dom.batch(el, f, Y.Dom, true);},/*** Returns the width of the client (viewport).* @method getClientWidth* @deprecated Now using getViewportWidth. This interface left intact for back compat.* @return {Int} The width of the viewable area of the page.*/getClientWidth: function() {return Y.Dom.getViewportWidth();},/*** Returns the height of the client (viewport).* @method getClientHeight* @deprecated Now using getViewportHeight. This interface left intact for back compat.* @return {Int} The height of the viewable area of the page.*/getClientHeight: function() {return Y.Dom.getViewportHeight();},/*** Returns an array of HTMLElements with the given class.* For optimized performance, include a tag and/or root node when possible.* Note: This method operates against a live collection, so modifying the* collection in the callback (removing/appending nodes, etc.) will have* side effects. Instead you should iterate the returned nodes array,* as you would with the native "getElementsByTagName" method.* @method getElementsByClassName* @param {String} className The class name to match against* @param {String} tag (optional) The tag name of the elements being collected* @param {String | HTMLElement} root (optional) The HTMLElement or an ID to use as the starting point.* This element is not included in the className scan.* @param {Function} apply (optional) A function to apply to each element when found* @param {Any} o (optional) An optional arg that is passed to the supplied method* @param {Boolean} overrides (optional) Whether or not to override the scope of "method" with "o"* @return {Array} An array of elements that have the given class name*/getElementsByClassName: function(className, tag, root, apply, o, overrides) {tag = tag || '*';root = (root) ? Y.Dom.get(root) : null || document;if (!root) {return [];}var nodes = [],elements = root.getElementsByTagName(tag),hasClass = Y.Dom.hasClass;for (var i = 0, len = elements.length; i < len; ++i) {if ( hasClass(elements[i], className) ) {nodes[nodes.length] = elements[i];}}if (apply) {Y.Dom.batch(nodes, apply, o, overrides);}return nodes;},/*** Determines whether an HTMLElement has the given className.* @method hasClass* @param {String | HTMLElement | Array} el The element or collection to test* @param {String | RegExp} className the class name to search for, or a regular* expression to match against* @return {Boolean | Array} A boolean value or array of boolean values*/hasClass: function(el, className) {return Y.Dom.batch(el, Y.Dom._hasClass, className);},_hasClass: function(el, className) {var ret = false,current;if (el && className) {current = Y.Dom._getAttribute(el, CLASS_NAME) || EMPTY;if (current) { // convert line breaks, tabs and other delims to spacescurrent = current.replace(/\s+/g, SPACE);}if (className.exec) {ret = className.test(current);} else {ret = className && (SPACE + current + SPACE).indexOf(SPACE + className + SPACE) > -1;}} else {YAHOO.log('hasClass called with invalid arguments', 'warn', 'Dom');}return ret;},/*** Adds a class name to a given element or collection of elements.* @method addClass* @param {String | HTMLElement | Array} el The element or collection to add the class to* @param {String} className the class name to add to the class attribute* @return {Boolean | Array} A pass/fail boolean or array of booleans*/addClass: function(el, className) {return Y.Dom.batch(el, Y.Dom._addClass, className);},_addClass: function(el, className) {var ret = false,current;if (el && className) {current = Y.Dom._getAttribute(el, CLASS_NAME) || EMPTY;if ( !Y.Dom._hasClass(el, className) ) {Y.Dom.setAttribute(el, CLASS_NAME, trim(current + SPACE + className));ret = true;}} else {YAHOO.log('addClass called with invalid arguments', 'warn', 'Dom');}return ret;},/*** Removes a class name from a given element or collection of elements.* @method removeClass* @param {String | HTMLElement | Array} el The element or collection to remove the class from* @param {String} className the class name to remove from the class attribute* @return {Boolean | Array} A pass/fail boolean or array of booleans*/removeClass: function(el, className) {return Y.Dom.batch(el, Y.Dom._removeClass, className);},_removeClass: function(el, className) {var ret = false,current,newClass,attr;if (el && className) {current = Y.Dom._getAttribute(el, CLASS_NAME) || EMPTY;Y.Dom.setAttribute(el, CLASS_NAME, current.replace(Y.Dom._getClassRegex(className), EMPTY));newClass = Y.Dom._getAttribute(el, CLASS_NAME);if (current !== newClass) { // else nothing changedY.Dom.setAttribute(el, CLASS_NAME, trim(newClass)); // trim after comparing to current classret = true;if (Y.Dom._getAttribute(el, CLASS_NAME) === '') { // remove class attribute if emptyattr = (el.hasAttribute && el.hasAttribute(_CLASS)) ? _CLASS : CLASS_NAME;YAHOO.log('removeClass removing empty class attribute', 'info', 'Dom');el.removeAttribute(attr);}}} else {YAHOO.log('removeClass called with invalid arguments', 'warn', 'Dom');}return ret;},/*** Replace a class with another class for a given element or collection of elements.* If no oldClassName is present, the newClassName is simply added.* @method replaceClass* @param {String | HTMLElement | Array} el The element or collection to remove the class from* @param {String} oldClassName the class name to be replaced* @param {String} newClassName the class name that will be replacing the old class name* @return {Boolean | Array} A pass/fail boolean or array of booleans*/replaceClass: function(el, oldClassName, newClassName) {return Y.Dom.batch(el, Y.Dom._replaceClass, { from: oldClassName, to: newClassName });},_replaceClass: function(el, classObj) {var className,from,to,ret = false,current;if (el && classObj) {from = classObj.from;to = classObj.to;if (!to) {ret = false;} else if (!from) { // just add if no "from"ret = Y.Dom._addClass(el, classObj.to);} else if (from !== to) { // else nothing to replace// May need to lead with DBLSPACE?current = Y.Dom._getAttribute(el, CLASS_NAME) || EMPTY;className = (SPACE + current.replace(Y.Dom._getClassRegex(from), SPACE + to).replace(/\s+/g, SPACE)). // normalize white spacesplit(Y.Dom._getClassRegex(to));// insert to into what would have been the first occurrence slotclassName.splice(1, 0, SPACE + to);Y.Dom.setAttribute(el, CLASS_NAME, trim(className.join(EMPTY)));ret = true;}} else {YAHOO.log('replaceClass called with invalid arguments', 'warn', 'Dom');}return ret;},/*** Returns an ID and applies it to the element "el", if provided.* @method generateId* @param {String | HTMLElement | Array} el (optional) An optional element array of elements to add an ID to (no ID is added if one is already present).* @param {String} prefix (optional) an optional prefix to use (defaults to "yui-gen").* @return {String | Array} The generated ID, or array of generated IDs (or original ID if already present on an element)*/generateId: function(el, prefix) {prefix = prefix || 'yui-gen';var f = function(el) {if (el && el.id) { // do not override existing IDYAHOO.log('generateId returning existing id ' + el.id, 'info', 'Dom');return el.id;}var id = prefix + YAHOO.env._id_counter++;YAHOO.log('generateId generating ' + id, 'info', 'Dom');if (el) {if (el[OWNER_DOCUMENT] && el[OWNER_DOCUMENT].getElementById(id)) { // in case one already exists// use failed id plus prefix to help ensure uniquenessreturn Y.Dom.generateId(el, id + prefix);}el.id = id;}return id;};// batch fails when no element, so just generate and return single IDreturn Y.Dom.batch(el, f, Y.Dom, true) || f.apply(Y.Dom, arguments);},/*** Determines whether an HTMLElement is an ancestor of another HTML element in the DOM hierarchy.* @method isAncestor* @param {String | HTMLElement} haystack The possible ancestor* @param {String | HTMLElement} needle The possible descendent* @return {Boolean} Whether or not the haystack is an ancestor of needle*/isAncestor: function(haystack, needle) {haystack = Y.Dom.get(haystack);needle = Y.Dom.get(needle);var ret = false;if ( (haystack && needle) && (haystack[NODE_TYPE] && needle[NODE_TYPE]) ) {if (haystack.contains && haystack !== needle) { // contains returns true when equalret = haystack.contains(needle);}else if (haystack.compareDocumentPosition) { // geckoret = !!(haystack.compareDocumentPosition(needle) & 16);}} else {YAHOO.log('isAncestor failed; invalid input: ' + haystack + ',' + needle, 'error', 'Dom');}YAHOO.log('isAncestor(' + haystack + ',' + needle + ' returning ' + ret, 'info', 'Dom');return ret;},/*** Determines whether an HTMLElement is present in the current document.* @method inDocument* @param {String | HTMLElement} el The element to search for* @param {Object} doc An optional document to search, defaults to element's owner document* @return {Boolean} Whether or not the element is present in the current document*/inDocument: function(el, doc) {return Y.Dom._inDoc(Y.Dom.get(el), doc);},_inDoc: function(el, doc) {var ret = false;if (el && el[TAG_NAME]) {doc = doc || el[OWNER_DOCUMENT];ret = Y.Dom.isAncestor(doc[DOCUMENT_ELEMENT], el);} else {YAHOO.log('inDocument failed: invalid input', 'error', 'Dom');}return ret;},/*** Returns an array of HTMLElements that pass the test applied by supplied boolean method.* For optimized performance, include a tag and/or root node when possible.* Note: This method operates against a live collection, so modifying the* collection in the callback (removing/appending nodes, etc.) will have* side effects. Instead you should iterate the returned nodes array,* as you would with the native "getElementsByTagName" method.* @method getElementsBy* @param {Function} method - A boolean method for testing elements which receives the element as its only argument.* @param {String} tag (optional) The tag name of the elements being collected* @param {String | HTMLElement} root (optional) The HTMLElement or an ID to use as the starting point* @param {Function} apply (optional) A function to apply to each element when found* @param {Any} o (optional) An optional arg that is passed to the supplied method* @param {Boolean} overrides (optional) Whether or not to override the scope of "method" with "o"* @return {Array} Array of HTMLElements*/getElementsBy: function(method, tag, root, apply, o, overrides, firstOnly) {tag = tag || '*';root = (root) ? Y.Dom.get(root) : null || document;var ret = (firstOnly) ? null : [],elements;// in case Dom.get() returns nullif (root) {elements = root.getElementsByTagName(tag);for (var i = 0, len = elements.length; i < len; ++i) {if ( method(elements[i]) ) {if (firstOnly) {ret = elements[i];break;} else {ret[ret.length] = elements[i];}}}if (apply) {Y.Dom.batch(ret, apply, o, overrides);}}YAHOO.log('getElementsBy returning ' + ret, 'info', 'Dom');return ret;},/*** Returns the first HTMLElement that passes the test applied by the supplied boolean method.* @method getElementBy* @param {Function} method - A boolean method for testing elements which receives the element as its only argument.* @param {String} tag (optional) The tag name of the elements being collected* @param {String | HTMLElement} root (optional) The HTMLElement or an ID to use as the starting point* @return {HTMLElement}*/getElementBy: function(method, tag, root) {return Y.Dom.getElementsBy(method, tag, root, null, null, null, true);},/*** Runs the supplied method against each item in the Collection/Array.* The method is called with the element(s) as the first arg, and the optional param as the second ( method(el, o) ).* @method batch* @param {String | HTMLElement | Array} el (optional) An element or array of elements to apply the method to* @param {Function} method The method to apply to the element(s)* @param {Any} o (optional) An optional arg that is passed to the supplied method* @param {Boolean} overrides (optional) Whether or not to override the scope of "method" with "o"* @return {Any | Array} The return value(s) from the supplied method*/batch: function(el, method, o, overrides) {var collection = [],scope = (overrides) ? o : null;el = (el && (el[TAG_NAME] || el.item)) ? el : Y.Dom.get(el); // skip get() when possibleif (el && method) {if (el[TAG_NAME] || el.length === undefined) { // element or not array-likereturn method.call(scope, el, o);}for (var i = 0; i < el.length; ++i) {collection[collection.length] = method.call(scope || el[i], el[i], o);}} else {YAHOO.log('batch called with invalid arguments', 'warn', 'Dom');return false;}return collection;},/*** Returns the height of the document.* @method getDocumentHeight* @return {Int} The height of the actual document (which includes the body and its margin).*/getDocumentHeight: function() {var scrollHeight = (document[COMPAT_MODE] != CSS1_COMPAT || isSafari) ? document.body.scrollHeight : documentElement.scrollHeight,h = Math.max(scrollHeight, Y.Dom.getViewportHeight());YAHOO.log('getDocumentHeight returning ' + h, 'info', 'Dom');return h;},/*** Returns the width of the document.* @method getDocumentWidth* @return {Int} The width of the actual document (which includes the body and its margin).*/getDocumentWidth: function() {var scrollWidth = (document[COMPAT_MODE] != CSS1_COMPAT || isSafari) ? document.body.scrollWidth : documentElement.scrollWidth,w = Math.max(scrollWidth, Y.Dom.getViewportWidth());YAHOO.log('getDocumentWidth returning ' + w, 'info', 'Dom');return w;},/*** Returns the current height of the viewport.* @method getViewportHeight* @return {Int} The height of the viewable area of the page (excludes scrollbars).*/getViewportHeight: function() {var height = self.innerHeight, // Safari, Operamode = document[COMPAT_MODE];if ( (mode || isIE) && !isOpera ) { // IE, Geckoheight = (mode == CSS1_COMPAT) ?documentElement.clientHeight : // Standardsdocument.body.clientHeight; // Quirks}YAHOO.log('getViewportHeight returning ' + height, 'info', 'Dom');return height;},/*** Returns the current width of the viewport.* @method getViewportWidth* @return {Int} The width of the viewable area of the page (excludes scrollbars).*/getViewportWidth: function() {var width = self.innerWidth, // Safarimode = document[COMPAT_MODE];if (mode || isIE) { // IE, Gecko, Operawidth = (mode == CSS1_COMPAT) ?documentElement.clientWidth : // Standardsdocument.body.clientWidth; // Quirks}YAHOO.log('getViewportWidth returning ' + width, 'info', 'Dom');return width;},/*** Returns the nearest ancestor that passes the test applied by supplied boolean method.* For performance reasons, IDs are not accepted and argument validation omitted.* @method getAncestorBy* @param {HTMLElement} node The HTMLElement to use as the starting point* @param {Function} method - A boolean method for testing elements which receives the element as its only argument.* @return {Object} HTMLElement or null if not found*/getAncestorBy: function(node, method) {while ( (node = node[PARENT_NODE]) ) { // NOTE: assignmentif ( Y.Dom._testElement(node, method) ) {YAHOO.log('getAncestorBy returning ' + node, 'info', 'Dom');return node;}}YAHOO.log('getAncestorBy returning null (no ancestor passed test)', 'error', 'Dom');return null;},/*** Returns the nearest ancestor with the given className.* @method getAncestorByClassName* @param {String | HTMLElement} node The HTMLElement or an ID to use as the starting point* @param {String} className* @return {Object} HTMLElement*/getAncestorByClassName: function(node, className) {node = Y.Dom.get(node);if (!node) {YAHOO.log('getAncestorByClassName failed: invalid node argument', 'error', 'Dom');return null;}var method = function(el) { return Y.Dom.hasClass(el, className); };return Y.Dom.getAncestorBy(node, method);},/*** Returns the nearest ancestor with the given tagName.* @method getAncestorByTagName* @param {String | HTMLElement} node The HTMLElement or an ID to use as the starting point* @param {String} tagName* @return {Object} HTMLElement*/getAncestorByTagName: function(node, tagName) {node = Y.Dom.get(node);if (!node) {YAHOO.log('getAncestorByTagName failed: invalid node argument', 'error', 'Dom');return null;}var method = function(el) {return el[TAG_NAME] && el[TAG_NAME].toUpperCase() == tagName.toUpperCase();};return Y.Dom.getAncestorBy(node, method);},/*** Returns the previous sibling that is an HTMLElement.* For performance reasons, IDs are not accepted and argument validation omitted.* Returns the nearest HTMLElement sibling if no method provided.* @method getPreviousSiblingBy* @param {HTMLElement} node The HTMLElement to use as the starting point* @param {Function} method A boolean function used to test siblings* that receives the sibling node being tested as its only argument* @return {Object} HTMLElement or null if not found*/getPreviousSiblingBy: function(node, method) {while (node) {node = node.previousSibling;if ( Y.Dom._testElement(node, method) ) {return node;}}return null;},/*** Returns the previous sibling that is an HTMLElement* @method getPreviousSibling* @param {String | HTMLElement} node The HTMLElement or an ID to use as the starting point* @return {Object} HTMLElement or null if not found*/getPreviousSibling: function(node) {node = Y.Dom.get(node);if (!node) {YAHOO.log('getPreviousSibling failed: invalid node argument', 'error', 'Dom');return null;}return Y.Dom.getPreviousSiblingBy(node);},/*** Returns the next HTMLElement sibling that passes the boolean method.* For performance reasons, IDs are not accepted and argument validation omitted.* Returns the nearest HTMLElement sibling if no method provided.* @method getNextSiblingBy* @param {HTMLElement} node The HTMLElement to use as the starting point* @param {Function} method A boolean function used to test siblings* that receives the sibling node being tested as its only argument* @return {Object} HTMLElement or null if not found*/getNextSiblingBy: function(node, method) {while (node) {node = node.nextSibling;if ( Y.Dom._testElement(node, method) ) {return node;}}return null;},/*** Returns the next sibling that is an HTMLElement* @method getNextSibling* @param {String | HTMLElement} node The HTMLElement or an ID to use as the starting point* @return {Object} HTMLElement or null if not found*/getNextSibling: function(node) {node = Y.Dom.get(node);if (!node) {YAHOO.log('getNextSibling failed: invalid node argument', 'error', 'Dom');return null;}return Y.Dom.getNextSiblingBy(node);},/*** Returns the first HTMLElement child that passes the test method.* @method getFirstChildBy* @param {HTMLElement} node The HTMLElement to use as the starting point* @param {Function} method A boolean function used to test children* that receives the node being tested as its only argument* @return {Object} HTMLElement or null if not found*/getFirstChildBy: function(node, method) {var child = ( Y.Dom._testElement(node.firstChild, method) ) ? node.firstChild : null;return child || Y.Dom.getNextSiblingBy(node.firstChild, method);},/*** Returns the first HTMLElement child.* @method getFirstChild* @param {String | HTMLElement} node The HTMLElement or an ID to use as the starting point* @return {Object} HTMLElement or null if not found*/getFirstChild: function(node, method) {node = Y.Dom.get(node);if (!node) {YAHOO.log('getFirstChild failed: invalid node argument', 'error', 'Dom');return null;}return Y.Dom.getFirstChildBy(node);},/*** Returns the last HTMLElement child that passes the test method.* @method getLastChildBy* @param {HTMLElement} node The HTMLElement to use as the starting point* @param {Function} method A boolean function used to test children* that receives the node being tested as its only argument* @return {Object} HTMLElement or null if not found*/getLastChildBy: function(node, method) {if (!node) {YAHOO.log('getLastChild failed: invalid node argument', 'error', 'Dom');return null;}var child = ( Y.Dom._testElement(node.lastChild, method) ) ? node.lastChild : null;return child || Y.Dom.getPreviousSiblingBy(node.lastChild, method);},/*** Returns the last HTMLElement child.* @method getLastChild* @param {String | HTMLElement} node The HTMLElement or an ID to use as the starting point* @return {Object} HTMLElement or null if not found*/getLastChild: function(node) {node = Y.Dom.get(node);return Y.Dom.getLastChildBy(node);},/*** Returns an array of HTMLElement childNodes that pass the test method.* @method getChildrenBy* @param {HTMLElement} node The HTMLElement to start from* @param {Function} method A boolean function used to test children* that receives the node being tested as its only argument* @return {Array} A static array of HTMLElements*/getChildrenBy: function(node, method) {var child = Y.Dom.getFirstChildBy(node, method),children = child ? [child] : [];Y.Dom.getNextSiblingBy(child, function(node) {if ( !method || method(node) ) {children[children.length] = node;}return false; // fail test to collect all children});return children;},/*** Returns an array of HTMLElement childNodes.* @method getChildren* @param {String | HTMLElement} node The HTMLElement or an ID to use as the starting point* @return {Array} A static array of HTMLElements*/getChildren: function(node) {node = Y.Dom.get(node);if (!node) {YAHOO.log('getChildren failed: invalid node argument', 'error', 'Dom');}return Y.Dom.getChildrenBy(node);},/*** Returns the left scroll value of the document* @method getDocumentScrollLeft* @param {HTMLDocument} document (optional) The document to get the scroll value of* @return {Int} The amount that the document is scrolled to the left*/getDocumentScrollLeft: function(doc) {doc = doc || document;return Math.max(doc[DOCUMENT_ELEMENT].scrollLeft, doc.body.scrollLeft);},/*** Returns the top scroll value of the document* @method getDocumentScrollTop* @param {HTMLDocument} document (optional) The document to get the scroll value of* @return {Int} The amount that the document is scrolled to the top*/getDocumentScrollTop: function(doc) {doc = doc || document;return Math.max(doc[DOCUMENT_ELEMENT].scrollTop, doc.body.scrollTop);},/*** Inserts the new node as the previous sibling of the reference node* @method insertBefore* @param {String | HTMLElement} newNode The node to be inserted* @param {String | HTMLElement} referenceNode The node to insert the new node before* @return {HTMLElement} The node that was inserted (or null if insert fails)*/insertBefore: function(newNode, referenceNode) {newNode = Y.Dom.get(newNode);referenceNode = Y.Dom.get(referenceNode);if (!newNode || !referenceNode || !referenceNode[PARENT_NODE]) {YAHOO.log('insertAfter failed: missing or invalid arg(s)', 'error', 'Dom');return null;}return referenceNode[PARENT_NODE].insertBefore(newNode, referenceNode);},/*** Inserts the new node as the next sibling of the reference node* @method insertAfter* @param {String | HTMLElement} newNode The node to be inserted* @param {String | HTMLElement} referenceNode The node to insert the new node after* @return {HTMLElement} The node that was inserted (or null if insert fails)*/insertAfter: function(newNode, referenceNode) {newNode = Y.Dom.get(newNode);referenceNode = Y.Dom.get(referenceNode);if (!newNode || !referenceNode || !referenceNode[PARENT_NODE]) {YAHOO.log('insertAfter failed: missing or invalid arg(s)', 'error', 'Dom');return null;}if (referenceNode.nextSibling) {return referenceNode[PARENT_NODE].insertBefore(newNode, referenceNode.nextSibling);} else {return referenceNode[PARENT_NODE].appendChild(newNode);}},/*** Creates a Region based on the viewport relative to the document.* @method getClientRegion* @return {Region} A Region object representing the viewport which accounts for document scroll*/getClientRegion: function() {var t = Y.Dom.getDocumentScrollTop(),l = Y.Dom.getDocumentScrollLeft(),r = Y.Dom.getViewportWidth() + l,b = Y.Dom.getViewportHeight() + t;return new Y.Region(t, r, b, l);},/*** Provides a normalized attribute interface.* @method setAttribute* @param {String | HTMLElement} el The target element for the attribute.* @param {String} attr The attribute to set.* @param {String} val The value of the attribute.*/setAttribute: function(el, attr, val) {Y.Dom.batch(el, Y.Dom._setAttribute, { attr: attr, val: val });},_setAttribute: function(el, args) {var attr = Y.Dom._toCamel(args.attr),val = args.val;if (el && el.setAttribute) {// set as DOM property, except for BUTTON, which errors on property setterif (Y.Dom.DOT_ATTRIBUTES[attr] && el.tagName && el.tagName != 'BUTTON') {el[attr] = val;} else {attr = Y.Dom.CUSTOM_ATTRIBUTES[attr] || attr;el.setAttribute(attr, val);}} else {YAHOO.log('setAttribute method not available for ' + el, 'error', 'Dom');}},/*** Provides a normalized attribute interface.* @method getAttribute* @param {String | HTMLElement} el The target element for the attribute.* @param {String} attr The attribute to get.* @return {String} The current value of the attribute.*/getAttribute: function(el, attr) {return Y.Dom.batch(el, Y.Dom._getAttribute, attr);},_getAttribute: function(el, attr) {var val;attr = Y.Dom.CUSTOM_ATTRIBUTES[attr] || attr;if (Y.Dom.DOT_ATTRIBUTES[attr]) {val = el[attr];} else if (el && 'getAttribute' in el) {if (/^(?:href|src)$/.test(attr)) { // use IE flag to return exact valueval = el.getAttribute(attr, 2);} else {val = el.getAttribute(attr);}} else {YAHOO.log('getAttribute method not available for ' + el, 'error', 'Dom');}return val;},_toCamel: function(property) {var c = propertyCache;function tU(x,l) {return l.toUpperCase();}return c[property] || (c[property] = property.indexOf('-') === -1 ?property :property.replace( /-([a-z])/gi, tU ));},_getClassRegex: function(className) {var re;if (className !== undefined) { // allow empty string to passif (className.exec) { // already a RegExpre = className;} else {re = reCache[className];if (!re) {// escape special chars (".", "[", etc.)className = className.replace(Y.Dom._patterns.CLASS_RE_TOKENS, '\\$1');className = className.replace(/\s+/g, SPACE); // convert line breaks and other delimsre = reCache[className] = new RegExp(C_START + className + C_END, G);}}}return re;},_patterns: {ROOT_TAG: /^body|html$/i, // body for quirks mode, html for standards,CLASS_RE_TOKENS: /([\.\(\)\^\$\*\+\?\|\[\]\{\}\\])/g},_testElement: function(node, method) {return node && node[NODE_TYPE] == 1 && ( !method || method(node) );},_calcBorders: function(node, xy2) {var t = parseInt(Y.Dom[GET_COMPUTED_STYLE](node, BORDER_TOP_WIDTH), 10) || 0,l = parseInt(Y.Dom[GET_COMPUTED_STYLE](node, BORDER_LEFT_WIDTH), 10) || 0;if (isGecko) {if (RE_TABLE.test(node[TAG_NAME])) {t = 0;l = 0;}}xy2[0] += l;xy2[1] += t;return xy2;}};var _getComputedStyle = Y.Dom[GET_COMPUTED_STYLE];// fix opera computedStyle default color unit (convert to rgb)if (UA.opera) {Y.Dom[GET_COMPUTED_STYLE] = function(node, att) {var val = _getComputedStyle(node, att);if (RE_COLOR.test(att)) {val = Y.Dom.Color.toRGB(val);}return val;};}// safari converts transparent to rgba(), others use "transparent"if (UA.webkit) {Y.Dom[GET_COMPUTED_STYLE] = function(node, att) {var val = _getComputedStyle(node, att);if (val === 'rgba(0, 0, 0, 0)') {val = 'transparent';}return val;};}if (UA.ie && UA.ie >= 8) {Y.Dom.DOT_ATTRIBUTES.type = true; // IE 8 errors on input.setAttribute('type')}})();/*** A region is a representation of an object on a grid. It is defined* by the top, right, bottom, left extents, so is rectangular by default. If* other shapes are required, this class could be extended to support it.* @namespace YAHOO.util* @class Region* @param {Int} t the top extent* @param {Int} r the right extent* @param {Int} b the bottom extent* @param {Int} l the left extent* @constructor*/YAHOO.util.Region = function(t, r, b, l) {/*** The region's top extent* @property top* @type Int*/this.top = t;/*** The region's top extent* @property y* @type Int*/this.y = t;/*** The region's top extent as index, for symmetry with set/getXY* @property 1* @type Int*/this[1] = t;/*** The region's right extent* @property right* @type int*/this.right = r;/*** The region's bottom extent* @property bottom* @type Int*/this.bottom = b;/*** The region's left extent* @property left* @type Int*/this.left = l;/*** The region's left extent* @property x* @type Int*/this.x = l;/*** The region's left extent as index, for symmetry with set/getXY* @property 0* @type Int*/this[0] = l;/*** The region's total width* @property width* @type Int*/this.width = this.right - this.left;/*** The region's total height* @property height* @type Int*/this.height = this.bottom - this.top;};/*** Returns true if this region contains the region passed in* @method contains* @param {Region} region The region to evaluate* @return {Boolean} True if the region is contained with this region,* else false*/YAHOO.util.Region.prototype.contains = function(region) {return ( region.left >= this.left &®ion.right <= this.right &®ion.top >= this.top &®ion.bottom <= this.bottom );// this.logger.debug("does " + this + " contain " + region + " ... " + ret);};/*** Returns the area of the region* @method getArea* @return {Int} the region's area*/YAHOO.util.Region.prototype.getArea = function() {return ( (this.bottom - this.top) * (this.right - this.left) );};/*** Returns the region where the passed in region overlaps with this one* @method intersect* @param {Region} region The region that intersects* @return {Region} The overlap region, or null if there is no overlap*/YAHOO.util.Region.prototype.intersect = function(region) {var t = Math.max( this.top, region.top ),r = Math.min( this.right, region.right ),b = Math.min( this.bottom, region.bottom ),l = Math.max( this.left, region.left );if (b >= t && r >= l) {return new YAHOO.util.Region(t, r, b, l);} else {return null;}};/*** Returns the region representing the smallest region that can contain both* the passed in region and this region.* @method union* @param {Region} region The region that to create the union with* @return {Region} The union region*/YAHOO.util.Region.prototype.union = function(region) {var t = Math.min( this.top, region.top ),r = Math.max( this.right, region.right ),b = Math.max( this.bottom, region.bottom ),l = Math.min( this.left, region.left );return new YAHOO.util.Region(t, r, b, l);};/*** toString* @method toString* @return string the region properties*/YAHOO.util.Region.prototype.toString = function() {return ( "Region {" +"top: " + this.top +", right: " + this.right +", bottom: " + this.bottom +", left: " + this.left +", height: " + this.height +", width: " + this.width +"}" );};/*** Returns a region that is occupied by the DOM element* @method getRegion* @param {HTMLElement} el The element* @return {Region} The region that the element occupies* @static*/YAHOO.util.Region.getRegion = function(el) {var p = YAHOO.util.Dom.getXY(el),t = p[1],r = p[0] + el.offsetWidth,b = p[1] + el.offsetHeight,l = p[0];return new YAHOO.util.Region(t, r, b, l);};//////////////////////////////////////////////////////////////////////////////*** A point is a region that is special in that it represents a single point on* the grid.* @namespace YAHOO.util* @class Point* @param {Int} x The X position of the point* @param {Int} y The Y position of the point* @constructor* @extends YAHOO.util.Region*/YAHOO.util.Point = function(x, y) {if (YAHOO.lang.isArray(x)) { // accept input from Dom.getXY, Event.getXY, etc.y = x[1]; // dont blow away x yetx = x[0];}YAHOO.util.Point.superclass.constructor.call(this, y, x, y, x);};YAHOO.extend(YAHOO.util.Point, YAHOO.util.Region);(function() {/*** Internal methods used to add style management functionality to DOM.* @module dom* @class IEStyle* @namespace YAHOO.util.Dom*/var Y = YAHOO.util,CLIENT_TOP = 'clientTop',CLIENT_LEFT = 'clientLeft',PARENT_NODE = 'parentNode',RIGHT = 'right',HAS_LAYOUT = 'hasLayout',PX = 'px',OPACITY = 'opacity',AUTO = 'auto',BORDER_LEFT_WIDTH = 'borderLeftWidth',BORDER_TOP_WIDTH = 'borderTopWidth',BORDER_RIGHT_WIDTH = 'borderRightWidth',BORDER_BOTTOM_WIDTH = 'borderBottomWidth',VISIBLE = 'visible',TRANSPARENT = 'transparent',HEIGHT = 'height',WIDTH = 'width',STYLE = 'style',CURRENT_STYLE = 'currentStyle',// IE getComputedStyle// TODO: unit-less lineHeight (e.g. 1.22)re_size = /^width|height$/,re_unit = /^(\d[.\d]*)+(em|ex|px|gd|rem|vw|vh|vm|ch|mm|cm|in|pt|pc|deg|rad|ms|s|hz|khz|%){1}?/i,ComputedStyle = {/*** @method get* @description Method used by DOM to get style information for IE* @param {HTMLElement} el The element to check* @param {String} property The property to check* @returns {String} The computed style*/get: function(el, property) {var value = '',current = el[CURRENT_STYLE][property];if (property === OPACITY) {value = Y.Dom.getStyle(el, OPACITY);} else if (!current || (current.indexOf && current.indexOf(PX) > -1)) { // no need to convertvalue = current;} else if (Y.Dom.IE_COMPUTED[property]) { // use compute functionvalue = Y.Dom.IE_COMPUTED[property](el, property);} else if (re_unit.test(current)) { // convert to pixelvalue = Y.Dom.IE.ComputedStyle.getPixel(el, property);} else {value = current;}return value;},/*** @method getOffset* @description Determine the offset of an element* @param {HTMLElement} el The element to check* @param {String} prop The property to check.* @return {String} The offset*/getOffset: function(el, prop) {var current = el[CURRENT_STYLE][prop], // value of "width", "top", etc.capped = prop.charAt(0).toUpperCase() + prop.substr(1), // "Width", "Top", etc.offset = 'offset' + capped, // "offsetWidth", "offsetTop", etc.pixel = 'pixel' + capped, // "pixelWidth", "pixelTop", etc.value = '',actual;if (current == AUTO) {actual = el[offset]; // offsetHeight/Top etc.if (actual === undefined) { // likely "right" or "bottom"value = 0;}value = actual;if (re_size.test(prop)) { // account for box model diffel[STYLE][prop] = actual;if (el[offset] > actual) {// the difference is padding + border (works in Standards & Quirks modes)value = actual - (el[offset] - actual);}el[STYLE][prop] = AUTO; // revert to auto}} else { // convert units to pxif (!el[STYLE][pixel] && !el[STYLE][prop]) { // need to map style.width to currentStyle (no currentStyle.pixelWidth)el[STYLE][prop] = current; // no style.pixelWidth if no style.width}value = el[STYLE][pixel];}return value + PX;},/*** @method getBorderWidth* @description Try to determine the width of an elements border* @param {HTMLElement} el The element to check* @param {String} property The property to check* @return {String} The elements border width*/getBorderWidth: function(el, property) {// clientHeight/Width = paddingBox (e.g. offsetWidth - borderWidth)// clientTop/Left = borderWidthvar value = null;if (!el[CURRENT_STYLE][HAS_LAYOUT]) { // TODO: unset layout?el[STYLE].zoom = 1; // need layout to measure client}switch(property) {case BORDER_TOP_WIDTH:value = el[CLIENT_TOP];break;case BORDER_BOTTOM_WIDTH:value = el.offsetHeight - el.clientHeight - el[CLIENT_TOP];break;case BORDER_LEFT_WIDTH:value = el[CLIENT_LEFT];break;case BORDER_RIGHT_WIDTH:value = el.offsetWidth - el.clientWidth - el[CLIENT_LEFT];break;}return value + PX;},/*** @method getPixel* @description Get the pixel value from a style property* @param {HTMLElement} node The element to check* @param {String} att The attribute to check* @return {String} The pixel value*/getPixel: function(node, att) {// use pixelRight to convert to pxvar val = null,styleRight = node[CURRENT_STYLE][RIGHT],current = node[CURRENT_STYLE][att];node[STYLE][RIGHT] = current;val = node[STYLE].pixelRight;node[STYLE][RIGHT] = styleRight; // revertreturn val + PX;},/*** @method getMargin* @description Get the margin value from a style property* @param {HTMLElement} node The element to check* @param {String} att The attribute to check* @return {String} The margin value*/getMargin: function(node, att) {var val;if (node[CURRENT_STYLE][att] == AUTO) {val = 0 + PX;} else {val = Y.Dom.IE.ComputedStyle.getPixel(node, att);}return val;},/*** @method getVisibility* @description Get the visibility of an element* @param {HTMLElement} node The element to check* @param {String} att The attribute to check* @return {String} The value*/getVisibility: function(node, att) {var current;while ( (current = node[CURRENT_STYLE]) && current[att] == 'inherit') { // NOTE: assignment in testnode = node[PARENT_NODE];}return (current) ? current[att] : VISIBLE;},/*** @method getColor* @description Get the color of an element* @param {HTMLElement} node The element to check* @param {String} att The attribute to check* @return {String} The value*/getColor: function(node, att) {return Y.Dom.Color.toRGB(node[CURRENT_STYLE][att]) || TRANSPARENT;},/*** @method getBorderColor* @description Get the bordercolor of an element* @param {HTMLElement} node The element to check* @param {String} att The attribute to check* @return {String} The value*/getBorderColor: function(node, att) {var current = node[CURRENT_STYLE],val = current[att] || current.color;return Y.Dom.Color.toRGB(Y.Dom.Color.toHex(val));}},//fontSize: getPixelFont,IEComputed = {};IEComputed.top = IEComputed.right = IEComputed.bottom = IEComputed.left =IEComputed[WIDTH] = IEComputed[HEIGHT] = ComputedStyle.getOffset;IEComputed.color = ComputedStyle.getColor;IEComputed[BORDER_TOP_WIDTH] = IEComputed[BORDER_RIGHT_WIDTH] =IEComputed[BORDER_BOTTOM_WIDTH] = IEComputed[BORDER_LEFT_WIDTH] =ComputedStyle.getBorderWidth;IEComputed.marginTop = IEComputed.marginRight = IEComputed.marginBottom =IEComputed.marginLeft = ComputedStyle.getMargin;IEComputed.visibility = ComputedStyle.getVisibility;IEComputed.borderColor = IEComputed.borderTopColor =IEComputed.borderRightColor = IEComputed.borderBottomColor =IEComputed.borderLeftColor = ComputedStyle.getBorderColor;Y.Dom.IE_COMPUTED = IEComputed;Y.Dom.IE_ComputedStyle = ComputedStyle;})();(function() {/*** Add style management functionality to DOM.* @module dom* @class Color* @namespace YAHOO.util.Dom*/var TO_STRING = 'toString',PARSE_INT = parseInt,RE = RegExp,Y = YAHOO.util;Y.Dom.Color = {/*** @property KEYWORDS* @type Object* @description Color keywords used when converting to Hex*/KEYWORDS: {black: '000',silver: 'c0c0c0',gray: '808080',white: 'fff',maroon: '800000',red: 'f00',purple: '800080',fuchsia: 'f0f',green: '008000',lime: '0f0',olive: '808000',yellow: 'ff0',navy: '000080',blue: '00f',teal: '008080',aqua: '0ff'},/*** @property re_RGB* @private* @type Regex* @description Regex to parse rgb(0,0,0) formatted strings*/re_RGB: /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,/*** @property re_hex* @private* @type Regex* @description Regex to parse #123456 formatted strings*/re_hex: /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,/*** @property re_hex3* @private* @type Regex* @description Regex to parse #123 formatted strings*/re_hex3: /([0-9A-F])/gi,/*** @method toRGB* @description Converts a hex or color string to an rgb string: rgb(0,0,0)* @param {String} val The string to convert to RGB notation.* @returns {String} The converted string*/toRGB: function(val) {if (!Y.Dom.Color.re_RGB.test(val)) {val = Y.Dom.Color.toHex(val);}if(Y.Dom.Color.re_hex.exec(val)) {val = 'rgb(' + [PARSE_INT(RE.$1, 16),PARSE_INT(RE.$2, 16),PARSE_INT(RE.$3, 16)].join(', ') + ')';}return val;},/*** @method toHex* @description Converts an rgb or color string to a hex string: #123456* @param {String} val The string to convert to hex notation.* @returns {String} The converted string*/toHex: function(val) {val = Y.Dom.Color.KEYWORDS[val] || val;if (Y.Dom.Color.re_RGB.exec(val)) {val = [Number(RE.$1).toString(16),Number(RE.$2).toString(16),Number(RE.$3).toString(16)];for (var i = 0; i < val.length; i++) {if (val[i].length < 2) {val[i] = '0' + val[i];}}val = val.join('');}if (val.length < 6) {val = val.replace(Y.Dom.Color.re_hex3, '$1$1');}if (val !== 'transparent' && val.indexOf('#') < 0) {val = '#' + val;}return val.toUpperCase();}};}());YAHOO.register("dom", YAHOO.util.Dom, {version: "2.9.0", build: "2800"});if (YAHOO.env._id_counter < 1e+6) {YAHOO.env._id_counter = Y.Env._yidx * 1e+6;}}, '2.9.0' ,{"requires": ["yui2-yahoo"]});