};
});
+var jsc = (new Date).getTime();
+
jQuery.extend({
/**
* @see ajaxSetup(Map)
*/
ajax: function( s ) {
+ var jsonp, jsre = /=(\?|%3F)/g, status, data;
+
// Extend the settings, but re-extend 's' so that it can be
// checked again later (in the test suite, specifically)
s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
- // if data available
- if ( s.data ) {
- // convert data if not already a string
- if ( s.processData && typeof s.data != "string" )
- s.data = jQuery.param(s.data);
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data != "string" )
+ s.data = jQuery.param(s.data);
- // append data to url for get requests
- if ( s.type.toLowerCase() == "get" ) {
- // "?" + data or "&" + data (in case there are already params)
- s.url += (s.url.indexOf("?") > -1 ? "&" : "?") + s.data;
+ // Break the data into one single string
+ var q = s.url.indexOf("?");
+ if ( q > -1 ) {
+ s.data = (s.data ? s.data + "&" : "") + s.url.slice(q + 1);
+ s.url = s.url.slice(0, q);
+ }
- // IE likes to send both get and post data, prevent this
- s.data = null;
- }
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType == "jsonp" ) {
+ if ( !s.data || !s.data.match(jsre) )
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType == "json" && s.data && s.data.match(jsre) ) {
+ jsonp = "jsonp" + jsc++;
+ s.data = s.data.replace(jsre, "=" + jsonp);
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = function(tmp){
+ data = tmp;
+ success();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+ try{ delete window[ jsonp ]; } catch(e){}
+ };
+ }
+
+ if ( s.dataType == "script" && s.cache == null )
+ s.cache = false;
+
+ if ( s.cache === false && s.type.toLowerCase() == "get" )
+ s.data = (s.data ? s.data + "&" : "") + "_=" + (new Date()).getTime();
+
+ // If data is available, append data to url for get requests
+ if ( s.data && s.type.toLowerCase() == "get" ) {
+ s.url += "?" + s.data;
+
+ // IE likes to send both get and post data, prevent this
+ s.data = null;
}
// Watch for a new set of requests
if ( s.global && ! jQuery.active++ )
jQuery.event.trigger( "ajaxStart" );
+ // If we're requesting a remote document
+ // and trying to load JSON or Script
+ if ( !s.url.indexOf("http") && s.dataType == "script" ) {
+ var script = document.createElement("script");
+ script.src = s.url;
+
+ // Handle Script loading
+ if ( !jsonp && (s.success || s.complete) ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState ||
+ this.readyState == "loaded" || this.readyState == "complete") ) {
+ done = true;
+ success();
+ complete();
+ document.body.removeChild( script );
+ }
+ };
+ }
+
+ document.body.appendChild(script);
+
+ // We handle everything using the script element injection
+ return;
+ }
+
var requestDone = false;
// Create the request object; Microsoft failed to properly
xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
// Allow custom headers/mimetypes
- if( s.beforeSend )
+ if ( s.beforeSend )
s.beforeSend(xml);
if ( s.global )
ival = null;
}
- var status = isTimeout == "timeout" && "timeout" ||
+ status = isTimeout == "timeout" && "timeout" ||
!jQuery.httpSuccess( xml ) && "error" ||
s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" ||
"success";
// Watch for, and catch, XML document parse errors
try {
// process the data (runs the xml through httpData regardless of callback)
- var data = jQuery.httpData( xml, s.dataType );
+ data = jQuery.httpData( xml, s.dataType );
} catch(e) {
status = "parsererror";
}
if ( s.ifModified && modRes )
jQuery.lastModified[s.url] = modRes;
-
- // If a local callback was specified, fire it and pass it the data
- if ( s.success )
- s.success( data, status );
-
- // Fire the global callback
- if ( s.global )
- jQuery.event.trigger( "ajaxSuccess", [xml, s] );
+
+ // JSONP handles its own success callback
+ if ( !jsonp )
+ success();
} else
jQuery.handleError(s, xml, status);
- // The request was completed
- if( s.global )
- jQuery.event.trigger( "ajaxComplete", [xml, s] );
-
- // Handle the global AJAX counter
- if ( s.global && ! --jQuery.active )
- jQuery.event.trigger( "ajaxStop" );
-
- // Process result
- if ( s.complete )
- s.complete(xml, status);
+ // Fire the complete handlers
+ complete();
// Stop memory leaks
- if(s.async)
+ if ( s.async )
xml = null;
}
};
// return XMLHttpRequest to allow aborting the request etc.
return xml;
+
+ function success(){
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success )
+ s.success( data, status );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxSuccess", [xml, s] );
+ }
+
+ function complete(){
+ // Process result
+ if ( s.complete )
+ s.complete(xml, status);
+
+ // The request was completed
+ if ( s.global )
+ jQuery.event.trigger( "ajaxComplete", [xml, s] );
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
},
handleError: function( s, xml, status, e ) {
httpData: function( r, type ) {
var ct = r.getResponseHeader("content-type");
var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
- data = xml ? r.responseXML : r.responseText;
+ var data = xml ? r.responseXML : r.responseText;
if ( xml && data.documentElement.tagName == "parsererror" )
throw "parsererror";
// Safari 3 randomly crashes when running these tests,
// but only in the full suite - you can run just the Ajax
// tests and they'll pass
-if ( !jQuery.browser.safari ) {
+//if ( !jQuery.browser.safari ) {
+
+test("$.ajax() - success callbacks", function() {
+ expect( 8 );
+
+ $.ajaxSetup({ timeout: 0 });
+
+ stop();
+
+ setTimeout(function(){
+ $('#foo').ajaxStart(function(){
+ ok( true, "ajaxStart" );
+ }).ajaxStop(function(){
+ ok( true, "ajaxStop" );
+ start();
+ }).ajaxSend(function(){
+ ok( true, "ajaxSend" );
+ }).ajaxComplete(function(){
+ ok( true, "ajaxComplete" );
+ }).ajaxError(function(){
+ ok( false, "ajaxError" );
+ }).ajaxSuccess(function(){
+ ok( true, "ajaxSuccess" );
+ });
+
+ $.ajax({
+ url: url("data/name.html"),
+ beforeSend: function(){ ok(true, "beforeSend"); },
+ success: function(){ ok(true, "success"); },
+ error: function(){ ok(false, "error"); },
+ complete: function(){ ok(true, "complete"); }
+ });
+ }, 13);
+});
+
+if ( !isLocal ) {
+ test("$.ajax() - error callbacks", function() {
+ expect( 8 );
+ stop();
+
+ $('#foo').ajaxStart(function(){
+ ok( true, "ajaxStart" );
+ }).ajaxStop(function(){
+ ok( true, "ajaxStop" );
+ start();
+ }).ajaxSend(function(){
+ ok( true, "ajaxSend" );
+ }).ajaxComplete(function(){
+ ok( true, "ajaxComplete" );
+ }).ajaxError(function(){
+ ok( true, "ajaxError" );
+ }).ajaxSuccess(function(){
+ ok( false, "ajaxSuccess" );
+ });
+
+ $.ajaxSetup({ timeout: 500 });
+
+ $.ajax({
+ url: url("data/name.php?wait=5"),
+ beforeSend: function(){ ok(true, "beforeSend"); },
+ success: function(){ ok(false, "success"); },
+ error: function(){ ok(true, "error"); },
+ complete: function(){ ok(true, "complete"); }
+ });
+ });
+}
+
+test("$.ajax() - disabled globals", function() {
+ expect( 3 );
+ stop();
+
+ $('#foo').ajaxStart(function(){
+ ok( false, "ajaxStart" );
+ }).ajaxStop(function(){
+ ok( false, "ajaxStop" );
+ }).ajaxSend(function(){
+ ok( false, "ajaxSend" );
+ }).ajaxComplete(function(){
+ ok( false, "ajaxComplete" );
+ }).ajaxError(function(){
+ ok( false, "ajaxError" );
+ }).ajaxSuccess(function(){
+ ok( false, "ajaxSuccess" );
+ });
+
+ $.ajax({
+ global: false,
+ url: url("data/name.html"),
+ beforeSend: function(){ ok(true, "beforeSend"); },
+ success: function(){ ok(true, "success"); },
+ error: function(){ ok(false, "error"); },
+ complete: function(){
+ ok(true, "complete");
+ setTimeout(function(){ start(); }, 13);
+ }
+ });
+});
+
+test("$.ajax - xml: non-namespace elements inside namespaced elements", function() {
+ expect(3);
+ stop();
+ $.ajax({
+ url: url("data/with_fries.xml"),
+ dataType: "xml",
+ success: function(resp) {
+ equals( $("properties", resp).length, 1, 'properties in responseXML' );
+ equals( $("jsconf", resp).length, 1, 'jsconf in responseXML' );
+ equals( $("thing", resp).length, 2, 'things in responseXML' );
+ start();
+ }
+ });
+});
+
+test("$.ajax - beforeSend", function() {
+ expect(1);
+ stop();
+
+ var check = false;
+
+ $.ajaxSetup({ timeout: 0 });
+
+ $.ajax({
+ url: url("data/name.html"),
+ beforeSend: function(xml) {
+ check = true;
+ },
+ success: function(data) {
+ ok( check, "check beforeSend was executed" );
+ start();
+ }
+ });
+});
+
+var foobar;
+
+test("$.ajax - dataType html", function() {
+ expect(5);
+ stop();
+
+ foobar = null;
+ testFoo = undefined;
+
+ var verifyEvaluation = function() {
+ ok( testFoo == "foo", 'Check if script was evaluated for datatype html' );
+ ok( foobar == "bar", 'Check if script src was evaluated for datatype html' );
+ start();
+ };
+
+ $.ajax({
+ dataType: "html",
+ url: url("data/test.html"),
+ success: function(data) {
+ $("#ap").html(data);
+ ok( data.match(/^html text/), 'Check content for datatype html' );
+ setTimeout(verifyEvaluation, 600);
+ }
+ });
+});
test("serialize()", function() {
expect(1);
expect(3);
var tmp = jQuery.extend({}, jQuery.ajaxSettings);
- var orig = { url: "data/with_fries.xml", data: null };
+ var orig = { url: "data/with_fries.xml", data: null };
var t;
$.ajaxSetup({ data: {foo: 'bar', bar: 'BAR'} });
- t = jQuery.extend({}, orig);
- $.ajax(t);
+ t = jQuery.extend({}, orig);
+ $.ajax(t);
ok( t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending null" );
- t = jQuery.extend({}, orig);
+ t = jQuery.extend({}, orig);
t.data = {};
- $.ajax(t);
+ $.ajax(t);
ok( t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending {}" );
- t = jQuery.extend({}, orig);
+ t = jQuery.extend({}, orig);
t.data = { zoo: 'a', ping: 'b' };
- $.ajax(t);
+ $.ajax(t);
ok( t.url.indexOf('ping') > -1 && t.url.indexOf('zoo') > -1 && t.url.indexOf('foo') > -1 && t.url.indexOf('bar') > -1, "Check extending { zoo: 'a', ping: 'b' }" );
jQuery.ajaxSettings = tmp;
$.getScript(url("data/test.js"), start);
});
-test("$.ajax - xml: non-namespace elements inside namespaced elements", function() {
- expect(3);
+if ( !isLocal ) {
+
+test("$.ajax() - JSONP, Local", function() {
+ expect(7);
+
+ var count = 0;
+ function plus(){ if ( ++count == 7 ) start(); }
+
stop();
+
$.ajax({
- url: url("data/with_fries.xml"),
- dataType: "xml",
- success: function(resp) {
- equals( $("properties", resp).length, 1, 'properties in responseXML' );
- equals( $("jsconf", resp).length, 1, 'jsconf in responseXML' );
- equals( $("thing", resp).length, 2, 'things in responseXML' );
- start();
- }
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, no callback)" );
+ plus();
+ }
});
-});
-test("test global handlers - success", function() {
- expect( isLocal ? 4 : 8 );
- stop();
-
- var counter = { complete: 0, success: 0, error: 0, send: 0 },
- success = function() { counter.success++ },
- error = function() { counter.error++ },
- complete = function() { counter.complete++ },
- send = function() { counter.send++ };
+ $.ajax({
+ url: "data/jsonp.php?callback=?",
+ dataType: "jsonp",
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, url callback)" );
+ plus();
+ }
+ });
- $('#foo').ajaxStart(complete).ajaxStop(complete).ajaxSend(send).ajaxComplete(complete).ajaxError(error).ajaxSuccess(success);
-
- // start with successful test
- $.ajax({url: url("data/name.html"), beforeSend: send, success: success, error: error, complete: function() {
- equals( counter.error, 0, 'Check succesful request, error callback' );
- equals( counter.success, 2, 'Check succesful request, success callback' );
- equals( counter.complete, 3, 'Check succesful request, complete callback' );
- equals( counter.send, 2, 'Check succesful request, send callback' );
-
- if ( !isLocal ) {
- counter.error = counter.success = counter.complete = counter.send = 0;
- $.ajaxTimeout(500);
-
- $.ajax({url: url("data/name.php?wait=5"), beforeSend: send, success: success, error: error, complete: function() {
- equals( counter.error, 2, 'Check failed request, error callback' );
- equals( counter.success, 0, 'Check failed request, success callback' );
- equals( counter.complete, 3, 'Check failed request, failed callback' );
- equals( counter.send, 2, 'Check failed request, send callback' );
- start();
- }});
- } else
- start();
- }});
-});
+ $.ajax({
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ data: "callback=?",
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, data callback)" );
+ plus();
+ }
+ });
-test("test global handlers - failure", function() {
- expect( isLocal ? 4 : 8 );
- stop();
-
- var counter = { complete: 0, success: 0, error: 0, send: 0 },
- success = function() { counter.success++ },
- error = function() { counter.error++ },
- complete = function() { counter.complete++ },
- send = function() { counter.send++ };
-
- $.ajaxTimeout(0);
-
- $('#foo').ajaxStart(complete).ajaxStop(complete).ajaxSend(send).ajaxComplete(complete).ajaxError(error).ajaxSuccess(success);
-
- $.ajax({url: url("data/name.php"), global: false, beforeSend: send, success: success, error: error, complete: function() {
- ok( counter.error == 0, 'Check sucesful request without globals' );
- ok( counter.success == 1, 'Check sucesful request without globals' );
- ok( counter.complete == 0, 'Check sucesful request without globals' );
- ok( counter.send == 1, 'Check sucesful request without globals' );
-
- if ( !isLocal ) {
- counter.error = counter.success = counter.complete = counter.send = 0;
- $.ajaxTimeout(500);
-
- $.ajax({url: url("data/name.php?wait=5"), global: false, beforeSend: send, success: success, error: error, complete: function() {
- var x = counter;
- ok( counter.error == 1, 'Check failed request without globals' );
- ok( counter.success == 0, 'Check failed request without globals' );
- ok( counter.complete == 0, 'Check failed request without globals' );
- ok( counter.send == 1, 'Check failed request without globals' );
- start();
- }});
- } else
- start();
- }});
+ $.ajax({
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ data: { callback: "?" },
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, data obj callback)" );
+ plus();
+ }
+ });
+
+ $.ajax({
+ type: "POST",
+ url: "data/jsonp.php",
+ dataType: "jsonp",
+ success: function(data){
+ ok( data.data, "JSON results returned (POST, no callback)" );
+ plus();
+ }
+ });
+
+ $.ajax({
+ type: "POST",
+ url: "data/jsonp.php",
+ data: "callback=?",
+ dataType: "jsonp",
+ success: function(data){
+ ok( data.data, "JSON results returned (POST, data callback)" );
+ plus();
+ }
+ });
+
+ $.ajax({
+ type: "POST",
+ url: "data/jsonp.php",
+ data: { callback: "?" },
+ dataType: "jsonp",
+ success: function(data){
+ ok( data.data, "JSON results returned (POST, data obj callback)" );
+ plus();
+ }
+ });
});
-test("$.ajax - beforeSend", function() {
- expect(1);
+test("$.ajax() - JSONP, Remote", function() {
+ expect(4);
+
+ var count = 0;
+ function plus(){ if ( ++count == 4 ) start(); }
+
+ var base = window.location.href.replace(/\?.*$/, "");
+
stop();
-
- var check = false;
-
- $.ajaxSetup({ timeout: 0 });
-
+
$.ajax({
- url: url("data/name.html"),
- beforeSend: function(xml) {
- check = true;
- },
- success: function(data) {
- ok( check, "check beforeSend was executed" );
- start();
+ url: base + "data/jsonp.php",
+ dataType: "jsonp",
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, no callback)" );
+ plus();
+ }
+ });
+
+ $.ajax({
+ url: base + "data/jsonp.php?callback=?",
+ dataType: "jsonp",
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, url callback)" );
+ plus();
+ }
+ });
+
+ $.ajax({
+ url: base + "data/jsonp.php",
+ dataType: "jsonp",
+ data: "callback=?",
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, data callback)" );
+ plus();
+ }
+ });
+
+ $.ajax({
+ url: base + "data/jsonp.php",
+ dataType: "jsonp",
+ data: { callback: "?" },
+ success: function(data){
+ ok( data.data, "JSON results returned (GET, data obj callback)" );
+ plus();
}
});
});
-test("$.ajax - dataType html", function() {
- expect(5);
+test("$.ajax() - script, Remote", function() {
+ expect(2);
+
+ var base = window.location.href.replace(/\?.*$/, "");
+
stop();
-
- foobar = null;
- testFoo = undefined;
-
- var verifyEvaluation = function() {
- ok( testFoo == "foo", 'Check if script was evaluated for datatype html' );
- ok( foobar == "bar", 'Check if script src was evaluated for datatype html' );
- start();
- };
-
+
$.ajax({
- dataType: "html",
- url: url("data/test.html"),
- success: function(data) {
- $("#ap").html(data);
- ok( data.match(/^html text/), 'Check content for datatype html' );
- setTimeout(verifyEvaluation, 600);
- }
+ url: base + "data/test.js",
+ dataType: "script",
+ success: function(data){
+ ok( foobar, "Script results returned (GET, no callback)" );
+ start();
+ }
});
});
-if ( !isLocal ) {
-
test("$.getJSON(String, Hash, Function) - JSON array", function() {
expect(4);
stop();
}
-}
+//}