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