landing patches for the following bugs, as 0.8.34:

193246	/list doesn't work on RFC2812 compliant IRC servers
114744 	File->Close vs. View-Close
80125 	Logging facility in Chatzilla.
198538 	Chat views tab titles are lowcase
200188 	PgDn/PgUp scroll left and right Chatzilla panes
199201 	sound settings blocks stalked messages if WAV sound file ...
114104 	messaging from private chat tab does not show the addressee
201324 	Userlist not always kept sorted as requested
202644 	Column sort behavior should parallel mailnews
184228 	Spelling error in irc.js: "function net_conenct()".
206915 	/join reports joining new channel in current window
209524 	stalk word list cannot have length one
198823 	Should be able to set Default Character Coding in Prefere...
200097 	lowcase ``<nickname> has changed the topic to...''
205792 	important text notification does not properly differentia...
86526 	chatzilla stores default prefs in prefs.js

Thanks to ssieb, kazhik ans Silver for the patches.
This commit is contained in:
rginda%netscape.com 2003-06-22 00:17:55 +00:00
parent 6909e303db
commit 95381c7eb2
16 changed files with 533 additions and 139 deletions

View File

@ -8,6 +8,7 @@ chatzilla.jar:
content/chatzilla/lib/js/command-manager.js (js/lib/command-manager.js)
content/chatzilla/lib/js/irc.js (js/lib/irc.js)
content/chatzilla/lib/js/irc-debug.js (js/lib/irc-debug.js)
content/chatzilla/lib/js/file-utils.js (js/lib/file-utils.js)
content/chatzilla/lib/xul/munger.js (xul/lib/munger.js)
content/chatzilla/chatzilla.xul (xul/content/chatzilla.xul)
content/chatzilla/scripts.xul (xul/content/scripts.xul)

View File

@ -90,6 +90,8 @@ function CIRCNetwork (name, serverList, eventPump)
this.serverList = serverList;
this.eventPump = eventPump;
this.servers = new Object();
if ("onInit" in this)
this.onInit();
}
@ -120,7 +122,7 @@ function net_geturl ()
}
CIRCNetwork.prototype.connect =
function net_conenct()
function net_connect()
{
if ("primServ" in this && this.primServ.connection.isConnected)
return;
@ -234,7 +236,7 @@ function net_doconnect(e)
* What to do when the client connects to it's primary server
*/
CIRCNetwork.prototype.onConnect =
function net_connect (e)
function net_onconnect (e)
{
this.primServ = e.server;
this.primServ.login (this.INITIAL_NICK, this.INITIAL_NAME,
@ -285,6 +287,8 @@ function CIRCServer (parent, connection, password)
"onPoll"));
parent.servers[serverName] = s;
if ("onInit" in s)
s.onInit();
return s;
}
@ -801,7 +805,7 @@ function serv_topic (e)
{
e.channel = new CIRCChannel (this, e.params[1]);
e.channel.topicBy = e.user.nick;
e.channel.topicBy = e.user.properNick;
e.channel.topicDate = new Date();
e.channel.topic = toUnicode(e.params[2], e.channel.charset);
e.destObject = e.channel;
@ -1697,6 +1701,8 @@ function CIRCChannel (parent, name, charset)
this.usersStable = true;
parent.channels[name] = this;
if ("onInit" in this)
this.onInit();
return this;
@ -2063,6 +2069,8 @@ function CIRCUser (parent, nick, name, host)
this.name = name;
this.host = host;
parent.users[nick] = this;
if ("onInit" in this)
this.onInit();
return this;

View File

@ -26,6 +26,8 @@
* 1999-08-15 rginda@ndcico.com v1.0
*/
var utils = new Object();
var DEBUG = true;
var dumpln;
@ -35,7 +37,7 @@ if (typeof document == "undefined") /* in xpcshell */
dumpln = print;
else
if (typeof dump == "function")
dumpln = function (str) {dump (str + "\n");}
dumpln = function (str) {dump (str + "\n"); }
else if (jsenv.HAS_RHINO)
dumpln = function (str) {var out = java.lang.System.out;
out.println(str); out.flush(); }
@ -636,3 +638,21 @@ function map(func, ary) {
}
function getSpecialDirectory(name)
{
if (!("directoryService" in utils))
{
const DS_CTR = "@mozilla.org/file/directory_service;1";
const nsIProperties = Components.interfaces.nsIProperties;
utils.directoryService =
Components.classes[DS_CTR].getService(nsIProperties);
}
return utils.directoryService.get(name, Components.interfaces.nsIFile);
}
function encodeChar(ch)
{
return "%" + ch.charCodeAt(0).toString(16);
}

View File

@ -62,6 +62,7 @@ function addCommands(commandObject)
add ("kick", "onInputKick");
add ("leave", "onInputLeave");
add ("list", "onInputList");
add ("log", "onInputLog");
add ("me", "onInputMe");
add ("msg", "onInputMsg");
add ("name", "onInputName");

View File

@ -78,8 +78,8 @@ function onInputFocus ()
function onLoad()
{
initHost(client);
initPrefs();
initHost(client);
readPrefs();
setClientOutput();
initStatic();
@ -573,7 +573,9 @@ function onDeleteView(view)
}
}
if (view.TYPE == "IRCChannel" && view.active)
view.part();
}
function onClearCurrentView()
@ -590,9 +592,6 @@ function onClearCurrentView()
function onSortCol(sortColName)
{
const nsIXULSortService = Components.interfaces.nsIXULSortService;
const isupports_uri = "@mozilla.org/xul/xul-sort-service;1";
var node = document.getElementById(sortColName);
if (!node)
return false;
@ -603,28 +602,10 @@ function onSortCol(sortColName)
if (sortDirection == "ascending")
sortDirection = "descending";
else if (sortDirection == "descending")
sortDirection = "natural";
else
sortDirection = "ascending";
var xulSortService =
Components.classes[isupports_uri].getService(nsIXULSortService);
if (!xulSortService)
return false;
try
{
if ("sort" in xulSortService)
xulSortService.sort(node, sortResource, sortDirection);
else
xulSortService.Sort(node, sortResource, sortDirection);
document.persist("user-list", "sortResource");
document.persist("user-list", "sortDirection");
}
catch(ex)
{
//dd("Exception calling xulSortService.sort()");
}
sortUserList(node, sortDirection);
return false;
}
@ -735,7 +716,11 @@ function onInputKeyPress (e)
switch (e.keyCode)
{
case 9: /* tab */
onTabCompleteRequest(e);
if (e.ctrlKey || e.metaKey)
cycleView(e.shiftKey ? -1: 1);
else
onTabCompleteRequest(e);
e.preventDefault();
break;
@ -904,7 +889,9 @@ function onWindowKeyPress (e)
var code = Number (e.keyCode);
var w;
var newOfs;
var userList = document.getElementById("user-list");
var elemFocused = document.commandDispatcher.focusedElement;
switch (code)
{
case 112: /* F1 */
@ -923,8 +910,11 @@ function onWindowKeyPress (e)
break;
case 33: /* pgup */
if (elemFocused == userList)
break;
w = client.currentFrame;
newOfs = w.pageYOffset - (w.innerHeight / 2);
newOfs = w.pageYOffset - (w.innerHeight * 0.9);
if (newOfs > 0)
w.scrollTo (w.pageXOffset, newOfs);
else
@ -933,8 +923,11 @@ function onWindowKeyPress (e)
break;
case 34: /* pgdn */
if (elemFocused == userList)
break;
w = client.currentFrame;
newOfs = w.pageYOffset + (w.innerHeight / 2);
newOfs = w.pageYOffset + (w.innerHeight * 0.9);
if (newOfs < (w.innerHeight + w.pageYOffset))
w.scrollTo (w.pageXOffset, newOfs);
else
@ -1835,10 +1828,10 @@ function cli_imsg (e)
if (ary == null)
return false;
var usr = e.network.primServ.addUser(ary[1].toLowerCase());
var usr = e.network.primServ.addUser(ary[1]);
var msg = filterOutput(ary[2], "PRIVMSG", "ME!");
client.currentObject.display (msg, "PRIVMSG", "ME!", usr);
usr.display (msg, "PRIVMSG", "ME!", usr);
usr.say (fromUnicode(ary[2], client.currentObject.charset));
return true;
@ -2571,6 +2564,12 @@ function cli_istalk (e)
}
client.stalkingVictims[client.stalkingVictims.length] = e.inputData;
for (var name in client.networks)
{
if ("stalkExpression" in client.networks[name])
updateStalkExpression(client.networks[name]);
}
client.currentObject.display(getMsg("cli_istalkMsg3",e.inputData), "STALK");
return true;
}
@ -2592,11 +2591,111 @@ function cli_iunstalk ( e )
}
}
for (var name in client.networks)
{
if ("stalkExpression" in client.networks[name])
updateStalkExpression(client.networks[name]);
}
client.currentObject.display(getMsg("cli_iunstalkMsg2", e.inputData),
"UNSTALK");
return true;
}
client.startLogging =
function cli_startlog (view)
{
var dir = getSpecialDirectory("ProfD");
switch (view.TYPE)
{
case "IRCNetwork":
view.logFile = view.name.replace(/:/, ".") + ".log";
break;
case "IRCChannel":
case "IRCUser":
view.logFile = view.parent.parent.name.replace(/:/, ".") +
"," + view.name + ".log";
break;
case "IRCClient":
view.logFile = "client.log";
break;
default:
view.displayHere(getMsg("cli_ilogMsg4"), "ERROR");
return;
}
view.logFile = view.logFile.replace(/[^\w\d.,#-_]/g, encodeChar);
dir.append(view.logFile);
view.logFile = dir.path;
try
{
view.logFile = fopen(view.logFile, ">>");
}
catch (ex)
{
view.displayHere(getMsg("cli_ilogMsg5", view.logFile), "ERROR");
return;
}
view.displayHere(getMsg("cli_ilogMsg6", view.logFile.path), "INFO");
try
{
view.logFile.write("Logging started at " + new Date() + "\n");
}
catch (ex)
{
view.displayHere(getMsg("cli_ilogMsg7", view.logFile.path),
"ERROR");
view.logFile.close();
return;
}
view.logging = true;
view.localPrefs.setBoolPref("logging", true);
}
client.stopLogging =
function cli_stoplog (view)
{
if (view.logging)
{
view.localPrefs.clearUserPref("logging");
view.logFile.close();
view.logging = false;
}
view.displayHere(getMsg("cli_ilogMsg3"), "INFO");
}
client.onInputLog =
function cli_ilog (e)
{
var view = client.currentObject;
if (!e.inputData)
{
if (!view.logging)
view.displayHere(getMsg("cli_ilogMsg"), "INFO");
else
view.displayHere(getMsg("cli_ilogMsg2", view.logFile.path), "INFO");
return true;
}
if (e.inputData == "off")
{
client.stopLogging(view);
}
else if (e.inputData == "on")
{
client.startLogging(view);
}
else
{
return false;
}
return true;
}
/* 'private' function, should only be used from inside */
CIRCChannel.prototype._addUserToGraph =
function my_addtograph (user)
@ -2619,6 +2718,15 @@ function my_remfgraph (user)
}
CIRCNetwork.prototype.onInit =
function net_oninit ()
{
var myBranch = this.name.replace(/[^\w\d]/g, encodeChar);
this.localPrefs =
client.prefService.getBranch(client.prefBranch.root + "viewList." +
myBranch + ".");
}
CIRCNetwork.prototype.onInfo =
function my_netinfo (e)
{
@ -2672,6 +2780,7 @@ function my_showtonet (e)
case "001":
updateTitle(this);
updateNetwork (this);
updateStalkExpression(this);
if (client.currentObject == this)
{
var status = document.getElementById("offline-status");
@ -2879,7 +2988,7 @@ function my_323 (e)
CIRCNetwork.prototype.on322 = /* LIST reply */
function my_listrply (e)
{
if (!("list" in this))
if (!("list" in this) || !("done" in this.list))
this.listInit();
++this.list.count;
e.params[2] = toUnicode(e.params[2]);
@ -3134,26 +3243,25 @@ function my_replyping (e)
CIRCNetwork.prototype.onNick =
function my_cnick (e)
{
if (userIsMe (e.user))
{
if (client.currentObject == this)
this.displayHere (getMsg("my_cnickMsg", e.user.properNick),
"NICK", "ME!", e.user, this);
updateNetwork();
updateStalkExpression(this);
}
else
{
this.display (getMsg("my_cnickMsg2", [e.oldNick, e.user.properNick]),
"NICK", e.user, this);
}
}
CIRCNetwork.prototype.onPing =
function my_netping (e)
{
updateNetwork (this);
}
CIRCNetwork.prototype.onPong =
@ -3164,6 +3272,19 @@ function my_netpong (e)
}
CIRCChannel.prototype.onInit =
function chan_oninit ()
{
var myBranch = this.parent.parent.name + "," + this.name;
myBranch = myBranch.replace(/[^\w\d,]/g, encodeChar);
this.localPrefs =
client.prefService.getBranch(client.prefBranch.root + "viewList." +
myBranch + ".");
if (getBoolPref("logging", false, this.localPrefs))
client.startLogging(this);
}
CIRCChannel.prototype.onPrivmsg =
function my_cprivmsg (e)
{
@ -3318,7 +3439,7 @@ function my_cjoin (e)
}
this._addUserToGraph (e.user);
updateUserList()
updateChannel (e.channel);
}
@ -3433,7 +3554,7 @@ function my_cnick (e)
*/
e.user.updateGraphResource();
updateUserList();
}
CIRCChannel.prototype.onQuit =
@ -3454,6 +3575,19 @@ function my_cquit (e)
}
CIRCUser.prototype.onInit =
function user_oninit ()
{
var myBranch = this.parent.parent.name + "," + this.name;
myBranch = myBranch.replace(/[^\w\d,]/g, encodeChar);
this.localPrefs =
client.prefService.getBranch(client.prefBranch.root + "viewList." +
myBranch + ".");
if (getBoolPref("logging", false, this.localPrefs))
client.startLogging(this);
}
CIRCUser.prototype.onPrivmsg =
function my_cprivmsg (e)
{

View File

@ -55,7 +55,7 @@
<command id="cmd_prev_view" oncommand="cycleView(-1);"/>
<!-- File commands -->
<command id="cmd_close" oncommand="window.close();"/>
<command id="cmd_closewin" oncommand="window.close();"/>
<command id="cmd_quit"/>
<!-- File:Options commands -->
@ -105,9 +105,11 @@
<key id="key_prev_view" observes="cmd_prev_view"
modifiers="control" keycode="VK_PAGE_UP"/>
<!-- File:Options keys -->
<!-- File keys -->
<key id="key_debug" observes="cmd_debug"
modifiers="accel shift" key="D"/>
<key id="key_closewin" observes="cmd_closewin"
modifiers="accel shift" key="W"/>
<!-- Edit Keys -->
<key id="key_undo"/>
@ -179,7 +181,12 @@
</menu>
<menuseparator/>
<menuitem id="menu_close"/>
<menuitem label="&DeleteViewCmd.label;"
accesskey="&DeleteViewCmd.aKey;"
observes="cmd_deleteview" key="key_deleteview"/>
<menuitem label="&CloseCmd.label;"
accesskey="&CloseCmd.aKey;"
observes="cmd_closewin" key="key_closewin"/>
</menupopup>
</menu>

View File

@ -42,7 +42,14 @@
<![CDATA[
var _elementIDs = ["czNickname", "czUsername", "czDesc",
"czNotify", "czDisplayCollapse", "czDisplayCopyMsgs",
"czReconnect", "czColorCodes", "czNickCompleteStr"];
"czReconnect", "czColorCodes", "czNickCompleteStr", "czCharset"];
const OSBS_CTRID = "@mozilla.org/observer-service;1";
const Components.interfaces.nsIObserverService = nsIObserverService;
var observerService =
Components.classes[OBS_CTRID].getService(nsIObserverService);
observerService.notifyObservers(null, "charsetmenu-selected", "other");
]]>
</script>
@ -111,4 +118,19 @@
</hbox>
<label>&global.nickCompleteStr.desc;</label>
</groupbox>
<groupbox align="start">
<caption label="&global.Charset.grouplabel;"/>
<hbox align="center">
<label value="&global.DefaultCharset.label;" accesskey="&global.DefaultCharset.accesskey;" control="DefaultCharsetList"/>
<menulist id="czCharset" ref="NC:DecodersRoot" datasources="rdf:charset-menu"
prefstring="extensions.irc.charset" preftype="localizedstring"
wsm_attributes="value">
<template>
<menupopup>
<menuitem label="rdf:http://home.netscape.com/NC-rdf#Name" value="..." uri="..."/>
</menupopup>
</template>
</menulist>
</hbox>
</groupbox>
</page>

View File

@ -47,7 +47,7 @@ function loadList(list)
var prefList = gList.getAttribute("prefvalue");
if (prefList.match(/;/))
if (prefList)
{
var items = prefList.split(/\s*;\s*/);
for (i in items)

View File

@ -43,31 +43,39 @@
<script src="chrome://chatzilla/content/prefpanel/stalk.js"/>
<script type="application/x-javascript">
<![CDATA[
var _elementIDs = ["czStalkWords"];
var _elementIDs = ["czStalkWords", "czStalkWholeWords"];
]]>
</script>
<groupbox flex="1">
<caption><label value="&stalkWords.title;" control="czStalkWords"
accesskey="&stalkWords.accesskey;"/></caption>
<vbox flex="1">
<groupbox flex="1">
<caption><label value="&stalkWords.title;" control="czStalkWords"
accesskey="&stalkWords.accesskey;"/></caption>
<label>&stalkWords.label1;</label>
<label>&stalkWords.label2;</label>
<label>&stalkWords.label1;</label>
<label>&stalkWords.label2;</label>
<hbox flex="1">
<listbox id="czStalkWords" flex="1"
<hbox flex="1">
<listbox id="czStalkWords" flex="1"
style="width: 0px; height: 0px;" crop="center"
prefstring="extensions.irc.stalkWords" preftype="string"
prefvalue="" prefattribute="prefvalue" wsm_attributes="prefvalue"
onselect="listUpdateButtons('StalkWords');"/>
</hbox>
<hbox>
<button id="czAddStalkWords" label="&list.add.label;"
accesskey="&list.add.stalk.accesskey;"
oncommand="listAdd('StalkWords');"/>
<button id="czDelStalkWords" label="&list.del.label;"
accesskey="&list.del.stalk.accesskey;"
oncommand="listDelete('StalkWords');"/>
</hbox>
</groupbox>
</hbox>
<hbox>
<button id="czAddStalkWords" label="&list.add.label;"
accesskey="&list.add.stalk.accesskey;"
oncommand="listAdd('StalkWords');"/>
<button id="czDelStalkWords" label="&list.del.label;"
accesskey="&list.del.stalk.accesskey;"
oncommand="listDelete('StalkWords');"/>
</hbox>
</groupbox>
<checkbox id="czStalkWholeWords" label="&stalkWholeWords.label;"
tooltiptext="&stalkWholeWords.tooltip;"
accesskey="&stalkWholeWords.accesskey;" prefdefval="true"
prefstring="extensions.irc.stalkWholeWords"/>
</vbox>
</page>

View File

@ -32,7 +32,7 @@
* +- multiline (Boolean) multiline input mode
* +- colorcodes (Boolean) enable color code escape characters
* +- bugURL (String) url to use for "bug 12345" links. Use %s to place
* the bug number.
* | the bug number.
* +- initialURLs (String) irc:// urls to connect to on startup, semicolon
* | separated
* +- initialScripts (String) urls for scripts to run at startup,
@ -53,6 +53,8 @@
* | at the beginning of sentences
* +- stalkWords (String) List of words to add to the stalk victims list
* | semicolon separated (see the /stalk command)
* +- stalkWholeWords (Boolean) True if stalk words should not match against
* | parts of words.
* +- deleteOnPart (Boolean) Delete channel window automatically after a /part
* |
* | The following beep prefs can be set to the text "beep" to use the
@ -82,46 +84,55 @@
* | +- chanuser
* | +- maxlines (Number) max lines to keep in /msg views
* +- debug
* +- tracer (Boolean) enable/disable debug message tracing
* | +- tracer (Boolean) enable/disable debug message tracing
* +- viewList
* +- client
* | +- logging (Boolean) enable/disable logging in the client view
* +- <escaped network name>
* | +- logging (Boolean) enable/disable logging in the <network> view
* +- <escaped network,channel>
* +- logging (Boolean) enable/disable logging in the <channel> view on
* <network>
*/
function initPrefs()
{
client.prefSpecs = {
"nickname": ["CIRCNetwork.prototype.INITIAL_NICK", "IRCMonkey"],
"username": ["CIRCNetwork.prototype.INITIAL_NAME", "chatzilla"],
"desc": ["CIRCNetwork.prototype.INITIAL_DESC", "New Now Know How"],
"reconnect": ["CIRCNetwork.prototype.stayingPower", true],
"multiline": ["client.MULTILINE", false],
"colorCodes": ["client.COLORCODES", false],
"defaultNet": ["client.DEFAULT_NETWORK", "moznet"],
"charset": ["client.CHARSET", ""],
"initialURLs": ["client.INITIAL_URLS", "irc://"],
"initialScripts": ["client.INITIAL_SCRIPTS", ""],
"newTabLimit": ["client.NEW_TAB_LIMIT", 15],
"raiseNewTab": ["client.RAISE_NEW_TAB", false],
"nickCompleteStr": ["client.ADDRESSED_NICK_SEP", ", "],
"stalkWords": ["client.stalkingVictims", []],
"deleteOnPart": ["client.DELETE_ON_PART", true],
"stalkBeep": ["client.STALK_BEEP", "beep"],
"msgBeep": ["client.MSG_BEEP", "beep beep"],
"queryBeep": ["client.QUERY_BEEP", "beep"],
"munger": ["client.munger.enabled", true],
"munger.colorCodes": ["client.enableColors", true],
"munger.smileyText": ["client.smileyText", false],
"nickname": ["CIRCNetwork.prototype.INITIAL_NICK", "IRCMonkey"],
"username": ["CIRCNetwork.prototype.INITIAL_NAME", "chatzilla"],
"desc": ["CIRCNetwork.prototype.INITIAL_DESC", "New Now Know How"],
"reconnect": ["CIRCNetwork.prototype.stayingPower", true],
"multiline": ["client.MULTILINE", false],
"colorCodes": ["client.COLORCODES", false],
"defaultNet": ["client.DEFAULT_NETWORK", "moznet"],
"charset": ["client.CHARSET", ""],
"initialURLs": ["client.INITIAL_URLS", "irc://"],
"initialScripts": ["client.INITIAL_SCRIPTS", ""],
"newTabLimit": ["client.NEW_TAB_LIMIT", 15],
"raiseNewTab": ["client.RAISE_NEW_TAB", false],
"nickCompleteStr": ["client.ADDRESSED_NICK_SEP", ", "],
"stalkWords": ["client.stalkingVictims", []],
"stalkWholeWords": ["client.STALK_WHOLE_WORDS", true],
"deleteOnPart": ["client.DELETE_ON_PART", true],
"stalkBeep": ["client.STALK_BEEP", "beep"],
"msgBeep": ["client.MSG_BEEP", "beep beep"],
"queryBeep": ["client.QUERY_BEEP", "beep"],
"munger": ["client.munger.enabled", true],
"munger.colorCodes": ["client.enableColors", true],
"munger.smileyText": ["client.smileyText", false],
"bugURL": ["client.BUG_URL",
"http://bugzilla.mozilla.org/show_bug.cgi?id=%s"],
"notify.aggressive": ["client.FLASH_WINDOW", true],
"settings.autoSave": ["client.SAVE_SETTINGS", true],
"debug.tracer" : ["client.debugHook.enabled", false],
"http://bugzilla.mozilla.org/show_bug.cgi?id=%s"],
"notify.aggressive": ["client.FLASH_WINDOW", true],
"settings.autoSave": ["client.SAVE_SETTINGS", true],
"debug.tracer" : ["client.debugHook.enabled", false],
"style.default": ["client.DEFAULT_STYLE",
"chrome://chatzilla/skin/output-default.css"],
"views.collapseMsgs": ["client.COLLAPSE_MSGS", false],
"views.copyMessages": ["client.COPY_MESSAGES", true],
"views.client.maxlines": ["client.MAX_MESSAGES", 200],
"views.network.maxlines": ["CIRCNetwork.prototype.MAX_MESSAGES", 100],
"views.channel.maxlines": ["CIRCChannel.prototype.MAX_MESSAGES", 300],
"views.chanuser.maxlines": ["CIRCChanUser.prototype.MAX_MESSAGES", 200]
"chrome://chatzilla/skin/output-default.css"],
"views.collapseMsgs": ["client.COLLAPSE_MSGS", false],
"views.copyMessages": ["client.COPY_MESSAGES", true],
"views.client.maxlines": ["client.MAX_MESSAGES", 200],
"views.network.maxlines": ["CIRCNetwork.prototype.MAX_MESSAGES", 100],
"views.channel.maxlines": ["CIRCChannel.prototype.MAX_MESSAGES", 300],
"views.chanuser.maxlines": ["CIRCChanUser.prototype.MAX_MESSAGES", 200]
};
const PREF_CTRID = "@mozilla.org/preferences-service;1";
@ -135,8 +146,6 @@ function initPrefs()
var internal = client.prefBranch.QueryInterface(nsIPrefBranchInternal);
internal.addObserver("", client.prefObserver, false);
readPrefs();
}
function destroyPrefs()
@ -191,7 +200,7 @@ function readPref(prefName)
eval (varName + " = " + prefValue.quote());
}
}
else if ((ary = prefName.match(/munger.(.*)/)) &&
else if ((ary = prefName.match(/munger\.(.*)/)) &&
ary[1] in client.munger.entries)
{
client.munger.entries[ary[1]].enabled =
@ -200,7 +209,8 @@ function readPref(prefName)
}
else
{
dd ("readPref: UNKNOWN PREF ``" + prefName + "''");
if (!(prefName.match(/viewList\..*/)))
dd ("readPref: UNKNOWN PREF ``" + prefName + "''");
}
}
@ -225,8 +235,18 @@ function readPrefs()
function writePref(prefName)
{
//if (prefName.indexOf("extensions.irc." == 0))
// prefName = prefName.substr(15);
function clearPref(prefName)
{
try
{
client.prefBranch.clearUserPref (prefName);
}
catch (ex)
{
// ignore missing pref exception
}
};
var ary;
if (prefName in client.prefSpecs)
@ -235,20 +255,30 @@ function writePref(prefName)
var defaultValue = client.prefSpecs[prefName][1];
var prefValue = eval(varName);
if (typeof defaultValue == "boolean")
client.prefBranch.setBoolPref(prefName, prefValue);
else if (typeof defaultValue == "number")
client.prefBranch.setIntPref(prefName, prefValue);
else if (defaultValue instanceof Array)
client.prefBranch.setCharPref(prefName, prefValue.join("; "));
if (prefValue != defaultValue)
{
if (typeof defaultValue == "boolean")
client.prefBranch.setBoolPref(prefName, prefValue);
else if (typeof defaultValue == "number")
client.prefBranch.setIntPref(prefName, prefValue);
else if (defaultValue instanceof Array)
client.prefBranch.setCharPref(prefName, prefValue.join("; "));
else
client.prefBranch.setCharPref(prefName, prefValue);
}
else
client.prefBranch.setCharPref(prefName, prefValue);
{
clearPref(prefName);
}
}
else if ((ary = prefName.match(/munger\.(.*)/)) &&
ary[1] in client.munger.entries)
{
client.prefBranch.setBoolPref (prefName,
client.munger.entries[ary[1]].enabled);
entry = client.munger.entries[ary[1]];
if (entry.enabled != entry.enabledDefault)
client.prefBranch.setBoolPref(prefName, entry.enabled);
else
clearPref (prefName);
}
else
{
@ -281,7 +311,7 @@ function writePrefs (rootNode)
function getCharPref (prefName, defaultValue)
{
var e, rv;
var rv;
try
{
@ -299,7 +329,6 @@ function getCharPref (prefName, defaultValue)
function getIntPref (prefName, defaultValue)
{
var e;
try
{
@ -312,12 +341,13 @@ function getIntPref (prefName, defaultValue)
}
function getBoolPref (prefName, defaultValue)
function getBoolPref (prefName, defaultValue, branch)
{
var e;
try
{
if (branch)
return branch.getBoolPref (prefName);
return client.prefBranch.getBoolPref (prefName);
}
catch (e)

View File

@ -55,6 +55,7 @@
<script src="chrome://chatzilla/content/lib/js/command-manager.js"/>
<script src="chrome://chatzilla/content/lib/js/irc.js"/>
<script src="chrome://chatzilla/content/lib/js/irc-debug.js"/>
<script src="chrome://chatzilla/content/lib/js/file-utils.js"/>
<script src="chrome://chatzilla/content/lib/xul/munger.js"/>
<script src="chrome://chatzilla/content/commands.js"/>

View File

@ -24,9 +24,19 @@
*/
if (DEBUG)
dd = function (m) { dump ("-*- chatzilla: " + m + "\n"); }
{
dd = function (m) {
dump ("-*- chatzilla: " + m + "\n");
// messages that start with ** are warnings, so we'll
// show a stack trace here too.
if (m.search(/^\*\*/) == 0)
dump(getStackTrace() + "\n");
};
}
else
{
dd = function (){};
}
var client = new Object();
@ -36,7 +46,7 @@ const MSG_UNKNOWN = getMsg ("unknown");
client.defaultNick = getMsg("defaultNick");
client.version = "0.8.31";
client.version = "0.8.34";
client.TYPE = "IRCClient";
client.COMMAND_CHAR = "/";
@ -297,7 +307,7 @@ function initStatic()
client.statusElement = document.getElementById ("status-text");
client.defaultStatus = getMsg ("defaultStatus");
client.display (getMsg("welcome"), "HELLO");
setCurrentObject (client);
@ -306,6 +316,8 @@ function initStatic()
setInterval ("onNotifyTimeout()", client.NOTIFY_TIMEOUT);
if (getBoolPref("logging", false, client.localPrefs))
client.startLogging(client);
}
function processStartupURLs()
@ -482,6 +494,9 @@ function initHost(obj)
obj.rdf.initTree("user-list");
obj.rdf.setTreeRoot("user-list", obj.rdf.resNullChan);
obj.localPrefs =
client.prefService.getBranch(obj.prefBranch.root +
"viewList.client.");
}
function insertLink (matchText, containerTag)
@ -806,15 +821,34 @@ function insertHyphenatedWord (longWord, containerTag)
}
}
function msgIsImportant (msg, sourceNick, myNick)
{
var sv = "(" + myNick + ")";
if (client.stalkingVictims.length > 0)
sv += "|(" + client.stalkingVictims.join(")|(") + ")";
function updateStalkExpression(network)
{
function escapeChar(ch)
{
return "\\" + ch;
};
var str = "(^|[\\W\\s])" + sv + "([\\W\\s]|$)";
var re = new RegExp(str, "i");
if (msg.search(re) != -1 || sourceNick && sourceNick.search(re) != -1)
list = client.stalkingVictims;
ary = new Array();
ary.push(network.primServ.me.nick.replace(/[^\w\d]/g, escapeChar));
for (var i = 0; i < list.length; ++i)
ary.push(list[i].replace(/[^\w\d]/g, escapeChar));
var re;
if (client.STALK_WHOLE_WORDS)
re = "(^|[\\W\\s])((" + ary.join(")|(") + "))([\\W\\s]|$)";
else
re = "(" + ary.join(")|(") + ")";
network.stalkExpression = new RegExp(re, "i");
}
function msgIsImportant (msg, sourceNick, network)
{
re = network.stalkExpression;
if (msg.search(re) != -1 || sourceNick && sourceNick.search(re) == 0)
return true;
return false;
@ -869,7 +903,12 @@ function playSound (file)
var uri = Components.classes["@mozilla.org/network/standard-url;1"];
uri = uri.createInstance(Components.interfaces.nsIURI);
uri.spec = file;
client.sound.play (uri);
try
{
client.sound.play (uri);
} catch (ex) {
// ignore exceptions from this pile of code.
}
}
}
@ -949,7 +988,7 @@ function getMsg (msgName)
function openQueryTab (server, nick)
{
var usr = server.addUser(nick.toLowerCase());
var usr = server.addUser(nick);
if (!("messages" in usr))
usr.displayHere (getMsg("cli_imsgMsg3", usr.properNick), "INFO");
server.sendData ("WHO " + nick + "\n");
@ -1190,8 +1229,9 @@ function joinChannel(e, namelist, key, charset)
if (!("messages" in e.channel))
{
this.display (getMsg("cli_ijoinMsg3", e.channel.unicodeName),
"INFO");
e.channel.displayHere (getMsg("cli_ijoinMsg3",
e.channel.unicodeName),
"INFO");
}
setCurrentObject(e.channel);
}
@ -1971,6 +2011,52 @@ function notifyAttention (source)
}
function updateUserList()
{
var node;
var sortDirection;
var colArray = ["usercol-op", "usercol-voice", "usercol-nick"];
for (var i = 0; i < colArray.length; i++)
{
node = document.getElementById(colArray[i]);
if (!node)
return false;
sortDirection = node.getAttribute("sortDirection");
if (sortDirection != "")
break;
}
sortUserList(node, sortDirection);
}
function sortUserList(node, sortDirection)
{
const nsIXULSortService = Components.interfaces.nsIXULSortService;
const isupports_uri = "@mozilla.org/xul/xul-sort-service;1";
var xulSortService =
Components.classes[isupports_uri].getService(nsIXULSortService);
if (!xulSortService)
return false;
var sortResource = node.getAttribute("resource");
try
{
if ("sort" in xulSortService)
xulSortService.sort(node, sortResource, sortDirection);
else
xulSortService.Sort(node, sortResource, sortDirection);
document.persist("user-list", "sortResource");
document.persist("user-list", "sortDirection");
}
catch(ex)
{
//dd("Exception calling xulSortService.sort()");
}
}
function getFrameForDOMWindow(window)
{
var frame;
@ -2108,7 +2194,7 @@ function getTabForObject (source, create)
{
case "IRCChanUser":
case "IRCUser":
name = source.nick;
name = source.properNick;
break;
case "IRCNetwork":
@ -2303,6 +2389,9 @@ function cli_connet (netname, pass)
var netobj = client.networks[netname];
if (getBoolPref("logging", false, netobj.localPrefs))
client.startLogging(netobj);
if (!("messages" in netobj))
netobj.displayHere (getMsg("cli_attachOpened", netname), "INFO");
setCurrentObject(netobj);
@ -2435,6 +2524,7 @@ function __display(message, msgtype, sourceObj, destObj)
{
var canMergeData = false;
var canCollapseRow = false;
var logText = "";
function setAttribs (obj, c, attrs)
{
@ -2464,7 +2554,7 @@ function __display(message, msgtype, sourceObj, destObj)
{
me = o.server.me; /* get the object representing the user */
}
if (sourceObj == "ME!") sourceObj = me; /* if the caller to passes "ME!"*/
if (sourceObj == "ME!") sourceObj = me; /* if the caller passes "ME!" */
if (destObj == "ME!") destObj = me; /* substitute the actual object */
var fromType = (sourceObj && sourceObj.TYPE) ? sourceObj.TYPE : "unk";
@ -2500,6 +2590,10 @@ function __display(message, msgtype, sourceObj, destObj)
mins = "0" + mins;
var statusString;
var timeStamp = getMsg("cli_dateString", [d.getMonth() + 1, d.getDate(),
d.getHours(), mins]);
logText = "[" + timeStamp + "] ";
if (fromUser)
{
statusString =
@ -2546,12 +2640,23 @@ function __display(message, msgtype, sourceObj, destObj)
{
getAttention = true;
this.defaultCompletion = "/msg " + nick + " ";
if (msgtype == "ACTION")
{
logText += "*" + nick + " ";
}
else
{
if (this.TYPE == "IRCUser")
logText += "<" + nick + "> ";
else
logText += "*" + nick + "* ";
}
}
else /* msg from user to channel */
{
if (typeof (message == "string") && me)
{
isImportant = msgIsImportant (message, nick, me.nick);
isImportant = msgIsImportant (message, nick, o.network);
if (isImportant)
{
this.defaultCompletion = nick +
@ -2560,18 +2665,35 @@ function __display(message, msgtype, sourceObj, destObj)
playSounds(client.STALK_BEEP);
}
}
if (msgtype == "ACTION")
logText += "*" + nick + " ";
else
logText += "<" + nick + "> ";
}
}
else if (toType == "IRCUser") /* msg from me to user */
{
if (this.TYPE == "IRCUser")
{
nick = sourceObj.properNick;
if (msgtype == "ACTION")
logText += "*" + nick + " ";
else
logText += "<" + nick + "> ";
}
else
{
nick = destObj.properNick;
logText += ">" + nick + "< ";
}
}
else /* msg from me to channel */
{
nick = sourceObj.properNick;
if (msgtype == "ACTION")
logText += "*" + nick + " ";
else
logText += "<" + nick + "> ";
}
if (!("mark" in this))
@ -2608,7 +2730,6 @@ function __display(message, msgtype, sourceObj, destObj)
msgRow.appendChild (msgSource);
canMergeData = client.COLLAPSE_MSGS;
canCollapseRow = client.COLLAPSE_ROWS;
}
else
{
@ -2632,6 +2753,7 @@ function __display(message, msgtype, sourceObj, destObj)
msgType.appendChild (newInlineText (code));
msgRow.appendChild (msgType);
logText += code + " ";
}
if (message)
@ -2639,7 +2761,8 @@ function __display(message, msgtype, sourceObj, destObj)
var msgData = document.createElementNS("http://www.w3.org/1999/xhtml",
"html:td");
setAttribs (msgData, "msg-data", {statusText: statusString,
colspan: client.INITIAL_COLSPAN});
colspan: client.INITIAL_COLSPAN,
timeStamp: timeStamp});
if (isImportant)
msgData.setAttribute ("important", "true");
@ -2649,9 +2772,13 @@ function __display(message, msgtype, sourceObj, destObj)
if (typeof message == "string")
{
msgData.appendChild (stringToMsg (message, this));
logText += message;
}
else
{
msgData.appendChild (message);
logText += message.innerHTML.replace(/<[^<]*>/g, "");
}
msgRow.appendChild (msgData);
}
@ -2709,6 +2836,22 @@ function __display(message, msgtype, sourceObj, destObj)
o.network.displayHere("{" + this.name + "} " + message, msgtype,
sourceObj, destObj);
}
if (("logging" in this) && this.logging)
{
try
{
this.logFile.write(logText + "\n");
}
catch (ex)
{
this.logging = false;
this.localPrefs.clearUserPref("logging");
this.displayHere(getMsg("cli_ilogMsg7", this.logFile.path),
"ERROR");
this.logFile.close();
}
}
}
function addHistory (source, obj, mergeData, collapseRow)

View File

@ -29,6 +29,7 @@ function CMungerEntry (name, regex, className, enable, tagName)
if (name[0] != ".")
this.description = getMsg("rule_" + name);
this.enabled = (typeof enable == "undefined" ? true : enable);
this.enabledDefault = this.enabled;
this.tagName = (tagName) ? tagName : "html:span";
if (regex instanceof RegExp)

View File

@ -72,11 +72,11 @@
<!ENTITY ClearViewCmd.label "Clear View">
<!ENTITY ClearViewCmd.aKey "e">
<!ENTITY DeleteViewCmd.label "Close View">
<!ENTITY DeleteViewCmd.aKey "o">
<!ENTITY DeleteViewCmd.aKey "V">
<!ENTITY StatusCmd.label "Connection Status">
<!ENTITY StatusCmd.aKey "C">
<!ENTITY CloseCmd.label "Close">
<!ENTITY CloseCmd.label "Close Window">
<!ENTITY CloseCmd.aKey "C">
<!ENTITY PopupQueryCmd.label "Private Chat ``$nick''">

View File

@ -118,6 +118,9 @@ leaveHelp=Leaves the current channel, use /delete or /hide to force the view to
listUsage=[channel]
listHelp=Lists channel name, user count, and topic information for the network/server you are attached to. If you omit the optional channel argument, all channels will be listed. On large networks, the server may disconnect you for asking for a complete list.
logUsage=on | off
logHelp=Turns logging on or off for the current channel. The state will be saved in prefs, so that if logging is on when you close chatzilla, it will resume logging the next time you join the channel.
rlistUsage=<regexp>
rlistHelp=Lists channel name, user count, and topic information for the network/server you are attached to, filtered by the regular expression.
@ -249,6 +252,7 @@ cli_loadLoading=Loading subscript ``%S''
cli_loadError=Error loading subscript, line %S of ``%S'': %S
cli_sayMsg=No default action for objects of type ``%S''
cli_statusString=%S/%S %S:%S, %S
cli_dateString=%S/%S %S:%S
# handlers.js
cli_closing=Disconnecting from IRC. Click close again to exit now.
@ -370,6 +374,13 @@ cli_istalkMsg3=Now stalking %S
cli_iunstalkMsg=No longer stalking %S
cli_iunstalkMsg2=Not stalking %S
cli_irlistMsg=Error in pattern ``%S'': %S
cli_ilogMsg=Logging is off.
cli_ilogMsg2=Logging is on. Log output is going to file ``%S''.
cli_ilogMsg3=Logfile closed.
cli_ilogMsg4=Unknown view type, logging not turned on.
cli_ilogMsg5=Unable to open file ``%S''.
cli_ilogMsg6=Now logging to file ``%S''.
cli_ilogMsg7=Unable to write to file ``%S''. Logging disabled.
my_ctcprunk=CTCP %S reply ``%S'' from %S
my_whoisreplyMsg=%S <%S@%S> ``%S''
my_whoisreplyMsg2=%S: member of %S

View File

@ -88,6 +88,10 @@
<!ENTITY global.nickCompleteStr.label "Nickname completion string:">
<!ENTITY global.nickCompleteStr.accesskey "k">
<!ENTITY global.nickCompleteStr.desc "This is appended to a nickname when tab-completed as the first word.">
<!ENTITY global.Charset.grouplabel "Character Coding">
<!ENTITY global.DefaultCharset.label "Default Character Coding:">
<!ENTITY global.DefaultCharset.accesskey "d">
<!-- LOCALIZATION NOTE Charset Coding Preferences Dialog: Do NOT localize the terms "en-bz, ar-jo" -->
<!ENTITY interface.window.title "Interface">
<!ENTITY tabs.title "Tab Options">
@ -134,6 +138,9 @@
<!ENTITY stalkWords.title "Stalk Words">
<!ENTITY stalkWords.accesskey "S">
<!ENTITY stalkWholeWords.label "Stalk whole words only">
<!ENTITY stalkWholeWords.tooltip "Do not match stalk words as substrings of larger words">
<!ENTITY stalkWholeWords.accesskey "w">
<!ENTITY stalkWords.label1 "When ChatZilla sees an 'important' message, it will highlight the line and the channel's tab. If you have 'aggressive notify' enabled, ChatZilla will also use an OS-dependent method to grab your attention.">
<!ENTITY stalkWords.label2 "Your nickname is always considered 'important', but you can add more words; just add them to the list below.">