2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
8 * Provides Attribute configurations.
9 * @namespace YAHOO.util
12 * @param hash {Object} The intial Attribute.
13 * @param {YAHOO.util.AttributeProvider} The owner of the Attribute instance.
16 YAHOO.util.Attribute = function(hash, owner) {
19 this.configure(hash, true);
23 YAHOO.util.Attribute.prototype = {
25 * The name of the attribute.
32 * The value of the attribute.
39 * The owner of the attribute.
41 * @type YAHOO.util.AttributeProvider
46 * Whether or not the attribute is read only.
53 * Whether or not the attribute can only be written once.
60 * The attribute's initial configuration.
62 * @property _initialConfig
68 * Whether or not the attribute's value has been set.
76 * A function to call when setting the attribute's value.
77 * The method receives the new value as the first arg and the attribute name as the 2nd
84 * The function to use when setting the attribute's value.
85 * The setter receives the new value as the first arg and the attribute name as the 2nd
86 * The return value of the setter replaces the value passed to set().
93 * The function to use when getting the attribute's value.
94 * The getter receives the new value as the first arg and the attribute name as the 2nd
95 * The return value of the getter will be used as the return from get().
102 * The validator to use when setting the attribute's value.
103 * @property validator
110 * Retrieves the current value of the attribute.
112 * @return {any} The current value of the attribute.
114 getValue: function() {
115 var val = this.value;
118 val = this.getter.call(this.owner, this.name, val);
125 * Sets the value of the attribute and fires beforeChange and change events.
127 * @param {Any} value The value to apply to the attribute.
128 * @param {Boolean} silent If true the change events will not be fired.
129 * @return {Boolean} Whether or not the value was set.
131 setValue: function(value, silent) {
138 prevValue: this.getValue(),
142 if (this.readOnly || ( this.writeOnce && this._written) ) {
143 YAHOO.log( 'setValue ' + name + ', ' + value +
144 ' failed: read only', 'error', 'Attribute');
145 return false; // write not allowed
148 if (this.validator && !this.validator.call(owner, value) ) {
149 YAHOO.log( 'setValue ' + name + ', ' + value +
150 ' validation failed', 'error', 'Attribute');
151 return false; // invalid value
155 beforeRetVal = owner.fireBeforeChangeEvent(event);
156 if (beforeRetVal === false) {
157 YAHOO.log('setValue ' + name +
158 ' cancelled by beforeChange event', 'info', 'Attribute');
164 value = this.setter.call(owner, value, this.name);
165 if (value === undefined) {
166 YAHOO.log('setter for ' + this.name + ' returned undefined', 'warn', 'Attribute');
171 this.method.call(owner, value, this.name);
174 this.value = value; // TODO: set before calling setter/method?
175 this._written = true;
180 this.owner.fireChangeEvent(event);
187 * Allows for configuring the Attribute's properties.
189 * @param {Object} map A key-value map of Attribute properties.
190 * @param {Boolean} init Whether or not this should become the initial config.
192 configure: function(map, init) {
196 this._written = false; // reset writeOnce
199 this._initialConfig = this._initialConfig || {};
201 for (var key in map) {
202 if ( map.hasOwnProperty(key) ) {
203 this[key] = map[key];
205 this._initialConfig[key] = map[key];
212 * Resets the value to the initial config value.
214 * @return {Boolean} Whether or not the value was set.
216 resetValue: function() {
217 return this.setValue(this._initialConfig.value);
221 * Resets the attribute config to the initial config state.
222 * @method resetConfig
224 resetConfig: function() {
225 this.configure(this._initialConfig, true);
229 * Resets the value to the current value.
230 * Useful when values may have gotten out of sync with actual properties.
232 * @return {Boolean} Whether or not the value was set.
234 refresh: function(silent) {
235 this.setValue(this.value, silent);
240 var Lang = YAHOO.util.Lang;
243 Copyright (c) 2006, Yahoo! Inc. All rights reserved.
244 Code licensed under the BSD License:
245 http://developer.yahoo.net/yui/license.txt
249 * Provides and manages YAHOO.util.Attribute instances
250 * @namespace YAHOO.util
251 * @class AttributeProvider
252 * @uses YAHOO.util.EventProvider
254 YAHOO.util.AttributeProvider = function() {};
256 YAHOO.util.AttributeProvider.prototype = {
259 * A key-value map of Attribute configurations
261 * @protected (may be used by subclasses and augmentors)
267 * Returns the current value of the attribute.
269 * @param {String} key The attribute whose value will be returned.
270 * @return {Any} The current value of the attribute.
273 this._configs = this._configs || {};
274 var config = this._configs[key];
276 if (!config || !this._configs.hasOwnProperty(key)) {
277 YAHOO.log(key + ' not found', 'error', 'AttributeProvider');
281 return config.getValue();
285 * Sets the value of a config.
287 * @param {String} key The name of the attribute
288 * @param {Any} value The value to apply to the attribute
289 * @param {Boolean} silent Whether or not to suppress change events
290 * @return {Boolean} Whether or not the value was set.
292 set: function(key, value, silent){
293 this._configs = this._configs || {};
294 var config = this._configs[key];
297 YAHOO.log('set failed: ' + key + ' not found',
298 'error', 'AttributeProvider');
302 return config.setValue(value, silent);
306 * Returns an array of attribute names.
307 * @method getAttributeKeys
308 * @return {Array} An array of attribute names.
310 getAttributeKeys: function(){
311 this._configs = this._configs;
314 for (key in this._configs) {
315 if ( Lang.hasOwnProperty(this._configs, key) &&
316 !Lang.isUndefined(this._configs[key]) ) {
317 keys[keys.length] = key;
325 * Sets multiple attribute values.
326 * @method setAttributes
327 * @param {Object} map A key-value map of attributes
328 * @param {Boolean} silent Whether or not to suppress change events
330 setAttributes: function(map, silent){
331 for (var key in map) {
332 if ( Lang.hasOwnProperty(map, key) ) {
333 this.set(key, map[key], silent);
339 * Resets the specified attribute's value to its initial value.
341 * @param {String} key The name of the attribute
342 * @param {Boolean} silent Whether or not to suppress change events
343 * @return {Boolean} Whether or not the value was set
345 resetValue: function(key, silent){
346 this._configs = this._configs || {};
347 if (this._configs[key]) {
348 this.set(key, this._configs[key]._initialConfig.value, silent);
355 * Sets the attribute's value to its current value.
357 * @param {String | Array} key The attribute(s) to refresh
358 * @param {Boolean} silent Whether or not to suppress change events
360 refresh: function(key, silent) {
361 this._configs = this._configs || {};
362 var configs = this._configs;
364 key = ( ( Lang.isString(key) ) ? [key] : key ) ||
365 this.getAttributeKeys();
367 for (var i = 0, len = key.length; i < len; ++i) {
368 if (configs.hasOwnProperty(key[i])) {
369 this._configs[key[i]].refresh(silent);
375 * Adds an Attribute to the AttributeProvider instance.
377 * @param {String} key The attribute's name
378 * @param {Object} map A key-value map containing the
379 * attribute's properties.
380 * @deprecated Use setAttributeConfig
382 register: function(key, map) {
383 this.setAttributeConfig(key, map);
388 * Returns the attribute's properties.
389 * @method getAttributeConfig
390 * @param {String} key The attribute's name
392 * @return {object} A key-value map containing all of the
393 * attribute's properties.
395 getAttributeConfig: function(key) {
396 this._configs = this._configs || {};
397 var config = this._configs[key] || {};
398 var map = {}; // returning a copy to prevent overrides
400 for (key in config) {
401 if ( Lang.hasOwnProperty(config, key) ) {
402 map[key] = config[key];
410 * Sets or updates an Attribute instance's properties.
411 * @method setAttributeConfig
412 * @param {String} key The attribute's name.
413 * @param {Object} map A key-value map of attribute properties
414 * @param {Boolean} init Whether or not this should become the intial config.
416 setAttributeConfig: function(key, map, init) {
417 this._configs = this._configs || {};
419 if (!this._configs[key]) {
421 this._configs[key] = this.createAttribute(map);
423 this._configs[key].configure(map, init);
428 * Sets or updates an Attribute instance's properties.
429 * @method configureAttribute
430 * @param {String} key The attribute's name.
431 * @param {Object} map A key-value map of attribute properties
432 * @param {Boolean} init Whether or not this should become the intial config.
433 * @deprecated Use setAttributeConfig
435 configureAttribute: function(key, map, init) {
436 this.setAttributeConfig(key, map, init);
440 * Resets an attribute to its intial configuration.
441 * @method resetAttributeConfig
442 * @param {String} key The attribute's name.
445 resetAttributeConfig: function(key){
446 this._configs = this._configs || {};
447 this._configs[key].resetConfig();
450 // wrapper for EventProvider.subscribe
451 // to create events on the fly
452 subscribe: function(type, callback) {
453 this._events = this._events || {};
455 if ( !(type in this._events) ) {
456 this._events[type] = this.createEvent(type);
459 YAHOO.util.EventProvider.prototype.subscribe.apply(this, arguments);
463 this.subscribe.apply(this, arguments);
466 addListener: function() {
467 this.subscribe.apply(this, arguments);
471 * Fires the attribute's beforeChange event.
472 * @method fireBeforeChangeEvent
473 * @param {String} key The attribute's name.
474 * @param {Obj} e The event object to pass to handlers.
476 fireBeforeChangeEvent: function(e) {
478 type += e.type.charAt(0).toUpperCase() + e.type.substr(1) + 'Change';
480 return this.fireEvent(e.type, e);
484 * Fires the attribute's change event.
485 * @method fireChangeEvent
486 * @param {String} key The attribute's name.
487 * @param {Obj} e The event object to pass to the handlers.
489 fireChangeEvent: function(e) {
491 return this.fireEvent(e.type, e);
494 createAttribute: function(map) {
495 return new YAHOO.util.Attribute(map, this);
499 YAHOO.augment(YAHOO.util.AttributeProvider, YAHOO.util.EventProvider);
503 // internal shorthand
504 var Dom = YAHOO.util.Dom,
505 AttributeProvider = YAHOO.util.AttributeProvider,
512 * Element provides an wrapper object to simplify adding
513 * event listeners, using dom methods, and managing attributes.
515 * @namespace YAHOO.util
516 * @requires yahoo, dom, event
520 * Element provides an wrapper object to simplify adding
521 * event listeners, using dom methods, and managing attributes.
523 * @uses YAHOO.util.AttributeProvider
525 * @param el {HTMLElement | String} The html element that
526 * represents the Element.
527 * @param {Object} map A key-value map of initial config names and values
529 var Element = function(el, map) {
530 this.init.apply(this, arguments);
533 Element.DOM_EVENTS = {
552 Element.prototype = {
554 * Dom events supported by the Element instance.
555 * @property DOM_EVENTS
560 DEFAULT_HTML_SETTER: function(value, key) {
561 var el = this.get('element');
571 DEFAULT_HTML_GETTER: function(key) {
572 var el = this.get('element'),
583 * Wrapper for HTMLElement method.
584 * @method appendChild
585 * @param {YAHOO.util.Element || HTMLElement} child The element to append.
586 * @return {HTMLElement} The appended DOM element.
588 appendChild: function(child) {
589 child = child.get ? child.get('element') : child;
590 return this.get('element').appendChild(child);
594 * Wrapper for HTMLElement method.
595 * @method getElementsByTagName
596 * @param {String} tag The tagName to collect
597 * @return {HTMLCollection} A collection of DOM elements.
599 getElementsByTagName: function(tag) {
600 return this.get('element').getElementsByTagName(tag);
604 * Wrapper for HTMLElement method.
605 * @method hasChildNodes
606 * @return {Boolean} Whether or not the element has childNodes
608 hasChildNodes: function() {
609 return this.get('element').hasChildNodes();
613 * Wrapper for HTMLElement method.
614 * @method insertBefore
615 * @param {HTMLElement} element The HTMLElement to insert
616 * @param {HTMLElement} before The HTMLElement to insert
617 * the element before.
618 * @return {HTMLElement} The inserted DOM element.
620 insertBefore: function(element, before) {
621 element = element.get ? element.get('element') : element;
622 before = (before && before.get) ? before.get('element') : before;
624 return this.get('element').insertBefore(element, before);
628 * Wrapper for HTMLElement method.
629 * @method removeChild
630 * @param {HTMLElement} child The HTMLElement to remove
631 * @return {HTMLElement} The removed DOM element.
633 removeChild: function(child) {
634 child = child.get ? child.get('element') : child;
635 return this.get('element').removeChild(child);
639 * Wrapper for HTMLElement method.
640 * @method replaceChild
641 * @param {HTMLElement} newNode The HTMLElement to insert
642 * @param {HTMLElement} oldNode The HTMLElement to replace
643 * @return {HTMLElement} The replaced DOM element.
645 replaceChild: function(newNode, oldNode) {
646 newNode = newNode.get ? newNode.get('element') : newNode;
647 oldNode = oldNode.get ? oldNode.get('element') : oldNode;
648 return this.get('element').replaceChild(newNode, oldNode);
653 * Registers Element specific attributes.
654 * @method initAttributes
655 * @param {Object} map A key-value map of initial attribute configs
657 initAttributes: function(map) {
661 * Adds a listener for the given event. These may be DOM or
662 * customEvent listeners. Any event that is fired via fireEvent
663 * can be listened for. All handlers receive an event object.
664 * @method addListener
665 * @param {String} type The name of the event to listen for
666 * @param {Function} fn The handler to call when the event fires
667 * @param {Any} obj A variable to pass to the handler
668 * @param {Object} scope The object to use for the scope of the handler
670 addListener: function(type, fn, obj, scope) {
672 scope = scope || this;
674 var Event = YAHOO.util.Event,
675 el = this.get('element') || this.get('id'),
679 if (specialTypes[type] && !Event._createMouseDelegate) {
680 YAHOO.log("Using a " + type + " event requires the event-mouseenter module", "error", "Event");
685 if (!this._events[type]) { // create on the fly
687 if (el && this.DOM_EVENTS[type]) {
688 Event.on(el, type, function(e, matchedEl) {
690 // Supplement IE with target, currentTarget relatedTarget
692 if (e.srcElement && !e.target) {
693 e.target = e.srcElement;
696 if ((e.toElement && !e.relatedTarget) || (e.fromElement && !e.relatedTarget)) {
697 e.relatedTarget = Event.getRelatedTarget(e);
700 if (!e.currentTarget) {
701 e.currentTarget = el;
704 // Note: matchedEl el is passed back for delegated listeners
705 self.fireEvent(type, e, matchedEl);
709 this.createEvent(type, {scope: this});
712 return YAHOO.util.EventProvider.prototype.subscribe.apply(this, arguments); // notify via customEvent
717 * Alias for addListener
719 * @param {String} type The name of the event to listen for
720 * @param {Function} fn The function call when the event fires
721 * @param {Any} obj A variable to pass to the handler
722 * @param {Object} scope The object to use for the scope of the handler
725 return this.addListener.apply(this, arguments);
729 * Alias for addListener
731 * @param {String} type The name of the event to listen for
732 * @param {Function} fn The function call when the event fires
733 * @param {Any} obj A variable to pass to the handler
734 * @param {Object} scope The object to use for the scope of the handler
736 subscribe: function() {
737 return this.addListener.apply(this, arguments);
741 * Remove an event listener
742 * @method removeListener
743 * @param {String} type The name of the event to listen for
744 * @param {Function} fn The function call when the event fires
746 removeListener: function(type, fn) {
747 return this.unsubscribe.apply(this, arguments);
751 * Wrapper for Dom method.
753 * @param {String} className The className to add
755 addClass: function(className) {
756 Dom.addClass(this.get('element'), className);
760 * Wrapper for Dom method.
761 * @method getElementsByClassName
762 * @param {String} className The className to collect
763 * @param {String} tag (optional) The tag to use in
764 * conjunction with class name
765 * @return {Array} Array of HTMLElements
767 getElementsByClassName: function(className, tag) {
768 return Dom.getElementsByClassName(className, tag,
769 this.get('element') );
773 * Wrapper for Dom method.
775 * @param {String} className The className to add
776 * @return {Boolean} Whether or not the element has the class name
778 hasClass: function(className) {
779 return Dom.hasClass(this.get('element'), className);
783 * Wrapper for Dom method.
784 * @method removeClass
785 * @param {String} className The className to remove
787 removeClass: function(className) {
788 return Dom.removeClass(this.get('element'), className);
792 * Wrapper for Dom method.
793 * @method replaceClass
794 * @param {String} oldClassName The className to replace
795 * @param {String} newClassName The className to add
797 replaceClass: function(oldClassName, newClassName) {
798 return Dom.replaceClass(this.get('element'),
799 oldClassName, newClassName);
803 * Wrapper for Dom method.
805 * @param {String} property The style property to set
806 * @param {String} value The value to apply to the style property
808 setStyle: function(property, value) {
809 return Dom.setStyle(this.get('element'), property, value); // TODO: always queuing?
813 * Wrapper for Dom method.
815 * @param {String} property The style property to retrieve
816 * @return {String} The current value of the property
818 getStyle: function(property) {
819 return Dom.getStyle(this.get('element'), property);
823 * Apply any queued set calls.
826 fireQueue: function() {
827 var queue = this._queue;
828 for (var i = 0, len = queue.length; i < len; ++i) {
829 this[queue[i][0]].apply(this, queue[i][1]);
834 * Appends the HTMLElement into either the supplied parentNode.
836 * @param {HTMLElement | Element} parentNode The node to append to
837 * @param {HTMLElement | Element} before An optional node to insert before
838 * @return {HTMLElement} The appended DOM element.
840 appendTo: function(parent, before) {
841 parent = (parent.get) ? parent.get('element') : Dom.get(parent);
843 this.fireEvent('beforeAppendTo', {
844 type: 'beforeAppendTo',
849 before = (before && before.get) ?
850 before.get('element') : Dom.get(before);
851 var element = this.get('element');
854 YAHOO.log('appendTo failed: element not available',
860 YAHOO.log('appendTo failed: parent not available',
865 if (element.parent != parent) {
867 parent.insertBefore(element, before);
869 parent.appendChild(element);
873 YAHOO.log(element + 'appended to ' + parent);
875 this.fireEvent('appendTo', {
884 var configs = this._configs || {},
885 el = configs.element; // avoid loop due to 'element'
887 if (el && !configs[key] && !YAHOO.lang.isUndefined(el.value[key]) ) {
888 this._setHTMLAttrConfig(key);
891 return AttributeProvider.prototype.get.call(this, key);
894 setAttributes: function(map, silent) {
895 // set based on configOrder
897 configOrder = this._configOrder;
899 // set based on configOrder
900 for (var i = 0, len = configOrder.length; i < len; ++i) {
901 if (map[configOrder[i]] !== undefined) {
902 done[configOrder[i]] = true;
903 this.set(configOrder[i], map[configOrder[i]], silent);
907 // unconfigured (e.g. Dom attributes)
908 for (var att in map) {
909 if (map.hasOwnProperty(att) && !done[att]) {
910 this.set(att, map[att], silent);
915 set: function(key, value, silent) {
916 var el = this.get('element');
918 this._queue[this._queue.length] = ['set', arguments];
919 if (this._configs[key]) {
920 this._configs[key].value = value; // so "get" works while queueing
926 // set it on the element if not configured and is an HTML attribute
927 if ( !this._configs[key] && !YAHOO.lang.isUndefined(el[key]) ) {
928 this._setHTMLAttrConfig(key);
931 return AttributeProvider.prototype.set.apply(this, arguments);
934 setAttributeConfig: function(key, map, init) {
935 this._configOrder.push(key);
936 AttributeProvider.prototype.setAttributeConfig.apply(this, arguments);
939 createEvent: function(type, config) {
940 this._events[type] = true;
941 return AttributeProvider.prototype.createEvent.apply(this, arguments);
944 init: function(el, attr) {
945 this._initElement(el, attr);
948 destroy: function() {
949 var el = this.get('element');
950 YAHOO.util.Event.purgeElement(el, true); // purge DOM listeners recursively
951 this.unsubscribeAll(); // unsubscribe all custom events
953 if (el && el.parentNode) {
954 el.parentNode.removeChild(el); // pull from the DOM
957 // revert initial configs
961 this._configOrder = [];
964 _initElement: function(el, attr) {
965 this._queue = this._queue || [];
966 this._events = this._events || {};
967 this._configs = this._configs || {};
968 this._configOrder = [];
970 attr.element = attr.element || el || null;
972 var isReady = false; // to determine when to init HTMLElement and content
974 var DOM_EVENTS = Element.DOM_EVENTS;
975 this.DOM_EVENTS = this.DOM_EVENTS || {};
977 for (var event in DOM_EVENTS) {
978 if (DOM_EVENTS.hasOwnProperty(event)) {
979 this.DOM_EVENTS[event] = DOM_EVENTS[event];
983 if (typeof attr.element === 'string') { // register ID for get() access
984 this._setHTMLAttrConfig('id', { value: attr.element });
987 if (Dom.get(attr.element)) {
989 this._initHTMLElement(attr);
990 this._initContent(attr);
993 YAHOO.util.Event.onAvailable(attr.element, function() {
994 if (!isReady) { // otherwise already done
995 this._initHTMLElement(attr);
998 this.fireEvent('available', { type: 'available', target: Dom.get(attr.element) });
1001 YAHOO.util.Event.onContentReady(attr.element, function() {
1002 if (!isReady) { // otherwise already done
1003 this._initContent(attr);
1005 this.fireEvent('contentReady', { type: 'contentReady', target: Dom.get(attr.element) });
1009 _initHTMLElement: function(attr) {
1011 * The HTMLElement the Element instance refers to.
1012 * @attribute element
1015 this.setAttributeConfig('element', {
1016 value: Dom.get(attr.element),
1021 _initContent: function(attr) {
1022 this.initAttributes(attr);
1023 this.setAttributes(attr, true);
1029 * Sets the value of the property and fires beforeChange and change events.
1031 * @method _setHTMLAttrConfig
1032 * @param {YAHOO.util.Element} element The Element instance to
1033 * register the config to.
1034 * @param {String} key The name of the config to register
1035 * @param {Object} map A key-value map of the config's params
1037 _setHTMLAttrConfig: function(key, map) {
1038 var el = this.get('element');
1042 map.setter = map.setter || this.DEFAULT_HTML_SETTER;
1043 map.getter = map.getter || this.DEFAULT_HTML_GETTER;
1045 map.value = map.value || el[key];
1046 this._configs[key] = new YAHOO.util.Attribute(map, this);
1051 * Fires when the Element's HTMLElement can be retrieved by Id.
1052 * <p>See: <a href="#addListener">Element.addListener</a></p>
1053 * <p><strong>Event fields:</strong><br>
1054 * <code><String> type</code> available<br>
1055 * <code><HTMLElement>
1056 * target</code> the HTMLElement bound to this Element instance<br>
1057 * <p><strong>Usage:</strong><br>
1058 * <code>var handler = function(e) {var target = e.target};<br>
1059 * myTabs.addListener('available', handler);</code></p>
1064 * Fires when the Element's HTMLElement subtree is rendered.
1065 * <p>See: <a href="#addListener">Element.addListener</a></p>
1066 * <p><strong>Event fields:</strong><br>
1067 * <code><String> type</code> contentReady<br>
1068 * <code><HTMLElement>
1069 * target</code> the HTMLElement bound to this Element instance<br>
1070 * <p><strong>Usage:</strong><br>
1071 * <code>var handler = function(e) {var target = e.target};<br>
1072 * myTabs.addListener('contentReady', handler);</code></p>
1073 * @event contentReady
1077 * Fires before the Element is appended to another Element.
1078 * <p>See: <a href="#addListener">Element.addListener</a></p>
1079 * <p><strong>Event fields:</strong><br>
1080 * <code><String> type</code> beforeAppendTo<br>
1081 * <code><HTMLElement/Element>
1082 * target</code> the HTMLElement/Element being appended to
1083 * <p><strong>Usage:</strong><br>
1084 * <code>var handler = function(e) {var target = e.target};<br>
1085 * myTabs.addListener('beforeAppendTo', handler);</code></p>
1086 * @event beforeAppendTo
1090 * Fires after the Element is appended to another Element.
1091 * <p>See: <a href="#addListener">Element.addListener</a></p>
1092 * <p><strong>Event fields:</strong><br>
1093 * <code><String> type</code> appendTo<br>
1094 * <code><HTMLElement/Element>
1095 * target</code> the HTMLElement/Element being appended to
1096 * <p><strong>Usage:</strong><br>
1097 * <code>var handler = function(e) {var target = e.target};<br>
1098 * myTabs.addListener('appendTo', handler);</code></p>
1102 YAHOO.augment(Element, AttributeProvider);
1103 YAHOO.util.Element = Element;
1106 YAHOO.register("element", YAHOO.util.Element, {version: "2.8.0r4", build: "2449"});