Initial dev repository
[kcls-web.git] / opac / common / js / opensrf_xhr.js
diff --git a/opac/common/js/opensrf_xhr.js b/opac/common/js/opensrf_xhr.js
new file mode 100644 (file)
index 0000000..d0d64ba
--- /dev/null
@@ -0,0 +1,133 @@
+/* -----------------------------------------------------------------------
+ * Copyright (C) 2008  Georgia Public Library Service
+ * Bill Erickson <erickson@esilibrary.com>
+ *  
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * ----------------------------------------------------------------------- */
+
+var OSRF_HTTP_HEADER_TO = 'X-OpenSRF-to';
+var OSRF_HTTP_HEADER_XID = 'X-OpenSRF-xid';
+var OSRF_HTTP_HEADER_FROM = 'X-OpenSRF-from';
+var OSRF_HTTP_HEADER_THREAD = 'X-OpenSRF-thread';
+var OSRF_HTTP_HEADER_TIMEOUT = 'X-OpenSRF-timeout';
+var OSRF_HTTP_HEADER_SERVICE = 'X-OpenSRF-service';
+var OSRF_HTTP_HEADER_MULTIPART = 'X-OpenSRF-multipart';
+var OSRF_HTTP_TRANSLATOR = '/osrf-http-translator'; /* XXX config */
+var OSRF_POST_CONTENT_TYPE = 'application/x-www-form-urlencoded';
+
+
+OpenSRF.XHRequest = function(osrf_msg, args) {
+    this.message = osrf_msg;
+    this.args = args;
+    try {
+           this.xreq =  new XMLHttpRequest();
+    } catch(e) {
+           try { 
+                   this.xreq = new ActiveXObject("Msxml2.XMLHTTP"); 
+           } catch (e2) {
+                       this.xreq = new ActiveXObject("Microsoft.XMLHTTP"); 
+           }
+    }
+
+}
+
+OpenSRF.XHRequest.prototype.send = function() {
+    var xhr_req = this;
+    var xreq = this.xreq
+    
+    if(this.args.timeout) {
+        /* this is a standard blocking (non-multipart) call */
+        xreq.open('POST', OSRF_HTTP_TRANSLATOR, false);
+
+    } else {
+
+       /* Only Firefox supports multipart calls, but Safari / Chrome include
+           "Mozilla" in their user agent strings... sigh */
+        if(!navigator.userAgent.match(/mozilla/i) || navigator.userAgent.match(/webkit/i) || navigator.userAgent.match(/msie/i)) {
+            /* standard asynchronous call */
+            xreq.onreadystatechange = function() {
+                if(xreq.readyState == 4)
+                    xhr_req.core_handler();
+            }
+            xreq.open('POST', OSRF_HTTP_TRANSLATOR, true);
+
+        } else {
+
+            /* asynchronous multipart call */
+            xreq.multipart = true;
+            xreq.onload = function(evt) {xhr_req.core_handler();}
+            xreq.open('POST', OSRF_HTTP_TRANSLATOR, true);
+            xreq.setRequestHeader(OSRF_HTTP_HEADER_MULTIPART, 'true');
+
+            /* multipart requests do not pass the status info to the onload if there 
+               is no new data to load.  Capture the status on the readystate handler */
+            xreq.onreadystatechange = function() {
+                if(xreq.readyState == 4 && xreq.status >= 400)
+                    xhr_req.transport_error_handler();
+            }
+        }
+    }
+
+    xreq.setRequestHeader('Content-Type', OSRF_POST_CONTENT_TYPE);
+    xreq.setRequestHeader(OSRF_HTTP_HEADER_THREAD, this.args.thread);
+    if(this.args.rcpt)
+        xreq.setRequestHeader(OSRF_HTTP_HEADER_TO, this.args.rcpt);
+    else
+        xreq.setRequestHeader(OSRF_HTTP_HEADER_SERVICE, this.args.rcpt_service);
+
+    var post = 'osrf-msg=' + encodeURIComponent(js2JSON([this.message.serialize()]));
+    xreq.send(post);
+
+    if(this.args.timeout) /* this was a blocking call, manually run the handler */
+        this.core_handler()
+
+    return this;
+}
+
+OpenSRF.XHRequest.prototype.core_handler = function() {
+    sender = this.xreq.getResponseHeader(OSRF_HTTP_HEADER_FROM);
+    thread = this.xreq.getResponseHeader(OSRF_HTTP_HEADER_THREAD);
+    json = this.xreq.responseText;
+    stat = this.xreq.status;
+
+    if(stat >= 400) 
+        return this.transport_error_handler();
+
+    OpenSRF.Stack.push(
+        new OpenSRF.NetMessage(null, sender, thread, json),
+        {
+            onresponse : this.args.onresponse,
+            oncomplete : this.args.oncomplete,
+            onerror : this.args.onerror,
+            onmethoderror : this.method_error_handler()
+        }
+    );
+}
+
+
+OpenSRF.XHRequest.prototype.method_error_handler = function() {
+    var xhr = this;
+    return function(req, status, status_text) {
+        if(xhr.args.onmethoderror) 
+            xhr.args.onmethoderror(req, status, status_text);
+        if(xhr.args.onerror)  
+            xhr.args.onerror(xhr.message, xhr.args.rcpt || xhr.args.rcpt_service, xhr.args.thread);
+    }
+}
+
+OpenSRF.XHRequest.prototype.transport_error_handler = function() {
+    if(this.args.ontransporterror) 
+        this.args.ontransporterror(this.xreq);
+    if(this.args.onerror) 
+        this.args.onerror(this.message, this.args.rcpt || this.args.rcpt_service, this.args.thread);
+}
+
+