From: Chris Porter Date: Thu, 19 Jun 2008 19:47:42 +0000 (+0100) Subject: Dos2Unix X-Git-Url: https://jfr.im/git/irc/quakenet/qwebirc.git/commitdiff_plain/9e769c12bfb7ac3beafbcfee9604f8aadcd8f2ca?hp=0019128d23892af53330295b65db0ecebe8135a0 Dos2Unix --- diff --git a/TODO.txt b/TODO.txt index 39c9325..1b61349 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,8 +1,8 @@ -TODO: - - isp transparent proxy issue - - new UI - - connect UI (do with newUI?) - - better error handling server side - - better error handling client side - - +TODO: + - isp transparent proxy issue + - tidy up UI + - connect UI (do with newUI?) + - better error handling server side + - better error handling client side + + diff --git a/js/copyright.js b/js/copyright.js index 21b9828..642bd83 100644 --- a/js/copyright.js +++ b/js/copyright.js @@ -1,2 +1,2 @@ -/* qwebirc -- Copyright (C) 2008 Chris Porter --- All rights reserved. */ - +/* qwebirc -- Copyright (C) 2008 Chris Porter --- All rights reserved. */ + diff --git a/js/irc/baseirc.js b/js/irc/baseirc.js index 29184ed..46e51bd 100644 --- a/js/irc/baseirc.js +++ b/js/irc/baseirc.js @@ -1,314 +1,314 @@ -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 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 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 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); + }], +}); diff --git a/js/irc/ircclient.js b/js/irc/ircclient.js index 2c8d822..e974a96 100644 --- a/js/irc/ircclient.js +++ b/js/irc/ircclient.js @@ -1,364 +1,364 @@ -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 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', '?', -/* '@'-'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', '?', +/* '@'-'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 -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; -} +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; +} diff --git a/js/ui/basetheme.js b/js/ui/basetheme.js index 80ab6cc..e81a92e 100644 --- a/js/ui/basetheme.js +++ b/js/ui/basetheme.js @@ -1,39 +1,39 @@ -/* 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"] -} +/* 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"] +} diff --git a/js/ui/baseui.js b/js/ui/baseui.js index 02a1d9a..4769cc6 100644 --- a/js/ui/baseui.js +++ b/js/ui/baseui.js @@ -1,93 +1,93 @@ -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]; - } -}); +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]; + } +}); diff --git a/js/ui/colour.js b/js/ui/colour.js index 47daba7..3bd29ea 100644 --- a/js/ui/colour.js +++ b/js/ui/colour.js @@ -1,103 +1,103 @@ -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 15) - bg = undefined; - if(fg > 15) - fg = undefined; - - emitStartToken(); - } else { - out.push(lc); - } - } - - emitEndToken(); +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 15) + bg = undefined; + if(fg > 15) + fg = undefined; + + emitStartToken(); + } else { + out.push(lc); + } + } + + emitEndToken(); } \ No newline at end of file diff --git a/js/ui/swmlayout.js b/js/ui/swmlayout.js index edd33be..17a0e31 100644 --- a/js/ui/swmlayout.js +++ b/js/ui/swmlayout.js @@ -1,106 +1,106 @@ -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 $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 $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 - -