spongy/app/wirc.js

257 lines
5.9 KiB
JavaScript
Raw Normal View History

2014-07-23 21:15:04 -06:00
var msgRe = /([^ ]+) (<[^>]+>) (.*)/;
var kibozeRe = /[Nn]eal/;
var urlRe = /[a-z]+:\/\/[^ ]*/;
var nick = "Mme. M";
2014-07-24 10:34:02 -06:00
2014-10-24 23:25:22 -06:00
// XXX: get rid of this
2014-10-24 15:51:53 -06:00
var scrollbackLength = 500;
2014-10-24 23:25:22 -06:00
var current;
2014-10-27 10:23:50 -06:00
var target;
2014-10-24 15:51:53 -06:00
2014-10-23 21:21:54 -06:00
if (String.prototype.startsWith == null) {
String.prototype.startsWith = function(needle) {
return this.lastIndexOf(needle, 0) == 0;
}
}
2014-10-27 10:23:50 -06:00
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;
}
2014-10-24 15:51:53 -06:00
function getTemplate(className) {
2014-10-24 23:25:22 -06:00
return templates.getElementsByClassName(className)[0].cloneNode(true);
2014-10-24 15:51:53 -06:00
}
2014-07-24 10:34:02 -06:00
function isinView(oObject) {
return (oObject.offsetParent.clientHeight <= oObject.offsetTop);
}
2014-07-23 21:15:04 -06:00
2014-10-24 15:51:53 -06:00
function selectForum(room) {
2014-10-24 23:25:22 -06:00
if (current) {
current.classList.remove("selected");
// XXX: do this with a class, too
2014-10-26 22:25:59 -06:00
current.messages.style.display = "none";
2014-10-24 23:25:22 -06:00
}
2014-10-24 15:51:53 -06:00
2014-10-24 23:25:22 -06:00
current = room;
2014-10-27 10:23:50 -06:00
target = room.target;
2014-10-24 23:25:22 -06:00
room.classList.add("selected");
2014-10-26 22:25:59 -06:00
room.messages.style.display = "block";
2014-10-24 23:25:22 -06:00
if (room.messages.lastChild) {
room.messages.lastChild.scrollIntoView(false);
}
2014-10-24 15:51:53 -06:00
}
2014-10-24 15:51:53 -06:00
fora = {}
function getForumElement(forum) {
2014-10-24 15:51:53 -06:00
var fe = fora[forum];
if (! fe) {
2014-10-24 15:51:53 -06:00
var room = getTemplate("channel room");
2014-10-26 22:25:59 -06:00
var content = room.getElementsByClassName("content-item")[0];
2014-10-24 23:25:22 -06:00
content.textContent = forum;
rooms.appendChild(room);
2014-10-24 15:51:53 -06:00
fe = getTemplate("messages");
fe.room = room;
room.messages = fe;
2014-10-27 10:23:50 -06:00
room.target = forum;
2014-10-24 15:51:53 -06:00
// XXX: split out into non-anon function
2014-10-24 23:25:22 -06:00
room.addEventListener("click", function() {selectForum(room)});
2014-10-24 15:51:53 -06:00
fora[forum] = fe;
document.getElementById("messages-container").appendChild(fe);
}
2014-10-24 15:51:53 -06:00
return fe;
2014-10-24 15:51:53 -06:00
}
2014-07-23 21:15:04 -06:00
function addMessagePart(p, className, text) {
var e = document.createElement("span");
e.className = className;
e.appendChild(document.createTextNode(text));
p.appendChild(e);
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;
2014-10-24 15:51:53 -06:00
while ((match = urlRe.exec(rhs)) != null) {
var before = rhs.substr(0, match.index);
var a = document.createElement("a");
var href = match[0];
2014-10-24 15:51:53 -06:00
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);
2014-10-24 15:51:53 -06:00
if ((kiboze) || (-1 != text.search(kibozeRe))) {
var k = document.getElementById("kiboze");
var p2 = p.cloneNode(true);
2014-10-24 15:51:53 -06:00
if (k) {
k.insertBefore(p2, k.firstChild);
p2.onclick = function() { focus(p); }
// Setting title makes the tab flash sorta
document.title = document.title;
}
}
}
2014-10-24 15:51:53 -06:00
2014-07-24 10:56:37 -06:00
function focus(e) {
var pct = 1;
var timeout;
2014-10-24 15:51:53 -06:00
selectForum(e.parentNode);
2014-07-24 10:56:37 -06:00
e.scrollIntoView(false);
e.style.backgroundColor = "yellow";
2014-10-24 15:51:53 -06:00
2014-07-24 10:56:37 -06:00
timeout = setInterval(function() {
pct = pct - 0.1;
e.style.backgroundColor = "rgba(255, 255, 0, " + pct + ")";
if (pct <= 0) {
2014-10-24 15:51:53 -06:00
e.style.backgroundColor = "inherit";
2014-07-24 10:56:37 -06:00
clearInterval(timeout);
}
}, 50)
}
2014-07-23 21:15:04 -06:00
2014-10-24 23:25:22 -06:00
function addMessage(timestamp, fullSender, command, sender, forum, args, msg) {
var forumElement = getForumElement(forum);
2014-10-26 22:25:59 -06:00
var msge = getTemplate("message");
2014-10-24 15:51:53 -06:00
2014-10-27 10:23:50 -06:00
msge.classList.add("update");
msge.classList.add("privmsg");
if (sender == ".") {
msge.classList.add("self");
}
2014-10-24 23:25:22 -06:00
console.log(timestamp, msg);
2014-10-26 22:25:59 -06:00
msge.getElementsByClassName("timestamp")[0].textContent = timestamp.toLocaleTimeString();
var sourcee = msge.getElementsByClassName("source")[0];
var contente = msge.getElementsByClassName("content")[0];
2014-10-27 11:51:46 -06:00
var senderhash = djbhash(sender) % 31;
2014-10-27 10:23:50 -06:00
sourcee.setAttribute("colornumber", senderhash)
2014-10-26 22:25:59 -06:00
sourcee.textContent = sender;
2014-10-24 15:51:53 -06:00
2014-07-23 21:15:04 -06:00
switch (command) {
case "PING":
case "PONG":
2014-10-26 22:25:59 -06:00
return;
2014-07-23 21:15:04 -06:00
case "PRIVMSG":
2014-10-26 22:25:59 -06:00
case "NOTICE":
2014-10-27 10:23:50 -06:00
addText(contente, msg);
2014-07-23 21:15:04 -06:00
break;
default:
2014-10-26 22:25:59 -06:00
contente.textContent = command + " " + args + " " + msg;
2014-07-23 21:15:04 -06:00
break;
}
2014-10-24 15:51:53 -06:00
while (forumElement.childNodes.length > scrollbackLength) {
2014-10-24 12:29:38 -06:00
forumElement.removeChild(forumElement.firstChild)
}
2014-10-26 22:25:59 -06:00
forumElement.appendChild(msge);
msge.scrollIntoView(false);
2014-07-23 21:15:04 -06:00
}
2014-10-24 15:51:53 -06:00
function handleInput(oEvent) {
var txt = oEvent.target.value;
2014-10-23 21:21:54 -06:00
if (txt.startsWith("/connect ")) {
// XXX: should allow tokens with spaces
var parts = txt.split(" ");
2014-10-24 23:25:22 -06:00
var network = parts[1];
var url = parts[2];
var authtok = parts[3];
2014-10-23 21:21:54 -06:00
2014-10-24 23:25:22 -06:00
connect(network, url, authtok);
storedConnections[network] = [url, authtok];
chrome.storage.sync.set({"connections": storedConnections});
2014-10-24 12:29:38 -06:00
} else {
2014-10-27 10:23:50 -06:00
server.send(target, txt);
2014-10-23 21:21:54 -06:00
}
2014-10-24 15:51:53 -06:00
oEvent.target.value = "";
2014-07-23 21:15:04 -06:00
return false;
}
2014-10-27 10:23:50 -06:00
var server;
2014-10-24 23:25:22 -06:00
var activeNetworks = {};
var storedConnections = {};
2014-10-24 12:29:38 -06:00
2014-10-24 23:25:22 -06:00
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);
}
2014-10-24 12:29:38 -06:00
2014-10-24 23:25:22 -06:00
newServer.room = newServer.element.getElementsByClassName("server room")[0];
newServer.content = newServer.element.getElementsByClassName("content-item")[0];
newServer.content.textContent = network;
activeNetworks[network] = newServer;
2014-10-27 10:23:50 -06:00
// XXX: this should be bound to the element
server = newServer;
2014-10-24 12:29:38 -06:00
}
2014-10-24 23:25:22 -06:00
2014-10-24 12:29:38 -06:00
function restore(items) {
2014-10-24 23:25:22 -06:00
storedConnections = items["connections"];
2014-10-24 15:51:53 -06:00
2014-10-24 23:25:22 -06:00
for (var network in storedConnections) {
var conn = storedConnections[network];
2014-10-24 15:51:53 -06:00
2014-10-24 23:25:22 -06:00
connect(network, conn[0], conn[1]);
2014-10-24 15:51:53 -06:00
}
2014-10-23 21:21:54 -06:00
}
function init() {
2014-10-24 23:25:22 -06:00
chrome.storage.sync.get(["connections"], restore);
2014-10-24 15:51:53 -06:00
document.getElementById("input").addEventListener("change", handleInput);
2014-10-24 23:25:22 -06:00
templates = document.getElementById("templates");
rooms = document.getElementById("rooms-container").getElementsByClassName("rooms")[0];
2014-07-23 21:15:04 -06:00
}
2014-10-24 15:51:53 -06:00
window.addEventListener("load", init);