|
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"]}); |