Requires

Provides

Powerful all purpose Request Class. Uses XMLHTTPRequest.

License:
MIT-style license.
  1. 18
  2. 19
  3. 20
  4. 21
  5. 22
  6. 23
  7. 24
  8. 25
  9. 26
  10. 27
  11. 28
  12. 29
  13. 30
  14. 31
  15. 32
  16. 33
  17. 34
  18. 35
  19. 36
  20. 37
  21. 38
  22. 39
  23. 40
  24. 41
  25. 42
  26. 43
  27. 44
  28. 45
  29. 46
  30. 47
  31. 48
  32. 49
  33. 50
  34. 51
  35. 52
  36. 53
  37. 54
  38. 55
  39. 56
  40. 57
  41. 58
  42. 59
  43. 60
  44. 61
  45. 62
  46. 63
  47. 64
  48. 65
  49. 66
  50. 67
  51. 68
  52. 69
  53. 70
  54. 71
  55. 72
  56. 73
  57. 74
  58. 75
  59. 76
  60. 77
  61. 78
  62. 79
  63. 80
  64. 81
  65. 82
  66. 83
  67. 84
  68. 85
  69. 86
  70. 87
  71. 88
  72. 89
  73. 90
  74. 91
  75. 92
  76. 93
  77. 94
  78. 95
  79. 96
  80. 97
  81. 98
  82. 99
  83. 100
  84. 101
  85. 102
  86. 103
  87. 104
  88. 105
  89. 106
  90. 107
  91. 108
  92. 109
  93. 110
  94. 111
  95. 112
  96. 113
  97. 114
  98. 115
  99. 116
  100. 117
  101. 118
  102. 119
  103. 120
  104. 121
  105. 122
  106. 123
  107. 124
  108. 125
  109. 126
  110. 127
  111. 128
  112. 129
  113. 130
  114. 131
  115. 132
  116. 133
  117. 134
  118. 135
  119. 136
  120. 137
  121. 138
  122. 139
  123. 140
  124. 141
  125. 142
  126. 143
  127. 144
  128. 145
  129. 146
  130. 147
  131. 148
  132. 149
  133. 150
  134. 151
  135. 152
  136. 153
  137. 154
  138. 155
  139. 156
  140. 157
  141. 158
  142. 159
  143. 160
  144. 161
  145. 162
  146. 163
  147. 164
  148. 165
  149. 166
  150. 167
  151. 168
  152. 169
  153. 170
  154. 171
  155. 172
  156. 173
  157. 174
  158. 175
  159. 176
  160. 177
  161. 178
  162. 179
  163. 180
  164. 181
  165. 182
  166. 183
  167. 184
  168. 185
  169. 186
  170. 187
  171. 188
  172. 189
  173. 190
  174. 191
  175. 192
  176. 193
  177. 194
  178. 195
  179. 196
  180. 197
  181. 198
  182. 199
  183. 200
  184. 201
  185. 202
  186. 203
  187. 204
  188. 205
  189. 206
  190. 207
  191. 208
  192. 209
  193. 210
  194. 211
  195. 212
  196. 213
  197. 214
  198. 215
  199. 216
  200. 217
  201. 218
  202. 219
  203. 220
  204. 221
  205. 222
  206. 223
  207. 224
  208. 225
  209. 226
  210. 227
  211. 228
  212. 229
  213. 230
  214. 231
  215. 232
  216. 233
  217. 234
  218. 235
  219. 236
  220. 237
  221. 238
  222. 239
  223. 240
  224. 241
  225. 242
  226. 243
  227. 244
  228. 245
  229. 246
  230. 247
  231. 248
  232. 249
  233. 250
  234. 251
  235. 252
  236. 253
  237. 254
  238. 255
  239. 256
  240. 257
  241. 258
  242. 259
  243. 260
  244. 261
  245. 262
  246. 263
  247. 264
  248. 265
  249. 266
  250. 267
  251. 268
  252. 269
  253. 270
  254. 271
  255. 272
  256. 273
  257. 274
  258. 275
  259. 276
(function(){ var progressSupport = ('onprogress' in new Browser.Request); var Request = this.Request = new Class({ Implements: [Chain, Events, Options], options: {/* onRequest: function(){}, onLoadstart: function(event, xhr){}, onProgress: function(event, xhr){}, onComplete: function(){}, onCancel: function(){}, onSuccess: function(responseText, responseXML){}, onFailure: function(xhr){}, onException: function(headerName, value){}, onTimeout: function(){}, user: '', password: '',*/ url: '', data: '', headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' }, async: true, format: false, method: 'post', link: 'ignore', isSuccess: null, emulation: true, urlEncoded: true, encoding: 'utf-8', evalScripts: false, evalResponse: false, timeout: 0, noCache: false }, initialize: function(options){ this.xhr = new Browser.Request(); this.setOptions(options); this.headers = this.options.headers; }, onStateChange: function(){ var xhr = this.xhr; if (xhr.readyState != 4 || !this.running) return; this.running = false; this.status = 0; Function.attempt(function(){ var status = xhr.status; this.status = (status == 1223) ? 204 : status; }.bind(this)); xhr.onreadystatechange = function(){}; clearTimeout(this.timer); this.response = {text: this.xhr.responseText || '', xml: this.xhr.responseXML}; if (this.options.isSuccess.call(this, this.status)) this.success(this.response.text, this.response.xml); else this.failure(); }, isSuccess: function(){ var status = this.status; return (status >= 200 && status < 300); }, isRunning: function(){ return !!this.running; }, processScripts: function(text){ if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return Browser.exec(text); return text.stripScripts(this.options.evalScripts); }, success: function(text, xml){ this.onSuccess(this.processScripts(text), xml); }, onSuccess: function(){ this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain(); }, failure: function(){ this.onFailure(); }, onFailure: function(){ this.fireEvent('complete').fireEvent('failure', this.xhr); }, loadstart: function(event){ this.fireEvent('loadstart', [event, this.xhr]); }, progress: function(event){ this.fireEvent('progress', [event, this.xhr]); }, timeout: function(){ this.fireEvent('timeout', this.xhr); }, setHeader: function(name, value){ this.headers[name] = value; return this; }, getHeader: function(name){ return Function.attempt(function(){ return this.xhr.getResponseHeader(name); }.bind(this)); }, check: function(){ if (!this.running) return true; switch (this.options.link){ case 'cancel': this.cancel(); return true; case 'chain': this.chain(this.caller.pass(arguments, this)); return false; } return false; }, send: function(options){ if (!this.check(options)) return this; this.options.isSuccess = this.options.isSuccess || this.isSuccess; this.running = true; var type = typeOf(options); if (type == 'string' || type == 'element') options = {data: options}; var old = this.options; options = Object.append({data: old.data, url: old.url, method: old.method}, options); var data = options.data, url = String(options.url), method = options.method.toLowerCase(); switch (typeOf(data)){ case 'element': data = document.id(data).toQueryString(); break; case 'object': case 'hash': data = Object.toQueryString(data); } if (this.options.format){ var format = 'format=' + this.options.format; data = (data) ? format + '&' + data : format; } if (this.options.emulation && !['get', 'post'].contains(method)){ var _method = '_method=' + method; data = (data) ? _method + '&' + data : _method; method = 'post'; } if (this.options.urlEncoded && ['post', 'put'].contains(method)){ var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : ''; this.headers['Content-type'] = 'application/x-www-form-urlencoded' + encoding; } if (!url) url = document.location.pathname; var trimPosition = url.lastIndexOf('/'); if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition); if (this.options.noCache) url += (url.contains('?') ? '&' : '?') + String.uniqueID(); if (data && method == 'get'){ url += (url.contains('?') ? '&' : '?') + data; data = null; } var xhr = this.xhr; if (progressSupport){ xhr.onloadstart = this.loadstart.bind(this); xhr.onprogress = this.progress.bind(this); } xhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password); if (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true; xhr.onreadystatechange = this.onStateChange.bind(this); Object.each(this.headers, function(value, key){ try { xhr.setRequestHeader(key, value); } catch (e){ this.fireEvent('exception', [key, value]); } }, this); this.fireEvent('request'); xhr.send(data); if (!this.options.async) this.onStateChange(); if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this); return this; }, cancel: function(){ if (!this.running) return this; this.running = false; var xhr = this.xhr; xhr.abort(); clearTimeout(this.timer); xhr.onreadystatechange = xhr.onprogress = xhr.onloadstart = function(){}; this.xhr = new Browser.Request(); this.fireEvent('cancel'); return this; } }); var methods = {}; ['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){ methods[method] = function(data){ var object = { method: method }; if (data != null) object.data = data; return this.send(object); }; }); Request.implement(methods); Element.Properties.send = { set: function(options){ var send = this.get('send').cancel(); send.setOptions(options); return this; }, get: function(){ var send = this.retrieve('send'); if (!send){ send = new Request({ data: this, link: 'cancel', method: this.get('method') || 'post', url: this.get('action') }); this.store('send', send); } return send; } }; Element.implement({ send: function(url){ var sender = this.get('send'); sender.send({data: this, url: url || sender.options.url}); return this; } }); })();