]> source.dussan.org Git - jquery.git/commitdiff
Fix 11004. getWH() box-sizing:border-box includes padding and border.
authorMike Sherov <mike.sherov@gmail.com>
Tue, 10 Apr 2012 21:18:00 +0000 (17:18 -0400)
committerDave Methvin <dave.methvin@gmail.com>
Tue, 10 Apr 2012 21:26:52 +0000 (17:26 -0400)
src/css.js
src/dimensions.js
src/support.js
test/unit/css.js

index afbf96afb753b70a617db69d0e2aa13b4cde3ff3..a4d31a62c438d057c9d5e68d49a11c7b760853a2 100644 (file)
@@ -272,15 +272,14 @@ curCSS = getComputedStyle || currentStyle;
 
 function getWidthOrHeight( elem, name, extra ) {
 
-       // Start with offset property
+       // Start with offset property, which is equivalent to the border-box value
        var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
                i = name === "width" ? 1 : 0,
                len = 4,
-               usedOffset = true;
+               valueIsBorderBox = true,
+               isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box";
 
        if ( val <= 0 ) {
-               usedOffset = false;
-
                // Fall back to computed then uncomputed css if necessary
                val = curCSS( elem, name );
                if ( val < 0 || val == null ) {
@@ -292,34 +291,47 @@ function getWidthOrHeight( elem, name, extra ) {
                        return val;
                }
 
+               // we need the check for style in case a browser which returns unreliable values
+               // for getComputedStyle silently falls back to the reliable elem.style
+               valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
+
                // Normalize "", auto, and prepare for extra
                val = parseFloat( val ) || 0;
        }
 
-       //if we're using border-box, the css width/height value behaves like the offsetWidth/Height property!
-       if ( usedOffset || ( jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" ) ) {
-               if ( extra !== "border" ) {
-                       for ( ; i < len; i += 2 ) {
-                               if ( !extra ) {
-                                       val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
+       // determine which box-sizing width we're supposed to be getting
+       if ( !extra ) {
+               extra = isBorderBox ? "border" : "content";
+       }
+
+       // if the measurement we need is already represented by the retrieved width
+       // there's no need to augment further
+       if ( extra !== (valueIsBorderBox ? "border" : "content") ) {
+               for ( ; i < len; i += 2 ) {
+                       // both box models exclude margin, so add it if we want it
+                       if ( extra === "margin" ) {
+                               // we use jQuery.css instead of curCSS here
+                               // because of the reliableMarginRight CSS hook!
+                               val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0;
+                       }
+
+                       if ( valueIsBorderBox ) {
+                               // border-box includes padding, so remove it if we want content
+                               if ( extra === "content" ) {
+                                       val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
                                }
-                               if ( extra === "margin" ) {
-                                       val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0;
-                               } else {
-                                       val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
+
+                               // at this point, extra isnt border nor margin, so remove border
+                               if ( extra !== "margin" ) {
+                                       val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
                                }
-                       }
-               }
-       } else {
-               // Add padding, border, margin
-               if ( extra ) {
-                       for ( ; i < len; i += 2 ) {
-                               val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
+                       } else {
+                               // at this point, extra isnt content, so add padding
+                               val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
+
+                               // at this point, extra isnt content nor padding, so add border
                                if ( extra !== "padding" ) {
-                                       val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
-                               }
-                               if ( extra === "margin" ) {
-                                       val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0;
+                                       val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
                                }
                        }
                }
index 1350b1fe37ef20bc1a7850d9ccd69878b8e2e426..9ea688d76d1f91f2f213bbd0dbda308dde85c981 100644 (file)
@@ -59,7 +59,7 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
 
                        // Get width or height on the element
                        if ( value === undefined ) {
-                               orig = jQuery.css( elem, type );
+                               orig = jQuery.css( elem, type, "content" );
                                ret = parseFloat( orig );
                                return jQuery.isNumeric( ret ) ? ret : orig;
                        }
index ccf9d4315610e436a779dfa7b81cecea3b7eee45..8e50a15b76fae7255f84735df1384cd539052969 100644 (file)
@@ -91,7 +91,8 @@ jQuery.support = (function() {
                inlineBlockNeedsLayout: false,
                shrinkWrapBlocks: false,
                reliableMarginRight: true,
-               pixelMargin: true
+               pixelMargin: true,
+               boxSizingReliable: true
        };
 
        // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead
@@ -251,17 +252,17 @@ jQuery.support = (function() {
                        support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
                }
 
-               div.style.cssText = boxSizingPrefixes.join("box-sizing:border-box;") + "width:4px;padding:1px;border:1px;display:block";
+               div.style.cssText = boxSizingPrefixes.join("box-sizing:border-box;") + "border:1px;width:4px;padding:1px;display:block;margin-top:1%;";
                support.boxSizing = ( div.offsetWidth === 4 );
+               if ( window.getComputedStyle ) {
+                       support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
+                       support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%";
+               }
 
                offsetSupport = {
                        doesNotIncludeMarginInBodyOffset: ( body.offsetTop !== conMarginTop )
                };
 
-               if ( window.getComputedStyle ) {
-                       div.style.marginTop = "1%";
-                       support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%";
-               }
 
                if ( typeof container.style.zoom !== "undefined" ) {
                        container.style.zoom = 1;
index 8e7f8ec104aca0bd69c9297c8f4be64c636a4ad6..6d0b39f812226201db13c23125f58d636cd02edb 100644 (file)
@@ -555,6 +555,18 @@ test("outerWidth(true) and css('margin') returning % instead of px in Webkit, se
        equal( el.outerWidth(true), 400, "outerWidth(true) and css('margin') returning % instead of px in Webkit, see #10639" );
 });
 
+test("css('width') should respect box-sizing, see #11004", function() {
+       var el_disconnected = jQuery("<div style='width:300px;margin:2px;padding:2px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;'>test</div>"),
+               el = el_disconnected.clone().appendTo("#qunit-fixture"),
+               width_initial = el.css("width"),
+               width_roundtrip = el.css("width", el.css("width")).css("width"),
+               width_initial_disconnected = el_disconnected.css("width"),
+               width_roundtrip_disconnected = el_disconnected.css("width", el_disconnected.css("width")).css("width");
+
+       equal( width_roundtrip, width_initial, "css('width') is not respecting box-sizing, see #11004");
+       equal( width_roundtrip_disconnected, width_initial_disconnected, "css('width') is not respecting box-sizing for disconnected element, see #11004");
+});
+
 test( "cssHooks - expand", function() {
        expect( 15 );
        var result,