From a0abd15b9e5aa9c1f36a9599e6095304825a7b9f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Go=C5=82=C4=99biowski-Owczarek?= Date: Mon, 18 Mar 2019 18:44:43 +0100 Subject: [PATCH] CSS: Avoid forcing a reflow in width/height getters unless necessary Fixes gh-4322 Closes gh-4325 Ref gh-3991 Ref gh-4010 Ref gh-4185 Ref gh-4187 --- src/css.js | 15 ++++++++++++--- test/unit/dimensions.js | 16 ++++++++-------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/css.js b/src/css.js index f18cf19f2..ac4c66e87 100644 --- a/src/css.js +++ b/src/css.js @@ -118,9 +118,15 @@ function getWidthOrHeight( elem, dimension, extra ) { // Start with computed style var styles = getStyles( elem ), - val = curCSS( elem, dimension, styles ), - isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); // Support: Firefox <=54 @@ -141,10 +147,13 @@ function getWidthOrHeight( elem, dimension, extra ) { // Also use offsetWidth/offsetHeight for when box sizing is unreliable // We use getClientRects() to check for hidden/disconnected. // In those cases, the computed value can be trusted to be border-box - if ( ( isBorderBox && !support.boxSizingReliable() || val === "auto" || + if ( ( !support.boxSizingReliable() && isBorderBox || + val === "auto" || !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && elem.getClientRects().length ) { + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + // Where available, offsetWidth/offsetHeight approximate border box dimensions. // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the // retrieved value as a content box dimension. diff --git a/test/unit/dimensions.js b/test/unit/dimensions.js index e5733fc86..3f690cecf 100644 --- a/test/unit/dimensions.js +++ b/test/unit/dimensions.js @@ -397,17 +397,17 @@ QUnit.test( "SVG dimensions (border-box)", function( assert ) { var svg = jQuery( "" ).appendTo( "#qunit-fixture" ); - assert.equal( svg.width(), 94 ); - assert.equal( svg.height(), 94 ); + assert.equal( svg.width(), 94, "width" ); + assert.equal( svg.height(), 94, "height" ); - assert.equal( svg.innerWidth(), 98 ); - assert.equal( svg.innerHeight(), 98 ); + assert.equal( svg.innerWidth(), 98, "innerWidth" ); + assert.equal( svg.innerHeight(), 98, "innerHeight" ); - assert.equal( svg.outerWidth(), 100 ); - assert.equal( svg.outerHeight(), 100 ); + assert.equal( svg.outerWidth(), 100, "outerWidth" ); + assert.equal( svg.outerHeight(), 100, "outerHeight" ); - assert.equal( svg.outerWidth( true ), 106 ); - assert.equal( svg.outerHeight( true ), 106 ); + assert.equal( svg.outerWidth( true ), 106, "outerWidth( true )" ); + assert.equal( svg.outerHeight( true ), 106, "outerHeight( true )" ); svg.remove(); } ); -- 2.39.5