Added enchancement for #1994 by adding two parameters to .stop() which give additiona...
authorDavid Serduke <davidserduke@gmail.com>
Fri, 30 Nov 2007 21:36:49 +0000 (21:36 +0000)
committerDavid Serduke <davidserduke@gmail.com>
Fri, 30 Nov 2007 21:36:49 +0000 (21:36 +0000)
While adding unit testing I noticed the stop() unit test wasn't working correctly because the element was hidden so I fixed it and added more unit tests around the new functionality.  I also added a cursor:pointer to the css (because for a long time I didn't know they were clickable).

src/fx.js
test/data/testsuite.css
test/unit/fx.js

index 9bfe999..b35dbcd 100644 (file)
--- a/src/fx.js
+++ b/src/fx.js
@@ -146,14 +146,28 @@ jQuery.fn.extend({
                });
        },
 
-       stop: function(){
+       stop: function(clearQueue, gotoEnd){
                var timers = jQuery.timers;
 
-               return this.each(function(){
-                       for ( var i = 0; i < timers.length; i++ )
-                               if ( timers[i].elem == this )
-                                       timers.splice(i--, 1);
-               }).dequeue();
+               if (clearQueue)
+                       this.queue([]);
+
+               this.each(function(){
+                       // go in reverse order so anything added to the queue during the loop is ignored
+                       for ( var i = timers.length - 1; i >= 0; i-- )
+                               if ( timers[i].elem == this ) {
+                                       if (gotoEnd)
+                                               // force the next step to be the last
+                                               timers[i](true);
+                                       timers.splice(i, 1);
+                               }
+               });
+
+               // start the next in the queue if the last step wasn't forced
+               if (!gotoEnd)
+                       this.dequeue();
+
+               return this;
        }
 
 });
@@ -269,8 +283,8 @@ jQuery.fx.prototype = {
                this.update();
 
                var self = this;
-               function t(){
-                       return self.step();
+               function t(gotoEnd){
+                       return self.step(gotoEnd);
                }
 
                t.elem = this.elem;
@@ -322,10 +336,10 @@ jQuery.fx.prototype = {
        },
 
        // Each step of an animation
-       step: function(){
+       step: function(gotoEnd){
                var t = (new Date()).getTime();
 
-               if ( t > this.options.duration + this.startTime ) {
+               if ( gotoEnd || t > this.options.duration + this.startTime ) {
                        this.now = this.end;
                        this.pos = this.state = 1;
                        this.update();
index b9d487b..b15f5ef 100644 (file)
@@ -11,6 +11,8 @@ p.result { margin-left: 1em; }
 h2.pass { background-color: green; }
 h2.fail { background-color: red; }
 
+ol#tests > li > strong { cursor:pointer; }
+
 div#fx-tests h4 {
        background: red;
 }
index c20e39c..1204e26 100644 (file)
@@ -54,21 +54,101 @@ test("queue() defaults to 'fx' type", function () {
 test("stop()", function() {
        expect(3);
        stop();
-       reset();
 
-       var foo = $("#foo")[0];
-       var h = foo.style.height;
+       var $foo = $("#nothiddendiv");
+       var w = 0;
+       $foo.hide().width(200).width();
 
-       $("#foo").slideUp(1000);
+       $foo.animate({ width:'show' }, 1000);
        setTimeout(function(){
-               var nh = foo.style.height;
-               ok( nh != h, "An animation occurred " + nh + " " + h );
-               $("#foo").stop();
+               var nw = $foo.width();
+               ok( nw != w, "An animation occurred " + nw + "px " + w + "px");
+               $foo.stop();
 
-               nh = foo.style.height;
-               ok( nh != h, "Stop didn't reset the animation " + nh + " " + h );
+               nw = $foo.width();
+               ok( nw != w, "Stop didn't reset the animation " + nw + "px " + w + "px");
                setTimeout(function(){
-                       equals( nh, foo.style.height, "The animation didn't continue" );
+                       equals( nw, $foo.width(), "The animation didn't continue" );
+                       start();
+               }, 100);
+       }, 100);
+});
+
+test("stop() - several in queue", function() {
+       expect(4);
+       stop();
+
+       var $foo = $("#nothiddendiv");
+       var w = 0;
+       $foo.hide().width(200).width();
+
+       $foo.animate({ width:'show' }, 1000);
+       $foo.animate({ width:'hide' }, 1000);
+       $foo.animate({ width:'show' }, 1000);
+       setTimeout(function(){
+               equals( $foo.queue().length, 3, "All 3 still in the queue" );
+               var nw = $foo.width();
+               ok( nw != w, "An animation occurred " + nw + "px " + w + "px");
+               $foo.stop();
+
+               nw = $foo.width();
+               ok( nw != w, "Stop didn't reset the animation " + nw + "px " + w + "px");
+               equals( $foo.queue().length, 2, "The next animation continued" );
+               $foo.stop(true);
+               start();
+       }, 100);
+});
+
+test("stop(clearQueue)", function() {
+       expect(4);
+       stop();
+
+       var $foo = $("#nothiddendiv");
+       var w = 0;
+       $foo.hide().width(200).width();
+
+       $foo.animate({ width:'show' }, 1000);
+       $foo.animate({ width:'hide' }, 1000);
+       $foo.animate({ width:'show' }, 1000);
+       setTimeout(function(){
+               var nw = $foo.width();
+               ok( nw != w, "An animation occurred " + nw + "px " + w + "px");
+               $foo.stop(true);
+
+               nw = $foo.width();
+               ok( nw != w, "Stop didn't reset the animation " + nw + "px " + w + "px");
+
+               equals( $foo.queue().length, 0, "The animation queue was cleared" );
+               setTimeout(function(){
+                       equals( nw, $foo.width(), "The animation didn't continue" );
+                       start();
+               }, 100);
+       }, 100);
+});
+
+test("stop(clearQueue, gotoEnd)", function() {
+       expect(3);
+       stop();
+
+       var $foo = $("#nothiddendiv");
+       var w = 0;
+       $foo.hide().width(200).width();
+
+       $foo.animate({ width:'show' }, 1000);
+       $foo.animate({ width:'hide' }, 1000);
+       $foo.animate({ width:'show' }, 1000);
+       $foo.animate({ width:'hide' }, 1000);
+       setTimeout(function(){
+               var nw = $foo.width();
+               ok( nw != w, "An animation occurred " + nw + "px " + w + "px");
+               $foo.stop(false, true);
+
+               nw = $foo.width();
+               equals( nw, 200, "Stop() reset the animation" );
+
+               setTimeout(function(){
+                       equals( $foo.queue().length, 3, "The next animation continued" );
+                       $foo.stop(true);
                        start();
                }, 100);
        }, 100);
@@ -77,11 +157,11 @@ test("stop()", function() {
 test("toggle()", function() {
        expect(3);
        var x = $("#foo");
-       ok( x.is(":visible") );
+       ok( x.is(":visible"), "is visible" );
        x.toggle();
-       ok( x.is(":hidden") );
+       ok( x.is(":hidden"), "is hidden" );
        x.toggle();
-       ok( x.is(":visible") );
+       ok( x.is(":visible"), "is visible again" );
 });
 
 var visible = {