2 * jQuery UI Position 1.8.2
4 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
5 * Dual licensed under the MIT (MIT-LICENSE.txt)
6 * and GPL (GPL-LICENSE.txt) licenses.
8 * http://docs.jquery.com/UI/Position
14 var horizontalPositions
= /left|center|right/,
15 horizontalDefault
= "center",
16 verticalPositions
= /top|center|bottom/,
17 verticalDefault
= "center",
18 _position
= $.fn
.position
,
19 _offset
= $.fn
.offset
;
21 $.fn
.position = function( options
) {
22 if ( !options
|| !options
.of ) {
23 return _position
.apply( this, arguments
);
26 // make a copy, we don't want to modify arguments
27 options
= $.extend( {}, options
);
29 var target
= $( options
.of ),
30 collision
= ( options
.collision
|| "flip" ).split( " " ),
31 offset
= options
.offset
? options
.offset
.split( " " ) : [ 0, 0 ],
36 if ( options
.of.nodeType
=== 9 ) {
37 targetWidth
= target
.width();
38 targetHeight
= target
.height();
39 basePosition
= { top
: 0, left
: 0 };
40 } else if ( options
.of.scrollTo
&& options
.of.document
) {
41 targetWidth
= target
.width();
42 targetHeight
= target
.height();
43 basePosition
= { top
: target
.scrollTop(), left
: target
.scrollLeft() };
44 } else if ( options
.of.preventDefault
) {
45 // force left top to allow flipping
46 options
.at
= "left top";
47 targetWidth
= targetHeight
= 0;
48 basePosition
= { top
: options
.of.pageY
, left
: options
.of.pageX
};
50 targetWidth
= target
.outerWidth();
51 targetHeight
= target
.outerHeight();
52 basePosition
= target
.offset();
55 // force my and at to have valid horizontal and veritcal positions
56 // if a value is missing or invalid, it will be converted to center
57 $.each( [ "my", "at" ], function() {
58 var pos
= ( options
[this] || "" ).split( " " );
59 if ( pos
.length
=== 1) {
60 pos
= horizontalPositions
.test( pos
[0] ) ?
61 pos
.concat( [verticalDefault
] ) :
62 verticalPositions
.test( pos
[0] ) ?
63 [ horizontalDefault
].concat( pos
) :
64 [ horizontalDefault
, verticalDefault
];
66 pos
[ 0 ] = horizontalPositions
.test( pos
[0] ) ? pos
[ 0 ] : horizontalDefault
;
67 pos
[ 1 ] = verticalPositions
.test( pos
[1] ) ? pos
[ 1 ] : verticalDefault
;
68 options
[ this ] = pos
;
71 // normalize collision option
72 if ( collision
.length
=== 1 ) {
73 collision
[ 1 ] = collision
[ 0 ];
76 // normalize offset option
77 offset
[ 0 ] = parseInt( offset
[0], 10 ) || 0;
78 if ( offset
.length
=== 1 ) {
79 offset
[ 1 ] = offset
[ 0 ];
81 offset
[ 1 ] = parseInt( offset
[1], 10 ) || 0;
83 if ( options
.at
[0] === "right" ) {
84 basePosition
.left
+= targetWidth
;
85 } else if (options
.at
[0] === horizontalDefault
) {
86 basePosition
.left
+= targetWidth
/ 2;
89 if ( options
.at
[1] === "bottom" ) {
90 basePosition
.top
+= targetHeight
;
91 } else if ( options
.at
[1] === verticalDefault
) {
92 basePosition
.top
+= targetHeight
/ 2;
95 basePosition
.left
+= offset
[ 0 ];
96 basePosition
.top
+= offset
[ 1 ];
98 return this.each(function() {
100 elemWidth
= elem
.outerWidth(),
101 elemHeight
= elem
.outerHeight(),
102 position
= $.extend( {}, basePosition
);
104 if ( options
.my
[0] === "right" ) {
105 position
.left
-= elemWidth
;
106 } else if ( options
.my
[0] === horizontalDefault
) {
107 position
.left
-= elemWidth
/ 2;
110 if ( options
.my
[1] === "bottom" ) {
111 position
.top
-= elemHeight
;
112 } else if ( options
.my
[1] === verticalDefault
) {
113 position
.top
-= elemHeight
/ 2;
116 // prevent fractions (see #5280)
117 position
.left
= parseInt( position
.left
);
118 position
.top
= parseInt( position
.top
);
120 $.each( [ "left", "top" ], function( i
, dir
) {
121 if ( $.ui
.position
[ collision
[i
] ] ) {
122 $.ui
.position
[ collision
[i
] ][ dir
]( position
, {
123 targetWidth
: targetWidth
,
124 targetHeight
: targetHeight
,
125 elemWidth
: elemWidth
,
126 elemHeight
: elemHeight
,
134 if ( $.fn
.bgiframe
) {
137 elem
.offset( $.extend( position
, { using
: options
.using
} ) );
143 left: function( position
, data
) {
144 var win
= $( window
),
145 over
= position
.left
+ data
.elemWidth
- win
.width() - win
.scrollLeft();
146 position
.left
= over
> 0 ? position
.left
- over
: Math
.max( 0, position
.left
);
148 top: function( position
, data
) {
149 var win
= $( window
),
150 over
= position
.top
+ data
.elemHeight
- win
.height() - win
.scrollTop();
151 position
.top
= over
> 0 ? position
.top
- over
: Math
.max( 0, position
.top
);
156 left: function( position
, data
) {
157 if ( data
.at
[0] === "center" ) {
160 var win
= $( window
),
161 over
= position
.left
+ data
.elemWidth
- win
.width() - win
.scrollLeft(),
162 myOffset
= data
.my
[ 0 ] === "left" ?
164 data
.my
[ 0 ] === "right" ?
167 offset
= -2 * data
.offset
[ 0 ];
168 position
.left
+= position
.left
< 0 ?
169 myOffset
+ data
.targetWidth
+ offset
:
171 myOffset
- data
.targetWidth
+ offset
:
174 top: function( position
, data
) {
175 if ( data
.at
[1] === "center" ) {
178 var win
= $( window
),
179 over
= position
.top
+ data
.elemHeight
- win
.height() - win
.scrollTop(),
180 myOffset
= data
.my
[ 1 ] === "top" ?
182 data
.my
[ 1 ] === "bottom" ?
185 atOffset
= data
.at
[ 1 ] === "top" ?
188 offset
= -2 * data
.offset
[ 1 ];
189 position
.top
+= position
.top
< 0 ?
190 myOffset
+ data
.targetHeight
+ offset
:
192 myOffset
+ atOffset
+ offset
:
198 // offset setter from jQuery 1.4
199 if ( !$.offset
.setOffset
) {
200 $.offset
.setOffset = function( elem
, options
) {
201 // set position first, in-case top/left are set even on static elem
202 if ( /static/.test( $.curCSS( elem
, "position" ) ) ) {
203 elem
.style
.position
= "relative";
205 var curElem
= $( elem
),
206 curOffset
= curElem
.offset(),
207 curTop
= parseInt( $.curCSS( elem
, "top", true ), 10 ) || 0,
208 curLeft
= parseInt( $.curCSS( elem
, "left", true ), 10) || 0,
210 top
: (options
.top
- curOffset
.top
) + curTop
,
211 left
: (options
.left
- curOffset
.left
) + curLeft
214 if ( 'using' in options
) {
215 options
.using
.call( elem
, props
);
217 curElem
.css( props
);
221 $.fn
.offset = function( options
) {
222 var elem
= this[ 0 ];
223 if ( !elem
|| !elem
.ownerDocument
) { return null; }
225 return this.each(function() {
226 $.offset
.setOffset( this, options
);
229 return _offset
.call( this );