[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
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 ) );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |