[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/resources/lib/jquery.ui/ -> jquery.ui.position.js (source)

   1  /*!
   2   * jQuery UI Position 1.9.2
   3   * http://jqueryui.com
   4   *
   5   * Copyright 2012 jQuery Foundation and other contributors
   6   * Released under the MIT license.
   7   * http://jquery.org/license
   8   *
   9   * http://api.jqueryui.com/position/
  10   */
  11  (function( $, undefined ) {
  12  
  13  $.ui = $.ui || {};
  14  
  15  var cachedScrollbarWidth,
  16      max = Math.max,
  17      abs = Math.abs,
  18      round = Math.round,
  19      rhorizontal = /left|center|right/,
  20      rvertical = /top|center|bottom/,
  21      roffset = /[\+\-]\d+%?/,
  22      rposition = /^\w+/,
  23      rpercent = /%$/,
  24      _position = $.fn.position;
  25  
  26  function getOffsets( offsets, width, height ) {
  27      return [
  28          parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
  29          parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
  30      ];
  31  }
  32  function parseCss( element, property ) {
  33      return parseInt( $.css( element, property ), 10 ) || 0;
  34  }
  35  
  36  $.position = {
  37      scrollbarWidth: function() {
  38          if ( cachedScrollbarWidth !== undefined ) {
  39              return cachedScrollbarWidth;
  40          }
  41          var w1, w2,
  42              div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
  43              innerDiv = div.children()[0];
  44  
  45          $( "body" ).append( div );
  46          w1 = innerDiv.offsetWidth;
  47          div.css( "overflow", "scroll" );
  48  
  49          w2 = innerDiv.offsetWidth;
  50  
  51          if ( w1 === w2 ) {
  52              w2 = div[0].clientWidth;
  53          }
  54  
  55          div.remove();
  56  
  57          return (cachedScrollbarWidth = w1 - w2);
  58      },
  59      getScrollInfo: function( within ) {
  60          var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
  61              overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
  62              hasOverflowX = overflowX === "scroll" ||
  63                  ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
  64              hasOverflowY = overflowY === "scroll" ||
  65                  ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
  66          return {
  67              width: hasOverflowX ? $.position.scrollbarWidth() : 0,
  68              height: hasOverflowY ? $.position.scrollbarWidth() : 0
  69          };
  70      },
  71      getWithinInfo: function( element ) {
  72          var withinElement = $( element || window ),
  73              isWindow = $.isWindow( withinElement[0] );
  74          return {
  75              element: withinElement,
  76              isWindow: isWindow,
  77              offset: withinElement.offset() || { left: 0, top: 0 },
  78              scrollLeft: withinElement.scrollLeft(),
  79              scrollTop: withinElement.scrollTop(),
  80              width: isWindow ? withinElement.width() : withinElement.outerWidth(),
  81              height: isWindow ? withinElement.height() : withinElement.outerHeight()
  82          };
  83      }
  84  };
  85  
  86  $.fn.position = function( options ) {
  87      if ( !options || !options.of ) {
  88          return _position.apply( this, arguments );
  89      }
  90  
  91      // make a copy, we don't want to modify arguments
  92      options = $.extend( {}, options );
  93  
  94      var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
  95          target = $( options.of ),
  96          within = $.position.getWithinInfo( options.within ),
  97          scrollInfo = $.position.getScrollInfo( within ),
  98          targetElem = target[0],
  99          collision = ( options.collision || "flip" ).split( " " ),
 100          offsets = {};
 101  
 102      if ( targetElem.nodeType === 9 ) {
 103          targetWidth = target.width();
 104          targetHeight = target.height();
 105          targetOffset = { top: 0, left: 0 };
 106      } else if ( $.isWindow( targetElem ) ) {
 107          targetWidth = target.width();
 108          targetHeight = target.height();
 109          targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
 110      } else if ( targetElem.preventDefault ) {
 111          // force left top to allow flipping
 112          options.at = "left top";
 113          targetWidth = targetHeight = 0;
 114          targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
 115      } else {
 116          targetWidth = target.outerWidth();
 117          targetHeight = target.outerHeight();
 118          targetOffset = target.offset();
 119      }
 120      // clone to reuse original targetOffset later
 121      basePosition = $.extend( {}, targetOffset );
 122  
 123      // force my and at to have valid horizontal and vertical positions
 124      // if a value is missing or invalid, it will be converted to center
 125      $.each( [ "my", "at" ], function() {
 126          var pos = ( options[ this ] || "" ).split( " " ),
 127              horizontalOffset,
 128              verticalOffset;
 129  
 130          if ( pos.length === 1) {
 131              pos = rhorizontal.test( pos[ 0 ] ) ?
 132                  pos.concat( [ "center" ] ) :
 133                  rvertical.test( pos[ 0 ] ) ?
 134                      [ "center" ].concat( pos ) :
 135                      [ "center", "center" ];
 136          }
 137          pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
 138          pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
 139  
 140          // calculate offsets
 141          horizontalOffset = roffset.exec( pos[ 0 ] );
 142          verticalOffset = roffset.exec( pos[ 1 ] );
 143          offsets[ this ] = [
 144              horizontalOffset ? horizontalOffset[ 0 ] : 0,
 145              verticalOffset ? verticalOffset[ 0 ] : 0
 146          ];
 147  
 148          // reduce to just the positions without the offsets
 149          options[ this ] = [
 150              rposition.exec( pos[ 0 ] )[ 0 ],
 151              rposition.exec( pos[ 1 ] )[ 0 ]
 152          ];
 153      });
 154  
 155      // normalize collision option
 156      if ( collision.length === 1 ) {
 157          collision[ 1 ] = collision[ 0 ];
 158      }
 159  
 160      if ( options.at[ 0 ] === "right" ) {
 161          basePosition.left += targetWidth;
 162      } else if ( options.at[ 0 ] === "center" ) {
 163          basePosition.left += targetWidth / 2;
 164      }
 165  
 166      if ( options.at[ 1 ] === "bottom" ) {
 167          basePosition.top += targetHeight;
 168      } else if ( options.at[ 1 ] === "center" ) {
 169          basePosition.top += targetHeight / 2;
 170      }
 171  
 172      atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
 173      basePosition.left += atOffset[ 0 ];
 174      basePosition.top += atOffset[ 1 ];
 175  
 176      return this.each(function() {
 177          var collisionPosition, using,
 178              elem = $( this ),
 179              elemWidth = elem.outerWidth(),
 180              elemHeight = elem.outerHeight(),
 181              marginLeft = parseCss( this, "marginLeft" ),
 182              marginTop = parseCss( this, "marginTop" ),
 183              collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
 184              collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
 185              position = $.extend( {}, basePosition ),
 186              myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
 187  
 188          if ( options.my[ 0 ] === "right" ) {
 189              position.left -= elemWidth;
 190          } else if ( options.my[ 0 ] === "center" ) {
 191              position.left -= elemWidth / 2;
 192          }
 193  
 194          if ( options.my[ 1 ] === "bottom" ) {
 195              position.top -= elemHeight;
 196          } else if ( options.my[ 1 ] === "center" ) {
 197              position.top -= elemHeight / 2;
 198          }
 199  
 200          position.left += myOffset[ 0 ];
 201          position.top += myOffset[ 1 ];
 202  
 203          // if the browser doesn't support fractions, then round for consistent results
 204          if ( !$.support.offsetFractions ) {
 205              position.left = round( position.left );
 206              position.top = round( position.top );
 207          }
 208  
 209          collisionPosition = {
 210              marginLeft: marginLeft,
 211              marginTop: marginTop
 212          };
 213  
 214          $.each( [ "left", "top" ], function( i, dir ) {
 215              if ( $.ui.position[ collision[ i ] ] ) {
 216                  $.ui.position[ collision[ i ] ][ dir ]( position, {
 217                      targetWidth: targetWidth,
 218                      targetHeight: targetHeight,
 219                      elemWidth: elemWidth,
 220                      elemHeight: elemHeight,
 221                      collisionPosition: collisionPosition,
 222                      collisionWidth: collisionWidth,
 223                      collisionHeight: collisionHeight,
 224                      offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
 225                      my: options.my,
 226                      at: options.at,
 227                      within: within,
 228                      elem : elem
 229                  });
 230              }
 231          });
 232  
 233          if ( $.fn.bgiframe ) {
 234              elem.bgiframe();
 235          }
 236  
 237          if ( options.using ) {
 238              // adds feedback as second argument to using callback, if present
 239              using = function( props ) {
 240                  var left = targetOffset.left - position.left,
 241                      right = left + targetWidth - elemWidth,
 242                      top = targetOffset.top - position.top,
 243                      bottom = top + targetHeight - elemHeight,
 244                      feedback = {
 245                          target: {
 246                              element: target,
 247                              left: targetOffset.left,
 248                              top: targetOffset.top,
 249                              width: targetWidth,
 250                              height: targetHeight
 251                          },
 252                          element: {
 253                              element: elem,
 254                              left: position.left,
 255                              top: position.top,
 256                              width: elemWidth,
 257                              height: elemHeight
 258                          },
 259                          horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
 260                          vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
 261                      };
 262                  if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
 263                      feedback.horizontal = "center";
 264                  }
 265                  if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
 266                      feedback.vertical = "middle";
 267                  }
 268                  if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
 269                      feedback.important = "horizontal";
 270                  } else {
 271                      feedback.important = "vertical";
 272                  }
 273                  options.using.call( this, props, feedback );
 274              };
 275          }
 276  
 277          elem.offset( $.extend( position, { using: using } ) );
 278      });
 279  };
 280  
 281  $.ui.position = {
 282      fit: {
 283          left: function( position, data ) {
 284              var within = data.within,
 285                  withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
 286                  outerWidth = within.width,
 287                  collisionPosLeft = position.left - data.collisionPosition.marginLeft,
 288                  overLeft = withinOffset - collisionPosLeft,
 289                  overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
 290                  newOverRight;
 291  
 292              // element is wider than within
 293              if ( data.collisionWidth > outerWidth ) {
 294                  // element is initially over the left side of within
 295                  if ( overLeft > 0 && overRight <= 0 ) {
 296                      newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
 297                      position.left += overLeft - newOverRight;
 298                  // element is initially over right side of within
 299                  } else if ( overRight > 0 && overLeft <= 0 ) {
 300                      position.left = withinOffset;
 301                  // element is initially over both left and right sides of within
 302                  } else {
 303                      if ( overLeft > overRight ) {
 304                          position.left = withinOffset + outerWidth - data.collisionWidth;
 305                      } else {
 306                          position.left = withinOffset;
 307                      }
 308                  }
 309              // too far left -> align with left edge
 310              } else if ( overLeft > 0 ) {
 311                  position.left += overLeft;
 312              // too far right -> align with right edge
 313              } else if ( overRight > 0 ) {
 314                  position.left -= overRight;
 315              // adjust based on position and margin
 316              } else {
 317                  position.left = max( position.left - collisionPosLeft, position.left );
 318              }
 319          },
 320          top: function( position, data ) {
 321              var within = data.within,
 322                  withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
 323                  outerHeight = data.within.height,
 324                  collisionPosTop = position.top - data.collisionPosition.marginTop,
 325                  overTop = withinOffset - collisionPosTop,
 326                  overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
 327                  newOverBottom;
 328  
 329              // element is taller than within
 330              if ( data.collisionHeight > outerHeight ) {
 331                  // element is initially over the top of within
 332                  if ( overTop > 0 && overBottom <= 0 ) {
 333                      newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
 334                      position.top += overTop - newOverBottom;
 335                  // element is initially over bottom of within
 336                  } else if ( overBottom > 0 && overTop <= 0 ) {
 337                      position.top = withinOffset;
 338                  // element is initially over both top and bottom of within
 339                  } else {
 340                      if ( overTop > overBottom ) {
 341                          position.top = withinOffset + outerHeight - data.collisionHeight;
 342                      } else {
 343                          position.top = withinOffset;
 344                      }
 345                  }
 346              // too far up -> align with top
 347              } else if ( overTop > 0 ) {
 348                  position.top += overTop;
 349              // too far down -> align with bottom edge
 350              } else if ( overBottom > 0 ) {
 351                  position.top -= overBottom;
 352              // adjust based on position and margin
 353              } else {
 354                  position.top = max( position.top - collisionPosTop, position.top );
 355              }
 356          }
 357      },
 358      flip: {
 359          left: function( position, data ) {
 360              var within = data.within,
 361                  withinOffset = within.offset.left + within.scrollLeft,
 362                  outerWidth = within.width,
 363                  offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
 364                  collisionPosLeft = position.left - data.collisionPosition.marginLeft,
 365                  overLeft = collisionPosLeft - offsetLeft,
 366                  overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
 367                  myOffset = data.my[ 0 ] === "left" ?
 368                      -data.elemWidth :
 369                      data.my[ 0 ] === "right" ?
 370                          data.elemWidth :
 371                          0,
 372                  atOffset = data.at[ 0 ] === "left" ?
 373                      data.targetWidth :
 374                      data.at[ 0 ] === "right" ?
 375                          -data.targetWidth :
 376                          0,
 377                  offset = -2 * data.offset[ 0 ],
 378                  newOverRight,
 379                  newOverLeft;
 380  
 381              if ( overLeft < 0 ) {
 382                  newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
 383                  if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
 384                      position.left += myOffset + atOffset + offset;
 385                  }
 386              }
 387              else if ( overRight > 0 ) {
 388                  newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
 389                  if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
 390                      position.left += myOffset + atOffset + offset;
 391                  }
 392              }
 393          },
 394          top: function( position, data ) {
 395              var within = data.within,
 396                  withinOffset = within.offset.top + within.scrollTop,
 397                  outerHeight = within.height,
 398                  offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
 399                  collisionPosTop = position.top - data.collisionPosition.marginTop,
 400                  overTop = collisionPosTop - offsetTop,
 401                  overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
 402                  top = data.my[ 1 ] === "top",
 403                  myOffset = top ?
 404                      -data.elemHeight :
 405                      data.my[ 1 ] === "bottom" ?
 406                          data.elemHeight :
 407                          0,
 408                  atOffset = data.at[ 1 ] === "top" ?
 409                      data.targetHeight :
 410                      data.at[ 1 ] === "bottom" ?
 411                          -data.targetHeight :
 412                          0,
 413                  offset = -2 * data.offset[ 1 ],
 414                  newOverTop,
 415                  newOverBottom;
 416              if ( overTop < 0 ) {
 417                  newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
 418                  if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
 419                      position.top += myOffset + atOffset + offset;
 420                  }
 421              }
 422              else if ( overBottom > 0 ) {
 423                  newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
 424                  if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
 425                      position.top += myOffset + atOffset + offset;
 426                  }
 427              }
 428          }
 429      },
 430      flipfit: {
 431          left: function() {
 432              $.ui.position.flip.left.apply( this, arguments );
 433              $.ui.position.fit.left.apply( this, arguments );
 434          },
 435          top: function() {
 436              $.ui.position.flip.top.apply( this, arguments );
 437              $.ui.position.fit.top.apply( this, arguments );
 438          }
 439      }
 440  };
 441  
 442  // fraction support test
 443  (function () {
 444      var testElement, testElementParent, testElementStyle, offsetLeft, i,
 445          body = document.getElementsByTagName( "body" )[ 0 ],
 446          div = document.createElement( "div" );
 447  
 448      //Create a "fake body" for testing based on method used in jQuery.support
 449      testElement = document.createElement( body ? "div" : "body" );
 450      testElementStyle = {
 451          visibility: "hidden",
 452          width: 0,
 453          height: 0,
 454          border: 0,
 455          margin: 0,
 456          background: "none"
 457      };
 458      if ( body ) {
 459          $.extend( testElementStyle, {
 460              position: "absolute",
 461              left: "-1000px",
 462              top: "-1000px"
 463          });
 464      }
 465      for ( i in testElementStyle ) {
 466          testElement.style[ i ] = testElementStyle[ i ];
 467      }
 468      testElement.appendChild( div );
 469      testElementParent = body || document.documentElement;
 470      testElementParent.insertBefore( testElement, testElementParent.firstChild );
 471  
 472      div.style.cssText = "position: absolute; left: 10.7432222px;";
 473  
 474      offsetLeft = $( div ).offset().left;
 475      $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
 476  
 477      testElement.innerHTML = "";
 478      testElementParent.removeChild( testElement );
 479  })();
 480  
 481  // DEPRECATED
 482  if ( $.uiBackCompat !== false ) {
 483      // offset option
 484      (function( $ ) {
 485          var _position = $.fn.position;
 486          $.fn.position = function( options ) {
 487              if ( !options || !options.offset ) {
 488                  return _position.call( this, options );
 489              }
 490              var offset = options.offset.split( " " ),
 491                  at = options.at.split( " " );
 492              if ( offset.length === 1 ) {
 493                  offset[ 1 ] = offset[ 0 ];
 494              }
 495              if ( /^\d/.test( offset[ 0 ] ) ) {
 496                  offset[ 0 ] = "+" + offset[ 0 ];
 497              }
 498              if ( /^\d/.test( offset[ 1 ] ) ) {
 499                  offset[ 1 ] = "+" + offset[ 1 ];
 500              }
 501              if ( at.length === 1 ) {
 502                  if ( /left|center|right/.test( at[ 0 ] ) ) {
 503                      at[ 1 ] = "center";
 504                  } else {
 505                      at[ 1 ] = at[ 0 ];
 506                      at[ 0 ] = "center";
 507                  }
 508              }
 509              return _position.call( this, $.extend( options, {
 510                  at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
 511                  offset: undefined
 512              } ) );
 513          };
 514      }( jQuery ) );
 515  }
 516  
 517  }( jQuery ) );


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1