From 26415e081b318dbe1d46d2b7c30e05f14c339b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Go=C5=82=C4=99biowski-Owczarek?= Date: Mon, 14 Oct 2019 18:41:35 +0200 Subject: [PATCH] CSS: Workaround buggy getComputedStyle on table rows in IE/Edge Fixes gh-4490 Closes gh-4506 --- src/css.js | 27 ++++++++++++++++++--------- src/css/support.js | 40 ++++++++++++++++++++++++++++++++++++++++ test/unit/css.js | 20 ++++++++++++++++++++ test/unit/support.js | 6 ++++++ 4 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 src/css/support.js diff --git a/src/css.js b/src/css.js index b3b05e40f..c700c0aa5 100644 --- a/src/css.js +++ b/src/css.js @@ -1,6 +1,7 @@ define( [ "./core", "./core/access", + "./core/nodeName", "./var/rcssNum", "./var/isIE", "./css/var/rnumnonpx", @@ -11,13 +12,14 @@ define( [ "./css/var/swap", "./css/curCSS", "./css/adjustCSS", + "./css/support", "./css/finalPropName", "./core/init", "./core/ready", "./selector" // contains -], function( jQuery, access, rcssNum, isIE, rnumnonpx, cssExpand, isAutoPx, - cssCamelCase, getStyles, swap, curCSS, adjustCSS, finalPropName ) { +], function( jQuery, access, nodeName, rcssNum, isIE, rnumnonpx, cssExpand, isAutoPx, + cssCamelCase, getStyles, swap, curCSS, adjustCSS, support, finalPropName ) { "use strict"; @@ -138,14 +140,21 @@ function getWidthOrHeight( elem, dimension, extra ) { } - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - // // Support: IE 9 - 11+ - // 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 ( ( isIE && isBorderBox || val === "auto" ) && + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( isIE && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" ) && + + // Make sure the element is visible & connected elem.getClientRects().length ) { isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; diff --git a/src/css/support.js b/src/css/support.js new file mode 100644 index 000000000..053f494b2 --- /dev/null +++ b/src/css/support.js @@ -0,0 +1,40 @@ +define( [ + "../var/document", + "../var/documentElement", + "../var/support" +], function( document, documentElement, support ) { + +"use strict"; + +var reliableTrDimensionsVal; + +// Support: IE 11+, Edge 15 - 18+ +// IE/Edge misreport `getComputedStyle` of table rows with width/height +// set in CSS while `offset*` properties report correct values. +support.reliableTrDimensions = function() { + var table, tr, trChild; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + var trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; +}; + +return support; + +} ); diff --git a/test/unit/css.js b/test/unit/css.js index 5d1a97dd0..e148f140d 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -1352,6 +1352,26 @@ QUnit.test( "css('width') and css('height') should respect box-sizing, see #1100 assert.equal( el_dis.css( "height" ), el_dis.css( "height", el_dis.css( "height" ) ).css( "height" ), "css('height') is not respecting box-sizing for disconnected element, see #11004" ); } ); +QUnit.test( "table rows width/height should be unaffected by inline styles", function( assert ) { + assert.expect( 2 ); + + var table = jQuery( + "\n" + + " \n" + + " \n" + + "
\n" + + "
\n" + + " \n" + + "
" + ); + var tr = table.find( "tr" ); + + table.appendTo( "#qunit-fixture" ); + + assert.ok( parseInt( tr.css( "width" ) ) > 10, "tr width unaffected by inline style" ); + assert.ok( parseInt( tr.css( "height" ) ) > 10, "tr height unaffected by inline style" ); +} ); + testIframe( "css('width') should work correctly before document ready (#14084)", "css/cssWidthBeforeDocReady.html", diff --git a/test/unit/support.js b/test/unit/support.js index 8be82bbe9..b2d4eb350 100644 --- a/test/unit/support.js +++ b/test/unit/support.js @@ -59,21 +59,27 @@ testIframe( userAgent = window.navigator.userAgent, expectedMap = { edge: { + reliableTrDimensions: false, scope: undefined }, ie_11: { + reliableTrDimensions: false, scope: undefined }, chrome: { + reliableTrDimensions: true, scope: true }, safari: { + reliableTrDimensions: true, scope: true }, firefox: { + reliableTrDimensions: true, scope: true }, ios: { + reliableTrDimensions: true, scope: true } };