]> jfr.im git - irc/quakenet/qwebirc.git/commitdiff
Lots of new stuff.
authorChris Porter <redacted>
Sat, 14 Jun 2008 15:35:25 +0000 (16:35 +0100)
committerChris Porter <redacted>
Sat, 14 Jun 2008 15:35:25 +0000 (16:35 +0100)
static/css/colours.css [new file with mode: 0644]
static/js/irc/baseirc.js
static/js/irc/ircclient.js
static/js/jslib.js
static/js/ui/basetheme.js [new file with mode: 0644]
static/js/ui/colour.js [new file with mode: 0644]
static/js/ui/theme.js [new file with mode: 0644]
static/js/ui/uglyui.js
static/uitest.html

diff --git a/static/css/colours.css b/static/css/colours.css
new file mode 100644 (file)
index 0000000..5b46551
--- /dev/null
@@ -0,0 +1,102 @@
+.Xc0 {\r
+  color: white;\r
+}\r
+.Xc1 {\r
+  color: black;\r
+}\r
+.Xc2 {\r
+  color: darkBlue;\r
+}\r
+.Xc3 {\r
+  color: darkGreen;\r
+}\r
+.Xc4 {\r
+  color: red;\r
+}\r
+.Xc5 {\r
+  color: darkRed;\r
+}\r
+.Xc6 {\r
+  color: purple;\r
+}\r
+.Xc7 {\r
+  color: orange;\r
+}\r
+.Xc8 {\r
+  color: yellow;\r
+}\r
+.Xc9 {\r
+  color: green;\r
+}\r
+.Xc10 {\r
+  color: teal;\r
+}\r
+.Xc11 {\r
+  color: cyan;\r
+}\r
+.Xc12 {\r
+  color: blue;\r
+}\r
+.Xc13 {\r
+  color: fuchsia;\r
+}\r
+.Xc14 {\r
+  color: darkGray;\r
+}\r
+.Xc15 {\r
+  color: gray;\r
+}\r
+.Xbc0 {\r
+  background-color: white;\r
+}\r
+.Xbc1 {\r
+  background-color: black;\r
+}\r
+.Xbc2 {\r
+  background-color: darkBlue;\r
+}\r
+.Xbc3 {\r
+  background-color: darkGreen;\r
+}\r
+.Xbc4 {\r
+  background-color: red;\r
+}\r
+.Xbc5 {\r
+  background-color: darkRed;\r
+}\r
+.Xbc6 {\r
+  background-color: purple;\r
+}\r
+.Xbc7 {\r
+  background-color: orange;\r
+}\r
+.Xbc8 {\r
+  background-color: yellow;\r
+}\r
+.Xbc9 {\r
+  background-color: green;\r
+}\r
+.Xbc10 {\r
+  background-color: teal;\r
+}\r
+.Xbc11 {\r
+  background-color: cyan;\r
+}\r
+.Xbc12 {\r
+  background-color: blue;\r
+}\r
+.Xbc13 {\r
+  background-color: fuchsia;\r
+}\r
+.Xbc14 {\r
+  background-color: darkGray;\r
+}\r
+.Xbc15 {\r
+  background-color: gray;\r
+}\r
+.Xb {\r
+  font-weight: bold;\r
+}\r
+.Xu {\r
+  text-decoration: underline;\r
+}\r
index fbc2d3b99547f734f97b7e3a8671c7de5e060a6a..51fd3617fe701391766d0f5db22853fa67878eb8 100644 (file)
@@ -5,6 +5,7 @@ function BaseIRCClient(nickname, view) {
   this.nickname = nickname;\r
   this.signedOn = false;\r
   this.pmodes = ["b", "k,", "o", "l", "v"];\r
+  this.channels = {}\r
   \r
   /* attempt javascript inheritence! */\r
   this.dispatch = function(data) {\r
@@ -83,7 +84,10 @@ function BaseIRCClient(nickname, view) {
     var user = prefix;\r
     var channel = params[0];\r
     var message = params[1];\r
+    var nick = hosttonick(user);\r
     \r
+    if((nick == self.nickname) && self.channels[channel])\r
+      delete self.channels[channel];\r
     view.userPart(user, channel, message);\r
     \r
     return true;\r
@@ -95,6 +99,8 @@ function BaseIRCClient(nickname, view) {
     var kickee = params[1];\r
     var message = params[2];\r
     \r
+    if((kickee == self.nickname) && self.channels[channel])\r
+      delete self.channels[channel];\r
     view.userKicked(kicker, channel, kickee, message);\r
     \r
     return true;\r
@@ -109,7 +115,11 @@ function BaseIRCClient(nickname, view) {
   this.irc_JOIN = function(prefix, params) {\r
     var channel = params[0];\r
     var user = prefix;\r
-\r
+    var nick = hosttonick(user);\r
+    \r
+    if(nick == self.nickname)\r
+      self.channels[channel] = true;\r
+      \r
     view.userJoined(user, channel);\r
     \r
     return true;\r
@@ -251,8 +261,10 @@ function BaseIRCClient(nickname, view) {
     var channel = params[1];\r
     var topic = ANI(params, -1);\r
     \r
-    view.initialTopic(channel, topic);\r
-    return true;\r
+    if(self.channels[channel]) {\r
+      view.initialTopic(channel, topic);\r
+      return true;\r
+    }\r
   }\r
   \r
   this.irc_RPL_TOPICWHOTIME = function(prefix, params) {\r
index 1cee0072b10da99c53f05b1636c966e3684bf066..46e3173750f35743a720dd6df8b9815cfd156ef8 100644 (file)
@@ -3,14 +3,36 @@ function IRCClient(nickname, ui) {
   this.prefixes = "@+";\r
   this.modeprefixes = "ov";\r
   \r
+  newLine = function(window, type, data) {\r
+    if(!data)\r
+      data = {};\r
+      \r
+    ui.newLine(window, type, data);\r
+  }\r
+  \r
+  newChanLine = function(channel, type, user, extra) {\r
+    if(!extra)\r
+      extra = {};\r
+\r
+    extra["n"] = hosttonick(user);\r
+    extra["h"] = hosttohost(user);\r
+    extra["c"] = channel;\r
+    \r
+    newLine(channel, type, extra);\r
+  }\r
+  \r
+  newServerLine = function(type, data) {\r
+    newLine("", type, data);\r
+  }\r
+  \r
   this.rawNumeric = function(numeric, prefix, params) {\r
-    ui.newLine("", params.slice(1));\r
+    newServerLine("RAW", {"n": "numeric", "m": params.slice(1).join(" ")});\r
   }\r
   \r
   this.signedOn = function(nickname) {\r
     self.tracker = new IRCTracker();\r
     self.nickname = nickname;\r
-    ui.newLine("", "Signed on!");\r
+    newServerLine("SIGNON");\r
   }\r
 \r
   this.updateNickList = function(channel) {\r
@@ -49,11 +71,12 @@ function IRCClient(nickname, ui) {
     var host = hosttohost(user);\r
     \r
     if(nick == self.nickname) {\r
-      /* */\r
+      ui.newWindow(channel, true);\r
+      ui.selectTab(channel);\r
     }\r
     self.tracker.addNickToChannel(nick, channel);\r
 \r
-    ui.newLine(channel, "== " + nick + " [" + host + "] has joined " + channel);\r
+    newChanLine(channel, "JOIN", user);\r
     \r
     self.updateNickList(channel);\r
   }\r
@@ -68,21 +91,27 @@ function IRCClient(nickname, ui) {
       self.tracker.removeNickFromChannel(nick, channel);\r
     }\r
     \r
-    ui.newLine(channel, "== " + nick + " [" + host + "] left " + channel);\r
-    \r
+    if(!message)\r
+      message = "";\r
+    newChanLine(channel, "PART", user, {"m": message});\r
     self.updateNickList(channel);\r
+    \r
+    if(nick == self.nickname)\r
+      ui.closeWindow(channel);      \r
   }\r
 \r
   this.userKicked = function(kicker, channel, kickee, message) {\r
     if(kickee == self.nickname) {\r
       self.tracker.removeChannel(channel);\r
+      ui.closeWindow(channel);\r
     } else {\r
       self.tracker.removeNickFromChannel(kickee, channel);\r
+      self.updateNickList(channel);\r
     }\r
-    \r
-    var kickernick = hosttonick(kicker);\r
-    ui.newLine(channel, "== " + kickee + " was kicked from " + channel + " by " + kickernick + " [" + message + "]");\r
-    self.updateNickList(channel);\r
+    if(!message)\r
+      message = "";\r
+      \r
+    newChanLine(channel, "KICK", kicker, {"v": kickee, "m": message});\r
   }\r
   \r
   this.channelMode = function(user, channel, modes, raw) {\r
@@ -104,30 +133,27 @@ function IRCClient(nickname, ui) {
         self.addPrefix(nc, prefixchar);\r
       }\r
     });\r
-    \r
-    var nick = hosttonick(user);\r
-    \r
-    ui.newLine(channel, "== mode/" + channel + " [" + raw.join(" ") + "] by " + nick);\r
+\r
+    newChanLine(channel, "MODE", user, {"m": raw.join(" ")});\r
     \r
     self.updateNickList(channel);\r
   }\r
 \r
   this.userQuit = function(user, message) {\r
     var nick = hosttonick(user);\r
-    var host = hosttohost(user);\r
     \r
     var channels = self.tracker.getNick(nick);\r
     \r
     var clist = [];\r
     for(var c in channels) {\r
       clist.push(c);\r
-      ui.newLine(c, "== " + nick + " [" + host + "] has quit [" + message + "]");\r
+      newChanLine(c, "QUIT", user);\r
     }\r
     \r
     self.tracker.removeNick(nick);\r
     \r
     forEach(clist, function(cli) {\r
-      this.updateNickList(cli);\r
+      self.updateNickList(cli);\r
     });\r
   }\r
 \r
@@ -142,15 +168,14 @@ function IRCClient(nickname, ui) {
     var channels = self.tracker.getNick(newnick);\r
     \r
     for(var c in channels) {\r
-      ui.newLine(c, "* " + oldnick + " changed nick to " + newnick);\r
-      this.updateNickList(c);\r
+      newChanLine(c, "NICK", user, {"w": newnick});\r
+      /* TODO: rename queries */\r
+      self.updateNickList(c);\r
     }\r
   }\r
   \r
   this.channelTopic = function(user, channel, topic) {\r
-    var nick = hosttonick(user);\r
-    \r
-    ui.newLine(channel, "== " + nick + " changed the topic of " + channel + " to: " + topic);\r
+    newChanLine(channel, "TOPIC", user, {"m": topic});    \r
     ui.updateTopic(channel, topic);\r
   }\r
   \r
@@ -159,37 +184,41 @@ function IRCClient(nickname, ui) {
   }\r
   \r
   this.channelPrivmsg = function(user, channel, message) {\r
-    var nick = hosttonick(user);\r
-    \r
-    ui.newLine(channel, "<" + nick + "> " + message);\r
+    newChanLine(channel, "CHANMSG", user, {"m": message});\r
   }\r
 \r
   this.channelNotice = function(user, channel, message) {\r
-    var nick = hosttonick(user);\r
-    ui.newLine(channel, "-" + nick + "- " + message);\r
+    newChanLine(channel, "CHANNOTICE", user, {"m": message});\r
   }\r
 \r
   this.userPrivmsg = function(user, message) {\r
     var nick = hosttonick(user);\r
-    \r
-    ui.newLine("", "*" + nick + "* " + message);\r
+    var host = hosttohost(user);\r
+\r
+    ui.newWindow(nick, false);\r
+    newLine(nick, "PRIVMSG", {"m": message, "h": host, "n": nick});\r
   }\r
   \r
   this.serverNotice = function(message) {\r
-    ui.newLine("", "-server- " + message);\r
+    newServerLine("SERVERNOTICE", {"m": message});\r
   }\r
   \r
   this.userNotice = function(user, message) {\r
-    ui.newLine("", "-(" + user + ")- " + message);\r
+    var nick = hosttonick(user);\r
+    var host = hosttohost(user);\r
+\r
+    newServerLine("NOTICE", {"m": message, "h": host, "n": nick});\r
   }\r
   \r
   this.userInvite = function(user, channel) {\r
     var nick = hosttonick(user);\r
-    ui.newLine("", "* " + nick + " invites you to join " + channel);\r
+    var host = hosttohost(user);\r
+\r
+    newServerLine("INVITE", {"c": channel, "h": host, "n": nick});\r
   }\r
   \r
   this.userMode = function(modes) {\r
-    ui.newLine("", "MODE " + self.nickname + " " + modes);\r
+    newServerLine("UMODE", {"m": modes, "n": self.nickname});\r
   }\r
   \r
   this.addPrefix = function(nickchanentry, prefix) {\r
@@ -208,7 +237,7 @@ function IRCClient(nickname, ui) {
   }\r
   \r
   this.removePrefix = function(nickchanentry, prefix) {\r
-    nickchanentry.prefixes = nickchanentry.prefixes.replace(prefix, "");\r
+    nickchanentry.prefixes = nickchanentry.prefixes.replaceAll(prefix, "");\r
   }\r
 \r
   this.channelNames = function(channel, names) {\r
@@ -242,7 +271,7 @@ function IRCClient(nickname, ui) {
   this.disconnected = function() {\r
     self.tracker = undefined;\r
     \r
-    ui.newLine("", "== Disconnected");\r
+    newServerLine("DISCONNECT");\r
     self.disconnect();\r
   }\r
   \r
@@ -256,11 +285,11 @@ function IRCClient(nickname, ui) {
   }\r
   \r
   this.connected = function() {\r
-    ui.newLine("", "== Connected!");\r
+    newServerLine("CONNECT");\r
   }\r
   \r
   this.serverError = function(message) {\r
-    ui.newLine("", "== ERROR: " + message);\r
+    newServerLine("ERROR", {"m": message});\r
   }\r
   \r
   this.parent = new BaseIRCClient(nickname, this);\r
index 11b7c70c598312c27dccb97c13084372fd5ec6fc..5742b034759540adab655118c87e3b5dedcb481d 100644 (file)
@@ -40,4 +40,16 @@ var forEach = function(x, fn) {
   for(var i=0;i<x.length;i++)\r
     if(fn(x[i]))\r
       return;\r
-}
\ No newline at end of file
+}\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
diff --git a/static/js/ui/basetheme.js b/static/js/ui/basetheme.js
new file mode 100644 (file)
index 0000000..79e991e
--- /dev/null
@@ -0,0 +1,78 @@
+/* don't even attempt to use a $! */\r
+var DefaultTheme = {\r
+  "PREFIX": [\r
+    "$C4==$O "\r
+  ],\r
+  "SIGNON": [\r
+    "Signed on!",\r
+    true\r
+  ],\r
+  "CONNECT": [\r
+    "Connected to server.",\r
+    true\r
+  ],\r
+  "RAW": [\r
+    "$m",\r
+    true\r
+  ],\r
+  "DISCONNECT": [\r
+    "Disconnected from server.",\r
+    true\r
+  ],\r
+  "ERROR": [\r
+    "ERROR: $m",\r
+    true\r
+  ],\r
+  "SERVERNOTICE": [\r
+    "$m",\r
+    true\r
+  ],\r
+  "JOIN": [\r
+    "$n [$h] has joined $c",\r
+    true\r
+  ],\r
+  "PART": [\r
+    "$n [$h] has left $c [$m]",\r
+    true\r
+  ],\r
+  "KICK": [\r
+    "$v was kicked from $c by $n [$m]",\r
+    true\r
+  ],\r
+  "MODE": [\r
+    "mode/$c [$m] by $n",\r
+    true\r
+  ],\r
+  "QUIT": [\r
+    "$n [$h] has quit [$m]",\r
+    true\r
+  ],\r
+  "NICK": [\r
+    "$n has changed nick to $w",\r
+    true\r
+  ],\r
+  "TOPIC": [\r
+    "$n changed the topic of $c to: $m",\r
+    true\r
+  ],\r
+  "UMODE": [\r
+    "MODE $n $m",\r
+    true\r
+  ],\r
+  "INVITE": [\r
+    "$n invites you to join $c",\r
+    true\r
+  ],\r
+  "CHANMSG": [\r
+    "<$n> $m"\r
+  ],\r
+  "PRIVMSG": [\r
+    "<$n> $m"\r
+  ],\r
+  "CHANNOTICE": [\r
+    "-$n:$c- $m"\r
+  ],\r
+  "NOTICE": [\r
+    "-$n- $m"\r
+  ]\r
+}\r
diff --git a/static/js/ui/colour.js b/static/js/ui/colour.js
new file mode 100644 (file)
index 0000000..460e98f
--- /dev/null
@@ -0,0 +1,93 @@
+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
+  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 = xline[i] + xline[i + 1];\r
+      i++;\r
+    } else {\r
+      fg = 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 = xline[i] + xline[i + 1];\r
+      i++;\r
+    } else {\r
+      bg = xline[i];\r
+    }\r
+    return i;\r
+  }\r
+\r
+  function ac() {\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 pc() {\r
+    classes = []\r
+    if(fg)\r
+      classes.push("Xc" + fg);\r
+    if(bg)\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
+      ac();\r
+\r
+      bold = !bold;\r
+      pc();\r
+    } else if(lc == "\x1F") {\r
+      ac();\r
+\r
+      underline = !underline;\r
+      pc();\r
+    } else if(lc == "\x0F") {\r
+      ac();\r
+      fg = undefined;\r
+      bg = undefined;\r
+      underline = false;\r
+      bold = false;\r
+    } else if(lc == "\x03") {\r
+      ac();\r
+      \r
+      i = parsecolours(xline, i);\r
+      pc();\r
+    } else {\r
+      out.push(lc);\r
+    }\r
+  }\r
+  \r
+  ac();\r
+}
\ No newline at end of file
diff --git a/static/js/ui/theme.js b/static/js/ui/theme.js
new file mode 100644 (file)
index 0000000..21f1355
--- /dev/null
@@ -0,0 +1,64 @@
+var ThemeControlCodeMap = {\r
+  "C": "\x03",\r
+  "B": "\x02",\r
+  "U": "\x1F",\r
+  "O": "\x0F",\r
+  "$": "$"\r
+};\r
+\r
+function Theme(values) {\r
+  var theme = {};\r
+  for(var k in DefaultTheme)\r
+    theme[k] = DefaultTheme[k];\r
+  \r
+  if(values)\r
+    for(var k in values)\r
+      theme[k] = values[k];\r
+      \r
+  function preprocess(line, useprefix) {\r
+    if(useprefix)\r
+      return theme["PREFIX"] + line;\r
+      \r
+    return line;\r
+  }\r
+  \r
+  for(var k in theme) {\r
+    if(k == "PREFIX")\r
+      continue;\r
+    var data = theme[k];\r
+    \r
+    theme[k] = preprocess(data[0], data[1]);\r
+  }\r
+  \r
+  var dollarReplace = function(x, h) {\r
+    var msg = [];\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
+            o = c;\r
+        }\r
+        msg.push(o);\r
+      } else {\r
+        msg.push(c);\r
+      }\r
+    }\r
+    \r
+    return msg.join("");\r
+  }\r
+  \r
+  this.message = function(type, data) {\r
+    var msg = theme[type];\r
+    \r
+    //msg = msg.replace("$C", "\x03").replace("$B", "\x02").replace("$U", "\x1F").replace("$O", "\x0F");\r
+    msg = dollarReplace(msg, data);\r
+\r
+    return msg;\r
+  }\r
+}\r
index 64a5ab51ac214d20e556f0f3f82a31010c63c074..d0319798716a2c3e6511cdf3d029c401b9d8a944 100644 (file)
@@ -1,4 +1,4 @@
-function UglyUI(parent) {\r
+function UglyUI(parent, theme) {\r
   var self = this;\r
   var active;\r
   \r
@@ -22,14 +22,18 @@ function UglyUI(parent) {
   form.appendChild(inputbox);\r
   inputbox.focus();\r
 \r
-  this.newWindow = function(windowname, displayname) {\r
-    var container = new Element("div", { "styles": { "display": "none" } });\r
+  this.newWindow = function(windowname, ischannel, displayname) {\r
+    var o = tabhash[windowname];\r
+    if(o)\r
+      return o;\r
+      \r
+    var container = new Element("div", { "styles": { "display": "none", "font-family": "Lucida Console" } });\r
     window.appendChild(container);\r
     \r
     var nicklist;\r
     var topic;\r
     \r
-    if(windowname != "") {\r
+    if(ischannel) {\r
       nicklist = new Element("div", {"styles": { "border-left": "1px solid black", "width": "125px", "float": "right", "height": "480px", "clear": "both", "overflow": "auto", "background": "white"} });\r
       container.appendChild(nicklist);\r
     }\r
@@ -37,7 +41,7 @@ function UglyUI(parent) {
     var x = new Element("div", {"styles": { "height": "480px" }});\r
     container.appendChild(x);\r
 \r
-    if(windowname != "") {\r
+    if(ischannel) {\r
       topic = new Element("div", {"styles": { "background": "#fef", "height": "20px" } });\r
       x.appendChild(topic);      \r
     }\r
@@ -56,15 +60,25 @@ function UglyUI(parent) {
     });\r
     tabs.appendChild(tab);\r
     \r
+    if(windowname != "") {\r
+      var tabclose = new Element("span", {"styles": { "border": "1px black solid" } });\r
+      tabclose.addEvent("click", function() {\r
+        if(ischannel)\r
+          self.send("PART " + windowname);\r
+        self.closeWindow(windowname);\r
+      });\r
+      tabclose.setText("X");\r
+      tab.appendChild(tabclose);\r
+    }\r
     tabhash[windowname] = { "container": container, "tab": tab, "element": e, "lastcolour": false, "nicklist": nicklist, "topic": topic };\r
     \r
-    self.selectTab(windowname);\r
-    \r
     return tabhash[windowname];\r
   }\r
   \r
   this.updateNickList = function(windowname, nicks) {\r
     var w = tabhash[windowname];\r
+    if(!w)\r
+      return;\r
     var n = w.nicklist;\r
     \r
     while(n.firstChild)\r
@@ -79,12 +93,15 @@ function UglyUI(parent) {
   \r
   this.updateTopic = function(windowname, topic) {\r
     var w = tabhash[windowname];\r
+    if(!w)\r
+      return;\r
+      \r
     var t = w.topic;\r
     \r
     while(t.firstChild)\r
       t.removeChild(t.firstChild);\r
 \r
-    t.appendChild(document.createTextNode(topic));\r
+    colourise(topic, t);\r
   }\r
   \r
   this.selectTab = function(windowname) {\r
@@ -100,21 +117,29 @@ function UglyUI(parent) {
     self.active = windowname;\r
   }\r
   \r
-  this.newLine = function(windowname, line) {\r
+  this.newLine = function(windowname,  type, line, colour) {\r
     var window = tabhash[windowname];\r
-    if(!window)\r
-      window = this.newWindow(windowname);\r
+    if(!window) {\r
+      window = tabhash[""];\r
+      windowname = "";\r
+    }\r
     \r
     var wx = window;\r
     window = window.element;\r
-    if(wx.lastcolour) {\r
+    var c;\r
+    if(colour) {\r
+      c = colour;\r
+    } else if(wx.lastcolour) {\r
       c = "#efefef";\r
     } else {\r
       c = "#eeffff";\r
     }\r
     \r
     var e = new Element("div", { "styles": { "background": c } });\r
-    e.appendText(line);\r
+    if(type)\r
+      line = theme.message(type, line);\r
+    \r
+    colourise(line, e);\r
     \r
     wx.lastcolour = !wx.lastcolour;\r
     window.appendChild(e);\r
@@ -122,4 +147,16 @@ function UglyUI(parent) {
     if(windowname != self.active)\r
       wx.tab.setStyle("color", "red");\r
   }\r
+  \r
+  this.closeWindow = function(windowname) {\r
+    var w = tabhash[windowname];\r
+    if(!w)\r
+      return;\r
+    \r
+    window.removeChild(w.container);\r
+    tabs.removeChild(w.tab);\r
+    self.selectTab("");\r
+    \r
+    delete tabhash[windowname];\r
+  }\r
 }\r
index 28948cc3eb2edeee6385bb4800ee98ab949c7db9..68a9891040283454438b93104baf907b60ec4936 100644 (file)
@@ -1,10 +1,13 @@
 <?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
-<html>\r
 <head>\r
+  <link rel="stylesheet" href="css/colours.css" type="text/css">\r
   <script src="js/mootools-release-1.11.js" type="text/javascript"></script>\r
   <script type="text/javascript" src="js/jslib.js"></script>\r
+  <script type="text/javascript" src="js/ui/colour.js"></script>\r
+  <script type="text/javascript" src="js/ui/basetheme.js"></script>\r
+  <script type="text/javascript" src="js/ui/theme.js"></script>\r
   <script type="text/javascript" src="js/ui/uglyui.js"></script>\r
   <script type="text/javascript" src="js/tcp.js"></script>\r
   <script type="text/javascript" src="js/irc/irclib.js"></script>\r
     }\r
     \r
     window.addEvent("domready", function() {\r
-      ui = new UglyUI($("ircui"));\r
-      ui.newWindow("", "Status");\r
+      var theme = new Theme();\r
+      ui = new UglyUI($("ircui"), theme);\r
       \r
+      ui.newWindow("", false, "Status");\r
+      ui.newLine("", "", "Welcome to QuakeNet webIRC", "#f99");\r
+      ui.selectTab("");\r
+\r
       var IRC = new IRCClient(prompt("Nickname","moofishaax"), ui);\r
       IRC.connect();\r
     });\r