Skip to content

Commit

Permalink
Refactor queueing system to allow auto-dequeuing to use dequeue direc…
Browse files Browse the repository at this point in the history
…tly and

therefore require dequeue to always leave the element it has dequeued on
the queue.

  - In the fx queue, a progress sentinel is added when a queue element
    is dequeued.
  - The sentinel is ignored when dequeue is called explicitly
  - When adding a new element to the fx queue, queue() checks if
    the progress sentinel is present. If not, it calls dequeue()
  • Loading branch information
wycats committed Jul 16, 2009
1 parent 190812c commit 991d039
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 39 deletions.
39 changes: 23 additions & 16 deletions src/data.js
Expand Up @@ -63,30 +63,37 @@ jQuery.extend({
} }
}, },
queue: function( elem, type, data ) { queue: function( elem, type, data ) {
if ( elem ){ if( !elem ) return;


type = (type || "fx") + "queue"; type = (type || "fx") + "queue";
var q = jQuery.data( elem, type );


var q = jQuery.data( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup
if( !data ) return q || [];


if ( !q || jQuery.isArray(data) ) if ( !q || jQuery.isArray(data) )
q = jQuery.data( elem, type, jQuery.makeArray(data) ); q = jQuery.data( elem, type, jQuery.makeArray(data) );
else if( data ) else
q.push( data ); q.push( data );


}
return q; return q;
}, },


dequeue: function( elem, type ){ dequeue: function( elem, type ){
var queue = jQuery.queue( elem, type ), type = type || "fx";
fn = queue.shift();
var queue = jQuery.queue( elem, type ), fn = queue.shift();


if( !type || type === "fx" ) // If the fx queue is dequeued, always remove the progress sentinel
fn = queue[0]; if( fn === "inprogress" ) fn = queue.shift();


if( fn !== undefined ) if( fn ) {
fn.call(elem, function() { jQuery(elem).dequeue(type); }); // Add a progress sentinel to prevent the fx queue from being
// automatically dequeued
if( type == "fx" ) queue.unshift("inprogress");

fn.call(elem, function() { jQuery.dequeue(elem, type); });
}
} }
}); });


Expand Down Expand Up @@ -129,8 +136,8 @@ jQuery.fn.extend({
return this.each(function(i, elem){ return this.each(function(i, elem){
var queue = jQuery.queue( this, type, data ); var queue = jQuery.queue( this, type, data );


if( type == "fx" && queue.length == 1 ) if( type == "fx" && queue[0] !== "inprogress" )
queue[0].call(this, function() { jQuery(elem).dequeue(type); }); jQuery.dequeue( this, type )
}); });
}, },
dequeue: function(type){ dequeue: function(type){
Expand Down
43 changes: 20 additions & 23 deletions test/unit/data.js
Expand Up @@ -113,20 +113,23 @@ test(".removeData()", function() {
}); });


test("queue() defaults to 'fx' type", function () { test("queue() defaults to 'fx' type", function () {
expect(2); expect(1);
stop(); stop();


var counter = 0;

var $foo = jQuery("#foo"); var $foo = jQuery("#foo");
$foo.queue("fx", [ "sample", "array" ]);
var arr = $foo.queue();
isSet(arr, [ "sample", "array" ], "queue() got an array set with type 'fx'");
$foo.queue([ "another", "one" ]);
var arr = $foo.queue("fx");
isSet(arr, [ "another", "one" ], "queue('fx') got an array set with no type");
// clean up after test
$foo.queue([]);


start(); $foo.queue(function() {
var self = this;
setTimeout(function() {
jQuery(self).dequeue("fx");
start();
}, 200);
}).queue(function() {
ok( "dequeuing 'fx' calls queues created with no name" )
});

}); });


test("queue() with other types",function() { test("queue() with other types",function() {
Expand Down Expand Up @@ -162,9 +165,6 @@ test("queue() with other types",function() {


equals( counter, 4, "Testing previous call to dequeue" ); equals( counter, 4, "Testing previous call to dequeue" );
equals( $div.queue('foo').length, 0, "Testing queue length" ); equals( $div.queue('foo').length, 0, "Testing queue length" );

// Clean up
$div.removeData();
}); });


test("queue(name) passes in the next item in the queue as a parameter", function() { test("queue(name) passes in the next item in the queue as a parameter", function() {
Expand All @@ -184,8 +184,6 @@ test("queue(name) passes in the next item in the queue as a parameter", function
}); });


div.dequeue("foo"); div.dequeue("foo");

div.removeData();
}); });


test("queue(name) passes in the next item in the queue as a parameter", function() { test("queue(name) passes in the next item in the queue as a parameter", function() {
Expand All @@ -205,27 +203,27 @@ test("queue(name) passes in the next item in the queue as a parameter", function
}); });


div.dequeue("foo"); div.dequeue("foo");

div.removeData();
}); });


test("queue() passes in the next item in the queue as a parameter to fx queues", function() { test("queue() passes in the next item in the queue as a parameter to fx queues", function() {
expect(2); expect(2);
stop();


var div = jQuery({}); var div = jQuery({});
var counter = 0; var counter = 0;


div.queue(function(next) { div.queue(function(next) {
equals(++counter, 1, "Dequeueing"); equals(++counter, 1, "Dequeueing");
next(); var self = this;
setTimeout(function() { next() }, 500);
}).queue(function(next) { }).queue(function(next) {
equals(++counter, 2, "Next was called"); equals(++counter, 2, "Next was called");
next(); next();
start();
}).queue("bar", function() { }).queue("bar", function() {
equals(++counter, 3, "Other queues are not triggered by next()") equals(++counter, 3, "Other queues are not triggered by next()")
}); });


div.removeData();
}); });


test("clearQueue(name) clears the queue", function() { test("clearQueue(name) clears the queue", function() {
Expand All @@ -245,8 +243,6 @@ test("clearQueue(name) clears the queue", function() {
div.dequeue("foo"); div.dequeue("foo");


equals(counter, 1, "the queue was cleared"); equals(counter, 1, "the queue was cleared");

div.removeData();
}); });


test("clearQueue() clears the fx queue", function() { test("clearQueue() clears the fx queue", function() {
Expand All @@ -257,7 +253,8 @@ test("clearQueue() clears the fx queue", function() {


div.queue(function(next) { div.queue(function(next) {
counter++; counter++;
setTimeout(function() { jQuery(this).clearQueue(); next(); }, 50); var self = this;
setTimeout(function() { jQuery(self).clearQueue(); next(); }, 50);
}).queue(function(next) { }).queue(function(next) {
counter++; counter++;
}); });
Expand Down

0 comments on commit 991d039

Please sign in to comment.