home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 January / 01_03.iso / software / ghostzilla_hit / files / ghostzilla-1.0-plus-install.exe / chrome / chatzilla.jar / content / chatzilla / handlers.js < prev    next >
Encoding:
JavaScript  |  2002-05-09  |  84.2 KB  |  3,268 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2.  *
  3.  * The contents of this file are subject to the Mozilla Public
  4.  * License Version 1.1 (the "License"); you may not use this file
  5.  * except in compliance with the License. You may obtain a copy of
  6.  * the License at http://www.mozilla.org/MPL/
  7.  *
  8.  * Software distributed under the License is distributed on an "AS
  9.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10.  * implied. See the License for the specific language governing
  11.  * rights and limitations under the License.
  12.  *
  13.  * The Original Code is ChatZilla
  14.  *
  15.  * The Initial Developer of the Original Code is New Dimensions Consulting,
  16.  * Inc. Portions created by New Dimensions Consulting, Inc. are
  17.  * Copyright (C) 1999 New Dimenstions Consulting, Inc. All
  18.  * Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *  Robert Ginda, rginda@ndcico.com, original author
  22.  *  Chiaki Koufugata chiaki@mozilla.gr.jp UI i18n 
  23.  */
  24.  
  25. function onTopicEditStart()
  26. {
  27.     if (client.currentObject.TYPE != "IRCChannel")
  28.         return;
  29.  
  30.     var text = client.statusBar["channel-topic"];
  31.     var edit = client.statusBar["channel-topicedit"];
  32.     text.setAttribute("collapsed", "true");
  33.     edit.removeAttribute("collapsed");
  34.     edit.value = client.currentObject.topic;
  35.     edit.focus();
  36.     edit.selectionStart = 0;
  37.     edit.selectionEnd = edit.value.length;
  38. }
  39.  
  40. function onTopicEditEnd ()
  41. {
  42.     if (!("statusBar" in client))
  43.         return;
  44.     
  45.     var edit = client.statusBar["channel-topicedit"];
  46.     var text = client.statusBar["channel-topic"];
  47.     edit.setAttribute("collapsed", "true");
  48.     text.removeAttribute("collapsed");
  49.     focusInput();
  50. }
  51.  
  52. function onTopicKeyPress (e)
  53. {
  54.     if (client.currentObject.TYPE != "IRCChannel")
  55.         return;
  56.     
  57.     if (e.keyCode == 13)
  58.     {        
  59.         var line = stringTrim(e.target.value);
  60.         client.currentObject.setTopic (line);
  61.         onTopicEditEnd();
  62.     }
  63. }
  64.  
  65. function onInputFocus ()
  66. {
  67.     if (!("statusBar" in client))
  68.         return;
  69.     
  70.     var edit = client.statusBar["channel-topicedit"];
  71.     var text = client.statusBar["channel-topic"];
  72.     edit.setAttribute("collapsed", "true");
  73.     text.removeAttribute("collapsed");
  74. }
  75.  
  76. function onLoad()
  77. {
  78.     
  79.     initHost(client);
  80.     readIRCPrefs();
  81.     setClientOutput();
  82.     frames[0].document.location.href =
  83.         "chrome://chatzilla/content/outputwindow.html?" + client.DEFAULT_STYLE;
  84.     initStatic();
  85.  
  86.     client.userScripts = new Array();
  87.     if (client.INITIAL_SCRIPTS)
  88.     {
  89.         var urls = client.INITIAL_SCRIPTS.split (";");
  90.         for (var i = 0; i < urls.length; ++i)
  91.         {
  92.             client.userScripts[i] = new Object();
  93.             client.load(stringTrim(urls[i]), client.userScripts[i]);
  94.         }
  95.     }
  96.     
  97.     mainStep();
  98. }
  99.  
  100. function onClose()
  101. {
  102.     if ("userClose" in client && client.userClose)
  103.         return true;
  104.     
  105.     client.userClose = true;
  106.     client.currentObject.display (getMsg("cli_closing"), "INFO");
  107.  
  108.     if (client.getConnectionCount() == 0)
  109.         /* if we're not connected to anything, just close the window */
  110.         return true;
  111.  
  112.     /* otherwise, try to close out gracefully */
  113.     client.quit (client.userAgent);
  114.     return false;
  115. }
  116.  
  117. function onUnload()
  118. {
  119.     if (client.SAVE_SETTINGS)
  120.         writeIRCPrefs();
  121. }
  122.  
  123. function onNotImplemented()
  124. {
  125.  
  126.     alert (getMsg("onNotImplementedMsg"));
  127.     
  128. }
  129.  
  130. /* tab click */
  131. function onTabClick (id)
  132. {
  133.     
  134.     var tbi = document.getElementById (id);
  135.     var view = client.viewsArray[tbi.getAttribute("viewKey")];
  136.  
  137.     setCurrentObject (view.source);
  138.     
  139. }
  140.  
  141. function onMouseOver (e)
  142. {
  143.     var i = 0;
  144.     var target = e.target;
  145.     var status = "";
  146.     while (!status && target && i < 5)
  147.     {
  148.         if ("getAttribute" in target)
  149.         {
  150.             status = target.getAttribute("href");
  151.             if (!status)
  152.                 status = target.getAttribute ("statusText");
  153.         }
  154.         ++i;
  155.         target = target.parentNode;
  156.     }
  157.         
  158.     if (status)
  159.     {
  160.         client.status = status;
  161.     }
  162.     else
  163.     {
  164.         if (client && "defaultStatus" in client)
  165.             client.status = client.defaultStatus;
  166.     }
  167. }
  168.     
  169. function onSimulateCommand (line)
  170. {
  171.     onInputCompleteLine ({line: line}, true);
  172. }
  173.  
  174. function onPopupSimulateCommand (line)
  175. {
  176.     if ("user" in client._popupContext)
  177.     {
  178.         var nick = client._popupContext.user;
  179.         if (nick.indexOf("ME!") != -1)
  180.         {
  181.             var details = getObjectDetails(client.currentObject);
  182.             if ("server" in details)
  183.                 nick = details.server.me.properNick;
  184.         }
  185.  
  186.         line = line.replace (/\$nick/ig, nick);
  187.     }
  188.     
  189.     onInputCompleteLine ({line: line}, true);
  190. }
  191.  
  192. function onPopupHighlight (ruleText)
  193. {
  194.     var user = client._popupContext.user;
  195.     
  196.     var rec = findDynamicRule(".msg[msg-user=" + user + "]");
  197.     
  198.     if (!ruleText)
  199.     {
  200.         if (rec)
  201.             rec.sheet.deleteRule(rec.index);
  202.         /* XXX just deleting it doesn't work */
  203.         addDynamicRule (".msg[msg-user=\"" + user + "\"] { }");
  204.     }
  205.     else
  206.     {
  207.         if (rec)
  208.             rec.sheet.deleteRule(rec.index);
  209.  
  210.         addDynamicRule (".msg[msg-user=\"" + user + "\"] " +
  211.                         "{" + ruleText + "}");
  212.     }
  213.  
  214. }
  215.  
  216. function onToggleMungerEntry(entryName)
  217. {
  218.     client.munger.entries[entryName].enabled =
  219.         !client.munger.entries[entryName].enabled;
  220.     var item = document.getElementById("menu-munger-" + entryName);
  221.     item.setAttribute ("checked", client.munger.entries[entryName].enabled);
  222. }
  223.  
  224. function createPopupContext(event, target)
  225. {
  226.     var targetType;
  227.     client._popupContext = new Object();
  228.     client._popupContext.menu = event.originalTarget;
  229.  
  230.     if (!target)
  231.         return "unknown";
  232.     
  233.     switch (target.tagName.toLowerCase())
  234.     {
  235.         case "html:a":
  236.             var href = target.getAttribute("href");
  237.             client._popupContext.url = href;
  238.             if (href.indexOf("irc://") == 0)
  239.             {
  240.                 var obj = parseIRCUrl(href);
  241.                 if (obj)
  242.                 {
  243.                     if (obj.target)
  244.                         if (obj.isnick)
  245.                         {
  246.                             targetType="nick-ircurl";
  247.                             client._popupContext.user = obj.target;
  248.                         }
  249.                         else
  250.                             targetType="channel-ircurl";
  251.                     else
  252.                         targetType="untargeted-ircurl";
  253.                 }
  254.                 else
  255.                     targetType="weburl";
  256.             }
  257.             else
  258.                 targetType="weburl";
  259.             break;
  260.             
  261.         case "html:td":
  262.             var user = target.getAttribute("msg-user");
  263.             if (user)
  264.             {
  265.                 if (user.indexOf("ME!") != -1)
  266.                     client._popupContext.user = "ME!";
  267.                 else
  268.                     client._popupContext.user = user;
  269.             }
  270.             targetType = target.getAttribute("msg-type");
  271.             break;            
  272.     }
  273.  
  274.     client._popupContext.targetType = targetType;
  275.     client._popupContext.targetClass = target.getAttribute("class");
  276.  
  277.     return targetType;
  278. }
  279.  
  280. function onOutputContextMenuCreate(e)
  281. {
  282.     function evalIfAttribute (node, attr)
  283.     {
  284.         var expr = node.getAttribute(attr);
  285.         if (!expr)
  286.             return true;
  287.         
  288.         expr = expr.replace (/\Wor\W/gi, " || ");
  289.         expr = expr.replace (/\Wand\W/gi, " && ");
  290.         return eval("(" + expr + ")");
  291.     }
  292.         
  293.     var target = document.popupNode;
  294.     var foundSomethingUseful = false;
  295.     
  296.     do
  297.     {
  298.         if ("tagName" in target &&
  299.             (target.tagName == "html:a" || target.tagName == "html:td"))
  300.             foundSomethingUseful = true;
  301.         else
  302.             target = target.parentNode;
  303.     } while (target && !foundSomethingUseful);
  304.     
  305.     var targetType = createPopupContext(e, target);
  306.     var targetClass = ("targetClass" in client._popupContext) ?
  307.         client._popupContext.targetClass : "";
  308.     var viewType = client.currentObject.TYPE;
  309.     var targetIsOp = "n/a";
  310.     var targetIsVoice = "n/a";
  311.     var iAmOp = "n/a";
  312.     var targetUser = ("user" in client._popupContext) ?
  313.         String(client._popupContext.user) : "";
  314.     var details = getObjectDetails(client.currentObject);
  315.     var targetServer = ("server" in details) ? details.server : "";
  316.  
  317.     if (targetServer && targetUser == "ME!")
  318.     {
  319.         targetUser = targetServer.me.nick;
  320.     }
  321.  
  322.     var targetProperNick = targetUser;
  323.     if (targetServer && targetUser in targetServer.users)
  324.         targetProperNick = targetServer.users[targetUser].properNick;
  325.     
  326.     if (viewType == "IRCChannel" && targetUser)
  327.     {
  328.         if (targetUser in client.currentObject.users)
  329.         {
  330.             var cuser = client.currentObject.users[targetUser];
  331.             targetIsOp = cuser.isOp ? "yes" : "no";
  332.             targetIsVoice = cuser.isVoice ? "yes" : "no";
  333.         }
  334.         
  335.         var server = getObjectDetails(client.currentObject).server;
  336.         if (server &&
  337.             server.me.nick in client.currentObject.users &&
  338.             client.currentObject.users[server.me.nick].isOp)
  339.         {
  340.             iAmOp =  "yes";
  341.         }
  342.         else
  343.         {
  344.             iAmOp = "no";
  345.         }
  346.     }
  347.  
  348.     var popup = document.getElementById ("outputContext");
  349.     var menuitem = popup.firstChild;
  350.  
  351.     do
  352.     {
  353.         if (evalIfAttribute(menuitem, "visibleif"))
  354.         {
  355.             menuitem.setAttribute ("hidden", "false");
  356.         }
  357.         else
  358.         {
  359.             menuitem.setAttribute ("hidden", "true");
  360.             continue;
  361.         }
  362.         
  363.         if (menuitem.hasAttribute("checkedif"))
  364.         {
  365.             if (evalIfAttribute(menuitem, "checkedif"))
  366.                 menuitem.setAttribute ("checked", "true");
  367.             else
  368.                 menuitem.setAttribute ("checked", "false");
  369.         }
  370.             
  371.         var format = menuitem.getAttribute("format");
  372.         if (format)
  373.         {
  374.             format = format.replace (/\$nick/gi, targetProperNick);
  375.             format = format.replace (/\$viewname/gi,
  376.                                      client.currentObject.name);
  377.             menuitem.setAttribute ("label", format);
  378.         }
  379.         
  380.     } while ((menuitem = menuitem.nextSibling));
  381.  
  382.     return true;
  383. }
  384.  
  385. /* popup click in user list */
  386. function onUserListPopupClick (e)
  387. {
  388.  
  389.     var code = e.target.getAttribute("code");
  390.     var ary = code.substr(1, code.length).match (/(\S+)? ?(.*)/);    
  391.  
  392.     if (!ary)
  393.         return;
  394.  
  395.     var command = ary[1];
  396.  
  397.     var ev = new CEvent ("client", "input-command", client,
  398.                          "onInputCommand");
  399.     ev.command = command;
  400.     ev.inputData =  ary[2] ? stringTrim(ary[2]) : "";    
  401.     ev.target = client.currentObject;
  402.  
  403.     getObjectDetails (ev.target, ev);
  404.  
  405.     client.eventPump.addEvent (ev);
  406. }
  407.  
  408.  
  409. function onToggleTraceHook()
  410. {
  411.     var h = client.eventPump.getHook ("event-tracer");
  412.     
  413.     h.enabled = client.debugMode = !h.enabled;
  414.     document.getElementById("menu-dmessages").setAttribute ("checked",
  415.                                                             h.enabled);
  416.     if (h.enabled)
  417.         client.currentObject.display (getMsg("debug_on"), "INFO");
  418.     else
  419.         client.currentObject.display (getMsg("debug_off"), "INFO");
  420. }
  421.  
  422. function onToggleSaveOnExit()
  423. {
  424.     client.SAVE_SETTINGS = !client.SAVE_SETTINGS;
  425.     var m = document.getElementById ("menu-settings-autosave");
  426.     m.setAttribute ("checked", String(client.SAVE_SETTINGS));
  427.  
  428.     var pref = Components.classes["@mozilla.org/preferences-service;1"]
  429.                          .getService(Components.interfaces.nsIPrefBranch);
  430.     pref.setBoolPref ("extensions.irc.settings.autoSave",
  431.                       client.SAVE_SETTINGS);
  432. }
  433.  
  434. function onToggleVisibility(thing)
  435. {    
  436.     var menu = document.getElementById("menu-view-" + thing);
  437.     var ids = new Array();
  438.     
  439.     switch (thing)
  440.     {
  441.         case "tabstrip":
  442.             ids = ["view-tabs"];
  443.             break;
  444.             
  445.         case "info":
  446.             ids = ["main-splitter", "user-list-box"];            
  447.             break;
  448.             
  449.         case "header":
  450.             ids = ["header-bar-tbox"];
  451.             break;
  452.             
  453.         case "status":
  454.             ids = ["status-bar"];
  455.             break;
  456.  
  457.         default:
  458.             dd ("** Unknown element ``" + menuId + 
  459.                 "'' passed to onToggleVisibility. **");
  460.             return;
  461.     }
  462.  
  463.  
  464.     var newState;
  465.     var elem = document.getElementById(ids[0]);
  466.     var d = elem.getAttribute("collapsed");
  467.     
  468.     if (d == "true")
  469.     {
  470.         if (thing == "info")
  471.         {
  472.             if (client.currentObject.TYPE == "IRCChannel")
  473.                 client.rdf.setTreeRoot ("user-list", 
  474.                                         client.currentObject.getGraphResource());
  475.             else
  476.                 client.rdf.setTreeRoot ("user-list", client.rdf.resNullChan);
  477.         }
  478.         
  479.         newState = "false";
  480.         menu.setAttribute ("checked", "true");
  481.         client.uiState[thing] = true;
  482.     }
  483.     else
  484.     {
  485.         newState = "true";
  486.         menu.setAttribute ("checked", "false");
  487.         client.uiState[thing] = false;
  488.     }
  489.     
  490.     for (var i in ids)
  491.     {
  492.         elem = document.getElementById(ids[i]);
  493.         elem.setAttribute ("collapsed", newState);
  494.     }
  495.  
  496.     updateTitle();
  497.     focusInput();
  498. }
  499.  
  500. function onDoStyleChange (newStyle)
  501. {
  502.  
  503.     if (newStyle == "other")
  504.         newStyle = window.prompt (getMsg("onDoStyleChangeMsg"));
  505.  
  506.     if (newStyle)
  507.     {
  508.         setOutputStyle (newStyle);
  509.         setCurrentObject(client.currentObject);
  510.     }
  511.     
  512. }
  513.  
  514. function onHideCurrentView()
  515. {
  516.     var tb = getTabForObject(client.currentObject);
  517.     
  518.     if (tb)
  519.     {
  520.         var i = deleteTab (tb);
  521.         if (i != -1)
  522.         {
  523.             if (i >= client.viewsArray.length)
  524.                 i = client.viewsArray.length - 1;
  525.             
  526.             setCurrentObject (client.viewsArray[i].source);
  527.         }
  528.         
  529.     }
  530. }
  531.  
  532. function onDeleteView(view)
  533. {
  534.     var tb = getTabForObject(view);
  535.     if (client.viewsArray.length < 2)
  536.     {
  537.         view.display (getMsg("onDeleteViewMsg"), "ERROR");
  538.         return;
  539.     }
  540.     
  541.     if (tb)
  542.     {
  543.         var i = deleteTab (tb);
  544.         if (i != -1)
  545.         {
  546.             delete view.messageCount;
  547.             delete view.messages;
  548.  
  549.             if (i >= client.viewsArray.length)
  550.                 i = client.viewsArray.length - 1;            
  551.             setCurrentObject (client.viewsArray[i].source);
  552.         }
  553.         
  554.     }
  555.     
  556. }
  557.  
  558. function onClearCurrentView()
  559. {
  560.  
  561.     if (client.output.firstChild)
  562.         client.output.removeChild (client.output.firstChild);
  563.  
  564.     client.currentObject.messages = null;
  565.     client.currentObject.messageCount = 0;
  566.  
  567.     client.currentObject.display (getMsg("onClearCurrentViewMsg"), "INFO");
  568.  
  569.     client.output.appendChild (client.currentObject.messages);
  570.     
  571. }
  572.  
  573. function onSortCol(sortColName)
  574. {
  575.     const nsIXULSortService = Components.interfaces.nsIXULSortService;
  576.    /* XXX remove the rdf version once 0.8 is a distant memory
  577.     * 2/22/2001
  578.     */
  579.     const isupports_uri =
  580.         (Components.classes["@mozilla.org/xul/xul-sort-service;1"]) ?
  581.          "@mozilla.org/xul/xul-sort-service;1" :
  582.          "@mozilla.org/rdf/xul-sort-service;1";
  583.     
  584.     var node = document.getElementById(sortColName);
  585.     if (!node)
  586.         return false;
  587.  
  588.     // determine column resource to sort on
  589.     var sortResource = node.getAttribute("resource");
  590.     var sortDirection = "ascending";
  591.         //node.setAttribute("sortActive", "true");
  592.  
  593.     switch (sortColName)
  594.     {
  595.         case "usercol-op":
  596.             document.getElementById("usercol-voice")
  597.                 .setAttribute("sortDirection", "natural");
  598.             document.getElementById("usercol-nick")
  599.                 .setAttribute("sortDirection", "natural");
  600.             break;
  601.         case "usercol-voice":
  602.             document.getElementById("usercol-op")
  603.                 .setAttribute("sortDirection", "natural");
  604.             document.getElementById("usercol-nick")
  605.                 .setAttribute("sortDirection", "natural");
  606.             break;
  607.         case "usercol-nick":
  608.             document.getElementById("usercol-voice")
  609.                 .setAttribute("sortDirection", "natural");
  610.             document.getElementById("usercol-op")
  611.                 .setAttribute("sortDirection", "natural");
  612.             break;
  613.     }
  614.     
  615.     var currentDirection = node.getAttribute("sortDirection");
  616.     
  617.     if (currentDirection == "ascending")
  618.         sortDirection = "descending";
  619.     else if (currentDirection == "descending")
  620.         sortDirection = "natural";
  621.     else
  622.         sortDirection = "ascending";
  623.     
  624.     node.setAttribute ("sortDirection", sortDirection);
  625.  
  626.     var xulSortService =
  627.         Components.classes[isupports_uri].getService(nsIXULSortService);
  628.     if (!xulSortService)
  629.         return false;
  630.     try
  631.     {
  632.         xulSortService.Sort(node, sortResource, sortDirection);
  633.     }
  634.     catch(ex)
  635.     {
  636.             //dd("Exception calling xulSortService.Sort()");
  637.     }
  638.     
  639.     return false;
  640. }
  641.  
  642. function onToggleMunger()
  643. {
  644.  
  645.     client.munger.enabled = !client.munger.enabled;
  646.     var item = document.getElementById("menu-munger-global");
  647.     item.setAttribute ("checked", !client.munger.enabled);
  648.  
  649. }
  650.  
  651. function onToggleColors()
  652. {
  653.  
  654.     client.enableColors = !client.enableColors;
  655.     document.getElementById("menu-colors").setAttribute ("checked",
  656.                                                          client.enableColors);
  657.  
  658. }
  659.  
  660. function onMultilineInputKeyPress (e)
  661. {
  662.     if ((e.ctrlKey || e.metaKey) && e.keyCode == 13)
  663.     {
  664.         /* meta-enter, execute buffer */
  665.         e.line = e.target.value;
  666.         onInputCompleteLine (e);
  667.     }
  668.     else
  669.     {
  670.         if ((e.ctrlKey || e.metaKey) && e.keyCode == 40)
  671.         {
  672.             /* ctrl/meta-down, switch to single line mode */
  673.             multilineInputMode (false);
  674.         }
  675.     }
  676. }
  677.  
  678. function onToggleMsgCollapse()
  679. {
  680.     client.COLLAPSE_MSGS = !client.COLLAPSE_MSGS;
  681. }
  682.  
  683. function onToggleCopyMessages()
  684. {
  685.     client.COPY_MESSAGES = !client.COPY_MESSAGES;
  686. }
  687.  
  688. function onToggleStartupURL()
  689. {
  690.     var tb = getTabForObject (client.currentObject);
  691.     if (!tb)
  692.         return;
  693.     
  694.     var vk = Number(tb.getAttribute("viewKey"));
  695.     
  696.     var ary = client.INITIAL_URLS ? 
  697.         client.INITIAL_URLS.split(/\s*;\s*/) : new Array();
  698.     var url = client.currentObject.getURL();
  699.     var index = arrayIndexOf(ary, url);
  700.     if (index != -1)
  701.         arrayRemoveAt(ary, index);
  702.     else
  703.         ary.push(url);
  704.     
  705.     client.INITIAL_URLS = ary.join ("; ");
  706. }
  707.  
  708. function onViewMenuShowing ()
  709. {
  710.     var loc = frames[0].document.location.href;
  711.     loc = loc.substr (loc.indexOf("?") + 1);
  712.  
  713.     var val = (loc == "chrome://chatzilla/skin/output-default.css");
  714.     document.getElementById ("menu-view-default").setAttribute ("checked", val);
  715.  
  716.     val = (loc == "chrome://chatzilla/skin/output-dark.css");
  717.     document.getElementById ("menu-view-dark").setAttribute ("checked", val);
  718.  
  719.     val = (loc == "chrome://chatzilla/skin/output-light.css");
  720.     document.getElementById ("menu-view-light").setAttribute ("checked", val);
  721.  
  722.     val = client.COLLAPSE_MSGS;
  723.     document.getElementById ("menu-view-collapse").setAttribute ("checked", val);
  724.  
  725.     val = client.COPY_MESSAGES;
  726.     document.getElementById ("menu-view-copymsgs").setAttribute ("checked", val);
  727.     
  728.     val = isStartupURL(client.currentObject.getURL());
  729.     document.getElementById ("menu-view-startup").setAttribute ("checked", val);
  730.     return true;
  731. }
  732.     
  733. function onInputKeyPress (e)
  734. {
  735.     
  736.     switch (e.keyCode)
  737.     {        
  738.         case 13: /* CR */
  739.             e.line = stringTrim(e.target.value);
  740.             if (!e.line)
  741.                 return;
  742.             onInputCompleteLine (e);
  743.             e.target.value = "";            
  744.             break;
  745.  
  746.         case 38: /* up */
  747.             if (e.ctrlKey || e.metaKey)
  748.             {
  749.                 /* ctrl/meta-up, switch to multi line mode */
  750.                 multilineInputMode (true);
  751.             }
  752.             else
  753.             {
  754.                 if (client.lastHistoryReferenced == -2)
  755.                 {
  756.                     client.lastHistoryReferenced = -1;
  757.                     e.target.value = client.incompleteLine;
  758.                 }
  759.                 else if (client.lastHistoryReferenced <
  760.                          client.inputHistory.length - 1)
  761.                 {
  762.                     e.target.value =
  763.                         client.inputHistory[++client.lastHistoryReferenced];
  764.                 }
  765.             }
  766.             break;
  767.  
  768.         case 40: /* down */
  769.             if (client.lastHistoryReferenced > 0)
  770.                 e.target.value =
  771.                     client.inputHistory[--client.lastHistoryReferenced];
  772.             else if (client.lastHistoryReferenced == -1)
  773.             {
  774.                 e.target.value = "";
  775.                 client.lastHistoryReferenced = -2;
  776.             }
  777.             else
  778.             {
  779.                 client.lastHistoryReferenced = -1;
  780.                 e.target.value = client.incompleteLine;
  781.             }
  782.             break;
  783.  
  784.         default:
  785.             client.lastHistoryReferenced = -1;
  786.             client.incompleteLine = e.target.value;
  787.             break;
  788.     }
  789.  
  790. }
  791.  
  792. function onTest ()
  793. {
  794.  
  795. }
  796.  
  797. function onTabCompleteRequest (e)
  798. {
  799.     var elem = document.commandDispatcher.focusedElement;
  800.     var singleInput = document.getElementById("input");
  801.     if (document.getBindingParent(elem) != singleInput)
  802.         return;
  803.  
  804.     e.preventDefault();
  805.     
  806.     var selStart = singleInput.selectionStart;
  807.     var selEnd = singleInput.selectionEnd;            
  808.     var line = singleInput.value;
  809.  
  810.     if (!line)
  811.     {
  812.         if ("defaultCompletion" in client.currentObject)
  813.             singleInput.value = client.currentObject.defaultCompletion;
  814.         return;
  815.     }
  816.     
  817.     if (selStart != selEnd) 
  818.     {
  819.         /* text is highlighted, just move caret to end and exit */
  820.         singleInput.selectionStart = singleInput.selectionEnd = line.length;
  821.         return;
  822.     }
  823.  
  824.     var wordStart = line.substr(0, selStart).search(/\s\w*$/);
  825.     if (wordStart == -1)
  826.         wordStart = 0;
  827.     else
  828.         ++wordStart;
  829.     
  830.     var wordEnd = line.substr(selStart).search(/\s/);
  831.     if (wordEnd == -1)
  832.         wordEnd = line.length;
  833.     else
  834.         wordEnd += selStart;
  835.  
  836.     if ("performTabMatch" in client.currentObject)
  837.     {
  838.         var word = line.substring (wordStart, wordEnd);
  839.         var matches = client.currentObject.performTabMatch (line, wordStart,
  840.                                                             wordEnd,
  841.                                                             word.toLowerCase(),
  842.                                                             selStart);
  843.         /* if we get null back, we're supposed to fail silently */
  844.         if (!matches)
  845.             return;
  846.  
  847.         var doubleTab = false;
  848.         var date = new Date();
  849.         if ((date - client.lastTabUp) <= client.DOUBLETAB_TIME)
  850.             doubleTab = true;
  851.         else
  852.             client.lastTabUp = date;
  853.  
  854.         if (doubleTab)
  855.         {
  856.             /* if the user hit tab twice quickly, */
  857.             if (matches.length > 0)
  858.             {
  859.                 /* then list possible completions, */
  860.                 client.currentObject.display(getMsg("tabCompleteList",
  861.                                                     [matches.length, word,
  862.                                                      matches.join(MSG_CSP)]),
  863.                                              "INFO");
  864.             }
  865.             else
  866.             {
  867.                 /* or display an error if there are none. */
  868.                 client.currentObject.display(getMsg("tabCompleteError", [word]),
  869.                                              "ERROR");
  870.             }
  871.         }
  872.         else if (matches.length >= 1)
  873.         {
  874.             var match;
  875.             if (matches.length == 1)
  876.                 match = matches[0];
  877.             else
  878.                 match = getCommonPfx(matches);
  879.             singleInput.value = line.substr(0, wordStart) + match + 
  880.                     line.substr(wordEnd);
  881.             if (wordEnd < line.length)
  882.             {
  883.                 /* if the word we completed was in the middle if the line
  884.                  * then move the cursor to the end of the completed word. */
  885.                 var newpos = wordStart + match.length;
  886.                 if (matches.length == 1)
  887.                 {
  888.                     /* word was fully completed, move one additional space */
  889.                     ++newpos;
  890.                 }
  891.                 singleInput.selectionEnd = e.target.selectionStart = newpos;
  892.             }
  893.         }
  894.     }
  895.  
  896. }
  897.  
  898. function onWindowKeyPress (e)
  899. {
  900.     var code = Number (e.keyCode);
  901.     var w;
  902.     var newOfs;
  903.     
  904.     switch (code)
  905.     {
  906.         case 112: /* F1 */
  907.         case 113: /* ... */
  908.         case 114:
  909.         case 115:
  910.         case 116:
  911.         case 117:
  912.         case 118:
  913.         case 119:
  914.         case 120:
  915.         case 121: /* F10 */
  916.             var idx = code - 112;
  917.             if ((idx in client.viewsArray) && (client.viewsArray[idx].source))
  918.                 setCurrentObject(client.viewsArray[idx].source);
  919.             break;
  920.  
  921.         case 33: /* pgup */
  922.             w = window.frames[0];
  923.             newOfs = w.pageYOffset - (w.innerHeight / 2);
  924.             if (newOfs > 0)
  925.                 w.scrollTo (w.pageXOffset, newOfs);
  926.             else
  927.                 w.scrollTo (w.pageXOffset, 0);
  928.             e.preventDefault();
  929.             break;
  930.             
  931.         case 34: /* pgdn */
  932.             w = window.frames[0];
  933.             newOfs = w.pageYOffset + (w.innerHeight / 2);
  934.             if (newOfs < (w.innerHeight + w.pageYOffset))
  935.                 w.scrollTo (w.pageXOffset, newOfs);
  936.             else
  937.                 w.scrollTo (w.pageXOffset, (w.innerHeight + w.pageYOffset));
  938.             e.preventDefault();
  939.             break;
  940.  
  941.         case 9: /* tab */
  942.             e.preventDefault();
  943.             break;
  944.             
  945.         default:
  946.             
  947.     }
  948.  
  949. }
  950.  
  951. function onInputCompleteLine(e, simulated)
  952. {
  953.  
  954.     if (!simulated)
  955.     {
  956.         if (client.inputHistory[0] != e.line)
  957.             client.inputHistory.unshift (e.line);
  958.     
  959.         if (client.inputHistory.length > client.MAX_HISTORY)
  960.             client.inputHistory.pop();
  961.         
  962.         client.lastHistoryReferenced = -1;
  963.         client.incompleteLine = "";
  964.     }
  965.     
  966.     if (e.line[0] == client.COMMAND_CHAR)
  967.     {
  968.         var ary = e.line.substr(1, e.line.length).match (/(\S+)? ?(.*)/);
  969.         var command = ary[1].toLowerCase();
  970.         
  971.         var ev = new CEvent ("client", "input-command", client,
  972.                              "onInputCommand");
  973.         ev.command = command;
  974.         ev.inputData =  ary[2] ? stringTrim(ary[2]) : "";
  975.         ev.line = e.line;
  976.         
  977.         ev.target = client.currentObject;
  978.         getObjectDetails (ev.target, ev);
  979.         client.eventPump.addEvent (ev);
  980.     }
  981.     else /* plain text */
  982.     {
  983.         client.sayToCurrentTarget (e.line);
  984.     }
  985. }
  986.  
  987. function onNotifyTimeout ()
  988. {
  989.     for (var n in client.networks)
  990.     {
  991.         var net = client.networks[n];
  992.         if (net.isConnected()) {
  993.             if ("notifyList" in net && net.notifyList.length > 0) {
  994.                 net.primServ.sendData ("ISON " +
  995.                                        client.networks[n].notifyList.join(" ")
  996.                                        + "\n");
  997.             } else {
  998.                 /* if the notify list is empty, just send a ping to see if we're
  999.                  * alive. */
  1000.                 net.primServ.sendData ("PING :ALIVECHECK\n");
  1001.             }
  1002.         }
  1003.     }
  1004. }
  1005.     
  1006. client.onInputCancel =
  1007. function cli_icancel (e)
  1008. {
  1009.     if (client.currentObject.TYPE != "IRCNetwork")
  1010.     {
  1011.         client.currentObject.display (getMsg("cli_icancelMsg"), "ERROR");
  1012.         return false;
  1013.     }
  1014.     
  1015.     if (!client.currentObject.connecting)
  1016.     {
  1017.         client.currentObject.display (getMsg("cli_icancelMsg2"), "ERROR");
  1018.         return false;
  1019.     }
  1020.     
  1021.     client.currentObject.connectAttempt = 
  1022.         client.currentObject.MAX_CONNECT_ATTEMPTS + 1;
  1023.  
  1024.     client.currentObject.display (getMsg("cli_icancelMsg3",
  1025.                                          client.currentObject.name), "INFO");
  1026.  
  1027.     return true;
  1028. }    
  1029.  
  1030. client.onInputCharset =
  1031. function cli_icharset (e)
  1032. {
  1033.     if (e.inputData)
  1034.     {
  1035.         if (!setCharset(e.inputData))
  1036.         {
  1037.             client.currentObject.display (getMsg("cli_charsetError",
  1038.                                                  e.inputData),
  1039.                                           "ERROR");
  1040.             return false;
  1041.         }
  1042.     }
  1043.  
  1044.     client.currentObject.display (getMsg("cli_currentCharset", client.CHARSET),
  1045.                                   "INFO");
  1046.     return true;
  1047. }
  1048.  
  1049. client.onInputCommand = 
  1050. function cli_icommand (e)
  1051. {
  1052.     var ary = client.commands.list (e.command);
  1053.     
  1054.     if (ary.length == 0)
  1055.     {        
  1056.         var o = getObjectDetails(client.currentObject);
  1057.         if ("server" in o)
  1058.         {
  1059.             client.currentObject.display (getMsg("cli_icommandMsg",
  1060.                                                  e.command), "WARNING");
  1061.             o.server.sendData (e.command + " " + e.inputData + "\n");
  1062.         }
  1063.         else
  1064.             client.currentObject.display (getMsg("cli_icommandMsg2",
  1065.                                                  e.command), "ERROR");
  1066.     }
  1067.     else if (ary.length == 1 || ary[0].name == e.command)
  1068.     {
  1069.         if (typeof client[ary[0].func] == "undefined")        
  1070.             client.currentObject.display (getMsg("cli_icommandMsg3",
  1071.                                                  ary[0].name), "ERROR");
  1072.         else
  1073.         {
  1074.             e.commandEntry = ary[0];
  1075.             if (!client[ary[0].func](e))
  1076.                 client.currentObject.display (ary[0].name + " " +
  1077.                                               ary[0].usage, "USAGE");
  1078.         }
  1079.     }
  1080.     else
  1081.     {
  1082.         client.currentObject.display (getMsg("cli_icommandMsg4",
  1083.                                              e.command), "ERROR");
  1084.         var str = "";
  1085.         for (var i in ary)
  1086.             str += str ? ", " + ary[i].name : ary[i].name;
  1087.         client.currentObject.display (getMsg("cli_icommandMsg5",
  1088.                                              [ary.length, str]), "ERROR");
  1089.     }
  1090.  
  1091. }
  1092.  
  1093. client.onInputCSS =
  1094. function cli_icss (e)
  1095. {
  1096.     if (!e.inputData)
  1097.         return false;
  1098.  
  1099.     e.inputData = stringTrim(e.inputData);
  1100.     
  1101.     if (e.inputData.search(/^light$/i) != -1)
  1102.         e.inputData = "chrome://chatzilla/skin/output-light.css";
  1103.     else if (e.inputData.search(/^dark$/i) != -1)
  1104.         e.inputData = "chrome://chatzilla/skin/output-dark.css";
  1105.     else if (e.inputData.search(/^default$/i) != -1)
  1106.         e.inputData = "chrome://chatzilla/skin/output-default.css";
  1107.     else if (e.inputData.search(/^none$/i) != -1)
  1108.         e.inputData = "chrome://chatzilla/content/output-base.css";
  1109.     
  1110.     client.currentObject.display (getMsg("cli_icss", e.inputData), "INFO");
  1111.     
  1112.     frames[0].document.location.href =
  1113.         "chrome://chatzilla/content/outputwindow.html?" + e.inputData;
  1114.     client.DEFAULT_STYLE = e.inputData;
  1115.     return true;
  1116. }
  1117.  
  1118. client.onInputSimpleCommand =
  1119. function cli_iscommand (e)
  1120. {    
  1121.     var o = getObjectDetails(client.currentObject);
  1122.     
  1123.     if ("server" in o)
  1124.     {
  1125.         o.server.sendData (e.command + " " + e.inputData + "\n");
  1126.         return true;
  1127.     }
  1128.     else
  1129.     {
  1130.         client.currentObject.display (getMsg("onInputSimpleCommandMsg",
  1131.                                              e.command),"WARNING");
  1132.         return false;
  1133.     }
  1134. }
  1135.  
  1136. client.onInputStatus =
  1137. function cli_istatus (e)
  1138. {    
  1139.     function serverStatus (s)
  1140.     {
  1141.         if (!s.connection.isConnected)
  1142.         {
  1143.             client.currentObject.display(getMsg("cli_istatusServerOff",
  1144.                                                 s.parent.name), "STATUS");
  1145.             return;
  1146.         }
  1147.         
  1148.         var serverType = (s.parent.primServ == s) ?
  1149.             getMsg("cli_istatusPrimary") : getMsg("cli_istatusSecondary");
  1150.         client.currentObject.display(getMsg("cli_istatusServerOn",
  1151.                                             [s.parent.name, s.me.properNick,
  1152.                                              s.connection.host,
  1153.                                              s.connection.port, serverType]),
  1154.                                      "STATUS");        
  1155.  
  1156.         var connectTime = formatDateOffset ((new Date() -
  1157.                                              s.connection.connectDate) / 1000);
  1158.         var pingTime = (s.lastPing) ?
  1159.             formatDateOffset ((new Date() - s.lastPing) / 1000) : getMsg("na");
  1160.         var lag = (s.lag >= 0) ? s.lag : getMsg("na");
  1161.  
  1162.         client.currentObject.display(getMsg("cli_istatusServerDetail", 
  1163.                                             [s.parent.name, connectTime,
  1164.                                              pingTime, lag]), "STATUS");
  1165.     }
  1166.  
  1167.     function channelStatus (c)
  1168.     {
  1169.         var cu;
  1170.         var net = c.parent.parent.name;
  1171.  
  1172.         if ((cu = c.users[c.parent.me.nick]))
  1173.         {
  1174.             var mtype;
  1175.             
  1176.             if (cu.isOp && cu.isVoice)
  1177.                 mtype = getMsg("cli_istatusBoth");
  1178.             else if (cu.isOp)
  1179.                 mtype = getMsg("cli_istatusOperator");
  1180.             else if (cu.isVoice)
  1181.                 mtype = getMsg("cli_istatusVoiced");
  1182.             else
  1183.                 mtype = getMsg("cli_istatusMember");
  1184.  
  1185.             var mode = c.mode.getModeStr();
  1186.             if (!mode)
  1187.                 mode = getMsg("cli_istatusNoMode");
  1188.             
  1189.             client.currentObject.display (getMsg("cli_istatusChannelOn",
  1190.                                                  [net, mtype, c.name, mode,
  1191.                                                   "irc://" + escape(net) + "/" +
  1192.                                                   escape(c.name) + "/"]),
  1193.                                           "STATUS");
  1194.             client.currentObject.display (getMsg("cli_istatusChannelDetail",
  1195.                                                  [net, c.name,
  1196.                                                   c.getUsersLength(),
  1197.                                                   c.opCount, c.voiceCount]),
  1198.                                           "STATUS");
  1199.             if (c.topic)
  1200.                 client.currentObject.display (getMsg("cli_istatusChannelTopic",
  1201.                                                      [net, c.name, c.topic]),
  1202.                                               "STATUS");
  1203.             else
  1204.                 client.currentObject.display (getMsg("cli_istatusChannelNoTopic",
  1205.                                                      [net, c.name]), "STATUS");
  1206.         }
  1207.         else
  1208.             client.currentObject.display (getMsg("cli_istatusChannelOff",
  1209.                                                  [net, c.name]), "STATUS");
  1210.     }
  1211.  
  1212.     client.currentObject.display (client.userAgent, "STATUS");
  1213.     client.currentObject.display (getMsg("cli_istatusClient",
  1214.                                          [CIRCNetwork.prototype.INITIAL_NICK,
  1215.                                          CIRCNetwork.prototype.INITIAL_NAME,
  1216.                                          CIRCNetwork.prototype.INITIAL_DESC]),
  1217.                                   "STATUS");
  1218.         
  1219.     var n, s, c;
  1220.  
  1221.     switch (client.currentObject.TYPE)
  1222.     {
  1223.         case "IRCNetwork":
  1224.             for (s in client.currentObject.servers)
  1225.             {
  1226.                 serverStatus(client.currentObject.servers[s]);
  1227.                 for (c in client.currentObject.servers[s].channels)
  1228.                     channelStatus (client.currentObject.servers[s].channels[c]);
  1229.             }
  1230.             break;
  1231.  
  1232.         case "IRCChannel":
  1233.             serverStatus(client.currentObject.parent);
  1234.             channelStatus(client.currentObject);
  1235.             break;
  1236.             
  1237.         default:
  1238.             for (n in client.networks)
  1239.                 for (s in client.networks[n].servers)
  1240.                 {
  1241.                     serverStatus(client.networks[n].servers[s]);
  1242.                     for (c in client.networks[n].servers[s].channels)
  1243.                         channelStatus (client.networks[n].servers[s].channels[c]);
  1244.                 }
  1245.             break;
  1246.     }
  1247.  
  1248.     client.currentObject.display (getMsg("cli_istatusEnd"), "END_STATUS");
  1249.     return true;
  1250.     
  1251. }            
  1252.             
  1253. client.onInputHelp =
  1254. function cli_ihelp (e)
  1255. {
  1256.     var ary = client.commands.list (e.inputData);
  1257.  
  1258.     if (ary.length == 0)
  1259.     {
  1260.         client.currentObject.display (getMsg("cli_ihelpMsg", e.inputData),
  1261.                                       "ERROR");
  1262.         return false;
  1263.     }
  1264.  
  1265.     var saveDir = client.PRINT_DIRECTION;
  1266.     client.PRINT_DIRECTION = 1;
  1267.     
  1268.     for (var i in ary)
  1269.     {        
  1270.         client.currentObject.display (ary[i].name + " " + ary[i].usage,
  1271.                                       "USAGE");
  1272.         client.currentObject.display (ary[i].help, "HELP");
  1273.     }
  1274.  
  1275.     client.PRINT_DIRECTION = saveDir;
  1276.     
  1277.     return true;
  1278.     
  1279. }
  1280.  
  1281. client.onInputTestDisplay =
  1282. function cli_testdisplay (e)
  1283. {
  1284.     var o = getObjectDetails(client.currentObject);
  1285.     
  1286.     client.currentObject.display (getMsg("cli_testdisplayMsg"), "HELLO");
  1287.     client.currentObject.display (getMsg("cli_testdisplayMsg2"), "INFO");
  1288.     client.currentObject.display (getMsg("cli_testdisplayMsg3"), "ERROR");
  1289.     client.currentObject.display (getMsg("cli_testdisplayMsg4"), "HELP");
  1290.     client.currentObject.display (getMsg("cli_testdisplayMsg5"), "USAGE");
  1291.     client.currentObject.display (getMsg("cli_testdisplayMsg6"), "STATUS");
  1292.  
  1293.     if (o.server && o.server.me)
  1294.     {
  1295.         var me = o.server.me;
  1296.         var viewType = client.currentObject.TYPE;
  1297.         var sampleUser = {TYPE: "IRCUser", nick: "ircmonkey",
  1298.                           name: "IRCMonkey", properNick: "IRCMonkey",
  1299.                           host: ""};
  1300.         var sampleChannel = {TYPE: "IRCChannel", name: "#mojo"};
  1301.  
  1302.         function test (from, to)
  1303.         {
  1304.             var fromText = (from != me) ? from.TYPE + " ``" + from.name + "''" :
  1305.                 getMsg("cli_testdisplayYou");
  1306.             var toText   = (to != me) ? to.TYPE + " ``" + to.name + "''" :
  1307.                 getMsg("cli_testdisplayYou");
  1308.             
  1309.             client.currentObject.display (getMsg("cli_testdisplayMsg7",
  1310.                                                  [fromText, toText]),
  1311.                                           "PRIVMSG", from, to);
  1312.             client.currentObject.display (getMsg("cli_testdisplayMsg8",
  1313.                                                  [fromText, toText]),
  1314.                                           "ACTION", from, to);
  1315.             client.currentObject.display (getMsg("cli_testdisplayMsg9",
  1316.                                                  [fromText, toText]),
  1317.                                           "NOTICE", from, to);
  1318.         }
  1319.         
  1320.         test (sampleUser, me); /* from user to me */
  1321.         test (me, sampleUser); /* me to user */
  1322.  
  1323.         client.currentObject.display (getMsg("cli_testdisplayMsg10"),
  1324.                                       "PRIVMSG", sampleUser, me);
  1325.         client.currentObject.display (getMsg("cli_testdisplayMsg11"),
  1326.                                       "PRIVMSG", sampleUser, me);
  1327.         client.currentObject.display (getMsg("cli_testdisplayMsg12"),
  1328.                                       "PRIVMSG", sampleUser, me);
  1329.         client.currentObject.display (getMsg("cli_testdisplayMsg13"),
  1330.                                       "PRIVMSG", sampleUser, me);
  1331.         client.currentObject.display (unescape(getMsg("cli_testdisplayMsg20")),
  1332.                                       "PRIVMSG", sampleUser, me);
  1333.         client.currentObject.display (unescape(getMsg("cli_testdisplayMsg21")),
  1334.                                       "PRIVMSG", sampleUser, me);
  1335.         
  1336.  
  1337.         if (viewType == "IRCChannel")
  1338.         {
  1339.             test (sampleUser, sampleChannel); /* user to channel */
  1340.             test (me, sampleChannel);         /* me to channel */
  1341.             client.currentObject.display (getMsg("cli_testdisplayMsg14"),
  1342.                                           "TOPIC", sampleUser, sampleChannel);
  1343.             client.currentObject.display (getMsg("cli_testdisplayMsg15"), "JOIN",
  1344.                                           sampleUser, sampleChannel);
  1345.             client.currentObject.display (getMsg("cli_testdisplayMsg16"), "PART",
  1346.                                           sampleUser, sampleChannel);
  1347.             client.currentObject.display (getMsg("cli_testdisplayMsg17"), "KICK",
  1348.                                           sampleUser, sampleChannel);
  1349.             client.currentObject.display (getMsg("cli_testdisplayMsg18"), "QUIT",
  1350.                                           sampleUser, sampleChannel);
  1351.             client.currentObject.display (getMsg("cli_testdisplayMsg19",
  1352.                                                  me.nick),
  1353.                                           "PRIVMSG", sampleUser, sampleChannel);
  1354.             client.currentObject.display (getMsg("cli_testdisplayMsg11"),
  1355.                                           "PRIVMSG", me, sampleChannel);
  1356.         }        
  1357.         
  1358.     }
  1359.     
  1360.     return true;
  1361.     
  1362. }   
  1363.  
  1364. client.onInputNetwork =
  1365. function cli_inetwork (e)
  1366. {
  1367.     if (!e.inputData)
  1368.         return false;
  1369.  
  1370.     var net = client.networks[e.inputData];
  1371.  
  1372.     if (net)
  1373.     {
  1374.         setCurrentObject (net);    
  1375.     }
  1376.     else
  1377.     {
  1378.         client.currentObject.display (getMsg("cli_inetworkMsg",e.inputData),
  1379.                                       "ERROR");
  1380.         return false;
  1381.     }
  1382.     
  1383.     return true;
  1384.     
  1385. }
  1386.  
  1387. client.onInputNetworks =
  1388. function clie_ilistnets (e)
  1389. {
  1390.     var span = document.createElementNS("http://www.w3.org/1999/xhtml",
  1391.                                         "html:span");
  1392.     
  1393.     span.appendChild (newInlineText(getMsg("cli_listNetworks.a")));
  1394.  
  1395.     var netnames = keys(client.networks).sort();
  1396.     var lastname = netnames[netnames.length - 1];
  1397.     
  1398.     for (n in netnames)
  1399.     {
  1400.         var net = client.networks[netnames[n]];
  1401.         var a = document.createElementNS("http://www.w3.org/1999/xhtml",
  1402.                                          "html:a");
  1403.         a.setAttribute ("class", "chatzilla-link");
  1404.         a.setAttribute ("href", "irc://" + net.name);
  1405.         var t = newInlineText (net.name);
  1406.         a.appendChild (t);
  1407.         span.appendChild (a);
  1408.         if (netnames[n] != lastname)
  1409.             span.appendChild (newInlineText (MSG_CSP));
  1410.     }
  1411.  
  1412.     span.appendChild (newInlineText(getMsg("cli_listNetworks.b")));
  1413.  
  1414.     client.currentObject.display (span, "INFO");
  1415.     return true;
  1416. }   
  1417.  
  1418. client.onInputServer =
  1419. function cli_iserver (e)
  1420. {
  1421.     if (!e.inputData)
  1422.         return false;
  1423.  
  1424.     var ary = 
  1425.         e.inputData.match(/^([^\s\:]+)[\s\:]?(?:(\d+)(?:\s+(\S+)|\s*$)|(\S+)|$)/);
  1426.     var pass;
  1427.     if (3 in ary && ary[3])
  1428.         pass = ary[3];
  1429.     else if (4 in ary && ary[4])
  1430.         pass = ary[4];
  1431.     
  1432.     if (ary == null)
  1433.         return false;
  1434.  
  1435.     var port;
  1436.     if (2 in ary && ary[2])
  1437.         port = ary[2];
  1438.     else
  1439.         port = 6667;
  1440.  
  1441.     var net = null;
  1442.     
  1443.     for (var n in client.networks)
  1444.     {
  1445.         if (n == ary[1])
  1446.         {
  1447.             if (client.networks[n].isConnected())
  1448.             {
  1449.                 client.currentObject.display (getMsg("cli_iserverMsg",ary[1]),
  1450.                                               "ERROR");
  1451.                 return false;
  1452.             }
  1453.             else
  1454.             {
  1455.                 net = client.networks[n];
  1456.                 break;
  1457.             }
  1458.         }
  1459.     }
  1460.  
  1461.     if (!net)
  1462.     {
  1463.         /* if there wasn't already a network created for this server,
  1464.          * make one. */
  1465.         client.networks[ary[1]] =
  1466.             new CIRCNetwork (ary[1],
  1467.                              [{name: ary[1], port: port, password: pass}],
  1468.                              client.eventPump);
  1469.     }
  1470.     else
  1471.     {
  1472.         /* if we've already created a network for this server, reinit the
  1473.          * serverList, in case the user changed the port or password */
  1474.         net.serverList = [{name: ary[1], port: port, password: pass}];
  1475.     }
  1476.  
  1477.     client.connectToNetwork (ary[1]);
  1478.     return true;
  1479.  
  1480. }
  1481.  
  1482. client.onInputQuit =
  1483. function cli_quit (e)
  1484. {
  1485.     if (!("server" in e))
  1486.     {
  1487.         client.currentObject.display (getMsg("cli_quitMsg"), "ERROR");
  1488.         return false;
  1489.     }
  1490.  
  1491.     if (!e.server.connection.isConnected)
  1492.     {
  1493.         client.currentObject.display (getMsg("cli_quitMsg2"), "ERROR");
  1494.         return false;
  1495.     }
  1496.  
  1497.     e.server.logout (e.inputData);
  1498.  
  1499.     return true;
  1500.     
  1501. }
  1502.  
  1503. client.onInputExit =
  1504. function cli_exit (e)
  1505. {
  1506.     client.quit(e.inputData);    
  1507.     window.close();
  1508.     return true;
  1509. }
  1510.  
  1511. client.onInputDelete =
  1512. function cli_idelete (e)
  1513. {
  1514.     if ("inputData" in e && e.inputData)
  1515.         return false;
  1516.     onDeleteView(client.currentObject);
  1517.     return true;
  1518.  
  1519. }
  1520.  
  1521. client.onInputHide=
  1522. function cli_ihide (e)
  1523. {
  1524.     
  1525.     onHideCurrentView();
  1526.     return true;
  1527.  
  1528. }
  1529.  
  1530. client.onInputClear =
  1531. function cli_iclear (e)
  1532. {
  1533.     
  1534.     onClearCurrentView();
  1535.     return true;
  1536.  
  1537. }
  1538.  
  1539. client.onInputNames =
  1540. function cli_inames (e)
  1541. {
  1542.     var chan;
  1543.     
  1544.     if (!e.network)
  1545.     {
  1546.         client.currentObject.display (getMsg("cli_inamesMsg"), "ERROR");
  1547.         return false;
  1548.     }
  1549.  
  1550.     if (e.inputData)
  1551.     {
  1552.         if (!e.network.isConnected())
  1553.         {
  1554.             client.currentObject.display (getMsg("cli_inamesMsg2",
  1555.                                                  e.network.name), "ERROR");
  1556.             return false;
  1557.         }
  1558.  
  1559.         chan = e.inputData;
  1560.     }
  1561.     else
  1562.     {
  1563.         if (client.currentObject.TYPE != "IRCChannel")
  1564.         {
  1565.             client.currentObject.display (getMsg("cli_inamesMsg3"),"ERROR");
  1566.             return false;
  1567.         }
  1568.         
  1569.         chan = e.channel.name;
  1570.     }
  1571.     
  1572.     client.currentObject.pendingNamesReply = true;
  1573.     e.server.sendData ("NAMES " + chan + "\n");
  1574.     
  1575.     return true;
  1576.     
  1577. }
  1578.  
  1579. client.onInputInfobar =
  1580. function cli_tinfo ()
  1581. {
  1582.     
  1583.     onToggleVisibility ("info");
  1584.     return true;
  1585.     
  1586. }
  1587.  
  1588. client.onInputTabstrip =
  1589. function cli_itabs ()
  1590. {
  1591.     
  1592.     onToggleVisibility ("tabstrip");
  1593.     return true;
  1594.  
  1595. }
  1596.  
  1597. client.onInputStatusbar =
  1598. function cli_isbar ()
  1599. {
  1600.     
  1601.     onToggleVisibility ("status");
  1602.     return true;
  1603.  
  1604. }
  1605.  
  1606. client.onInputHeaders =
  1607. function cli_isbar ()
  1608. {
  1609.     
  1610.     onToggleVisibility ("header");
  1611.     return true;
  1612.  
  1613. }
  1614.  
  1615. client.onInputCommands =
  1616. function cli_icommands (e)
  1617. {
  1618.  
  1619.     client.currentObject.display (getMsg("cli_icommandsMsg"), "INFO");
  1620.     
  1621.     var pattern = (e && e.inputData) ? e.inputData : "";
  1622.     var matchResult = client.commands.listNames(pattern).join(MSG_CSP);
  1623.     
  1624.     if (pattern)
  1625.         client.currentObject.display (getMsg("cli_icommandsMsg2a",
  1626.                                              [pattern, matchResult]), "INFO");
  1627.     else
  1628.         client.currentObject.display (getMsg("cli_icommandsMsg2b", matchResult),
  1629.                                       "INFO");
  1630.  
  1631.     return true;
  1632. }
  1633.  
  1634. client.onInputAttach =
  1635. function cli_iattach (e)
  1636. {
  1637.     if (!e.inputData)
  1638.     {
  1639.         return false;
  1640.     }
  1641.  
  1642.     if (e.inputData.search(/irc:\/\//i) != 0)
  1643.         e.inputData = "irc://" + e.inputData;
  1644.     
  1645.     var url = parseIRCURL(e.inputData);
  1646.     if (!url)
  1647.     {
  1648.         client.currentObject.display (getMsg("badIRCURL", e.inputData),
  1649.                                       "ERROR");
  1650.         return false;
  1651.     }
  1652.     
  1653.     gotoIRCURL (url);
  1654.     return true;
  1655. }
  1656.     
  1657. client.onInputMe =
  1658. function cli_ime (e)
  1659. {
  1660.     if (typeof client.currentObject.act != "function")
  1661.     {
  1662.         client.currentObject.display (getMsg("cli_imeMsg"), "ERROR");
  1663.         return false;
  1664.     }
  1665.  
  1666.     e.inputData = filterOutput (e.inputData, "ACTION", "ME!");
  1667.     client.currentObject.display (e.inputData, "ACTION", "ME!",
  1668.                                   client.currentObject);
  1669.     client.currentObject.act (fromUnicode(e.inputData));
  1670.     
  1671.     return true;
  1672. }
  1673.  
  1674. client.onInputQuery =
  1675. function cli_iquery (e)
  1676. {
  1677.     if (!e.server.users)
  1678.     {
  1679.         client.currentObject.display (getMsg("cli_imsgMsg"), "ERROR");
  1680.         return false;
  1681.     }
  1682.  
  1683.     var ary = e.inputData.match (/(\S+)\s*(.*)?/);
  1684.     if (ary == null)
  1685.     {
  1686.         client.currentObject.display (getMsg("cli_imsgMsg2"), "ERROR");
  1687.         return false;
  1688.     }
  1689.  
  1690.     var tab = openQueryTab (e.server, ary[1]);
  1691.     setCurrentObject (tab);
  1692.  
  1693.     if (ary[2])
  1694.     {
  1695.         var msg = filterOutput(ary[2], "PRIVMSG", "ME!");
  1696.         tab.display (msg, "PRIVMSG", "ME!", tab);
  1697.         tab.say (fromUnicode(ary[2]));
  1698.     }
  1699.     
  1700.     e.user = tab;
  1701.  
  1702.     return true;
  1703. }
  1704.  
  1705. client.onInputMsg =
  1706. function cli_imsg (e)
  1707. {
  1708.  
  1709.     if (!e.network || !e.network.isConnected())
  1710.     {
  1711.         client.currentObject.display (getMsg("cli_imsgMsg4"), "ERROR");
  1712.         return false;
  1713.     }
  1714.  
  1715.     var ary = e.inputData.match (/(\S+)\s+(.*)/);
  1716.     if (ary == null)
  1717.         return false;
  1718.  
  1719.     var usr = e.network.primServ.addUser(ary[1].toLowerCase());
  1720.  
  1721.     var msg = filterOutput(ary[2], "PRIVMSG", "ME!");
  1722.     client.currentObject.display (msg, "PRIVMSG", "ME!", usr);
  1723.     usr.say (fromUnicode(ary[2]));
  1724.  
  1725.     return true;
  1726.  
  1727. }
  1728.  
  1729. client.onInputNick =
  1730. function cli_inick (e)
  1731. {
  1732.  
  1733.     if (!e.inputData)
  1734.         return false;
  1735.     
  1736.     if (e.server) 
  1737.         e.server.sendData ("NICK " + e.inputData + "\n");
  1738.  
  1739.     CIRCNetwork.prototype.INITIAL_NICK = e.inputData;
  1740.     
  1741.     return true;
  1742.     
  1743.     
  1744. }
  1745.  
  1746. client.onInputName =
  1747. function cli_iname (e)
  1748. {
  1749.  
  1750.     if (!e.inputData)
  1751.         return false;
  1752.     
  1753.     CIRCNetwork.prototype.INITIAL_NAME = e.inputData;
  1754.  
  1755.     return true;
  1756.     
  1757. }
  1758.  
  1759. client.onInputDesc =
  1760. function cli_idesc (e)
  1761. {
  1762.  
  1763.     if (!e.inputData)
  1764.         return false;
  1765.     
  1766.     CIRCNetwork.prototype.INITIAL_DESC = e.inputData;
  1767.     
  1768.     return true;
  1769.     
  1770. }
  1771.  
  1772. client.onInputQuote =
  1773. function cli_iquote (e)
  1774. {
  1775.     if (!e.network || !e.network.isConnected())
  1776.     {
  1777.         client.currentObject.display (getMsg("cli_iquoteMsg"), "ERROR");
  1778.         return false;
  1779.     }
  1780.  
  1781.     e.server.sendData (e.inputData + "\n");
  1782.     
  1783.     return true;
  1784.     
  1785. }
  1786.  
  1787. client.onInputEval =
  1788. function cli_ieval (e)
  1789. {
  1790.     if (!e.inputData)
  1791.         return false;
  1792.     
  1793.     if (e.inputData.indexOf ("\n") != -1)
  1794.         e.inputData = "\n" + e.inputData + "\n";
  1795.     
  1796.     try
  1797.     {
  1798.         client.currentObject.doEval = function (__s) { return eval(__s); }
  1799.         client.currentObject.display (e.inputData, "EVAL-IN");
  1800.         
  1801.         var rv = String(client.currentObject.doEval (e.inputData));
  1802.         
  1803.         client.currentObject.display (rv, "EVAL-OUT");
  1804.  
  1805.     }
  1806.     catch (ex)
  1807.     {
  1808.         client.currentObject.display (String(ex), "ERROR");
  1809.     }
  1810.     
  1811.     return true;
  1812.     
  1813. }
  1814.  
  1815. client.onInputCTCP =
  1816. function cli_ictcp (e)
  1817. {
  1818.     if (!e.inputData)
  1819.         return false;
  1820.  
  1821.     if (!e.server)
  1822.     {
  1823.         client.currentObject.display (getMsg("cli_ictcpMsg"), "ERROR");
  1824.         return false;
  1825.     }
  1826.  
  1827.     var ary = e.inputData.match(/^(\S+) (\S+)\s?(.*)$/);
  1828.     if (ary == null)
  1829.         return false;
  1830.     
  1831.     e.server.ctcpTo (ary[1], ary[2], ary[3]);
  1832.     
  1833.     return true;
  1834.     
  1835. }
  1836.  
  1837.  
  1838. client.onInputJoin =
  1839. function cli_ijoin (e)
  1840. {
  1841.     if (!e.network || !e.network.isConnected())
  1842.     {
  1843.         if (!e.network)
  1844.             client.currentObject.display (getMsg("cli_ijoinMsg"), "ERROR");
  1845.         else
  1846.             client.currentObject.display (getMsg("cli_ijoinMsg2",
  1847.                                                  e.network.name1), "ERROR");
  1848.         return false;
  1849.     }
  1850.     
  1851.     var ary = e.inputData.match(/(\S+) ?(\S+)?/);
  1852.     var name;
  1853.     var key = "";
  1854.     
  1855.     if (ary)
  1856.     {
  1857.         name = ary[1];
  1858.         if (2 in ary)
  1859.             key = ary[2];
  1860.     }
  1861.     else
  1862.     {
  1863.         if (client.currentObject.TYPE == "IRCChannel")
  1864.             name = client.currentObject.name;
  1865.         else
  1866.             return false;
  1867.  
  1868.         if (client.currentObject.mode.key)
  1869.             key = client.currentObject.mode.key
  1870.     }
  1871.     
  1872.     if ((name[0] != "#") && (name[0] != "&") && (name[0] != "+") &&
  1873.         (name[0] != "!"))
  1874.         name = "#" + name;
  1875.  
  1876.     e.channel = e.server.addChannel (name);
  1877.     e.channel.join(key);
  1878.     if (!("messages" in e.channel))
  1879.         e.channel.display (getMsg("cli_ijoinMsg3",e.channel.name), "INFO");
  1880.     setCurrentObject(e.channel);
  1881.     
  1882.     return true;
  1883.     
  1884. }
  1885.  
  1886. client.onInputLeave =
  1887. function cli_ipart (e)
  1888. {
  1889.     if (!e.channel)
  1890.     {            
  1891.         client.currentObject.display (getMsg("cli_ipartMsg"), "ERROR");
  1892.         return false;
  1893.     }
  1894.  
  1895.     e.channel.part();
  1896.  
  1897.     return true;
  1898.     
  1899. }
  1900.  
  1901. client.onInputZoom =
  1902. function cli_izoom (e)
  1903. {
  1904.     client.currentObject.display (getMsg("cli_izoomMsg"), "WARNING");
  1905.  
  1906.     if (!e.inputData)
  1907.         return false;
  1908.     
  1909.     if (!e.channel)
  1910.     {
  1911.         client.currentObject.display (getMsg("cli_izoomMsg2"), "ERROR");
  1912.         return false;
  1913.     }
  1914.     
  1915.     var cuser = e.channel.getUser(e.inputData);
  1916.     
  1917.     if (!cuser)
  1918.     {
  1919.         client.currentObject.display (getMsg("cli_izoomMsg3",e.inputData),
  1920.                                       "ERROR");
  1921.         return false;
  1922.     }
  1923.     
  1924.     setCurrentObject(cuser);
  1925.  
  1926.     return true;
  1927.     
  1928. }    
  1929.  
  1930. /**
  1931.  * Performs a whois on a user.
  1932.  */
  1933. client.onInputWhoIs = 
  1934. function cli_whois (e) 
  1935. {
  1936.     if (!e.network || !e.network.isConnected())
  1937.     {
  1938.         client.currentObject.display (getMsg("cli_whoisMsg"), "ERROR");
  1939.         return false;
  1940.     }
  1941.  
  1942.     if (!e.inputData)
  1943.     {
  1944.         var nicksAry = e.channel.getSelectedUsers();
  1945.  
  1946.         if (nicksAry)
  1947.         {
  1948.             mapObjFunc(nicksAry, "whois", null);
  1949.             return true;
  1950.         }
  1951.         else
  1952.         {
  1953.             return false;
  1954.         }
  1955.     }
  1956.     // Otherwise, there is no guarantee that the username
  1957.     // is currently a user
  1958.     var nick = e.inputData.match( /\S+/ );
  1959.  
  1960.     e.server.whois (nick);
  1961.     
  1962.     return true;
  1963. }
  1964.  
  1965. client.onInputTopic =
  1966. function cli_itopic (e)
  1967. {
  1968.     if (!e.channel)
  1969.     {
  1970.         client.currentObject.display (getMsg("cli_itopicMsg"), "ERROR");
  1971.         return false;
  1972.     }
  1973.     
  1974.     if (!e.inputData)
  1975.     {
  1976.         e.server.sendData ("TOPIC " + e.channel.name + "\n");
  1977.     }
  1978.     else
  1979.     {
  1980.         if (!e.channel.setTopic(fromUnicode(e.inputData)))
  1981.             client.currentObject.display (getMsg("cli_itopicMsg2"), "ERROR");
  1982.     }
  1983.  
  1984.     return true;
  1985.     
  1986. }
  1987.  
  1988. client.onInputAbout =
  1989. function cli_iabout (e)
  1990. {
  1991.     client.currentObject.display (CIRCServer.prototype.VERSION_RPLY, "ABOUT");
  1992.     client.currentObject.display (getMsg("aboutHomepage"), "ABOUT");
  1993.     return true;
  1994. }
  1995.  
  1996. client.onInputAway =
  1997. function cli_iaway (e)
  1998.     if (!e.network || !e.network.isConnected())
  1999.     {
  2000.         client.currentObject.display (getMsg("cli_iawayMsg"), "ERROR");
  2001.         return false;
  2002.     }
  2003.     else if (!e.inputData) 
  2004.     {
  2005.         e.server.sendData ("AWAY\n");
  2006.     }
  2007.     else
  2008.     {
  2009.         e.server.sendData ("AWAY :" + e.inputData + "\n");
  2010.     }
  2011.  
  2012.     return true;
  2013. }    
  2014.  
  2015. /**
  2016.  * Removes operator status from a user.
  2017.  */
  2018. client.onInputDeop = 
  2019. function cli_ideop (e) 
  2020. {
  2021.     /* NOTE: See the next function for a well commented explanation
  2022.        of the general form of these Multiple-Target type functions */
  2023.  
  2024.     if (!e.channel)
  2025.     {
  2026.         client.currentObject.display (getMsg("cli_ideopMsg"), "ERROR");
  2027.         return false;
  2028.     }    
  2029.     
  2030.     if (!e.inputData)
  2031.     {
  2032.         var nicksAry = e.channel.getSelectedUsers();
  2033.  
  2034.  
  2035.         if (nicksAry)
  2036.         {
  2037.             mapObjFunc(nicksAry, "setOp", false);
  2038.             return true;
  2039.         }
  2040.         else
  2041.         {
  2042.             return false;
  2043.         }
  2044.     }
  2045.  
  2046.     var cuser = e.channel.getUser(e.inputData);
  2047.     
  2048.     if (!cuser)
  2049.     {
  2050.         /* use e.inputData so the case is retained */
  2051.         client.currentObject.display (getMsg("cli_ideopMsg2",e.inputData),
  2052.                                       "ERROR");
  2053.         return false;
  2054.     }
  2055.     
  2056.     cuser.setOp(false);
  2057.  
  2058.     return true;
  2059. }
  2060.  
  2061.  
  2062. /**
  2063.  * Gives operator status to a channel user.
  2064.  */
  2065. client.onInputOp = 
  2066. function cli_iop (e) 
  2067. {
  2068.     if (!e.channel)
  2069.     {
  2070.         client.currentObject.display (getMsg("cli_iopMsg"), "ERROR");
  2071.         return false;
  2072.     }
  2073.     
  2074.     
  2075.     if (!e.inputData)
  2076.     {
  2077.         /* Since no param is passed, check for selection */
  2078.         var nicksAry = e.channel.getSelectedUsers();
  2079.  
  2080.         /* If a valid array of user objects, then call the mapObjFunc */
  2081.         if (nicksAry)
  2082.         {
  2083.             /* See test3-utils.js: this simply
  2084.                applies the setOp function to every item
  2085.                in nicksAry with the parameter of "true" 
  2086.                each time 
  2087.             */
  2088.             mapObjFunc(nicksAry, "setOp", true);
  2089.             return true;
  2090.         }
  2091.         else
  2092.         {
  2093.             /* If no input and no selection, return false
  2094.                to display the usage */
  2095.             return false;
  2096.         }
  2097.     }
  2098.  
  2099.     /* We do have inputData, so use that, rather than any
  2100.        other option */
  2101.  
  2102.     var cuser = e.channel.getUser(e.inputData);
  2103.     
  2104.     if (!cuser)
  2105.     {
  2106.         client.currentObject.display (getMsg("cli_iopMsg2",e.inputData),"ERROR");
  2107.         return false;
  2108.     }
  2109.     
  2110.     cuser.setOp(true);
  2111.  
  2112.     return true;   
  2113.     
  2114. }
  2115.  
  2116. client.onInputPing = 
  2117. function cli_iping (e) 
  2118. {
  2119.     if (!e.inputData)
  2120.         return false;
  2121.     
  2122.     onSimulateCommand("/ctcp " + e.inputData + " PING");
  2123.     return true;
  2124. }
  2125.  
  2126. client.onInputVersion = 
  2127. function cli_iversion (e) 
  2128. {
  2129.     if (!e.inputData)
  2130.         return false;
  2131.     
  2132.     onSimulateCommand("/ctcp " + e.inputData + " VERSION");
  2133.     return true;
  2134. }
  2135.  
  2136. /**
  2137.  * Gives voice status to a user.
  2138.  */
  2139. client.onInputVoice = 
  2140. function cli_ivoice (e) 
  2141. {
  2142.     if (!e.channel)
  2143.     {
  2144.         client.currentObject.display (getMsg("cli_ivoiceMsg"), "ERROR");
  2145.         return false;
  2146.     }    
  2147.     
  2148.     if (!e.inputData)
  2149.     {
  2150.         var nicksAry = e.channel.getSelectedUsers();
  2151.  
  2152.         if (nicksAry)
  2153.         {
  2154.             mapObjFunc(nicksAry, "setVoice", true);
  2155.             return true;
  2156.         }
  2157.         else
  2158.         {
  2159.             return false;
  2160.         }
  2161.     }
  2162.  
  2163.     var cuser = e.channel.getUser(e.inputData);
  2164.     
  2165.     if (!cuser)
  2166.     {
  2167.         client.currentObject.display (getMsg("cli_ivoiceMsg2",e.inputData),
  2168.                                       "ERROR");
  2169.         return false;
  2170.     }
  2171.     
  2172.     cuser.setVoice(true);
  2173.  
  2174.     return true;
  2175. }
  2176.  
  2177. /**
  2178.  * Removes voice status from a user.
  2179.  */
  2180. client.onInputDevoice = 
  2181. function cli_devoice (e) 
  2182. {
  2183.     if (!e.channel)
  2184.     {
  2185.         client.currentObject.display (getMsg("cli_devoiceMsg"), "ERROR");
  2186.         return false;
  2187.     }    
  2188.     
  2189.     if (!e.inputData)
  2190.     {
  2191.         var nicksAry = e.channel.getSelectedUsers();
  2192.  
  2193.         if (nicksAry)
  2194.         {
  2195.             mapObjFunc(nicksAry, "setVoice", false);
  2196.             return true;
  2197.         }
  2198.         else
  2199.         {
  2200.             return false;
  2201.         }
  2202.     }
  2203.     
  2204.     var cuser = e.channel.getUser(e.inputData);
  2205.     
  2206.     if (!cuser)
  2207.     {
  2208.         client.currentObject.display (getMsg("cli_devoiceMsg2", e.inputData),
  2209.                                       "ERROR");
  2210.         return false;
  2211.     }
  2212.     
  2213.     cuser.setVoice(false);
  2214.  
  2215.     return true;
  2216. }
  2217.  
  2218. /**
  2219.  * Displays input to the current view, but doesn't send it to the server.
  2220.  */
  2221. client.onInputEcho =
  2222. function cli_iecho (e)
  2223. {
  2224.     if (!e.inputData)
  2225.     {
  2226.         return false;
  2227.     }
  2228.     else 
  2229.     {
  2230.         client.currentObject.display (e.inputData, "ECHO");
  2231.         
  2232.         return true;
  2233.     }
  2234. }
  2235.  
  2236. client.onInputInvite =
  2237. function cli_iinvite (e) 
  2238. {
  2239.  
  2240.     if (!e.network || !e.network.isConnected())
  2241.     {
  2242.         client.currentObject.display (getMsg("cli_iinviteMsg"), "ERROR");
  2243.         return false;
  2244.     }     
  2245.     else if (!e.channel)
  2246.     {
  2247.         client.currentObject.display (getMsg("cli_iinviteMsg2"), "ERROR");
  2248.         return false;
  2249.     }    
  2250.     
  2251.     if (!e.inputData) {
  2252.         return false;
  2253.     }
  2254.     else 
  2255.     {
  2256.         var ary = e.inputData.split( /\s+/ );
  2257.         
  2258.         if (ary.length == 1)
  2259.         {
  2260.             e.channel.invite (ary[0]);
  2261.         }
  2262.         else
  2263.         {
  2264.             var chan = e.server.channels[ary[1].toLowerCase()];
  2265.  
  2266.             if (chan == undefined) 
  2267.             {
  2268.                 client.currentObject.display (getMsg("cli_iinviteMsg3", ary[1]),
  2269.                                               "ERROR");
  2270.                 return false;
  2271.             }            
  2272.  
  2273.             chan.invite (ary[0]);
  2274.         }   
  2275.         
  2276.         return true;
  2277.     }
  2278. }
  2279.  
  2280.  
  2281. client.onInputKick =
  2282. function cli_ikick (e) 
  2283. {
  2284.     if (!e.channel)
  2285.     {
  2286.         client.currentObject.display (getMsg("cli_ikickMsg"), "ERROR");
  2287.         return false;
  2288.     }    
  2289.     
  2290.     if (!e.inputData)
  2291.     {
  2292.         var nicksAry = e.channel.getSelectedUsers();
  2293.  
  2294.         if (nicksAry)
  2295.         {
  2296.             mapObjFunc(nicksAry, "kick", "");
  2297.             return true;
  2298.         }
  2299.         else
  2300.         {
  2301.             return false;
  2302.         }
  2303.     }
  2304.  
  2305.     var ary = e.inputData.match ( /(\S+)? ?(.*)/ );
  2306.  
  2307.     var cuser = e.channel.getUser(ary[1]);
  2308.     
  2309.     if (!cuser)
  2310.     {    
  2311.         client.currentObject.display (getMsg("cli_ikickMsg2", e.inputData),
  2312.                                       "ERROR");
  2313.         return false;
  2314.     }
  2315.  
  2316.     if (ary.length > 2)
  2317.     {               
  2318.         cuser.kick(ary[2]);
  2319.     }
  2320.     else     
  2321.  
  2322.     cuser.kick();    
  2323.             
  2324.     return true;
  2325. }
  2326.  
  2327. client.onInputClient =
  2328. function cli_iclient (e)
  2329. {
  2330.     if (!client.messages)
  2331.         client.display (getMsg("cli_iclientMsg"), "INFO");
  2332.     getTabForObject (client, true);
  2333.     setCurrentObject (client);
  2334.     return true;
  2335. }
  2336.  
  2337. client.onInputNotify =
  2338. function cli_inotify (e)
  2339. {
  2340.     if (!("network" in e) || !e.network)
  2341.     {
  2342.         client.currentObject.display (getMsg("cli_inotifyMsg"), "ERROR");
  2343.         return false;
  2344.     }
  2345.  
  2346.     var net = e.network;
  2347.     
  2348.     if (!e.inputData)
  2349.     {
  2350.         if ("notifyList" in net && net.notifyList.length > 0)
  2351.         {
  2352.             /* delete the lists and force a ISON check, this will
  2353.              * print the current online/offline status when the server
  2354.              * responds */
  2355.             delete net.onList;
  2356.             delete net.offList;
  2357.             onNotifyTimeout();
  2358.         }
  2359.         else
  2360.             client.currentObject.display (getMsg("cli_inotifyMsg2"), "INFO");
  2361.     }
  2362.     else
  2363.     {
  2364.         var adds = new Array();
  2365.         var subs = new Array();
  2366.         
  2367.         if (!("notifyList" in net))
  2368.             net.notifyList = new Array();
  2369.         var ary = e.inputData.toLowerCase().split(/\s+/);
  2370.  
  2371.         for (var i in ary)
  2372.         {
  2373.             var idx = arrayIndexOf (net.notifyList, ary[i]);
  2374.             if (idx == -1)
  2375.             {
  2376.                 net.notifyList.push (ary[i]);
  2377.                 adds.push(ary[i]);
  2378.             }
  2379.             else
  2380.             {
  2381.                 arrayRemoveAt (net.notifyList, idx);
  2382.                 subs.push(ary[i]);
  2383.             }
  2384.         }
  2385.  
  2386.         var msgname;
  2387.         
  2388.         if (adds.length > 0)
  2389.         {
  2390.             msgname = (adds.length == 1) ? "cli_inotifyMsg3a" : 
  2391.                                            "cli_inotifyMsg3b";
  2392.             client.currentObject.display (getMsg(msgname, arraySpeak(adds)));
  2393.         }
  2394.         
  2395.         if (subs.length > 0)
  2396.         {
  2397.             msgname = (subs.length == 1) ? "cli_inotifyMsg4a" : 
  2398.                                            "cli_inotifyMsg4b";
  2399.             client.currentObject.display (getMsg(msgname, arraySpeak(subs)));
  2400.         }
  2401.             
  2402.         delete net.onList;
  2403.         delete net.offList;
  2404.         onNotifyTimeout();
  2405.     }
  2406.  
  2407.     return true;
  2408.     
  2409. }
  2410.  
  2411.                 
  2412. client.onInputStalk =
  2413. function cli_istalk (e)
  2414. {
  2415.     if (!e.inputData)
  2416.     {
  2417.         if (client.stalkingVictims.length == 0)
  2418.         {
  2419.             client.currentObject.display(getMsg("cli_istalkMsg"), "STALK");
  2420.         }
  2421.         else
  2422.         {
  2423.             client.currentObject.display
  2424.                 (getMsg("cli_istalkMsg2", client.stalkingVictims.join(MSG_CSP)),
  2425.                  "STALK");
  2426.         }
  2427.         return true;
  2428.     }
  2429.  
  2430.     client.stalkingVictims[client.stalkingVictims.length] = e.inputData;
  2431.     client.currentObject.display(getMsg("cli_istalkMsg3",e.inputData), "STALK");
  2432.     return true;
  2433. }
  2434.  
  2435. client.onInputUnstalk =
  2436. function cli_iunstalk ( e )
  2437. {
  2438.     if (!e.inputData)
  2439.         return false;
  2440.  
  2441.     for (i in client.stalkingVictims)
  2442.     {
  2443.         if (client.stalkingVictims[i].match("^" + e.inputData +"$", "i"))
  2444.         {
  2445.             client.stalkingVictims.splice(i, 1);
  2446.             client.currentObject.display(getMsg("cli_iunstalkMsg", e.inputData),
  2447.                                          "UNSTALK");
  2448.             return true;
  2449.         }
  2450.     }
  2451.  
  2452.     client.currentObject.display(getMsg("cli_iunstalkMsg2", e.inputData),
  2453.                                  "UNSTALK");
  2454.     return true;
  2455. }
  2456.  
  2457. /* 'private' function, should only be used from inside */
  2458. CIRCChannel.prototype._addUserToGraph =
  2459. function my_addtograph (user)
  2460. {
  2461.     if (!user.TYPE)
  2462.         dd (getStackTrace());
  2463.     
  2464.     client.rdf.Assert (this.getGraphResource(), client.rdf.resChanUser,
  2465.                        user.getGraphResource(), true);
  2466.     
  2467. }
  2468.  
  2469. /* 'private' function, should only be used from inside */
  2470. CIRCChannel.prototype._removeUserFromGraph =
  2471. function my_remfgraph (user)
  2472. {
  2473.  
  2474.     client.rdf.Unassert (this.getGraphResource(), client.rdf.resChanUser,
  2475.                          user.getGraphResource());
  2476.     
  2477. }
  2478.  
  2479. CIRCNetwork.prototype.onInfo =
  2480. function my_netinfo (e)
  2481. {
  2482.     this.display (e.msg, "INFO");
  2483. }
  2484.  
  2485. CIRCNetwork.prototype.onUnknown =
  2486. function my_unknown (e)
  2487. {
  2488.     e.params.shift(); /* remove the code */
  2489.     e.params.shift(); /* and the dest. nick (always me) */
  2490.         /* if it looks like some kind of "end of foo" code, and we don't
  2491.          * already have a mapping for it, make one up */
  2492.     if (!(e.code in client.responseCodeMap) && e.meat.search (/^end of/i) != -1)
  2493.         client.responseCodeMap[e.code] = "---";
  2494.     
  2495.     this.display (e.params.join(" ") + ": " + e.meat,
  2496.                   e.code.toUpperCase());
  2497. }
  2498.  
  2499. CIRCNetwork.prototype.on001 = /* Welcome! */
  2500. CIRCNetwork.prototype.on002 = /* your host is */
  2501. CIRCNetwork.prototype.on003 = /* server born-on date */
  2502. CIRCNetwork.prototype.on004 = /* server id */
  2503. CIRCNetwork.prototype.on005 = /* server features */
  2504. CIRCNetwork.prototype.on250 = /* highest connection count */
  2505. CIRCNetwork.prototype.on251 = /* users */
  2506. CIRCNetwork.prototype.on252 = /* opers online (in params[2]) */
  2507. CIRCNetwork.prototype.on254 = /* channels found (in params[2]) */
  2508. CIRCNetwork.prototype.on255 = /* link info */
  2509. CIRCNetwork.prototype.on265 = /* local user details */
  2510. CIRCNetwork.prototype.on266 = /* global user details */
  2511. CIRCNetwork.prototype.on375 = /* start of MOTD */
  2512. CIRCNetwork.prototype.on372 = /* MOTD line */
  2513. CIRCNetwork.prototype.on376 = /* end of MOTD */
  2514. function my_showtonet (e)
  2515. {
  2516.     var p = (2 in e.params) ? e.params[2] + " " : "";
  2517.     var str = "";
  2518.  
  2519.     switch (e.code)
  2520.     {
  2521.         case "004":
  2522.         case "005":
  2523.             str = e.params.slice(3).join (" ");
  2524.             break;
  2525.  
  2526.         case "001":
  2527.             updateTitle(this);
  2528.             updateNetwork (this);
  2529.             if (client.currentObject == this)
  2530.             {
  2531.                 var status = document.getElementById("offline-status");
  2532.                 status.removeAttribute ("offline");
  2533.             }
  2534.             if ("pendingURLs" in this)
  2535.             {
  2536.                 var url = this.pendingURLs.pop();
  2537.                 while (url)
  2538.                 {
  2539.                     gotoIRCURL(url);
  2540.                     url = this.pendingURLs.pop();
  2541.                 }
  2542.                 delete this.pendingURLs;
  2543.             }
  2544.             str = e.meat;
  2545.             break;
  2546.             
  2547.         case "372":
  2548.         case "375":
  2549.         case "376":
  2550.             if (this.IGNORE_MOTD)
  2551.                 return;
  2552.             /* no break */
  2553.  
  2554.         default:
  2555.             str = e.meat;
  2556.             break;
  2557.     }
  2558.  
  2559.     this.displayHere (p + str, e.code.toUpperCase());
  2560.     
  2561. }
  2562.  
  2563. CIRCNetwork.prototype.onUnknownCTCPReply = 
  2564. function my_ctcprunk (e)
  2565. {
  2566.     this.display (getMsg("my_ctcprunk",
  2567.                          [e.CTCPCode, e.CTCPData, e.user.properNick]),
  2568.                          "CTCP_REPLY", e.user, e.server.me);
  2569. }
  2570.  
  2571. CIRCNetwork.prototype.onNotice = 
  2572. function my_notice (e)
  2573. {
  2574.     this.display (e.meat, "NOTICE", this, e.server.me);
  2575. }
  2576.  
  2577. CIRCNetwork.prototype.on303 = /* ISON (aka notify) reply */
  2578. function my_303 (e)
  2579. {
  2580.     var onList = stringTrim(e.meat.toLowerCase()).split(/\s+/);
  2581.     var offList = new Array();
  2582.     var newArrivals = new Array();
  2583.     var newDepartures = new Array();
  2584.     var o = getObjectDetails(client.currentObject);
  2585.     var displayTab;
  2586.     var i;
  2587.  
  2588.     if ("network" in o && o.network == this && client.currentObject != this)
  2589.         displayTab = client.currentObject;
  2590.  
  2591.     for (i in this.notifyList)
  2592.         if (!arrayContains(onList, this.notifyList[i]))
  2593.             /* user is not on */
  2594.             offList.push (this.notifyList[i]);
  2595.         
  2596.     if ("onList" in this)
  2597.     {
  2598.         for (i in onList)
  2599.             if (!arrayContains(this.onList, onList[i]))
  2600.                 /* we didn't know this person was on */
  2601.                 newArrivals.push(onList[i]);
  2602.     }
  2603.     else
  2604.         this.onList = newArrivals = onList;
  2605.  
  2606.     if ("offList" in this)
  2607.     {
  2608.         for (i in offList)
  2609.             if (!arrayContains(this.offList, offList[i]))
  2610.                 /* we didn't know this person was off */
  2611.                 newDepartures.push(offList[i]);
  2612.     }
  2613.     else
  2614.         this.offList = newDepartures = offList;
  2615.     
  2616.     if (newArrivals.length > 0)
  2617.     {
  2618.         this.displayHere (arraySpeak (newArrivals, "is", "are") +
  2619.                           " online.", "NOTIFY-ON");
  2620.         if (displayTab)
  2621.             displayTab.displayHere (arraySpeak (newArrivals, "is", "are") +
  2622.                                     " online.", "NOTIFY-ON");
  2623.     }
  2624.     
  2625.     if (newDepartures.length > 0)
  2626.     {
  2627.         this.displayHere (arraySpeak (newDepartures, "is", "are") +
  2628.                           " offline.", "NOTIFY-OFF");
  2629.         if (displayTab)
  2630.             displayTab.displayHere (arraySpeak (newDepartures, "is", "are") +
  2631.                                     " offline.", "NOTIFY-OFF");
  2632.     }
  2633.  
  2634.     this.onList = onList;
  2635.     this.offList = offList;
  2636.     
  2637. }
  2638.  
  2639. CIRCNetwork.prototype.on321 = /* LIST reply header */
  2640. function my_321 (e)
  2641. {
  2642.     this.displayHere (e.params[2] + " " + e.meat, "321");
  2643.     if (client.currentObject != this)
  2644.     client.currentObject.display (getMsg("my_321", this.name), "INFO");
  2645. }
  2646.  
  2647. CIRCNetwork.prototype.on323 = /* end of LIST reply */
  2648. function my_323 (e)
  2649. {
  2650.     this.displayHere (e.params.join(" ") + ": " + e.meat, "323");
  2651. }
  2652.  
  2653. CIRCNetwork.prototype.on322 = /* LIST reply */
  2654. function my_listrply (e)
  2655. {
  2656.     this.displayHere (getMsg("my_322", [e.params[2], e.params[3], e.meat]),
  2657.                       "322");
  2658. }
  2659.  
  2660. /* end of WHO */
  2661. CIRCNetwork.prototype.on315 =
  2662. function my_315 (e)
  2663. {
  2664.     var matches;
  2665.     if ("whoMatches" in this)
  2666.         matches = this.whoMatches;
  2667.     else
  2668.         matches = 0;
  2669.     e.user.display (getMsg("my_315", [e.params[2], matches]), e.code);
  2670.     delete this.whoMatches;
  2671. }
  2672.  
  2673. CIRCNetwork.prototype.on352 =
  2674. function my_352 (e)
  2675. {
  2676.     //0-352 1-rginda_ 2-#chatzilla 3-chatzilla 4-h-64-236-139-254.aoltw.net 5-irc.mozilla.org 6-rginda 7-H
  2677.     var desc;
  2678.     var hops = "?";
  2679.     var ary = e.meat.match(/(\d+)\s(.*)/);
  2680.     if (ary)
  2681.     {
  2682.         hops = Number(ary[1]);
  2683.         desc = ary[2];
  2684.     }
  2685.     else
  2686.     {
  2687.         desc = e.meat;
  2688.     }
  2689.     
  2690.     var status = e.params[7];
  2691.     if (e.params[7] == "G")
  2692.         status = getMsg("my_352.g");
  2693.     else if (e.params[7] == "H")
  2694.         status = getMsg("my_352.h");
  2695.         
  2696.     e.user.display (getMsg("my_352", [e.params[6], e.params[3], e.params[4],
  2697.                                       desc, status, e.params[2], e.params[5],
  2698.                                       hops]), e.code, e.user);
  2699.     updateTitle (e.user);
  2700.     if ("whoMatches" in this)
  2701.         ++this.whoMatches;
  2702.     else
  2703.         this.whoMatches = 1;
  2704. }
  2705.  
  2706. CIRCNetwork.prototype.on311 = /* whois name */
  2707. CIRCNetwork.prototype.on319 = /* whois channels */
  2708. CIRCNetwork.prototype.on312 = /* whois server */
  2709. CIRCNetwork.prototype.on317 = /* whois idle time */
  2710. CIRCNetwork.prototype.on318 = /* whois end of whois*/
  2711. function my_whoisreply (e)
  2712. {
  2713.     var text = "egads!";
  2714.     var nick = e.params[2];
  2715.     
  2716.     switch (Number(e.code))
  2717.     {
  2718.         case 311:
  2719.             text = getMsg("my_whoisreplyMsg",
  2720.                           [nick, e.params[3], e.params[4], e.meat]);
  2721.             break;
  2722.             
  2723.         case 319:
  2724.             var ary = stringTrim(e.meat).split(" ");
  2725.             text = getMsg("my_whoisreplyMsg2",[nick, arraySpeak(ary)]);
  2726.             break;
  2727.             
  2728.         case 312:
  2729.             text = getMsg("my_whoisreplyMsg3",
  2730.                           [nick, e.params[3], e.meat]);
  2731.             break;
  2732.             
  2733.         case 317:
  2734.             text = getMsg("my_whoisreplyMsg4",
  2735.                           [nick, formatDateOffset(Number(e.params[3])),
  2736.                           new Date(Number(e.params[4]) * 1000)]);
  2737.             break;
  2738.             
  2739.         case 318:
  2740.             text = getMsg("my_whoisreplyMsg5", nick);
  2741.             break;
  2742.             
  2743.     }
  2744.  
  2745.     if (nick in e.server.users && "messages" in e.server.users[nick])
  2746.     {
  2747.         var user = e.server.users[nick];
  2748.         updateTitle(user);
  2749.         user.display (text, e.code);
  2750.     }
  2751.     else
  2752.     {
  2753.         e.server.parent.display(text, e.code);
  2754.     }
  2755. }
  2756.  
  2757. CIRCNetwork.prototype.on341 = /* invite reply */
  2758. function my_341 (e)
  2759. {
  2760.     this.display (getMsg("my_341", [e.params[2], e.params[3]]), "341");
  2761. }
  2762.  
  2763. CIRCNetwork.prototype.onInvite = /* invite message */
  2764. function my_invite (e)
  2765. {
  2766.     this.display (getMsg("my_Invite", [e.user.properNick, e.user.name,
  2767.                                        e.user.host, e.meat]), "INVITE");
  2768. }
  2769.  
  2770. CIRCNetwork.prototype.on433 = /* nickname in use */
  2771. function my_433 (e)
  2772. {
  2773.     if (e.params[2] == CIRCNetwork.prototype.INITIAL_NICK && this.connecting)
  2774.     {
  2775.         var newnick = CIRCNetwork.prototype.INITIAL_NICK + "_";
  2776.         CIRCNetwork.prototype.INITIAL_NICK = newnick;
  2777.         e.server.parent.display (getMsg("my_433Retry", [e.params[2], newnick]),
  2778.                                  "433");
  2779.         this.primServ.sendData("NICK " + newnick + "\n");
  2780.     }
  2781.     else
  2782.     {
  2783.         this.display (getMsg("my_433Msg", e.params[2]), "433");
  2784.     }
  2785. }
  2786.  
  2787. CIRCNetwork.prototype.onStartConnect =
  2788. function my_sconnect (e)
  2789. {
  2790.     this.display (getMsg("my_sconnect", [this.name, e.host, e.port,
  2791.                                          e.connectAttempt,
  2792.                                          this.MAX_CONNECT_ATTEMPTS]), "INFO");
  2793. }
  2794.     
  2795. CIRCNetwork.prototype.onError =
  2796. function my_neterror (e)
  2797. {
  2798.     var msg;
  2799.     
  2800.     if (typeof e.errorCode != "undefined")
  2801.     {
  2802.         switch (e.errorCode)
  2803.         {
  2804.             case JSIRC_ERR_NO_SOCKET:
  2805.                 msg = getMsg ("my_neterrorNoSocket");
  2806.                 break;
  2807.                 
  2808.             case JSIRC_ERR_EXHAUSTED:
  2809.                 msg = getMsg ("my_neterrorExhausted");
  2810.                 break;
  2811.         }
  2812.     }
  2813.     else
  2814.         msg = e.meat;
  2815.     
  2816.     this.display (msg, "ERROR");   
  2817. }
  2818.  
  2819.  
  2820. CIRCNetwork.prototype.onDisconnect =
  2821. function my_netdisconnect (e)
  2822. {
  2823.     var connection = e.server.connection;
  2824.     var msg;
  2825.     
  2826.     if (typeof e.disconnectStatus != "undefined")
  2827.     {
  2828.         switch (e.disconnectStatus)
  2829.         {
  2830.             case 0:
  2831.                 msg = getMsg("my_netdisconnectConnectionClosed", [this.name,
  2832.                              connection.host, connection.port]);
  2833.                 break;
  2834.  
  2835.             case NS_ERROR_CONNECTION_REFUSED:
  2836.                 msg = getMsg("my_netdisconnectConnectionRefused", [this.name,
  2837.                              connection.host, connection.port]);
  2838.                 break;
  2839.  
  2840.             case NS_ERROR_NET_TIMEOUT:
  2841.                 msg = getMsg("my_netdisconnectConnectionTimeout", [this.name,
  2842.                              connection.host, connection.port]);
  2843.                 break;
  2844.  
  2845.             case NS_ERROR_UNKNOWN_HOST:
  2846.                 msg = getMsg("my_netdisconnectUnknownHost",
  2847.                              connection.host);
  2848.                 break;
  2849.             
  2850.             default:
  2851.                 msg = getMsg("my_netdisconnectConnectionClosedStatus",
  2852.                              [this.name, connection.host, connection.port]);
  2853.                 break;
  2854.         }    
  2855.     }
  2856.     else
  2857.     {
  2858.         msg = getMsg("my_neterrorConnectionClosed", [this.name,
  2859.                      connection.host, connection.port]);
  2860.     }
  2861.     
  2862.     for (var v in client.viewsArray)
  2863.     {
  2864.         var obj = client.viewsArray[v].source;
  2865.         if (obj != client)
  2866.         {        
  2867.             var details = getObjectDetails(obj);
  2868.             if ("server" in details && details.server == e.server)
  2869.                 obj.displayHere (msg, "ERROR");
  2870.         }
  2871.     }
  2872.  
  2873.     for (var c in this.primServ.channels)
  2874.     {
  2875.         var channel = this.primServ.channels[c];
  2876.         client.rdf.clearTargets(channel.getGraphResource(),
  2877.                                 client.rdf.resChanUser);
  2878.     }
  2879.     
  2880.     this.connecting = false;
  2881.     updateTitle();
  2882.     if ("userClose" in client && client.userClose &&
  2883.         client.getConnectionCount() == 0)
  2884.         window.close();
  2885. }
  2886.  
  2887. CIRCNetwork.prototype.onCTCPReplyPing =
  2888. function my_replyping (e)
  2889. {
  2890.     var delay = formatDateOffset ((new Date() - new Date(Number(e.CTCPData))) /
  2891.                                   1000);
  2892.     display (getMsg("my_replyping", [e.user.properNick, delay]), "INFO",
  2893.              e.user, "ME!");
  2894. }
  2895.  
  2896. CIRCNetwork.prototype.onNick =
  2897. function my_cnick (e)
  2898. {
  2899.  
  2900.     if (userIsMe (e.user))
  2901.     {
  2902.         if (client.currentObject == this)
  2903.             this.displayHere (getMsg("my_cnickMsg", e.user.properNick),
  2904.                               "NICK", "ME!", e.user, this);
  2905.         updateNetwork();
  2906.     }
  2907.     else
  2908.         this.display (getMsg("my_cnickMsg2", [e.oldNick, e.user.properNick]),
  2909.                       "NICK", e.user, this);
  2910.  
  2911. }
  2912.  
  2913. CIRCNetwork.prototype.onPing =
  2914. function my_netping (e)
  2915. {
  2916.  
  2917.     updateNetwork (this);
  2918.     
  2919. }
  2920.  
  2921. CIRCNetwork.prototype.onPong =
  2922. function my_netpong (e)
  2923. {
  2924.  
  2925.     updateNetwork (this);
  2926.     
  2927. }
  2928.  
  2929. CIRCChannel.prototype.onPrivmsg =
  2930. function my_cprivmsg (e)
  2931. {
  2932.     
  2933.     this.display (e.meat, "PRIVMSG", e.user, this);
  2934.     
  2935.     if ((typeof client.prefix == "string") &&
  2936.         e.meat.indexOf (client.prefix) == 0)
  2937.     {
  2938.         try
  2939.         {
  2940.             var v = eval(e.meat.substring (client.prefix.length,
  2941.                                            e.meat.length));
  2942.         }
  2943.         catch (ex)
  2944.         {
  2945.             this.say (fromUnicode(e.user.nick + ": " + String(ex)));
  2946.             return false;
  2947.         }
  2948.         
  2949.         if (typeof (v) != "undefined")
  2950.         {                        
  2951.             if (v != null)                
  2952.                 v = String(v);
  2953.             else
  2954.                 v = "null";
  2955.             
  2956.             var rsp = getMsg("my_cprivmsgMsg", e.user.nick);
  2957.             
  2958.             if (v.indexOf ("\n") != -1)
  2959.                 rsp += "\n";
  2960.             else
  2961.                 rsp += " ";
  2962.             
  2963.             this.display (rsp + v, "PRIVMSG", e.server.me, this);
  2964.             this.say (fromUnicode(rsp + v));
  2965.         }
  2966.     }
  2967.  
  2968.     return true;
  2969.     
  2970. }
  2971.  
  2972. /* end of names */
  2973. CIRCChannel.prototype.on366 =
  2974. function my_366 (e)
  2975. {
  2976.     if (client.currentObject == this)    
  2977.         /* hide the tree while we add (possibly tons) of nodes */
  2978.         client.rdf.setTreeRoot("user-list", client.rdf.resNullChan);
  2979.     
  2980.     client.rdf.clearTargets(this.getGraphResource(), client.rdf.resChanUser);
  2981.  
  2982.     for (var u in this.users)
  2983.     {
  2984.         this.users[u].updateGraphResource();
  2985.         this._addUserToGraph (this.users[u]);
  2986.     }
  2987.     
  2988.     if (client.currentObject == this)
  2989.         /* redisplay the tree */
  2990.         client.rdf.setTreeRoot("user-list", this.getGraphResource());
  2991.     
  2992.     if ("pendingNamesReply" in e.channel)
  2993.     {       
  2994.         display (e.meat, "366");
  2995.         e.channel.pendingNamesReply = false;
  2996.     }
  2997. }    
  2998.  
  2999. CIRCChannel.prototype.onTopic = /* user changed topic */
  3000. CIRCChannel.prototype.on332 = /* TOPIC reply */
  3001. function my_topic (e)
  3002. {
  3003.  
  3004.     if (e.code == "TOPIC")
  3005.         this.display (getMsg("my_topicMsg", [this.topicBy, this.topic]),
  3006.                       "TOPIC");
  3007.     
  3008.     if (e.code == "332")
  3009.     {
  3010.         if (this.topic)
  3011.             this.display (getMsg("my_topicMsg2", [this.name, this.topic]),
  3012.                           "TOPIC");
  3013.         else
  3014.             this.display (getMsg("my_topicMsg3", this.name), "TOPIC");
  3015.     }
  3016.     
  3017.     updateChannel (this);
  3018.     updateTitle (this);
  3019.     
  3020. }
  3021.  
  3022. CIRCChannel.prototype.on333 = /* Topic setter information */
  3023. function my_topicinfo (e)
  3024. {
  3025.     
  3026.     this.display (getMsg("my_topicinfoMsg", [this.name, this.topicBy, 
  3027.                                              this.topicDate]), "TOPIC");
  3028.     
  3029. }
  3030.  
  3031. CIRCChannel.prototype.on353 = /* names reply */
  3032. function my_topic (e)
  3033. {
  3034.     if ("pendingNamesReply" in e.channel)
  3035.         e.channel.display (e.meat, "NAMES");
  3036. }
  3037.  
  3038.  
  3039. CIRCChannel.prototype.onNotice =
  3040. function my_notice (e)
  3041. {
  3042.     this.display (e.meat, "NOTICE", e.user, this);   
  3043. }
  3044.  
  3045. CIRCChannel.prototype.onCTCPAction =
  3046. function my_caction (e)
  3047. {
  3048.  
  3049.     this.display (e.CTCPData, "ACTION", e.user, this);
  3050.  
  3051. }
  3052.  
  3053. CIRCChannel.prototype.onUnknownCTCP =
  3054. function my_unkctcp (e)
  3055. {
  3056.  
  3057.     this.display (getMsg("my_unkctcpMsg", [e.CTCPCode, e.CTCPData,
  3058.                                            e.user.properNick]),
  3059.                   "BAD-CTCP", e.user, this);
  3060.     
  3061. }   
  3062.  
  3063. CIRCChannel.prototype.onJoin =
  3064. function my_cjoin (e)
  3065. {
  3066.  
  3067.     if (userIsMe (e.user))
  3068.     {
  3069.         this.display (getMsg("my_cjoinMsg", e.channel.name), "JOIN",
  3070.                       e.server.me, this);
  3071.         setCurrentObject(this);
  3072.     }
  3073.     else
  3074.         this.display(getMsg("my_cjoinmsg2", [e.user.properNick, e.user.name,
  3075.                                              e.user.host, e.channel.name]),
  3076.                      "JOIN", e.user, this);
  3077.  
  3078.     this._addUserToGraph (e.user);
  3079.     
  3080.     updateChannel (e.channel);
  3081.     
  3082. }
  3083.  
  3084. CIRCChannel.prototype.onPart =
  3085. function my_cpart (e)
  3086. {
  3087.  
  3088.     this._removeUserFromGraph(e.user);
  3089.  
  3090.     if (userIsMe (e.user))
  3091.     {
  3092.         this.display (getMsg("my_cpartMsg", e.channel.name), "PART", e.user,
  3093.                       this);
  3094.         if (client.currentObject == this)    
  3095.             /* hide the tree while we remove (possibly tons) of nodes */
  3096.             client.rdf.setTreeRoot("user-list", client.rdf.resNullChan);
  3097.         
  3098.         client.rdf.clearTargets(this.getGraphResource(),
  3099.                                 client.rdf.resChanUser, true);
  3100.  
  3101.         if (client.currentObject == this)
  3102.             /* redisplay the tree */
  3103.             client.rdf.setTreeRoot("user-list", this.getGraphResource());
  3104.  
  3105.         if (client.DELETE_ON_PART)
  3106.             onDeleteView(this);
  3107.     }
  3108.     else
  3109.         this.display (getMsg("my_cpartMsg2",
  3110.                              [e.user.properNick, e.channel.name]), 
  3111.                       "PART", e.user, this);
  3112.  
  3113.     updateChannel (e.channel);
  3114.     
  3115. }
  3116.  
  3117. CIRCChannel.prototype.onKick =
  3118. function my_ckick (e)
  3119. {
  3120.  
  3121.     if (userIsMe (e.lamer))
  3122.         this.display (getMsg("my_ckickMsg",
  3123.                              [e.channel.name, e.user.properNick, e.reason]),
  3124.                       "KICK", e.user, this);
  3125.     else
  3126.     {
  3127.         var enforcerProper, enforcerNick;
  3128.         if (userIsMe (e.user))
  3129.         {
  3130.             enforcerProper = "YOU";
  3131.             enforcerNick = "ME!";
  3132.         }
  3133.         else
  3134.         {
  3135.             enforcerProper = e.user.properNick;
  3136.             enforcerNick = e.user.nick;
  3137.         }
  3138.         
  3139.         this.display (getMsg("my_ckickMsg2",
  3140.                              [e.lamer.properNick, e.channel.name, enforcerProper,
  3141.                              e.reason]), "KICK", e.user, this);
  3142.     }
  3143.     
  3144.     this._removeUserFromGraph(e.lamer);
  3145.  
  3146.     updateChannel (e.channel);
  3147.     
  3148. }
  3149.  
  3150. CIRCChannel.prototype.onChanMode =
  3151. function my_cmode (e)
  3152. {
  3153.  
  3154.     if ("user" in e)
  3155.         this.display (getMsg("my_cmodeMsg", [e.params.slice(1).join(" "),
  3156.                                              e.user.properNick]), "MODE",
  3157.                       e.user, this);
  3158.  
  3159.     for (var u in e.usersAffected)
  3160.         e.usersAffected[u].updateGraphResource();
  3161.  
  3162.     updateChannel (e.channel);
  3163.     updateTitle (e.channel);
  3164.     
  3165. }
  3166.  
  3167.     
  3168.  
  3169. CIRCChannel.prototype.onNick =
  3170. function my_cnick (e)
  3171. {
  3172.  
  3173.     if (userIsMe (e.user))
  3174.     {
  3175.         this.display (getMsg("my_cnickMsg", e.user.properNick), "NICK",
  3176.                       "ME!", e.user, this);
  3177.         updateNetwork();
  3178.     }
  3179.     else
  3180.         this.display (getMsg("my_cnickMsg2", e.oldNick, e.user.properNick),
  3181.                       "NICK", e.user, this);
  3182.  
  3183.     /*
  3184.       dd ("updating resource " + e.user.getGraphResource().Value +
  3185.         " to new nickname " + e.user.properNick);
  3186.     */
  3187.  
  3188.     e.user.updateGraphResource();
  3189.     
  3190. }
  3191.  
  3192. CIRCChannel.prototype.onQuit =
  3193. function my_cquit (e)
  3194. {
  3195.  
  3196.     if (userIsMe(e.user)) /* I dont think this can happen */
  3197.         this.display (getMsg("my_cquitMsg", [e.server.parent.name, e.reason]),
  3198.                       "QUIT", e.user, this);
  3199.     else
  3200.         this.display (getMsg("my_cquitMsg2", [e.user.properNick,
  3201.                                               e.server.parent.name, e.reason]),
  3202.                       "QUIT", e.user, this);
  3203.  
  3204.     this._removeUserFromGraph(e.user);
  3205.  
  3206.     updateChannel (e.channel);
  3207.     
  3208. }
  3209.  
  3210. CIRCUser.prototype.onPrivmsg =
  3211. function my_cprivmsg (e)
  3212. {
  3213.     if ("messages" in this)
  3214.     {
  3215.         playSounds(client.QUERY_BEEP);
  3216.     }
  3217.     else
  3218.     {        
  3219.         playSounds(client.MSG_BEEP);
  3220.         if (client.NEW_TAB_THRESHOLD == 0 ||
  3221.             client.viewsArray.length < client.NEW_TAB_THRESHOLD)
  3222.         {
  3223.             var tab = openQueryTab (e.server, e.user.nick);
  3224.             if (client.FOCUS_NEW_TAB)
  3225.                 setCurrentObject(tab);
  3226.         }    
  3227.     }
  3228.     this.display (e.meat, "PRIVMSG", e.user, e.server.me);
  3229. }
  3230.  
  3231. CIRCUser.prototype.onNick =
  3232. function my_unick (e)
  3233. {
  3234.  
  3235.     if (userIsMe(e.user))
  3236.     {
  3237.         updateNetwork();
  3238.         updateTitle (e.channel);
  3239.     }
  3240.     
  3241. }
  3242.  
  3243. CIRCUser.prototype.onNotice =
  3244. function my_notice (e)
  3245. {
  3246.     this.display (e.meat, "NOTICE", this, e.server.me);   
  3247. }
  3248.  
  3249. CIRCUser.prototype.onCTCPAction =
  3250. function my_uaction (e)
  3251. {
  3252.  
  3253.     e.user.display (e.CTCPData, "ACTION", this, e.server.me);
  3254.  
  3255. }
  3256.  
  3257. CIRCUser.prototype.onUnknownCTCP =
  3258. function my_unkctcp (e)
  3259. {
  3260.  
  3261.     this.parent.parent.display (getMsg("my_unkctcpMsg",
  3262.                                        [e.CTCPCode, e.CTCPData,
  3263.                                        e.user.properNick]),
  3264.                                 "BAD-CTCP", this, e.server.me);
  3265.  
  3266. }
  3267.