[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 /* 2 YUI 3.17.2 (build 9c3c78e) 3 Copyright 2014 Yahoo! Inc. All rights reserved. 4 Licensed under the BSD License. 5 http://yuilibrary.com/license/ 6 */ 7 8 YUI.add('dom-screen', function (Y, NAME) { 9 10 (function(Y) { 11 12 /** 13 * Adds position and region management functionality to DOM. 14 * @module dom 15 * @submodule dom-screen 16 * @for DOM 17 */ 18 19 var DOCUMENT_ELEMENT = 'documentElement', 20 COMPAT_MODE = 'compatMode', 21 POSITION = 'position', 22 FIXED = 'fixed', 23 RELATIVE = 'relative', 24 LEFT = 'left', 25 TOP = 'top', 26 _BACK_COMPAT = 'BackCompat', 27 MEDIUM = 'medium', 28 BORDER_LEFT_WIDTH = 'borderLeftWidth', 29 BORDER_TOP_WIDTH = 'borderTopWidth', 30 GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect', 31 GET_COMPUTED_STYLE = 'getComputedStyle', 32 33 Y_DOM = Y.DOM, 34 35 // TODO: how about thead/tbody/tfoot/tr? 36 // TODO: does caption matter? 37 RE_TABLE = /^t(?:able|d|h)$/i, 38 39 SCROLL_NODE; 40 41 if (Y.UA.ie) { 42 if (Y.config.doc[COMPAT_MODE] !== 'BackCompat') { 43 SCROLL_NODE = DOCUMENT_ELEMENT; 44 } else { 45 SCROLL_NODE = 'body'; 46 } 47 } 48 49 Y.mix(Y_DOM, { 50 /** 51 * Returns the inner height of the viewport (exludes scrollbar). 52 * @method winHeight 53 * @return {Number} The current height of the viewport. 54 */ 55 winHeight: function(node) { 56 var h = Y_DOM._getWinSize(node).height; 57 return h; 58 }, 59 60 /** 61 * Returns the inner width of the viewport (exludes scrollbar). 62 * @method winWidth 63 * @return {Number} The current width of the viewport. 64 */ 65 winWidth: function(node) { 66 var w = Y_DOM._getWinSize(node).width; 67 return w; 68 }, 69 70 /** 71 * Document height 72 * @method docHeight 73 * @return {Number} The current height of the document. 74 */ 75 docHeight: function(node) { 76 var h = Y_DOM._getDocSize(node).height; 77 return Math.max(h, Y_DOM._getWinSize(node).height); 78 }, 79 80 /** 81 * Document width 82 * @method docWidth 83 * @return {Number} The current width of the document. 84 */ 85 docWidth: function(node) { 86 var w = Y_DOM._getDocSize(node).width; 87 return Math.max(w, Y_DOM._getWinSize(node).width); 88 }, 89 90 /** 91 * Amount page has been scroll horizontally 92 * @method docScrollX 93 * @return {Number} The current amount the screen is scrolled horizontally. 94 */ 95 docScrollX: function(node, doc) { 96 doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization 97 var dv = doc.defaultView, 98 pageOffset = (dv) ? dv.pageXOffset : 0; 99 return Math.max(doc[DOCUMENT_ELEMENT].scrollLeft, doc.body.scrollLeft, pageOffset); 100 }, 101 102 /** 103 * Amount page has been scroll vertically 104 * @method docScrollY 105 * @return {Number} The current amount the screen is scrolled vertically. 106 */ 107 docScrollY: function(node, doc) { 108 doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; // perf optimization 109 var dv = doc.defaultView, 110 pageOffset = (dv) ? dv.pageYOffset : 0; 111 return Math.max(doc[DOCUMENT_ELEMENT].scrollTop, doc.body.scrollTop, pageOffset); 112 }, 113 114 /** 115 * Gets the current position of an element based on page coordinates. 116 * Element must be part of the DOM tree to have page coordinates 117 * (display:none or elements not appended return false). 118 * @method getXY 119 * @param element The target element 120 * @return {Array} The XY position of the element 121 122 TODO: test inDocument/display? 123 */ 124 getXY: function() { 125 if (Y.config.doc[DOCUMENT_ELEMENT][GET_BOUNDING_CLIENT_RECT]) { 126 return function(node) { 127 var xy = null, 128 scrollLeft, 129 scrollTop, 130 mode, 131 box, 132 offX, 133 offY, 134 doc, 135 win, 136 inDoc, 137 rootNode; 138 139 if (node && node.tagName) { 140 doc = node.ownerDocument; 141 mode = doc[COMPAT_MODE]; 142 143 if (mode !== _BACK_COMPAT) { 144 rootNode = doc[DOCUMENT_ELEMENT]; 145 } else { 146 rootNode = doc.body; 147 } 148 149 // inline inDoc check for perf 150 if (rootNode.contains) { 151 inDoc = rootNode.contains(node); 152 } else { 153 inDoc = Y.DOM.contains(rootNode, node); 154 } 155 156 if (inDoc) { 157 win = doc.defaultView; 158 159 // inline scroll calc for perf 160 if (win && 'pageXOffset' in win) { 161 scrollLeft = win.pageXOffset; 162 scrollTop = win.pageYOffset; 163 } else { 164 scrollLeft = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollLeft : Y_DOM.docScrollX(node, doc); 165 scrollTop = (SCROLL_NODE) ? doc[SCROLL_NODE].scrollTop : Y_DOM.docScrollY(node, doc); 166 } 167 168 if (Y.UA.ie) { // IE < 8, quirks, or compatMode 169 if (!doc.documentMode || doc.documentMode < 8 || mode === _BACK_COMPAT) { 170 offX = rootNode.clientLeft; 171 offY = rootNode.clientTop; 172 } 173 } 174 box = node[GET_BOUNDING_CLIENT_RECT](); 175 xy = [box.left, box.top]; 176 177 if (offX || offY) { 178 xy[0] -= offX; 179 xy[1] -= offY; 180 181 } 182 if ((scrollTop || scrollLeft)) { 183 if (!Y.UA.ios || (Y.UA.ios >= 4.2)) { 184 xy[0] += scrollLeft; 185 xy[1] += scrollTop; 186 } 187 188 } 189 } else { 190 xy = Y_DOM._getOffset(node); 191 } 192 } 193 return xy; 194 }; 195 } else { 196 return function(node) { // manually calculate by crawling up offsetParents 197 //Calculate the Top and Left border sizes (assumes pixels) 198 var xy = null, 199 doc, 200 parentNode, 201 bCheck, 202 scrollTop, 203 scrollLeft; 204 205 if (node) { 206 if (Y_DOM.inDoc(node)) { 207 xy = [node.offsetLeft, node.offsetTop]; 208 doc = node.ownerDocument; 209 parentNode = node; 210 // TODO: refactor with !! or just falsey 211 bCheck = ((Y.UA.gecko || Y.UA.webkit > 519) ? true : false); 212 213 // TODO: worth refactoring for TOP/LEFT only? 214 while ((parentNode = parentNode.offsetParent)) { 215 xy[0] += parentNode.offsetLeft; 216 xy[1] += parentNode.offsetTop; 217 if (bCheck) { 218 xy = Y_DOM._calcBorders(parentNode, xy); 219 } 220 } 221 222 // account for any scrolled ancestors 223 if (Y_DOM.getStyle(node, POSITION) != FIXED) { 224 parentNode = node; 225 226 while ((parentNode = parentNode.parentNode)) { 227 scrollTop = parentNode.scrollTop; 228 scrollLeft = parentNode.scrollLeft; 229 230 //Firefox does something funky with borders when overflow is not visible. 231 if (Y.UA.gecko && (Y_DOM.getStyle(parentNode, 'overflow') !== 'visible')) { 232 xy = Y_DOM._calcBorders(parentNode, xy); 233 } 234 235 236 if (scrollTop || scrollLeft) { 237 xy[0] -= scrollLeft; 238 xy[1] -= scrollTop; 239 } 240 } 241 xy[0] += Y_DOM.docScrollX(node, doc); 242 xy[1] += Y_DOM.docScrollY(node, doc); 243 244 } else { 245 //Fix FIXED position -- add scrollbars 246 xy[0] += Y_DOM.docScrollX(node, doc); 247 xy[1] += Y_DOM.docScrollY(node, doc); 248 } 249 } else { 250 xy = Y_DOM._getOffset(node); 251 } 252 } 253 254 return xy; 255 }; 256 } 257 }(),// NOTE: Executing for loadtime branching 258 259 /** 260 Gets the width of vertical scrollbars on overflowed containers in the body 261 content. 262 263 @method getScrollbarWidth 264 @return {Number} Pixel width of a scrollbar in the current browser 265 **/ 266 getScrollbarWidth: Y.cached(function () { 267 var doc = Y.config.doc, 268 testNode = doc.createElement('div'), 269 body = doc.getElementsByTagName('body')[0], 270 // 0.1 because cached doesn't support falsy refetch values 271 width = 0.1; 272 273 if (body) { 274 testNode.style.cssText = "position:absolute;visibility:hidden;overflow:scroll;width:20px;"; 275 testNode.appendChild(doc.createElement('p')).style.height = '1px'; 276 body.insertBefore(testNode, body.firstChild); 277 width = testNode.offsetWidth - testNode.clientWidth; 278 279 body.removeChild(testNode); 280 } 281 282 return width; 283 }, null, 0.1), 284 285 /** 286 * Gets the current X position of an element based on page coordinates. 287 * Element must be part of the DOM tree to have page coordinates 288 * (display:none or elements not appended return false). 289 * @method getX 290 * @param element The target element 291 * @return {Number} The X position of the element 292 */ 293 294 getX: function(node) { 295 return Y_DOM.getXY(node)[0]; 296 }, 297 298 /** 299 * Gets the current Y position of an element based on page coordinates. 300 * Element must be part of the DOM tree to have page coordinates 301 * (display:none or elements not appended return false). 302 * @method getY 303 * @param element The target element 304 * @return {Number} The Y position of the element 305 */ 306 307 getY: function(node) { 308 return Y_DOM.getXY(node)[1]; 309 }, 310 311 /** 312 * Set the position of an html element in page coordinates. 313 * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 314 * @method setXY 315 * @param element The target element 316 * @param {Array} xy Contains X & Y values for new position (coordinates are page-based) 317 * @param {Boolean} noRetry By default we try and set the position a second time if the first fails 318 */ 319 setXY: function(node, xy, noRetry) { 320 var setStyle = Y_DOM.setStyle, 321 pos, 322 delta, 323 newXY, 324 currentXY; 325 326 if (node && xy) { 327 pos = Y_DOM.getStyle(node, POSITION); 328 329 delta = Y_DOM._getOffset(node); 330 if (pos == 'static') { // default to relative 331 pos = RELATIVE; 332 setStyle(node, POSITION, pos); 333 } 334 currentXY = Y_DOM.getXY(node); 335 336 if (xy[0] !== null) { 337 setStyle(node, LEFT, xy[0] - currentXY[0] + delta[0] + 'px'); 338 } 339 340 if (xy[1] !== null) { 341 setStyle(node, TOP, xy[1] - currentXY[1] + delta[1] + 'px'); 342 } 343 344 if (!noRetry) { 345 newXY = Y_DOM.getXY(node); 346 if (newXY[0] !== xy[0] || newXY[1] !== xy[1]) { 347 Y_DOM.setXY(node, xy, true); 348 } 349 } 350 351 } else { 352 } 353 }, 354 355 /** 356 * Set the X position of an html element in page coordinates, regardless of how the element is positioned. 357 * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 358 * @method setX 359 * @param element The target element 360 * @param {Number} x The X values for new position (coordinates are page-based) 361 */ 362 setX: function(node, x) { 363 return Y_DOM.setXY(node, [x, null]); 364 }, 365 366 /** 367 * Set the Y position of an html element in page coordinates, regardless of how the element is positioned. 368 * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 369 * @method setY 370 * @param element The target element 371 * @param {Number} y The Y values for new position (coordinates are page-based) 372 */ 373 setY: function(node, y) { 374 return Y_DOM.setXY(node, [null, y]); 375 }, 376 377 /** 378 * @method swapXY 379 * @description Swap the xy position with another node 380 * @param {Node} node The node to swap with 381 * @param {Node} otherNode The other node to swap with 382 * @return {Node} 383 */ 384 swapXY: function(node, otherNode) { 385 var xy = Y_DOM.getXY(node); 386 Y_DOM.setXY(node, Y_DOM.getXY(otherNode)); 387 Y_DOM.setXY(otherNode, xy); 388 }, 389 390 _calcBorders: function(node, xy2) { 391 var t = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_TOP_WIDTH), 10) || 0, 392 l = parseInt(Y_DOM[GET_COMPUTED_STYLE](node, BORDER_LEFT_WIDTH), 10) || 0; 393 if (Y.UA.gecko) { 394 if (RE_TABLE.test(node.tagName)) { 395 t = 0; 396 l = 0; 397 } 398 } 399 xy2[0] += l; 400 xy2[1] += t; 401 return xy2; 402 }, 403 404 _getWinSize: function(node, doc) { 405 doc = doc || (node) ? Y_DOM._getDoc(node) : Y.config.doc; 406 var win = doc.defaultView || doc.parentWindow, 407 mode = doc[COMPAT_MODE], 408 h = win.innerHeight, 409 w = win.innerWidth, 410 root = doc[DOCUMENT_ELEMENT]; 411 412 if ( mode && !Y.UA.opera ) { // IE, Gecko 413 if (mode != 'CSS1Compat') { // Quirks 414 root = doc.body; 415 } 416 h = root.clientHeight; 417 w = root.clientWidth; 418 } 419 return { height: h, width: w }; 420 }, 421 422 _getDocSize: function(node) { 423 var doc = (node) ? Y_DOM._getDoc(node) : Y.config.doc, 424 root = doc[DOCUMENT_ELEMENT]; 425 426 if (doc[COMPAT_MODE] != 'CSS1Compat') { 427 root = doc.body; 428 } 429 430 return { height: root.scrollHeight, width: root.scrollWidth }; 431 } 432 }); 433 434 })(Y); 435 (function(Y) { 436 var TOP = 'top', 437 RIGHT = 'right', 438 BOTTOM = 'bottom', 439 LEFT = 'left', 440 441 getOffsets = function(r1, r2) { 442 var t = Math.max(r1[TOP], r2[TOP]), 443 r = Math.min(r1[RIGHT], r2[RIGHT]), 444 b = Math.min(r1[BOTTOM], r2[BOTTOM]), 445 l = Math.max(r1[LEFT], r2[LEFT]), 446 ret = {}; 447 448 ret[TOP] = t; 449 ret[RIGHT] = r; 450 ret[BOTTOM] = b; 451 ret[LEFT] = l; 452 return ret; 453 }, 454 455 DOM = Y.DOM; 456 457 Y.mix(DOM, { 458 /** 459 * Returns an Object literal containing the following about this element: (top, right, bottom, left) 460 * @for DOM 461 * @method region 462 * @param {HTMLElement} element The DOM element. 463 * @return {Object} Object literal containing the following about this element: (top, right, bottom, left) 464 */ 465 region: function(node) { 466 var xy = DOM.getXY(node), 467 ret = false; 468 469 if (node && xy) { 470 ret = DOM._getRegion( 471 xy[1], // top 472 xy[0] + node.offsetWidth, // right 473 xy[1] + node.offsetHeight, // bottom 474 xy[0] // left 475 ); 476 } 477 478 return ret; 479 }, 480 481 /** 482 * Find the intersect information for the passed nodes. 483 * @method intersect 484 * @for DOM 485 * @param {HTMLElement} element The first element 486 * @param {HTMLElement | Object} element2 The element or region to check the interect with 487 * @param {Object} altRegion An object literal containing the region for the first element if we already have the data (for performance e.g. DragDrop) 488 * @return {Object} Object literal containing the following intersection data: (top, right, bottom, left, area, yoff, xoff, inRegion) 489 */ 490 intersect: function(node, node2, altRegion) { 491 var r = altRegion || DOM.region(node), region = {}, 492 n = node2, 493 off; 494 495 if (n.tagName) { 496 region = DOM.region(n); 497 } else if (Y.Lang.isObject(node2)) { 498 region = node2; 499 } else { 500 return false; 501 } 502 503 off = getOffsets(region, r); 504 return { 505 top: off[TOP], 506 right: off[RIGHT], 507 bottom: off[BOTTOM], 508 left: off[LEFT], 509 area: ((off[BOTTOM] - off[TOP]) * (off[RIGHT] - off[LEFT])), 510 yoff: ((off[BOTTOM] - off[TOP])), 511 xoff: (off[RIGHT] - off[LEFT]), 512 inRegion: DOM.inRegion(node, node2, false, altRegion) 513 }; 514 515 }, 516 /** 517 * Check if any part of this node is in the passed region 518 * @method inRegion 519 * @for DOM 520 * @param {Object} node The node to get the region from 521 * @param {Object} node2 The second node to get the region from or an Object literal of the region 522 * @param {Boolean} all Should all of the node be inside the region 523 * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance e.g. DragDrop) 524 * @return {Boolean} True if in region, false if not. 525 */ 526 inRegion: function(node, node2, all, altRegion) { 527 var region = {}, 528 r = altRegion || DOM.region(node), 529 n = node2, 530 off; 531 532 if (n.tagName) { 533 region = DOM.region(n); 534 } else if (Y.Lang.isObject(node2)) { 535 region = node2; 536 } else { 537 return false; 538 } 539 540 if (all) { 541 return ( 542 r[LEFT] >= region[LEFT] && 543 r[RIGHT] <= region[RIGHT] && 544 r[TOP] >= region[TOP] && 545 r[BOTTOM] <= region[BOTTOM] ); 546 } else { 547 off = getOffsets(region, r); 548 if (off[BOTTOM] >= off[TOP] && off[RIGHT] >= off[LEFT]) { 549 return true; 550 } else { 551 return false; 552 } 553 554 } 555 }, 556 557 /** 558 * Check if any part of this element is in the viewport 559 * @method inViewportRegion 560 * @for DOM 561 * @param {HTMLElement} element The DOM element. 562 * @param {Boolean} all Should all of the node be inside the region 563 * @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance e.g. DragDrop) 564 * @return {Boolean} True if in region, false if not. 565 */ 566 inViewportRegion: function(node, all, altRegion) { 567 return DOM.inRegion(node, DOM.viewportRegion(node), all, altRegion); 568 569 }, 570 571 _getRegion: function(t, r, b, l) { 572 var region = {}; 573 574 region[TOP] = region[1] = t; 575 region[LEFT] = region[0] = l; 576 region[BOTTOM] = b; 577 region[RIGHT] = r; 578 region.width = region[RIGHT] - region[LEFT]; 579 region.height = region[BOTTOM] - region[TOP]; 580 581 return region; 582 }, 583 584 /** 585 * Returns an Object literal containing the following about the visible region of viewport: (top, right, bottom, left) 586 * @method viewportRegion 587 * @for DOM 588 * @return {Object} Object literal containing the following about the visible region of the viewport: (top, right, bottom, left) 589 */ 590 viewportRegion: function(node) { 591 node = node || Y.config.doc.documentElement; 592 var ret = false, 593 scrollX, 594 scrollY; 595 596 if (node) { 597 scrollX = DOM.docScrollX(node); 598 scrollY = DOM.docScrollY(node); 599 600 ret = DOM._getRegion(scrollY, // top 601 DOM.winWidth(node) + scrollX, // right 602 scrollY + DOM.winHeight(node), // bottom 603 scrollX); // left 604 } 605 606 return ret; 607 } 608 }); 609 })(Y); 610 611 612 }, '3.17.2', {"requires": ["dom-base", "dom-style"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |