ChatZilla 0.8 checkin. see bug 71468 for details
r=ssieb, sr=shaver
|
@ -1,174 +1,71 @@
|
|||
JavaScript IRC library, bot (runs in xpcshell), and client (runs in Mozilla.)
|
||||
|
||||
Files You'll find...
|
||||
**-------------------------------------------
|
||||
irc/bslib
|
||||
|
||||
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.
|
||||
|
||||
irc.js
|
||||
|
||||
IRC Library. Provides DOM like access to IRC. This is what your looking
|
||||
for.
|
||||
|
||||
dcc.js
|
||||
|
||||
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.
|
||||
|
||||
**-------------------------------------------
|
||||
irc/js/tests
|
||||
|
||||
Scripts to test the various libraries including...
|
||||
|
||||
test_matchobject.js
|
||||
|
||||
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.
|
||||
|
||||
ircbot.js
|
||||
|
||||
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.
|
||||
|
||||
**-------------------------------------------
|
||||
Misc. Notes...
|
||||
|
||||
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"
|
||||
Using ChatZilla
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Table Of Contents
|
||||
|
||||
Part 1: Introduction to ChatZilla.
|
||||
|
||||
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?
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Part 2: Navigating IRC with ChatZilla.
|
||||
|
||||
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.
|
||||
|
||||
2.2: Channels.
|
||||
2.2.1: Finding a channel.
|
||||
2.2.2: Joining.
|
||||
2.2.3: Modes, Topics, and Kicks.
|
||||
2.2.4: Parting.
|
||||
|
||||
2.3: Private messages.
|
||||
2.3.1: Receiving messages.
|
||||
2.3.2: Sending messages.
|
||||
2.3.3: Query windows.
|
||||
|
||||
Part 3: Scripting ChatZilla.
|
||||
|
||||
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();
|
||||
|
||||
3.2: More Scripting.
|
||||
3.2.1: External scripts.
|
||||
3.2.2: Hooking into IRC events.
|
||||
|
||||
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,10 +21,6 @@ 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-frown.gif (xul/skin/images/face-frown.gif)
|
||||
skin/modern/chatzilla/images/face-tongue.gif (xul/skin/images/face-tongue.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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
* 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();
|
||||
/* .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)
|
||||
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");
|
||||
try
|
||||
{
|
||||
ev.server = this.primServ = new CIRCServer (this, c);
|
||||
this.eventPump.addEvent (ev);
|
||||
connected = true;
|
||||
}
|
||||
else
|
||||
catch (ex)
|
||||
{
|
||||
dd ("Caught following exception creating new CIRCServer in " +
|
||||
"CIRCNetwork::onDoConnect().\n" + dumpObjectTree(ex));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -205,24 +239,33 @@ function net_connected (e)
|
|||
*/
|
||||
function CIRCServer (parent, connection)
|
||||
{
|
||||
var serverName = connection.host + ":" + connection.port;
|
||||
var s = parent.servers[serverName];
|
||||
if (!s)
|
||||
{
|
||||
s = this;
|
||||
s.channels = new Object();
|
||||
s.users = new Object();
|
||||
}
|
||||
|
||||
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;
|
||||
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,
|
||||
s.parent.eventPump.addEvent(new CEvent ("server", "poll", s,
|
||||
"onPoll"));
|
||||
|
||||
parent.servers[serverName] = s;
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
CIRCServer.prototype.MAX_LINES_PER_SEND = 5;
|
||||
|
@ -431,13 +474,19 @@ CIRCServer.prototype.onDisconnect =
|
|||
function serv_disconnect(e)
|
||||
{
|
||||
|
||||
if ((this.parent.primServ == this) && (this.parent.stayingPower))
|
||||
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);
|
||||
}
|
||||
|
||||
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,6 +350,89 @@ 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;
|
||||
/* 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]/);
|
||||
|
||||
var left = str.substr (0, (length));
|
||||
var right = hyphenateWord(str.substr (length), length, hyphen);
|
||||
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,29 +1,26 @@
|
|||
<?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,6 +82,8 @@
|
|||
|
||||
<toolbox>
|
||||
<menubar id="main-menubar" persist="collapsed">
|
||||
<menu id="menu_File">
|
||||
<menupopup id="menu_FilePopup">
|
||||
<menu value="Options">
|
||||
<menupopup>
|
||||
|
||||
|
@ -89,9 +96,6 @@
|
|||
|
||||
<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"/>
|
||||
|
||||
|
@ -107,24 +111,11 @@
|
|||
<menuitem id="menu-settings-autosave" value="Save Settings On Exit"
|
||||
oncommand="onToggleSaveOnExit()" type="checkbox"/>
|
||||
|
||||
<!--
|
||||
<menuitem value="Logging..." enabled="false"
|
||||
oncommand="onNotImplemented();"/>
|
||||
|
||||
<menu value="Style">
|
||||
<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')"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
-->
|
||||
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_close"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menu value="View">
|
||||
|
@ -141,25 +132,21 @@
|
|||
<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"
|
||||
<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">
|
||||
multiple="true" context="userlistPopup">
|
||||
|
||||
<template>
|
||||
<treechildren flex="1">
|
||||
<treeitem uri="...">
|
||||
<treerow>
|
||||
<treeitem uri="..." flex="1">
|
||||
<treerow crop="right">
|
||||
<treecell>
|
||||
<image class="op-image"
|
||||
state="rdf:http://home.netscape.com/NC-irc#op"/>
|
||||
|
@ -168,113 +155,150 @@
|
|||
<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 flex="1">
|
||||
<text value="rdf:http://home.netscape.com/NC-irc#nick"
|
||||
flex="1" crop="right"/>
|
||||
</treecell>
|
||||
</treerow>
|
||||
</treeitem>
|
||||
</treechildren>
|
||||
</template>
|
||||
|
||||
<treecolgroup>
|
||||
<treecolgroup flex="1">
|
||||
<treecol
|
||||
resource="http://home.netscape.com/NC-irc#op"
|
||||
width="15"/>
|
||||
resource="http://home.netscape.com/NC-irc#op" wwidth="15"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
resource="http://home.netscape.com/NC-irc#voice"
|
||||
width="15"/>
|
||||
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>
|
||||
<treerow crop="right">
|
||||
<treecell id="usercol-op"
|
||||
resource="http://home.netscape.com/NC-irc#op"
|
||||
class="treecell-header sortDirectionIndicator" value="O"
|
||||
oncommand="return onSortCol('usercol-op');"/>
|
||||
onclick="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');"/>
|
||||
onclick="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');"/>
|
||||
onclick="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>
|
||||
|
||||
<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>
|
||||
</tree>
|
||||
|
||||
</vbox> <!-- user-list-box -->
|
||||
|
||||
<splitter id="main-splitter" align="vertical" collapse="before"
|
||||
persist="collapsed left">
|
||||
<grippy/>
|
||||
</splitter>
|
||||
|
||||
<vbox flex="1" persist="width">
|
||||
<iframe id="output-iframe" class="output-container" type="content"
|
||||
flex="1" src="chrome://chatzilla/content/outputwindow.html"/>
|
||||
</vbox>
|
||||
|
||||
</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>
|
||||
|
|
|
@ -32,181 +32,78 @@ 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.");
|
||||
|
||||
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 */
|
||||
"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 ("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,7 +10,7 @@
|
|||
* 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
|
||||
|
@ -18,9 +18,6 @@
|
|||
* 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%;
|
||||
|
||||
}
|
||||
|
||||
|
@ -168,4 +113,3 @@ 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,7 +9,7 @@
|
|||
* 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
|
||||
|
@ -17,299 +17,399 @@
|
|||
* 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: "}";
|
||||
}
|
||||
|
||||
|
|