aboutsummaryrefslogtreecommitdiffstats
path: root/src/css.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/css.js')
-rw-r--r--src/css.js114
1 files changed, 68 insertions, 46 deletions
diff --git a/src/css.js b/src/css.js
index 24c5c7327..5da9a3aea 100644
--- a/src/css.js
+++ b/src/css.js
@@ -80,58 +80,77 @@ function setPositiveNumber( elem, value, subtract ) {
value;
}
-function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
- var i,
- val = 0;
-
- // If we already have the right measurement, avoid augmentation
- if ( extra === ( isBorderBox ? "border" : "content" ) ) {
- i = 4;
-
- // Otherwise initialize for horizontal or vertical properties
- } else {
- i = name === "width" ? 1 : 0;
+function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
+ var i = dimension === "width" ? 1 : 0,
+ extra = 0,
+ delta = 0;
+
+ // Adjustment may not be necessary
+ if ( box === ( isBorderBox ? "border" : "content" ) ) {
+ return 0;
}
for ( ; i < 4; i += 2 ) {
- // Both box models exclude margin, so add it if we want it
- if ( extra === "margin" ) {
- val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+ // Both box models exclude margin
+ if ( box === "margin" ) {
+ delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
}
- if ( isBorderBox ) {
+ // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
+ if ( !isBorderBox ) {
- // border-box includes padding, so remove it if we want content
- if ( extra === "content" ) {
- val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
- }
+ // Add padding
+ delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
- // At this point, extra isn't border nor margin, so remove border
- if ( extra !== "margin" ) {
- val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+ // For "border" or "margin", add border
+ if ( box !== "padding" ) {
+ delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+
+ // But still keep track of it otherwise
+ } else {
+ extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
}
+
+ // If we get here with a border-box (content + padding + border), we're seeking "content" or
+ // "padding" or "margin"
} else {
- // At this point, extra isn't content, so add padding
- val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+ // For "content", subtract padding
+ if ( box === "content" ) {
+ delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+ }
- // At this point, extra isn't content nor padding, so add border
- if ( extra !== "padding" ) {
- val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+ // For "content" or "padding", subtract border
+ if ( box !== "margin" ) {
+ delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
}
}
}
- return val;
+ // Account for positive content-box scroll gutter when requested by providing computedVal
+ if ( !isBorderBox && computedVal >= 0 ) {
+
+ // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
+ // Assuming integer scroll gutter, subtract the rest and round down
+ delta += Math.max( 0, Math.ceil(
+ elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
+ computedVal -
+ delta -
+ extra -
+ 0.5
+ ) );
+ }
+
+ return delta;
}
-function getWidthOrHeight( elem, name, extra ) {
+function getWidthOrHeight( elem, dimension, extra ) {
// Start with computed style
var valueIsBorderBox,
styles = getStyles( elem ),
- val = curCSS( elem, name, styles ),
+ val = curCSS( elem, dimension, styles ),
isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
// Computed unit is not pixels. Stop here and return.
@@ -142,25 +161,28 @@ function getWidthOrHeight( elem, name, extra ) {
// Check for style in case a browser which returns unreliable values
// for getComputedStyle silently falls back to the reliable elem.style
valueIsBorderBox = isBorderBox &&
- ( support.boxSizingReliable() || val === elem.style[ name ] );
+ ( support.boxSizingReliable() || val === elem.style[ dimension ] );
// Fall back to offsetWidth/Height when value is "auto"
// This happens for inline elements with no explicit setting (gh-3571)
if ( val === "auto" ) {
- val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
+ val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ];
}
- // Normalize "", auto, and prepare for extra
+ // Normalize "" and auto
val = parseFloat( val ) || 0;
- // Use the active box-sizing model to add/subtract irrelevant styles
+ // Adjust for the element's box model
return ( val +
- augmentWidthOrHeight(
+ boxModelAdjustment(
elem,
- name,
+ dimension,
extra || ( isBorderBox ? "border" : "content" ),
valueIsBorderBox,
- styles
+ styles,
+
+ // Provide the current computed size to request scroll gutter calculation (gh-3589)
+ val
)
) + "px";
}
@@ -319,8 +341,8 @@ jQuery.extend( {
}
} );
-jQuery.each( [ "height", "width" ], function( i, name ) {
- jQuery.cssHooks[ name ] = {
+jQuery.each( [ "height", "width" ], function( i, dimension ) {
+ jQuery.cssHooks[ dimension ] = {
get: function( elem, computed, extra ) {
if ( computed ) {
@@ -336,18 +358,18 @@ jQuery.each( [ "height", "width" ], function( i, name ) {
// in IE throws an error.
( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
swap( elem, cssShow, function() {
- return getWidthOrHeight( elem, name, extra );
+ return getWidthOrHeight( elem, dimension, extra );
} ) :
- getWidthOrHeight( elem, name, extra );
+ getWidthOrHeight( elem, dimension, extra );
}
},
set: function( elem, value, extra ) {
var matches,
- styles = extra && getStyles( elem ),
- subtract = extra && augmentWidthOrHeight(
+ styles = getStyles( elem ),
+ subtract = extra && boxModelAdjustment(
elem,
- name,
+ dimension,
extra,
jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
styles
@@ -357,8 +379,8 @@ jQuery.each( [ "height", "width" ], function( i, name ) {
if ( subtract && ( matches = rcssNum.exec( value ) ) &&
( matches[ 3 ] || "px" ) !== "px" ) {
- elem.style[ name ] = value;
- value = jQuery.css( elem, name );
+ elem.style[ dimension ] = value;
+ value = jQuery.css( elem, dimension );
}
return setPositiveNumber( elem, value, subtract );