From 75203de7435b7f32c69da1dde88aa6708bf6bb7d Mon Sep 17 00:00:00 2001 From: timmywil Date: Mon, 6 Jun 2011 23:35:16 -0400 Subject: [PATCH] Optimize width/height retrieval (moved logic to getWH, removed adjustWH). Supplements #9441, #9300. --- src/css.js | 101 ++++++++++++++++------------------------ src/dimensions.js | 6 +-- test/unit/dimensions.js | 15 +++--- 3 files changed, 50 insertions(+), 72 deletions(-) diff --git a/src/css.js b/src/css.js index 47e6f31e75..cc249ce798 100644 --- a/src/css.js +++ b/src/css.js @@ -172,51 +172,13 @@ jQuery.each(["height", "width"], function( i, name ) { if ( computed ) { if ( elem.offsetWidth !== 0 ) { - val = getWH( elem, name, extra ); + return getWH( elem, name, extra ); } else { jQuery.swap( elem, cssShow, function() { val = getWH( elem, name, extra ); }); } - if ( val <= 0 ) { - val = curCSS( elem, name, name ); - - if ( val === "0px" && currentStyle ) { - val = currentStyle( elem, name, name ); - } - - if ( val != null ) { - fellback = true; - } - } - - if ( !fellback && ( val < 0 || val == null ) ) { - val = elem.style[ name ]; - fellback = true; - } - - // Should return "auto" instead of 0, use 0 for - // temporary backwards-compat - if ( fellback && ( val === "" || val === "auto" ) ) { - val = "0px"; - } else if ( typeof val !== "string" ) { - val += "px"; - } - - if ( extra ) { - val = parseFloat( val ) || 0; - if ( fellback ) { - val += adjustWH( elem, name, "padding" ); - if ( extra !== "padding" ) { - val += adjustWH( elem, name, "border", "Width" ); - } - } - if ( extra === "margin" ) { - val += adjustWH( elem, name, "margin" ); - } - } - return val; } }, @@ -224,7 +186,7 @@ jQuery.each(["height", "width"], function( i, name ) { set: function( elem, value ) { if ( rnumpx.test( value ) ) { // ignore negative width and height values #1599 - value = parseFloat(value); + value = parseFloat( value ); if ( value >= 0 ) { return value + "px"; @@ -347,36 +309,51 @@ if ( document.documentElement.currentStyle ) { curCSS = getComputedStyle || currentStyle; function getWH( elem, name, extra ) { - var val = name === "width" ? elem.offsetWidth : elem.offsetHeight; - if ( extra === "border" ) { - return val; - } + // Start with offset property + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + which = name === "width" ? cssWidth : cssHeight; - if ( !extra ) { - val -= adjustWH( elem, name, "padding"); + if ( extra !== "margin" && extra !== "border" ) { + jQuery.each( which, function() { + val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; + if ( !extra ) { + val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; + } + }); } - if ( extra !== "margin" ) { - val -= adjustWH( elem, name, "border", "Width"); + if ( val > 0 ) { + if ( extra === "margin" ) { + jQuery.each( which, function() { + val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; + }); + } + return val + "px"; } - return val; -} - -function adjustWH( elem, name, prepend, append ) { - var which = name === "width" ? cssWidth : cssHeight, - val = 0; - - if( !append ){ - append = ""; + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ] || 0; + } + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + + // Add padding, border, margin + if ( extra ) { + jQuery.each( which, function() { + val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; + if ( extra !== "padding" ) { + val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( extra === "margin" ) { + val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; + } + }); } - jQuery.each( which, function() { - val += parseFloat( jQuery.css( elem, prepend + this + append ) ) || 0; - }); - - return val; + return val + "px"; } if ( jQuery.expr && jQuery.expr.filters ) { diff --git a/src/dimensions.js b/src/dimensions.js index 8559056b5b..88fa175061 100644 --- a/src/dimensions.js +++ b/src/dimensions.js @@ -1,12 +1,12 @@ (function( jQuery ) { -// Create innerHeight, innerWidth, outerHeight and outerWidth methods +// 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() { + jQuery.fn[ "inner" + name ] = function() { var elem = this[0]; return elem && elem.style ? parseFloat( jQuery.css( elem, type, "padding" ) ) : @@ -14,7 +14,7 @@ jQuery.each([ "Height", "Width" ], function( i, name ) { }; // outerHeight and outerWidth - jQuery.fn["outer" + name] = function( margin ) { + jQuery.fn[ "outer" + name ] = function( margin ) { var elem = this[0]; return elem && elem.style ? parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) : diff --git a/test/unit/dimensions.js b/test/unit/dimensions.js index 2b0637063a..57229199af 100644 --- a/test/unit/dimensions.js +++ b/test/unit/dimensions.js @@ -214,23 +214,24 @@ test("outerWidth()", function() { test("child of a hidden elem has accurate inner/outer/Width()/Height() see #9441 #9300", function() { expect(8); - //setup html - var $divNormal = jQuery( '
' ).css({ width: "100px", border: "10px solid white", padding: "2px", margin: "3px" }); - var $divChild = $divNormal.clone(); - var $divHiddenParent = jQuery( '
' ).css( "display", "none" ).append( $divChild ); - jQuery( 'body' ).append( $divHiddenParent ).append( $divNormal ); + // setup html + var $divNormal = jQuery("
").css({ width: "100px", height: "100px", border: "10px solid white", padding: "2px", margin: "3px" }), + $divChild = $divNormal.clone(), + $divHiddenParent = jQuery("
").css( "display", "none" ).append( $divChild ).appendTo("body"); + $divNormal.appendTo("body"); - //tests that child div of a hidden div works the same as a normal div + // tests that child div of a hidden div works the same as a normal div equals( $divChild.width(), $divNormal.width(), "child of a hidden element width() is wrong see #9441" ); equals( $divChild.innerWidth(), $divNormal.innerWidth(), "child of a hidden element innerWidth() is wrong see #9441" ); equals( $divChild.outerWidth(), $divNormal.outerWidth(), "child of a hidden element outerWidth() is wrong see #9441" ); equals( $divChild.outerWidth(true), $divNormal.outerWidth( true ), "child of a hidden element outerWidth( true ) is wrong see #9300" ); + equals( $divChild.height(), $divNormal.height(), "child of a hidden element height() is wrong see #9441" ); equals( $divChild.innerHeight(), $divNormal.innerHeight(), "child of a hidden element innerHeight() is wrong see #9441" ); equals( $divChild.outerHeight(), $divNormal.outerHeight(), "child of a hidden element outerHeight() is wrong see #9441" ); equals( $divChild.outerHeight(true), $divNormal.outerHeight( true ), "child of a hidden element outerHeight( true ) is wrong see #9300" ); - //teardown html + // teardown html $divHiddenParent.remove(); $divNormal.remove(); });