From 479530bb61f3c40ef9360613a0a84baf1a14b87b Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Tue, 10 Apr 2012 18:11:28 +0200 Subject: Position: First draft for a new notification API, via using callback, telling you were the of-element is, not just when something flipped. New test page demonstrates usage --- tests/visual/position/position.html | 16 ++- tests/visual/position/position_notification.html | 120 +++++++++++++++++++++++ ui/jquery.ui.position.js | 38 +++---- 3 files changed, 152 insertions(+), 22 deletions(-) create mode 100644 tests/visual/position/position_notification.html diff --git a/tests/visual/position/position.html b/tests/visual/position/position.html index b9b769d9b..89d991231 100644 --- a/tests/visual/position/position.html +++ b/tests/visual/position/position.html @@ -17,16 +17,24 @@ $("ul").insertAfter(inputs); $(window).resize(function() { inputs.each(function() { - $(this).position({ + var input = $(this).position({ my: this.id.replace(/-/, " "), at: this.id.replace(/-/, " "), of: "#container", collision: "none" }); - $(this).next().menu().position({ + var menu = $(this).next().menu() + menu.position({ my: "left top+20", at: "left bottom", of: this, + using: function( position ) { + input.val(position.horizontal + " " + position.vertical) + $(this).offset( position ) + .removeClass("left right top bottom") + .addClass(position.horizontal) + .addClass(position.vertical); + } }); }); }).resize(); @@ -44,11 +52,11 @@ top: -22px; left: 5px; } - .ui-flipped-left:before { + .right:before { left: auto; right: 5px; } - .ui-flipped-top:before { + .bottom:before { content: "↓"; top: auto; bottom: -19px; diff --git a/tests/visual/position/position_notification.html b/tests/visual/position/position_notification.html new file mode 100644 index 000000000..d87c506ca --- /dev/null +++ b/tests/visual/position/position_notification.html @@ -0,0 +1,120 @@ + + + + + Position Visual Test: Default + + + + + + + + + + + + + +
all around me
+ +
+ + + diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 95b8b460d..003e43c3f 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -216,6 +216,26 @@ $.fn.position = function( options ) { if ( $.fn.bgiframe ) { elem.bgiframe(); } + var using = options.using; + if ( using ) { + // we have to proxy, as jQuery.offset.setOffset throws away other props then left/top + options.using = function( props ) { + // can't use basePosition, as that gets modified + var targetOffset = target.offset(), + left = targetOffset.left - props.left, + right = (targetOffset.left + targetWidth) - (props.left + elemWidth), + top = targetOffset.top - props.top, + bottom = (targetOffset.top + targetHeight) - (props.top + elemHeight); + props.horizontal = right < 0 ? "left" : left > 0 ? "right" : "center"; + props.vertical = bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"; + if (Math.max(Math.abs(left), Math.abs(right)) > Math.max(Math.abs(top), Math.abs(bottom))) { + props.important = "horizontal"; + } else { + props.important = "vertical"; + } + using.apply( this, arguments ); + }; + } elem.offset( $.extend( position, { using: options.using } ) ); }); }; @@ -309,9 +329,6 @@ $.ui.position = { return; } - data.elem - .removeClass( "ui-flipped-left ui-flipped-right" ); - var within = data.within, win = $( window ), isWindow = $.isWindow( data.within[0] ), @@ -337,18 +354,12 @@ $.ui.position = { if ( overLeft < 0 ) { newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; if ( newOverRight < 0 || newOverRight < Math.abs( overLeft ) ) { - data.elem - .addClass( "ui-flipped-right" ); - position.left += myOffset + atOffset + offset; } } else if ( overRight > 0 ) { newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; if ( newOverLeft > 0 || Math.abs( newOverLeft ) < overRight ) { - data.elem - .addClass( "ui-flipped-left" ); - position.left += myOffset + atOffset + offset; } } @@ -358,9 +369,6 @@ $.ui.position = { return; } - data.elem - .removeClass( "ui-flipped-top ui-flipped-bottom" ); - var within = data.within, win = $( window ), isWindow = $.isWindow( data.within[0] ), @@ -385,18 +393,12 @@ $.ui.position = { if ( overTop < 0 ) { newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < Math.abs( overTop ) ) ) { - data.elem - .addClass( "ui-flipped-bottom" ); - 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 || Math.abs( newOverTop ) < overBottom ) ) { - data.elem - .addClass( "ui-flipped-top" ); - position.top += myOffset + atOffset + offset; } } -- cgit v1.2.3 From e5ba731019ba32749e3c95d0fde30b64b8bcf147 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Tue, 10 Apr 2012 22:16:38 +0200 Subject: Position: Use a separate object and argument for the feedback information, keeping position props as they were --- tests/visual/position/position.html | 8 ++++---- tests/visual/position/position_notification.html | 10 +++++----- ui/jquery.ui.position.js | 11 ++++++----- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/visual/position/position.html b/tests/visual/position/position.html index 89d991231..532774526 100644 --- a/tests/visual/position/position.html +++ b/tests/visual/position/position.html @@ -28,12 +28,12 @@ my: "left top+20", at: "left bottom", of: this, - using: function( position ) { - input.val(position.horizontal + " " + position.vertical) + using: function( position, feedback ) { + input.val(feedback.horizontal + " " + feedback.vertical) $(this).offset( position ) .removeClass("left right top bottom") - .addClass(position.horizontal) - .addClass(position.vertical); + .addClass(feedback.horizontal) + .addClass(feedback.vertical); } }); }); diff --git a/tests/visual/position/position_notification.html b/tests/visual/position/position_notification.html index d87c506ca..810663c5e 100644 --- a/tests/visual/position/position_notification.html +++ b/tests/visual/position/position_notification.html @@ -37,14 +37,14 @@ my: "center", at: direction, of: target, - using: function( position ) { + using: function( position, feedback ) { $(this).offset( position ); - $(this).text(position.horizontal + " " + position.vertical + " " + position.important) + $(this).text(feedback.horizontal + " " + feedback.vertical + " " + feedback.important) $(this) .removeClass("left right top bottom") - .addClass(position.horizontal) - .addClass(position.vertical) - .addClass(position.important); + .addClass(feedback.horizontal) + .addClass(feedback.vertical) + .addClass(feedback.important); } }) }); diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 003e43c3f..cc0676370 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -226,14 +226,15 @@ $.fn.position = function( options ) { right = (targetOffset.left + targetWidth) - (props.left + elemWidth), top = targetOffset.top - props.top, bottom = (targetOffset.top + targetHeight) - (props.top + elemHeight); - props.horizontal = right < 0 ? "left" : left > 0 ? "right" : "center"; - props.vertical = bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"; + var feedback = {}; + feedback.horizontal = right < 0 ? "left" : left > 0 ? "right" : "center"; + feedback.vertical = bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"; if (Math.max(Math.abs(left), Math.abs(right)) > Math.max(Math.abs(top), Math.abs(bottom))) { - props.important = "horizontal"; + feedback.important = "horizontal"; } else { - props.important = "vertical"; + feedback.important = "vertical"; } - using.apply( this, arguments ); + using.call( this, props, feedback ); }; } elem.offset( $.extend( position, { using: options.using } ) ); -- cgit v1.2.3 From c0cceee8e49a57b64ef9e00bedee3fab431e77af Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Tue, 10 Apr 2012 23:41:41 +0200 Subject: Position: Fix single var, whitespace. Clone targetOffset to avoid reading that twice --- ui/jquery.ui.position.js | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index cc0676370..cde99cdca 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -69,26 +69,29 @@ $.fn.position = function( options ) { atOffset, targetWidth, targetHeight, + targetOffset, basePosition; if ( targetElem.nodeType === 9 ) { targetWidth = target.width(); targetHeight = target.height(); - basePosition = { top: 0, left: 0 }; + targetOffset = { top: 0, left: 0 }; } else if ( $.isWindow( targetElem ) ) { targetWidth = target.width(); targetHeight = target.height(); - basePosition = { top: target.scrollTop(), left: target.scrollLeft() }; + targetOffset = { top: target.scrollTop(), left: target.scrollLeft() }; } else if ( targetElem.preventDefault ) { // force left top to allow flipping options.at = "left top"; targetWidth = targetHeight = 0; - basePosition = { top: options.of.pageY, left: options.of.pageX }; + targetOffset = { top: options.of.pageY, left: options.of.pageX }; } else { targetWidth = target.outerWidth(); targetHeight = target.outerHeight(); - basePosition = target.offset(); + 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 @@ -166,7 +169,8 @@ $.fn.position = function( options ) { parseInt( offsets.my[ 1 ], 10 ) * ( rpercent.test( offsets.my[ 1 ] ) ? elem.outerHeight() / 100 : 1 ) ], - collisionPosition; + collisionPosition, + using = options.using; if ( options.my[ 0 ] === "right" ) { position.left -= elemWidth; @@ -216,20 +220,19 @@ $.fn.position = function( options ) { if ( $.fn.bgiframe ) { elem.bgiframe(); } - var using = options.using; + if ( using ) { - // we have to proxy, as jQuery.offset.setOffset throws away other props then left/top + // we have to proxy, as jQuery.offset.setOffset throws away props other than left/top options.using = function( props ) { - // can't use basePosition, as that gets modified - var targetOffset = target.offset(), - left = targetOffset.left - props.left, + var left = targetOffset.left - props.left, right = (targetOffset.left + targetWidth) - (props.left + elemWidth), top = targetOffset.top - props.top, - bottom = (targetOffset.top + targetHeight) - (props.top + elemHeight); - var feedback = {}; - feedback.horizontal = right < 0 ? "left" : left > 0 ? "right" : "center"; - feedback.vertical = bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"; - if (Math.max(Math.abs(left), Math.abs(right)) > Math.max(Math.abs(top), Math.abs(bottom))) { + bottom = (targetOffset.top + targetHeight) - (props.top + elemHeight), + feedback = { + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( Math.max( Math.abs( left ), Math.abs( right ) ) > Math.max( Math.abs( top ), Math.abs( bottom ) ) ) { feedback.important = "horizontal"; } else { feedback.important = "vertical"; @@ -237,6 +240,7 @@ $.fn.position = function( options ) { using.call( this, props, feedback ); }; } + elem.offset( $.extend( position, { using: options.using } ) ); }); }; -- cgit v1.2.3 From 623e8e68b4e396cd9a3cdb4985c9db343924c4ec Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 11 Apr 2012 00:19:26 +0200 Subject: Position: Mini refactoring, avoids proxying using callback multiple times if more then one element is positioned --- 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 cde99cdca..025d2c815 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -170,7 +170,7 @@ $.fn.position = function( options ) { ( rpercent.test( offsets.my[ 1 ] ) ? elem.outerHeight() / 100 : 1 ) ], collisionPosition, - using = options.using; + using; if ( options.my[ 0 ] === "right" ) { position.left -= elemWidth; @@ -221,9 +221,9 @@ $.fn.position = function( options ) { elem.bgiframe(); } - if ( using ) { - // we have to proxy, as jQuery.offset.setOffset throws away props other than left/top - options.using = function( props ) { + if ( options.using ) { + // adds feedback as second argument to using callback, if present + using = function( props ) { var left = targetOffset.left - props.left, right = (targetOffset.left + targetWidth) - (props.left + elemWidth), top = targetOffset.top - props.top, @@ -237,11 +237,11 @@ $.fn.position = function( options ) { } else { feedback.important = "vertical"; } - using.call( this, props, feedback ); + options.using.call( this, props, feedback ); }; } - elem.offset( $.extend( position, { using: options.using } ) ); + elem.offset( $.extend( position, { using: using } ) ); }); }; -- cgit v1.2.3 From 260261255baa3c891d265cf2266e66cbc2ac88b6 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 11 Apr 2012 15:20:30 +0200 Subject: Position: Extend feedback test page to include two mouse-positioned elements, highlights the 0px center/middle limitation Also rename the demo file to match the variables names, 'feedback', instead of 'notification' --- tests/visual/position/position_feedback.html | 140 +++++++++++++++++++++++ tests/visual/position/position_notification.html | 120 ------------------- 2 files changed, 140 insertions(+), 120 deletions(-) create mode 100644 tests/visual/position/position_feedback.html delete mode 100644 tests/visual/position/position_notification.html diff --git a/tests/visual/position/position_feedback.html b/tests/visual/position/position_feedback.html new file mode 100644 index 000000000..0bb483e4b --- /dev/null +++ b/tests/visual/position/position_feedback.html @@ -0,0 +1,140 @@ + + + + + Position Visual Test: Default + + + + + + + + + + + + + +
all around me
+ +
+ + + diff --git a/tests/visual/position/position_notification.html b/tests/visual/position/position_notification.html deleted file mode 100644 index 810663c5e..000000000 --- a/tests/visual/position/position_notification.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Position Visual Test: Default - - - - - - - - - - - - - -
all around me
- -
- - - -- cgit v1.2.3 From d077f9b360ebee63df48b7195780016671f2613e Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Thu, 12 Apr 2012 01:32:30 +0200 Subject: Position: Improve feedback API by giving the center/middle position more weight. Also removed themeswitcher from test pages, now load faster --- tests/visual/position/position.html | 8 ++++---- tests/visual/position/position_feedback.html | 23 +++++++++++++++++++++-- tests/visual/position/position_fit.html | 1 - tests/visual/position/position_flip.html | 1 - tests/visual/position/position_flipfit.html | 1 - tests/visual/position/position_margin.html | 1 - ui/jquery.ui.position.js | 6 ++++++ 7 files changed, 31 insertions(+), 10 deletions(-) diff --git a/tests/visual/position/position.html b/tests/visual/position/position.html index 532774526..64c5d2300 100644 --- a/tests/visual/position/position.html +++ b/tests/visual/position/position.html @@ -10,7 +10,6 @@ - - + + + +
all around me
+ +
+ + + diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 31da2237b..17d43b2a4 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -241,9 +241,22 @@ $.fn.position = function( options ) { top = targetOffset.top - props.top, bottom = (targetOffset.top + targetHeight) - (props.top + elemHeight), feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: props.left, + top: props.top, + width: elemWidth, + height: elemHeight + }, horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", - vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle", - target: target + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" }, max = Math.max, abs = Math.abs; -- cgit v1.2.3 From 5cf3f927a003566c690098c58a4c6c4a4729f12e Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Tue, 17 Apr 2012 09:56:20 +0200 Subject: Tooltip: Remove bad docs links from headers --- themes/base/jquery.ui.tooltip.css | 2 -- ui/jquery.ui.tooltip.js | 2 -- 2 files changed, 4 deletions(-) diff --git a/themes/base/jquery.ui.tooltip.css b/themes/base/jquery.ui.tooltip.css index f1fa50cc6..d144b0a7f 100644 --- a/themes/base/jquery.ui.tooltip.css +++ b/themes/base/jquery.ui.tooltip.css @@ -4,8 +4,6 @@ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tooltip#theming */ .ui-tooltip { padding:8px; diff --git a/ui/jquery.ui.tooltip.js b/ui/jquery.ui.tooltip.js index 97895a6a8..424eca7af 100644 --- a/ui/jquery.ui.tooltip.js +++ b/ui/jquery.ui.tooltip.js @@ -5,8 +5,6 @@ * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * - * http://docs.jquery.com/UI/Tooltip - * * Depends: * jquery.ui.core.js * jquery.ui.widget.js -- cgit v1.2.3 From db592b787e79964dc65b66dc24a8756108881fd8 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Tue, 17 Apr 2012 09:57:17 +0200 Subject: Tooltip: Update custom-style demo, remove the ugly padding that was hiding layout issues, use new position feedback API instead of position callout in more then just one place --- demos/tooltip/custom-style.html | 101 ++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 55 deletions(-) diff --git a/demos/tooltip/custom-style.html b/demos/tooltip/custom-style.html index 4d48616cb..633da3d95 100644 --- a/demos/tooltip/custom-style.html +++ b/demos/tooltip/custom-style.html @@ -13,76 +13,67 @@ -- cgit v1.2.3 From f594c0623ae096165df88160575ef55952be92c0 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 18 Apr 2012 00:30:47 +0200 Subject: Position: Make getOffsets and parseCss helpers local functions, no need to expose those --- ui/jquery.ui.position.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 17d43b2a4..7d30e4bca 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -19,6 +19,16 @@ var rhorizontal = /left|center|right/, _position = $.fn.position, cachedScrollbarWidth; +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 ) { @@ -65,15 +75,6 @@ $.position = { width: isWindow ? withinElement.width() : withinElement.outerWidth(), height: isWindow ? withinElement.height() : withinElement.outerHeight() }; - }, - getOffsets: function( 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 ) - ]; - }, - parseCss: function( element, property ) { - return parseInt( $.css( element, property ), 10 ) || 0; } }; @@ -167,7 +168,7 @@ $.fn.position = function( options ) { basePosition.top += targetHeight / 2; } - atOffset = $.position.getOffsets( offsets.at, targetWidth, targetHeight ); + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); basePosition.left += atOffset[ 0 ]; basePosition.top += atOffset[ 1 ]; @@ -175,12 +176,12 @@ $.fn.position = function( options ) { var elem = $( this ), elemWidth = elem.outerWidth(), elemHeight = elem.outerHeight(), - marginLeft = $.position.parseCss( this, "marginLeft" ), - marginTop = $.position.parseCss( this, "marginTop" ), - collisionWidth = elemWidth + marginLeft + $.position.parseCss( this, "marginRight" ) + scrollInfo.width, - collisionHeight = elemHeight + marginTop + $.position.parseCss( this, "marginBottom" ) + scrollInfo.height, + 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 = $.position.getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ), collisionPosition, using; -- cgit v1.2.3 From d3dc637b657b9e491c24a5d1ccd278178f102844 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 18 Apr 2012 16:43:25 +0200 Subject: Position: Cleanup variable definitions, move undefined vars to the top --- ui/jquery.ui.position.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 7d30e4bca..5be90dcfe 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -86,17 +86,13 @@ $.fn.position = function( options ) { // make a copy, we don't want to modify arguments options = $.extend( {}, options ); - var target = $( options.of ), + 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 = {}, - atOffset, - targetWidth, - targetHeight, - targetOffset, - basePosition; + offsets = {}; if ( targetElem.nodeType === 9 ) { targetWidth = target.width(); @@ -173,7 +169,8 @@ $.fn.position = function( options ) { basePosition.top += atOffset[ 1 ]; return this.each(function() { - var elem = $( this ), + var collisionPosition, using, + elem = $( this ), elemWidth = elem.outerWidth(), elemHeight = elem.outerHeight(), marginLeft = parseCss( this, "marginLeft" ), @@ -181,9 +178,7 @@ $.fn.position = function( options ) { 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() ), - collisionPosition, - using; + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); if ( options.my[ 0 ] === "right" ) { position.left -= elemWidth; -- cgit v1.2.3 From be3af5bc64c125ac933a7d80300884fe5bb83e24 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Fri, 20 Apr 2012 14:09:17 +0200 Subject: Position: Move Math.abs/max definitions to the top of the file --- 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 5be90dcfe..ea176688e 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -11,13 +11,15 @@ $.ui = $.ui || {}; -var rhorizontal = /left|center|right/, +var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + rhorizontal = /left|center|right/, rvertical = /top|center|bottom/, roffset = /[\+\-]\d+%?/, rposition = /^\w+/, rpercent = /%$/, - _position = $.fn.position, - cachedScrollbarWidth; + _position = $.fn.position; function getOffsets( offsets, width, height ) { return [ @@ -253,9 +255,7 @@ $.fn.position = function( options ) { }, horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" - }, - max = Math.max, - abs = Math.abs; + }; if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { feedback.horizontal = "center"; } -- cgit v1.2.3 From cfa6aa328e21514c2eec928272d769f77bc62e56 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Fri, 20 Apr 2012 14:13:52 +0200 Subject: Position: offset() always returns null for window, so provide default 0/0 coordinates to avoid checks further down --- ui/jquery.ui.position.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index ea176688e..5a2ede2b8 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -71,7 +71,7 @@ $.position = { return { element: withinElement, isWindow: isWindow, - offset: withinElement.offset(), + offset: withinElement.offset() || { left: 0, top: 0 }, scrollLeft: withinElement.scrollLeft(), scrollTop: withinElement.scrollTop(), width: isWindow ? withinElement.width() : withinElement.outerWidth(), @@ -361,7 +361,7 @@ $.ui.position = { } var within = data.within, - withinOffset = ( within.isWindow ? 0 : within.offset.left ) + within.scrollLeft, + withinOffset = within.offset.left + within.scrollLeft, outerWidth = within.width, offsetLeft = within.isWindow ? 0 : within.offset.left, collisionPosLeft = position.left - data.collisionPosition.marginLeft, @@ -399,7 +399,7 @@ $.ui.position = { } var within = data.within, - withinOffset = ( within.isWindow ? 0 : within.offset.top ) + within.scrollTop, + withinOffset = within.offset.top + within.scrollTop, outerHeight = within.height, offsetTop = within.isWindow ? 0 : within.offset.top, collisionPosTop = position.top - data.collisionPosition.marginTop, -- cgit v1.2.3 From 3b73177d0c5e131d4825080efbd203b2449b2f0f Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Fri, 20 Apr 2012 14:15:57 +0200 Subject: Position: Also create a local reference for Math.round; update other Math references --- ui/jquery.ui.position.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 5a2ede2b8..8f5601c28 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -14,6 +14,7 @@ $.ui = $.ui || {}; var cachedScrollbarWidth, max = Math.max, abs = Math.abs, + round = Math.round, rhorizontal = /left|center|right/, rvertical = /top|center|bottom/, roffset = /[\+\-]\d+%?/, @@ -199,8 +200,8 @@ $.fn.position = function( options ) { // if the browser doesn't support fractions, then round for consistent results if ( !$.support.offsetFractions ) { - position.left = Math.round( position.left ); - position.top = Math.round( position.top ); + position.left = round( position.left ); + position.top = round( position.top ); } collisionPosition = { @@ -312,7 +313,7 @@ $.ui.position = { position.left -= overRight; // adjust based on position and margin } else { - position.left = Math.max( position.left - collisionPosLeft, position.left ); + position.left = max( position.left - collisionPosLeft, position.left ); } }, top: function( position, data ) { @@ -350,7 +351,7 @@ $.ui.position = { position.top -= overBottom; // adjust based on position and margin } else { - position.top = Math.max( position.top - collisionPosTop, position.top ); + position.top = max( position.top - collisionPosTop, position.top ); } } }, @@ -382,13 +383,13 @@ $.ui.position = { if ( overLeft < 0 ) { newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; - if ( newOverRight < 0 || newOverRight < Math.abs( overLeft ) ) { + 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 || Math.abs( newOverLeft ) < overRight ) { + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { position.left += myOffset + atOffset + offset; } } @@ -419,13 +420,13 @@ $.ui.position = { newOverBottom; if ( overTop < 0 ) { newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; - if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < Math.abs( overTop ) ) ) { + 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 || Math.abs( newOverTop ) < overBottom ) ) { + if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { position.top += myOffset + atOffset + offset; } } -- cgit v1.2.3 From a9f1ffb4fd9b6953318e262b056c3a534a83e462 Mon Sep 17 00:00:00 2001 From: Scott González Date: Fri, 20 Apr 2012 10:10:02 -0400 Subject: Position: Simplify border calculations for feedback. --- ui/jquery.ui.position.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 8f5601c28..31920c161 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -236,9 +236,9 @@ $.fn.position = function( options ) { // adds feedback as second argument to using callback, if present using = function( props ) { var left = targetOffset.left - props.left, - right = (targetOffset.left + targetWidth) - (props.left + elemWidth), + right = left + targetWidth - elemWidth, top = targetOffset.top - props.top, - bottom = (targetOffset.top + targetHeight) - (props.top + elemHeight), + bottom = top + targetHeight - elemHeight, feedback = { target: { element: target, -- cgit v1.2.3 From 22b7f9a8196e0927bd993edd2ca3d1b1ef7bd79d Mon Sep 17 00:00:00 2001 From: Scott González Date: Fri, 20 Apr 2012 10:12:14 -0400 Subject: Position: Use targetElem for events to maintain consistency. --- ui/jquery.ui.position.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 31920c161..bba4dd4e6 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -109,7 +109,7 @@ $.fn.position = function( options ) { // force left top to allow flipping options.at = "left top"; targetWidth = targetHeight = 0; - targetOffset = { top: options.of.pageY, left: options.of.pageX }; + targetOffset = { top: targetElem.pageY, left: targetElem.pageX }; } else { targetWidth = target.outerWidth(); targetHeight = target.outerHeight(); -- cgit v1.2.3 From 2cf9948cadf45a24c591d6f7232f2470b4d9743e Mon Sep 17 00:00:00 2001 From: Scott González Date: Fri, 20 Apr 2012 11:02:50 -0400 Subject: Position: Use offsets for all calculations in feedback API. --- tests/visual/position/position_feedback.html | 2 +- ui/jquery.ui.position.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/visual/position/position_feedback.html b/tests/visual/position/position_feedback.html index f23d8a299..11bb19f3e 100644 --- a/tests/visual/position/position_feedback.html +++ b/tests/visual/position/position_feedback.html @@ -14,7 +14,7 @@ $(function() { function using( position, feedback ) { $(this) - .offset( position ) + .css( position ) .text( feedback.horizontal + " " + feedback.vertical + " " + feedback.important ) .removeClass( "left right top bottom center middle vertical horizontal" ) .addClass( feedback.horizontal ) diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index bba4dd4e6..b8764f2bb 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -235,9 +235,9 @@ $.fn.position = function( options ) { if ( options.using ) { // adds feedback as second argument to using callback, if present using = function( props ) { - var left = targetOffset.left - props.left, + var left = targetOffset.left - position.left, right = left + targetWidth - elemWidth, - top = targetOffset.top - props.top, + top = targetOffset.top - position.top, bottom = top + targetHeight - elemHeight, feedback = { target: { @@ -249,8 +249,8 @@ $.fn.position = function( options ) { }, element: { element: elem, - left: props.left, - top: props.top, + left: position.left, + top: position.top, width: elemWidth, height: elemHeight }, -- cgit v1.2.3 From af1576280a807dcc166ddf619abab1fc24cac664 Mon Sep 17 00:00:00 2001 From: Scott González Date: Fri, 20 Apr 2012 11:18:58 -0400 Subject: Position visual tests: Cleanup. --- tests/visual/position/position_feedback.html | 181 +++++++++++---------- .../visual/position/position_feedback_rotate.html | 100 ++++++------ 2 files changed, 143 insertions(+), 138 deletions(-) diff --git a/tests/visual/position/position_feedback.html b/tests/visual/position/position_feedback.html index 11bb19f3e..006a1be02 100644 --- a/tests/visual/position/position_feedback.html +++ b/tests/visual/position/position_feedback.html @@ -1,19 +1,19 @@ - + - + Position Visual Test: Default - - - - - - - - + + + + + -
all around me
- -
+
all around me
+
diff --git a/tests/visual/position/position_feedback_rotate.html b/tests/visual/position/position_feedback_rotate.html index a93287e7d..11138b112 100644 --- a/tests/visual/position/position_feedback_rotate.html +++ b/tests/visual/position/position_feedback_rotate.html @@ -1,22 +1,25 @@ - + - + Position Visual Test: Default - - - - - - - - + + + + + -
all around me
- -
+
all around me
+
-- cgit v1.2.3 From 1a0f2e46593ec9e3fbca51175d342210a9996fba Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Tue, 24 Apr 2012 16:17:02 +0200 Subject: Position: Extend unit test for using to check feedback properties --- tests/unit/position/position_core.js | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/tests/unit/position/position_core.js b/tests/unit/position/position_core.js index 0ebcabef3..b567b7299 100644 --- a/tests/unit/position/position_core.js +++ b/tests/unit/position/position_core.js @@ -255,11 +255,30 @@ test( "offsets", function() { }); test( "using", function() { - expect( 6 ); + expect( 10 ); var count = 0, elems = $( "#el1, #el2" ), - expectedPosition = { top: 40, left: 40 }, + of = $( "#parentx" ), + expectedPosition = { top: 60, left: 60 }, + expectedFeedback = { + target: { + element: of, + width: 20, + height: 20, + left: 40, + top: 40 + }, + element: { + width: 6, + height: 6, + left: 60, + top: 60 + }, + horizontal: "left", + vertical: "top", + important: "vertical" + }, originalPosition = elems.position({ my: "right bottom", at: "rigt bottom", @@ -269,11 +288,14 @@ test( "using", function() { elems.position({ my: "left top", - at: "left top", + at: "center+10 bottom", of: "#parentx", - using: function( position ) { + using: function( position, feedback ) { deepEqual( this, elems[ count ], "correct context for call #" + count ); deepEqual( position, expectedPosition, "correct position for call #" + count ); + deepEqual( feedback.element.element[ 0 ], elems[ count ] ); + delete feedback.element.element; + deepEqual( feedback, expectedFeedback ); count++; } }); -- cgit v1.2.3 From 252352e12473034dc86917bc9c7c1f764e6f7eb4 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Tue, 24 Apr 2012 17:23:25 +0200 Subject: Position: Fix scrollbar calculcation to correctly take overflow:scroll into account, along with unit tests --- tests/unit/position/position.html | 2 +- tests/unit/position/position_core.js | 61 ++++++++++++++++++++++++++++++ tests/visual/position/position_within.html | 2 +- ui/jquery.ui.position.js | 11 +++--- 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/tests/unit/position/position.html b/tests/unit/position/position.html index 518e1f960..2a6e43d36 100644 --- a/tests/unit/position/position.html +++ b/tests/unit/position/position.html @@ -43,7 +43,7 @@ elements smaller than 10px have a line-height set on them to avoid a bug in IE6
-
+
diff --git a/tests/unit/position/position_core.js b/tests/unit/position/position_core.js index b567b7299..f15ea48cc 100644 --- a/tests/unit/position/position_core.js +++ b/tests/unit/position/position_core.js @@ -591,6 +591,67 @@ test( "within", function() { }, "flipfit - left top" ); }); +test( "with scrollbars", function() { + expect( 4 ); + + $( "#scrollx" ).css({ + width: 100, + height: 100, + left: 0, + top: 0 + }); + + collisionTest({ + of: "#scrollx", + collision: "fit", + within: "#scrollx" + }, { + top: 90, + left: 90 + }, "visible" ); + + $( "#scrollx" ).css({ + overflow: "scroll" + }); + + var scrollbarInfo = $.position.getScrollInfo( $.position.getWithinInfo( $( "#scrollx" ) ) ); + + collisionTest({ + of: "#scrollx", + collision: "fit", + within: "#scrollx" + }, { + top: 90 - scrollbarInfo.height, + left: 90 - scrollbarInfo.width + }, "scroll" ); + + $( "#scrollx" ).css({ + overflow: "auto" + }); + + collisionTest({ + of: "#scrollx", + collision: "fit", + within: "#scrollx" + }, { + top: 90, + left: 90 + }, "auto, no scroll" ); + + $( "#scrollx" ).css({ + overflow: "auto" + }).append( $("
").height(300).width(300) ); + + collisionTest({ + of: "#scrollx", + collision: "fit", + within: "#scrollx" + }, { + top: 90 - scrollbarInfo.height, + left: 90 - scrollbarInfo.width + }, "auto, with scroll" ); +}); + test( "fractions", function() { expect( 1 ); diff --git a/tests/visual/position/position_within.html b/tests/visual/position/position_within.html index 7d8813582..692cb1067 100644 --- a/tests/visual/position/position_within.html +++ b/tests/visual/position/position_within.html @@ -97,7 +97,7 @@ collision: $( "#collision_horizontal" ).val() + " " + $( "#collision_vertical" ).val() }); } - $( ".demo" ).append("
").css("overflow","auto"); + $( ".demo" ).css("overflow","scroll"); $( ".positionable" ).css( "opacity", 0.5 ); diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index b8764f2bb..d4d09bee4 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -58,12 +58,13 @@ $.position = { getScrollInfo: function( within ) { var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), - scrollbarWidth = overflowX === "auto" || overflowX === "scroll" ? $.position.scrollbarWidth() : 0, - scrollbarHeight = overflowY === "auto" || overflowY === "scroll" ? $.position.scrollbarWidth() : 0; - + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); return { - height: within.height < within.element[0].scrollHeight ? scrollbarHeight : 0, - width: within.width < within.element[0].scrollWidth ? scrollbarWidth : 0 + width: hasOverflowX ? $.position.scrollbarWidth() : 0, + height: hasOverflowY ? $.position.scrollbarWidth() : 0 }; }, getWithinInfo: function( element ) { -- cgit v1.2.3