xhr.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. * xhr.js - XMLHttpRequest helper class
  3. * (c) 2008-2010 Jo-Philipp Wich
  4. */
  5. XHR = function()
  6. {
  7. this.reinit = function()
  8. {
  9. if (window.XMLHttpRequest) {
  10. this._xmlHttp = new XMLHttpRequest();
  11. }
  12. else if (window.ActiveXObject) {
  13. this._xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  14. }
  15. else {
  16. alert("xhr.js: XMLHttpRequest is not supported by this browser!");
  17. }
  18. }
  19. this.busy = function() {
  20. if (!this._xmlHttp)
  21. return false;
  22. switch (this._xmlHttp.readyState)
  23. {
  24. case 1:
  25. case 2:
  26. case 3:
  27. return true;
  28. default:
  29. return false;
  30. }
  31. }
  32. this.abort = function() {
  33. if (this.busy())
  34. this._xmlHttp.abort();
  35. }
  36. this.get = function(url,data,callback)
  37. {
  38. this.reinit();
  39. var xhr = this._xmlHttp;
  40. var code = this._encode(data);
  41. url = location.protocol + '//' + location.host + url;
  42. if (code)
  43. if (url.substr(url.length-1,1) == '&')
  44. url += code;
  45. else
  46. url += '?' + code;
  47. xhr.open('GET', url, true);
  48. xhr.onreadystatechange = function()
  49. {
  50. if (xhr.readyState == 4) {
  51. var json = null;
  52. if (xhr.getResponseHeader("Content-Type") == "application/json") {
  53. try {
  54. json = eval('(' + xhr.responseText + ')');
  55. }
  56. catch(e) {
  57. json = null;
  58. }
  59. }
  60. callback(xhr, json);
  61. }
  62. }
  63. xhr.send(null);
  64. }
  65. this.post = function(url,data,callback)
  66. {
  67. this.reinit();
  68. var xhr = this._xmlHttp;
  69. var code = this._encode(data);
  70. xhr.onreadystatechange = function()
  71. {
  72. if (xhr.readyState == 4)
  73. callback(xhr);
  74. }
  75. xhr.open('POST', url, true);
  76. xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  77. xhr.setRequestHeader('Content-length', code.length);
  78. xhr.setRequestHeader('Connection', 'close');
  79. xhr.send(code);
  80. }
  81. this.cancel = function()
  82. {
  83. this._xmlHttp.onreadystatechange = function(){};
  84. this._xmlHttp.abort();
  85. }
  86. this.send_form = function(form,callback,extra_values)
  87. {
  88. var code = '';
  89. for (var i = 0; i < form.elements.length; i++)
  90. {
  91. var e = form.elements[i];
  92. if (e.options)
  93. {
  94. code += (code ? '&' : '') +
  95. form.elements[i].name + '=' + encodeURIComponent(
  96. e.options[e.selectedIndex].value
  97. );
  98. }
  99. else if (e.length)
  100. {
  101. for (var j = 0; j < e.length; j++)
  102. if (e[j].name) {
  103. code += (code ? '&' : '') +
  104. e[j].name + '=' + encodeURIComponent(e[j].value);
  105. }
  106. }
  107. else
  108. {
  109. code += (code ? '&' : '') +
  110. e.name + '=' + encodeURIComponent(e.value);
  111. }
  112. }
  113. if (typeof extra_values == 'object')
  114. for (var key in extra_values)
  115. code += (code ? '&' : '') +
  116. key + '=' + encodeURIComponent(extra_values[key]);
  117. return(
  118. (form.method == 'get')
  119. ? this.get(form.getAttribute('action'), code, callback)
  120. : this.post(form.getAttribute('action'), code, callback)
  121. );
  122. }
  123. this._encode = function(obj)
  124. {
  125. obj = obj ? obj : { };
  126. obj['_'] = Math.random();
  127. if (typeof obj == 'object')
  128. {
  129. var code = '';
  130. var self = this;
  131. for (var k in obj)
  132. code += (code ? '&' : '') +
  133. k + '=' + encodeURIComponent(obj[k]);
  134. return code;
  135. }
  136. return obj;
  137. }
  138. }
  139. XHR.get = function(url, data, callback)
  140. {
  141. (new XHR()).get(url, data, callback);
  142. }
  143. XHR.poll = function(interval, url, data, callback)
  144. {
  145. if (isNaN(interval) || interval < 1)
  146. interval = 5;
  147. if (!XHR._q)
  148. {
  149. XHR._t = 0;
  150. XHR._q = [ ];
  151. XHR._r = function() {
  152. for (var i = 0, e = XHR._q[0]; i < XHR._q.length; e = XHR._q[++i])
  153. {
  154. if (!(XHR._t % e.interval) && !e.xhr.busy())
  155. e.xhr.get(e.url, e.data, e.callback);
  156. }
  157. XHR._t++;
  158. };
  159. }
  160. XHR._q.push({
  161. interval: interval,
  162. callback: callback,
  163. url: url,
  164. data: data,
  165. xhr: new XHR()
  166. });
  167. XHR.run();
  168. }
  169. XHR.halt = function()
  170. {
  171. if (XHR._i)
  172. {
  173. /* show & set poll indicator */
  174. try {
  175. document.getElementById('xhr_poll_status').style.display = '';
  176. document.getElementById('xhr_poll_status_on').style.display = 'none';
  177. document.getElementById('xhr_poll_status_off').style.display = '';
  178. } catch(e) { }
  179. window.clearInterval(XHR._i);
  180. XHR._i = null;
  181. }
  182. }
  183. XHR.run = function()
  184. {
  185. if (XHR._r && !XHR._i)
  186. {
  187. /* show & set poll indicator */
  188. try {
  189. document.getElementById('xhr_poll_status').style.display = '';
  190. document.getElementById('xhr_poll_status_on').style.display = '';
  191. document.getElementById('xhr_poll_status_off').style.display = 'none';
  192. } catch(e) { }
  193. /* kick first round manually to prevent one second lag when setting up
  194. * the poll interval */
  195. XHR._r();
  196. XHR._i = window.setInterval(XHR._r, 1000);
  197. }
  198. }
  199. XHR.running = function()
  200. {
  201. return !!(XHR._r && XHR._i);
  202. }