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