| (function( jQuery ) { |
| |
| var r20 = /%20/g, |
| rbracket = /\[\]$/, |
| rCRLF = /\r?\n/g, |
| rhash = /#.*$/, |
| rheaders = /^(.*?):[ \t]*([^\r\n]*)\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, |
| // #7653, #8125, #8152: local protocol detection |
| rlocalProtocol = /(?:^file|^widget|\-extension):$/, |
| rnoContent = /^(?:GET|HEAD)$/, |
| rprotocol = /^\/\//, |
| rquery = /\?/, |
| rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, |
| rselectTextarea = /^(?:select|textarea)/i, |
| rspacesAjax = /\s+/, |
| rts = /([?&])_=[^&]*/, |
| rucHeaders = /(^|\-)([a-z])/g, |
| rucHeadersFunc = function( _, $1, $2 ) { |
| return $1 + $2.toUpperCase(); |
| }, |
| rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?|\/[^\/])/, |
| |
| // Keep a copy of the old load method |
| _load = jQuery.fn.load, |
| |
| /* Prefilters |
| * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js 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) 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 = {}, |
| |
| // Document location |
| ajaxLocation, |
| |
| // Document location segments |
| ajaxLocParts; |
| |
| // #8138, IE may throw an exception when accessing |
| // a field from document.location if document.domain has been set |
| try { |
| ajaxLocation = document.location.href; |
| } catch( e ) { |
| // Use the href attribute of an A element |
| // since IE will modify it given document.location |
| ajaxLocation = document.createElement( "a" ); |
| ajaxLocation.href = ""; |
| ajaxLocation = ajaxLocation.href; |
| } |
| |
| // Segment location into parts |
| ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ); |
| |
| // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport |
| function addToPrefiltersOrTransports( structure ) { |
| |
| // dataTypeExpression is optional and defaults to "*" |
| return function( dataTypeExpression, func ) { |
| |
| if ( typeof dataTypeExpression !== "string" ) { |
| func = dataTypeExpression; |
| dataTypeExpression = "*"; |
| } |
| |
| if ( jQuery.isFunction( func ) ) { |
| var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ), |
| i = 0, |
| length = dataTypes.length, |
| dataType, |
| list, |
| placeBefore; |
| |
| // For each dataType in the dataTypeExpression |
| for(; i < length; i++ ) { |
| dataType = dataTypes[ i ]; |
| // We control if we're asked to add before |
| // any existing element |
| placeBefore = /^\+/.test( dataType ); |
| if ( placeBefore ) { |
| dataType = dataType.substr( 1 ) || "*"; |
| } |
| list = structure[ dataType ] = structure[ dataType ] || []; |
| // then we add to the structure accordingly |
| list[ placeBefore ? "unshift" : "push" ]( func ); |
| } |
| } |
| }; |
| } |
| |
| //Base inspection function for prefilters and transports |
| function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, |
| dataType /* internal */, inspected /* internal */ ) { |
| |
| dataType = dataType || options.dataTypes[ 0 ]; |
| inspected = inspected || {}; |
| |
| inspected[ dataType ] = true; |
| |
| var list = structure[ dataType ], |
| i = 0, |
| length = list ? list.length : 0, |
| executeOnly = ( structure === prefilters ), |
| selection; |
| |
| for(; i < length && ( executeOnly || !selection ); i++ ) { |
| selection = list[ i ]( options, originalOptions, jqXHR ); |
| // If we got redirected to another dataType |
| // we try there if executing only and not done already |
| if ( typeof selection === "string" ) { |
| if ( !executeOnly || inspected[ selection ] ) { |
| selection = undefined; |
| } else { |
| options.dataTypes.unshift( selection ); |
| selection = inspectPrefiltersOrTransports( |
| structure, options, originalOptions, jqXHR, selection, inspected ); |
| } |
| } |
| } |
| // If we're only executing or nothing was selected |
| // we try the catchall dataType if not done already |
| if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { |
| selection = inspectPrefiltersOrTransports( |
| structure, options, originalOptions, jqXHR, "*", inspected ); |
| } |
| // unnecessary when only executing (prefilters) |
| // but it'll be ignored by the caller in that case |
| return selection; |
| } |
| |
| jQuery.fn.extend({ |
| load: function( url, params, callback ) { |
| if ( typeof url !== "string" && _load ) { |
| return _load.apply( this, arguments ); |
| |
| // Don't do a request if no elements are being requested |
| } else if ( !this.length ) { |
| return this; |
| } |
| |
| var off = url.indexOf( " " ); |
| if ( off >= 0 ) { |
| var selector = url.slice( off, url.length ); |
| url = url.slice( 0, off ); |
| } |
| |
| // Default to a GET request |
| var type = "GET"; |
| |
| // If the second parameter was provided |
| if ( params ) { |
| // If it's a function |
| if ( jQuery.isFunction( params ) ) { |
| // We assume that it's the callback |
| callback = params; |
| params = undefined; |
| |
| // Otherwise, build a param string |
| } else if ( typeof params === "object" ) { |
| params = jQuery.param( params, jQuery.ajaxSettings.traditional ); |
| type = "POST"; |
| } |
| } |
| |
| var self = this; |
| |
| // Request the remote document |
| jQuery.ajax({ |
| url: url, |
| type: type, |
| dataType: "html", |
| data: params, |
| // Complete callback (responseText is used internally) |
| complete: function( jqXHR, status, responseText ) { |
| // Store the response as specified by the jqXHR object |
| responseText = jqXHR.responseText; |
| // If successful, inject the HTML into all the matched elements |
| if ( jqXHR.isResolved() ) { |
| // #4825: Get the actual response in case |
| // a dataFilter is present in ajaxSettings |
| jqXHR.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(responseText.replace(rscript, "")) |
| |
| // Locate the specified elements |
| .find(selector) : |
| |
| // If not, just inject the full result |
| responseText ); |
| } |
| |
| if ( callback ) { |
| self.each( callback, [ responseText, status, jqXHR ] ); |
| } |
| } |
| }); |
| |
| return this; |
| }, |
| |
| serialize: function() { |
| return jQuery.param( this.serializeArray() ); |
| }, |
| |
| serializeArray: function() { |
| return this.map(function(){ |
| return this.elements ? jQuery.makeArray( this.elements ) : this; |
| }) |
| .filter(function(){ |
| return this.name && !this.disabled && |
| ( this.checked || rselectTextarea.test( this.nodeName ) || |
| rinput.test( this.type ) ); |
| }) |
| .map(function( i, elem ){ |
| var val = jQuery( this ).val(); |
| |
| return val == null ? |
| null : |
| jQuery.isArray( val ) ? |
| jQuery.map( val, function( val, i ){ |
| return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; |
| }) : |
| { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; |
| }).get(); |
| } |
| }); |
| |
| // Attach a bunch of functions for handling common AJAX events |
| jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ |
| jQuery.fn[ o ] = function( f ){ |
| return this.bind( o, f ); |
| }; |
| } ); |
| |
| jQuery.each( [ "get", "post" ], function( i, method ) { |
| jQuery[ method ] = function( url, data, callback, type ) { |
| // shift arguments if data argument was omitted |
| if ( jQuery.isFunction( data ) ) { |
| type = type || callback; |
| callback = data; |
| data = undefined; |
| } |
| |
| return jQuery.ajax({ |
| type: method, |
| url: url, |
| data: data, |
| success: callback, |
| dataType: type |
| }); |
| }; |
| } ); |
| |
| jQuery.extend({ |
| |
| getScript: function( url, callback ) { |
| return jQuery.get( url, undefined, callback, "script" ); |
| }, |
| |
| getJSON: function( url, data, callback ) { |
| return jQuery.get( url, data, callback, "json" ); |
| }, |
| |
| // Creates a full fledged settings object into target |
| // with both ajaxSettings and settings fields. |
| // If target is omitted, writes into ajaxSettings. |
| ajaxSetup: function ( target, settings ) { |
| if ( !settings ) { |
| // Only one parameter, we extend ajaxSettings |
| settings = target; |
| target = jQuery.extend( true, jQuery.ajaxSettings, settings ); |
| } else { |
| // target was provided, we extend into it |
| jQuery.extend( true, target, jQuery.ajaxSettings, settings ); |
| } |
| // Flatten fields we don't want deep extended |
| for( var field in { context: 1, url: 1 } ) { |
| if ( field in settings ) { |
| target[ field ] = settings[ field ]; |
| } else if( field in jQuery.ajaxSettings ) { |
| target[ field ] = jQuery.ajaxSettings[ field ]; |
| } |
| } |
| return target; |
| }, |
| |
| ajaxSettings: { |
| url: ajaxLocation, |
| isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), |
| global: true, |
| type: "GET", |
| contentType: "application/x-www-form-urlencoded", |
| processData: true, |
| async: true, |
| /* |
| timeout: 0, |
| data: null, |
| dataType: null, |
| username: null, |
| password: null, |
| cache: null, |
| traditional: false, |
| headers: {}, |
| crossDomain: null, |
| */ |
| |
| accepts: { |
| xml: "application/xml, text/xml", |
| html: "text/html", |
| text: "text/plain", |
| json: "application/json, text/javascript", |
| "*": "*/*" |
| }, |
| |
| contents: { |
| xml: /xml/, |
| html: /html/, |
| json: /json/ |
| }, |
| |
| responseFields: { |
| xml: "responseXML", |
| text: "responseText" |
| }, |
| |
| // List of data converters |
| // 1) key format is "source_type destination_type" (a single space in-between) |
| // 2) the catchall symbol "*" can be used for source_type |
| converters: { |
| |
| // Convert anything to text |
| "* text": window.String, |
| |
| // Text to html (true = no transformation) |
| "text html": true, |
| |
| // Evaluate text as a json expression |
| "text json": jQuery.parseJSON, |
| |
| // Parse text as xml |
| "text xml": jQuery.parseXML |
| } |
| }, |
| |
| ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), |
| ajaxTransport: addToPrefiltersOrTransports( transports ), |
| |
| // Main method |
| ajax: function( url, options ) { |
| |
| // If url is an object, simulate pre-1.5 signature |
| if ( typeof url === "object" ) { |
| options = url; |
| url = undefined; |
| } |
| |
| // Force options to be an object |
| options = options || {}; |
| |
| var // Create the final options object |
| s = jQuery.ajaxSetup( {}, options ), |
| // Callbacks context |
| callbackContext = s.context || s, |
| // Context for global events |
| // It's the callbackContext if one was provided in the options |
| // and if it's a DOM node or a jQuery collection |
| globalEventContext = callbackContext !== s && |
| ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? |
| jQuery( callbackContext ) : jQuery.event, |
| // Deferreds |
| deferred = jQuery.Deferred(), |
| completeDeferred = jQuery._Deferred(), |
| // Status-dependent callbacks |
| statusCode = s.statusCode || {}, |
| // ifModified key |
| ifModifiedKey, |
| // Headers (they are sent all at once) |
| requestHeaders = {}, |
| // Response headers |
| responseHeadersString, |
| responseHeaders, |
| // transport |
| transport, |
| // timeout handle |
| timeoutTimer, |
| // Cross-domain detection vars |
| parts, |
| // The jqXHR state |
| state = 0, |
| // To know if global events are to be dispatched |
| fireGlobals, |
| // Loop variable |
| i, |
| // Fake xhr |
| jqXHR = { |
| |
| readyState: 0, |
| |
| // Caches the header |
| setRequestHeader: function( name, value ) { |
| if ( !state ) { |
| requestHeaders[ name.toLowerCase().replace( rucHeaders, rucHeadersFunc ) ] = value; |
| } |
| return this; |
| }, |
| |
| // Raw string |
| getAllResponseHeaders: function() { |
| return state === 2 ? responseHeadersString : null; |
| }, |
| |
| // Builds headers hashtable if needed |
| getResponseHeader: function( key ) { |
| var match; |
| if ( state === 2 ) { |
| if ( !responseHeaders ) { |
| responseHeaders = {}; |
| while( ( match = rheaders.exec( responseHeadersString ) ) ) { |
| responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; |
| } |
| } |
| match = responseHeaders[ key.toLowerCase() ]; |
| } |
| return match === undefined ? null : match; |
| }, |
| |
| // Overrides response content-type header |
| overrideMimeType: function( type ) { |
| if ( !state ) { |
| s.mimeType = type; |
| } |
| return this; |
| }, |
| |
| // Cancel the request |
| abort: function( statusText ) { |
| statusText = statusText || "abort"; |
| if ( transport ) { |
| transport.abort( statusText ); |
| } |
| 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, responses, headers ) { |
| |
| // Called once |
| if ( state === 2 ) { |
| return; |
| } |
| |
| // State is "done" now |
| state = 2; |
| |
| // Clear timeout if it exists |
| if ( timeoutTimer ) { |
| clearTimeout( timeoutTimer ); |
| } |
| |
| // Dereference transport for early garbage collection |
| // (no matter how long the jqXHR object will be used) |
| transport = undefined; |
| |
| // Cache response headers |
| responseHeadersString = headers || ""; |
| |
| // Set readyState |
| jqXHR.readyState = status ? 4 : 0; |
| |
| var isSuccess, |
| success, |
| error, |
| response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined, |
| lastModified, |
| etag; |
| |
| // 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 ) { |
| |
| if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) { |
| jQuery.lastModified[ ifModifiedKey ] = lastModified; |
| } |
| if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) { |
| jQuery.etag[ ifModifiedKey ] = etag; |
| } |
| } |
| |
| // If not modified |
| if ( status === 304 ) { |
| |
| statusText = "notmodified"; |
| isSuccess = true; |
| |
| // If we have data |
| } else { |
| |
| try { |
| success = ajaxConvert( s, response ); |
| statusText = "success"; |
| isSuccess = true; |
| } catch(e) { |
| // We have a parsererror |
| statusText = "parsererror"; |
| error = e; |
| } |
| } |
| } else { |
| // We extract error from statusText |
| // then normalize statusText and status for non-aborts |
| error = statusText; |
| if( !statusText || status ) { |
| statusText = "error"; |
| if ( status < 0 ) { |
| status = 0; |
| } |
| } |
| } |
| |
| // Set data for the fake xhr object |
| jqXHR.status = status; |
| jqXHR.statusText = statusText; |
| |
| // Success/Error |
| if ( isSuccess ) { |
| deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); |
| } else { |
| deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); |
| } |
| |
| // Status-dependent callbacks |
| jqXHR.statusCode( statusCode ); |
| statusCode = undefined; |
| |
| if ( fireGlobals ) { |
| globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), |
| [ jqXHR, s, isSuccess ? success : error ] ); |
| } |
| |
| // Complete |
| completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] ); |
| |
| if ( fireGlobals ) { |
| globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] ); |
| // Handle the global AJAX counter |
| if ( !( --jQuery.active ) ) { |
| jQuery.event.trigger( "ajaxStop" ); |
| } |
| } |
| } |
| |
| // Attach deferreds |
| deferred.promise( jqXHR ); |
| jqXHR.success = jqXHR.done; |
| jqXHR.error = jqXHR.fail; |
| jqXHR.complete = completeDeferred.done; |
| |
| // Status-dependent callbacks |
| jqXHR.statusCode = function( map ) { |
| if ( map ) { |
| var tmp; |
| if ( state < 2 ) { |
| for( tmp in map ) { |
| statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; |
| } |
| } else { |
| tmp = map[ jqXHR.status ]; |
| jqXHR.then( tmp, tmp ); |
| } |
| } |
| return this; |
| }; |
| |
| // Remove hash character (#7531: and string promotion) |
| // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) |
| // We also use the url parameter if available |
| s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); |
| |
| // Extract dataTypes list |
| s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax ); |
| |
| // Determine if a cross-domain request is in order |
| if ( !s.crossDomain ) { |
| parts = rurl.exec( s.url.toLowerCase() ); |
| s.crossDomain = !!( parts && |
| ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || |
| ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != |
| ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) |
| ); |
| } |
| |
| // Convert data if not already a string |
| if ( s.data && s.processData && typeof s.data !== "string" ) { |
| s.data = jQuery.param( s.data, s.traditional ); |
| } |
| |
| // Apply prefilters |
| inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); |
| |
| // If request was aborted inside a prefiler, stop there |
| if ( state === 2 ) { |
| return false; |
| } |
| |
| // We can fire global events as of now if asked to |
| fireGlobals = s.global; |
| |
| // 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 ( fireGlobals && jQuery.active++ === 0 ) { |
| jQuery.event.trigger( "ajaxStart" ); |
| } |
| |
| // 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; |
| } |
| |
| // Get ifModifiedKey before adding the anti-cache parameter |
| ifModifiedKey = s.url; |
| |
| // 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 ) { |
| ifModifiedKey = ifModifiedKey || s.url; |
| if ( jQuery.lastModified[ ifModifiedKey ] ) { |
| requestHeaders[ "If-Modified-Since" ] = jQuery.lastModified[ ifModifiedKey ]; |
| } |
| if ( jQuery.etag[ ifModifiedKey ] ) { |
| requestHeaders[ "If-None-Match" ] = jQuery.etag[ ifModifiedKey ]; |
| } |
| } |
| |
| // 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 ) { |
| jqXHR.setRequestHeader( i, s.headers[ i ] ); |
| } |
| |
| // Allow custom headers/mimetypes and early abort |
| if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { |
| // Abort if not done already |
| jqXHR.abort(); |
| return false; |
| |
| } |
| |
| // Install callbacks on deferreds |
| for ( i in { success: 1, error: 1, complete: 1 } ) { |
| jqXHR[ i ]( s[ i ] ); |
| } |
| |
| // Get transport |
| transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); |
| |
| // If no transport, we auto-abort |
| if ( !transport ) { |
| done( -1, "No Transport" ); |
| } else { |
| jqXHR.readyState = 1; |
| // Send global event |
| if ( fireGlobals ) { |
| globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); |
| } |
| // Timeout |
| if ( s.async && s.timeout > 0 ) { |
| timeoutTimer = setTimeout( function(){ |
| jqXHR.abort( "timeout" ); |
| }, s.timeout ); |
| } |
| |
| try { |
| state = 1; |
| transport.send( requestHeaders, done ); |
| } catch (e) { |
| // Propagate exception as error if not done |
| if ( status < 2 ) { |
| done( -1, e ); |
| // Simply rethrow otherwise |
| } else { |
| jQuery.error( e ); |
| } |
| } |
| } |
| |
| return jqXHR; |
| }, |
| |
| // Serialize an array of form elements or a set of |
| // key/values into a query string |
| param: function( a, traditional ) { |
| var s = [], |
| add = function( key, value ) { |
| // If value is a function, invoke it and return its value |
| 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 && !jQuery.isPlainObject( a ) ) ) { |
| // 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. |
| for ( var prefix in a ) { |
| buildParams( prefix, a[ prefix ], traditional, add ); |
| } |
| } |
| |
| // Return the resulting serialization |
| return s.join( "&" ).replace( r20, "+" ); |
| } |
| }); |
| |
| function buildParams( prefix, obj, traditional, add ) { |
| if ( jQuery.isArray( obj ) && obj.length ) { |
| // Serialize array item. |
| jQuery.each( obj, function( i, v ) { |
| if ( traditional || rbracket.test( prefix ) ) { |
| // Treat each array item as a scalar. |
| add( prefix, v ); |
| |
| } else { |
| // If array item is non-scalar (array or object), encode its |
| // numeric index to resolve deserialization ambiguity issues. |
| // Note that rack (as of 1.0.0) can't currently deserialize |
| // nested arrays properly, and attempting to do so may cause |
| // a server error. Possible fixes are to modify rack's |
| // deserialization algorithm or to provide an option or flag |
| // to force array serialization to be shallow. |
| buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add ); |
| } |
| }); |
| |
| } else if ( !traditional && obj != null && typeof obj === "object" ) { |
| // 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. |
| } else { |
| for ( var name in obj ) { |
| buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); |
| } |
| } |
| |
| } else { |
| // Serialize scalar item. |
| add( prefix, obj ); |
| } |
| } |
| |
| // This is still on the jQuery object... for now |
| // Want to move this to jQuery.ajax some day |
| jQuery.extend({ |
| |
| // Counter for holding the number of active queries |
| active: 0, |
| |
| // Last-Modified header cache for next request |
| lastModified: {}, |
| etag: {} |
| |
| }); |
| |
| /* Handles responses to an ajax request: |
| * - sets all responseXXX fields accordingly |
| * - finds the right dataType (mediates between content-type and expected dataType) |
| * - returns the corresponding response |
| */ |
| function ajaxHandleResponses( s, jqXHR, responses ) { |
| |
| var contents = s.contents, |
| dataTypes = s.dataTypes, |
| responseFields = s.responseFields, |
| ct, |
| type, |
| finalDataType, |
| firstDataType; |
| |
| // Fill responseXXX fields |
| for( type in responseFields ) { |
| if ( type in responses ) { |
| jqXHR[ responseFields[type] ] = responses[ type ]; |
| } |
| } |
| |
| // Remove auto dataType and get content-type in the process |
| while( dataTypes[ 0 ] === "*" ) { |
| dataTypes.shift(); |
| if ( ct === undefined ) { |
| ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); |
| } |
| } |
| |
| // Check if we're dealing with a known content-type |
| if ( ct ) { |
| for ( type in contents ) { |
| if ( contents[ type ] && contents[ type ].test( ct ) ) { |
| dataTypes.unshift( type ); |
| break; |
| } |
| } |
| } |
| |
| // Check to see if we have a response for the expected dataType |
| if ( dataTypes[ 0 ] in responses ) { |
| finalDataType = dataTypes[ 0 ]; |
| } else { |
| // Try convertible dataTypes |
| for ( type in responses ) { |
| if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { |
| finalDataType = type; |
| break; |
| } |
| if ( !firstDataType ) { |
| firstDataType = type; |
| } |
| } |
| // Or just use first one |
| finalDataType = finalDataType || firstDataType; |
| } |
| |
| // If we found a dataType |
| // We add the dataType to the list if needed |
| // and return the corresponding response |
| if ( finalDataType ) { |
| if ( finalDataType !== dataTypes[ 0 ] ) { |
| dataTypes.unshift( finalDataType ); |
| } |
| return responses[ finalDataType ]; |
| } |
| } |
| |
| // Chain conversions given the request and the original response |
| function ajaxConvert( s, response ) { |
| |
| // Apply the dataFilter if provided |
| if ( s.dataFilter ) { |
| response = s.dataFilter( response, s.dataType ); |
| } |
| |
| var dataTypes = s.dataTypes, |
| converters = {}, |
| i, |
| key, |
| length = dataTypes.length, |
| tmp, |
| // Current and previous dataTypes |
| current = dataTypes[ 0 ], |
| prev, |
| // Conversion expression |
| conversion, |
| // Conversion function |
| conv, |
| // Conversion functions (transitive conversion) |
| conv1, |
| conv2; |
| |
| // For each dataType in the chain |
| for( i = 1; i < length; i++ ) { |
| |
| // Create converters map |
| // with lowercased keys |
| if ( i === 1 ) { |
| for( key in s.converters ) { |
| if( typeof key === "string" ) { |
| converters[ key.toLowerCase() ] = s.converters[ key ]; |
| } |
| } |
| } |
| |
| // Get the dataTypes |
| prev = current; |
| current = dataTypes[ i ]; |
| |
| // If current is auto dataType, update it to prev |
| if( current === "*" ) { |
| current = prev; |
| // If no auto and dataTypes are actually different |
| } else if ( prev !== "*" && prev !== current ) { |
| |
| // Get the converter |
| conversion = prev + " " + current; |
| conv = converters[ conversion ] || converters[ "* " + current ]; |
| |
| // If there is no direct converter, search transitively |
| if ( !conv ) { |
| conv2 = undefined; |
| for( conv1 in converters ) { |
| tmp = conv1.split( " " ); |
| if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) { |
| conv2 = converters[ tmp[1] + " " + current ]; |
| if ( conv2 ) { |
| conv1 = converters[ conv1 ]; |
| if ( conv1 === true ) { |
| conv = conv2; |
| } else if ( conv2 === true ) { |
| conv = conv1; |
| } |
| break; |
| } |
| } |
| } |
| } |
| // If we found no converter, dispatch an error |
| if ( !( conv || conv2 ) ) { |
| jQuery.error( "No conversion from " + conversion.replace(" "," to ") ); |
| } |
| // If found converter is not an equivalence |
| if ( conv !== true ) { |
| // Convert with 1 or 2 converters accordingly |
| response = conv ? conv( response ) : conv2( conv1(response) ); |
| } |
| } |
| } |
| return response; |
| } |
| |
| })( jQuery ); |