aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Karneges <justin@affinix.com>2013-01-28 14:22:45 -0800
committerJustin Karneges <justin@affinix.com>2013-01-28 14:22:45 -0800
commitdee58864a8b761ce8ed11aa74ad9d7344e8c9b78 (patch)
tree7a1fc5b3e76fccc7347fc90d091291486d9c8374
parent06a444a0c776b158067d5b5dc0ef73df221534a3 (diff)
downloadpollymer-dee58864a8b761ce8ed11aa74ad9d7344e8c9b78.tar
pollymer-dee58864a8b761ce8ed11aa74ad9d7344e8c9b78.tar.gz
initial file based on fanout's pubsub.js
-rw-r--r--polldance.js192
1 files changed, 192 insertions, 0 deletions
diff --git a/polldance.js b/polldance.js
new file mode 100644
index 0000000..906aed6
--- /dev/null
+++ b/polldance.js
@@ -0,0 +1,192 @@
+// don't break if there's no console
+if(typeof(console) === "undefined")
+{
+ console = { log: function() {} };
+}
+
+var FO = FO || {};
+
+var fo_jsonp_callback_id = 0;
+var fo_jsonp_callbacks = {};
+
+function fo_jsonp_get_callback(cb_id)
+{
+ if(fo_jsonp_callbacks[cb_id])
+ {
+ return fo_jsonp_callbacks[cb_id];
+ }
+ else
+ {
+ console.log("no callback with id " + cb_id);
+ return function(result) {};
+ }
+}
+
+// FO.Request has onFinished(int code, object result) and onError(int reason) callback members
+// error reasons: 0=http, 1=timeout
+// note: failed json parse on http body results in empty object {}, not error
+
+FO.Request = function()
+{
+ if(!(this instanceof FO.Request))
+ throw new Error("Constructor called as a function");
+}
+
+FO.Request.prototype.start = function(method, url, headers, body)
+{
+ this._cors = false;
+ if("withCredentials" in new XMLHttpRequest())
+ this._cors = true;
+
+ var self = this;
+ this._timer = setTimeout(function() { self._timeout(); }, 60000);
+
+ if(this._cors)
+ {
+ this._xhr = new XMLHttpRequest();
+
+ this._xhr.onreadystatechange = function() { self._xhr_readystatechange(); };
+ this._xhr.open(method, url, true);
+
+ for(var key in headers)
+ {
+ if(!headers.hasOwnProperty(key))
+ continue;
+
+ this._xhr.setRequestHeader(key, headers[key]);
+ }
+
+ this._xhr.send(body);
+ }
+ else
+ {
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+
+ script.type = "text/javascript";
+
+ this._cb_id = fo_jsonp_callback_id.toString();
+ ++fo_jsonp_callback_id;
+
+ this._script_id = "fo-jsonp-script-" + this._cb_id;
+ script.id = this._script_id;
+
+ fo_jsonp_callbacks[this._cb_id] = function(result) { self._jsonp_callback(result); };
+
+ var param_list = new Array();
+
+ param_list.push("callback=" + encodeURIComponent("fo_jsonp_get_callback(\"" + this._cb_id + "\")"));
+ if(method != "GET")
+ param_list.push("method=" + encodeURIComponent(method));
+ if(headers)
+ param_list.push("headers=" + encodeURIComponent(JSON.stringify(headers)));
+ if(body)
+ param_list.push("body=" + encodeURIComponent(body));
+
+ var params = param_list.join("&");
+
+ var src;
+ if(url.indexOf("?") != -1)
+ src = url + "&" + params;
+ else
+ src = url + "?" + params;
+
+ script.src = src;
+ console.log("FO.Request json-p " + this._cb_id + " " + src);
+ head.appendChild(script);
+ }
+}
+
+FO.Request.prototype.abort = function()
+{
+ clearTimeout(this._timer);
+ this._timer = null;
+
+ this._cancelreq();
+}
+
+FO.Request.prototype._cancelreq = function()
+{
+ if(this._cors)
+ {
+ this._xhr.onreadystatechange = function() {}
+ this._xhr.abort();
+ this._xhr = null;
+ }
+ else
+ {
+ console.log("FO.Request json-p " + this._cb_id + " timeout");
+
+ delete fo_jsonp_callbacks[this._cb_id];
+ var script = document.getElementById(this._script_id);
+ script.parentNode.removeChild(script);
+ this._cb_id = null;
+ this._script_id = null;
+ }
+}
+
+FO.Request.prototype._xhr_readystatechange = function()
+{
+ if(this._xhr.readyState === 4)
+ {
+ clearTimeout(this._timer);
+ this._timer = null;
+
+ var status = this._xhr.status;
+ var responseText = this._xhr.responseText;
+ this._xhr = null;
+
+ if(status)
+ {
+ var result;
+
+ try
+ {
+ result = JSON.parse(responseText);
+ }
+ catch(e)
+ {
+ result = {}
+ }
+
+ this._finished(status, result);
+ }
+ else
+ this._error(0);
+ }
+}
+
+FO.Request.prototype._jsonp_callback = function(result)
+{
+ console.log("FO.Request json-p " + this._cb_id + " finished");
+
+ clearTimeout(this._timer);
+ this._timer = null;
+
+ delete fo_jsonp_callbacks[this._cb_id];
+ var script = document.getElementById(this._script_id);
+ script.parentNode.removeChild(script);
+ this._cb_id = null;
+ this._script_id = null;
+
+ this._finished(result.status, result.value);
+}
+
+FO.Request.prototype._timeout = function()
+{
+ this._timer = null;
+ this._cancelreq();
+ this._error(1);
+}
+
+FO.Request.prototype._finished = function(code, result)
+{
+ if(this.onFinished)
+ this.onFinished(code, result);
+}
+
+FO.Request.prototype._error = function(reason)
+{
+ if(this.onError)
+ this.onError(reason);
+}