OLD | NEW |
(Empty) | |
| 1 /* |
| 2 Copyright (c) 2008, Yahoo! Inc. All rights reserved. |
| 3 Code licensed under the BSD License: |
| 4 http://developer.yahoo.net/yui/license.txt |
| 5 version: 2.6.0 |
| 6 */ |
| 7 /** |
| 8 * The dom module provides helper methods for manipulating Dom elements. |
| 9 * @module dom |
| 10 * |
| 11 */ |
| 12 |
| 13 (function() { |
| 14 var Y = YAHOO.util, // internal shorthand |
| 15 lang = YAHOO.lang, |
| 16 getStyle, // for load time browser branching |
| 17 setStyle, // ditto |
| 18 propertyCache = {}, // for faster hyphen converts |
| 19 reClassNameCache = {}, // cache regexes for className |
| 20 document = window.document; // cache for faster lookups |
| 21 |
| 22 YAHOO.env._id_counter = YAHOO.env._id_counter || 0; // for use with gene
rateId (global to save state if Dom is overwritten) |
| 23 |
| 24 // brower detection |
| 25 var isOpera = YAHOO.env.ua.opera, |
| 26 isSafari = YAHOO.env.ua.webkit, |
| 27 isGecko = YAHOO.env.ua.gecko, |
| 28 isIE = YAHOO.env.ua.ie; |
| 29 |
| 30 // regex cache |
| 31 var patterns = { |
| 32 HYPHEN: /(-[a-z])/i, // to normalize get/setStyle |
| 33 ROOT_TAG: /^body|html$/i, // body for quirks mode, html for standards, |
| 34 OP_SCROLL:/^(?:inline|table-row)$/i |
| 35 }; |
| 36 |
| 37 var toCamel = function(property) { |
| 38 if ( !patterns.HYPHEN.test(property) ) { |
| 39 return property; // no hyphens |
| 40 } |
| 41 |
| 42 if (propertyCache[property]) { // already converted |
| 43 return propertyCache[property]; |
| 44 } |
| 45 |
| 46 var converted = property; |
| 47 |
| 48 while( patterns.HYPHEN.exec(converted) ) { |
| 49 converted = converted.replace(RegExp.$1, |
| 50 RegExp.$1.substr(1).toUpperCase()); |
| 51 } |
| 52 |
| 53 propertyCache[property] = converted; |
| 54 return converted; |
| 55 //return property.replace(/-([a-z])/gi, function(m0, m1) {return m1.toUp
perCase()}) // cant use function as 2nd arg yet due to safari bug |
| 56 }; |
| 57 |
| 58 var getClassRegEx = function(className) { |
| 59 var re = reClassNameCache[className]; |
| 60 if (!re) { |
| 61 re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)'); |
| 62 reClassNameCache[className] = re; |
| 63 } |
| 64 return re; |
| 65 }; |
| 66 |
| 67 // branching at load instead of runtime |
| 68 if (document.defaultView && document.defaultView.getComputedStyle) { // W3C
DOM method |
| 69 getStyle = function(el, property) { |
| 70 var value = null; |
| 71 |
| 72 if (property == 'float') { // fix reserved word |
| 73 property = 'cssFloat'; |
| 74 } |
| 75 |
| 76 var computed = el.ownerDocument.defaultView.getComputedStyle(el, '')
; |
| 77 if (computed) { // test computed before touching for safari |
| 78 value = computed[toCamel(property)]; |
| 79 } |
| 80 |
| 81 return el.style[property] || value; |
| 82 }; |
| 83 } else if (document.documentElement.currentStyle && isIE) { // IE method |
| 84 getStyle = function(el, property) { |
| 85 switch( toCamel(property) ) { |
| 86 case 'opacity' :// IE opacity uses filter |
| 87 var val = 100; |
| 88 try { // will error if no DXImageTransform |
| 89 val = el.filters['DXImageTransform.Microsoft.Alpha'].opa
city; |
| 90 |
| 91 } catch(e) { |
| 92 try { // make sure its in the document |
| 93 val = el.filters('alpha').opacity; |
| 94 } catch(e) { |
| 95 } |
| 96 } |
| 97 return val / 100; |
| 98 case 'float': // fix reserved word |
| 99 property = 'styleFloat'; // fall through |
| 100 default: |
| 101 // test currentStyle before touching |
| 102 var value = el.currentStyle ? el.currentStyle[property] : nu
ll; |
| 103 return ( el.style[property] || value ); |
| 104 } |
| 105 }; |
| 106 } else { // default to inline only |
| 107 getStyle = function(el, property) { return el.style[property]; }; |
| 108 } |
| 109 |
| 110 if (isIE) { |
| 111 setStyle = function(el, property, val) { |
| 112 switch (property) { |
| 113 case 'opacity': |
| 114 if ( lang.isString(el.style.filter) ) { // in case not appen
ded |
| 115 el.style.filter = 'alpha(opacity=' + val * 100 + ')'; |
| 116 |
| 117 if (!el.currentStyle || !el.currentStyle.hasLayout) { |
| 118 el.style.zoom = 1; // when no layout or cant tell |
| 119 } |
| 120 } |
| 121 break; |
| 122 case 'float': |
| 123 property = 'styleFloat'; |
| 124 default: |
| 125 el.style[property] = val; |
| 126 } |
| 127 }; |
| 128 } else { |
| 129 setStyle = function(el, property, val) { |
| 130 if (property == 'float') { |
| 131 property = 'cssFloat'; |
| 132 } |
| 133 el.style[property] = val; |
| 134 }; |
| 135 } |
| 136 |
| 137 var testElement = function(node, method) { |
| 138 return node && node.nodeType == 1 && ( !method || method(node) ); |
| 139 }; |
| 140 |
| 141 /** |
| 142 * Provides helper methods for DOM elements. |
| 143 * @namespace YAHOO.util |
| 144 * @class Dom |
| 145 */ |
| 146 YAHOO.util.Dom = { |
| 147 /** |
| 148 * Returns an HTMLElement reference. |
| 149 * @method get |
| 150 * @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. |
| 151 * @return {HTMLElement | Array} A DOM reference to an HTML element or a
n array of HTMLElements. |
| 152 */ |
| 153 get: function(el) { |
| 154 if (el) { |
| 155 if (el.nodeType || el.item) { // Node, or NodeList |
| 156 return el; |
| 157 } |
| 158 |
| 159 if (typeof el === 'string') { // id |
| 160 return document.getElementById(el); |
| 161 } |
| 162 |
| 163 if ('length' in el) { // array-like |
| 164 var c = []; |
| 165 for (var i = 0, len = el.length; i < len; ++i) { |
| 166 c[c.length] = Y.Dom.get(el[i]); |
| 167 } |
| 168 |
| 169 return c; |
| 170 } |
| 171 |
| 172 return el; // some other object, just pass it back |
| 173 } |
| 174 |
| 175 return null; |
| 176 }, |
| 177 |
| 178 /** |
| 179 * Normalizes currentStyle and ComputedStyle. |
| 180 * @method getStyle |
| 181 * @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. |
| 182 * @param {String} property The style property whose value is returned. |
| 183 * @return {String | Array} The current value of the style property for
the element(s). |
| 184 */ |
| 185 getStyle: function(el, property) { |
| 186 property = toCamel(property); |
| 187 |
| 188 var f = function(element) { |
| 189 return getStyle(element, property); |
| 190 }; |
| 191 |
| 192 return Y.Dom.batch(el, f, Y.Dom, true); |
| 193 }, |
| 194 |
| 195 /** |
| 196 * Wrapper for setting style properties of HTMLElements. Normalizes "op
acity" across modern browsers. |
| 197 * @method setStyle |
| 198 * @param {String | HTMLElement | Array} el Accepts a string to use as a
n ID, an actual DOM reference, or an Array of IDs and/or HTMLElements. |
| 199 * @param {String} property The style property to be set. |
| 200 * @param {String} val The value to apply to the given property. |
| 201 */ |
| 202 setStyle: function(el, property, val) { |
| 203 property = toCamel(property); |
| 204 |
| 205 var f = function(element) { |
| 206 setStyle(element, property, val); |
| 207 |
| 208 }; |
| 209 |
| 210 Y.Dom.batch(el, f, Y.Dom, true); |
| 211 }, |
| 212 |
| 213 /** |
| 214 * Gets the current position of an element based on page coordinates. E
lement must be part of the DOM tree to have page coordinates (display:none or el
ements not appended return false). |
| 215 * @method getXY |
| 216 * @param {String | HTMLElement | Array} el Accepts a string to use as a
n ID, an actual DOM reference, or an Array of IDs and/or HTMLElements |
| 217 * @return {Array} The XY position of the element(s) |
| 218 */ |
| 219 getXY: function(el) { |
| 220 var f = function(el) { |
| 221 // has to be part of document to have pageXY |
| 222 if ( (el.parentNode === null || el.offsetParent === null || |
| 223 this.getStyle(el, 'display') == 'none') && el != el.owne
rDocument.body) { |
| 224 return false; |
| 225 } |
| 226 |
| 227 return getXY(el); |
| 228 }; |
| 229 |
| 230 return Y.Dom.batch(el, f, Y.Dom, true); |
| 231 }, |
| 232 |
| 233 /** |
| 234 * 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). |
| 235 * @method getX |
| 236 * @param {String | HTMLElement | Array} el Accepts a string to use as a
n ID, an actual DOM reference, or an Array of IDs and/or HTMLElements |
| 237 * @return {Number | Array} The X position of the element(s) |
| 238 */ |
| 239 getX: function(el) { |
| 240 var f = function(el) { |
| 241 return Y.Dom.getXY(el)[0]; |
| 242 }; |
| 243 |
| 244 return Y.Dom.batch(el, f, Y.Dom, true); |
| 245 }, |
| 246 |
| 247 /** |
| 248 * 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). |
| 249 * @method getY |
| 250 * @param {String | HTMLElement | Array} el Accepts a string to use as a
n ID, an actual DOM reference, or an Array of IDs and/or HTMLElements |
| 251 * @return {Number | Array} The Y position of the element(s) |
| 252 */ |
| 253 getY: function(el) { |
| 254 var f = function(el) { |
| 255 return Y.Dom.getXY(el)[1]; |
| 256 }; |
| 257 |
| 258 return Y.Dom.batch(el, f, Y.Dom, true); |
| 259 }, |
| 260 |
| 261 /** |
| 262 * Set the position of an html element in page coordinates, regardless o
f how the element is positioned. |
| 263 * The element(s) must be part of the DOM tree to have page coordinates
(display:none or elements not appended return false). |
| 264 * @method setXY |
| 265 * @param {String | HTMLElement | Array} el Accepts a string to use as a
n ID, an actual DOM reference, or an Array of IDs and/or HTMLElements |
| 266 * @param {Array} pos Contains X & Y values for new position (coordinate
s are page-based) |
| 267 * @param {Boolean} noRetry By default we try and set the position a sec
ond time if the first fails |
| 268 */ |
| 269 setXY: function(el, pos, noRetry) { |
| 270 var f = function(el) { |
| 271 var style_pos = this.getStyle(el, 'position'); |
| 272 if (style_pos == 'static') { // default to relative |
| 273 this.setStyle(el, 'position', 'relative'); |
| 274 style_pos = 'relative'; |
| 275 } |
| 276 |
| 277 var pageXY = this.getXY(el); |
| 278 if (pageXY === false) { // has to be part of doc to have pageXY |
| 279 return false; |
| 280 } |
| 281 |
| 282 var delta = [ // assuming pixels; if not we will have to retry |
| 283 parseInt( this.getStyle(el, 'left'), 10 ), |
| 284 parseInt( this.getStyle(el, 'top'), 10 ) |
| 285 ]; |
| 286 |
| 287 if ( isNaN(delta[0]) ) {// in case of 'auto' |
| 288 delta[0] = (style_pos == 'relative') ? 0 : el.offsetLeft; |
| 289 } |
| 290 if ( isNaN(delta[1]) ) { // in case of 'auto' |
| 291 delta[1] = (style_pos == 'relative') ? 0 : el.offsetTop; |
| 292 } |
| 293 |
| 294 if (pos[0] !== null) { el.style.left = pos[0] - pageXY[0] + delt
a[0] + 'px'; } |
| 295 if (pos[1] !== null) { el.style.top = pos[1] - pageXY[1] + delta
[1] + 'px'; } |
| 296 |
| 297 if (!noRetry) { |
| 298 var newXY = this.getXY(el); |
| 299 |
| 300 // if retry is true, try one more time if we miss |
| 301 if ( (pos[0] !== null && newXY[0] != pos[0]) || |
| 302 (pos[1] !== null && newXY[1] != pos[1]) ) { |
| 303 this.setXY(el, pos, true); |
| 304 } |
| 305 } |
| 306 |
| 307 }; |
| 308 |
| 309 Y.Dom.batch(el, f, Y.Dom, true); |
| 310 }, |
| 311 |
| 312 /** |
| 313 * Set the X position of an html element in page coordinates, regardless
of how the element is positioned. |
| 314 * The element must be part of the DOM tree to have page coordinates (di
splay:none or elements not appended return false). |
| 315 * @method setX |
| 316 * @param {String | HTMLElement | Array} el Accepts a string to use as a
n ID, an actual DOM reference, or an Array of IDs and/or HTMLElements. |
| 317 * @param {Int} x The value to use as the X coordinate for the element(s
). |
| 318 */ |
| 319 setX: function(el, x) { |
| 320 Y.Dom.setXY(el, [x, null]); |
| 321 }, |
| 322 |
| 323 /** |
| 324 * Set the Y position of an html element in page coordinates, regardless
of how the element is positioned. |
| 325 * The element must be part of the DOM tree to have page coordinates (di
splay:none or elements not appended return false). |
| 326 * @method setY |
| 327 * @param {String | HTMLElement | Array} el Accepts a string to use as a
n ID, an actual DOM reference, or an Array of IDs and/or HTMLElements. |
| 328 * @param {Int} x To use as the Y coordinate for the element(s). |
| 329 */ |
| 330 setY: function(el, y) { |
| 331 Y.Dom.setXY(el, [null, y]); |
| 332 }, |
| 333 |
| 334 /** |
| 335 * Returns the region position of the given element. |
| 336 * The element must be part of the DOM tree to have a region (display:no
ne or elements not appended return false). |
| 337 * @method getRegion |
| 338 * @param {String | HTMLElement | Array} el Accepts a string to use as a
n ID, an actual DOM reference, or an Array of IDs and/or HTMLElements. |
| 339 * @return {Region | Array} A Region or array of Region instances contai
ning "top, left, bottom, right" member data. |
| 340 */ |
| 341 getRegion: function(el) { |
| 342 var f = function(el) { |
| 343 if ( (el.parentNode === null || el.offsetParent === null || |
| 344 this.getStyle(el, 'display') == 'none') && el != el.owne
rDocument.body) { |
| 345 return false; |
| 346 } |
| 347 |
| 348 var region = Y.Region.getRegion(el); |
| 349 return region; |
| 350 }; |
| 351 |
| 352 return Y.Dom.batch(el, f, Y.Dom, true); |
| 353 }, |
| 354 |
| 355 /** |
| 356 * Returns the width of the client (viewport). |
| 357 * @method getClientWidth |
| 358 * @deprecated Now using getViewportWidth. This interface left intact f
or back compat. |
| 359 * @return {Int} The width of the viewable area of the page. |
| 360 */ |
| 361 getClientWidth: function() { |
| 362 return Y.Dom.getViewportWidth(); |
| 363 }, |
| 364 |
| 365 /** |
| 366 * Returns the height of the client (viewport). |
| 367 * @method getClientHeight |
| 368 * @deprecated Now using getViewportHeight. This interface left intact
for back compat. |
| 369 * @return {Int} The height of the viewable area of the page. |
| 370 */ |
| 371 getClientHeight: function() { |
| 372 return Y.Dom.getViewportHeight(); |
| 373 }, |
| 374 |
| 375 /** |
| 376 * Returns a array of HTMLElements with the given class. |
| 377 * For optimized performance, include a tag and/or root node when possib
le. |
| 378 * Note: This method operates against a live collection, so modifying th
e |
| 379 * collection in the callback (removing/appending nodes, etc.) will have |
| 380 * side effects. Instead you should iterate the returned nodes array, |
| 381 * as you would with the native "getElementsByTagName" method. |
| 382 * @method getElementsByClassName |
| 383 * @param {String} className The class name to match against |
| 384 * @param {String} tag (optional) The tag name of the elements being col
lected |
| 385 * @param {String | HTMLElement} root (optional) The HTMLElement or an I
D to use as the starting point |
| 386 * @param {Function} apply (optional) A function to apply to each elemen
t when found |
| 387 * @return {Array} An array of elements that have the given class name |
| 388 */ |
| 389 getElementsByClassName: function(className, tag, root, apply) { |
| 390 className = lang.trim(className); |
| 391 tag = tag || '*'; |
| 392 root = (root) ? Y.Dom.get(root) : null || document; |
| 393 if (!root) { |
| 394 return []; |
| 395 } |
| 396 |
| 397 var nodes = [], |
| 398 elements = root.getElementsByTagName(tag), |
| 399 re = getClassRegEx(className); |
| 400 |
| 401 for (var i = 0, len = elements.length; i < len; ++i) { |
| 402 if ( re.test(elements[i].className) ) { |
| 403 nodes[nodes.length] = elements[i]; |
| 404 if (apply) { |
| 405 apply.call(elements[i], elements[i]); |
| 406 } |
| 407 } |
| 408 } |
| 409 |
| 410 return nodes; |
| 411 }, |
| 412 |
| 413 /** |
| 414 * Determines whether an HTMLElement has the given className. |
| 415 * @method hasClass |
| 416 * @param {String | HTMLElement | Array} el The element or collection to
test |
| 417 * @param {String} className the class name to search for |
| 418 * @return {Boolean | Array} A boolean value or array of boolean values |
| 419 */ |
| 420 hasClass: function(el, className) { |
| 421 var re = getClassRegEx(className); |
| 422 |
| 423 var f = function(el) { |
| 424 return re.test(el.className); |
| 425 }; |
| 426 |
| 427 return Y.Dom.batch(el, f, Y.Dom, true); |
| 428 }, |
| 429 |
| 430 /** |
| 431 * Adds a class name to a given element or collection of elements. |
| 432 * @method addClass |
| 433 * @param {String | HTMLElement | Array} el The element or collection to
add the class to |
| 434 * @param {String} className the class name to add to the class attribut
e |
| 435 * @return {Boolean | Array} A pass/fail boolean or array of booleans |
| 436 */ |
| 437 addClass: function(el, className) { |
| 438 var f = function(el) { |
| 439 if (this.hasClass(el, className)) { |
| 440 return false; // already present |
| 441 } |
| 442 |
| 443 |
| 444 el.className = lang.trim([el.className, className].join(' ')); |
| 445 return true; |
| 446 }; |
| 447 |
| 448 return Y.Dom.batch(el, f, Y.Dom, true); |
| 449 }, |
| 450 |
| 451 /** |
| 452 * Removes a class name from a given element or collection of elements. |
| 453 * @method removeClass |
| 454 * @param {String | HTMLElement | Array} el The element or collection to
remove the class from |
| 455 * @param {String} className the class name to remove from the class att
ribute |
| 456 * @return {Boolean | Array} A pass/fail boolean or array of booleans |
| 457 */ |
| 458 removeClass: function(el, className) { |
| 459 var re = getClassRegEx(className); |
| 460 |
| 461 var f = function(el) { |
| 462 var ret = false, |
| 463 current = el.className; |
| 464 |
| 465 if (className && current && this.hasClass(el, className)) { |
| 466 |
| 467 el.className = current.replace(re, ' '); |
| 468 if ( this.hasClass(el, className) ) { // in case of multiple
adjacent |
| 469 this.removeClass(el, className); |
| 470 } |
| 471 |
| 472 el.className = lang.trim(el.className); // remove any traili
ng spaces |
| 473 if (el.className === '') { // remove class attribute if empt
y |
| 474 var attr = (el.hasAttribute) ? 'class' : 'className'; |
| 475 el.removeAttribute(attr); |
| 476 } |
| 477 ret = true; |
| 478 } |
| 479 return ret; |
| 480 }; |
| 481 |
| 482 return Y.Dom.batch(el, f, Y.Dom, true); |
| 483 }, |
| 484 |
| 485 /** |
| 486 * Replace a class with another class for a given element or collection
of elements. |
| 487 * If no oldClassName is present, the newClassName is simply added. |
| 488 * @method replaceClass |
| 489 * @param {String | HTMLElement | Array} el The element or collection to
remove the class from |
| 490 * @param {String} oldClassName the class name to be replaced |
| 491 * @param {String} newClassName the class name that will be replacing th
e old class name |
| 492 * @return {Boolean | Array} A pass/fail boolean or array of booleans |
| 493 */ |
| 494 replaceClass: function(el, oldClassName, newClassName) { |
| 495 if (!newClassName || oldClassName === newClassName) { // avoid infin
ite loop |
| 496 return false; |
| 497 } |
| 498 |
| 499 var re = getClassRegEx(oldClassName); |
| 500 |
| 501 var f = function(el) { |
| 502 |
| 503 if ( !this.hasClass(el, oldClassName) ) { |
| 504 this.addClass(el, newClassName); // just add it if nothing t
o replace |
| 505 return true; // NOTE: return |
| 506 } |
| 507 |
| 508 el.className = el.className.replace(re, ' ' + newClassName + ' '
); |
| 509 |
| 510 if ( this.hasClass(el, oldClassName) ) { // in case of multiple
adjacent |
| 511 this.removeClass(el, oldClassName); |
| 512 } |
| 513 |
| 514 el.className = lang.trim(el.className); // remove any trailing s
paces |
| 515 return true; |
| 516 }; |
| 517 |
| 518 return Y.Dom.batch(el, f, Y.Dom, true); |
| 519 }, |
| 520 |
| 521 /** |
| 522 * Returns an ID and applies it to the element "el", if provided. |
| 523 * @method generateId |
| 524 * @param {String | HTMLElement | Array} el (optional) An optional eleme
nt array of elements to add an ID to (no ID is added if one is already present). |
| 525 * @param {String} prefix (optional) an optional prefix to use (defaults
to "yui-gen"). |
| 526 * @return {String | Array} The generated ID, or array of generated IDs
(or original ID if already present on an element) |
| 527 */ |
| 528 generateId: function(el, prefix) { |
| 529 prefix = prefix || 'yui-gen'; |
| 530 |
| 531 var f = function(el) { |
| 532 if (el && el.id) { // do not override existing ID |
| 533 return el.id; |
| 534 } |
| 535 |
| 536 var id = prefix + YAHOO.env._id_counter++; |
| 537 |
| 538 if (el) { |
| 539 el.id = id; |
| 540 } |
| 541 |
| 542 return id; |
| 543 }; |
| 544 |
| 545 // batch fails when no element, so just generate and return single I
D |
| 546 return Y.Dom.batch(el, f, Y.Dom, true) || f.apply(Y.Dom, arguments); |
| 547 }, |
| 548 |
| 549 /** |
| 550 * Determines whether an HTMLElement is an ancestor of another HTML elem
ent in the DOM hierarchy. |
| 551 * @method isAncestor |
| 552 * @param {String | HTMLElement} haystack The possible ancestor |
| 553 * @param {String | HTMLElement} needle The possible descendent |
| 554 * @return {Boolean} Whether or not the haystack is an ancestor of needl
e |
| 555 */ |
| 556 isAncestor: function(haystack, needle) { |
| 557 haystack = Y.Dom.get(haystack); |
| 558 needle = Y.Dom.get(needle); |
| 559 |
| 560 var ret = false; |
| 561 |
| 562 if ( (haystack && needle) && (haystack.nodeType && needle.nodeType)
) { |
| 563 if (haystack.contains && haystack !== needle) { // contains retu
rns true when equal |
| 564 ret = haystack.contains(needle); |
| 565 } |
| 566 else if (haystack.compareDocumentPosition) { // gecko |
| 567 ret = !!(haystack.compareDocumentPosition(needle) & 16); |
| 568 } |
| 569 } else { |
| 570 } |
| 571 return ret; |
| 572 }, |
| 573 |
| 574 /** |
| 575 * Determines whether an HTMLElement is present in the current document. |
| 576 * @method inDocument |
| 577 * @param {String | HTMLElement} el The element to search for |
| 578 * @return {Boolean} Whether or not the element is present in the curren
t document |
| 579 */ |
| 580 inDocument: function(el) { |
| 581 return this.isAncestor(document.documentElement, el); |
| 582 }, |
| 583 |
| 584 /** |
| 585 * Returns a array of HTMLElements that pass the test applied by supplie
d boolean method. |
| 586 * For optimized performance, include a tag and/or root node when possib
le. |
| 587 * Note: This method operates against a live collection, so modifying th
e |
| 588 * collection in the callback (removing/appending nodes, etc.) will have |
| 589 * side effects. Instead you should iterate the returned nodes array, |
| 590 * as you would with the native "getElementsByTagName" method. |
| 591 * @method getElementsBy |
| 592 * @param {Function} method - A boolean method for testing elements whic
h receives the element as its only argument. |
| 593 * @param {String} tag (optional) The tag name of the elements being col
lected |
| 594 * @param {String | HTMLElement} root (optional) The HTMLElement or an I
D to use as the starting point |
| 595 * @param {Function} apply (optional) A function to apply to each elemen
t when found |
| 596 * @return {Array} Array of HTMLElements |
| 597 */ |
| 598 getElementsBy: function(method, tag, root, apply) { |
| 599 tag = tag || '*'; |
| 600 root = (root) ? Y.Dom.get(root) : null || document; |
| 601 |
| 602 if (!root) { |
| 603 return []; |
| 604 } |
| 605 |
| 606 var nodes = [], |
| 607 elements = root.getElementsByTagName(tag); |
| 608 |
| 609 for (var i = 0, len = elements.length; i < len; ++i) { |
| 610 if ( method(elements[i]) ) { |
| 611 nodes[nodes.length] = elements[i]; |
| 612 if (apply) { |
| 613 apply(elements[i]); |
| 614 } |
| 615 } |
| 616 } |
| 617 |
| 618 |
| 619 return nodes; |
| 620 }, |
| 621 |
| 622 /** |
| 623 * Runs the supplied method against each item in the Collection/Array. |
| 624 * The method is called with the element(s) as the first arg, and the op
tional param as the second ( method(el, o) ). |
| 625 * @method batch |
| 626 * @param {String | HTMLElement | Array} el (optional) An element or arr
ay of elements to apply the method to |
| 627 * @param {Function} method The method to apply to the element(s) |
| 628 * @param {Any} o (optional) An optional arg that is passed to the suppl
ied method |
| 629 * @param {Boolean} override (optional) Whether or not to override the s
cope of "method" with "o" |
| 630 * @return {Any | Array} The return value(s) from the supplied method |
| 631 */ |
| 632 batch: function(el, method, o, override) { |
| 633 el = (el && (el.tagName || el.item)) ? el : Y.Dom.get(el); // skip g
et() when possible |
| 634 |
| 635 if (!el || !method) { |
| 636 return false; |
| 637 } |
| 638 var scope = (override) ? o : window; |
| 639 |
| 640 if (el.tagName || el.length === undefined) { // element or not array
-like |
| 641 return method.call(scope, el, o); |
| 642 } |
| 643 |
| 644 var collection = []; |
| 645 |
| 646 for (var i = 0, len = el.length; i < len; ++i) { |
| 647 collection[collection.length] = method.call(scope, el[i], o); |
| 648 } |
| 649 |
| 650 return collection; |
| 651 }, |
| 652 |
| 653 /** |
| 654 * Returns the height of the document. |
| 655 * @method getDocumentHeight |
| 656 * @return {Int} The height of the actual document (which includes the b
ody and its margin). |
| 657 */ |
| 658 getDocumentHeight: function() { |
| 659 var scrollHeight = (document.compatMode != 'CSS1Compat') ? document.
body.scrollHeight : document.documentElement.scrollHeight; |
| 660 |
| 661 var h = Math.max(scrollHeight, Y.Dom.getViewportHeight()); |
| 662 return h; |
| 663 }, |
| 664 |
| 665 /** |
| 666 * Returns the width of the document. |
| 667 * @method getDocumentWidth |
| 668 * @return {Int} The width of the actual document (which includes the bo
dy and its margin). |
| 669 */ |
| 670 getDocumentWidth: function() { |
| 671 var scrollWidth = (document.compatMode != 'CSS1Compat') ? document.b
ody.scrollWidth : document.documentElement.scrollWidth; |
| 672 var w = Math.max(scrollWidth, Y.Dom.getViewportWidth()); |
| 673 return w; |
| 674 }, |
| 675 |
| 676 /** |
| 677 * Returns the current height of the viewport. |
| 678 * @method getViewportHeight |
| 679 * @return {Int} The height of the viewable area of the page (excludes s
crollbars). |
| 680 */ |
| 681 getViewportHeight: function() { |
| 682 var height = self.innerHeight; // Safari, Opera |
| 683 var mode = document.compatMode; |
| 684 |
| 685 if ( (mode || isIE) && !isOpera ) { // IE, Gecko |
| 686 height = (mode == 'CSS1Compat') ? |
| 687 document.documentElement.clientHeight : // Standards |
| 688 document.body.clientHeight; // Quirks |
| 689 } |
| 690 |
| 691 return height; |
| 692 }, |
| 693 |
| 694 /** |
| 695 * Returns the current width of the viewport. |
| 696 * @method getViewportWidth |
| 697 * @return {Int} The width of the viewable area of the page (excludes sc
rollbars). |
| 698 */ |
| 699 |
| 700 getViewportWidth: function() { |
| 701 var width = self.innerWidth; // Safari |
| 702 var mode = document.compatMode; |
| 703 |
| 704 if (mode || isIE) { // IE, Gecko, Opera |
| 705 width = (mode == 'CSS1Compat') ? |
| 706 document.documentElement.clientWidth : // Standards |
| 707 document.body.clientWidth; // Quirks |
| 708 } |
| 709 return width; |
| 710 }, |
| 711 |
| 712 /** |
| 713 * Returns the nearest ancestor that passes the test applied by supplied
boolean method. |
| 714 * For performance reasons, IDs are not accepted and argument validation
omitted. |
| 715 * @method getAncestorBy |
| 716 * @param {HTMLElement} node The HTMLElement to use as the starting poin
t |
| 717 * @param {Function} method - A boolean method for testing elements whic
h receives the element as its only argument. |
| 718 * @return {Object} HTMLElement or null if not found |
| 719 */ |
| 720 getAncestorBy: function(node, method) { |
| 721 while ( (node = node.parentNode) ) { // NOTE: assignment |
| 722 if ( testElement(node, method) ) { |
| 723 return node; |
| 724 } |
| 725 } |
| 726 |
| 727 return null; |
| 728 }, |
| 729 |
| 730 /** |
| 731 * Returns the nearest ancestor with the given className. |
| 732 * @method getAncestorByClassName |
| 733 * @param {String | HTMLElement} node The HTMLElement or an ID to use as
the starting point |
| 734 * @param {String} className |
| 735 * @return {Object} HTMLElement |
| 736 */ |
| 737 getAncestorByClassName: function(node, className) { |
| 738 node = Y.Dom.get(node); |
| 739 if (!node) { |
| 740 return null; |
| 741 } |
| 742 var method = function(el) { return Y.Dom.hasClass(el, className); }; |
| 743 return Y.Dom.getAncestorBy(node, method); |
| 744 }, |
| 745 |
| 746 /** |
| 747 * Returns the nearest ancestor with the given tagName. |
| 748 * @method getAncestorByTagName |
| 749 * @param {String | HTMLElement} node The HTMLElement or an ID to use as
the starting point |
| 750 * @param {String} tagName |
| 751 * @return {Object} HTMLElement |
| 752 */ |
| 753 getAncestorByTagName: function(node, tagName) { |
| 754 node = Y.Dom.get(node); |
| 755 if (!node) { |
| 756 return null; |
| 757 } |
| 758 var method = function(el) { |
| 759 return el.tagName && el.tagName.toUpperCase() == tagName.toUppe
rCase(); |
| 760 }; |
| 761 |
| 762 return Y.Dom.getAncestorBy(node, method); |
| 763 }, |
| 764 |
| 765 /** |
| 766 * Returns the previous sibling that is an HTMLElement. |
| 767 * For performance reasons, IDs are not accepted and argument validation
omitted. |
| 768 * Returns the nearest HTMLElement sibling if no method provided. |
| 769 * @method getPreviousSiblingBy |
| 770 * @param {HTMLElement} node The HTMLElement to use as the starting poin
t |
| 771 * @param {Function} method A boolean function used to test siblings |
| 772 * that receives the sibling node being tested as its only argument |
| 773 * @return {Object} HTMLElement or null if not found |
| 774 */ |
| 775 getPreviousSiblingBy: function(node, method) { |
| 776 while (node) { |
| 777 node = node.previousSibling; |
| 778 if ( testElement(node, method) ) { |
| 779 return node; |
| 780 } |
| 781 } |
| 782 return null; |
| 783 }, |
| 784 |
| 785 /** |
| 786 * Returns the previous sibling that is an HTMLElement |
| 787 * @method getPreviousSibling |
| 788 * @param {String | HTMLElement} node The HTMLElement or an ID to use as
the starting point |
| 789 * @return {Object} HTMLElement or null if not found |
| 790 */ |
| 791 getPreviousSibling: function(node) { |
| 792 node = Y.Dom.get(node); |
| 793 if (!node) { |
| 794 return null; |
| 795 } |
| 796 |
| 797 return Y.Dom.getPreviousSiblingBy(node); |
| 798 }, |
| 799 |
| 800 /** |
| 801 * Returns the next HTMLElement sibling that passes the boolean method. |
| 802 * For performance reasons, IDs are not accepted and argument validation
omitted. |
| 803 * Returns the nearest HTMLElement sibling if no method provided. |
| 804 * @method getNextSiblingBy |
| 805 * @param {HTMLElement} node The HTMLElement to use as the starting poin
t |
| 806 * @param {Function} method A boolean function used to test siblings |
| 807 * that receives the sibling node being tested as its only argument |
| 808 * @return {Object} HTMLElement or null if not found |
| 809 */ |
| 810 getNextSiblingBy: function(node, method) { |
| 811 while (node) { |
| 812 node = node.nextSibling; |
| 813 if ( testElement(node, method) ) { |
| 814 return node; |
| 815 } |
| 816 } |
| 817 return null; |
| 818 }, |
| 819 |
| 820 /** |
| 821 * Returns the next sibling that is an HTMLElement |
| 822 * @method getNextSibling |
| 823 * @param {String | HTMLElement} node The HTMLElement or an ID to use as
the starting point |
| 824 * @return {Object} HTMLElement or null if not found |
| 825 */ |
| 826 getNextSibling: function(node) { |
| 827 node = Y.Dom.get(node); |
| 828 if (!node) { |
| 829 return null; |
| 830 } |
| 831 |
| 832 return Y.Dom.getNextSiblingBy(node); |
| 833 }, |
| 834 |
| 835 /** |
| 836 * Returns the first HTMLElement child that passes the test method. |
| 837 * @method getFirstChildBy |
| 838 * @param {HTMLElement} node The HTMLElement to use as the starting poin
t |
| 839 * @param {Function} method A boolean function used to test children |
| 840 * that receives the node being tested as its only argument |
| 841 * @return {Object} HTMLElement or null if not found |
| 842 */ |
| 843 getFirstChildBy: function(node, method) { |
| 844 var child = ( testElement(node.firstChild, method) ) ? node.firstChi
ld : null; |
| 845 return child || Y.Dom.getNextSiblingBy(node.firstChild, method); |
| 846 }, |
| 847 |
| 848 /** |
| 849 * Returns the first HTMLElement child. |
| 850 * @method getFirstChild |
| 851 * @param {String | HTMLElement} node The HTMLElement or an ID to use as
the starting point |
| 852 * @return {Object} HTMLElement or null if not found |
| 853 */ |
| 854 getFirstChild: function(node, method) { |
| 855 node = Y.Dom.get(node); |
| 856 if (!node) { |
| 857 return null; |
| 858 } |
| 859 return Y.Dom.getFirstChildBy(node); |
| 860 }, |
| 861 |
| 862 /** |
| 863 * Returns the last HTMLElement child that passes the test method. |
| 864 * @method getLastChildBy |
| 865 * @param {HTMLElement} node The HTMLElement to use as the starting poin
t |
| 866 * @param {Function} method A boolean function used to test children |
| 867 * that receives the node being tested as its only argument |
| 868 * @return {Object} HTMLElement or null if not found |
| 869 */ |
| 870 getLastChildBy: function(node, method) { |
| 871 if (!node) { |
| 872 return null; |
| 873 } |
| 874 var child = ( testElement(node.lastChild, method) ) ? node.lastChild
: null; |
| 875 return child || Y.Dom.getPreviousSiblingBy(node.lastChild, method); |
| 876 }, |
| 877 |
| 878 /** |
| 879 * Returns the last HTMLElement child. |
| 880 * @method getLastChild |
| 881 * @param {String | HTMLElement} node The HTMLElement or an ID to use as
the starting point |
| 882 * @return {Object} HTMLElement or null if not found |
| 883 */ |
| 884 getLastChild: function(node) { |
| 885 node = Y.Dom.get(node); |
| 886 return Y.Dom.getLastChildBy(node); |
| 887 }, |
| 888 |
| 889 /** |
| 890 * Returns an array of HTMLElement childNodes that pass the test method.
|
| 891 * @method getChildrenBy |
| 892 * @param {HTMLElement} node The HTMLElement to start from |
| 893 * @param {Function} method A boolean function used to test children |
| 894 * that receives the node being tested as its only argument |
| 895 * @return {Array} A static array of HTMLElements |
| 896 */ |
| 897 getChildrenBy: function(node, method) { |
| 898 var child = Y.Dom.getFirstChildBy(node, method); |
| 899 var children = child ? [child] : []; |
| 900 |
| 901 Y.Dom.getNextSiblingBy(child, function(node) { |
| 902 if ( !method || method(node) ) { |
| 903 children[children.length] = node; |
| 904 } |
| 905 return false; // fail test to collect all children |
| 906 }); |
| 907 |
| 908 return children; |
| 909 }, |
| 910 |
| 911 /** |
| 912 * Returns an array of HTMLElement childNodes. |
| 913 * @method getChildren |
| 914 * @param {String | HTMLElement} node The HTMLElement or an ID to use as
the starting point |
| 915 * @return {Array} A static array of HTMLElements |
| 916 */ |
| 917 getChildren: function(node) { |
| 918 node = Y.Dom.get(node); |
| 919 if (!node) { |
| 920 } |
| 921 |
| 922 return Y.Dom.getChildrenBy(node); |
| 923 }, |
| 924 |
| 925 /** |
| 926 * Returns the left scroll value of the document |
| 927 * @method getDocumentScrollLeft |
| 928 * @param {HTMLDocument} document (optional) The document to get the scr
oll value of |
| 929 * @return {Int} The amount that the document is scrolled to the left |
| 930 */ |
| 931 getDocumentScrollLeft: function(doc) { |
| 932 doc = doc || document; |
| 933 return Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft)
; |
| 934 }, |
| 935 |
| 936 /** |
| 937 * Returns the top scroll value of the document |
| 938 * @method getDocumentScrollTop |
| 939 * @param {HTMLDocument} document (optional) The document to get the scr
oll value of |
| 940 * @return {Int} The amount that the document is scrolled to the top |
| 941 */ |
| 942 getDocumentScrollTop: function(doc) { |
| 943 doc = doc || document; |
| 944 return Math.max(doc.documentElement.scrollTop, doc.body.scrollTop); |
| 945 }, |
| 946 |
| 947 /** |
| 948 * Inserts the new node as the previous sibling of the reference node |
| 949 * @method insertBefore |
| 950 * @param {String | HTMLElement} newNode The node to be inserted |
| 951 * @param {String | HTMLElement} referenceNode The node to insert the ne
w node before |
| 952 * @return {HTMLElement} The node that was inserted (or null if insert f
ails) |
| 953 */ |
| 954 insertBefore: function(newNode, referenceNode) { |
| 955 newNode = Y.Dom.get(newNode); |
| 956 referenceNode = Y.Dom.get(referenceNode); |
| 957 |
| 958 if (!newNode || !referenceNode || !referenceNode.parentNode) { |
| 959 return null; |
| 960 } |
| 961 |
| 962 return referenceNode.parentNode.insertBefore(newNode, referenceNode)
; |
| 963 }, |
| 964 |
| 965 /** |
| 966 * Inserts the new node as the next sibling of the reference node |
| 967 * @method insertAfter |
| 968 * @param {String | HTMLElement} newNode The node to be inserted |
| 969 * @param {String | HTMLElement} referenceNode The node to insert the ne
w node after |
| 970 * @return {HTMLElement} The node that was inserted (or null if insert f
ails) |
| 971 */ |
| 972 insertAfter: function(newNode, referenceNode) { |
| 973 newNode = Y.Dom.get(newNode); |
| 974 referenceNode = Y.Dom.get(referenceNode); |
| 975 |
| 976 if (!newNode || !referenceNode || !referenceNode.parentNode) { |
| 977 return null; |
| 978 } |
| 979 |
| 980 if (referenceNode.nextSibling) { |
| 981 return referenceNode.parentNode.insertBefore(newNode, referenceN
ode.nextSibling); |
| 982 } else { |
| 983 return referenceNode.parentNode.appendChild(newNode); |
| 984 } |
| 985 }, |
| 986 |
| 987 /** |
| 988 * Creates a Region based on the viewport relative to the document. |
| 989 * @method getClientRegion |
| 990 * @return {Region} A Region object representing the viewport which acco
unts for document scroll |
| 991 */ |
| 992 getClientRegion: function() { |
| 993 var t = Y.Dom.getDocumentScrollTop(), |
| 994 l = Y.Dom.getDocumentScrollLeft(), |
| 995 r = Y.Dom.getViewportWidth() + l, |
| 996 b = Y.Dom.getViewportHeight() + t; |
| 997 |
| 998 return new Y.Region(t, r, b, l); |
| 999 } |
| 1000 }; |
| 1001 |
| 1002 var getXY = function() { |
| 1003 if (document.documentElement.getBoundingClientRect) { // IE |
| 1004 return function(el) { |
| 1005 var box = el.getBoundingClientRect(), |
| 1006 round = Math.round; |
| 1007 |
| 1008 var rootNode = el.ownerDocument; |
| 1009 return [round(box.left + Y.Dom.getDocumentScrollLeft(rootNode)),
round(box.top + |
| 1010 Y.Dom.getDocumentScrollTop(rootNode))]; |
| 1011 }; |
| 1012 } else { |
| 1013 return function(el) { // manually calculate by crawling up offsetPar
ents |
| 1014 var pos = [el.offsetLeft, el.offsetTop]; |
| 1015 var parentNode = el.offsetParent; |
| 1016 |
| 1017 // safari: subtract body offsets if el is abs (or any offsetPare
nt), unless body is offsetParent |
| 1018 var accountForBody = (isSafari && |
| 1019 Y.Dom.getStyle(el, 'position') == 'absolute' && |
| 1020 el.offsetParent == el.ownerDocument.body); |
| 1021 |
| 1022 if (parentNode != el) { |
| 1023 while (parentNode) { |
| 1024 pos[0] += parentNode.offsetLeft; |
| 1025 pos[1] += parentNode.offsetTop; |
| 1026 if (!accountForBody && isSafari && |
| 1027 Y.Dom.getStyle(parentNode,'position') == 'absolu
te' ) { |
| 1028 accountForBody = true; |
| 1029 } |
| 1030 parentNode = parentNode.offsetParent; |
| 1031 } |
| 1032 } |
| 1033 |
| 1034 if (accountForBody) { //safari doubles in this case |
| 1035 pos[0] -= el.ownerDocument.body.offsetLeft; |
| 1036 pos[1] -= el.ownerDocument.body.offsetTop; |
| 1037 } |
| 1038 parentNode = el.parentNode; |
| 1039 |
| 1040 // account for any scrolled ancestors |
| 1041 while ( parentNode.tagName && !patterns.ROOT_TAG.test(parentNode
.tagName) ) |
| 1042 { |
| 1043 if (parentNode.scrollTop || parentNode.scrollLeft) { |
| 1044 pos[0] -= parentNode.scrollLeft; |
| 1045 pos[1] -= parentNode.scrollTop; |
| 1046 } |
| 1047 |
| 1048 parentNode = parentNode.parentNode; |
| 1049 } |
| 1050 |
| 1051 return pos; |
| 1052 }; |
| 1053 } |
| 1054 }() // NOTE: Executing for loadtime branching |
| 1055 })(); |
| 1056 /** |
| 1057 * A region is a representation of an object on a grid. It is defined |
| 1058 * by the top, right, bottom, left extents, so is rectangular by default. If |
| 1059 * other shapes are required, this class could be extended to support it. |
| 1060 * @namespace YAHOO.util |
| 1061 * @class Region |
| 1062 * @param {Int} t the top extent |
| 1063 * @param {Int} r the right extent |
| 1064 * @param {Int} b the bottom extent |
| 1065 * @param {Int} l the left extent |
| 1066 * @constructor |
| 1067 */ |
| 1068 YAHOO.util.Region = function(t, r, b, l) { |
| 1069 |
| 1070 /** |
| 1071 * The region's top extent |
| 1072 * @property top |
| 1073 * @type Int |
| 1074 */ |
| 1075 this.top = t; |
| 1076 |
| 1077 /** |
| 1078 * The region's top extent as index, for symmetry with set/getXY |
| 1079 * @property 1 |
| 1080 * @type Int |
| 1081 */ |
| 1082 this[1] = t; |
| 1083 |
| 1084 /** |
| 1085 * The region's right extent |
| 1086 * @property right |
| 1087 * @type int |
| 1088 */ |
| 1089 this.right = r; |
| 1090 |
| 1091 /** |
| 1092 * The region's bottom extent |
| 1093 * @property bottom |
| 1094 * @type Int |
| 1095 */ |
| 1096 this.bottom = b; |
| 1097 |
| 1098 /** |
| 1099 * The region's left extent |
| 1100 * @property left |
| 1101 * @type Int |
| 1102 */ |
| 1103 this.left = l; |
| 1104 |
| 1105 /** |
| 1106 * The region's left extent as index, for symmetry with set/getXY |
| 1107 * @property 0 |
| 1108 * @type Int |
| 1109 */ |
| 1110 this[0] = l; |
| 1111 }; |
| 1112 |
| 1113 /** |
| 1114 * Returns true if this region contains the region passed in |
| 1115 * @method contains |
| 1116 * @param {Region} region The region to evaluate |
| 1117 * @return {Boolean} True if the region is contained with this region, |
| 1118 * else false |
| 1119 */ |
| 1120 YAHOO.util.Region.prototype.contains = function(region) { |
| 1121 return ( region.left >= this.left && |
| 1122 region.right <= this.right && |
| 1123 region.top >= this.top && |
| 1124 region.bottom <= this.bottom ); |
| 1125 |
| 1126 }; |
| 1127 |
| 1128 /** |
| 1129 * Returns the area of the region |
| 1130 * @method getArea |
| 1131 * @return {Int} the region's area |
| 1132 */ |
| 1133 YAHOO.util.Region.prototype.getArea = function() { |
| 1134 return ( (this.bottom - this.top) * (this.right - this.left) ); |
| 1135 }; |
| 1136 |
| 1137 /** |
| 1138 * Returns the region where the passed in region overlaps with this one |
| 1139 * @method intersect |
| 1140 * @param {Region} region The region that intersects |
| 1141 * @return {Region} The overlap region, or null if there is no overlap |
| 1142 */ |
| 1143 YAHOO.util.Region.prototype.intersect = function(region) { |
| 1144 var t = Math.max( this.top, region.top ); |
| 1145 var r = Math.min( this.right, region.right ); |
| 1146 var b = Math.min( this.bottom, region.bottom ); |
| 1147 var l = Math.max( this.left, region.left ); |
| 1148 |
| 1149 if (b >= t && r >= l) { |
| 1150 return new YAHOO.util.Region(t, r, b, l); |
| 1151 } else { |
| 1152 return null; |
| 1153 } |
| 1154 }; |
| 1155 |
| 1156 /** |
| 1157 * Returns the region representing the smallest region that can contain both |
| 1158 * the passed in region and this region. |
| 1159 * @method union |
| 1160 * @param {Region} region The region that to create the union with |
| 1161 * @return {Region} The union region |
| 1162 */ |
| 1163 YAHOO.util.Region.prototype.union = function(region) { |
| 1164 var t = Math.min( this.top, region.top ); |
| 1165 var r = Math.max( this.right, region.right ); |
| 1166 var b = Math.max( this.bottom, region.bottom ); |
| 1167 var l = Math.min( this.left, region.left ); |
| 1168 |
| 1169 return new YAHOO.util.Region(t, r, b, l); |
| 1170 }; |
| 1171 |
| 1172 /** |
| 1173 * toString |
| 1174 * @method toString |
| 1175 * @return string the region properties |
| 1176 */ |
| 1177 YAHOO.util.Region.prototype.toString = function() { |
| 1178 return ( "Region {" + |
| 1179 "top: " + this.top + |
| 1180 ", right: " + this.right + |
| 1181 ", bottom: " + this.bottom + |
| 1182 ", left: " + this.left + |
| 1183 "}" ); |
| 1184 }; |
| 1185 |
| 1186 /** |
| 1187 * Returns a region that is occupied by the DOM element |
| 1188 * @method getRegion |
| 1189 * @param {HTMLElement} el The element |
| 1190 * @return {Region} The region that the element occupies |
| 1191 * @static |
| 1192 */ |
| 1193 YAHOO.util.Region.getRegion = function(el) { |
| 1194 var p = YAHOO.util.Dom.getXY(el); |
| 1195 |
| 1196 var t = p[1]; |
| 1197 var r = p[0] + el.offsetWidth; |
| 1198 var b = p[1] + el.offsetHeight; |
| 1199 var l = p[0]; |
| 1200 |
| 1201 return new YAHOO.util.Region(t, r, b, l); |
| 1202 }; |
| 1203 |
| 1204 ///////////////////////////////////////////////////////////////////////////// |
| 1205 |
| 1206 |
| 1207 /** |
| 1208 * A point is a region that is special in that it represents a single point on |
| 1209 * the grid. |
| 1210 * @namespace YAHOO.util |
| 1211 * @class Point |
| 1212 * @param {Int} x The X position of the point |
| 1213 * @param {Int} y The Y position of the point |
| 1214 * @constructor |
| 1215 * @extends YAHOO.util.Region |
| 1216 */ |
| 1217 YAHOO.util.Point = function(x, y) { |
| 1218 if (YAHOO.lang.isArray(x)) { // accept input from Dom.getXY, Event.getXY, etc
. |
| 1219 y = x[1]; // dont blow away x yet |
| 1220 x = x[0]; |
| 1221 } |
| 1222 |
| 1223 /** |
| 1224 * The X position of the point, which is also the right, left and index zero
(for Dom.getXY symmetry) |
| 1225 * @property x |
| 1226 * @type Int |
| 1227 */ |
| 1228 |
| 1229 this.x = this.right = this.left = this[0] = x; |
| 1230 |
| 1231 /** |
| 1232 * The Y position of the point, which is also the top, bottom and index one
(for Dom.getXY symmetry) |
| 1233 * @property y |
| 1234 * @type Int |
| 1235 */ |
| 1236 this.y = this.top = this.bottom = this[1] = y; |
| 1237 }; |
| 1238 |
| 1239 YAHOO.util.Point.prototype = new YAHOO.util.Region(); |
| 1240 |
| 1241 YAHOO.register("dom", YAHOO.util.Dom, {version: "2.6.0", build: "1321"}); |
OLD | NEW |