From 5e44b3ce8851f62a38ce9211c6721e1050e2dabf Mon Sep 17 00:00:00 2001 From: Jean-Francois Remy Date: Tue, 3 May 2011 04:38:17 -0400 Subject: [PATCH] Position: Handled scrolled windows properly with collision: fit. Fixes #7211 - Position: Collision: fit doesn't work at top of window when scrolled. --- tests/unit/position/position_core.js | 27 +++++++++++++++++---- ui/jquery.ui.position.js | 35 +++++++++++++++++++++------- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/tests/unit/position/position_core.js b/tests/unit/position/position_core.js index 5a47fe6bb..dbbda8a3b 100644 --- a/tests/unit/position/position_core.js +++ b/tests/unit/position/position_core.js @@ -1,5 +1,10 @@ (function( $ ) { +function scrollTopSupport() { + $( window ).scrollTop( 1 ); + return $( window ).scrollTop() === 1; +} + module( "position" ); test( "my, at, of", function() { @@ -161,11 +166,7 @@ test( "of", function() { left: $( window ).width() - 10 }, "window as jQuery object" ); - var scrollTopSupport = (function() { - $( window ).scrollTop( 1 ); - return $( window ).scrollTop() === 1; - }() ); - if ( scrollTopSupport ) { + if ( scrollTopSupport() ) { $( window ).scrollTop( 500 ).scrollLeft( 200 ); $( "#elx" ).position({ my: "right bottom", @@ -311,6 +312,22 @@ test( "collision: fit, with offset", function() { }, { top: 0, left: 0 }, "left top, negative offset" ); }); +test( "collision: fit, window scrolled", function() { + if ( scrollTopSupport() ) { + var win = $( window ); + win.scrollTop( 300 ).scrollLeft( 200 ); + collisionTest({ + collision: "fit", + at: "left-100 top-100" + }, { top: 300, left: 200 }, "top left" ); + collisionTest2({ + collision: "fit", + at: "right+100 bottom+100" + }, { top: 300 + win.height() - 10, left: 200 + win.width() - 10 }, "right bottom" ); + win.scrollTop( 0 ).scrollLeft( 0 ); + } +}); + test( "collision: flip, no offset", function() { collisionTest({ collision: "flip" diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index b6fcc7151..98b8198e2 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -184,20 +184,37 @@ $.ui.position = { fit: { left: function( position, data ) { var win = $( window ), - over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(); - position.left = over > 0 ? - position.left - over : - Math.max( position.left - data.collisionPosition.left, position.left ); + overLeft = win.scrollLeft() - data.collisionPosition.left, + overRight = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(); + + // element is wider than window or too far left -> align with left edge + if ( data.collisionWidth > win.width() || overLeft > 0 ) { + position.left = position.left + overLeft; + // too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left = position.left - overRight; + // adjust based on position and margin + } else { + position.left = Math.max( position.left - data.collisionPosition.left, position.left ); + } }, top: function( position, data ) { var win = $( window ), - over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(); - position.top = over > 0 ? - position.top - over : - Math.max( position.top - data.collisionPosition.top, position.top ); + overTop = win.scrollTop() - data.collisionPosition.top, + overBottom = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(); + + // element is taller than window or too far up -> align with top edge + if ( data.collisionHeight > win.height() || overTop > 0 ) { + position.top = position.top + overTop; + // too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top = position.top - overBottom; + // adjust based on position and margin + } else { + position.top = Math.max( position.top - data.collisionPosition.top, position.top ); + } } }, - flip: { left: function( position, data ) { if ( data.at[ 0 ] === center ) { -- 2.39.5