(function(){ jQuery.support = {}; var root = document.documentElement, script = document.createElement("script"), div = document.createElement("div"), id = "script" + (new Date).getTime(); div.style.display = "none"; div.innerHTML = '
a'; var all = div.getElementsByTagName("*"), a = div.getElementsByTagName("a")[0]; // Can't get basic test support if ( !all || !all.length || !a ) { return; } jQuery.support = { // IE strips leading whitespace when .innerHTML is used leadingWhitespace: div.firstChild.nodeType == 3, // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables tbody: !div.getElementsByTagName("tbody").length, // Make sure that you can get all elements in an element // IE 7 always returns no results objectAll: !!div.getElementsByTagName("object")[0] .getElementsByTagName("*").length, // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE htmlSerialize: !!div.getElementsByTagName("link").length, // Get the style information from getAttribute // (IE uses .cssText insted) style: /red/.test( a.getAttribute("style") ), // Make sure that URLs aren't manipulated // (IE normalizes it by default) hrefNormalized: a.getAttribute("href") === "/a", // Make sure that element opacity exists // (IE uses filter instead) opacity: a.style.opacity === "0.5", // Verify style float existence // (IE uses styleFloat instead of cssFloat) cssFloat: !!a.style.cssFloat, // Will be defined later scriptEval: false, noCloneEvent: true, boxModel: null }; script.type = "text/javascript"; try { script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); } catch(e){} root.insertBefore( script, root.firstChild ); // Make sure that the execution of code works by injecting a script // tag with appendChild/createTextNode // (IE doesn't support this, fails, and uses .text instead) if ( window[ id ] ) { jQuery.support.scriptEval = true; delete window[ id ]; } root.removeChild( script ); if ( div.attachEvent && div.fireEvent ) { div.attachEvent("onclick", function(){ // Cloning a node shouldn't copy over any // bound event handlers (IE does this) jQuery.support.noCloneEvent = false; div.detachEvent("onclick", arguments.callee); }); div.cloneNode(true).fireEvent("onclick"); } // Figure out if the W3C box model works as expected // document.body must exist before we can do this jQuery(function(){ var div = document.createElement("div"); div.style.width = "1px"; div.style.paddingLeft = "1px"; document.body.appendChild( div ); jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; document.body.removeChild( div ); }); })(); // Helper function used by the dimensions and offset modules function num(elem, prop) { return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0; } function now(){ return +new Date; } jQuery.extend({ speed: function(speed, easing, fn) { var opt = typeof speed === "object" ? speed : { complete: fn || !fn && easing || jQuery.isFunction( speed ) && speed, duration: speed, easing: fn && easing || easing && !jQuery.isFunction(easing) && easing }; opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default; // Queueing opt.old = opt.complete; opt.complete = function(){ if ( opt.queue !== false ) jQuery(this).dequeue(); if ( jQuery.isFunction( opt.old ) ) opt.old.call( this ); }; return opt; }, easing: { linear: function( p, n, firstNum, diff ) { return firstNum + diff * p; }, swing: function( p, n, firstNum, diff ) { return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum; } }, timers: [], timerId: null, fx: function( elem, options, prop ){ this.options = options; this.elem = elem; this.prop = prop; if ( !options.orig ) options.orig = {}; }, isArray: function( obj ) { return toString.call(obj) === "[object Array]"; } }); jQuery.fx.prototype = { // Simple function for setting a style value update: function(){ if ( this.options.step ) this.options.step.call( this.elem, this.now, this ); (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); // Set display property to block for height/width animations if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style ) this.elem.style.display = "block"; }, // Get the current size cur: function(force){ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) return this.elem[ this.prop ]; var r = parseFloat(jQuery.css(this.elem, this.prop, force)); return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0; }, // Start an animation from one number to another custom: function(from, to, unit){ this.startTime = now(); this.start = from; this.end = to; this.unit = unit || this.unit || "px"; this.now = this.start; this.pos = this.state = 0; var self = this; function t(gotoEnd){ return self.step(gotoEnd); } t.elem = this.elem; jQuery.timers.push(t); if ( t() && jQuery.timerId == null ) { jQuery.timerId = setInterval(function(){ var timers = jQuery.timers; for ( var i = 0; i < timers.length; i++ ) if ( !timers[i]() ) timers.splice(i--, 1); if ( !timers.length ) { clearInterval( jQuery.timerId ); jQuery.timerId = null; } }, 13); } }, // Simple 'show' function show: function(){ // Remember where we started, so that we can go back to it later this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); this.options.show = true; // Begin the animation // Make sure that we start at a small width/height to avoid any // flash of content this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur()); // Start by showing the element jQuery(this.elem).show(); }, // Simple 'hide' function hide: function(){ // Remember where we started, so that we can go back to it later this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop ); this.options.hide = true; // Begin the animation this.custom(this.cur(), 0); }, // Each step of an animation step: function(gotoEnd){ var t = now(); if ( gotoEnd || t >= this.options.duration + this.startTime ) { this.now = this.end; this.pos = this.state = 1; this.update(); this.options.curAnim[ this.prop ] = true; var done = true; for ( var i in this.options.curAnim ) if ( this.options.curAnim[i] !== true ) done = false; if ( done ) { if ( this.options.display != null ) { // Reset the overflow this.elem.style.overflow = this.options.overflow; // Reset the display this.elem.style.display = this.options.display; if ( jQuery.css(this.elem, "display") == "none" ) this.elem.style.display = "block"; } // Hide the element if the "hide" operation was done if ( this.options.hide ) jQuery(this.elem).hide(); // Reset the properties, if the item has been hidden or shown if ( this.options.hide || this.options.show ) for ( var p in this.options.curAnim ) jQuery.attr(this.elem.style, p, this.options.orig[p]); } if ( done ) // Execute the complete function this.options.complete.call( this.elem ); return false; } else { var n = t - this.startTime; this.state = n / this.options.duration; // Perform the easing function, defaults to swing this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration); this.now = this.start + ((this.end - this.start) * this.pos); // Perform the next step of the animation this.update(); } return true; } }; jQuery.extend( jQuery.fx, { speeds:{ slow: 600, fast: 200, // Default speed _default: 400 }, step: { opacity: function(fx){ jQuery.attr(fx.elem.style, "opacity", fx.now); }, _default: function(fx){ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) fx.elem.style[ fx.prop ] = fx.now + fx.unit; else fx.elem[ fx.prop ] = fx.now; } } }); if ( document.documentElement["getBoundingClientRect"] ) 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, 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 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], 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 ) { 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; prevOffsetParent = offsetParent, offsetParent = elem.offsetParent; } if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) top += parseInt( computedStyle.borderTopWidth, 10) || 0, left += parseInt( computedStyle.borderLeftWidth, 10) || 0; prevComputedStyle = computedStyle; } if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) top += body.offsetTop, left += body.offsetLeft; if ( prevComputedStyle.position === "fixed" ) top += Math.max(docElem.scrollTop, body.scrollTop), left += Math.max(docElem.scrollLeft, body.scrollLeft); return { top: top, left: left }; }; jQuery.offset = { initialize: function() { if ( this.initialized ) return; var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop, html = '
'; 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]; container.innerHTML = html; body.insertBefore(container, body.firstChild); innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild; this.doesNotAddBorder = (checkDiv.offsetTop !== 5); this.doesAddBorderForTableAndCells = (td.offsetTop === 5); innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative'; this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5); body.style.marginTop = '1px'; this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0); body.style.marginTop = bodyMarginTop; body.removeChild(container); this.initialized = true; }, bodyOffset: function(body) { jQuery.offset.initialized || 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; return { top: top, left: left }; } }; 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 }; } return results; }, offsetParent: function() { var offsetParent = this[0].offsetParent || document.body; while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') ) offsetParent = offsetParent.offsetParent; return jQuery(offsetParent); } }); // 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 null; return val !== undefined ? // Set the scroll offset this.each(function() { this == window || this == document ? window.scrollTo( !i ? val : jQuery(window).scrollLeft(), i ? val : jQuery(window).scrollTop() ) : this[ method ] = val; }) : // Return the scroll offset this[0] == window || this[0] == document ? self[ i ? 'pageYOffset' : 'pageXOffset' ] || jQuery.boxModel && document.documentElement[ method ] || document.body[ method ] : this[0][ method ]; }; }); // Create innerHeight, innerWidth, outerHeight and outerWidth methods jQuery.each([ "Height", "Width" ], function(i, name){ var tl = i ? "Left" : "Top", // top or left br = i ? "Right" : "Bottom"; // bottom or right // innerHeight and innerWidth jQuery.fn["inner" + name] = function(){ return this[ name.toLowerCase() ]() + num(this, "padding" + tl) + num(this, "padding" + br); }; // outerHeight and outerWidth jQuery.fn["outer" + name] = function(margin) { return this["inner" + name]() + num(this, "border" + tl + "Width") + num(this, "border" + br + "Width") + (margin ? num(this, "margin" + tl) + num(this, "margin" + br) : 0); }; var type = name.toLowerCase(); jQuery.fn[ type ] = function( size ) { // Get window width or height return this[0] == window ? // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] : // Get document width or height this[0] == document ? // Either scroll[Width/Height] or offset[Width/Height], whichever is greater Math.max( document.documentElement["client" + name], document.body["scroll" + name], document.documentElement["scroll" + name], document.body["offset" + name], document.documentElement["offset" + name] ) : // Get or set width or height on the element size === undefined ? // Get width or height on the element (this.length ? jQuery.css( this[0], type ) : null) : // Set the width or height on the element (default to pixels if value is unitless) this.css( type, typeof size === "string" ? size : size + "px" ); }; });