[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/dom-screen/ -> dom-screen-debug.js (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1