Moved unload abort code so that the event is only bound if the xhr transport is used...
[jquery.git] / src / core.js
index d41b9a9..b9e6d81 100644 (file)
@@ -59,7 +59,7 @@ var jQuery = function( selector, context ) {
 
        // Has the ready events already been bound?
        readyBound = false,
-       
+
        // The deferred used on DOM ready
        readyList,
 
@@ -75,10 +75,7 @@ var jQuery = function( selector, context ) {
        indexOf = Array.prototype.indexOf,
 
        // [[Class]] -> type pairs
-       class2type = {},
-       
-       // Marker for deferred
-       deferredMarker = [];
+       class2type = {};
 
 jQuery.fn = jQuery.prototype = {
        init: function( selector, context ) {
@@ -255,13 +252,13 @@ jQuery.fn = jQuery.prototype = {
        each: function( callback, args ) {
                return jQuery.each( this, callback, args );
        },
-       
+
        ready: function() {
                // Attach the listeners
                jQuery.bindReady();
-               
+
                // Change ready & apply
-               return ( jQuery.fn.ready = readyList.then ).apply( this , arguments );
+               return ( jQuery.fn.ready = readyList.done ).apply( this , arguments );
        },
 
        eq: function( i ) {
@@ -409,7 +406,7 @@ jQuery.extend({
 
                        // If there are functions bound, to execute
                        readyList.fire( document , [ jQuery ] );
-                       
+
                        // Trigger any bound ready events
                        if ( jQuery.fn.trigger ) {
                                jQuery( document ).trigger( "ready" ).unbind( "ready" );
@@ -547,6 +544,28 @@ jQuery.extend({
                }
        },
 
+       // Cross-browser xml parsing
+       // (xml & tmp used internally)
+       parseXML: function( data , xml , tmp ) {
+
+               if ( window.DOMParser ) { // Standard
+                       tmp = new DOMParser();
+                       xml = tmp.parseFromString( data , "text/xml" );
+               } else { // IE
+                       xml = new ActiveXObject( "Microsoft.XMLDOM" );
+                       xml.async = "false";
+                       xml.loadXML( data );
+               }
+
+               tmp = xml.documentElement;
+
+               if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
+                       jQuery.error( "Invalid XML: " + data );
+               }
+
+               return xml;
+       },
+
        noop: function() {},
 
        // Evalulates a script in a global context
@@ -781,13 +800,10 @@ jQuery.extend({
        now: function() {
                return (new Date()).getTime();
        },
-       
+
        // Create a simple deferred (one callbacks list)
-       _deferred: function( cancellable ) {
-               
-               // cancellable by default
-               cancellable = cancellable !== false;
-               
+       _Deferred: function() {
+
                var // callbacks list
                        callbacks = [],
                        // stored [ context , args ]
@@ -798,142 +814,136 @@ jQuery.extend({
                        cancelled,
                        // the deferred itself
                        deferred  = {
-                               
-                               // then( f1, f2, ...)
-                               then: function() {
-                                       
+
+                               // done( f1, f2, ...)
+                               done: function () {
+
                                        if ( ! cancelled ) {
-                                       
+
                                                var args = arguments,
                                                        i,
+                                                       length,
+                                                       elem,
                                                        type,
                                                        _fired;
-                                                       
+
                                                if ( fired ) {
                                                        _fired = fired;
                                                        fired = 0;
                                                }
-                                               
-                                               for ( i in args ) {
-                                                       i = args[ i ];
-                                                       type = jQuery.type( i );
+
+                                               for ( i = 0, length = args.length ; i < length ; i++ ) {
+                                                       elem = args[ i ];
+                                                       type = jQuery.type( elem );
                                                        if ( type === "array" ) {
-                                                               this.then.apply( this , i );
+                                                               deferred.done.apply( deferred , elem );
                                                        } else if ( type === "function" ) {
-                                                               callbacks.push( i );
+                                                               callbacks.push( elem );
                                                        }
                                                }
-                                               
+
                                                if ( _fired ) {
                                                        deferred.fire( _fired[ 0 ] , _fired[ 1 ] );
                                                }
                                        }
+
                                        return this;
                                },
-                               
+
                                // resolve with given context and args
-                               // (i is used internally)
-                               fire: function( context , args , i ) {
+                               fire: function( context , args ) {
                                        if ( ! cancelled && ! fired && ! firing ) {
+
                                                firing = 1;
+
                                                try {
-                                                       for( i = 0 ; ! cancelled && callbacks[ i ] ; i++ ) {
-                                                               cancelled = ( callbacks[ i ].apply( context , args ) === false ) && cancellable;
+                                                       while( callbacks[ 0 ] ) {
+                                                               callbacks.shift().apply( context , args );
                                                        }
-                                               } catch( e ) {
-                                                       cancelled = cancellable;
-                                                       jQuery.error( e );
-                                               } finally {
+                                               }
+                                               finally {
                                                        fired = [ context , args ];
-                                                       callbacks = cancelled ? [] : callbacks.slice( i + 1 );
                                                        firing = 0;
                                                }
                                        }
                                        return this;
                                },
-                               
+
                                // resolve with this as context and given arguments
                                resolve: function() {
-                                       deferred.fire( this , arguments );
+                                       deferred.fire( jQuery.isFunction( this.promise ) ? this.promise() : this , arguments );
                                        return this;
                                },
-                               
-                               // cancelling further callbacks
+
+                               // Has this deferred been resolved?
+                               isResolved: function() {
+                                       return !!( firing || fired );
+                               },
+
+                               // Cancel
                                cancel: function() {
-                                       if ( cancellable ) {
-                                               callbacks = [];
-                                               cancelled = 1;
-                                       }
+                                       cancelled = 1;
+                                       callbacks = [];
                                        return this;
                                }
-                               
                        };
-               
-               // Add the deferred marker
-               deferred.then._ = deferredMarker;
-               
+
                return deferred;
        },
-       
+
        // Full fledged deferred (two callbacks list)
        // Typical success/error system
-       deferred: function( func , cancellable ) {
-               
-               // Handle varargs
-               if ( arguments.length === 1 ) {
-                       
-                       if ( typeof func === "boolean" ) {
-                               cancellable = func;
-                               func = 0;
-                       }
-               }
-               
-               var errorDeferred = jQuery._deferred( cancellable ),
-                       deferred = jQuery._deferred( cancellable ),
-                       // Keep reference of the cancel method since we'll redefine it
-                       cancelThen = deferred.cancel;
-                       
-               // Add errorDeferred methods and redefine cancel                        
+       Deferred: function( func ) {
+
+               var deferred = jQuery._Deferred(),
+                       failDeferred = jQuery._Deferred();
+
+               // Add errorDeferred methods and redefine cancel
                jQuery.extend( deferred , {
 
-                               fail: errorDeferred.then,
-                               fireReject: errorDeferred.fire,
-                               reject: errorDeferred.resolve,
-                               cancel: function() {
-                                       cancelThen();
-                                       errorDeferred.cancel();
-                                       return this;
-                               }
+                       then: function( doneCallbacks , failCallbacks ) {
+                               deferred.done( doneCallbacks ).fail( failCallbacks );
+                               return this;
+                       },
+                       fail: failDeferred.done,
+                       fireReject: failDeferred.fire,
+                       reject: failDeferred.resolve,
+                       isRejected: failDeferred.isResolved,
+                       // Get a promise for this deferred
+                       // If obj is provided, the promise aspect is added to the object
+                       promise: function( obj ) {
+                               obj = obj || {};
+                               jQuery.each( "then done fail isResolved isRejected".split( " " ) , function( _ , method ) {
+                                       obj[ method ] = deferred[ method ];
+                               });
+                               obj.promise = function() {
+                                       return obj;
+                               };
+                               return obj;
+                       }
 
                } );
-               
+
                // Make sure only one callback list will be used
-               deferred.then( errorDeferred.cancel ).fail( cancelThen );
-               
+               deferred.then( failDeferred.cancel , deferred.cancel );
+
+               // Unexpose cancel
+               delete deferred.cancel;
+
                // Call given func if any
                if ( func ) {
                        func.call( deferred , deferred );
                }
-               
+
                return deferred;
        },
 
-       // Check if an object is a deferred
-       isDeferred: function( object , method ) {
-               method = method || "then";
-               return !!( object && object[ method ] && object[ method ]._ === deferredMarker );
-       },
-       
        // Deferred helper
-       when: function( object , method ) {
-               method = method || "then";
-               object = jQuery.isDeferred( object , method ) ?
+       when: function( object ) {
+               object = object && jQuery.isFunction( object.promise ) ?
                        object :
-                       jQuery.deferred().resolve( object );
-               object.fail = object.fail || function() { return this; };
-               object[ method ] = object[ method ] || object.then;
-               object.then = object.then || object[ method ];
-               return object;
+                       jQuery.Deferred().resolve( object );
+               return object.promise();
        },
 
        // Use of jQuery.browser is frowned upon.
@@ -954,9 +964,7 @@ jQuery.extend({
 });
 
 // Create readyList deferred
-// also force $.fn.ready to be recognized as a defer
-readyList = jQuery._deferred( false );
-jQuery.fn.ready._ = deferredMarker;
+readyList = jQuery._Deferred();
 
 // Populate the class2type map
 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
@@ -1026,11 +1034,6 @@ function doScrollCheck() {
        jQuery.ready();
 }
 
-// Expose jQuery as an Asynchronous Module
-if ( typeof define === "function" ) {
-       define( "jquery", [], function () { return jQuery; } );
-}
-
 // Expose jQuery to the global object
 return (window.jQuery = window.$ = jQuery);