[Pkg-javascript-commits] [sockjs-client] 01/434: Initial commit
Tonnerre Lombard
tonnerre-guest at moszumanska.debian.org
Wed Jan 8 00:46:56 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 a4fed05db6be1351f289bab53e65e7b555c27130
Author: Marek Majkowski <majek04 at gmail.com>
Date: Fri Jul 22 15:17:30 2011 +0100
Initial commit
---
bin/minify.js | 22 +++++
bin/render.js | 55 +++++++++++
bin/simple_http_server.js | 48 +++++++++
index.html | 45 +++++++++
lib/main.js | 8 ++
lib/reventtarget.js | 38 +++++++
lib/simpleevent.js | 20 ++++
lib/sockjs.js | 144 +++++++++++++++++++++++++++
lib/trans-jsonp.js | 180 +++++++++++++++++++++++++++++++++
lib/trans-ws.js | 31 ++++++
lib/utils.js | 85 ++++++++++++++++
package.json | 8 ++
run.sh | 27 +++++
static/jquery.min.js | 18 ++++
static/json2.min.js | 1 +
static/qunit.css | 225 ++++++++++++++++++++++++++++++++++++++++++
static/qunit.min.js | 1 +
tests-src/test-factory.coffee | 85 ++++++++++++++++
tests-src/test-run.coffee | 15 +++
tests/.placeholder | 0
20 files changed, 1056 insertions(+)
diff --git a/bin/minify.js b/bin/minify.js
new file mode 100644
index 0000000..8e49565
--- /dev/null
+++ b/bin/minify.js
@@ -0,0 +1,22 @@
+var fs = require('fs');
+var uglify = require('uglify-js');
+
+(function(){
+ var content = [];
+ var filenames = [];
+ for(var i = 2; i < process.argv.length; i++) {
+ var filename = process.argv[i];
+ filenames.push(filename);
+ var data = fs.readFileSync(filename, encoding='utf8');
+ content.push( data );
+ }
+ console.warn(" [.] Minifying:", filenames.join(', '));
+
+ var data = content.join('\n');
+ var ast = uglify.parser.parse(data);
+ ast = uglify.uglify.ast_mangle(ast);
+ ast = uglify.uglify.ast_squeeze(ast);
+ var minified = uglify.uglify.gen_code(ast);
+
+ process.stdout.write(minified);
+ })();
diff --git a/bin/render.js b/bin/render.js
new file mode 100644
index 0000000..c466ef6
--- /dev/null
+++ b/bin/render.js
@@ -0,0 +1,55 @@
+var fs = require('fs');
+
+function array_flatten(arr, acc) {
+ if (typeof acc === 'undefined') {
+ acc = [];
+ }
+ if(typeof arr === 'string') {
+ acc.push(arr);
+ return acc;
+ } else if (arr.constructor !== Array) {
+ throw "Value is not an Array nor a String!";
+ }
+ for(var i=0, l=arr.length; i < l; i++) {
+ var v = arr[i];
+ if(typeof v === 'string') {
+ acc.push(v);
+ } else if(v.constructor === Array) {
+ array_flatten(v, acc);
+ }else{
+ throw "Value is not an Array nor a String!";
+ }
+ }
+ return acc;
+}
+
+function render(filename, depth) {
+ console.warn(depth + " [.] Rendering", filename);
+
+ var data = fs.readFileSync(filename, encoding='utf8');
+ data = data.replace(/\s+$/, ''); // trailing whitespace
+ var content = [];
+ content.push('// ' + depth + '[*] Including ' + filename);
+
+ var elements = data.split(/<!--\s*include\s+(\S+)\s*-->/g);
+ for(var i=0; i < elements.length; i++) {
+ var e = elements[i];
+ if(i % 2 === 0) {
+ content.push(e);
+ } else {
+ content.push( render(e, depth + ' ') );
+ }
+ }
+ content.push('// ' + depth + '[*] End of ' + filename);
+ return content;
+}
+
+(function(){
+ var content = [];
+ for(var i = 2; i < process.argv.length; i++) {
+ var filename = process.argv[i];
+ content.push( render(filename, '') );
+ }
+ content.push('\n');
+ process.stdout.write(array_flatten(content).join('\n'), 'utf8');
+})();
diff --git a/bin/simple_http_server.js b/bin/simple_http_server.js
new file mode 100644
index 0000000..d5e13fb
--- /dev/null
+++ b/bin/simple_http_server.js
@@ -0,0 +1,48 @@
+var http = require('http');
+var url = require('url');
+var fs = require('fs');
+var path = require('path');
+
+var port = 8000;
+var host = "0.0.0.0";
+
+var mimetypes = {
+ html: 'text/html',
+ htm: 'text/html',
+ js: 'application/javascript',
+ json: 'application/json',
+ css: 'text/css',
+ png: 'image/png',
+ jpeg: 'image/jpeg',
+ jpg: 'image/jpeg',
+ gif: 'image/gif'
+};
+var handler = function(req, res) {
+ var filename = url.parse(req.url).pathname.slice(1) || 'index.html';
+ var cb = function (error, content) {
+ try{
+ if (error) {
+ console.log(req.method, filename, 404);
+ res.writeHead(404);
+ res.end();
+ } else {
+ console.log(req.method, filename, 200, content.length);
+ res.setHeader('Content-length', content.length);
+ var mimetype = mimetypes[path.extname(filename).slice(1)] || 'text/plain';
+ mimetype += '; charset=UTF-8';
+ res.setHeader('Content-type', mimetype);
+ res.writeHead(200, res.headers);
+ res.write(content);
+ res.end();
+ }
+ } catch (x) {
+ console.log(req.method, filename, "(closed)");
+ }
+ };
+ fs.readFile(filename, cb);
+};
+
+console.log(" [*] Listening on", host + ':' + port);
+var server = http.createServer();
+server.addListener('request', handler);
+server.listen(port, host);
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..049ce10
--- /dev/null
+++ b/index.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+ <meta charset="UTF-8" />
+
+ <link href="data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAAF0lEQVRIx2NgGAWjYBSMglEwCkbBSAcACBAAAeaR9cIAAAAASUVORK5CYII=" rel="icon" type="image/x-icon" />
+
+ <script type="text/javascript" src="sockjs.js"></script>
+
+ <script type="text/javascript" src="static/json2.min.js"></script>
+ <script type="text/javascript" src="static/jquery.min.js"></script>
+ <link rel="stylesheet" href="static/qunit.css" type="text/css" media="screen">
+ <script type="text/javascript" src="static/qunit.min.js"></script>
+
+ <script type="text/javascript" src="tests/test-factory.js"></script>
+ <script type="text/javascript" src="tests/test-run.js"></script>
+</head>
+<body>
+ <p>
+ <h1 id="qunit-header">SockJS Test Suite</h1>
+ <h2 id="qunit-banner"></h2>
+ <div id="qunit-testrunner-toolbar"></div>
+ <h2 id="qunit-userAgent"></h2>
+ <ol id="qunit-tests"></ol>
+ <div id="qunit-fixture">test markup</div>
+ </p>
+ <br>
+ <code id="logs" style="height:200px; overflow:auto; display: block; border: 1px grey solid;">
+ </code>
+
+<script>
+ var test_server_url = 'http://172.16.173.128:9999';
+ function log(a, e) {
+ if ('console' in window && 'log' in window.console) {
+ console.log(a, e);
+ }
+ $('#logs').append($("<code>").text(a));
+ $('#logs').append($("<pre>").text(JSON.stringify(e, null, 4)));
+ $('#logs').append($("<br>"));
+ $('#logs').scrollTop($('#logs').scrollTop()+10000);
+ }
+</script>
+</body>
+</html>
diff --git a/lib/main.js b/lib/main.js
new file mode 100644
index 0000000..e31efb9
--- /dev/null
+++ b/lib/main.js
@@ -0,0 +1,8 @@
+(function(){
+<!-- include lib/reventtarget.js -->
+<!-- include lib/simpleevent.js -->
+<!-- include lib/utils.js -->
+<!-- include lib/sockjs.js -->
+<!-- include lib/trans-ws.js -->
+<!-- include lib/trans-jsonp.js -->
+ })();
diff --git a/lib/reventtarget.js b/lib/reventtarget.js
new file mode 100644
index 0000000..c4431f3
--- /dev/null
+++ b/lib/reventtarget.js
@@ -0,0 +1,38 @@
+var REventTarget = function() {
+ this._listeners = {};
+};
+REventTarget.prototype.addEventListener = function (eventType, listener) {
+ if(!(eventType in this._listeners)) {
+ this._listeners[eventType] = [];
+ }
+ this._listeners[eventType].push(listener);
+ return true;
+};
+REventTarget.prototype.removeEventListener = function (eventType, listener) {
+ if(!(eventType in this._listeners)) {
+ return false;
+ }
+ var arr = this._listeners[eventType];
+ var idx = arr.indexOf(listener);
+ if (idx !== -1) {
+ if(arr.length > 1) {
+ this._listeners[eventType] = arr.slice(0, idx).concat( a.slice(idx+1) );
+ } else {
+ delete this._listeners[eventType];
+ }
+ return true;
+ }
+ return false;
+};
+REventTarget.prototype.dispatchEvent = function (event) {
+ var t = event.type;
+ var args = Array.prototype.slice.call(arguments, 0);
+ if (typeof this['on'+t] !== 'undefined') {
+ this['on'+t].apply(this, args);
+ }
+ if (t in this._listeners) {
+ for(var i=0; i < this._listeners[t].length; i++) {
+ this._listeners[t][i].apply(this, args);
+ }
+ }
+};
diff --git a/lib/simpleevent.js b/lib/simpleevent.js
new file mode 100644
index 0000000..c57842d
--- /dev/null
+++ b/lib/simpleevent.js
@@ -0,0 +1,20 @@
+var SimpleEvent = function(type, obj) {
+ this.type = type;
+ if (typeof obj !== 'undefined') {
+ for(var k in obj) {
+ if (!obj.hasOwnProperty(k)) continue;
+ this[k] = obj[k];
+ }
+ }
+};
+
+SimpleEvent.prototype.toString = function() {
+ var r = [];
+ for(var k in this) {
+ if (!this.hasOwnProperty(k)) continue;
+ var v = this[k];
+ if (typeof v === 'function') v = '[function]';
+ r.push(k + '=' + v);
+ }
+ return 'SimpleEvent(' + r.join(', ') + ')';
+};
diff --git a/lib/sockjs.js b/lib/sockjs.js
new file mode 100644
index 0000000..f7a2084
--- /dev/null
+++ b/lib/sockjs.js
@@ -0,0 +1,144 @@
+// Public object.
+SockJS = function(url, protocols, options) {
+ this._options = {devel: true, debug: true};
+ if (typeof options !== 'undefined') {
+ utils.objectExtend(this._options, options);
+ }
+ this._base_url = url;
+ this._server = utils.random_number_string(1000);
+ this._connid = utils.random_string(8);
+ this._trans_url = this._base_url + '/' + this._server + '/' + this._connid;
+ this._protocols = ['ws', 'jsonp'];
+ switch(typeof protocols) {
+ case 'undefined': break;
+ case 'string': this._protocols = [protocols]; break;
+ default: this._protocols = protocols; break;
+ }
+ this.protocol = undefined;
+ this.readyState = SockJS.CONNECTING;
+ this._try_next_protocol();
+};
+// Inheritance
+SockJS.prototype = new REventTarget();
+
+SockJS.version = "0.0.1";
+
+SockJS.CONNECTING = 0;
+SockJS.OPEN = 1;
+SockJS.CLOSING = 2;
+SockJS.CLOSED = 3;
+
+SockJS.prototype._debug = function() {
+ if ('console' in window && console.log) {
+ console.log.apply(console, arguments);
+ }
+};
+
+// SockJS.prototype._emit = function(eventType, value, t) {
+// this._debug('emit', eventType, value, t);
+// if (this._protocol_is_fine === false &&
+// (eventType === 'open' || eventType === 'message')) {
+// this._protocol_is_fine = true;
+// }
+// switch(eventType) {
+// case 'open':
+// break;
+// case 'message':
+// break;
+// case 'stop':
+// break;
+// case 'close':
+// if ('wasClean' in value &&
+// value.wasClean === false &&
+// this._protocol_is_fine === false) {
+// this._try_next_protocol();
+// }
+// break; // ignore
+// case 'error':
+// break;
+// default:
+// }
+// //this.dispatchEvent(eventType, value);
+// };
+
+SockJS.prototype._didOpen = function() {
+ if (this.readyState !== SockJS.CONNECTING)
+ throw 'INVALID_STATE_ERR';
+ this.readyState = SockJS.OPEN;
+ this.dispatchEvent(new SimpleEvent("open"));
+};
+
+SockJS.prototype._didClose = function(status, reason) {
+ if (this.readyState !== SockJS.CONNECTING &&
+ this.readyState !== SockJS.OPEN &&
+ this.readyState !== SockJS.CLOSING)
+ throw 'INVALID_STATE_ERR';
+
+ var close_event = new SimpleEvent("close", {status: status, reason: reason});
+ if (this.readyState === SockJS.CONNECTING) {
+ if (this._try_next_protocol(close_event) === false) {
+ this.readyState = SockJS.CLOSED;
+ var e = new SimpleEvent("close", {status: 2000,
+ reason: "All transports failed."});
+ this.dispatchEvent(e);
+ }
+ } else {
+ if (this.readyState === SockJS.CLOSING &&
+ status === 1001 && this._close_status) {
+ close_event = new SimpleEvent("close", {status: this._close_status,
+ reason: this._close_reason});
+ }
+ this.readyState = SockJS.CLOSED;
+ this.dispatchEvent(close_event);
+ }
+};
+
+SockJS.prototype._didMessage = function(data) {
+ if (this.readyState !== SockJS.OPEN)
+ return;
+ this.dispatchEvent(new SimpleEvent("message", {data: data}));
+};
+
+SockJS.prototype._try_next_protocol = function(close_event) {
+ if (this.protocol)
+ this._debug('Closed transport:', this.protocol, close_event);
+
+ if (this._transport) {
+ delete this._transport; this._transport = undefined;
+ }
+
+ this.protocol = this._protocols.shift();
+ if (typeof this.protocol === 'undefined') {
+ return false;
+ }
+
+ this._debug('Opening transport:', this.protocol);
+ if (SockJS[this.protocol].enabled() === true) {
+ this._transport = new SockJS[this.protocol](this, this._trans_url, this._base_url);
+ return true;
+ }
+ var e = new SimpleEvent("close", {status: 1000,
+ reason: "Transport unavailable"});
+ return this._try_next_protocol(e);
+};
+
+SockJS.prototype.close = function(status, reason) {
+ if(this.readyState !== SockJS.CONNECTING &&
+ this.readyState !== SockJS.OPEN) {
+ return false;
+ }
+ this.readyState = SockJS.CLOSING;
+ this._close_status = status || 1000;
+ this._close_reason = reason || "Normal closure";
+ this._transport.doClose();
+ return true;
+};
+
+SockJS.prototype.send = function(data) {
+ if (this.readyState === SockJS.CONNECTING)
+ throw 'INVALID_STATE_ERR';
+ if (this.readyState === SockJS.OPEN) {
+ this._transport.doSend(data);
+ }
+ return true;
+};
diff --git a/lib/trans-jsonp.js b/lib/trans-jsonp.js
new file mode 100644
index 0000000..255aee8
--- /dev/null
+++ b/lib/trans-jsonp.js
@@ -0,0 +1,180 @@
+var JsonPrefix = '_jp';
+
+var JsonPTransport = SockJS.jsonp = function(ri, trans_url){
+ // Unavoidable namespace pollution.
+ if (!(JsonPrefix in window)) {window[JsonPrefix] = {};}
+ this.ri = ri;
+ this.url = trans_url;
+ this._send_buffer = [];
+ this._schedule_recv();
+};
+
+JsonPTransport.prototype._schedule_recv = function() {
+ var that = this;
+ var callback = function(e, t) {
+ that._recv_stop = undefined;
+ if (typeof t === 'undefined') {
+ // messages
+ for(var i=0; i < e.length; i++) {
+ that.ri._didMessage(e[i]);
+ }
+ } else {
+ switch (t) {
+ case 'open':
+ that.ri._didOpen();
+ break;
+ case 'heartbeat':
+ break;
+ case 'close':
+ if (e) {
+ that.ri._didClose(e.status, e.reason);
+ } else {
+ that.ri._didClose(1001, "Server closed connection");
+ }
+ break;
+ }
+ }
+ if (t !== 'close' && !that._is_closing) {
+ that._schedule_recv();
+ }
+ };
+ that._recv_stop = jsonPReceiverWrapper(this.url + '/jsonp',
+ jsonPGenericReceiver, callback);
+};
+
+JsonPTransport.prototype.doClose = function(status, reason) {
+ this._is_closing = true;
+ if (this._recv_stop) {
+ this._recv_stop();
+ }
+ if (this._send_stop) {
+ this._send_stop();
+ }
+ this._recv_stop = this._send_stop = undefined;
+ this.ri._didClose();
+};
+
+JsonPTransport.prototype.doSend = function(message) {
+ var that = this;
+ that._send_buffer.push(message);
+ var _schedule_send = function () {
+ if (that._send_buffer.length > 0) {
+ that._send_stop = jsonPGenericSender(that.url+'/send', that._send_buffer,
+ function() {
+ that._send_stop = undefined;
+ _schedule_send();
+ });
+ that._send_buffer = [];
+ }
+ };
+ if (typeof that._send_stop === 'undefined') {
+ _schedule_send();
+ }
+};
+
+JsonPTransport.enabled = function() {
+ return true;
+};
+
+
+var jsonPReceiverWrapper = function(url, constructReceiver, user_callback) {
+ var id = 'a' + utils.random_string(6);
+ var url_id = url + '?c=' + escape(JsonPrefix + '.' + id);
+ var callback = function(e, t) {
+ delete window[JsonPrefix][id];
+ user_callback(e, t);
+ };
+
+ var close_script = constructReceiver(url_id, callback);
+ window[JsonPrefix][id] = close_script;
+ var stop = function() {
+ if (window[JsonPrefix][id]) {
+ close_script({status:1000, reson:"Normal closure"}, 'stop');
+ }
+ };
+ return stop;
+};
+
+var jsonPGenericReceiver = function(url, callback) {
+ var script = document.createElement('script');
+ var close_script = function(v, t) {
+ if (typeof script !== 'undefined') {
+ callback(v, t);
+ script.parentNode.removeChild(script);
+ script.onreadystatechange = script.onerror = script.onload = null;
+ delete script;
+ script = callback = undefined;
+ }
+ };
+ script.async = true;
+ script.defer = true;
+ script.src = url;
+ script.type = 'text/javascript';
+ script.charset = 'UTF-8';
+ script.onerror = function(e) {
+ close_script({status:1001, reason:"Onerror triggered on script"},
+ 'close');
+ };
+ script.onload = function(e) {
+ close_script({status:1001, reason:"Onload triggered on script"},
+ 'close');
+ };
+ script.onreadystatechange = function(e) {
+ if (script.readyState == 'loaded' ||
+ script.readyState == 'complete') {
+ close_script({status:1001, reason:"Onreadystatechange triggered on script"},
+ 'close');
+ }
+ };
+ var head = document.getElementsByTagName('head')[0];
+ head.insertBefore(script, head.firstChild);
+ return close_script;
+};
+
+
+var jsonPGenericSender = function(url, messages, callback) {
+ var that = this;
+ if (!('_send_form' in that)) {
+ var form = that._send_form = document.createElement('form');
+ var area = document.createElement('textarea');
+ area.name = 'd';
+ form.style.display = 'none';
+ form.style.position = 'absolute';
+ form.method = 'POST';
+ form.enctype = 'application/x-www-form-urlencoded';
+ form.appendChild(area);
+ document.body.appendChild(form);
+ }
+ var form = that._send_form;
+ var id = 'a' + utils.random_string(8);
+ form.target = id;
+ form.action = url + '?i=' + id;
+
+ var iframe;
+ try {
+ // ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
+ iframe = document.createElement('<iframe name="'+ id +'">');
+ } catch(x) {
+ iframe = document.createElement('iframe');
+ iframe.name = id;
+ }
+ iframe.id = id;
+ form.appendChild(iframe);
+ form.d.value = utils.stringsQuote(messages);
+ form.submit();
+
+ var completed = function() {
+ form.removeChild(iframe);
+ iframe.onreadystatechange = iframe.onerror = iframe.onload = null;
+ iframe = undefined;
+ form.d.value = undefined;
+ form.target = undefined;
+ form.reset();
+ callback();
+ };
+ iframe.onerror = iframe.onload = completed;
+ iframe.onreadystatechange = function(e) {
+ if (iframe.readyState == 'complete') completed();
+ };
+ return completed;
+};
\ No newline at end of file
diff --git a/lib/trans-ws.js b/lib/trans-ws.js
new file mode 100644
index 0000000..8bd977f
--- /dev/null
+++ b/lib/trans-ws.js
@@ -0,0 +1,31 @@
+var WebSocketTransport = SockJS.ws = function(ri, trans_url) {
+ var that = this;
+ var url = trans_url + '/websocket';
+ if (url.slice(0, 5) === 'https') {
+ url = 'wss' + url.slice(5);
+ } else {
+ url = 'ws' + url.slice(4);
+ }
+ that.ri = ri;
+ that.url = url;
+ var ws = that.ws = new WebSocket(that.url);
+ ws.onopen = function(e){that.ri._didOpen();};
+ ws.onmessage = function(e){that.ri._didMessage(e.data);};
+ ws.onclose = function(e){
+ ws.onopen = ws.onmessage = ws.onclose = null;
+ that.ws = undefined;
+ that.ri._didClose(1001, "Socket closed");
+ };
+};
+
+WebSocketTransport.prototype.doSend = function(data) {
+ this.ws.send(data);
+};
+
+WebSocketTransport.prototype.doClose = function() {
+ this.ws.close();
+};
+
+WebSocketTransport.enabled = function() {
+ return (typeof WebSocket === 'function');
+};
diff --git a/lib/utils.js b/lib/utils.js
new file mode 100644
index 0000000..8b401de
--- /dev/null
+++ b/lib/utils.js
@@ -0,0 +1,85 @@
+var utils = {};
+utils.random_string = function(letters, max) {
+ var chars = 'abcdefghijklmnopqrstuvwxyz0123456789_';
+ if (typeof max === 'undefined') {
+ max = chars.length;
+ }
+ var i, ret = [];
+ for(i=0; i<letters;i++) {
+ ret.push( chars[Math.floor(Math.random() * max)] );
+ }
+ return ret.join('');
+};
+utils.random_number = function(max) {
+ return Math.floor(Math.random() * max);
+};
+utils.random_number_string = function(max) {
+ var s = ''+utils.random_number(max);
+ var t = (''+(max - 1)).length;
+ while (s.length < t) {s = '0' + s;}
+ return s;
+};
+
+utils.attachMessage = function(listener) {
+ if (typeof window.addEventListener !== 'undefined') {
+ window.addEventListener("message", listener, false);
+ } else {
+ // IE quirks.
+ // According to: http://stevesouders.com/misc/test-postmessage.php
+ // the message gets delivered only to 'document', not 'window'.
+ document.attachEvent("onmessage", listener);
+ }
+};
+
+utils.dettachMessage = function(listener) {
+ if (typeof window.addEventListener !== 'undefined') {
+ window.removeEventListener("message", listener, false);
+ } else {
+ document.removeEvent("onmessage", listener);
+ }
+};
+
+// Assuming that url looks like: http://asdasd:111/asd
+utils.getOrigin = function(url) {
+ url += '/';
+ var parts = url.split('/').slice(0, 3);
+ return parts.join('/');
+};
+
+utils.objectExtend = function(dst, src) {
+ for(var k in src) {
+ if (src.hasOwnProperty(k)) {
+ dst[k] = src[k];
+ }
+ }
+ return dst;
+};
+
+// Stolen from: https://github.com/douglascrockford/JSON-js/blob/master/json2.js#L195
+var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+var meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ };
+var stringQuote = utils.stringQuote = function(string) {
+ escapable.lastIndex = 0;
+ return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
+ var c = meta[a];
+ return typeof c === 'string' ? c :
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + '"' : '"' + string + '"';
+};
+
+// Qutote an array of strings
+utils.stringsQuote = function(strings){
+ var d = [];
+ for(var i=0; i < strings.length; i++) {
+ d.push(stringQuote(strings[i]));
+ }
+ return '[' + d.join(',') + ']';
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..f2262a1
--- /dev/null
+++ b/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "sockjs-client",
+ "version": "0.0.1",
+ "dependencies": {
+ "uglify-js": "1.0.6",
+ "coffee-script": "1.1.1"
+ }
+}
diff --git a/run.sh b/run.sh
new file mode 100755
index 0000000..23c1da3
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+if [ -e .pidfile.pid ]; then
+ kill `cat .pidfile.pid`
+ rm .pidfile.pid
+fi
+
+while [ 1 ]; do
+ echo " [*] Generating javascript"
+ node bin/render.js lib/main.js > sockjs.js && \
+ coffee -o tests/ -c --bare tests-src/*.coffee && \
+ while [ 1 ]; do
+ node bin/minify.js sockjs.js > sockjs-min.js
+ echo " [*] Running http server"
+ node bin/simple_http_server.js &
+ SRVPID=$!
+ echo $SRVPID > .pidfile.pid
+
+ echo " [*] Server pid: $SRVPID"
+ break
+ done
+
+ inotifywait -r -q -e modify .
+ kill $SRVPID
+ rm -f .pidfile.pid
+ # Sync takes some time, wait to avoid races.
+ sleep 0.1
+done
diff --git a/static/jquery.min.js b/static/jquery.min.js
new file mode 100644
index 0000000..48590ec
--- /dev/null
+++ b/static/jquery.min.js
@@ -0,0 +1,18 @@
+/*!
+ * jQuery JavaScript Library v1.6.2
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Thu Jun 30 14:16:56 2011 -0400
+ */
+(function(a,b){function cv(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cs(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),ci.close();d=ci.createElement( [...]
+shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.tar [...]
+)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bi(a,d),e=bj(a),g=bj(d);for(h=0;e[h];++h)bi(e[h],g[h])}if(b){bh(a,d);if(c){e=bj(a),g=bj(d);for(h=0;e[h];++h)bh(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(v [...]
\ No newline at end of file
diff --git a/static/json2.min.js b/static/json2.min.js
new file mode 100644
index 0000000..04e8d93
--- /dev/null
+++ b/static/json2.min.js
@@ -0,0 +1 @@
+var JSON;JSON||(JSON={}),function(){function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c<f;c+=1)h[c]=str(c,i)||"null";e=h.l [...]
\ No newline at end of file
diff --git a/static/qunit.css b/static/qunit.css
new file mode 100644
index 0000000..b3c6db5
--- /dev/null
+++ b/static/qunit.css
@@ -0,0 +1,225 @@
+/**
+ * QUnit - A JavaScript Unit Testing Framework
+ *
+ * http://docs.jquery.com/QUnit
+ *
+ * Copyright (c) 2011 John Resig, Jörn Zaefferer
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * or GPL (GPL-LICENSE.txt) licenses.
+ */
+
+/** Font Family and Sizes */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
+ font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
+}
+
+#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
+#qunit-tests { font-size: smaller; }
+
+
+/** Resets */
+
+#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
+ margin: 0;
+ padding: 0;
+}
+
+
+/** Header */
+
+#qunit-header {
+ padding: 0.5em 0 0.5em 1em;
+
+ color: #8699a4;
+ background-color: #0d3349;
+
+ font-size: 1.5em;
+ line-height: 1em;
+ font-weight: normal;
+
+ border-radius: 15px 15px 0 0;
+ -moz-border-radius: 15px 15px 0 0;
+ -webkit-border-top-right-radius: 15px;
+ -webkit-border-top-left-radius: 15px;
+}
+
+#qunit-header a {
+ text-decoration: none;
+ color: #c2ccd1;
+}
+
+#qunit-header a:hover,
+#qunit-header a:focus {
+ color: #fff;
+}
+
+#qunit-banner {
+ height: 5px;
+}
+
+#qunit-testrunner-toolbar {
+ padding: 0.5em 0 0.5em 2em;
+ color: #5E740B;
+ background-color: #eee;
+}
+
+#qunit-userAgent {
+ padding: 0.5em 0 0.5em 2.5em;
+ background-color: #2b81af;
+ color: #fff;
+ text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+
+
+/** Tests: Pass/Fail */
+
+#qunit-tests {
+ list-style-position: inside;
+}
+
+#qunit-tests li {
+ padding: 0.4em 0.5em 0.4em 2.5em;
+ border-bottom: 1px solid #fff;
+ list-style-position: inside;
+}
+
+#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
+ display: none;
+}
+
+#qunit-tests li strong {
+ cursor: pointer;
+}
+
+#qunit-tests li a {
+ padding: 0.5em;
+ color: #c2ccd1;
+ text-decoration: none;
+}
+#qunit-tests li a:hover,
+#qunit-tests li a:focus {
+ color: #000;
+}
+
+#qunit-tests ol {
+ margin-top: 0.5em;
+ padding: 0.5em;
+
+ background-color: #fff;
+
+ border-radius: 15px;
+ -moz-border-radius: 15px;
+ -webkit-border-radius: 15px;
+
+ box-shadow: inset 0px 2px 13px #999;
+ -moz-box-shadow: inset 0px 2px 13px #999;
+ -webkit-box-shadow: inset 0px 2px 13px #999;
+}
+
+#qunit-tests table {
+ border-collapse: collapse;
+ margin-top: .2em;
+}
+
+#qunit-tests th {
+ text-align: right;
+ vertical-align: top;
+ padding: 0 .5em 0 0;
+}
+
+#qunit-tests td {
+ vertical-align: top;
+}
+
+#qunit-tests pre {
+ margin: 0;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+}
+
+#qunit-tests del {
+ background-color: #e0f2be;
+ color: #374e0c;
+ text-decoration: none;
+}
+
+#qunit-tests ins {
+ background-color: #ffcaca;
+ color: #500;
+ text-decoration: none;
+}
+
+/*** Test Counts */
+
+#qunit-tests b.counts { color: black; }
+#qunit-tests b.passed { color: #5E740B; }
+#qunit-tests b.failed { color: #710909; }
+
+#qunit-tests li li {
+ margin: 0.5em;
+ padding: 0.4em 0.5em 0.4em 0.5em;
+ background-color: #fff;
+ border-bottom: none;
+ list-style-position: inside;
+}
+
+/*** Passing Styles */
+
+#qunit-tests li li.pass {
+ color: #5E740B;
+ background-color: #fff;
+ border-left: 26px solid #C6E746;
+}
+
+#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
+#qunit-tests .pass .test-name { color: #366097; }
+
+#qunit-tests .pass .test-actual,
+#qunit-tests .pass .test-expected { color: #999999; }
+
+#qunit-banner.qunit-pass { background-color: #C6E746; }
+
+/*** Failing Styles */
+
+#qunit-tests li li.fail {
+ color: #710909;
+ background-color: #fff;
+ border-left: 26px solid #EE5757;
+}
+
+#qunit-tests > li:last-child {
+ border-radius: 0 0 15px 15px;
+ -moz-border-radius: 0 0 15px 15px;
+ -webkit-border-bottom-right-radius: 15px;
+ -webkit-border-bottom-left-radius: 15px;
+}
+
+#qunit-tests .fail { color: #000000; background-color: #EE5757; }
+#qunit-tests .fail .test-name,
+#qunit-tests .fail .module-name { color: #000000; }
+
+#qunit-tests .fail .test-actual { color: #EE5757; }
+#qunit-tests .fail .test-expected { color: green; }
+
+#qunit-banner.qunit-fail { background-color: #EE5757; }
+
+
+/** Result */
+
+#qunit-testresult {
+ padding: 0.5em 0.5em 0.5em 2.5em;
+
+ color: #2b81af;
+ background-color: #D2E0E6;
+
+ border-bottom: 1px solid white;
+}
+
+/** Fixture */
+
+#qunit-fixture {
+ position: absolute;
+ top: -10000px;
+ left: -10000px;
+}
diff --git a/static/qunit.min.js b/static/qunit.min.js
new file mode 100644
index 0000000..9cf944a
--- /dev/null
+++ b/static/qunit.min.js
@@ -0,0 +1 @@
+(function(a){function t(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=t(c.childNodes));return b}function s(a){return typeof document!="undefined"&&!!document&&!!document.getElementById&&document.getElementById(a)}function r(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent?a.attachEvent("on"+b,c):c()}function q(a,b){for(var c in b)b[c]===undefined?delete a[c]:a[c]=b[c];return a}function p(b,c,d){typeof console [...]
\ No newline at end of file
diff --git a/tests-src/test-factory.coffee b/tests-src/test-factory.coffee
new file mode 100644
index 0000000..f5e3ab3
--- /dev/null
+++ b/tests-src/test-factory.coffee
@@ -0,0 +1,85 @@
+debug = false
+
+echo_factory_factory = (protocol, messages, name) ->
+ return ->
+ expect(3 + messages.length)
+ a = messages.slice(0)
+ r = new SockJS(test_server_url + '/echo', [protocol])
+ ok(r)
+ r.onopen = (e) ->
+ if debug
+ log(name+'_'+protocol+'_open', e)
+ ok(true)
+ r.send(a[0])
+ r.onmessage = (e) ->
+ if debug
+ log(name+'_'+protocol+'_msg', e.data + ' ' + a[0])
+ equals(e.data, a[0])
+ a.shift()
+ if typeof a[0] is 'undefined'
+ r.close()
+ else
+ r.send(a[0])
+ r.onclose = (e) ->
+ if debug
+ log(name+'_'+protocol+'_close', e)
+ ok(true)
+ start()
+
+factor_echo_basic = (protocol) ->
+ messages = ['data']
+ return echo_factory_factory(protocol, messages, 'echo_basic')
+
+factor_echo_unicode = (protocol) ->
+ messages = [
+ "Τη γλώσσα μου έδωσαν ελληνική το σπίτι φτωχικό στις αμμουδιές του ",
+ "ღმერთსი შემვედრე, ნუთუ კვლა დამხსნას სოფლისა შრომასა, ცეცხლს, წყალს",
+ "⠊⠀⠉⠁⠝⠀⠑⠁⠞⠀⠛⠇⠁⠎⠎⠀⠁⠝⠙⠀⠊⠞⠀⠙⠕⠑⠎⠝⠞⠀⠓⠥⠗⠞⠀⠍⠑",
+ "Би шил идэй чадна, надад хортой биш",
+ "을",
+ "나는 유리를 먹을 수 있어요. 그래도 아프지 않아요",
+ "ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ",
+ "Ég get etið gler án þess að meiða mig.",
+ "Mogę jeść szkło, i mi nie szkodzi.",
+ "\ufffd\u10102\u2f877",
+ ]
+ return echo_factory_factory(protocol, messages, 'echo_unicode')
+
+factor_echo_special_chars = (protocol) ->
+ messages = [
+ " ",
+ "\u0000",
+ "\xff",
+ "\xff\x00",
+ "\x00\xff",
+ " \r ",
+ " \n ",
+ " \r\n ",
+ "\r\n",
+ "",
+ "message\t",
+ "\tmessage",
+ "message ",
+ " message",
+ "message\r",
+ "\rmessage",
+ "message\n",
+ "\nmessage",
+ "message\xff",
+ "\xffmessage",
+ "\ufffd",
+ "\ufffd\u0000",
+ "message\ufffd",
+ "\ufffdmessage",
+ ]
+ return echo_factory_factory(protocol, messages, 'echo_unicode')
+
+
+factor_echo_large_message = (protocol) ->
+ messages = [
+ Array(4096).join('x'),
+ Array(4096*2).join('x'),
+ Array(4096*4).join('x'),
+ Array(4096*8).join('x'),
+ ]
+ return echo_factory_factory(protocol, messages, 'large_message')
diff --git a/tests-src/test-run.coffee b/tests-src/test-run.coffee
new file mode 100644
index 0000000..012af09
--- /dev/null
+++ b/tests-src/test-run.coffee
@@ -0,0 +1,15 @@
+
+test_protocol = (protocol) ->
+ module(protocol)
+ if not SockJS[protocol].enabled()
+ test "skipping...", ->
+ log(name + " skipping protocol " + protocol)
+ else
+ asyncTest("echo", factor_echo_basic(protocol))
+ asyncTest("unicode", factor_echo_unicode(protocol))
+ asyncTest("special_chars", factor_echo_special_chars(protocol))
+ asyncTest("large_message", factor_echo_large_message(protocol))
+
+
+for protocol in ['ws', 'jsonp']
+ test_protocol(protocol)
diff --git a/tests/.placeholder b/tests/.placeholder
new file mode 100644
index 0000000..e69de29
--
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