remove trailing spaces
[jquery.git] / src / offset.js
index 479f106..9ef5aa0 100644 (file)
@@ -1,37 +1,41 @@
-if ( document.documentElement["getBoundingClientRect"] )
+if ( "getBoundingClientRect" in document.documentElement )
        jQuery.fn.offset = function() {
-               if ( !this[0] ) return { top: 0, left: 0 };
-               if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
-               var box  = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, docElem = doc.documentElement,
-                       top  = box.top  + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop  || doc.body.scrollTop ) - docElem.clientTop,
-                       left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || doc.body.scrollLeft) - docElem.clientLeft;
+               var elem = this[0];
+               if ( !elem ) return null;
+               if ( elem === elem.ownerDocument.body ) return jQuery.offset.bodyOffset( elem );
+               var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
+                       clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
+                       top  = box.top  + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop  || body.scrollTop ) - clientTop,
+                       left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
                return { top: top, left: left };
        };
-else 
+else
        jQuery.fn.offset = function() {
-               if ( !this[0] ) return { top: 0, left: 0 };
-               if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
-               jQuery.offset.initialized || jQuery.offset.initialize();
+               var elem = this[0];
+               if ( !elem ) return null;
+               if ( elem === elem.ownerDocument.body ) return jQuery.offset.bodyOffset( elem );
+               jQuery.offset.initialize();
 
-               var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
+               var offsetParent = elem.offsetParent, prevOffsetParent = elem,
                        doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
                        body = doc.body, defaultView = doc.defaultView,
                        prevComputedStyle = defaultView.getComputedStyle(elem, null),
                        top = elem.offsetTop, left = elem.offsetLeft;
 
                while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+                       if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) break;
                        computedStyle = defaultView.getComputedStyle(elem, null);
                        top -= elem.scrollTop, left -= elem.scrollLeft;
                        if ( elem === offsetParent ) {
                                top += elem.offsetTop, left += elem.offsetLeft;
                                if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
-                                       top  += parseInt( computedStyle.borderTopWidth,  10) || 0,
-                                       left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
+                                       top  += parseFloat( computedStyle.borderTopWidth,  10) || 0,
+                                       left += parseFloat( computedStyle.borderLeftWidth, 10) || 0;
                                prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
                        }
                        if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
-                               top  += parseInt( computedStyle.borderTopWidth,  10) || 0,
-                               left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
+                               top  += parseFloat( computedStyle.borderTopWidth,  10) || 0,
+                               left += parseFloat( computedStyle.borderLeftWidth, 10) || 0;
                        prevComputedStyle = computedStyle;
                }
 
@@ -39,7 +43,7 @@ else
                        top  += body.offsetTop,
                        left += body.offsetLeft;
 
-               if ( prevComputedStyle.position === "fixed" )
+               if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" )
                        top  += Math.max(docElem.scrollTop, body.scrollTop),
                        left += Math.max(docElem.scrollLeft, body.scrollLeft);
 
@@ -48,12 +52,10 @@ else
 
 jQuery.offset = {
        initialize: function() {
-               if ( this.initialized ) return;
-               var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, rules, prop, bodyMarginTop = body.style.marginTop,
-                       html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"cellpadding="0"cellspacing="0"><tr><td></td></tr></table>';
+               var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, prop, bodyMarginTop = body.style.marginTop,
+                       html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
 
-               rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' }
-               for ( prop in rules ) container.style[prop] = rules[prop];
+               jQuery.extend( container.style, { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' } );
 
                container.innerHTML = html;
                body.insertBefore(container, body.firstChild);
@@ -62,6 +64,10 @@ jQuery.offset = {
                this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
                this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
 
+               checkDiv.style.position = 'fixed', checkDiv.style.top = '20px';
+               this.supportsFixedPosition = (checkDiv.offsetTop >= 15); // safari subtracts parent border width here which is 5px
+               checkDiv.style.position = '', checkDiv.style.top = '';
+
                innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
                this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
 
@@ -70,15 +76,15 @@ jQuery.offset = {
                body.style.marginTop = bodyMarginTop;
 
                body.removeChild(container);
-               this.initialized = true;
+               jQuery.offset.initialize = function(){};
        },
 
        bodyOffset: function(body) {
-               jQuery.offset.initialized || jQuery.offset.initialize();
+               jQuery.offset.initialize();
                var top = body.offsetTop, left = body.offsetLeft;
                if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
-                       top  += parseInt( jQuery.curCSS(body, 'marginTop',  true), 10 ) || 0,
-                       left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
+                       top  += parseFloat( jQuery.curCSS(body, 'marginTop',  true), 10 ) || 0,
+                       left += parseFloat( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
                return { top: top, left: left };
        }
 };
@@ -86,32 +92,32 @@ jQuery.offset = {
 
 jQuery.fn.extend({
        position: function() {
-               var left = 0, top = 0, results;
-
-               if ( this[0] ) {
-                       // Get *real* offsetParent
-                       var offsetParent = this.offsetParent(),
-
-                       // Get correct offsets
-                       offset       = this.offset(),
-                       parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
-
-                       // Subtract element margins
-                       // note: when an element has margin: auto the offsetLeft and marginLeft 
-                       // are the same in Safari causing offset.left to incorrectly be 0
-                       offset.top  -= num( this, 'marginTop'  );
-                       offset.left -= num( this, 'marginLeft' );
-
-                       // Add offsetParent borders
-                       parentOffset.top  += num( offsetParent, 'borderTopWidth'  );
-                       parentOffset.left += num( offsetParent, 'borderLeftWidth' );
-
-                       // Subtract the two offsets
-                       results = {
-                               top:  offset.top  - parentOffset.top,
-                               left: offset.left - parentOffset.left
-                       };
-               }
+               if ( !this[0] ) return null;
+
+               var elem = this[0], left = 0, top = 0, results,
+
+               // Get *real* offsetParent
+               offsetParent = this.offsetParent(),
+
+               // Get correct offsets
+               offset       = this.offset(),
+               parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+               // Subtract element margins
+               // note: when an element has margin: auto the offsetLeft and marginLeft
+               // are the same in Safari causing offset.left to incorrectly be 0
+               offset.top  -= parseFloat( jQuery.curCSS(elem, 'marginTop',  true), 10 ) || 0;
+               offset.left -= parseFloat( jQuery.curCSS(elem, 'marginLeft', true), 10 ) || 0;
+
+               // Add offsetParent borders
+               parentOffset.top  += parseFloat( jQuery.curCSS(offsetParent[0], 'borderTopWidth',  true), 10 ) || 0;
+               parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], 'borderLeftWidth', true), 10 ) || 0;
+
+               // Subtract the two offsets
+               results = {
+                       top:  offset.top  - parentOffset.top,
+                       left: offset.left - parentOffset.left
+               };
 
                return results;
        },
@@ -128,11 +134,11 @@ jQuery.fn.extend({
 // Create scrollLeft and scrollTop methods
 jQuery.each( ['Left', 'Top'], function(i, name) {
        var method = 'scroll' + name;
-       
+
        jQuery.fn[ method ] = function(val) {
-               if (!this[0]) return;
+               if ( !this[0] ) return null;
 
-               return val != undefined ?
+               return val !== undefined ?
 
                        // Set the scroll offset
                        this.each(function() {