1 | /*! |
---|
2 | * Ext JS Library 3.4.0 |
---|
3 | * Copyright(c) 2006-2011 Sencha Inc. |
---|
4 | * licensing@sencha.com |
---|
5 | * http://www.sencha.com/license |
---|
6 | */ |
---|
7 | /* |
---|
8 | * Portions of this file are based on pieces of Yahoo User Interface Library |
---|
9 | * Copyright (c) 2007, Yahoo! Inc. All rights reserved. |
---|
10 | * YUI licensed under the BSD License: |
---|
11 | * http://developer.yahoo.net/yui/license.txt |
---|
12 | */ |
---|
13 | Ext.lib.Ajax = function() { |
---|
14 | var activeX = ['Msxml2.XMLHTTP.6.0', |
---|
15 | 'Msxml2.XMLHTTP.3.0', |
---|
16 | 'Msxml2.XMLHTTP'], |
---|
17 | CONTENTTYPE = 'Content-Type'; |
---|
18 | |
---|
19 | // private |
---|
20 | function setHeader(o) { |
---|
21 | var conn = o.conn, |
---|
22 | prop, |
---|
23 | headers = {}; |
---|
24 | |
---|
25 | function setTheHeaders(conn, headers){ |
---|
26 | for (prop in headers) { |
---|
27 | if (headers.hasOwnProperty(prop)) { |
---|
28 | conn.setRequestHeader(prop, headers[prop]); |
---|
29 | } |
---|
30 | } |
---|
31 | } |
---|
32 | |
---|
33 | Ext.apply(headers, pub.headers, pub.defaultHeaders); |
---|
34 | setTheHeaders(conn, headers); |
---|
35 | delete pub.headers; |
---|
36 | } |
---|
37 | |
---|
38 | // private |
---|
39 | function createExceptionObject(tId, callbackArg, isAbort, isTimeout) { |
---|
40 | return { |
---|
41 | tId : tId, |
---|
42 | status : isAbort ? -1 : 0, |
---|
43 | statusText : isAbort ? 'transaction aborted' : 'communication failure', |
---|
44 | isAbort: isAbort, |
---|
45 | isTimeout: isTimeout, |
---|
46 | argument : callbackArg |
---|
47 | }; |
---|
48 | } |
---|
49 | |
---|
50 | // private |
---|
51 | function initHeader(label, value) { |
---|
52 | (pub.headers = pub.headers || {})[label] = value; |
---|
53 | } |
---|
54 | |
---|
55 | // private |
---|
56 | function createResponseObject(o, callbackArg) { |
---|
57 | var headerObj = {}, |
---|
58 | headerStr, |
---|
59 | conn = o.conn, |
---|
60 | t, |
---|
61 | s, |
---|
62 | // see: https://prototype.lighthouseapp.com/projects/8886/tickets/129-ie-mangles-http-response-status-code-204-to-1223 |
---|
63 | isBrokenStatus = conn.status == 1223; |
---|
64 | |
---|
65 | try { |
---|
66 | headerStr = o.conn.getAllResponseHeaders(); |
---|
67 | Ext.each(headerStr.replace(/\r\n/g, '\n').split('\n'), function(v){ |
---|
68 | t = v.indexOf(':'); |
---|
69 | if(t >= 0){ |
---|
70 | s = v.substr(0, t).toLowerCase(); |
---|
71 | if(v.charAt(t + 1) == ' '){ |
---|
72 | ++t; |
---|
73 | } |
---|
74 | headerObj[s] = v.substr(t + 1); |
---|
75 | } |
---|
76 | }); |
---|
77 | } catch(e) {} |
---|
78 | |
---|
79 | return { |
---|
80 | tId : o.tId, |
---|
81 | // Normalize the status and statusText when IE returns 1223, see the above link. |
---|
82 | status : isBrokenStatus ? 204 : conn.status, |
---|
83 | statusText : isBrokenStatus ? 'No Content' : conn.statusText, |
---|
84 | getResponseHeader : function(header){return headerObj[header.toLowerCase()];}, |
---|
85 | getAllResponseHeaders : function(){return headerStr;}, |
---|
86 | responseText : conn.responseText, |
---|
87 | responseXML : conn.responseXML, |
---|
88 | argument : callbackArg |
---|
89 | }; |
---|
90 | } |
---|
91 | |
---|
92 | // private |
---|
93 | function releaseObject(o) { |
---|
94 | if (o.tId) { |
---|
95 | pub.conn[o.tId] = null; |
---|
96 | } |
---|
97 | o.conn = null; |
---|
98 | o = null; |
---|
99 | } |
---|
100 | |
---|
101 | // private |
---|
102 | function handleTransactionResponse(o, callback, isAbort, isTimeout) { |
---|
103 | if (!callback) { |
---|
104 | releaseObject(o); |
---|
105 | return; |
---|
106 | } |
---|
107 | |
---|
108 | var httpStatus, responseObject; |
---|
109 | |
---|
110 | try { |
---|
111 | if (o.conn.status !== undefined && o.conn.status != 0) { |
---|
112 | httpStatus = o.conn.status; |
---|
113 | } |
---|
114 | else { |
---|
115 | httpStatus = 13030; |
---|
116 | } |
---|
117 | } |
---|
118 | catch(e) { |
---|
119 | httpStatus = 13030; |
---|
120 | } |
---|
121 | |
---|
122 | if ((httpStatus >= 200 && httpStatus < 300) || (Ext.isIE && httpStatus == 1223)) { |
---|
123 | responseObject = createResponseObject(o, callback.argument); |
---|
124 | if (callback.success) { |
---|
125 | if (!callback.scope) { |
---|
126 | callback.success(responseObject); |
---|
127 | } |
---|
128 | else { |
---|
129 | callback.success.apply(callback.scope, [responseObject]); |
---|
130 | } |
---|
131 | } |
---|
132 | } |
---|
133 | else { |
---|
134 | switch (httpStatus) { |
---|
135 | case 12002: |
---|
136 | case 12029: |
---|
137 | case 12030: |
---|
138 | case 12031: |
---|
139 | case 12152: |
---|
140 | case 13030: |
---|
141 | responseObject = createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false), isTimeout); |
---|
142 | if (callback.failure) { |
---|
143 | if (!callback.scope) { |
---|
144 | callback.failure(responseObject); |
---|
145 | } |
---|
146 | else { |
---|
147 | callback.failure.apply(callback.scope, [responseObject]); |
---|
148 | } |
---|
149 | } |
---|
150 | break; |
---|
151 | default: |
---|
152 | responseObject = createResponseObject(o, callback.argument); |
---|
153 | if (callback.failure) { |
---|
154 | if (!callback.scope) { |
---|
155 | callback.failure(responseObject); |
---|
156 | } |
---|
157 | else { |
---|
158 | callback.failure.apply(callback.scope, [responseObject]); |
---|
159 | } |
---|
160 | } |
---|
161 | } |
---|
162 | } |
---|
163 | |
---|
164 | releaseObject(o); |
---|
165 | responseObject = null; |
---|
166 | } |
---|
167 | |
---|
168 | function checkResponse(o, callback, conn, tId, poll, cbTimeout){ |
---|
169 | if (conn && conn.readyState == 4) { |
---|
170 | clearInterval(poll[tId]); |
---|
171 | poll[tId] = null; |
---|
172 | |
---|
173 | if (cbTimeout) { |
---|
174 | clearTimeout(pub.timeout[tId]); |
---|
175 | pub.timeout[tId] = null; |
---|
176 | } |
---|
177 | handleTransactionResponse(o, callback); |
---|
178 | } |
---|
179 | } |
---|
180 | |
---|
181 | function checkTimeout(o, callback){ |
---|
182 | pub.abort(o, callback, true); |
---|
183 | } |
---|
184 | |
---|
185 | |
---|
186 | // private |
---|
187 | function handleReadyState(o, callback){ |
---|
188 | callback = callback || {}; |
---|
189 | var conn = o.conn, |
---|
190 | tId = o.tId, |
---|
191 | poll = pub.poll, |
---|
192 | cbTimeout = callback.timeout || null; |
---|
193 | |
---|
194 | if (cbTimeout) { |
---|
195 | pub.conn[tId] = conn; |
---|
196 | pub.timeout[tId] = setTimeout(checkTimeout.createCallback(o, callback), cbTimeout); |
---|
197 | } |
---|
198 | poll[tId] = setInterval(checkResponse.createCallback(o, callback, conn, tId, poll, cbTimeout), pub.pollInterval); |
---|
199 | } |
---|
200 | |
---|
201 | // private |
---|
202 | function asyncRequest(method, uri, callback, postData) { |
---|
203 | var o = getConnectionObject() || null; |
---|
204 | |
---|
205 | if (o) { |
---|
206 | o.conn.open(method, uri, true); |
---|
207 | |
---|
208 | if (pub.useDefaultXhrHeader) { |
---|
209 | initHeader('X-Requested-With', pub.defaultXhrHeader); |
---|
210 | } |
---|
211 | |
---|
212 | if(postData && pub.useDefaultHeader && (!pub.headers || !pub.headers[CONTENTTYPE])){ |
---|
213 | initHeader(CONTENTTYPE, pub.defaultPostHeader); |
---|
214 | } |
---|
215 | |
---|
216 | if (pub.defaultHeaders || pub.headers) { |
---|
217 | setHeader(o); |
---|
218 | } |
---|
219 | |
---|
220 | handleReadyState(o, callback); |
---|
221 | o.conn.send(postData || null); |
---|
222 | } |
---|
223 | return o; |
---|
224 | } |
---|
225 | |
---|
226 | // private |
---|
227 | function getConnectionObject() { |
---|
228 | var o; |
---|
229 | |
---|
230 | try { |
---|
231 | if (o = createXhrObject(pub.transactionId)) { |
---|
232 | pub.transactionId++; |
---|
233 | } |
---|
234 | } catch(e) { |
---|
235 | } finally { |
---|
236 | return o; |
---|
237 | } |
---|
238 | } |
---|
239 | |
---|
240 | // private |
---|
241 | function createXhrObject(transactionId) { |
---|
242 | var http; |
---|
243 | |
---|
244 | try { |
---|
245 | http = new XMLHttpRequest(); |
---|
246 | } catch(e) { |
---|
247 | for (var i = Ext.isIE6 ? 1 : 0; i < activeX.length; ++i) { |
---|
248 | try { |
---|
249 | http = new ActiveXObject(activeX[i]); |
---|
250 | break; |
---|
251 | } catch(e) {} |
---|
252 | } |
---|
253 | } finally { |
---|
254 | return {conn : http, tId : transactionId}; |
---|
255 | } |
---|
256 | } |
---|
257 | |
---|
258 | var pub = { |
---|
259 | request : function(method, uri, cb, data, options) { |
---|
260 | if(options){ |
---|
261 | var me = this, |
---|
262 | xmlData = options.xmlData, |
---|
263 | jsonData = options.jsonData, |
---|
264 | hs; |
---|
265 | |
---|
266 | Ext.applyIf(me, options); |
---|
267 | |
---|
268 | if(xmlData || jsonData){ |
---|
269 | hs = me.headers; |
---|
270 | if(!hs || !hs[CONTENTTYPE]){ |
---|
271 | initHeader(CONTENTTYPE, xmlData ? 'text/xml' : 'application/json'); |
---|
272 | } |
---|
273 | data = xmlData || (!Ext.isPrimitive(jsonData) ? Ext.encode(jsonData) : jsonData); |
---|
274 | } |
---|
275 | } |
---|
276 | return asyncRequest(method || options.method || "POST", uri, cb, data); |
---|
277 | }, |
---|
278 | |
---|
279 | serializeForm : function(form) { |
---|
280 | var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements, |
---|
281 | hasSubmit = false, |
---|
282 | encoder = encodeURIComponent, |
---|
283 | name, |
---|
284 | data = '', |
---|
285 | type, |
---|
286 | hasValue; |
---|
287 | |
---|
288 | Ext.each(fElements, function(element){ |
---|
289 | name = element.name; |
---|
290 | type = element.type; |
---|
291 | |
---|
292 | if (!element.disabled && name) { |
---|
293 | if (/select-(one|multiple)/i.test(type)) { |
---|
294 | Ext.each(element.options, function(opt){ |
---|
295 | if (opt.selected) { |
---|
296 | hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified; |
---|
297 | data += String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text)); |
---|
298 | } |
---|
299 | }); |
---|
300 | } else if (!(/file|undefined|reset|button/i.test(type))) { |
---|
301 | if (!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)) { |
---|
302 | data += encoder(name) + '=' + encoder(element.value) + '&'; |
---|
303 | hasSubmit = /submit/i.test(type); |
---|
304 | } |
---|
305 | } |
---|
306 | } |
---|
307 | }); |
---|
308 | return data.substr(0, data.length - 1); |
---|
309 | }, |
---|
310 | |
---|
311 | useDefaultHeader : true, |
---|
312 | defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8', |
---|
313 | useDefaultXhrHeader : true, |
---|
314 | defaultXhrHeader : 'XMLHttpRequest', |
---|
315 | poll : {}, |
---|
316 | timeout : {}, |
---|
317 | conn: {}, |
---|
318 | pollInterval : 50, |
---|
319 | transactionId : 0, |
---|
320 | |
---|
321 | // This is never called - Is it worth exposing this? |
---|
322 | // setProgId : function(id) { |
---|
323 | // activeX.unshift(id); |
---|
324 | // }, |
---|
325 | |
---|
326 | // This is never called - Is it worth exposing this? |
---|
327 | // setDefaultPostHeader : function(b) { |
---|
328 | // this.useDefaultHeader = b; |
---|
329 | // }, |
---|
330 | |
---|
331 | // This is never called - Is it worth exposing this? |
---|
332 | // setDefaultXhrHeader : function(b) { |
---|
333 | // this.useDefaultXhrHeader = b; |
---|
334 | // }, |
---|
335 | |
---|
336 | // This is never called - Is it worth exposing this? |
---|
337 | // setPollingInterval : function(i) { |
---|
338 | // if (typeof i == 'number' && isFinite(i)) { |
---|
339 | // this.pollInterval = i; |
---|
340 | // } |
---|
341 | // }, |
---|
342 | |
---|
343 | // This is never called - Is it worth exposing this? |
---|
344 | // resetDefaultHeaders : function() { |
---|
345 | // this.defaultHeaders = null; |
---|
346 | // }, |
---|
347 | |
---|
348 | abort : function(o, callback, isTimeout) { |
---|
349 | var me = this, |
---|
350 | tId = o.tId, |
---|
351 | isAbort = false; |
---|
352 | |
---|
353 | if (me.isCallInProgress(o)) { |
---|
354 | o.conn.abort(); |
---|
355 | clearInterval(me.poll[tId]); |
---|
356 | me.poll[tId] = null; |
---|
357 | clearTimeout(pub.timeout[tId]); |
---|
358 | me.timeout[tId] = null; |
---|
359 | |
---|
360 | handleTransactionResponse(o, callback, (isAbort = true), isTimeout); |
---|
361 | } |
---|
362 | return isAbort; |
---|
363 | }, |
---|
364 | |
---|
365 | isCallInProgress : function(o) { |
---|
366 | // if there is a connection and readyState is not 0 or 4 |
---|
367 | return o.conn && !{0:true,4:true}[o.conn.readyState]; |
---|
368 | } |
---|
369 | }; |
---|
370 | return pub; |
---|
371 | }(); |
---|