1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is ChatZilla.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
24 * Robert Ginda, <rginda@netscape.com>, original author
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 var initialized = false;
55 fields: ["container", "netcount", "version-container", "version",
62 fields: ["container", "url-anchor", "status", "lag"],
68 fields: ["container", "url-anchor", "modestr", "usercount",
69 "topicnodes", "topicinput"],
75 fields: ["container", "url-anchor", "serverstr", "title",
82 fields: ["container", "remotestr", "title"],
88 fields: ["container", "file", "progress", "progressbar"],
93 var initOutputWindow = stock_initOutputWindow;
95 function stock_initOutputWindow(newClient, newView, newClickHandler)
99 /* it's better if we wait a half a second before poking at these
101 setHeaderState(view.prefs["displayHeader"]);
103 var div = document.getElementById("messages-outer");
104 div.removeAttribute("hidden");
105 window.scrollTo(0, window.document.height);
110 clickHandler = newClickHandler;
111 mainWindow = client.mainWindow;
113 client.messageManager.importBundle(client.defaultBundle, window);
115 getMsg = mainWindow.getMsg;
116 getObjectDetails = mainWindow.getObjectDetails;
119 // Wheee... localize stuff!
120 //var nodes = document.getElementsByAttribute("localize", "*");
121 var nodes = document.getElementsByTagName("*");
122 for (var i = 0; i < nodes.length; i++)
124 if (nodes[i].hasAttribute("localize"))
126 var msg = nodes[i].getAttribute("localize");
127 msg = getMsg("msg." + msg);
128 nodes[i].appendChild(document.createTextNode(msg));
132 changeCSS(view.prefs["motif.current"]);
133 updateMotifSettings();
135 var output = document.getElementById("output");
136 output.appendChild(adoptNode(view.messages));
138 if (view.TYPE in headers)
140 header = cacheNodes(headers[view.TYPE].prefix,
141 headers[view.TYPE].fields);
142 // Turn off accessibility announcements: they're useless as all these
143 // changes are in the "log" as well, normally.
144 // We're setting the attribute here instead of in the HTML to cope with
145 // custom output windows and so we set it only on the Right header
147 header["container"].setAttribute("aria-live", "off");
148 header.update = headers[view.TYPE].update;
151 var splash = document.getElementById("splash");
153 if ("unicodeName" in view)
154 name = view.unicodeName;
157 splash.appendChild(document.createTextNode(name));
159 setTimeout(initHeader, 500);
164 function onTopicNodesClick(e)
166 if (!clickHandler(e))
177 function onTopicKeypress(e)
182 var topic = header["topicinput"].value;
183 topic = mainWindow.replaceColorCodes(topic);
184 view.setTopic(topic);
185 view.dispatch("focus-input");
189 view.dispatch("focus-input");
193 client.mainWindow.onInputKeyPress(e);
197 function startTopicEdit()
199 var me = view.getUser(view.parent.me.unicodeName);
200 if (!me || (!view.mode.publicTopic && !me.isOp && !me.isHalfOp) ||
201 !header["topicinput"].hasAttribute("hidden"))
206 header["topicinput"].value = mainWindow.decodeColorCodes(view.topic);
208 header["topicnodes"].setAttribute("hidden", "true")
209 header["topicinput"].removeAttribute("hidden");
210 header["topicinput"].focus();
211 header["topicinput"].selectionStart = 0;
214 function cancelTopicEdit()
216 if (!header["topicnodes"].hasAttribute("hidden"))
219 header["topicinput"].setAttribute("hidden", "true")
220 header["topicnodes"].removeAttribute("hidden");
223 function cacheNodes(pfx, ary, nodes)
226 nodes = new Object();
228 for (var i = 0; i < ary.length; ++i)
229 nodes[ary[i]] = document.getElementById(pfx + ary[i]);
234 function changeCSS(url, id)
239 node = document.getElementById(id);
243 node = document.createElement("link");
244 node.setAttribute("id", id);
245 node.setAttribute("rel", "stylesheet");
246 node.setAttribute("type", "text/css");
247 var head = document.getElementsByTagName("head")[0];
248 head.appendChild(node);
252 if (node.getAttribute("href") == url)
256 node.setAttribute("href", url);
257 window.scrollTo(0, window.document.height);
260 function updateMotifSettings(existingTimeout)
262 // Try... catch with a repeat to cope with the style sheet not being loaded
266 existingTimeout += TIMEOUT;
267 view.motifSettings = getMotifSettings();
271 if (existingTimeout >= 30000) // Stop after trying for 30 seconds
273 if (ex.name == "NS_ERROR_DOM_INVALID_ACCESS_ERR") //not ready, try again
274 setTimeout(updateMotifSettings, TIMEOUT, existingTimeout);
275 else // something else, panic!
280 function getMotifSettings()
282 var re = new RegExp("czsettings\\.(\\w*)", "i");
283 var rules = document.getElementById("main-css").sheet.cssRules;
284 var rv = new Object();
286 // Copy any settings, which are available in the motif using the
287 // "CZSETTINGS" selector. We only store the regexp match after checking
288 // the rule type because selectorText is not defined on other rule types.
289 for (var i = 0; i < rules.length; i++)
291 if ((rules[i].type == CSSRule.STYLE_RULE) &&
292 ((ary = rules[i].selectorText.match(re)) != null))
300 function adoptNode(node)
302 return client.adoptNode(node, document);
305 function setText(field, text, checkCondition)
307 if (!header[field].firstChild)
308 header[field].appendChild(document.createTextNode(""));
310 if (typeof text != "string")
314 setAttribute(field, "condition", "red");
316 else if (checkCondition)
318 setAttribute(field, "condition", "green");
321 header[field].firstChild.data = text;
324 function setAttribute(field, name, value)
329 header[field].setAttribute(name, value);
332 function removeAttribute(field, name)
334 header[field].removeAttribute(name);
337 function hasAttribute(field, name)
339 header[field].hasAttribute(name);
342 function setHeaderState(state)
349 removeAttribute("container", "hidden");
353 setAttribute("container", "hidden");
358 function updateHeader()
360 document.title = view.getURL();
362 if (!header || hasAttribute("container", "hidden"))
365 for (var id in header)
369 if (id == "url-anchor")
371 value = view.getURL();
372 setAttribute("url-anchor", "href", value);
373 setText("url-anchor", value);
377 setText(id, view[id]);
385 function updateClient()
388 for (name in client.networks)
391 if (client.networks[name].isConnected())
395 setAttribute("version-container", "title", client.userAgent);
396 setAttribute("version-container", "condition", mainWindow.__cz_condition);
397 setText("version", mainWindow.__cz_version);
398 setText("netcount", String(n));
399 setText("connectcount", String(c));
402 function updateNetwork()
404 if (view.state == client.mainWindow.NET_CONNECTING)
406 setText("status", MSG_CONNECTING);
407 setAttribute("status","condition", "yellow");
408 removeAttribute("status", "title");
409 setText("lag", MSG_UNKNOWN);
411 else if (view.isConnected())
413 setText("status", MSG_CONNECTED);
414 setAttribute("status","condition", "green");
415 setAttribute("status", "title",
416 getMsg(MSG_CONNECT_VIA, view.primServ.unicodeName));
417 if (view.primServ.lag != -1)
418 setText("lag", getMsg(MSG_FMT_SECONDS, view.primServ.lag));
420 setText("lag", MSG_UNKNOWN);
425 setText("status", MSG_DISCONNECTED);
426 setAttribute("status","condition", "red");
427 removeAttribute("status", "title");
428 setText("lag", MSG_UNKNOWN);
432 function updateChannel()
434 header["topicnodes"].removeChild(header["topicnodes"].firstChild);
438 var str = view.mode.getModeStr();
441 setText("modestr", str);
442 setAttribute("modestr", "condition", "green");
444 setText("usercount", getMsg(MSG_FMT_USERCOUNT,
445 [view.getUsersLength(), view.opCount,
446 view.halfopCount, view.voiceCount]));
447 setAttribute("usercount", "condition", "green");
451 var data = getObjectDetails(view);
452 data.dontLogURLs = true;
453 var mailto = client.prefs["munger.mailto"];
454 client.munger.getRule(".mailto").enabled = mailto;
455 var nodes = client.munger.munge(view.topic, null, data);
456 client.munger.getRule(".mailto").enabled = false;
457 header["topicnodes"].appendChild(adoptNode(nodes));
461 setText("topicnodes", MSG_NONE);
466 setText("modestr", MSG_UNKNOWN);
467 setAttribute("modestr", "condition", "red");
468 setText("usercount", MSG_UNKNOWN);
469 setAttribute("usercount", "condition", "red");
470 setText("topicnodes", MSG_UNKNOWN);
475 function updateUser()
479 source = "<" + view.name + "@" + view.host + ">";
481 source = MSG_UNKNOWN;
483 if (view.parent.isConnected)
484 setText("serverstr", view.connectionHost, true);
486 setText("serverstr", null, true);
488 setText("title", getMsg(MSG_TITLE_USER, [view.unicodeName, source]));
490 header["descnodes"].removeChild(header["descnodes"].firstChild);
491 if (typeof view.desc != "undefined")
493 var data = getObjectDetails(view);
494 data.dontLogURLs = true;
495 var nodes = client.munger.munge(view.desc, null, data);
496 header["descnodes"].appendChild(adoptNode(nodes));
500 setText("descnodes", "");
504 function updateDCCChat()
506 if (view.state.state == 4)
507 setText("remotestr", view.remoteIP + ":" + view.port, true);
509 setText("remotestr", null, true);
511 setText("title", getMsg(MSG_TITLE_DCCCHAT, view.user.unicodeName));
514 function updateDCCFile()
516 var pcent = Math.floor(100 * view.position / view.size);
518 setText("file", view.filename);
519 setText("progress", getMsg(MSG_DCCFILE_PROGRESS,
520 [pcent, mainWindow.getSISize(view.position),
521 mainWindow.getSISize(view.size),
522 mainWindow.getSISpeed(view.speed)]));
524 setAttribute("progressbar", "width", pcent + "%");