Project

General

Profile

1
define( [
2
	"./core",
3
	"./var/document",
4
	"./var/rnothtmlwhite",
5
	"./ajax/var/location",
6
	"./ajax/var/nonce",
7
	"./ajax/var/rquery",
8

    
9
	"./core/init",
10
	"./ajax/parseXML",
11
	"./event/trigger",
12
	"./deferred",
13
	"./serialize" // jQuery.param
14
], function( jQuery, document, rnothtmlwhite, location, nonce, rquery ) {
15

    
16
"use strict";
17

    
18
var
19
	r20 = /%20/g,
20
	rhash = /#.*$/,
21
	rantiCache = /([?&])_=[^&]*/,
22
	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
23

    
24
	// #7653, #8125, #8152: local protocol detection
25
	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
26
	rnoContent = /^(?:GET|HEAD)$/,
27
	rprotocol = /^\/\//,
28

    
29
	/* Prefilters
30
	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
31
	 * 2) These are called:
32
	 *    - BEFORE asking for a transport
33
	 *    - AFTER param serialization (s.data is a string if s.processData is true)
34
	 * 3) key is the dataType
35
	 * 4) the catchall symbol "*" can be used
36
	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
37
	 */
38
	prefilters = {},
39

    
40
	/* Transports bindings
41
	 * 1) key is the dataType
42
	 * 2) the catchall symbol "*" can be used
43
	 * 3) selection will start with transport dataType and THEN go to "*" if needed
44
	 */
45
	transports = {},
46

    
47
	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
48
	allTypes = "*/".concat( "*" ),
49

    
50
	// Anchor tag for parsing the document origin
51
	originAnchor = document.createElement( "a" );
52
	originAnchor.href = location.href;
53

    
54
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
55
function addToPrefiltersOrTransports( structure ) {
56

    
57
	// dataTypeExpression is optional and defaults to "*"
58
	return function( dataTypeExpression, func ) {
59

    
60
		if ( typeof dataTypeExpression !== "string" ) {
61
			func = dataTypeExpression;
62
			dataTypeExpression = "*";
63
		}
64

    
65
		var dataType,
66
			i = 0,
67
			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
68

    
69
		if ( jQuery.isFunction( func ) ) {
70

    
71
			// For each dataType in the dataTypeExpression
72
			while ( ( dataType = dataTypes[ i++ ] ) ) {
73

    
74
				// Prepend if requested
75
				if ( dataType[ 0 ] === "+" ) {
76
					dataType = dataType.slice( 1 ) || "*";
77
					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
78

    
79
				// Otherwise append
80
				} else {
81
					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
82
				}
83
			}
84
		}
85
	};
86
}
87

    
88
// Base inspection function for prefilters and transports
89
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
90

    
91
	var inspected = {},
92
		seekingTransport = ( structure === transports );
93

    
94
	function inspect( dataType ) {
95
		var selected;
96
		inspected[ dataType ] = true;
97
		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
98
			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
99
			if ( typeof dataTypeOrTransport === "string" &&
100
				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
101

    
102
				options.dataTypes.unshift( dataTypeOrTransport );
103
				inspect( dataTypeOrTransport );
104
				return false;
105
			} else if ( seekingTransport ) {
106
				return !( selected = dataTypeOrTransport );
107
			}
108
		} );
109
		return selected;
110
	}
111

    
112
	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
113
}
114

    
115
// A special extend for ajax options
116
// that takes "flat" options (not to be deep extended)
117
// Fixes #9887
118
function ajaxExtend( target, src ) {
119
	var key, deep,
120
		flatOptions = jQuery.ajaxSettings.flatOptions || {};
121

    
122
	for ( key in src ) {
123
		if ( src[ key ] !== undefined ) {
124
			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
125
		}
126
	}
127
	if ( deep ) {
128
		jQuery.extend( true, target, deep );
129
	}
130

    
131
	return target;
132
}
133

    
134
/* Handles responses to an ajax request:
135
 * - finds the right dataType (mediates between content-type and expected dataType)
136
 * - returns the corresponding response
137
 */
138
function ajaxHandleResponses( s, jqXHR, responses ) {
139

    
140
	var ct, type, finalDataType, firstDataType,
141
		contents = s.contents,
142
		dataTypes = s.dataTypes;
143

    
144
	// Remove auto dataType and get content-type in the process
145
	while ( dataTypes[ 0 ] === "*" ) {
146
		dataTypes.shift();
147
		if ( ct === undefined ) {
148
			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
149
		}
150
	}
151

    
152
	// Check if we're dealing with a known content-type
153
	if ( ct ) {
154
		for ( type in contents ) {
155
			if ( contents[ type ] && contents[ type ].test( ct ) ) {
156
				dataTypes.unshift( type );
157
				break;
158
			}
159
		}
160
	}
161

    
162
	// Check to see if we have a response for the expected dataType
163
	if ( dataTypes[ 0 ] in responses ) {
164
		finalDataType = dataTypes[ 0 ];
165
	} else {
166

    
167
		// Try convertible dataTypes
168
		for ( type in responses ) {
169
			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
170
				finalDataType = type;
171
				break;
172
			}
173
			if ( !firstDataType ) {
174
				firstDataType = type;
175
			}
176
		}
177

    
178
		// Or just use first one
179
		finalDataType = finalDataType || firstDataType;
180
	}
181

    
182
	// If we found a dataType
183
	// We add the dataType to the list if needed
184
	// and return the corresponding response
185
	if ( finalDataType ) {
186
		if ( finalDataType !== dataTypes[ 0 ] ) {
187
			dataTypes.unshift( finalDataType );
188
		}
189
		return responses[ finalDataType ];
190
	}
191
}
192

    
193
/* Chain conversions given the request and the original response
194
 * Also sets the responseXXX fields on the jqXHR instance
195
 */
196
function ajaxConvert( s, response, jqXHR, isSuccess ) {
197
	var conv2, current, conv, tmp, prev,
198
		converters = {},
199

    
200
		// Work with a copy of dataTypes in case we need to modify it for conversion
201
		dataTypes = s.dataTypes.slice();
202

    
203
	// Create converters map with lowercased keys
204
	if ( dataTypes[ 1 ] ) {
205
		for ( conv in s.converters ) {
206
			converters[ conv.toLowerCase() ] = s.converters[ conv ];
207
		}
208
	}
209

    
210
	current = dataTypes.shift();
211

    
212
	// Convert to each sequential dataType
213
	while ( current ) {
214

    
215
		if ( s.responseFields[ current ] ) {
216
			jqXHR[ s.responseFields[ current ] ] = response;
217
		}
218

    
219
		// Apply the dataFilter if provided
220
		if ( !prev && isSuccess && s.dataFilter ) {
221
			response = s.dataFilter( response, s.dataType );
222
		}
223

    
224
		prev = current;
225
		current = dataTypes.shift();
226

    
227
		if ( current ) {
228

    
229
			// There's only work to do if current dataType is non-auto
230
			if ( current === "*" ) {
231

    
232
				current = prev;
233

    
234
			// Convert response if prev dataType is non-auto and differs from current
235
			} else if ( prev !== "*" && prev !== current ) {
236

    
237
				// Seek a direct converter
238
				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
239

    
240
				// If none found, seek a pair
241
				if ( !conv ) {
242
					for ( conv2 in converters ) {
243

    
244
						// If conv2 outputs current
245
						tmp = conv2.split( " " );
246
						if ( tmp[ 1 ] === current ) {
247

    
248
							// If prev can be converted to accepted input
249
							conv = converters[ prev + " " + tmp[ 0 ] ] ||
250
								converters[ "* " + tmp[ 0 ] ];
251
							if ( conv ) {
252

    
253
								// Condense equivalence converters
254
								if ( conv === true ) {
255
									conv = converters[ conv2 ];
256

    
257
								// Otherwise, insert the intermediate dataType
258
								} else if ( converters[ conv2 ] !== true ) {
259
									current = tmp[ 0 ];
260
									dataTypes.unshift( tmp[ 1 ] );
261
								}
262
								break;
263
							}
264
						}
265
					}
266
				}
267

    
268
				// Apply converter (if not an equivalence)
269
				if ( conv !== true ) {
270

    
271
					// Unless errors are allowed to bubble, catch and return them
272
					if ( conv && s.throws ) {
273
						response = conv( response );
274
					} else {
275
						try {
276
							response = conv( response );
277
						} catch ( e ) {
278
							return {
279
								state: "parsererror",
280
								error: conv ? e : "No conversion from " + prev + " to " + current
281
							};
282
						}
283
					}
284
				}
285
			}
286
		}
287
	}
288

    
289
	return { state: "success", data: response };
290
}
291

    
292
jQuery.extend( {
293

    
294
	// Counter for holding the number of active queries
295
	active: 0,
296

    
297
	// Last-Modified header cache for next request
298
	lastModified: {},
299
	etag: {},
300

    
301
	ajaxSettings: {
302
		url: location.href,
303
		type: "GET",
304
		isLocal: rlocalProtocol.test( location.protocol ),
305
		global: true,
306
		processData: true,
307
		async: true,
308
		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
309

    
310
		/*
311
		timeout: 0,
312
		data: null,
313
		dataType: null,
314
		username: null,
315
		password: null,
316
		cache: null,
317
		throws: false,
318
		traditional: false,
319
		headers: {},
320
		*/
321

    
322
		accepts: {
323
			"*": allTypes,
324
			text: "text/plain",
325
			html: "text/html",
326
			xml: "application/xml, text/xml",
327
			json: "application/json, text/javascript"
328
		},
329

    
330
		contents: {
331
			xml: /\bxml\b/,
332
			html: /\bhtml/,
333
			json: /\bjson\b/
334
		},
335

    
336
		responseFields: {
337
			xml: "responseXML",
338
			text: "responseText",
339
			json: "responseJSON"
340
		},
341

    
342
		// Data converters
343
		// Keys separate source (or catchall "*") and destination types with a single space
344
		converters: {
345

    
346
			// Convert anything to text
347
			"* text": String,
348

    
349
			// Text to html (true = no transformation)
350
			"text html": true,
351

    
352
			// Evaluate text as a json expression
353
			"text json": JSON.parse,
354

    
355
			// Parse text as xml
356
			"text xml": jQuery.parseXML
357
		},
358

    
359
		// For options that shouldn't be deep extended:
360
		// you can add your own custom options here if
361
		// and when you create one that shouldn't be
362
		// deep extended (see ajaxExtend)
363
		flatOptions: {
364
			url: true,
365
			context: true
366
		}
367
	},
368

    
369
	// Creates a full fledged settings object into target
370
	// with both ajaxSettings and settings fields.
371
	// If target is omitted, writes into ajaxSettings.
372
	ajaxSetup: function( target, settings ) {
373
		return settings ?
374

    
375
			// Building a settings object
376
			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
377

    
378
			// Extending ajaxSettings
379
			ajaxExtend( jQuery.ajaxSettings, target );
380
	},
381

    
382
	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
383
	ajaxTransport: addToPrefiltersOrTransports( transports ),
384

    
385
	// Main method
386
	ajax: function( url, options ) {
387

    
388
		// If url is an object, simulate pre-1.5 signature
389
		if ( typeof url === "object" ) {
390
			options = url;
391
			url = undefined;
392
		}
393

    
394
		// Force options to be an object
395
		options = options || {};
396

    
397
		var transport,
398

    
399
			// URL without anti-cache param
400
			cacheURL,
401

    
402
			// Response headers
403
			responseHeadersString,
404
			responseHeaders,
405

    
406
			// timeout handle
407
			timeoutTimer,
408

    
409
			// Url cleanup var
410
			urlAnchor,
411

    
412
			// Request state (becomes false upon send and true upon completion)
413
			completed,
414

    
415
			// To know if global events are to be dispatched
416
			fireGlobals,
417

    
418
			// Loop variable
419
			i,
420

    
421
			// uncached part of the url
422
			uncached,
423

    
424
			// Create the final options object
425
			s = jQuery.ajaxSetup( {}, options ),
426

    
427
			// Callbacks context
428
			callbackContext = s.context || s,
429

    
430
			// Context for global events is callbackContext if it is a DOM node or jQuery collection
431
			globalEventContext = s.context &&
432
				( callbackContext.nodeType || callbackContext.jquery ) ?
433
					jQuery( callbackContext ) :
434
					jQuery.event,
435

    
436
			// Deferreds
437
			deferred = jQuery.Deferred(),
438
			completeDeferred = jQuery.Callbacks( "once memory" ),
439

    
440
			// Status-dependent callbacks
441
			statusCode = s.statusCode || {},
442

    
443
			// Headers (they are sent all at once)
444
			requestHeaders = {},
445
			requestHeadersNames = {},
446

    
447
			// Default abort message
448
			strAbort = "canceled",
449

    
450
			// Fake xhr
451
			jqXHR = {
452
				readyState: 0,
453

    
454
				// Builds headers hashtable if needed
455
				getResponseHeader: function( key ) {
456
					var match;
457
					if ( completed ) {
458
						if ( !responseHeaders ) {
459
							responseHeaders = {};
460
							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
461
								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
462
							}
463
						}
464
						match = responseHeaders[ key.toLowerCase() ];
465
					}
466
					return match == null ? null : match;
467
				},
468

    
469
				// Raw string
470
				getAllResponseHeaders: function() {
471
					return completed ? responseHeadersString : null;
472
				},
473

    
474
				// Caches the header
475
				setRequestHeader: function( name, value ) {
476
					if ( completed == null ) {
477
						name = requestHeadersNames[ name.toLowerCase() ] =
478
							requestHeadersNames[ name.toLowerCase() ] || name;
479
						requestHeaders[ name ] = value;
480
					}
481
					return this;
482
				},
483

    
484
				// Overrides response content-type header
485
				overrideMimeType: function( type ) {
486
					if ( completed == null ) {
487
						s.mimeType = type;
488
					}
489
					return this;
490
				},
491

    
492
				// Status-dependent callbacks
493
				statusCode: function( map ) {
494
					var code;
495
					if ( map ) {
496
						if ( completed ) {
497

    
498
							// Execute the appropriate callbacks
499
							jqXHR.always( map[ jqXHR.status ] );
500
						} else {
501

    
502
							// Lazy-add the new callbacks in a way that preserves old ones
503
							for ( code in map ) {
504
								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
505
							}
506
						}
507
					}
508
					return this;
509
				},
510

    
511
				// Cancel the request
512
				abort: function( statusText ) {
513
					var finalText = statusText || strAbort;
514
					if ( transport ) {
515
						transport.abort( finalText );
516
					}
517
					done( 0, finalText );
518
					return this;
519
				}
520
			};
521

    
522
		// Attach deferreds
523
		deferred.promise( jqXHR );
524

    
525
		// Add protocol if not provided (prefilters might expect it)
526
		// Handle falsy url in the settings object (#10093: consistency with old signature)
527
		// We also use the url parameter if available
528
		s.url = ( ( url || s.url || location.href ) + "" )
529
			.replace( rprotocol, location.protocol + "//" );
530

    
531
		// Alias method option to type as per ticket #12004
532
		s.type = options.method || options.type || s.method || s.type;
533

    
534
		// Extract dataTypes list
535
		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
536

    
537
		// A cross-domain request is in order when the origin doesn't match the current origin.
538
		if ( s.crossDomain == null ) {
539
			urlAnchor = document.createElement( "a" );
540

    
541
			// Support: IE <=8 - 11, Edge 12 - 13
542
			// IE throws exception on accessing the href property if url is malformed,
543
			// e.g. http://example.com:80x/
544
			try {
545
				urlAnchor.href = s.url;
546

    
547
				// Support: IE <=8 - 11 only
548
				// Anchor's host property isn't correctly set when s.url is relative
549
				urlAnchor.href = urlAnchor.href;
550
				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
551
					urlAnchor.protocol + "//" + urlAnchor.host;
552
			} catch ( e ) {
553

    
554
				// If there is an error parsing the URL, assume it is crossDomain,
555
				// it can be rejected by the transport if it is invalid
556
				s.crossDomain = true;
557
			}
558
		}
559

    
560
		// Convert data if not already a string
561
		if ( s.data && s.processData && typeof s.data !== "string" ) {
562
			s.data = jQuery.param( s.data, s.traditional );
563
		}
564

    
565
		// Apply prefilters
566
		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
567

    
568
		// If request was aborted inside a prefilter, stop there
569
		if ( completed ) {
570
			return jqXHR;
571
		}
572

    
573
		// We can fire global events as of now if asked to
574
		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
575
		fireGlobals = jQuery.event && s.global;
576

    
577
		// Watch for a new set of requests
578
		if ( fireGlobals && jQuery.active++ === 0 ) {
579
			jQuery.event.trigger( "ajaxStart" );
580
		}
581

    
582
		// Uppercase the type
583
		s.type = s.type.toUpperCase();
584

    
585
		// Determine if request has content
586
		s.hasContent = !rnoContent.test( s.type );
587

    
588
		// Save the URL in case we're toying with the If-Modified-Since
589
		// and/or If-None-Match header later on
590
		// Remove hash to simplify url manipulation
591
		cacheURL = s.url.replace( rhash, "" );
592

    
593
		// More options handling for requests with no content
594
		if ( !s.hasContent ) {
595

    
596
			// Remember the hash so we can put it back
597
			uncached = s.url.slice( cacheURL.length );
598

    
599
			// If data is available, append data to url
600
			if ( s.data ) {
601
				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
602

    
603
				// #9682: remove data so that it's not used in an eventual retry
604
				delete s.data;
605
			}
606

    
607
			// Add or update anti-cache param if needed
608
			if ( s.cache === false ) {
609
				cacheURL = cacheURL.replace( rantiCache, "$1" );
610
				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
611
			}
612

    
613
			// Put hash and anti-cache on the URL that will be requested (gh-1732)
614
			s.url = cacheURL + uncached;
615

    
616
		// Change '%20' to '+' if this is encoded form body content (gh-2658)
617
		} else if ( s.data && s.processData &&
618
			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
619
			s.data = s.data.replace( r20, "+" );
620
		}
621

    
622
		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
623
		if ( s.ifModified ) {
624
			if ( jQuery.lastModified[ cacheURL ] ) {
625
				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
626
			}
627
			if ( jQuery.etag[ cacheURL ] ) {
628
				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
629
			}
630
		}
631

    
632
		// Set the correct header, if data is being sent
633
		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
634
			jqXHR.setRequestHeader( "Content-Type", s.contentType );
635
		}
636

    
637
		// Set the Accepts header for the server, depending on the dataType
638
		jqXHR.setRequestHeader(
639
			"Accept",
640
			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
641
				s.accepts[ s.dataTypes[ 0 ] ] +
642
					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
643
				s.accepts[ "*" ]
644
		);
645

    
646
		// Check for headers option
647
		for ( i in s.headers ) {
648
			jqXHR.setRequestHeader( i, s.headers[ i ] );
649
		}
650

    
651
		// Allow custom headers/mimetypes and early abort
652
		if ( s.beforeSend &&
653
			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
654

    
655
			// Abort if not done already and return
656
			return jqXHR.abort();
657
		}
658

    
659
		// Aborting is no longer a cancellation
660
		strAbort = "abort";
661

    
662
		// Install callbacks on deferreds
663
		completeDeferred.add( s.complete );
664
		jqXHR.done( s.success );
665
		jqXHR.fail( s.error );
666

    
667
		// Get transport
668
		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
669

    
670
		// If no transport, we auto-abort
671
		if ( !transport ) {
672
			done( -1, "No Transport" );
673
		} else {
674
			jqXHR.readyState = 1;
675

    
676
			// Send global event
677
			if ( fireGlobals ) {
678
				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
679
			}
680

    
681
			// If request was aborted inside ajaxSend, stop there
682
			if ( completed ) {
683
				return jqXHR;
684
			}
685

    
686
			// Timeout
687
			if ( s.async && s.timeout > 0 ) {
688
				timeoutTimer = window.setTimeout( function() {
689
					jqXHR.abort( "timeout" );
690
				}, s.timeout );
691
			}
692

    
693
			try {
694
				completed = false;
695
				transport.send( requestHeaders, done );
696
			} catch ( e ) {
697

    
698
				// Rethrow post-completion exceptions
699
				if ( completed ) {
700
					throw e;
701
				}
702

    
703
				// Propagate others as results
704
				done( -1, e );
705
			}
706
		}
707

    
708
		// Callback for when everything is done
709
		function done( status, nativeStatusText, responses, headers ) {
710
			var isSuccess, success, error, response, modified,
711
				statusText = nativeStatusText;
712

    
713
			// Ignore repeat invocations
714
			if ( completed ) {
715
				return;
716
			}
717

    
718
			completed = true;
719

    
720
			// Clear timeout if it exists
721
			if ( timeoutTimer ) {
722
				window.clearTimeout( timeoutTimer );
723
			}
724

    
725
			// Dereference transport for early garbage collection
726
			// (no matter how long the jqXHR object will be used)
727
			transport = undefined;
728

    
729
			// Cache response headers
730
			responseHeadersString = headers || "";
731

    
732
			// Set readyState
733
			jqXHR.readyState = status > 0 ? 4 : 0;
734

    
735
			// Determine if successful
736
			isSuccess = status >= 200 && status < 300 || status === 304;
737

    
738
			// Get response data
739
			if ( responses ) {
740
				response = ajaxHandleResponses( s, jqXHR, responses );
741
			}
742

    
743
			// Convert no matter what (that way responseXXX fields are always set)
744
			response = ajaxConvert( s, response, jqXHR, isSuccess );
745

    
746
			// If successful, handle type chaining
747
			if ( isSuccess ) {
748

    
749
				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
750
				if ( s.ifModified ) {
751
					modified = jqXHR.getResponseHeader( "Last-Modified" );
752
					if ( modified ) {
753
						jQuery.lastModified[ cacheURL ] = modified;
754
					}
755
					modified = jqXHR.getResponseHeader( "etag" );
756
					if ( modified ) {
757
						jQuery.etag[ cacheURL ] = modified;
758
					}
759
				}
760

    
761
				// if no content
762
				if ( status === 204 || s.type === "HEAD" ) {
763
					statusText = "nocontent";
764

    
765
				// if not modified
766
				} else if ( status === 304 ) {
767
					statusText = "notmodified";
768

    
769
				// If we have data, let's convert it
770
				} else {
771
					statusText = response.state;
772
					success = response.data;
773
					error = response.error;
774
					isSuccess = !error;
775
				}
776
			} else {
777

    
778
				// Extract error from statusText and normalize for non-aborts
779
				error = statusText;
780
				if ( status || !statusText ) {
781
					statusText = "error";
782
					if ( status < 0 ) {
783
						status = 0;
784
					}
785
				}
786
			}
787

    
788
			// Set data for the fake xhr object
789
			jqXHR.status = status;
790
			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
791

    
792
			// Success/Error
793
			if ( isSuccess ) {
794
				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
795
			} else {
796
				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
797
			}
798

    
799
			// Status-dependent callbacks
800
			jqXHR.statusCode( statusCode );
801
			statusCode = undefined;
802

    
803
			if ( fireGlobals ) {
804
				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
805
					[ jqXHR, s, isSuccess ? success : error ] );
806
			}
807

    
808
			// Complete
809
			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
810

    
811
			if ( fireGlobals ) {
812
				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
813

    
814
				// Handle the global AJAX counter
815
				if ( !( --jQuery.active ) ) {
816
					jQuery.event.trigger( "ajaxStop" );
817
				}
818
			}
819
		}
820

    
821
		return jqXHR;
822
	},
823

    
824
	getJSON: function( url, data, callback ) {
825
		return jQuery.get( url, data, callback, "json" );
826
	},
827

    
828
	getScript: function( url, callback ) {
829
		return jQuery.get( url, undefined, callback, "script" );
830
	}
831
} );
832

    
833
jQuery.each( [ "get", "post" ], function( i, method ) {
834
	jQuery[ method ] = function( url, data, callback, type ) {
835

    
836
		// Shift arguments if data argument was omitted
837
		if ( jQuery.isFunction( data ) ) {
838
			type = type || callback;
839
			callback = data;
840
			data = undefined;
841
		}
842

    
843
		// The url can be an options object (which then must have .url)
844
		return jQuery.ajax( jQuery.extend( {
845
			url: url,
846
			type: method,
847
			dataType: type,
848
			data: data,
849
			success: callback
850
		}, jQuery.isPlainObject( url ) && url ) );
851
	};
852
} );
853

    
854
return jQuery;
855
} );
(2-2/22)