offset is now a setter
[jquery.git] / test / unit / offset.js
1 module("offset");
2
3 testoffset("absolute", function( jQuery ) {
4         // get offset tests
5         var tests = [
6                 { id: '#absolute-1',     top:  1, left:  1 }, 
7                 { id: '#absolute-1-1',   top:  5, left:  5 },
8                 { id: '#absolute-1-1-1', top:  9, left:  9 },
9                 { id: '#absolute-2',     top: 20, left: 20 }
10         ];
11         jQuery.each( tests, function() {
12                 equals( jQuery( this.id ).offset().top,  this.top,  "jQuery('" + this.id + "').offset().top" );
13                 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
14         });
15         
16         
17         // get position
18         tests = [
19                 { id: '#absolute-1',     top:  0, left:  0 },
20                 { id: '#absolute-1-1',   top:  1, left:  1 },
21                 { id: '#absolute-1-1-1', top:  1, left:  1 },
22                 { id: '#absolute-2',     top: 19, left: 19 }
23         ];
24         jQuery.each( tests, function() {
25                 equals( jQuery( this.id ).position().top,  this.top,  "jQuery('" + this.id + "').position().top" );
26                 equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
27         });
28         
29         
30         // set offset
31         tests = [
32                 { id: '#absolute-2',     top: 30, left: 30 },
33                 { id: '#absolute-2',     top: 10, left: 10 },
34                 { id: '#absolute-2',     top: -1, left: -1 },
35                 { id: '#absolute-2',     top: 19, left: 19 },
36                 { id: '#absolute-1-1-1', top: 15, left: 15 },
37                 { id: '#absolute-1-1-1', top:  5, left:  5 },
38                 { id: '#absolute-1-1-1', top: -1, left: -1 },
39                 { id: '#absolute-1-1-1', top:  9, left:  9 },
40                 { id: '#absolute-1-1',   top: 10, left: 10 },
41                 { id: '#absolute-1-1',   top:  0, left:  0 },
42                 { id: '#absolute-1-1',   top: -1, left: -1 },
43                 { id: '#absolute-1-1',   top:  5, left:  5 },
44                 { id: '#absolute-1',     top:  2, left:  2 },
45                 { id: '#absolute-1',     top:  0, left:  0 },
46                 { id: '#absolute-1',     top: -1, left: -1 },
47                 { id: '#absolute-1',     top:  1, left:  1 }
48         ];
49         jQuery.each( tests, function() {
50                 jQuery( this.id ).offset({ top: this.top, left: this.left });
51                 equals( jQuery( this.id ).offset().top,  this.top,  "jQuery('" + this.id + "').offset({ top: "  + this.top  + " })" );
52                 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
53                 
54                 jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
55                         jQuery( this ).css({
56                                 top:  props.top  + 1,
57                                 left: props.left + 1
58                         });
59                 }});
60                 equals( jQuery( this.id ).offset().top,  this.top  + 1, "jQuery('" + this.id + "').offset({ top: "  + (this.top  + 1) + ", using: fn })" );
61                 equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
62         });
63 });
64
65 testoffset("relative", function( jQuery ) {
66         // IE is collapsing the top margin of 1px
67         var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8;
68         
69         // get offset
70         var tests = [
71                 { id: '#relative-1',   top: ie ?   6 :   7, left:  7 },
72                 { id: '#relative-1-1', top: ie ?  13 :  15, left: 15 },
73                 { id: '#relative-2',   top: ie ? 141 : 142, left: 27 }
74         ];
75         jQuery.each( tests, function() {
76                 equals( jQuery( this.id ).offset().top,  this.top,  "jQuery('" + this.id + "').offset().top" );
77                 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
78         });
79         
80         
81         // get position
82         tests = [
83                 { id: '#relative-1',   top: ie ?   5 :   6, left:  6 },
84                 { id: '#relative-1-1', top: ie ?   4 :   5, left:  5 },
85                 { id: '#relative-2',   top: ie ? 140 : 141, left: 26 }
86         ];
87         jQuery.each( tests, function() {
88                 equals( jQuery( this.id ).position().top,  this.top,  "jQuery('" + this.id + "').position().top" );
89                 equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
90         });
91         
92         
93         // set offset
94         tests = [
95                 { id: '#relative-2',   top: 200, left:  50 },
96                 { id: '#relative-2',   top: 100, left:  10 },
97                 { id: '#relative-2',   top:  -5, left:  -5 },
98                 { id: '#relative-2',   top: 142, left:  27 },
99                 { id: '#relative-1-1', top: 100, left: 100 },
100                 { id: '#relative-1-1', top:   5, left:   5 },
101                 { id: '#relative-1-1', top:  -1, left:  -1 },
102                 { id: '#relative-1-1', top:  15, left:  15 },
103                 { id: '#relative-1',   top: 100, left: 100 },
104                 { id: '#relative-1',   top:   0, left:   0 },
105                 { id: '#relative-1',   top:  -1, left:  -1 },
106                 { id: '#relative-1',   top:   7, left:   7 }
107         ];
108         jQuery.each( tests, function() {
109                 jQuery( this.id ).offset({ top: this.top, left: this.left });
110                 equals( jQuery( this.id ).offset().top,  this.top,  "jQuery('" + this.id + "').offset({ top: "  + this.top  + " })" );
111                 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
112                 
113                 jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
114                         jQuery( this ).css({
115                                 top:  props.top  + 1,
116                                 left: props.left + 1
117                         });
118                 }});
119                 equals( jQuery( this.id ).offset().top,  this.top  + 1, "jQuery('" + this.id + "').offset({ top: "  + (this.top  + 1) + ", using: fn })" );
120                 equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
121         });
122 });
123
124 testoffset("static", function( jQuery ) {
125         // IE is collapsing the top margin of 1px
126         var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8;
127         
128         // get offset
129         var tests = [
130                 { id: '#static-1',     top: ie ?   6 :   7, left:  7 },
131                 { id: '#static-1-1',   top: ie ?  13 :  15, left: 15 },
132                 { id: '#static-1-1-1', top: ie ?  20 :  23, left: 23 },
133                 { id: '#static-2',     top: ie ? 121 : 122, left:  7 }
134         ];
135         jQuery.each( tests, function() {
136                 equals( jQuery( this.id ).offset().top,  this.top,  "jQuery('" + this.id + "').offset().top" );
137                 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
138         });
139         
140         
141         // get position
142         tests = [
143                 { id: '#static-1',     top: ie ?   5 :   6, left:  6 },
144                 { id: '#static-1-1',   top: ie ?  12 :  14, left: 14 },
145                 { id: '#static-1-1-1', top: ie ?  19 :  22, left: 22 },
146                 { id: '#static-2',     top: ie ? 120 : 121, left:  6 }
147         ];
148         jQuery.each( tests, function() {
149                 equals( jQuery( this.id ).position().top,  this.top,  "jQuery('" + this.top  + "').position().top" );
150                 equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.left +"').position().left" );
151         });
152         
153         
154         // set offset
155         tests = [
156                 { id: '#static-2',     top: 200, left: 200 },
157                 { id: '#static-2',     top: 100, left: 100 },
158                 { id: '#static-2',     top:  -2, left:  -2 },
159                 { id: '#static-2',     top: 121, left:   6 },
160                 { id: '#static-1-1-1', top:  50, left:  50 },
161                 { id: '#static-1-1-1', top:  10, left:  10 },
162                 { id: '#static-1-1-1', top:  -1, left:  -1 },
163                 { id: '#static-1-1-1', top:  22, left:  22 },
164                 { id: '#static-1-1',   top:  25, left:  25 },
165                 { id: '#static-1-1',   top:  10, left:  10 },
166                 { id: '#static-1-1',   top:  -3, left:  -3 },
167                 { id: '#static-1-1',   top:  14, left:  14 },
168                 { id: '#static-1',     top:  30, left:  30 },
169                 { id: '#static-1',     top:   2, left:   2 },
170                 { id: '#static-1',     top:  -2, left:  -2 },
171                 { id: '#static-1',     top:   7, left:   7 }
172         ];
173         jQuery.each( tests, function() {
174                 jQuery( this.id ).offset({ top: this.top, left: this.left });
175                 equals( jQuery( this.id ).offset().top,  this.top,  "jQuery('" + this.id + "').offset({ top: "  + this.top  + " })" );
176                 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
177                 
178                 jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
179                         jQuery( this ).css({
180                                 top:  props.top  + 1,
181                                 left: props.left + 1
182                         });
183                 }});
184                 equals( jQuery( this.id ).offset().top,  this.top  + 1, "jQuery('" + this.id + "').offset({ top: "  + (this.top  + 1) + ", using: fn })" );
185                 equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
186         });
187 });
188
189 testoffset("fixed", function( jQuery ) {
190         jQuery.offset.initialize();
191         
192         var tests = [
193                 { id: '#fixed-1', top: 1001, left: 1001 },
194                 { id: '#fixed-2', top: 1021, left: 1021 }
195         ];
196         jQuery.each( tests, function() {
197                 if ( jQuery.offset.supportsFixedPosition ) {
198                         equals( jQuery( this.id ).offset().top,  this.top,  "jQuery('" + this.id + "').offset().top" );
199                         equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
200                 } else {
201                         // need to have same number of assertions
202                         ok( true, 'Fixed position is not supported' );
203                         ok( true, 'Fixed position is not supported' );
204                 }
205         });
206         
207         tests = [
208                 { id: '#fixed-1', top: 100, left: 100 },
209                 { id: '#fixed-1', top:   0, left:   0 },
210                 { id: '#fixed-1', top:  -4, left:  -4 },
211                 { id: '#fixed-2', top: 200, left: 200 },
212                 { id: '#fixed-2', top:   0, left:   0 },
213                 { id: '#fixed-2', top:  -5, left:  -5 }
214         ];
215         
216         jQuery.each( tests, function() {
217                 if ( jQuery.offset.supportsFixedPosition ) {
218                         jQuery( this.id ).offset({ top: this.top, left: this.left });
219                         equals( jQuery( this.id ).offset().top,  this.top,  "jQuery('" + this.id + "').offset({ top: "  + this.top  + " })" );
220                         equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
221                 
222                         jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
223                                 jQuery( this ).css({
224                                         top:  props.top  + 1,
225                                         left: props.left + 1
226                                 });
227                         }});
228                         equals( jQuery( this.id ).offset().top,  this.top  + 1, "jQuery('" + this.id + "').offset({ top: "  + (this.top  + 1) + ", using: fn })" );
229                         equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
230                 } else {
231                         // need to have same number of assertions
232                         ok( true, 'Fixed position is not supported' );
233                         ok( true, 'Fixed position is not supported' );
234                         ok( true, 'Fixed position is not supported' );
235                         ok( true, 'Fixed position is not supported' );
236                 }
237         });
238 });
239
240 testoffset("table", function( jQuery ) {
241         var ie = jQuery.browser.msie;
242         
243         equals( jQuery('#table-1').offset().top, 6, "jQuery('#table-1').offset().top" );
244         equals( jQuery('#table-1').offset().left, 6, "jQuery('#table-1').offset().left" );
245         
246         equals( jQuery('#th-1').offset().top, 10, "jQuery('#th-1').offset().top" );
247         equals( jQuery('#th-1').offset().left, 10, "jQuery('#th-1').offset().left" );
248         
249         // equals( jQuery('#th-2').offset().top, 10, "jQuery('#th-2').offset().top" );
250         // equals( jQuery('#th-2').offset().left, 116, "jQuery('#th-2').offset().left" );
251         // 
252         // equals( jQuery('#th-3').offset().top, 10, "jQuery('#th-3').offset().top" );
253         // equals( jQuery('#th-3').offset().left, 222, "jQuery('#th-3').offset().left" );
254         
255         // equals( jQuery('#td-1').offset().top, ie ? 116 : 112, "jQuery('#td-1').offset().top" );
256         // equals( jQuery('#td-1').offset().left, 10, "jQuery('#td-1').offset().left" );
257         // 
258         // equals( jQuery('#td-2').offset().top, ie ? 116 : 112, "jQuery('#td-2').offset().top" );
259         // equals( jQuery('#td-2').offset().left, 116, "jQuery('#td-2').offset().left" );
260         // 
261         // equals( jQuery('#td-3').offset().top, ie ? 116 : 112, "jQuery('#td-3').offset().top" );
262         // equals( jQuery('#td-3').offset().left, 222, "jQuery('#td-3').offset().left" );
263 });
264
265 testoffset("scroll", function( jQuery, win ) {
266         var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8;
267         
268         // IE is collapsing the top margin of 1px
269         equals( jQuery('#scroll-1').offset().top, ie ? 6 : 7, "jQuery('#scroll-1').offset().top" );
270         equals( jQuery('#scroll-1').offset().left, 7, "jQuery('#scroll-1').offset().left" );
271         
272         // IE is collapsing the top margin of 1px
273         equals( jQuery('#scroll-1-1').offset().top, ie ? 9 : 11, "jQuery('#scroll-1-1').offset().top" );
274         equals( jQuery('#scroll-1-1').offset().left, 11, "jQuery('#scroll-1-1').offset().left" );
275         
276         
277         // scroll offset tests .scrollTop/Left
278         equals( jQuery('#scroll-1').scrollTop(), 5, "jQuery('#scroll-1').scrollTop()" );
279         equals( jQuery('#scroll-1').scrollLeft(), 5, "jQuery('#scroll-1').scrollLeft()" );
280         
281         equals( jQuery('#scroll-1-1').scrollTop(), 0, "jQuery('#scroll-1-1').scrollTop()" );
282         equals( jQuery('#scroll-1-1').scrollLeft(), 0, "jQuery('#scroll-1-1').scrollLeft()" );
283         
284         // equals( jQuery('body').scrollTop(), 0, "jQuery('body').scrollTop()" );
285         // equals( jQuery('body').scrollLeft(), 0, "jQuery('body').scrollTop()" );
286         
287         win.name = "test";
288         
289         equals( jQuery(win).scrollTop(), 1000, "jQuery(window).scrollTop()" );
290         equals( jQuery(win).scrollLeft(), 1000, "jQuery(window).scrollLeft()" );
291         
292         equals( jQuery(win.document).scrollTop(), 1000, "jQuery(document).scrollTop()" );
293         equals( jQuery(win.document).scrollLeft(), 1000, "jQuery(document).scrollLeft()" );
294 });
295
296 testoffset("body", function( jQuery ) {
297         equals( jQuery('body').offset().top, 1, "jQuery('#body').offset().top" );
298         equals( jQuery('body').offset().left, 1, "jQuery('#body').offset().left" );
299 });
300
301 test("offsetParent", function(){
302         expect(11);
303
304         var body = jQuery("body").offsetParent();
305         equals( body.length, 1, "Only one offsetParent found." );
306         equals( body[0], document.body, "The body is its own offsetParent." );
307
308         var header = jQuery("#header").offsetParent();
309         equals( header.length, 1, "Only one offsetParent found." );
310         equals( header[0], document.body, "The body is the offsetParent." );
311
312         var div = jQuery("#nothiddendivchild").offsetParent();
313         equals( div.length, 1, "Only one offsetParent found." );
314         equals( div[0], document.body, "The body is the offsetParent." );
315
316         jQuery("#nothiddendiv").css("position", "relative");
317
318         div = jQuery("#nothiddendivchild").offsetParent();
319         equals( div.length, 1, "Only one offsetParent found." );
320         equals( div[0], jQuery("#nothiddendiv")[0], "The div is the offsetParent." );
321
322         div = jQuery("body, #nothiddendivchild").offsetParent();
323         equals( div.length, 2, "Two offsetParent found." );
324         equals( div[0], document.body, "The body is the offsetParent." );
325         equals( div[1], jQuery("#nothiddendiv")[0], "The div is the offsetParent." );
326 });
327
328 function testoffset(name, fn) {
329         
330         test(name, function() {
331                 // pause execution for now
332                 stop();
333                 
334                 // load fixture in iframe
335                 var iframe = loadFixture(),
336                         win = iframe.contentWindow,
337                         interval = setInterval( function() {
338                                 if ( win && win.jQuery && win.jQuery.isReady ) {
339                                         clearInterval( interval );
340                                         // continue
341                                         start();
342                                         // call actual tests passing the correct jQuery isntance to use
343                                         fn.call( this, win.jQuery, win );
344                                         document.body.removeChild( iframe );
345                                         iframe = null;
346                                 }
347                         }, 15 );
348         });
349         
350         function loadFixture() {
351                 var src = './data/offset/' + name + '.html?' + parseInt( Math.random()*1000 ),
352                         iframe = jQuery('<iframe />').css({
353                                 width: 500, height: 500, position: 'absolute', top: -600, left: -600, visiblity: 'hidden'
354                         }).appendTo('body')[0];
355                 iframe.contentWindow.location = src;
356                 return iframe;
357         }
358 }