[Pkg-javascript-commits] [sockjs-client] 33/434: Refactoring the world continues.
Tonnerre Lombard
tonnerre-guest at moszumanska.debian.org
Wed Jan 8 00:46:59 UTC 2014
This is an automated email from the git hooks/post-receive script.
tonnerre-guest pushed a commit to branch master
in repository sockjs-client.
commit b6485b427c1f3bbec054492e3e9bf440a6d08161
Author: Marek Majkowski <majek04 at gmail.com>
Date: Mon Aug 1 11:45:32 2011 +0100
Refactoring the world continues.
---
lib/main.js | 4 +-
lib/sockjs.js | 8 +-
lib/trans-iframe-eventsource.js | 16 ++--
lib/trans-iframe-htmlfile.js | 41 +++------
lib/trans-iframe-within.js | 11 ++-
lib/trans-iframe.js | 19 ++--
lib/{trans-jsonp.js => trans-jsonp-receiver.js} | 80 +----------------
lib/trans-jsonp-sender.js | 8 ++
lib/trans-jsonp.js | 110 +++---------------------
lib/utils.js | 15 +++-
tests-src/test-factory.coffee | 7 ++
11 files changed, 85 insertions(+), 234 deletions(-)
diff --git a/lib/main.js b/lib/main.js
index e617bbf..fbfac9d 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -8,6 +8,7 @@ SockJS = (function(){
<!-- include lib/sockjs.js -->
<!-- include lib/trans-websocket.js -->
<!-- include lib/trans-jsonp-sender.js -->
+<!-- include lib/trans-jsonp-receiver.js -->
<!-- include lib/trans-jsonp.js -->
<!-- include lib/trans-iframe.js -->
<!-- include lib/trans-iframe-within.js -->
@@ -15,4 +16,5 @@ SockJS = (function(){
<!-- include lib/trans-iframe-htmlfile.js -->
return SockJS;
})();
-if ('_sockjs_onload' in window) setTimeout(function(){_sockjs_onload();}, 0);
+if ('_sockjs_onload' in window) setTimeout(_sockjs_onload, 1);
+
diff --git a/lib/sockjs.js b/lib/sockjs.js
index cc2d847..01f5f1c 100644
--- a/lib/sockjs.js
+++ b/lib/sockjs.js
@@ -36,7 +36,7 @@ SockJS.prototype._debug = function() {
SockJS.prototype._dispatchOpen = function() {
var that = this;
if (that.readyState !== SockJS.CONNECTING)
- throw Error('INVALID_STATE_ERR');
+ throw new Error('INVALID_STATE_ERR');
that.readyState = SockJS.OPEN;
that.dispatchEvent(new SimpleEvent("open"));
};
@@ -54,7 +54,7 @@ SockJS.prototype._didClose = function(status, reason) {
if (that.readyState !== SockJS.CONNECTING &&
that.readyState !== SockJS.OPEN &&
that.readyState !== SockJS.CLOSING)
- throw Error('INVALID_STATE_ERR');
+ throw new Error('INVALID_STATE_ERR');
that._transport.doCleanup();
that._transport = null;
var close_event = new SimpleEvent("close", {status: status, reason: reason});
@@ -119,7 +119,7 @@ SockJS.prototype._try_next_protocol = function(close_event) {
SockJS.prototype.close = function(status, reason) {
var that = this;
if (status && !utils.userSetStatus(status))
- throw Error("INVALID_ACCESS_ERR");
+ throw new Error("INVALID_ACCESS_ERR");
if(that.readyState !== SockJS.CONNECTING &&
that.readyState !== SockJS.OPEN) {
return false;
@@ -132,7 +132,7 @@ SockJS.prototype.close = function(status, reason) {
SockJS.prototype.send = function(data) {
var that = this;
if (that.readyState === SockJS.CONNECTING)
- throw Error('INVALID_STATE_ERR');
+ throw new Error('INVALID_STATE_ERR');
if (that.readyState === SockJS.OPEN) {
that._transport.doSend(JSON.stringify(data));
}
diff --git a/lib/trans-iframe-eventsource.js b/lib/trans-iframe-eventsource.js
index 359cad2..d42d04e 100644
--- a/lib/trans-iframe-eventsource.js
+++ b/lib/trans-iframe-eventsource.js
@@ -20,8 +20,8 @@ var EventSourceTransport = FacadeJS['w-iframe-eventsource'] = function (ri, tran
var es = that.es = new EventSource(url);
es.onmessage = function(e) {that.ri._didMessage(unescape(e.data));};
es.onerror = function(e) {
- // EventSource reconnects automatically by default.
- that.cleanup();
+ // EventSource reconnects automatically.
+ es.close();
that.ri._didClose(1001, "Socket closed.");
};
that.send_constructor(ajaxSender);
@@ -29,19 +29,13 @@ var EventSourceTransport = FacadeJS['w-iframe-eventsource'] = function (ri, tran
// Inheritnace
EventSourceTransport.prototype = new BufferedSender();
-EventSourceTransport.prototype.cleanup = function() {
+EventSourceTransport.prototype.doCleanup = function() {
var that = this;
var es = that.es;
es.onmessage = es.onerror = null;
es.close();
- that.es = null;
-};
-
-EventSourceTransport.prototype.doClose = function(data) {
- var that = this;
- that.cleanup();
- // Send didClose out of band.
- setTimeout(function(){that.ri._didClose(1001, "Socket closed.");}, 0);
+ that.send_destructor();
+ that.es = that.ri = null;
};
diff --git a/lib/trans-iframe-htmlfile.js b/lib/trans-iframe-htmlfile.js
index a1ef1be..23086c4 100644
--- a/lib/trans-iframe-htmlfile.js
+++ b/lib/trans-iframe-htmlfile.js
@@ -1,7 +1,7 @@
var HtmlFileIframeTransport = SockJS['iframe-htmlfile'] = function () {
var that = this;
that.protocol = 'w-iframe-htmlfile';
- that.i_constructor.apply(this, arguments);
+ that.i_constructor.apply(that, arguments);
};
// Inheritance.
HtmlFileIframeTransport.prototype = new IframeTransport();
@@ -20,46 +20,29 @@ var HtmlFileTransport = FacadeJS['w-iframe-htmlfile'] = function (ri, trans_url)
that.id = 'a' + utils.random_string(6, 26);
var iframe_url = trans_url + '/htmlfile?c=' + escape(WPrefix + '.' + that.id);
- var callback = function(e, t) {
- // alert('cb' + e + ' ' + t);
- // if (window.console)
- // console.log('cb', e, t, typeof t);
- switch(t) {
- case 'close':
- if (e) {
- that.ri._didClose(e.status, e.reason);
- } else {
- that.ri._didClose(1001, "Server closed iframe");
- }
- break;
- }
- if (typeof t === 'undefined') {
- that.ri._didMessage(e);
+ that.is_loaded = false;
+ var callback = function(data) {
+ if (!that.is_loaded) {
+ that.is_loaded = true;
+ that.iframeObj.loaded();
}
+ that.ri._didMessage(data);
};
_window[WPrefix][that.id] = callback;
- that.iframeObj = utils.createIframe(iframe_url, function() {
- that.cleanup();
- that.ri._didClose(1001, "Can't load iframe");
+ that.iframeObj = utils.createIframe(iframe_url, function(e) {
+ that.doCleanup();
+ that.ri._didClose(1001, "Can't load htmlfile iframe (" + e + ")");
});
};
// Inheritnace
HtmlFileTransport.prototype = new BufferedSender();
-HtmlFileTransport.prototype.cleanup = function() {
+HtmlFileTransport.prototype.doCleanup = function() {
var that = this;
if (that.iframeObj) {
that.iframeObj.cleanup();
delete _window[WPrefix][that.id];
}
+ that.send_destructor();
};
-
-HtmlFileTransport.prototype.doClose = function(data) {
- var that = this;
- that.cleanup();
- // Send didClose out of band.
- setTimeout(function(){that.ri._didClose(1001, "Socket closed.");}, 0);
-};
-
-
diff --git a/lib/trans-iframe-within.js b/lib/trans-iframe-within.js
index b392c9d..a43a81c 100644
--- a/lib/trans-iframe-within.js
+++ b/lib/trans-iframe-within.js
@@ -7,18 +7,17 @@ var postMessage = function (type, data) {
};
var FacadeJS = function() {};
-FacadeJS.prototype._debug = function () {};
FacadeJS.prototype._didClose = function (status, reason) {
postMessage('t', utils.closeFrame(status, reason));
};
FacadeJS.prototype._didMessage = function (frame) {
postMessage('t', frame);
};
-FacadeJS.prototype.send = function (data) {
+FacadeJS.prototype._doSend = function (data) {
this._transport.doSend(data);
};
-FacadeJS.prototype.close = function () {
- this._transport.doClose();
+FacadeJS.prototype._doCleanup = function () {
+ this._transport.doCleanup();
};
SockJS.bootstrap_iframe = function() {
@@ -42,10 +41,10 @@ SockJS.bootstrap_iframe = function() {
facade._transport = new FacadeJS[protocol](facade, trans_url);
break;
case 'm':
- facade.send(data);
+ facade._doSend(data);
break;
case 'c':
- facade.close();
+ facade._doCleanup();
facade = null;
break;
}
diff --git a/lib/trans-iframe.js b/lib/trans-iframe.js
index a3cb88d..b68e07d 100644
--- a/lib/trans-iframe.js
+++ b/lib/trans-iframe.js
@@ -23,7 +23,7 @@ IframeTransport.prototype.i_constructor = function(ri, trans_url, base_url) {
that.ri._didClose(1006, "Unable to load an iframe (" + r + ")");
});
- that.onmessage_cb = function(e){that.onmessage(e);};
+ that.onmessage_cb = utils.bind(that.onmessage, that);
utils.attachMessage(that.onmessage_cb);
};
@@ -31,10 +31,19 @@ IframeTransport.prototype.doCleanup = function() {
var that = this;
if (that.iframeObj) {
utils.detachMessage(that.onmessage_cb);
- if (that.iframeObj.iframe.contentWindow){
- that.postMessage('c');
- }
- that.iframeObj.cleanup();
+ try {
+ // When the iframe is not loaded, IE raises an exception
+ // on 'contentWindow'.
+ if (that.iframeObj.iframe.contentWindow) {
+ that.postMessage('c');
+ }
+ } catch (x) {}
+ var iframeObj = that.iframeObj;
+ // Give the iframe some time for cleanup.
+ setTimeout(function() {
+ iframeObj.cleanup();
+ iframeObj = null;
+ }, 100);
that.onmessage_cb = that.iframeObj = null;
}
};
diff --git a/lib/trans-jsonp.js b/lib/trans-jsonp-receiver.js
similarity index 60%
copy from lib/trans-jsonp.js
copy to lib/trans-jsonp-receiver.js
index 785d4c4..696ca91 100644
--- a/lib/trans-jsonp.js
+++ b/lib/trans-jsonp-receiver.js
@@ -1,77 +1,3 @@
-// The simplest and most robust transport, using the well-know cross
-// domain hack - JSONP. This transport is quite inefficient - one
-// mssage could use up to one http request. But at least it works almost
-// everywhere.
-// Known limitations:
-// o you will get a spinning cursor
-// o for Konqueror a dumb timer is needed to detect errors
-
-
-var JsonPTransport = SockJS.jsonp = function(ri, trans_url){
- utils.polluteGlobalNamespace();
- var that = this;
- that.ri = ri;
- that.trans_url = trans_url;
- that.send_constructor(jsonPGenericSender);
- that._schedule_recv();
-};
-
-// Inheritnace
-JsonPTransport.prototype = new BufferedSender();
-
-JsonPTransport.prototype._schedule_recv = function() {
- var that = this;
- var callback = function(data) {
- that._recv_stop = null;
- if (!that._is_closing) {
- that.ri._didMessage(data);
- }
- // The message can be a close message, and change is_closing state.
- if (!that._is_closing) {
- that._schedule_recv();
- }
- };
- that._recv_stop = jsonPReceiverWrapper(that.trans_url + '/jsonp',
- jsonPGenericReceiver, callback);
-};
-
-JsonPTransport.prototype.doCleanup = function() {
- var that = this;
- that._is_closing = true;
- if (that._recv_stop) {
- that._recv_stop();
- }
- if (that._send_stop) {
- that._send_stop();
- }
- that.ri = that._recv_stop = that._send_stop = null;
-};
-
-JsonPTransport.enabled = function() {
- return true;
-};
-
-
-// Abstract away code that handles global namespace pollution.
-var jsonPReceiverWrapper = function(url, constructReceiver, user_callback) {
- var id = 'a' + utils.random_string(6);
- var url_id = url + '?c=' + escape(WPrefix + '.' + id);
- // Callback will be called exactly once.
- var callback = function(frame) {
- delete _window[WPrefix][id];
- user_callback(frame);
- };
-
- var close_script = constructReceiver(url_id, callback);
- _window[WPrefix][id] = close_script;
- var stop = function() {
- if (_window[WPrefix][id]) {
- _window[WPrefix][id](utils.closeFrame(1000, "JSONP user aborted read"));
- }
- };
- return stop;
-};
-
// Parts derived from Socket.io:
// https://github.com/LearnBoost/socket.io/blob/0.6.17/lib/socket.io/transports/jsonp-polling.js
// and jQuery-JSONP:
@@ -140,7 +66,7 @@ var jsonPGenericReceiver = function(url, callback) {
} catch (x) {}
script.async = true;
} else if (typeof _document.attachEvent === 'function') {
- // opera, second sync script hack
+ // Opera, second sync script hack
script2 = _document.createElement('script');
script2.text = "try{document.getElementById('"+script.id+"').onerror();}catch(x){};";
script.async = script2.async = false;
@@ -149,9 +75,9 @@ var jsonPGenericReceiver = function(url, callback) {
script.async = true;
}
// Fallback mostly for Konqueror - stupid timer, 5 seconds shall be plenty.
- tref = setTimeout(function(){
+ tref = setTimeout(function() {
close_script(utils.closeFrame(1006, "JSONP script loaded abnormally (timeout)"));
- }, 5000);
+ }, 15000);
var head = _document.getElementsByTagName('head')[0];
head.insertBefore(script, head.firstChild);
diff --git a/lib/trans-jsonp-sender.js b/lib/trans-jsonp-sender.js
index 47b12b8..95c29d3 100644
--- a/lib/trans-jsonp-sender.js
+++ b/lib/trans-jsonp-sender.js
@@ -26,6 +26,14 @@ BufferedSender.prototype.send_schedule = function(message) {
}
};
+BufferedSender.prototype.send_destructor = function() {
+ var that = this;
+ if (that._send_stop) {
+ that._send_stop();
+ }
+ that._send_stop = null;
+};
+
var jsonPGenericSender = function(url, payload, callback) {
var that = this;
if (!('_send_form' in that)) {
diff --git a/lib/trans-jsonp.js b/lib/trans-jsonp.js
index 785d4c4..02bb5ae 100644
--- a/lib/trans-jsonp.js
+++ b/lib/trans-jsonp.js
@@ -23,8 +23,11 @@ JsonPTransport.prototype._schedule_recv = function() {
var that = this;
var callback = function(data) {
that._recv_stop = null;
- if (!that._is_closing) {
- that.ri._didMessage(data);
+ if (data) {
+ // no data - heartbeat;
+ if (!that._is_closing) {
+ that.ri._didMessage(data);
+ }
}
// The message can be a close message, and change is_closing state.
if (!that._is_closing) {
@@ -35,20 +38,18 @@ JsonPTransport.prototype._schedule_recv = function() {
jsonPGenericReceiver, callback);
};
+JsonPTransport.enabled = function() {
+ return true;
+};
+
JsonPTransport.prototype.doCleanup = function() {
var that = this;
that._is_closing = true;
if (that._recv_stop) {
that._recv_stop();
}
- if (that._send_stop) {
- that._send_stop();
- }
- that.ri = that._recv_stop = that._send_stop = null;
-};
-
-JsonPTransport.enabled = function() {
- return true;
+ that.ri = that._recv_stop = null;
+ that.send_destructor();
};
@@ -71,92 +72,3 @@ var jsonPReceiverWrapper = function(url, constructReceiver, user_callback) {
};
return stop;
};
-
-// Parts derived from Socket.io:
-// https://github.com/LearnBoost/socket.io/blob/0.6.17/lib/socket.io/transports/jsonp-polling.js
-// and jQuery-JSONP:
-// https://code.google.com/p/jquery-jsonp/source/browse/trunk/core/jquery.jsonp.js
-var jsonPGenericReceiver = function(url, callback) {
- var tref;
- var script = _document.createElement('script');
- var script2; // Opera synchronous load trick.
- var close_script = function(frame) {
- if (script2) {
- script2.parentNode.removeChild(script2);
- script2 = null;
- }
- if (script) {
- clearTimeout(tref);
- script.parentNode.removeChild(script);
- script.onreadystatechange = script.onerror =
- script.onload = script.onclick = null;
- script = null;
- callback(frame);
- callback = null;
- }
- };
- script.id = 'a' + utils.random_string(8);
- script.src = url;
- script.type = 'text/javascript';
- script.charset = 'UTF-8';
- script.onerror = function() {
- close_script(utils.closeFrame(1006, "JSONP script loaded abnormally (onerror)"));
- };
- script.onload = function(e) {
- close_script(utils.closeFrame(1006, "JSONP script loaded abnormally (onload)"));
- };
- script.onreadystatechange = function(e) {
- if (/loaded|closed/.test(script.readyState)) {
- if (script && script.htmlFor && script.onclick) {
- try {
- // In IE, actually execute the script.
- script.onclick();
- } catch (x) {}
- }
- if (script) {
- close_script(utils.closeFrame(1006, "JSONP script loaded abnormally (onreadystatechange)"));
- }
- }
- };
- // IE: event/htmlFor/onclick trick.
- // One can't rely on proper order for onreadystatechange. In order to
- // make sure, set a 'htmlFor' and 'event' properties, so that
- // script code will be installed as 'onclick' handler for the
- // script object. Later, onreadystatechange, manually execute this
- // code. FF and Chrome doesn't work with 'event' and 'htmlFor'
- // set. For reference see:
- // http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html
- // Also, read on that about script ordering:
- // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
- if (typeof script.async === 'undefined') {
- // According to mozilla docs, in recent browsers script.async defaults
- // to 'true', so we may use it to detect a good browser:
- // https://developer.mozilla.org/en/HTML/Element/script
- if (typeof _document.attachEvent === 'object') {
- // ie
- try {
- script.htmlFor = script.id;
- script.event = "onclick";
- } catch (x) {}
- script.async = true;
- } else if (typeof _document.attachEvent === 'function') {
- // opera, second sync script hack
- script2 = _document.createElement('script');
- script2.text = "try{document.getElementById('"+script.id+"').onerror();}catch(x){};";
- script.async = script2.async = false;
- }
- } else {
- script.async = true;
- }
- // Fallback mostly for Konqueror - stupid timer, 5 seconds shall be plenty.
- tref = setTimeout(function(){
- close_script(utils.closeFrame(1006, "JSONP script loaded abnormally (timeout)"));
- }, 5000);
-
- var head = _document.getElementsByTagName('head')[0];
- head.insertBefore(script, head.firstChild);
- if (script2) {
- head.insertBefore(script2, head.firstChild);
- }
- return close_script;
-};
diff --git a/lib/utils.js b/lib/utils.js
index d59da4a..ed3bf99 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -143,13 +143,14 @@ utils.createIframe = function (iframe_url, error_callback) {
if (iframe) {
unattach();
iframe.parentNode.removeChild(iframe);
+ iframe.src = "about:blank";
iframe = null;
}
};
- var onerror = function() {
+ var onerror = function(r) {
if (iframe) {
cleanup();
- error_callback();
+ error_callback(r);
}
};
iframe.src = iframe_url;
@@ -184,3 +185,13 @@ utils.log = function() {
console.log.apply(console, arguments);
}
};
+
+utils.bind = function(fun, that) {
+ if (fun.bind) {
+ return fun.bind(that);
+ } else {
+ return function() {
+ return fun.apply(that, arguments);
+ };
+ }
+};
diff --git a/tests-src/test-factory.coffee b/tests-src/test-factory.coffee
index 77bb949..3cc985d 100644
--- a/tests-src/test-factory.coffee
+++ b/tests-src/test-factory.coffee
@@ -5,6 +5,7 @@ echo_factory_factory = (protocol, messages) ->
r = new SockJS(sockjs_url + '/echo', [protocol])
ok(r)
r.onopen = (e) ->
+ log('onopen', e)
ok(true)
r.send(a[0])
r.onmessage = (e) ->
@@ -15,6 +16,7 @@ echo_factory_factory = (protocol, messages) ->
else
r.send(a[0])
r.onclose = (e) ->
+ log('a', ''+e)
ok(true)
start()
@@ -63,6 +65,11 @@ factor_echo_special_chars = (protocol) ->
"\nmessage",
"message\xff",
"\xffmessage",
+ "A",
+ "b",
+ "c",
+ "d",
+ "e",
"\ufffd",
"\ufffd\u0000",
"message\ufffd",
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/sockjs-client.git
More information about the Pkg-javascript-commits
mailing list