diff --git a/app/network.js b/app/network.js
new file mode 100644
index 0000000..c00b598
--- /dev/null
+++ b/app/network.js
@@ -0,0 +1,89 @@
+// Functionality dealing with server-level things
+
+var maxScrollback = 500;
+var networks = {};
+
+function networkConnect(network, baseURL, authtok) {
+ var eventSource;
+ var element = getTemplate("server-channels");
+ var channels = element.getElementByClassName("channels")[0];
+ var roomElement = element.getElementsByClassName("server")[0];
+ var rooms = {".": room};
+ newRoom(roomElement, element, network, maxScrollback);
+
+ function newRoom(name) {
+ var rElement = getTemplate("channel");
+ newRoom(rElement, element, name, maxScrollback);
+ channels.appendChild(rElement);
+ rooms[name] = rElement;
+ }
+
+ function handleEventSourceLine(line) {
+ var lhs = line.split(" :", 1)[0]
+ var parts = lhs.split(' ')
+ var timestamp = new Date(parts[0] * 1000);
+ var fullSender = parts[1];
+ var command = parts[2].toLowerCase();
+ var sender = parts[3];
+ var forum = parts[4];
+ var args = parts.slice(5);
+ var txt = line.substr(lhs.length + 2);
+
+ var room = rooms[forum];
+ if (! room) {
+ room = newRoom(forum);
+ }
+
+ // XXX: Handle differently based on command
+ room.addMessage(timestamp, command, sender, txt);
+ }
+
+ function handleEventSourceMessage(oEvent) {
+ msgs = oEvent.data.split("\n");
+
+ var first = Math.max(0, msgs.length - maxScrollback);
+ for (var i = first; i < msgs.length; i += 1) {
+ handleEventSourceLine(msgs[i]);
+ }
+ }
+
+ function handleEventSourceError(oEvent) {
+ timestamp = new Date();
+ messageHandler(timestamp, null, "ERROR", null, null, [], null);
+ }
+
+ element.send = function(target, text) {
+ function handleError(oEvent) {
+ console.log("XXX: That didn't work out.", target, text)
+ }
+
+ var form = new FormData();
+ form.append("type", "command");
+ form.append("auth", authtok);
+ form.append("network", network);
+ form.append("target", target);
+ form.append("text", text);
+ console.log(form);
+
+ var oReq = new XMLHttpRequest();
+ oReq.addEventListener("error", handleError);
+ oReq.open("POST", baseURL, true);
+ oReq.send(form);
+ }
+
+ element.close = function() {
+ eventSource.close();
+ element.parentNode.removeChild(element);
+ }
+
+
+ if (networks[network]) {
+ networks[network].close();
+ }
+ networks[network] = element;
+
+ var pullURL = baseURL + "?network=" + encodeURIComponent(network) + "&auth=" + encodeURIComponent(authtok);
+ eventSource = new EventSource(pullURL);
+ eventSource.addEventListener("message", handleEventSourceMessage);
+ eventSource.addEventListener("error", handleEventSourceError);
+}
diff --git a/app/room.js b/app/room.js
new file mode 100644
index 0000000..a741263
--- /dev/null
+++ b/app/room.js
@@ -0,0 +1,113 @@
+function djbhash(a) {
+ var r = 5381;
+
+ for (var i = 0; i < a.length; i += 1) {
+ r = (((r << 5) + r) + a.charCodeAt(i)) & 0xffff;
+ }
+ return r;
+}
+
+function addText(p, text, kiboze) {
+ // Look for a URL
+ var txtElement = document.createElement("span");
+ txtElement.className = "text";
+ var rhs = text;
+ var match;
+
+ while ((match = urlRe.exec(rhs)) != null) {
+ var before = rhs.substr(0, match.index);
+ var a = document.createElement("a");
+ var href = match[0];
+
+ if (href.indexOf("hxx") == 0) {
+ href = "htt" + href.substr(3);
+ }
+ a.href = href
+ a.target = "_blank";
+ a.appendChild(document.createTextNode(match[0]));
+ txtElement.appendChild(document.createTextNode(before));
+ txtElement.appendChild(a);
+ rhs = rhs.substr(match.index + match[0].length);
+ }
+ txtElement.appendChild(document.createTextNode(rhs));
+ p.appendChild(txtElement);
+
+ if ((kiboze) || (-1 != text.search(kibozeRe))) {
+ var k = document.getElementById("kiboze");
+ var p2 = p.cloneNode(true);
+
+ if (k) {
+ k.insertBefore(p2, k.firstChild);
+ p2.onclick = function() { focus(p); }
+
+ // Setting title makes the tab flash sorta
+ document.title = document.title;
+ }
+ }
+}
+
+var visibleRoom;
+
+function newRoom(element, network, name, maxSize) {
+ var messages = getTemplate("messages");
+ if (! maxsize) {
+ maxSize = 500;
+ }
+
+ element.addMessage = function(timestamp, command, source, content) {
+ var message = getTemplate("message");
+
+ var eTimestamp = message.getElementsByClassName("timestamp")[0];
+ var eSource = message.getElementsByClassName("source")[0];
+ var eContent = message.getElementsByClassName("content")[0];
+
+ message.nodeList.add(command);
+ if (source = ".") {
+ message.nodeList.add("self");
+ }
+
+ eTimestamp.textContent = timestamp.toLocaleTimeString();
+ eSource.textContent = source;
+ eSource.setAttribute("colornumber", djbhash(source) % 31);
+ eContent.textContent = content;
+
+ messages.appendChild(message);
+
+ while (messages.childNodes.length > maxSize) {
+ messages.removeChild(element.firstChild);
+ }
+
+ if (visibleRoom == element) {
+ message.scrollIntoView(false);
+ }
+ }
+
+ element.hide = function() {
+ element.classList.remove("selected");
+ messages.classList.add("hidden");
+ }
+
+ element.show = function() {
+ if (visibleRoom) {
+ visibleRoom.hide()
+ }
+ element.classList.add("selected");
+ messages.classList.remove("hidden");
+ visibleRoom = element;
+ }
+
+ element.send = function(text) {
+ network.send(name, text);
+ }
+
+ function clicked() {
+ element.show();
+ }
+
+ // start hidden
+ element.hide();
+ element.addEventListener("click", clicked);
+ element.getElementsByClassName("content-item")[0].textContent = name;
+
+ return element;
+}
\ No newline at end of file
diff --git a/app/server.js b/app/server.js
deleted file mode 100644
index bf2c081..0000000
--- a/app/server.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// Functionality dealing with server-level things
-
-var maxScrollback = 500;
-
-function Server(network, baseURL, authtok, messageHandler) {
- function init() {
- var pullURL = baseURL + "?network=" + encodeURIComponent(network) + "&auth=" + encodeURIComponent(authtok);
- this.eventSource = new EventSource(pullURL);
- this.eventSource.addEventListener("message", handleEventSourceMessage);
- this.eventSource.addEventListener("error", handleEventSourceError);
- }
-
- function close() {
- this.eventSource.close();
- }
-
- function handleEventSourceLine(line) {
- var lhs = line.split(" :", 1)[0]
- var parts = lhs.split(' ')
- var timestamp = new Date(parts[0] * 1000);
- var fullSender = parts[1];
- var command = parts[2];
- var sender = parts[3];
- var forum = parts[4];
- var args = parts.slice(5);
- var txt = line.substr(lhs.length + 2);
-
- messageHandler(timestamp, fullSender, command, sender, forum, args, txt);
- }
-
- function handleEventSourceMessage(oEvent) {
- msgs = oEvent.data.split("\n");
-
- var first = Math.max(0, msgs.length - maxScrollback);
- for (var i = first; i < msgs.length; i += 1) {
- handleEventSourceLine(msgs[i]);
- }
- }
-
- function handleEventSourceError(oEvent) {
- timestamp = new Date();
- messageHandler(timestamp, null, "ERROR", null, null, [], null);
- }
-
- function send(target, text) {
- function handleError(oEvent) {
- console.log("XXX: That didn't work out.", target, text)
- }
-
- var form = new FormData();
- form.append("type", "command");
- form.append("auth", authtok);
- form.append("network", network);
- form.append("target", target);
- form.append("text", text);
- console.log(form);
-
- var oReq = new XMLHttpRequest();
- oReq.addEventListener("error", handleError);
- oReq.open("POST", baseURL, true);
- oReq.send(form);
- }
-
- this.send = send;
-
- init();
-}
diff --git a/app/wirc.html b/app/wirc.html
index 8175e83..c383fb5 100644
--- a/app/wirc.html
+++ b/app/wirc.html
@@ -6,7 +6,8 @@
-
+
+
diff --git a/app/wirc.js b/app/wirc.js
index 25c35bd..03a69df 100644
--- a/app/wirc.js
+++ b/app/wirc.js
@@ -4,27 +4,12 @@ var urlRe = /[a-z]+:\/\/[^ ]*/;
var nick = "Mme. M";
-// XXX: get rid of this
-var scrollbackLength = 500;
-var current;
-var target;
-
if (String.prototype.startsWith == null) {
String.prototype.startsWith = function(needle) {
return this.lastIndexOf(needle, 0) == 0;
}
}
-function djbhash(a) {
- var r = 5381;
-
- for (var i = 0; i < a.length; i += 1) {
- r = (((r << 5) + r) + a.charCodeAt(i)) & 0xffff;
- }
- return r;
-}
-
-
function getTemplate(className) {
return templates.getElementsByClassName(className)[0].cloneNode(true);
}
@@ -33,50 +18,6 @@ function isinView(oObject) {
return (oObject.offsetParent.clientHeight <= oObject.offsetTop);
}
-function selectForum(room) {
- if (current) {
- current.classList.remove("selected");
- // XXX: do this with a class, too
- current.messages.style.display = "none";
- }
-
-
- current = room;
- target = room.target;
- room.classList.add("selected");
- room.messages.style.display = "block";
-
- if (room.messages.lastChild) {
- room.messages.lastChild.scrollIntoView(false);
- }
-}
-
-fora = {}
-function getForumElement(forum) {
- var fe = fora[forum];
-
- if (! fe) {
- var room = getTemplate("channel room");
- var content = room.getElementsByClassName("content-item")[0];
-
- content.textContent = forum;
- rooms.appendChild(room);
-
- fe = getTemplate("messages");
- fe.room = room;
-
- room.messages = fe;
- room.target = forum;
- // XXX: split out into non-anon function
- room.addEventListener("click", function() {selectForum(room)});
-
- fora[forum] = fe;
- document.getElementById("messages-container").appendChild(fe);
- }
-
- return fe;
-}
-
function addMessagePart(p, className, text) {
var e = document.createElement("span");
e.className = className;
@@ -85,45 +26,6 @@ function addMessagePart(p, className, text) {
p.appendChild(document.createTextNode(" "));
}
-function addText(p, text, kiboze) {
- // Look for a URL
- var txtElement = document.createElement("span");
- txtElement.className = "text";
- var rhs = text;
- var match;
-
- while ((match = urlRe.exec(rhs)) != null) {
- var before = rhs.substr(0, match.index);
- var a = document.createElement("a");
- var href = match[0];
-
- if (href.indexOf("hxx") == 0) {
- href = "htt" + href.substr(3);
- }
- a.href = href
- a.target = "_blank";
- a.appendChild(document.createTextNode(match[0]));
- txtElement.appendChild(document.createTextNode(before));
- txtElement.appendChild(a);
- rhs = rhs.substr(match.index + match[0].length);
- }
- txtElement.appendChild(document.createTextNode(rhs));
- p.appendChild(txtElement);
-
- if ((kiboze) || (-1 != text.search(kibozeRe))) {
- var k = document.getElementById("kiboze");
- var p2 = p.cloneNode(true);
-
- if (k) {
- k.insertBefore(p2, k.firstChild);
- p2.onclick = function() { focus(p); }
-
- // Setting title makes the tab flash sorta
- document.title = document.title;
- }
- }
-}
-
function focus(e) {
var pct = 1;
var timeout;
@@ -142,49 +44,6 @@ function focus(e) {
}, 50)
}
-function addMessage(timestamp, fullSender, command, sender, forum, args, msg) {
- var forumElement = getForumElement(forum);
- var msge = getTemplate("message");
-
- msge.classList.add("update");
- msge.classList.add("privmsg");
-
- if (sender == ".") {
- msge.classList.add("self");
- }
-
- console.log(timestamp, msg);
-
- msge.getElementsByClassName("timestamp")[0].textContent = timestamp.toLocaleTimeString();
- var sourcee = msge.getElementsByClassName("source")[0];
- var contente = msge.getElementsByClassName("content")[0];
-
- var senderhash = djbhash(sender) % 31;
- sourcee.setAttribute("colornumber", senderhash)
-
-
- sourcee.textContent = sender;
-
- switch (command) {
- case "PING":
- case "PONG":
- return;
- case "PRIVMSG":
- case "NOTICE":
- addText(contente, msg);
- break;
- default:
- contente.textContent = command + " " + args + " " + msg;
- break;
- }
- while (forumElement.childNodes.length > scrollbackLength) {
- forumElement.removeChild(forumElement.firstChild)
- }
-
- forumElement.appendChild(msge);
- msge.scrollIntoView(false);
-}
-
function handleInput(oEvent) {
var txt = oEvent.target.value;
if (txt.startsWith("/connect ")) {
@@ -198,7 +57,7 @@ function handleInput(oEvent) {
storedConnections[network] = [url, authtok];
chrome.storage.sync.set({"connections": storedConnections});
} else {
- server.send(target, txt);
+ visibleRoom.send(txt);
}
oEvent.target.value = "";
@@ -206,42 +65,13 @@ function handleInput(oEvent) {
return false;
}
-var server;
-var activeNetworks = {};
-var storedConnections = {};
-
-function connect(network, url, authtok) {
- var newServer = new Server(network, url, authtok, addMessage);
- var element;
-
- if (activeNetworks[network]) {
- activeNetworks[network].close();
- element = activeNetworks[network].element;
- } else {
- newServer.element = getTemplate("server-channels");
- rooms.appendChild(newServer.element);
- }
-
- newServer.room = newServer.element.getElementsByClassName("server room")[0];
- newServer.content = newServer.element.getElementsByClassName("content-item")[0];
-
- newServer.content.textContent = network;
-
- activeNetworks[network] = newServer;
-
- // XXX: this should be bound to the element
- server = newServer;
-}
-
-
-
function restore(items) {
storedConnections = items["connections"];
for (var network in storedConnections) {
var conn = storedConnections[network];
- connect(network, conn[0], conn[1]);
+ networkConnect(network, conn[0], conn[1]);
}
}