Merge in data_nocollide branch. Fixes #6968, improves unit testing framework checks...
authorColin Snover <github.com@zetafleet.com>
Mon, 17 Jan 2011 21:31:43 +0000 (15:31 -0600)
committerColin Snover <github.com@zetafleet.com>
Mon, 17 Jan 2011 21:31:43 +0000 (15:31 -0600)
16 files changed:
src/ajax.js
src/ajax/jsonp.js
src/ajax/script.js
src/ajax/xhr.js
src/core.js
src/css.js
src/event.js
src/manipulation.js
src/traversing.js
test/data/jsonp.php
test/unit/ajax.js
test/unit/core.js
test/unit/css.js
test/unit/event.js
test/unit/manipulation.js
version.txt

index dbea8d5..871481d 100644 (file)
@@ -11,6 +11,7 @@ var r20 = /%20/g,
        rselectTextarea = /^(?:select|textarea)/i,
        rts = /([?&])_=[^&]*/,
        rurl = /^(\w+:)?\/\/([^\/?#:]+)(?::(\d+))?/,
+       rCRLF = /\r?\n/g,
 
        // Slice function
        sliceFunc = Array.prototype.slice,
@@ -60,26 +61,34 @@ jQuery.fn.extend({
                        type: type,
                        dataType: "html",
                        data: params,
-                       complete: function( res, status ) {
+                       // Complete callback (responseText is used internally)
+                       complete: function( jXHR, status, responseText ) {
+                               // Store the response as specified by the jXHR object
+                               responseText = jXHR.responseText;
                                // If successful, inject the HTML into all the matched elements
-                               if ( status === "success" || status === "notmodified" ) {
+                               if ( jXHR.isResolved() ) {
+                                       // #4825: Get the actual response in case
+                                       // a dataFilter is present in ajaxSettings
+                                       jXHR.done(function( r ) {
+                                               responseText = r;
+                                       });
                                        // See if a selector was specified
                                        self.html( selector ?
                                                // Create a dummy div to hold the results
                                                jQuery("<div>")
                                                        // inject the contents of the document in, removing the scripts
                                                        // to avoid any 'Permission Denied' errors in IE
-                                                       .append(res.responseText.replace(rscript, ""))
+                                                       .append(responseText.replace(rscript, ""))
 
                                                        // Locate the specified elements
                                                        .find(selector) :
 
                                                // If not, just inject the full result
-                                               res.responseText );
+                                               responseText );
                                }
 
                                if ( callback ) {
-                                       self.each( callback, [res.responseText, status, res] );
+                                       self.each( callback, [responseText, status, jXHR] );
                                }
                        }
                });
@@ -107,9 +116,9 @@ jQuery.fn.extend({
                                null :
                                jQuery.isArray(val) ?
                                        jQuery.map( val, function(val, i){
-                                               return {name: elem.name, value: val.replace(/\r?\n/g, "\r\n")};
+                                               return { name: elem.name, value: val.replace(rCRLF, "\r\n") };
                                        }) :
-                                       {name: elem.name, value: val.replace(/\r?\n/g, "\r\n")};
+                                       { name: elem.name, value: val.replace(rCRLF, "\r\n") };
                }).get();
        }
 });
@@ -151,7 +160,8 @@ jQuery.extend({
        },
 
        ajaxSetup: function( settings ) {
-               jQuery.extend( jQuery.ajaxSettings, settings );
+               jQuery.extend( true, jQuery.ajaxSettings, settings );
+               return this;
        },
 
        ajaxSettings: {
@@ -165,11 +175,12 @@ jQuery.extend({
                timeout: 0,
                data: null,
                dataType: null,
-               dataTypes: null,
                username: null,
                password: null,
                cache: null,
                traditional: false,
+               headers: {},
+               crossDomain: null,
                */
                xhr: function() {
                        return new window.XMLHttpRequest();
@@ -256,6 +267,8 @@ jQuery.extend({
                        // Deferreds
                        deferred = jQuery.Deferred(),
                        completeDeferred = jQuery._Deferred(),
+                       // Status-dependent callbacks
+                       statusCode = s.statusCode || {},
                        // Headers (they are sent all at once)
                        requestHeaders = {},
                        // Response headers
@@ -265,6 +278,9 @@ jQuery.extend({
                        transport,
                        // timeout handle
                        timeoutTimer,
+                       // Cross-domain detection vars
+                       loc = document.location,
+                       parts,
                        // The jXHR state
                        state = 0,
                        // Loop variable
@@ -291,30 +307,35 @@ jQuery.extend({
                                // (match is used internally)
                                getResponseHeader: function( key , match ) {
 
-                                       if ( state !== 2 ) {
-                                               return null;
-                                       }
+                                       if ( state === 2 ) {
 
-                                       if ( responseHeaders === undefined ) {
+                                               if ( responseHeaders === undefined ) {
 
-                                               responseHeaders = {};
+                                                       responseHeaders = {};
 
-                                               if ( typeof responseHeadersString === "string" ) {
+                                                       if ( typeof responseHeadersString === "string" ) {
 
-                                                       while( ( match = rheaders.exec( responseHeadersString ) ) ) {
-                                                               responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
+                                                               while( ( match = rheaders.exec( responseHeadersString ) ) ) {
+                                                                       responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
+                                                               }
                                                        }
                                                }
+                                               match = responseHeaders[ key.toLowerCase() ];
+
+                                       } else {
+
+                                               match = null;
                                        }
-                                       return responseHeaders[ key.toLowerCase() ];
+
+                                       return match;
                                },
 
                                // Cancel the request
                                abort: function( statusText ) {
-                                       if ( transport && state !== 2 ) {
+                                       if ( transport ) {
                                                transport.abort( statusText || "abort" );
-                                               done( 0 , statusText );
                                        }
+                                       done( 0 , statusText );
                                        return this;
                                }
                        };
@@ -332,6 +353,10 @@ jQuery.extend({
                        // State is "done" now
                        state = 2;
 
+                       // Dereference transport for early garbage collection
+                       // (no matter how long the jXHR transport will be used
+                       transport = 0;
+
                        // Set readyState
                        jXHR.readyState = status ? 4 : 0;
 
@@ -353,17 +378,10 @@ jQuery.extend({
                                // Stored success
                                success,
                                // Stored error
-                               error = statusText;
-
-                       // If not timeout, force a jQuery-compliant status text
-                       if ( statusText != "timeout" ) {
-                               statusText = ( status >= 200 && status < 300 ) ?
-                                       "success" :
-                                       ( status === 304 ? "notmodified" : "error" );
-                       }
+                               error;
 
                        // If successful, handle type chaining
-                       if ( statusText === "success" || statusText === "notmodified" ) {
+                       if ( status >= 200 && status < 300 || status === 304 ) {
 
                                // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
                                if ( s.ifModified ) {
@@ -379,91 +397,124 @@ jQuery.extend({
                                        }
                                }
 
-                               if ( s.ifModified && statusText === "notmodified" ) {
+                               // If not modified
+                               if ( status === 304 ) {
 
-                                       success = null;
+                                       // Set the statusText accordingly
+                                       statusText = "notmodified";
+                                       // Mark as a success
                                        isSuccess = 1;
 
+                               // If we have data
                                } else {
+
+                                       // Set the statusText accordingly
+                                       statusText = "success";
+
                                        // Chain data conversions and determine the final value
                                        // (if an exception is thrown in the process, it'll be notified as an error)
                                        try {
 
                                                var i,
+                                                       // Current dataType
                                                        current,
+                                                       // Previous dataType
                                                        prev,
-                                                       checker,
+                                                       // Conversion function
                                                        conv,
+                                                       // Conversion functions (when text is used in-between)
                                                        conv1,
                                                        conv2,
-                                                       convertion,
+                                                       // Local references to dataTypes & converters
                                                        dataTypes = s.dataTypes,
                                                        converters = s.converters,
+                                                       // DataType to responseXXX field mapping
                                                        responses = {
                                                                "xml": "XML",
                                                                "text": "Text"
                                                        };
 
+                                               // For each dataType in the chain
                                                for( i = 0 ; i < dataTypes.length ; i++ ) {
 
                                                        current = dataTypes[ i ];
 
+                                                       // If a responseXXX field for this dataType exists
+                                                       // and if it hasn't been set yet
                                                        if ( responses[ current ] ) {
+                                                               // Set it
                                                                jXHR[ "response" + responses[ current ] ] = response;
+                                                               // Mark it as set
                                                                responses[ current ] = 0;
                                                        }
 
+                                                       // If this is not the first element
                                                        if ( i ) {
 
+                                                               // Get the dataType to convert from
                                                                prev = dataTypes[ i - 1 ];
 
+                                                               // If no catch-all and dataTypes are actually different
                                                                if ( prev !== "*" && current !== "*" && prev !== current ) {
 
-                                                                       conv = converters[ ( conversion = prev + " " + current ) ] ||
+                                                                       // Get the converter
+                                                                       conv = converters[ prev + " " + current ] ||
                                                                                converters[ "* " + current ];
 
                                                                        conv1 = conv2 = 0;
 
+                                                                       // If there is no direct converter and none of the dataTypes is text
                                                                        if ( ! conv && prev !== "text" && current !== "text" ) {
+                                                                               // Try with text in-between
                                                                                conv1 = converters[ prev + " text" ] || converters[ "* text" ];
                                                                                conv2 = converters[ "text " + current ];
+                                                                               // Revert back to a single converter
+                                                                               // if one of the converter is an equivalence
                                                                                if ( conv1 === true ) {
                                                                                        conv = conv2;
                                                                                } else if ( conv2 === true ) {
                                                                                        conv = conv1;
                                                                                }
                                                                        }
-
+                                                                       // If we found no converter, dispatch an error
                                                                        if ( ! ( conv || conv1 && conv2 ) ) {
                                                                                throw conversion;
                                                                        }
-
+                                                                       // If found converter is not an equivalence
                                                                        if ( conv !== true ) {
+                                                                               // Convert with 1 or 2 converters accordingly
                                                                                response = conv ? conv( response ) : conv2( conv1( response ) );
                                                                        }
                                                                }
+                                                       // If it is the first element of the chain
+                                                       // and we have a dataFilter
                                                        } else if ( s.dataFilter ) {
-
-                                                               response = s.dataFilter( response );
+                                                               // Apply the dataFilter
+                                                               response = s.dataFilter( response , current );
+                                                               // Get dataTypes again in case the filter changed them
                                                                dataTypes = s.dataTypes;
                                                        }
                                                }
+                                               // End of loop
 
                                                // We have a real success
                                                success = response;
                                                isSuccess = 1;
 
+                                       // If an exception was thrown
                                        } catch(e) {
 
+                                               // We have a parsererror
                                                statusText = "parsererror";
                                                error = "" + e;
 
                                        }
                                }
 
-                       } else { // if not success, mark it as an error
+                       // if not success, mark it as an error
+                       } else {
 
-                                       error = error || statusText;
+                                       error = statusText = statusText || "error";
 
                                        // Set responseText if needed
                                        if ( response ) {
@@ -482,6 +533,9 @@ jQuery.extend({
                                deferred.fireReject( callbackContext , [ jXHR , statusText , error ] );
                        }
 
+                       // Status-dependent callbacks
+                       jXHR.statusCode( statusCode );
+
                        if ( s.global ) {
                                globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ) ,
                                                [ jXHR , s , isSuccess ? success : error ] );
@@ -505,23 +559,37 @@ jQuery.extend({
                jXHR.error = jXHR.fail;
                jXHR.complete = completeDeferred.done;
 
+               // Status-dependent callbacks
+               jXHR.statusCode = function( map ) {
+                       if ( map ) {
+                               var resolved = jXHR.isResolved(),
+                                       tmp;
+                               if ( resolved || jXHR.isRejected() ) {
+                                       tmp = map[ jXHR.status ];
+                                       if ( tmp ) {
+                                               if ( map === statusCode ) {
+                                                       delete statusCode[ jXHR.status ];
+                                               }
+                                               jXHR[ resolved ? "done" : "fail" ]( tmp );
+                                       }
+                               } else {
+                                       for( tmp in map ) {
+                                               statusCode[ tmp ] = [ statusCode[ tmp ] , map[ tmp ] ];
+                                       }
+                               }
+                       }
+                       return this;
+               };
+
                // Remove hash character (#7531: and string promotion)
                s.url = ( "" + s.url ).replace( rhash , "" );
 
-               // Uppercase the type
-               s.type = s.type.toUpperCase();
-
-               // Determine if request has content
-               s.hasContent = ! rnoContent.test( s.type );
-
                // Extract dataTypes list
                s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( /\s+/ );
 
                // Determine if a cross-domain request is in order
-               var parts = rurl.exec( s.url.toLowerCase() ),
-                       loc = location;
-
                if ( ! s.crossDomain ) {
+                       parts = rurl.exec( s.url.toLowerCase() );
                        s.crossDomain = !!(
                                        parts &&
                                        ( parts[ 1 ] && parts[ 1 ] != loc.protocol ||
@@ -531,88 +599,97 @@ jQuery.extend({
                }
 
                // Convert data if not already a string
-               if ( s.data && s.processData && typeof s.data != "string" ) {
+               if ( s.data && s.processData && typeof s.data !== "string" ) {
                        s.data = jQuery.param( s.data , s.traditional );
                }
 
-               // Get transport
-               transport = jQuery.ajax.prefilter( s , options ).transport( s );
+               // Apply prefilters
+               jQuery.ajaxPrefilter( s , options );
+
+               // Uppercase the type
+               s.type = s.type.toUpperCase();
+
+               // Determine if request has content
+               s.hasContent = ! rnoContent.test( s.type );
 
                // Watch for a new set of requests
                if ( s.global && jQuery.active++ === 0 ) {
                        jQuery.event.trigger( "ajaxStart" );
                }
 
-               // If no transport, we auto-abort
-               if ( ! transport ) {
+               // More options handling for requests with no content
+               if ( ! s.hasContent ) {
 
-                       done( 0 , "transport not found" );
-                       jXHR = false;
-
-               } else {
+                       // If data is available, append data to url
+                       if ( s.data ) {
+                               s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
+                       }
 
-                       // More options handling for requests with no content
-                       if ( ! s.hasContent ) {
+                       // Add anti-cache in url if needed
+                       if ( s.cache === false ) {
 
-                               // If data is available, append data to url
-                               if ( s.data ) {
-                                       s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
-                               }
+                               var ts = jQuery.now(),
+                                       // try replacing _= if it is there
+                                       ret = s.url.replace( rts , "$1_=" + ts );
 
-                               // Add anti-cache in url if needed
-                               if ( s.cache === false ) {
+                               // if nothing was replaced, add timestamp to the end
+                               s.url = ret + ( (ret == s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "");
+                       }
+               }
 
-                                       var ts = jQuery.now(),
-                                               // try replacing _= if it is there
-                                               ret = s.url.replace( rts , "$1_=" + ts );
+               // Set the correct header, if data is being sent
+               if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+                       requestHeaders[ "content-type" ] = s.contentType;
+               }
 
-                                       // if nothing was replaced, add timestamp to the end
-                                       s.url = ret + ( (ret == s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "");
-                               }
+               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+               if ( s.ifModified ) {
+                       if ( jQuery_lastModified[ s.url ] ) {
+                               requestHeaders[ "if-modified-since" ] = jQuery_lastModified[ s.url ];
                        }
-
-                       // Set the correct header, if data is being sent
-                       if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
-                               requestHeaders[ "content-type" ] = s.contentType;
+                       if ( jQuery_etag[ s.url ] ) {
+                               requestHeaders[ "if-none-match" ] = jQuery_etag[ s.url ];
                        }
+               }
 
-                       // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-                       if ( s.ifModified ) {
-                               if ( jQuery_lastModified[ s.url ] ) {
-                                       requestHeaders[ "if-modified-since" ] = jQuery_lastModified[ s.url ];
-                               }
-                               if ( jQuery_etag[ s.url ] ) {
-                                       requestHeaders[ "if-none-match" ] = jQuery_etag[ s.url ];
-                               }
-                       }
+               // Set the Accepts header for the server, depending on the dataType
+               requestHeaders.accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
+                       s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
+                       s.accepts[ "*" ];
+
+               // Check for headers option
+               for ( i in s.headers ) {
+                       requestHeaders[ i.toLowerCase() ] = s.headers[ i ];
+               }
 
-                       // Set the Accepts header for the server, depending on the dataType
-                       requestHeaders.accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
-                               s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
-                               s.accepts[ "*" ];
+               // Allow custom headers/mimetypes and early abort
+               if ( s.beforeSend && ( s.beforeSend.call( callbackContext , jXHR , s ) === false || state === 2 ) ) {
 
-                       // Check for headers option
-                       for ( i in s.headers ) {
-                               requestHeaders[ i.toLowerCase() ] = s.headers[ i ];
+                               // Abort if not done already
+                               done( 0 , "abort" );
+
+                               // Return false
+                               jXHR = false;
+
+               } else {
+
+                       // Install callbacks on deferreds
+                       for ( i in { success:1, error:1, complete:1 } ) {
+                               jXHR[ i ]( s[ i ] );
                        }
 
-                       // Allow custom headers/mimetypes and early abort
-                       if ( s.beforeSend && ( s.beforeSend.call( callbackContext , jXHR , s ) === false || state === 2 ) ) {
+                       // Get transport
+                       transport = jQuery.ajaxTransport( s );
 
-                                       // Abort if not done already
-                                       done( 0 , "abort" );
-                                       jXHR = false;
+                       // If no transport, we auto-abort
+                       if ( ! transport ) {
+
+                               done( 0 , "notransport" );
 
                        } else {
 
                                // Set state as sending
-                               state = 1;
-                               jXHR.readyState = 1;
-
-                               // Install callbacks on deferreds
-                               for ( i in { success:1, error:1, complete:1 } ) {
-                                       jXHR[ i ]( s[ i ] );
-                               }
+                               state = jXHR.readyState = 1;
 
                                // Send global event
                                if ( s.global ) {
@@ -786,7 +863,7 @@ function ajax_selectOrExecute( structure , s ) {
                }
        }
 
-       return noSelect ? jQuery.ajax : selected;
+       return noSelect ? jQuery : selected;
 }
 
 // Add an element to one of the structures in ajaxSettings
@@ -845,13 +922,13 @@ function ajax_addElement( structure , args ) {
                }
        }
 
-       return jQuery.ajax;
+       return jQuery;
 }
 
 // Install prefilter & transport methods
-jQuery.each( [ "prefilter" , "transport" ] , function( _ , name ) {
-       _ = name + "s";
-       jQuery.ajax[ name ] = function() {
+jQuery.each( [ "Prefilter" , "Transport" ] , function( _ , name ) {
+       _ = name.toLowerCase() + "s";
+       jQuery[ "ajax" + name ] = function() {
                return ajax_addElement( _ , arguments );
        };
 } );
index f4b324e..883876f 100644 (file)
@@ -1,8 +1,7 @@
 (function( jQuery ) {
 
 var jsc = jQuery.now(),
-       jsre = /\=(?:\?|%3F)(&|$)/i,
-       rquery_jsonp = /\?/;
+       jsre = /(\=)(?:\?|%3F)(&|$)|()(?:\?\?|%3F%3F)()/i;
 
 // Default jsonp settings
 jQuery.ajaxSetup({
@@ -10,75 +9,78 @@ jQuery.ajaxSetup({
        jsonpCallback: function() {
                return "jsonp" + jsc++;
        }
-});
 
-// Normalize jsonp queries
-// 1) put callback parameter in url or data
-// 2) sneakily ensure transportDataType is always jsonp for jsonp requests
-jQuery.ajax.prefilter("json jsonp", function(s, originalSettings) {
+// Detect, normalize options and install callbacks for jsonp requests
+// (dataIsString is used internally)
+}).ajaxPrefilter("json jsonp", function(s, originalSettings, dataIsString) {
+
+       dataIsString = ( typeof(s.data) === "string" );
 
        if ( s.dataTypes[ 0 ] === "jsonp" ||
-               originalSettings.jsonp ||
                originalSettings.jsonpCallback ||
-               jsre.test(s.url) ||
-               typeof(s.data) === "string" && jsre.test(s.data) ) {
+               originalSettings.jsonp != null ||
+               s.jsonp !== false && ( jsre.test( s.url ) ||
+                               dataIsString && jsre.test( s.data ) ) ) {
 
-               var jsonpCallback = s.jsonpCallback =
+               var responseContainer,
+                       jsonpCallback = s.jsonpCallback =
                                jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
-                       url = s.url.replace(jsre, "=" + jsonpCallback + "$1"),
-                       data = s.url === url && typeof(s.data) === "string" ? s.data.replace(jsre, "=" + jsonpCallback + "$1") : s.data;
-
-               if ( url === s.url && data === s.data ) {
-                       url += (rquery_jsonp.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
+                       previous = window[ jsonpCallback ],
+                       url = s.url,
+                       data = s.data,
+                       replace = "$1" + jsonpCallback + "$2";
+
+               if ( s.jsonp !== false ) {
+                       url = url.replace( jsre, replace );
+                       if ( s.url === url ) {
+                               if ( dataIsString ) {
+                                       data = data.replace( jsre, replace );
+                               }
+                               if ( s.data === data ) {
+                                       // Add callback manually
+                                       url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
+                               }
+                       }
                }
 
                s.url = url;
                s.data = data;
-               s.dataTypes[ 0 ] = "jsonp";
-       }
-
-// Bind transport to jsonp dataType
-}).transport("jsonp", function(s) {
 
-       // Put callback in place
-       var responseContainer,
-               jsonpCallback = s.jsonpCallback,
-               previous = window[ jsonpCallback ];
+               window [ jsonpCallback ] = function( response ) {
+                       responseContainer = [response];
+               };
 
-       window [ jsonpCallback ] = function( response ) {
-               responseContainer = [response];
-       };
+               s.complete = [function() {
 
-       s.complete = [function() {
+                       // Set callback back to previous value
+                       window[ jsonpCallback ] = previous;
 
-               // Set callback back to previous value
-               window[ jsonpCallback ] = previous;
-
-               // Call if it was a function and we have a response
-               if ( previous) {
-                       if ( responseContainer && jQuery.isFunction ( previous ) ) {
-                               window[ jsonpCallback ] ( responseContainer[0] );
+                       // Call if it was a function and we have a response
+                       if ( previous) {
+                               if ( responseContainer && jQuery.isFunction ( previous ) ) {
+                                       window[ jsonpCallback ] ( responseContainer[0] );
+                               }
+                       } else {
+                               // else, more memory leak avoidance
+                               try{ delete window[ jsonpCallback ]; } catch(e){}
                        }
-               } else {
-                       // else, more memory leak avoidance
-                       try{ delete window[ jsonpCallback ]; } catch(e){}
-               }
 
-       }, s.complete ];
+               }, s.complete ];
 
-       // Sneakily ensure this will be handled as json
-       s.dataTypes[ 0 ] = "json";
+               // Use data converter to retrieve json after script execution
+               s.converters["script json"] = function() {
+                       if ( ! responseContainer ) {
+                               jQuery.error( jsonpCallback + " was not called" );
+                       }
+                       return responseContainer[ 0 ];
+               };
 
-       // Use data converter to retrieve json after script execution
-       s.converters["script json"] = function() {
-               if ( ! responseContainer ) {
-                       jQuery.error( jsonpCallback + " was not called" );
-               }
-               return responseContainer[ 0 ];
-       };
+               // force json dataType
+               s.dataTypes[ 0 ] = "json";
 
-       // Delegate to script transport
-       return "script";
+               // Delegate to script
+               return "script";
+       }
 });
 
 })( jQuery );
index 0db0de6..b0e576f 100644 (file)
@@ -1,7 +1,7 @@
 (function( jQuery ) {
 
-// Install text to script executor
-jQuery.extend( true, jQuery.ajaxSettings , {
+// Install script dataType
+jQuery.ajaxSetup({
 
        accepts: {
                script: "text/javascript, application/javascript"
@@ -14,20 +14,24 @@ jQuery.extend( true, jQuery.ajaxSettings , {
        converters: {
                "text script": jQuery.globalEval
        }
-} );
 
-// Bind script tag hack transport
-jQuery.ajax.transport("script", function(s) {
+// Handle cache's special case and global
+}).ajaxPrefilter("script", function(s) {
 
-       // Handle cache special case
        if ( s.cache === undefined ) {
                s.cache = false;
        }
 
-       // This transport only deals with cross domain get requests
-       if ( s.crossDomain && s.async && ( s.type === "GET" || ! s.data ) ) {
-
+       if ( s.crossDomain ) {
+               s.type = "GET";
                s.global = false;
+       }
+
+// Bind script tag hack transport
+}).ajaxTransport("script", function(s) {
+
+       // This transport only deals with cross domain requests
+       if ( s.crossDomain ) {
 
                var script,
                        head = document.getElementsByTagName("head")[0] || document.documentElement;
@@ -47,7 +51,7 @@ jQuery.ajax.transport("script", function(s) {
                                script.src = s.url;
 
                                // Attach handlers for all browsers
-                               script.onload = script.onreadystatechange = function( _ , statusText) {
+                               script.onload = script.onreadystatechange = function( _ , isAbort ) {
 
                                        if ( ! script.readyState || /loaded|complete/.test( script.readyState ) ) {
 
@@ -59,10 +63,13 @@ jQuery.ajax.transport("script", function(s) {
                                                        head.removeChild( script );
                                                }
 
+                                               // Dereference the script
                                                script = 0;
 
-                                               // Callback
-                                               callback( statusText ? 0 : 200, statusText || "success" );
+                                               // Callback if not abort
+                                               if ( ! isAbort ) {
+                                                       callback( 200, "success" );
+                                               }
                                        }
                                };
                                // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
@@ -70,9 +77,9 @@ jQuery.ajax.transport("script", function(s) {
                                head.insertBefore( script, head.firstChild );
                        },
 
-                       abort: function(statusText) {
+                       abort: function() {
                                if ( script ) {
-                                       script.onload( 0 , statusText );
+                                       script.onload(0,1);
                                }
                        }
                };
index 26e91ce..34aa832 100644 (file)
@@ -1,19 +1,16 @@
 (function( jQuery ) {
 
-var // Next fake timer id
-       xhrPollingId = jQuery.now(),
+var // Next active xhr id
+       xhrId = jQuery.now(),
 
-       // Callbacks hashtable
+       // active xhrs
        xhrs = {},
 
-       // XHR pool
-       xhrPool = [],
+       // #5280: see below
+       xhrUnloadAbortInstalled;
 
-       // #5280: see end of file
-       xhrUnloadAbortMarker;
 
-
-jQuery.ajax.transport( function( s , determineDataType ) {
+jQuery.ajaxTransport( function( s , determineDataType ) {
 
        // Cross domain only allowed if supported through XMLHttpRequest
        if ( ! s.crossDomain || jQuery.support.cors ) {
@@ -25,26 +22,24 @@ jQuery.ajax.transport( function( s , determineDataType ) {
                        send: function(headers, complete) {
 
                                // #5280: we need to abort on unload or IE will keep connections alive
-                               if ( ! xhrUnloadAbortMarker ) {
+                               if ( ! xhrUnloadAbortInstalled ) {
 
-                                       xhrUnloadAbortMarker = [];
+                                       xhrUnloadAbortInstalled = 1;
 
                                        jQuery(window).bind( "unload" , function() {
 
                                                // Abort all pending requests
                                                jQuery.each(xhrs, function(_, xhr) {
                                                        if ( xhr.onreadystatechange ) {
-                                                               xhr.onreadystatechange( xhrUnloadAbortMarker );
+                                                               xhr.onreadystatechange( 1 );
                                                        }
                                                });
 
-                                               // Reset polling structure to be safe
-                                               xhrs = {};
-
                                        });
                                }
 
-                               var xhr = xhrPool.pop() || s.xhr(),
+                               // Get a new xhr
+                               var xhr = s.xhr(),
                                        handle;
 
                                // Open the socket
@@ -58,7 +53,7 @@ jQuery.ajax.transport( function( s , determineDataType ) {
                                // Requested-With header
                                // Not set for crossDomain requests with no content
                                // (see why at http://trac.dojotoolkit.org/ticket/9486)
-                               // Won't change header if already provided in beforeSend
+                               // Won't change header if already provided
                                if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
                                        headers["x-requested-with"] = "XMLHttpRequest";
                                }
@@ -76,49 +71,40 @@ jQuery.ajax.transport( function( s , determineDataType ) {
                                try {
                                        xhr.send( ( s.hasContent && s.data ) || null );
                                } catch(e) {
-                                       // Store back in pool
-                                       xhrPool.push( xhr );
                                        complete(0, "error", "" + e);
                                        return;
                                }
 
                                // Listener
-                               callback = function ( abortStatusText ) {
+                               callback = function( _ , isAbort ) {
 
                                        // Was never called and is aborted or complete
-                                       if ( callback && ( abortStatusText || xhr.readyState === 4 ) ) {
+                                       if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+                                               // Only called once
+                                               callback = 0;
 
-                                               // Do not listen anymore
-                                               // and Store back in pool
+                                               // Do not keep as active anymore
+                                               // and store back into pool
                                                if (handle) {
                                                        xhr.onreadystatechange = jQuery.noop;
                                                        delete xhrs[ handle ];
-                                                       handle = undefined;
-                                                       xhrPool.push( xhr );
                                                }
 
-                                               callback = 0;
-
-                                               // Get info
-                                               var status, statusText, response, responseHeaders;
-
-                                               if ( abortStatusText ) {
+                                               // If it's an abort
+                                               if ( isAbort ) {
 
+                                                       // Abort it manually if needed
                                                        if ( xhr.readyState !== 4 ) {
                                                                xhr.abort();
                                                        }
-
-                                                       // Stop here if unloadAbort
-                                                       if ( abortStatusText === xhrUnloadAbortMarker ) {
-                                                               return;
-                                                       }
-
-                                                       status = 0;
-                                                       statusText = abortStatusText;
-
                                                } else {
 
-                                                       status = xhr.status;
+                                                       // Get info
+                                                       var status = xhr.status,
+                                                               statusText,
+                                                               response,
+                                                               responseHeaders = xhr.getAllResponseHeaders();
 
                                                        try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
 
@@ -130,8 +116,6 @@ jQuery.ajax.transport( function( s , determineDataType ) {
 
                                                        }
 
-                                                       responseHeaders = xhr.getAllResponseHeaders();
-
                                                        // Filter status for non standard behaviours
                                                        // (so many they seem to be the actual "standard")
                                                        status =
@@ -164,10 +148,10 @@ jQuery.ajax.transport( function( s , determineDataType ) {
                                                                        xhr.getResponseHeader("content-type"),
                                                                        xhr.responseText,
                                                                        xhr.responseXML );
-                                               }
 
-                                               // Call complete
-                                               complete(status,statusText,response,responseHeaders);
+                                                       // Call complete
+                                                       complete(status,statusText,response,responseHeaders);
+                                               }
                                        }
                                };
 
@@ -180,18 +164,16 @@ jQuery.ajax.transport( function( s , determineDataType ) {
 
                                } else {
 
-                                       // Listener is externalized to handle abort on unload
-                                       handle = xhrPollingId++;
+                                       // Add to list of active xhrs
+                                       handle = xhrId++;
                                        xhrs[ handle ] = xhr;
-                                       xhr.onreadystatechange = function() {
-                                               callback();
-                                       };
+                                       xhr.onreadystatechange = callback;
                                }
                        },
 
-                       abort: function(statusText) {
+                       abort: function() {
                                if ( callback ) {
-                                       callback(statusText);
+                                       callback(0,1);
                                }
                        }
                };
index b9e6d81..fbf6491 100644 (file)
@@ -3,7 +3,7 @@ var jQuery = (function() {
 // Define a local copy of jQuery
 var jQuery = function( selector, context ) {
                // The jQuery object is actually just the init constructor 'enhanced'
-               return new jQuery.fn.init( selector, context );
+               return new jQuery.fn.init( selector, context, rootjQuery );
        },
 
        // Map over jQuery in case of overwrite
@@ -63,6 +63,9 @@ var jQuery = function( selector, context ) {
        // The deferred used on DOM ready
        readyList,
 
+       // Promise methods
+       promiseMethods = "then done fail isResolved isRejected promise".split( " " ),
+
        // The ready event handler
        DOMContentLoaded,
 
@@ -78,7 +81,8 @@ var jQuery = function( selector, context ) {
        class2type = {};
 
 jQuery.fn = jQuery.prototype = {
-       init: function( selector, context ) {
+       constructor: jQuery,
+       init: function( selector, context, rootjQuery ) {
                var match, elem, ret, doc;
 
                // Handle $(""), $(null), or $(undefined)
@@ -112,6 +116,7 @@ jQuery.fn = jQuery.prototype = {
 
                                // HANDLE: $(html) -> $(array)
                                if ( match[1] ) {
+                                       context = context instanceof jQuery ? context[0] : context;
                                        doc = (context ? context.ownerDocument || context : document);
 
                                        // If a single string is passed in and it's a single tag
@@ -129,7 +134,7 @@ jQuery.fn = jQuery.prototype = {
 
                                        } else {
                                                ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
-                                               selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+                                               selector = (ret.cacheable ? jQuery(ret.fragment).clone()[0] : ret.fragment).childNodes;
                                        }
 
                                        return jQuery.merge( this, selector );
@@ -171,7 +176,7 @@ jQuery.fn = jQuery.prototype = {
                        // HANDLE: $(expr, context)
                        // (which is just equivalent to: $(context).find(expr)
                        } else {
-                               return jQuery( context ).find( selector );
+                               return this.constructor( context ).find( selector );
                        }
 
                // HANDLE: $(function)
@@ -222,7 +227,7 @@ jQuery.fn = jQuery.prototype = {
        // (returning the new matched element set)
        pushStack: function( elems, name, selector ) {
                // Build a new jQuery matched element set
-               var ret = jQuery();
+               var ret = this.constructor();
 
                if ( jQuery.isArray( elems ) ) {
                        push.apply( ret, elems );
@@ -287,7 +292,7 @@ jQuery.fn = jQuery.prototype = {
        },
 
        end: function() {
-               return this.prevObject || jQuery(null);
+               return this.prevObject || this.constructor(null);
        },
 
        // For internal use only.
@@ -896,9 +901,10 @@ jQuery.extend({
        Deferred: function( func ) {
 
                var deferred = jQuery._Deferred(),
-                       failDeferred = jQuery._Deferred();
+                       failDeferred = jQuery._Deferred(),
+                       promise;
 
-               // Add errorDeferred methods and redefine cancel
+               // Add errorDeferred methods, then and promise
                jQuery.extend( deferred , {
 
                        then: function( doneCallbacks , failCallbacks ) {
@@ -911,14 +917,18 @@ jQuery.extend({
                        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;
-                               };
+                       // (i is used internally)
+                       promise: function( obj , i ) {
+                               if ( obj == null ) {
+                                       if ( promise ) {
+                                               return promise;
+                                       }
+                                       promise = obj = {};
+                               }
+                               i = promiseMethods.length;
+                               while( i-- ) {
+                                       obj[ promiseMethods[ i ] ] = deferred[ promiseMethods[ i ] ];
+                               }
                                return obj;
                        }
 
@@ -940,10 +950,32 @@ jQuery.extend({
 
        // Deferred helper
        when: function( object ) {
-               object = object && jQuery.isFunction( object.promise ) ?
-                       object :
-                       jQuery.Deferred().resolve( object );
-               return object.promise();
+               var args = arguments,
+                       length = args.length,
+                       deferred = length <= 1 && object && jQuery.isFunction( object.promise ) ?
+                               object :
+                               jQuery.Deferred(),
+                       promise = deferred.promise(),
+                       resolveArray;
+
+               if ( length > 1 ) {
+                       resolveArray = new Array( length );
+                       jQuery.each( args, function( index, element, args ) {
+                               jQuery.when( element ).done( function( value ) {
+                                       args = arguments;
+                                       resolveArray[ index ] = args.length > 1 ? slice.call( args , 0 ) : value;
+                                       if( ! --length ) {
+                                               deferred.fire( promise, resolveArray );
+                                       }
+                               }).fail( function() {
+                                       deferred.fireReject( promise, arguments );
+                               });
+                               return !deferred.isRejected();
+                       });
+               } else if ( deferred !== object ) {
+                       deferred.resolve( object );
+               }
+               return promise;
        },
 
        // Use of jQuery.browser is frowned upon.
@@ -960,6 +992,25 @@ jQuery.extend({
                return { browser: match[1] || "", version: match[2] || "0" };
        },
 
+       subclass: function(){
+               function jQuerySubclass( selector, context ) {
+                       return new jQuerySubclass.fn.init( selector, context );
+               }
+               jQuerySubclass.superclass = this;
+               jQuerySubclass.fn = jQuerySubclass.prototype = this();
+               jQuerySubclass.fn.constructor = jQuerySubclass;
+               jQuerySubclass.subclass = this.subclass;
+               jQuerySubclass.fn.init = function init( selector, context ) {
+                       if (context && context instanceof jQuery && !(context instanceof jQuerySubclass)){
+                               context = jQuerySubclass(context);
+                       }
+                       return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass );
+               };
+               jQuerySubclass.fn.init.prototype = jQuerySubclass.fn;
+               var rootjQuerySubclass = jQuerySubclass(document);
+               return jQuerySubclass;
+       },
+
        browser: {}
 });
 
index 8a83c60..19c6342 100644 (file)
@@ -263,8 +263,9 @@ if ( document.defaultView && document.defaultView.getComputedStyle ) {
 
 if ( document.documentElement.currentStyle ) {
        currentStyle = function( elem, name ) {
-               var left, rsLeft,
+               var left, 
                        ret = elem.currentStyle && elem.currentStyle[ name ],
+                       rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
                        style = elem.style;
 
                // From the awesome hack by Dean Edwards
@@ -275,16 +276,19 @@ if ( document.documentElement.currentStyle ) {
                if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
                        // Remember the original values
                        left = style.left;
-                       rsLeft = elem.runtimeStyle.left;
 
                        // Put in the new values to get a computed value out
-                       elem.runtimeStyle.left = elem.currentStyle.left;
+                       if ( rsLeft ) {
+                               elem.runtimeStyle.left = elem.currentStyle.left;
+                       }
                        style.left = name === "fontSize" ? "1em" : (ret || 0);
                        ret = style.pixelLeft + "px";
 
                        // Revert the changed values
                        style.left = left;
-                       elem.runtimeStyle.left = rsLeft;
+                       if ( rsLeft ) {
+                               elem.runtimeStyle.left = rsLeft;
+                       }
                }
 
                return ret === "" ? "auto" : ret;
index 7fa5488..2ddf288 100644 (file)
@@ -607,7 +607,7 @@ jQuery.Event = function( src ) {
 
                // Events bubbling up the document may have been marked as prevented
                // by a handler lower down the tree; reflect the correct value.
-               this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
+               this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || 
                        src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
 
        // Event type
index 206476c..596a457 100644 (file)
@@ -427,15 +427,29 @@ function cloneFixAttributes(src, dest) {
        if ( nodeName === "object" ) {
                dest.outerHTML = src.outerHTML;
 
-       // IE6-8 fails to persist the checked state of a cloned checkbox
-       // or radio button
-       } else if ( nodeName === "input" && src.checked ) {
-               dest.defaultChecked = dest.checked = src.checked;
+       } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
+               // IE6-8 fails to persist the checked state of a cloned checkbox
+               // or radio button. Worse, IE6-7 fail to give the cloned element
+               // a checked appearance if the defaultChecked value isn't also set
+               if ( src.checked ) {
+                       dest.defaultChecked = dest.checked = src.checked;
+               }
+
+               // IE6-7 get confused and end up setting the value of a cloned
+               // checkbox/radio button to an empty string instead of "on"
+               if ( dest.value !== src.value ) {
+                       dest.value = src.value;
+               }
 
        // IE6-8 fails to return the selected option to the default selected
        // state when cloning options
        } else if ( nodeName === "option" ) {
                dest.selected = src.defaultSelected;
+
+       // IE6-8 fails to set the defaultValue to the correct value when
+       // cloning other types of input fields
+       } else if ( nodeName === "input" || nodeName === "textarea" ) {
+               dest.defaultValue = src.defaultValue;
        }
 
        // Event data gets referenced instead of copied if the expando
@@ -624,6 +638,11 @@ jQuery.extend({
                                                        jQuery.removeEvent( elem, type, data.handle );
                                                }
                                        }
+
+                                       // Null the DOM reference to avoid IE6/7/8 leak (#7054)
+                                       if ( data.handle ) {
+                                               data.handle.elem = null;
+                                       }
                                }
 
                                if ( deleteExpando ) {
index 689e901..b36ce3d 100644 (file)
@@ -6,7 +6,14 @@ var runtil = /Until$/,
        rmultiselector = /,/,
        isSimple = /^.[^:#\[\.,]*$/,
        slice = Array.prototype.slice,
-       POS = jQuery.expr.match.POS;
+       POS = jQuery.expr.match.POS,
+       // methods guaranteed to produce a unique set when starting from a unique set
+       guaranteedUnique = {
+               children: true,
+               contents: true,
+               next: true,
+               prev: true
+       };
 
 jQuery.fn.extend({
        find: function( selector ) {
@@ -196,7 +203,8 @@ jQuery.each({
        }
 }, function( name, fn ) {
        jQuery.fn[ name ] = function( until, selector ) {
-               var ret = jQuery.map( this, fn, until );
+               var ret = jQuery.map( this, fn, until ),
+        args = slice.call(arguments);
 
                if ( !runtil.test( name ) ) {
                        selector = until;
@@ -206,13 +214,13 @@ jQuery.each({
                        ret = jQuery.filter( selector, ret );
                }
 
-               ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+               ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
 
                if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
                        ret = ret.reverse();
                }
 
-               return this.pushStack( ret, name, slice.call(arguments).join(",") );
+               return this.pushStack( ret, name, args.join(",") );
        };
 });
 
index 9ae1d84..6c13d72 100644 (file)
@@ -1,6 +1,10 @@
 <?php
 error_reporting(0);
 $callback = $_REQUEST['callback'];
+if ( ! $callback ) {
+       $callback = explode("?",end(explode("/",$_SERVER['REQUEST_URI'])));
+       $callback = $callback[0];
+}
 $json = $_REQUEST['json'];
 if($json) {
        echo $callback . '([ {"name": "John", "age": 21}, {"name": "Peter", "age": 25 } ])';
index d29eddb..3f672ae 100644 (file)
@@ -276,7 +276,7 @@ test(".ajax() - retry with jQuery.ajax( this )", function() {
                                start();
                        }
                }
-       })
+       });
 
 });
 
@@ -316,6 +316,28 @@ test(".ajax() - headers" , function() {
 
 });
 
+test(".ajax() - Accept header" , function() {
+
+       expect( 1 );
+
+       stop();
+
+       jQuery.ajax(url("data/headers.php?keys=accept"), {
+               headers: {
+                       Accept: "very wrong accept value"
+               },
+               beforeSend: function( xhr ) {
+                       xhr.setRequestHeader( "Accept", "*/*" );
+               },
+               success: function( data ) {
+                       strictEqual( data , "accept: */*\n" , "Test Accept header is set to last value provided" );
+                       start();
+               },
+               error: function(){ ok(false, "error"); }
+       });
+
+});
+
 test(".ajax() - contentType" , function() {
 
        expect( 2 );
@@ -1025,6 +1047,18 @@ test("load(String, Function) - check file with only a script tag", function() {
        });
 });
 
+test("load(String, Function) - dataFilter in ajaxSettings", function() {
+       expect(2);
+       stop();
+       jQuery.ajaxSetup({ dataFilter: function() { return "Hello World"; } });
+       var div = jQuery("<div/>").load(url("data/name.html"), function(responseText) {
+               strictEqual( div.html(), "Hello World" , "Test div was filled with filtered data" );
+               strictEqual( responseText, "Hello World" , "Test callback receives filtered data" );
+               jQuery.ajaxSetup({ dataFilter: 0 });
+               start();
+       });
+});
+
 test("load(String, Object, Function)", function() {
        expect(2);
        stop();
@@ -1080,233 +1114,249 @@ test("jQuery.getScript(String, Function) - no callback", function() {
        });
 });
 
-test("jQuery.ajax() - JSONP, Local", function() {
-       expect(10);
-
-       var count = 0;
-       function plus(){ if ( ++count == 9 ) start(); }
-
-       stop();
-
-       jQuery.ajax({
-               url: "data/jsonp.php",
-               dataType: "jsonp",
-               success: function(data){
-                       ok( data.data, "JSON results returned (GET, no callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (GET, no callback)" );
-                       plus();
-               }
-       });
+jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label ) {
 
-       jQuery.ajax({
-               url: "data/jsonp.php?callback=?",
-               dataType: "jsonp",
-               success: function(data){
-                       ok( data.data, "JSON results returned (GET, url callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (GET, url callback)" );
-                       plus();
-               }
-       });
+       test("jQuery.ajax() - JSONP, " + label, function() {
+               expect(17);
 
-       jQuery.ajax({
-               url: "data/jsonp.php",
-               dataType: "jsonp",
-               data: "callback=?",
-               success: function(data){
-                       ok( data.data, "JSON results returned (GET, data callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (GET, data callback)" );
-                       plus();
-               }
-       });
+               var count = 0;
+               function plus(){ if ( ++count == 17 ) start(); }
 
-       jQuery.ajax({
-               url: "data/jsonp.php",
-               dataType: "jsonp",
-               data: {
-                       callback: "?"
-               },
-               success: function(data){
-                       ok( data.data, "JSON results returned (GET, processed data callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (GET, processed data callback)" );
-                       plus();
-               }
-       });
+               stop();
 
-       jQuery.ajax({
-               url: "data/jsonp.php",
-               dataType: "jsonp",
-               jsonp: "callback",
-               success: function(data){
-                       ok( data.data, "JSON results returned (GET, data obj callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (GET, data obj callback)" );
-                       plus();
-               }
-       });
+               jQuery.ajax({
+                       url: "data/jsonp.php",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       success: function(data){
+                               ok( data.data, "JSON results returned (GET, no callback)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, no callback)" );
+                               plus();
+                       }
+               });
 
-       jQuery.ajax({
-               url: "data/jsonp.php",
-               dataType: "jsonp",
-               jsonpCallback: "jsonpResults",
-               success: function(data){
-                       ok( data.data, "JSON results returned (GET, custom callback name)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (GET, custom callback name)" );
-                       plus();
-               }
-       });
+               jQuery.ajax({
+                       url: "data/jsonp.php?callback=?",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       success: function(data){
+                               ok( data.data, "JSON results returned (GET, url callback)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, url callback)" );
+                               plus();
+                       }
+               });
 
-       jQuery.ajax({
-               type: "POST",
-               url: "data/jsonp.php",
-               dataType: "jsonp",
-               success: function(data){
-                       ok( data.data, "JSON results returned (POST, no callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (GET, data obj callback)" );
-                       plus();
-               }
-       });
+               jQuery.ajax({
+                       url: "data/jsonp.php",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       data: "callback=?",
+                       success: function(data){
+                               ok( data.data, "JSON results returned (GET, data callback)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, data callback)" );
+                               plus();
+                       }
+               });
 
-       jQuery.ajax({
-               type: "POST",
-               url: "data/jsonp.php",
-               data: "callback=?",
-               dataType: "jsonp",
-               success: function(data){
-                       ok( data.data, "JSON results returned (POST, data callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (POST, data callback)" );
-                       plus();
-               }
-       });
+               jQuery.ajax({
+                       url: "data/jsonp.php?callback=??",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       success: function(data){
+                               ok( data.data, "JSON results returned (GET, url context-free callback)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, url context-free callback)" );
+                               plus();
+                       }
+               });
 
-       jQuery.ajax({
-               type: "POST",
-               url: "data/jsonp.php",
-               jsonp: "callback",
-               dataType: "jsonp",
-               success: function(data){
-                       ok( data.data, "JSON results returned (POST, data obj callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (POST, data obj callback)" );
-                       plus();
-               }
-       });
+               jQuery.ajax({
+                       url: "data/jsonp.php",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       data: "callback=??",
+                       success: function(data){
+                               ok( data.data, "JSON results returned (GET, data context-free callback)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, data context-free callback)" );
+                               plus();
+                       }
+               });
 
-       //#7578
-       jQuery.ajax({
-               url: "data/jsonp.php",
-               dataType: "jsonp",
-               beforeSend: function(){
-                       strictEqual( this.cache, false, "cache must be false on JSON request" );
-                       plus();
-                       return false;
-               }
-       });
-});
+               jQuery.ajax({
+                       url: "data/jsonp.php/??",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       success: function(data){
+                               ok( data.data, "JSON results returned (GET, REST-like)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, REST-like)" );
+                               plus();
+                       }
+               });
 
-test("jQuery.ajax() - JSONP - Custom JSONP Callback", function() {
-       expect(1);
-       stop();
+               jQuery.ajax({
+                       url: "data/jsonp.php/???json=1",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       success: function(data){
+                               strictEqual( jQuery.type(data), "array", "JSON results returned (GET, REST-like with param)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, REST-like with param)" );
+                               plus();
+                       }
+               });
 
-       window.jsonpResults = function(data) {
-               ok( data.data, "JSON results returned (GET, custom callback function)" );
-               window.jsonpResults = undefined;
-               start();
-       };
+               jQuery.ajax({
+                       url: "data/jsonp.php",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       data: {
+                               callback: "?"
+                       },
+                       success: function(data){
+                               ok( data.data, "JSON results returned (GET, processed data callback)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, processed data callback)" );
+                               plus();
+                       }
+               });
 
-       jQuery.ajax({
-               url: "data/jsonp.php",
-               dataType: "jsonp",
-               jsonpCallback: "jsonpResults"
-       });
-});
+               jQuery.ajax({
+                       url: "data/jsonp.php",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       jsonp: "callback",
+                       success: function(data){
+                               ok( data.data, "JSON results returned (GET, data obj callback)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, data obj callback)" );
+                               plus();
+                       }
+               });
 
-test("jQuery.ajax() - JSONP, Remote", function() {
-       expect(4);
+               window.jsonpResults = function(data) {
+                       ok( data.data, "JSON results returned (GET, custom callback function)" );
+                       window.jsonpResults = undefined;
+                       plus();
+               };
 
-       var count = 0;
-       function plus(){ if ( ++count == 4 ) start(); }
+               jQuery.ajax({
+                       url: "data/jsonp.php",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       jsonpCallback: "jsonpResults",
+                       success: function(data){
+                               ok( data.data, "JSON results returned (GET, custom callback name)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, custom callback name)" );
+                               plus();
+                       }
+               });
 
-       var base = window.location.href.replace(/[^\/]*$/, "");
+               jQuery.ajax({
+                       type: "POST",
+                       url: "data/jsonp.php",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       success: function(data){
+                               ok( data.data, "JSON results returned (POST, no callback)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, data obj callback)" );
+                               plus();
+                       }
+               });
 
-       stop();
+               jQuery.ajax({
+                       type: "POST",
+                       url: "data/jsonp.php",
+                       data: "callback=?",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       success: function(data){
+                               ok( data.data, "JSON results returned (POST, data callback)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (POST, data callback)" );
+                               plus();
+                       }
+               });
 
-       jQuery.ajax({
-               url: base + "data/jsonp.php",
-               dataType: "jsonp",
-               success: function(data){
-                       ok( data.data, "JSON results returned (GET, no callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (GET, no callback)" );
-                       plus();
-               }
-       });
+               jQuery.ajax({
+                       type: "POST",
+                       url: "data/jsonp.php",
+                       jsonp: "callback",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       success: function(data){
+                               ok( data.data, "JSON results returned (POST, data obj callback)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (POST, data obj callback)" );
+                               plus();
+                       }
+               });
 
-       jQuery.ajax({
-               url: base + "data/jsonp.php?callback=?",
-               dataType: "jsonp",
-               success: function(data){
-                       ok( data.data, "JSON results returned (GET, url callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (GET, url callback)" );
-                       plus();
-               }
-       });
+               //#7578
+               jQuery.ajax({
+                       url: "data/jsonp.php",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       beforeSend: function(){
+                               strictEqual( this.cache, false, "cache must be false on JSON request" );
+                               plus();
+                               return false;
+                       }
+               });
 
-       jQuery.ajax({
-               url: base + "data/jsonp.php",
-               dataType: "jsonp",
-               data: "callback=?",
-               success: function(data){
-                       ok( data.data, "JSON results returned (GET, data callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (GET, data callback)" );
-                       plus();
-               }
-       });
+               jQuery.ajax({
+                       url: "data/jsonp.php?callback=XXX",
+                       dataType: "jsonp",
+                       jsonp: false,
+                       jsonpCallback: "XXX",
+                       crossDomain: crossDomain,
+                       beforeSend: function() {
+                               ok( /^data\/jsonp.php\?callback=XXX&_=\d+$/.test( this.url ) ,
+                                       "The URL wasn't messed with (GET, custom callback name with no url manipulation)" );
+                               plus();
+                       },
+                       success: function(data){
+                               ok( data.data, "JSON results returned (GET, custom callback name with no url manipulation)" );
+                               plus();
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, custom callback name with no url manipulation)" );
+                               plus();
+                       }
+               });
 
-       jQuery.ajax({
-               url: base + "data/jsonp.php",
-               dataType: "jsonp",
-               jsonp: "callback",
-               success: function(data){
-                       ok( data.data, "JSON results returned (GET, data obj callback)" );
-                       plus();
-               },
-               error: function(data){
-                       ok( false, "Ajax error JSON (GET, data obj callback)" );
-                       plus();
-               }
        });
 });
 
@@ -1778,25 +1828,19 @@ test("jQuery ajax - failing cross-domain", function() {
 
        var i = 2;
 
-       if ( jQuery.ajax({
+       jQuery.ajax({
                url: 'http://somewebsitethatdoesnotexist-67864863574657654.com',
                success: function(){ ok( false , "success" ); },
                error: function(xhr,_,e){ ok( true , "file not found: " + xhr.status + " => " + e ); },
                complete: function() { if ( ! --i ) start(); }
-       }) === false ) {
-               ok( true , "no transport" );
-               if ( ! --i ) start();
-       }
+       });
 
-       if ( jQuery.ajax({
+       jQuery.ajax({
                url: 'http://www.google.com',
                success: function(){ ok( false , "success" ); },
                error: function(xhr,_,e){ ok( true , "access denied: " + xhr.status + " => " + e ); },
                complete: function() { if ( ! --i ) start(); }
-       }) === false ) {
-               ok( true , "no transport" );
-               if ( ! --i ) start();
-       }
+       });
 
 });
 
@@ -1828,6 +1872,76 @@ test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
        ok( success, "document.location did not generate exception" );
 });
 
+test( "jQuery.ajax - statusCode" , function() {
+
+       var count = 10;
+
+       expect( 16 );
+       stop();
+
+       function countComplete() {
+               if ( ! --count ) {
+                       start();
+               }
+       }
+
+       function createStatusCodes( name , isSuccess ) {
+               name = "Test " + name + " " + ( isSuccess ? "success" : "error" );
+               return {
+                       200: function() {
+                               ok( isSuccess , name );
+                       },
+                       404: function() {
+                               ok( ! isSuccess , name );
+                       }
+               };
+       }
+
+       jQuery.each( {
+               "data/name.html": true,
+               "data/someFileThatDoesNotExist.html": false
+       } , function( uri , isSuccess ) {
+
+               jQuery.ajax( url( uri ) , {
+                       statusCode: createStatusCodes( "in options" , isSuccess ),
+                       complete: countComplete
+               });
+
+               jQuery.ajax( url( uri ) , {
+                       complete: countComplete
+               }).statusCode( createStatusCodes( "immediately with method" , isSuccess ) );
+
+               jQuery.ajax( url( uri ) , {
+                       complete: function(jXHR) {
+                               jXHR.statusCode( createStatusCodes( "on complete" , isSuccess ) );
+                               countComplete();
+                       }
+               });
+
+               jQuery.ajax( url( uri ) , {
+                       complete: function(jXHR) {
+                               setTimeout( function() {
+                                       jXHR.statusCode( createStatusCodes( "very late binding" , isSuccess ) );
+                                       countComplete();
+                               } , 100 );
+                       }
+               });
+
+               jQuery.ajax( url( uri ) , {
+                       statusCode: createStatusCodes( "all (options)" , isSuccess ),
+                       complete: function(jXHR) {
+                               jXHR.statusCode( createStatusCodes( "all (on complete)" , isSuccess ) );
+                               setTimeout( function() {
+                                       jXHR.statusCode( createStatusCodes( "all (very late binding)" , isSuccess ) );
+                                       countComplete();
+                               } , 100 );
+                       }
+               }).statusCode( createStatusCodes( "all (immediately with method)" , isSuccess ) );
+
+       });
+
+});
+
 }
 
 //}
\ No newline at end of file
index 6231b1d..8e57edf 100644 (file)
@@ -12,7 +12,7 @@ test("Basic requirements", function() {
 });
 
 test("jQuery()", function() {
-       expect(23);
+       expect(24);
 
        // Basic constructor's behavior
 
@@ -21,7 +21,7 @@ test("jQuery()", function() {
        equals( jQuery(null).length, 0, "jQuery(null) === jQuery([])" );
        equals( jQuery("").length, 0, "jQuery('') === jQuery([])" );
 
-       var obj = jQuery("div")
+       var obj = jQuery("div");
        equals( jQuery(obj).selector, "div", "jQuery(jQueryObj) == jQueryObj" );
 
                // can actually yield more than one, when iframes are included, the window is an array as well
@@ -87,6 +87,14 @@ test("jQuery()", function() {
 
        // manually clean up detached elements
        elem.remove();
+
+       for ( var i = 0; i < 3; ++i ) {
+               elem = jQuery("<input type='text' value='TEST' />");
+       }
+       equals( elem[0].defaultValue, "TEST", "Ensure cached nodes are cloned properly (Bug #6655)" );
+
+       // manually clean up detached elements
+       elem.remove();
 });
 
 test("selector state", function() {
@@ -1001,7 +1009,7 @@ test("jQuery._Deferred()", function() {
 
 test("jQuery.Deferred()", function() {
 
-       expect( 4 );
+       expect( 10 );
 
        jQuery.Deferred( function( defer ) {
                strictEqual( this , defer , "Defer passed as this & first argument" );
@@ -1021,11 +1029,35 @@ test("jQuery.Deferred()", function() {
        }, function() {
                ok( true , "Error on reject" );
        });
+
+       ( new jQuery.Deferred( function( defer ) {
+               strictEqual( this , defer , "Defer passed as this & first argument (new)" );
+               this.resolve( "done" );
+       }) ).then( function( value ) {
+               strictEqual( value , "done" , "Passed function executed (new)" );
+       });
+
+       ( new jQuery.Deferred() ).resolve().then( function() {
+               ok( true , "Success on resolve (new)" );
+       }, function() {
+               ok( false , "Error on resolve (new)" );
+       });
+
+       ( new jQuery.Deferred() ).reject().then( function() {
+               ok( false , "Success on reject (new)" );
+       }, function() {
+               ok( true , "Error on reject (new)" );
+       });
+
+       var tmp = jQuery.Deferred();
+
+       strictEqual( tmp.promise() , tmp.promise() , "Test deferred always return same promise" );
+       strictEqual( tmp.promise() , tmp.promise().promise() , "Test deferred's promise always return same promise as deferred" );
 });
 
 test("jQuery.when()", function() {
 
-       expect( 21 );
+       expect( 23 );
 
        // Some other objects
        jQuery.each( {
@@ -1048,6 +1080,10 @@ test("jQuery.when()", function() {
 
        } );
 
+       ok( jQuery.isFunction( jQuery.when().then( function( resolveValue ) {
+               strictEqual( resolveValue , undefined , "Test the promise was resolved with no parameter" );
+       } ).promise ) , "Test calling when with no parameter triggers the creation of a new Promise" );
+
        var cache, i;
 
        for( i = 1 ; i < 4 ; i++ ) {
@@ -1061,3 +1097,106 @@ test("jQuery.when()", function() {
                });
        }
 });
+
+test("jQuery.when() - joined", function() {
+
+       expect(8);
+
+       jQuery.when( 1, 2, 3 ).done( function( a, b, c ) {
+               strictEqual( a , 1 , "Test first param is first resolved value - non-observables" );
+               strictEqual( b , 2 , "Test second param is second resolved value - non-observables" );
+               strictEqual( c , 3 , "Test third param is third resolved value - non-observables" );
+       }).fail( function() {
+               ok( false , "Test the created deferred was resolved - non-observables");
+       });
+
+       var successDeferred = jQuery.Deferred().resolve( 1 , 2 , 3 ),
+               errorDeferred = jQuery.Deferred().reject( "error" , "errorParam" );
+
+       jQuery.when( 1 , successDeferred , 3 ).done( function( a, b, c ) {
+               strictEqual( a , 1 , "Test first param is first resolved value - resolved observable" );
+               same( b , [ 1 , 2 , 3 ] , "Test second param is second resolved value - resolved observable" );
+               strictEqual( c , 3 , "Test third param is third resolved value - resolved observable" );
+       }).fail( function() {
+               ok( false , "Test the created deferred was resolved - resolved observable");
+       });
+
+       jQuery.when( 1 , errorDeferred , 3 ).done( function() {
+               ok( false , "Test the created deferred was rejected - rejected observable");
+       }).fail( function( error , errorParam ) {
+               strictEqual( error , "error" , "Test first param is first rejected value - rejected observable" );
+               strictEqual( errorParam , "errorParam" , "Test second param is second rejected value - rejected observable" );
+       });
+});
+
+test("jQuery.subclass", function(){
+       expect(378);
+
+       var Subclass = jQuery.subclass(),
+                       SubclassSubclass = Subclass.subclass(),
+                       jQueryDocument = jQuery(document),
+                       selectors, contexts, methods, method, arg, description;
+
+       jQueryDocument.toString = function(){ return 'jQueryDocument'; };
+
+       Subclass.fn.subclassMethod = function(){};
+       SubclassSubclass.fn.subclassSubclassMethod = function(){};
+
+       selectors = [
+               'body',
+               'html, body',
+               '<div></div>'
+       ];
+
+       methods = [ // all methods that return a new jQuery instance
+               ['eq', 1],
+               ['add', document],
+               ['end'],
+               ['has'],
+               ['closest', 'div'],
+               ['filter', document],
+               ['find', 'div']
+       ];
+
+       contexts = [undefined, document, jQueryDocument];
+
+       jQuery.each(selectors, function(i, selector){
+
+               jQuery.each(methods, function(){
+                       method = this[0];
+                       arg = this[1];
+
+                       jQuery.each(contexts, function(i, context){
+
+                               description = '("'+selector+'", '+context+').'+method+'('+(arg||'')+')';
+
+                               same(
+                                       jQuery(selector, context)[method](arg).subclassMethod, undefined,
+                                       'jQuery'+description+' doesnt have Subclass methods'
+                               );
+                               same(
+                                       jQuery(selector, context)[method](arg).subclassSubclassMethod, undefined,
+                                       'jQuery'+description+' doesnt have SubclassSubclass methods'
+                               );
+                               same(
+                                       Subclass(selector, context)[method](arg).subclassMethod, Subclass.fn.subclassMethod,
+                                       'Subclass'+description+' has Subclass methods'
+                               );
+                               same(
+                                       Subclass(selector, context)[method](arg).subclassSubclassMethod, undefined,
+                                       'Subclass'+description+' doesnt have SubclassSubclass methods'
+                               );
+                               same(
+                                       SubclassSubclass(selector, context)[method](arg).subclassMethod, Subclass.fn.subclassMethod,
+                                       'SubclassSubclass'+description+' has Subclass methods'
+                               );
+                               same(
+                                       SubclassSubclass(selector, context)[method](arg).subclassSubclassMethod, SubclassSubclass.fn.subclassSubclassMethod,
+                                       'SubclassSubclass'+description+' has SubclassSubclass methods'
+                               );
+
+                       });
+               });
+       });
+
+});
index 0637071..1b25987 100644 (file)
@@ -320,3 +320,25 @@ test(":visible selector works properly on children with a hidden parent (bug #45
        jQuery('#table').css('display', 'none').html('<tr><td>cell</td><td>cell</td></tr>');
        equals(jQuery('#table td:visible').length, 0, "hidden cell children not perceived as visible");
 });
+
+test("internal ref to elem.runtimeStyle (bug #7608)", function () {
+       expect(1);
+
+       var result = true,
+       val = 10;
+       
+       jQuery('<div id="bug7608" style="width:200px;border:solid 1px red;">' +
+    '<div  id="test" style="width:0%; background:#000;">&nbsp;</div></div>').appendTo("#main");
+
+       try {
+               // the bug is located within src/css.js
+               jQuery("#bug7608 #test").animate( { width: val }, 1000);
+
+       } catch (e) {
+               result = false;
+       }
+
+       ok( result, "elem.runtimeStyle does not throw exception" );
+  
+       jQuery("#bug7608").remove();
+});
index a6d8cb6..02824a9 100644 (file)
@@ -304,15 +304,15 @@ test("live/delegate immediate propagation", function() {
        $p.undelegate( "click" );
 });
 
-test("bind/delegate bubbling, isDefaultPrevented (Bug #7793)", function() {
+test("bind/delegate bubbling, isDefaultPrevented", function() {
        expect(2);
        var $anchor2 = jQuery( "#anchor2" ),
                $main = jQuery( "#main" ),
                fakeClick = function($jq) {
                        // Use a native click so we don't get jQuery simulated bubbling
                        if ( document.createEvent ) {
-                               var e = document.createEvent( "MouseEvents" );
-                               e.initEvent( "click", true, true );
+                               var e = document.createEvent( 'MouseEvents' );
+                               e.initEvent( "click", true, true ); 
                                $jq[0].dispatchEvent(e);
                        }
                        else if ( $jq[0].click ) {
@@ -323,7 +323,15 @@ test("bind/delegate bubbling, isDefaultPrevented (Bug #7793)", function() {
                e.preventDefault();
        });
        $main.delegate("#foo", "click", function(e) {
-               equals( e.isDefaultPrevented(), true, "isDefaultPrevented true passed to bubbled event" );
+               var orig = e.originalEvent;
+
+               if ( typeof(orig.defaultPrevented) === "boolean" || typeof(orig.returnValue) === "boolean" || orig.getPreventDefault ) {
+                       equals( e.isDefaultPrevented(), true, "isDefaultPrevented true passed to bubbled event" );
+
+               } else {
+                       // Opera < 11 doesn't implement any interface we can use, so give it a pass
+                       ok( true, "isDefaultPrevented not supported by this browser, test skipped" );
+               }
        });
        fakeClick( $anchor2 );
        $anchor2.unbind( "click" );
index de84144..37234d8 100644 (file)
@@ -402,7 +402,7 @@ test("append(Function) with incoming value", function() {
 });
 
 test("append the same fragment with events (Bug #6997, 5566)", function () {
-       expect(4 + (document.fireEvent ? 1 : 0));
+       expect(2 + (document.fireEvent ? 1 : 0));
        stop(1000);
 
        var element;
@@ -437,14 +437,6 @@ test("append the same fragment with events (Bug #6997, 5566)", function () {
 
        jQuery("#listWithTabIndex li").before(element);
        jQuery("#listWithTabIndex li.test6997").eq(1).click();
-
-       element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>");
-
-       equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" );
-
-       element = jQuery("<input type='checkbox'>").attr('checked', 'checked');
-
-       equals( element.clone().is(":checked"), element.is(":checked"), "Checked input cloned correctly" );
 });
 
 test("appendTo(String|Element|Array&lt;Element&gt;|jQuery)", function() {
@@ -976,6 +968,28 @@ test("clone()", function() {
        equal( jQuery("body").clone().children()[0].id, "qunit-header", "Make sure cloning body works" );
 });
 
+test("clone(form element) (Bug #3879, #6655)", function() {
+       expect(6);
+       element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>");
+
+       equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" );
+
+       element = jQuery("<input type='checkbox' value='foo'>").attr('checked', 'checked');
+       clone = element.clone();
+
+       equals( clone.is(":checked"), element.is(":checked"), "Checked input cloned correctly" );
+       equals( clone[0].defaultValue, "foo", "Checked input defaultValue cloned correctly" );
+       equals( clone[0].defaultChecked, !jQuery.support.noCloneEvent, "Checked input defaultChecked cloned correctly" );
+
+       element = jQuery("<input type='text' value='foo'>");
+       clone = element.clone();
+       equals( clone[0].defaultValue, "foo", "Text input defaultValue cloned correctly" );
+
+       element = jQuery("<textarea>foo</textarea>");
+       clone = element.clone();
+       equals( clone[0].defaultValue, "foo", "Textarea defaultValue cloned correctly" );
+});
+
 if (!isLocal) {
 test("clone() on XML nodes", function() {
        expect(2);
index 7810cd6..574f968 100644 (file)
@@ -1 +1 @@
-1.4.5pre
\ No newline at end of file
+1.5pre
\ No newline at end of file