From aba131d26e1c5f5f2fbd8e4bdc6a072a3e8f83ed Mon Sep 17 00:00:00 2001 From: Alex Dovenmuehle Date: Tue, 15 Feb 2011 20:31:36 -0500 Subject: [PATCH 1/3] Position: Merged offset option into my and at options. Fixes #6981 - Merge offset option into my and at options. --- tests/unit/position/position_core.js | 38 +++- tests/visual/position/position_offset.html | 47 +++++ .../visual/position/position_old_offset.html | 48 +++++ ui/jquery.ui.position.js | 173 +++++++++++++----- 4 files changed, 259 insertions(+), 47 deletions(-) create mode 100644 tests/visual/position/position_offset.html create mode 100644 tests/visual/position/position_old_offset.html diff --git a/tests/unit/position/position_core.js b/tests/unit/position/position_core.js index 643561c2028..367f198733c 100644 --- a/tests/unit/position/position_core.js +++ b/tests/unit/position/position_core.js @@ -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: 54, left: 60 }, 'percentage offsets in at'); + + $('#elx').position({ + my: 'left+30% top-50%', + at: 'left bottom', + of: '#parentx', + collision: 'none' + }); + same($('#elx').offset(), { top: 90, left: 28 }, 'percentage offsets in my'); +}); + +test('offset - deprecated', function() { $('#elx').position({ my: 'left top', at: 'left bottom', @@ -216,7 +250,7 @@ test('offset', function() { collision: 'none' }); same($('#elx').offset(), { top: 70, left: 50 }, 'single value'); - + $('#elx').position({ my: 'left top', at: 'left bottom', diff --git a/tests/visual/position/position_offset.html b/tests/visual/position/position_offset.html new file mode 100644 index 00000000000..22fcc97689e --- /dev/null +++ b/tests/visual/position/position_offset.html @@ -0,0 +1,47 @@ + + + + + Position Visual Test: Default + + + + + + + + + + + +
+
+ + diff --git a/tests/visual/position/position_old_offset.html b/tests/visual/position/position_old_offset.html new file mode 100644 index 00000000000..e3f66fb4a70 --- /dev/null +++ b/tests/visual/position/position_old_offset.html @@ -0,0 +1,48 @@ + + + + + Position Visual Test: Default + + + + + + + + + + + +
+
+ + diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 6f223b42473..b003457c9dc 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -13,6 +13,7 @@ $.ui = $.ui || {}; var horizontalPositions = /left|center|right/, verticalPositions = /top|center|bottom/, + offsetMatch = /([\+\-]\d+)([%]?)/, center = "center", _position = $.fn.position, _offset = $.fn.offset; @@ -28,7 +29,7 @@ $.fn.position = function( options ) { var target = $( options.of ), targetElem = target[0], collision = ( options.collision || "flip" ).split( " " ), - offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ], + offset = [0, 0], targetWidth, targetHeight, basePosition; @@ -52,48 +53,27 @@ $.fn.position = function( options ) { basePosition = target.offset(); } - // force my and at to have valid horizontal and veritcal positions - // if a value is missing or invalid, it will be converted to center - $.each( [ "my", "at" ], function() { - var pos = ( options[this] || "" ).split( " " ); - if ( pos.length === 1) { - pos = horizontalPositions.test( pos[0] ) ? - pos.concat( [center] ) : - verticalPositions.test( pos[0] ) ? - [ center ].concat( pos ) : - [ center, center ]; - } - pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center; - pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center; - options[ this ] = pos; - }); + normalizePositions( options ); // 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" ) { + if ( options.at.horizontal.value === "right" ) { basePosition.left += targetWidth; - } else if ( options.at[0] === center ) { + } else if ( options.at.horizontal.value === center ) { basePosition.left += targetWidth / 2; } - if ( options.at[1] === "bottom" ) { + if ( options.at.vertical.value === "bottom" ) { basePosition.top += targetHeight; - } else if ( options.at[1] === center ) { + } else if ( options.at.vertical.value === center ) { basePosition.top += targetHeight / 2; } - basePosition.left += offset[ 0 ]; - basePosition.top += offset[ 1 ]; + basePosition.left = options.at.horizontal.offset.calculate( basePosition.left ); + basePosition.top = options.at.vertical.offset.calculate( basePosition.top ); return this.each(function() { var elem = $( this ), @@ -108,21 +88,21 @@ $.fn.position = function( options ) { position = $.extend( {}, basePosition ), collisionPosition; - if ( options.my[0] === "right" ) { + if ( options.my.horizontal.value === "right" ) { position.left -= elemWidth; - } else if ( options.my[0] === center ) { + } else if ( options.my.horizontal.value === center ) { position.left -= elemWidth / 2; } - if ( options.my[1] === "bottom" ) { + if ( options.my.vertical.value === "bottom" ) { position.top -= elemHeight; - } else if ( options.my[1] === center ) { + } else if ( options.my.vertical.value === center ) { position.top -= elemHeight / 2; } // prevent fractions (see #5280) - position.left = Math.round( position.left ); - position.top = Math.round( position.top ); + position.left = Math.round( ( position.left - ( options.my.horizontal.offset.calculate( position.left ) - position.left ) ) ); + position.top = Math.round( ( position.top - ( options.my.vertical.offset.calculate( position.top ) - position.top ) ) ); collisionPosition = { left: position.left - marginLeft, @@ -169,20 +149,20 @@ $.ui.position = { flip: { left: function( position, data ) { - if ( data.at[0] === center ) { + if ( data.at.horizontal.value === center ) { return; } var win = $( window ), over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(), - myOffset = data.my[ 0 ] === "left" ? + myOffset = data.my.horizontal.value === "left" ? -data.elemWidth : - data.my[ 0 ] === "right" ? + data.my.horizontal.value === "right" ? data.elemWidth : 0, - atOffset = data.at[ 0 ] === "left" ? + atOffset = data.at.horizontal.value === "left" ? data.targetWidth : -data.targetWidth, - offset = -2 * data.offset[ 0 ]; + offset = -2 * data.at.horizontal.offset.offset; position.left += data.collisionPosition.left < 0 ? myOffset + atOffset + offset : over > 0 ? @@ -190,20 +170,20 @@ $.ui.position = { 0; }, top: function( position, data ) { - if ( data.at[1] === center ) { + if ( data.at.vertical.value === center ) { return; } var win = $( window ), over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(), - myOffset = data.my[ 1 ] === "top" ? + myOffset = data.my.vertical.value === "top" ? -data.elemHeight : - data.my[ 1 ] === "bottom" ? + data.my.vertical.value === "bottom" ? data.elemHeight : 0, - atOffset = data.at[ 1 ] === "top" ? + atOffset = data.at.vertical.value === "top" ? data.targetHeight : -data.targetHeight, - offset = -2 * data.offset[ 1 ]; + offset = -2 * data.at.vertical.offset.offset; position.top += data.collisionPosition.top < 0 ? myOffset + atOffset + offset : over > 0 ? @@ -213,4 +193,107 @@ $.ui.position = { } }; +$.extend ( $.ui.position, ( + + normalizePositions = function( options ) { + + // force my and at to have valid horizontal and veritcal positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + options[ this ] = positionData( options[ this ] ); + }); + }, + + positionData = function( position ) { + + var pos = ( ( position || "" ).split( " " ) ); + var positionData = {}; + + if ( pos.length === 1 ) { + pos = horizontalPositions.test( pos[ 0 ] ) ? + pos.concat( [ center ] ) : + verticalPositions.test( pos[ 0 ] ) ? + [ center ].concat( pos ) : + [ center, center ]; + } + + positionData.horizontal = {}, + positionData.vertical = {}; + + positionData.horizontal.originalValue = horizontalPositions.test( pos[ 0 ] ) ? pos[ 0 ] : center; + positionData.vertical.originalValue = verticalPositions.test( pos[ 1 ] ) ? pos[ 1 ] : center; + + positionData.horizontal.offset = new offsetTranslator( positionData.horizontal.originalValue ); + positionData.vertical.offset = new offsetTranslator( positionData.vertical.originalValue ); + + positionData.horizontal.value = positionData.horizontal.originalValue.match( horizontalPositions )[ 0 ]; + positionData.vertical.value = positionData.vertical.originalValue.match( verticalPositions )[ 0 ]; + + return positionData; + }, + + offsetTranslator = function( option ) { + + if ( !option ) { + return 0; + } + + var matched = option.match(offsetMatch); + this.offset = 0, + this.percent = false; + + if ( matched && matched.length >= 2 ) { + this.offset = matched[ 1 ] !== undefined + ? parseInt( matched[ 1 ], 10 ) + : 0, + this.percent = matched[ 2 ] !== ""; + } + + this.calculate = function( original ) { + var result; + + if ( typeof original !== "number" ) { + return original; + } + + if ( this.percent ) { + result = original * ( 1 + ( this.offset / 100 ) ); + } + else { + result = original + this.offset; + } + + return Math.floor( result ); + } + } +) +); + +// DEPRECATED +if ( $.uiBackCompat !== false ) { + //offset option + (function( $, prototype ) { + + var _normalizePositions = normalizePositions; + normalizePositions = function( options ) { + _normalizePositions.call( this, options ); + + if ( options.offset ) { + + offset = options.offset ? options.offset.split( " " ) : [ 0, 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; + + options.at.horizontal.offset.offset += offset[ 0 ]; + options.at.vertical.offset.offset += offset[ 1 ]; + } + } + }( jQuery, jQuery.ui.position.prototype ) ); +} + }( jQuery )); From 5411db6ecfcbb1f903d683b37b32c1655038256d Mon Sep 17 00:00:00 2001 From: Alex Dovenmuehle Date: Sun, 27 Feb 2011 00:29:45 -0500 Subject: [PATCH 2/3] Position: Clean up old offset and style changes. --- ui/jquery.ui.position.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index b003457c9dc..0d8a5ae84e5 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -29,7 +29,6 @@ $.fn.position = function( options ) { var target = $( options.of ), targetElem = target[0], collision = ( options.collision || "flip" ).split( " " ), - offset = [0, 0], targetWidth, targetHeight, basePosition; @@ -283,11 +282,11 @@ if ( $.uiBackCompat !== false ) { offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ], // normalize offset option - offset[ 0 ] = parseInt( offset[0], 10 ) || 0; + offset[ 0 ] = parseInt( offset[ 0 ], 10 ) || 0; if ( offset.length === 1 ) { offset[ 1 ] = offset[ 0 ]; } - offset[ 1 ] = parseInt( offset[1], 10 ) || 0; + offset[ 1 ] = parseInt( offset[ 1 ], 10 ) || 0; options.at.horizontal.offset.offset += offset[ 0 ]; options.at.vertical.offset.offset += offset[ 1 ]; From e16a68362c5fc8389ee848e59d498c83c8bf8894 Mon Sep 17 00:00:00 2001 From: Alex Dovenmuehle Date: Sun, 27 Feb 2011 00:35:23 -0500 Subject: [PATCH 3/3] Position: Deleted originalValue from positionData object because it's unnecessary. --- ui/jquery.ui.position.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 0d8a5ae84e5..ce948125689 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -219,14 +219,14 @@ $.extend ( $.ui.position, ( positionData.horizontal = {}, positionData.vertical = {}; - positionData.horizontal.originalValue = horizontalPositions.test( pos[ 0 ] ) ? pos[ 0 ] : center; - positionData.vertical.originalValue = verticalPositions.test( pos[ 1 ] ) ? pos[ 1 ] : center; + pos[ 0 ] = horizontalPositions.test( pos[ 0 ] ) ? pos[ 0 ] : center; + pos[ 1 ] = verticalPositions.test( pos[ 1 ] ) ? pos[ 1 ] : center; - positionData.horizontal.offset = new offsetTranslator( positionData.horizontal.originalValue ); - positionData.vertical.offset = new offsetTranslator( positionData.vertical.originalValue ); + positionData.horizontal.offset = new offsetTranslator( pos[ 0 ] ); + positionData.vertical.offset = new offsetTranslator( pos[ 1 ] ); - positionData.horizontal.value = positionData.horizontal.originalValue.match( horizontalPositions )[ 0 ]; - positionData.vertical.value = positionData.vertical.originalValue.match( verticalPositions )[ 0 ]; + positionData.horizontal.value = pos[ 0 ].match( horizontalPositions )[ 0 ]; + positionData.vertical.value = pos[ 1 ].match( verticalPositions )[ 0 ]; return positionData; },