aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/tooltip/custom-style.html101
-rw-r--r--tests/unit/position/position.html2
-rw-r--r--tests/unit/position/position_core.js91
-rw-r--r--tests/visual/position/position.html20
-rw-r--r--tests/visual/position/position_feedback.html146
-rw-r--r--tests/visual/position/position_feedback_rotate.html109
-rw-r--r--tests/visual/position/position_fit.html1
-rw-r--r--tests/visual/position/position_flip.html1
-rw-r--r--tests/visual/position/position_flipfit.html1
-rw-r--r--tests/visual/position/position_margin.html1
-rw-r--r--tests/visual/position/position_within.html2
-rw-r--r--themes/base/jquery.ui.tooltip.css2
-rw-r--r--ui/jquery.ui.position.js231
-rw-r--r--ui/jquery.ui.tooltip.js2
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