diff --git a/src/prototype/ajax/ajax.js b/src/prototype/ajax/ajax.js index e8b831abd..3f211e2e3 100644 --- a/src/prototype/ajax/ajax.js +++ b/src/prototype/ajax/ajax.js @@ -17,5 +17,6 @@ var Ajax = { * Represents the number of active XHR requests triggered through * [[Ajax.Request]], [[Ajax.Updater]], or [[Ajax.PeriodicalUpdater]]. **/ - activeRequestCount: 0 + activeRequestCount: 0, + _jsonpfunctions: [] }; diff --git a/src/prototype/ajax/request.js b/src/prototype/ajax/request.js index 9bcd689ba..078079871 100644 --- a/src/prototype/ajax/request.js +++ b/src/prototype/ajax/request.js @@ -188,6 +188,16 @@ Ajax.Request = Class.create(Ajax.Base, { params += (params ? '&' : '') + "_method=" + this.method; this.method = 'post'; } + if (this.options.jsonpparametername) { + this.method = 'get'; + var currentfunctioncount = Ajax._jsonpfunctions.length; + Ajax._jsonpfunctions.push(function(data){ + (this.options.onComplete || Prototype.emptyFunction)({'responseJSONP':data}); + (this.options.onSuccess || Prototype.emptyFunction)({'responseJSONP':data}); + $('AJAXJSONP_'+currentfunctioncount) ? $('AJAXJSONP_'+currentfunctioncount).remove() : ''; + }.bind(this)); + params += (params ? '&' : '') + this.options.jsonpparametername+'=Ajax._jsonpfunctions['+currentfunctioncount+']'; + } if (params && this.method === 'get') { // when GET, append parameters to URL @@ -196,6 +206,12 @@ Ajax.Request = Class.create(Ajax.Base, { this.parameters = params.toQueryParams(); + if (this.options.jsonpparametername) { + document.body.insert(new Element('script',{'type':'text/javascript','src':this.url,'id':'AJAXJSONP_'+(Ajax._jsonpfunctions.length-1)})); + Ajax.Responders.dispatch('onCreate', this, response); + return; + } + try { var response = new Ajax.Response(this); if (this.options.onCreate) this.options.onCreate(response); diff --git a/test/unit/tests/ajax.test.js b/test/unit/tests/ajax.test.js index caca3ee0d..5b4548079 100644 --- a/test/unit/tests/ajax.test.js +++ b/test/unit/tests/ajax.test.js @@ -477,6 +477,28 @@ suite("Ajax", function () { Ajax.Request.prototype.isSameOrigin = isSameOrigin; }); + // + // Commented out because I'm not sure how to make WEBRICK and Sinatra handle this JSONP request + // + // test("JSONP with Same Origin",function(done){ + // new Ajax.Request("/jsonp",extendDefault({ + // parameters: "handlejsonp=1", + // jsonpparametername:'callback', + // onSuccess: function(transport) { + // assert.equal(transport.responseJSONP.handlejsonp,"1"); + // done(); + // } + // })) + // }) + test("JSONP with Different Origin",function(done){ + new Ajax.Request("http://echo.jsontest.com/key/value/one/two",extendDefault({ + jsonpparametername:'callback', + onSuccess: function(transport) { + assert.deepEqual(transport.responseJSONP,{"one": "two","key": "value"}); + done(); + } + })) + }) });