From: Yehuda Katz Date: Thu, 16 Jul 2009 07:32:39 +0000 (+0000) Subject: Refactor queueing system to allow auto-dequeuing to use dequeue directly and X-Git-Url: http://git.asbjorn.biz/?p=jquery.git;a=commitdiff_plain;h=991d039b62f5dfcb9e3d99fe28212a6874e8f5c7 Refactor queueing system to allow auto-dequeuing to use dequeue directly 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() --- diff --git a/src/data.js b/src/data.js index 9cc76c6..03116e4 100644 --- a/src/data.js +++ b/src/data.js @@ -63,30 +63,37 @@ jQuery.extend({ } }, 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) ) - q = jQuery.data( elem, type, jQuery.makeArray(data) ); - else if( data ) - q.push( data ); + if ( !q || jQuery.isArray(data) ) + q = jQuery.data( elem, type, jQuery.makeArray(data) ); + else + q.push( data ); - } return q; }, dequeue: function( elem, type ){ - var queue = jQuery.queue( elem, type ), - fn = queue.shift(); + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), fn = queue.shift(); - if( !type || type === "fx" ) - fn = queue[0]; + // If the fx queue is dequeued, always remove the progress sentinel + if( fn === "inprogress" ) fn = queue.shift(); - if( fn !== undefined ) - fn.call(elem, function() { jQuery(elem).dequeue(type); }); + if( fn ) { + // 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); }); + } } }); @@ -129,8 +136,8 @@ jQuery.fn.extend({ return this.each(function(i, elem){ var queue = jQuery.queue( this, type, data ); - if( type == "fx" && queue.length == 1 ) - queue[0].call(this, function() { jQuery(elem).dequeue(type); }); + if( type == "fx" && queue[0] !== "inprogress" ) + jQuery.dequeue( this, type ) }); }, dequeue: function(type){ diff --git a/test/unit/data.js b/test/unit/data.js index 14483a1..6b79da2 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -113,20 +113,23 @@ test(".removeData()", function() { }); test("queue() defaults to 'fx' type", function () { - expect(2); + expect(1); stop(); + var counter = 0; + 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() { @@ -162,9 +165,6 @@ test("queue() with other types",function() { equals( counter, 4, "Testing previous call to dequeue" ); 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() { @@ -184,8 +184,6 @@ test("queue(name) passes in the next item in the queue as a parameter", function }); div.dequeue("foo"); - - div.removeData(); }); test("queue(name) passes in the next item in the queue as a parameter", function() { @@ -205,27 +203,27 @@ test("queue(name) passes in the next item in the queue as a parameter", function }); div.dequeue("foo"); - - div.removeData(); }); test("queue() passes in the next item in the queue as a parameter to fx queues", function() { expect(2); + stop(); var div = jQuery({}); var counter = 0; div.queue(function(next) { equals(++counter, 1, "Dequeueing"); - next(); + var self = this; + setTimeout(function() { next() }, 500); }).queue(function(next) { equals(++counter, 2, "Next was called"); next(); + start(); }).queue("bar", function() { equals(++counter, 3, "Other queues are not triggered by next()") }); - - div.removeData(); + }); test("clearQueue(name) clears the queue", function() { @@ -245,8 +243,6 @@ test("clearQueue(name) clears the queue", function() { div.dequeue("foo"); equals(counter, 1, "the queue was cleared"); - - div.removeData(); }); test("clearQueue() clears the fx queue", function() { @@ -257,7 +253,8 @@ test("clearQueue() clears the fx queue", function() { div.queue(function(next) { counter++; - setTimeout(function() { jQuery(this).clearQueue(); next(); }, 50); + var self = this; + setTimeout(function() { jQuery(self).clearQueue(); next(); }, 50); }).queue(function(next) { counter++; });