aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorscottjehl <scott@scottjehl.com>2011-01-13 14:14:04 -0500
committerscottjehl <scott@scottjehl.com>2011-01-13 14:14:04 -0500
commit610ab137da38106f8c464f099a304ae3795c2231 (patch)
treee55254f034702e0213c51e062a3d4aba5291f4e9 /src
parent18fa1fd9da12fd6a259b422f91b663d9fbdb181e (diff)
parenta8fa5f2ec1030bceb9a65d0237f0c92ae4e014dd (diff)
downloadjquery-610ab137da38106f8c464f099a304ae3795c2231.tar.gz
jquery-610ab137da38106f8c464f099a304ae3795c2231.zip
Merge branch 'master' of https://github.com/jquery/jquery
Diffstat (limited to 'src')
-rw-r--r--src/ajax.js826
-rw-r--r--src/ajax/jsonp.js83
-rw-r--r--src/ajax/script.js (renamed from src/transports/script.js)63
-rw-r--r--src/ajax/xhr.js (renamed from src/transports/xhr.js)182
-rw-r--r--src/attributes.js2
-rw-r--r--src/core.js268
-rw-r--r--src/css.js17
-rw-r--r--src/data.js15
-rw-r--r--src/dimensions.js2
-rw-r--r--src/effects.js4
-rw-r--r--src/event.js75
-rw-r--r--src/intro.js2
-rw-r--r--src/manipulation.js49
-rw-r--r--src/offset.js10
-rw-r--r--src/support.js2
-rw-r--r--src/transports/jsonp.js89
-rw-r--r--src/traversing.js14
-rw-r--r--src/xhr.js909
18 files changed, 1220 insertions, 1392 deletions
diff --git a/src/ajax.js b/src/ajax.js
index da130faed..645163ad2 100644
--- a/src/ajax.js
+++ b/src/ajax.js
@@ -1,11 +1,20 @@
(function( jQuery ) {
-
-var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
- rselectTextarea = /^(?:select|textarea)/i,
- rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+
+var r20 = /%20/g,
rbracket = /\[\]$/,
+ rhash = /#.*$/,
+ rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL
+ rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+ rnoContent = /^(?:GET|HEAD)$/,
rquery = /\?/,
- r20 = /%20/g,
+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+ rselectTextarea = /^(?:select|textarea)/i,
+ rts = /([?&])_=[^&]*/,
+ rurl = /^(\w+:)?\/\/([^\/?#:]+)(?::(\d+))?/,
+ rCRLF = /\r?\n/g,
+
+ // Slice function
+ sliceFunc = Array.prototype.slice,
// Keep a copy of the old load method
_load = jQuery.fn.load;
@@ -43,35 +52,43 @@ jQuery.fn.extend({
type = "POST";
}
}
-
+
var self = this;
-
+
// Request the remote document
jQuery.ajax({
url: url,
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] );
}
}
});
@@ -99,9 +116,9 @@ jQuery.fn.extend({
null :
jQuery.isArray(val) ?
jQuery.map( val, function(val, i){
- return {name: elem.name, value: val};
+ return { name: elem.name, value: val.replace(rCRLF, "\r\n") };
}) :
- {name: elem.name, value: val};
+ { name: elem.name, value: val.replace(rCRLF, "\r\n") };
}).get();
}
});
@@ -113,9 +130,8 @@ jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".sp
};
});
-jQuery.extend({
-
- get: function( url, data, callback, type ) {
+jQuery.each( [ "get", "post" ], function( i, method ) {
+ jQuery[ method ] = function( url, data, callback, type ) {
// shift arguments if data argument was omited
if ( jQuery.isFunction( data ) ) {
type = type || callback;
@@ -124,13 +140,16 @@ jQuery.extend({
}
return jQuery.ajax({
- type: "GET",
+ type: method,
url: url,
data: data,
success: callback,
dataType: type
});
- },
+ };
+});
+
+jQuery.extend({
getScript: function( url, callback ) {
return jQuery.get(url, null, callback, "script");
@@ -140,25 +159,9 @@ jQuery.extend({
return jQuery.get(url, data, callback, "json");
},
- post: function( url, data, callback, type ) {
- // shift arguments if data argument was omited
- if ( jQuery.isFunction( data ) ) {
- type = type || callback;
- callback = data;
- data = {};
- }
-
- return jQuery.ajax({
- type: "POST",
- url: url,
- data: data,
- success: callback,
- dataType: type
- });
- },
-
ajaxSetup: function( settings ) {
- jQuery.extend( jQuery.ajaxSettings, settings );
+ jQuery.extend( true, jQuery.ajaxSettings, settings );
+ return this;
},
ajaxSettings: {
@@ -181,12 +184,7 @@ jQuery.extend({
xhr: function() {
return new window.XMLHttpRequest();
},
- xhrResponseFields: {
- xml: "XML",
- text: "Text",
- json: "JSON"
- },
-
+
accepts: {
xml: "application/xml, text/xml",
html: "text/html",
@@ -194,97 +192,523 @@ jQuery.extend({
json: "application/json, text/javascript",
"*": "*/*"
},
-
- autoDataType: {
+
+ contents: {
xml: /xml/,
html: /html/,
json: /json/
},
-
+
// Prefilters
// 1) They are useful to introduce custom dataTypes (see transport/jsonp for an example)
// 2) These are called:
// * BEFORE asking for a transport
// * AFTER param serialization (s.data is a string if s.processData is true)
- // 3) They MUST be order agnostic
- prefilters: [],
-
+ // 3) key is the dataType
+ // 4) the catchall symbol "*" can be used
+ // 5) execution will start with transport dataType and THEN continue down to "*" if needed
+ prefilters: {},
+
// Transports bindings
// 1) key is the dataType
// 2) the catchall symbol "*" can be used
// 3) selection will start with transport dataType and THEN go to "*" if needed
- transports: {
- },
-
- // Checkers
- // 1) key is dataType
- // 2) they are called to control successful response
- // 3) error throws is used as error data
- dataCheckers: {
-
- // Check if data is a string
- "text": function(data) {
- if ( typeof data != "string" ) {
- jQuery.error("typeerror");
- }
- },
-
- // Check if xml has been properly parsed
- "xml": function(data) {
- var documentElement = data ? data.documentElement : data;
- if ( ! documentElement || ! documentElement.nodeName ) {
- jQuery.error("typeerror");
- }
- if ( documentElement.nodeName == "parsererror" ) {
- jQuery.error("parsererror");
- }
- }
- },
-
+ transports: {},
+
// List of data converters
- // 1) key format is "source_type => destination_type" (spaces required)
+ // 1) key format is "source_type destination_type" (a single space in-between)
// 2) the catchall symbol "*" can be used for source_type
- dataConverters: {
-
+ converters: {
+
// Convert anything to text
- "* => text": function(data) {
- return "" + data;
- },
-
- // Text to html (no transformation)
- "text => html": function(data) {
- return data;
- },
-
+ "* text": window.String,
+
+ // Text to html (true = no transformation)
+ "text html": true,
+
// Evaluate text as a json expression
- "text => json": jQuery.parseJSON,
-
+ "text json": jQuery.parseJSON,
+
// Parse text as xml
- "text => xml": function(data) {
- var xml, parser;
- if ( window.DOMParser ) { // Standard
- parser = new DOMParser();
- xml = parser.parseFromString(data,"text/xml");
- } else { // IE
- xml = new ActiveXObject("Microsoft.XMLDOM");
- xml.async="false";
- xml.loadXML(data);
- }
- return xml;
- }
+ "text xml": jQuery.parseXML
}
},
// Main method
- ajax: function( url , s ) {
-
+ // (s is used internally)
+ ajax: function( url , options , s ) {
+
+ // Handle varargs
if ( arguments.length === 1 ) {
- s = url;
- url = s ? s.url : undefined;
+ options = url;
+ url = options ? options.url : undefined;
+ }
+
+ // Force options to be an object
+ options = options || {};
+
+ // Get the url if provided separately
+ options.url = url || options.url;
+
+ // Create the final options object
+ s = jQuery.extend( true , {} , jQuery.ajaxSettings , options );
+
+ // We force the original context
+ // (plain objects used as context get extended)
+ s.context = options.context;
+
+ var // jQuery lists
+ jQuery_lastModified = jQuery.lastModified,
+ jQuery_etag = jQuery.etag,
+ // Callbacks contexts
+ callbackContext = s.context || s,
+ globalEventContext = s.context ? jQuery( s.context ) : jQuery.event,
+ // Deferreds
+ deferred = jQuery.Deferred(),
+ completeDeferred = jQuery._Deferred(),
+ // Status-dependent callbacks
+ statusCode = s.statusCode || {},
+ // Headers (they are sent all at once)
+ requestHeaders = {},
+ // Response headers
+ responseHeadersString,
+ responseHeaders,
+ // transport
+ transport,
+ // timeout handle
+ timeoutTimer,
+ // Cross-domain detection vars
+ loc = document.location,
+ parts,
+ // The jXHR state
+ state = 0,
+ // Loop variable
+ i,
+ // Fake xhr
+ jXHR = {
+
+ readyState: 0,
+
+ // Caches the header
+ setRequestHeader: function(name,value) {
+ if ( state === 0 ) {
+ requestHeaders[ name.toLowerCase() ] = value;
+ }
+ return this;
+ },
+
+ // Raw string
+ getAllResponseHeaders: function() {
+ return state === 2 ? responseHeadersString : null;
+ },
+
+ // Builds headers hashtable if needed
+ // (match is used internally)
+ getResponseHeader: function( key , match ) {
+
+ if ( state !== 2 ) {
+ return null;
+ }
+
+ if ( responseHeaders === undefined ) {
+
+ responseHeaders = {};
+
+ if ( typeof responseHeadersString === "string" ) {
+
+ while( ( match = rheaders.exec( responseHeadersString ) ) ) {
+ responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
+ }
+ }
+ }
+ return responseHeaders[ key.toLowerCase() ];
+ },
+
+ // Cancel the request
+ abort: function( statusText ) {
+ if ( transport && state !== 2 ) {
+ transport.abort( statusText || "abort" );
+ done( 0 , statusText );
+ }
+ return this;
+ }
+ };
+
+ // Callback for when everything is done
+ // It is defined here because jslint complains if it is declared
+ // at the end of the function (which would be more logical and readable)
+ function done( status , statusText , response , headers) {
+
+ // Called once
+ if ( state === 2 ) {
+ return;
+ }
+
+ // State is "done" now
+ state = 2;
+
+ // Set readyState
+ jXHR.readyState = status ? 4 : 0;
+
+ // Cache response headers
+ responseHeadersString = headers || "";
+
+ // Clear timeout if it exists
+ if ( timeoutTimer ) {
+ clearTimeout(timeoutTimer);
+ }
+
+ var // Reference url
+ url = s.url,
+ // and ifModified status
+ ifModified = s.ifModified,
+
+ // Is it a success?
+ isSuccess = 0,
+ // Stored success
+ success,
+ // Stored error
+ error;
+
+ // If successful, handle type chaining
+ 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 ) {
+
+ var lastModified = jXHR.getResponseHeader("Last-Modified"),
+ etag = jXHR.getResponseHeader("Etag");
+
+ if (lastModified) {
+ jQuery_lastModified[ s.url ] = lastModified;
+ }
+ if (etag) {
+ jQuery_etag[ s.url ] = etag;
+ }
+ }
+
+ // If not modified
+ if ( status === 304 ) {
+
+ // 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,
+ // Conversion function
+ conv,
+ // Conversion functions (when text is used in-between)
+ conv1,
+ conv2,
+ // 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 ) {
+
+ // 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 ) {
+ // 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;
+
+ }
+ }
+
+ // if not success, mark it as an error
+ } else {
+
+ error = statusText = statusText || "error";
+
+ // Set responseText if needed
+ if ( response ) {
+ jXHR.responseText = response;
+ }
+ }
+
+ // Set data for the fake xhr object
+ jXHR.status = status;
+ jXHR.statusText = statusText;
+
+ // Success/Error
+ if ( isSuccess ) {
+ deferred.fire( callbackContext , [ success , statusText , jXHR ] );
+ } else {
+ 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 ] );
+ }
+
+ // Complete
+ completeDeferred.fire( callbackContext, [ jXHR , statusText ] );
+
+ if ( s.global ) {
+ globalEventContext.trigger( "ajaxComplete" , [ jXHR , s] );
+ // Handle the global AJAX counter
+ if ( ! --jQuery.active ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ }
+ }
+
+ // Attach deferreds
+ deferred.promise( jXHR );
+ jXHR.success = jXHR.done;
+ 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
+ if ( ! s.crossDomain ) {
+ parts = rurl.exec( s.url.toLowerCase() );
+ s.crossDomain = !!(
+ parts &&
+ ( parts[ 1 ] && parts[ 1 ] != loc.protocol ||
+ parts[ 2 ] != loc.hostname ||
+ ( parts[ 3 ] || 80 ) != ( loc.port || 80 ) )
+ );
+ }
+
+ // Convert data if not already a string
+ if ( s.data && s.processData && typeof s.data != "string" ) {
+ s.data = jQuery.param( s.data , s.traditional );
+ }
+
+ // Get transport
+ transport = jQuery.ajaxPrefilter( s , options ).ajaxTransport( s );
+
+ // 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 ) {
+
+ done( 0 , "transport not found" );
+ jXHR = false;
+
+ } else {
+
+ // More options handling for requests with no content
+ if ( ! s.hasContent ) {
+
+ // If data is available, append data to url
+ if ( s.data ) {
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
+ }
+
+ // Add anti-cache in url if needed
+ if ( s.cache === false ) {
+
+ var ts = jQuery.now(),
+ // try replacing _= if it is there
+ ret = s.url.replace( rts , "$1_=" + ts );
+
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ( (ret == s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + 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;
+ }
+
+ // 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 ];
+ }
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext , jXHR , s ) === false || state === 2 ) ) {
+
+ // Abort if not done already
+ done( 0 , "abort" );
+ jXHR = false;
+
+ } 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 ] );
+ }
+
+ // Send global event
+ if ( s.global ) {
+ globalEventContext.trigger( "ajaxSend" , [ jXHR , s ] );
+ }
+
+ // Timeout
+ if ( s.async && s.timeout > 0 ) {
+ timeoutTimer = setTimeout(function(){
+ jXHR.abort( "timeout" );
+ }, s.timeout);
+ }
+
+ // Try to send
+ try {
+ transport.send(requestHeaders, done);
+ } catch (e) {
+ // Propagate exception as error if not done
+ if ( status === 1 ) {
+
+ done(0, "error", "" + e);
+ jXHR = false;
+
+ // Simply rethrow otherwise
+ } else {
+ jQuery.error(e);
+ }
+ }
+ }
}
-
- return jQuery.xhr().open( s ? s.type : undefined , url ).send( undefined , s );
-
+
+ return jXHR;
},
// Serialize an array of form elements or a set of
@@ -296,19 +720,19 @@ jQuery.extend({
value = jQuery.isFunction(value) ? value() : value;
s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
};
-
+
// Set traditional to true for jQuery <= 1.3.2 behavior.
if ( traditional === undefined ) {
traditional = jQuery.ajaxSettings.traditional;
}
-
+
// If an array was passed in, assume that it is an array of form elements.
if ( jQuery.isArray(a) || a.jquery ) {
// Serialize the form elements
jQuery.each( a, function() {
add( this.name, this.value );
});
-
+
} else {
// If traditional, encode the "old" way (the way 1.3.2 or older
// did it), otherwise encode params recursively.
@@ -341,9 +765,11 @@ function buildParams( prefix, obj, traditional, add ) {
buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
}
});
-
+
} else if ( !traditional && obj != null && typeof obj === "object" ) {
- if ( jQuery.isEmptyObject( obj ) ) {
+ // If we see an array here, it is empty and should be treated as an empty
+ // object
+ if ( jQuery.isArray( obj ) || jQuery.isEmptyObject( obj ) ) {
add( prefix, "" );
// Serialize object item.
@@ -352,7 +778,7 @@ function buildParams( prefix, obj, traditional, add ) {
buildParams( prefix + "[" + k + "]", v, traditional, add );
});
}
-
+
} else {
// Serialize scalar item.
add( prefix, obj );
@@ -372,6 +798,172 @@ jQuery.extend({
});
+//Execute or select from functions in a given structure of options
+function ajax_selectOrExecute( structure , s ) {
+
+ var dataTypes = s.dataTypes,
+ transportDataType,
+ list,
+ selected,
+ i,
+ length,
+ checked = {},
+ flag,
+ noSelect = structure !== "transports";
+
+ function initSearch( dataType ) {
+
+ flag = transportDataType !== dataType && ! checked[ dataType ];
+
+ if ( flag ) {
+
+ checked[ dataType ] = 1;
+ transportDataType = dataType;
+ list = s[ structure ][ dataType ];
+ i = -1;
+ length = list ? list.length : 0 ;
+ }
+
+ return flag;
+ }
+
+ initSearch( dataTypes[ 0 ] );
+
+ for ( i = 0 ; ( noSelect || ! selected ) && i <= length ; i++ ) {
+
+ if ( i === length ) {
+
+ initSearch( "*" );
+
+ } else {
+
+ selected = list[ i ]( s , determineDataType );
+
+ // If we got redirected to another dataType
+ // Search there (if not in progress or already tried)
+ if ( typeof( selected ) === "string" &&
+ initSearch( selected ) ) {
+
+ dataTypes.unshift( selected );
+ selected = 0;
+ }
+ }
+ }
+
+ return noSelect ? jQuery : selected;
+}
+
+// Add an element to one of the structures in ajaxSettings
+function ajax_addElement( structure , args ) {
+
+ var i,
+ start = 0,
+ length = args.length,
+ dataTypes = [ "*" ],
+ dLength = 1,
+ dataType,
+ functors = [],
+ first,
+ append,
+ list;
+
+ if ( length ) {
+
+ first = jQuery.type( args[ 0 ] );
+
+ if ( first === "object" ) {
+ return ajax_selectOrExecute( structure , args[ 0 ] );
+ }
+
+ structure = jQuery.ajaxSettings[ structure ];
+
+ if ( first !== "function" ) {
+
+ dataTypes = args[ 0 ].toLowerCase().split(/\s+/);
+ dLength = dataTypes.length;
+ start = 1;
+
+ }
+
+ if ( dLength && start < length ) {
+
+ functors = sliceFunc.call( args , start );
+
+ for( i = 0 ; i < dLength ; i++ ) {
+
+ dataType = dataTypes[ i ];
+
+ first = /^\+/.test( dataType );
+
+ if (first) {
+ dataType = dataType.substr(1);
+ }
+
+ if ( dataType !== "" ) {
+
+ append = Array.prototype[ first ? "unshift" : "push" ];
+ list = structure[ dataType ] = structure[ dataType ] || [];
+ append.apply( list , functors );
+ }
+ }
+ }
+ }
+
+ return jQuery;
+}
+
+// Install prefilter & transport methods
+jQuery.each( [ "Prefilter" , "Transport" ] , function( _ , name ) {
+ _ = name.toLowerCase() + "s";
+ jQuery[ "ajax" + name ] = function() {
+ return ajax_addElement( _ , arguments );
+ };
+} );
+
+// Utility function that handles dataType when response is received
+// (for those transports that can give text or xml responses)
+function determineDataType( s , ct , text , xml ) {
+
+ var contents = s.contents,
+ type,
+ regexp,
+ dataTypes = s.dataTypes,
+ transportDataType = dataTypes[0],
+ response;
+
+ // Auto (xml, json, script or text determined given headers)
+ if ( transportDataType === "*" ) {
+
+ for ( type in contents ) {
+ if ( ( regexp = contents[ type ] ) && regexp.test( ct ) ) {
+ transportDataType = dataTypes[0] = type;
+ break;
+ }
+ }
+ }
+
+ // xml and parsed as such
+ if ( transportDataType === "xml" &&
+ xml &&
+ xml.documentElement /* #4958 */ ) {
+
+ response = xml;
+
+ // Text response was provided
+ } else {
+
+ response = text;
+
+ // If it's not really text, defer to converters
+ if ( transportDataType !== "text" ) {
+ dataTypes.unshift( "text" );
+ }
+
+ }
+
+ return response;
+}
+
/*
* Create the request object; Microsoft failed to properly
* implement the XMLHttpRequest in IE7 (can't request local files),
@@ -386,7 +978,7 @@ if ( window.ActiveXObject ) {
return new window.XMLHttpRequest();
} catch( xhrError ) {}
}
-
+
try {
return new window.ActiveXObject("Microsoft.XMLHTTP");
} catch( activeError ) {}
diff --git a/src/ajax/jsonp.js b/src/ajax/jsonp.js
new file mode 100644
index 000000000..1df5dd427
--- /dev/null
+++ b/src/ajax/jsonp.js
@@ -0,0 +1,83 @@
+(function( jQuery ) {
+
+var jsc = jQuery.now(),
+ jsre = /(\=)(?:\?|%3F)(&|$)|()(?:\?\?|%3F%3F)()/i,
+ rquery_jsonp = /\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+ jsonp: "callback",
+ 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
+}).ajaxPrefilter("json jsonp", function(s, originalSettings) {
+
+ if ( s.dataTypes[ 0 ] === "jsonp" ||
+ originalSettings.jsonp ||
+ originalSettings.jsonpCallback ||
+ jsre.test(s.url) ||
+ typeof(s.data) === "string" && jsre.test(s.data) ) {
+
+ var jsonpCallback = s.jsonpCallback =
+ jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
+ url = s.url.replace(jsre, "$1" + jsonpCallback + "$2"),
+ data = s.url === url && typeof(s.data) === "string" ? s.data.replace(jsre, "$1" + jsonpCallback + "$2") : s.data;
+
+ if ( url === s.url && data === s.data ) {
+ url += (rquery_jsonp.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
+ }
+
+ s.url = url;
+ s.data = data;
+ s.dataTypes[ 0 ] = "jsonp";
+ }
+
+// Bind transport to jsonp dataType
+}).ajaxTransport("jsonp", function(s) {
+
+ // Put callback in place
+ var responseContainer,
+ jsonpCallback = s.jsonpCallback,
+ previous = window[ jsonpCallback ];
+
+ window [ jsonpCallback ] = function( response ) {
+ responseContainer = [response];
+ };
+
+ s.complete = [function() {
+
+ // 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] );
+ }
+ } else {
+ // else, more memory leak avoidance
+ try{ delete window[ jsonpCallback ]; } catch(e){}
+ }
+
+ }, 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 ];
+ };
+
+ // Delegate to script transport
+ return "script";
+});
+
+})( jQuery );
diff --git a/src/transports/script.js b/src/ajax/script.js
index fe3873557..8e2e89ac5 100644
--- a/src/transports/script.js
+++ b/src/ajax/script.js
@@ -1,39 +1,38 @@
(function( jQuery ) {
-// Install text to script executor
-jQuery.extend( true, jQuery.ajaxSettings , {
+// Install script dataType
+jQuery.ajaxSetup({
accepts: {
script: "text/javascript, application/javascript"
},
-
- autoDataType: {
+
+ contents: {
script: /javascript/
},
-
- dataConverters: {
- "text => script": jQuery.globalEval
+
+ converters: {
+ "text script": jQuery.globalEval
}
-} );
// Bind script tag hack transport
-jQuery.xhr.bindTransport("script", function(s) {
-
+}).ajaxTransport("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 ) ) {
-
+
s.global = false;
-
+
var script,
head = document.getElementsByTagName("head")[0] || document.documentElement;
-
+
return {
-
+
send: function(_, callback) {
script = document.createElement("script");
@@ -43,37 +42,39 @@ jQuery.xhr.bindTransport("script", function(s) {
if ( s.scriptCharset ) {
script.charset = s.scriptCharset;
}
-
+
script.src = s.url;
-
+
// Attach handlers for all browsers
- script.onload = script.onreadystatechange = function(statusText) {
-
- if ( (!script.readyState ||
- script.readyState === "loaded" || script.readyState === "complete") ) {
-
+ script.onload = script.onreadystatechange = function( _ , isAbort ) {
+
+ if ( ! script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
// Handle memory leak in IE
script.onload = script.onreadystatechange = null;
-
+
// Remove the script
if ( head && script.parentNode ) {
head.removeChild( script );
}
-
- script = undefined;
-
- // Callback & dereference
- callback(statusText ? 0 : 200, statusText || "success");
+
+ // Dereference the script
+ script = 0;
+
+ // Callback if not abort
+ if ( ! isAbort ) {
+ callback( 200, "success" );
+ }
}
};
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378).
head.insertBefore( script, head.firstChild );
},
-
- abort: function(statusText) {
+
+ abort: function() {
if ( script ) {
- script.onload(statusText);
+ script.onload(0,1);
}
}
};
diff --git a/src/transports/xhr.js b/src/ajax/xhr.js
index 783ee4604..34aa832fe 100644
--- a/src/transports/xhr.js
+++ b/src/ajax/xhr.js
@@ -1,29 +1,47 @@
(function( jQuery ) {
-var // Next fake timer id
- xhrPollingId = jQuery.now(),
-
- // Callbacks hashtable
+var // Next active xhr id
+ xhrId = jQuery.now(),
+
+ // active xhrs
xhrs = {},
- // #5280: see end of file
- xhrUnloadAbortMarker = [];
+ // #5280: see below
+ xhrUnloadAbortInstalled;
+
+
+jQuery.ajaxTransport( function( s , determineDataType ) {
-
-jQuery.xhr.bindTransport( function( s , determineDataType ) {
-
// Cross domain only allowed if supported through XMLHttpRequest
if ( ! s.crossDomain || jQuery.support.cors ) {
-
+
var callback;
-
+
return {
-
+
send: function(headers, complete) {
-
+
+ // #5280: we need to abort on unload or IE will keep connections alive
+ if ( ! xhrUnloadAbortInstalled ) {
+
+ xhrUnloadAbortInstalled = 1;
+
+ jQuery(window).bind( "unload" , function() {
+
+ // Abort all pending requests
+ jQuery.each(xhrs, function(_, xhr) {
+ if ( xhr.onreadystatechange ) {
+ xhr.onreadystatechange( 1 );
+ }
+ });
+
+ });
+ }
+
+ // Get a new xhr
var xhr = s.xhr(),
handle;
-
+
// Open the socket
// Passing null username, generates a login popup on Opera (#2865)
if ( s.username ) {
@@ -31,24 +49,24 @@ jQuery.xhr.bindTransport( function( s , determineDataType ) {
} else {
xhr.open(s.type, s.url, s.async);
}
-
+
// 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";
}
-
+
// Need an extra try/catch for cross domain requests in Firefox 3
try {
-
+
jQuery.each(headers, function(key,value) {
xhr.setRequestHeader(key,value);
});
-
+
} catch(_) {}
-
+
// Do send the request
try {
xhr.send( ( s.hasContent && s.data ) || null );
@@ -56,55 +74,48 @@ jQuery.xhr.bindTransport( function( s , determineDataType ) {
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 ) ) {
-
- // Do not listen anymore
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+ // Only called once
+ callback = 0;
+
+ // Do not keep as active anymore
+ // and store back into pool
if (handle) {
xhr.onreadystatechange = jQuery.noop;
delete xhrs[ handle ];
- handle = undefined;
}
-
- 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
-
+
statusText = xhr.statusText;
-
+
} catch( e ) {
-
+
statusText = ""; // We normalize with Webkit giving an empty statusText
-
+
}
-
- responseHeaders = xhr.getAllResponseHeaders();
-
+
// Filter status for non standard behaviours
// (so many they seem to be the actual "standard")
status =
@@ -129,63 +140,44 @@ jQuery.xhr.bindTransport( function( s , determineDataType ) {
:
status
);
-
- // Guess response if needed & update datatype accordingly
- if ( status >= 200 && status < 300 ) {
- response =
- determineDataType(
- s,
- xhr.getResponseHeader("content-type"),
- xhr.responseText,
- xhr.responseXML );
- }
+
+ // Guess response & update dataType accordingly
+ response =
+ determineDataType(
+ s,
+ xhr.getResponseHeader("content-type"),
+ xhr.responseText,
+ xhr.responseXML );
+
+ // Call complete
+ complete(status,statusText,response,responseHeaders);
}
-
- // Call complete
- complete(status,statusText,response,responseHeaders);
}
};
-
+
// if we're in sync mode
// or it's in cache and has been retrieved directly (IE6 & IE7)
// we need to manually fire the callback
if ( ! s.async || xhr.readyState === 4 ) {
-
+
callback();
-
+
} 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);
}
}
};
}
});
-// #5280: we need to abort on unload or IE will keep connections alive
-jQuery(window).bind( "unload" , function() {
-
- // Abort all pending requests
- jQuery.each(xhrs, function(_, xhr) {
- if ( xhr.onreadystatechange ) {
- xhr.onreadystatechange( xhrUnloadAbortMarker );
- }
- });
-
- // Resest polling structure to be safe
- xhrs = {};
-
-});
-
})( jQuery );
diff --git a/src/attributes.js b/src/attributes.js
index 78b1bfd20..fec132340 100644
--- a/src/attributes.js
+++ b/src/attributes.js
@@ -182,7 +182,7 @@ jQuery.fn.extend({
var option = options[ i ];
// Don't return options that are disabled or in a disabled optgroup
- if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
+ if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
// Get the specific value for the option
diff --git a/src/core.js b/src/core.js
index 346e52d70..4361577e2 100644
--- a/src/core.js
+++ b/src/core.js
@@ -56,12 +56,12 @@ var jQuery = function( selector, context ) {
// For matching the engine and version of the browser
browserMatch,
-
+
// Has the ready events already been bound?
readyBound = false,
-
- // The functions to execute on DOM ready
- readyList = [],
+
+ // The deferred used on DOM ready
+ readyList,
// The ready event handler
DOMContentLoaded,
@@ -73,7 +73,7 @@ var jQuery = function( selector, context ) {
slice = Array.prototype.slice,
trim = String.prototype.trim,
indexOf = Array.prototype.indexOf,
-
+
// [[Class]] -> type pairs
class2type = {};
@@ -92,7 +92,7 @@ jQuery.fn = jQuery.prototype = {
this.length = 1;
return this;
}
-
+
// The body element only exists once, optimize finding it
if ( selector === "body" && !context && document.body ) {
this.context = document;
@@ -129,11 +129,11 @@ 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 );
-
+
// HANDLE: $("#id")
} else {
elem = document.getElementById( match[2] );
@@ -226,7 +226,7 @@ jQuery.fn = jQuery.prototype = {
if ( jQuery.isArray( elems ) ) {
push.apply( ret, elems );
-
+
} else {
jQuery.merge( ret, elems );
}
@@ -252,25 +252,15 @@ jQuery.fn = jQuery.prototype = {
each: function( callback, args ) {
return jQuery.each( this, callback, args );
},
-
- ready: function( fn ) {
+
+ ready: function() {
// Attach the listeners
jQuery.bindReady();
- // If the DOM is already ready
- if ( jQuery.isReady ) {
- // Execute the function immediately
- fn.call( document, jQuery );
-
- // Otherwise, remember the function for later
- } else if ( readyList ) {
- // Add the function to the wait list
- readyList.push( fn );
- }
-
- return this;
+ // Change ready & apply
+ return ( jQuery.fn.ready = readyList.done ).apply( this , arguments );
},
-
+
eq: function( i ) {
return i === -1 ?
this.slice( i ) :
@@ -295,7 +285,7 @@ jQuery.fn = jQuery.prototype = {
return callback.call( elem, i, elem );
}));
},
-
+
end: function() {
return this.prevObject || jQuery(null);
},
@@ -384,14 +374,14 @@ jQuery.extend({
return jQuery;
},
-
+
// Is the DOM ready to be used? Set to true once it occurs.
isReady: false,
// A counter to track how many items to wait for before
// the ready event fires. See #6781
readyWait: 1,
-
+
// Handle when the DOM is ready
ready: function( wait ) {
// A third-party is pushing the ready event forwards
@@ -415,27 +405,15 @@ jQuery.extend({
}
// If there are functions bound, to execute
- if ( readyList ) {
- // Execute all of them
- var fn,
- i = 0,
- ready = readyList;
+ readyList.fire( document , [ jQuery ] );
- // Reset the list of functions
- readyList = null;
-
- while ( (fn = ready[ i++ ]) ) {
- fn.call( document, jQuery );
- }
-
- // Trigger any bound ready events
- if ( jQuery.fn.trigger ) {
- jQuery( document ).trigger( "ready" ).unbind( "ready" );
- }
+ // Trigger any bound ready events
+ if ( jQuery.fn.trigger ) {
+ jQuery( document ).trigger( "ready" ).unbind( "ready" );
}
}
},
-
+
bindReady: function() {
if ( readyBound ) {
return;
@@ -454,7 +432,7 @@ jQuery.extend({
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
-
+
// A fallback to window.onload, that will always work
window.addEventListener( "load", jQuery.ready, false );
@@ -463,7 +441,7 @@ jQuery.extend({
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent("onreadystatechange", DOMContentLoaded);
-
+
// A fallback to window.onload, that will always work
window.attachEvent( "onload", jQuery.ready );
@@ -514,20 +492,20 @@ jQuery.extend({
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
}
-
+
// Not own constructor property must be Object
if ( obj.constructor &&
!hasOwn.call(obj, "constructor") &&
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
return false;
}
-
+
// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
-
+
var key;
for ( key in obj ) {}
-
+
return key === undefined || hasOwn.call( obj, key );
},
@@ -537,11 +515,11 @@ jQuery.extend({
}
return true;
},
-
+
error: function( msg ) {
throw msg;
},
-
+
parseJSON: function( data ) {
if ( typeof data !== "string" || !data ) {
return null;
@@ -549,7 +527,7 @@ jQuery.extend({
// Make sure leading/trailing whitespace is removed (IE can't handle it)
data = jQuery.trim( data );
-
+
// Make sure the incoming data is actual JSON
// Logic borrowed from http://json.org/json2.js
if ( rvalidchars.test(data.replace(rvalidescape, "@")
@@ -566,6 +544,28 @@ jQuery.extend({
}
},
+ // Cross-browser xml parsing
+ // (xml & tmp used internally)
+ parseXML: function( data , xml , tmp ) {
+
+ if ( window.DOMParser ) { // Standard
+ tmp = new DOMParser();
+ xml = tmp.parseFromString( data , "text/xml" );
+ } else { // IE
+ xml = new ActiveXObject( "Microsoft.XMLDOM" );
+ xml.async = "false";
+ xml.loadXML( data );
+ }
+
+ tmp = xml.documentElement;
+
+ if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
+ jQuery.error( "Invalid XML: " + data );
+ }
+
+ return xml;
+ },
+
noop: function() {},
// Evalulates a script in a global context
@@ -691,7 +691,7 @@ jQuery.extend({
for ( var l = second.length; j < l; j++ ) {
first[ i++ ] = second[ j ];
}
-
+
} else {
while ( second[j] !== undefined ) {
first[ i++ ] = second[ j++ ];
@@ -772,7 +772,7 @@ jQuery.extend({
// The value/s can be optionally by executed if its a function
access: function( elems, key, value, exec, fn, pass ) {
var length = elems.length;
-
+
// Setting many attributes
if ( typeof key === "object" ) {
for ( var k in key ) {
@@ -780,19 +780,19 @@ jQuery.extend({
}
return elems;
}
-
+
// Setting one attribute
if ( value !== undefined ) {
// Optionally, function values get executed if exec is true
exec = !pass && exec && jQuery.isFunction(value);
-
+
for ( var i = 0; i < length; i++ ) {
fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
}
-
+
return elems;
}
-
+
// Getting an attribute
return length ? fn( elems[0], key ) : undefined;
},
@@ -801,6 +801,151 @@ jQuery.extend({
return (new Date()).getTime();
},
+ // Create a simple deferred (one callbacks list)
+ _Deferred: function() {
+
+ var // callbacks list
+ callbacks = [],
+ // stored [ context , args ]
+ fired,
+ // to avoid firing when already doing so
+ firing,
+ // flag to know if the deferred has been cancelled
+ cancelled,
+ // the deferred itself
+ deferred = {
+
+ // done( f1, f2, ...)
+ done: function () {
+
+ if ( ! cancelled ) {
+
+ var args = arguments,
+ i,
+ length,
+ elem,
+ type,
+ _fired;
+
+ if ( fired ) {
+ _fired = fired;
+ fired = 0;
+ }
+
+ for ( i = 0, length = args.length ; i < length ; i++ ) {
+ elem = args[ i ];
+ type = jQuery.type( elem );
+ if ( type === "array" ) {
+ deferred.done.apply( deferred , elem );
+ } else if ( type === "function" ) {
+ callbacks.push( elem );
+ }
+ }
+
+ if ( _fired ) {
+ deferred.fire( _fired[ 0 ] , _fired[ 1 ] );
+ }
+ }
+
+ return this;
+ },
+
+ // resolve with given context and args
+ fire: function( context , args ) {
+ if ( ! cancelled && ! fired && ! firing ) {
+
+ firing = 1;
+
+ try {
+ while( callbacks[ 0 ] ) {
+ callbacks.shift().apply( context , args );
+ }
+ }
+ finally {
+ fired = [ context , args ];
+ firing = 0;
+ }
+ }
+ return this;
+ },
+
+ // resolve with this as context and given arguments
+ resolve: function() {
+ deferred.fire( jQuery.isFunction( this.promise ) ? this.promise() : this , arguments );
+ return this;
+ },
+
+ // Has this deferred been resolved?
+ isResolved: function() {
+ return !!( firing || fired );
+ },
+
+ // Cancel
+ cancel: function() {
+ cancelled = 1;
+ callbacks = [];
+ return this;
+ }
+ };
+
+ return deferred;
+ },
+
+ // Full fledged deferred (two callbacks list)
+ // Typical success/error system
+ Deferred: function( func ) {
+
+ var deferred = jQuery._Deferred(),
+ failDeferred = jQuery._Deferred();
+
+ // Add errorDeferred methods and redefine cancel
+ jQuery.extend( deferred , {
+
+ then: function( doneCallbacks , failCallbacks ) {
+ deferred.done( doneCallbacks ).fail( failCallbacks );
+ return this;
+ },
+ fail: failDeferred.done,
+ fireReject: failDeferred.fire,
+ reject: failDeferred.resolve,
+ isRejected: failDeferred.isResolved,
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function( obj ) {
+ obj = obj || {};
+ jQuery.each( "then done fail isResolved isRejected".split( " " ) , function( _ , method ) {
+ obj[ method ] = deferred[ method ];
+ });
+ obj.promise = function() {
+ return obj;
+ };
+ return obj;
+ }
+
+ } );
+
+ // Make sure only one callback list will be used
+ deferred.then( failDeferred.cancel , deferred.cancel );
+
+ // Unexpose cancel
+ delete deferred.cancel;
+
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred , deferred );
+ }
+
+ return deferred;
+ },
+
+ // Deferred helper
+ when: function( object ) {
+ object = object && jQuery.isFunction( object.promise ) ?
+ object :
+ jQuery.Deferred().resolve( object );
+ return object.promise();
+ },
+
// Use of jQuery.browser is frowned upon.
// More details: http://docs.jquery.com/Utilities/jQuery.browser
uaMatch: function( ua ) {
@@ -818,6 +963,9 @@ jQuery.extend({
browser: {}
});
+// Create readyList deferred
+readyList = jQuery._Deferred();
+
// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
diff --git a/src/css.js b/src/css.js
index 8a83c6072..a6e2bb614 100644
--- a/src/css.js
+++ b/src/css.js
@@ -12,9 +12,6 @@ var ralpha = /alpha\([^)]*\)/i,
cssHeight = [ "Top", "Bottom" ],
curCSS,
- getComputedStyle,
- currentStyle,
-
fcamelCase = function( all, letter ) {
return letter.toUpperCase();
};
@@ -172,10 +169,6 @@ jQuery.each(["height", "width"], function( i, name ) {
if ( val <= 0 ) {
val = curCSS( elem, name, name );
- if ( val === "0px" && currentStyle ) {
- val = currentStyle( elem, name, name );
- }
-
if ( val != null ) {
// Should return "auto" instead of 0, use 0 for
// temporary backwards-compat
@@ -241,7 +234,7 @@ if ( !jQuery.support.opacity ) {
}
if ( document.defaultView && document.defaultView.getComputedStyle ) {
- getComputedStyle = function( elem, newName, name ) {
+ curCSS = function( elem, newName, name ) {
var ret, defaultView, computedStyle;
name = name.replace( rupper, "-$1" ).toLowerCase();
@@ -259,10 +252,8 @@ if ( document.defaultView && document.defaultView.getComputedStyle ) {
return ret;
};
-}
-
-if ( document.documentElement.currentStyle ) {
- currentStyle = function( elem, name ) {
+} else if ( document.documentElement.currentStyle ) {
+ curCSS = function( elem, name ) {
var left, rsLeft,
ret = elem.currentStyle && elem.currentStyle[ name ],
style = elem.style;
@@ -291,8 +282,6 @@ if ( document.documentElement.currentStyle ) {
};
}
-curCSS = getComputedStyle || currentStyle;
-
function getWH( elem, name, extra ) {
var which = name === "width" ? cssWidth : cssHeight,
val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
diff --git a/src/data.js b/src/data.js
index f1e031fff..4d1d1bd55 100644
--- a/src/data.js
+++ b/src/data.js
@@ -9,8 +9,9 @@ jQuery.extend({
// Please use with caution
uuid: 0,
- // Unique for each copy of jQuery on the page
- expando: "jQuery" + jQuery.now(),
+ // Unique for each copy of jQuery on the page
+ // Non-digits removed to match rinlinejQuery
+ expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
// The following elements throw uncatchable exceptions if you
// attempt to add expando properties to them.
@@ -21,6 +22,14 @@ jQuery.extend({
"applet": true
},
+ hasData: function( elem ) {
+ if ( elem.nodeType ) {
+ elem = jQuery.cache[ elem[jQuery.expando] ];
+ }
+
+ return !!elem && !jQuery.isEmptyObject(elem);
+ },
+
data: function( elem, name, data ) {
if ( !jQuery.acceptData( elem ) ) {
return;
@@ -144,7 +153,7 @@ jQuery.fn.extend({
var attr = this[0].attributes, name;
for ( var i = 0, l = attr.length; i < l; i++ ) {
name = attr[i].name;
-
+
if ( name.indexOf( "data-" ) === 0 ) {
name = name.substr( 5 );
dataAttr( this[0], name, data[ name ] );
diff --git a/src/dimensions.js b/src/dimensions.js
index b4dae83c4..a292899b9 100644
--- a/src/dimensions.js
+++ b/src/dimensions.js
@@ -25,7 +25,7 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
if ( !elem ) {
return size == null ? null : this;
}
-
+
if ( jQuery.isFunction( size ) ) {
return this.each(function( i ) {
var self = jQuery( this );
diff --git a/src/effects.js b/src/effects.js
index 600707427..bd57ffc3d 100644
--- a/src/effects.js
+++ b/src/effects.js
@@ -61,7 +61,7 @@ jQuery.fn.extend({
} else {
for ( var i = 0, j = this.length; i < j; i++ ) {
var display = jQuery.css( this[i], "display" );
-
+
if ( display !== "none" && !jQuery.data( this[i], "olddisplay" ) ) {
jQuery.data( this[i], "olddisplay", display );
}
@@ -337,7 +337,7 @@ jQuery.fx.prototype = {
}
var r = parseFloat( jQuery.css( this.elem, this.prop ) );
- return r && r > -10000 ? r : 0;
+ return r || 0;
},
// Start an animation from one number to another
diff --git a/src/event.js b/src/event.js
index fd470e718..675e5fff3 100644
--- a/src/event.js
+++ b/src/event.js
@@ -63,7 +63,7 @@ jQuery.event = {
var eventKey = elem.nodeType ? "events" : "__events__",
events = elemData[ eventKey ],
eventHandle = elemData.handle;
-
+
if ( typeof events === "function" ) {
// On plain objects events is a fn that holds the the data
// which prevents this data from being JSON serialized
@@ -143,9 +143,9 @@ jQuery.event = {
}
}
}
-
- if ( special.add ) {
- special.add.call( elem, handleObj );
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
if ( !handleObj.handler.guid ) {
handleObj.handler.guid = handler.guid;
@@ -184,7 +184,7 @@ jQuery.event = {
if ( !elemData || !events ) {
return;
}
-
+
if ( typeof events === "function" ) {
elemData = events;
events = events.events;
@@ -222,7 +222,7 @@ jQuery.event = {
namespaces = type.split(".");
type = namespaces.shift();
- namespace = new RegExp("(^|\\.)" +
+ namespace = new RegExp("(^|\\.)" +
jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
}
@@ -384,7 +384,7 @@ jQuery.event = {
isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
special = jQuery.event.special[ targetType ] || {};
- if ( (!special._default || special._default.call( elem, event ) === false) &&
+ if ( (!special._default || special._default.call( elem, event ) === false) &&
!isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
try {
@@ -454,7 +454,7 @@ jQuery.event = {
event.handler = handleObj.handler;
event.data = handleObj.data;
event.handleObj = handleObj;
-
+
var ret = handleObj.handler.apply( this, args );
if ( ret !== undefined ) {
@@ -553,7 +553,7 @@ jQuery.event = {
add: function( handleObj ) {
jQuery.event.add( this,
liveConvert( handleObj.origType, handleObj.selector ),
- jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
+ jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
},
remove: function( handleObj ) {
@@ -583,7 +583,7 @@ jQuery.removeEvent = document.removeEventListener ?
if ( elem.removeEventListener ) {
elem.removeEventListener( type, handle, false );
}
- } :
+ } :
function( elem, type, handle ) {
if ( elem.detachEvent ) {
elem.detachEvent( "on" + type, handle );
@@ -600,6 +600,12 @@ jQuery.Event = function( src ) {
if ( src && src.type ) {
this.originalEvent = src;
this.type = src.type;
+
+ // 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 ||
+ src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
+
// Event type
} else {
this.type = src;
@@ -630,7 +636,7 @@ jQuery.Event.prototype = {
if ( !e ) {
return;
}
-
+
// if preventDefault exists run it on the original event
if ( e.preventDefault ) {
e.preventDefault();
@@ -726,7 +732,7 @@ if ( !jQuery.support.submitBubbles ) {
return trigger( "submit", this, arguments );
}
});
-
+
jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
var elem = e.target,
type = elem.type;
@@ -788,7 +794,7 @@ if ( !jQuery.support.changeBubbles ) {
if ( e.type !== "focusout" || elem.type !== "radio" ) {
jQuery.data( elem, "_change_data", val );
}
-
+
if ( data === undefined || val === data ) {
return;
}
@@ -802,7 +808,7 @@ if ( !jQuery.support.changeBubbles ) {
jQuery.event.special.change = {
filters: {
- focusout: testChange,
+ focusout: testChange,
beforedeactivate: testChange,
@@ -873,15 +879,15 @@ if ( document.addEventListener ) {
if ( focusCounts[fix]++ === 0 ) {
document.addEventListener( orig, handler, true );
}
- },
- teardown: function() {
+ },
+ teardown: function() {
if ( --focusCounts[fix] === 0 ) {
document.removeEventListener( orig, handler, true );
}
}
};
- function handler( e ) {
+ function handler( e ) {
e = jQuery.event.fix( e );
e.type = fix;
return jQuery.event.trigger( e, null, e.target );
@@ -898,7 +904,7 @@ jQuery.each(["bind", "one"], function( i, name ) {
}
return this;
}
-
+
if ( jQuery.isFunction( data ) || data === false ) {
fn = data;
data = undefined;
@@ -938,20 +944,20 @@ jQuery.fn.extend({
return this;
},
-
+
delegate: function( selector, types, data, fn ) {
return this.live( types, data, fn, selector );
},
-
+
undelegate: function( selector, types, fn ) {
if ( arguments.length === 0 ) {
return this.unbind( "live" );
-
+
} else {
return this.die( types, null, fn, selector );
}
},
-
+
trigger: function( type, data ) {
return this.each(function() {
jQuery.event.trigger( type, data, this );
@@ -1008,12 +1014,12 @@ jQuery.each(["live", "die"], function( i, name ) {
var type, i = 0, match, namespaces, preType,
selector = origSelector || this.selector,
context = origSelector ? this : jQuery( this.context );
-
+
if ( typeof types === "object" && !types.preventDefault ) {
for ( var key in types ) {
context[ name ]( key, data, types[key], selector );
}
-
+
return this;
}
@@ -1060,7 +1066,7 @@ jQuery.each(["live", "die"], function( i, name ) {
context.unbind( "live." + liveConvert( type, selector ), fn );
}
}
-
+
return this;
};
});
@@ -1079,7 +1085,7 @@ function liveHandler( event ) {
if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
return;
}
-
+
if ( event.namespace ) {
namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
}
@@ -1177,21 +1183,4 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
}
});
-// Prevent memory leaks in IE
-// Window isn't included so as not to unbind existing unload events
-// More info:
-// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
-if ( window.attachEvent && !window.addEventListener ) {
- jQuery(window).bind("unload", function() {
- for ( var id in jQuery.cache ) {
- if ( jQuery.cache[ id ].handle ) {
- // Try/Catch is to handle iframes being unloaded, see #4280
- try {
- jQuery.event.remove( jQuery.cache[ id ].handle.elem );
- } catch(e) {}
- }
- }
- });
-}
-
})( jQuery );
diff --git a/src/intro.js b/src/intro.js
index cb15705a6..a75f3112f 100644
--- a/src/intro.js
+++ b/src/intro.js
@@ -11,7 +11,7 @@
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
- * Date:
+ * Date: @DATE
*/
(function( window, undefined ) {
diff --git a/src/manipulation.js b/src/manipulation.js
index 7dea3493c..cf533c818 100644
--- a/src/manipulation.js
+++ b/src/manipulation.js
@@ -370,14 +370,18 @@ function root( elem, cur ) {
}
function cloneCopyEvent(orig, ret) {
- var i = 0;
-
- ret.each(function() {
- if ( this.nodeType !== 1 || this.nodeName !== (orig[i] && orig[i].nodeName) ) {
+ ret.each(function (nodeIndex) {
+ if ( this.nodeType !== 1 || !jQuery.hasData(orig[nodeIndex]) ) {
return;
}
- var oldData = jQuery.data( orig[i++] ),
+ // XXX remove for 1.5 RC or merge back in if there is actually a reason for this check that has been
+ // unexposed by unit tests
+ if ( this.nodeName !== (orig[nodeIndex] && orig[nodeIndex].nodeName) ) {
+ throw "Cloned data mismatch";
+ }
+
+ var oldData = jQuery.data( orig[nodeIndex] ),
curData = jQuery.data( this, oldData ),
events = oldData && oldData.events;
@@ -386,8 +390,8 @@ function cloneCopyEvent(orig, ret) {
curData.events = {};
for ( var type in events ) {
- for ( var handler in events[ type ] ) {
- jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+ for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
+ jQuery.event.add( this, type, events[ type ][ i ], events[ type ][ i ].data );
}
}
}
@@ -416,15 +420,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
@@ -436,12 +454,12 @@ jQuery.buildFragment = function( args, nodes, scripts ) {
var fragment, cacheable, cacheresults,
doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
- // Only cache "small" (1/2 KB) strings that are associated with the main document
+ // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
// Cloning options loses the selected state, so don't cache them
// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
- !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+ args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
cacheable = true;
cacheresults = jQuery.fragments[ args[0] ];
@@ -613,6 +631,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 ) {
diff --git a/src/offset.js b/src/offset.js
index 3fb2917b2..2040c9d83 100644
--- a/src/offset.js
+++ b/src/offset.js
@@ -7,7 +7,7 @@ if ( "getBoundingClientRect" in document.documentElement ) {
jQuery.fn.offset = function( options ) {
var elem = this[0], box;
- if ( options ) {
+ if ( options ) {
return this.each(function( i ) {
jQuery.offset.setOffset( this, options, i );
});
@@ -49,7 +49,7 @@ if ( "getBoundingClientRect" in document.documentElement ) {
jQuery.fn.offset = function( options ) {
var elem = this[0];
- if ( options ) {
+ if ( options ) {
return this.each(function( i ) {
jQuery.offset.setOffset( this, options, i );
});
@@ -168,7 +168,7 @@ jQuery.offset = {
return { top: top, left: left };
},
-
+
setOffset: function( elem, options, i ) {
var position = jQuery.css( elem, "position" );
@@ -202,7 +202,7 @@ jQuery.offset = {
if (options.left != null) {
props.left = (options.left - curOffset.left) + curLeft;
}
-
+
if ( "using" in options ) {
options.using.call( elem, props );
} else {
@@ -262,7 +262,7 @@ jQuery.each( ["Left", "Top"], function( i, name ) {
jQuery.fn[ method ] = function(val) {
var elem = this[0], win;
-
+
if ( !elem ) {
return null;
}
diff --git a/src/support.js b/src/support.js
index 67b41c4a7..e4c3ea916 100644
--- a/src/support.js
+++ b/src/support.js
@@ -147,7 +147,7 @@
jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
}
- div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
+ div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
var tds = div.getElementsByTagName("td");
// Check if table cells still have offsetWidth/Height when they are set
diff --git a/src/transports/jsonp.js b/src/transports/jsonp.js
deleted file mode 100644
index d9e77f2f3..000000000
--- a/src/transports/jsonp.js
+++ /dev/null
@@ -1,89 +0,0 @@
-(function( jQuery ) {
-
-var jsc = jQuery.now(),
- jsre = /\=\?(&|$)/,
- rquery_jsonp = /\?/;
-
-// Default jsonp callback name
-jQuery.ajaxSettings.jsonpCallback = function() {
- return "jsonp" + jsc++;
-};
-
-// Normalize jsonp queries
-// 1) put callback parameter in url or data
-// 2) ensure transportDataType is json
-// 3) ensure options jsonp is always provided so that jsonp requests are always
-// json request with the jsonp option set
-jQuery.xhr.prefilter( function(s) {
-
- var transportDataType = s.dataTypes[0];
-
- if ( s.jsonp ||
- transportDataType === "jsonp" ||
- transportDataType === "json" && ( jsre.test(s.url) || typeof(s.data) === "string" && jsre.test(s.data) ) ) {
-
- var jsonp = s.jsonp = s.jsonp || "callback",
- 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 = url += (rquery_jsonp.test( url ) ? "&" : "?") + jsonp + "=" + jsonpCallback;
- }
-
- s.url = url;
- s.data = data;
-
- s.dataTypes[0] = "json";
- }
-
-});
-
-// Bind transport to json dataType
-jQuery.xhr.bindTransport("json", function(s) {
-
- if ( s.jsonp ) {
-
- // Put callback in place
- var responseContainer,
- jsonpCallback = s.jsonpCallback,
- previous = window[ jsonpCallback ];
-
- window [ jsonpCallback ] = function( response ) {
- responseContainer = [response];
- };
-
- s.complete = [function() {
-
- // 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] );
- }
- } else {
- // else, more memory leak avoidance
- try{ delete window[ jsonpCallback ]; } catch(e){}
- }
-
- }, s.complete ];
-
- // Use data converter to retrieve json after script execution
- s.dataConverters["script => json"] = function() {
- if ( ! responseContainer ) {
- jQuery.error("Callback '" + jsonpCallback + "' was not called");
- }
- return responseContainer[ 0 ];
- };
-
- // Delegate to script transport
- return "script";
-
- }
-
-});
-
-})( jQuery );
diff --git a/src/traversing.js b/src/traversing.js
index 15446bd8b..689e90196 100644
--- a/src/traversing.js
+++ b/src/traversing.js
@@ -51,7 +51,7 @@ jQuery.fn.extend({
filter: function( selector ) {
return this.pushStack( winnow(this, selector, true), "filter", selector );
},
-
+
is: function( selector ) {
return !!selector && jQuery.filter( selector, this ).length > 0;
},
@@ -69,7 +69,7 @@ jQuery.fn.extend({
selector = selectors[i];
if ( !matches[selector] ) {
- matches[selector] = jQuery.expr.match.POS.test( selector ) ?
+ matches[selector] = jQuery.expr.match.POS.test( selector ) ?
jQuery( selector, context || this.context ) :
selector;
}
@@ -92,7 +92,7 @@ jQuery.fn.extend({
return ret;
}
- var pos = POS.test( selectors ) ?
+ var pos = POS.test( selectors ) ?
jQuery( selectors, context || this.context ) : null;
for ( i = 0, l = this.length; i < l; i++ ) {
@@ -113,10 +113,10 @@ jQuery.fn.extend({
}
ret = ret.length > 1 ? jQuery.unique(ret) : ret;
-
+
return this.pushStack( ret, "closest", selectors );
},
-
+
// Determine the position of an element within
// the matched set of elements
index: function( elem ) {
@@ -197,7 +197,7 @@ jQuery.each({
}, function( name, fn ) {
jQuery.fn[ name ] = function( until, selector ) {
var ret = jQuery.map( this, fn, until );
-
+
if ( !runtil.test( name ) ) {
selector = until;
}
@@ -226,7 +226,7 @@ jQuery.extend({
jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
jQuery.find.matches(expr, elems);
},
-
+
dir: function( elem, dir, until ) {
var matched = [],
cur = elem[ dir ];
diff --git a/src/xhr.js b/src/xhr.js
deleted file mode 100644
index 57903e046..000000000
--- a/src/xhr.js
+++ /dev/null
@@ -1,909 +0,0 @@
-(function( jQuery ) {
-
-var rquery_xhr = /\?/,
- rhash = /#.*$/,
- rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL
- rnoContent = /^(?:GET|HEAD)$/,
- rts = /([?&])_=[^&]*/,
- rurl = /^(\w+:)?\/\/([^\/?#]+)/,
-
- sliceFunc = Array.prototype.slice,
-
- isFunction = jQuery.isFunction;
-
-// Creates a jQuery xhr object
-jQuery.xhr = function( _native ) {
-
- if ( _native ) {
- return jQuery.ajaxSettings.xhr();
- }
-
- function reset(force) {
-
- // We only need to reset if we went through the init phase
- // (with the exception of object creation)
- if ( force || internal ) {
-
- // Reset callbacks lists
- callbacksLists = {
- success: createCBList(),
- error: createCBList(),
- complete: createCBList()
- };
-
- // Reset private variables
- requestHeaders = {};
- responseHeadersString = responseHeaders = internal = done = timeoutTimer = s = undefined;
-
- // Reset state
- xhr.readyState = 0;
- sendFlag = 0;
-
- // Remove responseX fields
- for ( var name in xhr ) {
- if ( /^response/.test(name) ) {
- delete xhr[name];
- }
- }
- }
- }
-
- function init() {
-
- var // Options extraction
-
- // Remove hash character (#7531: first for string promotion)
- url = s.url = ( "" + s.url ).replace( rhash , "" ),
-
- // Uppercase the type
- type = s.type = s.type.toUpperCase(),
-
- // Determine if request has content
- hasContent = s.hasContent = ! rnoContent.test( type ),
-
- // Extract dataTypes list
- dataType = s.dataType,
- dataTypes = s.dataTypes = dataType ? jQuery.trim(dataType).toLowerCase().split(/\s+/) : ["*"],
-
- // Determine if a cross-domain request is in order
- parts = rurl.exec( url.toLowerCase() ),
- loc = location,
- crossDomain = s.crossDomain = !!( parts && ( parts[1] && parts[1] != loc.protocol || parts[2] != loc.host ) ),
-
- // Get other options locally
- data = s.data,
- originalContentType = s.contentType,
- prefilters = s.prefilters,
- accepts = s.accepts,
- headers = s.headers,
-
- // Other Variables
- transportDataType,
- i;
-
- // Convert data if not already a string
- if ( data && s.processData && typeof data != "string" ) {
- data = s.data = jQuery.param( data , s.traditional );
- }
-
- // Apply option prefilters
- for (i in prefilters) {
- prefilters[i](s);
- }
-
- // Get internal
- internal = selectTransport( s );
-
- // Re-actualize url & data
- url = s.url;
- data = s.data;
-
- // If internal was found
- if ( internal ) {
-
- // Get transportDataType
- transportDataType = dataTypes[0];
-
- // More options handling for requests with no content
- if ( ! hasContent ) {
-
- // If data is available, append data to url
- if ( data ) {
- url += (rquery_xhr.test(url) ? "&" : "?") + data;
- }
-
- // Add anti-cache in url if needed
- if ( s.cache === false ) {
-
- var ts = jQuery.now(),
- // try replacing _= if it is there
- ret = url.replace(rts, "$1_=" + ts );
-
- // if nothing was replaced, add timestamp to the end
- url = ret + ((ret == url) ? (rquery_xhr.test(url) ? "&" : "?") + "_=" + ts : "");
- }
-
- s.url = url;
- }
-
- // Set the correct header, if data is being sent
- if ( ( data && hasContent ) || originalContentType ) {
- requestHeaders["content-type"] = s.contentType;
- }
-
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if ( s.ifModified ) {
- if ( jQuery_lastModified[url] ) {
- requestHeaders["if-modified-since"] = jQuery_lastModified[url];
- }
- if ( jQuery_etag[url] ) {
- requestHeaders["if-none-match"] = jQuery_etag[url];
- }
- }
-
- // Set the Accepts header for the server, depending on the dataType
- requestHeaders.accept = transportDataType && accepts[ transportDataType ] ?
- accepts[ transportDataType ] + ( transportDataType !== "*" ? ", */*; q=0.01" : "" ) :
- accepts[ "*" ];
-
- // Check for headers option
- for ( i in headers ) {
- requestHeaders[ i.toLowerCase() ] = headers[ i ];
- }
- }
-
- callbackContext = s.context || s;
- globalEventContext = s.context ? jQuery(s.context) : jQuery.event;
-
- for ( i in callbacksLists ) {
- callbacksLists[i].bind(s[i]);
- }
-
- // Watch for a new set of requests
- if ( s.global && jQuery.active++ === 0 ) {
- jQuery.event.trigger( "ajaxStart" );
- }
-
- done = whenDone;
- }
-
- function whenDone(status, statusText, response, headers) {
-
- // Called once
- done = undefined;
-
- // Reset sendFlag
- sendFlag = 0;
-
- // Cache response headers
- responseHeadersString = headers || "";
-
- // Clear timeout if it exists
- if ( timeoutTimer ) {
- clearTimeout(timeoutTimer);
- }
-
- var // Reference url
- url = s.url,
- // and ifModified status
- ifModified = s.ifModified,
-
- // Is it a success?
- isSuccess = 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" );
- }
-
- // If successful, handle type chaining
- if ( statusText === "success" || statusText === "notmodified" ) {
-
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if ( ifModified ) {
- var lastModified = xhr.getResponseHeader("Last-Modified"),
- etag = xhr.getResponseHeader("Etag");
-
- if (lastModified) {
- jQuery_lastModified[url] = lastModified;
- }
- if (etag) {
- jQuery_etag[url] = etag;
- }
- }
-
- if ( ifModified && statusText === "notmodified" ) {
-
- success = null;
- isSuccess = 1;
-
- } else {
- // Chain data conversions and determine the final value
- // (if an exception is thrown in the process, it'll be notified as an error)
- try {
-
- function checkData(data) {
- if ( data !== undefined ) {
- var testFunction = s.dataCheckers[srcDataType];
- if ( isFunction( testFunction ) ) {
- testFunction(data);
- }
- }
- }
-
- function convertData (data) {
- var conversionFunction = dataConverters[srcDataType+" => "+destDataType] ||
- dataConverters["* => "+destDataType],
- noFunction = ! isFunction( conversionFunction );
- if ( noFunction ) {
- if ( srcDataType != "text" && destDataType != "text" ) {
- // We try to put text inbetween
- var first = dataConverters[srcDataType+" => text"] ||
- dataConverters["* => text"],
- second = dataConverters["text => "+destDataType] ||
- dataConverters["* => "+destDataType],
- areFunctions = isFunction( first ) && isFunction( second );
- if ( areFunctions ) {
- conversionFunction = function (data) {
- return second( first ( data ) );
- };
- }
- noFunction = ! areFunctions;
- }
- if ( noFunction ) {
- jQuery.error( "no data converter between " + srcDataType + " and " + destDataType );
- }
-
- }
- return conversionFunction(data);
- }
-
- var dataTypes = s.dataTypes,
- i,
- length,
- data = response,
- dataConverters = s.dataConverters,
- srcDataType,
- destDataType,
- responseTypes = s.xhrResponseFields;
-
- for ( i = 0, length = dataTypes.length ; i < length ; i++ ) {
-
- destDataType = dataTypes[i];
-
- if ( !srcDataType ) { // First time
-
- // Copy type
- srcDataType = destDataType;
- // Check
- checkData(data);
- // Apply dataFilter
- if ( isFunction( s.dataFilter ) ) {
- data = s.dataFilter(data, s.dataType);
- // Recheck data
- checkData(data);
- }
-
- } else { // Subsequent times
-
- // handle auto
- // JULIAN: for reasons unknown to me === doesn't work here
- if (destDataType == "*") {
-
- destDataType = srcDataType;
-
- } else if ( srcDataType != destDataType ) {
-
- // Convert
- data = convertData(data);
- // Copy type & check
- srcDataType = destDataType;
- checkData(data);
-
- }
-
- }
-
- // Copy response into the xhr if it hasn't been already
- var responseDataType,
- responseType = responseTypes[srcDataType];
-
- if ( responseType ) {
-
- responseDataType = srcDataType;
-
- } else {
-
- responseType = responseTypes[ responseDataType = "text" ];
-
- }
-
- if ( responseType !== 1 ) {
- xhr[ "response" + responseType ] = data;
- responseTypes[ responseType ] = 1;
- }
-
- }
-
- // We have a real success
- success = data;
- isSuccess = 1;
-
- } catch(e) {
-
- statusText = "parsererror";
- error = "" + e;
-
- }
- }
-
- } else { // if not success, mark it as an error
-
- error = error || statusText;
-
- }
-
- // Set data for the fake xhr object
- xhr.status = status;
- xhr.statusText = statusText;
-
- // Keep local copies of vars in case callbacks re-use the xhr
- var _s = s,
- _callbacksLists = callbacksLists,
- _callbackContext = callbackContext,
- _globalEventContext = globalEventContext;
-
- // Set state if the xhr hasn't been re-used
- function _setState( value ) {
- if ( xhr.readyState && s === _s ) {
- setState( value );
- }
- }
-
- // Really completed?
- if ( status && s.async ) {
- setState( 2 );
- _setState( 3 );
- }
-
- // We're done
- _setState( 4 );
-
- // Success
- _callbacksLists.success.fire( isSuccess , _callbackContext , success, statusText, xhr);
- if ( isSuccess && _s.global ) {
- _globalEventContext.trigger( "ajaxSuccess", [xhr, _s, success] );
- }
- // Error
- _callbacksLists.error.fire( ! isSuccess , _callbackContext , xhr, statusText, error);
- if ( !isSuccess && _s.global ) {
- _globalEventContext.trigger( "ajaxError", [xhr, _s, error] );
- }
- // Complete
- _callbacksLists.complete.fire( 1 , _callbackContext, xhr, statusText);
- if ( _s.global ) {
- _globalEventContext.trigger( "ajaxComplete", [xhr, _s] );
- // Handle the global AJAX counter
- if ( ! --jQuery.active ) {
- jQuery.event.trigger( "ajaxStop" );
- }
- }
- }
-
- // Ready state control
- function checkState( expected , test ) {
- if ( expected !== true && ( expected === false || test === false || xhr.readyState !== expected ) ) {
- jQuery.error("INVALID_STATE_ERR");
- }
- }
-
- // Ready state change
- function setState( value ) {
- xhr.readyState = value;
- if ( isFunction( xhr.onreadystatechange ) ) {
- xhr.onreadystatechange();
- }
- }
-
- var // jQuery lists
- jQuery_lastModified = jQuery.lastModified,
- jQuery_etag = jQuery.etag,
- // Options object
- s,
- // Callback stuff
- callbackContext,
- globalEventContext,
- callbacksLists,
- // Headers (they are sent all at once)
- requestHeaders,
- // Response headers
- responseHeadersString,
- responseHeaders,
- // Done callback
- done,
- // transport
- internal,
- // timeout handle
- timeoutTimer,
- // The send flag
- sendFlag,
- // Fake xhr
- xhr = {
- // state
- readyState: 0,
-
- // Callback
- onreadystatechange: null,
-
- // Open
- open: function(type, url, async, username, password) {
-
- xhr.abort();
- reset();
-
- s = {
- type: type,
- url: url,
- async: async,
- username: username,
- password: password
- };
-
- setState(1);
-
- return xhr;
- },
-
- // Send
- send: function(data, moreOptions) {
-
- checkState(1 , !sendFlag);
-
- s.data = data;
-
- s = jQuery.extend( true,
- {},
- jQuery.ajaxSettings,
- s,
- moreOptions || ( moreOptions === false ? { global: false } : {} ) );
-
- if ( moreOptions ) {
- // We force the original context
- // (plain objects used as context get extended)
- s.context = moreOptions.context;
- }
-
- init();
-
- // If not internal, abort
- if ( ! internal ) {
- done( 0 , "transport not found" );
- return false;
- }
-
- // Allow custom headers/mimetypes and early abort
- if ( s.beforeSend ) {
-
- var _s = s;
-
- if ( s.beforeSend.call(callbackContext, xhr, s) === false || ! xhr.readyState || _s !== s ) {
-
- // Abort if not done
- if ( xhr.readyState && _s === s ) {
- xhr.abort();
- }
-
- // Handle the global AJAX counter
- if ( _s.global && ! --jQuery.active ) {
- jQuery.event.trigger( "ajaxStop" );
- }
-
- return false;
- }
- }
-
- sendFlag = 1;
-
- // Send global event
- if ( s.global ) {
- globalEventContext.trigger("ajaxSend", [xhr, s]);
- }
-
- // Timeout
- if ( s.async && s.timeout > 0 ) {
- timeoutTimer = setTimeout(function(){
- xhr.abort("timeout");
- }, s.timeout);
- }
-
- if ( s.async ) {
- setState(1);
- }
-
- try {
-
- internal.send(requestHeaders, done);
- return xhr;
-
- } catch (e) {
-
- if ( done ) {
-
- done(0, "error", "" + e);
-
- } else {
-
- jQuery.error(e);
-
- }
- }
-
- return false;
- },
-
- // Caches the header
- setRequestHeader: function(name,value) {
- checkState(1, !sendFlag);
- requestHeaders[ name.toLowerCase() ] = value;
- return xhr;
- },
-
- // Raw string
- getAllResponseHeaders: function() {
- return xhr.readyState <= 1 ? "" : responseHeadersString;
- },
-
- // Builds headers hashtable if needed
- getResponseHeader: function( key ) {
-
- if ( xhr.readyState <= 1 ) {
-
- return null;
-
- }
-
- if ( responseHeaders === undefined ) {
-
- responseHeaders = {};
-
- if ( typeof responseHeadersString === "string" ) {
-
- var match;
-
- while( ( match = rheaders.exec( responseHeadersString ) ) ) {
- responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
- }
- }
- }
- return responseHeaders[ key.toLowerCase() ];
- },
-
- // Cancel the request
- abort: function(statusText) {
- if (internal) {
- internal.abort( statusText || "abort" );
- }
- xhr.readyState = 0;
- }
- };
-
- // Init data (so that we can bind callbacks early
- reset(1);
-
- // Install callbacks related methods
- jQuery.each(callbacksLists, function(name) {
- var list;
- xhr[name] = function() {
- list = callbacksLists[name];
- if ( list ) {
- list.bind.apply(list, arguments );
- }
- return this;
- };
- });
-
- // Return the xhr emulation
- return xhr;
-};
-
-// Create a callback list
-function createCBList() {
-
- var functors = [],
- autoFire = 0,
- fireArgs,
- list = {
-
- fire: function( flag , context ) {
-
- // Save info for later bindings
- fireArgs = arguments;
-
- // Remove autoFire to keep bindings in order
- autoFire = 0;
-
- var args = sliceFunc.call( fireArgs , 2 );
-
- // Execute callbacks
- while ( flag && functors.length ) {
- flag = functors.shift().apply( context , args ) !== false;
- }
-
- // Clean if asked to stop
- if ( ! flag ) {
- clean();
- }
-
- // Set autoFire
- autoFire = 1;
- },
-
- bind: function() {
-
- var args = arguments,
- i = 0,
- length = args.length,
- func;
-
- for ( ; i < length ; i++ ) {
-
- func = args[ i ];
-
- if ( jQuery.isArray(func) ) {
-
- list.bind.apply( list , func );
-
- } else if ( isFunction(func) ) {
-
- // Add if not already in
- if ( ! pos( func ) ) {
- functors.push( func );
- }
- }
- }
-
- if ( autoFire ) {
- list.fire.apply( list , fireArgs );
- }
- },
-
- unbind: function() {
-
- var i = 0,
- args = arguments,
- length = args.length,
- func,
- position;
-
- if ( length ) {
-
- for( ; i < length ; i++ ) {
- func = args[i];
- if ( jQuery.isArray(func) ) {
- list.unbind.apply(list,func);
- } else if ( isFunction(func) ) {
- position = pos(func);
- if ( position ) {
- functors.splice(position-1,1);
- }
- }
- }
-
- } else {
-
- functors = [];
-
- }
-
- }
-
- };
-
- // Get the index of the functor in the list (1-based)
- function pos( func ) {
- for (var i = 0, length = functors.length; i < length && functors[i] !== func; i++) {
- }
- return i < length ? ( i + 1 ) : 0;
- }
-
- // Clean the object
- function clean() {
- // Empty callbacks list
- functors = [];
- // Inhibit methods
- for (var i in list) {
- list[i] = jQuery.noop;
- }
- }
-
- return list;
-}
-
-jQuery.extend(jQuery.xhr, {
-
- // Add new prefilter
- prefilter: function (functor) {
- if ( isFunction(functor) ) {
- jQuery.ajaxSettings.prefilters.push( functor );
- }
- return this;
- },
-
- // Bind a transport to one or more dataTypes
- bindTransport: function () {
-
- var args = arguments,
- i,
- start = 0,
- length = args.length,
- dataTypes = [ "*" ],
- functors = [],
- functor,
- first,
- append,
- list,
- transports = jQuery.ajaxSettings.transports;
-
- if ( length ) {
-
- if ( ! isFunction( args[ 0 ] ) ) {
-
- dataTypes = args[ 0 ].toLowerCase().split(/\s+/);
- start = 1;
-
- }
-
- if ( dataTypes.length && start < length ) {
-
- for ( i = start; i < length; i++ ) {
- functor = args[i];
- if ( isFunction(functor) ) {
- functors.push( functor );
- }
- }
-
- if ( functors.length ) {
-
- jQuery.each ( dataTypes, function( _ , dataType ) {
-
- first = /^\+/.test( dataType );
-
- if (first) {
- dataType = dataType.substr(1);
- }
-
- if ( dataType !== "" ) {
-
- append = Array.prototype[ first ? "unshift" : "push" ];
-
- list = transports[ dataType ];
-
- jQuery.each ( functors, function( _ , functor ) {
-
- if ( ! list ) {
-
- list = transports[ dataType ] = [ functor ];
-
- } else {
-
- append.call( list , functor );
- }
- } );
- }
-
- } );
- }
- }
- }
-
- return this;
- }
-
-
-});
-
-// Select a transport given options
-function selectTransport( s ) {
-
- var dataTypes = s.dataTypes,
- transportDataType,
- transportsList,
- transport,
- i,
- length,
- checked = {},
- flag;
-
- function initSearch( dataType ) {
-
- flag = transportDataType !== dataType && ! checked[ dataType ];
-
- if ( flag ) {
-
- checked[ dataType ] = 1;
- transportDataType = dataType;
- transportsList = s.transports[ dataType ];
- i = -1;
- length = transportsList ? transportsList.length : 0 ;
- }
-
- return flag;
- }
-
- initSearch( dataTypes[ 0 ] );
-
- for ( i = 0 ; ! transport && i <= length ; i++ ) {
-
- if ( i === length ) {
-
- initSearch( "*" );
-
- } else {
-
- transport = transportsList[ i ]( s , determineDataType );
-
- // If we got redirected to another dataType
- // Search there (if not in progress or already tried)
- if ( typeof( transport ) === "string" &&
- initSearch( transport ) ) {
-
- dataTypes.unshift( transport );
- transport = 0;
- }
- }
- }
-
- return transport;
-}
-
-// Utility function that handles dataType when response is received
-// (for those transports that can give text or xml responses)
-function determineDataType( s , ct , text , xml ) {
-
- var autoDataType = s.autoDataType,
- type,
- regexp,
- dataTypes = s.dataTypes,
- transportDataType = dataTypes[0],
- response;
-
- // Auto (xml, json, script or text determined given headers)
- if ( transportDataType === "*" ) {
-
- for ( type in autoDataType ) {
- if ( ( regexp = autoDataType[ type ] ) && regexp.test( ct ) ) {
- transportDataType = dataTypes[0] = type;
- break;
- }
- }
- }
-
- // xml and parsed as such
- if ( transportDataType === "xml" &&
- xml &&
- xml.documentElement /* #4958 */ ) {
-
- response = xml;
-
- // Text response was provided
- } else {
-
- response = text;
-
- // If it's not really text, defer to dataConverters
- if ( transportDataType !== "text" ) {
- dataTypes.unshift( "text" );
- }
-
- }
-
- return response;
-}
-
-})( jQuery );