aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/css.js50
-rw-r--r--src/css/support.js134
-rw-r--r--test/unit/dimensions.js89
-rw-r--r--test/unit/event.js2
-rw-r--r--test/unit/support.js8
5 files changed, 192 insertions, 91 deletions
diff --git a/src/css.js b/src/css.js
index 3e7073507..66e5c3c75 100644
--- a/src/css.js
+++ b/src/css.js
@@ -18,13 +18,7 @@ import { support } from "./css/support.js";
import "./core/init.js";
import "./core/ready.js";
-var
-
- // Swappable if display is none or starts with table
- // except "table", "table-cell", or "table-caption"
- // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
- rdisplayswap = /^(none|table(?!-c[ea]).+)/,
- cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+var cssShow = { position: "absolute", visibility: "hidden", display: "block" },
cssNormalTransform = {
letterSpacing: "0",
fontWeight: "400"
@@ -137,24 +131,22 @@ function getWidthOrHeight( elem, dimension, extra ) {
}
- if ( (
+ if (
+ (
+
+ // Fall back to offsetWidth/offsetHeight when value is "auto"
+ // This happens for inline elements with no explicit setting (gh-3571)
+ val === "auto" ||
- // Fall back to offsetWidth/offsetHeight when value is "auto"
- // This happens for inline elements with no explicit setting (gh-3571)
- val === "auto" ||
+ // Support: IE 9 - 11+
+ // Use offsetWidth/offsetHeight for when box sizing is unreliable.
+ // In those cases, the computed value can be trusted to be border-box.
+ ( isIE && isBorderBox ) ||
- // Support: IE 9 - 11+
- // Use offsetWidth/offsetHeight for when box sizing is unreliable.
- // In those cases, the computed value can be trusted to be border-box.
- ( isIE && isBorderBox ) ||
+ ( !support.reliableColDimensions() && nodeName( elem, "col" ) ) ||
- // Support: IE 10 - 11+
- // IE misreports `getComputedStyle` of table rows with width/height
- // set in CSS while `offset*` properties report correct values.
- // Support: Firefox 70 - 135+
- // Firefox includes border widths
- // in computed dimensions for table rows. (gh-4529)
- ( !support.reliableTrDimensions() && nodeName( elem, "tr" ) ) ) &&
+ ( !support.reliableTrDimensions() && nodeName( elem, "tr" ) )
+ ) &&
// Make sure the element is visible & connected
elem.getClientRects().length ) {
@@ -316,17 +308,9 @@ jQuery.each( [ "height", "width" ], function( _i, dimension ) {
get: function( elem, computed, extra ) {
if ( computed ) {
- // Certain elements can have dimension info if we invisibly show them
- // but it must have a current display style that would benefit
- return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
-
- // Support: Safari <=8 - 12+, Chrome <=73+
- // Table columns in WebKit/Blink have non-zero offsetWidth & zero
- // getBoundingClientRect().width unless display is changed.
- // Support: IE <=11+
- // Running getBoundingClientRect on a disconnected node
- // in IE throws an error.
- ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
+ // Elements with `display: none` can have dimension info if
+ // we invisibly show them.
+ return jQuery.css( elem, "display" ) === "none" ?
swap( elem, cssShow, function() {
return getWidthOrHeight( elem, dimension, extra );
} ) :
diff --git a/src/css/support.js b/src/css/support.js
index bca0b6dbf..a05d31bd1 100644
--- a/src/css/support.js
+++ b/src/css/support.js
@@ -1,62 +1,96 @@
+import { jQuery } from "../core.js";
import { document } from "../var/document.js";
import { documentElement } from "../var/documentElement.js";
import { support } from "../var/support.js";
+import { isIE } from "../var/isIE.js";
-( function() {
+var reliableTrDimensionsVal, reliableColDimensionsVal,
+ table = document.createElement( "table" );
-var reliableTrDimensionsVal,
- div = document.createElement( "div" );
+// Executing table tests requires only one layout, so they're executed
+// at the same time to save the second computation.
+function computeTableStyleTests() {
+ if (
-// Finish early in limited (non-browser) environments
-if ( !div.style ) {
- return;
-}
+ // This is a singleton, we need to execute it only once
+ !table ||
+
+ // Finish early in limited (non-browser) environments
+ !table.style
+ ) {
+ return;
+ }
+
+ var trStyle,
+ col = document.createElement( "col" ),
+ tr = document.createElement( "tr" ),
+ td = document.createElement( "td" );
-// Support: IE 10 - 11+
-// IE misreports `getComputedStyle` of table rows with width/height
-// set in CSS while `offset*` properties report correct values.
-// Support: Firefox 70+
-// Only Firefox includes border widths
-// in computed dimensions. (gh-4529)
-support.reliableTrDimensions = function() {
- var table, tr, trStyle;
- if ( reliableTrDimensionsVal == null ) {
- table = document.createElement( "table" );
- tr = document.createElement( "tr" );
-
- table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
- tr.style.cssText = "box-sizing:content-box;border:1px solid;height:1px";
- div.style.height = "9px";
-
- // Support: Android Chrome 86+
- // In our bodyBackground.html iframe,
- // display for all div elements is set to "inline",
- // which causes a problem only in Android Chrome, but
- // not consistently across all devices.
- // Ensuring the div is `display: block`
- // gets around this issue.
- div.style.display = "block";
-
- documentElement
- .appendChild( table )
- .appendChild( tr )
- .appendChild( div );
-
- // Don't run until window is visible
- if ( table.offsetWidth === 0 ) {
- documentElement.removeChild( table );
- return;
- }
-
- trStyle = window.getComputedStyle( tr );
- reliableTrDimensionsVal = ( Math.round( parseFloat( trStyle.height ) ) +
- Math.round( parseFloat( trStyle.borderTopWidth ) ) +
- Math.round( parseFloat( trStyle.borderBottomWidth ) ) ) === tr.offsetHeight;
+ table.style.cssText = "position:absolute;left:-11111px;" +
+ "border-collapse:separate;border-spacing:0";
+ tr.style.cssText = "box-sizing:content-box;border:1px solid;height:1px";
+ td.style.cssText = "height:9px;width:9px;padding:0";
+ col.span = 2;
+
+ documentElement
+ .appendChild( table )
+ .appendChild( col )
+ .parentNode
+ .appendChild( tr )
+ .appendChild( td )
+ .parentNode
+ .appendChild( td.cloneNode( true ) );
+
+ // Don't run until window is visible
+ if ( table.offsetWidth === 0 ) {
documentElement.removeChild( table );
+ return;
+ }
+
+ trStyle = window.getComputedStyle( tr );
+
+ // Support: Firefox 135+
+ // Firefox always reports computed width as if `span` was 1.
+ // Support: Safari 18.3+
+ // In Safari, computed width for columns is always 0.
+ // In both these browsers, using `offsetWidth` solves the issue.
+ // Support: IE 11+
+ // In IE, `<col>` computed width is `"auto"` unless `width` is set
+ // explicitly via CSS so measurements there remain incorrect. Because of
+ // the lack of a proper workaround, we accept this limitation, treating
+ // IE as passing the test.
+ reliableColDimensionsVal = isIE || Math.round( parseFloat(
+ window.getComputedStyle( col ).width )
+ ) === 18;
+
+ // Support: IE 10 - 11+
+ // IE misreports `getComputedStyle` of table rows with width/height
+ // set in CSS while `offset*` properties report correct values.
+ // Support: Firefox 70 - 135+
+ // Only Firefox includes border widths
+ // in computed dimensions for table rows. (gh-4529)
+ reliableTrDimensionsVal = Math.round( parseFloat( trStyle.height ) +
+ parseFloat( trStyle.borderTopWidth ) +
+ parseFloat( trStyle.borderBottomWidth ) ) === tr.offsetHeight;
+
+ documentElement.removeChild( table );
+
+ // Nullify the table so it wouldn't be stored in the memory;
+ // it will also be a sign that checks were already performed.
+ table = null;
+}
+
+jQuery.extend( support, {
+ reliableTrDimensions: function() {
+ computeTableStyleTests();
+ return reliableTrDimensionsVal;
+ },
+
+ reliableColDimensions: function() {
+ computeTableStyleTests();
+ return reliableColDimensionsVal;
}
- return reliableTrDimensionsVal;
-};
-} )();
+} );
export { support };
diff --git a/test/unit/dimensions.js b/test/unit/dimensions.js
index 93cdb3d82..3a8b988f1 100644
--- a/test/unit/dimensions.js
+++ b/test/unit/dimensions.js
@@ -345,17 +345,94 @@ QUnit.test( "child of a hidden elem (or unconnected node) has accurate inner/out
$divNormal.remove();
} );
-QUnit.test( "table dimensions", function( assert ) {
+QUnit.test( "hidden element with dimensions from a stylesheet", function( assert ) {
assert.expect( 2 );
- var table = jQuery( "<table><colgroup><col></col><col></col></colgroup><tbody><tr><td></td><td>a</td></tr><tr><td></td><td>a</td></tr></tbody></table>" ).appendTo( "#qunit-fixture" ),
+ var div = jQuery( "" +
+ "<div class='display-none-style'>" +
+ " <style>" +
+ " .display-none-style {" +
+ " display: none;" +
+ " width: 111px;" +
+ " height: 123px;" +
+ " }" +
+ " </style>" +
+ "</div>" +
+ "" )
+ .appendTo( "#qunit-fixture" );
+
+ assert.strictEqual( div.width(), 111, "width of a hidden element" );
+ assert.strictEqual( div.height(), 123, "height of a hidden element" );
+} );
+
+QUnit.test( "hidden element with implicit content-based dimensions", function( assert ) {
+ assert.expect( 2 );
+
+ var container = jQuery( "" +
+
+ // font-size affects the child dimensions implicitly
+ "<div style='font-size: 20px'>" +
+ " <div style='padding: 10px; display: none'>" +
+ " <div style='width: 3em; height: 2em'></div>" +
+ " </div>" +
+ "</div>" +
+ "" ),
+ div = container.children().first();
+
+ container.appendTo( "#qunit-fixture" );
+
+ assert.strictEqual( div.width(), 60, "width of a hidden element" );
+ assert.strictEqual( div.height(), 40, "height of a hidden element" );
+} );
+
+QUnit.test( "table dimensions", function( assert ) {
+ assert.expect( 3 );
+
+ var table = jQuery( "" +
+ "<table style='border-spacing: 0'>" +
+ " <colgroup>" +
+ " <col />" +
+ " <col span='2' class='col-double' />" +
+ " </colgroup>" +
+ " <tbody>" +
+ " <tr>" +
+ " <td></td>" +
+ " <td class='td-a-1'>a</td>" +
+ " <td class='td-b-1'>b</td>" +
+ " </tr>" +
+ " <tr>" +
+ " <td></td>" +
+ " <td>a</td>" +
+ " <td>b</td>" +
+ " </tr>" +
+ " </tbody>" +
+ "</table>"
+ ).appendTo( "#qunit-fixture" ),
tdElem = table.find( "td" ).first(),
- colElem = table.find( "col" ).first().width( 300 );
+ colElem = table.find( "col" ).first(),
+ doubleColElem = table.find( ".col-double" );
- table.find( "td" ).css( { "margin": 0, "padding": 0 } );
+ table.find( "td" ).css( { margin: 0, padding: 0, border: 0 } );
+
+ colElem.width( 300 );
+
+ table.find( ".td-a-1" ).width( 200 );
+ table.find( ".td-b-1" ).width( 400 );
assert.equal( tdElem.width(), tdElem.width(), "width() doesn't alter dimension values of empty cells, see trac-11293" );
- assert.equal( colElem.width(), 300, "col elements have width(), see trac-12243" );
+ assert.equal( colElem.width(), 300, "col elements have width(), (trac-12243)" );
+
+ // Support: IE 11+
+ // In IE, `<col>` computed width is `"auto"` unless `width` is set
+ // explicitly via CSS so measurements there remain incorrect. Because of
+ // the lack of a proper workaround, we accept this limitation.
+ // To make IE pass the test, set the width explicitly.
+ if ( QUnit.isIE ) {
+ doubleColElem.width( 600 );
+ }
+
+ assert.equal( doubleColElem.width(), 600,
+ "col with span measured correctly (gh-5628)" );
} );
QUnit.test( "SVG dimensions (basic content-box)", function( assert ) {
@@ -668,7 +745,7 @@ QUnit.test( "interaction with scrollbars (gh-3589)", function( assert ) {
.appendTo( "#qunit-fixture" ),
// Workarounds for IE kill fractional output here.
- fraction = document.documentMode ? 0 : 0.5,
+ fraction = QUnit.isIE ? 0 : 0.5,
borderWidth = 1,
padding = 2,
size = 100 + fraction,
diff --git a/test/unit/event.js b/test/unit/event.js
index 474699105..dac53ed93 100644
--- a/test/unit/event.js
+++ b/test/unit/event.js
@@ -2707,7 +2707,7 @@ testIframe(
// IE does propagate the event to the parent document. In this test
// we mainly care about the inner element so we'll just skip this one
// assertion in IE.
- if ( !document.documentMode ) {
+ if ( !QUnit.isIE ) {
assert.ok( false, "fired a focusin event in the parent document" );
}
} );
diff --git a/test/unit/support.js b/test/unit/support.js
index 0961f3183..8e6fc83a7 100644
--- a/test/unit/support.js
+++ b/test/unit/support.js
@@ -82,26 +82,32 @@ testIframe(
expectedMap = {
ie_11: {
cssHas: true,
+ reliableColDimensions: 11,
reliableTrDimensions: false
},
chrome: {
cssHas: true,
+ reliableColDimensions: true,
reliableTrDimensions: true
},
safari: {
cssHas: true,
+ reliableColDimensions: false,
reliableTrDimensions: true
},
firefox: {
cssHas: true,
+ reliableColDimensions: false,
reliableTrDimensions: false
},
ios_16_3: {
cssHas: false,
+ reliableColDimensions: false,
reliableTrDimensions: true
},
ios: {
cssHas: true,
+ reliableColDimensions: false,
reliableTrDimensions: true
}
};
@@ -113,7 +119,7 @@ testIframe(
}
}
- if ( document.documentMode ) {
+ if ( QUnit.isIE ) {
expected = expectedMap.ie_11;
} else if ( /\b(?:headless)?chrome\//i.test( userAgent ) ) {