50dd57f0e3eee21821d10dc0a9db3e1c02665795
[lhc/web/wiklou.git] / resources / jquery.ui / jquery.ui.position.js
1 /*
2 * jQuery UI Position 1.8.2
3 *
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.
7 *
8 * http://docs.jquery.com/UI/Position
9 */
10 (function( $ ) {
11
12 $.ui = $.ui || {};
13
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;
20
21 $.fn.position = function( options ) {
22 if ( !options || !options.of ) {
23 return _position.apply( this, arguments );
24 }
25
26 // make a copy, we don't want to modify arguments
27 options = $.extend( {}, options );
28
29 var target = $( options.of ),
30 collision = ( options.collision || "flip" ).split( " " ),
31 offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
32 targetWidth,
33 targetHeight,
34 basePosition;
35
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 };
49 } else {
50 targetWidth = target.outerWidth();
51 targetHeight = target.outerHeight();
52 basePosition = target.offset();
53 }
54
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 ];
65 }
66 pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : horizontalDefault;
67 pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : verticalDefault;
68 options[ this ] = pos;
69 });
70
71 // normalize collision option
72 if ( collision.length === 1 ) {
73 collision[ 1 ] = collision[ 0 ];
74 }
75
76 // normalize offset option
77 offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
78 if ( offset.length === 1 ) {
79 offset[ 1 ] = offset[ 0 ];
80 }
81 offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
82
83 if ( options.at[0] === "right" ) {
84 basePosition.left += targetWidth;
85 } else if (options.at[0] === horizontalDefault ) {
86 basePosition.left += targetWidth / 2;
87 }
88
89 if ( options.at[1] === "bottom" ) {
90 basePosition.top += targetHeight;
91 } else if ( options.at[1] === verticalDefault ) {
92 basePosition.top += targetHeight / 2;
93 }
94
95 basePosition.left += offset[ 0 ];
96 basePosition.top += offset[ 1 ];
97
98 return this.each(function() {
99 var elem = $( this ),
100 elemWidth = elem.outerWidth(),
101 elemHeight = elem.outerHeight(),
102 position = $.extend( {}, basePosition );
103
104 if ( options.my[0] === "right" ) {
105 position.left -= elemWidth;
106 } else if ( options.my[0] === horizontalDefault ) {
107 position.left -= elemWidth / 2;
108 }
109
110 if ( options.my[1] === "bottom" ) {
111 position.top -= elemHeight;
112 } else if ( options.my[1] === verticalDefault ) {
113 position.top -= elemHeight / 2;
114 }
115
116 // prevent fractions (see #5280)
117 position.left = parseInt( position.left );
118 position.top = parseInt( position.top );
119
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,
127 offset: offset,
128 my: options.my,
129 at: options.at
130 });
131 }
132 });
133
134 if ( $.fn.bgiframe ) {
135 elem.bgiframe();
136 }
137 elem.offset( $.extend( position, { using: options.using } ) );
138 });
139 };
140
141 $.ui.position = {
142 fit: {
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 );
147 },
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 );
152 }
153 },
154
155 flip: {
156 left: function( position, data ) {
157 if ( data.at[0] === "center" ) {
158 return;
159 }
160 var win = $( window ),
161 over = position.left + data.elemWidth - win.width() - win.scrollLeft(),
162 myOffset = data.my[ 0 ] === "left" ?
163 -data.elemWidth :
164 data.my[ 0 ] === "right" ?
165 data.elemWidth :
166 0,
167 offset = -2 * data.offset[ 0 ];
168 position.left += position.left < 0 ?
169 myOffset + data.targetWidth + offset :
170 over > 0 ?
171 myOffset - data.targetWidth + offset :
172 0;
173 },
174 top: function( position, data ) {
175 if ( data.at[1] === "center" ) {
176 return;
177 }
178 var win = $( window ),
179 over = position.top + data.elemHeight - win.height() - win.scrollTop(),
180 myOffset = data.my[ 1 ] === "top" ?
181 -data.elemHeight :
182 data.my[ 1 ] === "bottom" ?
183 data.elemHeight :
184 0,
185 atOffset = data.at[ 1 ] === "top" ?
186 data.targetHeight :
187 -data.targetHeight,
188 offset = -2 * data.offset[ 1 ];
189 position.top += position.top < 0 ?
190 myOffset + data.targetHeight + offset :
191 over > 0 ?
192 myOffset + atOffset + offset :
193 0;
194 }
195 }
196 };
197
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";
204 }
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,
209 props = {
210 top: (options.top - curOffset.top) + curTop,
211 left: (options.left - curOffset.left) + curLeft
212 };
213
214 if ( 'using' in options ) {
215 options.using.call( elem, props );
216 } else {
217 curElem.css( props );
218 }
219 };
220
221 $.fn.offset = function( options ) {
222 var elem = this[ 0 ];
223 if ( !elem || !elem.ownerDocument ) { return null; }
224 if ( options ) {
225 return this.each(function() {
226 $.offset.setOffset( this, options );
227 });
228 }
229 return _offset.call( this );
230 };
231 }
232
233 }( jQuery ));