From 78dfcc4742e9ec5306885bee427aedeb0d561bad Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 11 Dec 2016 12:21:34 -0500 Subject: [PATCH 1/5] add websocks demo --- websocks-demo/index.html | 14 +++ websocks-demo/websocks.js | 195 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 websocks-demo/index.html create mode 100644 websocks-demo/websocks.js diff --git a/websocks-demo/index.html b/websocks-demo/index.html new file mode 100644 index 0000000..ea56a1d --- /dev/null +++ b/websocks-demo/index.html @@ -0,0 +1,14 @@ + + + + irc client with WebSOCKS + + + + + + + +
+
+ diff --git a/websocks-demo/websocks.js b/websocks-demo/websocks.js new file mode 100644 index 0000000..f2b0c04 --- /dev/null +++ b/websocks-demo/websocks.js @@ -0,0 +1,195 @@ + +function ws_try_connect() +{ + + + var elem = document.getElementById("irc-window"); + elem.remove(); + elem = document.createElement("div"); + elem.id ="irc-window"; + document.body.appendChild(elem); + + var text_e = document.createElement("pre"); + text_e.setAttribute("class", "text-window"); + elem.appendChild(text_e); + var input = document.createElement("input"); + elem.appendChild(input); + + + var irc = { + connected: 0, + line_in: "", + target: "", + nick: "ebin", + }; + + function irc_ui_println(line) + { + if(line == "") return; + var node = document.createTextNode(line); + var e = document.createElement("div"); + e.appendChild(node); + text_e.appendChild(e); + while(text_e.children.length > 20) { + text_e.children[0].remove(); + } + } + + function irc_on_privmsg(src, msg) + { + var parts = src.split("!"); + src = parts[0].slice(1); + irc_ui_println("<"+src+ "> "+msg); + } + + function irc_process_in(conn) + { + var line = irc.line_in.trim(); + console.log("--> "+line); + if(line.startsWith("PING ")) { + // handle ping + irc_sendline(conn, "PONG "+line.slice(5)); + return; + } + var parts = line.split(" "); + if (parts.length > 2) { + var src = parts[0]; + var cmd = parts[1]; + var target = parts[2]; + if (cmd == "PRIVMSG") { + var idx = line.indexOf(target); + var msg = line.slice(idx+target.length+2); + irc_on_privmsg(src, msg); + return; + } + if(cmd == "PONG") return; + } + irc_ui_println(line); + + } + + function irc_data(conn, data) + { + data = irc.line_in + data; + var lines = data.split("\n"); + for(var idx = 0; idx < lines.length; idx++) { + irc.line_in = lines [idx] + "\n"; + irc_process_in(conn); + } + } + + function irc_sendline(conn, line) + { + console.log("<-- "+ line); + conn.send(line + "\n"); + } + + function irc_privmsg(conn, target, msg) + { + irc_ui_println("<"+irc.nick+"> "+msg); + irc_sendline(conn, "PRIVMSG "+target+" :"+msg); + } + + function irc_join_channel(conn, chnl) + { + irc_sendline(conn, "JOIN "+chnl); + } + + function handle_input_command(conn, arg, params) + { + arg = arg.toLowerCase(); + if (arg == "j" || arg == "join") { + for (var idx = 0 ; idx < params.length; idx ++) { + irc_join_channel(conn, params[idx]); + } + } + + if(arg == "n" || arg == "nick") { + irc_sendline(conn, "NICK "+params[0]); + return; + } + + if(arg == "q" || arg == "quit") { + irc_sendline(conn, "QUIT"); + clearInterval(irc.pinger); + irc.connected = 0; + return; + } + if(arg == "t" || arg == "target") { + irc.target = params[0]; + return; + } + } + + function handle_input_line(conn, line) + { + if(line[0] == "/") { + var parts = line.split(" "); + handle_input_command(conn, parts[0].slice(1), parts.slice(1)); + } else { + irc_privmsg(conn, irc.target, line); + } + } + + function irc_connected(conn, url) + { + console.log("connected to irc"); + irc_ui_println("connecting to "+url+"..."); + // send user command + irc_sendline(conn, "NICK "+irc.nick); + irc_sendline(conn, "USER "+irc.nick+" "+irc.nick+" "+irc.nick+" :"+irc.nick); + irc.pinger = setInterval(function(){ + if(irc.connected) { + irc_sendline(conn, "PING :i-hate-tcp-lol-"+new Date().getTime()); + } + }, 10000); + input.addEventListener("keypress", function(ev){ + // handle enter key + switch(ev.key) { + case "Enter": + handle_input_line(conn, input.value); + ev.preventDefault(); + input.value = ""; + } + return; + }); + } + + var e = document.getElementById("ws-server"); + var ws = new WebSocket(e.value); + e = document.getElementById("irc-server"); + var irc_url = e.value; + + ws.onclose = function(err) { + console.log("connection closed "+err); + irc.connected = 0; + clearInterval(irc.pinger); + irc_ui_println("connection closed"); + } + + ws.onopen = function(ev) { + console.log("connect to "+irc_url); + ws.send(irc_url); + } + ws.onmessage = function(ev) { + var data = ev.data; + if(irc.connected) { + irc_data(ws, data); + } else { + var j = JSON.parse(data); + if(j.error) { + console.log("WebSOCKS error: "+j.error); + console.log("try again"); + setTimeout(function() { + ws.send(irc_url); + }, 1000); + } + irc.connected = j.success == "1"; + if(irc.connected) { + irc_connected(ws, irc_url); + } + } + } + + +} From c4077f2d49cf855dfffb38e9c10427f7f140f69c Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 11 Dec 2016 13:44:25 -0500 Subject: [PATCH 2/5] add css to websocks demo --- websocks-demo/style.css | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 websocks-demo/style.css diff --git a/websocks-demo/style.css b/websocks-demo/style.css new file mode 100644 index 0000000..50ce36d --- /dev/null +++ b/websocks-demo/style.css @@ -0,0 +1,6 @@ + +.text-window { + width: 90%; + white-space: pre-wrap; + overflow-wrap: break-word; +} \ No newline at end of file From c04bbad405910d10dbe7bb830cd47e6bf9482f5b Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 11 Dec 2016 13:45:59 -0500 Subject: [PATCH 3/5] add log event --- websocks-demo/websocks.js | 1 + 1 file changed, 1 insertion(+) diff --git a/websocks-demo/websocks.js b/websocks-demo/websocks.js index f2b0c04..d1282c5 100644 --- a/websocks-demo/websocks.js +++ b/websocks-demo/websocks.js @@ -169,6 +169,7 @@ function ws_try_connect() ws.onopen = function(ev) { console.log("connect to "+irc_url); + irc_ui_println("trying to connect to "+url_url); ws.send(irc_url); } ws.onmessage = function(ev) { From 6f735a4a6f884f426d48186cae583d22cd74142a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 11 Dec 2016 13:47:10 -0500 Subject: [PATCH 4/5] fix typo --- websocks-demo/websocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/websocks-demo/websocks.js b/websocks-demo/websocks.js index d1282c5..cef0cf8 100644 --- a/websocks-demo/websocks.js +++ b/websocks-demo/websocks.js @@ -169,7 +169,7 @@ function ws_try_connect() ws.onopen = function(ev) { console.log("connect to "+irc_url); - irc_ui_println("trying to connect to "+url_url); + irc_ui_println("resolving "+irc_url+" ..."); ws.send(irc_url); } ws.onmessage = function(ev) { From 9bbc01ca4fbdaaa6ec7b5ca95136a8824b646a81 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sat, 17 Dec 2016 12:48:54 -0500 Subject: [PATCH 5/5] more --- websocks-demo/style.css | 19 +++++- websocks-demo/websocks.js | 133 ++++++++++++++++++++++++++++++++------ 2 files changed, 133 insertions(+), 19 deletions(-) diff --git a/websocks-demo/style.css b/websocks-demo/style.css index 50ce36d..5b1ea8a 100644 --- a/websocks-demo/style.css +++ b/websocks-demo/style.css @@ -1,6 +1,23 @@ .text-window { - width: 90%; + position: fixed; + height: 90%; + width: 100%; white-space: pre-wrap; overflow-wrap: break-word; + overflow-y: scroll; +} + +.text-input { + width: 100%; + position: fixed; + bottom: 0px; + left: 10px; +} + +#irc-window { + position: fixed; + width: 95%; + top: 20px; + left: 10px; } \ No newline at end of file diff --git a/websocks-demo/websocks.js b/websocks-demo/websocks.js index cef0cf8..3b9850a 100644 --- a/websocks-demo/websocks.js +++ b/websocks-demo/websocks.js @@ -9,10 +9,8 @@ function ws_try_connect() elem.id ="irc-window"; document.body.appendChild(elem); - var text_e = document.createElement("pre"); - text_e.setAttribute("class", "text-window"); - elem.appendChild(text_e); var input = document.createElement("input"); + input.setAttribute("class", "text-input"); elem.appendChild(input); @@ -21,25 +19,85 @@ function ws_try_connect() line_in: "", target: "", nick: "ebin", + panes: {}, }; - function irc_ui_println(line) + function irc_ui_show_pane(pane) + { + irc_ui_ensure_pane(pane); + // hide all other panes + for (var k in irc.panes) { + if(k == pane) { + irc.panes[k].elem.style = "display: inline-block"; + irc.target = k; + } else { + irc.panes[k].elem.style = "display: none"; + } + } + } + + function irc_ui_ensure_pane(pane) + { + if(irc.panes[pane]) return; + var e = document.createElement("pre"); + e.setAttribute("class", "text-window"); + e.style = "display: none"; + e.setAttribute("panename", pane); + irc.panes[pane] = { + elem: e, + name: pane, + }; + var root = document.getElementById("irc-window"); + root.appendChild(e); + } + + function irc_ui_println(line, pane) { if(line == "") return; var node = document.createTextNode(line); var e = document.createElement("div"); e.appendChild(node); - text_e.appendChild(e); - while(text_e.children.length > 20) { - text_e.children[0].remove(); + if(!pane) { + pane = " "; + } + irc_ui_ensure_pane(pane); + var p = irc.panes[pane]; + if(p) { + p.elem.appendChild(e); + if (pane == irc.target) { + window.scroll(0, p.elem.offsetTop + p.elem.offsetHeight); + } + } else { + console.log("No pane called "+pane); } + } - function irc_on_privmsg(src, msg) + function irc_on_privmsg(src, target, msg) { var parts = src.split("!"); src = parts[0].slice(1); - irc_ui_println("<"+src+ "> "+msg); + irc_ui_println("<"+src+ "> "+msg, target); + } + + function irc_on_greeted(conn) + { + irc_ui_println("successfully joined irc"); + } + + function irc_on_join(src, target) + { + irc_ui_println("--> "+src, target); + } + + function irc_on_part(src, target) + { + irc_ui_println("<-- "+src, target); + } + + function irc_on_other(src, cmd, target, msg) + { + irc_ui_println("<"+src+"> "+msg, src); } function irc_process_in(conn) @@ -56,16 +114,30 @@ function ws_try_connect() var src = parts[0]; var cmd = parts[1]; var target = parts[2]; + var idx = line.indexOf(target); + var msg = line.slice(idx+target.length+2); if (cmd == "PRIVMSG") { - var idx = line.indexOf(target); - var msg = line.slice(idx+target.length+2); - irc_on_privmsg(src, msg); + irc_on_privmsg(src, target, msg); + return; + } + if (cmd == "JOIN" ) { + irc_on_join(src, target); + return; + } + if (cmd == "PART") { + irc_on_part(src, target); return; } + if(cmd == "PONG") return; + if(cmd == "376") { + // we have been greeted fully + irc_on_greeted(conn); + return; + } + irc_on_other(src.slice(1), cmd, target, msg); } irc_ui_println(line); - } function irc_data(conn, data) @@ -86,13 +158,14 @@ function ws_try_connect() function irc_privmsg(conn, target, msg) { - irc_ui_println("<"+irc.nick+"> "+msg); + irc_ui_println("<"+irc.nick+"> "+msg, target); irc_sendline(conn, "PRIVMSG "+target+" :"+msg); } function irc_join_channel(conn, chnl) { irc_sendline(conn, "JOIN "+chnl); + irc_ui_ensure_pane(chnl); } function handle_input_command(conn, arg, params) @@ -102,21 +175,44 @@ function ws_try_connect() for (var idx = 0 ; idx < params.length; idx ++) { irc_join_channel(conn, params[idx]); } + return; + } + + if(arg == "lp" || arg == "listpanes") { + irc_ui_println("--- begin list of panes", irc.target); + for (var k in irc.panes) { + if(k == irc.target) { + irc_ui_println("(active) : "+k, irc.target); + } else { + irc_ui_println(" : "+k, irc.target); + } + } + irc_ui_println("--- end list of panes", irc.target); + return; + } + + + if(arg == "m" || arg == "msg") { + irc_privmsg(conn, params[0], params.slice(1).join(" ")); + return; } if(arg == "n" || arg == "nick") { irc_sendline(conn, "NICK "+params[0]); + irc.nick = params[0]; + return; + } + if(arg == "r" || arg == "raw") { + irc_sendline(conn, params.join(" ")); return; } - if(arg == "q" || arg == "quit") { irc_sendline(conn, "QUIT"); - clearInterval(irc.pinger); - irc.connected = 0; return; } - if(arg == "t" || arg == "target") { + if(arg == "w" || arg == "window") { irc.target = params[0]; + irc_ui_show_pane(irc.target); return; } } @@ -134,6 +230,7 @@ function ws_try_connect() function irc_connected(conn, url) { console.log("connected to irc"); + irc_ui_show_pane(" "); irc_ui_println("connecting to "+url+"..."); // send user command irc_sendline(conn, "NICK "+irc.nick);