Position: Merged offset option into my and at options and added support for percentage-based offsets. Fixes #6981 - Position: Merge offset option into my and at options. Fixes #7028 - Position: Allow percent-based offsets.

This commit is contained in:
Scott González
2011-03-22 12:25:25 -04:00
parent d4dadd14c2
commit 6f051d5d6a
3 changed files with 114 additions and 18 deletions

View File

@@ -33,16 +33,14 @@
$.fn.left = function( using ) {
return this.position2({
my: "right middle",
at: "left middle",
offset: "25 0",
at: "left+25 middle",
using: using
});
}
$.fn.right = function( using ) {
return this.position2({
my: "left middle",
at: "right middle",
offset: "-25 0",
at: "right-25 middle",
using: using
});
}

View File

@@ -207,7 +207,41 @@ test('of', function() {
}, 'event - left top, right bottom');
});
test('offset', function() {
test('offsets', function() {
$('#elx').position({
my: 'left top',
at: 'left+10 bottom+10',
of: '#parentx',
collision: 'none'
});
same($('#elx').offset(), { top: 70, left: 50 }, 'offsets in at');
$('#elx').position({
my: 'left+10 top-10',
at: 'left bottom',
of: '#parentx',
collision: 'none'
});
same($('#elx').offset(), { top: 50, left: 50 }, 'offsets in my');
$('#elx').position({
my: 'left top',
at: 'left+50% bottom-10%',
of: '#parentx',
collision: 'none'
});
same($('#elx').offset(), { top: 58, left: 50 }, 'percentage offsets in at');
$('#elx').position({
my: 'left-30% top+50%',
at: 'left bottom',
of: '#parentx',
collision: 'none'
});
same($('#elx').offset(), { top: 65, left: 37 }, 'percentage offsets in my');
});
test('offset - deprecated', function() {
$('#elx').position({
my: 'left top',
at: 'left bottom',

View File

@@ -13,6 +13,9 @@ $.ui = $.ui || {};
var horizontalPositions = /left|center|right/,
verticalPositions = /top|center|bottom/,
roffset = /[+-]\d+%?/,
rposition = /^\w+/,
rpercent = /%$/,
center = "center",
_position = $.fn.position;
@@ -27,7 +30,8 @@ $.fn.position = function( options ) {
var target = $( options.of ),
targetElem = target[0],
collision = ( options.collision || "flip" ).split( " " ),
offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
offsets = {},
atOffset,
targetWidth,
targetHeight,
basePosition;
@@ -54,7 +58,10 @@ $.fn.position = function( options ) {
// 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( " " );
var pos = ( options[this] || "" ).split( " " ),
horizontalOffset,
verticalOffset;
if ( pos.length === 1) {
pos = horizontalPositions.test( pos[0] ) ?
pos.concat( [center] ) :
@@ -64,7 +71,20 @@ $.fn.position = function( options ) {
}
pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
options[ this ] = pos;
// 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
@@ -72,13 +92,6 @@ $.fn.position = function( options ) {
collision[ 1 ] = collision[ 0 ];
}
// normalize offset option
offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
if ( offset.length === 1 ) {
offset[ 1 ] = offset[ 0 ];
}
offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
if ( options.at[0] === "right" ) {
basePosition.left += targetWidth;
} else if ( options.at[0] === center ) {
@@ -91,8 +104,14 @@ $.fn.position = function( options ) {
basePosition.top += targetHeight / 2;
}
basePosition.left += offset[ 0 ];
basePosition.top += offset[ 1 ];
atOffset = [
parseInt( offsets.at[ 0 ], 10 ) *
( rpercent.test( offsets.at[ 0 ] ) ? targetWidth / 100 : 1 ),
parseInt( offsets.at[ 1 ], 10 ) *
( rpercent.test( offsets.at[ 1 ] ) ? targetHeight / 100 : 1 )
];
basePosition.left += atOffset[ 0 ],
basePosition.top += atOffset[ 1 ];
return this.each(function() {
var elem = $( this ),
@@ -105,6 +124,12 @@ $.fn.position = function( options ) {
collisionHeight = elemHeight + marginTop +
( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
position = $.extend( {}, basePosition ),
myOffset = [
parseInt( offsets.my[ 0 ], 10 ) *
( rpercent.test( offsets.my[ 0 ] ) ? elem.outerWidth() / 100 : 1 ),
parseInt( offsets.my[ 1 ], 10 ) *
( rpercent.test( offsets.my[ 1 ] ) ? elem.outerHeight() / 100 : 1 )
],
collisionPosition;
if ( options.my[0] === "right" ) {
@@ -119,6 +144,9 @@ $.fn.position = function( options ) {
position.top -= elemHeight / 2;
}
position.left += myOffset[ 0 ];
position.top += myOffset[ 1 ];
// prevent fractions (see #5280)
position.left = Math.round( position.left );
position.top = Math.round( position.top );
@@ -138,7 +166,7 @@ $.fn.position = function( options ) {
collisionPosition: collisionPosition,
collisionWidth: collisionWidth,
collisionHeight: collisionHeight,
offset: offset,
offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
my: options.my,
at: options.at
});
@@ -212,4 +240,40 @@ $.ui.position = {
}
};
// DEPRECATED
if ( $.uiBackCompat !== false ) {
// offset option
(function( $ ) {
var _position = $.fn.position;
$.fn.position = function( options ) {
if ( !options || !( "offset" in options ) ) {
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 ));