jQuery UI 1.10 has already been released, and 1.11 is on the horizon (1.9 is marked "legacy" as of writing). 1.10 drops the compatibility layer for 1.8 API. So, users should definitely be encouraged to upgrade their code to move away from the deprecated 1.8 APIs. However, to take it one step at a time, this commit upgrades us to 1.9 first. That way we're at least not using an unsupported code base anymore, while at the same time not rolling out breaking changes. jQuery UI has redesigned many of its APIs[1], but compatibility with the jQuery UI 1.8 API is maintained throughout 1.9.x. * Base theme is now called "Smoothness". * Sorting the entries in Resources.php alphabetically to make it easier to ensure all files are listed when comparing them side-by-side. * Update dependencies to match the "Depends:" header inside the javascript files. * In jQuery UI 1.9, effect files were renamed to match the jquery.ui.*.js naming pattern. * New modules: - jquery.ui.menu - jquery.ui.spinner - jquery.ui.tooltip * Release notes: - http://blog.jqueryui.com/2012/10/jquery-ui-1-9-0/ - http://jqueryui.com/upgrade-guide/1.9/ - http://jqueryui.com/changelog/1.9.0/ - http://blog.jqueryui.com/2012/10/jquery-ui-1-9-1/ - http://jqueryui.com/changelog/1.9.1/ - http://blog.jqueryui.com/2012/11/jquery-ui-1-9-2/ [1] http://blog.jqueryui.com/2011/03/api-redesigns-the-past-present-and-future/ Bug: 47076 Change-Id: I0e10b42fb7c25b9d4704719f21c44c08f36ddfa7
517 lines
16 KiB
JavaScript
517 lines
16 KiB
JavaScript
/*!
|
|
* jQuery UI Position 1.9.2
|
|
* http://jqueryui.com
|
|
*
|
|
* Copyright 2012 jQuery Foundation and other contributors
|
|
* Released under the MIT license.
|
|
* http://jquery.org/license
|
|
*
|
|
* http://api.jqueryui.com/position/
|
|
*/
|
|
(function( $, undefined ) {
|
|
|
|
$.ui = $.ui || {};
|
|
|
|
var cachedScrollbarWidth,
|
|
max = Math.max,
|
|
abs = Math.abs,
|
|
round = Math.round,
|
|
rhorizontal = /left|center|right/,
|
|
rvertical = /top|center|bottom/,
|
|
roffset = /[\+\-]\d+%?/,
|
|
rposition = /^\w+/,
|
|
rpercent = /%$/,
|
|
_position = $.fn.position;
|
|
|
|
function getOffsets( offsets, width, height ) {
|
|
return [
|
|
parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
|
|
parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
|
|
];
|
|
}
|
|
function parseCss( element, property ) {
|
|
return parseInt( $.css( element, property ), 10 ) || 0;
|
|
}
|
|
|
|
$.position = {
|
|
scrollbarWidth: function() {
|
|
if ( cachedScrollbarWidth !== undefined ) {
|
|
return cachedScrollbarWidth;
|
|
}
|
|
var w1, w2,
|
|
div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
|
|
innerDiv = div.children()[0];
|
|
|
|
$( "body" ).append( div );
|
|
w1 = innerDiv.offsetWidth;
|
|
div.css( "overflow", "scroll" );
|
|
|
|
w2 = innerDiv.offsetWidth;
|
|
|
|
if ( w1 === w2 ) {
|
|
w2 = div[0].clientWidth;
|
|
}
|
|
|
|
div.remove();
|
|
|
|
return (cachedScrollbarWidth = w1 - w2);
|
|
},
|
|
getScrollInfo: function( within ) {
|
|
var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
|
|
overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
|
|
hasOverflowX = overflowX === "scroll" ||
|
|
( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
|
|
hasOverflowY = overflowY === "scroll" ||
|
|
( overflowY === "auto" && within.height < within.element[0].scrollHeight );
|
|
return {
|
|
width: hasOverflowX ? $.position.scrollbarWidth() : 0,
|
|
height: hasOverflowY ? $.position.scrollbarWidth() : 0
|
|
};
|
|
},
|
|
getWithinInfo: function( element ) {
|
|
var withinElement = $( element || window ),
|
|
isWindow = $.isWindow( withinElement[0] );
|
|
return {
|
|
element: withinElement,
|
|
isWindow: isWindow,
|
|
offset: withinElement.offset() || { left: 0, top: 0 },
|
|
scrollLeft: withinElement.scrollLeft(),
|
|
scrollTop: withinElement.scrollTop(),
|
|
width: isWindow ? withinElement.width() : withinElement.outerWidth(),
|
|
height: isWindow ? withinElement.height() : withinElement.outerHeight()
|
|
};
|
|
}
|
|
};
|
|
|
|
$.fn.position = function( options ) {
|
|
if ( !options || !options.of ) {
|
|
return _position.apply( this, arguments );
|
|
}
|
|
|
|
// make a copy, we don't want to modify arguments
|
|
options = $.extend( {}, options );
|
|
|
|
var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
|
|
target = $( options.of ),
|
|
within = $.position.getWithinInfo( options.within ),
|
|
scrollInfo = $.position.getScrollInfo( within ),
|
|
targetElem = target[0],
|
|
collision = ( options.collision || "flip" ).split( " " ),
|
|
offsets = {};
|
|
|
|
if ( targetElem.nodeType === 9 ) {
|
|
targetWidth = target.width();
|
|
targetHeight = target.height();
|
|
targetOffset = { top: 0, left: 0 };
|
|
} else if ( $.isWindow( targetElem ) ) {
|
|
targetWidth = target.width();
|
|
targetHeight = target.height();
|
|
targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
|
|
} else if ( targetElem.preventDefault ) {
|
|
// force left top to allow flipping
|
|
options.at = "left top";
|
|
targetWidth = targetHeight = 0;
|
|
targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
|
|
} else {
|
|
targetWidth = target.outerWidth();
|
|
targetHeight = target.outerHeight();
|
|
targetOffset = target.offset();
|
|
}
|
|
// clone to reuse original targetOffset later
|
|
basePosition = $.extend( {}, targetOffset );
|
|
|
|
// force my and at to have valid horizontal and vertical positions
|
|
// if a value is missing or invalid, it will be converted to center
|
|
$.each( [ "my", "at" ], function() {
|
|
var pos = ( options[ this ] || "" ).split( " " ),
|
|
horizontalOffset,
|
|
verticalOffset;
|
|
|
|
if ( pos.length === 1) {
|
|
pos = rhorizontal.test( pos[ 0 ] ) ?
|
|
pos.concat( [ "center" ] ) :
|
|
rvertical.test( pos[ 0 ] ) ?
|
|
[ "center" ].concat( pos ) :
|
|
[ "center", "center" ];
|
|
}
|
|
pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
|
|
pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
|
|
|
|
// calculate offsets
|
|
horizontalOffset = roffset.exec( pos[ 0 ] );
|
|
verticalOffset = roffset.exec( pos[ 1 ] );
|
|
offsets[ this ] = [
|
|
horizontalOffset ? horizontalOffset[ 0 ] : 0,
|
|
verticalOffset ? verticalOffset[ 0 ] : 0
|
|
];
|
|
|
|
// reduce to just the positions without the offsets
|
|
options[ this ] = [
|
|
rposition.exec( pos[ 0 ] )[ 0 ],
|
|
rposition.exec( pos[ 1 ] )[ 0 ]
|
|
];
|
|
});
|
|
|
|
// normalize collision option
|
|
if ( collision.length === 1 ) {
|
|
collision[ 1 ] = collision[ 0 ];
|
|
}
|
|
|
|
if ( options.at[ 0 ] === "right" ) {
|
|
basePosition.left += targetWidth;
|
|
} else if ( options.at[ 0 ] === "center" ) {
|
|
basePosition.left += targetWidth / 2;
|
|
}
|
|
|
|
if ( options.at[ 1 ] === "bottom" ) {
|
|
basePosition.top += targetHeight;
|
|
} else if ( options.at[ 1 ] === "center" ) {
|
|
basePosition.top += targetHeight / 2;
|
|
}
|
|
|
|
atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
|
|
basePosition.left += atOffset[ 0 ];
|
|
basePosition.top += atOffset[ 1 ];
|
|
|
|
return this.each(function() {
|
|
var collisionPosition, using,
|
|
elem = $( this ),
|
|
elemWidth = elem.outerWidth(),
|
|
elemHeight = elem.outerHeight(),
|
|
marginLeft = parseCss( this, "marginLeft" ),
|
|
marginTop = parseCss( this, "marginTop" ),
|
|
collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
|
|
collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
|
|
position = $.extend( {}, basePosition ),
|
|
myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
|
|
|
|
if ( options.my[ 0 ] === "right" ) {
|
|
position.left -= elemWidth;
|
|
} else if ( options.my[ 0 ] === "center" ) {
|
|
position.left -= elemWidth / 2;
|
|
}
|
|
|
|
if ( options.my[ 1 ] === "bottom" ) {
|
|
position.top -= elemHeight;
|
|
} else if ( options.my[ 1 ] === "center" ) {
|
|
position.top -= elemHeight / 2;
|
|
}
|
|
|
|
position.left += myOffset[ 0 ];
|
|
position.top += myOffset[ 1 ];
|
|
|
|
// if the browser doesn't support fractions, then round for consistent results
|
|
if ( !$.support.offsetFractions ) {
|
|
position.left = round( position.left );
|
|
position.top = round( position.top );
|
|
}
|
|
|
|
collisionPosition = {
|
|
marginLeft: marginLeft,
|
|
marginTop: marginTop
|
|
};
|
|
|
|
$.each( [ "left", "top" ], function( i, dir ) {
|
|
if ( $.ui.position[ collision[ i ] ] ) {
|
|
$.ui.position[ collision[ i ] ][ dir ]( position, {
|
|
targetWidth: targetWidth,
|
|
targetHeight: targetHeight,
|
|
elemWidth: elemWidth,
|
|
elemHeight: elemHeight,
|
|
collisionPosition: collisionPosition,
|
|
collisionWidth: collisionWidth,
|
|
collisionHeight: collisionHeight,
|
|
offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
|
|
my: options.my,
|
|
at: options.at,
|
|
within: within,
|
|
elem : elem
|
|
});
|
|
}
|
|
});
|
|
|
|
if ( $.fn.bgiframe ) {
|
|
elem.bgiframe();
|
|
}
|
|
|
|
if ( options.using ) {
|
|
// adds feedback as second argument to using callback, if present
|
|
using = function( props ) {
|
|
var left = targetOffset.left - position.left,
|
|
right = left + targetWidth - elemWidth,
|
|
top = targetOffset.top - position.top,
|
|
bottom = top + targetHeight - elemHeight,
|
|
feedback = {
|
|
target: {
|
|
element: target,
|
|
left: targetOffset.left,
|
|
top: targetOffset.top,
|
|
width: targetWidth,
|
|
height: targetHeight
|
|
},
|
|
element: {
|
|
element: elem,
|
|
left: position.left,
|
|
top: position.top,
|
|
width: elemWidth,
|
|
height: elemHeight
|
|
},
|
|
horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
|
|
vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
|
|
};
|
|
if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
|
|
feedback.horizontal = "center";
|
|
}
|
|
if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
|
|
feedback.vertical = "middle";
|
|
}
|
|
if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
|
|
feedback.important = "horizontal";
|
|
} else {
|
|
feedback.important = "vertical";
|
|
}
|
|
options.using.call( this, props, feedback );
|
|
};
|
|
}
|
|
|
|
elem.offset( $.extend( position, { using: using } ) );
|
|
});
|
|
};
|
|
|
|
$.ui.position = {
|
|
fit: {
|
|
left: function( position, data ) {
|
|
var within = data.within,
|
|
withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
|
|
outerWidth = within.width,
|
|
collisionPosLeft = position.left - data.collisionPosition.marginLeft,
|
|
overLeft = withinOffset - collisionPosLeft,
|
|
overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
|
|
newOverRight;
|
|
|
|
// element is wider than within
|
|
if ( data.collisionWidth > outerWidth ) {
|
|
// element is initially over the left side of within
|
|
if ( overLeft > 0 && overRight <= 0 ) {
|
|
newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
|
|
position.left += overLeft - newOverRight;
|
|
// element is initially over right side of within
|
|
} else if ( overRight > 0 && overLeft <= 0 ) {
|
|
position.left = withinOffset;
|
|
// element is initially over both left and right sides of within
|
|
} else {
|
|
if ( overLeft > overRight ) {
|
|
position.left = withinOffset + outerWidth - data.collisionWidth;
|
|
} else {
|
|
position.left = withinOffset;
|
|
}
|
|
}
|
|
// too far left -> align with left edge
|
|
} else if ( overLeft > 0 ) {
|
|
position.left += overLeft;
|
|
// too far right -> align with right edge
|
|
} else if ( overRight > 0 ) {
|
|
position.left -= overRight;
|
|
// adjust based on position and margin
|
|
} else {
|
|
position.left = max( position.left - collisionPosLeft, position.left );
|
|
}
|
|
},
|
|
top: function( position, data ) {
|
|
var within = data.within,
|
|
withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
|
|
outerHeight = data.within.height,
|
|
collisionPosTop = position.top - data.collisionPosition.marginTop,
|
|
overTop = withinOffset - collisionPosTop,
|
|
overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
|
|
newOverBottom;
|
|
|
|
// element is taller than within
|
|
if ( data.collisionHeight > outerHeight ) {
|
|
// element is initially over the top of within
|
|
if ( overTop > 0 && overBottom <= 0 ) {
|
|
newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
|
|
position.top += overTop - newOverBottom;
|
|
// element is initially over bottom of within
|
|
} else if ( overBottom > 0 && overTop <= 0 ) {
|
|
position.top = withinOffset;
|
|
// element is initially over both top and bottom of within
|
|
} else {
|
|
if ( overTop > overBottom ) {
|
|
position.top = withinOffset + outerHeight - data.collisionHeight;
|
|
} else {
|
|
position.top = withinOffset;
|
|
}
|
|
}
|
|
// too far up -> align with top
|
|
} else if ( overTop > 0 ) {
|
|
position.top += overTop;
|
|
// too far down -> align with bottom edge
|
|
} else if ( overBottom > 0 ) {
|
|
position.top -= overBottom;
|
|
// adjust based on position and margin
|
|
} else {
|
|
position.top = max( position.top - collisionPosTop, position.top );
|
|
}
|
|
}
|
|
},
|
|
flip: {
|
|
left: function( position, data ) {
|
|
var within = data.within,
|
|
withinOffset = within.offset.left + within.scrollLeft,
|
|
outerWidth = within.width,
|
|
offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
|
|
collisionPosLeft = position.left - data.collisionPosition.marginLeft,
|
|
overLeft = collisionPosLeft - offsetLeft,
|
|
overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
|
|
myOffset = data.my[ 0 ] === "left" ?
|
|
-data.elemWidth :
|
|
data.my[ 0 ] === "right" ?
|
|
data.elemWidth :
|
|
0,
|
|
atOffset = data.at[ 0 ] === "left" ?
|
|
data.targetWidth :
|
|
data.at[ 0 ] === "right" ?
|
|
-data.targetWidth :
|
|
0,
|
|
offset = -2 * data.offset[ 0 ],
|
|
newOverRight,
|
|
newOverLeft;
|
|
|
|
if ( overLeft < 0 ) {
|
|
newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
|
|
if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
|
|
position.left += myOffset + atOffset + offset;
|
|
}
|
|
}
|
|
else if ( overRight > 0 ) {
|
|
newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
|
|
if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
|
|
position.left += myOffset + atOffset + offset;
|
|
}
|
|
}
|
|
},
|
|
top: function( position, data ) {
|
|
var within = data.within,
|
|
withinOffset = within.offset.top + within.scrollTop,
|
|
outerHeight = within.height,
|
|
offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
|
|
collisionPosTop = position.top - data.collisionPosition.marginTop,
|
|
overTop = collisionPosTop - offsetTop,
|
|
overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
|
|
top = data.my[ 1 ] === "top",
|
|
myOffset = top ?
|
|
-data.elemHeight :
|
|
data.my[ 1 ] === "bottom" ?
|
|
data.elemHeight :
|
|
0,
|
|
atOffset = data.at[ 1 ] === "top" ?
|
|
data.targetHeight :
|
|
data.at[ 1 ] === "bottom" ?
|
|
-data.targetHeight :
|
|
0,
|
|
offset = -2 * data.offset[ 1 ],
|
|
newOverTop,
|
|
newOverBottom;
|
|
if ( overTop < 0 ) {
|
|
newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
|
|
if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
|
|
position.top += myOffset + atOffset + offset;
|
|
}
|
|
}
|
|
else if ( overBottom > 0 ) {
|
|
newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
|
|
if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
|
|
position.top += myOffset + atOffset + offset;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
flipfit: {
|
|
left: function() {
|
|
$.ui.position.flip.left.apply( this, arguments );
|
|
$.ui.position.fit.left.apply( this, arguments );
|
|
},
|
|
top: function() {
|
|
$.ui.position.flip.top.apply( this, arguments );
|
|
$.ui.position.fit.top.apply( this, arguments );
|
|
}
|
|
}
|
|
};
|
|
|
|
// fraction support test
|
|
(function () {
|
|
var testElement, testElementParent, testElementStyle, offsetLeft, i,
|
|
body = document.getElementsByTagName( "body" )[ 0 ],
|
|
div = document.createElement( "div" );
|
|
|
|
//Create a "fake body" for testing based on method used in jQuery.support
|
|
testElement = document.createElement( body ? "div" : "body" );
|
|
testElementStyle = {
|
|
visibility: "hidden",
|
|
width: 0,
|
|
height: 0,
|
|
border: 0,
|
|
margin: 0,
|
|
background: "none"
|
|
};
|
|
if ( body ) {
|
|
$.extend( testElementStyle, {
|
|
position: "absolute",
|
|
left: "-1000px",
|
|
top: "-1000px"
|
|
});
|
|
}
|
|
for ( i in testElementStyle ) {
|
|
testElement.style[ i ] = testElementStyle[ i ];
|
|
}
|
|
testElement.appendChild( div );
|
|
testElementParent = body || document.documentElement;
|
|
testElementParent.insertBefore( testElement, testElementParent.firstChild );
|
|
|
|
div.style.cssText = "position: absolute; left: 10.7432222px;";
|
|
|
|
offsetLeft = $( div ).offset().left;
|
|
$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
|
|
|
|
testElement.innerHTML = "";
|
|
testElementParent.removeChild( testElement );
|
|
})();
|
|
|
|
// DEPRECATED
|
|
if ( $.uiBackCompat !== false ) {
|
|
// offset option
|
|
(function( $ ) {
|
|
var _position = $.fn.position;
|
|
$.fn.position = function( options ) {
|
|
if ( !options || !options.offset ) {
|
|
return _position.call( this, options );
|
|
}
|
|
var offset = options.offset.split( " " ),
|
|
at = options.at.split( " " );
|
|
if ( offset.length === 1 ) {
|
|
offset[ 1 ] = offset[ 0 ];
|
|
}
|
|
if ( /^\d/.test( offset[ 0 ] ) ) {
|
|
offset[ 0 ] = "+" + offset[ 0 ];
|
|
}
|
|
if ( /^\d/.test( offset[ 1 ] ) ) {
|
|
offset[ 1 ] = "+" + offset[ 1 ];
|
|
}
|
|
if ( at.length === 1 ) {
|
|
if ( /left|center|right/.test( at[ 0 ] ) ) {
|
|
at[ 1 ] = "center";
|
|
} else {
|
|
at[ 1 ] = at[ 0 ];
|
|
at[ 0 ] = "center";
|
|
}
|
|
}
|
|
return _position.call( this, $.extend( options, {
|
|
at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
|
|
offset: undefined
|
|
} ) );
|
|
};
|
|
}( jQuery ) );
|
|
}
|
|
|
|
}( jQuery ) );
|