ChatZilla 0.8 checkin. see bug 71468 for details

r=ssieb, sr=shaver
This commit is contained in:
rginda%netscape.com 2001-03-14 02:35:29 +00:00
Родитель 800a0f3794
Коммит ee3e25cd86
24 изменённых файлов: 2442 добавлений и 1591 удалений

Просмотреть файл

@ -1,174 +1,71 @@
JavaScript IRC library, bot (runs in xpcshell), and client (runs in Mozilla.)
Files You'll find...
**-------------------------------------------
irc/bslib
Using ChatZilla
basic-socket library. NSPR socket functions wrapped in an object oriented
C api. Allows clients to connect to as many servers as desired, without
having to worry about the messy details.
**-------------------------------------------
irc/js/lib
JavaScript library files, including...
utils.js
Utility functions used throughout the other files. Some are very useful,
some are only slightly useful.
events.js
Event and EventPump classes. Defines a common way to create and route
events in JavaScript. Used HEAVILY throughout the rest of the libs to
perform asychronous tasks. Check the code for more details.
connection.js
JavaScript wrapper around the bsIConnection component, (CBSConnection).
This is intended to make it easier to port the library to other (read
non-XPCOM) JavaScript platforms, or to dump bsIConnection all-together
when the time is right.
http.js
Retrieves documents using the HTTP protocol and a CBSConnection. I've got
the protocol all wrong here, but it will still retrieve the root document
for a web site. Needs more work.
Table Of Contents
irc.js
Part 1: Introduction to ChatZilla.
IRC Library. Provides DOM like access to IRC. This is what your looking
for.
1.1: Introduction
1.1.1: What is IRC?
1.1.2: What is ChatZilla?
1.1.3: Where do I get more information on IRC?
dcc.js
1.2: The User Interface.
1.2.1: Menu structure.
1.2.2: User list.
1.2.3: Output area.
1.2.4: View tabs.
1.2.5: Status bar.
DCC Library. DCC is a protocol initiated over irc, and then carried out
over a Direct Client to Client (hence the name) connection. Currently,
only DCC-Chat is supported. Adding the rest should be straightforward.
1.3: Features of the input area.
1.3.1: Responding to the last person who spoke to you.
1.3.2: Autocompleting nicknames.
1.3.3: Autocompleting commands.
1.3.4: Multiline input.
**-------------------------------------------
irc/js/tests
Part 2: Navigating IRC with ChatZilla.
Scripts to test the various libraries including...
2.1: Connecting to an IRC network.
2.1.1: Listing available networks.
2.1.2: Attaching to a network.
2.1.3: Canceling an attach that isn't going well.
2.1.4: Connecting to a specific server.
2.1.5: Disconnecting when you're finished.
test_matchobject.js
2.2: Channels.
2.2.1: Finding a channel.
2.2.2: Joining.
2.2.3: Modes, Topics, and Kicks.
2.2.4: Parting.
Tests the object pattern matching functionality of utils.js. Also a good
reference while learning the rules for matching an object against a group of
pattern objects. Object pattern matching is at the root of the hook
functionality provided by events.js, so look here if you need a clue.
2.3: Private messages.
2.3.1: Receiving messages.
2.3.2: Sending messages.
2.3.3: Query windows.
ircbot.js
Part 3: Scripting ChatZilla.
The sample bot I use to test the IRC library. It's mostly functional,
with a few mods you could even use it to secure a channel (if that's what
you're into.) This is a good place to look to get a feel for how the
whole thing fits together.
3.1: Scripting basics.
3.1.1: The /eval command.
3.1.2: Writing text to the output window.
3.1.3: Writing DOM nodes to the output window.
3.1.1: Exploring objects with dumpObjectTree();
**-------------------------------------------
Misc. Notes...
3.2: More Scripting.
3.2.1: External scripts.
3.2.2: Hooking into IRC events.
Events By object:
The IRCServer object generates/ handles the following events. It is generally
not advisable to override an event handler defined on the server, unless you
realize what your replacing. Alternatley, You can hook any of these events
through the normal event hooking facilities.
onRawData:
name value
set "server"
type "parsedata"
destMethod "onParsedData"
destObject server (this)
server server (this)
connection CBSConnection (this.connection)
source the <prefix> of the message (if it exists)
user user object initialized with data from the message <prefix>
params array containing the <middle> parameters of the message
code the first <middle> parameter (most messages have this)
meat the <trailing> parameter of the message
onParsedData:
type <code>.toLowerCase();
destMethod "on" + <Code>
onTopic:
channel new channel (params[1])
on332: topic reply
channel
topic
destObject e.channel
set "channel"
on333: topic info
channel
topicBy
topicDate
destObject e.channel
set "channel"
on353: name reply (also occurs on join) If this.usersStable == true; clear
this.users, set usersStable = false. Add all users in this message to
server.channel.users (which also adds to server.users), setting isOp
and isVoice, but not host information (because it isnt here.)
set "channel"
destObject e.channel
channel
on366: End of names. set usersStable = true; so the next we see a name
reply, we know it starts
a new list
set "channel"
destObject e.channel
channel
on329: /most likely/ the channel time stamp. sent after a 366
on some (all?) servers, not in the rev of the RFC I saw.
set "channel"
destObject e.channel
channel
timeStamp Date
on324: channel mode reply, happens in response to a /MODE <channel>.
type "chanmode"
destMethod "onChanMode"
channel
onMode: Some user issued a /MODE command relative to some channel the lib
is active on, *OR* the client's user has changed modes. This message
is just an incremental update if it relates to the channel.
channel IF this is in response to a USER mode change, ie, the user
representing the bot get's set +i or such, this property
will NOT be defined.
type "chanmode" or "usermode"
destMethod "onChanMode" or "onUserMode"
onUserMode: User 'me' has changed mode. Currently ignored.
onChanMode: User issued a MODE command in an active channel, or the client's
user requested a mode update/ joined a new channel.
When this event completes, the mode property of the channel in
question will be updated with the information in the event.
A channel.onBan event will be created for each ban that appears
in the new mode.
set "channel"
destObject channel
onNick: User in one of the active channels has changed their nickname. <user>
will be renamed on the <server> and all <channel>s in which
they appear.
channel
user
onQuit: User in one of the active channels has quit IRC. <user> will be
deleted from every <channel> they appear in. <server>.<user>
lastQuitDate and lastQuitMessage will be set.
channel
user previous CIRCUser will be upgraded to a CIRCChanUser
Appendix A:
A: Styling the output window.
(copy of the comment in output-window.css)

Просмотреть файл

@ -11,6 +11,7 @@ chatzilla.jar:
content/chatzilla/lib/xul/listbox.js (xul/lib/listbox.js)
content/chatzilla/lib/xul/munger.js (xul/lib/munger.js)
content/chatzilla/chatzilla.xul (xul/content/chatzilla.xul)
content/chatzilla/outputwindow.html (xul/content/outputwindow.html)
content/chatzilla/commands.js (xul/content/commands.js)
content/chatzilla/handlers.js (xul/content/handlers.js)
content/chatzilla/readprefs.js (xul/content/readprefs.js)
@ -20,11 +21,7 @@ chatzilla.jar:
content/chatzilla/chatzillaOverlay.js (xul/content/chatzillaOverlay.js)
skin/modern/chatzilla/chatzilla.css (xul/skin/chatzilla.css)
skin/modern/chatzilla/output-default.css (xul/skin/output-default.css)
skin/modern/chatzilla/output-loud.css (xul/skin/output-loud.css)
skin/modern/chatzilla/output-marble.css (xul/skin/output-marble.css)
skin/modern/chatzilla/images/xtal.jpg (xul/skin/images/xtal.jpg)
skin/modern/chatzilla/images/blue_rock.gif (xul/skin/images/blue_rock.gif)
skin/modern/chatzilla/images/face-ear.gif (xul/skin/images/face-ear.gif)
skin/modern/chatzilla/images/face-ear.gif (xul/skin/images/face-ear.gif)
skin/modern/chatzilla/images/face-frown.gif (xul/skin/images/face-frown.gif)
skin/modern/chatzilla/images/face-tongue.gif (xul/skin/images/face-tongue.gif)
skin/modern/chatzilla/images/face-angry.gif (xul/skin/images/face-angry.gif)
@ -38,10 +35,6 @@ chatzilla.jar:
skin/modern/chatzilla/images/isnt-op.gif (xul/skin/images/isnt-op.gif)
skin/modern/chatzilla/images/is-voice.gif (xul/skin/images/is-voice.gif)
skin/modern/chatzilla/images/isnt-voice.gif (xul/skin/images/isnt-voice.gif)
skin/modern/chatzilla/images/view-activity.gif (xul/skin/images/view-activity.gif)
skin/modern/chatzilla/images/view-attention.gif (xul/skin/images/view-attention.gif)
skin/modern/chatzilla/images/view-current.gif (xul/skin/images/view-current.gif)
skin/modern/chatzilla/images/view-normal.gif (xul/skin/images/view-normal.gif)
locale/en-US/chatzilla/chatzillaOverlay.dtd (xul/locale/en-US/chatzillaOverlay.dtd)
locale/en-US/chatzilla/chatzilla.dtd (xul/locale/en-US/chatzilla.dtd)
locale/en-US/chatzilla/pref-irc.dtd (xul/locale/en-US/pref-irc.dtd)

Просмотреть файл

@ -128,10 +128,12 @@ function (aContentType, aCommand, aWindowTarget, aSourceContext, aRequest)
}
else
{
var ass = Components.classes[ASS_CONTRACTID].getService(nsIAppShellService);
var ass =
Components.classes[ASS_CONTRACTID].getService(nsIAppShellService);
w = ass.getHiddenDOMWindow();
w.open("chrome://chatzilla/content/chatzilla.xul?" + channel.URI.spec,
"_blank", "chrome,menubar,toolbar,resizable");
w.openDialog("chrome://chatzilla/content/chatzilla.xul?" +
channel.URI.spec, "_blank",
"chrome,menubar,toolbar,resizable");
}
}

Просмотреть файл

@ -17,9 +17,6 @@
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
*
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
* Peter Van der Beken, peter.vanderbeken@pandora.be, necko-only version
@ -83,6 +80,7 @@ CBSConnection.prototype.connect = function(host, port, bind, tcp_flag)
if (!this._outputStream)
throw ("Error getting output stream.");
this.connectDate = new Date();
this.isConnected = true;
return this.isConnected;
@ -95,7 +93,9 @@ CBSConnection.prototype.disconnect = function()
if (this.isConnected) {
this.isConnected = false;
this._inputStream.close();
this._outputStream.close();
/* .close() not implemented for output streams
this._outputStream.close();
*/
}
}
@ -169,7 +169,6 @@ if (jsenv.HAS_DOCUMENT)
function (server)
{
this._channel.asyncRead (new StreamListener (server), this, 0, -1, 0);
}
}
@ -187,8 +186,23 @@ function (request, ctxt)
StreamListener.prototype.onStopRequest =
function (request, ctxt, status, errorMsg)
{
ctxt = ctxt.wrappedJSObject;
if (!ctxt)
{
dd ("*** Can't get wrappedJSObject from ctxt in " +
"StreamListener.onDataAvailable ***");
return;
}
ctxt.isConnected = false;
dd ("onStopRequest: " + request + ", " + ctxt + ", " + status + ", " +
errorMsg);
var ev = new CEvent ("server", "disconnect", this.server,
"onDisconnect");
this.server.parent.eventPump.addEvent (ev);
}
StreamListener.prototype.onDataAvailable =

Просмотреть файл

@ -191,7 +191,7 @@ function ep_routeevent (e)
catch (ex)
{
dd ("Error routing event: " + ex + " in " +
e.destMethod);
e.destMethod + "\n" + dumpObjectTree(ex));
}
else
destObject[e.destMethod] (e);

Просмотреть файл

@ -76,6 +76,9 @@ function event_tracer (e)
if (name)
name = "[" + name + "]";
if (e.type == "info")
data = "'" + e.msg + "'";
str = "Level " + e.level + ": '" + e.type + "', " +
e.set + name + "." + e.destMethod;
if (data)

Просмотреть файл

@ -89,6 +89,7 @@ function CIRCNetwork (name, serverList, eventPump)
this.name = name;
this.serverList = serverList;
this.eventPump = eventPump;
this.servers = new Object();
}
@ -99,7 +100,7 @@ CIRCNetwork.prototype.INITIAL_DESC = "INITIAL_DESC";
CIRCNetwork.prototype.INITIAL_CHANNEL = "#jsbot";
/* set INITIAL_CHANNEL to "" if you don't want a primary channel */
CIRCNetwork.prototype.MAX_CONNECT_ATTEMPTS = 5000;
CIRCNetwork.prototype.MAX_CONNECT_ATTEMPTS = 20;
CIRCNetwork.prototype.stayingPower = false;
CIRCNetwork.prototype.TYPE = "IRCNetwork";
@ -108,6 +109,8 @@ CIRCNetwork.prototype.connect =
function net_conenct(pass)
{
this.connectAttempt = 0;
this.nextHost = 0;
var ev = new CEvent ("network", "do-connect", this, "onDoConnect");
ev.password = pass;
this.eventPump.addEvent (ev);
@ -135,12 +138,18 @@ function net_doconnect(e)
if ((this.primServ) && (this.primServ.connection.isConnected))
return true;
var attempt = (typeof e.attempt == "undefined") ? 1 : e.attempt + 1;
var host = (typeof e.lastHost == "undefined") ? 0 : e.lastHost + 1;
this.connecting = true; /* connection is considered "made" when server
* sends a 001 message (see server.on001 */
var ev;
if (attempt > this.MAX_CONNECT_ATTEMPTS)
return false;
if (this.connectAttempt++ >= this.MAX_CONNECT_ATTEMPTS)
{
ev = new CEvent ("network", "info", this, "onInfo");
ev.msg = "Connection attempts exhausted, giving up.";
this.eventPump.addEvent (ev);
return false;
}
try
{
@ -156,21 +165,48 @@ function net_doconnect(e)
return false;
}
host = this.nextHost++;
if (host >= this.serverList.length)
{
this.nextHost = 1;
host = 0;
}
ev = new CEvent ("network", "info", this, "onInfo");
ev.msg = "Connecting to " + this.serverList[host].name + ":" +
this.serverList[host].port + ", attempt " + this.connectAttempt +
" of " + this.MAX_CONNECT_ATTEMPTS + "...";
this.eventPump.addEvent (ev);
var connected = false;
if (c.connect (this.serverList[host].name, this.serverList[host].port,
(void 0), true))
{
var ex;
ev = new CEvent ("network", "connect", this, "onConnect");
ev.server = this.primServ = new CIRCServer (this, c);
this.eventPump.addEvent (ev);
try
{
ev.server = this.primServ = new CIRCServer (this, c);
this.eventPump.addEvent (ev);
connected = true;
}
catch (ex)
{
dd ("Caught following exception creating new CIRCServer in " +
"CIRCNetwork::onDoConnect().\n" + dumpObjectTree(ex));
}
}
else
if (!connected)
{ /* connect failed, try again */
ev = new CEvent ("network", "info", this, "onInfo");
ev.msg = "Couldn't connect to " + this.serverList[host].name + ":" +
this.serverList[host].port + ", trying next server in list...";
this.eventPump.addEvent (ev);
ev = new CEvent ("network", "do-connect", this, "onDoConnect");
ev.lastHost = host;
ev.attempt = attempt;
this.eventPump.addEvent (ev);
}
@ -195,9 +231,7 @@ function net_connect (e)
CIRCNetwork.prototype.isConnected =
function net_connected (e)
{
return (this.primServ && this.primServ.connection.isConnected);
return (this.primServ && this.primServ.connection.isConnected);
}
/*
@ -205,23 +239,32 @@ function net_connected (e)
*/
function CIRCServer (parent, connection)
{
this.parent = parent;
this.connection = connection;
this.channels = new Object();
this.users = new Object();
this.sendQueue = new Array();
this.lastSend = new Date("1/1/1980");
this.sendsThisRound = 0;
this.savedLine = "";
this.lag = -1;
this.usersStable = true;
var serverName = connection.host + ":" + connection.port;
var s = parent.servers[serverName];
if (!s)
{
s = this;
s.channels = new Object();
s.users = new Object();
}
s.parent = parent;
s.connection = connection;
s.sendQueue = new Array();
s.lastSend = new Date("1/1/1980");
s.sendsThisRound = 0;
s.savedLine = "";
s.lag = -1;
s.usersStable = true;
if (typeof connection.startAsyncRead == "function")
connection.startAsyncRead(this);
connection.startAsyncRead(s);
else
this.parent.eventPump.addEvent(new CEvent ("server", "poll", this,
"onPoll"));
s.parent.eventPump.addEvent(new CEvent ("server", "poll", s,
"onPoll"));
parent.servers[serverName] = s;
return s;
}
@ -301,7 +344,7 @@ CIRCServer.prototype.getUsersLength =
function serv_chanlen()
{
var i = 0;
for (var p in this.users)
i++;
@ -431,14 +474,20 @@ CIRCServer.prototype.onDisconnect =
function serv_disconnect(e)
{
if ((this.parent.primServ == this) && (this.parent.stayingPower))
{ /* fell off primary server, reconnect to any host in the serverList */
if ((this.parent.connecting) ||
/* fell off while connecting, try again */
(this.parent.primServ == this) && (this.parent.stayingPower))
{ /* fell off primary server, reconnect to any host in the serverList */
var ev = new CEvent ("network", "do-connect", this.parent,
"onDoConnect");
this.parent.eventPump.addEvent (ev);
}
}
return true;
e.server = this;
e.set = "network";
e.destObject = this.parent;
return true;
}
@ -642,10 +691,18 @@ function serv_onParsedData(e)
if (typeof this[e.destMethod] == "function")
e.destObject = this;
else if (typeof this["onUnknown"] == "function")
e.destMethod = "onUnknown";
else if (typeof this.parent[e.destMethod] == "function")
{
e.set = "network";
e.destObject = this.parent;
}
else
{
e.set = "network";
e.destObject = this.parent;
e.destMethod = "onUnknown";
}
return true;
@ -672,6 +729,8 @@ function serv_topic (e)
CIRCServer.prototype.on001 =
function serv_001 (e)
{
this.parent.connectAttempt = 0;
this.parent.connecting = false;
/* servers wont send a nick change notification if user was forced
* to change nick while logging in (eg. nick already in use.) We need
@ -731,7 +790,10 @@ function serv_353 (e)
e.channel = new CIRCChannel (this, e.params[3]);
if (e.channel.usersStable)
{
e.channel.users = new Object();
e.channel.usersStable = false;
}
e.destObject = e.channel;
e.set = "channel";
@ -1029,28 +1091,38 @@ function serv_nick (e)
var newKey = newNick.toLowerCase();
var oldKey = e.user.nick;
renameProperty (e.server.users, oldKey, newKey);
renameProperty (this.users, oldKey, newKey);
e.oldNick = e.user.properNick;
e.user.changeNick(newNick);
for (var c in e.server.channels)
for (var c in this.channels)
{
var cuser = e.server.channels[c].users[oldKey];
var cuser = this.channels[c].users[oldKey];
if (typeof cuser != "undefined")
{
renameProperty (e.server.channels[c].users, oldKey, newKey);
var ev = new CEvent ("channel", "nick", e.server.channels[c],
renameProperty (this.channels[c].users, oldKey, newKey);
var ev = new CEvent ("channel", "nick", this.channels[c],
"onNick");
ev.channel = e.server.channels[c];
ev.channel = this.channels[c];
ev.user = cuser;
ev.server = ev.channel.parent;
ev.server = this;
ev.oldNick = e.oldNick;
this.parent.eventPump.addEvent(ev);
}
}
if (e.user == this.me)
{
/* if it was me, tell the network about the nick change as well */
var ev = new CEvent ("network", "nick", this.parent, "onNick");
ev.user = e.user;
ev.server = this;
ev.oldNick = e.oldNick;
this.parent.eventPump.addEvent(ev);
}
e.destObject = e.user;
e.set = "user";
@ -1155,7 +1227,7 @@ function serv_pong (e)
{
if (this.lastPingSent)
this.lag = (new Date() - this.lastPingSent) / 1000;
this.lag = roundTo ((new Date() - this.lastPingSent) / 1000, 1);
delete this.lastPingSent;
@ -1407,9 +1479,17 @@ CIRCChannel.prototype.getUsersLength =
function chan_userslen ()
{
var i = 0;
this.opCount = 0;
this.voiceCount = 0;
for (var p in this.users)
{
if (this.users[p].isOp)
++this.opCount;
else if (this.users[p].isVoice)
++this.voiceCount;
i++;
}
return i;

Просмотреть файл

@ -332,10 +332,10 @@ function getPriv (priv)
function keys (o)
{
var rv = "";
var rv = new Array();
for (var p in o)
rv += rv ? ", " + p : p;
rv.push(p);
return rv;
@ -350,7 +350,90 @@ function stringTrim (s)
}
function formatDateOffset (seconds, format)
{
seconds = parseInt(seconds);
var minutes = parseInt(seconds / 60);
seconds = seconds % 60;
var hours = parseInt(minutes / 60);
minutes = minutes % 60;
var days = parseInt(hours / 24);
hours = hours % 24;
if (!format)
{
var ary = new Array();
if (days > 0)
ary.push (days + " days");
if (hours > 0)
ary.push (hours + " hours");
if (minutes > 0)
ary.push (minutes + " minutes");
if (seconds > 0)
ary.push (seconds + " seconds");
format = ary.join(", ");
}
else
{
format = format.replace ("%d", days);
format = format.replace ("%h", hours);
format = format.replace ("%m", minutes);
format = format.replace ("%s", seconds);
}
return format;
}
function arraySpeak (ary, single, plural)
{
var rv = "";
switch (ary.length)
{
case 0:
break;
case 1:
rv = ary[0];
if (single)
rv += " " + single;
break;
case 2:
rv = ary[0] + " and " + ary[1];
if (plural)
rv += " " + plural;
break;
default:
for (var i = 0; i < ary.length - 1; ++i)
rv += ary[i] + ", ";
rv += "and " + ary[ary.length - 1];
if (plural)
rv += " " + plural;
break;
}
return rv;
}
function arrayContains (ary, elem)
{
return (arrayIndexOf (ary, elem) != -1);
}
function arrayIndexOf (ary, elem)
{
for (var i in ary)
if (ary[i] == elem)
return i;
return -1;
}
function arrayInsertAt (ary, i, o)
{
@ -399,20 +482,60 @@ function abbreviateWord (str, length)
return left + "..." + right;
}
function hyphenateWord (str, length, hyphen)
/*
* Inserts the string |hyphen| into string |str| every |pos| characters.
* If there are any wordbreaking characters in |str| within -/+5 characters of
* of a |pos| then the hyphen is inserted there instead, in order to produce a
* "cleaner" break.
*/
function hyphenateWord (str, pos, hyphen)
{
if (str.length <= pos)
return str;
if (typeof hyphen == "undefined")
hyphen = " ";
if (str.length <= length)
return str;
var left = str.substr (0, (length));
var right = hyphenateWord(str.substr (length), length, hyphen);
/* search for a nice place to break the word, fuzzfactor of +/-5, centered
* around |pos| */
var splitPos =
str.substring(pos - 5, pos + 5).search(/[^A-Za-z0-9]/);
splitPos = (splitPos != -1) ? pos - 4 + splitPos : pos;
var left = str.substr (0, splitPos);
var right = hyphenateWord(str.substr (splitPos), pos, hyphen);
return left + hyphen + right;
}
/*
* Like hyphenateWord, except individual chunks of the word are returned as
* elements of an array.
*/
function splitLongWord (str, pos)
{
if (str.length <= pos)
return [str];
var ary = new Array();
var right = str;
while (right.length > pos)
{
/* search for a nice place to break the word, fuzzfactor of +/-5,
* centered around |pos| */
var splitPos =
right.substring(pos - 5, pos + 5).search(/[^A-Za-z0-9]/);
splitPos = (splitPos != -1) ? pos - 4 + splitPos : pos;
ary.push(right.substr (0, splitPos));
right = right.substr (splitPos);
}
ary.push (right);
return ary;
}
function getRandomElement (ary)
{
var i = parseInt (Math.random() * ary.length)
@ -425,7 +548,7 @@ function getRandomElement (ary)
function roundTo (num, prec)
{
return parseInt (( Math.round(num) * Math.pow (10, prec))) /
return parseInt ( Math.round(num * Math.pow (10, prec))) /
Math.pow (10, prec);
}

Просмотреть файл

@ -1,30 +1,27 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is JSIRC Test Client #3
The Initial Developer of the Original Code is New Dimensions Consulting,
Inc. Portions created by New Dimensions Consulting, Inc. are
Copyright (C) 1999 New Dimenstions Consulting, Inc. All
Rights Reserved.
Contributor(s):
Contributor(s):
Robert Ginda, rginda@ndcico.com, original author
Josh Soref, timeless@mac.com, international support
-->
- The contents of this file are subject to the Mozilla Public
- License Version 1.1 (the "License"); you may not use this file
- except in compliance with the License. You may obtain a copy of
- the License at http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS
- IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- implied. See the License for the specific language governing
- rights and limitations under the License.
-
- The Original Code is JSIRC Test Client #3
-
- The Initial Developer of the Original Code is New Dimensions Consulting,
- Inc. Portions created by New Dimensions Consulting, Inc. are
- Copyright (C) 1999 New Dimenstions Consulting, Inc. All
- Rights Reserved.
-
- Contributor(s):
- Robert Ginda, rginda@ndcico.com, original author
- Josh Soref, timeless@mac.com, international support
-->
<!DOCTYPE window SYSTEM "chrome://chatzilla/locale/chatzilla.dtd">
@ -54,7 +51,15 @@
<script src="chrome://chatzilla/content/handlers.js"/>
<script src="chrome://chatzilla/content/rdf.js"/>
<broadcasterset id="broadcasterset"/>
<broadcasterset id="broadcasterset">
<broadcaster id="cmd_close" oncommand="window.close();"/>
<broadcaster id="cmd_quit"/>
</broadcasterset>
<keyset id="keyset">
<key id="key_close"/>
<key id="key_quit"/>
</keyset>
<popupset>
<popup id="userlistPopup" oncommand="onUserListPopupClick(event)">
@ -77,54 +82,40 @@
<toolbox>
<menubar id="main-menubar" persist="collapsed">
<menu value="Options">
<menupopup>
<menuitem id="menu-view-toolbar" value="Show Toolbar"
type="checkbox" oncommand="onToggleVisibility('toolbar');"/>
<menuitem id="menu-view-info" value="Show Userlist"
type="checkbox" oncommand="onToggleVisibility('info');"/>
<menuitem id="menu-view-status" value="Show Statusbar"
type="checkbox" oncommand="onToggleVisibility('status');"/>
<menuseparator/>
<menuitem id="menu-viewicons" value="LEDs in View Buttons"
type="checkbox" oncommand="onToggleToolbarIcons();"/>
<menuitem id="menu-munger" value="Enable Smileys"
oncommand="onToggleMunger()" type="checkbox"/>
<menuseparator/>
<menuitem id="menu-dmessages" value="Debug Messages"
oncommand="onToggleTraceHook()" type="checkbox"/>
<menuseparator/>
<menuitem id="menu-settings-save-now" value="Save Settings Now"
oncommand="writeIRCPrefs()"/>
<menuitem id="menu-settings-autosave" value="Save Settings On Exit"
oncommand="onToggleSaveOnExit()" type="checkbox"/>
<!--
<menuitem value="Logging..." enabled="false"
oncommand="onNotImplemented();"/>
<menu value="Style">
<menu id="menu_File">
<menupopup id="menu_FilePopup">
<menu value="Options">
<menupopup>
<menuitem value="Default"
oncommand="onDoStyleChange('output-default.css')"/>
<menuitem value="Marble"
oncommand="onDoStyleChange('output-marble.css')"/>
<menuitem value="Loud"
oncommand="onDoStyleChange('output-loud.css')"/>
<menuseparator/>
<menuitem value="Other..."
oncommand="onDoStyleChange('other')"/>
<menuitem id="menu-view-toolbar" value="Show Toolbar"
type="checkbox" oncommand="onToggleVisibility('toolbar');"/>
<menuitem id="menu-view-info" value="Show Userlist"
type="checkbox" oncommand="onToggleVisibility('info');"/>
<menuitem id="menu-view-status" value="Show Statusbar"
type="checkbox" oncommand="onToggleVisibility('status');"/>
<menuseparator/>
<menuitem id="menu-munger" value="Enable Smileys"
oncommand="onToggleMunger()" type="checkbox"/>
<menuseparator/>
<menuitem id="menu-dmessages" value="Debug Messages"
oncommand="onToggleTraceHook()" type="checkbox"/>
<menuseparator/>
<menuitem id="menu-settings-save-now" value="Save Settings Now"
oncommand="writeIRCPrefs()"/>
<menuitem id="menu-settings-autosave" value="Save Settings On Exit"
oncommand="onToggleSaveOnExit()" type="checkbox"/>
</menupopup>
</menu>
-->
<menuseparator/>
<menuitem id="menu_close"/>
</menupopup>
</menu>
<menu value="View">
@ -141,140 +132,173 @@
<menu id="tasksMenu"/>
</menubar>
<toolbar id="views-tbar" class="toolbar-primary chromeclass-toolbar"
persist="collapsed">
<box id="views-tbar-inner"/>
</toolbar>
</toolbox>
<box id="outer-box" align="vertical" flex="1">
<box id="inner-box" align="horizontal" flex="1">
<box id="user-list-box" flex="30%" persist="collapsed">
<tree id="user-list" container="true" datasources="rdf:null"
style="width:0px" flex="1"
containment="http://home.netscape.com/NC-irc#chanuser"
multiple="true"
context="userlistPopup">
<vbox id="outer-box" flex="1">
<vbox id="upper-box" flex="1">
<hbox id="tabpanel-contents-box" flex="1">
<vbox id="user-list-box" flex="1" width="20%" persist="collapsed width">
<tree id="user-list" container="true" datasources="rdf:null" flex="1"
containment="http://home.netscape.com/NC-irc#chanuser"
multiple="true" context="userlistPopup">
<template>
<treechildren flex="1">
<treeitem uri="...">
<treerow>
<treecell>
<image class="op-image"
state="rdf:http://home.netscape.com/NC-irc#op"/>
</treecell>
<treecell>
<image class="voice-image"
state="rdf:http://home.netscape.com/NC-irc#voice"/>
</treecell>
<treecell>
<text value="rdf:http://home.netscape.com/NC-irc#nick"/>
</treecell>
<template>
<treechildren flex="1">
<treeitem uri="..." flex="1">
<treerow crop="right">
<treecell>
<image class="op-image"
state="rdf:http://home.netscape.com/NC-irc#op"/>
</treecell>
<treecell>
<image class="voice-image"
state="rdf:http://home.netscape.com/NC-irc#voice"/>
</treecell>
<treecell flex="1">
<text value="rdf:http://home.netscape.com/NC-irc#nick"
flex="1" crop="right"/>
</treecell>
</treerow>
</treeitem>
</treechildren>
</template>
<treecolgroup flex="1">
<treecol
resource="http://home.netscape.com/NC-irc#op" wwidth="15"/>
<splitter class="tree-splitter"/>
<treecol
resource="http://home.netscape.com/NC-irc#voice" wwidth="15"/>
<splitter class="tree-splitter"/>
<treecol flex="1"
resource="http://home.netscape.com/NC-irc#nick"/>
</treecolgroup>
<treehead>
<treerow crop="right">
<treecell id="usercol-op"
resource="http://home.netscape.com/NC-irc#op"
class="treecell-header sortDirectionIndicator" value="O"
onclick="return onSortCol('usercol-op');"/>
<treecell id="usercol-voice"
resource="http://home.netscape.com/NC-irc#voice"
class="treecell-header sortDirectionIndicator" value="V"
onclick="return onSortCol('usercol-voice');"/>
<treecell id="usercol-nick"
resource="http://home.netscape.com/NC-irc#nick"
class="treecell-header sortDirectionIndicator" value="Nick"
onclick="return onSortCol('usercol-nick');"/>
</treerow>
</treeitem>
</treechildren>
</template>
</treehead>
</tree>
</vbox> <!-- user-list-box -->
<treecolgroup>
<treecol
resource="http://home.netscape.com/NC-irc#op"
width="15"/>
<treecol
resource="http://home.netscape.com/NC-irc#voice"
width="15"/>
<treecol flex="1"
resource="http://home.netscape.com/NC-irc#nick"/>
</treecolgroup>
<splitter id="main-splitter" align="vertical" collapse="before"
persist="collapsed left">
<grippy/>
</splitter>
<treehead>
<treerow>
<treecell id="usercol-op"
resource="http://home.netscape.com/NC-irc#op"
class="treecell-header sortDirectionIndicator" value="O"
oncommand="return onSortCol('usercol-op');"/>
<treecell id="usercol-voice"
resource="http://home.netscape.com/NC-irc#voice"
class="treecell-header sortDirectionIndicator" value="V"
oncommand="return onSortCol('usercol-voice');"/>
<treecell id="usercol-nick"
resource="http://home.netscape.com/NC-irc#nick"
class="treecell-header sortDirectionIndicator" value="Nick"
oncommand="return onSortCol('usercol-nick');"/>
</treerow>
</treehead>
</tree>
</box>
<splitter id="main-splitter" align="vertical" collapse="before"
persist="collapsed"/>
<box align="vertical" flex="60%">
<iframe id="it-doesnt-matter-anyway" class="output-container"
type="content" src="about:blank" flex="1"/>
<textfield id="input" class="input-window"/>
</box>
</box>
</box>
<vbox flex="1" persist="width">
<iframe id="output-iframe" class="output-container" type="content"
flex="1" src="chrome://chatzilla/content/outputwindow.html"/>
</vbox>
<toolbox id="status-bar-tbox">
<toolbar id="status-bar-tbar" class="chromeclass-status" persist="collapsed">
<box class="status-box" align="horizontal" flex="20%">
<box class="status-label" align="vertical">
<text value="&network.label;"/>
<text value="&channel.label;"/>
<text value="&topicBy.label;"/>
</box>
<box class="status-data" align="vertical">
<text id="net-name" value="(one)"/>
<text id="channel-name" value="(none)"/>
<text id="channel-topicby" value="(nobody)"/>
</box>
</hbox> <!-- tabpanel-contents-box -->
<hbox id="tabstrip-box" flex="0" crop="right">
<scrollbox id="views-tbar" persist="collapsed" orient="horizontal"
flex="1" onoverflow="dd('views-tbar overflow');"
onunderflow="dd('views-tbar underflow');">
<tabbox class="tabbox-bottom" id="views-tbar-inner" flex="1"
crop="right">
<tab collapsed="true"/> <!-- dummy tab to keep the freaking xbl from
causing an exception -->
</tabbox>
</scrollbox>
</hbox>
</vbox> <!-- upper-box -->
<splitter id="input-splitter" orient="vertical" collapse="after"
collapsed="true"/>
<vbox id="input-widgets">
<textfield id="multiline-input" multiline="true" flex="1" height="100px"
class="multiline-input-widget" collapsed="true"/>
<textfield id="input" class="input-widget"/>
</vbox>
</vbox> <!-- outer-box -->
<toolbox id="status-bar-tbox" crop="right">
<toolbar id="status-bar-tbar" class="chromeclass-status" persist="collapsed"
crop="right">
<hbox class="status-box" flex="20%" crop="right">
<vbox class="status-label" crop="right">
<text value="&network.label;" crop="right"/>
<text value="&channel.label;" crop="right"/>
<text value="&topicBy.label;" crop="right"/>
</vbox>
<vbox class="status-data" crop="right">
<text id="net-name" value="(one)" crop="right"/>
<text id="channel-name" value="(none)" crop="right"/>
<text id="channel-topicby" value="(nobody)" crop="right"/>
</vbox>
<spring flex="20%"/>
<box class="status-label" align="vertical">
<text value="&server.label;"/>
<text value="&mode.label;"/>
<text value="&topic.label;"/>
</box>
<box align="vertical" flex="80%">
<box align="horizontal" flex="1">
<box class="status-data" align="vertical">
<text id="server-name" value="(none)"/>
<text id="channel-mode" value="(none)"/>
</box>
<vbox class="status-label" crop="right">
<text value="&server.label;" crop="right"/>
<text value="&mode.label;" crop="right"/>
<text value="&topic.label;" crop="right"/>
</vbox>
<vbox flex="80%" crop="right">
<hbox flex="1" crop="right">
<vbox class="status-data" crop="right">
<text id="server-name" value="(none)" crop="right"/>
<text id="channel-mode" value="(none)" crop="right"/>
</vbox>
<spring flex="100%"/>
<box class="status-label" align="vertical">
<text value="&nickname.label;"/>
<text value="&users.label;"/>
</box>
<box class="status-data" align="vertical">
<text id="server-nick" value="(unknown)"/>
<text id="channel-users" value="(none)"/>
</box>
<vbox class="status-label" crop="right">
<text value="&nickname.label;" crop="right"/>
<text value="&users.label;" crop="right"/>
</vbox>
<vbox class="status-data" crop="right">
<text id="server-nick" value="(unknown)" crop="right"/>
<text id="channel-users" value="(none)" crop="right"/>
</vbox>
<spring flex="100%"/>
<box class="status-label" align="vertical">
<text value="&lag.label;"/>
<text value="&limit.label;"/>
</box>
<box class="status-data" align="vertical">
<text id="server-lag" value="-1"/>
<text id="channel-limit" value="(none)"/>
</box>
<vbox class="status-label" crop="right">
<text value="&lag.label;" crop="right"/>
<text value="&limit.label;" crop="right"/>
</vbox>
<vbox class="status-data" crop="right">
<text id="server-lag" value="-1" crop="right"/>
<text id="channel-limit" value="(none)" crop="right"/>
</vbox>
<spring flex="100%"/>
<box class="status-label" align="vertical">
<text value="&lastPing.label;"/>
<text value="&key.label;"/>
</box>
<box class="status-data" align="vertical">
<text id="last-ping" value="(never)"/>
<text id="channel-key" value="(none)"/>
</box>
</box>
<box align="horizontal" flex="1">
<box class="status-data" align="vertical" flex="1">
<text id="channel-topic" value="(none)"/>
</box>
</box>
</box>
</box>
<vbox class="status-label" crop="right"
collapsed="true">
<text value="&lastPing.label;" crop="right"/>
<text value="&key.label;" crop="right"/>
</vbox>
<vbox class="status-data" crop="right"
collapsed="true">
<text id="last-ping" value="(never)" crop="right"/>
<text id="channel-key" value="(none)" crop="right"/>
</vbox>
</hbox>
<hbox flex="1" crop="right">
<vbox class="status-data" flex="1" crop="right">
<text id="channel-topic" value="(none)" crop="right"/>
</vbox>
</hbox>
</vbox>
</hbox>
</toolbar>
</toolbox>
</window>

Просмотреть файл

@ -31,182 +31,79 @@ function addCommands(commandObject)
{
commandObject.add (name, func, usage, help);
}
add ("help", "onInputHelp",
"[<command-name>]",
"Displays help on all commands matching <command-name>, if " +
"<command-name> is not given, displays help on all commands");
add ("testdisplay", "onInputTestDisplay",
"",
"Displays a sample text. Used to preview styles");
add ("network", "onInputNetwork",
"<network-name>",
"Sets the current network to <network-name>");
add ("server", "onInputServer",
"<server-hostname> [<port>] [<password>]",
"Connects to server <server-hostname> on <port>, or 6667 if " +
"<port> is not specified. Provides the password <password> if " +
"specified.");
add ("quit", "onInputQuit", "[<reason>]",
"Disconnects from the server represented by the active view when " +
"the command is executed providing the reason <reason> " +
"or the default reason if <reason> is not specified.");
add ("exit", "onInputExit", "[<reason>]",
"Disconnects from all active servers and networks, providing the " +
"reason <reason>, or the default reason if <reason> is not " +
"specified. Exits ChatZilla after disconnecting.");
add ("clear", "onInputClear", "",
"Clear the current view, discarding *all* content.");
add ("delete", "onInputDelete", "",
"Clear the current view, discarding *all* content, and drop it's " +
"icon from the toolbar.");
add ("hide", "onInputHide", "",
"Drop the current view's icon from the toolbar, but save it's " +
"contents. The icon will reappear the next time there is activity " +
"on the view.");
add ("names", "onInputNames", "",
"Toggles the visibility of the username list.");
add ("toolbar", "onInputToolbar", "",
"Toggles the visibility of the channel toolbar.");
add ("statusbar", "onInputStatusbar", "",
"Toggles the visibility of the status bar.");
add ("commands", "onInputCommands", "[<pattern>]",
"Lists all command names matching <pattern>, or all command names " +
"if pattern is not specified.");
add ("attach", "onInputAttach",
"[<network-name>] [<password>]",
"Attaches to the network specified by <network-name>, " +
"or the current network, if no network is specified. " +
"Provides the password <password> if specified.");
add ("me", "onInputMe",
"<action>",
"Performs an 'action' on the current channel.");
add ("msg", "onInputMsg",
"<user> <msg>",
"Sends a private message <msg> to the user <user>.");
add ("nick", "onInputNick",
"<nickname>",
"Changes your current nickname.");
"Provides the password <password> if specified. If you are already " +
"attached, the view for <network-name> is made current. If that " +
"view has been deleted, it is recreated.");
add ("name", "onInputName",
"<username>",
"Changes the username displayed before your hostmask if the server " +
"you're connecting to allows it. Some servers will only trust the " +
"username reply from the ident service. You must specify this " +
"*before* connecting to the network.");
add ("desc", "onInputDesc",
"<description>",
"Changes the 'ircname' line returned when someone performs a /whois " +
"on you. You must specify this *before* connecting to the network.");
add ("quote", "onInputQuote",
"<irc-command>",
"Sends a raw command to the IRC server, not a good idea if you " +
"don't know what you're doing. see IRC 1459 " +
"( http://www.irchelp.org/irchelp/rfc1459.html ) for complete " +
"details.");
add ("eval", "onInputEval",
"<script>",
"Evaluates <script> as JavaScript code. Not for the faint of heart.");
add ("ctcp", "onInputCTCP",
"<target> <code> [<params>]",
"Sends the CTCP code <code> to the target (user or channel) " +
"<target>. If <params> are specified they are sent along as well.");
add ("join", "onInputJoin",
"[#|&|+]<channel-name> [<key>]",
"Joins a the global (name starts with #), local (name starts " +
"with &), or modeless (name starts with a +) channel named " +
"<channel-name>. If no prefix is given, # is " +
"assumed. Provides the key <key> if specified.");
add ("leave", "onInputLeave",
"",
"Leaves the current channel, use /delete or /hide to force the " +
"view to go away.");
add ("part", "onInputLeave",
"",
"See /leave");
add ("zoom", "onInputZoom",
"<nick>",
"Shows only messages <nick> has sent to the channel, filtering out " +
"all others, (including yours.)");
add ("whois", "onInputWhoIs",
"<nick>",
"Displays information about the user <nick>, including 'real name', " +
"server connected to, idle time, and signon time. Note that some " +
"servers will lie about the idle time.");
add ("topic", "onInputTopic",
"[<new-topic>]",
"If <new-topic> is specified and you are a chanop, or the channel " +
"is not in 'private topic' mode (+t), the topic will be changed to " +
"<new-topic>. If <new-topic> is *not* specified, the current topic " +
"will be displayed");
/* JG: commands below jan 24 2000, update mar 15 */
add ("away", "onInputAway",
"[<reason>]",
"If <reason> is spcecified, sets you away with that message. " +
"Used without <reason>, you are marked back as no longer being away.");
add ("op", "onInputOp",
"<nick>",
"Gives operator status to <nick> on current channel. Requires " +
"operator status.");
add ("cancel", "onInputCancel", "",
"Cancels a /attach or /server command. Use /cancel when ChatZilla " +
"is repeatdly trying to attach to a network that is not responding, " +
"to tell ChatZilla to give up before the normal number of retries.");
add ("clear", "onInputClear", "",
"Clear the current view, discarding *all* content.");
add ("client", "onInputClient", "",
"Make the ``*client*'' view current. If the ``*client*'' view has " +
"been deleted, it will be recreated.");
add ("commands", "onInputCommands", "[<pattern>]",
"Lists all command names matching <pattern>, or all command names " +
"if pattern is not specified.");
add ("ctcp", "onInputCTCP",
"<target> <code> [<params>]",
"Sends the CTCP code <code> to the target (user or channel) " +
"<target>. If <params> are specified they are sent along as well.");
add ("delete", "onInputDelete", "",
"Clear the current view, discarding *all* content, and drop it's " +
"icon from the toolbar.");
add ("deop", "onInputDeop",
"<nick>",
"Removes operator status from <nick> on current channel. " +
"Requires operator status.");
add ("voice", "onInputVoice",
"<nick>",
"Gives voice status to <nick> on current channel. " +
"Requires operator status.");
add ("desc", "onInputDesc",
"<description>",
"Changes the 'ircname' line returned when someone performs a /whois " +
"on you. You must specify this *before* connecting to the network.");
add ("devoice", "onInputDevoice",
"<nick>",
"Removes voice status from <nick> on current channel. " +
"Requires operator status.");
add ("stalk", "onInputStalk",
"<text>",
"Add text to list of words for which you would like to see alerts.");
add ("unstalk", "onInputUnstalk",
"<text>",
"Remove word from list of terms for which you would like to see " +
"alerts.");
add ("disconnect", "onInputQuit", "[<reason>]",
"Disconnects from the server represented by the active view when " +
"the command is executed providing the reason <reason> " +
"or the default reason if <reason> is not specified.");
add ("echo", "onInputEcho",
"<text>",
"Displays <text> in the current view, but does not send it to " +
"the server.");
add ("eval", "onInputEval",
"<script>",
"Evaluates <script> as JavaScript code. Not for the faint of heart.");
add ("exit", "onInputExit", "[<reason>]",
"Disconnects from all active servers and networks, providing the " +
"reason <reason>, or the default reason if <reason> is not " +
"specified. Exits ChatZilla after disconnecting.");
/* FIXME: JG: not implemented yet */
/*
add ("filter", "onInputFilter",
@ -215,14 +112,174 @@ function addCommands(commandObject)
"with no parameter, the contents are restored.");
*/
add ("help", "onInputHelp",
"[<command-name>]",
"Displays help on all commands matching <command-name>, if " +
"<command-name> is not given, displays help on all commands");
add ("hide", "onInputHide", "",
"Drop the current view's icon from the toolbar, but save it's " +
"contents. The icon will reappear the next time there is activity " +
"on the view.");
add ("infobar", "onInputInfobar", "",
"Toggles the visibility of the username list.");
add ("invite", "onInputInvite",
"<nick> [<channel>]",
"Invites <nick> to <channel> or current channel if not " +
"supplied. Requires operator status if +i is set.");
add ("join", "onInputJoin",
"[#|&|+]<channel-name> [<key>]",
"Joins a the global (name starts with #), local (name starts " +
"with &), or modeless (name starts with a +) channel named " +
"<channel-name>. If no prefix is given, # is " +
"assumed. Provides the key <key> if specified.");
add ("kick", "onInputKick",
"[<channel>] <nick>",
"Kicks <nick> from <channel> or current channel if not " +
"supplied. Requires operator status.");
add ("leave", "onInputLeave",
"",
"Leaves the current channel, use /delete or /hide to force the " +
"view to go away.");
add ("list", "onInputSimpleCommand",
"[channel]",
"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.");
add ("me", "onInputMe",
"<action>",
"Performs an 'action' on the current channel.");
add ("msg", "onInputMsg",
"<user> <msg>",
"Sends a private message <msg> to the user <user>.");
add ("name", "onInputName",
"<username>",
"Changes the username displayed before your hostmask if the server " +
"you're connecting to allows it. Some servers will only trust the " +
"username reply from the ident service. You must specify this " +
"*before* connecting to the network.");
add ("names", "onInputNames", "[<channel>]",
"Lists the users in a channel.");
add ("network", "onInputNetwork",
"<network-name>",
"Sets the current network to <network-name>");
add ("networks", "onInputNetworks",
"",
"Lists all available networks as clickable links.");
add ("nick", "onInputNick",
"<nickname>",
"Changes your current nickname.");
add ("notify", "onInputNotify",
"[<nickname> [...]]",
"With no parameters, /notify shows you the online/offline status " +
"of all the users on your notify list. If one or more <nickname> " +
"parameters are supplied, the nickname(s) will be added to your " +
"notify list if they are not yet on it, or removed from it if they "+
"are.");
add ("op", "onInputOp",
"<nick>",
"Gives operator status to <nick> on current channel. Requires " +
"operator status.");
add ("part", "onInputLeave",
"",
"See /leave");
add ("query", "onInputQuery", ",<user> [<msg>]",
"Opens a one-on-one chat with <usr>. If <msg> is supplied, it is " +
"sent as the initial private message to <user>.");
add ("quit", null, "[<reason>]",
"This command has been replaced by /disconnect.");
add ("quote", "onInputQuote",
"<irc-command>",
"Sends a raw command to the IRC server, not a good idea if you " +
"don't know what you're doing. see IRC 1459 " +
"( http://www.irchelp.org/irchelp/rfc1459.html ) for complete " +
"details.");
add ("server", "onInputServer",
"<server-hostname> [<port>] [<password>]",
"Connects to server <server-hostname> on <port>, or 6667 if " +
"<port> is not specified. Provides the password <password> if " +
"specified. If you are already connected, " +
"the view for <server-hostname> is made current. If that view " +
"has been deleted, it is recreated.");
add ("stalk", "onInputStalk",
"<text>",
"Add text to list of words for which you would like to see alerts." +
"Whenever a person with a nickname macthing <text> speaks, or " +
"someone says a phrase containing <text>, your " +
"ChatZilla window will become active (on some operating systems) " +
"and it's taskbar icon will flash (on some operating systems.)");
add ("status", "onInputStatus", "",
"Shows status information for the current view.");
add ("statusbar", "onInputStatusbar", "",
"Toggles the visibility of the status bar.");
add ("testdisplay", "onInputTestDisplay",
"",
"Displays a sample text. Used to preview styles");
add ("topic", "onInputTopic",
"[<new-topic>]",
"If <new-topic> is specified and you are a chanop, or the channel " +
"is not in 'private topic' mode (+t), the topic will be changed to " +
"<new-topic>. If <new-topic> is *not* specified, the current topic " +
"will be displayed");
add ("toolbar", "onInputToolbar", "",
"Toggles the visibility of the channel toolbar.");
add ("unstalk", "onInputUnstalk",
"<text>",
"Remove word from list of terms for which you would like to see " +
"alerts.");
add ("voice", "onInputVoice",
"<nick>",
"Gives voice status to <nick> on current channel. " +
"Requires operator status.");
add ("who", "onInputSimpleCommand",
"<pattern>",
"List users who have name, host, or description information matching" +
" <pattern>.");
add ("whois", "onInputWhoIs",
"<nick>",
"Displays information about the user <nick>, including 'real name', " +
"server connected to, idle time, and signon time. Note that some " +
"servers will lie about the idle time.");
/*
add ("zoom", "onInputZoom",
"<nick>",
"Shows only messages <nick> has sent to the channel, filtering out " +
"all others, (including yours.)");
*/
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -43,8 +43,6 @@
* | semicolon seperated (see the /stalk command)
* +- deleteOnPart (Boolean) Delete channel window automatically after a /part
* |
* +- toolbar
* | +- icons (Boolean) display icons in toolbar buttons
* +- notify
* | +- aggressive (Boolean) flash trayicon/ bring window to top when
* | your nickname is mentioned.
@ -109,9 +107,6 @@ function readIRCPrefs (rootNode)
client.smileyText =
getBoolPref (pref, rootNode + "munger.smileyText", false);
client.ICONS_IN_TOOLBAR =
getBoolPref (pref, rootNode + "toolbar.icons", false);
client.FLASH_WINDOW =
getBoolPref (pref, rootNode + "notify.aggressive", true);
@ -140,7 +135,7 @@ function readIRCPrefs (rootNode)
CIRCChanUser.prototype.MAX_MESSAGES);
var h = client.eventPump.getHook ("event-tracer");
h.enabled =
h.enabled = client.debugMode =
getBoolPref (pref, rootNode + "debug.tracer", h.enabled);
}
@ -170,7 +165,6 @@ function writeIRCPrefs (rootNode)
client.stalkingVictims.join ("; "));
pref.SetBoolPref (rootNode + "munger", client.munger.enabled);
pref.SetBoolPref (rootNode + "munger.smileyText", client.smileyText);
pref.SetBoolPref (rootNode + "toolbar.icons", client.ICONS_IN_TOOLBAR);
pref.SetBoolPref (rootNode + "notify.aggressive", client.FLASH_WINDOW);
var h = client.eventPump.getHook ("event-tracer");

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -10,16 +10,13 @@
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is JSIRC Test Client #3
* The Original Code is ChatZilla
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
*
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*/
@ -68,7 +65,7 @@ function mng_delrule (name)
}
CMunger.prototype.munge =
function mng_munge (text, containerTag, eventDetails)
function mng_munge (text, containerTag, data)
{
var entry;
var ary;
@ -87,7 +84,7 @@ function mng_munge (text, containerTag, eventDetails)
var rval;
rval = this.entries[entry].lambdaMatch(text, containerTag,
eventDetails,
data,
this.entries[entry]);
if (rval)
ary = [(void 0), rval];
@ -104,31 +101,40 @@ function mng_munge (text, containerTag, eventDetails)
if (typeof this.entries[entry].lambdaReplace == "function")
{
this.munge (text.substr(0,startPos), containerTag,
eventDetails);
data);
this.entries[entry].lambdaReplace (ary[1], containerTag,
eventDetails,
data,
this.entries[entry]);
this.munge (text.substr (startPos + ary[1].length,
text.length), containerTag,
eventDetails);
data);
return containerTag;
}
else
{
this.munge (text.substr(0,startPos), containerTag,
eventDetails);
data);
var subTag = document.createElementNS
("http://www.w3.org/1999/xhtml",
this.entries[entry].tagName);
subTag.setAttribute ("class", this.entries[entry].className);
subTag.appendChild (document.createTextNode (ary[1]));
subTag.setAttribute ("class",
this.entries[entry].className);
var wordParts = splitLongWord (ary[1],
client.MAX_WORD_DISPLAY);
for (var i in wordParts)
{
subTag.appendChild (document.createTextNode (wordParts[i]));
var img = document.createElementNS ("http://www.w3.org/1999/xhtml",
"html:img");
subTag.appendChild (img);
}
containerTag.appendChild (subTag);
this.munge (text.substr (startPos + ary[1].length,
text.length), containerTag,
eventDetails);
text.length), containerTag, data);
return containerTag;
}

Просмотреть файл

@ -34,76 +34,29 @@ window {
}
#tabpanel-contents-box {
margin: 3px;
}
#outer-box {
margin: 5px;
}
#main-splitter {
#input-widget,
#input-widget-multiline {
border: thin silver inset;
}
#views-tbar, #views-tbox {
height: 0px;
}
.activity-button-image {
.view-button {
color: black;
background: lightgrey;
}
.activity-button-image[state="normal"] {
list-style-image: url(chrome://chatzilla/skin/images/view-normal.gif);
.view-button[state="activity"] {
color: green;
}
.activity-button-image[state="activity"] {
list-style-image: url(chrome://chatzilla/skin/images/view-activity.gif);
}
.activity-button-image[state="current"] {
list-style-image: url(chrome://chatzilla/skin/images/view-current.gif);
}
.activity-button-image[state="attention"] {
list-style-image: url(chrome://chatzilla/skin/images/view-attention.gif);
}
.activity-button-text {
color: black;
background: lightgrey;
}
.activity-button-text[state="normal"] {
}
.activity-button-text[state="activity"] {
color: darkgreen;
}
.activity-button-text[state="current"] {
color: darkcyan;
}
.activity-button-text[state="attention"] {
.view-button[state="attention"] {
color: red;
}
.status-box {
@ -129,17 +82,9 @@ window {
}
/* Activity indicator buttons */
.activity-button {
font-weight: bold;
}
.output-container {
border: thin silver inset;
width: 100%;
}
@ -167,5 +112,4 @@ window {
list-style-image: url(chrome://chatzilla/skin/images/isnt-voice.gif)
}
<
}

Двоичные данные
extensions/irc/xul/skin/images/face-angry.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 113 B

После

Ширина:  |  Высота:  |  Размер: 150 B

Двоичные данные
extensions/irc/xul/skin/images/face-cry.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 114 B

После

Ширина:  |  Высота:  |  Размер: 153 B

Двоичные данные
extensions/irc/xul/skin/images/face-frown.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 113 B

После

Ширина:  |  Высота:  |  Размер: 151 B

Двоичные данные
extensions/irc/xul/skin/images/face-screw.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 112 B

После

Ширина:  |  Высота:  |  Размер: 150 B

Двоичные данные
extensions/irc/xul/skin/images/face-smile.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 112 B

После

Ширина:  |  Высота:  |  Размер: 150 B

Двоичные данные
extensions/irc/xul/skin/images/face-surprise.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 116 B

После

Ширина:  |  Высота:  |  Размер: 151 B

Двоичные данные
extensions/irc/xul/skin/images/face-tongue.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 112 B

После

Ширина:  |  Высота:  |  Размер: 151 B

Двоичные данные
extensions/irc/xul/skin/images/face-wink.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 115 B

После

Ширина:  |  Высота:  |  Размер: 155 B

Просмотреть файл

@ -9,307 +9,407 @@
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla JSIRC Library.
* The Original Code is Chatzilla.
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimenstions Consulting, Inc. All
* Rights Reserved.
*
* Contributor(s):
*
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*
* Styles for output window, See test3.css for UI styles
* Styles for output window
*
*/
body {
/*
* This file contains the CSS rules for the output window in ChatZilla.
* The output window is layed out as a table with two columns. The first
* column holds a message type or a nickname, depending on what view the
* message is contained by, and what kind of message it is. The second column
* contains the text of the message. For most message types, ChatZilla displays
* ascii-art instead of the actual code. For example, messages of type "JOIN"
* are displayed as "-->|", and most unclassified message types are displayed
* as "===". If you turn on debug messages (using the options->debug messages
* menuitem) ChatZilla will always show the actual message type. This can be
* helpful when styling a particular response from the IRC server. See the
* description of the msg-type attribute below.
*
* You can modify these styles on your local system by placing your desired
* styles in a file called chatzilla.css in your <profile>/chrome directory.
* (the file won't be there already, you have to create it.) Add the line
*
* @import url(chatzilla.css);
*
* to the to your userContent.css (also in your <profile>/chrome directory, and
* also not there unless you created it already.) End all CSS rules in your
* new chatzilla.css with !important to override any styles declared here.
* For example, on a Linux system, you would create a file called
* /home/<username>/.mozilla/<username>/chrome/userContent.css (if it
* doesn't already exist), and add the line @import url(chatzilla.css) to it.
* Next, create /home/<username>/.mozilla/<username>/chrome/chatzilla.css, and
* add the text:
*
* .msg {
* font-size: 14pt !important;
* }
*
* body.chatzilla-body {
* background: green !important;
* }
*
* Close your browser and restart. When you bring up ChatZilla, it should have
* a 14pt font and a green background.
*
* To learn how to make more useful changes to the ChatZilla output style, read
* on.
*
* All of the output in the message window is contained in an html <TABLE>.
* New messages are composed of <TR> and <TD> elements inside this <TABLE>.
* The message table and it's children have the following CSS classes assigned
* to them:
*
* + .msg-table is used as the class for the surrounding <TABLE>.
* Styles applied to this class will affect all parts of all messages.
*
* + .msg-nested-table is used as the class for the surrounding <TABLE> for
* messages sent from users with long nicknames. A new table is created, and
* nested inside a <TR colspan="2"> of the .msg-table. The rows of this
* table have their classes set as if they were direct children of the
* .msg-table. Placing messages from users with long nicknames in a nested
* table keeps the nickname column from getting too wide.
*
* + .msg is used as the class for the surrounding <TR>. This means that
* any styles applied here will affect the entire message.
*
* + .msg-type is used as the class for the <TD> surrounding the message type
* portion of messages. Styles applied here will only affect message
* types. ie. "-->|", or "[HELP]".
*
* + .msg-user is used as the class for the <TD> surrounding the nickname
* portion of messages. ChatZilla makes use of the :before and :after
* pseudoclasses to decorate nicknames with different characters depending
* on their message type. For example, when a user performs a /me, their
* nickname may be surrounded by asterisks.
*
* + .msg-data is used as the class for the <TD> surrounding the actual text
* of the message.
*
* In addition to CSS class properties, portions of a message may have one
* or mode of the following attributes set:
*
* + view-type is the type of view the message is contained in. The types
* are:
* "IRCClient" for the *client* view
* "IRCNetwork" for network and server views
* "IRCChannel" for channel views
* "IRCUser" for query views
*
* + msg-type is the message type described above. There are too many types
* to list here. Turn on debug messages to force message types to print
* in the left column of the output.
*
* + msg-user is the nickname (in lowercase) of the nickname who sent the
* message. If you sent the message, msg-user will be set to "ME!", so
* that you can style your messages regardless of your nickname.
*
* + msg-dest is the name of the object that the message is directed to. It
* could be a channel name, or a nickname (both in lowercase.)
*
* + dest-type is the type of object the message is directed to. The types
* are:
* "IRCChannel" for messages sent to a channel.
* "IRCUser" for messages sent directly to another user, including
* private messages that appear in a network or channel view (when
* a dedicated query view does not exist.)
*
* + mark is either the text "even" or "odd". When the first user speaks on
* a channel, that message is marked as "even". Messages will continue to
* be marked "even" until a different user speaks, when the mark switches
* to "odd". Each view maintains it's own mark state. An example of how
* ChatZilla marks messages would be:
*
* EVEN: <moe> this deep fat fry-o-later is great.
* EVEN: <moe> It'll deep fat fry a whole buffalo in 30 seconds.
* ODD: <homer> but I'm hungry *now*!
*
* + important is either the text "true", or it is not set at all. If
* important is true, then the message triggered ChatZilla /stalk function.
* This occurs when someone with a nickname matching a pattern in your
* /stalk list speaks, when someone says a word that matches a pattern in
* your /stalk list, or when someone says your nickname.
*
*
*/
margin: 0px 0px 0px 0px;
/* background: url(chrome://chatzilla/skin/images/blue_rock.gif);*/
/******************************************************************************
* basic classes *
******************************************************************************/
body.chatzilla-body { /* The topmost container in the ChatZilla */
margin: 0px 0px 0px 0px; /* output window. */
background: black;
}
a {
color: cyan;
.spacer-image { /* this image is inserted between the */
border: none; /* characters in long words, in order to */
height: 0px; /* break them up to allow word wrapping */
width: 0px;
}
.bold {
font-weight: bold;
.smiley-image { /* smiley face img tag */
margin-left: 3px;
margin-right: 3px;
}
.italic {
font-style: italic;
/* links */
a.chatzilla-link {
color: #7083ff;
text-decoration: none;
}
.underline {
/* link hover effect */
a.chatzilla-link:hover {
text-decoration: underline;
}
.strikethrough {
text-decoration: line-through;
}
.teletype {
font-family: monospace;
}
.smallcap {
font-variant: small-caps;
}
.rheet {
font-size: 14pt;
/* basic styles */
.chatzilla-bold {
font-weight: bold;
color: magenta;
}
/* output from a chat session (contains msgs) */
.chat-view {
vertical-align: text-bottom;
.chatzilla-italic {
font-style: italic;
}
/* common container for all portions of a message
* (contains msg-*s) */
.msg {
.chatzilla-underline {
text-decoration: underline;
}
.chatzilla-strikethrough {
text-decoration: line-through;
}
.chatzilla-teletype {
font-family: monospace;
}
.chatzilla-smallcap {
font-variant: small-caps;
}
.chatzilla-rheet {
font-weight: bold;
color: magenta !important;
}
/******************************************************************************
* message class base definitions *
******************************************************************************/
.msg-table { /* <TABLE> containing all of the */
width: 100%; /* messages. */
}
.msg-nested-table { /* <TABLE> nested inside */
width: 100%; /* .msg-table for users with long */
margin: 0px 0px 0px 0px; /* nicknames. */
padding: 0px 0px 0px 0px;
}
.msg { /* .msg = a single message in the */
width: 100%; /* output window */
font-size: 10pt;
font-family: sans-serif;
}
.msg[user="!ME"] {
background: lightgrey;
}
/* message data in output window */
.msg-data {
padding: 2px;
color: white;
}
.msg-data[msgtype="311"] {
border: none;
border-top: 1 cyan solid;
border-right: 1 cyan solid;
}
.msg-data[msgtype="319"],
.msg-data[msgtype="312"],
.msg-data[msgtype="317"] {
margin-top: 0px;
border: none;
border-right: 1 cyan solid;
}
.msg-data[msgtype="318"] {
border: none;
border-right: 1 cyan solid;
border-bottom: 1 cyan solid;
margin-top: 0px;
}
/* message data in output window */
.msg-data[user="!ME"]{
}
.msg-data[mark="odd"]{
color: lightgrey;
}
.msg-data[directedToMe="true"] {
color: orange;
}
.msg-data[msgtype="EVAL"] {
font-family: monospace;
}
.msg-data[msgtype="JOIN"],
.msg-data[msgtype="PART"] {
width: 100%;
font-variant: small-caps;
color: lightblue;
}
.msg-data[msgtype="HELLO"] {
border: 1 white solid;
color: yellow;
}
.msg-data[msgtype="ERROR"] {
background: red;
color: white;
}
.msg-data[msgtype="USAGE"] {
font-style: italic;
color: white;
}
.msg-data[msgtype="HELP"] {
font-weight: normal;
}
.msg-data[msgtype="ACTION"] {
color: #6ac9ee;
}
.msg-data[msgtype="NICK"] {
color: #96fa94;
}
.msg-data[msgtype="NOTICE"],
.msg-data[msgtype="MODE"] {
color: yellow;
}
.msg-data[msgtype="KICK"] {
background: orange;
color: yellow;
}
.msg-data[msgtype="QUIT"] {
background: #222222;
color: brown;
}
/* nickname field in output */
.msg-user {
text-align: center;
vertical-align: middle;
color: white;
font-weight: bold;
border: 1 white solid;
}
.msg-user[user="!ME"] {
color : yellow;
}
.msg-user[msgtype="ACTION"] {
font-style: italic;
}
.msg-user[msgtype="PRIVMSG"],
.msg-user[msgtype="ACTION"] {
border: none;
padding-right: 2px;
text-align: right;
vertical-align: middle;
font-weight: bold;
}
/* Message type indicator in output window */
.msg-type {
.msg-type { /* .msg-type = message type */
font-variant: small-caps; /* indicator */
font-size: 9pt;
text-align: center;
vertical-align: middle;
color: silver;
border: 1 white solid;
}
.msg-user { /* msg-user = nickname portion of */
text-align: right; /* a message (channel and query */
vertical-align: middle; /* views) */
color: white;
}
.msg-data { /* .msg-data = the text portion */
padding: 1px 1px 1px 3px; /* of a message */
color: white;
width: 100%;
}
/******************************************************************************
* message class specific definitions *
******************************************************************************/
.msg-data[mark="even"] { /* use even/odd marks to create a */
color: #FFFFFF; /* subtle brightness change when */
} /* the speaker changes. */
.msg-data[mark="odd"] {
color: lightgrey;
}
/* msg-user is the nickname of the person who spoke, or "ME!" if you said it.
* msg-type is the type of the message, taken from the irc message. If you
* turn on debug messages (options->debug messages), the msg-types will be
* displayed to the left of the messages for all messages except:
* PRIVMSG: when a user sends you, or a channel you are on a message.
* ACTION: when a user performs a /me.
* NOTIFY: when a server or user sends you a notification.
*/
.msg-data[msg-user="|"], /* messages from common "bulk */
.msg-data[msg-user="||"], /* paste" nicks */
.msg-data[msg-user="|||"],
.msg-data[msg-type="372"], /* MOTD */
.msg-data[msg-type="EVAL-IN"], /* /eval results */
.msg-data[msg-type="EVAL-OUT"] {
font-size: 9pt;
whitespace: pre; /* XXX why doesn't this take? */
font-family: monospace;
}
.msg-data[msg-type="JOIN"],
.msg-data[msg-type="PART"] {
color: lightblue;
}
.msg-data[msg-type="HELLO"] {
color: yellow;
}
.msg-data[msg-type="ERROR"] {
background: red;
color: white;
}
.msg-data[msg-type="USAGE"] {
font-style: italic;
color: white;
}
.msg-data[msg-type="HELP"] {
font-weight: normal;
}
.msg-user[msg-type="ACTION"] {
font-style: italic;
}
.msg-data[msg-type="ACTION"] {
color: #6ac9ee;
}
.msg-data[msg-type="NICK"] {
color: #96fa94;
}
.msg-data[msg-type="NOTICE"],
.msg-data[msg-type="MODE"] {
color: #6afc73;
}
.msg-data[msg-type="KICK"] {
color: #ff5700;
}
.msg-data[msg-type="QUIT"] {
color: #f7b183;
}
/* important="true" means that the message has text from your /stalk list in
* it, has your nickname in it, or was spoken by someone in your /stalk list.
*/
.msg[important="true"] {
background: #333333;
}
.msg-user[important="true"] {
font-weight: bold;
}
.msg-type[msgtype="311"] {
border: none;
border-top: 1 cyan solid;
border-left: 1 cyan solid;
/******************************************************************************
* nickname decorations *
******************************************************************************/
/* :before and :after pseudoclasses form the decorations around nicknames */
.msg-user:before {
color: blue;
content: "<";
}
.msg-user:after {
color: blue;
content: ">";
}
.msg-user[important="true"]:before {
font-weight: bold;
}
.msg-user[important="true"]:after {
font-weight: bold;
}
.msg-user[msg-user="ME!"]:before {
color: #6afc73;
content: "<";
}
.msg-user[msg-user="ME!"]:after {
color: #6afc73;
content: ">";
}
.msg-user[msg-type="ACTION"]:before {
color: cyan;
content: "*";
}
.msg-user[msg-type="ACTION"]:after {
color: cyan;
content: "*";
}
.msg-user[msg-type="NOTICE"]:before {
color: #6afc73;
content: "[";
}
.msg-user[msg-type="NOTICE"]:after {
color: #6afc73;
content: "]";
}
.msg-type[msgtype="319"],
.msg-type[msgtype="312"],
.msg-type[msgtype="317"] {
margin-top: 0px;
border: none;
border-left: 1 cyan solid;
/* private messages *not* in a query window */
.msg-user[dest-type="IRCUser"]:before {
color: #6afc73;
content: "to(";
}
.msg-user[dest-type="IRCUser"]:after {
color: #6afc73;
content: ")";
}
.msg-user[msg-dest="ME!"]:before {
color: magenta;
content: "from(";
}
.msg-user[msg-dest="ME!"]:after {
color: magenta;
content: ")";
}
.msg-type[msgtype="318"] {
border: none;
border-left: 1 cyan solid;
border-bottom: 1 cyan solid;
margin-top: 0px;
/* private messages in a query window */
.msg-user[view-type="IRCUser"]:before {
color: white;
content: "{";
}
.msg-type[user="!ME"] {
background: slategrey;
.msg-user[view-type="IRCUser"]:after {
color: white;
content: "}";
}
.msg-user[view-type="IRCUser"][msg-user="ME!"]:before {
color: #6afc73;
content: "{";
}
.msg-user[view-type="IRCUser"][msg-user="ME!"]:after {
color: #6afc73;
content: "}";
}