diff options
author | jaubourg <j@ubourg.net> | 2011-04-07 06:00:52 +0200 |
---|---|---|
committer | jaubourg <j@ubourg.net> | 2011-04-07 06:00:52 +0200 |
commit | 4552d135f404b78f4fa1494a3de2911b2e2e4773 (patch) | |
tree | d7177b0b0ef40893e9dbadf18b837c02043b8bef /src/queue.js | |
parent | bb99899ca0de93dd12f5a53f409ff6f72bfcf94c (diff) | |
download | jquery-4552d135f404b78f4fa1494a3de2911b2e2e4773.tar.gz jquery-4552d135f404b78f4fa1494a3de2911b2e2e4773.zip |
Adds fn.promise as a mean to observe the completion of animations on a set of elements. Only queued animations are handled for now, non-queued animations support coming soon. Effects unit tests updated to test the feature (needs more testing though).
Diffstat (limited to 'src/queue.js')
-rw-r--r-- | src/queue.js | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/src/queue.js b/src/queue.js index 9e3e2fb52..701d06ade 100644 --- a/src/queue.js +++ b/src/queue.js @@ -28,7 +28,8 @@ jQuery.extend({ type = type || "fx"; var queue = jQuery.queue( elem, type ), - fn = queue.shift(); + fn = queue.shift(), + defer; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { @@ -49,6 +50,17 @@ jQuery.extend({ if ( !queue.length ) { jQuery.removeData( elem, type + "queue", true ); + // Look if we have observers and resolve if needed + if (( defer = jQuery.data( elem, type + "defer", undefined, true ) )) { + // Give room for hard-coded callbacks to fire first + // and eventually add another animation on the element + setTimeout( function() { + if ( !jQuery.data( elem, type + "queue", undefined, true ) ) { + jQuery.removeData( elem, type + "defer", true ); + defer.resolve(); + } + }, 0 ); + } } } }); @@ -93,6 +105,37 @@ jQuery.fn.extend({ clearQueue: function( type ) { return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue"; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + jQuery.data( elements[ i ], queueDataKey, undefined, true ) && + jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) { + count++; + tmp.done( resolve ); + } + } + resolve(); + return defer.promise(); } }); |