1 |
(function( $ ) { |
2 |
|
3 |
var win = $( window ), |
4 |
scrollTopSupport = function() { |
5 |
var support = win.scrollTop( 1 ).scrollTop() === 1; |
6 |
win.scrollTop( 0 ); |
7 |
scrollTopSupport = function() { |
8 |
return support; |
9 |
}; |
10 |
return support; |
11 |
}; |
12 |
|
13 |
module( "position", { |
14 |
setup: function() { |
15 |
win.scrollTop( 0 ).scrollLeft( 0 ); |
16 |
} |
17 |
}); |
18 |
|
19 |
TestHelpers.testJshint( "position" ); |
20 |
|
21 |
test( "my, at, of", function() { |
22 |
expect( 4 ); |
23 |
|
24 |
$( "#elx" ).position({ |
25 |
my: "left top", |
26 |
at: "left top", |
27 |
of: "#parentx", |
28 |
collision: "none" |
29 |
}); |
30 |
deepEqual( $( "#elx" ).offset(), { top: 40, left: 40 }, "left top, left top" ); |
31 |
|
32 |
$( "#elx" ).position({ |
33 |
my: "left top", |
34 |
at: "left bottom", |
35 |
of: "#parentx", |
36 |
collision: "none" |
37 |
}); |
38 |
deepEqual( $( "#elx" ).offset(), { top: 60, left: 40 }, "left top, left bottom" ); |
39 |
|
40 |
$( "#elx" ).position({ |
41 |
my: "left", |
42 |
at: "bottom", |
43 |
of: "#parentx", |
44 |
collision: "none" |
45 |
}); |
46 |
deepEqual( $( "#elx" ).offset(), { top: 55, left: 50 }, "left, bottom" ); |
47 |
|
48 |
$( "#elx" ).position({ |
49 |
my: "left foo", |
50 |
at: "bar baz", |
51 |
of: "#parentx", |
52 |
collision: "none" |
53 |
}); |
54 |
deepEqual( $( "#elx" ).offset(), { top: 45, left: 50 }, "left foo, bar baz" ); |
55 |
}); |
56 |
|
57 |
test( "multiple elements", function() { |
58 |
expect( 3 ); |
59 |
|
60 |
var elements = $( "#el1, #el2" ), |
61 |
result = elements.position({ |
62 |
my: "left top", |
63 |
at: "left bottom", |
64 |
of: "#parent", |
65 |
collision: "none" |
66 |
}), |
67 |
expected = { top: 10, left: 4 }; |
68 |
|
69 |
deepEqual( result, elements ); |
70 |
elements.each(function() { |
71 |
deepEqual( $( this ).offset(), expected ); |
72 |
}); |
73 |
}); |
74 |
|
75 |
test( "positions", function() { |
76 |
expect( 18 ); |
77 |
|
78 |
var offsets = { |
79 |
left: 0, |
80 |
center: 3, |
81 |
right: 6, |
82 |
top: 0, |
83 |
bottom: 6 |
84 |
}, |
85 |
start = { left: 4, top: 4 }, |
86 |
el = $( "#el1" ); |
87 |
|
88 |
$.each( [ 0, 1 ], function( my ) { |
89 |
$.each( [ "top", "center", "bottom" ], function( vindex, vertical ) { |
90 |
$.each( [ "left", "center", "right" ], function( hindex, horizontal ) { |
91 |
var _my = my ? horizontal + " " + vertical : "left top", |
92 |
_at = !my ? horizontal + " " + vertical : "left top"; |
93 |
el.position({ |
94 |
my: _my, |
95 |
at: _at, |
96 |
of: "#parent", |
97 |
collision: "none" |
98 |
}); |
99 |
deepEqual( el.offset(), { |
100 |
top: start.top + offsets[ vertical ] * (my ? -1 : 1), |
101 |
left: start.left + offsets[ horizontal ] * (my ? -1 : 1) |
102 |
}, "Position via " + QUnit.jsDump.parse({ my: _my, at: _at }) ); |
103 |
}); |
104 |
}); |
105 |
}); |
106 |
}); |
107 |
|
108 |
test( "of", function() { |
109 |
expect( 9 + (scrollTopSupport() ? 1 : 0) ); |
110 |
|
111 |
var event; |
112 |
|
113 |
$( "#elx" ).position({ |
114 |
my: "left top", |
115 |
at: "left top", |
116 |
of: "#parentx", |
117 |
collision: "none" |
118 |
}); |
119 |
deepEqual( $( "#elx" ).offset(), { top: 40, left: 40 }, "selector" ); |
120 |
|
121 |
$( "#elx" ).position({ |
122 |
my: "left top", |
123 |
at: "left bottom", |
124 |
of: $( "#parentx"), |
125 |
collision: "none" |
126 |
}); |
127 |
deepEqual( $( "#elx" ).offset(), { top: 60, left: 40 }, "jQuery object" ); |
128 |
|
129 |
$( "#elx" ).position({ |
130 |
my: "left top", |
131 |
at: "left top", |
132 |
of: $( "#parentx" )[ 0 ], |
133 |
collision: "none" |
134 |
}); |
135 |
deepEqual( $( "#elx" ).offset(), { top: 40, left: 40 }, "DOM element" ); |
136 |
|
137 |
$( "#elx" ).position({ |
138 |
my: "right bottom", |
139 |
at: "right bottom", |
140 |
of: document, |
141 |
collision: "none" |
142 |
}); |
143 |
deepEqual( $( "#elx" ).offset(), { |
144 |
top: $( document ).height() - 10, |
145 |
left: $( document ).width() - 10 |
146 |
}, "document" ); |
147 |
|
148 |
$( "#elx" ).position({ |
149 |
my: "right bottom", |
150 |
at: "right bottom", |
151 |
of: $( document ), |
152 |
collision: "none" |
153 |
}); |
154 |
deepEqual( $( "#elx" ).offset(), { |
155 |
top: $( document ).height() - 10, |
156 |
left: $( document ).width() - 10 |
157 |
}, "document as jQuery object" ); |
158 |
|
159 |
win.scrollTop( 0 ); |
160 |
|
161 |
$( "#elx" ).position({ |
162 |
my: "right bottom", |
163 |
at: "right bottom", |
164 |
of: window, |
165 |
collision: "none" |
166 |
}); |
167 |
deepEqual( $( "#elx" ).offset(), { |
168 |
top: win.height() - 10, |
169 |
left: win.width() - 10 |
170 |
}, "window" ); |
171 |
|
172 |
$( "#elx" ).position({ |
173 |
my: "right bottom", |
174 |
at: "right bottom", |
175 |
of: win, |
176 |
collision: "none" |
177 |
}); |
178 |
deepEqual( $( "#elx" ).offset(), { |
179 |
top: win.height() - 10, |
180 |
left: win.width() - 10 |
181 |
}, "window as jQuery object" ); |
182 |
|
183 |
if ( scrollTopSupport() ) { |
184 |
win.scrollTop( 500 ).scrollLeft( 200 ); |
185 |
$( "#elx" ).position({ |
186 |
my: "right bottom", |
187 |
at: "right bottom", |
188 |
of: window, |
189 |
collision: "none" |
190 |
}); |
191 |
deepEqual( $( "#elx" ).offset(), { |
192 |
top: win.height() + 500 - 10, |
193 |
left: win.width() + 200 - 10 |
194 |
}, "window, scrolled" ); |
195 |
win.scrollTop( 0 ).scrollLeft( 0 ); |
196 |
} |
197 |
|
198 |
event = $.extend( $.Event( "someEvent" ), { pageX: 200, pageY: 300 } ); |
199 |
$( "#elx" ).position({ |
200 |
my: "left top", |
201 |
at: "left top", |
202 |
of: event, |
203 |
collision: "none" |
204 |
}); |
205 |
deepEqual( $( "#elx" ).offset(), { |
206 |
top: 300, |
207 |
left: 200 |
208 |
}, "event - left top, left top" ); |
209 |
|
210 |
event = $.extend( $.Event( "someEvent" ), { pageX: 400, pageY: 600 } ); |
211 |
$( "#elx" ).position({ |
212 |
my: "left top", |
213 |
at: "right bottom", |
214 |
of: event, |
215 |
collision: "none" |
216 |
}); |
217 |
deepEqual( $( "#elx" ).offset(), { |
218 |
top: 600, |
219 |
left: 400 |
220 |
}, "event - left top, right bottom" ); |
221 |
}); |
222 |
|
223 |
test( "offsets", function() { |
224 |
expect( 9 ); |
225 |
|
226 |
var offset; |
227 |
|
228 |
$( "#elx" ).position({ |
229 |
my: "left top", |
230 |
at: "left+10 bottom+10", |
231 |
of: "#parentx", |
232 |
collision: "none" |
233 |
}); |
234 |
deepEqual( $( "#elx" ).offset(), { top: 70, left: 50 }, "offsets in at" ); |
235 |
|
236 |
$( "#elx" ).position({ |
237 |
my: "left+10 top-10", |
238 |
at: "left bottom", |
239 |
of: "#parentx", |
240 |
collision: "none" |
241 |
}); |
242 |
deepEqual( $( "#elx" ).offset(), { top: 50, left: 50 }, "offsets in my" ); |
243 |
|
244 |
$( "#elx" ).position({ |
245 |
my: "left top", |
246 |
at: "left+50% bottom-10%", |
247 |
of: "#parentx", |
248 |
collision: "none" |
249 |
}); |
250 |
deepEqual( $( "#elx" ).offset(), { top: 58, left: 50 }, "percentage offsets in at" ); |
251 |
|
252 |
$( "#elx" ).position({ |
253 |
my: "left-30% top+50%", |
254 |
at: "left bottom", |
255 |
of: "#parentx", |
256 |
collision: "none" |
257 |
}); |
258 |
deepEqual( $( "#elx" ).offset(), { top: 65, left: 37 }, "percentage offsets in my" ); |
259 |
|
260 |
$( "#elx" ).position({ |
261 |
my: "left-30.001% top+50.0%", |
262 |
at: "left bottom", |
263 |
of: "#parentx", |
264 |
collision: "none" |
265 |
}); |
266 |
offset = $( "#elx" ).offset(); |
267 |
equal( Math.round( offset.top ), 65, "decimal percentage offsets in my" ); |
268 |
equal( Math.round( offset.left ), 37, "decimal percentage offsets in my" ); |
269 |
|
270 |
$( "#elx" ).position({ |
271 |
my: "left+10.4 top-10.6", |
272 |
at: "left bottom", |
273 |
of: "#parentx", |
274 |
collision: "none" |
275 |
}); |
276 |
offset = $( "#elx" ).offset(); |
277 |
equal( Math.round( offset.top ), 49, "decimal offsets in my" ); |
278 |
equal( Math.round( offset.left ), 50, "decimal offsets in my" ); |
279 |
|
280 |
$( "#elx" ).position({ |
281 |
my: "left+right top-left", |
282 |
at: "left-top bottom-bottom", |
283 |
of: "#parentx", |
284 |
collision: "none" |
285 |
}); |
286 |
deepEqual( $( "#elx" ).offset(), { top: 60, left: 40 }, "invalid offsets" ); |
287 |
}); |
288 |
|
289 |
test( "using", function() { |
290 |
expect( 10 ); |
291 |
|
292 |
var count = 0, |
293 |
elems = $( "#el1, #el2" ), |
294 |
of = $( "#parentx" ), |
295 |
expectedPosition = { top: 60, left: 60 }, |
296 |
expectedFeedback = { |
297 |
target: { |
298 |
element: of, |
299 |
width: 20, |
300 |
height: 20, |
301 |
left: 40, |
302 |
top: 40 |
303 |
}, |
304 |
element: { |
305 |
width: 6, |
306 |
height: 6, |
307 |
left: 60, |
308 |
top: 60 |
309 |
}, |
310 |
horizontal: "left", |
311 |
vertical: "top", |
312 |
important: "vertical" |
313 |
}, |
314 |
originalPosition = elems.position({ |
315 |
my: "right bottom", |
316 |
at: "rigt bottom", |
317 |
of: "#parentx", |
318 |
collision: "none" |
319 |
}).offset(); |
320 |
|
321 |
elems.position({ |
322 |
my: "left top", |
323 |
at: "center+10 bottom", |
324 |
of: "#parentx", |
325 |
using: function( position, feedback ) { |
326 |
deepEqual( this, elems[ count ], "correct context for call #" + count ); |
327 |
deepEqual( position, expectedPosition, "correct position for call #" + count ); |
328 |
deepEqual( feedback.element.element[ 0 ], elems[ count ] ); |
329 |
delete feedback.element.element; |
330 |
deepEqual( feedback, expectedFeedback ); |
331 |
count++; |
332 |
} |
333 |
}); |
334 |
|
335 |
elems.each(function() { |
336 |
deepEqual( $( this ).offset(), originalPosition, "elements not moved" ); |
337 |
}); |
338 |
}); |
339 |
|
340 |
function collisionTest( config, result, msg ) { |
341 |
var elem = $( "#elx" ).position( $.extend({ |
342 |
my: "left top", |
343 |
at: "right bottom", |
344 |
of: "#parent" |
345 |
}, config ) ); |
346 |
deepEqual( elem.offset(), result, msg ); |
347 |
} |
348 |
|
349 |
function collisionTest2( config, result, msg ) { |
350 |
collisionTest( $.extend({ |
351 |
my: "right bottom", |
352 |
at: "left top" |
353 |
}, config ), result, msg ); |
354 |
} |
355 |
|
356 |
test( "collision: fit, no collision", function() { |
357 |
expect( 2 ); |
358 |
|
359 |
collisionTest({ |
360 |
collision: "fit" |
361 |
}, { |
362 |
top: 10, |
363 |
left: 10 |
364 |
}, "no offset" ); |
365 |
|
366 |
collisionTest({ |
367 |
collision: "fit", |
368 |
at: "right+2 bottom+3" |
369 |
}, { |
370 |
top: 13, |
371 |
left: 12 |
372 |
}, "with offset" ); |
373 |
}); |
374 |
|
375 |
// Currently failing in IE8 due to the iframe used by TestSwarm |
376 |
if ( !/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ) ) { |
377 |
test( "collision: fit, collision", function() { |
378 |
expect( 2 + (scrollTopSupport() ? 1 : 0) ); |
379 |
|
380 |
collisionTest2({ |
381 |
collision: "fit" |
382 |
}, { |
383 |
top: 0, |
384 |
left: 0 |
385 |
}, "no offset" ); |
386 |
|
387 |
collisionTest2({ |
388 |
collision: "fit", |
389 |
at: "left+2 top+3" |
390 |
}, { |
391 |
top: 0, |
392 |
left: 0 |
393 |
}, "with offset" ); |
394 |
|
395 |
if ( scrollTopSupport() ) { |
396 |
win.scrollTop( 300 ).scrollLeft( 200 ); |
397 |
collisionTest({ |
398 |
collision: "fit" |
399 |
}, { |
400 |
top: 300, |
401 |
left: 200 |
402 |
}, "window scrolled" ); |
403 |
|
404 |
win.scrollTop( 0 ).scrollLeft( 0 ); |
405 |
} |
406 |
}); |
407 |
} |
408 |
|
409 |
test( "collision: flip, no collision", function() { |
410 |
expect( 2 ); |
411 |
|
412 |
collisionTest({ |
413 |
collision: "flip" |
414 |
}, { |
415 |
top: 10, |
416 |
left: 10 |
417 |
}, "no offset" ); |
418 |
|
419 |
collisionTest({ |
420 |
collision: "flip", |
421 |
at: "right+2 bottom+3" |
422 |
}, { |
423 |
top: 13, |
424 |
left: 12 |
425 |
}, "with offset" ); |
426 |
}); |
427 |
|
428 |
test( "collision: flip, collision", function() { |
429 |
expect( 2 ); |
430 |
|
431 |
collisionTest2({ |
432 |
collision: "flip" |
433 |
}, { |
434 |
top: 10, |
435 |
left: 10 |
436 |
}, "no offset" ); |
437 |
|
438 |
collisionTest2({ |
439 |
collision: "flip", |
440 |
at: "left+2 top+3" |
441 |
}, { |
442 |
top: 7, |
443 |
left: 8 |
444 |
}, "with offset" ); |
445 |
}); |
446 |
|
447 |
test( "collision: flipfit, no collision", function() { |
448 |
expect( 2 ); |
449 |
|
450 |
collisionTest({ |
451 |
collision: "flipfit" |
452 |
}, { |
453 |
top: 10, |
454 |
left: 10 |
455 |
}, "no offset" ); |
456 |
|
457 |
collisionTest({ |
458 |
collision: "flipfit", |
459 |
at: "right+2 bottom+3" |
460 |
}, { |
461 |
top: 13, |
462 |
left: 12 |
463 |
}, "with offset" ); |
464 |
}); |
465 |
|
466 |
test( "collision: flipfit, collision", function() { |
467 |
expect( 2 ); |
468 |
|
469 |
collisionTest2({ |
470 |
collision: "flipfit" |
471 |
}, { |
472 |
top: 10, |
473 |
left: 10 |
474 |
}, "no offset" ); |
475 |
|
476 |
collisionTest2({ |
477 |
collision: "flipfit", |
478 |
at: "left+2 top+3" |
479 |
}, { |
480 |
top: 7, |
481 |
left: 8 |
482 |
}, "with offset" ); |
483 |
}); |
484 |
|
485 |
test( "collision: none, no collision", function() { |
486 |
expect( 2 ); |
487 |
|
488 |
collisionTest({ |
489 |
collision: "none" |
490 |
}, { |
491 |
top: 10, |
492 |
left: 10 |
493 |
}, "no offset" ); |
494 |
|
495 |
collisionTest({ |
496 |
collision: "none", |
497 |
at: "right+2 bottom+3" |
498 |
}, { |
499 |
top: 13, |
500 |
left: 12 |
501 |
}, "with offset" ); |
502 |
}); |
503 |
|
504 |
test( "collision: none, collision", function() { |
505 |
expect( 2 ); |
506 |
|
507 |
collisionTest2({ |
508 |
collision: "none" |
509 |
}, { |
510 |
top: -6, |
511 |
left: -6 |
512 |
}, "no offset" ); |
513 |
|
514 |
collisionTest2({ |
515 |
collision: "none", |
516 |
at: "left+2 top+3" |
517 |
}, { |
518 |
top: -3, |
519 |
left: -4 |
520 |
}, "with offset" ); |
521 |
}); |
522 |
|
523 |
test( "collision: fit, with margin", function() { |
524 |
expect( 2 ); |
525 |
|
526 |
$( "#elx" ).css({ |
527 |
marginTop: 6, |
528 |
marginLeft: 4 |
529 |
}); |
530 |
|
531 |
collisionTest({ |
532 |
collision: "fit" |
533 |
}, { |
534 |
top: 10, |
535 |
left: 10 |
536 |
}, "right bottom" ); |
537 |
|
538 |
collisionTest2({ |
539 |
collision: "fit" |
540 |
}, { |
541 |
top: 6, |
542 |
left: 4 |
543 |
}, "left top" ); |
544 |
}); |
545 |
|
546 |
test( "collision: flip, with margin", function() { |
547 |
expect( 3 ); |
548 |
|
549 |
$( "#elx" ).css({ |
550 |
marginTop: 6, |
551 |
marginLeft: 4 |
552 |
}); |
553 |
|
554 |
collisionTest({ |
555 |
collision: "flip" |
556 |
}, { |
557 |
top: 10, |
558 |
left: 10 |
559 |
}, "left top" ); |
560 |
|
561 |
collisionTest2({ |
562 |
collision: "flip" |
563 |
}, { |
564 |
top: 10, |
565 |
left: 10 |
566 |
}, "right bottom" ); |
567 |
|
568 |
collisionTest2({ |
569 |
collision: "flip", |
570 |
my: "left top" |
571 |
}, { |
572 |
top: 0, |
573 |
left: 4 |
574 |
}, "right bottom" ); |
575 |
}); |
576 |
|
577 |
test( "within", function() { |
578 |
expect( 6 ); |
579 |
|
580 |
collisionTest({ |
581 |
within: "#within", |
582 |
collision: "fit" |
583 |
}, { |
584 |
top: 4, |
585 |
left: 2 |
586 |
}, "fit - right bottom" ); |
587 |
|
588 |
collisionTest2({ |
589 |
within: "#within", |
590 |
collision: "fit" |
591 |
}, { |
592 |
top: 2, |
593 |
left: 0 |
594 |
}, "fit - left top" ); |
595 |
|
596 |
collisionTest({ |
597 |
within: "#within", |
598 |
collision: "flip" |
599 |
}, { |
600 |
top: 10, |
601 |
left: -6 |
602 |
}, "flip - right bottom" ); |
603 |
|
604 |
collisionTest2({ |
605 |
within: "#within", |
606 |
collision: "flip" |
607 |
}, { |
608 |
top: 10, |
609 |
left: -6 |
610 |
}, "flip - left top" ); |
611 |
|
612 |
collisionTest({ |
613 |
within: "#within", |
614 |
collision: "flipfit" |
615 |
}, { |
616 |
top: 4, |
617 |
left: 0 |
618 |
}, "flipfit - right bottom" ); |
619 |
|
620 |
collisionTest2({ |
621 |
within: "#within", |
622 |
collision: "flipfit" |
623 |
}, { |
624 |
top: 4, |
625 |
left: 0 |
626 |
}, "flipfit - left top" ); |
627 |
}); |
628 |
|
629 |
test( "with scrollbars", function() { |
630 |
expect( 4 ); |
631 |
|
632 |
$( "#scrollx" ).css({ |
633 |
width: 100, |
634 |
height: 100, |
635 |
left: 0, |
636 |
top: 0 |
637 |
}); |
638 |
|
639 |
collisionTest({ |
640 |
of: "#scrollx", |
641 |
collision: "fit", |
642 |
within: "#scrollx" |
643 |
}, { |
644 |
top: 90, |
645 |
left: 90 |
646 |
}, "visible" ); |
647 |
|
648 |
$( "#scrollx" ).css({ |
649 |
overflow: "scroll" |
650 |
}); |
651 |
|
652 |
var scrollbarInfo = $.position.getScrollInfo( $.position.getWithinInfo( $( "#scrollx" ) ) ); |
653 |
|
654 |
collisionTest({ |
655 |
of: "#scrollx", |
656 |
collision: "fit", |
657 |
within: "#scrollx" |
658 |
}, { |
659 |
top: 90 - scrollbarInfo.height, |
660 |
left: 90 - scrollbarInfo.width |
661 |
}, "scroll" ); |
662 |
|
663 |
$( "#scrollx" ).css({ |
664 |
overflow: "auto" |
665 |
}); |
666 |
|
667 |
collisionTest({ |
668 |
of: "#scrollx", |
669 |
collision: "fit", |
670 |
within: "#scrollx" |
671 |
}, { |
672 |
top: 90, |
673 |
left: 90 |
674 |
}, "auto, no scroll" ); |
675 |
|
676 |
$( "#scrollx" ).css({ |
677 |
overflow: "auto" |
678 |
}).append( $("<div>").height(300).width(300) ); |
679 |
|
680 |
collisionTest({ |
681 |
of: "#scrollx", |
682 |
collision: "fit", |
683 |
within: "#scrollx" |
684 |
}, { |
685 |
top: 90 - scrollbarInfo.height, |
686 |
left: 90 - scrollbarInfo.width |
687 |
}, "auto, with scroll" ); |
688 |
}); |
689 |
|
690 |
test( "fractions", function() { |
691 |
expect( 1 ); |
692 |
|
693 |
$( "#fractions-element" ).position({ |
694 |
my: "left top", |
695 |
at: "left top", |
696 |
of: "#fractions-parent", |
697 |
collision: "none" |
698 |
}); |
699 |
deepEqual( $( "#fractions-element" ).offset(), $( "#fractions-parent" ).offset(), "left top, left top" ); |
700 |
}); |
701 |
|
702 |
test( "bug #5280: consistent results (avoid fractional values)", function() { |
703 |
expect( 1 ); |
704 |
|
705 |
var wrapper = $( "#bug-5280" ), |
706 |
elem = wrapper.children(), |
707 |
offset1 = elem.position({ |
708 |
my: "center", |
709 |
at: "center", |
710 |
of: wrapper, |
711 |
collision: "none" |
712 |
}).offset(), |
713 |
offset2 = elem.position({ |
714 |
my: "center", |
715 |
at: "center", |
716 |
of: wrapper, |
717 |
collision: "none" |
718 |
}).offset(); |
719 |
deepEqual( offset1, offset2 ); |
720 |
}); |
721 |
|
722 |
}( jQuery ) ); |