diff options
-rw-r--r-- | demos/tooltip/custom-style.html | 101 | ||||
-rw-r--r-- | tests/unit/position/position.html | 2 | ||||
-rw-r--r-- | tests/unit/position/position_core.js | 91 | ||||
-rw-r--r-- | tests/visual/position/position.html | 20 | ||||
-rw-r--r-- | tests/visual/position/position_feedback.html | 146 | ||||
-rw-r--r-- | tests/visual/position/position_feedback_rotate.html | 109 | ||||
-rw-r--r-- | tests/visual/position/position_fit.html | 1 | ||||
-rw-r--r-- | tests/visual/position/position_flip.html | 1 | ||||
-rw-r--r-- | tests/visual/position/position_flipfit.html | 1 | ||||
-rw-r--r-- | tests/visual/position/position_margin.html | 1 | ||||
-rw-r--r-- | tests/visual/position/position_within.html | 2 | ||||
-rw-r--r-- | themes/base/jquery.ui.tooltip.css | 2 | ||||
-rw-r--r-- | ui/jquery.ui.position.js | 231 | ||||
-rw-r--r-- | ui/jquery.ui.tooltip.js | 2 |
14 files changed, 535 insertions, 175 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 @@ <script> $(function() { $( ".demo" ).tooltip({ - open: function(event, ui) { - $("<div>").addClass("arrow").appendTo(ui.tooltip); - }, position: { - my: "center bottom", + my: "center bottom-20", at: "center top", - offset: "0 -20px" + using: function( position, feedback ) { + $( this ).css( position ); + $( "<div>" ) + .addClass( "arrow" ) + .addClass( feedback.vertical ) + .addClass( feedback.horizontal ) + .appendTo( this ); + } } }); }); </script> <style> - label { - display: inline-block; - width: 5em; - } - .demo { - margin: 10em 0 0 10em; - } .ui-tooltip, .arrow:after { - background: black; - border: 2px solid white; + background: black; + border: 2px solid white; } .ui-tooltip { - display: inline-block; - position: relative; - padding: 10px 20px; - color: white; - border-radius: 20px; - text-align: center; - font: bold 14px "Helvetica Neue", Sans-Serif; - font-stretch: condensed; - text-decoration: none; - text-transform: uppercase; - box-shadow: 0 0 7px black; + padding: 10px 20px; + color: white; + border-radius: 20px; + font: bold 14px "Helvetica Neue", Sans-Serif; + text-transform: uppercase; + box-shadow: 0 0 7px black; } .arrow { - width: 70px; - height: 16px; - overflow: hidden; - position: absolute; - left: 50%; - margin-left: -35px; - bottom: -16px; + width: 70px; + height: 16px; + overflow: hidden; + position: absolute; + left: 50%; + margin-left: -35px; + bottom: -16px; } - .arrow:after { - content: ""; - position: absolute; - left: 20px; - top: -20px; - width: 25px; - height: 25px; - -webkit-box-shadow: 6px 5px 9px -9px black, - 5px 6px 9px -9px black; - -moz-box-shadow: 6px 5px 9px -9px black, - 5px 6px 9px -9px black; - box-shadow: 6px 5px 9px -9px black, - 5px 6px 9px -9px black; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -ms-transform: rotate(45deg); - -o-transform: rotate(45deg); + .arrow.top { + top: -16px; + bottom: auto; } - div[data-tooltip].active { - opacity: 1; - margin-top: 6px; + .arrow.left { + left: 20%; + } + .arrow:after { + content: ""; + position: absolute; + left: 20px; + top: -20px; + width: 25px; + height: 25px; + box-shadow: 6px 5px 9px -9px black; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + tranform: rotate(45deg); } - div[data-tooltip].out { - opacity: 0; - margin-top: -20px; + .arrow.top:after { + bottom: -20px; + top: auto; } </style> </head> 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 <div id="parent" style="position: absolute; width: 6px; height: 6px; top: 4px; left: 4px; line-height: 6px;"></div> <div id="within" style="position: absolute; width: 12px; height: 12px; top: 2px; left: 0px;"></div> - <div style="position: absolute; top: 0px; left: 0px"> + <div id="scrollx" style="position: absolute; top: 0px; left: 0px"> <div id="elx" style="position: absolute; width: 10px; height: 10px; line-height: 10px;"></div> <div id="parentx" style="position: absolute; width: 20px; height: 20px; top: 40px; left: 40px;"></div> </div> diff --git a/tests/unit/position/position_core.js b/tests/unit/position/position_core.js index 837327b5d..e68e310f1 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++; } }); @@ -569,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( $("<div>").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.html b/tests/visual/position/position.html index b9b769d9b..64c5d2300 100644 --- a/tests/visual/position/position.html +++ b/tests/visual/position/position.html @@ -10,23 +10,31 @@ <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.menu.js"></script> - <script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script> <script type="text/javascript"> $(function() { var inputs = $("input"); $("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({ - my: "left top+20", + var menu = $(this).next().menu() + menu.position({ + my: "left+30 top+20", at: "left bottom", of: this, + using: function( position, feedback ) { + input.val(feedback.horizontal + " " + feedback.vertical) + $(this).offset( position ); + $(this) + .removeClass("left right top bottom center middle") + .addClass(feedback.horizontal) + .addClass(feedback.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_feedback.html b/tests/visual/position/position_feedback.html new file mode 100644 index 000000000..006a1be02 --- /dev/null +++ b/tests/visual/position/position_feedback.html @@ -0,0 +1,146 @@ +<!doctype html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Position Visual Test: Default</title> + <link rel="stylesheet" href="../visual.css"> + <link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css"> + <script src="../../../jquery-1.7.2.js"></script> + <script src="../../../ui/jquery.ui.core.js"></script> + <script src="../../../ui/jquery.ui.widget.js"></script> + <script src="../../../ui/jquery.ui.position.js"></script> + <script src="../../../ui/jquery.ui.menu.js"></script> + <script> + $(function() { + function using( position, feedback ) { + $( this ) + .css( position ) + .text( feedback.horizontal + " " + feedback.vertical + " " + feedback.important ) + .removeClass( "left right top bottom center middle vertical horizontal" ) + .addClass( feedback.horizontal ) + .addClass( feedback.vertical ) + .addClass( feedback.important ); + } + + var element = $( ".element" ), + target = $( "#target" ).position({ + my: "center", + at: "center", + of: window + }), + targetOffset = target.offset(), + oppositeElement = element.clone().width( 50 ).appendTo( "body" ), + leftElement = element.clone().width( 50 ).height( 150 ).appendTo( "body" ), + rightElement = element.clone().height( 150 ).width( 150 ).appendTo( "body" ); + + $.each([ + "center top-100", + "right+25 top-50", + "right+75 top", + "right+75 center", + "right+75 bottom", + "right+25 bottom+50", + "center bottom+100", + "left-25 bottom+50", + "left-75 bottom", + "left-75 center", + "left-75 top", + "left-25 top-50" + ], function( index, direction ) { + element.clone().insertAfter( target ).position({ + my: "center", + at: direction, + of: target, + using: using + }); + }); + + element.width( 150 ); + $( document ).on( "mousemove", function( event ) { + var base = { + my: "left top", + at: "left top", + of: target, + using: using + }; + element.position( $.extend({ + offset: (event.pageX - targetOffset.left) + " " + (event.pageY - targetOffset.top) + }, base )); + oppositeElement.position( $.extend({ + offset: (-1 * (event.pageX - targetOffset.left)) + " " + (-1 * (event.pageY - targetOffset.top)) + }, base )); + leftElement.position( $.extend({ + offset: (-0.9 * (event.pageX - targetOffset.left)) + " " + (0.9 * (event.pageY - targetOffset.top)) + }, base )); + rightElement.position( $.extend({ + offset: (0.9 * (event.pageX - targetOffset.left)) + " " + (-0.9 * (event.pageY - targetOffset.top)) + }, base) ); + }); + }); + </script> + <style> + #target, .element { + position: absolute; + border: 1px solid black; + border-radius: 5px; + width: 75px; + height: 25px; + padding: 5px; + } + #target { + height: 75px; + } + .element:before { + font-size: 12pt; + content: "↑"; + position: absolute; + top: -19px; + left: 5px; + } + .right:before { + left: auto; + right: 5px; + } + .bottom:before { + content: "↓"; + top: auto; + bottom: -19px; + } + .center:before { + left: 50%; + right: auto; + } + .middle:before { + top: 50%; + bottom: auto; + } + .horizontal:before { + height: 10px; + top: 50%; + margin-top: -8px; + bottom: auto; + left: -18px; + right: auto; + content: "←"; + } + .right.horizontal:before { + left: auto; + right: -18px; + content: "→"; + } + .bottom.horizontal:before { + top: auto; + bottom: 5px; + } + .top.horizontal:before { + top: 5px; + } + </style> +</head> +<body> + +<div id="target">all around me</div> +<div class="element"></div> + +</body> +</html> diff --git a/tests/visual/position/position_feedback_rotate.html b/tests/visual/position/position_feedback_rotate.html new file mode 100644 index 000000000..11138b112 --- /dev/null +++ b/tests/visual/position/position_feedback_rotate.html @@ -0,0 +1,109 @@ +<!doctype html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Position Visual Test: Default</title> + <link rel="stylesheet" href="../visual.css"> + <link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css"> + <script src="../../../jquery-1.7.2.js"></script> + <script src="../../../ui/jquery.ui.core.js"></script> + <script src="../../../ui/jquery.ui.widget.js"></script> + <script src="../../../ui/jquery.ui.position.js"></script> + <script src="../../../ui/jquery.ui.menu.js"></script> + <script> + $(function() { + function using( position, feedback ) { + var angleRad = Math.atan2( + feedback.target.top + feedback.target.height / 2 - feedback.element.top - feedback.element.height / 2, + feedback.target.left + feedback.target.width / 2 - feedback.element.left - feedback.element.width / 2 + ) * 180 / Math.PI, + angle = Math.round( angleRad * 100) / 100; + $( this ) + .css( position ) + .text( feedback.horizontal + " " + feedback.vertical + " " + feedback.important + " " + angle + "°" ) + .css({ + "-webkit-transform": "rotate(" + angle + "deg)", + "-moz-transform": "rotate(" + angle + "deg)", + "-ms-transform": "rotate(" + angle + "deg)", + "-o-transform": "rotate(" + angle + "deg)", + "transform": "rotate(" + angle + "deg)" + }); + } + + var element = $( ".element" ), + target = $( "#target" ).position({ + my: "center", + at: "center", + of: window + }), + targetOffset = target.offset(); + oppositeElement = element.clone().width( 50 ).appendTo( "body" ), + leftElement = element.clone().width( 50 ).height( 150 ).appendTo( "body" ), + rightElement = element.clone().height( 150 ).width( 150 ).appendTo( "body" ); + + $.each([ + "center top-100", + "right+25 top-50", + "right+75 top", + "right+75 center", + "right+75 bottom", + "right+25 bottom+50", + "center bottom+100", + "left-25 bottom+50", + "left-75 bottom", + "left-75 center", + "left-75 top", + "left-25 top-50" + ], function( index, direction ) { + element.clone().insertAfter( target ).position({ + my: "center", + at: direction, + of: target, + using: using + }); + }); + + element.width( 150 ); + $( document ).on( "mousemove", function( event ) { + var base = { + my: "left top", + at: "left top", + of: target, + using: using + }; + element.position( $.extend({ + offset: (event.pageX - targetOffset.left) + " " + (event.pageY - targetOffset.top) + }, base )); + oppositeElement.position( $.extend({ + offset: (-1 * (event.pageX - targetOffset.left)) + " " + (-1 * (event.pageY - targetOffset.top)) + }, base )); + leftElement.position( $.extend({ + offset: (-0.9 * (event.pageX - targetOffset.left)) + " " + (0.9 * (event.pageY - targetOffset.top)) + }, base )); + rightElement.position( $.extend({ + offset: (0.9 * (event.pageX - targetOffset.left)) + " " + (-0.9 * (event.pageY - targetOffset.top)) + }, base )); + }); + }); + </script> + <style> + #target, .element { + position: absolute; + border: 1px solid black; + border-radius: 5px; + width: 75px; + height: 25px; + padding: 5px; + } + #target { + height: 75px; + } + </style> +</head> +<body> + +<div id="target">all around me</div> +<div class="element"></div> + +</body> +</html> diff --git a/tests/visual/position/position_fit.html b/tests/visual/position/position_fit.html index 9c60b78f6..dbd52550f 100644 --- a/tests/visual/position/position_fit.html +++ b/tests/visual/position/position_fit.html @@ -10,7 +10,6 @@ <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.menu.js"></script> - <script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script> <script type="text/javascript"> $(function() { var inputs = $("input"); diff --git a/tests/visual/position/position_flip.html b/tests/visual/position/position_flip.html index bae3c649b..29ad32f96 100644 --- a/tests/visual/position/position_flip.html +++ b/tests/visual/position/position_flip.html @@ -10,7 +10,6 @@ <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.menu.js"></script> - <script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script> <script type="text/javascript"> $(function() { var inputs = $("input"); diff --git a/tests/visual/position/position_flipfit.html b/tests/visual/position/position_flipfit.html index fcfb75b6b..fb99e4007 100644 --- a/tests/visual/position/position_flipfit.html +++ b/tests/visual/position/position_flipfit.html @@ -10,7 +10,6 @@ <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.menu.js"></script> - <script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script> <script type="text/javascript"> $(function() { var inputs = $("input"); diff --git a/tests/visual/position/position_margin.html b/tests/visual/position/position_margin.html index 71d8f0a3c..2e3b63266 100644 --- a/tests/visual/position/position_margin.html +++ b/tests/visual/position/position_margin.html @@ -9,7 +9,6 @@ <script type="text/javascript" src="../../../ui/jquery.ui.core.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script> <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script> - <script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script> <script type="text/javascript"> $(function() { $( "#elem" ).position({ 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("<div style='width:5000px;height:5000px;' />").css("overflow","auto"); + $( ".demo" ).css("overflow","scroll"); $( ".positionable" ).css( "opacity", 0.5 ); 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.position.js b/ui/jquery.ui.position.js index 95b8b460d..d4d09bee4 100644 --- a/ui/jquery.ui.position.js +++ b/ui/jquery.ui.position.js @@ -11,16 +11,32 @@ $.ui = $.ui || {}; -var rhorizontal = /left|center|right/, +var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + round = Math.round, + rhorizontal = /left|center|right/, rvertical = /top|center|bottom/, roffset = /[\+\-]\d+%?/, rposition = /^\w+/, rpercent = /%$/, - center = "center", _position = $.fn.position; +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 ) { + return cachedScrollbarWidth; + } var w1, w2, div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), innerDiv = div.children()[0]; @@ -37,18 +53,31 @@ $.position = { div.remove(); - return w1 - w2; + return (cachedScrollbarWidth = w1 - w2); }, - getScrollInfo: function(within) { - var notWindow = within[0] !== window, - overflowX = notWindow ? within.css( "overflow-x" ) : "", - overflowY = notWindow ? within.css( "overflow-y" ) : "", - scrollbarWidth = overflowX === "auto" || overflowX === "scroll" ? $.position.scrollbarWidth() : 0, - scrollbarHeight = overflowY === "auto" || overflowY === "scroll" ? $.position.scrollbarWidth() : 0; - + getScrollInfo: function( within ) { + var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), + overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), + 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[0].scrollHeight ? scrollbarHeight : 0, - width: within.width() < within[0].scrollWidth ? scrollbarWidth : 0 + width: hasOverflowX ? $.position.scrollbarWidth() : 0, + height: hasOverflowY ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isWindow = $.isWindow( withinElement[0] ); + return { + element: withinElement, + isWindow: isWindow, + offset: withinElement.offset() || { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + width: isWindow ? withinElement.width() : withinElement.outerWidth(), + height: isWindow ? withinElement.height() : withinElement.outerHeight() }; } }; @@ -61,34 +90,34 @@ $.fn.position = function( options ) { // make a copy, we don't want to modify arguments options = $.extend( {}, options ); - var target = $( options.of ), - within = $( options.within || window ), + 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, - basePosition; + offsets = {}; 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: targetElem.pageY, left: targetElem.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 @@ -99,13 +128,13 @@ $.fn.position = function( options ) { if ( pos.length === 1) { pos = rhorizontal.test( pos[ 0 ] ) ? - pos.concat( [ center ] ) : + pos.concat( [ "center" ] ) : rvertical.test( pos[ 0 ] ) ? - [ center ].concat( pos ) : - [ center, center ]; + [ "center" ].concat( pos ) : + [ "center", "center" ]; } - pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : center; - pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : center; + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; // calculate offsets horizontalOffset = roffset.exec( pos[ 0 ] ); @@ -129,54 +158,41 @@ $.fn.position = function( options ) { if ( options.at[ 0 ] === "right" ) { basePosition.left += targetWidth; - } else if ( options.at[ 0 ] === center ) { + } else if ( options.at[ 0 ] === "center" ) { basePosition.left += targetWidth / 2; } if ( options.at[ 1 ] === "bottom" ) { basePosition.top += targetHeight; - } else if ( options.at[ 1 ] === center ) { + } else if ( options.at[ 1 ] === "center" ) { basePosition.top += targetHeight / 2; } - 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 ) - ]; + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); basePosition.left += atOffset[ 0 ]; basePosition.top += atOffset[ 1 ]; return this.each(function() { - var elem = $( this ), + var collisionPosition, using, + elem = $( this ), elemWidth = elem.outerWidth(), elemHeight = elem.outerHeight(), - marginLeft = parseInt( $.css( this, "marginLeft" ), 10 ) || 0, - marginTop = parseInt( $.css( this, "marginTop" ), 10 ) || 0, - scrollInfo = $.position.getScrollInfo( within ), - collisionWidth = elemWidth + marginLeft + - ( parseInt( $.css( this, "marginRight" ), 10 ) || 0 ) + scrollInfo.width, - collisionHeight = elemHeight + marginTop + - ( parseInt( $.css( this, "marginBottom" ), 10 ) || 0 ) + 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 = [ - 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; + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); if ( options.my[ 0 ] === "right" ) { position.left -= elemWidth; - } else if ( options.my[ 0 ] === center ) { + } else if ( options.my[ 0 ] === "center" ) { position.left -= elemWidth / 2; } if ( options.my[ 1 ] === "bottom" ) { position.top -= elemHeight; - } else if ( options.my[ 1 ] === center ) { + } else if ( options.my[ 1 ] === "center" ) { position.top -= elemHeight / 2; } @@ -185,8 +201,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 = { @@ -216,7 +232,48 @@ $.fn.position = function( options ) { if ( $.fn.bgiframe ) { elem.bgiframe(); } - elem.offset( $.extend( position, { using: options.using } ) ); + + if ( options.using ) { + // adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); }); }; @@ -224,10 +281,8 @@ $.ui.position = { fit: { left: function( position, data ) { var within = data.within, - win = $( window ), - isWindow = $.isWindow( data.within[0] ), - withinOffset = isWindow ? win.scrollLeft() : within.offset().left, - outerWidth = isWindow ? win.width() : within.outerWidth(), + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, collisionPosLeft = position.left - data.collisionPosition.marginLeft, overLeft = withinOffset - collisionPosLeft, overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, @@ -259,15 +314,13 @@ $.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 ) { var within = data.within, - win = $( window ), - isWindow = $.isWindow( data.within[0] ), - withinOffset = isWindow ? win.scrollTop() : within.offset().top, - outerHeight = isWindow ? win.height() : within.outerHeight(), + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, collisionPosTop = position.top - data.collisionPosition.marginTop, overTop = withinOffset - collisionPosTop, overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, @@ -299,25 +352,20 @@ $.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 ); } } }, flip: { left: function( position, data ) { - if ( data.at[ 0 ] === center ) { + if ( data.at[ 0 ] === "center" ) { return; } - data.elem - .removeClass( "ui-flipped-left ui-flipped-right" ); - var within = data.within, - win = $( window ), - isWindow = $.isWindow( data.within[0] ), - withinOffset = ( isWindow ? 0 : within.offset().left ) + within.scrollLeft(), - outerWidth = isWindow ? within.width() : within.outerWidth(), - offsetLeft = isWindow ? 0 : within.offset().left, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? 0 : within.offset.left, collisionPosLeft = position.left - data.collisionPosition.marginLeft, overLeft = collisionPosLeft - offsetLeft, overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, @@ -336,37 +384,26 @@ $.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" ); - + 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 ) { - data.elem - .addClass( "ui-flipped-left" ); - + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { position.left += myOffset + atOffset + offset; } } }, top: function( position, data ) { - if ( data.at[ 1 ] === center ) { + if ( data.at[ 1 ] === "center" ) { return; } - data.elem - .removeClass( "ui-flipped-top ui-flipped-bottom" ); - var within = data.within, - win = $( window ), - isWindow = $.isWindow( data.within[0] ), - withinOffset = ( isWindow ? 0 : within.offset().top ) + within.scrollTop(), - outerHeight = isWindow ? within.height() : within.outerHeight(), - offsetTop = isWindow ? 0 : within.offset().top, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? 0 : within.offset.top, collisionPosTop = position.top - data.collisionPosition.marginTop, overTop = collisionPosTop - offsetTop, overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, @@ -384,19 +421,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 ) ) ) { - data.elem - .addClass( "ui-flipped-bottom" ); - + 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 ) ) { - data.elem - .addClass( "ui-flipped-top" ); - + if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { position.top += myOffset + atOffset + offset; } } 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 |