Project

General

Profile

Download (23.5 KB) Statistics
| Branch: | Tag: | Revision:
1
/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
2
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
3
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
4
 *
5
 * $LastChangedDate: 2007-08-17 14:14:11 -0400 (Fri, 17 Aug 2007) $
6
 * $Rev: 2759 $
7
 *
8
 * Version: 1.1.2
9
 *
10
 * Requires: jQuery 1.1.3+
11
 */
12

    
13
(function($){
14

    
15
// store a copy of the core height and width methods
16
var height = $.fn.height,
17
    width  = $.fn.width;
18

    
19
$.fn.extend({
20
	/**
21
	 * If used on document, returns the document's height (innerHeight).
22
	 * If used on window, returns the viewport's (window) height.
23
	 * See core docs on height() to see what happens when used on an element.
24
	 *
25
	 * @example $("#testdiv").height()
26
	 * @result 200
27
	 *
28
	 * @example $(document).height()
29
	 * @result 800
30
	 *
31
	 * @example $(window).height()
32
	 * @result 400
33
	 *
34
	 * @name height
35
	 * @type Number
36
	 * @cat Plugins/Dimensions
37
	 */
38
	height: function() {
39
		if ( !this[0] ) error();
40
		if ( this[0] == window )
41
			if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) )
42
				return self.innerHeight - (($(document).height() > self.innerHeight) ? getScrollbarWidth() : 0);
43

    
44
			else if ( $.browser.safari )
45
				return self.innerHeight;
46
			else
47
          //return $.boxModel && Math.min(document.documentElement.clientHeight,document.body.clientHeight);
48
      		return $.boxModel && document.documentElement.clientHeight || document.body.clientHeight;
49
		if ( this[0] == document ) 
50
			return Math.max( ($.boxModel && document.documentElement.scrollHeight || document.body.scrollHeight), document.body.offsetHeight );
51
		
52
		return height.apply(this, arguments);
53
	},
54
	
55
	/**
56
	 * If used on document, returns the document's width (innerWidth).
57
	 * If used on window, returns the viewport's (window) width.
58
	 * See core docs on width() to see what happens when used on an element.
59
	 *
60
	 * @example $("#testdiv").width()
61
	 * @result 200
62
	 *
63
	 * @example $(document).width()
64
	 * @result 800
65
	 *
66
	 * @example $(window).width()
67
	 * @result 400
68
	 *
69
	 * @name width
70
	 * @type Number
71
	 * @cat Plugins/Dimensions
72
	 */
73
	width: function() {
74
		if (!this[0]) error();
75
		if ( this[0] == window )
76
			if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) )
77
				return self.innerWidth - (($(document).width() > self.innerWidth) ? getScrollbarWidth() : 0);
78
			else if ( $.browser.safari )
79
				return self.innerWidth;
80
			else
81
                return $.boxModel && document.documentElement.clientWidth || document.body.clientWidth;
82

    
83
		if ( this[0] == document )
84
			if ($.browser.mozilla) {
85
				// mozilla reports scrollWidth and offsetWidth as the same
86
				var scrollLeft = self.pageXOffset;
87
				self.scrollTo(99999999, self.pageYOffset);
88
				var scrollWidth = self.pageXOffset;
89
				self.scrollTo(scrollLeft, self.pageYOffset);
90
				return document.body.offsetWidth + scrollWidth;
91
			}
92
			else 
93
				return Math.max( (($.boxModel && !$.browser.safari) && document.documentElement.scrollWidth || document.body.scrollWidth), document.body.offsetWidth );
94

    
95
		return width.apply(this, arguments);
96
	},
97
	
98
	/**
99
	 * Gets the inner height (excludes the border and includes the padding) for the first matched element.
100
	 * If used on document, returns the document's height (innerHeight).
101
	 * If used on window, returns the viewport's (window) height.
102
	 *
103
	 * @example $("#testdiv").innerHeight()
104
	 * @result 210
105
	 *
106
	 * @name innerHeight
107
	 * @type Number
108
	 * @cat Plugins/Dimensions
109
	 */
110
	innerHeight: function() {
111
		if (!this[0]) error();
112
		return this[0] == window || this[0] == document ?
113
			this.height() :
114
			this.is(':visible') ?
115
				this[0].offsetHeight - num(this, 'borderTopWidth') - num(this, 'borderBottomWidth') :
116
				this.height() + num(this, 'paddingTop') + num(this, 'paddingBottom');
117
	},
118
	
119
	/**
120
	 * Gets the inner width (excludes the border and includes the padding) for the first matched element.
121
	 * If used on document, returns the document's width (innerWidth).
122
	 * If used on window, returns the viewport's (window) width.
123
	 *
124
	 * @example $("#testdiv").innerWidth()
125
	 * @result 210
126
	 *
127
	 * @name innerWidth
128
	 * @type Number
129
	 * @cat Plugins/Dimensions
130
	 */
131
	innerWidth: function() {
132
		if (!this[0]) error();
133
		return this[0] == window || this[0] == document ?
134
			this.width() :
135
			this.is(':visible') ?
136
				this[0].offsetWidth - num(this, 'borderLeftWidth') - num(this, 'borderRightWidth') :
137
				this.width() + num(this, 'paddingLeft') + num(this, 'paddingRight');
138
	},
139
	
140
	/**
141
	 * Gets the outer height (includes the border and padding) for the first matched element.
142
	 * If used on document, returns the document's height (innerHeight).
143
	 * If used on window, returns the viewport's (window) height.
144
	 *
145
	 * The margin can be included in the calculation by passing an options map with margin
146
	 * set to true.
147
	 *
148
	 * @example $("#testdiv").outerHeight()
149
	 * @result 220
150
	 *
151
	 * @example $("#testdiv").outerHeight({ margin: true })
152
	 * @result 240
153
	 *
154
	 * @name outerHeight
155
	 * @type Number
156
	 * @param Map options Optional settings to configure the way the outer height is calculated.
157
	 * @cat Plugins/Dimensions
158
	 */
159
	outerHeight: function(options) {
160
		if (!this[0]) error();
161
		options = $.extend({ margin: false }, options || {});
162
		return this[0] == window || this[0] == document ?
163
			this.height() :
164
			this.is(':visible') ?
165
				this[0].offsetHeight + (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0) :
166
				this.height() 
167
					+ num(this,'borderTopWidth') + num(this, 'borderBottomWidth') 
168
					+ num(this, 'paddingTop') + num(this, 'paddingBottom')
169
					+ (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0);
170
	},
171
	
172
	/**
173
	 * Gets the outer width (including the border and padding) for the first matched element.
174
	 * If used on document, returns the document's width (innerWidth).
175
	 * If used on window, returns the viewport's (window) width.
176
	 *
177
	 * The margin can be included in the calculation by passing an options map with margin
178
	 * set to true.
179
	 *
180
	 * @example $("#testdiv").outerWidth()
181
	 * @result 1000
182
	 *
183
	 * @example $("#testdiv").outerWidth({ margin: true })
184
	 * @result 1020
185
	 * 
186
	 * @name outerHeight
187
	 * @type Number
188
	 * @param Map options Optional settings to configure the way the outer width is calculated.
189
	 * @cat Plugins/Dimensions
190
	 */
191
	outerWidth: function(options) {
192
		if (!this[0]) error();
193
		options = $.extend({ margin: false }, options || {});
194
		return this[0] == window || this[0] == document ?
195
			this.width() :
196
			this.is(':visible') ?
197
				this[0].offsetWidth + (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0) :
198
				this.width() 
199
					+ num(this, 'borderLeftWidth') + num(this, 'borderRightWidth') 
200
					+ num(this, 'paddingLeft') + num(this, 'paddingRight')
201
					+ (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0);
202
	},
203
	
204
	/**
205
	 * Gets how many pixels the user has scrolled to the right (scrollLeft).
206
	 * Works on containers with overflow: auto and window/document.
207
	 *
208
	 * @example $(window).scrollLeft()
209
	 * @result 100
210
	 *
211
	 * @example $(document).scrollLeft()
212
	 * @result 100
213
	 * 
214
	 * @example $("#testdiv").scrollLeft()
215
	 * @result 100
216
	 *
217
	 * @name scrollLeft
218
	 * @type Number
219
	 * @cat Plugins/Dimensions
220
	 */
221
	/**
222
	 * Sets the scrollLeft property for each element and continues the chain.
223
	 * Works on containers with overflow: auto and window/document.
224
	 *
225
	 * @example $(window).scrollLeft(100).scrollLeft()
226
	 * @result 100
227
	 * 
228
	 * @example $(document).scrollLeft(100).scrollLeft()
229
	 * @result 100
230
	 *
231
	 * @example $("#testdiv").scrollLeft(100).scrollLeft()
232
	 * @result 100
233
	 *
234
	 * @name scrollLeft
235
	 * @param Number value A positive number representing the desired scrollLeft.
236
	 * @type jQuery
237
	 * @cat Plugins/Dimensions
238
	 */
239
	scrollLeft: function(val) {
240
		if (!this[0]) error();
241
		if ( val != undefined )
242
			// set the scroll left
243
			return this.each(function() {
244
				if (this == window || this == document)
245
					window.scrollTo( val, $(window).scrollTop() );
246
				else
247
					this.scrollLeft = val;
248
			});
249
		
250
		// return the scroll left offest in pixels
251
		if ( this[0] == window || this[0] == document )
252
			return self.pageXOffset ||
253
				$.boxModel && document.documentElement.scrollLeft ||
254
				document.body.scrollLeft;
255
				
256
		return this[0].scrollLeft;
257
	},
258
	
259
	/**
260
	 * Gets how many pixels the user has scrolled to the bottom (scrollTop).
261
	 * Works on containers with overflow: auto and window/document.
262
	 *
263
	 * @example $(window).scrollTop()
264
	 * @result 100
265
	 *
266
	 * @example $(document).scrollTop()
267
	 * @result 100
268
	 * 
269
	 * @example $("#testdiv").scrollTop()
270
	 * @result 100
271
	 *
272
	 * @name scrollTop
273
	 * @type Number
274
	 * @cat Plugins/Dimensions
275
	 */
276
	/**
277
	 * Sets the scrollTop property for each element and continues the chain.
278
	 * Works on containers with overflow: auto and window/document.
279
	 *
280
	 * @example $(window).scrollTop(100).scrollTop()
281
	 * @result 100
282
	 * 
283
	 * @example $(document).scrollTop(100).scrollTop()
284
	 * @result 100
285
	 *
286
	 * @example $("#testdiv").scrollTop(100).scrollTop()
287
	 * @result 100
288
	 *
289
	 * @name scrollTop
290
	 * @param Number value A positive number representing the desired scrollTop.
291
	 * @type jQuery
292
	 * @cat Plugins/Dimensions
293
	 */
294
	scrollTop: function(val) {
295
		if (!this[0]) error();
296
		if ( val != undefined )
297
			// set the scroll top
298
			return this.each(function() {
299
				if (this == window || this == document)
300
					window.scrollTo( $(window).scrollLeft(), val );
301
				else
302
					this.scrollTop = val;
303
			});
304
		
305
		// return the scroll top offset in pixels
306
		if ( this[0] == window || this[0] == document )
307
			return self.pageYOffset ||
308
				$.boxModel && document.documentElement.scrollTop ||
309
				document.body.scrollTop;
310

    
311
		return this[0].scrollTop;
312
	},
313
	
314
	/** 
315
	 * Gets the top and left positioned offset in pixels.
316
	 * The positioned offset is the offset between a positioned
317
	 * parent and the element itself.
318
	 *
319
	 * For accurate calculations make sure to use pixel values for margins, borders and padding.
320
	 *
321
	 * @example $("#testdiv").position()
322
	 * @result { top: 100, left: 100 }
323
	 *
324
	 * @example var position = {};
325
	 * $("#testdiv").position(position)
326
	 * @result position = { top: 100, left: 100 }
327
	 * 
328
	 * @name position
329
	 * @param Object returnObject Optional An object to store the return value in, so as not to break the chain. If passed in the
330
	 *                            chain will not be broken and the result will be assigned to this object.
331
	 * @type Object
332
	 * @cat Plugins/Dimensions
333
	 */
334
	position: function(returnObject) {
335
		return this.offset({ margin: false, scroll: false, relativeTo: this.offsetParent() }, returnObject);
336
	},
337
	
338
	/**
339
	 * Gets the location of the element in pixels from the top left corner of the viewport.
340
	 * The offset method takes an optional map of key value pairs to configure the way
341
	 * the offset is calculated. Here are the different options.
342
	 *
343
	 * (Boolean) margin - Should the margin of the element be included in the calculations? True by default.
344
	 * (Boolean) border - Should the border of the element be included in the calculations? False by default. 
345
	 * (Boolean) padding - Should the padding of the element be included in the calculations? False by default. 
346
	 * (Boolean) scroll - Should the scroll offsets of the parent elements be included in the calculations? True by default.
347
	 *                    When true it adds the total scroll offsets of all parents to the total offset and also adds two
348
	 *                    properties to the returned object, scrollTop and scrollLeft.
349
	 * (Boolean) lite - When true it will use the offsetLite method instead of the full-blown, slower offset method. False by default.
350
	 *                  Only use this when margins, borders and padding calculations don't matter.
351
	 * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative).
352
	 *                             It will retreive the offset relative to this parent element. By default it is the body element.
353
	 *
354
	 * Also an object can be passed as the second paramater to
355
	 * catch the value of the return and continue the chain.
356
	 *
357
	 * For accurate calculations make sure to use pixel values for margins, borders and padding.
358
	 * 
359
	 * Known issues:
360
	 *  - Issue: A div positioned relative or static without any content before it and its parent will report an offsetTop of 0 in Safari
361
	 *    Workaround: Place content before the relative div ... and set height and width to 0 and overflow to hidden
362
	 *
363
	 * @example $("#testdiv").offset()
364
	 * @result { top: 100, left: 100, scrollTop: 10, scrollLeft: 10 }
365
	 *
366
	 * @example $("#testdiv").offset({ scroll: false })
367
	 * @result { top: 90, left: 90 }
368
	 *
369
	 * @example var offset = {}
370
	 * $("#testdiv").offset({ scroll: false }, offset)
371
	 * @result offset = { top: 90, left: 90 }
372
	 *
373
	 * @name offset
374
	 * @param Map options Optional settings to configure the way the offset is calculated.
375
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
376
	 *                            chain will not be broken and the result will be assigned to this object.
377
	 * @type Object
378
	 * @cat Plugins/Dimensions
379
	 */
380
	offset: function(options, returnObject) {
381
		if (!this[0]) error();
382
		var x = 0, y = 0, sl = 0, st = 0,
383
		    elem = this[0], parent = this[0], op, parPos, elemPos = $.css(elem, 'position'),
384
		    mo = $.browser.mozilla, ie = $.browser.msie, oa = $.browser.opera,
385
		    sf = $.browser.safari, sf3 = $.browser.safari && parseInt($.browser.version) > 520,
386
		    absparent = false, relparent = false, 
387
		    options = $.extend({ margin: true, border: false, padding: false, scroll: true, lite: false, relativeTo: document.body }, options || {});
388
		
389
		// Use offsetLite if lite option is true
390
		if (options.lite) return this.offsetLite(options, returnObject);
391
		// Get the HTMLElement if relativeTo is a jquery collection
392
		if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0];
393
		
394
		if (elem.tagName == 'BODY') {
395
			// Safari 2 is the only one to get offsetLeft and offsetTop properties of the body "correct"
396
			// Except they all mess up when the body is positioned absolute or relative
397
			x = elem.offsetLeft;
398
			y = elem.offsetTop;
399
			// Mozilla ignores margin and subtracts border from body element
400
			if (mo) {
401
				x += num(elem, 'marginLeft') + (num(elem, 'borderLeftWidth')*2);
402
				y += num(elem, 'marginTop')  + (num(elem, 'borderTopWidth') *2);
403
			} else
404
			// Opera ignores margin
405
			if (oa) {
406
				x += num(elem, 'marginLeft');
407
				y += num(elem, 'marginTop');
408
			} else
409
			// IE does not add the border in Standards Mode
410
			if ((ie && jQuery.boxModel)) {
411
				x += num(elem, 'borderLeftWidth');
412
				y += num(elem, 'borderTopWidth');
413
			} else
414
			// Safari 3 doesn't not include border or margin
415
			if (sf3) {
416
				x += num(elem, 'marginLeft') + num(elem, 'borderLeftWidth');
417
				y += num(elem, 'marginTop')  + num(elem, 'borderTopWidth');
418
			}
419
		} else {
420
			do {
421
				parPos = $.css(parent, 'position');
422
			
423
				x += parent.offsetLeft;
424
				y += parent.offsetTop;
425

    
426
				// Mozilla and IE do not add the border
427
				// Mozilla adds the border for table cells
428
				if ((mo && !parent.tagName.match(/^t[d|h]$/i)) || ie || sf3) {
429
					// add borders to offset
430
					x += num(parent, 'borderLeftWidth');
431
					y += num(parent, 'borderTopWidth');
432

    
433
					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
434
					if (mo && parPos == 'absolute') absparent = true;
435
					// IE does not include the border on the body if an element is position static and without an absolute or relative parent
436
					if (ie && parPos == 'relative') relparent = true;
437
				}
438

    
439
				op = parent.offsetParent || document.body;
440
				if (options.scroll || mo) {
441
					do {
442
						if (options.scroll) {
443
							// get scroll offsets
444
							sl += parent.scrollLeft;
445
							st += parent.scrollTop;
446
						}
447
						
448
						// Opera sometimes incorrectly reports scroll offset for elements with display set to table-row or inline
449
						if (oa && ($.css(parent, 'display') || '').match(/table-row|inline/)) {
450
							sl = sl - ((parent.scrollLeft == parent.offsetLeft) ? parent.scrollLeft : 0);
451
							st = st - ((parent.scrollTop == parent.offsetTop) ? parent.scrollTop : 0);
452
						}
453
				
454
						// Mozilla does not add the border for a parent that has overflow set to anything but visible
455
						if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
456
							x += num(parent, 'borderLeftWidth');
457
							y += num(parent, 'borderTopWidth');
458
						}
459
				
460
						parent = parent.parentNode;
461
					} while (parent != op);
462
				}
463
				parent = op;
464
				
465
				// exit the loop if we are at the relativeTo option but not if it is the body or html tag
466
				if (parent == options.relativeTo && !(parent.tagName == 'BODY' || parent.tagName == 'HTML'))  {
467
					// Mozilla does not add the border for a parent that has overflow set to anything but visible
468
					if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
469
						x += num(parent, 'borderLeftWidth');
470
						y += num(parent, 'borderTopWidth');
471
					}
472
					// Safari 2 and opera includes border on positioned parents
473
					if ( ((sf && !sf3) || oa) && parPos != 'static' ) {
474
						x -= num(op, 'borderLeftWidth');
475
						y -= num(op, 'borderTopWidth');
476
					}
477
					break;
478
				}
479
				if (parent.tagName == 'BODY' || parent.tagName == 'HTML') {
480
					// Safari 2 and IE Standards Mode doesn't add the body margin for elments positioned with static or relative
481
					if (((sf && !sf3) || (ie && $.boxModel)) && elemPos != 'absolute' && elemPos != 'fixed') {
482
						x += num(parent, 'marginLeft');
483
						y += num(parent, 'marginTop');
484
					}
485
					// Safari 3 does not include the border on body
486
					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
487
					// IE does not include the border on the body if an element is positioned static and without an absolute or relative parent
488
					if ( sf3 || (mo && !absparent && elemPos != 'fixed') || 
489
					     (ie && elemPos == 'static' && !relparent) ) {
490
						x += num(parent, 'borderLeftWidth');
491
						y += num(parent, 'borderTopWidth');
492
					}
493
					break; // Exit the loop
494
				}
495
			} while (parent);
496
		}
497

    
498
		var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);
499

    
500
		if (returnObject) { $.extend(returnObject, returnValue); return this; }
501
		else              { return returnValue; }
502
	},
503
	
504
	/**
505
	 * Gets the location of the element in pixels from the top left corner of the viewport.
506
	 * This method is much faster than offset but not as accurate when borders and margins are
507
	 * on the element and/or its parents. This method can be invoked
508
	 * by setting the lite option to true in the offset method.
509
	 * The offsetLite method takes an optional map of key value pairs to configure the way
510
	 * the offset is calculated. Here are the different options.
511
	 *
512
	 * (Boolean) margin - Should the margin of the element be included in the calculations? True by default.
513
	 * (Boolean) border - Should the border of the element be included in the calculations? False by default. 
514
	 * (Boolean) padding - Should the padding of the element be included in the calcuations? False by default. 
515
	 * (Boolean) scroll - Sould the scroll offsets of the parent elements be included int he calculations? True by default.
516
	 *                    When true it adds the total scroll offsets of all parents to the total offset and also adds two
517
	 *                    properties to the returned object, scrollTop and scrollLeft.
518
	 * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative).
519
	 *                             It will retreive the offset relative to this parent element. By default it is the body element.
520
	 *
521
	 * @name offsetLite
522
	 * @param Map options Optional settings to configure the way the offset is calculated.
523
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
524
	 *                            chain will not be broken and the result will be assigned to this object.
525
	 * @type Object
526
	 * @cat Plugins/Dimensions
527
	 */
528
	offsetLite: function(options, returnObject) {
529
		if (!this[0]) error();
530
		var x = 0, y = 0, sl = 0, st = 0, parent = this[0], offsetParent, 
531
		    options = $.extend({ margin: true, border: false, padding: false, scroll: true, relativeTo: document.body }, options || {});
532
				
533
		// Get the HTMLElement if relativeTo is a jquery collection
534
		if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0];
535
		
536
		do {
537
			x += parent.offsetLeft;
538
			y += parent.offsetTop;
539

    
540
			offsetParent = parent.offsetParent || document.body;
541
			if (options.scroll) {
542
				// get scroll offsets
543
				do {
544
					sl += parent.scrollLeft;
545
					st += parent.scrollTop;
546
					parent = parent.parentNode;
547
				} while(parent != offsetParent);
548
			}
549
			parent = offsetParent;
550
		} while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML' && parent != options.relativeTo);
551

    
552
		var returnValue = handleOffsetReturn(this[0], options, x, y, sl, st);
553

    
554
		if (returnObject) { $.extend(returnObject, returnValue); return this; }
555
		else              { return returnValue; }
556
	},
557
	
558
	/**
559
	 * Returns a jQuery collection with the positioned parent of 
560
	 * the first matched element. This is the first parent of 
561
	 * the element that has position (as in relative or absolute).
562
	 *
563
	 * @name offsetParent
564
	 * @type jQuery
565
	 * @cat Plugins/Dimensions
566
	 */
567
	offsetParent: function() {
568
		if (!this[0]) error();
569
		var offsetParent = this[0].offsetParent;
570
		while ( offsetParent && (offsetParent.tagName != 'BODY' && $.css(offsetParent, 'position') == 'static') )
571
			offsetParent = offsetParent.offsetParent;
572
		return $(offsetParent);
573
	}
574
});
575

    
576
/**
577
 * Throws an error message when no elements are in the jQuery collection
578
 * @private
579
 */
580
var error = function() {
581
	throw "Dimensions: jQuery collection is empty";
582
};
583

    
584
/**
585
 * Handles converting a CSS Style into an Integer.
586
 * @private
587
 */
588
var num = function(el, prop) {
589
	return parseInt($.css(el.jquery?el[0]:el,prop))||0;
590
};
591

    
592
/**
593
 * Handles the return value of the offset and offsetLite methods.
594
 * @private
595
 */
596
var handleOffsetReturn = function(elem, options, x, y, sl, st) {
597
	if ( !options.margin ) {
598
		x -= num(elem, 'marginLeft');
599
		y -= num(elem, 'marginTop');
600
	}
601

    
602
	// Safari and Opera do not add the border for the element
603
	if ( options.border && (($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) {
604
		x += num(elem, 'borderLeftWidth');
605
		y += num(elem, 'borderTopWidth');
606
	} else if ( !options.border && !(($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) {
607
		x -= num(elem, 'borderLeftWidth');
608
		y -= num(elem, 'borderTopWidth');
609
	}
610

    
611
	if ( options.padding ) {
612
		x += num(elem, 'paddingLeft');
613
		y += num(elem, 'paddingTop');
614
	}
615
	
616
	// do not include scroll offset on the element ... opera sometimes reports scroll offset as actual offset
617
	if ( options.scroll && (!$.browser.opera || elem.offsetLeft != elem.scrollLeft && elem.offsetTop != elem.scrollLeft) ) {
618
		sl -= elem.scrollLeft;
619
		st -= elem.scrollTop;
620
	}
621

    
622
	return options.scroll ? { top: y - st, left: x - sl, scrollTop:  st, scrollLeft: sl }
623
	                      : { top: y, left: x };
624
};
625

    
626
/**
627
 * Gets the width of the OS scrollbar
628
 * @private
629
 */
630
var scrollbarWidth = 0;
631
var getScrollbarWidth = function() {
632
	if (!scrollbarWidth) {
633
		var testEl = $('<div>')
634
				.css({
635
					width: 100,
636
					height: 100,
637
					overflow: 'auto',
638
					position: 'absolute',
639
					top: -1000,
640
					left: -1000
641
				})
642
				.appendTo('body');
643
		scrollbarWidth = 100 - testEl
644
			.append('<div>')
645
			.find('div')
646
				.css({
647
					width: '100%',
648
					height: 200
649
				})
650
				.width();
651
		testEl.remove();
652
	}
653
	return scrollbarWidth;
654
};
655

    
656
})(jQuery);
(5-5/7)