jXHR.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // jXHR.js (JSON-P XHR)
  2. // v0.1 (c) Kyle Simpson
  3. // MIT License
  4. (function(global){
  5. var SETTIMEOUT = global.setTimeout, // for better compression
  6. doc = global.document,
  7. callback_counter = 0;
  8. global.jXHR = function() {
  9. var script_url,
  10. script_loaded,
  11. jsonp_callback,
  12. scriptElem,
  13. publicAPI = null;
  14. function removeScript() { try { scriptElem.parentNode.removeChild(scriptElem); } catch (err) { } }
  15. function reset() {
  16. script_loaded = false;
  17. script_url = "";
  18. removeScript();
  19. scriptElem = null;
  20. fireReadyStateChange(0);
  21. }
  22. function ThrowError(msg) {
  23. try { publicAPI.onerror.call(publicAPI,msg,script_url); } catch (err) { throw new Error(msg); }
  24. }
  25. function handleScriptLoad() {
  26. if ((this.readyState && this.readyState!=="complete" && this.readyState!=="loaded") || script_loaded) { return; }
  27. this.onload = this.onreadystatechange = null; // prevent memory leak
  28. script_loaded = true;
  29. if (publicAPI.readyState !== 4) ThrowError("Script failed to load ["+script_url+"].");
  30. removeScript();
  31. }
  32. function fireReadyStateChange(rs,args) {
  33. args = args || [];
  34. publicAPI.readyState = rs;
  35. if (typeof publicAPI.onreadystatechange === "function") publicAPI.onreadystatechange.apply(publicAPI,args);
  36. }
  37. publicAPI = {
  38. onerror:null,
  39. onreadystatechange:null,
  40. readyState:0,
  41. open:function(method,url){
  42. reset();
  43. internal_callback = "cb"+(callback_counter++);
  44. (function(icb){
  45. global.jXHR[icb] = function() {
  46. try { fireReadyStateChange.call(publicAPI,4,arguments); }
  47. catch(err) {
  48. publicAPI.readyState = -1;
  49. ThrowError("Script failed to run ["+script_url+"].");
  50. }
  51. global.jXHR[icb] = null;
  52. };
  53. })(internal_callback);
  54. script_url = url.replace(/=\?/,"=jXHR."+internal_callback);
  55. fireReadyStateChange(1);
  56. },
  57. send:function(){
  58. SETTIMEOUT(function(){
  59. scriptElem = doc.createElement("script");
  60. scriptElem.setAttribute("type","text/javascript");
  61. scriptElem.onload = scriptElem.onreadystatechange = function(){handleScriptLoad.call(scriptElem);};
  62. scriptElem.setAttribute("src",script_url);
  63. doc.getElementsByTagName("head")[0].appendChild(scriptElem);
  64. },0);
  65. fireReadyStateChange(2);
  66. },
  67. setRequestHeader:function(){}, // noop
  68. getResponseHeader:function(){return "";}, // basically noop
  69. getAllResponseHeaders:function(){return [];} // ditto
  70. };
  71. reset();
  72. return publicAPI;
  73. };
  74. })(window);