rselectTextarea = /^(?:select|textarea)/i,
rts = /([?&])_=[^&]*/,
rurl = /^(\w+:)?\/\/([^\/?#:]+)(?::(\d+))?/,
+ rCRLF = /\r?\n/g,
// Slice function
sliceFunc = Array.prototype.slice,
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] );
}
}
});
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();
}
});
},
ajaxSetup: function( settings ) {
- jQuery.extend( jQuery.ajaxSettings, settings );
+ jQuery.extend( true, jQuery.ajaxSettings, settings );
+ return this;
},
ajaxSettings: {
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();
// Deferreds
deferred = jQuery.Deferred(),
completeDeferred = jQuery._Deferred(),
+ // Status-dependent callbacks
+ statusCode = s.statusCode || {},
// Headers (they are sent all at once)
requestHeaders = {},
// Response headers
transport,
// timeout handle
timeoutTimer,
+ // Cross-domain detection vars
+ loc = document.location,
+ parts,
// The jXHR state
state = 0,
// Loop variable
// (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;
}
};
// 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;
// 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 ) {
}
}
- 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 ) {
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 ] );
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 ||
}
// 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 ) {
}
}
- return noSelect ? jQuery.ajax : selected;
+ return noSelect ? jQuery : selected;
}
// Add an element to one of the structures in ajaxSettings
}
}
- 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 );
};
} );
(function( jQuery ) {
var jsc = jQuery.now(),
- jsre = /\=(?:\?|%3F)(&|$)/i,
- rquery_jsonp = /\?/;
+ jsre = /(\=)(?:\?|%3F)(&|$)|()(?:\?\?|%3F%3F)()/i;
// Default jsonp settings
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 );
(function( jQuery ) {
-// Install text to script executor
-jQuery.extend( true, jQuery.ajaxSettings , {
+// Install script dataType
+jQuery.ajaxSetup({
accepts: {
script: "text/javascript, application/javascript"
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;
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 ) ) {
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.
head.insertBefore( script, head.firstChild );
},
- abort: function(statusText) {
+ abort: function() {
if ( script ) {
- script.onload( 0 , statusText );
+ script.onload(0,1);
}
}
};
(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 ) {
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
// 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";
}
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
}
- responseHeaders = xhr.getAllResponseHeaders();
-
// Filter status for non standard behaviours
// (so many they seem to be the actual "standard")
status =
xhr.getResponseHeader("content-type"),
xhr.responseText,
xhr.responseXML );
- }
- // Call complete
- complete(status,statusText,response,responseHeaders);
+ // Call complete
+ complete(status,statusText,response,responseHeaders);
+ }
}
};
} 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);
}
}
};
// 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
// The deferred used on DOM ready
readyList,
+ // Promise methods
+ promiseMethods = "then done fail isResolved isRejected promise".split( " " ),
+
// The ready event handler
DOMContentLoaded,
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)
// 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
} 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 );
// 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)
// (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 );
},
end: function() {
- return this.prevObject || jQuery(null);
+ return this.prevObject || this.constructor(null);
},
// For internal use only.
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 ) {
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;
}
// 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.
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: {}
});
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
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;
// 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
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
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 ) {
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 ) {
}
}, 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;
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(",") );
};
});
<?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 } ])';
start();
}
}
- })
+ });
});
});
+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 );
});
});
+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();
});
});
-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();
- }
});
});
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();
- }
+ });
});
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
});
test("jQuery()", function() {
- expect(23);
+ expect(24);
// Basic constructor's behavior
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
// 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() {
test("jQuery.Deferred()", function() {
- expect( 4 );
+ expect( 10 );
jQuery.Deferred( function( defer ) {
strictEqual( this , defer , "Defer passed as this & first argument" );
}, 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( {
} );
+ 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++ ) {
});
}
});
+
+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'
+ );
+
+ });
+ });
+ });
+
+});
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;"> </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();
+});
$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 ) {
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" );
});
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;
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<Element>|jQuery)", 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);
-1.4.5pre
\ No newline at end of file
+1.5pre
\ No newline at end of file