-TODO:\r
- - isp transparent proxy issue\r
- - new UI\r
- - connect UI (do with newUI?)\r
- - better error handling server side\r
- - better error handling client side\r
-\r
-\r
+TODO:
+ - isp transparent proxy issue
+ - tidy up UI
+ - connect UI (do with newUI?)
+ - better error handling server side
+ - better error handling client side
+
+
-/* qwebirc -- Copyright (C) 2008 Chris Porter --- All rights reserved. */\r
-\r
+/* qwebirc -- Copyright (C) 2008 Chris Porter --- All rights reserved. */
+
-var Numerics = {"001": "RPL_WELCOME", "433": "ERR_NICKNAMEINUSE", "004": "RPL_MYINFO", "005": "RPL_ISUPPORT", "353": "RPL_NAMREPLY", "366": "RPL_ENDOFNAMES", "331": "RPL_NOTOPIC", "332": "RPL_TOPIC", "333": "RPL_TOPICWHOTIME"};\r
-\r
-var RegisteredCTCPs = {\r
- "VERSION": function(x) {\r
- return "qwebirc v" + QWEBIRC_VERSION + ", copyright (C) Chris Porter 2008 -- user agent: " + Browser.Engine.name + " (" + Browser.Platform.name + ")";\r
- },\r
- "USERINFO": function(x) { return "qwebirc"; },\r
- "TIME": function(x) { return IRCTime(new Date()); },\r
- "PING": function(x) { return x; },\r
- "CLIENTINFO": function(x) { return "PING VERSION TIME USERINFO CLIENTINFO"; }\r
-};\r
-\r
-var BaseIRCClient = new Class({\r
- Implements: [Options],\r
- options: {\r
- nickname: "WCunset",\r
- },\r
- initialize: function(options) {\r
- this.setOptions(options);\r
-\r
- this.nickname = this.options.nickname;\r
- \r
- this.__signedOn = false;\r
- this.pmodes = ["b", "k,", "o", "l", "v"];\r
- this.channels = {}\r
- this.nextctcp = 0; \r
-\r
- this.connection = new IRCConnection({initialNickname: this.nickname, onRecv: this.dispatch.bind(this)});\r
- \r
- this.send = this.connection.send.bind(this.connection);\r
- this.connect = this.connection.connect.bind(this.connection);\r
- this.disconnect = this.connection.disconnect;\r
- },\r
- dispatch: function(data) {\r
- var message = data[0];\r
- if(message == "connect") {\r
- this.connected();\r
- } else if(message == "disconnect") {\r
- this.disconnected();\r
- } else if(message == "c") {\r
- var command = data[1].toUpperCase();\r
- \r
- var prefix = data[2];\r
- var sl = data[3];\r
- var n = Numerics[command];\r
- \r
- var x = n;\r
- if(!n)\r
- n = command; \r
-\r
- var o = this["irc_" + n];\r
- \r
- if(o) {\r
- var r = o.attempt([prefix, sl], this);\r
- if(!r)\r
- this.rawNumeric(command, prefix, sl);\r
- } else {\r
- this.rawNumeric(command, prefix, sl);\r
- }\r
- }\r
- },\r
-\r
- irc_RPL_WELCOME: function(prefix, params) {\r
- this.nickname = params[0];\r
- \r
- this.__signedOn = true;\r
- this.signedOn(this.nickname);\r
- },\r
- irc_ERR_NICKNAMEINUSE: function(prefix, params) {\r
- if(this.__signedOn)\r
- return;\r
- \r
- var newnick = params[1] + "_";\r
- if(newnick == this.lastnick)\r
- newnick = "webchat" + Math.floor(Math.random() * 1024 * 1024);\r
-\r
- this.send("NICK " + newnick);\r
- this.lastnick = newnick;\r
- },\r
- irc_NICK: function(prefix, params) {\r
- var user = prefix;\r
- var oldnick = user.hostToNick();\r
- var newnick = params[0];\r
- \r
- if(this.nickname == oldnick)\r
- this.nickname = newnick;\r
- \r
- this.nickChanged(user, newnick);\r
- \r
- return true;\r
- },\r
- irc_QUIT: function(prefix, params) {\r
- var user = prefix;\r
- \r
- var message = params.indexFromEnd(-1);\r
- \r
- this.userQuit(user, message);\r
- \r
- return true;\r
- },\r
- irc_PART: function(prefix, params) {\r
- var user = prefix;\r
- var channel = params[0];\r
- var message = params[1];\r
-\r
- var nick = user.hostToNick();\r
- \r
- if((nick == this.nickname) && this.channels[channel])\r
- delete this.channels[channel];\r
- \r
- this.userPart(user, channel, message);\r
- \r
- return true;\r
- },\r
- irc_KICK: function(prefix, params) {\r
- var kicker = prefix;\r
- var channel = params[0];\r
- var kickee = params[1];\r
- var message = params[2];\r
- \r
- if((kickee == this.nickname) && this.channels[channel])\r
- delete this.channels[channel];\r
- \r
- this.userKicked(kicker, channel, kickee, message);\r
- \r
- return true;\r
- },\r
- irc_PING: function(prefix, params) {\r
- this.send("PONG :" + params.indexFromEnd(-1));\r
- \r
- return true;\r
- },\r
- irc_JOIN: function(prefix, params) {\r
- var channel = params[0];\r
- var user = prefix;\r
- var nick = user.hostToNick();\r
- \r
- if(nick == this.nickname)\r
- this.channels[channel] = true;\r
- \r
- this.userJoined(user, channel);\r
- \r
- return true;\r
- },\r
- irc_TOPIC: function(prefix, params) {\r
- var user = prefix;\r
- var channel = params[0];\r
- var topic = params.indexFromEnd(-1);\r
- \r
- this.channelTopic(user, channel, topic);\r
- \r
- return true;\r
- },\r
- processCTCP: function(message) {\r
- if(message.charAt(0) != "\x01")\r
- return;\r
- \r
- if(message.charAt(message.length - 1) == "\x01") {\r
- message = message.substr(1, message.length - 2);\r
- } else {\r
- message = message.substr(1);\r
- }\r
- return message.splitMax(" ", 2);\r
- },\r
- irc_PRIVMSG: function(prefix, params) {\r
- var user = prefix;\r
- var target = params[0];\r
- var message = params.indexFromEnd(-1);\r
- \r
- var ctcp = this.processCTCP(message);\r
- if(ctcp) {\r
- var type = ctcp[0].toUpperCase();\r
- \r
- var replyfn = RegisteredCTCPs[type];\r
- if(replyfn) {\r
- var t = new Date().getTime() / 1000;\r
- if(t > this.nextctcp)\r
- this.send("NOTICE " + user.hostToNick() + " :\x01" + type + " " + replyfn(ctcp[1]) + "\x01");\r
- this.nextctcp = t + 5;\r
- }\r
- \r
- if(target == this.nickname) {\r
- this.userCTCP(user, type, ctcp[1]);\r
- } else {\r
- this.channelCTCP(user, target, type, ctcp[1]);\r
- }\r
- } else {\r
- if(target == this.nickname) {\r
- this.userPrivmsg(user, message);\r
- } else {\r
- this.channelPrivmsg(user, target, message);\r
- }\r
- }\r
- \r
- return true;\r
- },\r
- irc_NOTICE: function(prefix, params) {\r
- var user = prefix;\r
- var target = params[0];\r
- var message = params.indexFromEnd(-1);\r
- \r
- if(user == "") {\r
- this.serverNotice(message);\r
- } else if(target == this.nickname) {\r
- var ctcp = this.processCTCP(message);\r
- if(ctcp) {\r
- this.userCTCPReply(user, ctcp[0], ctcp[1]);\r
- } else {\r
- this.userNotice(user, message);\r
- }\r
- } else {\r
- this.channelNotice(user, target, message);\r
- }\r
- \r
- return true;\r
- },\r
- irc_INVITE: function(prefix, params) {\r
- var user = prefix;\r
- var channel = params.indexFromEnd(-1);\r
- \r
- this.userInvite(user, channel);\r
- \r
- return true;\r
- },\r
- irc_ERROR: function(prefix, params) {\r
- var message = params.indexFromEnd(-1);\r
- \r
- this.serverError(message);\r
- \r
- return true;\r
- },\r
- irc_MODE: function(prefix, params) {\r
- var user = prefix;\r
- var target = params[0];\r
- var args = params.slice(1);\r
- \r
- if(target == this.nickname) {\r
- this.userMode(args);\r
- } else {\r
- var modes = args[0].split("");\r
- var xargs = args.slice(1);\r
- \r
- var data = []\r
- var carg = 0;\r
- var pos = 0;\r
- var cmode = "+";\r
- \r
- modes.each(function(mode) {\r
- if((mode == "+") || (mode == "-")) {\r
- cmode = mode;\r
- return;\r
- }\r
-\r
- if(this.pmodes[mode]) { \r
- d = [cmode, mode, xargs[carg++]]\r
- } else {\r
- d = [cmode, mode]\r
- }\r
- \r
- data.push(d);\r
- }, this);\r
- \r
- this.channelMode(user, target, data, args);\r
- }\r
- \r
- return true;\r
- }, \r
- irc_RPL_ISUPPORT: function(prefix, params) {\r
- var supported = params.slice(1, -1);\r
- var supportedhash = {};\r
- \r
- for(var i=0;i<supported.length;i++) {\r
- var l = supported[i].splitMax("=", 2);\r
- this.supported(l[0], l[1]);\r
- }\r
- }, \r
- irc_RPL_MYINFO: function(prefix, params) {\r
- var pmodes = params[5].split("");\r
- this.pmodes = {}\r
- \r
- pmodes.each(function(pmode) {\r
- this.pmodes[pmode] = true;\r
- }, this);\r
- }, \r
- irc_RPL_NAMREPLY: function(prefix, params) {\r
- var channel = params[2]; \r
- var names = params[3];\r
- \r
- this.channelNames(channel, names.split(" "));\r
- \r
- return true;\r
- },\r
- irc_RPL_ENDOFNAMES: function(prefix, params) {\r
- var channel = params[1];\r
-\r
- this.channelNames(channel, []);\r
- return true;\r
- },\r
- irc_RPL_NOTOPIC: function(prefix, params) {\r
- return true;\r
- }, \r
- irc_RPL_TOPIC: function(prefix, params) {\r
- var channel = params[1];\r
- var topic = params.indexFromEnd(-1);\r
- \r
- if(this.channels[channel]) {\r
- this.initialTopic(channel, topic);\r
- return true;\r
- }\r
- }, \r
- irc_RPL_TOPICWHOTIME: function(prefix, params) {\r
- return true;\r
- }\r
-});\r
+var Numerics = {"001": "RPL_WELCOME", "433": "ERR_NICKNAMEINUSE", "004": "RPL_MYINFO", "005": "RPL_ISUPPORT", "353": "RPL_NAMREPLY", "366": "RPL_ENDOFNAMES", "331": "RPL_NOTOPIC", "332": "RPL_TOPIC", "333": "RPL_TOPICWHOTIME"};
+
+var RegisteredCTCPs = {
+ "VERSION": function(x) {
+ return "qwebirc v" + QWEBIRC_VERSION + ", copyright (C) Chris Porter 2008 -- user agent: " + Browser.Engine.name + " (" + Browser.Platform.name + ")";
+ },
+ "USERINFO": function(x) { return "qwebirc"; },
+ "TIME": function(x) { return IRCTime(new Date()); },
+ "PING": function(x) { return x; },
+ "CLIENTINFO": function(x) { return "PING VERSION TIME USERINFO CLIENTINFO"; }
+};
+
+var BaseIRCClient = new Class({
+ Implements: [Options],
+ options: {
+ nickname: "WCunset",
+ },
+ initialize: function(options) {
+ this.setOptions(options);
+
+ this.nickname = this.options.nickname;
+
+ this.__signedOn = false;
+ this.pmodes = ["b", "k,", "o", "l", "v"];
+ this.channels = {}
+ this.nextctcp = 0;
+
+ this.connection = new IRCConnection({initialNickname: this.nickname, onRecv: this.dispatch.bind(this)});
+
+ this.send = this.connection.send.bind(this.connection);
+ this.connect = this.connection.connect.bind(this.connection);
+ this.disconnect = this.connection.disconnect;
+ },
+ dispatch: function(data) {
+ var message = data[0];
+ if(message == "connect") {
+ this.connected();
+ } else if(message == "disconnect") {
+ this.disconnected();
+ } else if(message == "c") {
+ var command = data[1].toUpperCase();
+
+ var prefix = data[2];
+ var sl = data[3];
+ var n = Numerics[command];
+
+ var x = n;
+ if(!n)
+ n = command;
+
+ var o = this["irc_" + n];
+
+ if(o) {
+ var r = o.attempt([prefix, sl], this);
+ if(!r)
+ this.rawNumeric(command, prefix, sl);
+ } else {
+ this.rawNumeric(command, prefix, sl);
+ }
+ }
+ },
+
+ irc_RPL_WELCOME: function(prefix, params) {
+ this.nickname = params[0];
+
+ this.__signedOn = true;
+ this.signedOn(this.nickname);
+ },
+ irc_ERR_NICKNAMEINUSE: function(prefix, params) {
+ if(this.__signedOn)
+ return;
+
+ var newnick = params[1] + "_";
+ if(newnick == this.lastnick)
+ newnick = "webchat" + Math.floor(Math.random() * 1024 * 1024);
+
+ this.send("NICK " + newnick);
+ this.lastnick = newnick;
+ },
+ irc_NICK: function(prefix, params) {
+ var user = prefix;
+ var oldnick = user.hostToNick();
+ var newnick = params[0];
+
+ if(this.nickname == oldnick)
+ this.nickname = newnick;
+
+ this.nickChanged(user, newnick);
+
+ return true;
+ },
+ irc_QUIT: function(prefix, params) {
+ var user = prefix;
+
+ var message = params.indexFromEnd(-1);
+
+ this.userQuit(user, message);
+
+ return true;
+ },
+ irc_PART: function(prefix, params) {
+ var user = prefix;
+ var channel = params[0];
+ var message = params[1];
+
+ var nick = user.hostToNick();
+
+ if((nick == this.nickname) && this.channels[channel])
+ delete this.channels[channel];
+
+ this.userPart(user, channel, message);
+
+ return true;
+ },
+ irc_KICK: function(prefix, params) {
+ var kicker = prefix;
+ var channel = params[0];
+ var kickee = params[1];
+ var message = params[2];
+
+ if((kickee == this.nickname) && this.channels[channel])
+ delete this.channels[channel];
+
+ this.userKicked(kicker, channel, kickee, message);
+
+ return true;
+ },
+ irc_PING: function(prefix, params) {
+ this.send("PONG :" + params.indexFromEnd(-1));
+
+ return true;
+ },
+ irc_JOIN: function(prefix, params) {
+ var channel = params[0];
+ var user = prefix;
+ var nick = user.hostToNick();
+
+ if(nick == this.nickname)
+ this.channels[channel] = true;
+
+ this.userJoined(user, channel);
+
+ return true;
+ },
+ irc_TOPIC: function(prefix, params) {
+ var user = prefix;
+ var channel = params[0];
+ var topic = params.indexFromEnd(-1);
+
+ this.channelTopic(user, channel, topic);
+
+ return true;
+ },
+ processCTCP: function(message) {
+ if(message.charAt(0) != "\x01")
+ return;
+
+ if(message.charAt(message.length - 1) == "\x01") {
+ message = message.substr(1, message.length - 2);
+ } else {
+ message = message.substr(1);
+ }
+ return message.splitMax(" ", 2);
+ },
+ irc_PRIVMSG: function(prefix, params) {
+ var user = prefix;
+ var target = params[0];
+ var message = params.indexFromEnd(-1);
+
+ var ctcp = this.processCTCP(message);
+ if(ctcp) {
+ var type = ctcp[0].toUpperCase();
+
+ var replyfn = RegisteredCTCPs[type];
+ if(replyfn) {
+ var t = new Date().getTime() / 1000;
+ if(t > this.nextctcp)
+ this.send("NOTICE " + user.hostToNick() + " :\x01" + type + " " + replyfn(ctcp[1]) + "\x01");
+ this.nextctcp = t + 5;
+ }
+
+ if(target == this.nickname) {
+ this.userCTCP(user, type, ctcp[1]);
+ } else {
+ this.channelCTCP(user, target, type, ctcp[1]);
+ }
+ } else {
+ if(target == this.nickname) {
+ this.userPrivmsg(user, message);
+ } else {
+ this.channelPrivmsg(user, target, message);
+ }
+ }
+
+ return true;
+ },
+ irc_NOTICE: function(prefix, params) {
+ var user = prefix;
+ var target = params[0];
+ var message = params.indexFromEnd(-1);
+
+ if(user == "") {
+ this.serverNotice(message);
+ } else if(target == this.nickname) {
+ var ctcp = this.processCTCP(message);
+ if(ctcp) {
+ this.userCTCPReply(user, ctcp[0], ctcp[1]);
+ } else {
+ this.userNotice(user, message);
+ }
+ } else {
+ this.channelNotice(user, target, message);
+ }
+
+ return true;
+ },
+ irc_INVITE: function(prefix, params) {
+ var user = prefix;
+ var channel = params.indexFromEnd(-1);
+
+ this.userInvite(user, channel);
+
+ return true;
+ },
+ irc_ERROR: function(prefix, params) {
+ var message = params.indexFromEnd(-1);
+
+ this.serverError(message);
+
+ return true;
+ },
+ irc_MODE: function(prefix, params) {
+ var user = prefix;
+ var target = params[0];
+ var args = params.slice(1);
+
+ if(target == this.nickname) {
+ this.userMode(args);
+ } else {
+ var modes = args[0].split("");
+ var xargs = args.slice(1);
+
+ var data = []
+ var carg = 0;
+ var pos = 0;
+ var cmode = "+";
+
+ modes.each(function(mode) {
+ if((mode == "+") || (mode == "-")) {
+ cmode = mode;
+ return;
+ }
+
+ if(this.pmodes[mode]) {
+ d = [cmode, mode, xargs[carg++]]
+ } else {
+ d = [cmode, mode]
+ }
+
+ data.push(d);
+ }, this);
+
+ this.channelMode(user, target, data, args);
+ }
+
+ return true;
+ },
+ irc_RPL_ISUPPORT: function(prefix, params) {
+ var supported = params.slice(1, -1);
+ var supportedhash = {};
+
+ for(var i=0;i<supported.length;i++) {
+ var l = supported[i].splitMax("=", 2);
+ this.supported(l[0], l[1]);
+ }
+ },
+ irc_RPL_MYINFO: function(prefix, params) {
+ var pmodes = params[5].split("");
+ this.pmodes = {}
+
+ pmodes.each(function(pmode) {
+ this.pmodes[pmode] = true;
+ }, this);
+ },
+ irc_RPL_NAMREPLY: function(prefix, params) {
+ var channel = params[2];
+ var names = params[3];
+
+ this.channelNames(channel, names.split(" "));
+
+ return true;
+ },
+ irc_RPL_ENDOFNAMES: function(prefix, params) {
+ var channel = params[1];
+
+ this.channelNames(channel, []);
+ return true;
+ },
+ irc_RPL_NOTOPIC: function(prefix, params) {
+ return true;
+ },
+ irc_RPL_TOPIC: function(prefix, params) {
+ var channel = params[1];
+ var topic = params.indexFromEnd(-1);
+
+ if(this.channels[channel]) {
+ this.initialTopic(channel, topic);
+ return true;
+ }
+ },
+ irc_RPL_TOPICWHOTIME: function(prefix, params) {
+ return true;
+ }
+});
-var CommandParser = new Class({\r
- initialize: function(parentObject) {\r
- this.aliases = {\r
- "J": "JOIN",\r
- "K": "KICK",\r
- "MSG": "PRIVMSG",\r
- "Q": "QUERY"\r
- };\r
- \r
- this.send = parentObject.send;\r
- this.parentObject = parentObject;\r
- },\r
- newTargetLine: function(target, type, message, extra) {\r
- if(!extra)\r
- extra = {}\r
-\r
- extra["n"] = this.parentObject.getNickname();\r
- extra["m"] = message;\r
- extra["t"] = target;\r
-\r
- var window = this.parentObject.getWindow(target);\r
- var channel;\r
- if(!window) {\r
- type = "TARGETED" + type;\r
- target = false;\r
- } else if(window.type == WINDOW_CHANNEL) {\r
- type = "CHAN" + type;\r
- } else {\r
- type = "PRIV" + type;\r
- }\r
-\r
- this.parentObject.newLine(target, "OUR" + type, extra);\r
- },\r
- dispatch: function(line) {\r
- if(line.length == 0)\r
- return;\r
-\r
- if(line.charAt(0) != "/")\r
- line = "/SAY " + line;\r
- \r
- var line = line.substr(1);\r
- var allargs = line.splitMax(" ", 2);\r
- var command = allargs[0].toUpperCase();\r
- var args = allargs[1];\r
- \r
- var aliascmd = this.aliases[command];\r
- if(aliascmd)\r
- command = aliascmd;\r
- \r
- for(;;) {\r
- var cmdopts = this["cmd_" + command];\r
- if(!cmdopts) {\r
- if(args) {\r
- this.send(command + " " + args);\r
- } else {\r
- this.send(command);\r
- }\r
- return;\r
- }\r
- \r
- var activewin = cmdopts[0];\r
- var splitargs = cmdopts[1];\r
- var minargs = cmdopts[2]; \r
- var fn = cmdopts[3];\r
- \r
- var w = this.parentObject.getActiveWindow();\r
- if(activewin && w.type == WINDOW_STATUS) {\r
- w.errorMessage("Can't use this command in this window");\r
- return;\r
- }\r
- \r
- if(splitargs != undefined)\r
- args = args.splitMax(" ", splitargs);\r
- \r
- if((minargs != undefined) && (minargs > args.length)) {\r
- w.errorMessage("Insufficient arguments for command.")\r
- return;\r
- }\r
- \r
- var ret = fn.attempt([args], this);\r
- if(ret == undefined)\r
- return;\r
- \r
- command = ret[0];\r
- args = ret[1];\r
- }\r
- },\r
- \r
- \r
- cmd_ME: [true, undefined, undefined, function(args) {\r
- if(args == undefined)\r
- args = "";\r
- return ["SAY", "\x01ACTION " + args + "\x01"];\r
- }],\r
- cmd_CTCP: [false, 3, 2, function(args) {\r
- var target = args[0];\r
- var type = args[1].toUpperCase();\r
- var message = args[2];\r
- \r
- if(message == undefined)\r
- message = "";\r
-\r
- if(message == "") {\r
- this.send("PRIVMSG " + target + " :\x01" + type + "\x01");\r
- } else {\r
- this.send("PRIVMSG " + target + " :\x01" + type + " " + message + "\x01");\r
- }\r
- \r
- this.newTargetLine(target, "CTCP", message, {"x": type});\r
- }],\r
- cmd_PRIVMSG: [false, 2, 2, function(args) {\r
- var target = args[0];\r
- var message = args[1];\r
- \r
- this.newTargetLine(target, "MSG", message, {});\r
- \r
- this.send("PRIVMSG " + target + " :" + message);\r
- }],\r
- cmd_NOTICE: [false, 2, 2, function(args) {\r
- var target = args[0];\r
- var message = args[1];\r
-\r
- this.newTargetLine(target, "NOTICE", message);\r
- this.send("NOTICE " + target + " :" + message);\r
- }],\r
- cmd_QUERY: [false, 2, 1, function(args) {\r
- this.parentObject.newWindow(args[0], WINDOW_QUERY, true);\r
-\r
- if((args.length > 1) && (args[1] != ""))\r
- return ["SAY", args[1]];\r
- }],\r
- cmd_SAY: [true, undefined, undefined, function(args) {\r
- if(args == undefined)\r
- args = "";\r
- \r
- return ["PRIVMSG", this.parentObject.getActiveWindow().name + " " + args]\r
- }],\r
- KICK: [true, 3, 2, function(args) {\r
- var channel = args[0];\r
- var target = args[1];\r
- var message = args[2];\r
- if(!message)\r
- message = "";\r
- \r
- this.send("KICK " + channel + " " + target + " :" + message);\r
- }],\r
-});\r
+var CommandParser = new Class({
+ initialize: function(parentObject) {
+ this.aliases = {
+ "J": "JOIN",
+ "K": "KICK",
+ "MSG": "PRIVMSG",
+ "Q": "QUERY"
+ };
+
+ this.send = parentObject.send;
+ this.parentObject = parentObject;
+ },
+ newTargetLine: function(target, type, message, extra) {
+ if(!extra)
+ extra = {}
+
+ extra["n"] = this.parentObject.getNickname();
+ extra["m"] = message;
+ extra["t"] = target;
+
+ var window = this.parentObject.getWindow(target);
+ var channel;
+ if(!window) {
+ type = "TARGETED" + type;
+ target = false;
+ } else if(window.type == WINDOW_CHANNEL) {
+ type = "CHAN" + type;
+ } else {
+ type = "PRIV" + type;
+ }
+
+ this.parentObject.newLine(target, "OUR" + type, extra);
+ },
+ dispatch: function(line) {
+ if(line.length == 0)
+ return;
+
+ if(line.charAt(0) != "/")
+ line = "/SAY " + line;
+
+ var line = line.substr(1);
+ var allargs = line.splitMax(" ", 2);
+ var command = allargs[0].toUpperCase();
+ var args = allargs[1];
+
+ var aliascmd = this.aliases[command];
+ if(aliascmd)
+ command = aliascmd;
+
+ for(;;) {
+ var cmdopts = this["cmd_" + command];
+ if(!cmdopts) {
+ if(args) {
+ this.send(command + " " + args);
+ } else {
+ this.send(command);
+ }
+ return;
+ }
+
+ var activewin = cmdopts[0];
+ var splitargs = cmdopts[1];
+ var minargs = cmdopts[2];
+ var fn = cmdopts[3];
+
+ var w = this.parentObject.getActiveWindow();
+ if(activewin && w.type == WINDOW_STATUS) {
+ w.errorMessage("Can't use this command in this window");
+ return;
+ }
+
+ if(splitargs != undefined)
+ args = args.splitMax(" ", splitargs);
+
+ if((minargs != undefined) && (minargs > args.length)) {
+ w.errorMessage("Insufficient arguments for command.")
+ return;
+ }
+
+ var ret = fn.attempt([args], this);
+ if(ret == undefined)
+ return;
+
+ command = ret[0];
+ args = ret[1];
+ }
+ },
+
+
+ cmd_ME: [true, undefined, undefined, function(args) {
+ if(args == undefined)
+ args = "";
+ return ["SAY", "\x01ACTION " + args + "\x01"];
+ }],
+ cmd_CTCP: [false, 3, 2, function(args) {
+ var target = args[0];
+ var type = args[1].toUpperCase();
+ var message = args[2];
+
+ if(message == undefined)
+ message = "";
+
+ if(message == "") {
+ this.send("PRIVMSG " + target + " :\x01" + type + "\x01");
+ } else {
+ this.send("PRIVMSG " + target + " :\x01" + type + " " + message + "\x01");
+ }
+
+ this.newTargetLine(target, "CTCP", message, {"x": type});
+ }],
+ cmd_PRIVMSG: [false, 2, 2, function(args) {
+ var target = args[0];
+ var message = args[1];
+
+ this.newTargetLine(target, "MSG", message, {});
+
+ this.send("PRIVMSG " + target + " :" + message);
+ }],
+ cmd_NOTICE: [false, 2, 2, function(args) {
+ var target = args[0];
+ var message = args[1];
+
+ this.newTargetLine(target, "NOTICE", message);
+ this.send("NOTICE " + target + " :" + message);
+ }],
+ cmd_QUERY: [false, 2, 1, function(args) {
+ this.parentObject.newWindow(args[0], WINDOW_QUERY, true);
+
+ if((args.length > 1) && (args[1] != ""))
+ return ["SAY", args[1]];
+ }],
+ cmd_SAY: [true, undefined, undefined, function(args) {
+ if(args == undefined)
+ args = "";
+
+ return ["PRIVMSG", this.parentObject.getActiveWindow().name + " " + args]
+ }],
+ KICK: [true, 3, 2, function(args) {
+ var channel = args[0];
+ var target = args[1];
+ var message = args[2];
+ if(!message)
+ message = "";
+
+ this.send("KICK " + channel + " " + target + " :" + message);
+ }],
+});
-var IRCClient = new Class({\r
- Extends: BaseIRCClient,\r
- options: {\r
- nickname: "WCunset",\r
- autojoin: "",\r
- },\r
- initialize: function(options, ui) {\r
- this.parent(options);\r
-\r
- this.ui = ui;\r
-\r
- this.prefixes = "@+";\r
- this.modeprefixes = "ov";\r
- this.windows = {};\r
- \r
- this.commandparser = new CommandParser(this);\r
- this.exec = this.commandparser.dispatch.bind(this.commandparser);\r
-\r
- this.statusWindow = this.ui.newClient(this);\r
- },\r
- newLine: function(window, type, data) {\r
- if(!data)\r
- data = {};\r
- \r
- var w = this.getWindow(window);\r
- if(w) {\r
- w.addLine(type, data);\r
- } else {\r
- this.statusWindow.addLine(type, data);\r
- }\r
- },\r
- newChanLine: function(channel, type, user, extra) {\r
- if(!extra)\r
- extra = {};\r
-\r
- extra["n"] = user.hostToNick();\r
- extra["h"] = user.hostToHost();\r
- extra["c"] = channel;\r
- extra["-"] = this.nickname;\r
- \r
- this.newLine(channel, type, extra);\r
- },\r
- newServerLine: function(type, data) {\r
- this.statusWindow.addLine(type, data);\r
- },\r
- newActiveLine: function(type, data) {\r
- this.ui.getActiveWindow().addLine(type, data);\r
- },\r
- updateNickList: function(channel) {\r
- var n1 = this.tracker.getChannel(channel);\r
- var names = new Array();\r
- var tff = String.fromCharCode(255);\r
- var nh = {}\r
- \r
- /* MEGAHACK */\r
- for(var n in n1) {\r
- var nc = n1[n];\r
- var nx;\r
- \r
- if(nc.prefixes.length > 0) {\r
- var c = nc.prefixes.charAt(0);\r
- nx = String.fromCharCode(this.prefixes.indexOf(c)) + n.toIRCLower();\r
- nh[nx] = c + n;\r
- } else {\r
- nx = tff + n.toIRCLower();\r
- nh[nx] = n;\r
- }\r
- names.push(nx);\r
- };\r
- \r
- names.sort();\r
- \r
- var sortednames = new Array();\r
- names.each(function(name) {\r
- sortednames.push(nh[name]);\r
- });\r
- \r
- var w = this.getWindow(channel);\r
- if(w)\r
- w.updateNickList(sortednames);\r
- },\r
- getWindow: function(name) {\r
- return this.windows[name];\r
- },\r
- newWindow: function(name, type, select) {\r
- var w = this.getWindow(name);\r
- if(!w) {\r
- w = this.windows[name] = this.ui.newWindow(this, type, name);\r
- \r
- w.addEvent("close", function(w) {\r
- delete this.windows[name];\r
- }.bind(this));\r
- }\r
- \r
- if(select)\r
- this.ui.selectWindow(w);\r
- \r
- return w;\r
- },\r
- getActiveWindow: function() {\r
- return this.ui.getActiveWindow();\r
- },\r
- getNickname: function() {\r
- return this.nickname;\r
- },\r
- addPrefix: function(nickchanentry, prefix) {\r
- var ncp = nickchanentry.prefixes + prefix;\r
- var prefixes = [];\r
- \r
- /* O(n^2) */\r
- for(var i=0;i<this.prefixes.length;i++) {\r
- var pc = this.prefixes.charAt(i);\r
- var index = ncp.indexOf(pc);\r
- if(index != -1)\r
- prefixes.push(pc);\r
- }\r
- \r
- nickchanentry.prefixes = prefixes.join("");\r
- },\r
- removePrefix: function(nickchanentry, prefix) {\r
- nickchanentry.prefixes = nickchanentry.prefixes.replaceAll(prefix, "");\r
- },\r
- \r
- /* from here down are events */\r
- rawNumeric: function(numeric, prefix, params) {\r
- this.newServerLine("RAW", {"n": "numeric", "m": params.slice(1).join(" ")});\r
- },\r
- signedOn: function(nickname) {\r
- this.tracker = new IRCTracker();\r
- this.nickname = nickname;\r
- this.newServerLine("SIGNON");\r
- \r
- if(this.autojoin)\r
- this.send("JOIN " + this.autojoin);\r
- },\r
- userJoined: function(user, channel) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
- \r
- if((nick == this.nickname) && !this.getWindow(channel))\r
- this.newWindow(channel, WINDOW_CHANNEL, true);\r
- this.tracker.addNickToChannel(nick, channel);\r
-\r
- this.newChanLine(channel, "JOIN", user);\r
- this.updateNickList(channel);\r
- },\r
- userPart: function(user, channel, message) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
- \r
- if(nick == this.nickname) {\r
- this.tracker.removeChannel(channel);\r
- } else {\r
- this.tracker.removeNickFromChannel(nick, channel);\r
- this.newChanLine(channel, "PART", user, {"m": message});\r
- }\r
- \r
- this.updateNickList(channel);\r
- \r
- var w = this.getWindow(channel)\r
- if(w)\r
- w.close();\r
- },\r
- userKicked: function(kicker, channel, kickee, message) {\r
- if(kickee == this.nickname) {\r
- this.tracker.removeChannel(channel);\r
- this.getWindow(channel).close();\r
- } else {\r
- this.tracker.removeNickFromChannel(kickee, channel);\r
- this.updateNickList(channel);\r
- }\r
- \r
- this.newChanLine(channel, "KICK", kicker, {"v": kickee, "m": message});\r
- },\r
- channelMode: function(user, channel, modes, raw) {\r
- modes.each(function(mo) {\r
- var direction = mo[0];\r
- var mode = mo[1];\r
-\r
- var prefixindex = this.modeprefixes.indexOf(mode);\r
- if(prefixindex == -1)\r
- return;\r
- \r
- var nick = mo[2];\r
- var prefixchar = this.prefixes.charAt(prefixindex);\r
-\r
- var nc = this.tracker.getOrCreateNickOnChannel(nick, channel);\r
- if(direction == "-") {\r
- this.removePrefix(nc, prefixchar);\r
- } else {\r
- this.addPrefix(nc, prefixchar);\r
- }\r
- }, this);\r
-\r
- this.newChanLine(channel, "MODE", user, {"m": raw.join(" ")});\r
- \r
- this.updateNickList(channel);\r
- },\r
- userQuit: function(user, message) {\r
- var nick = user.hostToNick();\r
- \r
- var channels = this.tracker.getNick(nick);\r
- \r
- var clist = [];\r
- for(var c in channels) {\r
- clist.push(c);\r
- this.newChanLine(c, "QUIT", user, {"m": message});\r
- }\r
- \r
- this.tracker.removeNick(nick);\r
- \r
- clist.each(function(cli) {\r
- this.updateNickList(cli);\r
- }, this);\r
- },\r
- nickChanged: function(user, newnick) {\r
- var oldnick = user.hostToNick();\r
- \r
- if(oldnick == this.nickname)\r
- this.nickname = newnick;\r
- \r
- this.tracker.renameNick(oldnick, newnick);\r
-\r
- var channels = this.tracker.getNick(newnick);\r
- \r
- for(var c in channels) {\r
- this.newChanLine(c, "NICK", user, {"w": newnick});\r
- /* TODO: rename queries */\r
- this.updateNickList(c);\r
- }\r
- },\r
- channelTopic: function(user, channel, topic) {\r
- this.newChanLine(channel, "TOPIC", user, {"m": topic});\r
- this.getWindow(channel).updateTopic(topic);\r
- },\r
- initialTopic: function(channel, topic) {\r
- this.getWindow(channel).updateTopic(topic);\r
- },\r
- channelCTCP: function(user, channel, type, args) {\r
- if(args == undefined)\r
- args = "";\r
-\r
- if(type == "ACTION") {\r
- this.newChanLine(channel, "CHANACTION", user, {"m": args, "c": channel});\r
- return;\r
- }\r
- \r
- this.newChanLine(channel, "CHANCTCP", user, {"x": type, "m": args, "c": channel});\r
- },\r
- userCTCP: function(user, type, args) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
- if(args == undefined)\r
- args = "";\r
- \r
- if(type == "ACTION") { \r
- this.newWindow(nick, WINDOW_QUERY);\r
- this.newLine(nick, "PRIVACTION", {"m": args, "x": type, "h": host, "n": nick});\r
- return;\r
- }\r
- \r
- if(this.getWindow(nick)) {\r
- this.newLine(nick, "PRIVCTCP", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});\r
- } else {\r
- this.newActiveLine("PRIVCTCP", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});\r
- }\r
- },\r
- userCTCPReply: function(user, type, args) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
- if(args == undefined)\r
- args = "";\r
- \r
- if(this.getWindow(nick)) {\r
- this.newLine(nick, "CTCPREPLY", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});\r
- } else {\r
- this.newActiveLine("CTCPREPLY", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});\r
- }\r
- },\r
- channelPrivmsg: function(user, channel, message) {\r
- this.newChanLine(channel, "CHANMSG", user, {"m": message});\r
- },\r
- channelNotice: function(user, channel, message) {\r
- this.newChanLine(channel, "CHANNOTICE", user, {"m": message});\r
- },\r
- userPrivmsg: function(user, message) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
- \r
- this.newWindow(nick, WINDOW_QUERY);\r
- \r
- this.newLine(nick, "PRIVMSG", {"m": message, "h": host, "n": nick});\r
- },\r
- serverNotice: function(message) {\r
- this.newServerLine("SERVERNOTICE", {"m": message});\r
- },\r
- userNotice: function(user, message) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
-\r
- if(this.getWindow(nick)) {\r
- this.newLine(nick, "PRIVNOTICE", {"m": message, "h": host, "n": nick});\r
- } else {\r
- this.newActiveLine("PRIVNOTICE", {"m": message, "h": host, "n": nick});\r
- }\r
- },\r
- userInvite: function(user, channel) {\r
- var nick = user.hostToNick();\r
- var host = user.hostToHost();\r
-\r
- this.newServerLine("INVITE", {"c": channel, "h": host, "n": nick});\r
- },\r
- userMode: function(modes) {\r
- this.newServerLine("UMODE", {"m": modes, "n": this.nickname});\r
- },\r
- channelNames: function(channel, names) {\r
- if(names.length == 0) {\r
- this.updateNickList(channel);\r
- return;\r
- }\r
- \r
- names.each(function(nick) {\r
- var prefixes = [];\r
- var splitnick = nick.split("");\r
- \r
- splitnick.every(function(c, i) {\r
- if(this.prefixes.indexOf(c) == -1) {\r
- nick = nick.substr(i);\r
- return false;\r
- }\r
- \r
- prefixes.push(c);\r
- return true;\r
- }, this);\r
-\r
- var nc = this.tracker.addNickToChannel(nick, channel);\r
- prefixes.each(function(p) {\r
- this.addPrefix(nc, p);\r
- }, this);\r
- }, this);\r
- },\r
- disconnected: function() {\r
- for(var x in this.parent.channels)\r
- this.ui.closeWindow(x);\r
-\r
- this.tracker = undefined;\r
- \r
- this.newServerLine("DISCONNECT");\r
- },\r
- supported: function(key, value) {\r
- if(key == "PREFIX") {\r
- var l = (value.length - 2) / 2;\r
-\r
- this.modeprefixes = value.substr(1, l);\r
- this.prefixes = value.substr(l + 2, l);\r
- }\r
- },\r
- connected: function() {\r
- this.newServerLine("CONNECT");\r
- },\r
- serverError: function(message) {\r
- this.newServerLine("ERROR", {"m": message});\r
- }\r
-});\r
+var IRCClient = new Class({
+ Extends: BaseIRCClient,
+ options: {
+ nickname: "WCunset",
+ autojoin: "",
+ },
+ initialize: function(options, ui) {
+ this.parent(options);
+
+ this.ui = ui;
+
+ this.prefixes = "@+";
+ this.modeprefixes = "ov";
+ this.windows = {};
+
+ this.commandparser = new CommandParser(this);
+ this.exec = this.commandparser.dispatch.bind(this.commandparser);
+
+ this.statusWindow = this.ui.newClient(this);
+ },
+ newLine: function(window, type, data) {
+ if(!data)
+ data = {};
+
+ var w = this.getWindow(window);
+ if(w) {
+ w.addLine(type, data);
+ } else {
+ this.statusWindow.addLine(type, data);
+ }
+ },
+ newChanLine: function(channel, type, user, extra) {
+ if(!extra)
+ extra = {};
+
+ extra["n"] = user.hostToNick();
+ extra["h"] = user.hostToHost();
+ extra["c"] = channel;
+ extra["-"] = this.nickname;
+
+ this.newLine(channel, type, extra);
+ },
+ newServerLine: function(type, data) {
+ this.statusWindow.addLine(type, data);
+ },
+ newActiveLine: function(type, data) {
+ this.ui.getActiveWindow().addLine(type, data);
+ },
+ updateNickList: function(channel) {
+ var n1 = this.tracker.getChannel(channel);
+ var names = new Array();
+ var tff = String.fromCharCode(255);
+ var nh = {}
+
+ /* MEGAHACK */
+ for(var n in n1) {
+ var nc = n1[n];
+ var nx;
+
+ if(nc.prefixes.length > 0) {
+ var c = nc.prefixes.charAt(0);
+ nx = String.fromCharCode(this.prefixes.indexOf(c)) + n.toIRCLower();
+ nh[nx] = c + n;
+ } else {
+ nx = tff + n.toIRCLower();
+ nh[nx] = n;
+ }
+ names.push(nx);
+ };
+
+ names.sort();
+
+ var sortednames = new Array();
+ names.each(function(name) {
+ sortednames.push(nh[name]);
+ });
+
+ var w = this.getWindow(channel);
+ if(w)
+ w.updateNickList(sortednames);
+ },
+ getWindow: function(name) {
+ return this.windows[name];
+ },
+ newWindow: function(name, type, select) {
+ var w = this.getWindow(name);
+ if(!w) {
+ w = this.windows[name] = this.ui.newWindow(this, type, name);
+
+ w.addEvent("close", function(w) {
+ delete this.windows[name];
+ }.bind(this));
+ }
+
+ if(select)
+ this.ui.selectWindow(w);
+
+ return w;
+ },
+ getActiveWindow: function() {
+ return this.ui.getActiveWindow();
+ },
+ getNickname: function() {
+ return this.nickname;
+ },
+ addPrefix: function(nickchanentry, prefix) {
+ var ncp = nickchanentry.prefixes + prefix;
+ var prefixes = [];
+
+ /* O(n^2) */
+ for(var i=0;i<this.prefixes.length;i++) {
+ var pc = this.prefixes.charAt(i);
+ var index = ncp.indexOf(pc);
+ if(index != -1)
+ prefixes.push(pc);
+ }
+
+ nickchanentry.prefixes = prefixes.join("");
+ },
+ removePrefix: function(nickchanentry, prefix) {
+ nickchanentry.prefixes = nickchanentry.prefixes.replaceAll(prefix, "");
+ },
+
+ /* from here down are events */
+ rawNumeric: function(numeric, prefix, params) {
+ this.newServerLine("RAW", {"n": "numeric", "m": params.slice(1).join(" ")});
+ },
+ signedOn: function(nickname) {
+ this.tracker = new IRCTracker();
+ this.nickname = nickname;
+ this.newServerLine("SIGNON");
+
+ if(this.autojoin)
+ this.send("JOIN " + this.autojoin);
+ },
+ userJoined: function(user, channel) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+
+ if((nick == this.nickname) && !this.getWindow(channel))
+ this.newWindow(channel, WINDOW_CHANNEL, true);
+ this.tracker.addNickToChannel(nick, channel);
+
+ this.newChanLine(channel, "JOIN", user);
+ this.updateNickList(channel);
+ },
+ userPart: function(user, channel, message) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+
+ if(nick == this.nickname) {
+ this.tracker.removeChannel(channel);
+ } else {
+ this.tracker.removeNickFromChannel(nick, channel);
+ this.newChanLine(channel, "PART", user, {"m": message});
+ }
+
+ this.updateNickList(channel);
+
+ var w = this.getWindow(channel)
+ if(w)
+ w.close();
+ },
+ userKicked: function(kicker, channel, kickee, message) {
+ if(kickee == this.nickname) {
+ this.tracker.removeChannel(channel);
+ this.getWindow(channel).close();
+ } else {
+ this.tracker.removeNickFromChannel(kickee, channel);
+ this.updateNickList(channel);
+ }
+
+ this.newChanLine(channel, "KICK", kicker, {"v": kickee, "m": message});
+ },
+ channelMode: function(user, channel, modes, raw) {
+ modes.each(function(mo) {
+ var direction = mo[0];
+ var mode = mo[1];
+
+ var prefixindex = this.modeprefixes.indexOf(mode);
+ if(prefixindex == -1)
+ return;
+
+ var nick = mo[2];
+ var prefixchar = this.prefixes.charAt(prefixindex);
+
+ var nc = this.tracker.getOrCreateNickOnChannel(nick, channel);
+ if(direction == "-") {
+ this.removePrefix(nc, prefixchar);
+ } else {
+ this.addPrefix(nc, prefixchar);
+ }
+ }, this);
+
+ this.newChanLine(channel, "MODE", user, {"m": raw.join(" ")});
+
+ this.updateNickList(channel);
+ },
+ userQuit: function(user, message) {
+ var nick = user.hostToNick();
+
+ var channels = this.tracker.getNick(nick);
+
+ var clist = [];
+ for(var c in channels) {
+ clist.push(c);
+ this.newChanLine(c, "QUIT", user, {"m": message});
+ }
+
+ this.tracker.removeNick(nick);
+
+ clist.each(function(cli) {
+ this.updateNickList(cli);
+ }, this);
+ },
+ nickChanged: function(user, newnick) {
+ var oldnick = user.hostToNick();
+
+ if(oldnick == this.nickname)
+ this.nickname = newnick;
+
+ this.tracker.renameNick(oldnick, newnick);
+
+ var channels = this.tracker.getNick(newnick);
+
+ for(var c in channels) {
+ this.newChanLine(c, "NICK", user, {"w": newnick});
+ /* TODO: rename queries */
+ this.updateNickList(c);
+ }
+ },
+ channelTopic: function(user, channel, topic) {
+ this.newChanLine(channel, "TOPIC", user, {"m": topic});
+ this.getWindow(channel).updateTopic(topic);
+ },
+ initialTopic: function(channel, topic) {
+ this.getWindow(channel).updateTopic(topic);
+ },
+ channelCTCP: function(user, channel, type, args) {
+ if(args == undefined)
+ args = "";
+
+ if(type == "ACTION") {
+ this.newChanLine(channel, "CHANACTION", user, {"m": args, "c": channel});
+ return;
+ }
+
+ this.newChanLine(channel, "CHANCTCP", user, {"x": type, "m": args, "c": channel});
+ },
+ userCTCP: function(user, type, args) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+ if(args == undefined)
+ args = "";
+
+ if(type == "ACTION") {
+ this.newWindow(nick, WINDOW_QUERY);
+ this.newLine(nick, "PRIVACTION", {"m": args, "x": type, "h": host, "n": nick});
+ return;
+ }
+
+ if(this.getWindow(nick)) {
+ this.newLine(nick, "PRIVCTCP", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});
+ } else {
+ this.newActiveLine("PRIVCTCP", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});
+ }
+ },
+ userCTCPReply: function(user, type, args) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+ if(args == undefined)
+ args = "";
+
+ if(this.getWindow(nick)) {
+ this.newLine(nick, "CTCPREPLY", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});
+ } else {
+ this.newActiveLine("CTCPREPLY", {"m": args, "x": type, "h": host, "n": nick, "-": this.nickname});
+ }
+ },
+ channelPrivmsg: function(user, channel, message) {
+ this.newChanLine(channel, "CHANMSG", user, {"m": message});
+ },
+ channelNotice: function(user, channel, message) {
+ this.newChanLine(channel, "CHANNOTICE", user, {"m": message});
+ },
+ userPrivmsg: function(user, message) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+
+ this.newWindow(nick, WINDOW_QUERY);
+
+ this.newLine(nick, "PRIVMSG", {"m": message, "h": host, "n": nick});
+ },
+ serverNotice: function(message) {
+ this.newServerLine("SERVERNOTICE", {"m": message});
+ },
+ userNotice: function(user, message) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+
+ if(this.getWindow(nick)) {
+ this.newLine(nick, "PRIVNOTICE", {"m": message, "h": host, "n": nick});
+ } else {
+ this.newActiveLine("PRIVNOTICE", {"m": message, "h": host, "n": nick});
+ }
+ },
+ userInvite: function(user, channel) {
+ var nick = user.hostToNick();
+ var host = user.hostToHost();
+
+ this.newServerLine("INVITE", {"c": channel, "h": host, "n": nick});
+ },
+ userMode: function(modes) {
+ this.newServerLine("UMODE", {"m": modes, "n": this.nickname});
+ },
+ channelNames: function(channel, names) {
+ if(names.length == 0) {
+ this.updateNickList(channel);
+ return;
+ }
+
+ names.each(function(nick) {
+ var prefixes = [];
+ var splitnick = nick.split("");
+
+ splitnick.every(function(c, i) {
+ if(this.prefixes.indexOf(c) == -1) {
+ nick = nick.substr(i);
+ return false;
+ }
+
+ prefixes.push(c);
+ return true;
+ }, this);
+
+ var nc = this.tracker.addNickToChannel(nick, channel);
+ prefixes.each(function(p) {
+ this.addPrefix(nc, p);
+ }, this);
+ }, this);
+ },
+ disconnected: function() {
+ for(var x in this.parent.channels)
+ this.ui.closeWindow(x);
+
+ this.tracker = undefined;
+
+ this.newServerLine("DISCONNECT");
+ },
+ supported: function(key, value) {
+ if(key == "PREFIX") {
+ var l = (value.length - 2) / 2;
+
+ this.modeprefixes = value.substr(1, l);
+ this.prefixes = value.substr(l + 2, l);
+ }
+ },
+ connected: function() {
+ this.newServerLine("CONNECT");
+ },
+ serverError: function(message) {
+ this.newServerLine("ERROR", {"m": message});
+ }
+});
-var IRCConnection = new Class({\r
- Implements: [Events, Options],\r
- options: {\r
- initialNickname: "ircconnX"\r
- },\r
- initialize: function(options) {\r
- this.setOptions(options);\r
- \r
- this.initialNickname = this.options.initialNickname;\r
- \r
- this.counter = 0;\r
- this.disconnected = false;\r
- },\r
- send: function(data) {\r
- var r = new Request.JSON({url: "/e/p/" + this.sessionid + "?c=" + encodeURIComponent(data) + "&t=" + this.counter++, onComplete: function(o) {\r
- if(o[0] == false)\r
- alert("An error occured: " + o[1]);\r
- }});\r
- \r
- r.get();\r
- },\r
- x: function() {\r
- this.fireEvent("recv", [[false, "moo"]]);\r
- },\r
- recv: function() {\r
- if(this.disconnected)\r
- return;\r
- \r
- var r = new Request.JSON({url: "/e/s/" + this.sessionid + "?t=" + this.counter++, onComplete: function(o) {\r
- if(o[0] == false) {\r
- alert("An error occured: " + o[1]);\r
- return;\r
- }\r
- o.each(function(x) {\r
- this.fireEvent("recv", [x]);\r
- }, this);\r
- \r
- this.recv();\r
- }.bind(this)}); \r
- r.get();\r
- },\r
- connect: function() {\r
- var r = new Request.JSON({url: "/e/n?nick=" + encodeURIComponent(this.initialNickname) + "&r=" + Math.random() * 1024 * 1024, onComplete: function(o) {\r
- if(o[0] == false) {\r
- alert("An error occured: " + o[1]);\r
- return;\r
- }\r
- this.sessionid = o[1];\r
- \r
- this.recv(); \r
- }.bind(this)});\r
- r.get();\r
- },\r
- disconnect: function() {\r
- this.disconnected = true;\r
- }\r
-});\r
+var IRCConnection = new Class({
+ Implements: [Events, Options],
+ options: {
+ initialNickname: "ircconnX"
+ },
+ initialize: function(options) {
+ this.setOptions(options);
+
+ this.initialNickname = this.options.initialNickname;
+
+ this.counter = 0;
+ this.disconnected = false;
+ },
+ send: function(data) {
+ var r = new Request.JSON({url: "/e/p/" + this.sessionid + "?c=" + encodeURIComponent(data) + "&t=" + this.counter++, onComplete: function(o) {
+ if(o[0] == false)
+ alert("An error occured: " + o[1]);
+ }});
+
+ r.get();
+ },
+ x: function() {
+ this.fireEvent("recv", [[false, "moo"]]);
+ },
+ recv: function() {
+ if(this.disconnected)
+ return;
+
+ var r = new Request.JSON({url: "/e/s/" + this.sessionid + "?t=" + this.counter++, onComplete: function(o) {
+ if(o[0] == false) {
+ alert("An error occured: " + o[1]);
+ return;
+ }
+ o.each(function(x) {
+ this.fireEvent("recv", [x]);
+ }, this);
+
+ this.recv();
+ }.bind(this)});
+ r.get();
+ },
+ connect: function() {
+ var r = new Request.JSON({url: "/e/n?nick=" + encodeURIComponent(this.initialNickname) + "&r=" + Math.random() * 1024 * 1024, onComplete: function(o) {
+ if(o[0] == false) {
+ alert("An error occured: " + o[1]);
+ return;
+ }
+ this.sessionid = o[1];
+
+ this.recv();
+ }.bind(this)});
+ r.get();
+ },
+ disconnect: function() {
+ this.disconnected = true;
+ }
+});
-var IRCLowerTable = [\r
-/* x00-x07 */ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',\r
-/* x08-x0f */ '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',\r
-/* x10-x17 */ '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',\r
-/* x18-x1f */ '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',\r
-/* ' '-x27 */ ' ', '!', '"', '#', '$', '%', '&', '\x27',\r
-/* '('-'/' */ '(', ')', '*', '+', ',', '-', '.', '/',\r
-/* '0'-'7' */ '0', '1', '2', '3', '4', '5', '6', '7',\r
-/* '8'-'?' */ '8', '9', ':', ';', '<', '=', '>', '?',\r
-/* '@'-'G' */ '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',\r
-/* 'H'-'O' */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',\r
-/* 'P'-'W' */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',\r
-/* 'X'-'_' */ 'x', 'y', 'z', '{', '|', '}', '~', '_',\r
-/* '`'-'g' */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',\r
-/* 'h'-'o' */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',\r
-/* 'p'-'w' */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',\r
-/* 'x'-x7f */ 'x', 'y', 'z', '{', '|', '}', '~', '\x7f',\r
-/* x80-x87 */ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',\r
-/* x88-x8f */ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f',\r
-/* x90-x97 */ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97',\r
-/* x98-x9f */ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f',\r
-/* xa0-xa7 */ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7',\r
-/* xa8-xaf */ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf',\r
-/* xb0-xb7 */ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7',\r
-/* xb8-xbf */ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf',\r
-/* xc0-xc7 */ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7',\r
-/* xc8-xcf */ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',\r
-/* xd0-xd7 */ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xd7',\r
-/* xd8-xdf */ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xdf',\r
-/* xe0-xe7 */ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7',\r
-/* xe8-xef */ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',\r
-/* xf0-xf7 */ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7',\r
-/* xf8-xff */ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff'\r
-];\r
-\r
-String.prototype.toIRCLower = function() {\r
- var x = this;\r
- \r
- var p = [];\r
- for(var i=0;i<x.length;i++) {\r
- var l = x.charCodeAt(i);\r
-\r
- p.push(IRCLowerTable[l]);\r
- }\r
- \r
- return p.join("");\r
-}\r
-\r
-String.prototype.hostToNick = function() {\r
- return this.split("!", 1)[0];\r
-}\r
-\r
-String.prototype.hostToHost = function() {\r
- return this.split("!", 2)[1];\r
-}\r
-\r
-function IRCTimestamp(d) {\r
- function pad(x) {\r
- x = "" + x;\r
- if(x.length == 1)\r
- return "0" + x;\r
- return x\r
- }\r
- \r
- return "[" + pad(d.getHours()) + ":" + pad(d.getMinutes()) + "]";\r
-}\r
-\r
-var DaysOfWeek = {\r
- 0: "Sun",\r
- 1: "Mon",\r
- 2: "Tue",\r
- 3: "Wed",\r
- 4: "Thu",\r
- 5: "Fri",\r
- 6: "Sat"\r
-};\r
-\r
-var MonthsOfYear = {\r
- 0: "Jan",\r
- 1: "Feb",\r
- 2: "Mar",\r
- 3: "Apr",\r
- 4: "May",\r
- 5: "Jun",\r
- 6: "Jul",\r
- 7: "Aug",\r
- 8: "Sep",\r
- 9: "Oct",\r
- 10: "Nov",\r
- 11: "Dec"\r
-};\r
-\r
-function IRCDate(d) {\r
- return DaysOfWeek[d.getDay()] + " " + MonthsOfYear[d.getMonth()] + " " + pad(d.getDate()) + " " + pad(d.getHours()) + ":" + pad(d.getMinutes()) + ":" + pad(d.getSeconds()) + " " + d.getFullYear();\r
+var IRCLowerTable = [
+/* x00-x07 */ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
+/* x08-x0f */ '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
+/* x10-x17 */ '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
+/* x18-x1f */ '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
+/* ' '-x27 */ ' ', '!', '"', '#', '$', '%', '&', '\x27',
+/* '('-'/' */ '(', ')', '*', '+', ',', '-', '.', '/',
+/* '0'-'7' */ '0', '1', '2', '3', '4', '5', '6', '7',
+/* '8'-'?' */ '8', '9', ':', ';', '<', '=', '>', '?',
+/* '@'-'G' */ '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+/* 'H'-'O' */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+/* 'P'-'W' */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+/* 'X'-'_' */ 'x', 'y', 'z', '{', '|', '}', '~', '_',
+/* '`'-'g' */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+/* 'h'-'o' */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+/* 'p'-'w' */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+/* 'x'-x7f */ 'x', 'y', 'z', '{', '|', '}', '~', '\x7f',
+/* x80-x87 */ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',
+/* x88-x8f */ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f',
+/* x90-x97 */ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97',
+/* x98-x9f */ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f',
+/* xa0-xa7 */ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7',
+/* xa8-xaf */ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf',
+/* xb0-xb7 */ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7',
+/* xb8-xbf */ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf',
+/* xc0-xc7 */ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7',
+/* xc8-xcf */ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',
+/* xd0-xd7 */ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xd7',
+/* xd8-xdf */ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xdf',
+/* xe0-xe7 */ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7',
+/* xe8-xef */ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',
+/* xf0-xf7 */ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7',
+/* xf8-xff */ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff'
+];
+
+String.prototype.toIRCLower = function() {
+ var x = this;
+
+ var p = [];
+ for(var i=0;i<x.length;i++) {
+ var l = x.charCodeAt(i);
+
+ p.push(IRCLowerTable[l]);
+ }
+
+ return p.join("");
+}
+
+String.prototype.hostToNick = function() {
+ return this.split("!", 1)[0];
+}
+
+String.prototype.hostToHost = function() {
+ return this.split("!", 2)[1];
+}
+
+function IRCTimestamp(d) {
+ function pad(x) {
+ x = "" + x;
+ if(x.length == 1)
+ return "0" + x;
+ return x
+ }
+
+ return "[" + pad(d.getHours()) + ":" + pad(d.getMinutes()) + "]";
+}
+
+var DaysOfWeek = {
+ 0: "Sun",
+ 1: "Mon",
+ 2: "Tue",
+ 3: "Wed",
+ 4: "Thu",
+ 5: "Fri",
+ 6: "Sat"
+};
+
+var MonthsOfYear = {
+ 0: "Jan",
+ 1: "Feb",
+ 2: "Mar",
+ 3: "Apr",
+ 4: "May",
+ 5: "Jun",
+ 6: "Jul",
+ 7: "Aug",
+ 8: "Sep",
+ 9: "Oct",
+ 10: "Nov",
+ 11: "Dec"
+};
+
+function IRCDate(d) {
+ return DaysOfWeek[d.getDay()] + " " + MonthsOfYear[d.getMonth()] + " " + pad(d.getDate()) + " " + pad(d.getHours()) + ":" + pad(d.getMinutes()) + ":" + pad(d.getSeconds()) + " " + d.getFullYear();
}
\ No newline at end of file
-function NickChanEntry() {\r
- this.prefixes = "";\r
-}\r
-\r
-var IRCTracker = new Class({\r
- initialize: function() {\r
- this.channels = {};\r
- this.nicknames = {};\r
- },\r
- isEmpty: function(hash) {\r
- for(var x in hash)\r
- return false;\r
- return true;\r
- },\r
- getNick: function(nick) {\r
- return this.nicknames[nick];\r
- },\r
- getOrCreateNick: function(nick) {\r
- var n = this.getNick(nick);\r
- if(!n)\r
- n = this.nicknames[nick] = {};\r
- return n;\r
- },\r
- getChannel: function(channel) {\r
- return this.channels[channel];\r
- },\r
- getOrCreateChannel: function(channel) {\r
- var c = this.getChannel(channel);\r
- if(!c)\r
- c = this.channels[channel] = {};\r
- return c;\r
- },\r
- getOrCreateNickOnChannel: function(nick, channel) {\r
- var n = this.getNick(nick);\r
- \r
- var nc = n[channel];\r
- if(!nc)\r
- return this.addNickToChannel(nick, channel);\r
- \r
- return nc;\r
- },\r
- addNickToChannel: function(nick, channel) {\r
- var nc = new NickChanEntry();\r
-\r
- var n = this.getOrCreateNick(nick);\r
- n[channel] = nc;\r
- \r
- var c = this.getOrCreateChannel(channel);\r
- c[nick] = nc;\r
- \r
- return nc;\r
- },\r
- removeNick: function(nick) {\r
- var n = this.getNick(nick);\r
- if(!n)\r
- return;\r
- \r
- for(var channel in n) {\r
- var c = this.channels[channel];\r
- \r
- delete c[nick];\r
- if(this.isEmpty(c))\r
- delete this.channels[channel];\r
- }\r
- delete this.nicknames[nick];\r
- },\r
- removeChannel: function(channel) {\r
- var c = this.getChannel(channel);\r
- if(!c)\r
- return;\r
- \r
- for(var nick in c) {\r
- var n = this.nicknames[nick];\r
- \r
- delete n[channel];\r
- if(this.isEmpty(n))\r
- delete this.nicknames[nick];\r
- }\r
- delete this.channels[channel];\r
- },\r
- removeNickFromChannel: function(nick, channel) {\r
- var n = this.getNick(nick);\r
- var c = this.getChannel(channel);\r
- if(!n || !c)\r
- return;\r
- \r
- delete n[channel];\r
- delete c[nick];\r
- \r
- if(this.isEmpty(n))\r
- delete this.nicknames[nick];\r
- if(this.isEmpty(c))\r
- delete this.channels[channel];\r
- },\r
- renameNick: function(oldnick, newnick) {\r
- var n = this.getNick(oldnick);\r
- if(!n)\r
- return;\r
- \r
- for(var channel in n) {\r
- this.channels[channel][newnick] = this.channels[channel][oldnick];\r
- delete this.channels[channel][oldnick];\r
- } \r
- \r
- this.nicknames[newnick] = this.nicknames[oldnick];\r
- delete this.nicknames[oldnick];\r
- }\r
-});\r
+function NickChanEntry() {
+ this.prefixes = "";
+}
+
+var IRCTracker = new Class({
+ initialize: function() {
+ this.channels = {};
+ this.nicknames = {};
+ },
+ isEmpty: function(hash) {
+ for(var x in hash)
+ return false;
+ return true;
+ },
+ getNick: function(nick) {
+ return this.nicknames[nick];
+ },
+ getOrCreateNick: function(nick) {
+ var n = this.getNick(nick);
+ if(!n)
+ n = this.nicknames[nick] = {};
+ return n;
+ },
+ getChannel: function(channel) {
+ return this.channels[channel];
+ },
+ getOrCreateChannel: function(channel) {
+ var c = this.getChannel(channel);
+ if(!c)
+ c = this.channels[channel] = {};
+ return c;
+ },
+ getOrCreateNickOnChannel: function(nick, channel) {
+ var n = this.getNick(nick);
+
+ var nc = n[channel];
+ if(!nc)
+ return this.addNickToChannel(nick, channel);
+
+ return nc;
+ },
+ addNickToChannel: function(nick, channel) {
+ var nc = new NickChanEntry();
+
+ var n = this.getOrCreateNick(nick);
+ n[channel] = nc;
+
+ var c = this.getOrCreateChannel(channel);
+ c[nick] = nc;
+
+ return nc;
+ },
+ removeNick: function(nick) {
+ var n = this.getNick(nick);
+ if(!n)
+ return;
+
+ for(var channel in n) {
+ var c = this.channels[channel];
+
+ delete c[nick];
+ if(this.isEmpty(c))
+ delete this.channels[channel];
+ }
+ delete this.nicknames[nick];
+ },
+ removeChannel: function(channel) {
+ var c = this.getChannel(channel);
+ if(!c)
+ return;
+
+ for(var nick in c) {
+ var n = this.nicknames[nick];
+
+ delete n[channel];
+ if(this.isEmpty(n))
+ delete this.nicknames[nick];
+ }
+ delete this.channels[channel];
+ },
+ removeNickFromChannel: function(nick, channel) {
+ var n = this.getNick(nick);
+ var c = this.getChannel(channel);
+ if(!n || !c)
+ return;
+
+ delete n[channel];
+ delete c[nick];
+
+ if(this.isEmpty(n))
+ delete this.nicknames[nick];
+ if(this.isEmpty(c))
+ delete this.channels[channel];
+ },
+ renameNick: function(oldnick, newnick) {
+ var n = this.getNick(oldnick);
+ if(!n)
+ return;
+
+ for(var channel in n) {
+ this.channels[channel][newnick] = this.channels[channel][oldnick];
+ delete this.channels[channel][oldnick];
+ }
+
+ this.nicknames[newnick] = this.nicknames[oldnick];
+ delete this.nicknames[oldnick];
+ }
+});
-QWEBIRC_VERSION = "0.01";\r
+QWEBIRC_VERSION = "0.01";
-Array.prototype.indexFromEnd = function(d) {\r
- var p = this;\r
- \r
- if(d < 0)\r
- return p[p.length + d];\r
-\r
- return p[d];\r
-}\r
-\r
-/* how horribly inefficient */\r
-String.prototype.replaceAll = function(f, t) {\r
- var i = this.indexOf(f);\r
- var c = this;\r
- \r
- while(i > -1) {\r
- c = c.replace(f, t);\r
- i = c.indexOf(f);\r
- }\r
- return c;\r
-}\r
-\r
-/* how horribly inefficient (again) */\r
-String.prototype.splitMax = function(by, max) {\r
- var items = this.split(by);\r
- var newitems = items.slice(0, max-1);\r
-\r
- if(items.length >= max)\r
- newitems.push(items.slice(max-1).join(by));\r
- \r
- return newitems;\r
-}\r
+Array.prototype.indexFromEnd = function(d) {
+ var p = this;
+
+ if(d < 0)
+ return p[p.length + d];
+
+ return p[d];
+}
+
+/* how horribly inefficient */
+String.prototype.replaceAll = function(f, t) {
+ var i = this.indexOf(f);
+ var c = this;
+
+ while(i > -1) {
+ c = c.replace(f, t);
+ i = c.indexOf(f);
+ }
+ return c;
+}
+
+/* how horribly inefficient (again) */
+String.prototype.splitMax = function(by, max) {
+ var items = this.split(by);
+ var newitems = items.slice(0, max-1);
+
+ if(items.length >= max)
+ newitems.push(items.slice(max-1).join(by));
+
+ return newitems;
+}
-/* don't even attempt to use a $! */\r
-var DefaultTheme = {\r
- "PREFIX": ["$C4==$O "],\r
- "SIGNON": ["Signed on!", true],\r
- "CONNECT": ["Connected to server.", true],\r
- "RAW": ["$m", true],\r
- "DISCONNECT": ["Disconnected from server.", true],\r
- "ERROR": ["ERROR: $m", true],\r
- "SERVERNOTICE": ["$m", true],\r
- "JOIN": ["$n [$h] has joined $c", true],\r
- "PART": ["$n [$h] has left $c [$m]", true],\r
- "KICK": ["$v was kicked from $c by $n [$m]", true],\r
- "MODE": ["mode/$c [$m] by $n", true],\r
- "QUIT": ["$n [$h] has quit [$m]", true],\r
- "NICK": ["$n has changed nick to $w", true],\r
- "TOPIC": ["$n changed the topic of $c to: $m", true],\r
- "UMODE": ["MODE $n $m", true],\r
- "INVITE": ["$n invites you to join $c", true],\r
- "CHANMSG": ["<$n> $m"],\r
- "PRIVMSG": ["<$n> $m"],\r
- "CHANNOTICE": ["-$n:$c- $m"],\r
- "PRIVNOTICE": ["-$n- $m"],\r
- "OURCHANMSG": ["<$n> $m"],\r
- "OURPRIVMSG": ["<$n> $m"],\r
- "OURTARGETEDMSG": ["*$t* $m"],\r
- "OURTARGETEDNOTICE": ["[notice($t)] $m"],\r
- "OURCHANNOTICE": ["-$n:$t- $m"],\r
- "OURPRIVNOTICE": ["-$n- $m"],\r
- "OURCHANACTION": [" * $n $m"],\r
- "OURPRIVACTION": [" * $n $m"],\r
- "CHANACTION": [" * $n $m"],\r
- "PRIVACTION": [" * $n $m"],\r
- "CHANCTCP": ["$n [$h] requested CTCP $x from $c: $m"],\r
- "PRIVCTCP": ["$n [$h] requested CTCP $x from $-: $m"],\r
- "CTCPREPLY": ["CTCP $x reply from $n: $m"],\r
- "OURCHANCTCP": ["[ctcp($t)] $x $m"],\r
- "OURPRIVCTCP": ["[ctcp($t)] $x $m"],\r
- "OURTARGETEDCTCP": ["[ctcp($t)] $x $m"]\r
-}\r
+/* don't even attempt to use a $! */
+var DefaultTheme = {
+ "PREFIX": ["$C4==$O "],
+ "SIGNON": ["Signed on!", true],
+ "CONNECT": ["Connected to server.", true],
+ "RAW": ["$m", true],
+ "DISCONNECT": ["Disconnected from server.", true],
+ "ERROR": ["ERROR: $m", true],
+ "SERVERNOTICE": ["$m", true],
+ "JOIN": ["$n [$h] has joined $c", true],
+ "PART": ["$n [$h] has left $c [$m]", true],
+ "KICK": ["$v was kicked from $c by $n [$m]", true],
+ "MODE": ["mode/$c [$m] by $n", true],
+ "QUIT": ["$n [$h] has quit [$m]", true],
+ "NICK": ["$n has changed nick to $w", true],
+ "TOPIC": ["$n changed the topic of $c to: $m", true],
+ "UMODE": ["MODE $n $m", true],
+ "INVITE": ["$n invites you to join $c", true],
+ "CHANMSG": ["<$n> $m"],
+ "PRIVMSG": ["<$n> $m"],
+ "CHANNOTICE": ["-$n:$c- $m"],
+ "PRIVNOTICE": ["-$n- $m"],
+ "OURCHANMSG": ["<$n> $m"],
+ "OURPRIVMSG": ["<$n> $m"],
+ "OURTARGETEDMSG": ["*$t* $m"],
+ "OURTARGETEDNOTICE": ["[notice($t)] $m"],
+ "OURCHANNOTICE": ["-$n:$t- $m"],
+ "OURPRIVNOTICE": ["-$n- $m"],
+ "OURCHANACTION": [" * $n $m"],
+ "OURPRIVACTION": [" * $n $m"],
+ "CHANACTION": [" * $n $m"],
+ "PRIVACTION": [" * $n $m"],
+ "CHANCTCP": ["$n [$h] requested CTCP $x from $c: $m"],
+ "PRIVCTCP": ["$n [$h] requested CTCP $x from $-: $m"],
+ "CTCPREPLY": ["CTCP $x reply from $n: $m"],
+ "OURCHANCTCP": ["[ctcp($t)] $x $m"],
+ "OURPRIVCTCP": ["[ctcp($t)] $x $m"],
+ "OURTARGETEDCTCP": ["[ctcp($t)] $x $m"]
+}
-WINDOW_STATUS = 1;\r
-WINDOW_QUERY = 2;\r
-WINDOW_CHANNEL = 3;\r
-\r
-var UIWindow = new Class({\r
- Implements: [Events],\r
- initialize: function(parentObject, client, type, name, identifier) {\r
- this.parentObject = parentObject;\r
- this.type = type;\r
- this.name = name;\r
- this.active = false;\r
- this.client = client;\r
- this.identifier = identifier;\r
- },\r
- updateNickList: function(nicks) {\r
- },\r
- updateTopic: function(topic) {\r
- },\r
- close: function() {\r
- this.parentObject.__closed(this);\r
- this.fireEvent("close", this);\r
- },\r
- select: function() {\r
- this.active = true;\r
- this.parentObject.__setActiveWindow(this);\r
- },\r
- deselect: function() {\r
- this.active = false;\r
- },\r
- addLine: function(type, line, colour) {\r
- },\r
- errorMessage: function(message) {\r
- this.addLine("", message, "red");\r
- }\r
-});\r
-\r
-var UI = new Class({\r
- initialize: function(parentElement, windowClass, uiName) {\r
- this.windows = {};\r
- this.windowArray = [];\r
- this.windowClass = windowClass;\r
- this.parentElement = parentElement;\r
- this.parentElement.addClass("qwebirc");\r
- this.parentElement.addClass("qwebirc-" + uiName);\r
- },\r
- newClient: function(client) {\r
- this.windows[client] = {}\r
- var w = this.newWindow(client, WINDOW_STATUS, "Status");\r
- this.selectWindow(w);\r
- \r
- return w;\r
- },\r
- newWindow: function(client, type, name) {\r
- var identifier = name;\r
- if(type == WINDOW_STATUS)\r
- identifier = "";\r
- \r
- var w = this.windows[client][identifier] = new this.windowClass(this, client, type, name, identifier);\r
- this.windowArray.push(w);\r
- \r
- return w;\r
- },\r
- getActiveWindow: function() {\r
- return this.active;\r
- },\r
- __setActiveWindow: function(window) {\r
- this.active = window;\r
- },\r
- selectWindow: function(window) {\r
- if(this.active)\r
- this.active.deselect();\r
- window.select(); /* calls setActiveWindow */\r
- },\r
- __closed: function(window) {\r
- if(window.active) {\r
- this.active = undefined;\r
- if(this.windowArray.length == 1) {\r
- this.windowArray = [];\r
- } else {\r
- var index = this.windowArray.indexOf(window);\r
- if(index == 0) {\r
- this.selectWindow(this.windowArray[1]);\r
- } else {\r
- this.selectWindow(this.windowArray[index - 1]);\r
- }\r
- \r
- this.windowArray = this.windowArray.erase(window);\r
- }\r
- }\r
- \r
- delete this.windows[window.client][window.identifier];\r
- }\r
-});\r
+WINDOW_STATUS = 1;
+WINDOW_QUERY = 2;
+WINDOW_CHANNEL = 3;
+
+var UIWindow = new Class({
+ Implements: [Events],
+ initialize: function(parentObject, client, type, name, identifier) {
+ this.parentObject = parentObject;
+ this.type = type;
+ this.name = name;
+ this.active = false;
+ this.client = client;
+ this.identifier = identifier;
+ },
+ updateNickList: function(nicks) {
+ },
+ updateTopic: function(topic) {
+ },
+ close: function() {
+ this.parentObject.__closed(this);
+ this.fireEvent("close", this);
+ },
+ select: function() {
+ this.active = true;
+ this.parentObject.__setActiveWindow(this);
+ },
+ deselect: function() {
+ this.active = false;
+ },
+ addLine: function(type, line, colour) {
+ },
+ errorMessage: function(message) {
+ this.addLine("", message, "red");
+ }
+});
+
+var UI = new Class({
+ initialize: function(parentElement, windowClass, uiName) {
+ this.windows = {};
+ this.windowArray = [];
+ this.windowClass = windowClass;
+ this.parentElement = parentElement;
+ this.parentElement.addClass("qwebirc");
+ this.parentElement.addClass("qwebirc-" + uiName);
+ },
+ newClient: function(client) {
+ this.windows[client] = {}
+ var w = this.newWindow(client, WINDOW_STATUS, "Status");
+ this.selectWindow(w);
+
+ return w;
+ },
+ newWindow: function(client, type, name) {
+ var identifier = name;
+ if(type == WINDOW_STATUS)
+ identifier = "";
+
+ var w = this.windows[client][identifier] = new this.windowClass(this, client, type, name, identifier);
+ this.windowArray.push(w);
+
+ return w;
+ },
+ getActiveWindow: function() {
+ return this.active;
+ },
+ __setActiveWindow: function(window) {
+ this.active = window;
+ },
+ selectWindow: function(window) {
+ if(this.active)
+ this.active.deselect();
+ window.select(); /* calls setActiveWindow */
+ },
+ __closed: function(window) {
+ if(window.active) {
+ this.active = undefined;
+ if(this.windowArray.length == 1) {
+ this.windowArray = [];
+ } else {
+ var index = this.windowArray.indexOf(window);
+ if(index == 0) {
+ this.selectWindow(this.windowArray[1]);
+ } else {
+ this.selectWindow(this.windowArray[index - 1]);
+ }
+
+ this.windowArray = this.windowArray.erase(window);
+ }
+ }
+
+ delete this.windows[window.client][window.identifier];
+ }
+});
-function Colourise(line, entity) {\r
- var fg;\r
- var bg;\r
- var underline = false;\r
- var bold = false;\r
-\r
- var out = [];\r
- var xline = line.split("");\r
- var element = document.createElement("span");\r
-\r
- entity.addClass("colourline");\r
- \r
- function isNum(x) {\r
- return x >= '0' && x <= '9';\r
- }\r
-\r
- function parseColours(xline, i) {\r
- if(!isNum(xline[i + 1])) {\r
- fg = undefined;\r
- bg = undefined;\r
- return i;\r
- }\r
- i++;\r
- if(isNum(xline[i + 1])) {\r
- fg = parseInt(xline[i] + xline[i + 1]);\r
- i++;\r
- } else {\r
- fg = parseInt(xline[i]);\r
- }\r
- if(xline[i + 1] != ",")\r
- return i;\r
- if(!isNum(xline[i + 2]))\r
- return i;\r
- i+=2;\r
- \r
- if(isNum(xline[i + 1])) {\r
- bg = parseInt(xline[i] + xline[i + 1]);\r
- i++;\r
- } else {\r
- bg = parseInt(xline[i]);\r
- }\r
- return i;\r
- }\r
-\r
- function emitEndToken() {\r
- if(out.length > 0) {\r
- element.appendChild(document.createTextNode(out.join("")));\r
- entity.appendChild(element);\r
- out = [];\r
- }\r
- element = document.createElement("span");\r
- } \r
- function emitStartToken() {\r
- classes = []\r
- if(fg != undefined)\r
- classes.push("Xc" + fg);\r
- if(bg != undefined)\r
- classes.push("Xbc" + bg);\r
- if(bold)\r
- classes.push("Xb");\r
- if(underline)\r
- classes.push("Xu");\r
- element.className = classes.join(" ");\r
- }\r
- \r
- for(i=0;i<xline.length;i++) {\r
- var lc = xline[i];\r
- if(lc == "\x02") {\r
- emitEndToken();\r
-\r
- bold = !bold;\r
- \r
- emitStartToken();\r
- } else if(lc == "\x1F") {\r
- emitEndToken();\r
-\r
- underline = !underline;\r
- \r
- emitStartToken();\r
- } else if(lc == "\x0F") {\r
- emitEndToken();\r
- \r
- fg = undefined;\r
- bg = undefined;\r
- underline = false;\r
- bold = false;\r
- } else if(lc == "\x03") {\r
- emitEndToken();\r
- \r
- i = parseColours(xline, i);\r
- if(bg > 15)\r
- bg = undefined;\r
- if(fg > 15)\r
- fg = undefined;\r
- \r
- emitStartToken();\r
- } else {\r
- out.push(lc);\r
- }\r
- }\r
- \r
- emitEndToken();\r
+function Colourise(line, entity) {
+ var fg;
+ var bg;
+ var underline = false;
+ var bold = false;
+
+ var out = [];
+ var xline = line.split("");
+ var element = document.createElement("span");
+
+ entity.addClass("colourline");
+
+ function isNum(x) {
+ return x >= '0' && x <= '9';
+ }
+
+ function parseColours(xline, i) {
+ if(!isNum(xline[i + 1])) {
+ fg = undefined;
+ bg = undefined;
+ return i;
+ }
+ i++;
+ if(isNum(xline[i + 1])) {
+ fg = parseInt(xline[i] + xline[i + 1]);
+ i++;
+ } else {
+ fg = parseInt(xline[i]);
+ }
+ if(xline[i + 1] != ",")
+ return i;
+ if(!isNum(xline[i + 2]))
+ return i;
+ i+=2;
+
+ if(isNum(xline[i + 1])) {
+ bg = parseInt(xline[i] + xline[i + 1]);
+ i++;
+ } else {
+ bg = parseInt(xline[i]);
+ }
+ return i;
+ }
+
+ function emitEndToken() {
+ if(out.length > 0) {
+ element.appendChild(document.createTextNode(out.join("")));
+ entity.appendChild(element);
+ out = [];
+ }
+ element = document.createElement("span");
+ }
+ function emitStartToken() {
+ classes = []
+ if(fg != undefined)
+ classes.push("Xc" + fg);
+ if(bg != undefined)
+ classes.push("Xbc" + bg);
+ if(bold)
+ classes.push("Xb");
+ if(underline)
+ classes.push("Xu");
+ element.className = classes.join(" ");
+ }
+
+ for(i=0;i<xline.length;i++) {
+ var lc = xline[i];
+ if(lc == "\x02") {
+ emitEndToken();
+
+ bold = !bold;
+
+ emitStartToken();
+ } else if(lc == "\x1F") {
+ emitEndToken();
+
+ underline = !underline;
+
+ emitStartToken();
+ } else if(lc == "\x0F") {
+ emitEndToken();
+
+ fg = undefined;
+ bg = undefined;
+ underline = false;
+ bold = false;
+ } else if(lc == "\x03") {
+ emitEndToken();
+
+ i = parseColours(xline, i);
+ if(bg > 15)
+ bg = undefined;
+ if(fg > 15)
+ fg = undefined;
+
+ emitStartToken();
+ } else {
+ out.push(lc);
+ }
+ }
+
+ emitEndToken();
}
\ No newline at end of file
-var SWM_ANCHOR_NONE = 0x00;\r
-var SWM_ANCHOR_TOP = 0x01;\r
-var SWM_ANCHOR_BOTTOM = 0x02;\r
-var SWM_ANCHOR_LEFT = 0x04;\r
-var SWM_ANCHOR_RIGHT = 0x08;\r
-\r
-var SWMPanel = new Class({\r
- initialize: function(parent, hidden) {\r
- this.parent = parent;\r
- \r
- var element = new Element("div", {"styles": { "position": "absolute" } });\r
- this.element = element;\r
- this.element.wmpanel = this;\r
- \r
- if(hidden) {\r
- this.setHidden(true);\r
- } else {\r
- this.hidden = false;\r
- }\r
- parent.addClass("swmelement");\r
- \r
- parent.appendChild(this.element);\r
- this.anchor = SWM_ANCHOR_NONE;\r
- },\r
- setHeight: function(height) {\r
- this.height = height;\r
- },\r
- setWidth: function(width) {\r
- this.width = width;\r
- },\r
- setHidden: function(value) {\r
- this.hidden = value;\r
- if(value) {\r
- this.element.setStyle("display", "none");\r
- } else {\r
- this.element.setStyle("display", "block");\r
- }\r
- }\r
-});\r
-\r
-window.addEvent("domready", function() {\r
- function reworkLayout(container) {\r
- function anchorFilter(x, anchor) {\r
- return x.filter(function(y) {\r
- if(y.anchor == anchor)\r
- return true;\r
- });\r
- }\r
- var x = container.getChildren().map(function(x) {\r
- return x.wmpanel\r
- });\r
- var top = anchorFilter(x, SWM_ANCHOR_TOP);\r
- var bottom = anchorFilter(x, SWM_ANCHOR_BOTTOM);\r
- var none = anchorFilter(x, SWM_ANCHOR_NONE);\r
-\r
- var left = anchorFilter(x, SWM_ANCHOR_LEFT);\r
- var right = anchorFilter(x, SWM_ANCHOR_RIGHT);\r
- \r
- var tpos = 0;\r
- for(var i=0;i<top.length;i++) {\r
- if(top[i].hidden)\r
- continue;\r
- var obj = top[i].element;\r
- obj.setStyles({"top": tpos + "px", "left": "0px", "right": "0px"});\r
- tpos = tpos + obj.getSize().y;\r
- }\r
- \r
- var bpos = 0;\r
- for(var i=0;i<bottom.length;i++) {\r
- if(bottom[i].hidden)\r
- continue;\r
- var obj = bottom[i].element;\r
- obj.setStyles({"bottom": bpos + "px", "left": "0px", "right": "0px"});\r
- bpos = bpos + obj.getSize().y;\r
- }\r
- \r
- var lpos = 0;\r
- for(var i=0;i<left.length;i++) {\r
- if(left[i].hidden)\r
- continue;\r
- var obj = left[i].element;\r
- obj.setStyles({"left": lpos + "px", "top": tpos + "px", "bottom": bpos + "px"});\r
- lpos = lpos + obj.getSize().x;\r
- }\r
-\r
- var rpos = 0;\r
- for(var i=0;i<right.length;i++) {\r
- if(right[i].hidden)\r
- continue;\r
- var obj = right[i].element;\r
- obj.setStyles({"right": rpos + "px", "top": tpos + "px", "bottom": bpos + "px"});\r
- rpos = rpos + obj.getSize().x;\r
- }\r
-\r
- for(var i=0;i<none.length;i++) {\r
- if(none[i].hidden)\r
- continue;\r
- var obj = none[i].element;\r
- obj.setStyles({"left": lpos + "px", "right": rpos + "px", "top": tpos + "px", "bottom": bpos + "px"});\r
- }\r
- }\r
- \r
- window.addEvent("resize", function() {\r
- $$("div.swmelement").each(reworkLayout);\r
- });\r
+var SWM_ANCHOR_NONE = 0x00;
+var SWM_ANCHOR_TOP = 0x01;
+var SWM_ANCHOR_BOTTOM = 0x02;
+var SWM_ANCHOR_LEFT = 0x04;
+var SWM_ANCHOR_RIGHT = 0x08;
+
+var SWMPanel = new Class({
+ initialize: function(parent, hidden) {
+ this.parent = parent;
+
+ var element = new Element("div", {"styles": { "position": "absolute" } });
+ this.element = element;
+ this.element.wmpanel = this;
+
+ if(hidden) {
+ this.setHidden(true);
+ } else {
+ this.hidden = false;
+ }
+ parent.addClass("swmelement");
+
+ parent.appendChild(this.element);
+ this.anchor = SWM_ANCHOR_NONE;
+ },
+ setHeight: function(height) {
+ this.height = height;
+ },
+ setWidth: function(width) {
+ this.width = width;
+ },
+ setHidden: function(value) {
+ this.hidden = value;
+ if(value) {
+ this.element.setStyle("display", "none");
+ } else {
+ this.element.setStyle("display", "block");
+ }
+ }
+});
+
+window.addEvent("domready", function() {
+ function reworkLayout(container) {
+ function anchorFilter(x, anchor) {
+ return x.filter(function(y) {
+ if(y.anchor == anchor)
+ return true;
+ });
+ }
+ var x = container.getChildren().map(function(x) {
+ return x.wmpanel
+ });
+ var top = anchorFilter(x, SWM_ANCHOR_TOP);
+ var bottom = anchorFilter(x, SWM_ANCHOR_BOTTOM);
+ var none = anchorFilter(x, SWM_ANCHOR_NONE);
+
+ var left = anchorFilter(x, SWM_ANCHOR_LEFT);
+ var right = anchorFilter(x, SWM_ANCHOR_RIGHT);
+
+ var tpos = 0;
+ for(var i=0;i<top.length;i++) {
+ if(top[i].hidden)
+ continue;
+ var obj = top[i].element;
+ obj.setStyles({"top": tpos + "px", "left": "0px", "right": "0px"});
+ tpos = tpos + obj.getSize().y;
+ }
+
+ var bpos = 0;
+ for(var i=0;i<bottom.length;i++) {
+ if(bottom[i].hidden)
+ continue;
+ var obj = bottom[i].element;
+ obj.setStyles({"bottom": bpos + "px", "left": "0px", "right": "0px"});
+ bpos = bpos + obj.getSize().y;
+ }
+
+ var lpos = 0;
+ for(var i=0;i<left.length;i++) {
+ if(left[i].hidden)
+ continue;
+ var obj = left[i].element;
+ obj.setStyles({"left": lpos + "px", "top": tpos + "px", "bottom": bpos + "px"});
+ lpos = lpos + obj.getSize().x;
+ }
+
+ var rpos = 0;
+ for(var i=0;i<right.length;i++) {
+ if(right[i].hidden)
+ continue;
+ var obj = right[i].element;
+ obj.setStyles({"right": rpos + "px", "top": tpos + "px", "bottom": bpos + "px"});
+ rpos = rpos + obj.getSize().x;
+ }
+
+ for(var i=0;i<none.length;i++) {
+ if(none[i].hidden)
+ continue;
+ var obj = none[i].element;
+ obj.setStyles({"left": lpos + "px", "right": rpos + "px", "top": tpos + "px", "bottom": bpos + "px"});
+ }
+ }
+
+ window.addEvent("resize", function() {
+ $$("div.swmelement").each(reworkLayout);
+ });
});
\ No newline at end of file
-var SWMUIWindow = new Class({\r
- Extends: UIWindow,\r
- \r
- initialize: function(parentObject, client, type, name) {\r
- this.parent(parentObject, client, type, name);\r
- this.contentPanel = new SWMPanel(parentObject.mainPanel.element, true);\r
- this.contentPanel.element.addClass("content");\r
- this.contentPanel.element.setStyle("overflow", "auto");\r
-\r
- if(type == WINDOW_CHANNEL) {\r
- this.nickList = new SWMPanel(this.contentPanel.element);\r
- this.nickList.anchor = SWM_ANCHOR_RIGHT;\r
- this.nickList.element.setStyle("overflow", "auto");\r
- this.nickList.element.addClass("nicklist");\r
- }\r
-\r
- if(type == WINDOW_CHANNEL) {\r
- this.topic = new SWMPanel(this.contentPanel.element);\r
- this.topic.anchor = SWM_ANCHOR_TOP;\r
- this.topic.element.addClass("topic");\r
- }\r
- \r
- this.lines = new SWMPanel(this.contentPanel.element);\r
- this.lines.element.setStyle("overflow", "auto");\r
- \r
- this.tab = new Element("span");\r
- this.tab.addClass("tab");\r
- \r
- this.tab.appendText(name);\r
- this.tab.addEvent("click", function() {\r
- parentObject.selectWindow(this);\r
- }.bind(this));\r
-\r
- parentObject.tabPanel.element.appendChild(this.tab);\r
- parentObject.resize();\r
- \r
- if(type != WINDOW_STATUS) {\r
- tabclose = new Element("span");\r
- tabclose.addClass("tabclose");\r
- tabclose.addEvent("click", function(e) {\r
- new Event(e).stop();\r
- \r
- if(type == WINDOW_CHANNEL)\r
- this.client.exec("/PART " + name);\r
-\r
- this.close();\r
- }.bind(this));\r
- tabclose.set("text", "X");\r
- this.tab.appendChild(tabclose);\r
- }\r
- },\r
- updateNickList: function(nicks) {\r
- this.parent(nicks);\r
-\r
- var n = this.nickList.element;\r
- while(n.firstChild)\r
- n.removeChild(n.firstChild);\r
-\r
- nicks.each(function(nick) {\r
- var e = new Element("div");\r
- n.appendChild(e);\r
- e.appendChild(document.createTextNode(nick));\r
- });\r
- \r
- this.parentObject.resize();\r
- },\r
- updateTopic: function(topic) {\r
- this.parent(topic);\r
- var t = this.topic.element;\r
- \r
- while(t.firstChild)\r
- t.removeChild(t.firstChild);\r
-\r
- Colourise(topic, t);\r
-\r
- this.parentObject.resize();\r
- },\r
- select: function() {\r
- this.parent();\r
-\r
- this.contentPanel.setHidden(false);\r
- this.parentObject.resize();\r
- this.tab.removeClass("tab-highlighted");\r
- this.tab.removeClass("tab-unselected");\r
- this.tab.addClass("tab-selected");\r
- },\r
- deselect: function() {\r
- this.parent();\r
-\r
- this.contentPanel.setHidden(true);\r
- this.parentObject.resize();\r
- this.tab.removeClass("tab-selected");\r
- this.tab.addClass("tab-unselected");\r
- },\r
- close: function() {\r
- this.parent();\r
-\r
- this.parentObject.mainPanel.element.removeChild(this.contentPanel.element);\r
- this.parentObject.tabPanel.element.removeChild(this.tab);\r
- },\r
- addLine: function(type, line, colour) {\r
- this.parent(type, line, colour);\r
- \r
- var e = new Element("div");\r
-\r
- if(colour) {\r
- e.addStyle("background", colour);\r
- } else if(this.lastcolour) {\r
- e.addClass("linestyle1");\r
- } else {\r
- e.addClass("linestyle2");\r
- }\r
- \r
- if(type)\r
- line = this.parentObject.theme.message(type, line);\r
- \r
- Colourise(IRCTimestamp(new Date()) + " " + line, e);\r
- \r
- this.lastcolour = !this.lastcolour;\r
- \r
- var prev = this.lines.element.getScroll();\r
- var prevbottom = this.lines.element.getScrollSize().y;\r
- var prevsize = this.lines.element.getSize();\r
- this.lines.element.appendChild(e);\r
- \r
- if(prev.y + prevsize.y == prevbottom)\r
- this.lines.element.scrollTo(prev.x, this.lines.element.getScrollSize().y);\r
- \r
- if(!this.active)\r
- this.tab.addClass("tab-highlighted");\r
- }\r
-});\r
-\r
-var SWMUI = new Class({\r
- Extends: UI,\r
- initialize: function(parentElement, theme) {\r
- this.parent(parentElement, SWMUIWindow, "swmui");\r
- this.theme = theme;\r
- \r
- this.tabPanel = new SWMPanel(parentElement);\r
- this.tabPanel.anchor = SWM_ANCHOR_TOP;\r
- this.tabPanel.element.addClass("tabs");\r
- \r
- this.mainPanel = new SWMPanel(parentElement);\r
- this.mainPanel.element.addClass("main");\r
- \r
- this.entryPanel = new SWMPanel(parentElement);\r
- this.entryPanel.anchor = SWM_ANCHOR_BOTTOM;\r
- this.entryPanel.element.addClass("entry");\r
-\r
- var form = new Element("form");\r
- \r
- var inputbox = new Element("input");\r
- \r
- window.addEvent("resize", function() {\r
- var s = this.entryPanel.element.getSize().x - 4;\r
- inputbox.setStyle("width", s + "px");\r
- }.bind(this));\r
-\r
- form.addEvent("submit", function(e) {\r
- new Event(e).stop();\r
- \r
- this.getActiveWindow().client.exec(inputbox.value);\r
- inputbox.value = "";\r
- }.bind(this));\r
-\r
- this.entryPanel.element.appendChild(form);\r
- form.appendChild(inputbox);\r
- inputbox.focus();\r
-\r
- this.resize();\r
- },\r
- resize: function() {\r
- window.fireEvent("resize");\r
- }\r
-});\r
+var SWMUIWindow = new Class({
+ Extends: UIWindow,
+
+ initialize: function(parentObject, client, type, name) {
+ this.parent(parentObject, client, type, name);
+ this.contentPanel = new SWMPanel(parentObject.mainPanel.element, true);
+ this.contentPanel.element.addClass("content");
+ this.contentPanel.element.setStyle("overflow", "auto");
+
+ if(type == WINDOW_CHANNEL) {
+ this.nickList = new SWMPanel(this.contentPanel.element);
+ this.nickList.anchor = SWM_ANCHOR_RIGHT;
+ this.nickList.element.setStyle("overflow", "auto");
+ this.nickList.element.addClass("nicklist");
+ }
+
+ if(type == WINDOW_CHANNEL) {
+ this.topic = new SWMPanel(this.contentPanel.element);
+ this.topic.anchor = SWM_ANCHOR_TOP;
+ this.topic.element.addClass("topic");
+ }
+
+ this.lines = new SWMPanel(this.contentPanel.element);
+ this.lines.element.setStyle("overflow", "auto");
+
+ this.tab = new Element("span");
+ this.tab.addClass("tab");
+
+ this.tab.appendText(name);
+ this.tab.addEvent("click", function() {
+ parentObject.selectWindow(this);
+ }.bind(this));
+
+ parentObject.tabPanel.element.appendChild(this.tab);
+ parentObject.resize();
+
+ if(type != WINDOW_STATUS) {
+ tabclose = new Element("span");
+ tabclose.addClass("tabclose");
+ tabclose.addEvent("click", function(e) {
+ new Event(e).stop();
+
+ if(type == WINDOW_CHANNEL)
+ this.client.exec("/PART " + name);
+
+ this.close();
+ }.bind(this));
+ tabclose.set("text", "X");
+ this.tab.appendChild(tabclose);
+ }
+ },
+ updateNickList: function(nicks) {
+ this.parent(nicks);
+
+ var n = this.nickList.element;
+ while(n.firstChild)
+ n.removeChild(n.firstChild);
+
+ nicks.each(function(nick) {
+ var e = new Element("div");
+ n.appendChild(e);
+ e.appendChild(document.createTextNode(nick));
+ });
+
+ this.parentObject.resize();
+ },
+ updateTopic: function(topic) {
+ this.parent(topic);
+ var t = this.topic.element;
+
+ while(t.firstChild)
+ t.removeChild(t.firstChild);
+
+ Colourise(topic, t);
+
+ this.parentObject.resize();
+ },
+ select: function() {
+ this.parent();
+
+ this.contentPanel.setHidden(false);
+ this.parentObject.resize();
+ this.tab.removeClass("tab-highlighted");
+ this.tab.removeClass("tab-unselected");
+ this.tab.addClass("tab-selected");
+ },
+ deselect: function() {
+ this.parent();
+
+ this.contentPanel.setHidden(true);
+ this.parentObject.resize();
+ this.tab.removeClass("tab-selected");
+ this.tab.addClass("tab-unselected");
+ },
+ close: function() {
+ this.parent();
+
+ this.parentObject.mainPanel.element.removeChild(this.contentPanel.element);
+ this.parentObject.tabPanel.element.removeChild(this.tab);
+ },
+ addLine: function(type, line, colour) {
+ this.parent(type, line, colour);
+
+ var e = new Element("div");
+
+ if(colour) {
+ e.addStyle("background", colour);
+ } else if(this.lastcolour) {
+ e.addClass("linestyle1");
+ } else {
+ e.addClass("linestyle2");
+ }
+
+ if(type)
+ line = this.parentObject.theme.message(type, line);
+
+ Colourise(IRCTimestamp(new Date()) + " " + line, e);
+
+ this.lastcolour = !this.lastcolour;
+
+ var prev = this.lines.element.getScroll();
+ var prevbottom = this.lines.element.getScrollSize().y;
+ var prevsize = this.lines.element.getSize();
+ this.lines.element.appendChild(e);
+
+ if(prev.y + prevsize.y == prevbottom)
+ this.lines.element.scrollTo(prev.x, this.lines.element.getScrollSize().y);
+
+ if(!this.active)
+ this.tab.addClass("tab-highlighted");
+ }
+});
+
+var SWMUI = new Class({
+ Extends: UI,
+ initialize: function(parentElement, theme) {
+ this.parent(parentElement, SWMUIWindow, "swmui");
+ this.theme = theme;
+
+ this.tabPanel = new SWMPanel(parentElement);
+ this.tabPanel.anchor = SWM_ANCHOR_TOP;
+ this.tabPanel.element.addClass("tabs");
+
+ this.mainPanel = new SWMPanel(parentElement);
+ this.mainPanel.element.addClass("main");
+
+ this.entryPanel = new SWMPanel(parentElement);
+ this.entryPanel.anchor = SWM_ANCHOR_BOTTOM;
+ this.entryPanel.element.addClass("entry");
+
+ var form = new Element("form");
+
+ var inputbox = new Element("input");
+
+ window.addEvent("resize", function() {
+ var s = this.entryPanel.element.getSize().x - 4;
+ inputbox.setStyle("width", s + "px");
+ }.bind(this));
+
+ form.addEvent("submit", function(e) {
+ new Event(e).stop();
+
+ this.getActiveWindow().client.exec(inputbox.value);
+ inputbox.value = "";
+ }.bind(this));
+
+ this.entryPanel.element.appendChild(form);
+ form.appendChild(inputbox);
+ inputbox.focus();
+
+ this.resize();
+ },
+ resize: function() {
+ window.fireEvent("resize");
+ }
+});
-var ThemeControlCodeMap = {\r
- "C": "\x03",\r
- "B": "\x02",\r
- "U": "\x1F",\r
- "O": "\x0F",\r
- "$": "$"\r
-};\r
-\r
-var DefaultTheme = {\r
- "PREFIX": ["$C4==$O "],\r
- "SIGNON": ["Signed on!", true],\r
- "CONNECT": ["Connected to server.", true],\r
- "RAW": ["$m", true],\r
- "DISCONNECT": ["Disconnected from server.", true],\r
- "ERROR": ["ERROR: $m", true],\r
- "SERVERNOTICE": ["$m", true],\r
- "JOIN": ["$n [$h] has joined $c", true],\r
- "PART": ["$n [$h] has left $c [$m]", true],\r
- "KICK": ["$v was kicked from $c by $n [$m]", true],\r
- "MODE": ["mode/$c [$m] by $n", true],\r
- "QUIT": ["$n [$h] has quit [$m]", true],\r
- "NICK": ["$n has changed nick to $w", true],\r
- "TOPIC": ["$n changed the topic of $c to: $m", true],\r
- "UMODE": ["MODE $n $m", true],\r
- "INVITE": ["$n invites you to join $c", true],\r
- "CHANMSG": ["<$n> $m"],\r
- "PRIVMSG": ["<$n> $m"],\r
- "CHANNOTICE": ["-$n:$c- $m"],\r
- "PRIVNOTICE": ["-$n- $m"],\r
- "OURCHANMSG": ["<$n> $m"],\r
- "OURPRIVMSG": ["<$n> $m"],\r
- "OURTARGETEDMSG": ["*$t* $m"],\r
- "OURTARGETEDNOTICE": ["[notice($t)] $m"],\r
- "OURCHANNOTICE": ["-$n:$t- $m"],\r
- "OURPRIVNOTICE": ["-$n- $m"],\r
- "OURCHANACTION": [" * $n $m"],\r
- "OURPRIVACTION": [" * $n $m"],\r
- "CHANACTION": [" * $n $m"],\r
- "PRIVACTION": [" * $n $m"],\r
- "CHANCTCP": ["$n [$h] requested CTCP $x from $c: $m"],\r
- "PRIVCTCP": ["$n [$h] requested CTCP $x from $-: $m"],\r
- "CTCPREPLY": ["CTCP $x reply from $n: $m"],\r
- "OURCHANCTCP": ["[ctcp($t)] $x $m"],\r
- "OURPRIVCTCP": ["[ctcp($t)] $x $m"],\r
- "OURTARGETEDCTCP": ["[ctcp($t)] $x $m"]\r
-};\r
-\r
-var Theme = new Class({\r
- initialize: function(themeDict) {\r
- this.__theme = {};\r
- \r
- for(var k in DefaultTheme)\r
- this.__theme[k] = DefaultTheme[k];\r
- \r
- if(themeDict)\r
- for(var k in themeDict)\r
- this.__theme[k] = themeDict[k];\r
-\r
- for(var k in this.__theme) {\r
- if(k == "PREFIX")\r
- continue;\r
-\r
- var data = this.__theme[k];\r
- if(data[1]) {\r
- this.__theme[k] = this.__theme["PREFIX"] + data[0];\r
- } else {\r
- this.__theme[k] = data[0];\r
- }\r
- }\r
- },\r
- __dollarSubstitute: function(x, h) {\r
- var msg = [];\r
-\r
- var n = x.split("");\r
- for(var i=0;i<n.length;i++) {\r
- var c = n[i];\r
- if(c == "$" && (i <= n.length - 1)) {\r
- var c2 = n[++i];\r
-\r
- var o = ThemeControlCodeMap[c2];\r
- if(!o)\r
- o = h[c2];\r
- if(o)\r
- msg.push(o);\r
- } else {\r
- msg.push(c);\r
- }\r
- }\r
- \r
- return msg.join("");\r
- },\r
- message: function(type, data) {\r
- var msg = this.__theme[type];\r
- \r
- msg = this.__dollarSubstitute(msg, data);\r
-\r
- return msg;\r
- }\r
-});\r
+var ThemeControlCodeMap = {
+ "C": "\x03",
+ "B": "\x02",
+ "U": "\x1F",
+ "O": "\x0F",
+ "$": "$"
+};
+
+var DefaultTheme = {
+ "PREFIX": ["$C4==$O "],
+ "SIGNON": ["Signed on!", true],
+ "CONNECT": ["Connected to server.", true],
+ "RAW": ["$m", true],
+ "DISCONNECT": ["Disconnected from server.", true],
+ "ERROR": ["ERROR: $m", true],
+ "SERVERNOTICE": ["$m", true],
+ "JOIN": ["$n [$h] has joined $c", true],
+ "PART": ["$n [$h] has left $c [$m]", true],
+ "KICK": ["$v was kicked from $c by $n [$m]", true],
+ "MODE": ["mode/$c [$m] by $n", true],
+ "QUIT": ["$n [$h] has quit [$m]", true],
+ "NICK": ["$n has changed nick to $w", true],
+ "TOPIC": ["$n changed the topic of $c to: $m", true],
+ "UMODE": ["MODE $n $m", true],
+ "INVITE": ["$n invites you to join $c", true],
+ "CHANMSG": ["<$n> $m"],
+ "PRIVMSG": ["<$n> $m"],
+ "CHANNOTICE": ["-$n:$c- $m"],
+ "PRIVNOTICE": ["-$n- $m"],
+ "OURCHANMSG": ["<$n> $m"],
+ "OURPRIVMSG": ["<$n> $m"],
+ "OURTARGETEDMSG": ["*$t* $m"],
+ "OURTARGETEDNOTICE": ["[notice($t)] $m"],
+ "OURCHANNOTICE": ["-$n:$t- $m"],
+ "OURPRIVNOTICE": ["-$n- $m"],
+ "OURCHANACTION": [" * $n $m"],
+ "OURPRIVACTION": [" * $n $m"],
+ "CHANACTION": [" * $n $m"],
+ "PRIVACTION": [" * $n $m"],
+ "CHANCTCP": ["$n [$h] requested CTCP $x from $c: $m"],
+ "PRIVCTCP": ["$n [$h] requested CTCP $x from $-: $m"],
+ "CTCPREPLY": ["CTCP $x reply from $n: $m"],
+ "OURCHANCTCP": ["[ctcp($t)] $x $m"],
+ "OURPRIVCTCP": ["[ctcp($t)] $x $m"],
+ "OURTARGETEDCTCP": ["[ctcp($t)] $x $m"]
+};
+
+var Theme = new Class({
+ initialize: function(themeDict) {
+ this.__theme = {};
+
+ for(var k in DefaultTheme)
+ this.__theme[k] = DefaultTheme[k];
+
+ if(themeDict)
+ for(var k in themeDict)
+ this.__theme[k] = themeDict[k];
+
+ for(var k in this.__theme) {
+ if(k == "PREFIX")
+ continue;
+
+ var data = this.__theme[k];
+ if(data[1]) {
+ this.__theme[k] = this.__theme["PREFIX"] + data[0];
+ } else {
+ this.__theme[k] = data[0];
+ }
+ }
+ },
+ __dollarSubstitute: function(x, h) {
+ var msg = [];
+
+ var n = x.split("");
+ for(var i=0;i<n.length;i++) {
+ var c = n[i];
+ if(c == "$" && (i <= n.length - 1)) {
+ var c2 = n[++i];
+
+ var o = ThemeControlCodeMap[c2];
+ if(!o)
+ o = h[c2];
+ if(o)
+ msg.push(o);
+ } else {
+ msg.push(c);
+ }
+ }
+
+ return msg.join("");
+ },
+ message: function(type, data) {
+ var msg = this.__theme[type];
+
+ msg = this.__dollarSubstitute(msg, data);
+
+ return msg;
+ }
+});
-var UglyUIWindow = new Class({\r
- Extends: UIWindow,\r
- \r
- initialize: function(parentObject, client, type, name) {\r
- this.parent(parentObject, client, type, name);\r
- \r
- this.outerContainer = new Element("div");\r
- this.outerContainer.addClass("outercontainer");\r
- this.outerContainer.addClass("tab-invisible");\r
- \r
- parentObject.container.appendChild(this.outerContainer);\r
- \r
- if(type == WINDOW_CHANNEL) {\r
- this.nicklist = new Element("div");\r
- this.nicklist.addClass("nicklist");\r
- \r
- this.outerContainer.appendChild(this.nicklist);\r
- }\r
- \r
- var innerContainer = new Element("div");\r
- innerContainer.addClass("innercontainer");\r
- this.outerContainer.appendChild(innerContainer);\r
- \r
- if(type == WINDOW_CHANNEL) {\r
- this.topic = new Element("div");\r
- this.topic.addClass("topic");\r
- innerContainer.appendChild(this.topic);\r
- }\r
- \r
- this.lines = new Element("div");\r
- this.lines.addClass("lines");\r
- innerContainer.appendChild(this.lines);\r
- \r
- this.tab = new Element("span");\r
- this.tab.addClass("tab");\r
- \r
- this.tab.appendText(name);\r
- this.tab.addEvent("click", function() {\r
- parentObject.selectWindow(this);\r
- }.bind(this));\r
-\r
- parentObject.tabs.appendChild(this.tab);\r
- \r
- if(type != WINDOW_STATUS) {\r
- tabclose = new Element("span");\r
- tabclose.addClass("tabclose");\r
- tabclose.addEvent("click", function(e) {\r
- new Event(e).stop();\r
- \r
- if(type == WINDOW_CHANNEL)\r
- this.client.exec("/PART " + name);\r
-\r
- this.close();\r
- }.bind(this));\r
- tabclose.set("text", "X");\r
- this.tab.appendChild(tabclose);\r
- }\r
- },\r
- updateNickList: function(nicks) {\r
- this.parent(nicks);\r
- \r
- var n = this.nicklist;\r
- while(n.firstChild)\r
- n.removeChild(n.firstChild);\r
-\r
- nicks.each(function(nick) {\r
- var e = new Element("div");\r
- n.appendChild(e);\r
- e.appendChild(document.createTextNode(nick));\r
- });\r
- },\r
- updateTopic: function(topic) {\r
- this.parent(topic);\r
- \r
- var t = this.topic;\r
- \r
- while(t.firstChild)\r
- t.removeChild(t.firstChild);\r
-\r
- Colourise(topic, t);\r
- },\r
- select: function() {\r
- this.parent();\r
- \r
- this.outerContainer.removeClass("tab-invisible");\r
- this.tab.removeClass("tab-unselected");\r
- this.tab.removeClass("tab-highlighted");\r
- this.tab.addClass("tab-selected");\r
- },\r
- deselect: function() {\r
- this.parent();\r
- \r
- this.outerContainer.addClass("tab-invisible");\r
- this.tab.removeClass("tab-selected");\r
- this.tab.addClass("tab-unselected");\r
- },\r
- close: function() {\r
- this.parent();\r
- \r
- this.parentObject.container.removeChild(this.outerContainer);\r
- this.parentObject.tabs.removeChild(this.tab);\r
- },\r
- addLine: function(type, line, colour) {\r
- this.parent(type, line, colour);\r
- \r
- var e = new Element("div");\r
-\r
- if(colour) {\r
- e.addStyle("background", colour);\r
- } else if(this.lastcolour) {\r
- e.addClass("linestyle1");\r
- } else {\r
- e.addClass("linestyle2");\r
- }\r
- \r
- if(type)\r
- line = this.parentObject.theme.message(type, line);\r
- \r
- Colourise(IRCTimestamp(new Date()) + " " + line, e);\r
- \r
- this.lastcolour = !this.lastcolour;\r
- \r
- var prev = this.lines.getScroll();\r
- var prevbottom = this.lines.getScrollSize().y;\r
- var prevsize = this.lines.getSize();\r
- this.lines.appendChild(e);\r
- \r
- if(prev.y + prevsize.y == prevbottom)\r
- this.lines.scrollTo(prev.x, this.lines.getScrollSize().y);\r
- \r
- if(!this.active)\r
- this.tab.addClass("tab-highlighted");\r
- }\r
-});\r
-\r
-var UglyUI = new Class({\r
- Extends: UI,\r
- initialize: function(parentElement, theme) {\r
- this.parent(parentElement, UglyUIWindow, "uglyui");\r
- \r
- this.theme = theme;\r
- \r
- this.tabs = new Element("div");\r
- this.tabs.addClass("tabbar");\r
- \r
- parentElement.appendChild(this.tabs);\r
- \r
- this.container = new Element("div");\r
- this.container.addClass("container");\r
- \r
- parentElement.appendChild(this.container);\r
- \r
- var form = new Element("form");\r
- var inputbox = new Element("input");\r
- inputbox.addClass("input");\r
- \r
- form.addEvent("submit", function(e) {\r
- new Event(e).stop();\r
- \r
- this.getActiveWindow().client.exec(inputbox.value);\r
- inputbox.value = "";\r
- }.bind(this));\r
- parentElement.appendChild(form); \r
- form.appendChild(inputbox);\r
- inputbox.focus();\r
- }\r
+var UglyUIWindow = new Class({
+ Extends: UIWindow,
+
+ initialize: function(parentObject, client, type, name) {
+ this.parent(parentObject, client, type, name);
+
+ this.outerContainer = new Element("div");
+ this.outerContainer.addClass("outercontainer");
+ this.outerContainer.addClass("tab-invisible");
+
+ parentObject.container.appendChild(this.outerContainer);
+
+ if(type == WINDOW_CHANNEL) {
+ this.nicklist = new Element("div");
+ this.nicklist.addClass("nicklist");
+
+ this.outerContainer.appendChild(this.nicklist);
+ }
+
+ var innerContainer = new Element("div");
+ innerContainer.addClass("innercontainer");
+ this.outerContainer.appendChild(innerContainer);
+
+ if(type == WINDOW_CHANNEL) {
+ this.topic = new Element("div");
+ this.topic.addClass("topic");
+ innerContainer.appendChild(this.topic);
+ }
+
+ this.lines = new Element("div");
+ this.lines.addClass("lines");
+ innerContainer.appendChild(this.lines);
+
+ this.tab = new Element("span");
+ this.tab.addClass("tab");
+
+ this.tab.appendText(name);
+ this.tab.addEvent("click", function() {
+ parentObject.selectWindow(this);
+ }.bind(this));
+
+ parentObject.tabs.appendChild(this.tab);
+
+ if(type != WINDOW_STATUS) {
+ tabclose = new Element("span");
+ tabclose.addClass("tabclose");
+ tabclose.addEvent("click", function(e) {
+ new Event(e).stop();
+
+ if(type == WINDOW_CHANNEL)
+ this.client.exec("/PART " + name);
+
+ this.close();
+ }.bind(this));
+ tabclose.set("text", "X");
+ this.tab.appendChild(tabclose);
+ }
+ },
+ updateNickList: function(nicks) {
+ this.parent(nicks);
+
+ var n = this.nicklist;
+ while(n.firstChild)
+ n.removeChild(n.firstChild);
+
+ nicks.each(function(nick) {
+ var e = new Element("div");
+ n.appendChild(e);
+ e.appendChild(document.createTextNode(nick));
+ });
+ },
+ updateTopic: function(topic) {
+ this.parent(topic);
+
+ var t = this.topic;
+
+ while(t.firstChild)
+ t.removeChild(t.firstChild);
+
+ Colourise(topic, t);
+ },
+ select: function() {
+ this.parent();
+
+ this.outerContainer.removeClass("tab-invisible");
+ this.tab.removeClass("tab-unselected");
+ this.tab.removeClass("tab-highlighted");
+ this.tab.addClass("tab-selected");
+ },
+ deselect: function() {
+ this.parent();
+
+ this.outerContainer.addClass("tab-invisible");
+ this.tab.removeClass("tab-selected");
+ this.tab.addClass("tab-unselected");
+ },
+ close: function() {
+ this.parent();
+
+ this.parentObject.container.removeChild(this.outerContainer);
+ this.parentObject.tabs.removeChild(this.tab);
+ },
+ addLine: function(type, line, colour) {
+ this.parent(type, line, colour);
+
+ var e = new Element("div");
+
+ if(colour) {
+ e.addStyle("background", colour);
+ } else if(this.lastcolour) {
+ e.addClass("linestyle1");
+ } else {
+ e.addClass("linestyle2");
+ }
+
+ if(type)
+ line = this.parentObject.theme.message(type, line);
+
+ Colourise(IRCTimestamp(new Date()) + " " + line, e);
+
+ this.lastcolour = !this.lastcolour;
+
+ var prev = this.lines.getScroll();
+ var prevbottom = this.lines.getScrollSize().y;
+ var prevsize = this.lines.getSize();
+ this.lines.appendChild(e);
+
+ if(prev.y + prevsize.y == prevbottom)
+ this.lines.scrollTo(prev.x, this.lines.getScrollSize().y);
+
+ if(!this.active)
+ this.tab.addClass("tab-highlighted");
+ }
+});
+
+var UglyUI = new Class({
+ Extends: UI,
+ initialize: function(parentElement, theme) {
+ this.parent(parentElement, UglyUIWindow, "uglyui");
+
+ this.theme = theme;
+
+ this.tabs = new Element("div");
+ this.tabs.addClass("tabbar");
+
+ parentElement.appendChild(this.tabs);
+
+ this.container = new Element("div");
+ this.container.addClass("container");
+
+ parentElement.appendChild(this.container);
+
+ var form = new Element("form");
+ var inputbox = new Element("input");
+ inputbox.addClass("input");
+
+ form.addEvent("submit", function(e) {
+ new Event(e).stop();
+
+ this.getActiveWindow().client.exec(inputbox.value);
+ inputbox.value = "";
+ }.bind(this));
+ parentElement.appendChild(form);
+ form.appendChild(inputbox);
+ inputbox.focus();
+ }
});
\ No newline at end of file
-QWEBIRC_VERSION = "0.01"\r
+QWEBIRC_VERSION = "0.01"
-from root import RootSite\r
+from root import RootSite
-from twisted.web import resource, server, static\r
-from twisted.names import client\r
-from twisted.internet import reactor\r
-import simplejson, md5, sys, os, ircclient, time, config\r
-\r
-Sessions = {}\r
-\r
-def get_session_id():\r
- return md5.md5(os.urandom(16)).hexdigest()\r
- \r
-def jsondump(fn):\r
- def decorator(*args, **kwargs):\r
- x = fn(*args, **kwargs)\r
- if isinstance(x, list):\r
- return simplejson.dumps(x)\r
- return x\r
- return decorator\r
-\r
-class IRCSession:\r
- def __init__(self, id):\r
- self.id = id\r
- self.subscriptions = []\r
- self.buffer = []\r
- self.throttle = 0\r
- self.schedule = None\r
- \r
- def subscribe(self, channel):\r
- self.subscriptions.append(channel)\r
- self.flush()\r
- \r
- def flush(self, scheduled=False):\r
- if scheduled:\r
- self.schedule = None\r
- \r
- if not self.buffer or not self.subscriptions:\r
- return\r
- \r
- t = time.time()\r
- \r
- if t < self.throttle:\r
- if not self.schedule:\r
- self.schedule = reactor.callLater(self.throttle - t, self.flush, True)\r
- return\r
- else:\r
- # process the rest of the packet\r
- if not scheduled:\r
- if not self.schedule:\r
- self.schedule = reactor.callLater(0, self.flush, True)\r
- return\r
- \r
- self.throttle = t + config.UPDATE_FREQ\r
-\r
- encdata = simplejson.dumps(self.buffer)\r
- self.buffer = []\r
- \r
- newsubs = []\r
- for x in self.subscriptions:\r
- if x.write(encdata):\r
- newsubs.append(x)\r
-\r
- self.subscriptions = newsubs\r
- \r
- def event(self, data):\r
- self.buffer.append(data)\r
- self.flush()\r
- \r
- def push(self, data):\r
- self.client.write(data)\r
- \r
-class Channel:\r
- def __init__(self, request):\r
- self.request = request\r
- \r
-class SingleUseChannel(Channel):\r
- def write(self, data):\r
- self.request.write(data)\r
- self.request.finish()\r
- return False\r
- \r
-class MultipleUseChannel(Channel):\r
- def write(self, data):\r
- self.request.write(data)\r
- return True\r
-\r
-class AJAXEngine(resource.Resource):\r
- isLeaf = True\r
- \r
- def __init__(self, prefix):\r
- self.prefix = prefix\r
-\r
- @jsondump\r
- def render_GET(self, request):\r
- path = request.path[len(self.prefix):]\r
- if path == "/n":\r
- ip = request.transport.getPeer()\r
- ip = ip[1]\r
-\r
- nick, ident = request.args.get("nick"), "webchat"\r
- if not nick:\r
- return [False, "Nickname not supplied"]\r
- \r
- nick = nick[0]\r
- \r
- id = get_session_id()\r
- \r
- session = IRCSession(id)\r
-\r
- client = ircclient.createIRC(session, nick=nick, ident=ident, ip=ip, realname=nick)\r
- session.client = client\r
- \r
- Sessions[id] = session\r
- \r
- return [True, id]\r
- \r
- if path.startswith("/s/"):\r
- sessionid = path[3:]\r
- session = Sessions.get(sessionid)\r
- \r
- if not session:\r
- return [False, "Bad session ID"]\r
-\r
- session.subscribe(SingleUseChannel(request))\r
- return server.NOT_DONE_YET\r
- if path.startswith("/p/"):\r
- command = request.args.get("c")\r
- if not command:\r
- return [False, "No command specified"]\r
-\r
- command = command[0]\r
- \r
- sessionid = path[3:]\r
- session = Sessions.get(sessionid)\r
- if not session:\r
- return [False, "Bad session ID"]\r
-\r
- try:\r
- decoded = command.decode("utf-8")\r
- except UnicodeDecodeError:\r
- decoded = command.decode("iso-8859-1", "ignore")\r
- session.push(decoded)\r
- return [True]\r
-\r
- return [False, "404"]\r
-\r
+from twisted.web import resource, server, static
+from twisted.names import client
+from twisted.internet import reactor
+import simplejson, md5, sys, os, ircclient, time, config
+
+Sessions = {}
+
+def get_session_id():
+ return md5.md5(os.urandom(16)).hexdigest()
+
+def jsondump(fn):
+ def decorator(*args, **kwargs):
+ x = fn(*args, **kwargs)
+ if isinstance(x, list):
+ return simplejson.dumps(x)
+ return x
+ return decorator
+
+class IRCSession:
+ def __init__(self, id):
+ self.id = id
+ self.subscriptions = []
+ self.buffer = []
+ self.throttle = 0
+ self.schedule = None
+
+ def subscribe(self, channel):
+ self.subscriptions.append(channel)
+ self.flush()
+
+ def flush(self, scheduled=False):
+ if scheduled:
+ self.schedule = None
+
+ if not self.buffer or not self.subscriptions:
+ return
+
+ t = time.time()
+
+ if t < self.throttle:
+ if not self.schedule:
+ self.schedule = reactor.callLater(self.throttle - t, self.flush, True)
+ return
+ else:
+ # process the rest of the packet
+ if not scheduled:
+ if not self.schedule:
+ self.schedule = reactor.callLater(0, self.flush, True)
+ return
+
+ self.throttle = t + config.UPDATE_FREQ
+
+ encdata = simplejson.dumps(self.buffer)
+ self.buffer = []
+
+ newsubs = []
+ for x in self.subscriptions:
+ if x.write(encdata):
+ newsubs.append(x)
+
+ self.subscriptions = newsubs
+
+ def event(self, data):
+ self.buffer.append(data)
+ self.flush()
+
+ def push(self, data):
+ self.client.write(data)
+
+class Channel:
+ def __init__(self, request):
+ self.request = request
+
+class SingleUseChannel(Channel):
+ def write(self, data):
+ self.request.write(data)
+ self.request.finish()
+ return False
+
+class MultipleUseChannel(Channel):
+ def write(self, data):
+ self.request.write(data)
+ return True
+
+class AJAXEngine(resource.Resource):
+ isLeaf = True
+
+ def __init__(self, prefix):
+ self.prefix = prefix
+
+ @jsondump
+ def render_GET(self, request):
+ path = request.path[len(self.prefix):]
+ if path == "/n":
+ ip = request.transport.getPeer()
+ ip = ip[1]
+
+ nick, ident = request.args.get("nick"), "webchat"
+ if not nick:
+ return [False, "Nickname not supplied"]
+
+ nick = nick[0]
+
+ id = get_session_id()
+
+ session = IRCSession(id)
+
+ client = ircclient.createIRC(session, nick=nick, ident=ident, ip=ip, realname=nick)
+ session.client = client
+
+ Sessions[id] = session
+
+ return [True, id]
+
+ if path.startswith("/s/"):
+ sessionid = path[3:]
+ session = Sessions.get(sessionid)
+
+ if not session:
+ return [False, "Bad session ID"]
+
+ session.subscribe(SingleUseChannel(request))
+ return server.NOT_DONE_YET
+ if path.startswith("/p/"):
+ command = request.args.get("c")
+ if not command:
+ return [False, "No command specified"]
+
+ command = command[0]
+
+ sessionid = path[3:]
+ session = Sessions.get(sessionid)
+ if not session:
+ return [False, "Bad session ID"]
+
+ try:
+ decoded = command.decode("utf-8")
+ except UnicodeDecodeError:
+ decoded = command.decode("iso-8859-1", "ignore")
+ session.push(decoded)
+ return [True]
+
+ return [False, "404"]
+
-IRCSERVER, IRCPORT = "moo.com", 6667\r
-HMACKEY = "mrmoo"\r
-HMACTEMPORAL = 30\r
-UPDATE_FREQ = 0.5\r
+IRCSERVER, IRCPORT = "moo.com", 6667
+HMACKEY = "mrmoo"
+HMACTEMPORAL = 30
+UPDATE_FREQ = 0.5
-import twisted, sys\r
-from twisted.words.protocols import irc\r
-from twisted.internet import reactor, protocol\r
-from twisted.web import resource, server\r
-from twisted.protocols import basic\r
-\r
-import hmac, time, config\r
-from config import HMACTEMPORAL\r
-HMACKEY = hmac.HMAC(key=config.HMACKEY)\r
-\r
-def hmacfn(*args):\r
- h = HMACKEY.copy()\r
- h.update("%d %s" % (int(time.time() / HMACTEMPORAL), " ".join(args)))\r
- return h.hexdigest()\r
-\r
-class QWebIRCClient(basic.LineReceiver):\r
- delimiter = "\n"\r
- \r
- def dataReceived(self, data):\r
- basic.LineReceiver.dataReceived(self, data.replace("\r", ""))\r
-\r
- def lineReceived(self, line):\r
- line = irc.lowDequote(line)\r
- try:\r
- line = line.decode("utf-8")\r
- except UnicodeDecodeError:\r
- line = line.decode("iso-8859-1", "ignore")\r
- \r
- try:\r
- prefix, command, params = irc.parsemsg(line)\r
- self.handleCommand(command, prefix, params)\r
- except irc.IRCBadMessage:\r
- self.badMessage(line, *sys.exc_info())\r
- \r
- def badMessage(self, args):\r
- self("badmessage", args)\r
- \r
- def handleCommand(self, command, prefix, params):\r
- self("c", command, prefix, params)\r
- \r
- def __call__(self, *args):\r
- self.factory.publisher.event(args)\r
- \r
- def write(self, data):\r
- self.transport.write("%s\r\n" % irc.lowQuote(data.encode("utf-8")))\r
- \r
- def connectionMade(self):\r
- basic.LineReceiver.connectionMade(self)\r
- \r
- f = self.factory.ircinit\r
- nick, ident, ip, realname = f["nick"], f["ident"], f["ip"], f["realname"]\r
- \r
- hmac = hmacfn(ident, ip)\r
- self.write("USER %s bleh bleh %s %s :%s" % (ident, ip, hmac, realname))\r
- self.write("NICK %s" % nick)\r
- \r
- self.factory.client = self\r
- self("connect")\r
-\r
- def connectionLost(self, reason):\r
- self.factory.client = None\r
- basic.LineReceiver.connectionLost(self, reason)\r
- self("disconnect")\r
- \r
-class QWebIRCFactory(protocol.ClientFactory):\r
- protocol = QWebIRCClient\r
- def __init__(self, publisher, **kwargs):\r
- self.client = None\r
- self.publisher = publisher\r
- self.ircinit = kwargs\r
- \r
- def write(self, data):\r
- self.client.write(data)\r
- \r
-def createIRC(*args, **kwargs):\r
- f = QWebIRCFactory(*args, **kwargs)\r
- reactor.connectTCP(config.IRCSERVER, config.IRCPORT, f)\r
- return f\r
-\r
-if __name__ == "__main__":\r
- e = createIRC(lambda x: 2, nick="slug__moo", ident="mooslug", ip="1.2.3.6", realname="mooooo")\r
+import twisted, sys
+from twisted.words.protocols import irc
+from twisted.internet import reactor, protocol
+from twisted.web import resource, server
+from twisted.protocols import basic
+
+import hmac, time, config
+from config import HMACTEMPORAL
+HMACKEY = hmac.HMAC(key=config.HMACKEY)
+
+def hmacfn(*args):
+ h = HMACKEY.copy()
+ h.update("%d %s" % (int(time.time() / HMACTEMPORAL), " ".join(args)))
+ return h.hexdigest()
+
+class QWebIRCClient(basic.LineReceiver):
+ delimiter = "\n"
+
+ def dataReceived(self, data):
+ basic.LineReceiver.dataReceived(self, data.replace("\r", ""))
+
+ def lineReceived(self, line):
+ line = irc.lowDequote(line)
+ try:
+ line = line.decode("utf-8")
+ except UnicodeDecodeError:
+ line = line.decode("iso-8859-1", "ignore")
+
+ try:
+ prefix, command, params = irc.parsemsg(line)
+ self.handleCommand(command, prefix, params)
+ except irc.IRCBadMessage:
+ self.badMessage(line, *sys.exc_info())
+
+ def badMessage(self, args):
+ self("badmessage", args)
+
+ def handleCommand(self, command, prefix, params):
+ self("c", command, prefix, params)
+
+ def __call__(self, *args):
+ self.factory.publisher.event(args)
+
+ def write(self, data):
+ self.transport.write("%s\r\n" % irc.lowQuote(data.encode("utf-8")))
+
+ def connectionMade(self):
+ basic.LineReceiver.connectionMade(self)
+
+ f = self.factory.ircinit
+ nick, ident, ip, realname = f["nick"], f["ident"], f["ip"], f["realname"]
+
+ hmac = hmacfn(ident, ip)
+ self.write("USER %s bleh bleh %s %s :%s" % (ident, ip, hmac, realname))
+ self.write("NICK %s" % nick)
+
+ self.factory.client = self
+ self("connect")
+
+ def connectionLost(self, reason):
+ self.factory.client = None
+ basic.LineReceiver.connectionLost(self, reason)
+ self("disconnect")
+
+class QWebIRCFactory(protocol.ClientFactory):
+ protocol = QWebIRCClient
+ def __init__(self, publisher, **kwargs):
+ self.client = None
+ self.publisher = publisher
+ self.ircinit = kwargs
+
+ def write(self, data):
+ self.client.write(data)
+
+def createIRC(*args, **kwargs):
+ f = QWebIRCFactory(*args, **kwargs)
+ reactor.connectTCP(config.IRCSERVER, config.IRCPORT, f)
+ return f
+
+if __name__ == "__main__":
+ e = createIRC(lambda x: 2, nick="slug__moo", ident="mooslug", ip="1.2.3.6", realname="mooooo")
reactor.run()
\ No newline at end of file
-from ajaxengine import AJAXEngine\r
-\r
-from twisted.web import resource, server, static\r
-\r
-class RootResource(resource.Resource):\r
- isLeaf = True\r
- def render_GET(self, request):\r
- return "moo"\r
- \r
-class RootSite(server.Site):\r
- def __init__(self, path, *args, **kwargs):\r
- root = resource.Resource()\r
- server.Site.__init__(self, root, *args, **kwargs)\r
- \r
- root.putChild("", RootResource())\r
- root.putChild("e", AJAXEngine("/e"))\r
- root.putChild("static", static.File(path))\r
+from ajaxengine import AJAXEngine
+
+from twisted.web import resource, server, static
+
+class RootResource(resource.Resource):
+ isLeaf = True
+ def render_GET(self, request):
+ return "moo"
+
+class RootSite(server.Site):
+ def __init__(self, path, *args, **kwargs):
+ root = resource.Resource()
+ server.Site.__init__(self, root, *args, **kwargs)
+
+ root.putChild("", RootResource())
+ root.putChild("e", AJAXEngine("/e"))
+ root.putChild("static", static.File(path))
-.qwebirc .colourline .Xc0 {\r
- color: white;\r
-}\r
-.qwebirc .colourline .Xc1 {\r
- color: black;\r
-}\r
-.qwebirc .colourline .Xc2 {\r
- color: darkBlue;\r
-}\r
-.qwebirc .colourline .Xc3 {\r
- color: darkGreen;\r
-}\r
-.qwebirc .colourline .Xc4 {\r
- color: red;\r
-}\r
-.qwebirc .colourline .Xc5 {\r
- color: darkRed;\r
-}\r
-.qwebirc .colourline .Xc6 {\r
- color: purple;\r
-}\r
-.qwebirc .colourline .Xc7 {\r
- color: orange;\r
-}\r
-.qwebirc .colourline .Xc8 {\r
- color: yellow;\r
-}\r
-.qwebirc .colourline .Xc9 {\r
- color: green;\r
-}\r
-.qwebirc .colourline .Xc10 {\r
- color: teal;\r
-}\r
-.qwebirc .colourline .Xc11 {\r
- color: cyan;\r
-}\r
-.qwebirc .colourline .Xc12 {\r
- color: blue;\r
-}\r
-.qwebirc .colourline .Xc13 {\r
- color: fuchsia;\r
-}\r
-.qwebirc .colourline .Xc14 {\r
- color: darkGray;\r
-}\r
-.qwebirc .colourline .Xc15 {\r
- color: gray;\r
-}\r
-.qwebirc .colourline .Xbc0 {\r
- background-color: white;\r
-}\r
-.qwebirc .colourline .Xbc1 {\r
- background-color: black;\r
-}\r
-.qwebirc .colourline .Xbc2 {\r
- background-color: darkBlue;\r
-}\r
-.qwebirc .colourline .Xbc3 {\r
- background-color: darkGreen;\r
-}\r
-.qwebirc .colourline .Xbc4 {\r
- background-color: red;\r
-}\r
-.qwebirc .colourline .Xbc5 {\r
- background-color: darkRed;\r
-}\r
-.qwebirc .colourline .Xbc6 {\r
- background-color: purple;\r
-}\r
-.qwebirc .colourline .Xbc7 {\r
- background-color: orange;\r
-}\r
-.qwebirc .colourline .Xbc8 {\r
- background-color: yellow;\r
-}\r
-.qwebirc .colourline .Xbc9 {\r
- background-color: green;\r
-}\r
-.qwebirc .colourline .Xbc10 {\r
- background-color: teal;\r
-}\r
-.qwebirc .colourline .Xbc11 {\r
- background-color: cyan;\r
-}\r
-.qwebirc .colourline .Xbc12 {\r
- background-color: blue;\r
-}\r
-.qwebirc .colourline .Xbc13 {\r
- background-color: fuchsia;\r
-}\r
-.qwebirc .colourline .Xbc14 {\r
- background-color: darkGray;\r
-}\r
-.qwebirc .colourline .Xbc15 {\r
- background-color: gray;\r
-}\r
-.qwebirc .colourline .Xb {\r
- font-weight: bold;\r
-}\r
-.qwebirc .colourline .Xu {\r
- text-decoration: underline;\r
-}\r
+.qwebirc .colourline .Xc0 {
+ color: white;
+}
+.qwebirc .colourline .Xc1 {
+ color: black;
+}
+.qwebirc .colourline .Xc2 {
+ color: darkBlue;
+}
+.qwebirc .colourline .Xc3 {
+ color: darkGreen;
+}
+.qwebirc .colourline .Xc4 {
+ color: red;
+}
+.qwebirc .colourline .Xc5 {
+ color: darkRed;
+}
+.qwebirc .colourline .Xc6 {
+ color: purple;
+}
+.qwebirc .colourline .Xc7 {
+ color: orange;
+}
+.qwebirc .colourline .Xc8 {
+ color: yellow;
+}
+.qwebirc .colourline .Xc9 {
+ color: green;
+}
+.qwebirc .colourline .Xc10 {
+ color: teal;
+}
+.qwebirc .colourline .Xc11 {
+ color: cyan;
+}
+.qwebirc .colourline .Xc12 {
+ color: blue;
+}
+.qwebirc .colourline .Xc13 {
+ color: fuchsia;
+}
+.qwebirc .colourline .Xc14 {
+ color: darkGray;
+}
+.qwebirc .colourline .Xc15 {
+ color: gray;
+}
+.qwebirc .colourline .Xbc0 {
+ background-color: white;
+}
+.qwebirc .colourline .Xbc1 {
+ background-color: black;
+}
+.qwebirc .colourline .Xbc2 {
+ background-color: darkBlue;
+}
+.qwebirc .colourline .Xbc3 {
+ background-color: darkGreen;
+}
+.qwebirc .colourline .Xbc4 {
+ background-color: red;
+}
+.qwebirc .colourline .Xbc5 {
+ background-color: darkRed;
+}
+.qwebirc .colourline .Xbc6 {
+ background-color: purple;
+}
+.qwebirc .colourline .Xbc7 {
+ background-color: orange;
+}
+.qwebirc .colourline .Xbc8 {
+ background-color: yellow;
+}
+.qwebirc .colourline .Xbc9 {
+ background-color: green;
+}
+.qwebirc .colourline .Xbc10 {
+ background-color: teal;
+}
+.qwebirc .colourline .Xbc11 {
+ background-color: cyan;
+}
+.qwebirc .colourline .Xbc12 {
+ background-color: blue;
+}
+.qwebirc .colourline .Xbc13 {
+ background-color: fuchsia;
+}
+.qwebirc .colourline .Xbc14 {
+ background-color: darkGray;
+}
+.qwebirc .colourline .Xbc15 {
+ background-color: gray;
+}
+.qwebirc .colourline .Xb {
+ font-weight: bold;
+}
+.qwebirc .colourline .Xu {
+ text-decoration: underline;
+}
-body, html {\r
- height: 100%;\r
- width: 100%;\r
- margin: 0;\r
- padding: 0;\r
- font-family: "Lucida Console", sans-serif;\r
-}\r
-\r
-.qwebirc-swmui .container {\r
- height: 100%;\r
- width: 100%;\r
-}\r
-\r
-.qwebirc-swmui .tabs {\r
- background: #fdd;\r
-}\r
-\r
-.qwebirc-swmui .main {\r
- background: #ddf;\r
-}\r
-\r
-.qwebirc-swmui .entry {\r
- background: #dfd;\r
-}\r
-\r
-.qwebirc-swmui .content {\r
- background: #ddf;\r
-}\r
-\r
-.qwebirc-swmui .nicklist {\r
- background: #dff;\r
-}\r
-\r
-.qwebirc-swmui .tab {\r
- float: left;\r
- min-width: 100px;\r
- width: 100px;\r
- display: block;\r
- border: 1px solid black;\r
- margin-right: 2px;\r
- cursor: default;\r
-}\r
-\r
-.qwebirc-swmui .tabclose {\r
- border: 1px solid black;\r
- margin: 2px;\r
- font-size: 0.5em;\r
-}\r
-\r
-.qwebirc-swmui .entry input {\r
- padding: 0px;\r
-}\r
-\r
-.qwebirc-swmui .entry {\r
-}\r
-\r
-.qwebirc-swmui .tab-highlighted {\r
- color: red;\r
-}\r
-\r
-.qwebirc-swmui .linestyle1 {\r
- background: #efefef;\r
-}\r
-\r
-.qwebirc-swmui .linestyle2 {\r
- background: #eeffff;\r
-}\r
-\r
-.qwebirc-swmui .tab-selected {\r
- background: #fef;\r
-}\r
-\r
-.qwebirc-swmui .tab-unselected {\r
- background: #eee;\r
+body, html {
+ height: 100%;
+ width: 100%;
+ margin: 0;
+ padding: 0;
+ font-family: "Lucida Console", sans-serif;
+}
+
+.qwebirc-swmui .container {
+ height: 100%;
+ width: 100%;
+}
+
+.qwebirc-swmui .tabs {
+ background: #fdd;
+}
+
+.qwebirc-swmui .main {
+ background: #ddf;
+}
+
+.qwebirc-swmui .entry {
+ background: #dfd;
+}
+
+.qwebirc-swmui .content {
+ background: #ddf;
+}
+
+.qwebirc-swmui .nicklist {
+ background: #dff;
+}
+
+.qwebirc-swmui .tab {
+ float: left;
+ min-width: 100px;
+ width: 100px;
+ display: block;
+ border: 1px solid black;
+ margin-right: 2px;
+ cursor: default;
+}
+
+.qwebirc-swmui .tabclose {
+ border: 1px solid black;
+ margin: 2px;
+ font-size: 0.5em;
+}
+
+.qwebirc-swmui .entry input {
+ padding: 0px;
+}
+
+.qwebirc-swmui .entry {
+}
+
+.qwebirc-swmui .tab-highlighted {
+ color: red;
+}
+
+.qwebirc-swmui .linestyle1 {
+ background: #efefef;
+}
+
+.qwebirc-swmui .linestyle2 {
+ background: #eeffff;
+}
+
+.qwebirc-swmui .tab-selected {
+ background: #fef;
+}
+
+.qwebirc-swmui .tab-unselected {
+ background: #eee;
}
\ No newline at end of file
-.qwebirc-uglyui .tabbar {\r
- border: 1px solid black;\r
- padding: 4px;\r
- font-family: "Lucida Console", sans-serif;\r
-}\r
-\r
-.qwebirc-uglyui .tab {\r
- border: 1px black solid;\r
- padding: 2px;\r
- cursor: default;\r
- margin-right: 2px;\r
- background: #eee;\r
- clear: both;\r
-}\r
-\r
-.qwebirc-uglyui .container {\r
- border: 1px solid black;\r
- margin: 2px 0px 0px 0px;\r
- height: 480px;\r
-}\r
-\r
-.qwebirc-uglyui .input {\r
- width: 400px;\r
- border: 1px solid black;\r
- margin: 2px 0px 0px 0px;\r
-}\r
-\r
-.qwebirc-uglyui .tabclose {\r
- border: 1px black solid;\r
- margin-left: 5px;\r
- padding: 2px;\r
- font-size: 0.5em;\r
-}\r
-\r
-.qwebirc-uglyui .nicklist {\r
- border-left: 1px solid black;\r
- width: 125px;\r
- float: right;\r
- height: 480px;\r
- clear: both;\r
- overflow: auto;\r
- background: white;\r
-}\r
-\r
-.qwebirc-uglyui .tab-invisible {\r
- display: none;\r
-}\r
-\r
-.qwebirc-uglyui .outercontainer {\r
- font-family: Lucida Console;\r
-}\r
-\r
-.qwebirc-uglyui .innercontainer {\r
- height: 480px;\r
-}\r
-\r
-.qwebirc-uglyui .topic {\r
- background: #fef;\r
- height: 20px;\r
-}\r
-\r
-.qwebirc-uglyui .tab-selected {\r
- background: #eff;\r
-}\r
-\r
-.qwebirc-uglyui .tab-unselected {\r
- background: #eee;\r
-}\r
-\r
-.qwebirc-uglyui .tab-highlighted {\r
- color: red;\r
-}\r
-\r
-.qwebirc-uglyui .lines {\r
- height: 460px;\r
- overflow: auto;\r
- word-wrap: break-word;\r
-}\r
-\r
-.qwebirc-uglyui .linestyle1 {\r
- background: #efefef;\r
-}\r
-\r
-.qwebirc-uglyui .linestyle2 {\r
- background: #eeffff;\r
-}\r
+.qwebirc-uglyui .tabbar {
+ border: 1px solid black;
+ padding: 4px;
+ font-family: "Lucida Console", sans-serif;
+}
+
+.qwebirc-uglyui .tab {
+ border: 1px black solid;
+ padding: 2px;
+ cursor: default;
+ margin-right: 2px;
+ background: #eee;
+ clear: both;
+}
+
+.qwebirc-uglyui .container {
+ border: 1px solid black;
+ margin: 2px 0px 0px 0px;
+ height: 480px;
+}
+
+.qwebirc-uglyui .input {
+ width: 400px;
+ border: 1px solid black;
+ margin: 2px 0px 0px 0px;
+}
+
+.qwebirc-uglyui .tabclose {
+ border: 1px black solid;
+ margin-left: 5px;
+ padding: 2px;
+ font-size: 0.5em;
+}
+
+.qwebirc-uglyui .nicklist {
+ border-left: 1px solid black;
+ width: 125px;
+ float: right;
+ height: 480px;
+ clear: both;
+ overflow: auto;
+ background: white;
+}
+
+.qwebirc-uglyui .tab-invisible {
+ display: none;
+}
+
+.qwebirc-uglyui .outercontainer {
+ font-family: Lucida Console;
+}
+
+.qwebirc-uglyui .innercontainer {
+ height: 480px;
+}
+
+.qwebirc-uglyui .topic {
+ background: #fef;
+ height: 20px;
+}
+
+.qwebirc-uglyui .tab-selected {
+ background: #eff;
+}
+
+.qwebirc-uglyui .tab-unselected {
+ background: #eee;
+}
+
+.qwebirc-uglyui .tab-highlighted {
+ color: red;
+}
+
+.qwebirc-uglyui .lines {
+ height: 460px;
+ overflow: auto;
+ word-wrap: break-word;
+}
+
+.qwebirc-uglyui .linestyle1 {
+ background: #efefef;
+}
+
+.qwebirc-uglyui .linestyle2 {
+ background: #eeffff;
+}
-<html>\r
-<body>\r
- <iframe src="swmui.html" height="600" width="600"/>\r
-</body>\r
+<html>
+<body>
+ <iframe src="swmui.html" height="600" width="600"/>
+</body>
</html>
\ No newline at end of file
-<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\r
-"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
-<head>\r
- <title>QuakeNet Web IRC</title>\r
- <link rel="stylesheet" href="css/colours.css" type="text/css">\r
- <link rel="stylesheet" href="css/swmui.css" type="text/css">\r
- <script type="text/javascript" src="js/mootools-1.2-core.js"></script>\r
- <!--<script type="text/javascript" src="js/debug/version.js"></script>\r
- <script type="text/javascript" src="js/debug/jslib.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/ircconnection.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/irclib.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/baseirc.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/irctracker.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/commandparser.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/ircclient.js"></script>\r
- <script type="text/javascript" src="js/debug/ui/baseui.js"></script>\r
- <script type="text/javascript" src="js/debug/ui/colour.js"></script>\r
- <script type="text/javascript" src="js/debug/ui/theme.js"></script>\r
- <script type="text/javascript" src="js/debug/ui/swmlayout.js"></script>\r
- <script type="text/javascript" src="js/debug/ui/swmui.js"></script>-->\r
- <script type="text/javascript" src="js/qwebirc.js"></script>\r
- <script type="text/javascript" src="js/swmui.js"></script>\r
- <script type="text/javascript"> \r
- window.addEvent("domready", function() {\r
- var theme = new Theme();\r
- var ui = new SWMUI($("ircui"), theme);\r
-\r
- var IRC = new IRCClient({nickname: "mcgoogle"}, ui);\r
- IRC.connect();\r
-\r
- });\r
- </script>\r
-</head>\r
-<body>\r
- <div id="ircui"></div>\r
-</body>\r
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+ <title>QuakeNet Web IRC</title>
+ <link rel="stylesheet" href="css/colours.css" type="text/css">
+ <link rel="stylesheet" href="css/swmui.css" type="text/css">
+ <script type="text/javascript" src="js/mootools-1.2-core.js"></script>
+ <!--<script type="text/javascript" src="js/debug/version.js"></script>
+ <script type="text/javascript" src="js/debug/jslib.js"></script>
+ <script type="text/javascript" src="js/debug/irc/ircconnection.js"></script>
+ <script type="text/javascript" src="js/debug/irc/irclib.js"></script>
+ <script type="text/javascript" src="js/debug/irc/baseirc.js"></script>
+ <script type="text/javascript" src="js/debug/irc/irctracker.js"></script>
+ <script type="text/javascript" src="js/debug/irc/commandparser.js"></script>
+ <script type="text/javascript" src="js/debug/irc/ircclient.js"></script>
+ <script type="text/javascript" src="js/debug/ui/baseui.js"></script>
+ <script type="text/javascript" src="js/debug/ui/colour.js"></script>
+ <script type="text/javascript" src="js/debug/ui/theme.js"></script>
+ <script type="text/javascript" src="js/debug/ui/swmlayout.js"></script>
+ <script type="text/javascript" src="js/debug/ui/swmui.js"></script>-->
+ <script type="text/javascript" src="js/qwebirc.js"></script>
+ <script type="text/javascript" src="js/swmui.js"></script>
+ <script type="text/javascript">
+ window.addEvent("domready", function() {
+ var theme = new Theme();
+ var ui = new SWMUI($("ircui"), theme);
+
+ var IRC = new IRCClient({nickname: "mcgoogle"}, ui);
+ IRC.connect();
+
+ });
+ </script>
+</head>
+<body>
+ <div id="ircui"></div>
+</body>
</html>
\ No newline at end of file
-<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\r
-"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
-<head>\r
- <title>QuakeNet Web IRC</title>\r
- <link rel="stylesheet" href="css/colours.css" type="text/css">\r
- <link rel="stylesheet" href="css/uglyui.css" type="text/css">\r
- <script type="text/javascript" src="js/mootools-1.2-core.js"></script>\r
- <!--<script type="text/javascript" src="js/debug/version.js"></script>\r
- <script type="text/javascript" src="js/debug/jslib.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/ircconnection.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/irclib.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/baseirc.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/irctracker.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/commandparser.js"></script>\r
- <script type="text/javascript" src="js/debug/irc/ircclient.js"></script>\r
- <script type="text/javascript" src="js/debug/ui/baseui.js"></script>\r
- <script type="text/javascript" src="js/debug/ui/colour.js"></script>\r
- <script type="text/javascript" src="js/debug/ui/theme.js"></script>\r
- <script type="text/javascript" src="js/debug/ui/uglyui.js"></script>-->\r
- <script type="text/javascript" src="js/qwebirc.js"></script>\r
- <script type="text/javascript" src="js/uglyui.js"></script>\r
- <script type="text/javascript"> \r
- window.addEvent("domready", function() {\r
- var theme = new Theme();\r
- var ui = new UglyUI($("ircui"), theme);\r
-\r
- var IRC = new IRCClient({nickname: "mcgoogle"}, ui);\r
- IRC.connect();\r
- });\r
- </script>\r
-</head>\r
-<body>\r
- <div id="ircui"></div>\r
-</body>\r
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+ <title>QuakeNet Web IRC</title>
+ <link rel="stylesheet" href="css/colours.css" type="text/css">
+ <link rel="stylesheet" href="css/uglyui.css" type="text/css">
+ <script type="text/javascript" src="js/mootools-1.2-core.js"></script>
+ <!--<script type="text/javascript" src="js/debug/version.js"></script>
+ <script type="text/javascript" src="js/debug/jslib.js"></script>
+ <script type="text/javascript" src="js/debug/irc/ircconnection.js"></script>
+ <script type="text/javascript" src="js/debug/irc/irclib.js"></script>
+ <script type="text/javascript" src="js/debug/irc/baseirc.js"></script>
+ <script type="text/javascript" src="js/debug/irc/irctracker.js"></script>
+ <script type="text/javascript" src="js/debug/irc/commandparser.js"></script>
+ <script type="text/javascript" src="js/debug/irc/ircclient.js"></script>
+ <script type="text/javascript" src="js/debug/ui/baseui.js"></script>
+ <script type="text/javascript" src="js/debug/ui/colour.js"></script>
+ <script type="text/javascript" src="js/debug/ui/theme.js"></script>
+ <script type="text/javascript" src="js/debug/ui/uglyui.js"></script>-->
+ <script type="text/javascript" src="js/qwebirc.js"></script>
+ <script type="text/javascript" src="js/uglyui.js"></script>
+ <script type="text/javascript">
+ window.addEvent("domready", function() {
+ var theme = new Theme();
+ var ui = new UglyUI($("ircui"), theme);
+
+ var IRC = new IRCClient({nickname: "mcgoogle"}, ui);
+ IRC.connect();
+ });
+ </script>
+</head>
+<body>
+ <div id="ircui"></div>
+</body>
</html>
\ No newline at end of file
-from zope.interface import implements\r
-\r
-from twisted.python import usage\r
-from twisted.internet import task\r
-from twisted.plugin import IPlugin\r
-from twisted.application.service import IServiceMaker\r
-from twisted.application import internet, strports\r
-from twisted.web import static, server\r
-\r
-from qwebirc import RootSite\r
-\r
-class Options(usage.Options):\r
- optParameters = [["port", "p", "9090","Port to start the server on."],\r
- ["logfile", "l", None, "Path to web CLF (Combined Log Format) log file."],\r
- ["https", None, None, "Port to listen on for Secure HTTP."],\r
- ["certificate", "c", "server.pem", "SSL certificate to use for HTTPS. "],\r
- ["privkey", "k", "server.pem", "SSL certificate to use for HTTPS."],\r
- ["staticpath", "s", "static", "Path to static content"],\r
- ]\r
-\r
- optFlags = [["notracebacks", "n", "Display tracebacks in broken web pages. " +\r
- "Displaying tracebacks to users may be security risk!"],\r
- ]\r
- \r
- zsh_actions = {"logfile" : "_files -g '*.log'", "certificate" : "_files -g '*.pem'",\r
- "privkey" : "_files -g '*.pem'"} \r
-\r
- def postOptions(self):\r
- if self['https']:\r
- try:\r
- from twisted.internet.ssl import DefaultOpenSSLContextFactory\r
- except ImportError:\r
- raise usage.UsageError("SSL support not installed")\r
- \r
-class QWebIRCServiceMaker(object):\r
- implements(IServiceMaker, IPlugin)\r
- tapname = "qwebirc"\r
- description = "QuakeNet web-based IRC client"\r
- options = Options\r
-\r
- \r
- def makeService(self, config):\r
- if config['logfile']:\r
- site = RootSite(config['staticpath'], logPath=config['logfile'])\r
- else:\r
- site = RootSite(config['staticpath'])\r
- \r
- \r
- site.displayTracebacks = not config["notracebacks"]\r
- if config['https']:\r
- from twisted.internet.ssl import DefaultOpenSSLContextFactory\r
- i = internet.SSLServer(int(config['https']), site, DefaultOpenSSLContextFactory(config['privkey'], config['certificate']))\r
- else:\r
- i = internet.TCPServer(int(config['port']), site)\r
- \r
- return i\r
- \r
+from zope.interface import implements
+
+from twisted.python import usage
+from twisted.internet import task
+from twisted.plugin import IPlugin
+from twisted.application.service import IServiceMaker
+from twisted.application import internet, strports
+from twisted.web import static, server
+
+from qwebirc import RootSite
+
+class Options(usage.Options):
+ optParameters = [["port", "p", "9090","Port to start the server on."],
+ ["logfile", "l", None, "Path to web CLF (Combined Log Format) log file."],
+ ["https", None, None, "Port to listen on for Secure HTTP."],
+ ["certificate", "c", "server.pem", "SSL certificate to use for HTTPS. "],
+ ["privkey", "k", "server.pem", "SSL certificate to use for HTTPS."],
+ ["staticpath", "s", "static", "Path to static content"],
+ ]
+
+ optFlags = [["notracebacks", "n", "Display tracebacks in broken web pages. " +
+ "Displaying tracebacks to users may be security risk!"],
+ ]
+
+ zsh_actions = {"logfile" : "_files -g '*.log'", "certificate" : "_files -g '*.pem'",
+ "privkey" : "_files -g '*.pem'"}
+
+ def postOptions(self):
+ if self['https']:
+ try:
+ from twisted.internet.ssl import DefaultOpenSSLContextFactory
+ except ImportError:
+ raise usage.UsageError("SSL support not installed")
+
+class QWebIRCServiceMaker(object):
+ implements(IServiceMaker, IPlugin)
+ tapname = "qwebirc"
+ description = "QuakeNet web-based IRC client"
+ options = Options
+
+
+ def makeService(self, config):
+ if config['logfile']:
+ site = RootSite(config['staticpath'], logPath=config['logfile'])
+ else:
+ site = RootSite(config['staticpath'])
+
+
+ site.displayTracebacks = not config["notracebacks"]
+ if config['https']:
+ from twisted.internet.ssl import DefaultOpenSSLContextFactory
+ i = internet.SSLServer(int(config['https']), site, DefaultOpenSSLContextFactory(config['privkey'], config['certificate']))
+ else:
+ i = internet.TCPServer(int(config['port']), site)
+
+ return i
+
serviceMaker = QWebIRCServiceMaker()
\ No newline at end of file