From bfbc0b1fb3c0bf43ccbaefd03bcfa2cf19ea4a03 Mon Sep 17 00:00:00 2001 From: kborchers Date: Wed, 26 Oct 2011 10:43:01 -0400 Subject: [PATCH] Position: Added a check for fraction support in element positions. Fixes #7255 - Position: Revisit solution for off-by-1 errors. --- tests/unit/position/position_core.js | 34 +++++++++--------- ui/jquery.ui.position.js | 52 ++++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 20 deletions(-) diff --git a/tests/unit/position/position_core.js b/tests/unit/position/position_core.js index f4075ccfe..b7d0894d3 100644 --- a/tests/unit/position/position_core.js +++ b/tests/unit/position/position_core.js @@ -406,22 +406,22 @@ test("collision: flip, with margin", function() { }, { top: 0, left: 0 }, "right bottom"); }); -//test('bug #5280: consistent results (avoid fractional values)', function() { -// var wrapper = $('#bug-5280'), -// elem = wrapper.children(), -// offset1 = elem.position({ -// my: 'center', -// at: 'center', -// of: wrapper, -// collision: 'none' -// }).offset(), -// offset2 = elem.position({ -// my: 'center', -// at: 'center', -// of: wrapper, -// collision: 'none' -// }).offset(); -// same(offset1, offset2); -//}); +test('bug #5280: consistent results (avoid fractional values)', function() { + var wrapper = $('#bug-5280'), + elem = wrapper.children(), + offset1 = elem.position({ + my: 'center', + at: 'center', + of: wrapper, + collision: 'none' + }).offset(), + offset2 = elem.position({ + my: 'center', + at: 'center', + of: wrapper, + collision: 'none' + }).offset(); + same(offset1, offset2); +}); })(jQuery); diff --git a/ui/jquery.ui.position.js b/ui/jquery.ui.position.js index 837f23f40..92cf8001d 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -14,6 +14,7 @@ $.ui = $.ui || {}; var horizontalPositions = /left|center|right/, verticalPositions = /top|center|bottom/, center = "center", + support = {}, _position = $.fn.position, _offset = $.fn.offset; @@ -121,9 +122,11 @@ $.fn.position = function( options ) { position.top -= elemHeight / 2; } - // prevent fractions (see #5280) - position.left = Math.round( position.left ); - position.top = Math.round( position.top ); + // prevent fractions if jQuery version doesn't support them (see #5280) + if ( !support.fractions ) { + position.left = Math.round( position.left ); + position.top = Math.round( position.top ); + } collisionPosition = { left: position.left - marginLeft, @@ -249,4 +252,47 @@ if ( !$.offset.setOffset ) { }; } +// fraction support test (older versions of jQuery don't support fractions) +(function () { + var body = document.getElementsByTagName( "body" )[ 0 ], + div = document.createElement( "div" ), + testElement, testElementParent, testElementStyle, offset, offsetTotal; + + //Create a "fake body" for testing based on method used in jQuery.support + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + background: "none" + }; + if ( body ) { + jQuery.extend( testElementStyle, { + position: "absolute", + left: "-1000px", + top: "-1000px" + }); + } + for ( var i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || document.documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); + + div.style.cssText = "position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;"; + + offset = $( div ).offset( function( _, offset ) { + return offset; + }).offset(); + + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); + + offsetTotal = offset.top + offset.left + ( body ? 2000 : 0 ); + support.fractions = offsetTotal > 21 && offsetTotal < 22; +})(); + }( jQuery ));