From 92a9e73bbef6f995c4b4fc6fb6c566432f2d0671 Mon Sep 17 00:00:00 2001 From: John Resig <jeresig@gmail.com> Date: Sun, 23 Sep 2007 16:55:19 +0000 Subject: [PATCH] Completely overhauled the syntax of core - re-worked variable names, formatting, comments, and some structure. --- src/core.js | 998 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 575 insertions(+), 423 deletions(-) diff --git a/src/core.js b/src/core.js index 92945a4..3b0c465 100644 --- a/src/core.js +++ b/src/core.js @@ -13,11 +13,11 @@ if ( typeof jQuery != "undefined" ) var _jQuery = jQuery; -var jQuery = window.jQuery = function(selector, context) { +var jQuery = window.jQuery = function( selector, context ) { // If the context is a namespace object, return a new object return this instanceof jQuery ? - this.init(selector, context) : - new jQuery(selector, context); + this.init( selector, context ) : + new jQuery( selector, context ); }; // Map over the $ in case of overwrite @@ -27,67 +27,84 @@ if ( typeof $ != "undefined" ) // Map the jQuery namespace to the '$' one window.$ = jQuery; +// A simple way to check for HTML strings or ID strings +// (both of which we optimize for) var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/; jQuery.fn = jQuery.prototype = { - init: function(selector, context) { + init: function( selector, context ) { // Make sure that a selection was provided selector = selector || document; // Handle HTML strings if ( typeof selector == "string" ) { - var m = quickExpr.exec(selector); - if ( m && (m[1] || !context) ) { + // Are we dealing with HTML string or an ID? + var match = quickExpr.exec( selector ); + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + // HANDLE: $(html) -> $(array) - if ( m[1] ) - selector = jQuery.clean( [ m[1] ], context ); + if ( match[1] ) + selector = jQuery.clean( [ match[1] ], context ); // HANDLE: $("#id") else { - var tmp = document.getElementById( m[3] ); - if ( tmp ) + var elem = document.getElementById( match[3] ); + + // Make sure an element was located + if ( elem ) // Handle the case where IE and Opera return items // by name instead of ID - if ( tmp.id != m[3] ) + if ( elem.id != match[3] ) return jQuery().find( selector ); + + // Otherwise, we inject the element directly into the jQuery object else { - this[0] = tmp; + this[0] = elem; this.length = 1; return this; } + else selector = []; } - // HANDLE: $(expr) + // HANDLE: $(expr, [context]) + // (which is just equivalent to: $(content).find(expr) } else return new jQuery( context ).find( selector ); // HANDLE: $(function) // Shortcut for document ready - } else if ( jQuery.isFunction(selector) ) - return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( selector ); + } else if ( jQuery.isFunction( selector ) ) + return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector ); return this.setArray( // HANDLE: $(array) selector.constructor == Array && selector || // HANDLE: $(arraylike) - // Watch for when an array-like object is passed as the selector + // Watch for when an array-like object, contains DOM nodes, is passed in as the selector (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) || // HANDLE: $(*) [ selector ] ); }, + // The current version of jQuery being used jquery: "@VERSION", + // The number of elements contained in the matched element set size: function() { return this.length; }, + // The number of elements contained in the matched element set length: 0, + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array get: function( num ) { return num == undefined ? @@ -95,52 +112,77 @@ jQuery.fn = jQuery.prototype = { jQuery.makeArray( this ) : // Return just the object - this[num]; + this[ num ]; }, - pushStack: function( a ) { - var ret = jQuery(a); + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + // Build a new jQuery matched element set + var ret = jQuery( elems ); + + // Add the old object onto the stack (as a reference) ret.prevObject = this; + + // Return the newly-formed element set return ret; }, - setArray: function( a ) { + // Force the current matched set of elements to become + // the specified array of elements (destroying the stack in the process) + // You should use pushStack() in order to do this, but maintain the stack + setArray: function( elems ) { + // Resetting the length to 0, then using the native Array push + // is a super-fast way to populate an object with array-like properties this.length = 0; - Array.prototype.push.apply( this, a ); + Array.prototype.push.apply( this, elems ); + return this; }, - each: function( fn, args ) { - return jQuery.each( this, fn, args ); + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); }, - index: function( obj ) { - var pos = -1; + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + var ret = -1; + + // Locate the position of the desired element this.each(function(i){ - if ( this == obj ) pos = i; + if ( this == elem ) + ret = i; }); - return pos; + + return ret; }, - attr: function( key, value, type ) { - var obj = key; + attr: function( name, value, type ) { + var options = name; // Look for the case where we're accessing a style value - if ( key.constructor == String ) + if ( name.constructor == String ) if ( value == undefined ) - return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined; + return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined; + else { - obj = {}; - obj[ key ] = value; + options = {}; + options[ name ] = value; } // Check to see if we're setting style values - return this.each(function(index){ + return this.each(function(i){ // Set all the styles - for ( var prop in obj ) + for ( name in options ) jQuery.attr( - type ? this.style : this, - prop, jQuery.prop(this, obj[prop], type, index, prop) + type ? + this.style : + this, + name, jQuery.prop( this, options[ name ], type, i, name ) ); }); }, @@ -149,31 +191,36 @@ jQuery.fn = jQuery.prototype = { return this.attr( key, value, "curCSS" ); }, - text: function(e) { - if ( typeof e != "object" && e != null ) - return this.empty().append( document.createTextNode( e ) ); + text: function( text ) { + if ( typeof text != "object" && text != null ) + return this.empty().append( document.createTextNode( text ) ); + + var ret = ""; - var t = ""; - jQuery.each( e || this, function(){ + jQuery.each( text || this, function(){ jQuery.each( this.childNodes, function(){ if ( this.nodeType != 8 ) - t += this.nodeType != 1 ? - this.nodeValue : jQuery.fn.text([ this ]); + ret += this.nodeType != 1 ? + this.nodeValue : + jQuery.fn.text( [ this ] ); }); }); - return t; + + return ret; }, - wrapAll: function(html) { + wrapAll: function( html ) { if ( this[0] ) // The elements to wrap the target around - jQuery(html, this[0].ownerDocument) + jQuery( html, this[0].ownerDocument ) .clone() - .insertBefore(this[0]) + .insertBefore( this[0] ) .map(function(){ var elem = this; + while ( elem.firstChild ) elem = elem.firstChild; + return elem; }) .append(this); @@ -181,56 +228,62 @@ jQuery.fn = jQuery.prototype = { return this; }, - wrapInner: function(html) { + wrapInner: function( html ) { return this.each(function(){ - jQuery(this).contents().wrapAll(html); + jQuery( this ).contents().wrapAll( html ); }); }, - wrap: function(html) { + wrap: function( html ) { return this.each(function(){ - jQuery(this).wrapAll(html); + jQuery( this ).wrapAll( html ); }); }, append: function() { - return this.domManip(arguments, true, 1, function(a){ - this.appendChild( a ); + return this.domManip(arguments, true, false, function(elem){ + this.appendChild( elem ); }); }, prepend: function() { - return this.domManip(arguments, true, -1, function(a){ - this.insertBefore( a, this.firstChild ); + return this.domManip(arguments, true, true, function(elem){ + this.insertBefore( elem, this.firstChild ); }); }, before: function() { - return this.domManip(arguments, false, 1, function(a){ - this.parentNode.insertBefore( a, this ); + return this.domManip(arguments, false, false, function(elem){ + this.parentNode.insertBefore( elem, this ); }); }, after: function() { - return this.domManip(arguments, false, -1, function(a){ - this.parentNode.insertBefore( a, this.nextSibling ); + return this.domManip(arguments, false, true, function(elem){ + this.parentNode.insertBefore( elem, this.nextSibling ); }); }, end: function() { - return this.prevObject || jQuery([]); + return this.prevObject || jQuery( [] ); }, - find: function(t) { - var data = jQuery.map(this, function(a){ return jQuery.find(t,a); }); - return this.pushStack( /[^+>] [^+>]/.test( t ) || t.indexOf("..") > -1 ? - jQuery.unique( data ) : data ); + find: function( selector ) { + var elems = jQuery.map(this, function(elem){ + return jQuery.find( selector, elem ); + }); + + return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? + jQuery.unique( elems ) : + elems ); }, - clone: function(events) { + clone: function( events ) { // Do the clone var ret = this.map(function(){ - return this.outerHTML ? jQuery(this.outerHTML)[0] : this.cloneNode(true); + return this.outerHTML ? + jQuery( this.outerHTML )[0] : + this.cloneNode( true ); }); // Need to set the expando to null on the cloned set if it exists @@ -242,68 +295,65 @@ jQuery.fn = jQuery.prototype = { }); // Copy the events from the original to the clone - if (events === true) - this.find("*").andSelf().each(function(i) { - var events = jQuery.data(this, "events"); + if ( events === true ) + this.find("*").andSelf().each(function(i){ + var events = jQuery.data( this, "events" ); + for ( var type in events ) - for ( var handler in events[type] ) - jQuery.event.add(clone[i], type, events[type][handler], events[type][handler].data); + for ( var handler in events[ type ] ) + jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); }); // Return the cloned set return ret; }, - filter: function(t) { + filter: function( selector ) { return this.pushStack( - jQuery.isFunction( t ) && - jQuery.grep(this, function(el, index){ - return t.apply(el, [index]); + jQuery.isFunction( selector ) && + jQuery.grep(this, function(elem, i){ + return selector.call( elem, i ); }) || - jQuery.multiFilter(t,this) ); + jQuery.multiFilter( selector, this ) ); }, - not: function(t) { + not: function( selector ) { return this.pushStack( - t.constructor == String && - jQuery.multiFilter(t, this, true) || - - jQuery.grep(this, function(a) { - return ( t.constructor == Array || t.jquery ) - ? jQuery.inArray( a, t ) < 0 - : a != t; - }) - ); + selector.constructor == String && + jQuery.multiFilter( selector, this, true ) || + + jQuery.grep(this, function(elem) { + return selector.constructor == Array || selector.jquery ? + jQuery.inArray( elem, selector ) < 0 : + elem != selector; + }) ); }, - add: function(t) { - return this.pushStack( jQuery.merge( - this.get(), - t.constructor == String ? - jQuery(t).get() : - t.length != undefined && (!t.nodeName || jQuery.nodeName(t, "form")) ? - t : [t] ) - ); + add: function( selector ) { + return this.pushStack( jQuery.merge( this.get(), jQuery( selector ) ) ); }, - is: function(expr) { - return expr ? jQuery.multiFilter(expr,this).length > 0 : false; + is: function( selector ) { + return selector ? + jQuery.multiFilter( selector, this ).length > 0 : + false; }, - hasClass: function(expr) { - return this.is("." + expr); + hasClass: function( selector ) { + return this.is( "." + selector ); }, - val: function( val ) { - if ( val == undefined ) { + val: function( value ) { + if ( value == undefined ) { + if ( this.length ) { var elem = this[0]; // We need to handle select boxes special - if ( jQuery.nodeName(elem, "select") ) { + if ( jQuery.nodeName( elem, "select" ) ) { var index = elem.selectedIndex, - a = [], + values = [], options = elem.options, one = elem.type == "select-one"; @@ -313,67 +363,76 @@ jQuery.fn = jQuery.prototype = { // Loop through all the selected options for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[i]; + var option = options[ i ]; + if ( option.selected ) { // Get the specifc value for the option - var val = jQuery.browser.msie && !option.attributes["value"].specified ? option.text : option.value; + value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; // We don't need an array for one selects if ( one ) - return val; + return value; // Multi-Selects return an array - a.push(val); + values.push( value ); } } - return a; + return values; // Everything else, we just grab the value } else return this[0].value.replace(/\r/g, ""); + } + } else return this.each(function(){ - if ( val.constructor == Array && /radio|checkbox/.test(this.type) ) - this.checked = (jQuery.inArray(this.value, val) >= 0 || - jQuery.inArray(this.name, val) >= 0); - else if ( jQuery.nodeName(this, "select") ) { - var tmp = val.constructor == Array ? val : [val]; - - jQuery("option", this).each(function(){ - this.selected = (jQuery.inArray(this.value, tmp) >= 0 || - jQuery.inArray(this.text, tmp) >= 0); + if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) + this.checked = (jQuery.inArray(this.value, value) >= 0 || + jQuery.inArray(this.name, value) >= 0); + + else if ( jQuery.nodeName( this, "select" ) ) { + var values = value.constructor == Array ? + value : + [ value ]; + + jQuery( "option", this ).each(function(){ + this.selected = (jQuery.inArray( this.value, values ) >= 0 || + jQuery.inArray( this.text, values ) >= 0); }); if ( !tmp.length ) this.selectedIndex = -1; + } else - this.value = val; + this.value = value; }); }, - html: function( val ) { - return val == undefined ? - ( this.length ? this[0].innerHTML : null ) : - this.empty().append( val ); + html: function( value ) { + return value == undefined ? + (this.length ? + this[0].innerHTML : + null) : + this.empty().append( value ); }, - replaceWith: function( val ) { - return this.after( val ).remove(); + replaceWith: function( value ) { + return this.after( value ).remove(); }, - eq: function(i){ - return this.slice(i, i+1); + eq: function( i ) { + return this.slice( i, i + 1 ); }, slice: function() { return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); }, - map: function(fn) { - return this.pushStack(jQuery.map( this, function(elem,i){ - return fn.call( elem, i, elem ); + map: function( callback ) { + return this.pushStack( jQuery.map(this, function(elem, i){ + return callback.call( elem, i, elem ); })); }, @@ -381,51 +440,60 @@ jQuery.fn = jQuery.prototype = { return this.add( this.prevObject ); }, - domManip: function(args, table, dir, fn) { - var clone = this.length > 1, a; + domManip: function( args, table, reverse, callback ) { + var clone = this.length > 1, elems; return this.each(function(){ - if ( !a ) { - a = jQuery.clean(args, this.ownerDocument); - if ( dir < 0 ) - a.reverse(); + if ( !elems ) { + elems = jQuery.clean( args, this.ownerDocument ); + + if ( reverse ) + elems.reverse(); } var obj = this; - if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") ) - obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody")); + if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) + obj = this.getElementsByTagName("tbody")[0] || this.appendChild( document.createElement("tbody") ); + + jQuery.each(elems, function(){ + var elem = clone ? + this.cloneNode( true ) : + this; - jQuery.each( a, function(){ - var elem = clone ? this.cloneNode(true) : this; - if ( !evalScript(0, elem) ) - fn.call( obj, elem ); + if ( !evalScript( 0, elem ) ) + callback.call( obj, elem ); }); }); } }; -function evalScript(i, elem){ - var script = jQuery.nodeName(elem, "script"); +function evalScript( i, elem ) { + var script = jQuery.nodeName( elem, "script" ); if ( script ) { if ( elem.src ) - jQuery.ajax({ url: elem.src, async: false, dataType: "script" }); + jQuery.ajax({ + url: elem.src, + async: false, + dataType: "script" + }); + else jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); if ( elem.parentNode ) - elem.parentNode.removeChild(elem); + elem.parentNode.removeChild( elem ); } else if ( elem.nodeType == 1 ) - jQuery("script", elem).each(evalScript); + jQuery( "script", elem ).each( evalScript ); return script; } jQuery.extend = jQuery.fn.extend = function() { // copy reference to target object - var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false; + var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; // Handle a deep copy situation if ( target.constructor == Boolean ) { @@ -434,42 +502,46 @@ jQuery.extend = jQuery.fn.extend = function() { } // extend jQuery itself if only one argument is passed - if ( al == 1 ) { + if ( length == 1 ) { target = this; - a = 0; + i = 0; } - var prop; - - for ( ; a < al; a++ ) + for ( ; i < length; i++ ) // Only deal with non-null/undefined values - if ( (prop = arguments[a]) != null ) + if ( (options = arguments[ i ]) != null ) // Extend the base object - for ( var i in prop ) { + for ( var name in options ) { // Prevent never-ending loop - if ( target == prop[i] ) + if ( target == options[ name ] ) continue; // Recurse if we're merging object values - if ( deep && typeof prop[i] == 'object' && target[i] ) - jQuery.extend( target[i], prop[i] ); + if ( deep && typeof options[ name ] == "object" && target[ name ] ) + jQuery.extend( target[ name ], options[ name ] ); // Don't bring in undefined values - else if ( prop[i] != undefined ) - target[i] = prop[i]; + else if ( options[ name ] != undefined ) + target[ name ] = options[ name ]; + } // Return the modified object return target; }; -var expando = "jQuery" + (new Date()).getTime(), uuid = 0, win = {}; +var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {}; + +// exclude the following css properties to add px +var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i; jQuery.extend({ - noConflict: function(deep) { + noConflict: function( deep ) { window.$ = _$; + if ( deep ) window.jQuery = _jQuery; + return jQuery; }, @@ -480,8 +552,8 @@ jQuery.extend({ fn.constructor != Array && /function/i.test( fn + "" ); }, - // check if an element is in a XML document - isXMLDoc: function(elem) { + // check if an element is in a (or is an) XML document + isXMLDoc: function( elem ) { return elem.documentElement && !elem.body || elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; }, @@ -490,12 +562,15 @@ jQuery.extend({ // Evaluates Async. in Safari 2 :-( globalEval: function( data ) { data = jQuery.trim( data ); + if ( data ) { if ( window.execScript ) window.execScript( data ); + else if ( jQuery.browser.safari ) // safari doesn't provide a synchronous global eval window.setTimeout( data, 0 ); + else eval.call( window, data ); } @@ -508,7 +583,9 @@ jQuery.extend({ cache: {}, data: function( elem, name, data ) { - elem = elem == window ? win : elem; + elem = elem == window ? + windowData : + elem; var id = elem[ expando ]; @@ -526,11 +603,15 @@ jQuery.extend({ jQuery.cache[ id ][ name ] = data; // Return the named cache data, or the ID for the element - return name ? jQuery.cache[ id ][ name ] : id; + return name ? + jQuery.cache[ id ][ name ] : + id; }, removeData: function( elem, name ) { - elem = elem == window ? win : elem; + elem = elem == window ? + windowData : + elem; var id = elem[ expando ]; @@ -542,7 +623,10 @@ jQuery.extend({ // If we've removed all the data, remove the element's cache name = ""; - for ( name in jQuery.cache[ id ] ) break; + + for ( name in jQuery.cache[ id ] ) + break; + if ( !name ) jQuery.removeData( elem ); } @@ -565,194 +649,228 @@ jQuery.extend({ }, // args is for internal usage only - each: function( obj, fn, args ) { + each: function( object, callback, args ) { if ( args ) { - if ( obj.length == undefined ) - for ( var i in obj ) - fn.apply( obj[i], args ); + if ( object.length == undefined ) + for ( var name in object ) + callback.apply( object[ name ], args ); else - for ( var i = 0, ol = obj.length; i < ol; i++ ) - if ( fn.apply( obj[i], args ) === false ) break; + for ( var i = 0, length = object.length; i < length; i++ ) + if ( callback.apply( object[ i ], args ) === false ) + break; // A special, fast, case for the most common use of each } else { - if ( obj.length == undefined ) - for ( var i in obj ) - fn.call( obj[i], i, obj[i] ); + if ( object.length == undefined ) + for ( var name in object ) + callback.call( object[ name ], name, object[ name ] ); else - for ( var i = 0, ol = obj.length, val = obj[0]; - i < ol && fn.call(val,i,val) !== false; val = obj[++i] ){} + for ( var i = 0, length = object.length, value = object[0]; + i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} } - return obj; + return object; }, - prop: function(elem, value, type, index, prop){ + prop: function( elem, value, type, i, name ) { // Handle executable functions if ( jQuery.isFunction( value ) ) - value = value.call( elem, [index] ); + value = value.call( elem, i ); - // exclude the following css properties to add px - var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i; - // Handle passing in a number to a CSS property - return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ? + return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ? value + "px" : value; }, className: { // internal only, use addClass("class") - add: function( elem, c ){ - jQuery.each( (c || "").split(/\s+/), function(i, cur){ - if ( !jQuery.className.has( elem.className, cur ) ) - elem.className += ( elem.className ? " " : "" ) + cur; + add: function( elem, classNames ) { + jQuery.each((classNames || "").split(/\s+/), function(i, className){ + if ( !jQuery.className.has( elem.className, className ) ) + elem.className += (elem.className ? " " : "") + className; }); }, // internal only, use removeClass("class") - remove: function( elem, c ){ - elem.className = c != undefined ? - jQuery.grep( elem.className.split(/\s+/), function(cur){ - return !jQuery.className.has( c, cur ); - }).join(" ") : ""; + remove: function( elem, classNames ) { + elem.className = classNames != undefined ? + jQuery.grep(elem.className.split(/\s+/), function(className){ + return !jQuery.className.has( classNames, className ); + }).join(" ") : + ""; }, // internal only, use is(".class") - has: function( t, c ) { - return jQuery.inArray( c, (t.className || t).toString().split(/\s+/) ) > -1; + has: function( elem, className ) { + return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; } }, - swap: function(e,o,f) { - for ( var i in o ) { - e.style["old"+i] = e.style[i]; - e.style[i] = o[i]; + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + // Remember the old values, and insert the new ones + for ( var name in options ) { + elem.style[ "old" + name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; } - f.apply( e, [] ); - for ( var i in o ) - e.style[i] = e.style["old"+i]; + + callback.call( elem ); + + // Revert the old values + for ( var name in options ) + elem.style[ name ] = elem.style[ "old" + name ]; }, - css: function(e,p) { - if ( p == "height" || p == "width" ) { - var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"]; + css: function( elem, name ) { + if ( name == "height" || name == "width" ) { + var old = {}, height, width; - jQuery.each( d, function(){ - old["padding" + this] = 0; - old["border" + this + "Width"] = 0; + // Revert the padding and border widths to get the + // correct height/width values + jQuery.each([ "Top", "Bottom", "Right", "Left" ], function(){ + old[ "padding" + this ] = 0; + old[ "border" + this + "Width" ] = 0; }); - jQuery.swap( e, old, function() { - if ( jQuery(e).is(':visible') ) { - oHeight = e.offsetHeight; - oWidth = e.offsetWidth; + // Swap out the padding/border values temporarily + jQuery.swap( elem, old, function() { + + // If the element is visible, then the calculation is easy + if ( jQuery( elem ).is(":visible") ) { + height = elem.offsetHeight; + width = elem.offsetWidth; + + // Otherwise, we need to flip out more values } else { - e = jQuery(e.cloneNode(true)) + elem = jQuery( elem.cloneNode(true) ) .find(":radio").removeAttr("checked").end() .css({ - visibility: "hidden", position: "absolute", display: "block", right: "0", left: "0" - }).appendTo(e.parentNode)[0]; + visibility: "hidden", + position: "absolute", + display: "block", + right: "0", + left: "0" + }).appendTo( elem.parentNode )[0]; - var parPos = jQuery.css(e.parentNode,"position") || "static"; - if ( parPos == "static" ) - e.parentNode.style.position = "relative"; + var position = jQuery.css( elem.parentNode, "position" ) || "static"; + if ( position == "static" ) + elem.parentNode.style.position = "relative"; - oHeight = e.clientHeight; - oWidth = e.clientWidth; + height = elem.clientHeight; + width = elem.clientWidth; - if ( parPos == "static" ) - e.parentNode.style.position = "static"; + if ( position == "static" ) + elem.parentNode.style.position = "static"; - e.parentNode.removeChild(e); + elem.parentNode.removeChild( elem ); } }); - return p == "height" ? oHeight : oWidth; + return name == "height" ? + height : + width; } - return jQuery.curCSS( e, p ); + return jQuery.curCSS( elem, name ); }, - curCSS: function(elem, prop, force) { - var ret, stack = [], swap = []; + curCSS: function( elem, name, force ) { + var ret; // A helper method for determining if an element's values are broken - function color(a){ + function color( elem ) { if ( !jQuery.browser.safari ) return false; - var ret = document.defaultView.getComputedStyle(a,null); + var ret = document.defaultView.getComputedStyle( elem, null ); return !ret || ret.getPropertyValue("color") == ""; } - if (prop == "opacity" && jQuery.browser.msie) { - ret = jQuery.attr(elem.style, "opacity"); - return ret == "" ? "1" : ret; + // We need to handle opacity special in IE + if ( name == "opacity" && jQuery.browser.msie ) { + ret = jQuery.attr( elem.style, "opacity" ); + + return ret == "" ? + "1" : + ret; } - if (prop.match(/float/i)) - prop = styleFloat; + // Make sure we're using the right name for getting the float value + if ( name.match( /float/i ) ) + name = styleFloat; + + if ( !force && elem.style[ name ] ) + ret = elem.style[ name ]; - if (!force && elem.style[prop]) - ret = elem.style[prop]; + else if ( document.defaultView && document.defaultView.getComputedStyle ) { - else if (document.defaultView && document.defaultView.getComputedStyle) { + // Only "float" is needed here + if ( name.match( /float/i ) ) + name = "float"; - if (prop.match(/float/i)) - prop = "float"; + name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); - prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase(); - var cur = document.defaultView.getComputedStyle(elem, null); + var getComputedStyle = document.defaultView.getComputedStyle( elem, null ); - if ( cur && !color(elem) ) - ret = cur.getPropertyValue(prop); + if ( getComputedStyle && !color( elem ) ) + ret = getComputedStyle.getPropertyValue( name ); // If the element isn't reporting its values properly in Safari // then some display: none elements are involved else { + var swap = [], stack = []; + // Locate all of the parent display: none elements for ( var a = elem; a && color(a); a = a.parentNode ) stack.unshift(a); // Go through and make them visible, but in reverse // (It would be better if we knew the exact display type that they had) - for ( a = 0; a < stack.length; a++ ) - if ( color(stack[a]) ) { - swap[a] = stack[a].style.display; - stack[a].style.display = "block"; + for ( var i = 0; i < stack.length; i++ ) + if ( color( stack[ i ] ) ) { + swap[ i ] = stack[ i ].style.display; + stack[ i ].style.display = "block"; } // Since we flip the display style, we have to handle that // one special, otherwise get the value - ret = prop == "display" && swap[stack.length-1] != null ? + ret = name == "display" && swap[ stack.length - 1 ] != null ? "none" : - document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop) || ""; + document.defaultView.getComputedStyle( elem, null ).getPropertyValue( name ) || ""; // Finally, revert the display styles back - for ( a = 0; a < swap.length; a++ ) - if ( swap[a] != null ) - stack[a].style.display = swap[a]; + for ( var i = 0; i < swap.length; i++ ) + if ( swap[ i ] != null ) + stack[ i ].style.display = swap[ i ]; } - if ( prop == "opacity" && ret == "" ) + // We should always get a number back from opacity + if ( name == "opacity" && ret == "" ) ret = "1"; - } else if (elem.currentStyle) { - var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();}); - ret = elem.currentStyle[prop] || elem.currentStyle[newProp]; + } else if ( elem.currentStyle ) { + var camelCase = name.replace(/\-(\w)/g, function(all, letter){ + return letter.toUpperCase(); + }); + + ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; // From the awesome hack by Dean Edwards // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 // If we're not dealing with a regular pixel number // but a number that has a weird ending, we need to convert it to pixels - if ( !/^\d+(px)?$/i.test(ret) && /^\d/.test(ret) ) { - var style = elem.style.left; - var runtimeStyle = elem.runtimeStyle.left; + if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { + // Remember the original values + var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left; + + // Put in the new values to get a computed value out elem.runtimeStyle.left = elem.currentStyle.left; elem.style.left = ret || 0; ret = elem.style.pixelLeft + "px"; + + // Revert the changed values elem.style.left = style; elem.runtimeStyle.left = runtimeStyle; } @@ -761,55 +879,58 @@ jQuery.extend({ return ret; }, - clean: function(a, doc) { - var r = []; - doc = doc || document; + clean: function( elems, context ) { + var ret = []; + context = context || document; - jQuery.each( a, function(i,arg){ - if ( !arg ) return; + jQuery.each(elems, function(i, elem){ + if ( !elem ) + return; - if ( arg.constructor == Number ) - arg = arg.toString(); + if ( elem.constructor == Number ) + elem = elem.toString(); // Convert html string into DOM nodes - if ( typeof arg == "string" ) { + if ( typeof elem == "string" ) { // Fix "XHTML"-style tags in all browsers - arg = arg.replace(/(<(\w+)[^>]*?)\/>/g, function(m, all, tag){ - return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)? m : all+"></"+tag+">"; + elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ + return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i) ? + all : + front + "></" + tag + ">"; }); // Trim whitespace, otherwise indexOf won't work as expected - var s = jQuery.trim(arg).toLowerCase(), div = doc.createElement("div"), tb = []; + var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div"); var wrap = // option or optgroup - !s.indexOf("<opt") && - [1, "<select>", "</select>"] || + !tags.indexOf("<opt") && + [ 1, "<select>", "</select>" ] || - !s.indexOf("<leg") && - [1, "<fieldset>", "</fieldset>"] || + !tags.indexOf("<leg") && + [ 1, "<fieldset>", "</fieldset>" ] || - s.match(/^<(thead|tbody|tfoot|colg|cap)/) && - [1, "<table>", "</table>"] || + tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && + [ 1, "<table>", "</table>" ] || - !s.indexOf("<tr") && - [2, "<table><tbody>", "</tbody></table>"] || + !tags.indexOf("<tr") && + [ 2, "<table><tbody>", "</tbody></table>" ] || // <thead> matched above - (!s.indexOf("<td") || !s.indexOf("<th")) && - [3, "<table><tbody><tr>", "</tr></tbody></table>"] || + (!tags.indexOf("<td") || !tags.indexOf("<th")) && + [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] || - !s.indexOf("<col") && - [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"] || + !tags.indexOf("<col") && + [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] || // IE can't serialize <link> and <script> tags normally jQuery.browser.msie && - [1, "div<div>", "</div>"] || + [ 1, "div<div>", "</div>" ] || - [0,"",""]; + [ 0, "", "" ]; // Go to html and back, then peel off extra wrappers - div.innerHTML = wrap[1] + arg + wrap[2]; + div.innerHTML = wrap[1] + elem + wrap[2]; // Move to the right depth while ( wrap[0]-- ) @@ -819,41 +940,45 @@ jQuery.extend({ if ( jQuery.browser.msie ) { // String was a <table>, *may* have spurious <tbody> - if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 ) - tb = div.firstChild && div.firstChild.childNodes; + var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ? + div.firstChild && div.firstChild.childNodes : - // String was a bare <thead> or <tfoot> - else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 ) - tb = div.childNodes; - - for ( var n = tb.length-1; n >= 0 ; --n ) - if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length ) - tb[n].parentNode.removeChild(tb[n]); + // String was a bare <thead> or <tfoot> + wrap[1] == "<table>" && s.indexOf("<tbody") < 0 ? + div.childNodes : + []; + + for ( var i = tbody.length - 1; i >= 0 ; --i ) + if ( jQuery.nodeName( tbody[ i ], "tbody" ) && !tbody[ i ].childNodes.length ) + tbody[ i ].parentNode.removeChild( tbody[ i ] ); // IE completely kills leading whitespace when innerHTML is used - if ( /^\s/.test(arg) ) - div.insertBefore( doc.createTextNode( arg.match(/^\s*/)[0] ), div.firstChild ); + if ( /^\s/.test( elem ) ) + div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild ); } - arg = jQuery.makeArray( div.childNodes ); + elem = jQuery.makeArray( div.childNodes ); } - if ( 0 === arg.length && (!jQuery.nodeName(arg, "form") && !jQuery.nodeName(arg, "select")) ) + if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) ) return; - if ( arg[0] == undefined || jQuery.nodeName(arg, "form") || arg.options ) - r.push( arg ); + if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options ) + ret.push( elem ); + else - r = jQuery.merge( r, arg ); + ret = jQuery.merge( ret, elem ); }); - return r; + return ret; }, - attr: function(elem, name, value){ - var fix = jQuery.isXMLDoc(elem) ? {} : jQuery.props; + attr: function( elem, name, value ) { + var fix = jQuery.isXMLDoc( elem ) ? + {} : + jQuery.props; // Safari mis-reports the default selected property of a hidden option // Accessing the parent's selectedIndex property fixes it @@ -861,25 +986,30 @@ jQuery.extend({ elem.parentNode.selectedIndex; // Certain attributes only work when accessed via the old DOM 0 way - if ( fix[name] ) { - if ( value != undefined ) elem[fix[name]] = value; - return elem[fix[name]]; + if ( fix[ name ] ) { + if ( value != undefined ) + elem[ fix[ name ] ] = value; + + return elem[ fix[ name ] ]; + } else if ( jQuery.browser.msie && name == "style" ) return jQuery.attr( elem.style, "cssText", value ); - else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName(elem, "form") && (name == "action" || name == "method") ) - return elem.getAttributeNode(name).nodeValue; + else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName( elem, "form" ) && (name == "action" || name == "method") ) + return elem.getAttributeNode( name ).nodeValue; // IE elem.getAttribute passes even for style else if ( elem.tagName ) { if ( value != undefined ) { - if ( name == "type" && jQuery.nodeName(elem,"input") && elem.parentNode ) + // We can't allow the type property to be changed (since it causes problems in IE) + if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode ) throw "type property can't be changed"; + elem.setAttribute( name, value ); } - if ( jQuery.browser.msie && /href|src/.test(name) && !jQuery.isXMLDoc(elem) ) + if ( jQuery.browser.msie && /href|src/.test( name ) && !jQuery.isXMLDoc( elem ) ) return elem.getAttribute( name, 2 ); return elem.getAttribute( name ); @@ -894,115 +1024,124 @@ jQuery.extend({ elem.zoom = 1; // Set the alpha filter to set the opacity - elem.filter = (elem.filter || "").replace(/alpha\([^)]*\)/,"") + - (parseFloat(value).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); + elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) + + (parseFloat( value ).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); } return elem.filter ? - (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : ""; + (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : + ""; } - name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();}); - if ( value != undefined ) elem[name] = value; - return elem[name]; + + name = name.replace(/-([a-z])/ig, function(all, letter){ + return letter.toUpperCase(); + }); + + if ( value != undefined ) + elem[ name ] = value; + + return elem[ name ]; } }, - trim: function(t){ - return (t||"").replace(/^\s+|\s+$/g, ""); + trim: function( text ) { + return (text || "").replace( /^\s+|\s+$/g, "" ); }, - makeArray: function( a ) { - var r = []; + makeArray: function( array ) { + var ret = []; // Need to use typeof to fight Safari childNodes crashes - if ( typeof a != "array" ) - for ( var i = 0, al = a.length; i < al; i++ ) - r.push( a[i] ); + if ( typeof array != "array" ) + for ( var i = 0, length = array.length; i < length; i++ ) + ret.push( array[ i ] ); else - r = a.slice( 0 ); + ret = array.slice( 0 ); - return r; + return ret; }, - inArray: function( b, a ) { - for ( var i = 0, al = a.length; i < al; i++ ) - if ( a[i] == b ) + inArray: function( elem, array ) { + for ( var i = 0, length = array.length; i < length; i++ ) + if ( array[ i ] == elem ) return i; + return -1; }, - merge: function(first, second) { + merge: function( first, second ) { // We have to loop this way because IE & Opera overwrite the length // expando of getElementsByTagName // Also, we need to make sure that the correct elements are being returned // (IE returns comment nodes in a '*' query) if ( jQuery.browser.msie ) { - for ( var i = 0; second[i]; i++ ) - if ( second[i].nodeType != 8 ) - first.push(second[i]); + for ( var i = 0; second[ i ]; i++ ) + if ( second[ i ].nodeType != 8 ) + first.push( second[ i ] ); + } else - for ( var i = 0; second[i]; i++ ) - first.push(second[i]); + for ( var i = 0; second[ i ]; i++ ) + first.push( second[ i ] ); return first; }, - unique: function(first) { - var r = [], done = {}; + unique: function( array ) { + var ret = [], done = {}; try { - for ( var i = 0, fl = first.length; i < fl; i++ ) { - var id = jQuery.data(first[i]); - if ( !done[id] ) { - done[id] = true; - r.push(first[i]); + + for ( var i = 0, length = array.length; i < length; i++ ) { + var id = jQuery.data( array[ i ] ); + + if ( !done[ id ] ) { + done[ id ] = true; + ret.push( array[ i ] ); } } - } catch(e) { - r = first; + + } catch( e ) { + ret = array; } - return r; + return ret; }, - grep: function(elems, fn, inv) { + grep: function( elems, callback, inv ) { // If a string is passed in for the function, make a function // for it (a handy shortcut) - if ( typeof fn == "string" ) - fn = eval("false||function(a,i){return " + fn + "}"); + if ( typeof callback == "string" ) + callback = eval("false||function(a,i){return " + callback + "}"); - var result = []; + var ret = []; // Go through the array, only saving the items // that pass the validator function - for ( var i = 0, el = elems.length; i < el; i++ ) - if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) ) - result.push( elems[i] ); + for ( var i = 0, length = elems.length; i < length; i++ ) + if ( !inv && callback( elems[ i ], i ) || inv && !callback( elems[ i ], i ) ) + ret.push( elems[ i ] ); - return result; + return ret; }, - map: function(elems, fn) { - // If a string is passed in for the function, make a function - // for it (a handy shortcut) - if ( typeof fn == "string" ) - fn = eval("false||function(a){return " + fn + "}"); - - var result = []; + map: function( elems, callback ) { + var ret = []; // Go through the array, translating each of the items to their // new value (or values). - for ( var i = 0, el = elems.length; i < el; i++ ) { - var val = fn(elems[i],i); + for ( var i = 0, length = elems.length; i < length; i++ ) { + var value = callback( elems[ i ], i ); - if ( val !== null && val != undefined ) { - if ( val.constructor != Array ) val = [val]; - result = result.concat( val ); + if ( value !== null && value != undefined ) { + if ( value.constructor != Array ) + value = [ value ]; + + ret = ret.concat( value ); } } - return result; + return ret; } }); @@ -1010,21 +1149,21 @@ var userAgent = navigator.userAgent.toLowerCase(); // Figure out what browser is being used jQuery.browser = { - version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1], - safari: /webkit/.test(userAgent), - opera: /opera/.test(userAgent), - msie: /msie/.test(userAgent) && !/opera/.test(userAgent), - mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent) + version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1], + safari: /webkit/.test( userAgent ), + opera: /opera/.test( userAgent ), + msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ), + mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent ) }; -var styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat"; +var styleFloat = jQuery.browser.msie ? + "styleFloat" : + "cssFloat"; jQuery.extend({ // Check to see if the W3C box model is being used boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat", - styleFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat", - props: { "for": "htmlFor", "class": "className", @@ -1044,21 +1183,25 @@ jQuery.extend({ }); jQuery.each({ - parent: "a.parentNode", - parents: "jQuery.dir(a,'parentNode')", - next: "jQuery.nth(a,2,'nextSibling')", - prev: "jQuery.nth(a,2,'previousSibling')", - nextAll: "jQuery.dir(a,'nextSibling')", - prevAll: "jQuery.dir(a,'previousSibling')", - siblings: "jQuery.sibling(a.parentNode.firstChild,a)", - children: "jQuery.sibling(a.firstChild)", - contents: "jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)" -}, function(i,n){ - jQuery.fn[ i ] = function(a) { - var ret = jQuery.map(this,n); - if ( a && typeof a == "string" ) - ret = jQuery.multiFilter(a,ret); - return this.pushStack( jQuery.unique(ret) ); + parent: "elem.parentNode", + parents: "jQuery.dir(elem,'parentNode')", + next: "jQuery.nth(elem,2,'nextSibling')", + prev: "jQuery.nth(elem,2,'previousSibling')", + nextAll: "jQuery.dir(elem,'nextSibling')", + prevAll: "jQuery.dir(elem,'previousSibling')", + siblings: "jQuery.sibling(elem.parentNode.firstChild,elem)", + children: "jQuery.sibling(elem.firstChild)", + contents: "jQuery.nodeName(elem,'iframe')?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes)" +}, function(name, fn){ + fn = eval("false||function(elem){return " + fn + "}"); + + jQuery.fn[ name ] = function( selector ) { + var ret = jQuery.map( this, fn ); + + if ( selector && typeof selector == "string" ) + ret = jQuery.multiFilter( selector, ret ); + + return this.pushStack( jQuery.unique( ret ) ); }; }); @@ -1068,74 +1211,83 @@ jQuery.each({ insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" -}, function(i,n){ - jQuery.fn[ i ] = function(){ - var a = arguments; +}, function(name, original){ + jQuery.fn[ name ] = function() { + var args = arguments; + return this.each(function(){ - for ( var j = 0, al = a.length; j < al; j++ ) - jQuery(a[j])[n]( this ); + for ( var i = 0, length = args.length; i < length; i++ ) + jQuery( args[ i ] )[ original ]( this ); }); }; }); -jQuery.each( { - removeAttr: function( key ) { - jQuery.attr( this, key, "" ); - this.removeAttribute( key ); +jQuery.each({ + removeAttr: function( name ) { + jQuery.attr( this, name, "" ); + this.removeAttribute( name ); }, - addClass: function(c){ - jQuery.className.add(this,c); + + addClass: function( classNames ) { + jQuery.className.add( this, classNames ); }, - removeClass: function(c){ - jQuery.className.remove(this,c); + + removeClass: function( classNames ) { + jQuery.className.remove( this, classNames ); }, - toggleClass: function( c ){ - jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c); + + toggleClass: function( classNames ) { + jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames ); }, - remove: function(a){ - if ( !a || jQuery.filter( a, [this] ).r.length ) { + + remove: function( selector ) { + if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) { jQuery.removeData( this ); this.parentNode.removeChild( this ); } }, + empty: function() { // Clean up the cache - jQuery("*", this).each(function(){ jQuery.removeData(this); }); + jQuery( "*", this ).each(function(){ + jQuery.removeData(this); + }); while ( this.firstChild ) this.removeChild( this.firstChild ); } -}, function(i,n){ - jQuery.fn[ i ] = function() { - return this.each( n, arguments ); +}, function(name, fn){ + jQuery.fn[ name ] = function(){ + return this.each( fn, arguments ); }; }); -jQuery.each( [ "Height", "Width" ], function(i,name){ - var n = name.toLowerCase(); +jQuery.each([ "Height", "Width" ], function(i, name){ + var type = name.toLowerCase(); - jQuery.fn[ n ] = function(h) { + jQuery.fn[ type ] = function( size ) { // Get window width or height return this[0] == window ? // Opera reports document.body.client[Width/Height] properly in both quirks and standards - jQuery.browser.opera && document.body["client" + name] || + jQuery.browser.opera && document.body[ "client" + name ] || // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths) - jQuery.browser.safari && self["inner" + name] || + jQuery.browser.safari && self[ "inner" + name ] || // 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] : + document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] : - // Get document width or height + // Get document width or height this[0] == document ? // Either scroll[Width/Height] or offset[Width/Height], whichever is greater (Mozilla reports scrollWidth the same as offsetWidth) - Math.max( document.body["scroll" + name], document.body["offset" + name] ) : + Math.max( document.body[ "scroll" + name ], document.body[ "offset" + name ] ) : - // Get or set width or height on the element - h == undefined ? + // Get or set width or height on the element + size == undefined ? // Get width or height on the element - ( this.length ? jQuery.css( this[0], n ) : null ) : + (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( n, h.constructor == String ? h : h + "px" ); + this.css( type, size.constructor == String ? size : size + "px" ); }; }); -- 1.7.10.4