Optimizations to animation queue/promise logic, closes gh-776.

This commit is contained in:
Corey Frang
2012-05-22 23:04:45 -04:00
committed by Dave Methvin
parent ae20e732f0
commit 4621a0131b
4 changed files with 224 additions and 180 deletions

81
test/unit/effects.js vendored
View File

@@ -1628,3 +1628,84 @@ asyncTest( "hide, fadeOut and slideUp called on element width height and width =
start();
});
});
asyncTest( "Handle queue:false promises", 10, function() {
var foo = jQuery( "#foo" ).clone().andSelf(),
step = 1;
foo.animate({
top: 1
}, {
duration: 10,
queue: false,
complete: function() {
ok( step++ <= 2, "Step one or two" );
}
}).animate({
bottom: 1
}, {
duration: 10,
complete: function() {
ok( step > 2 && step < 5, "Step three or four" );
step++;
}
});
foo.promise().done( function() {
equal( step++, 5, "steps 1-5: queue:false then queue:fx done" );
foo.animate({
top: 10
}, {
duration: 10,
complete: function() {
ok( step > 5 && step < 8, "Step six or seven" );
step++;
}
}).animate({
bottom: 10
}, {
duration: 10,
queue: false,
complete: function() {
ok( step > 7 && step < 10, "Step eight or nine" );
step++;
}
}).promise().done( function() {
equal( step++, 10, "steps 6-10: queue:fx then queue:false" );
start();
});
});
});
asyncTest( "multiple unqueued and promise", 4, function() {
var foo = jQuery( "#foo" ),
step = 1;
foo.animate({
marginLeft: 300
}, {
duration: 500,
queue: false,
complete: function() {
strictEqual( step++, 2, "Step 2" );
}
}).animate({
top: 100
}, {
duration: 1500,
queue: false,
complete: function() {
strictEqual( step++, 3, "Step 3" );
}
}).animate({}, {
duration: 2000,
queue: false,
complete: function() {
// no properties is a non-op and finishes immediately
strictEqual( step++, 1, "Step 1" );
}
}).promise().done( function() {
strictEqual( step++, 4, "Step 4" );
start();
});
});

View File

@@ -1,15 +1,15 @@
module("queue", { teardown: moduleTeardown });
module( "queue", {
teardown: moduleTeardown
});
test("queue() with other types",function() {
expect(12);
test( "queue() with other types", 12, function() {
var counter = 0;
stop();
var $div = jQuery({}),
defer;
$div.promise("foo").done(function() {
$div.promise( "foo" ).done(function() {
equal( counter, 0, "Deferred for collection with no queue is automatically resolved" );
});
@@ -30,7 +30,7 @@ test("queue() with other types",function() {
});
defer = $div.promise("foo").done(function() {
equal( counter, 4, "Testing previous call to dequeue in deferred" );
equal( counter, 4, "Testing previous call to dequeue in deferred" );
start();
});
@@ -216,85 +216,46 @@ test("clearQueue() clears the fx queue", function() {
div.removeData();
});
test("_mark() and _unmark()", function() {
expect(1);
asyncTest( "fn.promise() - called when fx queue is empty", 3, function() {
var foo = jQuery( "#foo" ).clone().andSelf(),
promised = false;
var div = {},
$div = jQuery( div );
stop();
jQuery._mark( div, "foo" );
jQuery._mark( div, "foo" );
jQuery._unmark( div, "foo" );
jQuery._unmark( div, "foo" );
$div.promise( "foo" ).done(function() {
ok( true, "No more marks" );
foo.queue( function( next ) {
// called twice!
ok( !promised, "Promised hasn't been called" );
setTimeout( next, 10 );
});
foo.promise().done( function() {
ok( promised = true, "Promised" );
start();
});
});
test("_mark() and _unmark() default to 'fx'", function() {
expect(1);
var div = {},
$div = jQuery( div );
stop();
jQuery._mark( div );
jQuery._mark( div );
jQuery._unmark( div, "fx" );
jQuery._unmark( div );
$div.promise().done(function() {
ok( true, "No more marks" );
start();
asyncTest( "fn.promise( \"queue\" ) - called whenever last queue function is dequeued", 5, function() {
var foo = jQuery( "#foo" ),
test;
foo.promise( "queue" ).done( function() {
strictEqual( test, undefined, "called immediately when queue was already empty" );
});
});
test("promise()", function() {
expect(1);
stop();
var objects = [];
jQuery.each( [{}, {}], function( i, div ) {
var $div = jQuery( div );
$div.queue(function( next ) {
setTimeout( function() {
if ( i ) {
next();
setTimeout( function() {
jQuery._unmark( div );
}, 20 );
} else {
jQuery._unmark( div );
setTimeout( function() {
next();
}, 20 );
}
}, 50 );
}).queue(function( next ) {
test = 1;
foo.queue( "queue", function( next ) {
strictEqual( test++, 1, "step one" );
setTimeout( next, 0 );
}).queue( "queue", function( next ) {
strictEqual( test++, 2, "step two" );
setTimeout( function() {
strictEqual( test++, 4, "step four" );
next();
});
jQuery._mark( div );
objects.push( $div );
start();
}, 10 );
}).promise( "queue" ).done( function() {
strictEqual( test++, 3, "step three" );
});
jQuery.when.apply( jQuery, objects ).done(function() {
ok( true, "Deferred resolved" );
start();
});
jQuery.each( objects, function() {
this.dequeue();
});
foo.dequeue( "queue" );
});
test(".promise(obj)", function() {
test( ".promise(obj)", function() {
expect(2);
var obj = {};
@@ -303,3 +264,23 @@ test(".promise(obj)", function() {
ok( jQuery.isFunction( promise.promise ), ".promise(type, obj) returns a promise" );
strictEqual( promise, obj, ".promise(type, obj) returns obj" );
});
asyncTest( "queue stop hooks", 2, function() {
var foo = jQuery( "#foo" );
foo.queue( function( next, hooks ) {
hooks.stop = function( gotoEnd ) {
equal( !!gotoEnd, false, "Stopped without gotoEnd" );
};
});
foo.stop();
foo.queue( function( next, hooks ) {
hooks.stop = function( gotoEnd ) {
equal( gotoEnd, true, "Stopped with gotoEnd" );
start();
};
});
foo.stop( false, true );
});