]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/RemoteRequest.js
LP1615805 No inputs after submit in patron search (AngularJS)
[Evergreen.git] / Open-ILS / web / opac / common / js / RemoteRequest.js
1 var XML_HTTP_GATEWAY = "osrf-gateway-v1";
2 var XML_HTTP_SERVER = "";
3
4
5 /* This object is thrown when network failures occur */
6 function NetworkFailure(stat, url) { 
7         this._status = stat; 
8         this._url = url;
9 }
10
11 NetworkFailure.prototype.status = function() { return this._status; }
12 NetworkFailure.prototype.url = function() { return this._url; }
13 NetworkFailure.prototype.toString = function() { 
14         return "Network Failure: status = " + this.status() +'\n'+this.url(); 
15 }
16
17
18
19 function isXUL() { try { if(IAMXUL) return true;}catch(e){return false;}; }
20 var _allrequests = {};
21
22 // If the legacy JSON gateway is needed by the staff client, uncomment this
23 /* 
24 if(isXUL()) {
25     XML_HTTP_GATEWAY = 'gateway';
26 }
27 */
28
29 function cleanRemoteRequests() {
30         for( var i in _allrequests ) 
31                 destroyRequest(_allrequests[i]);
32 }
33
34 function abortAllRequests() {
35         for( var i in _allrequests ) {
36                 var r = _allrequests[i];
37                 if(r) { 
38                         r.abort();
39                         destroyRequest(r);
40                 }
41         }
42 }
43
44 function destroyRequest(r) {
45         if(r == null) return;
46
47         if( r.xmlhttp ) {
48                 r.xmlhttp.onreadystatechange = function(){};
49                 r.xmlhttp = null;
50         }
51
52         r.callback                              = null;
53         r.userdata                              = null;
54         _allrequests[r.id]      = null;
55 }
56
57 /* ----------------------------------------------------------------------- */
58 /* Request object */
59 var rrId = 0;
60 function RemoteRequest( service, method ) {
61
62         /* dojo is currently only available in the OPAC */
63         try {
64                 /* We want OpenSRF.locale for xx-YY format */
65                 this.locale     = OpenSRF.locale;
66         }
67         catch (e) {
68                 this.locale = null;
69         }
70         this.service    = service;
71         this.method             = method;
72         this.xmlhttp    = false;
73         this.name               = null;
74         this.alertEvent = true; /* only used when isXUL is false */
75
76         this.type               = "POST"; /* default */
77         this.id                 = rrId++;
78         this.cancelled = false;
79
80         this.setSecure(false);
81         if(isXUL()) this.setSecure(true);
82
83         _allrequests[this.id] = this;
84
85         var i = 2;
86         this.params = ""; 
87
88         while(i < arguments.length) {
89                 var object = js2JSON(arguments[i++]);
90                 this.params += "&param=" + encodeURIComponent(object);
91         }
92
93         if(!this.params) { this.params = ""; }
94
95         this.param_string = "service=" + service + "&method=" + method + this.params;
96         if (this.locale != null) {
97                 this.param_string = this.param_string + "&locale=" + this.locale;
98         }
99         if( this.buildXMLRequest() == null ) alert("Browser is not supported!");
100
101 }
102
103
104 RemoteRequest.prototype.timeout = function(t) {
105         t *= 1000
106         var req = this;
107         req.timeoutFunc = setTimeout(
108                 function() {
109                         if( req && req.xmlhttp ) {
110                                 req.cancelled = true;
111                                 req.abort();
112                                 if( req.abtCallback ) {
113                                         req.abtCallback(req);
114                                 }
115                         }
116                 },
117                 t
118         );
119 }
120
121 RemoteRequest.prototype.abortCallback = function(func) {
122         this.abtCallback = func;
123 }
124
125 RemoteRequest.prototype.event = function(evt) {
126         if( arguments.length > 0 )
127                 this.evt = evt;
128         return this.evt;
129 }
130
131 RemoteRequest.prototype.abort = function() {
132         if( this.xmlhttp ) {
133                 /* this has to come before abort() or IE will puke on you */
134                 this.xmlhttp.onreadystatechange = function(){};
135                 this.xmlhttp.abort();
136         }
137 }
138
139 /* constructs our XMLHTTPRequest object */
140 RemoteRequest.prototype.buildXMLRequest = function() {
141         this.xmlhttp = buildXMLRequest();
142         return true;
143 }
144
145
146 function buildXMLRequest() {
147     try {
148             return new XMLHttpRequest();
149     } catch(e) {
150             try { 
151                     return new ActiveXObject("Msxml2.XMLHTTP"); 
152             } catch (e2) {
153                     try { 
154                             return new ActiveXObject("Microsoft.XMLHTTP"); 
155                     } catch (e3) {
156                         alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
157                 return null;
158                     }
159             }
160     }
161 }
162
163
164 function _remoteRequestCallback(id) {
165
166         var object = _allrequests[id];
167         if(object.cancelled) return;
168
169         if( object.xmlhttp.readyState == 4 ) {
170
171         try {
172             object.duration = new Date().getTime() - object.sendTime;
173             dump('request ' + object.id + ': duration = ' + object.duration + ' ms\n');
174         } catch(ee){}
175
176                 try {
177                         object.callback(object);
178                 } catch(E) {
179             throw E
180                 } finally { 
181                         destroyRequest(object); 
182                         object = null; 
183                 }  
184         }
185 }
186
187
188 /* define the callback we use when this request has received
189         all of its data */
190 RemoteRequest.prototype.setCompleteCallback = function(callback) {
191         if(this.cancelled) return;
192         this.callback = callback;
193         var id = this.id;
194         this.xmlhttp.onreadystatechange = function() { _remoteRequestCallback(id); }
195 }
196
197
198 /* http by default.  This makes it https. *ONLY works when
199         embedded in a XUL app. */
200 RemoteRequest.prototype.setSecure = function(bool) {
201         this.secure = bool; 
202 }
203
204 RemoteRequest.prototype.send = function(blocking) {
205
206         if(this.cancelled) return;
207
208         /* determine the xmlhttp server dynamically */
209         var url = location.protocol + "//" + location.host + "/" + XML_HTTP_GATEWAY;
210
211         if(isXUL()) {
212                 if( XML_HTTP_SERVER ) 
213                         url = 'http://'+XML_HTTP_SERVER+'/'+XML_HTTP_GATEWAY;
214
215                 if( url.match(/^http:/) && 
216                                 (this.secure || location.href.match(/^https:/) || location.href.match(/^chrome:/) || location.href.match(/^oils:/) ) ) {
217                         url = url.replace(/^http:/, 'https:');
218                 }
219         }
220
221         var data = null;
222         if( this.type == 'GET' ) url +=  "?" + this.param_string; 
223
224         this.url = url;
225
226    //if( isXUL() ) dump('request URL = ' + url + '?' + this.param_string + '\n');
227
228         try {
229
230                 if(blocking) this.xmlhttp.open(this.type, url, false);
231                 else this.xmlhttp.open(this.type, url, true);
232                 
233         } catch(E) {
234                 alert("Fatal error opening XMLHTTPRequest for URL:\n" + url + '\n' + E);
235                 return;
236         }
237
238         if( this.type == 'POST' ) {
239                 data = this.param_string;
240                 this.xmlhttp.setRequestHeader('Content-Type',
241                                 'application/x-www-form-urlencoded');
242         }
243
244         try {
245                 var auth;
246                 try { dojo.require('dojo.cookie'); auth = dojo.cookie(COOKIE_SES) } catch(ee) {}
247                 if( isXUL() ) auth = fetchXULStash().session.key;
248                 if( auth ) 
249                         this.xmlhttp.setRequestHeader('X-OILS-Authtoken', auth);
250
251         } catch(e) {}
252
253         if(data && data.match(/param=undefined/)) {
254                 /* we get a bogus param .. replace with NULL */
255                 try{dump('!+! UNDEFINED PARAM IN QUERY: ' + this.service + ' : ' + this.method+'\n');}catch(r){}
256                 data = data.replace(/param=undefined/g,'param=null');
257         }
258
259
260     this.sendTime = new Date().getTime();
261         try{ this.xmlhttp.send( data ); } catch(e){}
262
263         return this;
264 }
265
266 /* returns the actual response text from the request */
267 RemoteRequest.prototype.getText = function() {
268         return this.xmlhttp.responseText;
269 }
270
271 RemoteRequest.prototype.isReady = function() {
272         return this.xmlhttp.readyState == 4;
273 }
274
275
276 /* returns the JSON->js result object  */
277 RemoteRequest.prototype.getResultObject = function() {
278
279         if(this.cancelled) return null;
280         if(!this.xmlhttp) return null;
281
282         var failed = false;
283         var status = null;
284         this.event(null);
285
286         /*
287         try {
288                 dump(this.url + '?' + this.param_string + '\n' +
289                         'Returned with \n\tstatus = ' + this.xmlhttp.status + 
290                         '\n\tpayload= ' + this.xmlhttp.responseText + '\n');
291         } catch(e) {}
292         */
293
294         try {
295                 status = this.xmlhttp.status;
296                 if( status != 200 ) failed = true;
297         } catch(e) { failed = true; }
298
299         if( failed ) {
300                 if(!status) status = '<unknown>';
301                 try{dump('! NETWORK FAILURE.  HTTP STATUS = ' +status+'\n'+this.param_string+'\n');}catch(e){}
302                 if(isXUL()) 
303                         throw new NetworkFailure(status, this.param_string);
304                 else return null;
305         }
306
307         var text = this.xmlhttp.responseText;
308
309         //try{if(getDebug()) _debug('response: ' + text + '\n')}catch(e){}
310
311         if(text == "" || text == " " || text == null) {
312                 try { dump('dbg: Request returned no text!\n'); } catch(E) {}
313                 if(isXUL()) 
314                         throw new NetworkFailure(status, this.param_string);
315                 return null;
316         }
317
318         var obj = JSON2js(text);
319         if(!obj) return null;
320
321         if( obj.status != 200 ) {
322
323                 var str = 'A server error occurred. Debug information follows: ' +
324                                         '\ncode = '             + obj.status + 
325                                         '\ndebug: '             + obj.debug + 
326                                         '\npayload: '   + js2JSON(obj.payload); 
327
328                 if(isXUL()) {
329                         dump(str);
330                         throw obj;
331
332                 } else {
333                         _debug(str);
334                         throw str;
335                 }
336         }
337
338         var payload = obj.payload;
339         if(!payload || payload.length == 0) return null;
340         payload = (payload.length == 1) ? payload[0] : payload;
341
342         if(!isXUL()) {
343                 if( checkILSEvent(payload) ) {
344                         this.event(payload);
345                         if( this.alertEvent ) {
346                                 alertILSEvent(payload);
347                                 return null;
348                         }
349                 } 
350         }
351
352         return payload;
353 }
354
355 /* adds a new parameter to the request */
356 RemoteRequest.prototype.addParam = function(param) {
357         var string = encodeURIComponent(js2JSON(param));
358         this.param_string += "&param=" + string;
359 }
360
361 function fetchXULStash() {
362         if( isXUL() ) {
363                 try {
364                         var __OILS = Components.classes["@open-ils.org/openils_data_cache;1"].getService();
365                         return __OILS.wrappedJSObject.data;
366         
367                 } catch(E) {
368                         _debug('Error in OpenILS.data._debug_stash(): ' + js2JSON(E) );
369                 }
370         }
371         return {};
372 }
373
374