]> jfr.im git - irc/quakenet/qwebirc.git/blobdiff - js/ui/baseui.js
use home-made string hashset/map instead of js default
[irc/quakenet/qwebirc.git] / js / ui / baseui.js
index d91d5ffa55448c6f5b8f2c0ede435750b047b429..582a49021c1a4d6ac1cc2efd5d7e73b93d2bb02b 100644 (file)
@@ -3,7 +3,7 @@ qwebirc.ui.WINDOW_QUERY =    0x02;
 qwebirc.ui.WINDOW_CHANNEL =  0x04;
 qwebirc.ui.WINDOW_CUSTOM =   0x08;
 qwebirc.ui.WINDOW_CONNECT =  0x10;
-qwebirc.ui.WINDOW_MESSAGES = 0x32;
+qwebirc.ui.WINDOW_MESSAGES = 0x20;
 
 qwebirc.ui.CUSTOM_CLIENT = "custom";
 
@@ -12,9 +12,9 @@ qwebirc.ui.BaseUI = new Class({
   initialize: function(parentElement, windowClass, uiName, options) {
     this.options = options;
     
-    this.windows = {};
-    this.clients = {};
-    this.windows[qwebirc.ui.CUSTOM_CLIENT] = {};
+    this.windows = new QHash();
+    this.clients = new QHash();
+    this.windows.put(qwebirc.ui.CUSTOM_CLIENT, new QHash());
     this.windowArray = [];
     this.windowClass = windowClass;
     this.parentElement = parentElement;
@@ -25,21 +25,43 @@ qwebirc.ui.BaseUI = new Class({
     this.clientId = 0;
     
     this.windowFocused = true;
-    window.addEvent("blur", function() { if(this.windowFocused) { this.windowFocused = false; this.focusChange(false); } }.bind(this));
-    window.addEvent("focus", function() { if(!this.windowFocused) { this.windowFocused = true; this.focusChange(true); } }.bind(this));
+
+    if(Browser.Engine.trident) {
+      var checkFocus = function() {
+        var hasFocus = document.hasFocus();
+        if(hasFocus != this.windowFocused) {
+          this.windowFocused = hasFocus;
+          this.focusChange(hasFocus);
+        }
+      }
+
+      checkFocus.periodical(100, this);
+    } else {
+      var blur = function() { if(this.windowFocused) { this.windowFocused = false; this.focusChange(false); } }.bind(this);
+      var focus = function() { if(!this.windowFocused) { this.windowFocused = true; this.focusChange(true); } }.bind(this);
+
+      /* firefox requires both */
+
+      document.addEvent("blur", blur);
+      window.addEvent("blur", blur);
+      document.addEvent("focus", focus);
+      window.addEvent("focus", focus);
+    }
   },
   newClient: function(client) {
-    client.id = this.clientId++;
+    client.id = String(this.clientId++);
     client.hilightController = new qwebirc.ui.HilightController(client);
-    
-    this.windows[client.id] = {}
-    this.clients[client.id] = client;
+    client.addEvent("signedOn", function() {
+      this.fireEvent("signedOn", client);
+    }.bind(this));
+    this.windows.put(client.id, new QHash());
+    this.clients.put(client.id, client);
     var w = this.newWindow(client, qwebirc.ui.WINDOW_STATUS, "Status");
     this.selectWindow(w);
     if(!this.firstClient) {
       this.firstClient = true;
       w.addLine("", "qwebirc v" + qwebirc.VERSION);
-      w.addLine("", "Copyright (C) 2008-2009 Chris Porter and the qwebirc project.");
+      w.addLine("", "Copyright (C) 2008-2014 Chris Porter and the qwebirc project.");
       w.addLine("", "http://www.qwebirc.org");
       w.addLine("", "Licensed under the GNU General Public License, Version 2.");
     }
@@ -69,13 +91,14 @@ qwebirc.ui.BaseUI = new Class({
       return w;
       
     var wId = this.getWindowIdentifier(client, type, name);
-    var w = this.windows[this.getClientId(client)][wId] = new this.windowClass(this, client, type, name, wId);
+    var w = new this.windowClass(this, client, type, name, wId);
+    this.windows.get(this.getClientId(client)).put(wId, w);
     this.windowArray.push(w);
     
     return w;
   },
   getWindow: function(client, type, name) {
-    var c = this.windows[this.getClientId(client)];
+    var c = this.windows.get(this.getClientId(client));
     if(!$defined(c))
       return null;
       
@@ -86,7 +109,7 @@ qwebirc.ui.BaseUI = new Class({
   },
   getActiveIRCWindow: function(client) {
     if(!this.active || this.active.type == qwebirc.ui.WINDOW_CUSTOM) {
-      return this.windows[this.getClientId(client)][this.getWindowIdentifier(client, qwebirc.ui.WINDOW_STATUS)];
+      return this.windows.get(this.getClientId(client)).get(this.getWindowIdentifier(client, qwebirc.ui.WINDOW_STATUS));
     } else {
       return this.active;
     }
@@ -94,6 +117,29 @@ qwebirc.ui.BaseUI = new Class({
   __setActiveWindow: function(window) {
     this.active = window;
   },
+  renameWindow: function(window, name) {
+    if(this.getWindow(window.client, window.type, name))
+      return null;
+    
+    var clientId = this.getClientId(window.client);
+    var index = this.windowArray.indexOf(window);
+    if(index == -1)
+      return null;
+    
+    this.windows.get(clientId).remove(window.identifier);
+    
+    var window = this.windowArray[index];
+    window.name = name;
+    window.identifier = this.getWindowIdentifier(window.client, window.type, window.name);
+    
+    this.windows.get(clientId).put(window.identifier, this.windowArray[index]);
+    
+    if(window.active)
+      this.updateTitle(window.name + " - " + this.options.appTitle);
+    
+    window.rename(window.name);
+    return window;
+  },
   selectWindow: function(window) {
     if(this.active)
       this.active.deselect();
@@ -144,7 +190,7 @@ qwebirc.ui.BaseUI = new Class({
     }
     
     this.windowArray = this.windowArray.erase(window);
-    delete this.windows[this.getClientId(window.client)][window.identifier];
+    this.windows.get(this.getClientId(window.client)).remove(window.identifier);
   },
     /*
       this shouldn't be called by overriding classes!
@@ -170,8 +216,17 @@ qwebirc.ui.StandardUI = new Class({
     this.parent(parentElement, windowClass, uiName, options);
 
     this.tabCompleter = new qwebirc.ui.TabCompleterFactory(this);
-    this.uiOptions = new qwebirc.ui.DefaultOptionsClass(this);
-    this.customWindows = {};
+    this.uiOptions = new qwebirc.ui.DefaultOptionsClass(this, options.uiOptionsArg);
+    this.customWindows = new QHash();
+    
+    this.__styleValues = {hue: this.uiOptions.STYLE_HUE, saturation: 0, lightness: 0};
+    if($defined(this.options.hue)) this.__styleValues.hue = this.options.hue;
+    if($defined(this.options.saturation)) this.__styleValues.saturation = this.options.saturation;
+    if($defined(this.options.lightness)) this.__styleValues.lightness = this.options.lightness;
+
+    if(this.options.thue !== null) this.__styleValues.textHue = this.options.thue;
+    if(this.options.tsaturation !== null) this.__styleValues.textSaturation = this.options.tsaturation;
+    if(this.options.tlightness !== null) this.__styleValues.textLightness = this.options.tlightness;
     
     var ev;
     if(Browser.Engine.trident) {
@@ -238,7 +293,7 @@ qwebirc.ui.StandardUI = new Class({
       
     var w = this.newWindow(qwebirc.ui.CUSTOM_CLIENT, type, name);
     w.addEvent("close", function(w) {
-      delete this.windows[qwebirc.ui.CUSTOM_CLIENT][w.identifier];
+      this.windows.get(qwebirc.ui.CUSTOM_CLIENT).remove(w.identifier);
     }.bind(this));
     
     if(select)
@@ -250,16 +305,16 @@ qwebirc.ui.StandardUI = new Class({
     if(!$defined(options))
       options = {};
       
-    if(this.customWindows[windowName]) {
-      this.selectWindow(this.customWindows[windowName]);
+    if(this.customWindows.contains(windowName)) {
+      this.selectWindow(this.customWindows.get(windowName));
       return;
     }
     
     var d = this.newCustomWindow(windowName, true);
-    this.customWindows[windowName] = d;
+    this.customWindows.put(windowName, d);
     
     d.addEvent("close", function() {
-      this.customWindows[windowName] = null;
+      this.customWindows.remove(windowName);
     }.bind(this));
         
     if(cssClass)
@@ -273,7 +328,9 @@ qwebirc.ui.StandardUI = new Class({
     d.setSubWindow(ew);
   },
   embeddedWindow: function() {
-    this.addCustomWindow("Embedding wizard", qwebirc.ui.EmbedWizard, "embeddedwizard", {baseURL: this.options.baseURL});
+    this.addCustomWindow("Add webchat to your site", qwebirc.ui.EmbedWizard, "embeddedwizard", {baseURL: this.options.baseURL, uiOptions: this.uiOptions, optionsCallback: function() {
+      this.optionsWindow();
+    }.bind(this)});
   },
   optionsWindow: function() {
     this.addCustomWindow("Options", qwebirc.ui.OptionsPane, "optionspane", this.uiOptions);
@@ -287,8 +344,8 @@ qwebirc.ui.StandardUI = new Class({
   feedbackWindow: function() {
     this.addCustomWindow("Feedback", qwebirc.ui.FeedbackPane, "feedbackpane", this.uiOptions);
   },
-  faqWindow: function() {
-    this.addCustomWindow("FAQ", qwebirc.ui.FAQPane, "faqpane", this.uiOptions);
+  helpWindow: function() {
+    this.addCustomWindow("Help!", qwebirc.ui.HelpPane, "helppane", this.uiOptions);
   },
   urlDispatcher: function(name, window) {
     if(name == "embedded")
@@ -300,8 +357,12 @@ qwebirc.ui.StandardUI = new Class({
     /* doesn't really belong here */
     if(name == "whois") {
       return ["span", function(nick) {
-        this.client.exec("/WHOIS " + nick);
-      }.bind(window)];
+        if(this.uiOptions.QUERY_ON_NICK_CLICK) {
+          window.client.exec("/QUERY " + nick);
+        } else {
+          window.client.exec("/WHOIS " + nick);
+        }
+      }.bind(this)];
     }
 
     return null;
@@ -311,6 +372,43 @@ qwebirc.ui.StandardUI = new Class({
   },
   resetTabComplete: function() {
     this.tabCompleter.reset();
+  },
+  setModifiableStylesheet: function(name) {
+    this.__styleSheet = new qwebirc.ui.style.ModifiableStylesheet(qwebirc.global.staticBaseURL + "css/" + name + qwebirc.FILE_SUFFIX + ".mcss");
+    this.setModifiableStylesheetValues({});
+  },
+  setModifiableStylesheetValues: function(values) {
+    for(var k in values)
+      this.__styleValues[k] = values[k];
+      
+    if(!$defined(this.__styleSheet))
+      return;
+      
+    var back = {hue: this.__styleValues.hue, lightness: this.__styleValues.lightness, saturation: this.__styleValues.saturation};
+    var front = {hue: this.__styleValues.textHue, lightness: this.__styleValues.textLightness, saturation: this.__styleValues.textSaturation};
+
+    if(!this.__styleValues.textHue && !this.__styleValues.textLightness && !this.__styleValues.textSaturation)
+      front = back;
+
+    var colours = {
+      back: back,
+      front: front
+    };
+
+    this.__styleSheet.set(function() {
+      var mode = arguments[0];
+      if(mode == "c") {
+        var t = colours[arguments[2]];
+        var x = new Color(arguments[1]);
+        var c = x.setHue(t.hue).setSaturation(x.hsb[1] + t.saturation).setBrightness(x.hsb[2] + t.lightness);
+        if(c == "255,255,255") /* IE confuses white with transparent... */
+          c = "255,255,254";
+        
+        return "rgb(" + c + ")";
+      } else if(mode == "o") {
+        return this.uiOptions[arguments[1]] ? arguments[2] : arguments[3];
+      }
+    }.bind(this));
   }
 });
 
@@ -346,7 +444,8 @@ qwebirc.ui.NewLoginUI = new Class({
   loginBox: function(callbackfn, initialNickname, initialChannels, autoConnect, autoNick) {
     this.postInitialize();
 
-    var w = this.newCustomWindow("Connect", true, qwebirc.ui.WINDOW_CONNECT);
+    /* I'd prefer something shorter and snappier! */
+    var w = this.newCustomWindow("Connection details", true, qwebirc.ui.WINDOW_CONNECT);
     var callback = function(args) {
       w.close();
       callbackfn(args);
@@ -370,15 +469,61 @@ qwebirc.ui.QuakeNetUI = new Class({
     if(!qwebirc.auth.loggedin())
       return;
     if(confirm("Log out?")) {
-      for(var client in this.clients) {
-        this.clients[client].quit("Logged out");
-      };
+      this.clients.each(function(k, v) {
+        v.quit("Logged out");
+      }, this);
       
       /* HACK */
-      var foo = function() { document.location = "/auth?logout=1"; };
+      var foo = function() { document.location = qwebirc.global.dynamicBaseURL + "auth?logout=1"; };
       foo.delay(500);
     }
   }
 });
 
 qwebirc.ui.RootUI = qwebirc.ui.QuakeNetUI;
+
+qwebirc.ui.RequestTransformHTML = function(options) {
+  var HREF_ELEMENTS = {
+    "IMG": 1
+  };
+
+  var update = options.update;
+  var onSuccess = options.onSuccess;
+
+  var fixUp = function(node) {
+    if(node.nodeType != 1)
+      return;
+
+    var tagName = node.nodeName.toUpperCase();
+    if(HREF_ELEMENTS[tagName]) {
+      var attr = node.getAttribute("transform_attr");
+      var value = node.getAttribute("transform_value");
+      if($defined(attr) && $defined(value)) {
+        node.removeAttribute("transform_attr");
+        node.removeAttribute("transform_value");
+        node.setAttribute(attr, qwebirc.global.staticBaseURL + value);
+      }
+    }
+
+    for(var i=0;i<node.childNodes.length;i++)
+      fixUp(node.childNodes[i]);
+  };
+
+  delete options["update"];
+  options.onSuccess = function(tree, elements, html, js) {
+    var container = new Element("div");
+    container.set("html", html);
+    fixUp(container);
+    update.empty();
+
+    while(container.childNodes.length > 0) {
+      var x = container.firstChild;
+      container.removeChild(x);
+      update.appendChild(x);
+    }
+    onSuccess();
+  };
+
+  return new Request.HTML(options);
+};
+