]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/RemoteRequest.js
force post for IE to prevent caching
[Evergreen.git] / Open-ILS / web / opac / common / js / RemoteRequest.js
1 var XML_HTTP_GATEWAY = "gateway";
2 var XML_HTTP_SERVER = "";
3 var XML_HTTP_MAX_TRIES = 3;
4
5 //var IAMXUL = false;
6 function isXUL() { try { if(IAMXUL) return true;}catch(e){return false;}; }
7
8 /* some communication exceptions */
9 function EX(message) { this.init(message); }
10 EX.prototype.init = function(message) { this.message = message; }
11 EX.prototype.toString = function() { return "\n *** Exception Occured \n" + this.message; }  
12 EXCommunication.prototype              = new EX();
13 EXCommunication.prototype.constructor  = EXCommunication;
14 EXCommunication.baseClass              = EX.prototype.constructor;
15 function EXCommunication(message) { this.classname="EXCommunication"; this.init("EXCommunication: " + message); }                          
16 /* ------------------------------------------------ */
17
18
19 var _allrequests = {};
20
21 function cleanRemoteRequests() {
22         for( var i in _allrequests ) 
23                 destroyRequest(_allrequests[i]);
24 }
25
26 function abortAllRequests() {
27         for( var i in _allrequests ) {
28                 var r = _allrequests[i];
29                 if(r) { 
30                         r.abort();
31                         destroyRequest(r);
32                 }
33         }
34 }
35
36 function destroyRequest(r) {
37         if(r == null) return;
38
39         if( r.xmlhttp ) {
40                 r.xmlhttp.onreadystatechange = function(){};
41                 r.xmlhttp = null;
42         }
43
44         r.callback                              = null;
45         r.userdata                              = null;
46         _allrequests[r.id]      = null;
47 }
48
49 /* ----------------------------------------------------------------------- */
50 /* Request object */
51 function RemoteRequest( service, method ) {
52
53
54         this.service    = service;
55         this.method             = method;
56         this.xmlhttp    = false;
57         this.name               = null;
58         this.sendCount = 0;
59         this.alertEvent = true; /* only used when isXUL is false */
60
61         this.type               = "POST"; /* default */
62         this.id                 = service + method + Math.random();
63         this.cancelled = false;
64
65         _allrequests[this.id] = this;
66
67         var i = 2;
68         this.params = ""; 
69
70         while(i < arguments.length) {
71                 var object = js2JSON(arguments[i++]);
72                 this.params += "&param=" + encodeURIComponent(object);
73         }
74
75         if(!this.params) { this.params = ""; }
76         this.param_string = "service=" + service + "&method=" + method + this.params;
77         if( this.buildXMLRequest() == null ) alert("Browser is not supported!");
78
79 }
80
81
82 RemoteRequest.prototype.timeout = function(t) {
83         t *= 1000
84         var req = this;
85         req.timeoutFunc = setTimeout(
86                 function() {
87                         if( req && req.xmlhttp ) {
88                                 req.cancelled = true;
89                                 req.abort();
90                                 if( req.abtCallback ) {
91                                         req.abtCallback(req);
92                                 }
93                         }
94                 },
95                 t
96         );
97 }
98
99 RemoteRequest.prototype.abortCallback = function(func) {
100         this.abtCallback = func;
101 }
102
103 RemoteRequest.prototype.event = function(evt) {
104         if( arguments.length > 0 )
105                 this.evt = evt;
106         return this.evt;
107 }
108
109 RemoteRequest.prototype.abort = function() {
110         if( this.xmlhttp ) {
111                 /* this has to come before abort() or IE will puke on you */
112                 this.xmlhttp.onreadystatechange = function(){};
113                 this.xmlhttp.abort();
114         }
115 }
116
117 /* constructs our XMLHTTPRequest object */
118 RemoteRequest.prototype.buildXMLRequest = function() {
119         this.xmlhttp = buildXMLRequest();
120         return true;
121 }
122
123
124 function buildXMLRequest() {
125         var x;
126         try { 
127                 x = new ActiveXObject("Msxml2.XMLHTTP"); 
128         } catch (e) {
129                 try { 
130                         x = new ActiveXObject("Microsoft.XMLHTTP"); 
131                 } catch (E) {
132                         x = false;
133                 }
134         }
135
136         if (!x && typeof XMLHttpRequest!='undefined') x = new XMLHttpRequest();
137
138         if(!x) {
139                 alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
140                 return null;
141         }
142
143         return x;
144 }
145
146
147 function _remoteRequestCallback(id) {
148
149         var object = _allrequests[id];
150         if(object.cancelled) return;
151
152         if( object.xmlhttp.readyState == 4 ) {
153                 try {
154                         object.callback(object);
155                 } catch(E) {
156
157                         /* if we receive a communication error, retry the request up
158                                 to XML_HTTP_MAX_TRIES attempts */
159                         if( E && E.classname == "EXCommunication" ) {
160
161                                 //try { dump('Communication Error: ' + E ); } catch(e){}
162                                 alert('Debug:  Communication Error: ' + E );
163
164                                 if(object.sendCount >= XML_HTTP_MAX_TRIES ) {
165                                         if(isXUL()) throw object;
166                                          else alert("Arrrgghh, Matey! Error communicating:\n" + E  + "\n" + object.param_string);
167                                 } else {
168                                         object.buildXMLRequest();
169                                         object.send();
170                                         return;
171                                 }
172                         } else { throw E; }
173
174                 } finally { 
175                         destroyRequest(object); 
176                         object = null; 
177                 }  
178         }
179 }
180
181
182 /* define the callback we use when this request has received
183         all of its data */
184 RemoteRequest.prototype.setCompleteCallback = function(callback) {
185         if(this.cancelled) return;
186         this.callback = callback;
187         var id = this.id;
188         this.xmlhttp.onreadystatechange = function() { _remoteRequestCallback(id); }
189 }
190
191
192 /* http by default.  This makes it https. *ONLY works when
193         embedded in a XUL app. */
194 RemoteRequest.prototype.setSecure = function(bool) {
195         this.secure = bool; 
196 }
197
198 RemoteRequest.prototype.send = function(blocking) {
199
200         if(this.cancelled) return;
201
202         /* determine the xmlhttp server dynamically */
203         var url = location.protocol + "//" + location.host + "/" + XML_HTTP_GATEWAY;
204
205         if(isXUL() && XML_HTTP_SERVER) {
206                 if(this.secure || url.match(/^https:/) )
207                         url =   "https://" + XML_HTTP_SERVER + "/" + XML_HTTP_GATEWAY;
208                 else
209                         url =   "http://" + XML_HTTP_SERVER + "/" + XML_HTTP_GATEWAY;
210         }
211
212         /* this number could be a lot higher.. */
213         var whole = url + this.param_string + 1;
214
215
216         if(!IE) {
217                 /* IE will cache this, so don't use it if IE.
218                 useful for debugging */
219                 if( whole.length < 256 ) this.type = 'GET';
220         }
221
222         var data = null;
223         if( this.type == 'GET' ) url +=  "?" + this.param_string; 
224
225         try {
226
227                 if(blocking) this.xmlhttp.open(this.type, url, false);
228                 else this.xmlhttp.open(this.type, url, true);
229                 
230         } catch(E) {
231                 alert("Fatal error opening XMLHTTPRequest for URL:\n" + url + '\n');
232                 return;
233         }
234
235
236         if( this.type == 'POST' ) {
237                 data = this.param_string;
238                 this.xmlhttp.setRequestHeader('Content-Type',
239                                 'application/x-www-form-urlencoded');
240         }
241
242         try{ this.xmlhttp.send( data ); } catch(e){}
243
244         this.sendCount += 1;
245         return this;
246 }
247
248 /* returns the actual response text from the request */
249 RemoteRequest.prototype.getText = function() {
250         return this.xmlhttp.responseText;
251 }
252
253 RemoteRequest.prototype.isReady = function() {
254         return this.xmlhttp.readyState == 4;
255 }
256
257
258 /* returns the JSON->js result object  */
259 RemoteRequest.prototype.getResultObject = function() {
260
261         if(this.cancelled) return null;
262         if(!this.xmlhttp) return null;
263
264         this.event(null);
265
266         var text = this.xmlhttp.responseText;
267         if(text == "" || text == " " || text == null) null;
268
269         var obj = JSON2js(text);
270         if(!obj) return null;
271
272         if( obj.status != 200 ) {
273
274                 var str = 'A server error occurred. Debug information follows: ' +
275                                         '\ncode = '             + obj.status + 
276                                         '\ndebug: '             + obj.debug + 
277                                         '\npayload: '   + js2JSON(obj.payload); 
278
279                 if(isXUL()) {
280                         dump(str);
281                         throw obj;
282
283                 } else {
284                         _debug(str);
285                         alert(str);
286                 }
287         }
288
289         var payload = obj.payload;
290         if(!payload || payload.length == 0) return null;
291         payload = (payload.length == 1) ? payload[0] : payload;
292
293         if(!isXUL()) {
294                 if( checkILSEvent(payload) ) {
295                         this.event(payload);
296                         if( this.alertEvent )
297                                 alertILSEvent(payload);
298                         return null;
299                 } 
300         }
301
302         return payload;
303 }
304
305 /* adds a new parameter to the request */
306 RemoteRequest.prototype.addParam = function(param) {
307         var string = encodeURIComponent(js2JSON(param));
308         this.param_string += "&param=" + string;
309 }
310