[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