Skip to content

Commit

Permalink
Position: Merged offset option into my and at options and added suppo…
Browse files Browse the repository at this point in the history
…rt for percentage-based offsets. Fixes #6981 - Position: Merge offset option into my and at options. Fixes #7028 - Position: Allow percent-based offsets.
  • Loading branch information
scottgonzalez committed Mar 22, 2011
1 parent d4dadd1 commit 6f051d5
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 18 deletions.
6 changes: 2 additions & 4 deletions demos/position/cycler.html
Expand Up @@ -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
});
}
Expand Down
36 changes: 35 additions & 1 deletion tests/unit/position/position_core.js
Expand Up @@ -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',
Expand Down
90 changes: 77 additions & 13 deletions ui/jquery.ui.position.js
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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] ) :
Expand All @@ -64,21 +71,27 @@ $.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
if ( collision.length === 1 ) {
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 ) {
Expand All @@ -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 ),
Expand All @@ -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" ) {
Expand All @@ -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 );
Expand All @@ -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
});
Expand Down Expand Up @@ -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 ));

0 comments on commit 6f051d5

Please sign in to comment.