]> source.dussan.org Git - jquery.git/commitdiff
Fix #11971: force numeric animation start to be numeric, closes gh-836.
authorRichard Gibson <richard.gibson@gmail.com>
Tue, 26 Jun 2012 17:48:31 +0000 (13:48 -0400)
committerDave Methvin <dave.methvin@gmail.com>
Fri, 6 Jul 2012 01:38:17 +0000 (21:38 -0400)
src/effects.js
test/data/testsuite.css
test/unit/effects.js

index f1bbed763b44ca432fb773ec084b93104e111cca..0716248f11c65055077fc8cfa87444a7936bb23e 100644 (file)
@@ -1,6 +1,6 @@
 var fxNow, timerId,
        rfxtypes = /^(?:toggle|show|hide)$/,
-       rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
+       rfxnum = /^(?:([\-+])=)?([\d+.\-]+)([a-z%]*)$/i,
        rrun = /queueHooks$/,
        animationPrefilters = [ defaultPrefilter ],
        tweeners = {
@@ -8,9 +8,9 @@ var fxNow, timerId,
                        var end, unit, prevScale,
                                tween = this.createTween( prop, value ),
                                parts = rfxnum.exec( value ),
-                               start = tween.cur(),
-                               scale = 1,
-                               target = start;
+                               target = tween.cur(),
+                               start = +target || 0,
+                               scale = 1;
 
                        if ( parts ) {
                                end = +parts[2];
@@ -21,7 +21,7 @@ var fxNow, timerId,
                                        // Iteratively approximate from a nonzero starting point
                                        // Prefer the current property, because this process will be trivial if it uses the same units
                                        // Fallback to end or a simple constant
-                                       start = parseFloat( jQuery.css( tween.elem, prop ) ) || end || 1;
+                                       start = jQuery.css( tween.elem, prop, true ) || end || 1;
 
                                        do {
                                                // If previous iteration zeroed out, double until we get *something*
@@ -35,14 +35,14 @@ var fxNow, timerId,
                                                // Update scale, tolerating zeroes from tween.cur()
                                                scale = tween.cur() / target;
 
-                                       // Stop looping if scale is unchanged or we've hit the mark
+                                       // Stop looping if we've hit the mark or scale is unchanged
                                        } while ( scale !== 1 && scale !== prevScale );
                                }
 
                                tween.unit = unit;
                                tween.start = start;
                                // If a +=/-= token was provided, we're doing a relative animation
-                               tween.end = parts[1] ? start + end * ( parts[1] === "-=" ? -1 : 1 ) : end;
+                               tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;
                        }
                        return tween;
                }]
index d3e4b4e40a949620186c59fdf199779dd8bced52..0046c2fe24bf6e51152575598632f73b811a147a 100644 (file)
@@ -125,4 +125,7 @@ body, div { background: url(http://static.jquery.com/files/rocker/images/logo_jq
 #t6652 div { filter: alpha(opacity=50); }
 
 /* #10501 */
-section { background:#f0f; display:block; }
\ No newline at end of file
+section { background:#f0f; display:block; }
+
+/* #11971 */
+#foo { background: url(data/1x1.jpg) right bottom no-repeat; }
index 57fa8c966e2d6ba99a6cb2521471c68c908f1172..402a7a58799239ec41a8d7630be4234b59e4abb7 100644 (file)
@@ -1677,13 +1677,40 @@ asyncTest( "animate does not change start value for non-px animation (#7109)", 1
        });
 });
 
-asyncTest("Animation callbacks (#11797)", 12, function() {
+asyncTest( "non-px animation handles non-numeric start (#11971)", 2, function() {
+       var foo = jQuery("#foo"),
+               initial = foo.css("backgroundPositionX");
+
+       foo.animate({ backgroundPositionX: "42%" }, {
+               duration: 1,
+               progress: function( anim, percent ) {
+                       if ( percent ) {
+                               return;
+                       }
+
+                       if ( parseFloat( initial ) ) {
+                               equal( jQuery.style( this, "backgroundPositionX" ), initial, "Numeric start preserved" );
+                       } else {
+                               equal( jQuery.style( this, "backgroundPositionX" ), "0%", "Non-numeric start zeroed" );
+                       }
+               },
+               done: function() {
+                       equal( jQuery.style( this, "backgroundPositionX" ), "42%", "End reached" );
+                       start();
+               }
+       });
+});
+
+asyncTest("Animation callbacks (#11797)", 15, function() {
        var targets = jQuery("#foo").children(),
                done = false,
                expectedProgress = 0;
 
        targets.eq( 0 ).animate( {}, {
                duration: 1,
+               start: function() {
+                       ok( true, "empty: start" );
+               },
                progress: function( anim, percent ) {
                        equal( percent, 0, "empty: progress 0" );
                },
@@ -1699,13 +1726,16 @@ asyncTest("Animation callbacks (#11797)", 12, function() {
                }
        });
 
-       ok( done, "animation done" );
+       ok( done, "empty: done immediately" );
 
        done = false;
        targets.eq( 1 ).animate({
                opacity: 0
        }, {
                duration: 1,
+               start: function() {
+                       ok( true, "stopped: start" );
+               },
                progress: function( anim, percent ) {
                        equal( percent, 0, "stopped: progress 0" );
                },
@@ -1721,12 +1751,15 @@ asyncTest("Animation callbacks (#11797)", 12, function() {
                }
        }).stop();
 
-       ok( done, "animation stopped" );
+       ok( done, "stopped: stopped immediately" );
 
        targets.eq( 2 ).animate({
                opacity: 0
        }, {
                duration: 1,
+               start: function() {
+                       ok( true, "async: start" );
+               },
                progress: function( anim, percent ) {
                        equal( percent, expectedProgress, "async: progress " + expectedProgress );
                        // once at 0, once at 1