aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Gibson <richard.gibson@gmail.com>2017-07-18 15:40:41 -0400
committerGitHub <noreply@github.com>2017-07-18 15:40:41 -0400
commit20cdf4e7de60f515a7acf6c70228c52668301d9b (patch)
treeb4629ff31128571e1eff1479901577152062256d
parent3fcddd6e72e7e318c0b062e391d60867732318ae (diff)
downloadjquery-20cdf4e7de60f515a7acf6c70228c52668301d9b.tar.gz
jquery-20cdf4e7de60f515a7acf6c70228c52668301d9b.zip
Support: Properly check for IE9 absolute scrollbox mishandling
Ref gh-3589 Fixes gh-3699 Fixes gh-3730 Closes gh-3729
-rw-r--r--src/css.js2
-rw-r--r--src/css/support.js44
-rw-r--r--test/unit/dimensions.js82
-rw-r--r--test/unit/support.js30
4 files changed, 91 insertions, 67 deletions
diff --git a/src/css.js b/src/css.js
index 79e06319c..87bf2481d 100644
--- a/src/css.js
+++ b/src/css.js
@@ -378,7 +378,7 @@ jQuery.each( [ "height", "width" ], function( i, dimension ) {
// Account for unreliable border-box dimensions by comparing offset* to computed and
// faking a content-box to get border and padding (gh-3699)
- if ( isBorderBox && !support.borderBoxReliable() ) {
+ if ( isBorderBox && support.scrollboxSize() === styles.position ) {
subtract -= Math.ceil(
elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
parseFloat( styles[ dimension ] ) -
diff --git a/src/css/support.js b/src/css/support.js
index 7b7945fef..97f5aad70 100644
--- a/src/css/support.js
+++ b/src/css/support.js
@@ -18,29 +18,33 @@ define( [
return;
}
+ container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
+ "margin-top:1px;padding:0;border:0";
div.style.cssText =
- "box-sizing:border-box;" +
- "position:relative;display:block;" +
+ "position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
"margin:auto;border:1px;padding:1px;" +
- "top:1%;width:50%";
- div.innerHTML = "";
- documentElement.appendChild( container );
+ "width:60%;top:1%";
+ documentElement.appendChild( container ).appendChild( div );
var divStyle = window.getComputedStyle( div );
pixelPositionVal = divStyle.top !== "1%";
// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
- reliableMarginLeftVal = divStyle.marginLeft === "2px";
- boxSizingReliableVal = divStyle.width === "5px";
-
- // Support: IE 9 only
- // Detect misreporting of content dimensions for border-box elements (gh-3699)
- borderBoxReliableVal = divStyle.width[ 0 ] === "5";
+ reliableMarginLeftVal = divStyle.marginLeft === "12px";
// Support: Android 4.0 - 4.3 only
// Some styles come back with percentage values, even though they shouldn't
- div.style.marginRight = "50%";
- pixelMarginRightVal = divStyle.marginRight === "5px";
+ div.style.marginRight = "60%";
+ pixelMarginRightVal = divStyle.marginRight === "36px";
+
+ // Support: IE 9 - 11 only
+ // Detect misreporting of content dimensions for box-sizing:border-box elements
+ boxSizingReliableVal = divStyle.width === "36px";
+
+ // Support: IE 9 only
+ // Detect overflow:scroll screwiness (gh-3699)
+ div.style.position = "absolute";
+ scrollboxSizeVal = div.offsetWidth === 36 || "absolute";
documentElement.removeChild( container );
@@ -49,7 +53,7 @@ define( [
div = null;
}
- var pixelPositionVal, boxSizingReliableVal, borderBoxReliableVal, pixelMarginRightVal,
+ var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelMarginRightVal,
reliableMarginLeftVal,
container = document.createElement( "div" ),
div = document.createElement( "div" );
@@ -65,15 +69,7 @@ define( [
div.cloneNode( true ).style.backgroundClip = "";
support.clearCloneStyle = div.style.backgroundClip === "content-box";
- container.style.cssText = "border:0;width:10px;height:0;top:0;left:-9999px;" +
- "padding:0;margin-top:1px;position:absolute";
- container.appendChild( div );
-
jQuery.extend( support, {
- borderBoxReliable: function() {
- computeStyleTests();
- return borderBoxReliableVal;
- },
boxSizingReliable: function() {
computeStyleTests();
return boxSizingReliableVal;
@@ -89,6 +85,10 @@ define( [
reliableMarginLeft: function() {
computeStyleTests();
return reliableMarginLeftVal;
+ },
+ scrollboxSize: function() {
+ computeStyleTests();
+ return scrollboxSizeVal;
}
} );
} )();
diff --git a/test/unit/dimensions.js b/test/unit/dimensions.js
index 5db465868..13cd9662b 100644
--- a/test/unit/dimensions.js
+++ b/test/unit/dimensions.js
@@ -545,7 +545,7 @@ QUnit.test( "width/height on an inline element with no explicitly-set dimensions
} );
QUnit.test( "interaction with scrollbars (gh-3589)", function( assert ) {
- assert.expect( 36 );
+ assert.expect( 48 );
var i,
suffix = "",
@@ -561,31 +561,29 @@ QUnit.test( "interaction with scrollbars (gh-3589)", function( assert ) {
borderWidth = 1,
padding = 2,
size = 100 + fraction,
- scrollBox = {
- position: "absolute",
- overflow: "scroll",
- width: size + "px",
- height: size + "px"
- },
- borderBox = {
- border: borderWidth + "px solid blue",
- padding: padding + "px"
- },
- plainContentBox = jQuery( "<div />" )
- .css( scrollBox )
- .css( { "box-sizing": "content-box" } )
- .appendTo( parent ),
- contentBox = jQuery( "<div />" )
- .css( scrollBox )
- .css( borderBox )
- .css( { "box-sizing": "content-box" } )
- .appendTo( parent ),
- borderBox = jQuery( "<div />" )
- .css( scrollBox )
- .css( borderBox )
- .css( { "box-sizing": "border-box" } )
- .appendTo( parent ),
- $boxes = jQuery( [ plainContentBox[ 0 ], contentBox[ 0 ], borderBox[ 0 ] ] ),
+ plainBox = jQuery( "<div />" )
+ .css( {
+ "box-sizing": "content-box",
+ position: "absolute",
+ overflow: "scroll",
+ width: size + "px",
+ height: size + "px"
+ } ),
+ contentBox = plainBox
+ .clone()
+ .css( {
+ border: borderWidth + "px solid blue",
+ padding: padding + "px"
+ } ),
+ borderBox = contentBox
+ .clone()
+ .css( { "box-sizing": "border-box" } ),
+ relativeBorderBox = borderBox
+ .clone()
+ .css( { position: "relative" } ),
+ $boxes = jQuery(
+ [ plainBox[ 0 ], contentBox[ 0 ], borderBox[ 0 ], relativeBorderBox[ 0 ] ]
+ ).appendTo( parent ),
// Support: IE 9 only
// Computed width seems to report content width even with "box-sizing: border-box", and
@@ -594,6 +592,13 @@ QUnit.test( "interaction with scrollbars (gh-3589)", function( assert ) {
borderBox.clone().css( { overflow: "auto" } ).appendTo( parent )[ 0 ].offsetWidth -
borderBox[ 0 ].offsetWidth;
+ if ( borderBoxLoss > 0 ) {
+ borderBox.css( {
+ width: ( size + borderBoxLoss ) + "px",
+ height: ( size + borderBoxLoss ) + "px"
+ } );
+ }
+
for ( i = 0; i < 3; i++ ) {
if ( i === 1 ) {
suffix = " after increasing inner* by " + i;
@@ -605,13 +610,13 @@ QUnit.test( "interaction with scrollbars (gh-3589)", function( assert ) {
$boxes.outerWidth( updater( i ) ).outerHeight( updater( i ) );
}
- assert.equal( plainContentBox.innerWidth(), size,
+ assert.equal( plainBox.innerWidth(), size,
"plain content-box innerWidth includes scroll gutter" + suffix );
- assert.equal( plainContentBox.innerHeight(), size,
+ assert.equal( plainBox.innerHeight(), size,
"plain content-box innerHeight includes scroll gutter" + suffix );
- assert.equal( plainContentBox.outerWidth(), size,
+ assert.equal( plainBox.outerWidth(), size,
"plain content-box outerWidth includes scroll gutter" + suffix );
- assert.equal( plainContentBox.outerHeight(), size,
+ assert.equal( plainBox.outerHeight(), size,
"plain content-box outerHeight includes scroll gutter" + suffix );
assert.equal( contentBox.innerWidth(), size + 2 * padding,
@@ -623,14 +628,23 @@ QUnit.test( "interaction with scrollbars (gh-3589)", function( assert ) {
assert.equal( contentBox.outerHeight(), size + 2 * padding + 2 * borderWidth,
"content-box outerHeight includes scroll gutter" + suffix );
- assert.equal( borderBox.innerWidth(), size - borderBoxLoss - 2 * borderWidth,
+ assert.equal( borderBox.innerWidth(), size - 2 * borderWidth,
"border-box innerWidth includes scroll gutter" + suffix );
- assert.equal( borderBox.innerHeight(), size - borderBoxLoss - 2 * borderWidth,
+ assert.equal( borderBox.innerHeight(), size - 2 * borderWidth,
"border-box innerHeight includes scroll gutter" + suffix );
- assert.equal( borderBox.outerWidth(), size - borderBoxLoss,
+ assert.equal( borderBox.outerWidth(), size,
"border-box outerWidth includes scroll gutter" + suffix );
- assert.equal( borderBox.outerHeight(), size - borderBoxLoss,
+ assert.equal( borderBox.outerHeight(), size,
"border-box outerHeight includes scroll gutter" + suffix );
+
+ assert.equal( relativeBorderBox.innerWidth(), size - 2 * borderWidth,
+ "relative border-box innerWidth includes scroll gutter" + suffix );
+ assert.equal( relativeBorderBox.innerHeight(), size - 2 * borderWidth,
+ "relative border-box innerHeight includes scroll gutter" + suffix );
+ assert.equal( relativeBorderBox.outerWidth(), size,
+ "relative border-box outerWidth includes scroll gutter" + suffix );
+ assert.equal( relativeBorderBox.outerHeight(), size,
+ "relative border-box outerHeight includes scroll gutter" + suffix );
}
} );
diff --git a/test/unit/support.js b/test/unit/support.js
index daa8dc664..f893886da 100644
--- a/test/unit/support.js
+++ b/test/unit/support.js
@@ -73,7 +73,8 @@ testIframe(
"pixelMarginRight": true,
"pixelPosition": true,
"radioValue": true,
- "reliableMarginLeft": true
+ "reliableMarginLeft": true,
+ "scrollboxSize": true
};
} else if ( /(msie 10\.0|trident\/7\.0)/i.test( userAgent ) ) {
expected = {
@@ -90,7 +91,8 @@ testIframe(
"pixelMarginRight": true,
"pixelPosition": true,
"radioValue": false,
- "reliableMarginLeft": true
+ "reliableMarginLeft": true,
+ "scrollboxSize": true
};
} else if ( /msie 9\.0/i.test( userAgent ) ) {
expected = {
@@ -107,7 +109,8 @@ testIframe(
"pixelMarginRight": true,
"pixelPosition": true,
"radioValue": false,
- "reliableMarginLeft": true
+ "reliableMarginLeft": true,
+ "scrollboxSize": "absolute"
};
} else if ( /chrome/i.test( userAgent ) ) {
@@ -127,7 +130,8 @@ testIframe(
"pixelMarginRight": true,
"pixelPosition": true,
"radioValue": true,
- "reliableMarginLeft": true
+ "reliableMarginLeft": true,
+ "scrollboxSize": true
};
} else if ( /\b(?:9|10)\.\d(\.\d+)* safari/i.test( userAgent ) ) {
expected = {
@@ -144,7 +148,8 @@ testIframe(
"pixelMarginRight": true,
"pixelPosition": false,
"radioValue": true,
- "reliableMarginLeft": true
+ "reliableMarginLeft": true,
+ "scrollboxSize": true
};
} else if ( /firefox/i.test( userAgent ) ) {
expected = {
@@ -161,7 +166,8 @@ testIframe(
"pixelMarginRight": true,
"pixelPosition": true,
"radioValue": true,
- "reliableMarginLeft": false
+ "reliableMarginLeft": false,
+ "scrollboxSize": true
};
} else if ( /iphone os (?:9|10)_/i.test( userAgent ) ) {
expected = {
@@ -178,7 +184,8 @@ testIframe(
"pixelMarginRight": true,
"pixelPosition": false,
"radioValue": true,
- "reliableMarginLeft": true
+ "reliableMarginLeft": true,
+ "scrollboxSize": true
};
} else if ( /iphone os 8_/i.test( userAgent ) ) {
expected = {
@@ -195,7 +202,8 @@ testIframe(
"pixelMarginRight": true,
"pixelPosition": false,
"radioValue": true,
- "reliableMarginLeft": true
+ "reliableMarginLeft": true,
+ "scrollboxSize": true
};
} else if ( /iphone os 7_/i.test( userAgent ) ) {
expected = {
@@ -212,7 +220,8 @@ testIframe(
"pixelMarginRight": true,
"pixelPosition": false,
"radioValue": true,
- "reliableMarginLeft": true
+ "reliableMarginLeft": true,
+ "scrollboxSize": true
};
} else if ( /android 4\.[0-3]/i.test( userAgent ) ) {
expected = {
@@ -229,7 +238,8 @@ testIframe(
"pixelMarginRight": false,
"pixelPosition": false,
"radioValue": true,
- "reliableMarginLeft": false
+ "reliableMarginLeft": false,
+ "scrollboxSize": true
};
}