mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
CSS: Support relative adjustment in any applicable unit
Fixes gh-1711
Closes gh-2011
(cherry picked from commit 9b03f6df88
)
Conflicts:
src/css.js
src/effects.js
This commit is contained in:
parent
9edd95ffd7
commit
6fb2cefc60
19
src/css.js
19
src/css.js
@ -3,10 +3,12 @@ define([
|
||||
"./var/pnum",
|
||||
"./core/access",
|
||||
"./css/var/rmargin",
|
||||
"./var/rcssNum",
|
||||
"./css/var/rnumnonpx",
|
||||
"./css/var/cssExpand",
|
||||
"./css/var/isHidden",
|
||||
"./css/curCSS",
|
||||
"./css/adjustCSS",
|
||||
"./css/defaultDisplay",
|
||||
"./css/addGetHookIf",
|
||||
"./css/support",
|
||||
@ -15,8 +17,8 @@ define([
|
||||
"./css/swap",
|
||||
"./core/ready",
|
||||
"./selector" // contains
|
||||
], function( jQuery, pnum, access, rmargin, rnumnonpx, cssExpand, isHidden,
|
||||
curCSS, defaultDisplay, addGetHookIf, support ) {
|
||||
], function( jQuery, pnum, access, rmargin, rcssNum, rnumnonpx, cssExpand, isHidden,
|
||||
curCSS, adjustCSS, defaultDisplay, addGetHookIf, support ) {
|
||||
|
||||
var
|
||||
// BuildExclude
|
||||
@ -30,7 +32,6 @@ var
|
||||
// https://developer.mozilla.org/en-US/docs/CSS/display
|
||||
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
|
||||
rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
|
||||
rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
|
||||
|
||||
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
|
||||
cssNormalTransform = {
|
||||
@ -273,9 +274,9 @@ jQuery.extend({
|
||||
if ( value !== undefined ) {
|
||||
type = typeof value;
|
||||
|
||||
// convert relative number strings (+= or -=) to relative numbers. #7345
|
||||
if ( type === "string" && (ret = rrelNum.exec( value )) ) {
|
||||
value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
|
||||
// Convert "+=" or "-=" to relative numbers (#7345)
|
||||
if ( type === "string" && (ret = rcssNum.exec( value )) && ret[ 1 ] ) {
|
||||
value = adjustCSS( elem, name, ret );
|
||||
// Fixes bug #9237
|
||||
type = "number";
|
||||
}
|
||||
@ -285,9 +286,9 @@ jQuery.extend({
|
||||
return;
|
||||
}
|
||||
|
||||
// If a number was passed in, add 'px' (except for certain CSS properties)
|
||||
if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
|
||||
value += "px";
|
||||
// If a number was passed in, add the unit (except for certain CSS properties)
|
||||
if ( type === "number" ) {
|
||||
value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
|
||||
}
|
||||
|
||||
// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
|
||||
|
61
src/css/adjustCSS.js
Normal file
61
src/css/adjustCSS.js
Normal file
@ -0,0 +1,61 @@
|
||||
define([
|
||||
"../core",
|
||||
"../var/rcssNum"
|
||||
], function( jQuery, rcssNum ) {
|
||||
|
||||
function adjustCSS( elem, prop, valueParts, tween ) {
|
||||
var adjusted,
|
||||
scale = 1,
|
||||
maxIterations = 20,
|
||||
currentValue = tween ?
|
||||
function() { return tween.cur(); } :
|
||||
function() { return jQuery.css( elem, prop, "" ); },
|
||||
initial = currentValue(),
|
||||
unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
|
||||
// Starting value computation is required for potential unit mismatches
|
||||
initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
|
||||
rcssNum.exec( jQuery.css( elem, prop ) );
|
||||
|
||||
if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
|
||||
// Trust units reported by jQuery.css
|
||||
unit = unit || initialInUnit[ 3 ];
|
||||
|
||||
// Make sure we update the tween properties later on
|
||||
valueParts = valueParts || [];
|
||||
|
||||
// Iteratively approximate from a nonzero starting point
|
||||
initialInUnit = +initial || 1;
|
||||
|
||||
do {
|
||||
// If previous iteration zeroed out, double until we get *something*.
|
||||
// Use string for doubling so we don't accidentally see scale as unchanged below
|
||||
scale = scale || ".5";
|
||||
|
||||
// Adjust and apply
|
||||
initialInUnit = initialInUnit / scale;
|
||||
jQuery.style( elem, prop, initialInUnit + unit );
|
||||
|
||||
// Update scale, tolerating zero or NaN from tween.cur()
|
||||
// Break the loop if scale is unchanged or perfect, or if we've just had enough.
|
||||
} while (
|
||||
scale !== (scale = currentValue() / initial) && scale !== 1 && --maxIterations
|
||||
);
|
||||
}
|
||||
|
||||
if ( valueParts ) {
|
||||
initialInUnit = +initialInUnit || +initial || 0;
|
||||
// Apply relative offset (+=/-=) if specified
|
||||
adjusted = valueParts[ 1 ] ?
|
||||
initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
|
||||
+valueParts[ 2 ];
|
||||
if ( tween ) {
|
||||
tween.unit = unit;
|
||||
tween.start = initialInUnit;
|
||||
tween.end = adjusted;
|
||||
}
|
||||
}
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
return adjustCSS;
|
||||
});
|
57
src/effects.js
vendored
57
src/effects.js
vendored
@ -1,8 +1,9 @@
|
||||
define([
|
||||
"./core",
|
||||
"./var/pnum",
|
||||
"./var/rcssNum",
|
||||
"./css/var/cssExpand",
|
||||
"./css/var/isHidden",
|
||||
"./css/adjustCSS",
|
||||
"./css/defaultDisplay",
|
||||
|
||||
"./core/init",
|
||||
@ -11,65 +12,17 @@ define([
|
||||
"./css",
|
||||
"./deferred",
|
||||
"./traversing"
|
||||
], function( jQuery, pnum, cssExpand, isHidden, defaultDisplay ) {
|
||||
], function( jQuery, rcssNum, cssExpand, isHidden, adjustCSS, defaultDisplay ) {
|
||||
|
||||
var
|
||||
fxNow, timerId,
|
||||
rfxtypes = /^(?:toggle|show|hide)$/,
|
||||
rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
|
||||
rrun = /queueHooks$/,
|
||||
animationPrefilters = [ defaultPrefilter ],
|
||||
tweeners = {
|
||||
"*": [ function( prop, value ) {
|
||||
var tween = this.createTween( prop, value ),
|
||||
target = tween.cur(),
|
||||
parts = rfxnum.exec( value ),
|
||||
unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
|
||||
|
||||
// Starting value computation is required for potential unit mismatches
|
||||
start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
|
||||
rfxnum.exec( jQuery.css( tween.elem, prop ) ),
|
||||
scale = 1,
|
||||
maxIterations = 20;
|
||||
|
||||
if ( start && start[ 3 ] !== unit ) {
|
||||
// Trust units reported by jQuery.css
|
||||
unit = unit || start[ 3 ];
|
||||
|
||||
// Make sure we update the tween properties later on
|
||||
parts = parts || [];
|
||||
|
||||
// Iteratively approximate from a nonzero starting point
|
||||
start = +target || 1;
|
||||
|
||||
do {
|
||||
// If previous iteration zeroed out, double until we get *something*
|
||||
// Use a string for doubling factor so we don't accidentally see scale
|
||||
// as unchanged below
|
||||
scale = scale || ".5";
|
||||
|
||||
// Adjust and apply
|
||||
start = start / scale;
|
||||
jQuery.style( tween.elem, prop, start + unit );
|
||||
|
||||
// Update scale, tolerating zero or NaN from tween.cur()
|
||||
// And breaking the loop if scale is unchanged or perfect,
|
||||
// or if we've just had enough
|
||||
} while (
|
||||
scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations
|
||||
);
|
||||
}
|
||||
|
||||
// Update tween properties
|
||||
if ( parts ) {
|
||||
start = tween.start = +start || +target || 0;
|
||||
tween.unit = unit;
|
||||
// If a +=/-= token was provided, we're doing a relative animation
|
||||
tween.end = parts[ 1 ] ?
|
||||
start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
|
||||
+parts[ 2 ];
|
||||
}
|
||||
|
||||
var tween = this.createTween( prop, value );
|
||||
adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
|
||||
return tween;
|
||||
} ]
|
||||
};
|
||||
|
7
src/var/rcssNum.js
Normal file
7
src/var/rcssNum.js
Normal file
@ -0,0 +1,7 @@
|
||||
define([
|
||||
"../var/pnum"
|
||||
], function( pnum ) {
|
||||
|
||||
return new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
|
||||
|
||||
});
|
@ -217,6 +217,58 @@ test( "css() explicit and relative values", 29, function() {
|
||||
equal( $elem.css("opacity"), "1", "'+=0.5' on opacity (params)" );
|
||||
});
|
||||
|
||||
test( "css() non-px relative values (gh-1711)", 17, function() {
|
||||
var cssCurrent,
|
||||
units = {},
|
||||
$child = jQuery( "#nothiddendivchild" ),
|
||||
add = function( prop, val, unit ) {
|
||||
var str = ( val < 0 ? "-=" : "+=" ) + Math.abs( val ) + unit;
|
||||
$child.css( prop, str );
|
||||
equal(
|
||||
Math.round( parseFloat( $child.css( prop ) ) ),
|
||||
Math.round( cssCurrent += val * units[ prop ][ unit ] ),
|
||||
prop + ": '" + str + "'"
|
||||
);
|
||||
},
|
||||
getUnits = function( prop ) {
|
||||
units[ prop ] = {
|
||||
"px": 1,
|
||||
"em": parseFloat( $child.css( prop, "100em" ).css( prop ) ) / 100,
|
||||
"pt": parseFloat( $child.css( prop, "100pt" ).css( prop ) ) / 100,
|
||||
"pc": parseFloat( $child.css( prop, "100pc" ).css( prop ) ) / 100,
|
||||
"cm": parseFloat( $child.css( prop, "100cm" ).css( prop ) ) / 100,
|
||||
"mm": parseFloat( $child.css( prop, "100mm" ).css( prop ) ) / 100,
|
||||
"%" : parseFloat( $child.css( prop, "100%" ).css( prop ) ) / 100
|
||||
};
|
||||
};
|
||||
|
||||
jQuery( "#nothiddendiv" ).css({ height: 1, padding: 0, width: 400 });
|
||||
$child.css({ height: 1, padding: 0 });
|
||||
|
||||
getUnits( "width" );
|
||||
cssCurrent = parseFloat( $child.css( "width", "50%" ).css( "width" ) );
|
||||
add( "width", 25, "%" );
|
||||
add( "width", -50, "%" );
|
||||
add( "width", 10, "em" );
|
||||
add( "width", 10, "pt" );
|
||||
add( "width", -2.3, "pt" );
|
||||
add( "width", 5, "pc" );
|
||||
add( "width", -5, "em" );
|
||||
add( "width", +2, "cm" );
|
||||
add( "width", -15, "mm" );
|
||||
add( "width", 21, "px" );
|
||||
|
||||
getUnits( "lineHeight" );
|
||||
cssCurrent = parseFloat( $child.css( "lineHeight", "1em" ).css( "lineHeight" ) );
|
||||
add( "lineHeight", 2, "em" );
|
||||
add( "lineHeight", -10, "px" );
|
||||
add( "lineHeight", 20, "pt" );
|
||||
add( "lineHeight", 30, "pc" );
|
||||
add( "lineHeight", 1, "cm" );
|
||||
add( "lineHeight", -20, "mm" );
|
||||
add( "lineHeight", 50, "%" );
|
||||
});
|
||||
|
||||
test("css(String, Object)", function() {
|
||||
expect( 19 );
|
||||
var j, div, display, ret, success;
|
||||
|
Loading…
Reference in New Issue
Block a user