Skip to content
Snippets Groups Projects
jquery.js 242 KiB
Newer Older
  • Learn to ignore specific revisions
  • Martin Poirier's avatar
    Martin Poirier committed
    
    		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
    			top  += body.offsetTop;
    			left += body.offsetLeft;
    		}
    
    		if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
    			top  += Math.max( docElem.scrollTop, body.scrollTop );
    			left += Math.max( docElem.scrollLeft, body.scrollLeft );
    		}
    
    		return { top: top, left: left };
    	};
    }
    
    jQuery.offset = {
    
    	bodyOffset: function( body ) {
    		var top = body.offsetTop,
    			left = body.offsetLeft;
    
    		if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
    			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
    			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
    		}
    
    		return { top: top, left: left };
    	},
    
    	setOffset: function( elem, options, i ) {
    		var position = jQuery.css( elem, "position" );
    
    		// set position first, in-case top/left are set even on static elem
    		if ( position === "static" ) {
    			elem.style.position = "relative";
    		}
    
    		var curElem = jQuery( elem ),
    			curOffset = curElem.offset(),
    			curCSSTop = jQuery.css( elem, "top" ),
    			curCSSLeft = jQuery.css( elem, "left" ),
    			calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
    			props = {}, curPosition = {}, curTop, curLeft;
    
    		// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
    		if ( calculatePosition ) {
    			curPosition = curElem.position();
    			curTop = curPosition.top;
    			curLeft = curPosition.left;
    		} else {
    			curTop = parseFloat( curCSSTop ) || 0;
    			curLeft = parseFloat( curCSSLeft ) || 0;
    		}
    
    		if ( jQuery.isFunction( options ) ) {
    			options = options.call( elem, i, curOffset );
    		}
    
    		if ( options.top != null ) {
    			props.top = ( options.top - curOffset.top ) + curTop;
    		}
    		if ( options.left != null ) {
    			props.left = ( options.left - curOffset.left ) + curLeft;
    		}
    
    		if ( "using" in options ) {
    			options.using.call( elem, props );
    		} else {
    			curElem.css( props );
    		}
    	}
    };
    
    
    jQuery.fn.extend({
    
    	position: function() {
    		if ( !this[0] ) {
    			return null;
    		}
    
    		var elem = this[0],
    
    		// Get *real* offsetParent
    		offsetParent = this.offsetParent(),
    
    		// Get correct offsets
    		offset       = this.offset(),
    		parentOffset = rroot.test(offsetParent[0].nodeName) ? { 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.css(elem, "marginTop") ) || 0;
    		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
    
    		// Add offsetParent borders
    		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
    		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
    
    		// Subtract the two offsets
    		return {
    			top:  offset.top  - parentOffset.top,
    			left: offset.left - parentOffset.left
    		};
    	},
    
    	offsetParent: function() {
    		return this.map(function() {
    			var offsetParent = this.offsetParent || document.body;
    			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
    				offsetParent = offsetParent.offsetParent;
    			}
    			return offsetParent;
    		});
    	}
    });
    
    
    // Create scrollLeft and scrollTop methods
    jQuery.each( ["Left", "Top"], function( i, name ) {
    	var method = "scroll" + name;
    
    	jQuery.fn[ method ] = function( val ) {
    		var elem, win;
    
    		if ( val === undefined ) {
    			elem = this[ 0 ];
    
    			if ( !elem ) {
    				return null;
    			}
    
    			win = getWindow( elem );
    
    			// Return the scroll offset
    			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
    				jQuery.support.boxModel && win.document.documentElement[ method ] ||
    					win.document.body[ method ] :
    				elem[ method ];
    		}
    
    		// Set the scroll offset
    		return this.each(function() {
    			win = getWindow( this );
    
    			if ( win ) {
    				win.scrollTo(
    					!i ? val : jQuery( win ).scrollLeft(),
    					 i ? val : jQuery( win ).scrollTop()
    				);
    
    			} else {
    				this[ method ] = val;
    			}
    		});
    	};
    });
    
    function getWindow( elem ) {
    	return jQuery.isWindow( elem ) ?
    		elem :
    		elem.nodeType === 9 ?
    			elem.defaultView || elem.parentWindow :
    			false;
    }
    
    
    
    
    // Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
    jQuery.each([ "Height", "Width" ], function( i, name ) {
    
    	var type = name.toLowerCase();
    
    	// innerHeight and innerWidth
    	jQuery.fn[ "inner" + name ] = function() {
    		var elem = this[0];
    		return elem ?
    			elem.style ?
    			parseFloat( jQuery.css( elem, type, "padding" ) ) :
    			this[ type ]() :
    			null;
    	};
    
    	// outerHeight and outerWidth
    	jQuery.fn[ "outer" + name ] = function( margin ) {
    		var elem = this[0];
    		return elem ?
    			elem.style ?
    			parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
    			this[ type ]() :
    			null;
    	};
    
    	jQuery.fn[ type ] = function( size ) {
    		// Get window width or height
    		var elem = this[0];
    		if ( !elem ) {
    			return size == null ? null : this;
    		}
    
    		if ( jQuery.isFunction( size ) ) {
    			return this.each(function( i ) {
    				var self = jQuery( this );
    				self[ type ]( size.call( this, i, self[ type ]() ) );
    			});
    		}
    
    		if ( jQuery.isWindow( elem ) ) {
    			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
    			// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
    			var docElemProp = elem.document.documentElement[ "client" + name ],
    				body = elem.document.body;
    			return elem.document.compatMode === "CSS1Compat" && docElemProp ||
    				body && body[ "client" + name ] || docElemProp;
    
    		// Get document width or height
    		} else if ( elem.nodeType === 9 ) {
    			// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
    			return Math.max(
    				elem.documentElement["client" + name],
    				elem.body["scroll" + name], elem.documentElement["scroll" + name],
    				elem.body["offset" + name], elem.documentElement["offset" + name]
    			);
    
    		// Get or set width or height on the element
    		} else if ( size === undefined ) {
    			var orig = jQuery.css( elem, type ),
    				ret = parseFloat( orig );
    
    			return jQuery.isNumeric( ret ) ? ret : orig;
    
    		// Set the width or height on the element (default to pixels if value is unitless)
    		} else {
    			return this.css( type, typeof size === "string" ? size : size + "px" );
    		}
    	};
    
    });
    
    
    
    
    // Expose jQuery to the global object
    window.jQuery = window.$ = jQuery;
    
    // Expose jQuery as an AMD module, but only for AMD loaders that
    // understand the issues with loading multiple versions of jQuery
    // in a page that all might call define(). The loader will indicate
    // they have special allowances for multiple jQuery versions by
    // specifying define.amd.jQuery = true. Register as a named module,
    // since jQuery can be concatenated with other files that may use define,
    // but not use a proper concatenation script that understands anonymous
    // AMD modules. A named AMD is safest and most robust way to register.
    // Lowercase jquery is used because AMD module names are derived from
    // file names, and jQuery is normally delivered in a lowercase file name.
    // Do this after creating the global so that if an AMD module wants to call
    // noConflict to hide this version of jQuery, it will work.
    if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
    	define( "jquery", [], function () { return jQuery; } );
    }
    
    
    
    })( window );