/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * 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 ChatZilla. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Robert Ginda, , original author * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ var initialized = false; var view; var client; var mainWindow; var clickHandler; var dd; var getMsg; var getObjectDetails; var header = null; var headers = { IRCClient: { prefix: "cli-", fields: ["container", "netcount", "version-container", "version", "connectcount"], update: updateClient }, IRCNetwork: { prefix: "net-", fields: ["container", "url-anchor", "status", "lag"], update: updateNetwork }, IRCChannel: { prefix: "ch-", fields: ["container", "url-anchor", "modestr", "usercount", "topicnodes", "topicinput"], update: updateChannel }, IRCUser: { prefix: "usr-", fields: ["container", "url-anchor", "serverstr", "title", "descnodes"], update: updateUser }, IRCDCCChat: { prefix: "dcc-chat-", fields: ["container", "remotestr", "title"], update: updateDCCChat }, IRCDCCFileTransfer: { prefix: "dcc-file-", fields: ["container", "file", "progress", "progressbar"], update: updateDCCFile } }; var initOutputWindow = stock_initOutputWindow; function stock_initOutputWindow(newClient, newView, newClickHandler) { function initHeader() { /* it's better if we wait a half a second before poking at these * dom nodes. */ setHeaderState(view.prefs["displayHeader"]); updateHeader(); var div = document.getElementById("messages-outer"); div.removeAttribute("hidden"); window.scrollTo(0, window.document.height); }; client = newClient; view = newView; clickHandler = newClickHandler; mainWindow = client.mainWindow; client.messageManager.importBundle(client.defaultBundle, window); getMsg = mainWindow.getMsg; getObjectDetails = mainWindow.getObjectDetails; dd = mainWindow.dd; // Wheee... localize stuff! //var nodes = document.getElementsByAttribute("localize", "*"); var nodes = document.getElementsByTagName("*"); for (var i = 0; i < nodes.length; i++) { if (nodes[i].hasAttribute("localize")) { var msg = nodes[i].getAttribute("localize"); msg = getMsg("msg." + msg); nodes[i].appendChild(document.createTextNode(msg)); } } changeCSS(view.prefs["motif.current"]); updateMotifSettings(); var output = document.getElementById("output"); output.appendChild(view.messages); if (view.TYPE in headers) { header = cacheNodes(headers[view.TYPE].prefix, headers[view.TYPE].fields); header.update = headers[view.TYPE].update; } var splash = document.getElementById("splash"); var name; if ("unicodeName" in view) name = view.unicodeName; else name = view.name; splash.appendChild(document.createTextNode(name)); setTimeout(initHeader, 500); initialized = true; } function onTopicNodesClick(e) { if (!clickHandler(e)) { if (e.which != 1) return; startTopicEdit(); } e.stopPropagation(); } function onTopicKeypress(e) { switch (e.keyCode) { case 13: /* enter */ var topic = header["topicinput"].value; topic = mainWindow.replaceColorCodes(topic); view.setTopic(topic); view.dispatch("focus-input"); break; case 27: /* esc */ view.dispatch("focus-input"); break; default: client.mainWindow.onInputKeyPress(e); } } function startTopicEdit() { var me = view.getUser(view.parent.me.unicodeName); if (!me || (!view.mode.publicTopic && !me.isOp && !me.isHalfOp) || !header["topicinput"].hasAttribute("hidden")) { return; } header["topicinput"].value = mainWindow.decodeColorCodes(view.topic); header["topicnodes"].setAttribute("hidden", "true") header["topicinput"].removeAttribute("hidden"); header["topicinput"].focus(); header["topicinput"].selectionStart = 0; } function cancelTopicEdit() { if (!header["topicnodes"].hasAttribute("hidden")) return; header["topicinput"].setAttribute("hidden", "true") header["topicnodes"].removeAttribute("hidden"); } function cacheNodes(pfx, ary, nodes) { if (!nodes) nodes = new Object(); for (var i = 0; i < ary.length; ++i) nodes[ary[i]] = document.getElementById(pfx + ary[i]); return nodes; } function changeCSS(url, id) { if (!id) id = "main-css"; node = document.getElementById(id); if (!node) { node = document.createElement("link"); node.setAttribute("id", id); node.setAttribute("rel", "stylesheet"); node.setAttribute("type", "text/css"); var head = document.getElementsByTagName("head")[0]; head.appendChild(node); } else { if (node.getAttribute("href") == url) return; } node.setAttribute("href", url); window.scrollTo(0, window.document.height); } function updateMotifSettings(existingTimeout) { // Try... catch with a repeat to cope with the style sheet not being loaded const TIMEOUT = 100; try { existingTimeout += TIMEOUT; view.motifSettings = getMotifSettings(); } catch(ex) { if (existingTimeout >= 30000) // Stop after trying for 30 seconds return; if (ex.name == "NS_ERROR_DOM_INVALID_ACCESS_ERR") //not ready, try again setTimeout(updateMotifSettings, TIMEOUT, existingTimeout); else // something else, panic! dd(ex); } } function getMotifSettings() { var re = new RegExp("czsettings\\.(\\w*)", "i"); var rules = document.getElementById("main-css").sheet.cssRules; var rv = new Object(); var ary; // Copy any settings, which are available in the motif using the // "CZSETTINGS" selector. We only store the regexp match after checking // the rule type because selectorText is not defined on other rule types. for (var i = 0; i < rules.length; i++) { if ((rules[i].type == CSSRule.STYLE_RULE) && ((ary = rules[i].selectorText.match(re)) != null)) { rv[ary[1]] = true; } } return rv; } function setText(field, text, checkCondition) { if (!header[field].firstChild) header[field].appendChild(document.createTextNode("")); if (typeof text != "string") { text = MSG_UNKNOWN; if (checkCondition) setAttribute(field, "condition", "red"); } else if (checkCondition) { setAttribute(field, "condition", "green"); } header[field].firstChild.data = text; } function setAttribute(field, name, value) { if (!value) value = "true"; header[field].setAttribute(name, value); } function removeAttribute(field, name) { header[field].removeAttribute(name); } function hasAttribute(field, name) { header[field].hasAttribute(name); } function setHeaderState(state) { if (header) { if (state) { updateHeader(); removeAttribute("container", "hidden"); } else { setAttribute("container", "hidden"); } } } function updateHeader() { document.title = view.getURL(); if (!header || hasAttribute("container", "hidden")) return; for (var id in header) { var value; if (id == "url-anchor") { value = view.getURL(); setAttribute("url-anchor", "href", value); setText("url-anchor", value); } else if (id in view) { setText(id, view[id]); } } if (header.update) header.update(); } function updateClient() { var n = 0, c = 0; for (name in client.networks) { ++n; if (client.networks[name].isConnected()) ++c; } setAttribute("version-container", "title", client.userAgent); setAttribute("version-container", "condition", mainWindow.__cz_condition); setText("version", mainWindow.__cz_version); setText("netcount", String(n)); setText("connectcount", String(c)); } function updateNetwork() { if (view.state == client.mainWindow.NET_CONNECTING) { setText("status", MSG_CONNECTING); setAttribute("status","condition", "yellow"); removeAttribute("status", "title"); setText("lag", MSG_UNKNOWN); } else if (view.isConnected()) { setText("status", MSG_CONNECTED); setAttribute("status","condition", "green"); setAttribute("status", "title", getMsg(MSG_CONNECT_VIA, view.primServ.unicodeName)); if (view.primServ.lag != -1) setText("lag", getMsg(MSG_FMT_SECONDS, view.primServ.lag)); else setText("lag", MSG_UNKNOWN); } else { setText("status", MSG_DISCONNECTED); setAttribute("status","condition", "red"); removeAttribute("status", "title"); setText("lag", MSG_UNKNOWN); } } function updateChannel() { header["topicnodes"].removeChild(header["topicnodes"].firstChild); if (view.active) { var str = view.mode.getModeStr(); if (!str) str = MSG_NO_MODE; setText("modestr", str); setAttribute("modestr", "condition", "green"); setText("usercount", getMsg(MSG_FMT_USERCOUNT, [view.getUsersLength(), view.opCount, view.halfopCount, view.voiceCount])); setAttribute("usercount", "condition", "green"); if (view.topic) { var data = getObjectDetails(view); data.dontLogURLs = true; var nodes = client.munger.munge(view.topic, null, data); header["topicnodes"].appendChild(nodes); } else { setText("topicnodes", MSG_NONE); } } else { setText("modestr", MSG_UNKNOWN); setAttribute("modestr", "condition", "red"); setText("usercount", MSG_UNKNOWN); setAttribute("usercount", "condition", "red"); setText("topicnodes", MSG_UNKNOWN); } } function updateUser() { var source; if (view.name) source = "<" + view.name + "@" + view.host + ">"; else source = MSG_UNKNOWN; if (view.parent.isConnected) setText("serverstr", view.connectionHost, true); else setText("serverstr", null, true); setText("title", getMsg(MSG_TITLE_USER, [view.unicodeName, source])); header["descnodes"].removeChild(header["descnodes"].firstChild); if (typeof view.desc != "undefined") { var data = getObjectDetails(view); data.dontLogURLs = true; var nodes = client.munger.munge(view.desc, null, data); header["descnodes"].appendChild(nodes); } else { setText("descnodes", ""); } } function updateDCCChat() { if (view.state.state == 4) setText("remotestr", view.remoteIP + ":" + view.port, true); else setText("remotestr", null, true); setText("title", getMsg(MSG_TITLE_DCCCHAT, view.user.unicodeName)); } function updateDCCFile() { var pcent = Math.floor(100 * view.position / view.size); setText("file", view.filename); setText("progress", getMsg(MSG_DCCFILE_PROGRESS, [pcent, mainWindow.getSISize(view.position), mainWindow.getSISize(view.size), mainWindow.getSISpeed(view.speed)])); setAttribute("progressbar", "width", pcent + "%"); }