]> jfr.im git - irc/quakenet/qwebirc.git/commitdiff
Merge.
authorChris Porter <redacted>
Mon, 13 Feb 2012 01:46:47 +0000 (01:46 +0000)
committerChris Porter <redacted>
Mon, 13 Feb 2012 01:46:47 +0000 (01:46 +0000)
23 files changed:
bin/compile.py
bin/pagegen.py
bin/pages.py
css/dialogs.css
js/auth.js
js/irc/baseircclient.js
js/irc/ircclient.js
js/qwebirc.js
js/qwebircinterface.js
js/sound.js
js/soundmanager_defer.js [new file with mode: 0644]
js/ui/baseui.js
js/ui/panes/connect.js
js/ui/panes/embed.js
js/ui/panes/options.js
js/ui/xdomain.js [new file with mode: 0644]
qwebirc/engines/authgateengine.py
static/api.js [new file with mode: 0644]
static/images/favicon.png
static/images/hue.png
static/images/icon.png
static/images/qwebircsmall.png
static/panes/connect.html [new file with mode: 0644]

index 151c1ec7cb81f9a9f87e1ad092f335e7dbd76522..5ca4a8463fdbb18155ef270d49b4ab4b308763fe 100644 (file)
@@ -61,6 +61,8 @@ def merge_files(output, files, root_path=lambda x: x):
   f = open(output, "wb")
 
   for x in files:
+    if x.startswith("//"):
+      continue
     f2 = open(root_path(x), "rb")
     f.write(f2.read() + "\n")
     f2.close()
@@ -139,4 +141,4 @@ def vcheck():
   
 if __name__ == "__main__":
   main()
-  
\ No newline at end of file
+  
index c89102c51df15c054cb90b17e63c1206d7757660..1c042d02206c2960ff725d1f3ccfa4f43660b2aa 100755 (executable)
@@ -6,14 +6,14 @@ class HGException(Exception):
 def jslist(name, debug):
   ui = pages.UIs[name]
   if debug:
-    x = [pages.JS_BASE, ui.get("extra", []), pages.DEBUG, ["debug/ui/frontends/%s" % y for y in ui["uifiles"]]]
+    x = [pages.JS_DEBUG_BASE, ui.get("extra", []), pages.DEBUG, ["debug/ui/frontends/%s" % y for y in ui["uifiles"]]]
     hgid = ""
   else:
     #x = [pages.JS_BASE, ui.get("buildextra", ui.get("extra", [])), pages.BUILD_BASE, name]
-    x = [name]
+    x = [pages.JS_RAW_BASE, name]
     hgid = "-" + gethgid()  
   
-  return list("js/%s%s.js" % (y, hgid) for y in pages.flatten(x))
+  return list(y if y.startswith("//") else "js/%s%s.js" % (y, hgid) for y in pages.flatten(x))
 
 def csslist(name, debug, gen=False):
   ui = pages.UIs[name]
@@ -54,7 +54,7 @@ def producehtml(name, debug):
   js = jslist(name, debug)
   css = csslist(name, debug, gen=True)
   csshtml = "\n".join("  <link rel=\"stylesheet\" href=\"%s%s\" type=\"text/css\"/>" % (config.STATIC_BASE_URL, x) for x in css)
-  jshtml = "\n".join("  <script type=\"text/javascript\" src=\"%s%s\"></script>" % (config.STATIC_BASE_URL, x) for x in js)
+  jshtml = "\n".join("  <script type=\"text/javascript\" src=\"%s%s\"></script>" % ("" if x.startswith("//") else config.STATIC_BASE_URL, x) for x in js)
 
   div = ui.get("div", "")
   customjs = ui.get("customjs", "")
index 9251d4bbeddd137a022038ee26db6c758ba4e3d6..b3877342743db7c3bd58bd680e38763d28315cf8 100644 (file)
@@ -1,13 +1,15 @@
 #!/usr/bin/env python
 IRC_BASE = ["ircconnection", "irclib", "numerics", "baseircclient", "irctracker", "commandparser", "commands", "ircclient", "commandhistory", "nicknamevalidator"]
 PANES = ["connect", "embed", "options", "about", "privacypolicy", "feedback", "faq"]
-UI_BASE = ["menuitems", "baseui", "baseuiwindow", "colour", "url", "theme", "notifications", "tabcompleter", "style"]
+UI_BASE = ["menuitems", "baseui", "baseuiwindow", "colour", "url", "theme", "notifications", "tabcompleter", "style", "xdomain"]
 UI_BASE.extend(["panes/%s" % x for x in PANES])
 
 DEBUG_BASE = ["qwebirc", "version", "jslib", "crypto", "md5", ["irc/%s" % x for x in IRC_BASE], ["ui/%s" % x for x in UI_BASE], "qwebircinterface", "auth", "sound"]
 BUILD_BASE = ["qwebirc"]
-JS_BASE = ["mootools-1.2.5-core", "mootools-1.2.5.1-more"]
-JS_EXTRA = ["soundmanager2"]
+JS_DEBUG_BASE = ["mootools-1.2.5-core-nc", "mootools-1.2.5.1-more-nc", "debug/soundmanager_defer", "soundmanager2"]
+JS_RAW_BASE = ["//ajax.googleapis.com/ajax/libs/mootools/1.2.5/mootools-yui-compressed.js"]
+JS_BASE = ["mootools-1.2.5.1-more", "../../js/soundmanager_defer", "soundmanager2-nodebug-jsmin"]
+JS_EXTRA = []
 
 UIs = {
   "qui": {
index a40d0ec671e55ecf6ae363844982dfbb0d3f29dd..35c4b652d6b9637c033aad81c54c0417385f0dc1 100644 (file)
   text-align: left;
 }
 
+.qwebirc-loginbox input#loginnickname, .qwebirc-loginbox input#loginchannels {
+  width: 200px;
+}
+
 /**************** CONFIRM LOGIN BOX *******************/
 .qwebirc-confirmbox {
   width: 100%;
index d0e1be406043c7ac9328544b5f6b89008e449199..c58b85ac8eccba604324b7f8fcbe09933475e9bb 100644 (file)
@@ -1,19 +1,22 @@
 qwebirc.auth.loggedin = function() {
   var user = Cookie.read("user");
-  
+  var expiry = Cookie.read("ticketexpiry");
+  if(expiry && new Date().getTime() > expiry - (5 * 60 * 1000))
+    return;
+
   return user;
 }
 
 qwebirc.auth.enabled = function() {
-  return false;
+  return true;
 }
 
 qwebirc.auth.quakeNetAuth = function() {
-  return false;
+  return true;
 }
 
 qwebirc.auth.passAuth = function() {
-  return true;
+  return false;
 }
 
 qwebirc.auth.bouncerAuth = function() {
index 7722b24337717647ba5b22ee901e4ba76bdf8e97..948e6f7ed01371e0010701aca438f336317b3063 100644 (file)
@@ -504,5 +504,10 @@ qwebirc.irc.BaseIRCClient = new Class({
 
     this.channelModeIs(channel, modes);
     return true;
+  },
+  irc_QWEBIRCIMAGE: function(prefix, params) {
+    var target = params[0];
+    var url = params.indexFromEnd(-1);
+    return this.qwebircImage(target, url);
   }
 });
index a26ae86861749da9f84bf6ebec6bff2d8a7788f7..dc8a09772c5b3f8ad3a7ad0784f6edc72c2020c8 100644 (file)
@@ -242,6 +242,8 @@ qwebirc.irc.IRCClient = new Class({
 
       this.exec("/AUTOJOIN");
     }
+
+    this.ui.signedOn();
   },
   userJoined: function(user, channel) {
     var nick = user.hostToNick();
@@ -669,5 +671,22 @@ qwebirc.irc.IRCClient = new Class({
   },
   channelCreationTime: function(channel, time) {
     this.newTargetOrActiveLine(channel, "CHANNELCREATIONTIME", {c: channel, m: qwebirc.irc.IRCDate(new Date(time * 1000))});
-  }  
+  },
+  qwebircImage: function(target, url) {
+    var w;
+    if(target == "-STATUS") {
+      w = this.statusWindow;
+    } else {
+      w = this.getWindow(target);
+    }
+
+    if(!w)
+      w = this.getActiveWindow();
+
+    var img = new Element("img", {src: qwebirc.global.dynamicBaseURL + "image?filename=" + url});
+    var d = new Element("div", {styles: {"paddingTop": "2px", "paddingBottom": "2px", "paddingLeft": "9px"}});
+    d.appendChild(img);
+    w.scrollAdd(d);
+    return true;
+  }
 });
index 03e8b80d1cc0a486777e1b1b73eae1a553cb80b1..8e4b08561d2ffddd46fdda4714bb968aa219d9be 100644 (file)
@@ -1,4 +1,4 @@
-var qwebirc = {ui: {themes: {}, style: {}}, irc: {}, util: {crypto: {}}, config: {}, auth: {}, sound: {}, connected: false};
+var qwebirc = {ui: {themes: {}, style: {}}, irc: {}, util: {crypto: {}}, config: {}, auth: {}, sound: {}, connected: false, xdomain: {}};
 
 if(typeof QWEBIRC_BUILD != "undefined") {
   qwebirc.BUILD = QWEBIRC_BUILD;
index 1d7f249a6701d4e9a34a52deff10520304a62a54..44ea44c42cf3d6267e4dbaa4aa6c0851553719b5 100644 (file)
@@ -33,14 +33,31 @@ qwebirc.ui.Interface = new Class({
   },
   initialize: function(element, ui, options) {
     this.setOptions(options);
+    var extractHost = function(uri) {
+      var start = uri.indexOf('?');
+      if(start != -1)
+        uri = uri.substring(0, start);
+      var start = uri.indexOf('#');
+      if(start != -1)
+        uri = uri.substring(0, start);
+
+      if(uri.substr(uri.length - 1) != "/")
+        uri = uri + "/";
+
+      return uri;
+    };
+
+    options.baseURL = extractHost(document.location.href);
     
     /* HACK */
     qwebirc.global = {
       dynamicBaseURL: options.dynamicBaseURL,
       staticBaseURL: options.staticBaseURL,
+      baseURL: options.baseURL,
       nicknameValidator: $defined(options.nickValidation) ? new qwebirc.irc.NicknameValidator(options.nickValidation) : new qwebirc.irc.DummyNicknameValidator()
     };
 
+
     window.addEvent("domready", function() {
       var callback = function(options) {
         var IRC = new qwebirc.irc.IRCClient(options, ui_);
index f2043824a0bd760eb7f3abd49fc3ab514ebc3b22..f8822013ea44f832cf2a2e25de2f81a7e518a385 100644 (file)
@@ -8,6 +8,12 @@ qwebirc.sound.SoundPlayer = new Class({
   initialize: function() {
     this.loadingSWF = false;
     this.loadedSWF = false;
+
+    var sb = qwebirc.global.staticBaseURL;
+    if(qwebirc.global.baseURL.substr(qwebirc.global.baseURL.length - 1, 1) == "/" && sb.substr(0, 1) == "/")
+      sb = sb.substr(1)
+
+    this.soundURL = qwebirc.global.baseURL + sb + "sound/";
   },
   go: function() {
     if(qwebirc.sound.domReady) {
@@ -22,24 +28,23 @@ qwebirc.sound.SoundPlayer = new Class({
     if(this.loadingSWF)
       return;
     this.loadingSWF = true;
-    if(eval("typeof soundManager") != "undefined") {
+
+    var debugMode = false;
+
+    window.soundManager = new SoundManager();
+
+    var sb = qwebirc.global.staticBaseURL;
+    if(qwebirc.global.baseURL.substr(-1) == "/" && sb.substr(0, 1) == "/")
+      sb = sb.substr(1)
+    
+    window.soundManager.url = this.soundURL;
+    window.soundManager.debugMode = debugMode;
+    window.soundManager.useConsole = debugMode;
+    window.soundManager.onload = function() {
       this.loadedSWF = true;
       this.fireEvent("ready");
-      return;
-    }
-    
-    var debugMode = false;
-    qwebirc.util.importJS(qwebirc.global.staticBaseURL + "js/" + (debugMode?"soundmanager2":"soundmanager2-nodebug-jsmin") + ".js", "soundManager", function() {
-      soundManager.url = qwebirc.global.staticBaseURL + "sound/";
-      
-      soundManager.debugMode = debugMode;
-      soundManager.useConsole = debugMode;
-      soundManager.onload = function() {
-        this.loadedSWF = true;
-        this.fireEvent("ready");
-      }.bind(this);
-      soundManager.beginDelayedInit();
-    }.bind(this));
+    }.bind(this);
+    window.soundManager.beginDelayedInit();
   },
   createSound: function(name, src) {
     soundManager.createSound(name, src);
@@ -49,7 +54,7 @@ qwebirc.sound.SoundPlayer = new Class({
   },
   beep: function() {
     if(!this.beepLoaded) {
-      this.createSound("beep", qwebirc.global.staticBaseURL + "sound/beep3.mp3");
+      this.createSound("beep", this.soundURL + "beep3.mp3");
       this.beepLoaded = true;
     }
     this.playSound("beep");
diff --git a/js/soundmanager_defer.js b/js/soundmanager_defer.js
new file mode 100644 (file)
index 0000000..5255280
--- /dev/null
@@ -0,0 +1 @@
+window.SM2_DEFER = true;
index ec54d473b1e1cc064ebfc7e118468de99b7d40b7..1a5c5801ae6dbe1b7cab4e378fc40b934149d296 100644 (file)
@@ -197,12 +197,42 @@ qwebirc.ui.BaseUI = new Class({
       tricked into getting themselves glined
     */
   loginBox: function(callback, initialNickname, initialChannels, autoConnect, autoNick) {
-    qwebirc.ui.GenericLoginBox(this.parentElement, callback, initialNickname, initialChannels, autoConnect, autoNick, this.options.networkName);
+    this.postInitialize();
+
+    this.addCustomWindow("Connection details", qwebirc.ui.ConnectPane, "connectpane", {
+      initialNickname: initialNickname, initialChannels: initialChannels, autoConnect: autoConnect, networkName: this.options.networkName, callback: callback, autoNick: autoNick
+    }, qwebirc.ui.WINDOW_CONNECT);
   },
   focusChange: function(newValue) {
     var window_ = this.getActiveWindow();
     if($defined(window_))
       window_.focusChange(newValue);
+  },
+  signedOn: function() {
+    this.poller = new qwebirc.xdomain.Poller(this.oobMessage.bind(this));
+  },
+  oobMessage: function(message) {
+    var c = message.splitMax(" ", 2);
+    if(c.length != 2)
+      return;
+
+    var command = c[0];
+    if(command != "CMD")
+      return;
+
+    var d = c[1].splitMax(" ", 2);
+    if(d.length != 2)
+      return;
+
+    var command = d[0];
+    var args = d[1];
+    if(command == "SAY") {
+      var w = this.getActiveIRCWindow();
+      if($defined(w) && (w.type == qwebirc.ui.WINDOW_CHANNEL || w.type == qwebirc.ui.WINDOW_QUERY)) {
+        w.client.exec("/SAY " + args);
+        return;
+      }
+    }
   }
 });
 
@@ -287,7 +317,7 @@ qwebirc.ui.StandardUI = new Class({
   newCustomWindow: function(name, select, type) {
     if(!type)
       type = qwebirc.ui.WINDOW_CUSTOM;
-      
+
     var w = this.newWindow(qwebirc.ui.CUSTOM_CLIENT, type, name);
     w.addEvent("close", function(w) {
       delete this.windows[qwebirc.ui.CUSTOM_CLIENT][w.identifier];
@@ -298,7 +328,7 @@ qwebirc.ui.StandardUI = new Class({
 
     return w;
   },
-  addCustomWindow: function(windowName, class_, cssClass, options) {
+  addCustomWindow: function(windowName, class_, cssClass, options, type) {
     if(!$defined(options))
       options = {};
       
@@ -307,7 +337,7 @@ qwebirc.ui.StandardUI = new Class({
       return;
     }
     
-    var d = this.newCustomWindow(windowName, true);
+    var d = this.newCustomWindow(windowName, true, type);
     this.customWindows[windowName] = d;
     
     d.addEvent("close", function() {
@@ -436,24 +466,8 @@ qwebirc.ui.NotificationUI = new Class({
   }
 });
 
-qwebirc.ui.NewLoginUI = new Class({
-  Extends: qwebirc.ui.NotificationUI,
-  loginBox: function(callbackfn, initialNickname, initialChannels, autoConnect, autoNick) {
-    this.postInitialize();
-
-    /* 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);
-    };
-    
-    qwebirc.ui.GenericLoginBox(w.lines, callback, initialNickname, initialChannels, autoConnect, autoNick, this.options.networkName);
-  }
-});
-
 qwebirc.ui.QuakeNetUI = new Class({
-  Extends: qwebirc.ui.NewLoginUI,
+  Extends: qwebirc.ui.NotificationUI,
   urlDispatcher: function(name, window) {
     if(name == "qwhois") {
       return ["span", function(auth) {
index c7004d7c5f155be3ca17bd4da8affe8c9795dec8..6f1e7ec3a1d1ed2250c17a7967fd595e183840ef 100644 (file)
-qwebirc.ui.GenericLoginBox = function(parentElement, callback, initialNickname, initialChannels, autoConnect, autoNick, networkName) {
-  if(autoConnect) {
-    qwebirc.ui.ConfirmBox(parentElement, callback, initialNickname, initialChannels, autoNick, networkName);
-  } else {
-    qwebirc.ui.LoginBox(parentElement, callback, initialNickname, initialChannels, networkName);
-  }
-}
+qwebirc.ui.ConnectPane = new Class({
+  Implements: [Events],
+  initialize: function(parent, options) {
+    var callback = options.callback, initialNickname = options.initialNickname, initialChannels = options.initialChannels, networkName = options.networkName, autoConnect = options.autoConnect, autoNick = options.autoNick;
+    this.options = options;
+    this.__windowName = "authgate_" + Math.floor(Math.random() * 100000);
 
-qwebirc.ui.AuthLogin = function(e) {
-  var cookie = Cookie.write("redirect", document.location);
-  document.location = qwebirc.global.dynamicBaseURL + "auth/";
-  new Event(e).stop();
-}
+    var delayfn = function() { parent.set("html", "<div class=\"loading\">Loading. . .</div>"); };
+    var cb = delayfn.delay(500);
 
-qwebirc.ui.ConfirmBox = function(parentElement, callback, initialNickname, initialChannels, autoNick, networkName) {
-  var outerbox = new Element("table");
-  outerbox.addClass("qwebirc-centrebox");
-  parentElement.appendChild(outerbox);
-  var tbody = new Element("tbody");
-  outerbox.appendChild(tbody);
-  var tr = new Element("tr");
-  tbody.appendChild(tr);
-  var td = new Element("td");
-  tr.appendChild(td);
-  
-  var box = new Element("table");
-  box.addClass("qwebirc-confirmbox");
-  td.appendChild(box);
+    var r = qwebirc.ui.RequestTransformHTML({url: qwebirc.global.staticBaseURL + "panes/connect.html", update: parent, onSuccess: function() {
+      $clear(cb);
 
-  var tbody = new Element("tbody");
-  box.appendChild(tbody);
-  
-  var tr = new Element("tr");
-  tbody.appendChild(tr);
-  tr.addClass("tr1");
-  
-  var text = new Element("td");
-  tr.appendChild(text);
-  
-  var nick = new Element("b");
-  nick.set("text", initialNickname);
-  
-  var c = initialChannels.split(" ")[0].split(",");
-  
-  text.appendChild(document.createTextNode("To connect to " + networkName + " IRC and join channel" + ((c.length>1)?"s":"") + " "));
+      var box = (autoConnect ? "confirm" : "login");
+      var rootElement = parent.getElement("[name=" + box + "box]");
+      this.rootElement = rootElement;
+      
+      this.util.exec = function(n, x) { rootElement.getElements(n).each(x); };
+      var util = this.util;
+      var exec = util.exec;
+      util.makeVisible(rootElement);
 
-  for(var i=0;i<c.length;i++) {
-    if((c.length > 1) && (i == c.length - 1)) {
-      text.appendChild(document.createTextNode(" and "));
-    } else if(i > 0) {
-      text.appendChild(document.createTextNode(", "));
-    }
-    text.appendChild(new Element("b").set("text", c[i]));
-    
-  }
-  
-  if(!autoNick) {
-    text.appendChild(document.createTextNode(" as "));
-    text.appendChild(nick);
-  }
-  
-  text.appendChild(document.createTextNode(" click 'Connect'."));
-  text.appendChild(new Element("br"));
-  if(qwebirc.auth.enabled() && qwebirc.auth.quakeNetAuth() && !qwebirc.auth.loggedin())
-    text.appendChild(document.createTextNode("If you'd like to connect using your Q auth click 'Log in'."));
-
-  var tr = new Element("tr");
-  tbody.appendChild(tr);
-  tr.addClass("tr2");
-  
-  var td = new Element("td");
-  tr.appendChild(td);
+      exec("[name=nickname]", util.setText(initialNickname));
+      exec("[name=channels]", util.setText(initialChannels));
+      exec("[name=prettychannels]", function(node) { this.__buildPrettyChannels(node, initialChannels); }.bind(this));
+      exec("[name=networkname]", util.setText(networkName));
 
-  var yes = new Element("input", {"type": "submit", "value": "Connect"});
-  td.appendChild(yes);
-  yes.addEvent("click", function(e) {
-    parentElement.removeChild(outerbox);
-    callback({"nickname": initialNickname, "autojoin": initialChannels});
-  });
-  
-  if(qwebirc.auth.enabled() && qwebirc.auth.quakeNetAuth() && !qwebirc.auth.loggedin()) {
-    var auth = new Element("input", {"type": "submit", "value": "Log in"});
-    td.appendChild(auth);
-    auth.addEvent("click", qwebirc.ui.AuthLogin);
-  }
-  
-  if(window == window.top) 
-    yes.focus();
-}
+      var focus = "connect";
+      if(autoConnect) {
+        if(!autoNick)
+          exec("[name=nickselected]", util.makeVisible);
 
-qwebirc.ui.LoginBox = function(parentElement, callback, initialNickname, initialChannels, networkName) {
-  var outerbox = new Element("table");
-  outerbox.addClass("qwebirc-centrebox");
-  parentElement.appendChild(outerbox);
-  var tbody = new Element("tbody");
-  outerbox.appendChild(tbody);
-  var tr = new Element("tr");
-  tbody.appendChild(tr);
-  var td = new Element("td");
-  tr.appendChild(td);
-  
-  var box = new Element("table");
-  box.addClass("qwebirc-loginbox");
-  td.appendChild(box);
-  
-  var tbody = new Element("tbody");
-  box.appendChild(tbody);
-  
-  var tr = new Element("tr");
-  tbody.appendChild(tr);
-  tr.addClass("tr1");
-  
-  var td = new Element("td");
-  tr.appendChild(td);
-  td.set("html", "<h1>Connect to " + networkName + " IRC</h1>");  
-    
-  var tr = new Element("tr");
-  tbody.appendChild(tr);
-  tr.addClass("tr2");
-  
-  var td = new Element("td");
-  tr.appendChild(td);
-  
-  var form = new Element("form");
-  td.appendChild(form);
+        this.__validate = this.__validateConfirmData;
+      } else {
+       if(!initialNickname) {
+          focus = "nickname";
+        } else if(initialNickname && !initialChannels) {
+          focus = "channels";
+        }
+
+        this.__validate = this.__validateLoginData;
+      }
+
+      if(qwebirc.auth.loggedin()) {
+        exec("[name=authname]", util.setText(qwebirc.auth.loggedin()));
+        exec("[name=connectbutton]", util.makeVisible);
+        exec("[name=loginstatus]", util.makeVisible);
+      } else {
+        if(qwebirc.ui.isAuthRequired()) {
+          exec("[name=loginconnectbutton]", util.makeVisible);
+          if(focus == "connect")
+            focus = "loginconnect";
+        } else {
+          exec("[name=connectbutton]", util.makeVisible);
+          exec("[name=loginbutton]", util.makeVisible);
+        }
+      }
 
-  var boxtable = new Element("table");
-  form.appendChild(boxtable);
+      if(window == window.top) /* don't focus when we're iframe'd */
+        exec("[name=" + focus + "]", util.focus);
+      exec("[name=connect]", util.attachClick(this.__connect.bind(this)));
+      exec("[name=loginconnect]", util.attachClick(this.__loginConnect.bind(this)));
+      exec("[name=login]", util.attachClick(this.__login.bind(this)));
+    }.bind(this)});
+    r.get();
+  },
+  util: {
+    makeVisible: function(x) { x.setStyle("display", ""); },
+    setVisible: function(y) { return function(x) { x.setStyle("display", y ? "" : "none"); }; },
+    focus: function(x) { x.focus(); },
+    attachClick: function(fn) { return function(x) { x.addListener("click", fn); } },
+    setText: function(x) { return function(y) {
+      if(typeof y.value === "undefined") {
+        y.set("text", x);
+      } else {
+        y.value = x === null ? "" : x;
+      }
+    } }
+  },
+  validate: function() {
+    return this.__validate();
+  },
+  __connect: function(e) {
+    new Event(e).stop();
+    var data = this.validate();
+    if(data === false)
+      return;
 
-  var tbody = new Element("tbody");
-  boxtable.appendChild(tbody); /* stupid IE */
+    this.__cancelLogin();
+    this.fireEvent("close");
+    this.options.callback(data);
+  },
+  __cancelLogin: function(noUIModifications) {
+    if(this.__cancelLoginCallback)
+      this.__cancelLoginCallback(noUIModifications);
+  },
+  __loginConnect: function(e) {
+    new Event(e).stop();
+    if(this.validate() === false)
+      return;
 
-  function createRow(label, e2, style) {
-    var r = new Element("tr");
-    tbody.appendChild(r);
+    this.__performLogin(function() {
+      var data = this.validate();
+      if(data === false) {
+        /* we're logged in -- show the normal join button */
+        this.util.exec("[name=connectbutton]", this.util.setVisible(true));
+        return;
+      }
 
-    var d1 = new Element("td");
-    if(label)
-      d1.set("text", label);
-    r.appendChild(d1);
+      this.fireEvent("close");
+      this.options.callback(data);
+    }.bind(this), "loginconnectbutton");
+  },
+  __login: function(e) {
+    new Event(e).stop();
 
-    var d2 = new Element("td");
-    r.appendChild(d2);
-    
-    if($defined(e2))
-      d2.appendChild(e2);
-    if($defined(style)) {
-      r.setStyles(style);
-      return [r, d2];
+    this.__cancelLogin(true);
+
+    this.__performLogin(function() {
+      var focus = "connect";
+      if(!this.options.autoConnect) {
+        var nick = this.rootElement.getElement("input[name=nickname]").value, chan = this.rootElement.getElement("input[name=channels]").value;
+        if(!nick) {
+          focus = "nickname";
+        } else if(!chan) {
+          focus = "channels";
+        }
+      }
+      this.util.exec("[name=" + focus + "]", this.util.focus);        
+    }.bind(this), "login");
+  },
+  __performLogin: function(callback, calleename) {
+    Cookie.write("jslogin", "1");
+
+    var handle = window.open("/auth", this.__windowName, "status=0,toolbar=0,location=1,menubar=0,directories=0,resizable=0,scrollbars=1,height=280,width=550");
+
+    if(handle === null || handle === undefined) {
+      Cookie.dispose("jslogin");
+//      Cookie.write("redirect", document.location);
+//      window.location = "auth?";
+      return;
+    }        
+
+    var closeDetector = function() {
+      if(handle.closed)
+        this.__cancelLoginCallback();
+    }.bind(this);
+    var closeCallback = closeDetector.periodical(100);
+
+    this.__cancelLoginCallback = function(noUIModifications) {
+      $clear(closeCallback);
+
+      Cookie.dispose("jslogin");
+
+      try {
+        handle.close();
+      } catch(e) {
+      }
+
+      if(!noUIModifications) {
+        this.util.exec("[name=loggingin]", this.util.setVisible(false));
+        this.util.exec("[name=" + calleename + "]", this.util.setVisible(true));
+      }
+      this.__cancelLoginCallback = null;
+    }.bind(this);
+
+    this.util.exec("[name=loggingin]", this.util.setVisible(true));
+    this.util.exec("[name=" + calleename + "]", this.util.setVisible(false));
+
+    __qwebircAuthCallback = function(username, expiry, serverNow) {
+      this.__cancelLoginCallback(true);
+
+      var now = new Date().getTime();
+      var offset = (serverNow * 1000) - now;
+      var ourExpiry = expiry * 1000 - offset;
+      Cookie.write("ticketexpiry", ourExpiry)
+
+      this.util.exec("[name=loggingin]", this.util.setVisible(false));
+      this.util.exec("[name=loginstatus]", this.util.setVisible(true));
+      this.util.exec("[name=authname]", this.util.setText(username));
+      callback();
+    }.bind(this);
+
+  },
+  __validateConfirmData: function() {
+    return {nickname: this.options.initialNickname, autojoin: this.options.initialChannels};
+  },
+  __validateLoginData: function() {
+    var nick = this.rootElement.getElement("input[name=nickname]"), chan = this.rootElement.getElement("input[name=channels]");
+
+    var nickname = nick.value;
+    var chans = chan.value;
+    if(chans == "#") /* sorry channel "#" :P */
+      chans = "";
+
+    if(!nickname) {
+      alert("You must supply a nickname.");
+      nick.focus();
+      return false;
+    }
+
+    var stripped = qwebirc.global.nicknameValidator.validate(nickname);
+    if(stripped != nickname) {
+      nick.value = stripped;
+      alert("Your nickname was invalid and has been corrected; please check your altered nickname and try again.");
+      nick.focus();
+      return false;
     }
     
-    return d2;
+    var data = {nickname: nickname, autojoin: chans};
+    return data;
+  },
+  __buildPrettyChannels: function(node, channels) {
+    var c = channels.split(" ")[0].split(",");
+    node.appendChild(document.createTextNode("channel" + ((c.length>1)?"s":"") + " "));
+    for(var i=0;i<c.length;i++) {
+      if((c.length > 1) && (i == c.length - 1)) {
+        node.appendChild(document.createTextNode(" and "));
+      } else if(i > 0) {
+        node.appendChild(document.createTextNode(", "));
+      }
+      node.appendChild(new Element("b").set("text", c[i]));
+    }
   }
+});
 
-  var nick = new Element("input");
-  createRow("Nickname:", nick);
-  
-  var chanStyle = null;
-  if(qwebirc.auth.enabled() && qwebirc.auth.bouncerAuth())
-    chanStyle = {display: "none"};
-  
-  var chan = new Element("input");
-  createRow("Channels:", chan, chanStyle);
-
+qwebirc.ui.LoginBox2 = function(parentElement, callback, initialNickname, initialChannels, networkName) {
+/*
   if(qwebirc.auth.enabled()) {
     if(qwebirc.auth.passAuth()) {
       var authRow = createRow("Auth to services:");
@@ -179,19 +243,15 @@ qwebirc.ui.LoginBox = function(parentElement, callback, initialNickname, initial
       var passwordBox = qwebirc.util.createInput("password", passwordRow, "connect_auth_password");
     }
   }
-  
+  */
+
   var connbutton = new Element("input", {"type": "submit"});
   connbutton.set("value", "Connect");
   var r = createRow(undefined, connbutton);
   
-  if(qwebirc.auth.enabled() && qwebirc.auth.quakeNetAuth() && !qwebirc.auth.loggedin()) {
-    var auth = new Element("input", {"type": "submit", "value": "Log in"});
-    r.appendChild(auth);
-    auth.addEvent("click", qwebirc.ui.AuthLogin);
-  }
-
   form.addEvent("submit", function(e) {
     new Event(e).stop();
+
     var nickname = nick.value;
     var chans = chan.value;
     if(chans == "#") /* sorry channel "#" :P */
@@ -257,3 +317,12 @@ qwebirc.ui.authShowHide = function(checkbox, authRow, usernameBox, usernameRow,
     usernameBox.focus();
   }
 }
+
+qwebirc.ui.isAuthRequired = (function() {
+  var args = qwebirc.util.parseURI(String(document.location));
+  var value = $defined(args) && args["authrequired"];
+  return function() {
+    return value && qwebirc.auth.enabled();
+  };
+})();
+
index baf4cba3fbd3df562679a15522ff592aaba12738..c52ce6b28cb2459a45ced666d4afd2ea380a13bb 100644 (file)
@@ -319,6 +319,6 @@ qwebirc.ui.EmbedWizard = new Class({
         URL.push("uio=" + uioptions);
     }
     
-    return this.options.baseURL + (URL.length>0?"?":"") + URL.join("&");
+    return qwebirc.global.baseURL + (URL.length>0?"?":"") + URL.join("&");
   }
 });
index ff50c0ff0fa59b5e58fc62cec8b59411061d5cf4..1d6b075624e05006d5f8e1b1915141ca8637d780 100644 (file)
@@ -31,7 +31,7 @@ qwebirc.config.DEFAULT_OPTIONS = [
   [2, "DEDICATED_MSG_WINDOW", "Send privmsgs to dedicated messages window", false],
   [4, "DEDICATED_NOTICE_WINDOW", "Send notices to dedicated message window", false],
   [3, "NICK_OV_STATUS", "Show status (@/+) before nicknames in channel lines", true],
-  [5, "ACCEPT_SERVICE_INVITES", "Automatically join channels when invited by Q", true, {
+  [5, "ACCEPT_SERVICE_INVITES", "Automatically join channels when invited by Q", false, {
     settableByURL: false
   }],
   [6, "USE_HIDDENHOST", "Hide your hostmask when authed to Q (+x)", true, {
@@ -443,8 +443,12 @@ qwebirc.ui.SuppliedArgOptions = new Class({
       var checksum = arg.substr(arg.length - 2, 2);
       var decoded = qwebirc.util.b64Decode(arg.substr(0, arg.length - 2));
       
-      if(decoded && (new qwebirc.util.crypto.MD5().digest(decoded).slice(0, 2) == checksum))
-        p = qwebirc.util.parseURI("?" + decoded);
+      if(decoded && (new qwebirc.util.crypto.MD5().digest(decoded).slice(0, 2) == checksum)) {
+        var p2 = qwebirc.util.parseURI("?" + decoded);
+        for(var k in p2) {
+          p[k] = JSON.decode(p2[k], true);
+        }
+      }
     }
     
     this.parsedOptions = p;
@@ -464,7 +468,7 @@ qwebirc.ui.SuppliedArgOptions = new Class({
     var result = [];
     this.getOptionList().forEach(function(x) {
       if(x.settableByURL && x.default_ != x.value)
-        result.push(x.optionId + "=" + x.value);
+        result.push(x.optionId + "=" + JSON.encode(x.value));
     }.bind(this));
     
     var raw = result.join("&");
diff --git a/js/ui/xdomain.js b/js/ui/xdomain.js
new file mode 100644 (file)
index 0000000..a814756
--- /dev/null
@@ -0,0 +1,33 @@
+qwebirc.xdomain.Poller = new Class({
+  initialize: function(callback) {
+    this._callback = callback;
+    this._poll.periodical(100, this);
+    this._lastValue = null;
+    this._counter = -1;
+  },
+  _poll: function() {
+    var value = window.location.href;
+    if(value === null || value === undefined || value == this._lastValue)
+      return;
+    this._lastValue = value;
+    var fragment = value.splitMax("#", 2)[1];
+
+    if(fragment === undefined || fragment.substr(0, 6) != "qwmsg:")
+      return;
+
+    var components = fragment.substr(6).split(":", 3);
+    var counter = parseInt(components[0]);
+    if(counter <= this._counter)
+      return;
+
+    this._counter = counter;
+
+    var len = parseInt(components[1]);
+    var message = decodeURIComponent(components[2]);
+    if(len != message.length)
+      return;
+
+    message = message.replaceAll("\000", "").replaceAll("\n", "").replaceAll("\r", "");
+    this._callback(message);
+  }
+});
index bd097b6838ee3c7869bbfbde6fd0cdc9c01653cb..f4f29df7060bf1011b1314f21fe6270a00245349 100644 (file)
@@ -2,6 +2,7 @@ from twisted.web import resource, server, static
 import config, urlparse, urllib, hashlib, re
 import qwebirc.util.rijndael, qwebirc.util.ciphers
 import qwebirc.util
+import qwebirc.util.qjson as json
 
 authgate = config.AUTHGATEPROVIDER.twisted
 BLOCK_SIZE = 128/8
@@ -35,6 +36,10 @@ class AuthgateEngine(resource.Resource):
         getSessionData(request)["qticket"] = decodeQTicket(qt)
       
       self.__hit()
+      if request.getCookie("jslogin"):
+        self.deleteCookie(request, "jslogin")
+        return """<html><head><script>window.opener.__qwebircAuthCallback(%s);</script></head></html>""" % json.dumps(ticket.username)
+
       location = request.getCookie("redirect")
       if location is None:
         location = "/"
@@ -77,4 +82,4 @@ def getSessionData(request):
   
 def login_optional(request):
   return authgate(request, config.AUTHGATEDOMAIN).login_optional()
\ No newline at end of file
diff --git a/static/api.js b/static/api.js
new file mode 100644 (file)
index 0000000..ae28ad5
--- /dev/null
@@ -0,0 +1,19 @@
+/* example usage:
+ *
+ * var qwebirc = new QWebIRC(document.getElementById("myiframeid"));
+ * function f() {
+ *   qwebirc.say("hi there mr wibbles");
+ * }
+ */
+
+var QWebIRC = function(element) {
+  var counter = 0;
+  var send = function(message) {
+    element.src = element.src.split("#")[0] + "#qwmsg:" + counter++ + ":" + message.length + ":" + encodeURIComponent(message);
+  };
+
+  this.say = function(message) {
+    send("CMD SAY " + message);
+  };
+};
+
index d9e13d3b31268e26083bcce3d090d6539ef9afc1..13f53071b996ce8055d5002ffc604aa41bf5e026 100644 (file)
Binary files a/static/images/favicon.png and b/static/images/favicon.png differ
index 88a8e400a3c94321d311004b51f2d81d6036191a..5293e4fae1bbd7130be84fdd995c0a509a893d08 100644 (file)
Binary files a/static/images/hue.png and b/static/images/hue.png differ
index 4a1ef9190cd4939aba4b7acc38591c4ecbff3151..616e70d8e2cd0d9928f280d979ff6ac2d1ded889 100644 (file)
Binary files a/static/images/icon.png and b/static/images/icon.png differ
index b1e5d666c6615feb98171dba5f783234c15dd27d..784b774b90ccbfb29ade8074101df08ed45bbdde 100644 (file)
Binary files a/static/images/qwebircsmall.png and b/static/images/qwebircsmall.png differ
diff --git a/static/panes/connect.html b/static/panes/connect.html
new file mode 100644 (file)
index 0000000..8ba69b0
--- /dev/null
@@ -0,0 +1,73 @@
+<table class="qwebirc-centrebox">
+  <tr>
+    <td>
+      <table class="qwebirc-loginbox" style="display: none" name="loginbox">
+        <tr class="tr1">
+          <td>
+            <h1>Connect to <span name="networkname"></span> IRC</h1>
+          </td>
+        </tr>
+        <tr class="tr2">
+          <td>
+            <form>
+              <table>
+                <tr>
+                  <td><label for="loginnickname">Nickname:</label></td>
+                  <td><input type="text" name="nickname" id="loginnickname" /></td>
+                </tr>
+                <tr>
+                  <td><label for="loginchannels">Channels:</label></td>
+                  <td><input type="text" name="channels" id="loginchannels" /></td>
+                </tr>
+                <tr name="connectbutton" style="display: none">
+                  <td></td>
+                  <td>
+                    <input type="submit" value="Join chat" name="connect" />
+                  </td>
+                </tr>
+                <tr name="loginbutton" style="display: none">
+                  <td></td>
+                  <td><input type="submit" value="Log in to Q" name="login" /></td>
+                </tr>
+                <tr name="loginconnectbutton" style="display: none">
+                  <td></td>
+                  <td><input type="submit" value="Join chat (Q account required)" name="loginconnect" /></td>
+                </tr>
+                <tr name="loginstatus" style="display: none">
+                  <td></td>
+                  <td><small>(logged in as <b name="authname"></b>)</small></td>
+                </tr>
+                <tr name="loggingin" style="display: none">
+                  <td></td>
+                  <td><small>(waiting for you to log in...)</td>
+                </tr>
+              </table>
+            </form>
+          </td>
+        </tr>
+      </table>
+      <table class="qwebirc-confirmbox" style="display: none" name="confirmbox">
+        <tr class="tr1">
+          <td>
+            To connect to <span name="networkname"></span> IRC and join <span name="prettychannels"></span><span name="nickselected" style="display: none"> as <b name="nickname"></b></span> click 'Join chat'.
+          </td>
+        </tr>
+        <tr class="tr2" name="connectbutton" style="display: none">
+          <td><input type="submit" value="Join chat" name="connect" /></td>
+        </tr>
+        <tr class="tr2" name="loginbutton" style="display: none">
+          <td><input type="submit" value="Log in to Q" name="login" /></td>
+        </tr>
+        <tr class="tr2" name="loginconnectbutton" style="display: none;">
+          <td><input type="submit" value="Join chat (Q account required)" name="loginconnect" /></td>
+        </tr>
+        <tr class="tr2" name="loginstatus" style="display: none">
+          <td><small>(logged in as <b name="authname"></b>)</small></td>
+        </tr>
+        <tr class="tr2" name="loggingin" style="display: none">
+          <td><small>(waiting for you to log in...)</small></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>