src/cm/media/js/lib/yui/yui3-3.15.0/build/dom-base/dom-base-debug.js
changeset 602 e16a97fb364a
equal deleted inserted replaced
601:d334a616c023 602:e16a97fb364a
       
     1 YUI.add('dom-base', function (Y, NAME) {
       
     2 
       
     3 /**
       
     4 * @for DOM
       
     5 * @module dom
       
     6 */
       
     7 var documentElement = Y.config.doc.documentElement,
       
     8     Y_DOM = Y.DOM,
       
     9     TAG_NAME = 'tagName',
       
    10     OWNER_DOCUMENT = 'ownerDocument',
       
    11     EMPTY_STRING = '',
       
    12     addFeature = Y.Features.add,
       
    13     testFeature = Y.Features.test;
       
    14 
       
    15 Y.mix(Y_DOM, {
       
    16     /**
       
    17      * Returns the text content of the HTMLElement.
       
    18      * @method getText
       
    19      * @param {HTMLElement} element The html element.
       
    20      * @return {String} The text content of the element (includes text of any descending elements).
       
    21      */
       
    22     getText: (documentElement.textContent !== undefined) ?
       
    23         function(element) {
       
    24             var ret = '';
       
    25             if (element) {
       
    26                 ret = element.textContent;
       
    27             }
       
    28             return ret || '';
       
    29         } : function(element) {
       
    30             var ret = '';
       
    31             if (element) {
       
    32                 ret = element.innerText || element.nodeValue; // might be a textNode
       
    33             }
       
    34             return ret || '';
       
    35         },
       
    36 
       
    37     /**
       
    38      * Sets the text content of the HTMLElement.
       
    39      * @method setText
       
    40      * @param {HTMLElement} element The html element.
       
    41      * @param {String} content The content to add.
       
    42      */
       
    43     setText: (documentElement.textContent !== undefined) ?
       
    44         function(element, content) {
       
    45             if (element) {
       
    46                 element.textContent = content;
       
    47             }
       
    48         } : function(element, content) {
       
    49             if ('innerText' in element) {
       
    50                 element.innerText = content;
       
    51             } else if ('nodeValue' in element) {
       
    52                 element.nodeValue = content;
       
    53             }
       
    54     },
       
    55 
       
    56     CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8
       
    57         'for': 'htmlFor',
       
    58         'class': 'className'
       
    59     } : { // w3c
       
    60         'htmlFor': 'for',
       
    61         'className': 'class'
       
    62     },
       
    63 
       
    64     /**
       
    65      * Provides a normalized attribute interface.
       
    66      * @method setAttribute
       
    67      * @param {HTMLElement} el The target element for the attribute.
       
    68      * @param {String} attr The attribute to set.
       
    69      * @param {String} val The value of the attribute.
       
    70      */
       
    71     setAttribute: function(el, attr, val, ieAttr) {
       
    72         if (el && attr && el.setAttribute) {
       
    73             attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
       
    74             el.setAttribute(attr, val, ieAttr);
       
    75         }
       
    76         else { Y.log('bad input to setAttribute', 'warn', 'dom'); }
       
    77     },
       
    78 
       
    79 
       
    80     /**
       
    81      * Provides a normalized attribute interface.
       
    82      * @method getAttribute
       
    83      * @param {HTMLElement} el The target element for the attribute.
       
    84      * @param {String} attr The attribute to get.
       
    85      * @return {String} The current value of the attribute.
       
    86      */
       
    87     getAttribute: function(el, attr, ieAttr) {
       
    88         ieAttr = (ieAttr !== undefined) ? ieAttr : 2;
       
    89         var ret = '';
       
    90         if (el && attr && el.getAttribute) {
       
    91             attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
       
    92             // BUTTON value issue for IE < 8
       
    93             ret = (el.tagName === "BUTTON" && attr === 'value') ? Y_DOM.getValue(el) : el.getAttribute(attr, ieAttr);
       
    94 
       
    95             if (ret === null) {
       
    96                 ret = ''; // per DOM spec
       
    97             }
       
    98         }
       
    99         else { Y.log('bad input to getAttribute', 'warn', 'dom'); }
       
   100         return ret;
       
   101     },
       
   102 
       
   103     VALUE_SETTERS: {},
       
   104 
       
   105     VALUE_GETTERS: {},
       
   106 
       
   107     getValue: function(node) {
       
   108         var ret = '', // TODO: return null?
       
   109             getter;
       
   110 
       
   111         if (node && node[TAG_NAME]) {
       
   112             getter = Y_DOM.VALUE_GETTERS[node[TAG_NAME].toLowerCase()];
       
   113 
       
   114             if (getter) {
       
   115                 ret = getter(node);
       
   116             } else {
       
   117                 ret = node.value;
       
   118             }
       
   119         }
       
   120 
       
   121         // workaround for IE8 JSON stringify bug
       
   122         // which converts empty string values to null
       
   123         if (ret === EMPTY_STRING) {
       
   124             ret = EMPTY_STRING; // for real
       
   125         }
       
   126 
       
   127         return (typeof ret === 'string') ? ret : '';
       
   128     },
       
   129 
       
   130     setValue: function(node, val) {
       
   131         var setter;
       
   132 
       
   133         if (node && node[TAG_NAME]) {
       
   134             setter = Y_DOM.VALUE_SETTERS[node[TAG_NAME].toLowerCase()];
       
   135             val = (val === null) ? '' : val;
       
   136             if (setter) {
       
   137                 setter(node, val);
       
   138             } else {
       
   139                 node.value = val;
       
   140             }
       
   141         }
       
   142     },
       
   143 
       
   144     creators: {}
       
   145 });
       
   146 
       
   147 addFeature('value-set', 'select', {
       
   148     test: function() {
       
   149         var node = Y.config.doc.createElement('select');
       
   150         node.innerHTML = '<option>1</option><option>2</option>';
       
   151         node.value = '2';
       
   152         return (node.value && node.value === '2');
       
   153     }
       
   154 });
       
   155 
       
   156 if (!testFeature('value-set', 'select')) {
       
   157     Y_DOM.VALUE_SETTERS.select = function(node, val) {
       
   158         for (var i = 0, options = node.getElementsByTagName('option'), option;
       
   159                 option = options[i++];) {
       
   160             if (Y_DOM.getValue(option) === val) {
       
   161                 option.selected = true;
       
   162                 //Y_DOM.setAttribute(option, 'selected', 'selected');
       
   163                 break;
       
   164             }
       
   165         }
       
   166     };
       
   167 }
       
   168 
       
   169 Y.mix(Y_DOM.VALUE_GETTERS, {
       
   170     button: function(node) {
       
   171         return (node.attributes && node.attributes.value) ? node.attributes.value.value : '';
       
   172     }
       
   173 });
       
   174 
       
   175 Y.mix(Y_DOM.VALUE_SETTERS, {
       
   176     // IE: node.value changes the button text, which should be handled via innerHTML
       
   177     button: function(node, val) {
       
   178         var attr = node.attributes.value;
       
   179         if (!attr) {
       
   180             attr = node[OWNER_DOCUMENT].createAttribute('value');
       
   181             node.setAttributeNode(attr);
       
   182         }
       
   183 
       
   184         attr.value = val;
       
   185     }
       
   186 });
       
   187 
       
   188 
       
   189 Y.mix(Y_DOM.VALUE_GETTERS, {
       
   190     option: function(node) {
       
   191         var attrs = node.attributes;
       
   192         return (attrs.value && attrs.value.specified) ? node.value : node.text;
       
   193     },
       
   194 
       
   195     select: function(node) {
       
   196         var val = node.value,
       
   197             options = node.options;
       
   198 
       
   199         if (options && options.length) {
       
   200             // TODO: implement multipe select
       
   201             if (node.multiple) {
       
   202                 Y.log('multiple select normalization not implemented', 'warn', 'DOM');
       
   203             } else if (node.selectedIndex > -1) {
       
   204                 val = Y_DOM.getValue(options[node.selectedIndex]);
       
   205             }
       
   206         }
       
   207 
       
   208         return val;
       
   209     }
       
   210 });
       
   211 var addClass, hasClass, removeClass;
       
   212 
       
   213 Y.mix(Y.DOM, {
       
   214     /**
       
   215      * Determines whether a DOM element has the given className.
       
   216      * @method hasClass
       
   217      * @for DOM
       
   218      * @param {HTMLElement} element The DOM element.
       
   219      * @param {String} className the class name to search for
       
   220      * @return {Boolean} Whether or not the element has the given class.
       
   221      */
       
   222     hasClass: function(node, className) {
       
   223         var re = Y.DOM._getRegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
       
   224         return re.test(node.className);
       
   225     },
       
   226 
       
   227     /**
       
   228      * Adds a class name to a given DOM element.
       
   229      * @method addClass
       
   230      * @for DOM
       
   231      * @param {HTMLElement} element The DOM element.
       
   232      * @param {String} className the class name to add to the class attribute
       
   233      */
       
   234     addClass: function(node, className) {
       
   235         if (!Y.DOM.hasClass(node, className)) { // skip if already present
       
   236             node.className = Y.Lang.trim([node.className, className].join(' '));
       
   237         }
       
   238     },
       
   239 
       
   240     /**
       
   241      * Removes a class name from a given element.
       
   242      * @method removeClass
       
   243      * @for DOM
       
   244      * @param {HTMLElement} element The DOM element.
       
   245      * @param {String} className the class name to remove from the class attribute
       
   246      */
       
   247     removeClass: function(node, className) {
       
   248         if (className && hasClass(node, className)) {
       
   249             node.className = Y.Lang.trim(node.className.replace(Y.DOM._getRegExp('(?:^|\\s+)' +
       
   250                             className + '(?:\\s+|$)'), ' '));
       
   251 
       
   252             if ( hasClass(node, className) ) { // in case of multiple adjacent
       
   253                 removeClass(node, className);
       
   254             }
       
   255         }
       
   256     },
       
   257 
       
   258     /**
       
   259      * Replace a class with another class for a given element.
       
   260      * If no oldClassName is present, the newClassName is simply added.
       
   261      * @method replaceClass
       
   262      * @for DOM
       
   263      * @param {HTMLElement} element The DOM element
       
   264      * @param {String} oldClassName the class name to be replaced
       
   265      * @param {String} newClassName the class name that will be replacing the old class name
       
   266      */
       
   267     replaceClass: function(node, oldC, newC) {
       
   268         //Y.log('replaceClass replacing ' + oldC + ' with ' + newC, 'info', 'Node');
       
   269         removeClass(node, oldC); // remove first in case oldC === newC
       
   270         addClass(node, newC);
       
   271     },
       
   272 
       
   273     /**
       
   274      * If the className exists on the node it is removed, if it doesn't exist it is added.
       
   275      * @method toggleClass
       
   276      * @for DOM
       
   277      * @param {HTMLElement} element The DOM element
       
   278      * @param {String} className the class name to be toggled
       
   279      * @param {Boolean} addClass optional boolean to indicate whether class
       
   280      * should be added or removed regardless of current state
       
   281      */
       
   282     toggleClass: function(node, className, force) {
       
   283         var add = (force !== undefined) ? force :
       
   284                 !(hasClass(node, className));
       
   285 
       
   286         if (add) {
       
   287             addClass(node, className);
       
   288         } else {
       
   289             removeClass(node, className);
       
   290         }
       
   291     }
       
   292 });
       
   293 
       
   294 hasClass = Y.DOM.hasClass;
       
   295 removeClass = Y.DOM.removeClass;
       
   296 addClass = Y.DOM.addClass;
       
   297 
       
   298 var re_tag = /<([a-z]+)/i,
       
   299 
       
   300     Y_DOM = Y.DOM,
       
   301 
       
   302     addFeature = Y.Features.add,
       
   303     testFeature = Y.Features.test,
       
   304 
       
   305     creators = {},
       
   306 
       
   307     createFromDIV = function(html, tag) {
       
   308         var div = Y.config.doc.createElement('div'),
       
   309             ret = true;
       
   310 
       
   311         div.innerHTML = html;
       
   312         if (!div.firstChild || div.firstChild.tagName !== tag.toUpperCase()) {
       
   313             ret = false;
       
   314         }
       
   315 
       
   316         return ret;
       
   317     },
       
   318 
       
   319     re_tbody = /(?:\/(?:thead|tfoot|tbody|caption|col|colgroup)>)+\s*<tbody/,
       
   320 
       
   321     TABLE_OPEN = '<table>',
       
   322     TABLE_CLOSE = '</table>', 
       
   323     
       
   324     selectedIndex;
       
   325 
       
   326 Y.mix(Y.DOM, {
       
   327     _fragClones: {},
       
   328 
       
   329     _create: function(html, doc, tag) {
       
   330         tag = tag || 'div';
       
   331 
       
   332         var frag = Y_DOM._fragClones[tag];
       
   333         if (frag) {
       
   334             frag = frag.cloneNode(false);
       
   335         } else {
       
   336             frag = Y_DOM._fragClones[tag] = doc.createElement(tag);
       
   337         }
       
   338         frag.innerHTML = html;
       
   339         return frag;
       
   340     },
       
   341 
       
   342     _children: function(node, tag) {
       
   343             var i = 0,
       
   344             children = node.children,
       
   345             childNodes,
       
   346             hasComments,
       
   347             child;
       
   348 
       
   349         if (children && children.tags) { // use tags filter when possible
       
   350             if (tag) {
       
   351                 children = node.children.tags(tag);
       
   352             } else { // IE leaks comments into children
       
   353                 hasComments = children.tags('!').length;
       
   354             }
       
   355         }
       
   356 
       
   357         if (!children || (!children.tags && tag) || hasComments) {
       
   358             childNodes = children || node.childNodes;
       
   359             children = [];
       
   360             while ((child = childNodes[i++])) {
       
   361                 if (child.nodeType === 1) {
       
   362                     if (!tag || tag === child.tagName) {
       
   363                         children.push(child);
       
   364                     }
       
   365                 }
       
   366             }
       
   367         }
       
   368 
       
   369         return children || [];
       
   370     },
       
   371 
       
   372     /**
       
   373      * Creates a new dom node using the provided markup string.
       
   374      * @method create
       
   375      * @param {String} html The markup used to create the element
       
   376      * @param {HTMLDocument} doc An optional document context
       
   377      * @return {HTMLElement|DocumentFragment} returns a single HTMLElement
       
   378      * when creating one node, and a documentFragment when creating
       
   379      * multiple nodes.
       
   380      */
       
   381     create: function(html, doc) {
       
   382         if (typeof html === 'string') {
       
   383             html = Y.Lang.trim(html); // match IE which trims whitespace from innerHTML
       
   384 
       
   385         }
       
   386 
       
   387         doc = doc || Y.config.doc;
       
   388         var m = re_tag.exec(html),
       
   389             create = Y_DOM._create,
       
   390             custom = creators,
       
   391             ret = null,
       
   392             creator, tag, node, nodes;
       
   393 
       
   394         if (html != undefined) { // not undefined or null
       
   395             if (m && m[1]) {
       
   396                 creator = custom[m[1].toLowerCase()];
       
   397                 if (typeof creator === 'function') {
       
   398                     create = creator;
       
   399                 } else {
       
   400                     tag = creator;
       
   401                 }
       
   402             }
       
   403             
       
   404             node = create(html, doc, tag);
       
   405             nodes = node.childNodes;
       
   406 
       
   407             if (nodes.length === 1) { // return single node, breaking parentNode ref from "fragment"
       
   408                 ret = node.removeChild(nodes[0]);
       
   409             } else if (nodes[0] && nodes[0].className === 'yui3-big-dummy') { // using dummy node to preserve some attributes (e.g. OPTION not selected)
       
   410                 selectedIndex = node.selectedIndex;
       
   411                 
       
   412                 if (nodes.length === 2) {
       
   413                     ret = nodes[0].nextSibling;
       
   414                 } else {
       
   415                     node.removeChild(nodes[0]);
       
   416                     ret = Y_DOM._nl2frag(nodes, doc);
       
   417                 }
       
   418             } else { // return multiple nodes as a fragment
       
   419                  ret = Y_DOM._nl2frag(nodes, doc);
       
   420             }
       
   421 
       
   422         }
       
   423 
       
   424         return ret;
       
   425     },
       
   426 
       
   427     _nl2frag: function(nodes, doc) {
       
   428         var ret = null,
       
   429             i, len;
       
   430 
       
   431         if (nodes && (nodes.push || nodes.item) && nodes[0]) {
       
   432             doc = doc || nodes[0].ownerDocument;
       
   433             ret = doc.createDocumentFragment();
       
   434 
       
   435             if (nodes.item) { // convert live list to static array
       
   436                 nodes = Y.Array(nodes, 0, true);
       
   437             }
       
   438 
       
   439             for (i = 0, len = nodes.length; i < len; i++) {
       
   440                 ret.appendChild(nodes[i]);
       
   441             }
       
   442         } // else inline with log for minification
       
   443         return ret;
       
   444     },
       
   445 
       
   446     /**
       
   447      * Inserts content in a node at the given location
       
   448      * @method addHTML
       
   449      * @param {HTMLElement} node The node to insert into
       
   450      * @param {HTMLElement | Array | HTMLCollection} content The content to be inserted
       
   451      * @param {HTMLElement} where Where to insert the content
       
   452      * If no "where" is given, content is appended to the node
       
   453      * Possible values for "where"
       
   454      * <dl>
       
   455      * <dt>HTMLElement</dt>
       
   456      * <dd>The element to insert before</dd>
       
   457      * <dt>"replace"</dt>
       
   458      * <dd>Replaces the existing HTML</dd>
       
   459      * <dt>"before"</dt>
       
   460      * <dd>Inserts before the existing HTML</dd>
       
   461      * <dt>"before"</dt>
       
   462      * <dd>Inserts content before the node</dd>
       
   463      * <dt>"after"</dt>
       
   464      * <dd>Inserts content after the node</dd>
       
   465      * </dl>
       
   466      */
       
   467     addHTML: function(node, content, where) {
       
   468         var nodeParent = node.parentNode,
       
   469             i = 0,
       
   470             item,
       
   471             ret = content,
       
   472             newNode;
       
   473 
       
   474 
       
   475         if (content != undefined) { // not null or undefined (maybe 0)
       
   476             if (content.nodeType) { // DOM node, just add it
       
   477                 newNode = content;
       
   478             } else if (typeof content == 'string' || typeof content == 'number') {
       
   479                 ret = newNode = Y_DOM.create(content);
       
   480             } else if (content[0] && content[0].nodeType) { // array or collection
       
   481                 newNode = Y.config.doc.createDocumentFragment();
       
   482                 while ((item = content[i++])) {
       
   483                     newNode.appendChild(item); // append to fragment for insertion
       
   484                 }
       
   485             }
       
   486         }
       
   487 
       
   488         if (where) {
       
   489             if (newNode && where.parentNode) { // insert regardless of relationship to node
       
   490                 where.parentNode.insertBefore(newNode, where);
       
   491             } else {
       
   492                 switch (where) {
       
   493                     case 'replace':
       
   494                         while (node.firstChild) {
       
   495                             node.removeChild(node.firstChild);
       
   496                         }
       
   497                         if (newNode) { // allow empty content to clear node
       
   498                             node.appendChild(newNode);
       
   499                         }
       
   500                         break;
       
   501                     case 'before':
       
   502                         if (newNode) {
       
   503                             nodeParent.insertBefore(newNode, node);
       
   504                         }
       
   505                         break;
       
   506                     case 'after':
       
   507                         if (newNode) {
       
   508                             if (node.nextSibling) { // IE errors if refNode is null
       
   509                                 nodeParent.insertBefore(newNode, node.nextSibling);
       
   510                             } else {
       
   511                                 nodeParent.appendChild(newNode);
       
   512                             }
       
   513                         }
       
   514                         break;
       
   515                     default:
       
   516                         if (newNode) {
       
   517                             node.appendChild(newNode);
       
   518                         }
       
   519                 }
       
   520             }
       
   521         } else if (newNode) {
       
   522             node.appendChild(newNode);
       
   523         }
       
   524 
       
   525         // `select` elements are the only elements with `selectedIndex`.
       
   526         // Don't grab the dummy `option` element's `selectedIndex`.
       
   527         if (node.nodeName == "SELECT" && selectedIndex > 0) {
       
   528             node.selectedIndex = selectedIndex - 1;
       
   529         }
       
   530         
       
   531         return ret;
       
   532     },
       
   533 
       
   534     wrap: function(node, html) {
       
   535         var parent = (html && html.nodeType) ? html : Y.DOM.create(html),
       
   536             nodes = parent.getElementsByTagName('*');
       
   537 
       
   538         if (nodes.length) {
       
   539             parent = nodes[nodes.length - 1];
       
   540         }
       
   541 
       
   542         if (node.parentNode) {
       
   543             node.parentNode.replaceChild(parent, node);
       
   544         }
       
   545         parent.appendChild(node);
       
   546     },
       
   547 
       
   548     unwrap: function(node) {
       
   549         var parent = node.parentNode,
       
   550             lastChild = parent.lastChild,
       
   551             next = node,
       
   552             grandparent;
       
   553 
       
   554         if (parent) {
       
   555             grandparent = parent.parentNode;
       
   556             if (grandparent) {
       
   557                 node = parent.firstChild;
       
   558                 while (node !== lastChild) {
       
   559                     next = node.nextSibling;
       
   560                     grandparent.insertBefore(node, parent);
       
   561                     node = next;
       
   562                 }
       
   563                 grandparent.replaceChild(lastChild, parent);
       
   564             } else {
       
   565                 parent.removeChild(node);
       
   566             }
       
   567         }
       
   568     }
       
   569 });
       
   570 
       
   571 addFeature('innerhtml', 'table', {
       
   572     test: function() {
       
   573         var node = Y.config.doc.createElement('table');
       
   574         try {
       
   575             node.innerHTML = '<tbody></tbody>';
       
   576         } catch(e) {
       
   577             return false;
       
   578         }
       
   579         return (node.firstChild && node.firstChild.nodeName === 'TBODY');
       
   580     }
       
   581 });
       
   582 
       
   583 addFeature('innerhtml-div', 'tr', {
       
   584     test: function() {
       
   585         return createFromDIV('<tr></tr>', 'tr');
       
   586     }
       
   587 });
       
   588 
       
   589 addFeature('innerhtml-div', 'script', {
       
   590     test: function() {
       
   591         return createFromDIV('<script></script>', 'script');
       
   592     }
       
   593 });
       
   594 
       
   595 if (!testFeature('innerhtml', 'table')) {
       
   596     // TODO: thead/tfoot with nested tbody
       
   597         // IE adds TBODY when creating TABLE elements (which may share this impl)
       
   598     creators.tbody = function(html, doc) {
       
   599         var frag = Y_DOM.create(TABLE_OPEN + html + TABLE_CLOSE, doc),
       
   600             tb = Y.DOM._children(frag, 'tbody')[0];
       
   601 
       
   602         if (frag.children.length > 1 && tb && !re_tbody.test(html)) {
       
   603             tb.parentNode.removeChild(tb); // strip extraneous tbody
       
   604         }
       
   605         return frag;
       
   606     };
       
   607 }
       
   608 
       
   609 if (!testFeature('innerhtml-div', 'script')) {
       
   610     creators.script = function(html, doc) {
       
   611         var frag = doc.createElement('div');
       
   612 
       
   613         frag.innerHTML = '-' + html;
       
   614         frag.removeChild(frag.firstChild);
       
   615         return frag;
       
   616     };
       
   617 
       
   618     creators.link = creators.style = creators.script;
       
   619 }
       
   620 
       
   621 if (!testFeature('innerhtml-div', 'tr')) {
       
   622     Y.mix(creators, {
       
   623         option: function(html, doc) {
       
   624             return Y_DOM.create('<select><option class="yui3-big-dummy" selected></option>' + html + '</select>', doc);
       
   625         },
       
   626 
       
   627         tr: function(html, doc) {
       
   628             return Y_DOM.create('<tbody>' + html + '</tbody>', doc);
       
   629         },
       
   630 
       
   631         td: function(html, doc) {
       
   632             return Y_DOM.create('<tr>' + html + '</tr>', doc);
       
   633         },
       
   634 
       
   635         col: function(html, doc) {
       
   636             return Y_DOM.create('<colgroup>' + html + '</colgroup>', doc);
       
   637         },
       
   638 
       
   639         tbody: 'table'
       
   640     });
       
   641 
       
   642     Y.mix(creators, {
       
   643         legend: 'fieldset',
       
   644         th: creators.td,
       
   645         thead: creators.tbody,
       
   646         tfoot: creators.tbody,
       
   647         caption: creators.tbody,
       
   648         colgroup: creators.tbody,
       
   649         optgroup: creators.option
       
   650     });
       
   651 }
       
   652 
       
   653 Y_DOM.creators = creators;
       
   654 Y.mix(Y.DOM, {
       
   655     /**
       
   656      * Sets the width of the element to the given size, regardless
       
   657      * of box model, border, padding, etc.
       
   658      * @method setWidth
       
   659      * @param {HTMLElement} element The DOM element.
       
   660      * @param {String|Number} size The pixel height to size to
       
   661      */
       
   662 
       
   663     setWidth: function(node, size) {
       
   664         Y.DOM._setSize(node, 'width', size);
       
   665     },
       
   666 
       
   667     /**
       
   668      * Sets the height of the element to the given size, regardless
       
   669      * of box model, border, padding, etc.
       
   670      * @method setHeight
       
   671      * @param {HTMLElement} element The DOM element.
       
   672      * @param {String|Number} size The pixel height to size to
       
   673      */
       
   674 
       
   675     setHeight: function(node, size) {
       
   676         Y.DOM._setSize(node, 'height', size);
       
   677     },
       
   678 
       
   679     _setSize: function(node, prop, val) {
       
   680         val = (val > 0) ? val : 0;
       
   681         var size = 0;
       
   682 
       
   683         node.style[prop] = val + 'px';
       
   684         size = (prop === 'height') ? node.offsetHeight : node.offsetWidth;
       
   685 
       
   686         if (size > val) {
       
   687             val = val - (size - val);
       
   688 
       
   689             if (val < 0) {
       
   690                 val = 0;
       
   691             }
       
   692 
       
   693             node.style[prop] = val + 'px';
       
   694         }
       
   695     }
       
   696 });
       
   697 
       
   698 
       
   699 }, '@VERSION@', {"requires": ["dom-core"]});